KNN学习报告

news2024/12/25 23:44:46

  1. 原理

KNN算法就是在其表征空间中,求K个最邻近的点。根据已知的这几个点对其进行分类。如果其特征参数只有一个,那么就是一维空间。如果其特征参数只有两个,那么就是二维空间。如果其特征参数只有三个,那么就是三维空间。如果其特征参数大于三个,那么就是N维抽象空间。在表征空间中,不同点的距离采用如下所示的欧几里得方法进行计算。

K值根据经验选择最合适的参数,太小不够稳健,太大的话容易受样本不足制约。也可以根据交叉验证的方法,确定最优的K值。一般取5~10之间的一个数。

如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 看下面这幅图:

KNN的算法过程是是这样的: 从上图中我们可以看到,图中的数据集是良好的数据,即都打好了label,一类是蓝色的正方形,一类是红色的三角形,那个绿色的圆形是我们待分类的数据。 如果K=3,那么离绿色点最近的有2个红色三角形和1个蓝色的正方形,这3个点投票,于是绿色的这个待分类点属于红色的三角形 如果K=5,那么离绿色点最近的有2个红色三角形和3个蓝色的正方形,这5个点投票,于是绿色的这个待分类点属于蓝色的正方形 我们可以看到,KNN本质是基于一种数据统计的方法!其实很多机器学习算法也是基于数据统计的。 KNN是一种memory-based learning,也叫instance-based learning,属于lazy learning。即它没有明显的前期训练过程,而是程序开始运行时,把数据集加载到内存后,不需要进行训练,就可以开始分类了。 具体是每次来一个未知的样本点,就在附近找K个最近的点进行投票。

  1. 三个距离算法

欧氏距离:是一个通常采用的距离定义,指在n维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离),在二维和n维空间中的欧氏距离就是两点之间的实际距离。

def euclideanDistance(x1, x2):
    #
欧氏距离
    tempDistance = 0
    for i in range(x1.shape[0]):
        difference = x1[i] - x2[i]
        tempDistance += difference * difference

    tempDistance = tempDistance ** 0.5
    return tempDistance

马氏距离:马氏距离(Mahalanobis Distance)是一种距离的度量,可以看作是欧氏距离的一种修正,修正了欧式距离中各个维度尺度不一致且相关的问题。其中Σ是多维随机变量的协方差矩阵,μ为样本均值,如果协方差矩阵是单位向量,也就是各维度独立同分布,马氏距离就变成了欧氏距离。

def mashi_distance(x,y):
    X = numpy.vstack([x, y])
    XT = X.T
    #
方法一:根据公式求解
    S = numpy.cov(X)  #
两个维度之间协方差矩阵
    SI = numpy.linalg.inv(S)  #
协方差矩阵的逆矩阵
    #
马氏距离计算两个样本之间的距离
    n = XT.shape[0]
    d1 = 0
    for i in range(0, n):
        for j in range(i + 1, n):
            delta = XT[i] - XT[j]
            d = numpy.sqrt(numpy.dot(numpy.dot(delta, SI), delta.T))
            d1 = d1 + d
    return d1

曼哈顿距离:种使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总和。

def ManhattanDistance(x, y):
    x = numpy.array(x)
    y = numpy.array(y)
    return numpy.sum(numpy.abs(x-y))

  1. 三个数据集

Iris数据集Iris Data Set(鸢尾属植物数据集)是我现在接触到的历史最悠久的数据集,它首次出现在著名的英国统计学家和生物学家Ronald Fisher 1936年的论文《The use of multiple measurements in taxonomic problems》中,被用来介绍线性判别式分析。在这个数据集中,包括了三类不同的鸢尾属植物:Iris SetosaIris VersicolourIris Virginica。每类收集了50个样本,因此这个数据集一共包含了150个样本。

该数据集测量了所有150个样本的4个特征,分别是:sepal length(花萼长度);sepal width(花萼宽度);petal length(花瓣长度);petal width(花瓣宽度)以上四个特征的单位都是厘米(cm)。通常使用mm表示样本量的大小,nn表示每个样本所具有的特征数。因此在该数据集中,m=150,n=4m=150,n=4

# iris数据集
tempDataset = sklearn.datasets.load_iris()

葡萄酒分类数据集Wine葡萄酒数据集是来自UCI上面的公开数据集,这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果,这些葡萄酒来自三个不同的品种。该分析确定了三种葡萄酒中每种葡萄酒中含有的13种成分的数量。从UCI数据库中得到的这个wine数据记录的是在意大利某一地区同一区域上三种不同品种的葡萄酒的化学成分分析。数据里含有178个样本分别属于三个类别,这些类别已经给出。每个样本含有13个特征分量(化学成分),分析确定了13种成分的数量,然后对其余葡萄酒进行分析发现该葡萄酒的分类。

wine数据集中,这些数据包括了三种酒中13种不同成分的数量。文件中,每行代表一种酒的样本,共有178个样本;一共有14列,其中,第一个属性是类标识符,分别是1/2/3来表示,代表葡萄酒的三个分类。后面的13列为每个样本的对应属性的样本值。剩余的13个属性是,酒精、苹果酸、灰、灰分的碱度、镁、总酚、黄酮类化合物、非黄烷类酚类、原花色素、颜色强度、色调、稀释葡萄酒的OD280/OD315、脯氨酸。其中第1类有59个样本,第2类有71个样本,第3类有48个样本。

# 葡萄酒分类数据集
tempDataset = sklearn.datasets.load_wine()

手写分类数据集:在这个数据集中,包含17978*8灰度的图像。每个数据点都是一个数字,共有10种类别(数字0~9)。

# 手写数字分类数据集
tempDataset = sklearn.datasets.load_digits()

  1. 实验对比

  1. 结论

本次实验内容包括三种数据集分别对三种距离测量算法进行knn预测分类,同一种数据集在不同距离测量算法下计算精度也不尽相同。其中,手写数字数据集在使用马氏距离过程中计算量过大,不适宜使用马氏距离计算。

import sklearn.datasets, sklearn.neighbors, sklearn.model_selection
import numpy
from sklearn import metrics


def sklearnKnnTest():
    #Step 1. Load the dataset
    # iris数据集
    #tempDataset = sklearn.datasets.load_iris()
    # 葡萄酒分类数据集
    #tempDataset = sklearn.datasets.load_wine()
    # 手写数字分类数据集
    tempDataset = sklearn.datasets.load_digits()

    x = tempDataset.data
    y = tempDataset.target

    #print("x = ", x)
    #print("y = ", y)

    #Step 2. Split the data
    X1, X2, Y1, Y2 = sklearn.model_selection.train_test_split(x, y, test_size = 0.2)
    print("X1 = ", X1)
    print("Y1 = ", Y1)
    print("X2 = ", X2)
    print("Y2 = ", Y2)

    #Step 3. Indicate the training set.
    tempClassifier = sklearn.neighbors.KNeighborsClassifier(n_neighbors = 5)
    tempClassifier.fit(X1, Y1)

    #Step 4. Test.
    tempScore = tempClassifier.score(X2, Y2)
    print("The score is: ", tempScore)

def euclideanDistance(x1, x2):
    # 欧氏距离
    tempDistance = 0
    for i in range(x1.shape[0]):
        difference = x1[i] - x2[i]
        tempDistance += difference * difference

    tempDistance = tempDistance ** 0.5
    return tempDistance
# 马氏距离
def mashi_distance(x,y):
    X = numpy.vstack([x, y])
    XT = X.T
    # 方法一:根据公式求解
    S = numpy.cov(X)  # 两个维度之间协方差矩阵
    SI = numpy.linalg.inv(S)  # 协方差矩阵的逆矩阵
    # 马氏距离计算两个样本之间的距离
    n = XT.shape[0]
    d1 = 0
    for i in range(0, n):
        for j in range(i + 1, n):
            delta = XT[i] - XT[j]
            d = numpy.sqrt(numpy.dot(numpy.dot(delta, SI), delta.T))
            d1 = d1 + d
    return d1
# 曼哈顿距离
def ManhattanDistance(x, y):
    x = numpy.array(x)
    y = numpy.array(y)
    return numpy.sum(numpy.abs(x-y))

