1. 数据集说明
trec06c是一个公开的垃圾邮件语料库,由国际文本检索会议提供,分为英文数据集(trec06p)和中文数据集(trec06c),其中所含的邮件均来源于真实邮件保留了邮件的原有格式和内容,下载地址:https://plg.uwaterloo.ca/~gvcormac/treccorpus06/
由于数据集分散在各个文件中,为了方便我将正样本和负样本分别放在了ham_data和spam_data文件夹中(处女座的强迫症)
正样本数:21766
负样本数:42854
中文停用词:chinese_stop_vocab.txt
下面使用的所有数据集都已上传github
2. 实现思路
- 对单个邮件进行数据预处理
- 去除所有非中文字符,如标点符号、英文字符、数字、网站链接等特殊字符
- 对邮件内容进行分词处理
- 过滤停用词
- 创建特征矩阵和样本数据集
- feature_maxtrix:shape=(samples, feature_word_nums)
- leabel; shape = (samples, 1)
- 词向量的选择:索引或word2vect,注意二者的区别
拆分数据集:训练数据集、测试数据集和验证数据集
选择模型,这里选择svm
训练、测试、调参
3. 具体实现过程
3.1 所用到的库
import os
import jieba
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.model_selection import RandomizedSearchCV,train_test_split
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
from scipy.stats import uniform
3.2 将邮件转换为特征词矩阵类
class EmailToWordFeatures:
'''
功能:将邮件转换为特征词矩阵
整个过程包括:
- 对邮件内容进行分词处理
- 去除所有非中文字符,如标点符号、英文字符、数字、网站链接等特殊字符
- 过滤停用词
- 创建特征矩阵
'''
def __init__(self,stop_word_file=None,features_vocabulary=None):
self.features_vocabulary = features_vocabulary
self.stop_vocab_dict = {} # 初始化停用词
if stop_word_file is not None:
self.stop_vocab_dict = self._get_stop_words(stop_word_file)
def text_to_feature_matrix(self,words,vocabulary=None,threshold =10):
cv = CountVectorizer()
if vocabulary is None:
cv.fit(words)
else:
cv.fit(vocabulary)
words_to_vect = cv.transform(words)
words_to_matrix = pd.DataFrame(words_to_vect.toarray()) # 转换成索引矩阵
print(words_to_matrix.shape)
# 进行训练特征词选择,给定一个阈值,当单个词在所有邮件中出现的次数的在阈值范围内时及选为训练特征词、
selected_features = []
selected_features_index = []
for key,value in cv.vocabulary_.items():
if words_to_matrix[value].sum() >= threshold: # 词在每封邮件中出现的次数与阈值进行比较
selected_features.append(key)