# function.py import numpy as np from collections import Counter from scipy.spatial.distance import cdist from sklearn.preprocessing import StandardScaler """ 挑战说明: - 自行编写实现 KNN 分类算法。 - 函数输入: 待分类的样本 inX, 训练数据集 dataSet, 训练集对应的标签 labels。 - 函数返回: 预测的分类标签。 注意事项: - 可以自行导入其他库,需要在 requirements.txt 添加依赖,若未在 requirements.txt 中添加使用到的依赖,则无法自动评测,成绩为零。 - 在 function.py 中实现 KNN 分类算法。 - 自动评测脚本仅会加载 classify0 函数,请勿修改函数名。 - 训练集在本目录下的 datingTrainSet2.tsv 中。 - 评测数据集在本目录下的 datingTestSet2.tsv 中。 挑战环境: - CPU: Intel Xeon(R) CPU E3-1231 v3 @ 3.40GHz - OS: Ubuntu 22.04.4 LTS - Python: 3.10.12 - numpy: 2.1.1 """ """ 请在这里填写学号和姓名,不填写即成绩无效。 """ id = "202210423210" name = "陈宇杰" """ 参数说明: - inX (numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 返回值: - int: 预测的分类标签。 """ # 这里写自己的代码实现 def classify0(inX, dataSet, labels, k=37): """ KNN 分类函数 :param inX: 待分类的样本 :param dataSet: 训练数据集 :param labels: 训练集对应的标签 :param k: 选择的邻居数 :return: 预测的分类标签 """ distances = np.linalg.norm(dataSet - inX, axis=1) # 计算欧几里得距离 nearest_indices = distances.argsort()[:k] # 获取最近的 k 个邻居 nearest_labels = [labels[i] for i in nearest_indices] # 获取这些邻居的标签 predicted_label = Counter(nearest_labels).most_common(1)[0][0] # 多数投票 return predicted_label def load_data(file_path): """ 加载 TSV 格式数据文件 :param file_path: 数据文件路径 :return: 特征和标签 """ data = np.loadtxt(file_path, delimiter="\t") # 加载数据 features = data[:, :-1] # 特征 labels = data[:, -1].astype(int) # 标签 return features, labels def main(): # 加载训练集 train_file = "datingTrainSet2.tsv" # 训练集文件路径 train_data, train_labels = load_data(train_file) # 加载数据 # 特征缩放 scaler = StandardScaler() # 创建标准化对象 train_data = scaler.fit_transform(train_data) # 对训练数据进行标准化 # 设置 K 值 k = 8 # 将 K 值设置为 3 # 手动实现 KNN 分类计算准确率 correct_predictions = 0 total_tests = len(train_data) # 测试的总数 for i in range(total_tests): # 留出一条数据作为测试集,其余作为训练集 test_sample = train_data[i] train_subset = np.delete(train_data, i, axis=0) train_labels_subset = np.delete(train_labels, i) # 使用 KNN 分类器预测 predicted_label = classify0(test_sample, train_subset, train_labels_subset) # 输出分类结果 if predicted_label == train_labels[i]: correct_predictions += 1 else: print(f"第 {i + 1} 次测试错误,数据 {test_sample} 被分类到 {predicted_label},实际是 {train_labels[i]}") accuracy = correct_predictions / total_tests # 计算准确性 print(f"使用 K 值 {k} 的准确率: {accuracy:.4f}") # 测试分类 test_sample = [65915, 3.868359, 0.128078] # 测试样本 test_sample = scaler.transform([test_sample]) # 对测试样本进行相同的缩放 predicted_label = classify0(test_sample[0], train_data, train_labels) # 分类 print(f"测试样本 {test_sample[0]} 的预测分类标签为: {predicted_label}") if __name__ == "__main__": main()