六、学习曲线判断选择参数
- 使用学习曲线判断最佳深度
信息熵:
# 使用学习曲线判断最佳深度——信息熵 import matplotlib.pyplot as plt test = [] for i in range(10): clf = tree.DecisionTreeClassifier(max_depth=i+1 #1-10层 ,criterion="entropy" ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,11),test,color="red",label="max_depth") plt.legend() plt.show()
由下图可以看出:使用信息熵得到的最佳深度应该是3
# 使用学习曲线判断最佳深度——基尼系数 import matplotlib.pyplot as plt test = [] for i in range(10): clf = tree.DecisionTreeClassifier(max_depth=i+1 #1-10层 ,criterion="gini" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,11),test,color="red",label="max_depth") plt.legend() plt.show()
由下图可以看出:使用基尼系数得到的最佳深度应该是5
2. 使用学习曲线判断最佳的最小叶子节点样本个数
选取的最小样本从1到30
信息熵:
# 使用学习曲线判断最佳的最小叶子节点样本个数 # 选取的最小样本从1到30 import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(30): clf = tree.DecisionTreeClassifier(min_samples_leaf=i+1 #1-10层 ,criterion="entropy" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,31),test,color="red",label="min_samples_leaf") plt.legend() plt.show()
# 使用学习曲线判断最佳的最小叶子节点样本个数 # 选取的最小样本从1到30 import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(30): clf = tree.DecisionTreeClassifier(min_samples_leaf=i+1 #1-10层 ,criterion="gini" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,31),test,color="red",label="min_samples_leaf") plt.legend() plt.show()
3. 使用学习曲线判断最佳的最小分枝样本数
这里如果直接按照最小叶子节点样本个数的方法,会报如下的错误,
因此要把min_samples_split对应的范围调整在0~1之间:
信息熵:
# 使用学习曲线判断最佳的最小分枝样本数 # 选取的最小样本从1到30 import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(30): clf = tree.DecisionTreeClassifier(min_samples_split=float(i+1)/100 #1-10层 ,criterion="entropy" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,31),test,color="red",label="min_samples_split") plt.legend() plt.show()
# 使用学习曲线判断最佳的最小分枝样本数 # 选取的最小样本从1到30 import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(30): clf = tree.DecisionTreeClassifier(min_samples_split=float(i+1)/100 #1-10层 ,criterion="gini" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,31),test,color="red",label="max_depth") plt.legend() plt.show()
七、目标权重参数
【1】class_weight & min_weight_fraction_leaf
完成样本标签平衡的参数。样本不平衡是指在一组数据集中,标签的一类天生占有很大的比例。
比如说,在银行要判断“一个办了信用卡的人是否会违约”,就是是vs否(1%:99%)的比例。这种分类状况下,即便模型什么也不做,全把结果预测成“否”,正确率也能有99%。
因此我们要使用class_weight参数对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给与数据集中的所有标签相同的权重。
有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_weight_fraction_leaf这个基于权重的剪枝参数来使用。
另请注意,基于权重的剪枝参数(例如min_weight_fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。
【2】class_weight
目标类型的权重,其数据类型为dict或者列表内的dict,或者为"balanced"
【3】min_weight_fraction_leaf
权重剪枝参数,搭配目标权重使用,比min_samples_leaf更偏向于主导类
import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(10): clf = tree.DecisionTreeClassifier(max_depth=i+1 #1-10层 ,criterion="entropy" ,random_state=30 ,splitter="random" ,class_weight="balanced" ,min_weight_fraction_leaf=0.005 ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,11),test,color="red",label="max_depth") plt.legend() plt.show()
八、重要的属性和接口
属性是在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,最重要的是feature_importances_,能够查看各个特征对模型的重要性。
sklearn中许多算法的接口都是相似的,比如之前已经用到的fit和score,几乎对每个算法都可以使用。
除了这两个接口之外,决策树最常用的接口还有apply和predict。
【1】apply中输入测试集返回每个测试样本所在的叶子节点的索引。
【2】predict输入测试集返回每个测试样本的标签。
所有接口中要求输入X_train和X_test的部分,输入的特征矩阵必须至少是一个二维矩阵。sklearn不接受任何一维矩阵作为特征矩阵被输入。
如果你的数据的确只有一个特征,那必须用reshape(-1,1)来给矩阵增维;如果你的数据只有一个特征和一个样本,使用reshape(1,-1)来给你的数据增维。
Xtest.shape clf
八个参数:Criterion,两个随机性相关的参数(random_state,splitter),五个剪枝参数(max_depth,
min_samples_split,min_samples_leaf,max_feature,min_impurity_decrease)
一个属性:feature_importances_
四个接口:fit(拟合),score(评分),apply,predict(样本预测)
九、决策树里面做回归
回归树衡量分枝质量的指标,支持的标准有三种:
【1】使用均方误差MSE,父节点和叶子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子结点的均值来最小化损失。
【2】在回归树当中,MSE不仅是我们分枝质量衡量指标,也是我们最常用的衡量回归树回归质量的指标,当我们在使用交叉验证,或者其他方式获取回归树的结果时,我们往往选择均方误差作为评估。
【3】MSE的本质其实是样本真实数据与回归结果的差异。
CART算法:Classification And Regression Tree
CART,分类与回归树,是一个二分类法,结点的内部特征取值只有是与否。
回归树就是将特定的空间划分为若干个单元,每个特定的单元都有特定的输出。
因为只有是与否两个取值,因此是平行于坐标轴的。
使用波士顿房价的数据:
#简单用法——波士顿房价 from sklearn.datasets import load_boston from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeRegressor boston = load_boston() regressor = DecisionTreeRegressor(random_state=0) cross_val_score(regressor, boston.data, boston.target, cv=10,scoring = "neg_mean_squared_error")
一维回归的图像绘制
# 一维回归的图像绘制 from sklearn.datasets import load_boston from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeRegressor
boston.data.shape
实例化,得到第一次交叉验证的平均值
regressor = DecisionTreeRegressor(random_state=0) #实例化 cross_val_score(regressor, boston.data, boston.target, cv=10).mean()
#### 01 导入库 import numpy as np from sklearn.tree import DecisionTreeRegressor import matplotlib.pyplot as plt
创建含有噪声的正弦曲线
先创建一组随机的,分布在0~5上的横坐标轴的取值(x),然后将这一组值放到sin函数中去生成纵坐标的值(y),接着再到y上去添加噪声。全程使用numpy库来生成这个正弦曲线。
rng = np.random.RandomState(1) X = np.sort(5 * rng.rand(80,1), axis=0) y = np.sin(X).ravel() y[::5] += 3 * (0.5 - rng.rand(16)) #噪声 np.random.random((2,1)) np.random.random((2,1)).ravel() # ravel将多维数组变成一维数组 np.random.random((2,1)).ravel().shape
plt.figure() plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data")
将这句话注释掉,则绘制出来的就是没有噪声的正弦曲线 # y[::5] += 3 * (0.5 - rng.rand(16)) #噪声
#### 03 实例化&训练模型 #创建两个模型,在不同拟合情况下的观察 regr_1 = DecisionTreeRegressor(max_depth=1) # 最大深度为2 regr_2 = DecisionTreeRegressor(max_depth=3) regr_1.fit(X, y) # y是存在噪声的 regr_2.fit(X, y)
# (4)测试集导入模型,预测结果 X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test) y_2 = regr_2.predict(X_test)
#(5)绘制图像 plt.figure(figsize=(16,13)) plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data") plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=1", linewidth=2) plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=3", linewidth=2) plt.xlabel("data") plt.ylabel("target") plt.title("Decision Tree Regression") plt.legend() plt.show()