机器学习系列(10)_决策树与随机森林回归(上)

简介: 优点:易于理解;数据的预处理工作可以较少;使用树的成本比如预测数据的时候,对于训练树的数据点往往使用的是数量的对数;能够同时处理数值和分类数据‘处理多输出的问题;属于易于理解的白盒模型;可通过统计测试试验模型;

一、决策树优缺点



(1)优点:易于理解;数据的预处理工作可以较少;使用树的成本比如预测数据的时候,对于训练树的数据点往往使用的是数量的对数;能够同时处理数值和分类数据‘处理多输出的问题;属于易于理解的白盒模型;可通过统计测试试验模型;


(2)缺点:如果树过于复杂,即过拟合,导致不能很好的推广;可能不稳定;基于贪婪算法;


二、泰坦尼克号幸存者案例



【1】导入库

#(1)导入库
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

【2】导入数据集

#(2)导入数据集
data = pd.read_csv(r"data.csv",index_col= 0)
data.head()
data.info()

590018b346c8402a8e1ca724df847cc9.png

【3】对数据集进行预处理 特征筛选

# (3)对数据集进行预处理  特征筛选
data.drop(["Cabin","Name","Ticket"],inplace=True,axis=1)  
data["Age"] = data["Age"].fillna(data["Age"].mean())
data = data.dropna()
data["Sex"] = (data["Sex"]== "male").astype("int")
labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
data.head()

651500d87cb44053a394db4e4cdf5f4a.png

【4】提取标签和特征矩阵,分测试集和训练集

# (4)提取标签和特征矩阵,分测试集和训练集
X = data.iloc[:,data.columns != "Survived"]
y = data.iloc[:,data.columns == "Survived"]
from sklearn.model_selection import train_test_split
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y,test_size=0.3)
for i in [Xtrain, Xtest, Ytrain, Ytest]:
    i.index = range(i.shape[0])
Xtrain.head()

b7358cb8fb5942bf8897b6c54a01ea3b.png


【5】导入模型,试运行查看结果

#(5) 导入模型,试运行查看结果
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(Xtrain, Ytrain)
score_ = clf.score(Xtest, Ytest)
score_
score = cross_val_score(clf,X,y,cv=10).mean()
score

【6】在不同max_depth下观察模型的拟合状况

# (6)在不同max_depth下观察模型的拟合状况
tr = []
te = []
for i in range(10):  
    clf = DecisionTreeClassifier(random_state=25
                                ,max_depth=i+1
                                ,criterion="entropy"  
                                )
    clf = clf.fit(Xtrain, Ytrain)
    score_tr = clf.score(Xtrain,Ytrain)
    score_te = cross_val_score(clf,X,y,cv=10).mean()
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.plot(range(1,11),tr,color="red",label="train")
plt.plot(range(1,11),te,color="blue",label="test")
plt.xticks(range(1,11))
plt.legend()
plt.show()

9f707b798c444adf9585344ca1a2308b.png


【7】用网格搜索调整参数,枚举参数


网格搜索:

它是通过遍历给定的参数组合来优化模型表现的方法。网格搜索从候选参数集合中,选出一系列参数并把他们组合起来,得到候选参数列表。然后遍历参数列表,把候选参数放在模型中,计算得到该参数组合的得分。而后再从候选参数列表中,选择得分最高的参数,作为模型的最优参数。

# (7)用网格搜索调整参数,枚举参数
import numpy as np
gini_thresholds = np.linspace(0,0.5,20)
parameters = {'splitter':('best','random')
            ,'criterion':("gini","entropy")
            ,"max_depth":[*range(1,10)]
            ,'min_samples_leaf':[*range(1,50,5)]
            ,'min_impurity_decrease':[*np.linspace(0,0.5,20)]
            }
clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf, parameters, cv=10)
GS.fit(Xtrain,Ytrain)
GS.best_params_

通过网格搜索得到的最佳参数:

316075e899a8414f8780c1bd786e4ad0.png


分类树在合成数据上的表现:

sklearn的红酒数据集为例子,展示多个参数会对树形造成怎样的影响。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification
from sklearn.tree import DecisionTreeClassifier

生成三种数据集:

我们先从sklearn自带的数据库中生成三种类型的数据集:

【1】月亮型数据

【2】环形数据

【3】二分型数据

在这三种数据集上测试决策树的效果。

make_classification库生成随机的二分型数据

