博士以前

人間です

2019年後半

2019年も半分が終わるので色々と軌道修正していきたいと思う。最重要課題はD論をちゃんと完成させることだけど、就職で言ってみればかなりのキャリアチェンジもするので、主にコンピュータサイエンスの初歩的な事柄も勉強したい。

  • 研究:やたらめったら共同研究を引き受けない。春先に複数の共同研究でハードなエンジニアリングを要求されて死んでしまった。今後はとにかくD論のテーマを掘ることに集中したい。

  • プログラミング:LeetCodeのTop Interview Questionsを解いてみるのがいいのかもしれないと思い始めた。

  • 機械学習:読みかけのPRMLをちゃんと読んで問題解く。積読状態のHands-On Machine Learning with Scikit-Learn and TensorFlow を読んで手を動かす。Kaggle の入門的なコースをやるのも良いかもしれない。あと機械学習ではないが、統計検定一級くらいは取っておきたい。

  • 生活:節制する。主に外食と飲み会を減らす。家計簿アプリの予算を適切に設定しきちんと守る。忙しくても週に一回は運動する。

就職について

就職先を決めたので就職活動を振り返ってみる。

企業で働くことを考えるようになったのは去年の今くらいだったと思う。研究はまあまあ面白かったし、この業界で最低限死なずに生き残っていくくらいなら出来るだろうとは思っていた。 一方で、自分の分野への興味を維持するのにエネルギーが必要になっている現状を認めないわけにもいかなかった。モチベーションを自分の純粋な興味関心から維持できないのに研究を続ける意味なんてあるのだろうかと考えるようになった。 加えて、アカデミックな世界の厳しいジョブマーケット事情もあった。海外で何年もポスドクをしているけど日本に帰ってこれないという人(それも僕なんかより全然頭が良い)をこれまで少なくない数見てきて、自分が同じような境遇でやっていけるだろうかと考えるとそれも厳しかった(僕は日本の、特に東京での暮らしが好きだ)。

そんなこともあって去年の夏〜秋頃にインターンに参加した。業界としてはいわゆるデータサイエンスや機械学習をやっている会社が親和性が高そうだと思っていて、その中でも業務として面白そうだと思ったところで少しの間働いてみた。 最初は全くやったことのない分野で苦労したけど、教科書や論文を読んで実際に手を動かすうちに段々と慣れていくことができ、思ったよりも楽しい経験ができたので、企業で働くのも悪くないなと思うようになった。この辺りから明確にアカデミアには残らず、就職をしようという意識になったように記憶している。それからインターン先の企業の一つに早々に内定を貰ったので、とりあえずこのまま何もやらなくても食いっぱぐれないという気持ちになったのは、後々就活をする上で大きかった。

経団連という謎の組織のルールがどうなっているかは知らないが、年末から2月くらいまでに合同説明会や気になる企業の説明会に参加し、3月に何回か面接をした。と言ってもすでに内定があり、本当に興味のある企業に絞ることができたのでスケジュール的にはとても楽だった。そんな感じだったので時々しかスーツを着なくて、毎回ネクタイの締め方をググったりしていた。最終的に4月頭には内定が出揃って、インターンに行った企業も含めて最終的な進路を決めねばならなくなった。

しかし、ここで今までまともに将来のことを考えてこなかったツケが回ってきた。どこに就職したいのか自分でもよくわからなくなってしまったのである。 これはインターンで早々に内定が出たことも関係していて、安心感から他の企業の詳しい業務について深く調べていなかったし、人に聞いたりもしていなかった。 朝起きたらA社の方が良いなと思っていたのに、帰宅するとB社で働きたいなと心変わりするような日もあった。 そこで何人かの先輩に連絡を取って相談したり、飲みながら社会人の友達と話したりした。自分のキャリアなるものに対して初めて思いを巡らせたりもした。 それでもまあ先日ようやく決心して内定を受け入れる会社を決めたのだけど、最終的な決め手は結局のところ「この人達と働きたい」というものだった。

