用Python處理不平衡數據集

2021-01-07 51CTO

1. 什麼是數據不平衡

所謂的數據不平衡(imbalanced data)是指數據集中各個類別的數量分布不均衡;不平衡數據在現實任務中十分的常見。如

 信用卡欺詐數據:99%都是正常的數據, 1%是欺詐數據  貸款逾期數據

不平衡數據一般是由於數據產生的原因導致的,類別少的樣本通常是發生的頻率低,需要很長的周期進行採集。

在機器學習任務(如分類問題)中,不平衡數據會導致訓練的模型預測的結果會偏向於樣本數量多的類別,這個時候除了要選擇合適的評估指標外,想要提升模型的性能,就要對數據和模型做一些預處理。

處理數據不平衡的主要方法:

 欠採樣  過採樣  綜合採樣  模型集成  調整類別權重或者樣本權重

2. 數據不平衡處理方法

imbalanced-learn庫提供了許多不平衡數據處理的方法,本文的例子都以imbalanced-learn庫來實現。

pip install -U imbalanced-learn  

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

本文例子的數據來自進行中的比賽山東省第二屆數據應用創新創業大賽-日照分賽場-公積金貸款逾期預測

先來看下數據

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 

2.1 欠採樣

所謂欠採樣,就是將數量多類別(記為majority)的樣本進行抽樣,使之數量與數量少的類別(minority)的數量相當,以此達到數量的平衡。

由於欠採樣是丟失了一部分數據,不可避免的使得數量多類別樣本的分布發生了變化(方差變大)。好的欠採樣策略應該儘可能保持原有數據分布。

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

 一種是overlapping的數據,就是多餘的數據  一種是幹擾的數據,幹擾minority的分布

基於此,有兩種思路來欠採樣

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

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

這裡重點講下TomekLinks, TomekLinks方法簡單的說:對每一個minority樣本找1NN(最近的鄰居),如果最近的鄰居是majority, 就形成一個tome-links,該方法人為這個majority是幹擾的,將它刪除。

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個tomek-link被刪除,好像刪除還不夠多,可以測試下是否對分類結果有幫助。需要注意的因為需要計算最近鄰,所以樣本屬性必須數值屬性,或者可以轉化為數值屬性。

        這類方法通過多個聚類,把原始樣本劃分成多個聚類簇,然後用每個聚類簇的中心來代替這個聚類簇的特性,完成採樣的目的。可知,這種採樣的樣本不是來自原始樣本集,而是聚類生成              的。 

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 過採樣

所謂過採樣,就是將數量少的類別(minority)的樣本進行copy,使之數量與數量多的類別(majortity)的數量相當,以此達到數量的平衡。由於複製了多份minoruty樣本,過採樣會改變minority方差。

過採樣一種簡單的方式是隨機copy minority的樣本;另外一種是根據現有樣本生成人造樣本。這裡介紹人造樣本的經典算法SMOTE(Synthetic Minority Over-sampling Technique)。

SMOTE基於minority樣本相似的特徵空間構造新的人工樣本。步驟如下:

 選擇一個minority樣本,計算其KNN鄰居  在K個鄰居中,隨機選擇一個近鄰  修改某一個特徵,偏移一定的大小:偏移的大小為該minority樣本與該近鄰差距乘以一個小的隨機比率(0, 1), 就此生成新樣本

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 

對於SMOTE方法,對每一個minority都會構造新樣本。但是並不總是這樣的,考慮下面A,B,C三個點。從數據分布來看,C點很可能是一個異常點(Noise),B點是正常分布的點(SAFE),而A點分布在邊界位置(DANGER);直觀上,對於C點我們不應該去構造新樣本,對B點,構造新樣本不會豐富minority類別的分布。只有A點,如果構造新樣本能夠使得A點從(DANGER)到(SAFE),加強minority類別的分類邊界。這個就是Borderline-SMOTE

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方法從保持樣本分布的角度來確定生成數據,生成數據的方式和SMOTE是一樣的,不同在於每個minortiy樣本生成樣本的數量不同。

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

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提供的過採樣的方法如下(包括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 綜合採樣

過採樣是針對minority樣本,欠採樣是針對majority樣本;而綜合採樣是既對minority樣本,又對majority樣本,同時進行操作的方法。主要有SMOTE+Tomek-links和SMOTE+Edited Nearest Neighbours。

綜合採樣的方法,是先進行過採樣,在進行欠採樣。

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 模型集成

這裡的模型集成主要體現在數據上,即用眾多平衡的數據集(majortiry的樣本進行欠採樣加上minority樣本)訓練多個模型,然後進行集成。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 調整類別權重或者樣本權重

對於很多用梯度下降方法來學習(使得某個損失Loss最小)的機器學習的方法,可以通過調整類別權重或樣本權重的方式,來一定程度上平衡不平衡數據。如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) 

3. 總結

