文章目录
1 前言
Hi,大家好,这里是丹成学长,今天做一个nlp项目,基于机器学习的垃圾邮件分类
🧿 选题指导, 项目分享:见文末
2 垃圾短信/邮件 分类算法 原理
垃圾邮件内容往往是广告或者虚假信息,甚至是电脑病毒、情色、反动等不良信息,大量垃圾邮件的存在不仅会给人们带来困扰,还会造成网络资源的浪费;
网络舆情是社会舆情的一种表现形式,网络舆情具有形成迅速、影响力大和组织发动优势强等特点,网络舆情的好坏极大地影响着社会的稳定,通过提高舆情分析能力有效获取发布舆论的性质,避免负面舆论的不良影响是互联网面临的严肃课题。
将邮件分为垃圾邮件(有害信息)和正常邮件,网络舆论分为负面舆论(有害信息)和正面舆论,那么,无论是垃圾邮件过滤还是网络舆情分析,都可看作是短文本的二分类问题。
2.1 常用的分类器 - 贝叶斯分类器
贝叶斯算法解决概率论中的一个典型问题:一号箱子放有红色球和白色球各 20 个,二号箱子放油白色球 10 个,红色球 30 个。现在随机挑选一个箱子,取出来一个球的颜色是红色的,请问这个球来自一号箱子的概率是多少?
利用贝叶斯算法识别垃圾邮件基于同样道理,根据已经分类的基本信息获得一组特征值的概率(如:“茶叶”这个词出现在垃圾邮件中的概率和非垃圾邮件中的概率),就得到分类模型,然后对待处理信息提取特征值,结合分类模型,判断其分类。
贝叶斯公式:
P(B|A)=P(A|B)*P(B)/P(A)
P(B|A)=当条件 A 发生时,B 的概率是多少。代入:当球是红色时,来自一号箱的概率是多少?
P(A|B)=当选择一号箱时,取出红色球的概率。
P(B)=一号箱的概率。
P(A)=取出红球的概率。
代入垃圾邮件识别:
P(B|A)=当包含"茶叶"这个单词时,是垃圾邮件的概率是多少?
P(A|B)=当邮件是垃圾邮件时,包含“茶叶”这个单词的概率是多少?
P(B)=垃圾邮件总概率。
P(A)=“茶叶”在所有特征值中出现的概率。
3 数据集介绍
使用中文邮件数据集:丹成学长自己采集,通过爬虫以及人工筛选。
数据集“data” 文件夹中,包含,“full” 文件夹和 “delay” 文件夹。
“data” 文件夹里面包含多个二级文件夹,二级文件夹里面才是垃圾邮件文本,一个文本代表一份邮件。“full” 文件夹里有一个 index 文件,该文件记录的是各邮件文本的标签。
数据集可视化:
4 数据预处理
这一步将分别提取邮件样本和样本标签到一个单独文件中,顺便去掉邮件的非中文字符,将邮件分好词。
邮件大致内容如下图:
每一个邮件样本,除了邮件文本外,还包含其他信息,如发件人邮箱、收件人邮箱等。因为我是想把垃圾邮件分类简单地作为一个文本分类任务来解决,所以这里就忽略了这些信息。
用递归的方法读取所有目录里的邮件样本,用 jieba 分好词后写入到一个文本中,一行文本代表一个邮件样本:
import re
import jieba
import codecs
import os
# 去掉非中文字符
def clean_str(string):
string = re.sub(r"[^\u4e00-\u9fff]", " ", string)
string = re.sub(r"\s{2,}", " ", string)
return string.strip()
def get_data_in_a_file(original_path, save_path='all_email.txt'):
files = os.listdir(original_path)
for file in files:
if os.path.isdir(original_path + '/' + file):
get_data_in_a_file(original_path + '/' + file, save_path=save_path)
else:
email = ''
# 注意要用 'ignore',不然会报错
f = codecs.open(original_path + '/' + file, 'r', 'gbk', errors='ignore')
# lines = f.readlines()
for line in f:
line = clean_str(line)
email += line
f.close()
"""
发现在递归过程中使用 'a' 模式一个个写入文件比 在递归完后一次性用 'w' 模式写入文件快很多
"""
f = open(save_path, 'a', encoding='utf8')
email = [word for word in jieba.cut(email) if word.strip() != '']
f.write(' '.join(email) + '\n