วิธีการคำนวณเคอร์เนล Gaussian ได้อย่างมีประสิทธิภาพในจำนวน [ปิด]


12

ฉันมีอาร์เรย์ numpy ที่มีคอลัมน์mและnแถวคอลัมน์ที่มีมิติและ datapoints แถว

ตอนนี้ฉันต้องคำนวณค่าเคอร์เนลสำหรับการรวมกันของจุดข้อมูล

สำหรับเคอร์เนลเชิงเส้นฉันทำได้ง่ายๆK(xi,xj)=xi,xjdot(X,X.T)

ฉันจะคำนวณค่าทั้งหมดสำหรับเคอร์เนล Gaussianอย่างมีประสิทธิภาพด้วยs ?K(xi,xj)=expxixj22s2


1
ถ้าคุณไม่สนใจมากเกินไปเกี่ยวกับการเพิ่มขึ้นของการคำนวณสองครั้งคุณสามารถทำS=XXTแล้วK(xผม,xJ)=ประสบการณ์(-(Sผมผม+SJJ-2SผมJ)/s2)โดยที่แน่นอนSผมJคือ(ผม,J)องค์ประกอบของ TH S S นี่อาจจะเป็นไม่ได้มีเสถียรภาพมากที่สุดตัวเลขทั้งแม้ว่า
พระคาร์ดินัล

2
(หลายปีต่อมา) สำหรับอาร์เรย์ขนาดใหญ่โปรดดูsklearn.metrics.pairwise.pairwise_distances.htmlใน scikit เรียนรู้
ปฏิเสธ

คำตอบ:


26

ฉันคิดว่าปัญหาหลักคือการได้รับระยะทางคู่ได้อย่างมีประสิทธิภาพ เมื่อคุณมีส่วนที่เหลือเป็นองค์ประกอบที่ชาญฉลาด

ในการทำเช่นนี้คุณอาจต้องการใช้สคิเปีย ฟังก์ชั่นscipy.spatial.distance.pdistทำในสิ่งที่คุณต้องการและscipy.spatial.distance.squareformอาจจะทำให้ชีวิตของคุณง่ายขึ้น

ดังนั้นถ้าคุณต้องการเคอร์เนลเมทริกซ์ที่คุณทำ

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)

เอกสารที่สามารถพบได้ที่นี่ 


3
ดูเหมือนว่าผมว่าคำตอบ bayerj ต้องมีการปรับเปลี่ยนเล็กน้อยเพื่อให้พอดีกับสูตรในความต้องการอื่นกรณีที่ใครสักคนมันK = scipy.exp(-pairwise_dists**2 / s**2)
โคลอี

ถ้าใครอยากรู้อยากเห็นอัลกอริทึมที่ใช้โดยpdistง่ายมาก: มันเป็นแค่วง C-ดำเนินการโดยตรงคำนวณระยะทางในวิธีที่ชัดเจน , บ่วงถูกทำที่นี่ ; ไม่มี vectorization แฟนซีหรือสิ่งใดนอกเหนือจากสิ่งที่ผู้รวบรวมสามารถทำได้โดยอัตโนมัติ
Dougal

11

ในฐานะที่เป็นภาคผนวกขนาดเล็กที่จะตอบ bayerj ของ SciPy ของฟังก์ชั่นได้โดยตรงสามารถคำนวณบรรทัดฐานยุคลิดสแควร์โดยเรียกมันว่าเป็นpdist pdist(X, 'sqeuclidean')รหัสเต็มสามารถเขียนได้อย่างมีประสิทธิภาพมากขึ้นเช่น

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
หรือเพียงแค่pairwise_sq_dists = cdist(X, X, 'sqeuclidean')ให้ซึ่งเหมือนกัน
user1721713

5

คุณยังสามารถเขียนแบบตารางด้วยมือ:

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 แต่ใช้งานได้ช้าลง 30%


สิ่งนี้ซึ่งเป็นวิธีการที่พระคาร์ดินัลแนะนำในการแสดงความคิดเห็นอาจเร่งความเร็วขึ้นเล็กน้อยโดยใช้การดำเนินการในสถานที่ มันเป็นวิธีการที่ scikit การเรียนรู้ไม่ได้มีโทรของคุณ einsumX2
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)

ซึ่งเท่ากับ

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

คุณสามารถคำนวณ RBF ได้อย่างมีประสิทธิภาพจากหมายเหตุโค้ดด้านบนว่าค่าแกมม่าคือ 1 เนื่องจากมันเป็นค่าคงที่ s ที่คุณร้องขอนั้นก็เป็นค่าคงที่เดียวกัน


ยินดีต้อนรับสู่เว็บไซต์ของเรา! เราให้ความสำคัญกับ Stack Overflow ที่แตกต่างออกไปเล็กน้อยโดยทั่วไปแล้วเรามักจะให้ความสำคัญกับโค้ดน้อยลงและมีแนวคิดพื้นฐานมากขึ้นดังนั้นจึงอาจมีความคิดเห็นเกี่ยวกับโค้ดของคุณหรือให้ความคิดสั้น ๆ ว่าแนวคิดหลัก ๆ คำตอบอื่น ๆ ได้ทำไปแล้ว นั่นจะช่วยอธิบายว่าคำตอบของคุณแตกต่างจากคนอื่นอย่างไร
Silverfish

นี่จะช้ากว่าคำตอบอื่น ๆ มากเพราะใช้ Python loops แทน vectorization
Dougal

-1

ฉันคิดว่านี่จะช่วย:

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

3
ยินดีต้อนรับสู่เว็บไซต์ @Kernel คุณสามารถแสดงคณิตศาสตร์โดยใส่นิพจน์ระหว่างเครื่องหมาย $ และใช้ LateX เช่นไวยากรณ์ และคุณสามารถแสดงรหัส (พร้อมการเน้นไวยากรณ์) โดยเยื้องบรรทัดด้วย 4 ช่องว่าง ดูความช่วยเหลือในการแก้ไข markdown สำหรับแนวทางการจัดรูปแบบและคำถามที่พบบ่อยสำหรับแนวทางทั่วไปเพิ่มเติม
แอนทอน Vernet

1
นี่ไม่ได้สะท้อนสิ่งที่เป็นปัญหาหรือไม่
whuber
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.