人と話すと「やっぱり働きたくないでござる」みたいなことを言ってしまうけど、これまでずっといたアカデミアの世界から外に出て新しい人と関わるのは純粋に楽しみというのはある。 それに仕事内容もどうせやるなら面白いことをしたいと思って選んでいるし、楽しんでできれば何よりである。 もちろん研究だって本当に楽しいのは全体の5%くらいなので、仕事だって似たようなものだろうけれど。 研究をしていて一番面白いのは、対象について自分なりに深く潜って考えて、そこから戻ってくる時に他の人には見つけられなかった何かを持ち帰ることができた時だ。 やることは変わっても、これからもそういう体験ができれば良いなと思っている。

Gaussian quadrature で遊んでみた

はじめに

最近そこそこ大変な多重積分が必要になり Gaussian quadrature という数値積分法の威力を知りました。日本語で書かれた記事は専門的なものしかなさそうなので、概要をメモしておこうと思います。 なお数学的な厳密さは考慮していないですが、許してください。

基本的な定理

Gaussian quadrature というのは、積分  \int_a^b dx\, f(x) を、被積分関数  f(x) の重み付き和によって近似する手法です。 これの基盤になっているのは多項式積分に関する次の定理です。

 h(x)積分したい 2n-1 次の多項式とする。積分区間 ( [-1,1], [0,\infty]など) 上の、関数  \omega(x) についての直交多項式 p_n(x) とする。つまり  p_n(x)

 \displaystyle{\int_a^b dx\, \omega(x) p_n(x)p_m(x) \propto \delta_{n,m}}

を満たす多項式とする。ただし  n, m多項式の次数を表す。この時次の式が厳密に成立する:

 \displaystyle{\int_a^b dx\, \omega (x) h(x) = \sum_{i=1}^n w_i h(x_i)}

ここで  x_i p_n(x_i)=0 を満たす n 個の点 (ノードと呼ばれる) で、  w_i は各ノードに対応したウェイトと呼ばれる量である。

証明とウェイトの具体的な形は、英語版のウィキペディアに書いてあります。

Gaussian quadrature - Wikipedia

この定理のおかげで、多項式で良く近似できる関数  f(x) については積分が重み付きの和

 \displaystyle{\int_a^b dx\,\omega(x) f(x) \simeq \sum_{i=1}^n w_i f(x_i)}

によって近似できることがわかります。なお考える直交多項式によって、呼び方が微妙に変わります。 例えば  [-1,1] で直交多項式としてルジャンドル多項式を使うときは Gauss–Legendre quadrature と呼ばれ、 [0, \infty] 上でラゲール多項式を使うときは Gauss–Laguerre quadrature と呼ばれたりします。

具体例

具体的に次の3重積分を考えてみましょう*1:

\begin{aligned}
 I &= \int_0^\infty dx \int_{-\infty}^\infty dx_1 \int_{-\infty}^\infty dx_2\, x^3 f(x_1)f(x_2)f(x-x_1-x_2)\,,\\
 &\text{where}\, f(x) = \frac{1}{e^x+1}
\end{aligned}

これを Gauss–Laguerre quadrature で計算するために次のように書き換えます:

\begin{aligned}
 I &= \int_0^\infty dx \int_{0}^\infty dx_1 \int_{0}^\infty dx_2\, \sum_{j_1=\pm 1}\sum_{j_2=\pm 1} x^3 f(j_1x_1)f(j_2x_2)f(x-j_1x_1-j_2x_2)\,,\\
   &= \int_0^\infty dx \omega(x)\int_{0}^\infty dx_1\omega(x_1) \int_{0}^\infty dx_2\omega(x_2)\, 
e^{x+x_1+x_2}
\sum_{j_1=\pm 1}\sum_{j_2=\pm 1} x^3 f(j_1x_1)f(j_2x_2)f(x-j_1x_1-j_2x_2)\,,
\end{aligned}

ここで \omega(x) = e^{-x} としました。この \omega(x) [0,\infty] に対してはラゲール多項式が直交多項式になります。

あとは適当な次数のラゲール多項式を持ってきて、そのノードとウェイトを計算し、公式に当てはめれば積分計算ができます。 ノードとウェイトの計算は次数が上がるほど大変になるのですが、世の中には色々なパッケージが存在するのでありがたく使わせてもらいましょう。

