垃圾邮件分类(trec06c数据集)数据处理-特征提取

目录

目标:我要提取 发件人(From)、收件人(To)、邮件主题(Subject)、邮件正文(zhengwen) 作为邮件特征,然后输入到线性分类模型中进行训练

首先是这四个特征提取的部分

发件人

收件人

邮件主题

邮件正文

获取 标签--路径 对照表

把这一部分的全部的代码放这儿:

~~~~~~~~~~~待更新~~~~~~~~~~~~~~~~~~~~~~~~~~~


数据集是这样的 

data里是数据文件

full里是index文件,存放哪个路径的文件是什么类型

index文件 (类型--文件路径 对照表)

目标:我要提取 发件人(From)、收件人(To)、邮件主题(Subject)、邮件正文(zhengwen) 作为邮件特征,然后输入到线性分类模型中进行训练

首先是这四个特征提取的部分

发件人

通过上面的邮件的图,可以看到From、Subject中有用gb2312和base64编码的部分,需要进行解码

另外 如果多打开几个文件可以观察到 From字段的情况比较复杂,我观察到了这四种(列在下面),其实可能不止这四种格式

From: wei@13.com
From: "yan"<(8月27-28,上海)培训课程>
From: ke@163.com" <chunyang-sz@163.com>
From: =?GB2312?B?zuLmw+bD?= <hou@163.com>

我做的处理步骤大体如下:

 解码部分优先用gb2312解 ,如果报异常 就在用gbk解,如果还是报异常,就直接赋空串

def From_email(email): # email是整封邮件的内容字符串
    # 发件人
    # 先提取From后的所有内容
    try:
        From_raw = re.search(r'From: (.*)', email).group(1)
    except:
        From_raw = ''
    From = ''
    # 先看看有没有加密部分 有加密部分就给他解密
    name = re.search(r'=\?GB2312\?B\?(.*)\?=', From_raw, re.I)  # name保存加密部分
    if name is None:  # 没有加密部分
        name = ''
        # 没有加密部分 就保留串的所有内容
        From = From_raw
    else:  # 有加密部分
        name = name.group(1)
        try:
            name = base64.b64decode(name).decode('gb2312')
        except:
            try:
                name = base64.b64decode(name).decode('gbk')
            except:
                name = ''
        From = name + re.search(r'\?=(.*)', From_raw).group(1)
    # print('From: ', From)
    return From

收件人

存在以TO: 开头的情况,加个re.I 就不区分大小写了

def To_email(email):
    # 收件人
    To = re.search(r'^To: (.*)', email, re.M | re.I).group(1)  # re.M 从每行文本开头的位置开始匹配
    # print('To: ', To)
    return To

邮件主题

处理这个字段的流程基本和From字段一样,Subject的格式比较统一,基本都是加密形式

def Subject_email(email):
    # 主题
    Subject = re.search(r'=\?gb2312\?B\?(.*)\?=', email)
    if Subject is None:
        Subject = ''
    else:  # subject 有内容
        Subject = Subject.group(1)
        Subject = base64.b64decode(Subject)  # 解密
        try:
            Subject = Subject.decode('gb2312')  # 解码
        except:
            try:
                Subject = Subject.decode('gbk')  # 解码
            except:
                Subject = ''
    # print('Subject: ', Subject)
    return Subject

邮件正文

有两个换行符后是正文的,也有三个换行符后是正文的情况,这里就直接:第一次成功遇到两个换行符,就返回之后的所有内容,re.S的作用是一直到正文底部,而不是\n\n随后的一行(单拎出来自己运行一下代码就懂我的意思了)

def zhengwen_email(email):
    # 正文
    zhengwen = re.search(r'\n\n(.*)', email, re.S).group(1)
    zhengwen = clean_str(zhengwen) # 剔除了非中文字符
    # print('正文: \n', zhengwen)
    return zhengwen

 然后对正文部分有一个去掉非中文字符的处理

# 去掉非中文字符
def clean_str(string):
    string = re.sub(r"[^\u4e00-\u9fff]", " ", string)
    string = re.sub(r"\s{2,}", " ", string)  # 能直接变成一个字符串 可以在txt中写成一行
    return string.strip()

 所以在主函数中调用上面四个函数就可以了

path = 'C:\\Users\\zhang\\Desktop\\trec06c\\data' # trec06c数据集所在路径
    dirs = os.listdir(path)# ['000','001',...]
    for dir in dirs: # 文件夹
        dir_path = path + '\\' + dir
        files = os.listdir(dir_path) # ['000','001',...]
        for file in files: # 数据文件
            file_path = dir_path + '\\' + file
            f = codecs.open(file_path, 'r', 'gbk', errors='ignore')
            email = '' # 存储一封邮件的所有内容
            for line in f: # 每一行
                email += line
            print(index)
            # 提取特征
            # 发件人
            From = From_email(email)
            # 收件人
            To = To_email(email)
            # 主题
            Subject = Subject_email(email)
            # 正文
            zhengwen = zhengwen_email(email)

获取 标签--路径 对照表

存成dataframe类型,另外把标签从字符串弄成了0,1数值  (1是垃圾邮件  0是正常邮件)

def Index_File():
    """index文件 路径--标签 对照表"""
    index_file = 'C:\\Users\\zhang\\Desktop\\trec06c\\full\\index'
    f = codecs.open(index_file, 'r', 'gbk', errors='ignore')
    table = defaultdict(list)
    for line in f:
        label, path = line.strip().split()
        if label == 'spam': # 是垃圾邮件
            label = 1
        else:
            label = 0
        table['label'].append(label)
        table['path'].append(path)
    table = pd.DataFrame(data=table)
    return table

 接下来就将提取到的四个特征存成文件,对照着 标签--路径 对照表,也就是table,判断是哪类,然后将垃圾邮件存入spam.txt中,将正常邮件存入ham.txt中

一封邮件四个特征存成一行,用 ‘<<<<<’ 串进行分隔

if __name__ == '__main__':
    """主函数"""
    # 获取 路径--标签 对照表
    table = Index_File()
    i = 0
    j = 0
    path = 'C:\\Users\\zhang\\Desktop\\trec06c\\data'
    dirs = os.listdir(path)# ['000','001',...]
    for dir in dirs: # 文件夹
        dir_path = path + '\\' + dir
        files = os.listdir(dir_path) # ['000','001',...]
        for file in files: # 数据文件
            file_path = dir_path + '\\' + file
            f = codecs.open(file_path, 'r', 'gbk', errors='ignore')
            email = '' # 存储一封邮件的所有内容
            for line in f: # 每一行
                email += line
            # 打印文件路径
            index = '../data/' + dir + '/' + file
            print(index)
            # 提取特征
            # 发件人
            From = From_email(email)
            # 收件人
            To = To_email(email)
            # 主题
            Subject = Subject_email(email)
            # 正文
            zhengwen = zhengwen_email(email)

            print('*'*100)
            f.close()

            flag = table[table['path'] == index]['label'].values[0]
            if flag == 1:
                f = open('.\\trec06c\\data\\spam.txt', 'a', encoding='utf8')
                i += 1
            elif flag == 0:
                f = open('.\\trec06c\\data\\ham.txt', 'a', encoding='utf8')
                j += 1
            f.write(From + '<<<<<' + To + '<<<<<' + Subject + '<<<<<' + zhengwen + '\n') # 保存成一行用<<<<<分隔
            f.close()

 处理完成后,我手动将spam.txt 和 ham.txt 合并成了 mailcorous.txt 文件,正常邮件在前,垃圾邮件在后。稍微的看一下这个文件哈(见下图)

mailcorous.txt

 因为From、To、Subject里面的内容是中英文混杂的状态,正文全是中文,这个时候如果将中文和英文分开来进行分词很麻烦,我就试了试能不能偷个懒儿,哈哈~

我们都知道jieba可以处理纯中文文本,我就想看看jieba能不能同时对中英文进行分词。然后,随便取了mailcorous.txt中的两行,也就是两封邮件的内容进行测试。

测试一下 四个特征在一行当中,且中英文混杂,且不去掉分隔符  进行分词

