СОДЕРЖАНИЕ

  1. Введение
  2. Бизнес-проблема
  3. Состав ML
  4. Показатели производительности
  5. Анализ набора данных
  6. Исследовательский анализ данных (EDA)
  7. Методы вменения
  8. Функциональная инженерия
  9. Выбор функции
  10. Модели с гиперпараметрической настройкой
  11. Развертывание модели машинного обучения с использованием Flask в Google Colab
  12. Сравнение результатов испытаний
  13. Будущая работа
  14. использованная литература

1. Введение

Это третье энергетическое соревнование, проводимое ASHRAE в 2019 году.

Этот конкурс отличается от двух других конкурсов, проводившихся в прошлом, потому что набор данных, представленный в нем, охватывает трехлетний период (январь 2016 г. - декабрь 2018 г.), тогда как для двух других были доступны данные только за несколько месяцев. Обобщение моделей ML. Здесь мы должны спрогнозировать потребление энергии для четырех различных типов счетчиков (пара, электричество, охлажденная вода, горячая вода).

Набор обучающих данных содержит данные о 1448 зданиях, взятых из 16 различных мест Северной Америки и Европы, а также погодные условия и информацию о зданиях.

2) Бизнес-проблема

В сегодняшнем мире энергетики мы всегда видим, что отрасли придумывают новые способы сокращения выбросов парниковых газов, а также внедряют новые способы снижения затрат на потребление энергии. расширяется, но не такими высокими темпами, как следовало бы, если принять во внимание нынешние условия окружающей среды.

Итак, вопрос в том, почему они не могут расширяться быстрее, хотя они разработали эффективные методы снижения потребления энергии.

Это связано с тем, что в электроэнергетике нет точной методологии расчета экономии в период после модернизации.

Теперь, если отрасли электроэнергетики могут получить модель, которая может точно спрогнозировать потребление энергии в зданиях на основе исторического использования энергии, тогда они могут сравнить ее с потреблением энергии в период после модернизации, что может помочь им эффективно рассчитать экономию энергии. Это также приведет к лучшей оптимизации затрат и стимулов.

Кто будет строить эти модели? Вот тут и пригодятся специалисты по обработке данных и практики машинного обучения. Они построят эти контрфактические модели, которые будут предсказывать показания счетчиков на основе исторического использования энергии.

3) Состав ML

Поскольку мы должны предсказать показания счетчика, которые являются действительными числами, данная проблема может быть сформулирована как проблема ML на основе регрессии.

Данные почасового счетчика за первый год были предоставлены в качестве обучающего набора вместе с погодными условиями и метаданными здания.

Данные за следующие два года были предоставлены в качестве тестового набора, на основе которого мы должны делать наши прогнозы.

4) Показатели производительности

Используемая здесь метрика производительности - это среднеквадратическая логарифмическая ошибка (RMSLE).

Теперь я объясню, почему мы используем эту метрику для решения нашей проблемы регрессии, почему бы не использовать RMSE.

RMSLE влечет за собой большой штраф за недооценку фактической переменной по сравнению с RMSE. Это очень полезно для нашего бизнес-кейса, поскольку недооценка нашей целевой переменной недопустима. Например: если мы недооцениваем потребление электроэнергии, это может привести к отключению зданий в рабочее время, что может привести к денежным потерям. Этот момент действительно является наиболее важным для нашего сценария использования.

В моделях на основе регрессии на RMSE очень сильно влияют выбросы. Теперь, если мы возьмем случай RMSLE, он будет гораздо более устойчивым к выбросам, поскольку он принимает log1p значений, которые как бы сжимают значение.

N - общее количество наблюдений в общедоступном / частном наборе данных.

yi - фактическая целевая переменная

yi ^ - прогнозируемая целевая переменная

log (x) - натуральный логарифм x

Источник → https://www.google.com/url?q=https://www.kaggle.com/c/ashrae-energy-prediction/overview/evaluation&sa=D&ust=1602591028562000&usg=AOvVaw2Pp9JH8h-5U0AgWobeEeml

5) Анализ набора данных

Набор обучающих данных состоит из 20 миллионов точек данных с почасовыми показаниями счетчика для каждого счетчика. Также были предоставлены метаданные о погодных условиях и зданиях. Этот набор данных охватывает период в один год (январь 2016 г. - декабрь 2016 г.).

