0 引言
筆者在閱讀周志華老師的《機器學習》中的線性判別分析(LDA)章節時,很多地方推導不太明白,於是本文將結合該書做深入補充推導與python程式碼實踐。
在上篇文章中,
我們講解了如何利用LDA實現二分類問題,本文我們繼續推導下如何用LDA實現多分類問題。可以將LDA推廣到多分類任務中(假定分為N個類),當使用LDA處理多分類問題時,通常是作為一個降維工具來使用的。
1 預備知識
可以將LDA推廣到多分類任務中(假定分為N個類),當使用LDA處理多分類問題時,通常是作為一個降維工具來使用的。多分類示意圖如下:
3 求解最佳化方程
4 LDA降維流程
5 Iris資料集
Iris Data Set(鳶尾屬植物資料集)被廣泛用於分類演算法的示例中,很多機器學習相關的資料都對這個資料集進行了介紹。它首次出現在著名的英國統計學家和生物學家Ronald Fisher 1936年的論文《The use of multiple measurements in taxonomic problems》中,被用來介紹線性判別式分析。在這個資料集中,包括了三類不同的鳶尾屬植物:Iris Setosa,Iris Versicolour,Iris Virginica。每類收集了50個樣本,因此這個資料集一共包含了150個樣本。
該資料集測量了所有150個樣本的4個特徵,分別是:
1。 sepal length(花萼長度)
2。 sepal width(花萼寬度)
3。 petal length(花瓣長度)
4。 petal width(花瓣寬度)
以上四個特徵的單位都是釐米(cm)。通常使用
表示樣本量的大小,
表示每個樣本所具有的特徵數。因此在該資料集中,
。
6 python實現LDA降維
根據LDA進行降維的演算法流程。我們使用python實現LDA降維,對Iris資料集從四維降至二維。模擬結果如下:
(a)本文LDA方法降維表現
(b)sklearn自帶LDA方法降維表現
程式碼如下:
import
numpy
as
np
from
sklearn。datasets
import
load_iris
import
matplotlib。pyplot
as
plt
from
sklearn。discriminant_analysis
import
LinearDiscriminantAnalysis
def
LDA_dimensionality
(
X
,
y
,
k
):
‘’‘
X為資料集,y為label,k為目標維數
’‘’
label_
=
list
(
set
(
y
))
X_classify
=
{}
for
label
in
label_
:
Xi
=
np
。
array
([
X
[
i
]
for
i
in
range
(
len
(
X
))
if
y
[
i
]
==
label
])
X_classify
[
label
]
=
Xi
mju
=
np
。
mean
(
X
,
axis
=
0
)
mju_classify
=
{}
for
label
in
label_
:
mjui
=
np
。
mean
(
X_classify
[
label
],
axis
=
0
)
mju_classify
[
label
]
=
mjui
# 計算類內散度矩陣
# Sw = np。dot((X - mju)。T, X - mju)
Sw
=
np
。
zeros
((
len
(
mju
),
len
(
mju
)))
for
i
in
label_
:
Sw
+=
np
。
dot
((
X_classify
[
i
]
-
mju_classify
[
i
])
。
T
,
X_classify
[
i
]
-
mju_classify
[
i
])
# 計算類間散度矩陣
# Sb=St-Sw
Sb
=
np
。
zeros
((
len
(
mju
),
len
(
mju
)))
for
i
in
label_
:
Sb
+=
len
(
X_classify
[
i
])
*
np
。
dot
((
mju_classify
[
i
]
-
mju
)
。
reshape
(
(
len
(
mju
),
1
)),
(
mju_classify
[
i
]
-
mju
)
。
reshape
((
1
,
len
(
mju
))))
eig_vals
,
eig_vecs
=
np
。
linalg
。
eig
(
np
。
linalg
。
inv
(
Sw
)
。
dot
(
Sb
))
# 計算Sw-1*Sb的特徵值和特徵矩陣
# 按從小到大排序,輸出排序指示值
sorted_indices
=
np
。
argsort
(
eig_vals
)
# 反轉
sorted_indices
=
sorted_indices
[::
-
1
]
# 提取前k個特徵向量
topk_eig_vecs
=
eig_vecs
[:,
sorted_indices
[
0
:
k
:
1
]]
“”“https://blog。csdn。net/qq_41973536/article/details/82690242
s[i:j:k],i起始位置,j終止位置,k表示步長,預設為1
s[::-1]是從最後一個元素到第一個元素複製一遍(反向)
”“”
“”“也可使用如下方法”“”
# # 按從小到大排序,輸出排序指示值
# sorted_indices = np。argsort(eig_vals)
# # 提取前k個特徵向量
# topk_eig_vecs = eig_vecs[:, sorted_indices[:-k - 1:-1]]
return
topk_eig_vecs
if
‘__main__’
==
__name__
:
iris
=
load_iris
()
X
=
iris
。
data
y
=
iris
。
target
W
=
LDA_dimensionality
(
X
,
y
,
2
)
X_new
=
np
。
dot
((
X
),
W
)
# 估計值
plt
。
figure
(
1
)
plt
。
scatter
(
X_new
[:,
0
],
X_new
[:,
1
],
marker
=
‘o’
,
c
=
y
)
plt
。
title
(
“LDA reducing dimension - our method”
)
plt
。
xlabel
(
“x1”
)
plt
。
ylabel
(
“x2”
)
# 與sklearn中的LDA函式對比
lda
=
LinearDiscriminantAnalysis
(
n_components
=
2
)
lda
。
fit
(
X
,
y
)
X_new
=
lda
。
transform
(
X
)
X_new
=
-
X_new
# 為了對比方便,取個相反數,並不影響分類結果
(
X_new
)
plt
。
figure
(
2
)
plt
。
scatter
(
X_new
[:,
0
],
X_new
[:,
1
],
marker
=
‘o’
,
c
=
y
)
plt
。
title
(
“LDA reducing dimension - sklearn method”
)
plt
。
xlabel
(
“x1”
)
plt
。
ylabel
(
“x2”
)
plt
。
show
()
參考資料:
《機器學習》周志華
https://
blog。csdn。net/z96201348
9/article/details/79871789
https://
blog。csdn。net/weixin_39
910711/article/details/82285670
https://www。
cnblogs。com/Belter/p/88
31216。html