From 9c7a560fbd3ed41d95cae784def69c660adac1d9 Mon Sep 17 00:00:00 2001 From: wangchunlin Date: Sun, 23 Jul 2023 03:50:22 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E7=BB=99=E5=B9=BA?= =?UTF-8?q?=E7=88=B8=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Psychological_Classification_4Classes.pth | Bin 0 -> 39159 bytes detect.py | 2 +- detect_num.py | 126 ++++++++++++++++++ record.txt | 24 +++- train_gpu_blance.py | 155 ++++++++++++++++++++++ 5 files changed, 303 insertions(+), 4 deletions(-) create mode 100644 Psychological_Classification_4Classes.pth create mode 100644 detect_num.py create mode 100644 train_gpu_blance.py diff --git a/Psychological_Classification_4Classes.pth b/Psychological_Classification_4Classes.pth new file mode 100644 index 0000000000000000000000000000000000000000..857abcbb23da12e41d50d21af9fe8d839cea0774 GIT binary patch literal 39159 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 Hzsvp$+;jSh literal 0 HcmV?d00001 diff --git a/detect.py b/detect.py index 678be40..f86bb60 100644 --- a/detect.py +++ b/detect.py @@ -40,7 +40,7 @@ class MLP(nn.Module): # 加载模型 model = MLP().to(device) -model.load_state_dict(torch.load('model_5.pth')) +model.load_state_dict(torch.load('Psychological_Classification_4Classes.pth')) model.eval() # 创建数据加载器 diff --git a/detect_num.py b/detect_num.py new file mode 100644 index 0000000..7fa49d1 --- /dev/null +++ b/detect_num.py @@ -0,0 +1,126 @@ +""" +文件名: detect_num.py + +推理部分代码 + +作者: 王春林 +创建日期: 2023年7月14日 +最后修改日期: 2023年7月18日 +版本号: 1.0.0 + +""" +import pandas as pd +import numpy as np +from sklearn.preprocessing import MinMaxScaler +import torch +from torch import nn +from torch.utils.data import DataLoader, TensorDataset + +# 检查GPU是否可用 +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") +#device = torch.device("cpu") + +# 读取特征和标签 +data = pd.read_excel('feature_label.xlsx') + +# 获取编号列 +sample_ids = data['编号'].values + +# 以下是你的特征名 +feature_names = ["躯体化", "强迫症状", "人际关系敏感", "抑郁", "焦虑", "敌对", "恐怖", "偏执", "精神病性", "其他", "父亲教养方式数字化", "母亲教养方式数字化", "自评家庭经济条件数字化", "有无心理治疗(咨询)史数字化", "出勤情况数字化", "学业情况数字化", "权重数字化值"] + +# 将特征和标签分开,并做归一化处理 +X = data[feature_names].values +y = data['label'].values - 1 # 将标签从1-4转换为0-3 + +scaler = MinMaxScaler() +X = scaler.fit_transform(X) + +# 定义 MLP 网络 +class MLP(nn.Module): + def __init__(self): + super(MLP, self).__init__() + self.model = nn.Sequential( + nn.Linear(17, 32), # 输入层 + nn.ReLU(), # 激活函数 + nn.Linear(32, 128), # 隐藏层 + nn.ReLU(), # 激活函数 + nn.Linear(128, 32), # 隐藏层 + nn.ReLU(), # 激活函数 + nn.Linear(32, 4), # 输出层,4个类别 + ) + + def forward(self, x): + return self.model(x) + +# 加载模型 +model = MLP().to(device) +model.load_state_dict(torch.load('Psychological_Classification_4Classes.pth')) +model.eval() + +# 创建数据加载器 +dataset = TensorDataset(torch.from_numpy(X).float().to(device), torch.from_numpy(y).long().to(device)) +loader = DataLoader(dataset, batch_size=32) + +# 推理 +corrects = 0 +sample_index = 0 +for inputs, targets in loader: + outputs = model(inputs) + _, preds = torch.max(outputs, 1) + corrects += torch.sum(preds == targets.data) + + # 打印每个样本的推理结果 + for i in range(len(inputs)): + print(f'Sample ID: {sample_ids[sample_index]} | Target: {targets[i]} | Prediction: {preds[i]} (-1 in excel)') + sample_index += 1 + +# 计算整体推理的正确率 +accuracy = corrects.double().cpu() / len(loader.dataset) +print(f'Overall Accuracy: {accuracy:.4f}') + +# ...(之前的代码) + +# 创建文件来存储预测结果为0和1的学号 +file_1st_warning = open("一级预警.txt", "w", encoding="utf-8") +file_2nd_warning = open("二级预警.txt", "w", encoding="utf-8") + +# 初始化每个类别的计数器 +class_counts = {0: 0, 1: 0, 2: 0, 3: 0} +class_corrects = {0: 0, 1: 0, 2: 0, 3: 0} + +# 进行推理 +corrects = 0 +sample_index = 0 +for inputs, targets in loader: + outputs = model(inputs) + _, preds = torch.max(outputs, 1) + corrects += torch.sum(preds == targets.data) + + # 记录预测结果为0和1的学号 + for i in range(len(inputs)): + if preds[i] == 0: + file_1st_warning.write(f"{sample_ids[sample_index]}\n") + elif preds[i] == 1: + file_2nd_warning.write(f"{sample_ids[sample_index]}\n") + sample_index += 1 + + # 更新每个类别的计数器和正确计数器 + for i in range(len(targets)): + class_counts[targets[i].item()] += 1 + if preds[i] == targets[i]: + class_corrects[targets[i].item()] += 1 + +# 关闭文件 +file_1st_warning.close() +file_2nd_warning.close() + +# 计算整体准确率 +accuracy = corrects.double().cpu() / len(loader.dataset) +print(f'整体准确率: {accuracy:.4f}') + +# 打印每个类别的信息 +for class_idx in range(4): + class_accuracy = class_corrects[class_idx] / class_counts[class_idx] + print(f'类别 {class_idx + 1} | 预测数量: {class_counts[class_idx]} | 准确率: {class_accuracy:.4f}') + diff --git a/record.txt b/record.txt index 28e7b7f..244ff28 100644 --- a/record.txt +++ b/record.txt @@ -23,14 +23,32 @@ 完成学业预警统计统计,去除错误数据,一个错误 姓名重合:扎西尼玛, 扎西尼马 -2023年7月8日 +2023年7月3日 完成特征值缩放和选择工作(选择17个特征,包括幺爸给的加权值,相关性不管,没想到好方法),完成数据清洗,和缺失值处理前面已经完成 -2023年7月12日 +2023年7月4日 最后筛选出需要的特征 -2023年7月13日 +2023年7月7日 按照特征数字量化表的要求,完成了除学业和考勤外所有特征的量化,在Feature_Processed_2.py这个文件中处理,进一步统计特征,学业和出勤特征没有进一步统计进去 +2023年7月8日 +平均请假次数有一点歧义,不知道是统计26111个的,还是表里面的15342,我按全部来,没有记录的默认0次 + +2023年7月9日 +完成所有特征选择和数字化操作,Feature_Process_5.py文件可以把数字化全部做完,待检查其他特征是否集中完全,需要研究下特征的归一化怎么来做。初步选用17个特征来做 + +2023年7月11日 +删除信息严重不全的23人,总样本数26088(26111) + +2023年7月13日 +完成训练 + +2023年7月14日 +完成推理部分 + +2023年7月16日 +增加样本平衡机制,使用GPU训练,优化代码结构,增加必要打印输出信息 + diff --git a/train_gpu_blance.py b/train_gpu_blance.py new file mode 100644 index 0000000..81efea9 --- /dev/null +++ b/train_gpu_blance.py @@ -0,0 +1,155 @@ +""" +文件名: detect_num.py + +训练部分代码 + +作者: 王春林 +创建日期: 2023年7月13日 +最后修改日期: 2023年7月18日 +版本号: 1.0.0 + +""" +import pandas as pd +import numpy as np +from sklearn.preprocessing import MinMaxScaler +from sklearn.model_selection import StratifiedKFold +import torch +from torch import nn +from torch.utils.data import DataLoader, TensorDataset +import matplotlib.pyplot as plt + +# 检查GPU是否可用 +device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + +# 读取特征和标签 +data = pd.read_excel('feature_label.xlsx') + +# 以下是你的特征名 +feature_names = ["躯体化", "强迫症状", "人际关系敏感", "抑郁", "焦虑", "敌对", "恐怖", "偏执", "精神病性", "其他", "父亲教养方式数字化", "母亲教养方式数字化", "自评家庭经济条件数字化", "有无心理治疗(咨询)史数字化", "出勤情况数字化", "学业情况数字化", "权重数字化值"] + +# 将特征和标签分开,并做归一化处理 +X = data[feature_names].values +y = data['label'].values - 1 # 将标签从1-4转换为0-3 + +scaler = MinMaxScaler() +X = scaler.fit_transform(X) + +# 定义 MLP 网络 +class MLP(nn.Module): + def __init__(self): + super(MLP, self).__init__() + self.model = nn.Sequential( + nn.Linear(17, 32), # 输入层 + nn.ReLU(), # 激活函数 + nn.Linear(32, 128), # 隐藏层 + nn.ReLU(), # 激活函数 + nn.Linear(128, 32), # 隐藏层 + nn.ReLU(), # 激活函数 + nn.Linear(32, 4), # 输出层,4个类别 + ) + + def forward(self, x): + return self.model(x) + +# 使用5折交叉验证 +skf = StratifiedKFold(n_splits=5, shuffle=True) + +# 用于存储所有折的损失和准确率 +all_train_losses, all_val_losses, all_train_accs, all_val_accs = [], [], [], [] + +for fold, (train_index, test_index) in enumerate(skf.split(X, y)): + X_train, X_val = X[train_index], X[test_index] + y_train, y_val = y[train_index], y[test_index] + + train_dataset = TensorDataset(torch.from_numpy(X_train).float().to(device), torch.from_numpy(y_train).long().to(device)) + val_dataset = TensorDataset(torch.from_numpy(X_val).float().to(device), torch.from_numpy(y_val).long().to(device)) + + train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) + val_loader = DataLoader(val_dataset, batch_size=32) + + model = MLP().to(device) + criterion = nn.CrossEntropyLoss() + optimizer = torch.optim.Adam(model.parameters()) + + n_epochs = 120 # 增加到150个epoch + train_losses, val_losses, train_accs, val_accs = [], [], [], [] + + # 增加样本平衡机制 + class_sample_counts = np.bincount(y_train) + class_weights = 1.0 / torch.tensor(class_sample_counts, dtype=torch.float32) + class_weights = class_weights.to(device) + + # 存储每一折的模型和对应的验证准确率 + best_val_acc = 0.0 + best_model = None + + for epoch in range(n_epochs): + model.train() + running_loss, corrects = 0, 0 + for inputs, targets in train_loader: + optimizer.zero_grad() + outputs = model(inputs) + loss = criterion(outputs, targets) + # 使用样本平衡机制 + loss = loss * class_weights[targets] + loss = loss.mean() + loss.backward() + optimizer.step() + running_loss += loss.item() * inputs.size(0) + _, preds = torch.max(outputs, 1) + corrects += torch.sum(preds == targets.data) + + epoch_loss = running_loss / len(train_loader.dataset) + epoch_acc = corrects.double().cpu() / len(train_loader.dataset) + train_losses.append(epoch_loss) + train_accs.append(epoch_acc) + + print(f'Fold {fold+1}, Epoch {epoch+1} | Train Loss: {epoch_loss:.4f} | Train Accuracy: {epoch_acc:.4f}') + + model.eval() + running_loss, corrects = 0, 0 + with torch.no_grad(): + for inputs, targets in val_loader: + outputs = model(inputs) + loss = criterion(outputs, targets) + running_loss += loss.item() * inputs.size(0) + _, preds = torch.max(outputs, 1) + corrects += torch.sum(preds == targets.data) + + epoch_loss = running_loss / len(val_loader.dataset) + epoch_acc = corrects.double().cpu() / len(val_loader.dataset) + val_losses.append(epoch_loss) + val_accs.append(epoch_acc) + + print(f'Fold {fold+1}, Epoch {epoch+1} | Validation Loss: {epoch_loss:.4f} | Validation Accuracy: {epoch_acc:.4f}') + + # 保存最佳模型 + if epoch_acc > best_val_acc: + best_val_acc = epoch_acc + best_model = model.state_dict() + + # 保存每一折的最佳模型 + torch.save(best_model, f'model_fold{fold+1}.pth') + + all_train_losses.append(train_losses) + all_val_losses.append(val_losses) + all_train_accs.append(train_accs) + all_val_accs.append(val_accs) + +# 绘制所有折的平均损失和准确率曲线 +plt.figure(figsize=(12, 4)) +plt.subplot(1, 2, 1) +plt.plot(range(n_epochs), np.mean(all_train_losses, axis=0), label='Train Loss') +plt.plot(range(n_epochs), np.mean(all_val_losses, axis=0), label='Validation Loss') +plt.legend() +plt.title('Loss') + +plt.subplot(1, 2, 2) +plt.plot(range(n_epochs), np.mean(all_train_accs, axis=0), label='Train Accuracy') +plt.plot(range(n_epochs), np.mean(all_val_accs, axis=0), label='Validation Accuracy') +plt.legend() +plt.title('Accuracy') + +print(f'All Fold Average | Train Loss: {np.mean(all_train_losses, axis=0)[-1].item():.4f} | Train Accuracy: {np.mean(all_train_accs, axis=0)[-1].item():.4f} | Validation Loss: {np.mean(all_val_losses, axis=0)[-1].item():.4f} | Validation Accuracy: {np.mean(all_val_accs, axis=0)[-1].item():.4f}') + +plt.show()