SKYROCKETING WORK!

日常のエントロピーを上げてくぞ🚀

カリタのコーヒーメーカーはいいぞ

カリタのコーヒーメーカーはいいぞ。

コーヒーメーカーを知らない人のために、念のために下記にWikipediaへのリンクを貼っておく。

ja.wikipedia.org

ようは自動的にコーヒーをいれてくれる小型機械みたいなものだ。
コーヒー専用炊飯器みたいなもんである。

コーヒーメーカーには様々な種類があって、全自動コーヒーミルつきやら容器が分離されてるものやら、たくさんある。

自分はそれなりに美味しいコーヒーを如何に簡単に淹れるか、淹れた後の後処理を如何に少なくするかにこだわってきた。
そのため、数十秒で挽いた豆から淹れられ、処理も楽なエアロプレスを使っていたこともあった。

エアロプレス コーヒーメーカー

エアロプレス コーヒーメーカー

  • メディア: ホーム&キッチン

これを使ってると、豆を富豪的に使ってる気がして、もう少しちゃんと淹れてみようという気が湧いてくる。

そのため、コーヒーメーカーの世界に入門したのだが、はじめに使ったのは全自動ミルつきで容器が一体となっているタイプだった。 これはとても楽に見える、なんてたってコーヒー豆を淹れたら放置しておくだけでコーヒーができるのだから。

しかし、現実は違っていた。

容器が全自動でミルを挽いてくれ、かつ容器が一体型になっているタイプは、なんといっても掃除が面倒なのである。
飲んだ後にコーヒーメーカーを分解して、ミル&ドリッパーの掃除(ここで使いおわった豆の処理をするのがなんと言っても面倒)をし、容器の掃除をして乾かして組み立て直す...。

掃除の時間も勘案するとハンドドリップで淹れた方がかける時間が少ないんじゃないかと思ったほどである。
使いおわった豆はペーパーフィルターごとポイして、ドリッパーと容器をサクッと洗えば済むからね。

コーヒーメーカーの掃除の面倒くささを知った僕は使う頻度が減っていたのだが...、ある時ふと「掃除が簡単なコーヒーメーカーはないのか?」と思うようになった。
そこでたどり着いたのがカリタのコーヒーメーカーである。

Kalita コーヒーメーカー ブラック ET-102

Kalita コーヒーメーカー ブラック ET-102

  • メディア: ホーム&キッチン

商品の写真を見ていただけるとわかるのだが、このコーヒーメーカーはドリッパーとコーヒーサーバーが物理的に分離されている。
そして、ドリッパーの上にはコーヒーフィルターをおいて使用するようなのである。

これだけで、もはや僕にとって天啓なのである。

また、試しに買うにしても、定価は5000円であったが自分が買ったタイミングでは3000円程度になっており、失敗しても財布へのダメージは大きくないことも購入に踏み出す後押しした。

と、まあ、購入したのであるが感想としては、「最高。」の一言である。

まさに怠惰な人間が「面倒なことをしたくないけど、それなりに美味しいコーヒーは飲みたいんだよな。」などとのたまえば、「我儘も大概にせえよ」と一蹴されそうだが、このカリタのコーヒーメーカーならば叶えてくれるのである。

そして、プログラマの三大美徳に「怠惰」「短気」「傲慢」というのがあるが、

  1. 「コーヒーを淹れることにまつわる面倒な作業を簡略化してくれる」という点で怠惰さ
  2. 「コーヒーを入れる時間を節約してくれる」という点で短気さ
  3. 「インスタントコーヒーではない豆から淹れたコーヒーを飲める」という点で傲慢さ

を満たしているため、プログラマの方にはマッチする一品なのではないかと思う。

何を書いているのかわからなくなってきたので、これで終わりです。
大事なのでもう一度、カリタのコーヒーメーカーはいいぞ。

Linuxbrew - sudoを使えないLinuxのユーザがPackageを管理するための魔法の杖

拝啓 Linxubrew様、私はあなたに命そのものである時間を助けられました。
ここに感謝の手紙を記します...。

docs.brew.sh


という冗談はさておき、Linuxbrewというパッケージ管理ツールを紹介する。

LinuxbrewとはMac OS Xでは有名なパッケージ管理ツールであるHomebrewのLinux版という位置づけのものである。

しかし、考えてほしい。
Linuxの各ディストリビューションには、デフォルトで著名なaptやyumなどのパッケージ管理ツールが入っている。
そのため、このパッケージ管理ツールはいったいどこで使うのだろうか...?と思ったりしていた。

なんと、使い所は意外なところにあったのだ。

LinuxbrewのWebサイトのキャッチコピーを引用する。

It can be installed in your home directory, in which case it does not use sudo.

おわかりいただけただろうか。
Linuxbrewはsudoを使わずに、ホームディレクトリにインストールをすることができる。

セキュリティ上の理由などで学校や会社で使えるユーザにroot権限が与えられていないというのはよく聞く話である。
それゆえに、「apt-get sudo なし」やら"How to install packages in CentOS without root user?"。で検索し、あまりの面倒さに環境構築で途方に暮れるなんて経験はしたことがないだろうか。

Linuxbrewは、この問題を解決する魔法の杖である。
sudoが使えないユーザであっても、パッケージ管理をすることができる。
コマンドひとつでパッケージをインストールをすることができるようになるのだ。

インストール方法はWebサイト内にも書いてあるが、こちらにも日本語の解説とともに記しておく。

## install用スクリプト、sudoが使えなければ諸々のファイルなど~/.linuxbrew下にインストールされる
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

## ここからはsudoが使えない前提で書いておく

## brewが吐き出す環境変数を読み込む
test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)

## 環境変数を読み込むコマンドを.bash_profile (.profile) に書き加えておく
# CentOS/Fedora/RedHat
test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile

# Debian/Ubuntu 
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile

以上の手順を踏むと、brewコマンドが使えるようになっているはずである。

brewとそのまま打ち込んで実行すると、以下のような基本的な使い方が出てくる。

Example usage:
  brew search [TEXT|/REGEX/]
  brew info [FORMULA...]
  brew install FORMULA...
  brew update
  brew upgrade [FORMULA...]
  brew uninstall FORMULA...
  brew list [FORMULA...]

Troubleshooting:
  brew config
  brew doctor
  brew install --verbose --debug FORMULA

Contributing:
  brew create [URL [--no-fetch]]
  brew edit [FORMULA...]

Further help:
  brew commands
  brew help [COMMAND]
  man brew
  https://docs.brew.sh

Linuxbrewを使えば、sudo利用できずとも快適なパッケージ管理ライフを楽しめるようになることだろう、きっと。

NAISTに入学してからもうすぐ3ヶ月が過ぎます。

このエントリは社会人学生 Advent Calendar 2019 - Adventarの22日目の記事です!

自分は今年の9月末に退職をして10月からNAISTで修士課程に在籍して自然言語処理をやっている元社会人学生です。
本エントリでは1クォータが過ぎての感想です。

NAISTでの生活はどうか、講義や研究はどうなのかみたいな、特に聞かれてもいない「元気にやってますか?」への解答を語ります。
会社をやめて修士課程に入ろうかと考えている人の参考になったら良いなと思います。

ちょっとポエミーな文章になっていますので、ご注意を。

ここまでのあらすじ

入学数日後に書いた意気込みと合格体験記、退職エントリの入り混じったポエムです。
www.skyrocketing.work

