需要数据集,请私信作者。
本文目标:knn实现
创作不易,转发请带上本文链接。
一、KNN介绍
K-最近邻法(KNN)最初由Cover和Hart于1968年提出,是一个在理论上比较成熟的分类算法。
KNN是一类可用于分类或回归的技术。作为一个非参数学习算法,K-最近邻并不局限于固定数目的参数。我们通常认为K-最近邻算法没有任何参数,而且使用训练数据的简单函数。事实上,它甚至也没有一个真正的训练阶段或学习过程。反之,在测试阶段我们希望在新的测试输入x上产生y,我们需要在训练数据X上找到x的K-最近邻。然后我们返回训练集上对应的y值的平均值。这几乎适用于任何类型可以确定y值平均值的监督学习。
算法核心
训练样本是多维特征空间向量,其中每个训练样本带有一个类别标签。算法的训练阶段只包含存储的特征向量和训练样本的标签。在分类阶段,k是一个用户定义的常数。一个没有类别标签的向量将被归类为最接近该点的k个样本点中最频繁使用的一类。一般情况下,将欧式距离作为距离度量,但是这只适用于连续变量。在文本分类这种离散变量情况下,另一个度量----重叠度量(或汉明距离)可以用来作为度量。
参数选择
如何选择一个最佳的K值取决于数据。一般情况下,在分类时较大的K值能够减少噪声的影响,但会使类别之间的界限变得模糊。一个较好的K值能通过各种启发式技术来获取。噪声和非相关性特征的存在,或特征尺度与它们的重要性不一致会使K近邻算法的准确性严重降低。在两类分类问题中,选取k为奇数有助于避免两个分类平票的情形。在此问题下,选取最佳经验k值的方法是自助法。
核心思想
如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。KNN方法在类别决策上仅仅依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
二、代码实现
理论讲了这么多,下面来编程实现一下吧,本文以k=1,k=3为栗。
导入必要库
import os
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
获取图像特征函数
def get_feature(img_path):
image = np.array(Image.open(img_path))
r, g, b = image[:, :, 0], image[:, :, 1], image[:, :, 2]
rgb_max = np.argmax(image, axis=2)
r = np.ones((image.shape[0], image.shape[1])) * 0
g = np.ones((image.shape[0], image.shape[1])) * 1
b = np.ones((image.shape[0], image.shape[1])) * 2
# print(np.mean(rgb_max == r))
# print(np.mean(rgb_max == g))
# print(np.mean(rgb_max == b))
x1 = np.mean(rgb_max == g)
x2 = np.mean(rgb_max == b)
return x1, x2
图像读取函数
def read_image(image_fold, color):
path_list = os.listdir(image_fold)
Point = []
for path in path_list:
if path.split('.')[-1] != 'jpg':
continue
path = image_fold + path
p = get_feature(path)
Point.append(p)
Point = np.array