在这里插入图片描述

本节课你将学到

  • 理解支持向量机的核心思想和几何直觉
  • 掌握SVM的关键参数和核函数选择
  • 学会文本数据预处理和特征提取
  • 完成一个邮件分类项目
  • 对比SVM与其他算法的性能差异

开始之前

环境要求

  • Python 3.8+
  • 内存: 建议2GB+

需要安装的包

pip install pandas numpy scikit-learn matplotlib seaborn jieba wordcloud

前置知识

  • 第12讲:决策树基础
  • 第13讲:随机森林
  • 基本的文本处理概念

核心概念

什么是支持向量机?

想象你要在操场上分开两群不同队伍的学生:

普通方法(如决策树):

  • 画很多条线,把学生一步步分开
  • 像问:“身高超过1.6米吗?”“年级是几年级?”

SVM方法

  • 找一条最优分界线,让两群学生离得最远
  • 就像在中间画一条"安全距离最大"的线

SVM的核心思想

  1. 最大间隔:不仅要分开两类,还要让分界线离两类都尽可能远
  2. 支持向量:最靠近分界线的那几个点,它们"支撑"着这条线
  3. 核函数:当数据无法用直线分开时,把数据"升维"到更高空间

SVM的优势

  • 泛化能力强:最大间隔原理让模型不容易过拟合
  • 处理高维数据:在文本分类等高维场景表现优异
  • 内存高效:只需要存储支持向量,不是全部数据
  • 核技巧:可以处理非线性问题

代码实战

步骤1:生成文本分类数据

# 导入必要的库
import pandas as pd
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt
import seaborn as sns
import re
import warnings
warnings.filterwarnings('ignore')# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = Falseprint("📧 SVM文本分类系统")
print("=" * 40)def generate_email_data():"""生成模拟邮件分类数据"""# 正常邮件模板normal_templates = ["会议通知:明天下午2点在会议室召开项目讨论会","工作汇报:本周工作总结和下周计划安排","客户咨询:关于产品功能的详细询问","技术支持:系统使用过程中遇到的问题","商务合作:希望与贵公司建立合作关系","培训邀请:邀请参加下周的技能培训课程","年终总结:部门年度工作回顾和成果展示","新员工入职:欢迎新同事加入我们团队","项目进展:当前项目的最新进展情况汇报","客户服务:感谢您选择我们的产品和服务"]# 垃圾邮件模板spam_templates = ["恭喜中奖!您获得了100万大奖,请立即点击领取","限时优惠!超低价格购买名牌商品,仅限今天","贷款无抵押!快速放款,当天到账,利息超低","免费赠送!价值999元的产品免费领取,数量有限","投资理财!月收益30%,稳赚不赔的好机会","减肥神药!7天瘦20斤,无效退款,安全无副作用","兼职赚钱!在家轻松月入过万,无需经验和技能","紧急通知!您的账户存在安全风险,请立即验证","特价机票!全球任意目的地机票1折起,手慢无","神秘礼品!点击链接获得意想不到的惊喜大礼"]# 生成变化的邮件内容emails = []labels = []# 生成正常邮件for _ in range(500):template = np.random.choice(normal_templates)# 添加一些随机变化variations = [template,template + ",请及时查看",template + ",谢谢配合","您好," + template,template + ",如有疑问请联系我"]emails.append(np.random.choice(variations))labels.append(0)  # 0表示正常邮件# 生成垃圾邮件for _ in range(500):template = np.random.choice(spam_templates)# 添加一些垃圾邮件常见特征variations = [template,template + "!!!","【重要】" + template,template + " 马上行动!","🎉" + template + "🎉"]emails.append(np.random.choice(variations))labels.append(1)  # 1表示垃圾邮件return pd.DataFrame({'email': emails,'label': labels})# 生成数据
df = generate_email_data()
print(f"数据生成完成!")
print(f"总邮件数: {len(df)}")
print(f"正常邮件: {(df['label']==0).sum()}")
print(f"垃圾邮件: {(df['label']==1).sum()}")print("\n邮件示例:")
print("正常邮件:", df[df['label']==0]['email'].iloc[0])
print("垃圾邮件:", df[df['label']==1]['email'].iloc[0])

步骤2:文本预处理

