用于文本分类的 SkLearn 模型

Posted

技术标签:

【中文标题】用于文本分类的 SkLearn 模型【英文标题】:SkLearn model for text classification 【发布时间】:2020-08-11 16:19:50 【问题描述】:

我有一个分类器多类,使用 Sklearn 库提供的 LinearSVC 模型进行训练。 该模型提供了一个decision_function 方法,我将其与 numpy 库函数一起使用以正确解释结果集。

但是,我不明白为什么这种方法总是试图将总概率(在我的例子中为 1)分配到每个可能的类之间。

我预计我的分类器会有不同的行为。

我的意思是,例如,假设我有一段这样的短文本:

"There are a lot of types of virus and bacterias that cause disease."

但是我的分类器是用三种类型的文本训练的,比如说“数学”、“历史”和“技术”。

所以,当我尝试对其进行分类时,我认为这三个主题中的每一个的概率都非常接近于零(因此远不及 1)。

是否有更合适的方法或模型来获得我刚才描述的结果?

decision_function是不是我用错了方式?

有时,您的文本可能与用于训练分类器的任何主题无关,反之亦然,对于多个主题,概率可能约为 1。

我想我需要对这些问题有所了解(文本分类、非二进制分类等)

非常感谢您的帮助!

【问题讨论】:

【参考方案1】:

您的问题有多个部分,我会尽量回答。

    我不明白为什么这种方法总是试图分配总概率?

这是大多数 ML 模型的本质,必须将给定的示例放入某个类中,并且每个模型都有某种机制来计算给定数据点属于某个类以及哪个类具有的概率您将预测相应类别的最高概率。

为了解决您的问题,即示例的存在不属于任何类,您可以在训练模型时始终创建一个名为 others 的伪类,即使您的数据点不属于这种方式对应于您的任何实际类,例如mathshistorytechnology,根据您的示例,它将被分箱到 other 类。

    解决您的数据点可能属于多个类的问题。

这是multi-label classification 的典型用途。

希望这会有所帮助!

【讨论】:

【参考方案2】:

您正在寻找的是多标签分类模型。参考here了解多标签分类以及支持多标签分类任务的模型列表。

演示多标签分类的简单示例:

from sklearn.datasets import fetch_20newsgroups

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import LinearSVC
from sklearn.preprocessing import OneHotEncoder
categories = ['sci.electronics', 'sci.space', 'talk.religion.misc',]
newsgroups_train = fetch_20newsgroups(subset='all',
                                      remove=('headers', 'footers', 'quotes'),
                                      categories=categories)

from sklearn.multioutput import MultiOutputClassifier
from sklearn.pipeline import make_pipeline

X, y = newsgroups_train.data, OneHotEncoder(sparse=False)\
    .fit_transform([[newsgroups_train.target_names[i]]
                      for i in newsgroups_train.target])

model = make_pipeline(TfidfVectorizer(stop_words='english'),
                      MultiOutputClassifier(LinearSVC()))

model.fit(X, y)

print(newsgroups_train.target_names)
# ['sci.electronics', 'sci.space', 'talk.religion.misc']


print(model.predict(['religion followers of jesus']))
# [[0. 0. 1.]]


print(model.predict(['Upper Atmosphere Satellite Research ']))
# [[0. 1. 0.]]


print(model.predict(['There are a lot of types of virus and bacterias that cause disease.']))
# [[0. 0. 0.]]

【讨论】:

【参考方案3】:

解决此问题的常用方法是尝试将文本样本投射到某种向量空间中,并测量该向量空间与同一向量空间中代表分类的某些原型位置之间的“距离”。

这种分类器模型很方便,因为如果您将文本样本折叠成词汇频率向量,它几乎可以简单地表示为向量 - 其中维度由您选择跟踪的词汇特征的数量定义。

通过对更广泛的文本语料库进行聚类分析,您可以尝试确定通常出现在聚类中的中心点,并且可以根据它们所在的向量位置来描述它们。

最后,在定义了几个聚类中心后,您可以简单地用毕达哥拉斯法找到您选择的样本最接近这些主题聚类中的哪个 - 但您也可以轻松获得样本之间的相对距离以及所有其他集群中心 - 所以它的概率更低,更多的是空间度量。

【讨论】:

以上是关于用于文本分类的 SkLearn 模型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sklearn Pipeline 和 FeatureUnion 选择多个(数字和文本)列进行文本分类?

sklearn 除了文本之外的其他输入用于文本分类

[学习记录]sklearn贝叶斯及SVM文本分类

朴素贝叶斯分类算法的sklearn实现

sklearn:文本分类交叉验证中的向量化

如何使用 sklearn 库使用朴素贝叶斯执行文本分类?