Scikit-Learn: прогнозирование новых точек с помощью DBSCAN
Я использую DBSCAN для кластеризации некоторых данных с помощью Scikit-Learn (Python 2.7):
from sklearn.cluster import DBSCAN
dbscan = DBSCAN(random_state=0)
dbscan.fit(X)
Однако я обнаружил, что не было встроенной функции (кроме "fit_predict" ), которая могла бы назначать новые точки данных Y в кластеры, идентифицированные в исходных данных X. Метод K -средства имеет "предсказывать", но я хочу иметь возможность сделать то же самое с DBSCAN. Что-то вроде этого:
dbscan.predict(X, Y)
Чтобы плотность могла быть выведена из X, но возвращаемые значения (назначения/метки кластера) предназначены только для Y. Из того, что я могу сказать, эта возможность доступна в R, поэтому я предполагаю, что она также доступна на Python, Я просто не могу найти документацию для этого.
Кроме того, я попытался найти причины, по которым DBSCAN не может использоваться для маркировки новых данных, но я не нашел никаких оправданий.
Ответы
Ответ 1
Кластеризация не является классификацией.
Кластеризация не мечена. Если вы хотите сжать его в мышление предсказания (это не самая лучшая идея), то он, по сути, предсказывает без обучения. Потому что для кластеризации нет данных о методах обучения. Он должен составлять новые метки для данных, основываясь на том, что он видит. Но вы не можете сделать это в одном экземпляре, вы можете только "массовое предсказание".
Но что-то не так с scipys DBSCAN:
random_state
: numpy.RandomState, необязательно:
Генератор, используемый для инициализации центров. По умолчанию используется numpy.random.
DBSCAN не "инициализирует центры", потому что в DBSCAN нет центров.
В значительной степени единственным алгоритмом кластеризации, в котором вы можете назначить новые точки старым кластерам, является k-средство (и его многочисленные варианты). Поскольку он выполняет классификацию "1NN", используя предыдущие центры кластеров итераций, затем обновляет центры. Но большинство алгоритмов не работают, как k-означает, поэтому вы не можете скопировать это.
Если вы хотите классифицировать новые точки, лучше всего подготовить классификатор к результату кластеризации.
Что, возможно, делает R-версия, использует классификатор 1NN для прогнозирования; возможно, с дополнительным правилом, которому присваивается точка метка шума, если их расстояние в 1NN больше, чем epsilon, mabye также использует только основные точки. Возможно, нет.
Получите документ DBSCAN, он не обсуждает "предсказание" IIRC.
Ответ 2
В то время как у Анони-Мусса есть несколько хороших моментов (кластеризация действительно не классифицируется), я считаю, что способность назначать новые точки имеет полезность. *
На основе оригинальной статьи DBSCAN и идей robertlaytons на github.com/scikit-learn, я предлагаю запустить основные точки и назначить кластер первой базовой точки, находящейся в пределах eps
новой точки.
Тогда гарантируется, что ваша точка будет по крайней мере быть граничной точкой назначенного кластера в соответствии с определениями, используемыми для кластеризации.
(Имейте в виду, что ваша точка может считаться помехой и не назначена кластеру)
Я сделал быструю реализацию:
import numpy as np
import scipy as sp
def dbscan_predict(dbscan_model, X_new, metric=sp.spatial.distance.cosine):
# Result is noise by default
y_new = np.ones(shape=len(X_new), dtype=int)*-1
# Iterate all input samples for a label
for j, x_new in enumerate(X_new):
# Find a core sample closer than EPS
for i, x_core in enumerate(dbscan_model.components_):
if metric(x_new, x_core) < dbscan_model.eps:
# Assign label of x_core to x_new
y_new[j] = dbscan_model.labels_[dbscan_model.core_sample_indices_[i]]
break
return y_new
Ярлыки, полученные кластеризацией (dbscan_model = DBSCAN(...).fit(X)
и метками, полученными из той же модели по тем же данным (dbscan_predict(dbscan_model, X)
), иногда различаются. Я не совсем уверен, что это где-то ошибка или результат случайности.
EDIT: Я думаю, что вышеупомянутая проблема с разными результатами прогнозирования может быть связана с возможностью того, что пограничная точка может быть близка к нескольким кластерам. Обновите, если вы проверите это и найдите ответ. Неоднозначность может быть решена путем перетасовки основных точек каждый раз или путем выбора ближайшего вместо первой точки ядра.
*) Дело под рукой: я хотел бы оценить, есть ли кластеры, полученные из подмножества моих данных, для другого подмножества, или это просто частный случай.
Если он обобщает, он поддерживает действительность кластеров и применяемые ранее шаги предварительной обработки.