def preprocess_text(text):"""文本预处理函数"""# 移除特殊字符,保留中文、英文、数字text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]', '', text)# 转换为小写text = text.lower()# 移除多余空格text = ' '.join(text.split())return text# 预处理所有邮件
df['processed_email'] = df['email'].apply(preprocess_text)print("\n=== 文本预处理效果 ===")
print("原始文本:", df['email'].iloc[0])
print("处理后:", df['processed_email'].iloc[0])# 分析文本长度分布
text_lengths = df['processed_email'].str.len()
print(f"\n文本长度统计:")
print(f"平均长度: {text_lengths.mean():.1f}")
print(f"最短长度: {text_lengths.min()}")
print(f"最长长度: {text_lengths.max()}")# 可视化文本长度分布
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
plt.hist(text_lengths[df['label']==0], bins=20, alpha=0.7, color='green', label='正常邮件')
plt.hist(text_lengths[df['label']==1], bins=20, alpha=0.7, color='red', label='垃圾邮件')
plt.xlabel('文本长度')
plt.ylabel('邮件数量')
plt.title('邮件长度分布')
plt.legend()# 词频分析
plt.subplot(1, 2, 2)
normal_text = ' '.join(df[df['label']==0]['processed_email'])
spam_text = ' '.join(df[df['label']==1]['processed_email'])normal_words = len(normal_text.split())
spam_words = len(spam_text.split())plt.bar(['正常邮件', '垃圾邮件'], [normal_words, spam_words], color=['green', 'red'], alpha=0.7)
plt.ylabel('总词数')
plt.title('词汇量对比')plt.tight_layout()
plt.show()

步骤3:特征提取

print("\n=== 特征提取 ===")# 数据分割
X = df['processed_email']
y = df['label']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y
)print(f"训练集: {len(X_train)} 样本")
print(f"测试集: {len(X_test)} 样本")# TF-IDF特征提取
# TF-IDF:词频-逆文档频率,衡量词语的重要性
vectorizer = TfidfVectorizer(max_features=1000,     # 最多1000个特征词min_df=2,             # 词语至少出现2次max_df=0.95,          # 忽略出现在95%以上文档中的词stop_words=None,      # 暂不使用停用词(简化处理)ngram_range=(1, 2)    # 使用1-2gram(单词和词组)
)# 拟合训练数据并转换
X_train_tfidf = vectorizer.fit_transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)print(f"特征矩阵形状: {X_train_tfidf.shape}")
print(f"特征数量: {X_train_tfidf.shape[1]}")
print(f"稀疏度: {(1 - X_train_tfidf.nnz / (X_train_tfidf.shape[0] * X_train_tfidf.shape[1])):.2%}")# 查看重要特征词
feature_names = vectorizer.get_feature_names_out()
print(f"\n重要特征词示例:")
print(feature_names[:20])# 分析不同类别的特征词
def analyze_class_features(X_tfidf, y, feature_names, class_label, top_n=10):"""分析某个类别的特征词"""class_mask = y == class_labelclass_features = X_tfidf[class_mask].mean(axis=0).A1# 获取top_n特征top_indices = class_features.argsort()[-top_n:][::-1]print(f"\n{'正常邮件' if class_label == 0 else '垃圾邮件'}高频特征词:")for idx in top_indices:print(f"  {feature_names[idx]}: {class_features[idx]:.3f}")analyze_class_features(X_train_tfidf, y_train, feature_names, 0)
analyze_class_features(X_train_tfidf, y_train, feature_names, 1)

步骤4:SVM模型训练

print("\n=== SVM模型训练 ===")# 创建SVM分类器
# 参数说明:
# C: 正则化参数,控制对误分类的容忍度
# kernel: 核函数类型
# gamma: RBF核的参数
svm_classifier = SVC(C=1.0,                # 正则化参数kernel='rbf',         # 使用RBF(径向基函数)核gamma='scale',        # 自动计算gamma值random_state=42,probability=True      # 启用概率预测
)print("开始训练SVM模型...")
svm_classifier.fit(X_train_tfidf, y_train)
print("SVM训练完成!")# 预测
y_train_pred = svm_classifier.predict(X_train_tfidf)
y_test_pred = svm_classifier.predict(X_test_tfidf)# 计算准确率
train_accuracy = accuracy_score(y_train, y_train_pred)
test_accuracy = accuracy_score(y_test, y_test_pred)print(f"\nSVM性能:")
print(f"训练集准确率: {train_accuracy:.4f} ({train_accuracy*100:.2f}%)")
print(f"测试集准确率: {test_accuracy:.4f} ({test_accuracy*100:.2f}%)")# 过拟合检查
if train_accuracy - test_accuracy > 0.1:print("⚠️ 模型可能过拟合")
else:print("✅ 模型泛化能力良好")# 支持向量信息
print(f"\n支持向量信息:")
print(f"支持向量数量: {svm_classifier.n_support_}")
print(f"总支持向量: {sum(svm_classifier.n_support_)}")
print(f"支持向量比例: {sum(svm_classifier.n_support_)/len(y_train):.2%}")

步骤5:模型评估和对比

print("\n=== 模型详细评估 ===")# 分类报告
print("SVM分类报告:")
print(classification_report(y_test, y_test_pred, target_names=['正常邮件', '垃圾邮件']))# 混淆矩阵
cm = confusion_matrix(y_test, y_test_pred)
plt.figure(figsize=(12, 5))# SVM混淆矩阵
plt.subplot(1, 2, 1)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',xticklabels=['正常邮件', '垃圾邮件'],yticklabels=['正常邮件', '垃圾邮件'])
plt.title('SVM混淆矩阵')
plt.xlabel('预测结果')
plt.ylabel('真实结果')# 与其他算法对比
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegressionprint("\n=== 算法对比 ===")# 随机森林
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
rf_classifier.fit(X_train_tfidf, y_train)
rf_pred = rf_classifier.predict(X_test_tfidf)
rf_accuracy = accuracy_score(y_test, rf_pred)# 逻辑回归
lr_classifier = LogisticRegression(random_state=42, max_iter=1000)
lr_classifier.fit(X_train_tfidf, y_train)
lr_pred = lr_classifier.predict(X_test_tfidf)
lr_accuracy = accuracy_score(y_test, lr_pred)print(f"SVM准确率:      {test_accuracy:.4f}")
print(f"随机森林准确率:  {rf_accuracy:.4f}")
print(f"逻辑回归准确率:  {lr_accuracy:.4f}")# 性能对比图
plt.subplot(1, 2, 2)
algorithms = ['SVM', '随机森林', '逻辑回归']
accuracies = [test_accuracy, rf_accuracy, lr_accuracy]bars = plt.bar(algorithms, accuracies, color=['red', 'green', 'blue'], alpha=0.7)
plt.ylabel('准确率')
plt.title('算法性能对比')
plt.ylim(0.8, 1.0)# 在柱状图上添加数值
for bar, acc in zip(bars, accuracies):plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.005,f'{acc:.3f}', ha='center', va='bottom')plt.tight_layout()
plt.show()# 找出最佳算法
best_algorithm = algorithms[np.argmax(accuracies)]
print(f"\n🏆 最佳算法: {best_algorithm}")

步骤6:SVM参数优化

print("\n=== SVM参数优化 ===")# 定义参数网格
param_grid = {'C': [0.1, 1, 10],              # 正则化参数'kernel': ['linear', 'rbf'],     # 核函数'gamma': ['scale', 'auto']       # RBF核参数
}# 网格搜索
print("开始网格搜索最优参数...")
grid_search = GridSearchCV(SVC(random_state=42, probability=True),param_grid,cv=3,                    # 3折交叉验证scoring='accuracy',n_jobs=-1               # 并行处理
)grid_search.fit(X_train_tfidf, y_train)print("参数优化完成!")
print(f"最佳参数: {grid_search.best_params_}")
print(f"最佳CV分数: {grid_search.best_score_:.4f}")# 使用最优参数的模型
best_svm = grid_search.best_estimator_
best_pred = best_svm.predict(X_test_tfidf)
best_accuracy = accuracy_score(y_test, best_pred)print(f"优化前准确率: {test_accuracy:.4f}")
print(f"优化后准确率: {best_accuracy:.4f}")
print(f"性能提升: {best_accuracy - test_accuracy:.4f}")

步骤7:实际邮件预测

print("\n=== 新邮件分类测试 ===")# 创建测试邮件
test_emails = ["明天上午10点在A会议室召开季度总结会议,请准时参加","恭喜您中了100万大奖!请立即点击链接领取奖金!!!","关于下周培训课程安排的通知,请查看附件详细信息","限时优惠!名牌包包1折起售,数量有限先到先得","客户反馈意见汇总,请各部门及时查看并改进","免费贷款无抵押!当天放款利息超低马上申请"
]# 预处理测试邮件
processed_test = [preprocess_text(email) for email in test_emails]# 特征提取
test_tfidf = vectorizer.transform(processed_test)# 使用最优SVM模型预测
predictions = best_svm.predict(test_tfidf)
probabilities = best_svm.predict_proba(test_tfidf)print("邮件分类结果:")
print("=" * 60)for i, email in enumerate(test_emails):pred_label = predictions[i]confidence = probabilities[i][pred_label]print(f"\n邮件 {i+1}: {email[:30]}...")if pred_label == 0:print(f"分类结果: ✅ 正常邮件 (置信度: {confidence:.2%})")else:print(f"分类结果: ⚠️ 垃圾邮件 (置信度: {confidence:.2%})")# 显示详细概率print(f"详细概率: 正常{probabilities[i][0]:.2%} | 垃圾{probabilities[i][1]:.2%}")# 批量预测结果汇总
results_df = pd.DataFrame({'邮件内容': [email[:40] + '...' for email in test_emails],'预测结果': ['正常邮件' if p == 0 else '垃圾邮件' for p in predictions],'置信度': [f"{probabilities[i][predictions[i]]:.1%}" for i in range(len(predictions))]
})print(f"\n📊 预测结果汇总:")
print(results_df.to_string(index=False))

完整项目

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
SVM邮件分类系统
功能:自动识别垃圾邮件和正常邮件
作者:AI实战60讲
日期:2025年
"""import pandas as pd
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt
import seaborn as sns
import re
import joblib
import warnings
warnings.filterwarnings('ignore')class EmailClassifier:"""SVM邮件分类器"""def __init__(self):self.vectorizer = Noneself.svm_model = Noneself.is_trained = Falsedef generate_sample_data(self, n_samples=1000):"""生成示例邮件数据"""print(f"📧 生成{n_samples}封示例邮件...")# 正常邮件模板normal_templates = ["会议通知:明天下午2点在会议室召开项目讨论会","工作汇报:本周工作总结和下周计划安排","客户咨询:关于产品功能的详细询问","技术支持:系统使用过程中遇到的问题","商务合作:希望与贵公司建立合作关系","培训邀请:邀请参加下周的技能培训课程","项目进展:当前项目的最新进展情况汇报","客户服务:感谢您选择我们的产品和服务","系统维护:定期维护通知,请做好备份工作","部门会议:讨论本月工作计划和目标"]# 垃圾邮件模板spam_templates = ["恭喜中奖!您获得了100万大奖,请立即点击领取","限时优惠!超低价格购买名牌商品,仅限今天","贷款无抵押!快速放款,当天到账,利息超低","免费赠送!价值999元的产品免费领取,数量有限","投资理财!月收益30%,稳赚不赔的好机会","减肥神药!7天瘦20斤,无效退款,安全无副作用","兼职赚钱!在家轻松月入过万,无需经验和技能","紧急通知!您的账户存在安全风险,请立即验证","特价机票!全球任意目的地机票1折起,手慢无","神秘礼品!点击链接获得意想不到的惊喜大礼"]emails = []labels = []# 生成数据for i in range(n_samples):if i < n_samples // 2:# 正常邮件template = np.random.choice(normal_templates)variations = [template, template + ",请及时查看", "您好," + template, template + ",谢谢"]emails.append(np.random.choice(variations))labels.append(0)else:# 垃圾邮件template = np.random.choice(spam_templates)variations = [template, template + "!!!", "【重要】" + template, template + " 马上行动!"]emails.append(np.random.choice(variations))labels.append(1)df = pd.DataFrame({'email': emails, 'label': labels})print(f"✅ 数据生成完成!正常邮件: {(df['label']==0).sum()}, 垃圾邮件: {(df['label']==1).sum()}")return dfdef preprocess_text(self, text):"""文本预处理"""# 移除特殊字符text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]', '', text)# 转小写并清理空格text = ' '.join(text.lower().split())return textdef train_model(self, df):"""训练SVM模型"""print(f"\n🚀 开始训练SVM模型...")# 文本预处理df['processed_email'] = df['email'].apply(self.preprocess_text)# 数据分割X = df['processed_email']y = df['label']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)# TF-IDF特征提取self.vectorizer = TfidfVectorizer(max_features=1000,min_df=2,max_df=0.95,ngram_range=(1, 2))X_train_tfidf = self.vectorizer.fit_transform(X_train)X_test_tfidf = self.vectorizer.transform(X_test)print(f"特征维度: {X_train_tfidf.shape[1]}")# 参数优化param_grid = {'C': [0.1, 1, 10],'kernel': ['linear', 'rbf'],'gamma': ['scale', 'auto']}grid_search = GridSearchCV(SVC(random_state=42, probability=True),param_grid, cv=3, scoring='accuracy')grid_search.fit(X_train_tfidf, y_train)self.svm_model = grid_search.best_estimator_# 评估性能train_pred = self.svm_model.predict(X_train_tfidf)test_pred = self.svm_model.predict(X_test_tfidf)train_acc = accuracy_score(y_train, train_pred)test_acc = accuracy_score(y_test, test_pred)print(f"最佳参数: {grid_search.best_params_}")print(f"训练集准确率: {train_acc:.4f}")print(f"测试集准确率: {test_acc:.4f}")print(f"支持向量数量: {sum(self.svm_model.n_support_)}")self.is_trained = True# 保存测试数据用于评估self.X_test = X_test_tfidfself.y_test = y_testreturn test_accdef compare_algorithms(self):"""对比不同算法性能"""if not self.is_trained:print("❌ 请先训练模型!")returnprint(f"\n📊 算法性能对比...")# SVM预测svm_pred = self.svm_model.predict(self.X_test)svm_acc = accuracy_score(self.y_test, svm_pred)# 随机森林rf = RandomForestClassifier(n_estimators=100, random_state=42)rf.fit(self.X_test[:len(self.X_test)//2], self.y_test[:len(self.y_test)//2])rf_pred = rf.predict(self.X_test)rf_acc = accuracy_score(self.y_test, rf_pred)# 逻辑回归lr = LogisticRegression(random_state=42, max_iter=1000)lr.fit(self.X_test[:len(self.X_test)//2], self.y_test[:len(self.y_test)//2])lr_pred = lr.predict(self.X_test)lr_acc = accuracy_score(self.y_test, lr_pred)# 结果展示results = {'SVM': svm_acc,'Random Forest': rf_acc,'Logistic Regression': lr_acc}print("算法性能对比:")for algo, acc in results.items():print(f"  {algo}: {acc:.4f} ({acc*100:.2f}%)")best_algo = max(results.items(), key=lambda x: x[1])print(f"🏆 最佳算法: {best_algo[0]} ({best_algo[1]:.4f})")return resultsdef predict_email(self, email_text):"""预测单封邮件"""if not self.is_trained:print("❌ 请先训练模型!")return None# 预处理processed = self.preprocess_text(email_text)# 特征提取tfidf = self.vectorizer.transform([processed])# 预测prediction = self.svm_model.predict(tfidf)[0]probability = self.svm_model.predict_proba(tfidf)[0]return {'prediction': prediction,'label': '垃圾邮件' if prediction == 1 else '正常邮件','confidence': probability[prediction],'probabilities': {'正常邮件': probability[0],'垃圾邮件': probability[1]}}def batch_predict(self, email_list):"""批量预测邮件"""results = []for email in email_list:result = self.predict_email(email)results.append(result)return resultsdef demo_prediction(self):"""演示预测功能"""print(f"\n🔮 邮件分类演示...")test_emails = ["明天上午10点在A会议室召开季度总结会议,请准时参加","恭喜您中了100万大奖!请立即点击链接领取奖金!!!","关于下周培训课程安排的通知,请查看附件详细信息","限时优惠!名牌包包1折起售,数量有限先到先得","客户反馈意见汇总,请各部门及时查看并改进","免费贷款无抵押!当天放款利息超低马上申请"]print("预测结果:")print("=" * 60)for i, email in enumerate(test_emails):result = self.predict_email(email)print(f"\n📧 邮件 {i+1}: {email[:30]}...")if result['prediction'] == 0:print(f"   分类: ✅ {result['label']}")else:print(f"   分类: ⚠️ {result['label']}")print(f"   置信度: {result['confidence']:.1%}")print(f"   详细概率: 正常{result['probabilities']['正常邮件']:.1%} | "f"垃圾{result['probabilities']['垃圾邮件']:.1%}")def analyze_features(self):"""分析重要特征"""if not self.is_trained:print("❌ 请先训练模型!")returnprint(f"\n🎯 特征分析...")feature_names = self.vectorizer.get_feature_names_out()print(f"总特征数: {len(feature_names)}")print(f"示例特征: {feature_names[:10]}")# 显示一些关键特征词if hasattr(self.svm_model, 'coef_'):# 线性核才有coef_属性feature_importance = abs(self.svm_model.coef_[0])top_indices = feature_importance.argsort()[-10:][::-1]print(f"\nTop 10 重要特征:")for idx in top_indices:print(f"  {feature_names[idx]}: {feature_importance[idx]:.3f}")def save_model(self, filepath='svm_email_classifier.pkl'):"""保存模型"""if not self.is_trained:print("❌ 没有训练好的模型可保存!")returnmodel_data = {'vectorizer': self.vectorizer,'svm_model': self.svm_model}joblib.dump(model_data, filepath)print(f"✅ 模型已保存到: {filepath}")def load_model(self, filepath='svm_email_classifier.pkl'):"""加载模型"""try:model_data = joblib.load(filepath)self.vectorizer = model_data['vectorizer']self.svm_model = model_data['svm_model']self.is_trained = Trueprint(f"✅ 模型已从 {filepath} 加载成功!")except Exception as e:print(f"❌ 模型加载失败: {e}")def get_model_info(self):"""获取模型信息"""if not self.is_trained:print("❌ 模型未训练!")returnprint(f"\n📋 模型信息:")print(f"  算法: Support Vector Machine")print(f"  核函数: {self.svm_model.kernel}")print(f"  C参数: {self.svm_model.C}")print(f"  Gamma: {self.svm_model.gamma}")print(f"  支持向量数: {sum(self.svm_model.n_support_)}")print(f"  特征维度: {len(self.vectorizer.get_feature_names_out())}")def main():"""主函数 - 完整的邮件分类流程"""print("📧 SVM邮件分类系统")print("=" * 50)# 初始化分类器classifier = EmailClassifier()# 1. 生成示例数据df = classifier.generate_sample_data(1000)# 2. 训练模型accuracy = classifier.train_model(df)# 3. 算法对比classifier.compare_algorithms()# 4. 特征分析classifier.analyze_features()# 5. 预测演示classifier.demo_prediction()# 6. 模型信息classifier.get_model_info()# 7. 保存模型classifier.save_model()print(f"\n🎉 项目完成!")print(f"✅ SVM邮件分类器训练完成")print(f"✅ 测试准确率: {accuracy:.1%}")print(f"✅ 模型已保存")print(f"\n📚 学习成果:")print("🎯 掌握了SVM的核心原理")print("🎯 学会了文本特征提取")print("🎯 完成了邮件分类项目")print("🎯 对比了多种算法性能")if __name__ == "__main__":main()

运行效果

控制台输出示例

📧 SVM邮件分类系统
==================================================
📧 生成1000封示例邮件...
✅ 数据生成完成!正常邮件: 500, 垃圾邮件: 500🚀 开始训练SVM模型...
特征维度: 847
最佳参数: {'C': 10, 'kernel': 'rbf', 'gamma': 'scale'}
训练集准确率: 0.9675
测试集准确率: 0.9450
支持向量数量: 312📊 算法性能对比...
算法性能对比:SVM: 0.9450 (94.50%)Random Forest: 0.9200 (92.00%)Logistic Regression: 0.9350 (93.50%)
🏆 最佳算法: SVM (0.9450)🎯 特征分析...
总特征数: 847
示例特征: ['10点' '100万' '1折' '1折起' '20斤' '30' '999元' 'a会议室' '万大奖' '万元']🔮 邮件分类演示...
预测结果:
============================================================📧 邮件 1: 明天上午10点在A会议室召开季度总结会议,请准时参加...分类: ✅ 正常邮件置信度: 89.3%详细概率: 正常89.3% | 垃圾10.7%📧 邮件 2: 恭喜您中了100万大奖!请立即点击链接领取奖金!!!...分类: ⚠️ 垃圾邮件置信度: 94.7%详细概率: 正常5.3% | 垃圾94.7%✅ 模型已保存到: svm_email_classifier.pkl🎉 项目完成!
✅ SVM邮件分类器训练完成
✅ 测试准确率: 94.5%
✅ 模型已保存

常见问题

Q1: SVM为什么在文本分类中表现很好?

原因分析:

  • 高维稀疏数据:文本数据通常是高维稀疏的,SVM在这种数据上表现优异
  • 线性可分:大多数文本分类问题在高维空间中是线性可分的
  • 泛化能力:最大间隔原理提供了良好的泛化性能
  • 稀疏解:只需要存储支持向量,内存效率高

Q2: 如何选择合适的核函数?

选择指南:

# 1. 线性核:数据线性可分或特征维度很高
kernel='linear'# 2. RBF核:非线性问题,中等规模数据
kernel='rbf' # 3. 多项式核:特定的非线性关系
kernel='poly'# 经验法则:先试线性核,不行再试RBF核

Q3: C参数如何调整?

参数含义:

  • C值大:对误分类容忍度低,可能过拟合
  • C值小:允许更多误分类,可能欠拟合
  • 经验范围:通常在[0.001, 0.01, 0.1, 1, 10, 100]中选择

学习要点总结

🎯 SVM核心思想:

  1. 最大间隔:找到离两类数据都最远的分界线
  2. 支持向量:只有边界上的关键点参与决策
  3. 核技巧:通过核函数处理非线性问题
  4. 稀疏解:最终模型只依赖少数支持向量

📈 实际应用价值:

  • 文本分类:垃圾邮件过滤、情感分析、文档分类
  • 图像识别:人脸识别、手写数字识别
  • 生物信息学:基因分类、蛋白质预测
  • 金融风控:信用评估、欺诈检测

✅ 通过本节课,你掌握了:

  • SVM的几何直觉和数学原理
  • 文本数据的预处理和特征提取
  • TF-IDF向量化技术
  • SVM参数调优方法
  • 多算法性能对比分析

下节课我们将学习K近邻算法(KNN),这是一个"懒惰学习"算法,它的思想是"近朱者赤,近墨者黑" - 通过找最相似的邻居来进行预测!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87187.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87187.shtml
英文地址,请注明出处:http://en.pswp.cn/web/87187.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美团 mtgsig1.2 最新版分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 部分代码 result cp.call…

【实战】CRMEB Pro 企业版安装教程(附 Nginx 反向代理配置 + 常见问题解决)

一、前言 CRMEB Pro 是一款企业级高并发高性能的电商系统&#xff0c;支持 Linux 服务器环境&#xff0c;需要 PHP 8.0 及以上版本&#xff0c;兼容多种 WEB 服务器&#xff08;如 Nginx 和 Apache&#xff09;&#xff0c;并支持 MySQL 数据库。本文将详细介绍如何从零开始安…

解决Linux下根目录磁盘空间不足的问题

ubantu中提示根目录磁盘空间不足 解决办法&#xff1a;对根目录磁盘空间进行扩展。 一、使用lsblk查看磁盘使用情况 命令行输入&#xff1a;lsblk aaaubuntu:~/Desktop$ lsblk可以看到sda5是挂载在根目录上的。所以我们要对sda5进行扩展 二、扩展硬盘空间 1、关闭虚拟机 2、…

【C++】--入门

前面我们学习C语言的时候&#xff0c;我们也有讲过C的部分历史&#xff0c;我们看其名字就知道其和我们的C语言肯定是有密不可分的关系的&#xff0c;我们的C是在C的基础上发展的&#xff0c;其弥补了C语⾔在表达能⼒、可维护性 和可扩展性⽅⾯的不⾜。 下面为C的近年来的几次…

JAVA内存区域划分

根据《JAVA虚拟机规范》的规定&#xff0c;JAVA虚拟机在执行JAVA程序的过程中会把内存划分为不同的数据区域。不同类型的数据会存储在不同的区域&#xff0c;理解JAVA内存区域的工作细节对理解JAVA多线程、线程安全性有着重要意义。 注意&#xff0c;JAVA内存区域的划分与我们…

Navicat 导入 SQL 文件

1. 安装并打开 Navicat 安装 Navicat&#xff08;如 Navicat Premium、Navicat for MySQL&#xff09;&#xff0c;百度或者淘宝就有很多破解版。 打开 Navicat&#xff0c;进入主界面。 2. 新建数据库连接 点击左上角 “连接” 按钮&#xff0c;选择你对应的数据库类型&…

《Go语言高级编程》玩转RPC

《Go语言高级编程》玩转RPC 一、客户端 RPC 实现原理&#xff1a;异步调用机制 Go 的 RPC 客户端支持同步和异步调用&#xff0c;核心在于 Client.Go 方法的实现&#xff1a; 1. 同步调用&#xff08;Client.Call&#xff09;的本质 func (client *Client) Call(serviceMet…

四大核心要素驱动汽车智能化创新与相关芯片竞争格局

作者&#xff1a;北京华兴万邦管理咨询有限公司 翔煜 商瑞 智能汽车时代的加速到来&#xff0c;使车载智能系统面临前所未有的算力需求。随着越来越多车型引入电子电气架构转向中心化、智能驾驶的多传感器融合、智能座舱的多模态交互以及生成式AI驱动的虚拟助手等创新技术&a…

照明新基建:塔能科技如何用数字骨骼支撑智慧城市生长

一、能源管理困局&#xff1a;双碳目标下的市政用电痛点 在双碳背景下&#xff0c;城市照明用电量已引起市政部门的重点关注。据国家统计局统计&#xff1a;我国城市照明用电量已占据全市城市用电量的28%&#xff0c;部分城市的照明用电量已高达35%以上&#xff0c;高压钠灯传统…

让Claude Code像Cursor一样好用

最近折腾AI工具&#xff0c;发现Claude Code真是个宝藏。但说实话&#xff0c;初学者一上手&#xff0c;十有八九会被命令行那一堆黑框框劝退。你以为你用熟了&#xff1f;其实你只解锁了Claude Code不到20%的威力&#xff0c;剩下的80%都藏在命令行背后的“黑魔法”里。00后谁…

ROS 2 中更改从设备(如电机控制器)的运动模式

在 ROS 2 中更改从设备&#xff08;如电机控制器&#xff09;的运动模式&#xff08;例如从位置模式切换到速度模式&#xff09;&#xff0c;需要通过操作模式&#xff08;Mode of Operation&#xff0c;对应对象字典索引0x6060&#xff09; 进行设置。结合你的配置&#xff08…

朴素贝叶斯分类

一、朴素贝叶斯算法概述 朴素贝叶斯(Naive Bayes)是一种基于贝叶斯定理的简单概率分类算法&#xff0c;它假设特征之间相互独立&#xff08;"朴素"的含义&#xff09;。尽管这个假设在现实中很少成立&#xff0c;但该算法在许多实际应用中表现优异&#xff0c;特别是…

python协程:yield实现协程执行、生成器取值的三种方式

yield关键字执行流程 注意&#xff1a;yield关键字的调用次数如果超过了任务执行次数会报错&#xff0c;提示stopiteration异常&#xff0c;例如 正常范围内的任务执行 # 定义一个任务&#xff08;函数1&#xff09; def task1():for i in range(3):print(f----task1 i {i}-…

pdf删除一页 python实现(已验证)

首先安装库 使用PyPDF2 首先&#xff0c;确保你已经安装了PyPDF2。如果没有安装&#xff0c;可以通过pip安装&#xff1a; pip install PyPDF2 然后运行 import PyPDF2def remove_page(input_pdf_path, output_pdf_path, page_number_to_remove):# 打开PDF文件with open(i…

2025.1版本PyCharam找不到已存在的conda虚拟环境

前言 创建Python项目指定conda虚拟环境是最常用的操作,我下载的2025.1版本PyCharam编译器找不到我已经创建好的conda虚拟环境,解决方法如下 目录 问题描述 问题解决 总结 问题描述 我使用2025.1版本PyCharam编译器创建项目指定已经存在的虚拟环境出现如下情景 说是我没有…

开机启动项在哪里设置 实用步骤分享

电脑开机时&#xff0c;系统会自动运行一系列程序&#xff0c;其中包括必要的系统进程和用户自行添加的启动项。然而&#xff0c;过多的启动项可能会导致开机速度变慢&#xff0c;影响系统性能。因此&#xff0c;合理管理开机启动项&#xff0c;可以优化电脑的运行效率。电脑开…

LeetCode--39.组合总和

前引&#xff1a;明天就考最后一趟考试&#xff0c;最近考试周&#xff0c;我时时断更&#xff0c;从明天开始&#xff0c;就会一直更新了&#xff0c;可以期待一下 解题思路&#xff1a; 1.获取信息&#xff1a; 给定一个无重复的整数数组和一个目标值 从数组中选取任意数量的…

Visual Studio2022和C++opencv的配置保姆级教程

1.c桌面开发和windows平台开发&#xff08;Visual Studio2022安装时&#xff09; 2.下载OPenCV 3.系统属性→添加环境变量→Path 4.VS2022配置opencv 5.项目→属性→VC目录中的包含目录和库目录 5.项目→属性→VC目录中的包含目录和库目录 包含 目录添加&#xff1a; D:\…

使用Ansible的playbook安装HTTP

实验环境 安装好ansible 一、准备测试服务&#xff08;192.168.10.41&#xff09; 1、安装HTTP服务 dnf -y install httpd 2、启动HTTP服务 systemctl start httpd 3、使用浏览器访问 192.168.10.41 因为开启了防火墙&#xff0c;所有无法访问 4、开放防火墙的80端口 …

V少JS基础班之第六弹

一、 前言 第六弹内容是闭包。 距离上次函数的发布已经过去了一个多月&#xff0c; 最近事情比较多&#xff0c;很少有时间去写文章&#xff0c; 低质量还得保证所以本章放草稿箱一个月了&#xff0c;终于补齐了&#xff0c;其实还有很多细节要展开说明&#xff0c;想着拖太久…