# 生成三种数据集
# 我们先从sklearn自带的数据库中生成三种类型的数据集:1)月亮型数据,2)环形数据,3)二分型数据
#make_classification库生成随机的二分型数据
X, y = make_classification(n_samples=100, #生成100个样本
                            n_features=2, #包含2个特征,即生成二维数据
                            n_redundant=0, #添加冗余特征0个
                            n_informative=2, #包含信息的特征是2个
                           random_state=1, #随机模式1
                            n_clusters_per_class=1 #每个簇内包含的标签类别有1个
                            )
plt.scatter(X[:,0],X[:,1])

下面这张图两种数据分得较开,使得机器很容易将数据分成两类。但是这样就不利于机器学习

67c3345c0c874ee690bcbaced75f15ce.png

#承接
rng = np.random.RandomState(2) 
X += 2 * rng.uniform(size=X.shape) 
linearly_separable = (X, y) 
plt.scatter(X[:,0],X[:,1])

为数据添加噪声,提升机器学习的难度。

5275cb4b94b1427a8c22bc62ddca1b7b.png

构建不同的数据类型:

# 构建不同的数据类型
datasets = [make_moons(noise=0.3, random_state=0),
            make_circles(noise=0.2, factor=0.5, random_state=1),
            linearly_separable]

71d69fc45f2247c686d3a3e35f9f38ff.png

meshgrid的用法:从坐标向量中返回坐标矩阵

例子:二维坐标系中,X轴可以取三个值 1,2,3, Y轴可以取三个值 7,8, 请问可以获得多少个点的坐标?

显而易见是 6 个:

(1, 7) (2, 7) (3, 7)

(1, 8) (2, 8) (3, 8)

可以用meshgrid实现这个:

import numpy as np
# 坐标向量
a = np.array([1,2,3])
# 坐标向量
b = np.array([7,8])
# 从坐标向量中返回坐标矩阵
# 返回list,有两个元素,第一个元素是X轴的取值,第二个元素是Y轴的取值
res = np.meshgrid(a,b)
#返回结果: [array([ [1,2,3] [1,2,3] ]), array([ [7,7,7] [8,8,8] ])]

画出三种数据集和三棵决策树的分类效应图像:

figure = plt.figure(figsize=(6, 9))
i = 1
for ds_index, ds in enumerate(datasets): # 枚举
    X, y = ds  # X:全部数据
    X = StandardScaler().fit_transform(X) # 标准化,分为训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4,
    random_state=42)
    # 最小值最大值分别做扰动,创造一个比两个特征区间本身更大范围的区间
    x1_min, x1_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    x2_min, x2_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    # meshgrid函数用两个坐标轴上的点在平面上画格。
    # meshgrid生成网格数据,目的是为了绘制决策的边缘
    array1,array2 = np.meshgrid(np.arange(x1_min, x1_max, 0.2),
                        np.arange(x2_min, x2_max, 0.2))
    cm = plt.cm.RdBu # 生成带有特定颜色的画布
    cm_bright = ListedColormap(['#FF0000', '#0000FF'])
    ax = plt.subplot(len(datasets), 2, i) # 绘制子图
    # 行数:len(datasets) ,列数:2
    if ds_index == 0: # 设置图表的标签
        ax.set_title("Input data")
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train,
    cmap=cm_bright,edgecolors='k') #训练集数据
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test,
    cmap=cm_bright, alpha=0.6,edgecolors='k') # 测试集数据
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    ax.set_xticks(()) # 设置标签
    ax.set_yticks(()) # 设置标签
    i += 1 # 循环
    ax = plt.subplot(len(datasets),2,i)
    clf = DecisionTreeClassifier(max_depth=5)
    clf.fit(X_train, y_train)
    score = clf.score(X_test, y_test) # 准确率
    Z = clf.predict_proba(np.c_[array1.ravel(),array2.ravel()])[:, 1]
    Z = Z.reshape(array1.shape)
    ax.contourf(array1, array2, Z, cmap=cm, alpha=.8)
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright,
    edgecolors='k')
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright,
    edgecolors='k', alpha=0.6)
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    ax.set_xticks(())
    ax.set_yticks(())
    if ds_index == 0:
        ax.set_title("Decision Tree")
        ax.text(array1.max() - .3, array2.min() + .3, ('{:.1f}%'.format(score*100)),
                size=15, horizontalalignment='right')
    i += 1
plt.tight_layout()
plt.show()

针对数据拟合的结果:

78edae49a8dd4994aa2c6dd0d4459aa1.png


上图中的第二类对于环形数据使用决策树得到的结果并不准确,因此需要引入新的模型与算法,去解决类似的较复杂的数据的分类和预测。


三、随机森林介绍



集成学习:ensemble learning,对同一个数据集构建多个模型,集成所有模型的建模结果 。


集成算法的目标:考虑多个评估器的建模结果,汇总后得到一个综合结果,一依次获取比单个模型更理想的分类或回归表现。


多个模型集成的模型称为集成评估器(ensemble estimator),组成集成评估器的每个模型称为基评估器(base estimator)


1、集成算法主要类型包括:随机森林,梯度提升树(GBDT),Xgboost等


2、集成算法包括:装袋法Bagging,提升法Boosting和堆叠法Stacking


【1】装袋法的核心思想是构建多个相互独立的评估器,然后对其预测进行平均或多数表决原则来决定集成评估器的结果。


【2】提升法中,基评估器是相关的,是按顺序一一构建的。其核心思想是结合弱评估器的力量一次次对难以评估的样本进行预测,从而构成一个强评估器 。


【3】堆叠法。整合多个分类器,比如随机森林,线性回归,支持向量机等,每个分类器(弱分类器)通过K折交叉验证学习得到一个结果,第二个阶段拿另一个分类器对第一个阶段的进行再学习,训练和测试。


装袋法与提升法的区别?


通俗理解:有一道判断题,一群学习不好的人怎么去做能让题目的成功率比较高呢。


在这里就有两种方法:


第一种是序列集成方法 (提升法Boosting):


先让学渣A做一遍,然后再让学渣B做,且让B重点关注A做错的那些题,再让C做,同样重点关注B做错的,依次循环,直到所有的学渣都把题目做了一遍为止


第二种就是并行集成方法 (装袋法Bagging):


多个学渣一起做, 每个人随机挑选一部分题目来做,最后将所有人的结果进行汇总,然后根据将票多者作为最后的结果

aa6f5a58935a4e3f80f7e12451e2a193.png


装袋法的一个必要条件:

基分类器要尽量独立,所以,基评估器的判断准确率至少要超过随机分类器。因此基分类器的准确率要超过50%

e0e28c14cc1a4fd5b1daa5b2234cf0cb.png

# 假设有25颗树,i是判断错误的次数,也是判断错误的树的数量。Ω是判断错误的树的概率,1-Ω是正确的概率。共判断对25-i。采用comb是因为25颗树种,有任意i颗都可能判断错误。0.2是假设一棵树判断错误的可能性是0.2。
import numpy as np 
from scipy.special import comb
np.array([comb(25,i)*(0.2**i)*((1-0.2)**(25-i)) for i in range(13,26)]).sum()

c7f63bd86f3f462c90f55c7491a8f159.png

import numpy as np 
x=np.linspace(0,1,20)
y=[]
for epsilon in np.linspace(0,1,20):
    E=np.array([comb(25,i)*(epsilon**i)*((1-epsilon)**(25-i))
                for i in range(13,26)]).sum()
    y.append(E)
plt.plot(x,y,"o-",label="when estimators are different")
plt.plot(x,x,"--",color="red",label="if all estimators are same")
plt.xlabel("individual estimator's error")
plt.ylabel("RandomForest's error" )
plt.legend()
plt.show()

下图表明

当当单个分类器的错误小于50%的情况下,随机森林分类器的准确性会大于单个的分类器。

反之,当单个分类器的错误大于50%的情况下,随机森林的错误率就会高于单个分类器。

984c1e4e66ff40f5b15de49ee5db04b1.png


1、随机森林的分类

使用的参数是基尼系数:

sklearn.ensemble.RandomForestClassifier (n_estimators='10', criterion='gini', max_depth=None,
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto',
max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, bootstrap=True, oob_score=False,
n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None)

(1)导入我们需要的包,这里使用sklearn自带的红酒数据集

%matplotlib inline
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine

(2)导入需要的数据集

import pandas as pd
import numpy as np
wine = load_wine()
wine.data
wine.target

总共有三类红酒:

9d47d39af46d419dbe261e9b01e7b49a.png

红酒特征:

8e734f2c4a1c44cf9a4f30bdb6f09113.png


(3)对数据进行分割 :

train_test_split函数划分出训练集和测试集,测试集占比0.3

