Кластеризация текста в MATLAB
Я хочу сделать иерархическую агломерационную кластеризацию по текстам в MATLAB. Скажи, у меня есть четыре предложения,
I have a pen.
I have a paper.
I have a pencil.
I have a cat.
Я хочу объединить четыре вышеупомянутых предложения, чтобы увидеть, какие из них более похожи. Я знаю, что в панели инструментов статистики есть команда pdist
измерять попарные расстояния, linkage
рассчитать сходство кластеров и т. д. Простой код, такой как:
X=[1 2; 2 3; 1 4];
Y=pdist(X, 'euclidean');
Z=linkage(Y, 'single');
H=dendrogram(Z)
работает нормально и возвращает дендрограмму.
Интересно, могу ли я использовать эти команды в текстах, как я упоминал выше? Какие-нибудь мысли?
ОБНОВЛЕНИЕ:
Спасибо Амро. Прочитал Понял и вычислил расстояние между строками. Код следует:
clc
S1='I have a pen'; % first String
f_id=fopen('events.txt','r'); %saved strings to compare with
events=textscan(f_id, '%s', 'Delimiter', '\n');
fclose(f_id); %close file.
events=events{1}; % saving the text read.
ii=numel(events); % selects one text randomly.
% store the texts in a cell array
for kk=1:ii
S2=events(kk);
S2=cell2mat(S2);
Z=levenshtein_distance(S1,S2);
X(kk)=Z;
end
Я ввел строку, и у меня было 4 сохраненных строки. Теперь я рассчитал парное расстояние, используя levenshtein_distance
функция. Возвращает матрицу X=[ 17 0 16 18 16]
,
** Полагаю, это моя матрица парных расстояний. Подобно тому, что делает pdist. Это?
** Теперь я пытаюсь ввести X, чтобы вычислить связь как
Z=linkage(X, 'single);
Вывод, который я получаю:
Ошибка при использовании ==> linkage в 93 Размер Y не совместим с выходом функции PDIST.
Ошибка в ==> Untitled2 при 20 Z= связь (X, "одиночный") .
Почему так? Можно ли вообще использовать функцию связи? Помощь приветствуется.
ОБНОВЛЕНИЕ 2
clc
S1='I have a pen';
f_id=fopen('events.txt','r');
events=textscan(f_id, '%s', 'Delimiter', '\n');
fclose(f_id); %close file.
events=events{1}; % saving the text read.
ii=numel(events)+1; % total number of strings in the comparison
D=zeros(ii, ii); % initialized distance matrix;
for kk=1:ii
S2=events(kk);
%S2=cell2mat(S2);
for jk=kk+1:ii
D(kk,jk)= levenshtein_distance(S1{kk},S2{jk});
end
end
D = D + D'; %'# symmetric distance matrix
%# linkage expects the output format to match that of pdist,
%# so we convert D to a row vector (lower/upper part of matrix)
D = squareform(D, 'tovector');
T = linkage(D, 'single');
dendrogram(T).
Ошибка:??? Ссылка на содержимое ячейки из объекта массива не из ячеек. Ошибка в ==> Untitled2 в 22 D(кк,jk)= левенштейн_дистанция (S1{kk},S2{jk});
Кроме того, почему я читаю событие из файла в первом цикле? Не кажется логичным. Немного смущен, если я могу работать таким образом или единственное решение - ввести все строки внутри кода. Помощь высоко ценится.
ОБНОВИТЬ
код для сравнения двух предложений:
clc
str1 = 'Fire in NY';
str2= 'Jeff is sick';
D=levenshtein_distance(str1,str2);
D = D + D'; %'# symmetric distance matrix
%# linkage expects the output format to match that of pdist,
%# so we convert D to a row vector (lower/upper part of matrix)
%D = squareform(D, 'tovector');
T = linkage(D, 'complete');
[H,P] = dendrogram(T,'colorthreshold','default');
Выход D=18.
С разными строками:
clc
str1 = 'Fire in NY';
str2= 'NY catches fire';
D=levenshtein_distance(str1,str2);
D = D + D'; %'# symmetric distance matrix
%# linkage expects the output format to match that of pdist,
%# so we convert D to a row vector (lower/upper part of matrix)
%D = squareform(D, 'tovector');
T = linkage(D, 'complete');
[H,P] = dendrogram(T,'colorthreshold','default');
D = 28.
В зависимости от расстояния совершенно другое предложение выглядит похожим. Что я пытаюсь сделать, если я храню Fire в Нью-Йорке, я не буду хранить NY catches fire
, Тем не менее, для первого случая, я бы сохранил, поскольку информация новая.
Достаточно ли LD для этого? Помощь приветствуется.
1 ответ
Что вам нужно, это функция расстояния, которая может обрабатывать строки. Проверьте расстояние Левенштейна (изменить расстояние). Существует множество реализаций:
Кроме того, вы должны извлечь некоторые интересные особенности (например: количество гласных, длина строки и т. Д.), Чтобы построить представление векторного пространства, затем вы можете применить любую из обычных мер расстояния (евклидов, ...) к новому представление.
РЕДАКТИРОВАТЬ
Проблема с вашим кодом в том, что LINKAGE ожидает, что формат входных расстояний будет совпадать с форматом PDIST, а именно вектор строки, соответствующий парам наблюдений в порядке 1-vs-2, 1-vs-3, 2-vs-3 и т. Д... которая в основном является нижней половиной полной матрицы расстояний (поскольку она должна быть симметричной как dist(1,2) == dist(2,1)
)
%# instances
str = {'I have a pen.'
'I have a paper.'
'I have a pencil.'
'I have a cat.'};
numStr = numel(str);
%# create and fill upper half only of distance matrix
D = zeros(numStr,numStr);
for i=1:numStr
for j=i+1:numStr
D(i,j) = levenshtein_distance(str{i},str{j});
end
end
D = D + D'; %'# symmetric distance matrix
%# linkage expects the output format to match that of pdist,
%# so we convert D to a row vector (lower/upper part of matrix)
D = squareform(D, 'tovector');
T = linkage(D, 'single');
dendrogram(T)
Пожалуйста, обратитесь к документации по соответствующим функциям для получения дополнительной информации...