Набор тестовых данных содержит около 41 миллиона точек данных, охватывающих двухлетний период с января 2017 года по декабрь 2018 года.

Train.csv → Building_id, Timestamp, Meter (0-Электричество, 1-Холодная вода, 2-Пар, 3-Горячая вода)

Weather_train.csv → Site_id, Timestamp, wind_speed, wind_direction, cloud_coverage, air_temperature, Осадки_depth_1_hr, dew_temperature, sea_level_pressure

Building_metadata.csv → Building_id, floor_count, square_feet, year_built, primary_usage

Site_id → Уникальный идентификатор сайта. Диапазон значений 0–15.

Building_id → уникальный идентификатор здания. Диапазон значений 0–1448.

Источники → https://www.kaggle.com/c/ashrae-energy-prediction/data

6) Исследовательский анализ данных

Сначала я объединил данные о поездах с метаданными зданий и данными о погоде. Теперь, получив последний набор данных о поездах, я начал анализировать каждую строительную площадку по каждой.

  1. Интересные выводы

Когда я начал анализировать показания счетчиков для каждого здания для каждого сайта, я обнаружил, что показания счетчиков для сайтов 0 и 0 были в основном нулевыми до 20 мая 2016 г. Ниже показано изображение вместе с фрагментом кода.

df.drop(index=df[(df['building_id']<=104) & (df['meter']==0) & (df['timestamp']<'2016-05-21')].index,inplace=True)

Было много зданий с нерегулярными или очень высокими показаниями счетчиков, которые также необходимо удалить. Эти здания распределены по многим объектам с разными счетчиками. Ниже приведен код для этого

df.drop(index=df[(df['building_id']==53) & (df['meter']==0)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1099) & (df['meter']==2)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1250) & (df['meter']==2)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1227) & (df['meter']==0)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1314) & (df['meter']==0)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1281) & (df['meter']==0)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==279) & (df['meter']==3)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==263) & (df['meter']==3)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==287) & (df['meter']==3)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1018) & (df['meter']==1)].index,inplace=True)#Removing Anamolous Building
  df.drop(index=df[(df['building_id']==1022) & (df['meter']==1)].index,inplace=True)#Removing Anamolous Building

Отметка времени в эфире не была согласована с местной отметкой времени показаний почасового счетчика. Из 15 разных участков эта проблема наблюдалась для 13 разных участков. Ниже приведено изображение для одного участка, но то же самое наблюдалось еще на 12 участках, где температура был максимальным примерно с 19:00 до 23:00.

Я также проверил потребление энергии различными счетчиками в течение часа дня, чтобы увидеть закономерности использования энергии. Здесь мы видим, что показания счетчика электроэнергии начинают расти с 6:00 утра и начинают уменьшаться после 18:00. вечера.

Если мы хотим проверить показания для охлажденной воды, оно обычно достигает максимума в дневные часы и начинает снижаться с вечерних часов.

Горячая вода и пар не демонстрируют каких-либо заметных тенденций в течение дня.

Давайте дальше исследуем энергетический образец в течение дня недели.

Первое, что я показал здесь, - это потребление электроэнергии в течение дня недели. Здесь мы можем заметить, что потребление меньше в выходные дни по сравнению с будними днями. Эта закономерность сохраняется почти на всех объектах при проверке счетчика. 0. Теперь для остальных трех метров эта картина более или менее одинакова для большинства участков.

Теперь, переходя к следующему пункту, я покажу вам энергопотребление счетчиков в зависимости от времени года. Наиболее заметное влияние этого фактора на потребление охлажденной и горячей воды.

Из двух графиков выше видно, что потребление охлажденной и горячей воды сильно колеблется в зависимости от времени года.

7) Методы вменения

Сначала я проверю процент пропущенных значений для каждой присутствующей функции. Ниже приведен код вместе с процентами нулевых значений.

(df_train_merge_cleaned.isnull().sum()/df_train_merge_cleaned.shape[0])*100

building_id- ›0,000000 метра-› 0,000000 метка времени- ›0,000000 считывание_метра -› 0,000000 site_id- ›0,000000 primary_use-› 0,000000 square_feet - ›0,000000 year_built-› 61.010820 floor_count- ›82,361341 air_temperature-› 0,486579 cloud_coverage_content_forms - ›43.647889_hrdew_tempo_1 ›18.948532 sea_level_pressure-› 6.191485 wind_direction- ›7.264534 wind_speed-› 0.724510

Теперь перейдем к вмененной части, поскольку величина энергопотребления зависит от конкретного объекта, а также от дня недели и месяца, поэтому нам нужно сгруппировать ее, взяв все три упомянутые характеристики.

Сначала я снизил количество этажей, так как его не хватало более чем на 80%.

df_train_merge_cleaned.drop('floor_count',axis=1,inplace=True)
df_train_merge_cleaned.reset_index(inplace=True)

Теперь перейдем к другим функциям. Это код, который я использовал для заполнения всех других функций, кроме температуры воздуха и росы.

df_train_merge_cleaned['day']=df_train_merge_cleaned['timestamp'].dt.day
df_train_merge_cleaned['month']=df_train_merge_cleaned['timestamp'].dt.month
cc_fill=df_train_merge_cleaned.groupby(['site_id','day','month'])['cloud_coverage'].median().reset_index()
cc_fill.rename(columns={'cloud_coverage':'cc_filler'},inplace=True)
cc_fill['cc_filler'].fillna(method='ffill',inplace=True)
df_train_merge_cleaned=df_train_merge_cleaned.merge(cc_fill,how='left',on=['site_id','day','month'])
df_train_merge_cleaned['cloud_coverage'].fillna(df_train_merge_cleaned['cc_filler'],inplace=True)
df_train_merge_cleaned.drop(labels=['cc_filler'],axis=1,inplace=True)

Для температуры воздуха и росы, поскольку она показывала сильную корреляцию с данными за предыдущий час, поэтому я использовал линейную интерполяцию, чтобы заполнить недостающие значения.

z = df_train.set_index («отметка времени»). copy ()

plot_pacf (z [‘air_temperature’]. resample (‘1h’). mean (), lags = 24)

df_train_merge_cleaned [‘air_temperature’] = df_train_merge_cleaned [‘air_temperature’]. Interpolate (method = ’linear’) df_train_merge_cleaned [‘dew_temperature’] = df_train_merge_cleaned (‘’ ’’ ’method)

8) Разработка функций

Во-первых, я выровнял всю температуру воздуха с местной меткой времени показаний счетчика.

Теперь для сайта 0 температура воздуха была сдвинута на 5 часов. Это было разным для разных сайтов, но код точно такой же. Ниже приведен код для выравнивания временных меток.

df_train_site_0=df_train_merge_cleaned_imputed[df_train_merge_cleaned_imputed['site_id']==0]
df_train_site_0.reset_index(inplace=True)
df_train_site_0['timestamp_aligned']=df_train_site_0['timestamp']-timedelta(hours=5,minutes=0)
df_air_temp_timestamp=df_train_site_0[['timestamp_aligned','building_id','meter','air_temperature']].copy()
df_air_temp_timestamp.rename(columns={'timestamp_aligned':'timestamp'},inplace=True)
df_train_site_0.drop(['air_temperature','timestamp_aligned'],axis=1,inplace=True)
df_train_site_0['air_temperature_aligned']=df_air_temp_timestamp[df_air_temp_timestamp['timestamp'].isin(df_train_site_0['timestamp'])].reset_index(drop=True)['air_temperature']
df_train_site_0['air_temperature_aligned']=df_train_site_0['air_temperature_aligned'].interpolate()
df_train_site_0.rename(columns={'air_temperature_aligned':'air_temperature'},inplace=True)
df_train_site_0.drop(['level_0','index'],axis=1,inplace=True)

1) ОТНОСИТЕЛЬНАЯ ВЛАЖНОСТЬ → ВЛАЖНОСТЬ ВЛИЯЕТ НА ТРЕБОВАНИЯ К ЭНЕРГИИ ЗДАНИЙ. ВЛАЖНОСТЬ УВЕЛИЧИВАЕТ НАГРУЗКУ НА СИСТЕМУ ОВиКВ, ИЗ-ЗА которой ВЛИЯЮТСЯ ПОКАЗАНИЯ ИЗМЕРИТЕЛЯ. ЭТА ФУНКЦИЯ ПОМОГАЕТ МОДЕЛИ ПОМОГАЕТ МОДЕЛИ ПОМОГАЮТ УЗНАТЬ ЭНЕРГИЮ. НИЖЕ КОД ДЛЯ ЭТОГО

