Python机器学习:通过scikit-learn实现集成算法

简介:

有时提高机器学习算法的准确度很困难,本文将通过scikit-learn介绍三种提高算法准确度的集成算法。本文选自《机器学习——Python实践》一书。



在现实生活中,常常采用集体智慧来解决问题。那么在机器学习中,能否将多种机器学习算法组合在一起,使计算出来的结果更好呢?这就是集成算法的思想。集成算法是提高算法准确度的有效方法之一,本文将会介绍以下几种算法:

装袋(Bagging)算法。

提升(Boosting)算法。

投票(Voting)算法。

scikit-learn是Python中开发和实践机器学习的著名类库之一,依赖于SciPy及其相关类库来运行。scikit-learn的基本功能主要分为六大部分:分类、回归、聚类、数据降维、模型选择和数据预处理。需要指出的是,由于scikit-learn本身不支持深度学习,也不支持GPU加速,因此scikit-learn对于多层感知器(MLP)神经网络的实现并不适合处理大规模问题。(scikit-learn对MLP的支持在0.18版之后增加)

scikit-learn是一个开源项目,遵守BSD协议,可以将项目应用于商业开发。目前主要由社区成员自发进行维护。可能是由于维护成本的限制,scikit-learn相比其他项目要显得更为保守,这主要体现在两个方面:

scikit-learn从来不做除机器学习领域之外的其他扩展。

scikit-learn从来不采用未经广泛验证的算法。

1 集成的方法

下面是三种流行的集成算法的方法。

装袋(Bagging)算法:先将训练集分离成多个子集,然后通过各个子集训练多个模型。

提升(Boosting)算法:训练多个模型并组成一个序列,序列中的每一个模型都会修正前一个模型的错误。

投票(Voting)算法:训练多个模型,并采用样本统计来提高模型的准确度。

本文只简单地介绍一下相关的集成算法。在这里采用Pima Indians数据集,并用10折交叉验证来分离数据,再通过相应的评估矩阵来评估算法模型。

2 装袋算法

装袋算法是一种提高分类准确率的算法,通过给定组合投票的方式获得最优解。比如你生病了,去n个医院看了n个医生,每个医生都给你开了药方,最后哪个药方的出现次数多,就说明这个药方越有可能是最优解,这很好理解,这也是装袋算法的思想。下面将介绍三种装袋模型:

装袋决策树(Bagged Decision Trees)。

随机森林(Random Forest)。

极端随机树(Extra Trees)。

2.1 装袋决策树

装袋算法在数据具有很大的方差时非常有效,最常见的例子就是决策树的装袋算法。下面将在scikit-learn中通过BaggingClassifier实现分类与回归树算法。本例中创建了100棵决策树,代码如下:

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
cart = DecisionTreeClassifier()
num_tree = 100
model = BaggingClassifier(base_estimator=cart, n_estimators=num_tree, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print(result.mean())

与第12章的分类与回归树的结果(0.701708817498)比较,发现结果有了很大的提升。执行结果如下:

0.770745044429

2.2 随机森林

顾名思义,随机森林是用随机的方式建立一个森林,森林由很多的决策树组成,而且每一棵决策树之间是没有关联的。得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行判断,看看这个样本应该属于哪一类,再看看哪一类被选择最多,就预测这个样本为哪一类。

在建立每一棵决策树的过程中,有两点需要注意:采样与完全分裂。首先是两个随机采样的过程,随机森林对输入的数据要进行行、列的采样。对于行采样采用有放回的方式,也就是在采样得到的样本集合中可能有重复的样本。假设输入样本为N个,那么采样的样本也为N个。这样在训练的时候,每一棵树的输入样本都不是全部的样本,就相对不容易出现过拟合。然后进行列采样,从M个feature中选出m个(m << M)。之后再对采样之后的数据使用完全分裂的方式建立决策树,这样决策树的某一个叶子节点要么是无法继续分裂的,要么所有样本都指向同一个分类。一般很多的决策树算法都有一个重要的步骤——剪枝,但是这里不这么做,因为之前的两个随机采样过程保证了随机性,所以不剪枝也不会出现过拟合。

这种算法得到的随机森林中的每一棵决策树都是很弱的,但是将它们组合起来就会很厉害了。我觉得可以这样比喻随机森林算法:每一棵决策树就是一个精通某一个领域的专家,这样在随机森林中就有了很多个精通不同领域的专家,对于一个新的问题(新的输入数据),可以从不同的角度去看待它,最终由各个专家投票得到结果。

这种算法在scikit-learn中的实现类是RandomForestClassifier。下面的例子是实现了100棵树的随机森林。代码如下:

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
num_tree = 100
max_features = 3
model = RandomForestClassifier(n_estimators=num_tree, random_state=seed, max_features=max_features)
result = cross_val_score(model, X, Y, cv=kfold)
print(result.mean())

执行结果如下:

0.77337662337

2.3 极端随机树

极端随机树是由PierreGeurts等人于2006年提出的,它与随机森林十分相似,都是由许多决策树构成。但它与随机森林有两个主要的区别:

(1)随机森林应用的是Bagging模型,而极端随机树是使用所有的训练样本得到每棵决策树,也就是每棵决策树应用的是相同的全部训练样本。

(2)随机森林是在一个随机子集内得到最优分叉特征属性,而极端随机树是完全随机地选择分叉特征属性,从而实现对决策树进行分叉的。

它在scikit-learn中的实现类是ExtraTreesClassifier。下面的例子是实现了100棵树和7个随机特征的极端随机树。代码如下:

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import ExtraTreesClassifier
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
num_tree = 100
max_features = 7
model = ExtraTreesClassifier(n_estimators=num_tree, random_state=seed, max_features=max_features)
result = cross_val_score(model, X, Y, cv=kfold)
print(result.mean())

执行结果如下:
0.762987012987

3 提升算法

提升算法是一种用来提高弱分类算法准确度的方法,这种方法先构造一个预测函数系列,然后以一定的方式将它们组合成一个预测函数。提升算法也是一种提高任意给定学习算法准确度的方法,它是一种集成算法,主要通过对样本集的操作获得样本子集,然后用弱分类算法在样本子集上训练生成一系列的基分类器。它可以用来提高其他弱分类算法的识别率,也就是将其他的弱分类算法作为基分类算法放于提升框架中,通过提升框架对训练样本集的操作,得到不同的训练样本子集,再用该样本子集去训练生成基分类器。每得到一个样本集就用该基分类算法在该样本集上产生一个基分类器,这样在给定训练轮数n后,就可产生n个基分类器,然后提升算法将这n个基分类器进行加权融合,产生最后的结果分类器。在这n个基分类器中,每个分类器的识别率不一定很高,但它们联合后的结果有很高的识别率,这样便提高了弱分类算法的识别率。下面是两个非常常见的用于机器学习的提升算法:

AdaBoost。

随机梯度提升(Stochastic Gradient Boosting)。

3.1 AdaBoost

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

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import AdaBoostClassifie
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
num_tree = 30
model = AdaBoostClassifier(n_estimators=num_tree, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print(result.mean())

执行结果如下:
0.76045796309

3.2 随机梯度提升

随机梯度提升法(GBM)基于的思想是:要找到某个函数的最大值,最好的办法就是沿着该函数的梯度方向探寻。梯度算子总是指向函数值增长最快的方向。由于梯度提升算法在每次更新数据集时都需要遍历整个数据集,计算复杂度较高,于是有了一个改进算法——随机梯度提升算法,该算法一次只用一个样本点来更新回归系数,极大地改善了算法的计算复杂度。在scikit-learn中的实现类是GradientBoostingClassifier。代码如下:

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import GradientBoostingClassifier
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
num_tree = 100
model = GradientBoostingClassifier(n_estimators=num_tree, random_state=seed)
result = cross_val_score(model, X, Y, cv=kfold)
print(result.mean())

执行结果如下:

0.766900205058

4 投票算法

投票算法(Voting)是一个非常简单的多个机器学习算法的集成算法。投票算法是通过创建两个或多个算法模型,利用投票算法将这些算法包装起来,计算各个子模型的平均预测状况。在实际的应用中,可以对每个子模型的预测结果增加权重,以提高算法的准确度。但是,在scikit-learn中不提供加权算法。下面通过一个例子来展示在scikit-learn中如何实现一个投票算法。在scikit-learn中的实现类是VotingClassifier。代码如下:

from pandas import read_csv
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import VotingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
# 导入数据
filename = 'pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)
# 将数据分为输入数据和输出结果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
num_folds = 10
seed = 7
kfold = KFold(n_splits=num_folds, random_state=seed)
cart = DecisionTreeClassifier()
models = []
model_logistic = LogisticRegression()
models.append(('logistic', model_logistic))
model_cart = DecisionTreeClassifier()
models.append(('cart', model_cart))
model_svc = SVC()
models.append(('svm', model_svc))
ensemble_model = VotingClassifier(estimators=models)
result = cross_val_score(ensemble_model, X, Y, cv=kfold)
print(result.mean())

执行结果如下:

0.732997265892

相关文章
|
1月前
|
机器学习/深度学习 数据采集 数据挖掘
实战派教学:掌握Scikit-learn,轻松实现数据分析与机器学习模型优化!
【10月更文挑战第4天】Scikit-learn凭借高效、易用及全面性成为数据科学领域的首选工具,简化了数据预处理、模型训练与评估流程,并提供丰富算法库。本文通过实战教学,详细介绍Scikit-learn的基础入门、数据预处理、模型选择与训练、评估及调优等关键步骤,助你快速掌握并优化数据分析与机器学习模型。从环境搭建到参数调优,每一步都配有示例代码,便于理解和实践。
80 2
|
7天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
18 3
|
12天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
机器学习基础:使用Python和Scikit-learn入门
23 1
|
23天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
【10月更文挑战第12天】本文介绍了如何使用Python和Scikit-learn进行机器学习的基础知识和入门实践。首先概述了机器学习的基本概念,包括监督学习、无监督学习和强化学习。接着详细讲解了Python和Scikit-learn的安装、数据处理、模型训练和评估等步骤,并提供了代码示例。通过本文,读者可以掌握机器学习的基本流程,并为深入学习打下坚实基础。
18 1
|
25天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
本文介绍了如何使用Python和Scikit-learn进行机器学习的基础知识和实践。首先概述了机器学习的基本概念,包括监督学习、无监督学习和强化学习。接着详细讲解了Python和Scikit-learn的安装、数据处理、模型选择与训练、模型评估及交叉验证等关键步骤。通过本文,初学者可以快速上手并掌握机器学习的基本技能。
46 2
|
25天前
|
机器学习/深度学习 数据挖掘 Serverless
手把手教你全面评估机器学习模型性能:从选择正确评价指标到使用Python与Scikit-learn进行实战演练的详细指南
【10月更文挑战第10天】评估机器学习模型性能是开发流程的关键,涉及准确性、可解释性、运行速度等多方面考量。不同任务(如分类、回归)采用不同评价指标,如准确率、F1分数、MSE等。示例代码展示了使用Scikit-learn库评估逻辑回归模型的过程,包括数据准备、模型训练、性能评估及交叉验证。
47 1
|
29天前
|
机器学习/深度学习 人工智能 数据挖掘
机器学习基础:使用Python和Scikit-learn入门
【10月更文挑战第6天】在人工智能领域,机器学习已成为核心技术。本文指导初学者使用Python与Scikit-learn入门机器学习,涵盖基本概念、环境搭建、数据处理、模型训练及评估等环节。Python因简洁性及其生态系统成为首选语言,而Scikit-learn则提供了丰富工具,简化数据挖掘与分析流程。通过实践示例,帮助读者快速掌握基础知识,为进一步深入研究奠定坚实基础。
23 4
|
1月前
|
机器学习/深度学习 算法 数据挖掘
从零到精通:Scikit-learn在手,数据分析与机器学习模型评估不再难!
【10月更文挑战第4天】在数据科学领域,模型评估是连接理论与实践的桥梁,帮助我们理解模型在未知数据上的表现。对于初学者而言,众多评估指标和工具常令人困惑。幸运的是,Scikit-learn 这一强大的 Python 库使模型评估变得简单。本文通过问答形式,带你逐步掌握 Scikit-learn 的评估技巧。Scikit-learn 提供了丰富的工具,如交叉验证、评分函数(准确率、精确率、召回率、F1 分数)、混淆矩阵和 ROC 曲线等。
34 1
|
1月前
|
机器学习/深度学习 数据采集 算法
【Python篇】从零到精通:全面分析Scikit-Learn在机器学习中的绝妙应用
【Python篇】从零到精通:全面分析Scikit-Learn在机器学习中的绝妙应用
37 2
|
2月前
|
机器学习/深度学习 算法 数据挖掘
Python数据分析革命:Scikit-learn库,让机器学习模型训练与评估变得简单高效!
在数据驱动时代,Python 以强大的生态系统成为数据科学的首选语言,而 Scikit-learn 则因简洁的 API 和广泛的支持脱颖而出。本文将指导你使用 Scikit-learn 进行机器学习模型的训练与评估。首先通过 `pip install scikit-learn` 安装库,然后利用内置数据集进行数据准备,选择合适的模型(如逻辑回归),并通过交叉验证评估其性能。最终,使用模型对新数据进行预测,简化整个流程。无论你是新手还是专家,Scikit-learn 都能助你一臂之力。
118 8