ready to roll version of newspaper article topic classifier
Thomas Michael Hagen <[email protected]> Wed, 6 May 2009 17:10:57 +0200
| Newsgroups | gmane.mail.spam.crm114 |
|---|---|
| Message-ID | <[email protected]> |
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