十三、預測
原文: Prediction 譯者: 飛龍 協定: CC BY-NC-SA 4.0 自豪地采用 谷歌翻譯
資料科學的一個重要方面,是發現資料可以告訴我們什麼未來的事情。氣候和污染的資料說了幾十年内溫度的什麼事情?根據一個人的網際網路個人資訊,哪些網站可能會讓他感興趣?病人的病史如何用來判斷他或她對治療的反應?
為了回答這樣的問題,資料科學家已經開發出了預測的方法。在本章中,我們将研究一種最常用的方法,基于一個變量的值來預測另一個變量。
方法的基礎由弗朗西斯·高爾頓爵士(Sir Francis Galton)奠定。我們在 7.1 節看到,高爾頓研究了身體特征是如何從一代傳到下一代的。他最著名的工作之一,是根據父母的高度預測子女的身高。我們已經研究了高爾頓為此收集的資料集。
heights
表包含了 934 個成年子女的雙親身高和子女身高(全部以英寸為機關)。
# Galton's data on heights of parents and their adult children
galton = Table.read_table('galton.csv')
heights = Table().with_columns(
'MidParent', galton.column('midparentHeight'),
'Child', galton.column('childHeight')
)
heights
MidParent | Child |
---|---|
75.43 | 73.2 |
69.2 | |
69 | |
73.66 | 73.5 |
72.5 | |
65.5 | |
72.06 | 71 |
68 |
(省略了 924 行)
heights.scatter('MidParent')
收集資料的主要原因是能夠預測成年子女的身高,他們的父母與資料集中相似。 在注意到兩個變量之間的正相關之後,我們在第 7.1 節中做了這些預測。
我們的方法是,基于新人的雙親身高周圍的所有點來做預測。 為此,我們編寫了一個名為
predict_child
的函數,該函數以雙親身高作為參數,并傳回雙親身高在半英寸之内的,所有子女的平均身高。
def predict_child(mpht):
"""Return a prediction of the height of a child
whose parents have a midparent height of mpht.
The prediction is the average height of the children
whose midparent height is in the range mpht plus or minus 0.5 inches.
"""
close_points = heights.where('MidParent', are.between(mpht-0.5, mpht + 0.5))
return close_points.column('Child').mean()
我們将函數應用于
Midparent
列,可視化我們的結果。
# Apply predict_child to all the midparent heights
heights_with_predictions = heights.with_column(
'Prediction', heights.apply(predict_child, 'MidParent')
)
# Draw the original scatter plot along with the predicted values
heights_with_predictions.scatter('MidParent')
給定雙親身高的預測值,大緻位于給定身高處的垂直條形的中心。這種預測方法稱為回歸。 本章後面我們會看到這個術語的來源。 我們也會看到,我們是否可以避免将“接近”任意定義為“在半英寸之内”。 但是首先我們要開發一個可用于很多環境的方法,來決定一個變量作為另一個變量的預測值有多好。
相關性
在本節中,我們将開發一種度量,度量散點圖緊密聚集在一條直線上的程度。 形式上,這被稱為測量線性關聯。
hybrid
表包含了 1997 年到 2013 年在美國銷售的混合動力車的資料。資料來自佛羅裡達大學
Larry Winner 教授的線上資料檔案。這些列為:
-
:車的型号vehicle
-
:出廠年份year
-
: 2013 年制造商的建議零售價(美元)msrp
-
: 加速度(千米每小時每秒)acceleration
-
: 燃油效率(英裡每加侖)mpg
-
: 型号的類别class
(省略了 143 行)
下圖是
msrp
與
acceleration
的散點圖。 這意味着
msrp
繪制在縱軸上并且
acceleration
在橫軸上。
hybrid.scatter('acceleration', 'msrp')
注意正相關。 散點圖傾斜向上,表明加速度較大的車輛通常成本更高;相反,價格更高的汽車通常具有更大的加速。
msrp
mpg
的散點圖表明了負相關。
mpg
較高的混合動力車往往成本較低。 這似乎令人驚訝,直到你明白了,加速更快的汽車往往燃油效率更低,行駛裡程更低。 之前的散點圖顯示,這些也是價格更高的車型。
hybrid.scatter('mpg', 'msrp')
除了負相關,價格與效率的散點圖顯示了兩個變量之間的非線性關系。 這些點似乎圍繞在一條曲線周圍,而不是一條直線。
但是,如果我們隻将資料限制在 SUV 類别中,價格和效率之間仍然負相關的,但是這種關系似乎更為線性。 SUV 價格與加速度之間的關系也呈線性趨勢,但是斜率是正的。
suv = hybrid.where('class', 'SUV')
suv.scatter('mpg', 'msrp')
suv.scatter('acceleration', 'msrp')
你會注意到,即使不關注變量被測量的機關,我們也可以從散點圖的大體方向和形狀中得到有用的資訊。
事實上,我們可以将所有的變量繪制成标準機關,并且繪圖看起來是一樣的。 這給了我們一個方法,來比較兩個散點圖中的線性程度。
回想一下,在前面的章節中,我們定義了
standard_units
函數來将數值數組轉換為标準機關。
def standard_units(any_numbers):
"Convert any array of numbers to standard units."
return (any_numbers - np.mean(any_numbers))/np.std(any_numbers)
我們可以使用這個函數重新繪制 SUV 的兩個散點圖,所有變量都以标準機關測量。
Table().with_columns(
'mpg (standard units)', standard_units(suv.column('mpg')),
'msrp (standard units)', standard_units(suv.column('msrp'))
).scatter(0, 1)
plots.xlim(-3, 3)
plots.ylim(-3, 3);
Table().with_columns(
'acceleration (standard units)', standard_units(suv.column('acceleration')),
'msrp (standard units)', standard_units(suv.column('msrp'))
).scatter(0, 1)
plots.xlim(-3, 3)
plots.ylim(-3, 3);
我們在這些數字中看到的關聯與我們之前看到的一樣。 另外,由于現在兩張散點圖的刻度完全相同,我們可以看到,第二張圖中的線性關系比第一張圖中的線性關系更加模糊。
我們現在将定義一個度量,使用标準機關來量化我們看到的這種關聯。
相關系數
相關系數測量兩個變量之間線性關系的強度。 在圖形上,它測量散點圖聚集在一條直線上的程度。
相關系數這個術語不容易表述,是以它通常縮寫為相關性并用
r
表示。
以下是一些關于
r
的數學事實,我們将通過模拟觀察。
-
是介于r
和-1
之間的數字。1
-
度量了散點圖圍繞一條直線聚集的程度。r
- 如果散點圖是完美的向上傾斜的直線,
,如果散點圖是完美的向下傾斜的直線,r = 1
。r = -1
函數
r_scatter
接受
r
值作為參數,模拟相關性非常接近
r
的散點圖。 由于模拟中的随機性,相關性不會完全等于
r
調用
r_scatter
幾次,以
r
的不同值作為參數,并檢視散點圖如何變化。
當
r = 1
時,散點圖是完全線性的,向上傾斜。 當
r = -1
時,散點圖是完全線性的,向下傾斜。 當
r = 0
時,散點圖是圍繞水準軸的不定形雲,并且變量據說是不相關的。
r_scatter(0.9)
r_scatter(0.25)
r_scatter(0)
r_scatter(-0.55)
計算 r
r
目前為止,
r
的公式還不清楚。 它擁有超出本課程範圍的數學基礎。 然而,你将會看到,這個計算很簡單,可以幫助我們了解
r
的幾個屬性。
r
的公式:
r
是兩個變量的乘積的均值,這兩個變量都以标準機關來衡量。
以下是計算中的步驟。 我們将把這些步驟應用于
x
y
值的簡單表格。
x = np.arange(1, 7, 1)
y = make_array(2, 3, 1, 5, 2, 7)
t = Table().with_columns(
'x', x,
'y', y
)
t
x | y |
---|---|
1 | 2 |
3 | |
4 | 5 |
6 | 7 |
根據散點圖,我們預計
r
将是正值,但不等于 1。
t.scatter(0, 1, s=30, color='red')
第一步:将每個變量轉換為标準機關。
t_su = t.with_columns(
'x (standard units)', standard_units(x),
'y (standard units)', standard_units(y)
)
t_su
x (standard units) | y (standard units) | ||
---|---|---|---|
-1.46385 | -0.648886 | ||
-0.87831 | -0.162221 | ||
-0.29277 | -1.13555 | ||
0.29277 | 0.811107 | ||
0.87831 | |||
1.46385 | 1.78444 |
第二步:将每一對标準機關相乘
t_product = t_su.with_column('product of standard units', t_su.column(2) * t_su.column(3))
t_product
product of standard units | ||||
---|---|---|---|---|
0.949871 | ||||
0.142481 | ||||
0.332455 | ||||
0.237468 | ||||
-0.569923 | ||||
2.61215 |
第三步:
r
是第二步計算的乘積的均值。
# r is the average of the products of standard units
r = np.mean(t_product.column(4))
r
0.61741639718977093
正如我們的預期,
r
是個不等于的正值。
r
的性質
r
計算結果表明:
r
是一個純數字。 它沒有機關。 這是因為
r
基于标準機關。
r
不受任何軸上機關的影響。 這也是因為
r
r
不受軸的交換的影響。 在代數上,這是因為标準機關的乘積不依賴于哪個變量被稱為
x
y
。 在幾何上,軸的切換關于
y = x
直線翻轉了散點圖,但不會改變群聚度和關聯的符号。
t.scatter('y', 'x', s=30, color='red')
correlation
correlation
我們将要重複計算相關性,是以定義一個函數會有幫助,這個函數通過執行上述所有步驟來計算它。 讓我們定義一個函數
correlation
,它接受一個表格,和兩列的标簽。該函數傳回
r
,它是标準機關下這些列的值的乘積的平均值。
def correlation(t, x, y):
return np.mean(standard_units(t.column(x))*standard_units(t.column(y)))
讓我們在
t
的
x
y
列上調用函數。 該函數傳回
x
y
之間的相關性的相同答案,就像直接應用
r
的公式一樣。
correlation(t, 'x', 'y')
0.61741639718977093
我們注意到,變量被指定的順序并不重要。
correlation(t, 'y', 'x')
0.61741639718977093
在
suv
表的列上調用
correlation
,可以使我們看到價格和效率之間的相關性,以及價格和加速度之間的相關性。
correlation(suv, 'mpg', 'msrp')
-0.6667143635709919
correlation(suv, 'acceleration', 'msrp')
0.48699799279959155
這些數值證明了我們的觀察:
價格和效率之間存在負相關關系,而價格和加速度之間存在正相關關系。
價格和加速度之間的線性關系(相關性約為 0.5),比價格和效率之間的線性關系稍弱(相關性約為 -0.67)。
相關性是一個簡單而強大的概念,但有時會被誤用。 在使用
r
之前,重要的是要知道相關性能做和不能做什麼。
相關不是因果
相關隻衡量關聯,并不意味着因果。 盡管學區内的孩子的體重與數學能力之間的相關性可能是正的,但這并不意味着做數學會使孩子更重,或者說增加體重會提高孩子的數學能力。 年齡是一個使人混淆的變量:平均來說,較大的孩子比較小的孩子更重,數學能力更好。
相關性度量線性關聯
相關性隻測量一種關聯 - 線性關聯。 具有較強非線性關聯的變量可能具有非常低的相關性。 這裡有一個變量的例子,它具有完美的二次關聯
y = x ^ 2
,但是相關性等于 0。
new_x = np.arange(-4, 4.1, 0.5)
nonlinear = Table().with_columns(
'x', new_x,
'y', new_x**2
)
nonlinear.scatter('x', 'y', s=30, color='r')
correlation(nonlinear, 'x', 'y')
0.0
相關性受到離群點影響
離群點可能對相關性有很大的影響。 下面是一個例子,其中通過增加一個離群點,
r
等于 1 的散點圖變成
r
等于 0 的圖。
line = Table().with_columns(
'x', make_array(1, 2, 3, 4),
'y', make_array(1, 2, 3, 4)
)
line.scatter('x', 'y', s=30, color='r')
correlation(line, 'x', 'y')
1.0
outlier = Table().with_columns(
'x', make_array(1, 2, 3, 4, 5),
'y', make_array(1, 2, 3, 4, 0)
)
outlier.scatter('x', 'y', s=30, color='r')
correlation(outlier, 'x', 'y')
0.0
生态相關性應謹慎解讀
基于彙總資料的相關性可能會産生誤導。 作為一個例子,這裡是 2014 年 SAT 批判性閱讀和數學成績的資料。50 個州和華盛頓特區各有一個點。
Participation Rate
列包含參加考試的高中學生的百分比。 接下來的三列顯示了每個州的測試每個部分的平均得分,最後一列是測試總得分的平均值。
sat2014 = Table.read_table('sat2014.csv').sort('State')
sat2014
State | Participation Rate | Critical Reading | Math | Writing | Combined |
---|---|---|---|---|---|
Alabama | 6.7 | 547 | 538 | 532 | 1617 |
Alaska | 54.2 | 507 | 503 | 475 | 1485 |
Arizona | 36.4 | 522 | 525 | 500 | 1547 |
Arkansas | 4.2 | 573 | 571 | 554 | 1698 |
California | 60.3 | 498 | 510 | 496 | 1504 |
Colorado | 14.3 | 582 | 586 | 567 | 1735 |
Connecticut | 88.4 | 508 | 1525 | ||
Delaware | 100 | 456 | 459 | 444 | 1359 |
District of Columbia | 440 | 438 | 431 | 1309 | |
Florida | 72.2 | 491 | 485 | 472 | 1448 |
(省略了 41 行)
數學得分與批判性閱讀得分的散點圖緊密聚集在一條直線上; 相關性接近 0.985。
sat2014.scatter('Critical Reading', 'Math')
correlation(sat2014, 'Critical Reading', 'Math')
0.98475584110674341
這是個非常高的相關性。但重要的是要注意,這并不能反映學生的數學和批判性閱讀得分之間的關系強度。
資料由每個州的平均分數組成。但是各州不參加考試 - 而是學生。表中的資料通過将每個州的所有學生聚集為(這個州裡面的兩個變量的均值處的)單個點而建立。但并不是所有州的學生都會在這個位置,因為學生的表現各不相同。如果你為每個學生繪制一個點,而不是每個州一個點,那麼在上圖中的每個點周圍都會有一圈雲狀的點。整體畫面會更模糊。學生的數學和批判性閱讀得分之間的相關性,将低于基于州均值計算的數值。
基于聚合和均值的相關性被稱為生态相關性,并且經常用于報告。正如我們剛剛所看到的,他們必須謹慎解讀。
嚴重還是開玩笑?
2012 年,在著名的《新英格蘭醫學雜志》(New England Journal of Medicine)上發表的一篇論文,研究了一組國家巧克力消費與的諾貝爾獎之間的關系。《科學美國人》(Scientific American)嚴肅地做出回應,而其他人更加輕松。 歡迎你自行決定!下面的圖表應該讓你有興趣去看看。
回歸直線
r
并不隻是測量散點圖中的點聚集在一條直線上的程度。 它也有助于确定點聚集的直線。 在這一節中,我們将追溯高爾頓和皮爾遜發現這條直線的路線。
高爾頓的父母及其成年子女身高的資料顯示出線性關系。 當我們基于雙親身高的子女身高的預測大緻沿着直線時,就證明了線性。
galton = Table.read_table('galton.csv')
heights = Table().with_columns(
'MidParent', galton.column('midparentHeight'),
'Child', galton.column('childHeight')
)
def predict_child(mpht):
"""Return a prediction of the height of a child
whose parents have a midparent height of mpht.
The prediction is the average height of the children
whose midparent height is in the range mpht plus or minus 0.5 inches.
"""
close_points = heights.where('MidParent', are.between(mpht-0.5, mpht + 0.5))
return close_points.column('Child').mean()
heights_with_predictions = heights.with_column(
'Prediction', heights.apply(predict_child, 'MidParent')
)
heights_with_predictions.scatter('MidParent')
标準機關下的度量
讓我們看看,我們是否能找到一個方法來确定這條線。 首先,注意到線性關聯不依賴于度量機關 - 我們也可以用标準機關來衡量這兩個變量。
def standard_units(xyz):
"Convert any array of numbers to standard units."
return (xyz - np.mean(xyz))/np.std(xyz)
heights_SU = Table().with_columns(
'MidParent SU', standard_units(heights.column('MidParent')),
'Child SU', standard_units(heights.column('Child'))
)
heights_SU
MidParent SU | Child SU |
---|---|
3.45465 | 1.80416 |
0.686005 | |
0.630097 | |
2.47209 | 1.88802 |
1.60848 | |
-0.348285 | |
1.58389 | 1.18917 |
0.350559 |
在這個刻度上,我們可以像以前一樣精确地計算我們的預測。 但是首先我們必須弄清楚,如何将“接近”的點的舊定義轉換為新的刻度上的一個值。 我們曾經說過,如果雙親高度在 0.5 英寸之内,它們就是“接近”的。 由于标準機關以标準差為機關測量距離,是以我們必須計算出,0.5 英寸是多少個雙親身高的标準差。
雙親身高的标準差約為 1.8 英寸。 是以 0.5 英寸約為 0.28 個标準差。
sd_midparent = np.std(heights.column(0))
sd_midparent
1.8014050969207571
0.5/sd_midparent
0.27756111096536701
現在我們準備修改我們的預測函數,來預測标準機關。 所有改變的是,我們正在使用标準機關的值的表格,并定義如上所述的“接近”。
def predict_child_su(mpht_su):
"""Return a prediction of the height (in standard units) of a child
whose parents have a midparent height of mpht_su in standard units.
"""
close = 0.5/sd_midparent
close_points = heights_SU.where('MidParent SU', are.between(mpht_su-close, mpht_su + close))
return close_points.column('Child SU').mean()
heights_with_su_predictions = heights_SU.with_column(
'Prediction SU', heights_SU.apply(predict_child_su, 'MidParent SU')
)
heights_with_su_predictions.scatter('MidParent SU')
這個繪圖看起來就像在原始刻度上繪圖。 隻改變了軸上的數字。 這證明了我們可以通過在标準機關下工作,來了解預測過程。
确定标準機關下的直線
高爾頓的散點圖形狀是個橄榄球 - 就是說,像橄榄球一樣大緻橢圓形。不是所有的散點圖都是橄榄形的,甚至那些線性關聯的也不都是。但在這一節中,我們假裝我們是高爾頓,隻能處理橄榄形的散點圖。在下一節中,我們将把我們的分析推廣到其他形狀的繪圖。
這裡是一個橄榄形散點圖,兩個變量以标準機關測量。 45 度線顯示為紅色。
但是 45 度線不是經過垂直條形的中心的線。你可以看到在下圖中,1.5 個标準機關的垂直線顯示為黑色。藍線附近的散點圖上的點的高度都大緻在 -2 到 3 的範圍内。紅線太高,無法命中中心。
是以 45 度線不是“均值圖”。該線是下面顯示的綠線。
兩條線都經過原點
(0,0)
。綠線穿過垂直條形的中心(至少大概),比紅色的 45 度線平坦。
45 度線的斜率為 1。是以綠色的“均值圖”直線的斜率是正值但小于 1。
這可能是什麼值呢?你猜對了 - 這是
r
标準機關下的回歸直線
綠色的“均值圖”線被稱為回歸直線,我們将很快解釋原因。 但首先,讓我們模拟一些
r
值不同的橄榄形散點圖,看看直線是如何變化的。 在每種情況中,繪制紅色 45 度線作比較。
執行模拟的函數為
regression_line
,并以
r
為參數。
regression_line(0.95)
regression_line(0.6)
r
接近于 1 時,散點圖,45 度線和回歸線都非常接近。 但是對于
r
較低值來說,回歸線顯然更平坦。
回歸效應
就預測而言,這意味着,對于雙親身高為 1.5 個标準機關的家長來說,我們對女子身高的預測要稍低于 1.5 個标準機關。如果雙親高度是 2 個标準機關,我們對子女身高的預測,會比 2 個标準機關少一些。
換句話說,我們預測,子女會比父母更接近均值。
弗朗西斯·高爾頓爵士就不高興了。他一直希望,特别高的父母會有特别高的子女。然而,資料是清楚的,高爾頓意識到,高個子父母通常擁有并不是特别高的子女。高爾頓沮喪地将這種現象稱為“回歸平庸”。
高爾頓還注意到,特别矮的父母通常擁有相對于他們這一代高一些的子女。一般來說,一個變量的平均值遠遠低于另一個變量的平均值。這被稱為回歸效應。
回歸直線的方程
在回歸中,我們使用一個變量(我們稱
x
)的值來預測另一個變量的值(我們稱之為
y
)。 當變量
x
y
以标準機關測量時,基于
x
預測
y
的回歸線斜率為
r
并通過原點。 是以,回歸線的方程可寫為:
在資料的原始機關下,就變成了:
原始機關的回歸線的斜率和截距可以從上圖中導出。
下面的三個函數計算相關性,斜率和截距。 它們都有三個參數:表的名稱,包含
x
的列的标簽以及包含
y
的列的标簽。
def correlation(t, label_x, label_y):
return np.mean(standard_units(t.column(label_x))*standard_units(t.column(label_y)))
def slope(t, label_x, label_y):
r = correlation(t, label_x, label_y)
return r*np.std(t.column(label_y))/np.std(t.column(label_x))
def intercept(t, label_x, label_y):
return np.mean(t.column(label_y)) - slope(t, label_x, label_y)*np.mean(t.column(label_x))
回歸直線和高爾頓的資料
雙親身高和子女身高之間的相關性是 0.32:
galton_r = correlation(heights, 'MidParent', 'Child')
galton_r
0.32094989606395924
我們也可以找到回歸直線的方程,來基于雙親身高預測子女身高:
galton_slope = slope(heights, 'MidParent', 'Child')
galton_intercept = intercept(heights, 'MidParent', 'Child')
galton_slope, galton_intercept
(0.63736089696947895, 22.636240549589751)
回歸直線的方程是:
這也成為回歸方程。回歸方程的主要用途是根據
x
y
例如,對于 70.48 英寸的雙親身高,回歸直線預測,子女身高為 67.56 英寸。
galton_slope*70.48 + galton_intercept
67.557436567998622
我們最初的預測,通過計算雙親身高接近 70.48 的所有子女的平均身高來完成,這個預測非常接近:67.63 英寸,而回歸線的預測是 67.55 英寸。
heights_with_predictions.where('MidParent', are.equal_to(70.48)).show(3)
70.48 | 74 | 67.6342 |
70 | ||
(省略了 5 行)
這裡是高爾頓的表格的所有行,我們的原始預測,以及子女身高的回歸預測。
heights_with_predictions = heights_with_predictions.with_column(
'Regression Prediction', galton_slope*heights.column('MidParent') + galton_intercept
)
heights_with_predictions
Regression Prediction | |||
---|---|---|---|
70.1 | 70.7124 | ||
70.4158 | 69.5842 | ||
68.5025 | 68.5645 | ||
heights_with_predictions.scatter('MidParent')
灰色圓點顯示回歸預測,全部在回歸線上。 注意這條線與均值的金色圖非常接近。 對于這些資料,回歸線很好地逼近垂直條形的中心。
拟合值
所有的預測值都在直線上,被稱為“拟合值”。 函數
fit
使用表名和
x
y
的标簽,并傳回一個拟合值數組,散點圖中每個點一個。
def fit(table, x, y):
"""Return the height of the regression line at each x value."""
a = slope(table, x, y)
b = intercept(table, x, y)
return a * table.column(x) + b
下圖比上圖更輕易看到直線:
heights.with_column('Fitted', fit(heights, 'MidParent', 'Child')).scatter('MidParent')
另一個繪制直線的方式是在表方法
scatter
中,使用選項
fit_line=True
heights.scatter('MidParent', fit_line=True)
斜率的測量機關
斜率是一個比值,值得花點時間來研究它的測量機關。 我們的例子來自熟悉的醫院系統中産婦的資料集。 孕期體重與高度的散點圖看起來像是一個橄榄球,已經在一場比賽中使用了很多次,但足夠接近橄榄球,我們可以讓我們的拟合直線穿過它來證明。 在後面的章節中,我們将看到如何使這種證明更正式。
baby = Table.read_table('baby.csv')
baby.scatter('Maternal Height', 'Maternal Pregnancy Weight', fit_line=True)
slope(baby, 'Maternal Height', 'Maternal Pregnancy Weight')
3.5728462592750558
回歸線的斜率是 3.57 磅每英寸。 這意味着,對于身高相差 1 英寸的兩名女性來說,我們對孕期體重的預測相差 3.57 磅。 對于身高相差 2 英寸的女性,我們預測的孕期體重相差
2 * 3.57 ~= 7.14
磅。
請注意,散點圖中的連續垂直條形相距 1 英寸,因為高度已經舍入到最近的英寸。 另一種考慮斜率的方法是取兩個相連的條形(相隔 1 英寸),相當于兩組身高相差 1 英寸的女性。 3.57 磅每英寸的斜率意味着,較高組的平均孕期體重比較矮組多大約 3.57 磅。
示例
假設我們的目标是使用回歸,基于巴塞特獵犬的體重來估計它的身高,所用的樣本與回歸模型看起來一緻。 假設觀察到的相關性
r
為 0.5,并且這兩個變量的彙總統計量如下表所示:
average | SD |
---|---|
height | 14 inches |
weight | 50 pounds |
為了計算回歸線的方程,我們需要斜率和截距。
回歸線的方程允許我們,根據給定重量(磅)計算估計高度(英寸):
線的斜率衡量随着重量的機關增長的估計高度的增長。 斜率是正值,重要的是要注意,這并不表示我們認為,如果體重增加巴塞特獵狗就會變得更高。 斜率反映了兩組狗的平均身高的差異,這兩組狗的體重相差 1 磅。 具體來說,考慮一組重量為
w
磅,以及另一組重量為
w + 1
磅的狗。 我們估計,第二組的均值高出 0.2 英寸。 對于樣本中的所有
w
值都是如此。
一般來說,回歸線的斜率可以解釋為随着
x
機關增長的
y
平均增長。 請注意,如果斜率為負值,那麼對于
x
的每機關增長,
y
的平均值會減少。
尾注
即使我們沒有建立回歸方程的數學基礎,我們可以看到,當散點圖是橄榄形的時候,它會給出相當好的預測。 這是一個令人驚訝的數學事實,無論散點圖的形狀如何,同一個方程給出所有直線中的“最好”的預測。 這是下一節的主題。
最小二乘法
我們已經回溯了高爾頓和皮爾森用于開發回歸線方程的步驟,它穿過橄榄形的散點圖。但不是所有的散點圖都是橄榄形的,甚至不是線性的。每個散點圖都有一個“最優”直線嗎?如果是這樣,我們仍然可以使用上一節中開發的斜率和截距公式,還是需要新的公式?
為了解決這些問題,我們需要一個“最優”的合理定義。回想一下,這條線的目的是預測或估計
y
的值,在給定
x
值的情況下。估計通常不是完美的。每個值都由于誤差而偏離真正的值。“最優”直線的合理标準是,它在所有直線中總體誤差盡可能最小。
在本節中,我們将精确确定這個标準,看看我們能否确定标準下的最優直線。
我們的第一個例子是小說《小女人》資料集,每章都有一行。目标是根據句子數來估計字元數(即字母,空格标點符号等等)。回想一下,我們在本課程的第一堂課中試圖實作它。
little_women = Table.read_table('little_women.csv')
little_women = little_women.move_to_start('Periods')
little_women.show(3)
Periods | Characters |
---|---|
189 | 21759 |
188 | 22148 |
231 | 20558 |
(省略了 44 行)
little_women.scatter('Periods', 'Characters')
為了探索資料,我們将需要使用上一節定義的函數
correlation
,
slope
intercept
fit
correlation(little_women, 'Periods', 'Characters')
0.92295768958548163
散點圖明顯接近線性,相關性大于 0.92。
估計中的誤差
下圖顯示了我們在上一節中開發的散點圖和直線。 我們還不知道這是否是所有直線中最優的。 我們首先必須準确表達“最優”的意思。
lw_with_predictions = little_women.with_column('Linear Prediction', fit(little_women, 'Periods', 'Characters'))
lw_with_predictions.scatter('Periods')
對應于散點圖上的每個點,預測的誤差是計算為實際值減去預測值。 它是點與直線之間的垂直距離,如果點線上之下,則為負值。
actual = lw_with_predictions.column('Characters')
predicted = lw_with_predictions.column('Linear Prediction')
errors = actual - predicted
lw_with_predictions.with_column('Error', errors)
Linear Prediction | Error | ||
---|---|---|---|
21183.6 | 575.403 | ||
21096.6 | 1051.38 | ||
24836.7 | -4278.67 | ||
195 | 25526 | 21705.5 | 3820.54 |
255 | 23395 | 26924.1 | -3529.13 |
140 | 14622 | 16921.7 | -2299.68 |
131 | 14431 | 16138.9 | -1707.88 |
214 | 22476 | 23358 | -882.043 |
337 | 33767 | 34056.3 | -289.317 |
185 | 18508 | 20835.7 | -2327.69 |
(省略了 37 行)
我們可以使用
slope
intercept
來計算拟合直線的斜率和截距。 下圖顯示了該直線(淺藍色)。 對應于四個點的誤差以紅色顯示。 這四個點沒什麼特别的。 他們隻是為了展示的清晰而被選中。 函數
lw_errors
以斜率和截距(按照該順序)作為參數,并繪制該圖形。
lw_reg_slope = slope(little_women, 'Periods', 'Characters')
lw_reg_intercept = intercept(little_women, 'Periods', 'Characters')
print('Slope of Regression Line: ', np.round(lw_reg_slope), 'characters per period')
print('Intercept of Regression Line:', np.round(lw_reg_intercept), 'characters')
lw_errors(lw_reg_slope, lw_reg_intercept)
Slope of Regression Line: 87.0 characters per period
Intercept of Regression Line: 4745.0 characters
如果我們用不同的線來建立我們的估計,誤差将會不同。 下面的圖表顯示了如果我們使用另一條線進行估算,誤差會有多大。 第二張圖顯示了通過使用完全愚蠢的線獲得了較大誤差。
lw_errors(50, 10000)
lw_errors(-100, 50000)
均方根誤差(RMSE)
我們現在需要的是誤差大小的一個總體衡量。 你會認識到建立它的方法 - 這正是我們開發标準差的方式。
如果你使用任意直線來計算你的估計值,那麼你的一些誤差可能是正的,而其他的則是負的。 為了避免誤差大小在測量時抵消,我們将采用誤差平方的均值而不是誤差的均值。
估計的均方誤差大概是誤差的平方有多大,但正如我們前面提到的,它的機關很難解釋。 取平方根産生均方根誤差(RMSE),與預測變量的機關相同,是以更容易了解。
使 RMSE 最小
到目前為止,我們的觀察可以總結如下。
- 要根據
估算x
,可以使用任何你想要的直線。y
- 每個直線都有估計的均方根誤差。
- “更好”的直線有更小的誤差。
有沒有“最好”的直線? 也就是說,是否有一條線可以使所有行中的均方根誤差最小?
為了回答這個問題,我們首先定義一個函數
lw_rmse
,通過《小女人》的散點圖來計算任意直線的均方根誤差。 函數将斜率和截距(按此順序)作為參數。
def lw_rmse(slope, intercept):
lw_errors(slope, intercept)
x = little_women.column('Periods')
y = little_women.column('Characters')
fitted = slope * x + intercept
mse = np.mean((y - fitted) ** 2)
print("Root mean squared error:", mse ** 0.5)
lw_rmse(50, 10000)
Root mean squared error: 4322.16783177
lw_rmse(-100, 50000)
Root mean squared error: 16710.1198374
正如預期的那樣,不好的直線 RMSE 很大。 但是如果我們選擇接近于回歸線的斜率和截距,則 RMSE 要小得多。
lw_rmse(90, 4000)
Root mean squared error: 2715.53910638
這是對應于回歸線的均方根誤差。 通過顯着的數學事實,沒有其他線路能擊敗這一條。
回歸線是所有直線之間的唯一直線,使估計的均方誤差最小。
lw_rmse(lw_reg_slope, lw_reg_intercept)
Root mean squared error: 2701.69078531
這個聲明的證明需要超出本課程範圍的抽象數學。 另一方面,我們有一個強大的工具 – Python,它可以輕松執行大量的數值計算。 是以我們可以使用 Python 來确認回歸線最小化的均方誤差。
數值優化
首先注意,使均方根誤差最小的直線,也是使平方誤差最小的直線。 平方根對最小值沒有任何影響。 是以我們會為自己節省一個計算步驟,并将平均方差 MSE 減到最小。
我們試圖根據《小女人》的句子數(
x
)來預測字元數量(
y
)。 如果我們使用
直線,它将有一個 MSE,它取決于斜率
a
和截距
b
。 函數
lw_mse
以斜率和截距為參數,并傳回相應的 MSE。
def lw_mse(any_slope, any_intercept):
x = little_women.column('Periods')
y = little_women.column('Characters')
fitted = any_slope*x + any_intercept
return np.mean((y - fitted) ** 2)
讓我們确認一下,
lw_mse
得到回歸線的 RMSE 的正确答案。 請記住,
lw_mse
傳回均方誤差,是以我們必須取平方根來得到 RMSE。
lw_mse(lw_reg_slope, lw_reg_intercept)**0.5
2701.690785311856
它和我們之前使用
lw_rmse
得到的值相同。
lw_rmse(lw_reg_slope, lw_reg_intercept)
Root mean squared error: 2701.69078531
你可以确認對于其他的斜率和截距,
lw_mse
也傳回正确的值。 例如,這裡是我們之前嘗試的,非常不好的直線的 RMSE。
lw_mse(-100, 50000)**0.5
16710.119837353752
這裡是這條直線的 RMSE,它接近回歸線。
lw_mse(90, 4000)**0.5
2715.5391063834586
如果我們嘗試不同的值,我們可以通過反複試驗找到一個誤差較低的斜率和截距,但這需要一段時間。 幸運的是,有一個 Python 函數為我們做了所有的試錯。
minimize
函數可用于尋找函數的參數,函數在這裡傳回其最小值。 Python 使用類似的試錯法,遵循使輸出值遞減的變化量。
minimize
的參數是一個函數,它本身接受數值參數并傳回一個數值。 例如,函數
lw_mse
以數值斜率和截距作為參數,并傳回相應的 MSE。
minimize(lw_mse)
傳回一個數組,由斜率和截距組成,它們使 MSE 最小。 這些最小值是通過智能試錯得出的極好的近似值,而不是基于公式的精确值。
best = minimize(lw_mse)
best
array([ 86.97784117, 4744.78484535])
這些值與我們之前使用
slope
intercept
函數計算的值相同。 由于最小化的不精确性,我們看到較小的偏差,但是這些值本質上是相同的。
print("slope from formula: ", lw_reg_slope)
print("slope from minimize: ", best.item(0))
print("intercept from formula: ", lw_reg_intercept)
print("intercept from minimize: ", best.item(1))
slope from formula: 86.9778412583
slope from minimize: 86.97784116615884
intercept from formula: 4744.78479657
intercept from minimize: 4744.784845352655
最小二乘直線
是以我們發現,不僅回歸線具有最小的均方誤差,而且均方誤差的最小化也給出了回歸線。 回歸線是最小化均方誤差的唯一直線。
這就是回歸線有時被稱為“最小二乘直線”的原因。
最小二乘回歸
在前面的章節中,我們開發了回歸直線的斜率和截距方程,它穿過一個橄榄形的散點圖。 事實證明,無論散點圖的形狀如何,最小二乘直線的斜率和截距都與我們開發的公式相同。
我們在《小女人》的例子中看到了它,但是讓我們以散點圖顯然不是橄榄形的例子來證明它。 對于這些資料,我們再次受惠于佛羅裡達大學 Larry Winner 教授的豐富資料檔案。 《國際運動科學雜志》(International Journal of Exercise Science)2013 年的一項研究,研究了大學生鉛球運動員,并考察了力量與鉛球距離的關系。 總體由 28 名女大學生運動員組成。 運動員在賽季前的“1RM power clean”中舉起的最大值(公斤)是衡量力量的名額。 距離(米)是運動員個人最佳成績。
shotput = Table.read_table('shotput.csv')
shotput
Weight Lifted | Shot Put Distance |
---|---|
37.5 | 6.4 |
51.5 | 10.2 |
61.3 | 12.4 |
13 | |
63.6 | 13.2 |
66.1 | |
12.7 | |
92.7 | 13.9 |
90.5 | 15.5 |
15.8 |
(省略了 18 行)
shotput.scatter('Weight Lifted')
這不是橄榄形的散點圖。 事實上,它似乎有一點非線性成分。 但是,如果我們堅持用一條直線來做出預測,那麼所有直線之中仍然有一條最好的直線。
我們為回歸線的斜率和截距建立公式,它來源于橄榄形的散點圖,并給出了下列值:
slope(shotput, 'Weight Lifted', 'Shot Put Distance')
0.098343821597819972
intercept(shotput, 'Weight Lifted', 'Shot Put Distance')
5.9596290983739522
即使散點圖不是橄榄形,使用這些公式還有意義嗎? 我們可以通過求出使 MSE 最小的斜率和截距來回答這個問題。
我們将定義函數
shotput_linear_mse
,以斜體和截距作為參數并傳回相應的 MSE。 然後将
minimize
應用于
shotput_linear_mse
将傳回最優斜率和截距。
def shotput_linear_mse(any_slope, any_intercept):
x = shotput.column('Weight Lifted')
y = shotput.column('Shot Put Distance')
fitted = any_slope*x + any_intercept
return np.mean((y - fitted) ** 2)
minimize(shotput_linear_mse)
array([ 0.09834382, 5.95962911])
這些值與我們使用我們的公式得到的值相同。 總結:
無論散點圖的形狀如何,都有一條獨特的線,可以使估計的均方誤差最小。 它被稱為回歸線,其斜率和截距由下式給出:
譯者注:也就是 cov(x, y)/var(x)
fitted = fit(shotput, 'Weight Lifted', 'Shot Put Distance')
shotput.with_column('Best Straight Line', fitted).scatter('Weight Lifted')
非線性回歸
上面的圖表強化了我們之前的觀察,即散點圖有點彎曲。 是以,最好拟合曲線而不是直線。 研究假設舉起的重量與鉛球距離之間是二次關系。 是以讓我們使用二次函數來預測,看看我們能否找到最好的曲線。
我們必須找到所有二次函數中最好的二次函數,而不是所有直線中最好的直線。 最小二乘法允許我們這樣做。
這種最小化的數學是複雜的,不容易僅僅通過檢查散點圖來發現。 但是數值最小化和線性預測一樣簡單! 再次通過使用最小化我們可以得到最好的二次預測。 讓我們看看這是如何工作的。
回想一下,二次函數的形式:
f(x) = ax^2 + bx + c
a
、
b
c
是常數。
為了基于舉起的重量找到最好的二次函數來預測距離,使用最小二乘法,我們首先編寫一個函數,以三個常量為自變量的,用上面的二次函數計算拟合值,然後傳回均方誤差。
該函數被稱為
shotput_quadratic_mse
。 請注意,定義與
lw_mse
的定義類似,不同的是拟合值基于二次函數而不是線性。
def shotput_quadratic_mse(a, b, c):
x = shotput.column('Weight Lifted')
y = shotput.column('Shot Put Distance')
fitted = a*(x**2) + b*x + c
return np.mean((y - fitted) ** 2)
我們現在可以像之前那樣使用
minimize
,并找到使 MSE 最小的常數。
best = minimize(shotput_quadratic_mse)
best
array([ -1.04004838e-03, 2.82708045e-01, -1.53182115e+00])
我們預測,一個舉起
x
公斤的運動員的鉛球距離大概是
-0.00104x^2 + 0.2827x - 1.5318
米。 例如,如果運動員可以舉起 100 公斤,預測的距離是 16.33 米。 在散點圖上,在 100 公斤左右的垂直條形的中心附近。
(-0.00104)*(100**2) + 0.2827*100 - 1.5318
16.3382
以下是所有
Weight Lifted
的預測。 你可以看到他們穿過散點圖的中心,大緻上接近。
x = shotput.column(0)
shotput_fit = best.item(0)*(x**2) + best.item(1)*x + best.item(2)
shotput.with_column('Best Quadratic Curve', shotput_fit).scatter(0)
視覺診斷
假設資料科學家已經決定使用線性回歸,基于預測變量估計響應變量的值。 為了了解這種估計方法的效果如何,資料科學家必須知道估計值距離實際值多遠。 這些差異被稱為殘差。
殘差就是剩下的東西 - 估計之後的剩餘。
殘差是回歸線和點的垂直距離。 散點圖中的每個點都有殘差。 殘差是
y
的觀測值與
y
的拟合值之間的內插補點,是以對于點
(x, y)
:
residual
函數計算殘差。 該計算假設我們已經定義的所有相關函數:
standard_units
correlation
slope
intercept
fit
def residual(table, x, y):
return table.column(y) - fit(table, x, y)
繼續使用高爾頓的資料的例子,基于雙親身高(預測變量)來估計成年子女身高(響應變量),讓我們計算出拟合值和殘差。
heights = heights.with_columns(
'Fitted Value', fit(heights, 'MidParent', 'Child'),
'Residual', residual(heights, 'MidParent', 'Child')
)
heights
Fitted Value | Residual | ||
---|---|---|---|
2.48763 | |||
-1.51237 | |||
-1.71237 | |||
3.91576 | |||
2.91576 | |||
-4.08424 | |||
2.43553 | |||
-0.564467 |
如果要處理的變量太多,以可視化開始總是很有幫助的。 函數
scatter_fit
繪制資料的散點圖,以及回歸線。
def scatter_fit(table, x, y):
table.scatter(x, y, s=15)
plots.plot(table.column(x), fit(table, x, y), lw=4, color='gold')
plots.xlabel(x)
plots.ylabel(y)
scatter_fit(heights, 'MidParent', 'Child')
通過繪制殘差和預測變量來繪制殘差圖。函數
residual_plot
就是這樣做的。
def residual_plot(table, x, y):
x_array = table.column(x)
t = Table().with_columns(
x, x_array,
'residuals', residual(table, x, y)
)
t.scatter(x, 'residuals', color='r')
xlims = make_array(min(x_array), max(x_array))
plots.plot(xlims, make_array(0, 0), color='darkblue', lw=4)
plots.title('Residual Plot')
residual_plot(heights, 'MidParent', 'Child')
雙親身高在橫軸上,就像原始散點圖中一樣。 但是現在縱軸顯示了殘差。 請注意,該圖看上去以
y=0
的橫線為中心(以深藍色顯示)。 還要注意,繪圖沒有顯示上升或下降的趨勢。 我們稍後會觀察到所有的回歸都是如此。
回歸診斷
殘差圖有助于我們直覺評估線性回歸分析的品質。 這種評估被稱為診斷。 函數
regression_diagnostic_plots
繪制原始散點圖以及殘差圖,以便于比較。
def regression_diagnostic_plots(table, x, y):
scatter_fit(table, x, y)
residual_plot(table, x, y)
regression_diagnostic_plots(heights, 'MidParent', 'Child')
這個殘差圖表明,線性回歸是合理的估計方法。 注意殘差關于
y=0
的橫線上下對稱分布,相當于原始散點圖大緻上下對稱。 還要注意,繪圖的垂直延伸,在子女身高最常見的值上相當均勻。 換句話說,除了一些離群點之外,繪圖并不是一些地方窄。另一些地方寬。
換句話說,在預測變量的觀察範圍内,回歸的準确性似乎是相同的。
良好回歸的殘差圖不顯示任何規律。 在預測變量的範圍内,殘差在
y=0
的直線處上下相同。
檢測非線性
繪制資料的散點圖,通常表明了兩個變量之間的關系是否是非線性的。 然而,通常情況下,殘差圖中比原始散點圖中更容易發現非線性。 這通常是因為這兩個圖的規模:殘差圖允許我們放大錯誤,進而更容易找出規律。
我們的資料是海牛的年齡和長度的資料集,這是一種海洋哺乳動物(維基共享資源圖)。 資料在一個名為
dugong
的表中。 年齡以年為機關,長度以米為機關。 因為海牛通常不跟蹤他們的生日,年齡是根據他們的牙齒狀況等變量來估計的。
dugong = Table.read_table('http://www.statsci.org/data/oz/dugongs.txt')
dugong = dugong.move_to_start('Length')
dugong
Length | Age |
---|---|
1.8 | |
1.85 | 1.5 |
1.87 | |
1.77 | |
2.02 | 2.5 |
2.27 | |
2.15 | |
2.26 | |
2.35 | |
2.47 | 8 |
(省略了 17 行)
如果我們可以衡量海牛的長度,對于它的年齡我們可以說什麼呢? 讓我們來看看我們的資料說了什麼。 這是一個長度(預測變量)和年齡(響應變量)的回歸。 這兩個變量之間的相關性相當大,為 0.83。
correlation(dugong, 'Length', 'Age')
0.82964745549057139
盡管相關性仍然很高,繪圖顯示出曲線規律,在殘差圖中更加明顯。
regression_diagnostic_plots(dugong, 'Length', 'Age')
雖然你可以發現原始散點圖中的非線性,但在殘差圖中更明顯。
在長度的較低一端,殘差幾乎都是正的;然後他們幾乎都是負的;然後在較高一端,殘差再次為正。 換句話說,回歸估計值過高,然後過低,然後過高。 這意味着使用曲線而不是直線來估計年齡會更好。
當殘差圖顯示了規律時,變量之間可能存在非線性關系。
檢測異方差
異方差這個詞,那些準備拼寫遊戲的人肯定會感興趣。 對于資料科學家來說,其興趣在于它的意義,即“不均勻延伸”。
回想一下
hybrid
表,包含美國混合動力汽車的資料。這是燃油效率對加速度的回歸。這個關聯是負面的:加速度高的汽車往往效率較低。
regression_diagnostic_plots(hybrid, 'acceleration', 'mpg')
注意殘差圖在加速度的較低一端變得發散。 換句話說,對于較低的加速度,誤差的大小的變化比較高值更大。 殘差圖中比原始的散點圖中更容易注意到不均勻的變化。
如果殘差圖顯示
y=0
的橫線處的不均勻變化,則在預測變量的範圍内,回歸的估計不是同等準确的。
數值診斷
除了可視化之外,我們還可以使用殘差的數值屬性來評估回歸的品質。 我們不會在數學上證明這些屬性。 相反,我們将通過計算來觀察它們,看看它們告訴我們回歸的什麼東西。
下面列出的所有事實都适用于散點圖的所有形狀,無論它們是否是線性的。
殘差圖不展示形狀
對于每一個線性回歸,無論是好還是壞,殘差圖都不展示任何趨勢。 總的來說,它是平坦的。 換句話說,殘差和預測變量是不相關的。
你可以在上面所有的殘差圖中看到它。 我們還可以計算每種情況下,預測變量和殘差之間的相關性。
correlation(heights, 'MidParent', 'Residual')
-2.7196898076470642e-16
這看起來不是零,但它是個很小的數字,除了由于計算的舍入誤差之外,它就是零。 在這裡也一樣,取小數點後 10 位。 減号是因為上面的舍入。
round(correlation(heights, 'MidParent', 'Residual'), 10)
-0.0
dugong = dugong.with_columns(
'Fitted Value', fit(dugong, 'Length', 'Age'),
'Residual', residual(dugong, 'Length', 'Age')
)
round(correlation(dugong, 'Length', 'Residual'), 10)
0.0
殘差的均值
不管散點圖的形狀如何,剩餘的均值都是 0。
這類似于這樣一個事實,如果你選取任何數值清單并計算距離均值的偏差的清單,則偏差的均值為 0。
在上面的所有殘差圖中,你看到
y=0
的橫線穿過圖的中心。 這是這個事實的可視化。
作為一個數值示例,這裡是高爾頓資料集中,基于雙親高度的子女高度的回歸的殘差均值。
round(np.mean(heights.column('Residual')), 10)
0.0
海牛長度和年齡的回歸的殘差均值也是一樣。 殘差均值為 0,除了舍入誤差。
round(np.mean(dugong.column('Residual')), 10)
0.0
殘差的标準差
無論散點圖的形狀如何,殘差的标準差是響應變量的标準差的一個比例。 比例是
我們将很快看到,它如何衡量回歸估計的準确性。 但首先,讓我們通過例子來确認。
在子女身高和雙親身高的案例中,殘差的标準差約為 3.39 英寸。
np.std(heights.column('Residual'))
3.3880799163953426
這和響應變量的标準差乘
sqrt(1 - r^2)
相同。
r = correlation(heights, 'MidParent', 'Child')
np.sqrt(1 - r**2) * np.std(heights.column('Child'))
3.3880799163953421
混合動力汽車的加速和裡程的回歸也是如此。 相關性
r
是負數(約 -0.5),但
r^2
是正數,是以
sqrt(1 - r^2)
是一個分數。
r = correlation(hybrid, 'acceleration', 'mpg')
r
-0.5060703843771186
hybrid = hybrid.with_columns(
'fitted mpg', fit(hybrid, 'acceleration', 'mpg'),
'residual', residual(hybrid, 'acceleration', 'mpg')
)
np.std(hybrid.column('residual')), np.sqrt(1 - r**2)*np.std(hybrid.column('mpg'))
(9.4327368334302903, 9.4327368334302903)
現在讓我們看看,殘差的标準差是如何衡量回歸的好壞。請記住,殘差的均值為 0。是以,殘差的标準差越小,則殘差越接近于 0。換句話說,如果殘差的标準差小,那麼回歸中的總體誤差就小。
極端情況是
r = 1
或
r = -1
。在這兩種情況下,
sqrt(1 - r^2) = 0
。是以,殘差的均值為 0,标準差為 0,是以殘差都等于 0。回歸線确實是完美的估計。我們在本章的前面看到,如果
r = ± 1
,散點圖是一條完美的直線,與回歸線相同,是以回歸估計中确實沒有錯誤。
但通常
r
不是極端的。如果
r
既不是
±1
也不是 0,那麼
sqrt(1 - r^2)
是一個适當的分數,并且回歸估計的誤差大小,整體上大緻在 0 和
y
的标準差之間。
最糟糕的情況是
r = 0
。那麼
sqrt(1 - r^2)
= 1,殘差的标準差等于
y
的标準差。這與觀察結果一緻,如果
r = 0
那麼回歸線就是
y
的均值上的一條橫線。在這種情況下,回歸的均方根誤差是距離
y
的平均值的偏差的均方根,這是
y
的标準差。實際上,如果
r = 0
,那麼這兩個變量之間就沒有線性關聯,是以使用線性回歸沒有任何好處。
另一種解釋 r
的方式
r
我們可以重寫上面的結果,不管散點圖的形狀如何:
互補的結果是,無論散點圖的形狀如何,拟合值的标準差是觀察值
y
的标準差的一個比例。比例是
|r|
要檢視比例在哪裡出現,請注意拟合值全部位于回歸線上,而
y
的觀測值是散點圖中所有點的高度,并且更加可變。
scatter_fit(heights, 'MidParent', 'Child')
拟合值的範圍在 64 到 71 之間,而所有子女的身高則變化很大,大約在 55 到 80 之間。
為了在數值上驗證結果,我們隻需要計算雙方的一緻性。
correlation(heights, 'MidParent', 'Child')
0.32094989606395924
這裡是出生體重的拟合值的标準差與觀察值的标準差的比值:
np.std(heights.column('Fitted Value'))/np.std(heights.column('Child'))
0.32094989606395957
這個比例等于
r
,證明了我們的結果。
絕對值出現在哪裡? 首先要注意的是,标準差不能是負數,标準差的比值也不行。 那麼當
r
是負數時會發生什麼呢? 燃油效率和加速度的例子将向我們展示。
correlation(hybrid, 'acceleration', 'mpg')
-0.5060703843771186
np.std(hybrid.column('fitted mpg'))/np.std(hybrid.column('mpg'))
0.5060703843771186
兩個标準差的比值就是
|r|
解釋這個結果的更标準的方法是,回想一下:
是以,對結果的兩邊取平方: