垃圾短信分类

垃圾短信分类

使用说明:

  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. 可视化部分展示了数据分布和关键词云,帮助理解数据特征

引入依赖库

python 复制代码
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  # 导入词云生成库

数据加载

python 复制代码
# 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  # 返回加载后的数据框

数据清洗

python 复制代码
# 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  # 返回清洗后的数据框

数据脱敏函数

python 复制代码
# 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  # 返回脱敏后的数据框

文本分词函数

python 复制代码
# 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)

模型训练函数

python 复制代码
# 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  # 返回训练好的模型和向量化器

数据可视化函数

python 复制代码
# 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()  # 显示图表

主程序流程

python 复制代码
# 主程序流程
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]]



相关推荐
Nona99612 分钟前
从零开始学AI——2
机器学习
张琪杭3 分钟前
python算法:leetcode二叉树相关算法题
python·算法·leetcode·职场和发展
点我头像干啥5 分钟前
乳腺超声图像结节分割
人工智能·深度学习·opencv·计算机视觉
import_random5 分钟前
[机器学习]模型的参数 vs 超参数
机器学习
java1234_小锋5 分钟前
一周学会Flask3 Python Web开发-SQLAlchemy数据迁移migrate
开发语言·前端·python·flask·flask3
Uzuki8 分钟前
AI可解释性 I | 对抗样本(Adversarial Sample)论文导读(持续更新)
深度学习·机器学习·可解释性
天天进步201523 分钟前
Python项目-基于Python的网络爬虫与数据可视化系统
爬虫·python·信息可视化
高-老师24 分钟前
AI(DeepSeek、ChatGPT)、Python、ArcGIS Pro多技术融合下的空间数据分析、建模与科研绘图及论文写作
人工智能·python·gpt·chatgpt·空间分析
少年码客26 分钟前
机器学习、图像识别、视觉识别框架的对比表:
人工智能·机器学习
Funny_AI_LAB33 分钟前
DeepSeek-V3-0324对比OpenAI GPT-4o和Gemini 2.5 Pro
人工智能·ai·语言模型·chatgpt