TensorFlow练习1: 对评论进行分类
来源:互联网 发布:阿里云服务器空间清理 编辑:程序博客网 时间:2024/05/22 06:44
本帖展示怎么使用TensorFlow实现文本的简单分类,判断评论是正面的还是负面的。
使用的数据集
- neg.txt:5331条负面电影评论(http://blog.topspeedsnail.com/wp-content/uploads/2016/11/neg.txt)
- pos.txt:5331条正面电影评论 (http://blog.topspeedsnail.com/wp-content/uploads/2016/11/pos.txt)
由于处理的是字符串,我们首先要想方法把字符串转换为向量/数字表示。一种解决方法是可以把单词映射为数字ID。
第二个问题是每行评论字数不同,而神经网络需要一致的输入(其实有些神经网络不需要,至少本帖需要),这可以使用词汇表解决。
代码部分:安装nltk(自然语言工具库 Natural Language Toolkit)
pip install nltk
下载nltk数据:
控制台输入 python,然后输入以下命令。
>>> import nltk
>>> nltk.download()
等待其安装完成;测试:
>>> from nltk.corpus import brown
>>> brown.words()
['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...]
检测代码:
#coding=utf-8import numpy as npimport tensorflow as tfimport randomimport cPicklefrom collections import Counterimport nltkfrom nltk.tokenize import word_tokenize"""'I'm super man'tokenize:['I', ''m', 'super','man' ]"""from nltk.stem import WordNetLemmatizer"""词形还原(lemmatizer),即把一个任何形式的英语单词还原到一般形式,与词根还原不同(stemmer),后者是抽取一个单词的词根。"""pos_file = 'pos.txt'neg_file = 'neg.txt'# 创建词汇表def create_lexicon(pos_file, neg_file): lex = [] # 读取文件 def process_file(f): with open(pos_file, 'rb') as f: lex = [] lines = f.readlines() # print(lines) for line in lines: words = word_tokenize(line.lower()) lex += words return lex lex += process_file(pos_file) lex += process_file(neg_file) # print(len(lex)) lemmatizer = WordNetLemmatizer() lex = [lemmatizer.lemmatize(word) for word in lex] # 词形还原 (cats->cat) word_count = Counter(lex) # print(word_count) # {'.': 13944, ',': 10536, 'the': 10120, 'a': 9444, 'and': 7108, 'of': 6624, 'it': 4748, 'to': 3940......} # 去掉一些常用词,像the,a and等等,和一些不常用词; 这些词对判断一个评论是正面还是负面没有做任何贡献 lex = [] for word in word_count: if word_count[word] < 2000 and word_count[word] > 20: # 这写死了,好像能用百分比 lex.append(word) # 齐普夫定律-使用Python验证文本的Zipf分布 http://blog.topspeedsnail.com/archives/9546 return lexlex = create_lexicon(pos_file, neg_file)# lex里保存了文本中出现过的单词。# 把每条评论转换为向量, 转换原理:# 假设lex为['woman', 'great', 'feel', 'actually', 'looking', 'latest', 'seen', 'is'] 当然实际上要大的多# 评论'i think this movie is great' 转换为 [0,1,0,0,0,0,0,1], 把评论中出现的字在lex中标记,出现过的标记为1,其余标记为0def normalize_dataset(lex): dataset = [] # lex:词汇表;review:评论;clf:评论对应的分类,[0,1]代表负面评论 [1,0]代表正面评论 def string_to_vector(lex, review, clf): words = word_tokenize(line.lower()) lemmatizer = WordNetLemmatizer() words = [lemmatizer.lemmatize(word) for word in words] features = np.zeros(len(lex)) for word in words: if word in lex: features[lex.index(word)] = 1 # 一个句子中某个词可能出现两次,可以用+=1,其实区别不大 return [features, clf] with open(pos_file, 'r') as f: lines = f.readlines() for line in lines: one_sample = string_to_vector(lex, line, [1, 0]) # [array([ 0., 1., 0., ..., 0., 0., 0.]), [1,0]] dataset.append(one_sample) with open(neg_file, 'r') as f: lines = f.readlines() for line in lines: one_sample = string_to_vector(lex, line, [0, 1]) # [array([ 0., 0., 0., ..., 0., 0., 0.]), [0,1]]] dataset.append(one_sample) # print(len(dataset)) return datasetdataset = normalize_dataset(lex)random.shuffle(dataset)"""#把整理好的数据保存到文件,方便使用。到此完成了数据的整理工作with open('save.cPickle', 'wb') as f:cPickle.dump(dataset, f)"""# 取样本中的10%做为测试数据test_size = int(len(dataset) * 0.1)dataset = np.array(dataset)train_dataset = dataset[:-test_size]test_dataset = dataset[-test_size:]# Feed-Forward Neural Network# 定义每个层有多少'神经元''n_input_layer = len(lex) # 输入层n_layer_1 = 1000 # hide layern_layer_2 = 1000 # hide layer(隐藏层)听着很神秘,其实就是除输入输出层外的中间层n_output_layer = 2 # 输出层# 定义待训练的神经网络def neural_network(data): # 定义第一层"神经元"的权重和biases layer_1_w_b = {'w_': tf.Variable(tf.random_normal([n_input_layer, n_layer_1])), 'b_': tf.Variable(tf.random_normal([n_layer_1]))} # 定义第二层"神经元"的权重和biases layer_2_w_b = {'w_': tf.Variable(tf.random_normal([n_layer_1, n_layer_2])), 'b_': tf.Variable(tf.random_normal([n_layer_2]))} # 定义输出层"神经元"的权重和biases layer_output_w_b = {'w_': tf.Variable(tf.random_normal([n_layer_2, n_output_layer])), 'b_': tf.Variable(tf.random_normal([n_output_layer]))} # w·x+b layer_1 = tf.add(tf.matmul(data, layer_1_w_b['w_']), layer_1_w_b['b_']) layer_1 = tf.nn.relu(layer_1) # 激活函数 layer_2 = tf.add(tf.matmul(layer_1, layer_2_w_b['w_']), layer_2_w_b['b_']) layer_2 = tf.nn.relu(layer_2) # 激活函数 layer_output = tf.add(tf.matmul(layer_2, layer_output_w_b['w_']), layer_output_w_b['b_']) return layer_output# 每次使用50条数据进行训练batch_size = 50X = tf.placeholder('float', [None, len(train_dataset[0][0])])# [None, len(train_x)]代表数据数据的高和宽(矩阵),好处是如果数据不符合宽高,tensorflow会报错,不指定也可以。Y = tf.placeholder('float')# 使用数据训练神经网络def train_neural_network(X, Y): predict = neural_network(X)#得到预测结果(通过神经网络) cost_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(predict, Y))#定义损失函数 optimizer = tf.train.AdamOptimizer().minimize(cost_func) # learning rate 默认 0.001 epochs = 13#13次整体迭代 with tf.Session() as session: session.run(tf.initialize_all_variables()) epoch_loss = 0 i = 0 random.shuffle(train_dataset)#数据集随机 train_x = dataset[:, 0]#train_x train_y = dataset[:, 1]#标签 #训练过程 for epoch in range(epochs): while i < len(train_x): start = i end = i + batch_size#训练了一个batch大小 batch_x = train_x[start:end] batch_y = train_y[start:end] _, c = session.run([optimizer, cost_func], feed_dict={X: list(batch_x), Y: list(batch_y)}) epoch_loss += c#一个epoch内一个batch的损失 i += batch_size#下一个开始位置 print(epoch, ' : ', epoch_loss)#输出 所有数据后的一次迭代 text_x = test_dataset[:, 0]#测试数据 text_y = test_dataset[:, 1]#标签 correct = tf.equal(tf.argmax(predict, 1), tf.argmax(Y, 1)) accuracy = tf.reduce_mean(tf.cast(correct, 'float')) print('准确率: ', accuracy.eval({X: list(text_x), Y: list(text_y)}))train_neural_network(X, Y)
执行结果:
这个结果,说明效率并不高,当然你每次运行时结果是不一样的,但最高也就70%+。
那么问题出在哪呢?
准确率低主要是因为数据量太小,同样的模型,如果使用超大数据训练,准确率会有显著的提升。
下文我会使用同样的模型,但是数据量要比本文使用的多得多,看看准确率能提高多少。由于本文使用的神经网络模型(feed-forward)过于简单,使用大数据也不一定有质的提升,尤其是涉及到自然语言处理。
- TensorFlow练习1: 对评论进行分类
- TensorFlow练习1: 对评论进行分类
- Tensorflow练习1-对评论进行分类
- TensorFlow练习2: 对评论进行分类
- [TensorFlow实战练习]1-对电影评论的分类
- tensorflow练习1:利用神经网络进行分类
- 评论进行分类
- 基于对评论进行分类的持续运行模型
- 利用opencv3读取tensorflow model,对图像进行分类
- Python:用Word2Vec 和 sklearn 对IMDB评论进行分类训练
- 利用tensorflow进行单词分类
- [TensorFlow实战练习]2-对推特数据的情绪分析分类
- 对情况进行分类
- 对数据进行分类
- 对list进行分类
- 用深度神经网络对Iris数据集进行分类的程序--tensorflow
- 使用Tensorflow自定义一个线性分类器用于对“良/恶性乳腺癌肿瘤”进行预测
- 使用TensorFlow双流卷积神经网络对CK+表情数据库进行分类
- C++二维动态数组的创建与删除
- C++ 读写utf-8文件
- SharePoint 部署时报错: 未能提取此解决方案中的cab文件
- 字符串工具类
- 总结2333
- TensorFlow练习1: 对评论进行分类
- kibana3的安装与使用
- PHP面对对象继承练习
- R里面数字取整相关的操作有一组函数: ceiling ;floor;trunc; round; signif
- Objective-C - self关键字和super关键字
- 后台学习研究路线
- ASP.NET MVC4学习1之初次见面,请多关照。
- Android动态加载的类型
- Android 动态设置 ListView 和 GridView 高度