Python中文自然语言处理

发布于 22 天前  29 次阅读


NLP的理解

NLP的全称为Natural Language Understanding,也就是自然语言理解,可用于机器翻译、信息检索、文本分类等等应用,包括先前的聊天情感分析也是的。

Anaconda

Anaconda为一个开源的python发行版本,内含各种代码库和数学库。以下代码使用Spyder编写。

虚拟环境的创建

所有虚拟环境的下载在软件Anaconda Prompt中完成。

第一步:根据下载的python版本创建虚拟环境

本篇默认使用3.12.6的python版本,可根据自己的电脑python版本进行替换

在Anaconda Prompt中输入以下命令查看现在电脑的python版本:

python --version

返回Python 3.12.6,继续输入以下命令:

conda create -n NLP python=3.12.6 # 这里的python后接查看的版本数字

第二章

以下为肖刚主编的Python中文自然语言处理教程的实践第二章操作,但是说实话这个上面的代码有问题的部分比较多,可能是因为编写的环境和库的迭代导致的。

nltk使用代码

# In[1] 引入
from nltk.book import text1
from nltk.book import *
# In[2] 搜索与pretty相似的词汇
text1.similar('pretty')
# In[3] 指定搜索danger词汇文本
text1.concordance(word='danger')
# In[4] 统计文本长度
len(text1)
# In[5] 展示文本中多次出现的搭配词语
text1.collocations()
# In[6] 搜索词的共同上下文
text1.common_contexts(['monstrous','very'])
# In[6] 获取文本的词汇表
set(text1)
# In[7] 按照英文字母排序
sorted(set(text1)) # 词汇表排序
len(set(text1)) # 词汇表大小
len(text1)/len(set(text1)) # 每个词平均使用的次数
# In[8] 查询词汇频数分布
fdist = FreqDist(text1) # 查询文本中的词汇频数分布
fdist['ship'] # ship出现的次数
voc = fdist.most_common(10) # 出现频率最高的十个词
# In[9] 按照英文字母进行排序
len(text1) # 词汇表从头到尾的长度,包括文本text1中出现的词和标点符号
sorted(set(text1)) # 获取文本text1的词汇表,并且按照英文字母排序
len(set(text1)) # 获取文本text1词汇表的数量
len(text1)/len(set(text1)) # 每个词平均使用次数

词汇分布情况

# In[1] 引入
from nltk.book import text1
from nltk.book import *
# In[2] 搜索与pretty相似的词汇
text1.similar('pretty')
# In[3] 指定搜索danger词汇文本
text1.concordance(word='danger')
# In[4] 统计文本长度
len(text1)
# In[5] 展示文本中多次出现的搭配词语
text1.collocations()
# In[6] 搜索词的共同上下文
text1.common_contexts(['monstrous','very'])
# In[6] 获取文本的词汇表
set(text1)
# In[7] 按照英文字母排序
sorted(set(text1)) # 词汇表排序
len(set(text1)) # 词汇表大小
len(text1)/len(set(text1)) # 每个词平均使用的次数
# In[8] 查询词汇频数分布
fdist = FreqDist(text1) # 查询文本中的词汇频数分布
fdist['ship'] # ship出现的次数
voc = fdist.most_common(10) # 出现频率最高的十个词
# In[9] 按照英文字母进行排序
len(text1) # 词汇表从头到尾的长度,包括文本text1中出现的词和标点符号
sorted(set(text1)) # 获取文本text1的词汇表,并且按照英文字母排序
len(set(text1)) # 获取文本text1词汇表的数量
len(text1)/len(set(text1)) # 每个词平均使用次数

累积频率分布图

import matplotlib.pyplot as plt
from nltk.book import *

plt.rcParams['font.sans-serif'] = 'SimHei' # 设置可显示中文
plt.rcParams["axes.unicode_minus"] = False

plt.grid() # 绘制网格
fdist = FreqDist(text1) # 书上缺少,用于统计词频
fdist1 = dict(fdist) # 创建词典,用于收录统计的词频数
fdist1 = sorted(fdist.items(), key = lambda x:x[1], reverse=True) 
# 对fdist根据词频升序排列,key为比较对象,reserve为是否使用升序排序

x = [] # x表示词汇
y = [] # y表示对应的数量
for i in range(10):
    x.append(fdist1[i][0]) # 在x数组中向后添加元素fdist1[i][0]
    y.append(fdist1[i][1]) # 在y数组中向后添加元素fdist1[i][1]

t = 0
for i in range(len(y)):
    y[i] = y[i]+t
    t = y[i]
# 上段的for用于平均划分y轴

plt.plot(x, y)
plt.title('常用词累计频率图')
plt.ylabel('累计频率')
plt.xlabel('常用词')
plt.show()
# 绘制图像

古腾堡语料库

import nltk
nltk.corpus.gutenberg.fileids() #获取古腾堡语料库文本
# In[1] 打开文件并且统计词数
emma = nltk.corpus.gutenberg.words('austen-emma.txt') # 打开古腾堡语料库的一个文本
print(emma)
len(emma)
# In[2] 索引文本
emma = nltk.Text(nltk.corpus.gutenberg.words('austen-emma.txt'))
emma.concordance('surprise')
# In[3] 获取古腾堡语料库中的所有文本及其统计信息
from nltk.corpus import gutenberg # 加载古腾堡语料库
for fileid in gutenberg.fileids():
    raw = gutenberg.raw(fileid) # 给出原始内容
    num_chars = len(raw) # 计算文本长度
    
    words = gutenberg.words(fileid) # 获取文本的词
    num_words = len(words) # 计算词数
    
    sents = gutenberg.sents(fileid) # 获取文本的句子
    num_sents = len(sents) #计算句子的数量
    
    vocab = set([w.lower() for w in gutenberg.words(fileid)])
    num_vocab = len(vocab)
    print('%d %d %d %s' % (num_chars, num_words, num_sents, fileid))
# In[3] 获取网络聊天文本
from nltk.corpus import webtext # 加载网络聊天语料库
for fileid in webtext.fileids():
    print((fileid,webtext.raw(fileid)))
# In[4] 查看网络聊天文本信息
for fileid in webtext.fileids():
    print(fileid, len(webtext.raw(fileid)),len(webtext.words(fileid)),
          len(webtext.sents(fileid)))
# In[5] 获取即时消息聊天会话语料库
from nltk.corpus import nps_chat # 加载即时消息聊天会话语料库
chatroom1 = nps_chat.posts('11-08-adults_705posts.xml')
chatroom2 = nps_chat.posts('10-19-20s_706posts.xml')
print(chatroom1[135])
print(chatroom2[123])

布朗语料库

from nltk.corpus import brown
from nltk.book import *
# In[1] 查看语料
print(brown.categories()) #查看类别
print(brown.words(categories='news')) # 查看news类别里的词
print(brown.words(fileids=['cb15'])) # 查看cb15文件里的词
print(brown.sents(categories=['news','editorial','reviews'])) #查看句子
# In[2] 比较不同文体之间情态动词的用法
news_texts = brown.words(categories='news')
fdist = nltk.FreqDist([w.lower() for w in news_texts]) # w.lower将词汇转化为小写
modals = ['can','could','may','might','must','will']
for m in modals:
    print('%s: %d' %(m, fdist[m]))

路透社语料库

from nltk.corpus import reuters #加载路透社语料库
# In[1] 查看语料文档编号
reuters.categories() # 查看分类
len(reuters.categories())
reuters.fileids()
len(reuters.fileids())
print(reuters.fileids()[:5]) # 查看前五个文档
# In[2] 查看某编号下的语料信息
reuters.categories('test/14832')
# In[3] 查看指定类别下的编号文件
print(reuters.fileids(['barley','corn']))

就职演讲语料库

import nltk
from nltk.corpus import inaugural # 加载就职演说语料库
# In[1] 查看语料信息
len(inaugural.fileids()) # 查看文本个数
inaugural.fileids()
# In[2] 提取年份
print([fileid[:4] for fileid in inaugural.fileids()])
# In[]
# 获取语料库
from nltk.corpus import inaugural
import matplotlib.pyplot as plt

print(inaugural.fileids())
# 每个文本的年代都出现在他的文件名中。要从文件名中提取出年代,只需要使用fileid[:4]即可。
for fileid in inaugural.fileids():
    print(fileid[:4])
# 看看‘American’和‘citizen’随着时间推移的使用情况。
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 ['citizen','free']
                            if w.lower().startswith(target) )
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置可中文显示
plt.grid()
tt = ['citizen','free']
style = ['--','-']
for j,k in zip(tt,style):
    fdist = dict(cfd[j])
    fdist = sorted(fdist.items(),key = lambda x:x[0])
    x = []
    y = []
    for i in range(len(fdist)):
        x.append(fdist[i][0])
        y.append(fdist[i][1])
    x = list(map(lambda i:eval(i), x))
    plt.plot(x, y, linestyle=k, label = j)
    plt.xlabel('年份')
    plt.ylabel('计数')
    plt.legend()
plt.show()

查找书籍

