sklearn机器学习库(二)sklearn中的随机森林

sklearn机器学习库(二)sklearn中的随机森林

集成算法会考虑多个评估器的建模结果,汇总之后得到一个综合的结果,以此来获取比单个模型更好的回归或分类表现

多个模型集成成为的模型叫做集成评估器(ensemble estimator),组成集成评估器的每个模型都叫做基评估器(base estimator)。通常来说,有三类集成算法:装袋法(Bagging),提升法(Boosting)和stacking。

  • 装袋法(Bagging)的核心思想是构建多个相互独立的评估器,然后对其预测进行平均或多数表决原则来决定集成评估器的结果。装袋法的代表模型就是随机森林

  • 提升法(Boosting)中,基评估器是相关的,是按顺序一一构建的。其核心思想是结合弱评估器的力量一次次对难以评估的样本
    进行预测,从而构成一个强评估器。提升法的代表模型有Adaboost和梯度提升树(GBDT)

sklearn中的集成算法模块ensemble

类的功能
ensemble.AdaBoostClassifierAdaBoost分类
ensemble.AdaBoostRegressorAdaboost回归
ensemble.BaggingClassifier装袋分类器
ensemble.BaggingRegressor装袋回归器
ensemble.ExtraTreesClassifierExtra-trees分类(超树,极端随机树)
ensemble.ExtraTreesRegressorExtra-trees回归
ensemble.GradientBoostingClassifier梯度提升分类
ensemble.GradientBoostingRegressor梯度提升回归
ensemble.IsolationForest隔离森林
ensemble.RandomForestClassifier随机森林分类
ensemble.RandomForestRegressor随机森林回归
ensemble.RandomTreesEmbedding完全随机树的集成
ensemble.VotingClassifier用于不合适估算器的软投票/多数规则分类器

集成算法中,有一半以上都是树的集成模型。

决策树的核心问题有两个,一个是如何找出正确的特征来进行分枝,二是树生长到什么时候应该停下。

  • 对于第一个问题,我们定义了用来衡量分枝质量的指标不纯度,分类树的不纯度用基尼系数或信息熵来衡量,回归
    树的不纯度用MSE均方误差来衡量。每次分枝时,决策树对所有的特征进行不纯度计算,选取不纯度最低的特征进
    行分枝,分枝后,又再对被分枝的不同取值下,计算每个特征的不纯度,继续选取不纯度最低的特征进行分枝。
  • 决策树非常容易过拟合,为了防止决策树的过拟合,我们要对决策树进行剪枝,sklearn中提供了大量的剪枝参数 。

1 RandomForestClassifier

随机森林是非常具有代表性的Bagging集成算法,它的所有基评估器都是决策树,分类树组成的森林就叫做随机森林分类器,回归树所集成的森林就叫做随机森林回归器。

sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='sqrt', max_leaf_nodes=None, min_impurity_decrease=0.0, 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
)

1.1 重要参数

1.1.1 基评估器的控制参数

参数含义
criterion不纯度的衡量指标,{“gini”, “entropy”, “log_loss”},默认是”gini”
max_depth树的最大深度,超过最大深度的树枝都会被剪掉
min_samples_leaf一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,
min_samples_split一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生
max_featuresmax_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃, 默认值为总特征个数开平方取整(sqrt),可选值有**{“sqrt”, “log2”, None}**
min_impurity_decrease信息增益小于设定数值的分枝不会发生

详细解释可参考官网。https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html#sklearn.ensemble.RandomForestClassifier

1.1.2 n_estimators

  • 这是森林中树木的数量,即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越大,模型的效果往往越好

  • 但是相应的,任何模型都有决策边界,n_estimators达到一定的程度之后,随机森林的精确性往往不在上升或开始波动,并且,n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越长。对于这个参数,我们是渴望在训练难度和模型效果之间取得平衡。

  • n_estimators的默认值在0.22版本中,默认值从10改为100,这个修正显示出了使用者的调参倾向:要更大的n_estimators。

from matplotlib import pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split,cross_val_score
%matplotlib inline# 导入红酒数据集
wine = load_wine()Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)# 训练模型
clf = DecisionTreeClassifier(random_state=0)
rfc = RandomForestClassifier(random_state=0)clf = clf.fit(Xtrain, Ytrain)
rfc = rfc.fit(Xtrain, Ytrain)tree_score = clf.score(Xtest,Ytest)
forest_score = rfc.score(Xtest,Ytest)print('单棵树:{}'.format(tree_score),'随机森林:{}'.format(forest_score))
单棵树:0.9444444444444444 随机森林:1.0
# 交叉验证
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()

在这里插入图片描述

# n_estimators的学习曲线
forest_scores = []for i in range(100):rfc = RandomForestClassifier(n_estimators=i+1)s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean()forest_scores.append(s)# 打印最大值及最大值的索引
print(max(forest_scores),forest_scores.index(max(forest_scores)))
plt.figure(figsize=(10,8))
plt.plot(range(1,101),forest_scores)
plt.legend()
plt.show()

在这里插入图片描述

1.1.3 random_state

  • 随机森林的本质是一种装袋集成算法(bagging),装袋集成算法是对基评估器的预测结果进行平均或用多数表决原则来决定集成评估器的结果。

  • 在刚才的红酒例子中,我们建立了25棵树,对任何一个样本而言,平均或多数表决原则下,当且仅当有13棵以上的树判断错误的时候,随机森林才会判断错误。单独一棵决策树对红酒数据集的分类准确率在0.85上下浮动,假设一棵树判断错误的可能性为0.2(ε),那20棵树以上都判断错误的可能性是0.000369。判断错误的几率非常小,这让随机森林在红酒数据集上的表现远远好于单棵决策树

在这里插入图片描述

  • 随机森林中其实也有random_state,用法和分类树中相似。
    • 只不过在分类树中,一个random_state只控制生成一棵树
    • 而随机森林中的random_state控制的是生成森林的模式,而非让一个森林中只有一棵树
rfc = RandomForestClassifier(n_estimators=20,random_state=2)
rfc = rfc.fit(Xtrain, Ytrain)#随机森林的重要属性之一:estimators,查看森林中树的状况
for i in range(len(rfc.estimators_)):print(rfc.estimators_[i].random_state)
1872583848
794921487
111352301
1853453896
213298710
1922988331
......
  • 当random_state固定时,随机森林中生成是一组固定的树,但每棵树依然是不一致的,这是用随机挑选特征进行分枝的方法得到的随机性。并且我们可以证明,当这种随机性越大的时候,袋装法的效果一般会越来越好。用袋装法集成时,基分类器应当是相互独立的,是不相同的

  • 但这种做法的局限性是很强的,当我们需要成千上万棵树的时候,数据不一定能够提供成千上万的特征来让我们构筑尽量多尽量不同的树。因此,除了random_state。我们还需要其他的随机性

1.1.4 bootstrap & oob_score

  • 要让基分类器尽量都不一样,另一种很容易理解的方法是使用不同的训练集来进行训练,而袋装法正是通过有放回的随机抽样技术来形成不同的训练数据,bootstrap就是用来控制抽样技术的参数。

  • 在一个含有n个样本的原始训练集中,我们进行随机采样,每次采样一个样本,并在抽取下一个样本之前将该样本放回原始训练集,也就是说下次采样时这个样本依然可能被采集到,由于是随机采样,这样每次的自助集和原始数据集不同,和其他的采样集也是不同的。用这些自助集来训练我们的基分类器,我们的基分类器自然也就各不相同了。

  • bootstrap参数默认True,代表采用这种有放回的随机抽样技术。

  • 一般来说,自助集大约平均会包含63%的原始数据 。因此,会有约37%的训练数据被浪费掉,没有参与建模,这些数据被称为袋外数据(out of bag data,简写为oob)

