日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

sklearn中多种编码方式——category_encoders(one-hot多种用法)

發(fā)布時(shí)間:2023/12/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sklearn中多种编码方式——category_encoders(one-hot多种用法) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 1 Ordinal Encoding 序數(shù)編碼
  • 2 One-hot Encoding 獨(dú)熱編碼
  • 3 Target Encoding 目標(biāo)編碼
  • 4 BinaryEncoder 編碼
  • 5 CatBoostEncoder編碼
  • 6 WOEEncoder編碼
  • 9 效果對(duì)比與使用心得
  • 額外:10 用pandas的get_dummies進(jìn)行one-hot
  • 額外:11 文本one_hot的方式


離散型編碼的Python庫(kù),里面封裝了十幾種(包括文中的所有方法)對(duì)于離散型特征的編碼方法,接口接近于Sklearn通用接口,非常實(shí)用
可以使用多種不同的編碼技術(shù)把類別變量轉(zhuǎn)換為數(shù)值型變量,并且符合sklearn模式的轉(zhuǎn)換。

  • 官方github:https://github.com/scikit-learn-contrib/category_encoders
  • 官方文檔:http://contrib.scikit-learn.org/category_encoders/#

這個(gè)庫(kù)的作者將類別編碼分為兩類,無(wú)監(jiān)督和有監(jiān)督(指用target)

Unsupervised:

Backward Difference Contrast BaseN Binary Count Hashing Helmert Contrast Ordinal One-Hot Polynomial Contrast Sum Contrast

Supervised:

CatBoost James-Stein Estimator LeaveOneOut M-estimator Target Encoding Weight of Evidence

無(wú)監(jiān)督中有很大一部分是線性模型/回歸模型用的對(duì)比編碼,有監(jiān)督主要是目標(biāo)編碼和WOE(Weight of Evidence)
利用標(biāo)簽進(jìn)行特征編碼是存在特征穿越的風(fēng)險(xiǎn)的,只不過(guò)很多時(shí)候影響并不大,不會(huì)出現(xiàn)極端的情況,利用標(biāo)簽進(jìn)行特征編碼例如target encoding、woe encoding或者是catboost encoding本質(zhì)上都是利用類別和標(biāo)簽之間的某種統(tǒng)計(jì)特征來(lái)代替原始的類別,從而使得無(wú)法直接處理類別的模型可以在編碼后的結(jié)果上正常運(yùn)行。
woe編碼的穿越問(wèn)題


文章目錄

  • 1 Ordinal Encoding 序數(shù)編碼
  • 2 One-hot Encoding 獨(dú)熱編碼
  • 3 Target Encoding 目標(biāo)編碼
  • 4 BinaryEncoder 編碼
  • 5 CatBoostEncoder編碼
  • 6 WOEEncoder編碼
  • 9 效果對(duì)比與使用心得
  • 額外:10 用pandas的get_dummies進(jìn)行one-hot
  • 額外:11 文本one_hot的方式


1 Ordinal Encoding 序數(shù)編碼

專欄 | 基于 Jupyter 的特征工程手冊(cè):數(shù)據(jù)預(yù)處理(二)
feature-engineering-handbook/中文版/

這個(gè)編碼方式非常容易理解,就是把所有的相同類別的特征編碼成同一個(gè)值,例如女=0,男=1,狗狗=2,所以最后編碼的特征值是在[0, n-1]之間的整數(shù)。

這個(gè)編碼的缺點(diǎn)在于它隨機(jī)的給特征排序了,會(huì)給這個(gè)特征增加不存在的順序關(guān)系,也就是增加了噪聲。假設(shè)預(yù)測(cè)的目標(biāo)是購(gòu)買力,那么真實(shí)Label的排序顯然是 女 > 狗狗 > 男,與我們編碼后特征的順序不存在相關(guān)性。

