[561]TensorFlow练习1: 对评论进行分类

2023-11-02

TensorFlow是谷歌2015年开源的一个深度学习库,到现在正好一年。和TensorFlow类似的库还有Caffe、Theano、MXNet、Torch。但是论火爆程度,TensorFlow当之无愧,短短一年就在Github就收获了4万+颗星,把前面几个库获得的star加起来也不敌TensorFlow。

TensorFlow使用C++开发,并提供了Python等语言的封装。如命名一样,TensorFlow为张量从图一端流动到另一端的计算过程,可以把张量看作矩阵(矩阵rank为2,Tensor的rank更高)。TensorFlow并不是一个抽象程度特别高的库,但是它实现了所有深度学习所需的函数。貌似有几个高度抽象的库使用TensorFlow做为后端。

TensorFlow可被用于语音识别或图像识别等多项机器深度学习领域,它可在小到手机、大到数千台服务器上运行。

本帖展示怎么使用TensorFlow实现文本的简单分类,判断评论是正面的还是负面的。

使用的数据集

我本想使用Python爬一些淘宝评论,但是脚本做到一半卡壳了,搞得火起。然后我上网找现成的数据,只找到了英文的电影评论数据(其实不管是英文还是中文,处理逻辑都一样)。

TensorFlow练习1: 对评论进行分类

由于处理的是字符串,我们首先要想方法把字符串转换为向量/数字表示。一种解决方法是可以把单词映射为数字ID。

第二个问题是每行评论字数不同,而神经网络需要一致的输入(其实有些神经网络不需要,至少本帖需要),这可以使用词汇表解决。

代码部分

安装nltk(自然语言工具库 Natural Language Toolkit

$  pip install nltk

下载nltk数据:

$ python
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import nltk
>>> nltk.download()

ntlk有详细安装文档。

测试nltk安装:

>>> from nltk.corpus import brown
>>> brown.words()
['The', 'Fulton', 'County', 'Grand', 'Jury', 'said', ...]

Python代码:

# -*- coding:utf-8 -*-
"""
对评论进行分类
"""
import numpy as np
import random,pickle
from collections import Counter
import nltk
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer

# 安装的tensorflow是1.x(1.9.0)版本的下面代码引入,本代码使用1.x版本
# import tensorflow as tf
# 安装的tensorflow是2.x版本的,加入下面代码解决报错
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()


"""
>>> a="I'm super man"
>>> word_tokenize(a)
['I', "'m", 'super', 'man']

词形还原(lemmatizer),即把一个任何形式的英语单词还原到一般形式,与词根还原不同(stemmer),
后者是抽取一个单词的词根。
>>> lemmatizer = WordNetLemmatizer()
>>> lemmatizer.lemmatize('words')
'word'
"""

# 创建词汇表
def create_lexicon(pos_file, neg_file):
    lex = []
    # 读取文件
    def process_file(file):
        with open(file, 'r') 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 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,其余标记为0
def 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 dataset

# 定义待训练的神经网络
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

# 使用数据训练神经网络
def train_neural_network(X, Y):
    predict = neural_network(X)
    cost_func = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=predict,labels=Y))
    optimizer = tf.train.AdamOptimizer().minimize(cost_func)  # learning rate 默认 0.001

    epochs = 13
    with tf.Session() as session:
        # session.run(tf.initialize_all_variables())
        session.run(tf.global_variables_initializer())
        epoch_loss = 0
        i = 0
        random.shuffle(train_dataset)
        train_x = dataset[:, 0]
        train_y = dataset[:, 1]
        for epoch in range(epochs):
            while i < len(train_x):
                start = i
                end = i + batch_size
                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
                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)}))


if __name__=='__main__':
    pos_file = 'pos.txt'
    neg_file = 'neg.txt'
    # lex里保存了文本中出现过的单词。
    lex = create_lexicon(pos_file, neg_file)

    dataset = normalize_dataset(lex)
    random.shuffle(dataset)
    #把整理好的数据保存到文件,方便使用。到此完成了数据的整理工作
    # with open('save.pickle', 'wb') as f:
    # 	pickle.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 layer
    n_layer_2 = 1000  # hide layer(隐藏层)听着很神秘,其实就是除输入输出层外的中间层
    n_output_layer = 2  # 输出层
    # 每次使用50条数据进行训练
    batch_size = 50
    X = tf.placeholder('float', [None, len(train_dataset[0][0])])
    # [None, len(train_x)]代表数据数据的高和宽(矩阵),好处是如果数据不符合宽高,tensorflow会报错,不指定也可以。
    Y = tf.placeholder('float')
    train_neural_network(X, Y)
    

