首页 > 编程语言 >Python数据分析案例45——基于融合模型(Stack)的电商用户购买行为预测

Python数据分析案例45——基于融合模型(Stack)的电商用户购买行为预测

时间:2024-06-05 10:00:40浏览次数:31  
标签:plt val Python 模型 45 df import model 电商

案例背景

最近618快到了,上电商购买的人很多,正好我手上还有这个用户购买行为的数据,就做了一个机器学习模型流程,然后也使用的都是常见的机器学习模型,但是加了一点创新吧,使用了stacking融合模型。简单来说就是使用了很多机器学习模型一起融合,这样的好处在于会降低方差,使预测结果更精准和鲁棒。


数据集介绍,大概长这个样子:

 最后一列是Y,是我们要预测的是否购买。其他的X具体如下:

数据属性包括:10个数值属性和8个类别属性,每列变量表示的含义如下:

“用户相关页面”、“用户页面访问持续时间”、“信息相关页面”、“信息相关页面访问持续时间”、“产品相关页面”和“产品相关页面访问持续时间”表示访问者在该会话中访问的不同类型页面的数量以及在这些页面类别中花费的总时间。这些特性的值来自于用户访问的页面URL  Session信息, Session记录了用户采取的操作(例如从一个页面移动到另一个页面)的实时更新信息。

“跳出率”、“退出率”和“页面值”特性代表了由Google Analytics为电子商务网站中的每个页面计算出来的指标。跳出率是指仅阅读了一个页面就离开的用户占一组页面或一个页面拜访次数的百分比。 跳出次数是指拜访者不拜访您网站的其他任何一页便从进入页退出的次数。 所以跳出率的算法就是:阅读了一个页面就离开网站的次数/进入网站的次数= 跳出率。退出率指:某个时间段内,离开网页的次数占该网页总浏览次数的比例。 比如,今天开心推首页综合浏览量是1000次,从这个页面离开本站的次数是40次,则首页的退出率是4%。“网页价值”是用户在进入目标网页或完成电子商务交易(或两者)之前访问过的网页的平均价值。

“节假日”属性表示网站访问时间接近某个特定的日子(如母亲节、情人节),在这一天附近会更有可能最终完成交易。

数据集还包括“操作系统类型”、“浏览器类型”、“区域”、“流量类型”、“访客类型”(老访客或新访客)、“周末”。

总之就是18个X,一个y,x代表用户浏览的时候的一些信息还有一些时间设备地区等基础信息。

需要这个演示数据和全部代码的同学可以参考:购买行为数据


Stacking模型介绍

所谓的Stacking就是通过模型对原数据拟合的堆叠进行建模,他首先通过基学习器学习原数据,然后这几个基学习器都会对原数据进行输出,然后将这几个模型的输出按照列的方式进行堆叠,构成了 ( m , p ) (m,p)(m,p) 维的新数据,m代表样本数,p代表基学习器的个数,然后将新的样本数据交给第二层模型进行拟合。

但是这样模型往往会过拟合,所以将上述方法进行改进,使用K折交叉验证的方式,不同的地方就是上面的示意图每个模型训练了所有的数据,然后输出y形成新的数据,使用K折交叉验证,每次只训练k-1折,然后将剩下1折的预测值作为新的数据,这就有效的防止了过拟合。

如果每个模型训练所有的数据,然后再用这个模型去预测y值,那么生成新数据的y非常精确和真实值差不多,为了增强模型的泛化能力,我们每次只训练其中一部分数据,然后用剩余一部分数据进行预测。

首先利用K折交叉验证,将数据分成4折切分,那么就会形成4组数据集,其中黄色代表训练集,绿色的为验证集,然后将每组的训练集交给模型进行训练,然后对验证集进行预测,就会得到对应验证集的输出,因为4折交叉验证,将数据分成4组,所以我们会形成4个验证集,然后将每个模型对各自组的验证集预测的结果进行按照行的方式堆叠,就会获得完整样本数据的预测值,这只是针对于一个模型,不同学习器同理,每个模型按照这个方式获得预测值,然后再将其按照列合并。

不过实际使用没这么复杂,skleran里面全部有现成的类,很简单看下面我怎么用的就行。


代码实现

数据准备

数据分析还是先导入包:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import seaborn as sns 
#%matplotlib inline
plt.rcParams['font.sans-serif'] = ['KaiTi']  #中文
plt.rcParams['axes.unicode_minus'] = False   #负号

读取数据

df=pd.read_csv('./6-数据集/train.csv',na_values=['NA', 'NAN']) 
df.head()

查看数据的基础信息

df.info()

可以看到每个变量的类别是非空值的数量,缺失值是存在的,但是不多。#有几个变量存在略微的缺失值。


数据清洗和整理

缺失值填充

缺失值不多,那就用前一个有效值进行填充算了。

df=df.fillna(method='pad')  #前一个有效值进行填充

特征工程

我们要对文本的特征进行转化

#' 访客类型 ',' 月份',' 周末'这三个变量是文本型,需要进行处理

#对月份进行处理,映射为数值
d_month={'May': 5, 'Nov': 11, 'Mar': 3, 'Dec': 12, 'Oct': 10, 'Sep': 9, 'Aug': 8, 'Jul': 7, 'June': 6, 'Feb': 2}
df['月份']=df['月份'].map(d_month)

#周末变为0和1的虚拟变量

df['周末']=(df['周末']*1).astype('int')

#访客类型,生成哑变量

df=pd.get_dummies(df)

查看处理后的数据信息

df.info()

#所有变量都为数值型,可以直接计算,没有缺失值

然后取出X和y

#取出X和y
y=df['是否购买']
df.drop(['是否购买'],axis=1,inplace=True)
X=df.copy()
print(X.shape,y.shape)

可以看到是8631条数据,X19列,y一列。


数据探索

清洗完成后,我们开始探索数据特点

y.value_counts(normalize=True)

这是y的分布,大部分客户还是没有购买的,数据里面只有15%的客户发生了购买行为。

画图查看

# 查看y的分布
#分类问题
plt.figure(figsize=(4,2),dpi=128)
plt.subplot(1,2,1)
y.value_counts().plot.bar(title='响应变量柱状图图')
plt.subplot(1,2,2)
y.value_counts().plot.pie(title='响应变量饼图')
plt.tight_layout()
plt.show()

分析X,对x画核密度图,查看分布特点

#查看特征变量的核密度分布
dis_cols = 4                   #一行几个
dis_rows = 4
plt.figure(figsize=(3*dis_cols, 2*dis_rows),dpi=128)
for i in range(16):
    plt.subplot(dis_rows,dis_cols,i+1)
    sns.kdeplot(X[X.columns[i]], color="tomato" ,fill=True)
    #plt.xlabel((y.unique().tolist()),fontsize=12)
    plt.ylabel(df.columns[i], fontsize=12)
plt.tight_layout()
plt.show()

很多分布都是偏态的。 


相关系数热力图

corr = plt.subplots(figsize = (10,10),dpi=128)
corr= sns.heatmap(X.iloc[:,:16].assign(Y=y).corr(),annot=True,fmt='.2f',square=True)

X和y的相关性都不是很高的亚子。


开始机器学习 

#划分训练集和验证集

from sklearn.model_selection import train_test_split
X_train,X_val,y_train,y_val=train_test_split(X,y,test_size=0.2,random_state=0)

数据标准化

#数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train_s = scaler.transform(X_train)
X_val_s = scaler.transform(X_val)
#X2_s=scaler.transform(data2)
print('训练数据形状:')
print(X_train_s.shape,y_train.shape)
print('验证集数据形状:')
print(X_val_s.shape,y_val.shape)

#采用八种机器学习模型对比准确率

from sklearn.linear_model import LogisticRegression
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
from sklearn.ensemble import StackingClassifier

实例化

#逻辑回归
model1 =  LogisticRegression(C=1e10,max_iter=10000)
 
#线性判别
model2 =  LinearDiscriminantAnalysis()
 
#K近邻
model3 = KNeighborsClassifier(n_neighbors=20)
 
#决策树
model4 = DecisionTreeClassifier(random_state=77)
 
#随机森林
model5= RandomForestClassifier(n_estimators=500,  max_features='sqrt',random_state=10)
 
#梯度提升
model6 = GradientBoostingClassifier(random_state=123)
 
#支持向量机
model7 = SVC(kernel="rbf", random_state=77)
 
#神经网络
model8 = MLPClassifier(hidden_layer_sizes=(16,8), random_state=77, max_iter=10000)
 
model_list=[model1,model2,model3,model4,model5,model6,model7,model8]
model_name=['逻辑回归','线性判别','K近邻','决策树','随机森林','梯度提升','支持向量机','神经网络']

单独创建stacking模型作为model9

# 创建 stacking 模型
estimators = [
    ('逻辑回归', model1),
    ('线性判别', model2),
    ('K近邻', model3),
    ('决策树', model4),
    ('随机森林', model5),
    ('梯度提升', model6),
    ('支持向量机', model7),
    ('神经网络', model8)
]

stacking_model = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())

model_list.append(stacking_model)
model_name.append('Stacking模型')

print(model_list)
print(model_name)


可以看到,stacking模型把我前面8个模型全部都涵盖进去了。

#定义评价指标计算函数

from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import cohen_kappa_score

def evaluation(y_test, y_predict):
    accuracy=classification_report(y_test, y_predict,output_dict=True)['accuracy']
    s=classification_report(y_test, y_predict,output_dict=True)['weighted avg']
    precision=s['precision']
    recall=s['recall']
    f1_score=s['f1-score']
    #kappa=cohen_kappa_score(y_test, y_predict)
    return accuracy,precision,recall,f1_score #, kappa


拟合模型,计算指标

df_eval=pd.DataFrame(columns=['Accuracy','Precision','Recall','F1_score'])
for i in range(len(model_list)):
    print(f'{model_name[i]}训练中...')
    model_C=model_list[i]
    name=model_name[i]
    model_C.fit(X_train_s, y_train)
    pred=model_C.predict(X_val_s)
    s=classification_report(y_val, pred)
    s=evaluation(y_val,pred)
    df_eval.loc[name,:]=list(s)

查看计算的评价指标

df_eval

可以看到,基础模型里面,准确率最好的市随机森林,但是在表示综合来看的F1值,stack模型比其他模型都稍微好一点点。看来stacking,融合还是有效的。

画图可视化

bar_width = 0.4
colors=['c', 'b', 'g', 'tomato', 'm', 'y', 'lime', 'k','orange','pink','grey','tan']
fig, ax = plt.subplots(2,2,figsize=(10,8),dpi=128)
for i,col in enumerate(df_eval.columns):
    n=int(str('22')+str(i+1))
    plt.subplot(n)
    df_col=df_eval[col]
    m =np.arange(len(df_col))
    plt.bar(x=m,height=df_col.to_numpy(),width=bar_width,color=colors)
    
    #plt.xlabel('Methods',fontsize=12)
    names=df_col.index
    plt.xticks(range(len(df_col)),names,fontsize=10)
    plt.xticks(rotation=40)
    plt.ylabel(col,fontsize=14)
    
plt.tight_layout()
#plt.savefig('柱状图.jpg',dpi=512)
plt.show()

本来想#利用K折交叉验证搜索最优超参数

from sklearn.model_selection import KFold, StratifiedKFold
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV

但是stacking模型参数太多了,他包含8个基础机器学习模型的所有参数,所以就算了,。。简单计算一些混淆矩阵好了

stacking_model = StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())#, stack_method='predict_proba'
stacking_model.fit(X_train_s, y_train)
pred_stack=stacking_model.predict(X_val_s)

打印混淆矩阵

print(classification_report(y_val, pred_stack))


画混淆矩阵和计算AUC

上面是打印,下面可视化

from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_estimator(stacking_model, X_val_s, y_val,cmap='Blues')
plt.tight_layout()

AUC图

from sklearn.metrics import RocCurveDisplay
RocCurveDisplay.from_estimator(stacking_model, X_val_s, y_val)
x = np.linspace(0, 1, 100)
plt.plot(x, x, 'k--', linewidth=1)
plt.title('ROC Curve (Test Set)')

AUC的值

from sklearn.metrics import roc_auc_score
roc_auc_score(y_val,stacking_model.predict_proba(X_val_s)[:,1])

##使用该模型在全部数据上进行训练,作为最终的预测模型

#利用找出来的最优超参数在所有的训练集上训练,然后预测
model=StackingClassifier(estimators=estimators, final_estimator=LogisticRegression())
model.fit(np.r_[X_train_s,X_val_s],np.r_[y_train,y_val])  #使用所有数据训练
pred=model.predict(np.r_[X_train_s,X_val_s])
evaluation(np.r_[y_train,y_val],pred)

得到的模型然后储存下来

import joblib # 保存模型文件
joblib.dump(model, "train_model.m")

好,得到了模型文件了。

下次我们有测试集数据后,就直接预测。


对测试集预测

#读取训练好的模型

import joblib
mode= joblib.load("train_model.m")
#读取数据,和上面一样处理
df1=pd.read_csv('./6-数据集/test1.csv',na_values=['NA', 'NAN'],encoding='ANSI') 
df1.head()

可以看到和训练集是一模一样,但是少了一列y,也就是我们需要预测的y。

前面的特征工程都同样要处理:

df1=df1.fillna(method='pad')  #前一个有效值进行填充
#对月份进行处理,映射为数值
d_month={'May': 5, 'Nov': 11, 'Mar': 3, 'Dec': 12, 'Oct': 10, 'Sep': 9, 'Aug': 8, 'Jul': 7, 'June': 6, 'Feb': 2,'Jan':1,'Apr':4}
df1['月份']=df1['月份'].map(d_month)
#周末变为0和1的虚拟变量
df1['周末']=(df1['周末']*1).astype('int')
#访客类型,生成哑变量
df1=pd.get_dummies(df1)
for col in df.columns:
    if col not in df1.columns:
        df1[col]=0
df1.shape

标准化

X2=df1[df.columns]
X2_s = scaler.transform(X2)

 预测,然后查看分布

predictY=model.predict(X2_s)
d=pd.DataFrame()
d['pred']=predictY
d['pred'].value_counts(normalize=True)

也和训练集差不多的比例。

储存预测结果,就可以提交了。

d.to_csv('Results.csv',encoding='utf-8',index=False,header=False)


 创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制类似的代码可私信)

  

标签:plt,val,Python,模型,45,df,import,model,电商
From: https://blog.csdn.net/weixin_46277779/article/details/139447611

相关文章

  • (免费领源码)Java/Mysql数据库+04770 基于Java的书籍借阅管理系统设计与实现,计算机毕业
    摘 要随着科学技术的告诉发展,我们已经步入数字化、网络化的时代。图书馆是学校的文献信息中心,是为全校教学和科学研究服务的学术性机构,是学校信息化的重要基地。图书馆的工作是学校和科学研究工作的重要组成部分,是全校师生学习和研究的重要场所。为了提高图书馆的工作效率......
  • (免费领源码)Java/Mysql数据库+04827基于PHP的高校二手物品交易系统的设计与实现,计算机
    本科生毕业论文(设计) 题   目PHP高校二手物品交易系统学   院       XXXXX     专业班级   XXXXX学生姓名       XXXX    指导教师            XXXX          撰写日期:2022年5月10日目 录摘......
  • Python怎么样, Python能做什么,可以自学Python吗?最全面Python教程
    短时间掌握一门技能是现代社会的需求。生活节奏越来越快,现在不是大鱼吃小鱼,而是快鱼吃慢鱼的时代,人的时间比机器的时间更值钱。Python作为一种轻量级编程语言,语言简洁开发快,没那么多技巧,受到众多追捧。如今,Pyhon越来越火,屡次超越Java、C++成为编程语言排行榜第一的语言,国内的......
  • Python break 语句
    Pythonbreak语句,就像在C语言中,打破了最小封闭for或while循环。break语句用来终止循环语句,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句。break语句用在while和for循环中。如果您使用嵌套循环,break语句将停止执行最深层的循环,并开始执行下一行代码......
  • Python项目代码太多if-else? 这样优化才优雅!
    前言代码中不可避免地会出现复杂的if-else条件逻辑,而简化这些条件表达式是一种提高代码可读性极为实用的技巧。在Python中,有多种方法可以避免复杂的if-else条件逻辑,使代码更加清晰和易于维护。筑基期提前return,去掉多余的else在Python中,使用"提前返回"(early......
  • (十五)统计学基础练习题九(选择题T401-450)
    本文整理了统计学基础知识相关的练习题,共50道,适用于想巩固统计学基础或备考的同学。来源:如荷学数据科学题库(技术专项-统计学三)。序号之前的题请看往期文章。401)402)403)404)405)406)407)408)409)410)411)412)413)414)415)416)417)418)419)420)421)422)......
  • Python Socket编程:从原理到实践
    在当今的网络世界中,Socket编程是构建网络通信应用的关键技术之一。从简单的聊天应用到复杂的分布式系统,Socket编程都扮演着至关重要的角色。本文将首先介绍Socket编程的基本原理,然后详细讲解如何使用Python进行Socket编程。注意:文中谈到的TCP/IP协议可以去我另一篇文章看一下,......
  • Python案例
    音乐播放器importtkinterastkimporttkinter.filedialogimportosfrompygameimportmixerclassMusicPlayer:def__init__(self,root):self.root=rootself.root.title("MusicPlayer")self.root.geometry("300x100&......
  • [轨迹规划实操] 横向优化算法+纵向DP算法的python复现(2)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言纵向速度规划1.对路程和时间进行采样2.计算代价函数3.选出最小代价的点进行回溯4.实验结果前言本文采用基于优化的横向规划方法和基于动态规划的纵向规划方法横向优化控制详见第一......
  • 使用Venv创建Python的虚拟环境
    创建虚拟环境python3-mvenv<directory_name>激活虚拟环境source<directory_name>/bin/active检查当前使用的是哪个Python下面这条命令会输出当前使用Python环境的目录:whichpython配置好之后使用pip安装的库就会默认放在这个环境中停用当前环境deactivate重启环......