Pregunta

Quiero hacer agrupamiento aglutinador jerárquica de textos en MATLAB. Por ejemplo, tengo cuatro frases,

I have a pen.
I have a paper. 
I have a pencil.
I have a cat. 

Quiero agrupar los anteriores cuatro frases para ver que son más similares. Yo sé caja de herramientas Estadística tiene comando como pdist para medir distancias por pares, linkage para calcular la similitud cúmulo etc. Un código simple como:

X=[1 2; 2 3; 1 4];
Y=pdist(X, 'euclidean');
Z=linkage(Y, 'single');
H=dendrogram(Z)

funciona bien y regresar un dendrograma.

Me pregunto puedo utilizar estos comandos en los textos como he mencionado anteriormente. Alguna idea ?


Actualizaciones:

Gracias a Amro. Leer entendida y calculada la distancia entre las cuerdas. Código siguiente:

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 

I de entrada una cadena y yo tuvimos 4 cadenas guardadas. Ahora he calculado la distancia por pares usando la función levenshtein_distance. Devuelve un X=[ 17 0 16 18 16] matriz.

** Creo que esta es mi par matriz prudente distancia. De manera similar a lo que hace pdist. Es?

** Ahora, estoy tratando de entrada X para calcular la vinculación como

Z=linkage(X, 'single);

Salida estoy consiguiendo es:

  

Error usando ==> vinculación a 93 Tamaño de   Y no es compatible con la salida de   la función PDIST.

     

Error en ==> Untitled2 en 20   Z = enlace (X, 'single').

¿Por qué? Se puede utilizar la función de enlace en absoluto? Ayuda apreciada.

ACTUALIZACIÓN 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).

Error: ??? Referencia Contenido de la celda a partir de una matriz de objetos no-celular. Error en ==> Untitled2 a 22   D (kk, jk) = levenshtein_distance (S1 {kk}, S2 {jk});

Además, ¿Por qué estoy leyendo el evento desde el archivo dentro del primer bucle? No parece lógico. Poco confundido, si puedo trabajar de esta manera o única solución es a la entrada de todas las cadenas en el código. Ayuda muy apreciada.

Actualizar

código para comparar dos frases:

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');  

Salida D = 18.

con diferentes cadenas:

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.

Con base en la distancia, una frase completamente diferente es similar. Lo que estoy tratando de hacer, si he almacenado Fuego en Nueva York , que suele tienda NY catches fire . Sin embargo, para el primer caso, que almacenaría como la información es nueva.

es suficiente para hacer esto LD? Ayuda apreciado.

¿Fue útil?

Solución

Lo que necesita es una función de la distancia que puede manejar cadenas. Echa un vistazo a la Levenshtein distancia (distancia de edición). Hay un montón de implementaciones por ahí:

Como alternativa, usted debe extraer algunas características interesantes (por ejemplo: número de vocales, longitud de cadena, etc ..) para construir una representación de espacio vectorial, entonces se puede aplicar alguna de las medidas habituales de distancia (euclidiana, ...) en la nueva representación.


Editar

El problema con el código es que VARILLAJE espera la entrada formato de distancias para que coincida con la de PDIST , a saber, una vector fila que corresponde a pares de observaciones en el orden 1-vs-2, 1-vs-3, 2-vs-3, etc .., que es básicamente la mitad inferior de la matriz de distancia completa (ya que se supone que es simétrica como 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)

Por favor, consulte la documentación de las funciones en cuestión para más información ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top