import numpy as np import os import time def classify(input_vector, dataSet, labels, k=4): """ KNN 分类算法。 Args: - input_vector (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 - k (int): kNN 算法参数,默认值为 4。 Returns: - int: 预测的分类标签。 """ # 计算输入向量与数据集中每个向量的欧式距离 diffMat = np.tile(input_vector, (dataSet.shape[0], 1)) - dataSet sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) distances = sqDistances**0.5 # 获取距离最近的 k 个样本的索引 sortedDistIndices = distances.argsort() classCount = {} for i in range(k): voteIlabel = labels[sortedDistIndices[i]] # 统计每个类别的出现次数 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 返回出现次数最多的类别 sortedClassCount = sorted(classCount.items(), key=lambda x: x[1], reverse=True) return sortedClassCount[0][0] def load_dataset(directory): """ 从文件夹中加载数据。 Args: - directory (str): 数据文件夹路径。 Returns: - np.array: 特征数据。 - np.array: 标签数据。 """ fileList = os.listdir(directory) m = len(fileList) dataSet = np.zeros((m, 1024)) # 28*28的二值图像数据 labels = [] for i in range(m): filename = fileList[i] filePath = os.path.join(directory, filename) vector = img_to_vector(filePath) dataSet[i, :] = vector # 假设文件名的格式为 "label_number.txt" label = int(filename.split('_')[0]) labels.append(label) return dataSet, np.array(labels) def img_to_vector(filename): """ 将二值图像转换为向量。 Args: - filename (str): 图像文件路径。 Returns: - np.array: 二值图像向量。 """ returnVect = np.zeros((1, 1024)) with open(filename, 'r') as file: lines = file.readlines() n = 0 for line in lines: # 去除每行末尾的换行符 line = line.strip() for i in range(len(line)): returnVect[0, n] = int(line[i]) n = n + 1 if n >= 1024: break if n >= 1024: break return returnVect if __name__ == "__main__": # 加载训练数据集 train_data, train_labels = load_dataset("trainingDigits") # 测试数据 test_data = ( "00000000000000110000000000000000" "00000000000011111000000000000000" "00000000000011111100000000000000" "00000000001111111110000000000000" "00000000001111111110000000000000" "00000000001111111100000000000000" "00000000011111111000000000000000" "00000000111111111000000000000000" "00000000111111110000000000000000" "00000000111111110000000000000000" "00000000111111110000000000000000" "00000000111111110000000000000000" "00000000111111100000000000000000" "00000001111111100000000000000000" "00000001111111100000000000000000" "00000001111111100000000000000000" "00000001111111111111000000000000" "00000001111111111111111000000000" "00000001111111111111111100000000" "00000011111111111111111110000000" "00000011111111111111111110000000" "00000001111111111111111110000000" "00000001111111111111111110000000" "00000000111111111100111111100000" "00000000111111111000111111100000" "00000000011111111001111111100000" "00000000011111111111111111000000" "00000000001111111111111111000000" "00000000000111111111111111000000" "00000000000011111111111100000000" "00000000000001111111110000000000" "00000000000000000111100000000000" ) test_data_vector = np.array([int(char) for char in test_data]).reshape(1, 1024) # 使用k=4进行分类 start_time = time.time() predicted_label = classify(test_data_vector, train_data, train_labels, k=4) end_time = time.time() print(f"k = 4, 预测的标签: {predicted_label}, 执行时间: {end_time - start_time:.2f} 秒")