决策树分类器在Scikit-learn的使用小结

scikit-learn决策树算法库介绍

  scikit-learn决策树算法库内部实现是使用了调优过的CART树算法,既可以做分类,又可以做回归。分类决策树的类对应的是DecisionTreeClassifier,而回归决策树的类对应的是DecisionTreeRegressor。两者的参数定义几乎完全相同,但是意义不全相同。
  本文详细介绍DecisionTreeClassifier 在python scikit-learn上的使用。
  包含数据读取,模块载入,模块使用,规则导出,模型保存,调参说明。

模块加载

import pandas as pd
from sklearn import tree

数据载入

#训练集数据读取
train = pd.read_csv('train.csv')
target='TRADER' # TRADER的值就是二元分类的输出(列名)
ID = 'USER_ID' 
train['TRADER'].value_counts() #类别计算

x_columns0 = [x for x in train.columns if x not in [target, ID]]
X = train[x_columns0]
y = train['TRADER']

#测试集数据读取
test = pd.read_csv('test.csv')
test['TRADER'].value_counts() #类别计算
x_columns1 = [x for x in test.columns if x not in [target, ID]]
x_test = test[x_columns1]
y_test = test['TRADER']

print ('数据读取完毕')

另外,读取excel格式会比csv格式的数据速度慢很多,至少在我这个数据集上是这样子的。csv用了不到5s,而excel读取花了1min+。

#引入tree模块,对应的参数设置将于后面提及
clf = tree.DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
            max_features=7, max_leaf_nodes=None,
            min_impurity_split=0.005, min_samples_leaf=3,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            presort=False, random_state=1, splitter='random')
clf = clf.fit(X,y) #此时完成训练

y_pred=clf.predict(x_test) #预测

#混淆矩阵模块
from sklearn.metrics import confusion_matrix
print confusion_matrix(y_test,y_pred)#验证集上的混淆矩阵

y_tpre=clf.predict(X)
print confusion_matrix(y,y_tpre)#训练集上的混淆矩阵

#准确率及召回率等Report模块
from sklearn.metrics import classification_report
print classification_report(y_test,y_pred)

参数设置说明

tree.DecisionTreeClassifier(class_weight=None, #balanced & None 可选
                            criterion='gini',#"gini"或者"entropy",前者代表基尼系数,后者代表信息增益。
                            max_depth=None,#max_depth控制树的深度防止overfitting
            max_features=None, #可使用多种类型值,默认是"None",划分时考虑所有的特征数;
                               #"log2" 划分时最多考虑log2Nlog2N个特征;
                               #"sqrt"或者"auto" 划分时最多考虑√N个特征。
                               #整数,代表考虑的特征绝对数。
                               #浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。
                               #其中N为样本总特征数。
            max_leaf_nodes=None,#最大叶节点树
            min_impurity_split=1e-07, #限制决策树的增长,
                            #如果某节点的不纯度(基尼系数,信息增益)小于这个阈值,则该节点不再生成子节点,即为叶子节点。 
            min_samples_leaf=1,min_samples_split=2,#min_samples_split或min_samples_leaf来控制叶节点上的样本数量;
            #两者之间的主要区别在于min_samples_leaf保证了叶片中最小的样本数量,而min_samples_split可以创建任意的小叶子。但min_samples_split在文献中更常见。
            min_weight_fraction_leaf=0.0,#限制叶子节点所有样本权重和的最小值。如果小于这个值,则会和兄弟节点一起被剪枝。
                            # 默认是0,就是不考虑权重问题。
                            #一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,
                            #就会引入样本权重,这时我们就要注意这个值了。
            presort=False,#布尔值,默认是False不排序。预排序,提高效率。
                          #设置为true可以让划分点选择更加快,决策树建立的更加快。
            random_state=None, #随机生成器种子设置,默认设置为None,如此,则每次模型结果都会有所不同。
            splitter='best')#split"best"或者"random"。
           #前者在特征的所有划分点中找出最优的划分点。
           #后者是随机的在部分划分点中找局部最优的划分点。
           #默认的"best"适合样本量不大的时候,而如果样本数据量非常大,此时决策树构建推荐"random"。

