diff --git a/function.py b/function.py index cdce729..73b0ef1 100644 --- a/function.py +++ b/function.py @@ -28,50 +28,53 @@ id = "202210423117" name = "程悦" -def normalize(data): - """ - 对数据进行归一化处理,将数据缩放到 [0, 1] 范围内。 - - Args: - - data (numpy array): 待归一化的数据。 - - Returns: - - numpy array: 归一化后的数据。 - """ - min_val = data.min(axis=0) - max_val = data.max(axis=0) - return (data - min_val) / (max_val - min_val + 1e-10) # 避免除以零 - -def classify(input_vector, dataSet, labels, k=2): - """ - KNN 分类算法,添加了数据归一化处理。 - - Args: - - input_vector (numpy array): 输入待分类的样本。 - - dataSet (numpy array): 训练数据集。 - - labels (list or numpy array): 训练集对应的标签。 - - k (int): kNN 算法参数。 - - Returns: - - int: 预测的分类标签。 - """ - # 归一化训练数据集和输入向量 - dataSet = normalize(dataSet) - input_vector = normalize(input_vector) - - dataSet_size = dataSet.shape[0] - # 计算欧氏距离 - diff_mat = np.tile(input_vector, (dataSet_size, 1)) - dataSet - sq_diff_mat = diff_mat ** 2 - sq_distances = sq_diff_mat.sum(axis=1) - distances = np.sqrt(sq_distances) - # 对距离进行排序 - sorted_indices = distances.argsort() - class_count = {} - for i in range(k): - vote_label = labels[sorted_indices[i]] - class_count[vote_label] = class_count.get(vote_label, 0) + 1 - sorted_class_count = sorted(class_count.items(), key=lambda x: x[1], reverse=True) +def standardize(data): + """ + 对数据进行标准化处理,将数据转换为标准分数(Z分数),均值为0,标准差为1。 + + Args: + - data (numpy array): 待标准化的数据。 + + Returns: + - numpy array: 标准化后的数据。 + - numpy array: 每个特征的均值。 + - numpy array: 每个特征的标准差。 + """ + mean_val = data.mean(axis=0) + std_val = data.std(axis=0, ddof=0) # ddof=0 表示使用样本标准差(N-1作为分母) + standardized_data = (data - mean_val) / (std_val + 1e-10) # 避免除以零 + return standardized_data, mean_val, std_val + +def classify(input_vector, dataSet, labels, k=2): + """ + KNN 分类算法,添加了数据标准化处理。 + + Args: + - input_vector (numpy array): 输入待分类的样本。 + - dataSet (numpy array): 训练数据集。 + - labels (list or numpy array): 训练集对应的标签。 + - k (int): kNN 算法参数。 + + Returns: + - int: 预测的分类标签。 + """ + # 标准化训练数据集和输入向量 + dataSet_standardized, mean_dataSet, std_dataSet = standardize(dataSet) + input_vector_standardized, _, _ = standardize(np.array([input_vector])) # 注意输入向量需要转换为二维数组形式 + + dataSet_size = dataSet_standardized.shape[0] + # 计算欧氏距离 + diff_mat = np.tile(input_vector_standardized, (dataSet_size, 1)) - dataSet_standardized + sq_diff_mat = diff_mat ** 2 + sq_distances = sq_diff_mat.sum(axis=1) + distances = np.sqrt(sq_distances) + # 对距离进行排序 + sorted_indices = distances.argsort() + class_count = {} + for i in range(k): + vote_label = labels[sorted_indices[i]] + class_count[vote_label] = class_count.get(vote_label, 0) + 1 + sorted_class_count = sorted(class_count.items(), key=lambda x: x[1], reverse=True) return sorted_class_count[0][0]