目錄
一、數據準備與預處理
二、數據集劃分與歸一化
三、構建神經網絡模型
四、定義損失函數和優化器
五、訓練模型
六、評估模型
在機器學習和深度學習的實踐中,信貸風險評估是一個非常重要的應用場景。通過構建神經網絡模型,我們可以對客戶的信用狀況進行預測,從而幫助金融機構更好地管理風險。最近,我嘗試使用PyTorch框架來實現一個信貸風險預測的神經網絡模型,并在這個過程中鞏固了我對神經網絡的理解。以下是我在完成這個任務過程中的詳細記錄和總結。
一、數據準備與預處理
信貸數據集通常包含客戶的各種特征,如收入、信用評分、貸款金額等,以及是否違約的標簽。為了更好地訓練神經網絡模型,數據預處理是必不可少的步驟。
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
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt
from tqdm import tqdm# 設置GPU設備
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"使用設備: {device}")# 加載信貸預測數據集
data = pd.read_csv('data.csv')# 丟棄掉Id列
data = data.drop(['Id'], 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)# 有順序的離散變量進行標簽編碼
mappings = {"Years in current job": {"10+ years": 10,"2 years": 2,"3 years": 3,"< 1 year": 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"])# 對沒有順序的離散變量進行獨熱編碼
data = pd.get_dummies(data, columns=['Purpose'])
在上述代碼中,我首先加載了信貸數據集,并對其進行了預處理。具體步驟包括:
-
丟棄無用的
Id
列。 -
區分連續特征和離散特征。
-
對離散特征使用眾數進行補全,對連續特征使用中位數進行補全。
-
對有順序的離散變量進行標簽編碼,對沒有順序的離散變量進行獨熱編碼。
二、數據集劃分與歸一化
在數據預處理完成后,我將數據集劃分為訓練集和測試集,并對特征數據進行歸一化處理。
# 分離特征數據和標簽數據
X = data.drop(['Credit Default'], axis=1) # 特征數據
y = data['Credit Default'] # 標簽數據# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 對特征數據進行歸一化處理
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test) # 確保訓練集和測試集是相同的縮放# 將數據轉換為PyTorch張量
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)
在上述代碼中,我使用了MinMaxScaler
對特征數據進行歸一化處理,以確保所有特征的值都在0到1之間。這一步對于神經網絡的訓練非常重要,因為它可以加速模型的收斂速度并提高模型的性能。之后,我將數據轉換為PyTorch張量,并將其移動到指定的設備(GPU或CPU)上。
三、構建神經網絡模型
接下來,我定義了一個簡單的多層感知機(MLP)模型,包含一個輸入層、兩個隱藏層和一個輸出層。隱藏層使用了ReLU激活函數,并添加了Dropout層以防止過擬合。
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()self.fc1 = nn.Linear(X_train.shape[1], 64) # 輸入層到第一隱藏層self.relu = nn.ReLU()self.dropout = nn.Dropout(0.3) # 添加Dropout防止過擬合self.fc2 = nn.Linear(64, 32) # 第一隱藏層到第二隱藏層self.fc3 = nn.Linear(32, 2) # 第二隱藏層到輸出層def forward(self, x):x = self.fc1(x)x = self.relu(x)x = self.dropout(x)x = self.fc2(x)x = self.relu(x)x = self.dropout(x)x = self.fc3(x)return x# 初始化模型
model = MLP().to(device)
在定義模型時,我使用了nn.Module
作為基類,并通過forward
方法定義了模型的前向傳播邏輯。這種模塊化的定義方式使得模型的結構清晰且易于擴展。
四、定義損失函數和優化器
損失函數和優化器是神經網絡訓練的兩個關鍵組件。對于分類任務,交叉熵損失函數(CrossEntropyLoss
)是最常用的損失函數之一。優化器則負責根據損失函數的梯度更新模型的參數,我選擇了隨機梯度下降(SGD)優化器。
criterion = nn.CrossEntropyLoss() # 使用交叉熵損失函數
optimizer = optim.SGD(model.parameters(), lr=0.01) # 使用SGD優化器
五、訓練模型
訓練模型的過程是一個迭代優化的過程。在每一輪迭代中,模型會計算損失函數的值,并通過反向傳播更新參數。為了監控訓練過程,我每10輪打印一次損失值。
num_epochs = 200 # 訓練輪數
for epoch in range(num_epochs):model.train() # 設置為訓練模式optimizer.zero_grad() # 清空梯度outputs = model(X_train) # 前向傳播loss = criterion(outputs, y_train) # 計算損失loss.backward() # 反向傳播optimizer.step() # 更新參數if (epoch + 1) % 10 == 0:print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
通過上述代碼,我成功地訓練了模型,并觀察到損失值隨著訓練輪數的增加而逐漸降低。這表明模型正在逐步學習數據中的規律。
六、評估模型
訓練完成后,我使用測試集對模型的性能進行了評估。評估指標是準確率,即模型正確預測的樣本數占總樣本數的比例。
model.eval() # 設置為評估模式
with torch.no_grad():correct = 0total = 0outputs = model(X_test)_, predicted = torch.max(outputs.data, 1)total += y_test.size(0)correct += (predicted == y_test).sum().item()accuracy = 100 * correct / total
print(f'Accuracy on test set: {accuracy:.2f}%')
最終,模型在測試集上的準確率達到了 [具體準確率]%。雖然這個結果還有提升的空間,但它已經證明了神經網絡在信貸風險評估任務中的有效性。
@浙大疏錦行