import numpy as np import pandas as pd from category_encoders import OrdinalEncoder # category_encoders 直接支持dataframe# 隨機(jī)生成一些訓(xùn)練集 train_set = pd.DataFrame(np.array([['male',10],['female', 20], ['male',10], ['female',20],['female',15]]),columns = ['Sex','Type']) train_y = np.array([False, True, True, False, False])# 隨機(jī)生成一些測(cè)試集, 并有意讓其包含未在訓(xùn)練集出現(xiàn)過(guò)的類別與缺失值 test_set = pd.DataFrame(np.array([['female',20],['male', 20], ['others',15], ['male',20],['female',40], ['male', 25]]),columns = ['Sex','Type']) test_set.loc[4,'Type'] = np.nanencoder = OrdinalEncoder(cols = ['Sex', 'Type'], handle_unknown = 'value', handle_missing = 'value').fit(train_set,train_y) # 在訓(xùn)練集上訓(xùn)練 # 將 handle_unknown設(shè)為‘value’,即測(cè)試集中的未知特征值將被標(biāo)記為-1 # 將 handle_missing設(shè)為‘value’,即測(cè)試集中的缺失值將被標(biāo)記為-2 # 其他的選擇為:‘error’:即報(bào)錯(cuò);‘return_nan’:即未知值/缺失之被標(biāo)記為nan encoded_train = encoder.transform(train_set) # 轉(zhuǎn)換訓(xùn)練集 encoded_test = encoder.transform(test_set) # 轉(zhuǎn)換測(cè)試集# 以測(cè)試集結(jié)果為例 encoded_test# 在序數(shù)編碼中:# 變量Sex中: 'male' => 1.0, 'female' => 2.0, 未知 => -1.0, 缺失值 => -2.0 # (事實(shí)上,測(cè)試集中完全有可能出現(xiàn)未知與缺失情況) # 在我們的例子中, Sex這一變量中的'other' 類別從未在訓(xùn)練集中出現(xiàn)過(guò)# 變量 Type 中: 10 => 1.0, 20 => 2.0, 15 => 3.0, 未知 => -1.0, 缺失值 => -2.0


變成序列化:

2 One-hot Encoding 獨(dú)熱編碼

專欄 | 基于 Jupyter 的特征工程手冊(cè):數(shù)據(jù)預(yù)處理(二)
feature-engineering-handbook/中文版/

大家熟知的OneHot方法就避免了對(duì)特征排序的缺點(diǎn)。對(duì)于一列有N種取值的特征,Onehot方法會(huì)創(chuàng)建出對(duì)應(yīng)的N列特征,其中每列代表該樣本是否為該特征的某一種取值。因?yàn)樯傻拿恳涣杏兄档亩际?,所以這個(gè)方法起名為Onehot特征。Dummy特征也是一樣,只是少了一列,因?yàn)榈贜列可以看做是前N-1列的線性組合。但是在離散特征的特征值過(guò)多的時(shí)候不宜使用,因?yàn)闀?huì)導(dǎo)致生成特征的數(shù)量太多且過(guò)于稀疏。

Scikit-learn中也提供來(lái)獨(dú)熱編碼函數(shù),其可以將具有n_categories個(gè)可能值的一個(gè)分類特征轉(zhuǎn)換為n_categories個(gè)二進(jìn)制特征,其中一個(gè)為1,所有其他為0在category_encoders中,它包含了附加功能,即指示缺失或未知的值。在這里,我們繼續(xù)使用category_encoders

import numpy as np import pandas as pd from category_encoders import OneHotEncoder # category_encoders 直接支持dataframe# 隨機(jī)生成一些訓(xùn)練集 train_set = pd.DataFrame(np.array([['male',10],['female', 20], ['male',10], ['female',20],['female',15]]),columns = ['Sex','Type']) train_y = np.array([False, True, True, False, False])# 隨機(jī)生成一些測(cè)試集, 并有意讓其包含未在訓(xùn)練集出現(xiàn)過(guò)的類別與缺失值 test_set = pd.DataFrame(np.array([['female',20],['male', 20], ['others',15], ['male',20],['female',40], ['male', 25]]),columns = ['Sex','Type']) test_set.loc[4,'Type'] = np.nanencoder = OneHotEncoder(cols=['Sex', 'Type'], handle_unknown='indicator', handle_missing='indicator', use_cat_names=True).fit(train_set,train_y) # 在訓(xùn)練集上訓(xùn)練 encoded_train = encoder.transform(train_set) # 轉(zhuǎn)換訓(xùn)練集 encoded_test = encoder.transform(test_set) # 轉(zhuǎn)換測(cè)試集 # 將 handle_unknown設(shè)為‘indicator’,即會(huì)新增一列指示未知特征值 # 將 handle_missing設(shè)為‘indicator’,即會(huì)新增一列指示缺失值 # 其他的handle_unknown/handle_missing 的選擇為: # ‘error’:即報(bào)錯(cuò); ‘return_nan’:即未知值/缺失之被標(biāo)記為nan; ‘value’:即未知值/缺失之被標(biāo)記為0# 以測(cè)試集結(jié)果為例 encoded_test# 在獨(dú)熱編碼中:# 變量 Sex => 變?yōu)榱?個(gè)新變量: 'male' => [1 ,0 ,0, 0]; # 'female' => [0 ,1 ,0, 0]; # 未知 => [0 ,0 ,0, 1]; # 缺失 => [0, 0, 1, 0];# 變量 Type => 變?yōu)榱?個(gè)新變量: 10 => [1, 0, 0, 0, 0]; # 20 => [0, 1, 0, 0, 0];, # 15 => [0, 0, 1, 0, 0]; # 未知 => [0, 0, 0, 0, 1]; # 缺失 => [0, 0, 0, 1, 0];


