在当今的商业环境中,公司经常需要将数据分析和机器学习模型的洞察力传达给利益相关者。为此,他们通常会使用各种工具来构建仪表板和Web应用,如Tableau、PowerBI或使用Flask等Web框架定制的工具。然而,这些类型的仪表板构建起来往往耗时且成本较高。幸运的是,有一个开源的Python库Streamlit,为数据科学家提供了一个简单的解决方案。
Streamlit是一个基于Python的库,它允许数据科学家利用他们已有的Python技能来开发Web应用。本博客将展示如何使用Streamlit构建一个应用程序,该程序接收特定用户输入,并预测具有这些特征的客户进行购买的概率。将包括一些商业Web应用中最常见的前端特性。
本文旨在向读者传达Streamlit在可视化、用户输入和机器学习模型集成方面的便捷性。使用了Kaggle的数据集,可以在这里查看。
首先查看训练数据。为了简单起见,从数据集中选择了一个特征子集,并保存了这个子集以便稍后在Streamlit应用中加载。
import pandas as pd
training_data=pd.read_csv("training_sample.csv")
training_data=training_data[['UserID',"basket_add_detail",'promo_banner_click',"sign_in","saw_homepage","returning_user","ordered"]]
training_data.to_csv("training_sample_subset.csv")
让仔细看看数据集中的列:
手头的问题是一个分类问题。由于这篇博客侧重于Streamlit应用,使用Python中的逻辑回归构建了一个简单的模型。请注意,在实践中,可能需要进行EDA,选择适当的模型(逻辑回归、随机森林分类器、KNN分类器等),可能使用交叉验证、正则化、考虑不平衡的数据集等。无论如何,让看看模型吧?
# 分离因变量和自变量
X=training_data[["basket_add_detail",'promo_banner_click',"sign_in","saw_homepage","returning_user"]]
y=training_data[["ordered"]]
# 将X和y分割为训练集和测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=0)
from sklearn.linear_model import LogisticRegression
# 实例化模型(使用默认参数)
propensity_model = LogisticRegression()
# 用数据拟合模型
propensity_model.fit(X_train,y_train)
# 为测试数据集预测
y_pred=propensity_model.predict(X_test)
# 评估模型拟合情况
from sklearn import metrics
metrics.accuracy_score(y_test, y_pred)
模型的准确度为0.9693。就这个Streamlit博客而言,可以为此感到高兴。现在已经准备好了模型,让将其保存为pickle文件。将在稍后的Streamlit应用中使用它来做出预测。以下是将机器学习模型保存为pickle文件的Python代码:
# 将pickle文件保存以便在streamlit应用中加载
import pickle
with open("propensity_model.pkl", 'wb') as pfile:
pickle.dump(propensity_model, pfile)
构建多页应用通常是项目利益相关者最常见的要求之一。在这里,将看到如何使用Streamlit中的单选按钮构建一个两页应用。为此,需要编写3个Python(.py)脚本。其中两个将是分别在各自页面上执行的任务,另一个脚本来集成这两个脚本。在例子中,第1页将显示有关训练数据的详细信息,此代码写在“training.py”中。第2页将有用户输入字段和预测。此代码写在“predict.py”中。这两个文件将通过第三个Python脚本“Streamlit_main_app.py”集成。
让看看如何在脚本“Streamlit_main_app.py”中实际集成这两个页面:
import streamlit as st
import training
import predict
# 应用标题
st.title("客户购买倾向")
# 页面选择
page_choices={"了解训练数据":training,
"预测购买倾向":predict}
# 创建页面选择的单选按钮
page_selection = st.radio("转到", list(page_choices.keys()))
# 根据用户从单选按钮中的选择选择页面
page = page_choices[page_selection]
# 显示页面
with st.spinner(f'正在加载 {page_selection} ...'):
page.app()
请注意,已经导入了“training.py”和“predict.py”。在这里,page.app()指的是在training.py和predict.py中定义的“app()”。将在本博客的后面阶段遇到这个。
import streamlit as st
import pandas as pd
# import altair as alt
import matplotlib.pyplot as plt
st.set_option('deprecation.showPyplotGlobalUse', False)
def app():
# 标题
st.write("使用的培训数据")
# 读取数据
training_sample_subset=pd.read_csv("training_sample_subset.csv")
# 将数据作为表格显示
st.write(training_sample_subset.head(30))
# 标题
st.write("订单分布(因变量)")
# 条形图
temp=training_sample_subset["ordered"].value_counts()
fig, ax = plt.subplots()
ax.bar(["未下单","已下单"],temp,color ='褐红色',width = 0.4)
plt.xlabel("订单状态")
plt.ylabel("客户数量")
st.pyplot()
import streamlit as st
import pandas as pd
import pickle
def app():
option_basket = st.sidebar.selectbox(
'客户是否将任何商品添加到购物篮?',
('是', '否'))
option_promo = st.sidebar.selectbox(
'客户是否点击了任何促销横幅?',
('是', '否'))
option_sign_in = st.sidebar.selectbox(
'客户是否登录?',
('是', '否'))
option_home = st.sidebar.selectbox(
'客户是否看到了首页?',
('是', '否'))
option_repeat = st.sidebar.selectbox(
'他是否是重复客户?',
('是', '否'))
if st.sidebar.button('预测客户购买倾向'):
lookup_dict={"是":1,"否":0}
dict = {'basket_add_detail':[lookup_dict[option_basket]],
'promo_banner_click':[lookup_dict[option_promo]],
'sign_in':[lookup_dict[option_sign_in]],
"saw_homepage":[lookup_dict[option_home]],
"returning_user":[lookup_dict[option_repeat]]
}
prediction_df = pd.DataFrame(dict)
st.write("客户详情用于倾向预测")
st.write(prediction_df)
with open("propensity_model.pkl", 'rb') as pfile:
propensity_model_loaded=pickle.load(pfile)
y_predicted=propensity_model_loaded.predict(prediction_df)
if (y_predicted[0]==1):
st.write("客户将从网站下单。下单概率:")
else:
st.write("客户不会从网站下单。下单概率:")
st.write(propensity_model_loaded.predict_proba(prediction_df))