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

注:本篇文章接上一篇文章》》机器学习系列(9)_决策树详解01

一、决策树优缺点

(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()

在这里插入图片描述
【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()

在这里插入图片描述
【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()

在这里插入图片描述
【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()

在这里插入图片描述
【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_

通过网格搜索得到的最佳参数:
在这里插入图片描述


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

以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])

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

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

为数据添加噪声,提升机器学习的难度。
在这里插入图片描述
构建不同的数据类型:

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

在这里插入图片描述

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()

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

三、随机森林介绍

集成学习: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)

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

在这里插入图片描述
装袋法的一个必要条件:

基分类器要尽量独立,所以,基评估器的判断准确率至少要超过随机分类器。因此基分类器的准确率要超过50%
在这里插入图片描述

# 假设有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()

在这里插入图片描述

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%的情况下,随机森林的错误率就会高于单个分类器。在这里插入图片描述

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

总共有三类红酒:
在这里插入图片描述
红酒特征:
在这里插入图片描述
(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])

在这里插入图片描述


(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()

从图上看出决策树总体的正确率在随机森林下面。随机森林效果更好。
在这里插入图片描述

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()

在这里插入图片描述
在这里插入图片描述
通过修改随机森林当中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()

在这里插入图片描述

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] 

在这里插入图片描述
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

准确率如下:
在这里插入图片描述

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返回的概率,得到一个平均概率,从而决定测试样本的分类。

在这里插入图片描述

四、随机森林回归

1、参数介绍

下面使用的参数是MSE:

sklearn.ensemble.RandomForestClassifier (n_estimators='warn', criterion='mse', 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)

回归树衡量分枝质量的指标:

  • MSE mean squard error 均方误差
  • friedman_mse 费里德曼均方误差
  • MAE 绝对平均误差 mean absolute error 使用叶子节点中的中值来最小化L1损失

在这里插入图片描述
【1】N:样本量。
【2】i:是每个样本。
【3】fi:是模型回归得到的数值。
【4】yi:是样本点i实际的数值标签。
【5】MSE是样本真实数据与回归结果的差异。不只是分枝质量衡量的指标,也是用来衡量回归树回归质量的指标。在使用交叉验证,或者其他方式获取回归树的时候,往往选择均方误差作为评估的标准,MSE追求越小越好。

分类树中用score代表准确率,但在回归树中score返回的是R平方:
在这里插入图片描述
【1】u:残差平方和
【2】v:总平方和
【3】残差平方和远远大于总平方和,则模型非常差,R平方就会为负数。取值范围是1到负无穷,越接近1越好。
【4】neg_mean_squared_error:sklearn在进行模型评估指标的时候,会考虑指标本身的性质,由于均方误差本身是一种误差,会被sklearn划定为是某一种损失,而在sklearn当中是以负数表示损失。

(1)随机森林回归用法

这里使用sklearn自带的数据集——波士顿房价

# 和决策树完全一致,除了多了参数n_estimators
# 这里使用sklearn自带的数据集——波士顿房价 
from sklearn.datasets import load_boston 
from sklearn.model_selection import cross_val_score 
from sklearn.ensemble import RandomForestRegressor 
import sklearn 
boston=load_boston()
regressor=RandomForestRegressor(n_estimators=100,random_state=0)
cross_val_score(regressor,boston.data,boston.target,cv=10,scoring="neg_mean_squared_error")

sorted(sklearn.metrics.SCORERS.keys()) 
# SCORERS.keys是整个随机森林里面使用的标签

上面的代码中如果参数scoring不写成scoring="neg_mean_squared_error",那么交叉验证模型的衡量指标默认就是R平方,因此交叉验证的结果可能为正也可能为负数。如果写上了scoring="neg_mean_squared_error",则衡量的标准是负的均方误差,那么交叉验证的结果只能是为负数。

在这里插入图片描述
如下所示:

cross_val_score(regressor,boston.data,boston.target,cv=10,scoring="neg_mean_squared_error")
cross_val_score(regressor,boston.data,boston.target,cv=10)

在这里插入图片描述

2、利用随机森林回归算法进行缺失值填充

(1)导入库

#(1)导入库
import sklearn 
import matplotlib.pyplot as plt
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
from sklearn.datasets import load_boston 
from sklearn.model_selection import cross_val_score 
from sklearn.ensemble import RandomForestRegressor 

在这里插入图片描述
(2)以波士顿数据集为例,导入完整的数据集并探索

# (2)以波士顿数据集为例,导入完整的数据集并探索 
dataset=load_boston()
dataset.data.shape 
X_full,y_full=dataset.data,dataset.target
n_samples=X_full.shape[0]
n_features=X_full.shape[1]

在这里插入图片描述
在这里插入图片描述
通过使用shape观察数据是否存在缺失值:
在这里插入图片描述
(3)人为设置缺失值

