1. 程式人生 > >十大機器學習演算法之KNN(用於信用風險)

十大機器學習演算法之KNN(用於信用風險)

    k-Nearest Neighbor(簡稱KNN)是“懶惰學習”的代表,此類技術在訓練階段僅僅是將訓練樣本儲存起來,不會去構造一個泛化的內部模型,即訓練開銷為零,帶收到測試集時再進行處理,與之對應的是“急切學習”。

    演算法原理:對給定的測試樣本,基於某種距離度量尋找與其相鄰最近的k個訓練樣本,再依據“投票法”(分類)或“平均法”(迴歸)確定其分類,顯然在k取不同值的時候,結果可能是不同的。該演算法雖然非常簡單,但其泛華錯誤率不會超過貝葉斯最優分類器的錯誤率的兩倍(Cover & Hart, 1967)。

    在資料量比較小時,採用暴力演算法計算出每個測試樣本與所有訓練資料的距離是很具競爭力的,但對於資料量較大時,暴力演算法就不切實際了。為了解決效率低下的暴力計算方法,已經發明瞭大量的基於樹的資料結構。總的來說,這些結構試圖通過有效地編碼樣本的 aggregate distance (聚合距離) 資訊來減少所需的距離計算量。基本思想是,若

A點距離 B點非常遠,B點距離 C點非常近,可知 A點與 C點很遙遠,不需要明確計算它們的距離。 通過這樣的方式,近鄰搜尋的計算成本可以降低為O[nlog(n)]或更低。這是對於暴力搜尋在大樣本數 N中表現的顯著改善。

    利用這種聚合資訊的早期方法是 KD tree 資料結構(* K-dimensional tree* 的簡寫),它將二維 Quad-trees 和三維 Oct-trees 推廣到任意數量的維度。KD 樹是一個二叉樹結構,它沿著資料軸遞迴地劃分引數空間,將其劃分為嵌入資料點的巢狀的各向異性區域。 KD 樹的構造非常快:因為只需沿資料軸執行分割槽, 無需計算 D-dimensional

距離。 一旦構建完成, 查詢點的最近鄰距離計算複雜度僅為O[log(n)]。 雖然 KD 樹的方法對於低維度 (D<20) 近鄰搜尋非常快, 當D增長到很大時, 效率變低: 這就是所謂的 “維度災難” 的一種體現。

    為了解決 KD 樹在高維上效率低下的問題, ball 樹 資料結構就被研發出來了. 其中 KD 樹沿卡迪爾軸(即座標軸)分割資料, ball 樹在沿著一系列的 hyper-spheres 來分割資料. 通過這種方法構建的樹要比 KD 樹消耗更多的時間, 但是這種資料結構對於高結構化的資料是非常有效的, 即使在高維度上也是一樣。ball 樹將資料遞迴地劃分為由質心C半徑

r定義的節點,使得節點中的每個點位於由 rC定義的 hyper-sphere 內. 通過使用 triangle inequality(三角不等式) 減少近鄰搜尋的候選點數:

                                                                                             |x+y|≤|x|+|y|

通過這種設定, 測試點和質心之間的單一距離計算足以確定距節點內所有點的距離的下限和上限. 由於 ball 樹節點的球形幾何, 它在高維度上的效能超出 KD-tree, 儘管實際的效能高度依賴於訓練資料的結構。


# coding: utf-8



# In[7]:

import pandas as pd
import numpy as np
import time,os,sys,datetime


# In[25]:

from sklearn.neighbors import KNeighborsClassifier


# In[12]:

train_df = pd.read_csv('traindata.csv')
test_df = pd.read_csv('testdata.csv')


# In[13]:

train_df.columns


# In[20]:

X = train_df[['gender', 'marriage', 'creditLevel',
       'sumCreditPoint', 'salary', 'workYears', 'graduation', 
       'hasHouse','houseLoan', 'hasCar', 'carLoan', 'amount', 
       'interest', 'months', 'age', 'effort_degree', 'city_score',
       'audit_num']].values


# In[21]:

y = train_df.overDued.values


# In[26]:

knn = KNeighborsClassifier(n_neighbors=5)


# In[27]:

knn.fit(X, y)


# In[28]:

knn.score(X, y)


# In[29]:

test_X = test_df[['gender', 'marriage', 'creditLevel',
       'sumCreditPoint', 'salary', 'workYears', 'graduation', 
       'hasHouse','houseLoan', 'hasCar', 'carLoan', 'amount', 
       'interest', 'months', 'age', 'effort_degree', 'city_score',
       'audit_num']].values
test_y = test_df.overDued.values


# In[30]:

knn.score(test_X, test_y)


# In[36]:

test_y_pred = knn.predict(test_X)


# In[35]:

from sklearn.metrics import classification_report


# In[40]:

print(classification_report(test_y, test_y_pred, target_names=['no_default','default']))


             precision    recall  f1-score   support

 no_default       0.99      0.94      0.97     12137
    default       0.43      0.78      0.55       643

avg / total       0.96      0.94      0.95     12780