Re: ready to roll version of newspaper article topic classifier
Thomas Michael Hagen <[email protected]> Wed, 6 May 2009 17:50:20 +0200
| Newsgroups | gmane.mail.spam.crm114 |
|---|---|
| Message-ID | <[email protected]> |
a small correction (i made a last minute change without testing it
before posting):
the last section in the main function, the one that looks like this:
{
eval /:@::*:count: > 0:/
liaf
}
alius
{
output /Didn't improve enough; reinforcing your answer...\n/
call /:refute:/ [:*:refute-args:]
}
return /:*:user-feedback:/
will of course make the liaf statement enter an infinite loop.
it should look something like this:
eval (:count:) /:@::*:count: - 1:/
eval /:@::*:count: > 0:/
liaf
}
output /Didn't improve enough; reinforcing your answer...\n/
call /:refute:/ [:*:refute-args:]
}
return /:*:user-feedback:/
but really, i'm not even sure i should put refute in there - that
would mean refutation every time the classifier never gets confident.
perhaps that is too brutal.
On Wed, May 6, 2009 at 5:10 PM, Thomas Michael Hagen
<[email protected]> wrote:
> i'm on my fifth version now, after a lot of work, and a lot of
> valuable input from this list.
>
> eight people in my department are now going to train the classifier by
> categorizing about a thousand articles each.
>
> here is the core of the program they are using:
>
> i hope this can be of use to some, and i always love harsh feedback :)
>
>
> :try-to-classify: (:article:)
> {
> #THE CLASSIFICATION HALF:
> {
> {
> isolate (:stats:)
> classify <osbf microgroom> [:article:] \
> (bus.cfc cli.cfc con.cfc cul.cfc dom.cfc \
> eco.cfc edu.cfc ene.cfc ent.cfc env.cfc \
> for.cfc hea.cfc loc.cfc pol.cfc sci.cfc \
> spo.cfc tec.cfc tra.cfc wor.cfc | unc.cfc out.cfc) (:stats:)
> match (:: :class-conc:) [:stats:] /(...)\.cfc/ #perhaps pick the
> top 3 cats, and tag article with all 3 (if above some threshold)
> { #classify succeeded, checking pR:
> match (:: :pR:) [:stats:] /Best match.*: (.*) \nTotal/
> output /pR::*:pR:. /
> eval /:@::*:pR: > 30:/ #play around with this number
> output /Classify succeeded as ':*:class-conc:'\n/
> return
> }
> output /Classification NOT confident! Please classify:\n\n/
> }
> alius
> {
> output /Classify failed! Please classify:\n\n/
> }
> }
> #compare a low conf answer with the result of try-to-learn here,
> and use it if they are the same
> isolate (:conc-file:) /:*:class-conc:.cfc/
> isolate (:interaction:) /:*:class-conc::*:article::*:stats:/
> call /:interact:/ [:*:interaction:] #asking the user for the right topic
> { #if the answer was right, use that answer, and refute fram all
> other categories:
> match [:user-feedback:] /^y$/
> isolate (:user-feedback:) /:*:class-conc:/
> isolate (:refute-args:) /:*:conc-file::*:article:/
> call /:refute:/ [:*:refute-args:]
> }
> #THE LEARNING HALF:
> isolate (:user-feedback-conc-file:) /:*:user-feedback:.cfc/
> isolate (:count:) /7/
> isolate (:print-p:) /1/
> { # entering the training loop
> learn <osbf microgroom> (:*:user-feedback-conc-file:) [:article:]
> {
> match [:print-p:] /1/
> output /\nLearning as :*:user-feedback-conc-file:...\n/
> isolate (:print-p:) /0/
> }
> isolate (:stats2:)
> { #reclassifying to check improvement:
> classify <osbf microgroom> [:article:] \
> (bus.cfc cli.cfc con.cfc cul.cfc dom.cfc \
> eco.cfc edu.cfc ene.cfc ent.cfc env.cfc \
> for.cfc hea.cfc loc.cfc pol.cfc sci.cfc \
> spo.cfc tec.cfc tra.cfc wor.cfc | unc.cfc out.cfc) (:stats2:)
> isolate (:pR2:) #here, you assume it ends up with the same cat as
> before. what if it doesn't?
> match (:: :pR2:) [:stats2:] /Best match.*: (.*) \nTotal/
> isolate (:improvement:)
> eval (:improvement:) /:@:(:*:pR2: - :*:pR:):/
> output /imp::*:improvement:\n/
> eval /:@::*:improvement: > 3:/
> eval /:@::*:pR2: > 10:/ #play around with this number too
> output /Succesfully learned! Moving on\n/
> return
> }
> eval (:count:) /:@::*:count: - 1:/
> {
> eval /:@::*:count: > 0:/
> liaf
> }
> alius
> {
> output /Didn't improve enough; reinforcing your answer...\n/
> call /:refute:/ [:*:refute-args:]
> }
> }
> return /:*:user-feedback:/
> }
>
> insert interact.crm
>
> :refute: (:aargh:) # here, we train OUT of all the incorrect classes
> {
> output /Reinforcing correct answer...\n/
> {
> match (:: :conc-ffile: :aarticle:) [:aargh:] /(...\.cfc)(.*)/
> isolate (:cfc-files:) /bus.cfc cli.cfc con.cfc cul.cfc dom.cfc
> eco.cfc edu.cfc ene.cfc ent.cfc env.cfc for.cfc hea.cfc loc.cfc
> pol.cfc sci.cfc spo.cfc tec.cfc tra.cfc wor.cfc unc.cfc out.cfc /
> { #first instance:
> match (:: :cfc-file:) /(.*?\.cfc) / [:cfc-files:]
> {
> match <absent> /:*:conc-ffile:/ [:cfc-file:]
> learn <osbf microgroom refute> (:*:cfc-file:) [:aarticle:]
> }
> { #next instances:
> match <fromnext> (:: :cfc-file:) /(.*?\.cfc) / [:cfc-files:]
> {
> match <absent> /:*:conc-ffile:/ [:cfc-file:]
> learn <osbf microgroom refute> (:*:cfc-file:) [:aarticle:]
> }
> liaf
> }
> }
> return
> }
> output /Match missed in refute!\n/
> return
> }
>
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled. http://p.sf.net/sfu/kodak-com