Press "Enter" to skip to content

基于TF-IDF的文本分析–短信识别分类

垃圾短信的识别分类

 

背景介绍

 

垃圾短信利用基站或者程序进行发送,每每想要收到正常且需要的短信(醒醒没有女生向你表白(bushi))。当手机发生震动,迫不及待点开的时候映入眼帘的就是买彩票吗,买六合彩吗这种短信。让人烦不胜烦

 

因此,经过一顿分析:肯定是因为遭受大量垃圾短信后,害我的女神无法为我发送短信,害我单身至今。让人深恶痛绝的垃圾短信,今天我就要写代码制裁你。

 

数据来源:泰迪杯 edu.tipdm.org/course/4255…

 

大体的思路如下:

 

1、文本进行去除x

 

2、jieba进行中文分词

 

3、文本进行stop词的去除

 

4、去除后将列表转化为字符串(用于后面的数据分析)

 

5、文本数据和标签分开

 

(可以选择词云的绘制 使得文字的分析更加清晰) 6、字符串通过TF-IDF进行向量化 获得每个词以及每个词出现的频率 (one-hot只能知道是否有,coutVectorizer知道每个词的频率,TF-IDF是利用算法进行词语的计算) TF:词的数量/词的总数 IDF:log((N+1)/(N(x)+1))+1 N=训练集文本总数(行数), N(x)=包含词x的文本数(包含x的行数) TF-IDF算法就是 TF*IDF

 

7、数据结构化之后 进行机器学习的预测

 

基本数据处理

 

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
    a = data[data['label'] == 0].sample(n) #获取5000个非垃圾短信样本
    b = data[data['label'] == 1].sample(n) #获取5000个垃圾短信样本
    data_new = pd.concat([a, b], axis=0)  #合并行合并 一个在上一个在下
    data_dup = data_new['message'].drop_duplicates()#去除重复列
    data_qumin = data_dup.apply(lambda x: re.sub('x', '', x))#去除data_dup中每一个样本的的x字符 换成' '
    jieba.load_userdict('newdic1.txt')#加载自定义文库 给结巴添加特有词语
    data_cut = data_qumin.apply(lambda x: jieba.lcut(x))#切分中文词语 lcut参数cut_all默认为False 如果写为True那幺就变为全模式 会有重复的词
    stopWords = pd.read_csv('stopword.txt', encoding='GB18030', sep='hahaha', header=None) #读取文本  sep指定分隔符为'hahaha' 默认为,
    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']#index是行名 形成一个只有标签的dataframe
    adata = data_after_stop.apply(lambda x: ' '.join(x))#将列表转化为字符串 分隔为' '
    return adata, data_after_stop, labels #data_after_stop是列表 adata是字符串 labels是标签

 

结果的预测

 

from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
adata, data_after_stop, lables = data_process()#获得结构化之后的数据
data_tr, data_te, labels_tr, labels_te = train_test_split(adata, lables, test_size=0.2)#进行测试集和训练集的划分
countVectorizer = CountVectorizer()
data_tr = countVectorizer.fit_transform(data_tr)#仅仅考虑词频 每个词出现一次 数值加一
X_tr = TfidfTransformer().fit_transform(data_tr.toarray()).toarray()#使用TF-IDF进行计算
data_te = CountVectorizer(vocabulary=countVectorizer.vocabulary_).fit_transform(data_te)#vocabulary=countVectorizer.vocabulary_为了保持上面相同的向量列数
X_te = TfidfTransformer().fit_transform(data_te.toarray()).toarray()#不toarray()的话 出现的是告诉你哪个位置是什幺数值
model = MLPClassifier()#神经网络模型的构建 
model.fit(X_tr, labels_tr)#放入训练集数据
model.score(X_te, labels_te)#测试集数据进行跑分

 

这里的神经网络是调用默认参数,如果需要更好的效果可以调参或者使用其他的模型

 

跑分结果

 

 

词云的绘制

 

#绘制词云
from data_process import data_process
from wordcloud import WordCloud
import matplotlib.pyplot as plt
adata, data_after_stop, labels = data_process()
word_fre = {}
for i in data_after_stop[labels == 1]:#遍历data标签为1的(列表)
    for j in i:
        if j not in word_fre.keys():#keys为键名 不含这个键名就建立一个
            word_fre[j] = 1
        else:
            word_fre[j] += 1
mask = plt.imread('duihuakuan.jpg')#添加图标
wc = WordCloud(mask=mask, background_color='white', font_path=r'C:\Windows\Fonts\simhei.ttf')#绘制词云 图片和背景颜色以及文字的格式设置
wc.fit_words(word_fre)#添加字典
plt.imshow(wc)#画图

 

 

for循环为1的话 就表示垃圾短信的词云,为0的话就是普通短信的词云 这里的难点是font_path的参数调整 需要使用可以显示的字体

 

总结

 

使用了垃圾短信的识别,马上有女神找我聊天~~

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注