線性迴歸模型在機器學習中應用廣泛,其可解釋性對於理解預測結果至關重要。本篇著重於提升線性模型的可靠性和解讀能力,涵蓋資料預處理、模型訓練、多重共線性處理、模型評估以及模型解釋等方面。首先,透過相關係數矩陣分析變數間的線性關係,並進行統計顯著性檢驗。接著,將類別變數轉換為虛擬變數,避免多重共線性問題。然後,使用訓練集和測試集評估模型效能,並透過 VIF 檢測和處理多重共線性。最後,分析模型係數、計算調整後的 R 平方值和 p 值,深入理解各個特徵對目標變數的影響,並使用 MAPE 和 MSSE 等指標評估模型的預測誤差。
線性模型的可解釋性分析
在進行線性迴歸分析之前,瞭解變數之間的相關性是非常重要的。相關係數可以用來衡量兩個變數之間的線性關係強度。
相關係數矩陣的建立與分析
首先,我們需要計算資料集中各個數值變數之間的相關係數。相關係數的取值範圍在-1到1之間,其中1表示完全正相關,-1表示完全負相關,0表示無相關性。
corrl = df[['Price','Age','Odometer','mileage','engineCC','powerBhp']].corr()
corrl.style.background_gradient(cmap='coolwarm')
內容解密:
df[['Price','Age','Odometer','mileage','engineCC','powerBhp']]:選取資料集中與價格相關的數值變數。.corr():計算這些變數之間的相關係數矩陣。.style.background_gradient(cmap='coolwarm'):使用漸層色彩來視覺化相關係數矩陣,正相關以暖色表示,負相關以冷色表示。
相關係數的統計顯著性檢驗
為了驗證相關係數是否具有統計顯著性,我們可以使用統計檢驗方法。
np.where((df[['Price','Age','Odometer','mileage','engineCC','powerBhp']]).corr()>0.6,'Yes','No')
內容解密:
(df[['Price','Age','Odometer','mileage','engineCC','powerBhp']]).corr():計算相關係數矩陣。np.where(..., >0.6, 'Yes', 'No'):找出相關係數大於0.6的變數對,並標記為’Yes’,否則標記為’No’。
虛擬變數的建立
由於資料集中存在類別變數(Location、FuelType、Transmission、OwnerType),我們需要將這些變數轉換為虛擬變數,以便進行線性迴歸分析。
Location_dummy = pd.get_dummies(df.Location, prefix='Location', drop_first=True)
FuelType_dummy = pd.get_dummies(df.FuelType, prefix='FuelType', drop_first=True)
Transmission_dummy = pd.get_dummies(df.Transmission, prefix='Transmission', drop_first=True)
OwnerType_dummy = pd.get_dummies(df.OwnerType, prefix='OwnerType', drop_first=True)
combine_all_dummy = pd.concat([df, Location_dummy, FuelType_dummy, Transmission_dummy, OwnerType_dummy], axis=1)
clean_df = combine_all_dummy.drop(columns=['Make', 'Location', 'FuelType', 'Transmission', 'OwnerType', 'Mileage', 'EngineCC', 'PowerBhp'])
內容解密:
pd.get_dummies():將類別變數轉換為虛擬變數。prefix引數:指定虛擬變數的字首。drop_first=True:丟棄第一個類別,以避免多重共線性。pd.concat():將原始資料集與虛擬變數合併。drop(columns=...):丟棄原始的類別變數和不需要的變數。
線性迴歸模型的建立與評估
建立線性迴歸模型之前,需要將資料集分割為訓練集和測試集。
data_train, data_test = train_test_split(clean_df, test_size=0.25, random_state=1234)
XTrain = np.array(data_train.iloc[:, 0:(clean_df.shape[1]-1)])
YTrain = np.array(data_train['Price'])
XTest = np.array(data_test.iloc[:, 0:(clean_df.shape[1]-1)])
YTest = np.array(data_test['Price'])
reg = linear_model.LinearRegression()
reg.fit(XTrain, YTrain)
print('Coefficients: \n', np.round(reg.coef_, 4))
print('Intercept: \n', np.round(reg.intercept_, 0))
內容解密:
train_test_split():將資料集分割為訓練集和測試集。linear_model.LinearRegression():建立線性迴歸模型。reg.fit():訓練模型。reg.coef_:取得模型的係數。reg.intercept_:取得模型的截距。
模型評估與可解釋性分析
模型的評估結果顯示,訓練準確度和測試準確度均為100%,但模型的係數均為0,截距為1,表明模型存在問題。這時就需要使用可解釋性AI技術來瞭解模型出了什麼問題。
reg.score(XTrain, YTrain)
reg.score(XTest, YTest)
內容解密:
reg.score():計算模型的R平方值。
使用統計API進行驗證
為了驗證結果,我們可以使用統計API來進行驗證。
import statsmodels.api as sm
y = np.array(clean_df['Price'])
xx = np.array(clean_df.drop('Price', axis=1))
sm.OLS(y, xx).fit().summary()
內容解密:
sm.OLS():建立普通最小二乘法模型。.fit():訓練模型。.summary():輸出模型的摘要資訊。
線性模型的可解釋性分析
線性迴歸模型是機器學習中最基礎也是最重要的模型之一,其可解釋性對於理解模型的預測結果至關重要。在本章中,我們將探討線性模型的可解釋性,並透過具體的例項來分析如何提升模型的可靠性和解讀能力。
OLS 迴歸結果分析
首先,我們使用 statsmodels 套件進行 OLS(普通最小二乘法)迴歸分析,並輸出迴歸結果的摘要。
y = clean_df['Price']
x = clean_df.drop(['Price'], axis=1)
mod = sm.OLS(y, x)
results = mod.fit()
print(results.summary())
內容解密:
- 使用
sm.OLS建立 OLS 迴歸模型,其中y是因變數(目標變數),x是自變數(特徵變數)。 results.summary()輸出迴歸分析的詳細結果,包括 R 平方值、係數、標準誤差等重要指標。- R 平方值為 1.0,表示模型能夠完美解釋因變數的變異,但這通常不現實,可能存在多重共線性問題。
多重共線性的檢測與處理
多重共線性是指多個自變數之間存在高度相關性,這會影響模型的穩定性和解釋力。我們使用 VIF(變異數膨脹因子)來檢測多重共線性。
from statsmodels.stats.outliers_influence import variance_inflation_factor
def calc_vif(X):
vif = pd.DataFrame()
vif["variables"] = X.columns
vif["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
return vif
X = clean_df.drop('Price', axis=1)
vif_df = calc_vif(X)
vif_df.sort_values(by='VIF', ascending=False).head()
內容解密:
variance_inflation_factor函式用於計算每個特徵的 VIF 值。- VIF 值大於 10 表示存在嚴重的多重共線性,需要對相關變數進行處理。
- 透過逐步刪除高 VIF 值的變數,重複計算 VIF,直到所有變數的 VIF 值均小於 10。
模型最佳化與評估
經過多重共線性處理後,我們重新訓練模型並評估其效能。
y = clean_df['Price']
x = clean_df.drop(['Price', 'engineCC', 'FuelType_Diesel', 'mileage'], axis=1)
xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.25, random_state=1234)
new_model = LinearRegression()
new_model.fit(xtrain, ytrain)
print(new_model.score(xtrain, ytrain))
print(new_model.score(xtest, ytest))
內容解密:
- 刪除高 VIF 值的變數後,重新進行訓練集和測試集的劃分。
- 使用
LinearRegression重新訓練模型,並計算訓練集和測試集上的 R 平方值。 - 最終模型的訓練集 R 平方值為 0.70,測試集 R 平方值為 0.69,表示模型具有良好的泛化能力。
模型係數分析
最後,我們分析模型的係數,以瞭解各個特徵對目標變數的影響。
resultsDF = pd.DataFrame()
resultsDF['Variables'] = pd.Series(xtrain.columns)
resultsDF['coefficients'] = pd.Series(np.round(new_model.coef_, 2))
resultsDF.sort_values(by='coefficients', ascending=False)
內容解密:
- 將模型的係數與對應的變數名稱整理成 DataFrame。
- 按係數大小排序,以直觀地觀察哪些變數對目標變數有較大的正向或負向影響。
調整後的 R 平方值計算
為了更準確地評估模型的擬合優度,我們計算調整後的 R 平方值。
def AdjustedRSquare(model, X, Y):
YHat = model.predict(X)
n, k = X.shape
# 公式實作
內容解密:
- 調整後的 R 平方值考慮了模型中變數的數量,能夠更真實地反映模型的解釋能力。
- 實作調整後的 R 平方值計算函式,有助於更全面地評估模型效能。
透過上述步驟,我們不僅提高了線性模型的可靠性,也增強了對模型結果的解讀能力。這對於實際應用中的決策支援具有重要意義。
線性模型的解釋能力
調整後的R平方值計算函式
在評估線性迴歸模型的表現時,R平方值($R^2$)是一個重要的指標。然而,$R^2$會隨著模型中預測變數的增加而增加,即使這些變數並不具有統計顯著性。因此,引入了調整後的R平方值($adjR^2$)來糾正這個問題。
def AdjustedRSquare(model, X, Y):
YHat = model.predict(X)
n, k = X.shape
sse = np.sum(np.square(YHat - Y), axis=0) # 殘差平方和
sst = np.sum(np.square(Y - np.mean(Y)), axis=0) # 總平方和
R2 = 1 - sse / sst # R平方值
adjR2 = R2 - (1 - R2) * (float(k) / (n - k - 1)) # 調整後的R平方值
return adjR2, R2
內容解密:
YHat = model.predict(X):使用模型對輸入資料X進行預測,得到預測值YHat。n, k = X.shape:取得樣本數量n和特徵數量k。sse = np.sum(np.square(YHat - Y), axis=0):計算殘差平方和,即預測值與實際值之間的差異的平方和。sst = np.sum(np.square(Y - np.mean(Y)), axis=0):計算總平方和,即實際值與其均值之間的差異的平方和。R2 = 1 - sse / sst:計算R平方值,表示模型能夠解釋的變異比例。adjR2 = R2 - (1 - R2) * (float(k) / (n - k - 1)):計算調整後的R平方值,對R平方值進行調整以考慮模型的複雜度。
計算p值的函式
p值是用於評估模型中每個預測變數統計顯著性的指標。
from scipy import stats
def ReturnPValue(model, X, Y):
YHat = model.predict(X)
n, k = X.shape
sse = np.sum(np.square(YHat - Y), axis=0)
x = np.hstack((np.ones((n, 1)), np.matrix(X)))
df = float(n - k - 1)
sampleVar = sse / df
sampleVarianceX = x.T * x
covarianceMatrix = linalg.sqrtm(sampleVar * sampleVarianceX.I)
se = covarianceMatrix.diagonal()[1:]
betasTstat = np.zeros(len(se))
for i in range(len(se)):
betasTstat[i] = model.coef_[i] / se[i]
betasPvalue = 1 - stats.t.cdf(abs(betasTstat), df)
return betasPvalue
內容解密:
YHat = model.predict(X):使用模型對輸入資料X進行預測,得到預測值YHat。sse = np.sum(np.square(YHat - Y), axis=0):計算殘差平方和。x = np.hstack((np.ones((n, 1)), np.matrix(X))):在資料矩陣X前新增一列全為1的列,以表示截距項。df = float(n - k - 1):計算自由度。sampleVar = sse / df:計算樣本變異數。covarianceMatrix = linalg.sqrtm(sampleVar * sampleVarianceX.I):計算迴歸係數的協方差矩陣。betasTstat = model.coef_ / se:計算迴歸係數的t統計量。betasPvalue = 1 - stats.t.cdf(abs(betasTstat), df):計算迴歸係數的p值。
模型評估與變數篩選
透過計算調整後的R平方值和p值,可以評估模型的表現和篩選具有統計顯著性的變數。
resultsDF['p_value'] = pd.Series(np.round(ReturnPValue(new_model, xtrain, ytrain), 2))
resultsDF.sort_values(by='coefficients', ascending=False)
最終模型
在移除多重共線性變數和統計上不顯著的變數後,模型的準確度仍然保持在訓練集上的70%和測試集上的69%左右。
模型解釋能力
線性迴歸模型的優勢在於其簡單性和線性,使得模型解釋變得容易。透過檢視模型的beta係數,可以瞭解每個變數對預測結果的影響。
reg.adjR2, reg.R2 = AdjustedRSquare(new_model, xtrain, ytrain)
print(reg.adjR2, reg.R2)
此圖示說明模型的擬合優度。
錯誤指標計算函式
def ErrorMetric(model, X, Y):
Yhat = model.predict(X)
MAPE = np.mean(abs(Y - Yhat) / Y) * 100
MSSE = np.mean(np.square(Y - Yhat))
Error = sns.distplot(Y - Yhat)
return MAPE, MSSE, Error
內容解密:
Yhat = model.predict(X):使用模型對輸入資料X進行預測,得到預測值Yhat。MAPE = np.mean(abs(Y - Yhat) / Y) * 100:計算平均絕對百分比誤差,表示預測誤差的平均大小。MSSE = np.mean(np.square(Y - Yhat)):計算均方誤差,表示預測誤差的平方的平均值。Error = sns.distplot(Y - Yhat):繪製殘差的分佈圖,用於檢查殘差是否呈現正態分佈。