样本类别不平衡问题之SMOTE算法(Python imblearn极简实现)

类别不平衡问题

       类别不平衡问题,顾名思义,即数据集中存在某一类样本,其数量远多于或远少于其他类样本,从而导致一些机器学习模型失效的问题。例如逻辑回归即不适合处理类别不平衡问题,例如逻辑回归在欺诈检测问题中,因为绝大多数样本都为正常样本,欺诈样本很少,逻辑回归算法会倾向于把大多数样本判定为正常样本,这样能达到很高的准确率,但是达不到很高的召回率。

       类别不平衡问题在很多场景中存在,例如欺诈检测,风控识别,在这些样本中,黑样本(一般为存在问题的样本)的数量一般远少于白样本(正常样本)。

       上采样(过采样)和下采样(负采样)策略是解决类别不平衡问题的基本方法之一。上采样即增加少数类样本的数量,下采样即减少多数类样本以获取相对平衡的数据集。

       最简单的上采样方法可以直接将少数类样本复制几份后添加到样本集中,最简单的下采样则可以直接只取一定百分比的多数类样本作为训练集。

       SMOTE算法是用的比较多的一种上采样算法,SMOTE算法的原理并不是太复杂,用python从头实现也只有几十行代码,但是python的imblearn包提供了更方便的接口,在需要快速实现代码的时候可直接调用imblearn。

       imblearn类别不平衡包提供了上采样和下采样策略中的多种接口,基本调用方式一致,主要介绍一下对应的SMOTE方法和下采样中的RandomUnderSampler方法。imblearn可使用pip install imblearn直接安装。

生成类别不平衡数据

# 使用sklearn的make_classification生成不平衡数据样本
from sklearn.datasets import make_classification
# 生成一组0和1比例为9比1的样本,X为特征,y为对应的标签
X, y = make_classification(n_classes=2, class_sep=2,
                               weights=[0.9, 0.1], n_informative=3,
                               n_redundant=1, flip_y=0,
                               n_features=20, n_clusters_per_class=1,
                               n_samples=1000, random_state=10)

查看数据分布
 

from collections import Counter
# 查看所生成的样本类别分布,0和1样本比例9比1,属于类别不平衡数据
print(Counter(y))
# Counter({0: 900, 1: 100})

SMOTE算法核心语句(重要点)

# 使用imlbearn库中上采样方法中的SMOTE接口
from imblearn.over_sampling import SMOTE
# 定义SMOTE模型,random_state相当于随机数种子的作用
smo = SMOTE(random_state=42)
X = X.astype('float64')
X_smo, y_smo = smo.fit_sample(X, y)

查看经过SMOTE之后的数据分布
 

print(Counter(y_smo))
# Counter({0: 900, 1: 900})

       从上述代码中可以看出,SMOTE模型默认生成一比一的数据,如果想生成其他比例的数据,可以使用radio参数。不仅可以处理二分类问题,同样适用于多分类问题

# 可通过radio参数指定对应类别要生成的数据的数量
smo = SMOTE(ratio={1: 300 },random_state=42)
# 生成0和1比例为3比1的数据样本
X_smo, y_smo = smo.fit_sample(X, y)
print(Counter(y_smo))
# Counter({0: 900, 1: 300})

       imblearn中上采样接口提供了随机上采样RandomOverSampler,SMOTE,ADASYN三种方式,调用方式和主要参数基本一样。下采样接口中也提供了多种方法,以RandomUnderSampler为例。

from imblearn.under_sampling import RandomUnderSampler
# 同理,也可使用ratio来指定下采样的比例
rus = RandomUnderSampler(ratio={0: 500 }, random_state=0)
X_rus, y_rus = rus.fit_sample(X, y)
print(Counter(y_smo))
# Counter({0: 500, 1: 300})

SMOTE算法核心语句(重要点)部分  X = X.astype('float64')代码是我自己添加的,如果不加入这个在fit_sample会有类型不符合的报错。

来源:https://blog.csdn.net/nlpuser/article/details/81265614

参考:https://blog.csdn.net/qq_31813549/article/details/79964973

  • 12
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
SMOTE算法是一种用于解决数据不平衡问题算法,它通过对少数类样本进行合成来增加数据集的平衡性。下面是SMOTE算法Python实现: ```python import numpy as np from sklearn.neighbors import NearestNeighbors def SMOTE(T, N, k): """ T: 少数类样本集 N: 需要生成的新样本数目 k: 选取的最近邻个数 """ n_samples, n_features = T.shape if N < 100: print("Error: N must be larger than 100!") return None if (N % 100) != 0: print("Error: N must be a multiple of 100!") return None N = N // 100 # Step 1: 对少数类样本集进行k近邻搜索 neigh = NearestNeighbors(n_neighbors=k) neigh.fit(T) # Step 2: 对每个少数类样本进行N/k次合成 new_index = [] for i in range(n_samples): nn_array = neigh.kneighbors(T[i].reshape(1, -1), return_distance=False)[0] for j in range(N // k): nn = np.random.choice(nn_array) diff = T[nn] - T[i] gap = np.random.rand() new_sample = T[i] + gap * diff new_index.append(new_sample) new_samples = np.array(new_index) return new_samples ``` 使用示例: ```python from collections import Counter from sklearn.datasets import make_classification from matplotlib import pyplot as plt # 生成样本数据 X, y = make_classification(n_classes=3, class_sep=2, weights=[0.05, 0.25, 0.7], n_informative=3, n_redundant=1, flip_y=0, n_features=20, n_clusters_per_class=1, n_samples=1000, random_state=10) # 查看样本分布 print("Original dataset shape:", Counter(y)) # 进行SMOTE过采样 X_smote = SMOTE(X[y == 1], N=500, k=5) X_resampled = np.vstack((X[y == 0], X[y == 1], X_smote, X[y == 2])) y_resampled = np.hstack((y[y == 0], y[y == 1], np.ones(500, dtype=int) * 1, y[y == 2])) # 查看过采样后的样本分布 print("Resampled dataset shape:", Counter(y_resampled)) # 可视化样本分布 plt.figure(figsize=(10, 8)) plt.scatter(X_resampled[:, 0], X_resampled[:, 1], c=y_resampled) plt.show() ``` 在上面的示例中,我们生成了一个三分类不平衡样本数据集,然后使用SMOTE算法进行过采样,并可视化样本分布。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值