두 버전의 코드를 모두 파헤쳐서 두 기능이 모두 무엇을하는지 이해하고 있다고 생각합니다. 작은 간단한 X
(밀도)와
시작 :
X = np.arange(9.).reshape(3,3)
pdist
코사인을 수행합니다 _row_norms
은 행 점이다
norms = _row_norms(X)
_distance_wrap.pdist_cosine_wrap(_convert_to_double(X), dm, norms)
-einsum
를 사용하여 : 그래서
norms = np.sqrt(np.einsum('ij,ij->i', X,X)
가 이 첫 번째 장소는입니다.은 배열이어야합니다. 생산
(아마 사이 썬에서) 나는 cosine_wrap 파고하지 않은,하지만 그것을 할 것으로 보인다
xy = np.dot(X, X.T)
# or xy = np.einsum('ij,kj',X,X)
d = np.zeros((3,3),float) # square receiver
d2 = [] # condensed receiver
for i in range(3):
for j in range(i+1,3):
val=1-xy[i,j]/(norms[i]*norms[j])
d2.append(val)
d[j,i]=d[i,j]=val
print('array')
print(d)
print('condensed',np.array(d2))
from scipy.spatial import distance
d1=distance.pdist(X,'cosine')
print(' pdist',d1)
:
array
[[ 0. 0.11456226 0.1573452 ]
[ 0.11456226 0. 0.00363075]
[ 0.1573452 0.00363075 0. ]]
condensed [ 0.11456226 0.1573452 0.00363075]
pdist [ 0.11456226 0.1573452 0.00363075]
distance.squareform(d1)
내 d
배열로 같은 일을 생성합니다.
I는 해당 norm
외적으로 xy
내적 나누어 동일한 정방형 어레이를 생성 할 수
dd=1-xy/(norms[:,None]*norms)
dd[range(dd.shape[0]),range(dd.shape[1])]=0 # clean up 0s
또는 내적을 찍기 전에 X
를 정규화한다.이것은 scikit
버전이하는 것처럼 보입니다.
Xnorm = X/norms[:,None]
1-np.einsum('ij,kj',Xnorm,Xnorm)
scikit
빨리 스파 스 계산을 할 몇 가지 사이 썬 코드 추가 (sparse.sparse
에서 제공하는 이상을,하지만 같은 csr
형식 사용)했습니다
from scipy import sparse
Xc=sparse.csr_matrix(X)
# csr_row_norm - pyx of following
cnorm = Xc.multiply(Xc).sum(axis=1)
cnorm = np.sqrt(cnorm)
X1 = Xc.multiply(1/cnorm) # dense matrix
dd = 1-X1*X1.T
스파 스 매트릭스와 빠른 압축 된 양식을 얻으려면을 I X1*X1.T
의 빠른 압축 버전을 구현해야한다고 생각합니다. 즉, 희소 행렬 곱셈이 구현되는 방식을 이해해야합니다 (c
코드). scikit
cython '빠른 스파 스'코드도 아이디어를 줄 수 있습니다.
numpy
에는 직설적 인 파이썬 코드 인 일부 tri...
기능이 있습니다. 트라이 계산을 직접 구현하여 시간이나 공간을 절약하려고하지 않습니다. 삼각형 배열의보다 복잡한 가변 길이 단계를 수행하는 것보다 모양과 스트라이드가있는 nd 배열의 사각형 레이아웃을 반복하는 것이 더 쉽습니다. 응축 된 형태 만 공간과 계산 단계를 절반으로 줄입니다.
============는
여기 i
상부 j
, 반복 처리가 dot(x[i],y[j])/(norm[i]*norm[j])
산출 c
pdist_cosine
기능의 주요 부분이다.
for (i = 0; i < m; i++) {
for (j = i + 1; j < m; j++, dm++) {
u = X + (n * i);
v = X + (n * j);
cosine = dot_product(u, v, n)/(norms[i] * norms[j]);
if (fabs(cosine) > 1.) {
/* Clip to correct rounding error. */
cosine = npy_copysign(1, cosine);
}
*dm = 1. - cosine;
}
}
https://github.com/scipy/scipy/blob/master/scipy/spatial/src/distance_impl.h
당신은 구체적인 예를 추가해야합니다
; 복사해서 붙여 넣을 수있는 것. 분명히 그것은 메모리 문제로 실행되지 않습니다. 그러나 정확히 동일한 문제를 해결하지 않으면 귀하의 구두 설명을 따르기가 어렵습니다. 스파 스 매트릭스 코드는 잘 알고 있지만'sklearn '을 사용하지는 않았습니다. 그래서 '응축 된 형태'와 같은 용어는 외국어입니다. – hpaulj
@ hpaulj 그것은 모든 stackoverflow, 결국 물어 오는 것처럼 보인다 : http://stackoverflow.com/questions/13079563/how-does-condensed-distance-matrix-work-pdist –
또한 상단에 작성에 대한 질문이있다/아래쪽 삼각형 (또는 양쪽 모두)을 값의 벡터로부터 분리합니다. – hpaulj