Borderline-SMOTE 是基于 SMOTE 的一种改进版本,它只对那些靠近多数类的少数类样本进行过采样,从而避免了对所有少数类样本进行过采样可能导致的过拟合问题。下面详细介绍 Borderline-SMOTE 的算法流程及公式。
算法流程:
- 找到少数类样本中的边界样本(即与多数类样本之间的距离小于某个阈值),将这些样本标记为 Borderline-SMOTE 样本。
- 对于每个 Borderline-SMOTE 样本,计算其 K 个最近邻样本的平均值。
- 针对每个 Borderline-SMOTE 样本,选择其中一个最近邻样本,并随机生成一些新样本,生成规则为:4. 新样本 = Borderline-SMOTE 样本 + (Borderline-SMOTE 样本 – 最近邻样本)* 随机数。
将生成的新样本添加到少数类样本中。
公式:
假设某个 Borderline-SMOTE 样本为 x,它的 K 个最近邻样本为 N(x)={x1, x2, …, xk},新样本生成的公式为:
xnew=x+λ(x−xnn)x_{new} = x + lambda (x – x_{nn})
其中,λlambda 是随机数,xnnx_{nn} 是从 N(x) 中选择的最近邻样本。
需要注意的是,在实现 Borderline-SMOTE 时,需要确定阈值、K 值和生成样本的数量等参数,这些参数的选取需要结合具体问题和数据集进行调整。
下面给出一个 Python 实现的例子:
from collections import Counter
from sklearn.neighbors import NearestNeighbors
import numpy as np
def borderline_SMOTE(X, y, k_neighbors=5, m_neighbors=10, thresh=0.5, N=100):
"""
Borderline-SMOTE 算法实现。
参数:
- X: 原始特征矩阵。
- y: 原始标签。
- k_neighbors: K 值,默认为 5。
- m_neighbors: M 值,即生成样本的最大个数,默认为 10。
- thresh: 阈值,默认为 0.5。
- N: 需要生成的新样本数量,默认为 100。
返回:
- X_resampled: 过采样后的特征矩阵。
- y_resampled: 过采样后的标签。
"""
# 统计各个类别的数量
counter = Counter(y)
max_class_count = max(counter.values())
minority_class = [k for k, v in counter.items() if v < max_class_count][0]
# 找到少数类样本中的边界样本
neigh = NearestNeighbors(n_neighbors=k_neighbors)
neigh.fit(X)
X_min = X[y == minority_class]
border = []
for i, x in enumerate(X_min):
# 找到 x 的 K 个最近邻样本
knn = neigh.kneighbors([x], n_neighbors=k_neighbors+1, return_distance=False)[0]
knn = knn[1:] # 将 x 本身排除掉
# 计算 x 与其 K 个最近邻样本之间的距离
dist = np.linalg.norm(X[knn] - x, axis=1)
# 判断 x 是否为边界样本
if np.mean(dist) < thresh:
border.append(i)
# 针对边界样本生成新样本
X_new = []
y_new = []
for i in border:
x = X_min[i]
# 找到 x 的 M 个最近邻样本
knn = neigh.kneighbors([x], n_neighbors=m_neighbors+1, return_distance=False)[0]
knn = knn[1:] # 将 x 本身排除掉
# 计算 x 与其 M 个最近邻样本之间的距离
dist = np.linalg.norm(X[knn] - x, axis=1)
# 找到 x 的最近邻样本
nn = knn[np.argmin(dist)]
for j in range(N):
# 生成新样本
lambda_ = np.random.rand()
x_new = x + lambda_ * (x - X[nn])
X_new.append(x_new)
y_new.append(minority_class)
# 将生成的新样本添加到原始数据中
X_resampled = np.vstack([X, np.array(X_new)])
y_resampled = np.hstack([y, np.array(y_new)])
return X_resampled, y_resampled
以上是 Borderline-SMOTE 的一个简单实现,使用时只需要传入原始特征矩阵和标签,以及一些参数(如 K 值、M 值、阈值等)即可。
需要注意的是,Borderline-SMOTE 算法是基于 SMOTE 算法的改进版,因此它也具有一些局限性和不足之处。比如:
只适用于二分类问题。Borderline-SMOTE 算法只能用于二分类问题中的少数类样本增强,对于多分类问题中的类别不平衡问题,需要采用其他方法;
对参数敏感。Borderline-SMOTE 算法的效果受到一些关键参数(如 K 值、M 值、阈值等)的影响,需要进行调参才能获得最佳的增强效果;
不适用于噪声数据。当数据中存在大量噪声数据时,Borderline-SMOTE 算法可能会增加噪声数据的数量,从而影响分类器的性能。
因此,在实际使用中,需要根据具体情况选择合适的方法来处理数据不平衡问题,以获得更好的分类效果。
需要注意的是,Borderline-SMOTE 算法是基于 SMOTE 算法的改进版,因此它也具有一些局限性和不足之处。比如:
- 只适用于二分类问题。Borderline-SMOTE 算法只能用于二分类问题中的少数类样本增强,对于多分类问题中的类别不平衡问题,需要采用其他方法;
- 对参数敏感。Borderline-SMOTE 算法的效果受到一些关键参数(如 K 值、M 值、阈值等)的影响,需要进行调参才能获得最佳的增强效果;
- 不适用于噪声数据。当数据中存在大量噪声数据时,Borderline-SMOTE 算法可能会增加噪声数据的数量,从而影响分类器的性能。
因此,在实际使用中,需要根据具体情况选择合适的方法来处理数据不平衡问题,以获得更好的分类效果。