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