前言以及迴歸分析

Mercuryadore發表於2024-05-01

統計建模

前言

這次想嘗試一下統計建模,準備長三角建模的同時,加強一下自己的資料分析能力,學習的教材是張良均的《Python資料分析與挖掘實戰》,這本書後面的實戰練習相當不錯,值得一做,書長下面這樣,zlib裡有pdf的,裡面涉及的程式碼和資料在本書中均有給出獲得方式。此學習筆記僅供參考,大部分內容和書中的內容相同,程式碼部分會有一些改進。

image-20240430222612646

這本書第1~5章在講基礎部分,主要是資料的處理方法、python的使用以及一些常用的模型與方法,前四章內容我先前接觸過,內容較為簡單,這裡就先略過,從第五章 挖掘建模開始學習。

第五章 挖掘建模

5.1 分類與預測

分類主要是預測分類標號(離散屬性), 而預測主要是建立連續值函式模型,預測給定自變數對應的因變數的值。

5.1.1 實現過程

image-20240430223507137

5.1.2 常用演算法

image-20240430223559139

5.1.3 迴歸分析

迴歸分析:透過建立模型來研究變數之間相互關係的密切程度、結構狀態及進行模型預測的有效工具。研究的範圍大致如下:

image-20240430223845012

在資料探勘環境下,自變數與因變數具有相關關係,自變數的值是已知的,因變數是要預測的。

常用的迴歸模型見下表:

image-20240430224121750

線性迴歸模型是相對簡單的迴歸模型,但是通常因變數和自變數之間呈現出某種曲線關係,這就需要建立非線性迴歸模型。

1. Logistic 迴歸分析介紹

Logistic 迴歸屬於機率型非線性迴歸,分為二分類和多分類的迴歸模型。

( 1 )Logistic 函式

Logistic 迴歸模型中的因變數只有 1-0(如“是”和“否”、“發生”和“不發生”)兩種取值。假設在\(p\)個獨立自變數\(x_1,x_2,\cdots,x_p\)的作用下,記\(y\)取 1 的機率是\(p=P(y=1\mid X)\) , 取 0 的機率是 1\(-p\) ,取 1 和取 0 的機率之比為\(\frac p{1-p}\),稱為事件的優勢比(odds),對odds 取自然對數即得 Logistic 變換 \(\mathrm{Logit}(p)=\ln\left(\frac p{1-p}\right)\circ\)

\(\mathrm{Logit}(p)=\ln\left(\frac p{1-p}\right)=z\), 則\(p=\frac1{1+\mathrm{e}^{-z}}\)即為 Logistic 函式,如圖所示。

image-20240430231719902
( 2 ) Logistic 迴歸模型

Logistic 迴歸模型是建立 \(\ln\left(\frac p{1-p}\right)\)與自變數的線性迴歸模型。Logistic 迴歸模型為下式:

\[\ln\biggl(\frac{p}{1-p}\biggr)=\beta_0+\beta_1x_1+\cdots+\beta_px_p+\varepsilon \]

因為\(\ln\left(\frac p{1-n}\right)\)的取值範圍是\((-\infty,+\infty)\),這樣,自變數 \(x_1,x_2,\cdots,x_p\) 可在任意範圍內取值。記\(g(x)=\beta_0+\beta_1x_1+\cdots+\beta_px_p\),得到式\((5-2)\)和式\((5-3)\)

\[p=P(y=1\mid X)=\frac{1}{1+\mathrm{e}^{-g(x)}} \tag{5-2} \]

\[1-p=P(y=0\mid X)=1-\frac{1}{1+\mathrm{e}^{-g(x)}}=\frac{1}{1+\mathrm{e}^{g(x)}}\tag{5-3} \]

( 3 )Logistic 迴歸模型的解釋

\[\frac p{1-p}=\mathrm{e}^{\beta_0+\beta_1x_1+\cdots+\beta_px_p+\varepsilon}\tag{5-4} \]

