sklearn:模型拟合和数据处理
决策树:决策树(Decision Tree)是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。决策树算法容易理解,适用各种数据,在解决各种问题时都有良好表现,尤其是以树模型为核心的各种集成算法,简单理解就是一种分类画图工具。
节点:决策树分类时不同标准分开的地方
根节点:没有进边,有出边。包含最初的,针对特征的提问。
中间节点:既有进边也有出边,进边只有一条,出边可以有很多条。都是针对特征的提问。
叶子节点:有进边,没有出边,每个叶子节点都是一个类别标签。
*子节点和父节点:在两个相连的节点中,更接近根节点的是父节点,另一个是子节点。
决策树算法的核心是要解决两个问题:
1.如何从数据表中找出最佳节点和最佳分枝
2.如何让决策树停止生长,防止过拟合
sklearn————决策树*
1.10,分类
DecisionTreeClassifier是一个能够执行多类的类 对数据集进行分类。
from sklearn import tree
X = [[0, 0], [1, 1]]
Y = [0, 1] clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, Y) # 拟合之后预测样本类型
clf.predict([[2., 2.]])
# 拟合之后预测样本类型
clf.predict([[2., 2.]])
1.1.0DecisionTreeClassifier能够同时处理二进制(其中 标签为 [-1, 1])分类和多类(其中标签为 [0, …, K-1]) 分类。
使用 Iris 数据集,我们可以构建一棵树
from sklearn.datasets import load_iris
from sklearn import tree iris = load_iris()
X, y = iris.data, iris.target
clf = tree.DecisionTreeClassifier()
clf = clf.fit(X, y)
tree.plot_tree(clf)
如下所示:
1.10.2回归DecisionTreeRegressor
与DecisionTreeClassifier一样,拟合方法将采用数组 X 作为参数 和 y,只是用DecisionTreeRegressor了之后y 预计具有浮点值 而不是整数值:
from sklearn import tree X = [[0, 0], [2, 2]] y = [0.5, 2.5] clf = tree.DecisionTreeRegressor() clf = clf.fit(X, y) clf.predict([[1, 1]])
决策树回归例子
import matplotlib.pyplot as plt
import numpy as np
from sklearn.tree import DecisionTreeRegressor
rng = np.random.RandomState(1) # 创建随机数据
X = np.sort(5 * rng.rand(80, 1), axis=0) #对随机生成数据排序
y = np.sin(X).ravel() #其中X是按列排序的随机数,而y是对X进行正弦变换后的结果,并在其中的一些点上加入了一些噪声。
y[::5] += 3 * (0.5 - rng.rand(16))
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(X, y)
regr_2.fit(X, y)
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)
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black", c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue", label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
1.10.3多输出问题
多输出问题是具有多个输出的监督学习问题 来预测,即当 Y 是形状为 的二维数组时。
当建立n个独立的模型,每个模型一个 输出,然后使用这些模型独立预测 n 个中的每一个模型 输出。然而,因为输出值很可能与 相同的输入本身是相关的,所以最好构建一个单一的 能够同时预测所有 n 个输出的模型。它需要 由于只构建了一个估计器,因此训练时间较短。 估计器的泛化精度也可以提高。
对于决策树,该策略可以很容易地用于支持 多输出问题。这需要进行以下更改:
将n个输出值存储在叶子中,而不是1个;
使用分割标准来计算所有数据的平均减少量 n 个输出。
该模块通过实现此功能来提供对多输出问题的支持 DecisionTreeClassifier 和 中的策略 DecisionTreeRegressor。如果决策树适合输出数组 Y 形状 那么生成的估计器将:
输出n_output值
predict
;输出 n_output 个类别概率数组的列表
predict_proba
。
多输出决策树回归例子
决策树 用于同时预测圆的噪声 x 和 y 观测值 给定一个单一的基本特征。结果,它学习局部线性 近似圆的回归。
由图可以看到,如果树的最大深度(由 max_depth
参数)设置得太高,决策树学习得太精细 训练数据的细节并从噪声中学习,即它们过度拟合。
import matplotlib.pyplot as plt import numpy as np
from sklearn.tree import DecisionTreeRegressor
rng = np.random.RandomState(1)
X = np.sort(200 * rng.rand(100, 1) - 100, axis=0)
y = np.array([np.pi * np.sin(X).ravel(), np.pi * np.cos(X).ravel()]).T
[::5, :] += 0.5 - rng.rand(20, 2)
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_3 = DecisionTreeRegressor(max_depth=8)
regr_1.fit(X, y)
regr_2.fit(X, y)
regr_3.fit(X, y)
X_test = np.arange(-100.0, 100.0, 0.01)[:, np.newaxis] #升为高维(二维数组)
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
y_3 = regr_3.predict(X_test)
plt.figure()
s = 25
plt.scatter(y[:, 0], y[:, 1], c="navy", s=s, edgecolor="black", label="data")
plt.scatter( y_1[:, 0], y_1[:, 1], c="cornflowerblue", s=s, edgecolor="black", label="max_depth=2", ) plt.scatter(y_2[:, 0], y_2[:, 1], c="red", s=s, edgecolor="black", label="max_depth=5")
plt.scatter( y_3[:, 0], y_3[:, 1], c="orange", s=s, edgecolor="black", label="max_depth=8" ) plt.xlim([-6, 6]) plt.ylim([-6, 6])
plt.xlabel("target 1")
plt.ylabel("target 2")
plt.title("Multi-output Decision Tree Regression")
plt.legend(loc="best")
plt.show()
可以明显看出不同最大深度对数据不同的影响,明显max_depth设置的太高很容易过度拟合
进而对样本产生误差预估
使用多输出估计器对人脸补全
通过与第一列图像对比,可以看出随机树、k近邻、线性回归和岭回归还原面的下半部分的效果。
import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import fetch_olivetti_faces from sklearn.ensemble import ExtraTreesRegressor from sklearn.linear_model import LinearRegression, RidgeCV from sklearn.neighbors import KNeighborsRegressor from sklearn.utils.validation import check_random_state # Load the faces datasets data, targets = fetch_olivetti_faces(return_X_y=True) train = data[targets < 30] test = data[targets >= 30] # Test on independent people # Test on a subset of people n_faces = 5 rng = check_random_state(4) face_ids = rng.randint(test.shape[0], size=(n_faces,)) test = test[face_ids, :] n_pixels = data.shape[1] # Upper half of the faces X_train = train[:, : (n_pixels + 1) // 2] # Lower half of the faces y_train = train[:, n_pixels // 2 :] X_test = test[:, : (n_pixels + 1) // 2] y_test = test[:, n_pixels // 2 :] # Fit estimators ESTIMATORS = { "Extra trees": ExtraTreesRegressor( n_estimators=10, max_features=32, random_state=0 ), "K-nn": KNeighborsRegressor(), "Linear regression": LinearRegression(), "Ridge": RidgeCV(), } y_test_predict = dict() for name, estimator in ESTIMATORS.items(): estimator.fit(X_train, y_train) y_test_predict[name] = estimator.predict(X_test) # Plot the completed faces image_shape = (64, 64) n_cols = 1 + len(ESTIMATORS) plt.figure(figsize=(2.0 * n_cols, 2.26 * n_faces)) plt.suptitle("Face completion with multi-output estimators", size=16) for i in range(n_faces): true_face = np.hstack((X_test[i], y_test[i])) if i: sub = plt.subplot(n_faces, n_cols, i * n_cols + 1) else: sub = plt.subplot(n_faces, n_cols, i * n_cols + 1, title="true faces") sub.axis("off") sub.imshow( true_face.reshape(image_shape), cmap=plt.cm.gray, interpolation="nearest" ) for j, est in enumerate(sorted(ESTIMATORS)): completed_face = np.hstack((X_test[i], y_test_predict[est][i])) if i: sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j) else: sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j, title=est) sub.axis("off") sub.imshow( completed_face.reshape(image_shape), cmap=plt.cm.gray, interpolation="nearest", ) plt.show()
决策树使用技巧
1:决策树往往会过度拟合具有大量特征的数据, 高维空间中样本较少的树很可能会过度拟合。考虑执行降维(PCA, ICA,或特征选择) 让你的树有更好的机会找到有区别的特征。
2:树每增加一层填充树所需的样本数量会加倍。使用max_depth
来控制 树的大小以防止过度拟合
3:使用 min_samples_split
或 min_samples_leaf
确保多个 样本通过控制哪些分裂将通知树中的每个决策 予以考虑。非常小的数字通常意味着树会过度拟合, 而大量的数据会阻止树学习数据。尝试 min_samples_leaf=5
作为初始值。如果样本量不同 很大程度上,浮点数可以用作这两个参数的百分比。 虽然 min_samples_split
可以创建任意小的叶子, min_samples_leaf
保证每个叶子都有最小尺寸,避免 回归问题中的低方差、过度拟合叶节点。为了 类别较少的分类,min_samples_leaf=1
通常是最好的 选择
决策树的优缺点
决策树优点
-
易于理解和解释,因为树木可以画出来被看见
-
需要很少的数据准备。其他很多算法通常都需要数据规范化,需要创建虚拟变量并删除空值等。但请注意,sklearn中的决策树模块不支持对缺失值的处理。
-
使用树的成本(比如说,在预测数据的时候)是用于训练树的数据点的数量的对数,相比于其他算法,这是一个很低的成本。
-
能够同时处理数字和分类数据,既可以做回归又可以做分类。其他技术通常专门用于分析仅具有一种变量类型的数据集。
-
能够处理多输出问题,即含有多个标签的问题,注意与一个标签中含有多种标签分类的问题区别开
-
是一个白盒模型,结果很容易能够被解释。如果在模型中可以观察到给定的情况,则可以通过布尔逻辑轻松解释条件。相反,在黑盒模型中(例如,在人工神经网络中),结果可能更难以解释。
-
可以使用统计测试验证模型,这让我们可以考虑模型的可靠性。
-
即使其假设在某种程度上违反了生成数据的真实模型,也能够表现良好。
决策树的缺点
-
决策树学习者可能创建过于复杂的树,这些树不能很好地推广数据。这称为过度拟合。修剪,设置叶节点所需的最小样本数或设置树的最大深度等机制是避免此问题所必需的,而这些参数的整合和调整对初学来说会比较晦涩
-
决策树可能不稳定,数据中微小的变化可能导致生成完全不同的树,这个问题需要通过集成算法来解决。
-
决策树的学习是基于贪婪算法,它靠优化局部最优(每个节点的最优)来试图达到整体的最优,但这种做法不能保证返回全局最优决策树。这个问题也可以由集成算法来解决,在随机森林中,特征和样本会在分枝过程中被随机采样。
-
有些概念很难学习,因为决策树不容易表达它们,例如XOR,奇偶校验或多路复用器问题。
-
如果标签中的某些类占主导地位,决策树学习者会创建偏向主导类的树。因此,建议在拟合决策树之前平衡数据集