2013/09/25(水)感情の分類を考える

趣味で人工知能のために会話文の感情分類がしたいなぁっと思ったので、ちょいと調べていました。そもそも感情は明確に分類できるものなのか怪しいのですが・・・。

ちょろっと自然言語処理関連の論文を調べた限りでは、

  • 「感情表現辞典」という辞典の分類:「喜」「怒」「哀」「怖」「恥」「好」「厭」「昂」「安」「驚」
  • Ekmanの分類:「怒り」「嫌悪」「恐れ」「幸福感」「悲しみ」「驚き」
  • Plutchikの分類:「喜び」「悲しみ」「受容」「嫌悪」「恐れ」「怒り」「驚き」「期待」とこれらの合成 (日本語訳は 山口大学工学部研究報告第53巻第1号pp.85-90 を参考にしました:http://memoirs.lib-e.yamaguchi-u.ac.jp/531/11.pdf

という分類がよく使われているようです。

自分がしたいのは会話文の感情分類。

Ekmanの分類は表情から読み取れる感情とのことなので、除外。残りは Plutchik の分類か「感情表現辞典」の分類。

Plutchik の混合感情の考え方とかはよく出来ていると思うんだけど、自分以外の人に混合感情を意識させて妥当な感情を選ばせるのはあまりに負担がかかり過ぎるように思えます。かといって混合感情を意識させない場合、ドンピシャに純粋感情を過不足なく複数選択させるのが困難。

一人で感情分類作業する場合は、Plutchik の分類でもいいけど、誰かに手伝ってもらう場合はPlutchikの分類はキツい。

というわけで、「感情表現辞典」の10分類をベースにすることにしました。

今日、注文していた「感情表現辞典」が来たのでちょろっと読みました。

この10分類は実際の表現例から「喜」「怒」「苛」「悲」「淋」「鬱」「悄(ショウ:しょんぼりする)」「苦」「安」「悔」「昂」「感動」「好」「嫌」「憎」「驚」「怖」「恥」「惑」の19感情を抽出して境界線の引きにくさを理由に以下のように圧縮したもののようです。

  • 「哀」={「悲」,「淋」}
  • 「厭」={「鬱」,「悄」,「苦」,「悔」,「嫌」,「憎」,「惑」}
  • 「昂」={「苛」,「昂」,「感動」}

これでほぼ自分の直感にも反しないのですが、いくらか拡張しました。

人工知能を考えると、

  • 友達としての好き
  • 恋人としての好き
  • 慕う(目上の人への)の好き
  • 憧れの好き はそれぞれ分けるべきと考えて、

「好」ー>「友情」,「恋愛」,「忠誠(忠義)」,「欲」

に拡張しました。

これで「喜」「怒」「哀」「怖」「恥」「厭」「昂」「安」「驚」「欲」「友情」「恋愛」「忠誠」の13感情。

これらの13種のうちのどれかか、これらのうちの組み合わせで会話文に表れるほとんどの感情は網羅できるかな?

-追記-
研究レベルなら、「An Argument For Basic Emotions」とか読んでおいたほうがいいです。これによると、愛はemotional attitudeで感情(情動)と区別されています。 Plutchikの3次元モデルは「The Nature of Emotions」を読んだけど根拠が不明でした。

2013/09/06(金)Perl製Wiki MojoMojo メモ #02 トラブルシューティング

最近同じPerl製Wikiの https://github.com/yuki-kimoto/ringowiki もコミットが盛んになってきましたが、今のMojoMojoを越えるにはまだまだ時間がかかりそうだというわけで本格的にMojoMojoを使うことにしました。

早速いろいろ問題が発生したので解決のメモです。

  • 「ユーザーの新規登録ができない!」 What is this wiki powered by (look at the bottom; 8 letters, all lowercase)? の入力欄でcatalystと何回入力してもパスできないと思ったら、「mojomojo」でした。 MojoMojoのGithubのレポジトリではJun 27, 2013 のコミットでこの問題(?)は解消されているっぽいです。

  • 「JPEGをアップロードするとサムネイルが作れない!」

[error] Caught exception in MojoMojo::Controller::Attachment->thumb "format 'jpeg' not supported - formats bmp, ico, pnm, raw, sgi, tga available for reading

というエラーが出る。

↓で解決。

yum install libjpeg-devel
yum install libpng-devel
yum install giflib-devel

mojomojo再起動 -> 同じエラー

cpanm Imager --reinstall

mojomojo再起動 -> OK
  • 「サムネイルをページに挿入するとエラーが出る!」
    ↓のようなエラー
[error] Caught exception in MojoMojo::Controller::PageAdmin->edit "Operation "ne": no method found,
        left argument in overloaded package Text::Balanced::ErrorMsg,
        right argument has no overloaded magic at hogehoge/DBIx/Class/Storage/TxnScopeGuard.pm line 26."

DBIx/Class/Storage/TxnScopeGuard.pm の26行目の

if (defined $@ and $@ ne '') {

を↓に書き換える。

if (defined $@ and "$@" ne '') {

(Text::Balanced::ErrorMsgが$@に入るがこれをオーバーライドされた「"」を使って文字列に変換する必要がある)

*「登録したユーザを消したい」

perl /script/util/delete_inactive_users.pl

を実行して注意書きをよく読んで適当な引数(本当になんでもいい)をつけて↓を実行

perl /script/util/delete_inactive_users.pl hoge

マークダウンも使えるし、プレビューも見ながら編集できるし、TWikiより高速に動くし、HTMLが綺麗し中々良いです。あとはMojoMojoを拡張するプラグインがあればというところ。

mojomojo

2013/06/30(日)Raspberry Pi でミクにしゃべらせよう

回路の知識いるのかと思ってスルーしてたけど、最近そうでもないことに気づいて購入しました。買ったのは↓の通り

「Raspberry Pi Type B 512MB」
Raspberry Pi Type B 512MB

「SanDisk サンディスク SDHCカード 16GB(SD 16GB) Extreme HD Video 45MB/秒 並行輸入品 海外パッケージ品」
SanDisk サンディスク SDHCカード 16GB(SD 16GB) Extreme HD Video 45MB/秒  並行輸入品 海外パッケージ品

「iBUFFALO 【iPhone5対応】USB充電器(ACアダプタ) 1ポートタイプ 平型 ブラック BSIPA02BK」
iBUFFALO 【iPhone5対応】USB充電器(ACアダプタ) 1ポートタイプ 平型 ブラック BSIPA02BK

「Amazonベーシック USB2.0ケーブル 1.8m (タイプAオス- マイクロタイプBオス)」
Amazonベーシック USB2.0ケーブル 1.8m (タイプAオス- マイクロタイプBオス)

「PLANEX USB→3.5mmヘッドホン/マイク端子 USBオーディオ変換アダプタ PL-US35AP」
PLANEX USB→3.5mmヘッドホン/マイク端子 USBオーディオ変換アダプタ PL-US35AP

「ELECOM USBハブ USB2.0対応 ACアダプタ付 セルフ・バスパワー両対応 4ポート ホワイト U2H-EG4SWH」
ELECOM USBハブ USB2.0対応 ACアダプタ付 セルフ・バスパワー両対応 4ポート ホワイト U2H-EG4SWH

とりあえず↓のクイックスタートガイド通りやれば動きます。

http://www.raspberrypi.org/quick-start-guide

日本語なら「Raspberry Pi を始める (NOOBSで)」が参考になるかな。

USBオーディオ変換アダプタ「PL-US35AP」の音の出し方は「Raspberry PiとUSBオーディオ」を参考にさせてもらいました。

その後やったことは

  • 「Rsapberry PiのIPアドレスの固定化(ルータの設定)」
  • 「sudo apt-get install ibus-anthy」
  • 「デフォルトのエディタをvimに変更」
  • 「Perlのアップデート(plenvとcpanmのインストール)」
  • 「KyTea(京都テキスト解析ツールキット)のインストール」(読み推定の機能が使えるかな?と思って) とか。

Raspberry PiをしゃべらせるためのOpen JTalkのインストールは「Raspberry Piに喋らせる」を参考にさせてもらいました。

↑では「MMDAgent_Example-1.3.zip」になっていますが、現在では「MMDAgent_Example-1.3.1.zip」が利用可能です。jsayコマンドのシェルスクリプトも公開されているので、TMPのところを「TMP=mktemp -t」に変更して「/usr/local/bin/」に入れときました。(固定のファイル名だとほとんど同時にjsayを実行した場合にまずいことになる)

初音ミクの声のダウンロードは「http://cube370.wiki.fc2.com/wiki/%E8%87%AA%E4%BD%9C%E9%9F%B3%E9%9F%BF%E3%83%A2%E3%83%87%E3%83%AB」からできます。これをダウンロードして、メイちゃんの声(MMDAgent-Exampleのを解凍したらある)に上書きすれば初音ミクの声がOpen JTalkでも使えます。

何をしゃべらせるかですが、とりあえず現在時刻と天気をしゃべらせるスクリプトを書いて見ました。こういうのがパパっと書けると情報系で良かったと思えますね。

現在時刻をしゃべるスクリプト↓

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/say/;
use Time::Piece;

my $t = localtime;
my $now = $t->strftime("%p%I時%M分");
$now =~ s/00分//; # ちょうどx時の場合は分を省略する
$now =~ s/12時/零時/;

system("jsay ${now}です");

天気をしゃべるスクリプト↓

#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use feature qw/say/;
use WebService::Livedoor::Weather;
use Data::Printer;

my $city_id = '170010';

my $lw = WebService::Livedoor::Weather->new;
my $weather = $lw->get($city_id);

#p $weather;

my $talk = "天気概況 $weather->{title}。$weather->{description}{text}。";
$talk =~ s/\n//g; # 改行があると音声がそこで途切れるため

system(qq|jsay "$talk"|);

$talk = "天気予報 "; # 一度に渡しすぎるとセグメンテーション違反になるため

for my $forecast (@{ $weather->{forecasts} })
{
    my $date = $forecast->{date};
    $date =~ s/[0-9]{4}-([0-9]{2})-([0-9]{2})/${1}月${2}日/;
    $date =~ s/0([0-9])/$1/; # 01月 -> 1月

    my $date_label = $forecast->{dateLabel};

    my $telop = $forecast->{telop};
    $telop = 'あさって' if $telop eq '明後日';

    my $kion_max = $forecast->{temperature}{max}{celsius};
    my $kion_min = $forecast->{temperature}{min}{celsius};

    $talk .= "$date_label${date}は${telop}。";
    $talk .= "最高気温は${kion_max}度。" if defined $kion_max;
    $talk .= "最低気温は${kion_min}度。" if defined $kion_min;
}

$talk =~ s/\n/ /g; # 改行があると音声がそこで途切れるため
$talk .= "以上、天気予報をお伝えしました。";

system(qq|jsay "$talk"|);

これらをcronに登録しておくと、時報鳴らしたり、朝食食べながら天気予報聞けたりできます。

GoogleカレンダーとかGmailとかもしゃべらせたいですね。

cronではplenv関連で少しハマったけど、echo $PATHで出てくるのを「PATH=hogehoge」みたいな形でcronの設定ファイルの最上部に書いたら上手く動きました。

ちなみに声は↓のような感じ。

ミクのType-βの声がかわいいですな。

これからRaspberry Piで遊びたい人は「これからRaspberry Piをいじる方向けの資料」という資料がいい感じですかね。

2013/05/16(木)Perl勉強メモ #003 グラフ描く

「Graphviz::DSL」がレポートで活躍しています。

#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use Graphviz::DSL;
use open IO => qw/:utf8 :std/;

my $graph = graph {
    name 'Miscellaneous Symbols';

    global rankdir => 'LR';

    my $cnt = 0;

    for my $dec ( hex('2600') .. hex('2609') )
    {
        $cnt++;
        my $char = chr $dec;
        node "node${cnt}", shape => 'record', label => "{<p>$char|<n>}";
    }

    while ($cnt > 1)
    {
        edge [ "node" . ($cnt - 1) . ":n" => "node" . $cnt . ":p" ];
        $cnt--;
    }
};

$graph->save(path => 'symbols', type => 'png', encoding => 'utf-8');

だけで以下のグラフが出ます。

symbols

日本語WordNetに使うとかなり面白いグラフが出ます。

graph

こんなんして意味あんのか?と思ってたけど、ログを解析してOSのデッドロック状態をグラフで表したりすると全然わかりやすさが違って驚きました。

2013/05/09(木)Perl製Wiki MojoMojo メモ #01 インストール編

一応メンテナンスされている MojoMojo というWikiがあったのでインストールしました。インストールで少しハマりどころがあったのでメモです。

git clone https://github.com/mojomojo/mojomojo.git
cd mojomojo
perl Makefile.pl
(多分エラーが出るのでエラーメッセージ見て必要なモジュールを入れる)
cpanm http://cpan.metacpan.org/authors/id/B/BO/BOBTFISH/Catalyst-Devel-1.37.tar.gz
(↑は1.38だと動かないため)
sudo yum install libxslt-devel.x86_64
perl Makefile.pl
make
make test

cp mojomojo.conf mojomojo_local.conf
vim mojomojo_local.conf

# イカを編集
user **** (一応ユーザ名を変更)
dsn  dbi:SQLite:__HOME__/db/sqlite/mojomojo.db
# 編集終わり

mkdir db/sqlite -p
touch db/sqlite/mojomojo.db
./script/mojomojo_spawn_db.pl

# ↓が表示される
Creating a new wiki ...

  dsn:            dbi:SQLite:./db/sqlite/mojomojo.db
  wiki name:      MojoMojo
  admin username: admin
  admin password: admin
  admin name:     ****
  admin email:    ****@localhost
  anon email:     anonymous.coward@localhost

Deploying schema to dbi:SQLite:./db/sqlite/mojomojo.db
Creating initial data
Success!
# 表示終わり

 ./script/mojomojo_server.pl -p 3020

# 以下 nginx の設定
server {
    listen      80;
    server_name ドメイン名;
    access_log  アクセスログのパス;

    allow  自分のIP;
    deny   all;

    location / { 
        proxy_pass  http://127.0.0.1:3020; # 3000番使用済みのため
        proxy_redirect  off;
        proxy_set_header Host       $host;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
    }
}
# nginx の設定終わり

↓のように動きます。

mojomojo

編集がリアルタイムで反映されて中々良い感じ。

mojomojo2

参考サイト: