朴素贝叶斯是一个很不错的分类器,在使用朴素贝叶斯分类器划分邮件有关于朴素贝叶斯的简单介绍。html
若一个样本有n个特征,分别用x1,x2,...,xn表示,将其划分到类yk的可能性P(yk|x1,x2,...,xn)为:python
P(yk|x1,x2,...,xn)=P(yk)∏ni=1P(xi|yk)算法
上式中等号右侧的各个值能够经过训练获得。根据上面的公式能够求的某个数据属于各个分类的可能性(这些可能性之和不必定是1),该数据应该属于具备最大可能性的分类中。ruby
通常来讲,若是一个样本没有特征xi,那么P(xi|yk)将不参与计算。不过下面的伯努利模型除外。dom
以上是朴素贝叶斯的最基本的内容。函数
有些特征多是连续型变量,好比说人的身高,物体的长度,这些特征能够转换成离散型的值,好比若是身高在160cm如下,特征值为1;在160cm和170cm之间,特征值为2;在170cm之上,特征值为3。也能够这样转换,将身高转换为3个特征,分别是f一、f二、f3,若是身高是160cm如下,这三个特征的值分别是一、0、0,若身高在170cm之上,这三个特征的值分别是0、0、1。不过这些方式都不够细腻,高斯模型能够解决这个问题。高斯模型假设这些一个特征的全部属于某个类别的观测值符合高斯分布,也就是:atom
P(xi|yk)=12πσ2yk√exp(−(xi−μyk)22σ2yk)spa
下面看一个sklearn中的示例:code
>>> from sklearn import datasets >>> iris = datasets.load_iris() >>> iris.feature_names # 四个特征的名字 ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] >>> iris.data array([[ 5.1, 3.5, 1.4, 0.2], [ 4.9, 3. , 1.4, 0.2], [ 4.7, 3.2, 1.3, 0.2], [ 4.6, 3.1, 1.5, 0.2], [ 5. , 3.6, 1.4, 0.2], [ 5.4, 3.9, 1.7, 0.4], [ 4.6, 3.4, 1.4, 0.3], [ 5. , 3.4, 1.5, 0.2], ...... [ 6.5, 3. , 5.2, 2. ], [ 6.2, 3.4, 5.4, 2.3], [ 5.9, 3. , 5.1, 1.8]]) #类型是numpy.array >>> iris.data.size 600 #共600/4=150个样本 >>> iris.target_names array(['setosa', 'versicolor', 'virginica'], dtype='|S10') >>> iris.target array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,....., 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ......, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) >>> iris.target.size 150 >>> from sklearn.naive_bayes import GaussianNB >>> clf = GaussianNB() >>> clf.fit(iris.data, iris.target) >>> clf.predict(iris.data[0]) array([0]) # 预测正确 >>> clf.predict(iris.data[149]) array([2]) # 预测正确 >>> data = numpy.array([6,4,6,2]) >>> clf.predict(data) array([2]) # 预测结果很合理
该模型经常使用于文本分类,特征是单词,值是单词的出现次数。htm
P(xi|yk)=Nykxi+αNyk+αn
其中,Nykxi是类别yk下特征xi出现的总次数;Nyk是类别yk下全部特征出现的总次数。对应到文本分类里,若是单词word
在一篇分类为label1
的文档中出现了5次,那么Nlabel1,word的值会增长5。若是是去除了重复单词的,那么Nlabel1,word的值会增长1。n是特征的数量,在文本分类中就是去重后的全部单词的数量。α的取值范围是[0,1],比较常见的是取值为1。
待预测样本中的特征xi在训练时可能没有出现,若是没有出现,则Nykxi值为0,若是直接拿来计算该样本属于某个分类的几率,结果都将是0。在分子中加入α,在分母中加入αn能够解决这个问题。
下面的代码来自sklearn的示例:
>>> import numpy as np >>> X = np.random.randint(5, size=(6, 100)) >>> y = np.array([1, 2, 3, 4, 5, 6]) >>> from sklearn.naive_bayes import MultinomialNB >>> clf = MultinomialNB() >>> clf.fit(X, y) MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True) >>> print(clf.predict(X[2])) [3]
值得注意的是,多项式模型在训练一个数据集结束后能够继续训练其余数据集而无需将两个数据集放在一块儿进行训练。在sklearn中,MultinomialNB()类的partial_fit()方法能够进行这种训练。这种方式特别适合于训练集大到内存没法一次性放入的状况。
在第一次调用partial_fit()
时须要给出全部的分类标号。
>>> import numpy >>> from sklearn.naive_bayes import MultinomialNB >>> clf = MultinomialNB() >>> clf.partial_fit(numpy.array([1,1]), numpy.array(['aa']), ['aa','bb']) GaussianNB() >>> clf.partial_fit(numpy.array([6,1]), numpy.array(['bb'])) GaussianNB() >>> clf.predict(numpy.array([9,1])) array(['bb'], dtype='|S2')
伯努利模型中,对于一个样原本说,其特征用的是全局的特征。
在伯努利模型中,每一个特征的取值是布尔型的,即true和false,或者1和0。在文本分类中,就是一个特征有没有在一个文档中出现。
若是特征值xi值为1,那么
P(xi|yk)=P(xi=1|yk)
若是特征值xi值为0,那么
P(xi|yk)=1−P(xi=1|yk)
这意味着,“没有某个特征”也是一个特征。 下面的示例来自sklearn官方文档:
>>> import numpy as np >>> X = np.random.randint(2, size=(6, 100)) >>> Y = np.array([1, 2, 3, 4, 4, 5]) >>> from sklearn.naive_bayes import BernoulliNB >>> clf = BernoulliNB() >>> clf.fit(X, Y) BernoulliNB(alpha=1.0, binarize=0.0, class_prior=None, fit_prior=True) >>> print(clf.predict(X[2])) [3]
BernoulliNB()类也有partial_fit()函数。
在基于naive bayes的文本分类算法给出了很好的解释。
在多项式模型中:
在多项式模型中, 设某文档d=(t1,t2,…,tk),tk是该文档中出现过的单词,容许重复,则
先验几率P(c)= 类c下单词总数/整个训练样本的单词总数
类条件几率P(tk|c)=(类c下单词tk在各个文档中出现过的次数之和+1)/(类c下单词总数+|V|)
V是训练样本的单词表(即抽取单词,单词出现屡次,只算一个),|V|则表示训练样本包含多少种单词。 P(tk|c)能够看做是单词tk在证实d属于类c上提供了多大的证据,而P(c)则能够认为是类别c在总体上占多大比例(有多大可能性)。
在伯努利模型中:
P(c)= 类c下文件总数/整个训练样本的文件总数
P(tk|c)=(类c下包含单词tk的文件数+1)/(类c下单词总数+2)
http://scikit-learn.org/stable/modules/naive_bayes.html
http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.GaussianNB.html
http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.MultinomialNB.html
http://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.BernoulliNB.html