自然语言处理小案例:基于文本内容的垃圾短信分类

案例目标:识别垃圾短信

基于短信文本内容,建立识别模型,准确识别出垃圾短信,以及垃圾短信过滤的问题

一、数据获取

1、数据读取

data = pd.read_csv('fileName', header=None, index_col=0)  #读取数据
data.columns = ['label', 'message']

2、数据抽取

n = 5000            # 设置抽取5000条测试数据
a = data[data['label'] == 0].sample(n)   # 正常短信0,取出5000条
b = data[data['label'] == 1].sample(n)   # 垃圾短信1,取出5000条
data_new = pd.concat([a, b], axis=0)     # 将垃圾短信和正常短信拼接起来,共10000条,10000行2列

二、数据预处理

大概流程:数据清洗——>分词——>添加词典、去除停用词——>词云绘制

1、数据清洗:去除重复短信文本

data_dup = data_new['message'].drop_duplicates()   #去除重复文本

2、数据清洗:去除文本中的x序列
(对短信中的具体时间、地点、人名等隐私信息进行脱敏处理后变成的X序列)

data_qumin = data_dup.apply(lambda x: re.sub('x', '', x))  #去除文本中的x序列

3、添加新词

jieba.load_userdict('newdic1.txt') #将一部分新词添加到“newdic1.txt”中
#jieba.lcut('女人节是一个新兴词汇')

4、结巴分词

data_cut = data_qumin.apply(lambda x: jieba.lcut(x))   # 分词

5、去除停用词

stopWords = pd.read_csv('stopword.txt', encoding='GB18030', sep='hahaha', header=None)    # 读入停用词典 
stopWords = ['≮', '≯', '≠', '≮', ' ', '会', '月', '日', '–'] + list(stopWords.iloc[:, 0])    # 将这些特殊字符添加到停用词表中
data_after_stop = data_cut.apply(lambda x: [i for i in x if i not in stopWords])       # 去除停用词
labels = data_new.loc[data_after_stop.index, 'label']   # 取出data_after_stop中的标签(标签为0和1),用loc来索引
adata = data_after_stop.apply(lambda x: ' '.join(x))    # 将列表中的元素用空格拼接,为“文本转化为向量”做准备

6、数据预处理的函数封装

将上面的所有操作封装在一个方法中:

def data_process(file='message80W1.csv'):

数据预处理部分的完整代码展示(data_process.py):

import pandas as pd
import re
import jieba
 
def data_process(file='message80W1.csv'):
    data = pd.read_csv(file, header=None, index_col=0)     # 读取数据
    data.columns = ['label', 'message']
    n = 5000            # 设置抽取5000条测试数据
    # 构建语料库
    a = data[data['label'] == 0].sample(n)      # 正常短信0,取出5000条
    b = data[data['label'] == 1].sample(n)      # 垃圾短信1,取出5000条
    data_new = pd.concat([a, b], axis=0)         # 将垃圾短信和正常短信拼接起来,共10000条,10000行2列
 
    data_dup = data_new['message'].drop_duplicates()             # 去除重复文本
    data_qumin = data_dup.apply(lambda x: re.sub('x', '', x))    # 去除文本中的x序列
 
    jieba.load_userdict('newdic1.txt')       # 添加新词
     # jieba.lcut('女人节是一个新兴词汇')
    data_cut = data_qumin.apply(lambda x: jieba.lcut(x))   # 分词
 
     # data['label'].value_counts()
 
    stopWords = pd.read_csv('stopword.txt', encoding='GB18030', sep='hahaha', header=None)
    stopWords = ['≮', '≯', '≠', '≮', ' ', '会', '月', '日', '–'] + list(stopWords.iloc[:, 0])   # 将这些特殊字符添加到停用词表中
    data_after_stop = data_cut.apply(lambda x: [i for i in x if i not in stopWords])       # 去除停用词
    labels = data_new.loc[data_after_stop.index, 'label']   # 取出data_after_stop中的标签(标签为0和1),用loc来索引
    adata = data_after_stop.apply(lambda x: ' '.join(x))    # 将列表中的元素/词语用空格拼接,为“文本转化为向量”做准备
 
    return adata, data_after_stop, labels
 
 
data_process()
 
#def~~return部分一起执行后,再执行调用语句data_process()查看结果

7、词云图绘制脚本(word_cloud.py)

from data_process import data_process
from wordcloud import WordCloud
import matplotlib.pyplot as plt
 
word_fre = {}  #创建一个空字典
adata, data_after_stop, labels = data_process() #调用数据预处理模块的函数
 
# 统计标签为1的垃圾短信中的词频,统计标签为0的正常短信同理
for i in data_after_stop[labels == 1]:
    for j in i:
        if j not in word_fre.keys():
            word_fre[j] = 1
        else:
            word_fre[j] += 1
 
mask = plt.imread('ciyuntupian.jpg')  # 导入自己找的词云轮廓
wc = WordCloud(mask=mask, background_color='white', font_path=r'C:\Windows\Fonts\msyh.ttc')  #词云的绘制
wc.fit_words(word_fre)   # 统计词频
plt.imshow(wc)           # 词云展示

三、文本的向量表示

Q:如何将文本数据放入模型,从而识别这个文本数据
A:

  • One-Hot表达;缺陷:忽略了句子的词频信息 TF-IDF权重策略;
  • 增加了词频信息、归一化(避免了句子长度不一致的问题)

将处理好的数据转换成TF-IDF权值向量,然后进行模型的构建,使用朴素贝叶斯模型做训练

1、文本数据的向量化表达

2、获取训练样本的TF-IDF权值向量

3、获取测试样本的TF-IDF权值向量

model.py脚本的完整代码展示:

from data_process import data_process
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer

adata, data_after_stop, lables = data_process()  #调用data_process()
data_tr, data_te, labels_tr, labels_te = train_test_split(adata, lables, test_size=0.2)  #分割训练样本和测试样本,训练样本占80%,测试样本占20%

countVectorizer = CountVectorizer()
data_tr = countVectorizer.fit_transform(data_tr)  #将训练集样本转换成TF-IDF权值向量,矩阵维度:1599*8302
X_tr = TfidfTransformer().fit_transform(data_tr.toarray()).toarray()    #获得IF-IDF的向量权值

#将测试样本的列数转成和训练样本的列数一样的,维度:400*8302
data_te = CountVectorizer(vocabulary=countVectorizer.vocabulary_).fit_transform(data_te)
X_te = TfidfTransformer().fit_transform(data_te.toarray()).toarray()

model = GaussianNB()
model.fit(X_tr, labels_tr)      # 模型训练
model.score(X_te, labels_te)    # 模型预测

模型训练结果在0.86左右,自行尝试用不同的模型做训练

写原创博客,记录学习情况,温习项目过程。

做个有情的搬运工点个赞再走吧~

你可能感兴趣的:(自然语言处理,python,机器学习)