NAISTで過ごして1ヶ月が経ち、興奮冷めやらぬまま書いた近況報告です。
www.skyrocketing.work

本題

約3ヶ月を振り返ってみてどうだったか。

引き続き、入ってよかったなと思っています。
1mmも後悔の感情が湧くことなく、本当に楽しく過ごしています。
むしろ、もっと早く入りたかったなという気持ちでいっぱい。

けれども、これは3年間のWeb Developer経験があったからこその感情でもあると思っているので、縁だと思うことにしてます。

講義が始まってから急激に忙しくなり、目の前の調査や勉強をやり遂げるのに必死になっていた気がします。
特にクォーターの後半に入ると、レポートの量が増えたり、講義の内容と課題の内容も難しくなったり、試験対策がはじまったりと非常に慌ただしい毎日でした。
この1クォーターはマラソン大会であっぷあっぷしながらなんとか走り抜けたような感じです。

忙しすぎて研究室にひたすらこもってた時期のツイート

しかし、振り返ってみると「もう3ヶ月が経ってしまったのか...。」という気持ちと、「まだ3ヶ月しか経ってなかったのか。」という驚きが入り混じった複雑な感情が渦巻いてることに気が付きました。
前者の焦燥感のような気持ちは、「これが3回続くだけで1年が終わってしまうのか。」という不安です。
本当に研究成果が出せるのだろうか、卒業後に自分が進みたい道に進めるのだろうかという不穏な気持ちが渦巻いています。

一方で、後者の驚きというのはたった3ヶ月で自然言語処理や機械学習、その周辺分野の知識を現在の状態までキャッチアップ出来たことに対する期待感です。
おそらく、これは独学で続けていたら成し得なかったことだろうと思っているからです。

そこで1クォーターが終わったいま感じている大学院に入学して「よかったこと」と「不安に思っていること」を綴りたいと思います。

良かったと感じたこと

働いているとき以上に知識の拡張をできている実感がある

講義や研究、そして環境、それに捧げることのできる時間のおかげもあってか、働いているとき以上に知識の拡張をできていると感じています。
自分はCSを専攻してきていないのもあってか、講義を受けるだけでもはじめて知る知識が多く、また講義の課題を通して「はじめて○○を実装してみた」といったこともあり、刺激的な毎日をを送っています。*1

そして、なんといっても研究をするために専門領域の学習や調査にひたすら時間を注ぐことができるのが大きいです...!
というのも、先行研究を読みすすめると自分が全く知らない要素技術に出会う機会が非常に多いです。 *2
それにぶつかるたびに、内容を理解しようと要素技術に関してググったり本を参照したりして必死にキャッチアップするといったことを繰り返してきました。
そのおかげもあってか、わからなかったことがわかるようになっていることに気がつく機会が増えたり、「あ、これはXXXで知った内容だ!」と気がつく機会があったり、学習したことが知識がしっかりと積み重なってるんだなぁという実感が湧くようになってきました。

3ヶ月という短期間で、これを実感できたのは注ぐことのできる時間いざとなったら相談できる研究室の環境のおかげだろうと感じています。

刺激を受ける環境に身を置くことができる

研究室とはすごいもので、その専門領域に関して非常に詳しく濃い方々が近くに集まっているんですよね。
そして、そんな場所で皆がその領域で新しい貢献を生み出そうと毎日研究を進めていて、ときには相談をしあったり、ときには切磋琢磨をしあえる環境なのです。
刺激を受けないわけないですよね...!

不安になっていること

後悔は特にないのですが、不安がないかと言われたら少しはあります。
大別したら2つ。

  • お金の話
  • 時間の話
お金の話

仕事を辞めて学生になっているので、もちろんお金は不安です。
現在でも週に数時間程度のリモートワークをして収入を得ておりますが、働いていた当時に比べれば収入はとても減ってしまっています。
そこに加えて、大学の学費などが積み重なってくることを考えると、覚悟はしていたもののどうしても不安感は拭えません。

また、博士課程にも進学するとなれば、これはより悩ましい問題になるんだろうなと考えています...。
数億円とか降ってこないかな...。

時間の話

これは進路に関わった話です。
実際に大学院に入ってみて、すごく楽しい毎日を送っています。
まだ調査の段階であって具体的な進捗が出ているわけではないのですが、この分野の研究をすることに楽しみを覚えています。
それもあってか、博士課程を少しずつ考えるようになってきました。

けれども、先にあるような収入の問題を考えると学振を狙うか給与のいただける研究室(基本的には海外...?)にいかねばならないなぁと考えています。
そのためには、研究の成果を出す必要がありますし、GPAのために良い成績を取らねばなりませんし、もっと英語を使えるようにしなければならないといった数々の課題を抱えております...。
それもあってから、最近はよく「時間が足りないなぁ...。」と思うことが非常に多くなりました。

なんにせよ、すべては努力と計画、工夫で解決せねばなぁと思っており、目標のための計画を立てつつ毎日の行動を最適化して1分1秒を大切に過ごしていこうと思います。

やっていき

ちなみに、研究としてはこの分野で頑張っていくつもりです。

www.skyrocketing.work

気になることやらなにかあれば、@otakumesiまで連絡をどうぞ。
研究の話でも学校やNAISTの入試の相談でも、気軽に話しかけてください!

*1:例えば、因子分析や線形動的システムをnumpyだけで実装したのははじめての経験でした。

*2:投稿されてる論文はなんにせよ新規性のある提案をしようとしているのだから当然といえば当然である。

"Canonicalizing Open Knowledge Base"とはなにか、そしてその可能性。

この記事は自然言語処理アドベントカレンダー 2019その2)の18日目の記事です。
昨日はid:sh111hさんの10年前 (2009年) のACL論文を紹介する - エイエイレトリックでした。

はじめに

Canonicalzing Open Knowledge Basesというタスクをご存知でしょうか。
本記事ではいくつかの論文を例にざっとこのタスクを紹介していきます。

Canonicalizing Open Knowledge Basesってなに?

Galárraga et al.の"Canonicalizing Open Knowledge Bases"に端を発する、Open Knowledge BaseのEntityとRelationを正規化(canonicalizing)していくタスクです。*1
(Entityは固有名詞などの何かを表現した名詞で、Relationはis-aやhas-aのようなEntity同士の関係を表現したものです。)

そもそもOpen Knowledge Baseってなに?

Open Knowledge BaseはOpen Information Extraction(以下、OpenIE)によって出力されたTripleからなるKnowledge Base(以下、KBと略)のことです。

入力された文書から(主語フレーズ, 述語フレーズ, 目的語フレーズ)という形式のTripleをTupleとして抽出して、それを(Entity, Relation, Entity)として捉えてEntity間のRelationを得るタスクです。

そして、OpenIEの抽出結果であるTripleはKBのように捉えることができ、これをOpenKBと呼んでいます。

OpenIEについて詳しく知りたいという方は次のブログエントリや論文がとてもわかりやすいので見ていただければと適宜参照していただければ...!

Knowledge Baseって...?

Knowledge base - Wikipediaから引用させていただくと...

Knowledge Baseはコンピュータシステムによって利用される複雑な構造化、あるいは非構造化された情報を記憶する技術。

とのこと。

つまり、Entity同士をRelationで結んで知識でネットワークを作れるように記録し、これをコンピュータから扱えるようにしているものです。

