第1关:基于决策树模型的应用案例
任务描述
本关任务:使用决策树算法完成成人收入预测。
相关知识
为了完成本关任务,你需要掌握:1.数据特征处理,2.使用决策树算法完成成人收入预测。
数据处理及特征工程
本次任务我们将会使用成人数据集(来源于UCI数据集:UCI Machine Learning Repository ),该数据集从美国1994年人口普查数据库中抽取而来,共48842条数据,涉及到收入统计,因此也称作“人口普查收入”数据集。该数据集可以通过对属性变量包括年龄、工种、学历、职业等14种信息来判断年收入是否超过50k。
首先,我们来了解一下我们的数据,从而进一步明确任务,并作出针对性的分析。人口普查收入数据集是一个分类问题,目的是用来预测年收入是否超过50k$,对应我们所需要的标签,这在数据集中以“<=50K”和“>50K”
来进行表示;除此之外,数据包含了用于判断该决定的相关信息,对应我们所需要的特征,这些特征一共有14个。特征与标签的表示如下:
- age:年龄
- workclass: 工作类别
- fnlwgt: 序号
- education: 受教育程度
- education-num: 受教育时间
- marital-status: 婚姻状况
- occupation: 职业
- relationship: 社会角色
- race: 种族
- sex: 性别
- capital-gain: 资本收益
- capital-loss: 资本支出
- hours-per-week: 每周工作时间
- native-country: 国籍
- salary: 收入
我们可以通过以下代码,进行数据预览:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
import seaborn as sns
data_path ='/data/bigfiles/7db918ff-d514-49ea-8f6b-ea968df742e9'
df = pd.read_csv(data_path,header=None,names=['age', 'workclass', 'fnlwgt', 'education', 'education-num','marital-status','occupation','relationship','race','sex','capital-gain','capital-loss','hours-per-week','native-country','salary'])
对上述对数据的预览我们需要注意数据集中这样的几个问题:
- 字符型属性数据中是否存在缺失值,例如:‘unknow’
- 部分特征为字符串格式,无法放到模型训练,后期需要该字段需要进行离散型特征编码
capital-gain capital-loss
属性取值为0的占比75%以上考虑去除这两个属性
在分析出这些问题后我们使用代码逐步对数据进行处理:
# 去除字符串数值前面的空格
str_cols=[1,3,5,6,7,8,9,13,14]
for col in str_cols:
df.iloc[:,col]=df.iloc[:,col].map(lambda x: x.strip())
# 去除capital-gain, capital-loss特征属性
df.drop(['capital-gain','capital-loss'], axis=1, inplace=True)
#查找字符型属性缺失情况
for col in df.columns:
if df[col].dtype == object:
print("Percentage of \"unknown\" in %s:" %col ,df[df[col] == "unknown"][col].count(),"/",df[col].count())
经过这些过程,我们的数据处理便结束了,我们接下来使用处理后的数据进行决策树分类器训练和预测。
决策树分类器完成成人收入预测之训练
从上述的数据分析,我们可以得知我们所要解决的是一个二分类问题,由已知的特征来推断结果的取值(0或者1),根据上节决策树的相关知识,我们开始构建模型训练及预测。 sklearn
做为一个强大机器学习工具,为我们提供了决策树的函数接口。不仅如此,我们还可以使用它进行训练集和测试集的划分。下面我们便使用该工具完成上述数据集的训练,来探究各特征与预测结果之间存在的内在联系。我们的训练过程将包含以下几个方面:
数据处理
训练测试集的划分,函数
sklearn.model_selection.train_test_split
模型训练函数
sklearn.tree.DecisionTreeClassifier
下面是部分关键代码:
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_graphviz # 导入决策树模型
from sklearn.model_selection import train_test_split # 导入数据集划分模块
import matplotlib.pyplot as plt
# 数据的读入与处理
# 去除fnlwgt, capital-gain, capital-loss,特征属性
df.drop(['fnlwgt','capital-gain','capital-loss'], axis=1, inplace=True)
# 将特征采用哑变量进行编码,字符型特征经过转化可以进行训练
features=pd.get_dummies(df.iloc[:,:-1])
# 将label编码
df['salary'] = df['salary'].replace(to_replace=['<=50K', '>50K'], value=[0, 1])
labels=df.loc[:,'salary']
# 使用train_test_split按4:1的比例划分训练和测试集
# 使用DecisionTreeClassifier构建模型
#对训练集X_train训练
决策树分类器完成成人收入预测之预测及评价
上述的训练过程中我们只能大概看出模型对训练结果的拟合程度,我们还需要使用一系列指标在测试集上进行模型的衡量。分类模型的一般评价有如下几种方式:
- 准确率acc
- 精准率pre
- 召回率recall
- f1-Score
- auc曲线
这几个指标可由混淆矩阵计算得到,我们先来看一下混淆矩阵的产生,它是由预测结果和标签值进行计算得到的,如下图所示:
下面我们使用混淆矩阵进行这几个指标的说明:
-
准确率:Accuracy = (TP+TN)/(TP+FN+FP+TN)
解释:(预测正确)/(预测对的和不对的所有结果),即预测正确的比例。
API:score()方法返回的就是模型的准确率 -
精确率:Precision = TP/(TP+FP)
解释:预测结果为正例样本(TP+FP)中真实值为正例(TP)的比例。
API:accuracy_score -
召回率:Recall = TP/(TP+FN)
解释:真正为正例的样本中预测结果为正例的比例。正样本有多少被找出来了(召回了多少)
API:recall_score -
综合精确率和召回率的指标 :f1-score:
f1=2P∗R/(P+R)
解释:F1分数(F1-score)是分类问题的一个衡量指标 ,f1-score是精确率和召回率的调和平均数 ,最大为1,最小为0 。
API:f1_score -
AUC:ROC曲线下的面积
解释:在理想情况下,最佳的分类器应该尽可能地处于左上角,这就意味着分类器在伪反例率(预测错的概率FPR = FP / (FP + TN))很低的同时获得了很高的真正例率(预测对的概率TPR = TP / (TP + FN))。也就是说ROC曲线围起来的面积越大越好,因为ROC曲线面积越大,则曲线上面的面积越小,则分类器越能停留在ROC曲线的左上角。
相关API接口:
from sklearn.metrics import roc_auc_score
# 概率值
y_pre = predict_proba(x_test)
# auc
auc=roc_auc_score(y_test,y_pre[:,1])
下面使用这几个指标进行模型性能评估的关键代码:
from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report
#对于测试集x_test进行预测
x_pre_test=clf.predict(x_test)
# 其他指标计算
classification_report(y_test, x_pre_test)
# 预测测试集概率值
# 计算验证集的auc值,参数为预测值和概率估计
这样整个过程便结束了。
编程要求
根据提示,在右侧编辑器补充代码,实现使用决策树进行成人收入预测,包括:
数据处理
模型训练
模型预测
测试指标计算,并打印aou的值,函数:
print("auc的值:{}".format(auc))
测试说明
平台会对你编写的代码进行测试:
预期输出:
提示: 参照示例完成任务
第1关任务——代码题
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_graphviz # 导入决策树模型
from sklearn.model_selection import train_test_split # 导入数据集划分模块
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report# 数据的读入与处理
data_path ='/data/bigfiles/7db918ff-d514-49ea-8f6b-ea968df742e9'
df = pd.read_csv(data_path,header=None,names=['age', 'workclass', 'fnlwgt', 'education', 'education-num','marital-status','occupation','relationship','race','sex','capital-gain','capital-loss','hours-per-week','native-country','income'])# 去除字符串数值前面的空格
df = df.applymap(lambda x: x.strip() if isinstance(x, str) else x)# 去除fnlwgt, capital-gain, capital-loss,特征属性
df.drop(['fnlwgt','capital-gain','capital-loss'], axis=1, inplace=True)# 将特征采用哑变量进行编码,字符型特征经过转化可以进行训练
features=pd.get_dummies(df.iloc[:,:-1])# 将label编码
df['income'] = df['income'].map({'<=50K': 0, '>50K': 1})# 按4:1的比例划分训练和测试集
X_train, X_test, y_train, y_test = train_test_split(features, df['income'], test_size=0.2, random_state=1)# 构建模型
clf = DecisionTreeClassifier(criterion='entropy',max_depth=6,random_state=17)#对训练集X_train训练
clf.fit(X_train, y_train)#对于测试集x_test进行预测
x_pre_test = clf.predict(X_test)# 其他指标计算
print(classification_report(y_test, x_pre_test))# 预测测试集概率值
x_pre_test_proba = clf.predict_proba(X_test)[:, 1]#计算验证集的auc值,参数为预测值和概率估计
auc = roc_auc_score(y_test, x_pre_test_proba)
print("auc的值:{}".format(auc))