こんにちは。暑いですがみなさんどうお過ごしでしょうか。 tanaka-m です。 投稿一発目は「Gスボット」です。 オープンソースの形態素解析エンジン「MeCab」を利用して、 チャンネルの発言に関係のある名ゼリフを返答します。 ・MeCab http://mecab.sourceforge.net/
============================================== 形態素解析エンジンとは(Wikipedia) 対象言語の文法の知識や辞書を情報源として用い、自然言語で書かれた文を形態素の 列に分割し、それぞれの品詞を判別する作業を指す。(ナンノコッチャ) 例) すもももももももものうち 以下のようなアウトプットになります。 すもも  名詞,一般,*,*,*,*,すもも,スモモ,スモモ も      助詞,係助詞,*,*,*,*,も,モ,モ もも    名詞,一般,*,*,*,*,もも,モモ,モモ も      助詞,係助詞,*,*,*,*,も,モ,モ もも    名詞,一般,*,*,*,*,もも,モモ,モモ の      助詞,連体化,*,*,*,*,の,ノ,ノ うち    名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
ブログのタギングなどに利用できるのではないかと言われています。 ==============================================
各発言に対して分析を行い、関連のある文章をひっぱってくるようにさせ、 絶妙な脱力感を醸し出します。
イメージ↓ (Aさん) 豚が食べたい。 (bot)    飛べない豚はただの豚だぜ。 昨日から社内のチャンネルにて放し飼いにしてますが、 いかにして「空気を読まない奴の発言」的に見せるかは実装する人の工夫次第のよう です。(※今はただ脈絡のない発言にしか見えない) このbotのいいところは、データを用意すればジャンルを自由に入れ替えられることです。 同じソースで「ドラゴン●ールbot」「セーラー●ーンbot」も動くわけですね。
今回は初Pythonで実装しました。(ワッショーイ) 以下、ソース (1)名ゼリフを単語に紐付けてDBに登録する
#!/usr/bin/python
# coding: utf-8

import MeCab
import sys
import string
import re
import MySQLdb

file = sys.argv[1]
print file
connect = MySQLdb.connect(db="irc_db", host="127.0.0.1", port=3306, user="root", passwd="password")
cur = connect.cursor()
cur.execute("truncate table sentence;")

for line in open(file):
    value = line.split(' - ')
    msg = value[0]
    print msg
    
    t = MeCab.Tagger ()
    m = t.parseToNode (msg)
    cnt = 0
    while m:
        print m.surface, "\t", m.feature
        if m.surface.find('BOS/EOS') >= 0 or len(m.surface) == 0:
            m = m.next
            continue
        feat = m.feature
        arr = feat.split(',')
        gram = arr[0] #品詞
        word = arr[6] #原形
        if gram in ('名詞', '動詞', '形容詞'):
            print gram, word
            cur.execute("insert into sentence values(NULL, '"+ gram +"', '"+ word +"', '" + msg +"');")
     
        cnt = cnt + 1
        m = m.next
        
connect.commit();
cur.close()
connect.close()
(2)IRCの発言から関連するセリフを選び出す
while (1):
    buffer = IRC.recv(1024)
    print buffer
    msg = string.split(buffer)
    if msg[0] == "PING": 
        send_data("PONG %s" % msg[1]) 
    if msg [1] == 'PRIVMSG':
        
        nick_name = msg[0][:string.find(msg[0],"!")] 
        message = ' '.join(msg[3:])

        print message
        if message == ':stop '+NICKNAME:
            print 'stopping..'
            send_data("QUIT ")
            break            
        
        #毎回出るとウザいので5回に1回
        luck = random.randint(0, 5)
        if luck != 1:
            continue
        
        message = unicode(message, 'iso-2022-jp').encode('utf-8')
        print 'encoded:'
        print message
        t = MeCab.Tagger ()
        m = t.parseToNode (message)
        
        alist = []
        while m:
            print m.surface, "\t", m.feature
            if m.surface.find('BOS/EOS') >= 0 or len(m.surface) == 0:
                m = m.next
                continue
            feat = m.feature
            arr = feat.split(',')
            gram = arr[0] #品詞
            word = arr[6] #原形
            if gram in ('名詞', '動詞', '形容詞') and word != '*':
                print gram, word
                arr = {'gram':gram, 'word':word}
                alist.append(arr)
            m = m.next

        print alist
        if len(alist) > 0:
            connect = MySQLdb.connect(db="irc_db", host="127.0.0.1", port=3306, user="root", passwd="password")
            cur = connect.cursor()

            where = ' (1 = 2) '
            for arr in alist:
                where = where + " OR ( word ='" + arr['word'] + "' AND gram ='" + arr['gram'] + "')"

            print where
            cur.execute('select * from sentence where' + where)
            rows = cur.fetchall()
            for row in rows:
                print row[3]
            cur.close()
            connect.close()
                
            if len(rows) > 0:
                idx = random.randint(0, len(rows) - 1)
                send_data("PRIVMSG " + CHANNEL +" :" + unicode(rows[idx][3], 'utf-8').encode('iso-2022-jp'))

夏バテに負けずにがんばっていきましょう!!