之前对淘宝婴儿用品销售数据集做了基本的业务指标探索性分析。这里还是以这个数据集为例,进行后续的相关性探索。通过分析两个问题,熟悉机器学习算法建模流程。
两个预测问题:
- 根据孩子的信息(年龄、性别等)预测用户会购买什么样的商品;
- 根据父母的购买行为预测孩子的年龄。
分析流程:
- 提出问题
- 理解数据
包括:采集数据,导入数据,查看数据集信息,理解字段含义,查看是否有缺失值
- 预处理/数据清洗
包括:选择子集、列名重命名、缺失值处理、类型转换、重复值处理、异常值处理、数据排序等
- 特征提取
包括:对不同类型的数据做特征提取,如,数值型直接使用;分类型可能需要进行one-hot编码;字符串型可能需要做一些提取工作等
- 特征选择/特征降维
特征选择的好坏,会直接影响模型的预测性能。这个过程涉及到特征工程的知识,相关学习可以参考以下两篇博文:
- 建立模型
选择合适的机器学习算法,用训练集和算法得到机器学习模型,并用测试集来评估得到的模型。
字段含义:
- user_id:用户id
- auction_id:购买行为编号
- cat_id:商品种类ID
- cat1:商品属于哪个类别
- property:商品属性
- buy_mount:购买数量
- day:购买时间
- birthday:出生日期
- gender:性别(0 男性;1 女性)
问题1:根据孩子的信息预测用户会购买什么样的商品
一、提出问题
问题一:根据孩子的信息(年龄、性别等)预测用户会购买什么样的商品。
首先确定特征和标签是什么,特征是年龄age
和性别gender
,标签是预测出商品类别cat1
。
二、理解数据
下载并导入数据后,查看数据集信息:
1 | fileName1 = './(sample)sam_tianchi_mum_baby_trade_history.csv' |
1 | trade_data.info() |
1 | baby_data.info() |
三、数据预处理
- 以婴儿信息表为主,合并两个数据集。
1 | combined_data = pd.merge(trade_data,baby_data,on='user_id',how='right') |
查看合并后的数据集信息:
1 | combined_data.info() |
- 处理重复数据
发现有3个user_id
重复出现,删除:
1 | combined_data.drop_duplicates(subset='user_id',inplace=True) |
- 处理缺失值
发现property
商品属性这个字段有2条缺失。可以看到每个商品的属性都有多个,以逗号连接。这里采取删除的处理方式:
1 | combined_data.dropna(inplace=True) |
现在所有字段都不为空,总共951条数据。
- 数据类型转换
将购买商品日期和婴儿出生日期转换为时间格式:
1 | combined_data['day'] = combined_data['day'].astype('str') |
1 | combined_data['day'] = pd.to_datetime(combined_data['day'],format='%Y-%m-%d') |
- 处理异常值
性别gender
字段除了0(男),1(女)之外,还存在2的情况,这应该是用户不愿意透露婴儿的性别信息,这部分值只有26个,故删除这部分数据:
1 | combined_data['gender'].value_counts() |
1 | combined_data = combined_data[combined_data['gender']<2] |
到目前为止,总共925条数据。
四、特征提取
- 计算婴儿年龄,并进行分段,增加
age
列和age_group
列
增加年龄列,年龄的计算通过购买日期的年份减去出生日期的年份得到:
1 | combined_data['age'] = (combined_data['day'].dt.year - combined_data['birthday'].dt.year) |
发现年龄有异常大的值28岁,将其删去:
1 | combined_data = combined_data[combined_data['age'] < 28] |
这里只有一个异常大值,所以最终剩下924条数据。然后删除销售时间day
字段和出生日期birthday
字段:
1 | combined_data.drop(['day','birthday'],axis=1,inplace=True) |
将年龄进行分组,总共分为5个年龄组,增加年龄组列:
1 | bin_labels = ['G0','G1','G2','G3','G4'] |
对年龄组列进行one-hot编码,并将创建的虚拟变量添加到数据集:
1 | ageDf = pd.get_dummies(combined_data['age_group']) |
查看数据集是否得到预期效果:
1 | combined_data.head(3) |
如下图所示:
五、特征选择
该问题是根据孩子的信息(年龄、性别等)预测用户会购买什么样的商品。
那么选择的特征为:
- 特征:年龄区间
age_group
或者年龄age
,性别gender
- 标签:商品种类
cat1
特征以选择年龄区间age_group
和性别gender
为例:
1 | # 特征选择 |
六、构建模型
- 拆分数据集为训练集和测试集
训练集用于训练模型,测试集用于验证模型:
1 | from sklearn.model_selection import train_test_split |
打印结果为:
- 建立模型,训练和验证
这里选择梯度增强算法:
1 | # 梯度增强 |
- 训练模型,并用测试集验证:
1 | model.fit(train_X_2, train_y_2) |
问题2:根据父母的购买行为预测孩子的年龄
首先确定特征和标签是什么,现在能非常确定的是预测标签是年龄组age_group
;而对于特征则是不确定有哪些。
与问题1的相同之处
理解数据、数据预处理步骤与问题1相同。
与问题1的不同之处
- 在第四步特征提取中,增添了对商品属性
property
的处理,因为商品属性也是购买行为的特征之一。
商品属性property
字段是字符型,每个商品具有多个大类别属性以及大类别属性下的具体属性。每对属性数字,表示大类别属性下的具体属性,即大类别属性 : 具体属性
;每对属性数字用;
隔开,如下图红框中所示。
处理方式:
- 先按分号划分字符串,得到每个商品具有的所有属性对;
- 再按冒号划分每个属性对,保留每个商品含有的具体属性。
首先按属性值将property拆分成多行,并将新的列命名为new_property:
1 | new_prop = combined_data['property'].str.split(';',expand=True).stack().reset_index(level=1,drop=True).rename('new_property') |
如图所示:
然后,再拆分每个属性对,提取出其中的具体属性;为此定义一个函数:
1 | # 定义函数,提取具体属性 |
调用函数,提取具体属性,并将提取后的特征连接到原数据集上:
1 | #存放提取后的特征 |
对数据集进行去重处理,同一个商品若具有多条相同商品属性则删除:
1 | combined_data.drop_duplicates(['cat1','property'],inplace=True) |
最终得到2690条数据,提取具体属性之后的结果:
- 第五步中特征选择不同
这里是将所有的字段都作为特征输入,包括提取后的property
字段,而标签为年龄组:
1 | train_features_1 = combined_data[['user_id','cat_id','gender','auction_id','cat1','property']] |
总结
机器学习建模分析的流程与业务指标分析的流程大同小异。特别注意的是机器学习的模型效果很大程度取决于特征工程,特征工程做得好,即便模型简单,参数不优,也能获得很好的性能。本文主要以呈现机器学习算法分析流程为目标,特征工程工作做得相对简单,得到的模型准确率并不高,待后续深入学习这块知识后再作改进。