def mfKnnTest(k = 3):
    #Step 1. Load the dataset
    # iris数据集
    #tempDataset = sklearn.datasets.load_iris()
    # 葡萄酒分类数据集
    #tempDataset = sklearn.datasets.load_wine()
    # 手写数字分类数据集
    tempDataset = sklearn.datasets.load_digits()
    x = tempDataset.data
    y = tempDataset.target

    #print("x = ", x)
    #print("y = ", y)

    #Step 2. Split the data
    X1, X2, Y1, Y2 = sklearn.model_selection.train_test_split(x, y, test_size = 0.2)
    # print("X1 = ", X1)
    # print("Y1 = ", Y1)
    # print("X2 = ", X2)
    # print("Y2 = ", Y2)

    #Step 3. Classify
    tempPredicts = numpy.zeros(Y2.shape[0])
    for i in range(X2.shape[0]):
        #Step 3.1 Find k neigbhors
        #Initialize
        tempNeighbors = numpy.zeros(k + 2)
        tempDistances = numpy.zeros(k + 2)
        for j in range(k + 2):
            tempDistances[j] = 1000
        tempDistances[0] = -1

        for j in range(X1.shape[0]):
            # 欧氏距离
            #tempDistance = euclideanDistance(X2[i], X1[j])
            # 马氏距离
            tempDistance = mashi_distance(X2[i], X1[j])
            # 曼哈顿距离
            #tempDistance = ManhattanDistance(X2[i], X1[j])
            tempIndex = k
            while True:
                if tempDistance < tempDistances[tempIndex]:
                    #Move forward
                    #print("tempDistance = {} and tempDistances[{}] = {}".format(tempDistance, tempIndex, tempDistances[tempIndex]))
                    tempNeighbors[tempIndex + 1] = tempNeighbors[tempIndex]
                    tempDistances[tempIndex + 1] = tempDistances[tempIndex]
                    tempIndex -= 1
                else:
                    #Insert here
                    tempNeighbors[tempIndex + 1] = j
                    tempDistances[tempIndex + 1] = tempDistance
                    #print("Insert to {}.".format(tempIndex))
                    break
        #print("Classifying ", X2[i])

        #print("tempNeighbors = ", tempNeighbors)

        #Step 3.2 Vote
        #Step 2.2 Vote for the class
        tempLabels = []
        for j in range(k):
            tempIndex = int(tempNeighbors[j + 1])
            tempLabels.append(int(Y1[tempIndex]))

        tempCounts = []
        for label in tempLabels:
            #print("count = ", tempLabels.count(label))
            tempCounts.append(int(tempLabels.count(label)))
        tempPredicts[i] = tempLabels[numpy.argmax(tempCounts)]

    print("The predictions are: ", tempPredicts)
    print("The true labels are: ", Y2)
    print('The accuracy of the KNN is: {:.3f}'.format(metrics.accuracy_score(tempPredicts, Y2)))
    return metrics.accuracy_score(tempPredicts, Y2)


def main():
    #sklearnKnnTest()
    #print("Life is short, so I study python.")
    list = []
    for i in range(6):
        list.append(mfKnnTest())
    print(list)

main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/389927.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件设计师教程(七)计算机系统知识-操作系统知识

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;三&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;…

Redis十大类型——Hash常见操作

Redis十大类型——Hash常见操作命令操作简列存放及获取获取健值对长度元素查找列出健值对对数字进行操作赋值hsetnx很明显咯它也是以健值对方式存在的&#xff0c;只不过value也就是值&#xff0c;在这里也变成了一组简直对。 &#x1f34a;个&#x1f330;&#xff1a; 想必多…

【Linux】P3 用户与用户组

用户与用户组root 超级管理员设置超级管理员密码切换到超级管理员sudo 临时使用超级权限用户与用户组用户组管理用户管理getentroot 超级管理员 设置超级管理员密码 登陆后不会自动开启 root 访问权限&#xff0c;需要首先执行如下步骤设定 root 超级管理员密码 1、解除 roo…

【C++】string的使用及其模拟实现

文章目录1. STL的介绍1.1 STL的六大组件1.2 STL的版本1.3 STL的缺陷2. string的使用2.1 为什么要学习string类&#xff1f;2.2 常见构造2.3 Iterator迭代器2.4 Capacity2.5 Modifiers2.6 String operations3. string的模拟实现3.1 构造函数3.2 拷贝构造函数3.3 赋值运算符重载和…

DevOps实战50讲-(2)Jenkins配置

1. Docker镜像方式安装拉取Jenkins镜像docker pull jenkins/jenkins编写docker-compose.ymlversion: "3.1" services:jenkins:image: jenkins/jenkinscontainer_name: jenkinsports:- 8080:8080- 50000:50000volumes:- ./data/:/var/jenkins_home/首次启动会因为数据…

iis之web服务器搭建、部署(详细)~千锋

目录 Web服务器 部署web服务器 实验一 发布一个静态网站 实验二 一台服务器同时发布多个web站点 网站类型 Web服务器 也叫网页服务或HTTP服务器web服务器使用的协议是HTTPHTTP协议端口号&#xff1a;TCP 80、HTTPS协议端口号&#xff1a;TCP 443Web服务器发布软件&…

【备战面试】每日10道面试题打卡-Day4

本篇总结的是Java集合知识相关的面试题&#xff0c;后续也会更新其他相关内容 文章目录1、HashMap在JDK1.7和JDK1.8中有哪些不同&#xff1f;2、HashMap 的长度为什么是2的幂次方&#xff1f;3、HashMap的扩容操作是怎么实现的&#xff1f;4、HashMap是怎么解决哈希冲突的&…

Android 基础知识4-3.5 RadioButton(单选按钮)Checkbox(复选框)详解

