вступление
Когда мы посещаем новое место и хотим найти что-нибудь вкусненькое, первое, что приходит мне в голову, - это достать телефон, открыть Yelp и начать поиск ресторана с самых высоких звезд. И я знаю, что многие поступили бы так же.
Насколько мощно визжит звезда? Исследование показало, что каждая «звезда» в рейтинге Yelp влияет на продажи владельца бизнеса на 5–9 процентов, а исследование, проведенное в 2012 году двумя экономистами из Беркли, показало, что повышение с 3,5 до 4 звезд на Yelp привело к увеличению шансов на 19 процентов. ресторана, забронированного в часы пик.
Чтобы получить более высокую звезду, следует рассмотреть не только предложение качественной и вкусной еды. Есть и другие факторы, которые влияют на рейтинг Yelp и в конечном итоге определяют успех одного бизнеса.
Поэтому в этой статье я бы использовал Python для построения модели множественной линейной регрессии, чтобы выяснить, какие факторы больше всего влияют на рейтинг Yelp ресторана, и спрогнозировать рейтинг Yelp для других ресторанов.
Набор данных
Набор данных предоставлен Yelp на Codecademy. Он включает шесть файлов json: бизнес, отзывы, пользователей, отметки, советы и фотографии. Business ID - это столбец, который является общим для этих шести наборов данных, поэтому он будет использоваться для объединения данных.
Инструменты
- Инструменты: Python Jupyter Notebook
- Навыки: объединение, очистка и исследование данных с помощью Pandas, визуализация с помощью Matplotlib и моделирование с помощью Scikit-Learn.
Прежде всего, я загрузил необходимые для анализа пакеты, включая pandas и matplotlib.
import pandas as pd from matplotlib import pyplot as plt
Затем я использую Pandas для передачи шести файлов json в форму DataFrame.
businesses = pd.read_json(‘yelp_business.json’, lines=True) reviews = pd.read_json(‘yelp_review.json’, lines=True) users = pd.read_json(‘yelp_user.json’, lines=True) checkins = pd.read_json(‘yelp_checkin.json’, lines=True) tips = pd.read_json(‘yelp_tip.json’, lines=True) photos = pd.read_json(‘yelp_photo.json’, lines=True)
Если мы хотим узнать рейтинг для определенного бизнес-идентификатора, мы можем использовать логическое индексирование Pandas, чтобы найти его:
businesses[businesses[‘business_id’] == ‘bFzdJJ3wp3PZssNEsyU23g’][‘stars’]
Объединение, очистка и исследование данных
Поскольку мы работаем с данными из нескольких файлов, нам необходимо объединить данные в один DataFrame, который мы получаем для анализа различных функций в отношении нашей целевой переменной. Итак, здесь я объединяю несколько DataFrames и присоединяю их к общим столбцам, которым является business_id.
df = pd.merge(businesses, reviews, how=’left’, on=’business_id’) df = pd.merge(df, users, how=’left’, on=’business_id’) df = pd.merge(df, checkins, how=’left’, on=’business_id’) df = pd.merge(df, tips, how=’left’, on=’business_id’) df = pd.merge(df, photos, how=’left’, on=’business_id’) print(df.columns)
И это все функции, которые есть в новом фрейме данных «df».
Теперь я удалю из набора данных все столбцы, которые не являются непрерывными или двоичными и по которым мы не хотим делать прогнозы.
features_to_remove = [‘address’,’attributes’,’business_id’,’categories’,’city’,’hours’,’is_open’,’latitude’,’longitude’,’name’,’neighborhood’,’postal_code’,’state’,’time’] df.drop(features_to_remove, axis=1, inplace=True)
И проверьте данные, чтобы убедиться, что нет пропущенных значений или NaN.
df.isna().any()
Как видите, есть несколько столбцов с пропущенными значениями. Итак, я заполню недостающие значения в df 0.
df.fillna({‘weekday_checkins’:0, ‘weekend_checkins’:0, ‘average_tip_length’:0, ‘number_tips’:0, ‘average_caption_length’:0, ‘number_pics’:0}, inplace=True) df.isna().any()
df.corr()
В ходе корреляционного анализа мы обнаружили, что average_review_sentiment имеет очень высокую корреляцию с рейтингом Yelp, что понятно.
Моделирование
Я включаю все функции в раздел моделирования, чтобы увидеть коэффициент каждого параметра, и, конечно же, целевая переменная - «звезды».
features = df[[‘alcohol?’,’has_bike_parking’,’takes_credit_cards’,’good_for_kids’,’take_reservations’,’has_wifi’, ‘review_count’,’price_range’,’average_caption_length’,’number_pics’,’average_review_age’,’average_review_length’,’number_funny_votes’,’number_cool_votes’,’number_useful_votes’, ‘average_review_sentiment’, ‘average_tip_length’,’number_tips’,’average_number_friends’,’average_days_on_yelp’,’average_number_fans’,’average_review_count’,’average_number_years_elite’,’weekday_checkins’,’weekend_checkins’]] ratings = df[‘stars’]
Здесь я разделил данные на наборы для обучения и тестирования.
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(features, ratings, test_size = 0.2, random_state = 1)
После разделения набора данных на обучающий и тестовый наборы, настало время для моделирования. Я импортирую LinearRegression из модуля linear_model scikit-learn и создаю новый объект LinearRegression с именем model.
from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(X_train, y_train)
Оцените модель
model.score(X_train, y_train)
Это показывает, что около 68% обучающего набора данных объясняется моделью.
model.score(X_test, y_test)
Это показывает, что около 67,8% набора данных тестирования объясняется моделью.
Давайте посмотрим на коэффициенты для разных функций. Это показывает, что фактор, предлагающий алкоголь в ресторане, является наиболее предсказуемым по сравнению с другими факторами.
sorted(list(zip([‘alcohol?’,’has_bike_parking’,’takes_credit_cards’,’good_for_kids’,’take_reservations’,’has_wifi’, ‘review_count’,’price_range’,’average_caption_length’,’number_pics’,’average_review_age’,’average_review_length’,’average_review_sentiment’,’number_funny_votes’,’number_cool_votes’,’number_useful_votes’,’average_tip_length’,’number_tips’,’average_number_friends’,’average_days_on_yelp’,’average_number_fans’,’average_review_count’,’average_number_years_elite’,’weekday_checkins’,’weekend_checkins’],model.coef_)),key = lambda x: abs(x[1]),reverse=True)
y_predicted = model.predict(X_test) plt.scatter(y_test, y_predicted) plt.xlabel(‘Yelp Rating’) plt.ylabel(‘Predicted Yelp Rating’) plt.ylim(1,5) plt.show()
Вывод
Мы ожидаем увидеть данные, нанесенные вдоль линии y = x, что указывает на гомоскедастичность и будет относиться к идеальной модели линейной регрессии. Но в данном случае он показывает гетероскедастику вместо гомоскедастики. Для дальнейшего анализа мы можем либо изменить количество параметров в модели, либо выполнить нормализацию, чтобы повысить точность модели.