垃圾邮件分类
- 朴素贝叶斯的介绍:
贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素贝叶斯(Naive Bayes)分类是贝叶斯分类中最简单,也是常见的一种分类方法。
朴素贝叶斯算法的核心思想是通过考虑特征概率来预测分类,即对于给出的待分类样本,求解在此样本出现的条件下各个类别出现的概率,哪个最大,就认为此待分类样本属于哪个类别。 - 朴素贝叶斯的优缺点:
优点:在数据较少的情况下依然有效,可以处理多类别问题
缺点:对于输入数据的准备方式较为敏感 - 朴素贝叶斯的算法:
朴素贝叶斯模型的基本思想是:对于给定的待分类项 X { a 1 , a 2 , a 3 , ⋯ , a n } X \left{ a_1,a_2,a_3,⋯,a_n \right}X{a 1,a 2,a 3,⋯,a n },求解在此项出现的条件下各个类别yi出现的概率,哪个P ( yi ∣ X ) 最大,就把此待分类项归属于哪个类别。
这里用数学问题来介绍一下:
一号箱子放有红色球和白色球各 20 个,二号箱子放油白色球 10 个,红色球 30 个。现在随机挑选一个箱子,取出来一个球的颜色是红色的,请问这个球来自一号箱子的概率是多少?
P(A)=取出红球的概率。P(B)=一号箱的概率。
P(A|B)=当选择一号箱时,取出红色球的概率。
P(B|A)=当条件 A 发生时,B 的概率是多少。代入:当球是红色时,来自一号箱的概率是多少?
P(B|A)=P(A|B)*P(B)/P(A)
P ( A ) 是先验概率,一般都是人主观给出的。贝叶斯中的先验概率一般特指它。
P ( B ) 是先验概率,在贝叶斯的很多应用中不重要(因为只要最大后验不求绝对值),需要时往往用全概率公式计算得到。
P ( B ∣ A ) 是条件概率,又叫似然概率,一般是通过历史数据统计得到。
P ( A ∣ B ) 是后验概率,一般是我们求解的目标。 - 垃圾邮件的分类实现
1.数据集的收集:
邮件的收集来源于网上,保存在email文件夹中。其中email分两个子文件,一个为right文件夹(保存非垃圾邮件),另一个为wrong文件夹(保存垃圾邮件)。right与wrong中各保存25各邮件,保存格式为x.txt(x为1到25)。
2.训练集和测试集的选取:
取80%的邮件作为训练集,其方式为随机选取。剩余20%邮件作为测试集。 - 代码的实现
import math
import os
import re
from collections import Counter
class Spamfilter:
"""A naive Bayesian spam filter"""
def __init__(self, training_dir):
""" inits Spamfilter with training data
:param training_dir: path of training directory with subdirectories
'/ham' and '/spam'
"""
print("Training filter with known ham ...")
self.ham_table = dict(Counter(dir_tokens(training_dir + "ham/")))
print("Training filter with known spam...")
self.spam_table = dict(Counter(dir_tokens(training_dir + "spam/")))
self.uniq_h_toks = len(self.ham_table)
self.uniq_s_toks = len(self.spam_table)
self.total_h_toks = sum(self.ham_table.values())
self.total_s_toks = sum(self.spam_table.values())
self.tok_arr = sorted(
list(self.ham_table.keys()) + list(self.spam_table.keys())
)
self.freq_tab = self.create_frequency_table()
self.file_count = 0
self.count_spam = 0
self.count_ham = 0
self.spam_list = []
self.ham_list = []
def create_frequency_table(self):
""" Generates token frequency table from training emails
:return: dict{
k,v}: spam/ham frequencies
k = (str)token, v = {
spam_freq: , ham_freq:, prob_spam:, prob_ham:}
"""
freq_table = {
}
for tok in self.tok_arr:
entry = {
}


2967

被折叠的 条评论
为什么被折叠?



