t-SNE Python uygulaması: Kullback-Leibler sapması


11

t-SNE, [1] 'de olduğu gibi, belirli bir koşul karşılanıncaya kadar Kullback-Leibler (KL) sapmasını giderek azaltarak çalışır. T-SNE'nin yaratıcıları, KL diverjansını görselleştirmeler için bir performans kriteri olarak kullanmanızı önerir:

t-SNE'nin bildirdiği Kullback-Leibler sapmalarını karşılaştırabilirsiniz. T-SNE'yi on kez çalıştırmak ve en düşük KL diverjansına sahip çözümü seçmek son derece iyidir [2]

T-SNE'nin iki uygulamasını denedim:

  • python : sklearn.manifold.TSNE ().
  • R : tsne, kütüphaneden (tsne).

Her iki uygulama da ayrıntı ayarlandığında, her yineleme için hatayı (Kullback-Leibler sapması) yazdırın. Ancak, kullanıcının bana biraz garip görünen bu bilgiyi almasına izin vermiyorlar.

Örneğin, kod:

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)

üretir:

[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

Şimdi anladığım kadarıyla, 0.270186 KL sapması olmalı. Ancak ne model ne de t (ki basit bir numpy.ndarray) bu bilgiyi alamıyorum.

Bu sorunu çözmek için: i) KL sapmasını kendim hesaplayabilirim, ii) Python'da TSNE () fonksiyonunun çıktısını yakalamak ve ayrıştırmak için kötü bir şey yapmak [3]. Bununla birlikte: i) KL sapmasını yeniden hesaplamak oldukça aptal olacaktır, TSNE () zaten hesapladığında, ii) kod açısından biraz sıra dışı olurdu.

Başka öneriniz var mı? Bu kütüphaneyi kullanarak bu bilgiyi almanın standart bir yolu var mı?

R'nin tsne kütüphanesini denediğimi söylemiştim, fakat cevapların python sklearn uygulamasına odaklanmasını tercih ederim .


Referanslar

[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

Yanıtlar:


4

Scikit-learn'daki TSNE kaynağı saf Python'da. Fit fit_transform()yöntemi aslında _fit()daha sonra özel bir işlevi çağıran özel bir işlevi çağırıyor _tsne(). Bu _tsne()işlev, errorsığdırmanın sonunda yazdırılan yerel bir değişkene sahiptir. Bu değerin döndürülmesi için kaynak kodunun bir veya iki satırını kolayca değiştirebileceğiniz anlaşılıyor fit_transform().


Aslında yapabileceğim, daha sonra TSNE örneğinden almak için _tsne () sonunda self.error = error ayarlanmasıdır. Evet, ama bu sklearn.manifold kodunu değiştirmek anlamına gelecektir ve geliştiricilerin bilgi almak için başka yollar düşünüp düşünmediğini veya neden yapmadıklarını merak ediyordum (yani: 'hata' onlar tarafından işe yaramaz mı?). Ayrıca, eğer bu kodu değiştirdiysem sklearn kurulumlarında aynı kesmek için kodumu çalıştıran tüm insanlara ihtiyacım olacaktı. Önerdiğin bu mu yoksa yanlış mı anladım?
joker

Evet, olası bir çözüm olarak önerdiğim buydu. Scikit-learn açık kaynak olduğundan, çözümünüzü bir çekme isteği olarak gönderebilir ve yazarların bunu gelecekteki sürümlere dahil edip etmeyeceğini görebilirsiniz. Neden çeşitli şeyler yaptığını ya da içermediğini konuşamıyorum.
Trey

2
Teşekkürler. Başka biri bununla ilgileniyorsa, github.com/scikit-learn/scikit-learn/pull/3422 .
joker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.