本文分享了常見的幾種處理不平衡數據集的方法,並且提供imbalanced-learn的簡單例子。總結如下:

 欠採樣: 減少majoritry樣本  過採樣:增加minority樣本  綜合採樣:先過採樣,在欠採樣  模型集成:製造平衡數據(majoritry樣本欠採樣+minority樣本),多次不同的欠採樣,訓練不同的模型,然後融合  不管是欠採樣和過採樣,都一定程度的改變了原始數據的分布,可能造成模型過擬合。需要去嘗試哪種方法,符合實際的數據分布。當然不一定有效果,去勇敢嘗試吧 just do it! 

【責任編輯:

龐桂玉

TEL:(010)68476606】

點讚 0

相關焦點

  • 一文教你如何處理不平衡數據集(附代碼)
    大數據文摘授權轉載自數據派THU分類是機器學習最常見的問題之一,處理它的最佳方法是從分析和探索數據集開始,即從探索式數據分析(Exploratory Data Analysis, EDA)開始。除了生成儘可能多的數據見解和信息,它還用於查找數據集中可能存在的任何問題。在分析用於分類的數據集時,類別不平衡是常見問題之一。
  • 特徵錦囊:如何在Python中處理不平衡數據
    今日錦囊特徵錦囊:如何在Python中處理不平衡數據🚙 Index1、到底什麼是不平衡數據2、處理不平衡數據的理論方法3、Python裡有什麼包可以處理不平衡樣本4、Python中具體如何處理失衡樣本印象中很久之前有位朋友說要我寫一篇如何處理不平衡數據的文章,整理相關的理論與實踐知識(可惜本人太懶了,現在才開始寫),於是乎有了今天的文章。
  • 【機器學習基礎】如何在Python中處理不平衡數據
    特徵錦囊:如何在Python中處理不平衡數據🚙 Index1、到底什麼是不平衡數據2、處理不平衡數據的理論方法3、Python裡有什麼包可以處理不平衡樣本4、Python中具體如何處理失衡樣本印象中很久之前有位朋友說要我寫一篇如何處理不平衡數據的文章,整理相關的理論與實踐知識(可惜本人太懶了,現在才開始寫),於是乎有了今天的文章。
  • 機器學習:處理不平衡數據的5個重要技術
    【IT168 技術】數據分布不平衡是機器學習工作流中的一個重要問題。所謂不平衡的數據集,意思就是兩個類中一個類的實例比另一個要高,換句話說,在一個分類數據集之中,所有類的觀察值的數量是不一樣的。這個問題不僅存在於二進位類數據中,也存在於多類數據中。  本文中將列出一些重要的技術,幫助您處理不平衡的數據。
  • Python數學建模技巧之pandas數據處理
    最常見的庫有進行矩陣運算的Numpy、進行數據處理的pandas、進行科學計算的Scipy、進行圖形繪製及科學可視化的matplotlib、進行符號計算的Sympy以及方便進行機器學習任務的Sklearn。由於今年美賽官方公告中稱,將會提前在賽題公布之前就提供下載C題數據集的方式。
  • 零基礎開始用Python處理Excel數據
    【曾賢志】從零基礎開始用Python處理Excel數據 – 第1季 基礎篇課程目標:首先學習Python的基礎知識,然後使用Python來控制Excel,做數據處理。適用人群:Excel使用者、Python愛好者、數據處理人員、辦公人員等講師介紹:曾賢志51CTO金牌講師課程簡介:第1章 python基礎
  • python數據處理 | 氣象數據的常用格式以及處理方法
    這次我們來簡單了解下氣象數據常用的格式以及處理的工具,常用的數據格式包括普通的二進位格式、文本數據、NetCDF、HDF4/5以及GRIB1/2數據。我們可以利用程式語言例如python、matlab以及c語言,根據數據的說明文檔或者相應的數據api開發文檔進行讀取,此外我們也可以根據提供的command命令行進行高效提取數據。
  • 【Python教程】用Python進行數據可視化
    下面我們就用上面這個簡單的數據集作為例子,展示用 Python 做出9種可視化效果,並附有相關代碼。Pandas 納入了大量庫和一些標準的數據模型,提供了高效地操作大型數據集所需的工具。Mapbox: 處理地理數據引擎更強的可視化工具庫geoplotlibcufflinks:a library for easy interactive Pandas charting with Plotly數據的可視化是表達信息的過程,在可視化化過程我們要思考:要處理多少變量?我們試圖畫出怎樣的圖像?
  • Kaggle影評數據集,Python數據分析小例子1-4
    1 了解數據數據來自kaggle,共包括三個文件:movies.dat包括三個欄位:['Movie ID', 'Movie Title
  • 樣本不平衡數據集防坑騙指南
    很多人總是會強調極端狀況下的數據不平衡,如醫療數據,犯罪數據等。但在實際中,更多的不平衡並不會顯得那麼極端。如果你關注過kaggle上的比賽冠軍的分享,你會發現觀察數據尤其是了解不平衡情況經常會是第一步(當然還會有其他的預處理和分析)。除了數據本身外,有些算法如決策樹,Logistic回歸等對數據的不平衡比較敏感,算法取向會明顯朝著數據量比較大的類。
  • python數據分析專題 (7):python數據分析模塊
    也就是這些python的擴展包讓python可以做數據分析,主要包括numpy,scipy,pandas,matplotlib,scikit-learn等等諸多強大的模塊,在結合上ipython交互工具 ,以及python強大的爬蟲數據獲取能力,字符串處理能力,讓python成為完整的數據分析工具。
  • 如何快速學會Python處理數據?(5000字走心總結)
    很多同學抱怨自己很想學好Python,但學了好久,書也買不少,視頻課程也看了不少,但是總是學了一段時間,感覺還是沒什麼收穫,碰到問題沒思路,有思路寫不出多少行代碼,遇到報錯時也不知道怎麼處理。從入門到放棄,這是很多學習python的同學常常掛在嘴邊上的口頭禪。
  • python數據分析萬字乾貨!一個數據集全方位解讀pandas
    說到python與數據分析,那肯定少不了pandas的身影,本文希望通過分析經典的NBA數據集來系統的全方位講解pandas包,建議搭配IDE一遍敲一邊讀哦。話不多說,開始吧!但是,如何確定數據集包含NBA的哪些統計數據?
  • 如何用Python增強Excel,減少處理複雜數據的痛苦?
    一個名為xlwings的python庫允許用戶通過VBA調用python腳本並在兩者之間傳遞數據。為什麼要將Python與ExcelVBA集成?事實上,用戶可以在VBA中做任何事情。所以,如果是這樣,為什麼要使用Python?嗯,有很多原因。
  • 通過隨機採樣和數據增強來解決數據不平衡的問題
    大多數用於分類的機器學習算法都是在假設平衡類的情況下開發的,然而,在現實生活中,擁有適當平衡的數據並不常見。因此,人們提出了各種方案來解決這個問題,以及一些應用這些解決方案的工具或者類庫。例如,imbalanced-learn 這個python庫,它實現了最相關的算法來解決類不平衡的問題。
  • 如何利用Python處理JSON格式的數據接口(詳細版)
    在網際網路公司,當我們需要其他團隊提供數據支持時,一般沒有團隊會直接給你一個資料庫或者數據表的權限,道理很簡單,一是數據安全性,二是增加自身工作量。通常情況下,提供一個數據接口,數據格式為JSON。本篇將對數據接口為JSON格式時,如何進行數據處理進行詳細的介紹,內容分如下兩個部分:JSON(JavaScript Object Notation, JS 對象簡譜)是一種輕量級的數據交換格式。它基於 ECMAScript的一個子集,採用完全獨立於程式語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得JSON成為理想的數據交換語言。
  • 小白數據分析——Python職位數據分析全鏈路
    數據採集巧婦難為無米之炊,我們做數據分析大部分情況是用公司的業務數據,因此就不需要關心數據採集的問題。然而我們自己業餘時間做的一些數據探索更多的需要自己採集數據,常用的數據採集技術就是爬蟲。因此,我們的分析思路就要按照他們所想看的去展開,而不能沒有章法的亂堆數據。2.0 大盤數據統計分析的數據一般都是按照數據粒度由粗到細展開的,粒度最粗的數據就是不加任何過濾條件、不按照任何維度拆分的數字。在我們的項目裡其實就是總職位數,上面我們也看到了 9715 個。
  • Python 網頁爬蟲 & 文本處理 & 科學計算 & 機器學習 & 數據挖掘兵器譜
    當然,這也僅僅是拋磚引玉,希望大家能提供更多的線索,來匯總整理一套Python網頁爬蟲,文本處理,科學計算,機器學習和數據挖掘的兵器譜。一、Python網頁爬蟲工具集一個真實的項目,一定是從獲取數據開始的。
  • 機器學習中不平衡數據集分類示例:乳腺鉬靶微鈣化攝影數據集分類
    一個典型的不平衡分類數據集是乳腺攝影數據集,這個數據集用於從放射掃描中檢測乳腺癌(特別是在乳腺攝影中出現明亮的微鈣化簇)。研究人員通過掃描圖像,對目標進行分割,然後用計算機視覺算法描述分割對象,從而獲得了這一數據集。由於類別不平衡十分嚴重,這是一個非常流行的不平衡分類數據集。
  • Python做數據分析-簡潔、易讀、強大
    由於python是一種解釋性語言,大部分編譯型語言都要比python代碼運行速度快,有些同學就因此鄙視python。但是python是一門高級語言,其生產效率更高,時間通常比CPU的時間值錢,因此為了權衡利弊,考慮用python是值得的。