请原谅我在这领域还比较新手,如果我的问题听起来很简单或基础,请多包涵。
我有一组数据集(具体来说是词袋),我需要通过计算它们之间的编辑距离来生成一个邻近矩阵,以便寻找和生成这个邻近矩阵。
然而,我对如何在矩阵中跟踪我的数据/字符串感到相当困惑。我需要这个邻近矩阵来进行聚类。
或者,在这个领域中,您通常是如何处理这类问题的?我正在使用Perl和R来实现这个功能。
这里是我编写的一个典型的Perl代码,用于从包含我的词袋的文本文件中读取数据
use strict ; use warnings ; use Text::Levenshtein qw(distance) ; main(@ARGV); sub main { my @TokenDistances ; my $Tokenfile = 'TokenDistinct.txt'; my @Token ; my $AppendingCount = 0 ; my @Tokencompare ; my %Levcount = (); open (FH ,"< $Tokenfile" ) or die ("Error opening file . $!"); while(<FH>) { chomp $_; $_ =~ s/^(\s+)$//g; push (@Token , $_ ); } close(FH); @Tokencompare = @Token ; foreach my $tokenWord(@Tokencompare) { my $lengthoffile = scalar @Tokencompare; my $i = 0 ; chomp $tokenWord ; #@TokenDistances = levDistance($tokenWord , \@Tokencompare ); for($i = 0 ; $i < $lengthoffile ;$i++) { if(scalar @TokenDistances == scalar @Tokencompare) { print "Yipeeeeeeeeeeeeeeeeeeeee\n"; } chomp $tokenWord ; chomp $Tokencompare[$i]; #print $tokenWord. " {$Tokencompare[$i]} " . " $TokenDistances[$i] " . "\n"; #$Levcount{$tokenWord}{$Tokencompare[$i]} = $TokenDistances[$i]; $Levcount{$tokenWord}{$Tokencompare[$i]} = levDistance($tokenWord , $Tokencompare[$i] ); } StoreSortedValues ( \%Levcount ,\$tokenWord , \$AppendingCount); $AppendingCount++; %Levcount = () ; } # %Levcount = (); }sub levDistance{ my $string1 = shift ; #my @StringList = @{(shift)}; my $string2 = shift ; return distance($string1 , $string2);}sub StoreSortedValues { my $Levcount = shift; my $tokenWordTopMost = ${(shift)} ; my $j = ${(shift)}; my @ListToken; my $Tokenfile = 'LevResult.txt'; if($j == 0 ) { open (FH ,"> $Tokenfile" ) or die ("Error opening file . $!"); } else { open (FH ,">> $Tokenfile" ) or die ("Error opening file . $!"); } print $tokenWordTopMost; my %tokenWordMaster = %{$Levcount->{$tokenWordTopMost}}; @ListToken = sort { $tokenWordMaster{$a} cmp $tokenWordMaster{$b} } keys %tokenWordMaster; #@ListToken = keys %tokenWordMaster; print FH "-------------------------- " . $tokenWordTopMost . "-------------------------------------\n"; #print FH map {"$_ \t=> $tokenWordMaster{$_} \n "} @ListToken; foreach my $tokey (@ListToken) { print FH "$tokey=>\t" . $tokenWordMaster{$tokey} . "\n" } close(FH) or die ("Error Closing File. $!");}
问题在于,我如何从中表示邻近矩阵,并且仍然能够跟踪矩阵中的哪个比较代表哪个。
回答:
在RecordLinkage
包中,有一个levenshteinDist
函数,这是计算字符串之间编辑距离的一种方法。
install.packages("RecordLinkage")library(RecordLinkage)
设置一些数据:
fruit <- c("Apple", "Apricot", "Avocado", "Banana", "Bilberry", "Blackberry", "Blackcurrant", "Blueberry", "Currant", "Cherry")
现在创建一个由零组成的矩阵,以预留内存用于距离表。然后使用嵌套的for
循环来计算各个距离。我们最终得到一个矩阵,每个水果都有一行和一列。因此,我们可以将列和行重命名为与原始向量相同。
fdist <- matrix(rep(0, length(fruit)^2), ncol=length(fruit))for(i in seq_along(fruit)){ for(j in seq_along(fruit)){ fdist[i, j] <- levenshteinDist(fruit[i], fruit[j]) }}rownames(fdist) <- colnames(fdist) <- fruit
结果如下:
fdist Apple Apricot Avocado Banana Bilberry Blackberry BlackcurrantApple 0 5 6 6 7 9 12Apricot 5 0 6 7 8 10 10Avocado 6 6 0 6 8 9 10Banana 6 7 6 0 7 8 8Bilberry 7 8 8 7 0 4 9Blackberry 9 10 9 8 4 0 5Blackcurrant 12 10 10 8 9 5 0Blueberry 8 9 9 8 3 3 8Currant 7 5 6 5 8 10 6Cherry 6 7 7 6 4 6 10