十大机器学习算法之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



猜你喜欢

转载自blog.csdn.net/PyDarren/article/details/82454370