解析解

なお、実はこの積分は解析的に実行することができます;

\begin{aligned}
 I = \frac{457 \pi^6}{5040} = 87.1735836238\dots
\end{aligned}

数値積分

実際に Gauss–Laguerre quadrature を使って上の解析表式を数値的に再現してみます。

コード

以下では Julia の FastGaussQuadrature モジュールを使って計算します。 試しに1次から20次までの quadrature を実行して、結果を比べてみます。

GitHub - ajt60gaibb/FastGaussQuadrature.jl: Gauss quadrature nodes and weights in Julia.

using FastGaussQuadrature

f(x) = 1.0/(exp(x)+1.0)

function integrand(x1, x2, x)
    integrand_tmp = 0.0
    for j1=[-1,1], j2=[-1,1]
        integrand_tmp += x^3 * f(j1*x1) * f(j2*x2) * f(x - j1*x1 - j2*x2)
    end
    return integrand_tmp
end

function main()
    for n in 1:20
        integ_tmp = 0.0
        nodes, weights = gausslaguerre(n)
        
        for i1=1:n, i2=1:n, i=1:n
            x1=nodes[i1]
            x2=nodes[i2]
            x=nodes[i]
            integ_tmp += weights[i1]*weights[i2]*weights[i] * exp(x1+x2+x) * integrand(x1, x2, x)
        end
        
        println("n=", n, ", I=", integ_tmp)
    end
end

main()

実行結果

n=1, I=3.695294445091779
n=2, I=61.88325249650755
n=3, I=87.32157370172439
n=4, I=87.35456973636666
n=5, I=87.22502771278617
n=6, I=87.19838277730469
n=7, I=87.1816826909689
n=8, I=87.1739737777013
n=9, I=87.17318617155999
n=10, I=87.17367651240122
n=11, I=87.17389771350166
n=12, I=87.17387417770796
n=13, I=87.17377359537485
n=14, I=87.17368240366083
n=15, I=87.17362525065808
n=16, I=87.17359768692653
n=17, I=87.17358772170228
n=18, I=87.17358557612305
n=19, I=87.1735857713404
n=20, I=87.17358607174498

20次のラゲール多項式を使うことで7桁の精度で積分値が合うことが確かめられました。 3桁程度の精度でよければ、たった n=5 の計算でも十分なことがわかります。 さらに多重の積分になった時には、台形公式を使うよりずっと効率的であろうと予測できます。*2

まとめ

まあ FORTRAN の QUADPACK やそのラッパーを使えばよいという話だけど、中身をなんとなく理解しておくのは重要だと思います。

*1:見る人が見たらわかるかもしれませんが、これは一応物理的なモチベーションがある式です

*2:本当は台形公式でもやって計算時間を比較したかった

2018年まとめ

研究

今年は論文を二本書いた。国際会議は三つ参加した。 正直D2で論文二本は少ないと思うが質はまあまあ良かったと思う。

国際会議ではヨーロッパでいろいろ遊べたのでとても充実していた。 フランスのスポーツバーでビールを飲みながら見たW杯や、スペインで毎晩バルを巡って飲んだサングリアの味はこれからも忘れられないと思う。

秋以降は就職のことを考え始めたりして研究に身が入らない時期が断続的に訪れたので、生産性が下がってしまった。反省している。 まあもともと大したものを生産しているわけではないが。

大学院に入ってもうすぐ四年だけど、未だに研究をするというのがどういうことなのかよくわからない。自分の仕事に必要な論文の調べ方とか、計算のテクニックとか、図の見せ方とかそういう技術的なことはそれなりに少しずつ身についてきたようには思う。 しかし肝心の、研究の始め方というのがまだよくわかっていない。自分がなんとなくやりたいと思っていることから、具体的な仕事になるテーマを引っ張り出すというのがまだできない。 卒業までに一つくらい自分のネタで論文を書きたいな。

就活

夏にいくつかインターンに行った。特に二週間ちゃんと給料をもらって働いたところでは色々よくしていただいて、企業で働くのもまあ悪くないかなと思えるようになった。

