实现跨验证的离线学习模型时遇到问题?

我在进行文本分类工作,在特征提取步骤之后得到了非常好的矩阵,因此我尝试使用增量学习如下所示:

import xgboost as xgbfrom sklearn.model_selection import ShuffleSplit, train_test_splitfrom sklearn.metrics import accuracy_score as accdef incremental_learning2(X, y):    # 将数据分割为训练集和测试集    # 然后将训练集分成两半    X_train, X_test, y_train, y_test = train_test_split(X,                                                        y, test_size=0.1,                                                        random_state=0)    X_train_1, X_train_2, y_train_1, y_train_2 = train_test_split(X_train,                                                      y_train,                                                      test_size=0.5,                                                     random_state=0)    xg_train_1 = xgb.DMatrix(X_train_1, label=y_train_1)    xg_train_2 = xgb.DMatrix(X_train_2, label=y_train_2)    xg_test = xgb.DMatrix(X_test, label=y_test)    #params = {'objective': 'reg:linear', 'verbose': False}    params = {}    model_1 = xgb.train(params, xg_train_1, 30)    model_1.save_model('model_1.model')    # ================= 训练模型的两个版本 =====================#    model_2_v1 = xgb.train(params, xg_train_2, 30)    model_2_v2 = xgb.train(params, xg_train_2, 30, xgb_model='model_1.model')    #预测    y_pred = model_2_v2.predict(X_test)    kfold = StratifiedKFold(n_splits=10, random_state=1).split(X_train, y_train)    scores = []    for k, (train, test) in enumerate(kfold):        model_2_v2.fit(X_train[train], y_train[train])        score = model_2_v2.score(X_train[test], y_train[test])        scores.append(score)        print('Fold: %s, Class dist.: %s, Acc: %.3f' % (k+1, np.bincount(y_train[train]), score))    print('\nCV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores)))

关于上述代码。我尝试进行交叉验证并预测一些实例。然而,它不起作用。我该如何修复上述代码,以便在非常大的数据集上拟合和更新GBM模型后获得交叉验证的指标和预测?


回答:

这是我想到的解决方案。首先我们导入必要的模块并定义一个简单的函数来计算均方根误差:

import numpy as npimport xgboost as xgbfrom sklearn.model_selection import train_test_split as ttsfrom sklearn.model_selection import StratifiedKFolddef rmse(a, b):    return np.sqrt(((a - b) ** 2).mean())

均方根误差可以以不同的方式计算(查看此线程以获取详细信息),但为了清晰起见,我选择了一个明确的公式。

这是您的函数的一个快速且粗糙的版本。我尝试保持您的代码结构不变,但为了可读性,我进行了一些重构。

def incremental_learning2(X, y, n_splits=10, params = {}):        # 初始化分数数组    sc_1, sc_2_v1, sc_2_v2 = (np.zeros(n_splits) for i in range(3))    # 创建交叉验证器    kfold = StratifiedKFold(n_splits=n_splits, random_state=0).split(X, y)    # 迭代折叠    for k, (train, test) in enumerate(kfold):        # 分割数据        X_test, y_test = X[test], y[test]            splits = tts(X[train], y[train], test_size=0.5, random_state=0)        X_train_1, X_train_2, y_train_1, y_train_2 = splits        # 创建数据矩阵        xg_train_1 = xgb.DMatrix(X_train_1, label=y_train_1)        xg_train_2 = xgb.DMatrix(X_train_2, label=y_train_2)        xg_test = xgb.DMatrix(X_test, label=y_test)            # 拟合模型        model_1 = xgb.train(params, xg_train_1, 30)                model_1.save_model('model_1.model')        model_2_v1 = xgb.train(params, xg_train_2, 30)        model_2_v2 = xgb.train(params, xg_train_2, 30, xgb_model='model_1.model')        # 进行预测和计算分数        preds = (m.predict(xg_test) for m in [model_1, model_2_v1, model_2_v2])        sc_1[k], sc_2_v1[k], sc_2_v2[k] = (rmse(p, y_test) for p in preds)    # 返回分数    return sc_1, sc_2_v1, sc_2_v2

我还改进了输出格式,以表格形式显示结果。此功能在单独的函数中实现:

def display_results(a, b, c):    def hline():         print('-'*50)    print('交叉验证均方根误差\n')        print('折叠\tmodel_v1\tmodel_2_v1\tmodel_2_v2')    hline()    for k, (ak, bk, ck) in enumerate(zip(a, b, c)):        print('%s\t%.3f\t\t%.3f\t\t%.3f' % (k+1, ak, bk, ck))            hline()    print('平均\t%.3f\t\t%.3f\t\t%.3f' % tuple(np.mean(s) for s in [a, b, c]))    print('标准差\t%.3f\t\t%.3f\t\t%.3f' % tuple(np.std(s) for s in [a, b, c]))

演示

由于您没有分享您的数据集,我不得不生成模拟数据来测试我的代码。

from sklearn.datasets import make_blobsX, y = make_blobs(n_samples=500000, centers=50, random_state=0)scores_1, scores_2_v1, scores2_v2 = incremental_learning2(X, y)display_results(scores_1, scores_2_v1, scores2_v2)

上述代码运行无误,输出如下所示:

交叉验证均方根误差折叠    model_v1        model_2_v1      model_2_v2--------------------------------------------------1       9.127           9.136           9.1162       9.168           9.155           9.1283       9.117           9.095           9.0804       9.107           9.113           9.0895       9.122           9.126           9.1096       9.096           9.099           9.0847       9.148           9.163           9.1458       9.089           9.090           9.0699       9.128           9.122           9.10810      9.185           9.162           9.160--------------------------------------------------平均    9.129           9.126           9.109标准差 0.029           0.026           0.028

备注

  • 为了比较目的,我也对model_1进行了交叉验证。
  • 在示例运行中,model_1model_2_v1的准确性大致相同,而model_2_v2表现得稍好,正如人们合理预期的那样。
  • 我尝试了不同的大数据集大小(n_samples)和类别数(centers),有趣的是,当这些参数的值降低时,model_2_v2是三者中准确性最低的。
  • 希望通过使用不同的配置,即正确设置命名的函数参数params,应该可以使事情按预期进行。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注