第3节:K邻近法原理即numpy实现版

2021-12-04 13:52:03 浏览数 (1)

文章目录
  • KNN基础
  • 原理
  • numpy复现

KNN基础

  • KNN(k-nearest neighbor,k-NN)是一种基本分类和回归方法.
  • 原理:给定一个数据集,对新输入的实例,在训练集中找到与该实例最邻近的k个实例,这K个实例多数属于某一类就把输入的实例分为这个类.
  • K近邻法

训练数据集

T = {(x_1,y_1),(x_2,y_2)...(x_N,y_N)}

根据给定的距离度量,在训练集T中找出与x最邻近的k个点,涵盖这k个点的x 的邻域记作

N_k (x)

; 在

N_k(x)

中根据分类决策规则(如多数表决)决定x的类别y: k近邻法的特殊情况是k=1的情形,称为最近邻算法。对于输入的实例点(特征向 量)x,最近邻法将训练数据集中与x最邻近点的类作为x的类。

原理

  • 三个要素-距离度量,k值选择,分类决策规则
  • 两个点的距离是相似程度的反应.使用欧式距离或者Lp距离或Minnkowski距离.
  • k值选择关键,因为K值的减小意味着整体的模型变得复杂,容易发生过拟合.
  • 分类规则:多数表决规则.
  • kd树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。 kd树是二叉树,表示对k维空间的一个划分(partition)。构造kd树相当于不断地用垂直于 坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个结点对应于一 个k维超矩形区域。

numpy复现

代码语言:javascript复制
# -*- coding:utf-8 -*-
# /usr/bin/python
'''
-------------------------------------------------------------------------
   @File Name      :  knn.py
   @Description    :  
   @Run Script     :  python  knn.py 
   @Envs           :  pip install 
   @Change Activity:
        1.  2021/12/3  下午1:48  : build
-------------------------------------------------------------------------
   @CodeStyle      :  standard, simple, readable, maintainable, and portable!
   @Author         :  Yan Errol 13075851954
   @Email          :  260187357@qq.com
   @Copyright      :  "Copyright 2021, Yan Errol"
-------------------------------------------------------------------------
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from collections import Counter
# 加载读取数据

data = pd.read_csv("dataset.csv")
print(data.label.value_counts())
print("datan",data)

# 数据可视化 验证线性可分性
plt.scatter(data[:50]['sepal length'], data[:50]['sepal width'], label='0')
plt.scatter(data[50:100]['sepal length'], data[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()
plt.show()
plt.savefig("show.png")

# 数据集拆分
data = np.array(data.iloc[:100,[0,1,-1]])
X,Y = data[:,:-1],data[:, -1]
XTrain,xtest,YTrain,ytest = train_test_split(X,Y,test_size=0.2)
class KNN():
    def __init__(self,XTrain,YTrain,nNeighbors=5,p=2):
        self.XTrain = XTrain
        self.YTrain = YTrain
        self.nNeighbors = nNeighbors
        self.p = p

    def predict(self,X):
        '''预测'''
        # 全局遍历
        knnlist = []
        for i in range(len(self.XTrain)):
            dist = np.linalg.norm(X - self.XTrain[i], ord=self.p)
            knnlist.append([round(dist,2), self.YTrain[i]])
        knnlist = sorted(knnlist,key=lambda x:x[0])
        minKnnlist = knnlist[0:self.nNeighbors]

        # 统计
        knn = [k[-1] for k in minKnnlist]
        count_pairs = Counter(knn)
        max_count = sorted(count_pairs, key=lambda x: x)[-1]
        return max_count

    def score(self,X_test, y_test):
        right_count = 0
        n = 10
        for X, y in zip(X_test, y_test):
            label = self.predict(X)
            if label == y:
                right_count  = 1
        return right_count / len(X_test)

clf = KNN(XTrain, YTrain)
resultScore = clf.score(xtest, ytest)
print(resultScore)

0 人点赞