决策树的原理即利用不同的最优特征选择方法,优先选择样本纯度最高的特征来进行样本分类。其中:
使用信息增益的决策树算法为 ID3;
使用信息增益率的决策树算法为 C4.5;
使用Gini指数的决策树算法为 CART算法。
ID3算法中,信息增益(Information gain)越大,数据越纯净,越有序,自然地我们优先选取信息增益最大的特征来分类样本。样本集的信息熵(Entorpy)的值越小,其数据越纯,混乱程度越低。
熵增原理:孤立热力系统学系统的熵不减少,总是增大或者不变。一个孤立系统不可能朝低熵的状态发展,即不会变得有序。
in:
#实现jupyter一次多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
本文利用DecisionTreeClassifier决策树分类模型,预测泰坦尼克号的哪些乘客可能成为幸存者。数据集来自:https://www.kaggle.com/c/titanic
sklearn.tree.DecisionTreeClassifier 决策树分类算法类
# 参数解释
criterion: 特征选择算法,一种是基于信息熵,一种是基于基尼指数。 两者对于模型准确性差异不大,相对来讲因为对数运算,信息熵运算效率较低。
splitter: 创建决策树分支,一种是选择最优的分支创建原则,一种是从排名靠前的特征中随机选择一个特征来创建,第二种效果类似于正则化,可避免过拟合。
max_depth: 决策树最大深度。用来解决过拟合问题。
min_samples_split: 指定能创建分支的数据集大小,默认为2. 也是一种前剪枝的方法。
min_samples_leaf: 创建分支后的节点样本数量需大于该值,否则不再创建分支,也是一中前剪枝的方法。
max_leaf_nodes: 限制最大样本节点个数。
min_impurity_split: 指定信息增益阈值。信息增益需大于该值,否则不创建分支。
一、数据清洗与特征选择(预处理)
文件中的csv格式数据中,train.csv是训练集,test.csv为预测集。
train.csv为892行、12列的数据表格,意味着我们有891个训练样本,12个样本特征。在训练模型前,需对12个特征及数据进行预处理:
- 丢弃不需要的特征及对应数据;
- 提取标记列数据;
- 将非数值型数据转换为数值型数据;
- 处理缺失数据、异常数据。
那么先对特征进行逐个分析:
- Passenger:乘客ID,且为顺序编号。此特征用于标识不同样本,在训练中不使用。
- Survived:1幸存,0遇难。此列作为样本标记。
- Pclass:舱位等级。不同舱位等级的人登上甲板的优先程度不同,因此该特征较重要。
- Name:乘客姓名,此特征可丢弃。
- Sex:乘客性别。此特征与登上救生艇的优先程度有关,该特征较重要。需将其转换为数值型数据。
- Age:乘客年龄。儿童优先,因此该特征较重要。
- SibSp:兄弟姐妹在船上的数量。
- Parch:同船的父辈人员数量。
- Ticket:乘客票号,此特征可丢弃。
- Fare:乘客的体热指标。
- Cabin:乘客所在舱船号。舱船号与在船中位置有关,因此有关系。但该特征出现大量缺失数据,因此丢弃该特征。
- Embarked:乘客登船的港口。需将其转换为数值型数据。
in:
#数据预处理
import numpy as np
import pandas as pd
def read_dataset(fname):
# 指定第一列为行索引
data = pd.read_csv(fname, index_col=0)
# 丢弃无用数据
data.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)
# 处理非数值型数据
data['Sex'] = (data['Sex'] == 'male').astype('int') #男性为1,女性为0
labels = data['Embarked'].unique().tolist() #tolist()将数组转换为列表,unique()返回数组中不同的值,从小到大排
data['Embarked'] = data['Embarked'].apply(lambda n: labels.index(n)) #lambda匿名函数
# 处理缺失数据
data = data.fillna(0)
return data
# 疑问:年龄数据缺失数也较多,且存在异常数据,该处理方式合适吗?是否应计算异常数据及缺失数据占总数据的比例,若较少则丢弃?
导入训练集。
in:
train = read_dataset('C:/Users/dell/Desktop/titanic/train.csv')
train.head()
out:
Survived | Pclass | Sex | Age | SibSp | Parch | Fare | Embarked | |
---|---|---|---|---|---|---|---|---|
PassengerId | ||||||||
1 | 0 | 3 | 1 | 22.0 | 1 | 0 | 7.2500 | 0 |
2 | 1 | 1 | 0 | 38.0 | 1 | 0 | 71.2833 | 1 |
3 | 1 | 3 | 0 | 26.0 | 0 | 0 | 7.9250 | 0 |
4 | 1 | 1 | 0 | 35.0 | 1 | 0 | 53.1000 | 0 |
5 | 0 | 3 | 1 | 35.0 | 0 | 0 | 8.0500 | 0 |
train_test_split用来将数据集分为训练集和交叉验证集。
in:
from sklearn.model_selection import train_test_split
Y = train['Survived'].values # 标签
X = train.drop(['Sur