自然非言語処理第1日目: はじめに


はじめに

みなさんは、友達と出会ったら、「おはよう」と言いながら手をあげたり、職場の人に会ったら、「お疲れ様です」と言いながら会釈したりした経験はないでしょうか。

人と人と出会う時、そこにはコミュニケーションが生まれます
コミュニケーションとはありふれたものですが、振り返って考えてみるとなんなのでしょうか。

広辞苑から引いてみると、
コミュニケーションとは、

社会生活を営む人間の間で行われる知覚・感情・思考の伝達

とあります。

なんかいまいちピンと来るようなピンとこないような説明です。
コミュニケーションという概念は、短い言葉で表現するのは難しい概念だと思われます。
そこで、本記事では、コミュニケーションを少しずつ分解していきながら
このアドベントカレンダーの本題である自然非言語処理について考えていきたいと思います。

人対人のコミュニケーション

コミュニケーションといえば、2人以上の人がいないと成り立たないような気がします。
たとえば、冒頭にあったやりとりでも自分と相手がいなければなりたちませんでした。
そこで本記事ではコミュニケーションの最小単位である人と人の例を考えていきましょう。
これまでの研究によると、人と人とのコミュニケーションには、「おはよう」といった言語的コミュニケーションと、手をあげるといった非言語コミュニケーション ( Non-verval communicaiton) に大別されることが分かっています。

しかし、コミュニケーションとは人と人との間でしか成り立たないのでしょうか。
私はかつてねこをかっていましたが、喉元をなでたら喜びますし、なき真似をするとねこも鳴いてくれます。そうすると、人と動物でもコミュニケーションは成り立つような気がします。しかも、言語でコミュニケーションしているわけでもないので、非言語コミュニケーションが成り立っています。

さて、人と動物でもなく、人と機械がコミュニケーションする場合はどうなのでしょうか?

人対機械のコミュニケーション

人と機械がコミュニケーションするというと、とても奇妙に見えてきます。機械といえば、自動車とかコンピュータとか自動販売機とかたくさん思いつきますが、言葉を理解するようには思えません。

しかし、近年の技術革新、特にディープラーニングによる機械学習技術の発展により、ソフトバンクのPepperのようなロボットやAmazon Echoのようなスピーカーと音声対話できるようになりました。また、日本マイクロソフトのりんなといったチャットボットのような文字入力を元に対話ができる人工知能も増えてきました。


図1 Pepperのイメージ([2]より引用)

このように人と機械がコミュニケーションする時代が確実に迫ってきてきます。ただ、よくよく考えてみると、これらは音声認識、音声合成、自然言語処理といった言語的コミュニケーションしか今のところ注目されていません。ここで人と人とのコミュニケーションが言語と非言語に分類できるというはなしを思い出してみると、非言語コミュニケーションはどうなってしまったのだろうと思ってしまいます。非言語コミュニケーションが出来なければ、人と機械は、人と人のようにコミュニケーションできないままになってしまいます。

図2 Amazon Echoの利用例([3]より引用)

そこで、本アドベントカレンダーでは、人と機械の非言語コミュニケーションを重点的に紹介していくことにします。そして、このコミュニケーションを成り立たせるための技術を

自然”非”言語処理

と勝手に名付けて整理していきます。

それでは、その自然非言語処理の導入編として、「非言語処理の代表例である表情認識」によるコミュニケーションを自分たちの手で作ってみましょう。

実装:人と機械との表情によるコミュニケーション

今回はパソコンについているWebカメラで人の笑顔を認識すると、画面上の機械が笑顔になり、怒った顔になると泣いてしまうというとてもシンプルなコミュニケーションをプログラミングで実装してみましょう。実装にはプログラミング言語Pythonと画像処理ライブラリOpenCVを用います。また、表情認識そのもののプログラムを書くには、機械学習の知識やたくさんのデータが必要となるので、ここではマイクロソフト社のEmotion APIを用います。
(なお、この認識技術あたりの知識も応用編として紹介する予定です。)

EmotionalAgent.py
#!/usr/bin/python
# -*- Coding: utf-8 -*-
"""
機械(バーチャルエージェント)と人が表情によるコミュニケーションするためのプログラム
"""
__author__="alfredplpl"

