0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何用PaddlePaddle手写一个垃圾邮件分类器

lviY_AI_shequ 来源:未知 作者:李倩 2018-06-19 15:05 次阅读

擅长用通俗易懂的方式讲解深度学习机器学习算法,熟悉Tensorflow,PaddlePaddle等深度学习框架,负责过多个机器学习落地项目,如垃圾评论自动过滤,用户分级精准营销,分布式深度学习平台搭建等,都取了的不错的效果。

背景介绍

在我们日常生活中,经常会受到各种垃圾邮件,譬如来自商家的广告、打折促销信息、澳门博彩邮件、理财推广信息等,一般来说邮件客户端都会设置一定的关键词屏蔽这种垃圾邮件,或者对邮件进行归类,但是总会有一些漏网之鱼。  不过,自己手动做一个垃圾邮件分类器也并不是什么难事。传统的机器学习算法通常会采用朴素贝叶斯、支持向量机等算法对垃圾邮件进行过滤,今天我们主要讲如何用PaddlePaddle手写一个垃圾邮件分类器。当然,在讲PaddlePaddle做垃圾邮件处理之前,先回顾一下传统的机器学习算法是如何对垃圾邮件进行分类的。

了解数据集

首先先了解一下今天的数据集:trec06c。trec06c是一个公开的垃圾邮件语料库,由国际文本检索会议提供,分为英文数据集(trec06p)和中文数据集(trec06c),其中所含的邮件均来源于真实邮件保留了邮件的原有格式和内容。文件下载地址:trec06c文件格式:

trec06c│└───data│ │ 000│ │ 001│ │ ...│ └───215└───delay│ │ index└───full│ │ index

文件内容:

垃圾邮件示例:本公司有部分普通发票(商品销售发票)增值税发票及海关代征增值税专用缴款书及其它服务行业发票,公路、内河运输发票。可以以低税率为贵公司代开,本公司具有内、外贸生意实力,保证我司开具的票据的真实性。 希望可以合作!共同发展!敬侯您的来电洽谈、咨询! 联系人:李先生 联系电话:13632588281 如有打扰望谅解,祝商琪。正常邮件示例:讲的是孔子后人的故事。一个老领导回到家乡,跟儿子感情不和,跟贪财的孙子孔为本和睦。老领导的弟弟魏宗万是赶马车的。有个洋妞大概是考察民俗的,在他们家过年。孔为本总想出国,被爷爷教育了。最后,一家人基本和解。 顺便问另一类电影,北京青年电影制片厂的。

数据预处理

拿到数据后我们可以很清楚的看到邮件的内容,但并不是所有的内容都是我们需要的,在这里我们仅提取了邮件中的中文来作为训练语料。如果仔细观察的话,会发现不是所有的邮件都能直接打开,数据的编码格式也需要转换成utf-8格式方便我们后面训练使用。所以我们需要对原始数据做一些数据预处理,包括以下几个内容。

基本步骤

转换源数据编码格式为utf-8格式

过滤字符

去除所有非中文字符,如标点符号、英文字符、数字、网站链接等特殊字符。

过滤停用词

对邮件内容进行分词处理

训练代码

下面是具体的代码 transfer.py:

# -*- coding: utf-8 -*-#Created by huxiaoman 2018.1.28#transfer.py:生成spam和ham数据import jiebaimport sysimport osimport re# 判断邮件中的字符是否是中文def check_contain_chinese(check_str): for ch in check_str.decode('utf-8'): if u'\u4e00' <= ch <= u'\u9fff': return True return False# 加载邮件数据的labeldef load_label_files(label_file): label_dict ={} for line in open(label_file).readlines(): list1 = line.strip().split("..") label_dict[list1[1].strip()] = list1[0].strip() return label_dict# 加载停用词词表def load_stop_train(stop_word_path): stop_dict = {} for line in open(stop_word_path).readlines(): line = line.strip() stop_dict[line] = 1 return stop_dict# 读取邮件数据,并转换为utf-8格式,生成spam和ham样本def read_files(file_path,label_dict,stop_dict,spam_file_path,ham_file_path): parents = os.listdir(file_path) spam_file = open(spam_file_path,'a') ham_file = open(ham_file_path,'a') for parent in parents: child = os.path.join(file_path,parent) if os.path.isdir(child): read_files(child,label_dict,stop_dict,spam_file_path,ham_file_path) else: print child[10:] label = "unk" if child[10:] in label_dict: label = label_dict[child[10:]] # deal file temp_list = [] for line in open(child).readlines(): line = line.strip().decode("gbk",'ignore').encode('utf-8') if not check_contain_chinese(line): continue seg_list = jieba.cut(line, cut_all=False) for word in seg_list: if word in stop_dict: continue else: temp_list.append(word) line = " ".join(temp_list) print label if label == "spam": spam_file.write(line.encode("utf-8","ignore") + "\n") if label == "ham": ham_file.write(line.encode("utf-8","ignore")+"\n")# 生成word2vec词表def generate_word2vec(file_path,label_dict,stop_dict,word_vec): parents = os.listdir(file_path) fh1 = open(word_vec,'a') i = 0 for parent in parents: child = os.path.join(file_path,parent) if os.path.isdir(child): generate_word2vec(child,label_dict,stop_dict,word_vec) else: print child[10:] i += 1 print i label = "unk" if child[10:] in label_dict: label = label_dict[child[10:]] # deal file temp_list = [] for line in open(child).readlines(): line = line.strip().decode("gbk",'ignore').encode('utf-8') if not check_contain_chinese(line): continue if len(line) == 0: continue seg_list = jieba.cut(line, cut_all=False) for word in seg_list: if word in stop_dict: continue else: temp_list.append(word) line = " ".join(temp_list) fh1.write(line.encode("utf-8","ingore")+"\n")if __name__=="__main__": file_path = sys.argv[1] label_path = sys.argv[2] stop_word_path = "stop_words.txt" word_vec_path = "word2vec.txt" spam_data = "spam.txt" ham_data = "ham.txt" label_dict = load_label_files(label_path) stop_dict = load_stop_train(stop_word_path) read_files(file_path,label_dict,stop_dict,spam_data,ham_data)

运行脚本

run.sh:

bashif [ $1 = "test" ]; then echo "test" python transfer.py ../test/ ../trec06c/full/indexelse echo "whole" python transfer.py ../trec06c/data/ ../trec06c/full/indexfi

运行方式:

sh run.sh

运行结果:

ham.txt: 正样本,正常邮件。共21373条数据。

示例:我 就 闹 不 明白 了 只要 你 本人 不介意 跟 你 爸爸妈妈 有 何干 为啥 要说 呢 ..... 首先 谢谢 大家 安慰 我 。 但是 我 确实 很 难受 , 我 有 自己 的 苦衷 。 我 不敢 和 我 妈妈 说 的 这种 情况 。 我 妈妈 是 那种 特别 容易 担心 的 那种 类型 。 而且 我 又 不 在 她 身边 。 我家 是 外地 的 。 如果 和 妈妈 说 了 , 她 一定 不会 同意 我 和 在 一起 的 。 妈妈 对 身体健康 看 的 特别 重要 。 有 一年 姐夫 那年 经常 流鼻血 , 妈妈 都 特别 担心 , 老 催 姐姐 带 着 去 看看 。

spam.txt: 负样本,垃圾邮件。共41627条数据。

示例:您好 以下 是 特别 为 阁下 发 的 香港 信息 图片 、 景点 等 不 知道 阁下 是否 喜 希望 没有 打扰到 阁下 如果 无法 看到 下面 内容 请 稍侯 或者 直接 进入 香港 行网 域名论坛 地址 真诚 为您服务

word2vec.txt: 包含所有邮件分词的内容,为Word2Vec提供训练预料。共63000条数据。

示例:我 觉得 , 负债 不要紧 , 最 重要 的 是 能 负得起 这个 责任 来 , 欠 了 那么 多钱 , 至少 对 当初 拿出 爱心 来 的 网友 们 有 个 交待 , 还 , 还是 不 还 了 , 或者 , 是 有 这个 心 但 实在 没 能力 , 说明 一声 还 都 好 不要 连 ID 都 不 激活 了 , 连 手机号 都 换 了 … … 别说 外地 的 了 , 就 连 北京 的 网友 都 找 不到 他 … … 他 当时 在 水木 fl 版 的 那阵 , 我 旁观 了 全过程 。

生成词向量

传统方法的局限性

我们知道,分词后的数据是不能直接拿到模型里去训练的,我们需要把词语转换成词向量才能进行模型的训练,这样一个词可以有一个多维的词向量组成。  传统的方法是one-hot encoding,即用一个长向量来表示一个词,向量的长度为词典的大小,向量的分量只有一个1,其余全为0,1的位置即对应改词在词典中的位置,如电脑表示为:[0 0 0 0 0 1 0 0 0 0 ],耳机表示为[0 0 0 0 0 0 0 1 0 ]这种方式如果采用稀疏存储,表达简洁,占用空间少,但是这种方法也有几个缺点,一是容易受维数灾难的困扰,尤其是将其用于 Deep Learning的一些算法时;二是不能很好地刻画词与词之间的相似性,即任意两个词之间都是孤立的。光从这两个向量中看不出两个词是否有关系,损失大部分信息,导致结果会有较大偏差。

Word2Vec方法的优势

在1968年Hinton又提出了Distributed REpresentation,可以One-hot encoding的缺点。其基本想法是直接用一个普通的向量表示一个词,这种向量一般长成这个样子:[0.792, −0.177, −0.107, 0.109, −0.542, ...],也就是普通的向量表示形式。维度以 50 维和 100 维比较常见。当然一个词怎么表示成这么样的一个向量需要通过训练得到,训练方法较多,word2vec是最常见的一种。需要注意的是,每个词在不同的语料库和不同的训练方法下,得到的词向量可能是不一样的。词向量一般维数不高,一般情况下指定1000、500维就可以了,所以用起来维数灾难的机会现对于one-hot representation表示就大大减少了。  由于是用向量表示,而且用较好的训练算法得到的词向量的向量一般是有空间上的意义的,也就是说,将所有这些向量放在一起形成一个词向量空间,而每一向量则为该空间中的一个点,在这个空间上的词向量之间的距离度量也可以表示对应的两个词之间的“距离”。所谓两个词之间的“距离”,就是这两个词之间的语法,语义之间的相似性。  一个比较不错的应用方法是,得到词向量后,假如对于某个词A,想找出这个词最相似的词,在建立好词向量后的情况,对计算机来说,只要拿这个词的词向量跟其他词的词向量一一计算欧式距离或者cos距离,得到距离最小的那个词,就是它最相似的。  所以在这里我们选择了word2vec方法来训练生成词向量。关于word2vec的原理大家可以在网上搜索学习,此处不再赘述。

实现代码

在数据预处理中我们生成的word2vec.txt就可以放到此处训练word2vec模型生成词向量了,具体实现代码如下: word2vec.py

# -*- coding: utf-8 -*-# Created by huxiaoman 2018.1.28# word2vec.py:生成word2vec模型import osimport sysimport numpy as npfrom gensim.models.word2vec import Word2Vecfrom gensim.corpora.dictionary import Dictionaryimport codecsreload(sys)sys.setdefaultencoding( "utf-8" )class MySentences(object): def __init__(self, dirname): self.dirname = dirname def __iter__(self): for fname in os.listdir(self.dirname): for line in codecs.open(os.path.join(self.dirname, fname),"r", encoding="utf-8",errors="ignore"): yield line.strip().split()# word2vec.txt数据的地址train_path = "rawData/"# 生成的word2vec模型的地址model_path = "/modelPath/"sentences = MySentences(train_path) # 此处min_count=5代表5元模型,size=100代表词向量维度,worker=15表示15个线程model = Word2Vec(sentences,min_count = 5,size=100,workers=15)#保存模型model.save(model_path+'/Word2vec_model.pkl')

运行方式

python word2vec.py

运行结果

Word2vec_model.pkl

模型训练

生成正负样本数据并将词语全部转化为词向量后我们就可以把数据灌倒模型里进行训练了,本篇中将采用传统的机器学习算法svm来进行训练。

具体步骤

加载数据集

划分训练集train、验证集val与测试集test

定义训练模型,并训练

验证准确率

实现代码

# 构建svm模型,加载数据等代码详见githubdef get_svm_model(x_train,y_train,x_val,y_val): model = SVC(C=1,kernel='rbf',max_iter=10,gamma=1,probability=True) model.fit(x_train,y_train) pred=model.predict(x_val) fpr,tpr,thresholds = roc_curve(y_val, pred, pos_label=2) score = metrics.f1_score(y_val,pred) print score

运行方式

python train_svm.py

运行结果

0.73343221

小结

本篇文章作为用PaddlePaddle处理垃圾邮件实战系列的预热,主要讲了如何对文本数据进行数据预处理与过滤,如何生成词向量以及用传统的机器学习方法--支持向量机训练模型,得到的准确率为0.73343221。其结果的好坏取决于词典的大小,词向量维度的大小,svm的基本参数的调整,在实际操作过程中还需要不断的调参才能达到最优的效果。下一篇我们将带领大家如何用PaddlePaddle来做垃圾邮件处理,用深度学习的方法对垃圾邮件进行分类,看看效果是否比传统的机器学习方法要更好,性能和速度是否能有一定的提升。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器学习
    +关注

    关注

    66

    文章

    8373

    浏览量

    132395
  • 数据集
    +关注

    关注

    4

    文章

    1205

    浏览量

    24635

原文标题:PaddlePaddle垃圾邮件处理实战(一)

文章出处:【微信号:AI_shequ,微信公众号:人工智能爱好者社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何防范垃圾邮件

    ;  3.被黑客利用成助纣为虐的工具。如在2000年2月,黑客攻击雅虎等五大热门网站就是例子。黑客先是侵入并控制了些高带宽的网站,集中众多服务的带宽能力,然后用数以亿万计的
    发表于 12-21 11:08

    防范垃圾邮件的秘诀!

    ;nbsp;  3.被黑客利用成助纣为虐的工具。如在2000年2月,黑客攻击雅虎等五大热门网站就是例子。黑客先是侵入并控制了些高带宽的网站,集中众多服务的带宽能力,然后用数以亿
    发表于 01-07 17:54

    看我如何防范垃圾邮件!!!

    2000年2月,黑客攻击雅虎等五大热门网站就是例子。黑客先是侵入并控制了些高带宽的网站,集中众多服务的带宽能力,然后用数以亿万计的垃圾邮件
    发表于 05-31 15:36

    朴素贝叶斯过滤邮箱里的垃圾邮件

    朴素贝叶斯垃圾邮件识别
    发表于 03-18 11:28

    基于协同过滤的垃圾邮件过滤系统

    针对当前垃圾邮件过滤技术中邮件性质评价难及邮件附件判断难的问题,提出协同过滤模型,设计多层次垃圾邮件
    发表于 04-10 08:39 26次下载

    代价敏感支持向量机在垃圾邮件过滤中的应用

    支持向量机在垃圾邮件过滤中能达到较高的分类准确率,实际应用中,将正常邮件误判为垃圾邮件会给用户造成更大的损失。该文提出
    发表于 04-22 10:01 14次下载

    基于朴素贝叶斯算法的垃圾邮件网关

    本文针对垃圾邮件过滤问题,结合中文自身的特点,把广泛适用于英文文本和邮件分类的朴素贝叶斯过滤方法应用在垃圾邮件网关邮件过滤层;把信息增益修剪
    发表于 08-14 14:28 17次下载

    基于Bayes的种改良垃圾邮件过滤模型

    文章首先分析了垃圾邮件的产生机理,介绍了目前比较常见的几种垃圾邮件过滤技术,然后从朴素贝叶斯的理论依据出发,针对当前应用于重要商业领域的垃圾邮件过滤系统的不足
    发表于 08-18 09:39 6次下载

    垃圾邮件(Spam)与邮件过滤技术

    垃圾邮件(Spam)与邮件过滤技术 垃圾邮件直是Internet的顽症之垃圾邮件不仅浪费
    发表于 03-02 11:40 1091次阅读
    <b class='flag-5'>垃圾邮件</b>(Spam)与<b class='flag-5'>邮件</b>过滤技术

    垃圾邮件详解

    垃圾邮件详解 引言 我们中的大多数人每天都会收到垃圾邮件。只不过有些人收到的多些,有些人则少些,但是对于拥有电子邮件账户的人来说,
    发表于 08-05 10:12 1364次阅读

    CCERT中文垃圾邮件过滤解决方案

    Chinese_rules.cf是用于业界广泛使用的免费垃圾邮件过滤系统 SpamAssassin的中文垃圾邮件过滤规则集。由于以前没有中文的过滤规则集,SpamAssassin对中文邮件过滤的准确性不高。CCERT反
    发表于 04-18 21:37 28次下载

    中文垃圾邮件过滤邮件服务的实现_李玉峰

    中文垃圾邮件过滤邮件服务的实现_李玉峰
    发表于 03-19 11:41 1次下载

    垃圾U-Mail邮件网关是如何防范垃圾邮件、病毒、钓鱼软件的攻击?

    首先当然是建立最庞大的数据样本库,这个库里收罗了世界各地最新涌现出来的垃圾邮件、病毒、钓鱼软件标本,U-Mail依托在全球主要中心城市架设的服务,能够第
    的头像 发表于 05-20 00:07 7976次阅读

    简单的伪贝叶斯垃圾邮件过滤主程序资料免费下载

    本文档的主要内容详细介绍的是简单的伪贝叶斯垃圾邮件过滤主程序资料免费下载。
    发表于 04-10 08:00 0次下载
    <b class='flag-5'>一</b><b class='flag-5'>个</b>简单的伪贝叶斯<b class='flag-5'>垃圾邮件</b>过滤主程序资料免费下载

    企业究竟该如何做好邮件安全防护,防止垃圾邮件的攻击?

    据不完全统计,全球超80%的企业邮箱用户,都曾遭遇过垃圾邮件的攻击。企业邮箱长期受到大量垃圾邮件的侵扰,严重影响了员工工作效率,而且还容易漏掉正常邮件,直接影响企业业务的开展。企业究竟该如何做好
    的头像 发表于 10-08 11:04 3371次阅读