ナイーブベイズを一緒に学ぶ

 Zhai Cunqi360 クラウドコンピューティング


ヒロイン宣言

最近、編集者は機械学習の知識も学び始めています。そこで、私はNaive Bayesから始めて、誰もが学ぶことができる関連情報をまとめました。

PS:豊富な第一線の技術と多様な表現形式はすべて「HULK第一線の技術トーク」にあります、注意してください

前書き

ナイーブベイズ法は、ベイズの定理と特徴条件の独立性の仮定に基づく分類法です。特定のトレーニングデータセットについて、最初に特徴条件の独立性の仮定に基づいて入力/出力の同時確率分布を学習し、次にこのモデルに基づいて学習します。 。与えられた入力xに対して、ベイズの定理を使用して、事後確率が最大の出力yを見つけます。ナイーブベイズ法は実装が簡単で、学習と予測の効率が非常に高く、一般的に使用される方法です。

キャラクター紹介

イギリスの数学者ベイズ。1701年にロンドンで生まれ、司祭でした。1742年に王立学会の会員になりました。1763年4月7日に亡くなりました。ベイズは主に数学の確率を研究しています。方法は確率論の基礎理論で使用され、ベイズの統計理論が作成され、統計的決定関数、統計的推論、および統計的推定に貢献しました。1763年に、このトピックに関する出版物が現代の確率論と数学で出版されました。統計。どちらも非常に重要な役割を果たします。ベイズの他の本「機会の教義の紹介」は1758年に出版されました。ベイズが使用する多くの用語が今日使用されています。統計的推論への彼の主な貢献は、「逆確率」の概念を使用し、それを普遍的な推論方法として提唱することです。ベイズの定理はもともと確率論の定理でしたが、この定理は有名なベイズの定理である数式で表すことができます。-360Baikeから抜粋

アルゴリズムの原理

  • 条件付き確率式

  • 全確率の式

  • 特徴的な条件付き独立性仮説

1

条件付き確率式

条件付き確率とは、別のイベントBがすでに発生しているという条件の下でイベントAが発生する確率を指します。条件付き確率は次のように表されます。P(A | B)、これは「Bの条件下でのAの確率」として読み取られます。イベントAとBが2つしかない場合は、次のようになります。

P(A | B)= P(AB)/ P(B)

P(B | A)= P(AB)/ P(A)

など:

P(A | B)= P(B | A)* P(A)/ P(B)

2

全確率の式

イベントA1、A2、A3 ... Anが完全なイベントグループを構成する場合、つまり、それらは互いに互換性がなく、それらの合計が完全なセットであり、P(Ai)が0より大きい場合、任意のイベントB :

