Scikit-learn: кластеризация текстовых документов с использованием DBSCAN

Я пытаюсь использовать scikit-learn для кластерных текстовых документов. В целом, я нахожу свой путь, но у меня есть проблемы с конкретными проблемами. Большинство примеров, которые я нашел, иллюстрируют кластеризацию с использованием scikit-learn с k-средствами в качестве алгоритма кластеризации. Принятие этого примера с помощью k-средств для моей настройки работает в принципе. Однако k-средство не подходит, так как я не знаю количество кластеров. Из того, что я прочитал до сих пор, пожалуйста, исправьте меня здесь, если необходимо - DBSCAN или MeanShift кажутся более подходящими в моем случае. Веб-сайт scikit-learn предоставляет примеры для каждого алгоритма кластера. Проблема в том, что с DBSCAN и MeanShift я получаю ошибки, которые я не могу понять, не говоря уже о решении.

Мой минимальный код выглядит следующим образом:

docs = []
for item in [database]:
    docs.append(item)

vectorizer = TfidfVectorizer(min_df=1)
X = vectorizer.fit_transform(docs)

X = X.todense() # <-- This line was needed to resolve the isse

db = DBSCAN(eps=0.3, min_samples=10).fit(X)
...

(Мои документы уже обработаны, т.е. были удалены стоп-слова, и был применен Stormmer Porter.)

Когда я запускаю этот код, я получаю следующую ошибку при инициализации DBSCAN и вызове fit():

...
File "/usr/local/lib/python2.7/dist-packages/sklearn/cluster/dbscan_.py", line 248, in fit
clust = dbscan(X, **self.get_params())
File "/usr/local/lib/python2.7/dist-packages/sklearn/cluster/dbscan_.py", line 86, in dbscan
n = X.shape[0]
IndexError: tuple index out of range

Нажав на строку в dbscan_.py, которая выдает ошибку, я заметил следующую строку

...
X = np.asarray(X)
n = X.shape[0]
...

Когда я использую их для строк непосредственно в моем коде для тестирования, я получаю ту же ошибку. Я не знаю, что здесь делает np.asarray(X), но после команды X.shape = (). Следовательно, X.shape[0] бомбы - раньше, X.shape[0] правильно ссылается на количество документов. Из любопытства я удалил X = np.asarray(X) из dbscan_.py. Когда я это делаю, что-то сильно вычисляет. Но через несколько секунд я получаю еще одну ошибку:

...
File "/usr/lib/python2.7/dist-packages/scipy/sparse/csr.py", line 214, in extractor
(min_indx,max_indx) = check_bounds(indices,N)
File "/usr/lib/python2.7/dist-packages/scipy/sparse/csr.py", line 198, in check_bounds
max_indx = indices.max()
File "/usr/lib/python2.7/dist-packages/numpy/core/_methods.py", line 17, in _amax
out=out, keepdims=keepdims)
ValueError: zero-size array to reduction operation maximum which has no identity

Короче говоря, я не знаю, как заставить DBSCAN работать, или, возможно, что-то пропустил в целом.

Ответ 1

Реализация в sklearn, по-видимому, предполагает, что вы имеете дело с конечным векторным пространством и хотите найти размерность вашего набора данных. Текстовые данные обычно представлены как разреженные векторы, но теперь с одинаковой размерностью.

Ваши входные данные, вероятно, не являются матрицей данных, но реализация sklearn требует, чтобы они были такими.

Вам нужно найти другую реализацию. Возможно, попробуйте реализацию в ELKI, что очень быстро и не должно иметь этого ограничения.

Сначала вам нужно потратить некоторое время на понимание подобия. Для DBSCAN вы должны выбрать epsilon таким образом, который имеет смысл для ваших данных. Нет эмпирического правила; это специфично для домена. Поэтому вам сначала нужно выяснить, какой порог подобия означает, что два документа похожи.

Среднее смещение действительно может потребовать, чтобы ваши данные были векторным пространством фиксированной размерности.

Ответ 2

Похоже, что разреженные представления для DBSCAN поддерживаются по состоянию на январь 2015 г..

Я обновил sklearn до 0,16.1, и он работал у меня по тексту.