Python 第三方库决策树算法
一、决策树分类器第三方库参数及涉及的函数参数介绍
(1)DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None,min_samples_split=2, min_samples_leaf=1,min_weight_fraction_leaf=0.0,
max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort=False)
- criterion:用于指定选择节点字段的评价指标,对于分类决策树,默认为'gini',表示采用基尼指数选择节点的最佳分割字段;对于回归决策树,默认为'mse',表示使用均方误差选择节点的最佳分割字段
- splitter:用于指定节点中的分割点选择方法,默认为'best',表示从所有的分割点中选择最佳分割点;如果指定为'random',则表示随机选择分割点
- max_depth:用于指定决策树的最大深度,默认为None,表示树的生长过程中对深度不做任何限制
- min_samples_split:用于指定根节点或中间节点能够继续分割的最小样本量, 默认为2
- min_samples_leaf:用于指定叶节点的最小样本量,默认为1
- min_weight_fraction_leaf:用于指定叶节点最小的样本权重,默认为None,表示不考虑叶节点的样本权值
- max_features:用于指定决策树包含的最多分割字段数,默认为None,表示分割时使用所有的字段,与指定'auto'效果一致;如果为具体的整数,则考虑使用对应的分割字段数;如果为0~1的浮点数,则考虑对应百分比的字段个数;如果为'sqrt',则表示最多考虑√𝑃个字段;如果为'log2',则表示最多使用〖𝑙𝑜𝑔〗_2 𝑃个字段
- random_state:用于指定随机数生成器的种子,默认为None,表示使用默认的随机数生成器
- max_leaf_nodes:用于指定最大的叶节点个数,默认为None,表示对叶节点个数不做任何限制
- min_impurity_decrease:用于指定节点是否继续分割的最小不纯度值,默认为0
- min_impurity_split:同参数min_impurity_decrease含义一致,该参数已在0.21版本剔除
- class_weight:用于指定因变量中类别之间的权重,默认为None,表示每个类别的权重都相等;如果为balanced,则表示类别权重与原始样本中类别的比例成反比;还可以通过字典传递类别之间的权重差异,其形式为{class_label:weight}
- presort:bool类型参数,是否对数据进行预排序,默认为False。如果数据集的样本量比较小,设置为True可以提高模型的执行速度;如果数据集的样本量比较大,则不易设置为True
官方链接:https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
(2)sklearn.model_selection .GridSearchCV(estimator, param_grid, scoring=None, n_jobs=None, iid=’warn’, refit=True, cv=’warn’, verbose=0, pre_dispatch=‘2*n_jobs’,
error_score=’raise-deprecating’, return_train_score=False)[source]
- estimator:所使用的分类器,如 estimator = tree.DecisionTreeClassifier()
- param_grid:值为字典或者列表,即分类器需要最优化的参数的取值
- scoring:准确度评价标准,默认None,这时需要使用score函数;或者如scoring='roc_auc',根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。
- n_jobs:并行数,int:个数,-1:跟CPU核数一致, 1:默认值。
- pre_dispatch:指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次
- iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。
- cv:交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。
- refit:默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。
- verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。
Attributes:
- best_estimator_:效果最好的分类器
- best_score_:成员提供优化过程期间观察到的最好的评分
- best_params_:描述了已取得最佳结果的参数的组合
- best_index_:对应于最佳候选参数设置的索引(cv_results_数组的索引)。
Methods:
- decision_function:使用找到的参数最好的分类器调用decision_function。
fit(X, y=None, groups=None, **fit_params):训练
get_params(deep=True):获取这个估计器的参数
- predict(X):用找到的最佳参数调用预估器。(直接预测每个样本属于哪一个类别)
- predict_log_proda(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分取log情况)
- predict_proba(X):用找到的最佳参数调用预估器。(得到每个测试集样本在每一个类别的得分情况)
- score(X, y=None):返回给定数据上的得分,如果预估器已经选出最优的分类器。
- transform(X):调用最优分类器进行对X的转换。
官方链接:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html
二、决策树算法实战
1 def dataset():
"""导入数据及测试"""" 2 # 导入第三方模块 3 import pandas as pd 4 5 # 读入数据 6 Titanic = pd.read_csv(r'Titanic.csv') 7 # 删除无意义的变量,并检查剩余自字是否含有缺失值 8 Titanic.drop(['PassengerId','Name','Ticket','Cabin'], axis = 1, inplace = True) # axis = 1纵向删除 9 10 # 对Sex分组,用各组乘客的平均年龄填充各组中的缺失年龄 11 fillna_Titanic = [] 12 for i in Titanic.Sex.unique(): 13 update = Titanic.loc[Titanic.Sex == i].fillna(value = {'Age': Titanic.Age[Titanic.Sex == i].mean()}, inplace = False) 14 fillna_Titanic.append(update) 15 Titanic = pd.concat(fillna_Titanic) 16 # 使用Embarked变量的众数填充缺失值,也可以用其他插值方法 17 Titanic.fillna(value = {'Embarked':Titanic.Embarked.mode()[0]}, inplace=True) 18 19 # 将数值型的Pclass转换为类别型,否则无法对其哑变量处理 20 Titanic.Pclass = Titanic.Pclass.astype('category') 21 # 哑变量处理 22 dummy = pd.get_dummies(Titanic[['Sex','Embarked','Pclass']]) 23 # 水平合并Titanic数据集和哑变量的数据集 24 Titanic = pd.concat([Titanic,dummy], axis = 1) 25 # 删除原始的Sex、Embarked和Pclass变量 26 Titanic.drop(['Sex','Embarked','Pclass'], inplace=True, axis = 1) 27 28 return Titanic 29
1 def chooseBestParemete(Titanic):
"""寻找参数最优解""" 2 # 导入第三方包 3 from sklearn import model_selection 4 from sklearn.model_selection import GridSearchCV 5 from sklearn import tree 6 7 # 取出所有自变量名称 8 predictors = Titanic.columns[1:] 9 # 将数据集拆分为训练集和测试集,且测试集的比例为25% 10 X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived, 11 test_size = 0.25, random_state = 1234) 12 13 # 预设各参数的不同选项值 14 max_depth = [2,3,4,5,6] 15 min_samples_split = [2,4,6,8] 16 min_samples_leaf = [2,4,8,10,12] 17 # 将各参数值以字典形式组织起来 18 parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf} 19 # 网格搜索法,测试不同的参数值 20 grid_dtcateg = GridSearchCV(estimator = tree.DecisionTreeClassifier(), param_grid = parameters, cv=10) 21 # 模型拟合 22 grid_dtcateg.fit(X_train, y_train) 23 # 返回最佳组合的参数值 24 bestParams = grid_dtcateg.best_params_ 25 26 return bestParams
1 if __name__=='__main__': 2 """代码测试""" 3 Titanic = dataset() 4 bestParams = chooseBestParemete(Titanic) 5 print(bestParams)
结果:
{'max_depth': 3, 'min_samples_leaf': 4, 'min_samples_split': 2}
(二)计算模型准确率及Roc值
(1)准确率代码
1 def model_traintest(): 2 """模型训练及测试准确率""" 3 # 导入第三方模块 4 from sklearn import metrics 5 from sklearn.tree import DecisionTreeClassifier 6 7 #调用函数获取数据 8 Titanic = dataset() 9 # 将数据集拆分为训练集和测试集,且测试集的比例为25% 10 X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived, 11 test_size = 0.25, random_state = 1234) 12 13 # 构建分类决策树 14 CART_Class = tree.DecisionTreeClassifier(max_depth=4, min_samples_leaf = 8, min_samples_split=8) 15 # 模型拟合 16 decision_tree = CART_Class.fit(X_train, y_train) 17 # 模型在测试集上的预测 18 pred = CART_Class.predict(X_test) 19 20 # 模型的准确率 21 print('模型在测试集的预测准确率:',metrics.accuracy_score(y_test, pred))
1 model_traintest()
结果:
模型在测试集的预测准确率: 0.8430493273542601
(2)Roc可视化
1 def vision(): 2 """模型训练计算roc值并可视化""" 3 # 导入第三方模块 4 from sklearn import metrics 5 from sklearn.tree import DecisionTreeClassifier 6 7 #调用dataset()函数获取数据 8 Titanic = dataset() 9 # 将数据集拆分为训练集和测试集,且测试集的比例为25% 10 X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived, 11 test_size = 0.25, random_state = 1234) 12 13 # 构建分类决策树 14 CART_Class = DecisionTreeClassifier(max_depth=4, min_samples_leaf = 8, min_samples_split=8) 15 # 模型拟合 16 decision_tree = CART_Class.fit(X_train, y_train) 17 18 #计算每类标签的得分率 19 y_score = CART_Class.predict_proba(X_test)[:,1] 20 # 计算AUC的值 21 fpr,tpr,threshold = metrics.roc_curve(y_test, y_score) 22 23 roc_auc = metrics.auc(fpr,tpr) 24 25 # 绘制面积图 26 plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black') 27 # 添加边际线 28 plt.plot(fpr, tpr, color='black', lw = 1) 29 # 添加对角线 30 plt.plot([0,1],[0,1], color = 'red', linestyle = '--') 31 # 添加文本信息 32 plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc) 33 # 添加x轴与y轴标签 34 plt.xlabel('1-Specificity') 35 plt.ylabel('Sensitivity') 36 # 显示图形 37 plt.show()
结果:

(三)模型最终的决策树
1 def creat_tree(): 2 # 需要在电脑中安装Graphviz 3 # https://graphviz.gitlab.io/_pages/Download/Download_windows.html 4 # 然后将解压文件中的bin设置到环境变量中 5 # 导入第三方模块 6 from sklearn.tree import export_graphviz 7 from IPython.display import Image 8 import pydotplus 9 from sklearn.externals.six import StringIO 10 from sklearn import metrics 11 from sklearn.tree import DecisionTreeClassifier 12 13 #调用dataset()函数获取数据 14 Titanic = dataset() 15 # 将数据集拆分为训练集和测试集,且测试集的比例为25% 16 X_train, X_test, y_train, y_test = model_selection.train_test_split(Titanic[predictors], Titanic.Survived, 17 test_size = 0.25, random_state = 1234) 18 19 # 构建分类决策树 20 CART_Class = DecisionTreeClassifier(max_depth=4, min_samples_leaf = 8, min_samples_split=8) 21 # 模型拟合 22 decision_tree = CART_Class.fit(X_train, y_train) 23 24 # 绘制决策树 25 dot_data = StringIO() 26 export_graphviz( 27 decision_tree, 28 out_file=dot_data, 29 feature_names=predictors, 30 class_names=['Unsurvived','Survived'], 31 # filled=True, 32 rounded=True, 33 special_characters=True 34 ) 35 # 决策树展现 36 graph = pydotplus.graph_from_dot_data(dot_data.getvalue()) 37 return Image(graph.create_png())
结果:

浙公网安备 33010602011771号