1. 程式人生 > >一份關於kaggle特徵構建技巧和心得

一份關於kaggle特徵構建技巧和心得

       在很長的一段時間裡,我們表現出缺乏創造力,所做出的工作被認為是山寨、借鑑,這一點是不可否認,但隨著自身的積累,厚積薄發,完成了從借鑑到創造的突破。創造力是我們工作的基本要素之一,這點在各行各業都顯得很重要,在機器學習領域也無所例外。
       建立特徵也需要創造力,因此本文在這裡列出了我日常生活中的一些想法,希望對其它人有些啟發,以至於能夠在此基礎上利用創造力在Kaggle排行榜上取得很好的成績。
       這篇文章的靈感來自於 Beluga在Kaggle上分享的文章

,本文部分內容是直接摘自該文章中,因此,讀者也可以看看這篇文章。以下是分享的正文:

1.當不需要時,不要嘗試預測未來:

       如果訓練/測試都來自同一時間線,那麼就可以非常巧妙地使用特性。雖然這只是一個kaggle的案例,但可以利用這個優勢。例如:在出租車出行持續時間挑戰賽中,從訓練資料中隨機抽取測試資料。在這種情況下,可以使用不同類別變數的平均目標變數作為特徵。在這種情況下, Beluga 實際上使用了不同工作日的平均目標變數。然後,將相同的平均值對映為一個變數,並將其對映到測試資料中。

2. logloss裁剪技術:

       這部分內容是在Jeremy Howard的神經網路課程中學到的內容,它基於一個非常簡單的想法。如果我們非常自信和不公正的,Logloss會受到很多懲罰。因此,在必須預測概率的分類問題情況下,將概率剪下在0.05-0.95之間會好得多,這樣就對自己的預測變得不是十分確定。

3.以gzip格式提交到kaggle:

       下面一小段程式碼可以幫助我們節省無數的上傳時間:

df.to_csv('submission.csv.gz', index=False, compression='gzip')

4.如何最好地使用緯度和經度特徵——第1部分:

       在Beluga寫的文章中,我最喜歡的一部分內容之一就是他如何使用經緯度(Lat / Lon)資料,這裡建立了以下特徵:

A.兩個經緯度之間的Haversine距離:

def haversine_array(lat1, lng1, lat2, lng2):
    lat1, lng1, lat2, lng2 = map(np.radians, (lat1, lng1, lat2, lng2))
    AVG_EARTH_RADIUS = 6371  # in km
    lat = lat2 - lat1
    lng = lng2 - lng1
    d = np.sin(lat * 0.5) ** 2 + np.cos(lat1) * np.cos(lat2) * np.sin(lng * 0.5) ** 2
    h = 2 * AVG_EARTH_RADIUS * np.arcsin(np.sqrt(d))
    return h

B.兩個經緯度之間的曼哈頓距離:

def dummy_manhattan_distance(lat1, lng1, lat2, lng2):
    a = haversine_array(lat1, lng1, lat1, lng2)
    b = haversine_array(lat1, lng1, lat2, lng1)
    return a + b

C.兩個經緯度之間的方位:

def bearing_array(lat1, lng1, lat2, lng2):
    AVG_EARTH_RADIUS = 6371  # in km
    lng_delta_rad = np.radians(lng2 - lng1)
    lat1, lng1, lat2, lng2 = map(np.radians, (lat1, lng1, lat2, lng2))
    y = np.sin(lng_delta_rad) * np.cos(lat2)
    x = np.cos(lat1) * np.sin(lat2) - np.sin(lat1) * np.cos(lat2) * np.cos(lng_delta_rad)
    return np.degrees(np.arctan2(y, x))

D.取放點之間的中心緯度和經度:

train.loc[:, 'center_latitude'] = (train['pickup_latitude'].values + train['dropoff_latitude'].values) / 2
train.loc[:, 'center_longitude'] = (train['pickup_longitude'].values + train['dropoff_longitude'].values) / 2

5.如何最好地使用經緯度特徵——第2部分:

在Beluga寫的文章中,他使用經緯度資料的第二種方式是為取放點的經緯度建立叢集,它的工作方式是通過設計在資料中建立了一些行政區。

from sklearn.cluster import MiniBatchKMeans
coords = np.vstack((train[['pickup_latitude', 'pickup_longitude']].values,
                    train[['dropoff_latitude', 'dropoff_longitude']].values,
                    test[['pickup_latitude', 'pickup_longitude']].values,
                    test[['dropoff_latitude', 'dropoff_longitude']].values))

sample_ind = np.random.permutation(len(coords))[:500000]
kmeans = MiniBatchKMeans(n_clusters=100, batch_size=10000).fit(coords[sample_ind])

