1. 程式人生 > >特徵雜湊編碼及雜湊演算法

特徵雜湊編碼及雜湊演算法

       前言

        在特徵處理中,可以利用笛卡爾乘積的方法來構造組合特徵。這種方法雖然簡單,但麻煩的是會使得特徵數量爆炸式增長。比如一個可以取N個不同值的類別特徵,與一個可以去M個不同值的類別特徵做笛卡爾乘積,就能構造出N*M個組合特徵。

        特徵太多這個問題在具有個性化的問題裡尤為突出。如果把使用者id看成一個類別特徵,那麼它可以取的值的數量就等於使用者數。把這個使用者id特徵與其他特徵做笛卡爾積,就能產生龐大的特徵集。做廣告演算法的公司經常宣稱自己模型裡有幾十上百億的特徵,基本都是這麼搞出來的。

        當然,特徵數量多的問題自古有之,高基數類別特徵在啞編碼後,也會造成高緯度的情況。雖然目前也已經有很多用於降維的方法,比如聚類、PCA等都是常用的降維方法。但這類方法在特徵量和樣本量很多的時候本身就計算量很大,所以對大問題也基本無能為力。

        雜湊演算法        

       雜湊演算法並不是一個特定的演算法而是一類演算法的統稱。雜湊演算法也叫雜湊演算法,一般來說滿足這樣的關係:f(data)=key,輸入任意長度的data資料,經過雜湊演算法處理後輸出一個定長的資料key。同時這個過程是不可逆的,無法由key逆推出data。

        如果是一個data資料集,經過雜湊演算法處理後得到key的資料集,然後將keys與原始資料進行一一對映就得到了一個雜湊表。一般來說雜湊表M符合M[key]=data這種形式。雜湊表的好處是當原始資料較大時,我們可以用雜湊演算法處理得到定長的雜湊值key,那麼這個key相對原始資料要小得多。我們就可以用這個較小的資料集來做索引,達到快速查詢的目的。

        因此在面對高基數類別變數時,就可以用特徵雜湊法編碼的方式將原始的高維特徵向量壓縮成較低維特徵向量,且儘量不損失原始特徵的表達能力。

        但是哈斯演算法有一個問題,就是雜湊值是一個有限集合,而輸入資料則可以是無窮多個。那麼建立一對一關係明顯是不現實的。所以"碰撞"(不同的輸入資料對應了相同的雜湊值)是必然會發生的,所以一個成熟的雜湊演算法會有較好的抗衝突性。同時在實現雜湊表的結構時也要考慮到雜湊衝突的問題。

       但是有一份部落格做過這個實驗,發現特徵雜湊法可以降低特徵數量,從而加速演算法訓練與預測過程,以及降低記憶體消耗;但代價是通過雜湊轉換後學習的模型變得很難檢驗,我們很難對訓練出的模型引數做出合理解釋。特徵雜湊法的另一個問題是它會把多個原始特徵雜湊到相同的位置上,出現雜湊裡的collision現象。但實際實驗表明這種collision對演算法的精度影響很小。

      特徵雜湊法優勢

      1.實現簡單,所需額外計算量小;

      2.可以新增新的任務(如新使用者),或者新的原始特徵而保持雜湊轉換後的特徵長度不變,很適合任務數頻繁變化的問題(如個性化推薦裡新使用者,新item的出現);

      3.可以保持原始特徵的稀疏性,既然雜湊轉換時只有非0原始特徵才起作用。    

      python程式碼嘗試: