요즘에는 python이 인기가 더 많은듯 한데 개인적으로 python을 별로
좋아하지 않는다. 사실 매우 편협한 이유인데 들여쓰기와 함수의 시작
과 끝이 { }로 구분되지 않는다는 점때문이다.
간단히 Cosine similarity를 구하기 위해서 python이나 perl과 같은 스크립트
언어로 스크립트를 짜야 할 때가 많은데 다음의 cosine similarity를 구해주는
간단한 perl 스크립트를 이용해 보시라.
사용법은 간단하다.
document.txt 라는 파일을 만들고 파일에 여러 다큐먼트를 다음과 같은
포맷으로 합친후 스크립트를 그냥 실행하면 된다.
<TITLE> doc1 </TITLE>
This is document1.
<TITLE> doc2 </TITLE>
This is document2.
소스는 별로 어렵지 않으니 다큐먼트를 합치기가 귀찮다거나 아니면
알고리즘을 수정하고 싶다면 간단히 수정해보아도 공부하는데 도움이
될듯하다.
기본적으로 소스에서는 IDF를 log2 ( N / DF )로 계산하고 있다.
#!/usr/bin/perl
use strict;
open(IN, "document.txt") or die;
my $nstory = -1;
my @words;
my %granddict;
my @weight;
my @unit;
my $i;
my $j;
my @cosine;
my $word;
my $sum;
my $df;
my @tf;
my $n;
my %df;
my $len2;
my $len;
#Step 1: Compute the term frequencies
while(<IN>){
chomp;
my $title;
if ( /<TITLE>(.*)<\/TITLE>/ ){
$title = $1;
++$nstory;
print "Title of story $nstory = $title \n";
} else {
$_ = lc;
s/--/ /g;
s/ - / /g;
s/[,.";!()?:_\[\]]//g;
s/\s+/ /g;
s/^\s+//g;
@words = split(/ /);
foreach $word (@words){
if ($word =~ /^;?(.*?)'?$/){
$word = $1;
}
++$tf[$nstory]{$word};
++$granddict{$word};
}
}
}
foreach $word (sort keys %granddict ) {
$sum = 0;
for $i ( 0 .. $#tf ){
if ($tf[$i]{$word} > 0){
++$sum;
}
$df{$word} = $sum;
}
}
$n = $#tf + 1;
foreach $word (sort keys %granddict){
for $i (0 .. $#tf){
$weight[$i]{$word} = $tf[$i]{$word}*log($n/$df{$word})/log(2);
}
}
for $i ( 0 .. $#tf ) {
$len2 = 0;
foreach $word ( sort keys %granddict){
$len2 += $weight[$i]{$word}**2;
}
$len = sqrt($len2);
foreach $word ( sort keys %granddict){
$unit[$i]{$word} = $weight[$i]{$word}/$len;
}
}
for $i ( 0 .. $#tf ) {
for $j ( 0 .. $#tf ) {
$sum = 0;
foreach $word ( sort keys %granddict ) {
$sum += $unit[$i]{$word} * $unit[$j]{$word};
}
$cosine[$i][$j] = $sum;
}
}
print "\n";
for $i ( 0 .. $#tf) {
for $j (0 .. $#tf) {
printf "%.4f ", $cosine[$i][$j];
}
print "\n";
}
댓글 없음:
댓글 쓰기