什么是对文本文档进行分类的好方法?

时间:2018-05-10 02:11:50

标签: text nlp similarity words measure

我编写了一个测量文本重要性的应用程序。它需要一篇文章文章,将其分成单词,删除停用词,执行词干,并计算词频和文档频率。字频是衡量给定单词在所有文档中出现次数的度量,而文档频率是计算给定单词出现的文档数量的度量。

以下是两篇文章的例子:

  • 第一条)“狐狸跳过另一只狐狸。”
  • 第二条)“猎人看到了一只狐狸。”

第一条被分成单词(在后续词语中删除):

  • [“fox”,“jump”,“another”,“fox”]。

第二条分为单词:

  • [“hunter”,“see”,“fox”]。

这两篇文章产生了以下词频和文档频率计数器:

  • fox(字频:3,文档频率:2)
  • jump(字频:1,文档频率:1)
  • another(字频:1,文档频率:1)
  • hunter(字频:1,文档频率:1)
  • see(字频:1,文档频率:1)

鉴于一篇新的文章文章,我如何衡量这篇文章与之前文章的相似之处?

我已经阅读过关于df-idf措施的内容,但它不适用于此处,因为我正在删除停用词,因此“a”和“the”之类的单词不会出现在计数器中。

例如,我有一篇新的文章文章说“猎人爱狐狸”,我怎么想出一个措施,说这篇文章与以前见过的文章很相似?

另一个例子,我有一篇新文章说“鹿很有趣”,然后这篇文章是一篇全新的文章,相似度应为0。

我想我在某种程度上需要对词频和文档频率计数器值进行求和,但是使用什么好的公式?

7 个答案:

答案 0 :(得分:6)

标准解决方案是应用朴素贝叶斯分类器,该分类器在文档 D 的情况下估计类 C 的后验概率,表示为 P(C = k | D)(对于二元分类问题,k = 0和1)。

这是通过从类标记文档的训练集计算先验来估计的,其中给定文档 D 我们知道它的类 C

P(C|D) = P(D|C) * P(D)              (1)

朴素贝叶斯认为术语是独立的,在这种情况下你可以写P(D | C)为

P(D|C) = \prod_{t \in D} P(t|C)     (2)

P(t | C)可以简单地通过计算某个术语在给定类中出现的次数来计算,例如:您希望 football 这个词在属于该类(类别) sports 的文档中会出现很多次。

当谈到另一个因素 P(D)时,您可以通过计算每个班级给出的标签文件数来估算它,可能您有更多体育文章而不是财务,这使您相信将看不见的文档分类为 sports 类别的可能性更高。

很容易将因子(例如术语重要性(idf)或术语依赖性)纳入等式(1)。对于idf,您可以将其作为术语采样事件添加到集合中(与该类无关)。 对于术语依赖,您必须插入形式 P(u | C)* P(u | t)的概率,这意味着您可以采样不同的术语 u 和将其转换(转换)为 t

朴素贝叶斯分类器的标准实现可以在Stanford NLP packageWekaScipy等许多其他地方找到。

答案 1 :(得分:6)

您似乎正在尝试回答几个相关问题:

  1. 如何衡量文件A和B之间的相似性? (指标学习)
  2. 与某些文档集合相比,如何衡量文档C的异常程度? (异常检测)
  3. 如何将一组文档拆分成类似的文档? (聚类)
  4. 如何预测文档属于哪个类? (分级)
  5. 所有这些问题通常分两步解决:

    1. 提取功能:文档 - >表示(通常是数字向量)
    2. 应用模型:表示 - >结果(通常是一个数字)
    3. 功能工程和建模有很多选项。这里只是几个。

      功能提取

      1. 一句话:文件 - >每个单词出现的次数(即术语频率)。这是基本选项,但不是唯一的选项。
      2. 一袋n-gram(字级或字符级别):考虑了几个令牌的共同出现。
      3. 词汇+语法特征(例如POS标签)
      4. 一词嵌入(由外部模型学习,例如word2vec)。您可以使用嵌入作为序列或采用加权平均值。
      5. 无论你能发明什么(例如基于字典查找的规则)......
      6. 功能可能预处理,以减少其中的相对噪音量。预处理的一些选项是:

        • 除以IDF,如果你没有一个坚硬的单词列表,或者认为单词可能更多或更少" stoppy"
        • 将每列标准化(例如字数)以使其具有零均值和单位方差
        • 记录字数以减少噪音
        • 将每行标准化以使L2范数等于1

        您无法提前知道哪个选项最适合您的特定应用 - 您必须进行实验。

        现在您可以构建ML模型。 4个问题中的每一个都有其自身的良好解决方案。

        对于分类,最好的研究问题,你可以使用多种模型,包括朴素贝叶斯,k近邻,逻辑回归,SVM,决策树和神经网络。同样,您无法提前知道哪个会表现最佳。

        这些模型中的大多数都可以使用几乎任何类型的功能。但是,KNN和基于内核的SVM要求您的特征具有特殊结构:在欧几里德距离度量的意义上,一类文档的表示应该彼此接近。这有时可以通过简单的线性和/或对数归一化来实现(见上文)。更困难的情况需要非线性变换,原则上可以通过神经网络学习。学习这些转换是人们称之为度量学习的东西,而且一般来说这是一个尚未解决的问题。

        最常规的距离度量确实是欧几里德。然而,其他距离度量是可能的(例如曼哈顿距离),或不同的方法,不基于文本的向量表示。例如,您可以尝试根据将一个文本转换为另一个文本所需的操作数量计算文本之间的Levenstein距离。或者你可以计算"字移动距离" - 具有最接近嵌入的字对的距离之和。

        对于群集,基本选项是K-means和DBScan。这两种模型都要求您的特征空间具有此Euclidean属性。

        对于异常检测,您可以使用由各种概率算法生成的密度估计:分类(例如朴素贝叶斯或神经网络),聚类(例如高斯模型的混合)或其他无监督方法(例如概率PCA)。对于文本,您可以利用顺序语言结构,估计每个单词在前一个单词条件下的可能性(使用n-gram或卷积/递归神经网络) - 这称为语言模型,它是通常比Naive Bayes的词袋假设更有效,它忽略了词序。几种语言模型(每个类一个)可以组合成一个分类器。

        无论您解决什么问题,强烈建议您使用已知的" 基本事实":哪些文档彼此接近或属于同一类,或(通常)。使用此集,您可以评估特征工程和建模的不同方法,并选择最佳方法。

        如果您没有资源或不愿意进行多项实验,我建议您选择以下方法之一来评估文本之间的相似性:

        • 字数+ idf标准化+ L2标准化(相当于@mcoav的解决方案)+欧几里德距离
        • 意味着word2vec嵌入文本中的所有单词(嵌入字典可以用Google搜索和下载)+欧几里德距离

        基于这些表示之一,您可以为其他问题构建模型 - 例如用于分类的KNN或用于聚类的k均值。

答案 2 :(得分:4)

我建议使用tf-idf和cosine similarity

如果你删除了停用词,你仍然可以使用tf-idf。甚至可能是否包含停用词都不会产生这样的差异:反向文档频率测量会自动减少停用词,因为它们非常频繁并出现在大多数文档中。

如果您的新文档完全由未知术语组成,则每个已知文档的余弦相似度将为0。

答案 3 :(得分:0)

当我搜索df-idf时,我一无所获。

带有tf-idf

cosine similarity是非常接受和通行的做法

过滤停用词不会破坏它。对于常见词汇,无论如何,idf给予他们低重量。

idf由Lucene使用。

不要理解为什么要在这里重新发明轮子。

不要理解为什么你认为df idf的总和是一个相似度量。

对于分类,您是否有一些预定义的类和示例文档可供学习?如果是这样,可以使用Naive Bayes。使用tf-idf。

如果您没有预定义的课程,可以使用k means clustering。使用tf-idf。

这很大程度上取决于您对语料库和分类目标的了解。在为您提供的诉讼支持文件中,您有并且不知道。在安然,他们使用猛禽的名字来处理很多不好的事情,你无法预先了解它。 k表示让文档找到自己的集群。

词干并不总能产生更好的分类。如果你以后想要突出显示命中它会使它变得非常复杂,并且词干不会是单词的长度。

答案 4 :(得分:0)

虽然用英语单独说一个单词就足够了,但在其他一些更复杂的语言中并非如此。

一个词有很多含义,有许多不同的用例。一个文本可以谈论相同的事情,而使用少数几个没有匹配的单词。

您需要在文本中找到最重要的单词。然后你需要捕捉他们可能的同义词。

为此,以下 api 可以提供帮助。用一些词典创建类似的东西是可行的。



tf.Session(config = config)




从那里比较阵列将提供更多的准确性,更少的误报。

答案 5 :(得分:0)

您是否评估了sent2vecdoc2vec方法?您可以使用向量来查看句子的接近程度。只是一个想法。不是您问题的经过验证的解决方案。

答案 6 :(得分:-1)

一个充分的解决方案,可能类似的任务:

  • 使用二进制词袋(BOW)方法进行矢量表示(频繁的单词不是比很少的单词更高的加权),而不是真正的TF方法

  • 嵌入" word2vec"方法,对序列和距离效应敏感。它可能会 - 取决于你的超参数 - 猎人看到一只狐狸之间的差异'和一只狐狸看到一个跳跃的猎人' ......所以你必须决定,如果这意味着在你的任务中添加噪音 - 或者,只是将它作为一个平均向量用于你的所有文本

  • 提取高句内相关词(例如,通过使用变量 - 均值 - 正则 - 余弦 - 相似度)

  • 第二步:使用此高相关词列表作为肯定列表,即作为新二元矢量化程序的新词汇

第二步余弦比较的这个孤立的有意义的词 - 在我的情况下,即使是相当少量的训练文本