Pythonで作った80行の検索エンジン
- 昨年9月にWallapopの検索データサイエンティストとして加わり、Solrというオープンソースの検索エンジンを扱う仕事をしている。
- 検索エンジンの基本原理を理解するため、Pythonを使ってゼロから検索エンジンを作ることにした。
- 目標は「小規模ウェブサイトの発見可能性の危機」を解決することで、Googleのような検索エンジンでは見つけられない小さなウェブサイトを再び素晴らしいものにすることだ。
- この記事では、Pythonを使って検索エンジンを作る過程を案内し、書いたすべてのコードはGitHubのmicrosearchリポジトリで確認できる。
- 実装された検索エンジンは本番運用に対応した検索エンジンではなく、検索エンジンが内部でどのように動作するのかを示す実用的なおもちゃの例である。
microsearch
- microsearchを構成する要素を見ていき、それぞれをどのように作ったかを探る: (1) クローラー、(2) 転置インデックス、(3) ランキング、(4) インターフェース。
クローラー
- 検索エンジンを作るための最初のステップは、検索対象となるデータを確保することだ。
- 「ローカルGoogle」を作るつもりで、フォローしているブログのデータを使って検索エンジンを構築した。
- クローリングには、特定のブログ一覧にあるすべての投稿をダウンロードして整理する作業が含まれる。
- より高速にするため、asyncio Pythonライブラリを使ってクローリング時間を20分から20秒に短縮した。
- 642個のRSSフィードを使い、そのうち約100個は普段よく読むブログ、残り500個はsurprisetalkブログプロジェクトから取得した。
転置インデックス
- 転置インデックスは、キーワードを文書に対応付けるデータ構造で、特定の単語が現れる文書を簡単に見つけられるようにする。
- ユーザーがクエリを検索するとき、転置インデックスを使ってクエリのキーワードに一致するすべての文書を検索する。
- 転置インデックスのロジックは
SearchEngineというクラス内に定義されており、2つの辞書を初期化することで実装している。
ランキング
- あるクエリに対して一致する文書集合が得られたら、それを並べ替える方法が必要になる。
- 最も有名なランキング手法はGoogleのPageRankだが、BM25のように内容ベースで文書をランキングする別の選択肢もある。
- BM25スコアの計算方法を含め、
SearchEngineクラスの不足している部分を実装した。
インターフェース
- 検索エンジンを構築した後は、何らかの形でそれを公開したい。
- FastAPIアプリを構築して検索エンジンを公開するエンドポイントを提供し、検索を実行できるシンプルなウェブページをレンダリングする。
- 出力を読みやすくするため、上位N個のURLだけを選ぶことにした。
足りない機能
- 検索エンジンを日頃よく扱う読者なら、実装に多くの機能が欠けていることに気づくだろう。
- クエリ演算子、n-gramインデキシング、クエリまたは文書の拡張、クローリングとインデキシングを同時に行う機能などが欠けている。
結論
- このプロジェクトを進める中で、Solrの内部動作についてより深く理解でき、非同期コードを書くことの驚きも学んだ。
- 個人向け検索エンジンを作る次のステップとして、検索エンジンにセマンティック検索機能を実装する予定だ。
GN⁺の意見
- この記事で最も重要なのは、小規模ウェブサイトの発見可能性を改善するために、個人が自分で検索エンジンを作れるという点だ。
- Pythonとオープンソースライブラリを活用し、複雑な機能を持つ検索エンジンを単純化して実装した経験は、初級ソフトウェアエンジニアにとっても刺激になる。
- 非同期プログラミングの効率とデータ構造の重要性を実例で示すことで、この記事は技術的な洞察と実践的な学習機会を提供している。
1件のコメント
Hacker Newsの意見
Pandasを使ったBM25検索エンジンの開発
コードレビュー:
SearchEngineクラスk1とbというパラメータの意味が分からず、コードにはコメントがまったくない。_documentsはURLをキーに、そのURLの内容を値として持つものと推測される。検索エンジンの複雑さ
コード行数についての意見
コード内の表現に関するジョーク
chunk for chunk in chunks if chunkという表現を見て、木こりに関するジョークを思い出した。推薦エンジンのコード例
パースライブラリの性能比較
lxml.htmlとlxml.html.cleanはBeautifulSoupよりはるかに高速な場合があると述べている。キーワード利用に関する助言
教育的なプロジェクトに対する意見
Pythonによる大規模データ処理への疑問