import jieba
from sklearn.feature_extraction.text import CountVectorizer
text = """
"pan" <pan@jdl.ac.cn><<<<<shi@ccert.edu.cn<<<<<● 问一部魏宗万的电影名称<<<<<讲的是孔子后人的故事 一个老领导回到家乡 跟儿子感情不和 跟贪财的孙子孔为本和睦 老领导的弟弟魏宗万是赶马车的 有个洋妞大概是考察民俗的 在他们家过年 孔为本总想出国 被爷爷教育了 最后 一家人基本和解 顺便问另一类电影 北京青年电影制片厂的 中越战背景 一军人被介绍了一个对象 去相亲 女方是军队医院的护士 犹豫不决 总是在回忆战场上负伤的男友 好像还没死 最后 男方表示理解 归队了
"xin" <xin@jdl.ac.cn><<<<<zhong@ccert.edu.cn<<<<<Re: 我家的烦心事<<<<<我很理解的 但是不知道你说的这个挑是什么意思 如果是挑一些带框框的死条件 或者说传统的社会性条件 会随着自身的条件不利而改变的 但如果是一种比较虚的原则性的 被迫放弃了会很悲剧的 但其实为难的往往就是这样的意识形态领域的条件 其实北京也好不到那儿去 否则就不会有几十万北大荒了 你也不必激她 都到这个份上了 更不能凑合了 其实我也这么想过 让她来北京 可是她在那边工作非常好 换地方成本抬高
"""
split_corpus = []
split_corpus.append(" ".join(jieba.lcut(text)))  # jieba.lcut(text) 列表类型 每个元素是字符串  # " ".join(jieba.lcut(text)) 字符串类型
cv = CountVectorizer(token_pattern=r'(?u)\b\w\w+\b') # 保留两个字及以上的特征词  # 去掉特殊字符 乱七八糟的字符
X = cv.fit_transform(split_corpus)
print(cv.get_feature_names()) # 特征词列表
print(X.toarray()) # 特征向量

结果发现,我敲~!!可以哎~!! 哈哈~

 

把这一部分的全部的代码放这儿:

process.py

# coding=gbk
import os
import codecs
import re
import base64

import pandas as pd
from collections import defaultdict

# 去掉非中文字符
def clean_str(string):
    string = re.sub(r"[^\u4e00-\u9fff]", " ", string)
    string = re.sub(r"\s{2,}", " ", string)  # 能直接变成一个字符串 可以在txt中写成一行
    return string.strip()

def Index_File():
    """index文件 路径--标签 对照表"""
    index_file = 'C:\\Users\\zhang\\Desktop\\trec06c\\full\\index'
    f = codecs.open(index_file, 'r', 'gbk', errors='ignore')
    table = defaultdict(list)
    for line in f:
        label, path = line.strip().split()
        if label == 'spam': # 是垃圾邮件
            label = 1
        else:
            label = 0
        table['label'].append(label)
        table['path'].append(path)
    table = pd.DataFrame(data=table)
    return table



#提取四个特征

def From_email(email):
    # 发件人
    # 先提取From后的所有内容
    try:
        From_raw = re.search(r'From: (.*)', email).group(1)
    except:
        From_raw = ''
    From = ''
    # 先看看有没有加密部分 有加密部分就给他解密
    name = re.search(r'=\?GB2312\?B\?(.*)\?=', From_raw, re.I)  # name保存加密部分
    if name is None:  # 没有加密部分
        name = ''
        # 没有加密部分 就保留串的所有内容
        From = From_raw
    else:  # 有加密部分
        name = name.group(1)
        try:
            name = base64.b64decode(name).decode('gb2312')
        except:
            try:
                name = base64.b64decode(name).decode('gbk')
            except:
                name = ''
        From = name + re.search(r'\?=(.*)', From_raw).group(1)
    # print('From: ', From)
    return From

def To_email(email):
    # 收件人
    To = re.search(r'^To: (.*)', email, re.M | re.I).group(1)  # re.M 从每行文本开头的位置开始匹配
    # print('To: ', To)
    return To

def Subject_email(email):
    # 主题
    Subject = re.search(r'=\?gb2312\?B\?(.*)\?=', email)
    if Subject is None:
        Subject = ''
    else:  # subject 有内容
        Subject = Subject.group(1)
        Subject = base64.b64decode(Subject)  # 解密
        try:
            Subject = Subject.decode('gb2312')  # 解码
        except:
            try:
                Subject = Subject.decode('gbk')  # 解码
            except:
                Subject = ''
    # print('Subject: ', Subject)
    return Subject

def zhengwen_email(email):
    # 正文
    zhengwen = re.search(r'\n\n(.*)', email, re.S).group(1)
    zhengwen = clean_str(zhengwen) # 剔除了非中文字符
    # print('正文: \n', zhengwen)
    return zhengwen



