KNN

机器学习之KNN

  1. K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表
     核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。KNN算法的结果很大程度取决于K的选择
      优点:精度高,对异常值不敏感,无数据输入假定
      缺点:计算复杂度高,空间复杂度高
      使用数据范围:数据型和标称型

  2. 算法三要素:
          k值的选取:较小的k值,训练误差会减小,容易发生过拟合
                较大的k值,减少泛化误差,训练误差会增大
          距离度量的方式:
          分类决策规则:分类:多数表决法
           回归:平均值

  3. 距离:
          

  4. 分类决策规则
      分类
       多数表决法
      回归
       平均值

KNN的主要优点有:
 1.理论成熟,思想简单,既可以用来做分类也可以用来做回归
 2. 可用于非线性分类
 3. 训练时间复杂度比支持向量机之类的算法低,仅为O(n)
 4.和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
 5.由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
 6.该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分小结
KNN的主要缺点有
  1.计算量大,尤其是特征数非常多的时候
  2.样本不平衡的时候,对稀有类别的预测准确率低
  3. KD树,球树之类的模型建立需要大量的内存
  4.使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
  5. 相比决策树模型,KNN模型可解释性不强

"""
自定义实现knn算法:
    给定一组数据集:这组数据集包括(x,y)
    然后 给定一个预测的样本
    通过knn来预测该样本属于哪个分类
样本集:
    1,1,A
    1,2,A
    1.5,1.5,A
    3,4,B
    4,4,B
预测数据:
    2,2
请通过knn来对该数据进行分类预测

算法实现思路:
1.计算预测样本和数据集中样本的距离
2.将所有距离从小到大排序
3.计算前k个最小距离的类别的个数
4.返回前k个最小距离中 个数最多的分类
"""
import numpy as np
import operator

def handle_data(dataset):
    """
    :param dataset: 样本集
    :return: 输出 x和y
    """
    x = dataset[:, :-1].astype(np.float)
    y = dataset[:, -1]
    return x,y


def knn_classifier(k,dataset,input):
    """
    :param k:  k个邻居
    :param dataset: 所有数据集
    :param input: 输出的预测数据
    :return: 输出预测的分类
    """
    x,y = handle_data(dataset)
    #1.计算预测样本和数据集中样本的距离
    distance = np.sum((input-x)**2,axis=1)**0.5
    #2.将所有距离从小到大排序
    sortedDist = np.argsort(distance)
    #3.计算前k个最小距离的类别的个数
    countLabel={}
    for i in range(k):
        label = y[sortedDist[i]]
        countLabel[label] = countLabel.get(label,0)+1
    print(countLabel)
    #4.返回前k个最小距离中 个数最多的分类
    # maxCount = 0
    # label =None
    # for k,v in countLabel.items():
    #     if v>maxCount:
    #         maxCount = v
    #         label = k
    sortedLabel = sorted(countLabel.items(),key=operator.itemgetter(1),reverse=True)
    return sortedLabel[0][0]

if __name__=="__main__":
    dataset = np.loadtxt("dataset.txt",dtype=np.str,delimiter=",")

    #预测数据
    predict_data =[2,2]
    print(knn_classifier(3,dataset,predict_data))

sklearn_knn

import numpy as np

from sklearn.neighbors import KNeighborsClassifier

if __name__=="__main__":
    dataset = np.loadtxt("dataset.txt",dtype=np.str,delimiter=",")
    x = dataset[:,:-1].astype(np.float)
    y = dataset[:,-1]
    #建立模型
    model = KNeighborsClassifier(n_neighbors=5,weights="distance")
    #训练模型
    model.fit(x,y)
    #预测
    predict_data = [[2, 2]]
    result = model.predict(predict_data)
    print(result)
    print(model.predict_proba(predict_data))
    print(model.score(x,y))
