有監督度量學習算法利用輸入點與目標標籤作爲來學習一個距離矩陣,這個距離矩陣拉近同類別的點(分類問題)或者目標值鄰近的點(迴歸問題)的距離,並使不同類別或目標值相差大的點的互相遠離。
1. 通用API
有監督的度量學習算法實質上利用了與scikit-learn相同的應用程序接口(API)。
1.1 輸入數據
爲了訓練一個模型,我們需要兩個array-like對象:與。應該爲 的2D數組,其中爲樣本的個數,爲數據的維數。爲大小爲的一維數組,該數組包含中每個數據的類別標籤(迴歸問題是爲實數,例如度量學習核迴歸MLKR)。
下面給出用於度量學習的數據例子,數據中包含兩種類別:狗與貓。
import numpy as np
X = np.array([[2.3, 3.6], [0.2, 0.5], [6.7, 2.1]])
y = np.array(['dog', 'cat', 'dog'])
注意:我們也可以利用數據預處理器來替代直接給出2D數組形式的輸入,詳情請查閱Preprocessor一節。
1.2 Fit, transform以及其它
有監督度量學習算法的目標是爲了將數據轉換到新空間中,在該空間中,同類別的兩個數據點的距離會非常小,而不同類別的兩個數據的距離則很大。爲了得到這個轉換矩陣,我們需要利用訓練數據來fit度量學習器(例子:最近鄰成分分析NCA)。
>>> from metric_learn import NCA
>>> nca = NCA(random_state=42)
>>> nca.fit(X, y)
NCA(init=None, max_iter=100, n_components=None, num_dims='deprecated',
preprocessor=None, random_state=42, tol=None, verbose=False)
上面的代碼塊已經fit
了度量學習器nca
,現在我們可以將nca
用於新的數據上。
首先,我們可以利用transform
將數據轉換到新的狀態空間。下面給出轉換兩個數據到嵌入空間的例子:
>>> X_new = np.array([[9.4, 4.1], [2.1, 4.4]])
>>> nca.transform(X_new)
array([[ 5.91884732, 10.25406973],
[ 3.1545886 , 6.80350083]])
通過以上步驟,我們的度量學習器已經學到了數據點之間的距離,我們有以下兩種使用它的途徑:
- 我們可以利用
score_pairs
返回兩個數據點之間的距離:
>>> nca.score_pairs([[[3.5, 3.6], [5.6, 2.4]], [[1.2, 4.2], [2.1, 6.4]]])
array([0.49627072, 3.65287282])
- 也可以利用
get_metric
函數返回兩個數據點之間的距離:
>>> metric_fun = nca.get_metric()
>>> metric_fun([3.5, 3.6], [5.6, 2.4])
0.4962707194621285
注意:如果度量學習是學習馬氏距離,我們可以利用
get_mahalanobis_matrix
得到學習到的矩陣。
>>> nca.get_mahalanobis_matrix()
array([[0.43680409, 0.89169412],
[0.89169412, 1.9542479 ]])
2. 算法
2.1 LMNN
大邊緣最近鄰度量學習 Large Margin Nearest Neighbor Metric Learning (LMNN)
LMNN在kNN分類任務的前提下學習一個馬氏距離度量。學習到的度量嘗試保持同類別的K最近鄰很近,並將不同類別的數據以大邊緣隔離開來。該算法不對數據的分佈作假設。
該距離是通過求解以下優化問題來學習得到的:
此處,爲一數據點,爲的一個具有相同標籤的k最近鄰點,爲所有其它不同標籤的k最近鄰點,都是指標參數,表示爲與相同標籤的k最近鄰數,表示屬於不同的類別,表示損失函數Hinge Loss。
import numpy as np
from metric_learn import LMNN
from sklearn.datasets import load_iris
iris_data = load_iris()
X = iris_data['data']
Y = iris_data['target']
lmnn = LMNN(k=5, learn_rate=1e-6)
lmnn.fit(X, Y, verbose=False)
參考文獻:
[1] Weinberger et al. Distance Metric Learning for Large Margin Nearest Neighbor Classification. JMLR 2009
[2] Wikipedia entry on Large Margin Nearest Neighbor
2.2 NCA
近鄰成分分析 Neighborhood Components Analysis (NCA)
NCA是一個距離度量學習算法,該度量算法旨在提升最近鄰分類器的精確度(與傳統歐式距離相比較)。算法直接最大化訓練集上留一法KNN評價器的隨機變量。它也可以用來學習一個低張維度的線性轉換矩陣,用於數據可視化和快速分類。
利用分解,並定義概率,此概率通過的鄰居來對其進行正確分類的概率,如下通過馬氏距離意義下的softmax似然值表示:
對每一個與近鄰的數據點,我們將上式計算的概率加和得到被正確分類的最終概率:
優化問題變爲找到矩陣使得所有數據點的正確分類概率和最大:
import numpy as np
from metric_learn import NCA
from sklearn.datasets import load_iris
iris_data = load_iris()
X = iris_data['data']
Y = iris_data['target']
nca = NCA(max_iter=1000)
nca.fit(X, Y)
參考文獻:
[1] Goldberger et al. Neighbourhood Components Analysis. NIPS 2005
[2] Wikipedia entry on Neighborhood Components Analysis
2.3 LFDA
局部Fisher差別分析 Local Fisher Discriminant Analysis (LFDA)
LFDA是一個線性的有監督降維方法。該算法對於多模態問題特別有效,所謂的多模態就是一個或多個類別在狀態空間中包含多個獨立的聚集。LFDA的核心優化問題是一個廣義特徵值求解問題。
該算法定義Fisher局部的類內、類間散佈矩陣
此處,
爲接近矩陣第個元素,可以根據局部縮放方法來計算。
因此,學習問題變成推導LFDA變換矩陣:
得到的變換矩陣可保證同類中鄰近的數據靠的更近,不同類中的數據離的更遠,但是不能保證同類中離的遠的數據靠近。
import numpy as np
from metric_learn import LFDA
from sklearn.datasets import load_iris
iris_data = load_iris()
X = iris_data['data']
Y = iris_data['target']
lfda = LFDA(k=2, dim=2)
lfda.fit(X, Y)
參考文獻:
[1] Sugiyama. Dimensionality Reduction of Multimodal Labeled Data by Local Fisher Discriminant Analysis. JMLR 2007
[2] Tang. Local Fisher Discriminant Analysis on Beer Style Clustering.
2.4 MLKR
核迴歸度量學習 Metric Learning for Kernel Regression (MLKR)
MLKR是一個有監督度量學習算法,該算法通過直接最小化留一法迴歸誤差來學習一個距離函數。MLKR可以被看作爲一個有監督版本的PCA,能用於降維和高維數據可視化。
理論上,MLKR也能應用於許多不同形式的核函數和距離度量。此處,我們利用高斯核函數與馬氏距離。一個高斯核函數如下所示:
此處,爲某一測度下的距離平方,此處該測度爲馬氏距離,爲,爲推導出的分解矩陣爲:。
可以歸併到中,此處我們簡單的設。我們利用以下在訓練樣本上的累積留一法二次迴歸誤差作爲損失函數:
此處,預測是由核迴歸器得到的:
from metric_learn import MLKR
from sklearn.datasets import load_iris
iris_data = load_iris()
X = iris_data['data']
Y = iris_data['target']
mlkr = MLKR()
mlkr.fit(X, Y)
參考文獻:
[1] Weinberger et al. Metric Learning for Kernel Regression. AISTATS 2007
2.5 有監督版本的弱監督度量學習算法
每一個弱監督度量學習算法都有一個對應的有監督版本*_Supervised
,其中,相似元組從標籤信息中生成並傳遞給底層算法。
對於成對的學習者(參見“成對學習”),使用metric_learn.constraints.positive_negative_pair
函數採樣成對(數據集中兩個點的元組)和成對標籤(int
,表示這兩個點是相似的(+1)還是不同的(-1))。爲了對(標籤+1的)正對進行抽樣,該方法將對來自同一標籤的所有樣本進行抽樣,並從中隨機抽取一對樣本。爲了對負對(標籤-1)進行抽樣,該方法將查看來自不同類的所有樣本,並隨機抽取其中的一對樣本。該方法將嘗試構建num_constraints
正對和num_constraints
負對,但有時它找不到足夠的一個,因此強制same_length=True
將返回兩個lenghts
的最小值。
使用四元組學習器(見基於四元組的學習)以監督的方式,積極的和消極的對採樣如上和連接,這樣我們有一個3維四元組的數組,其中每個成套的一分之二點來自同一個類,最後兩個點來自不同的類(事實上類似最後兩點應該低於前兩個點)。
from metric_learn import MMC_Supervised
from sklearn.datasets import load_iris
iris_data = load_iris()
X = iris_data['data']
Y = iris_data['target']
mmc = MMC_Supervised(num_constraints=200)
mmc.fit(X, Y)