太陽がまぶしかったから

C'etait a cause du soleil.

はてなブックマークタグ to Evernoteの設計と実装

はてなブックマークタグ to Evernoteの設計と実装

 Evernoteでクリップした記事にいちいちタグをふるのが面倒だからはてなブックマークで他の人が付けたタグを取り込むよ。なお本記事は以下のユーザーを対象とする。

  • Evernote APIは申請済み
  • Evernoteの使い道はクリップが中心
  • はてな語に抵抗がない
  • JavaとかPerlとか大丈夫だ。問題ない。

ノートに設定されたパーマリンク

 ブラウザからのクリップを行うと「sourceURL」という属性にURLが格納される。最近メールインターフェースを使って全文クリップしろという記事が多いが、メールで全文転送している場合は「sourceURL」が設定されないため、まず元URLを復元する工程が必要となる。自分はメール転送する際の文頭に以下のようなアノテーション領域を作成し、それを解釈して各種情報をEvernoteに復元するようにしている。

% sourceURL=http://ja.wikipedia.org %

処理対象の決定

 タグを付けたい対象は要件によって異なると思われるが、例えば一番シンプルに「タグがまだ付いておらず、sourceURLがhttp(s)プロトコルのノート」を処理対象とする場合、以下のフィルターを作成する。ちなみにEvernoteの検索窓への入力は要素を指定するような書き方も可能であるため、このフィルター文字列をEvernoteに直接入力しても取得できる。

NoteFilter filter = new NoteFilter();
filter.setWords("-tag:* sourceURL:http*");

 以上のフィルターを使用する場合、処理対象になったものの、はてなブックマークタグがなかった場合にEvernoteタグが付けられないと再度処理対象となって無駄であるため、処理終了後にフラグとしてのタグを付けるようにするとよい。

はてなブックマークタグの取得

 ノートの「sourceURL」は以下のメソッドで取得する。

Note note = getNote();
note.getAttributes().getSourceURL();

 あるエントリについて付けられたはてなブックマークタグの一覧は以下の記述法でGETリクエストを送ることでJSON形式で取得できる。詳細ははてなブックマークエントリー情報取得APIとは - はてなキーワードを参照のこと。

http://b.hatena.ne.jp/entry/json/${URL}
※${URL}は「#」を「%23」にエンコードした任意のURL。${}は実際の文字列に必要なし))

 取得したJSONデータの「bookmarks」配列の「tags」配列要素からROME等のライブラリで全体のタグ配列を取得する。処理時間に制限がある場合などに超人気エントリーを解析すると処理に時間が掛かるため、例えば取得するタグ数は最大1000個までといったサンプリングを行う。

タグ文字列の正規化

 タグの記述方法のカオスさはフォークソノミーの醍醐味であるが、そのままEvernoteに格納すると有用性の面で疑問符が付く、このため以下の手順でタグ文字列の正規化を行い、表記乱れを吸収する。処理にはCommons StringUtilsや正規表現、マップなどを使用する。

  • 記号除去
  • 全角英数の半角化
  • 半角カナの全角化
  • 大文字の小文字化(好み)

シノニムの読み替え

 シノニム辞書を作成し、正規化した文字列をマッチングして、破棄したり、好みの文字列に置き換える。たとえば「2ちゃんねる」を「2ch」に読み替えるなど。使い勝手を上げるために、ノートブック全体である程度は統一したほうがよい。シノニムを事前に補足するのは大変なので実際に取得したタグをみていってだんだんと辞書を育成することになる。

 「2ちゃんねる」があれば「2ch」も大抵あるのだが、上位N個のタグを決定する際に、表記乱れを統一したうえで「2ちゃんねる」と「2ch」のタグ数が合算されるため、表記が異なることによるタグの分散で正しい結果にならなかったということが起こりにくくなるという効用もある。

タグ数上位N個を決定

 以上までで意図するタグ配列が作成されるため、配列要素をマップに格納していきカウントする。タグセットを取得する際に該当の要素数を判定に使用したTreeSetを生成してカウント数が多い順に取得する。この時、正規化や置換によって空文字になったものはカウント対象にしないようにする。

Evernoteのノートにタグを設定

 取得したはてなブックマークタグ文字列について以下のような手順でEvernoteにタグを設定する。Guidではなく文字列でタグを設定する正式な手順は不明であるが、TagGuidsをリセットしないとノートにタグ文字列が反映されないため、一旦空リストを渡してから既存タグを復元している。タグ文字列はユーザー毎に一意になっており、既に同一文字列のタグがあればEvernote側が同一タグとして認識する。

  • 既にノートに設定されているタグ文字列リストを取得
  • Note#setTagGuidsに空リストを渡してタグをリセット
  • 既存タグ文字列リストにはてなブックマークブタグセットを追加(ノート内での重複チェックは行う)
  • Note#setTagNamesでマージしたタグ文字列セットを設定
  • ノートをアップデート

 その他、はてなブックマークをソースとしたタグには特定のプレフィックスをつけたり、特定の親タグを設定すると運用上便利になる。その辺は個々人のノートブックの形に依存するので割愛する。

ウェブページのCCDB

 以上の実装をすることで、はてなブックマークのタグをEvernoteに設定できるようになる。何を探したいかが明らかな場合は、「これは何であるか」の定義が必要となるが、クリップするときに「それが何であるか」などいちいち入力して分類に時間を掛けるというのは本質的な作業ではない。iTunesでCDを取り込めばMP3タグは自動的につけてくれる。

 これは誰かが定義してくれたものであるが、大抵はうまくいく。EvernoteはN個のタグが付けられるのだから、むしろ「自分がどう使うか」のみに集中して「追記」すればよいのだ。個々のベクトルは、「既にそこにあったもの」であり、その方向は様々であるが、自分にとって正しい方向に微調整して取り込み、また自分の視点も加えることでオリジナルとなる。

 他人の検索語をEvernoteに取り込むことで思いもよらない気づきを得ることもある。自分だけでなく、社会全体だけでなく、はてな村民という集合における視点も加えることになる。マーケット主体の経済は「これは何であるか」はトップダウンで決まっていったが、ユーザー主体の経済は「これは何であるか」はボトムアップで決まる。だから偏った集合における多数派に群集委託し、「これは何であるか」を再定義するのだ。探し物はギャンですか? 見つけにくいネモですか?

Evernote豆技50選 (Espresso Books)

Evernote豆技50選 (Espresso Books)