NLP2017の論文を読みました

NLP2017の論文を読んだので、面白かった論文を中心に読んだメモを残しておきます。もう一月ほど前になるので、大分昔な感じがしますが…。

参考リンク集

D4-1 ニュース制作に役立つtweetの自動抽出手法

  • ○宮﨑太郎 (NHK), 鳥海心 (都市大), 武井友香, 山田一郎, 後藤淳 (NHK)
  • ニュース取材に役立つ情報をソーシャルメディアから抽出するプロジェクトがNHKにある
  • SNSから検索するためのいい感じのクエリを網羅的に用意するのは大変
  • SNSでは口語体や略語もあるので、形態素解析をせずに文字単位のRNNを作る
    • bi-directionalなRNNでベクトル表現を作ってNNでニュース取材に役立つかを判定する
    • RNNではないベースラインでは実験されていない
  • attentionとマルチタスク学習を取り入れるとさらに精度が向上した
    • マルチタスクは「ニュースが役に立つか」「言語モデル(次の文字を予測)」を2つで解く
    • 若干上がる
  • 最終的性能はF値で6割くらいでなかなか難しい

P8-7 STAIR Captions: 大規模日本語画像キャプションデータセット

  • 吉川友也 (千葉工大), ○重藤優太郎 (NAIST), 竹内彰一 (千葉工大)
  • 最近画像と言語の融合が活発、特にキャプション生成
    • 視覚障害者支援や画像検索に役に立つ
  • 画像キャプションを日本語で生成するためのデータセット
  • 構築したデータセットでNNでのキャプション生成ができることも確かめた
  • http://captions.stair.center/
    • クラウドソーシングでアノテーション
  • YJ! Captionsも類似のデータセットだが、画像数やキャプション数はこちらのほうが多い
  • MS-COCOを翻訳したものを学習データに使うよりは性能がよい
  • YJ! Captionsで学習させたものとの性能比較はどんな感じだろうか
    • よくよく考えると直接的な比較はできなかった

P7-4 抽出型文書要約における分散表現の学習―文書と要約の距離最小化―

  • ○田口雄哉, 重藤優太郎, 新保仁, 松本裕治 (NAIST)
  • 文書と要約の類似度をよりよく見れるように抽出型文書要約専用の分散表現を学習しましょう、という話
    • 教師あり学習といえば教師あり学習、直接的ではないにせよ
  • 0から学習させるわけではなく、word2vecの結果から離れないように正則化を入れる
  • 凸関数になるので、最適解はclosed-formで得られる
  • ROUGEでもまぁまぁよくなってる
  • 簡単にできるのでいい感じに見えた

B4-5 ニューラルネットワークによる日本語述語項構造解析の素性の汎化

  • ○松林優一郎, 乾健太郎 (東北大)
  • いい論文でした
  • 述語項構造は、文章内の述語とその項間の関係を規定する構造
  • 従来用いられてきた素性(統語関係パス、単語共起)を分散表現で汎化する
    • 組み合わせ素性だとsparseになるので分散表現でなましたい
    • 述語項毎に個別のルールを覚えることが重要である、ということも昔から知られており、汎化すれば性能が上がるかは自明ではない
  • 分散表現で汎化したものは二値素性と同等の精度で、二値素性も組合せると従来のものから性能が向上した
    • お互い捉えているものが異なる
    • state of the artの性能
  • 図1が大体表している
    • 統語関係パスをGRUを通して埋め込む
    • 述語・項候補の単語を埋め込む(concatする)
    • その他の二値素性
    • ガヲニ無のスコアをsoftmaxで吐く
    • 従来は5次程度の組み合わせ素性を使っていたため、多段にする

