溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python中怎么處理不平衡數(shù)據(jù)集

發(fā)布時(shí)間:2021-07-10 16:37:22 來(lái)源:億速云 閱讀:155 作者:Leah 欄目:編程語(yǔ)言

本篇文章給大家分享的是有關(guān)Python中怎么處理不平衡數(shù)據(jù)集,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

1. 什么是數(shù)據(jù)不平衡

所謂的數(shù)據(jù)不平衡(imbalanced data)是指數(shù)據(jù)集中各個(gè)類別的數(shù)量分布不均衡;不平衡數(shù)據(jù)在現(xiàn)實(shí)任務(wù)中十分的常見。如

  •  信用卡欺詐數(shù)據(jù):99%都是正常的數(shù)據(jù), 1%是欺詐數(shù)據(jù)

  •  貸款逾期數(shù)據(jù)

不平衡數(shù)據(jù)一般是由于數(shù)據(jù)產(chǎn)生的原因?qū)е碌模悇e少的樣本通常是發(fā)生的頻率低,需要很長(zhǎng)的周期進(jìn)行采集。

在機(jī)器學(xué)習(xí)任務(wù)(如分類問(wèn)題)中,不平衡數(shù)據(jù)會(huì)導(dǎo)致訓(xùn)練的模型預(yù)測(cè)的結(jié)果會(huì)偏向于樣本數(shù)量多的類別,這個(gè)時(shí)候除了要選擇合適的評(píng)估指標(biāo)外,想要提升模型的性能,就要對(duì)數(shù)據(jù)和模型做一些預(yù)處理。

處理數(shù)據(jù)不平衡的主要方法:

  •  欠采樣

  •  過(guò)采樣

  •  綜合采樣

  •  模型集成

  •  調(diào)整類別權(quán)重或者樣本權(quán)重

2. 數(shù)據(jù)不平衡處理方法

imbalanced-learn庫(kù)提供了許多不平衡數(shù)據(jù)處理的方法,本文的例子都以imbalanced-learn庫(kù)來(lái)實(shí)現(xiàn)。

pip install -U imbalanced-learn

https://github.com/scikit-learn-contrib/imbalanced-learn

本文例子的數(shù)據(jù)來(lái)自進(jìn)行中的比賽山東省第二屆數(shù)據(jù)應(yīng)用創(chuàng)新創(chuàng)業(yè)大賽-日照分賽場(chǎng)-公積金貸款逾期預(yù)測(cè)

先來(lái)看下數(shù)據(jù)

import pandas as pd  train_data = './data/train.csv'  test_data = './data/test.csv'  train_df = pd.read_csv(train_data)  test_df = pd.read_csv(test_data)  print(train_df.groupby(['label']).size())  # label為是否違約, 1為違約, 0為非違約  #     label  # 0    37243  # 1     2757

Python中怎么處理不平衡數(shù)據(jù)集

2.1 欠采樣

所謂欠采樣,就是將數(shù)量多類別(記為majority)的樣本進(jìn)行抽樣,使之?dāng)?shù)量與數(shù)量少的類別(minority)的數(shù)量相當(dāng),以此達(dá)到數(shù)量的平衡。

Python中怎么處理不平衡數(shù)據(jù)集

由于欠采樣是丟失了一部分?jǐn)?shù)據(jù),不可避免的使得數(shù)量多類別樣本的分布發(fā)生了變化(方差變大)。好的欠采樣策略應(yīng)該盡可能保持原有數(shù)據(jù)分布。

欠采樣是刪除majority的樣本,那哪些樣本可以刪除呢?

  •  一種是overlapping的數(shù)據(jù),就是多余的數(shù)據(jù)

  •  一種是干擾的數(shù)據(jù),干擾minority的分布

基于此,有兩種思路來(lái)欠采樣

  • 邊界相鄰匹配,考慮在近鄰空間內(nèi)刪除majority樣本,方法如TomekLinks, NearMiss

下面這張圖,展示6NN(6個(gè)最近鄰居)

Python中怎么處理不平衡數(shù)據(jù)集

這里重點(diǎn)講下TomekLinks, TomekLinks方法簡(jiǎn)單的說(shuō):對(duì)每一個(gè)minority樣本找1NN(最近的鄰居),如果最近的鄰居是majority, 就形成一個(gè)tome-links,該方法人為這個(gè)majority是干擾的,將它刪除。

Python中怎么處理不平衡數(shù)據(jù)集

