Hatena::Groupbugrammer

蟲!虫!蟲!

Esehara Profile Site (by Heroku) / Github / bookable.jp (My Service)
過去の記事一覧はこちら

なにかあったら「えせはら あっと Gmail」まで送って頂ければ幸いです。
株式会社マリーチでは、Pythonやdjango、また自然言語処理を使ったお仕事を探しています

 | 

2013-06-30

[] 人工無能について興味を持ち始める 03:12

始めに

 実は、ちょこちょこと機械学習について調べているのですが、元文系である自分としては、数式であったりとか、アルゴリズムの理解とかが大変な感じで、理解がなかなか追いつかない感じです。

 「機械学習」は、一般的には「人工知能」の分野の一つ、みたいに捉えていますが、その一方で「人工無能」と呼ばれる一連のシステムがあります。

 もちろん、「人工知能」と「人工無能」という概念は、よく調べる限りだと余り対立するわけではなく、どのように、「知能」というものに対してアプローチしていくかという違いになるようです。

 例えば、wikipediaを見てみると、「人工知能」がボトムアップ、つまり普段から人間がやっているような、

トライアンドエラーであったり、フィードバックをしたりしながら、知能を形成していくようにアルゴリズムを組むのに対して、「人工無能」の場合であるならば、「トップダウン」で、「知能というのはこういうものである」というように組んであげるといった違いがある、と言えるのでしょうか。

 最も簡単な「人工無能」の最小単位というものを考えてみましょう。ある出力が入ってきたら、自分が所持する文字列のリストから、ランダムに結果を返すというものだと思います。簡単に、Pythonの場合の実装を考えてみましょう。

# -*- coding: utf-8 -*-
import random


def reply():
    answers = [
        u'ふむふむ',
        u'それで?',
        u'もっと具体的には?',
        u'ちょっと違うと思うな',
        u'別の観点から考えよう',
        u'とてもいい視点だね',
        u'あとは何が足りないかな']
    print answers[random.randint(0, len(answers) - 1)]


def start():
    while 1:
        command = raw_input('>>>')
        reply()
        if command == 'exit':
            break


if __name__ == '__main__':
    start()
    print 'Bye :) .'

 さて、ここで人工無能が突きつける一つの事実があります。それは、人工無能の、この単純なアルゴリズム自体が、順番によって、一瞬だけ「知能がある」という錯覚を私たちに与えてしまうということです。要するに、「知能があるかどうか」ということを、判断しているのは、私たちの側であるということに気がつかされます。

 例えば、文章の場合、人工知能的なアプローチだと、如何に与えられた言葉を解析するのか、という問題が出てきます。いわゆる自然言語処理と呼ばれる分野です。そこから色々なアプローチを使って、重要そうな文章であったり、あるいは、その中からトピックを探し出したり、ということを行なったりします。

 しかし、人工無能の場合、果たして、私たちが入力している文章自体を理解するべきなのかといった問題も含まれて来ます。もちろん、それだけでは何にも使えないので、何かの単語が入っていたならば、という条件であったり、あるいは「こういう文章の並びならこうしろ」というような条件を与えます。

中国人の部屋の問題

 ところで、ジョン・サールという哲学者が、文章を理解することについての思考実験をしています。それを『知能の謎 認知発達ロボティクスの挑戦 (ブルーバックス)』という本から引用してみましょう。

 部屋に閉じ込められたサールは、外部から中国語で書かれた質問カードを与えられる。まったく中国語を知らないサールは、この質問を中国語で応えて外部にカードを出力しなければならない。この部屋には質問に応えるためのたくさんの中国語カードが常備されており(これを常識的知識のデータベースとよんでもよいだろう)、また「こういう中国語記号が来たらこういった中国語のカードを並べよ」などと細かく示されたルールブックもある。ルールブックは英語でかかれているのでサールも読めるとしよう。もしサールがこのルールブックに乗っとってきちんと作業をすれば、外部にいる人は「ここには中国語に堪能な人が入っているに違いない」と思うだろう。だが、サール自信が中国語を理解しているとはいえないのではないか?サールはこの思考実験で、チューリング・テストに合格するような機械であっても「考えている」とはいえないのではないか、と反論したのである。(p.80)

 長くなりましたが、ざっくりとまとめてしまうならば、ここで提起されている問題は、「ルールの束を運用すること」と「理解する」ということには隔たりがあるのではないか、ということです。

 人工知能の場合において、この問題がどのように扱われているのかはわかりませんが、しかし人工無能というのは、むしろ「中国人の部屋」の問題に近い状態です。人工無能の場合は、単なる「ルールの束」を運用しているに過ぎません。ですが、私はむしろ、この「ここには中国語に堪能な人が入っているに違いない」という錯覚のほうが重要のように感じるのです。

 そのことについて、次に書いてみましょう。

