机器学习模型如何处理看不见的数据和看不见的标签?

Posted

技术标签:

【中文标题】机器学习模型如何处理看不见的数据和看不见的标签?【英文标题】:How can a machine learning model handle unseen data and unseen label? 【发布时间】:2019-02-21 15:02:38 【问题描述】:

我正在尝试解决文本分类问题。我有有限数量的标签来捕获我的文本数据的类别。如果传入的文本数据不适合任何标签,则将其标记为“其他”。在下面的示例中,我构建了一个文本分类器来将文本数据分类为“早餐”或“意大利”。在测试场景中,我包含了一些不适合我用于训练的标签的文本数据。这是我面临的挑战。理想情况下,我希望模型说——“我喜欢徒步旅行”和“每个人都应该理解数学”的“其他”。我怎样才能做到这一点?

import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer

X_train = np.array(["coffee is my favorite drink",
                    "i like to have tea in the morning",
                    "i like to eat italian food for dinner",
                    "i had pasta at this restaurant and it was amazing",
                    "pizza at this restaurant is the best in nyc",
                    "people like italian food these days",
                    "i like to have bagels for breakfast",
                    "olive oil is commonly used in italian cooking",
                    "sometimes simple bread and butter works for breakfast",
                    "i liked spaghetti pasta at this italian restaurant"])

y_train_text = ["breakfast","breakfast","italian","italian","italian",
                "italian","breakfast","italian","breakfast","italian"]

X_test = np.array(['this is an amazing italian place. i can go there every day',
                   'i like this place. i get great coffee and tea in the morning',
                   'bagels are great here',
                   'i like hiking',
                   'everyone should understand maths'])

classifier = Pipeline([
    ('vectorizer', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', MultinomialNB())])

classifier.fit(X_train, y_train_text)
predicted = classifier.predict(X_test)
proba = classifier.predict_proba(X_test)
print(predicted)
print(proba)

['italian' 'breakfast' 'breakfast' 'italian' 'italian']
[[0.25099411 0.74900589]
 [0.52943091 0.47056909]
 [0.52669142 0.47330858]
 [0.42787443 0.57212557]
 [0.4        0.6       ]]

我将“其他”类别视为噪音,我无法为该类别建模。

【问题讨论】:

【参考方案1】:

不,你不能那样做。

您必须定义第三个类别“其他”或任何适合您的名称,并为您的模型提供与该类别相关的一些数据。确保所有三个类别的训练示例数量大致相等,否则“其他”是一个非常广泛的类别可能会使您的模型偏向“其他”类别。

解决此问题的其他方法是从所有句子中获取不同类别(包括其他)的名词短语,然后将其输入模型,将此视为机器学习模型的特征选择步骤。这样会去除不相关词添加的噪音,比 tf-idf 性能更好。

如果您有大量数据,请选择自动进行特征选择的深度学习模型。

不要使用自己操纵概率的方法,50-50% 的概率意味着模型在您定义的两个类之间混淆,它不知道第三个“其他类”。 假设这句话是“我想要意大利早餐”,模型会混淆这句话是属于“意大利”还是“早餐”类别,但这并不意味着它属于“其他”类别。

【讨论】:

【参考方案2】:

我认为 Kalsi 可能提出了这个建议,但我并不清楚。您可以为您的课程定义一个置信度阈值。如果预测的概率未达到您的任何类别的阈值(您的示例中为“意大利”和“早餐”),则您无法对产生“其他”“类别”的样本进行分类。

我说“类”是因为 other 不完全是一个类。您可能不希望您的分类器擅长预测“其他”,因此此置信度阈值可能是一个不错的方法。

【讨论】:

【参考方案3】:

你不能这样做。

您已训练模型仅预测两个标签,即breakfastitalian。所以模型对第三个标签或第四个标签等没有任何想法。

你和我都知道"i like hiking" 既不是breakfast 也不是italian。但是模型 a 怎么会知道呢?它只知道breakfast & italian。所以必须有一种方法告诉模型:如果你对breakfastitalian感到困惑,那么将标签预测为other

您可以通过训练以other 作为标签的模型以及"i like hiking" 等文本来实现这一点

但在您的情况下,可以按以下方式完成一点hack


那么,当模型以 0.5(或大约 0.5)的概率预测标签时,这意味着什么?这意味着模型在标签breakfastitalian 之间混淆了。所以在这里你可以利用这一点。

如果概率值介于 0.45 和 0.55 之间,您可以获取所有预测的概率值并分配标签 other。通过这种方式,您可以预测other 标签(显然有一些错误),而无需让模型知道有一个名为other 的标签

【讨论】:

【参考方案4】:

您可以在创建 MultinomialNB 时尝试设置类先验。您可以创建一个虚拟的“其他”训练示例,然后为其他设置足够高的先验,以便在没有足够证据选择其他类时实例默认为其他。

【讨论】:

以上是关于机器学习模型如何处理看不见的数据和看不见的标签?的主要内容,如果未能解决你的问题,请参考以下文章

橙色用于数据挖掘和看不见的测试集

通过先前训练的模型预测看不见的数据

机器学习之监督学习-分类模型决策树的基本概念

机器学习基本概念和模型训练基本问题

dbvisualize为啥有些数据库看不见了

机器学习中如何处理不平衡数据?