機械学習をするというので、とりあえずディープしか聞いたことがない僕は Chainer のドキュメントを読んだりしてから参加したのだが、結局使わなかった。代わりにインターンでは主にベイズ学習を利用して仕事をしていた。僕としてはこれがかえって良かった気がしていて、機械学習という分野の広さを知るきっかけになった。

そろそろエントリーが始まるわけだけど、自分が面白いと思えて、給料がまあまあ良くて都内勤務の会社で働きたい。私服勤務で裁量労働制ならなお良い。

僕はなんだかんだでまだ学生なので、これからまだ人生がガラッと変えられるのではないかという期待がある。特に就職して環境が変われば、何か新しいことが始まるのではないかと思ってしまう。 だから、もしそこに進んで何も変わらなかったらと考えるととても怖い。同じようなことは『宇宙よりも遠い場所』でも言っていたけど。

趣味

Vtuber

ミーハーかもしれないが、僕にとって今年は Vtuber の年だった。 毎日 Siro Channel を見て、 毎日生きる元気をもらっていた。去年まで電脳少女シロちゃんなしでどうやって生きてきたのか思い出せない。 電脳少女シロちゃん本当に可愛くてクレイジーで最高なので見てください。 某後輩系 Vtuber と違って、事務所がちゃんと出演者たちを大事にしていそうなのも安心できる。 神回を紹介しようと思ったが、全部神回なので選べなかった。

www.youtube.com

読書

あまりたくさん本を読んだわけではないが、今年初めて読んだケン・リュウにはまってしまった。 特に『Good Hunting』という短編が本当に素晴らしい。大げさでなく、人生で読んだ中で1番の短編小説だと思った。 幻想的なスチームパンクで、映像作品にしたら絶対映えるだろうなという描写の数々で、しかし短編なので話が重くなりすぎないのが良い。

The Paper Menagerie

The Paper Menagerie

音楽

Apple Music に再加入した。新しい音楽もそうだけど、少し昔の曲がたくさんあるのが良い。もっと以前に触れておくべきだったけど機会を逃してしまったような音楽を色々聴いた。 くるりとか実はあんまり聞いていなくて、Apple Music で初めて色々アルバムを聴いた。THE WORLD IS MINE が好き。

ゲーム

FGOやめたい。第二部早く完結してくれ…

人間関係

色々うまくいったりいかなかったり、どうしようもないときはなんとかやり過ごしたり、そういう一年だった。

2019年の抱負

D論

ついにD論と向き合わなければならない。とりあえず今やっている仕事をちゃんと完成させれば、それのコピペで行けるはずなので頑張る。

就活をちゃんとやる

ベンチャー系は一つ内定があるので、大企業をいくつか見て自分の適性とか色々考えたい。もちろんオファーをもらえればの話だけど。

運動をする

出張続きで生活リズムが崩れると、定期的な運動をサボってしまう。2019年は強い意志を持って臨みたい

機械学習の勉強をする

手を動かしたいのでKaggle をやるのも良いかと思ったが、ああいう答えがほぼ決まってるような問題はどうもやる気が起きない。うまい勉強方法を考えたい。

生き方

自己愛みたいなのをもっと持たずに生きていきたい。

まとめ

2018年お世話になった方々ありがとうございました。来年もよろしくお願い申し上げます。

Julia でLDAの周辺化ギブスサンプリングを実装した

トピックモデルとLDA

文書のクラスタリング手法として Latent Dirichlet Allocation (LDA) というものがある。クラスタリングというのは何らかの基準に応じてデータを(教師なしで)分類することで、LDAはトピックモデルという、各文書の潜在トピックに応じてクラスタリングを行うモデルの一つである (Blei et. al., 2003)。潜在トピックというのは、例えばニュース記事なら「政治」や「経済」「スポーツ」というものを想像すればよい。それぞれのトピックに応じて出やすい単語があるはずだし、またトピックに関係なく出やすい単語(日本語なら助詞、英語なら I, we や前置詞など)もあるはずである。また文書のクラスタリングとはいったものの、別に単語の意味に頼って解析をするわけではないので、離散的なデータになら広く応用できるのも利点の一つである。

