分享

nltk自然语言处理

 AI量化实验室 2023-10-12 发布于北京

自然语言处理,也就从自然语言中解读信息,知识。目前机器翻译取得一些不错的进展,深度学习在NLP的应用还比较有限。本质原因在于文本里,并未包含所有信息,语言有太多的潜台词,所以即便LSTM统计到所有的细节,仍然有限的原因。

深度学习只是一种工具,适当的输入才有恰当的输出。所以纯粹文本seq2seq的学习,在NLP上注定没有什么大用途。必须要文本解读,分词,POS, NER,建立语法树,提取事件等,然后再借助深度学习强大的统计力去建模。

nltk是学习文本处理一个很好的入门框架。里面有大量的语料供学习(大部分是英文)。比如:布朗语料库是第一个百万词级的英语电子语料库的,由布朗大学于1961 年创建。这个语料库包含500 个不同来源的文本,按照文体分类,如:新闻、社论等。

from nltk.corpus import brown
print(brown.categories())
#['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor', 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']

分类很丰富,有科幻,言情,探险...

自然语言最小单元当然是字,如果英文就是字母(char-rnn这个级别的统计会直接按字/char为单元来学习)。一般有意义的处理单元是词,所以分词就是首要任务,英文nlp就占了这个优势,它本来就是分好词的,而中文分词本身就是个难题,比如新词,口语词,行业特定词汇等如何处理。

最直接的一个分析,就是统计词频,不同的文体,通过词频可以看出风格迥异。

#词频统计
fdist = nltk.FreqDist([w.lower() for w in new_words])
print(fdist)
modals = ['can', 'could', 'may', 'might', 'must', 'will']
#词频统计
for m in modals:
print(m + ':', fdist[m])

nltk里还包含大量nlp基本任务的已标注数据,另外还包含了很多非英文的语料,也有繁体中文。

词性标注,就是把分好的词,确定它的词性,中文就是名动形数量代:

tokens = nltk.word_tokenize("And now for something completely different")
tagged = nltk.pos_tag(tokens)
print(tagged)
#[('And', 'CC'), ('now', 'RB'), ('for', 'IN'), ('something', 'NN'), ('completely', 'RB'), ('different', 'JJ')]

在这里我们看到and 是CC,并列连词;now 和completely 是RB,副词;for 是IN,介词;something 是NN,名词;different 是JJ,形容词。

词性就是一种“额外”信息了,比传统只统计词频,把所有词同等对待,又进了一步。text.similar()方法为一个词w 找出所有上下文w1 w w2,然

后找出所有出现在相同上下文中的词w',即w1 w' w2。就是出现在”类似“的位置,“woman”找到的相似的词,都是“名词”

text = nltk.Text(word.lower() for word in nltk.corpus.brown.words())
text.similar('woman')
#man day time year moment car world family house boy child country
#state job place way girl war question word

针对文本处理,更多在词这个层面,统计词频,算tf-idf等,把文档向量化,然后通过传统机器学习,去分类(情感识别也是分类),比如判断名字是男或女的概率,通过的方法有贝叶斯,SVM等。这些把所有词当作同样的东西处理,得到的信息自然很有限。

真正的自然语言理解,要做到像人类一样,还有很长很长的路要走。但从文本中提供更多信息(结构化)信息,可借机器查询,这是可能的。

首先,当然是词性标注,实词比较重要,比如名词,动词。

其次,分块,尤其是名词分块(NP-chunking)

看一个句子:

the little yellow dog barked at the cat.

sentence = [("the", "DT"), ("little", "JJ"), ("yellow", "JJ"),\
("dog", "NN"), ("barked", "VBD"), ("at", "IN"), ("the", "DT"), ("cat", "NN")]
grammar = "NP: {<DT>?<JJ>*<NN>}"
cp = nltk.RegexpParser(grammar)
result = cp.parse(sentence)
print(result)
result.draw()

标注完词性后,我们使用一个简单的正则规则,就是DT NN,之间,可能有或没有形容词,然后把分块画出来。我们得到两个名词分块,句子也很清晰了。

有了分块,就可以识别命名实体(NER),主要是名词短语,人物,事件,地点,组织等。有了命名实体,我们再去抽取这些实体之间的关系,比如三元组或五元组,这些就是知识图谱的基础了。

目前很流行的QA系统,在电商,客服系统里有大量的应用。其实,在我们数据库里大量的结构化数据本身就可以支持回答很多问题。比如一个股票的数据库。你想知道“昨天涨幅超过5%的股票有多少支?”。这个问题通过SQL是可以查询的,但对于普通用户就有难度了,他需要知道数据库的设计,还要会数据库查询。

from nltk import load_parser
cp = load_parser('grammars/book_grammars/sql0.fcfg')
query = 'What cities are located in China'
trees = next(cp.parse(query.split()))
for tree in cp.parse(query.split()):
print(tree)

得到sql语句:

(SELECT City FROM city_table, WHERE  Country="china")

NLTK是学习,研究NLP处理的一个很好的工具包,包括深度学习的实验等都可以在这个库上进行。

关于作者:魏佳斌,互联网产品/技术总监,北京大学光华管理学院(MBA),特许金融分析师(CFA),资深产品经理/码农。偏爱python,深度关注互联网趋势,人工智能,AI金融量化。致力于使用最前沿的认知技术去理解这个复杂的世界。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多