kaggle比赛_Kaggle比赛神器集成学习

本文转载自 

点击上方"枫叶AI",获取更多信息  

c58b97b75b1dbf4ee0e487960af1f91c.gif

1、集成学习概述

集成学习的原理正如盲人摸象这个古代寓言所揭示的道理类似:一群盲人第一次遇到大象,想要通过触觉来了解大象。每个人都摸到大象身体的不同部位。但只摸到不同部分,比如鼻子或一条腿。这些人描述的大象是这样的:“它像一条蛇”,“像一根柱子或一棵树”,等等。这些盲人就好比机器学习模型,每个人都是根据自己的假设,并从自己的角度来理解训练数据的多面性。每个人都得到真相的一部分,但不是全部真相。将他们的观点汇集在一起,你就可以得到对数据更加准确的描述。大象是多个部分的组合,每个盲人说的都不完全准确,但综合起来就成了一个相当准确的观点。

集成学习(ensemble learning)可以说是现在非常火爆的机器学习方法了。目前,集成方法在许多著名的机器学习比赛(如 Netflix、KDD 2009 和 Kaggle 比赛)中能够取得很好的名次。

集成学习本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务。也就是我们常说的“博采众长”。集成学习可以用于分类问题集成,回归问题集成,特征选取集成,异常点检测集成等等,可以说所有的机器学习领域都可以看到集成学习的身影。

集成学习的主要思想:对于一个比较复杂的任务,综合许多人的意见来进行决策往往比一家独大好,正所谓集思广益。其过程如下:

ae4569b3b47021361932aeb7e743d290.png

一般来说集成学习可以分为三大类:

①用于减少方差的bagging(方差描述的是预测值作为随机变量的离散程度)

②用于减少偏差的boosting(偏差描述的是预测值和真实值之间的差异,即提高拟合能力)

③用于提升预测效果的stacking

18.1.1 Bagging

Bagging是引导聚合的意思。减少一个估计方差的一种方式就是对多个估计进行平均。

Bagging使用装袋采样来获取数据子集训练基础学习器。通常分类任务使用投票的方式集成,而回归任务通过平均的方式集成。

给定一个大小为n的训练集 D,Bagging算法从中均匀、有放回地选出 m个大小为 n' 的子集Di,作为新的训练集。在这 m个训练集上使用分类、回归等算法,则可得到 m个模型,再通过取平均值、取多数票等方法综合产生预测结果,即可得到Bagging的结果。具体如下图:

757da8716d11b901a9ac84cdf5c8f0c6.png

对于Bagging需要注意的是,每次训练集可以取全部的特征进行训练,也可以随机选取部分特征训练,例如随机森林就是每次随机选取部分特征。

常用的集成算法模型是随机森林和随机树等。

在随机森林中,每个树模型都是装袋采样训练的。另外,特征也是随机选择的,最后对于训练好的树也是随机选择的。

这种处理的结果是随机森林的偏差增加的很少,而由于弱相关树模型的平均,方差也得以降低,最终得到一个方差小,偏差也小的模型。

0efe975b1c6a4c9995d1c456bd492a8a.png

18.1.2 boosting

Boosting指的是通过算法集合将弱学习器转换为强学习器。boosting的主要原则是训练一系列的弱学习器,所谓弱学习器是指仅比随机猜测好一点点的模型,例如较小的决策树,训练的方式是利用加权的数据。在训练的早期对于错分数据给予较大的权重。

对于训练好的弱分类器,如果是分类任务按照权重进行投票,而对于回归任务进行加权,然后再进行预测。boosting和bagging的区别在于是对加权后的数据利用弱分类器依次进行训练。

boosting是一族可将弱学习器提升为强学习器的算法,这族算法的工作机制类似:

(1)先从初始训练集训练出一个基学习器;

(2)再根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续受到更多关注;

(3)基于调整后的样本分布来训练下一个基学习器;

(4)重复进行上述步骤,直至基学习器数目达到事先指定的值T,最终将这T个基学习器进行加权结合。具体步骤如下图

e2f27cdd64e8e89b556f8b713e6554c1.png

如果上面这个图还不太直观,大家可参考以下简单示例:

1、假设我们有如下样本图:

89664212273c62d5b7d207e50471b839.png