P10-5 疑似データの事前学習に基づくEncoder-decoder型日本語崩れ表記正規化

  • ○斉藤いつみ, 鈴木潤, 貞光九月, 西田京介, 齋藤邦子, 松尾義博 (NTT)
  • SNS等のくずれた日本語をどうにかしたい研究の続編
    • 崩れた分の分かち書きではなく、正規化をするタスクをやる
  • attention付きのencoder-decoder
  • 文字列正規化の正解データは多くないため、いくつかの変換パターンで疑似データを作る(表1)
    • twitterデータに対して変換をして、約11万分の疑似正解データを作った
  • Mosesでは疑似データも学習に加えるとノイズに負けて精度が落ちる
  • 提案法では疑似データも学習に加えるとノイズに負けず精度が上がる
    • とはいっても、表3によるとMosesと同じくらいの性能
    • 疑似データを増やしていくとMosesも越えられそう、という感じかな?

C2-2 係り受け構造との同時予測によるA* CCG解析

  • ○♠吉川将司, 能地宏, 松本裕治 (NAIST)
  • 優秀賞を受賞していた
  • CCGによる構文解析で曖昧性があった場合に英語ではヒューリステックを使うことである程度解決できた問題が日本語ではヒューリステックな方法では簡単には解決できない
  • 係り受け構造と同時予測することにより曖昧性を解消し、従来法と比べて高い解析精度を達成している
  • Nojiらの手法では正解の品詞情報を使っているが、提案法では品詞情報を使わず高い性能を出している

A2-1 医療テキスト解析のための事実性判定と融合した病名表現認識器

  • ○矢野憲, 若宮翔子, 荒牧英治 (NAIST)
  • 日本語の医療用NLPツールを提案する。以下の2つからなる。
    • 事象認識: 病名、疾患名を同定する
    • 陽性判定: 陽性か陰性か判定する
  • 形態素だと難しいので、文字単位で処理を行う
    • 形態素単位の実験と比較したい
    • 素性には単語ベースのものも入っている
  • 2つのタスクは関連しているので、融合(同時に解く)する
  • NTCIRの共有タスクを解く
  • 方法は固有表現抽出と同じく系列ラベリングっぽい方法で解く
  • 単語ベースのやつよりかはマージンを持ってよさそうな感じに見える
  • 方法は単純だが、医療系テキストの特徴を捉えていてよさそう

深層学習による自然言語処理 (機械学習プロフェッショナルシリーズ)

深層学習による自然言語処理 (機械学習プロフェッショナルシリーズ)

AWS Lambdaに入門する

Amazon Elasticsearch Serviceに引き続き、AWS Lambdaに入門しました。Lambdaを使って、Amazon Elasticsearch Serviceで特定の単語を検索をさせてslackに書き込んでくれるbot君を練習台でやってみました。

やりたいこと

AWS強化月間(?)ということでAmazon Elasticsearch Serviceに入門していました。

twitterやslackのデータ置き場は無事に自宅のmac miniからAmazon Elasticsearch Serviceに移行できました。しかし、肝心のクローラーは相変わらず自宅のmac miniのjenkinsが頑張っているので、それをAWS Lambdaで代わりにやってもらおうというのがやりたいことです。一気にやるのはしんどいので、今回は以下のことをやってみます。

  • CloudWatch Eventsで定期的にlambdaを起動
  • Amazon Elasticsearch Serviceに貯蓄されているtwitterのデータから特定の単語を含むものを検索
    • goを使って書いていますが、AWSの認証をどうやるか
  • 検索にヒットした発言をslackに投稿
    • lambdaから簡単に外に出られるのか

簡単なことしかやっていないですが、まぁ手始めということで。

準備: 適切なポリシーを設定する

後で説明しますが、apexからあれこれできるようにする必要があるので、IAMのポリシーを設定します。

IAMのポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:Create*",
                "iam:Attach*",
                "lambda:*"
            ],
            "Resource": "*"
        }
    ]
}

Goで書いたプログラムをapexを使いAWS Lambdaに転送

AWS Lambdaでサポートされている言語はNode.js、Java、C#、Pythonのみですが、最近練習しているGoで書きたかったので方法を探りました。

ちょっと脇道にそれますが、最近オフィスでNetatmoを使ってco2濃度をはかって、閾値を越えたら強制的に窓を開ける活動が流行っています。東京はGoogle App Scriptでやっています。

京都では同様のことをlambdaでやっている同僚がいて、聞いてみるとapexを使っているようでした。なるほど、これを使うとGoで書いてlambdaで動かせるようです。

Goでビルドしたバイナリをlambdaに送り、それを実行しているようで、外部のライブラリに依存していても割と安心なのはいいですね。サーバー上でライブラリをインストールする手間が省けます。AWSのコンソール画面をほぼ開くことなく、apex deployでlambdaにコードがdeployされていき、apex invoke hello --logsとやるとlambdaのプロセスを叩けました。1時間もかからずお手軽。

Lambda上からAmazon Elasticsearch Serviceで検索

GoからElasticsearchを叩けるようにするライブラリを作っている人はすでにいらっしゃいました。

これを使うとやりたいことができそうですが、AWSの認証を突破しないといけません。私の場合、IPでの接続制限ではなくロールでの制限をやっているので、その情報を上述のclientに渡す必要があります。AWSがgo用のsdkを用意してくれていて、それを利用した認証情報をclientに食わせると、Amazon Elasticsearch Serviceで検索できるようになりました。

あとはこれをlambda上で動かせるようにすれば完成です。githubに上げました。

ACCESS_KEYやtokenも環境変数としてlambdaに登録していく必要がありますが、以下のようにするとそこまで面倒を見てくれます。

% apex deploy --set AWS_ES_ENDPOINT=https://search-XXX.ap-northeast-1.es.amazonaws.com --set AWS_ES_ACCESS_KEY_ID=XXX --set AWS_ES_SECRET_ACCESS_KEY=YYY --set SLACK_TOKEN=xoxp-XXX --set SLACK_CHANNEL_NAME=mackerel_search
% apex invoke hello --logs < event.json

毎回invokeしたくないので、AWSのコンソール画面からトリガー(CloudWatch イベント - スケジュール: cron)を設定しました。これで数分に一回、lambda側で勝手に起動してくれます。

MackerelのAWS連携でLambdaを監視

お決まり感がありますが、Mackerelで監視させます。MackerelのAWS連携はLambdaに先日対応したので、agentを入れることなくlambdaをMackerelにホストとして登録することができます。

read_onlyなロールを作ったらすぐ連携できます、便利。

f:id:syou6162:20170331091611p:plain

まとめ

AWS lambda上でGoを使って割と自由にコードを実行することができました。今回はElasticsearchの検索しかやっていませんが、元々はクローラーを作ってElasticsearchに結果を格納していきたかったのでした。しかし、ひとまず準備は整ったかなと思います。AWSのサービスも2つ触ったことになるし、段々雰囲気が分かってきたので勉強も進みつつあると思いたいです。勉強だけだと辛いので、自分で楽しめるやつをやっていこうとは思います。

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Javaの例外をScalaで扱う

タイトルのことを調べようとしていて、三ヶ月に同じことを調べていたのでブログにメモしておきます…。主に↓に書いてある内容以上のことはありません。前より早く理解できたり、理解が深まったりしたので、進捗していると思いたい。

Scalaの場合

Scalaの関数の場合、以下のケースが多いと思います。

  • 値が存在しない場合もあるときはOption[A]を返す
    • 例: DBから値を引いてきたけど、存在しないときはNoneを返す
  • 失敗するかもしれない処理で、失敗した場合は理由も返して欲しいときはEither[A, B]を返す
    • 例: 外部との通信で破壊的な処理が失敗するかもしれないので、Left("Could not delete user")を返す
    • TrySuccessFailureというパターンもできる

SomeRightになっているもの同士の演算は取り出してくるんで…と手で丁寧にやっていると疲れるし読むのも大変です。mapflatMapforを組み合わせると書くのも楽になるし、読むのも楽になります。Haskellの本で勉強した。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

どれを使うにしてもパターンマッチでかちっとできるのは書いてても読んでても安心できますね(特にsealed traitなどを使っている場合)。

Javaの場合

ScalaのプロジェクトでもJavaのライブラリを使うことはよくよくあると思いますが、Javaの場合は失敗するかもしれない処理でもOptionEitherを返さず例外を吐くことが多いです。以下のように、一旦OptionEitherでくるむとScalaの場合と同じように扱うことができてよさそうですね。

  • allCatch opt => 例外吐いたときはNoneにして、成功した場合はSomeでくるんで返してくれる
  • allCatch either => 例外を吐いたときはLeftにして、成功した場合はRightでくるんで返してくれる