1 − ( 1 − 1 / n ) n 当 n 足够大时,这个概率收敛于 1 − ( 1 / e ) ,约等于 0.632 。 1-(1-1/n)^n \\ 当n足够大时,这个概率收敛于1-(1/e),约等于0.632。 1(11/n)nn足够大时,这个概率收敛于1(1/e),约等于0.632

  • 在使用随机森林时,我们可以不划分测试集和训练集,只需要用袋外数据来测试我们的模型即可。
    • 当然,这也不是绝对的,当n和n_estimators都不够大的时候,很可能就没有数据掉落在袋外,自然也就无法使用oob数据来测试模型了。
    • 如果希望用袋外数据来测试,则需要在实例化时就将oob_score这个参数调整为True
    • 训练完毕之后,可以用oob_score_来查看在袋外数据上测试的结果
# 无需划分训练集和测试集
rfc = RandomForestClassifier(n_estimators=25,oob_score=True)
rfc = rfc.fit(wine.data, wine.target)# 重要属性oob_score_
print(rfc.oob_score_) 

1.2 重要接口

  • 随机森林的接口与决策树完全一致,因此依然有四个常用接口:apply, fit, predict和score

  • 除此之外,还需要注意随机森林的predict_proba接口,这个接口返回每个测试样本对应的被分到每一类标签的概率,标签有几个分类就返回几个概率。如果是二分类问题,则predict_proba返回的数值大于0.5的,被分为1,小于0.5的,被分为0。

  • 传统的随机森林是利用袋装法中的规则,平均或少数服从多数来决定集成的结果,而sklearn中的随机森林是平均每个样本对应的predict_proba返回的概率,得到一个平均概率,从而决定测试样本的分类

在这里插入图片描述

在这里插入图片描述

注意:

当基分类器的误差率小于0.5,即准确率大于0.5时,集成的效果是比基分类器要好的。

相反,当基分类器的误差率大于0.5,袋装的集成算法就失效了。

所以在使用随机森林之前,一定要检查,用来组成随机森林的分类树们是否都有至少50%的预测正确率。

2 RandomForestRegressor

DecisionTreeRegressor(*,criterion='squared_error', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, ccp_alpha=0.0
)

所有的参数,属性与接口,全部和随机森林分类器一致。仅有的不同就是回归树与分类树的不同,不纯度的指标,
参数Criterion不一致。

2.1 Criterion

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

  • 均方误差的squared_error,父节点和叶子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子节点的均值来最小化L2损失

  • friedman_mse,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差

  • 平均绝对误差absolute_error,这种指标使用叶节点的中值来最小化L1损失

  • 以及poisson,它使用泊松偏差的减少来寻找分裂

虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算负均方误差

这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss),因此在sklearn当中,都以负数表示。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字 。

# 读取波士顿数据集,注意:新版本的sklearn中自带的已经删除
data = pd.read_csv("boston_housing.data", sep='\s+', header=None)x = data.iloc[:, :-1]
y = data.iloc[:, -1]regressor = RandomForestRegressor(n_estimators=100,random_state=0)
cross_val_score(regressor, x, y, cv=10,scoring = "neg_mean_squared_error")

在这里插入图片描述

返回十次交叉验证的结果,注意在这里,如果不填写scoring = “neg_mean_squared_error”,交叉验证默认的模型衡量指标是R平方,因此交叉验证的结果可能有正也可能有负。

而如果写上scoring,则衡量标准是负MSE,交叉验证的结果只可能为负。

2.2 使用随机森林填补缺失值

我们从现实中收集的数据,往往都会有一些缺失值。面对缺失值,很多人选择的方式是直接将含有缺失值的样本删除,这是一种有效的方法。

有时候填补缺失值会比直接丢弃样本效果更好。在sklearn中,我们用sklearn.impute.SimpleImputer来轻松地将均值,中值,或者其他最常用的数值填补到数据中。

在这个案例中,我们将使用均值,0,和随机森林回归来填补缺失值,并验证四种状况下的拟合状况,找出对使用的数据集来说最佳的缺失值填补方法。

