From d18773adc3724b091179b1f7bbf8ee40f10a2149 Mon Sep 17 00:00:00 2001 From: zhangchenghong <1598349064@qq.com> Date: Tue, 22 Oct 2024 20:51:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20function.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- function.py | 255 +++++++++++++++++++++++++--------------------------- 1 file changed, 123 insertions(+), 132 deletions(-) diff --git a/function.py b/function.py index c72d396..161cc84 100644 --- a/function.py +++ b/function.py @@ -28,136 +28,127 @@ import os id = "202210423215" name = "章程鸿·" - -import numpy as np -import os -from collections import Counter - - -def classify(input_vector, dataSet, labels, k=2): - """ - 使用 KNN 算法对输入样本进行分类。 - - 参数: - - input_vector (numpy array): 输入待分类的样本(1xN)。 - - dataSet (numpy array): 训练数据集(MxN)。 - - labels (list or numpy array): 训练集对应的标签。 - - k (int): kNN 算法参数,默认值为 2。 - - 返回: - - int: 预测的分类标签。 - """ - # 计算马氏距离 - centered_dataSet = dataSet - np.mean(dataSet, axis=0) - centered_input_vector = input_vector - np.mean(dataSet, axis=0) - cov_matrix = np.cov(centered_dataSet.T) - if np.linalg.det(cov_matrix) == 0: - raise ValueError("协方差矩阵不可逆") - inv_cov_matrix = np.linalg.inv(cov_matrix) - mahalanobis_distances = np.sqrt(np.sum(centered_input_vector.dot(inv_cov_matrix) * centered_input_vector, axis=1)) - - sorted_indices = mahalanobis_distances.argsort() - k_nearest_distances = mahalanobis_distances[sorted_indices[:k]] - k_nearest_labels = labels[sorted_indices[:k]] - - # 计算权重(距离的倒数) - weights = 1 / k_nearest_distances - # 归一化权重 - weights /= weights.sum() - - # 计算加权投票 - weighted_votes = np.zeros((10,)) - for label, weight in zip(k_nearest_labels, weights): - weighted_votes[label] += weight - - return np.argmax(weighted_votes) - - -def load_dataset(directory): - """ - 加载数据集中的图像,并将其转换为特征向量和标签。 - - 参数: - - directory (str): 数据文件夹路径。 - - 返回: - - np.array: 特征数据(Mx1024)。 - - np.array: 标签数据(Mx1)。 - """ - feature_list = [] - label_list = [] - for file in os.listdir(directory): - file_path = os.path.join(directory, file) - feature_vector = img_to_vector(file_path) - feature_list.append(feature_vector) - label_list.append(int(file.split('_')[0])) - feature_matrix = np.array(feature_list) - label_array = np.array(label_list) - - # 特征缩放 - feature_matrix = feature_matrix / 255.0 - return feature_matrix, label_array - - -def img_to_vector(filename): - """ - 将二值图像转换为向量。 - - Args: - - filename (str): 图像文件路径。 - - Returns: - - np.array: 二值图像向量。 - """ - vector = np.zeros((1024,)) - with open(filename) as file: - for i, line in enumerate(file): - vector[i * 32:i * 32 + 32] = np.array([int(char) for char in line.strip()]) - return vector - - -if __name__ == "__main__": - train_data, train_labels = load_dataset("trainingDigits") - - test_data = ( - "00000000000000110000000000000000" - "00000000000011111000000000000000" - "00000000000011111100000000000000" - "00000000001111111110000000000000" - "00000000001111111110000000000000" - "00000000001111111100000000000000" - "00000000011111111000000000000000" - "00000000111111111000000000000000" - "00000000111111110000000000000000" - "00000000111111110000000000000000" - "00000000111111110000000000000000" - "00000000111111110000000000000000" - "00000000111111100000000000000000" - "00000001111111100000000000000000" - "00000001111111100000000000000000" - "00000001111111100000000000000000" - "00000001111111111111000000000000" - "00000001111111111111111000000000" - "00000001111111111111111100000000" - "00000011111111111111111110000000" - "00000011111111111111111110000000" - "00000001111111111111111110000000" - "00000001111111111111111110000000" - "00000000111111111100111111100000" - "00000000111111111000111111100000" - "00000000011111111001111111100000" - "00000000011111111111111111000000" - "00000000001111111111111111000000" - "00000000000111111111111111000000" - "00000000000011111111111100000000" - "00000000000001111111110000000000" - "00000000000000000111100000000000" - ) - predicted_label = classify( - np.array([int(char) for char in test_data]).reshape(1, 1024), - train_data, - train_labels, - ) - +import numpy as np +import os +from collections import Counter + +def classify(input_vector, dataSet, labels, k=2): + """ + 使用 KNN 算法对输入样本进行分类。 + + 参数: + - input_vector (numpy array): 输入待分类的样本(1xN)。 + - dataSet (numpy array): 训练数据集(MxN)。 + - labels (list or numpy array): 训练集对应的标签。 + - k (int): kNN 算法参数,默认值为 2。 + + 返回: + - int: 预测的分类标签。 + """ + # 计算输入向量与训练集之间的欧氏距离 + distances = np.sum((input_vector - dataSet) ** 2, axis=1) + # 根据距离排序并获取索引 + sorted_indices = distances.argsort() + # 选择距离最近的k个点 + k_nearest_labels = labels[sorted_indices[:k]] + + # 统计k个点中各类别的数量 + count = Counter(k_nearest_labels) + # 返回数量最多的类别标签 + return count.most_common(1)[0][0] + +def load_dataset(directory): + """ + 加载数据集中的图像,并将其转换为特征向量和标签。 + + 参数: + - directory (str): 数据文件夹路径。 + + 返回: + - np.array: 特征数据(Mx1024)。 + - np.array: 标签数据(Mx1)。 + """ + # 初始化特征数据列表和标签列表 + feature_list = [] + label_list = [] + # 遍历目录中的所有文件 + for file in os.listdir(directory): + # 获取文件的完整路径 + file_path = os.path.join(directory, file) + # 将图像文件转换为向量 + feature_vector = img_to_vector(file_path) + # 将特征向量添加到列表中 + feature_list.append(feature_vector) + # 获取文件名中的标签并添加到标签列表中 + label_list.append(int(file.split('_')[0])) + # 将特征列表和标签列表转换为numpy数组 + feature_matrix = np.array(feature_list) + label_array = np.array(label_list) + # 特征缩放(如果需要) + feature_matrix = feature_matrix / 255.0 + return feature_matrix, label_array + +def img_to_vector(filename): + """ + 将二值图像转换为向量。 + + Args: + - filename (str): 图像文件路径。 + + Returns: + - np.array: 二值图像向量。 + """ + # 初始化向量 + vector = np.zeros((1024,)) # 创建一个一维数组 + # 打开文件并逐行读取 + with open(filename) as file: + for i, line in enumerate(file): + # 将每行的数字字符转换为整数并存储到向量中 + vector[i*32:i*32+32] = np.array([int(char) for char in line.strip()]) + return vector + +if __name__ == "__main__": + # 以下代码可用于测试,可自行随意修改 + train_data, train_labels = load_dataset("trainingDigits") + + test_data = ( + "00000000000000110000000000000000" + "00000000000011111000000000000000" + "00000000000011111100000000000000" + "00000000001111111110000000000000" + "00000000001111111110000000000000" + "00000000001111111100000000000000" + "00000000011111111000000000000000" + "00000000111111111000000000000000" + "00000000111111110000000000000000" + "00000000111111110000000000000000" + "00000000111111110000000000000000" + "00000000111111110000000000000000" + "00000000111111100000000000000000" + "00000001111111100000000000000000" + "00000001111111100000000000000000" + "00000001111111100000000000000000" + "00000001111111111111000000000000" + "00000001111111111111111000000000" + "00000001111111111111111100000000" + "00000011111111111111111110000000" + "00000011111111111111111110000000" + "00000001111111111111111110000000" + "00000001111111111111111110000000" + "00000000111111111100111111100000" + "00000000111111111000111111100000" + "00000000011111111001111111100000" + "00000000011111111111111111000000" + "00000000001111111111111111000000" + "00000000000111111111111111000000" + "00000000000011111111111100000000" + "00000000000001111111110000000000" + "00000000000000000111100000000000" + ) + predicted_label = classify( + np.array([int(char) for char in test_data]).reshape(1, 1024), + train_data, + train_labels, + ) + print(f"预测的标签: {predicted_label}") -