- Python机器学习中的DictVectorizer(特征向量化
- 利用sklearn进行分类2:良/恶性乳腺癌肿瘤预测(二)
- 利用sklearn进行分类:良/恶性乳腺癌肿瘤预测(一)
- 利用sklearn进行分类3:初级手写数字识别
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记七
- PYTHON机器学习及实践_从零开始通往KAGGLE竞赛之路pd
- Python机器学习及实践_从零开始通往KAGGLE竞赛之路 高
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记二
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记三
- 《机器学习及实践——从零开始通往KAGGLE竞赛之路》读书笔记四
决策树
模型介绍
在前面使用的Logistic回归和支持向量机模型,都在某种程度上要求被学习的数据特征和目标之间遵循线性的假设,然而很多情况下不实际的。
Example
我们要根据一个人的年龄来预测其患流感死亡的概率。
如果采用线性模型假设,那么我们只有两种情况:年龄越大死亡率越高;年龄越小死亡率越高。然而我们根据常识判断,青壮年有更加健全的免疫系统,相较于儿童和老年人死亡率更低。如果使用数学表达式来描述这种非线性关系,使用分段函数更加合理;而在机器学习模型中,决策树是不二之选。
信用卡申请的审核涉及申请人的多项特征,也是典型的决策树模型。决策树节点代表数据特征,如年龄、身份是否是学生、信用评级等,每个节点下的分支代表对应特征值的分类,如年龄包括青年人、中年人和老年人等。而决策树的所有叶子节点则显示模型的决策结果,对于信用卡申请而言,这是一个二分类决策任务。
信用卡申请决策树模型
数据描述
我们使用决策树来预测泰坦尼克号乘客的生还情况。
import pandas as pd
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
# 观察一下前几行数据,可以发现,数据种类各异,数值型、类别型,甚至还有缺失数据。
titanic.head
<bound method NDFrame.head of row.names pclass survived \
0 1 1st 1
1 2 1st 0
2 3 1st 0
3 4 1st 0
4 5 1st 1
... ... ... ...
1308 1309 3rd 0
1309 1310 3rd 0
1310 1311 3rd 0
1311 1312 3rd 0
1312 1313 3rd 0
name age embarked \
0 Allen, Miss Elisabeth Walton 29.0000 Southampton
1 Allison, Miss Helen Loraine 2.0000 Southampton
2 Allison, Mr Hudson Joshua Creighton 30.0000 Southampton
3 Allison, Mrs Hudson J.C. (Bessie Waldo Daniels) 25.0000 Southampton
4 Allison, Master Hudson Trevor 0.9167 Southampton
... ... ... ...
1308 Zakarian, Mr Artun NaN NaN
1309 Zakarian, Mr Maprieder NaN NaN
1310 Zenn, Mr Philip NaN NaN
1311 Zievens, Rene NaN NaN
1312 Zimmerman, Leo NaN NaN
home.dest room ticket boat sex
0 St Louis, MO B-5 24160 L221 2 female
1 Montreal, PQ / Chesterville, ON C26 NaN NaN female
2 Montreal, PQ / Chesterville, ON C26 NaN (135) male
3 Montreal, PQ / Chesterville, ON C26 NaN NaN female
4 Montreal, PQ / Chesterville, ON C22 NaN 11 male
... ... ... ... ... ...
1308 NaN NaN NaN NaN male
1309 NaN NaN NaN NaN male
1310 NaN NaN NaN NaN male
1311 NaN NaN NaN NaN female
1312 NaN NaN NaN NaN male
[1313 rows x 11 columns]>
# 使用pandas,数据都转入pandas独有的dataframe格式(二维数据表格),直接使用info(),查看数据的统计特性。
titanic.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 row.names 1313 non-null int64
1 pclass 1313 non-null object
2 survived 1313 non-null int64
3 name 1313 non-null object
4 age 633 non-null float64
5 embarked 821 non-null object
6 home.dest 754 non-null object
7 room 77 non-null object
8 ticket 69 non-null object
9 boat 347 non-null object
10 sex 1313 non-null object
dtypes: float64(1), int64(2), object(8)
memory usage: 113.0+ KB
# 机器学习有一个不太被初学者重视,并且耗时,但是十分重要的一环,特征的选择,这个需要基于一些背景知识。根据我们对这场事故的了解,sex, age, pclass这些都很有可能是决定幸免与否的关键因素。
X = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
# 对当前选择的特征进行探查。
X.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 pclass 1313 non-null object
1 age 633 non-null float64
2 sex 1313 non-null object
dtypes: float64(1), object(2)
memory usage: 30.9+ KB
# 借由上面的输出,我们设计如下几个数据处理的任务:
# 1) age这个数据列,只有633个,需要补完。
# 2) sex 与 pclass两个数据列的值都是类别型的,需要转化为数值特征,用0/1代替。
# 首先我们补充age里的数据,使用平均数或者中位数都是对模型偏离造成最小影响的策略。
X['age'].fillna(X['age'].mean(), inplace=True)
X.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1313 entries, 0 to 1312
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 pclass 1313 non-null object
1 age 1313 non-null float64
2 sex 1313 non-null object
dtypes: float64(1), object(2)
memory usage: 30.9+ KB
# 由此得知,age特征得到了补完。
# 数据分割。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state = 33)
# 我们使用scikit-learn.feature_extraction中的特征转换器,详见3.1.1.1特征抽取。
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
# 转换特征后,我们发现凡是类别型的特征都单独剥离出来,独成一列特征,数值型的则保持不变。
X_train = vec.fit_transform(X_train.to_dict(orient='record'))
print(vec.feature_names_)
['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
# 同样需要对测试数据的特征进行转换。
X_test = vec.transform(X_test.to_dict(orient='record'))
# 从sklearn.tree中导入决策树分类器。
from sklearn.tree import DecisionTreeClassifier
# 使用默认配置初始化决策树分类器。
dtc = DecisionTreeClassifier()
# 使用分割到的训练数据进行模型学习。
dtc.fit(X_train, y_train)
# 用训练好的决策树模型对测试特征数据进行预测。
y_predict = dtc.predict(X_test)
# 从sklearn.metrics导入classification_report。
from sklearn.metrics import classification_report
# 输出预测准确性。
print (dtc.score(X_test, y_test))
# 输出更加详细的分类性能。
print (classification_report(y_predict, y_test, target_names = ['died', 'survived']))
0.7811550151975684
precision recall f1-score support
died 0.91 0.78 0.84 236
survived 0.58 0.80 0.67 93
accuracy 0.78 329
macro avg 0.74 0.79 0.75 329
weighted avg 0.81 0.78 0.79 329
特点分析
相比于其他模型,决策树在模型描述上有着巨大的优势。决策树的推断逻辑非常直观,具有清晰的可解释性,也方便了模型的可视化。这些特性同时也保证在使用决策树模型时,无需考虑对数据的量化甚至标准化。与K邻近不同的是,决策树仍然属于有参数模型,需要花费更多的时间在训练数据上。
网友评论