机器学习之knn

1、KNN分类算法

KNN分类算法(K-Nearest-Neighbors Classification),又叫K近邻算法,是一个概念极其简单,而分类效果又很优秀的分类算法。

他的核心思想就是,要确定测试样本属于哪一类,就寻找所有训练样本中与该测试样本“距离”最近的前K个样本,然后看这K个样本大部分属于哪一类,那么就认为这个测试样本也属于哪一类。简单的说就是让最相似的K个样本来投票决定。

KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的 权值(weight),如权值与距离成反比。 该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的解决方法是事先对已知 样本点进行剪辑,事先去除对分类作用不大的样本。该算法比较适用于 样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
实现 K 近邻算法时,主要考虑的问题是如何对训练数据进行快速 K 近邻搜索,这在特征空间维数大及训练数据容量大时非常必要。
2、数据集介绍

machine-learning-databases/iris 点击打开链接

数据集信息:

这也许是最著名的数据库模式识别文献中被发现。 费舍尔的论文是一个典型的,经常被引用。 (见杜达&哈特,例如)。 50个实例的数据集包含3类,其中

每个类是指一种虹膜。 一个类是线性可分的从其他2;后者不是线性可分的。 

预测属性:类的虹膜。 

UCI中的Iris(鸢尾属植物)数据集。Iris数据包含150条样本记录,分剐取自三种不同的鸢尾属植物setosa、versic010r和virginica的花朵样本,每一

类各50条记录,其中每条记录有4个属性:萼片长度(sepal length)、萼片宽度sepalwidth)、花瓣长度(petal length)和花瓣宽度(petal width)。

这是一个极其简单的域。 


3、完整源码
[html]  view plain  copy
  1. <pre code_snippet_id="1766654" snippet_file_name="blog_20160717_1_8836404" name="code" class="python">#-*- coding: UTF-8 -*-     
  2. '''''   
  3. Created on 2016/7/17   
  4.    
  5. @author: chen   
  6. '''    
  7. import csv     #用于处理csv文件    
  8. import random    #用于随机数    
  9. import math             
  10. import operator  #    
  11. from sklearn import neighbors    
  12.     
  13. #加载数据集    
  14. def loadDataset(filename,split,trainingSet=[],testSet = []):    
  15.     with open(filename,"rb") as csvfile:    
  16.         lines = csv.reader(csvfile)    
  17.         dataset = list(lines)    
  18.         for x in range(len(dataset)-1):    
  19.             for y in range(4):    
  20.                 dataset[x][y] = float(dataset[x][y])    
  21.             if random.random()<split:    
  22.                 trainingSet.append(dataset[x])    
  23.             else:    
  24.                 testSet.append(dataset[y])    
  25.     
  26. #计算距离    
  27. def euclideanDistance(instance1,instance2,length):    
  28.     distance = 0    
  29.     for x in range(length):    
  30.         distance = pow((instance1[x] - instance2[x]),2)    
  31.     return math.sqrt(distance)    
  32.     
  33. #返回K个最近邻    
  34. def getNeighbors(trainingSet,testInstance,k):    
  35.     distances = []    
  36.     length = len(testInstance) -1    
  37.     #计算每一个测试实例到训练集实例的距离    
  38.     for x in range(len(trainingSet)):    
  39.         dist = euclideanDistance(testInstance, trainingSet[x], length)    
  40.         distances.append((trainingSet[x],dist))    
  41.     #对所有的距离进行排序    
  42.     distances.sort(key=operator.itemgetter(1))    
  43.     neighbors = []    
  44.     #返回k个最近邻    
  45.     for x in range(k):    
  46.         neighbors.append(distances[x][0])    
  47.     return neighbors    
  48.     
  49. #对k个近邻进行合并,返回value最大的key    
  50. def getResponse(neighbors):    
  51.     classVotes = {}    
  52.     for x in range(len(neighbors)):    
  53.         response = neighbors[x][-1]    
  54.         if response in classVotes:    
  55.             classVotes[response]+=1    
  56.         else:    
  57.             classVotes[response] = 1    
  58.     #排序    
  59.     sortedVotes = sorted(classVotes.iteritems(),key = operator.itemgetter(1),reverse =True)    
  60.     return sortedVotes[0][0]    
  61.     
  62. #计算准确率    
  63. def getAccuracy(testSet,predictions):    
  64.     correct = 0    
  65.     for x in range(len(testSet)):    
  66.         if testSet[x][-1] == predictions[x]:    
  67.             correct+=1    
  68.     return (correct/float(len(testSet))) * 100.0    
  69.     
  70. def main():    
  71.     trainingSet = []  #训练数据集    
  72.     testSet = []      #测试数据集    
  73.     split = 0.67      #分割的比例    
  74.     loadDataset(r"../data/iris.txt", split, trainingSet, testSet)     
  75.     print "Train set :" + repr(len(trainingSet))    
  76.     print "Test set :" + repr(len(testSet))                    
  77.         
  78.     predictions = []    
  79.     k = 3    
  80.     for x in range(len(testSet)):    
  81.         neighbors = getNeighbors(trainingSet, testSet[x], k)    
  82.         result = getResponse(neighbors)    
  83.         predictions.append(result)    
  84.         print ">predicted = " + repr(result) + ",actual = " + repr(testSet[x][-1])    
  85.     accuracy = getAccuracy(testSet, predictions)    
  86.     print "Accuracy:" + repr(accuracy) + "%"    
  87.     
  88. if __name__ =="__main__":    
  89.     main()  </pre><br>  
  90. <br>  
  91. <pre></pre>  
  92. <div><br>  

  1. </div>  
  2. 2. sklearn knn的使用,以及cross validation交叉验证

    2.1 数据集的准备

    数据集来源:https://archive.ics.uci.edu/ml/datasets/Iris

    代码github地址以及数据集github地址,见本人的github


    import numpy as np
    from sklearn.metrics import accuracy_score
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.cross_validation import train_test_split, cross_val_score
    import pandas as pd
    import matplotlib.pyplot as plt
    
    
    def load_data():
        names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class']
        # loading training data
        path = '../dataset/knn/iris_data.txt'
        df = pd.read_csv(path, header=None, names=names)
        # print df.head()
        x = np.array(df.ix[:, 0: 4])
        y = np.array(df['class'])
    
        print x.shape, y.shape
        # x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=40)
        return train_test_split(x, y, test_size=0.33, random_state=40)
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    这里写图片描述

    2.2 验证预测效果
    def predict():
        x_train, x_test, y_train, y_test = load_data()
        k = 3
        knn = KNeighborsClassifier(n_neighbors=k)
        knn.fit(x_train, y_train)
        pred = knn.predict(x_test)
        print accuracy_score(y_test, pred)
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    2.3 交叉验证
    def cross_validation():
        x_train, x_test, y_train, y_test = load_data()
        k_lst = list(range(1, 30))
        lst_scores = []
    
        for k in k_lst:
            knn = KNeighborsClassifier(n_neighbors=k)
            scores = cross_val_score(knn, x_train, y_train, cv=10, scoring='accuracy')
            lst_scores.append(scores.mean())
    
        # changing to misclassification error
        MSE = [1 - x for x in lst_scores]
        optimal_k = k_lst[MSE.index(min(MSE))]
        print "The optimal number of neighbors is %d" % optimal_k
        # plot misclassification error vs k
        # plt.plot(k_lst, MSE)
        # plt.ylabel('Misclassification Error')
        plt.plot(k_lst, lst_scores)
        plt.xlabel('Number of Neighbors K')
        plt.ylabel('correct classification rate')
        plt.show()
         
         
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这里写图片描述


    knn改进方法
    1. 不同的K值加权

    2. 距离度量标准根据实际问题,使用不同的距离

    3. 特征归一化,例如,身高和体重x=[180,70],升高计算明显,更影响结果,所有需要对两者分别求平均值,然后归一化。

    4. 如果维数过大,可以做PCA降维处理


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: B'educoder机器学习KNN算法'是指在机器学习,使用KNN(K-最近邻)算法进行数据分类或回归的过程。它通过计算每个样本点与其最近的k个邻居之间的距离来分类或回归。该算法常用于给定一些已经被分类或回归的数据,以对新的、未知的数据进行分类或回归。 ### 回答2: KNN算法机器学习最常见的分类算法之一,属于无参数的非线性算法,也是解决分类问题的一种最简单有效的算法之一。KNN全称为K-Nearest Neighbor算法,它的主要思想是如果一个样本在特征空间的k个最相似(即特征空间最近)的样本的大多数属于某一个类别,则该样本也属于这个类别。 KNN算法的主要流程是先将数据集所有实例按照特征向量之间的距离从小到大进行排序,然后选取相邻的K个样本,根据它们属于的类别计算出该样本的类别,即选取K个样本出现最多的类别作为该样本的预测类别。通常情况下,K的选择是非常重要的,如果K太小会使得预测错误率变高,而K太大会使得不同的样本预测出的类别相同,从而无法实现分类。 KNN算法的应用非常广泛,包括文本分类、图像识别、推荐系统等领域。由于该算法的思路简单易懂且计算量相对较小,因此它在大数据时代依然被广泛应用。同时,在KNN算法的基础上也有很多改进算法被提出,如KD树、球树等,它们可以有效地提高KNN算法的运行效率和准确率。 在educoder机器学习的学习,我们可以利用Python语言的scikit-learn库实现KNN算法。该库提供了KNeighborsClassifier类,它可以根据给定的数据集和K值训练KNN分类器,并用来预测新的样本。在使用scikit-learn库进行分类问题解决时,通常需要将数据进行归一化处理,以避免特征之间的差异对结果的影响。同时,还需要采用交叉验证等方法优化模型的参数和选择最优的K值,从而提高KNN算法的准确率和泛化能力。 总的来说,KNN算法机器学习一种简单有效的分类算法,它的应用非常广泛。在educoder机器学习的学习,我们可以通过掌握KNN算法的基本原理和应用方法,来更好地应用这种算法解决实际的分类问题。 ### 回答3: KNN(K-Nearest Neighbor)算法是一种基本的分类和回归算法,经常被用于机器学习。其基本思想是预测未知的样本所属类别或预测目标值,通过已知的样本集来找到与未知样本最近的K个样本(即K个最近邻)来进行预测。KNN算法的核心是距离度量和K值的选择。 在KNN算法的训练过程,首先需要将所有样本的特征向量保存在内存里。对于一个未知的样本,计算其与内存所有样本的距离,并选出离该样本最近的K个样本。可以使用欧式距离或曼哈顿距离来度量距离。在分类问题,K个邻居样本占比最大的那个类别即为预测结果;在回归问题,K个邻居的目标值的平均值或加权平均值即为预测结果。 KNN算法的优点是简单有效,不需要训练过程,可以自适应地进行分类或回归。但也存在缺点,如不善处理多分类问题和高维数据,受样本分布的影响较大等。在实际应用,可以采用交叉验证和特征选择等手段来解决一些问题。 在educoder机器学习KNN算法教学,可以学习到该算法的具体实现和应用,如如何选择距离度量、K值的选择和分类与回归问题的应用。同时也可以通过练习和作业来加深对算法的理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值