# (3)人为设置缺失值
rng=np.random.RandomState(0)
missing_rate=0.5 # 将数据的50%弄成缺失值
n_missing_samples=int(np.floor(n_samples * n_features * missing_rate))

由上面得知共有6578个数据,我们选取其中的3289个数据做缺失值
在这里插入图片描述

# 构建缺失值的行列坐标
missing_features=rng.randint(0,n_features,n_missing_samples)
missing_samples=rng.randint(0,n_samples,n_missing_samples)

在这里插入图片描述
当设置缺失值的样本分量小于样本量时可考虑choice方法:

missing_samples=rng.choice(dataset.data.shape[0],n_missing_samples,replace=False)
X_missing=X_full.copy()
y_missing=y_full.copy()
X_missing[missing_samples,missing_features]=np.nan #利用我们设置的行列位置将值设置为NAN
X_missing=pd.DataFrame(X_missing)

在这里插入图片描述

(4)使用0和均值填补缺失值

# (4)使用0和均值填补缺失值 
# 使用均值进行填补
from sklearn.impute import SimpleImputer
imp_mean=SimpleImputer(missing_values=np.nan,strategy='mean')
X_missing_mean=imp_mean.fit_transform(X_missing)

# 使用01进行填补 
imp_0=SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0)
X_missing_0=imp_0.fit_transform(X_missing)
sortindex=np.argsort(X_missing_reg.isnull().sum(axis=0)).values
# 对缺失值的数据进行排序
sortindex
# 得到缺失值排序之后的索引

在这里插入图片描述

在这里插入图片描述
(5)使用随机森林填补缺失值

# (5)使用随机森林填补缺失值 
from sklearn.impute import SimpleImputer
X_missing_reg=X_missing.copy() 
for i in sortindex:
    #构建我们的新特征矩阵和新标签 
    df=X_missing_reg 
    fillc=df.iloc[:,i]
    df=pd.concat([df.iloc[:,df.columns!=i],pd.DataFrame(y_full)],axis=1)
    # 将y_full)变成特征值而非标签值,并进行合并
    # 在新特征矩阵中,对含有缺失值的列,进行0的填补 
    df_0=SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df) 
    # 找出我们的训练集和测试集 
    Ytrain=fillc[fillc.notnull()]
    Ytest=fillc[fillc.isnull()]
    Xtrain=df_0[Ytrain.index,:]
    Xtest=df_0[Ytest.index,:]
    # 用随机森林回归来填补缺失值 
    rfc=RandomForestRegressor(n_estimators=100)
    rfc=rfc.fit(Xtrain,Ytrain)
    Ypredict=rfc.predict(Xtest)
    # 将填补好的特征返回我们的原始特征矩阵中 
    X_missing_reg.loc[X_missing_reg.iloc[:,i].isnull(),i]=Ypredict
X_missing_reg.isnull().sum()

在这里插入图片描述

(6)对于填充后的数据进行建模

# (6)对于填充后的数据进行建模 
X=[X_full,X_missing_mean,X_missing_0,X_missing_reg]
# 四种填充,分别是原始数据填充,均值填充缺失值,0填充缺失值,随机森林回归填充缺失值
mse=[]
std=[]
for x in X: 
    estimator=RandomForestRegressor(random_state=0,n_estimators=100)
    scores=cross_val_score(estimator,x,y_full,scoring='neg_mean_squared_error',cv=5).mean()
    mse.append(scores*-1)

在这里插入图片描述

# 对四种填充进行MSE值的比较:
# 对于MSE来说,值越小越好
[*zip(['X_full','X_missing_mean','X_missing_0','X_missing_reg'],mse)]

在这里插入图片描述
(7)用所得结果画出条形图

# (7)用所得结果画出条形图 
x_labels=['Full data',
'Zero Imputation',
'Mean Imputation',
'Regressor Imputation']
colors=['r','g','b','orange']
plt.figure(figsize=(12,6))
ax=plt.subplot(111)
for i in np.arange(len(mse)):
    ax.barh(i,mse[i],color=colors[i],alpha=0.6,align='center')
ax.set_title('Imputation Techniques with Boston Data')
ax.set_xlim(left=np.min(mse)*0.9,right=np.max(mse)*1.1)
ax.set_yticks(np.arange(len(mse)))
ax.set_xlabel('MSE')
ax.set_yticklabels(x_labels)
plt.show() 

由下图知,使用均值填充的效果最差,因为其MSE最大,而回归填充的效果是最好的。
在这里插入图片描述

五、利用随机森林与乳腺癌数据分析

(1)导入库

#(1)导入库
from sklearn.datasets import load_breast_cancer # 乳腺癌数据
from sklearn.model_selection import GridSearchCV # 网格搜索
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.ensemble import RandomForestClassifier # 随机森林分类器

(2)导入数据,探索数据

