洞窟の比喩

μετὰ ταῦτα δή, εἶπον, ἀπείκασον τοιούτῳ πάθει τὴν ἡμετέραν φύσιν παιδείας τε πέρι καὶ ἀπαιδευσίας. ἰδὲ γὰρ ἀνθρώπους οἷον ἐν καταγείῳ οἰκήσει σπηλαιώδει, ἀναπεπταμένην πρὸς τὸ φῶς τὴν εἴσοδον ἐχούσῃ μακρὰν παρὰ πᾶν τὸ σπήλαιον, ἐν ταύτῃ ἐκ παίδων ὄντας ἐν

空想サカモトbot 2.0

これは52代アドカレ19日目の記事になります。徒然

 

こんにちは、ΙΔΈΑです。

 

みなさん、「空想サカモトbot」をご存知ですか?私は知りません。

きっかけは、サカモトカレンダー。

 

サカモトカレンダー

adventar.org

サカモトカレンダー、通称サカカレ。今からちょうど1年前となる2019年の12月、それは幕を開けました。多くの参加者が集ったその戦いは熾烈を極め(中略)それに敗れた私の贖罪として空想サカモトbotは誕生したのです。

idea-misw.github.io

 

空想サカモトbot

ということで……

 

空想サカモトbot、待望の大型アップデート!ずばりリプライ機能が追加されます。空想サカモトbotにリプライを送ると、なにかしらのリプライを返してくれます。ウワーッウレチーッッッ

f:id:idea_misw:20201113211637p:plain

注:なにせ私の手による実装をもとにしているため信頼性や可用性に乏しく、少しの負荷がかかるだけでも機能が破壊してしまうということがあるかもしれません。多分壊れます。例のごとく私が気づき次第修正されると思うので、そのときは何卒よろしくお願いいたします……

注:あと返信のタイミングは気まぐれです。来ないときは気長に待ちましょう……

そんなわけで今回の記事は以上となります。どうもありがとうございました。また次回にお会いしましょう。

 

それでは、さようなら。

 

 

 

 

 

 

 

 

 

 

 

 

 

――と終わってしまうのも少し寂しいので、もうちょっとだけ続きます。

 

夢を壊す話

今回ついにアップデートが施された空想サカモトbotというアカウントですが、その背景には稚拙ながらも複雑な諸々があります。これもまた公開から一年ばかりが経過しようとしているということで、少しその辺りに関する話をしておこうと思います。興味がある方はどうぞ。

 

ツイートの生起について

これは"○○時○○分に呟く"というように時間を決定してもよかったのですが、せっかくなのでリアリティを求めました。結果として、現在このアカウントによるツイートはポアソン分布にしたがう形になっています。なぜそうなのかと言われたら、それはなんとなくです。

 \displaystyle P(X=k) = e^{-\lambda} \frac{\lambda^k}{k!}

より正確にいえば、ツイートの生起をポアソン分布にしたがわせるべくインターバルを指数分布から抽出していたりします。なにやら難しい話ですが、ここまでくると私にも正直よくわかりません。なにかこう不思議な力によって機能は実現されているということです。

 \displaystyle P(X=x) = \lambda e^{-\lambda x}

 

リプライの内容について

今回のアップデートでもっとも大変だった点は、実装でも運営でもなくリプライの内容です。送られた文の内容にもとづく適切な応答を返すことはなかなかに困難で、現状私の能力からは実現できないと判断しました。かといって通常のツイートと同様な文脈のないテキストを返すだけでは少し物足りないのではないかという懸念もありました。

最終的にたどり着いた策は"文をいくらかまとめて生成し、その中でもっとも対象に近いものを選択する"というものでした。つまるところこれは文書間の類似度判定という問題に落とし込まれます。2文がどれだけ類似しているのかを測る方法はいろいろとあるようですが、今回はもっともオーソドックスなものを用います。まず各文をBoWでベクトル化し、それらのコサイン類似度を求めるという手法です。

BoW どうにかして文の特徴量を抽出し、それをベクトルとして表現したいのです。たくさんの方法がある中で、あまりここに凝っていても仕方がないので今回は適当にBoW (Bag of Words)というものを使います。これは非常に簡単なアプローチで、対象に含まれる単語をベクトルの各次元に割り当て、それらの出現頻度をもってベクトルを構築するというものです。べつにブレスオブ(ザ)ワイルドではありません。どの単語がどれくらいの頻度で出現するのかを特徴量としてとらえ、それをもとに文の類似度を測ることになります。とてもわかりやすいですね。

コサイン類似度 なんらかの指標をもとにベクトル間の類似度を測ります。今回はコサイン類似度というものを採用します。これは2ベクトルの類似度を次のようにして測るものです。

 \displaystyle \text{cos-sim} (\boldsymbol{a}, \boldsymbol{b}) = \frac{\langle\boldsymbol{a}, \boldsymbol{b}\rangle}{\|\boldsymbol{a}\|_2 \|\boldsymbol{b}\|_2}

コサイン類似度という名前が少し仰々しいですが、幾何的に考えればこれはただの角です。同じような方を向いているベクトルを類似していると考えているだけです。いわば上の式も \vec{a} \vec{b}のなす角を求めんとするばかりで、これもなんら難しいことはありません。

 \displaystyle \hat{\boldsymbol{v}} = \mathop{\text{argmax}}_\boldsymbol{v} \text{cos-sim} (\boldsymbol{v}_\text{given}, \boldsymbol{v})

いくつか出力された文の中から与えられた文とのコサイン類似度がもっとも高い値となるものを選択し、それをリプライとして返すことになります。これによって少しは送られた文を考慮することができるのではないでしょうか。できるといいのですが。

 

サーバ周りについて

タスケテーッッ

 

公式ページについて

しれっと載せた公式ページですが、実は私のお手製だったりします。記憶が曖昧でそのときのことをよく覚えていないのですが、どうにかして作ったのだと思われます。

中には"れすぽんしぶ"とかいう仕掛けが施してあったりします。難しいですね、これ。

 

 

 

……そんな感じです。なにやら夢を壊すとか言っておきながらほぼ寝言のようなコメントばかりで大変申し訳ありません。壊れているのは私の方でした。

 

こうしたバックグラウンドのもとに、あのアカウントは運営されているのです。いかんせんサーバとかバックエンドとかの話にめっぽう疎く、終始泣きながらの開発となっていたわけなのですが、どうにか形にすることができて心から安堵しております。

今度こそ以上です。あらためて、またいつかにお会いしましょう。

 

そして空想サカモトbotをよろしくお願いいたします。

 

 

 

おまけ

とくに理由はありませんが、せっかくなのでジェネレータ改とディスクリミネータのノートブックも置いておきます。プレゼント。

github.com

github.com

じっくりとは見ないでくださいね……