数模国赛冲刺 | 数据预处理方法合集(特征工程、数据降维、数据划分、数据平衡)

​数据预处理方法合集(特征工程数据降维数据划分数据平衡

本文继续介绍数据预处理中的特征工程数据降维数据划分数据平衡的内容,接下来我们将详细地介绍具体的方法,文末可获得预处理方法合集PDF

目录

特征工程

特征选择(Feature Selection)

特征提取

数据降维

线性降维方法

非线性降维方法

数据划分

训练集、验证集和测试集划分

交叉验证(Cross-Validation)

分层抽样(Stratified Sampling)

时间序列数据划分(Time Series Split)

留出法(Hold-Out Method)

自助法(Bootstrap Method)

数据平衡

欠采样(Undersampling)

过采样(Oversampling)

混合采样(Hybrid Sampling)

集成方法(Ensemble Methods)

成本敏感学习(Cost-Sensitive Learning)

生成对抗网络(GAN)

自适应采样


特征工程

特征选择(Feature Selection)

特征选择是从数据集中选择对目标变量最有影响的特征,同时剔除不相关或冗余的特征。通过特征选择,可以减少模型的复杂度,提高模型的性能和可解释性。

  • 过滤法(Filter Methods):依据统计特性(如方差、相关系数、卡方检验、互信息)选择特征。

  • 包裹法(Wrapper Methods): 使用模型性能指标(如精度、AUC)评估特征组合。

  • 嵌入法(Embedded Methods): 在模型训练过程中内置特征选择(如Lasso回归、决策树)。

1)过滤法(Filter Method)
  • 方差选择法(Variance Threshold)

低方差特征可能对模型贡献较小,因此可以删除方差低于某个阈值的特征。

适用场景:在数据中存在常数特征或几乎不变的特征时,可以通过方差选择法来去除它们。

from sklearn.feature_selection import VarianceThreshold

# 示例数据
X = [[0, 2, 0, 3],
     [0, 1, 4, 3],
     [0, 1, 1, 3]]

# 去除低方差特征
selector = VarianceThreshold(threshold=0.1)
X_high_variance = selector.fit_transform(X)

print("去除低方差特征后的数据:")
print(X_high_variance)
  • 卡方检验(Chi-Square Test)

卡方检验用于检查类别变量之间的独立性。通过计算特征与目标变量之间的卡方统计量来判断其相关性。

适用场景:用于分类问题中的特征选择,特别是类别变量的处理。

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest, chi2

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 使用卡方检验选择前2个最相关特征
selector = SelectKBest(score_func=chi2, k=2)
X_kbest = selector.fit_transform(X, y)

print("卡方检验选择的特征:")
print(X_kbest)
  •  皮尔逊相关系数(Pearson Correlation Coefficient)

计算每个特征与目标变量之间的线性相关性,选择相关性较高的特征。

适用场景:用于连续型特征和目标变量之间的线性关系分析。

import numpy as np
from scipy.stats import pearsonr

# 示例数据
X = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])

# 计算相关系数
corr, _ = pearsonr(X, y)
print("皮尔逊相关系数:", corr)
  •  互信息(Mutual Information)

互信息衡量两个变量之间的依赖性,捕捉线性和非线性关系。它是信息论中的一个概念,表示通过一个变量可以获得多少关于另一个变量的信息。

适用场景:用于处理分类问题中的非线性关系特征选择。

from sklearn.feature_selection import mutual_info_classif

# 示例数据
X = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
y = [0, 1, 0]

# 计算互信息
mi = mutual_info_classif(X, y)

print("互信息得分:", mi)
2)包裹法(Wrapper Method)

包裹法使用一个预测模型来评估特征子集的性能,通过训练模型来找到最优的特征组合。包裹法比过滤法更能捕捉特征之间的相互作用,但计算成本较高,特别是当特征数量很多时。

  • 递归特征消除(Recursive Feature Elimination, RFE)

RFE通过递归地构建模型,逐步消除最不重要的特征,最终得到最优特征子集。

适用场景:适用于需要选择少量最重要特征的场景,尤其是在特征数量较多时。

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

# 加载数据
data = load_iris()
X, y = data.data, data.target

