生猪市场数据分析(四):基于无监督学习构建LSTM模型用于咨询分类

import numpy as np
import matplotlib.pylab as plt
import re
import jieba
import bz2
from sklearn.model_selection import train_test_split
from gensim.models import word2vec,KeyedVectors
import os
import pandas as pd

from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers import Dense,GRU,Embedding,LSTM,Bidirectional
from tensorflow.python.keras.preprocessing.text import Tokenizer
from tensorflow.python.keras.preprocessing.sequence import pad_sequences
from tensorflow.python.keras.optimizers import RMSprop,Adam
from tensorflow.python.keras.callbacks import EarlyStopping,ModelCheckpoint,TensorBoard,ReduceLROnPlateau
def clean_text(text):
   text = text.replace('\n','')
   text = re.sub('\d.?-\d.?-\d.?','',text)
   text = re.sub('\s','',text)
   text = re.sub('\d.?','',text)
   text = re.sub('\.','',text)
   text = re.findall('[\u4e00-\u9fa5]',text)
   text = (''.join(text))
   return text
fileList = os.listdir('../生猪市场资讯/猪价格网')

stop_words = pd.read_table('stopwords.txt',sep='\t',encoding='utf-8')
doc = []

for file in fileList:
    try:
        da1 = pd.read_table('../生猪市场资讯/猪价格网/'+file)
        d = da1.iloc[:,0].tolist()
        text=(''.join(d))
        doc.append(text)
    except:
        print(file)
fileList = os.listdir('../生猪市场资讯')

stop_words = pd.read_table('stopwords.txt',sep='\t',encoding='utf-8')
for file in fileList:
    try:
        da1 = pd.read_table('../生猪市场资讯/'+file)
        d = da1.iloc[:,0].tolist()
        text=(''.join(d))
        doc.append(text)
    except:
        print(file)
  • 分词并去除停用词
cn_model = KeyedVectors.load_word2vec_format('sgns.financial.bigram',binary=False,unicode_errors="ignore")

doc_tokens = []
for t in doc:
    text = clean_text(t)
    text_s = jieba.cut(text)
    text_clean = [word for word in text_s if word not in stop_words.aboard.tolist()]
    cut_list = [i for i in text_clean]
    for i,word in enumerate(cut_list):
        try:
            cut_list[i]=cn_model.vocab[word].index
        except KeyError:
            cut_list[i] = 0
    doc_tokens.append(cut_list)
  • 分析句子长度,通过分析句子长度分布情况获取较为合理的句子长度
    因为词向量模型的训练数据并非全部来自于养殖行业咨询数据,对于一些特定的词并没有纳入词向量模型,未剔除误差,剔除文本tokens<50的文本。
#处理token较小的部分:计数<50
doc_tokens_delete=[]
num_tokens=[len(tokens) for tokens in doc_tokens]
num_tokens = np.array(num_tokens)
for i in range(len(doc_tokens)):
   if num_tokens[i] < 50:
       doc_tokens_delete.append(i)

doc_tokens_new=np.delete(doc_tokens,doc_tokens_delete)
``
num_tokens_new=[len(tokens) for tokens in doc_tokens_new]
num_tokens_new = np.array(num_tokens_new)

plt.hist(np.log(num_tokens_new),bins=100)

在这里插入图片描述
从文本tokens分布情况来看,其分布近似于正态分布,因此利用区间估计知识,将最大的文本tokens设置为:
max_tokens = int(np.mean(num_tokens_new) + 2*np.std(num_tokens_new))

  • 修剪文本词库
#padding(填充)与 truncating(修剪)
doc_pad = pad_sequences(doc_tokens_new,maxlen=max_tokens,padding='pre',truncating='pre')
doc_pad[doc_pad>=num_words]=0
  • 聚类分析并可视化
    利用k-means算法将文本聚类分类为2类,并通过利用PCA降维将文本tonkens文本数据降维为两维,绘制散点图可视化。
#聚类分析
#聚类
#1.1 k-means
from sklearn import cluster
model_cluster = cluster.KMeans(n_clusters=2)
doc_label = model_cluster.fit(doc_pad)


# In[128]:


#聚类分析可视化
from sklearn.decomposition import PCA
model_pca = PCA(n_components=2)
model_pca.fit(doc_pad)
x=model_pca.transform(doc_pad)
x2 = []
x1=[]
for i in x:
    x1.append(i[0])
    x2.append(i[1])


# In[129]:


import matplotlib.pyplot as plt
import seaborn as sns
color = {0:'red',1:'blue'}
plt.scatter(x1,x2,color=[color[i] for i in doc_label.labels_],alpha=0.6)

在这里插入图片描述
通过上图可视化的结果来看,聚类的效果还是比较明显的,这也为后面训练LSTM模型打下了基础。

  • 构建LSTM模型

  • 构建词向量层
    这里的目的利用文本tokens在词向量模型里面反向查找各个词的向量表示。

#构建embedding marrix
embedding_dim = 300
num_words = 50000
embedding_matrix = np.zeros((num_words,embedding_dim))

for i in range(num_words):
    embedding_matrix[i,:] = cn_model[cn_model.index2word[i]]
embedding_matrix = embedding_matrix.astype('float32')
#构建词向量层、LSTM层、全连接层
model = Sequential()
model.add(Embedding(num_words,embedding_dim,weights=[embedding_matrix],input_length=max_tokens,trainable=False))
model.add(Bidirectional(LSTM(units=64, return_sequences=True)))
model.add(LSTM(units=16, return_sequences=False))
model.add(Dense(1,activation='sigmoid'))
optimizer = Adam(lr=1e-3)
model.compile(loss='binary_crossentropy',metrics=['accuracy'])
model.summary()

模型框架如下图,可以看见参数主要用于词向量层。
在这里插入图片描述

-构建权重存储点及训练停止条件并训练模型
采用十折交叉验证,训练20轮,步长为128.

#建立一个权重的存储点
path_checkpoint = 'sentiment_checkpoin.keras'
checkpoint = ModelCheckpoint(filepath=path_checkpoint,monitor='')

try:
    model.load_weightsweights(path_checkpoint)
except Exception as e:
    print(e)
    
earlystopping = EarlyStopping(monitor='val_loss',patience=5,verbose=1)
lr_reduction=ReduceLROnPlateau(monitor='val_loss',factor=0.1,min_lr=1e-8,patience=0,verbose=1)
callbacks=[earlystopping,checkpoint,lr_reduction]

#training: 7:3的比例划分测试集和验证集
(doc_pad_train ,doc_pad_test,doc_label_train,doc_label_test) = train_test_split(doc_pad,doc_label.labels_,test_size=0.3)
model.fit(doc_pad_train,doc_label_train,validation_split=0.1,epochs=20,batch_size=128,callbacks=callbacks)

训练过程如下图所示

  • 验证
    模型结果输出为一个概率值,在此我们认为result<0.5即为属于分类集0类,反之即为分类集1类。
result=model.predict(doc_pad_test)
for i in range(len(result)):
    if result[i]< 0.5:
        result[i] = 0
    else:
        result[i] =1    
acc=0
for i in range(len(doc_pad_test)):
    if doc_label_test[i] == result[i]:
        acc +=1
acc/300

从最后的准确率来看,LSTM模型准确率可达97%,模型的结果可观。

  • 03结语

  • 农业领域开展人工智能技术应用尚处于起步阶段,缺少数据集,只能寄希望与其他领域已经开放的标准数据集或者预训练模型;

  • 本项目采用聚类的方式获得样本集的原始标签,可解释性较差,后续将利用其他行业已有的用于文本分类或者情感分析的标准数据集 ,探索建议迁移学习模型的可能。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值