python數據預處理 :樣本分布不均的解決(過采樣和欠采樣)
何為樣本分布不均:
樣本分布不均衡就是指樣本差異非常大,例如共1000條數據樣本的數據集中,其中占有10條樣本分類,其特征無論如何你和也無法實現完整特征值的覆蓋,此時屬于嚴重的樣本分布不均衡。
為何要解決樣本分布不均:
樣本分部不均衡的數據集也是很常見的:比如惡意刷單、黃牛訂單、信用卡欺詐、電力竊電、設備故障、大企業客戶流失等。
樣本不均衡將導致樣本量少的分類所包含的特征過少,很難從中提取規律,即使得到分類模型,也容易產生過度依賴于有限的數量樣本而導致過擬合問題,當模型應用到新的數據上時,模型的準確性和健壯性將會很差。
樣本分布不均的解決方法:
過采樣 通過增加分類中樣本較少的類別的采樣數量來實現平衡,最直接的方法是簡單復制小樣本數據,缺點是如果特征少,會導致過擬合的問題。經過改進的過抽樣方法通過在少數類中加入隨機噪聲、干擾數據或通過一定規則產生新的合成樣本。
欠采樣 通過減少分類中多數類樣本的數量來實現樣本均衡,最直接的方法是隨機去掉一些多數類樣本來減小多數類的規模,缺點是會丟失多數類中的一些重要信息。
設置權重 對不同樣本數量的類別賦予不同的權重(通常會設置為與樣本量成反比)
集成方法 每次生成訓練集時使用所有分類中的小樣本量,同時從分類中的大樣本量中隨機抽取數據來與小樣本量合并構成訓練集,這樣反復多次會得到很多訓練集和訓練模型。最后在應用時,使用組合方法(例如投票、加權投票等)產生分類預測結果。這種方法類似于隨機森林。缺點是,比較吃計算資源,費時。
python代碼:
# 生成不平衡分類數據集from collections import Counterfrom sklearn.datasets import make_classificationX, y = make_classification(n_samples=3000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=3, n_clusters_per_class=1, weights=[0.1, 0.05, 0.85], class_sep=0.8, random_state=2018)Counter(y)# Counter({2: 2532, 1: 163, 0: 305})# 使用RandomOverSampler從少數類的樣本中進行隨機采樣來增加新的樣本使各個分類均衡from imblearn.over_sampling import RandomOverSampler ros = RandomOverSampler(random_state=0)X_resampled, y_resampled = ros.fit_sample(X, y)sorted(Counter(y_resampled).items())# [(0, 2532), (1, 2532), (2, 2532)]# SMOTE: 對于少數類樣本a, 隨機選擇一個最近鄰的樣本b, 然后從a與b的連線上隨機選取一個點c作為新的少數類樣本from imblearn.over_sampling import SMOTE X_resampled_smote, y_resampled_smote = SMOTE().fit_sample(X, y) sorted(Counter(y_resampled_smote).items())# [(0, 2532), (1, 2532), (2, 2532)]# ADASYN: 關注的是在那些基于K最近鄰分類器被錯誤分類的原始樣本附近生成新的少數類樣本from imblearn.over_sampling import ADASYNX_resampled_adasyn, y_resampled_adasyn = ADASYN().fit_sample(X, y) sorted(Counter(y_resampled_adasyn).items())# [(0, 2522), (1, 2520), (2, 2532)]# RandomUnderSampler函數是一種快速并十分簡單的方式來平衡各個類別的數據: 隨機選取數據的子集.from imblearn.under_sampling import RandomUnderSamplerrus = RandomUnderSampler(random_state=0)X_resampled, y_resampled = rus.fit_sample(X, y) sorted(Counter(y_resampled).items())# [(0, 163), (1, 163), (2, 163)]# 在之前的SMOTE方法中, 當由邊界的樣本與其他樣本進行過采樣差值時, 很容易生成一些噪音數據. 因此, 在過采樣之后需要對樣本進行清洗. # 這樣TomekLink 與 EditedNearestNeighbours方法就能實現上述的要求.from imblearn.combine import SMOTEENNsmote_enn = SMOTEENN(random_state=0)X_resampled, y_resampled = smote_enn.fit_sample(X, y) sorted(Counter(y_resampled).items())# [(0, 2111), (1, 2099), (2, 1893)]from imblearn.combine import SMOTETomeksmote_tomek = SMOTETomek(random_state=0)X_resampled, y_resampled = smote_tomek.fit_sample(X, y) sorted(Counter(y_resampled).items())# [(0, 2412), (1, 2414), (2, 2396)]# 使用SVM的權重調節處理不均衡樣本 權重為balanced 意味著權重為各分類數據量的反比from sklearn.svm import SVC svm_model = SVC(class_weight=’balanced’)svm_model.fit(X, y)# # EasyEnsemble 通過對原始的數據集進行隨機下采樣實現對數據集進行集成.# EasyEnsemble 有兩個很重要的參數: (i) n_subsets 控制的是子集的個數 and (ii) replacement 決定是有放回還是無放回的隨機采樣.from imblearn.ensemble import EasyEnsembleee = EasyEnsemble(random_state=0, n_subsets=10)X_resampled, y_resampled = ee.fit_sample(X, y)sorted(Counter(y_resampled[0]).items())# [(0, 163), (1, 163), (2, 163)]# BalanceCascade(級聯平衡)的方法通過使用分類器(estimator參數)來確保那些被錯分類的樣本在下一次進行子集選取的時候也能被采樣到. 同樣, n_max_subset 參數控制子集的個數, 以及可以通過設置bootstrap=True來使用bootstraping(自助法).from imblearn.ensemble import BalanceCascadefrom sklearn.linear_model import LogisticRegressionbc = BalanceCascade(random_state=0, estimator=LogisticRegression(random_state=0), n_max_subset=4)X_resampled, y_resampled = bc.fit_sample(X, y) sorted(Counter(y_resampled[0]).items())# [(0, 163), (1, 163), (2, 163)]# BalancedBaggingClassifier 允許在訓練每個基學習器之前對每個子集進行重抽樣. 簡而言之, 該方法結合了EasyEnsemble采樣器與分類器(如BaggingClassifier)的結果.from sklearn.tree import DecisionTreeClassifierfrom imblearn.ensemble import BalancedBaggingClassifierbbc = BalancedBaggingClassifier(base_estimator=DecisionTreeClassifier(),ratio=’auto’,replacement=False,random_state=0)bbc.fit(X, y)
以上這篇python數據預處理 :樣本分布不均的解決(過采樣和欠采樣)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。
相關文章:
