精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

以KaggleDays數據集為例,編碼方法介紹

zhKF_jqr_AI ? 來源:未知 ? 作者:李倩 ? 2018-11-22 09:10 ? 次閱讀

編者按:華沙大學機器學習科學家Wojciech Rosinski介紹了類別編碼的主要方法。

介紹

這是特征工程方法系列的第一篇。在機器學習的實踐中,特征工程是最重要而定義最松散的方面之一。它可以被視為藝術,沒有嚴格的規則,創造性是其關鍵。

特征工程是要為機器學習模型創建更好的信息表示。即便使用非線性算法,如果使用原始數據,我們也無法建模數據集的變量之間的所有交互(關系)。因此,我們需要手工探查、處理數據。

這就帶來了一個問題——深度學習怎么講?深度學習是為了最小化手工處理數據的需求,使模型能夠自行學習恰當的數據表示。在圖像、語音、文本之類沒有給定其他“元數據”的數據上,深度學習會表現得更好。而在表格式數據上,沒有什么可以戰勝梯度提升樹方法,例如XGBoost或LightGBM。機器學習競賽證明了這一點——幾乎所有表格式數據的獲勝方案中,基于決策樹的模型是最佳的,而深度學習模型通常沒法達到這么好的結果(但混合基于決策樹的模型時效果非常好 ;-) )

特征工程的偏差是領域知識。取決于需要解決的問題,每個數據集應該使用不同的特征工程方法,原因正在于此。不過,仍有一些廣泛使用的方法,至少值得嘗試下能否提升模型表現。HJ vav Veen的講演中提到了大量的實用信息。下面的一些方法正是根據講演的描述實現的。

本文以KaggleDays數據集為例,編碼方法介紹參考了上面的講演。

數據集

數據來自reddit,包含問題和回答。目標是預測回答的贊數。之所以用這個數據集為例,是因為它包含文本和標準特征。

引入需要用到的庫:

import gc

import numpy as np

import pandas as pd

加載數據:

X = pd.read_csv('../input/train.csv', sep="\t", index_col='id')

列:

['question_id',

'subreddit',

'question_utc',

'question_text',

'question_score',

'answer_utc',

'answer_text',

'answer_score']

每個question_id對應一個具體問題(見question_text)。每個question_id可能出現多次,因為每一行包含對這一問題的一個不同回答(見answer_text)。問題和回答的時間日期由_utc列提供。另外還包括問題發布的subreddit(版塊)的信息。question_score是問題的贊數,而answer_score是回答的贊數。answer_score是目標變量。

數據需要根據question_id分為訓練子集和驗證子集,仿效Kaggle分訓練集和測試集的做法。

question_ids = X.question_id.unique()

question_ids_train = set(pd.Series(question_ids).sample(frac=0.8))

question_ids_valid = set(question_ids).difference(question_ids_train)

X_train = X[X.question_id.isin(question_ids_train)]

X_valid = X[X.question_id.isin(question_ids_valid)]

類別特征和數值特征

機器學習模型只能處理數字。數值(連續、定量)變量是可以在有限或無限區間內取任何值的變量,它們可以很自然地用數字表示,所以可以在模型中直接使用。原始類別變量通常以字符串的形式存在,在傳入模型之前需要變換。

subreddit是類別變量的一個好例子,其中包含41個不同的類別,例如:

['AskReddit', 'Jokes', 'politics', 'explainlikeimfive', 'gaming']

讓我們看下最流行的類別(X.subreddit.value_counts()[:5]):

AskReddit 275667

politics 123003

news 42271

worldnews 40016

gaming 32117

Name: subreddit, dtype: int64

數值變量的一個例子是question_score,可以通過X.question_score.describe()瀏覽信息:

mean 770.891169

std 3094.752794

min 1.000000

25% 2.000000

50% 11.000000

75% 112.000000

max 48834.000000

Name: question_score, dtype: float64

類別特征編碼

類別編碼的兩個基本方法是獨熱編碼(onehot encoding)和標簽編碼(label encoding)。獨熱編碼可以通過pandas.get_dummies完成。具備K個類別的變量的編碼結果是一個K列的二值矩陣,其中第i列的值為1意味著這項觀測屬于第i類。

