AstroJS で関連記事を出力する【TF-IDF】
1. はじめに
読者に他のブログ記事を読んでもらう確率を上げることを考えると、関連記事を表示させることは有効な手段だと思います。WordPress ではプラグインをインストールすることで関連記事を出力することが出来ます。また、Hugo では関連記事を出力する仕組み 1 が標準機能として実装されています。
残念ながら AstroJS には、関連記事を出力する機能が執筆時点では組み込まれていません。そこで、関連記事を出力する仕組みを実装したいと思います。具体的には、ブログ記事のタイトル同士の関連度を算出します。本記事では、関連度として Term Frequency–Inverse Document Frequency (TF-IDF) を使います。また、TF-IDF を計算するために外部パッケージの natural
を使います。natural の詳しい情報については、公式ドキュメント 2 を参照ください。
2. テンプレート
まず初めに、yarn create astro
で blog テンプレートを生成します。次に、生成した blog テンプレートのディレクトリに移動して natural
パッケージをインストールします。これで下準備完了です。
3. TF-IDF
src/pages/blog/[...slug].astro
にコード (ハイライト部分) を追加します。処理としては、任意のブログ記事のタイトルと全ブログ記事のタイトルの関連度を算出して、関連度が高い順にソートしています。
yarn run dev
で起動して、http://localhost:4322/blog/first-post/ にアクセスした際の実行結果が、以下の通りです。最も関連度が高いものとして First post が出力されているのは、重複しているからなので無視します。次に関連度が高いものとして Second post と Third post が出力されています。これは、First post の post
と Second post、Third post の post
がマッチしているからです。Markdown Style Guide と Using MDX はマッチする単語がないので関連なしになっています。
本記事では、ブログ記事のタイトルで計算していますが、ブログ記事の本文やタグなどで計算することも可能です。
4. おわりに
第 3 章で示したコードでは、ブログ記事のタイトルだけで関連度を計算しています。そのため、そこまで精度は高くありません。もう少し精度を上げるとしたら、本文やタグなどを追加する必要があると思います。また、同じようなブログ記事が出力されるといった挙動をする場合があります。これは、変数 posts
の順序が固定されているために発生します。そのため、本記事では sort
でランダム性を追加しています。日時でソートして、最新の記事を表示するなどの応用も考えられます。
-
Hugo, Related content:https://gohugo.io/content-management/related/ ↩
-
Natural, TF-IDF:https://naturalnode.github.io/natural/tfidf.html ↩