diff --git a/function.py b/function.py index bf6e2c2..b128aee 100644 --- a/function.py +++ b/function.py @@ -27,26 +27,21 @@ name = "章程鸿" # 这里写自己的代码实现 import numpy as np -from sklearn.preprocessing import MinMaxScaler -from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler def sigmoid(z): + """Sigmoid 激活函数。""" return 1.0 / (1 + np.exp(-z)) -def compute_gradient(X_batch, y_batch, weights, lambda_reg): - z = np.dot(X_batch, weights) - h = sigmoid(z) - gradient = np.dot(X_batch.T, (h - y_batch)) / len(y_batch) - gradient += (lambda_reg / len(y_batch)) * weights # L2正则化 - return gradient - -def train_logreg(X, y, learning_rate=0.001, iterations=10000, batch_size=64, lambda_reg=0.1): +def train_logreg(X, y, learning_rate=0.05, iterations=1500, batch_size=64, reg_lambda=0.01): + """训练逻辑回归模型的函数,使用梯度下降算法。""" m, n = X.shape - weights = np.random.randn(n) * np.sqrt(2. / n) # He初始化 + weights = np.random.randn(n) * 0.01 # 初始化权重 best_weights = weights.copy() best_accuracy = 0 + wait = 0 - for _ in range(iterations): + for i in range(iterations): indices = np.random.permutation(m) X_shuffled = X[indices] y_shuffled = y[indices] @@ -54,7 +49,10 @@ def train_logreg(X, y, learning_rate=0.001, iterations=10000, batch_size=64, lam for j in range(0, m, batch_size): X_batch = X_shuffled[j:j + batch_size] y_batch = y_shuffled[j:j + batch_size] - gradient = compute_gradient(X_batch, y_batch, weights, lambda_reg) + z = np.dot(X_batch, weights) + h = sigmoid(z) + gradient = np.dot(X_batch.T, (h - y_batch)) / len(y_batch) + reg_lambda * weights + weights -= learning_rate * gradient # 计算训练集准确率 @@ -62,20 +60,26 @@ def train_logreg(X, y, learning_rate=0.001, iterations=10000, batch_size=64, lam if train_accuracy > best_accuracy: best_accuracy = train_accuracy best_weights = weights.copy() + wait = 0 + else: + wait += 1 - # 动态调整学习率 - if _ % 100 == 0 and train_accuracy > 0.95: # 达到高准确率时减小学习率 - learning_rate *= 0.9 + # 如果准确率没有提高,提前停止 + if wait > 50: + break return best_weights def predict_logreg(X, weights): + """预测函数。""" z = np.dot(X, weights) h = sigmoid(z) - return np.where(h >= 0.5, 1, 0) + return np.where(h > 0.5, 1, 0) def load_data(filepath): - data, labels = [], [] + """加载数据函数。""" + data = [] + labels = [] with open(filepath, 'r') as f: for line in f: line = line.strip().split() @@ -86,41 +90,34 @@ def load_data(filepath): data = np.array(data) labels = np.array(labels) - # 将标签二分类化,2和3为0,其余为1 - target_variable = np.where((labels == 2) | (labels == 3), 0, 1) - + target_variable = np.where((labels == 2) | (labels == 3), 0, labels) + + n_features = data.shape[1] + columns_to_delete = [2] + list(range(23, min(28, n_features))) + data = np.delete(data, columns_to_delete, axis=1) + + scaler = StandardScaler() + data = scaler.fit_transform(data) + return data, target_variable def accuracy(X, y, weights): + """计算准确率。""" predictions = predict_logreg(X, weights) return np.mean(predictions == y) if __name__ == "__main__": - # 加载数据 - X, y = load_data("./data/horse-colic.data") - - # 拆分训练集和验证集 - X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42) + X_train, y_train = load_data("./horse-colic.data") + X_test, y_test = load_data("./horse-colic.test") - # 数据归一化 - scaler = MinMaxScaler() + # 特征标准化 + scaler = StandardScaler() X_train = scaler.fit_transform(X_train) - X_val = scaler.transform(X_val) - - # 训练模型 - final_weights = train_logreg(X_train, y_train, learning_rate=0.001, iterations=10000, batch_size=64, lambda_reg=0.1) - - # 验证模型 - val_accuracy = accuracy(X_val, y_val, final_weights) - print(f"验证集的准确率: {val_accuracy:.4f}") - - # 加载测试集 - X_test, y_test = load_data("./data/horse-colic.test") X_test = scaler.transform(X_test) - # 测试模型 - final_test_accuracy = accuracy(X_test, y_test, final_weights) - print(f"最终测试集的准确率: {final_test_accuracy:.4f}") - - + # 训练模型 + final_weights = train_logreg(X_train, y_train, learning_rate=0.001, iterations=1500, batch_size=64, reg_lambda=0.01) + # 计算测试集准确率 + final_accuracy = accuracy(X_test, y_test, final_weights) + print(f"最终测试集的准确率: {final_accuracy:.4f}")