第三十七天打卡

知識點回顧:

  1. 過擬合的判斷:測試集和訓練集同步打印指標
  2. 模型的保存和加載
    1. 僅保存權重
    2. 保存權重和模型
    3. 保存全部信息checkpoint,還包含訓練狀態
  3. 早停策略

作業:對信貸數據集訓練后保存權重,加載權重后繼續訓練50輪,并采取早停策略

import pandas as pd
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.preprocessing import MinMaxScaler, StandardScaler, OneHotEncoder, LabelEncoder
import time
import matplotlib.pyplot as plt
from tqdm import tqdm
from imblearn.over_sampling import SMOTE# ------------------- 設備配置(GPU/CPU) -------------------
# 檢查是否有可用的GPU:如果有則用GPU加速訓練(速度更快),否則用CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"使用設備: {device}")  # 打印當前使用的設備(確認是否啟用GPU)# ------------------- 加載并清洗數據 -------------------
# 加載信貸預測數據集(假設data.csv在當前目錄下)
# 數據包含用戶信息(如收入、工作年限)和標簽(是否違約:Credit Default)
data = pd.read_csv(r'data.csv')# 丟棄無用的Id列(Id是用戶唯一標識,與信貸違約無關)
data = data.drop(['Id'], axis=1)  # axis=1表示按列刪除# 區分連續特征(數值型)和離散特征(文本型/類別型)
# 連續特征:比如年齡、收入(可以取任意數值)
# 離散特征:比如職業、教育程度(只能取有限的類別)
continuous_features = data.select_dtypes(include=['float64', 'int64']).columns.tolist()  # 數值列
discrete_features = data.select_dtypes(exclude=['float64', 'int64']).columns.tolist()  # 非數值列# 離散特征用眾數(出現次數最多的值)填充缺失值
# 例:如果"職業"列有缺失,用出現最多的職業填充
for feature in discrete_features:if data[feature].isnull().sum() > 0:  # 檢查是否有缺失值mode_value = data[feature].mode()[0]  # 計算眾數data[feature].fillna(mode_value, inplace=True)  # 填充缺失值# 連續特征用中位數(中間位置的數)填充缺失值
# 例:如果"收入"列有缺失,用所有收入的中間值填充(比平均數更抗異常值)
for feature in continuous_features:if data[feature].isnull().sum() > 0:median_value = data[feature].median()  # 計算中位數data[feature].fillna(median_value, inplace=True)# ------------------- 離散特征編碼(轉成數值) -------------------
# 有順序的離散特征(比如"工作年限"有"1年"<"2年"<"10+年")用標簽編碼(轉成數字)
mappings = {"Years in current job": {"10+ years": 10,  # "10+年"對應數字10(最大)"2 years": 2,     # "2年"對應數字2"3 years": 3,"< 1 year": 0,    # "<1年"對應數字0(最小)"5 years": 5,"1 year": 1,"4 years": 4,"6 years": 6,"7 years": 7,"8 years": 8,"9 years": 9},"Home Ownership": {  # 房屋所有權(有順序:租房 < 房貸 < 有房貸 < 自有房?)"Home Mortgage": 0,  # 房貸"Rent": 1,           # 租房"Own Home": 2,       # 自有房"Have Mortgage": 3   # 有房貸(可能順序需要根據業務調整)},"Term": {  # 貸款期限(短期 < 長期)"Short Term": 0,  # 短期"Long Term": 1    # 長期}
}# 使用映射字典將文本轉成數字(標簽編碼)
data["Years in current job"] = data["Years in current job"].map(mappings["Years in current job"])
data["Home Ownership"] = data["Home Ownership"].map(mappings["Home Ownership"])
data["Term"] = data["Term"].map(mappings["Term"])# 無順序的離散特征(比如"貸款用途":購車/教育/裝修,彼此無大小關系)用獨熱編碼
# 獨熱編碼:將1列轉成N列(N是類別數),每列用0/1表示是否屬于該類別
data = pd.get_dummies(data, columns=['Purpose'])  # 對"Purpose"列做獨熱編碼# 獨熱編碼后會生成新列(比如Purpose_購車、Purpose_教育),需要將這些列的類型從bool轉成int(0/1)
list_final = []  # 存儲新生成的列名
data2 = pd.read_csv(r'data.csv')  # 重新讀取原始數據(對比列名)
for i in data.columns:if i not in data2.columns:  # 原始數據沒有的列,就是新生成的獨熱列list_final.append(i)
for i in list_final:data[i] = data[i].astype(int)  # 將bool型(True/False)轉成int(1/0)# ------------------- 分離特征和標簽 -------------------
X = data.drop(['Credit Default'], axis=1)  # 特征數據(所有列,除了標簽列)
y = data['Credit Default']  # 標簽數據(0=未違約,1=違約)# 劃分訓練集(80%)和測試集(20%):訓練集用來學習規律,測試集驗證模型效果
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # random_state固定隨機種子,保證結果可復現# 特征標準化(將特征縮放到0-1區間,避免大數值特征"欺負"小數值特征)
scaler = MinMaxScaler()  # 創建MinMaxScaler(最小-最大標準化)
X_train = scaler.fit_transform(X_train)  # 用訓練集擬合標準化參數并轉換
X_test = scaler.transform(X_test)  # 用訓練集的參數轉換測試集(保證數據分布一致)# 將數據轉成PyTorch張量(神經網絡只能處理張量數據),并移動到GPU(如果有)
# FloatTensor:32位浮點數(特征數據)
# LongTensor:64位整數(標簽數據,分類任務需要)
X_train = torch.FloatTensor(X_train).to(device)
y_train = torch.LongTensor(y_train.values).to(device)
X_test = torch.FloatTensor(X_test).to(device)
y_test = torch.LongTensor(y_test.values).to(device)# ------------------- 定義神經網絡模型 -------------------
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()  # 調用父類構造函數(必須)# 全連接層1:輸入30個特征(根據數據預處理后的列數確定),輸出64個神經元self.fc1 = nn.Linear(30, 64)self.relu = nn.ReLU()  # 激活函數(引入非線性,讓模型能學習復雜規律)self.dropout = nn.Dropout(0.2)  # Dropout層(隨機丟棄30%的神經元,防止過擬合)# 全連接層2:輸入64個神經元,輸出32個神經元self.fc2 = nn.Linear(64, 32)# 全連接層3:輸入32個神經元,輸出2個類別(0=未違約,1=違約)self.fc3 = nn.Linear(32, 2)def forward(self, x):# 前向傳播:數據從輸入層→隱藏層→輸出層的計算流程x = self.fc1(x)    # 輸入層→隱藏層1:30→64x = self.relu(x)   # 激活函數(過濾負數值)x = self.dropout(x)  # 應用Dropout(防止過擬合)x = self.fc2(x)    # 隱藏層1→隱藏層2:64→32x = self.relu(x)   # 激活函數x = self.fc3(x)    # 隱藏層2→輸出層:32→2(輸出未歸一化的分數)return x# ------------------- 初始化模型、損失函數、優化器 -------------------
model = MLP().to(device)  # 實例化模型并移動到GPU
criterion = nn.CrossEntropyLoss()  # 交叉熵損失函數(適合分類任務)
optimizer = optim.Adam(model.parameters(), lr=0.001)  # Adam優化器(比SGD更智能,自動調整學習率)# ------------------- 模型訓練 -------------------
num_epochs = 20000  # 訓練輪數(完整遍歷訓練集的次數)
train_losses = []         # 記錄每200輪的訓練損失
test_losses = []          # 記錄每200輪的測試損失
accuracies = []     # 記錄每200輪的測試準確率
epochs = []         # 記錄對應的輪數
# ==========新增早停相關參數==========
best_test_loss = float('inf')  # 記錄最佳測試集損失
best_epoch = 0                 # 記錄最佳epoch
patience =  50              # 早停耐心值(連續多少輪測試集損失未改善時停止訓練)
counter = 0                    # 早停計數器
early_stopped = False          # 是否早停標志
# =====================================
start_time = time.time()  # 記錄訓練開始時間# 創建tqdm進度條(可視化訓練進度)
with tqdm(total=num_epochs, desc="訓練進度", unit="epoch") as pbar:for epoch in range(num_epochs):# 前向傳播:模型根據輸入數據計算預測值outputs = model(X_train)  # 模型輸出(形狀:[訓練樣本數, 2],表示每個樣本屬于2個類別的分數)train_loss = criterion(outputs, y_train)  # 計算損失(預測值與真實標簽的差異,越小越好)# 反向傳播和參數更新optimizer.zero_grad()  # 清空歷史梯度(避免梯度累加)train_loss.backward()        # 反向傳播計算梯度(自動求導)optimizer.step()       # 根據梯度更新模型參數(優化器核心操作)# 每200輪記錄一次損失和準確率(避免記錄太頻繁影響速度)if (epoch + 1) % 200 == 0:# 在測試集上評估模型(不更新參數,只看效果)model.eval()  # 切換到評估模式(關閉Dropout,保證結果穩定)with torch.no_grad():  # 禁用梯度計算(節省內存,加速推理)test_outputs = model(X_test)  # 測試集預測值test_loss = criterion(test_outputs, y_test)  # 計算測試集損失model.train()  # 切換回訓練模式# 記錄損失值和準確率train_losses.append(train_loss.item())  # 訓練集損失test_losses.append(test_loss.item())  # 測試集損失epochs.append(epoch + 1)  # 記錄輪數# 更新進度條顯示的信息(當前損失和準確率)pbar.set_postfix({'Train Loss': f'{train_loss.item():.4f}', 'Test Loss': f'{test_loss.item():.4f}'})# ===== 新增早停邏輯 =====if test_loss.item() < best_test_loss: # 如果當前測試集損失小于最佳損失best_test_loss = test_loss.item() # 更新最佳損失best_epoch = epoch + 1 # 更新最佳epochcounter = 0 # 重置計數器# 保存最佳模型torch.save(model.state_dict(), 'best_model.pth')else:counter += 1if counter >= patience:print(f"早停觸發!在第{epoch+1}輪,測試集損失已有{patience}輪未改善。")print(f"最佳測試集損失出現在第{best_epoch}輪,損失值為{best_test_loss:.4f}")early_stopped = Truebreak  # 終止訓練循環# ======================# 每1000輪更新一次進度條(避免進度條刷新太頻繁)if (epoch + 1) % 1000 == 0:pbar.update(1000)  # 進度條前進1000步# 確保進度條最終顯示100%(防止最后一輪未更新)if pbar.n < num_epochs:pbar.update(num_epochs - pbar.n)# 計算總訓練時間并打印
time_all = time.time() - start_time
print(f'Training time: {time_all:.2f} seconds')# ===== 新增:加載最佳模型用于最終評估 =====
if early_stopped:print(f"加載第{best_epoch}輪的最佳模型進行最終評估...")model.load_state_dict(torch.load('best_model.pth'))
# ================================# ------------------- 可視化訓練結果 -------------------
# 創建雙y軸圖表(損失和準確率在同一張圖顯示)
# 可視化損失曲線
plt.figure(figsize=(10, 6))
plt.plot(epochs, train_losses, label='Train Loss')
plt.plot(epochs, test_losses, label='Test Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training and Test Loss over Epochs')
plt.legend()
plt.grid(True)
plt.show()# ------------------- 最終測試集評估 -------------------
model.eval()  # 切換到評估模式
with torch.no_grad():  # 禁用梯度計算outputs = model(X_test)  # 測試集預測值_, predicted = torch.max(outputs, 1)  # 取預測類別(0或1)correct = (predicted == y_test).sum().item()  # 正確預測的樣本數accuracy = correct / y_test.size(0)  # 計算準確率print(f'測試集準確率: {accuracy * 100:.2f}%')  # 打印準確率(百分比形式)
#測試集準確率: 77.20%

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906996.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906996.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906996.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java高頻面試之并發編程-21

hello啊&#xff0c;各位觀眾姥爺們&#xff01;&#xff01;&#xff01;本baby今天又來報道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面試官&#xff1a;詳細說說AQS AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是 Java 并發包&#xff08;java.util.concurre…

按鍵狀態機

原工程地址&#xff1a;https://github.com/candylife9/state_machine_example 視頻&#xff1a;C語言之狀態機編程_02_狀態機使用案例分析_嗶哩嗶哩_bilibili 我覺得講的挺好的。 來自豆包封裝的通用接口 頭文件 /*** file key_state_machine.h* brief 通用按鍵狀態機接口…

華為OD機試真題——新學校選址(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳實現

2025 A卷 100分 題型 本專欄內全部題目均提供Java、python、JavaScript、C、C++、GO六種語言的最佳實現方式; 并且每種語言均涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、3個測試用例以及綜合分析; 本文收錄于專欄:《2025華為OD真題目錄+全流程解析+備考攻略+經驗分…

歐拉操作系統下安裝hadoop集群

背景&#xff1a;歐拉操作系統下安裝CDH集群的時候&#xff0c;需要安裝python2.7.5&#xff0c;但是本身歐拉系統對python2的支持可能沒有那么好&#xff0c;所以考慮搭建原生的hadoop集群。 基礎環境如下 組件名稱組件版本歐拉VERSION“22.03 (LTS-SP4)”jdkopenjdk versio…

SQL語句的執行流程

文章目錄 一、執行流程二、建立連接三、預處理器四、解析器4.1 詞法分析4.2 語法分析4.3 語義分析 五、優化器六、執行器七、返回結果 一、執行流程 階段主要功能關鍵組件1. 建立連接身份驗證、權限檢查連接器2. 預處理器緩存檢查、SQL預處理查詢緩存3. 解析器詞法分析、語法分…

TiDB:從快速上手到核心原理與最佳實踐

文章目錄 引言第一部分&#xff1a;TiDB快速體驗與實踐指南1. TiDB概述2. TiDB部署方式2.1 本地測試環境部署2.2 生產環境部署2.3 Kubernetes部署2.4 云服務 3. TiDB基本操作3.1 連接TiDB3.2 數據庫和表操作3.3 分區表3.4 事務操作 4. 數據遷移到TiDB4.1 從MySQL遷移4.2 使用Ti…

總結:進程和線程的聯系和區別

前言:通過學習javaEE初階中的多線程章節后加上我自己的理解,想來總結一下線程和進程的聯系和區別. 一來是能更好地復習知識,二來是為了記錄我的學習路程,相信未來的我回首不會忘記這段難忘的經歷. 1.進程 先來談談進程:進程是操作系統中資源分配的基本單位. 1)進程的執行方…

邊緣云的定義、實現與典型應用場景!與傳統云計算的區別!

一、什么是邊緣云&#xff1f;? 邊緣云是一種?分布式云計算架構?&#xff0c;將計算、存儲和網絡資源部署在?靠近數據源或終端用戶的網絡邊緣側?&#xff08;如基站、本地數據中心或終端設備附近&#xff09;&#xff0c;而非傳統的集中式云端數據中心。 ?核心特征?&…

海康威視攝像頭C#開發指南:從SDK對接到安全增強與高并發優化

一、海康威視SDK核心對接流程?? 1. ??開發環境準備?? ??官方SDK獲取??&#xff1a;從海康開放平臺下載最新版SDK&#xff08;如HCNetSDK.dll、PlayCtrl.dll&#xff09;。??依賴項安裝??&#xff1a;確保C運行庫&#xff08;如vcredist_x86.exe&#xff09;與S…

《軟件工程》第 9 章 - 軟件詳細設計

目錄 9.1 詳細設計的任務與過程模型 9.2 用例設計 9.2.1 設計用例實現方案 9.2.2 構造設計類圖 9.2.3 整合并優化用例實現方案 9.3 子系統設計 9.3.1 確立內部設計元素 9.3.2 導出設計類圖 9.4 構件設計 9.5 類設計 9.5.1 精化類間關系 9.5.2 精化屬性和操作 9.5.…

spring+tomcat 用戶每次發請求,tomcat 站在線程的角度是如何處理用戶請求的,spinrg的bean 是共享的嗎

對于 springtomcat 用戶每次發請求&#xff0c;tomcat 站在線程的角度是如何處理的 比如 bio nio apr 等情況 tomcat 配置文件中 maxThreads 的數量是相對于誰來說的&#xff1f; 以及 spring Controller 中的全局變量:各種bean 對于線程來說是共享的嗎&#xff1f; 一、Tomca…

存儲引擎系列--LSM不同Compaction策略性能分析對比

本文介紹一下參考論文里的Compaction性能分析部分,作者在RocksDB的基礎上做了多種策略的改造,然后提出了benchmarking方法論,關注compaction性能的哪些維度,并對結果進行分析。 一、Standardization of Compaction Strategies 1.1 實驗平臺的選擇 作者選擇了RocksDB作為…

leetcode 3559. Number of Ways to Assign Edge Weights II

leetcode 3559. Number of Ways to Assign Edge Weights II 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3559. Number of Ways to Assign Edge Weights II 1. 解題思路 這一題是題目3558. Number of Ways to Assign Edge Weights I的進階版本。 對于題目3558來說&#xf…

推理模型 vs 非推理模型:核心區別及優劣勢解析

推理能力上的差異 推理模型在推理能力方面表現突出,它們擅長通過生成中間步驟和“思維鏈”逐步解決復雜問題。這意味著面對數學計算、邏輯推理、多跳推斷等任務時,推理模型能夠將問題分解為若干子步驟,每一步給出推理結果,最終匯總得到答案。這種逐步推導的方式使得推理模…

OPENEULER搭建私有云存儲服務器

一、關閉防火墻和selinux 二、下載相關軟件 下載nginx&#xff0c;mariadb、php、nextcloud 下載nextcloud&#xff1a; sudo wget https://download.nextcloud.com/server/releases/nextcloud-30.0.1.zip sudo unzip nextcloud-30.0.1.zip -d /var/www/html/ sudo chown -R…

Docker 與微服務架構:從單體應用到容器化微服務的遷移實踐

隨著軟件系統規模和復雜性的日益增長,傳統的單體應用(Monolithic Application)在開發效率、部署靈活性和可伸縮性方面逐漸暴露出局限性。微服務架構(Microservice Architecture)作為一種將大型應用拆分為一系列小型、獨立、松耦合服務的模式,正成為現代企業構建彈性、敏捷…

【C#】Invalidate()的使用

Invalidate()的使用 Invalidate() 是 C# 中用于通知控件需要重新繪制的方法。它通常用于 Windows Forms 應用程序中&#xff0c;當想要更新控件的顯示內容時使用。調用 Invalidate() 方法后&#xff0c;系統會安排對該控件進行重繪&#xff0c;這將導致后續調用 OnPaint 方法&…

我店模式系統開發打造本地生活生態商圈

在當今快節奏的商業環境中&#xff0c;商家們面臨著越來越多的挑戰&#xff0c;包括市場競爭加劇、消費者需求多樣化以及運營效率的提高等。為了應對這些挑戰&#xff0c;越來越多的商家開始尋求信息化解決方案&#xff0c;以提升運營效率和客戶體驗。我的店模式系統平臺應運而…

Linux(Ubuntu)新建文件權限繼承問題

當你在一個工作目權限為777的文件下&#xff0c;新建一個文件的時候&#xff0c;就有可能發生&#xff0c;新建的這個文件&#xff0c;權限和其他文件&#xff0c;或者工作目錄不一致的問題&#xff0c;我們不可能每次新建一個文件&#xff0c;就要 sudo chmod -R 777 /PATH 所…

Vue3和React中插件化設計思想

Vue 3 和 React 都廣泛支持插件化設計思想&#xff0c;但因為它們的架構和理念不同&#xff0c;插件化的實現方式也不盡相同。以下分別詳細講解這兩者中如何實現插件化&#xff1a; &#x1f7e9; 一、Vue 3 中的插件化實現 Vue 3 繼承了 Vue 2 的插件機制&#xff0c;同時增強…