#See also:
#https://westus.dev.cognitive.microsoft.com/docs/services/5639d931ca73072154c1ce89/operations/56f23eb019845524ec61c4d7
#http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_gui/py_video_display/py_video_display.html

import httplib,cv2,json

## 定数群
headers = {
    # Request headers
    'Content-Type': 'application/octet-stream',
    'Ocp-Apim-Subscription-Key': '[Your Key]',
}

SIZE=(480,270)
WAIT_TIME=5000#[ms]

#機械側の反応
HAPINESS_PATH="./img/hapiness.png"
SADNESS_PATH="./img/sadness.png"
NEUTRAL_PATH="./img/neutral.png"
HAPINESS_IMG=cv2.imread(HAPINESS_PATH)
SADNESS_IMG=cv2.imread(SADNESS_PATH)
NEUTRAL_IMG=cv2.imread(NEUTRAL_PATH)

############

#ここからメイン関数に相当する場所
if __name__ == "__main__":
    #パソコンに付いているWebカメラから撮影
    cap = cv2.VideoCapture(0)

    while (True):
        #撮影した画像を表示しています。
        ret, frame = cap.read()
        resized=cv2.resize(frame,SIZE)
        cv2.imshow("Captured",resized)

        #撮影した画像をメモリ上にJPG圧縮しています
        cv2.imencode(".jpg",resized)
        result, encimg = cv2.imencode('.jpg', resized)

        #メモリ上にJPG圧縮した画像をEmotion APIに投げつけています。
        try:
            conn = httplib.HTTPSConnection('westus.api.cognitive.microsoft.com')
            conn.request("POST", "/emotion/v1.0/recognize", encimg,
                         headers)
            response = conn.getresponse()
            data = response.read()
            print(data)
            conn.close()
        except Exception as e:
            print("[Errno {0}] {1}".format(e.errno, e.strerror))
            if cv2.waitKey(WAIT_TIME) & 0xFF == ord('q'):
                break

        #Emotion APIによる表情認識結果をもとに機械の返答を変化させています。
        result=json.loads(data)
        if(len(result)>0):
            if(result[0]["scores"]["happiness"]>0.5):
                cv2.imshow("AgentResponse",HAPINESS_IMG)
            elif (result[0]["scores"]["anger"] > 0.3):
                cv2.imshow("AgentResponse",SADNESS_IMG)
            else:
                cv2.imshow("AgentResponse", NEUTRAL_IMG)

        if cv2.waitKey(WAIT_TIME) & 0xFF == ord('q'):
            break
    #お片付け
    cap.release()
    cv2.destroyAllWindows()

実行結果は以下の画像の通りです。左が機械側の反応、右が人間側の反応です。



たったこれだけのプログラムで人と機械は非言語コミュニケーションが取れるようになります。
ただし、判断能力や文脈を読めなさすぎて、コミュニケーションできている気がするだけですが。

応用例

このような表情認識の応用例として、ソニーのスマイルシャッター機能[4]があります。集合写真を撮る時、全員が笑顔になるとシャッターが下りるという機能です。この機能を使えば、みんな笑顔で写真に写ることができます。半目にもならないはずです

図3 スマイルシャッター機能の説明([4]より引用)

まとめ

今回はコミュニケーションとはなんぞや、人と機械のコミュニケーションとはさらになんぞやといった話をしました。

人と機械のコミュニケーションの中でも言語は進んできたけれども、非言語はまだバラバラで散らかっている状況にあります。そこで本アドベントカレンダーでは人と機械のコミュニケーションに必要な技術を自然非言語処理と勝手に名付けました。自然非言語処理の実装例では表情によるコミュニケーションを機械とはかれるようにしてみました。

次回は、もう少し言語と非言語ってなんなんだ。僕らは感じた情報をどう取り扱っているのか。といった深めな話をしていきましょう。

参考文献

[1] 広辞苑
[2] https://www.softbank.jp/robot/consumer/products/
[3] https://www.amazon.co.jp/Amazon-Echo-New%E3%83%A2%E3%83%87%E3%83%AB-%E3%80%81%E3%83%81%E3%83%A3%E3%82%B3%E3%83%BC%E3%83%AB-%E3%83%95%E3%82%A1%E3%83%96%E3%83%AA%E3%83%83%E3%82%AF/dp/B071ZF5KCM
[4] http://www.sony.jp/cyber-shot/products/DSC-T70/feature_1.html