【问题标题】:ValueError: Classification metrics can't handle a mix of multiclass and multilabel-indicator targetsValueError:分类指标无法处理多类和多标签指标目标的混合
【发布时间】:2019-10-23 02:26:59
【问题描述】:

我有 2000 个不同标签的多类标签文本分类问题。使用 LSTM 和 Glove Embedding 进行分类。

  1. 目标变量的标签编码器
  2. 带有嵌入层的 LSTM 层
  3. 错误度量是 F2 分数

LabelEncoded 目标变量:

le = LabelEncoder()  
le.fit(y)
train_y = le.transform(y_train)
test_y = le.transform(y_test)

LSTM 网络如下所示,带有 Glove Embeddings

np.random.seed(seed)
K.clear_session()
model = Sequential()
model.add(Embedding(max_features, embed_dim, input_length = X_train.shape[1],
         weights=[embedding_matrix]))#,trainable=False
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(num_classes, activation='softmax'))
model.compile(optimizer='rmsprop', loss='sparse_categorical_crossentropy')
print(model.summary())

我的错误指标是 F1 分数。我为错误指标构建了以下函数

class Metrics(Callback):
    def on_train_begin(self, logs={}):
        self.val_f1s = []
        self.val_recalls = []
        self.val_precisions = []
 
    def on_epoch_end(self, epoch, logs={}):
        val_predict = (np.asarray(self.model.predict(self.validation_data[0]))).round()
        val_targ = self.validation_data[1]
        _val_f1 = f1_score(val_targ, val_predict)
        _val_recall = recall_score(val_targ, val_predict)
        _val_precision = precision_score(val_targ, val_predict)
        self.val_f1s.append(_val_f1)
        self.val_recalls.append(_val_recall)
        self.val_precisions.append(_val_precision)
        print("— val_f1: %f — val_precision: %f — val_recall %f" % (_val_f1, _val_precision, _val_recall))
        return
 
metrics = Metrics()

##模型拟合为

model.fit(X_train, train_y, validation_data=(X_test, test_y),epochs=10, batch_size=64, callbacks=[metrics])

在第一个 epoch 后出现以下错误:

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

我的代码哪里出错了?

【问题讨论】:

    标签: python machine-learning lstm data-science text-classification


    【解决方案1】:

    F1 分数、召回率和准确率是二元分类的指标,用于在多类/多标签问题中使用它,您需要向函数 f1_scorerecall_scoreprecision_score 添加参数。

    试试这个:

    _val_f1 = f1_score(val_targ, val_predict, average='weighted')
    _val_recall = recall_score(val_targ, val_predict, average='weighted')
    _val_precision = precision_score(val_targ, val_predict, average='weighted')
    

    在此处查找有关平均参数的更多信息:
    https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html

    【讨论】:

    • 运气不好。
    【解决方案2】:

    您的问题是由这行代码中的 val_predict 中存在 continuous 值引起的

    _val_f1 = f1_score(val_targ, val_predict)
    

    在计算 f1_score 之前,您应该在 val_predict 中四舍五入您的预测。

    示例解决方案:

     _val_f1 = f1_score(val_targ,np.round(val_predict))
    

    想提一下:如果要改变round函数的阈值(默认0.5)可以在[0,1]区间内加减值:

    >>> a = np.arange(0,1,0.1)
    >>> print(a, abs(np.round(a-0.1)), sep='\n')
    >>> print(a, abs(np.round(a+0.3)), sep='\n')
    
    [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
    array([0.  0.  0.  0.  0.  0.  1.  1.  1.  1.])
    
    [0.  0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
    array([0., 0., 0., 1., 1., 1., 1., 1., 1., 1.])
    

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 2019-06-29
      • 2021-03-18
      • 2021-12-20
      • 2021-04-14
      • 2019-09-07
      • 2020-12-30
      • 2020-05-10
      • 2017-09-25
      • 2018-12-03
      相关资源
      最近更新 更多