今回は SparseLDA (Yao et. al., 2009) に基づいて、LDAの効率的なギブスサンプリングのアルゴリズムを Julia 言語を使って実装してみたので、紹介しようと思う。

Github リポジトリはこちら

github.com

LDAとは

LDAは一つの文書が複数のトピックからなっているとする混合モデルである。 ある文書のある箇所にどんな単語が入るかは次のように決まる:

  1. その文書に固有のトピック分布からその箇所のトピックを確率的に抽出する
  2. そのトピックにおける単語分布から確率的に単語を抽出する

これは二種類の(一般には)いびつな形の多面サイコロがあって、まず一つ目のサイコロを振るとトピックが決まる、次にそのトピックに応じたサイコロを選び、それを振ることで単語が決まる、これを繰り返すことで文書が出来上がるモデルだと考えれば良い。 さらにLDAはこの「サイコロ」自体もある確率分布から生成されたとモデルする。

数学的に言えば、トピックと単語はそれぞれあるパラメータを持つ多項分布によって生成され、その多項分布のパラメーター自体はさらに別の確率分布(ディリクレ分布)から生成される、ということである。 詳しい説明は以前紹介した教科書を読んでもらえると良いと思うし、いろんな人がブログで解説をしたりもしている。

predoc.hatenablog.com

通常我々が持っているのは実際の文書データだけで、トピックが何であるかはわからない(だから潜在, latent という)。 LDAを使って解析するというのは、与えられた文書の単語データから潜在するトピックを推定するということである。これはベイズの定理を使って、likelihood  p(w|t) ( t はトピックで  w は単語) から事後分布  p(t|w) を計算することに対応する。

周辺化ギブスサンプリング

LDAの事後分布は(多くのベイズ学習でそうであるように)解析的には計算できないため、色々な近似推論が行われる。 ここでは周辺化ギブスサンプリング (Collapsed Gibbs Sampling, CGS) というマルコフ連鎖モンテカルロ法(MCMC)を使った学習を紹介する。 モンテカルロ法は実際に分布から何回も何回もサンプリングをして、そのヒストグラムによって確率分布を近似しようという手法である。

LDAの事後分布は各文書の各単語に付随するトピックという膨大な数の変数を持っているので、通常のモンテカルロ法のように変数全てを一度にサンプルするのは現実的ではない。 代わりにCGSではどれか一つの変数に着目して、それ以外の変数は既知であるとして一変数についてだけのサンプリングを繰り返す。 LDAでは興味のない潜在変数を全て積分した後で(これを周辺化という)、単語  w が観測された時にそれがトピック  z=t を持つ確率は


\displaystyle
 p(z=t|w) \propto \frac{\alpha_t + n_{t|d}}{\sum_t \alpha_t + n_d} \frac{\beta +n_{w|t}}{\beta V + n_t} \equiv U(t)

となる。ここで

  •  \alpha_t,  \beta :ディリクレ事前分布のパラメーター
  • n_{t|d} :文書  d 中のトピック  t の数
  •  n_{w|t} :トピック  t 中の単語  w の数
  •  n_t :トピック  t 中の全単語数
  •  n_d :文書  d 中の全単語数

この式を見るとLDAが何をやっているかをなんとなく掴むことができる。大雑把に、積の第一項が文書 d でトピック t が選ばれる確率を、第二項がトピック  t で単語  w が選ばれる確率を表しているだろう。 もし  \alpha_t = \beta = 0 ならそれぞれの確率は単に実際に観測された割合、 n_{t|d}/n_d n_{w|t}/n_t になる。 これはつまり最尤推定をしているということで、本当の確率が小さく、またデータ数が少なかったために偶然 n_{t|d}=0 n_{w|t}=0 になった場合にそれを過剰にフィットして、ゼロを返してしまう。 ディリクレ分布のパラメーター  \alpha_t \beta はそれを smoothing して過学習を防ぐ役割をしていると考えられる。

