Получение границ кластера ELKI OPTICSXi

У меня есть одномерный набор данных, для которого график гистограммы показывает несколько локальных максимумов, поэтому я знаю, что в моем одномерном пространстве есть несколько областей, где данные более плотные. Я хочу определить границы для этих плотных регионов, которые позволяют мне классифицировать плотный регион/кластер, в котором находится определенная точка данных. Для этого я использую ОПТИК, потому что он должен иметь возможность лучше справляться с различной плотностью между сравниваемыми кластерами. к DBSCAN.

Я использую ELKI (версия 0.6.0) в коде Java (я знаю, что команда ELKI не рекомендует встраивать ELKI в Java, но мне нужно повторить рабочий процесс для многих наборов данных, и поэтому лучше автоматизировать это в моем случае) . Фрагмент кода ниже выводит индексы начального и конечного элементов кластеров. Документация ELKI по OPTICSModel четко не определяет, чему соответствуют эти номера индексов, но я предполагаю, что это индексы начального и конечного элементов данных в расширенном кластерном упорядочении базы данных (например, объект ClusterOrderResult, который OPTICS.run()-созданный), в отличие от индексов начального и конечного элементов данных самой базы данных (неупорядоченных).

ListParameterization opticsParams = new ListParameterization();
opticsParams.addParameter(OPTICSXi.XI_ID, 0.01);
opticsParams.addParameter(OPTICS.MINPTS_ID, 100);
OPTICSXi<DoubleDistance> optics = ClassGenericsUtil.parameterizeOrAbort(OPTICSXi.class, opticsParams);

ArrayAdapterDatabaseConnection arrayAdapterDatabaseConnection = new ArrayAdapterDatabaseConnection(myListOfOneDimensionalFeatureVectors.toArray(new double[myListOfOneDimensionalFeatureVectors.size()][2]));
ListParameterization dbParams = new ListParameterization();
dbParams.addParameter(AbstractDatabase.Parameterizer.INDEX_ID, RStarTreeFactory.class);
dbParams.addParameter(RStarTreeFactory.Parameterizer.BULK_SPLIT_ID, SortTileRecursiveBulkSplit.class);
dbParams.addParameter(AbstractDatabase.Parameterizer.DATABASE_CONNECTION_ID, arrayAdapterDatabaseConnection);

Database db = ClassGenericsUtil.parameterizeOrAbort(StaticArrayDatabase.class, dbParams);
db.initialize();

result = optics.run(db);
List<Cluster<OPTICSModel>> clusters = result.getAllClusters();
    for(Cluster<OPTICSModel> cluster : clusters){
        if(!cluster.isNoise())
            System.out.println(cluster.getModel().getStartIndex() + ", "+ cluster.getModel().getEndIndex() +";  ");
    }

Теперь я хочу знать, где в моем одномерном пространстве начинаются и заканчиваются мои кластеры. Поэтому я хотел бы получить элементы данных, соответствующие начальным и конечным индексам, которые уже получает мой код выше. Я предполагаю, что мне нужен был бы объект ClusterOrderResult для того, из которого я мог бы затем получить полученные индексы. Однако в документации кажется, что невозможно получить такую ​​вещь из объекта результата кластеризации, который я получил, вызвав optics.run(). Поскольку, казалось, не было никакого способа получить эту упорядоченную базу данных, я наивно попытался получить индексы из моего исходного набора входных данных, вместо этого заменив println в приведенном выше коде на println ниже:

System.out.println(myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getStartIndex())[0] + ", "+ myListOfOneDimensionalFeatureVectors.get(cluster.getModel().getEndIndex())[0] +";  ";

Однако, как я уже ожидал, индексы, похоже, не принадлежат исходному входному файлу, поскольку он регулярно печатает конечные границы с более низкими значениями в моем одномерном пространстве, чем конечные границы. Кто-нибудь знает какой-либо способ получить исходные значения одномерных данных, которые соответствуют начальным и конечным индексам, найденным с помощью кластеризации OPTICS? Я хочу использовать эти значения позже в своем коде.


person Niek Tax    schedule 18.04.2015    source источник


Ответы (1)


