2016-09-13 2 views
0

У меня есть файл содержать, например, этот текст:косинуса сходства между строками PERL

perl java python php scala 
java pascal perl ruby ada 
ASP awk php java perl 
C# ada python java scala 

я нашел модуль, который вычисляет косинус similaity, http://search.cpan.org/~wollmers/Bag-Similarity-0.019/lib/Bag/Similarity/Cosine.pm

Я сделал простой тест в bignning,

my $cosine = Bag::Similarity::Cosine->new; 
my $similarity = $cosine->similarity(['perl','java','python','php','scala'],['java','pascal','perl','ruby','ada']); 
print $similarity; 

rusult было 0,4;

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

open(F,"/home/ahmed/FILE.txt") or die " Pb pour ouvrir"; 
my @data; # containt each line of the FILE in each case 

while(<F>) { 
    chomp; 
    push @data, $_; 
} 
#print join " ", @data; 

my $cosine = Bag::Similarity::Cosine->new; 

for my $i (0 .. $#data-1) { 

    for my $j ($i + 1 .. $#data) { 

my $similarity = $cosine->similarity($data[$i],$data[$j]); 

print "line $i a une similarite de $similarity avec line $j\n"; 

$i + 1, 

      $j + 1; 
} 
} 

результаты:

line 0 has a similarity of 0.933424735647156 with line 1 
line 0 has a similarity of 0.953945734121021 with line 2 
line 0 has a similarity of 0.939759036144578 with line 3 
line 1 has a similarity of 0.917585834612093 with line 2 
line 1 has a similarity of 0.945092544842746 with line 3 
line 2 has a similarity of 0.908826679128811 with line 3 

сходство должно 0,4 между линиями 1 и 2;

Я изменил ФАЙЛ так:

['perl','java','python','php','scala'] 
['java','pascal','perl','ruby','ada'] 
['ASP','awk','php','java','perl'] 
['C#','ada','python','java','scala'] 

, но тот же результат, Спасибо.

+0

Это очень странное изменение, чтобы внести в свой входной файл. Вы сделали его похожим на строковое представление ссылки на массив. Откуда у вас эта идея? –

+1

Я знаю, что это странно, я попробовал все решения, прежде чем я разместил этот вопрос, это мои первые шаги с perl, без ошибок, мы не можем учиться :) – Ahmed

ответ

1

В вашей программе есть синтаксическая ошибка. Вы пытались использовать printf и использовали ошибку? print Понятно? Не уверен, что вы, но ниже, отлично подходят для меня.

#!/usr/bin/perl 
use strict; 
use warnings; 
use Bag::Similarity::Cosine; 

my $cosine = Bag::Similarity::Cosine->new; 
my @data; 

while (<DATA>) { 
    push @data, { map { $_ => 1 } split }; 
} 

for my $i (0 .. $#data-1) { 
    for my $j ($i + 1 .. $#data) { 
     my $similarity = $cosine->similarity($data[$i],$data[$j]); 
     print "line $i has a similarity of $similarity with line $j\n"; 
    } 
} 

__DATA__ 
perl java python php scala 
java pascal perl ruby ada 
ASP awk php java perl 
C# ada python java scala 

Выход:

line 0 has a similarity of 0.4 with line 1 
line 0 has a similarity of 0.6 with line 2 
line 0 has a similarity of 0.6 with line 3 
line 1 has a similarity of 0.4 with line 2 
line 1 has a similarity of 0.4 with line 3 
line 2 has a similarity of 0.2 with line 3 
+0

Спасибо, chankey, :) действительно у меня много проблем с массивами ref, map, grep ... пожалуйста, у вас есть полный курс для perl – Ahmed

+0

Любая причина, по которой вы конвертируете данные в хэш-ссылки чем массив refs? Я ничего не знаю об этой области, поэтому я мог бы пропустить что-то очевидное. –

0

Я ничего не знаю об этом модуле. Но я могу читать the documentation.

Мне кажется, что модуль имеет два метода. similarity() используется для сравнения двух строк, а используется для сравнения двух ссылок на массивы, содержащие строки. Я ожидаю, что когда вы вызываете similarity, передавая ему две ссылки на массивы, то то, что сравнивается, на самом деле является строкой двух ссылок.

Попробуйте переключиться на from_bags() и посмотрите, не лучше ли это.

Update: Исследуя дальше, я вижу, что similarity() будет сравнивать любой вид ввода (строки, рефы массива или хэш-реф).

Это демонстрирует использование similarity() для сравнения строк как текста и массивов слов.

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

use Bag::Similarity::Cosine; 

chomp(my @data = <DATA>); 

my $cos = Bag::Similarity::Cosine->new; 

for my $i (0 .. $#data - 1) { 
    for my $j (1 .. $#data) { 
    next if $i == $j; 
    say "$i -> $j: strings ", $cos->similarity($data[$i], $data[$j]); 
    say "$i -> $j: array refs ", $cos->similarity([split /\s+/, $data[$i]], [split /\s+/, $data[$j]]); 
    } 
} 

__DATA__ 
perl java python php scala 
java pascal perl ruby ada 
ASP awk php java perl 
C# ada python java scala 

И это дает этот результат:

$ perl similar 
0 -> 1: strings 0.88602000346543 
0 -> 1: array refs 0.4 
0 -> 2: strings 0.89566858950296 
0 -> 2: array refs 0.6 
0 -> 3: strings 0.852802865422442 
0 -> 3: array refs 0.6 
1 -> 2: strings 0.872356744289958 
1 -> 2: array refs 0.4 
1 -> 3: strings 0.884721984738799 
1 -> 3: array refs 0.4 
2 -> 1: strings 0.872356744289958 
2 -> 1: array refs 0.4 
2 -> 3: strings 0.753778361444409 
2 -> 3: array refs 0.2 

Я не знаю, какая версия дает вам информацию, которую вы хотите. Я подозреваю, что это может быть эталонная версия массива.

+0

Я тоже попробовал, у меня есть эта ошибка, Не могу использовать строку («['perl', 'java', 'python', 'php', 's' ...) как ARRAY ref, в то время как« строгие refs »используются в Bag/Similarity/Cosine.pm, cosine.pm - это длинный файл конфигурации, который я загрузил из приведенной выше ссылки, – Ahmed

+0

Вы, кажется, используете, где нужна ссылка на массив. Но, не зная, что изменилось, я больше не могу помочь. –

+0

Спасибо, Дэйв, он работает :) – Ahmed

Смежные вопросы