Files
Experiment-222/function.py
T
yuankun fae216a47a
Gitea Actions Experiment Test / Experiment-Actions (push) Successful in 12s
更新 function.py
2024-11-03 12:50:40 +08:00

144 lines
4.3 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 os
import numpy as np
"""
实验说明:
- 自行编写实现数据加载与预测病马死亡的对率回归算法。
注意事项:
- 在 function.py 中实现对率回归算法。
- 可以自行导入其他库,需要在 requirements.txt 添加依赖,若未在 requirements.txt 中添加使用到的依赖,则无法自动评测,成绩为零。
- 自动评测脚本仅会加载 train_logreg、predict_logreg 和 load_data 函数,请勿修改函数名。
测评环境:
- CPU: Intel Xeon(R) CPU E3-1231 v3 @ 3.40GHz
- OS: Ubuntu 22.04.4 LTS
- Python: 3.10.12
- numpy: 2.1.1
"""
"""
请在这里填写学号和姓名,不填写即成绩无效。
"""
id = "202210423120"
name = "袁焜"
# 这里写自己的代码实现
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
def sigmoid(z):
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):
m, n = X.shape
weights = np.random.randn(n) * np.sqrt(2. / n) # He初始化
best_weights = weights.copy()
best_accuracy = 0
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
# 计算训练集准确率
train_accuracy = accuracy(X, y, weights)
if train_accuracy > best_accuracy:
best_accuracy = train_accuracy
best_weights = weights.copy()
# 动态调整学习率
if _ % 100 == 0 and train_accuracy > 0.95: # 达到高准确率时减小学习率
learning_rate *= 0.9
return best_weights
def predict_logreg(X, weights):
z = np.dot(X, weights)
h = sigmoid(z)
return np.where(h >= 0.5, 1, 0)
def load_data(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]
# 特征选择:去掉特征3(索引2)和特征24~28(索引23~26),确保索引有效
indices_to_delete = [2] # 特征3
if num_features > 24: # 确保特征数量足够
indices_to_delete += list(range(24, 27)) # 特征24到27(索引23到26)
# 删除特征
data = np.delete(data, indices_to_delete, axis=1)
# 将标签二分类化,特征23(索引22)取值2和3合并为0,其余为1
target_variable = np.where((labels == 2) | (labels == 3), 0, 1)
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)
# 数据归一化
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.transform(X_val)
# 训练模型
final_weights = train_logreg(X_train, y_train, learning_rate=0.01, iterations=5000, 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}")