From 7d09d02642e737e4d3d0f45badbb3b75aead849f Mon Sep 17 00:00:00 2001 From: dong <2938690875@qq.com> Date: Sat, 2 Nov 2024 12:50:35 +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 | 105 ++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 64 deletions(-) diff --git a/function.py b/function.py index 1c27c90..bcd504d 100644 --- a/function.py +++ b/function.py @@ -1,125 +1,102 @@ import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler -from sklearn.model_selection import train_test_split +from sklearn.model_selection import train_test_split, KFold +from sklearn.metrics import accuracy_score id = "202210423130" name = "董秋" - def sigmoid(z): - """ - Sigmoid 激活函数。 - """ return 1 / (1 + np.exp(-z)) def train_logreg(X, y, learning_rate=0.01, iterations=1000, lambda_reg=0.01): - """ - 逻辑回归训练函数,随机初始化权重,并在每次迭代前打乱数据。 - """ m, n = X.shape - weights = np.random.randn(n) * 0.01 # 随机初始化权重,取较小值 - + weights = np.random.randn(n) * 0.01 for i in range(iterations): - # 每次迭代打乱数据 indices = np.random.permutation(m) X = X[indices] y = y[indices] - z = np.dot(X, weights) predictions = sigmoid(z) gradient = np.dot(X.T, (predictions - y)) / m - - # L2正则化 gradient += (lambda_reg / m) * weights - - # 更新权重 weights -= learning_rate * gradient - - # 动态调整学习率,逐渐减小 learning_rate *= 0.99 - return weights - def predict_logreg(inX, weights): - """ - 逻辑回归预测函数。 - Args: - - inX (numpy array): 输入待分类的样本。 - - weights (numpy array): 训练得到的权重。 - Returns: - - int: 预测的分类标签。 - """ z = np.dot(inX, weights) prediction_prob = sigmoid(z) return 1 if prediction_prob >= 0.5 else 0 def handle_outliers(df, threshold=3): - """ - 使用 Z 分数法检测并处理异常值(噪音)。 - 任何 Z 分数大于指定阈值的数值会被替换为列的均值。 - """ z_scores = np.abs((df - df.mean()) / df.std()) - df[z_scores > threshold] = np.nan # 标记异常值为 NaN - df.fillna(df.mean(), inplace=True) # 均值填充 + df[z_scores > threshold] = np.nan + df.fillna(df.mean(), inplace=True) return df - def load_data(filepath): data = [] labels = [] - with open(filepath, 'r') as f: for line in f: values = line.strip().replace('?', '0').split() try: values = [float(v) for v in values] - - # 合并特征23的取值 - if values[22] == 2 or values[22] == 3: # 特征23(索引22) - labels.append(0) # 死亡 + if values[22] == 2 or values[22] == 3: + labels.append(0) elif values[22] == 1: - labels.append(1) # 生存 + labels.append(1) else: - continue # 无效标签,丢弃 - - # 用0填充缺失值 - values = [np.nan if v == 0 else v for v in values] # 先标记为NaN - data.append(values[:2] + values[3:23]) # 保留特征1, 2 和特征4-23 + continue + values = [np.nan if v == 0 else v for v in values] + data.append(values[:2] + values[3:23]) except ValueError: continue - data = np.array(data) labels = np.array(labels) - - # 转换成 DataFrame 以便进一步处理 df = pd.DataFrame(data) - - # 使用均值填充缺失值 - df.fillna(df.mean(), inplace=True) # 初步均值填充 - - # 处理噪音数据 - df = handle_outliers(df) # 检测并处理异常值 - + df.fillna(df.mean(), inplace=True) + df = handle_outliers(df) return df.to_numpy(), labels def preprocess_data(X): - # 特征标准化 scaler = StandardScaler() return scaler.fit_transform(X) +def cross_validate_learning_rate(X, y, learning_rates, k=5, iterations=1000, lambda_reg=0.01): + best_lr = None + best_score = 0 + kf = KFold(n_splits=k, shuffle=True, random_state=42) + + for lr in learning_rates: + cv_scores = [] + for train_index, val_index in kf.split(X): + X_train, X_val = X[train_index], X[val_index] + y_train, y_val = y[train_index], y[val_index] + weights = train_logreg(X_train, y_train, learning_rate=lr, iterations=iterations, lambda_reg=lambda_reg) + y_pred = [predict_logreg(x, weights) for x in X_val] + cv_scores.append(accuracy_score(y_val, y_pred)) + + avg_score = np.mean(cv_scores) + print(f"Learning Rate: {lr}, Cross-Validation Accuracy: {avg_score:.4f}") + + if avg_score > best_score: + best_score = avg_score + best_lr = lr + + print(f"Best Learning Rate: {best_lr}, Best CV Accuracy: {best_score:.4f}") + return best_lr + if __name__ == "__main__": - # 加载数据集 X, y = load_data("./data/horse-colic.data") X = preprocess_data(X) - # 使用 train_test_split 打乱并随机抽取数据 + learning_rates = [0.001, 0.01, 0.05, 0.1, 0.2] + best_learning_rate = cross_validate_learning_rate(X, y, learning_rates) + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - - # 训练逻辑回归模型 - weights = train_logreg(X_train, y_train, learning_rate=0.1, iterations=1000, lambda_reg=0.01) - - # 测试单个数据 + weights = train_logreg(X_train, y_train, learning_rate=best_learning_rate, iterations=1000, lambda_reg=0.01) y_pred = predict_logreg(X_test[11], weights) print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}")