1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        機(jī)器學(xué)習(xí)中類(lèi)別變量的編碼方法總結(jié)

        共 3725字,需瀏覽 8分鐘

         ·

        2020-09-25 01:50

        ?機(jī)器學(xué)習(xí)

        Author:louwill

        Machine Learning Lab


        ? ? ?在做結(jié)構(gòu)化數(shù)據(jù)訓(xùn)練時(shí),類(lèi)別特征是一個(gè)非常常見(jiàn)的變量類(lèi)型。機(jī)器學(xué)習(xí)中有多種類(lèi)別變量編碼方式,各種編碼方法都有各自的適用場(chǎng)景和特點(diǎn)。本文就對(duì)機(jī)器學(xué)習(xí)中常見(jiàn)的類(lèi)別編碼方式做一個(gè)簡(jiǎn)單的總結(jié)。

        硬編碼:Label Encoding
        ? ? ?所謂硬編碼,即直接對(duì)類(lèi)別特征進(jìn)行數(shù)值映射,有多少類(lèi)別取值就映射多少數(shù)值。這種硬編碼方式簡(jiǎn)單粗暴,方便快捷。但其僅在類(lèi)別特征內(nèi)部取值是有序的情況才好使用,即類(lèi)別特征取值存在明顯的順序性,比如說(shuō)學(xué)歷特征取值為高中、本科、碩士和博士,各學(xué)歷之間存在明顯的順序關(guān)系。

        ? ? ?Sklearn提供了Label Encoding的實(shí)現(xiàn)方式,示例代碼如下:
        from sklearn import preprocessingle = preprocessing.LabelEncoder()le.fit(['undergraduate', 'master', 'PhD', 'Postdoc'])le.transform(['undergraduate', 'master', 'PhD', 'Postdoc'])
        array([3, 2, 0, 1], dtype=int64)

        獨(dú)熱編碼:One-hot Encoding
        ? ? ?One-hot編碼應(yīng)該是應(yīng)用最廣泛的類(lèi)別特征編碼方式了。假設(shè)一個(gè)類(lèi)別特征有m個(gè)類(lèi)別取值,通過(guò)One-hot編碼我們可以將其轉(zhuǎn)換為m個(gè)二元特征,每個(gè)特征對(duì)應(yīng)該取值類(lèi)別。

        ? ? ?對(duì)于類(lèi)別特征內(nèi)部取值不存在明顯的內(nèi)在順序時(shí),即直接的硬編碼不適用時(shí),One-hot編碼的作用就凸顯出來(lái)了。但當(dāng)類(lèi)別特征取值過(guò)多時(shí),One-hot編碼很容易造成維度災(zāi)難,特別是對(duì)于文本類(lèi)的特征,如果使用One-hot編碼對(duì)其進(jìn)行編碼,基本上都是茫茫零海。所以,在類(lèi)別特征取值無(wú)序,且特征取值數(shù)量少于5個(gè)時(shí),可使用One-hot方法進(jìn)行類(lèi)別編碼。有朋友可能會(huì)問(wèn),一定得是5個(gè)嗎,6個(gè)行不行,當(dāng)然也可以,這里并沒(méi)有固定標(biāo)準(zhǔn),但差不多就是這個(gè)數(shù)據(jù)左右。數(shù)量再多就不建議使用One-hot了。

        ? ? ?Pandas和Sklearn都提供了One-hot編碼的實(shí)現(xiàn)方式,示例代碼如下。
        import pandas as pddf = pd.DataFrame({'f1':['A','B','C'], 'f2':['Male','Female','Male']})df = pd.get_dummies(df, columns=['f1', 'f2'])df

        from sklearn.preprocessing import OneHotEncoderenc = OneHotEncoder(handle_unknown='ignore')X = [['Male', 1], ['Female', 3], ['Female', 2]]enc.fit(X)enc.transform([['Female', 1], ['Male', 4]]).toarray()
        array([[1., 0., 1., 0., 0.],[0., 1., 0., 0., 0.]])

        目標(biāo)變量編碼:Target Encoding
        ? ? ?Target Encoding就是用目標(biāo)變量的類(lèi)別均值來(lái)給類(lèi)別特征做編碼。CatBoost中就大量使用目標(biāo)變量統(tǒng)計(jì)的方法來(lái)對(duì)類(lèi)別特征編碼。但在實(shí)際操作時(shí),直接用類(lèi)別均值替換類(lèi)別特征的話(huà),會(huì)造成一定程度的標(biāo)簽信息泄露的情況,主流方法是使用兩層的交叉驗(yàn)證來(lái)計(jì)算目標(biāo)均值。Target Encoding一般適用于類(lèi)別特征無(wú)序且類(lèi)別取值數(shù)量大于5個(gè)的情形。

        ? ? ?參考代碼如下:
        ### 該代碼來(lái)自知乎專(zhuān)欄:### https://zhuanlan.zhihu.com/p/40231966from sklearn.model_selection import KFoldn_folds = 20n_inner_folds = 10likelihood_encoded = pd.Series()likelihood_coding_map = {}# global prior meanoof_default_mean = train[target].mean()      kf = KFold(n_splits=n_folds, shuffle=True)oof_mean_cv = pd.DataFrame()split = 0for infold, oof in kf.split(train[feature]):print ('==============level 1 encoding..., fold %s ============' % split)inner_kf = KFold(n_splits=n_inner_folds, shuffle=True)inner_oof_default_mean = train.iloc[infold][target].mean()inner_split = 0inner_oof_mean_cv = pd.DataFrame()likelihood_encoded_cv = pd.Series()for inner_infold, inner_oof in inner_kf.split(train.iloc[infold]):print ('==============level 2 encoding..., inner fold %s ============' % inner_split)        # inner out of fold meanoof_mean = train.iloc[inner_infold].groupby(by=feature)[target].mean()        # assign oof_mean to the infoldlikelihood_encoded_cv = likelihood_encoded_cv.append(train.iloc[infold].apply(lambda x : oof_mean[x[feature]]if x[feature] in oof_mean.indexelse inner_oof_default_mean, axis = 1))inner_oof_mean_cv = inner_oof_mean_cv.join(pd.DataFrame(oof_mean), rsuffix=inner_split, how='outer')inner_oof_mean_cv.fillna(inner_oof_default_mean, inplace=True)inner_split += 1oof_mean_cv = oof_mean_cv.join(pd.DataFrame(inner_oof_mean_cv), rsuffix=split, how='outer')oof_mean_cv.fillna(value=oof_default_mean, inplace=True)split += 1print ('============final mapping...===========')likelihood_encoded = likelihood_encoded.append(train.iloc[oof].apply(lambda x: np.mean(inner_oof_mean_cv.loc[x[feature]].values)if x[feature] in inner_oof_mean_cv.indexelse?oof_default_mean,?axis=1))

        模型自動(dòng)編碼
        ? ? ?在LightGBM和CatBoost等算法中,模型可以直接對(duì)類(lèi)別特征進(jìn)行編碼,實(shí)際使用時(shí)直接將類(lèi)別特征標(biāo)記后傳入對(duì)應(yīng)的api即可。一個(gè)示例代碼如下:
        lgb_train = lgb.Dataset(train2[features], train2['total_cost'], ???????????????????????categorical_feature=['sex'])

        總結(jié)
        根據(jù)本文的梳理,可總結(jié)機(jī)器學(xué)習(xí)中類(lèi)別特征的編碼方式如下:
        • Label Encoding

          • 類(lèi)別特征內(nèi)部有序

        • One-hot Encoding

          • 類(lèi)別特征內(nèi)部無(wú)序

          • 類(lèi)別數(shù)值<5

        • Target Encoding

          • 類(lèi)別特征內(nèi)部無(wú)序

          • 類(lèi)別數(shù)值>5

        • 模型自動(dòng)編碼

          • LightGBM

          • CatBoost


        往期精彩:

        【原創(chuàng)首發(fā)】機(jī)器學(xué)習(xí)公式推導(dǎo)與代碼實(shí)現(xiàn)30講.pdf

        【原創(chuàng)首發(fā)】深度學(xué)習(xí)語(yǔ)義分割理論與實(shí)戰(zhàn)指南.pdf


        喜歡您就點(diǎn)個(gè)在看!

        瀏覽 34
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精视频| 大波大乳videos | 顶级少妇做爰视频在线观看 | 国产精品人妻人伦a 6 2v久软件 自拍啪啪视频 | 99热6这里只有精品 | 大乱斗肉寡妇怎么出装最好看视频 | 色老久久| 成人自拍偷拍在线 | free性欧美hd精品4k | 尤物网址 |