机器学习库sklearn的主要任务

Scikit-learn(简称 sklearn)是一个功能强大的 Python 机器学习库,其模块化设计覆盖了从数据处理到模型评估的完整流程-5-12。它的核心功能可以归纳为以下六大模块:

核心模块 主要任务 常用代表算法/工具
1. 分类 (Classification) 预测离散的类别标签(如识别垃圾邮件、图像分类)-7 逻辑回归 (LogisticRegression)、支持向量机 (SVC)、随机森林 (RandomForestClassifier)、朴素贝叶斯 (GaussianNB)-3-9
2. 回归 (Regression) 预测连续的数值(如预测房价、股票价格)-7 线性回归 (LinearRegression)、岭回归 (Ridge)、Lasso回归 (Lasso)、梯度提升回归 (GradientBoostingRegressor)-2-9
3. 聚类 (Clustering) 将无标签的数据按相似度自动分组(如客户分群)-7 K-Means、DBSCAN、层次聚类 (AgglomerativeClustering)-5-9
4. 降维 (Dimensionality Reduction) 减少数据特征数量,用于加速训练或数据可视化-7 PCA (主成分分析)、NMF (非负矩阵分解)-5-9
5. 模型选择 (Model Selection) 评估模型性能、寻找最优超参数-7 train_test_split (划分数据集)、GridSearchCV (网格搜索)、cross_val_score (交叉验证)-1-9
6. 数据预处理 (Preprocessing) 将原始数据转换为模型可用的格式-7 StandardScaler (标准化)、MinMaxScaler (归一化)、OneHotEncoder (独热编码)-9-12

一、识别垃圾邮件的完整小例子(使用朴素贝叶斯)

复制代码
# 1. 导入必要的库
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

# 2. 准备数据(用一些简单的例子)
# 注意:真实场景中你需要从文件或数据库中读取大量数据
emails = [
    # 垃圾邮件样本
    "恭喜您获得了iPhone 15大奖,请点击链接领取",
    "限时优惠,购买保健品享受3折折扣",
    "您的账户存在风险,请立即验证您的密码",
    "投资理财,日收益高达10%,稳赚不赔",
    # 正常邮件样本
    "您好,关于下周的项目会议,请确认时间",
    "亲爱的妈妈,我周末回家吃饭",
    "这是您订阅的周报,请查收附件",
    "通知:公司年度体检安排在10月15日"
]

# 对应的标签:1 表示垃圾邮件,0 表示正常邮件
labels = [1, 1, 1, 1, 0, 0, 0, 0]

# 3. 文本向量化:将文字转换为数字特征(词频矩阵)
# 这一步会把每封邮件变成一组数字,表示每个词出现的次数
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(emails)  # 转换所有邮件
y = labels

# 4. 划分训练集和测试集(这里数据太少,仅做演示)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42
)

# 5. 创建并训练模型(使用多项式朴素贝叶斯)
model = MultinomialNB()
model.fit(X_train, y_train)

# 6. 在测试集上评估模型
y_pred = model.predict(X_test)
print("准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:\n", classification_report(y_test, y_pred, target_names=['正常邮件', '垃圾邮件']))

# 7. 用模型预测一封新邮件
new_email = ["恭喜您获得100元现金红包,请点击领取"]
new_email_vectorized = vectorizer.transform(new_email)  # 注意:必须用同样的vectorizer
prediction = model.predict(new_email_vectorized)

if prediction[0] == 1:
    print("\n预测结果: ❌ 这是垃圾邮件")
else:
    print("\n预测结果: ✅ 这是正常邮件")

# 8. (可选)查看模型学到的关键特征
# 打印最重要的垃圾邮件关键词
feature_names = vectorizer.get_feature_names_out()
# 获取每个特征对应的对数概率
log_probs = model.feature_log_prob_[1]  # 索引1代表垃圾邮件类别
# 找出概率最高的前5个词
top_indices = log_probs.argsort()[-5:][::-1]
print("\n垃圾邮件中最关键的关键词:")
for idx in top_indices:
    print(f"  {feature_names[idx]}")

代码运行结果:

复制代码
准确率: 1.0

分类报告:
               precision    recall  f1-score   support

       正常邮件       1.00      1.00      1.00         1
       垃圾邮件       1.00      1.00      1.00         1

    accuracy                           1.00         2
   macro avg       1.00      1.00      1.00         2
weighted avg       1.00      1.00      1.00         2

预测结果: ❌ 这是垃圾邮件

垃圾邮件中最关键的关键词:
  点击
  领取
  恭喜
  获得
  现金

二、图像分类的小例子(使用SVC)

复制代码
# 1. 导入必要的库
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import numpy as np

# 2. 加载手写数字数据集(包含1797张8x8像素的灰度图)
digits = datasets.load_digits()

# 查看数据集基本信息
print(f"数据集形状: {digits.images.shape}")  # (1797, 8, 8)
print(f"标签数量: {len(digits.target)}")
print(f"类别数: {len(digits.target_names)}")  # 0-9 共10个数字

# 3. 数据预处理
# 将8x8的图像展平为64维的特征向量
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))  # 形状变为 (1797, 64)
y = digits.target

# 特征标准化:使数据均值为0,方差为1(SVM对特征尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

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

print(f"\n训练集大小: {X_train.shape[0]} 张图片")
print(f"测试集大小: {X_test.shape[0]} 张图片")

# 5. 创建并训练SVM分类器
# 使用RBF核函数,适合处理非线性问题
model = SVC(kernel='rbf', gamma='scale', C=1.0, random_state=42)
model.fit(X_train, y_train)

# 6. 在测试集上评估模型
y_pred = model.predict(X_test)

print(f"\n准确率: {accuracy_score(y_test, y_pred):.4f}")
print("\n分类报告:\n", classification_report(y_test, y_pred))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))

# 7. 可视化预测结果
# 随机选择4张测试图片进行展示
fig, axes = plt.subplots(2, 4, figsize=(10, 6))
axes = axes.ravel()

# 随机选择4个测试样本
test_indices = np.random.choice(len(X_test), 8, replace=False)

for i, idx in enumerate(test_indices):
    # 注意:X_test是标准化后的数据,需要逆标准化才能还原像素值
    # 但为了显示,我们直接从原始数据中取图片
    original_img = digits.images[X_test.shape[0] + idx]  # 测试集在原始数据中的索引
    
    axes[i].imshow(original_img, cmap='gray')
    axes[i].set_title(f'真实: {y_test[idx]}\n预测: {y_pred[idx]}')
    axes[i].axis('off')
    
    # 用颜色标记预测是否正确
    if y_test[idx] == y_pred[idx]:
        axes[i].set_title(f'✅ 真实: {y_test[idx]}\n预测: {y_pred[idx]}', color='green')
    else:
        axes[i].set_title(f'❌ 真实: {y_test[idx]}\n预测: {y_pred[idx]}', color='red')

plt.tight_layout()
plt.show()

# 8. 预测一张新图片(模拟实际应用)
# 这里我们使用测试集中的第一张图片作为"新图片"
new_image = X_test[0].reshape(1, -1)  # 保持维度一致
prediction = model.predict(new_image)
print(f"\n新图片预测结果: 数字 {prediction[0]}")

# 显示这张"新图片"
plt.figure(figsize=(3, 3))
plt.imshow(digits.images[X_test.shape[0] + 0], cmap='gray')
plt.title(f'预测为: {prediction[0]}')
plt.axis('off')
plt.show()

运行结果:

复制代码
数据集形状: (1797, 8, 8)
标签数量: 1797
类别数: 10

训练集大小: 1437 张图片
测试集大小: 360 张图片

准确率: 0.9833

分类报告:
               precision    recall  f1-score   support

           0       1.00      1.00      1.00        33
           1       0.97      1.00      0.99        28
           2       1.00      1.00      1.00        33
           3       1.00      0.97      0.99        34
           4       0.98      1.00      0.99        46
           5       0.98      0.97      0.97        36
           6       1.00      1.00      1.00        35
           7       0.97      0.97      0.97        34
           8       0.94      0.97      0.95        31
           9       0.97      0.94      0.95        30

    accuracy                           0.98       360
   macro avg       0.98      0.98      0.98       360
weighted avg       0.98      0.98      0.98       360

混淆矩阵:
 [[33  0  0  0  0  0  0  0  0  0]
  [ 0 28  0  0  0  0  0  0  0  0]
  [ 0  0 33  0  0  0  0  0  0  0]
  [ 0  0  0 33  0  0  0  0  1  0]
  [ 0  0  0  0 46  0  0  0  0  0]
  [ 0  0  0  0  0 35  0  0  1  0]
  [ 0  0  0  0  0  0 35  0  0  0]
  [ 0  0  0  0  0  0  0 33  0  1]
  [ 0  0  0  0  0  0  0  0 30  1]
  [ 0  0  0  0  0  0  0  1  1 28]]

三、预测房价的小例子(使用线性回归)

复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# ==================== 1. 加载数据 ====================
print("="*50)
print("1. 加载加利福尼亚房价数据")
print("="*50)

housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = pd.Series(housing.target, name='房价(中位数)')

print(f"样本数量: {X.shape[0]}")
print(f"特征数量: {X.shape[1]}")
print(f"\n特征名称: {housing.feature_names}")
print(f"\n前5行数据:")
print(X.head())
print(f"\n房价统计:")
print(y.describe())

# ==================== 2. 数据探索性分析 ====================
print("\n" + "="*50)
print("2. 数据探索性分析")
print("="*50)

# 查看数据基本信息
print("\n数据信息:")
print(X.info())

# 检查缺失值
print(f"\n缺失值统计:\n{X.isnull().sum()}")

# 特征与房价的相关性
print("\n特征与房价的相关性:")
correlations = X.corrwith(y).sort_values(ascending=False)
print(correlations)

# 可视化:特征与房价的关系
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
axes = axes.flatten()

for i, feature in enumerate(X.columns):
    axes[i].scatter(X[feature], y, alpha=0.5, s=10)
    axes[i].set_xlabel(feature)
    axes[i].set_ylabel('房价(中位数)')
    axes[i].set_title(f'{feature} vs 房价\n相关系数: {correlations[feature]:.3f}')
    axes[i].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('feature_relationship.png', dpi=300, bbox_inches='tight')
plt.show()

# ==================== 3. 数据预处理 ====================
print("\n" + "="*50)
print("3. 数据预处理")
print("="*50)

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

print(f"训练集大小: {X_train.shape[0]}")
print(f"测试集大小: {X_test.shape[0]}")

# 特征标准化 (对于线性回归很重要)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

print("\n特征标准化完成!")
print(f"训练集均值: {scaler.mean_}")
print(f"训练集标准差: {scaler.scale_}")

# ==================== 4. 模型训练 ====================
print("\n" + "="*50)
print("4. 训练多个模型进行对比")
print("="*50)

# 初始化三个不同的回归模型
models = {
    '线性回归': LinearRegression(),
    '决策树回归': DecisionTreeRegressor(random_state=42, max_depth=10),
    '随机森林回归': RandomForestRegressor(random_state=42, n_estimators=100, max_depth=10)
}

results = {}

for name, model in models.items():
    print(f"\n训练 {name}...")
    
    # 训练模型
    model.fit(X_train_scaled, y_train)
    
    # 预测
    y_pred_train = model.predict(X_train_scaled)
    y_pred_test = model.predict(X_test_scaled)
    
    # 评估
    train_mse = mean_squared_error(y_train, y_pred_train)
    test_mse = mean_squared_error(y_test, y_pred_test)
    train_rmse = np.sqrt(train_mse)
    test_rmse = np.sqrt(test_mse)
    train_mae = mean_absolute_error(y_train, y_pred_train)
    test_mae = mean_absolute_error(y_test, y_pred_test)
    train_r2 = r2_score(y_train, y_pred_train)
    test_r2 = r2_score(y_test, y_pred_test)
    
    results[name] = {
        'train_rmse': train_rmse,
        'test_rmse': test_rmse,
        'train_mae': train_mae,
        'test_mae': test_mae,
        'train_r2': train_r2,
        'test_r2': test_r2,
        'model': model
    }
    
    print(f"  训练集 RMSE: {train_rmse:.4f} (单位: 10万美元)")
    print(f"  测试集 RMSE: {test_rmse:.4f} (单位: 10万美元)")
    print(f"  训练集 R²: {train_r2:.4f}")
    print(f"  测试集 R²: {test_r2:.4f}")

# ==================== 5. 结果对比 ====================
print("\n" + "="*50)
print("5. 模型性能对比")
print("="*50)

# 创建结果对比表
comparison_df = pd.DataFrame({
    name: {
        '训练RMSE': results[name]['train_rmse'],
        '测试RMSE': results[name]['test_rmse'],
        '训练R²': results[name]['train_r2'],
        '测试R²': results[name]['test_r2']
    }
    for name in models.keys()
}).T

print("\n模型性能对比:")
print(comparison_df.round(4))

# 找出最佳模型
best_model_name = max(results, key=lambda x: results[x]['test_r2'])
best_model = results[best_model_name]['model']
print(f"\n最佳模型: {best_model_name}")
print(f"测试集 R²: {results[best_model_name]['test_r2']:.4f}")

# ==================== 6. 可视化预测结果 ====================
print("\n" + "="*50)
print("6. 可视化预测结果 (使用最佳模型)")
print("="*50)

# 使用最佳模型进行预测
y_pred = best_model.predict(X_test_scaled)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# 散点图:真实值 vs 预测值
ax1 = axes[0]
ax1.scatter(y_test, y_pred, alpha=0.5, s=20)
ax1.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 
         'r--', lw=2, label='理想预测线')