В целях автоматизации очень хорошо работает вызов ELKI из командной строки. Это мой предпочтительный способ, потому что таким образом каждый запуск хорошо изолирован в своей собственной JVM.

Тогда у вас будет легкий доступ к этим данным из выходных файлов.

Почему вы используете старую версию ELKI? Версии 0.6.5 намного лучше из-за удаленных дженериков. Хотя сейчас я перешел на версию github.

Если вам нужен прямой доступ к объекту ClusterOrder, он прикрепляется к объекту кластеризации как дочерний результат. Вы должны быть в состоянии получить его, используя

ClusterOrder clusterOrder = ResultUtil.filterResults(clustering, ClusterOrder.class).get(0);

и его идентификаторы объектов через:

ArrayDBIDs ids = DBIDUtil.ensureArray(clusterOrder.getDBIDs());

( ensureArray является накладным, но в любом случае это noop - это операция приведения или преобразования, и здесь это будет приведение; по крайней мере, в моей версии ELKI идентификаторы всегда хранятся как ArrayDBID)

Итераторы массива (DBIDArrayIter it = ids.iter()) можно перемещать в позицию через seek(offset). Таким образом, вы должны иметь возможность использовать что-то вроде

DBIDArrayIter it = ids.iter();
NumberVector vec = relation.get(it.seek(model.getStartIndex()));

Итераторы в ELKI необычны для Java API, но очень быстры, если вы используете один итератор для всех ваших обращений.

Так много для вашей части вопроса ELKI. Однако с статистической точки зрения не имеет смысла использовать OPTICS для одномерных данных. Вместо этого для одномерных данных используйте правильную оценку плотности ядра. ОПТИКА — это грубый и грубый метод, который имеет смысл, когда ваши данные слишком сложны для моделирования с использованием соответствующих статистических инструментов. ОПТИКА использует очень примитивную плотность ядра, а метод xi представляет собой очень наивное извлечение кластеров из графика плотности... по крайней мере, на одномерных данных статистика предлагает более сильные инструменты. У ELKI есть реализация под названием KNNKernelDensityMinimaClustering, но я ей еще не пользовался. Но оценка плотности ядра должна быть доступна в любом наборе статистических инструментов, поэтому я бы попробовал этот класс.

person Has QUIT--Anony-Mousse    schedule 19.04.2015
comment
Спасибо, как за ответ, так и за отзыв по статистической части! На самом деле я пробовал методы KDE до того, как попробовал OPTICS. Проблема заключалась в том, что после нахождения KDE, хорошо вписывающегося в данные, получить из него кластеры по-прежнему далеко не тривиально. Приятно слышать, что KNNKernelDensityMinimaClustering может предложить мне некоторые возможности в этом направлении. Вы случайно не знаете, есть ли информация о том, как KNNKernelDensityMinimaClustering вычисляет кластеры из плотностей ядра? Javadoc класса и список публикаций на веб-сайте ELLI, похоже, не содержат информации об этом. - person Niek Tax; 19.04.2015
comment
Без понятия. Обычно у них есть ссылка в JavaDoc, но у этого класса ее нет. - person Has QUIT--Anony-Mousse; 19.04.2015
comment
Я также переключился на github-версию ELKI. Еще один вопрос по фрагментам кода, которые вы предоставили. каков тип переменной «отношение» в вашем примере? Сначала я думал, что это будет Database, но it.seek возвращает объект типа DBIDArrayIter, а помещение туда Database приводит к ошибке get(DBIDArrayIter) underfined для типа Database. - person Niek Tax; 20.04.2015
comment
Я исправил это сам. Я обнаружил, что могу извлечь Collection‹Relation› из объекта Dabase с помощью метода getRelations(). - person Niek Tax; 20.04.2015
comment
Извините, KNNKernelDensityMinimaClustering основано на моих собственных соображениях, мне не удалось найти на него ссылку; однако этот метод слишком прост, чтобы его можно было где-либо публиковать. Пожалуйста, укажите ELKI для этого метода, если вы его используете. - person Erich Schubert; 27.04.2015
comment
Кроме того, я изменю ClusterOrder.getDBIDs(), чтобы вам больше не нужен был вызов ensureArray. Спасибо за этот отзыв. - person Erich Schubert; 27.04.2015