【问题标题】:Clustering text in MATLAB在 MATLAB 中对文本进行聚类
【发布时间】:2011-04-08 10:51:10
【问题描述】:

我想在 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)

工作正常并返回树状图。

我想知道我可以在上面提到的文本上使用这些命令。有什么想法吗 ?


更新:

感谢 Amro。阅读理解并计算字符串之间的距离。代码如下:

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

我得到的输出是:

在 93 处使用 ==> 链接时出错 Y 与输出不兼容 PDIST 函数。

错误 ==> Untitled2 at 20 Z=linkage(X,'single') .

为什么会这样?可以使用联动功能吗?帮助表示赞赏。

更新 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 at 22 中的错误 D(kk,jk)= levenshtein_distance(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 in NY,我不会存储 NY catches fire。但是,对于第一种情况,我会存储为新信息。

LD 是否足以做到这一点?帮助表示赞赏。

【问题讨论】:

  • 仍在搜索和阅读代码。我计算出 A=double(B),将字符串 B 转换为其等效向量 A。因此,我为句子创建了向量,最后将它们全部放入矩阵中。现在,我可以使用 Matlab 命令了。
  • 天哪!仅在句子长度相同时有效。不记得如何强制所有矩阵大小相同且填充为零。
  • 请花点时间正确格式化代码(编辑问题时,突出显示代码部分,然后按“代码示例”按钮[带有0和1的那个])跨度>
  • @Amro。感谢您的编辑建议。现在看起来好多了。很高兴能学到这么多东西。

标签: matlab cluster-analysis text-mining


【解决方案1】:

你需要的是一个可以处理字符串的距离函数。查看Levenshtein distance(编辑距离)。那里有很多实现:

或者,您应该提取一些有趣的特征(例如:元音的数量、字符串的长度等)来构建向量空间表示,然后您可以应用任何常用的距离度量(欧几里得、...)关于新的表示。


编辑

您的代码的问题是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)

有关更多信息,请参阅相关函数的文档...

【讨论】:

  • L.distance 与 HAC 不同,不是吗?我只寻找HAC。我找不到 HAC 是否使用任何特殊功能提取矢量。我可以将文本转换为矢量(全无字符)吗?关于如何构建向量空间的任何提示?
  • Levenshtein distance 不是聚类算法,它是两个字符串之间的距离函数。这是必要的,因为分层聚类首先计算所有实例对之间的距离矩阵PDIST,然后开始以自下而上的方法(凝聚)合并它们LINKAGE
  • 我正在阅读您提供的链接。将更新我能做什么。谢谢阿姆罗。
  • 看了文档就明白了。复制代码并运行。如果我理解正确,第一个循环一次取一个字符串,第二个循环与其余循环进行比较。我将一个字符串定义为 S1 并想从文件中读取其他字符串。我正在更新我刚刚按照您的代码编辑的代码。我有一个错误,想知道我是否可以这样做。非常感谢和帮助。
  • @Tinglin:你想做什么?层次聚类采用所有个实例并计算它们彼此之间的距离(不是一个特定的与所有其他实例),然后将相似的实例组合在一起形成集群。至于循环,它将比较实例按我之前解释的顺序:1-vs-2、1-vs-3、1-vs-4、2-vs-3、2-vs-4 和 3-vs-4(基本上所有可能的无序对)
猜你喜欢
  • 2014-05-29
  • 1970-01-01
  • 2015-06-22
  • 2019-01-06
  • 2015-03-09
  • 2013-12-10
  • 2014-10-02
  • 1970-01-01
  • 2019-12-09
相关资源
最近更新 更多