if __name__ == '__main__':
    """主函数"""
    # 获取 路径--标签 对照表
    table = Index_File()
    i = 0
    j = 0
    path = 'C:\\Users\\zhang\\Desktop\\trec06c\\data'
    dirs = os.listdir(path)# ['000','001',...]
    for dir in dirs: # 文件夹
        dir_path = path + '\\' + dir
        files = os.listdir(dir_path) # ['000','001',...]
        for file in files: # 数据文件
            file_path = dir_path + '\\' + file
            f = codecs.open(file_path, 'r', 'gbk', errors='ignore')
            email = '' # 存储一封邮件的所有内容
            for line in f: # 每一行
                email += line
            # 打印文件路径
            index = '../data/' + dir + '/' + file
            print(index)
            # 提取特征
            # 发件人
            From = From_email(email)
            # 收件人
            To = To_email(email)
            # 主题
            Subject = Subject_email(email)
            # 正文
            zhengwen = zhengwen_email(email)

            print('*'*100)
            f.close()

            flag = table[table['path'] == index]['label'].values[0]
            if flag == 1:
                f = open('.\\trec06c\\data\\spam.txt', 'a', encoding='utf8')
                i += 1
            elif flag == 0:
                f = open('.\\trec06c\\data\\ham.txt', 'a', encoding='utf8')
                j += 1
            f.write(From + '<<<<<' + To + '<<<<<' + Subject + '<<<<<' + zhengwen + '\n') # 保存成一行用<<<<<分割
            f.close()



接下来就是分词转化为词向量然后输入到线性模型里面训练的步骤啦~

哎呀到饭点儿了,去吃饭了喽~,回来接着写~

欢迎转发~ 评论讨论~ 点赞~

转载请注明出处~

谢谢大家的支持!~ O(∩_∩)O~

~~~~~~~~~~~待更新~~~~~~~~~~~~~~~~~~~~~~~~~~~

后续来了:

垃圾邮件分类(trec06c数据集)特征分词、特征向量化、模型训练https://blog.csdn.net/qq_39321513/article/details/112021355

 

 

  • 38
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: 为了下载TREC06C数据集,您可以按照以下步骤进行操作: 1. 首先,您需要打开网页浏览器并访问TREC官方网站。您可以在搜索引擎中输入"TREC官方网站"来找到该网站。 2. 在TREC官方网站上,您可以找到与TREC06C数据集相关的信息和资源。您可以使用网站上的搜索功能,搜索TREC06C数据集。 3. 在搜索结果中,您可能会看到有关TREC06C数据集的页面或链接。请点击相关链接以获取进一步的信息。 4. 在相关页面上,您可能会找到关于TREC06C数据集的描述、下载链接或访问权限的说明。请根据页面上的引导,选择适合您的下载选项。 5. 请注意,有些数据集可能需要您注册或登录才能进行下载。如果需要注册,请按照页面上的要求进行注册。 6. 一旦您找到适合的下载选项并完成相关步骤,您可以点击下载链接或按照页面上的说明进行下载。 7. 下载时间可能会根据您的网络连接速度和数据集的大小而有所不同。请耐心等待下载完成。 8. 下载完成后,您可以查看下载的文件,并根据需要进行相应的数据分析或研究。 希望以上信息对您有所帮助,祝您成功下载TREC06C数据集! ### 回答2: TREC06C是一个公开的数据集,用于信息检索和文本分类的研究和评估。它是2006年美国国家标准技术研究所(NIST)举办的TREC竞赛中使用的数据集。 要下载TREC06C数据集,首先需要在NIST的TREC网站上注册一个账号。注册完成后,根据网站上的指引,选择TREC06C数据集并查找下载链接。 在下载链接中,可能会有不同格式的数据集可供选择,如原始文本、索引文件或预处理的数据等。根据自己的需要选择合适的数据格式并下载。 一旦下载完成,就可以开始使用TREC06C数据集进行研究和评估了。可以根据数据集的文档来了解数据的结构和标记方式,这有助于更好地理解和处理数据集。 在进行研究和评估过程中,可以使用TREC06C数据集来构建文本分类模型、评估信息检索算法的性能,或者进行其他相关的任务。可以根据自己的具体需求和研究目标来利用数据集,并按照科研的规范进行实验和分析。 总之,下载TREC06C数据集需要在NIST的TREC网站上注册账号,找到对应的下载链接,并选择合适的数据格式进行下载。通过合理利用数据集进行研究和评估,可以提高信息检索和文本分类等领域的研究成果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值