执行结果:

2019-03-13 16:05:31.299662: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
0  :  73450.83477020264
1  :  73450.83477020264
2  :  73450.83477020264
3  :  73450.83477020264
4  :  73450.83477020264
5  :  73450.83477020264
6  :  73450.83477020264
7  :  73450.83477020264
8  :  73450.83477020264
9  :  73450.83477020264
10  :  73450.83477020264
11  :  73450.83477020264
12  :  73450.83477020264
准确率:  0.6726079

准确率才60%多,比瞎猜强点有限。

那么问题出在哪呢?

准确率低主要是因为数据量太小,同样的模型,如果使用超大数据训练,准确率会有显著的提升。

下文我会使用同样的模型,但是数据量要比本文使用的多得多,看看准确率能提高多少。由于本文使用的神经网络模型(feed-forward)过于简单,使用大数据也不一定有质的提升,尤其是涉及到自然语言处理。

参考:http://blog.topspeedsnail.com/archives/10399

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[561]TensorFlow练习1: 对评论进行分类 的相关文章

  • Spring Cloud 集成Gson 包冲突

    昨天再引入包的时候 Run了下main直接报错 就知道是包版本冲突了 然后添加的包排除 启动是正常了 但是项目一跑方法直接抛出来 gson转换异常 所以又得放开 于是尝试下引入Gson包试试
  • 3D文档(BRD、MRD、PRD)怎么写

    3D文档 一般来说 BRD作为战略方向的制定 是最早产出的文档 而MRD则是在战略方向的基础上对市场进行的分析 同时对后续工作的方向进行一些说明和指导 也可以说是通过对市场环境 竞品的分析 明确用户定位和产品定位的过程 PRD则是在战略方向
  • rpm的安装和卸载

    1 安装rpm包 强制安装目录下所有rpm包 rpm ivh rpm force nodeps 2 卸载rpm包 rpm e 包名 rpm nodeps