# 使用RFE选择特征
model = LogisticRegression(max_iter=200)
selector = RFE(model, n_features_to_select=2)
X_rfe = selector.fit_transform(X, y)

print("RFE选择的特征:")
print(X_rfe)
  • 前向选择(Forward Selection)

从空特征集开始,每次加入一个最能提高模型性能的特征,直到达到某个停止条件。适用场景:适用于逐步构建特征集,尤其在计算资源有限的情况下。

  •  后向选择(Backward Elimination)

从完整特征集开始,每次去除一个对模型影响最小的特征,直到达到某个停止条件。适用场景:适用于逐步减少特征,尤其在已经有一个比较好的特征集的情况下。

3)嵌入法(Embedded Method)

嵌入法在模型训练过程中自动进行特征选择,特征选择过程与模型的训练过程是同步进行的。嵌入法结合了过滤法和包裹法的优点,既考虑了特征与目标变量之间的关系,也考虑了特征之间的相互作用。

  •  Lasso回归(L1正则化)

Lasso回归通过在损失函数中加入L1正则化项,使得某些特征的系数缩小为零,从而起到特征选择的作用。

适用场景:适用于线性模型,尤其是当特征数量多于样本数量时。

from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston

# 加载数据
X, y = load_boston(return_X_y=True)

# 使用Lasso进行特征选择
model = Lasso(alpha=0.1)
model.fit(X, y)
importance = model.coef_

print("Lasso回归选择的特征:")
print(importance)
  •  决策树模型(Decision Tree)

决策树模型通过选择信息增益最大的特征来进行分裂,天然地进行特征选择。

适用场景:适用于处理分类和回归问题,尤其是当特征之间存在非线性关系时。

from sklearn.tree import DecisionTreeClassifier

# 加载数据
X, y = load_iris(return_X_y=True)

# 使用决策树进行特征选择
model = DecisionTreeClassifier()
model.fit(X, y)
importance = model.feature_importances_

print("决策树模型选择的特征:")
print(importance)
  • 基于正则化的随机森林(Random Forest with Regularization)

随机森林通过构建多个决策树,计算每个特征的重要性得分,选择最重要的特征。

适用场景:适用于处理高维数据和非线性问题,特别是在特征之间存在复杂交互时。

from sklearn.ensemble import RandomForestClassifier

# 加载数据
X, y = load_iris(return_X_y=True)

# 使用随机森林进行特征选择
model = RandomForestClassifier(n_estimators=100)
model.fit(X, y)
importance = model.feature_importances_

print("随机森林模型选择的特征:")
print(importance)

总结

  •  过滤法: 简单且计算效率高,适合初步筛选特征,但无法考虑特征之间的交互作用。

  • 包裹法: 更能捕捉特征之间的交互作用,但计算成本较高,适用于特征数量较少的情况。

  • 嵌入法: 在模型训练过程中自动选择特征,结合了模型的性能和特征的重要性,适用于大多数机器学习问题。

特征提取

特征提取是将高维数据转换为低维特征空间的过程,目的是提取出对模型预测有用的特征,同时去除噪声和冗余信息。

1)主成分分析(PCA)

主成分分析(PCA)是一种线性降维技术,通过将数据投影到方差最大的方向上,从而减少数据的维度。PCA的目标是找到数据中一组新的正交坐标轴(称为主成分),这些轴上的投影能最大程度地保留数据的方差信息。

Step1 计算数据的协方差矩阵。

Step2 求解协方差矩阵的特征值和特征向量。

Step3 根据特征值的大小选择对应的特征向量作为主成分。

Step4 将原始数据投影到选择的主成分上。

适用场景: PCA适用于需要降维和去除噪声的场景,尤其是在数据集中包含大量相关特征的情况下。常用于图像处理、数据可视化和压缩等领域。

from sklearn.decomposition import PCA
import numpy as np

# 示例数据
X = np.array([[2.5, 2.4], [0.5, 0.7], [2.2, 2.9], [1.9, 2.2], [3.1, 3.0], [2.3, 2.7]])

# 使用PCA进行特征提取
pca = PCA(n_components=1)
X_pca = pca.fit_transform(X)

print("PCA提取的主成分:")
print(X_pca)
2)独立成分分析(ICA)

