1、logistic 迴歸介紹
logistic 迴歸是一種廣義線性迴歸 (generalized linear model),與多重線性迴歸分析有很多相同之處。它們的模型形式基本上相同,都具有 wx+b,其中 w 和 b 是待求參數,其區別在於他們的因變量不同,多重線性迴歸直接將 wx+b 作爲因變量,即 y=wx+b,而 logistic 迴歸則通過函數L 將 wx+b 對應一個隱狀態 p, p = L(wx+b), 然後根據 p 與 1-p 的大小決定變量的值。如果 L 是logistc 函數,就是 logistic 迴歸,如果 L是多項式函數就是多項式回說的更通俗一點,就是 logistc 迴歸會在線性迴歸後再加一層 logistic 函數的調用。
logistic 迴歸主要是進行二分類預測,我們在激活函數時候講到過 Sigmod 函數, Sigmod 函數是最常見的 logistc 函數爲 Sigmod 函數的輸出的是是對於 0-1 之間的概率值,當概率大於 0.5預測爲 1,小於 0.5 預測爲 0。
2、數據集
德國信用數據集:UCI German Credit
https://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/
3、代碼實戰
# 導入相關的包
import torch # torch 是一種科學計算框架
import torch.nn as nn # torch.nn 神經網絡的接口
import numpy as np # numpy 科學計算的軟件包
torch.__version__ # 查看 torch 的版本
# 使用 numpy 的 load 方法讀取數據
data = np.loadtxt("german.data-numeric")
注:
numpy 中的 loadtxt() 函數可以用來讀取文件,主要是 txt 文件;
# 對數據做一下歸一化處理
n, l = data.shape
for j in range(l-1):
meanVal = np.mean(data[:, j])
stdVal = np.std(data[:, j])
data[:, j] = (data[:, j]-meanVal) / stdVal
注:
- n, l = data.shape --讀取 data 的大小;n 代表行數,l 代表列數
實例:
- data[:, j] --讀取 data 所有行的 j 列的數
實例:
- meanVal = np.mean(data[:, j]) # 求 data 所有行 j 列所有數的平均值
- stdVal = np.std(data[:, j]) # 求 data 所有行 j 列所有數的方差
- data[:, j] = (data[:, j]-meanVal)/stdVal # 歸一化
# 打亂數據
np.random.shuffle(data)
注:
shuffle() 方法將序列的所有元素隨機排序,但 shuffle() 是不能直接訪問的,需要導入 random 模塊,然後通過 random 靜態對象調用該方法。
# 區分訓練集和測試集
由於這裏沒有驗證集,所以我們直接使用測試集的準確度作爲評判好壞的標準
區分規則:900條用於訓練,100條作爲測試訓練
train_data = data[: 900, : l-1] # 訓練試集
train_lab = data[: 900, l-1] -1 # 訓練標籤
test_data = data[900: , : l-1] # 測試集
test_lab = data[900: , l-1] - 1 # 測試標籤
注意:
這裏爲什麼需要在 label 中 -1 呢?
打開原始數據看一下就明白了,主要原因是原始的數據標籤範圍是1和2,而在代碼中使用的是sigmoid函數,其對應的範圍是 0-1,因此需要把原始的 label-1.
# 定義模型
class LR(nn.Module):
def __init__(self): # 構造函數
super(LR,self).__init__() # 繼承父類的構造方法,等價於 LR.__init__(self)
self.fc = nn.Linear(24, 2)
# 定義前向傳播函數
def forward(self,x):
out = self.fc(x)
out = torch.sigmoid(out)
return out
注:
- nn.Linear(24, 2) --- 對輸入的數據進行線性變換 y = x + b
原型: torch.nn.Linear(in_features, out_features, bias=True)
參數: in_features -- 輸入樣本數據的大小
out_features -- 輸出樣本數據的大小;
bias -- 如果設置爲 False,則該圖層將不會學習加法偏差。默認值:True
參考 :https://pytorch.org/docs/master/nn.html#torch.nn.Linear
# 測試集上的準確率
def test(pred,lab):
t = pred.max(-1)[1] == lab
return torch.mean(t.float())
注:
- pred.max(-1) --- 表示取 pred 每一行的最大值;
- Pred.max(-1)[1] --- 表示取 pred 每一行最大值的索引;
實例:
參考:https://blog.csdn.net/jzwong/article/details/103267516
- t = pred.max(-1)[1] == lab --- 返回的是一個長度爲樣本個數的 0,1 向量
- torch.mean(t.float()) --- 準確率的定義,其實就是計算 1 佔整個樣本的比率
# 設置
net = LR() # 類的實例化,創建一個實例
criterion = nn.CrossEntropyLoss() # 使用 CrossEntropyLoss 損失
optm = torch.optim.Adam(net.parameters()) # Adam 優化
epochs = 1000 # 訓練 1000 次
# 開始訓練
for i in range(epochs):
# 指定模型爲訓練模式,計算梯度
net.train()
# 輸入值都需要轉換成 torch 的Tensor
x = torch.from_numpy(train_data).float()
y = torch.from_numpy(train_lab).long()
y_hat = net(x)
loss = criterion(y_hat, y) # 計算損失
optm.zero_grad() # 前一步的損失清零
loss.backward() # 反向傳播
optm.step() # 優化
if (i + 1) % 100 == 0: # 這裏我們每 100 次輸出相關的信息
# 指定模型爲計算模式
net.eval()
test_in = torch.from_numpy(test_data).float()
test_l = torch.from_numpy(test_lab).float()
test_out = net(test_in)
# 使用我們的測試函數計算準確率
accu = test(test_out, test_l)
print("Epoch:{}, Loss:{:.4f}, Accurary:{:.2f}".format(i+1, loss.item(),accu))
準確率: