我有一组格式为:
的地理数据46.52100798 6.567126449 gps
46.52368591 6.59208188 gps
46.52338534 6.593065244 gps
46.52303304 6.594046262 gps
我想进行DBSCAN聚类并设置与实际距离相同的epsilon参数,如5米: 目前代码如下:
public static float distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
float dist = (float) (earthRadius * c);
return dist;
}
//一种计算给定两对地理数据的距离的方法。
cl = new DBSCAN();
double [] timeArray = new double[data.numInstances()-1];
for (int i = 1; i<data.numInstances();i++){
timeArray[i-1] =(data.instance(i).value(0)-data.instance(i-1).value(0));
}
Arrays.sort(timeArray);
int point =(int)(30*60/timeArray[data.numInstances()/2]);
System.out.println(point);
cl.setMinPoints(point);
cl.setEpsilon(0.01);
cl.buildClusterer(newData);
//设置DBSCAN实例的参数 谁知道如何将上面的距离计算代码插入DBSCAN实例?
答案 0 :(得分:0)
ELKI已经包含了这个距离函数LatLngDistanceFunction
(请注意纬度和经度的顺序很重要;这就是我们根据您的列顺序提供两者的原因)。
-algorithm.distancefunction geo.LatLngDistanceFunction
使用此距离函数的距离将为米。使用参数-geo.model
,您还可以在不同的地球近似值之间切换,例如简单的球形模型或WGS84球体。对于DBSCAN而言,这并没有太大的区别,因为你会想要使用一个小的epsilon(比如你建议的5米)。
ELKI还包括此距离函数的索引功能。当您拥有大型数据集时,ELKI将更多更快(我邀请您自己参加基准 Weka对抗ELKI)。有关地理距离的索引加速的详细信息,请参阅出版物:
电子。舒伯特,A.Zimek,H.-P。克里格尔
的 Geodetic Distance Queries on R-Trees for Indexing Geographic Data 强>
在第13届国际空间与时间数据库研讨会(SSTD)会议录中,德国慕尼黑:146-164,2013。
只要你选择足够小的epsilon并使用真实数据,R * -tree通常会给你一个从O(n ^ 2)到大约的加速。 O(n log n) - 如果你有数百万点,加速通常是100x-1000x。