一、RadioButton&#xff08;单选按钮&#xff09; 1.1、简介 RadioButton表示单选按钮&#xff0c;是button的子类&#xff0c;每一个按钮都有选择和未选中两种状态&#xff0c;经常与RadioGroup一起使用&#xff0c;否则不能实现其单选功能。RadioGroup继承自LinearLayout&a…

滚动升级回滚

滚动升级回滚 ReplicationController 资源文件 apiVersion: v1 kind: ReplicationController metadata:name: kubia-v1labels:app: kubia spec:replicas: 3template:metadata:name: kubialabels:app: kubiaspec:containers:- image: luksa/kubia:v1name: nodejes --- apiVer…

【Linux学习】基础IO——软硬链接 | 制作动静态库

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 基础IO&#x1f353;软硬链接&#x1f332;软链接&#x1f332;硬链接&#x1f353;动静态库&…

BPMN2.0规范及流程引擎选型方案

BPMN2.0规范及流程引擎选型方案一、基本概念二、BPMN意义三、主要元素3.1 活动任务子流程调用活动事件子流程事务3.2 网关排他网关包容网关并行网关事件网关3.3 事件开始事件结束事件中间事件3.4 辅助泳道图注释与组数据存储四、图类型4.1 编排图4.2 会话图五、技术选型5.1 前端…

大数据ETL开发之图解Kettle工具

详细笔记参考&#xff1a;https://blog.csdn.net/yuan2019035055/article/details/120409547以下只是简单记录一下我学习过程中的心得3.1.5 JSON输入JSONPath 类似于 XPath 在 xml 文档中的定位&#xff0c;JsonPath 表达式通常是用来路径检索或设置Json的。其表达式可以接受“…

阶段二11_面向对象高级_学生管理系统案例2

主要内容&#xff1a; 添加学生 static关键字一.添加学生时判断id是否存在 0.思路图片&#xff1a; 04/图片/2_添加学生判断id存在的问题分析.png 1.思路实现详细步骤&#xff1a; StudentController【客服接待】 /** 接收到学生id后&#xff0c;判断该id在数组中是否存在 这…

SRS源码分析-SDP内容解析

前言 在学习SRS的RTC模块之前&#xff0c;首先来分析下SRS在将rtmp推流转成rtc流&#xff0c;通过浏览器拉取webrtc流场景下产生的SDP内容 SDP格式介绍 SDP数据是文本格式&#xff0c;由多个 <key><value> 表达式构成&#xff0c;<key>的值只能是一个字符…

第二讲:ambari编译复盘,如何实现一次性成功编译ambari

上节课我们已经讲解了如何成功编译ambari源码,安装ambari-server rpm包以及成功部署ambari。本节课我们来复盘一下上节课的编译过程,以及思考如何实现一次性成功编译ambari。 要想一次性成功编译ambari,那么就需要将预置工作做好,比如: maven镜像源配置,node_moudle模块…

Go项目(商品微服务-2)

文章目录简介handler商品分类轮播图品牌和品牌与分类oss前端直传库存服务数据不一致redis 分布式锁小结简介 开发商品微服务 API 层类似的&#xff0c;将 user-web 目拷贝一份&#xff0c;全局替换掉 user-web修改 config 去掉不用的配置更新本地和远程 nacos 配置文件 把 pro…

OpenGL环境配置

方法一&#xff1a;1.下载GLFW点击GLFW跳转2.下载后解压3.下载glad&#xff0c;解压后4.用vs2019新建Cmake项目5.在新建的Cmake项目下建立depend文件夹在depend里放置我们下载解压的glad和glfw-3.3.8.bin.WIN646.项目中可以看到我们加进来的文件7.编写我们项目的CMakeLists.txt…

Condition 源码解读

一、Condition 在并发情况下进行线程间的协调&#xff0c;如果是使用的 synchronized 锁&#xff0c;我们可以使用 wait/notify 进行唤醒&#xff0c;如果是使用的 Lock 锁的方式&#xff0c;则可以使用 Condition 进行针对性的阻塞和唤醒&#xff0c;相较于 wait/notify 使用…

路径规划-人工势场法

一.基本思想 目标点对机器人产生吸引力&#xff0c;障碍物对机器人产生排斥力&#xff1b; 所有力的合成构成机器人的控制律 二. 主要步骤 1.构建人工势场 目标点&#xff1a;吸引势场 障碍物&#xff1a;排斥势场 2.根据人工势场计算力 对势场求偏导 3.计算合力 计…

bpftrace 笔记

bpftrace -e BEFIN {printf("hello world!\n");}获取调用 vfs_read 函数的进程id, 每2s打印一次 bpftrace -e kprobe:vfs_read {ID pid;} interval:s:2 {printf{"ID:%d\n", ID);}用户态调试 bpftrace -e uprobe:/*/a.out:and {printf("ID:%d\n&qu…