Atomエディタから、はてなブログのエントリーを編集できるようになりました
以前から開発していた、Atomからはてなブログにエントリーを投稿できるようにするパッケージ
にプルリクエストをもらって、エントリーが編集できるようになりました。
ついでに日本語ドキュメントも作成しました。
パッケージはapm install hatena-blog-entry-post
でインストールできます。
Processingでカレンダーを作る
カレンダーを作ってみたが、長いし読み解きにくいコードになってしまった。input areaみたいなのは作れないのかな?
int defaultYear = 2015; int defaultMonth = 5; int rectRX, rectRY; int rectLX, rectLY; int rectSize = 20; boolean leftButtonOver = false; boolean rightButtonOver = false; color currentColor = 200; void setup() { size(800, 700); background(currentColor); rectLX = width/2-50; rectLY = 50; rectRX = width/2+50; rectRY = 50; } void draw() { update(); drawCalendar(defaultYear, defaultMonth); if (rightButtonOver) { fill(255); } else { fill(0); } rect(rectRX, rectRY, rectSize, rectSize); if (leftButtonOver) { fill(255); } else { fill(0); } rect(rectLX, rectLY, rectSize, rectSize); } void update() { if (overLeftButton(rectLX, rectLY, rectSize, rectSize)) { leftButtonOver = true; rightButtonOver = false; } else if (overRightButton(rectRX, rectRY, rectSize, rectSize)) { leftButtonOver = false; rightButtonOver = true; } else { leftButtonOver = false; rightButtonOver = false; } } void mousePressed() { if (leftButtonOver) { background(currentColor); if (defaultMonth == 1) { defaultMonth = 12; defaultYear -= 1; } else { defaultMonth -= 1; } } if (rightButtonOver) { background(currentColor); if (defaultMonth == 12) { defaultMonth = 1; defaultYear += 1; } else { defaultMonth += 1; } } } boolean overRightButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } boolean overLeftButton(int x, int y, int width, int height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } void drawCalendar(int year, int month) { fill(0); text(year, width/2-20, 30); text(month, width/2+20, 30); int days = daysOfMonth(year, month); // draw days of the Month for (int day = 1; day <= days; day++) { fill(50); int x = dayOfWeek(year, month, day); int y = weekOfMonth(year, month, day); fill(0); noFill(); rect(x*100+40, y*100-20, 100, 100); color z = setColor(x); fill(z); text(day, x*100+50, y*100); } } color setColor(int day) { if (day == 0) { return #FF0000; } else if (day == 6) { return #0008FF; } else { return #000000; } } int weekOfMonth(int year, int month, int date) { return (date - dayOfWeek(year, month, date) + 12) / 7; } int daysSum(int year, int month, int date) { // 2000,1,1 int daysSum = 1; for (int y = year-1; y >= 2000; y--) { if (isLeapYear(y)) { daysSum += 366; } else { daysSum += 365; } } for (int m = month-1; m >= 1; m--) { daysSum += daysOfMonth(year, m); } daysSum += date; return daysSum; } int dayOfWeek(int year, int month, int date) { int daysSum = daysSum(year, month, date); // 0 - Sun / 6 - Sat return daysSum % 7; } boolean isLeapYear(int year) { if (year % 4 == 0 && year % 100 != 0) { return true; } else { return false; } } // 4,6,9,11 has 30 days. int daysOfMonth(int year, int month) { if (month == 4 || month == 6 || month == 9 || month == 11) { return 30; } else if (month == 2) { if (isLeapYear(year)) { return 29; } else { return 28; } } else { return 31; } }
最近読んだ論文まとめ(随時更新)
最近読んだ論文の要約。Google Scholarで論文検索やGoogle検索すれば読めるものも。
カレンダー
大橋亮人, et al. "イベント履歴を用いたスケジュール推薦カレンダーシステム." 情報処理学会第 73 回全国大会 2 (2011): 4.
機械学習関連
近藤陽介, and 佐藤理史. "多項ナイーブベイズ分類を用いた日本語テキストの難易度判定手法の検討." 言語処理学会第 13 回年次大会発表論文集 (2007): 534-537.
- ナイーブベイズ分類というアルゴリズムを利用した、日本語文章の難易度カテゴライズ研究。機械学習とよばれる人工知能の研究課題のひとつで、難易度ごとのモデルの特徴をコンピューターに教えこませることで、対象文章の難易度を判定する。
Borriello, G. "Bayesian filters for location estimation." IEEE Pervasive Computing (2003).
- 位置情報センサーの精度を高めるために、ベイジアンフィルタを用いて、超音波センサー、赤外線センサー、レーザー光探知による位置情報推定システムを融合できることを示した
-
- 既存のベイジアンフィルタでは分類しきれない画像付きスパムメッセージを分類するために、ファイルネーム・ファイルサイズ・画像位置といった画像情報を訓練データとしてベイジアンフィルタに流すことで、有効なアンチ画像スパムフィルタを作成できることを示した
風間淳一, 宮尾祐介, and 辻井潤一. "教師なし隠れマルコフモデルを利用した最大エントロピータグ付けモデル." 自然言語処理 11.4 (2004): 3-23.
- コーパスを用いてタグ付け器を教師あり学習させ、テクストにタグを付ける。ユーザーが手動でタグの誤りを修正するフィードバックを行うことで、コーパスの精度を高める。
-
- メールの自動タグ付けシステムを開発。ユーザーはタグ付けにミスがあればそれを修正し、ミスがなければ何もしない。この暗黙の(implicit)フィードバックを用いた訓練システムが有効であることを示した。
-
- 通信授業はどれも単調で興味あるものを探すのが難しい。動画内の発話や文字を認識するシステムを使い、動画を自動でタグ付け、セクションごとに分類して、ユーザーが興味ある動画のセクションにたどり着きやすくする。
Web上での人物評価関連
-
- オンラインオークション等、個人の人物評価情報が必要とされるサービスにおいては、レーティングシステムが使われる。レーティングシステムを効果的にするは、レーティングするためのコストが低いこと、レーティングを比較できる取引相手が多くいること、他人になりすますことが難しいこと、レーティングシステムのホストが信頼できること、が挙げられる。
Das, Manoj. "Using Social Networking Sites (SNS): Mediating Role of Self Disclosure and Effect on Well-being." Editorial Team: 30.
- ヒトは自己開示(他人と自分のことについて共有すること)で、結束を強くする。例えば友だちがいなくとも、社会から疎外されても、自分の容姿に自信がなくとも、テクストベースのSNSでは、これらはフラットなので、気にせずSNSを使うことができる。SNS上で自己開示することで、社会的結束を感じ、幸福になる。
緒方進, et al. "Web 上のテキスト情報を用いた人物評価手法." 情報処理学会研究報告 (2005): 9-14.
- Web上の書き込み記事から人物の特徴を評価するために、テキストマイニング手法を適用し、EQ(Emotional Intelligence Quotient)で人物評価を行った。
通知システム関連
-
- モバイルデバイスからのメッセージ等情報提示の過度な負担を軽減するために、加速度計付きのコンテキスト・アウェア・コンピューティング・デバイスを開発して計測した結果、ランダムに情報提示するより、2つの身体動作の移行期に情報提示した時のほうが、負担が軽減されることがわかった。
笠井裕之, and 倉掛正治. "受信ユーザ状況に依存したモバイル向け情報通知制御システム." 情報処理学会論文誌 48.3 (2007): 1393-1404.
- ユーザーがモバイル端末画面上に注意を向けているかどうか、モバイル端末上のタスクの状況に着目。通知の提示時間やタイミングを制御することで、ユーザーのタスクを極力邪魔することなく、ユーザーが気づきやすいように情報を提示できる機能、さらにユーザーが気付かなかったであろう情報を特定し再掲示する機能を提供する
三好史隆, et al. "タスク集中度と認知時間を指標とした周辺表示法の評価." 電子情報通信学会論文誌 A 89.10 (2006): 831-839.
- 情報が提示された時に周辺表示法がユーザーに与える”情報提示の気づかせやすさ”と”メインタスクへの妨害の度合い”を定量化することで、あらかじめ情報の重要度がわかっている場合、周辺情報の重要度や緊急性を考慮して提示方法を選択することができる。
次読む論文
20分で作るFacebookメッセンジャーボット(hubot)
20分で作るFacebookメッセンジャーボット(hubot)
すごーく簡単にFacebookメッセンジャーボットが作成できました。後のためにその手順を分かりやすくメモしておきます。
別にhubotでなくともボットは作成できますが、今回は使い方に慣れているhubotを使用します。
hubot
hubotの作成
hubot作成手順については以前の記事参考。
アダプターのインストール
hubot作成後、Facebookメッセンジャーアダプタであるhubot-fbをインストールします。
$ npm install -S hubot-fb
次にProcfile
を編集します。
web: bin/hubot -a fb
Facebookページ、アプリの作成、設定
メッセンジャーボットを利用するには、FacebookページとFacebookアプリが必要になります。
Facebookページの作成
https://www.facebook.com/pages/create/
上記のページから、ジャンルやその他必要事項を入力し、Facebookページを作成します。
Facebookアプリの作成
https://developers.facebook.com/quickstarts/?platform=web
Facebookディベロッパー登録後、上記のページにアクセスします。
画像のボタンをクリックして、アプリのディスプレイネームやメールアドレス等必要な情報を入力して、新しくアプリを作成します。
トークンの設定
アプリIDの新規作成に成功すると、アプリのダッシュボードに移動します。
サイドバーの"Messenger"をクリックして、ウィザードを起動、Messagerプラットフォームを有効にしましょう。
次に、"Token Generation"から作成したFacebookページを選択し、アクセストークンを生成します。生成されたトークンをコピーしておきましょう。
アプリの登録
先ほど取得したトークンを使い、次のcurlコマンドを実行しましょう。
curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=[FB_PAGE_TOKEN]"
Herokuで動かす
hubotのスクリプトをherokuに上げましょう。
Herokuにプッシュ
まずはgitにコミット。
$ git init $ git add . $ git commit -m "first commit"
次にherokuにプッシュ。その際、わかりやすいアプリの名前をつけておきます。
$ heroku apps:create アプリ名 $ git push heroku master
heroku側の設定として、環境変数を使う必要があります。FB_PAGE_TOKEN
は先ほど生成したもの。FB_VERIFY_TOKEN
は適当な文字列を使用します。
$ heroku config:set FB_PAGE_TOKEN=**** $ heroku config:set FB_VERIFY_TOKEN=abcd
Webhooks
Webhookを設定することで、ユーザーからのメッセージ等を受け取ることが可能になります。
アプリのダッシュボードからWebhookの設定を行いましょう。
Setup Webhooksをクリックすると、次のようなダイアログが表示されます。
Callback URLにはhubotのURLに/hubot/
を追加したものを入力しましょう。
例:
アプリ名.herokuapp.com/hubot/
"Verify Token"の欄には、先ほどherokuに設定したFB_VERIFY_TOKEN
を入力します。
"Subscription Fields"のすべてのチェックボックスをチェックし、"Verify and Save"をクリックして完了です。
実際にメッセージを送る
適当にスクリプトを追加して、Facebookページを検索して、語りかけてみましょう。
module.exports = (robot) -> robot.hear /疲れた/i, (res) -> res.send "頑張って!"
人工知能/機械学習: ベイジアンフィルタによるテクスト分類
人工知能/機械学習: ベイジアンフィルタによるテクスト分類
機械学習には多種ありますが、今回は自然言語処理、その中でも特に、ベイジアンフィルタについて扱ってみたいと思います。
このエントリを書くにあたって、下記の書籍がかなり参考になりました。機械学習のみならず、Webデータ全般について、取得法から解析法、利用法までを初心者にも分かりやすく解説しています。
JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック
- 作者: クジラ飛行机
- 出版社/メーカー: ソシム
- 発売日: 2015/08/31
- メディア: 単行本
- この商品を含むブログ (2件) を見る
ベイジアンフィルタとは、「ナイーブベイズ分類」を応用したもので、対象のデータを解析・学習するためのフィルタです。
フィルタにはキーワード指定のブラックリスト・ホワイトリスト方式から、ベイジアンフィルタを代表とする学習タイプのフィルタまで、幅広く存在します。
テクスト分類とは
テクスト分類とは、与えられた対象のテクストが、同じく与えられたクラスのどれに属するかを判断するタスクを指します。こうしたクラスは、たいてい一般的な主題になります。
この技術は、身近なところでは、
- Eメールのソート: 受信したメールを「家族から」「SNSから」「広告」といった正しいフォルダ(クラス)に分類する。
- レビューのクラス分け: 製品や映画のレビューがポジティブであるか、ネガティブであるかを判断し、自動的に分類する。
などに使われています。
テクスト分類には、手作業で行われるものも多々あります。例えば、映画のジャンル分けには、明確な基準はなく、広告代理店の売り方次第で変わり得るものです(多分)。こうした手動の分類は、大規模になると大変です。そこで、機械学習をもとにした自動テクスト分類が必要とされます。
アルゴリズム
ベイジアンフィルタ、つまり、ナイーブベイズ分類のアルゴリズムについて見てみましょう。
文書dが与えられたときに、カテゴリcである確率を、$P(c|d)$と表します。そしてこれを、ベイズの定理で表すと、次のようになります。
$$ P(c|d)=\frac {P(c) P(d|c)}{P(d)} $$
一つ一つ見ていきましょう。$P(c)$とは与えられたある文書がそのカテゴリである事前確率です。つまり、メール1000通中50通がスパムであれば、
P(スパム) = 50 / 1000 = 0.05
となります。
$P(c|d)$とは、ここで求めたい結果、つまり、ある文書dが与えられたとき、カテゴリcである事後確率です。次に、$P(d|c)$とはカテゴリcに文書dが生成される確率で、統計学では尤度(ゆうど)と呼ばれます。$P(d)$はすべての文書中、文書dが生成される確率です。
ここで、文書dは単語の出現場所を考慮しない単語の集合$(t_1, t_2, ... , t_i)$とします。すると次の式が成り立ちます。
$$ P(d|c)=P(t_1|c)\ P(t_2|c)\ ...\ P(t_i|c)=\prod_i P(t_i|c) $$
第三式のギリシア文字は積の記号らしいです。さっき知りました。
今度は、$P(t_i|c)$を求めましょう。あるカテゴリにその単語が出現する確率です。これは訓練データのカテゴリcに単語$t_i$が出てきた回数をカテゴリcの全単語数で割ることで計算できます。
テクスト分類においては、ある文書のもっともそれらしいカテゴリを求めることが目標です。ナイーブベイズ分類では、それはカテゴリcである最大事後確率(maximum a posteriori)の、$c_{map}$で表します。
$$ c_{map}=arg\ max_c P(c|d)=arg\ max_c P(c) \prod_i P(t_i|c) $$
もし、訓練データにおいて、WTOという単語がChinaカテゴリの文書にのみ出現するとき、UKカテゴリにWTOが出現する確率$P(WTO|UK)$について、次の式が成り立ちます。
$$ P(WTO|UK)=0 $$
次に、対象の文書Britain is a member of the WTOが与えられたとします。この文書はBritainを含むので、UKカテゴリである確率が高そうです。しかし、訓練データではUKカテゴリに出てこなかったWTOという新単語が含まれているために、この文書をd1とした時、$P(d1|UK)=0$となり、この文書がカテゴリUKから生成された確率はゼロとなってしまいます。
というのも、カテゴリcに文書dが生成される尤度$P(d|c)$は、単語が出現する確率$P(t|c)$の積で求められるためです。
これを解消するために、各単語を出現回数にシンプルに1を足す、add-one, Laplace-smoothing が使用されます。
ベイジアンフィルタのNodeライブラリ
さて、アルゴリズムについて理解したところで、いや、実は理解していなくともいいんですが、実際にベイジアンフィルタを使用してみましょう。
Node.js には、ベイジアンフィルタを実装したbayesライブラリが存在します。以下、このライブラリを使用して、ベイジアンフィルタを実装します。
まずはインストール。
$ npm install bayes mecab-lite
次にjsファイルを編集します。今回はサンプルとして、Wikipediaから「織田信長」、「明智光秀」、「豊臣秀吉」について学習するフィルタを実装することにしましょう。
var bayes = require('bayes'); var Mecab = require('mecab-lite'); var mecab = new Mecab() var nobunaga = '織田 信長(おだ のぶなが)は、戦国時代から安土桃山時代にかけての武将・戦国大名。三英傑の一人。尾張国(現在の愛知県)の古渡城主・織田信秀の嫡男[注釈 5]。 尾張守護代の織田氏の中でも庶流・弾正忠家の生まれであったが、父の代から主家の清洲織田氏(織田大和守家)や尾張守護の斯波氏をも凌ぐ力をつけ、家督争いの混乱を収めて尾張を統一し、桶狭間の戦いで今川義元を討ち取ると、婚姻による同盟策などを駆使しながら領土を拡大した。足利義昭を奉じて上洛すると、将軍、次いでは天皇の権威を利用して天下に号令。後には義昭を追放して室町幕府を事実上滅ぼし、畿内を中心に強力な中央集権的政権(織田政権)を確立して天下人となった。これによって他の有力な大名を抑えて戦国乱世の終焉に道筋をつけた。しかし天正10年6月2日(1582年6月21日)、重臣・明智光秀に謀反を起こされ、本能寺で自害した。すでに家督を譲っていた嫡男・織田信忠も同日に二条城で没し、信長の政権は、豊臣秀吉による豊臣政権、徳川家康が開いた江戸幕府へと引き継がれていくことになる。'; var mitsuhide = '明智 光秀(あけち みつひで)は、戦国時代から安土桃山時代にかけての武将。戦国大名・織田信長に見出されて重臣に取り立てられるが、本能寺の変を起こして信長を暗殺。直後に中国大返しにより戻った羽柴秀吉に山崎の戦いで敗れた。一説では、落ちていく途中、小栗栖において落ち武者狩りで殺害されたとも[注釈 4][6]致命傷を受けて自害したもとされる[7]。これは光秀が信長を討って天下人になってからわずか13日後のことであり、その短い治世は「三日天下」とも言う。本姓は源氏で、家系は清和源氏の摂津源氏系で、美濃源氏土岐氏支流である明智氏。通称は十兵衛。雅号は咲庵(しょうあん)。のちに朝廷より惟任の姓を賜ったため惟任光秀とも言う。妻は妻木煕子。その間には、細川忠興室・珠(洗礼名:ガラシャ)、嫡男・光慶(十五郎)、津田信澄室がいる。領地では善政を行ったとされ、忌日に祭事を伝える地域(光秀公正辰祭・御霊神社 (福知山市))もある。後世、江戸時代の文楽「絵本太功記」や歌舞伎「時桔梗出世請状」をはじめ、小説・映画・テレビドラマなどでもその人物がとりあげられている。'; var hideyoshi = '豊臣秀吉(とよとみ ひでよし、とよとみ の ひでよし、旧字体: 豐臣秀吉)、または羽柴 秀吉(はしば ひでよし)は、戦国時代から安土桃山時代にかけての武将、大名、天下人、関白、太政大臣、太閤。三英傑の一人[1][2]。初め木下氏を名字とし、羽柴氏に改める。本姓としては、初め平氏を自称するが、近衛家の猶子となり藤原氏に改姓した後、豊臣氏に改めた。尾張国愛知郡中村郷の下層民の家に生まれたとされる。(出自参照)当初、今川家に仕えるも出奔した後に織田信長に仕官し、次第に頭角を現した。信長が本能寺の変で明智光秀に討たれると「中国大返し」により京へと戻り山崎の戦いで光秀を破った後、信長の孫・三法師を擁して織田家内部の勢力争いに勝ち、信長の後継の地位を得た。大坂城を築き、関白・太政大臣に就任し、豊臣姓を賜り、日本全国の大名を臣従させて天下統一を果たした。天下統一後は太閤検地や刀狩令、惣無事令、石高制などの全国に及ぶ多くの政策で国内の統合を進めた。理由は諸説あるが明の征服を決意して朝鮮に出兵した文禄・慶長の役の最中に、嗣子の秀頼を徳川家康ら五大老に託して病没した。秀吉の死後に台頭した徳川家康が関ヶ原の戦いで勝利して天下を掌握し、豊臣家は凋落。慶長19年(1614年)から同20年(1615年)の大坂の陣で豊臣家は江戸幕府に滅ぼされた。墨俣の一夜城、金ヶ崎の退き口、高松城の水攻め、中国大返し、石垣山一夜城などが、機知に富んだ功名立志伝として広く親しまれ、百姓から天下人へと至った生涯は「戦国一の出世頭」と評される。'; var classifier = bayes({ tokenizer: function(text) { return mecab.wakatigakiSync(text); } }); // 学習 classifier.learn(nobunaga, '織田信長'); classifier.learn(mitsuhide, '明智光秀'); classifier.learn(hideyoshi, '豊臣秀吉'); // 与えられたテキストデータのカテゴリを予想 categorize('部下に謀反を起こされる'); categorize('三日天下'); categorize('下層農民の生まれ'); function categorize(text) { var r = classifier.categorize(text); console.log("[" + r + "] - " + text); }
以下出力結果です。ちゃんと分類されていますね。
[織田信長] - 部下に謀反を起こされる [明智光秀] - 三日天下 [豊臣秀吉] - 下層農民の生まれ
英語と違って、日本語の文章は単語間の区切りがコンピューターにとってはわかりにくいので、分かち書きしたものをベイジアンフィルタにトークンとして与えています。
参考文献
JS+Node.jsによるWebクローラー/ネットエージェント開発テクニック
- 作者: クジラ飛行机
- 出版社/メーカー: ソシム
- 発売日: 2015/08/31
- メディア: 単行本
- この商品を含むブログ (2件) を見る
- 作者: Christopher D.Manning,Prabhakar Raghavan,Hinrich Schutze,岩野和生,黒川利明,濱田誠司,村上明子
- 出版社/メーカー: 共立出版
- 発売日: 2012/06/23
- メディア: 単行本
- 購入: 2人 クリック: 69回
- この商品を含むブログ (5件) を見る
HubotからGithubのissueを扱う
HubotからGithubのissueを扱う
http://shokai.org/blog/archives/9560
こちらコードに少し手を加えて、HubotからGtihub issueを扱えるようにしてみた。
create, list up, close github issues via hubot
使い方
Githubのトークンが必要:
$ curl -i https://api.github.com/authorizations -d '{"scopes":["repo"]}' -u "username" $ heroku config:set HUBOT_GITHUB_TOKEN=token_value
TODO listとかブログ記事のネタとかのために使う。
hubot issue list
hubot issue create タイトル body コンテンツ
hubot close issueのナンバー(#)
Processing のエディタとして Atom を使う
Processing のコーディングを快適にするために、Atom を使ってみる。
Processing とは
ビジュアルアートを学ぶためのオープンソースのプログラミング言語であり、開発環境。Java でビルドされており、その構文は Java をシンプルにしたもの。
エディタも備わっているが、より快適にコーディングするために、Atom に Processing 用のパッケージを導入してみる。
インストールするパッケージ一覧
これらのパッケージをインストールする。
$ apm install processing processing-autocomplete processing-language
Processing の導入
まずは、こちらから Processing の開発環境をダウンロード。
Processingを立ち上げて、Toolsメニューからprocessing-java
をインストールする。
which コマンドでパスを確認し、
$ which processing-java /usr/local/bin/processing-java
processing の実行パスに設定する
実際に使ってみる
.pde
ファイルを作成し、コーディングする。
ctrl-alt-b コマンドでビルドされれば、成功。