独立成分分析(ICA)是一种统计和计算方法,旨在将观察到的混合信号分解为具有统计独立性的源信号。ICA常用于盲源分离(如音频信号的分离)和数据降维中。

Step1 寻找一个解混合矩阵,使得分离后的信号相互独立。

Step2 通过最大化信号的非高斯性来实现信号的独立性。

适用场景: ICA适用于信号处理领域,尤其是在音频、图像处理和神经科学中,用于从混合信号中提取独立成分。

from sklearn.decomposition import FastICA

# 示例数据
X = np.array([[2, 4], [1, 3], [2, 2], [3, 5], [4, 6], [2, 3]])

# 使用ICA进行特征提取
ica = FastICA(n_components=2)
X_ica = ica.fit_transform(X)

print("ICA提取的独立成分:")
print(X_ica)
3)线性判别分析(LDA)

线性判别分析(LDA)是一种监督式降维方法,旨在通过最大化类间方差与类内方差的比率,找到能最好区分不同类别的数据投影方向。与PCA不同,LDA考虑了类别标签的信息。

Step1 计算类内散布矩阵(SW)和类间散布矩阵(SB)。

Step2 求解矩阵SW−1SB的特征值和特征向量。

Step3 将数据投影到选定的特征向量方向上。

适用场景: LDA适用于分类问题中的降维,特别是在特征数量多于样本数量的情况下,如人脸识别、文本分类等。

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

# 示例数据
X = np.array([[2, 3], [3, 4], [4, 5], [5, 6], [6, 7]])
y = np.array([0, 0, 1, 1, 1])

# 使用LDA进行特征提取
lda = LDA(n_components=1)
X_lda = lda.fit_transform(X, y)

print("LDA提取的判别分量:")
print(X_lda)
4)奇异值分解(SVD)

奇异值分解(SVD)是一种矩阵分解方法,用于将一个矩阵分解为三个矩阵的乘积:左奇异矩阵、对角奇异值矩阵和右奇异矩阵。SVD广泛应用于降维、数据压缩、图像处理和推荐系统中。

SVD分解公式为:X=U⋅Σ⋅VT其中,X是原始数据矩阵,𝑈是左奇异矩阵,Σ是对角奇异值矩阵,VT是右奇异矩阵的转置。

适用场景: SVD适用于数据降维、矩阵补全、图像压缩等场景,特别是在处理大规模稀疏矩阵时非常有效。

from sklearn.decomposition import TruncatedSVD
import numpy as np

# 示例数据
X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 使用SVD进行特征提取
svd = TruncatedSVD(n_components=2)
X_svd = svd.fit_transform(X)

print("SVD提取的特征:")
print(X_svd)
5)核PCA(Kernel PCA)

核PCA是PCA的非线性扩展,通过使用核技巧(Kernel Trick),将数据映射到一个高维特征空间,然后在高维空间中进行PCA。这使得核PCA能够捕捉数据中的非线性结构。K(X,X′)=ϕ(X)⋅ϕ(X′)其中,𝐾(𝑋,𝑋′)是核函数,𝜙(𝑋)是将数据映射到高维空间的映射函数。

适用场景: 核PCA适用于非线性数据结构的降维,常用于图像处理、非线性分类问题中。

from sklearn.decomposition import KernelPCA

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])

# 使用核PCA进行特征提取
kpca = KernelPCA(n_components=2, kernel='rbf')
X_kpca = kpca.fit_transform(X)

print("核PCA提取的特征:")
print(X_kpca)
6)非负矩阵分解(NMF)

非负矩阵分解(NMF)是一种矩阵分解方法,用于将一个非负矩阵分解为两个非负矩阵的乘积。NMF常用于数据降维、特征提取和信号处理等领域。与PCA不同,NMF要求分解后的矩阵元素都为非负数,这使得NMF在解释性上有优势。

适用场景: NMF适用于处理非负数据(如图像数据、文档-词矩阵)和需要解释性结果的场景,如主题建模、信号分解等。

from sklearn.decomposition import NMF
import numpy as np

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6]])

# 使用NMF进行特征提取
nmf = NMF(n_components=2)
X_nmf = nmf.fit_transform(X)

print("NMF提取的特征:")
print(X_nmf)

数据降维

