Я пытаюсь сгруппировать некоторые геопространственные данные и ранее использовал библиотеку WEKA. . Я нашел этот сравнительный анализ и решил попробовать ELKI.
Несмотря на совет не использовать ELKI в качестве библиотеки Java (которая предположительно менее обслуживаема, чем пользовательский интерфейс), я включил ее в свое приложение и могу сказать, что вполне доволен результатами. . Структуры, которые он использует для хранения данных, гораздо более эффективны, чем те, которые использует Weka, и тот факт, что у него есть возможность использовать пространственный индекс, определенно является плюсом.
Однако, когда я сравниваю результаты DBSCAN от Weka с результатами от DBSCAN ELKI, я немного озадачен. Я бы согласился с тем, что разные реализации могут дать немного разные результаты, но эта величина разницы заставляет меня думать, что с алгоритмом что-то не так (возможно, с моим кодом). Количество кластеров и их геометрия сильно различаются в двух алгоритмах.
Для справки, я использую последнюю версию ELKI (0.6.0), и параметры, которые я использовал для своих симуляций, были следующими:
minpts=50 эпсилон=0,008
Я закодировал две функции DBSCAN (для Weka и ELKI), где «точка входа» — это csv с точками, а «выход» для обеих из них также идентичен: функция, вычисляющая вогнутую оболочку набора точек ( по одному на каждый кластер). Поскольку функция, которая считывает файл csv в «базу данных» ELKI, относительно проста, я думаю, что моя проблема может заключаться в следующем:
а) в параметризации алгоритма; б) чтение результатов (наиболее вероятно).
Параметризация DBSCAN не представляет никаких проблем, и я использую два обязательных параметра, которые я ранее тестировал через пользовательский интерфейс:
ListParameterization params2 = new ListParameterization();
params2.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.MINPTS_ID, minPoints);
params2.addParameter(de.lmu.ifi.dbs.elki.algorithm.clustering.DBSCAN.Parameterizer.EPSILON_ID, epsilon);
Чтение результата немного сложнее, так как я не совсем понимаю организацию структуры, в которой хранятся кластеры; Моя идея состоит в том, чтобы перебрать каждый кластер, получить список точек и передать его функции, которая вычисляет вогнутую оболочку, чтобы создать многоугольник.
ArrayList<Clustering<?>> cs = ResultUtil.filterResults(result, Clustering.class);
for (Clustering<?> c : cs) {
System.out.println("clusters: " + c.getAllClusters().size());
for (de.lmu.ifi.dbs.elki.data.Cluster<?> cluster : c.getAllClusters()) {
if (!cluster.isNoise()){
Coordinate[] ptList=new Coordinate[cluster.size()];
int ct=0;
for (DBIDIter iter = cluster.getIDs().iter(); iter.valid(); iter.advance()) {
ptList[ct]=dataMap.get(DBIDUtil.toString(iter));
++ct;
}
//there are no "empty" clusters
assertTrue(ptList.length>0);
GeoPolygon poly=getBoundaryFromCoordinates(ptList);
if (poly.getCoordinates().getGeometryType()==
"Polygon"){
try {
out.write(poly.coordinates.toText()+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else
System.out.println(
poly.getCoordinates().getGeometryType());
}//!noise
}
}
Я заметил, что «шум» возник как кластер, поэтому я проигнорировал этот кластер (я не хочу его рисовать). Я не уверен, что это правильный способ чтения кластеров, так как я не нашел много примеров. У меня также есть несколько вопросов, на которые я пока не нашел ответов:
- В чем разница между getAllClusters() и getTopLevelClusters()?
- Являются ли кластеры DBSCAN «вложенными», то есть можем ли мы иметь точки, принадлежащие многим кластерам одновременно? Почему?
- Я где-то читал, что мы не должны использовать идентификаторы базы данных для идентификации точек, так как они предназначены для внутреннего использования ELKI, но как еще можно получить список точек в каждом кластере? Я читал, что вы можете использовать отношение для меток, но я не уверен, как это реализовать...
Любые комментарии, которые могли бы указать мне правильное направление, или любые предложения по коду для повторения набора результатов ELKI DBSCAN будут действительно приветствоваться! Я также использовал ELKI OPTICSxi в своем коде, и у меня есть еще больше вопросов относительно этих результатов, но, думаю, я приберегу их для другого поста.