diff --git a/function.py b/function.py index be01a25..f663efa 100644 --- a/function.py +++ b/function.py @@ -1,106 +1,51 @@ -import os -import csv 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 -# 姓名和学号 - id = 202210423118 - name = 刘国庆 +def load_data(filepath): + for delimiter in [',', ' ', '\t']: + 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 load_data(file_path): - 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 sigmoid(z): + return 1 / (1 + np.exp(-z)) -# 评估模型的函数 -def evaluate_model(y_true, y_pred, y_prob=None): - print("Confusion Matrix:") - print(confusion_matrix(y_true, y_pred)) - print("\nClassification Report:") - print(classification_report(y_true, y_pred)) - print(f"Accuracy: {accuracy_score(y_true, y_pred):.4f}") - - if y_prob is not None: - auc = roc_auc_score(y_true, y_prob) - print(f"AUC Score: {auc:.4f}") +def train_logreg(X, y, learning_rate=0.01, epochs=1000): + X = np.c_[np.ones(X.shape[0]), X] + weights = np.zeros(X.shape[1]) + for epoch in range(epochs): + z = np.dot(X, weights) + predictions = sigmoid(z) + gradient = np.dot(X.T, (predictions - y)) / y.size + weights -= learning_rate * gradient + return weights -# 定义模型类 -class LogisticRegressionModel(nn.Module): - def __init__(self, input_size): - super(LogisticRegressionModel, self).__init__() - self.fc = nn.Linear(input_size, 1) - - def forward(self, x): - return torch.sigmoid(self.fc(x)) +def predict_logreg(X, weights): + X = np.c_[np.ones(X.shape[0]), X] + probabilities = sigmoid(np.dot(X, weights)) + return (probabilities >= 0.5).astype(int) -# 主函数 -def main(): - # 加载数据 - file_path = 'data.csv' # 修改为你的 CSV 文件路径 - X, y = load_data(file_path) - - # 拆分数据集 - X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) - - # 处理不平衡数据 - 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() +# Load data and train model +data_file_path = 'path_to_your_data/horse-colic.data' # Update with your actual path +X, y = load_data(data_file_path) +if X is not None and y is not None: + weights = train_logreg(X, y) + predictions = predict_logreg(X, weights) + print("Weights:", weights) + print("Predictions:", predictions)