# function.py import numpy as np from collections import Counter from scipy.spatial import distance from sklearn.preprocessing import StandardScaler """ 挑战说明: - 自行编写实现 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 = "202210423117" name = "程悦" """ 参数说明: - inX (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 返回值: - int: 预测的分类标签。 """ # 这里写自己的代码实现 def classify0(inX, dataSet, labels, k=9): """ KNN 分类算法。 Args: - inX (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 - k (int): KNN 算法参数,请自行设置默认值,评测时仅会使用其默认值。 Returns: - int: 预测的分类标签。 """ # 计算协方差矩阵并求逆矩阵 cov_matrix = np.cov(dataSet, rowvar=False) inv_cov_matrix = np.linalg.inv(cov_matrix) # 计算输入样本与训练集样本的马氏距离 distances = [distance.mahalanobis(inX, data_point, inv_cov_matrix) for data_point in dataSet] # 按距离排序并选择前 k 个最近的邻居 k_indices = np.argsort(distances)[:k] k_nearest_labels = [labels[i] for i in k_indices] # 统计最近邻居中最多的标签 label_counts = Counter(k_nearest_labels) most_common_label = label_counts.most_common(1)[0][0] return most_common_label def load_data(file_path): """ 加载 TSV 格式数据文件。 """ data = np.loadtxt(file_path, delimiter="\t") features = data[:, :-1] labels = data[:, -1].astype(int) return features, labels if __name__ == "__main__": # 以下代码可用于测试,可自行随意修改 train_file = "datingTrainSet2.tsv" test_file = "datingTestSet2.tsv" train_data, train_labels = load_data(train_file) test_data, test_labels = load_data(test_file) # # 特征缩放 # scaler = StandardScaler() # train_data = scaler.fit_transform(train_data) # test_data = scaler.transform(test_data) # 测试 classify0 函数 test_sample = test_data[0] # 使用测试集中的第一个样本进行测试 predicted_label = classify0(test_sample, train_data, train_labels) print(f"Predicted label: {predicted_label}, Actual label: {test_labels[0]}") # 遍历整个测试集来评估分类器的性能 correct_count = 0 for i in range(len(test_data)): predicted_label = classify0(test_data[i], train_data, train_labels) if predicted_label == test_labels[i]: correct_count += 1 accuracy = correct_count / len(test_data) print(f"Accuracy: {accuracy * 100:.2f}%")