使用Naive Bayes进行文本分类

1.Naive Bayes算法

朴素贝叶斯是一个简单但是十分高效的算法,在处理不是特别复杂的文本分类问题时,准确率相当不错,而且速度很快。像经典的垃圾邮件判别就是朴素贝叶斯算法的一个成功案例。

简单复习一下Bayes的原理:
Bayes公式:

P ( A B ) = P ( A ∣ B ) P ( B ) = P ( B ∣ A ) P ( A ) P(AB) = P(A|B)P(B) = P(B|A)P(A) P(AB)=P(AB)P(B)=P(BA)P(A)
P ( A ∣ B ) = P ( B ∣ A ) P ( A ) P ( B ) P(A|B) = \frac{P(B|A)P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)

如果我们简单换个写法,表示成如下形式
P ( H ∣ E ) = P ( E ∣ H ) P ( H ) P ( E ) P(H|E) = \frac{P(E|H)P(H)}{P(E)} P(HE)=P(E)P(EH)P(H)
其中,E表示Evidence,即事实证据。H表示Hypothesis,即假设。
我们想求解的P(H|E)表示在证据Evidence的情况下,假设Hypothesis发生的概率,经常被称为后验概率。
P(H)表示假设H的先验概率
而P(E|H)被称为似然概率,即likelihood。

2.Bayes求解的一个例子

通过一个例子,来分析一下Bayes算法的基本思路

假设有一个学校图书馆,图书管理员正为找不到某本书而发愁。已知老师有 70% 的意愿借走这本书,而是学生的意愿是 30%,这个学校的师生比例是 1:10,那么借走这本书的人是老师的概率有多大?

上面的例子中,Evidence是借走了书,要求的是借走人为老师的概率P(H|E),即H为老师

所以根据贝叶斯公式
P ( H ∣ E ) = 1 1 + 10 ⋅ 0.7 1 1 + 10 ⋅ 0.7 + 10 1 + 10 ⋅ 0.3 = 7 37 \begin{aligned} P(H|E) &= \frac{\frac{1}{1+10} \cdot 0.7 }{\frac{1}{1+10} \cdot 0.7 + \frac{10}{1+10} \cdot 0.3} \\ & = \frac{7}{37} \end{aligned} P(HE)=1+1010.7+1+10100.31+1010.7=377

其中,1/11为先验概率,表示学校里的人为老师的概率。0.7为似然概率,表示老师借书的概率。
分母为全概率公式展开,表示借书的概率,而借书的概率为老师与学生借书概率和相加。

3.准备数据

文本数据为游戏评论文本,格式为csv

sentence,label
游戏太坑,暴率太低,太克金,平民不能玩,negative
让人失望,negative
能解决一下服务器问题?网络正常老掉线,换手机也一样。。。,negative
期待,positive
一星也不想给,这特么简直龟速,炫舞老年版?,negative
衣服不好看游戏内容无特色,界面乱糟糟的,negative
喜欢喜欢,positive
从有了这个手游就一直玩,很喜欢呀,希望更多漂漂衣服,positive
因违反评价条例规定被折叠,negative

文本第一列为具体的评论内容,第二列为label,表示该评论为positive还是negative。

4.模型训练

import jieba
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report
from sklearn import metrics
from sklearn.metrics import confusion_matrix


np.set_printoptions(suppress=True)


def get_stop_words():
    filename = "your stop words file path"
    stop_words_list = []
    with open(filename) as f:
        for line in f:
            stop_words_list.append(line.strip())
    return stop_words_list


def processing_sentence(x, stop_words):
    cut_word = jieba.cut(str(x).strip())
    words = [word for word in cut_word if word not in stop_words and word != ' ']
    return " ".join(words)

def data_processing():
    train_file = "your  train file path"
    train_df = pd.read_csv(train_file)
    train_df, val_df = train_df[:int(len(train_df) * 0.9)], train_df[int(len(train_df) * 0.9):]
    x_train, y_train = train_df['sentence'], train_df['label']
    x_test, y_test = val_df['sentence'], val_df['label']
    stop_words = get_stop_words()
    x_train = x_train.apply(lambda x: processing_sentence(x, stop_words))
    x_test = x_test.apply(lambda x: processing_sentence(x, stop_words))
    return x_train, y_train, x_test, y_test

def evaluate(model, X, y):
    """评估数据集,并返回评估结果,包括:正确率、AUC值
    """
    accuracy = model.score(X, y)
    fpr, tpr, thresholds = metrics.roc_curve(y, model.predict_proba(X)[:, 1], pos_label="positive")
    return accuracy, metrics.auc(fpr, tpr)

def model_train(x_train, y_train, x_test, y_test):
    # 进行tfidf特征抽取
    tf = TfidfVectorizer()
    x_train = tf.fit_transform(x_train)
    x_test = tf.transform(x_test)

    mlb = MultinomialNB(alpha=1)
    mlb.fit(x_train, y_train)

    # 训练集上的评测结果
    accuracy, auc = evaluate(mlb, x_train, y_train)
    print("训练集正确率:%.4f%%\n" % (accuracy * 100))
    print("训练集AUC值:%.6f\n" % (auc))

    # 测试集上的评测结果
    accuracy, auc = evaluate(mlb, x_test, y_test)
    print("测试集正确率:%.4f%%\n" % (accuracy * 100))
    print("测试AUC值:%.6f\n" % (auc))

    y_predict = mlb.predict(x_test)
    print(classification_report(y_test, y_predict, target_names=['negative', 'positive']))

    cm = confusion_matrix(y_test, y_predict)
    print("confusion matrix: ", cm)


x_train, y_train, x_test, y_test = data_processing()
model_train(x_train, y_train, x_test, y_test)

上面的训练步骤主要如下:
1.对文本进行分词,去除停用词。
2.切分训练集,测试集。
3.对文本进行tfidf特征抽取。
4.使用MultinomialNB模型进行训练分类。
5.对结果进行评估。

代码输出结果为

训练集正确率:89.7897%

训练集AUC值:0.957826

测试集正确率:82.0663%

测试AUC值:0.880516

              precision    recall  f1-score   support

    negative       0.79      0.84      0.82       242
    positive       0.85      0.80      0.83       271

    accuracy                           0.82       513
   macro avg       0.82      0.82      0.82       513
weighted avg       0.82      0.82      0.82       513

confusion matrix:  [[203  39]
 [ 53 218]]

你可能感兴趣的:(text,classifier,bayes,naive,文本分类)