机器学习笔记二------决策树

一颗决策树包含一个根结点,若干内部结点(对应一个测试属性)和若干叶结点(对应决策结果)。决策流程采用分而治之的整体思想,根结点包含样本全集,对各个特征进行判断,直至所有叶结点均对应一种类别的样本。

决策树的关键在于划分属性的选择,随着划分不断进行,分支结点所包含样本应尽可能属于同一类别,即纯度越来越高,有三种划分属性选择指标:

(1)  信息增益Gain(D,a)= H(D)-H(D|a):以类别做随机变量,根据各类别比例求得集合集合的信息熵减去用属性a划分后再次计算得到的集合的信息熵即可得到信息增益,信息增益越大,纯度提升越高,可以用最高信息增益选择属性。

缺点:属性可取值越多,得到的信息熵越大,用其划分后信息增益越高,故此方法对属性可取值更多的属性有所偏好

(2)  增益率Gain_ratio(D,a)= Gain(D,a)/Ha(D):信息增益除以属性的固有值(以属性a做随机变量,由集合中a属性各个取值所占的比例计算的信息熵),a可取数值越多,固定值越大,在一定程度上抑制了上述偏好

缺点:对可取数值较小的属性有偏好。故实际上,采用先找信息增益高于平均水平的属性,再从中找增益率高

(3)  基尼指数Gini(D):从集合中随机抽取两个样本,其类别不一致的概率。概率越小,基尼指数越小,数据集纯度越高。

预防过拟合的方法:剪枝

(1)  预剪枝:结点划分前,若划分不能带来泛化性能提高,就停止划分标为叶结点。性能提高的判断由划分前后验证集的精度决定。

优点:分支较少,减小过拟合风险,也减少了训练时间开销和测试时间开销

缺点:带来了欠拟合的风险(当前划分虽不能提升泛化能力,但继续划分呢?)

(2)  后剪枝:生成完整的决策树后自底向上对非叶结点考察,若替换为叶结点能带来泛化性能提升,则替换。

优点:比预剪枝分支多,欠拟合风险小,泛化性能往往优于预剪枝

缺点:训练时间开销大得多

连续值属性处理

将属性取值进行排序,按大于t和小于t分为两个子集,划分点t由最大化信息增益来确定,需要注意的是,对于连续属性,该属性可在决策树中多次使用。

缺省值属性处理

判断属性优劣(如计算信息增益)只考虑没有缺省值的样本,且相应地乘以除去缺省值所占的比例做权重,以保证缺省值不要过多;对于含缺省值样本对于该属性的划分,则根据该属性各种取值的分布情况,以不同的概率划分到不同的结点(划分后样本带权)。

 

代码实践:使用决策树算法预测泰坦尼克号乘客生存情况

# 导入pandas用于数据分析。
import pandas as pd
# 利用pandas的read_csv模块直接从互联网收集泰坦尼克号乘客数据。
titanic =pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
# 观察一下前几行数据,可以发现,数据种类各异,数值型、类别型,甚至还有缺失数据。
titanic.head()
# 使用pandas,数据都转入pandas独有的dataframe格式(二维数据表格),直接使用info(),查看数据的统计特性。
titanic.info()
# 特征的选择,这个需要基于一些背景知识。根据我们对这场事故的了解,sex, age, pclass这些都很有可能是决定幸免与否的关键因素。
X = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
# 对当前选择的特征进行探查。
X.info()
# 首先我们补充age里的缺省值,使用平均数或者中位数都是对模型偏离造成最小影响的策略。
X['age'].fillna(X['age'].mean(), inplace=True)
# 对补完的数据重新探查。
X.info()
# 数据分割。
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_)
# 同样需要对测试数据的特征进行文本转换。
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']))

--来自《Python机器学习及实践 —— 从零开始通往Kaggle竞赛之路》

猜你喜欢

转载自blog.csdn.net/qy724728631/article/details/78632735