import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
import matplotlib.pyplot as plt
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score# 读取波士顿数据集,注意:新版本的sklearn中自带的已经删除
data = pd.read_csv("boston_housing.data", sep='\s+', header=None)x = data.iloc[:, :-1]
y = data.iloc[:, -1]print(x.shape)
x.info()  # 均非空

在这里插入图片描述

# 人为填充缺失值
#所有数据要随机遍布在数据集的各行各列当中,而一个缺失的数据会需要一个行索引和一个列索引
#如果能够创造一个数组,包含3289个分布在0~506中间的行索引,和3289个分布在0~13之间的列索引,那我们就可以利用索引来为数据中的任意3289个位置赋空值n_samples = x.shape[0]
n_features = x.shape[1]rng = np.random.RandomState(0)
miss_rate = 0.5 # 缺失50%,即3289数据n_missing_samples = int(np.floor(n_samples * n_features * miss_rate))missing_features = rng.randint(0,n_features,n_missing_samples)
missing_samples = rng.randint(0,n_samples,n_missing_samples)
X_missing = x.copy().to_numpy()
y_missing = y.copy()
X_missing[missing_samples,missing_features] = np.nan
X_missing = pd.DataFrame(X_missing)X_missing.head(10)

在这里插入图片描述

# 使用0和均值填补缺失值# 1、使用均值进行填充
s_mean = SimpleImputer(missing_values=np.nan, strategy='mean')x_miss_mean = s_mean.fit_transform(X_missing)# 2、使用常数0进行填充
zero_mean = SimpleImputer(missing_values=np.nan, strategy='constant',fill_value=0)x_miss_zero = zero_mean.fit_transform(X_missing)# 3、使用随机森林填充缺失值
'''
特征T不缺失的值对应的其他n-1个特征 + 本来的标签:X_train
特征T不缺失的值:Y_train特征T缺失的值对应的其他n-1个特征 + 本来的标签:X_test
特征T缺失的值:未知,我们需要预测的Y_test这种做法,对于某一个特征大量缺失,其他特征却很完整的情况,非常适用那如果数据中除了特征T之外,其他特征也有缺失值怎么办?
答案是遍历所有的特征,从缺失最少的开始进行填补(因为填补缺失最少的特征所需要的准确信息最少)。
填补一个特征时,先将其他特征的缺失值用0代替,每完成一次回归预测,就将预测值放到原本的特征矩阵中,
再继续填补下一个特征。每一次填补完毕,有缺失值的特征会减少一个,所以每次循环后,需要用0来填补的特征就越来越少'''
X_missing_reg = X_missing.copy()
sortindex = np.argsort(X_missing_reg.isnull().sum(axis=0))for i in sortindex:#构建我们的新特征矩阵和新标签df = X_missing_regfillc = df.iloc[:,i]df = pd.concat([df.iloc[:,df.columns != i],y],axis=1)#在新特征矩阵中,对含有缺失值的列,进行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 = [x,x_miss_mean,x_miss_zero,X_missing_reg]mse = []
std = []
for x in X:estimator = RandomForestRegressor(random_state=0, n_estimators=100)scores = cross_val_score(estimator,x,y,scoring='neg_mean_squared_error',cv=5).mean()mse.append(scores * -1)
# 画图
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()

在这里插入图片描述

3 泛化误差详解

模型调参,第一步是要找准目标:我们要做什么?

一般来说,这个目标是提升某个模型评估指标,比如对于随机森林来说,我们想要提升的是模型在未知数据上的准确率(由score或oob_score_来衡量)。

找准了这个目标,我们就需要思考:模型在未知数据上的准确率受什么因素影响?

在机器学习中,我们用来衡量模型在未知数据上的准确率的指标,叫做泛化误差(Genelization error)

3.1 泛化误差与模型结构的关系

当模型在未知数据(测试集或者袋外数据)上表现糟糕时,我们说模型的泛化程度不够,泛化误差大,模型的效果
不好。泛化误差受到模型的结构(复杂度)影响。