参考

RedPenで技術文書の誤りを指摘してもらおう

自然言語の誤りを指摘してくれるRedPenを手元で使えるようにしてみました、という記事です。気が向いたので、色々書いてみました。

エンジニアであっても意外と文書を書いたり見たりする機会が多い

エンジニアとしてはてなに入社後、コードレビューをする機会はもちろん多いですが、意外と自然言語(私の場合は日本語、英語がメイン)のレビューをする機会も多いことに気が付きました。他人の書いた文書に対するレビューに限らず、自分の書いた文書に対するレビューも含みます。

自然言語も機械が勝手に間違いを指摘して欲しい

プログラムでは各言語のlinterやciのテストを通すことで、レビュー前に単純な誤りに気づくことができます。typoやsyntax errorのようなささいなことを人間がやっていると疲れるので、機械が勝手にやってくれるのはいいですね。自然言語にもlinterっぽいものはいくつかあって、例えばMicrosoftのwordなどはそうでしょう。研究論文を書いてるときに簡単な誤りはwordに投げてざっとチェックして、というのをやっていました。

しかし、技術文書をwordに投げるとうまくいかないことが多いです。私の場合、markdownで文書を書く機会が多いですが、markdownのsyntaxをwordは当然ながら解釈してくれません。markdownのsyntaxに関する赤線なのか、日本語の文法としておかしいことへの赤線なのかを人間が判断していると、これまた消耗します。私はとにかく消耗したくないのです。

自然言語もルールで分かることは機械(RedPen)に指摘してもらう

自然言語もプログラミング言語と同様に文法を持ちますが、最大の違いは曖昧性の有無でしょう。自然言語処理の大部分は曖昧性をいかに扱うかとの戦いといっても過言ではありません。自然言語処理の研究分野でも最近誤り訂正の話題は活発に議論されていて、コンペティションも開かれています。Shared taskで有名なCoNLLでも2013年にテーマになりました。

100%に近い精度を出すことがまだまだ難しいため、このように研究分野になっているわけですが、ルールでも分かる簡単なものは将来と言わず今でも指摘して欲しいです。RedPenはその要望を満たしてくれるソフトウェアの1つです。

詳しい機能はサイトを見てもらうといいですが、私がよいと感じたのは以下の部分です。

  • 様々なマークアップ言語に対応している
    • markdownを含め、LaTeXにも対応
  • 日本語や英語など様々な言語に対応
  • 必要ない指摘は設定でオフにできる
    • 「誤りと指摘されたこの箇所は自分は誤りだとは思わない」というのがよくあるパターンですが、うざいと思ったら設定でオフにできます

インストールも簡単でした。

% brew install redpen

予想通り、指摘が多かったため、設定で以下の項目はオフにしました。

  • InvalidSymbol
  • KatakanaEndHyphen
  • EmptySection

指摘例

最近書いたブログの元テキストをRedPenに流してみました。私の場合、特に一文が長い表現を書いてしまう傾向があるのですが、SentenceLengthCommaNumberで怒ってくれているのはまさにそれですね。