代表例としては、DBPediaWikidataFreeBaseYAGOなどのプロダクトがあり、これらはOntological KBと呼ばれています。

Open KBの可能性と問題

Open KBはOntological KBとどう違うのでしょうか。

Entity同士をRelationで結んで知識のネットワーク構造を作るというKBとしての機能は同じです。
しかし、OpenKBは成り立ちが根本的に異なるため、Ontological KBに比べて変化に強く柔軟であるという強みを持っています。

Ontological KBの多くがコミュニティや団体によって、Wikipediaなどのソースを元に更新していくことで作られています。
なので、アプリケーションで利用中のKBが新しい情報を取り入れるためには、以下のようなプロセスを経る必要があります。

  1. ソース元の更新
  2. コミュニティによる配布
  3. 配布されたKBの導入

一方で、OpenKBはOpenIEに文書を入力することで得られる出力であるTripleから構成されます。
つまり、OpenKBは保有している文書が更新されていていれば、OpenIEを実行するだけで新しい情報を取り入れることができるのです。

この側面だけ見ると、OpenKBが夢のような手法のように見えてきますが、もちろん課題もあります。
深刻な課題の一つとして挙げられるのは、OpenIEによって得られるTripleが含んでいるEntityやRelationを表層の形のままで抽出してしまっているということです。

それによって、同じ意味を持つ語や節にも関わらず、別のEntityやRelationに認識されてしまうという課題が引き起こされます。

例えば、CESIが論文内で挙げている例をみてみましょう。
同じドキュメント内に以下の二つの文章があるとします。

  • Barack Obama was the president of US.
  • Obama was born in Honolulu.

これらが含まれたドキュメントをOpenIEに入力すると、下記のようなTripleを出力します。

  • (Barack Obama, was president of, US)
  • (Obama, born in, Honolulu)

このとき、文中ではBarack ObamaObamaは同じ人物を示しているはずですが、OpenIEを介すると別のEntityとして出力されてしまっています。
そして、これと同様の課題がRelationでも発生しえます。

こうした課題がOpenKBを実際の運用で利用するのを難しくしています。

Canonicalizingとはなにか

さきほどOpenIEの出力結果を利用すると同じような意味のEntityとRelationがダブってしまう可能性があるというOpenKBの課題を取り上げました。
Canonicalizing Open Knowledge Baseとは、この課題を解決しようというものです。

このタスクにおけるCanonicalizingとは同様の意味を持つ複数の表現を1つにまとめることだと説明できます。

つまり、先程の例を利用するとBarack ObamaObamaという二つの名詞フレーズをどちらかの表現に寄せてしまうということです。
例えば、ObamaBarack Obamaとして扱うといった具合です。

このCanonicalizingをする手法としては、現在提案されて手法の中ではClusteringを利用する方法が多いようです。

Canonicalizing Open KBの流れと現在

代表的な先行研究としては三つの論文が存在しています。

Canonicalizing Open Knowledge Base

ACM CIKM 2014のGalárraga et al.による論文。
タスクとしてCanonicalizing Open Knowledge Baseをはじめて定義しました。

Clusteringによって、Entityの名詞フレーズとRelationの関係フレーズをCanonicalizeしていく、という手法です。 EntityのClusteringでは、階層的クラスタリングを用いていてクラスタリングのための使われる類似度のためにSimilarity Functionが定義されています。
そのSimilarity Functionとは、仮説から良い特徴量空間から距離関数を選び、それらをロジスティクス回帰を用いて結合したものです。

また、RelationのClusteringでは、Galárraga et al.によるAMIEと呼ばれる統計的に包摂関係を導き出す手法を適用しています。
AMIEの出力結果を元に共通の包摂関係になったフレーズを同じクラスターとして扱って、いくつかのルールに基づいて代表的な語を選ぶことでCanonicalizeします。

CESI: Canonicalizing Open Knowledge Bases using Embeddings and Side Information

The WebConf 2018 (WWW 2018)のVashishth et al.による論文。

f:id:otakumesi:20191216210139p:plain
https://github.com/malllabiisc/cesi より引用

CESIでは、Galárraga et al. の手法をover manually-defined feature spacesであると指摘していて、学習されたEmbeddingからClusteringをする手法を提案しています。

CESIの特徴はOpenIEのTripleを活用して各フレーズのSide Informationを取得し、それを利用して名詞フレーズと関係フレーズのEmbeddingを学習するところにあります。
そして、そのEmbeddingの空間における距離をもとにClusteringをしていくアーキテクチャになっています。

Embeddingの目的関数は、Nickel et al.のHolEというKnowledge GraphのEmbeddingのlossをベースにしたものを使っています。

また、Side InformationとはでOpenIEのTripleに含まれる有用なコンテキストを利用して得られる情報です。
これは名詞フレーズや関係フレーズそれぞれで別々のものが定義されています。

CESIには、提案手法のコードや提案データセットをまとめたリポジトリが存在しているので、もう少し詳しく知りたい方はこちらへ。
github.com

CaRe: Open Knowledge Graph Embeddings

EMNLP 2019のGupta et al.による論文。

f:id:otakumesi:20191216210305p:plain
https://github.com/malllabiisc/CaRe より引用

CaReは前者二つとは、少し毛色が違っています。

というのも...
前者二つはOpenKBを入力にして、OpenKBの精度を上げることに焦点を当てています。
一方で、CaReはOpenKB自身をCanonicalizeするのではなく、OpenKBから作るKnowledge GraphのCanonicalizeを目的としているからです。

そして、CaReの入力はOpenIEの実行結果ではなくCESIの出力結果であるCanonicalizeされたOpen Knowledge Baseです。
それゆえ、これはCanonicalizing Open Knowledge Baseを拡張するモデルだとも考えられます。

また、CaReではこのCanonicalizeされたOpen Knowledge Baseをaugmented OpenKGと表現しており、このaugmented OpenKGからKnowledge Graph Embeddingを学習していくのが特徴です。

Careでは、3つのコンポーネントから構成されるTriplet Lossを用いて学習されます。
コンポーネントはそれぞれ下記のとおりで...

  1. 主語フレーズをCanonicalizeするCanonical Cluster Encoder Network(CN)
  2. 述語フレーズをCanonicalizeするPhrase Encoder Network(PN)
  3. 目的語フレーズをCanonicalizeするCanonical Cluster Encoder Network(CN)

CNはLocal Averaging Networkと呼ばれるGraph Neural Networkのようなアーキテクチャを定義し、名詞フレーズをembeddingにEncodeしています。
一方で、PNではbidirectional GRUを用いて最後に両方向の隠れ層を結合することで、関係フレーズをEncodeしています。

CaReにも提案手法のコードのリポジトリが存在するため、もう少し詳しく調べてみたい方はこちらへ。
github.com

最後に

Vashishth et al.Gupta et al.も言及しているようにCanonicalizing Open Knowledge Baseは、まだまだ未開拓な分野です。

しかし、これらの技術が実際のアプリケーションで運用が可能になったとき、様々な利益をもたらすと考えていて大きな可能性を秘めた分野だとも感じています。
(例えば、Webアプリケーションの世界ではファセットナビゲーションの作成に応用ができそうに見えます。)
そのため、自分は注目していきたいなと考えていて、アドベントカレンダーとして書かせていだきました。

