朴素貝葉斯(垃圾郵件分類)
郵箱訓練集下載地址
郵箱訓練集可以加我微信:a1171958281
模塊導入
import re
import os
from jieba import cut
from itertools import chain
from collections import Counter
import numpy as np
from sklearn.naive_bayes import MultinomialNB
文本預處理
def get_words(filename):
"""讀取文本並過濾無效字符和長度為1的詞"""
words = []
with open(filename, 'r', encoding='utf-8') as fr:
for line in fr:
line = line.strip()
# 過濾無效字符
line = re.sub(r'[.【】0-9、——。,!~\*]', '', line)
# 使用jieba.cut()方法對文本切詞處理
line = cut(line)
# 過濾長度為1的詞
line = filter(lambda word: len(word) > 1, line)
words.extend(line)
return words
遍歷郵件
all_words = []
def get_top_words(top_num):
"""遍歷郵件建立詞庫后返回出現次數最多的詞"""
filename_list = ['郵件_files/{}.txt'.format(i) for i in range(151)]
# 遍歷郵件建立詞庫
for filename in filename_list:
all_words.append(get_words(filename))
# itertools.chain()把all_words內的所有列表組合成一個列表
# collections.Counter()統計詞個數
freq = Counter(chain(*all_words))
return [i[0] for i in freq.most_common(top_num)]
top_words = get_top_words(100)
# 構建詞-個數映射表
vector = []
for words in all_words:
'''
words:
['國際', 'SCI', '期刊', '材料', '結構力學', '工程', '雜志', '國際', 'SCI', '期刊', '先進', '材料科學',
'材料', '工程', '雜志', '國際', 'SCI', '期刊', '圖像處理', '模式識別', '人工智能', '工程', '雜志', '國際',
'SCI', '期刊', '數據', '信息', '科學雜志', '國際', 'SCI', '期刊', '機器', '學習', '神經網絡', '人工智能',
'雜志', '國際', 'SCI', '期刊', '能源', '環境', '生態', '溫度', '管理', '結合', '信息學', '雜志', '期刊',
'網址', '論文', '篇幅', '控制', '以上', '英文', '字數', '以上', '文章', '撰寫', '語言', '英語', '論文',
'研究', '內容', '詳實', '方法', '正確', '理論性', '實踐性', '科學性', '前沿性', '投稿', '初稿', '需要',
'排版', '錄用', '提供', '模版', '排版', '寫作', '要求', '正規', '期刊', '正規', '操作', '大牛', '出版社',
'期刊', '期刊', '質量', '放心', '檢索', '穩定', '邀請函', '推薦', '身邊', '老師', '朋友', '打擾', '請諒解']
'''
word_map = list(map(lambda word: words.count(word), top_words))
'''
word_map:
[0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
'''
vector.append(word_map)
訓練模型
vector = np.array(vector)
# 0-126.txt為垃圾郵件標記為1;127-151.txt為普通郵件標記為0
labels = np.array([1]*127 + [0]*24)
model = MultinomialNB()
model.fit(vector, labels)
測試模型
def predict(filename):
"""對未知郵件分類"""
# 構建未知郵件的詞向量
words = get_words(filename)
current_vector = np.array(
tuple(map(lambda word: words.count(word), top_words)))
# 預測結果
result = model.predict(current_vector.reshape(1, -1))
return '**垃圾郵件**' if result == 1 else '普通郵件'
print('151.txt分類情況:{}'.format(predict('郵件_files/151.txt')))
print('152.txt分類情況:{}'.format(predict('郵件_files/152.txt')))
print('153.txt分類情況:{}'.format(predict('郵件_files/153.txt')))
print('154.txt分類情況:{}'.format(predict('郵件_files/154.txt')))
print('155.txt分類情況:{}'.format(predict('郵件_files/155.txt')))