PGは電子羊の夢を見るのか?

データとパターンのあいだ

世界金融危機で儲けた男たちを描いた作品「マネーショート」を見てきた。

前から気になっていた「マネーショート 華麗なる大逆転」を見てきました。

www.moneyshort.jp

2007年に起きた世界金融危機の裏側で、アメリカの住宅ローンが破綻することに事前に気がついた投資家たちの考えや戦略、そして低所得者に対してお金を貸す銀行の手口などを交えながら、主人公たちがどのようにして儲けを得たかが描かれている。

原作はマイケル・ルイス作の「世紀の空売り 世界経済の破綻に賭けた男たち」。
この作家は過去に初期のサイバーメトリクスが導入されたメジャーリーグの舞台裏を描いた「マネーボール」で知られている。
今回は世界金融危機の裏側をノンフィクションで描いている。

この映画、予備知識無しで行くと非常に難しい!
所々でちょっとした解説が入るものの、専門用語がかなり出てくるので意味を知っていないとわけがわからない場面もある。
ただ、最終的には「あぁこういうことが原因で金融危機が起こったのね」というのは雰囲気はつかめるようになっている。

この映画で良かったのは、「数字や統計に強くてひらめきのある人が行動することで、世界は変わるんだな」ということが描かれていたところ。
随所で主人公たちがお金の動きを察知し、未来を予測して金融商品を取引し、自分たちの儲けを増やすだけではなく銀行側の不正を暴こうとする。
銀行や金融商品を扱う大きな組織に翻弄されながらも、主人公たちは銀行が創りだした虚構が近いうちに崩壊すると察知し行動していく。
この辺りの駆け引きであったり金融危機を引き起こした引き金に少しずつ迫っていくところは、見ていて面白かった。

いや〜、やっぱりまだまだ数学統計が世界を動かしますかね〜。
世界金融危機自体は2007年辺りに起きた出来事ですが、そこから今までも(むしろ今のほうが)数学や統計の知識が必要だと言われてますね。
最近は「ビッグデータ」「人工知能」なんて言葉がバズってますしね。

というわけで、僕はこれから黙々と数学と統計をやっていこうと思います。
まずは手元に積んである統計関係の本を消化していきます…

フジテレビ「ワイドナショー」って面白いなぁ...

「ワイドナショー」って見てて面白いなぁと思う。

www.fujitv.co.jp

「日曜日はこの番組があるおかげで、朝起きていられる」と言っても過言ではない。

僕はこの番組で気に入っているところは「ツッコミがちゃんと入る」ということ。
ダウンタウン松本人志さんと東野幸治さんがメインなので、まわりのコメントに対して丁寧にツッコミを入れていく。
他の人のコメントを拾ってツッコミ、オチが弱ければ自分たちでボケてツッコミ、膨らませられるようなネタがあればドンドン話が続いていく。 ワイドショー番組だけれど、特定のトピックスを中心としたボケとツッコミの漫才を見ているような気分になれる。

とは言えワイドショー番組なので、扱う題材は政治や経済、エンタメ系と幅広く切り込んでいく。
面白いのが、「過去の出演者の話題を積極的に扱っていくこと」。
今年に入っても覚せい剤所持で逮捕された清原容疑者(逮捕の1週間前にワイドナショーに出演)や、不倫騒動で炎上した乙武さんらの話題も取り扱った。
それぞれに共演していながらも、トピックスとして上がってきた時にはそれぞれの持論を展開。

ワイドナショーとこれまで見てきた他のワイドショーを比較して思うことは、「やっぱりワイドショーのコメンテーターになると当り障りのないことを言い始める人が多いんだな」ということ。
ワイドナショーでは芸人さんやコメンテーターの人が割りとぶっちゃけていっている印象で(そのせいか、番組の発言がYahoo!ニュースによく取り上げられている...)、他のワイドショー番組では聞けないような発言や考え方がよく出てくる。
自分の思っていたことと違う目線での発言も多く、「こんな考え方もあるのかぁ...」と思うことも多い。

あと、B面も面白い。
前園さん、頑張って!

今年の「エンジニア的な学習テーマ」を考える。

本業がエンジニアなので、今年の「エンジニア的な学習テーマ」について考えてみる。

去年を振り返ってみると「自分でWebサービスを1から作れるんかいな?」と思うことが去年度々あった。 もちろん、サーバーの構築だったりデータベースの設計だったりアプリの実装だったり、パーツパーツではやってきた。(実務でも趣味でも。) でも、改めてこれらを組み合わせて「一つのWebサービス」という形でできるのか?と言われると、そういえばやったことないな、と。

じゃあ、やりましょう!

ということで、今年のテーマは「Webサービスを作る」にします。 去年勉強した機械学習も絡めていきたいので、「アップロードされた画像を学習するWebアプリ」を作ってみようと思います。

今週と来週は時間があるので、環境の選定とか言語の選定とかをしようと思います。

AlphaGoとかそれ関連のニュースに関して思うことなど

AlphaGoがプロの囲碁棋士に勝った。 将棋ではすでに人工知能が勝利を収めている。

相変わらず「人工知能」は熱い話題のようで。 ただ、はてブとかQiitaを見ていたら、去年ほど投稿数は伸びていない印象を受ける。 去年はChainerの公開があったりして、特に深層学習系の記事が沢山上がってきていた。

AlphaGoに関しては2016年3月20日のフジテレビ「ワイドナショー」でも取り上げられ、その中での竹俣紅(女流棋士)さんと厚切りジェイソンさんのコメントが印象的だった。 竹俣さんは今回のAlphaGoとプロ囲碁棋士との対戦の結果を受けて「疲れや動揺のない機械に対して、初戦から連敗するという精神的なショックや連日の対戦での疲れという中で4戦目に棋士が勝ったことはとても感動した」とコメントしていて、厚切りジェイソンさんはAlphaGoに対して「やってることは確率の計算、決まったルールの中で有限な手を取り合うゲームであればリソースをかければすべて計算できる」とコメントした。

全くその通りだろう。 確かに今回の結果は「人間の作った囲碁というゲームにおいて、プログラムが人間よりも強くなれる」ということを示した。 ただ、それ自体は将棋やチェスで人工知能が結果を収めた時点でわかっていたことで、ルールの設定を変えて調整を行いこれまでの対局データを学習させれば同種のゲームで同じような結果になる。 コンディションというハンデがある以上、疲れも知らず精神的にブレることのない機械に今後人間が勝利をおさめるのは難しくなってくるだろう。

こういったプログラムがやっていることは「過去の対戦結果を解析し、それを元に今の局面から勝利にたどり着くにはどれを選択すればよいか?」であり、要はデータ解析と確率論。 囲碁や将棋のゲームにおいては、その場面その場面での最善の一手を打ち続けるようになっている。(ゲームの展開に合わせて、どれぐらい深読みするかの調整はあるが。)

というわけなので、プログラマ的な観点から大事なことは「人工知能すごい!」ということではなく、統計やデータ解析やアルゴリズムを組み合わせて「過去の傾向を知り、未来を予測し、その時点での最善の一手を判断する」事ができる実装が書けるかどうか、ということ。

Python3 + Mecabでベイジアンフィルタを実装してみた。

技評さんの過去の機械学習関連の連載の中に「ベイジアンフィルタを実装してみよう」というものがあります。
ちょっとした理由からベイジアンフィルタの実装をしなければいけなくなったので、勉強を兼ねて上記のリンクのものを形態素解析エンジン「MeCab」を使いPython3で書きなおしてみた。(元記事では形態素解析にはYahoo!APIを使用し、Pythonも2.X系で実装されている。)

まず、そもそも「ベイジアンフィルタとは何か?」みたいな話はここでは詳しくはしないけれど、ざっくりと言うと「主観によって変動するベイズ確率を用いたフィルタ」のこと。

早速実装。
環境は以下のとおり。

上記サイトに習って、文章を形態素解析する部分は単独のクラスとして実装。
今回はMeCabを使っているので、「mecabutil.py」としています。

# coding: utf-8
import MeCab

mode = '-Ochasen'
word_classes = ['名詞', '動詞', '形容詞']


def getwords(sentence):
    tagger = MeCab.Tagger(mode)
    tagger.parse('')
    node = tagger.parseToNode(sentence)
    words = []
    while node:
        if node.feature.split(',')[0] in word_classes:
            words.append(node.surface)
        node = node.next

    return words

上2行はおまじないとインポート。