變成了:

3 Target Encoding 目標(biāo)編碼

專欄 | 基于 Jupyter 的特征工程手冊(cè):數(shù)據(jù)預(yù)處理(二)
feature-engineering-handbook/中文版/

目標(biāo)編碼是一種不僅基于特征值本身,還基于相應(yīng)因變量的類別變量編碼方法。對(duì)于分類問(wèn)題:將類別特征替換為給定某一特定類別值的因變量后驗(yàn)概率與所有訓(xùn)練數(shù)據(jù)上因變量的先驗(yàn)概率的組合。對(duì)于連續(xù)目標(biāo):將類別特征替換為給定某一特定類別值的因變量目標(biāo)期望值與所有訓(xùn)練數(shù)據(jù)上因變量的目標(biāo)期望值的組合。該方法嚴(yán)重依賴于因變量的分布,但這大大減少了生成編碼后特征的數(shù)量。

公式:

其中min_samples_leaf和smoothing是用戶定義的參數(shù);
min_samples_leaf:計(jì)算類別平均值時(shí)的最小樣本數(shù)(即若該類別出現(xiàn)次數(shù)少,則將被忽略),用以控制過(guò)擬合;
smoothing:平衡分類平均值與先驗(yàn)平均值的平滑系數(shù)。其值越高,則正則化越強(qiáng);
′ 是類別特征X中類別為k的編碼值;
Prior Prob:目標(biāo)變量的先驗(yàn)概率/期望;
n:類別特征X中,類別為k的樣本數(shù);
+:不僅在類別特征X中具有類別k,而且具有正結(jié)果的樣本數(shù)(分類問(wèn)題);

參考文獻(xiàn): Micci-Barreca, D. (2001). A preprocessing scheme for high-cardinality categorical attributes in classification and prediction problems. ACM SIGKDD Explorations Newsletter, 3(1), 27-32.

import numpy as np import pandas as pd from category_encoders.target_encoder import TargetEncoder # category_encoders 直接支持dataframe# 隨機(jī)生成一些訓(xùn)練集 train_set = pd.DataFrame(np.array([['male',10],['female', 20], ['male',10], ['female',20],['female',15]]),columns = ['Sex','Type']) train_y = np.array([False, True, True, False, False])# 隨機(jī)生成一些測(cè)試集, 并有意讓其包含未在訓(xùn)練集出現(xiàn)過(guò)的類別與缺失值 test_set = pd.DataFrame(np.array([['female',20],['male', 20], ['others',15], ['male',20],['female',40], ['male', 25]]),columns = ['Sex','Type']) test_set.loc[4,'Type'] = np.nanencoder = TargetEncoder(cols=['Sex','Type'], handle_unknown='value', handle_missing='value').fit(train_set,train_y) # 在訓(xùn)練集上訓(xùn)練 encoded_train = encoder.transform(train_set) # 轉(zhuǎn)換訓(xùn)練集 encoded_test = encoder.transform(test_set) # 轉(zhuǎn)換測(cè)試集# handle_unknown 和 handle_missing 被設(shè)定為 'value' # 在目標(biāo)編碼中,handle_unknown 和 handle_missing 僅接受 ‘error’, ‘return_nan’ 及 ‘value’ 設(shè)定 # 兩者的默認(rèn)值均為 ‘value’, 即對(duì)未知類別或缺失值填充訓(xùn)練集的因變量平均值encoded_test # 編碼后的變量數(shù)與原類別變量數(shù)一致


到了:

# 驗(yàn)證一下計(jì)算的結(jié)果,在測(cè)試集中,‘male’類別的編碼值為 0.473106 prior = train_y.mean() # 先驗(yàn)概率 min_samples_leaf = 1.0 # 默認(rèn)為1.0 smoothing = 1.0 # 默認(rèn)為1.0 n = 2 # 訓(xùn)練集中,兩個(gè)樣本包含‘male’這個(gè)標(biāo)簽 n_positive = 1 # 在訓(xùn)練集中,這兩個(gè)包含‘male’標(biāo)簽的樣本中僅有一個(gè)有正的因變量標(biāo)簽= 1 / (1 + np.exp(-(n - min_samples_leaf) / smoothing)) male_encode = prior * (1- ) + * n_positive/n male_encode # return 0.4731058578630005,與要驗(yàn)證的值吻合

