当前位置: 首页 > news >正文

机器学习——模型的简单优化

在训练模型时我们可能会遇到模型不满足于预期需要进行改善的环节,这些情况通常包括以下几种常见问题和对应的解决方案:

数据质量不足

  • 数据量过少:当训练样本不足时,模型难以学习到有效的特征表示。建议通过数据增强(如图像旋转、加噪等)或收集更多数据来解决
  • 数据不平衡:某些类别样本远多于其他类别时,可以采用过采样(如SMOTE)、欠采样或类别加权等方法
  • 数据质量问题:需要检查并处理缺失值、异常值和标注错误

模型欠拟合

  • 表现为训练集和验证集上表现都不佳
  • 可能原因:模型结构过于简单、特征工程不足或正则化过度
  • 解决方案:增加模型复杂度、优化特征选择、减少正则化强度模型过拟合

模型过拟合

  • 表现为训练集表现很好但验证集表现差
  • 可能原因:模型过于复杂、训练数据不足或训练轮次过多
  • 解决方案:增加dropout层、使用早停(early stopping)、添加L1/L2正则化、数据增强

一、数据集改善

1、数据集拆分

1. 核心功能​

train_test_split是 scikit-learn 中用于将数据集随机划分为训练集和测试集的函数,主要作用包括:

  • ​防止过拟合​​:通过分离训练和测试数据,评估模型在未见数据上的泛化能力。

  • ​灵活划分比例​​:支持自定义测试集或训练集的比例(如 80% 训练 + 20% 测试)。

  • ​分层抽样​​:处理类别不均衡数据时,保持训练集和测试集的类别分布一致。


​2. 参数详解​

​参数​

​说明​

​示例值​

*arrays

待划分的数据(如特征 X和标签 y),支持多个数组同时划分

X, y

test_size

测试集比例(0.0-1.0)或样本数。默认 0.25

0.2(20% 测试集)

train_size

训练集比例,若未设置则自动补全 1 - test_size

0.8(80% 训练集)

random_state

随机种子,保证划分结果可复现

42

shuffle

是否打乱数据(默认 True),时间序列数据需设为 False

True

stratify

按标签分层抽样,保持类别比例一致

y(标签数组)

3.示例

from sklearn.model_selection import train_test_split
import numpy as npX = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
y = np.array([0, 1, 0, 1])# 80% 训练集,20% 测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("训练集:", X_train)  # 输出示例:[[3 4], [1 2], [7 8]]
print("测试集:", X_test)   # 输出示例:[[5 6]][1,5]

2.样本归一化

样本归一化是指对数据集中的​​每个样本(行)​​进行缩放,使其满足特定范数(如L1、L2或最大值范数),从而消除样本间量纲差异。与特征归一化(按列处理)不同,样本归一化适用于样本向量需整体比较的场景,如文本分类、聚类分析等。

​1.核心公式​

  • ​L2归一化(默认)​​:

    使每个样本的欧几里得范数为1。

  • ​L1归一化​​:

    使样本的绝对值和为1。

  • ​最大值归一化(Max)​​:

    将样本最大值缩放到1。


​2. 适用场景​

  1. ​文本数据处理​

    如TF-IDF向量或词频向量,归一化后可比性更强。
  2. ​基于距离的算法​

    KNN、SVM等需计算样本间距离的模型,归一化避免大数值特征主导结果。
  3. ​神经网络输入​

    归一化到统一范围(如[0,1])可加速梯度下降收敛。
  4. ​图像处理​

    像素值归一化后更适应卷积神经网络的输入要求。

​3. 方法对比与选择​

​方法​

​特点​

​适用场景​

​L2归一化​

保留样本向量的方向信息,对异常值敏感度较低

文本分类、聚类分析

​L1归一化​

生成稀疏解,适合特征选择

高维稀疏数据(如词袋模型)

​Max归一化​

快速缩放至[-1,1],但对极端值敏感

图像像素值处理

​注意事项​​:

  • 若样本中存在异常值,建议使用L2归一化或RobustScaler(基于中位数和四分位数)。

  • 归一化会改变原始数据分布,但保留相对大小关系

 代码实现(Python)

