diff --git a/function.py b/function.py index 80c7f74..8696acf 100644 --- a/function.py +++ b/function.py @@ -40,94 +40,68 @@ name = "章程鸿" # 这里写自己的代码实现 -import numpy as np -from sklearn.neighbors import KNeighborsClassifier -from sklearn.model_selection import GridSearchCV - -def mahalanobis_distance(x, y, cov_inv): - """ - 计算两个向量之间的马氏距离。 - - 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] - labels = data[:, -1].astype(int) - return features, labels - -def normalize_min_max(data): - """ - 对数据进行最小-最大缩放归一化。 - - Args: - - data (numpy array): 待归一化的数据。 - - Returns: - - tuple: 归一化后的数据、最小值、最大值。 - """ - min_vals = data.min(0) - max_vals = data.max(0) - ranges = max_vals - min_vals - # 避免除以零的情况 - ranges[ranges == 0.0] = 1.0 - norm_data = (data - min_vals) / ranges - return norm_data, min_vals, max_vals - -if __name__ == "__main__": - # 以下代码可用于测试,可自行随意修改 - train_file = "datingTrainSet2.tsv" - - # 加载训练数据 - train_data, train_labels = load_data(train_file) - - # 归一化训练数据,并获取最小值和最大值 - train_data_normalized, min_vals, max_vals = normalize_min_max(train_data) - - # 计算协方差矩阵及其逆矩阵 - 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))} - - # 使用GridSearchCV进行网格搜索 - grid_search = GridSearchCV(knn, param_grid, cv=10, scoring='accuracy') - grid_search.fit(train_data_normalized, train_labels) - - # 获取最佳的k值 - optimal_k = grid_search.best_params_['n_neighbors'] - print("Optimal k:", optimal_k) - - # 使用最佳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) - - # 测试数据点也需要用同样的方式归一化 - test_point = np.array([65915, 3.868359, 0.128078]) - test_point_normalized = (test_point - min_vals) / (max_vals - min_vals) - - # 使用归一化后的数据进行预测 - predicted_label = best_knn.predict([test_point_normalized]) +import numpy as np +from sklearn.model_selection import GridSearchCV +from sklearn.neighbors import KNeighborsClassifier + +def load_data(file_path): + """ + 加载 TSV 格式数据文件。 + """ + data = np.loadtxt(file_path, delimiter="\t") + features = data[:, :-1] + labels = data[:, -1].astype(int) + return features, labels + +def normalize_min_max(data): + """ + 对数据进行最小-最大缩放归一化。 + + Args: + - data (numpy array): 待归一化的数据。 + + Returns: + - numpy array: 归一化后的数据。 + - numpy array: 最小值。 + - numpy array: 最大值。 + """ + min_vals = data.min(0) + max_vals = data.max(0) + ranges = max_vals - min_vals + ranges[ranges == 0.0] = 1.0 # 避免除以零 + norm_data = (data - min_vals) / ranges + return norm_data, min_vals, max_vals + +if __name__ == "__main__": + train_file = "datingTrainSet2.tsv" + test_file = "datingTestSet2.tsv" # 假设您有一个测试集文件 + + # 加载训练和测试数据 + train_data, train_labels = load_data(train_file) + test_data, test_labels = load_data(test_file) + + # 归一化训练和测试数据 + train_data_normalized, min_vals, max_vals = normalize_min_max(train_data) + test_data_normalized = (test_data - min_vals) / (max_vals - min_vals) + + # 定义KNN分类器 + knn = KNeighborsClassifier() + + # 定义要搜索的k值范围 + param_grid = {'n_neighbors': list(range(1, 31))} + + # 使用GridSearchCV进行网格搜索 + grid_search = GridSearchCV(knn, param_grid, cv=10, scoring='accuracy') + grid_search.fit(train_data_normalized, train_labels) + + # 获取最佳的k值 + optimal_k = grid_search.best_params_['n_neighbors'] + print("Optimal k:", optimal_k) + + # 使用最佳k值进行预测 + best_knn = KNeighborsClassifier(n_neighbors=optimal_k) + best_knn.fit(train_data_normalized, train_labels) + + # 对测试数据进行预测 + predicted_labels = best_knn.predict(test_data_normalized) print("预测的分类标签是:", predicted_label[0]) \ No newline at end of file