基于关键词组对文本进行分类?

时间:2009-09-29 00:54:15

标签: algorithm nlp text-processing

我有一份软件项目的要求清单,由其前身的遗体组装而成。每个要求应映射到一个或多个类别。每个类别都包含一组关键字。我正在尝试做的是找到一种算法,它可以给我一个分数排名,每个要求可能属于哪个类别。结果将作为进一步分类要求的起点。

举个例子,假设我有这个要求:

  

系统应将存款应用于客户的指定账户。

和类别/关键字:

  1. 客户交易:存款,存款,客户,账户,账户
  2. 余额账户:账户,账户,借方,贷方
  3. 其他类别:foo,bar
  4. 我希望算法在类别1中得分最高,在类别2中得分较低,而在类别3中得不到。评分机制与我无关,但需要表达第1类应用的可能性。比第2类。

    我是NLP的新手,所以我有点不知所措。我一直在阅读 Python中的自然语言处理,并希望应用一些概念,但没有看到任何非常适合的东西。我认为简单的频率分布不会起作用,因为我正在处理的文本很小(一句话)。

3 个答案:

答案 0 :(得分:4)

您可能希望查看“相似性度量”或“距离度量”的类别(在数据挖掘术语中,与“分类”不同。)

基本上,相似性度量是数学的一种方式:

  1. 获取两组数据(在您的情况下,单词)
  2. 做一些计算/方程式/算法
  3. 结果是你有一些数字告诉你这个数据是多么“相似”。
  4. 使用相似性度量,此数字是介于0和1之间的数字,其中“0”表示“根本不匹配”,“1”表示“相同”

    因此,您实际上可以将您的句子视为一个向量 - 并且您的句子中的每个单词都代表该向量的一个元素。同样,对于每个类别的关键字列表。

    然后你可以做一些非常简单的事情:取“cosine similarity”或“Jaccard index”(取决于你如何构建数据。)

    这两个指标的作用是它们同时采用两个向量(您的输入句子和“关键字”列表)并给出一个数字。如果您在所有类别中执行此操作,则可以对这些数字进行排名,以便查看哪个匹配具有最大的相似系数。

    举个例子:

    从你的问题:

      

    客户交易:存款,   存款,客户,账户,账户

    所以你可以构造一个包含5个元素的向量:(1,1,1,1,1)。这意味着,对于“客户交易”关键字,您有5个单词,并且(这听起来很明显但是)每个单词都出现在您的搜索字符串中。跟我一起。

    现在你接受你的判决:

      

    系统应将存款应用于a   客户指定的帐户。

    这有来自“客户交易”集的2个字:{deposit,account,customer}

    (实际上,这说明了另一个细微差别:你实际上有“顾客”。这相当于“顾客”吗?)

    句子的向量可能是(1,0,1,1,0)

    此向量中的1与第一个向量中的1位置相同 - 因为这些单词是相同的。

    所以我们可以说:这些载体有多少次不同?让我们比较一下:

    (1,1,1,1,1) (1,0,1,1,0)

    嗯。它们具有相同的“位”3次 - 在第1,第3和第4位置。它们只相差2位。所以我们说当我们比较这两个向量时,我们的“距离”为2.恭喜,我们只计算了Hamming distance!汉明距离越低,数据越“相似”。

    (“相似性”度量与“距离”度量之间的差异在于前者是标准化的 - 它给出的值介于0和1之间。距离只是任意数字,所以它只给出一个相对值。)

    无论如何,这可能不是进行自然语言处理的最佳方式,但就您的目的而言,它是最简单的,并且实际上可以很好地适用于您的应用程序,或者至少作为起点。

    (PS:“分类” - 正如你在标题中所说的那样 - 会回答这个问题“如果你接受我的判决,哪一类最有可能落入?”这与说“多少有点不同”更类似的是我的第1类比第2类的句子?“这似乎是你所追求的。”

    祝你好运!

答案 1 :(得分:2)

问题的主要特征是:

  • 外部定义的分类标准(关键字列表)
  • 要分类的项目(需求文档中的行)由相对较少的属性值组成,实际上是单个维度:“keyword”。
  • 根据定义,没有反馈/校准(尽管可能适合建议其中一些)

这些特征带来好消息和坏消息:实施应该相对简单,但分类过程的一致准确度可能难以实现。此外,如果需要,少量的各种数量(可能类别的数量,项目中的最大/平均字数等)应该为我们提供选择可能是CPU和/或空间的解决方案的空间。

然而,即使这个许可证变得“花哨”,我建议从一个简单的算法开始(并保持接近),并在此基础上花费除了一些补充和考虑之外,还要保持对过度拟合的危险的警惕。

基本算法(概念,即此时不关注效果技巧)

   Parameters = 
     CatKWs = an array/hash of lists of strings.  The list contains the possible
              keywords, for a given category.
         usage: CatKWs[CustTx] = ('deposits', 'deposit', 'customer' ...)
     NbCats = integer number of pre-defined categories
   Variables:
      CatAccu = an array/hash of numeric values with one entry per each of the
                possible categories.  usage:  CatAccu[3] = 4 (if array) or 
                 CatAccu['CustTx'] += 1  (hash)
      TotalKwOccurences = counts the total number of keywords matches (counts
       multiple when a word is found in several pre-defined categories)

    Pseudo code:  (for categorizing one input item)
       1. for x in 1 to NbCats
            CatAccu[x] = 0    // reset the accumulators
       2. for each word W in Item
             for each x in 1 to NbCats
                 if W found in CatKWs[x]
                      TotalKwOccurences++
                      CatAccu[x]++
       3. for each x in 1 to NbCats
             CatAccu[x] = CatAccu[x] / TotalKwOccurences  // calculate rating
       4. Sort CatAccu by value
       5. Return the ordered list of (CategoryID, rating)
              for all corresponding CatAccu[x] values about a given threshold.

简单但似乎合理:我们赞成匹配最多的类别,但我们除以匹配的总数,作为在找到许多单词时降低置信度的方法。请注意,此划分不会影响给定项目的类别选择的相对排名,但在比较不同项目的评级时可能会很重要。

现在,我想到了几个简单的改进:(我认真考虑前两个,并考虑其他的;决定每一个与项目的范围,统计资料的关系非常紧密要分类的数据和其他因素......)

  • 我们应该规范化从输入项中读取的关键字和/或以容忍拼写错误的方式匹配它们。由于我们的言辞很少,我们需要确保我们不要因为愚蠢的错字而失去重要的一句话。
  • 我们应该更加重视在CatKW中发现频率较低的词语。例如,“帐户”一词应该小于“foo”或“credit”这个词
  • 我们可以(但可能没有用,甚至没有帮助)对具有较少[非噪音]字词的项目的评分给予更多权重。
  • 我们还可以包括基于digrams(连续两个单词)的考虑因素,对于自然语言(并且需求文档不太自然:-))单词接近度通常是单词本身的更强指示。
  • 我们可以为分配给前一个(甚至后面的,在前瞻逻辑中)项目的类别添加一点点重要性。项目可能会出现在相关系列中,我们可以从这种规律性中受益。