saturated_vapor_pressure = 6.11 * (10**(7.5*df_train_merged_final['air_temperature']/(237.3+df_train_merged_final['air_temperature'])))
actual_vapor_pressure = 6.11 * (10**(7.5*df_train_merged_final['dew_temperature']/(237.3+df_train_merged_final['dew_temperature'])))
df_train_merged_final['relative_humidity']=(actual_vapor_pressure/saturated_vapor_pressure)*100

2) ЕСТЬ ЛЕТНИЙ МЕСЯЦ И ЯВЛЯЕТСЯ ЗИМОЙ.

df_train_merged_final ['is_winter_month'] = (df_train_merged_final ['месяц']. isin ([12,1,2])). astype (int) df_train_merged_final ['is_summer_month'] = (df_train_merged_merged_final. [' , 7,8])). Astype (число)

3) ПРАЗДНИКИ → КАК ТРЕБОВАНИЯ К ЭНЕРГИИ ВО ВРЕМЯ ПРАЗДНИКА МОГУТ БЫТЬ ОТЛИЧНЫМИ ОТ ДРУГИХ ДНЕЙ, ВКЛЮЧАЯ ДАННУЮ ФУНКЦИЮ ПОМОЖЕТ МОДЕЛИ УЗНАТЬ ЭТО.

holiday_datetime = pd.to_datetime (праздники, yearfirst = True) df_train_merged_final [‘is_pub_holiday’] = (df_train_merged_final [‘timestamp’]. dt.date.isin (holiday_datetime.date)). astype (int)

4) ЕСТЬ НЕДЕЛЮ → ДАННАЯ ФУНКЦИЯ ДОБАВЛЕНА, ЧТОБЫ ПРОВЕРИТЬ ТРЕБОВАНИЯ К ЭНЕРГИИ ДНЯ ПО СРАВНЕНИЮ С ВЫХОДНЫМИ. КАК НАБЛЮДАЕТСЯ В EDA, ПОКАЗЫВАЕТ ЗНАЧИТЕЛЬНУЮ ТЕНДЕНЦИЮ ЗА НЕДЕЛЮ ПО СРАВНЕНИЮ С ЭНЕРГОПОТРЕБЛЕНИЕМ ВЫХОДНОЙ ЭНЕРГИИ. КОД ДЛЯ ЭТОГО

df_train_merged_final['is_weekday']=((~df_train_merged_final['timestamp'].dt.date.isin(holiday_datetime.date))&(df_train_merged_final['weekday'].isin([0,1,2,3,4]))).astype(int)

5) РАБОЧИЕ ЧАСЫ → ПОСКОЛЬКУ ТРЕБОВАНИЯ К ЭНЕРГОПОТРЕБЛЕНИЮ В ДЕНЬ ОТЛИЧАЮТСЯ ОТ НОЧИ. ПОМОЩЬ МОДЕЛИ УЗНАЙТЕ, ЧТО МЫ МОЖЕМ ИСПОЛЬЗОВАТЬ ЧАСЫ НАГРУЗКИ (с 6:00 до 18:00).

z_busy_hours=df_train_merged_final.set_index(['timestamp']).between_time('06:00:00','18:00:00').reset_index()
z_busy_hours_timestamp=[i for i in z_busy_hours['timestamp']]
df_train_merged_final['busy_hours']=((~df_train_merged_final['timestamp'].dt.date.isin(holiday_datetime.date))&(df_train_merged_final['timestamp'].isin(z_busy_hours_timestamp))).astype(int)

6) ДОБАВЛЕНИЕ ОСНОВНЫХ ФУНКЦИЙ TIMESTAMP, КАК ДЕНЬ, МЕСЯЦ И ЧАС.

df_train_merged_final['hour']=df_train_merged_final['timestamp'].dt.hour
df_train_merged_final['weekday']=df_train_merged_final['timestamp'].dt.weekday
df_train_merge_cleaned['day']=df_train_merge_cleaned['timestamp'].dt.day
df_train_merge_cleaned['month']=df_train_merge_cleaned['timestamp'].dt.month

7) КОДИРОВАНИЕ МЕТКИ КАТЕГОРИЧЕСКИХ ПЕРЕМЕННЫХ. НИЖЕ КОД ДЛЯ ЭТОГО

label_encoder=LabelEncoder()
df_train_merged_final_red['primary_use']=label_encoder.fit_transform(df_train_merged_final_red['primary_use'])

9) Выбор функции

Я сделал выбор функций перед подгонкой моей модели, так как набор данных был большим, поэтому дополнительные функции определенно увеличили бы шансы переобучения. Я сделал это, используя XGB Regressor в качестве базовой модели.

Как видно из приведенного выше графика, всего 17 важных функций, а остальные 6 отброшены.

10) Настройка модели и гиперпараметров

Здесь я пробовал разные модели, такие как RF, XGBOOST, LGBM, CATBOOST, CUSTOM-ENSEMBLING и DEEP LEARNING MODEL. Для каждой модели я выполнил настройку гиперпараметров. Сначала я применил целевое преобразование (log1p) к моей целевой переменной, поэтому Я использую RMSE в качестве метрики оценки, которая по умолчанию становится RMSLE.

  1. МОДЕЛЬ XGBOOST

Настройка гиперпараметров для МОДЕЛИ XGBOOST с лучшими параметрами

x_cfl = XGBRegressor (tree_method = ’gpu_hist’)

params = {‘n_estimators’: [300,500,1000,1500,2000],

«Скорость обучения»: [0.01,0.03,0.05,0.1],

‘Max_depth’: [3,5,7,9],

‘Colsample_bytree’: [0.5,0.8,0.9,1]}

random_clf = RandomizedSearchCV (x_cfl, params, scoring = ’neg_root_mean_squared_error’, n_jobs = -1, cv = 3, verbose = 10, random_state = 0, n_iter = 10)

random_clf.fit (X_train, y_train)

random_clf.best_params_

{'colsample_bytree': 0.8,
 'learning_rate': 0.1,
 'max_depth': 9,
 'n_estimators': 500}

2) МОДЕЛЬ ЛГБМ

Настройка гиперпараметров для LGBM-МОДЕЛИ с лучшими параметрами

params = {‘max_depth’: [3,5,7,9,11],

«Скорость обучения»: [0.1,0.01,0.03,0.05],

‘Colsample_bytree’: [0.7,0.8,0.9,1.0],

‘N_estimators’: [300,500,800,1200],

‘Min_child_samples’: [50,100,200,300,500]}

lgb_reg = LGBMRegressor ()

random_clf = RandomizedSearchCV (lgb_reg, params, n_iter = 8, scoring = ’neg_root_mean_squared_error’, cv = kf, verbose = 24, random_state = 1, n_jobs = -1)

random_clf.fit (X_train, y_train)

random_clf.best_params_

{'colsample_bytree': 0.9,
 'learning_rate': 0.1,
 'max_depth': 7,
 'min_child_samples': 100,
 'n_estimators': 1200}

3) МОДЕЛЬ CATBOOST

params=[]
err_score=[]
for i in range(10):
  max_depth=np.random.randint(3,15)
  estimators=np.random.randint(300,1500)

 


  cat_reg=CatBoostRegressor(task_type='GPU',loss_function='RMSE',max_depth=max_depth,n_estimators=estimators,learning_rate=0.1)
  cat_reg.fit(X_train,y_train)
  test_pred=cat_reg.predict(X_test)
  err_test=np.sqrt(mean_squared_error(y_test,test_pred))
  err_score.append(err_test)
  params.append((max_depth,estimators))

err_score

[0.8014502674080963,
 0.969339306037929,
 1.1105379937315227,
 0.8017482632418587,
 1.083261361679219,
 0.7968043441249344,
 0.88638072298227,
 1.2696015010888373,
 1.0057081335900901,
 1.3935640553815056]

параметры

[(13, 1183), (10, 467), (5, 1456), (14, 925), (6, 986), (13, 1289), (10, 756), (4, 928), (8, 696), (3, 695)]

Из оценки ошибок мы видим, что лучшие найденные параметры - max_depth-13 и n_estimators-1289.

4) РЕГРЕССОР РФ

Настройка гиперпараметров с лучшими параметрами. Лучшие параметры можно найти здесь

