通过使用测试用例,我能够看到如何从Java语言中直接使用ELKI,但是现在我想从MongoDB中读取我的数据,然后使用ELKI来集群地理(经度、经度)数据。
我只能使用ELKI对CSV文件中的数据进行集群。是否可以使用MongoDB连接de.lmu.ifi.dbs.elki.database.Database?我可以从java调试器中看到,在de.lmu.ifi.dbs.elki.database.Database中有一个数据库连接字段。
我查询MongoDB,为每一行创建POJO,现在我想使用ELKI对这些对象进行集群。
可以从MongoDB读取数据并将其写入CSV文件,然后使用ELKI读取CSV文件,但我想知道是否有更简单的解决方案。
-调查结果_1:
从ELKI - Use List of objects to populate the Database中,我发现我需要实现de.lmu.ifi.dbs.elki.datasource.DatabaseConnection,特别是覆盖loadData()方法,该方法返回MultiObjectsBundle的一个实例。
所以我想我应该用MultiObjectsBundle包装一个POJO列表。现在我看一下MultiObjectsBundle,看起来数据应该保存在列中。为什么列的数据类型是List>,不应该是List吗?只是一个你想要集群的项目列表?
我有点困惑。ELKI如何知道它应该关注POJO的长期和后期?我该在哪里告诉ELKI做这件事?使用de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation?
-调查结果_2:
我尝试过使用ArrayAdapterDatabaseConnection,也尝试过实现DatabaseConnection。对不起,我需要用非常简单的术语让我理解。
这是我的集群代码:
int minPts=3;
double eps=0.08;
double[][] data1 = {{-0.197574246, 51.49960695}, {-0.084605692, 51.52128377}, {-0.120973687, 51.53005939}, {-0.156876, 51.49313},
{-0.144228881, 51.51811784}, {-0.1680743, 51.53430039}, {-0.170134484,51.52834133}, { -0.096440751, 51.5073853},
{-0.092754157, 51.50597426}, {-0.122502346, 51.52395143}, {-0.136039674, 51.51991453}, {-0.123616824, 51.52994371},
{-0.127854211, 51.51772703}, {-0.125979294, 51.52635795}, {-0.109006325, 51.5216612}, {-0.12221963, 51.51477076}, {-0.131161087, 51.52505093} };
// ArrayAdapterDatabaseConnection dbcon = new ArrayAdapterDatabaseConnection(data1);
DatabaseConnection dbcon = new MyDBConnection();
ListParameterization params = new ListParameterization();
params.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.MINPTS_ID, minPts);
params.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.EPSILON_ID, eps);
params.addParameter(DBSCAN.DISTANCE_FUNCTION_ID, EuclideanDistanceFunction.class);
params.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, dbcon);
params.addParameter(AbstractDatabase.Parameterizer.INDEX_ID,
RStarTreeFactory.class);
params.addParameter(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID,
SortTileRecursiveBulkSplit.class);
params.addParameter(AbstractPageFileFactory.Parameterizer.PAGE_SIZE_ID, 1000);
Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, params);
db.initialize();
GeneralizedDBSCAN dbscan = ClassGenericsUtil.parameterizeOrAbort(GeneralizedDBSCAN.class, params);
Relation<DoubleVector> rel = db.getRelation(TypeUtil.DOUBLE_VECTOR_FIELD);
Relation<ExternalID> relID = db.getRelation(TypeUtil.EXTERNALID);
DBIDRange ids = (DBIDRange) rel.getDBIDs();
Clustering<Model> result = dbscan.run(db);
int i =0;
for(Cluster<Model> clu : result.getAllClusters()) {
System.out.println("#" + i + ": " + clu.getNameAutomatic());
System.out.println("Size: " + clu.size());
System.out.print("Objects: ");
for(DBIDIter it = clu.getIDs().iter(); it.valid(); it.advance()) {
DoubleVector v = rel.get(it);
ExternalID exID = relID.get(it);
System.out.print("DoubleVec: ["+v+"]");
System.out.print("ExID: ["+exID+"]");
final int offset = ids.getOffset(it);
System.out.print(" " + offset);
}
System.out.println();
++i;
} ArrayAdapterDatabaseConnection生成两个集群,当我设置epsilon=0.008数据库扫描开始创建集群时,我只需要处理epsilon的值。当我设置epsilon=0.04时,所有的项目都在一个集群中。
我还尝试实现了DatabaseConnection:
@Override
public MultipleObjectsBundle loadData() {
MultipleObjectsBundle bundle = new MultipleObjectsBundle();
List<Station> stations = getStations();
List<DoubleVector> vecs = new ArrayList<DoubleVector>();
List<ExternalID> ids = new ArrayList<ExternalID>();
for (Station s : stations){
String strID = Integer.toString(s.getId());
ExternalID i = new ExternalID(strID);
ids.add(i);
double[] st = {s.getLongitude(), s.getLatitude()};
DoubleVector dv = new DoubleVector(st);
vecs.add(dv);
}
SimpleTypeInformation<DoubleVector> type = new VectorFieldTypeInformation<>(DoubleVector.FACTORY, 2, 2, DoubleVector.FACTORY.getDefaultSerializer());
bundle.appendColumn(type, vecs);
bundle.appendColumn(TypeUtil.EXTERNALID, ids);
return bundle;
} 这些长/纬度与一个ID相关联,我需要将它们链接回此ID和值。使用ID偏移(在上面的代码中)是唯一的方法吗?我试图添加ExternalID列,但我不知道如何检索特定NumberVector的ExternalID?
此外,在看到Using ELKI's Distance Function之后,我尝试使用Elki的longLatDistance,但它不起作用,而且我找不到任何实现它的示例。
发布于 2015-10-29 20:37:55
数据源的接口称为DatabaseConnection。
JavaDoc of DatabaseConnection
您可以实现一个基于MongoDB的接口来获取数据。
它不是复杂的接口,它只有一个方法。
https://stackoverflow.com/questions/33392006
复制相似问题