train.loc[:, 'pickup_cluster'] = kmeans.predict(train[['pickup_latitude', 'pickup_longitude']])
train.loc[:, 'dropoff_cluster'] = kmeans.predict(train[['dropoff_latitude', 'dropoff_longitude']])
test.loc[:, 'pickup_cluster'] = kmeans.predict(test[['pickup_latitude', 'pickup_longitude']])
test.loc[:, 'dropoff_cluster'] = kmeans.predict(test[['dropoff_latitude', 'dropoff_longitude']])

       然後,他使用這些叢集建立了一些特徵,例如比如計算某一天外出和入境的次數。

6.如何最好地使用緯度和經度特徵——第3部分

       在Beluga寫的文章中,還使用了PCA方法來轉換經度和緯度座標。在這種情況下,它不是進行降維,而是進行了座標的變換,2D—>2D變換,它實際上做了如下操作。

pca = PCA().fit(coords)
train['pickup_pca0'] = pca.transform(train[['pickup_latitude', 'pickup_longitude']])[:, 0]
train['pickup_pca1'] = pca.transform(train[['pickup_latitude', 'pickup_longitude']])[:, 1]
train['dropoff_pca0'] = pca.transform(train[['dropoff_latitude', 'dropoff_longitude']])[:, 0]
train['dropoff_pca1'] = pca.transform(train[['dropoff_latitude', 'dropoff_longitude']])[:, 1]
test['pickup_pca0'] = pca.transform(test[['pickup_latitude', 'pickup_longitude']])[:, 0]
test['pickup_pca1'] = pca.transform(test[['pickup_latitude', 'pickup_longitude']])[:, 1]
test['dropoff_pca0'] = pca.transform(test[['dropoff_latitude', 'dropoff_longitude']])[:, 0]
test['dropoff_pca1'] = pca.transform(test[['dropoff_latitude', 'dropoff_longitude']])[:, 1]

7.不要忘記可以用特徵做的正常事情:

  • 按Max-Min縮放;
  • 使用標準偏差進行標準化;
  • 基於特徵/目標的日誌:使用基於特徵或基於目標特徵的日誌;
  • 熱編碼;

8.建立直觀的附加特徵:

  • A)日期時間特徵:基於時間的特徵,如“晚上”、“中午”、“夜晚”、“上月購買行為”,“上週購買行為”等;
  • B)思想特徵:假設有購物車資料,並且想要對行程進行分類(參閱Walmart Recruiting:Kaggle的行程型別分類);

       此外,還可以考慮建立一個像“時尚”這樣的特徵,可以通過新增屬於男裝時尚、女裝時尚、青少年時尚類別的專案來建立這個變數。
       另外,也可以建立一個像“稀有”這樣的特徵,它是根據我們擁有的資料標記一些稀有物品然後計算購物車中稀有物品的數量而建立的,這些特徵可能是有效的或無效的。根據我的觀察,它們通常能夠提供很多價值。

9.做的不那麼正常的事情:

       這些特徵非常不直觀,不應在機器學習模型需要解釋的地方建立。

  • A)互動特徵:如果有特徵A和B,並建立特徵A * B、A + B、A / B、AB,這會使得特徵空間爆炸。如果你有10個特徵,並且要建立兩個可變互動特徵,這將為模型新增 180個特徵。並且,絕大多數時候,都會有超過10個的特徵。
  • B)使用雜湊的儲存桶特徵:假設你有數千的特徵,並按順序排好,但考慮到演算法的訓練時間,並不想使用所有的數千千個特徵。一般是使用一些雜湊演算法來實現這一點,最後完成文字分類任務。

例如:
       假設有6個特徵A、B、C、D、E、F:
並且資料行是:

A:1、B:1、C:1、D:0、E:1、F:0 

       可能決定使用雜湊函式,以便這6個特徵對應於3個桶並建立使用此特徵的資料雜湊向量。
       處理完後,資料可能如下所示:

Bucket1:2、Bucket2:2、Bucket3:0

       A:1、B:1、C:1、D:0、E:1、F:0 之所以發生這種情況是因為A和B掉落在桶1中、C和E落在桶2中、D和F落在桶3中。這裡只是總結了上述的觀察結果,你也可以用你想要的任何數學函式替換掉上述的加法操作。
之後,將使用Bucket1、Bucket2、Bucket3作為機器學習的變數。
       A:1、B:1、C:1、D:0、E:1、F:0 以上是本文的全部內容,後續將持續更新,如果讀者有比較好的處理方法,請在下面留言給出。

作者資訊

Rahul Agarwal,統計分析
本文由阿里云云棲社群組織翻譯。
文章原標題《Good Feature Building Techniques and Tricks for Kaggle》,譯者:海棠,審校:Uncle_LLD。
文章簡譯,更為詳細的內容,請檢視原文