基于樸素貝葉斯自動過濾垃圾廣告
貝葉斯定理
貝葉斯定理是關于事件A和事件B的條件概率。先認識一下這幾個符號:
P(A|B):表示在事件B發生的情況下事件A發生的概率
P(B|A):表示在事件A發生的情況下事件B發生的概率
通常在已知P(A|B)的情況下,計算P(B|A)的值,此時P(A|B)可以稱為先驗概率,P(B|A)稱為后驗概率。
這個時候貝葉斯定理就登場啦:

通過這個定理我們就可以計算出P(B|A)的值。舉個栗子:
一座別墅在過去的 20 年里一共發生過 2 次被盜,別墅的主人有一條狗,狗平均每周晚上叫 3 次,在盜賊入侵時狗叫的概率被估計為 0.9,在狗叫的時候發生入侵的概率是多少?
我們假設 A 事件為狗在晚上叫,B 為盜賊入侵,則以天為單位統計,P(A) = 3/7,P(B) = 2/(20*365) = 2/7300,P(A|B) = 0.9,按照公式很容易得出結果:P(B|A) = 0.9*(2/7300) / (3/7) = 0.00058
貝葉斯定理延伸
其實到這里只是貝葉斯定理的簡單版,下面來看看它的一般版。一般事件B的發生不止有一個影響因素,比如事件B為早上是否吃早餐,那么事件A1可以為幾點起床,A2表示為早上是否有課,A3天氣是否寒冷,...An食堂早餐賣到幾點,這n個事件共同影響事件B是否吃早飯的發生,此時各事件的概率就發生了變化:
P(A)=P(A1,A2,A3,...An)
P(A|B)=P(A1,A2,A3,...An|B)
假設A1,A2,A3,...An都有兩種結果,那么一共有2^n個結果,對應需要的樣本數也是呈指數增加,這顯然是不合實際的,這時,就提出了半樸素貝葉斯和樸素貝葉斯。
這兩個定理都有樸素二字,這二字什么意思呢?白話一點就是簡化的意思,將A1,A2,A3,...An這n個事件的關聯切斷,假設它們是相互獨立的,即P(A)=P(A1,A2,A3,...An)=P(A1)P(A2)P(A3)...P(An);
P(A|B)=P(A1,A2,A3,...An|B)=
P(A1|B)P(A2|B)P(A3|B)...P(An|B)
這么一樸素,整個過程簡單了不止一點點。但是事件A1可以為幾點起床和事件A2表示為早上是否有課真的一點關聯都沒有嗎?肯定是有關聯的,將相關性很高的一些事件提出,P(A)=P(A1,A2,A3,...An)=
P(A1)P(A2)P(A3)...P(An)P(A1A2);既不忽略事件的相關性,又擁有樸素的特性,這就叫半樸素貝葉斯。
半樸素貝葉斯
樸素貝葉斯分類的正式定義如下:
1、設

為一個待分類項,而每個a為x的一個特征屬性。
2、有類別集合

3、計算

4、如果

則

基于屬性條件獨立性假設,現在來計算P(y1|x),P(y2|x),...P(yn|x)。

對于所有類別來說P(x)是相同的,因此只需計算分子部分。

在實際計算時,為了避免下溢(小數點位數過高),一般會對等式兩邊同時進行Ln變形,將*變為+;這里ln為一個增函數,因此可以保證不改變P(yn|x)的大小排序。
另一個需要注意的點是:樣本數是有限的,不可能包括所有的情形,這時會出現P(xn|yi)=0,但是這種情況不出現是不等價于不發生的,這是用到拉普拉斯修正進行平滑:
P(xn|yi)=(N(結果yi發生的前提下xn發生的次數)+1)/(結果yi發生的次數+屬性xn所有可能的取值)
數據預處理

上圖是這次要用到的原始數據,一行代表一則廣告。ham代表有用的廣告,spam代表垃圾短信。預處理一共有三部:
第一步:將數據讀入進來。
def read_txt():
file = 'C:/Users/伊雅/Desktop/bayes.txt'
with open(file, encoding='utf-8') as f:
con = f.readlines()
return con
第二步:廣告存到dataset中,分類結果存儲到txt_class中,得到一個詞匯表將dataset中的廣告用于split為一個一個的單詞,并將長度小于1的單詞去掉(a)
def create_word_list(con):
reg = re.compile(r'W*')
dataset = []
wordlist = set([])
txt_class = []
for i in con[1:]:
dataset.append(re.split(reg, i)[1:])
wordlist = wordlist | set(re.split(reg, i)[1:])
if re.split(reg, i)[0]=='ham':#有用的郵件
txt_class.append(1)
else:#垃圾郵件
txt_class.append(0)
wordlist=[i for i in wordlist if len(i)>2]
return dataset,wordlist,txt_class
第三步:對每一個廣告做循環,通過函數words_vec輸入參數為每則廣告的單詞以及詞匯表wordlists,返回一個文檔向量,向量的每一個元素為0或1,分別表示詞匯表中的單詞在廣告次中是否出現,如果出現該單詞的index則更新為1,否則則為0。
def words_vec(txt,wordlist):
returnvec=[0]*len(wordlist)
for word in txt:
if word in wordlist:
returnvec[list(wordlist).index(word)]=1
return returnvec
經過這三步把單詞文本轉化為了數學向量,大大簡化了計算。
請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
- 1 AI狂歡遇上油價破百,全球股市還能漲多久? | 產聯看全球
- 2 OpenAI深夜王炸!ChatGPT Images 2.0實測:中文穩、細節炸,設計師慌了
- 3 6000億美元估值錨定:字節跳動的“去單一化”突圍與估值重構
- 4 Tesla AI5芯片最新進展總結
- 5 連夜測了一波DeepSeek-V4,我發現它可能只剩“審美”這個短板了
- 6 熱點丨AI“瑜亮之爭”:既生OpenClaw,何生Hermes?
- 7 AI界的殺豬盤:9秒刪庫跑路,全員被封號,還繼續扣錢!
- 8 2026,人形機器人只贏了面子
- 9 DeepSeek降價90%:價格屠夫不是身份,是戰略
- 10 AI Infra產業鏈卡在哪里了?


分享













