• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

上采样和下采样

武飞扬头像
Yore_999
帮助1

首先,谈谈不平衡数据集。不平衡数据集指的是训练数据中不同类别的样本数量差别较大的情况。在这种情况下,模型容易出现偏差,导致模型对数量较少的类别预测效果不佳。

为了解决这个问题,可以使用上采样和下采样等方法来调整数据集的平衡性,除此之外也有一些数据增强的方法。

上采样(Oversampling)和下采样(Undersampling)都是数据预处理技术,用于处理不平衡数据集的问题。

上采样:增加数量较少的类别的样本数量,使得数据集中各个类别的样本数量相等或接近。

        常见:随机上采样、SMOTE(Synthetic Minority Over-sampling Technique)等。

        优点:不会丢失信息,

        缺点:可能会导致过拟合和噪声数据的引入。

下采样:减少数据集中数量较多的类别的样本数量,使得数据集中各个类别的样本数量相等或接近。

        常见:随机下采样、聚类下采样等。

        优点:可以快速处理大型不平衡数据集

        缺点:可能会导致数据量减少,可能会损失一些重要的信息。

代码示例:

  1.  
    '''
  2.  
    随机上采样(Random Oversampling)
  3.  
    随机上采样是指对少数类样本进行复制,使得样本数量与多数类样本数量相等。
  4.  
    下面是使用Python的imbalanced-learn库进行随机上采样的示例代码:
  5.  
    X和y分别表示原始的特征矩阵和标签向量,fit_resample()方法将进行随机上采样操作。
  6.  
    '''
  7.  
    from imblearn.over_sampling import RandomOverSampler
  8.  
     
  9.  
    ros = RandomOverSampler(random_state=42)
  10.  
    X_resampled, y_resampled = ros.fit_resample(X, y)
  1.  
    '''
  2.  
    SMOTE是一种通过插值的方式来合成新的少数类样本的方法。
  3.  
    它的基本思想是对每个少数类样本进行分析,找到它最近的k个少数类样本,然后在这些样本中随机选择一个样本,以该样本为基础生成新的少数类样本。
  4.  
    下面是使用Python的imbalanced-learn库进行SMOTE的示例代码:
  5.  
    X和y分别表示原始的特征矩阵和标签向量,fit_resample()方法将进行SMOTE操作。
  6.  
     
  7.  
    '''
  8.  
    from imblearn.over_sampling import SMOTE
  9.  
     
  10.  
    smote = SMOTE(random_state=42)
  11.  
    X_resampled, y_resampled = smote.fit_resample(X, y)
  1.  
    '''
  2.  
    随机下采样(Random Undersampling)
  3.  
    随机下采样是指从多数类样本中随机选择样本,使得样本数量与少数类样本数量相等。
  4.  
    下面是使用Python的imbalanced-learn库进行随机下采样的示例代码:
  5.  
    X和y分别表示原始的特征矩阵和标签向量,fit_resample()方法将进行随机下采样操作。
  6.  
    '''
  7.  
    from imblearn.under_sampling import RandomUnderSampler
  8.  
     
  9.  
    rus = RandomUnderSampler(random_state=42)
  10.  
    X_resampled, y_resampled = rus.fit_resample(X, y)
  1.  
    '''
  2.  
    聚类下采样(Cluster Centroids Undersampling)
  3.  
    聚类下采样是指对多数类样本进行聚类,然后选择每个聚类的中心点作为新的样本。
  4.  
    下面是使用Python的imbalanced-learn库进行聚类下采样的示例代码:
  5.  
    X和y分别表示原始的特征矩阵和标签向量,fit_resample()方法将进行聚类下采样操作。
  6.  
    '''
  7.  
    from imblearn.under_sampling import ClusterCentroids
  8.  
     
  9.  
    cc = ClusterCentroids(random_state=42)
  10.  
    X_resampled, y_resampled = cc.fit_resample(X, y)

关于SMOTE(Synthetic Minority Over-sampling Technique),这种基于插值实现的上采样方法,很有意思,手动尝试实现一下:

方法思路:

  1. 对于每一个少数类样本,选择它最近的k个少数类样本,并计算它们之间的距离。

  2. 对于每一个选定的少数类样本,从它的k个最近的少数类样本中随机选择一个样本,以该样本为基础生成新的少数类样本。具体而言,对于第i个少数类样本,选择第j个最近的少数类样本作为基础样本,然后在i和j之间进行插值,生成一个新的样本。插值的具体方式可以是在i和j之间进行线性插值或多项式插值。

  3. 将新的样本添加到原始数据集中,形成新的数据集。

手动实现::

  1. 对于每一个少数类样本,计算它与所有少数类样本之间的距离,找到最近的k个少数类样本。

  2. 对于每一个选定的少数类样本,从它的k个最近的少数类样本中随机选择一个样本,以该样本为基础生成新的少数类样本。

  3. 将新的样本添加到原始数据集中,形成新的数据集。

  1.  
    import numpy as np
  2.  
    from sklearn.neighbors import NearestNeighbors
  3.  
     
  4.  
    def SMOTE(X, y, k, ratio=1.0):
  5.  
    """
  6.  
    X: shape例如[n_samples, n_features]
  7.  
    Training data
  8.  
    y: shape例如[n_samples]
  9.  
    Target values
  10.  
    k: int
  11.  
    最近邻居的数量
  12.  
    ratio: float, 可选,默认1.0
  13.  
    合成样本数与原始样本数之比
  14.  
    """
  15.  
    n_samples, n_features = X.shape
  16.  
    n_syn = int(ratio * n_samples)
  17.  
    n_classes = len(np.unique(y))
  18.  
     
  19.  
    if n_syn <= 0:
  20.  
    return X, y
  21.  
     
  22.  
    X_syn = np.zeros((n_syn, n_features))
  23.  
    y_syn = np.zeros(n_syn, dtype=np.int)
  24.  
     
  25.  
    # 对于每一个选定的少数类样本,从它的k个最近的少数类样本中随机选择一个样本,以该样本为基础生成新的少数类样本。
  26.  
    #knn 对象是使用 sklearn.neighbors 库中的 NearestNeighbors 类创建的,其中 n_neighbors=k 1 表示要找到每个样本的 k 个近邻样本
  27.  
    knn = NearestNeighbors(n_neighbors=k 1, algorithm='auto', n_jobs=-1)
  28.  
    knn.fit(X)
  29.  
    indices = np.arange(n_samples)
  30.  
     
  31.  
    for i, x in enumerate(X):
  32.  
    # return_distance=False 表示只返回近邻样本的索引。使用 [:, 1:] 切片操作是为了去掉每个样本本身,只保留它的近邻样本的索引。
  33.  
    nn = knn.kneighbors([x], return_distance=False)[:, 1:]
  34.  
    for j in range(int(ratio)):
  35.  
    # 从 nn 数组中随机选择一个元素,也就是随机选择一个近邻样本的索引。这里的 nn 是一个形状为 (1, k) 的二维数组,表示 x 的 k 个近邻样本的索引。由于 choice() 方法只能对一维数组进行操作,因此需要使用 nn[0] 获取其中的一维数组。
  36.  
    # 选择一个随机的近邻样本索引是为了在原始样本和其近邻之间生成新的样本,从而增加训练数据的样本数量,同时减少训练数据的不平衡性。
  37.  
    # 假设 nn 的值为 np.array([[1, 3, 5]]),则 nn[0] 返回的是一个包含 1、3 和 5 的一维数组,即 [1, 3, 5]。然后,np.random.choice(nn[0]) 方法从中随机选择一个元素,比如选择了 3,就表示选择了 x 的第 3 个近邻样本。
  38.  
    nn_idx = np.random.choice(nn[0])
  39.  
    diff = X[nn_idx] - x
  40.  
    gap = np.random.random()
  41.  
    X_syn[i*int(ratio) j] = x gap * diff
  42.  
    y_syn[i*int(ratio) j] = y
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiabkji
系列文章
更多 icon
同类精品
更多 icon
继续加载