2、第一次分类

1d10560505a93d4b2f62a2500b696938.png

第2次分类

22b16bf9775dfaf3634681c751c08517.png

在图2中被正确测的点有较小的权重(尺寸较小),而被预测错误的点(+)则有较大的权重(尺寸较大)

第3次分类

7514ed556a3750aedcd330b54b1516d9.png

在图3中被正确测的点有较小的权重(尺寸较小),而被预测错误的点(-)则有较大的权重(尺寸较大)。

第4次综合以上分类

27bdc9336f08b332b182de3d555d01f4.png

下面描述的算法是最常用的一种boosting算法,叫做AdaBoost,表示自适应boosting。

c4fb9e31fcf367cae779e91e6f434786.png

AdaBoost算法每一轮都要判断当前基学习器是否满足条件,一旦条件不满足,则当前学习器被抛弃,且学习过程停止。

AdaBoost算法中的个体学习器存在着强依赖关系,应用的是串行生成的序列化方法。每一个基生成器的目标,都是为了最小化损失函数。所以,可以说AdaBoost算法注重减小偏差。

由于属于boosting算法族,采用的是加性模型,对每个基学习器的输出结果加权处理,只会得到一个输出预测结果。所以标准的AdaBoost只适用于二分类任务。基于Boosting思想的除AdaBoost外,还有GBDT、XGBoost等。

18.1.3 Stacking

将训练好的所有基模型对训练基进行预测,第j个基模型对第i个训练样本的预测值(概率值或标签)将作为新的训练集中第i个样本的第j个特征值,最后基于新的训练集进行训练。同理,预测的过程也要先经过所有基模型的预测形成新的测试集,最后再对测试集进行预测。如下图所示。

94b400608763930d06ced7cd032ea618.png

上图可简化为:

8de5d3271c8ab6e855d886cecec47897.png

其中Meta-Classifier在实际应用中通常使用单层logistic回归模型。

具体算法为:

18.1.3 .1Stacking中元分类层

为何要Meta-Classifier层?设置该层的目的是啥?其原理是什么?等等或许你还不很清楚,没关系。你看了下面这个说明或许就清楚多了。

让我们假设有三个学生名为LR,SVM,KNN,他们争论一个物理问题,他们对正确的答案可能有不同的看法:

af108bb40572273d7f7ed65622473b0d.png

他们认为没有办法相互说服他们的情况,他们通过平均估计他们做民主的事情,这个案例是14.他们使用了最简单的集合形式-AKA模型平均。

他们的老师,DL小姐 - 一位数学老师 - 见证了学生们所拥有的论点并决定提供帮助。她问“问题是什么?”,但是学生们拒绝告诉她(因为他们知道提供所有信息对他们不利,除了他们认为她可能会觉得愚蠢他们在争论这么微不足道的事情)。然而,他们确实告诉她这是一个与物理相关的论点。

在这种情况下,教师无法访问初始数据,因为她不知道问题是什么。然而,她确实非常了解学生 - 他们的优点和缺点,她决定她仍然可以帮助解决这个问题。使用历史信息,了解学生过去的表现,以及她知道SVM喜欢物理并且在这个课程中表现优异的事实(加上她的父亲在青年科学家的物理学院工作),她认为最多适当的答案会更像17。

edba2a40423947664760eb40b852d145.png

在这种情况下,教师(DL)是元学习者。她使用其他模型(学生)输出的结果作为输入数据。然后,她将其与历史信息结合起来,了解学生过去的表现,以便更好地估计(并帮助解决冲突)。

然而......物理老师RF先生的意见略有不同。他一直在那里,但他一直等到这一刻才行动!RF先生最近一直在教授LR私人物理课程,以提高他的成绩(错过DL不知道的事情),他认为LR对最终估计的贡献应该更大。因此他声称正确的答案更像是16!

在这种情况下,RF先生也是一个元学习者,他用不同的逻辑处理历史数据 - 他可以访问比DL小姐更多的来源(或不同的历史信息)。

只有校长GBM做出决定,才能解决此争议!GBM不知道孩子们说了什么,但他很了解他的老师,他更热衷于信任他的物理老师(RF)。他总结答案更像是16.2。

c1d45aae966ce30dff4e7928826b7872.png

