导读:
分类问题是机器学习应用中的常见问题,而二分类问题是其中的典型,例如垃圾邮件的识别。本文基于UCI机器学习数据库中的银行营销数据集,从对数据集进行探索,数据预处理和特征工程,到学习模型的评估与选择,较为完整的展示了解决分类问题的大致流程。文中包含了一些常见问题的处理方式,例如缺失值的处理、非数值属性如何编码、如何使用过抽样和欠抽样的方法解决分类问题中正负样本不均衡的问题等等。
作者:llhthinker
欢迎转载,请保留原文链接:http://www.cnblogs.com/llhthinker/p/7101572.html
1. 数据集选取与问题定义
本次实验选取UCI机器学习库中的银行营销数据集(Bank Marketing Data Set: http://archive.ics.uci.edu/ml/datasets/Bank+Marketing )[Moro et al., 2014]. 。这些数据与葡萄牙银行机构的直接营销活动有关。这些直接营销活动是以电话为基础的。通常来说,银行机构的客服人员至少需要联系一次客户来得知客户是否将认购银行的产品(定期存款)。因此,与该数据集对应的任务是分类任务,而分类目标是预测客户是(yes)否(no)认购定期存款(变量y)。
数据集包含四个csv文件:
1) bank-additional-full.csv: 包含所有的样例(41188个)和所有的特征输入(20个),根据时间排序(从2008年5月到2010年9月);
2) bank-additional.csv: 从1)中随机选出10%的样例(4119个);
3) bank-full.csv: 包含所有的样例(41188个)和17个特征输入,根据时间排序。(该数据集是更老的版本,特征输入较少);
4) bank.csv: 从3)中随机选出10%的样例4119个)。
提供小的数据集(bank-additional.csv和bank.csv)是为了能够快速测试一些计算代价较大的机器学习算法(例如SVM)。本次实验将选取较新的数据集,即包含20个特征量的1)和2)。
2. 认识数据
2.1 数据集输入变量与输出变量
数据集的输入变量是20个特征量,分为数值变量(numeric)和分类(categorical)变量。具体描述见数据集网站http://archive.ics.uci.edu/ml/datasets/Bank+Marketing。
输出变量为y,即客户是否已经认购定期存款(binary: "yes", "no")。
2.2 原始数据分析
首先载入数据,
然后使用info()函数和describe()函数查看数据集的基本信息。
3. 数据预处理与特征工程
3.1 缺失值处理
从2.2节给出的数据集基本信息可以看出,数值型变量(int64和float64)没有缺失。非数值型变量可能存在unknown值。使用如下代码查看字符型变量unknown值的个数。
缺失值处理通常有如下的方法:
-
对于unknown值数量较少的变量,包括job和marital,删除这些变量是缺失值(unknown)的行;
-
如果预计该变量对于学习模型效果影响不大,可以对unknown值赋众数,这里认为变量都对学习模型有较大影响,不采取此法;
-
可以使用数据完整的行作为训练集,以此来预测缺失值,变量housing,loan,education和default的缺失值采取此法。由于sklearn的模型只能处理数值变量,需要先将分类变量数值化,然后进行预测。本次实验使用随机森林预测缺失值,代码如下:
def fill_unknown(data, bin_attrs, cate_attrs, numeric_attrs): # fill_attrs = ['education', 'default', 'housing', 'loan'] fill_attrs = [] for i in bin_attrs+cate_attrs: if data[data[i] == 'unknown']['y'].count() < 500: # delete col containing unknown data = data[data[i] != 'unknown'] else: fill_attrs.append(i) data = encode_cate_attrs(data, cate_attrs) data = encode_bin_attrs(data, bin_attrs) data = trans_num_attrs(data, numeric_attrs) data['y'] = data['y'].map({ 'no': 0, 'yes': 1}).astype(int) for i in fill_attrs: test_data = data[data[i] == 'unknown'] testX = test_data.drop(fill_attrs, axis=1) train_data = data[data[i] != 'unknown'] trainY = train_data[i] trainX = train_data.drop(fill_attrs, axis=1) test_data[i] = train_predict_unknown(trainX, trainY, testX) data = pd.concat([train_data, test_data]) return data