返回文章列表

迴歸分析預測應用與因子變數處理

本文探討迴歸分析在預測中的應用,特別關注因子變數的處理技巧。從預測區間和信賴區間的比較,到虛擬變數的建立和解釋,以及多重共線性和混雜變數的處理,文章提供了全面的,並輔以 R 和 Python 的程式碼範例。

機器學習 資料科學

迴歸分析除了統計推論外,在機器學習領域也扮演著預測模型的角色。預測模型的重點在於準確預測新資料,而非解釋變數間的因果關係。因此,理解預測區間和信賴區間的差異至關重要。預測區間估計的是單個觀測值的範圍,而信賴區間估計的是平均值的範圍。針對因子變數,需要將其轉換為數值變數才能應用於迴歸模型。常用的方法是建立虛擬變數,將每個類別轉換為0或1的二元變數。處理多個水平的因子變數時,可以根據其對模型的影響進行分組或合併,例如郵遞區號可以根據房價分組。此外,還需注意多重共線性和混雜變數對模型的影響。多重共線性會導致係數估計不穩定,而混雜變數會造成虛假的相關性。

預測迴歸分析

迴歸分析在資料科學中的主要用途是進行預測。迴歸分析是一種古老且成熟的統計方法,它帶有一些與其傳統角色相關的負擔,這些負擔更適用於解釋性建模,而非預測。

預測迴歸分析的關鍵術語

  • 預測區間:圍繞單個預測值的不確定性區間。
  • 外推:將模型擴充套件到超出用於擬合它的資料範圍。

外推的危險性

迴歸模型不應被用於外推超出資料範圍(暫且不考慮迴歸在時間序列預測中的使用)。模型僅對具有足夠值的預測變數有效(即使有足夠的資料,也可能存在其他問題——請參見“迴歸診斷”第176頁)。一個極端的例子是,如果使用 model_lm 來預測一塊5,000平方英尺的空地的價值。在這種情況下,所有與建築物相關的預測變數都將具有0的值,而迴歸方程將得出一個荒謬的預測結果:-521,900 + 5,000 × -0.0605 = -$522,202。為什麼會發生這種情況?資料中只包含有建築物的地塊——沒有與空地相對應的記錄。因此,模型沒有資訊來告訴它如何預測空地的銷售價格。

信賴區間和預測區間

統計學的大部分內容涉及理解和衡量變異性(不確定性)。迴歸輸出中報告的t統計量和p值以一種正式的方式處理了這一點,這有時對變數選擇很有用(請參見“評估模型”第153頁)。更有用的指標是圍繞迴歸係數和預測值的置信區間。理解這一點的一種簡單方法是透過自助法(有關一般自助程式的更多詳細資訊,請參見“自助法”第61頁)。

生成迴歸係數信賴區間的自助演算法

  1. 將每一行(包括結果變數)視為一張單獨的“票”,並將所有n張票放入一個盒子中。
  2. 隨機抽取一張票,記錄其值,並將其放回盒子中。
  3. 重複步驟2 n次;現在你有了一個自助重抽樣。
  4. 對自助樣本進行迴歸,並記錄估計的係數。
  5. 重複步驟2到4,比如說1,000次。
  6. 現在你有1,000個自助法值對每個係數;為每個係數找到適當的百分位數(例如,90%信賴區間的第5和第95百分位數)。

你可以使用R中的Boot函式來生成實際的自助法信賴區間,或者簡單地使用根據公式的區間,這是R輸出的常規內容。概念上的含義和解釋是相同的,並且對於資料科學家來說並不是非常重要,因為它們關注的是迴歸係數。

預測區間的不確定性來源

圍繞預測值 $Y_i$ 的不確定性來自兩個來源:

  • 關於相關預測變數及其係數的不確定性(請參見前面的自助演算法)
  • 固有於個別資料點的額外誤差

建模個別資料點誤差

個別資料點誤差可以被認為是這樣的:即使我們確切知道迴歸方程是什麼(例如,如果我們有大量的記錄來擬合它),對於給定的一組預測值,實際結果值也會有所不同。例如,幾棟房屋——每棟都有8個房間、6,500平方英尺的地塊、3個浴室和一個地下室——可能具有不同的價值。我們可以使用與擬合值殘差來建模這種個別誤差。

用於建模迴歸模型誤差和個別資料點誤差的自助演算法

  1. 從資料中抽取一個自助樣本(前面已經詳細說明)。
  2. 擬合迴歸,並預測新的值。
  3. 從原始迴歸擬閤中隨機抽取一個殘差,將其新增到預測值中,並記錄結果。
  4. 重複步驟1到3,比如說1,000次。
  5. 找到結果的第2.5和第97.5百分位數。

關鍵概念

  • 超出資料範圍的外推可能會導致錯誤。
  • 信賴區間量化了圍繞迴歸係數的不確定性。
  • 預測區間量化了個別預測中的不確定性。
  • 大多數軟體,包括R,預設或指定輸出中會產生預測和信賴區間,使用公式。
  • 自助法也可以用來產生預測和信賴區間;解釋和想法是相同的。

應該使用預測區間還是信賴區間?

預測區間與單個值的不確定性相關,而信賴區間與從多個值計算得出的平均值或其他統計量相關。因此,對於相同的值,預測區間通常比信賴區間寬得多。我們在自助模型中透過選擇一個單獨的殘差新增到預測值來建模這個個別值誤差。

迴歸中的因子變數

因子變數,也稱為分類別變數,採用有限數量的離散值。例如,貸款目的可以是“債務合併”、“婚禮”、“汽車”等。二元(是/否)變數,也稱為指示變數,是因子變數的特殊情況。迴歸需要數字輸入,因此因子變數需要被重新編碼以在模型中使用。最常見的方法是將一個變數轉換為一組二元虛擬變數。

虛擬變數的作用

虛擬變數的引入使得迴歸模型能夠處理分類別資料,從而擴充套件了迴歸分析的應用範圍。

# 建立虛擬變數的範例程式碼
data$loan_purpose_dummy <- ifelse(data$loan_purpose == "debt_consolidation", 1, 0)

內容解密:

上述程式碼展示瞭如何為貸款目的建立虛擬變數。如果貸款目的是“債務合併”,則虛擬變數的值為1,否則為0。這樣,迴歸模型就可以處理原本是分類別的貸款目的變數。

因子變數在迴歸分析中的應用

在迴歸分析中,常常需要處理具有多個類別的因子變數(factor variables)。這些變數不能直接用於迴歸模型,需要透過適當的編碼(coding)轉換為數值變數。本文將介紹因子變數的編碼方法及其在迴歸分析中的應用。

虛擬變數(Dummy Variables)

虛擬變數是透過重新編碼因子變數而得到的二元(0-1)變數,用於迴歸模型或其他統計模型。虛擬變數的建立是透過為每個因子水平建立一個二元變數來實作的。

R 語言實作

在 R 語言中,可以使用 model.matrix 函式將因子變數轉換為虛擬變數。例如,對於 King County 房價資料中的 PropertyType 變數:

prop_type_dummies <- model.matrix(~PropertyType -1, data=house)
head(prop_type_dummies)

輸出的結果如下:

  PropertyTypeMultiplex PropertyTypeSingle Family PropertyTypeTownhouse
1                     1                           0                      0
2                     0                           1                      0
3                     0                           1                      0
4                     0                           1                      0
5                     0                           1                      0
6                     0                           0                      1

Python 語言實作

在 Python 中,可以使用 pandas 的 get_dummies 方法將類別變數轉換為虛擬變數:

pd.get_dummies(house['PropertyType']).head()
pd.get_dummies(house['PropertyType'], drop_first=True).head()

虛擬變數的解釋

在迴歸模型中,虛擬變數的係數表示相對於參考水平(reference level)的變化。例如,在 King County 房價資料中,PropertyType 的參考水平是 Multiplex,其他水平的係數表示相對於 Multiplex 的房價變化。

不同編碼方式的比較

除了參考編碼(reference coding)外,還有其他編碼方式,如偏差編碼(deviation coding)和多項式編碼(polynomial coding)。偏差編碼比較每個水平與整體平均值,而多項式編碼適用於有序因子變數。

R 語言中的預設編碼方式

在 R 中,預設的編碼方式是參考編碼,可以透過 lm 函式實作:

lm(AdjSalePrice ~ SqFtTotLiving + SqFtLot + Bathrooms + 
   Bedrooms + BldgGrade + PropertyType, data=house)

Python 語言中的實作

在 Python 中,可以使用 get_dummies 方法並設定 drop_first=True 來實作參考編碼:

X = pd.get_dummies(house[predictors], drop_first=True)
house_lm_factor = LinearRegression()
house_lm_factor.fit(X, house[outcome])

具有多個水平的因子變數

當因子變數具有大量水平時,需要考慮是否保留所有水平或進行合併。例如,在 King County 房價資料中,郵遞區號(zip code)是一個具有多個水平的因子變數。

R 語言中的實作

在 R 中,可以使用 table 函式檢視郵遞區號的分佈:

table(house$ZipCode)

Python 語言中的實作

在 Python 中,可以使用 value_counts 方法檢視郵遞區號的分佈:

pd.DataFrame(house['ZipCode'].value_counts()).transpose()

迴歸分析中的因子變數處理與模型解釋

在迴歸分析中,處理因子變數(Factor Variables)是一項重要的任務。因子變數通常代表不同的類別或等級,需要被轉換成數值變數才能在迴歸模型中使用。本文將討論如何處理因子變數以及如何解釋迴歸方程。

處理具有多個水平的因子變數

當一個因子變數具有多個不同的水平(levels)時,通常需要將其轉換成多個虛擬變數(Dummy Variables)以便在迴歸模型中使用。例如,如果一個因子變數有 $P$ 個不同的水平,則可以使用 $P-1$ 個虛擬變數來表示。

程式碼範例:使用 dplyr 套件處理因子變數

zip_groups <- house %>%
  mutate(resid = residuals(house_lm)) %>%
  group_by(ZipCode) %>%
  summarize(med_resid = median(resid),
            cnt = n()) %>%
  arrange(med_resid) %>%
  mutate(cum_cnt = cumsum(cnt),
         ZipGroup = ntile(cum_cnt, 5))
house <- house %>%
  left_join(select(zip_groups, ZipCode, ZipGroup), by='ZipCode')

內容解密:

  1. 計算殘差:首先對每個觀測值計算殘差,即實際值與預測值之間的差異。
  2. 分組計算中位數殘差:按照 ZipCode 分組,並計算每組的中位數殘差和觀測值的數量。
  3. 排序和分組:根據中位數殘差排序,並使用 ntile 函式將郵政編碼分成五組。
  4. 合併資料:將分組結果與原始資料集合併。

程式碼範例:使用 pandas 套件處理因子變數

zip_groups = pd.DataFrame([
    *pd.DataFrame({
        'ZipCode': house['ZipCode'],
        'residual': house[outcome] - house_lm.predict(house[predictors]),
    })
    .groupby(['ZipCode'])
    .apply(lambda x: {
        'ZipCode': x.iloc[0,0],
        'count': len(x),
        'median_residual': x.residual.median()
    })
]).sort_values('median_residual')
zip_groups['cum_count'] = np.cumsum(zip_groups['count'])
zip_groups['ZipGroup'] = pd.qcut(zip_groups['cum_count'], 5, labels=False, retbins=False)
to_join = zip_groups[['ZipCode', 'ZipGroup']].set_index('ZipCode')
house = house.join(to_join, on='ZipCode')
house['ZipGroup'] = house['ZipGroup'].astype('category')

內容解密:

  1. 計算殘差:首先計算每個觀測值的殘差。
  2. 分組計算:按照 ZipCode 分組,並計算每組的中位數殘差和觀測值的數量。
  3. 排序和累積計數:根據中位數殘差排序,並計算累積計數。
  4. 分組:使用 qcut 函式將郵政編碼分成五組。
  5. 合併資料:將分組結果與原始資料集合併,並將 ZipGroup 轉換為類別型變數。

有序因子變數

某些因子變數具有內在的順序,例如貸款等級(A、B、C 等)。在這種情況下,可以將其轉換為數值變數以保留其順序資訊。

表格範例:建築等級及其對應的數值

描述
1簡易房
2次標準
5普通
10非常好
12豪華
13華廈

解釋迴歸方程

在資料科學中,迴歸分析的主要用途是預測某個因變數。然而,瞭解迴歸方程本身對於理解預測變數與因變數之間的關係也非常重要。

