我开始使用Python的Tensorflow库进行一个基于K近邻(K-Nearest-Neighbors)的机器学习项目。我之前没有使用Tensorflow的经验,所以我在GitHub上找到了部分代码,并根据我的数据进行了修改。
我的数据集如下所示:
2,2,2,2,0,0,32,2,2,2,0,1,02,2,2,4,2,2,1...2,2,2,4,2,0,0
以下是运行正常的代码:
import tensorflow as tfimport numpy as np# 整个数据集 => 1428个样本dataset = 'car-eval-data-1.csv'# 用于训练的样本,剩余用于测试samples = 1300reader = np.loadtxt(open(dataset, "rb"), delimiter=",", skiprows=1, dtype=np.int32)train_x, train_y = reader[:samples,:5], reader[:samples,6]test_x, test_y = reader[samples:, :5], reader[samples:, 6]# 占位符,你可以在未来为其赋值。这类似于变量# v = ("变量类型",[None,4]) -- 你可以在这里使用多维值training_values = tf.placeholder("float",[None,len(train_x[0])])test_values = tf.placeholder("float",[len(train_x[0])])# 曼哈顿距离distance = tf.abs(tf.reduce_sum(tf.square(tf.subtract(training_values,test_values)),reduction_indices=1))prediction = tf.arg_min(distance, 0)init = tf.global_variables_initializer()accuracy = 0.0with tf.Session() as sess: sess.run(init) # 遍历测试集以与训练集进行比较 for i in range (len(test_x)): # 使用Tensorflow方法获取与测试参数在训练集中最接近的预测。 index_in_trainingset = sess.run(prediction, feed_dict={training_values:train_x,test_values:test_x[i]}) print("测试 %d, 预测结果是 %s, 实际值是 %s"%(i,train_y[index_in_trainingset],test_y[i])) if train_y[index_in_trainingset] == test_y[i]: # 如果预测正确,准确率增加。 accuracy += 1. / len(test_x)print('准确率 -> ', accuracy * 100, ' %')
我唯一不理解的是,如果使用的是KNN方法,那么应该有一个K参数来定义每个测试样本用于预测标签的邻居数量。
我们如何为代码设置K参数来调整最近邻居的数量?
有没有办法修改这段代码以使用K参数?
回答:
你说的对,以上的例子确实没有提供选择K近邻的功能。在下面的代码中,我添加了设置此类参数(knn_size)的能力,并进行了其他修正
import tensorflow as tfimport numpy as np# 整个数据集 => 1428个样本dataset = 'PATH_TO_DATASET_CSV'knn_size = 1# 用于训练的样本,剩余用于测试samples = 1300reader = np.loadtxt(open(dataset, "rb"), delimiter=",", skiprows=1, dtype=np.int32)train_x, train_y = reader[:samples,:6], reader[:samples,6]test_x, test_y = reader[samples:, :6], reader[samples:, 6]# 占位符,你可以在未来为其赋值。这类似于变量# v = ("变量类型",[None,4]) -- 你可以在这里使用多维值training_values = tf.placeholder("float",[None, len(train_x[0])])test_values = tf.placeholder("float",[len(train_x[0])])# 曼哈顿距离distance = tf.abs(tf.reduce_sum(tf.square(tf.subtract(training_values,test_values)),reduction_indices=1))# 这里,我们将距离乘以-1以反转距离的大小,即最大的距离变为最小的距离# tf.nn.top_k返回前k个值及其索引,这里k由参数knn_size控制 k_nearest_neighbour_values, k_nearest_neighbour_indices = tf.nn.top_k(tf.scalar_mul(-1,distance),k=knn_size)#基于前一步获得的索引,我们在训练数据中找到k个最近匹配的精确类标签集best_training_labels = tf.gather(train_y,k_nearest_neighbour_indices)if knn_size==1: prediction = tf.squeeze(best_training_labels)else: # 现在我们根据在训练数据中出现频率最高的类标签进行预测 # tf.unique_with_counts() 给出1-D张量中所有唯一值及其索引和计数 values, indices, counts = tf.unique_with_counts(best_training_labels) # 这给出重复次数最多的类标签的索引 max_count_index = tf.argmax(counts,0) #检索所需的类标签 prediction = tf.gather(values,max_count_index)init = tf.global_variables_initializer()accuracy = 0.0with tf.Session() as sess: sess.run(init) # 遍历测试集以与训练集进行比较 for i in range (len(test_x)): # 使用Tensorflow方法获取与测试参数在训练集中最接近的预测。 prediction_value = sess.run([prediction], feed_dict={training_values:train_x,test_values:test_x[i]}) print("测试 %d, 预测结果是 %s, 实际值是 %s"%(i,prediction_value[0],test_y[i])) if prediction_value[0] == test_y[i]: # 如果预测正确,准确率增加。 accuracy += 1. / len(test_x)print('准确率 -> ', accuracy * 100, ' %')