【问题标题】:classifying text by sentence structure in python在python中按句子结构对文本进行分类
【发布时间】:2017-05-10 02:27:15
【问题描述】:

我希望能够判断一个句子在 python 中是否真的有意义。例如

Hello, how are you today? --> Correct
Hello, are today are how --> Incorrect

到目前为止,我有以下代码:

1 - 从 nltk.browns 语料库中获取 20 000 个句子。
2 - 混淆最后 10 000 句的单词(用于不正确的数据)
3 - 使用 Stanford POS Tagger 标记所有句子

from nltk.corpus import brown
from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.classify import accuracy
from nltk.tag import StanfordPOSTagger
from nltk import pos_tag
import string
import random

PUNC = [x for x in string.punctuation] + ["''", "``"]

def download_data(target_path):
    brown_data = brown.sents()
    i = 0; n = 0
    with open(target_path, 'w') as data_file:
        while n < 20000:
            for sent in sent_tokenize(' '.join(brown_data[i])):
                updated_list = [x for x in word_tokenize(sent) if x not in PUNC]
                if n > 10000:
                    random.shuffle(updated_list)
                sent = ' '.join(updated_list) + '\n'
                if sent != '\n':
                    data_file.write(sent)
                    n += 1
                i += 1

def get_data(data_path):
    with open(data_path, 'r') as data_file:
        return [x for x in data_file.readlines()]

def parse_data(data, tagger):
    parsed_data = []
    for i in range(len(data)):
        if i > 10000:
            parsed_data.append((tagger.tag(word_tokenize(data[i].replace('\n', ''))), False))
        else:
            parsed_data.append((tagger.tag(word_tokenize(data[i].replace('\n', ''))), True))
    random.shuffle(parsed_data)
    return parsed_data[:15000], parsed_data[15000:]

if __name__ == '__main__':
    data_path = 'data.txt'

    stanford_jar_path = 'stanford-postagger.jar'
    stanford_model_path = 'models/english-bidirectional-distsim.tagger'

    tagger = StanfordPOSTagger(model_filename=stanford_model_path,
                               path_to_jar=stanford_jar_path)

    #download_data(data_path)
    all_data = get_data(data_path)
    train_data, test_data = parse_data(all_data, tagger)

那么我如何训练分类器,例如,根据我提供的数据将新文本分类为正确或不正确?

如果有人有更好的建议,我也愿意。

【问题讨论】:

  • 解决此类问题的技术上正确的方法自然是(a)从您感兴趣的领域的文本中训练语言模型(某种 RNN/LSTM,如果您想切割边缘工作),然后(b)针对已知的好句子和坏句子集合建立一个可接受的概率截止值,最后(c)使用模型为您提供的新的、看不见的句子的句子概率来分离您的二元案例。与现有答案类似,您可能应该首先确保任何这些都是值得的,不过,使用快速而肮脏的二元或三元模型。

标签: python python-2.7 python-3.x machine-learning nlp


【解决方案1】:

我会查看是否存在连续的词性。您的示例可以转换为以下 POS 连续序列:

[('NNP', 'VBP'), ('VBP', 'NN'), ('NN', 'VBP'), ('VBP', 'WRB')] # incorrect
[('NNP', 'WRB'), ('WRB', 'VBP'), ('VBP', 'PRP'), ('PRP', 'NN')] # correct

如果您对两个 POS 的所有可能组合进行排序并构建 0 和 1 的特征向量,则可以使用这些向量来训练您的算法。

【讨论】:

    【解决方案2】:

    您正处于需要为训练集创建特征的阶段。我会使用 2 个和 3 个单词的 n-gram 作为特征,并且可能使用 2 个和 3 个长度的 n-gram 的 POS。因此,例如,您将获取所有句子并找到所有二元/三元组并将它们二值化(如果当前句子不包含它们,则将它们设为 0,如果包含则设为 1)。我会为 POS 做同样的事情。制作 POS 的二元/三元组并将它们二值化。然后,您可以使用诸如朴素贝叶斯之类的方法来查看是否存在任何预测能力。

    【讨论】:

    • 添加 n-gram 作为特征和 pos-gram 作为特征是否会比仅 pos-gram 提高准确性?
    • 我认为会有一些预测能力,因为“棕色狐狸”应该比“狐狸棕色”更频繁地出现。某些单词组合永远不会出现在一个句子中。当然,您应该根据经验进行测试。
    • 如何将它们二值化?我会以一长串的 0 和 1 结束吗? @TedPetrou
    【解决方案3】:

    考虑词性标签虽然很好,但我相信考虑 n-gram 语言模型应该足以满足您的任务。这里我的假设是,POS 标签的数量很少(根据Penn Treebank,36 个),因此与语料库的词汇量相比,变化的数量会更少。因此,POS 标签可能会给您带来良好的性能,但也可能会误导您的分类器。 (个人意见)

    您最多可以使用 5 克语言模型进行实验。所有的 n-gram 都将成为分类器的特征。请注意,更多的 n-gram 会增加复杂性,但应该会提高准确性。

    对于分类,您可以考虑生成模型和判别模型。对于生成模型,您可以考虑朴素贝叶斯,对于判别模型,您可以考虑支持向量机或逻辑回归。这些分类器在文本分类任务中效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 2013-08-27
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2014-06-04
      相关资源
      最近更新 更多