使用Scikit-learn的Normalizer​

from sklearn.preprocessing import Normalizer
import numpy as np# 示例数据(每行一个样本)
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# L2归一化(默认)
normalizer = Normalizer(norm='l2')
X_l2 = normalizer.fit_transform(X)
print("L2归一化结果:\n", X_l2)#[0.267, 0.534, 0.801]# L1归一化
normalizer = Normalizer(norm='l1')
X_l1 = normalizer.fit_transform(X)
print("L1归一化结果:\n", X_l1)

​3.样本标准化

样本标准化(也称为数据标准化或特征缩放)是将不同尺度的数据转换为统一尺度的过程,使不同特征具有可比性。

常见的标准化方法

  1. ​Z-score标准化(标准差标准化)​

    • 公式:z = (x - μ) / σ

    • 其中μ是均值,σ是标准差

    • 处理后数据均值为0,标准差为1

  2. ​Min-Max标准化​

    • 公式:x' = (x - min) / (max - min)

    • 将数据线性变换到[0,1]区间

  3. ​Max标准化​

    • 公式:x' = x / max

    • 将数据按最大值缩放

  4. ​小数缩放​

    • 公式:x' = x / 10^j

    • j为使最大绝对值小于1的最小整数

标准化的作用

  • 消除不同特征间的量纲影响

  • 提高模型收敛速度(特别是梯度下降算法)

  • 提高模型精度

  • 使不同特征对模型有相近的贡献度

应用场景

  • 基于距离的算法(如KNN、K-means)

  • 使用梯度下降的模型(如神经网络)

  • 主成分分析(PCA)等降维方法

  • 正则化模型(如Lasso、Ridge回归)

Z-score标准化

import numpy as np
from sklearn.preprocessing import StandardScaler# 原始数据
data = np.array([[1, 2], [3, 4], [5, 6]])# 使用sklearn
scaler = StandardScaler()
scaled_data = scaler.fit_transform(data)
print("Z-score标准化结果:\n", scaled_data)# 手动计算
mean = np.mean(data, axis=0)
std = np.std(data, axis=0)
manual_scaled = (data - mean) / std
print("手动计算结果:\n", manual_scaled)

 Min-Max标准化

from sklearn.preprocessing import MinMaxScaler# 使用sklearn
minmax_scaler = MinMaxScaler()
minmax_scaled = minmax_scaler.fit_transform(data)
print("Min-Max标准化结果:\n", minmax_scaled)# 手动计算
data_min = np.min(data, axis=0)
data_max = np.max(data, axis=0)
manual_minmax = (data - data_min) / (data_max - data_min)
print("手动计算结果:\n", manual_minmax)

4.上采样和下采样

上采样和下采样是处理数据不平衡问题的两种常用技术,主要用于解决分类任务中类别分布不均的情况。

下采样(Downsampling)

基本概念

  • 也称为欠采样(Undersampling)

  • 减少多数类样本数量,使其与少数类样本数量接近或相同

  • 适用于多数类样本数量远大于少数类的情况

常用方法

  1. ​随机下采样​

    • 从多数类中随机删除样本

    from sklearn.utils import resample# 假设df是DataFrame,'class'是目标列
    majority_class = df[df['class'] == 0]
    minority_class = df[df['class'] == 1]# 随机下采样多数类
    majority_downsampled = resample(majority_class,replace=False,n_samples=len(minority_class),random_state=42)# 合并下采样后的数据
    df_downsampled = pd.concat([majority_downsampled, minority_class])
    
  2. ​Tomek Links​

    • 移除边界附近造成分类困难的多数类样本

    from imblearn.under_sampling import TomekLinkstl = TomekLinks()
    X_res, y_res = tl.fit_resample(X, y)
  3. ​Cluster Centroids​

    • 使用聚类方法减少多数类样本

from imblearn.under_sampling import ClusterCentroidscc = ClusterCentroids(random_state=42)
X_res, y_res = cc.fit_resample(X, y)

优缺点

​优点​​:

  • 减少训练数据量,加快训练速度

  • 解决类别不平衡问题

​缺点​​:

  • 可能丢失重要信息

  • 可能导致模型欠拟合

