Машинное обучение
Направление путешествия ✈️ Рекомендация для пользователей Airbnb с XGBoost
Система рекомендаций с использованием Python, Pandas, Plotly, Numpy, Sklearn
Пандемия все еще скрывается; некоторые из нас были затворниками и заключены в течение длительного времени. Выход, путешествие, открытие новых мест кажется идеальным способом избежать этого вопроса.
В ожидании окончания пандемии разработка системы рекомендаций, которая поможет выбрать правильное место для нашей авантюры, — это интересный мысленный эксперимент с реальной практической пользой.
Это то, о чем Airbnb, онлайн-рынок аренды жилья для отпуска, размышлял в 2015 году. В рамках конкурса Kaggle Airbnb запускает задачу, чтобы предсказать первое место для бронирования своих новых пользователей. Пользователи из США. В наборе данных есть 12 возможных мест назначения:
США: США, Франция: Франция, Калифорния: Канада, Великобритания: Великобритания, Испания: Испания, Италия: Италия, PT: Португалия, Голландия: Нидерланды, Германия: Германия, Австралия: Австралия, NDF: пункт назначения не найден.
Мы попытаемся решить этот вопрос, используя различные методы машинного обучения, такие как дерево решений, случайный лес, XGBoost и K.N.N.
Оглавление
∘ Машинное обучение
∘ EDA
∘ Aibnb_df — наш обучающий набор данных. Это основной набор данных, который мы будем использовать для решения задачи.
∘ Предварительная обработка данных
∘ Обучение моделей
∘ Улучшение модели
∘ K-Fold Cross-Validation
∘ Прогноз
∘ Заключение
ЭДА
Исследование данных — важный шаг в решении этой проблемы. Это расширяет наш уровень понимания данных. Мы начнем с импорта некоторых библиотек.
#dataframe and numerical columns import pandas as pd import numpy as np #Visualization import matplotlib import matplotlib.pyplot as plt import plotly.express as px import seaborn as sns
Затем мы прочитаем некоторые кадры данных, которые нам дали.
airbnb_df=pd.read_csv(path) age_df=pd.read_csv(path1) country_df=pd.read_csv(path2) test_df=pd.read_csv(path3) submission_df=pd.read_csv(path4) session_df=pd.read_csv(path5)
Aibnb_df — наш обучающий набор данных. Это основной набор данных, который мы будем использовать для решения задачи.
Набор данных содержит 213451 строку и 16 столбцов.
Давайте посмотрим на Columns:
- ID: идентификатор пользователя
- Date_account_created: дата создания учетной записи.
- Timestamp_first_active: временная метка первого действия, обратите внимание, что оно может быть раньше, чем date_account_created или date_first_booking, поскольку пользователь может выполнить поиск перед регистрацией date_first_booking: дата первого бронирования.
- Пол
- Возраст
- Signup_method: веб-сайт Airbnb, Facebook или Google.
- Signup_flow: страница, с которой пользователь пришел зарегистрироваться.
- Язык: выбор международного языка.
- Affiliate_channel: какой платный маркетинг
- Affiliate_provider: где маркетинг, например. гугл, крейгслист, другое
- First_affiliate_tracked: с чем первым взаимодействовал пользователь перед регистрацией.
- Signup_app
- First_device_type
- Первый_браузер
- Country_destination: это целевая переменная для прогнозирования.
Age_df представляет возрастную группу пользователей.
Session_df представляет действия каждого пользователя на веб-сайте.
Country_df представляет координаты стран назначения.
Мы посмотрим на распределение входных переменных (столбцов), чтобы проверить некоторые предположения, выявить некоторые ошибки. Гистограмма — хороший визуальный инструмент для передачи этих выводов.
Выводы:
- Date_account_created и date_first_booking экспоненциальны со временем с 2010 по 2014 год. Однако с 2014 по 2015 год количество бронирований уменьшилось.
- Путешествует больше женщин, чем мужчин. Однако большинство людей не раскрывают свой пол.
- Средний возраст пользователей составляет от 30 до 34 лет. Как мы предполагаем, у нас большой всплеск в 37 лет.
- Большинство людей получают доступ и открывают для себя Airbnb через веб-сайт. Facebook — это еще один способ, с помощью которого пользователи регистрируются на веб-сайте.
- Большинство пользователей в США говорят по-английски
- Лучшие браузеры для доступа к Airbnb — Chrome, Safari и Firefox.
- Люди чаще всего используют устройства Mac, Windows Desktop, iPhone.
- Пункт назначения, куда люди едут, называется «NDF». Во-вторых, большинство американцев путешествуют по своей стране. Зарубежные направления, в которые американцы путешествуют, — это Франция, Канада и Англия. Тем не менее, они все еще малы по сравнению с путешествиями по штатам.
Предварительная обработка данных
Мы выполним некоторую предварительную обработку данных, чтобы подготовить наши данные перед применением какой-либо статистической модели.
Мы начнем с преобразования данных в объект DateTime и извлечения года, месяца и дня в качестве других входных переменных.
for data in [airbnb_df,test_df]: data.date_account_created=pd.to_datetime(data['date_account_created']) data['account_year']=data.date_account_created.dt.year data['account_month']=data.date_account_created.dt.month data['account_day']=airbnb_df.date_account_created.dt.day
Затем мы проверим, есть ли у нас недостающие данные.
airbnb_df.isna().sum() timestamp_first_active 0 gender 0 age 87990 signup_method 0 signup_flow 0 language 0 affiliate_channel 0 affiliate_provider 0 signup_app 0 first_device_type 0 first_browser 0 account_year 0 account_month 0 account_day 0 country_destination 0 dtype: int64
У нас отсутствует 87990 значений. Проблема заключается в распределении возрастной переменной. Мы изменим некоторое значение, которое больше 100 и меньше 18, на значение nan. Затем мы заменим значение nan на средний возраст.
for data in [airbnb_df,test_df]: data.age=data.age.apply(lambda x: np.nan if x<18 else x) data.age=data.age.apply(lambda x: np.nan if x>100 else x) #remplace the nan value with the age mean for data in [airbnb_df,test_df]: data.age.fillna(data.age.mean(),inplace=True)
Давайте еще раз проверим, есть ли какая-либо отсутствующая переменная.
airbnb_df.isna().sum() timestamp_first_active 0 gender 0 age 0 signup_method 0 signup_flow 0 language 0 affiliate_channel 0 affiliate_provider 0 signup_app 0 first_device_type 0 first_browser 0 account_year 0 account_month 0 account_day 0 country_destination 0 dtype: int64
Мы будем использовать межквартильный диапазон, также известный как IQR, для выявления выбросов путем определения ограничений для выборок.
def remove_outliers(df,name='feature'): #Store the 25th and 75th percentile q25,q75=percentile(df[name],25),percentile(df[name],75) #Calculate the Interquartile range iqr_cut=1.5*(q75-q25) #Create variable of lower and upper cut lower,upper=q25-iqr_cut,q75+iqr_cut #Remove the outliers df=df[(df[name] >= lower) & (df[name] <= upper)] return df
Мы разделим входные данные (столбцы) на два поля: числовой и категориальный.
В нашей числовой группе мы применим некоторую нормализацию, чтобы значение находилось между 0 и 1.
#Normalization scaler=MinMaxScaler() inputs[numerical_cols]=scaler.fit_transform(inputs[numerical_cols])
В нашей категориальной группе мы будем преобразовывать данные с помощью кодирования меток.
#label encoding encoder=LabelEncoder() for col in categorical_cols: inputs[col]=encoder.fit_transform(inputs[col])
кодировка метки преобразует значение столбца в число.
Мы также пометим encode целевую переменную (то, что мы хотим предсказать).
enc_countries={'NDF':0,'US':1,'FR':2,'CA':3,'GB':4,'ES':5,'IT':6,'PT':7,'NL':8,'DE':9,'AU':10,'other':11} target['country_destination']=target['country_destination'].apply(lambda x:enc_countries[x])
Обучите модели
В этом проекте мы будем использовать 4 модели:
- Древо решений
- Случайный лес
- КНН
- XGBoost
Дерево решений – это модель контролируемого обучения, в которой данные непрерывно разбиваются на основе определенного параметра. Дерево может быть определено с двумя основными параметрами
Случайный лес — это модель контролируемого обучения, в которой используется ensemble learning
множества деревьев решений, выходные данные которых основаны на среднем значении выходных данных этих деревьев. Ensemble learning
— это метод, который объединяет множество моделей для решения проблемы.
KNN – это контролируемая модель обучения, которая сегментирует данные, определяя расстояние между запросом и входными данными. Он выбирает количество входных данных, близких к запросу, и голосует за наиболее частую цель.
XGBoost, также известный как Extreme Gradient Boosting, представляет собой алгоритм, в котором используются два метода: градиент и повышение на ансамбле деревьев. Градиент означает, что каждое дерево используется для уменьшения потерь предыдущих итераций. Повышение – это факт обучения новой модели, улучшающей существующую.
#Store results names,score_train,score_val=[],[],[] #Evaluate model models=get_models() for name,model in models.items(): # score1,score2=evalutate_model(model,X,y) score_train.append(score1) score_val.append(score2) names.append(name) print('{}:\n(train_score): {:.2f}%, (val_score): {:.2f}%\n'.format(name,score_train[0]*100,score_val[0]*100))
Результат:
xgb: (train_score): 65.19%, (val_score): 65.90% knn: (train_score): 69.03%, (val_score): 61.36% rf: (train_score): 98.03%, (val_score): 58.84% tree: (train_score): 98.01%, (val_score): 52.52%
После обучения моделей все они переобучаются. Переоснащение происходит, когда модель хорошо работает на обучающем примере и плохо работает на проверочном наборе. Более того,показатель точности,отношение правильных спрогнозированных примеров к общему количеству примеров может быть неверным. метрика для этой задачи.
Улучшить модель
На этот раз мы гипернастроим XGBoost, так как он работает лучше, чем другие алгоритмы. Мы добавляем гиперпараметр max_depth, чтобы помочь нам с переоснащением. Max_Depth определяет количество деревьев, которые модель будет использовать для каждой итерации.
#XGB Classifier XGB= XGBClassifier(random_state=3,n_jobs=-1,max_depth=5,use_label_encoder=False)
Вместо оценки точности мы будем использовать показатель NDCG. Оценка точности — это безранговая метрика, которая охватывает весь набор данных и не учитывает основные рекомендации.
Normalized Discounted Cumulative Gain
, также известный как NDCG, является показателем качества ранжирования. Это среднее значение суммы всех релевантных баллов, которые были обесценены путем деления на журнал соответствующих позиций в наборе рекомендаций.
Наши прогнозы учитывают 12 возможных исходов, при которых каждому из них будет присвоена вероятность наступления. NDCG нормализует и суммирует соответствующий балл с оптимальным набором соответствующих баллов для каждого входа.
Давайте рассмотрим два набора рекомендаций:
Рекомендуемый балл = [3,8,4,2,5]
Идеальный рекомендуемый балл = [8,5,4,3,2]
Соответствующая оценка DCG будет:
DCG=3/ log₂(1+1) +8/ log₂(2+1) + 4/ log₂(3+1) + 2/ log₂(4+1)+ 5/ log₂(5+1) = 12,84
iDCG= 8/ log₂(1+1) +5/ log₂(2+1) + 4/ log₂(3+1) + 3/ log₂(4+1)+ 2/ log₂(5+1) = 15.22
Группа NDCG для рекомендации будет следующей:
NDCG = DCG/iDCG=12,84/15,22=0,84
Мы создадим функцию, которая поможет нам в этом процессе.
def evaluate_model(model,X_train,y_train,X_val,y_val): model.fit(X_train,y_train,eval_metric='merror') #Predict the probabilities of the train and val target xgb_predict=model.predict_proba(X_train) xgb_predict_val=model.predict_proba(X_val) #transform the target into one hot encoder array y_train1 = pd.get_dummies(y_train).to_numpy() y_val1 = pd.get_dummies(y_val).to_numpy() #Compute the ndcg_score train_score= ndcg_score(y_train1,xgb_predict) val_score= ndcg_score(y_val1,xgb_predict_val) # print('train_acc: {:2f}%, val_acc: {:2f}%'.format(train_score*100, val_score*100)) return train_score,val_score,model
K-кратная перекрестная проверка
Мы будем использовать метод перекрестной проверки вместо метода разделения обучения и тестирования.
Перекрестная проверка или k-кратная перекрестная проверка — это процедура повторной выборки, используемая для оценки модели машинного обучения. Он принимает один параметр k, который разбивает данные на k групп. Итак, если K равно 5, данные будут разделены 5 раз на 5 раз.
kfold=KFold(5) t_score,v_score=[],[] for train_idx,val_idx in kfold.split(X): print('First Fold...\n') X_train,X_val=X.iloc[train_idx],X.iloc[val_idx] y_train,y_val=y.iloc[train_idx],y.iloc[val_idx] train_score,val_score,model=evaluate_model(XGB,X_train,y_train,X_val,y_val) t_score.append(train_score) v_score.append(val_score) print('mean train_acc: {:2f}%, mean val_acc: {:2f}%'.format(np.mean(t_score), np.mean(v_score)))
В итоге мы получили средний балл 85,62% для нашего набора поездов и 84,14% для нашего набора проверки. Это огромное улучшение по сравнению с нашей первой попыткой.
Мы рассмотрим важность каждой функции в модели.
Мы видим, что метод signup_method и возраст вносят наибольший вклад в прогнозирование целевой аудитории с учетом пола и потока signup_flow.
Прогноз
Теперь давайте предскажем тестовый набор. Мы создадим функцию predict_test, которая поможет нам.
def predict_test(df): #Normalization scaler=MinMaxScaler() df[numerical_cols]=scaler.fit_transform(df[numerical_cols]) #label encoding encoder=LabelEncoder() for col in categorical_cols: df[col]=encoder.fit_transform(df[col]) #Define X variable X=df[numerical_cols + categorical_cols] print('Processing Destinations ....\n') pred=XGB.predict_proba(X) if len(df) == 1: print('Country of destination: ',enc_label[np.argsort(pred)[::-1][:5]]) # return the label return pred
Мы предскажем 5 возможных направлений для каждого пользователя.
pred1=predict_test(input1) # predict 5 destination for 5 users for i in range(len(test_id)): idx = test_id[i] ids += [idx]*5 countries += [enc_label[ar] for ar in np.argsort(pred[i])[::-1]][:5]
После отправки прогноза на Kaggle я получил 85,05% на тестовом наборе.
Заключение
- Статистические модели, такие как дерево решений, KNN, случайный лес и XGBoost, являются полезными процедурами, которые сопоставляют входные данные с выходными для решения задач классификации.
- Max Depth, гиперпараметр, управляет количеством обучающих примеров, которые будет использовать модель, и может уменьшить переоснащение.
- Разработка признаков может улучшить производительность модели.
- K-fold — это метод повторной выборки, который оценивает навыки модели машинного обучения на невидимых данных и снижает высокую дисперсию.
- NDCG — это хорошая метрика ранжирования для рекомендательных систем, которые учитывают соответствующую оценку в наборе рекомендаций.
Будущая работа
- Создание небольшого приложения с использованием Streamlit для развертывания модели.
- Разверните приложение с помощью Heroku.
Ссылки
coursera
: https://www.coursera.org/learn/machine-learning
jovian
: https://jovian.ai/learn/machine-learning-with-python-zero-to-gbms
Chandekar
: https://towardsdatascience.com/evaluate-your-recommendation-engine-using-ndcg-759a851452d1
Вот ссылка на блокнот.
Если у вас есть какие-либо предложения или что-то на ваш взгляд, вы можете найти меня на LinkedIn.