# =============================================================================
# 注意:langconv需要另外下载 在Anaconda prompt中输入
# ## pip install langconv ##
# 需要翻墙!!!
# 另外,由于网站的变化,选取内容和书上不一样
# =============================================================================
# In[0]
from urllib.request import urlopen
# In[0] 配置语言转换,参考网址如下:
### https://pypi.org/project/langconv/ ###
from langconv.converter import LanguageConverter
from langconv.language.zh import zh_cn
lc_cn = LanguageConverter.from_language(zh_cn)
# In[1] 查找西游记内容
html1 = urlopen(url='https://www.gutenberg.org/cache/epub/23962/pg23962.txt').read()
html1 = html1.decode('utf-8')
lc_cn.convert(html1[2200:2384])
# In[2] 查找红楼梦内容
html1 = urlopen(url='https://www.gutenberg.org/cache/epub/24264/pg24264.txt').read()
html1 = html1.decode('utf-8')
lc_cn.convert(html1[2220:2670])

获取网络在线语料库文本


# In[0]
from urllib.request import urlopen
# In[0] 配置语言转换,参考网址如下:
### https://pypi.org/project/langconv/ ###
from langconv.converter import LanguageConverter
from langconv.language.zh import zh_cn
lc_cn = LanguageConverter.from_language(zh_cn)
# In[1] 查看三国志文本
text1 = urlopen(url='https://www.gutenberg.org/cache/epub/25606/pg25606.txt').read()
text1 = text1.decode('utf-8')
len(text1) # 查看文本长度
lc_cn.convert(text1[657:999])
# In[1] 查看窦娥冤文本
text2 = urlopen(url='https://www.gutenberg.org/cache/epub/25606/pg25606.txt').read()
text2 = text2.decode('utf-8')
len(text2) # 查看文本长度
lc_cn.convert(text2[657:1300])

语料库的构建与应用

# =============================================================================
# 由于这本书没有提供金庸小说的下载地址
# 只能自己下载了,这里我使用的小说下载网址如下:
# http://www.janpn.info/
# 不一定长期有效,注意自己更换自己下载的小说!
# =============================================================================
# In[0]
import nltk
from nltk.book import *
from nltk.corpus import PlaintextCorpusReader
# In[1] 获取保存的文件列表
corpus_root ='G:/桌面/pyhon/txtdata' # 这里的引号内防止下载的小说存放目录
### 注意,目录中的 / 要改成 \
wordlists = PlaintextCorpusReader(corpus_root, '.*')
wordlists.fileids() # 获取文件列表
# In[2] 统计金庸作品语料中总词量和平均每个词的使用次数
### 下面语句中参考链接:https://blog.csdn.net/qq_42008430/article/details/105300096
with open('G:/桌面/pyhon/txtdata/金庸作品全集精排(三联版).txt', 
          encoding='utf-8') as f:
    str = f.read() # 读取文本
    len(set(str)) # 统计总用词量
    len(str)/len(set(str)) # 统计平均每个词的使用次数
print(len(set(str))) # 输出总用词量
print(len(str)/len(set(str)))
# In[3] 查看小龙女
print('小龙女,杨过,雕,侠分别出现以下次数:')
print(str.count('小龙女'))
print(str.count('杨过'))
print(str.count('雕'))
print(str.count('侠'))
# In[4] 查看部分文本
str[53940:54400]
# In[5] 统计并输出前30个高频词和高频标识符次数
fdist = FreqDist(str)
print(fdist.most_common(30))
# In[6] 查询指定区间的词汇的数量
from collections import Counter
W = Counter(str)
print('词频在0~99的词数量为:',len([w for w in W.values() if w < 100]))
print('词频在100~999的词数量为:',len([w for w in W.values() if w >= 100 
                           and w < 1000]))
print('词频在1000~4999的词数量为:',len([w for w in W.values() if w >= 1000
                           and w < 5000]))
print('词频在5000以上:',len([w for w in W.values() if w > 5000]))
# In[7] 利用jieba分词
# =============================================================================
# 因为用到jieba
# 在Anaconda Promp里输入以下命令:
# pip install jieba
# =============================================================================
import re
import jieba
print(str)
cleaned_data = ''.join(re.findall('[\u4e00-\u9fa5]',str))
wordlist = jieba.lcut(cleaned_data) # 结巴分词处理
text = nltk.Text(wordlist)
print(text)
# In[8] 查看指定单词上下文
text.concordance(word='侠', width=30, lines=10)
# In[9] 搜索相似的词语
text.similar(word='李莫愁', num = 10)
# In[10] 绘制词汇离散图
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['font.sans-serif'] = ['SimHei']
words = ['小龙女', '杨过', '郭靖', '黄蓉']
nltk.draw.dispersion.dispersion_plot(text, words, title='词汇离散图')
plt.show()