自分はNLPの研究者としてはまだまだ未熟なため、間違った記述を書いてしまっているかもしれません...。
「おや?」と思うことがあれば、よければご指摘ください。

参考文献


明日のアドベントカレンダーは、mhangyoさんのウェブリードコーパスについての記事と、yusa87さんのGiNZAに関する記事だそうです!

*1:Knowledge Baseではなく、Knowledge Graphが対象となったりするがそれほど変わらない。

NAISTに入学して一ヶ月が経ったので近況報告。

正確には一ヶ月と二日経ちました。

あらすじ

特に断らない限りは情報領域の話です。

もくじ

  • NAISTはいいぞ
  • 秋入学は意外と大変
  • 学校周辺での生活について
  • 今後のTOOD

ちなみに入学エントリはこちらから。

www.skyrocketing.work

NAISTはいいぞ

本当に入って良かったなと思った一ヶ月でした。
理由はいくつもありすぎて数えることが難しいのですが、ちょこっとだけ触れていきます。

講義は難しいが楽しい

自分は今現在いくつかの講義をとっているのですが、すべてレベルが高くおもしろい。(その分、難しさもあるのですが...。)

例えば、「系列データモデリング」では、古典的な話で終わること無くseq2seqやAttentionの割と新しめのアーキテクチャまで触れたり*1しますし、「ユビキタスシステム」なども教授の研究室での研究での事例を紹介*2してくれたり、発見がたくさんで「へぇ〜!」となることがいくらでもあります。
もし、へぇボタンがあれば一回の講義で20回を使い切ることでしょう。

研究室の皆さんのすごい

自分は松本研に所属をしています。
なので、ここの話はすべて松本研での話だと思って読んでください。

研究室はとても自由な雰囲気で、自らが主体的に研究に取り組むことが重要視されています。
松本先生や博士のみなさんと相談しながらも、自分の研究したいことにひたすら打ち込むことになります。
そんな雰囲気の中で、最終的にみなさんが物凄い成果を出していく研究室です。*3
自分もそんな研究室の一員であることが恐れ多いと思いつつも、修士号を得る頃までに大きな成果を出せてるように全力で走っていきの気持ちです。

とはいえ、研究室の雰囲気はとてもゆるく、研究で迷ったり勉強会などでわからないことがあったりすれば、松本先生や博士、M2のみなさんが気軽に相談に乗ってくれ、的確なアドバイスをいただけたりします。
そして、M1のみなさんも「M1だったの!?」と焦りを覚えるほどの自然言語処理に詳しい方々ばかりで驚くことばかりでした。*4
そんな春入学のM1の方に「どうやってキャッチアップしましたー?」って聞いたりして、オススメの本やキャッチアップの仕方*5を教えてもらったので頑張る毎日を送ってます。

このようなとてつもない環境にいるのもあって、自分の自然言語処理に対するモチベーションもぐんとより一層上がりました。
いまは寝る間も惜しんで、キャッチアップに勤しんでおります。
(最近は寝ないと駄目だとわかったので寝るようにしてますが...。)

社会人経験者の学生が意外と多く、全体のモチベーションも高い

数年間働いてからNAISTに進学することに決めたという自分と似たようなバックグラウンドを持っているような方が割といます。(特に秋入学は特にその傾向が強い。)
なので、最初は年齢的に浮かないかを心配することもありましたが、それは杞憂に終わりました。*6

また、社会人経験者の学生が多いこともさることながら、大学院で専攻を変えるという覚悟をもって来ている学生もかなり多く、そういう空気もあってか全体として学生のモチベーションが非常に高い学校です。

秋入学は意外と大変

ところで、ここまでめちゃくちゃ褒めてきたのですが、入学してから大変だなと思ったことももちろんありました。
それは秋入学者にちょこっと厳し目だということです。

それは三つくらいの理由があって...

  • 秋入学はちょっと留学生向けになっている
  • カリキュラムが秋入学者に優しくない
  • 秋入学者の人が少ないので情報が少なく、相談できる人が少ない

秋入学はちょっと留学生向けになっている

NAISTには入学したての学生向けに様々な分野を浅く広くさらっていく序論講座なるものがあるのですが、秋には英語で開講されている講義しかありません。
とはいえ、春開講で取るという手もありますし、序論科目ゆえに内容は優しいため取ってしまっても苦労しないとも思います。

カリキュラムが秋入学者に優しくない

NAISTでは4月から序論科目→基盤科目→専門科目という順に、講義が開講されていきます。
なので、秋入学者はいきなり専門科目を取ることになります。

専門科目は春開講の基盤科目を履修している前提の講義であるため、前提とするレベルの高い講義ばかりです。
そのため、バックグラウンドがない方はとても苦労することになるかもしれません。
(特に数学や情報科学まわりでしょうか。)

秋入学者の人が少ないので相談できる先輩方の人数が少ない

春入学の入学者数秋入学の入学者数を比較していただくとわかると思うのですが秋入学者は少ないです。

そのため、秋入学には上記のようなカリキュラムの特殊性があるにもかかわらず、先輩方の人数が少ないため情報が少なかったりします。
なので、職員さんに聞きに行ったり、秋入学者同士で情報交換をする繋がり作るのがすごく重要だったり...。

こうして困ったことを書き連ねているものの、一年待たずに今年中に入学ができたというのは秋入学のおかげでもあり、とても感謝しています。

学校周辺での生活について

自分は大学院が借り上げて提供している中登美ヶ丘のUR住宅に住んでいます。
周辺にはイオンやスーパー、薬局、病院、美容院もあり、徒歩でも生活に全く不便することはなく、特に田舎という感じもしません。
イオンにはGUや靴屋さんもあるので、服にも困ることはないと思います。

しかし、登美ヶ丘を含めてNAISTの周辺は勾配がキツイ坂がたくさんあり、上下の差が激しい土地です。
なので、生半可な自転車は使い物にならず、車やバイク、原付、電動自転車のどれかが必要になります。
(僕は大学院まで徒歩35分くらいかけて行ってますが、そろそろキツイ...。)

そして、専門書を探しに行こうと大型書店に行こうとすると梅田のジュンク堂に行く必要があります。
そのときに、関東地方から引っ越してきた人は電車代の高さにびっくりするかもしれない...。
(学研奈良登美ヶ丘から梅田に行くのに片道820円かかるのは最初は驚いた...。)

余談ですが、近鉄奈良の周辺は息抜きにちょうどよい街だなと思いました。
ならまちが高円寺に古民家の風味を足したような街ですごく好きです。
きっとあの周辺に疲れたときの僕が生息しているかもしれません。

今後のTODO

「自然言語処理のキャッチアップをひたすらしていたら、あっという間に一ヶ月が過ぎていた...。」という気持ちがあり、もう大学院生活の1/24が終わったのかと焦りの気持ちが溢れています。
とはいえ、振り返ってみると一年前には全く理解できなかった『深層学習による自然言語処理』の内容を掴むことができるようになってることに気がついたり、意外といろいろやっていれてるなという気持ちもあり、まだ一ヶ月しか経っていないのかとも思える濃さもありました。

ここから大学院生活の本分たる研究に打ち込むためにも、しっかりとした具体的なテーマを決める必要があります。
やりたいことなるものは存在するのですが、ここから二年間で成果を繋げられそうなテーマにどう降ろしていくかを知恵を絞って考えています。

