收集您的数据
根据您声明的评论,您希望将评论分类为标签(1-差、2-一般、3-好、4-好、5-非常好)。因此,您将训练一个模型,该模型将一组单词(段落)映射到一个代表评分的数字。我假设你也有一些评论的标签,我们称之为你的训练集。
我无权访问您的数据,但我有一个类似的虚拟示例,它使用评论并试图将它们归类为对酒店或汽车租赁的评论。我认为这个例子很适合这个目的。
预处理数据
为此,我们可以使用许多技术。例如,一些流行词是bag-of-words、tf-idf和n-grams。这些技术将接受评论并将其矢量化为一组特征。我们将使用的特征是从训练集中学习的,然后对于进来的新评论也是一样的。我们将在这个例子中使用词袋。
词袋
这种方法有一个我们从训练集中识别出来的单词字典。我们在词干后取所有独特的词。然后我们计算每个单词在评论中出现的次数,即表示给定实例的向量。例如,如果我们的字典看起来像
['汽车','书','测试','哇']
评论是
哇,这车好厉害!!!!!!
结果向量将是
[1, 0, 0, 1]
我们将为每条评论重复这个矢量化过程。然后我们将得到一个矩阵,其中行代表每个评论,列代表这些词在评论中出现的频率。我们称这个矩阵X这是我们的数据集。这些实例中的每一个都有一个标签,我们称之为向量是. 我们想将每一行映射到X 给它的标签 是.
假设这是您在汽车/酒店评论的训练数据集中拥有 40 个实例的数据。右侧有相应的标签。标签 0 用于汽车,标签 1 用于酒店。

矩阵的列 X 是
['汽车', '乘客', '座位', '驱动器', '动力', '高速公路', '采购', '酒店', '房间', '夜', '工作人员', '水', '地点']
拆分数据
我们将拆分数据以测试模型的准确性
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3)

应用朴素贝叶斯
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
clf = clf.fit(X_train, y_train)
clf.score(X_test, y_test)
这给出了一个结果
1.0
完美分类!
它是如何工作的?
高斯朴素贝叶斯假设每个特征都由高斯分布描述(您可以选择其他可能更适合您的数据的分布,例如多项式)。然后它将假设每个特征完全相互独立。因此我们可以说概率
磷(是= 0 | X) = P(X0| 是= 0 ) P(X0) * 。. . * P(Xn| 是= 0 ) P(Xn)
磷(是= 1 | X) = P(X0| 是= 1 ) P(X0) * 。. . * P(Xn| 是= 1 ) P(Xn)
为您 n特征。最大的将是我们的标签。如果磷(是= 1 | X)更大然后我们会说评论是汽车的评论。所以要做到这一点,我们需要训练我们的概率分布的参数磷(X一世| 是). 要计算这个术语,我们需要知道分布的参数,在我们的例子中,我们使用的是高斯分布,因此我们需要均值和方差ñ( μ , θ ).
我们将为每个标签构建一个值字典,其中包含每个特征的均值和方差。这是训练阶段!
自制朴素贝叶斯
import csv
import random
import math
import pandas as pd
import numpy as np
class NaiveBayes(object):
def __init__(self):
self.groupClass = None
self.stats = None
def calculateGaussian(self, x, mean, std):
exponent = np.exp(-1*(np.power(x-mean,2)/(2*np.power(std,2))))
std[std==0] = 0.00001
return (1 / (np.sqrt(2*math.pi) * std)) * exponent
def predict(self, x):
probs = np.ones((len(x), len(self.stats)))
for ix, instance in enumerate(x):
for label_ix, label in enumerate(self.stats):
probs[ix, int(label)] = probs[ix, int(label)] * \
np.prod(self.calculateGaussian(instance, self.stats[label][0], self.stats[label][1]))
return np.argmax(probs, 1)
def score(self, x, y):
pred = self.predict(x)
return np.sum(1-np.abs(y - pred))/len(x)
def train(self, x, y):
self.splitClasses(x, y)
self.getStats()
pass
def splitClasses(self, x, y):
groupClass = {}
for instance, label in zip(x, y):
if not label in groupClass:
groupClass.update({label: [instance]})
else:
groupClass[label].append(instance)
self.groupClass = groupClass
def getStats(self):
stats = {}
for label in self.groupClass:
mean = np.mean(np.asarray(self.groupClass[label]), 0)
std = np.std(np.asarray(self.groupClass[label]), 0)
stats.update({label: [mean, std]})
self.stats = stats
clf = NaiveBayes()
clf.train(X_train, y_train)
clf.score(X_test, y_test)
我们再次在测试集上获得了 1.0 的准确度!