参与:王宇欣、吴攀 本文介绍了如何通过 Python 和 scikit-learn 实现垃圾邮件过滤的。对比和分析了两个分类器的结果:多项式朴素贝叶斯和支持向量机。 文本挖掘(text mining,从文本中导出信息)是一个广泛的领域,因为不断产生的巨量文本数据而已经得到了普及。情绪分析、文档分类、主题分类、文本概括、机器翻译等许多任务的自动化都已经通过机器学习得到了实现。 垃圾邮件过滤(spam filtering)是文档分类任务的入门级示例,开奖,其涉及了将电子邮件分为垃圾邮件或非垃圾邮件(也称为 ham)。你的 Gmail 账户的垃圾邮箱就是最好的例子。那么让我们在公开的邮件语料库上构建垃圾邮件过滤器吧。我已经从 Ling-spam 语料库()上提取了同等数量的垃圾邮件和非垃圾邮件。我们从这里下载将要对其操作的提取出来的子集:https://www.dropbox.com/s/yjiplngoa430rid/ 我们将通过以下步骤构建此应用程序: 1. 准备文本数据 2. 创建词典 3. 特征提取过程 4. 训练分类器 此外,我们将在该子集中的测试集上测试我们的结果。 1、 准备文本数据 这里使用的数据集被分为训练集和测试集,分别包含了 702 封邮件和 260 封邮件,其中垃圾邮件和 ham 邮件的数量相等。垃圾邮件的文件名中包含了 spmsg,所以很容易识别。 在任何一个文本挖掘问题中,文本清理(text cleaning)是我们从文档中删除那些可能对我们想要提取的信息无用的文字的第一步。电子邮件可能包含了大量对垃圾邮件检测无用的字符,如标点符号、停止词、数字等。Ling-spam 语料库中的邮件已经通过以下方式进行了预处理: a) 移除停止词—像「and」、「the」、「of」之类的停止词在所有的英语句子当中都非常常见,在判定是否为垃圾邮件时没有多少作用,所以这些词已经从电子邮件中删除。 b) 词形还原(lemmatization)—这是将一个单词的不同变化形式分组在一起的过程,以便其可被视为单个项进行分析。例如,「include」、「includes」和「included」将全部用「include」表示。在词形还原中,句子的语境也会得到保留,而词干提取(stemming)则不会。(词干提取是文本挖掘中的另一个术语,其不会考虑句意)。 我们还需要从邮件文档中删除非文字信息,比如标点符号或者特殊字符。有几种方法可以做到这一点。这里,我们将在创建词典后删除这样的词,这非常方便,因为当你有了一个词典时你只需要删除每个这样的单词一次。欢呼吧!!到现在为止,你不需要做任何事情。 2、创建词典 数据集中的示例邮件如下所示: hi , ' m work phonetics project modern irish ' m hard source . anyone recommend book article english ? ' , specifically interest palatal ( slender ) consonant , work helpful too . thank ! laurel sutton ( sutton @ garnet . berkeley . edu可以看出,邮件第一行是主题(subject),第三行包含了邮件的正文。我们只会对其内容执行文本分析以检测垃圾邮件。作为第一步,我们需要创建一个词及其频率的词典。对于此任务,我们使用了 700 封邮件作为训练集。这个 Python 函数可为你创建这个词典。 def make_Dictionary(train_dir): emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)] all_words = [] for mail in emails: with open(mail) as m: for i,line in enumerate(m): if i == 2: #Body of email is only 3rd line of text file words = line.split() all_words += words dictionary = Counter(all_words) # Paste code for non-word removal here(code snippet is given below) return dictionary 一旦词典被创建,我们可以添加下面几行代码到上面的函数以删除移除非词(如第 1 步所示)。我也删除了词典中不合理的单个字符,这些字符在这里是不相关的。别忘了在函数 def make_Dictionary(train_dir) 中插入以下代码。 list_to_remove = dictionary.keys() for item in list_to_remove: if item.isalpha() == False: del dictionary[item] elif len(item) == 1: del dictionary[item] dictionary = dictionary.most_common(3000) (责任编辑:本港台直播) |