なので、自分のやりたいことに近い先行研究がありそうな、下記の領域のサーベイをしていく予定です。

  • Entity Linking
  • Knowledge Graph Construction
  • Knowledge Graph Completion
  • Knowledge Base Question Answering
  • Knowledge Base Construction

以上です。
書き散らしているので、まとまってないところもあったかもしれません。

*1:シラバスを見ていただけるとわかるのですが、

*2:これは特に人間の行動認識をする機械学習モデルで、ランダムフォレストとLSTMあたりの精度がだいたい同じくらいになっているという話とかが面白かったです。

*3:にもかかわらず、必ずしも皆さんが自然言語処理をやってきているわけではないのもすごいですよね。

*4:そして、そんな方々もNAISTに入ってから自然言語処理をはじめたという方々だったり...!

*5:レビュー論文を探し出して、関連研究を当たる...などなど

*6:ホントに年齢層も元々の分野も出身国も多様な大学院です。

退職をしてNAISTの修士課程に入学します

※これはポエムであり、自分語りです。ただただ時系列順に書き連ねていきます。
本記事は退職エントリというよりは入学エントリ、合格体験記に近いです。

TL;DR

FROM: 株式会社リブセンス
TO: 奈良先端科学技術大学院大学 先端科学技術研究科 博士前期課程

リブセンスは、9月27日が最終出社でした。

10月2日より奈良先端科学技術大学院大学(NAIST)の先端科学技術研究科の博士前期課程に入学します。
専攻は自然言語処理で、松本研に入る予定。

f:id:otakumesi:20190930124931p:plain

進学を考え始めた時の話

遡ること昨年の春過ぎ...。
この頃からコンピューターサイエンスをやりたいと考え始めていました。
それは自分が経済学部出身であることを負い目を感じていたことや、自身の未熟な技術力に対する欠乏感から湧いた気持ちだったように思います。

当時は「流行りを追い続けるのではなく、それらの技術が基礎に置いている技術を学びたい」と同僚によく相談していました。

はじめはコンピューターサイエンスを独学する方向で考えていました。
ですが、アメリカ就職に失敗したはなしというエントリ読んでから、真剣にアカデミックを考えるようになりました。
というのも、自分も海外志向で人生で一度はシリコンバレーで働いてみたいと思っているからです。

とはいえ、このときはまだ具体的に研究していきたい分野を考えておらず、それもあって具体的な進路は考えていませんでした。
なので、ググって見つけた(当時は)学費が安くて三年制だったタリン工科大学の学部や、
北陸先端科学技術大学院大学の東京社会人コースを目指そうかなぐらいの気持ちでいました。

NAISTへと進路を固めた時の話

自分はリブセンスでSEOに関わるようなチームに所属をしていて、昨年の夏くらいの当時はサイト内の検索に触れる開発していました。
そんな最中で、SIGIR2018 報告会 〜世界の検索テクノロジーとメルカリの未来〜という勉強会に参加して、その面白さに感化されて検索技術に関心を持ったのがひとつのキッカケです。
また、SEOに関わる中で某検索エンジンに課題を感じるようになってきて、それをどうにかするような研究をしたいと思うようになりました。

この辺の話は、NAISTへの道というスライドにまとめています。

そこで検索技術を学習するために掘り下げていき、たどり着いたのが自然言語処理でした。
小町守さんの自然言語処理を独習したい人のためにというページを参考に学習を進めていたことを覚えています。

実際に学習をはじめてみると、自然言語処理はすごく楽しいと思える分野であるという発見がありました。
というのも、自分はソフトウェア開発に対して、「ドメイン領域を理解して、それをシステムに落とし込むために知恵を絞る」ところに最も楽しさを感じていたので、言語学の知見や人の営みを参考にコンピューターで言語を取り扱う方法を考案するというのがとても面白く感じたのでした。

とはいえ、検索技術にしても自然言語処理にしても学習の道筋が整備されているわけではなく独学の限界を感じ、次第に大学院のような学習環境が整っている場所に行ったほうがよいと考えて進学を決意しました。

そこで、研究室を調べはじめて最終的にNAISTの松本研にたどり着いたわけです。*1
所属している皆さんのブログエントリを読んで「ここで研究できたら絶対楽しいだろうな。」と思い、第一志望に定めることにしました。

入試のための準備の日々

NAISTの入試科目は以下の通りだったので、計画的に準備していきました。

  • 数学(解析・線形代数)
  • 英語(TOEIC)
  • 小論文(主に研究計画)

途中で忙しさのあまり心が荒んでたこともあったのですが、人生で自分が乗るべきたったひとつの電車というエントリに励まされ、自分はいま乗るべき電車に乗るための荷造りをしているんだと奮いたたせてモチベーションを高めたりしてました。

数学

自身が文系出身であるため、数学が足を引っ張ることのないように最初の時期から最も力をいれていました。
まずは、マセマのキャンパスゼミシリーズを二周ほどして基礎知識を叩き込むなどやってます。

その後はリポジトリにまとまっていた過去問を何周もしました。
実際の入試は過去問と全く違う問題が出てきて、泣きそうになりましたが...。(それはそう。)
github.com

英語

TOEICなので割愛。

小論文

以下の研究計画を提出しました。

github.com

これに至るまでの経緯をば...。

研究計画を練るのに以下のプロセスを踏んでいました。
(この辺はリブセンスで施策の企画をさせてもらった経験が活きたなと思ってます。マジ感謝。)

  1. 自分の達成したい課題を明確にする
  2. それに関連する分野の動向を把握する
  3. 提案内容を考える

自分の達成したい課題を明確にする

前述したとおりに、僕には業務でSEOに関わる中で某検索エンジンに感じるようになった課題があったので特に悩まず...。
その課題とは、利用者に検索の意図を言葉にすることを強要しているために、言語化能力によって検索能力に格差が生じていることでした。

それに関連する分野の動向を把握する

その次には関連する分野を定めてレビュー論文を読むことをしていたのでした。

まずは各種の自然言語処理タスクについて学ぶことで、解決したい課題がどの分野に属しているかのあたりをつけました。
とはいえ、知識の浅い自分には限界があったため、松本研に研究室訪問をして松本先生に相談したりもしてます。

最終的には情報検索や情報抽出周りを深堀りしていくと当てをつけて各種レビュー論文を読んでました。
論文探しには、はじめはGoogle ScholararXivを使っていて、"Information Extraction"や"Infomation Retrieval"という語に、"Review"や"Survey"といった語を絡めて検索しては出てきた無料で読める論文を漁ったりしてました。
その後に松本先生にACL Anthlogyを教えていただき、論文探しの視野が圧倒的に広がったりすることもありました。

このときは2014-現在までの論文を中心に読んで、現在はどこまでできて、どこまでができないのかなにが課題とされているのかの把握することにしていました。
その上で、なにをすれば課題のどの部分にアプローチできるのかを都度判断するようにもしていたのでした。

ちなみに同時に論文を読むための基礎的な知識をつけていたりもしてて、以下の記事を書いたのもこの時期です。

提案内容を考える

最初にたどり着きたいゴールだけを定めておいて、あとはアイデア発想法を用いて考えたり、四六時中トイレに居るときも寝る直前もシャワーを浴びてるときも考えたりして、なんとか辿り着きました。
何度も書き直した覚えがあります。
最後は急に降りてきた思いつきです。
全く参考にならなくてすみません...。

リブセンスについて

