目录
一、数据预处理
二、训练
三、测试
四、全部代码及数据集
一、数据预处理
经过常用的数据预处理,如删除停用词等后,统计所有训练集中垃圾邮件的内容,经分词后输出频次,得到垃圾邮件的特征库并画出词云图
background_image = np.array(Image.open('001.png'))
colormaps = colors.ListedColormap(['#871A84', '#BC0F6A', '#BC0F60', '#CC5F6A', '#AC1F4A'])
wordcloud = WordCloud(font_path='simhei.ttf', # 字体
prefer_horizontal=0.99,
background_color='white', # 背景色
max_words=200, # 显示单词数
max_font_size=200, # 最大字号
stopwords=stop, # 过滤噪声词
mask=background_image, # 背景轮廓
colormap=colormaps, # 使用自定义颜色
collocations=False
).fit_words(dict)
image = wordcloud.to_image()
image.show() # 展示图片
wordcloud.to_file('词云图.png') # 保存图片片
二、训练
普通的朴素贝叶斯训练过程,本实验采用定义来做,并没有调用库。最终利用GUI可视化来训练过程和结果
本实验可以通过GUI界面更改垃圾邮件的权重,训练集和测试集的比例,选择是否加权等。
def test(row):
# 总邮件数量
total = ham + spam
wordDict = row['wordDict']
V = len(wordDict)
# 正常邮件概率,取对数防止数值过小,取对数不影响概率的比较
hp = math.log(float(ham) / total)
# 垃圾邮件概率
sp = math.log(float(spam) / total)
for w in wordDict:
w = w.strip()
# 在统计词典中查找该词,未查找到则赋予默认值
countDict.setdefault(w, {0: 0, 1: 0}) # w[0]=0, w[1]=0
pih = countDict[w][0] # 该词在词典中正常邮件出现的次数
pis = countDict[w][1] # 该词在词典中垃圾邮件出现的次数
# 平滑处理,防止出现零概率, 每个词汇基数+1,正常邮件数+2(因为有两种类型邮件所以+2)
# 因为取对数,可以将概率的逐个相乘转化为逐个相加
if m == '是':
Wh = ((pih + 1) / (ham + 2)) / ((pis + 1) / (spam + 2))
Ws = ((pis + 1) / (spam + 2)) / ((pih + 1) / (ham + 2))
hp += ((math.log((float(pih) + 1) / (ham + 2)) + 10) * Wh)
sp += ((math.log((float(pis) + 1) / (spam + 2)) + 10) * Ws)
else:
Wh = (pih + 1) / (ham + V)
Ws = (pis + 1) / (spam + V)
hp += math.log(float(Wh))
sp += math.log(float(Ws))
# 得到预测结果
# predict = 1 if sp > hp else 0 # 直接比较
predict = 1 if sp > hp * k else 0
# print("hp=", hp)
# print("sp=", sp)
# print("=======================")
# 判断预测值跟真实值是否相符
return 1 if predict == row['spam'] else 0
三、测试
新增黑白名单功能
先经过黑白名单的检测再输出结果
运用一个简单的判断语句:
for email in emails_found:
if email in white_emails_to_compare:
print(f'发件人{email} 在白名单内')
elif email in black_emails_to_compare:
print(f'发件人{email} 在黑名单内')
else:
print(f'发件人{email} 既不在黑名单也不在白名单')