% redpen --format markdown --conf /usr/local/Cellar/redpen/1.8.0/libexec/conf/redpen-conf-ja.xml ~/Dropbox/_posts/2017-03-20-清算用Slack-botを書いた.md 2>/dev/null
2017-03-20-清算用Slack-botを書いた.md:14: ValidationError[SentenceLength], 文長("121")が最大値 "100" を超えています。 at line: 昔のことは忘れてしまうので、清算用のSpreadsheetを作ろうとしましたが、出先で開くのは手間なので、slackからできるといいよねという妻の声がありましたが、外部でちょうどいいサーバーを持っていなかったので、そのときは流れました...。
2017-03-20-清算用Slack-botを書いた.md:14: ValidationError[CommaNumber], カンマの数 (5) が最大の "3" を超えています。 at line: 昔のことは忘れてしまうので、清算用のSpreadsheetを作ろうとしましたが、出先で開くのは手間なので、slackからできる といいよねという妻の声がありましたが、外部でちょうどいいサーバーを持っていなかったので、そのときは流れました...。
2017-03-20-清算用Slack-botを書いた.md:14: ValidationError[DoubledConjunctiveParticleGa], 一文に逆説の接続助詞 "が" が複数回使用されています。 at line: 昔のことは忘れてしまうので、清算用のSpreadsheetを作ろうとしましたが、出先で開くのは手 間なので、slackからできるといいよねという妻の声がありましたが、外部でちょうどいいサーバーを持っていなかったので、そのときは流れました...。
2017-03-20-清算用Slack-botを書いた.md:24: ValidationError[InvalidExpression], 不正な表現 "俺" がみつかりました。 at line: 俺は好きなエディタで書きたいし、gitでコード管理したいし、何ならTypeScriptで書きたいんじゃー、と思っていたところでいいエントリを見つけました。
2017-03-20-清算用Slack-botを書いた.md:29: ValidationError[InvalidExpression], 不正な表現 "最高" がみつかりました。 at line: 最高です、IDEAでリファクタリングや定義元に戻るとかもできるようになったので完璧です。

EmacsからRedPenを使う

Emacsで技術文書を書くことが多いので、Eamcs内からRedPenを叩けるとよさそうですが、すでに作っている方がいらっしゃいました。

作者の方がインストールの手間が省けるように、ディフォルトでは(作者が立てた)Herokuサーバーを見に行くようになっています。私の場合、オフラインで動いて欲しいことや社外に出すとまずい文書でも動いて欲しいということがあるため、設定でローカルのRedPenを見に行くように変更しました。

(el-get-bundle karronoli/redpen-paragraph.el)

(define-key markdown-mode-map (kbd "C-c C-r") 'redpen-paragraph)

(defvar redpen-commands
  '("redpen --format markdown --result-format json2 --conf /usr/local/Cellar/redpen/1.8.0/libexec/conf/redpen-conf-en.xml %s 2>/dev/null"
    "redpen --format markdown --result-format json2 --conf /usr/local/Cellar/redpen/1.8.0/libexec/conf/redpen-conf-ja.xml %s 2>/dev/null"))

(defvar redpen-paragraph-force-reading-whole t)

これでC-c C-rで校正の結果が出てきて、編集すべき箇所にすぐに飛べるようになったので、快適になりました。

まとめ

機械で指摘してくれる箇所は機械にやってもらって、人間はもっと本質的なところを考える時間を増やしていきたいですね。

理科系の作文技術 (中公新書 (624))

理科系の作文技術 (中公新書 (624))

家庭内財政会議を開きました(2016年版)

2016年はとっに終わっているという声は聞こえない…。昨年の様子はこちら。

前提

30歳サラリーマンで京都で夫婦で共働き(子どもなし)です。今のところ財布は別々にしていて、家賃光熱費等の共通出費の用途には別途口座を設けています。お金を貯めるために普段の生活をめっちゃ頑張りたいわけではなく、外食もまあまあ多く、時には散財もしたい(apple watchも買ったし、iPadの一番でかいやつも買ったし、何ならswitchも買った)という感じです。しかし、新卒の最初の2-3年ほどは自分の収入と支出がいったいいくらなのかを全く考えずに過ごしていて、さすがにこれではいかんだろうと思い自分の財政状況を確認し出しました。結婚もしたので年に一度妻と一緒にそれぞれの財政報告会議を開き、将来の計画等について話す機会を作っています。

リタイヤ後にまあまあな生活をするためにはX000万必要そうなので(金融機関がぜったい教えたくない 年利15%でふやす資産運用術を元に計算)、年に100万程度を3.5%程度で株式/投資信託/債券/年金で運用という計算を立てています。3.5%のところはインデックス投資や10年の国債を買っていて、変にブレまくることはないので無駄に売買して取引コストがかからないように気を付けよう、程度しかやっていない(NISAは一度も売却していない)。それぞれのアセットにどの程度投資するかは、以下のエントリに書いています。

資産の時系列推移

2014年末からMoney Forwardで自分の口座や収入、支出を見るようになりました。推移は下の図の通り。Money Forwardで記録し始めた前後でNISAや確定拠出年金が開始しました。何となく縦軸の数字は隠していますが、エントリを読んでいくと大体想像が付く…。

f:id:syou6162:20170317073310p:plain

2016年は4月からはてなに転職したので、その前後で資産総額がぐらついています(退職月は手取りが少なく翌月には退職金でがっと増えた)。はてなに入社後は順調に資産総額は増えているのでいい感じかなと思います。前職時代は手取りが少なくボーナスでがっと増えており、年間で見ると増えている状況でした。

企業型確定拠出年金で毎月一定額が年金に行く関係で資産に占める年金の割合が多くなってきたのが2016年の大きな特徴でした。年金なので今すぐ使えるわけではないですが、税制面で圧倒的に優遇されているため今後も続けていこうと思います。企業型確定拠出年金での投資が増えているので、NISAは以前よりは額を抑えめでいこうかなと思っています。総額で年間100万投資できればよかろう、という目標なので。

収支

支出

絶対額は書かないですが、額の大きな項目を上げていきます。項目はMoney Forwardの項目をそのまま使っています。

家賃はやはり一番大きな支出の項目であり、固定費なのでなるべく下げたいですが、会社から遠いと疲弊するし狭すぎるとつらいので難しいですね…。今は通勤時間15分で自転車通勤なので、ギリギリまで寝られて満員電車で疲れることもなく快適です。家賃は支出の約3割を占めていました。収入がめっちゃ増えない限りは絶対額はなるべく増やしたくない…。

食費は次に大きい項目でしたが、はてなに入ってお昼がまかないが出たりTGIFで会社で飲み食いすることも増えました(技術勉強会のあとに寿司も出る)。その結果、食費の支出は昨年の60%まで削減されていました。マジか。

3番目に大きな項目が奨学金で、どうしようもないとはいえ毎月あるのは辛いですね。学部と修士で借りていたので、まだまだ7桁あります。幸い無利子なので、じわじわと返していきます。

特別な支出が4番目でこれは主に散財項目。apple watch、ipadやswitchなどがここでした。昨年と大体同額ペースできていましたが、年末に調子に乗ってapple watchやipadを買ったため、去年よりも増加した項目です。

教育・教養が5番目にきていて、これは主にAmazonの本の購入です。はてなに入って色々勉強しないといけない項目があるので、それ関連の本を買ったのと後はマンガが多い。

収入

ここも絶対額は書かないですが、前職時代よりは毎月の手取りは増えました。加えて、毎月の企業型確定拠出年金があるので、いい感じでした。

その他

ふるさと納税

2016年もふるさと納税を行ないました。2016年からワンストップ納税ができるようになっていたにも関わらず、すっかり忘れていて先週税務署に行ってきましたが。絶対額は大きくないですが、税金控除があるので、2017年もふるさと納税はやっていこうと思います。ちょうど昨日お刺身が届いたところでした、うまかった…。

共通口座の残高の監視

家賃振り込みを忘れると恥ずかしいことになりますが、定期的に見に行くのは面倒です。家賃口座を定期的にプログラムでクロールしてきてmackerelのサービスメトリックに登録するようにしました。残高が家賃を下回ったらslackに通知がいくので急いで入金するというプロセスができました。

清算用botの作成

家庭用の清算君(Slack bot)をGoogle App Scriptで書いた + TypeScript化した

こんな話です。大体は先人の真似っこ。

  • 家庭用の清算をGoogle Spreadsheetでやりたい
    • Spreadsheetを出先で開くのは手間なので、slackからできるといいよね
  • slackからSpreadsheetに書き込んでくれる君を作ろう
    • 外のサーバーでやるのも面倒だからGoogle App Scriptでやろう
  • Script Editorで書くのダルい、自分の好きなエディタで書きたい
    • ローカルで書けるようにして、ついでにTypeScript化した

TypeScriptの簡単な練習をしたい感じだったので、ちょうどいい練習になった気がします。

家庭用の清算をGoogle Spreadsheetでやりたい

