# -*- coding:utf-8 -*-
"""
#-------------------------------------
@author:wangdong
@mail:aufe_wangdong@sina.cn
@version:v1.0
@date:2018/1/8
-------------------------------------
# @Brief:
"""
from sklearn.datasets import make_classification
from imblearn.under_sampling import ClusterCentroids,RandomUnderSampler,NearMiss,EditedNearestNeighbours,RepeatedEditedNearestNeighbours,AllKNN
from imblearn.over_sampling import RandomOverSampler,SMOTE,ADASYN
from imblearn.ensemble import EasyEnsemble,BalanceCascade,BalancedBaggingClassifier
from imblearn.combine import SMOTEENN,SMOTETomek
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
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.1, 0.3, 0.6],
class_sep=0.8, random_state=0)
print Counter(y)
ros=RandomOverSampler(random_state=0)
#随机过采样
X_ros,y_ros=ros.fit_sample(X,y)
print Counter(y_ros)
#SMOTE算法 kind有三个参数分别为(1)borderline1 (2)borderline2 (3)svm (4)regular
X_smote,y_smote=SMOTE(kind='borderline1').fit_sample(X,y)
print Counter(y_smote)
#ADASYN算法
X_adasyn,y=ADASYN().fit_sample(X,y)
print Counter(y_smote)
#下采样
#原型生成算法
#给定数据集S, 原型生成算法将生成一个子集S1,其中|S1| < |S|, 但是子集并非来自于原始数据集.意思就是说: 原型生成方法将减少数据集的样本数量,剩下的样本是由原始数据集生成的,而不是直接来源于原始数据集.
#ClusterCentroids函数实现了上述功能: 每一个类别的样本都会用K-Means算法的中心点来进行合成, 而不是随机从原始样本进行抽取.
cc=ClusterCentroids(random_state=0)
X_centroids,y_centroids=cc.fit_sample(X,y)
print Counter(y_centroids)
#原型选择算法
#原型选择算法是直接从原始数据集中进行抽取
#RandomUnderSampler函数是一种快速并十分简单的方式来平衡各个类别的数据:随机选取数据的子集.
#通过设置RandomUnderSampler中的replacement=True参数, 可以实现自助法(Bootstrap)有放回抽样.
rus=RandomUnderSampler(random_state=0,replacement=True)
X_rus,y_rus=rus.fit_sample(X,y)
print Counter(y_rus)
#NearMiss函数则添加了一些启发式(heuristic)的规则来选择样本, 通过设定version参数来实现三种启发式的规则.
#NearMiss-1: 选择离N个近邻的负样本的平均距离最小的正样本;
#NearMiss-2: 选择离N个负样本最远的平均距离最小的正样本;
#NearMiss-3: 是一个两段式的算法. 首先, 对于每一个负样本, 保留它们的M个近邻样本; 接着, 那些到N个近邻样本平均距离最大的正样本将被选择.
nm1 = NearMiss(random_state=0, version=1)
X_nm1, y_nm1 = nm1.fit_sample(X, y)
print Counter(y_rus)
#Cleaning under-sampling techniques
#TomekLinks : 样本x与样本y来自于不同的类别,满足以下条件,它们之间被称之为TomekLinks;不存在另外一个样本z,使得d(x,z)<d(x,y)或者 d(y,z)< d(x,y)成立.其中d(.)表示两个样本之间的距离,也就是说两个样本之间互为近邻关系.
#这个时候, 样本x或样本y很有可能是噪声数据, 或者两个样本在边界的位置附近.
#TomekLinks函数中的auto参数控制Tomek's links中的哪些样本被剔除. 默认的ratio='auto' 移除多数类的样本, 当ratio='all'时, 两个样本均被移除.
#EditedNearestNeighbours这种方法应用最近邻算法来编辑(edit)数据集, 找出那些与邻居不太友好的样本然后移除. 对于每一个要进行下采样的样本, 那些不满足一些准则的样本将会被移除;
#他们的绝大多数(kind_sel='mode')或者全部(kind_sel='all')的近邻样本都属于同一个类, 这些样本会被保留在数据集中.
enn = EditedNearestNeighbours(random_state=0)
renn = RepeatedEditedNearestNeighbours(random_state=0)
allknn = AllKNN(random_state=0)
#上采用与下采样的结合
#在之前的SMOTE方法中,当由边界的样本与其他样本进行过采样差值时,很容易生成一些噪音数据.因此,在过采样之后需要对样本进行清洗.
#这样,第三节中涉及到的TomekLink与 EditedNearestNeighbours方法就能实现上述的要求.
#所以就有了两种结合过采样与下采样的方法: (i) SMOTETomek and (ii) SMOTEENN.
smote_enn = SMOTEENN(random_state=0)
smote_tomek = SMOTETomek(random_state=0)
#Ensemble例子
#EasyEnsemble 有两个很重要的参数:(i)n_subsets 控制的是子集的个数(ii)replacement决定是有放回还是无放回的随机采样.
ee = EasyEnsemble(random_state=0,n_subsets=10,replacement=True)
X_ee, y_ee = ee.fit_sample(X, y)
print X_ee.shape
print Counter(y_ee[0])
#BalanceCascade(级联平衡)的方法通过使用分类器(estimator参数)来确保那些被错分类的样本在下一次进行子集选取的时候也能被采样到.
#同样,n_max_subset参数控制子集的个数,以及可以通过设置bootstrap=True来使用bootstraping(自助法).
bc = BalanceCascade(random_state=0,
estimator=LogisticRegression(random_state=0),
n_max_subset=4)
X_bc, y_bc = bc.fit_sample(X, y)
print X_bc.shape
print Counter(y_bc[0])
#在集成分类器中,装袋方法(Bagging)在不同的随机选取的数据集上建立了多个估计量.在scikit-learn中这个分类器叫做BaggingClassifier.
#然而,该分类器并不允许对每个数据集进行均衡.因此,在对不均衡样本进行训练的时候,分类器其实是有偏的,偏向于多数类.
#BalancedBaggingClassifier允许在训练每个基学习器之前对每个子集进行重抽样.简而言之,该方法结合了EasyEnsemble采样器与分类器(如BaggingClassifier)的结果.
bbc = BalancedBaggingClassifier(base_estimator=DecisionTreeClassifier(),
ratio='auto',
replacement=False,
random_state=0)
X_train,y_train,X_test,y_test=train_test_split(X,y)
bbc.fit(X_train, y)
y_pred = bbc.predict(X_test)
confusion_matrix(y_test, y_pred)
机器学习中不平衡学习方法总结二(实践)
最新推荐文章于 2024-03-13 11:36:11 发布