日本語テキスト検索のためのシンプルなGo言語ライブラリです。TF-IDFとコサイン類似度を使用して、クエリに最も関連性の高い文書を検索します。
- 🇯🇵 日本語対応: Kagome形態素解析エンジンを使用した高精度な日本語トークナイズ
- 🔍 TF-IDF検索: 古典的ながら効果的なTF-IDFアルゴリズムを実装
- 🚀 シンプルなAPI: わずか1行で検索を実行
- 📊 類似度スコア: 各検索結果にコサイン類似度スコアを付与
- ⚡ 高速: メモリ内処理による高速な検索
go get github.com/SpringMT/simple-searchpackage main
import (
"fmt"
simplesearch "github.com/SpringMT/simple-search"
)
func main() {
// 検索対象の文書コーパス
corpus := []string{
"日本の伝統的な料理である寿司は、世界中で愛される食文化の一つです。",
"富士山は日本の象徴として、古くから人々に親しまれてきました。",
"京都は千年以上にわたって日本の首都であり、数多くの歴史的建造物が残る古都です。",
}
// 検索クエリ
query := "日本の歴史的な観光地について"
// 検索実行(上位3件を取得)
results := simplesearch.Search(query, corpus, 3)
// 結果表示
for i, result := range results {
fmt.Printf("%d位 (スコア: %.4f)\n%s\n\n", i+1, result.Score, result.Text)
}
}このライブラリでは、以下の手順でTF-IDFベクトルを計算しています。
Kagome形態素解析エンジンを使用して、各文書を単語(トークン)に分割します。
- 対象品詞: 名詞、動詞、形容詞、形容動詞
- 基本形への変換: 動詞や形容詞は基本形(辞書形)に変換
- ストップワード除去: 「する」「いる」「の」などの一般的な単語を除外
各単語の重要度を表すIDF値を計算します。
IDF(t) = log((N + 1) / (df(t) + 1)) + 1
N: 総ドキュメント数df(t): 単語tが出現したドキュメント数+1: スムージング(ゼロ除算を防ぐ)
IDF値の意味:
- 多くの文書に出現する単語(例:「日本」)→ 低いIDF値
- 特定の文書にのみ出現する単語(例:「寿司」)→ 高いIDF値
各文書における単語の出現頻度を計算します。
TF(t, d) = (単語tの文書d内での出現回数) / (文書dの総単語数)
各単語に対してTFとIDFを掛け合わせます。
TF-IDF(t, d) = TF(t, d) × IDF(t)
これにより、各文書は全単語の語彙サイズの次元を持つベクトルとして表現されます。
コサイン類似度の計算を効率化するため、各ベクトルをL2ノルムで正規化します。
正規化ベクトル = ベクトル / ||ベクトル||₂
ここで、||ベクトル||₂ = √(v₁² + v₂² + ... + vₙ²) です。
クエリベクトルと各文書ベクトルの類似度を計算します。
cosine_similarity(A, B) = A · B
L2正規化済みのベクトル同士では、内積がそのままコサイン類似度になります。
以下のような小さなコーパスで説明します:
文書1: "寿司 美味しい 日本"
文書2: "富士山 美しい 日本"
クエリ: "日本 料理"
-
語彙: ["寿司", "美味しい", "日本", "富士山", "美しい", "料理"]
-
DF(Document Frequency):
- "日本": 2(両方の文書に出現)
- "寿司": 1(文書1のみ)
- "富士山": 1(文書2のみ)
- その他: 各1
-
IDF計算 (N=2):
- IDF("日本") = log((2+1)/(2+1)) + 1 = 0 + 1 = 1.0
- IDF("寿司") = log((2+1)/(1+1)) + 1 = log(1.5) + 1 ≈ 1.405
- IDF("料理") = log((2+1)/(0+1)) + 1 = log(3) + 1 ≈ 2.099
-
文書1のTF-IDF:
- "寿司": (1/3) × 1.405 ≈ 0.468
- "美味しい": (1/3) × 1.405 ≈ 0.468
- "日本": (1/3) × 1.0 ≈ 0.333
- その他: 0
-
L2正規化後、クエリと各文書のコサイン類似度を計算し、スコアの高い順に結果を返します。
func Search(query string, corpus []string, topK int) []SearchResultパラメータ:
query: 検索クエリ文字列corpus: 検索対象の文書の配列topK: 返す結果の最大数(0または文書数より大きい場合はデフォルトの10件)
戻り値:
type SearchResult struct {
Text string // 文書のテキスト
Score float64 // コサイン類似度スコア(0.0〜1.0)
}- Go 1.25.3以上
- github.com/ikawaha/kagome/v2 - 日本語形態素解析
- github.com/ikawaha/kagome-dict/ipa - IPA辞書
examples/ディレクトリに完全な使用例があります。
cd examples
go run main.goこれは20件の日本語文書(各約300文字)に対して検索を実行するデモです。
このプロジェクトはMITライセンスの下で公開されています。詳細はLICENSEファイルを参照してください。
プルリクエストを歓迎します。大きな変更の場合は、まずissueを開いて変更内容を議論してください。
- 文書の事前インデックス化機能
- BM25アルゴリズムのサポート
- マルチスレッド処理による高速化
- 永続化ストレージのサポート
- より高度なトークナイズオプション