実際のサンプリングでは  Z=\sum_{t=1}^{t=T} U(t) を計算して、乱数  u 0-Z で生成し、 \sum_{t=1}^{t-1}U(t) \lt u \lt \sum_{t}^{T}U(t) となる  t を探す、などの操作をすると思う。 この計算は我々が事前に固定するパラメーターである全トピック数  T に対して線形で、訓練用の全ての文書の全ての単語について毎回行われるため、トピック数が増えると計算量がどんどん増えてしまうことが想像できるだろう。

SparseLDA

SparseLDAというのは Yao 達が提案した、サンプリングを効率的に行うアルゴリズムで、特にトピック数に対して線形に計算が増えないという点で優れている。 まず着目するのは上のサンプリング式で、それを以下のように分解する:


\displaystyle
p(z=t|w) \propto  \frac{\alpha_t\beta}{\beta V + n_t} +n_{t|d} \frac{\beta}{\beta V + n_t} + n_{w|t} \frac{\alpha_t + n_{t|d}}{\beta V + n_t}

単に分子を展開しただけである。*1 サンプリングのためにこれのトピックに関する和を取る:


\displaystyle
Z= \sum_{t} \frac{\alpha_t\beta}{\beta V + n_t} +\sum_{t}n_{t|d} \frac{\beta}{\beta V + n_t} + \sum_{t}n_{w|t} \frac{\alpha_t + n_{t|d}}{\beta V + n_t}

この形にすると以下のような戦略を取れば良さそうだということがわかる:

  • 第一項は文書にも単語にも依存しない量なので、一回のバッチ学習を通して同じ値を使うことができる。*2
  • 第二項の和の中の  n_{t|d} の係数も文書や単語に依存しないので同様に同じ値を使い続けられる。また和自体は一つの文章で共通して使うことができる。
  •  n_{t|d} は実際の学習ではかなり sparse になるベクトルなので、ノンゼロになる成分だけを保持しておけば  t の和は比較的少ない計算で済む。
  • 第三項の和の中の  n_{w|t} の係数は文書には依存するが単語には依存しないので、一つの文書を通じて同じ量を使い続けることができる。また  n_{t|d} は sparse な量なので、 n_{t|d} = 0 とした量をバッチ学習の初めに作っておき、 n_{t|d} がノンゼロになる部分だけを文書ごとに更新すればさらに効率化できる。
  • また  n_{w|t} も非常に sparse なベクトルなので、これもノンゼロになる成分だけを保持しておくようにする。

要は、単語トピックを更新する際に、 t について 毎回1 から順々に足していくのは非常に非効率なので、キャッシュできる量はしておく、sparse なベクトルについてはノンゼロ成分だけで和を取るようにしましょうということ。

 Z を計算したら、次に乱数を生成してどのトピックになるか調べることになる。実際の学習では上の式の第三項の重みが他二つに比べて桁で大きいのでまずはそこから見るようにする。またその際に n_{w|t} を降順にソートしておくことで高速化を図ることもでき、Yao 達の論文では、そのために  n_{w|t} をbitwise で持つようにしようという手法も提案している。*3 これ以上の詳細は論文を読んでほしい。

感想

夏のインターンで取り組んだので、どこかにまとめておこうと思いながら冬になってしまいました。*4なんとか年内に終わってよかったです。 LDAは実装も手軽で、典型的なベイズ学習を勉強するのに適していると思います。 また SparseLDA のように単に式を展開するだけで高速な計算ができるようになるというのも非常に勉強になりました。 次はディリクレ過程を勉強したい。

*1: \sum_t \alpha_t + n_d t に無関係なので無視

*2:同じ値と言っても、ギブスサンプリングなので今更新しようとしている単語の寄与は、毎回引いておく必要がある。この計算量はトピック数が増えても変わらない。以後「同じ値」とか「共通して使える」とか言った時は同様の意味である。

*3:実装が悪いのか、そうしても僕のコードでは siginificant な improvement は無かったが......

*4:多くの研究論文がそうであるように、このノートが念頭に置いているメインの読者は将来の自分である。人は忘れる生き物なので......

二週間

研究会や共同研究があり、2週間韓国に行っていた。 韓国は近くて食べ物も美味しくてとても良い。僕は韓国で食べて初めてキムチが美味しいと思うようになった。

