學(xué)原理到Python實(shí)戰(zhàn)的完整指南)
1. 項(xiàng)目概述從“湊合”到“最優(yōu)”的數(shù)學(xué)藝術(shù)干了這么多年數(shù)據(jù)分析我處理過(guò)無(wú)數(shù)散亂的數(shù)據(jù)點(diǎn)。很多時(shí)候客戶扔過(guò)來(lái)一堆X和Y問(wèn)你“這倆玩意兒到底啥關(guān)系”畫個(gè)散點(diǎn)圖點(diǎn)倒是都在一條直線附近晃悠但真要你畫一條線穿過(guò)去怎么畫才算“最對(duì)”憑感覺(jué)手繪一條那太不靠譜了。這時(shí)候線性最小二乘就是那個(gè)讓你從“大概齊”走向“最合理”的數(shù)學(xué)工具箱。它不是什么高深莫測(cè)的黑科技而是一個(gè)解決“如何找到一條直線讓它最好地代表一堆數(shù)據(jù)點(diǎn)”這個(gè)問(wèn)題的標(biāo)準(zhǔn)答案。簡(jiǎn)單說(shuō)線性最小二乘的核心任務(wù)就是給一組看上去有線性趨勢(shì)的數(shù)據(jù)(x1, y1), (x2, y2), ..., (xn, yn)找到一條直線y ax b。這里的“最好”有一個(gè)非常直觀的數(shù)學(xué)定義讓所有數(shù)據(jù)點(diǎn)到這條直線的垂直距離的平方和最小。為什么是平方和而不是直接加距離因?yàn)榫嚯x有正有負(fù)直接相加會(huì)相互抵消無(wú)法真實(shí)反映總的偏差而平方既能消除正負(fù)號(hào)的影響又在數(shù)學(xué)上具有良好的性質(zhì)可導(dǎo)便于我們求出那個(gè)唯一的、最優(yōu)的解。這個(gè)方法的應(yīng)用場(chǎng)景無(wú)處不在。從金融里預(yù)測(cè)股票趨勢(shì)雖然不準(zhǔn)但模型簡(jiǎn)單到工業(yè)上校準(zhǔn)傳感器比如溫度傳感器的讀數(shù)與真實(shí)溫度的關(guān)系再到日常的廣告點(diǎn)擊率預(yù)估、用戶行為分析只要是涉及兩個(gè)或多個(gè)變量之間線性關(guān)系的建模和預(yù)測(cè)線性最小二乘往往是工程師和科學(xué)家們上手的第一選擇。它構(gòu)建的模型透明、計(jì)算高效、原理易懂是機(jī)器學(xué)習(xí)里線性回歸的基石也是無(wú)數(shù)更復(fù)雜模型的起點(diǎn)。接下來(lái)我就把這套方法的里里外外、實(shí)操細(xì)節(jié)和踩過(guò)的坑給你徹底拆解明白。2. 核心原理與數(shù)學(xué)拆解為什么“平方和最小”就是最優(yōu)2.1 問(wèn)題形式化從直覺(jué)到方程我們面對(duì)的數(shù)據(jù)集可以看作是一系列觀測(cè)點(diǎn)。假設(shè)我們認(rèn)為y和x之間存在線性關(guān)系即y ≈ β? β?x。這里β?是截距β?是斜率也就是我們要求解的未知參數(shù)。對(duì)于第i個(gè)數(shù)據(jù)點(diǎn)(x_i, y_i)我們用模型預(yù)測(cè)的值是?_i β? β?x_i而實(shí)際觀測(cè)值是y_i。那么預(yù)測(cè)的誤差或稱殘差就是e_i y_i - ?_i y_i - (β? β?x_i)。線性最小二乘的目標(biāo)就是找到一組β?和β?使得所有數(shù)據(jù)點(diǎn)的殘差平方和RSS, Residual Sum of Squares最小RSS(β?, β?) Σ (y_i - β? - β?x_i)2其中求和i從1到n。注意這里選擇垂直距離即y方向上的誤差的平方隱含了一個(gè)重要假設(shè)我們認(rèn)為x是精確的、沒(méi)有誤差的或者誤差遠(yuǎn)小于y所有的隨機(jī)波動(dòng)和不確定性都體現(xiàn)在y的觀測(cè)值上。這在很多實(shí)驗(yàn)和觀測(cè)場(chǎng)景中是合理的比如固定溫度x測(cè)量材料長(zhǎng)度y。如果x也有顯著誤差則需要考慮更復(fù)雜的“總體最小二乘”等方法。2.2 求解過(guò)程求導(dǎo)與正規(guī)方程如何找到使RSS最小的β?和β?這是一個(gè)典型的多元函數(shù)求極值問(wèn)題。由于RSS是β?和β?的二次函數(shù)開口向上的拋物線其最小值點(diǎn)必然出現(xiàn)在偏導(dǎo)數(shù)為零的地方。我們對(duì)RSS分別關(guān)于β?和β?求偏導(dǎo)并令其等于零?RSS/?β? -2 Σ (y_i - β? - β?x_i) 0?RSS/?β? -2 Σ [x_i (y_i - β? - β?x_i)] 0整理這兩個(gè)方程我們得到所謂的正規(guī)方程n β? (Σx_i) β? Σy_i(Σx_i) β? (Σx_i2) β? Σx_i y_i這是一個(gè)關(guān)于β?和β?的二元一次方程組。解這個(gè)方程組就能得到最小二乘估計(jì)的顯式公式β? [n Σ(x_i y_i) - (Σx_i)(Σy_i)] / [n Σ(x_i2) - (Σx_i)2]β? (Σy_i)/n - β? * (Σx_i)/n ? - β? x?其中x?和?分別是x和y的樣本均值。這個(gè)結(jié)果非常優(yōu)美最優(yōu)直線的斜率β?由數(shù)據(jù)的協(xié)方差結(jié)構(gòu)決定而截距β?則確保直線穿過(guò)數(shù)據(jù)的中心點(diǎn)(x?, ?)。2.3 幾何視角與矩陣形式對(duì)于理解多元線性回歸多個(gè)自變量和編程實(shí)現(xiàn)矩陣形式至關(guān)重要。我們將數(shù)據(jù)表示為矩陣y [y1, y2, ..., yn]?n×1列向量X [ [1, x1], [1, x2], ..., [1, xn] ]n×2設(shè)計(jì)矩陣第一列全1用于估計(jì)截距β [β?, β?]?2×1參數(shù)向量那么模型可以寫成y ≈ Xβ殘差向量e y - Xβ。最小二乘的目標(biāo)變?yōu)樽钚』瘹埐钕蛄康臍W幾里得范數(shù)平方RSS(β) ||y - Xβ||2 (y - Xβ)?(y - Xβ)。通過(guò)矩陣求導(dǎo)或幾何投影可以推導(dǎo)出正規(guī)方程的矩陣形式(X?X) β X?y。當(dāng)X?X可逆時(shí)最小二乘解為β? (X?X)?1 X?y。幾何解釋尋找最優(yōu)參數(shù)β?本質(zhì)上是在尋找由X的列向量所張成的列空間中的一個(gè)向量Xβ?使得這個(gè)向量與觀測(cè)向量y的歐幾里得距離最短。Xβ?正是y在X列空間上的正交投影。殘差向量e y - Xβ?垂直于整個(gè)列空間。這個(gè)視角將最小二乘從一個(gè)優(yōu)化問(wèn)題升華為了一個(gè)清晰的幾何投影問(wèn)題對(duì)于理解模型的擬合與殘差性質(zhì)非常有幫助。3. 從零實(shí)現(xiàn)與代碼實(shí)操不只是調(diào)個(gè)庫(kù)理解原理后自己動(dòng)手實(shí)現(xiàn)一遍是加深印象的最好方式。我們會(huì)用Python從最基礎(chǔ)的公式實(shí)現(xiàn)再到利用NumPy的矩陣運(yùn)算最后與scikit-learn的結(jié)果進(jìn)行對(duì)比驗(yàn)證。3.1 基礎(chǔ)公式法實(shí)現(xiàn)這是最直接的方式完全按照我們推導(dǎo)出的顯式公式進(jìn)行計(jì)算。優(yōu)點(diǎn)是邏輯清晰易于理解每一步。import numpy as np def simple_linear_regression(x, y): 根據(jù)顯式公式計(jì)算簡(jiǎn)單線性回歸的斜率和截距。 參數(shù): x: 自變量數(shù)組 y: 因變量數(shù)組 返回: beta_1: 斜率 beta_0: 截距 n len(x) if n ! len(y): raise ValueError(x和y的長(zhǎng)度必須相同) # 計(jì)算必要的中間量 sum_x np.sum(x) sum_y np.sum(y) sum_xy np.sum(x * y) sum_x2 np.sum(x ** 2) # 計(jì)算斜率 beta_1 numerator n * sum_xy - sum_x * sum_y denominator n * sum_x2 - sum_x ** 2 if abs(denominator) 1e-10: # 防止除零錯(cuò)誤 raise ValueError(分母接近零x的取值可能無(wú)方差無(wú)法計(jì)算斜率。) beta_1 numerator / denominator # 計(jì)算截距 beta_0 beta_0 (sum_y - beta_1 * sum_x) / n # 等價(jià)于 beta_0 np.mean(y) - beta_1 * np.mean(x) return beta_0, beta_1 # 示例數(shù)據(jù) x np.array([1, 2, 3, 4, 5]) y np.array([2.1, 2.9, 4.2, 5.1, 5.8]) beta_0, beta_1 simple_linear_regression(x, y) print(f手動(dòng)公式計(jì)算: 截距 beta_0 {beta_0:.4f}, 斜率 beta_1 {beta_1:.4f}) print(f擬合直線: y {beta_0:.4f} {beta_1:.4f} * x)實(shí)操心得在實(shí)現(xiàn)公式時(shí)一定要警惕數(shù)值穩(wěn)定性問(wèn)題。當(dāng)數(shù)據(jù)量很大或x的取值范圍很廣時(shí)直接計(jì)算sum_x2和sum_x**2可能導(dǎo)致大數(shù)吃小數(shù)或精度損失。一個(gè)更穩(wěn)健的做法是使用“校正和”公式但為了初次理解的清晰性我們這里使用最直接的公式。在生產(chǎn)環(huán)境中更推薦使用矩陣法或經(jīng)過(guò)數(shù)值優(yōu)化的庫(kù)。3.2 矩陣法實(shí)現(xiàn)對(duì)于簡(jiǎn)單線性回歸矩陣法有點(diǎn)“殺雞用牛刀”但這是通向多元線性回歸的必經(jīng)之路也能讓我們更好地理解np.linalg.lstsq等函數(shù)背后的邏輯。def matrix_linear_regression(x, y): 使用矩陣運(yùn)算求解線性最小二乘。 n len(x) # 構(gòu)建設(shè)計(jì)矩陣 X第一列為1對(duì)應(yīng)截距項(xiàng) X np.column_stack((np.ones(n), x)) # 形狀 (n, 2) # 求解正規(guī)方程 (X^T X) beta X^T y # 使用 np.linalg.solve 直接解線性方程組比求逆更穩(wěn)定高效 XT_X X.T X # 矩陣乘法 XT_y X.T y # 解方程 XT_X * beta XT_y beta np.linalg.solve(XT_X, XT_y) # beta 包含 [beta_0, beta_1] return beta[0], beta[1] beta_0_m, beta_1_m matrix_linear_regression(x, y) print(f矩陣法計(jì)算: 截距 beta_0 {beta_0_m:.4f}, 斜率 beta_1 {beta_1_m:.4f})3.3 使用專業(yè)庫(kù)驗(yàn)證最后我們用業(yè)界標(biāo)準(zhǔn)的scikit-learn來(lái)驗(yàn)證我們手算的結(jié)果。這不僅是驗(yàn)證也是學(xué)習(xí)如何使用工業(yè)級(jí)工具。from sklearn.linear_model import LinearRegression # 注意sklearn 要求輸入的特征 X 是二維數(shù)組即使只有一列 X_sklearn x.reshape(-1, 1) # 變?yōu)?(n, 1) 的矩陣 model LinearRegression(fit_interceptTrue) # 默認(rèn)擬合截距 model.fit(X_sklearn, y) print(fsklearn 驗(yàn)證: 截距 {model.intercept_:.4f}, 斜率 {model.coef_[0]:.4f}) # 計(jì)算預(yù)測(cè)值并評(píng)估 y_pred model.predict(X_sklearn) # 計(jì)算殘差平方和 RSS rss np.sum((y - y_pred) ** 2) print(f殘差平方和 RSS {rss:.4f}) # 計(jì)算 R-squared from sklearn.metrics import r2_score r2 r2_score(y, y_pred) print(f決定系數(shù) R2 {r2:.4f})運(yùn)行上述三段代碼你會(huì)發(fā)現(xiàn)三種方法得到的beta_0和beta_1是完全一致的可能存在極微小的浮點(diǎn)數(shù)誤差這證實(shí)了我們推導(dǎo)和實(shí)現(xiàn)的正確性。sklearn不僅給出了參數(shù)還提供了R2等重要的模型評(píng)估指標(biāo)。4. 模型評(píng)估與診斷你的直線真的“好”嗎擬合出一條直線只是第一步更重要的是評(píng)估這條直線在多大程度上描述了數(shù)據(jù)以及模型假設(shè)是否成立。盲目相信擬合結(jié)果而不加診斷是數(shù)據(jù)分析中的大忌。4.1 關(guān)鍵評(píng)估指標(biāo)解讀殘差平方和這是我們優(yōu)化的目標(biāo)函數(shù)RSS。其絕對(duì)值大小依賴于y的量綱通常用于比較同一個(gè)數(shù)據(jù)集上不同模型的擬合好壞RSS越小越好但不宜跨數(shù)據(jù)集比較??偲椒胶蚑SS Σ (y_i - ?)2反映了因變量y自身的總波動(dòng)。決定系數(shù)R2 1 - RSS/TSS。這是最常用的指標(biāo)之一表示模型能夠解釋的y的方差比例。R2越接近1說(shuō)明模型對(duì)數(shù)據(jù)的擬合程度越好。注意R2高并不絕對(duì)意味著模型好。如果模型過(guò)度復(fù)雜例如用高階多項(xiàng)式去擬合線性數(shù)據(jù)R2也會(huì)很高但模型失去了預(yù)測(cè)新數(shù)據(jù)的能力過(guò)擬合。在簡(jiǎn)單線性回歸中R2也等于皮爾遜相關(guān)系數(shù)的平方。調(diào)整后R2當(dāng)模型包含多個(gè)自變量時(shí)R2會(huì)隨著變量增加而自然增大即使新增變量無(wú)關(guān)緊要。調(diào)整后R2引入了懲罰項(xiàng)更適用于模型比較。均方誤差與均方根誤差MSE RSS / nRMSE sqrt(MSE)。RMSE與y同量綱更直觀。例如預(yù)測(cè)房?jī)r(jià)RMSE為5萬(wàn)元可以理解為平均預(yù)測(cè)誤差在5萬(wàn)元左右。4.2 殘差分析檢驗(yàn)?zāi)P图僭O(shè)線性最小二乘的有效性建立在幾個(gè)關(guān)鍵假設(shè)之上線性關(guān)系、誤差項(xiàng)獨(dú)立、同方差性方差恒定、正態(tài)性。殘差圖是檢驗(yàn)這些假設(shè)最強(qiáng)大的工具。import matplotlib.pyplot as plt # 計(jì)算殘差 residuals y - y_pred # 創(chuàng)建殘差診斷圖 fig, axes plt.subplots(1, 3, figsize(15, 4)) # 1. 殘差 vs. 擬合值圖 axes[0].scatter(y_pred, residuals, alpha0.7) axes[0].axhline(y0, colorr, linestyle--) axes[0].set_xlabel(擬合值 (Fitted values)) axes[0].set_ylabel(殘差 (Residuals)) axes[0].set_title(殘差 vs. 擬合值) # 理想情況殘差隨機(jī)、均勻分布在0線兩側(cè)無(wú)任何趨勢(shì)或模式。 # 2. 殘差的正態(tài)概率圖 (Q-Q圖) from scipy import stats stats.probplot(residuals, distnorm, plotaxes[1]) axes[1].set_title(正態(tài)Q-Q圖) # 理想情況點(diǎn)大致分布在一條直線上說(shuō)明殘差近似正態(tài)分布。 # 3. 殘差 vs. 自變量X圖 axes[2].scatter(x, residuals, alpha0.7) axes[2].axhline(y0, colorr, linestyle--) axes[2].set_xlabel(自變量 X) axes[2].set_ylabel(殘差 (Residuals)) axes[2].set_title(殘差 vs. 自變量 X) # 理想情況同樣應(yīng)隨機(jī)分布在0線兩側(cè)。如果出現(xiàn)漏斗形或曲線形可能意味著異方差或非線性。 plt.tight_layout() plt.show()解讀“殘差 vs. 擬合值”圖如果圖中出現(xiàn)明顯的曲線模式如U型或倒U型則強(qiáng)烈暗示數(shù)據(jù)中存在非線性關(guān)系簡(jiǎn)單的直線模型可能不合適需要考慮加入x2等項(xiàng)。如果殘差的離散度隨著擬合值增大而增大或減小形成漏斗形則存在異方差性這會(huì)影響參數(shù)估計(jì)的標(biāo)準(zhǔn)誤和假設(shè)檢驗(yàn)的有效性。解讀Q-Q圖嚴(yán)重偏離直線尤其是尾部偏離說(shuō)明殘差分布與正態(tài)分布有差異。這對(duì)于小樣本下的精確假設(shè)檢驗(yàn)如t檢驗(yàn)有影響但對(duì)于大樣本下的參數(shù)估計(jì)中心極限定理通常能保證其穩(wěn)健性。解讀“殘差 vs. X”圖其信息常與“殘差 vs. 擬合值”圖類似因?yàn)閿M合值是x的線性函數(shù)。注意事項(xiàng)在實(shí)際項(xiàng)目中我經(jīng)常發(fā)現(xiàn)新手只關(guān)注R2而完全忽略殘差圖。這是一個(gè)巨大的誤區(qū)。一個(gè)R20.9的模型如果殘差圖顯示明顯的非線性那么這個(gè)模型對(duì)于預(yù)測(cè)和因果推斷可能是危險(xiǎn)且具有誤導(dǎo)性的。殘差分析是判斷模型是否“正確使用”了最小二乘法的守門員。5. 陷阱、擴(kuò)展與實(shí)戰(zhàn)考量5.1 常見陷阱與應(yīng)對(duì)策略多重共線性在多元回歸中突出當(dāng)自變量之間高度相關(guān)時(shí)X?X矩陣接近奇異導(dǎo)致參數(shù)估計(jì)(X?X)?1極其不穩(wěn)定方差巨大。雖然簡(jiǎn)單線性回歸只有一個(gè)自變量不存在此問(wèn)題但這是邁向多元回歸時(shí)必須警惕的。診斷計(jì)算方差膨脹因子。應(yīng)對(duì)剔除相關(guān)性高的變量、使用主成分回歸、嶺回歸等正則化方法。異常值與強(qiáng)影響點(diǎn)個(gè)別遠(yuǎn)離主體數(shù)據(jù)群的“離群點(diǎn)”會(huì)對(duì)最小二乘擬合產(chǎn)生不成比例的巨大影響因?yàn)樽钚《藘?yōu)化的是平方和異常值的殘差平方非常大模型會(huì)為了“討好”這個(gè)點(diǎn)而嚴(yán)重偏離主流趨勢(shì)。診斷計(jì)算庫(kù)克距離、杠桿值??梢暬Ⅻc(diǎn)圖通常也能一眼看出。應(yīng)對(duì)檢查首先檢查是否為數(shù)據(jù)錄入錯(cuò)誤。理解分析其是否代表一種特殊但有意義的機(jī)制。處理如果確定為無(wú)益的噪聲可以考慮使用穩(wěn)健回歸方法如 Huber回歸、RANSAC算法它們對(duì)異常值不敏感。非線性關(guān)系數(shù)據(jù)本質(zhì)上是曲線卻強(qiáng)行用直線擬合。這會(huì)導(dǎo)致系統(tǒng)性的擬合不足。診斷殘差圖呈現(xiàn)明顯的曲線模式觀察原始散點(diǎn)圖。應(yīng)對(duì)對(duì)變量進(jìn)行變換如對(duì)數(shù)、平方根變換或直接采用多項(xiàng)式回歸、樣條回歸等非線性模型。偽回歸當(dāng)x和y都是隨時(shí)間變化的非平穩(wěn)序列時(shí)即使它們毫無(wú)關(guān)系也可能僅僅因?yàn)槎加袝r(shí)間趨勢(shì)而計(jì)算出很高的R2。這在時(shí)間序列數(shù)據(jù)分析中非常常見。應(yīng)對(duì)對(duì)時(shí)間序列數(shù)據(jù)必須先進(jìn)行平穩(wěn)性檢驗(yàn)或協(xié)整檢驗(yàn)不能直接套用普通最小二乘。5.2 向多元線性回歸的平滑過(guò)渡簡(jiǎn)單線性回歸是多元線性回歸的特例。當(dāng)自變量從一個(gè)x擴(kuò)展到多個(gè)x1, x2, ..., xp時(shí)模型變?yōu)閥 β? β?x? β?x? ... β_p x_p ε所有的核心思想完全不變尋找參數(shù)β最小化殘差平方和RSS。矩陣形式y(tǒng) ≈ Xβ和正規(guī)方程(X?X)β X?y依然適用只是設(shè)計(jì)矩陣X從n×2變成了n×(p1)。求解依然可以用np.linalg.lstsq(X, y)或sklearn.linear_model.LinearRegression。# 多元線性回歸示例 import pandas as pd from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split # 生成模擬數(shù)據(jù)100個(gè)樣本3個(gè)有效特征 X, y make_regression(n_samples100, n_features3, noise10, random_state42) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) model_multi LinearRegression() model_multi.fit(X_train, y_train) print(f截距: {model_multi.intercept_:.4f}) print(f系數(shù): {model_multi.coef_}) # 在測(cè)試集上評(píng)估 r2_test model_multi.score(X_test, y_test) print(f測(cè)試集 R2: {r2_test:.4f})5.3 正則化應(yīng)對(duì)過(guò)擬合與共線性當(dāng)特征很多或特征間存在共線性時(shí)普通最小二乘估計(jì)的方差可能很大模型容易過(guò)擬合。正則化通過(guò)在損失函數(shù)中加入對(duì)參數(shù)大小的懲罰項(xiàng)來(lái)解決這個(gè)問(wèn)題。嶺回歸在RSS上增加L2懲罰項(xiàng)λ Σ β_j2。其解為β?_ridge (X?X λI)?1 X?y。它使參數(shù)估計(jì)向0收縮但不會(huì)等于0適用于處理共線性。Lasso回歸在RSS上增加L1懲罰項(xiàng)λ Σ |β_j|。它可以將某些不重要的特征的系數(shù)壓縮至精確為0從而實(shí)現(xiàn)特征選擇。from sklearn.linear_model import Ridge, Lasso from sklearn.preprocessing import StandardScaler # 重要使用正則化前通常需要對(duì)特征進(jìn)行標(biāo)準(zhǔn)化使懲罰項(xiàng)公平作用于所有系數(shù) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) ridge Ridge(alpha1.0) # alpha 是正則化強(qiáng)度 λ ridge.fit(X_train_scaled, y_train) print(嶺回歸系數(shù):, ridge.coef_) lasso Lasso(alpha0.1) lasso.fit(X_train_scaled, y_train) print(Lasso回歸系數(shù):, lasso.coef_) # 注意Lasso可能會(huì)產(chǎn)生稀疏系數(shù)部分為06. 工程實(shí)踐與高級(jí)話題6.1 數(shù)值計(jì)算穩(wěn)定性在實(shí)際計(jì)算中尤其是特征維度很高時(shí)直接求解正規(guī)方程(X?X)β X?y可能面臨數(shù)值不穩(wěn)定的問(wèn)題。因?yàn)閄?X可能是一個(gè)病態(tài)矩陣條件數(shù)很大求逆會(huì)放大誤差。更穩(wěn)健的解法是使用QR分解或奇異值分解QR分解將設(shè)計(jì)矩陣X分解為正交矩陣Q和上三角矩陣R即X QR。代入正規(guī)方程得到Rβ Q?y。由于R是上三角矩陣可以通過(guò)回代法穩(wěn)定求解。np.linalg.lstsq默認(rèn)使用的就是基于SVD或QR分解的算法。SVD分解將X分解為U Σ V?其中U和V是正交矩陣Σ是對(duì)角陣。最小二乘解可以優(yōu)雅地表示為β? V Σ? U? y其中Σ?是Σ的偽逆。SVD方法是最穩(wěn)定、最通用的即使X不是滿秩也能給出一個(gè)解。# 使用SVD直接求解學(xué)術(shù)理解實(shí)際用np.linalg.lstsq即可 U, s, Vt np.linalg.svd(X, full_matricesFalse) # 計(jì)算偽逆 Σ? S_inv np.diag(1.0 / s) # 求解參數(shù) beta_svd Vt.T S_inv U.T y6.2 統(tǒng)計(jì)推斷系數(shù)真的可信嗎在科研和嚴(yán)謹(jǐn)?shù)纳虡I(yè)分析中我們不僅要知道參數(shù)估計(jì)值β?還要知道它的不確定性。這需要通過(guò)統(tǒng)計(jì)推斷來(lái)完成其前提是誤差項(xiàng)ε滿足獨(dú)立同分布且服從正態(tài)分布N(0, σ2)。在此假設(shè)下參數(shù)估計(jì)β?也服從一個(gè)多元正態(tài)分布。我們可以計(jì)算參數(shù)的標(biāo)準(zhǔn)誤衡量β?的估計(jì)精度。t 統(tǒng)計(jì)量t β?_j / SE(β?_j)用于檢驗(yàn)單個(gè)系數(shù)是否顯著不為零原假設(shè) H?: β_j 0。置信區(qū)間給出系數(shù)真實(shí)值可能落入的范圍例如95%置信區(qū)間。statsmodels庫(kù)提供了非常完善的統(tǒng)計(jì)推斷輸出。import statsmodels.api as sm # 使用statsmodels它會(huì)自動(dòng)添加截距項(xiàng)需指定add_constant X_sm sm.add_constant(x) # 添加一列常數(shù)1 model_sm sm.OLS(y, X_sm).fit() # 普通最小二乘 # 打印詳細(xì)的總結(jié)報(bào)告 print(model_sm.summary())summary()的輸出會(huì)包含系數(shù)估計(jì)值、標(biāo)準(zhǔn)誤、t值、P值以及置信區(qū)間還有R2、調(diào)整后R2、F統(tǒng)計(jì)量等模型整體檢驗(yàn)指標(biāo)。P值小于顯著性水平如0.05通常認(rèn)為該系數(shù)是顯著的。6.3 案例實(shí)戰(zhàn)房?jī)r(jià)預(yù)測(cè)簡(jiǎn)化模型假設(shè)我們想用房屋面積area來(lái)預(yù)測(cè)房?jī)r(jià)price。我們模擬一份數(shù)據(jù)并完成全流程。import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score import statsmodels.api as sm # 1. 模擬數(shù)據(jù) np.random.seed(123) area np.random.normal(100, 30, 100).clip(50, 150) # 面積50-150平米 # 假設(shè)真實(shí)關(guān)系房?jī)r(jià) 5000 300 * 面積 隨機(jī)噪聲 true_price 5000 300 * area noise np.random.normal(0, 10000, 100) # 較大的噪聲 price true_price noise df pd.DataFrame({area: area, price: price}) # 2. 可視化數(shù)據(jù)關(guān)系 plt.figure(figsize(8,6)) plt.scatter(df[area], df[price], alpha0.6, label數(shù)據(jù)點(diǎn)) plt.xlabel(房屋面積 (平米)) plt.ylabel(房?jī)r(jià) (元)) plt.title(房屋面積與房?jī)r(jià)關(guān)系散點(diǎn)圖) plt.grid(True, linestyle--, alpha0.5) # 3. 擬合線性模型 X df[[area]].values y df[price].values model LinearRegression() model.fit(X, y) print(f模型截距: {model.intercept_:.2f}) print(f模型斜率: {model.coef_[0]:.2f}) # 繪制擬合直線 x_fit np.linspace(df[area].min(), df[area].max(), 100).reshape(-1,1) y_fit model.predict(x_fit) plt.plot(x_fit, y_fit, colorred, linewidth2, labelf擬合直線: price {model.intercept_:.0f} {model.coef_[0]:.0f}*area) plt.legend() plt.show() # 4. 模型評(píng)估 y_pred model.predict(X) mse mean_squared_error(y, y_pred) rmse np.sqrt(mse) r2 r2_score(y, y_pred) print(f\n模型評(píng)估:) print(f均方誤差 (MSE): {mse:.2f}) print(f均方根誤差 (RMSE): {rmse:.2f} (元)) print(f決定系數(shù) R2: {r2:.4f}) # 5. 殘差分析 residuals y - y_pred fig, axes plt.subplots(1, 2, figsize(12,4)) axes[0].scatter(y_pred, residuals, alpha0.6) axes[0].axhline(y0, colorr, linestyle--) axes[0].set_xlabel(預(yù)測(cè)房?jī)r(jià)) axes[0].set_ylabel(殘差) axes[0].set_title(殘差 vs. 擬合值圖) axes[0].grid(True, linestyle--, alpha0.5) axes[1].hist(residuals, bins20, edgecolorblack, alpha0.7) axes[1].set_xlabel(殘差) axes[1].set_ylabel(頻數(shù)) axes[1].set_title(殘差分布直方圖) plt.tight_layout() plt.show() # 6. 統(tǒng)計(jì)推斷 (使用statsmodels) X_sm sm.add_constant(df[area]) # 添加常數(shù)項(xiàng) model_sm sm.OLS(df[price], X_sm).fit() print(\n 統(tǒng)計(jì)推斷詳細(xì)報(bào)告 ) print(model_sm.summary())通過(guò)這個(gè)完整案例你可以看到從數(shù)據(jù)探索、模型擬合、可視化、評(píng)估到統(tǒng)計(jì)推斷的全過(guò)程。報(bào)告中的P值會(huì)告訴你“面積”這個(gè)系數(shù)是否顯著置信區(qū)間給出了斜率的一個(gè)范圍例如我們可能得到斜率在[280, 320]之間95%置信水平這比單純報(bào)告一個(gè)點(diǎn)估計(jì)值300包含了更多的信息。線性最小二乘的魅力在于其簡(jiǎn)潔與深刻。它用最優(yōu)雅的數(shù)學(xué)解決了“最佳直線”的問(wèn)題為無(wú)數(shù)復(fù)雜的模型奠定了基石。然而真正的功夫在模型之外——在于你對(duì)數(shù)據(jù)的理解、對(duì)假設(shè)的檢驗(yàn)、對(duì)異常的處理。下次當(dāng)你看到一組散點(diǎn)圖本能地想畫一條趨勢(shì)線時(shí)希望你能想起背后這套完整的思考框架和工具箱而不僅僅是點(diǎn)擊軟件里的一個(gè)按鈕。工具本身是簡(jiǎn)單的但如何正確地、批判性地使用工具才是數(shù)據(jù)工作中區(qū)分新手與老手的關(guān)鍵。