一、背景
小红书,是目前非常热门的电商平台。和其他电商平台不同,小红书是从社区起家。在小红书社区,用户通过文字、图片、视频笔记的分享,记录了这个时代年轻人的正能量和美好生活。
小红书通过机器学习对海量信息和人进行精准、高效匹配,已累积海量的海外购物数据,分析出最受欢迎的商品及全球购物趋势,并在此基础上把全世界的好东西,以最短的路径、最简洁的方式提供给用户。
本次的任务是协助小红书分析不同的业务决策所带来的销售额变化。
二、界定业务问题
预测用户的消费金额变化找到对用户消费影响较大的因素
三、数据收集与评估
#调包
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
#忽略报错
import warnings
warnings.filterwarnings("ignore")
plt.rcParams[font.sans-serif]=[Simhei]#显示中文
plt.rcParams[axes.unicode_minus]=False#显示负号
#读取数据
df=pd.read_csv("小红书数据.csv")
四、数据概况分析
df.info()
#查看缺失值
np.sum(df.isnull(),axis=0)
df.describe()
df.head(10)
小结:
共有8个字段,29452条数据;gender,engaged_last_30数据类型错误,需转为str;;gender、age、engaged_last_30存在缺失值,缺失率达到40%;age、engaged_last_30可使用0、均值、中位数填充;gender用unknown填充,再转化为哑变量;revenue和previous_order_amount存在极端值。
五、单变量分析
revenue
df.revenue.plot(kind=hist)
存在极端值
#查看<2000销售额分布
df[df.revenue<2000][revenue].plot(kind=hist)
#查看<500销售额分布
df[df.revenue<500][revenue].plot(kind=hist)
df[df.revenue<200].shape
(15589, 8)
df[df.revenue<500].shape
(22218, 8)
53%的销售额分布在2000以下;75%的销售额分布在500以下。
【判断离群值】
一般的,我们认定超过75%分位数 1.5倍的四分位差的数值为离群值。
四分位差: 75%分位数 - 25%分位数
sns.boxplot(y=revenue,data=df)
df.revenue.describe()
df.revenue.describe()[25%]
74.97
df.revenue.describe()[75%]
498.7725
diff=df.revenue.describe()[75%]-df.revenue.describe()[25%]
new_max=df.revenue.describe()[75%]+1.5*diff
new_max
1134.47625
df[df.revenue<1135].shape
(27286, 8)
存在7.35%的离群值
清洗>1135的离群值
df1 = df[df.revenue<=1135]
df1.revenue.describe()
经过清洗离群值后,购买金额75%分布在400元以下
gender
df1.gender.value_counts(dropna=False)#dropna=False查看NA的数据
df1.gender.value_counts(dropna=False).plot(kind=bar)
age
df1[age].plot(kind=hist,bins=100)
engaged_last_30
df1.engaged_last_30.value_counts(dropna=False)
lifecycle
df1[lifecycle].value_counts().plot(kind=bar)
days_since_last_order
df1[ days_since_last_order ].plot(kind=hist)
previous_order_amount
3rd_party_stores
df1[3rd_party_stores].value_counts().plot(kind=bar)
六、相关与可视化
a=df1.corr()[[revenue]].sort_values(revenue,ascending=False)
a
sns.heatmap(a)
sns.regplot(x=previous_order_amount,y=revenue,data=df1)
sns.regplot(x= days_since_last_order ,y=revenue,data=df1)
sns.barplot(x=engaged_last_30,y=revenue,data=df1)
sns.barplot(x=engaged_last_30,y=revenue,estimator=sum,data=df1)
sns.barplot(x=gender,y=revenue,data=df1)
sns.barplot(x=gender,y=revenue,estimator=sum,data=df1)
sns.regplot(x=age,y=revenue,data=df1)
sns.barplot(x=3rd_party_stores,y=revenue,data=df1)
sns.barplot(x=3rd_party_stores,y=revenue,estimator=sum,data=df1)
对销售额影响因素最大的以往累积购买金额;previous_order_amount、 days_since_last_order数值跨度很大;性别为女销售额明显高;只在自营产品购买的销售额明显高。
七、回归模型建立
1、数据处理
df2=df1.copy()
#缺失值处理 :gender-unknown填充
df2[gender]=df2[gender].fillna(unknown)
#缺失值处理 :age-o填充
df2[age]=df2[age].fillna(0)
#缺失值处理 :engaged_last_30-0填充
df2[engaged_last_30]=df2[engaged_last_30].fillna(0)
#转换数据类型
df2[gender]=df2[gender].astype(str)
df2[engaged_last_30]=df2[engaged_last_30].astype(str)
#哑变量
df2=pd.get_dummies(df2)
df2.info()
2、模型建立
#调包
from sklearn import datasets
#调取线性回归包工具
from sklearn.linear_model import LinearRegression
#建模
model=LinearRegression()
#设置自变量和因变量 ,本次先设previous_order_amount、days_since_last_order为自变量
x=df2[[previous_order_amount, days_since_last_order ]]
y=df2[revenue]
model.fit(x,y)
#查看斜率
model.coef_
#查看截距
model.intercept_
array([0.01841742, 5.00650081])
189.26109618921646
y=0.018 * previous_order_amount+5.0065 * days_since_last_order+189.26
3、模型评估
#计算y预测值
predictions=model.predict(x)
#计算误差
error=y-predictions
#计算mae
mae=abs(error).mean()
#计算rmse
rmse=(error**2).mean()**.5
#输出mae、rmse
print(mae)
print(rmse)
208.25098860671116
263.2688258746202
八、回归模型优化
1、模型优化
改变缺失值填充方式,age、engaged_last_30均值填充增加X变量 X=previous_order_amount、days_since_last_order、engaged_last_30、gender或者除revenue的所有列
#缺失值处理 :age、engaged_last_30-均值填充
df3=df1.copy()
df3[gender]=df3[gender].fillna(unknown)
df3[age]=df3[age].fillna(df3[age].mean())
df3[engaged_last_30]=df3[engaged_last_30].fillna(df3[engaged_last_30].mean())
#更改数据类型
df3[gender]=df3[gender].astype(str)
df3[engaged_last_30]=df3[engaged_last_30].astype(str)
#生成哑变量
df3=pd.get_dummies(df3)
df3.info()
#设置自变量和因变量 ,本次先设previous_order_amount、days_since_last_order为自变量
x=df3[[previous_order_amount, days_since_last_order ,engaged_last_30_0.0,engaged_last_30_1.0,engaged_last_30_0.0698705875205055,gender_0.0,gender_1.0,gender_unknown]]
y=df3[revenue]
model.fit(x,y)
#查看斜率
model.coef_
#查看截距
model.intercept_
array([ 1.80980666e-02, 4.90543842e+00, -2.38038702e+01, 2.68323878e+01, -3.02851755e+00, 1.03894426e+00, 1.98957329e+00, -3.02851755e+00])
204.57579835360295
#计算y预测值
predictions=model.predict(x)
#计算误差
error=y-predictions
#计算mae
mae=abs(error).mean()
#计算rmse
rmse=(error**2).mean()**.5
#输出mae、rmse
print(mae)
print(rmse)
207.88316933247887
263.00322131497086
进一步优化 ,X为除revenue的所有列
#模型的评估,x为除revenue列的所有列
x=df3.drop(revenue,axis=1)
y=df3[revenue]
model.fit(x,y)
predictions=model.predict(x)#计算y预测值
error=predictions-y#计算误差
rmse=(error**2).mean()**.5#计算rmse
mae=abs(error).mean()#计算mae
print(mae)
print(rmse)
206.8590215207069
262.14209518606816
2、标准模型输出表
from statsmodels.formula.api import ols
# x为除revenue列的所有列
x=df3.drop(revenue,axis=1)
y=df3[revenue]
# 用ols的方法根据store数据中已经设置好的X变量和y变量训练模型
model=ols(y~x,df3).fit()
#查看coef-系数、P值显著性等更加细致的模型特征
print(model.summary()
销售额=106.7028+0.348age+6.75521days_since_last_order+0.0161*previous_order_amount-
5.8082*3rd_party_stores+36.2225gender_0.0+37.0396gender_1.0+33.4406gender_unkonwn+
11.4798engaged_last_30_0.0+34.4406engaged_last_30_0.06980548991092529+61.7823engaged_last_30_1.0+
43.6289*lifecycle_A+39*lifecycle_B+24.0739*lifecycle_C
3、业务解读
最近一次距今下单天数每增加1天,可以得到6.755元的销售额回报;不在自营产品购买的用户,每增加1个,减少5.808元销售额;每增加一个女性,可以得到37.03元销售汇报,高于男性0.81元;最近30天参与重点活动的客户比未参加的客户带来的销售回报高50.31元;每多一个注册用户为6个月的用户可以得到43.63元销售回报,高于注册一年内用户4.63元,高于注册2年内用户19.56元
综上,我们需要寻找性别为1(女性),距今下单天数越长,最近三十天有在app上参与重点讨论,且生命周期为6个月以内的用户,向这些用户展开营销活动,查看其消费情况,做进一步的测试