我们开发一个预测模型的目的是为了运用这个模型对未知数据进行预测。通过本教程,你将学会如何使用python来评估你的梯度提升模型XGBoost的模型性能。完成本教程你将知道:
- 如何使用训练集和测试集来评估你的XGBoost模型的性能。
- 如何使用K折交叉验证来评估你的XGBoost模型的性能。
一、运用训练集和测试集来评估XGBoost模型的性能
我们可以用来评估机器学习算法性能的最简单的方法就是使用不同的训练集和测试集。
我们可以将我们的原始数据集拆分为两个部分,第一部分用来训练模型,第二部分用来进行预测,并对预测的结果进行评估。
如果对原始数据集进行分割这取决于数据集的大小和数据集的一些细节,通常使用67%的数据用于训练,其余33%用于测试。
这种算法评估的技术是快速的。对于大量的数据集(数百万条记录)来说,这是非常理想的。由于速度的原因,当你正在研究的算法训练缓慢时,使用这种方法是很有用的。
这种技术的缺点是它可能具有很高的方差。这就意味着训练集和测试集的差异会导致模型的准确率相差较大。
在周志华老师的《机器学习》中对偏差和方差做了如下定义:
- 偏差:度量学习算法的期望预测与真实结果的偏离程度,也叫拟合能力。
- 方差:度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动造成的影响。
我们可以使用scikit-learn
库中的train_test_split()
函数将数据集拆分为训练集和测试集。比如:我们可以通过该函数通过如下命令将数据集拆分为67%作为训练集,33%作为测试集:
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=7)
二、运用K折交叉验证评估XGBoost模型的性能
运用交叉验证的方法来评估模型性能比起运用单次训练集和测试集拆分的方法具有更小的方差。
它通过将数据集拆分为k个部分(例如:k=5或k=10)数据集的每个分割被称为折,算法在k-1折上进行训练,在剩下的那一折上进行测试,通过重复,使得每一折都有机会作为测试集。
运行交叉验证后,你将得到k个不同的表现分数,你可以获取这些分数分平均值和标准差来衡量模型的性能。
通过这种方法对算法进行评估更加可靠,因为算法在不同的数据上记性了多次的训练和评估。
我们可以使用scikit-learn
提供的k折交叉验证方法。·scikit-learn·的cross_val_score()
函数允许我们使用交叉验证方案来评估一个模型,并返回包含k个得分的列表。
对于预测类别有多类或者类别不平衡的预测问题(一个类,比另一个类多很多)那么我们使用分层的k折交叉交叉验证是个不错的方法。这种交叉验证使得每次划分的数据集类别比例保持和原始数据集类别比例大致相同。
scikit-learn
库在StratifiedKFold
类中提供了这个功能。
三、实例
这里我们需要用到UCI中的皮马印第安人糖尿病发病情况数据集。
数据集介绍:
皮马印第安人糖尿病发病情况数据集介绍:
该数据集描述了768名pima印第安人的患病医疗记录数据,以及他们在五年内是否发生糖尿病。描述每个患者的输入变量是数值的,具有不同的比例。
数据集的每一列代表的意义如下所示:
1、'No_pregnant':怀孕次数
2、'Plasma_glucose':2小时口服葡萄糖耐量试验中血浆葡萄糖浓度
3、'Diastolic Blood_pres':舒张压
4、'Skin_thick':肱三头肌皮皱褶厚度
5、'Serum_insu':2小时血清胰岛素浓度
6、'BMI(body mass index:(重量/身高^2))’:身体质量指数
7、'Diabetes_func' :糖尿病谱系功能
8、'Age' :年龄
9、'Class':是否5年后患糖尿病,如果患则标签为1,如果否则标签为0.
部分数据集展示:
实验过程:
1、加载数据集,查看是否具有缺失值
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 27 15:24:16 2017
@author: Amica
"""
import pandas as pd
#加载糖尿病数据集,原始数据集中没有列名,通过names给数据集添加上列名
data=pd.read_csv("data.csv",names=["怀孕次数","葡萄糖浓度","舒张压",
"皱褶厚度","胰岛素浓度","身体质量指数",
"糖尿病谱系功能","年龄","5年后是否患病"])
#定义函数用于统计数据集缺失值情况
def na_data(data):
# (1)统计每个特征缺失值的个数并按降序排序
NaN_count = data.isnull().sum().sort_values(ascending=False)
# (2)计算每个特征中缺失值所占的比率
NaN_rate = (NaN_count / len(data))
# 将每个特征的缺失值个数和缺失率连接起来
NaN_data = pd.concat([NaN_count, NaN_rate], axis=1, keys=['count', 'ratio'])
print("数据集缺失值的统计情况:")
return NaN_data
na_data(data)
运行结果:
2、通过train_test_split拆分训练集和测试集并评估模型性能
#从xgboost中导入XGBClassifier
from xgboost import XGBClassifier
from xgboost import plot_importance
#导入train_test_split用于拆分数据集
from sklearn.model_selection import train_test_split
#导入accuracy_score用于评估模型的准确率
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
#将数据集的特征和标签分离
X = data.values[:,0:8]
Y = data.values[:,8]
#按照所给比例拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33, random_state=0)
#在训练集上训练模型
model = XGBClassifier()
model.fit(X_train, y_train)
# 通过训练的模型对测试集进行预测
y_pred = model.predict(X_test)
#由于model.predict(X_test)得到的是模型数据正例的概率,所以通过round将结果转换为类别标签
predictions = [round(value) for value in y_pred]
# 对预测结果进行评估
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
plot_importance(model)
plt.show()
运行结果:
3、通过KFold交叉验证评估模型性能
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
kfold=KFold(n_splits=10,random_state=7)
results=cross_val_score(model,X,Y,cv=kfold)
print("Accuracy: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
x=range(1,11)
plt.plot(x,results)
plt.show()
运行结果:
4、通过分层的交叉验证评估模型性能
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score
kfold = StratifiedKFold(n_splits=10, random_state=7)
results = cross_val_score(model, X, Y, cv=kfold)
print("Accuracy: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
x=range(1,11)
plt.plot(x,results)
plt.show()
运行结果:
参考资料:评估模型性能