from sklearn.model_selection import train_test_split 
Xtrain,Xtest,Ytrain,Ytest=train_test_split(wine.data,wine.target,test_size=0.3)

关于train_test_split的用法如下:

import numpy as np
from sklearn.model_selection import train_test_split
#创建一个数据集X和相应的标签y,X中样本数目为100
X, y = np.arange(200).reshape((100, 2)), range(100)
#用train_test_split函数划分出训练集和测试集,测试集占比0.33
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42)
#打印出原始样本集、训练集和测试集的数目
print("The length of original data X is:", X.shape[0])
print("The length of train Data is:", X_train.shape[0])
print("The length of test Data is:", X_test.shape[0])
da56800afe964f4b93471a106748b826.png


(4)绘制决策树与随机森林交叉验证后的效果对比

from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
rfc = RandomForestClassifier(n_estimators=25) # 随机森林
rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10)
clf = DecisionTreeClassifier() # 决策树
clf_s = cross_val_score(clf,wine.data,wine.target,cv=10)
plt.plot(range(1,11),rfc_s,label = "RandomForest")
plt.plot(range(1,11),clf_s,label = "Decision Tree")
plt.legend()
plt.show()

从图上看出决策树总体的正确率在随机森林下面。随机森林效果更好。

5cff93280aa248008cf5401d53d3d97c.png

rfc_l = []
clf_l = []
for i in range(10):
    rfc = RandomForestClassifier(n_estimators=25)
    rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
    rfc_l.append(rfc_s)
    clf = DecisionTreeClassifier()
    clf_s = cross_val_score(clf,wine.data,wine.target,cv=10).mean()
    clf_l.append(clf_s)
plt.plot(range(1,11),rfc_l,label = "Random Forest")
plt.plot(range(1,11),clf_l,label = "Decision Tree")
plt.legend()
plt.show()

9778a15e3cfe47bda335129be3e4c715.pngccb7f268aa324431963672eaece36afd.png

通过修改随机森林当中n_estimators的个数来绘制学习曲线:

superpa = []
for i in range(200):
    rfc = RandomForestClassifier(n_estimators=i+1,n_jobs=-1)
    rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean()
    superpa.append(rfc_s)
print(max(superpa),superpa.index(max(superpa)))
plt.figure(figsize=[20,5])
plt.plot(range(1,201),superpa)
plt.show()

8fbcd9db2ea745ee883b5b7d9b50a19e.png


2、重要参数


【1】n_estimators

  • n_estimators:森林中树的数量,即基评估器的数量。越大则模型往往越好;但是也是有边界的。如果n_estimators=100,需要10次交叉验证,则需要1000颗树。 默认为10(低版本),新版本默认为100。

【2】random_state


random_state:随机森林每次的基评估器的结果是可能不同的。主要原因在于决策树自带的随机性参数。与决策树不同的是,随机森林生成的不是一棵树,而是一片树。如果random_state是固定的,则随机森林会生成一组固定的树,但是每棵树的细节部分还是不一致的。原因在于挑选的随机性。并且随机性越大,则装袋法的效果越好。如果总体样本特征不够,实际上就限制了随机森林的创建。因此需要其他的随机性参数。

查看第1次的random_state结果:

rfc =RandomForestClassifier(n_estimators=20,random_state=2)
rfc = rfc.fit(Xtrain, Ytrain)  #训练
rfc.estimators_[0] 

59bed01a25c74c949ae7ee5419cf21ef.png

for循环查看每一次random_state的结果:

for i in range(len(rfc.estimators_)):
    print(rfc.estimators_[i].random_state)


【3】bootstrap


bootstrap:用来控制有放回的抽样技术参数。放回抽样有可能会导致一些样本多次出现,而另外一些则几乎被忽略。 放回数据集的敛财概率一般是:1-(1/e) 0.63,剩下37%的数据可能会被忽略而称为out of bag data,obb 可以被当做测试集数据。所以在随机森林中,有时不进行训练集和测试集的划分,而直接使用oob作为测试集。如果样本数和estimator本身不够大的情况,就不会oob。

在使用随机森林时,我们可以不划分测试集和训练集,只需要用袋外数据来测试我们的模型即可。 oob_score_来查看我们的在袋外数据上测试的结果:

#无需划分训练集和测试集
rfc = RandomForestClassifier(n_estimators=25,oob_score=True)
rfc = rfc.fit(wine.data,wine.target)
#重要属性oob_score_
rfc.oob_score_


不划分测试集和训练集,则需要使用参数oob_score=True