問題解決と問題発見

 ちょっとした、人工知能関連の本を読んだ人ならわかる通り、人工知能の最初の関心というのは、問題解決と、それにまつわる検索の問題がまっさきに来ます。人工知能の本っぽく言うならば、「問題の表現」であり、そのために状態空間表現というのが使われます。「問題」は「初期状態」と「目標状態」と「規則」によって定義されます。

 ちょっとややこしいですが、例えば降順ソートのことを考えてみましょう。目の前にランダムに引かれたトランプのカードを、小さい数の順に並べるといったことを考えた場合を考えてみます。

 例えば、カードが[1, 12, 9, 5]という形で渡された場合、これが初期状態になります。目標状態は[1, 5, 9, 12]になるでしょう。この場合は、どちらかというと、一番効率の良い規則を考えることになるかと思われます。

 ソートアルゴリズムに関しては色々とあると思うのですが、ここは一つ、人工無能が持ちうる実装の一つとして、ランダム性というのを取り上げてみようと思います。それは、ネタアルゴリズムとして有名なボゴソートです。

 ボゴソートというのは、初期状態である配列をランダムに並べなおし、それをソートされているかどうかチェックし、もしソートされていないならまた配列をランダムにしなおす、といったようなことをするソートのことで、非常に効率の悪いソートとして良く知られています。下に、サンプルコードを載せておきます。

# -*- coding: utf-8 -*-
import random


def _bogosort(init_array, times):
    work_array = []
    while len(init_array) > 0:
        target_pop = random.randint(0, len(init_array) - 1)
        work_array.append(init_array.pop(target_pop))
    if not check_sorted(work_array):
        return False, work_array, times
    else:
        print "Times: %d" % times
        print work_array
        return True, work_array, times


def bogosort(init_array):
    is_sorted, result, times = _bogosort(init_array, 1)
    while not is_sorted:
        is_sorted, result, times = _bogosort(result, times + 1)
    return times


def check_sorted(check_array):
    previous = None
    for i in check_array:
        if previous is None:
            previous = i
            continue
        if previous > i:
            return False
        previous = i
    return True


if __name__ == "__main__":
    times = []
    for i in range(100):
        times.append(
            bogosort([4, 9, 2, 1, 5, 12]))
    bogosum = sum(times)
    print "Means:"
    print bogosum / len(times)

 このように、ランダム性自体が、問題解決としてはあまりいいものではない、という側面があることが確認できると思います。

 しかし、逆に問題を作る側としてはどうでしょうか?

 例えば、Haskellのテストの方法に、QuickCheckというテスト方法があります。どういうものなのか、については本物のプログラマはHaskellを使う - 第17回 QuickCheckでデータ駆動型テストを行う:ITproを見ていくとして、要するにテストデータをランダムに作成して、それらをデータとして使うわけです。これらの問題をあぶり出していくときには、むしろこういうランダム性のほうが有効であることがあります。

 また、Loguelikeと言われるゲームがあります。有名なところだと、Nethack、あるいは「トルネコの大冒険」ときけばピンと来るでしょう。殆どのゲームに関してはランダムが関わっています。よりよいランダムを実装することによって、問題を作ることには長けている部分があるように感じます*1

 他にも、Twitterの初期のころからマルコフ連鎖を使うことによって、面白い文章を生成するというno titleもあります。マルコフ連鎖が出てくると、少し確率の話も出てくるのですが、このあたりのアルゴリズムの不完全さを利用して、逆にコンテンツを作り出すという部分は面白いかもしれません。

遺伝的アルゴリズムによる突然変異

 とはいえ、人工知能のことに対してランダム性がない、というのはフェアではないでしょう。上記で「問題を解決するさいに〜」という話をしましたが、遺伝的アルゴリズムでは、ランダム性を上手く取り入れています。その部分はどういうところかというと、突然変異の部分です。

 実装したことがないので、詳しいところはよくわからないのですが、解説書を読む限りだと、遺伝子に類似するデータを、選択・交叉していくのが基本なんだそうですが、しかしこれだけだと、もしものときに偏りが生じる可能性が出てくる。なので、たまに突然変異をしてあげることによって、その偏りを無くそうというアプローチだそうです。

 ここはまだ全然勉強していない半端者の想像でしかないのですが、例えばある経路を最適解として実行していた場合、実際の最適解は、実はその実行とは全く違う形をとっていたとき、「ある経路」にいつまでもこだわり続けると、最適解にたどり着くことができない。なので、乱数を与えてあげることによって、その最適解へと飛ぶのだそうです。

まとめ:ランダム性をどのように取り入れるのか

 だんだんまとまりが無くなってきましたし、もう長すぎるので、今日は一度筆を起きたいと思いますが、自分がなぜ「人工無能」に惹かれるのかといえば、上記のように、いわゆる「推論」であったり「解決」であったり「分析」といったような部分ではない、もう少し創造的な関わりとして、人工無能的なアプローチは使えそうなのではないか、というのがするわけです。

 きっかけがあったらアイデアが出てくるのですが、そのきっかけを作るのが案外難しいというのがあります。そのきっかけを作るという意味では、上記の意味でのランダム性という部分に惹かれるわけです。

 このあたりについては、「エキスパートシステム」、つまり専門家の代わりをして、必要な知識を見付け出してユーザーに与えるといったような分野の問題とも絡んでくるのかなあ、とは思うのですが、今日は夜が遅くなりましたので、またの機会に書ければと思います。

*1:ただ、本当にランダムのほうがいいのか。例えば、レベルデザイナーがちゃんと設計したステージのほうが、ランダムで生成されるものよりも満足度が高いという話はあるそうです

ゲスト



トラックバック - http://bugrammer.g.hatena.ne.jp/nisemono_san/20130630
 |