Интерактивная аналитика и прогнозы по ресторанным советам

Представьте, что у вас есть ресторан, и вы хотите проанализировать не только тенденцию вашего дохода, но и причину периодов особенно высоких доходов, моменты дня, когда в ваш ресторан приходят клиенты определенного типа, почему в некоторые дни чаевые выше чем другие и так далее.

Знание всех этих функций позволит вам использовать их и повысить привлекательность вашего ресторана.

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

"Food servers' tips in restaurants may be influenced by many factors, including the nature of the restaurant, size of the party, and table locations in the restaurant. Restaurant managers need to know which factors matter when they assign tables to food servers. For the sake of staff morale, they usually want to avoid either the substance or the appearance of unfair treatment of the servers, for whom tips (at least in restaurants in the United States) are a major component of pay. In one restaurant, a food server recorded the following data on all customers they served during an interval of two and a half months in early 1990. The restaurant, located in a suburban shopping mall, was part of a national chain and served a varied menu. In observance of local law, the restaurant offered to seat in a non-smoking section to patrons who requested it. Each record includes a day and time, and taken together, they show the server's work schedule."

Кроме того, я собираюсь сделать это в интерактивном режиме, чтобы пользователь мог запрашивать конкретную аналитику / прогнозы. Для этой цели я воспользуюсь пакетом Python Streamlit, очень мощным инструментом, позволяющим легко создавать веб-приложения.

Итак, приступим к аналитике.

Исследовательский анализ

После того, как я загрузил свой набор данных (и попросил мое приложение показать его мне с помощью флажка), я хочу визуализировать некоторые содержательные его резюме. Я напишу свой код в файле .py, а затем запустил его в своем Терминале через streamlit run tips.py.

Итак, давайте начнем с основ построения графиков с помощью гистограммы:

import plotly.graph_objects as go
import pandas as pd
import streamlit as st
import plotly.express as px
import streamlit as st
st.title('Restaurants tips analysis')
tips = px.data.tips()
if st.checkbox('Show dataframe'):
    st.write(tips)

st.subheader('Visualizing bar charts')
label = st.selectbox('Which label do you want to visualize?', ['total_bill', 'tips'])
x = st.selectbox('Pick the x variable: ', ['sex', 'smoker', 'day', 'time', 'size'])
tips=tips.sort_values('size')
fig = px.bar(tips, x=x, y=label, height=400)
st.plotly_chart(fig)
if st.checkbox('Want to group with respect to another variable?'):
    group1 = st.selectbox('Pick the group variable: ', ['smoker', 'day', 'time', 'size','sex'])
    fig1 = px.bar(tips, x=x, y=label, color=group1, barmode='group',
             height=400)
    st.plotly_chart(fig1)
if st.checkbox('Want to group with respect to another variable?'):
    group2 = st.selectbox('Pick the group variable: ', ['day', 'time', 'size','sex', 'smoker'])
    fig2 = px.bar(tips, x=x, y=label, color=group1, barmode='group',facet_col=group2,
             height=400)
    st.plotly_chart(fig2)

А именно, если мы хотим собрать информацию относительно пола, курильщика и дня недели, мы получаем что-то вроде этого:

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

Еще одна интересная функция для сбора - это распределение наших потенциальных целевых переменных, которыми являются советы и total_bill:

st.subheader('Visualizing distributions')
label1 = st.selectbox('Which label do you want to visualize?', ['total_bill', 'tip'])
fig3 = px.histogram(tips, x=label1, hover_data=tips.columns, marginal="box")
st.plotly_chart(fig3)
if st.checkbox('Want to condition the probability?'):
    group1_d = st.selectbox('Pick the conditioning variable: ', ['smoker', 'day', 'time', 'size','sex'])
    fig4 = px.histogram(tips, x=label1, color=group1_d,
                   marginal="box", hover_data=tips.columns)
    st.plotly_chart(fig4)
if st.checkbox('Want to condition the probability on a further variable?'):
    group2_d = st.selectbox('Pick the group variable: ', ['day', 'time', 'size','sex', 'smoker'])
    fig5 = px.histogram(tips, x=label1, color=group1_d, facet_col=group2_d,
                   marginal="box",
                   hover_data=tips.columns)
    st.plotly_chart(fig5)

А именно, распределение total_bill, зависимости от курильщика и дня выглядит следующим образом:

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

ML и прогнозы

Перед запуском нашей линейной регрессии мы должны манипулировать нашим набором данных, поскольку он содержит категориальные данные, такие как пол или курильщик, которые не могут быть обработаны нашей моделью в том виде, в каком они есть. Следовательно, нам необходимо кодировать их как фиктивные переменные, которые действительно используются для сбора качественной / порядковой информации:

tips.replace({ 'sex': {'Male':0 , 'Female':1} , 'smoker' : {'No': 0 , 'Yes': 1}} ,inplace=True)
days=pd.get_dummies(df['day'],drop_first=True)
tips = pd.concat([tips,days],axis=1)
times=pd.get_dummies(tips['time'],drop_first=True)
tips = pd.concat([tips,times],axis=1)
tips.drop(['day','time'],inplace=True,axis=1)
tips.head()

Как видите, теперь вместо Male и Female у нас есть 0 и 1, и то же самое касается курильщика.

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

Теперь давайте построим нашу модель, позволяющую пользователю выбирать как цель, так и функции:

st.subheader('Running Regression')
X = st.multiselect('Pick the covariates: ', ['sex','smoker','size','Thur','Sat','Sun','Lunch']) 
X = tips[X]
y = st.selectbox('Select the target: ', ['tip', 'total_bill'])
y = tips[y]
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X_train, X_test , y_train , y_test = train_test_split(X,y,test_size=0.3,random_state=123)
model = LinearRegression()
model.fit(X_train, y_train)
predictions=model.predict(X_test)
if st.checkbox('Show score'):
    score=model.score(X_test,y_test)
    st.write(f'Score is: {score}')

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

Надеюсь, вам понравилось чтение, и, если вас интересует Streamlit, вы можете прочитать официальную документацию здесь и некоторые из моих предыдущих статей по этой теме:

Ссылки:

Первоначально опубликовано на http://datasciencechalktalk.com 3 ноября 2019 г.