在这种情况下,校长是元级学习者或元学习者的元学习者,并且通过处理他的老师的历史信息,他仍然可以提供比他们的结果的简单平均值更好的估计。

参考文档:

18.1.3.2Stacking的几种方法

1) 使用分类器产生的特征输出作为meta-classifier的输入

基本使用方法就是,使用前面分类器产生的特征输出作为最后总的meta-classifier的输入数据,以下为利用stacking的基本使用方法实例。

(1)生成数据

from sklearn import datasetsiris = datasets.load_iris()X, y = iris.data[:, 1:3], iris.target

(2)导入需要的库

from sklearn import model_selectionfrom sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifierfrom mlxtend.classifier import StackingClassifierimport numpy as np

(3)训练各种基模型

clf1 = KNeighborsClassifier(n_neighbors=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()lr = LogisticRegression()sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],                           meta_classifier=lr)print('3-fold cross validation:\n')for clf, label in zip([clf1, clf2, clf3, sclf],                       ['KNN',                        'Random Forest',                        'Naive Bayes',                       'StackingClassifier']):    scores = model_selection.cross_val_score(clf, X, y,                                               cv=3, scoring='accuracy')    print("Accuracy: %0.2f (+/- %0.2f) [%s]"           % (scores.mean(), scores.std(), label))

运行结果

3-fold cross validation:

Accuracy: 0.91 (+/- 0.01) [KNN]

Accuracy: 0.91 (+/- 0.06) [Random Forest]

Accuracy: 0.92 (+/- 0.03) [Naive Bayes]

Accuracy: 0.95 (+/- 0.03) [StackingClassifier]

(4)可视化结果

%matplotlib inlineimport matplotlib.pyplot as pltfrom mlxtend.plotting import plot_decision_regionsimport matplotlib.gridspec as gridspecimport itertoolsgs = gridspec.GridSpec(2, 2)fig = plt.figure(figsize=(10,8))for clf, lab, grd in zip([clf1, clf2, clf3, sclf],                          ['KNN',                           'Random Forest',                           'Naive Bayes',                          'StackingClassifier'],                          itertools.product([0, 1], repeat=2)):    clf.fit(X, y)    ax = plt.subplot(gs[grd[0], grd[1]])    fig = plot_decision_regions(X=X, y=y, clf=clf)    plt.title(lab)

运行结果

4d601d8852894da06ce976d32643e9a4.png

使用网格方法选择超参数

from sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import GridSearchCVfrom mlxtend.classifier import StackingClassifier# Initializing modelsclf1 = KNeighborsClassifier(n_neighbors=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()lr = LogisticRegression()sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],                           meta_classifier=lr)params = {'kneighborsclassifier__n_neighbors': [1, 5],          'randomforestclassifier__n_estimators': [10, 50],          'meta-logisticregression__C': [0.1, 10.0]}grid = GridSearchCV(estimator=sclf,                     param_grid=params,                     cv=5,                    refit=True)grid.fit(X, y)cv_keys = ('mean_test_score', 'std_test_score', 'params')for r, _ in enumerate(grid.cv_results_['mean_test_score']):    print("%0.3f +/- %0.2f %r"          % (grid.cv_results_[cv_keys[0]][r],             grid.cv_results_[cv_keys[1]][r] / 2.0,             grid.cv_results_[cv_keys[2]][r]))print('Best parameters: %s' % grid.best_params_)print('Accuracy: %.2f' % grid.best_score_)

运行结果

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 10}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.927 +/- 0.02 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

0.913 +/- 0.03 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 10}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.933 +/- 0.02 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

0.940 +/- 0.02 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

Best parameters: {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

Accuracy: 0.94

2)使用类别概率值作为meta-classfier的输入

另一种使用第一层基本分类器产生的类别概率值作为meta-classfier的输入,这种情况下需要将StackingClassifier的参数设置为 use_probas=True。如果将参数设置为 average_probas=True,那么这些基分类器对每一个类别产生的概率值会被平均,否则会拼接。

例如有两个基分类器产生的概率输出为:

classifier 1: [0.2, 0.5, 0.3]

classifier 2: [0.3, 0.4, 0.4]

1) average = True :

产生的meta-feature 为:[0.25, 0.45, 0.35]

2) average = False:

产生的meta-feature为:[0.2, 0.5, 0.3, 0.3, 0.4, 0.4]

以下为具体实例

from sklearn import datasetsiris = datasets.load_iris()X, y = iris.data[:, 1:3], iris.targetfrom sklearn import model_selectionfrom sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifierfrom mlxtend.classifier import StackingClassifierimport numpy as npclf1 = KNeighborsClassifier(n_neighbors=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()lr = LogisticRegression()sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],                          use_probas=True,                          average_probas=False,                          meta_classifier=lr)print('3-fold cross validation:\n')for clf, label in zip([clf1, clf2, clf3, sclf],                       ['KNN',                        'Random Forest',                        'Naive Bayes',                       'StackingClassifier']):    scores = model_selection.cross_val_score(clf, X, y,                                               cv=3, scoring='accuracy')    print("Accuracy: %0.2f (+/- %0.2f) [%s]"           % (scores.mean(), scores.std(), label))

运行结果

3-fold cross validation:

Accuracy: 0.91 (+/- 0.01) [KNN]

Accuracy: 0.91 (+/- 0.06) [Random Forest]

Accuracy: 0.92 (+/- 0.03) [Naive Bayes]

Accuracy: 0.94 (+/- 0.03) [StackingClassifier]

显然,用stacking方法的精度(Accuracy: 0.94)明显好于单个模型的精度。

3)使用堆叠分类及网格搜索

使用堆叠分类及网格搜索(Stacked Classification and GridSearch)方法,要为scikit-learn网格搜索设置参数网格,我们只需在参数网格中提供估算器的名称 - 在meta-regressor的特殊情况下,我们附加'meta-'前缀即可,以下为代码实例。

from sklearn.linear_model import LogisticRegressionfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import GridSearchCVfrom mlxtend.classifier import StackingClassifier# Initializing modelsclf1 = KNeighborsClassifier(n_neighbors=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()lr = LogisticRegression()sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],                           meta_classifier=lr)params = {'kneighborsclassifier__n_neighbors': [1, 5],          'randomforestclassifier__n_estimators': [10, 50],          'meta-logisticregression__C': [0.1, 10.0]}grid = GridSearchCV(estimator=sclf,                     param_grid=params,                     cv=5,                    refit=True)grid.fit(X, y)cv_keys = ('mean_test_score', 'std_test_score', 'params')for r, _ in enumerate(grid.cv_results_['mean_test_score']):    print("%0.3f +/- %0.2f %r"          % (grid.cv_results_[cv_keys[0]][r],             grid.cv_results_[cv_keys[1]][r] / 2.0,             grid.cv_results_[cv_keys[2]][r]))print('Best parameters: %s' % grid.best_params_)print('Accuracy: %.2f' % grid.best_score_)

运行结果

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 10}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.967 +/- 0.01 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

0.967 +/- 0.01 {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 10}

0.667 +/- 0.00 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.967 +/- 0.01 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

0.967 +/- 0.01 {'kneighborsclassifier__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

Best parameters: {'kneighborsclassifier__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

Accuracy: 0.97

最一句是各参数最佳匹配模型的结果,显然,这个精度高于其他情况的精度。

如果我们计划多次使用回归算法,我们需要做的就是在参数网格中添加一个额外的数字后缀,如下所示:

from sklearn.model_selection import GridSearchCV# Initializing modelsclf1 = KNeighborsClassifier(n_neighbors=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()lr = LogisticRegression()sclf = StackingClassifier(classifiers=[clf1, clf1, clf2, clf3],                           meta_classifier=lr)params = {'kneighborsclassifier-1__n_neighbors': [1, 5],          'kneighborsclassifier-2__n_neighbors': [1, 5],          'randomforestclassifier__n_estimators': [10, 50],          'meta-logisticregression__C': [0.1, 10.0]}grid = GridSearchCV(estimator=sclf,                     param_grid=params,                     cv=5,                    refit=True)grid.fit(X, y)cv_keys = ('mean_test_score', 'std_test_score', 'params')for r, _ in enumerate(grid.cv_results_['mean_test_score']):    print("%0.3f +/- %0.2f %r"          % (grid.cv_results_[cv_keys[0]][r],             grid.cv_results_[cv_keys[1]][r] / 2.0,             grid.cv_results_[cv_keys[2]][r]))print('Best parameters: %s' % grid.best_params_)print('Accuracy: %.2f' % grid.best_score_)

运行结果

0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 10}

0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.967 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-....

0.667 +/- 0.00 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta-logisticregression__C': 0.1, 'randomforestclassifier__n_estimators': 50}

0.967 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

.......................................

0.967 +/- 0.01 {'kneighborsclassifier-1__n_neighbors': 5, 'kneighborsclassifier-2__n_neighbors': 5, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 50}

Best parameters: {'kneighborsclassifier-1__n_neighbors': 1, 'kneighborsclassifier-2__n_neighbors': 1, 'meta-logisticregression__C': 10.0, 'randomforestclassifier__n_estimators': 10}

Accuracy: 0.97

StackingClassifier还可以对分类器参数进行网格搜索。但是,由于目前scikit-learn中GridSearchCV的实现,不可能同时搜索不同分类器和分类器参数。例如,虽然以下参数字典有效。

4)给不同及分类器不同特征

