NLP with Python 阅读笔记及Python3纠正(更新中)

2020.1.15
Q1:遇到nltk.downlad() 出现远程服务器关闭的错误,无法下载book的数据
A1:用cmd命令行运行 python会出错,但是改成用python 的3.7.0 的shell使用

>>>import nltk 
>>>nltk.download()

则成功打开GUI可视化下载界面,但是进度条旁边出现了Aborting download...
所以必须手动下载NLTK包,网盘里有。然后将下载好的nltk_data解压后的文件夹放到GUI界面里显示的放置路径里就可以了,用from nltk.book import *在Python shell里面测试是否成功安装。

切换Python版本,例如

py -3 -m pip install xxx

2020.1.16
发现用python shell安装package太麻烦了,果然还是想用pycharm
只需要在pycharm里面,用terminal,安装ipython ,测试有没有安装好nltk,就可以直接使用了
而且使用到numpy的matplotlib的函数也可以直接用。就不需要研究这些包怎么安装了。

#搜索某词语
text1.concordance("lived") 
#搜索相关的词语
text1.similar("monstrous")
#看本语料库的信息
text1
#研究两个或两个以上的词共同的上下文,
text2.common_contexts(["monstrous","very"])
#查看一个或多个词在文本位置中的分布的离散图
text4.dispersion_plot(["citizens","democracy","freedom"])
#根据源文本生成随机对应风格的文本
text3.generate()
#计算文本从头到尾的长度
len(text3)
#获得text的词汇表
set(text3)
#获得经过排序的text词汇表
sorted(set(text3))
#~上面获得的内容叫做唯一项目类型,而不是词类型,因为包括标点符号~
#每个字被平均使用的次数
len(text3)/len(set(text3))
#计算一个词在文本中出现的次数
text3.count("smote")
#计算一个特定词在文本中占据的百分比
100*text4.count('a')/len(text4)
#每次重读输入这些函数,会很繁琐,所以定义函数计算百分比等数据
def percentage(count,total):
    return 100*count/total

列表/链表

#创建一个列表
sent1=['Call','me','Ishmael','.']
#其实nltk包里已经定义好了sent1,sent2....sent9
sent1
#列表可以直接相加,成为一个新列表。这个叫做连接。
['小米','最近在读']+['推荐','系统']
#不必逐字输入,用别名也行
sent1+sent2
#在列表中追加一个新的元素。这个叫做追加。
sent1.append("Some")

索引列表

#根据位置查询词语的下标,下标从0开始
text4[173]
#根据词语查询第一次出现的下标
text4.index('awaken')
#获取子列表,从大文本中任意抽取语言片段,这个叫做切片
text5[16715:16735]
#5:8
sent=['1','2','3','4','5','6','7','8','9']
sent[5:8]
结果是 6,7,8
sent[:8]
结果是 1,2,3,...,8
sent[2:]
结果是 3,...,9

字符串

#对于访问列表方式,同样可以运用到字符串上
>>> name='Morty'
>>> name*2
'MortyMorty'
#把词用列表连接起来,拼接成单个字符串
>>>'这里输入用于连接的字符'.join(['Morty','Python'])
'Morty这里输入用于连接的字符Python'
#把字符串分割成一个链表
>>>'Morty Python'.split()
['Morty','Python']

计算语言:简单的统计

>>>tokens=['After', 'all', 'done', 'is', 'more', 'said', 'than']
tokens[-2:]
['said', 'than']

频率分布:表示文本中每一个词项的频率

#寻找该文本中最常见的50个词
>>>fdist1=FreqDist(text1)
>>>vocabulary1=fdist1.keys()
>>>vocabulary1[:50]
报错:'dict_keys' object is not subscriptable
#这是Python3才会出现的错误,需改成
>>>vocabulary1=list(fdist1.most_common(50))
>>>vocabulary1
#这样才能得到正确的结果,因为先前的vocabulary不能进行切片
#生成前频率最高的50个词的累计频率图
fdist1.plot(50,cumulative=True)
#列出只出现了一次的词
fdist1.hapaxes()

细粒度的选择词
设性质P:一个超过15个字符的词,V代表这个词汇表
a. {w | w ∈ V & P(w)}
b. [w for w in V if p(w)]

#筛选出该文本v中的超过15个字符的
v=set(text1)
long_words=[w for w in v if len(w) >15 ]
sorted(long_words)#排序,发现大写在前,小写在后
#筛选出该文本中的长低频词
>>>fidst5=FreqDist(text5)
>>> sorted([w for w in set(text5) if len(w)>7 and fidst5[w]>7])

2020.1.17
词语搭配和双连词(bigrams)

#Q1:>>>bigrams(['more','is','said','than','done'])
 Error:<generator object bigrams at 0x1E176070>
 #A1:>>>list(bigrams([]'more','is','said','than','done'])
 [('more', 'is'), ('is', 'said'), ('said', 'than'), ('than', 'done
')]
#Q2:>>>text4.collocations()
ValueError      Traceback (most recent call last)
#A2:>>>text4.colocation_list()
['United States',
 'fellow citizens',
 'four years',
 'years ago',
 'Federal Government',
#......省略
 'one another',
 'foreign nations',
 'political parties']

计数其他东西

#创造一个列表,其中每个数字是文本中对应词的长度
>>>[len(w) for w in text1]
>>>fdist=FreqDist([len(w) for w in text1])
>>>fdist
#以频率递减顺序排序的样本列表
>>>fdist.keys()
#(长度,频率)
>>>fdist.items()
#最大频率的长度
>>>fdist.max()
#长度为3的词在全书单词中的频率
>>>fdist.freq(3)
#增加样本
>>>fdist.inc(sample)
#样本总数
>>>fdist.N() 
#频率分布表
>>>fdist.tabulate()
#测试样本在fdist1中出现的频率是否小于fdist2
fdist1<fdist2

1.4回到python:决策与控制
让机器能按照我们的意愿决策,遇到特定条件时执行特定命令,这一特征被成为控制。
条件

[w for w in sent7 if len(w) < 4]
#其中, <可以换成其他条件符号
[w for w in text if condition]
#测试s是否以t开头
s.startswith(t)
#测试s是否以t结尾
s.endswith(t)
#测试s是否包含t
t in s 
#测试s是否所有字符都是小写字母
s.islower()
#测试s是否所有字符都是大写字母
s.isupper()
#测试s是否所有字符都是字母
s.isalpha()
#测试s是否所有字符都是字母或数字
s.isalnum()
#测试s是否所有字符都是数字
s.isdigit()
#测试s是否所有字符都是首字母大写
s.istitle()

文本中选择词汇运算符

>>>sorted([w for w in set(text1) if w.endswith('ableness')])
>>>sorted([item for item in set(sent7) if item.isdigit()])
>>>sorted([item for item in set(text6) if item.istitle()])
>>>sorted([term for term in set(text4) if 'gnt' in term])
>>>sorted([w for w in set(text7) if '-' in w and 'index' in w])
>>>sorted([wd for wd in set(text3) if wd.istitle() and len(wd)])
>>>sorted([t for t in set(text2) if 'cie' in t or 'cei' in t])
>>>sorted([t for t in set(sent7) if not t.islower()])

条件循环

for word in ['Call','me','Ishmael','.']:
     print(word)
for word in tricky:
     print(word,end=',')

1.5自动理解自然语言
词义消歧:推算出特定上下文中的词被赋予的意思。
指代消解(anaphora resolution):检测主语和动词的宾语的计算技术。
语义角色标注(semantic role labeling):确定名词短语如何与动词相关联。
自动生成语言:例如自动问答和机器翻译。
文本对齐:给出一个双语文档,自动配对组成句子的过程。

Q1: name 'babelize_shell' is not defined
A1:The issue isn't with your code. The problem is that the
babelfish translation service is no longer in operation 
so the example code no longer works.
#原始的对话系统
nltk.chat.chatbots()

简单的语音对话系统的流程架构

2020.1.18

古登堡语料库

nltk.corpus.gutenberg.fileids()
emma=nltk.corpus.gutenberg.words('austen-emma.txt')
#为了简化
from nltk.corpus import gutenberg
gutenberg.fileids()
emma=gutenberg.words('austen-emma.txt')
for fileid in gutenberg.fileids():
    num_chars=len(gutenberg.raw(fileid))
    num_words=len(gutenberg.words(fileid))
    num_sents=len(gutenberg.sents(fileid))
    num_vocab=len(set([w.lower() for w in gutenberg.words(fileid)]))
    print(int(num_chars/num_words),int(num_words/num_sents),int(num_words/num_vocab))
#sents()函数分割句子
macbeth_sentences=gutenberg.sents('shakespeare-macbeth.txt')
#访问句子
macbeth_sentences[1037]
#找最长的句子
longest_len=max([len(s) for s in macbeth_sentences])
[s for s in macbeth_sentences if len(s) == longest_len]
#“原始”的文本
len(gutenberg.raw('blake-poems.txt')
#网络聊天文本
import nltk
from nltk.corpus import webtext
for fileid in webtext.fileids():
    print(fileid,webtext.raw(fileid)[:65],'...')
from nltk.corpus import nps_chat
#2006年10月19日20岁聊天室手机的706个帖子
chatroom=nps_chat.posts('10-19-20s_706posts.xml')
chatroom[123]
#布朗语料库
from nltk.corpus import brown
#布朗语料库的分类
brown.categories()
#输入对应的File_id,访问对应的文件
brown.words(fileids=['cg22'])
#三个类型的sents
brown.sents(categories=['news','editorial','reviews'])
new_text=brown.words(categories='news')
cfd=nltk.ConditionalFreqDist((genre,word)
    for genre in brown.categories()
    for word in brown.words(categories=genre))
genres=['news','religion','hobbies','science_fiction','romantic','humor']
modals=['can','could','may','might','must','will']
#不同类型文章下的形态动词频率分布图
cfd.tabulate(conditions=genres,samples=modals)
#路透社语料库
from nltk.corpus import reuters
#查看路透社全部主题的文件名
reuters.fileids()
#查看路透社某主题的文件名
reuters.fileids('barley')
#查看路透社某几个主题的文件名
reuters.fileids(['barley','corn'])
#查看路透社的文章的类别下的文档
reuters.categories()
reuters.categories('training/9865')
reuters.categories(['training/9865','training/9880'])
#根据类别看文档内容
reuters.words(['training/9865','training/9880'])
reuters.words(categories=['barley','corn'])
#就职演说语料库
from nltk.corpus import inaugural
inaugural.fileids()
 [fileids[:4] for fileids in inaugural.fileids()]
from nltk.corpus import inaugural
cfd = nltk.ConditionalFreqDist(
      (target, fileid[:4])
                 for fileid in inaugural.fileids()
                 for w in inaugural.words(fileid)
                 for target in ['america', 'citizen']
                 if w.lower().startswith(target))
cfd.plot()

标注文本语料库
许多文本语料库都包含语言学标注,有词性标注、命名实体、句法结构、语义角色等。
其他语言的语料库。

nltk.corpus.cess_esp.words()
nltk.corpus.floresta.words()
nltk.corpus.indian.words()
#超过300种语言的世界人权宣言
nltk.corpus.udhr.fileids()
nltk.corpus.udhr.words('Javanese-Latin1')[11:]
#查看该文本的字母频率分布图
raw_text=udhr.raw('Yoruba-UTF8')
nltk.FreqDist(raw_text).plot()
#不同版本的世界人权宣言的累积字长条件频率分布图
from nltk.corpus import udhr
languages = ["Chickasaw", "English", "German_Deutsch"]
cfd = nltk.ConditionalFreqDist(
     (lang, len(word))
     for lang in languages
     for word in udhr.words(lang+"-Latin1"))#文件编码是Latin1
cfd.plot(cumulative=True)

文本语料库的结构

fileids() #语料库中的文件
fileids([categories]) #这些分类对应的语料库中的文件
categories() #语料库中的分类
categories([fileids]) #这些文件对应的语料库中的分类
raw() #语料库的原始内容
raw(fileids=[f1,f2,f3]) #指定文件的原始内容
raw(categories=[c1,c2]) #指定分类的原始内容
words() #整个语料库中的词汇
words(fileids=[f1,f2,f3]) #指定文件中的词汇
words(categories=[c1,c2]) #指定分类中的词汇
sents() #指定分类中的句子
sents(fileids=[f1,f2,f3]) #指定文件中的句子
sents(categories=[c1,c2]) #指定分类中的句子
abspath(fileid) #指定文件在磁盘上的位置
encoding(fileid) #文件的编码(如果知道的话)
open(fileid) #打开指定语料库文件的文件流
root() #到本地安装的语料库根目录的路径

载入自己的语料库
from nltk.corpus import PlaintextCorpusReader
corpus_root =r"C:\Users\Greenaway\Desktop\text-mining"
wordlists=PlaintextCorpusReader(corpus_root,'.*')
wordlists.fileids()
wordlists.words('train.csv')

from nltk.corpus import BracketParseCorpusReader
 file_pattern=r".*.csv"
 ptb = BracketParseCorpusReader(corpus_root, file_pattern)
 ptb.fileids()

2020.1.24

条件频率分布:是频率分布的集合,每个频率分布有一个不同的条件。

条件和事件:不是处理一个词序列,而是处理一个配对序列
按文体计数词汇

from nltk.corpus import brown
cfd=nltk.ConditionalFreqDist(
    (genre,word)
    for genre in brown.categories()
    for word in brown.words(categories=genre))
genre_word=[(genre,word)
            for genre in ['news','romance']
            for word in brown.words(categories=genre)]
len(genre_word)
genre_word[:4]
genre_word[-4]

cfd=nltk.ConditionalFreqDist(genre_word)
cfd
cfd.conditions()
cfd['news']
cfd['romance']
list(cfd['romance'])
cfd['romance']['could']

绘制分布图和分布表

from nltk.corpus import inaugural
cfd=nltk.ConditionalFreqDist(
    (atrget,fileid[:4])
    for fileid in inaugural.fileids()
    for w in inaugural.words(fileid)
    for target in ['america','citizen']
    if w.lower().startswith(target)
)

from nltk.corpus import udhr
languages=['Chickasaw','English']
cfd=nltk.ConditionalFreqDist(
    (lang,len(word))
    for lang in languages
    for word in udhr.words(lang+'-Latin1')
)

cfd.tabulate(conditiona=['English','German_Deutsch'],
samples=range(10),cumulative=True)

使用双连词生成随机文本

sent=['In','the','beginning','God','created','the','heaven','and','the','earth','.']
list(nltk.bigrams(sent))
def generate_model(cfdist,word,num=15):
    for i in range(num):
        print(word)
        word=cfdist[word].max()
text=nltk.corpus.genesis.words('english-kjv.txt')
bigrams=nltk.bigrams(text)
cfd=nltk.ConditionalFreqDist(bigrams)

print(cfd['living'])
generate_model(cfd,'living')

cfdist= ConditionalFreqDist(pairs) 从配对链表中创建条件频率分布
cfdist.conditions() 将条件按字母排序
cfdist[condition] 此条件下的频率分布
cfdist[condition][sample] 此条件下给定样本的频率
cfdist.tabulate() 为条件频率分布制表
cfdist.tabulate(samples, conditions) 指定样本和条件限制下制表
cfdist.plot() 为条件频率分布绘图
cfdist.plot(samples, conditions) 指定样本和条件限制下绘图
cfdist1 < cfdist2 测试样本在cfdist1 中出现次数是否小于在cfdist2 中出现次
数

代码重用:
在一个文件中的变量和函数定义的集合被称为一个Python 模块(module)。相关模块的
集合称为一个包(package)。处理布朗语料库的NLTK 代码是一个模块,处理各种不同的语
料库的代码的集合是一个包。NLTK 的本身是包的集合,有时被称为一个库(library)。

词典资源:
词汇列表语料库
发音词典
比较词表
Swadesh wordlists

#导入Swadesh包
from nltk.corpus import swadesh
#查看file id列表
swadesh.fileids()
swadesh.words('en')
#选择不同语言转换的词典
#entries方法指定一个语言列表来访问多语言中的同源词
fr2en=swadesh.entries(['fr','en'])#法-英
fr2en
#利用dict()函数转换成字典
translate=dict(fr2en)
#因为字典的特性只能 法译英
fr2en['nom']
fr2en['si']

词汇工具

#Toolbox(http://www.sil.org/computing/toolbox/)  Shoebox
#一个Toolbox 文件由一个大量条目的集合组成,其中每个条目由一个或多个字段组成。
#大多数字段都是可选的或重复的

from nltk.corpus import toolbox
toolbox.entries('rotokas.dic')

2.5WordNet
类似于传统辞典
意义与同义词

#import A as B  :这种方式为给引入的包A定义一个别名B
from nltk.corpus import wordnet as wn 
#这样就不用输入wordnet了,定义了别名以后,原名就不能用了
#探索一个词的同义词:
>>>wn.synsets('motorcar')
[Synset('car.n.01')]
#('car.n.01')被称为synset(同义词集)

Q1:wn.synset('car.n.01').lemma_names
 出现了<bound method Synset.lemma_names of Synset('car.n.01')>
A1:应改为 wn.synset('car.n.01').lemma_names()

#查询一个同义词集的定义
wn.synset('car.n.01').definition()
#查询一个同义词集的例句
wn.synset('car.n.01').examples()
#查询一个同义词集的所有词意的包(?
wn.synset('car.n.01').lemmas()
#查看一个同义词集的词集名
wn.lemma('car.n.01.automobile')
#查看一个同义词集的上级词集名
wn.lemma('car.n.01.automobile').synset()
#查看一个同义词集的当前级词集名
wn.lemma('car.n.01.automobile').name()
#查看一个单词的所有释义的同义词集
wn.synsets('car')
#输出每个释义下的同义词
for synset in wn.synsets('car'):
    print(synset.lemma_names())

Q2:  轮到你来:写下词dishd 的你能想到的所有意思。现在,在WordNet 的帮助下
使用前面所示的相同的操作探索这个词。wn.synsets('dishd')输出为空列表
#A2:dishd应该没有收录它的同义词

Wordnet的层次结构

#查看一个词的下位词
motorcar.hyponyms()
#查看一个词的上位词
motorcar.hypernyms()
#WordNet层次路径
paths=motorcar.hypernym_paths()
#查看路径
[synset.name() for synset in paths[0]]
#查看根上位的同义词集
motorcar.root_hypernyms()
#图形化WordNet浏览器
nltk.app.wordnet()

更多的词汇关系
上位词和下位词被称为词汇关系。
一棵树的部分是它的树干,树冠等;这些都是part_meronyms()。
一棵树的实质是包括心材和边材组成的,即substance_meronyms()。
树木的集合形成了一个森林,即member_holonyms()

wn.synset('tree.n.01').part_meronyms()
wn.synset('tree.n.01').substance_meronyms()
wn.synset('tree.n.01').member_holonyms()
#输出一个单词所有同义词集的定义
for synset in wn.synsets('mint',wn.NOUN):
    print(synset.name()+':',synset.definition())
#输出一个单词的细致释义
wn.synset('eat.v.01').entailments()
#输出一个单词的反义词
wn.lemma('rush.v.01.rush').antonyms()
#查看其他词汇关系的使用方法
dir(wn.synset('harmony.n.02'))
#查看和另一个单词的共同最小上位词
orca=wn.synset('orca.n.01')
novel=wn.synset('novel.n.01')
orca.lowest_common_hypernyms(novel)
#查看一个 单词同义词集的深度量化
wn.synset('tortoise.n.01').min_depth()
#查看一个单词和另一个单词的路径相似度
orca.path_similarity(novel)

第3章加工原料文本
3.1 从网络和硬盘访问文本
处理html
*clean_html等函数已经失效

from bs4 import BeautifulSoup
from urllib.request import urlopen
url='http://novel.tingroom.com/jingdian/3274/89548.html(a page)'
res=urlopen(url)
html=res.read()
clean=BeautifulSoup(html).get_text()
tokens=nltk.word_tokenize(clean)
tokens

处理搜索引擎的结果
处理RSS订阅

import feedparser
url="http://feed.cnblogs.com/blog/sitehome/rss"#注意是rss网页
html=urlopen(url)
llog=feedparser.parse(url)
llog['feed']['title']#博客标题
len(llog.entries)
post.title #标题
content=post.content[0].value#输出目录
token=BeautifulSoup(content[0].value).get_text()#输出清洗后的文字
nltk.word_tokenize(token)

字符串前有 u代表是 unicode字符

处理文件:

f=open("document.txt")
f.read()
for line in  f:
    print(line.strip())
#删除输入行结尾的换行符
import PyPDF2
f=open("document.pdf",'rb')
pdfreader=PyPDF2.PdfFileReader(f)
#输出pdf页数
print(pdfreader.numPages)
#查看某一页的pdf
page=pdfreader.getPage(50)

捕捉用户输入
raw_input()已经在python3中被归入input()了
>>>s=input("Enter some text: ")
2019-cndjska f dsf
>>>print("You typed",nltk.word_tokenize(s),"words.")

3.2字符串的操作

s.find(t) 字符串s 中包含t 的第一个索引(没找到返回-1)
s.rfind(t) 字符串s 中包含t 的最后一个索引(没找到返回-1)
s.index(t) 与s.find(t)功能类似,但没找到时引起ValueError
s.rindex(t) 与s.rfind(t)功能类似,但没找到时引起ValueError
s.join(text) 连接字符串s 与text 中的词汇
s.split(t) 在所有找到t 的位置将s 分割成链表(默认为空白符)
s.splitlines() 将s 按行分割成字符串链表
s.lower() 将字符串s 小写
s.upper() 将字符串s 大写
s.titlecase() 将字符串s 首字母大写
s.strip() 返回一个没有首尾空白字符的s 的拷贝
s.replace(t, u) 用u 替换s 中的t

字符串和链表都是一种序列。我们可以通过索引抽取它们中的一部分,可以给它们切片,可以使用连接将它们合并在一起。但是,字符串和链表之间不能连接。字符串是不可变的。

每个字符分配一个编号,称为编码点。翻译成Unicode 叫做解码。Unicode 转化为其它编码的过程叫做编码。

3.4使用正则表达式检测词组搭配

import re
wordlist=[w for w in nltk.corpus.words.words('en') if w.islower()]
#re.search(p,s)检查字符串s中是否有模式p
#比如检测单词是否以ed结尾
[w for w in wordlist if re.search('ed$',w)]
# ^表示一定是这么长的字符,且j是第3个,t是倒数第3个字符
[w for w in wordlist if re.search('^..j..t..$',w)]
#去掉$,j是第3个,t无所谓
[w for w in wordlist if re.search('^..j..t..',w)]
#去掉^,t是第3个,j无所谓
[w for w in wordlist if re.search('..j..t..$',w)]
#去掉^和$只要包含j 和 t就行,两个字母的先后无所谓
[w for w in wordlist if re.search('..j..t..',w)]
#4个字符分别从四个[]中选择,并且按照[]先后顺序
[w for w in wordlist if re.search('^[ghi][mno][jlk][def]$',w)]
#在wordlist中 由g到o组成的长短不一的单词
[w for w in wordlist if re.search('^[g-o]+$',w)]
#在wordlist中 由a-f j-o 中的至少1个字母组成的长短不一的单词
[w for w in wordlist if re.search('^[a-gj-o]+$')]

chat_words=sorted(set(w for w in nltk.corpus.nps_chat.word()))
#在chat_words 中 严格包含这四个字母的单词
[w for w in chat_words if re.search('^m+i+n+e+$',w)]
#在chat_words 中 含有 m i n e中的一个或没有的单词(所有元素)
[w for w in chat_words if re.search('^m*i*n*e*$',w)]
#在chat_words 中 含有至少h a中的一个字母的单词
[w for w in chat_words if re.search('^[ha]+$',w)]


wsj=sorted(set(nltk.corpus.treebank.words()))
#\. 为转义字符,避免混淆
#逗号左侧和逗号右侧的字符必须由0-9之间的数字组成的所有元素,长度不定
[w for w in wsj if re.search('^[0-9]+\.[0-9]+$',w)]
#在wsj中由A-Z且后缀为$的所有元素
[w for w in wsj if re.search('^[A-Z]+\$$',w)]
#在wsj中仅仅由0-9之间的数字组成且长度严格为4的元素
[w for w in wsj if re.search('^[0-9]{4}$',w)]
#在wsj中被-分割的 前半部分由0-9长度不定的字符串,
#后半部分由长度在3-5之间的a-z组成的单词的所有元素
[w for w in wsj if re.search('^[0-9]+-[a-z]{3,5}',w)]
#被-分割成三部分的长度分别 ≥5, 2或3,≤6 的字母串的所有元素
[w for w in wsj if re.search('^[a-z]{5,}-[a-z]{2,3}-[a-z]{,6}$',w)]
#ing或ed结尾的单词
[w for w in wsj if re.search('(ed|ing)',w)]

3.5正则表达式的有益应用
运算符“”当它出现在方括号内的第一个字符位置时有另外的功能。例如:«[aeiouAEIOU]»匹配除元音字母之外的所有字母。
提取字符块

word='supercalifragilisticexpialidocious'
re.findall(r'[aeiou]',word)
fd=nltk.FreqDist(vs for word in wsj)
        for vs in findall(r'[aeiou]{2,}',word)
fd.items()

#将2009-12-31转化成2009.12.31
[int(n) for n in re.findall(r'[0-9]+','2009-12-31')]
#消除前几个元音字母
regexp=r'^[AEIOUaeiou]+|[AEIOUaeiou]+$|[^AEIOUaeiou]'
#
def compress(word):
    pieces=re.findall(regexp,word)
    return ''.join(pieces)
english_udhr=nltk.corpus.udhr.words('English-Latin1')
print(nltk.tokenwrap(compress(w) for w in english_udhr[:75]))

#查看正则匹配的地方 例如
nltk.re_show('ed$','happened')
#正则表达式的demo
nltk.app.nemo()

查找词干

#低级原始的处理词干的方法,不能直接用pycharm的Terminal运行,改用IDLE
def stem(word):
	for suffix in ['ing','ly','ed','ious','ies','ive','es','s','ment']:
		if word.endswith(suffix):
			return word[:-len(suffix)]
	return word#输出删掉后缀的词干
#将上面的函数可以直接用正则表达式改写成另外一句,得到检测出来的后缀
re.findall(r'^.*(ing|ly|ed|ious|ies|ive|es|s|ment)$','processing')
#将上面的正则表达式改为不想选择要输出的字符串
re.findall(r'^.*(?:ing|ly|ed|ious|ies|ive|es|s|ment)$)','processing')
#将单词分为词干和后缀,但是正则表达式的".*"部分会尽可能多的匹配输入的字符串
re.findall(r'^(.*)(ing|ly|ed|ious|ies|ive|es|s|ment)$','processing')
#在*后加上?使得正则表达式不会尽可能多的匹配输入的字符串
re.finall(r'^(.*?)(ing|ly|ed|ious|ies|ive|es|s|ment)$','processing')

尖括号用于标记标识符的边界,尖括号之间的所有空白都被忽略(这只对NLTK 中的findall()方法处理文本有效)
<.*>,它将匹配所有单个标识符

from nltk.corpus import gutenberg,nps_chat
moby=nltk.Text(gutenberg.words('melville-moby_dick.txt'))
#输出中间的词
moby.findall(r"<a>(<.*>)<man>")
#输出 x x bro
chat=nltk.Text(nps_chat.words())
chat.findall(r"<.*><.*><bro>")
#输出as x as y
chat.findall(r"<as><.*><as><.*>")
输出长度≥3的所有单词由l开头的短语
chat.findall(r"<l.*>{3,}")
#输出x and other y的短语,可以从中找出x的上位词是y
from nltk.corpus import brown
hobby=nltk.Text(brown.words(categories=['hoobies','learned']))
hobby.findall(r"<\w*><and><other><\w*s>")

3.6词形规范化
WordNet 词形归并器删除词缀产生的词都是在它的字典中的词。这个额外的检查过程使
词形归并器比刚才提到的词干提取器要慢。请注意,它并没有处理“lying”,但它将“wom
en”转换为“woman”。
另一个规范化任务涉及识别非标准词,包括数字、缩写、日期以及任何此
类标识符到一个特殊的词汇的映射。
词干提取器

raw = """DENNIS: Listen, strange women lying in ponds distributing
   swords is no basis for a system of government. Supreme executive powe
   r derives from a mandate from the masses, not from some farcical aquat
    ic ceremony."""
tokens=nltk.word_tokenize(raw)
[porter.stem(t) for t in tokens]
[lancaster.stem(t) for t in tokens]

Porter词干提取器
class IndexedText(object):
def __init__(self, stemmer, text):
    self._text = text
    self._stemmer = stemmer
    self._index = nltk.Index((self._stem(word), i)
            for (i, word) in enumerate(text))
def concordance(self, word, width=40):
    key = self._stem(word)
    wc = width/4 # words of context
    for i in self._index[key]:
        lcontext = ' '.join(self._text[i-wc:i])
        rcontext = ' '.join(self._text[i:i+wc])
        ldisplay = '%*s' % (width, lcontext[-width:])
        rdisplay = '%-*s' % (width, rcontext[:width])
        print ldisplay, rdisplay
def _stem(self, word):
    return self._stemmer.stem(word).lower()
    
   
porter=nltk.PorterStemmer()
grail=nltk.corpus.webtext.words('grail.txt')
text=IndexedText(porter,grail)



wnl=nltk.WordNetLemmatizer()
[wnl.lemmatizer(t) for t in tokens]

3.7 用正则表达式为文本分词
re 库内置的缩写“\s”,它表示匹配所有空白字符。
“\S”是“\s”的补
用Python 提供给我们的字符类“\w”匹配词中的字符,相当于[a-zA-Z0-9_]。
也定义了这个类的补“\W”即所有字母、数字和下划线以外的字符。
\b 词边界(零宽度)
\d 任一十进制数字(相当于[0-9])
\D 任何非数字字符(等价于\(\[^0-9]\)

re.split(r'[ \t\n]+',raw)
re.split(r'\s+',raw)

正则表达式分词器

text = 'That U.S.A. poster-print costs $12.40...'
pattern=r'\S+'#自定义的正则表达式
nltk.regexp_tokenize(text,pattern)
posted @ 2020-04-03 15:39  鹤花之歌  阅读(340)  评论(0编辑  收藏  举报