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) ;

它们是多余的。您只是在重新创建相同的(空的)对象。