|
AI::Categorize - Automatically categorize documents based on content |
AI::Categorize::Result MethodsAI::Categorize::Map Methods
AI::Categorize - Automatically categorize documents based on content
### This is one of the categorizers available (see below for more) use AI::Categorize::NaiveBayes; my $c = new AI::Categorize::NaiveBayes();
### Supply some training documents so it can learn how to categorize
$c->stopwords('the','a','and','but','I'); # Ignore these words
$c->add_document($name, \@categories, $content);
... repeat for many documents, then:
$c->crunch();
$c->save_state('filename'); # Save machine for later use
### Categorize a new unknown document
my $c = new AI::Categorize::NaiveBayes();
$c->restore_state('filename');
my $results = $c->categorize($content);
if ($results->in_category('sports')) { ... }
my @cats = $results->categories;
my @scores = $results->scores(@cats);
This module implements several algorithms for automatically guessing category information of documents based on the category information of existing documents. For example, one might categorize incoming email messages in order to place them into existing mailboxes, or one might categorize newspaper articles by general topic (business, sports, etc.). All of the categorizers learn their categorization rules from a body of existing pre-categorized documents.
Disclaimer: the results of any of these algorithms are far from infallible (close to fallible?). Categorization of documents is often a difficult task even for humans well-trained in the particular domain of knowledge, and there are many things a human would consider that none of these algorithms consider. These are only statistical tests - at best they are neat tricks or helpful assistants, and at worst they are totally unreliable. If you plan to use this module for anything important, human supervision is essential.
But this voodoo can be quite fun. =)
Currently two different algorithms are implemented in this bundle:
AI::Categorize::NaiveBayes AI::Categorize::kNN
These are all subclasses of AI::Categorize. Please see the
documentation of these individual modules for more details on their
guts and quirks. The common interface for all the algorithms is
described here.
All these classes are designed to be subclassible so you can modify their behavior to suit your needs.
new()$c).
The arguments to new() will depend on which subclass of
AI::Categorize you happen to be using. See the subclasses'
individual documentation for more info.
stopwords()stopwords(@words)The stoplist should be set before processing any documents.
stopwords_hash()add_stopword($word)$name should be a
unique string identifying this document. $categories may be either
the name of a single category to which this document belongs, or a
reference to an array containing the names of several categories.
$content is the text content of the document.
To ease syntax, in the future $content may be allowed
to be given as a path to the document, which will be opened and parsed.
crunch()crunch() so that the
categorizer can compute some statistics on the training data and get
ready to categorize new documents.
categorize($content)$content and returns an object blessed into
the AI::Categorize::Result class.
To ease memory requirements, in the future $content may be allowed
to be passed as a filehandle.
cat_map()AI::Categorize::Map. See the documentation for this class below.
save_state($filename)restore_state() method.
restore_state($filename)save_state() method.
@assigned_categories, 5 entries in @correct_categories, 2 of
those catagories overlap, and there are a total of 20 categories to
choose from, then the error is (2+3)/20 = 5/20 = 0.25. In this
case, 2 errors of false assignment were made, and 3 errors of
omission were made.
The accuracy and error will always have a sum of 1.
@assigned_categories, 5 entries in @correct_categories, 2 of
those catagories overlap, and there are a total of 20 categories to
choose from, then the accuracy is (2+13)/20 = 15/20 = 0.75. In
this case, 2 correct assignments were made, and 13 categories were
correctly omitted.
The accuracy and error will always have a sum of 1.
In other words, if A is the set of categories that were assigned by the system, C is the set of categories that should have been assigned by the system, and I is the intersection of A and C, then
2*I
F1 = -------
A + C
(Other sources may define F1 as 2*recall*precision/(recall+precision),
which is equivalent to the above formula but forces division by zero
if either A or C is empty.)
A perfect job categorizing (all correct categories were assigned and no extras were assigned) will have an F1 score of 1. A terrible job categorizing (no overlap between correct & assigned categories) will have an F1 score of 0. Medium jobs will be somewhere in between.
I/A, where
A is the number of elements in @assigned_categories, and I is
the number of elements in the intersection of @assigned_categories
and @correct_categories.
If your categorizer is being too strict, i.e. assigning fewer categories than it should be, then the precision will be significantly higher than the recall.
I/C, where
C is the number of elements in @correct_categories, and I is
the number of elements in the intersection of @assigned_categories
and @correct_categories.
If your categorizer is being too lenient, i.e. assigning more categories than it should be, then the recall will be significantly higher than the precision.
extract_words($text)$text and whose values are the number of times each word appears.
Stopwords are omitted and words are put into canonical form
(lower-cased, leading & trailing non-word characters stripped).
Don't call this method directly, as it is used internally by the
various categorization modules. However, you may be interested in
subclassing one of the modules and overriding extract_words() to
behave differently. For instance, you may want to ``lemmatize'' your
words to remove affixes so that ``abominable'', ``abominableness'',
``abominably'', ``abominate'', ``abomination'', and ``abominator'' all share a
single entry in the categorizer.
AI::Categorize::Result MethodsAn AI::Categorize::Result object (hereafter abbreviated as $r) is returned by the
$c->categorize method, described above.
in_category($category)categories()scores(@categories)Please consider the scoring feature somewhat unstable for now.
AI::Categorize::Map MethodsThe AI::Categorize::Map class manages the relationships between
documents and categories. It is designed to support fast lookups
either by category or by document. An AI::Categorize::Map object
is returned by the $c->cat_map method (described above) and
will be called $m for convenience in this documentation.
In general, feel free to make any queries of the map, but don't make any changes to its data. Changes should usually only be made through the categorizer object.
AI::Categorize add_document() method calls this
internally.
categories()documents()categories_of($doc_name)$doc_name belongs to in a list
context, or the number of such categories in a scalar context.
documents_of($cat_name)$cat_name contains in a list
context, or the number of such documents in a scalar context.
$doc_name belongs to the $cat_name category, or
false otherwise.
$cat_name contains the document $doc_name, or
false otherwise. Note that this is just a synonym for the
is_in_category() method with the names turned around.
Don't depend on the specific scores given by $r->scores. They
may change in future releases.
The entire categorizer is currently created in memory, which can get pretty demanding if you have a lot of data. If this turns out to be a problem, future versions may try to cache large chunks on disk. This would come with a speed penalty.
Finally, I am not an expert in document categorization. I have thought about it some, and I have written these modules largely as a way to concretize my thinking and learn more about the processes. If you know of ways to improve accuracy, please let me know.
Idea from obvy: try tying into infobot (purl) to identify IRC moods: @moods = qw(indifferent flame_mode pissed inebriated happy sad)
Ken Williams, ken@forum.swarthmore.edu
Copyright 2000-2001 Ken Williams. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
perl(1), DBI(3).
``A re-examination of text categorization methods'' by Yiming Yang http://www.cs.cmu.edu/~yiming/publications.html
Other links from Na'im Tyson:
www.ruf.rice.edu/~barlow/corpus.html (corp. lx.) ciir.cs.umass.edu (info. ret) www.georgetown.edu/wilson/IR/IR.html (class in IR @ Georgetown University) www.research.att.com/~lewis (professional homepage of David Lews, one of the leaders in document categorization. you may want to visit his site sooner than the others since he has left AT&T research.)
|
AI::Categorize - Automatically categorize documents based on content |