如下图:

  • 当模型太复杂,模型就会过拟合,泛化能力就不够,所以泛化误差大。

  • 当模型太简单,模型就会欠拟合,拟合能力就不够,所以误差也会大。

  • 只有当模型的复杂度刚刚好的才能够达到泛化误差最小的目标

在这里插入图片描述

模型的复杂度与参数的关系

  • 对树模型来说,树越茂盛,深度越深,枝叶越多,模型就越复杂

  • 所以树模型是天生位于图的右上角的模型,随机森林是以树模型为基础,所以随机森林也是天生复杂度高的模型。随机森林的参数,都是向着一个目标去:减少模型的复杂度,把模型往图像的左边移动,防止过拟合

  • 当然了,调参没有绝对,也有天生处于图像左边的随机森林,所以调参之前,我们要先判断,模型现在究竟处于图像的哪一边。

3.2 随机森林与泛化误差

我们现在已经知道:

1)模型太复杂或者太简单,都会让泛化误差高,我们追求的是位于中间的平衡点
2)模型太复杂就会过拟合,模型太简单就会欠拟合
3)对树模型和树的集成模型来说,树的深度越深,枝叶越多,模型越复杂
4)树模型和树的集成模型的目标,都是减少模型复杂度,把模型往图像的左边移动

随机森林的调参方向:降低模型的复杂度

我们就可以将那些对复杂度影响巨大的参数挑选出来,研究他们的单调性,然后专注调整那些能最大限度让复杂度降低的参数。 当复杂度已经不能再降低的时候,我们就不必再调整了。

参数对模型在未知数据上的评估性能的影响影响程度
n_estimators提升至平稳,n_estimators↑,不影响单个模型的复杂度⭐⭐⭐⭐
max_depth有增有减,默认最大深度,即最高复杂度,向复杂度降低的方向调参 max_depth↓,模型更简单,且向图像的左边移动⭐⭐⭐
min_samples _leaf有增有减,默认最小限制1,即最高复杂度,向复杂度降低的方向调参 min_samples_leaf↑,模型更简单,且向图像的左边移动⭐⭐
min_samples _split有增有减,默认最小限制2,即最高复杂度,向复杂度降低的方向调参 min_samples_split↑,模型更简单,且向图像的左边移动⭐⭐
max_features有增有减,默认auto,是特征总数的开平方,位于中间复杂度,既可以 向复杂度升高的方向,也可以向复杂度降低的方向调参 max_features↓,模型更简单,图像左移 max_features↑,模型更复杂,图像右移 max_features是唯一的,既能够让模型更简单,也能够让模型更复杂的参 数,所以在调整这个参数的时候,需要考虑我们调参的方向
criterion有增有减,一般使用gini

3.3 方差与偏差

集成模型在未知数据集上的泛化误差E,由方差(var),偏差(bais)和噪声(ε)共同决定。

偏差:模型的预测值与真实值之间的差异,模型越精确,偏差越低。

方差:反映的是模型每一次输出结果与模型预测值的平均水平之间的误差,模型越稳定,方差越低。

其中偏差衡量模型是否预测得准确,偏差越小,模型越“准”;而方差衡量模型每次预测的结果是否接近,即是说方
差越小,模型越“稳” 。

偏差大偏差小
方差大模型不适合这个数据过拟合 模型很复杂 对某些数据集预测很准确 对某些数据集预测很糟糕
方差小欠拟合、模型相对简单 预测很稳定 但对所有的数据预测都不太准确泛化误差小,我们的目标

泛化误差和方差及偏差的关系

在这里插入图片描述

  • 模型复杂度大的时候,方差高,偏差低。

    • 偏差低,就是要求模型要预测得“准”。模型就会更努力去学习更多信息,会具体于训练数据,这会导致,模型在一部分数据上表现很好,在另一部分数据上表现却很糟糕。
    • 模型泛化性差,在不同数据上表现不稳定,所以方差就大。而要尽量学习训练集,模型的建立必然更多细节,复杂程度必然上升。所以,复杂度高,方差高,总泛化误差高。
  • 相对的,复杂度低的时候,方差低,偏差高。

    • 方差低,要求模型预测得“稳”,泛化性更强,那对于模型来说,它就不需要对数据进行一个太深的学习,只需要建立一个比较简单,判定比较宽泛的模型就可以了。
    • 结果就是,模型无法在某一类或者某一组数据上达成很高的准确度,所以偏差就会大。所以,复杂度低,偏差高,总泛化误差高。

随机森林中的方差与偏差

随机森林的基评估器都拥有较低的偏差和较高的方差,因为决策树本身是预测比较”准“,比较容易过拟合的模型,装袋法本身也要求基分类器的准确率必须要有50%以上。

所以以随机森林为代表的装袋法的训练过程旨在降低方差,即降低模型复杂度,所以随机森林参数的默认设定都是假设模型本身在泛化误差最低点的右边

4 随机森林在乳腺癌数据集上的调参

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import pandas as pd
import numpy as npdata = load_breast_cancer()# 乳腺癌数据集有569条记录,30个特征,单看维度虽然不算太高,但是样本量非常少。过拟合的情况可能存在
data.data.shape
# 进行一次简单的建模,看看模型本身在数据集上的效果
rfc = RandomForestClassifier(n_estimators=100,random_state=20)
score_pre = cross_val_score(rfc,data.data,data.target,cv=10).mean()print(score_pre)  # 0.9648809523809524
# 随机森林调整的第一步:无论如何先来调n_estimatorsscorel = []
for i in range(0,200,10):rfc = RandomForestClassifier(n_estimators=i+1,n_jobs=-1,random_state=20)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()

在这里插入图片描述

# 在确定好的范围内,进一步细化学习曲线
scorel = []
for i in range(45,80):rfc = RandomForestClassifier(n_estimators=i,n_jobs=-1,random_state=20)score = cross_val_score(rfc,data.data,data.target,cv=10).mean()scorel.append(score)print(max(scorel),([*range(45,80)][scorel.index(max(scorel))]))
plt.figure(figsize=[20,5])
plt.plot(range(45,80),scorel)
plt.show()

在这里插入图片描述

# 接下来就进入网格搜索,使用网格搜索对参数一个个进行调整。
# 为什么我们不同时调整多个参数呢?
# 1)同时调整多个参数会运行非常缓慢。
# 2)同时调整多个参数,会让我们无法理解参数的组合是怎么得来的,所以即便网格搜索调出来的结果不好,我们也不知道从哪里去改。
# 在这里,为了使用复杂度-泛化误差方法(方差-偏差方法),我们对参数进行一个个地调整。# 为网格搜索做准备,书写网格搜索的参数
"""
有一些参数是没有参照的,很难说清一个范围,这种情况下我们使用学习曲线,看趋势从曲线跑出的结果中选取一个更小的区间,再跑曲线param_grid = {'n_estimators':np.arange(0, 200, 10)}
param_grid = {'max_depth':np.arange(1, 20, 1)}
param_grid = {'max_leaf_nodes':np.arange(25,50,1)}有一些参数是可以找到一个范围的,或者说我们知道他们的取值和随着他们的取值,模型的整体准确率会如何变化,这样的参数我们就可以直接跑网格搜索param_grid = {'criterion':['gini', 'entropy']}
param_grid = {'min_samples_split':np.arange(2, 2+20, 1)}
param_grid = {'min_samples_leaf':np.arange(1, 1+10, 1)}
param_grid = {'max_features':np.arange(1,30,1)}
"""# 按照参数对模型整体准确率的影响程度进行调参,首先调整max_depth# 调整max_depth
param_grid = {'max_depth':np.arange(1, 20, 1)}# 一般根据数据的大小来进行一个试探,乳腺癌数据很小,所以可以采用1~10,或者1~20这样的试探
# 但对于大型数据来说,我们应该尝试30~50层深度(或许还不足够更应该画出学习曲线,来观察深度对模型的影响)
rfc = RandomForestClassifier(n_estimators=59,random_state=20)GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)
print(GS.best_params_)
print(GS.best_score_) # 模型评分和之前一模一样,说明已经在最佳参数了,无需再调了#{'max_depth': 9}
#0.968421052631579
# 调整max_features
param_grid = {'max_features':np.arange(1,30,1)}
"""
max_features是唯一一个即能够将模型往左(低方差高偏差)推,也能够将模型往右(高方差低偏差)推的参数。max_features的默认最小值是sqrt(n_features)。
"""
rfc = RandomForestClassifier(n_estimators=59,random_state=20)GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(data.data,data.target)print(GS.best_params_)
print(GS.best_score_)  # 最佳模型评分和之前一模一样,说明模型达到了上限
# {'max_features': 5}
# 0.968421052631579

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/94031.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第四十二天|LeetCode 121,122