from imblearn.under_sampling import TomekLinks  X_train = train_df.drop(['id', 'type'], axis=1)  y = train_df['label']  tl = TomekLinks()  X_us, y_us = tl.fit_sample(X_train, y)  print(X_us.groupby(['label']).size())  # label  # 0    36069  # 1     2757

從上可知, 有1174個(gè)tomek-link被刪除,好像刪除還不夠多,可以測(cè)試下是否對(duì)分類結(jié)果有幫助。需要注意的因?yàn)樾枰?jì)算最近鄰,所以樣本屬性必須數(shù)值屬性,或者可以轉(zhuǎn)化為數(shù)值屬性。

  •  聚類

        這類方法通過(guò)多個(gè)聚類,把原始樣本劃分成多個(gè)聚類簇,然后用每個(gè)聚類簇的中心來(lái)代替這個(gè)聚類簇的特性,完成采樣的目的。可知,這種采樣的樣本不是來(lái)自原始樣本集,而是聚類生成              的。 

from imblearn.under_sampling import ClusterCentroids       cc = ClusterCentroids(random_state=42)      X_res, y_res = cc.fit_resample(X_train, y)      X_res.groupby(['label']).size()      # label      # 0    2757      # 1    2757

im-balance提供的欠采樣的方法如下:

  •  Random majority under-sampling with replacement

  •  Extraction of majority-minority Tomek links

  •  Under-sampling with Cluster Centroids

  •  NearMiss-(1 & 2 & 3)

  •  Condensed Nearest Neighbour

  •  One-Sided Selection

  •  Neighboorhood Cleaning Rule

  •  Edited Nearest Neighbours

  •  Instance Hardness Threshold

  •  Repeated Edited Nearest Neighbours

  •  AllKNN

2.2 過(guò)采樣

所謂過(guò)采樣,就是將數(shù)量少的類別(minority)的樣本進(jìn)行copy,使之?dāng)?shù)量與數(shù)量多的類別(majortity)的數(shù)量相當(dāng),以此達(dá)到數(shù)量的平衡。由于復(fù)制了多份minoruty樣本,過(guò)采樣會(huì)改變minority方差。

Python中怎么處理不平衡數(shù)據(jù)集

過(guò)采樣一種簡(jiǎn)單的方式是隨機(jī)copy minority的樣本;另外一種是根據(jù)現(xiàn)有樣本生成人造樣本。這里介紹人造樣本的經(jīng)典算法SMOTE(Synthetic Minority Over-sampling Technique)。

SMOTE基于minority樣本相似的特征空間構(gòu)造新的人工樣本。步驟如下:

  •  選擇一個(gè)minority樣本,計(jì)算其KNN鄰居

  •  在K個(gè)鄰居中,隨機(jī)選擇一個(gè)近鄰

  •  修改某一個(gè)特征,偏移一定的大?。浩频拇笮樵搈inority樣本與該近鄰差距乘以一個(gè)小的隨機(jī)比率(0, 1), 就此生成新樣本

Python中怎么處理不平衡數(shù)據(jù)集

Python中怎么處理不平衡數(shù)據(jù)集

from imblearn.over_sampling import SMOTE  smote = SMOTE(k_neighbors=5, random_state=42)  X_res, y_res = smote.fit_resample(X_train, y)  X_res.groupby(['label']).size()  # label  # 0    37243  # 1    37243

對(duì)于SMOTE方法,對(duì)每一個(gè)minority都會(huì)構(gòu)造新樣本。但是并不總是這樣的,考慮下面A,B,C三個(gè)點(diǎn)。從數(shù)據(jù)分布來(lái)看,C點(diǎn)很可能是一個(gè)異常點(diǎn)(Noise),B點(diǎn)是正常分布的點(diǎn)(SAFE),而A點(diǎn)分布在邊界位置(DANGER);直觀上,對(duì)于C點(diǎn)我們不應(yīng)該去構(gòu)造新樣本,對(duì)B點(diǎn),構(gòu)造新樣本不會(huì)豐富minority類別的分布。只有A點(diǎn),如果構(gòu)造新樣本能夠使得A點(diǎn)從(DANGER)到(SAFE),加強(qiáng)minority類別的分類邊界。這個(gè)就是Borderline-SMOTE

Python中怎么處理不平衡數(shù)據(jù)集

