generated from LufsX/Experiment-LogReg
This commit is contained in:
+44
-99
@@ -1,106 +1,51 @@
|
|||||||
import os
|
|
||||||
import csv
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
|
||||||
import torch.nn as nn
|
|
||||||
import torch.optim as optim
|
|
||||||
from sklearn.model_selection import train_test_split
|
|
||||||
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score, roc_auc_score
|
|
||||||
from sklearn.preprocessing import StandardScaler
|
|
||||||
from imblearn.over_sampling import SMOTE
|
|
||||||
|
|
||||||
# 姓名和学号
|
def load_data(filepath):
|
||||||
id = 202210423118
|
for delimiter in [',', ' ', '\t']:
|
||||||
name = 刘国庆
|
try:
|
||||||
|
data = np.genfromtxt(filepath, delimiter=delimiter, missing_values='?', filling_values=np.nan)
|
||||||
|
if data.ndim < 2 or data.shape[1] < 2:
|
||||||
|
continue
|
||||||
|
data = data[~np.isnan(data).any(axis=1)]
|
||||||
|
if data.size == 0:
|
||||||
|
print(f"Error: No valid data after removing NaN rows in file '{filepath}'.")
|
||||||
|
return None, None
|
||||||
|
X = data[:, :-1]
|
||||||
|
y = data[:, -1]
|
||||||
|
if X.shape[0] != y.shape[0]:
|
||||||
|
print(f"Error: Feature and label count mismatch in file '{filepath}'")
|
||||||
|
return None, None
|
||||||
|
print(f"Loaded data from '{filepath}': {X.shape[0]} samples, {X.shape[1]} features.")
|
||||||
|
return X, y
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading data with delimiter '{delimiter}': {e}")
|
||||||
|
print(f"Error: File '{filepath}' may be empty or improperly formatted.")
|
||||||
|
return None, None
|
||||||
|
|
||||||
# 读取 CSV 数据的函数
|
def sigmoid(z):
|
||||||
def load_data(file_path):
|
return 1 / (1 + np.exp(-z))
|
||||||
if not os.path.exists(file_path):
|
|
||||||
raise FileNotFoundError(f"文件未找到: {file_path}")
|
|
||||||
|
|
||||||
features = []
|
|
||||||
labels = []
|
|
||||||
with open(file_path, 'r') as csvfile:
|
|
||||||
reader = csv.reader(csvfile)
|
|
||||||
next(reader) # 跳过标题行
|
|
||||||
for row in reader:
|
|
||||||
features.append([float(x) for x in row[:-1]]) # 假设最后一列为标签
|
|
||||||
labels.append(int(row[-1]))
|
|
||||||
return np.array(features), np.array(labels)
|
|
||||||
|
|
||||||
# 评估模型的函数
|
def train_logreg(X, y, learning_rate=0.01, epochs=1000):
|
||||||
def evaluate_model(y_true, y_pred, y_prob=None):
|
X = np.c_[np.ones(X.shape[0]), X]
|
||||||
print("Confusion Matrix:")
|
weights = np.zeros(X.shape[1])
|
||||||
print(confusion_matrix(y_true, y_pred))
|
for epoch in range(epochs):
|
||||||
print("\nClassification Report:")
|
z = np.dot(X, weights)
|
||||||
print(classification_report(y_true, y_pred))
|
predictions = sigmoid(z)
|
||||||
print(f"Accuracy: {accuracy_score(y_true, y_pred):.4f}")
|
gradient = np.dot(X.T, (predictions - y)) / y.size
|
||||||
|
weights -= learning_rate * gradient
|
||||||
if y_prob is not None:
|
return weights
|
||||||
auc = roc_auc_score(y_true, y_prob)
|
|
||||||
print(f"AUC Score: {auc:.4f}")
|
|
||||||
|
|
||||||
# 定义模型类
|
def predict_logreg(X, weights):
|
||||||
class LogisticRegressionModel(nn.Module):
|
X = np.c_[np.ones(X.shape[0]), X]
|
||||||
def __init__(self, input_size):
|
probabilities = sigmoid(np.dot(X, weights))
|
||||||
super(LogisticRegressionModel, self).__init__()
|
return (probabilities >= 0.5).astype(int)
|
||||||
self.fc = nn.Linear(input_size, 1)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
return torch.sigmoid(self.fc(x))
|
|
||||||
|
|
||||||
# 主函数
|
# Load data and train model
|
||||||
def main():
|
data_file_path = 'path_to_your_data/horse-colic.data' # Update with your actual path
|
||||||
# 加载数据
|
X, y = load_data(data_file_path)
|
||||||
file_path = 'data.csv' # 修改为你的 CSV 文件路径
|
if X is not None and y is not None:
|
||||||
X, y = load_data(file_path)
|
weights = train_logreg(X, y)
|
||||||
|
predictions = predict_logreg(X, weights)
|
||||||
# 拆分数据集
|
print("Weights:", weights)
|
||||||
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
print("Predictions:", predictions)
|
||||||
|
|
||||||
# 处理不平衡数据
|
|
||||||
smote = SMOTE(random_state=42)
|
|
||||||
X_train_res, y_train_res = smote.fit_resample(X_train, y_train)
|
|
||||||
|
|
||||||
# 标准化数据
|
|
||||||
scaler = StandardScaler()
|
|
||||||
X_train_res = scaler.fit_transform(X_train_res)
|
|
||||||
X_test = scaler.transform(X_test)
|
|
||||||
|
|
||||||
# 转换为 PyTorch 张量
|
|
||||||
X_train_res = torch.tensor(X_train_res, dtype=torch.float32)
|
|
||||||
y_train_res = torch.tensor(y_train_res, dtype=torch.float32).view(-1, 1)
|
|
||||||
X_test = torch.tensor(X_test, dtype=torch.float32)
|
|
||||||
y_test = torch.tensor(y_test, dtype=torch.float32).view(-1, 1)
|
|
||||||
|
|
||||||
# 创建模型
|
|
||||||
model = LogisticRegressionModel(input_size=X_train_res.shape[1])
|
|
||||||
|
|
||||||
# 定义损失函数和优化器
|
|
||||||
criterion = nn.BCELoss()
|
|
||||||
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
|
||||||
|
|
||||||
# 训练模型
|
|
||||||
model.train()
|
|
||||||
for epoch in range(100):
|
|
||||||
optimizer.zero_grad() # 清空梯度
|
|
||||||
outputs = model(X_train_res) # 前向传播
|
|
||||||
loss = criterion(outputs, y_train_res) # 计算损失
|
|
||||||
loss.backward() # 反向传播
|
|
||||||
optimizer.step() # 更新权重
|
|
||||||
|
|
||||||
if (epoch + 1) % 10 == 0:
|
|
||||||
print(f'Epoch [{epoch + 1}/100], Loss: {loss.item():.4f}')
|
|
||||||
|
|
||||||
# 评估模型
|
|
||||||
model.eval()
|
|
||||||
with torch.no_grad():
|
|
||||||
y_pred_prob = model(X_test).numpy().flatten() # 获取预测概率
|
|
||||||
y_pred = (y_pred_prob > 0.5).astype(int)
|
|
||||||
|
|
||||||
# 评估模型
|
|
||||||
evaluate_model(y_test.numpy(), y_pred, y_pred_prob)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user