另外,除了计算评级本身外,我们还应该考虑:

  • 将用于评估算法结果本身的一些指标(tbd)
  • 一些逻辑,用于收集与指定类别关联的单词列表,并最终对这些单词运行统计。这可以允许识别代表类别的单词,而不是最初在CatKW中列出的。

度量的问题,应该尽早考虑,但这也需要输入项的参考集:排序的“训练集”,即使我们正在处理预定义的字典类别 - 关键字(通常是培训)集合用于确定这个类别关键字列表以及权重因子。当然,这样的参考/训练集应具有统计学意义和统计学上的[整套]。

总结一下:坚持简单方法,无论如何,上下文不会留下非常花哨的空间。考虑引入测量特定算法效率的方法(或给定算法中的特定参数),但要注意这些指标可能存在缺陷,并提示您专门针对给定集合的解决方案。损害其他项目(过度拟合)。

答案 2 :(得分:0)

我也面临着仅基于关键字创建分类器的问题。我有一个类关键字映射器文件,其中包含类变量和出现在特定类中的关键字列表。我提供了以下算法来执行,并且效果很好。

# predictor algorithm
for docs in readContent:
    for x in range(len(docKywrdmppr)):
        catAccum[x]=0
    for i in range(len(docKywrdmppr)):
        for word in removeStopWords(docs):
            if word.casefold() in removeStopWords(docKywrdmppr['Keywords'][i].casefold()):
                print(word)
                catAccum[i]=catAccum[i]+counter
    print(catAccum)
    ind=catAccum.index(max(catAccum))
    print(ind)
    predictedDoc.append(docKywrdmppr['Document Type'][ind])