承接上一篇案例电商直播间提取的特征,进而做一篇机器学习的案例,来预测直播间的成交金额。
Python数据分析案例39——电商直播间评论可视化分析(LDA)
1. 引言
1.1 直播电商与传统电商的比较
直播电商作为一种新兴的电子商务模式,与传统电商在多个方面展现出显著的差异。传统电商通常依赖于图文描述和用户评论来展示产品,而直播电商则利用实时视频直播的方式,通过主播的演示和解说来展示产品。这种形式增强了产品的展示效果,使消费者能更直观地了解产品。此外,直播电商的一个显著特点是其社交互动性,主播与观众之间的即时交流为消费者提供了实时咨询的机会,增强了购物体验的互动性和社交性。
1.2 社交互动功能对消费者购物体验的影响
社交互动功能是直播电商成功的关键因素之一。在直播过程中,消费者不仅可以观看产品展示,还可以通过弹幕、评论、点赞等方式与主播或其他观众互动。这种互动提高了用户的参与度和购买意愿。消费者的互动行为,如提问、评论和反馈,可以即时获得回应,这不仅增加了购物的乐趣,还帮助消费者做出更加明智的购买决策。
1.3 研究背景与意义
随着直播电商的迅速发展,对其销售模式的研究变得日益重要。先前的研究主要集中在销量预测和用户行为分析上,但对于直播间内部的互动行为及其对销售影响的深入研究仍相对有限。理解消费者在直播间内的互动行为对预测销量和优化销售策略具有重要意义。本研究旨在通过分析直播间的互动数据,探索消费者行为模式及其对销售的影响,以提供更准确的销量预测和更有效的销售策略。
2. 数据集描述
本研究旨在通过分析直播间的实时评论数据,深入探索消费者行为模式和兴趣偏好。研究主要关注于从评论数据中提取有效信息,并将这些信息与成交数据相结合,以揭示消费者行为与直播间销售效果之间的关系,从而做到销售量的预测。
数据集包括2023年9月期间两个直播间(RoomJ和RoomL)的40场次直播的实时评论与成交数据。数据粒度为分钟级。收集的数据变量主要包括:
live_room_id | 直播间ID |
time | 记录的时间点 |
live_comment | 直播评论内容 |
ONLINE_USER_CNT | 在线用户数量 |
follow_anchor_ucnt | 关注主播的用户数量 |
fans_club_join_ucnt | 加入粉丝团的用户数量 |
pay_combo_cnt | 成交件数 |
pay_ucnt | 成交人数 |
pay_amt | 成交金额 |
其中live_comment是非标准的数据,主要是评论用户的信息,我们需要对评论内容进行解析和处理。为了准确预测销售量,构建有效的特征变量,从评论信息我们从中抽取了新的四个特征值,分别是comment_count代表该时间点的评论数量,该时间点的评论平均长度是avg_comment_length,最后是该时间点的评论的情感系数值sentiment,和主播账户是否发言open,该四个变量能更好的帮助模型预测直播间的销售量。
需要这代码演示数据和全部代码文件的同学可以参考:电商直播间预测数据
3. 数据探索
先导入包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import jieba
plt.rcParams ['font.sans-serif'] ='SimHei' #显示中文
plt.rcParams ['axes.unicode_minus']=False #显示负号
读取数据,我们将直播间J和直播间L的数据进行合并,删除不能算的文本和时间对象,
data = pd.read_csv('预测RoomJ.csv',parse_dates=['time']).set_index('time')
data = data.loc[:, ~data.columns.str.contains('Unnamed')]
data2 = pd.read_csv('预测RoomL.csv',parse_dates=['time']).set_index('time')
data2 = data2.loc[:, ~data2.columns.str.contains('Unnamed')]
data=pd.concat([data,data2],axis=0)
data.head(3)
3.1 数据描述性统计
先看数据基础信息
data.info()
都是数值型数据,第一列有点缺失值。
#观察缺失值
import missingno as msno
msno.matrix(data)
数据集大小和完整性:数据集共有 10432 条记录,每条记录包含 10 个特征。
特征 ONLINE_USER_CNT 拥有较少的非空值(9917),这可能意味着这个字段在某些记录中缺失。这需要在数据预处理阶段进行处理,比如通过插值、删除缺失值所在的行或采用其他适合的方法。数据类型:大部分特征(follow_anchor_ucnt, fans_club_join_ucnt, pay_combo_cnt, pay_ucnt, pay_amt, comment_count, open)是整数型(int64),这表明这些数据是计数或分类数据。ONLINE_USER_CNT, avg_comment_length, sentiment 是浮点数(float64),表示它们可能包含更精细的量化信息,例如平均值或比率。
变量的描述性统计信息如下
np.round(data.describe(),2)
ONLINE_USER_CNT(在线用户数):平均值为 450.72,但标准差为 504.66,表明数据分布的波动性很大。最高在线用户数为 4783,最低仅为 4,这可能意味着某些直播非常受欢迎,而其他则参与度较低。follow_anchor_ucnt(关注主播用户数):平均关注用户数为 845.28,但标准差高达 1364.46,说明关注数量在不同主播间差异显著。最高关注用户数为 8181,最低为 0。fans_club_join_ucnt(粉丝俱乐部加入用户数):平均加入用户数为 51.3,标准差为 94.76。这表明虽然某些主播的粉丝俱乐部有较高的加入率,但总体上加入粉丝俱乐部的用户数量较少。pay_combo_cnt(支付组合数量):平均支付组合数量为 1170.96,但其标准差为 1527.22,反映了在不同直播间支付组合数量的巨大差异。pay_ucnt(支付用户数):平均支付用户数为 1061.51,标准差为 1450.90,说明在不同的直播中,参与支付的用户数量差异很大。pay_amt(支付金额):平均支付金额为 11377464.57,标准差为 15014470.57,表示某些直播的销售额非常高,而其他的则相对较低。comment_count(评论数量):平均评论数量为 10.96,但标准差为 14.86,表明用户参与度在不同的直播间有显著差异。avg_comment_length(平均评论长度):平均评论长度为 10.00,标准差为 6.36。这个数据显示了评论的普遍简洁性。sentiment(情感):平均情感分数为 0.45,标准差为 0.40,范围从 0(最负面)到 1(最正面),这可能反映了用户评论的整体情感倾向。
数据显示在在线用户数、关注用户数、支付用户数等方面存在显著的波动,这可能与直播内容的吸引力、主播的人气或其他市场因素有关。高支付金额的直播往往与较高的用户参与度(如评论数量和支付用户数)相关联,但也存在一些例外。用户情感倾向与销售成绩之间的关系不明确,需要更深入的分析来探索这一关联。
3.2 初步的数据可视化
然后对整体的数据框进行初步的信息探索,画箱线图。
#查看特征变量的箱线图分布
columns = data.columns.tolist() # 列表头
dis_cols = 4 #一行几个
dis_rows = len(columns)
plt.figure(figsize=(4 * dis_cols, 4 * dis_rows))
for i in range(len(columns)):
plt.subplot(dis_rows,dis_cols,i+1)
sns.boxplot(data=data[columns[i]], orient="v",width=0.5)
plt.xlabel(columns[i],fontsize = 20)
plt.tight_layout()
#plt.savefig('特征变量箱线图',formate='png',dpi=500)
plt.show()
-
ONLINE_USER_CNT:在线用户数量的中位数相对较低,但是有很多异常值,显示出某些时间点在线用户数量远高于其他时间。
-
follow_anchor_ucnt:关注主播的用户数量也呈现出相似的分布,中位数较低,异常值较多。
-
fans_club_join_ucnt:粉丝俱乐部加入的用户数量的分布与上述两个变量相似,但异常值相对较少。
-
pay_ucnt:付费用户数量的分布显示,大部分的时间点付费用户数量较少,但也存在一些高峰值。
-
pay_amt:付费金额的分布情况表明,尽管大多数时间点的付费金额不高,但有一些非常高的异常值。
-
pay_combo_cnt:组合支付次数的分布表明,大多数时间点的组合支付次数都较低,但仍然有一些异常高的支付次数。
-
comment_count:评论数量的中位数很低,但有大量的异常值,表明某些情况下评论活动非常活跃。
-
avg_comment_length:平均评论长度的分布较为集中,但也有一些较长评论的异常值。
-
sentiment:情感倾向分布较为集中且无异常值,这可能表明大部分时间用户的情感倾向是相对稳定的。
-
open:此变量的箱线图看起来像一个正方形,可能表明数据非常集中,没有变化,或者每个点的值都相同
对应的核密度图:
#画密度图,训练集和测试集对比
dis_cols = 4 #一行几个
dis_rows = len(columns)
plt.figure(figsize=(4 * dis_cols, 4 * dis_rows))
for i in range(len(columns)):
ax = plt.subplot(dis_rows, dis_cols, i+1)
ax = sns.kdeplot(data[columns[i]], color="Red" ,fill=True)
#ax = sns.kdeplot(data2[columns[i]], color="Blue",warn_singular=False,fill=True)
ax.set_xlabel(columns[i],fontsize = 20)
ax.set_ylabel("Frequency",fontsize = 18)
ax = ax.legend(["train", "test"])
plt.tight_layout()
#plt.savefig('训练测试特征变量核密度图',formate='png',dpi=500)
plt.show()
和前面的结论差不多。
我们选择有代表性的['ONLINE_USER_CNT', 'pay_combo_cnt', 'pay_ucnt', 'pay_amt']这四个变量画出其核密度图,观察其分布特点:
#sns.set(style="whitegrid")
# 关键字段列表
key_columns = ['ONLINE_USER_CNT', 'pay_combo_cnt', 'pay_ucnt', 'pay_amt']
# 绘制关键字段的分布图
plt.figure(figsize=(10, 6),dpi=256)
for i, column in enumerate(key_columns):
plt.subplot(2, 2, i+1)
sns.histplot(data[column], kde=True)
plt.title(f'{column}')
plt.xlabel(column)
plt.ylabel('Frequency')
plt.tight_layout()
plt.show()
ONLINE_USER_CNT(在线用户数):分布呈现出右偏(正偏态),绝大部分的直播观看人数集中在较低的区间,但也有少数直播时间的在线用户数非常高。这表明大部分直播时间的吸引力有限,而只有少数直播的时候,可能是活动期间能够吸引大量观众。
pay_combo_cnt(支付组合数量):同样呈现出右偏分布。大多数直播的支付组合数量较低,但有少数直播的支付组合数量远高于平均水平。这可能表明对于大部分直播来说,用户倾向于购买较少的商品组合,但也存在着一些高销量的异常值。
pay_ucnt(支付用户数):支付用户数的分布与上述两个变量相似,也是右偏的。大部分直播的购买用户数量不多,但有少数直播能吸引大量购买用户。这种分布可能暗示了用户购买意愿与直播内容或推广活动的相关性。
pay_amt(支付金额):支付金额的分布极为右偏,这是上述所有图中最明显的。大多数直播时间的总销售额较低,但有极少数直播时间实现了非常高的销售额。这种极端的不平衡分布可能指出,虽然大部分直播的经济效益有限,但一小部分直播时间能够产生巨大的销售和利润。
整体分析与建议:这四个变量的分布都显示了市场上存在极大的不平衡,即“长尾效应”,其中少数直播时间能够吸引大量用户并实现高销售额,而大多数直播时间则表现平平。
在预测电商直播的销售量时,应特别关注那些能夜吸引大量在线用户和支付用户的直播时间和活动。这可能需要分析直播内容的特点、主播的影响力、以及用户的购买行为模式。
考虑到右偏的分布特点,可能需要利用非线性模型来更好地预测销售量,例如使用决策树或随机森林来处理这种非对称性。此外,考虑到少数直播的销售额远高于其他,异常值处理也将是预测准确性的关键。
我们将在线人数和成交金融画出散点图观察其相关性:
# 绘制ONLINE_USER_CNT与pay_amt之间的关系
plt.figure(figsize=(8, 6))
sns.scatterplot(x='ONLINE_USER_CNT', y='pay_amt', data=data)
plt.title('Relationship between ONLINE_USER_CNT and pay_amt')
plt.xlabel('ONLINE_USER_CNT')
plt.ylabel('pay_amt')
plt.show()
绘制重要的变量与pay_amt的散点图
fig, axes = plt.subplots(2, 2, figsize=(7,7),dpi=128)
# 绘制每个变量与pay_amt的散点图
sns.scatterplot(x=data.columns[0], y='pay_amt', data=data, ax=axes[0, 0])
sns.scatterplot(x=data.columns[1], y='pay_amt', data=data, ax=axes[0, 1])
sns.scatterplot(x=data.columns[2], y='pay_amt', data=data, ax=axes[1, 0])
sns.scatterplot(x=data.columns[3], y='pay_amt', data=data, ax=axes[1, 1])
# 调整子图间距
plt.tight_layout()
# 显示图表
plt.show()
相关性:散点图显示了在线用户数和成交金额之间的正向关联。可以观察到随着在线用户数的增加,成交金额也有增加的趋势,尽管这种关系不是严格的线性关系。
数据分布:大部分数据点集中在图的左下角,即在线用户数和成交金额都较低的区域。这与之前核密度图的分析相符,大多数直播的观众数量和销售额较低。
异常值:有些数据点显示了非常高的成交金额,即使在线用户数并不是最高的。这可能表明有些直播的转化率(即用户购买的可能性)非常高,或者有较高单价的商品被销售。
集群现象:数据中似乎存在几个不同的“集群”,特别是在成交金额较高的区域。这可能表明某些直播活动具有特殊的吸引力或销售策略,从而实现了较高的成交金额。
变化趋势:尽管在线用户数与成交金额之间存在正相关性,但该关系的变化趋势并非均匀。例如,在较低的在线用户数区间,成交金额的增长较为缓慢;而在用户数较高的区间,成交金额的增长则更为显著。
数据表明,增加在线用户数可能是提高成交金额的一个途径,但也暗示了单纯的用户数量增长并不一定直接转化为销售额的增加。可能存在很多高净值客户,他们人数少却能创造很大的成交金额。
3.3 相关性分析
所有变量的相关性热力图如下:
corr = plt.subplots(figsize = (12,10),dpi=128)
corr= sns.heatmap(data.corr(),annot=True,square=True)
#plt.savefig('训练集特征热力图.png',dpi=512)
从图中我们可以得知,高度相关的变量:pay_combo_cnt(支付组合数量)与 follow_anchor_ucnt(关注主播用户数)和 pay_ucnt(支付用户数)显示出非常高的相关性(接近 1),这表明关注主播的用户更倾向于进行购买。pay_amt(支付金额)与 follow_anchor_ucnt、pay_combo_cnt 和 pay_ucnt 也呈现出非常高的相关性,这说明成交金额与支付用户数、关注主播用户数和支付组合数量强相关。
中度相关的变量:ONLINE_USER_CNT(在线用户数)与 comment_count(评论数量)有中度正相关(0.68),指出在线用户越多,评论活动也越频繁。sentiment(情感)与大多数变量呈负相关,尤其是与 pay_amt(-0.093),这可能表明情感评分较低的评论并不一定与低销售额直接相关联。
低度或无显著相关的变量:avg_comment_length(平均评论长度)与其他变量大多没有显著相关性,最高的相关性是与 sentiment(0.47),这可能意味着评论的长度与其情感倾向有一定的联系。
鉴于相关性热力图显示的信息,我们发现销售金额和成交件数和成交人数都是线性相关的,这说明他们本质上可以看为一个变量。在后续进行成交量预测的时候需要处理。
4. 数据预处理
填充一下缺失值
data.fillna(method='ffill',inplace=True)
4.1 特征构造和特征选择
分开x和y,对x进行异常值的观察。
本文从评论中构建了四个新特征,然后发现直播的时间也和成交量有一定的影响,所以我们提出每个直播的时间小时h作为一个新特征。然后pay_combo_cnt,pay_ucnt,pay_amt三个变量本质来说是一个变量,我们选择使用pay_amt作为响应变量,其他两个变量删除。
4.2 异常值处理
在本项目中,我们采用了标准化(Standardization)方法来对数据进行转化。标准化处理后,每个特征的数据将会具有0的均值(mean)和1的标准差(standard deviation)
实施数据标准化之后,我们将能够更准确地评估不同特征对电商直播销售量预测的贡献,从而构建一个效果更好、更稳健的预测模型。此外,这还有助于识别出哪些特征对于预测任务来说是冗余的,从而可能在模型简化和特征选择过程中被去除。
data['hour']=pd.Series(data.index).dt.hour.to_numpy()
y=data['pay_amt'].reset_index(drop=True)
X=data[['ONLINE_USER_CNT', 'follow_anchor_ucnt', 'fans_club_join_ucnt','comment_count',
'avg_comment_length', 'sentiment', 'open','hour']].reset_index(drop=True)
#X异常值处理,先标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_s = scaler.fit_transform(X)
plt.figure(figsize=(20,8))
plt.boxplot(x=X_s,labels=X.columns)
#plt.hlines([-10,10],0,len(columns))
plt.show()
可以看到有点变量存在一些异常值,需要处理。
#异常值多的列进行处理
def deal_outline(data,col,n): #数据,要处理的列名,几倍的方差
for c in col:
mean=data[c].mean()
std=data[c].std()
data=data[(data[c]>mean-n*std)&(data[c]<mean+n*std)]
#print(data.shape)
return data
X=deal_outline(X,['ONLINE_USER_CNT', 'follow_anchor_ucnt', 'fans_club_join_ucnt',
'comment_count', 'avg_comment_length'],6)
y=y[X.index]
X.shape,y.shape
# 查看y的分布
# 查看y的分布
#回归问题
plt.figure(figsize=(8,3),dpi=128)
plt.subplot(1,3,1)
y.plot.box(title='box')
plt.subplot(1,3,2)
y.plot.hist(title='hist')
plt.subplot(1,3,3)
y.plot.kde(title='kde')
#sns.kdeplot(y, color='Red', shade=True)
#plt.savefig('响应变量.png')
plt.tight_layout()
plt.show()
偏态
#处理y的异常值之后
y=y[y <= 80000000]
plt.figure(figsize=(8,3),dpi=128)
plt.subplot(1,3,1)
y.plot.box(title='box')
plt.subplot(1,3,2)
y.plot.hist(title='hist')
plt.subplot(1,3,3)
y.plot.kde(title='kde')
#sns.kdeplot(y, color='Red', shade=True)
#plt.savefig('响应变量.png')
plt.tight_layout()
plt.show()
对y进行异常值处理,筛选给x
#筛选给x
X=X.loc[y.index,:]
X.shape,y.shape
最终我们还剩下10209个样本,X有8个特征,开始进行机器学习建模预测。
4.3 划分训练集与验证集
#划分训练集和验证集
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)
我们采用28分发, 测试集20%的数据,训练集80%侧数据。
#数据标准化
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)
print('训练数据形状:')
print(X_train_s.shape,y_train.shape)
print('验证数据形状:')
(X_val_s.shape,y_val.shape)
我们采用十种常用的机器学习模型['线性回归','惩罚回归','K近邻','决策树','随机森林','梯度提升'] 进行训练,然后查看他们在测试集上的表现。
使用sklearn库直接进行训练呢拟合,然后再测试集上进行评分计算。
#模型训练
#采用十种模型,对比验证集精度
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import ElasticNet
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from xgboost.sklearn import XGBRegressor
from lightgbm import LGBMRegressor
from sklearn.svm import SVR
from sklearn.neural_network import MLPRegressor
定义评价指标
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error,r2_score
from sklearn.model_selection import KFold
def evaluation(y_test, y_predict):
mae = mean_absolute_error(y_test, y_predict)
mse = mean_squared_error(y_test, y_predict)
rmse = np.sqrt(mean_squared_error(y_test, y_predict))
#mape=(abs(y_predict -y_test)/ y_test).mean()
r_2=r2_score(y_test, y_predict)
return mae, mse ,rmse, r_2 #mse
模型都装入列表,然后准备拟合
#线性回归
model1 = LinearRegression()
#弹性网回归
model2 = ElasticNet(alpha=0.05, l1_ratio=0.5)
#K近邻
model3 = KNeighborsRegressor(n_neighbors=10)
#决策树
model4 = DecisionTreeRegressor(random_state=77,max_depth=5)
#随机森林
model5= RandomForestRegressor(n_estimators=500, max_features=int(X_train.shape[1]/3) , random_state=0)
#梯度提升
model6 = GradientBoostingRegressor(n_estimators=500,random_state=123)
#极端梯度提升
model7 = XGBRegressor(objective='reg:squarederror', n_estimators=1000, random_state=0)
#轻量梯度提升
model8 = LGBMRegressor(n_estimators=1000,objective='regression', # 默认是二分类
random_state=0)
#支持向量机
#model9 = SVR(kernel="rbf")
#神经网络
model9 = MLPRegressor(hidden_layer_sizes=(64,16), random_state=77, max_iter=15000)
model_list=[model1,model2,model3,model4,model5,model6,model7,model8,model9]
model_name=['线性回归','惩罚回归','K近邻','决策树','随机森林','梯度提升','极端梯度提升','轻量梯度提升','神经网络']
计算,模型拟合,预测。计算评价指标,转入表
df_eval=pd.DataFrame(columns=['MAE','RMSE','MSE','R2'])
for i in range(len(model_list)):
model_C=model_list[i]
name=model_name[i]
model_C.fit(X_train_s, y_train)
y_pred=model_C.predict(X_val_s)
df_eval.loc[f'{name}',:]=list(evaluation(y_val, y_pred))
#print(name+'方法在验证集的准确率为:'+str(s))
查看结果
df_eval
进行可视化:
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()
可以看到,随机森林,xgboost,LGBM,这三个模型最好。
一般来说,对于这种表格数据,集成模型方法都是最好的,也就是XGB,LGBM,RF等。前人的经验也都是这样说的。使用后面交叉验证我们只选三个模型,随机森林,极端梯度提升,轻量梯度提升。
4.4交叉验证选出最好的模型
def evaluation2(lis):
array=np.array(lis)
return array.mean() , array.std()
def cross_val(model=None,X=None,Y=None,K=5,repeated=1):
df_mean=pd.DataFrame(columns=['R2','MAE','RMSE','MSE'])
df_std=pd.DataFrame(columns=['R2','MAE','RMSE','MSE'])
for n in range(repeated):
print(f'正在进行第{n+1}次重复K折.....随机数种子为{n}\n')
kf = KFold(n_splits=K, shuffle=True, random_state=n)
R2=[]
MAE=[]
RMSE=[]
MSE=[]
print(f" 开始本次在{K}折数据上的交叉验证.......\n")
i=1
for train_index, test_index in kf.split(X):
print(f' 正在进行第{i}折的计算')
X_train=X.values[train_index]
y_train=y.values[train_index]
X_test=X.values[test_index]
y_test=y.values[test_index]
model.fit(X_train,y_train)
score=model.score(X_test,y_test)
R2.append(score)
pred=model.predict(X_test)
mae, rmse, mse,_=evaluation(y_test, pred)
MAE.append(mae)
RMSE.append(rmse)
MSE.append(mse)
print(f' 第{i}折的拟合优度为:{round(score,4)},MAE为{round(mae,4)},RMSE为{round(rmse,4)},MSE为{round(mse,4)}')
i+=1
print(f' ———————————————完成本次的{K}折交叉验证———————————————————\n')
R2_mean,R2_std=evaluation2(R2)
MAE_mean,MAE_std=evaluation2(MAE)
RMSE_mean,RMSE_std=evaluation2(RMSE)
MSE_mean,MSE_std=evaluation2(MSE)
print(f'第{n+1}次重复K折,本次{K}折交叉验证的总体拟合优度均值为{R2_mean},方差为{R2_std}')
print(f' 总体MAE均值为{MAE_mean},方差为{MAE_std}')
print(f' 总体RMSE均值为{RMSE_mean},方差为{RMSE_std}')
print(f' 总体MSE均值为{MSE_mean},方差为{MSE_std}')
print("\n====================================================================================================================\n")
df1=pd.DataFrame(dict(zip(['R2','MAE','RMSE','MSE'],[R2_mean,MAE_mean,RMSE_mean,MSE_mean])),index=[n])
df_mean=pd.concat([df_mean,df1])
df2=pd.DataFrame(dict(zip(['R2','MAE','RMSE','MSE'],[R2_std,MAE_std,RMSE_std,MSE_std])),index=[n])
df_std=pd.concat([df_std,df2])
return df_mean,df_std
首选计算轻量梯度提升lgbm模型
model = LGBMRegressor(n_estimators=500,objective='regression',random_state=0)
lgb_crosseval,lgb_crosseval2=cross_val(model=model,X=X,Y=y,K=3,repeated=5)
然后计算xgboost
model = XGBRegressor(n_estimators=500,objective='reg:squarederror',random_state=0)
xgb_crosseval,xgb_crosseval2=cross_val(model=model,X=X,Y=y,K=3,repeated=5)
随机森林
model = RandomForestRegressor(n_estimators=500, max_features=int(X_train.shape[1]/3) , random_state=0)
rf_crosseval,rf_crosseval2=cross_val(model=model,X=X,Y=y,K=3,repeated=5)
不同模型的效果均值对比
plt.subplots(1,4,figsize=(16,3))
for i,col in enumerate(lgb_crosseval.columns):
n=int(str('14')+str(i+1))
plt.subplot(n)
plt.plot(lgb_crosseval[col], 'k', label='LGB')
plt.plot(xgb_crosseval[col], 'b-.', label='XGB')
plt.plot(rf_crosseval[col], 'r-^', label='RF')
plt.title(f'不同模型的{col}对比')
plt.xlabel('重复交叉验证次数')
plt.ylabel(col,fontsize=16)
plt.legend()
plt.tight_layout()
plt.show()
黑色是LGB,很明显我们可以看到在拟合优度上LGB明显好于其他两个模型,其他三个误差指标上看,lgb都是最小的。四个指标都说明LGB最好。
不同模型的方差对比
plt.subplots(1,4,figsize=(16,3))
for i,col in enumerate(lgb_crosseval2.columns):
n=int(str('14')+str(i+1))
plt.subplot(n)
plt.plot(lgb_crosseval2[col], 'k', label='LGB')
plt.plot(xgb_crosseval2[col], 'b-.', label='XGB')
plt.plot(rf_crosseval2[col], 'r-^', label='RF')
plt.title(f'不同模型的{col}方差对比')
plt.xlabel('重复交叉验证次数')
plt.ylabel(col,fontsize=16)
plt.legend()
plt.tight_layout()
plt.show()
方差代表稳定性,可以看到三个模型的方差都差不多,稳定性都差不多。
并且在运行的时候,LGBM的时间是小于XGB小于随机森林的。
所以综合他们的表现效果、稳定性、运行时间来看——LGBM优于XGB优于RF。
最好的模型是LGBM!!,下面对它进行超参数搜索。
4.5 超参数搜索
#利用K折交叉验证搜索最优超参数
from sklearn.model_selection import KFold, StratifiedKFold
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV
# Choose best hyperparameters by RandomizedSearchCV
#随机搜索决策树的参数
param_distributions = {'max_depth': range(4, 10), 'subsample':np.linspace(0.5,1,5 ),'num_leaves': [15, 31, 63, 127],
'colsample_bytree': [0.6, 0.7, 0.8, 1.0]}
# 'min_child_weight':np.linspace(0,0.1,2 ),
kfold = KFold(n_splits=3, shuffle=True, random_state=1)
model =RandomizedSearchCV(estimator= LGBMRegressor(objective='regression',random_state=0,learning_rate= 0.05,n_estimators= 500),
param_distributions=param_distributions, n_iter=200)
model.fit(X_train_s, y_train)
最优参数
model.best_params_
最优参数模型预测
model = model.best_estimator_
model.score(X_val_s, y_val)
效果很好,99.5%准确率。
## 利用最好的参数模型,在所有的数据上进行训练
model=LGBMRegressor(objective='regression',subsample=0.75,learning_rate= 0.05,n_estimators= 500,num_leaves= 63,
max_depth= 9,colsample_bytree=1,random_state=0)
model.fit(X.to_numpy(),y.to_numpy())
model.score(X.to_numpy(), y.to_numpy())
变量重要性
reversed_sorted_index= model.feature_importances_.argsort()[::-1]
plt.figure(figsize=(6, 4),dpi=256)
sns.barplot(y=np.arange(X.shape[1]), x=model.feature_importances_[reversed_sorted_index], orient='h')
plt.yticks(np.arange(X.shape[1]), X.columns[reversed_sorted_index])
plt.xlabel('Feature Importance')
plt.ylabel('')
#plt.title('变量重要性')
plt.show()
可以看到对于成交量预测贡献最大的变量是关注数和加入粉丝团人数还有在线数量。我们自己构建的时间小时的指标表现也还不错。
5. 结论
通过对电商直播销售数据的综合分析,我们进行了数据描述图统计分析,变量的的可视化,相关性分析,异常值处理,特征工程的构建,再构建了机器学习模型训练拟合测试评价对比,我们可以得出以下结论:
关注主播用户数这是对成交销售量最重要的特征,其特征重要性远超其他变量。这表明主播的受欢迎程度对销售额有很大影响,关注数越多,可能意味着更高的用户参与度和购买意愿。加入粉丝团人数和在线人数都是一样的逻辑,它表明粉丝对主播的忠诚度也是销售量的一个重要预测因素。
用户参与度的重要性。数据显示,主播的受欢迎程度(如关注主播的用户数)和用户的参与度(如粉丝俱乐部加入的用户数)是影响销售量的关键因素。这强调了提高用户对直播内容的兴趣和参与度在电商直播中的重要性。
虽然评论数量在特征重要性中排名较低,但仍显示出与销售量的正相关性。这指出互动性是重要的,但可能不是唯一决定因素。
时间因素的次要作用:直播的具体时间(小时)特征的重要性也较高,这可能意味着用户参与和购买更多地受到内容质量和主播互动的影响,这和直播的具体时间也是对应的,一遍大家都是晚上看直播,然后会购物从而促进消费。
情感和评论质量的较低影响:论的平均长度和情感得分在特征重要性中排名较低,这表明这些因素可能不直接影响用户的购买决策。
非线性模式的识别:在构建的多个机器学习模型中,随机森林rf,极端梯度提升xgboost,轻量梯度提升lgbm等表现最佳,这表明销售数据中存在复杂的非线性关系,这些关系可以通过集成学习方法更有效地捕捉。
需要这代码演示数据和全部代码文件的同学可以参考:电商直播间预测数据
创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~