一、决策树分类器第三方库参数及涉及的函数参数介绍
(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())
结果: