使用Scikit-learn构建集成学习模型
集成学习使用多个机器学习模型来尝试对数据集进行更好的预测。集成模型通过在数据集上训练不同机器学习模型并使每个模型单独进行预测来工作。这些模型的预测随后进行组合以做出最终预测。
每个模型都有自己的优点和缺点。通过组合各个模型来帮助隐藏单个模型的弱点。
在本教程中,我们将使用一个投票分类器,其中集成模型通过多数投票进行预测。例如,如果我们使用三个模型并且他们预测目标变量的[1,0,1],则集成模型将做出的最终预测将是1,因为三个模型中的两个预测为1。
我们将使用三个不同的模型放到我们的投票分类器:k-最近邻,随机森林和逻辑回归。我们将使用Python中的Scikit-learn库来实现这些方法,并在我们的示例中使用diabetes数据集。
注意:集成模型也可用于回归问题,其中集成模型将使用不同模型的平均输出或最终预测的加权平均值。
读取训练数据
第一步是读入我们将用作输入的数据。对于此示例,我们使用diabetes数据集(http://www.kankanyun.com/data/diabetes_data.csv)。首先,我们将使用Pandas库来读取数据。
import pandas as pd #read in the dataset df = pd.read_csv('data/diabetes_data.csv') #take a look at the data df.head()
接下来,让我们看看我们有多少数据。我们将在dataframe 上调用'shape'函数,以查看数据中有多少行和列。行指示患者的数量,列指示每个患者的数据集中的特征的数量(年龄,体重等)。
#check dataset size df.shape
将数据集拆分为输入和目标
现在让我们将数据集拆分为输入(X)和目标(y)。我们的输入将是除“diabetes”之外的每一栏,因为“diabetes”是我们将试图预测的。因此,'diabetes'将成为我们的目标。
我们将使用pandas'drop'函数从我们的dataframe 中删除“diabetes”列,并将其存储在变量“X”中。
#split data into inputs and targets X = df.drop(columns = ['diabetes']) y = df['diabetes']
将数据集拆分为训练和测试数据
现在我们将数据集分成训练数据和测试数据。训练数据是模型将从中学习的数据。测试数据是我们将用于查看模型在看不见的数据上的表现的数据。
Scikit-learn有一个我们可以使用的函数叫做“train_test_split”,这使我们可以很容易地将数据集分成训练和测试数据。
from sklearn.model_selection import train_test_split #split data into train and test sets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y)
'train_test_split'包含5个参数。前两个参数是我们之前拆分的输入和目标数据。接下来,我们将'test_size'设置为0.3。这意味着所有数据的30%将用于测试,这使得70%的数据作为机器学习模型的训练数据来学习。
将'stratify'设置为y使我们的训练拆分代表y变量中每个值的比例。例如,在我们的数据集中,如果25%的患者患有糖尿病,75%的患者没有糖尿病,那么将“分层”设置为y将确保随机分组有25%的糖尿病患者和75%的非糖尿病患者。
建立机器学习模型
接下来,我们必须构建我们的机器学习模型。我们构建的每个模型都有一组我们可以调整的超参数。调整参数是指您经历一个过程以找到模型的最佳参数以提高准确性。我们将使用网格搜索来查找每个模型的最佳超参数。
网格搜索通过在我们指定的一系列参数上多次训练模型来工作。这样,我们可以使用每个超参数值测试我们的模型,并找出最佳值以获得最佳精度结果。
k-最近邻(k-NN)
我们将构建的第一个模型是k-Nearest Neighbors(k-NN)。k-NN模型通过获取数据点并查看“k”最接近的标记数据点来工作。然后为数据点分配大多数“k”个最近点的标签。
例如,如果k = 5,并且3个点为“绿色”而2个为“红色”,则所讨论的数据点将标记为“绿色”,因为“绿色”占多数。
Python代码:
import numpy as np from sklearn.model_selection import GridSearchCV from sklearn.neighbors import KNeighborsClassifier #create new a knn model knn = KNeighborsClassifier() #create a dictionary of all values we want to test for n_neighbors params_knn = {‘n_neighbors’: np.arange(1, 25)} #use gridsearch to test all values for n_neighbors knn_gs = GridSearchCV(knn, params_knn, cv=5) #fit model to training data knn_gs.fit(X_train, y_train)
首先,我们将创建一个新的k-NN分类器。接下来,我们需要创建一个字典来存储我们将为'n_neighbors'测试的所有值,这是我们需要调整的超参数。我们将为'n_neighbors'测试24个不同的值。然后我们将创建我们的网格搜索,输入我们的k-NN分类器,我们的超参数集和交叉验证值。
交叉验证是指将数据集随机拆分为“k”组。其中一组用作测试集,其余组用作训练集。该模型在训练集上训练并在测试集上评分。然后重复该过程,直到每个唯一组用作测试集。
在我们的例子中,我们使用5-fold交叉验证。数据集分为5组,模型经过5次单独的训练和测试,因此每组都有机会成为测试集。这就是我们如何使用每个超参数值对我们的模型进行评分,以查看“n_neighbors”的哪个值为我们提供了最佳分数。
然后我们将使用'fit'函数来运行我们的网格搜索。
现在我们将使用'best_estimator_'函数将我们最好的k-NN模型保存到'knn_best',并检查'n_neighbors'的最佳值是什么。
#save best model knn_best = knn_gs.best_estimator_ #check best n_neigbors value print(knn_gs.best_params_)
随机森林
我们将构建的下一个模型是随机森林。随机森林本身被认为是一个集成模型,因为它是决策树的集合,组合起来制作更准确的模型。
Python代码如下:
from sklearn.ensemble import RandomForestClassifier #create a new rf classifier rf = RandomForestClassifier() #create a dictionary of all values we want to test for n_estimators params_rf = {'n_estimators': [50, 100, 200]} #use gridsearch to test all values for n_estimators rf_gs = GridSearchCV(rf, params_rf, cv=5) #fit model to training data rf_gs.fit(X_train, y_train)
我们将创建一个随机森林分类器并设置我们想要调整的超参数。'n_estimators'是我们随机森林中树的数量。然后我们可以运行网格搜索来找到最佳树数。
就像以前一样,我们将保存最好的模型并打印最好的'n_estimators'值。
#save best model rf_best = rf_gs.best_estimator_ #check best n_estimators value print(rf_gs.best_params_)
Logistic回归
我们的最后一个模型是逻辑回归。即使它的名称中有“回归”,逻辑回归也是一种分类方法。这个更简单,因为我们不会调整任何超参数。我们只需要创建和训练模型。
from sklearn.linear_model import LogisticRegression #create a new logistic regression model log_reg = LogisticRegression() #fit the model to the training data log_reg.fit(X_train, y_train)
现在让我们在测试数据上检查所有三个模型的准确度分数。
#test the three models with the test data and print their accuracy scores print('knn: {}'.format(knn_best.score(X_test, y_test))) print('rf: {}'.format(rf_best.score(X_test, y_test))) print('log_reg: {}'.format(log_reg.score(X_test, y_test)))
从输出中可以看出,逻辑回归是三者中最准确的。
投票分类器
现在我们已经构建了三个单独的机器学习模型,现在是时候构建我们的投票分类器了。
Python实现如下:
from sklearn.ensemble import VotingClassifier #create a dictionary of our models estimators=[('knn', knn_best), ('rf', rf_best), ('log_reg', log_reg)] #create our voting classifier, inputting our models ensemble = VotingClassifier(estimators, voting='hard')
首先,让我们将三个模型放在一个名为“estimators”的数组中。接下来,我们将创建我们的投票分类器。它需要两个输入。第一个是我们的三个模型的estimators array 。我们将投票参数设置为hard,这告诉我们的分类器通过多数投票来做出预测。
现在我们可以将我们的集成模型与我们的训练数据相匹配,并在我们的测试数据上进行评分。
#fit model to training data ensemble.fit(X_train, y_train) #test our model on the test data ensemble.score(X_test, y_test)
我们的集成模型比我们的单个k-NN,随机森林和逻辑回归模型表现更好!
您现在已经构建了一个整体模型来组合各个模型!