垃圾短信分类

垃圾短信分类

使用说明:

  1. 需要准备 stopwords.txt 停用词表和 sms_dict.txt 自定义词表

  2. 原始数据文件需为竖线分隔的文本格式

  3. 首次运行可能需要安装依赖库:

    pip install pandas jieba scikit-learn matplotlib seaborn wordcloud

    或者

    python -m pip install --upgrade pandas jieba scikit-learn matplotlib seaborn wordcloud

  4. 输出包含模型准确率、分类报告、混淆矩阵以及可视化图表

关键注释说明

  1. 数据加载阶段特别指定手机号为字符串类型,避免解析错误

  2. 清洗过程中通过 lambda 表达式生成垃圾短信标签,规则可根据需要调整

  3. 脱敏处理采用部分隐藏的方式保护隐私,同时处理异常情况

  4. 分词过程包含 URL 替换和停用词过滤,提高文本表示质量

  5. 模型训练使用 TF-IDF + 多项式贝叶斯组合,适合短文本分类

  6. 可视化部分展示了数据分布和关键词云,帮助理解数据特征

引入依赖库

import pandas as pd  # 导入数据处理库
import jieba  # 导入中文分词库
import re  # 导入正则表达式库
from sklearn.feature_extraction.text import TfidfVectorizer  # 导入TF-IDF向量化工具
from sklearn.model_selection import train_test_split  # 导入数据集划分工具
from sklearn.naive_bayes import MultinomialNB  # 导入多项式朴素贝叶斯分类器
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix  # 导入模型评估指标
import matplotlib.pyplot as plt  # 导入基础可视化库
import seaborn as sns  # 导入高级可视化库
from wordcloud import WordCloud  # 导入词云生成库

数据加载

# 1. 数据加载函数
def load_data(file_path):
  # 使用pandas读取文本文件,指定分隔符为竖线,设置列名
  # dtype参数确保手机号保持字符串类型,避免转换为整数
  df = pd.read_csv(file_path, sep='|', header=None, names=['phone_number', 'datetime', 'content'], dtype={'phone_number': str})
  return df  # 返回加载后的数据框

数据清洗

# 2. 数据清洗函数
def clean_data(df):
  # 去除重复行
  df = df.drop_duplicates()

  # 尝试将时间列转换为datetime格式,错误转换的条目设为NaN
  df['datetime'] = pd.to_datetime(df['datetime'], errors='coerce')

  # 删除时间列为空的无效行
  df = df.dropna(subset=['datetime'])

  # 生成垃圾短信标签:内容中同时包含http视为垃圾短信(1表示垃圾短信,0表示正常)
  df['label'] = df['content'].apply(lambda x: 1 if 'http' in str(x) else 0)

  # 过滤掉内容为空或过短的条目(保留至少5个字符的内容)
  df = df[df['content'].apply(lambda x: isinstance(x, str) and len(x)>=5)]

  return df  # 返回清洗后的数据框

数据脱敏函数

# 3. 数据脱敏函数
def desensitize_data(df):
  # 手机号脱敏:保留前3位和后4位,中间用****填充
  # 检查是否为字符串且长度>=11,否则返回默认值
  df['phone_number'] = df['phone_number'].apply(lambda x: x[:3] + '****' + x[7:] if (isinstance(x, str) and len(x)>=11) else '*******')

  # 时间脱敏:仅保留日期部分(去除时间)
  df['datetime'] = df['datetime'].dt.date

  return df  # 返回脱敏后的数据框

文本分词函数

# 4. 文本分词函数
def tokenize_text(text):
  # 替换URL为统一标识
  text = re.sub(r'http\S+', 'URL', text)

  # 去除所有非字母数字字符
  text = re.sub(r'[^\w\s]', '', text)

  # 加载自定义词典
  jieba.load_userdict('./data/sms_dict.txt')

  # 使用jieba进行中文分词
  tokens = jieba.lcut(text)

  # 加载停用词表(需提前准备stopwords.txt文件)
  with open('./data/stopwords.txt', 'r', encoding='utf-8') as f:
    stopwords = set(f.read().splitlines())

  # 过滤停用词并返回空格分隔的字符串
  tokens = [word for word in tokens if word not in stopwords]
  return ' '.join(tokens)

模型训练函数

# 5. 模型训练函数
def train_model(df):
  # 初始化TF-IDF向量化器,保留前5000个最重要的特征
  vectorizer = TfidfVectorizer(max_features=5000)

  # 将文本转换为TF-IDF特征矩阵
  X = vectorizer.fit_transform(df['clean_content'])

  # 提取标签列
  y = df['label']

  # 划分训练集和测试集(80%训练,20%测试)
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

  # 初始化多项式朴素贝叶斯分类器
  model = MultinomialNB()

  # 模型训练
  model.fit(X_train, y_train)

  # 对测试集进行预测
  y_pred = model.predict(X_test)

  # 输出模型评估结果
  print("准确率:", accuracy_score(y_test, y_pred))
  print(classification_report(y_test, y_pred))
  print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))

  return model, vectorizer  # 返回训练好的模型和向量化器

数据可视化函数