現在、妻と家賃用口座以外は財布が別なので、定期的に清算をしています。昔のことは忘れてしまうので、清算用のSpreadsheetを作りました。出先で開くのは手間なので、slackからできるといいよねという妻の声がありました。しかし、外部でちょうどいいサーバーを持っていなかったので、一旦話は流れてしまいました…。

slackからSpreadsheetに書き込んでくれる君を作ろう

最近チームでid:daiksyさんがslackでKPTをSpreadsheetに入力できるkpt君(bot)を作っていました。これはGoogle App Scriptで動いているので、外部に自前でサーバーを持つ必要がありません。

これいいじゃん、ということで清算用botも真似させてもらって作りました。1時間もかからずできて快適。KUMAOはうちのぬいぐるみの名前です。

f:id:syou6162:20170320211958p:plain f:id:syou6162:20170320212003p:plain

Script Editorで書くのダルい、自分の好きなエディタで書きたい

簡単にできるようになったのはいいのですが、Google App Scriptのscript editorで書くの、めっちゃダルいです。俺は好きなエディタで書きたいし、gitでコード管理したいし、何ならTypeScriptで書きたいんじゃー、と思っていたところでいいエントリを見つけました。

最高です、IDEAでリファクタリングや定義元に戻るとかもできるようになったので完璧です。できたものも公開しておきます。

自宅のElasticsearchとKibanaをAmazon Elasticsearch Serviceに引越し

例のごとく簡単なことしかやっていないのであまり参考にならないかもしれないですが、アクセスポリシーや自宅からどうやってAmazon Elasticsearch Serviceにデータを流すか、kibanaで閲覧するかは参考になる人がいるかもしれません。前置き終わり。

なぜMac MiniからAmazon Elasticsearch Serviceへ?

約二年前から自分に関連する可能な限りの情報(お金や位置情報、作業時間などなど…)をElasticSearchに放り込み、kibanaで可視化や検索がさっとできるような環境を自宅のMac Miniで運用していました。

そんなわけで二年ほどMac Miniで運用していましたが、以下のような理由で移行を考えてました。

  • Mac Miniも大分古い(5-6年前に買ったやつ)ので、そろそろ買い替えたい
    • SSDではなくHDDなので今となってはつらい。地獄かよ
    • 新卒入社直後だったので、金なしだった記憶がある…
  • ElasticsearchおよびKibanaのバージョンを上げたい
  • 仕事でAWS連携をやっているにも関わらず、個人ではAWSをほとんど使ったことがなく割と(かなり?)まずい
    • 使い勝手とかどういうメトリックが欲しくなりそう、というのは自分もドックフードしてみないと分からない

Mac Miniを新しく買い替えるのが一番無難でコスパも最終的にはよい気がしたのですが、ずっと個人でAWS使ったことないっていうのはどうなのか…というのがひっかかったのでAWS上で運用することにしました。EC2を借りて、そこでElasticsearchやKibanaをインストールして、というのでもよかったのですが、自分の性格的に色々できる環境だと色々やりすぎて本末転倒なことをやりそうな気しかしなかったので、Amazon Elasticsearch Serviceに移行することにしました。

AWSの設定

  • AWSのアカウント作成、クレジットカードの登録
    • MFAを有効化
  • グループの作成
    • Elasticsearchの読み書きができればいいので、AmazonESFullAccessのポリシーのみを持つグループを作りました
    • kibanaもダッシュボート等の情報を保存する必要があるので、readだけなくwriteの権限も必要

Amazon Elasticsearch Serviceの設定

  • Create a new domainで新しいドメインを作る
    • elasticseachのバージョンを選択。新しいのを使いたかったので、5.1を選んだ
  • Configure clusterでインスタンスのタイプを選択
    • elasticseachの5.1を選ぶにはmicroではなく最低でもsmallを選ぶ必要があるということにここで気づく…
  • Set up access policyでアクセスポリシーを選択
    • IPアドレスベースかロールベースかで選べる
    • 自分の場合、自宅や会社からkibanaが見れるといいなと思ったので、ロールで制限した

