Text::Document 中用于测量 CosineSimilarity 的变量未初始化
Variable used to measure CosineSimilarity in Text::Document is uninitialized
我正在使用 Text::Document 来计算两个文档之间的余弦相似度。当我尝试打印包含结果余弦相似度得分 ($sim) 的变量时,我收到一条错误消息:"Use of unitialized value $sim in concatenation (.) or string..."。据我所知,我在打印命令的正上方初始化了这个变量。不可否认,这是我第一次涉足 Text::Document 模块,我在这里的对象构造可能 faulty/ugly/potentially 有问题。任何想法变量初始化有什么问题?
use strict ;
use warnings ;
use autodie ;
use Text::Document ;
### BEGIN BY READING IN EACH FILE ONE BY ONE. ###
################## LOOP BEGIN ##################
# Process every file with a `txt` file type
my $parent = "D:/Cleaned 10Ks" ;
my ($par_dir, $sub_dir);
opendir($par_dir, $parent);
while (my $sub_folders = readdir($par_dir)) {
next if ($sub_folders =~ /^..?$/); # skip . and ..
my $path = $parent . '/' . $sub_folders;
next unless (-d $path); # skip anything that isn't a directory
chdir($path) or die "Cant chdir to $path $!";
for my $filename ( grep -f, glob('*') ) {
open my ($fh), '<', $filename;
my $data1 = do {local $/; <$fh> } ;
my $data2 = Text::Document->new(file=>'$data1') ;
my $data3 = $data2->WriteToString() ;
my $data4 = Text::Document::NewFromString($data3) ;
my ($comp_id, $year, $rest) = split '-', $filename, 3;
my $prev_year = ($year ne '00') ? $year - 1 : 99;
my $prev_year_base = join '-', $comp_id, $year ;
my ($prev_year_file) = glob "$prev_year_base*" ;
open my ($fh_prior), '<', $prev_year_file ;
my $data1_prior = do {local $/; <$fh_prior> } ;
my $data2_prior = Text::Document->new(file=>'$data1_prior') ;
my $data3_prior = $data2->WriteToString() ;
my $data4_prior = Text::Document::NewFromString($data3_prior) ;
my $sim = $data4->CosineSimilarity( $data4_prior ) ;
print "The cosine similarity score is $sim\n" ;
}
}
查看源代码,我看到 CosineSimilarity
有这个金块:
if( ($nD==0) || ($nE==0) ){
return undef;
} else {
return $dotProduct / $nD / $nE;
}
它会 return undef 而不是因被零除错误而爆炸。 (虽然处理您的错误很好,但有时错误处理会使错误的发生变得不那么明显。我认为您的情况就是这样一种情况-一旦您知道了,检查 undef 就更明显了,但是如果您有除以零异常,您可能会以不同的方式看待事物。)
无论如何,$nD
和$nE
都是通过在$d
($self
)和$e
上调用的EuclideanNorm
方法来确定的.您可能应该尝试将它们打印出来作为下一个调试步骤,我猜您的 $data4_prior
会输出 0,但实际上也可能是。没有你的实际数据,我无法找出答案,所以希望这能为你进一步调试提供一个良好的起点。
你有几个问题..
my $data2 = Text::Document->new(file=>'$data1') ;
这里你似乎想象$data2
会被$data1
的内容初始化。
实际上 file
关键字在这里什么都不做,该行等同于
my $data2 = Text::Document->new() ;
您已成功初始化一个 Text::Document
对象,但它没有数据。
你对先前的对象做同样的事情,所以你最终比较了两个没有比较项的对象。 $sim
为空。
解决方法是向新对象添加一些内容:
my $data2 = Text::Document->new() ;
$data2->AddContent($data1);
...与先前的对象相同。
此外,您可以删除这些行:
my $data3 = $data2->WriteToString() ;
my $data4 = Text::Document::NewFromString($data3) ;
它们是多余的。您只是在重新创建相同的(空的)对象。
我正在使用 Text::Document 来计算两个文档之间的余弦相似度。当我尝试打印包含结果余弦相似度得分 ($sim) 的变量时,我收到一条错误消息:"Use of unitialized value $sim in concatenation (.) or string..."。据我所知,我在打印命令的正上方初始化了这个变量。不可否认,这是我第一次涉足 Text::Document 模块,我在这里的对象构造可能 faulty/ugly/potentially 有问题。任何想法变量初始化有什么问题?
use strict ;
use warnings ;
use autodie ;
use Text::Document ;
### BEGIN BY READING IN EACH FILE ONE BY ONE. ###
################## LOOP BEGIN ##################
# Process every file with a `txt` file type
my $parent = "D:/Cleaned 10Ks" ;
my ($par_dir, $sub_dir);
opendir($par_dir, $parent);
while (my $sub_folders = readdir($par_dir)) {
next if ($sub_folders =~ /^..?$/); # skip . and ..
my $path = $parent . '/' . $sub_folders;
next unless (-d $path); # skip anything that isn't a directory
chdir($path) or die "Cant chdir to $path $!";
for my $filename ( grep -f, glob('*') ) {
open my ($fh), '<', $filename;
my $data1 = do {local $/; <$fh> } ;
my $data2 = Text::Document->new(file=>'$data1') ;
my $data3 = $data2->WriteToString() ;
my $data4 = Text::Document::NewFromString($data3) ;
my ($comp_id, $year, $rest) = split '-', $filename, 3;
my $prev_year = ($year ne '00') ? $year - 1 : 99;
my $prev_year_base = join '-', $comp_id, $year ;
my ($prev_year_file) = glob "$prev_year_base*" ;
open my ($fh_prior), '<', $prev_year_file ;
my $data1_prior = do {local $/; <$fh_prior> } ;
my $data2_prior = Text::Document->new(file=>'$data1_prior') ;
my $data3_prior = $data2->WriteToString() ;
my $data4_prior = Text::Document::NewFromString($data3_prior) ;
my $sim = $data4->CosineSimilarity( $data4_prior ) ;
print "The cosine similarity score is $sim\n" ;
}
}
查看源代码,我看到 CosineSimilarity
有这个金块:
if( ($nD==0) || ($nE==0) ){
return undef;
} else {
return $dotProduct / $nD / $nE;
}
它会 return undef 而不是因被零除错误而爆炸。 (虽然处理您的错误很好,但有时错误处理会使错误的发生变得不那么明显。我认为您的情况就是这样一种情况-一旦您知道了,检查 undef 就更明显了,但是如果您有除以零异常,您可能会以不同的方式看待事物。)
无论如何,$nD
和$nE
都是通过在$d
($self
)和$e
上调用的EuclideanNorm
方法来确定的.您可能应该尝试将它们打印出来作为下一个调试步骤,我猜您的 $data4_prior
会输出 0,但实际上也可能是。没有你的实际数据,我无法找出答案,所以希望这能为你进一步调试提供一个良好的起点。
你有几个问题..
my $data2 = Text::Document->new(file=>'$data1') ;
这里你似乎想象$data2
会被$data1
的内容初始化。
实际上 file
关键字在这里什么都不做,该行等同于
my $data2 = Text::Document->new() ;
您已成功初始化一个 Text::Document
对象,但它没有数据。
你对先前的对象做同样的事情,所以你最终比较了两个没有比较项的对象。 $sim
为空。
解决方法是向新对象添加一些内容:
my $data2 = Text::Document->new() ;
$data2->AddContent($data1);
...与先前的对象相同。
此外,您可以删除这些行:
my $data3 = $data2->WriteToString() ;
my $data4 = Text::Document::NewFromString($data3) ;
它们是多余的。您只是在重新创建相同的(空的)对象。