当前位置:   article > 正文

基于文本内容的垃圾短信识别实战

垃圾短信识别

1、实战的背景与目标

背景:

垃圾短信形式日益多变,相关报告可以在下面网站查看

360互联网安全中心(http://zt.360.cn/report/)

目标:

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

2、总体流程

 3、代码实现

1、数据探索

导入数据

  1. #数据导入,设置第一行不为头标签并设置第一列数据为索引
  2. message = pd.read_csv("./data/message80W1.csv",encoding="UTF-8",header=None,index_col=0)

更换列名

  1. message.columns =["label","message"]

查看数据形状

  1. message.shape
  2. # (800000, 2)

整体查看数据

  1. message.info()
  2. """
  3. <class 'pandas.core.frame.DataFrame'>
  4. Int64Index: 800000 entries, 1 to 800000
  5. Data columns (total 2 columns):
  6. # Column Non-Null Count Dtype
  7. --- ------ -------------- -----
  8. 0 label 800000 non-null int64
  9. 1 message 800000 non-null object
  10. dtypes: int64(1), object(1)
  11. memory usage: 18.3+ MB
  12. """

查看数据是否有重复值(若有目前不清除,等抽样后,再处理样本数据)

  1. message.duplicated().sum()
  2. #13424

查看垃圾短信与非垃圾短信的占比

  1. data_group = message.groupby("label").count().reset_index()
  2. import matplotlib.pyplot as plt
  3. fig = plt.figure(figsize=(8,8))
  4. plt.rcParams["font.sans-serif"] = ["SimHei"] # 设置中文字体为黑体
  5. plt.rcParams["axes.unicode_minus"] = False # 设置显示负号
  6. plt.title("垃圾短信与非垃圾短信的占比饼图",fontsize=12)
  7. plt.pie(data_group["message"],labels=["非垃圾短信","垃圾短信"],autopct="%0.2f%%",startangle=90,explode=[0,0.04])
  8. plt.savefig("垃圾短信与非垃圾短信的占比饼图.jpg")
  9. plt.show()

 2、进行数据抽样

先抽取抽样操作 ,垃圾短信,非垃圾短信  各1000, 占比为   1:1

  1. n = 1000
  2. a = message[message["label"] == 0].sample(n) #随机抽样
  3. b = message[message["label"] == 1].sample(n)
  4. data_new = pd.concat([a,b],axis=0) #数据按行合并
3、进行数据预处理

数据清洗 去重  去除x序列 (这里的 x序列指  数据中已经用 XXX 隐藏的内容,例如手机号、名字,薪资等敏感数据)

  1. #去重
  2. data_dup = data_new["message"].drop_duplicates()
  3. #去除x序列
  4. import re
  5. data_qumin = data_dup.apply(lambda x:re.sub("x","",x))

进行 jieba分词操作

  1. import jieba
  2. jieba.load_userdict("./data/newdic1.txt") #向 jieba 模块中添加自定义词语
  3. data_cut = data_qumin.apply(lambda x:jieba.lcut(x)) #进行分词操作
  4. #设置停用词
  5. stopWords = pd.read_csv('./data/stopword.txt', encoding='GB18030', sep='hahaha', header=None) #设置分隔符为 不存在的内容,实现分割
  6. stopWords = ['≮', '≯', '≠', '≮', ' ', '会', '月', '日', '–'] + list(stopWords.iloc[:, 0])
  7. #去除停用词
  8. data_after_stop = data_cut.apply(lambda x:[i for i in x if i not in stopWords])
  9. #提取标签
  10. labels = data_new.loc[data_after_stop.index,"label"]
  11. #使用空格分割词语
  12. adata = data_after_stop.apply(lambda x:" ".join(x))

将上述操作封装成函数

  1. def data_process(file='./data/message80W1.csv'):
  2. data = pd.read_csv(file, header=None, index_col=0)
  3. data.columns = ['label', 'message']
  4. n = 10000
  5. a = data[data['label'] == 0].sample(n)
  6. b = data[data['label'] == 1].sample(n)
  7. data_new = pd.concat([a, b], axis=0)
  8. data_dup = data_new['message'].drop_duplicates()
  9. data_qumin = data_dup.apply(lambda x: re.sub('x', '', x))
  10. jieba.load_userdict('./data/newdic1.txt')
  11. data_cut = data_qumin.apply(lambda x: jieba.lcut(x))
  12. stopWords = pd.read_csv('./data/stopword.txt', encoding='GB18030', sep='hahaha', header=None)
  13. stopWords = ['≮', '≯', '≠', '≮', ' ', '会', '月', '日', '–'] + list(stopWords.iloc[:, 0])
  14. data_after_stop = data_cut.apply(lambda x: [i for i in x if i not in stopWords])
  15. labels = data_new.loc[data_after_stop.index, 'label']
  16. adata = data_after_stop.apply(lambda x: ' '.join(x))
  17. return adata, data_after_stop, labels
4、进行词云图绘制

调用函数,设置数据

  1. adata,data_after_stop,labels = data_process()

非垃圾短信的词频统计

  1. word_fre = {}
  2. for i in data_after_stop[labels == 0]:
  3. for j in i:
  4. if j not in word_fre.keys():
  5. word_fre[j] = 1
  6. else:
  7. word_fre[j] += 1

绘图

  1. from wordcloud import WordCloud
  2. import matplotlib.pyplot as plt
  3. fig = plt.figure(figsize=(12,8))
  4. plt.title("非垃圾短息词云图",fontsize=20)
  5. mask = plt.imread('./data/duihuakuan.jpg')
  6. wc = WordCloud(mask=mask, background_color='white', font_path=r'D:\2023暑假\基于文本内容的垃圾短信分类\基于文本内容的垃圾短信识别-数据&代码\data\simhei.ttf')
  7. wc.fit_words(word_fre)
  8. plt.imshow(wc)

 垃圾短信词云图绘制(方法类似)

  1. word_fre = {}
  2. for i in data_after_stop[labels == 1]:
  3. for j in i:
  4. if j not in word_fre.keys():
  5. word_fre[j] = 1
  6. else:
  7. word_fre[j] += 1
  8. from wordcloud import WordCloud
  9. import matplotlib.pyplot as plt
  10. fig = plt.figure(figsize=(12,8))
  11. plt.title("垃圾短息词云图",fontsize=20)
  12. mask = plt.imread('./data/duihuakuan.jpg')
  13. wc = WordCloud(mask=mask, background_color='white', font_path=r'D:\2023暑假\基于文本内容的垃圾短信分类\基于文本内容的垃圾短信识别-数据&代码\data\simhei.ttf')
  14. wc.fit_words(word_fre)
  15. plt.imshow(wc)

 

 5、模型的构建

采用   TF-IDF权重策略

权重策略文档中的高频词应具有表征此文档较高的权重,除非该词也是高文档频率词

TF:Term frequency即关键词词频,是指一篇文档中关键词出现的频率

TF = N / M                   N:单词在某文档中的频次 ,     M:该文档的单词数

IDF:Inverse document frequency指逆向文本频率,是用于衡量关键词权重的指数

IDF = \log (D/DW)       D:总文档数 ,     Dw:出现了该单词的文档数

调用 Sklearn库中相关模块解释

  1. sklearn.feature_extraction.text #文本特征提取模块
  2. CosuntVectorizer #转化词频向量函数
  3. fit_transform() #转化词频向量方法
  4. get_feature_names() #获取单词集合方法
  5. toarray() #获取数值矩阵方法
  6. TfidfTransformer #转化tf-idf权重向量函数
  7. fit_transform(counts) #转成tf-idf权重向量方法
  8. transformer = TfidfTransformer() #转化tf-idf权重向量函数
  9. vectorizer = CountVectorizer() #转化词频向量函数
  10. word_vec = vectorizer.fit_transform(corpus) #转成词向量
  11. words = vectorizer.get_feature_names() #单词集合
  12. word_cout = word_vec.toarray() #转成ndarray
  13. tfidf = transformer.fit_transform(word_cout) #转成tf-idf权重向量
  14. tfidf_ma= tfidf.toarray() #转成ndarray

采用朴素贝叶斯算法

 多项式朴素贝叶斯——用于文本分类 构造方法:

  1. sklearn.naive_bayes.MultinomialNB(alpha=1.0 #平滑参数,
  2. fit_prior=True #学习类的先验概率  ,
  3. class_prior=None) #类的先验概率

模型代码实现

  1. from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
  2. from sklearn.model_selection import train_test_split
  3. from sklearn.naive_bayes import GaussianNB
  4. data_train,data_test,labels_train,labels_test = train_test_split(adata,labels,test_size=0.2)
  5. countVectorizer = CountVectorizer()
  6. data_train = countVectorizer.fit_transform(data_train)
  7. X_train = TfidfTransformer().fit_transform(data_train.toarray()).toarray()
  8. data_test = CountVectorizer(vocabulary=countVectorizer.vocabulary_).fit_transform(data_test)
  9. X_test = TfidfTransformer().fit_transform(data_test.toarray()).toarray()
  10. model = GaussianNB()
  11. model.fit(X_train, labels_train) #训练
  12. model.score(X_test,labels_test) #测试
  13. # 0.9055374592833876
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/377480
推荐阅读
相关标签
  

闽ICP备14008679号