From 8b948cdab4ec1ab036d80db391e93fcc56960c81 Mon Sep 17 00:00:00 2001 From: zhangchenghong <1598349064@qq.com> Date: Tue, 8 Oct 2024 22:57:11 +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 | 70 ++++++++++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/function.py b/function.py index b3b1f56..80c7f74 100644 --- a/function.py +++ b/function.py @@ -41,46 +41,33 @@ name = "章程鸿" # 这里写自己的代码实现 import numpy as np -from collections import Counter -from sklearn.model_selection import GridSearchCV from sklearn.neighbors import KNeighborsClassifier +from sklearn.model_selection import GridSearchCV -def classify0(inX, dataSet, labels, k=1): +def mahalanobis_distance(x, y, cov_inv): """ - KNN 分类算法。 - - Args: - - inX (numpy array): 输入待分类的样本。 - - dataSet (numpy array): 训练数据集。 - - labels (list or numpy array): 训练集对应的标签。 - - k (int): KNN 算法参数,默认为3。 - - Returns: - - int: 预测的分类标签。 - """ - # 计算马氏距离 - cov_matrix = np.cov(dataSet, rowvar=False) - inv_cov_matrix = np.linalg.inv(cov_matrix) - mean_vector = np.mean(dataSet, axis=0) - - diffMat = inX - dataSet - mahalanobis_distances = np.sqrt(np.sum((diffMat @ inv_cov_matrix) * diffMat, axis=1)) + 计算两个向量之间的马氏距离。 - # 排序并选取前k个最小距离 - sortedDistIndices = mahalanobis_distances.argsort() - classCount = {} - - for i in range(k): - voteIlabel = labels[sortedDistIndices[i]] - classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 - - # 返回出现频率最高的类别 - sortedClassCount = sorted(classCount.items(), key=lambda x: x[1], reverse=True) - return sortedClassCount[0][0] + Args: + - x (numpy array): 向量1。 + - y (numpy array): 向量2。 + - cov_inv (numpy array): 协方差矩阵的逆矩阵。 + + Returns: + - float: 马氏距离。 + """ + diff = x - y + return np.sqrt(np.dot(np.dot(diff, cov_inv), diff.T)) def load_data(file_path): """ 加载 TSV 格式数据文件。 + + Args: + - file_path (str): 数据文件路径。 + + Returns: + - tuple: 特征和标签。 """ data = np.loadtxt(file_path, delimiter="\t") features = data[:, :-1] @@ -90,21 +77,18 @@ def load_data(file_path): def normalize_min_max(data): """ 对数据进行最小-最大缩放归一化。 - + Args: - data (numpy array): 待归一化的数据。 - + Returns: - - numpy array: 归一化后的数据。 - - numpy array: 最小值。 - - numpy array: 最大值。 + - tuple: 归一化后的数据、最小值、最大值。 """ min_vals = data.min(0) max_vals = data.max(0) ranges = max_vals - min_vals # 避免除以零的情况 ranges[ranges == 0.0] = 1.0 - m = data.shape[0] norm_data = (data - min_vals) / ranges return norm_data, min_vals, max_vals @@ -118,8 +102,12 @@ if __name__ == "__main__": # 归一化训练数据,并获取最小值和最大值 train_data_normalized, min_vals, max_vals = normalize_min_max(train_data) - # 定义KNN分类器 - knn = KNeighborsClassifier() + # 计算协方差矩阵及其逆矩阵 + cov_matrix = np.cov(train_data_normalized, rowvar=False) + inv_cov_matrix = np.linalg.inv(cov_matrix) + + # 定义KNN分类器,使用自定义的马氏距离 + knn = KNeighborsClassifier(metric=lambda x, y: mahalanobis_distance(x, y, inv_cov_matrix)) # 定义要搜索的k值范围 param_grid = {'n_neighbors': list(range(1, 31))} @@ -133,7 +121,7 @@ if __name__ == "__main__": print("Optimal k:", optimal_k) # 使用最佳k值进行预测 - best_knn = KNeighborsClassifier(n_neighbors=optimal_k) + best_knn = KNeighborsClassifier(n_neighbors=optimal_k, metric=lambda x, y: mahalanobis_distance(x, y, inv_cov_matrix)) best_knn.fit(train_data_normalized, train_labels) # 测试数据点也需要用同样的方式归一化