让我看看是谁还不会交叉验证?

331 阅读4分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

详细代码可见👉gitee.com/xin-yue-qin…,有问题欢迎随时指教~🔎

交叉验证

在机器学习建模过程中,通常的做法通常是将数据分为训练集和测试集。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。在训练过程中,经常会出现过拟合的问题。

过拟合问题就是模型可以很好的匹配训练数据,却不能很好在预测训练集外的数据。

交叉验证的基本思想是在训练数据再中分出一部分做为验证(Validation)数据,用来评估模型的训练效果。

验证数据从训练数据中获取,但不参与训练,这样可以相对客观的评估模型对于训练集之外数据的匹配程度。

模型的评价指标(recall、precision、f1值)你记得不?🤔

使用交叉验证主要是看那些指标怎么样,为了保证指标具有说服力,避免偶然性

交叉验证优点:

  • 交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减小过拟合。
  • 可以从有限的数据中获取尽可能多的有效信息。

一般我们在模型训练过程中,会采用K折交叉验证的方法来验证模型的表现,从而进行调参

K-Fold 交叉验证

将原始数据分成K组,将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型。这K个模型分别在验证集中评估结果,最后的均方误差MSE加和平均就得到交叉验证误差。

何时使用K-Fold🤔? 数据总量较小时,其他方法无法继续提升性能,可以尝试K-Fold。其他情况就不太建议了,例如数据量很大,就没必要更多训练数据,同时训练成本也要扩大K倍(主要指的训练时间)。

上手

说那么多,到底交叉验证怎么用起来?

这就来了~

老规矩,你可以永远相信万能的sklearn,这次想交叉验证我们照样直接引用其中的函数:👇

一般我们会用到sklearn.model_selection.cross_val_score 方法来计算模型的得分

sklearn.cross_validation.cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)
  • estimator:数据对象

  • X:数据特征(Features)

  • y:数据标签(Labels)

  • scoring:调用的方法,包括accuracy和mean_squared_error等,默认正类是数据集中标签为1的那类

  • cv:几折交叉验证

  • n_jobs:同时工作的cpu个数(-1代表全部)

  • verbose:详细程度

  • fit_params:传递给估计器的拟合方法的参数

  • pre_dispatch:控制并行执行期间调度的作业数量。减少这个数量对于避免在CPU发送更多作业时CPU内存消耗的扩大是有用的。该参数可以是:

    • 没有,在这种情况下,所有的工作立即创建并产生。将其用于轻量级和快速运行的作业,以避免由于按需产生作业而导致延迟
    • 一个int,给出所产生的总工作的确切数量
    • 一个字符串,给出一个表达式作为n_jobs的函数,如'2 * n_jobs'

返回:交叉验证每次运行的评分数组

机器学习实战的demo该如何简单用?

from sklearn.metrics import classification_report 
from sklearn.model_selection import train_test_split, cross_val_score
import xgboost
from imblearn.over_sampling import SMOTE
​
# 取数据
csv_df = pd.read_csv('data/abalone.csv')
​
# 设置列名
csv_df.columns= ['Sex', 'Length', 'Diameter', 'Height', 'Whole weight','Shucked weight', 'Viscera weight', 'Shell weight', 'result']
df = pd.DataFrame(csv_df)
​
​
# 对lable进行硬编码(factorize),对性别变量进行one-hot编码(dummies)
label = pd.DataFrame({'label': pd.factorize(df['result'])[0]})  # 用字典指定列名
dummies = pd.get_dummies(df.drop(columns=['result']))
​
data = pd.concat([dummies, label], axis=1)  # 行拼接X = data.drop(columns=["label"]) #删除label列
Y = data["label"]  #label列
​
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=10)
​
smo = SMOTE(random_state=20)
x_train, y_train = smo.fit_resample(x_train, y_train)
​
Xgb = xgboost.XGBClassifier().fit(x_train, y_train)
print(classification_report(y_test, Xgb.predict(x_test)))
​
scores = cross_val_score(Xgb, X, Y, cv=5).mean()
print("scores:",scores)

两句关键代码(引入库+应用),很牛逼很好用,你值得拥有~

详细代码可见👉gitee.com/xin-yue-qin…

写在后面

kfold是将数据集划分为K-折,只是划分数据集;

cross_val_score是根据模型进行计算,计算交叉验证的结果,你可以简单认为就是cross_val_score中调用了kfold进行数据集划分。

欢迎随时指导~

想看分层交叉验证吗?戳👉 K-Fold加了分层能升级,你知道嘛?

参考资料

k折交叉验证sklearn中的StratifiedKFold---turbo624

cross_val_score的 scoring参数值解析---瓜而不皮