美文网首页
第十二天 贝叶斯垃圾邮件分类

第十二天 贝叶斯垃圾邮件分类

作者: 未不明不知不觉 | 来源:发表于2018-12-12 20:13 被阅读19次

    这节的目标是实现垃圾邮件分类,俗话说巧妇难为无米之炊,要实现垃圾邮件分类,首先要有数据,这里我使用kaggle提供的spam.csv

    加载数据集

    这里我把数据集放在dataset文件夹下,使用pandas加载数据集

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.read_csv("dataset/spam.csv", encoding="latin-1")
    df.head()
    

    得到的输出

    v1 v2 Unnamed:2 Unnamed:3 Unnamed:4
    0 ham Go until jurong point, crazy.. Available only ... NaN NaN NaN
    1 ham Ok lar... Joking wif u oni... NaN NaN NaN
    2 spam Free entry in 2 a wkly comp to win FA Cup fina.. NaN NaN NaN
    3 ham U dun say so early hor... U c already then say. NaN NaN NaN
    4 ham Nah I don't think he goes to usf, he lives aro... NaN NaN NaN

    其中我们只需要第一列(类别)和第二列(邮件内容),然后我们使用describe函数来查看数据集的大致描述

    df = df.drop(["Unnamed: 2", "Unnamed: 3", "Unnamed: 4"], axis=1)
    df.describe()
    

    输出为

    -- label sms
    count 5572 5572
    unique 2 5169
    top ham Sorry, I'll call later
    freq 4825 30

    通过上面的描述我们得知,该数据集有5572条数据,其中label代表该数据集的类别,总共有两类(ham|spam),在这5572条数据在有4825条为正常邮件,有5169条内容唯一的邮件,其中内容为Sorry, I'll call later的邮件出现了30次

    数据预处理

    我们的数据中含有大量的文本数据,但是一般原始数据无法直接丢给算法,这些原始数据是一组符号,因为大多数算法期望的输入是固定长度的数值特征向量而不是不同长度的文本文件。为了解决这个问题,scikit-learn提供了一些实用工具可以用最常见的方式从文本内容中抽取数值特征,比如说:

    • 标记(tokenizing)文本以及为每一个可能的标记(token)分配的一个整型ID ,例如用白空格和标点符号作为标记的分割符(中文的话涉及到分词的问题)
    • 计数(counting)标记在每个文本中的出现频率
    • 正态化(nomalizating) 降低在大多数样本/文档中都出现的标记的权重

    在这个方案中,特征和样本的定义如下:

    • 每个标记出现的频率(无论是否正态化)作为特征

    • 给定文件中所有标记的出现频率所构成的向量作为多元样本

    因此,语料文件可以用一个词文档矩阵代表,每行是一个文档,每列是一个标记(即词)。

    将文档文件转化为数值特征的一般过程被称为向量化。这个特殊的策略(标记,计数和正态化)被称为词袋或者Bag of n-grams表征。用词频描述文档,但是完全忽略词在文档中出现的相对位置信息。

    假设我们有4个样本如下:

    [
    'Hello, how are you!',
    'Win money, win from home.',
    'Call me now',
    'Hello, Call you tomorrow?'
    ]
    

    我们的目标是将这组文本转换为频率分布矩阵,如下所示

    词袋

    词袋的sklearn实现

    词频统计可以用scikit-learn的CountVectorizer实现:

    from sklearn.feature_extraction.text import CountVectorizer
    vectorizer = CountVectorizer()
    data_train_cnt = vectorizer.fit_transform(data_train)
    data_test_cnt = vectorizer.transform(data_test)
    

    CountVectorizer类会把文本全部转换成小写,然后将文本词块化(tokenize)。文本词块化是把句子分割成词块(token)或有意义的字母序列的过程。词块大多是单词,但它们也可能是一些短语,如标点符号和词缀。CountVectorizer类通过正则表达式用空格分割句子,然后抽取长度大于等于2的字母序列

    贝叶斯分类

    这里我们使用sklearn中的MultinomialNB对数据集进行分类,分类代码如下

    from sklearn.naive_bayes import MultinomialNB
    clf = MultinomialNB()
    clf.fit(data_train_cnt, label_train)
    score = clf.score(data_test_cnt,label_test)
    print(score)
    

    得到的评分为:

    0.987443946
    

    接下来我们使用交叉验证来测试模型的性能

    from sklearn.model_selection import cross_val_score
    accuracy = cross_val_score(clf, data_train_cnt, label_train, cv=20, scoring='accuracy')
    print(accuracy.mean())
    

    打印出来的平均得分为:

    0.982495042
    

    相关文章

      网友评论

          本文标题:第十二天 贝叶斯垃圾邮件分类

          本文链接:https://www.haomeiwen.com/subject/bdophqtx.html