[笔记]Tensorflow-Lesson4_K邻近(K Nearest Neighbors)numpy到Tensorf

前言

在机器学习当中KNN算是简单的算法之一,但KNN稳定度是非常不稳定的,主要取决于K的设置,但K不是越大也不是越小越好,所以这就是我们困扰地方之一,还有KNN主要需计算输入资料与现有的标记资料两者的距离,这时候又产生一个问题,当维度越大计算量就越大,但若资料分群很明显使用KNN还是一个不错的方法,往后也可以拿来与其它机器学习合併做为参考。

KNN算法步骤

这里使用二维讲解KNN,它公式很简单,就是计算输入资料与标记资料每个点距离取出K个距离最小值进行投票。这里使用欧式距离。

计算输入资料和标记资料距离。取出K个距离最小值的原始标记。取出标记最多的标记。

Numpy实作KNN

程式码

1.创建标记资料与输入资料。

这里分为三群,使用concatenate将三群资料水平列(axis=0)合併,real_data为输入资料。

# initreal_datas1 = np.array(np.random.rand(10, 2) * 5)real_labels1 = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])real_datas2 = np.array(10 + np.random.rand(10, 2) * 5)real_labels2 = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])real_datas3 = np.array(20 + np.random.rand(10, 2) * 5)real_labels3 = np.array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2])# np.appendreal_datas = np.concatenate((real_datas1, real_datas2, real_datas3), axis=0)real_labels = np.concatenate((real_labels1, real_labels2, real_labels3))input_data = np.array([7.5, 7.5])

2.距离函数。

参数:value1为标籤资料,value2为输入资料。
value1大小为[N, 2],value2大小为[2],这里value2会往下自动扩展到[N, 2],计算完每个点距离后,设置axis=1垂直行加总,最后结果为与每个标记资料的距离。
注:若需要预测多笔则可使用扩展或一开始设置三维标记资料再用扩展。

def distance(value1, value2):    return np.sum((value1 - value2) ** 2, axis=1)
预测函数。

参数:real_datareal_label为标籤资料,input_data为输入资料,k为取几个投票数。
使用argpartition得到索引由小到大,排序至k个并取出索引放入real_label取出真实标籤。而取出标籤后要进行投票取出哪个标籤最多,这时候可使用迴圈方法(注解部分),或使用one-hot方法(因可直接用sum指令水平列往上加即是投票结果)。
这里使用one-hot,首先宣告一个数值为0、大小为[K, N群]的阵列,再将one_hot_labels放入索引位置指派1,结果即是one-hot,在使用sum设置axis=0往上加总,结果为投票结果,最后取出最大值的索引位置即是预测结果。

def predict(real_data, real_label, input_data, k):    distances = distance(real_data, input_data)    near_labels = real_label[np.argpartition(distances, np.arange(0, k, 1))[0:k]]    one_hot_labels = np.zeros((k, class_type))    one_hot_labels[np.arange(k), near_labels] = 1    vote_labels = np.sum(one_hot_labels, axis=0)    #vote_labels = np.zeros([class_type])    #for index in range(class_type - 1) :    #    vote_labels[index] = np.sum(near_labels == index)     return np.argmax(vote_labels)
绘图

get_predict_color输入为标籤,回传为绘图的颜色和形状。

def get_predict_color(type):    if type == 0:        return 'yo'    elif type == 1:        return 'ro'    else:        return 'bo'        plt.plot(real_datas1[:, 0], real_datas1[:, 1], 'yo')plt.plot(real_datas2[:, 0], real_datas2[:, 1], 'ro')plt.plot(real_datas3[:, 0], real_datas3[:, 1], 'bo')plt.plot(input_data[0], input_data[1], get_predict_color(predict_type))plt.show()

结果图

http://img2.58codes.com/2024/20110564frIICNZdUB.png
预测图为第二类,有时候会第一类。

Tensorflow实作KNN

两者非常相似,很多只差在宣告或API不同,但Tensorboard能方便提供可视化流程和数据给我们参考,所以如果需要给别人看流程或者数据可以使用Tensorflow来实作。

程式码

1.创建标记资料与输入资料。

这里分为三群,使用concat将三群资料水平列(axis=0)合併,real_data为输入资料。

real_datas1 = tf.random_uniform([10, 2], minval=0, maxval=5, name="real_datas1")real_labels1 = tf.constant([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], name="real_labels1")real_datas2 = tf.random_uniform([10, 2], minval=10, maxval=15, name="real_datas2")real_labels2 = tf.constant([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], name="real_labels2")real_datas3 = tf.random_uniform([10, 2], minval=20, maxval=25, name="real_datas3")real_labels3 = tf.constant([2, 2, 2, 2, 2, 2, 2, 2, 2, 2], name="real_labels3")real_datas = tf.concat([real_datas1, real_datas2, real_datas3], axis=0, name="real_datas")real_labels = tf.concat([real_labels1, real_labels2, real_labels3], axis=0, name="real_labels")input_data = tf.constant([7.5, 7.5], dtype=tf.float32, name="input_data")

http://img2.58codes.com/2024/20110564qAy5Iw8UdX.png
初始化数据。

2.距离函数。

参数:value1为标籤资料,value2为输入资料。
real_datas大小为[N, 2],input_data大小为[2],使用subtract计算矩阵减法,input_data会自动扩展至[N, 2],计算完每个点距离后,设置axis=1垂直行加总,最后结果为与每个标记资料的距离。
注:若需要预测多笔则可使用扩展或一开始设置三维标记资料再用扩展。

def distance(real_datas, input_data):    diff = tf.subtract(real_datas, input_data) ** 2    row_sum = tf.reduce_sum(diff, axis=1)    return row_sum

http://img2.58codes.com/2024/20110564zzXMbqOUUm.png
距离函数。

预测函数。

参数:real_datasreal_labels为标籤资料,input_data为输入资料,k为取几个投票数。
使用top_k得到k个由小到大(使用negativetop_k预设大到小)的索引值(indices),使用gather取出索引对应的真实标籤。使用one_hot_labels取得one-hot,在使用sum设置axis=0往上加总,结果为投票结果,最后取出最大值的索引位置即是预测结果。

def predict(real_datas, real_labels, input_data, k):    distances = distance(real_datas, input_data)    near_indexs = tf.nn.top_k(tf.negative(distances), k).indices    near_labels = tf.gather(real_labels, near_indexs, name="near_labels")    one_hot_labels = tf.one_hot(indices=near_labels, depth=class_type, on_value=1, off_value=0, name="one_hot_labels")    count_labels = tf.reduce_sum(one_hot_labels, axis=0)    return tf.argmax(count_labels)

http://img2.58codes.com/2024/20110564N5BCqimtl0.png
预测函数。

绘图。
plt.plot(session.run(real_datas1[:, 0]), session.run(real_datas1[:, 1]), 'yo')plt.plot(session.run(real_datas2[:, 0]), session.run(real_datas2[:, 1]), 'ro')plt.plot(session.run(real_datas3[:, 0]), session.run(real_datas3[:, 1]), 'bo')plt.plot(session.run(input_data[0]), session.run(input_data[1]), get_predict_color(predict_type))plt.show()

结果图

http://img2.58codes.com/2024/20110564gnGceLbzKn.png
预测图为第一类,有时候会第二类。

结语

参考的东西其实算是之前上人工智慧课程老师介绍的,但不知该如何打所以省略,下次介绍计算方式有些地方很像的KMean,若有问题或错误欢迎留言或私讯。

参考网址与书籍

[1] https://www.tensorflow.org/api_docs/python/tf


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章