LSA(Latent Semantic Analysis)の検索機能において、現状の実装がダミーデータ(全てのベクトルがゼロ、または同一)を返していたため、検索結果に意味のある差異が生じていなかった。ndarray-linalg などの外部LAPACK依存を避けつつ、純粋なRust実装(ndarrayのみ)で特異値分解(SVD)を実装し、精度の高い意味検索を実現する必要があった。
lsa.rs の train 関数がダミー実装であり、検索結果が常に同一(1.0 または 0.0)であった。TermDocumentMatrixBuilder に TF-IDF 重み付けを実装し、単語の重要度を反映させた。LsaModel::train に べき乗法(Power Method)とデフレーション(Deflation) による、反復的截断SVD(Truncated SVD)を実装した。sqlite-vec(L2距離)での近傍検索がコサイン類似度と等価になるようにした。AIエージェントは以下の手順で実装を行った。
TF-IDFの実装:
build_matrix 内で文書頻度(DF)を計算し、ln(N/(df+1)) + 1 による IDF を適用。SVDアルゴリズムの実装:
正規化と距離計算の改善:
project_query において、射影後のベクトルを $L2$ ノルムで正規化。検証:
test_lsa_variance を作成。Similarities: [0.965, 0.061, 0.0] のように、意味的に近い文書にのみ高いスコアが出ることを実証した。純Rust実装のSVDにより、外部依存のトラブル(DLLの不一致やビルドエラー)を完全に回避しつつ、実用的な精度のLSA検索が可能となった。 特に、截断SVD(Truncated SVD)は必要な上位 $k$ 成分のみを抽出するため、今回の TelosDB のような小〜中規模な文書管理には非常に効率的である。 今後は、文書数が増えた際の計算負荷を監視し、必要であればより高度なアルゴリズム(Lanczos法やRandomized SVD)へのアップグレードを検討する余地がある。
graph TD
A[文書集合] --> B[Tokenizer / Vibrato]
B --> C[Term-Document Matrix / TF-IDF]
C --> D[SVD Training / Power Method]
D --> E[LSA Model / Topic Space]
F[Query] --> G[LSA Projection / Normalized]
G --> H[sqlite-vec / Vector Search]
H --> I[Scored Results]
E -.-> G