基于词向量word2vec模型的文本分类实现(算例有代码)

词向量

词向量大白话解释:就是一个神经网络。针对一段文本,输入前面几个单词和后面几个单词。输出当前这个单词。然后用神经网络中间层的权重系数来表示输出的这个Y单词。
或者是输入当前这个词,输出它的上下文,我们取出中间层向量即词向量。
词向量是表示文本的一种方式,词汇表中的每个单词由高维空间的实值向量表示。具有相似含义的单词在向量空间中具有相似的表达能力(在向量空间中接近)。
有很多封装好的模块可以帮我们词向量。我们只需将得到的词向量作为我们分类器的输入,来完成文本分类。

算例

数据集
电力95598工单 两行,第一行为类别标签。第二行为工单文本。

本文主要基于95598工单完成文本分类,选取浙江省95598工单数据集3171条。其中的工单可以分类为反映、建议、表扬、举报、投诉、以往业务、查询、报修8个类别。

导入包
采用keras完成模型训练,我比较喜欢keras,TensorFlow不怎么用生疏啦。

import pandas as pd
import numpy as np
import jieba as jb
import re
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import  pad_sequences
from keras .models import  Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers import Embedding
from keras.layers.convolutional import  Conv1D
from keras.layers.convolutional import  MaxPooling1D
import keras
from keras .models import load_model

读取数据

csv='95598.csv'
file_txt=pd.read_csv(csv, header=0,encoding='gbk')#[1169656 rows x 3 columns]

file_txt=file_txt.dropna()#删除空值[1005981 rows x 2 columns]

#添加文字标签
file_txt['biaoqian']=''
file_txt.loc[file_txt['BUSI_TYPE_CODE']==7,'biaoqian']='反映'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==6,'biaoqian']='建议'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==5,'biaoqian']='表扬'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==4,'biaoqian']='举报'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==3,'biaoqian']='投诉'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==2,'biaoqian']='以往业务'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==1,'biaoqian']='查询'
file_txt.loc[file_txt['BUSI_TYPE_CODE']==0,'biaoqian']='报修'
print(file_txt)

去除标点符号和停用词

# 定义删除除字母,数字,汉字以外的所有符号的函数
def remove_punctuation(line):
    line = str(line)
    if line.strip() == '':
        return ''
    rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
    line = rule.sub('', line)
    return line

#停用词
def stopwordslist(filepath):
    stopwords = [line.strip() for line in open(filepath, 'r', encoding='gbk').readlines()]
    return stopwords

# 加载停用词
stopwords = stopwordslist("停用词.txt")

#去除标点符号
file_txt['clean_review']=file_txt['ACCEPT_CONTENT'].apply(remove_punctuation)
#去除停用词
file_txt['cut_review']=file_txt['clean_review'].apply(lambda x:" ".join([w for w in list(jb.cut(x)) if w not in stopwords]))

词向量 预处理来啦
keras 中的词向量层Embedding需要整数输入。
首先我们得将单词映射到整数。
from keras.preprocessing.text import Tokenizer
读取的是所有文本

#将单词编成整数系列
#单词-整数的映射
def create_tokenizer(lines):
	tokenizer=Tokenizer()
	tokenizer.fit_on_texts(lines)
	return  tokenizer
tokenizer=create_tokenizer(file_txt['cut_review'])

填充句子长度
由于每个文本长短不一。我们需要将短文本用0填充,使所有文本长读一致。
找到最大长度的文本单词数 即最大长度

#找到最长句子长度
max_length=max([len(s.split()) for s in file_txt['cut_review']])
print('最长词语 句子:',max_length)#126

填充长度,使长度一致
from keras.preprocessing.sequence import pad_sequences

docs为所有文本
padding='post’为向后填充,即在后面填充0.也有在前面填充0的

单词-整数映射 包含在这个encode_docs函数里啦

#使用tokenizer.text_to_sequences()函数来获取单词-整数编码
#使用pad_sequences 函数来为长度不够的文本进行填0操作,使所有文本长度一致
def encode_docs(tokenizer,max_length,docs):
	encoded=tokenizer.texts_to_sequences(docs)#单词-整数映射
	padded=pad_sequences(encoded,maxlen=max_length,padding='post')
	return padded

输入,输出 处理

X_train=encode_docs(tokenizer,max_length,file_txt['cut_review'])
y_train=file_txt['BUSI_TYPE_CODE']
y_train=np.array(y_train)#(130583, 1)
Y_train=keras.utils.to_categorical(y_train,8)#8分类

查看下X_train

查看下Y_train

定义神经网络模型
用下简单的卷积神经网络。只是演示下词向量文本分类流程,没必要用高级模型

#使用Embedding层作为第一层,需要指定词汇表大小,
实值向量空间的大小以及输入文档的最大长度。词汇表大小是我们词汇表中的单词总数,加上一个未知单词 vocad_size=len(tokenizer.word_index)+1

Embedding(vocad_size,100,input_length=max_length)
vocad_size:为词汇表大小
实值向量空间的大小:取100,即一个单词用100维的“权重”表示。
input_length:输入文本的最大长度。

#定义神经网络模型
"""
#使用Embedding层作为第一层,需要指定词汇表大小,
实值向量空间的额大小以及输入文档的最大长度。词汇表大小是我们词汇表中的单词总数,加上一个未知单词
"""
vocad_size=len(tokenizer.word_index)+1
print('词汇表大小:',vocad_size)#7896

#定义神经网络模型
def define_model(vocad_size,max_length):
	model=Sequential()
	model.add(Embedding(vocad_size,100,input_length=max_length))
	model.add(Conv1D(filters=32,kernel_size=5,activation='relu'))
	model.add(MaxPooling1D(pool_size=2))
	model.add(Flatten())
	model.add(Dense(16,activation='relu'))
	model.add(Dense(8,activation='softmax'))
	model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
	model.summary()
	return model

训练模型

#模型训练
def model_train():
    model = define_model(vocad_size, max_length)
    model.fit(X_train, Y_train, epochs=10, verbose=2)
    model.save('词向量模型分类.h5')
    #model_train()#
model_train()

模型评估

from sklearn.metrics import accuracy_score#分类器评估
model=load_model('词向量模型分类.h5')
predict_y=model.predict(X_train)
pred_y=np.argmax(predict_y,axis=1)
test_y=np.array(file_txt['BUSI_TYPE_CODE'])
f1=accuracy_score(pred_y,test_y)
print(f1)

结果完美

对新的文本进行预测
代码就不写啦,简单写下流程。
1首先准备好一个字典(标签数字:标签文字)方便预测时直接输出文字
2.对输入的文本进行分词,去除停用词,标点符号等操作
3.处理后文本line加上中括号。对文本进行 单词整数映射,填充长度。整个操作包括在了encode_docs()函数里(如果文本比训练集文本最长还长,Keras中pad_sequences会截断,取前面的)
4 模型预测,得到最大数字索引,即类别数字标签
5.查找字典,得到 类别文字。打印

yd_names1 = {'0':'报修','1':'查询','2':'以往业务','3':'投诉','4':'举报','5':'表扬','6':'建议','7':'反映'}

def predict_text(文本,停用词,tokenizer,max_length,model):
    line='对文本进行分词并去除停用词,标点符号后的文本'
    #填充长度,注意line要加[]号括起来。
    padded=encode_docs(tokenizer,max_length,[line])
    y_predict=model.predict(padded,verbose=0)
    pred_y = np.argmax(y_predict, axis=1) #得到的是最大数值索引
    print(yd_names1[pred_y])#获取类型文字信息

基于tf-idf的文本分类见链接
短文本分类:电力95598工单分类实现

tensorflow版词向量分类
word2vec词向量 文本分类实现(TensorFlow版,算法TextCNN)

在这里插入图片描述

电气专业的计算机萌新:余登武,写博文不容易。如果你觉得本文对你有用,请点个赞支持下。谢谢。
在这里插入图片描述

评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

总裁余(余登武)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值