python中基于句子结构的文本分类

python中基于句子结构的文本分类,python,python-2.7,python-3.x,machine-learning,nlp,Python,Python 2.7,Python 3.x,Machine Learning,Nlp,我想知道一个句子在python中是否有意义。比如说 Hello, how are you today? --> Correct Hello, are today are how --> Incorrect 到目前为止,我有以下代码: 1-从nltk.browns语料库中获取20000个句子。 2-混合最后10000句话的单词(对于不正确的数据) 3-使用Stanford词性标记器标记所有句子 from nltk.corpus import brown from nltk.token

我想知道一个句子在python中是否有意义。比如说

Hello, how are you today? --> Correct
Hello, are today are how --> Incorrect
到目前为止,我有以下代码:

1-从nltk.browns语料库中获取20000个句子。
2-混合最后10000句话的单词(对于不正确的数据)
3-使用Stanford词性标记器标记所有句子

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)
从nltk.corpus导入布朗
从nltk.tokenize导入发送\u tokenize,单词\u tokenize
从nltk.1分类导入准确性
从nltk.tag导入StanfordPOSTagger
从nltk导入位置标签
导入字符串
随机输入
PUNC=[x代表字符串中的x。标点符号]+[“''”,“``']
def下载_数据(目标_路径):
brown_data=brown.sents()
i=0;n=0
打开(目标路径“w”)作为数据文件:
当n<20000时:
对于传入的sent_标记化(“”.join(brown_data[i]):
更新的\u列表=[x代表word中的x\u标记化(已发送),如果x不在PUNC中]
如果n>10000:
随机。随机(更新的\u列表)
发送=“”。加入(更新的_列表)+'\n'
如果发送!='\n':
数据文件写入(已发送)
n+=1
i+=1
def get_数据(数据路径):
打开(数据路径“r”)作为数据文件:
返回[x代表数据文件.readlines()中的x]
def parse_数据(数据、标记器):
解析的_数据=[]
对于范围内的i(len(数据)):
如果i>10000:
已解析的_data.append((tagger.tag(word_tokenize(数据[i].replace('\n','')),False))
其他:
已解析的_data.append((tagger.tag(word_tokenize(数据[i].replace('\n','')),True))
随机.shuffle(解析的_数据)
返回解析的_数据[:15000],解析的_数据[15000:]
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
数据路径='data.txt'
stanford_jar_path='stanford postagger.jar'
斯坦福大学模型路径='models/english双向distsim.tagger'
tagger=stanfordpastagger(model_filename=stanford_model_path,
path_to_jar=stanford_jar_路径)
#下载数据(数据路径)
所有数据=获取数据(数据路径)
列车数据,测试数据=分析数据(所有数据,标记器)
因此,我如何训练分类器,例如,根据我提供的数据将新文本分类为正确或不正确


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

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

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

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

当您需要为训练集创建特征时,您已经到了这一步。我会使用2个和3个单词的n-gram作为特征,可能还有2个和3个长度的n-gram词组。例如,你会把你所有的句子,找到所有的bi/三角形,并对它们进行二值化(如果当前句子不包含它们,则将它们设为0,如果包含它们,则设为1)。我也会对POS做同样的操作。制作POS的bi/三叉图并将其二值化。然后,您可以使用naive bayes之类的方法来查看是否存在任何预测能力。

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

您最多可以使用五个gram语言模型进行实验。所有n-gram将是分类器的特征。请注意,n-gram的数量越高,复杂度越高,但准确度越高


对于分类,可以考虑生成模型和判别模型。对于生成模型,可以考虑朴素贝叶斯和判别模型,可以考虑SVM或Logistic回归。这些分类器在文本分类任务中工作得很好。

添加n-gram作为特征和pos-gram作为特征会比pos-gram提高准确性吗?我认为会有一些预测能力,因为“棕色狐狸”应该比“棕色狐狸”更频繁地出现。有些词的组合永远不会出现在相邻的句子中。当然,你应该根据经验来测试。我该如何对它们进行二值化?我会以0和1的长字符串结束吗@从技术上讲,解决这些问题的正确方法自然是:(a)从你感兴趣的领域(某种RNN/LSTM,如果你想成为最前沿的工作)的文本中训练一个语言模型,然后(b)根据已知的好句子和坏句子集合建立一个可接受的概率界限,最后(c)使用该模型给出的新的、看不见的句子的句子概率来分离二进制大小写。与现有的答案类似,您可能首先应该使用快速而肮脏的双元或三元模型来确保所有这些都是值得的。