diff --git a/function.py b/function.py index 16424fd..84aada3 100644 --- a/function.py +++ b/function.py @@ -1,7 +1,6 @@ # function.py import numpy as np from sklearn.preprocessing import StandardScaler -from sklearn.model_selection import train_test_split, KFold """ 实验说明: @@ -25,83 +24,76 @@ from sklearn.model_selection import train_test_split, KFold id = "202210423117" name = "程悦" -import numpy as np -from sklearn.preprocessing import StandardScaler -from sklearn.model_selection import train_test_split, KFold - -# 学号和姓名 -id = "202210423117" -name = "程悦" - def sigmoid(z): - """计算Sigmoid激活函数值""" - return 1 / (1 + np.exp(-z)) + return 1.0 / (1 + np.exp(-z)) -def train_logreg(X, y, learning_rate=0.1, iterations=2000, lambda_reg=0.01, batch_size=32): - """训练逻辑回归模型""" +def train_logreg(X, y, learning_rate=0.05, + iterations=1500, + batch_size=64, regularization='L2', lambda_reg=0.05): m, n = X.shape weights = np.random.randn(n) * 0.01 - - for _ in range(iterations): + for i in range(iterations): indices = np.random.permutation(m) - X_shuffled, y_shuffled = X[indices], y[indices] + X_shuffled = X[indices] + y_shuffled = y[indices] for j in range(0, m, batch_size): - X_batch, y_batch = X_shuffled[j:j + batch_size], y_shuffled[j:j + batch_size] + X_batch = X_shuffled[j:j + batch_size] + y_batch = y_shuffled[j:j + batch_size] z = np.dot(X_batch, weights) - predictions = sigmoid(z) - gradient = np.dot(X_batch.T, (predictions - y_batch)) / batch_size - gradient += (lambda_reg / m) * weights # L2正则化 + h = sigmoid(z) + gradient = np.dot(X_batch.T, (h - y_batch)) / X_batch.shape[0] + + # 添加正则化项 + if regularization == 'L1': + gradient += lambda_reg * np.sign(weights) / len(y_batch) + elif regularization == 'L2': + gradient += (lambda_reg / m) * weights + weights -= learning_rate * gradient - learning_rate *= 0.95 if _ % 100 == 0 else 1 # 动态调整学习率 + if i % 100 == 0: + learning_rate *= 0.95 return weights -def predict_logreg(X, weights): - """使用逻辑回归模型进行预测""" - return (sigmoid(np.dot(X, weights)) >= 0.5).astype(int) +def predict_logreg(inX, weights): + z = np.dot(inX, weights) + h = sigmoid(z) + return 1 if h > 0.5 else 0 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] - if values[22] in [1, 2, 3]: - labels.append(0 if values[22] in [2, 3] else 1) - data.append([0 if v == 0 else v for v in values[:2] + values[3:23]]) - except ValueError: - continue + for line in f.readlines(): + line = line.strip().split() + if len(line) >= 1 and line[-1].isdigit(): + line_data = [1] + [0 if x == '?' else float(x) for x in line[:-1]] + data.append(line_data) + labels.append(int(line[-1])) data = np.array(data) labels = np.array(labels) - return StandardScaler().fit_transform(data), labels + + target_variable = labels + target_variable[(target_variable == 2) | (target_variable == 3)] = 0 + + data = np.delete(data, [2] + list(range(23, 28)), axis=1) + + scaler = StandardScaler() + data = scaler.fit_transform(data) + + return data, target_variable def accuracy(X, y, weights): - """计算模型准确率""" - return np.mean(predict_logreg(X, weights) == y) + predictions = [predict_logreg(x, weights) for x in X] + return np.mean(predictions == y) if __name__ == "__main__": - X_train, y_train = load_data("./data/horse-colic.data") - X_test, y_test = load_data("./data/horse-colic.test") + X_train, y_train = load_data("./horse-colic.data") + X_test, y_test = load_data("./horse-colic.test") - kf = KFold(n_splits=5, shuffle=True, random_state=42) - accuracies = [accuracy(X_test_kf, y_test_kf, train_logreg(X_train_kf, y_train_kf, batch_size=32)) - for train_index, val_index in kf.split(X_train) - for X_train_kf, X_test_kf in [(X_train[train_index], X_train[test_index])] - for y_train_kf, y_test_kf in [(y_train[train_index], y_train[test_index])]] + final_weights = train_logreg(X_train, y_train, learning_rate=0.01, iterations=5000, batch_size=32, regularization='None', lambda_reg=0.01) - print(f"K折交叉验证得分: {accuracies}") - print(f"平均准确率: {np.mean(accuracies):.4f}") - - final_weights = train_logreg(X_train, y_train, batch_size=32) - test_accuracy = accuracy(X_test, y_test, final_weights) - print(f"测试集的准确率: {test_accuracy:.4f}") - - # 测试单个数据 - y_pred = predict_logreg(X_test[11], final_weights) - print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}") + final_accuracy = accuracy(X_test, y_test, final_weights) + print(f"最终测试集的准确率: {final_accuracy:.4f}")