Adaboost处理多分类问题(参数调优,解决数据不平衡问题)

AdaBoostClassifier和AdaBoostRegressor框架参数

我们首先来看看AdaBoostClassifier和AdaBoostRegressor框架参数。两者大部分框架参数相同,下面我们一起讨论这些参数,两个类如果有不同点我们会指出。

1)base_estimator:AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。另外有一个要注意的点是,如果我们选择的AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict还需要有predict_proba。

2)algorithm:这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。

3)loss:这个参数只有AdaBoostRegressor有,Adaboost.R2算法需要用到。有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择, 默认是线性,一般使用线性就足够了,除非你怀疑这个参数导致拟合程度不好。这个值的意义在原理篇我们也讲到了,它对应了我们对第k个弱分类器的中第i个样本的误差的处理。

4) n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是50。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。

5) learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,即每个弱学习器的权重缩减系数ν,较小的ν意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的ν开始调参,默认是1。

AdaBoostClassifier和AdaBoostRegressor弱学习器参数

这里我们再讨论下AdaBoostClassifier和AdaBoostRegressor弱学习器参数,由于使用不同的弱学习器,则对应的弱学习器参数各不相同。这里我们仅仅讨论默认的决策树弱学习器的参数。即CART分类树DecisionTreeClassifier和CART回归树DecisionTreeRegressor。

DecisionTreeClassifier和DecisionTreeRegressor的参数基本类似,在scikit-learn决策树算法类库使用小结这篇文章中我们对这两个类的参数做了详细的解释。这里我们只拿出调参数时需要尤其注意的最重要几个的参数再拿出来说一遍:

1) 划分时考虑的最大特征数max_features: 可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑"log2"个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

2) 决策树最大深max_depth: 默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。

3) 内部节点再划分所需最小样本数min_samples_split: 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

4) 叶子节点最少样本数min_samples_leaf: 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

5)叶子节点最小的样本权重和min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

6) 最大叶子节点数max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

adaboost方法

decision_function(X):返回决策函数值(比如svm中的决策距离)
fit(X,Y):在数据集(X,Y)上训练模型。
get_parms():获取模型参数
predict(X):预测数据集X的结果。
predict_log_proba(X):预测数据集X的对数概率。
predict_proba(X):预测数据集X的概率值。
score(X,Y):输出数据集(X,Y)在模型上的准确率。
staged_decision_function(X):返回每个基分类器的决策函数值
staged_predict(X):返回每个基分类器的预测数据集X的结果。
staged_predict_proba(X):返回每个基分类器的预测数据集X的概率结果。
staged_score(X, Y):返回每个基分类器的预测准确率。

案例代码:

import pandas as pd
from sklearn.model_selection import train_test_split


df=pd.read_csv("C:/Users/86152/Desktop/data.csv")
newdf=df[df['Breast']<5] #数据清洗
# for x in newdf.index:
#     if newdf.loc[x]['Breast'] == 5:
#         print("have one data is 5")

train,test =train_test_split(newdf,test_size=0.2,random_state=1234)
lable=['Dage', 'Dyear', 'ajcc', 'cs','rx', 'Survival.month']
train_x=train[lable]
test_x=test[lable]
train_y=train.Breast
test_y=test.Breast
from sklearn.ensemble import AdaBoostClassifier
from sklearn import metrics



ada=AdaBoostClassifier()
ada.fit(train_x,train_y)
pred=ada.predict(test_x)
print(f'实际结果:{test_y[20:40]}')
print(f'预测结果:{pred[20:40]}')
print(f'标签:{ada.classes_}')
print("模型的准确率:\n",metrics.accuracy_score(test_y,pred))
print("模型的评估报告:\n",metrics.classification_report(test_y,pred))

Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第1张图片
可以发现上面的预测结果只有一类,说明模型并没有学习到更多的分类,需要对模型进行进一步的调参,使用网格法进行参数调优。

gridSearchCV(网格搜索)的参数、方法及示例

1.简介
GridSearchCV的sklearn官方网址:

GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数。但是这个方法适合于小数据集,一旦数据的量级上去了,很难得出结果。这个时候就是需要动脑筋了。数据量比较大的时候可以使用一个快速调优的方法——坐标下降。它其实是一种贪心算法:拿当前对模型影响最大的参数调优,直到最优化;再拿下一个影响最大的参数调优,如此下去,直到所有的参数调整完毕。这个方法的缺点就是可能会调到局部最优而不是全局最优,但是省时间省力,巨大的优势面前,还是试一试吧,后续可以再拿bagging再优化。