给不同及分类器不同特征是对训练基中的特征维度进行操作的,这次不是给每一个基分类器全部的特征,而是给不同的基分类器分不同的特征,即比如基分类器1训练前半部分特征,基分类器2训练后半部分特征(可以通过sklearn 的pipelines 实现)。最终通过StackingClassifier组合起来。以下为代码实例。

from sklearn.datasets import load_irisfrom mlxtend.classifier import StackingClassifierfrom mlxtend.feature_selection import ColumnSelectorfrom sklearn.pipeline import make_pipelinefrom sklearn.linear_model import LogisticRegressioniris = load_iris()X = iris.datay = iris.targetpipe1 = make_pipeline(ColumnSelector(cols=(0, 2)),                      LogisticRegression())pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)),                      LogisticRegression())sclf = StackingClassifier(classifiers=[pipe1, pipe2],                           meta_classifier=LogisticRegression())sclf.fit(X, y)

参考文档:

https://rasbt.github.io/mlxtend/user_guide/classifier/StackingClassifier/

2、投票分类器(VotingClassifier)

投票分类器的原理是结合了多个不同的机器学习分类器,使用多数票或者平均预测概率(软票),预测类标签。这类分类器对一组相同表现的模型十分有用,同时可以平衡各自的弱点。投票分类又可进一步分为多数投票分类(Majority Class Labels)、加权平均概率(soft vote,软投票)。

2.1多数投票分类(MajorityVote Class)

多数投票分类的分类原则为预测标签不同时,按最多种类为最终分类;如果预测标签相同时,则按顺序,选择排在第1的标签为最终分类。举例如下:

预测类型的标签为该组学习器中相同最多的种类:例如给出的分类如下

分类器1 -> 标签1

分类器2 -> 标签1

分类器3 -> 标签2

投票分类器(voting=‘hard’)则该预测结果为‘标签1’。

在各个都只有一个的情况下,则按照顺序来,如下:

分类器1 -> 标签2

分类器2 -> 标签1

最终分类结果为“标签2”

2.1.1 Iris数据集概述

首先,我们取得数据,下面这个链接中有数据的详细介绍,并可以下载数据集。https://archive.ics.uci.edu/ml/datasets/Iris

从数据的说明上,我们可以看到Iris有4个特征,3个类别。但是,我们为了数据的可视化,我们只保留2个特征(sepal length和petal length)。数据可视化代码如下:

%matplotlib inlineimport pandas as pdimport matplotlib.pylab as pltimport numpy as np# 加载Iris数据集作为DataFrame对象df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None) X = df.iloc[:, [0, 2]].values # 取出2个特征,并把它们用Numpy数组表示plt.scatter(X[:50, 0], X[:50, 1],color='red', marker='o', label='setosa') # 前50个样本的散点图plt.scatter(X[50:100, 0], X[50:100, 1],color='blue', marker='x', label='versicolor') # 中间50个样本的散点图plt.scatter(X[100:, 0], X[100:, 1],color='green', marker='+', label='Virginica') # 后50个样本的散点图plt.xlabel('petal length')plt.ylabel('sepal length')plt.legend(loc=2) # 把说明放在左上角,具体请参考官方文档plt.show()