准确率如下:

5ca4d831eaca498c825f06755c4b4921.png


3、重要的属性和接口


rfc=RandomForestClassifier(n_estimators=25) 
rfc=rfc.fit(Xtrain,Ytrain)
rfc.score(Xtest,Ytest)
rfc.feature_importances_
rfc.apply(Xtest)
rfc.predict(Xtest)
rfc.predict_proba(Xtest) 

predict_proba

predict_proba返回每个测试样本对应的被分到每一类标签的概率。标签有几个分类就返回几个概率。如果是二分类,则该值大于0.5,则被分为1,否则为0。在sklearn下随机森林是平均每个样本对应的predict_proba返回的概率,得到一个平均概率,从而决定测试样本的分类。


8ebf9031866e44e8989af7cf45155080.png


相关文章
|
2月前
|
机器学习/深度学习 存储 算法
决策树和随机森林在机器学习中的应用
在机器学习领域,决策树(Decision Tree)和随机森林(Random Forest)是两种非常流行且强大的分类和回归算法。它们通过模拟人类决策过程,将复杂的数据集分割成易于理解和处理的子集,从而实现对新数据的准确预测。
95 10
|
2月前
|
机器学习/深度学习 数据采集 监控
探索机器学习:从数据到决策
【9月更文挑战第18天】在这篇文章中,我们将一起踏上一段激动人心的旅程,穿越机器学习的世界。我们将探讨如何通过收集和处理数据,利用算法的力量来预测未来的趋势,并做出更加明智的决策。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和思考方式。
|
1月前
|
机器学习/深度学习 算法 数据可视化
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
|
2月前
|
机器学习/深度学习 算法 Python
从菜鸟到大师:一棵决策树如何引领你的Python机器学习之旅
【9月更文挑战第9天】在数据科学领域,机器学习如同璀璨明珠,吸引无数探索者。尤其对于新手而言,纷繁复杂的算法常让人感到迷茫。本文将以决策树为切入点,带您从Python机器学习的新手逐步成长为高手。决策树以其直观易懂的特点成为入门利器。通过构建决策树分类器并应用到鸢尾花数据集上,我们展示了其基本用法及效果。掌握决策树后,还需深入理解其工作原理,调整参数,并探索集成学习方法,最终将所学应用于实际问题解决中,不断提升技能。愿这棵智慧之树助您成为独当一面的大师。
44 3
|
2月前
|
机器学习/深度学习 算法 Python
决策树下的智慧果实:Python机器学习实战,轻松摘取数据洞察的果实
【9月更文挑战第7天】当我们身处数据海洋,如何提炼出有价值的洞察?决策树作为一种直观且强大的机器学习算法,宛如智慧之树,引领我们在繁复的数据中找到答案。通过Python的scikit-learn库,我们可以轻松实现决策树模型,对数据进行分类或回归分析。本教程将带领大家从零开始,通过实际案例掌握决策树的原理与应用,探索数据中的秘密。
47 1
|
2月前
|
机器学习/深度学习 算法 前端开发
R语言基础机器学习模型:深入探索决策树与随机森林
【9月更文挑战第2天】决策树和随机森林作为R语言中基础且强大的机器学习模型,各有其独特的优势和适用范围。了解并熟练掌握这两种模型,对于数据科学家和机器学习爱好者来说,无疑是一个重要的里程碑。希望本文能够帮助您更好地理解这两种模型,并在实际项目中灵活应用。
|
3月前
|
机器学习/深度学习 算法 数据挖掘
【白话机器学习】算法理论+实战之决策树
【白话机器学习】算法理论+实战之决策树
|
3月前
|
机器学习/深度学习 算法 自动驾驶
揭秘机器学习模型的决策之道
【8月更文挑战第22天】本文将深入浅出地探讨机器学习模型如何从数据中学习并做出预测。我们将一起探索模型背后的数学原理,了解它们是如何被训练以及如何对新数据进行预测的。文章旨在为初学者提供一个清晰的机器学习过程概述,并启发读者思考如何在自己的项目中应用这些技术。
|
6月前
|
机器学习/深度学习 存储 搜索推荐
利用机器学习算法改善电商推荐系统的效率
电商行业日益竞争激烈,提升用户体验成为关键。本文将探讨如何利用机器学习算法优化电商推荐系统,通过分析用户行为数据和商品信息,实现个性化推荐,从而提高推荐效率和准确性。
239 14
|
6月前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)