今回は「特定の品詞の単語のみを抽出したい!」と思ったので、単語ごとに品詞を拾ってこれるchasenを採用。 あと、word_classesという配列にほしい品詞を入れておきます。

getwords関数について。 まずはMeCab.Taggerに先ほどのmodeを渡してtaggerを作ります。 その次の行はmecab-python3のバグ対応のため。(参考: python3 + mecabでnode.surfaceが取得できないバグへの対応 - Qiita

tagger.parseToNode()に文章を渡すことで、含まれる単語とその品詞の情報を持ったnodeの一覧を返してくれます。 あとは、これをループで回して含まれるのnodeを一つ一つ確認していく。

node.featureは「名詞,一般,,,,,*」という形式の文字列を持っているので、コンマで分割した時の先頭を見れば品詞が取ってこれます。 これがword_classesに含まれる品詞だった場合には出力となるwordsの中に格納。

最後にnodeを次のnodeへと進めます。 最終的にすべてのnodeを見終わると、node=nullになってwhileループを抜けます。

以上が今回の単語抽出部です。

次に、ベイジアンフィルタ部分。 これは上記リンクとほぼ同じです。(一部バグ修正やリファクタリングあり。)

# coding: utf-8

import math
import sys
import mecabutil


def getwords(doc):
    words = [s.lower() for s in mecabutil.getwords(doc)]
    return tuple(w for w in words)


class NaiveBayes:
    def __init__(self):
        self.vocablaries = set()
        self.wordcount = {}
        self.catcount = {}

    def wordcountup(self, word, cat):
        self.wordcount.setdefault(cat, {})
        self.wordcount[cat].setdefault(word, 0)
        self.wordcount[cat][word] += 1
        self.vocablaries.add(word)

    def catcountup(self, cat):
        self.catcount.setdefault(cat, 0)
        self.catcount[cat] += 1

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

    def priorprob(self, cat):
        return float(self.catcount[cat]) / sum(self.catcount.values())

    def incategory(self, word, cat):
        if word in self.wordcount[cat]:
            return float(self.wordcount[cat][word])
        return 0.0

    def wordprob(self, word, cat):
        return (self.incategory(word, cat) + 1.0) / (sum(self.wordcount[cat].values()) + len(self.vocablaries) * 1.0)

    def score(self, word, cat):
        score = math.log(self.priorprob(cat))
        for w in word:
            score += math.log(self.wordprob(w, cat))
        return score

    def classifier(self, doc):
        best = None
        max = -sys.maxsize
        word = getwords(doc)

        for cat in self.catcount.keys():
            prob = self.score(word, cat)
            if prob > max:
                max = prob
                best = cat
        return best

Python2 -> Python3に変更したけれど、大きな修正はなかったので簡単に移植できました。 こちらの実装内容についてはベイジアンフィルタに関する理解も必要になるので、上記リンクに任せます。 しばらくはデータを突っ込んでみて遊んでみようと思います。

実装リンク

github.com

参考リンク

d.hatena.ne.jp

ブログ名変えました。

僕はこのブログで生きていきます。

機械学習の新しい入門書「データサイエンティスト養成読本 機械学習入門編」

今年一冊目として、「データサイエンティスト養成読本 機械学習入門編」を読了しました!

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

内容としては

といった感じ。機械学習全般について、広く浅く解説している本となっています。

機械学習を全く知らない」「ちょっと興味があってこれから始めてみたい」という人にはオススメ。
機械学習にかぎらず、統計的手法についても紹介されているし、言語もR・Pythonを中心にいろいろ紹介されているので、機械学習のはじめの一歩にはとりあえずこれを読んでおけばいいと思います。

反面、すでに勉強したり実装したりしている人には物足りないかもしれません。
紹介されているライブラリなどもメジャーなものが多く、また実装サンプルも統計手法や推薦システム・画像認識なのでちょっとほかで勉強していたらすでに触れたことのある内容。
あと、深層学習についてはほとんど用語の説明になっているので、この本を読んだからといって理解できるわけではありません。(過度な期待は厳禁です...)

とはいえ、この本は「入門編」となっているので、その意味では十分にいろいろな情報を網羅しているのではないかと思います。
この本を読んで機械学習に興味を持って深掘りするも良し、統計的手法に目覚めてそちらに進むも良し。

僕はちょっと物足りなかったので、機械学習方面をもっと掘り下げていこうと思います!