情感分析_CodingPark编程公园

基础知识

Python lambda介绍

问题:lambda是什么,为什么要使用lambda,是不是必须使用lambda?
回答:lambda 是为了减少单行函数的定义而存在的。

举个例子 🌰

g = lambda x:x+1

看一下执行的结果

g(1)

>>>2

g(2)

>>>3

当然,你也可以这样使用

lambda x:x+1(1)

>>>2

可以这样认为,lambda作为一个表达式,定义了一个匿名函数,上例的代码x为入口参数,x+1为函数体,用函数来表示为:

 def g(x):
     return x+1

这里lambda简化了函数定义的书写形式。使代码更为简洁,但是使用函数的定义方式更为直观,易理解。

Python中,也有几个定义好的全局函数方便使用的,filter, map, reduce

>>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
>>>
>>> print filter(lambda x: x % 3 == 0, foo)
[18, 9, 24, 12, 27]
>>>
>>> print map(lambda x: x * 2 + 10, foo)
[14, 46, 28, 54, 44, 58, 26, 34, 64]
>>>
>>> print reduce(lambda x, y: x + y, foo)
139

上面例子中的map的作用,非常简单清晰。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for…in…if语法已经很强大,并且在易读上胜过了lambda。

比如上面map的例子,可以写成:

print [x * 2 + 10 for x in foo]

非常的简洁,易懂。

filter的例子可以写成:

print [x for x in foo if x % 3 == 0]

同样也是比lambda的方式更容易理解。

gensim word2vec API概述

在gensim中,word2vec 相关的API都在包gensim.models.word2vec中,和算法有关的参数都在类gensim.models.word2vec.Word2Vec中。算法需要注意的参数有:

  1. sentences: 我们要分析的语料,可以是一个列表,或者从文件中遍历读出。后面我们会有从文件读出的例子。

  2. size: 词向量的维度,默认值是100。这个维度的取值一般与我们的语料的大小相关,如果是不大的语料,比如小于100M的文本语料,则使用默认值一般就可以了。如果是超大的语料,建议增大维度。

  3. window:即词向量上下文最大距离,这个参数在我们的算法原理篇中标记为𝑐
    c
    ,window越大,则和某一词较远的词也会产生上下文关系。默认值为5。在实际使用中,可以根据实际的需求来动态调整这个window的大小。如果是小语料则这个值可以设的更小。对于一般的语料这个值推荐在[5,10]之间。

  4. sg: 即我们的word2vec两个模型的选择了。如果是0, 则是CBOW模型,是1则是Skip-Gram模型,默认是0即CBOW模型。

  5. hs: 即我们的word2vec两个解法的选择了,如果是0, 则是Negative Sampling,是1的话并且负采样个数negative大于0, 则是Hierarchical Softmax。默认是0即Negative Sampling。

  6. negative:即使用Negative Sampling时负采样的个数,默认是5。推荐在[3,10]之间。这个参数在我们的算法原理篇中标记为neg。

  7. cbow_mean: 仅用于CBOW在做投影的时候,为0,则算法中的𝑥𝑤为上下文的词向量之和,为1则为上下文的词向量的平均值。在我们的原理篇中,是按照词向量的平均值来描述的。个人比较喜欢用平均值来表示𝑥𝑤,默认值也是1,不推荐修改默认值。

  8. min_count:需要计算词向量的最小词频。这个值可以去掉一些很生僻的低频词,默认是5。如果是小语料,可以调低这个值。

  9. iter: 随机梯度下降法中迭代的最大次数,默认是5。对于大语料,可以增大这个值。

  10. alpha: 在随机梯度下降法中迭代的初始步长。算法原理篇中标记为𝜂,默认是0.025。

  11. min_alpha: 由于算法支持在迭代的过程中逐渐减小步长,min_alpha给出了最小的迭代步长值。随机梯度下降中每轮的迭代步长可以由iter,alpha, min_alpha一起得出。这部分由于不是word2vec算法的核心内容,因此在原理篇我们没有提到。对于大语料,需要对alpha, min_alpha,iter一起调参,来选择合适的三个值。

gensim Word2Vec 训练和使用

