KNN算法

KNN即k近邻算法 k nearest neighbors algorithm.knn算法是以离预测点距离最近的k个点中类别中最多的元素作为预测结果。特点是不需要训练。因此算法简单。

基本要素:

1.k值的选择

2.距离的度量

3.分类决策原则

k值的选择

是knn算法中的一个超参数,也就是在模型建立前需要指定的参数。k值大,会导致近似误差过大,而k过小,则会过拟合。

 

距离的度量

通常用p函数,其中这个p是KNN算法中的另一个超参数

p=1时,称为1范数,也叫曼哈顿距离,p=2,称为2范数,也就是经典的欧式距离。

 

 

分类决策原则

多数表决

KNN算法是希望找到最佳的k和p,使得预测准确率能够最高。实现这一点还需要用到网格搜索。其实也就是for循环。

算法:

# -*- coding:utf-8 -*-
# 加入assert断言,是为了判断语句是否合法,这样做更为友好,当不写断言,出现错误,不知道出现在那里

import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
import pandas as pd


class KNNClassifier:
    '''KNN算法'''
    def __init__(self,k):
        '''初始化'''
        assert k >= 1,\
        "k must be valid."
        self._x_train = None  # 定义_x_traion和_y_train 属性
        self._y_train = None
        self.k = k  # k 属性

    def fit(self, x_train, y_train):
        '''训练'''
       # assert x_train.shape[0] == y_train.shape[0], \
       #     "x's row ==y's row"
        assert self.k <= x_train.shape[0],\
        "the num of k must less than x_train's row num"
        self._x_train= x_train  # 把用户输入的训练数据导入到这两个属性
        self._y_train= y_train
        print(self)
        return self

    def predict(self,x_predict):
        '''给定x_predict预测'''
        self.x_predict = x_predict   # 定义self.x_predict 属性
        assert self._x_train is not None and self._y_train is not None,\
        "Before predict must be fitted."
        assert x_predict.shape[1] == self._x_train.shape[1],\
        "the features must equal."
        y_predict=np.array([self._predict(x=i) for i in self.x_predict])
      #  print(y_predict)
        return y_predict

# 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

    def _predict(self,x):
        '''给定单个待预测值'x',求其预测值'''
        distance = np.array([np.sum((x_train - x) ** 2) ** 0.5 for x_train in self._x_train ])
        near = np.argsort(distance)
        top_k = [self._y_train[i] for i in near[:self.k]]
        votes = Counter(top_k)
        return votes.most_common(1)[0][0]
# 预测准确度
    def accuracy(self,x_test,y_test):
        y_predict=self.predict(x_predict=x_test)
        return sum(y_predict==y_test)/len(y_test)

    def __repr__(self):
        return "KNN(k=%d)" % self.k

对于超参数k,可以选择网格搜索和交叉验证的方式得到。

可以参考sklearn中的GrideSearch和Cross_Validation。最好是自己设计。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值