【问题标题】:python: How to use POS (part of speech) features in scikit learn classfiers (SVM) etcpython:如何在 scikit 学习分类器(SVM)等中使用 POS(词性)功能
【发布时间】:2014-07-23 00:58:01
【问题描述】:

我想将 nltk.pos_tag 返回的词性 (POS) 用于 sklearn 分类器,如何将它们转换为向量并使用它? 例如

sent = "这是 POS 示例"

tok=nltk.tokenize.word_tokenize(发送) pos=nltk.pos_tag(tok) 打印(位置)

这将返回以下 [('This', 'DT'), ('is', 'VBZ'), ('POS', 'NNP'), ('example', 'NN')]

现在我无法应用任何矢量化器(DictVectorizer,或 FeatureHasher,来自 scikitlearn 的 CountVectorizer 在分类器中使用

请推荐

【问题讨论】:

  • 除非您不知道矢量化器的作用,否则您并非“无法”使用它们。 DictVectorizerFeatureHasher 处理得很好,其他人有一点工作。

标签: python machine-learning scikit-learn nltk


【解决方案1】:

如果我的理解正确,这有点棘手。一旦你标记它,你的句子(或文档,或其他)不再由单词组成,而是由对(单词 + 标签)组成,并且不清楚如何从中制作最有用的标量向量。

大多数文本向量化器都会做一些事情,比如计算每个词汇项出现的次数,然后为每个词项制作一个特征:

 the: 4, player: 1, bats: 1, well: 2, today: 3,...

下一个文档可能有:

 the: 0, quick:5, flying:3, bats:1, caught:1, bugs:2

只要您始终将相同的键放在同一个数组元素中(对于大多数文档,您将有很多零),两者都可以存储为整数数组 - 或作为字典。因此,矢量化器对许多“文档”执行此操作,然后对其进行处理。

所以您的问题归结为如何将一对列表转换为矢量化器可以计算的项目的平面列表。

最简单的方法是将数据扁平化为

('This', 'POS_DT', 'is', 'POS_VBZ', 'POS', 'POS_NNP', 'example', 'POS_NN')

通常的计数会得到一个包含 8 个词汇项的向量,每个词汇项出现一次。我重命名了标签以确保它们不会与单词混淆。

这会让你启动并运行,但它可能不会完成太多。这是因为仅仅知道样本中每个词性出现了多少可能并不能告诉你你需要什么——请注意,在矢量化器进行计数之后,任何关于哪些词性与哪些词相关的概念都消失了。

如果您想区分风格之类的东西,在其上运行分类器可能会有一些价值——小说可能有更多的形容词,实验室报告可能有更少的专有名称(也许)等等。

相反,您可以将数据更改为

('This_DT', 'is_VBZ', 'POS_NNP', 'example_NN')

这使每个标签都“绑定”到它所属的单词,所以现在向量将能够区分“bat”用作动词的样本和仅用作名词的样本。这会告诉你一些稍微不同的事情——例如,“bat”作为动词在关于棒球的文本中比在关于动物园的文本中更有可能。

你还可以做很多其他的安排。

要在自然语言文本上使用矢量方法获得良好的结果,您可能需要对希望矢量化器生成和使用的功能进行大量思考(和测试)。这在很大程度上取决于您最终要完成的工作。

希望对您有所帮助。

【讨论】:

  • 感谢您的帮助。我正在尝试仅关注 POS 标签、POS tags_word(如您所建议的)并仅连接所有 pos 标签(以便保留 pos 标签信息的位置)。看看哪一个更有帮助
  • 很好的建议。但是,如果我有其他正在寻找特定单词出现的功能(不是矢量化器)怎么办?
【解决方案2】:

我知道这有点晚了,但会在这里添加一个答案。

根据您想要的功能,您需要以有意义的方式对 POST 进行编码。当我将原始句子粘贴到 POST 句子时,使用 ngram 进行 SVM 分类时,我得到了最好的结果,如下所示:

word1 word2 word3 ... wordn POST1 POST2 POST3... POSTn

完成后,我将其输入标准 ngram 或其他任何内容,然后将其输入 SVM。

这种方法保留了单个词的信息,但也保留了 POST 模式的重要信息,当你给你的系统一个它以前没有见过但标注器以前遇到过的词时。

【讨论】:

  • 这个值得一试!谢谢
【解决方案3】:

如何合并单词及其标签,如“单词/标签”,然后您可以将新语料库提供给计算单词(TF-IDF 或袋子词)的矢量化器,然后为每个单词制作一个特征:

    wpt = nltk.WordPunctTokenizer()
    text = wpt.tokenize('Someone should have this ring to a volcano')
    text_tagged = nltk.pos_tag(text)
    new_text = []
    for word in text_tagged:
      new_text.append(word[0] + "/" + word[1])

    doc = ' '.join(new_text)

输出是

   Someone/NN should/MD have/VB this/DT piece/NN of/IN shit/NN to/TO a/DT volcano/NN

【讨论】:

    【解决方案4】:

    我认为更好的方法是:

    1. Step-1: Create word/sentence embeddings for each text/sentence.
    2. Step-2: Calculate the POS-tags. Feed the POS-tags to a embedder as Step-1.
    3. Step-3: Elementwise multiply the two vectors. (This is to ensure that the word-embeddings in each sentence is weighted by the POS-tags associated with it.

    谢谢

    【讨论】:

      猜你喜欢
      • 2018-08-24
      • 2014-02-02
      • 2020-12-10
      • 2014-02-25
      • 2016-05-06
      • 2016-12-06
      • 2018-02-06
      • 2012-11-19
      • 2014-02-20
      相关资源
      最近更新 更多