线性降维方法

线性降维方法假设数据的结构可以通过线性变换来捕捉,这些方法在处理具有线性特征的数据时非常有效。常见方法有:

  • 主成分分析(PCA): 基于线性变换,将数据投影到方差最大的方向上。

  • 线性判别分析(LDA): 寻找能够最好分离不同类别的线性投影方向。

  • 奇异值分解(SVD): 通过线性分解将矩阵分解为低维子空间。

  • 独立成分分析(ICA): 通过线性变换分离出独立的成分。

非线性降维方法

非线性降维方法用于处理具有复杂非线性结构的数据,这些方法能够捕捉到数据中更复杂的模式。

1)t-SNE

t-SNE是一种非线性降维方法,通过最小化高维空间中相似点在低维空间中的分布差异来实现降维。t-SNE特别擅长保留数据的局部结构,适用于高维数据的可视化。

适用场景: 常用于高维数据的可视化,特别是当需要展示数据的簇结构时。

from sklearn.manifold import TSNE

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

# 使用t-SNE进行降维
tsne = TSNE(n_components=2)
X_tsne = tsne.fit_transform(X)

print("t-SNE降维后的数据:")
print(X_tsne)
2)局部线性嵌入(LLE)

LLE是一种非线性降维方法,通过保留数据的局部结构,将高维数据嵌入到低维空间中。LLE假设每个数据点及其邻居可以通过线性组合表示,并通过保留这些线性组合关系来实现降维。

适用场景: 适用于处理复杂的非线性数据,特别是当数据位于流形上时。

from sklearn.manifold import LocallyLinearEmbedding

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

# 使用LLE进行降维
lle = LocallyLinearEmbedding(n_components=2)
X_lle = lle.fit_transform(X)

print("LLE降维后的数据:")
print(X_lle)
3)Isomap

Isomap是一种基于流形学习的非线性降维方法,通过保留数据的全局几何结构,将高维数据嵌入到低维空间中。Isomap通过计算数据点之间的最短路径距离来捕捉数据的流形结构。

适用场景: 适用于数据位于复杂的非线性流形上的情况,常用于图像分析和数据可视化。

from sklearn.manifold import Isomap

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

# 使用Isomap进行降维
isomap = Isomap(n_components=2)
X_isomap = isomap.fit_transform(X)

print("Isomap降维后的数据:")
print(X_isomap)
4)UMAP

UMAP通过构建高维空间中的近邻图,并将其投影到低维空间中,以保留数据的拓扑结构。

  • 数据可视化: UMAP常用于将高维数据嵌入到二维或三维空间中,以便于可视化和理解数据的内在结构。

  • 聚类分析: UMAP可以在低维空间中保留聚类结构,帮助识别数据中的群体和模式。

  • 降维预处理: UMAP可作为降维预处理步骤,减少数据维度,从而提高后续机器学习模型的效率和性能。

import umap
import numpy as np

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])

# 使用UMAP进行降维
reducer = umap.UMAP(n_components=2)
X_umap = reducer.fit_transform(X)

print("UMAP降维后的数据:")
print(X_umap)

数据划分

训练集、验证集和测试集划分

数据集通常被划分为训练集、验证集和测试集,以便对模型进行训练、调优和最终评估。这种划分方式确保模型在训练过程中不会看到测试集数据,从而能够更准确地评估模型的泛化能力。

  • 训练集(Training Set): 用于训练模型的部分数据,模型通过这个数据学习特征和规律。

  • 验证集(Validation Set): 用于调优模型参数的部分数据,帮助选择最佳模型超参数,防止过拟合。

  • 测试集(Test Set): 最终用于评估模型性能的数据,模型在训练和调优过程中未曾见过这些数据。

from sklearn.model_selection import train_test_split

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
y = [0, 1, 0, 1, 0]

# 将数据划分为训练集和测试集(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)
print("测试集数据:", X_test)

交叉验证(Cross-Validation)

交叉验证是一种常用的模型评估方法,尤其在数据量较少时非常有效。交叉验证通过将数据集划分为多个互斥的子集,每次使用其中一个子集作为验证集,其他子集作为训练集,反复进行训练和验证,从而更全面地评估模型的性能。

  • k折交叉验证(k-Fold Cross-Validation): 将数据集划分为k个子集,每次使用k-1个子集进行训练,剩下的一个子集进行验证,重复k次,最终计算平均性能。

  • 留一法(LOO, Leave-One-Out): 每次只留出一个数据点作为验证集,其余数据用于训练,适合小数据集。

from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
import numpy as np

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([0, 1, 0, 1, 0])

# 使用k折交叉验证评估模型(5折交叉验证)
model = RandomForestClassifier(random_state=42)
scores = cross_val_score(model, X, y, cv=5)

print("交叉验证得分:", scores)

分层抽样(Stratified Sampling)

分层抽样是一种用于处理类别不平衡数据集的划分方法。通过在每个类别中按比例抽取样本,分层抽样确保训练集和测试集中各类别的比例与原始数据集一致。分层交叉验证(Stratified Cross-Validation)是其在交叉验证中的应用。在处理类别不平衡问题时,能够确保各类别的代表性,防止模型在某些类别上表现过差。提高了模型评估的公平性和稳定性。

from sklearn.model_selection import train_test_split

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
y = [0, 0, 1, 1, 1, 0]

# 分层抽样划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, stratify=y, random_state=42)

print("分层抽样后的训练集:", y_train)
print("分层抽样后的测试集:", y_test)

时间序列数据划分(Time Series Split)

时间序列数据的划分不同于静态数据,因为时间序列数据具有时间依赖性。传统的随机划分可能会破坏数据的时间结构,因此需要使用特定的方法来处理时间序列数据。

  • 滚动窗口法(Rolling Window Method): 在时间序列数据上应用滚动窗口,每次使用一段时间的数据作为训练集,接下来的数据作为测试集。

  • 时间序列交叉验证(Time Series Cross-Validation): 在时间序列数据中,通过递增的时间窗口进行交叉验证,保证训练集数据总是早于测试集数据。

from sklearn.model_selection import TimeSeriesSplit
import numpy as np

# 示例时间序列数据
X = np.array([[1], [2], [3], [4], [5], [6], [7]])
y = np.array([1, 2, 3, 4, 5, 6, 7])

# 时间序列交叉验证(3次分割)
tscv = TimeSeriesSplit(n_splits=3)

for train_index, test_index in tscv.split(X):
    print("训练集索引:", train_index, "测试集索引:", test_index)

留出法(Hold-Out Method)

留出法是最简单的数据划分方法,将数据随机划分为两部分,一部分用于训练模型,另一部分用于测试模型。通常按比例划分,比如70%用于训练,30%用于测试。

from sklearn.model_selection import train_test_split

# 示例数据
X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
y = [0, 1, 0, 1, 0]

# 留出法划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

print("留出法训练集:", X_train)
print("留出法测试集:", X_test)

自助法(Bootstrap Method)

自助法是一种基于重采样的数据划分方法,通过从原始数据集中有放回地抽样生成多个训练集,未被抽到的样本作为测试集。自助法常用于模型评估、集成学习(如Bagging)等。

from sklearn.utils import resample
import numpy as np

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([0, 1, 0, 1, 0])

# 使用自助法生成训练集
X_resampled, y_resampled = resample(X, y, n_samples=4, random_state=42)

print("自助法生成的训练集:")
print(X_resampled)

数据平衡

数据平衡方法主要用于处理类别不平衡问题,特别是在分类任务中,类别不平衡可能导致模型对少数类别的预测性能较差。

欠采样(Undersampling)

1)随机欠采样

随机欠采样是一种直接减少多数类样本数量的策略,通过随机删除多数类中的一些样本,使其数量与少数类接近,从而达到平衡数据集的目的。

适用场景: 适用于多数类样本数量非常多的情况,尤其是在数据量大到处理时间和存储资源成为瓶颈时。随机欠采样能够有效地减少数据量,降低计算资源的消耗。

from imblearn.under_sampling import RandomUnderSampler
import numpy as np

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 随机欠采样
rus = RandomUnderSampler(random_state=42)
X_res, y_res = rus.fit_resample(X, y)

print("欠采样后的数据:", X_res)
print("欠采样后的标签:", y_res)
2)聚类欠采样