\(\beta_0:\)在沒有自變數,即\(x_1,x_2,\cdots,x_p\)全部取 0 時,\(y=1\)\(y=0\)發生機率之比的自然對數;

\(\beta_1:\)某自變數\(x_i\)變化時,即\(x_i=1\)\(x_i=0\)相比,\(y=1\)優勢比的對數值。

image-20240430233117395

2. Logistic 迴歸建模步驟

image-20240430233506079
( 1 )Code

利用 \(\text{scikit-learn}\) 庫對這個資料建立邏輯迴歸模型

import pandas as pd
from sklearn.linear_model import LogisticRegression as LR
# 引數初始化
filename = '../data/bankloan.xls'
data = pd.read_excel(filename)

x = data.iloc[:,:8]
y = data.iloc[:,8]

lr = LR()  # 建立邏輯迴歸模型
lr.fit(x, y)  # 用篩選後的特徵資料來訓練模型
print('模型的平均準確度為:%s' % lr.score(x, y))

模型的平均準確度為:0.8085714285714286

一些引數如下:

image-20240430233813359

  • model.coef_ 得到[\(\beta_1\),\(\beta_2\),\(\cdots\),\(\beta_k\) ]

  • model.intercept_得到\(\beta_0\),截距,預設有截距

5.1.4 決策樹

決策樹方法在分類、預測、規則提取等領域有著廣泛應用。決策樹是一種樹狀結構,它的每一個葉節點對應著一個分類,非葉節點對應著在某個屬性上的劃分,根據樣本在該屬性上的不同取值將其劃分成若干個子集。對於非純的葉節點,多數類的標號給出到達這個節點的樣本所屬的類。構造決策樹的核心問題是在每一步如何選擇適當的屬性對樣本做拆分。對一個分類問題,從已知類標記的訓練樣本中學習並構造出決策樹是一個自上而下、分而治之的過程。

image-20240501183116302

1.ID3演算法

image-20240501183540591

這個圖片中的公式是關於資訊熵的一個變體,特別是針對集合 ( A ) 中的事件 \(( a_1, a_2, \ldots, a_k )\) 對某個特定系統狀態 \(S\) 的貢獻。這個系統狀態 \(S\) 可以進一步細分為 \(( S_1, S_2, \ldots, S_k )\)。公式中的 $E(A) $ 表示的是系統狀態 $ S $ 下集合 $ A $ 中各事件的資訊熵期望值。

公式 \(E(A)\) 定義如下:

\[E(A) = \sum_{j=1}^k \frac{s_{j}}{s} I(s_{j1}, s_{j2}, \ldots, s_{jm_j}) \]

這裡:

  • $s_j $ 表示在狀態 $S_j $ 下的特定事件的數量。
  • $s $是所有事件的總數。
  • $I(s_{j1}, s_{j2}, \ldots, s_{jm_j}) $是在狀態 $S_j $ 下,對應 $ s_j $ 事件集合的資訊熵。

簡而言之,這個公式計算的是給定系統狀態下,各個子狀態的加權資訊熵總和。每個子狀態的資訊熵是根據該子狀態的事件數量進行加權的。這種方法常用於考慮條件機率或者系統在不同子狀態下的不確定性。

image-20240501183708744

2. ID3 演算法具體流程

示例較為簡單,自行閱讀。

image-20240501184835492 image-20240501185006504

( 1 )具體步驟

就是在按照具體流程一步一步計算。

image-20240501185513678 image-20240501185610927 image-20240501185830494

( 2 )Code

import pandas as pd
# 引數初始化
filename = '../data/sales_data.xls'
data = pd.read_excel(filename, index_col = '序號')  # 匯入資料

# 資料是類別標籤,要將它轉換為資料
# 用1來表示“好”“是”“高”這三個屬性,用-1來表示“壞”“否”“低”
data[data == '好'] = 1
data[data == '是'] = 1
data[data == '高'] = 1
data[data != 1] = -1
x = data.iloc[:,:3].astype(int)
y = data.iloc[:,3].astype(int)


