机器学习大数据,机器学习,人工智能互联网科技

朴素贝叶斯分类算法实践

2017-12-21  本文已影响105人  xhades

少年壮志不言愁
劝君惜取少年时

图片来自网络

贝叶斯定理:
贝叶斯定理是关于随机事件A和B的条件概率(或边缘概率)的一则定理。其中P(A|B)是在B发生的情况下A发生的可能性。关于贝叶斯理论的详细推理,可以参考这篇文章

P(A丨B)=P(A)P(B丨A)/P(B)

小试牛刀

这里选择当当网书评价(好评、差评)应用贝叶斯分类算法,其中差评数据10w条,好评数据11w条,数据保存到trainset.csv数据下载链接

训练集trainset.csv.png
训练集中包括差评和好评数据共221968,其中包括无效数据及空行,后面将被清除
训练集第一行header包括两个字段rate即评论正文和评论类型type即差评与好评

1. 首先对抓取的数据清洗,删除空格\u3000\xa0等字符

  def cleanTrianSet(filepath):
      """
      清洗句子中空行、空格
      目前采用将所有数据读取到内存,后续思考其他高效方式
      """
      # 删除评论上面的 \n
      fileDf = pd.read_csv(filepath, keep_default_na=False)
      fileDf["rate"] = fileDf["rate"].apply(lambda x: x.replace("\n", ""))
      linelist = fileDf.values.tolist()
      filelines = [ _[0] + "," + _[-1] for _ in linelist]
      cleaned_lines = map(lambda x: x.translate({ord('\u3000'): '', ord('\r'): '', ord('\xa0'): None,
                                                  ord(' '): None}), filelines[1:])  # 更加优雅的方式 在这个问题中是比较快的方式
      return cleaned_lines  # 返回一个map对象

2. 使用开源分词工具jieba分词对正负面语料进行分词,分词过程中删除了空行等。分词代码tools/jieba_split.py,分词结果如下图

分词后数据集.png
同时将label写入data/label.txt
label.txt.png

3.使用Word2Vec对分词数据集训练词向量

参数设置说明

#!/usr/bin/env python
# -*-coding:utf-8-*-
"""
@Time: 17-11-20 
@author: xhades
@version: v0.1
"""
from gensim.models import word2vec

sentence = word2vec.Text8Corpus('../data/splited_words.txt')
model = word2vec.Word2Vec(sentence, size=128, min_count=10, sg=1, window=12, workers=8)
model.wv.save_word2vec_format("../data/embedding.txt", binary=False, )
model.save("../Model/word2vec.model")

形成embedding.txt词嵌入文件,即保存了所有词的词向量

4.数据预处理

代码模块preprocessing.py

5.训练数据

sklearn中,提供了3中朴素贝叶斯分类算法:GaussianNB(高斯朴素贝叶斯)、MultinomialNB(多项式朴素贝叶斯)、BernoulliNB(伯努利朴素贝叶斯)

我这里主要选择使用伯努利模型的贝叶斯分类器来进行短评分类。

并且按照7:3的比例划分训练集和测试集

import numpy as np
from numpy import array, argmax, reshape
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
from sklearn.naive_bayes import BernoulliNB
import pickle

np.set_printoptions(threshold=np.inf)


# 训练集测试集 3/7分割
def train(xFile, yFile):
    with open(xFile, "rb") as file_r:
        X = pickle.load(file_r)
    # print(X.shape)
    X = reshape(X, (212841, -1))  # reshape一下 (212841, 30*128)
    # 读取label数据,并且使用LabelEncoder对label进行编号
    with open(yFile, "r") as yFile_r:
        labelLines = [_.strip("\n") for _ in yFile_r.readlines()]
    values = array(labelLines)
    labelEncoder = LabelEncoder()
    integerEncoded = labelEncoder.fit_transform(values)
    integerEncoded = integerEncoded.reshape(len(integerEncoded), 1)
    # print(integerEncoded)

    # 获得label 编码
    Y = integerEncoded.reshape(212841, )
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

    # 训练数据
    clf = BernoulliNB()
    clf.fit(X_train, Y_train)

    # 测试数据
    predict = clf.predict(X_test)
    count = 0
    for p, t in zip(predict, Y_test):
        if p == t:
            count += 1
    print("Accuracy is:", count/len(Y_test))

最终使用朴素贝叶斯分类器最终准确率在71%左右,分类效果还算不错=。=

=========================12.25更新========================

完整代码查看rates_classify

上一篇 下一篇

猜你喜欢

热点阅读