2014-02-27 2 views
4

DBSCAN (scikit learn implementation) 및 위치 데이터를 사용하여 클러스터를 만들려고합니다. 내 데이터는 np 배열 형식이지만 Haversine 공식을 사용하여 DBSCAN을 사용하려면 거리 매트릭스를 만들어야합니다. 나는 (모듈 '호출 할 수없는 오류')이 일을하려고하면 다음과 같은 오류가 나타납니다. 이것은 온라인으로 읽은 것에서 가져 오기 오류입니다.하지만 저에게는 그다지 확실하지 않습니다. 내 haversine 거리 수식을 만들었지 만, 나는이 오류가 아니라고 확신합니다.nparray와 pdist 및 squareform을 사용한 거리 행렬 생성

이것은 입력 데이터 인 np 배열 (ResultArray)입니다.

[[ 53.3252628 -6.2644198 ] 
[ 53.3287395 -6.2646543 ] 
[ 53.33321202 -6.24785807] 
[ 53.3261015 -6.2598324 ] 
[ 53.325291 -6.2644105 ] 
[ 53.3281323 -6.2661467 ] 
[ 53.3253074 -6.2644483 ] 
[ 53.3388147 -6.2338417 ] 
[ 53.3381102 -6.2343826 ] 
[ 53.3253074 -6.2644483 ] 
[ 53.3228188 -6.2625379 ] 
[ 53.3253074 -6.2644483 ]] 

그리고 이것은 erroring 코드 줄입니다.

File "Location.py", line 48, in <module> 
distance_matrix = sp.spatial.distance.squareform(sp.spatial.distance.pdist 
(ResArray,(lambda u,v: haversine(u,v)))) 
File "/usr/lib/python2.7/dist-packages/scipy/spatial/distance.py", line 1118, in pdist 
dm[k] = dfun(X[i], X[j]) 
File "Location.py", line 48, in <lambda> 
distance_matrix = sp.spatial.distance.squareform(sp.spatial.distance.pdist 
(ResArray,(lambda u,v: haversine(u,v)))) 
TypeError: 'module' object is not callable 

내가 SP로 scipy 가져옵니다

distance_matrix = sp.spatial.distance.squareform(sp.spatial.distance.pdist 
(ResultArray,(lambda u,v: haversine(u,v)))) 

는 오류 메시지입니다. (sp를 sp로 가져 오기)

+0

ELKI는 R * -trees를 사용하여 DBSCAN에서 haversine distance에 대한 인덱스 가속도를가집니다. 이것은 O (n^2) 시간과 메모리를 필요로하지 않습니다. 또한 DBTIAN 2.0과 같은 OPTICS도 있습니다. –

답변

4

scipypdist은 맞춤형 거리 기능을 사용할 수 없습니다. docs에서 읽을 수 있듯이 몇 가지 옵션이 있지만 하버 사이드 거리는 지원되는 측정 항목 목록에 포함되어 있지 않습니다.

당신이 "수동"계산을 할 필요가

을 (matlab에 pdisthere를 참조하지만 옵션을 지원), 즉 루프와,이 같은 일이 작동합니다

from numpy import array,zeros 

def haversine(lon1, lat1, lon2, lat2): 
    """ See the link below for a possible implementation """ 
    pass 

#example input (your's, truncated) 
ResultArray = array([[ 53.3252628, -6.2644198 ], 
        [ 53.3287395 , -6.2646543 ], 
        [ 53.33321202 , -6.24785807], 
        [ 53.3253074 , -6.2644483 ]]) 

N = ResultArray.shape[0] 
distance_matrix = zeros((N, N)) 
for i in xrange(N): 
    for j in xrange(N): 
     lati, loni = ResultArray[i] 
     latj, lonj = ResultArray[j] 
     distance_matrix[i, j] = haversine(loni, lati, lonj, latj) 
     distance_matrix[j, i] = distance_matrix[i, j] 

print distance_matrix 
[[ 0.   0.38666203 1.41010971 0.00530489] 
[ 0.38666203 0.   1.22043364 0.38163748] 
[ 1.41010971 1.22043364 0.   1.40848782] 
[ 0.00530489 0.38163748 1.40848782 0.  ]] 

을 그냥 참조 Haverside의 Python 구현은 here입니다. 이 link에서 문서에 의해 제안 및 편의를 위해 여기에보고 된 사용자 정의 거리 함수를 정의 할 수 있습니다 Scipy으로

5

: 여기

Y = pdist(X, f) 
Computes the distance between all pairs of vectors in X using the user supplied 2-arity function f. For example, Euclidean distance between the vectors could be computed as follows: 

dm = pdist(X, lambda u, v: np.sqrt(((u-v)**2).sum())) 

나는 영감 코드의 내 버전을보고 이 코드에서 코드 link :

from numpy import sin,cos,arctan2,sqrt,pi # import from numpy 
# earth's mean radius = 6,371km 
EARTHRADIUS = 6371.0 

def getDistanceByHaversine(loc1, loc2): 
    '''Haversine formula - give coordinates as a 2D numpy array of 
    (lat_denter link description hereecimal,lon_decimal) pairs''' 
    #  
    # "unpack" our numpy array, this extracts column wise arrays 
    lat1 = loc1[1] 
    lon1 = loc1[0] 
    lat2 = loc2[1] 
    lon2 = loc2[0] 
    # 
    # convert to radians ##### Completely identical 
    lon1 = lon1 * pi/180.0 
    lon2 = lon2 * pi/180.0 
    lat1 = lat1 * pi/180.0 
    lat2 = lat2 * pi/180.0 
    # 
    # haversine formula #### Same, but atan2 named arctan2 in numpy 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = (sin(dlat/2))**2 + cos(lat1) * cos(lat2) * (sin(dlon/2.0))**2 
    c = 2.0 * arctan2(sqrt(a), sqrt(1.0-a)) 
    km = EARTHRADIUS * c 
    return km 

과 같은 방법으로 호출 내에서 구현

D = spatial.distance.pdist(A, lambda u, v: getDistanceByHaversine(u,v)) 

행렬 A는 첫 번째 열 경도 값으로 및 제 열로 위도 값 소수점 각도를 나타냈다.

0

이제 scipy를 사용하여 거리 매트릭스를 사전 계산하지 않고도 scikit-learn의 DBSCAN 및 haversine 메트릭을 사용하여 공간 위도 - 경도 데이터를 클러스터링 할 수 있습니다.

db = DBSCAN(eps=2/6371., min_samples=5, algorithm='ball_tree', metric='haversine').fit(np.radians(coordinates)) 

clustering spatial data with scikit-learn DBSCAN에이 튜토리얼에서 온다.특히 eps 값은 2km를 6371 (지구의 반경 (km))로 나눠 라디안으로 변환합니다. 또한 .fit()은 haversine 메트릭에 대해 라디안 단위로 좌표를 취합니다.