P(B)= P(A1B)+ P(A1B)+···+ P(AnB)

        = ∑P(AiB)

        = ∑P(B | Ai)* P(Ai)······················(i as 1、2 as

3

ベイズの公式

イベントAkとイベントBの場合、合計確率式を条件付き確率式に入れます。

P(Ak | B)= [P(Ak)* P(B | Ak)] /(P(B | Ai)* P(Ai)·······i = 1、2、····· 、n)

P(Ak | B)の場合、分子∑P(B | Ai)* P(Ai)は固定値です。これは、P(Ak | B)のサイズを比較するだけでよいため、分母の固定値です。削除することができます、それは結果に影響を与えません。したがって、次の式が得られます。

P(Ak | B)= P(Ak)* P(B | Ak)

P(Ak)事前確率、P(Ak | B)事後確率、P(B | Ak)尤度関数

4

特徴的な条件付き独立性仮説

分類問題では、物を特定のカテゴリに分類する必要があることがよくあります。モノには多くの属性があります。つまり、x =(x1、x2、···、xn)です。多くの場合、複数のカテゴリがあります。つまり、y =(y1、y2、···、yk)です。P(y1 | x)、P(y2 | x)、...、P(yk | x)は、xが特定のカテゴリに属する​​確率を表します。次に、最大の確率P(yk | x)を見つける必要があります。 。

前のステップで得られた式によると:P(yk | x)= P(yk)* P(x | yk) 

サンプルxにはn個の属性があります:x =(x1、x2、···、xn)、したがって:P(yk | X)= P(yk)* P(x1、x2、···、xn | yk) 

条件付き独立性の仮定は、条件が相互に影響を与えないことを意味します。したがって、P(x1、x2、···、xn | yk)= ∏P(xi | yk)最終式は次のとおりです。P(yk | x) = P(yk)* ∏P(xi | yk)  

式P(yk | x)= P(yk)* ∏P(xi | yk)に従って、分類問題を実行できます。

ラプラシアン平滑化

引入这个概率的意义,公式P(yk|x) =P(yk) * ∏P(xi|yk),是一个多项乘法公式,其中有一项数值为0,则整个公式就为0,显然不合理,避免每一项为零的做法就是,在分子、分母上各加一个数值。

P(y) = (|Dy| + 1) / (|D| + N)

参数说明:|Dy|表示分类y的样本数,|D|样本总数。

P(xi|Dy) = (|Dy,xi| + 1) / (|Dy| + Ni)

参数说明:|Dy,xi|表示分类y属性i的样本数,|Dy|表示分类y的样本数,Ni表示i属性的可能的取值数。

文本分类

手动实现邮件分类


首先要对所有的已标记的邮件进行分词,整理得到每封邮件分词向量和全分词向量

根据邮件向量可以得到每个词在正常邮件中出现的概率(∏P(wi|Normal))及垃圾邮件中出现的概率(∏P(wi|Spam))

垃圾邮件的概率:P(spam)

正常邮件的概率:P(normal)

邮件是垃圾邮件的概率:

P(Spam|mail) = P(Spam) * ∏P(wi|Spam)

邮件是正常邮件的概率:

P(Normal|mail) = P(Normal) * ∏P(wi|Normal)

最后比较 P(Spam|mail) 与 P(Normal|mail) 的大小就可以了。

使用sklearn实现文本分类

# sklearn 实现文本分类
import os
import random
from numpy import *
from numpy.ma import arange
from sklearn.pipeline import Pipeline
# TfidfVectorizer 文本特征提取(根据词出现的频率及在语句中的重要性)
# HashingVectorizer 文本的特征哈希
# CountVectorizer 将文本转换为每个词出现的个数的向量

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import BernoulliNB
from sklearn.naive_bayes import MultinomialNB
import matplotlib.pyplot as plt

# 获取样本集
def get_dataset():    data = []
   for root, dirs, files in os.walk(r'./mix20_rand700_tokens_cleaned/tokens/neg'):
       for file in files:            realpath = os.path.join(root, file)
           with open(realpath, errors='ignore') as f:                data.append((f.read(), 'bad'))
   for root, dirs, files in os.walk(r'./mix20_rand700_tokens_cleaned/tokens/pos'):
       for file in files:            realpath = os.path.join(root, file)
           with open(realpath, errors='ignore') as f:                data.append((f.read(), 'good'))    random.shuffle(data)
   return data
   
# 处理训练集与测试集

def train_and_test_data(data_):    # 训练集和测试集的比例为7:3    filesize = int(0.7 * len(data_))
   # 训练集    train_data_ = [each[0] for each in data_[:filesize]]    train_target_ = [each[1] for each in data_[:filesize]]
   # 测试集    test_data_ = [each[0] for each in data_[filesize:]]    test_target_ = [each[1] for each in data_[filesize:]]
   return train_data_, train_target_, test_data_, test_target_
   
""" 多项式模型: 在多项式模型中, 设某文档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在整体上占多大比例(有多大可能性)。 """
def mnb(train_da, train_tar, test_da, test_tar):    nbc = Pipeline([        ('vect', TfidfVectorizer()),        ('clf', MultinomialNB(alpha=1.0)),    ])    nbc.fit(train_da, train_tar)  # 训练我们的多项式模型贝叶斯分类器    predict = nbc.predict(test_da)  # 在测试集上预测结果    count = 0  # 统计预测正确的结果个数    for left, right in zip(predict, test_tar):
       if left == right:            count += 1    # print("多项式模型:", count / len(test_target))    return count / len(test_tar)

""" 伯努利模型: P(c)= 类c下文件总数/整个训练样本的文件总数 P(tk|c)=(类c下包含单词tk的文件数+1)/(类c下单词总数+2) """
def bnb(train_da, train_tar, test_da, test_tar):    nbc_1 = Pipeline([        ('vect', TfidfVectorizer()),        ('clf', BernoulliNB(alpha=1.0)),    ])    nbc_1.fit(train_da, train_tar)  # 训练我们的多项式模型贝叶斯分类器    predict = nbc_1.predict(test_da)  # 在测试集上预测结果    count = 0  # 统计预测正确的结果个数    for left, right in zip(predict, test_tar):
       if left == right:            count += 1    # print("伯努利模型:", count / len(test_target))    return count / len(test_tar)

# 训练十次
x = arange(10) y1 = [] y2 = []for i in x:    print(i)    data = get_dataset()    train_data, train_target, test_data, test_target = train_and_test_data(data)    y1.append(mnb(train_data, train_target, test_data, test_target))    y2.append(bnb(train_data, train_target, test_data, test_target)) print(x) print(y1) print(y2) plt.plot(x, y1, lw='2', label='MultinomialNB') plt.plot(x, y2, lw='2', label='BernoulliNB') plt.legend(loc="upper right") plt.ylim(0, 1) plt.grid(True) plt.show()

sklearn结果对比

image.png

总结

Scikit learn 也简称 sklearn, 是机器学习领域当中最知名的 python 模块之一。Sklearn 把所有机器学习的模式整合统一起来了,学会了一个模式就可以通吃其他不同类型的学习模式。

おすすめ

転載: blog.51cto.com/15127564/2667407