原文链接:https://baijiahao.baidu.com/s?id=1805446353580114832
【摘要】
母婴购物是淘宝网站的一项重要产业,同时受到大量新生儿、准新生儿父母的关注,具有庞大的市场。随着社会生活水平的进步,近年来对该市场的更高质量服务的潜在需求越来越大。本论文旨在通过根据已有数据集中的数据,通过孩子的信息(年龄、性别等)以及用户购物情况分析用户购买商品的习惯,并进一步预测用户可能的购物操作。本论文借助Python数据挖掘的手段,对数据集实行数据可视化的操作,并运用商务分析中关联分析、聚类分析的知识进行建模,力求以准确、易理解的方法构建一套购物数据体系,从而更好地揭示用户购物的情况,服务于淘宝商家和购物用户。
关键词:母婴产品 淘宝 建模 Python 数据挖掘 商务分析
一、 项目/案例分析的背景及意义
随着当前科技和生活水平的快速进步,母婴产业正在受到越来越多的需求的同时,对服务的质量也有了更高要求,成为社会焦点。当前的新生儿、准新生儿父母,由于网络水平进步的时代背景,可能更倾向于以网购的形式进行购物。同时,母婴产品的商家也迫切需要通过精确预测用户需求,更快地销售出商品。因此,对于网购母婴产品的更高质量服务受到广泛关注和需求,对这方面的工作势在必行。
二、 项目/案例分析所涉及的数据分析问题/科学问题
在本项目分析中,首先需要对已有的数据集进行数据挖掘,清洗出需要的数据,并利用可视化使数据易于为阅读者直观理解,并给进一步操作提供根据;然后运用学过的商务分析知识,先对整理后的数据进行聚类、关联分析,构建出合适的商务模型,再用可视化的方法对模型做基本的阐释;最后利用推荐系统分析的知识,进行对本项目后续可能的应用做基本的展望。
三、 数据集介绍
本项目使用的数据集来自于阿里云天池平台,网址https://tianchi.aliyun.com/dataset/45。数据集名称《淘宝母婴购物数据集》,由淘宝&天猫官方提供,具有很强的参考意义。该数据集由两部分组成,一部分为29971行*7列的用户ID和购物信息组成,另一部分为953行*3列的用户ID和孩子信息组成,其中两组数据集的用户ID部分重叠。第一部分在python中运用pandas功能后概述图如下:
数据集第一部分
第二部分在python中运用pandas功能后概述图如下:
数据集第二部分
四、 数据预处理与探索性分析
1、数据预处理:先分别删除第一组、第二组数据集中的重复行,取第二组数据集中第一列用户ID,在第一组数据集中的用户ID中遍历搜索,提取出两组数据集中共有的953个用户ID,以用户ID为寻找依据,将这些用户ID下对应的购物信息和孩子信息放到一起,形成新的第三组数据集,并将这个数据集命名为“a”。 a的概述图如下:
数据集a
2、探索性分析:利用数据集中的“day”和“birthday”两列,计算出每个孩子的年龄,记为“age”,单位为年,加在最后一列,删除无关的列,构成最终的数据集“c”,并以c作为后续建模的参考集。c的概述图如下:
数据集c
五、数据建模分析
通过初步设想,决定分别两次通过不同方式建模并分析数据集:①数据标准化后用k-means聚类,从而进行聚类分析;②对数据集进行等频离散化,随后用置信-支持规则进行关联分析。接下来将分别对两种建模进行阐述。
①:聚类分析:先对数据列“age”和“gender”实行标准化,然后运用肘部法则(SSE)和轮廓系数法将相似用户聚类,发现肘部法则和轮廓系数法结果相同,并取其得出的最优簇数Cluster_n=3。将数据集按照3簇进行聚类,得到结果如图所示:
聚类分析
其中肘部法则(SSE)曲线如图所示:
肘部法则(SSE)曲线
其中轮廓系数柱状图如图所示:
轮廓系数法柱状图
把聚簇结果表格化,返回表中数据即得每簇情况,成功将用户组以年龄和性别分为三类,聚类成功!后续可以认为同簇的用户具有相似性,并对他们购买物品的喜好做基于用户数据的推荐分析(UserKnn)。
②:关联分析:先用等频离散化将用户按照年龄分为三类:large,medium,small,性别分为male和female,购买数量分为single(1个)和multi(多个),运用one-hot方法和map功能进行关联,计算出每一种属性关于各种产品编号的置信度与支持度,结果如图所示。
每种产品置信度与支持度
从图中可以得出每一种属性的置信度与支持度,后续开发完全可以依靠此规则表,制定合适的阈值进行合理的推荐功能啦!
六、 数据分析的结论总结
从本数据集中,我们经过数据预处理、数据整合、聚类分析、关联分析、数据可视化等操作,对数据集进行了研究,最终得到了描述顾客的孩子信息以及预测顾客可能喜欢的产品的初步方法。在研究中曾经使用过多种手段解决问题(如建模过程中同时尝试了k-means和等频离散化两种操作,最后发现k-means法得到的聚簇结果中在理论上三类用户应该有一定的相似性,然而运用推荐系统知识对照真实结果发现效果较差,显得粗糙),在探究中提升了我们的辩证思维,让我们意识到通往目的的路常常不止一条,而我们要做的是找到最好的那一条。与此同时本论文也存在不足之处,如数据集对顾客信息缺乏进一步挖掘,包括顾客收入水平、家庭情况等,使结果略显粗糙,然而处理这些数据的本质思路与本文中所用的方法在本质上是趋同的;如数据集中的购物内容是以根目录形式实现的,得出的结论也是基于根目录,无法形象化加以理解和验证;又如受限于笔者的水平和精力,以及所获取资料的有限性,不能详细对推荐系统进行建模而只能提出理论上的设想等等。这些问题望阅者海涵并自行研究。
七、 项目/案例的实践价值与展望
本项目基于淘宝官方母婴产品购物信息出发,对数据进行聚类分析和关联分析,由于数据集的信息量之庞大且真实,其实践价值较高。对于本论文成果的未来展望,显然可以以本论文中的聚类分析结果出发,设计基于用户的推荐系统模型(UserKnn),同时也可以按照相同模式从反向着手,设计基于产品的推荐系统模型(ItemKnn)。与此同时,通过本文最后得出的关联分析数据表格,淘宝/天猫商家或商业分析者可以自由设定支持度、置信度阈值,自行设计规则进行预测,并使用训练集-测试集的方法进行验证,从而得到准确的预测顾客购物喜好的模型。本论文做的这些工作,对上述进一步任务的实现帮助很大。
附录(参考文献、主要代码等)
主要代码附录如下:
1.import pandas as p
df=p.read_csv("./(sample)sam_tianchi_mum_baby_trade_history.csv")
df
2.df2=p.read_csv("./(sample)sam_tianchi_mum_baby.csv")
df2
3.b=p.DataFrame(df["user_id"]).drop_duplicates()
b
4. a=df.loc[1:1]
for n in df2['user_id']:
for m in b.index:
if b['user_id'][m]==n:
a=a.append(df.loc[m:m])
a
5. a=a.drop(index=1)
a.index=df2.index
a
6. a['birthday']=df2['birthday']
a['gender']=df2['gender']
a
7. a['day1']=a['day']/10000
a['day1']=a['day1'].astype('int')
a['day2']=((a['day']-a['day1']*10000)/100).astype('int')
a['day3']=(a['day']-a['day1']*10000-a['day2']*100).astype('int')
a['day4']=a['day1']+a['day2']/12+a['day3']/365
a['birthday1']=a['birthday']/10000
a['birthday1']=a['birthday1'].astype('int')
a['birthday2']=((a['birthday']-a['birthday1']*10000)/100).astype('int')
a['birthday3']=(a['birthday']-a['birthday1']*10000-a['birthday2']*100).astype('int')
a['birthday4']=a['birthday1']+a['birthday2']/12+a['birthday3']/365
a['age']=a['day4']-a['birthday4']
a
8.c=a.drop(columns=['day1','day2','day3','birthday1','birthday2','birthday3','day4','birthday4','day','birthday','property','user_id','auction_id','cat_id'],axis=1)
c
9. c['cat1'].value_counts()
data_r = c[['buy_mount','age']]
10. from sklearn import preprocessing
z_scaler = preprocessing.StandardScaler().fit(data_r)
print('mean:', z_scaler.mean_)
print('std:', z_scaler.scale_)
preprocessing.StandardScaler().fit(data_r).transform(data_r)
data_normed = z_scaler.transform(data_r)
data_normed[0:5,]
d=p.DataFrame(data_normed)
d
11. c['buy_mount']=d[0]
c['age']=d[1]
c
12. import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
n_clusters =3
kmeans = KMeans(n_clusters = n_clusters, random_state = 2021)
labels = kmeans.fit_predict(c)
labels #每个数据点所在的簇标号
c["age"]=labels
cluster_size = [sum(labels==cluster_id) for cluster_id in range(n_clusters)]
print(cluster_size)
print(kmeans.cluster_centers_)
c['labels'] = kmeans.labels_ #给data数据框增加labels一列
c.groupby('labels').mean() #基于labels分组,求每组各属性的平均
from sklearn.metrics import silhouette_score
s = []
cluster_list = range(2, 30)
for i in cluster_list: #变换聚簇数从2-15
kmeans = KMeans(n_clusters = i, random_state = 2021)
labels = kmeans.fit_predict(c)
s.append(silhouette_score(c, labels))
print(s)
# Plotting a bar graph to compare the results
plt.bar(cluster_list, s)
plt.xlabel('Number of clusters', fontsize = 10)
plt.ylabel('Silhouette Score', fontsize = 10)
plt.show()
kmeans = KMeans(n_clusters = 3, random_state = 2021)
labels = kmeans.fit_predict(c)
c["cluster"] = labels
# plot cluster sizes
plt.hist(labels, bins = range(3))
plt.title ('customers per Cluster')
plt.xlabel('Cluster')
plt.ylabel('Customers')
plt.show()
13. sse = []
cluster_list = range(1, 16)
for i in cluster_list:
kmeans = KMeans(n_clusters = i, random_state = 2021)
kmeans.fit(c)
sse.append(kmeans.inertia_)#SSE
plt.plot(cluster_list, sse)
plt.title('Elbow Method')
plt.xlabel('Clusters')
plt.ylabel('SSE')
plt.show()
14. c['labels']=labels
e=c[c['labels']==0].mean()
f=c[c['labels']==1].mean()
g=c[c['labels']==2].mean()
e=p.DataFrame(e)
e[1]=f
e[2]=g
e
15. cats = p.qcut(c['age'],q=3)
cats.value_counts()
cats = p.qcut(c['age'],q=3,labels=['small','medium','large'])
cats.value_counts()
c['age']=cats
c
16. Sex_map = {
1: 'male',
0: 'female'
}
c['gender'] = c['gender'].map(Sex_map)
c.head()
17. map1={
1:'single',
2:'multi',
3:'multi',
4:'multi',
5:'multi',
6:'multi',
7:'multi',
9:'multi',
12:'multi',
15:'multi',
10:'multi',
13:'multi',
26:'multi',
25:'multi',
160:'multi',
40:'multi',
30:'multi',
}
c['buy_mount'] = c['buy_mount'].map(map1)
c.head()
18. x=[]
for n in range(953):
x.append(str(c['buy_mount'][n])+' '+str(c['gender'][n])+' '+str(c['age'][n]))
c['cha']=x
c
19. c=c.drop(columns=['buy_mount','gender','age'])
d=c.values.tolist()
d
20. for n in range(953):
d[n][0]=str(d[n][0])
d
21. from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
te = TransactionEncoder()
te_ary = te.fit(d).transform(d)
df = p.DataFrame(te_ary, columns = te.columns_)
df
22. from mlxtend.frequent_patterns import apriori
freq = apriori(df, min_support = 0.01, use_colnames = True)
freq
23. from mlxtend.frequent_patterns import association_rules
Rules = association_rules(freq, metric = "confidence", min_threshold = 0.2)
Rules