from sklearn.tree import DecisionTreeClassifier as DTC
dtc = DTC(criterion='entropy')  # 建立決策樹模型,基於資訊熵
dtc.fit(x, y)  # 訓練模型

# 匯入相關函式,視覺化決策樹。
# 匯出的結果是一個dot檔案,需要安裝Graphviz才能將它轉換為pdf或png等格式。
from sklearn.tree import export_graphviz
x = pd.DataFrame(x)

"""
string1 = '''
edge [fontname="NSimSun"];
node [ fontname="NSimSun" size="15,15"];
{
''' 
string2 = '}'
"""
 
with open("../tmp/tree.dot", 'w') as f:
    export_graphviz(dtc, feature_names = x.columns, out_file = f)
    f.close()


from IPython.display import Image  
from sklearn import tree
import pydotplus 

dot_data = tree.export_graphviz(dtc, out_file=None,  #regr_1 是對應分類器
                         feature_names=data.columns[:3],   #對應特徵的名字
                         class_names=data.columns[3],    #對應類別的名字
                         filled=True, rounded=True,  
                         special_characters=True)  
graph = pydotplus.graph_from_dot_data(dot_data)  
graph.write_png('../tmp/example.png')    #儲存影像
Image(graph.create_png()) 

( 2 )Result

image-20240501190310990

5.1.5 人工神經網路

神經網路本人學習較多,所以此處不加以展開,這裡用pytorch重構一下案例程式碼。

  • 本案例資料量太少只有34條,所以使用神經網路效果肯定是不好的,這邊只是實現一下程式碼。
  • 書中給出的程式碼,直接在訓練集上做測試,簡直是不可理喻,但是此題資料量太少了,所以資料分割其實意義也不大,此處結果單純做一個示範,不要較真。

1.Code

import pandas as pd
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
import seaborn as sns

# 引數初始化
inputfile = '../data/sales_data.xls'
data = pd.read_excel(inputfile, index_col='序號')  # 匯入資料

# 資料是類別標籤,要將它轉換為資料
# 用1來表示“好”“是”“高”這三個屬性,用0來表示“壞”“否”“低”
data[data == '好'] = 1
data[data == '是'] = 1
data[data == '高'] = 1
data[data != 1] = 0

# 分割資料
x_train_data = np.array(data.iloc[1:29, :3].values).astype(float)
y_train_data = np.array(data.iloc[1:29, 3].values).astype(float)
x_eval_data =  np.array(data.iloc[29:35, :3].values).astype(float)
y_eval_data =  np.array(data.iloc[29:35, 3].values).astype(float)

x = torch.Tensor(x_train_data)
y = torch.Tensor(y_train_data)
x_eval = torch.Tensor(x_eval_data)
y_eval = torch.Tensor(y_eval_data)
# 建立TensorDatasets和DataLoader
dataset = TensorDataset(x, y)
dataloader = DataLoader(dataset, batch_size=10, shuffle=False)

# 定義模型
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(3, 10)
        self.fc2 = nn.Linear(10, 1)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.sigmoid(self.fc2(x))
        return x

model = Net()

# 損失函式和最佳化器
loss_fn = nn.BCELoss()

optimizer = optim.Adam(model.parameters(),lr=0.01)

# 訓練模型
for epoch in range(1000):
    for inputs, labels in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = loss_fn(outputs.squeeze(), labels)
        loss.backward()
        optimizer.step()

# 預測
with torch.no_grad():
    predictions1 = model(x_eval).squeeze()
    predictions = (predictions1 >= 0.5).float()  # 將輸出轉換為0或1

# 繪製混淆矩陣
def cm_plot(original, predictions):
    cm = confusion_matrix(original, predictions)
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
    plt.xlabel('Predicted')
    plt.ylabel('True')
    plt.show()

cm_plot(y_eval, predictions)

2.Result

Figure_1

資料量太少了,此處單純用來練習視覺化,測試資料太少不要較真。

5.1.6 分類與預測演算法評價

