# function.py import numpy as np """ 挑战说明: - 自行编写实现 KNN 分类算法。 - 输入: 待分类的样本 inX, 训练数据集 dataSet, 训练集对应的标签 labels。 - 输出: 预测的分类标签。 注意事项: - 可以自行导入其他库,需要在 requirements.txt 添加依赖,若未在 requirements.txt 中添加使用到的依赖,则无法自动评测,成绩为零。 - 在 function.py 中实现 KNN 分类算法。 - 自动评测脚本仅会加载 classify0 函数,请勿修改函数名。 - 训练集在本目录下的 datingTrainSet2.tsv 中。 - 评测数据集在本目录下的 datingTestSet2.tsv 中。 挑战环境: - Ubuntu 22.04.04 LTS - Python 3.10.12 """ """ 请在这里填写学号和姓名,不填写即成绩无效。 """ id = "202210423226" name = "潘宇豪" """ 参数说明: - inX (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 返回值: - int: 预测的分类标签。 """ def classify0(inx, dataSet, labels, k_values=[3,4,8,9], _cache={"VI": None}): """ KNN分类算法,使用多种k值并通过投票机制预测最终结果。此版本不使用显式for循环。 参数: - inx (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 - k_values (list): 使用的邻居数量的不同k值。 - _cache (dict): 缓存数据,用于存储协方差矩阵的逆。 返回值: - int: 预测的分类标签。 """ # 使用缓存,直接获取协方差矩阵的逆 if _cache["VI"] is None: _cache["VI"] = np.linalg.inv(np.cov(dataSet.T)) # 计算输入样本与数据集的差值 diff = dataSet - inx # 使用矩阵运算计算马氏距离 distances = np.sum(diff @ _cache["VI"] * diff, axis=1) # 对距离排序,获取所有样本索引 sortedDistIndices = np.argsort(distances) # 创建一个矩阵来保存每个k值的前k个样本的标签 max_k = max(k_values) # 找到最大的k nearest_labels = labels[sortedDistIndices[:max_k]] # 取最大的k个邻居的标签 # 为每个k值计算预测结果,统计不同k值下出现最多的标签 predictions = np.array([np.bincount(nearest_labels[:k]).argmax() for k in k_values]) # 对所有预测结果进行投票,选择出现次数最多的标签作为最终结果 final_prediction = np.bincount(predictions).argmax() return final_prediction def load_data(file_path): """ 加载TSV格式的数据文件。 参数: - file_path (str): 数据文件的路径。 返回值: - tuple: 包含特征数组和标签数组的元组。 """ features = [] labels = [] with open(file_path, "r") as file: for line in file: values = line.strip().split("\t") features.append([float(x) for x in values[:-1]]) labels.append(int(values[-1])) return np.array(features), np.array(labels) if __name__ == "__main__": train_file = "datingTrainSet2.tsv" train_data, train_labels = load_data(train_file) # 使用一个测试样本进行测试 test_result = classify0([65915, 3.868359, 0.128078], train_data, train_labels, k=3) print("预测结果:", test_result)