目录 LeetCode 121.买卖股票的最佳时机 动态规划五步曲: 1.确定dp[i][j] 的含义 2.找出递推公式 3.初始化dp数组 4.确定遍历方向 5.打印dp数组 LeetCode 122.买卖股票的最佳时间II 动态规划五步曲: 1.确定dp[i][j] 的含义 2.找出递推公式 3.初始化dp数组…

[K8s]问题描述:k8s拉起来的容器少了cuda的so文件

问题解决:需要设置Runtimes:nvidia的同时设置Default Runtimenvidia

SpringCloud实用篇7——深入elasticsearch

目录 1 数据聚合1.1 聚合的种类1.2 DSL实现聚合1.2.1 Bucket聚合语法1.2.2 聚合结果排序1.2.3 限定聚合范围1.2.4 Metric聚合语法1.2.5.小结 1.3 RestAPI实现聚合1.3.1 API语法1.3.2 业务需求1.3.3 业务实现 2 自动补全2.1 拼音分词器2.2 自定义分词器2.3 自动补全查询2.4 实现…

git一次错误提交的回滚(不同分支因merge-需回滚)

—————————————————————————————— 注意!注意!注意!git revert的坑(能不revert千万不要操作) —————————————————————————————— 场景:提交到…

Express 实战(一):概览

在正式学习 Express 内容之前,我们有必要从大的方面了解一下 Node.js 。 在很长的一段时间里,JavaScript 一门编写浏览器中运行脚本的语言。不过近些年,随着互联网的发展以及技术进步,JavaScript 迎来了一个集中爆发的时代。一个…

图数据库_Neo4j基于docker服务版安装_Neo4j Desktop桌面版安装---Neo4j图数据库工作笔记0004

然后我们来看看如何用docker来安装Neo4j community server 首先去执行docker pull neo4j:3.5.22-community 去拉取镜像 然后执行命令就可以安装了 可以用docker ps查看一下 看看暴露了哪些端口 然后再看一下访问一下这个时候,要用IP地址了注意 然后再来看一下安装Desktop 去下…

竞赛项目 车位识别车道线检测 - python opencv

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) …

Redis_亿级访问量数据处理

11. 亿级访问量数据处理 11.1 场景表述 手机APP用户登录信息,一天用户登录ID或设备ID电商或者美团平台,一个商品对应的评论文章对应的评论APP上有打卡信息网站上访问量统计统计新增用户第二天还留存商品评论的排序月活统计统计独立访客(Unique Vistito…

nginx反向代理后实现nginx和apache两种web服务器能够记录客户端的真实IP地址

一.构建环境 二.配置反向代理 1.基于源码安装的nginx环境下修改nginx.conf(设备1) 2.通过windows powershell进行修改hosts文件并测试 3.设备2和设备3上查看日志,可以看到访问来源都是代理服务器(2.190)而不是真实…

自定义WEB框架结合Jenkins实现全自动测试

自定义WEB框架结合Jenkins实现全自动测试 allure生成 allure生成 1.allure–纯命令运行 -固定的–稍微记住对应的单词即可。2 安装,2个步骤: 1.下载allure包,然后配置环境变量。 https://github.com/allure-framework/allure2/releases/tag/2.22.4 2.在…

【boost网络库从青铜到王者】第五篇:asio网络编程中的同步读写的客户端和服务器示例

文章目录 1、简介2、客户端设计3、服务器设计3.1、session函数3.2、StartListen函数3、总体设计 4、效果测试5、遇到的问题5.1、服务器遇到的问题5.1.1、不用显示调用bind绑定和listen监听函数5.1.2、出现 Error occured!Error code : 10009 .Message: 提供的文件句柄无效。 [s…

召集令:CloudQuery 社区有奖征文活动来啦!

CloudQuery 社区第一期征文活动来袭!!!只要你对 CloudQuery 产品感兴趣,或者是希望了解 CQ ,都可以来参加,在本期活动中,我们也为大家准备了多种主题供你选择,CQ 使用案例、版本对比…

Java【Spring】Bean 的作用域和生命周期

文章目录 前言前言一、关于 Bean 的作用域问题引入二、Bean 的作用域1, 什么是 Bean 的作用域2, Bean 的六种作用域3, 设置 Bean 的作用域(解决开篇的问题) 三、Bean 的生命周期总结 前言 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4…

在vue中使用swiper轮播图(搭配watch和$nextTick())

在组件中使用轮播图展示图片信息: 1.下载swiper,5版本为稳定版本 cnpm install swiper5 2.在组件中引入swiper包和对应样式,若多组件使用swiper,可以把swiper引入到main.js入口文件中: import swiper/css/swiper.css //引入swipe…

iOS 17 正式版预计 9 月中下旬发布,部分新功能延后推出

苹果公司预计将在 9 月中下旬推出 iOS 17 正式版,iPhone XS 及更新的机型可免费更新。这次更新包含了许多新功能,但是根据苹果公司的网站显示,并不是所有的功能都会立即可用。苹果表示有一些功能“将在今年晚些时候推出”,比如&am…

213、仿真-基于51单片机智能电表电能表用电量电费报警Proteus仿真设计(程序+Proteus仿真+原理图+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、原理图 五、程序源码 资料包括: 需要完整的资料可以点击下面的名片加下我,找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选…

Constanze‘s Machine

一、题目 二、分析 列表找规律&#xff0c;不同长度的u能够带来多少种不同的情况 发现规律&#xff0c;case满足斐波那契数列。 所以可以先预计算斐波那契数列fib。 #include<iostream> #include<cstring> #include<algorithm> #define int long long usi…

VS2019生成的DLL,给QT(MinGW版本)使用的小结

VS2019端&#xff1a; a 基于生成一个DLL的工程&#xff08;要注意生成是x86&#xff0c;还是x64的&#xff0c;需要和后面的QT的App工程对应&#xff09;&#xff0c;这里不多解释了&#xff0c;网上多的是&#xff1b; b 在cpp实现文件里&#xff0c;假如要导出一个这样的…

IDEA关闭项目,但是后台程序没有关闭进程(解决方案)

最近遇到一个很奇怪的问题&#xff0c;idea关闭项目后&#xff0c;系统进程没有杀死进程&#xff0c;再次执行的时候会提示端口占用&#xff0c;并提示Process exited with an error: 1 (Exit value: 1) 错误原因&#xff1a;应用程序关闭后&#xff0c;进程不能同步关闭 解决方…

【Nginx17】Nginx学习:目录索引、字符集与浏览器判断模块

Nginx学习&#xff1a;目录索引、字符集与浏览器判断模块 今天要学习的内容有几个还是大家比较常见的&#xff0c;所以学习起来也不会特别费劲。对于目录的默认页设置大家都不会陌生&#xff0c;字符集的设置也比较常见&#xff0c;而浏览器的判断这一块&#xff0c;可能有同学…