вступление

Когда мы посещаем новое место и хотим найти что-нибудь вкусненькое, первое, что приходит мне в голову, - это достать телефон, открыть 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, что указывает на гомоскедастичность и будет относиться к идеальной модели линейной регрессии. Но в данном случае он показывает гетероскедастику вместо гомоскедастики. Для дальнейшего анализа мы можем либо изменить количество параметров в модели, либо выполнить нормализацию, чтобы повысить точность модели.