開発ノート

フォルダ名こそが、学習データだった

このアプリの元になったアーカイブは314,391ファイル:写真がおよそ223,000枚、動画がおよそ91,000本、6TBの外付けドライブに収まっている。ある家族の視覚的な記録のすべてであり、多くの家族と同じように、彼らも記録の残し方について、まったく違う2つの時代を経てきた。

2004年から2016年まで、イベントごとに専用のフォルダが作られ、それが起きた翌日に手作業で名付けられていた:2012-04 — the spring trip、そういう感じだ。数はおよそ600個。それが、2016年頃を境に止まった。代わりに出てきたのは現代の典型例だった:巨大でフラットなスマホバックアップの山、IMG_4471.HEICのようなファイルが何千個も、バックアップが実行された日付範囲以外は何も基準なくグループ化されている。(もし直近の年の写真がまだスマホの中に閉じ込められているなら、iPhone取り出しガイド(英語)でドライブに移す手順を紹介している。)

こういうアプリで当然考える計画は、名付けられた時代と山になった時代の両方について、イベントを自動検出し、名前を自動生成することだ。始める前は予想していなかったのは、名付けられた時代が、見た目が良いだけではなく、無料で手に入るラベル付きデータセットが、12年分もそこにずっと存在していたということだった。

推測ではなく、正解データ

「一つのイベント」とみなすものの境界を人間が引いたものが600個。これは通常、お金を払って手に入れるようなものだ。この家族はすでに、イベントごとに、ある瞬間がどこで終わり、次がどこから始まるかを判断する作業をやり終えていた。だから、既製のイベントクラスタリング手法を選んで感覚に合うことを期待するのではなく、名付けられたフォルダを、この特定の家族がどのように時間をイベントに分割するかについての正解データとして扱い、それに対して直接調整した。

クラスタリング手法自体は意図的にシンプルにしている:連続するタイムスタンプ間の間隔がしきい値未満であれば同じイベントとしてまとめる、時間差ベースの処理だ。実際に調整すべきパラメータはそのしきい値をどこに置くかだけ。地味だが正しい方法で測定した — ペアごとの共同メンバーシップ一致率だ。名付けられた時代の写真すべてのペアについて、人間によるフォルダ分割とアルゴリズムによる分割が一致するか(両方一緒か、両方別かのどちらか)を確認し、一致する割合をスコアにする。しきい値を動かし、曲線をプロットし、ピークを取る。

314,391
元になったアーカイブのファイル数
約600
手作業で名付けられたイベントフォルダ、2004〜2016年
F1 0.93
24時間の間隔しきい値での値

ピークは24時間の間隔で、名付けられたフォルダに対するF1は0.93だった。これは論文のベンチマークではない — ある一つの家族が12年かけて積み重ねた、自分たちのイベントがどこで始まりどこで終わるかについての判断に対して調整された数字だ。それこそがまさに要点だ:「正しい」クラスタリングしきい値は普遍的なものではなく、特定の家族がどう生活しているかを反映する属性なのだ。この家族はどうやら、2日間の旅行を、間に一泊挟んだだけで2つのイベントに分けることはしない。24時間の間隔がそれを捉えている。別の家族が名付けたフォルダなら、まったく違う場所にピークが来るかもしれない。だからこのアプリは、デフォルト値を仮定するのではなく、アーカイブごとに再測定するように作られている。

イベントが家族自身のやり方でまとまったところで、次の問題は命名になる。そしてまた同じ手法が効く:600個の名付けられたフォルダは、境界であるだけでなく、スタイルガイドでもある。2012-04 — the spring tripは、この家族の慣習が「日付のプレフィックス、エムダッシュ、小文字、汎用的な言い方(「Family Outing」のような)ではなく短く具体的な表現」だと教えてくれる。名付けられなかった10年分の自動命名は、一般的な語調を押し付けるのではなく、その声を学ぶ。

放置していれば静かに全体を壊していたはずの落とし穴たち

これを作る過程で出てきた、書き記しておく価値のある3つのことがある。どれも、実際に探しに行くまでは見えないもので、もし明白な「正解のソース」をそのまま信じていたら、タイムラインを静かに劣化させていたはずのものだ。

カメラの時計は嘘をつくが、フォルダ名は嘘をつかない。 名付けられた時代には、カメラの時計が1年ずれていることが時々あった — ひどくずれているわけではなく、電池交換や日付をまたぐ移動のあとにリセットされなかったカメラの時計にありがちな、ちょっとしたずれだ。修正方法は、EXIFを日付判定のデフォルトの真実として信頼するのをやめ、両者が食い違ったときは人間がタイプしたフォルダの日付プレフィックスを優先させることだった。その週のうちに2012-04とフォルダ名に打ち込んだ人は、何年も確認されていないカメラの内部時計よりも信頼できる証人だ。

デジタル化されたメディアは、間違った日付を二重に持っている。 もっとやっかいなのは、後からデジタル化された古いカムコーダーのテープだ:ファイル自身のタイムスタンプ情報は、撮影された時ではなく、デジタル化された時を反映している。このクラスのファイルでは、EXIFはたまに間違っているのではなく、特定の、構造的なやり方で間違っている。修正方法はカメラ時計の修正と同じ形を一段上げたものだ:スキャンしたりデジタル化したメディアについては、家族がそれを保存した年フォルダが、ファイル自身のタイムスタンプを上書きする。フォルダは記憶を記述していて、タイムスタンプはスキャン作業そのものを記述しているからだ。

旅行の判定には、思い入れに騙されない「家」の定義が必要だ。 ある旅行を旅行として検出するには — 通常の生活からの離脱として — アプリは「通常の生活」がどこだったかを知る必要があり、それは家族が引っ越すにつれて22年間で移り変わる。素朴な発想、場所ごとの写真数を数える、というやり方は、考えてみれば明らかな形で失敗する:5日間の休暇は、5日間の平凡な自宅生活よりもはるかに多くの写真を生む。だから、1週間だけ訪れた場所が、実際に半年住んでいた家を、写真の数で簡単に押し切ってしまう可能性がある。修正方法は、半年ごとに、写真の枚数ではなく、その場所にいた明確な日数で投票する「家」モデルだ。ある場所が「家」だとカウントされるのは、たくさんの異なる日にそこで生活していたことによってであって、少ない日数にたくさん写真を撮ったことによってではない。この一つの置き換え — 写真ではなく日数 — こそが、旅行が家からの離脱として正しく認識され、家の場所が静かに書き換えられてしまわないようにしている。

名付けられた年月は、ただラベルを得たわけではない。この家族自身の手で、イベントとは何かということそのものを定義してくれたのだ。

この話のどれも「これが正しいしきい値だから、そのまま出荷しろ」という形では一般化しない。一般化するのは方法論だ:アーカイブの一部が、それを生きた人たち自身によって手作業でラベル付けされているなら、その部分は良い見た目であるだけでなく正解データであり、デフォルト値で十分だろうと仮定するのではなく、それに対して測定する余分な一手をかける価値がある。典型的な家族アーカイブの他の2万ファイルは、決して管理者の丁寧な注意を受けることはなかっただろう。しかし、12年分のうち一つは、それを受けていたことがある。

← 記事一覧へ戻る