去年初めて行ってから今回でもう3回目になのだが、いまだにハングルを全く覚えていないので困ることが多い。飲食店で英語が通じることはほとんどないので、適当に指差しで注文したりすることがほとんど。最近はようやく「これを一つください」が言えるようになった。海外に行くときもやることは日本と変わらなくて、だいたいご飯を食べて酒を飲んでいる。

今回初めて食べたのはポッサムと牛焼き肉。 ポッサムは豚バラや豚の足を蒸したもので、キムチ等の薬味と一緒に食べるととても美味しかった。 焼き肉は安いので豚を食べることが多いけど、もちろん牛もあって豚よりは多少値が張る。 しかしその分味も良いので、普通のサムギョプサルに飽きた人にはオススメしたい。

韓国は食べ物は美味しいのだけど、お酒に関してはあまり良くない。 彼らは基本安くて酔えればいいという感じのようだ。 一番よく見かけるビールは Cass という名前のものだが、これは味が薄くお世辞にも美味しいとは言えない。 韓国人の知り合いもだいたい同意見で、財閥が強くて競争が生まれないのが原因だと言っていたが、本当かはわからない。 比較的美味しい国産ビールは Kloud というものだが、置いていない店も多い。 ただ繁華街に行けば若者向けのビアパブはたくさん見つかるので、美味しいビールが飲みたければそういう所に行って普通に外国ビールを飲めば良いと思う。

ビールの他によく飲まれているお酒はソジュ(焼酎)である。どこでも飲める緑の瓶のソジュは一本360mlとかで約400円ととても安価だが、日本でいう甲類焼酎に当たるものでまあ安酒。今回共同研究者に連れて行ってもらったお店で10倍の値段がする焼酎を飲んだけど、それは結構美味しかった。

研究会は面白い話もいくつかあったが、モチベがよくわからない研究も少なくなくて、業界の混迷感が見えていたと思う。 まあこれは僕が朝起きられなくて、午前の最初の方のトークをスキップしがちだったからかもしれない。 参加者を集めるために早めの時間に良い研究者を配置することはよくある。 自分の発表は短時間であまりこの業界の人が知らないテーマを話さないといけなかったので大変だったが、一応質問も出たので悪くはなかったと思う。 共同研究の方もまあ進展したので行った元は取れた。

そろそろ本当に就活の方をやっていかなければならないので説明会のようなものに申し込んだりしている。 就活サイトに登録したら怖い企業から、生きる意味や社会で果たすべき役割などを問うDMが来るようになり震えている。 そんなこと考えながら生きても一ミリも楽しくないと思うんだけど。

文献管理とノート整理に Zotero が最適だった

仕事(?)柄常日頃多くの論文を読んだり、たくさんノートをとったりしている。 最近は紙でノートを取るのをやめてソニーのデジタルペーパーに移行した。 いつでもどこでも自分の昔やった計算にアクセスできて便利である。特に出張にどのノートを持って行こうかと悩むことがなくなったのは大きい。 自費で買うのは少し高いが研究費等で購入できる人にはオススメ。

ソニー デジタルペーパー dpt-rp1

ソニー デジタルペーパー dpt-rp1

文献やノートの数が多くなってくると必然的にその管理方法が問題になる。 論文に関してはフリーの spires.app https://member.ipmu.jp/yuji.tachikawa/spires/ を使っていた。これは INSPIRE (高エネルギー物理の論文データベース)を利用する人専用のアプリだが、軽量で arxiv の新着や BibTeX key の取得も簡単なので便利だった。 しかし最近は INSPIRE にない分野の論文もよく読むようになり、それらは適当にドロップボックスに入れていたので、管理が行き届かなくなってしまった。 またデジタルペーパーで取ったノートも同様にドロップボックスに投げていたが、こちらも文献と同じシステムで管理したいと思っていた。

そのような目的でいくつか有名どころの文献管理ソフトを調べて使ってみた結果 Zotero が僕の目的には最適だったので紹介というか使い方をメモしておく。

www.zotero.org