本当にすごく暖かい人たちばかりの良い会社でした。

自分がとても未熟なときに入社させてもらって、そこから本当に様々な経験をさせてもらうなど大変お世話になりました!

皆さんのおかげですごく成長させてもらい、本当に本当に感謝の気持ちしかないです。
もちろん大変な時期もあったけれど、それも含めて楽しい日々でした。

そして、特に昨年末に大学院進学を打ち明けたところ、周りのみなさんが全力でサポートしてくれたりしてくれて、なんていい職場なんだと感動したりもしたことを覚えています。

僕のリブセンスに対する思いは、ワンピースのサンジがバラティエを出るときの如く「くそお世話になりました!」と叫びたい気持ちなくらいで、簡単に言葉では表現できないくらいなので本当にいい会社だったことを最後に伝えさせていただきました。

最後に

ついに入学式が迫ってまいりました...。
二年以内に実績を出すつもりで頑張ってまいりますので、応援よろしくお願いします!

*1:小町さんがまとめている自然言語処理が学べる研究室を参考にしました

ジョブ理論を読んだけれど、読み甲斐のある一冊だった

ジョブ理論を読んだ。

ジョブ理論 イノベーションを予測可能にする消費のメカニズム (ビジネスリーダー1万人が選ぶベストビジネス書トップポイント大賞第2位!  ハーパーコリンズ・ノンフィクション)

ジョブ理論 イノベーションを予測可能にする消費のメカニズム (ビジネスリーダー1万人が選ぶベストビジネス書トップポイント大賞第2位! ハーパーコリンズ・ノンフィクション)

  • 作者: クレイトン M クリステンセン,タディホール,カレンディロン,デイビッド S ダンカン,依田光江
  • 出版社/メーカー: ハーパーコリンズ・ ジャパン
  • 発売日: 2017/08/01
  • メディア: 単行本
  • この商品を含むブログ (6件) を見る

読み始めたキッカケ

一言でいえば、上司氏にオススメしてもらったからというもの。

遡ること半年と数ヶ月前の話、当時の上司との1 on 1でこんな感じの話をした。

ぼく「機械学習ってある結果を出力するモデルを開発するために、学習のためのデータを設計しますよね。例えば、映像配信サービスを例にすると、動画ページにある『お気に入り』ボタンを押された結果などを『ユーザがそれを好んだ』と解釈して、教師データにするじゃないですか。」
ぼく「でも、『お気に入り』ボタンが一部のユーザにとってはサービスの不備によって発生していたとある需要を満たすのに、たまたまそこで使えるものだったというだけだとしたらと思ったんですよ...。そしたら、その結果を『ユーザがそれを好んだ』と解釈して学習してしまうと間違ったデータが含まれていることになってしまうじゃないですか。」
ぼく「それを考えると、データをどうやって解釈するかの前に、データを収集するタイミングの体験の設計が大事になりそうな気がしているんですよね。」

上司氏「ジョブ理論っていう本を読んだことある?もしかして、新妻くんが考えていることのヒントになるかもしれないから読んでみるといいよ。」

勧めてもらった当初は、院試の最中で忙しく読めなかったが先月に院試が終わったので早速読み始めてみた。

結論から言えば、たしかにそのヒントは読み取れたので、頭に残したいところを抜き出して書き留めておく。
個人的なメモに近いので、割と主観的かつ自分の意見が混じったまとめになりそう。

語りたい項目

  1. ジョブ理論とは?
  2. ユーザストーリーについて
  3. データはすべて人為的である

ジョブ理論とは?

ざっくり言えば、人が特定の状況下にいるときに発生する課題を解決しようとする場面を「ジョブ」と定義している。
そして、すべての商品・サービスはジョブをうまくこなすために”雇用される”と考える。

本書はこの「ジョブ」という概念によって、ビジネス上の製品改善プロセスでありがちな固定観念的な視点を変革しようという試みを感じるなどした。

【ありがちな製品改善】
  • 業界の競合製品にあって、自社製品にない機能を追加する
  • 業界の標準的な指標のスペックの向上させる
    • スマホでいえば、画素数やCPU性能、メモリなど...みたいな
  • ニーズやトレンドから機能を追加する
  • ...etc
【本書の提唱する方法】
  • 顧客のジョブを見つけて、それを解決することで製品の改善を試みるべき
  • 顧客の日々の生活の中で発生するジョブをとらえて、その状況から文脈を読み解け
    • なぜ『その解決策を選んだのか』あるいは『選ばなかったのか』を読み解く
  • ジョブをとらえるには機能面だけでなく感情面や社会面も重要である
    • ジョブに対して製品が果たす役割のうち、それを使うことへの感情と他社からの視線を考えるべき、ということ。

そもそも、あるジョブを解決するのに利用されるのは自社製品が属する業界の製品だけではないはずのため...。
つまり、具体の末端である製品を始点に考えるのではなく、より抽象的な顧客の日常に発生するジョブに対して製品の持つ役割を考えよと言ってるのでは、雑に要約してみる。

ユーザーストーリー

ジョブを捉えるには、顧客がある困難に直面したときに解決しようと苦心する姿をストーリーとして描くと良い。

そのときに問うべきポイントは5つある。 - 顧客が解決したい課題はなに? - 顧客は具体的に何に苦労しているのか? - 課題を解決するのを阻んでいるのはなに? - 顧客は不完全な解決策で我慢し、埋め合わせている行動をとっているか? - その人にとっての解決策の品質はなに?そして、そのために引き換えにしていいと思うものはなに?

これらの質問は、そもそも製品に対してだけではなく、課題解決の視点に役立つと思った。
漠然とだが、研究や普段のコミュニケーションにも役に立つんじゃないかなぁというイメージ感もあるので、院に入学したあとにも本章を読み返したいと思ったりもした。

データはすべて人為的である

データが定量的なデータだろうと、人類学的な記述的データだとしても...
それは現象をある側面から切り取って表現・シミュレーションできるようにしたものに過ぎず、必ず主観的なものになってしまうという主旨。

データは収集されている時点で、すでに誰かが切り口や収集間隔、見せ方を決定していて、そこには善悪問わず「意図」が含まれているのだ。 と雑に要約。

僕はこの章に深く共感している。
それは、僕がデータの収集方法に対して、漠然と感じていた課題が説明されていたからだ。
おそらく、僕にこれを勧めてくれた上司は、ここを読ませたかったのだと思う。

この章だけでも切り取って、いろんな人に読んでもらうために勧めて回りたい気分だったので、敢えてとりあげた。

終わりに

この他にも、「ジョブを探す方法」、「顧客とのコミュニケーション方法」や「ジョブのための組織づくり」などの章もあったが、自分にはピンと来なかったため、本記事では触れなかった。 興味を持たれた方は購入 or 図書館で借りるなどしてみてはどうでしょう。
ちなみに、Kindle版もあるので、僕のような電子書籍支持者でも楽に読めたった。

冬にだけ気持ちが落ち込む「冬季うつ病」というモノがあるらしい

冬という季節、なんだか気分が落ち込んだりすることがないだろうか。

僕は冬な苦手なタイプで気分が落ち込みがちだ。

ただただ「寒い」というだけでも十分に厳しさを感じる。
心に余裕がなり、とてつもない閉塞感を感じる。
必要以上に感傷的になったり、頭が働かなくなったりする。

冬の時期に退職エントリも多いことだし、きっとこういう季節なのだろうとは思う。