相關術語

  • 相關變數:當預測變數之間高度相關時,很難解釋個別係數的意義。
  • 多重共線性:當預測變數之間存在完全或近乎完全的相關性時,迴歸分析可能會不穩定或無法計算。
  • 混淆變數:遺漏了重要的預測變數可能會導致迴歸方程中出現虛假的關係。
  • 主效應:預測變數與因變數之間的關係,不考慮其他變數的影響。
  • 互動作用:兩個或多個預測變數與因變數之間的相互依賴關係。

相關預測變數

在多元迴歸分析中,預測變數之間通常存在相關性。這使得解釋個別係數變得困難。

程式碼範例:查看迴歸係數

step_lm$coefficients

內容解密:

輸出迴歸模型的係數,以瞭解各個預測變數對因變數的影響。

迴歸方程的解釋

在迴歸分析中,係數的解釋是非常重要的。係數代表了當其他變數保持不變時,某個變數變化一個單位對結果變數的影響。然而,在實際應用中,變數之間的相關性可能會使得係數的解釋變得困難。

相關變數的問題

在房價預測的例子中,變數如臥室數量、房屋大小和浴室數量之間存在相關性。這種相關性使得係數的解釋變得困難。例如,在原始模型中,臥室數量的係數是負的,這意味著增加臥室數量會降低房價。這看起來似乎不合理,但實際上是由於房屋大小是驅動房價的主要因素,而臥室數量只是房屋大小的代理變數。

print(f'截距:{best_model.intercept_:.3f}')
print('係數:')
for name, coef in zip(best_variables, best_model.coef_):
    print(f' {name}: {coef}')

內容解密:

  • best_model.intercept_:迴歸模型的截距,代表當所有預測變數為0時的結果變數值。
  • best_model.coef_:迴歸模型的係數,代表每個預測變數對結果變數的影響。
  • zip(best_variables, best_model.coef_):將變數名稱與對應的係數配對,以便輸出。

當我們移除與房屋大小相關的變數(如SqFtTotLivingSqFtFinBasementBathrooms)後,重新擬合模型,發現臥室數量的係數變成了正值。這表明,在控制其他變數後,臥室數量對房價有正向影響。

predictors = ['Bedrooms', 'BldgGrade', 'PropertyType', 'YrBuilt']
outcome = 'AdjSalePrice'
X = pd.get_dummies(house[predictors], drop_first=True)
reduced_lm = LinearRegression()
reduced_lm.fit(X, house[outcome])

內容解密:

  • pd.get_dummies(house[predictors], drop_first=True):將分類別變數轉換為虛擬變數,並刪除第一個虛擬變數以避免多重共線性。
  • LinearRegression():建立一個線性迴歸模型。
  • reduced_lm.fit(X, house[outcome]):使用新的預測變數擬合線性迴歸模型。

多重共線性

當兩個或多個預測變數之間存在高度相關性時,就會出現多重共線性。這種情況下,迴歸係數的估計值可能會變得不穩定。為瞭解決這個問題,我們需要移除冗餘的變數,直到多重共線性消失。

混雜變數

另一個問題是混雜變數,即未被納入模型的重要變數。例如,在房價預測中,地點是一個非常重要的因素,但原始模型中沒有包含這個變數。透過新增一個代表地點的變數ZipGroup,我們發現模型的解釋能力大大提高。

predictors = ['SqFtTotLiving', 'SqFtLot', 'Bathrooms', 'Bedrooms',
              'BldgGrade', 'PropertyType', 'ZipGroup']
outcome = 'AdjSalePrice'
X = pd.get_dummies(house[predictors], drop_first=True)
confounding_lm = LinearRegression()
confounding_lm.fit(X, house[outcome])
print(f'截距:{confounding_lm.intercept_:.3f}')
print('係數:')
for name, coef in zip(X.columns, confounding_lm.coef_):
    print(f' {name}: {coef}')

內容解密:

  • ZipGroup:代表地點的變數,將郵政編碼分組為五個等級,從最便宜到最昂貴。
  • confounding_lm.fit(X, house[outcome]):使用包含地點變數的預測變數擬合線性迴歸模型。

透過新增地點變數,我們發現模型的係數更加合理,例如浴室數量的係數現在是正值。這個例子說明瞭在迴歸分析中考慮混雜變數的重要性。