# (2)导入数据,探索数据 
data=load_breast_cancer() 
data 

在这里插入图片描述
(3)进行一次简单的建模,看看模型本身在数据集上面的效果

# (3)进行一次简单的建模,看看模型本身在数据集上面的效果 
rfc=RandomForestClassifier(n_estimators=100,random_state=90)
score_pre=cross_val_score(rfc,data.data,data.target,cv=10).mean()
# 模型,完整特殊矩阵,完整的标签,校验验证 
score_pre 

在这里插入图片描述
(4)随机森林调整的第一步:无论如何先来调整n_estimators

# (4)随机森林调整的第一步:无论如何先来调整n_estimators 
scorel=[]
for i in range(0,200,10):# 每一次取10个
    rfc=RandomForestClassifier(n_estimators=i+1,
                              n_jobs=-1,
                              random_state=90)
    score=cross_val_score(rfc,data.data,data.target,cv=10).mean()
    scorel.append(score)
print(max(scorel),(scorel.index(max(scorel))*10)+1)
plt.figure(figsize=[20,5])
plt.plot(range(1,201,10),scorel)
plt.show() 

由下图可以看出,大概在75附近的效果最好

在这里插入图片描述
(5)在确定好的范围内,进一步细化学习曲线

# (5)在确定好的范围内,进一步细化学习曲线 
scorel=[]
for i in range(65,75):# 上分的峰值出现在哪里,比如71,则range的设置就在这个前后
    rfc=RandomForestClassifier(n_estimators=i+1,
                              n_jobs=-1,
                              random_state=90)
    score=cross_val_score(rfc,data.data,data.target,cv=10).mean()
    scorel.append(score)
print(max(scorel),([*range(65,75)][scorel.index(max(scorel))]))
plt.figure(figsize=[20,5])
plt.plot(range(65,75),scorel)
plt.show() 

在这里插入图片描述
(6)利用网格搜索做准备,网格搜索的参数

【1】调整参数max_depth

# (6)利用网格搜索做准备,网格搜索的参数 
# 调整max_depth 
param_grid={'max_depth':np.arange(1,20,1)}
rfc=RandomForestClassifier(n_estimators=72
                          ,random_state=90
                          )
GS=GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 
GS.best_score_ # 返回调整好的最佳参数对应的准确率

在这里插入图片描述
【2】调整参数max_features

# (6)利用网格搜索做准备,网格搜索的参数 
# 调整max_depth 
# param_grid={'max_depth':np.arange(1,20,1)}
# 调整max_features
param_grid={'max_features':np.arange(5,30,1)}
rfc=RandomForestClassifier(n_estimators=72
                          ,random_state=90
                          )
GS=GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 
GS.best_score_ # 返回调整好的最佳参数对应的准确率

在这里插入图片描述
【3】调整参数:min_samples_leaf

# (6)利用网格搜索做准备,网格搜索的参数 
# 调整max_depth 
# param_grid={'max_depth':np.arange(1,20,1)}
# 调整max_features
# param_grid={'max_features':np.arange(5,30,1)}
# 调整min_samples_leaf
param_grid={'min_samples_leaf':np.arange(1,1+10,1)}
rfc=RandomForestClassifier(n_estimators=72
                          ,random_state=90
                          )
GS=GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 
GS.best_score_ # 返回调整好的最佳参数对应的准确率

在这里插入图片描述
【4】调整criterion

# (6)利用网格搜索做准备,网格搜索的参数 
# 调整max_depth 
# param_grid={'max_depth':np.arange(1,20,1)}
# 调整max_features
# param_grid={'max_features':np.arange(5,30,1)}
# 调整min_samples_leaf
# 调整Criterion
param_grid={'criterion':['gini','entropy']}
rfc=RandomForestClassifier(n_estimators=72
                          ,random_state=90
                          )
GS=GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
GS.best_params_ # 显示调整出来的最佳参数,比如在此显示的是深度 
GS.best_score_ # 返回调整好的最佳参数对应的准确率

在这里插入图片描述
调整完毕,总结出模型最佳的参数

# 调整完毕,总结出模型最佳的参数 
rfc=RandomForestClassifier(n_estimators=72,random_state=90)
score=cross_val_score(rfc,data.data,data.target,cv=10).mean()
score

在这里插入图片描述

# 最后,对所有参数进行总结和梳理 
rfc=RandomForestClassifier(
                          n_estimators=73
                          ,random_state=90
                          ,criterion="gini"
                          ,min_samples_split=8
                          ,min_samples_leaf=1
                          ,max_depth=12
                          ,max_features=2 
                          ,max_leaf_nodes=36
)
score_pre=cross_val_score(rfc,data.data,data.target,cv=10).mean()
# 模型,完整特殊矩阵,完整的标签,校验验证 
score_pre

在这里插入图片描述

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温欣2030

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值