機(jī)器學(xué)習(xí)中的一個(gè)常見問(wèn)題是處理不平衡數(shù)據(jù),其中目標(biāo)類中比例嚴(yán)重失調(diào),存在高度不成比例的數(shù)據(jù)。如何處理多類不平衡數(shù)據(jù)呢?什么是多類不平衡數(shù)據(jù)?什么是SMOTE算法?為什么使用類別權(quán)重(Class weight)......下面將進(jìn)行詳細(xì)介紹。
什么是多類不平衡數(shù)據(jù)?
當(dāng)分類問(wèn)題的目標(biāo)類(兩個(gè)或兩個(gè)以上)不均勻分布時(shí),稱為不平衡數(shù)據(jù)。如果不能處理好這個(gè)問(wèn)題,模型將會(huì)成為災(zāi)難,因?yàn)槭褂妙惒黄胶鈹?shù)據(jù)建模會(huì)偏向于大多數(shù)類。處理不平衡數(shù)據(jù)有不同的方法,最常見的是過(guò)采樣(Oversampling)和創(chuàng)建合成樣本。
什么是SMOTE算法?
SMOTE是一種從數(shù)據(jù)集生成合成算例的過(guò)采樣技術(shù),它提高了對(duì)少數(shù)類的預(yù)測(cè)能力。雖然沒有信息損失,但它有一些限制。
合成樣本
限制:
· SMOTE不適用于高維數(shù)據(jù)。
· 可能會(huì)發(fā)生類的重疊,并給數(shù)據(jù)帶來(lái)更多干擾。
因此,為了跳過(guò)這個(gè)問(wèn)題,可以使用'class_weight '參數(shù)手動(dòng)為類分配權(quán)重。
為什么使用類別權(quán)重(Class weight)?
類別權(quán)重通過(guò)對(duì)具有不同權(quán)重的類進(jìn)行懲罰來(lái)直接修改損失函數(shù),有目的地增加少數(shù)階級(jí)的權(quán)力,減少多數(shù)階級(jí)的權(quán)力。因此,它比SMOTE效果更好。本文將介紹一些最受歡迎的獲得數(shù)據(jù)的權(quán)重的技術(shù),它們對(duì)不平衡學(xué)習(xí)問(wèn)題十分奏效。
· Sklearn utils
可以使用sklearn來(lái)獲得和計(jì)算類權(quán)重。在訓(xùn)練模型的同時(shí)將這些權(quán)重加入到少數(shù)類別中,可以提高類別的分類性能。
from sklearn.utils import class_weightclass_weight =class_weight.compute_class_weight('balanced,np.unique(target_Y),target_Y)model = LogisticRegression(class_weight = class_weight)model.fit(X,target_Y)# ['balanced', 'calculated balanced', 'normalized'] arehyperpaameterswhic we can play with.
對(duì)于幾乎所有的分類算法,從邏輯回歸到Catboost,都有一個(gè)class_weight參數(shù)。但是XGboost對(duì)二進(jìn)制分類使用scale_pos_weight,對(duì)二進(jìn)制和多類問(wèn)題使用樣本權(quán)重。
· 數(shù)長(zhǎng)比
非常簡(jiǎn)單明了,用行數(shù)除以每個(gè)類的計(jì)數(shù)數(shù),然后
weights = df[target_Y].value_counts()/len(df)model = LGBMClassifier(class_weight = weights)model.fit(X,target_Y)
· 平和權(quán)重技術(shù)(Smoothen Weights)
這是選擇權(quán)重的最佳方法之一。labels_dict是包含每個(gè)類的計(jì)數(shù)的字典對(duì)象,對(duì)數(shù)函數(shù)對(duì)不平衡類的權(quán)重進(jìn)行平和處理。
def class_weight(labels_dict,mu=0.15): total = np.sum(labels_dict.values()) keys = labels_dict.keys() weight = dict()for i in keys: score =np.log(mu*total/float(labels_dict[i])) weight[i] = score if score > 1else 1return weight# random labels_dictlabels_dict = df[target_Y].value_counts().to_dict()weights =class_weight(labels_dict)model = RandomForestClassifier(class_weight = weights)model.fit(X,target_Y)
· 樣本權(quán)重策略
下面的函數(shù)不同于用于為XGboost算法獲取樣本權(quán)重的class_weight參數(shù)。它為每個(gè)訓(xùn)練樣本返回不同的權(quán)重。樣本權(quán)重是一個(gè)與數(shù)據(jù)長(zhǎng)度相同的數(shù)組,包含應(yīng)用于每個(gè)樣本的模型損失的權(quán)重。
def BalancedSampleWeights(y_train,class_weight_coef): classes = np.unique(y_train, axis =0)classes.sort()class_samples = np.bincount(y_train)total_samples = class_samples.sum()n_classes = len(class_samples) weights = total_samples / (n_classes* class_samples * 1.0)class_weight_dict = {key : value for (key, value) in zip(classes, weights)}class_weight_dict[classes[1]] = class_weight_dict[classes[1]] *class_weight_coefsample_weights = [class_weight_dict[i] for i in y_train] return sample_weights#Usageweight=BalancedSampleWeights(target_Y,class_weight_coef)model = XGBClassifier(sample_weight = weight)model.fit(X, target_Y)
· 類權(quán)重與樣本權(quán)重:
樣本權(quán)重用于為每個(gè)訓(xùn)練樣本提供權(quán)重,這意味著應(yīng)該傳遞一個(gè)一維數(shù)組,其元素?cái)?shù)量與訓(xùn)練樣本完全相同。類權(quán)重用于為每個(gè)目標(biāo)類提供權(quán)重,這意味著應(yīng)該為要分類的每個(gè)類傳遞一個(gè)權(quán)重。
更多關(guān)于大數(shù)據(jù)培訓(xùn)的問(wèn)題,歡迎咨詢千鋒教育在線名師。千鋒教育擁有多年IT培訓(xùn)服務(wù)經(jīng)驗(yàn),采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,擁有國(guó)內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),助力更多學(xué)員實(shí)現(xiàn)高薪夢(mèng)想。