From eff8dfd6d928818d1a1950be133a32a9aedaf016 Mon Sep 17 00:00:00 2001 From: 202210423104 <1961532386@qq.com> Date: Wed, 16 Oct 2024 22:10:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=20/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- function.py | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/function.py b/function.py index 630511a..946a307 100644 --- a/function.py +++ b/function.py @@ -5,7 +5,8 @@ from collections import Counter id = "202210423104" name = "张钦诚" -def classify0(inX, dataSet, labels, k=5): + +def classify0(inX, dataSet, labels, k=1): """ 加权 kNN 分类算法。 @@ -13,7 +14,7 @@ def classify0(inX, dataSet, labels, k=5): - inX (list or numpy array): 输入待分类的样本。 - dataSet (numpy array): 训练数据集。 - labels (list or numpy array): 训练集对应的标签。 - - k (int): kNN 算法参数,默认值为5。 + - k (int): kNN 算法参数,默认值为1。 Returns: - int: 预测的分类标签。 @@ -24,13 +25,23 @@ def classify0(inX, dataSet, labels, k=5): # 获取距离最小的k个样本的索引 nearest_indices = np.argpartition(distances, k)[:k] nearest_labels = labels[nearest_indices] - nearest_distances = distances[nearest_indices] - # 计算权重,距离越近权重越大 - weights = 1 / (nearest_distances + 1e-5) # 防止除以零 - # 使用 np.bincount 进行加权统计 - label_weights = np.bincount(nearest_labels, weights=weights) - # 返回权重最大的标签 - return np.argmax(label_weights) + + if k == 1: + # 如果k=1,直接返回最近邻的标签 + return nearest_labels[0] + else: + # 加权 kNN + nearest_distances = distances[nearest_indices] + weights = 1 / (nearest_distances + 1e-5) # 防止除以零 + label_weights = {} + for label, weight in zip(nearest_labels, weights): + if label in label_weights: + label_weights[label] += weight + else: + label_weights[label] = weight + # 返回权重最大的标签 + return max(label_weights.items(), key=lambda x: x[1])[0] + def load_data(file_path): """ @@ -47,6 +58,7 @@ def load_data(file_path): labels = data[:, -1].astype(int) return features, labels + def standardize(train_data, test_data): """ 对训练数据和测试数据进行标准化处理。 @@ -56,15 +68,15 @@ def standardize(train_data, test_data): - test_data (numpy array): 测试数据集。 Returns: - - tuple: (标准化后的训练数据, 标准化后的测试数据) + - tuple: (标准化后的训练数据, 标准化后的测试数据, 均值, 标准差) """ mean = np.mean(train_data, axis=0) std = np.std(train_data, axis=0) - # 防止标准差为零 - std[std == 0] = 1 + std[std == 0] = 1 # 防止标准差为零 train_standardized = (train_data - mean) / std test_standardized = (test_data - mean) / std - return train_standardized, test_standardized + return train_standardized, test_standardized, mean, std + if __name__ == "__main__": train_file = "datingTrainSet2.tsv" @@ -76,12 +88,12 @@ if __name__ == "__main__": test_data, test_labels = load_data(test_file) # 数据标准化 - train_data, test_data = standardize(train_data, test_data) + train_data, test_data, mean, std = standardize(train_data, test_data) # 测试样本 test_sample = [65915, 3.868359, 0.128078] # 标准化测试样本 - test_sample = (np.array(test_sample) - np.mean(train_data, axis=0)) / np.std(train_data, axis=0) + test_sample = (np.array(test_sample) - mean) / std # 预测标签 predicted_label = classify0(test_sample, train_data, train_labels)