"""
 n_neighbors=5           

int 型参数    knn算法中指定以最近的几个最近邻样
本具有投票权,默认参数为5

  weights='uniform'       

str参数        即每个拥有投票权的样本是按什么比重投票,
'uniform'表示等比重投票,'distance'表示按距离反比投票,
[callable]表示自己定义的一个函数,这个函数接收一个
距离数组,返回一个权值数组。默认参数为‘uniform’

  algrithm='auto'           
str参数       即内部采用什么算法实现。有以下几种选择参数:
'ball_tree':球树、'kd_tree':kd树、
'brute':暴力搜索、'auto':自动根据数据的类型和结构选择合适的算法。
默认情况下是‘auto’。暴力搜索就不用说了大家都知道。具体前两种树型
数据结构哪种好视情况而定。KD树是对依次对K维坐标轴,以中值切分构造
的树,每一个节点是一个超矩形,在维数小于20时效率最高
ball tree 是为了克服KD树高维失效而发明的,其构造过程是以质心
C和半径r分割样本空间,每一个节点是一个超球体。一般低维数据用
kd_tree速度快,用ball_tree相对较慢。超过20维之后的高维数据
用kd_tree效果反而不佳,而ball_tree效果要好,具体构造过程及
优劣势的理论大家有兴趣可以去具体学习。

  leaf_size=30               

int参数      基于以上介绍的算法,此参数给出了kd_tree或者
ball_tree叶节点规模,叶节点的不同规模会影响数的构造和搜索速度,
同样会影响储树的内存的大小。具体最优规模是多少视情况而定。

  matric='minkowski'     

str或者距离度量对象   即怎样度量距离。默认是闵氏距离,
闵氏距离不是一种具体的距离度量方法,它可以说包括了其他距离度量方式,
是其他距离度量的推广,具体各种距离度量只是参数p的取值不同或者是否
去极限的不同情况,
具体大家可以参考这里https://wenku.baidu.com/view/d3a9acede009581b6bd9ebf3.html
 
  p=2                         

int参数       就是以上闵氏距离各种不同的距离参数,默认为2,
即欧氏距离。p=1代表曼哈顿距离等等

  metric_params=None                

距离度量函数的额外关键字参数,一般不用管,默认为None

  n_jobs=1                

int参数       指并行计算的线程数量,默认为1表示一个线程,
为-1的话表示为CPU的内核数,也可以指定为其他数量的线程,
这里不是很追求速度的话不用管,需要用到的话去看看多线程。



fit()                     

训练函数,它是最主要的函数。接收参数只有1个,就是训练数据集,
每一行是一个样本,每一列是一个属性。它返回对象本身,即只是修
改对象内部属性,因此直接调用就可以了,后面用该对象的预测函数
取预测自然及用到了这个训练的结果。其实该函数并不是
KNeighborsClassifier这个类的方法,
而是它的父类SupervisedIntegerMixin继承下来的方法。



predict()               

预测函数   接收输入的数组类型测试样本,一般是二维数组,
每一行是一个样本,每一列是一个属性返回数组类型的预测结果,
如果每个样本只有一个输出,则输出为一个一维数组。如果每个样
本的输出是多维的,则输出二维数组,每一行是一个样本,每一列是一维输出。



predict_prob()      

基于概率的软判决,也是预测函数,只是并不是给出某一个样本
的输出是哪一个值,而是给出该输出是各种可能值的概率各是多少
接收参数和上面一样返回参数和上面类似,只是上面该是值的地方
全部替换成概率,比如说输出结果又两种选择0或者1,上面的预测
函数给出的是长为n的一维数组,代表各样本一次的输出是0还是1.
而如果用概率预测函数的话,返回的是n*2的二维数组,每一行代
表一个样本,每一行有两个数,分别是该样本输出为0的概率为多少,
输出1的概率为多少。而各种可能的顺序是按字典顺序排列,
比如先0后1,或者其他情况等等都是按字典顺序排列。


score()                

计算准确率的函数,接受参数有3个。 X:接收输入的数组类型测试样本,
一般是二维数组,每一行是一个样本,每一列是一个属性。y:X这些预测
样本的真实标签,一维数组或者二维数组。sample_weight=None,
是一个和X第一位一样长的各样本对准确率影响的权重,一般默认为None.
输出为一个float型数,表示准确率。内部计算是按照predict()函数计
算的结果记性计算的。其实该函数并不是KNeighborsClassifier这个类
的方法,而是它的父类KNeighborsMixin继承下来的方法。

kneighbors()          

计算某些测试样本的最近的几个近邻训练样本。接收3个参数。X=None:
需要寻找最近邻的目标样本。n_neighbors=None,表示需要寻找目标样
本最近的几个最近邻样本,默认为None,需要调用时给出。
return_distance=True:是否需要同时返回具体的距离值。
返回最近邻的样本在训练样本中的序号。其实该函数并不是
KNeighborsClassifier这个类的方法,而是它的父类KNeighborsMixin

"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值