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], ...)
我正在构建一个非常简单的 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], ...)