From 95763dc72abf4c2a016fbc987d2d966cada634c0 Mon Sep 17 00:00:00 2001 From: Xionghaoran <719929980@qq.com> Date: Thu, 31 Oct 2024 17:26:56 +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 | 141 ++++++++++++++++++---------------------------------- 1 file changed, 48 insertions(+), 93 deletions(-) diff --git a/function.py b/function.py index 87d09b9..78d7c58 100644 --- a/function.py +++ b/function.py @@ -1,104 +1,59 @@ import numpy as np -import pandas as pd from sklearn.impute import SimpleImputer from sklearn.feature_selection import SelectKBest, f_classif # 填写学号和姓名 id = "202210423213" -name = " 熊浩燃" +name = "熊浩燃" -def load_data(filepath): +def load_data(filepath, k_features=20): """ - 从文件中加载数据,填充缺失值,并进行特征处理。 + 从文件中加载数据并进行预处理,包括缺失值填充和特征选择。 + + Args: + - filepath (str): 数据文件路径。 + - k_features (int): 选择的特征数量。 + + Returns: + - np.array: 特征数据。 + - np.array: 标签数据。 """ - # 使用pandas读取数据,处理缺失值 - df = pd.read_csv(filepath, delim_whitespace=True, header=None) - # 将问号替换为NaN,并填充为0 - df.replace('?', 0, inplace=True) - df = df.astype(float) # 转换为浮点数类型 - # 将最后一列设置为标签 - labels = df.iloc[:, -1].values.astype(int) - labels[(labels == 2) | (labels == 3)] = 0 # 合并死亡和安乐死为0 - # data = df.drop(columns=[2] + list(range(23, 28))).values # 删除不相关特征 - # 数据标准化 - scaler = StandardScaler() - data = scaler.fit_transform(data) + data = [] + labels = [] + with open(filepath, 'r') as file: + for line in file: + line = line.strip().split() + if line: + features = [] + for i, feature in enumerate(line[:-1]): # 最后一个元素是标签 + if i in [2, 23, 24, 25, 26, 27]: # 跳过特征3和24-28 + continue + try: + features.append(float(feature)) + except ValueError: + features.append(np.nan) # 用 NaN 表示缺失值 + label = int(line[-1]) + data.append(features) + labels.append(label) + + # 转换为 numpy 数组 + data = np.array(data) + labels = np.array(labels) + + # 使用SimpleImputer填充NaN + imputer = SimpleImputer(strategy='mean') + data = imputer.fit_transform(data) + + # 特征标准化,避免除零错误 + mean = data.mean(axis=0) + std_dev = data.std(axis=0) + std_dev[std_dev == 0] = 1 # 如果标准差为0,将其设为1,避免除以零 + data = (data - mean) / std_dev + + # 特征选择 + selector = SelectKBest(f_classif, k=k_features) + data = selector.fit_transform(data, labels) + return data, labels -def sigmoid(z): - """ - Sigmoid激活函数,用于对率回归模型。 - - Args: - - z (numpy array): 输入数据。 - - Returns: - - numpy array: Sigmoid函数输出值。 - """ - return 1 / (1 + np.exp(-z)) - -def train_logreg(X, y, initial_lr=0.005, iterations=5000, regularization=0.01, decay=0.0001): - """ - 对率回归训练函数,包含学习率衰减策略。 - - Args: - - X (numpy array): 特征数据。 - - y (numpy array): 标签数据。 - - initial_lr (float): 初始学习率。 - - iterations (int): 迭代次数。 - - regularization (float): 正则化强度。 - - decay (float): 学习率衰减系数。 - - Returns: - - numpy array: 训练得到的权重。 - """ - m, n = X.shape - weights = np.zeros(n) - learning_rate = initial_lr - - for i in range(iterations): - z = np.dot(X, weights) - predictions = sigmoid(z) - errors = y - predictions - gradient = np.dot(X.T, errors) / m - regularization * weights / m - weights += learning_rate * gradient - - # 学习率衰减 - learning_rate = initial_lr / (1 + decay * i) - - return weights - -def predict_logreg(inX, weights, threshold=0.5): - """ - 对率回归预测函数,包含可调阈值。 - - Args: - - inX (numpy array): 输入待分类的样本。 - - weights (numpy array): 训练得到的权重。 - - threshold (float): 判定阈值,默认为0.5。 - - Returns: - - int: 预测的分类标签。 - """ - probability = sigmoid(np.dot(inX, weights)) - return 1 if probability >= threshold else 2 - -# 测试代码 -if __name__ == "__main__": - # 加载数据并选择前20个最重要的特征 - X_train, y_train = load_data("./data/horse-colic.data", k_features=20) - X_test, y_test = load_data("./data/horse-colic.test", k_features=20) - - # 训练模型 - weights = train_logreg(X_train, y_train, initial_lr=0.005, iterations=5000, regularization=0.01, decay=0.0001) - - # 模型评估 - correct_predictions = 0 - for i in range(len(X_test)): - y_pred = predict_logreg(X_test[i], weights, threshold=0.5) - if y_pred == y_test[i]: - correct_predictions += 1 - print(f"预测结果: {y_pred}, 实际结果: {y_test[i]}") - - accuracy = correct_predictions / len(X_test) - print(f"测试集准确率: {accuracy:.2f}") \ No newline at end of file +# 其余代码保持不变