上采样(Upsampling)

基本概念

  • 也称为过采样(Oversampling)

  • 增加少数类样本数量,使其与多数类样本数量接近或相同

  • 适用于少数类样本数量不足的情况

常用方法

  1. ​随机上采样​

    • 随机复制少数类样本

from sklearn.utils import resampleminority_upsampled = resample(minority_class,replace=True,n_samples=len(majority_class),random_state=42)df_upsampled = pd.concat([majority_class, minority_upsampled])
  1. ​SMOTE(Synthetic Minority Oversampling Technique)​

    • 合成新的少数类样本

from imblearn.over_sampling import SMOTEsmote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)
  1. ​ADASYN(Adaptive Synthetic Sampling)​

    • 基于数据分布的自适应上采样

from imblearn.over_sampling import ADASYNadasyn = ADASYN(random_state=42)
X_res, y_res = adasyn.fit_resample(X, y)

优缺点

​优点​​:

  • 不丢失原始信息

  • 可以改善模型对少数类的识别能力

​缺点​​:

  • 可能导致过拟合

  • 增加计算负担

二、交叉验证

交叉验证是评估机器学习模型性能和选择超参数的重要技术,它通过将数据集分成多个子集来减少评估结果的方差。

常见交叉验证方法

1. K折交叉验证(K-Fold CV)

​原理​​:将数据集随机分成K个大小相似的互斥子集(称为"折"),每次用K-1折训练,剩下1折验证,重复K次。

from sklearn.model_selection import KFold, cross_val_score
from sklearn.linear_model import LogisticRegressionkfold = KFold(n_splits=5, shuffle=True, random_state=42)
model = LogisticRegression()
scores = cross_val_score(model, X, y, cv=kfold)
print("平均准确率:", scores.mean())

2. 分层K折交叉验证(Stratified K-Fold)

​特点​​:保持每个折中类别比例与原始数据集一致,适用于分类问题,特别是类别不平衡时。

from sklearn.model_selection import StratifiedKFoldskf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=skf)

3. 留一法交叉验证(Leave-One-Out, LOO)

​原理​​:每次留一个样本作为验证集,其余作为训练集,重复N次(N为样本数)。

from sklearn.model_selection import LeaveOneOutloo = LeaveOneOut()
scores = cross_val_score(model, X, y, cv=loo)
print("LOO平均准确率:", scores.mean())

4. 留P法交叉验证(Leave-P-Out)

​原理​​:每次留P个样本作为验证集。

from sklearn.model_selection import LeavePOutlpo = LeavePOut(p=2)
scores = cross_val_score(model, X, y, cv=lpo)  # 注意:计算量很大

5. 时间序列交叉验证(Time Series CV)

​特点​​:考虑数据的时间顺序,防止未来信息泄露。

from sklearn.model_selection import TimeSeriesSplittscv = TimeSeriesSplit(n_splits=5)
for train_index, test_index in tscv.split(X):X_train, X_test = X[train_index], X[test_index]y_train, y_test = y[train_index], y[test_index]

交叉验证的最佳实践

  1. ​数据预处理​​:应在交叉验证循环内进行,防止数据泄露

    from sklearn.pipeline import make_pipeline
    from sklearn.preprocessing import StandardScalerpipeline = make_pipeline(StandardScaler(), LogisticRegression())
    scores = cross_val_score(pipeline, X, y, cv=5)
  2. ​类别不平衡处理​​:使用分层抽样或自定义采样策略

    from sklearn.model_selection import StratifiedKFoldskf = StratifiedKFold(n_splits=5)
  3. ​随机性控制​​:设置random_state确保结果可复现

  4. ​折数选择​​:

    • 小数据集:5-10折

    • 大数据集:3-5折(减少计算量)

    • 超参数调优:可使用更多折数

  5. ​性能指标选择​​:根据问题类型选择合适的评估指标

    from sklearn.metrics import make_scorer, f1_scorescorer = make_scorer(f1_score, average='macro')
    scores = cross_val_score(model, X, y, cv=5, scoring=scorer)

交叉验证的局限性

  1. 计算成本高,特别是大数据集或复杂模型

  2. 对数据顺序敏感的数据集(如时间序列)需要特殊处理

  3. 极端不平衡数据可能需要分层抽样或其他采样技术