0.4731058578630005

4 BinaryEncoder 編碼

# 相關(guān)模塊加載 import pandas as pd import category_encoders as ce# 準(zhǔn)備數(shù)據(jù) df = pd.DataFrame({'ID':[1,2,3,4,5,6],'RATING':['G','B','G','B','B','G']})# 使用binary編碼的方式來(lái)編碼類別變量 encoder = ce.BinaryEncoder(cols=['RATING']).fit(df)# 轉(zhuǎn)換數(shù)據(jù) numeric_dataset = encoder.transform(df)df # 轉(zhuǎn)換前的數(shù)據(jù)


到:

5 CatBoostEncoder編碼

這個(gè)跟CatBoost一致,是Catboost中的encode方法,這個(gè)方法據(jù)說(shuō)效果非常好,而且可以避免過(guò)擬合,可能有些復(fù)雜

import pandas as pd import numpy as np #from unittest import TestCase # or `from unittest import ...` if on Python 3.4+import category_encoders as encodersX = pd.DataFrame({'col1': ['A', 'B', 'B', 'C', 'A']}) y = pd.Series([1, 0, 1, 0, 1]) enc = encoders.CatBoostEncoder() obtained = enc.fit_transform(X, y) obtained# For testing set, use statistics calculated on all the training data. # See: CatBoost: unbiased boosting with categorical features, page 4. X_t = pd.DataFrame({'col1': ['B', 'B', 'A']}) obtained = enc.transform(X_t) obtained

本來(lái):

現(xiàn)在:

col1 0 0.6 1 0.6 2 0.3 3 0.6 4 0.8

其他案例(github):

X = pd.DataFrame({'col1': ['fuzzy', 'soft', 'smooth', 'fuzzy', 'smooth', 'soft', 'smooth', 'smooth']}) y = pd.Series([4, 1, 4, 3, 6, 0, 7, 5]) enc = encoders.CatBoostEncoder() obtained = enc.fit_transform(X, y) prior = 30./8

6 WOEEncoder編碼

【數(shù)據(jù)建模 WOE編碼】WOE(weight of evidence, 證據(jù)權(quán)重)
一種有監(jiān)督的編碼方式,將預(yù)測(cè)類別的集中度的屬性作為編碼的數(shù)值

  • 優(yōu)勢(shì)
      將特征的值規(guī)范到相近的尺度上。
      (經(jīng)驗(yàn)上講,WOE的絕對(duì)值波動(dòng)范圍在0.1~3之間)。
      具有業(yè)務(wù)含義。
  • 缺點(diǎn)
      需要每箱中同時(shí)包含好、壞兩個(gè)類別。

當(dāng)然也會(huì)出現(xiàn)標(biāo)簽穿越的問(wèn)題:woe編碼的穿越問(wèn)題

X = ['a', 'a', 'b', 'b'] y = [1, 0, 0, 0] enc = encoders.WOEEncoder()result = enc.fit_transform(X, y) 從: (['a', 'a', 'b', 'b'], [1, 0, 0, 0])變成:0 0 0.510826 1 0.510826 2 -0.587787 3 -0.587787

案例二:

cols = ['unique_str', 'underscore', 'extra', 'none', 'invariant', 321, 'categorical', 'na_categorical', 'categorical_int']# balanced label with balanced features X_balanced = pd.DataFrame(data=['1', '1', '1', '2', '2', '2'], columns=['col1']) y_balanced = [True, False, True, False, True, False] enc = encoders.WOEEncoder() enc.fit(X_balanced, y_balanced) X1 = enc.transform(X_balanced)

9 效果對(duì)比與使用心得

11種離散型變量編碼方式及效果對(duì)比
語(yǔ)雀文檔

數(shù)據(jù)集使用了八個(gè)存在離散型變量的數(shù)據(jù)集,最后的結(jié)果加權(quán)如下:

不使用交叉驗(yàn)證的情況:

HelmertEncoder 0.9517 SumEncoder 0.9434 FrequencyEncoder 0.9176 CatBoostEncoder 0.5728 TargetEncoder 0.5174 JamesSteinEncoder 0.5162 OrdinalEncoder 0.4964 WOEEncoder 0.4905 MEstimateEncoder 0.4501 BackwardDifferenceEncode0.4128 LeaveOneOutEncoder 0.0697

