[機械学習で推奨タグ付け #4]　機械学習のスクリプト・・・？

#\<ENGLISH>

Hi, I hope you're doing well. 
I'm so sleepy... because gym activities in morning time. But I'd like to resume my process ... with drink :stuck_out_tongue_closed_eyes: yahoo!

So today's topic is finally ... machine learning! we already got necessary elements for learning ant test, so only what I have to do, train my machine!
Start ... but I have to say one thing before starting. 

**I can't do coding of Machine Learning...!**

Really sorry, oh, stop!! don't through a stone in you hand ... yep, light. I don't make it actually I can't. 
Instead, I'd like to use script from another site. And I think you know it. Here. 
[機械学習 はじめよう 第3回　ベイジアンフィルタを実装してみよう - gihyo.jp](http://gihyo.jp/dev/serial/01/machine-learning/0003)
This is very good site for learning Machine Learning as entrance. I really recommend it. 

So today, that's call it for today... ? Humm. Actually I have to change some points to apply to my purpose. I'd like to show some change how I can change it. Nothing of machine learning today... 

    def train(self, doc, cat):
    word = getwords(doc)
    for w in word:
        self.wordcountup(w, cat)
    self.catcountup(cat)

This is train function: Got words in doc then cat value amounts are counted up for the words. However this is only for one category by one web content. However there are two or upper category will also be tagged for one web content. So I changed the script like this. 

    def train(self, doc, cats):
    word = getwords(doc)
    for w in word:
        for cat in cats:
            self.wordcountup(w, cat)
            self.catcountup(cat)

Use cats value as list. Not single string. using for to count up each category by words. 

Next is to modifying the result showing. Original script is like this. 

    
    def classifier(self, doc):
        best = None
        max = -sys.maxint
        word = getwords(doc)
    
        for cat in self.catcount.keys():
            prob = self.score(word, cat)
            if prob < max:
                max = prob
                best = cat
        return best

This function returns the best category name. However I'd like to show all category and probability. So I modified like this. 

    def classifier(self, doc):
        best = None
        max = -sys.maxint
        word = getwords(doc)
        pList = []
        
        for cat in self.catcount.keys():
            prob = math.exp(self.score(word, cat))
            pList.append([cat, self.score(word, cat)]) 

        return sorted( pList, key=lambda prob: prob[1], reverse=True)


Previous code, just return maximum probably tag. But I'd like to know all tag's result. so return the list. 

The engine of machine language is just using other person's idea... Next I'd like to show you the result of the machine learning and consideration. 


#<日本語>
どうもどうも、梅村です。

いつもビール一缶あおってから文章書いています。ほろよいがちょうどよいんす。

では、きょうはとうとう機械学習の本丸にいきます。いやー、ここまでお待ちいただいて申しわけないです。とうとうはじまりますよー。いやはや。。ひとつ謝りたいことがあります。

**今回は機械学習のコーディングはいたしません！**

いや、やめて、石投げないで！　・・・　そうなんです。やりません。というかできません。代わりに機械学習以下のサイトのネイティブベイズのサンプルコードを流用いたします。

[機械学習 はじめよう 第3回　ベイジアンフィルタを実装してみよう - gihyo.jp](http://gihyo.jp/dev/serial/01/machine-learning/0003)

この記事とシリーズはとても勉強になります。実は私もこの記事をとっかかりにして機械学習をはじめました。高校数学の確率、代数計算、微分の知識を一回思い出せればだれでも機械学習に取り組むことができる、とても丁寧なつくりになっています。

では、本日の内容がおわってしまいました。。。それでは！
と、いうのも寂しいので今日はこのネイティブベイズのコードをどのように改変したのかのご紹介をしたいとおもいます。
まずは以下の部分。

    def train(self, doc, cat):
    word = getwords(doc)
    for w in word:
        self.wordcountup(w, cat)
    self.catcountup(cat)

ここで、docは学習をする文章、catは当てはめるタグなのですがオリジナルは一つの文章に一つのタグしかつけられない形になっています。ただ、今回は複数のタグ付けをすることができるのでcatをcatsにしてタグのリストを入れられるようにします。

    def train(self, doc, cats):
    word = getwords(doc)
    for w in word:
        for cat in cats:
            self.wordcountup(w, cat)
            self.catcountup(cat)

それにあわせてリストのなかのタグひとつひとつの出現カウントをアップさせておりやす。

そして次。推定の判定結果の見せ方ですが、オリジナルのスクリプトはただ、一番確率が高かったタグを返すようにしています。
    
    def classifier(self, doc):
        best = None
        max = -sys.maxint
        word = getwords(doc)
    
        for cat in self.catcount.keys():
            prob = self.score(word, cat)
            if prob < max:
                max = prob
                best = cat
        return best

それだけだと考察のネタが少ないので、すべてのタグとその確率（実際は対数値）を返すようにします。確率高い順に並び替えてます。

    def classifier(self, doc):
        best = None
        max = -sys.maxint
        word = getwords(doc)
        pList = []
        
        for cat in self.catcount.keys():
            prob = math.exp(self.score(word, cat))
            pList.append([cat, self.score(word, cat)]) 

        return sorted( pList, key=lambda prob: prob[1], reverse=True)


はてさて、本日は機械学習のスクリプト・・・をご紹介させていただきました。次回はこのスクリプトを使って学習をさせて、その結果をお見せしたいと思います。そしてその結果についていろいろ考察をしていきたいと思います。

それではまた、お元気で！