学习笔记——Kaggle_Digit Recognizer (KNN算法 Python实现)

来源:互联网 发布:网络用语128是什么意思 编辑:程序博客网 时间:2024/06/11 05:15

本文是个人学习笔记,该篇主要学习KNN算法理论和应用范围,并应用KNN算法解决Kaggle入门级Digit Recognizer,也是个人入坑ML和Kaggle的开端,希望能够有始有终。

  • KNN算法
  • 距离计算算法
  • Python 代码

KNN算法

K最近邻分类算法(K-NearestNeighbor),由Cover和Hart在1968年提出,是最简单的机器学习算法之一,主要被应用于文本分类、相似推荐

基本原理:
从训练样本集中选择k个与测试样本“距离”最近的样本,该k个样本中出现频率最高的类别即作为测试样本的类别,其中参数k的取值通常不大于20。

实现流程:
算法目标:未知类别样本集分类;
输入信息:待分类目标样本集和已分类学习样本集;
输出结果:已分类目标样本集;

算法步骤:
(a) 确定k值,即每个待分类样本要到它k个已分类样本邻居;
(b) 根据距离度量公式(如:欧氏距离),确定待分类样本集和已分类样本集中,距离该样本点最近的k个样本;
(c) 统计该k个邻居样本中,各类别的数量。最终将待分类样本点定义为数量最多的类别;

优缺点:
算法简单,易于实现,不需要参数估计,不需要事先训练;但由于不进行事先训练,而在输入待分类样本集时才开始,导致KNN计算量特别大;同时训练样本必须存储在本地,消耗大量内存。


距离计算算法

在数据分析和数据挖掘中,个体间的“距离”实际是对个体间差异大小的空间衡量,距离越远说明个体间的差异越大,然后根据实际差异情况进行相关性分析

假设:X个体和Y个体都包含了N个维的特征,即X=(x1x2x3xnY=y1y2y3yn

欧几里得距离(欧式距离):
欧式距离是最常用的距离度量,计算多维空间中各点之间的绝对距离。因为距离计算是基于各维度特征的绝对数值,所以需要保证各维度指标在相同的刻度级别。

公式:

dist(X,Y)=i=1n(xiyi)2

马哈拉诺比斯距离(马氏距离):
马氏距离是欧式距离的改进版本,即基于各指标维度进行标准化后再使用欧氏距离,规避了指标度量的差异;


曼哈顿距离:
曼哈顿距离来源于城市区块距离,是将多个维度上的距离进行求和后的结果;

公式:

dist(X,Y)=i=1n|xiyi|


切比雪夫距离:
切比雪夫距离起源于国际象棋中国王的走法,国际象棋国王每次只能往周围的8格中走一步,那么如果要从棋盘中A格x1y1走到B格x2y2最少需要走几步。

公式:

dist(X,Y)=limp(i=1n|xiyi|p)1/p


明可夫斯基距离(明氏距离):
明氏距离是欧式距离的推广版本,是多个距离度量公式的概括性表述。

公式:

dist(X,Y)=(i=1n|xiyi|p)1/p

当p值为1时,即为曼哈顿距离,p值为2时,即为欧式距离,而当p趋向于无穷时,即为切比雪夫距离;


Python 代码

Python 代码1:

import pandas as pdimport numpy as npimport timeimport operatordef data_load():    # 利用pandas读取csv文件内容    train_ttl=pd.read_csv('/Users/Sweet-home/PycharmProjects/Kaggle/reco data/train.csv')    train_label=pd.DataFrame(train_ttl['label'])    train_data=pd.DataFrame(train_ttl.ix[:,1:])    test_data=pd.read_csv('/Users/Sweet-home/PycharmProjects/Kaggle/reco data/test.csv')    # dataframe归整化    train_data[train_data!=0]=1    test_data[test_data!=0]=1    return train_data,train_label,test_data    #inX:1*n  dataSet:m*n labels:m*1def classify(inX, dataSet, labels, k): #确定类别    diffmats = (dataSet-inX)**2#计算KNN 欧式距离    sumdiffs=diffmats.sum(axis=1)    distances=sumdiffs**0.5    sortedDistIndicies = distances.argsort()#根据距离排序    classcount={}    for i in range(k):#统计各标签值count        votelabel = labels.ix[sortedDistIndicies[i],0]        classcount[votelabel] = classcount.get(votelabel,0) + 1    # 根据字典值降序排序    sortedClassCount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)    # 返回最相似label值    return sortedClassCount[0][0]if __name__=='__main__':    start = time.clock()    traindata,trainlabel,testdata=data_load()#加载raw data    m,n=testdata.shape    result_labels=[]    result={}    for i in range(m):#对test样本一次确定其类别        result_label=classify(testdata.ix[i],traindata,trainlabel,8)        result_labels.append(result_label)    #将结果转化成Dataframe结构    ImageId=np.arange(m)+1    result['Label']=result_labels    result_frame=pd.DataFrame(result,index=ImageId)    #导出结果    result_frame.to_csv('/Users/Sweet-home/PycharmProjects/Kaggle/reco data/result.csv')    end = time.clock()    print('总耗时:', end - start)

Python 代码2:

import pandas as pdimport numpy as npimport timefrom sklearn.neighbors import KNeighborsClassifierdef data_load():    # 利用pandas读取csv文件内容    train_ttl=pd.read_csv('D:\Program files\JetBrains\digit recognizer\Raw data\\train.csv')    train_label=pd.DataFrame(train_ttl['label'])    train_data=pd.DataFrame(train_ttl.ix[:,1:])    test_data=pd.read_csv('D:\Program files\JetBrains\digit recognizer\Raw data\\test.csv')    # dataframe归整化    test_data[test_data!=0]=1    # train_data[train_data!=0]=1    m,n=train_data.shape#这里似乎因为dataframe太大,用bool判断更改时总会异常跳出,所以选择循环更改    for i in range(m):        for j in range(n):            if train_data.ix[i,j]!=0:                train_data.ix[i,j]=1    return train_data,train_label,test_data#利用Python Sklearn包,进行test样本集分类判别def knn_classify(traindata,trainlabel,testdata):    knn_clf = KNeighborsClassifier(n_neighbors=5, algorithm='kd_tree', weights='distance', p=3)#设置参数    knn_clf.fit(traindata,trainlabel.values.ravel())#训练Train样本    knn_result=knn_clf.predict(testdata)#预测Test样本    return knn_resultif __name__=='__main__':    start = time.clock()    traindata,trainlabel,testdata=data_load()#加载raw data    m,n=testdata.shape    result_labels=knn_classify(traindata,trainlabel,testdata)    #将结果转化成Dataframe结构    result={}    ImageId=np.arange(m)+1    result['Label']=result_labels    result_frame=pd.DataFrame(result,index=ImageId)    #导出结果    result_frame.to_csv('D:\Program files\JetBrains\digit recognizer\Raw data\\result.csv')    end = time.clock()    print('总耗时:', end - start)#接近5小时
2 0
原创粉丝点击