一份關於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。
文章簡譯,更爲詳細的內容,請查看原文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章