自然语言处理实战-基于LSTM的藏头诗和古诗自动生成
第一次写也是自己的第一篇博客,分享一下自己做的实验以及遇到的一些问题和上交的结课作业。资源都是开源的,参考文章写的很好,菜鸟的我也能理解。原文链接基于LSTM网络的藏头诗和古诗自动生成(附完整代码和数据)_一路狂奔的猪的博客-CSDN博客_lstm生成唐诗r
如果有问题欢迎大家交流。
一、自然语言处理基础与实战
自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门融语言学、计算机科学、数学于一体的科学。因此,这一领域的研究将涉及自然语言,即人们日常使用的语言,所以它与语言学的研究有着密切的联系,但又有重要的区别。自然语言处理并不是一般地研究自然语言,而在于研制能有效地实现自然语言通信的计算机系统,特别是其中的软件系统。因而它是计算机科学的一部分。
自然语言处理主要应用于机器翻译、舆情监测、自动摘要、观点提取、文本分类、问题回答、文本语义对比、语音识别、中文OCR等方面。自己这学期也上了语音识别课程,后面有时间可以更新一下自己做的语音识别试验。
二、实验
1.中文分词的应用
读取文本,加载停用词,分词,打印样本,分词结果,高频词。代码如下
import jieba
def word_extract():
corpus = []
path = 'D:/python/data/flightnews.txt'
content = ''
for line in open(path, 'r', encoding='utf-8', errors='ignore'):
line = line.strip()
content += line
corpus.append(content)
stop_words = []
path = 'D:/python/data/stopwords.txt'
for line in open(path, encoding='utf-8'):
line = line.strip()
stop_words.append(line)
# jieba分词
split_words = []
word_list = jieba.cut(corpus[0])
for word in word_list:
if word not in stop_words:
split_words.append(word)
dic = {}
word_num = 10
for word in split_words:
dic[word] = dic.get(word, 0) + 1
freq_word = sorted(dic.items(), key = lambda x: x[1],
reverse=True) [: word_num]
print('样本:' + corpus[0])
print('样本分词效果:' + '/ '.join(split_words))
print('样本前10个高频词:' + str(freq_word))
word_extract()
结果展示
2. 词性标注命名体识别
中文命名实体识别的流程,CRF条件随机场命名实体识别的使用。 代码如下
from sklearn_crfsuite import metrics
import joblib
import sklearn_crfsuite
class CorpusProcess(object):
# 由词性提取标签
def pos_to_tag(self, p):
t = self._maps.get(p, None)
return t if t else 'O'
# 标签使用BIO模式
def tag_perform(self, tag, index):
if index == 0 and tag != 'O':
return 'B_{}'.format(tag)
elif tag != 'O':
return 'I_{}'.format(tag)
else:
return tag
#全角转半角
def q_to_b(self, q_str):
b_str = ""
for uchar in q_str:
inside_code = ord(uchar)
if inside_code == 12288: # 全角空格直接转换
inside_code = 32
elif 65374 >= inside_code >= 65281: # 全角字符(除空格)根据关系转化
inside_code -= 65248
b_str += chr(inside_code)
return b_str
# 语料初始化
def initialize(self):
lines = self.read_corpus_from_file(self.process_corpus_path)
words_list = [line.strip().split(' ') for line in lines if line.strip()]
del lines
self.init_sequence(words_list)
# 初始化字序列、词性序列
def init_sequence(self, words_list):
words_seq = [[word.split('/')[0] for word in words] for words in words_list]
pos_seq = [[word.split('/')[1] for word in words] for words in words_list]
tag_seq = [[self.pos_to_tag(p) for p in pos] for pos in pos_seq]
self.tag_seq = [[[self.tag_perform(tag_seq[index][i], w)
for w in range(len(words_seq[index][i]))]
for i in range(len(tag_seq[index]))]
for index in range(len(tag_seq))]
self.tag_seq = [[t for tag in tag_seq for t in tag] for tag_seq in self.tag_seq]
self.word_seq = [['<BOS>'] + [w for word in word_seq for w in word]
+ ['<EOS>'] for word_seq in words_seq]
def segment_by_window(self, words_list=None, window=3):
words = []
begin, end = 0, window
for _ in range(1, len(words_list)):
if end > len(words_list):
break
words.append(words_list[begin: end])
begin = begin + 1
end = end + 1
return words
# 特征提取
def extract_feature(self, word_grams):
features, feature_list = [], []
for index in range(len(word_grams)):
for i in range(len(word_grams[index])):
word_gram = word_grams[index][i]
feature = {'w-1': word_gram[0],
'w': word_gram[1], 'w+1': word_gram[2],
'w-1:w': word_gram[0] + word_gram[1],
'w:w+1': word_gram[1] + word_gram[2],
'bias': 1.0}
feature_list.append(feature)
features.append(feature_list)
feature_list = []
return features
# 训练数据
def generator(self):
word_grams = [self.segment_by_window(word_list) for word_list in self.word_seq]
features = self.extract_feature(word_grams)
return features, self.tag_seq
class CRF_NER(object):
# 初始化CRF模型参数
def __init__(self):
self.algorithm = 'lbfgs'
self.c1 = '0.1'
self.c2 = '0.1'
self.max_iterations = 100 # 迭代次数
self.model_path = 'D:/python/data/model.pkl'
self.corpus = CorpusProcess() # 加载语料预处理模块
self.model = None
# 定义模型
def initialize_model(self):
self.corpus.pre_process() # 语料预处理
self.corpus.initialize() # 初始化语料
algorithm = self.algorithm
c1 = float(self.c1)
c2 = float(self.c2)
max_iterations = int(self.max_iterations)
self.model = sklearn_crfsuite.CRF(algorithm=algorithm, c1=c1, c2=c2,
max_iterations=max_iterations,
all_possible_transitions=True)
# 模型训练
def train(self):
self.initialize_model()
x, y = self.corpus.generator()
x_train, y_train = x[500: ], y[500: ]
x_test, y_test = x[: 500], y[: 500]
self.model.fit(x_train, y_train)
labels = list(self.model.classes_)
labels.remove('O')
y_predict = self.model.predict(x_test)
metrics.flat_f1_score(y_test, y_predict, average='weighted', labels=labels)
sorted_labels = sorted(labels, key=lambda name: (name[1: ], name[0]))
print(metrics.flat_classification_report(
y_test, y_predict, labels=sorted_labels, digits=3))
# 保存模型
joblib.dump(self.model, self.model_path)
def predict(self, sentence):
# 加载模型
self.model = joblib.load(self.model_path)
u_sent = self.corpus.q_to_b(sentence)
word_lists = [['<BOS>'] + [c for c in u_sent] + ['<EOS>']]
word_grams = [
self.corpus.segment_by_window(word_list) for word_list in word_lists]
features = self.corpus.extract_feature(word_grams)
y_predict = self.model.predict(features)
entity = ''
for index in range(len(y_predict[0])):
if y_predict[0][index] != 'O':
if index > 0 and(
y_predict[0][index][-1] != y_predict[0][index - 1][-1]):
entity += ' '
entity += u_sent[index]
elif entity[-1] != ' ':
entity += ' '
return entity
ner=CRF_NER()
sentence1 = '2020年9月23日,’1+X‘证书制度试点第四批职业教育培训评价组织和职业技能等级公证书公示,其中广东泰迪智能' \
'科技股份有限公司申请的大数据应用开发(python)位列其中。'
output1 = ner.predict(sentence1)
print(output1)
import jieba.posseg as psg # 加载jieba库中的分词函数
sent = '我爱黄河科技学院'
for w, t in psg.cut(sent):
print(w, '/', t)
结果展示
3.关键词提取算法
TF-IDF,,extRank,LSI三种算法的实现,以及一些文本预处理的方法。在实验过程中,安装gensim第三方库的时候遇到了一个问题,就是版本不匹配问题,自己搜的别人博客上说的是gensim版本与numpy的版本不匹配,需要把这两个库卸载重新安装就可以了,我试了试还是不行,因为我发现卸载之后重新默认安装的第三方库的版本和之前的版本是一样的。我的python是3.6版本的,但是默认安装的gensim版本是最新的,我的numpy库在之前也是正常使用的,因为不知道版本之间的对应关系在哪里查,就降版本安装,没想到第一次就成功了,我在命令行使用pip命令安装的指定版本gensim3.6。然后就可以运行了。(可能不规范但的确是这样解决的)
上代码
import jieba
import jieba.posseg
import numpy as np
import pandas as pd
import math
import operator
'''
提供Python内置的部分操作符函数,这里主要应用于序列操作
用于对大型语料库进行主题建模,支持TF-IDF、LSA和LDA等多种主题模型算法,提供了
诸如相似度计算、信息检索等一些常用任务的API接口
'''
from gensim import corpora, models
text = '广州地铁集团工会主席钟学军在开幕式上表示,在交通强国战略的指引下,我国城市轨道' \
'交通事业蓬勃发展,城轨线路运营里程不断增长,目前,全国城市轨道交通线网总里程' \
'接近5000公里,每天客运量超过5000万人次。城市轨道交通是高新技术密集型行业,' \
'几十个专业纷繁复杂,几十万台(套)设备必须安全可靠,线网调度必须联动周密,' \
'列车运行必须精准分秒不差。城市轨道交通又是人员密集型行业,产业工人素质的好坏、' \
'高低,直接与人民生命安全息息相关。本届“国赛”选取的列车司机和行车值班员,' \
'正是行业安全运营的核心、关键工种。开展职业技能大赛的目的,就是要弘扬' \
'“工匠精神”,在行业内形成“比、学、赶、帮、超”的良好氛围,在校园里掀起' \
'“学本领、争上游”的学习热潮,共同为我国城市轨道交通的高质量发展和交通强国' \
'建设