机器学习入门之决策树(python实现)

本次学习利用MT_Train.csv中所给的数据对MT_Test.csv中的数据进行预测,判断客户是否会定期存款。根据所学知识,可采用sklearn中的决策树等方法进行程序设计。欢迎大家一起讨论学习进步。

训练集和测试集链接如下:

一. 设计思路

1.读取训练集和测试集文件

2.对数据进行处理

3.训练决策树

4.输出预测结果

5.将预测结果按要求保存

 代码

import numpy as np
import pydotplus
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder
from sklearn import ensemble
from sklearn.externals.six import StringIO
from sklearn.metrics import precision_recall_curve  
from IPython.display import Image

##read train_scv and test_scv
tmp = np.loadtxt("MT_Train.csv", dtype=np.str, delimiter=",")
tmp_test = np.loadtxt("MT_Test.csv", dtype=np.str, delimiter=",")
y_csv = np.loadtxt("MTSampleSubmission.csv", dtype=np.str, delimiter=",")
data = tmp[1:,:-1]
label = tmp[1:,-1:]
data_test = tmp_test[1:,1:]


#label_test = tmp_test[1:,-1:]
#print(data)
## binarize lable and label_test
lb = preprocessing.LabelBinarizer()
label=lb.fit_transform(label)
#label_test=lb.fit_transform(label_test)
#print(label)

## encode data and data_test
for i in range(1,10):
        data[:,i]=LabelEncoder().fit_transform(data[:,i])
        data_test[:,i]=LabelEncoder().fit_transform(data_test[:,i])
        #print(data[:,i])
data[:,14]=LabelEncoder().fit_transform(data[:,14])
data_test[:,14]=LabelEncoder().fit_transform(data_test[:,14])

## train decision tree
clf = ensemble.RandomForestClassifier(criterion='entropy',n_estimators= 60, max_depth=13, min_samples_split=110)
#print(clf)  
clf.fit(data,label)

#test and caculate precision
y_predict = clf.predict(data_test)

for i in range(0,len(y_predict)):
    if(y_predict[i]==0):
        y_csv[i+1,1] = 'no'
    else:
        y_csv[i+1,1] = 'yes'

np.savetxt('new.csv',y_csv,fmt='%s',delimiter=",")
print("finish")

二. 设计及测试过程

1. 分类器的选择

A. 在最开始的设计中,选择了sklearn中的DecisionTreeClassifier,分类器在之前的作业中使用过,方便简单,用起来得心应手。但是后来发现准确率并不高,只有0.86左右,测试效果没有那么好,于是决定寻找新的方法,或者采用其他分类器,比如神经网络等。

B. 上网查阅资料后,发现两个方法:随机森林算法和ExtraTrees的方法。sklearn.ensemble模块中包含两种基于随机决策树的平均算法:随机森林算法和ExtraTrees的方法。这两种算法都是专为决策树设计的包含混合扰动技术的算法。这意味着分类器依赖着引入随机性来进行建模。整体的预测结果,来自各个独立分类器的综合平均预测结果。原理:随机森林,顾名思义,就是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是独立没有关联的。

C. 由于随机森林与决策树的框架相同,代码修改起来比较简单,只需将DecisionTreeClassifier修改为RandomForestClassifier,导入相应的包即可。具体修改如下:


2. 参数的选择

为了进一步提高准确率,可以对RandomForestClassifier中的参数进行设置,这个过程相当于预剪枝。可设置的参数如下:
 n_estimators: 也就是弱学习器的最代大迭次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是100。

oob_score :即是否采用袋外样本来评估模型的好坏。默认识False。个人推荐设置为True,因为袋外分数反应了一个模型拟合后的泛化能力。

criterion: CART树做划分时对特征的评价标准。分类模型和回归模型的损失函数是不一样的。分类RF对应的CART分类树默认是基尼系数gini,另一个可选择的标准是信息增益。

RF划分时考虑的最大特征数max_features: 可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑log2Nlog2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑N−−√N个特征。

 决策树最大深度max_depth: 默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。

内部节点再划分所需最小样本数min_samples_split: 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

叶子节点最少样本数min_samples_leaf: 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

叶子节点最小的样本权重和min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

最大叶子节点数max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

 节点划分最小不纯度min_impurity_split:  这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。


三. 评价和改进

A. 优点

1. 模型易于理解、结果易于解释;树结构能够可视化

2. 训练决策树的成本随着树的高度呈指数增加。

3. 是一个白盒子模型,易于理解和解释,不像人工神经网络模型(黑盒子),难以解释。

4. 只需少量的数据准备。别的方法经常要求数据标准化,创建虚拟变量,移除空白值。

5. 与神经网络等分类器进行比较,训练时间短,输出结果比神经网络快,节省大量的时间。

B. 缺点

1. 本模型可能存在过拟合或者欠拟合的问题,但是无法直接判断。决策树不宜创建过度复杂的树,以免造成过拟合。需要诸如修剪,设置叶节点所需的最小样本数或设置树的最大深度的机制来避免这个问题。

2. 决策树可能不稳定,小数据的变化可能导致生成完全不同的树。这个问题可以通过在集成模型中使用决策树来缓解。

3. 学习一棵最优决策树相当难的,即使对于相当简单概念。因此,在实际的决策树学习算法中,往往是基于启发式算法(如贪婪算法)来实现。但是贪婪算法并不能得到全局最优结果。这可以通过在集成模型中使用多棵树的方法来缓解面临的问题。

4. 在测试中发现输出结果存在随机性,每次输出的结果都不一样,后来查阅资料后发现random_state必须为已确定值,输出才会稳定。但是多次调试对提高准确率并无多大帮助故设为默认值。

C. 改进

1. 若需要得到稳定的输出结果,可设置random_state

2. 可尝试采用神经网络进行预测。

猜你喜欢

转载自blog.csdn.net/dhaduce/article/details/79033671