ふと、なぜこんな症状になりやすいのだろうかと調べてみた。

すると、なんと冬季うつ病というものがあるらしいことを知った。
ja.wikipedia.org

冬季うつ病とは...

とりあえず、ウィキペディアからの引用。

季節性情動障害(きせつせいじょうどうしょうがい、英: Seasonal Affective Disorder; SAD)、季節性感情障害とは、うつ病のサブタイプの一つで、ある季節にのみ、体のだるさや疲れやすさ、気分の落ち込みなどの症状が出る気分障害。冬季うつ病 (Winter Depression)、季節性うつ病(Seasonal depression)ともいう。
(中略)
西洋圏や日本では一般に、秋か冬に発症し春になると治る。
(中略)
抑うつ、倦怠感、気力の低下、過眠、過食、体重増加、炭水化物への渇望がみられる。
季節性情動障害 - Wikipedia

まさに僕の症状と一致しているなー。
見当さえつけば原因を調べて対策をすればよい。
えんじにゃーりんぐである。

冬期うつ病の原因

理由は不確定で様々な仮説があるらしい。

  • 高緯度地域で発生しやすく、女性や若年者に多い
  • 冬の日照時間の減少が関係している可能性がある
  • 光の刺激が減ることでセロトニンやドーパミンが減少して、うつっぽくなる

12月〜2月の自身の生活を振り返ると、「冬の日照時間の減少が関係している可能性がある」はありそうだなーと思った。
というのも、入眠時間が普段よりも1〜2時間くらい後ろにズレていたからだ。

対策を考える

もう3月に入っていて、改善しつつある...。
とはいえ、来年も冬は来るので対策を考えたい。

【冬を避ける】
  • 赤道に近い国(シンガポール、ハワイ、インドネシア、etc...)で働く
    • いっそ、冬だけリモートワークで働く?
    • 現地企業に転職するか...
【睡眠時間が崩れない工夫をする】

概日リズムのバグが原因であるとすると、その治療法を参考にしたい。

  • カフェインなどの刺激剤を避けること
  • 昼寝を慎重に取る
  • 毎日1-2時間ずつ寝る時間を遅らせたり早めたりして調節する
  • 寝る前に酒を飲まない

なるほどー、って感じ。
忙しくなるとカフェインを19時以降もバンバン飲んでた人間なので、「オッ...、これは...」ってなってしまった。

【医学的療法もあるらしい】
  • 光療法
  • 薬物療法
    • メラトニンのタイミングを見極めた服用
  • 心理療法

とりあえず対策になりうるものを集めて並べてみた。
今後は、もう少し科学的根拠を掘り下げて調べた上で有効性のありそうなモノを選んで試したい。

参考文献

変化が激しく脆いドメインで技術的負債を増やさない設計

はじめに

ソフトウェア設計についてのポエム。
それも、ドメインが短期的なサイクルで大きく変化をしてしまうような領域での。
僕が携わる領域、つまりメディアサイトでのSEO施策を反映するシステムでの経験を念頭にしている。

結論から言えば、ビルド・アンド・スクラップを可能にしようという話です。

「変化の激しく脆いドメイン」とは?

問題の解決策のコアとなる部分が頻繁に変わるドメインのこと。
特にプロダクトのライフサイクルよりも早く変わるドメインのことを指したい。

僕が携わっている「Webメディア」というのも、この変化の激しく脆いドメインに当たると思う。
Webメディアにおける開発では、SEOやUXについて考慮することは避けることはできない。
しかし、SEOやUXは頻繁に変わるGoogleのアルゴリズムやユーザの嗜好によって正解が変わっていく
一年前に正解だったものが、次の年にはただの技術的負債になっている可能性すらあるからだ。

補足: ドメイン is 何?

少なくとも僕が表す文脈で言えば「問題領域」と訳されるもの。
以下の記事で「problem domain」と表されているものを指している。

オブジェクト指向分析 (OOA; object-oriented analysis) は、システム化の対象となる領域 (問題領域; problem domain) を対象とし、分析の対象となる問題領域に存在するさまざまな情報の概念モデル (conceptual model) を作ることを目標とする工程である。
オブジェクト指向分析設計 - Wikipedia』より

ドメインや責務の賞味期限を考えて切り分ける

設計をするとき、私たちはドメインに横たわる概念を責務として表現している。 *1
「決済」というドメインの中には、「買い物の合計額を計算する」「クレジットカード会社との取引を仲介してくれるサービスへ通信をする」などといった責務があるという具合に。

そうしたドメインや責務には賞味期限がある。
賞味期限が異なるモノを一緒にしてしまうと、本来は賞味期限が長かったモノまで賞味期限が 短くなってしまう。

変わりやすさを基準に概念に境界を引いていく

環境や状況というのは常に変化をするもので、それにともなってある時に問題だったものが問題ではなくなり、その解決策も解決策ではなくなってしまう。
時間だけでなく場所を変えるだけでも、問題が変化してしまうことさえある。
ましてや、解決策が技術的負債となって襲いかかってるくることも...。

例えば、和暦だ。
和暦は日本ローカルな紀年法で世界では使われていない。
日本で展開しているサービスで生年月日を表現する際に、その表現の解決策として和暦を使っていたとする。
そのサービスが運良く成功して海外展開をしようという時、その概念に依存して構築されたシステムは技術的負債になるかもしれない。

このような変化によって発生する技術的負債に対処するためには、概念の変わりやすさを基準にして設計を考えるといい。
ここで「変わりやすさ」を基準に、変わりやすいものを脆い、変わりにくいものを堅いとする。
ある概念を表現しようとするとき、概念を掘り下げて境界を引き脆い責務と堅い責務を切り分けましょうという話。

そうすることで、堅い責務を表現したモジュールを脆い責務の変化の影響から守れる。*2
つまり、脆い責務によって発生するシステム改修の影響を最小限にとどめることができる。

先にあげた例で説明すると「和暦は時間の表現方法の一種類に過ぎないので、時間を表す責務と切り分けて考えると良い」という話。

時間を表す責務は堅く、時間の記法である和暦の責務は脆い概念にあたる。
特に和暦は天皇の交代という短めのサイクルで変化が起こることがわかる脆い概念なので。

コードに落として考えるとしたら、時間class時間表現classを別々にすると良い、という感じだろうか。
とはいえ、時間表現は様々なバリエーションがあるコト自体がわかりきっているため、interfaceabstract class、あるいはダックタイピングの利用を検討すべきだと思う。
時間表現interfaceでアプリケーション内における時間表現の概念を定義して、それを実装する和暦表現classで計算して出力するという具合だ。

脆い概念を堅い概念に依存させる

そして、切り分けた2つの責務を組み合わせて元の概念の表現しようとするときは、脆い責務を堅い責務に依存させたほうがいい。
コード上の変更の影響は結合によって発生していて、その影響は依存関係によって各モジュールへと伝播していくので。

これも具体的に説明する。

時間という概念を表す時間class時間表現の1つである和暦表現classがいるとしよう。

Rubyの擬似コードで表すならば、以下のように設計できる。

# 時間の記法を表現する責務である
time = 時間.now
# 時間classはその代表値として西暦を使っているとする
puts time.year.to_s
#=> "2019年"

j_time = 和暦表現.new(time)
# 西暦から和暦に変換して出力する
puts j_time.year.to_s
#=> "平成31年"

