diff --git a/function.py b/function.py index 0b1bff6..1a57eaf 100644 --- a/function.py +++ b/function.py @@ -53,23 +53,23 @@ def classify(input_vector, dataSet, labels, k=3): Returns: - int: 预测的分类标签。 """ - # 计算输入向量与数据集中每个向量之间的距离 - distances = [np.linalg.norm(row-input_vector) for row in dataSet] - # 获取距离最小的k个样本的索引 - sortedDistIndices = np.argsort(distances) - # 获取这些样本对应的标签 - classCount = {} - for i in range(k): - voteLabel = labels[sortedDistIndices[i]] - # 统计每个类别的出现次数 - classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 - # 返回出现次数最多的类别 - sortedClassCount = sorted(classCount.items(), key=lambda x: x[1], reverse=True) - return sortedClassCount[0][0] + # 检查k的值是否大于训练集样本数,如果是,则抛出异常 + if k > len(labels): + raise ValueError("k 不能大于训练集样本数") + + # 计算输入向量与数据集中每个样本的欧几里得距离 + distances = np.linalg.norm(dataSet - input_vector, axis=1) + # 获取距离最近的k个样本的索引 + sorted_indices = distances.argsort() + # 获取这k个最近邻样本的标签 + nearest_labels = np.array(labels)[sorted_indices[:k]] + # 统计这k个样本中出现次数最多的标签,并返回该标签作为预测结果 + predicted_label = np.bincount(nearest_labels).argmax() + return predicted_label def load_dataset(directory): """ - 从文件夹中加载数据,若不自行正确实现,则无法通过评测,**不记录成绩**。 + 从文件夹中加载数据,若不自行正确实现,则无法通过评测,不记录成绩。 Args: - directory (str): 数据文件夹路径。 @@ -78,25 +78,23 @@ def load_dataset(directory): - np.array: 特征数据。 - np.array: 标签数据。 """ - fileList = os.listdir(directory) - numberOfFiles = len(fileList) - m = numberOfFiles - n = 1024 # 假设每个图像是32x32的 - dataSet = np.zeros((m, n)) # 存储特征数据 - labels = [] # 存储标签 - for i in range(m): - filename = fileList[i] - filePath = os.path.join(directory, filename) - vector = img_to_vector(filePath) - dataSet[i, :] = vector - # 假设文件名的格式是"label01.txt",其中label是标签 - label = int(filename.split('.')[0][1]) - labels.append(label) - return dataSet, np.array(labels) + data = [] + labels = [] + # 遍历文件夹中的所有文件 + for filename in os.listdir(directory): + if filename.endswith(".txt"): + # 提取文件名中的标签信息 + label = int(filename.split('_')[0]) + labels.append(label) + # 将图像文件转换为向量 + vector = img_to_vector(os.path.join(directory, filename)) + data.append(vector) + return np.array(data), np.array(labels) def img_to_vector(filename): """ 将二值图像转换为向量。 + 该部分应为 load_dataset 函数的辅助子函数,可单独在这里实现,也可直接集成至 load_dataset 函数中。 Args: - filename (str): 图像文件路径。 @@ -104,57 +102,29 @@ def img_to_vector(filename): Returns: - np.array: 二值图像向量。 """ - returnVect = np.zeros((1, 1024)) # 假设图像是32x32的 - with open(filename, 'r') as file: - lines = file.readlines() - index = 0 - for line in lines: - for i in range(len(line)-1): - if line[i] == '1': - returnVect[0, index] = 1 - index += 1 - return returnVect + with open(filename, 'r') as f: + lines = f.readlines() + # 将32x32的字符矩阵转换为长度为1024的一维数组 + vector = np.array([int(char) for line in lines for char in line.strip()]) + return vector 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" - ) - predicted_label = classify( - np.array([int(char) for char in test_data]).reshape(1, 1024), - train_data, - train_labels, - ) + # 加载训练集和测试集 + train_data, train_labels = load_dataset("D:\projects\机器学习_projects\实验\trainingDigits") + test_data, test_labels = load_dataset("D:\projects\机器学习_projects\实验\testDigits") - print(f"预测的标签: {predicted_label}") \ No newline at end of file + # 记录预测的正确数量 + correct_count = 0 + + # 遍历测试集,逐个样本进行分类 + for i in range(len(test_data)): + predicted_label = classify(test_data[i], train_data, train_labels) + print(f"测试样本 {i+1} 的真实标签: {test_labels[i]},预测标签: {predicted_label}") + + # 如果预测正确,则正确数量加一 + if predicted_label == test_labels[i]: + correct_count += 1 + + # 打印准确率 + accuracy = correct_count / len(test_data) * 100 + print(f"测试集的准确率: {accuracy:.2f}%") \ No newline at end of file