CNN中文垃圾邮件分类(一)

版权声明:转载请注明出处 https://blog.csdn.net/The_lastest/article/details/81672711

整理自唐宇迪老师的视频课程,感谢他!

1.思路

对于中文垃圾邮件的分类,在CNN部分同前面介绍的英文垃圾邮件分类完全相同。而不同之处在于对数据的预处理上。

由于英文自然而然的是用空格隔开的,所以对于中文来说,首先要做的就是分词。而对于分词后,就有两种处理方式:

第一种,完全效仿英文的处理方式;建立词表,得到每封邮件中每个词在词表中的索引,然后随机初始化一个词向量矩阵,利用标签让它们自己训练。值得注意的是,在处理中文时,文本的长度可能过大,所以对于文本的最大长度max_document_length就不要选择邮件中词数最长的为标准了。比如在此例中,最长的邮件有300多个词,我开始也选择了这个,不过太大跑不动,于是我就只选择了100为长度,但效果依然很好。

第二种,先用分好词的数据作为训练语料,选择前n个词作为词表,然后先训练出每个词所代表的词向量。再根据词表得到每封邮件中每个词在词表中的索引,然后按索引取出向量量堆叠起来。同样,对于文本长度也要选取一个合适的值。

2.数据预处理

在此处,我们先用第一种方式来进行预处理,然后在下一篇博客中,再来用第二种方法处理。

先来看看数据集,下面分别是一封垃圾垃圾邮件和一封正常邮件:

真正的爱就那么一次,不想委屈自己,也不能委屈别人。不过是孤单,不过是落寞。 想起小家伙的时候就不觉得孤单了,世界上最近的距离,不是两个人面对面说情话, 而是,小家伙一直在我心里面,在那个夏天,微微笑。换了岁月,不变容颜,沧海桑田, 作为一个男人我有着和你一样细腻的心情也好感情也罢,但是我觉得作为男人是不应该这么细腻的,是最近两年才感觉到的,这对一个男人来说是致命的弱点,所以我在改的像一个真正的北方汉子!

靓图请点击:http://elin.home.sunbo.net/ 众所周知,意大利是个出美女的地方,但跟其他美女相比, 意大利国宝级宝贝BENEDETTA却有她独特的撩人魅力, 那一头柔软而卷曲的黑发,那勾魂慑魄的眼神,那美妙绝伦的曲线,实在让你不能不被打动。 靓图请点击:http://elin.home.sunbo.net/

我们可以看到,首先在按行读入(原始数据每一行为一封邮件)的时候需要去掉其他非中文字符,然后进行分词,接着保存到list中开始处理下一行。
紧接着之后就是构造标签了。

def clean_str(string):
    string.strip('\n')
    string = re.sub(r"[^\u4e00-\u9fff]", " ", string)
    string = re.sub(r"\s{2,}", " ", string)
    return string.strip()

def cut_line(line):
    line = clean_str(line)
    seg_list = jieba.cut(line)
    cut_words = " ".join(seg_list)
    return cut_words
def load_data_and_labels(positive_data_file, negative_data_file):
    positive = []
    negative = []
    for line in open(positive_data_file,encoding='utf-8'):
        positive.append(cut_line(line))
    for line in open(negative_data_file,encoding='utf-8'):
        negative.append(cut_line(line))
    x_text = positive + negative

    positive_label = [[0, 1] for _ in positive]  # 构造one-hot 标签[[0, 1], [0, 1], [0, 1], [0, 1],....]
    negative_label = [[1, 0] for _ in negative]

    y = np.concatenate([positive_label, negative_label], axis=0)

    return x_text,y

处理后的结果大致如下:(每个样本间用逗号隔开)

 ['中信   国际   电子科技 有限公司 推出 新 产品   升职 步步高   做生意 发大财   连 找 情人 都 用 的 上   详情 进入   网   址   电话   服务 热线', '您好   本 公司 主要 从事 税务代理   并 可代 开发票 范围 如下   商品销售 发票   广告   运输   建筑   服务 咨询 等 发票   税率   点   增值税 发票 税率   点   所 开发票 皆 可验证 后 付款   联系人   张 小姐   电话   邮箱']

3.数字化训练集并训练

vocab_processor = learn.preprocessing.VocabularyProcessor(max_document_length)
x = np.array(list(vocab_processor.fit_transform(x_text)))  # 得到每个样本中,每个单词对应在词典中的序号

np.random.seed(10)
shuffle_indices = np.random.permutation(np.arange(len(y)))
x_shuffled = x[shuffle_indices]  # 打乱数据
y_shuffled = y[shuffle_indices]


dev_sample_index = -1 * int(FLAGS.dev_sample_percentage * float(len(y)))
x_train, x_dev = x_shuffled[:dev_sample_index], x_shuffled[dev_sample_index:]
y_train, y_dev = y_shuffled[:dev_sample_index], y_shuffled[dev_sample_index:]  # 划分训练集和验证集

最终的训练模型在测试集上也能达到1的效果。由于这仅仅只是一个二分类问题,并且垃圾邮件和正常邮件之间比较容易分辨,所以采用这种数据预处理方式也能得到很好的效果。但是跟一般的应该是先训练词向量,这将在下一篇博客中讲述。

源码

猜你喜欢

转载自blog.csdn.net/The_lastest/article/details/81672711