【问题标题】:Classification metrics can't handle a mix of multiclass and continuous-multioutput targets分类度量不能处理多类和连续多输出目标的混合
【发布时间】:2020-11-11 02:29:42
【问题描述】:

我正在 multiclass 数据集上运行 BERT 预训练模型,用于文本分类。由于它是多类的,我无法弄清楚如何生成classification report。我找到的解决方案是thisthis。我明白,因为它是一个多类分类,我必须 one-hot-encode test_y 值(我做了)

test_y = to_categorical(np.asarray(test_y.factorize()[0]))

但是当我这样做时

from sklearn.metrics import classification_report
print(classification_report(test_y, y_pred, digits=8))

我仍然得到这个错误:

     88     if len(y_type) > 1:
     89         raise ValueError("Classification metrics can't handle a mix of {0} "
---> 90                          "and {1} targets".format(type_true, type_pred))
     91 
     92     # We can't have more than one value on y_type => The set is no more needed

ValueError: Classification metrics can't handle a mix of multilabel-indicator and continuous-multioutput targets

为什么?

如果我尝试计算 accuracy_score,我会得到 0.0 准确度:(但我的准确度约为 60%)

from sklearn.metrics import accuracy_score
y_pred = np.argmax(y_pred, axis=1)
accuracy_score(test_y, y_pred)
>> 0.0

为什么?

具体型号如下:

train_test_split

train, test, train_y, test_y = train_test_split(df['text'], df['label'],test_size = 0.3)

型号:

 def build_model(bert_layer, max_len=512):
    input_word_ids = Input(shape=(max_len,), dtype=tf.int32, name="input_word_ids")
    input_mask = Input(shape=(max_len,), dtype=tf.int32, name="input_mask")
    segment_ids = Input(shape=(max_len,), dtype=tf.int32, name="segment_ids")

    _, sequence_output = bert_layer([input_word_ids, input_mask, segment_ids])
    clf_output = sequence_output[:, 0, :]
    #out = Dense(1, activation='sigmoid')(clf_output)
    out = Dense(8, activation='sigmoid')(clf_output)
    
    model = Model(inputs=[input_word_ids, input_mask, segment_ids], outputs=out)
    model.compile(Adam(lr=2e-6), loss='categorical_crossentropy', metrics=['accuracy'])
    
    return model

模型.fit

    train_history = model.fit(train_input, train_labels, validation_split=0.2, epochs=1,batch_size=16 )

模型.预测

y_pred = model.predict(test_input)

参数的形状

print(type(y_pred))
print(y_pred.shape)
>> <class 'numpy.ndarray'>
>> (621,)

print(type(test_y)) #before running to_categorical
print(test_y.shape)
>> <class 'pandas.core.series.Series'>
>>(621,)

【问题讨论】:

  • 只需打印出test_yy_pred 并检查它们的格式是否相同

标签: tensorflow scikit-learn one-hot-encoding multiclass-classification


【解决方案1】:

嗯,你的输出层定义为out = Dense(1, activation='sigmoid')(clf_output),这意味着有一个输出节点,后面跟着sigmoid激活。这是为了训练二进制分类或回归的目标,其中输出值是介于 0 和 1 之间的实数。使用阈值将其更改为二进制标签。这可以使用

threshold =0.5 # this can be changed. For simplistic example, let uss consider 0.5
y_pred = np.where(y<threshold,0,1)

或者,如果是多类问题,则将out = Dense(1, activation='sigmoid')(clf_output)改为out = Dense(number_of_classes, activation='sigmoid')(clf_output)

【讨论】:

  • 我做了同样的结果
  • 您可能需要调整阈值。在 0.1 的步骤中在 0.1 到 0.9 之间变化并寻找变化。
猜你喜欢
  • 2018-08-05
  • 2021-12-20
  • 2019-10-22
  • 2021-04-14
  • 2020-05-10
  • 2021-06-25
  • 2022-01-25
  • 2022-01-24
  • 2017-04-03
相关资源
最近更新 更多