聚类欠采样通过使用聚类算法将多数类样本分为多个簇,然后从每个簇中选择代表性样本进行训练。这种方法在保持多数类样本多样性的同时减少样本数量,避免了随机欠采样可能带来的信息丢失。

适用场景: 适用于多数类样本数量多但样本分布复杂的情况,通过聚类保持多数类样本的代表性和多样性。

from imblearn.under_sampling import ClusterCentroids

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用聚类欠采样
cc = ClusterCentroids(random_state=42)
X_res, y_res = cc.fit_resample(X, y)

print("聚类欠采样后的数据:", X_res)
print("聚类欠采样后的标签:", y_res)

过采样(Oversampling)

1) 随机过采样

随机过采样通过复制少数类样本来增加少数类的数量,使其数量与多数类接近。这种方法简单直接,可以有效平衡数据集,但也容易导致过拟合。

适用场景: 适用于少数类样本数量非常少的场景,尤其是在少数类样本对模型性能影响较大时。随机过采样能够增加少数类的数量,提高模型对少数类的识别能力。

from imblearn.over_sampling import RandomOverSampler

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 随机过采样
ros = RandomOverSampler(random_state=42)
X_res, y_res = ros.fit_resample(X, y)

print("随机过采样后的数据:", X_res)
print("随机过采样后的标签:", y_res)
2)SMOTE

SMOTE通过在少数类样本之间插值来合成新的少数类样本。这种方法通过生成新的样本来避免简单复制带来的过拟合问题,从而更好地平衡数据集。

适用场景: 适用于少数类样本较少且模型容易过拟合的场景。SMOTE能够在增加少数类样本数量的同时保持数据的多样性。

from imblearn.over_sampling import SMOTE

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用SMOTE进行过采样
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)

print("SMOTE过采样后的数据:", X_res)
print("SMOTE过采样后的标签:", y_res)

混合采样(Hybrid Sampling)

1)SMOTE + ENN(Edited Nearest Neighbors)

SMOTE + ENN结合了SMOTE和ENN两种方法。首先通过SMOTE合成新的少数类样本,接着使用ENN算法删除数据集中可能包含噪声的多数类样本,从而在增加少数类样本的同时清理数据。

适用场景: 适用于数据集复杂、含噪声较多的场景,通过这种方法可以提高数据的质量和模型的性能。

from imblearn.combine import SMOTEENN

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用SMOTE + ENN进行混合采样
smote_enn = SMOTEENN(random_state=42)
X_res, y_res = smote_enn.fit_resample(X, y)

print("SMOTE + ENN混合采样后的数据:", X_res)
print("SMOTE + ENN混合采样后的标签:", y_res)

SMOTE + Tomek Links通过结合SMOTE和Tomek Links两种技术,先使用SMOTE生成少数类样本,然后使用Tomek Links去除数据中容易混淆的多数类样本,从而进一步平衡数据集。

适用场景: 适用于希望通过去除冗余多数类样本来提高数据集质量的场景。

from imblearn.combine import SMOTETomek

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用SMOTE + Tomek Links进行混合采样
smote_tomek = SMOTETomek(random_state=42)
X_res, y_res = smote_tomek.fit_resample(X, y)

print("SMOTE + Tomek Links混合采样后的数据:", X_res)
print("SMOTE + Tomek Links混合采样后的标签:", y_res)

集成方法(Ensemble Methods)

1)EasyEnsemble

EasyEnsemble是一种集成方法,它通过对多数类进行多次随机欠采样,生成多个平衡的子集,并训练多个分类器,将这些分类器的结果集成。这种方法能够有效减少多数类样本的数量,同时保留数据的多样性。

适用场景: 适用于数据量大且需要构建稳健模型的场景,尤其在少数类样本非常重要的任务中。

from imblearn.ensemble import EasyEnsembleClassifier

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用EasyEnsemble进行数据平衡
model = EasyEnsembleClassifier(random_state=42)
model.fit(X, y)
y_pred = model.predict(X)

print("EasyEnsemble预测结果:", y_pred)
2)BalanceCascade

BalanceCascade是一种逐步欠采样方法,每次对多数类进行欠采样,去除当前分类器可以正确分类的多数类样本,直至达到数据集的平衡。然后集成所有分类器的预测结果。

