![51c2aa0dcc9d58582db1c0655c796c71.png](https://i-blog.csdnimg.cn/blog_migrate/64ab608b9f18af84fbc06e90148c6c0b.jpeg)
0 目录
1.简单分析报告
2.具体操作
(1)数据读取
(2)描述性分析
(3)参数估计与统计推断
(4)模型选择
(5)预测和评估
3.Python代码和数据集链接
4.参考文献
正文
1 简单分析报告
超市会员光顾频数预测分析报告
内容提要 研究消费者光顾超市的频数对于超市的管理者有着特别重要的意义。本报告利用消费者光顾超市的历史数据,对其未来的光顾频数进行了预测分析。我们的分析结果表明,消费者在前三个月的光顾频数和消费金额都影响着其未来的光顾频数,其中前三个月的光顾频数对其未来的光顾频数的影响要大于消费金额,尤其是消费者最近一个月的行为对其未来的预测能力最强。根据本报告的模型及结论,超市的管理者可以更好地衡量顾客的活跃程度,度量客户的价值,从而制定更为科学、合理的经营管理策略。
一、研究目的
在超市的经营管理中,消费者光顾超市的次数是一个衡量消费者活跃程度、度量客户价值的重要指标。因此,合理地预测消费者的光顾次数,并且知道什么样的消费者光顾超市会频繁一些,而什么样的消费者较少光顾超市,有助于超市的管理者更好地制定相应的经营管理策略。本报告试图利用超市会员的历史消费数据,找出影响消费者未来光顾频率的因素,并建立合理的经济计量学模型对其未来光顾频率进行预测,最后根据分析结果提出合理的建议。
二、数据来源和相关说明
本报告的数据来源于我国北方某城市处于垄断地位的一家超市,数据包含了该城市一部分会员的详细消费记录。为了便于分析,我们以某年某月为基准月份(第0月),将前一个月记为第-1月,以此类推。在数据中,我们感兴趣的因变量是每一个会员在基准月份光顾该超市的次数,对应的自变量是每一个会员在前三个月中每月的光顾次数以及每月的消费金额。特别地,如果该会员在某月没有光顾超市,那么将他的消费金额记为0。具体地说,本报告所使用的数据共包含了3995个有效样本,而对于相关变量的详细解释如表1-1所示。
![c41e54cca7789a1f91d91161fc3d24a6.png](https://i-blog.csdnimg.cn/blog_migrate/47c7a0c7351f88f9015b6e38ae085593.jpeg)
三、描述性分析
为了获得对数据的整体认识,我们首先对数据做简单的描述性分析,得到的结果如表1-2所示。从中可以看到,按平均水平来说(以算数平均计),每个月每位会员光顾该超市大约1次,消费金额为5-20元。
![605515b74030999159b3d6646360fa16.png](https://i-blog.csdnimg.cn/blog_migrate/1853b4aabed5a50eee992a5617a4c471.jpeg)
考虑到因变量为计数变量的特点,我们利用箱线图考察因变量与自变量之间的关系,得到图1-1。
![47fe51df4be17704db6843b4b24d3274.png](https://i-blog.csdnimg.cn/blog_migrate/69469387bcc7b3c325d0e8da98b75154.jpeg)
从图1-1我们可以得出如下的初步结论:
- 第0月光顾频数较高的顾客,其第-1月光顾频数(以中位数计)也较高。这表明消费者在第-1月的光顾次数可能是一个对其当月的光顾次数有显著影响的重要因素。
- 第0月光顾频数较高的顾客,其第-1月消费金额(以中位数计)也较高。这表明消费者在第-1月的消费金额也可能是一个对第0月光顾次数具有预测能力的变量。但是,其变化趋势没有第-1月的光顾频数那样显著,因此,我们可以猜测第-1月消费金额的预测能力有限。
- 第0月光顾频数较高的顾客在第-2月和第-3月的光顾频数也较高,但这种趋势在第0月的光顾频数较高时并不稳定。这表明,第-2和第-3月的光顾频数可能有一定的预测能力,但预测能力很有限。
- 第0月光顾频数较高的顾客在第-2和第-3月的消费金额(以中位数计)也较高,第-2月的趋势和第-1月的趋势类似,而第-3月的趋势要强于第-1月和第-2月。但这种趋势在第0月的光顾频数较高时也不稳定。这也表明,第-2月和第-3月的消费金额可能有一定的预测能力,但预测能力也比较弱。
四、数据建模
- 全模型分析
根据因变量为计数变量的特点,我们采用泊松分布(Possion)回归的方法建立模型。首先对包含全部自变量的全部模型进行估计,得到的估计结果如表1-3所示:
![415b0ec0ad6d36b3b54aeb75f95f20a1.png](https://i-blog.csdnimg.cn/blog_migrate/7b9da9859362e9fc14daae7b43c867b7.jpeg)
从表1-3中我们可以看到,对模型的广义似然比检验的P值非常小(P值<0.001),表明该模型是显著的,即我们所考虑的6个解释性变量中,至少有一个与第0消费者的光顾频数显著相关。进一步通过对各自变量所对应的Z检验的考察,我们可以得到以下3个结论:
- 六个解释性变量都和因变量高度正相关。这说明,无论是较高的历史光顾频率(无论哪一个月),还是较高的历史消费金额,都预示着较高的未来光顾频率。
- 这六个解释性变量的影响力很不一样。历史消费金额的系数非常小,这在一定程度上说明,其对未来光顾频率的预测能力弱于历史光顾频率的预测能力。
- 同样是历史光顾频率,最近一个月的光顾频率(freq1)的系数明显高于另外两个月(freq2和freq3),类似的现象也存在于消费金额中。这说明,消费者最近一个月的行为对未来的预测能力很强。
2. 模型选择和预测
上一节的分析结果表明,我们选择的自变量确实对因变量有一定的预测能力。但是全模型过于复杂,为了得到一个尽量简单同时又具有良好的预测能力的模型,我们采用 AIC 和 BIC 的模型选择标准来选择一个最优的模型。对于本报告使用的数据,AIC 和 BIC 得到了相同的结论,它们都认为全模型就是最优的模型。这表明,这六个自变量确实都有一定的预测能力,也就是说,前三个月中消费者的购买行为确实影响着当月的购买行为。
根据我们所得到的全模型(同时也是选择的最优模型),我们可以预测消费者当月的光顾次数。通过对新的测试集进行预测,并计算预测值和真实值之间的误差,我们得到该模型的均方根误差(RMSE)为1.345,这表明该模型有一定的预测能力。
五、结论和建议
从上述的分析结果可知,消费者在前三个月的光顾频数和消费金额都影响着其未来的光顾频数,其中前三个月的光顾频数对未来的光顾频数对的影响要大于消费金额。因此,对超市的管理者而言,能够使消费者经常光顾超市对超市的经营具有重要的意义。我们还发现消费者最近一个月的行为对未来的预测能力最强,因而超市管理者要特别关注近期的经营状况,而不是更长期的情形。另外,根据本报告的模型及结论,超市的管理者可以利用会员的历史消费记录,对会员未来的光顾频数进行合理的预测,并根据预测结果制定相应的营销策略。具体地说,如果预测结果表明消费者未来的光顾频数较小,那么超市就需要通过某些促销活动来增加消费者的光顾次数,进而提高超市的经营业绩。
2 具体操作
以下是用python代码操作。
(1)数据读取
读取数据:
import numpy as np
import pandas as pd
path = r'D:Documentspython_documentsPractical Business Data AnalysiscaseCH6crm.csv'
data = pd.read_csv(path)
data.head()
输出:
![2bbd9e40216aa5309e0d4c2e4b4dc1fa.png](https://i-blog.csdnimg.cn/blog_migrate/f025c6bc51f759fd2bb9e04858b939ae.jpeg)
这几个变量的含义见表1-1。上表第1行数据说明有一名超市会员,他在第-3个月光顾一次,消费45.4元。除此之外,该顾客没有在光顾超市。
![df89369467e3c1cbbb3b902898adb224.png](https://i-blog.csdnimg.cn/blog_migrate/bf42d6eaa272e030bb56511c8f819d05.jpeg)
(2)描述性分析
数据的简单描述性统计如下:
round(data.describe(), 3)
输出:
![51654339b66bc0f28af314174b067a58.png](https://i-blog.csdnimg.cn/blog_migrate/9d6626a583f7514ea44615e6e2a0811b.jpeg)
上图可见样本总数为3995条,以及一些描述性统计量。
再画出所有解释性变量的箱线图:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set() #设置seaborn默认格式
from matplotlib.font_manager import FontProperties #显示中文,并指定字体
myfont=FontProperties(fname=r'C:/Windows/Fonts/simhei.ttf',size=14)
sns.set(font=myfont.get_name()) #seaborn解决中文乱码的问题
plt.rcParams['axes.unicode_minus']=False #显示负号
plt.rcParams['figure.figsize'] = (12, 8) #设定图片大小
f = plt.figure() #确定画布
f.add_subplot(2,3,1)
sns.boxplot(x="freq0", y="freq1",
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-1月光顾超市的频数',fontsize=16)
plt.title("(a)", fontsize=20) #设置子图标题
f.add_subplot(2,3,2)
sns.boxplot(x="freq0", y="freq2",
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-2月光顾超市的频数',fontsize=16)
plt.title("(b)", fontsize=20) #设置子图标题
f.add_subplot(2,3,3)
sns.boxplot(x='freq0', y='freq3',
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-3月光顾超市的频数',fontsize=16)
plt.title("(c)", fontsize=20) #设置子图标题
f.add_subplot(2,3,4)
sns.boxplot(x="freq0", y="exp1",
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-1月的消费金额',fontsize=16)
plt.title("(d)", fontsize=20) #设置子图标题
f.add_subplot(2,3,5)
sns.boxplot(x="freq0", y="exp2",
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-2月的消费金额',fontsize=16)
plt.title("(e)", fontsize=20) #设置子图标题
f.add_subplot(2,3,6)
sns.boxplot(x="freq0", y="exp3",
data=data, linewidth=2.5)
plt.xticks(fontsize=16)
plt.yticks(fontsize=16)
plt.xlabel('第0月光顾超市的频数', fontsize=16)
plt.ylabel('第-3月的消费金额',fontsize=16)
plt.title("(f)", fontsize=20) #设置子图标题
#plt.subplots_adjust(wspace=0.3) #调整两幅子图的间距
plt.tight_layout()
plt.savefig('(3)计数回归:6幅箱线图.png',dpi=600) #保存png格式图片
输出:
![47fe51df4be17704db6843b4b24d3274.png](https://i-blog.csdnimg.cn/blog_migrate/69469387bcc7b3c325d0e8da98b75154.jpeg)
(3)参数估计与统计推断
用似然比对整体的显著性进行检验。
先以空模型:log{P(
import statsmodels.formula.api as smf
import statsmodels.api as sm
glm_1 = smf.glm('freq0~1', data, family=sm.families.Poisson())
res_1 = glm_1.fit()
print(res_1.summary())
输出:
![7468afa82b0085e227d86be23509c284.png](https://i-blog.csdnimg.cn/blog_migrate/d13c1462194c6dcf48d5f65e5cbb4167.jpeg)
再以全模型进行泊松回归: log{λ(x)} =
import statsmodels.formula.api as smf
import statsmodels.api as sm
glm = smf.glm('freq0~freq1 + freq2 + freq3 + exp1 + exp2 + exp3', data, family=sm.families.Poisson())
res_quan = glm.fit()
print(res_quan.summary())
输出:
![7851292b638ddd73358c25269b5c307f.png](https://i-blog.csdnimg.cn/blog_migrate/a53cbbe5f4ceb5082d1b18323eef02f8.jpeg)
空模型与全模型的Deviance项的差是2146,而自由度为6(全模型与空模型的Df Model之差)。接着在excel卡方检验,计算“=CHIDIST(2146, 6)”,得到P值为0。此说明模型整体高度显著,也就意味着我们所考虑的六个解释性变量中,至少有一个与因变量显著相关。
Z检验讨论各个自变量的显著性。由全模型的possion回归结果分析可知,在0.001的显著性水平下,所有因素都高度显著。
(4)模型选择
先拆分自变量与因变量:
X = data.drop('freq0', axis=1)
Y = data.freq0
然后进行AIC变量选择:
import statsmodels.api as sm
import itertools
predictorcols = list(X.columns) #将各个自变量汇成一个列表
AICs = {}
for k in range(1, len(predictorcols)+1):
#print(k)
for variables in itertools.combinations(predictorcols, k):
#Python itertools模块combinations(iterable, r)方法可以创建一个迭代器,
#返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序。
predictors = X[list(variables)]
predictors2 = sm.add_constant(predictors)
est = sm.Poisson(Y, predictors2)
res = est.fit()
AICs[variables] = res.aic
from collections import Counter
c = Counter(AICs) #AICs为字典,则按values来统计,把value视为key出现的次数。注意这是从高到低排列。
c.most_common()[:-4:-1] #出现次数最少的10个元素,对应这里aic最小的3个值。接着倒序排列
输出:
![61b85bb7aaeed0057512512415a32f56.png](https://i-blog.csdnimg.cn/blog_migrate/fc29b340963eeeae7d74e7cc1cc6be4d.png)
根据AIC最小的原则,可知AIC选择了全部自变量。
再进行BIC变量选择:
import statsmodels.api as sm
import itertools
predictorcols = list(X.columns) #将各个自变量汇成一个列表
BICs = {}
for k in range(1, len(predictorcols)+1):
#print(k)
for variables in itertools.combinations(predictorcols, k):
#Python itertools模块combinations(iterable, r)方法可以创建一个迭代器,
#返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序。
predictors = X[list(variables)]
predictors2 = sm.add_constant(predictors)
est = sm.Poisson(Y, predictors2)
res = est.fit()
BICs[variables] = res.bic
from collections import Counter
c = Counter(BICs) #BICs为字典,则按values来统计,把value视为key出现的次数。注意这是从高到低排列。
c.most_common()[:-4:-1] #出现次数最少的3个元素,对应这里bic最小的3个值。接着倒序排列。
输出:
![3a38768bceb83482e429299a02628af2.png](https://i-blog.csdnimg.cn/blog_migrate/d5c89ca6e85a66943fb369cf413242e8.png)
可见,BIC也选择了全部自变量。
综合以上,AIC和BIC都认为全模型是最优的模型。
(5)预测和评估
读取测试集:
import numpy as np
import pandas as pd
path_1 = r'D:Documentspython_documentsPractical Business Data AnalysiscaseCH6new.csv'
data_new = pd.read_csv(path_1)
data_new.head()
输出:
![fbe094285ef3066fc28682176cb438bf.png](https://i-blog.csdnimg.cn/blog_migrate/d33204e996cacdc58e360c52d906a066.jpeg)
在测试集上预测:
data_new['predict_result'] = res_quan.predict(data_new)
data_new['predict_result'] = data_new['predict_result'].apply(lambda x:round(x, 3))
data_new.head()
输出前5条样本的预测结果:
![78e728cb52484ff416a6efc670bebb2b.png](https://i-blog.csdnimg.cn/blog_migrate/dd5e358ca041ce9a780ba2706f52d023.jpeg)
最后采用均方根误差(RMSE)来评估模型预测结果:
from sklearn.metrics import mean_squared_error
import numpy as np
print("RMSE:", np.sqrt(mean_squared_error(data_new.predict_result, data_new.freq0)))
输出:
![6eb64a861cc8988ff34e50592f71ca92.png](https://i-blog.csdnimg.cn/blog_migrate/899846a199673fa2307a93100ae39f42.png)
我们得到该模型的均方根误差(RMSE)为1.345,这表明该模型有一定的预测能力。
3.Python代码和数据集链接
nameli0722/Data-Analysisgithub.com![ce756973db84966c86bb118b91baaf13.png](https://i-blog.csdnimg.cn/blog_migrate/03d0587ba146719be553b752596bfe4d.jpeg)
4.参考文献
(1)《应用商务统计》王汉生著,2011,北京大学出版社;
(2)《数据思维——从数据分析到商业价值》王汉生编著,2017,中国人民大学出版社。