基本流程:

1、计算测试实例到所有训练集实例的距离;

2、对所有的距离进行排序,找到k个最近的邻居;

3、对k个近邻对应的结果进行合并,再排序,返回出现次数最多的那个结果。

交叉验证:

对每一个k,使用验证集计算,记录k对应的错误次数,取错误数最小的k

# -*- coding: utf-8 -*-
import os
import pandas as pd
import matplotlib.pyplot as plt
import math
import operator #按照8:2的比例分割数据
#testSetIndex : 第几组为测试样本,取值范围0 - 4
def splitData(trainSet, testSet, testSetIndex):
#data = pd.read_csv('iris.txt', skiprows=0, skipfooter=0, sep=r'\s+', encoding="utf-8", engine='python', header=None)
data = pd.read_csv('iris.txt', encoding="utf-8", engine='python', header=None) for i in range(150):
if testSetIndex == (i % 50) / 10:
testSet.append(data.iloc[i])
else:
trainSet.append(data.iloc[i])
return #计算欧氏距离
#instance1 : 实例1
#instance2 : 实例2
#dimension :维度
def computeDistance(instance1, instance2, dimension):
distance = 0
for i in xrange(dimension):
#print(instance1[i], instance2[i])
distance += pow((instance1[i] - instance2[i]), 2)
return math.sqrt(distance) #trainSet : 训练样本集
#instance : 实例数据
#k : 1 - 120
def kNN(trainSet, instance, k):
distances = []
dimension = len(instance) - 1
#计算测试实例到训练集实例的距离
for i in xrange(len(trainSet)):
dist = computeDistance(instance, trainSet[i], dimension)
distances.append((trainSet[i], dist))
#对所有的距离进行排序
distances.sort(key=operator.itemgetter(1))
neighbors = []
#返回k个最近邻
for i in range(k):
neighbors.append(distances[i][0]) #对k个近邻进行合并,返回最多的那个
listClass = {}
for i in xrange(len(neighbors)):
response = neighbors[i][4]
if response in listClass:
listClass[response] += 1
else:
listClass[response] = 1
#排序
sortResult = sorted(listClass.iteritems(), key = operator.itemgetter(1), reverse=True)
return sortResult[0][0] def main():
trainSet = [] #训练数据集
testSet = [] #测试数据集
#1. 数据分割8:2
splitData(trainSet, testSet, 4) #2. 使用交叉验证方法确定最优 k 值,并给出在该情形下分类器的错误分类率
errCountSet = [0] * 120
#9总数据切割方式,对每一个k,记录k对应的总错误次数
for j in xrange(0, 5):
trainSet = []
testSet = []
splitData(trainSet, testSet, j)
for k in xrange(0, 120):
#对每一个k,使用验证集计算,记录k对应的错误次数
for i in xrange(len(testSet)):
trainResult = kNN(trainSet, testSet[i], k + 1)
if trainResult != testSet[i][4]:
errCountSet[k] = errCountSet[k] + 1 #取错误数最小的k 有多个
min = 1
for i in xrange(0, 120):
errCountSet[i] = errCountSet[i] / (30 * 5.0)
if min > errCountSet[i]:
min = errCountSet[i]
#k = i + 1 #打印错误率最小的k值
for i in xrange(0, 120):
if min == errCountSet[i]:
print i + 1, min fig = plt.figure(figsize=(20, 15))
ax1 = fig.add_subplot(111)
#ax2 = fig.add_subplot(122)
ax1.plot(range(1, 121), errCountSet)
ax1.set_xlabel('k')
ax1.set_ylabel('Error Rate')
plt.show() return if __name__ == "__main__":
main()

分别使用参数k=1~120进行实验,并进行交叉验证,错误分类率曲线如下:

kNN处理iris数据集-使用交叉验证方法确定最优 k 值的更多相关文章

  1. 使用KNN对iris数据集进行分类——python

    filename='g:\data\iris.csv' lines=fr.readlines()Mat=zeros((len(lines),4))irisLabels=[]index=0for lin ...

  2. 十折交叉验证10-fold cross validation, 数据集划分 训练集 验证集 测试集

    机器学习 数据挖掘 数据集划分 训练集 验证集 测试集 Q:如何将数据集划分为测试数据集和训练数据集? A:three ways: 1.像sklearn一样,提供一个将数据集切分成训练集和测试集的函数 ...

  3. 用交叉验证改善模型的预测表现-着重k重交叉验证

    机器学习技术在应用之前使用“训练+检验”的模式(通常被称作”交叉验证“). 预测模型为何无法保持稳定? 让我们通过以下几幅图来理解这个问题: 此处我们试图找到尺寸(size)和价格(price)的关系 ...

  4. 机器学习——交叉验证,GridSearchCV,岭回归

    0.交叉验证 交叉验证的基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set) ...

  5. 机器学习基础:(Python)训练集测试集分割与交叉验证

    在上一篇关于Python中的线性回归的文章之后,我想再写一篇关于训练测试分割和交叉验证的文章.在数据科学和数据分析领域中,这两个概念经常被用作防止或最小化过度拟合的工具.我会解释当使用统计模型时,通常 ...

  6. S折交叉验证(S-fold cross validation)

    S折交叉验证(S-fold cross validation) 觉得有用的话,欢迎一起讨论相互学习~Follow Me 仅为个人观点,欢迎讨论 参考文献 https://blog.csdn.net/a ...

  7. 总结:Bias(偏差),Error(误差),Variance(方差)及CV(交叉验证)

    犀利的开头 在机器学习中,我们用训练数据集去训练(学习)一个model(模型),通常的做法是定义一个Loss function(误差函数),通过将这个Loss(或者叫error)的最小化过程,来提高模 ...

  8. 验证和交叉验证(Validation & Cross Validation)

    之前在<训练集,验证集,测试集(以及为什么要使用验证集?)(Training Set, Validation Set, Test Set)>一文中已经提过对模型进行验证(评估)的几种方式. ...

  9. MATLAB曲面插值及交叉验证

    在离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点.插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值.曲面插值是对三维数据进行离 ...

随机推荐

  1. Caffe 使用记录(五):math_functions 分析

    本文转载自 Caffe源码(一):math_functions 分析 math_function 定义了caffe 中用到的一些矩阵操作和数值计算的一些函数,这里以float类型为例做简单的分析 1. ...

  2. Linux入门搭建可视化桌面环境小合集virtual box centOS7.10

    常用命令: 关联主机与虚拟机(方便文件共享): # sudo mount -t vboxsf share(主机文件夹名) /usr/share(虚拟机内自创) Linux shell进入root模式: ...

  3. [源码]一键获取windows系统登陆密码vc6版源码

    [源码]一键获取windows系统登陆密码vc6版源码支持:XP/2000/2003/WIN7/2008等 此版本编译出来的程序体积较小几十KB... 而vs版则1点几M,体积整整大了2-30倍对某些 ...

  4. MySQL 中的数字类型

    MySQL 中数据类型常用的就三大类: 数字类型/numeric types 日期和时间/date and time types 字符类型/string (character and byte) ty ...

  5. ABP实践(3)-ASP.NET Core 2.x版本(从创建实体到输出api)简单实现商品列表及增删改

    项目基于前两篇文章. 本章创建一个简单版的商品管理后台api,用到EF Core用code fist迁移数据创建数据库. 创建Goods实体 在领域层xxx.Core项目[新建文件夹Goods;文件夹 ...

  6. Java中IO流中的装饰设计模式(BufferReader的原理)

    本文粗略的介绍下JavaIO的整体框架,重在解释BufferReader/BufferWriter的演变过程和原理(对应的设计模式) 一.JavaIO的简介 流按操作数据分为两种:字节流与字符流. 流 ...

  7. 搜索核心原理之网页和查询的相关性——TF-IDF

    1.相关性的演进:      i.单文本词频TF(Term Frequency)           用关键词的出现的次数除以文章的总次数,做归一化处理得到TF,来屏蔽文章长度对用关键词出现次数来衡量 ...

  8. 线程的中断(Lock与synchronized)

    Thread包含interrupt()方法,因此你可以终止被阻塞的任务,这个方法将设置线程的中断状态.如果一个线程已经被阻塞,或者试图执行一个阻塞操作.那么设置这个线程的中断状态将 抛出Interru ...

  9. Eclipse 工程目录下的.classpath、.project文件和.settings文件作用

    1..classpath 定义了你这个项目在编译时所使用的$CLASSPATH (注: 每次在更新jar的版本或者增加jar之后,请在SVN提交.classpath文件,否则工程的build path ...

  10. Android 内存溢出解决方案(OOM) 整理总结<转>

    在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总 ...