特徵工程究竟是什麼呢?顧名思義,其本質是一項工程活動,目的是最大限度地從原始數據中提取特徵以供算法和模型使用。git
此以前,我已經寫了如下幾篇AI基礎的快速入門,本篇文章講解特徵工程基礎第一部分:(類別特徵)。github
已發佈:算法
AI 基礎:Python 簡易入門apache
AI 基礎:Numpy 簡易入門json
AI 基礎:Pandas 簡易入門app
AI 基礎:Scipy(科學計算庫) 簡易入門機器學習
AI基礎:數據可視化簡易入門(matplotlib和seaborn)分佈式
後續持續更新ide
參考資料:函數
[1]原版(英文)圖書地址:
https://www.oreilly.com/library/view/feature-engineering-for/9781491953235/
[2]翻譯來源apachecn:
https://github.com/apachecn
[3]翻譯做者@ZhenLeiXu:
代碼修改和整理:黃海廣,原文修改爲jupyter notebook格式,並增長和修改了部分代碼,測試所有經過,全部數據集已經放在百度雲下載。
本文代碼能夠在github下載:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering
數據集的百度雲:
連接:https://pan.baidu.com/s/1uDXt5jWUOfI0fS7hD91vBQ 提取碼:8p5d
一個類別特徵,見名思義,就是用來表達一種類別或標籤。好比,一個類別特徵可以表達世界上的主要城市,一年四季,或者說一個公司的產品(石油、路程、技術)。在真實世界的數據集中,類別值的數量老是無限的。同時這些值通常能夠用數值來表示。可是,與其餘數值變量不同的是,類別特徵的數值變量沒法與其餘數值變量進行比較大小。(做爲行業類型,石油與旅行沒法進行比較)它們被稱之爲非序的。
一個簡單的問題能夠做爲測試是否應該是一個分類變量的試金石測試:「兩個價值有多麼不一樣,或者只是它們不一樣?」500美圓的股票價格比100美圓的價格高5倍。因此股票價格應該用一個連續的數字變量表示。另外一方面,公司的產業(石油,旅遊,技術等)應該沒法被比較的,也就是類別特徵。
大的分類變量在交易記錄中特別常見。對於實例中,許多Web服務使用id做爲分類變量來跟蹤用戶具備數百至數百萬的值,取決於惟一的數量服務的用戶。互聯網交易的IP地址是另外一個例子一個很大的分類變量。它們是分類變量,由於即便用戶ID和IP地址是數字,它們的大小一般與任務無關在眼前。例如,在進行欺詐檢測時,IP地址多是相關的我的交易。某些IP地址或子網可能會產生更多欺騙性交易比其餘人。可是164.203.x.x的子網本質上並很少欺詐性比164.202.x.x; 子網的數值可有可無。
文檔語料庫的詞彙能夠被解釋爲一個大的分類變量,類別是惟一的單詞。它可能在計算上很昂貴表明如此多的不一樣類別。若是一個類別(例如,單詞)出現多個數據點(文檔)中的時間,而後咱們能夠將它表示爲一個計數並表示全部的類別經過他們的統計數字。這被稱爲bin-counting。咱們用分類變量的共同表示開始討論,而且最終蜿蜒曲折地討論了大範圍的bin-counting問題變量,這在現代數據集中很是廣泛。
分類變量的類別一般不是數字。例如,眼睛的顏色能夠是「黑色」,「藍色」,「棕色」等。所以,須要使用編碼方法將這些非數字類別變爲數字。簡單地將一個整數(好比1到k)分配給k個可能的類別中的每個都是誘人的。可是,由此產生的價值觀能夠互相受權,這在類別中不該該被容許。
將類別特徵進行表示一個最好的辦法就是使用一組比特位來表達。每一位表明一個可能的類別。若是該變量不能一次成爲多個類別,那麼該組中只有一位能夠是1。這被稱爲獨熱編碼,它在Scikit Learn中實現sklearn.preprocessing.OneHotEncoder。每一個位都是一個特徵。所以是一個絕對的具備k個可能類別的變量被編碼爲長度爲k的特徵向量。
表1-1 對3個城市的類別進行獨熱編碼
City | e1 | e2 | e3 |
---|---|---|---|
San Francisco | 1 | 0 | 0 |
New York | 0 | 1 | 0 |
Seattle | 0 | 0 | 1 |
獨熱編碼很是易於理解。但它使用的是比嚴格必要的更多的一點。若是咱們看到k-1位是零,那麼最後一位必須是1,由於變量必須具備k個值中的一個。在數學上,能夠寫下這個約束條件爲「全部位的和必須等於1」。
等式 5-1. 獨熱編碼e1,e2,e3限制條件。
所以,咱們有一個線性的依賴性。線性相關特徵,就像咱們同樣在tfidf中發現,有點煩人,由於它意味着訓練線性模型不會是惟一的。特徵的不一樣線性組合能夠作出一樣的預測,因此咱們須要跳過額外條件的來理解特徵對預測的影響。
獨熱編碼的問題是它容許
個自由度,其中變量自己只須要。虛擬編碼經過僅使用表示中的
個特徵來消除額外的自由度。
公共汽車下面有一個特徵,由全零向量表示。這被稱爲參考類別。虛擬編碼和獨熱編碼都是在Pandas中以pandas.get_dummies的形式實現的。
表1-2 對3個城市的類別進行dummy編碼
圖1-1 公寓租金價格在one-hot編碼中的向量空間表示。點的大小表達了數據集中租金不一樣價格的平均數。
咱們這時可以僅僅依靠城市這一個變量來創建線性迴歸來預測租金的價格。
線性迴歸模型能夠這樣寫
例1-1.在獨熱編碼上的線性迴歸
import pandas as pd from sklearn import linear_model df = pd.DataFrame({ 'City': ['SF', 'SF', 'SF', 'NYC', 'NYC', 'NYC', 'Seattle', 'Seattle', 'Seattle'], 'Rent': [3999, 4000, 4001, 3499, 3500, 3501, 2499, 2500, 2501] }) df['Rent'].mean()
3333.3333333333335
one_hot_df = pd.get_dummies(df, prefix=['city']) one_hot_df
model = linear_model.LinearRegression() model.fit(one_hot_df[['city_NYC', 'city_SF', 'city_Seattle']], one_hot_df[['Rent']]) model.coef_
array([[ 166.66666667, 666.66666667, -833.33333333]])
model.intercept_
array([3333.33333333])
使用dummy code進行迴歸
dummy_df = pd.get_dummies(df, prefix=['city'], drop_first=True) dummy_df
model.fit(dummy_df[['city_SF', 'city_Seattle']], dummy_df['Rent'])
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
normalize=False)
model.coef_
array([ 500., -1000.])
model.intercept_
3500.0
經過獨熱編碼,截距項表示目標變量的全局均值租金價格,而且每一個線性係數表示該城市的平均租金與全局平均值的差別。
經過虛擬編碼,誤差係數表明響應的平均值參考類別的變量y,在這個例子中是紐約市。該第i個特徵的係數等於平均響應之間的差別第i類別的值和參考類別的平均值。
表1-4:線性迴歸學得的係數
id | x1 | x2 | x3 | b |
---|---|---|---|---|
one-hot | 166.67 | 666.67 | -833.33 | 3333.33 |
dummy | coding | 0 | 500 -1000 | 3500 |
分類變量編碼的另外一種變體稱爲Effect編碼。Effect編碼與虛擬編碼很是類似,區別在於參考類別如今由全部-1的向量表示。
表1-5: Effect編碼表示3個城市
City | e1 | e2 |
---|---|---|
San Francisco | 1 | 0 |
New York | 0 | 1 |
Seattle | -1 | -1 |
Effect編碼與虛擬編碼很是類似,可是在線性迴歸中更容易被擬合。例1-2表達了運行機理。截距項表示目標的全球平均值變量,單個係數表示各個類別的平均值與全球平均值有多少差別。(這被稱爲類別或級別的主要效果,所以名稱爲「效果編碼」。)獨熱編碼實際上具備相同的截距和係數,但在這種狀況下,每一個城市都有線性係數。在效果編碼中,沒有單一特徵表明參考類別。所以,參考類別的影響須要分別計算爲全部其餘類別的係數的負和。(查看what is effect coding?)
例1-2 Effect編碼的線性迴歸
effect_df = dummy_df.copy() effect_df.loc[3:5, ['city_SF', 'city_Seattle']] = -1.0 effect_df
Rent | city_SF | city_Seattle | |
---|---|---|---|
0 | 3999 | 1.0 | 0.0 |
1 | 4000 | 1.0 | 0.0 |
2 | 4001 | 1.0 | 0.0 |
3 | 3499 | -1.0 | -1.0 |
4 | 3500 | -1.0 | -1.0 |
5 | 3501 | -1.0 | -1.0 |
6 | 2499 | 0.0 | 1.0 |
7 | 2500 | 0.0 | 1.0 |
8 | 2501 | 0.0 | 1.0 |
model.fit(effect_df[['city_SF', 'city_Seattle']], effect_df['Rent'])
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,
normalize=False)
model.coef_
array([ 666.66666667, -833.33333333])
model.intercept_
3333.3333333333335
獨熱,虛擬和效果編碼很是類似。他們每一個人都有優勢和缺點。獨熱編碼是多餘的,它容許多個有效模型同樣的問題。非惟一性有時候對解釋有問題。該優勢是每一個特徵都明顯對應於一個類別。此外,失蹤數據能夠編碼爲全零矢量,輸出應該是總體目標變量的平均值。
虛擬編碼和效果編碼不是多餘的。他們產生獨特和可解釋的模型。虛擬編碼的缺點是它不能輕易處理缺乏數據,由於全零矢量已經映射到參考類別。它還編碼每一個類別相對於參考類別的影響,其中看起來很奇怪。效果編碼經過使用不一樣的代碼來避免此問題參考類別。可是,全部-1的矢量都是一個密集的矢量,對於存儲和計算來講都很昂貴。所以,Pandas和Scikit Learn等流行的ML軟件包選擇了虛擬編碼或獨熱編碼,而不是效應編碼。當類別數量變得很是多時,全部三種編碼技術都會失效大。須要不一樣的策略來處理很是大的分類變量。
互聯網上的自動數據收集能夠生成大量的分類變量。這在諸如定向廣告和欺詐檢測等應用中很常見。在有針對性的廣告中,任務是根據用戶的搜索查詢或當前頁面將用戶與一組廣告進行匹配。功能包括用戶ID,廣告的網站域,搜索查詢,當前頁面以及這些功能的全部可能的成對連詞。(查詢是一個文本字符串,能夠切分紅經常使用的文本特徵,但查詢一般很短,一般由短語組成,所以在這種狀況下最好的行爲一般是保持完整,或 經過哈希函數來簡化存儲和比較,咱們將在下面更詳細地討論哈希。)其中每個都是一個很是大的分類變量。咱們面臨的挑戰是如何找到一個可以提升內存效率的優秀特徵表示,並生成訓練速度快的準確模型。
對於這種類別特徵處理的方案有:
對編碼不作任何事情。使用便宜的訓練簡單模型。在許多機器上將獨熱編碼引入線性模型(邏輯迴歸或線性支持向量機)。
壓縮編碼,有兩種方式
a. 對特徵進行哈希--在線性迴歸中特別常見
b. bin-counting--在線性迴歸中與樹模型都常見
使用one-hot編碼是可行的。在微軟搜索廣告研究中,Graepel等人 [2010]報告在貝葉斯機率迴歸模型中使用這種二值特徵,可使用簡單更新在線進行培訓。與此同時,其餘組織則爭論壓縮方法。來自雅虎的研究人員 經過特徵散列方式[Weinberger et al.2009年]。儘管McMahan等人[2013]在谷歌的廣告引擎上嘗試了功能哈希,並無找到顯着的改進。然而,微軟的其餘人則被認爲是計數[Bilenko,2015]。
咱們將會看到,全部這些想法都有利有弊。咱們將首先描述解決方案自己,而後討論他們的權衡。
散列函數是一個肯定性函數,它映射一個潛在的***整數到有限整數範圍
,。因爲輸入域可能大於輸出範圍,多個數字可能會映射到相同的輸出。這被稱爲a碰撞。統一的散列函數可確保大體相同數量的數字被映射到每一個
箱。在視覺上,咱們能夠將散列函數視爲一臺機器能夠吸入編號的球並將它們傳送到一個m箱。球與相同的號碼將始終被路由到同一個bin。
散列函數能夠爲任何能夠用數字表示的對象構造(對於能夠存儲在計算機上的任何數據都是如此):數字,字符串,複雜的結構等。
圖1-2 哈希編碼
當有不少特徵時,存儲特徵向量可能佔用不少空間。特徵散列將原始特徵向量壓縮爲m維經過對特徵ID應用散列函數來建立矢量。例如,若是原件特徵是文檔中的單詞,那麼散列版本將具備固定的詞彙大小爲m,不管輸入中有多少獨特詞彙。
例1-3 對單詞的特徵哈希
def hash_features(word_list, m): output = [0] * m for word in word_list: index = hash_fcn(word) % m output[index] += 1 return output
功能散列的另外一個變體添加了一個符號組件,所以計數也是從哈希箱中增長或減小。這確保了內部產品之間散列特徵與原始特徵的指望值相同。
def hash_features(word_list, m): output = [0] * m for word in word_list: index = hash_fcn(word) % m sign_bit = sign_hash(word) % 2 if (sign_bit == 0): output[index] -= 1 else: output[index] += 1 return output
哈希後內積的值在時間複雜度在O(1/(m**0.5)).因此哈希表m的大小能夠根據可接受的錯誤來選擇。在實踐中,選擇合適的m可能須要一些試驗和錯誤。特徵哈希能夠用於涉及特徵內積的模型矢量和係數,例如線性模型和核心方法。它一直證實在垃圾郵件過濾任務中取得成功[Weinberger等,2009]。在有針對性的廣告案例中,McMahan et al. [2013年]報告不能將預測偏差下降到可接受的水平,除非m的數量級爲數十億。散列特徵的一個缺點是散列特徵是聚合的原始特徵,再也不可解釋。
在這個例子中,咱們將使用Yelp評論數據集來演示存儲和,解釋性使用的爲sklearn的庫FeatureHasher。
import pandas as pd import json js = [] with open('data/yelp_academic_dataset_review.json') as f: for i in range(10000): js.append(json.loads(f.readline())) review_df = pd.DataFrame(js) m = len(review_df.business_id.unique())
m
4174
from sklearn.feature_extraction import FeatureHasher h = FeatureHasher(n_features=m, input_type='string') f = h.transform(review_df['business_id'])
review_df['business_id'].unique().tolist()[0:5]
['9yKzy9PApeiPPOUJEtnvkg',
'ZRJwVLyzEJq1VAihDhYiow',
'6oRAC4uyJCsJl1X0WZpVSA',
'_1QQZuf4zZOyFCvXc0o6Vg',
'6ozycU1RpktNG2-1BroVtw']
f.toarray()
array([[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
...,
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.],
[0., 0., 0., ..., 0., 0., 0.]])
咱們看看特徵的存儲
from sys import getsizeof
print('Our pandas Series, in bytes: ', getsizeof(review_df['business_id'])) print('Our hashed numpy array, in bytes: ', getsizeof(f))
Our pandas Series, in bytes: 790104
Our hashed numpy array, in bytes: 56
咱們能夠清楚地看到如何使用特徵散列會以計算方式使咱們受益,犧牲直接的用戶解釋能力。這是一個容易的權衡來接受什麼時候從數據探索和可視化發展到機器學習管道對於大型數據集。
Bin-counting是機器學習中常見的從新發現之一。從廣告點擊率預測到硬件分支預測,它已經被從新建立並用於各類應用[Yeh and Patt,1991; Lee等人,1998; Pavlov等,2009; 李等人,2010]。然而,由於它是一種特徵工程技術,而不是一種建模或優化方法,因此沒有關於該主題的研究論文。關於該技術最詳細的描述能夠在Misha Bilenko的博客文章「Big Learning Made with Easy」以及相關的幻燈片中找到。
bin-counting的想法很是簡單:而不是使用分類變量做爲特徵,而不是使用條件機率的目標在該價值下。換句話說,而不是編碼的身份分類值,計算該值和該值之間的關聯統計量咱們但願預測的目標。對於那些熟悉Na?veBayes分類器的人來講,這個統計學應該敲響一下鍾,由於它是該類的條件機率假設全部功能都是獨立的。最好用一個例。
表1-6. bin-counting的例子
Bin-counting假定歷史數據可用於計算統計。表1-6包含分類變量每一個可能值的彙總歷史計數。根據用戶點擊任何廣告的次數以及未點擊的次數,咱們能夠計算用戶「Alice」點擊任何廣告的機率。一樣,咱們能夠計算任何查詢 - 廣告 - 域組合的點擊機率。在訓練時,每當咱們看到「愛麗絲」時,都使用她的點擊機率做爲模型的輸入特徵。QueryHash-AdDomain對也是如此,例如「0x437a45e1,qux.net」。
假設有10,000個用戶。獨熱編碼會生成一個稀疏矢量長度爲10,000,在列中對應於值的單個1當前數據點。Bin-counting將全部10,000個二進制列編碼爲一個功能的真實值介於0和1之間。
除了歷史點擊機率外,咱們還能夠包含其餘功能:原始計數自己(點擊次數和非點擊次數),對數比率或任何其餘機率的衍生物。咱們的例子是預測廣告點擊率,經過率。但該技術很容易應用於通常的二元分類。它也可使用一般的技術容易地擴展到多級分類將二元分類器擴展到多個類,即經過一對多優點比或其餘多類標籤編碼。
比值比一般定義在兩個二元變量之間。它經過提出這樣一個問題來看待他們的聯想強度:「當
爲真時,有多大多是真的」。例如,咱們可能會問,「Alice點擊廣告的可能性大於通常人口?「在這裏,是二進制變量」是Alice是當前用戶「,而是變量」點擊廣告與否「。該計算使用所謂的雙向列聯表(基本上,四個數字對應於和
的四種可能組合)。
表1-7. 偶然發生的用戶點擊事件
圖1-3 分類變量的獨熱編碼與二進制計數統計的說明。
在實施方面,垃圾箱計數須要在每一個類別之間存儲地圖及其相關計數。(其他的統計數據能夠從中獲得原始計數)。所以它須要
空間,其中
是惟一值的數量的分類變量。
咱們採用Kaggle的比賽Avazu舉個例子。
mAvazu競賽使用廣告數據來預測點擊率,但咱們將使用它來演示如何bin計數能夠大大減小大的特徵空間流數據量。
編者注:這個數據集特別大,大概6g,咱們讀取前10k行存儲爲train_subset.csv,並傳到了百度雲,可能跑出來的結果與原書不一致,但不影響學習。
例1-6 Bin-counting例子
import pandas as pd #讀取前面的10k行 df = pd.read_csv('data/train_subset.csv') #有多少獨立的特徵 len(df['device_id'].unique())
1075
df.head()
5 rows × 24 columns
def click_counting(x, bin_column): clicks = pd.Series( x[x['click'] > 0][bin_column].value_counts(), name='clicks') no_clicks = pd.Series( x[x['click'] < 1][bin_column].value_counts(), name='no_clicks') counts = pd.DataFrame([clicks, no_clicks]).T.fillna('0') counts['total'] = counts['clicks'].astype( 'int64') + counts['no_clicks'].astype('int64') return counts def bin_counting(counts): counts['N+'] = counts['clicks'].astype('int64').divide( counts['total'].astype('int64')) counts['N-'] = counts['no_clicks'].astype('int64').divide( counts['total'].astype('int64')) counts['log_N+'] = counts['N+'].divide(counts['N-']) # If we wanted to only return bin-counting properties, we would filter here bin_counts = counts.filter(items=['N+', 'N-', 'log_N+']) return counts, bin_counts
bin_column = 'device_id' device_clicks = click_counting(df.filter(items= [bin_column, 'click']), bin_column) device_all, device_bin_counts = bin_counting(device_clicks)
# check to make sure we have all the devices len(device_bin_counts)
1075
device_all.sort_values(by = 'total', ascending=False).head(4)
# We can see how this can change model evaluation time by comparing raw vs. bin-counting size from sys import getsizeof print('Our pandas Series, in bytes: ', getsizeof(df.filter(items=['device_id', 'click']))) print('Our bin-counting feature, in bytes: ', getsizeof(device_bin_counts))
Our pandas Series, in bytes: 730104
Our bin-counting feature, in bytes: 95699
就像罕見的詞,罕見的類別須要特殊的處理。想一想一個用戶每一年登陸一次:幾乎沒有數據能夠可靠估計她廣告的點擊率。並且,稀有類別會在計數表中浪費空間。解決這個問題的一種方法是經過補償,一種積累的簡單技術一個特殊垃圾箱中全部稀有類別的數量。若是計數大於必定的門檻,那麼這個類別就有本身的統計數字。不然,使用來自回退箱的統計數據。這基本上會恢復單個的統計信息罕見類別與全部罕見類別的統計數據進行比較。當使用back-off方法,它有助於爲統計信息添加二進制指標來自後退箱。
圖1-4
若是罕見類別得到收益,它可使用本身的統計數據進行建模,從而超過回退庫的閾值。
還有另外一種方法來處理這個問題,稱爲count-min sketch [Cormode和Muthukrishnan,2005]。在這種方法中,全部類別,罕見或頻繁相似經過多個散列函數進行映射,輸出範圍爲
,遠小於類別的數量。當檢索一個統計量時,計算全部的哈希值該類別,並返回最小的統計量。擁有多個散列函數減輕單個散列函數內碰撞的可能性。該計劃有效由於能夠作出散列函數次數,散列表大小小於
,類別的數量,仍然保持較低的總體碰撞可能性。
因爲二進制計數依賴於歷史數據來生成必要的統計數據須要經過數據收集期等待,致使了數據收集時間的輕微延遲學習管道。這也意味着當數據分佈發生變化時,計數須要更新。數據變化越快,計數須要的次數越多從新計算。這對於目標應用程序尤爲重要廣告,用戶偏好和熱門查詢變化很是快,並且缺少適應當前的分佈可能意味着廣告的巨大損失平臺。
有人可能會問,爲何不使用相同的數據集來計算相關統計量並訓練模型?這個想法看起來很無辜。這裏最大的問題是統計涉及目標變量,這是模型試圖預測的。使用輸出來計算輸入特徵會致使一個稱爲泄漏的有害問題。簡而言之,泄漏意味着信息被揭示給模型,從而使它有更好的預測的不切實際的優點。當測試數據泄露到訓練集中,或者將來的數據泄漏到過去時,可能會發生這種狀況。任什麼時候候都會向模型提供在生產中實時進行預測時應該沒法訪問的信息,這會致使泄漏。Kaggle的維基提供了更多泄漏示例以及爲何它對機器學習應用程序不利。
若是二進制計數程序使用當前數據點的標籤來計算輸入統計量的一部分,則這構成直接泄漏。防止這種狀況的一種方法是在計數收集(用於計算箱計數統計)和訓練之間進行嚴格分離,即便用較早批次的數據點進行計數,將當前數據點用於訓練(將分類變量映射到歷史統計咱們剛剛收集),並使用將來的數據點進行測試。這解決了泄漏問題,但引入了上述延遲(輸入統計信息,所以模型將跟蹤當前數據)。
事實證實,還有另外一種基於差異隱私的解決方案。若是統計數據的分佈保持大體相同或不存在任何一個數據點,則該統計近似是防漏的。在實踐中,增長一個分佈拉普拉斯
的小隨機噪聲足以掩蓋單個數據點的任何潛在泄漏。這個想法能夠結合一次性計算來制定當前數據的統計數據。
Owen Zhang在他的「贏得數據科學競賽」的演講中詳細介紹了這個技巧。
若是在愈來愈多的歷史數據下統計數據不斷更新,原始數量將無限增加。這多是模型的問題。訓練有素的模型「知道」輸入數據直至觀察到的比例。一個訓練有素的決策樹可能會說「當x大於3時,預測爲1」。一個通過訓練的線性模型可能會說「乘以0.7的多個x並查看結果是否大於全局平均值」。這些多是x介於0和5之間。可是除此以外會發生什麼?沒有人知道。當輸入計數增長時,模型將須要從新訓練以適應當前的比例。若是計數積累得至關緩慢,那麼有效量表不會變得太快,而且模型不須要過於頻繁地從新訓練。可是當計數增長很快時,頻繁的再培訓將是一個麻煩。
出於這個緣由,使用標準化計數一般會更好。
以已知的時間間隔爲界。例如,估計的點擊率是介於
之間。另外一種方法是採起對數變換,即施加一個嚴格的限制,可是當數量很是大時,增長速度會很慢。這兩種方法都不能防止轉移投入分佈,例如,去年的芭比娃娃如今已通過時,人們將再也不點擊這些廣告。該模型須要從新訓練以適應輸入數據分佈中的這些更根本性的變化,不然整個流程將須要遷移到模型不斷適應輸入的在線學習環境。
空間複雜度:
時間複雜度:
優勢:
缺點
Feature hashing
空間複雜度:
時間複雜度:
優勢:
缺點:
空間複雜度:O(n+k)
時間複雜度:O(n)
優勢:
缺點:
正如咱們所看到的,沒有任何方法是完美的。選擇使用哪個取決於所需的型號。
線性模型比較簡單,所以能夠進行訓練處理非壓縮表示,例如獨熱編碼。
基於樹的模型,另外一方面,須要反覆搜索右側分割的全部特徵,而且是所以限於小型表示,如箱計數。
哈希函數處於在這兩個極端之間,可是由此產生的精確度各有不一樣。
原版(英文)圖書地址:
https://www.oreilly.com/library/view/feature-engineering-for/9781491953235/
本文代碼能夠在github下載:
https://github.com/fengdu78/Data-Science-Notes/tree/master/9.feature-engineering
數據集的百度雲:
連接:https://pan.baidu.com/s/1uDXt5jWUOfI0fS7hD91vBQ 提取碼:8p5d