Scikit-learn官方文档说明:

http://scikit-learn.org/stable/modules/tree.html#tree-classification

模型保存及读取

from sklearn.externals import joblib #pip install joblib
joblib.dump(clf, 'filename.pkl')  #保存为pkl文件

clf = joblib.load('filename.pkl') #读取模型文件
y_tpred=clf.predict(x_test)#进行预测,预测数据仍需重新导入。

模型规则导出

#方法一:dot文件,类似word形式的规则
import sys  
import os     
os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/' #有时候python会很笨,仍然找不到graphviz,这时需在代码里面加入该行。注意后面的路径是graphviz的bin目录。
with open("trader.dot", 'w') as f:
    f = tree.export_graphviz(clf, out_file=f)
print '写入dot文件完成!'

#使用该方法需事先:
 "第一步是安装graphviz。下载地址:http://www.graphviz.org/。
   如果你是linux,可以用apt-get或者yum的方法安装。
   如果是windows,就在官网下载msi文件安装。
    无论是linux还是windows,装完后都要设置环境变量,将graphviz的bin目录加到PATH。
  第二步是安装python插件graphviz:pip install graphviz
  第三步是安装python插件pydotplus:pip install pydotplus"
#方法二:pdf文件
import graphviz
import pydotplus 
dot_data = tree.export_graphviz(clf, out_file=None) 
graph = pydotplus.graph_from_dot_data(dot_data) 
graph.write_pdf("trader.pdf") 
#方法三:png图片形式
from IPython.display import Image  
dot_data = tree.export_graphviz(clf, out_file=None, 
                         feature_names=train.feature_names,  
                         class_names=train.target_names, 
                         filled=True, rounded=True,  
                         special_characters=True)  
graph = pydotplus.graph_from_dot_data(dot_data)  
Image(graph.create_png()) 

调参

param_test1 = {'max_features':range(3,9,1),'random_state':range(0,10,1),'min_samples_leaf':range(1,10,1)}
gsearch1 = GridSearchCV(estimator = tree.DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
            max_leaf_nodes=None,
            min_impurity_split=0.005,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            presort=False, random_state=1, splitter='random'), 
                       param_grid = param_test1, scoring='roc_auc',cv=5)
gsearch1.fit(X,y)
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_

GridSearchCV官方文档介绍:
http://scikit-learn.org/stable/modules/generated/sklearn.grid_search.GridSearchCV.html

相应参数简要说明:
estimator:所用的模型,包含模型参数设置,除需搜索调整以及默认的参数外都要。

param_grid:dict or list of dictionaries,如{‘列名’:取值的list,如range(3,9,1),…},建议不要太多,调参过程可优先选择重要(贡献大、变化大)的列进行调整,看感觉。由于是网格搜索,也就是当前param_grid 所有情况的枚举,注意控制时间。

cv:即交叉验证(Cross-validation),如10折交叉验证,将数据集分成十份,轮流将其中9份做训练1份做测试,10次的结果的均值作为对算法精度的估计。

关于GridSearchCV的内容目前我就接触这么点,所以无法展开详细的说明。

调参完后,根据最优参数输入对应的模型,进一步分析。

注:本文代码在Anaconda2上运行,对应的是python2的版本,与3差异就在print后面的括号。

参考文章:
1.scikit-learn随机森林调参小结 http://www.cnblogs.com/pinard/p/6160412.html
2.scikit-learn决策树使用小结 http://www.cnblogs.com/pinard/p/6056319.html

推荐文章:
1.决策树五大算法比较 http://bbs.pinggu.org/thread-3852506-1-1.html

没有更多推荐了,返回首页