随机推荐

  • Buck的振铃实验与分析

    上上期我们提到了buck电路的开关的振铃波形 本质原因是LC的阻尼振荡 文章偏理论 那BUCK到底是怎么产生尖峰振荡呢 要想把这个问题搞清楚 也很是不容易 所以文章有点长 请直接点赞转发加收藏 问题 本期主要分析以下这两个问题 1 死区时间
  • 缩尾处理 stata

    要求 对连续变量上下1 的分位数进行了缩尾处理 目录 安装 具体命令 疑问1 需要对所有变量缩尾吗 疑问2 面板数据每年的截面数据分别进行处理吗 还是这么多年都混在一起处理 安装 ssc install winsor2 结果发现自己卡在了第
  • android 绘图之Path与Paint详解 - 冷冷汤圆

    http www cnblogs com aibuli p efef9d774df97c553a8a0c0c3495ba35 html utm source tuicool utm medium referral
  • 注释转换小项目(c注释->到c++注释)

    首先欢迎阅读本文 注释转换小项目涉及到c语言对文件的操作 另外这个小项目还应该对各种情况都考虑到 将c语言注释转换为c 注释 经过分析思考 我得到证据要的注释转换有以下几类 我将之整理并放入一个文件里 起名input c 1 一般情况 in
  • 【JavaScript高级】函数相关知识:函数、纯函数、柯里化、严格模式

    文章目录 函数 函数对象的属性 arguments arguments转Array 箭头函数不绑定arguments 剩余参数 rest 纯函数 定义 纯函数的案例 作用和优势 柯里化 定义 优势 自动柯里化 组合函数 定义 组合函数的封装
  • QT信号与槽的6种连接方式以及传递参数为自定义参数时

    文章目录 前言 一 信号与槽的连接 二 connect的第五个参数 三 传递参数为自定义参数时 扩展 前言 QT提供了信号与槽机制来实现对象之间的通信 只有QObject及其派生类才能使用信号和槽机制 且在类之中还需要使用Q OBJECT宏
  • CVTE面试总结(全网面经,已收offer)

    CVTE面试总结 文章目录 CVTE面试总结 CVTE一面 CVTE二面 CVTE面试hr面准备工作 1 问工资 2 给前面两轮面试打分 3 家庭关系和谁最好 4 未来5 10年会做什么 怎么规划 5 有没有别的offer 6 如果给off
  • 专家讲解 Hadoop:HBASE松散数据存储设计

    http developer 51cto com art 201006 203833 htm 本节和大家一起学习一下Hadoop HBASE松散数据存储设计方面的内容 希望通过本节介绍大家能够掌握Hadoop HBASE松散数据存储设计的方
  • 设计模式复习(七)-------适配器模式

    1 定义 将一个类的接口转换成客户希望的另一个接口 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 设计模式 GoF 适配 即在不改变原有实现的基础上 将原先不兼容的接口转换为兼容的接口 Adapter模式很像货
  • C语言之移位操作符、位操作符详解

    目录 1 移位操作符 2 位操作符 1 移位操作符 分为左移操作符 lt lt 和右移操作符 gt gt 左移操作符 移位规则 左边抛弃 右边补0 什么意思呢 现在就让我来仔细讲解一番 比如我们定义一个整型变量a 给它赋初值5 如int a
  • tablayout固定在顶端

    当tablayout上方还有其他布局只需要给其他布局添加 app layout scrollFlags scroll 就可以实现
  • postgresql查找数据库端口

    netstat a grep PGSQL
  • 使用git时出现fatal: Authentication failed for

    出现如下错误 fatal Authentication failed for 这是因为我使用的git账号的密码修改了 但是之前已经保存了原来的密码 所以就是密码错误导致无法登陆 但是又不会弹出来让我重新输入密码的界面 这就尴尬了 后来找到了
  • MSYS2 介绍、下载与安装、Pacman常用命令

    一 MSYS2 介绍 MSYS2 官网 MSYS2 MSYS2 Minimal SYStem 2 是一个集成了大量的GNU工具链 工具和库的开源软件包集合 它提供了一个类似于Linux的shell环境 可以在Windows系统中编译和运行许
  • odoo15设置定时任务

    概念 主要是 ir cron模型 它有以下属性 ir actions server id 服务端动作 cron name 任务名称 user id 调度程序用户 默认是当前环境用户 active 默认True interval number
  • KNN最近邻算法——原理和Python代码

    KNN最近邻算法是一种监督学习算法 基本思想是取距离测试数据最近的K个点 这K个点训练数据属于某一类型的数量多 则将该测试数据点也判断为该类 距离可以取 1 欧氏距离 2 曼哈顿距离 算法 1 计算测试数据与各个训练数据之间的距离 2 按照
  • java基础:Object类和Objects工具类的介绍

    1 Object 1 说明 Object类是所有类 数组 枚举类的父类 java允许把任何类型的对象赋给Object类型的变量 当定义一个类时没有使用extends为它显式指定父类 则该类默认继承Object父类 2 Object类的常用方
  • Servlet的Cookie与Seesion的介绍

    什么是Cookie Cookie是服务器在本地机器上存储的小段文本 它是一个简单的字符串形式的键值对 网络服务器用HTTP头向客户端发送cookie 一般情况下Cookie是由服务端生成的 当然js也能操作cookie 在客户端 浏览器解析
  • Python将numpy(.npy文件)存储为.ply文件

    Python将numpy npy文件 存储为 ply文件 安装Open3D From NumPy to Ply Open3D文档 安装Open3D pip install open3d From NumPy to Ply Pass xyz
  • [561]TensorFlow练习1: 对评论进行分类

    TensorFlow是谷歌2015年开源的一个深度学习库 到现在正好一年 和TensorFlow类似的库还有Caffe Theano MXNet Torch 但是论火爆程度 TensorFlow当之无愧 短短一年就在Github就收获了4万