学习日记 7.28
在机器学习的学习之路上线性回归和逻辑回归是两块重要的基石。今天我们将通过两个实战案例从理论到代码全面掌握这两种算法的应用案例一多元线性回归—— 根据体重和年龄预测血压收缩压案例二逻辑回归—— 信用卡欺诈交易检测Kaggle 经典数据集。一、多元线性回归1.1 什么是多元线性回归简单线性回归使用一个自变量来预测因变量而多元线性回归则使用两个或以上的自变量。其数学表达式为y β₀ β₁x₁ β₂x₂ ... βₙxₙ ε其中y是目标变量因变量x₁, x₂, ..., xₙ是特征自变量β₀是截距β₁, β₂, ..., βₙ是回归系数ε是误差项。1.2 实战血压预测数据集我们使用的数据集包含三个字段体重、年龄、血压收缩共 14 条记录。体重(kg)年龄(岁)血压收缩(mmHg)76.05012091.52014185.52012482.53012679.030117.........完整代码import pandas as pd from sklearn.linear_model import LinearRegression 1. 读取数据 data pd.read_csv(多元线性回归.csv, encodinggbk, enginepython) 2. 查看相关性 —— 了解各特征与目标变量之间的关系 corr data[[体重, 年龄, 血压收缩]].corr() print( 相关性矩阵 ) print(corr) 3. 创建模型 lr_model LinearRegression() 4. 准备特征和目标变量 x data[[体重, 年龄]] # 特征矩阵 y data[血压收缩] # 目标变量 5. 训练模型 lr_model.fit(x, y) 6. 模型评估 —— R² 分数 score lr_model.score(x, y) print(f\n模型 R² 分数: {score}) 7. 查看模型参数 print(f\n回归系数: {lr_model.coef_}) print(f截距: {lr_model.intercept_:.2f})运行结果 相关性矩阵 体重 年龄 血压收缩 体重 1.000000 -0.700283 0.906402 年龄 -0.700283 1.000000 -0.382773 血压收缩 0.906402 -0.382773 1.000000 模型 R² 分数: 0.9461441227520285结果深度解读1. 相关性矩阵分析体重 年龄 血压收缩 体重 1.000000 -0.700283 0.906402 年龄 -0.700283 1.000000 -0.382773 血压收缩 0.906402 -0.382773 1.000000从相关性矩阵中可以得出以下结论关系相关系数解读体重 ↔ 血压收缩0.906强正相关—— 体重越大收缩压越高。这是影响血压的最主要因素年龄 ↔ 血压收缩-0.383弱负相关—— 在这组数据中年龄与血压呈现轻微负相关体重 ↔ 年龄-0.700中等负相关—— 数据中体重和年龄存在一定的负相关关系关键发现体重的相关系数高达 0.906说明体重是影响收缩压的核心因素。而年龄在本数据集中与收缩压呈弱负相关-0.383这可能与样本特性有关。2. R² 分数分析模型 R² 分数为0.9461这意味着模型能够解释94.61%的血压收缩压变化。拟合效果非常好说明体重和年龄这两个特征对血压有很强的解释力。不过需要注意这里 R² 是在训练集上计算的没有做训练集/测试集划分14 条数据太少。在实际项目中应该划分数据集并用测试集来评估避免过拟合。二、逻辑回归 —— 信用卡欺诈检测2.1 什么是逻辑回归尽管名字里有回归但逻辑回归是一种分类算法。它通过 Sigmoid 函数将线性回归的输出映射到 [0, 1] 区间从而得到属于某个类别的概率P(y1|x) 1 / (1 e^-(β₀ β₁x₁ ... βₙxₙ))对于二分类问题通常设定阈值为 0.5概率 ≥ 0.5 → 正类1欺诈交易概率 0.5 → 负类0正常交易。2.2 数据集介绍本案例使用的是Kaggle 信用卡欺诈检测数据集包含约 28.5 万条交易记录。字段说明Time交易时间秒V1 ~ V28PCA 降维后的特征脱敏处理Amount交易金额Class标签0 正常交易1 欺诈交易2.3 完整代码详解Step 1读取数据并查看基本信息import pandas as pd data pd.read_csv(r./creditcard.csv) print(data.head())输出结果前 5 行Time V1 V2 V3 V4 V5 ... V27 V28 Amount Class 0 0.0 -1.359807 -0.072781 2.536347 1.378155 -0.338321 ... 0.133558 -0.021053 149.62 0 1 0.0 1.191857 0.266151 0.166480 0.448154 0.060018 ... -0.008983 0.014724 2.69 0 2 1.0 -1.358354 -1.340163 1.773209 0.379780 -0.503198 ... -0.055353 -0.059752 378.66 0 3 1.0 -0.966272 -0.185226 1.792993 -0.863291 -0.010309 ... 0.062723 0.061458 123.50 0 4 2.0 -1.158233 0.877737 1.548718 0.403034 -0.407193 ... 0.219422 0.215153 69.99 0 [5 rows x 31 columns]数据共有 31 列包含 28 个 PCA 特征V1~V28、Time、Amount 和 Class 标签。可以看到 Amount 列的数值149.62, 2.69, 378.66...差异很大后面需要进行标准化处理。Step 2数据预处理 —— Z-score 标准化from sklearn.preprocessing import StandardScaler scaler StandardScaler() data[Amount] scaler.fit_transform(data[[Amount]]) data data.drop([Time], axis1)为什么要对 Amount 做标准化Amount列的数值范围0 ~ 25691远大于 V1~V28经过 PCA 后基本在 [-5, 5] 范围内。如果不进行标准化模型会错误地认为 Amount 比其他特征重要得多从而影响模型效果。Z-score 标准化公式zᵢⱼ (xᵢⱼ - x̄ᵢ) / sᵢx̄ᵢ该特征的均值数学期望sᵢ该特征的标准差标准化后数据均值为 0标准差为 1。这里我们把Time列删除了 —— 交易发生的绝对时间与欺诈行为之间通常没有直接的线性关系保留它反而可能引入噪声。Step 3数据可视化 —— 查看正负样本分布import matplotlib.pyplot as plt from pylab import mpl 解决中文显示问题 mpl.rcParams[font.sans-serif] [Microsoft YaHei] mpl.rcParams[axes.unicode_minus] False 统计类别数量并绘图 labels_count data[Class].value_counts() print(labels_count) plt.title(正负样本分布) plt.xlabel(类别) plt.ylabel(频数) labels_count.plot(kindbar) plt.show()输出结果Class 0 284315 1 492 Name: count, dtype: int64这个结果非常震撼类别数量占比正常交易0284,31599.83%欺诈交易14920.17%关键发现正常交易和欺诈交易的比例约为578:1这意味着每 579 笔交易中才可能出现 1 笔欺诈交易 —— 这是一个极度不平衡的数据集。Step 4划分训练集和测试集from sklearn.model_selection import train_test_split X_model data.drop([Class], axis1) # 特征矩阵29列 y_model data.Class # 标签列 X_train_w, X_test_w, y_train_w, y_test_w train_test_split( X_model, y_model, test_size0.3, # 30% 作为测试集 random_state1000 # 随机种子保证结果可复现 )train_test_split 参数说明参数含义test_size0.330% 的数据划分为测试集70% 为训练集random_state1000固定随机种子确保每次运行得到相同的划分结果Step 5训练逻辑回归模型from sklearn.linear_model import LogisticRegression C 是正则化强度的倒数C 越小正则化越强模型越简单 lr LogisticRegression(C0.01) lr.fit(X_train_w, y_train_w)关于参数 C 的深入理解C是正则化强度的倒数。C 0.01正则化非常强 → 防止模型过拟合。逻辑回归默认使用L2 正则化岭回归。这里选较小的 C 值是因为数据极度不平衡需要用强正则化来约束模型。Step 6模型评估test_predicted lr.predict(X_test_w) # 对测试集进行预测 result lr.score(X_test_w, y_test_w) # 计算准确率 print(f模型准确率: {result})输出结果模型准确率: 0.9990168884519505运行结果深度解读准确率高达99.90%这看起来非常优秀但这里有一个重要陷阱准确率 99.90% 并不意味着模型真的很好还记得我们之前统计的类别分布吗欺诈交易只占 0.17%。如果我们写一个傻瓜模型——把所有交易都预测为正常交易# 傻瓜策略全部预测为 0 dummy_accuracy (y_test_w 0).sum() / len(y_test_w) print(f全部预测为正常的准确率: {dummy_accuracy}) # 输出约: 0.9983 (99.83%)这个什么都不做的策略也能达到99.83%的准确率所以核心结论在不平衡数据集中准确率Accuracy不是一个可靠的评估指标。我们需要关注的是精确率Precision被预测为欺诈的交易中有多少是真正的欺诈召回率Recall真正的欺诈交易中有多少被模型检测出来了F1 分数精确率和召回率的调和平均。AUC-ROC模型区分正负样本的能力。三、线性回归 vs 逻辑回归对比总结对比维度线性回归逻辑回归任务类型回归预测连续值分类预测离散类别输出范围(-∞, ∞)[0, 1]概率值损失函数均方误差MSE交叉熵损失Log Loss激活函数无线性输出Sigmoid 函数评估指标R², MAE, MSE, RMSE精确率、召回率、F1、AUC-ROC典型应用房价预测、气温预测垃圾邮件检测、欺诈检测、疾病诊断四、实战经验总结4.1 两个案例的对比启示维度案例一线性回归案例二逻辑回归数据量14 条小样本28.5 万条大数据特征数2 个29 个核心挑战样本太少容易过拟合样本极度不平衡R²/准确率0.9461优秀0.9990看似优秀实则存疑可信度需更多数据验证不能只看准确率4.2 关键R² 0.9461 说明什么体重和年龄共同解释了 94.61% 的血压变异。但 14 条数据太少模型可能过拟合需要更多样本验证。准确率 99.90% 说明什么单独看模型表现极好。结合类别分布看几乎所有样本都是负类全部预测为 0也有 99.83%。真相模型的提升仅为 0.07%这点提升来自正确识别了极少数的欺诈交易。数据预处理的重要性Amount 标准化消除量纲差异避免大数值特征主导模型Time 删除去除与目标变量无关的特征减少噪声相关性分析中体重与血压的相关性0.906远超年龄-0.383。五、进阶建议针对信用卡欺诈检测案例可以从以下方向继续优化处理样本不平衡设置class_weightbalanced让模型自动按类别频率调整权重或用 SMOTE 过采样random_state42固定随机种子保证结果可复现。更全面的模型评估不平衡数据中准确率不可靠应关注精确率、召回率、F1 和 AUC用classification_report和roc_auc_score全面评估。