通常算法不够好,需要调试参数时必不可少。比如SVM的惩罚因子C,核函数kernel,gamma参数等,对于不同的数据使用不同的参数,结果效果可能差1-5个点,sklearn为我们提供专门调试参数的函数grid_search。

2.参数说明
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, iid=True, refit=True, cv=None, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise’, return_train_score=’warn’)

(1) estimator

选择使用的分类器,并且传入除需要确定最佳的参数之外的其他参数。每一个分类器都需要一个scoring参数,或者score方法:estimator=RandomForestClassifier(min_samples_split=100,min_samples_leaf=20,max_depth=8,max_features=‘sqrt’,random_state=10),

(2) param_grid

需要最优化的参数的取值,值为字典或者列表,例如:param_grid =param_test1,param_test1 = {‘n_estimators’:range(10,71,10)}。

(3) scoring=None

模型评价标准,默认None,这时需要使用score函数;或者如scoring=‘roc_auc’,根据所选模型不同,评价准则不同。字符串(函数名),或是可调用对象,需要其函数签名形如:scorer(estimator, X, y);如果是None,则使用estimator的误差估计函数。具体值的选取看本篇第三节内容。

(4) fit_params=None

(5) n_jobs=1

n_jobs: 并行数,int:个数,-1:跟CPU核数一致, 1:默认值

(6) iid=True

iid:默认True,为True时,默认为各个样本fold概率分布一致,误差估计为所有样本之和,而非各个fold的平均。

(7) refit=True

默认为True,程序将会以交叉验证训练集得到的最佳参数,重新对所有可用的训练集与开发集进行,作为最终用于性能评估的最佳模型参数。即在搜索参数结束后,用最佳参数结果再次fit一遍全部数据集。

(8) cv=None

交叉验证参数,默认None,使用三折交叉验证。指定fold数量,默认为3,也可以是yield训练/测试数据的生成器。

(9) verbose=0, scoring=None

verbose:日志冗长度,int:冗长度,0:不输出训练过程,1:偶尔输出,>1:对每个子模型都输出。

(10) pre_dispatch=‘2*n_jobs’

指定总共分发的并行任务数。当n_jobs大于1时,数据将在每个运行点进行复制,这可能导致OOM,而设置pre_dispatch参数,则可以预先划分总共的job数量,使数据最多被复制pre_dispatch次

(11) error_score=’raise’

(12) return_train_score=’warn’

如果“False”,cv_results_属性将不包括训练分数

回到sklearn里面的GridSearchCV,GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。

  1. Scoring parameter:评价标准参数详细说明
    Model-evaluation tools using cross-validation (such as model_selection.cross_val_score andmodel_selection.GridSearchCV) rely on an internal scoring strategy. This is discussed in the section The scoring parameter: defining model evaluation rules.
    Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第2张图片

For the most common use cases, you can designate a scorer object with the scoring parameter; the table below shows all possible values. All scorer objects follow the convention that higher return values are better than lower return values. Thus metrics which measure the distance between the model and the data, like metrics.mean_squared_error, are available as neg_mean_squared_error which return the negated value of the metric.

4.属性
(1)cv_results_ : dict of numpy (masked) ndarrays

具有键作为列标题和值作为列的dict,可以导入到DataFrame中。注意,“params”键用于存储所有参数候选项的参数设置列表。

(2)best_estimator_ : estimator

通过搜索选择的估计器,即在左侧数据上给出最高分数(或指定的最小损失)的估计器。 如果refit = False,则不可用。

(3)best_score_ : float best_estimator的分数

(4)best_params_ : dict 在保存数据上给出最佳结果的参数设置

(5)best_index_ : int 对应于最佳候选参数设置的索引(cv_results_数组)。
search.cv_results _ [‘params’] [search.best_index_]中的dict给出了最佳模型的参数设置,给出了最高的平均分数(search.best_score_)。

(6)scorer_ : function

Scorer function used on the held out data to choose the best parameters for the model.

(7)n_splits_ : int

The number of cross-validation splits (folds/iterations).

(8)grid_scores_:给出不同参数情况下的评价结果

数据不平衡问题

当使用 auc的时候,会出现评分都是nan的情况。 因为auc是进行二分类的评分。不适用于多分类模型评分。
Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第3张图片

当使用默认的评估函数的时候1,25,50,75,100.
Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第4张图片
当使用默认的评估函数的时候1,3,7,11,15.
在这里插入图片描述

(1)朴素随即过采样

就是通过生成少量样本的数据,使得整体数据看起来更加的平衡。
对应python库中的RandomOverSmpler:

from imblearn.over_sampling import RandomOverSampler

ros = RandomOverSampler(random_state=0)
X_resampled, y_resampled = ros.fit_sample(X, y)

(2)朴素随机欠采样

与过采样相反,是通过在多量样本中随即采取一些样本与少量样本共同组成新的数据集。采取样本又分为有放回和不放回两种,有放回就是这一次选取的数据下一次又有可能选取到。
对应python库中的RandomUnderSampler:其中replacement=True 参数,可以实现自动法boostrap

from imblearn.under_sampling import RandomUnderSampler

ros = RandomUnerSampler(random_state=0,replacement=True)
X_resampled,y_resampled = ros.fit_sample(X,y)

随机采样的优缺点
随机采样最大的优点是简单,但缺点也很明显。

  • 上采样后的数据集中会反复出现一些样本,训练出来的模型会有一定的过拟合;
  • 而下采样的缺点显而易见,那就是最终的训练集丢失了数据,模型只学到了总体模式的一部分。

上采样会把小众样本复制多份,一个点会在高维空间中反复出现,这会导致一个问题,那就是运气好就能分对很多点,否则分错很多点。

为了解决这一问题,可以在每次生成新数据点时加入轻微的随机扰动,经验表明这种做法非常有效,但是这一方式会加重过拟合。

SMOTE(过采样的改进)

SMOTE算法的基本思想是对少数类样本进行分析并根据少数类样本人工合成新样本添加到数据集中。
但是SMOTE算法缺点也十分明显:一方面是增加了类之间重叠的可能性(由于对每个少数类样本都生成新样本,因此容易发生生成样本重叠(Overlapping)的问题),另一方面是生成一些没有提供有益信息的样本。
对应Python库中函数为SMOTE:

from imblearn.under_sampling import ClusterCentroids

cc = ClusterCentroids(random_state=0)
X_resampled, y_resampled = cc.fit_sample(X, y)

EasyEnsemble(欠采样的改进)高版本已经被删除

随机欠采样的问题主要是信息丢失,为了解决信息丢失的问题提出了以下几种改进的方式:

EasyEnsemble,利用模型融合的方法(Ensemble)
多次过采样(放回采样,这样产生的训练集才相互独立)产生多个不同的训练集,进而训练多个不同的分类器,通过组合多个分类器的结果得到最终的结果。简单的最佳实践是建立n个模型,每个模型使用少数类的所有样本和多数类的n个不同样本。假设二分类数据集的正负类比例为50000:1000,最后要得到10个模型,那么将保留负类的1000个样本,并随机采样得到10000个正类样本。
然后,将10000个样本成10份,每一份与负类样本组合得到新的子训练集,训练10个不同的模型。

EasyEnsemble方法对应Python库中函数为EasyEnsemble,有两个很重要的参数:

  • n_subsets控制的是子集的个数
  • replacement决定是有放回还是无放回的随机采样
from imblearn.ensemble import EasyEnsemble

ee = EasyEnsemble(random_state=0, n_subsets=10)
X_resampled, y_resampled = ee.fit_sample(X, y)

BalanceCascade,利用增量训练的思想(Boosting)高版本已经被删除了

先通过一次下采样产生训练集,训练一个分类器,对于那些分类正确的多数类样本不放回,然后对这个更小的多数类样本下采样产生训练集,训练第二个分类器,以此类推,最终组合所有分类器的结果得到最终结果。

BalanceCascade方法对应Python库中函数为BalanceCascade,有三个很重要的参数:

  • estimator是选择使用的分类器
  • n_max_subset控制的是子集的个数
  • bootstrap决定是有放回还是无放回的随机采样
from imblearn.ensemble import BalanceCascade
from sklearn.linear_model import LogisticRegression

bc = BalanceCascade(random_state=0,
             estimator=LogisticRegression(random_state=0),
             n_max_subset=4)
X_resampled, y_resampled = bc.fit_sample(X, y)

反复调节参数,得到最好的参数,为最终的模型训练

确定决策树的最大深度

(1)15-30
在这里插入图片描述
(2)22-29 :23
Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第5张图片

确定adaboost的弱学习器数量和步长

(1)步长:0.1 ,弱学习器为100
Adaboost处理多分类问题(参数调优,解决数据不平衡问题)_第6张图片

你可能感兴趣的:(分类,数据挖掘,人工智能,python,决策树,算法)