交叉验证是机器学习工作流中不可或缺的部分,合理使用可以有效评估模型泛化能力并防止过拟合。

三、数据结果

混淆矩阵

混淆矩阵是评估分类模型性能的重要工具,它以矩阵形式直观展示模型的预测结果与真实标签的对比情况。

基本结构

对于二分类问题,混淆矩阵为2×2矩阵:

  • ​TP(True Positive)​​:真正例,实际为阳性且预测为阳性

  • ​FN(False Negative)​​:假反例,实际为阳性但预测为阴性

  • ​FP(False Positive)​​:假正例,实际为阴性但预测为阳性

  • ​TN(True Negative)​​:真反例,实际为阴性且预测为阴性

#Python实现
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns# 示例数据
y_true = [1, 0, 1, 1, 0, 1, 0, 0]
y_pred = [1, 0, 0, 1, 0, 1, 1, 0]# 计算混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print("混淆矩阵:\n", cm)# 可视化
plt.figure(figsize=(6, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['预测阴性', '预测阳性'],yticklabels=['真实阴性', '真实阳性'])
plt.xlabel('预测值')
plt.ylabel('真实值')
plt.title('混淆矩阵')
plt.show()

分类指标

指标

公式

侧重

适用场景

sklearn函数

准确率

(TP+TN)/Total

整体正确率

平衡数据集

accuracy_score

精确率

TP/(TP+FP)

预测阳性准确度

FP代价高

precision_score

召回率

TP/(TP+FN)

阳性样本识别率

FN代价高

recall_score

F1分数

2(PR)/(P+R)

精确率召回率平衡

不平衡数据

f1_score

AUC

ROC曲线下面积

整体区分能力

阈值无关评估

roc_auc_score

http://www.dtcms.com/a/323158.html

相关文章:

  • CPU缓存(CPU Cache)和TLB(Translation Lookaside Buffer)缓存现代计算机体系结构中用于提高性能的关键技术
  • 盟接之桥说制造:以品质为基,消费者导向差异而生
  • Linux系统编程Day10 -- 进程管理
  • CTF常用工具汇总(二)
  • 【32】C#实战篇——两个文件夹下 相同名字的文件 进行配对(两个文件夹下的文件数量和文件类型不一定相同,所以要过滤掉我们不要的文件)
  • ArkUI中的布局组件Row(一)
  • 计算机网络1-6:计算机网络体系结构
  • 【Python 高频 API 速学 ④】
  • Office安装使用?借助Ohook开源工具?【图文详解】微软Office产品
  • 使用 Conda 安装 xinference[all](详细版)
  • 一个“加锁无效“的诡异现象
  • Java 日志从入门到精通:告别日志混乱
  • C++高性能细粒度时间跟踪实战
  • Python基础教程(五)list和tuple:深度剖析Python列表与元组的终极对决
  • PHP-单引号和双引号(通俗易懂讲解版)
  • 卫星遥感与AI大模型
  • JS逆向实战案例之----【通姆】252个webpack模块自吐
  • NFS 挂载失败** 问题(`mount: wrong fs type`),以下是详细的排查步骤和解决方案
  • 20250809在WIN10下使用diskpart命令格式化TF卡【卡刷荣品PRO-RK3566的核心板】
  • 云渲染的未来已来:渲酷云如何重新定义数字内容生产效率
  • SimBA算法实现过程
  • 39.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--调整发布脚本
  • 利用SymPy与SciPy高效求解参数化方程组的数值解
  • [激光原理与应用-207]:光学器件 - 光纤种子源激光器常用元器件
  • 9-DS18B20-verilog驱动
  • Zabbix自动注册:轻松实现大规模监控
  • [LLM 应用评估] 评估指标 | 评估协调器 | 测试集生成组件
  • 【MATLAB例程】基于UKF的IMM例程,模型使用CA(匀加速)和CT(协调转弯)双模型,二维环境下的轨迹定位。附代码下载链接
  • Python映射合并技术:多源数据集成的高级策略与工程实践
  • Python如何合并两个Excel文件