分類與預測模型對訓練集進行預測而得出的準確率並不能很好地反映預測模型未來的效能,為了有效判斷一個預測模型的效能表現,需要一組沒有參與預測模型建立的資料集,並在該資料集上評價預測模型的準確率,這組獨立的資料集叫測試集。模型預測效果評價,通常用絕對誤差與相對誤差、平均絕對誤差、根均方差、相對平方根誤差等指標來衡量。

1. 絕對誤差與相對誤差

\(Y\)表示實際值,\(\hat{Y}\)表示預測值,則稱\(E\) 為絕對誤差(Absolute Error),計算公式如下:

\[E=Y-\hat{Y} \]

\(e\)為相對誤差(Relative Error),計算公式如下:

\[e=\frac{Y-\hat{Y}}Y \]

有時相對誤差也用百分數表示,如下式所示。

\[e=\frac{Y-\hat{Y}}Y\times100\% \]

這是一種直觀的誤差表示方法。

2.平均絕對誤差

平均絕對誤差( Mean Absolute Error, MAE),計算公式如下所示:

\[\mathrm{MAE}=\frac1n\sum_{i=1}^n\mid E_i\mid=\frac1n\sum_{i=1}^n\mid Y_i-\hat{Y_i}\mid \]

式中,\(\rm{MAE}\) 表示平均絕對誤差,\(E_i\)表示第\(i\)個實際值與預測值的絕對誤差,\(Y_{i}\)表示第\(i\)個實際值,\(\hat{Y}_i\)表示第\(i\)個預測值。由於預測誤差有正有負,為了避免正負相抵消,故取誤差的絕對值進行綜合並取其平均數,這是誤差分析的綜合指標法之一。

3.均方誤差

均方誤差(Mean Squared Error, MSE),計算公式如下式所示:

\[\mathrm{MSE}=\frac1n\sum_{i=1}^nE_i^2=\frac1n\sum_{i=1}^n(Y_i-\hat{Y}_i)^2 \]

式中,\(\rm{MSE}\) 表示均方差。本方法用於還原平方失真程度。均方誤差是預測誤差平方之和的平均數,它避免了正負誤差不能相加的問題。由於對誤差\(E\)進行了平方,加強了數值大的誤差在指標中的作用,從而提高了這個指標的靈敏性,是一大優點。均方誤差是誤差分析的綜合指標法之一。

4.均方根誤差

均方根誤差(Root Mean Squared Error, RMSE)計算公式如下式所示。

\[\mathrm{RMSE}=\sqrt{\frac1n\sum_{i=1}^nE_i^2}=\sqrt{\frac1n\sum_{i=1}^n\left(Y_i-\hat{Y}_i\right)^2} \]

式中,\(\rm{RMSE}\) 表示均方根誤差。這是均方誤差的平方根,代表了預測值的離散程度,也叫標準誤差,最佳擬合情況
\(\rm{RMSE}=0\)。均方根誤差也是誤差分析的綜合指標之一。

5.平均絕對百分誤差

平均絕對百分誤差( Mean Absolute Percentage Error, MAPE)計算公式如下式所示。

\[\mathrm{MAPE}=\frac{1}{n}\sum_{i=1}^{n}\mid E_{i}\:/\:Y_{i}\mid=\frac{1}{n}\sum_{i=1}^{n}\mid(Y_{i}-\hat{Y}_{i})\:/\:Y_{i}\mid \]

式中,\(\rm{MAPE}\) 表示平均絕對百分誤差。一般認為 MAPE 小於 10 時,預測精度較高。

6. Kappa 統計

image-20240501222749747

7. 識別準確度

image-20240501222817114 image-20240501222827639

8. 識別精確率

image-20240501222921016

9. 反饋率

image-20240501222942872

10. ROC 曲線

image-20240501223133656

11. 混淆矩陣

image-20240501223158052 image-20240501223329242

神經網路那個例子裡的結果就是混淆矩陣,看一下就明白了。

5.1.7 Python 分類預測模型特點

image-20240501223556624

相關文章