t-SNE Python 구현 : Kullback-Leibler 분기


11

[1]에서와 같이 t-SNE는 특정 조건이 충족 될 때까지 KL (Kullback-Leibler) 발산을 점진적으로 줄임으로써 작동합니다. t-SNE의 제작자는 KL 분기를 시각화의 성능 기준으로 사용하도록 제안합니다.

Kullback-Leibler가 t-SNE가보고 한 차이점을 비교할 수 있습니다. t-SNE를 10 번 실행하고 KL 발산이 가장 낮은 솔루션을 선택하는 것이 좋습니다 [2]

t-SNE의 두 가지 구현을 시도했습니다.

  • 파이썬 : sklearn.manifold.TSNE ().
  • R : 라이브러리에서 tsne (tsne).

이 두 가지 구현 모두 상세도가 설정되면 각 반복에 대한 오류 (Kullback-Leibler divergence)를 인쇄하십시오. 그러나 그들은 사용자 가이 정보를 얻도록 허용하지 않습니다.

예를 들어 코드는 다음과 같습니다.

import numpy as np
from sklearn.manifold import TSNE
X = np.array([[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 1]])
model = TSNE(n_components=2, verbose=2, n_iter=200)
t = model.fit_transform(X)

생산 :

[t-SNE] Computing pairwise distances...
[t-SNE] Computed conditional probabilities for sample 4 / 4
[t-SNE] Mean sigma: 1125899906842624.000000
[t-SNE] Iteration 10: error = 6.7213750, gradient norm = 0.0012028
[t-SNE] Iteration 20: error = 6.7192064, gradient norm = 0.0012062
[t-SNE] Iteration 30: error = 6.7178683, gradient norm = 0.0012114
...
[t-SNE] Error after 200 iterations: 0.270186

이제 내가 이해하는 한 0.270186 은 KL 발산이어야합니다. 그러나 모델 이나 t (간단한 numpy.ndarray) 에서이 정보를 얻을 수 없습니다 .

이 문제를 해결하기 위해 나는 : i) 스스로 KL 발산을 계산한다. ii) TSNE () 함수의 출력을 캡처하고 파싱하기 위해 파이썬에서 불쾌한 일을한다 [3]. 그러나 : i) TSNE ()가 이미 계산했을 때 KL 발산을 다시 계산하는 것은 매우 어리석은 일입니다. ii) 코드 측면에서 약간 이례적입니다.

다른 제안이 있습니까? 이 라이브러리를 사용하여이 정보를 얻는 표준 방법이 있습니까?

나는 R 의 tsne 라이브러리를 시도했지만 언급했지만 파이썬 sklearn 구현 에 중점을 두는 대답을 선호합니다 .


참고 문헌

[1] http://nbviewer.ipython.org/urls/gist.githubusercontent.com/AlexanderFabisch/1a0c648de22eff4a2a3e/raw/59d5bc5ed8f8bfd9ff1f7faa749d1b095aa97d5a/t-SNE.ipynb

[2] http://homepage.tudelft.nl/19j49/t-SNE.html

[3] /programming/16571150/how-to-capture-stdout-output-from-a-python-function-call

답변:


4

scikit-learn의 TSNE 소스는 순수 Python입니다. Fit fit_transform()메소드는 실제로 개인 _fit()함수를 호출 한 다음 개인 함수를 호출 _tsne()합니다. 이 _tsne()함수에는 error맞춤이 끝날 때 인쇄되는 지역 변수 가 있습니다. 한 줄 또는 두 줄의 소스 코드를 쉽게 변경하여 해당 값을 반환 할 수있는 것처럼 보입니다 fit_transform().


본질적으로 내가 할 수있는 일은 TSNE 인스턴스에서 나중에 검색하기 위해 _tsne () 끝에 self.error = error를 설정하는 것입니다. 예, 그러나 그것은 sklearn.manifold 코드를 변경하는 것을 의미하며, 개발자가 정보를 얻는 다른 방법을 생각했는지 또는 정보를 얻지 못한 이유를 생각하는지 궁금합니다 (예 : '오류'가 쓸모없는 것으로 간주됩니까?). 또한 해당 코드를 변경하면 내 코드를 실행하는 모든 사람들이 sklearn 설치에서 동일한 핵을 갖도록해야합니다. 그게 당신이 제안한 것입니까, 아니면 잘못 되었습니까?
joker

예, 이것이 가능한 해결책으로 제안한 것입니다. scikit-learn은 오픈 소스이므로 솔루션을 풀 요청으로 제출하여 향후 릴리스에 작성자가 포함시킬 수 있는지 확인할 수도 있습니다. 나는 그들이 다양한 것들을 포함하거나 포함하지 않은 이유에 대해 말할 수 없습니다.
Trey

2
감사. 다른 누군가가 이것에 관심이 있다면 github.com/scikit-learn/scikit-learn/pull/3422 .
joker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.