[机器学习 04] 树,集成学习-sklearn

    技术2022-07-10  249

    特点:树结构清晰,而且运算快。 关键问题:树的构建。 缺点:树的能力太强,一般都会过拟合。——特征一层一层划分,可以把所有特征分完,所有的特征都会被分到最细,因此会造成数据过拟合。也因此,树可以剪枝。

    1. 决策树

    (1)决策树是一种分类树。 (2)基础知识: ① 熵:信息的不确定性。(熵的最大化,可以达到最大的探索能力,即信息量越大,遇到的可能性越多。) ② 条件熵:再已知随机变量X的条件下,随机变量Y的不确定性。 就是说,我们在不知道任何事情的情况下,不确定性最大,也就是信息量最多,当某事发生后,实际上某些事情就被确定了,剩下的不确定性就变少了,信息量也就变少了。 ③ 信息增益:表示已知特征X的信息而使得Y的信息的不确定性减少的程度。(就是发生某事后,不确定信息减少了,信息增益就是减少的这一部分,即信息增加了多少。——熵减去条件熵) ④ 信息增益率:假设H(D)为一个信息熵,当A事件发生后,H(D | A)为A发生后D的条件熵。信息增益为g(D,A) = H(D)-H(D | A);信息增益率为g(D ,A)/ HA(D);HA(D)为数据集D关于特征A的值的熵。(即信息增加的比率) ⑤ 基尼指数:表示集合D不确定性,基尼指数越小,样本的不确定性越小。(基尼指数取值范围0-1之间) (3)决策树的构建:按照数据的信息熵划分树的分支——熵越大,信息量越大。所以根结点的信息量最大,往下根据特征的不同,信息量逐渐降低。 按照不同的划分标准,可以生成不同的决策树。 ① ID3:信息增益;各个结点上根据信息增益来选择进行划分。

    缺点:没有剪枝;采用信息增益作为选择最优划分特征的标准,然而信息增益会偏向那些取值较多的特征。 因此,改进可以用C4.5.

    ② C4.5:信息增益率;各个结点上根据信息增益率来选择进行划分。

    信息增益率克服了用信息增益选择的不足; 在构造树的过程中进行了剪枝; 可对连续值与缺失值进行处理。

    ③ CART 分类回归树(可回归也可分类):基尼指数;各个结点上根据基尼指数来选择进行划分。 (4)剪枝:① 规定最大深度;② 规定每个子节点最小/最大的叶子数;③ 最大特征数。

    # 决策树 # import numpy as np from sklearn import tree, datasets, preprocessing from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import graphviz np.random.RandomState(0) # 加载数据 wine = datasets.load_wine() # 划分训练集与测试集 x, y = wine.data, wine.target x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3,random_state=0) # 数据预处理 scaler = preprocessing.StandardScaler().fit(x_train) x_train = scaler.transform(x_train) x_test = scaler.transform(x_test) # 创建模型 # 划分标准 gini 基尼指数 # max_depth=4 规定最大深度——相当于剪枝 clf = tree.DecisionTreeClassifier(criterion="gini",random_state=0,max_depth=4) # 模型拟合 clf.fit(x_train, y_train) # 预测 y_pred = clf.predict(x_test) # 评估 print(accuracy_score(y_test, y_pred)) # 查看特征权重 print(wine.feature_names) print(clf.feature_importances_) dot_data = tree.export_graphviz(clf, out_file=None, feature_names=wine.feature_names, class_names=wine.target_names, filled=True, rounded=True, special_characters=True) graph = graphviz.Source(dot_data) graph.render("wine")

    2. 回归树

    一般来讲,能用来分类的模型,都可以用来回归。 CART回归树:不断的进行二分类。 红色线为普通的线性回归,另外两条线为限制不同深度后拟合得到的线。(可以看出决策树的能力非常强)

    import numpy as np import matplotlib.pyplot as plt from sklearn.tree import DecisionTreeRegressor from sklearn import linear_model # Data set x = np.array(list(range(1, 11))).reshape(-1, 1) y = np.array([5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05]).ravel() # Fit regression model model1 = DecisionTreeRegressor(max_depth=1) model2 = DecisionTreeRegressor(max_depth=3) model3 = linear_model.LinearRegression() model1.fit(x, y) model2.fit(x, y) model3.fit(x, y) # Predict X_test = np.arange(0.0, 10.0, 0.01)[:, np.newaxis] y_1 = model1.predict(X_test) y_2 = model2.predict(X_test) y_3 = model3.predict(X_test) # Plot the results 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=1", linewidth=2) plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=3", linewidth=2) plt.plot(X_test, y_3, color='red', label='liner regression', linewidth=2) plt.xlabel("data") plt.ylabel("target") plt.title("Decision Tree Regression") plt.legend() plt.show()

    集成学习

    多个模型一起使用,规定某种评价标准,来得到目标结果。从而提高模型的泛化能力/鲁棒性。 ① 同一种模型,不同参数。 ② 不同模型,不同参数。 决策方法: ① 平均方法:多个不同模型的预测结果占的权重都是一样的,取它们结果的平均作为最终结果。(bagging,随即深林。) ② boosting 递进式方法:结合多个弱模型集成一个较强的模型,再结合再增强。逐步提升模型的强度,得到更好的结果。(adaboost,GBRT)

    1. 随机深林

    # 随机深林 # 树的数量 最大深度 clf = ensemble.RandomForestClassifier(n_estimators=25,max_depth=3) ''' def __init__(self, n_estimators=100, criterion="gini", max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0., max_features="auto", max_leaf_nodes=None, min_impurity_decrease=0., min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None): '''

    2. Bagging

    # bagging 可以用任意方法创建模型 随机参数随机采样 # 模型 模型数量(多少个模型进行集成) 最大随机采样数 最大随机特征数 clf = ensemble.BaggingClassifier(neighbors.KNeighborsClassifier(), n_estimators=10, max_samples=0.5, max_features=0.5) ''' def __init__(self, base_estimator=None, n_estimators=10, max_samples=1.0, max_features=1.0, bootstrap=True, bootstrap_features=False, oob_score=False, warm_start=False, n_jobs=None, random_state=None, verbose=0): '''

    3. Adaboost

    Adaboost算法是一种提升方法,将多个弱分类器,组合成强分类器。

    ① 初始化训练数据的权值分布,使得每个样本点开始都有相同的权重,1/N。 ② 训练弱分类器。如果某个样本已经被准确地分类,那么构造下一个训练分类器中,它的权重就被降低;相反,如果某个样本点没有被准确分类,那么它的权重就得到提高。 ③ 将各个训练得到的弱分类器组合成强分类器,不断更新每个分类器的权重,使得最终的分类函数中,误差较大的弱分类器话语权较小,反之误差较小的弱分类器话语权较大,最终的结果就是每一个分类器的加权平均。

    # Adaboost clf = ensemble.AdaBoostClassifier(n_estimators=50)

    4. GBRT

    GBRT(梯度提升树):对任意的可微损失函数的提升算法的泛化,即可回归亦可分类。

    即每次计算都是为了减少上一次的残差,为了减少这些残差,在每次残差减少的梯度方向上建立一个新的模型。换句话说,就是每次调整参数,通过一个新的模型进行调整。 优点: ① 对混合型数据的自然处理(异构特征); ② 强大的预测能力; ③ 在输出空间中对异常点的鲁棒性。

    # Fit regression model # GBRT model1 = ensemble.GradientBoostingRegressor(max_depth=1,n_estimators=20)
    Processed: 0.026, SQL: 9