こんな感じにしておきました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::XXX:user/es-manager"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:ap-northeast-1:XXX:domain/YOUR_DOMAIN/*"
    }
  ]
}

これでElasticsearchやKibanaが立ち上がります。といっても立ち上がってくるまで20-30分くらいかかった気がする。アクセスポリシーを変更してそれが反映されるのも同じくらいの時間がかかるようです。

データを流す先をMac MiniからAmazon Elasticsearch Serviceに変える

自宅のMac Miniでは大体のタスクは

  • jenkinsでjobがキックされる
  • データ取得元からクロールする
  • 取ってきたデータをcurlでElasticsearchに流し込む

といった流れで動いていました(nasne残量の例自宅の回線速度を取る例)。例えばruby speedtest_logger.rb | curl -XPOST localhost:9200/_bulk --data-binary @-のエンドポイントをAWSに向ければ終わり、という予定でいましたが、アクセスポリシーの関連でそのままcurlでやるのは難しそうでした。aws-sdkを使うと対応できそうな雰囲気がありますが、Elasticsearchに流し込むプログラムはbash、ruby、perl、pythonと多岐に渡り(どうしてこうなった…)、流し込むjenkinsのjobも50程度まで増えていたので、困りました…。自宅も固定IP環境ではないので、IPのアクセスポリシーでやると運用が難しい。ここが一番時間がかかった。

先人の知恵を調べたところ、proxyを立てて、そこを通すという手が簡単そうでした。goなので簡単にビルドできる。go1.5じゃないといけないのが面倒といえば面倒ですが、割とすぐできる。

これでlocalhostでAWS上のElasticSearchが見えるようになりました。ruby speedtest_logger.rb | curl -XPOST localhost:9200/_bulk --data-binary @-とやっていたプログラムもポート番号を変えればよいだけなので、簡単に対応できます。これでデータはAmazon ElasticSearch Serviceに流れるようになりました。

kibanaも見れるようになりましたが、しかしちゃんとは動いていないようでした(jsが4xxのエラーを吐いていて管理画面が真っ白)。これについてもnodeでproxyを立てて解決する、というのをdockerに作っている人がいたので、それを使うと動かせるようになりました。

環境変数でawsのkeyを渡します。

docker run -e AWS_ACCESS_KEY_ID=XXX -e AWS_SECRET_ACCESS_KEY=XXX -p 9200:9200 rlister/aws-es-kibana search-XXX.ap-northeast-1.es.amazonaws.com

kibana5だ、わいわい。

f:id:syou6162:20170319151121p:plain

各種情報をMackerelで見れるように

Amazon ElasticSearch Serviceの管理画面からは検索可能なドキュメント数やディスク残量などが分かるようになっています。

f:id:syou6162:20170319151425p:plain

しかし、普段はMackerelのダッシュボードを見るようにしているので、見る画面が増えるのは面倒です。mackerel-agent-pluginsを使って、同じ情報をMackerelにも登録しましょう。

mackerel-agent-pluginsはMacには公式対応していませんが、それぞれのプラグインはMacでも簡単にビルドして使うことができます(正確に言うと使えるものもあります。elasticseachは大丈夫)。GOPATHに移動してbuildするとよいです。

% cd go/src/github.com/mackerelio
% git clone https://github.com/mackerelio/mackerel-agent-plugins.git
% cd mackerel-agent-plugins/mackerel-plugin-elasticsearch
% go build

./mackerel-plugin-elasticsearchで動かしてみるとよいでしょう。これで準備は終わったので、設定ファイル(/usr/local/etc/mackerel-agent.conf)に書きましょう。ひとまずこんな感じで書きました。

[plugin.metrics.elasticsearch]
command = "/Users/yasuhisa/go/src/github.com/mackerelio/mackerel-agent-plugins/mackerel-plugin-elasticsearch/mackerel-plugin-elasticsearch -port=9876"

agentを再起動するとちゃんとメトリックが取れるようになっています。これでディスク残量等も監視できるようになって安心ですね。

f:id:syou6162:20170319151543p:plain

AWS童貞を卒業したので、暇ができたらlambdaでbotを作って遊んだりしてみようと思います。