对于分类数据集而言,往往类别会有比较大的差异,比如分析贷款逾期的数据,往往没有逾期的数据远远大于逾期的数据,因此样本会存在不均衡的情况,这样对于数据的训练不利,因此可以使用某些方法对数据集进行调整,分为过采样和欠采样,过采样就是将少的类别变多,欠采样就是将多的类别变少,这里只给出代码,不给出每种算法的具体的原理。
具体使用欠采样还是过采样,应该视情况而定,因为数据训练需要保证数据的充足,因此如果对数据进行欠采样后,数据量明显很少,那么绝对是不能使用欠采样的。
#生成数据集
from sklearn.datasets import make_classification
from collections import Counter
X, y = make_classification(n_samples=5000, n_features=2,
n_informative=2, n_redundant=0,
n_repeated=0, n_classes=3,
n_clusters_per_class=1,
weights=[0.01, 0.05, 0.94],
class_sep=0.8, random_state=0)
#随机过采样
#生成数据集
from sklearn.datasets import make_classification
from collections import Counter
X, y = make_classification(n_samples=5000, n_features=2,
n_informative=2, n_redundant=0,
n_repeated=0, n_classes=3,
n_clusters_per_class=1,
weights=[0.01, 0.05, 0.94],
class_sep=0.8, random_state=0)
#随机过采样
from imblearn.over_sampling import RandomOverSampler
X_resampled, y_resampled = RandomOverSampler().fit_resample(X, y)
print ("原始y:"+str(Counter(y)))
print("随机过采样后的y:"+str(Counter(y_resampled)))
#SMOTE过采样及其变体
from imblearn.over_sampling import SMOTE
from imblearn.over_sampling import BorderlineSMOTE
X_resampled_smote, y_resampled_smote = SMOTE().fit_resample(X, y)
X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-1').fit_resample(X, y)
X_resampled, y_resampled = BorderlineSMOTE(kind='borderline-2').fit_resample(X, y)
#ADASYN过采样
from imblearn.over_sampling import ADASYN
X_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_resample(X, y)
#随机欠采样
from imblearn.under_sampling import RandomUnderSampler
X_resampled, y_resampled = RandomUnderSampler().fit_resample(X, y)
print("原始y:"+str(Counter(y)))
print("随机欠采样后的y:"+str(Counter(y_resampled)))
#基于k-means聚类的欠采样
from imblearn.under_sampling import ClusterCentroids
X_resampled, y_resampled = ClusterCentroids().fit_resample(X, y)
#基于最近邻算法的欠采样
from imblearn.under_sampling import RepeatedEditedNearestNeighbours
X_resampled, y_resampled = RepeatedEditedNearestNeighbours().fit_resample(X, y)
#在数据上运用一种分类器
#然后将概率低于阈值的样本剔除掉
#从而实现欠采样
from sklearn.linear_model import LogisticRegression
from imblearn.under_sampling import InstanceHardnessThreshold
lr_underS = InstanceHardnessThreshold(
random_state=0, estimator=LogisticRegression())
X_resampled, y_resampled = lr_underS.fit_resample(X, y)
看下下面的结果,可以发现过采样把1和0类别的样本增加了,欠采样把2类别的样本减少了,当然这里肯定是使用过采样更好因为欠采样导致数据集太小了。