目录
实验目的:
加深对汉语文本信息处理基础理论及方法的认识和了解,锻炼和提高分析问题、解决问题的能力。通过对具体项目的任务分析、数据准备、算法设计和编码实现以及测试评价几个环节的练习,基本掌握实现一个自然语言处理系统的基本过程。
实验要求:
1.构建基于逻辑斯蒂回归模型分类模型
2.对实验六中的VSM表示文本进行分类
3.对实验七中基于Word2Vec表示的文本进行分类
4.任意输入一句话,能够对其进行基于Word2Vec的向量表示,并进行分类输出其类别标签。
实验内容及原理:
实验8.1:构建基于逻辑斯蒂回归模型分类模型
实验8.2:对实验六中的VSM表示文本进行分类
实验8.3:对实验七中基于Word2Vec表示的文本进行分类、
实验8.4:任意输入一句话,能够对其进行基于Word2Vec的向量表示,并进行分类输出其类别标签。
对数据集进行划分,对同一批数据进行不同的文本表示方法,输出分类准确率、召回率和F1值,比较两类表示方法的效果差异。
该子任务使用sklearn工具包中的
LogisticRegression模型,要求熟练掌握工具包安装、数据读取、模型训练、结果保存等相关内容。
参考文档: https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression
主要流程:
1)将实验数据集重新随机打乱顺序,分别获得实验六和实验七中的句子表示。
2)调用sklearn.model_selection库的train_test_split方法划分训练集和测试集,要求训练集:测试集=4: 1。
3)调用sklearn.linear_model库的LogisticRegression方法实例化模型对象。
4)调用sklearn.linear_model库的fit方法进行训练、score方法获取在测试集上的分类正确率。
5)使用pickle保存模型文件。
6)调用sklearn. linear_model库的predict方法输出所有测试集的预测标签,并给出其准确率、召回率和F1指标。
7)任意输入一句新的文本,完成分词-文本表示-类别预测全过程。
实验数据说明:
实验数据采用htl_del_4000宾馆情感分析数据进行处理,所有数据已按照情感极性划分为褒(pos)贬(neg)两类,各2000篇,每个文本文件为一篇文章,实验数据需要先进行分词,分词方法不限。
参考代码:
四合一
#实验8全部整合
import csv
import numpy as np
import pandas as pd
import jieba.analyse as ana
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
import pickle
import jieba
path='./中文信息处理技术实验数据/htl_del_4000'
np.set_printoptions(threshold=np.inf)#矩阵完全显示
#输出评价指标
def pingjia6(d,lmodel,x_test):
with open('pred.txt','w+',encoding='utf-8')as f:
f.write("基于VSM文本表示的测试集预测标签:\n")
f.write(str(lmodel.predict(x_test))+'\n')
f.write("基于VSM文本表示的评估指数:"+'\n')
d1 = dict()
for k in range(3):
d.popitem() # 去除后三个指标
for i in d.items():
d1.update(i[1])
d1.popitem() # 去除support
d1["准确率"] = d1.pop("precision")
d1["召回率"] = d1.pop("recall")
d1["F1值"] = d1.pop("f1-score")
f.write(i[0]+' '+str(d1)+'\n')
def pingjia7(d,lmodel,x_test):
with open('pred.txt','a+',encoding='utf-8')as f:
f.write("基于Word2Vec文本表示的测试集预测标签:\n")
f.write(str(lmodel.predict(x_test)) + '\n')
f.write("基于Word2Vec文本表示的评估指数:" + '\n')
d1 = dict()
for k in range(3):
d.popitem() # 去除后三个指标
for i in d.items():
d1.update(i[1])
d1.popitem() # 去除support
d1["准确率"] = d1.pop("precision")
d1["召回率"] = d1.pop("recall")
d1["F1值"] = d1.pop("f1-score")
f.write(i[0]+' '+str(d1)+"\n")
def fun():
print("训练成功")
def fun1():
i=0
if i==0:
pass
#将数据按照文档id提取内容,并返回字符串
def Sread(file):
with open(file,'r',encoding='gbk',errors='ignore') as f:
f.seek(0)
s=f.read().replace('\n','')
return s
def ToCSV6(file1,file2):
with open(file1, 'w', newline='', encoding='utf-8') as cf:
writer = csv.writer(cf)
writer.writerow(["id", "label"])
with open(file2, 'r', encoding='utf-8') as f:
l = f.readlines()
i = 0
for s in l:
l0 = []#存储要写入csv文件的数据
l1 = s.split('\t') # l1[0]为文档id
if i < 2000: # l[0]到l[1999]为neg
p = path + '/neg/' + 'neg.' + l1[0] + '.txt'
l0.append(Sread(p))
l0.append('neg')
i += 1
writer.writerow([l0[0], l0[1]])
else:
p = path + '/pos/' + 'pos.' + l1[0] + '.txt'
l0.append(Sread(p))
l0.append('pos')
i += 1
writer.writerow([l0[0], l0[1]])
def Tocsv7(file1,file2):
with open(file1, 'w', newline='', encoding='utf-8') as cf:
writer = csv.writer(cf)
writer.writerow(["id", "label"])
with open(file2, 'r', encoding='utf-8') as f:
l = f.readlines()
for s in l:
l0 = []#存储要写入csv文件的数据
l1 = s.split(' ')
l2 = l1[0].split('-')
if l1[1] == '0':#neg
p = path + '/neg/' + 'neg.' + l2[0] + '.txt'
with open(p, 'r', encoding='gbk', errors='ignore') as f1:
f1.seek(0)
s = f1.read().replace('.', '。').replace(';', '。').replace('\n', '') # 将. ;转换为。便于分割
l3 = s.split('。')
for j in l3:
if j != '':
l0.append(j)
l0.append('neg')
writer.writerow([l0[0], l0[1]])
l0 = []#重置l0
else:#pos
p = path + '/pos/' + 'pos.' + l2[0] + '.txt'
with open(p, 'r', errors='ignore') as f1:
f1.seek(0)
s = f1.read().replace('.', '。').replace(';', '。').replace('\n', '') # 将. ;转换为。便于分割
l3 = s.split('。')
for j in l3:
if j != '':
l0.append(j)
l0.append('pos')
writer.writerow([l0[0], l0[1]])
l0 = []
def pr():
print('*****************我是分割线**********************')
def flat(l): # 用于将list in list 转为list
for k in l:
if not isinstance(k, (list, tuple)):
yield k
else:
yield from flat(k)
def TrSave6(file1,file2):
#任务1
raw = pd.read_csv(file1, encoding='utf-8')
text = raw["id"].values.tolist()
ana.set_stop_words('cn_stopwords.txt') # 输入停用词
text_list = []
text_list3 = []
for w in text:
word_list = ana.extract_tags(str(w), topK=10000, withWeight=False) # 去除停用词+词频分析
text_list.append(word_list)
for m1 in text_list:
text_list2 = [" ".join(m1)] # 切好的词用空格连接
text_list3.append(text_list2)
text_list4 = list(flat(text_list3))
# TF-IDF
vectorizer = TfidfVectorizer()
wordmtx = vectorizer.fit_transform(text_list4) # fit_transform()的作用就是先拟合数据,然后转化它将其转化为标准形式
# 第一步第二步 分为训练集和测试集 shuffle=True打乱数据集 test_size=0.2测试集占比0.2
x_train, x_test, y_train, y_test = train_test_split(wordmtx, raw["label"],shuffle=True, test_size=0.2, random_state=11)
# 第三步 实例化模型对象
lmodel = LogisticRegression(max_iter=1000)#max_iter=1000设置最大迭代次数,防止保存模型时报错
# 第四步 训练模型
lmodel=lmodel.fit(x_train, y_train)#训练模型
fun()
sc=lmodel.score(x_test, y_test)#获取测试集上的分类正确率
print("基于"+file1.replace('.csv','')+"文本表示测试集上的分类正确率为",sc)
# 第五步 使用pickle保存模型
with open(file2, 'wb') as f:
pickle.dump(lmodel, f)
print("模型已成功保存至" + file2)
#导入模型 #任务2
with open(file2,'rb')as f:
lmodel=pickle.load(f)
print("模型导入成功!")
# 第六步 输出测试集标签以及评价指标
d=classification_report(y_test, lmodel.predict(x_test),output_dict=True)
pingjia6(d,lmodel,x_test)
# # 第七步 输入文本测试
# s = input("输入文本:")
# words = " ".join(jieba.lcut(s))
# words_vecs = vectorizer.transform([words])
# print(file1.replace('.csv','')+"预测为:"+lmodel.predict(words_vecs)[0])
def TrSave7(file1,file2):
#任务1
raw = pd.read_csv(file1, encoding='utf-8')
text = raw["id"].values.tolist()
ana.set_stop_words('cn_stopwords.txt') # 输入停用词
text_list = []
text_list3 = []
for w in text:
word_list = ana.extract_tags(str(w), topK=10000, withWeight=False) # 去除停用词+词频分析
text_list.append(word_list)
for m1 in text_list:
text_list2 = [" ".join(m1)] # 切好的词用空格连接
text_list3.append(text_list2)
text_list4 = list(flat(text_list3))
# TF-IDF
vectorizer = TfidfVectorizer()
wordmtx = vectorizer.fit_transform(text_list4) # fit_transform()的作用就是先拟合数据,然后转化它将其转化为标准形式
# 第一步第二步 分为训练集和测试集 shuffle=True打乱数据集 test_size=0.2测试集占比0.2
x_train, x_test, y_train, y_test = train_test_split(wordmtx, raw["label"],shuffle=True, test_size=0.2, random_state=11)
# 第三步 实例化模型对象
lmodel = LogisticRegression(max_iter=1000)#max_iter=1000设置最大迭代次数,防止保存模型时报错
# 第四步 训练模型
lmodel=lmodel.fit(x_train, y_train)#训练模型
fun()
sc=lmodel.score(x_test, y_test)#获取测试集上的分类正确率
print("基于" + file1.replace('.csv', '') + "文本表示测试集上的分类正确率为", sc)
# 第五步 使用pickle保存模型
with open(file2, 'wb') as f:
pickle.dump(lmodel, f)
print("模型已成功保存至" + file2)
#导入模型 #任务3
with open(file2,'rb')as f:
lmodel=pickle.load(f)
print("模型导入成功!")
# 第六步 输出测试集标签以及评价指标
d=classification_report(y_test, lmodel.predict(x_test),output_dict=True)
pingjia7(d,lmodel,x_test)
print("任务1 2 3完成!")
# 第七步 输入文本测试
#任务4
pr()
s = input("输入文本:")
words = " ".join(jieba.lcut(s))
words_vecs = vectorizer.transform([words])
print("基于"+file1.replace('.csv','')+"表示文本预测为:"+lmodel.predict(words_vecs)[0])
print("任务4完成!")
if __name__ == '__main__':
ToCSV6('VSM.CSV', '6-1.txt')
Tocsv7('Word2Vec.csv', '表示.txt')
TrSave6('VSM.csv','model6.pickle')
pr()
TrSave7('Word2Vec.csv','model7.pickle')