seaborn: 迴歸模型的視覺化
本文主要是對seaborn官方教程:Visualizing regression models 的翻譯,並新增額外學習筆記與相關函式提示。
首先匯入本文所需的模組:
import
numpy
as
np
import
seaborn
as
sns
import
matplotlib。pyplot
as
plt
sns
。
set
(
color_codes
=
True
)
線性關係的視覺化
約翰·圖基
(英語:John Tukey,1915年6月16日-2000年7月26日),美國數學家,快速傅立葉變換髮明人,同時提出了“位元”、“資料分析”等概念。因開創了探索性資料分析(Exploratory Data Analysis,簡稱EDA)精神聞名。
EDA的本質是對現有資料在做出儘量少的假設下前提下,透過對資料作圖、方程擬合等方法來探索資料的結構與規律。這種方法對於雜亂,不知如何下手處理的資料來說,是一種非常有效的分析方法。
Seaborn也是本著探索資料的精神發展的,透過快速對資料視覺化,研究資料的主要模式。如果希望定量的對資料分析,那麼可以結合一些其他常用的資料分析庫,例如
statsmodel
。
繪製線性迴歸模型的函式
Seaborn主要提供了兩個函式
regplot()
和
lmplot()
來繪製線性迴歸模型。
這兩個函式的核心功能很相似,兩個函式都會繪製資料散點圖,並且擬合關於變數
之間的迴歸曲線,同時顯示迴歸的95%置信區間。
本節的主要目的是帶領大家發掘兩個函式的區別,以此在實際應用中能夠快速選擇合適的函式。
# 載入資料集
tips
=
sns
。
load_dataset
(
‘tips’
)
繪製顧客消費總額和小費數額兩個變數之間的關係:
sns
。
regplot
(
x
=
‘total_bill’
,
y
=
‘tip’
,
data
=
tips
);
sns
。
lmplot
(
x
=
‘total_bill’
,
y
=
‘tip’
,
data
=
tips
);
不難發現,除了形狀不太相同,兩個影象非常接近。
現在介紹兩個函式之間的一個主要區別:
regplot()
: 接受變數
的型別可以是numpy陣列、pandas序列(Series)。或者直接對data傳入pandas DataFrame物件資料。而
lmplot()
的
data
引數是必須的,且變數
都必須為字串。
傳入資料的格式被稱為
“tidy”資料
或者“long-term”資料,在統計中稱為“model matrix”或“data matrix”,即資料的排列方式為:每個變數為資料集的一列,每次觀察都是資料集中的一行。
regplot()
和
lmplot()
除了可以接受連續型資料,也可接受離散型資料。然而,對於離散型資料,散點圖的迴歸模擬不是很直觀:
sns
。
lmplot
(
x
=
‘size’
,
y
=
‘tip’
,
data
=
tips
);
可以看到上圖中,很多資料點都重合在了一起。為了解決這個問題,可以對離散資料加入一些隨機噪聲(抖動,jitter),從而使得資料分佈更分散:
sns
。
lmplot
(
x
=
‘size’
,
y
=
‘tip’
,
data
=
tips
,
x_jitter
=。
05
);
或者,我們可以將分散的資料點聚合表示為離散的資料柱,表達資料中集中趨勢及估計的置信區間:
sns
。
lmplot
(
x
=
‘size’
,
y
=
‘tip’
,
data
=
tips
,
x_estimator
=
np
。
mean
);
使用其他型別的模型擬合
使用線性迴歸擬合數據非常容易操作,然而當資料分佈比較複雜時,其不能很好的表示資料。
# 載入安斯庫姆四重奏資料
anscombe
=
sns
。
load_dataset
(
‘anscombe’
)
安斯庫姆四重
(Anscombe‘s quartet)是四組基本的統計特性一致(例如均值,方程)的資料,但由它們繪製出的圖表則截然不同。
這四組資料由統計學家弗朗西斯·安斯庫姆(Francis Anscombe)於1973年構造,用來說明在分析資料前先繪製圖表的重要性,以及
離群值
對統計的影響之大。
sns
。
lmplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’I‘”
),
ci
=
None
,
scatter_kws
=
{
’s‘
:
80
});
上述程式碼中,我們使用anscombe資料中,擬合為線性的資料。取消
lmplot()
的置信區間,
scatter_kws
用來控制散點圖的屬性。
現在,我們再來載入另一個數據,看看線性迴歸的擬合情況:
sns
。
lmplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’II‘”
),
ci
=
None
,
scatter_kws
=
{
’s‘
:
80
});
可以看到,即使兩份資料的統計特性一致,但是使用同一模型對資料擬合的效果大不相同,這樣凸顯了在實際分析中,先將資料視覺化觀察資料大致模式的重要性。
為了表達上圖中二階甚至更高階的關係,
lmplot()
和
regplot()
可以擬合多項式迴歸模型來探索資料的非線性趨勢:
sns
。
lmplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’II‘”
),
order
=
2
,
ci
=
None
,
scatter_kws
=
{
’s‘
:
80
});
在上面兩例中,資料的分佈都很正常,可以使用相應的線性或多項式迴歸完美擬合。然而,當資料中出現
離群值
時,則會對擬合效果造成很大的影響:
sns
。
lmplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’III‘”
),
ci
=
None
,
scatter_kws
=
{
’s‘
:
80
});
在上圖中,由於一個離群值,造成擬合曲線整體向離群值偏移。這顯然不是我們希望的效果,為了解決這個問題,可以採用
穩健迴歸
((robust regression),透過選擇不同的損失函式 (例如加入懲罰項) 來降低離群值與擬合直線之間殘差(residual)的權重,從而減少離群值的影響。
sns
。
lmplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’III‘”
),
robust
=
True
,
ci
=
None
,
scatter_kws
=
{
’s‘
:
80
});
對於兩分類資料,使用簡單線性迴歸也能有效,但是其預測效果不是很直觀:
tips
[
“big_tip”
]
=
(
tips
。
tip
/
tips
。
total_bill
)
>
。
15
sns
。
lmplot
(
x
=
“total_bill”
,
y
=
“big_tip”
,
data
=
tips
,
y_jitter
=。
03
);
兩分類問題,直覺(intuitive)的想法是模型能夠返回每個分類相應的機率,從而選擇機率較大的一者作為預測類別。邏輯迴歸 (logistic regression) 很適合這樣的問題,其返回值在
之間,可以看作返回每個類別對應的分類機率。我們選擇一個閾值,當迴歸模型返回的機率值大於閾值時,則選擇該值對應的類別。
sns
。
lmplot
(
x
=
“total_bill”
,
y
=
“big_tip”
,
data
=
tips
,
logistic
=
True
,
y_jitter
=。
03
);
由於邏輯迴歸函式相較線性模型要複雜(邏輯迴歸還包含指數運算操作), 穩健迴歸函式也較為複雜,因此它們的計算量都會被線性模型大,所以為了減少計算量,我們通常會取消置信區間,即設定
ci=None
。
seaborn中會使用
自舉法
)(bootstrapping),來計算置信區間。
另一種使用非引數迴歸擬合的方式——
區域性加權迴歸散點平滑法
(locally weighted scatterplot smoothing,LOWESS),其主要思想是選取一定比例的區域性資料,擬合多項式迴歸曲線,以便觀察到資料的區域性規律和趨勢。
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
data
=
tips
,
lowess
=
True
);
為了觀察迴歸模型的效果,可以使用
residplot()
,繪製觀察點與迴歸曲線上的預測點之間的殘差圖:
# 使用安斯庫姆四重奏資料集中的線性資料
sns
。
residplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’I‘”
),
scatter_kws
=
{
’s‘
:
80
});
如果
residplot()
反應資料的殘差分佈具有結構性,那麼這意味著我們當前選擇的模型不是很適合:
sns
。
residplot
(
x
=
’x‘
,
y
=
’y‘
,
data
=
anscombe
。
query
(
“dataset == ’II‘”
),
scatter_kws
=
{
’s‘
:
80
});
“第三者”插入
以上的內容,我們學習瞭如何探索兩個變數之間的迴歸關係。現在來探究一個更有意思的問題:如果這兩個變數都是關於第三個變數的函式,例如
,那麼我們改變
,會導致
的關係怎麼改變呢?
那麼這裡就可以引入
regplot()
和
lmplot()
的差別了。
regplot()
函式只顯示單一關係,而
lmplot()
將
regplot()
和
FacetGrid
結合,來提供一個基於
facet
的線性迴歸的介面,以此我們可以探索三個的分類變數的互動關係。
關於
FacetGrid
和
facet
,可以檢視
seaborn_statistical。ipynb
中最後一小節的內容。
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
hue
=
’smoker‘
,
data
=
tips
);
此例中,我們加入顧客是否吸菸這一資訊,以此觀察在以是否吸菸分類前提下,顧客總消費和小費之間的關係。
為了使得不同類別資料區分開,為念可以對散點圖的屬性進行修改:
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
hue
=
’smoker‘
,
data
=
tips
,
markers
=
[
’o‘
,
’x‘
],
palette
=
’Set1‘
);
在上圖中,我們設定調色盤的樣式為
Set1
,並且兩個類別的散點樣式分別為點狀和叉狀。
由於
lmplot()
基於
FacetGrid
,這允許我們顯示不至三個變數的關係。我們加入顧客用餐時間的資訊
time
:
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
hue
=
’smoker‘
,
col
=
’time‘
,
data
=
tips
);
我們再上圖基礎上,再加入性別資訊:
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
hue
=
’smoker‘
,
col
=
’time‘
,
row
=
’sex‘
,
data
=
tips
);
控制影象的大小與形狀
在之前,我們使用相同的資料和屬性打印出
lmplot()
和
regplot()
的影象,發現兩者除了影象大小形狀之外,其他基本相同。這是因為
regplot()
影象繪製在一根特殊的軸上。
regplot()
是一個“軸級”函式,這意味著我們可以繪製多個面板(panel)影象,並且精確控制迴歸影象的各種屬性。 如果對
regplot()
函式沒有顯式指定選擇的軸,則它會使用“current active” ( 不知如何翻譯( ̄▽ ̄)“) 的軸。
”current active“ axes 貌似是matplotlib中繪製圖像函式使用的軸物件。
於是,我們可直接使用matplotlib中影象物件返回的軸,來作為繪製
regplot
的軸:
f
,
ax
=
plt
。
subplots
(
figsize
=
(
5
,
6
))
sns
。
regplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
data
=
tips
,
ax
=
ax
);
相比之下,
lmplot()
的影象屬性完全由
FacetGrid
介面控制:
sns
。
lmplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
col
=
’day‘
,
data
=
tips
,
col_wrap
=
2
,
height
=
3
,
aspect
=
1
);
在其他函式中繪製迴歸曲線
除了顯式呼叫
lmplot()
和
regplot()
函式,我們可以在其他繪圖函式中設定
kind=’reg‘
引數來繪製迴歸曲線。
例如我們在聯合分佈函式
jointplot()
中繪製迴歸曲線:
sns
。
jointplot
(
x
=
’total_bill‘
,
y
=
’tip‘
,
kind
=
’reg‘
,
data
=
tips
);
或者使用
pairplot()
,結合
PairGrid
來顯示多個變數之間的線性關係:
sns
。
pairplot
(
tips
,
x_vars
=
[
’total_bill‘
,
’size‘
],
y_vars
=
[
’tip‘
],
height
=
5
,
aspect
=。
8
,
kind
=
’reg‘
);
與
FacetGrid
不同,
PairGrid
將變數兩兩成對,即對
x_vars
中的變數與
y_vars
中的變數做笛卡爾乘積,獲得變數間的配對,然後對每個配對,繪製其相應的關係圖。
和
lmplot()
類似,如果我們希望增加第三個變數作為條件資訊,則可以對
pairplot()
新增
hue
語義:
sns
。
pairplot
(
tips
,
x_vars
=
[
’total_bill‘
,
’size‘
],
y_vars
=
[
’tip‘
],
hue
=
’smoker‘
,
height
=
5
,
aspect
=。
8
,
kind
=
’reg‘
);
Reference
[1] Visualizing regression models
[2] 個人seaborn官方教程翻譯:Burofen/seaborn-tutorials-from-scratch
上一篇:智慧決策型產品覆盤
下一篇:向左VS向右 哪種睡覺姿勢最健康