Files
Experiment-LogReg/function.py
T
dong 8b26b7173f
Gitea Actions Experiment Test / Experiment-Actions (push) Has been cancelled
更新 function.py
2024-11-02 16:27:16 +08:00

120 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import numpy as np
import os
# 学号和姓名
id = "202210423130"
name = "董秋"
def sigmoid(z):
"""计算sigmoid函数"""
return 1.0 / (1 + np.exp(-z))
def compute_gradient(X_batch, y_batch, weights, lambda_reg):
"""计算梯度,包含L2正则化"""
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):
"""对率回归训练函数。"""
m, n = X.shape
weights = np.random.randn(n) * np.sqrt(2. / n) # He初始化
for _ in range(iterations):
indices = np.random.permutation(m)
X_shuffled = X[indices]
y_shuffled = y[indices]
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)
weights -= learning_rate * gradient
return weights
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):
"""从文件中加载数据。"""
if not os.path.exists(filepath):
raise FileNotFoundError(f"文件 {filepath} 不存在!")
data, labels = [], []
with open(filepath, 'r') as f:
for line in f:
line = line.strip().split()
if len(line) >= 1 and line[-1].isdigit():
line_data = [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)
num_features = data.shape[1]
indices_to_remove = [2] # 去掉特征3(索引2)
if num_features > 23:
indices_to_remove.extend(range(23, min(28, num_features)))
data = np.delete(data, indices_to_remove, axis=1)
target_variable = np.where((labels == 2) | (labels == 3), 0, 1)
return data, target_variable
def k_fold_cross_validation(X, y, k=5, learning_rate=0.001, iterations=10000, batch_size=64, lambda_reg=0.1):
"""K折交叉验证。"""
m = X.shape[0]
fold_size = m // k
accuracies = []
for i in range(k):
val_start = i * fold_size
val_end = (i + 1) * fold_size if i != k - 1 else m
X_val = X[val_start:val_end]
y_val = y[val_start:val_end]
X_train = np.concatenate((X[:val_start], X[val_end:]))
y_train = np.concatenate((y[:val_start], y[val_end:]))
weights = train_logreg(X_train, y_train, learning_rate, iterations, batch_size, lambda_reg)
val_accuracy = np.mean([predict_logreg(X_val[j], weights) == y_val[j] for j in range(len(y_val))])
accuracies.append(val_accuracy)
print(f"Fold {i + 1}/{k} - 验证准确率: {val_accuracy:.4f}")
return np.mean(accuracies)
if __name__ == "__main__":
# 加载训练集
try:
X_train, y_train = load_data("./data/horse-colic.data")
except FileNotFoundError as e:
print(e)
exit()
# k折交叉验证
avg_accuracy = k_fold_cross_validation(X_train, y_train, k=5, learning_rate=0.01, iterations=1000)
print(f"K折交叉验证的平均准确率: {avg_accuracy:.4f}")
# 加载测试集
try:
X_test, y_test = load_data("./data/horse-colic.test")
except FileNotFoundError as e:
print(e)
exit()
# 训练对率回归模型
weights = train_logreg(X_train, y_train, learning_rate=0.01, iterations=1000)
# 测试单个数据
y_pred = predict_logreg(X_test[11], weights)
print(f"预测结果: {y_pred}, 实际结果: {y_test[11]}")