|
|
|
|
@ -17,7 +17,7 @@ from sklearn import model_selection as ms
|
|
|
|
|
from sqlalchemy import text
|
|
|
|
|
from django.contrib.gis.db.models.functions import Distance
|
|
|
|
|
from postamates.settings import AGE_DAY_LIMIT
|
|
|
|
|
from postamates.settings import DB_URL, STATUS_TASK_NAME
|
|
|
|
|
from postamates.settings import DB_URL, STATUS_TASK_NAME, STATUS_TASK_NAME_IMPORT
|
|
|
|
|
from service.models import PlacementPoint, LastMLCall
|
|
|
|
|
from service import models
|
|
|
|
|
from service.utils import log_to_telegram
|
|
|
|
|
@ -26,44 +26,37 @@ from io import StringIO
|
|
|
|
|
from django.core.cache import cache
|
|
|
|
|
from service.layer_service import LayerService
|
|
|
|
|
from service.service import PointService
|
|
|
|
|
from service.utils import run_psql_command
|
|
|
|
|
from service.utils import run_psql_command, change_status
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task()
|
|
|
|
|
def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
def raschet(table_name='service_placementpoint', need_time=True, task_name=STATUS_TASK_NAME):
|
|
|
|
|
print('start raschet')
|
|
|
|
|
status, _ = models.TaskStatus.objects.get_or_create(task_name=STATUS_TASK_NAME)
|
|
|
|
|
# status, _ = models.TaskStatus.objects.get_or_create(task_name=STATUS_TASK_NAME)
|
|
|
|
|
raschet_objs = models.RaschetObjects.objects.all()
|
|
|
|
|
if raschet_objs:
|
|
|
|
|
status.status = 'Начало расчета кол-ва ПВЗ вокруг точек'
|
|
|
|
|
status.save()
|
|
|
|
|
change_status('Начало расчета кол-ва ПВЗ вокруг точек', task_name=task_name)
|
|
|
|
|
total = raschet_objs.count()
|
|
|
|
|
for _i, r_o in enumerate(raschet_objs):
|
|
|
|
|
obj = models.Post_and_pvz.objects.get(id=r_o.obj_id)
|
|
|
|
|
LayerService().count_post_pvz_for_placementpoint(obj)
|
|
|
|
|
status.status = "Подсчет кол-ва ПВЗ вокруг точек: " + str(int((_i + 1) / total * 100)) + "%"
|
|
|
|
|
status.save()
|
|
|
|
|
status.status = 'Расчет кол-ва ПВЗ вокруг точек завершен'
|
|
|
|
|
status.save()
|
|
|
|
|
change_status(f'Подсчет кол-ва ПВЗ вокруг точек: {str(int((_i + 1) / total * 100))}%', task_name=task_name)
|
|
|
|
|
change_status('Подсчет кол-ва ПВЗ вокруг точек завершен', task_name=task_name)
|
|
|
|
|
group_objects = models.RaschetGroups.objects.all()
|
|
|
|
|
group_total = group_objects.count()
|
|
|
|
|
if group_objects:
|
|
|
|
|
status.status = 'Начало расчета расстояний'
|
|
|
|
|
status.save()
|
|
|
|
|
change_status('Начало расчета расстояний', task_name=task_name)
|
|
|
|
|
qs = models.PlacementPoint.objects.all()
|
|
|
|
|
for _k, g_o in enumerate(group_objects):
|
|
|
|
|
g = models.Post_and_pvzGroup.objects.get(id=g_o.obj_id)
|
|
|
|
|
for q in qs:
|
|
|
|
|
PointService.calculate_dist_for_group(point=q, group=g)
|
|
|
|
|
status.status = "Подсчет расстояний: " + str(int(_k / group_total * 100)) + "%"
|
|
|
|
|
status.save()
|
|
|
|
|
status.status = "Подсчет расстояний завершен"
|
|
|
|
|
status.save()
|
|
|
|
|
change_status(f'Подсчет расстояний: {str(int((_k + 1) / group_total * 100))}%', task_name=task_name)
|
|
|
|
|
change_status('Расчет завершен', task_name=task_name)
|
|
|
|
|
models.RaschetObjects.objects.all().delete()
|
|
|
|
|
models.RaschetGroups.objects.all().delete()
|
|
|
|
|
# Запуск ML
|
|
|
|
|
status.status = 'Запуск ML'
|
|
|
|
|
status.save()
|
|
|
|
|
change_status('Запуск ML', task_name=task_name)
|
|
|
|
|
log_to_telegram(f'{table_name} start raschet')
|
|
|
|
|
try:
|
|
|
|
|
log_to_telegram('try connect to db')
|
|
|
|
|
@ -121,9 +114,9 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
X_trn = pts_trn[feats].drop(columns=['id'])
|
|
|
|
|
Y_trn = pts_trn[['fact']]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
status.status = 'Записи для инференса'
|
|
|
|
|
status.save()
|
|
|
|
|
# status.status = 'Записи для инференса'
|
|
|
|
|
# status.save()
|
|
|
|
|
change_status('Записи для инференса', task_name=task_name)
|
|
|
|
|
# Записи для инференса
|
|
|
|
|
if table_name == 'service_placementpoint':
|
|
|
|
|
pts_inf = pts.loc[(pts.status == 'Pending') |
|
|
|
|
|
@ -152,17 +145,23 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
target_feature_coords = np.array(target_feature_coords)
|
|
|
|
|
|
|
|
|
|
pts_inf['target_dist'] = pts_inf.apply(
|
|
|
|
|
lambda x: ((sorted(distance.cdist([[x['geometry'].x, x['geometry'].y]], target_feature_coords)[0])[0])),
|
|
|
|
|
lambda x: (
|
|
|
|
|
(sorted(distance.cdist([[x['geometry'].x, x['geometry'].y]], target_feature_coords)[0])[1]) if (
|
|
|
|
|
(x.status == 'Working') or (x.status == 'Installation')) else
|
|
|
|
|
(sorted(distance.cdist([[x['geometry'].x, x['geometry'].y]], target_feature_coords)[0])[0])),
|
|
|
|
|
axis=1,
|
|
|
|
|
)
|
|
|
|
|
pts_inf.loc[pts_inf.target_dist > 700, 'target_dist'] = 700
|
|
|
|
|
|
|
|
|
|
pts_inf = pts_inf.sort_values(by='id').reset_index(drop=True)
|
|
|
|
|
target_post = gpd.sjoin(pts_inf, pts_target, op='contains').groupby('id', as_index=False).agg({'cnt': 'count'})
|
|
|
|
|
target_post = gpd.sjoin(pts_inf, pts_target, op='contains').groupby('id', as_index=False).agg(
|
|
|
|
|
{'cnt': 'count'})
|
|
|
|
|
target_post = target_post.rename(columns={'cnt': 'target_post_cnt'})
|
|
|
|
|
pts_inf = pts_inf.drop(columns=['target_post_cnt'])
|
|
|
|
|
pts_inf = pts_inf.join(target_post.set_index('id'), on='id')
|
|
|
|
|
pts_inf['target_post_cnt'] = pts_inf['target_post_cnt'].fillna(0)
|
|
|
|
|
pts_inf['target_post_cnt'] = pts_inf.apply(lambda x: ((x.target_post_cnt - 1) if (
|
|
|
|
|
(x.status == 'Working') or (x.status == 'Installation')) else x.target_post_cnt), axis=1)
|
|
|
|
|
pts_inf['age_day_init'] = pts_inf['age_day']
|
|
|
|
|
pts_inf['age_day'] = 240
|
|
|
|
|
X_inf = pts_inf[feats]
|
|
|
|
|
@ -173,11 +172,14 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
r2_scores = []
|
|
|
|
|
mapes = []
|
|
|
|
|
y_infers = []
|
|
|
|
|
status.status = 'Обучение inference 0%'
|
|
|
|
|
status.save()
|
|
|
|
|
# status.status = 'Обучение inference 0%'
|
|
|
|
|
# status.save()
|
|
|
|
|
change_status('Обучение inference 0%', task_name=task_name)
|
|
|
|
|
for i in seeds:
|
|
|
|
|
status.status = 'Обучение inference: ' + str(int((seeds.index(i) + 1) / len(seeds) * 100)) + '%'
|
|
|
|
|
status.save()
|
|
|
|
|
# status.status = 'Обучение inference: ' + str(int((seeds.index(i) + 1) / len(seeds) * 100)) + '%'
|
|
|
|
|
# status.save()
|
|
|
|
|
change_status(f'Обучение inference: {str(int((seeds.index(i) + 1) / len(seeds) * 100))}%',
|
|
|
|
|
task_name=task_name)
|
|
|
|
|
x_trn, x_test, y_trn, y_test = ms.train_test_split(X_trn, Y_trn, test_size=0.2, random_state=i)
|
|
|
|
|
model = catboost.CatBoostRegressor(cat_features=['property_era'], random_state=i)
|
|
|
|
|
model.fit(x_trn, y_trn, verbose=False)
|
|
|
|
|
@ -187,7 +189,8 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
r2_scores.append(r2_score)
|
|
|
|
|
mapes.append(mape)
|
|
|
|
|
y_infers.append(model.predict(X_inf.drop(columns=['id'])))
|
|
|
|
|
status.status = 'Обучение inference 100%'
|
|
|
|
|
change_status('Обучение inference 100%', task_name=task_name)
|
|
|
|
|
# status.status = 'Обучение inference 100%'
|
|
|
|
|
current_pred = sum(y_infers) / 5
|
|
|
|
|
|
|
|
|
|
# расчет шапов
|
|
|
|
|
@ -195,14 +198,15 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
shap_values = explainer(X_inf.drop(columns=['id']))
|
|
|
|
|
shap_fields = pd.DataFrame(shap_values.values)
|
|
|
|
|
shap_fields.columns = X_inf.drop(columns=['id']).columns + '_shap'
|
|
|
|
|
shap_fields = shap_fields.drop(columns = ['age_day_shap'])
|
|
|
|
|
shap_fields = shap_fields.drop(columns=['age_day_shap'])
|
|
|
|
|
shap_fields['sum'] = abs(shap_fields).sum(axis=1)
|
|
|
|
|
shap_fields = round(shap_fields.iloc[:,:32].div(shap_fields['sum'], axis=0)*100, 2)
|
|
|
|
|
shap_fields = round(shap_fields.iloc[:, :32].div(shap_fields['sum'], axis=0) * 100, 2)
|
|
|
|
|
|
|
|
|
|
# Обновление полей по результатам работы модели
|
|
|
|
|
update_fields = pts_inf[
|
|
|
|
|
[
|
|
|
|
|
'id', 'age_day_init', 'status', 'fact', 'delta_current', 'delta_first', 'plan_current', 'plan_first',
|
|
|
|
|
'id', 'age_day_init', 'status', 'fact', 'delta_current', 'delta_first', 'plan_current',
|
|
|
|
|
'plan_first',
|
|
|
|
|
'prediction_first', 'target_post_cnt', 'target_dist'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
@ -227,7 +231,8 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
axis=1,
|
|
|
|
|
)
|
|
|
|
|
update_fields['plan_current'] = update_fields.apply(
|
|
|
|
|
lambda x: (x.prediction_current * interpolate.splev(x.age_day_init, spl) if x.status == 'Working' else 0),
|
|
|
|
|
lambda x: (
|
|
|
|
|
x.prediction_current * interpolate.splev(x.age_day_init, spl) if x.status == 'Working' else 0),
|
|
|
|
|
axis=1,
|
|
|
|
|
)
|
|
|
|
|
update_fields['delta_first'] = update_fields.apply(
|
|
|
|
|
@ -246,8 +251,10 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
log_to_telegram(f'Ошибка при обновлении полей в базе данных: {e}')
|
|
|
|
|
log_to_telegram('Начинается обновление полей в базе')
|
|
|
|
|
if len(pts_inf) > 0:
|
|
|
|
|
status.status = 'Перерасчет ML: 50%'
|
|
|
|
|
status.save()
|
|
|
|
|
|
|
|
|
|
# status.status = 'Перерасчет ML: 50%'
|
|
|
|
|
# status.save()
|
|
|
|
|
change_status('Перерасчет ML: 50%', task_name=task_name)
|
|
|
|
|
# Загрузка в базу обновленных значений
|
|
|
|
|
try:
|
|
|
|
|
log_to_telegram('Подключение к базе данных 2')
|
|
|
|
|
@ -377,14 +384,14 @@ def raschet(table_name='service_placementpoint', need_time=True):
|
|
|
|
|
log_to_telegram('len(pts_inf) <= 0')
|
|
|
|
|
run_psql_command()
|
|
|
|
|
log_to_telegram('end raschet')
|
|
|
|
|
status.status = 'Перерасчет ML завершен'
|
|
|
|
|
status.save()
|
|
|
|
|
# status.status = 'Перерасчет ML завершен'
|
|
|
|
|
# status.save()
|
|
|
|
|
change_status('Перерасчет ML завершен', task_name=task_name)
|
|
|
|
|
if need_time:
|
|
|
|
|
LastMLCall.objects.all().delete()
|
|
|
|
|
LastMLCall.objects.create()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task
|
|
|
|
|
def load_post_and_pvz(obj_id: int):
|
|
|
|
|
file = models.TempFiles.objects.get(id=obj_id)
|
|
|
|
|
@ -443,7 +450,7 @@ def load_post_and_pvz(obj_id: int):
|
|
|
|
|
status.status = "Завершено"
|
|
|
|
|
cache.clear()
|
|
|
|
|
status.save()
|
|
|
|
|
|
|
|
|
|
run_psql_command()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task()
|
|
|
|
|
@ -486,6 +493,7 @@ def load_other_objects(obj_id: int):
|
|
|
|
|
status.status = "Загрузка данных завершена"
|
|
|
|
|
cache.clear()
|
|
|
|
|
status.save()
|
|
|
|
|
run_psql_command()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task()
|
|
|
|
|
@ -511,3 +519,10 @@ def load_data(obj_id: int):
|
|
|
|
|
status.status = "Загрузка данных завершена"
|
|
|
|
|
status.save()
|
|
|
|
|
models.TempFiles.objects.all().delete()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@shared_task()
|
|
|
|
|
def import_task(file_id):
|
|
|
|
|
PointService().start_mathing(file_id)
|
|
|
|
|
PointService().make_enrichment()
|
|
|
|
|
raschet('service_preplacementpoint', need_time=False, task_name=STATUS_TASK_NAME_IMPORT)
|
|
|
|
|
|