Zotero のメリットをいくつか挙げよう:

  • オープンソースであり、有志の作成したプラグインを使うことで機能拡張ができる。もちろん頑張れば自分でも作れる

  • ユーザー登録をすることで Zorero のサーバー上で文献リストを共有できる。複数端末で文献管理する人には必須。無料アカウントでは容量は少ないが、PDFは同期せず、文献データだけを共有するようにすれば問題にはならない

  • Firefox プラグインが存在する。これは論文以外にも参考になりそうな WEB ページ等をワンクリックで登録するのにも使えて便利

  • 後述する Zotfile というプラグインが便利。デジタルペーパーと連携させるのにとても役立つ

  • 軽い

もちろん同様な機能は他の文献管理ソフトにも存在するとは思うが、細かい部分が僕の使い方にあっていると感じた(あと基本的にフリーで拡張性が高いソフトウェアを僕が好むというのもある)。

Zorero の設定

基本的な使い方やアカウント作成方法等は本家のページ、もしくは日本語が良ければ「Zotero 使い方」でググれば大体わかると思う。 個人的にデフォルトから変えるべきだと思う設定は

  • [General] -> [File Handling] -> [Automatically take snapshots when creating items from web pages] のチェックを外す。いちいち余計なページ情報も付与されて邪魔なので

  • [Sync] -> [File Syncing] のチェックを全部外す。これは Zotero アカウントの容量に余裕のある人は使っても良いとは思う。僕は Zotero サーバーにファイルを入れるのをやめて(後述するように)自前のドロップボックスで共有している

くらいだろうか。

一つネックなのは Zotero の外部からファイルを参照するのが難しいということだ。 というのも、ローカルのデータベース管理には SQLite というソフトが使われているのだが、これが人間にとっては意味がわからない文字や数字によって文献名をつけてしまうからだ。 例えばZotero ソフト内で [Deep lerning] - [textbook] のように階層を定義して資料を管理していたとしても、実際の保存先のディレクトリ内ではその階層構造も崩れるし、どこに [Deep learning] の文献があるかも容易には確認できない。 僕は Zotero にさらにデジタルペーパーを連携させたいのだが、このように外から見たファイルの場所や名前がめちゃくちゃだと、単に Zotero の保存先とデジタルペーパーを同期させるだけでは快適な環境は作れない。 ということでこれを解消するために ZotFile というプラグインを使う。

Zotfile を使う

以下でプラグインをダウンロードして Zotero にインストールする。

ZotFile - Advanced PDF management for Zotero

  • [Tools] -> [ZotFile Preferences] -> [Location of Files] の [Custom Location] に保存先を設定する。僕の場合はドロップボックスの中に Zotero という名前のディレクトリを作成してそれを使った

  • [Use subfolder defined by] に /%c と書くことで、Zotero 内の Collection の階層と同じ構造を持ったディレクトリが作成される

設定のオプションなどは以下のブログが参考になる。

humosy.hatenablog.com

ただし、ここでドロップボックスを使ったファイル共有方法として紹介されている、「Zorero のデータベース情報を直接ドロップボックスにおく」というやり方はオススメしない([Advanced] -> [Files and Folders] の話)。 なぜなら複数端末で同時に Zotero を起動している場合に、データベース間の整合性が取れなくなって、登録したと思った文献がなくなっている等のトラブルが起きかねないからだ。 ここで書いたように、ZotFile の保存先のみをドロップボックスに設定して、データベース情報はあくまでローカルと公式のクラウド経由で管理するのが良いと思う。

デジタルペーパーと連携する

ここまでくるとデジタルペーパーと連携するのも簡単である。単にデジタルペーパーと、ドロップボックスに作った ZotFile 用のディレクトリを同期すれば良い。 デジタルペーパーは配下のPDFを勝手に探して、ディレクトリ構造を保ったまま同期してくれる。 しかもZotFile によって著者やタイトルをもとにリネームされているのでとても探しやすくもなっている。

Zotero は自分で書いた手書きのノートなども論文と同じレベルで管理してくれる。 僕の普段の使い方としては、研究プロジェクトごとに Zotero の Collection を作成する、そこに参考文献用の sub collection とノート用の sub collection を作成して管理するという風にやっている。