适用场景: 适用于数据集中多数类样本明显多于少数类的情况,通过这种方法可以逐步优化模型对少数类的识别能力。

import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import train_test_split
from collections import Counter

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12], [13, 14], [15, 16], [17, 18], [19, 20]])
y = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1])

# 自定义 BalanceCascade 方法
def balance_cascade(X, y, n_classifiers=3):
    classifiers = []
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
    
    for i in range(n_classifiers):
        clf = DecisionTreeClassifier(random_state=42)
        clf.fit(X_train, y_train)
        
        y_pred = clf.predict(X_train)
        correct_classified_indices = np.where((y_pred == y_train) & (y_train == 0))[0]
        
        # 剔除当前分类器能够正确分类的多数类样本
        X_train = np.delete(X_train, correct_classified_indices, axis=0)
        y_train = np.delete(y_train, correct_classified_indices, axis=0)
        
        classifiers.append(clf)
        print(f"Classifier {i+1} trained with {len(y_train)} samples remaining.")
    
    # 使用VotingClassifier集成多个分类器
    voting_clf = VotingClassifier(estimators=[(f'clf{i}', clf) for i, clf in enumerate(classifiers)], voting='hard')
    voting_clf.fit(X, y)
    
    return voting_clf

# 运行 BalanceCascade
voting_clf = balance_cascade(X, y, n_classifiers=3)

# 预测测试集
X_test = np.array([[2, 3], [6, 7], [10, 11]])
y_pred = voting_clf.predict(X_test)
print("预测结果:", y_pred)

成本敏感学习(Cost-Sensitive Learning)

1)加权随机森林

加权随机森林通过为少数类样本分配较高的权重,使模型在训练时更加关注少数类。这种方法通过调整权重来解决类别不平衡问题,而无需对数据进行采样处理。

适用场景: 适用于不希望改变数据集结构但希望模型更加关注少数类的场景,如医疗诊断、欺诈检测等任务。

from sklearn.ensemble import RandomForestClassifier

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用加权随机森林进行数据平衡
model = RandomForestClassifier(class_weight={0: 1, 1: 10}, random_state=42)
model.fit(X, y)
y_pred = model.predict(X)

print("加权随机森林预测结果:", y_pred)
2)代价敏感决策树

代价敏感决策树在决策树模型中为不同类别设定不同的代价权重,使得模型在分类错误时对少数类的惩罚更大,从而更倾向于正确分类少数类样本。

适用场景: 适用于希望在决策树模型中显式控制分类错误代价的场景,如不对称损失函数的问题。

from sklearn.tree import DecisionTreeClassifier

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用代价敏感决策树
model = DecisionTreeClassifier(class_weight={0: 1, 1: 10}, random_state=42)
model.fit(X, y)
y_pred = model.predict(X)

print("代价敏感决策树预测结果:", y_pred)

生成对抗网络(GAN)

生成对抗网络通过生成模型和判别模型的对抗训练,生成逼真的少数类样本。生成模型负责生成新的样本,判别模型则用于区分生成的样本与真实样本,二者在对抗中不断改进。

适用场景: 适用于复杂数据类型的少数类样本扩展,如图像分类、文本生成等任务。

自适应采样

ADASYN

ADASYN是一种自适应采样方法,通过在少数类样本之间合成新的样本,特别关注那些难以分类的样本,生成更多类似这些样本的新数据。

适用场景: 适用于希望通过关注难以分类的少数类样本来提高模型性能的场景,如数据复杂度较高的分类任务。

from imblearn.over_sampling import ADASYN

# 示例数据
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]])
y = np.array([0, 0, 0, 0, 1, 1])

# 使用ADASYN进行自适应过采样
adasyn = ADASYN(random_state=42)
X_res, y_res = adasyn.fit_resample(X, y)

print("ADASYN采样后的数据:", X_res)
print("ADASYN采样后的标签:", y_res)

Easy数模,让数学建模变得轻松易懂。我们提供从基础到高级的建模教程、个性化竞赛助攻、丰富的建模资源分享,旨在帮助您快速提升数学建模能力,无论是学术竞赛还是实际应用,都能轻松应对。

关注公众号,后台回复“数据预处理”即可获得数据预处理方法合集PDF

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值