机器学习(1)-KNN算法理解

来源:互联网 发布:dd linux命令复制磁盘 编辑:程序博客网 时间:2024/06/05 13:27

开始弄机器学习了,一点一点学习机器学习中相关的概念和算法。

  1. k-NN用来干什么的
    简单来说,我理解的就是分类,就是根据已知训练集样本的种类,来对测试集样本做一个分类。
    比如,我有1000张训练样本图片,总共有3个类,然后测试集有500张图片,就可以利用KNN算法根据训练样本的1000个数据来对500张未知分类的样本做一个分类。现在应该了解kNN的用途了吧。

2.K-NN算法原理
首先要知道,NN(nearst neighbor),就是最近邻的意思,最前面的‘K’表示K个最近领的坐标点。
然后理解下面一句话:要确定测试样本属于哪一类,就要寻找“所有”训练样本中与该测试样本点“距离”最近的前”k“个样本,找出的这K个样本是已经分类好的训练集中的,所以可以统计出有几个样本点属于那几个类(这可能有点绕,下面用具体例子来更加清晰理解一下)
比如前面我的1000张图片训练样本总共有3个类,为猫,狗,猪。现在输入一张测试集中的一张图片,和这1000张图片计算距离,将距离排序后,取前k个距离最小的图片出来,假设这里k 取值为10,那么上面所说的”k个最近邻点“就是这里的10张图片。现在找出了k 个样本,再来理解上面这句话(统计出有几个样本点属于那几个类):比如这K张已知分类图片,有4个猫,3个狗,3个猪,猫的图片出现的次数最多,那么输入的未知类别的图片就被分入了猫这一类。这就完成了一次K-NN算法循环。

这里大家应该明白了KNN算法在图像分类中的原理了吧。后面再来介绍具体怎么计算图片之间的”距离“。
3.k-NN算法的python实现(我做了详细注释)

class KNearestNeighbor(object):    def __init__(self):    pass   def train(self, X, y):    self.X_train = X //X是一个N×D的矩阵,N张图片,每张图片D个像素点    self.y_train = y//y也是一个矩阵,大小N×1,每个元素对应的X每张图片的分类(猫的话就是1,狗的话就是2,猪的话就是3def compute_distances_no_loops(self, X)://这是向量化操作计算图片之间的欧式距离,效率高,但是有点难理解    """    Compute the distance between each test point in X and each training point    in self.X_train using no explicit loops.    """    num_test = X.shape[0]//测试集图片数量    num_train = self.X_train.shape[0]//训练集图片数量    dists = np.zeros((num_test, num_train))//最后得到的距离矩阵,每个元素对应两张图片之间的距离//下面的就是矩阵操作,大家可以在之上做一个简单的运算(比如拿两个2*2的矩阵当成训练集和测试级),就会发现,得到的距离矩阵每个元素为两张图片的所有对应像素值的差的平方和(pixel_test - pixel_train)^2,    dists = np.multiply(np.dot(X, self.X_train.T), -2)    sq1 = np.sum(np.square(X), axis=1)    sq2 = np.sum(np.square(self.X_train), axis=1)    dists = np.add(dists, sq1)    dists = np.add(dists, sq2)    dists = np.sqrt(dists)    return dists //这个矩阵大小为【num_test*num_train】

下面代码根据计算出来的距离矩阵,进行k-NN算法预测测试集合图片的种类。
这里大家可以查一查argmax()函数和bincount()函数的作用。我后面的博客也会有这些函数功能的总结。

def predict_labels(self, dists, k=1):      num_test = dists.shape[0]      y_pred = np.zeros(num_test)      closest_y = [] #列表      sort_dist_index = np.argsort(dists)      k_sort_dist_index = sort_dist_index[:,0:k]//对距离排序后取前k和距离值在排序前的索引值,好知道这是第几张图      for i in dists.shape[0]:        for j in range(k):          k_sort_dist_index[i,j] = self.y_train[k_sort_dist_index[i,j]]//将对应的距离根据索引找到对应的类别      for i in dists.shape[0]:        y_pred[i] =np.argmax(np.bincount(k_sort_dist_index[i,:]))//找出出现频率最高的类别,则待判断图片就是出现频率最高的这一类别      return y_pred

以上就是对图片进行kNN分类的讲解。后面会继续完善。

原创粉丝点击