Это моя первая история среднего размера. Надеюсь, вам было так же интересно читать его, как мне понравилось писать его для аудитории.
Управление успешным рестораном требует от владельцев и менеджеров ресторанов не только управления повседневной работой, но и оценки способов снижения затрат и увеличения продаж в будущем.
Прогнозирование на основе исторических данных, которые могут дать представление о двух ваших самых больших расходах, еде и рабочей силе, и помочь вам принять решение о том, куда вы вкладываете свои ресурсы.
Прогнозирование количества посетителей является значимой задачей в сфере услуг. Существуют различные факторы, которые помогают прогнозировать будущих клиентов в ресторане, такие как местоположение, качество обслуживания, стоимость, персонал и т. д. Сегодня я собираюсь провести вас через реальную задачу науки о данных, которую я выбрал из живого соревнования Kaggle. и продемонстрирую мой способ решения. В этом кейсе все решается с нуля и я рассказываю о своем подходе к решению проблемы.
Постановка задачи
Может быть трудно узнать, сколько посетителей приходило в ресторан в день, поэтому мы не можем знать общий доход ресторана в день на основе посетителей, пришедших в ресторан, поэтому мы разрабатываем реальную проблему, где у нас есть чтобы спрогнозировать количество посетителей, пришедших в ресторан за день, и на основе этого владельцам ресторанов необходимо знать прогноз на следующий день. У рекрутского холдинга есть уникальный доступ к наборам данных, которые могут сделать возможным автоматическое прогнозирование будущих клиентов в будущем.
Проблемы, которые нужно решить:
Учитывая подробную информацию об идентификаторе ресторана, названии, местоположении и районе, можете ли вы создать алгоритм, который автоматически предлагает посетителей? Сложно, правда?
Но при правильном решении это может исключить вмешательство человека в прогнозирование посетителей ресторана, что делает владельцев ресторанов более влиятельными в принятии решений о будущих клиентах, а также официантам, чтобы узнать больше о приготовленной еде для клиентов за день.
Сопоставление реальной проблемы с проблемой машинного обучения:
Тип задачи машинного обучения:
Для данного идентификатора ресторана нам нужно предложить общее количество посетителей этого ресторана на основе их различных характеристик, таких как местоположение, область, название жанра и т. д. Данная проблема является проблемой регрессии, поскольку она возвращает общее количество посетителей ресторана.
Использование машинного обучения/глубокого обучения:
Здесь мы используем данные о бронировании и посещении, чтобы предсказать общее количество посетителей ресторанов в будущем, и на основе этого мы предварительно обработали и спроектировали данные и передали их в модель машинного обучения и глубокого обучения для решения этой проблемы.
Источник данных:
Здесь данные поступают на два отдельных сайта:
1)Горячий перец для гурманов (hpg): пользователи могут искать рестораны по идентификатору hpg_id и бронировать места онлайн.
2)AIRREGI(air): система контроля бронирования и кассового аппарата.
Мы также использовали информацию о бронировании, посещениях и другую информацию с этих сайтов, чтобы спрогнозировать общее количество будущих посетителей ресторана на определенную дату. Данные обучения охватывают даты с 2016 по апрель 2017 года. Набор тестов охватывает последнюю неделю апреля и мая 2017 года.
В тестовом наборе есть дни, когда рестораны были закрыты и в них не было посетителей. Они игнорируются при подсчете очков.
Мы получаем данные для этой проблемы по ссылке ниже: https://www.kaggle.com/c/recruit-restaurant-visitor-forecasting/data
Дата файлы:
Это реляционный набор данных из двух систем. В air_restaurant перед ним стоит air, а в hpg_restaurant — hpg. Каждый ресторан имеет уникальный air_store_id и hpg_store_id.
air_reserve.csv: этот файл содержит бронирование, сделанное в воздушной системе, и здесь backup_datetime указывает время создания бронирования, а visit_datetime указывает время в будущем, когда произойдет посещение.
o air_store_id: идентификатор ресторана в системе air.
o visit_datetime: время бронирования.
oreserve_datetime: время резервирования.
o Reserve_visitors: количество посетителей для данного бронирования.
hpg_reserve.csv: этот файл содержит резервирование, сделанное в системе hpg.
o hpg_store_id: идентификатор ресторана в системе hpg.
o visit_datetime: время бронирования.
oreserve_datetime: время резервирования.
backup_visitors: количество посетителей для этого бронирования.
air_store_info.csv: этот файл содержит информацию о выборе ресторанов Air.
о air_store_id
o air_genre_name
о air_area_name
о широта
о долгота
hpg_store_info.csv: этот файл содержит информацию о выборе ресторанов HPG.
о hpg_store_id
o hpg_Genre_name
о hpg_area_name
о широта
о долгота
store_id_relation.csv: этот файл позволяет вам присоединяться к избранным ресторанам, в которых есть системы Air и HPG.
о hpg_store_id
о air_store_id
air_visit_data: этот файл содержит исторические данные о посещениях air_restaurants.
о air_store_id
о посещение_дата
о посетители
Sample_submission: в этом файле показана отправка, включая дни, на которые вы должны сделать прогноз.
o Id: Идентификатор формируется из air_store_id и даты посещения.
o Посетители: прогнозируемое количество посетителей для комбинации магазина и даты.
date_info: этот файл содержит основную информацию о календарных датах в наборе данных.
o Calendar_date
o Day_of_week
o Holiday_flg: это выходной день в Японии.
Метрика оценки:
Метрикой оценки является среднеквадратическая логарифмическая ошибка, которая рассчитывается как:
Где:
n - общее количество наблюдений
p_i — прогноз посетителей.
a_i — фактическое количество посетителей.
log(x) — натуральный логарифм x.
Q) почему RMSLE не RMSE?
В случае завышенного прогноза небольшие рестораны не понесут убытков, но в случае заниженного прогноза небольшие рестораны страдают от убытков, поскольку многие пищевые материалы выбрасываются, в то время как крупные рестораны терпимы как к завышенным, так и к заниженным прогнозам, а RMSLE наказывает. заниженных прогнозов больше, чем завышенных, что является плюсом для небольших ресторанов, поскольку в Японии большое количество небольших ресторанов.
→ RMSLE штрафуется относительно величины чисел.
Исследовательский анализ данных:
Наблюдения:
1) Это началось с января 2016 года, и тенденция посетителей колебалась от даты посещения до июля, а затем произошел резкий рост с примерно 4500 посетителей до более чем 15000 посетителей.
2)После июля он колебался до ноября, а в конце декабря тренд показывает падение посетителей в 3 раза от текущих значений.
3)После января 2017 года снова один раз крутость увеличилась, а затем колебалась.
Наблюдения:
1) В первые 4 недели наблюдается небольшое увеличение тенденции посетителей по дням недели по сравнению с 5-й неделей, а затем на последней неделе, что показывает тенденцию к снижению посетителей.
2) Наблюдается тенденция к увеличению количества посетителей с начала до конца недели, а количество посетителей незначительно увеличивается и уменьшается в течение всего рабочего дня.
visitor_by_month=airvisit_df.groupby('month')['visitors'].sum() visitor_by_month. head() ax=visitor_by_month.plot.bar() ax.set_ylabel('Monthly Visitors')
Наблюдения:
1) Наибольшее количество посетителей в марте по сравнению со всеми месяцами и самый низкий вклад посетителей в мае и июне.
2) Есть небольшая смена посетителей в ресторане, за исключением марта и мая месяца.
visitors_by_day=airvisit_df.groupby('day')['visitors'].sum() visitors_by_day.head() ax1=visitors_by_day.plot.bar() ax1.set_ylabel('# of Visitors')
Наблюдения:
1) Это флуктуационный тренд, начинающийся с первого дня до конца дня месяца.
2) Наибольшее количество посетителей приходится на 23-й день, а самое низкое количество посетителей приходится на последний день месяца, а другие дни колеблются.
weekly_median_visitors=airvisit_df.groupby('weekday'['visitors'].mean() weekly_median_visitors. Head() df1=pd.DataFrame(weekly_median_visitors) ax2=df1.plot.bar() ax2.set_ylabel('weekly Median visitors')
Наблюдения:
1) Первые четыре недели среднее количество посетителей увеличивается, а в последнюю неделю наблюдается резкое снижение среднего количества посетителей.
2) Наибольшее среднее количество посетителей приходится на последнюю неделю, а наименьшее — на первую и третью недели.
Monthly_mean_visitors=airvisit_df.groupby('month')['visitors'].mean() Monthly_mean_visitors.head() ax2=Monthly_mean_visitors.plot.bar() ax2.set_ylabel('Monthly mean visitors')
Наблюдения:
1) В декабре наблюдается самое высокое среднее количество посетителей, а все остальные месяцы кумулятивно увеличиваются за счет небольшого количества посетителей, а в августе наблюдается небольшое снижение посетителей.
2) В целом тенденция посетителей идти в ресторан и брать еду немного колеблется.
Бронирование:
reservervisitors_by_visit_date=air_reserve.groupby('visit_datetime')['reserve_visitors'].sum() reservervisitors_by_visit_date.head() ax5=reservervisitors_by_visit_date.plot(figsize=[18,5]) ax5.set_ylabel('Total # of Reservation by visit datetime')
Наблюдения:
1) Бронирование начинается после 5-го числа первого месяца января 2016 года, а затем колеблется до конца августа 2016 года.
2) Одинаковый вклад посетителей с сентября 2016 г., затем он колеблется и в конце июня 2017 г. последовательно снижается.
reservedvisitors_by_hour=air_reserve.groupby('hour')['reserve_visitors'].sum() reservedvisitors_by_hour.head() ax6=reservedvisitors_by_hour.plot.bar() ax6.set_ylabel('# of Reserve visitors by Hour')
Наблюдения:
1) Вклад посетителя в почасовом бронировании невелик рано утром, а во второй половине дня он резко возрастает до 8 часов вечера, а затем резко снижается после 23 часов ночи.
2) Этот график показывает, что в первые часы резервирования не так много, но во второй половине дня резервирование увеличивается.
Наблюдения:
1) Существует очень большой разрыв шкалы между бронированием и посещением, и это самые экстремальные значения для данных о воздухе, поскольку формат часа находится между 24 часами до 24 часов и 24 часами следующего дня.
2) На этом графике показана разница между резервным временем и временем посещения, исходя из количества посетителей, посещенных в этот конкретный час, и между резервированием и посещением есть перерывы.
Наблюдения:
1) В начальные дни, т.е. с 1 по 45 дни, количество посетителей находится на пике, а после завершения 50-го дня наблюдается аналогичная тенденция посетителей до 400 дней разницы.
2) по разнице дней между посещениями и резервированием наблюдается падение посетителей при увеличении дней и через несколько дней постоянно есть одинаковые посетители.
ax=air_reserve.pivot_table(index=air_reserve['reserve_hour'],columns='reserve_datetime_weekdayname',values='reserve_visitors',aggfunc='sum').plot(figsize=(12,8),title='making reservation by hour by weekday', xticks=np.arange(0, 24, 1)) ax.set_xlabel('Hour of day') ax.set_ylabel('number of visitors')
Наблюдения:
1) Во все дни, начиная с понедельника по воскресенье, в начальные часы наблюдается тенденция роста посетителей до 6 часов вечера, а после этого наблюдается тенденция снижения посетителей до 23:00 ночи.
2) Этот график основан на резервном дне недели дня часа, сколько посетителей посещает ресторан, а также на сравнении посетителей в день часа между временным интервалом.
Наблюдения:
- В 2016 году количество посетителей, сделавших больше бронирований, увеличилось по сравнению с 2017 годом.
Наблюдения:
1) Бронирование начинается после 5-го числа первого месяца января 2016 года, а затем колеблется до конца 2016 года.
2) В первые месяцы 2017 года наблюдается восходящая тенденция, которая сохраняется до мая, после чего происходит резкое снижение.
Наблюдения:
- Посетители не бронируют до 10 часов утра и после этого начинают с очень небольшого количества бронирований, сделанных до 5 часов вечера, а с 18:00 до 19:00 происходит наибольшее количество бронирований по сравнению с в остальные часы дня и ночи наблюдается тенденция к уменьшению бронирования посетителей.
Наблюдения:
1) Существует очень частая шкала между бронированием и посещением, и это самые экстремальные значения для hpgreservedata, поскольку существует формат часа от 24 часов до 24 часов следующего дня.
2) На этом графике показана разница между резервным временем и временем посещения, исходя из того, что количество посетителей — это посещения в этот конкретный час, а между посещениями и резервированием есть перерывы.
Наблюдения:
1) В первые дни посетители находятся на пике популярности, а после завершения 50-го дня наблюдается аналогичная тенденция посетителей до разницы в 350 дней.
2) По разнице дней между визитом и бронированием наблюдается падение посетителей при увеличении количества дней, а через несколько дней постоянно есть одинаковые посетители.
ax=hpg_reserve.pivot_table(index=hpg_reserve['reserve_hour'],columns='reserve_datetime_weekdayname',values='reserve_visitors',aggfunc='sum').plot(figsize=(12,8),title='making reservation by hour by weekday', xticks=np.arange(0, 24, 1)) ax.set_xlabel('Hour of day') ax.set_ylabel('number of visitors')
Наблюдения:
1) Во все дни, начиная с понедельника по воскресенье, начальные часы показывают одинаковую тенденцию посетителей до 7 часов утра, а затем показывают флуктуирующую тенденцию до 6 часов вечера, а после этого наблюдается тенденция к снижению посетителей. до ночи 23:00
2) В понедельник, пятницу и среду пик посетителей приходится на период с 12:30 до 15:30.
Наблюдения
- В 2016 году количество посетителей, сделавших больше бронирований, увеличилось по сравнению с 2017 годом.
Наблюдения:
1) В Izakya самое большое количество ресторанов, за которыми следуют Caffe/Sweets и Dining Bar, в то время как международная кухня имеет наименьшее количество посетителей.
2) Этот анализ показывает предпочтение посещения определенного типа ресторана по количеству филиалов в конкретном районе.
Наблюдения:
1) В японском стиле самое большое количество ресторанов, за которыми следуют интернациональная кухня и творчество.
2) Есть несколько жанров, у которых меньше или совсем нет ресторанов.
Наблюдения:
1) В праздничные дни посетителей больше, чем в непраздничные.
Существующий подход:
6-е место Kaggle Solution (команда: Yunfeng и Ankit):
1) Помимо набора данных, предоставленного в конкурсе, также используются данные о погоде для конкурса Recruit Restaurant.
2) Из информации календаря используется функция, называемая часовым интервалом, которая дает интервал между бронированием ресторана и посещением в часах, который снова подразделяется на 5 категорий в зависимости от продолжительности интервала.
3)Среднее,медианное,максимальное и минимальное количество посетителей на ресторан учитывается отдельно для рабочих и нерабочих дней.
4) Также рассчитывается общее количество ресторанов по площади.
5) Из информации о погоде, здесь также используется информация о температуре и осадках, но температура подразделяется на низкую, среднюю и высокую.
6) Также рассчитывается среднее количество посетителей по дням недели за все 7 дней всех ресторанов.
7) Также рассчитывается месячное количество посетителей за все 12 месяцев для каждого ресторана.
Первый подход:
1) Прежде всего импортируйте необходимые библиотеки и вспомогательную функцию
Что можно использовать для решения этой проблемы.
2) Загрузите данные airvisit, airreserve, hpgreserve и т. д. и сделайте некоторую статистику, такую как количество нулевых значений, общую форму данных, среднее значение, медиану и некоторую очистку данных, например, некоторые дублированные столбцы, которые можно удалить в вышеприведенный набор данных после загрузки, а также выполнил некоторую предварительную обработку в текстовых столбцах.
3) Делаем ЭДА по всем признакам.
3.1) Анализ количества посещений воздушного ресторана и построение графика количества посетителей в день за весь период обучения и с медианным количеством посетителей за неделю и месяц года и получение представления о том, в какой день недели больше посетителей, чем по сравнению с другим днем недели мы делаем то же самое в месяце и году.
3.2) Проанализируйте на основе бронирования количество посетителей, посещающих конкретный ресторан в этот день, а также время посещения и время между бронированием и посещением.
3.3) Анализ данных о количестве резервирований, сделанных в течение месяца, и сопоставление разницы между ежемесячным резервированием и годовым резервированием в воздушной системе.
3.4) Анализ количества посещений в ресторане HPG и построение графика количества посетителей в день в течение всего периода времени обучения с учетом медианного числа посетителей за неделю и месяц года и получение представления о том, в какой день недели больше посетителей, чем по сравнению с другим днем недели мы делаем то же самое с месяцем и годом.
3.5) анализ данных по области/региону, сколько ресторанов имеется (система air/hpg), сколько вегетарианских ресторанов и сколько не вегетарианских.
3.6) Среднее количество посетителей на основе бронирования в ресторане мультикухни по сравнению с одним рестораном.
3.7) Визуализируйте площадь ресторана, к которой он относится, на основе широты и долготы и количества кухонь (жанров) в зависимости от области.
Объяснение моделей:
· RandomForestRegressor:
· При настройке гиперпараметров мы выяснили, что max_depth=5,n_estimators=3000.
· Обучение и прогнозирование модели RandomForestRegressor: -
def random_forest(train_x,train_y,test_x,**kwargs): forest = RandomForestRegressor(**kwargs) forest.fit(train_x, train_y) pred_y = forest.predict(test_x) return forest,pred_y model = RandomForestRegressor(n_estimators=3000,max_depth=5, random_state=42) model.fit(train_x,train_y) rmsle_rf = model_rf_eval(model,test_x,test_y) print('RF Test RMSLE: %.3f' % rmsle_rf)
· RMSLE, который мы получили для RandomForestRegressor, составляет 10,59.
· Линейная регрессия:
· При настройке гиперпараметров мы обнаружили, что наилучшее значение альфа: 0,01.
· Обучение и прогнозирование модели линейной регрессии: -
clf=linear_model.SGDRegressor(alpha=0.01,loss='squared_loss',penalty='l2',max_iter=3500,average=True) scaler = StandardScaler(with_mean=False) scaler.fit(train_x) train_x = scaler.transform(train_x) test_x = scaler.transform(test_x) clf.fit(train_x,train_y) pred_y=clf.predict(test_x) rmsle_SGD =RMSLE(test_y,pred_y) print('RF Test RMSLE: %.3f' % rmsle_SGD)
· RMSLE, который мы получили для линейной регрессии, составляет 29,86.
· Регрессия хребта:
· При настройке гиперпараметров мы обнаружили, что наилучшее значение альфа: 2.
· Обучение и прогнозирование модели гребневой регрессии: -
cross_val_scores_ridge = [] alpha=[] for i in range(1,9): RidgeModel=Ridge(alpha=i*0.25) RidgeModel.fit(train_x,train_y) scores=cross_val_score(RidgeModel,Xtrain,Ytrain ,cv=10) avg_cross_val_score = mean(scores)*100 cross_val_scores_ridge.append(avg_cross_val_score) alpha.append(i * 0.25) for i in range(0, len(alpha)): print(str(alpha[i])+' : '+str(cross_val_scores_ridge[i])) ridgeModelChosen = Ridge(alpha = 2) ridgeModelChosen.fit(train_x, train_y) pred_y=ridgeModelChosen.predict(test_x) rmsle_Ridge =RMSLE(test_y,pred_y) print('RF Test RMSLE: %.3f' % rmsle_Ridge)
· RMSLE, который мы получили для гребневой регрессии, составляет 0,53.
· Регрессор дерева решений:
· При настройке гиперпараметров мы обнаружили, что max_depth=8, min_sample_split=10
· Здесь также мы использовали log(y), так как это помогает дереву решений упаковывать значения в лист, потому что значения «ближе» друг к другу.
· Обучение и прогнозирование модели DecisionTreeRegressor: -
def DecisionTree(train_x, train_y, test_x, **kwargs): Tree=DecisionTreeRegressor(**kwargs) Tree.fit(train_x,train_y) pred_y=Tree.predict(test_x) return(Tree,pred_y) model = DecisionTreeRegressor() parameters = { "min_samples_split": [10, 20, 40], "max_depth": [2, 6, 8], "min_samples_leaf": [20, 40, 100], "max_leaf_nodes": [5, 20, 100], } grid_obj = GridSearchCV(model, parameters, scoring=acc_scorer) grid_obj = grid_obj.fit(train_x, train_y) model_params = grid_obj.best_params_ model_params model_params = {'max_depth': 8, 'max_leaf_nodes': 100, 'min_samples_leaf': 100, 'min_samples_split': 10} Tree, pred_testy = DecisionTree(train_x,train_y,test_x,**model_params) RMSLE(test_y,pred_testy)
· RMSLE, который мы получили для DecisionTree Regressor, составляет 0,53.
· CatboostRegressor:
· При настройке гиперпараметров мы обнаружили, что глубина = 10, итерация = 2000 и скорость обучения = 0,05.
· Обучение и прогнозирование модели CatboostRegressor: -
def Catboost(train_x,train_y, test_x,**kwargs): Cat=CatBoostRegressor(**kwargs) Cat.fit(train_x, train_y) pred_y=Cat.predict(test_x) return(Cat,pred_y) model = CatBoostRegressor() parameters = { 'depth' : [6,8,10], 'learning_rate' : [0.01, 0.05, 0.1], 'iterations' : [2000] } grid_obj = GridSearchCV(model, parameters, scoring=acc_scorer,cv=2, n_jobs=-1) grid_obj = grid_obj.fit(train_x, train_y) model_params = grid_obj.best_params_ model_params parameters = { 'depth' : [10], 'learning_rate' : [ 0.05], 'iterations' : [2000] } Cat, pred_testy = Catboost(train_x,train_y,test_x,**model_params) plot_important_feature_Cat(Cat) rmsle_cat =RMSLE(test_y,pred_testy) rmsle_cat
· RMSLE, который мы получили для CatboostRegressor, составляет 0,50.
· Модели глубокого обучения:
o Глубокая нейронная сеть:
· Здесь мы создаем глубокую NN с 3 слоями с отсевом 0,25, подгоняем модель и вычисляем RMSLE.
dropout=0.25 model=Sequential() model.add(Dense(250, activation='relu',input_shape=(train_x.shape[1],))) model.add(Dropout(dropout)) model.add(Dense(30, activation='relu')) model.add(Dropout(dropout)) model.add(Dense(1,activation='relu')) model.summary() model.compile(loss='mse',optimizer=adam) model.fit(np.array(train_x), np.array(train_y), epochs=150, batch_size=10, validation_data=(np.array(test_x), np.array(test_y)),verbose=2, callbacks=callbacks, shuffle=False) pred = model.predict(test_x) print('RMSE NeuralNetwork: ', RMSLE(np.log1p(test_y), pred))
· RMSLE, который мы получили для Deep NN, составляет 21,36.
o Архитектура LSTM:
· Здесь мы используем сеть 1D LSTM для прогнозирования посетителей и расчета RMSLE.
model1=Sequential() model1.add(LSTM(4,input_shape=(1, 31),return_sequences=True)) model1.add(Dense(1)) model1.summary() model1.fit(train_x, train_y, epochs=100, batch_size=20,callbacks=callbacks, verbose=2) pred = model1.predict(test_x) print('RMSE NeuralNetwork: ', RMSLE(np.log1p(test_y), p2))
· RMSLE, который мы получили для архитектуры LSTM, составляет 21,89.
o Архитектура CNN:
Здесь мы используем сеть 1D CNN для прогнозирования посетителей и расчета RMSLE.
model3=Sequential() model3.add(Conv1D(16,16, activation='relu', input_shape=(train_x.shape[1],1))) model3.add(Dropout(0.5)) model3.add(MaxPooling1D(pool_size=2)) model3.add(Flatten()) model3.add(Dense(1, activation='relu')) model3.summary() model3.fit(train_x, train_y, epochs=100, batch_size=10,callbacks=callbacks, verbose=2) pred=model3.predict(test_x) p3=pd.DataFrame(pred) print('RMSE NeuralNetwork: ', RMSLE(np.log1p(test_y), p3))
· RMSLE, который мы получили для архитектуры CNN, составляет 19,98.
Сравнение моделей:
Представление Kaggle:
Будущая работа:
· Прямо сейчас данные о посетителях доступны на ежедневной основе, но если они будут доступны на почасовой основе, мы можем еще больше уменьшить детализацию прогноза до прогноза посетителей на следующий час.
· Это даст больше контроля ресторанам с точки зрения подготовки к следующему часу пика и, следовательно, еще больше повысит производительность и время доставки еды.
Вывод:
Это было мое первое самостоятельное исследование машинного обучения, а также моя первая работа на конкурсе Kaggle. Хотя это было поздно, я получил довольно приличный балл Kaggle. Мне пришлось изучить множество методов, работая над повышением точности моделирования машинного обучения. Всегда приятно читать книги и блоги о методологиях, но если вы не делаете это самостоятельно и не изучаете вещи с нуля, вы не получите хорошего представления о том, как вы можете решить это на практике. Итак, я бы посоветовал любому начинающему специалисту по данным начать участвовать в соревнованиях Kaggle и никогда не позволять жажде изучения новых вещей умирать внутри вас.
Несмотря на то, что некоторые фрагменты кода включены в блог, полный код можно найти здесь https://github.com/Kenil706/Visitor-Forecast.
Использованная литература:
1) https://www.kaggle.com/headsortails/be-my-guest-recruit-restaurant-eda
2) https://github.com/mihwa-han/Приятного аппетита
3)https://www.appliedaicourse.com/
Вы также можете найти меня и связаться со мной в Linkdin:https://www.linkedin.com/in/kenil-shah-06613b97/