rf_reg = RandomForestRegressor (n_jobs = -1)

params = {‘n_estimators’: [20,40,60,80,100],

‘Max_depth’: [3,5,7,9]}

random_clf = RandomizedSearchCV (rf_reg, params, scoring = ’neg_root_mean_squared_error’, n_jobs = -1, cv = 3, verbose = 15, n_iter = 5, random_state = 0)

random_clf.fit (X_train, y_train)

random_clf.best_params_

{'max_depth': 9, 'n_estimators': 100}

5) ТАМОЖЕННЫЙ АНСАМБЛИРОВАНИЕ

Здесь я делю набор поездов на 80–20. Теперь 20% остается в качестве тестового набора, а 80% делится на 50–50 (df1 и df2). На df1 мы берем наши базовые модели, настраиваем гиперпараметры и прогнозируем на df2. .Теперь мы объединяем прогнозы df2, которые используются в качестве обучающего набора для моей метамодели. Поскольку у нас есть целевая переменная для остальных 20%, вместе с прогнозами df2 используется для настройки гиперпараметров.

Далее мы делаем прогнозы на окончательном наборе тестов, и эти прогнозы снова объединяются и используются в качестве входных данных для метамодели. Теперь окончательные прогнозы поступают из метамодели.

Используемые базовые модели - CATBOOST, LGBM И XGBOOST. Используемая мета-модель - LGBM.

X_train,X_test,y_train,y_test=train_test_split(df_tr_red_final,y_tr,test_size=0.2,random_state=0)
X_train_d1,X_train_d2,y_train_d1,y_train_d2=train_test_split(X_train,y_train,test_size=0.5,random_state=0)
s1_d1=X_train_d1.sample(frac=0.8,replace=True,random_state=0)
y1_d1=y_train_d1.sample(frac=0.8,replace=True,random_state=0)
s2_d1=X_train_d1.sample(frac=0.8,replace=True,random_state=1)
y2_d1=y_train_d1.sample(frac=0.8,replace=True,random_state=1)
s3_d1=X_train_d1.sample(frac=0.8,replace=True,random_state=2)
y3_d1=y_train_d1.sample(frac=0.8,replace=True,random_state=2)

Вот код для настройки гиперпараметров моих базовых моделей

x_cfl=XGBRegressor(tree_method='gpu_hist')
params={'n_estimators':[300,500,1000,1500,2000],
        'learning_rate':[0.01,0.03,0.05,0.1],
        'max_depth':[3,5,7,9],
        'colsample_bytree':[0.5,0.8,0.9,1]}
random_xgb=RandomizedSearchCV(x_cfl,params,scoring='neg_root_mean_squared_error',n_jobs=-1,cv=3,verbose=10,random_state=1,n_iter=10)
random_xgb.fit(s1_d1,y1_d1)
random_xgb.best_params_
{'colsample_bytree': 0.8,
 'learning_rate': 0.1,
 'max_depth': 7,
 'n_estimators': 2000}
params={'max_depth':[3,5,7,9,11,13,15],
'n_estimators':[300,500,800,1000,1200,1500],
'learning_rate':[0.1,0.01,0.03,0.05]}
cat_reg=CatBoostRegressor()
random_cat=RandomizedSearchCV(cat_reg,params,scoring='neg_root_mean_squared_error',n_jobs=-1,cv=3,verbose=1,random_state=1,n_iter=8)
random_cat.fit(s2_d1,y2_d1)
random_cat.best_params_
{'learning_rate': 0.1, 'max_depth': 15, 'n_estimators': 1200}
params={'max_depth':[3,5,7,9,11],
'learning_rate':[0.1,0.01,0.03,0.05],
'colsample_bytree':[0.7,0.8,0.9,1.0],
'n_estimators':[300,500,800,1200],
'min_child_samples':[50,100,200,300,500]}


lgb_reg=LGBMRegressor()
random_lgb=RandomizedSearchCV(lgb_reg,params,n_iter=8,scoring='neg_root_mean_squared_error',cv=3,verbose=1,random_state=42,n_jobs=-1)
random_lgb.fit(s3_d1,y3_d1)
random_lgb.best_params_
{'colsample_bytree': 1.0,
 'learning_rate': 0.1,
 'max_depth': 11,
 'min_child_samples': 300,
 'n_estimators': 800}

