堆叠并不能提高准确性

数据挖掘 机器学习 Python 多类分类
2022-03-08 14:25:49

我正在尝试构建一个 2 级堆叠模型,以解决 8 个类的多类分类问题。我的基础(1 级)模型和他们在测试集中的微 f1 分数是:

  1. 随机森林分类器 (0.51)
  2. XGBoost 分类器 (0.54)
  3. LightGBM 分类器 (0.54)
  4. 逻辑回归 (0.44)
  5. keras 神经网络 (0.57)
  6. keras 神经网络 (0.56)

作为 2 级模型,我使用未调整的 XGBClassifier。我使用 7 折交叉验证来生成 2 级模型的元特征。我用来为简单分类器生成元特征的代码是:

ntrain = X_train.shape[0]
ntest = X_test.shape[0]
seed = 0 
nfolds = 7
kf = StratifiedKFold(nfolds, random_state=seed)
def get_meta(clf, Χ_train, y_train, Χ_test):
meta_train = np.zeros((ntrain,))
meta_test = np.zeros((ntest,))

for i, (train_index, test_index) in enumerate(kf.split(X_train, y_train)):
    Χ_tr = X_train.iloc[train_index]
    y_tr = y_train.iloc[train_index]
    Χ_te = Χ_train.iloc[test_index]

    clf.train(Χ_tr, y_tr)

    meta_train[test_index] = clf.predict(Χ_te)

clf.fit(X_train,y_train)
meta_test = clf.predict(X_test)
return meta_train.reshape(-1, 1), meta_test.reshape(-1, 1)

对于 keras 神经网络是:

def get_meta_keras(clf, Χ_train, y_train, Χ_test, epochs = 200, batch_size = 70, class_weight=class_weights):
meta_train = np.zeros((ntrain,))
meta_test = np.zeros((ntest,))

encoder = LabelEncoder()
encoder.fit(y_train)
encoded_Y = encoder.transform(y_train)
# convert integers to dummy variables (i.e. one hot encoded)
dummy_y = np_utils.to_categorical(encoded_Y)


for i, (train_index, test_index) in enumerate(kf.split(X_train, y_train)):
    Χ_tr = X_train.iloc[train_index]
    y_tr = dummy_y[train_index]
    Χ_te = Χ_train.iloc[test_index]

    clf.fit(Χ_tr, y_tr, epochs = epochs, batch_size = batch_size, class_weight=class_weights)

    meta_train[test_index] = clf.predict_classes(Χ_te)

clf.fit(X_train, dummy_y, epochs = epochs, batch_size = batch_size, class_weight=class_weights)
meta_test = clf.predict_classes(X_test)
return meta_train.reshape(-1, 1), meta_test.reshape(-1, 1)

我最终的 micro f1 分数是 0.54,低于我的基本模型分数。我的模型不相关(corr<0.55)。我尝试添加更简单的模型,如 knn、朴素贝叶斯等,但分数下降得更多。为什么我的堆叠方法没有提高分数?

2个回答

虽然没有提供数据,但我会尝试分享我的想法。

堆叠

我们通过使用保留数据集进行多个预测来堆叠模型,然后收集这些预测以形成一个新数据集,您可以在其中拟合一个新模型

堆叠模型(也称为 2 级模型)通常会优于每个单独的模型,因为它具有平滑特性,并且能够突出表现最佳的每个基本模型,并诋毁表现不佳的每个基本模型

模型多样性

但是堆叠中最重要的丁字裤之一是模型多样性,模型彼此之间有多么不同。您应该考虑每个模型带来的新信息是什么?

它会找出为什么你的一个模型很好,而另一个模型不好或相当弱。你不需要太担心让所有的模型真的很强大。因此,你真正需要关注的是这个模型带来了什么信息,即使它通常很弱?这样的模型带来了元模型可以利用的新信息。

通常,您从两种形式引入多样性:

  1. 通过选择不同的算法或通过 . 这是有道理的,某些算法利用数据中的不同关系。例如,线性模型会关注线性关系,非线性模型可以更好地捕捉非线性关系。所以预测可能会有点不同

  2. 运行相同的模型,但您尝试在输入数据的不同转换上运行它,要么是更少的特征,要么是完全不同的转换。例如,在一个数据集中,您可以将分类特征视为一次性编码。在另一种情况下,您可能只使用标签编码,结果可能会产生一个非常不同的模型。

所以你需要测试不同的模型。正如@Aditya 所说 - 除非你有强大的基线,否则不能保证任何一种方式的改进

我是一个喜欢简单事物的老人 :D

所以我会为 2 级模型尝试一些更基本的选项:

  • 多数投票(几乎没有比这更简单的了!)
  • 线性回归
  • 单决策树
  • 支持向量机

除了我老了,还有两个原因可以说明这些可能有用:

  • 过拟合的风险更小:如果 2 级模型太复杂,它往往会过拟合,根据我的经验,在堆叠学习器时,就 2 级的性能而言,要为此付出高昂的代价。
  • 审查:可以很容易地调查预测组合中发生的情况。