Реализация матрицы близости для кластеризации - PullRequest
6 голосов
/ 08 августа 2011

Пожалуйста, я немного новичок в этой области, так что извините, если вопрос звучит тривиально или просто.

У меня есть группа данных (Мешок слов, чтобы быть конкретным), и мне нужно сгенерировать матрицу близости, используя их расстояние редактирования друг от друга, чтобы найти и сгенерировать матрицу близости.

Я, однако, очень озадачен тем, как я буду отслеживать свои данные / строки в матрице. Мне нужна матрица близости для кластеризации.

Или как обычно вы подходите к этой проблеме в поле. Я использую 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.  $!");

}

проблема в том, как я могу из этого представить матрицу близости и все еще иметь возможность отслеживать, какое сравнение представляет, какое в моей матрице.

Ответы [ 2 ]

7 голосов
/ 09 августа 2011

В пакете 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 Blackcurrant
Apple            0       5       6      6        7          9           12
Apricot          5       0       6      7        8         10           10
Avocado          6       6       0      6        8          9           10
Banana           6       7       6      0        7          8            8
Bilberry         7       8       8      7        0          4            9
Blackberry       9      10       9      8        4          0            5
Blackcurrant    12      10      10      8        9          5            0
Blueberry        8       9       9      8        3          3            8
Currant          7       5       6      5        8         10            6
Cherry           6       7       7      6        4          6           10
2 голосов
/ 08 августа 2011

Матрица близости или сходства (или различий) - это просто таблица, в которой хранится показатель сходства для пар объектов.Таким образом, если у вас есть N объектов, тогда код R может быть simMat <- matrix(nrow = N, ncol = N), и тогда каждая запись (i, j) из simMat указывает на сходство между элементом i и элементом j.

ВR, вы можете использовать несколько пакетов, включая vwr, для вычисления расстояния редактирования Левенштейна.

Вы также можете найти этот Викиучебник интересным: http://en.wikibooks.org/wiki/R_Programming/Text_Processing

...