from imblearn.over_sampling import BorderlineSMOTE  bsmote = BorderlineSMOTE(k_neighbors=5, random_state=42)  X_res, y_res = bsmote.fit_resample(X_train, y)  X_res.groupby(['label']).size()  # label  # 0    37243  # 1    37243

ADASYN方法從保持樣本分布的角度來(lái)確定生成數(shù)據(jù),生成數(shù)據(jù)的方式和SMOTE是一樣的,不同在于每個(gè)minortiy樣本生成樣本的數(shù)量不同。

  •  先確定要生成樣本的數(shù)量 beta為[0, 1]   

Python中怎么處理不平衡數(shù)據(jù)集

  •  對(duì)每個(gè)每個(gè)minortiy樣本,確定有它生成樣本的比例。先找出K最近鄰,計(jì)算K最近鄰中屬于majority的樣本比例(即分子),Z是歸一化因子,保證所有的minortiry的比例和為1,可以認(rèn)為是所有分子的和。  

Python中怎么處理不平衡數(shù)據(jù)集

  •  計(jì)算每個(gè)minortiy生成新樣本的數(shù)量

Python中怎么處理不平衡數(shù)據(jù)集

  •  按照SMOTE方式生成樣本 

from imblearn.over_sampling import ADASYN   adasyn = ADASYN(n_neighbors=5, random_state=42)  X_res, y_res = adasyn.fit_resample(X_train, y)  X_res.groupby(['label']).size()  # label  # 0    37243  # 1    36690

im-balance提供的過(guò)采樣的方法如下(包括SMOTE算法的變種):

  •  Random minority over-sampling with replacement

  •  SMOTE - Synthetic Minority Over-sampling Technique

  •  SMOTENC - SMOTE for Nominal Continuous

  •  bSMOTE(1 & 2) - Borderline SMOTE of types 1 and 2

  •  SVM SMOTE - Support Vectors SMOTE

  •  ADASYN - Adaptive synthetic sampling approach for imbalanced learning

  •  KMeans-SMOTE

  •  ROSE - Random OverSampling Examples

2.3 綜合采樣

過(guò)采樣是針對(duì)minority樣本,欠采樣是針對(duì)majority樣本;而綜合采樣是既對(duì)minority樣本,又對(duì)majority樣本,同時(shí)進(jìn)行操作的方法。主要有SMOTE+Tomek-links和SMOTE+Edited Nearest Neighbours。

綜合采樣的方法,是先進(jìn)行過(guò)采樣,在進(jìn)行欠采樣。

from imblearn.combine import SMOTETomek  smote_tomek = SMOTETomek(random_state=0)  X_res, y_res = smote_tomek.fit_sample(X_train, y)  X_res.groupby(['label']).size()  # label  # 0    36260  # 1    36260

2.4 模型集成

這里的模型集成主要體現(xiàn)在數(shù)據(jù)上,即用眾多平衡的數(shù)據(jù)集(majortiry的樣本進(jìn)行欠采樣加上minority樣本)訓(xùn)練多個(gè)模型,然后進(jìn)行集成。imblearn.ensemble提供幾種常見的模型集成算法,如BalancedRandomForestClassifier

from imblearn.ensemble import BalancedRandomForestClassifier  from sklearn.datasets import make_classification  X, y = make_classification(n_samples=1000, n_classes=3,                             n_informative=4, weights=[0.2, 0.3, 0.5],                             random_state=0)  clf = BalancedRandomForestClassifier(max_depth=2, random_state=0)  clf.fit(X, y)    print(clf.feature_importances_)    print(clf.predict([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]))

im-balance提供的模型集成的方法如下

  •  Easy Ensemble classifier

  •  Balanced Random Forest

  •  Balanced Bagging

  •  RUSBoost

2.5 調(diào)整類別權(quán)重或者樣本權(quán)重

對(duì)于很多用梯度下降方法來(lái)學(xué)習(xí)(使得某個(gè)損失Loss最?。┑臋C(jī)器學(xué)習(xí)的方法,可以通過(guò)調(diào)整類別權(quán)重或樣本權(quán)重的方式,來(lái)一定程度上平衡不平衡數(shù)據(jù)。如gbdt模型lightgbm 中 class_weight

import lightgbm as lgb  clf = lgb.LGBMRegressor(num_leaves=31,                           min_child_samples= np.random.randint(20,25),                          max_depth=25,                          learning_rate=0.1,                           class_weight={0:1, 1:10},                          n_estimators=500,                           n_jobs=30)

以上就是Python中怎么處理不平衡數(shù)據(jù)集,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI