Matlab k-средний косинус присваивает все одному кластеру

Я использую обычный алгоритм kmeans Matlab с «Расстоянием», «Косинусом», «EmptyAction», «Drop» на матрице функций, нормализованной L2, и у меня есть проблема. Результат, который генерирует Matlab, просто назначает КАЖДУЮ точку данных кластеру 1.00000, даже если k = 20, а все центроиды в C равны NaN. У кого-нибудь есть предложения относительно того, что может быть причиной этого?

Макет матрицы ([0,1,...,1,0,1],[...],[0,1,...,1,0,1]). Я выполнил нормализацию L2, используя numpy.linalg.norm Python, прежде чем передать файл в Matlab. Именно так я запускаю kmeans:

m=importdata('matrix.txt');
data=m'; % transpose, because kmeans treats columns as features instead of rows
[L, C]=kmeans(data, 20, 'Distance', 'cosine', 'EmptyAction', 'drop')

Вот пример моего нормализованного набора данных:

10.3440804328
12.6885775404
15.5884572681
15.9059737206
17.4355957742
17.0
17.3493515729
17.3205080757
18.6279360102
19.7230829233
21.400934559
22.0
22.5831795813
23.0
24.0416305603
25.2388589282
26.8141753556
22.5388553392
9.2736184955
13.5277492585
15.2970585408

Будем признательны за любую помощь или предложения. Если вам нужна дополнительная информация, дайте мне знать!


person Doa    schedule 08.05.2012    source источник
comment
из того, что я понял из примера, который они показывают в документе, kmeans работает с наборами координат x-y, в то время как вы предоставляете только одну функцию в строке, есть ли у вас какое-либо связанное значение с вашими данными, которые вы должны включить?   -  person Smash    schedule 08.05.2012
comment
Я предполагал, что в данном случае у него была только одна черта   -  person Matt    schedule 08.05.2012
comment
может быть, добавить второй столбец 1s?   -  person Smash    schedule 08.05.2012
comment
Это определенно заставит его что-то сделать, зависит от того, что это означает. Один минус косинус угла между точками (рассматриваемыми как векторы). Каждый центроид является средним значением точек в этом кластере после нормализации этих точек на единицу евклидовой длины.   -  person Matt    schedule 08.05.2012
comment
Смотрите мой ответ на ответ Мэтта. Сферические k-средние (или математические описания, которые я смог найти) принимают в качестве входных данных единичный вектор. Возможно ли, что это будет иначе для реализации Matlab?   -  person Doa    schedule 08.05.2012


Ответы (1)


Это косинусное расстояние делает его неудачным, оно работает с sqEuclidean. Я думаю, что косинусное расстояние нуждается в дополнительной информации, иначе не имеет смысла в вашем наборе данных.

Редактировать: я соглашусь с вами, что документация здесь немного расплывчата ... но определение косинусного расстояния в функции pdist Matlab: «Один минус косинус включенного угла между точками (обрабатываемыми как векторы)».

Я исхожу из того, что угол должен быть включен (я предполагаю в следующем столбце). Но похоже, что это противоречит цели. подобие косинуса Изменить еще раз: я думаю, это больше похоже, что включенный означает "включенный угол между 2 векторами". В этом случае я думаю, что косинус ожидает, что будут работать 2 или более столбца.

Кроме того, если вы уже увлекаетесь python, есть несколько хороших инструментов машинного обучения. Вот один, который я использовал. Существует также MILK, но я сам им никогда не пользовался.

person Matt    schedule 08.05.2012
comment
Насколько я знаю, kmeans с косинусом принимает в качестве входных данных единичный вектор, не так ли? Например, см. это описание для сферических k-средних, как это также известно: shi-zhong .com/papers/oskm_ijcnn05.pdf Есть еще идеи? - person Doa; 08.05.2012
comment
Кроме того, хотя у sklearn есть kmeans, он не позволяет мне установить другую меру расстояния, или нет? Это всего лишь евклидов AFAICT. - person Doa; 08.05.2012
comment
Вы можете увидеть, запустив pdist(data,'cosine'), что он вычисляет нулевое расстояние для всех ваших данных. Таким образом, очевидно, что определение Matlab - это не то, что вы ожидаете. Если вы поместите столбец единиц рядом с вашими данными, вы получите что-то, но я не очень хорошо знаком с косинусным расстоянием, поэтому я не знаю, чего ожидать. - person Matt; 08.05.2012
comment
Вы были правы, я дал ему неправильные входные данные. Для нормализации я должен был сделать: def l2(a): power=np.power(a,2) norm=np.matrix(np.sqrt(np.sum(np.power(a,2),1)) ) вернуть a/np.tile (норма, a.shape [1]) - person Doa; 09.05.2012