一种热编码标签和分层 K 折交叉验证

Posted

技术标签:

【中文标题】一种热编码标签和分层 K 折交叉验证【英文标题】:One Hot Encoded Labels and Stratified K-Fold Cross Validation 【发布时间】:2021-03-22 22:22:15 【问题描述】:

我正在尝试在我的 ResNet-50 模型上实施分层 K 折交叉验证。 不幸的是,当我对标签进行一次热编码并尝试使用分层 k 折叠分割我的数据时,我得到了这个错误: TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.

one-hot 编码器的实现方式如下:

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
enc.fit(Y)
Y = enc.transform(Y)
Y.toarray()

如果我不对标签进行一次性编码,则会因拟合模型而出现此错误: ValueError: Shapes (None, 1) and (None, 4) are incompatible

这是实现 Stratified K-fold 的代码:

for train, test in skf.split(X, Y):
  x = base_model.output
  x = GlobalAveragePooling2D()(x)
  x = Dropout(0.7)(x)
  predictions = Dense(num_classes, activation= 'softmax')(x)
  model = Model(inputs = base_model.input, outputs = predictions)
  adam = Adam(lr=0.0001)
  model.compile(optimizer= adam, loss='categorical_crossentropy', metrics=['accuracy'])

  # Training
  history = model.fit(X[train], Y[train], epochs = 100, batch_size = 16)

其中 num_classes = 4。

所以我的问题是:

问:如何让 one-hot 编码标签与 skf.split() 一起使用?

【问题讨论】:

【参考方案1】:

如果问题是模型不接受 sparse matrix 作为使用 OneHotEncoding 的结果(这是一般预期的行为),您可以尝试通过设置参数 sparse=False 来更改 OneHotEncoding 模型。

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(sparse=False)
enc.fit(Y)
Y = enc.transform(Y)

【讨论】:

谢谢!这回答了我的问题,但是我遇到了另一个问题。ValueError:支持的目标类型是:('binary','multiclass')。取而代之的是“多标签指示器”。似乎存在一个针对此问题的帖子link 我在你的代码中没有看到 multilabel-indicator 被定义的地方,但是如果它是一个多类问题,那么把它改成 multiclass OneHotEncoder 似乎返回了一个多标签指示符。当我将编码更改为多类时,我的 CNN 中的输出是否应该只包含 1 个节点? 不,如果您使用的是 softmax,它应该包含与类一样多的输出节点。

以上是关于一种热编码标签和分层 K 折交叉验证的主要内容,如果未能解决你的问题,请参考以下文章

如何计算分层 K 折交叉验证的不平衡数据集的误报率?

Scikit-Learn 中的分层标记 K 折交叉验证

k折交叉验证模型选择方法

机器学习--K折交叉验证和非负矩阵分解

交叉验证,K折交叉验证的偏差和方差分析

R中的分层k倍交叉验证