標簽編碼直接將類別轉換為數字。pandas.factorize提供了這一功能,或者,pandas中category類型的列提供了cat.codes。使用標簽編碼能夠保持原本的維度。

還有一些不那么標準的編碼方法也值得一試,它們可能可以提升模型的表現。這里將介紹三種方法:

頻數編碼(count encoding)

labelcount編碼

目標編碼(target encoding)

頻數編碼

頻數編碼使用頻次替換類別,頻次根據訓練集計算。這個方法對離群值很敏感,所以結果可以歸一化或者轉換一下(例如使用對數變換)。未知類別可以替換為1。

盡管可能性不是非常大,有些變量的頻次可能是一樣的,這將導致碰撞——兩個類別編碼為相同的值。沒法說這是否會導致模型退化或者改善,不過原則上我們不希望出現這種情況。

def count_encode(X, categorical_features, normalize=False):

print('Count encoding: {}'.format(categorical_features))

X_ = pd.DataFrame()

for cat_feature in categorical_features:

X_[cat_feature] = X[cat_feature].astype(

'object').map(X[cat_feature].value_counts())

if normalize:

X_[cat_feature] = X_[cat_feature] / np.max(X_[cat_feature])

X_ = X_.add_suffix('_count_encoded')

if normalize:

X_ = X_.astype(np.float32)

X_ = X_.add_suffix('_normalized')

else:

X_ = X_.astype(np.uint32)

return X_

讓我們編碼下subreddit列:

train_count_subreddit = count_encode(X_train, ['subreddit'])

并查看結果。最流行的5個subreddit:

AskReddit 221941

politics 98233

news 33559

worldnews 32010

gaming 25567

Name: subreddit, dtype: int64

編碼為:

221941 221941

98233 98233

33559 33559

32010 32010

25567 25567

Name: subreddit_count_encoded, dtype: int64

基本上,這用頻次替換了subreddit類別。我們也可以除以最頻繁出現的類別的頻次,以得到歸一化的值:

1.000000 221941

0.442609 98233

0.151207 33559

0.144228 32010

0.115197 25567

Name: subreddit_count_encoded_normalized, dtype: int64

LabelCount編碼

我們下面將描述的方法稱為LabelCount編碼,它根據類別在訓練集中的頻次排序類別(升序或降序)。相比標準的頻次編碼,LabelCount具有特定的優勢——對離群值不敏感,也不會對不同的值給出同樣的編碼。

def labelcount_encode(X, categorical_features, ascending=False):

print('LabelCount encoding: {}'.format(categorical_features))

X_ = pd.DataFrame()

for cat_feature in categorical_features:

cat_feature_value_counts = X[cat_feature].value_counts()

value_counts_list = cat_feature_value_counts.index.tolist()

if ascending:

# 升序

value_counts_range = list(

reversed(range(len(cat_feature_value_counts))))

else:

# 降序

value_counts_range = list(range(len(cat_feature_value_counts)))

labelcount_dict = dict(zip(value_counts_list, value_counts_range))

X_[cat_feature] = X[cat_feature].map(

labelcount_dict)

X_ = X_.add_suffix('_labelcount_encoded')

if ascending:

X_ = X_.add_suffix('_ascending')

else:

X_ = X_.add_suffix('_descending')

X_ = X_.astype(np.uint32)

return X_

編碼:

train_lc_subreddit = labelcount_encode(X_train, ['subreddit'])

這里默認使用降序,subreddit列最流行的5個類別是:

0 221941

1 98233

2 33559

3 32010

4 25567

Name: subreddit_labelcount_encoded_descending, dtype: int64

AskReddit是最頻繁的類別,因此被轉換為0,也就是第一位。

使用升序的話,同樣這5個類別編碼如下:

40 221941

39 98233

38 33559

37 32010

36 25567

Name: subreddit_labelcount_encoded_ascending, dtype: int64

目標編碼

最后是最有技巧性的方法——目標編碼。它使用目標變量的均值編碼類別變量。我們為訓練集中的每個分組計算目標變量的統計量(這里是均值),之后會合并驗證集、測試集以捕捉分組和目標之間的關系。

舉一個更明確的例子,我們可以在每個subreddit上計算answer_score的均值,這樣,在特定subreddit發帖可以期望得到多少贊,我們可以有個大概的估計。

使用目標變量時,非常重要的一點是不要泄露任何驗證集的信息。所有基于目標編碼的特征都應該在訓練集上計算,接著僅僅合并或連接驗證集和測試集。即使驗證集中有目標變量,它不能用于任何編碼計算,否則會給出過于樂觀的驗證誤差估計。

如果使用K折交叉驗證,基于目標的特征應該在折內計算。如果僅僅進行單次分割,那么目標編碼應該在分開訓練集和驗證集之后進行。

此外,我們可以通過平滑避免將特定類別編碼為0. 另一種方法是通過增加隨機噪聲避免可能的過擬合。

處置妥當的情況下,無論是線性模型,還是非線性模型,目標編碼都是最佳的編碼方式。

def target_encode(X, X_valid, categorical_features, X_test=None,

target_feature='target'):

print('Target Encoding: {}'.format(categorical_features))

X_ = pd.DataFrame()

X_valid_ = pd.DataFrame()

if X_test isnotNone:

X_test_ = pd.DataFrame()

for cat_feature in categorical_features:

group_target_mean = X.groupby([cat_feature])[target_feature].mean()

X_[cat_feature] = X[cat_feature].map(group_target_mean)

X_valid_[cat_feature] = X_valid[cat_feature].map(group_target_mean)

X_ = X_.astype(np.float32)

X_ = X_.add_suffix('_target_encoded')

X_valid_ = X_valid_.astype(np.float32)

X_valid_ = X_valid_.add_suffix('_target_encoded')

if X_test isnotNone:

X_test_[cat_feature] = X_test[cat_feature].map(group_target_mean)

X_test_ = X_test_.astype(np.float32)

X_test_ = X_test_.add_suffix('_target_encoded')

return X_, X_valid_, X_test_

return X_, X_valid_

編碼:

train_tm_subreddit, valid_tm_subreddit = target_encode(

X_train, X_valid, categorical_features=['subreddit'],

target_feature='answer_score')

如果我們查看下編碼后的值,就會發現不同reddit的平均贊數有明顯的差別:

23.406061 220014

13.082699 98176

19.020845 33916

17.521887 31869

18.235424 25520

21.535477 24692

18.640282 20416

23.688890 20009

3.159401 18695

Name: subreddit_target_encoded, dtype: int64

AskReddit 220014

politics 98176

news 33916

worldnews 31869

gaming 25520

todayilearned 24692

funny 20416

videos 20009

teenagers 18695

Name: subreddit, dtype: int64

AskReddit中的回答平均能有23.4個贊,而politics和teenagers中的回答分別只有13.1個贊。這樣的特征可能非常強大,因為它讓我們可以在特征集中明確編碼一些目標信息。

獲取類別的編碼值

無需修改編碼函數,我們可以通過如下方式在驗證集或測試集上合并取得的值:

encoded = train_lc_subreddit.subreddit_labelcount_encoded_descending.value_counts().index.values

raw = X_train.subreddit.value_counts().index.values

encoding_dict = dict(zip(raw, encoded))

X_valid['subreddit_labelcount_encoded_descending'] = X_valid.loc[:,

'subreddit'].map(

encoding_dict)

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編碼
    +關注

    關注

    6

    文章

    935

    瀏覽量

    54768
  • 機器學習
    +關注

    關注

    66

    文章

    8381

    瀏覽量

    132428
  • 數據集
    +關注

    關注

    4

    文章

    1205

    瀏覽量

    24648

原文標題:特征工程方法:一、類別變量編碼

文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    存儲器的編碼方法

    ,上述編碼運算包括相加或者相減運算。圖2的示意圖為。假設第一存儲體中的數據“10110”,第二存儲體中的
    發表于 11-15 15:44

    求一種準循環LDPC碼的快速編碼方法

    LDPC碼的通用編碼方法有哪些?準循環LDPC碼的快速編碼方法是什么?
    發表于 04-25 07:16

    一種實用的混沌保密編碼方法

    基于實用符號動力學的基礎理論,提出了一種實用的混沌保密編碼方法,該方法借助于單峰的logistic映射處于混沌吸引子狀態時產生的符號序列作為密鑰,對信源編碼信號進行加密
    發表于 11-18 00:17 ?12次下載

    一種宏塊分裂的多描述視頻編碼方法

    一種宏塊分裂的多描述視頻編碼方法:多描述編碼是近年來提出的用于不可靠網絡的視頻編碼方法。本文在塊基編碼的基礎上,提出了一種基于宏塊分裂的多描述編碼方
    發表于 08-08 08:29 ?19次下載

    一種實用的混沌保密編碼方法

    一種實用的混沌保密編碼方法 基于實用符號動力學的基礎理論,提出了一種實用的混沌保密編碼方法,該方法借助于單峰的logistic映射處于混沌吸引子狀態時產生的符號序列
    發表于 11-18 10:55 ?10次下載

    定點小數的編碼方法

    定點小數的編碼方法  用定點小數引出數值的三種編碼(原碼、補碼和反碼)方法是最方便的。   (1) 原碼表示法,是用機器數的最高一位代表符號,以下各位
    發表于 10-13 17:19 ?3318次閱讀
    定點小數的<b class='flag-5'>編碼方法</b>

    整數的編碼方法

    整數的編碼方法   與定點小數的三種編碼方法類似,整數也可以用原碼、補碼和反碼三種不同的編碼方法表示。區別主要表現在:
    發表于 10-13 17:19 ?5513次閱讀

    浮點數常用的編碼方法

    浮點數常用的編碼方法  前面已經說到,在計算機內,浮點數被表示如下格式:    通常情況
    發表于 10-13 17:21 ?4451次閱讀
    浮點數常用的<b class='flag-5'>編碼方法</b>

    AVS立體視頻編碼方法

    提出一種基于AVS(audio video coding standard)的快速立體視頻編碼方法,對左路參考圖像使用AVS編碼編碼,對右路目標圖像同時在時間域和空間域進行預測. 使用兩級神經分類器來快速確定預
    發表于 05-14 10:54 ?36次下載
    AVS立體視頻<b class='flag-5'>編碼方法</b>

    DNA計算中的單模板編碼方法改進研究

    如何避免各種不期望的雜交是DNA 計算以及微陣列技術中的一個關鍵問題. 為了得到穩定可靠的雜交,必須探索一種可靠的、魯棒性的編碼方法. 單模板編碼方法是Arita 提出的另一種模板編
    發表于 08-18 15:24 ?0次下載
    DNA計算中的單模板<b class='flag-5'>編碼方法</b>改進研究

    一種低耦合翻轉的數據總線編碼方法

    一種低耦合翻轉的數據總線編碼方法
    發表于 01-07 20:32 ?2次下載

    一種新的基于素數的XML動態編碼方法_田帥

    一種新的基于素數的XML動態編碼方法_田帥
    發表于 03-19 11:45 ?0次下載

    基于引用圖片的信息編碼方法

    編碼方法。該方法中,每個字符都用一個RGB分量的相對位置和偏移量表示,編碼數據則通過激活擴散的方法生成。同一個字符可以用不同的編碼表示,而相
    發表于 12-06 13:52 ?1次下載
    基于引用圖片的信息<b class='flag-5'>編碼方法</b>

    改進的分形圖像編碼方法

    傳統圖像編碼方法一般已成定式,發展潛力不大。分形圖像編碼方法思想新穎,是極具發展潛力的壓縮方法,但分形編碼存在編碼耗時過長的缺點。本文基于分
    發表于 12-20 13:56 ?2次下載

    常見的11個分類變量編碼方法

    機器學習算法只接受數值輸入,所以如果我們遇到分類特征的時候都會對分類特征進行編碼,本文總結了常見的11個分類變量編碼方法
    的頭像 發表于 11-28 15:45 ?3405次閱讀