手动实现KNN算法
手动实现KNN算法
- 计算距离
- 取k个邻近排序
距离(欧氏)
预习
import numpy as np
# 数组运算是面向元素级别的
arr1 = np.array([1,2,3])
arr2 = np.array([4,5,6])
arr1 - arr2
array([-3, -3, -3])
(arr1-arr2)**2
array([9, 9, 9], dtype=int32)
sum(arr1-arr2)
-9
# 计算a(1,2,3) 和点b(4,5,6)的距离
# 1. 计算'差'向量
(arr1-arr2) ** 2
array([9, 9, 9], dtype=int32)
# 2. 平方求和再开根号, 即可np.sqrt(9+9+9)
np.sqrt(sum((arr1-arr2)**2))
5.196152422706632
实现欧式距离
def euc_distance(arr1, arr2):
"""
计算两个样本(向量或数组)的欧氏距离
arr1: 样本点1, array类型
arr2: 样本点2, array类型
"""
return np.sqrt(sum((arr1 - arr2)**2))
# test
dis = euc_distance(np.array([1,2,3]), np.array([4,5,6]))
print('(1,2,3)与(4,5,6)的欧氏距离为:', round(dis,3))
(1,2,3)与(4,5,6)的欧氏距离为: 5.196
KNN
- 计算输入样本点,到每个样本的距离 -> 距离值向量
- 将距离值向量降序取前k个值
- 投票
预习
# 计算点(1,2) 到 (3,4), (5,6), (7,8), (9,10) 的距离
X = [np.array([3,4]), np.array([5,6]), np.array([7,8]), np.array([9,10])]
# 逐个计算该点到其他点的距离
dis_arr = [euc_distance(np.array([1,2]), x) for x in X]
dis_arr
[2.8284271247461903, 5.656854249492381, 8.48528137423857, 11.313708498984761]
# 按值升序排列, 取出前k个值的下标
np.argsort(np.array([1,4,2,3]))[:2]
array([0, 2], dtype=int64)
# 按值降序排列, 取出前k个值的下标
arr = np.array([1,4,2,3])
np.argsort(-arr)[:2]
array([1, 3], dtype=int64)
Counter类(计数器)
- Counter (计数器): 用于追踪值出现的次数
- Counter 类继承dict类, 能顺颂dict类的方法
# 1. 创建一个Counter类
from collections import Counter
obj = Counter('aabbccdde')
print(obj)
Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 1})
# 2. elements()
# 按元素降序输出
for elem in sorted(obj.elements(), reverse=True):
print(elem, end=' ')
e d d c c b b a a
# 3. most_common(n): 列出频次最高的n个元素, 不指定则列所有
print(obj.most_common(2))
[('a', 2), ('b', 2)]
# test
obj2 = Counter('abcccccddddddeeefff')
obj2.most_common(2)
[('d', 6), ('c', 5)]
# 4. items() 继承dict的方法
for k, v in obj.items():
print(k,v)
a 2
b 2
c 2
d 2
e 1
# 5. update() 增加元素
obj.update('cj')
print(obj)
Counter({'c': 3, 'a': 2, 'b': 2, 'd': 2, 'e': 1, 'j': 1})
# 6. subtract() 减去新传入的元素, 变负数了都
obj.subtract('j')
print(obj)
Counter({'c': 3, 'a': 2, 'b': 2, 'd': 2, 'e': 1, 'j': -3})
实现
def knn_classify(X, y, testInstance, k):
"""
给定一个测试数据(向量)testInstance, 通过knn算法来预测其标签
X: 训练数据特征
y: 训练数据标签
testInstance: 测试数据,一个点(向量), array类型
k: 选择多少个neighbors
"""
# todo: 返回testInstance的预测标签=> {0,1,2}
# 1. 计算输入的点instance 到每个训练点的距离
distances = [euc_distance(testInstance, x) for x in X]
# 2. 按距离值升序,选取前k个值的下标, 注意是下标哦
neighbors = np.argsort(distances)[:k]
# 3. 取到对应的 训练数据标签, 计数投票
count = Counter(y[neighbors]) # key:value
# {a:2, b:3, c:1} -> 只取出3这个值
return count.most_common()[0][0]
案例-iris的KNN实现
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from collections import Counter
def euc_distance(arr1, arr2):
"""计算两个向量的欧式距离"""
return np.sqrt(sum((arr1-arr2)**2))
def knn_classify(X, y, testVector, k):
"""给定一个测试样本(向量), 通过knn计算其在训练y中的标签值"""
distance_list = [euc_distance(testVector, x) for x in X]
# 按距离值升序,选取前k个值的下标
neighbors = np.argsort(distance_list)[:k]
count = Counter(y[neighbors]) # vote
return count.most_common()[0][0]
if __name__ == '__main__':
# 1. 导入iris数据 {'data':[[]], 'target':[], 'target...':xxx}
iris = datasets.load_iris()
X = iris.data
y = iris.target
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y)
# 3. 特征工程: 特征选取, 标准化, OneHot编码...
# 4. 训练模型: 遍历每个点(行向量)
predictions = [knn_classify(X_train, y_train, row, 3) for row in X_test]
# 5. 计算准确率
correct_num = np.count_nonzero((predictions == y_test) == True)
print('y_test', y_test, end='')
print('y_pre',predictions, end='')
print("\n准确率为:", round(correct_num / len(y_test), 3))
y_test [0 2 2 2 2 0 1 0 1 2 2 2 0 0 1 1 1 2 1 1 1 1 0 0 2 2 2 1 0 0 1 2 1 1 2 2 0
1]y_pre [0, 2, 2, 2, 2, 0, 1, 0, 1, 2, 2, 2, 0, 0, 1, 2, 1, 2, 1, 1, 1, 1, 0, 0, 2, 2, 2, 1, 0, 0, 1, 2, 1, 1, 2, 2, 0, 1]
准确率为: 0.974
手动实现KNN算法的更多相关文章
- 机器学习回顾篇(6):KNN算法
1 引言 本文将从算法原理出发,展开介绍KNN算法,并结合机器学习中常用的Iris数据集通过代码实例演示KNN算法用法和实现. 2 算法原理 KNN(kNN,k-NearestNeighbor)算法, ...
- knn算法详解
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代 ...
- KNN算法实现手写体区分
KNN算法在python里面可以使用pip install指令安装,我在实现之前查看过安装的KNN算法,十分全面,包括了对于手写体数据集的处理.我这里只是实现了基础的识别方法,能力有限,没有数据处理方 ...
- 【机器学习】机器学习入门01 - kNN算法
0. 写在前面 近日加入了一个机器学习的学习小组,每周按照学习计划学习一个机器学习的小专题.笔者恰好近来计划深入学习Python,刚刚熟悉了其基本的语法知识(主要是与C系语言的差别),决定以此作为对P ...
- KNN算法推理与实现
Overview K近邻值算法 KNN (K - Nearest Neighbors) 是一种机器学习中的分类算法:K-NN是一种非参数的惰性学习算法.非参数意味着没有对基础数据分布的假设,即模型结构 ...
- KNN算法之集美大学
在本篇文章中,我即将以在集美大学收集到的一些数据集为基础,使用KNN算法进行一系列的操作 一.KNN算法 首先,什么是KNN算法呢,这得用到老祖宗说的一句话"近朱者赤近墨者黑", ...
- 【Machine Learning】KNN算法虹膜图片识别
K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...
- KNN算法
1.算法讲解 KNN算法是一个最基本.最简单的有监督算法,基本思路就是给定一个样本,先通过距离计算,得到这个样本最近的topK个样本,然后根据这topK个样本的标签,投票决定给定样本的标签: 训练过程 ...
- kNN算法python实现和简单数字识别
kNN算法 算法优缺点: 优点:精度高.对异常值不敏感.无输入数据假定 缺点:时间复杂度和空间复杂度都很高 适用数据范围:数值型和标称型 算法的思路: KNN算法(全称K最近邻算法),算法的思想很简单 ...
随机推荐
- docker build提示error checking context:can't stat xxx
现象描述 使用docker build一个镜像的时候,提示下面的错误: ➜ docker build -t image_name -f xxx.dockerfile . error checking ...
- Mac下GoogleChromeHelper占用内存过高 的一个排查过程记录
测试需要在Mac上装了个虚拟机,结果忘记限制资源了,直接崩溃重启过一次. 后面限制了一下资源,发现内存占用率还是特别高,其中最高的居然是Chrome相关的一个东西.这让我8G内存该如何是好. 于是查了 ...
- Sql server 中将数据行转列列转行(一)
在做一些数据分析与数据展示时,经常会遇到行转列,列转行的需求,今天就来总结下: 在开始之前,先来创建一个临时表,并且写入一些测试数据: /* 第一步:创建临时表结构 */ CREATE TABLE # ...
- 工控随笔_22_关于Profibus网络接线的规则
最近在做一个项目调试,用的是西门子的PLC,416-2 DP,下面挂了几个DP子网,在进行现场网络测试的时候,有几个走的DP网络的 绝对值编码器,无论怎么弄DP网络不能联通. 一开始我以为DP网线接的 ...
- 为Endnote中的期刊名称添加缩写期刊名
为Endnote中的期刊名称添加缩写期刊名 Endnote - tools - Open term lists - Journals term lists - lists -- Journals - ...
- 【ARM-Linux开发】OpenACC并行编程实战笔记
今年运气比较好,学了cuda之后,了解到了gpu的另两种使用语言opencl和openacc, opencl(Open Computing Language ,开放计算语言)是面向异构系统的并行编程 ...
- 【快捷键】【idea】的eclipse格式化快捷键Ctrl+Shift+F与win10冲突的解决方法
1.多按一个win键解决[Ctrl+Shift+Win+F],试了一下,只要F键最后按就可以了 注意:win键就是微软的logo键 2.先按Ctrl+F,然后松开F键[注意不要松开Ctrl键],再按S ...
- ThinkPHP3(结构,路由,模板的调用,后台搭建,系统常量)
ThinkPHP的结构如下: 在ThinkPHP\Library\Think文件夹中,几个重要的文件 1.App.class.php 框架核心类文件 2.Think.class.php 每次请求都要执 ...
- 材质(Material)和几何体(Geometry)
1. 材质 一个材质结合一个几何体可以组成一个mesh对象.材质就像物体的皮肤,决定了几何体的外表.例如:皮肤定义了一个几何体看起来是否像金属.透明与否,或者显示为线框. 基本的材质如下: 1. ...
- Locust性能测试_参数关联
前言 前面[Locust性能测试2-先登录场景案例]讲了登录的案例,这种是直接传账号和密码就能登录了,有些登录的网站会复杂一点, 需要先从页面上动态获取参数,作为登录接口的请求参数,如[学信网:htt ...