训练模型

  • 利用gensim.models.Word2Vec(sentences)建立词向量模型
    该构造函数执行了三个步骤:建立一个空的模型对象,遍历一次语料库建立词典,第二次遍历语料库建立神经网络模型
    可以通过分别执行model=gensim.models.Word2Vec(),model.build_vocab(sentences),model.train(sentences)来实现

  • 训练时可以指定以下参数
    min_count指定了需要训练词语的最小出现次数,默认为5
    size指定了训练时词向量维度,默认为100
    worker指定了完成训练过程的线程数,默认为1不使用多线程。只有注意安装Cython的前提下该参数设置才有意义

  • 训练结果保存可以通过model.save(‘fname’)或model.save_word2vec_format(fname)来保存为文件,再使用model.load(fname)或model.load_word2vec_format(fname,encoding=‘utf-8’)读取查询结果

例如:

from gensim.models.word2vec import Word2Vec 

sentences = [['A1''A2'][][]....] 
model= Word2Vec()
model.build_vocab(sentences)
model.train(sentences,total_examples = model.corpus_count,epochs = model.iter)

基于商品评价的情感分析讲解

实现步骤

载数据
处理
分训练集和测试集

向量计算
练SVM模型

引用包说明
导入几个python常见的库:

train_test_split 用来对特征向量的划分
numpy和pandas 是处理数据常见的库
jieba 库用来分词
joblib 用来保存训练好的模型
Word2Vec 将自然语言中的字词转为计算机可以理解的稠密向量
sklearn.svm 是机器学习训练模型常用的库

加载数据

数据就是正反两类,保存在neg.xls和pos.xls文件中
在这里插入图片描述

预处理

  • 分词
  • 标点符号
  • 停用此过滤

切分训练集和测试集

利用train_test_split函数切分训练集和测试集,test_size表示切分的比例,百分之二十用来测试。

词向量计算

word2vec也叫word embeddings,中文名“词向量”,作用就是将自然语言中的字词转为计算机可以理解的稠密向量(Dense Vector)。在word2vec出现之前,自然语言处理经常把字词转为离散的单独的符号,也就是One-Hot Encoder。
Word2Vec可以将One-Hot Encoder转化为低维度的连续值,也就是稠密向量,并且其中意思相近的词将被映射到向量空间中相近的位置。

训练SVM模型

训练使用SVM,sklearn库已经封装好了算法,只需调用就行

预测

在这里插入图片描述

基于商品评价的情感分析实战

sentiment_analysis.py

# -*- encoding: utf-8 -*-
"""
@File    :   sentiment_analysis.py    
@Contact :   ag@team-ag.club
@License :   (C)Copyright 2019-2020, CodingPark

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2020-08-05 15:30   AG         1.0         None
"""
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import jieba as jb
from sklearn.externals import joblib
from sklearn.svm import SVC
from gensim.models.word2vec import Word2Vec


def loadfile_and_preprocessing():
    # 加载数据
    pos = pd.read_excel('pos.xls', header=None, index=None)
    neg = pd.read_excel('neg.xls', header=None, index=None)
    # print(pos)

    # 这时两类数据都是x值
    pos['words'] = pos[0].apply(lambda x: list(jb.cut(x)))
    neg['words'] = neg[0].apply(lambda x: list(jb.cut(x)))

    # 现在制作y  其中, 1代表是pos  0 代表neg
    Y = np.concatenate((np.ones(len(pos)), np.zeros(len(neg))))
    X = np.concatenate((pos['words'], neg['words']))
    # print(Y)

    x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=3)
    # 保存数据
    np.save("y_train", y_train)
    np.save("y_test", y_test)

    return x_train, x_test


def build_vec(text, size, wv):
    # 创建一个指定大小的数据空间
    vec = np.zeros(size).reshape((1, size))
    # count是统计有多少词向量
    count = 0
    # 循环所有的词向量进行求和
    for w in text:
        try:
            vec += wv[w].reshape((1, size))
            count += 1
        except:
            continue

    # 循环完成后求均值
    if count != 0:
        vec /= count
    return vec


def get_w2v(x_train, x_test):
    wv = Word2Vec(size=300, min_count=10)
    wv.build_vocab(x_train)

    # 训练集
    # 训练
    wv.train(x_train, total_examples=1, epochs=1)
    # 获取train_vecs
    train_vecs = np.concatenate([build_vec(z, 300, wv) for z in x_train])
    # 保存
    np.save('train_vecs', train_vecs)
    # 保存模型
    wv.save("model3.pkl")

    # 测试集
    # 训练
    wv.train(x_test, total_examples=1, epochs=1)
    # 获取train_vecs
    test_vecs = np.concatenate([build_vec(z, 300, wv) for z in x_test])
    # 保存
    np.save('test_vecs', test_vecs)


def get_data():
    train_vecs = np.load("train_vecs.npy")
    y_train = np.load("y_train.npy")
    test_vecs = np.load("test_vecs.npy")
    y_test = np.load("y_test.npy")

    return train_vecs, y_train, test_vecs, y_test


def svc_train(train_vecs, y_train, test_vecs, y_test):
    # 创建SVC模型
    cls = SVC(kernel='rbf', verbose=True)

    # 训练模型
    cls.fit(train_vecs, y_train)

    # 保存模型
    joblib.dump(cls, 'svcmodel.pkl')

    # 评分
    print(cls.score(test_vecs, y_test))


def get_predict_vecs(words):
    # 加载模型
    wv = Word2Vec.load("model3.pkl")
    #将新的词转换为向量
    train_vecs = build_vec(words, 300, wv)
    return train_vecs


def svm_predict(string):
    # 对语句进行分词
    words = jb.cut(string)
    # 将分词结果转换为词向量
    word_vecs = get_predict_vecs(words)
    # 加载模型
    cls = joblib.load("svcmodel.pkl")
    # 预测得到结果
    result = cls.predict(word_vecs)
    # 输出结果
    if result[0] == 1:
        print("pos")
    else:
        print("neg")


def train():
    x_train, x_test = loadfile_and_preprocessing()
    get_w2v(x_train, x_test)
    train_vecs, y_train, test_vecs, y_test = get_data()
    svc_train(train_vecs, y_train, test_vecs, y_test)


train()

string = "这本书非常好,我喜欢"

svm_predict(string)







# -*- encoding: utf-8 -*-
"""
@File    :  Test.py    
@Contact :   ag@team-ag.club
@License :   (C)Copyright 2019-2020, CodingPark

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2020-08-05 15:30   AG         1.0        带界面的预测
"""

from tkinter import *
import numpy as np
import jieba as jb
import joblib
from gensim.models.word2vec import Word2Vec


class core():
    def __init__(self, str):
        self.string = str

    def build_vector(self, text, size, wv):
        # 创建一个指定大小的数据空间
        vec = np.zeros(size).reshape((1, size))
        # count是统计有多少词向量
        count = 0
        # 循环所有的词向量进行求和
        for w in text:
            try:
                vec += wv[w].reshape((1, size))
                count += 1
            except:
                continue
        # 循环完成后求均值
        if count != 0:
            vec /= count
        return vec

    def get_predict_vecs(self, words):
        # 加载模型
        wv = Word2Vec.load("model3.pkl")
        # 将新的词转换为向量
        train_vecs = self.build_vector(words, 300, wv)
        return train_vecs

    def svm_predict(self, string):
        # 对语句进行分词
        words = jb.cut(string)
        # 将分词结果转换为词向量
        word_vecs = self.get_predict_vecs(words)
        # 加载模型
        cls = joblib.load("svcmodel.pkl")
        # 预测得到结果
        result = cls.predict(word_vecs)
        # 输出结果
        if result[0] == 1:
            return "好评"
        else:
            return "差评"

    def main(self):
        s = self.svm_predict(self.string)
        return s


root = Tk()
root.title("TEAM-AG情感分析app")
sw = root.winfo_screenwidth()
# 得到屏幕宽度
sh = root.winfo_screenheight()
# 得到屏幕高度
ww = 800
wh = 500
x = (sw - ww) / 2
y = (sh - wh) / 2 - 50
root.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
# root.iconbitmap('tb.ico')

lb2 = Label(root, text="输入内容,按回车键分析")
lb2.place(relx=0, rely=0.05)

txt = Text(root, font=("宋体", 20))
txt.place(rely=0.7, relheight=0.3, relwidth=1)

inp1 = Text(root, height=15, width=65, font=("宋体", 18))
inp1.place(relx=0, rely=0.2, relwidth=1, relheight=0.4)


def run1():
    txt.delete("0.0", END)
    a = inp1.get('0.0', (END))
    p = core(a)
    s = p.main()
    print(s)
    txt.insert(END, s)  # 追加显示运算结果


def button1(event):
    btn1 = Button(root, text='开始分析', font=("", 12), command=run1)  # 鼠标响应
    btn1.place(relx=0.35, rely=0.6, relwidth=0.15, relheight=0.1)
    # inp1.bind("<Return>",run2) #键盘响应


button1(1)
root.mainloop()







更多信息

📍gensim Word2Vec 训练和使用
https://blog.csdn.net/qq_19707521/article/details/79169826?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159661722719195188312209%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159661722719195188312209&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-4-79169826.first_rank_ecpm_v3_pc_rank_v2&utm_term=.build_vocab&spm=1018.2118.3001.4187

在这里插入图片描述

评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页
实付 79.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值