使用交叉驗(yàn)證的情況:

CatBoostEncoder 0.9726 OrdinalEncoder 0.9694 HelmertEncoder 0.9558 SumEncoder 0.9434 WOEEncoder 0.9326 FrequencyEncoder 0.9315 BackwardDifferenceEncode0.9108 TargetEncoder 0.8915 JamesSteinEncoder 0.8555 MEstimateEncoder 0.8189 LeaveOneOutEncoder 0.0729

下面是Kaggle上大佬們給出的一些建議,具體原因尚未分析,希望有大神在評(píng)論區(qū)可以給出解釋。

對(duì)于無(wú)序的離散特征,實(shí)戰(zhàn)中使用 OneHot, Hashing, LeaveOneOut, and Target encoding 方法效果較好,但是使用OneHot時(shí)要避免高基類別的特征以及基于決策樹(shù)的模型,理由如下圖所示。

但是在實(shí)戰(zhàn)中,我發(fā)現(xiàn)使用Xgboost處理高維稀疏的問(wèn)題效果并不會(huì)很差。例如在IJCAI-18商鋪中用戶定位比賽中,一個(gè)很好的baseline就是把高維稀疏的wifi信號(hào)向量直接當(dāng)做特征放到Xgboost里面,也可以獲得很好的預(yù)測(cè)結(jié)果。不知道是不是因?yàn)閄gboost對(duì)于稀疏特征的優(yōu)化導(dǎo)致。

  • 對(duì)于有序離散特征,嘗試 Ordinal (Integer), Binary, OneHot, LeaveOneOut, and Target. Helmert, Sum, BackwardDifference and Polynomial 基本沒(méi)啥用,但是當(dāng)你有確切的原因或者對(duì)于業(yè)務(wù)的理解的話,可以進(jìn)行嘗試。
  • 對(duì)于回歸問(wèn)題而言,Target 與 LeaveOneOut 方法可能不會(huì)有比較好的效果。
    LeaveOneOut、 WeightOfEvidence、 James-Stein、M-estimator 適合用來(lái)處理高基數(shù)特征。Helmert、 Sum、 Backward Difference、 Polynomial 在機(jī)器學(xué)習(xí)問(wèn)題里的效果往往不是很好(過(guò)擬合的原因)

額外:10 用pandas的get_dummies進(jìn)行one-hot

參考:pandas.get_dummies 的用法
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False)

import pandas as pd df = pd.DataFrame([ ['green' , 'A'], ['red' , 'B'], ['blue' , 'A']]) df.columns = ['color', 'class'] pd.get_dummies(df)

get_dummies 前:

get_dummies 后:

上述執(zhí)行完以后再打印df 出來(lái)的還是get_dummies 前的圖,因?yàn)槟銢](méi)有寫(xiě)
df = pd.get_dummies(df)

可以對(duì)指定列進(jìn)行g(shù)et_dummies
pd.get_dummies(df.color)

額外:11 文本one_hot的方式

from sklearn.feature_extraction.text import CountVectorizer #from sklearn.feature_extraction.text import TfidfTransformer import pandas as pddef text_one_hot(tag_list,prefix = ''):'''Parameters----------tag_list : TYPE常規(guī)分詞,以空格隔開(kāi).[['格式','不一定'],['空格','隔開(kāi)','常規(guī)']]prefix : TYPE, optional前綴. The default is ''.Returns-------data : TYPEdataframe,完整的TF的頻次.'''vectorizer = CountVectorizer() #將文本中的詞語(yǔ)轉(zhuǎn)換為詞頻矩陣 X = vectorizer.fit_transform(tag_list) #計(jì)算個(gè)詞語(yǔ)出現(xiàn)的次數(shù)data = pd.DataFrame(X.toarray(),columns = [prefix +'_'+ si for si in sorted(vectorizer.vocabulary_)])return datatag_list = ['青年 吃貨', '少年 游戲 叛逆', '少年 吃貨 足球'] data = text_one_hot(tag_list)

返回的結(jié)果是:

_叛逆 _吃貨 _少年 _游戲 _足球 _青年 0 0 1 0 0 0 1 1 1 0 1 1 0 0 2 0 1 1 0 1 0

總結(jié)

以上是生活随笔為你收集整理的sklearn中多种编码方式——category_encoders(one-hot多种用法)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。