Python、Keras - 二进制文本分类器预测结果为值数组而不是单一概率

Python, Keras - Binary text classifier prediction results in array of values instead of single probability

我正在构建一个非常简单的 DNN 二元模型,我将其定义为:

def __build_model(self, vocabulary_size):
    model = Sequential()
    model.add(Embedding(vocabulary_size, 12, input_length=vocabulary_size))
    model.add(Flatten())
    model.add(Dense(16, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
    return model

训练如下:

def __train_model(self, model, model_data, training_data, labels):
    hist = model.fit(training_data, labels, epochs=20, verbose=True, validation_split=0.2)

    model.save('models/' + model_data['Key'] + '.h5')

    return model

这个想法是在训练后输入 tfidf 矢量化文本,并在它属于 class 1 或 0 时进行预测。遗憾的是,当我 运行 预测它时,我得到了一组预测而不是属于 class 1 的文章的预期概率为 1。数组值看起来非常统一。我认为这是由于模型中的一些错误造成的。我尝试像这样弹出预测:

            self._tokenizer.fit_on_texts(asset_article_data.content)

            predicted_post_vector = self._tokenizer.texts_to_matrix(post, mode='tfidf')

            return model.predict(predicted_post_vector) > 0.60 // here return array instead of true/false

训练数据本身就是矢量化文本。可能有什么问题?

Keras 被构建为预测多个输入的输出,这就是为什么输出是一个数组。请参阅 keras 文档 here(Returns Numpy 预测数组)。因此,如果您需要单个输出,只需 select 数组的第一个元素:

model.predict(predicted_post_vector)[0] > 0.60

有两种方法可以解决您的问题:

model.predict_classes 正如西蒙所说或使用 argmax

np.argmax(model.predict(predicted_post_vector), axis=1)

我个人会在你的目标变量中使用 pd.get_dummies(y_train) 并将输出层调整为 Dense(2, activation='sigmoid')

您可能犯的错误是 post 是一个字符串,而它应该是一个字符串列表。这就是为什么,正如您提到的,model.predict() 会产生很多值:因为分词器已经迭代了 post 的字符并为每个字符生成了一个 Tf-idf 向量!只需将其放入列表即可解决问题:

... = self._tokenizer.texts_to_matrix([post], ...)