Вот код для настройки гиперпараметров для моей метамодели.

params={'max_depth':[3,5,7,9,11],
'learning_rate':[0.1,0.01,0.03,0.05],
'colsample_bytree':[0.7,0.8,0.9,1.0],
'n_estimators':[300,500,800,1200],
'min_child_samples':[50,100,200,300,500]}


lgb_reg=LGBMRegressor()
random_lgb=RandomizedSearchCV(lgb_reg,params,n_iter=8,scoring='neg_root_mean_squared_error',cv=3,verbose=24,random_state=5,n_jobs=-1)
random_lgb.fit(X_train_d2_pred,y_train_d2)
random_lgb.best_params_
{'colsample_bytree': 0.9,
 'learning_rate': 0.05,
 'max_depth': 7,
 'min_child_samples': 50,
 'n_estimators': 800}

6) Простая модель MLP

Здесь я строю свою первую модель нейронной сети.

model_3=Sequential()
model_3.add(Dense(256,activation='relu',input_shape=(X_train.shape[1],)))
model_3.add(Dense(128,activation='relu'))
model_3.add(Dense(64,activation='relu'))
model_3.add(Dense(32,activation='relu'))
model_3.add(Dense(1))
model_3.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.1),loss=rmse)
model_3.fit(X_train,y_train,epochs=10,validation_data=(X_test,y_test),batch_size=int(X_train.shape[0]/10))
Epoch 1/10
11/11 [==============================] - 57s 5s/step - loss: 1200632.2554 - val_loss: 3.3051
Epoch 2/10
11/11 [==============================] - 55s 5s/step - loss: 2.6724 - val_loss: 2.3621
Epoch 3/10
11/11 [==============================] - 55s 5s/step - loss: 2.3916 - val_loss: 2.1868
Epoch 4/10
11/11 [==============================] - 55s 5s/step - loss: 2.1294 - val_loss: 2.0849
Epoch 5/10
11/11 [==============================] - 55s 5s/step - loss: 2.0988 - val_loss: 2.0801
Epoch 6/10
11/11 [==============================] - 55s 5s/step - loss: 2.0969 - val_loss: 2.1468
Epoch 7/10
11/11 [==============================] - 55s 5s/step - loss: 2.1280 - val_loss: 2.0903
Epoch 8/10
11/11 [==============================] - 55s 5s/step - loss: 2.1155 - val_loss: 2.1396
Epoch 9/10
11/11 [==============================] - 55s 5s/step - loss: 2.1278 - val_loss: 2.0815
Epoch 10/10
11/11 [==============================] - 55s 5s/step - loss: 2.0806 - val_loss: 2.0793

11) Сравнение результатов испытаний всех моделей

Здесь мы видим, что модель ЛГБМ показывает лучшие результаты из всех моделей, с которыми мы экспериментировали.

12) Развертывание моделей машинного обучения с использованием Flask в Google Colab

В качестве последнего шага я развернул свою модель с помощью flask в google colab. Еще одна важная вещь, которую следует отметить при развертывании модели с помощью colab, - это использовать ngrok, поскольку он делает ip общедоступным, поскольку colab является виртуальной машиной. Здесь я прикрепляю видео ссылка моей развернутой модели.

13) Дальнейшая работа

Здесь можно попробовать разные идеи, такие как создание 16 разных моделей для каждого сайта или создание 4 разных моделей для каждого измерителя. Еще одна вещь, которую я хотел бы добавить, это то, что я не использовал утечки данных, которые определенно можно использовать для целей перекрестной проверки. которые могут улучшить нашу метрическую оценку. Также можно попробовать объединение различных моделей на метр или на участок.

14) ССЫЛКИ

Прогнозирование спроса на энергию с помощью нейронных сетей | К науке о данных

Оценка противофактического энергопотребления зданий с помощью машинного обучения | Стивен Смайли | К науке о данных



ASHRAE - Обработка отсутствующих погодных данных | Kaggle

ASHRAE - EDA и предварительная обработка | Kaggle

M5-Forecasting-Accuracy / Ensemble_Model.ipynb на главной · vence-andersen / M5-Forecasting-Accuracy · GitHub

Находить города по погодной температуре🌇 | Kaggle