「这是我参与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加了分层能升级,你知道嘛?
参考资料