You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2007/03/05 14:09:49 UTC
svn commit: r514663 - /spamassassin/trunk/masses/rule-dev/seek-phrases-in-log
Author: jm
Date: Mon Mar 5 05:09:48 2007
New Revision: 514663
URL: http://svn.apache.org/viewvc?view=rev&rev=514663
Log:
optimisations; no need to do a lot of the work performed for the ham case
Modified:
spamassassin/trunk/masses/rule-dev/seek-phrases-in-log
Modified: spamassassin/trunk/masses/rule-dev/seek-phrases-in-log
URL: http://svn.apache.org/viewvc/spamassassin/trunk/masses/rule-dev/seek-phrases-in-log?view=diff&rev=514663&r1=514662&r2=514663
==============================================================================
--- spamassassin/trunk/masses/rule-dev/seek-phrases-in-log (original)
+++ spamassassin/trunk/masses/rule-dev/seek-phrases-in-log Mon Mar 5 05:09:48 2007
@@ -2,7 +2,7 @@
=head1 NAME
-phrase-extract-in-log - extract good-looking rule phrases from a text-dump mc log
+seek-phrases-in-log - extract good-looking rules from a text-dump mc log
=cut
@@ -50,34 +50,35 @@
warn "reading $fs...\n";
open IN, "<$fs" or die "cannot open spam log $fs";
while (<IN>) {
- /^text: (.*)$/ and proc_text(1, $1);
+ /^text: (.*)$/ and proc_text_spam($1);
}
close IN;
+warn "n-grams active: ".(scalar keys %ngram_count)."\n";
warn "reading $fh...\n";
open IN, "<$fh" or die "cannot open ham log $fh";
while (<IN>) {
- /^text: (.*)$/ and proc_text(0, $1);
+ /^text: (.*)$/ and proc_text_ham($1);
}
close IN;
+warn "n-grams active: ".(scalar keys %ngram_count)."\n";
-%word2sym = (); # free this, no longer needed
+undef %word2sym; # free this, no longer needed
summarise();
exit;
-sub proc_text {
- my ($adding, $text) = @_;
+sub proc_text_spam {
+ my ($text) = @_;
+ # we only need to chop off the end of spam samples
if (length($text) > $MAX_TEXT_IN_MESSAGE) {
$text = substr $text, 0, $MAX_TEXT_IN_MESSAGE; # chop!
}
# we only need to save spam samples in memory, ignore ham samples
- if ($adding) {
- push @text_string, $text;
- }
+ push @text_string, $text;
my $cp = pack "l", $msgcount;
$msgcount++;
@@ -103,20 +104,52 @@
# simple bayesian N-grams to start
$tokens{"$w3.$w2.$w1"} = $tokens{"$w3.$w2"} = 1;
}
+
+ # deal with leftovers
+ if ($w2 && $w1) {
+ $tokens{"$w2.$w1"} = 1;
+ }
foreach my $tok (keys %tokens) {
- if ($adding) {
- # incr the counter for this token
- $ngram_count{$tok}++;
- $msg_subset_hit{$tok} .= $cp; # the message subset hit by this tok
-
- } else {
- # we're not tracking hits; we're killing false positives.
- # as soon as a single FP appears, kill all record of that token,
- # it cannot be used
- delete $ngram_count{$tok};
- delete $msg_subset_hit{$tok};
+ # incr the counter for this token
+ $ngram_count{$tok}++;
+ $msg_subset_hit{$tok} .= $cp; # the message subset hit by this tok
+ }
+}
+
+sub proc_text_ham {
+ my ($text) = @_;
+
+ my $w1 = '';
+ my $w2 = '';
+ my $w3 = '';
+
+ my %tokens = ();
+ foreach my $w (split(' ', $text)) {
+ $w3 = $w2;
+ $w2 = $w1;
+
+ $w1 = $word2sym{$w};
+ if (!$w1) {
+ # since we're deleting, there's no need to add new words
+ # to the dictionary; just use the final $sym_acc to mean
+ # "unknown ham word", and don't increment it
+ $word2sym{$w} = $w1 = $sym_acc;
}
+
+ $tokens{"$w3.$w2.$w1"} = $tokens{"$w3.$w2"} = 1;
+ }
+
+ if ($w2 && $w1) {
+ $tokens{"$w2.$w1"} = 1;
+ }
+
+ foreach my $tok (keys %tokens) {
+ # we're not tracking hits; we're killing false positives.
+ # as soon as a single FP appears, kill all record of that token,
+ # it cannot be used
+ delete $ngram_count{$tok};
+ delete $msg_subset_hit{$tok};
}
}
@@ -160,9 +193,12 @@
push @{$all_patterns_for_set{$set}}, decode_sym2words($id);
}
+ warn "message subsets found: ".(scalar keys %all_patterns_for_set)."\n";
+
my %done_set = ();
printf ("%6s %6s %6s %s\n", "RATIO", "SPAM%", "HAM%", "DATA");
+ $| = 1;
foreach my $id (sort {
$ngram_count{$a} <=> $ngram_count{$b}
} keys %ngram_count)
@@ -184,12 +220,15 @@
sub decode_sym2words {
my $ids = shift;
my $r;
- if ($ids =~ /^(.*)\.(.*)\.(.*)$/) {
+ if ($ids =~ /^([^.]*)\.([^.]*)\.([^.]*)$/) {
$r = "$sym2word{$1} $sym2word{$2} $sym2word{$3}";
}
- elsif ($ids =~ /^(.*)\.(.*)$/) {
+ elsif ($ids =~ /^([^.]*)\.([^.]*)$/) {
$r = "$sym2word{$1} $sym2word{$2}";
}
+ else {
+ warn "bad decode_sym2words format: '$ids'";
+ }
$r =~ s/^\s+//;
return $r;
}
@@ -217,7 +256,7 @@
}
# we don't have all day!
- my $pat_maxlen = 32768;
+ my $pat_maxlen = $MAX_TEXT_IN_MESSAGE;
my $s = $hits[0];
# Now, expand the pattern using a BLAST-style algorithm
@@ -228,11 +267,7 @@
last if ($l > $pat_maxlen); # too long
my $found;
- # this is too slow
if ($s =~ /(.)\Q$pat\E/s) { $found = $1; }
-
- # this is faster, since it doesn't start with a (.)
- # if ($s =~ /\Q$pat\E/s) { $found = substr($s, pos($s) - $l, 1); }
if (!defined $found) {
# start of string. break