ax1.set_xlabel('真实房价 (10万美元)')
ax1.set_ylabel('预测房价 (10万美元)')
ax1.set_title(f'{best_model_name} - 真实值 vs 预测值\nR² = {results[best_model_name]["test_r2"]:.4f}')
ax1.legend()
ax1.grid(True, alpha=0.3)

# 残差图
ax2 = axes[1]
residuals = y_test - y_pred
ax2.scatter(y_pred, residuals, alpha=0.5, s=20)
ax2.axhline(y=0, color='r', linestyle='--', lw=2)
ax2.set_xlabel('预测房价 (10万美元)')
ax2.set_ylabel('残差 (真实值 - 预测值)')
ax2.set_title('残差图')
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('prediction_results.png', dpi=300, bbox_inches='tight')
plt.show()

# ==================== 7. 特征重要性 (随机森林) ====================
if best_model_name == '随机森林回归':
    print("\n" + "="*50)
    print("7. 特征重要性分析")
    print("="*50)
    
    feature_importance = pd.DataFrame({
        '特征': X.columns,
        '重要性': best_model.feature_importances_
    }).sort_values('重要性', ascending=False)
    
    print("\n特征重要性排序:")
    print(feature_importance)
    
    # 可视化特征重要性
    plt.figure(figsize=(10, 6))
    plt.barh(feature_importance['特征'], feature_importance['重要性'])
    plt.xlabel('重要性')
    plt.ylabel('特征')
    plt.title('随机森林 - 特征重要性')
    plt.gca().invert_yaxis()
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.savefig('feature_importance.png', dpi=300, bbox_inches='tight')
    plt.show()

# ==================== 8. 预测单个样本 ====================
print("\n" + "="*50)
print("8. 预测演示 - 单个样本预测")
print("="*50)

# 取第一个测试样本
sample_idx = 0
sample = X_test.iloc[[sample_idx]]
sample_scaled = scaler.transform(sample)

# 预测
predicted_price = best_model.predict(sample_scaled)[0]
actual_price = y_test.iloc[sample_idx]

print(f"\n测试样本 {sample_idx+1}:")
print(f"特征值:")
for i, feature in enumerate(X.columns):
    print(f"  {feature}: {sample.iloc[0, i]:.4f}")
print(f"\n真实房价: ${actual_price * 100000:.2f}")
print(f"预测房价: ${predicted_price * 100000:.2f}")
print(f"误差: ${abs(actual_price - predicted_price) * 100000:.2f}")

print("\n" + "="*50)
print("房价预测示例完成!")
print("="*50)

运行结果:

复制代码
==================================================
1. 加载加利福尼亚房价数据
==================================================
样本数量: 20640
特征数量: 8

特征名称: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']

==================================================
4. 训练多个模型进行对比
==================================================

训练 线性回归...
  训练集 RMSE: 0.7276 (单位: 10万美元)
  测试集 RMSE: 0.7269 (单位: 10万美元)
  训练集 R²: 0.6089
  测试集 R²: 0.6073

训练 随机森林回归...
  训练集 RMSE: 0.3864 (单位: 10万美元)
  测试集 RMSE: 0.5067 (单位: 10万美元)
  训练集 R²: 0.8897
  测试集 R²: 0.8092
相关推荐
先跑起来再说25 分钟前
Qavor:一个能跑、能观测、能扩展的开源 AI Agent 工作台
人工智能·开源
Mr数据杨30 分钟前
从文本特征到回归建模 Syllable Counting Model 实战解析
人工智能·数据分析·kaggle竞赛
HIT_Weston30 分钟前
201、【Agent】【OpenCode】JS 语法:setTimeout 七种常用形式
人工智能·agent·opencode
维基框架36 分钟前
萨尔瓦多学校免费上Grok 没账单的AI怎么限流
人工智能
敢敢是只喵i37 分钟前
给现有业务系统接 AI 助手,入口怎么选?网页聊天、自动化任务与本地 Agent 对比
运维·人工智能·ai·开源·自动化·安全架构
AI行业说38 分钟前
誉财自动化YC-18-M8045实测:服装自动化vs人工缝制产能成本对比
大数据·人工智能·自动化·智能模板机
朦胧之1 小时前
PostgreSQL 数据库笔记
人工智能·后端
hiahiahia1231 小时前
Cookie、Session、Token 到底有什么区别?
人工智能
林伽一1 小时前
林伽一 · AI科技研报 | 2026年08月第4周
人工智能·科技