1

私は、書いている Web クローラーの感情分類を試しています (少なくともクローラーに関する限り、車輪の再発明について私に尋ねないでください!)。私は現在、Naive Bayes の使用を検討しています。これは主に、簡単にするための perl モジュールが存在するためです。ただし、映画のレビューの良し悪しを判断するためのテスト ケースの設定に少し問題があります。

私が理解しているように、まず、モジュールがトレーニングする一連のテスト データを用意する必要があります。私は映画をレビューするいくつかの Web サイトにアクセスし、12 の悪いレビューと 12 の良いレビューをダウンロードしました。各ファイルを読み込んで単語リストを生成し、それを単語頻度のハッシュに変換します。次に、一連の「不明な」レビューに対して同じ処理を行います (感情は多かれ少なかれ知っていますが) が、問題が発生しており、これについて間違った方法で行っているかどうかはわかりません!

テスト出力は次のとおりです。

*** Processing good reviews
Reading set/good/anniehall.txt
Reading set/good/biglebowski.txt
Reading set/good/contact.txt
Reading set/good/eternalsunshine.txt
Reading set/good/harakiri.txt
Reading set/good/killing.txt
Reading set/good/lincoln.txt
Reading set/good/mulhollanddr.txt
Reading set/good/narayama.txt
Reading set/good/scarface.txt
Reading set/good/seven.txt
Reading set/good/shoah.txt
Reading set/good/spiritedaway.txt
*** Processing bad reviews
Reading set/bad/battlefieldearth.txt
Reading set/bad/charliesangels.txt
Reading set/bad/deathsmootchy.txt
Reading set/bad/deucebigaloweuro.txt
Reading set/bad/freddyfingered.txt
Reading set/bad/humancentipede.txt
Reading set/bad/jasonx.txt
Reading set/bad/north.txt
Reading set/bad/pootietang.txt
Reading set/bad/residentevilapocalypse.txt
Reading set/bad/savingsilverman.txt
Reading set/bad/slackers.txt
Reading set/bad/texaschainsaw.txt
*** Predicting unknown reviews
set/unknown/benjaminbutton.txt: $VAR1 = {
          'bad' => '1.06973342245912e-68',
          'good' => '1'
        };
set/unknown/epic.txt: $VAR1 = {
          'good' => '1',
          'bad' => '7.2271232924459e-35'
        };
set/unknown/hangoverpart3.txt: $VAR1 = {
          'good' => '1',
          'bad' => '1.08569835047604e-17'
        };
set/unknown/jacobsladder.txt: $VAR1 = {
          'good' => '1',
          'bad' => '9.31582505503138e-60'
        };
set/unknown/marleyme.txt: $VAR1 = {
          'good' => '1',
          'bad' => '5.57603799052706e-26'
        };
set/unknown/quantumofsolace.txt: $VAR1 = {
          'bad' => '2.40424666202666e-27',
          'good' => '1'
        };
set/unknown/thespirit.txt: $VAR1 = {
          'bad' => '2.47177895177767e-19',
          'good' => '1'
        };
set/unknown/twilight.txt: $VAR1 = {
          'good' => '1',
          'bad' => '9.77187340648713e-62'
        };

常に未知のデータを「良い」とマークするようです!

これはプログラム自体です:

use 5.010;
use strict;
use warnings;
use utf8;
use Data::Dumper;

BEGIN { push @INC, "../lib"; }
use Algorithm::NaiveBayes;

my $nb = Algorithm::NaiveBayes->new;

# For each file in each directory, retrieve a hash with each key being a
# unique word, and each value the associated frequency of that word.

# Start with scanning good reviews directory
say "*** Processing good reviews";
my @files = <set/good/*>;
foreach (@files) {
    next if ($_ =~ m/^\./); # ignore files beginning with .
    say "Reading $_";
    my %attr = hash_file($_);
    $nb->add_instance ( attributes => \%attr, label => 'good');
}

# Then scan bad reviews
say "*** Processing bad reviews";
@files = <set/bad/*>;
foreach (@files) {
    next if ($_ =~ m/^\./); # ignore files beginning with .
    say "Reading $_";
    my %attr = hash_file($_);
    $nb->add_instance ( attributes => \%attr, label => 'bad');
}

# Train, and cross fingers
$nb->train;

# Test unknown reviews
say "*** Predicting unknown reviews";
@files = <set/unknown/*>;
foreach (@files) {
    next if ($_ =~ m/^\./); # ignore files beginning with .
    print "$_: ";
    my %attr = hash_file($_);
    my $result = $nb->predict(attributes => \%attr);
    print Dumper($result);
}


# Subroutine that takes a file path and returns a hash of the word frequencies
sub hash_file {
    my ($file) = @_;
    my %words;

    my @word_list;
    open FILE, $file or die $!;
    while(<FILE>){
        chomp;
        push @word_list, split;
    }
    close FILE;

    foreach (@word_list){
        $_ =~ s/[[:punct:]]//g; # Remove punctuation
        next if ($_ eq '');

        # Increment frequency if word is in hash, or add to hash
        if (exists $words{$_} ){
            $words{$_}++;
        } else {
            $words{$_} = 1;
        }

    }
    return %words;
}

そのコードに明らかなエラーがあることを願っていますが、ハッシュ サブルーチンをチェックしたところ、正しいハッシュが出力されているようです。他に考えられる唯一のことは、トレーニングに十分なデータを使用していない可能性があるということです。私のアプローチ全体が間違っているのでしょうか?

洞察をありがとう

4

0 に答える 0