# Rubyならば以下のようなメソッドを生やして型変換っぽくメソッドを追加するのもあり...かも?
# 時間#to_ja
#
# class Time
#   ...
#   def to_ja
#     和暦表現.new(self)
#   end
# end

汎用的な時間表現を西暦の時間classにもたせて、和暦表現が必要なタイミングのみに変換をするように設計する。
こうすることで、和暦表現classに新しい年号を追加するというイベントが発生しても、変更の影響範囲は和暦表現classとその利用箇所にだけとどまる。
時間classを利用している箇所には、変更の影響が及ばないはずだ。

時間class自身も、便宜上の理由で西暦を使っていて、時間表現でないと言ったら嘘になる。
とはいえ、時間を表現するためには何かで時間を代表させる必要があり、そこで西暦を選んだのは国や時間が変わっても使われているだろうという見込みが高いからだ。
和暦に依存する場合に比べて変更が発生する回数少ない堅い設計になるはずだ。

賞味期限の早いものは「捨てやすく」しよう

賞味期限が切れたモジュールは、開発の邪魔になりがちである。
いわゆる技術的負債となっていることが多い。

  • 無意味だけれど、なぜか動き続けているロジック
  • 一部の機能はほしいけれど、そこまで大きい必要がない過剰に高機能なclass
  • メディア側では見えていないのになぜか残っているコード
  • grepにたくさん引っかかる謎の動いていないコード
  • ...etc

こうした技術的負債は、回り回っていつか自分の足を撃ち抜くような事故に至る可能性がある。
また、こうした技術的負債によって、プロダクトのコード量が無駄に増え、変更の影響範囲が拡大し開発工数を増やすこともある。
そして、その存在自体が割れ窓理論的にコードの治安も悪くしがちなため、早急にご退場を願ったほうがよい。
割れ窓理論 - Wikipedia

とはいえ、そうした技術的負債も過去では金脈だった可能性もあり、様々な施策で利用されて巨大なモジュールと化し、簡単には捨てられない可能性がある。

技術的負債を捨てやすい設計にするためには、不要になる確率の高いモジュール(以下、脆いモジュール)の依存関係を最小限に抑える設計をすることだ。

脆いモジュールとは、変化の激しい領域で設計されたものであることが多い。
それは上で説明したような脆い概念の領域だ。

例えば、社内システムで職場のルールを実装する場合がここに当たるだろうか。
おそらく、ある年に作られたルールが、次の年には撤回されている可能性すらあるはずだ。

そして、脆いモジュールの依存関係を最小限に抑えるとは、「依存性逆転の原則」に従うことである。
依存性逆転の原則 - Wikipedia

というのも具体的な概念ほど脆い傾向があるため。
なので、具体的な概念に依存する必要がある場合は、それが変化することを前提にするとよい。
つまり、具体を直接使うのではなく、その抽象に依存するように設計するということ。

総務に備品の購入の申請をする社内システムがあるとしよう。
入力フォームで必要事項を記入し申請ボタンを押すと、備品の購入ルールに基づいたチェックが走ると考えてほしい。

そこで、ルールチェックclassと、個々のルールを表現した申請ごとの上限額ルールclass金額の参照元の入力ルールclassなどがあると想像してほしい。
このときに、備品購入ルールチェッカーclassは直にそれらのルールclassを実行するのではなく、それらのルールの抽象を抜き出してをinterfaceabstract classあるいはダックタイピングとして定義をして、それに依存するということだ。

Rubyの擬似コードで表すならば、以下のように設計できるだろうか。

# すべてのルールclassは、
# 抽象を抜き出すと「フォームの内容が正しいかどうかを返すという責務を負っている」とし、
# その結果を#valid?で返すというダックタイプと考えた。

class 備品購入ルールチェッカー
  def initialize(form)
    # RULESは下記のルールclassを配列にしたモノ
    # ルールclassを配列で取得できれば定数だろうがYAMLだろうがJSONだろうがなんでも良い
    @rules = RULES.map { |rule| rule.new(form) }
  end

  def valid?
    # すべてのルールの`#valid?`がtrueであれば、trueを返す
    @rules.all?(&:valid?)
  end
end

class 申請ごとの上限額ルール
  ...
  def valid?
    # 申請内の上限額が超えていないかをチェックする
    ...
  end
end

class 金額の参照元の入力ルール
  ...
  def valid?
    # 金額の参照元が正しく入力されているかをチェックする
    ...
  end
end
...

こうすることで、ある年にルールが増えたり消えたりしても、ルールclassを追加したり削除をしたりするだけで済む。
ルールclassを利用する側である備品購入ルールチェッカーclassのロジックを変更する必要はない。*3

最後に

この僕の考えは以下の書籍がベースになっている。
非常にオススメなので、本屋などでお手にとっていただければと思う。

*1:「そもそも責務ってなんだよ」という方にオススメの記事。 オブジェクト指向設計帖 巻之二

*2:モジュールという表現は、各プログラミング言語におけるclassやpackageなどのひとかたまりのコードを表している。

*3:ルールclassの配列の取得に定数を利用している場合は定数を修正する必要はあるけれど

朝倉涼子の言葉に共感できるようになった自分がいた

自分は「やらなくて後悔するよりも、やって後悔したほうがいい」という言葉が好きだ。
この格言のオリジナルがどこなのかは知らない。
しかし、ぼく自身がこの言葉を知ったのは、「涼宮ハルヒの憂鬱」の朝倉涼子の言葉だった。

涼宮ハルヒの消失 (角川スニーカー文庫)

涼宮ハルヒの消失 (角川スニーカー文庫)

(憂鬱ではなく、朝倉涼子が表紙になっている消失をあえて選びました。)

あるとき、この言葉に思いを馳せる機会に巡り合った。
そんなときに、ふと改めてこのシーンを読み返そうと思い立ったのだった。

すると、思わぬ発見があった。

というのも、朝倉涼子の言葉に共感できてしまったのだ。

中学生だった頃の僕は、間違いなくキョンに感情を移入していた。
当時は朝倉涼子の一連のセリフにピンと来ることはなかった。

けれども、いまの僕は朝倉涼子が抱えていた閉塞感がなんとなくわかるような気がしたのだ。
というのも、この朝倉涼子が紡ぐ言葉が、僕が社会に対して感じているモノと同じだったからだ。

「じゃあさあ、たとえ話なんだけれど、現状を維持するまではジリ貧になることはわかっているけど、どうすれば良い方向に向かうことが出来るのか解らないとき。あなたならどうする?」
(中略)
「とりあえず何でもいいから変えてみようと思うんじゃない? どうせ今のままでは何も変わらないんだし」
(中略)
「でもね、上の方にいる人は頭が固くて、急な変化にはついていけないの。でも現場はそうもしてられない。手をつかねていたらどんどん良くないことになりそうだから。だったらもう現場の独断で強硬に変革を進めちゃってもいいわよね?」
谷川 流 『涼宮ハルヒの憂鬱』 角川書店 [角川スニーカー文庫] 2003年

過去に読んだ本を読み返すことで「自身の趣味趣向の変化に気がつけること」に気がついた。
完全に不意打ちだっただけに、まさに『発見』だなと思った。

なんとなく、人生における楽しみが一つだけ増えた気がする。

せっかくなので、これを機に「涼宮ハルヒ」シリーズをすべて読み返したい。