Gauss çekirdeği nümerik olarak etkili bir şekilde nasıl hesaplanır [kapalı]


12

M sütunları ve n satırları olan sütunları ve satırları veri noktaları olan bir numpy dizi var .

Şimdi her veri noktası kombinasyonu için çekirdek değerlerini hesaplamam gerekiyor.

Doğrusal bir çekirdek için K(xben,xj)=xben,xj Sadece yapabilirdot(X,X.T)

K(xben,xj)=tecrübe-xben-xj22s2


1
Eğer hesaplamalarda iki artış faktörünü çok , her zaman \ newcommand {\ m} {\ mathbf} \ m S = \ m X \ m X ^ TS=XXT ve sonra K(xben,xj)=tecrübe(-(Sbenben+Sjj-2Sbenj)/s2) burada, tabii ki, Sbenj olan (i, j) \ m S(ben,j) öğesinin . Yine de, bu muhtemelen en sayısal olarak kararlı değil . S
kardinal

2
(Yıllar sonra) büyük seyrek diziler için scikit- learn'daki sklearn.metrics.pairwise.pairwise_distances.html adresine bakın .
denis

Yanıtlar:


26

Bence asıl sorun çift mesafeleri verimli bir şekilde elde etmektir. Bir kez sen-si olmak kalan gerisi element akıllıca.

Bunu yapmak için muhtemelen scipy kullanmak istiyorsunuz. İşlev scipy.spatial.distance.pdistihtiyacınız olanı yapar vescipy.spatial.distance.squareform muhtemelen hayatınızı kolaylaştıracaktır.

Eğer çekirdek matrisini istiyorsanız

from scipy.spatial.distance import pdist, squareform
  # this is an NxD matrix, where N is number of items and D its dimensionalites
X = loaddata() 
pairwise_dists = squareform(pdist(X, 'euclidean'))
K = scip.exp(-pairwise_dists ** 2 / s ** 2)

Belgeleri burada bulabilirsiniz


3
Bana öyle geliyor ki bayerj'in cevabı, başka birine ihtiyaç duyması durumunda formüle uyacak bazı küçük değişiklikler gerektiriyor:K = scipy.exp(-pairwise_dists**2 / s**2)
chloe

Herkes merak ediyorsa, kullanılan algoritma pdistçok basittir: sadece mesafeleri doğrudan açık bir şekilde hesaplayan C tarafından uygulanan bir döngü , döngü burada yapılır ; hiçbir süslü vectorizasyon veya derleyicinin otomatik olarak başarabileceği her şeyin ötesinde bir şey.
Dougal

11

Bayerj'in cevabına küçük bir ek olarak scipy'nin pdistfonksiyonu, kare öklidik normları doğrudan olarak adlandırarak hesaplayabilir pdist(X, 'sqeuclidean'). Tam kod daha sonra daha verimli bir şekilde yazılabilir.

from scipy.spatial.distance import pdist, squareform
  # this is an NxD matrix, where N is number of items and D its dimensionalites
X = loaddata() 
pairwise_sq_dists = squareform(pdist(X, 'sqeuclidean'))
K = scip.exp(-pairwise_sq_dists / s**2)

1
Ya da sadece pairwise_sq_dists = cdist(X, X, 'sqeuclidean')aynı şeyi verir.
user1721713

5

Kare formunu elle de yazabilirsiniz:

import numpy as np
def vectorized_RBF_kernel(X, sigma):
    # % This is equivalent to computing the kernel on every pair of examples
    X2 = np.sum(np.multiply(X, X), 1) # sum colums of the matrix
    K0 = X2 + X2.T - 2 * X * X.T
    K = np.power(np.exp(-1.0 / sigma**2), K0)
    return K

PS ama bu% 30 daha yavaş çalışıyor


Yorumlarda kardinal tarafından önerilen yöntem olan bu, yerinde operasyonlar kullanılarak biraz hızlandırılabilir. Bu var bunu nasıl scikit-öğrenme ile, bir einsumçağrı şunlara ait X2.
Dougal

4
def my_kernel(X,Y):
    K = np.zeros((X.shape[0],Y.shape[0]))
    for i,x in enumerate(X):
        for j,y in enumerate(Y):
            K[i,j] = np.exp(-1*np.linalg.norm(x-y)**2)
    return K

clf=SVR(kernel=my_kernel)

bu eşittir

clf=SVR(kernel="rbf",gamma=1)

Yukarıdaki kod notundan RBF'yi etkili bir şekilde hesaplayabilirsiniz.


Sitemize hoşgeldiniz! Stack Overflow'a biraz daha farklı bir vurgu yapıyoruz, çünkü genellikle koda daha az odaklanıyoruz ve temel fikirlere daha fazla odaklanıyoruz, bu nedenle kodunuza açıklama eklemeye veya anahtar fikirlerin ne olduğu hakkında kısa bir fikir vermeye değer olabilir. başka cevaplar da oldu. Bu, cevabınızın diğerlerine göre nasıl farklı olduğunu açıklamaya yardımcı olacaktır.
Silverfish

Bu, diğer cevaplardan çok daha yavaş olacaktır çünkü vektörleştirme yerine Python döngüleri kullanır.
Dougal

-1

Bunun yardımcı olacağını düşünüyorum:

def GaussianKernel(v1, v2, sigma):
    return exp(-norm(v1-v2, 2)**2/(2.*sigma**2))

3
@Kernel sitesine hoş geldiniz. İfadeyi $ işaretleri arasına koyarak ve LateX benzeri sözdizimini kullanarak matematiği görüntüleyebilirsiniz. Ve satırları 4 boşluk girintili olarak kodu (sözdizimi vurgulamalı) görüntüleyebilirsiniz. Biçimlendirme yönergeleri için işaretleme düzenleme yardımına ve daha genel yönergeler için SSS'ye bakın.
Antoine Vernet

1
Bu sadece soruda ne olduğunu yansıtmıyor mu?
whuber
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.