# 6. 数据可视化函数
def visualize_data(df):
  plt.rcParams['font.sans-serif'] = ['SimHei']  # 指定字体为 SimHei
  plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

  # 绘制类别分布柱状图
  plt.figure(figsize=(12, 6))  # 设置画布大小
  sns.countplot(x='label', data=df)  # 绘制计数图
  plt.title('垃圾短信类别分布')  # 设置标题
  plt.xlabel('标签(1=垃圾短信)')  # 设置x轴标签
  plt.ylabel('数量')  # 设置y轴标签
  plt.savefig('./img/sms_bar.png', dpi=1080)
  plt.show()  # 显示图表

  # 绘制类别分布饼图显示百分比
  counts = df['label'].value_counts()
  labels = ['正常短信', '垃圾短信']
  colors = ['#4CAF50', '#FF5722']

  plt.figure(figsize=(12, 6))
  plt.pie(counts, labels=labels, colors=colors, autopct='%1.1f%%', pctdistance=0.85, startangle=90)
  plt.title('短信类型百分比分布', fontsize=14)
  plt.axis('equal')

  # 添加数据标签
  plt.text(-1.2, 0.5, f'正常短信\n{counts[0]}条', ha='center', va='center', fontsize=12)
  plt.text(1.2, 0.5, f'垃圾短信\n{counts[1]}条', ha='center', va='center', fontsize=12)

  plt.legend(title='类别', bbox_to_anchor=(1, 1), loc='upper left')
  plt.savefig('./img/sms_pie.png', dpi=1080)
  plt.show()

  # 生成垃圾短信关键词云
  all_text = ' '.join(df[df['label']==1]['clean_content'])  # 提取所有垃圾短信内容
  # 设置字体路径,这里需要根据你系统中字体的实际路径来设置
  font_path = 'C:/Windows/Fonts/simkai.ttf'
  wordcloud = WordCloud(font_path=font_path, width=800, height=400, background_color='white').generate(all_text) # 生成词云

  plt.figure(figsize=(12, 6))  # 设置画布大小
  plt.imshow(wordcloud)  # 显示词云图像
  plt.axis("off")  # 关闭坐标轴
  plt.title('垃圾短信关键词云')  # 设置标题
  plt.savefig('./img/sms_word_could.png', dpi=1080)
  plt.show()  # 显示图表

主程序流程

# 主程序流程
if __name__ == "__main__":
  # 1. 加载原始数据
  df = load_data('./data/sms_data.txt')

  # 2. 数据清洗
  df_clean = clean_data(df)

  # 3. 数据脱敏处理
  df_desensitized = desensitize_data(df_clean)

  # 4. 文本预处理(分词和停用词过滤)3 
  df_desensitized['clean_content'] = df_desensitized['content'].apply(tokenize_text)

  # 5. 模型训练与评估
  model, vectorizer = train_model(df_desensitized)

  # 6. 可视化分析结果
  visualize_data(df_desensitized)
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\64626\AppData\Local\Temp\jieba.cache
Loading model cost 0.454 seconds.
Prefix dict has been built successfully.


准确率: 1.0
              precision    recall  f1-score   support

           0       1.00      1.00      1.00     44983
           1       1.00      1.00      1.00     15017

    accuracy                           1.00     60000
   macro avg       1.00      1.00      1.00     60000
weighted avg       1.00      1.00      1.00     60000

混淆矩阵:
 [[44983     0]
 [    0 15017]]

垃圾短信分类柱状图
垃圾短信分类饼图
垃圾短信分类词云图

LSTM(Long Short-Term Memory),也就是长期循环单元网络,是一种深度学习模型,主要用于处理序列数据,例如文本、语音等。在垃圾短信分类任务中,LSTM 的应用可以帮助我们识别和区分正常信息与垃圾信息。 ### LSTM 在垃圾短信分类中的工作原理 1. **输入层**:接收待分类的文本数据作为输入,可以对每个单词或词组编码成向量形式,形成序列输入到神经网络中。 2. **隐藏层**:LSTM 层的核心在于其独特的结构设计,它通过记忆单元 (memory cell) 来存储信息,并通过三个门控机制来控制信息的流入和流出: - 输入门(Input Gate):决定新的信息是否被添加到记忆单元中。 - 遗忘门(Forget Gate):控制旧的信息是否从记忆单元中被遗忘。 - 输出门(Output Gate):决定记忆单元中哪些部分将被用于计算当前时间步的输出。 3. **输出层**:基于 LSTM 计算出的状态值,经过适当的转换(如全连接层和激活函数)生成垃圾短信的概率分数,从而实现分类决策。 ### 应用流程概览: 1. **预处理**:清洗数据,去除无关字符,转换文本为可输入模型的形式(如分词并转换为数字ID)。 2. **特征提取**:可以结合词嵌入技术提高模型性能,将每个单词转化为高维向量表示。 3. **模型训练**:使用大量已标记的数据集训练 LSTM 模型,调整超参数以优化性能。 4. **评估与测试**:验证模型的准确性和泛化能力,在真实场景下进行实际应用。 ### 相关问题: 1. **如何选择合适的 LSTM 参数进行垃圾短信分类?** 2. **在构建LSTM模型时,应如何处理大量的非结构化文本数据?** 3. **有哪些常见的技巧可以提升LSTM在网络架构和训练过程中的效率?** 通过合理地设置和调整参数,以及有效的数据预处理策略,LSTM 能够在垃圾短信分类任务中展现出强大的性能,有效地帮助用户过滤不必要的信息流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昊哲小课

桃李不言下自成蹊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值