1、概述
在聊天场景中有很多情况下需要对用户的意图进行分析。这些分析功能基本上就是自然语言分类模型的变种。从技术难度上来讲这种模型实现比较简单。但要保证效果主要受一下几个方面的制约。
- 词向量的准确程度
- 语料的多少
- 模型的选择
词向量是一个多维的坐标,用于在高纬度空间中的距离表示两个词之间的相似度。所以词向量能否准确的表示词与其相关词的关系会直接影响到整个神经网络的推理能力,以及对于新预料的预测的准确度。另一方面,由于用户训练的聊天语料并不是很多所以,词向量的准确性如果很好可以很大程度上解决这方面的问题。
用于聊天的语料本很就很难获得,尤其是在垂直领域中中文语料就更难获取。所以语料的获取其实是意图识别模型准确性的重要决定因素。
如果我们将锁定在某一个特殊场景比如,订餐,出行,旅游。在这一类的语言中词的特征就比普通的自然语言处理更加重要。比如如果我们在旅游中出现了“好吃”这样的此那么我的意图往往就是“美食”相关内容。此时上下文的语境对于最终的意图识别与分析其实影响不大,所以在此类模型中个人比较倾向于简单粗暴的一些模型而不是采用RNN这种讲究时序的模型。相比较而言dnn,cnn,deep&wide模型的效果应该会更好一些。当然这只是个人分析,具体的效果还需要在实际场景中去验证。
2、数据处理
在之前的文章中对于dataset读取数据的功能有着非常详细的说明。这里会使用之前的方法直接对数据进行处理。首先,数据以csv格式存储在文本文件中。我们可以先将数据导入到pandas的dataframe当中。对数据的基本情况进行观察。首先读取数据,请参照下面代码:
# 读取数据
import pandas as pd
data = pd.read_csv('data/data.csv',header=None, names=['text','class','classid'])
data.head()
输出效果如下图所示:
在后续的程序中,我们会使用tensorflow的功能直接读取。
2.1 读取数据
由于tensorflow只能处理张量,所以一般情况,我们可以将数据读入到内存中,再将其传递给palceholder变量。但是在数据量很大时就很不方便,并且在数据批量化随机化时也不太容易处理。所以这里读取的方式是直接使用tf读取csv文件的方式读取数据。
1、读取数据。
import tensorflow as tf
import numpy as np
COLUMNS = ['text', 'class','class_id']
dataset = tf.data.TextLineDataset('data/data.csv')
dataset=dataset.map(_parse_csv)
2、编写_parse_csv函数
该函数用于对csv文件逐行进行处理。
def _parse_csv(line):
FIELD_DEFAULTS = [[''], [''],[0]]
fields = tf.decode_csv(line,FIELD_DEFAULTS,name=None,field_delim=',')
features = dict(zip(COLUMNS,fields))
features.pop('class')
return features
可以编写下面代码测试一下读取效果。
import tensorflow as tf
import numpy as np
COLUMNS = ['text', 'class','class_id']
dataset = tf.data.TextLineDataset('data/data.csv')
dataset=dataset.map(_parse_csv)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
value = sess.run(next_element)
print(value['class_id'],value['text'].decode('utf-8'))
输出效果如下图所示:
可以将数据批量化与随机化,请参照如下代码:
import tensorflow as tf
import numpy as np
COLUMNS = ['text', 'class','class_id']
dataset = tf.data.TextLineDataset('data/data.csv')
dataset=dataset.map(_parse_csv)
dataset=dataset.repeat(1000)
dataset=dataset.shuffle(buffer_size=10000)
dataset=dataset.batch(10)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
value = sess.run(next_element)
print(value)
输出效果如下图所示:
3、编写函数转化为词向量_word_embed
请参照如下代码,同时解析csv的相关代码也做了修改:
_word_embed函数
def _word_embed(features):
maxlen =8
features=features.decode('utf-8')
padding = '<PAD>'
train_sentences = []
embeddingUnknown = [0 for i in range(300)]
labels = []
tag = [word for word in jieba.cut(features)]
if len(tag)>maxlen:
tag = tag[0:maxlen]
else:
tag.extend([padding]*(maxlen-len(tag)))
train_sentence = []
for word in tag:
if word in model.wv.vocab:
train_sentence.append(model.wv[word])
else:
train_sentence.append(embeddingUnknown)
return np.array(train_sentence,dtype=np.float32)
_parse_csv函数
def _parse_csv(line):
FIELD_DEFAULTS = [[''], [''],[0]]
fields = tf.decode_csv(line,FIELD_DEFAULTS,name=None,field_delim=',')
features = dict(zip(COLUMNS,fields))
features.pop('class')
y = tf.py_func(_word_embed,[features['text']], [tf.float32])
y = tf.convert_to_tensor(y)
return y,features['class_id']
相关测试函数
from gensim.models import KeyedVectors
import jieba
import tensorflow as tf
import numpy as np
model = KeyedVectors.load('mymodel')
COLUMNS = ['text', 'class','class_id']
dataset = tf.data.TextLineDataset('data/data.csv')
dataset=dataset.map(_parse_csv)
dataset=dataset.repeat(1000)
dataset=dataset.shuffle(buffer_size=10000)
dataset=dataset.batch(2)
iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()
with tf.Session() as sess:
value = sess.run(next_element)
print(value)
输出结果如下图所示: