我正在尝试使用DBSCAN(scikit learn implementation)和位置数据进行集群。我的数据是np数组格式,但要使用带有Haversine公式的DBSCAN,我需要创建一个距离矩阵。当我尝试这样做时,我得到以下错误('模块'不可调用错误。)从我在线阅读这是一个导入错误,但我很确定不是我的情况。我已经创建了自己的半身距离公式,但我确定错误与此无关。
这是我的输入数据,一个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 ]]
这是错误的代码行。
distance_matrix = sp.spatial.distance.squareform(sp.spatial.distance.pdist
(ResultArray,(lambda u,v: haversine(u,v))))
这是错误消息:
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
我将scipy导入为sp。 (将scipy导入sp)
答案 0 :(得分:5)
使用Scipy,您可以根据此link的文档建议定义自定义距离函数,并在此处报告以方便使用:
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的第一列是经度值,第二列是以十进制度表示的纬度值。
答案 1 :(得分:4)
简单scipy
的{{1}}不允许传递自定义距离函数。正如您可以在docs中阅读的那样,您有一些选项,但是里程距离不在支持的指标列表中。
(Matlab pdist
确实支持该选项,请参阅here)
你需要“手动”进行计算,即使用循环,这样的东西会起作用:
pdist
仅供参考,可以在Python中找到Haverside的实现here。
答案 2 :(得分:0)
现在,您可以使用scikit-learn的DBSCAN和半正线指标对空间纬度 - 经度数据进行聚类,而无需使用scipy预先计算距离矩阵。
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
值是2 km除以6371(地球半径(km))将其转换为弧度。另请注意,.fit()
以半径为单位获取半正弦坐标的坐标。