示例代码如下:

运行结果如下:

Accuracy: 0.90 (+/- 0.05) [Logistic Regression]

Accuracy: 0.93 (+/- 0.05) [Random Forest]

Accuracy: 0.91 (+/- 0.04) [naive Bayes]

Accuracy: 0.95 (+/- 0.05) [Ensemble]

 7c16525fe936a0a42105a5722f687cb0.png

示例代码如下:

from sklearn import datasetsfrom sklearn import cross_validationfrom sklearn.linear_model import LogisticRegressionfrom sklearn.naive_bayes import GaussianNBfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.ensemble import VotingClassifieriris = datasets.load_iris()X, y = iris.data[:, 1:3], iris.targetclf1 = LogisticRegression(random_state=1)clf2 = RandomForestClassifier(random_state=1)clf3 = GaussianNB()eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard', weights=[2,1,2])for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):    scores = cross_validation.cross_val_score(clf, X, y, cv=5, scoring='accuracy')    print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std

运行结果如下:Accuracy: 0.90 (+/- 0.05) [Logistic Regression]Accuracy: 0.93 (+/- 0.05) [Random Forest]Accuracy: 0.91 (+/- 0.04) [naive Bayes]Accuracy: 0.95 (+/- 0.05) [Ensemble]

2.2多数投票分类(MajorityVote Class)

相对于多数投票(hard voting),软投票返回预测概率值的总和最大的标签。可通过参数weights指定每个分类器的权重;若权重提供了,在计算时则会按照权重计算,然后取平均;标签则为概率最高的标签。

举例说明,假设有3个分类器,3个类,每个分类器的权重为:w1=1,w2=1,w3=1。如下表:

489634442bf3fb0383d6727f6398381a.png

下面例子为线性SVM,决策树,K邻近分类器:

from sklearn import datasets  from sklearn.tree import DecisionTreeClassifier  from sklearn.neighbors import KNeighborsClassifier  from sklearn.svm import SVC  from itertools import product  from sklearn.ensemble import VotingClassifier  #Loading some example data  iris = datasets.load_iris()  X = iris.data[:, [0,2]]  y = iris.target  #Training classifiers  clf1 = DecisionTreeClassifier(max_depth=4)  clf2 = KNeighborsClassifier(n_neighbors=7)  clf3 = SVC(kernel='rbf', probability=True)  eclf = VotingClassifier(estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)], voting='soft', weights=[2,1,2])  clf1 = clf1.fit(X,y)  clf2 = clf2.fit(X,y)  clf3 = clf3.fit(X,y)  eclf = eclf.fit(X,y)##这些分类器分类结果x_min,x_max = X[:,0].min()-1,X[:,0].max()+1  y_min,y_max = X[:,1].min()-1,X[:,1].max()+1  xx,yy = np.meshgrid(np.arange(x_min,x_max,0.1),                      np.arange(y_min,y_max,0.1))  f, axarr = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(10, 8))  for idx, clf, tt in zip(product([0, 1], [0, 1]),                          [clf1, clf2, clf3, eclf],                          ['Decision Tree (depth=4)', 'KNN (k=7)',                           'Kernel SVM', 'Soft Voting']):      Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])      Z = Z.reshape(xx.shape)      axarr[idx[0], idx[1]].contourf(xx, yy, Z, alpha=0.4)      axarr[idx[0], idx[1]].scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)      axarr[idx[0], idx[1]].set_title(tt)  plt.show()

de67e07b08d13d016f0694ea43acc921.png

3自适应分类器(Adaboost)

Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。其算法本身是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。使用adaboost分类器可以排除一些不必要的训练数据特征,并放在关键的训练数据上面。

下面的例子展示了AdaBoost算法拟合100个弱学习器

from sklearn.model_selection import cross_val_score  from sklearn.datasets import load_iris  from sklearn.ensemble import AdaBoostClassifier  iris = load_iris()  clf = AdaBoostClassifier(n_estimators=100)  scores = cross_val_score(clf, iris.data, iris.target)

输出结果为:0.95996732026143794

4822ef030c0b64ab33b5be6928a3c23b.png

    58e3876ca3e6a0d582e1d2c28c6e73b0.gif

点个再看,鼓励下吧

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值