Issue #142: 検索機能改善: 空白区切りクエリの最適化とクエリ拡張機能
Opened 2025/8/5 by @nyasuto Open
enhancement
Description
概要
現在のベクトル検索における空白区切りクエリの精度をさらに向上させる改善提案
現状分析
- 良い点: OpenAI Embeddingsによる意味的理解は機能している
- 課題: クエリの前処理とクエリ拡張が不十分
- 例:
"趣味 好み 興味"→ より柔軟な検索体験を提供可能
提案改善
1. インテリジェントクエリ前処理
class QueryProcessor:
async def process_query(self, raw_query: str) -> ProcessedQuery:
"""クエリの前処理・最適化"""
# 1. クエリ正規化
normalized = self.normalize_query(raw_query)
# 2. 同義語展開
expanded = await self.expand_synonyms(normalized)
# 3. 関連語推定
related_terms = await self.suggest_related_terms(expanded)
# 4. 重要度計算
weighted_terms = self.calculate_term_weights(expanded)
return ProcessedQuery(
original=raw_query,
processed=expanded,
related_terms=related_terms,
weights=weighted_terms
)
def normalize_query(self, query: str) -> str:
"""クエリ正規化"""
# ひらがな・カタカナ統一
# 表記ゆれ修正(例:コンピュータ → コンピューター)
# 不要な助詞削除
return normalized_query
async def expand_synonyms(self, query: str) -> str:
"""同義語展開"""
# 例: "趣味" → "趣味 hobby 嗜好 関心事"
synonyms = await self.get_synonyms(query)
return f"{query} {' '.join(synonyms)}"
2. 重み付きベクトル検索
class WeightedSemanticSearch:
async def search_with_weights(self, query: ProcessedQuery, db: Session) -> SearchResults:
"""重み付きセマンティック検索"""
# 複数のembedding生成
embeddings = {
'original': await self.get_embedding(query.original),
'expanded': await self.get_embedding(query.processed),
'terms': [await self.get_embedding(term) for term in query.related_terms]
}
# 重み付き類似度計算
for memory in memories:
scores = {
'original': self.cosine_similarity(embeddings['original'], memory.embedding) * 0.6,
'expanded': self.cosine_similarity(embeddings['expanded'], memory.embedding) * 0.3,
'terms': max([self.cosine_similarity(emb, memory.embedding) for emb in embeddings['terms']]) * 0.1
}
final_score = sum(scores.values())
results.append(SearchResult(memory=memory, score=final_score))
3. 文脈理解の向上
class ContextualSearch:
def analyze_query_intent(self, query: str) -> QueryIntent:
"""クエリ意図解析"""
patterns = {
'exploration': ['趣味', '興味', '好み'], # 探索的検索
'factual': ['とは', 'について', '定義'], # 事実検索
'procedural': ['方法', 'やり方', 'どうやって'], # 手順検索
'comparative': ['違い', '比較', 'vs'], # 比較検索
}
detected_intent = self.detect_intent(query, patterns)
return QueryIntent(
type=detected_intent,
confidence=self.calculate_confidence(query, detected_intent),
suggested_filters=self.suggest_filters(detected_intent)
)
4. リアルタイムクエリ改善
@router.post("/api/search/suggest")
async def suggest_query_improvements(query: str) -> QuerySuggestions:
"""リアルタイムクエリ改善提案"""
# 入力途中でのサジェスト
suggestions = {
'completions': await autocomplete_service.suggest(query),
'corrections': await spell_check_service.check(query),
'expansions': await synonym_service.expand(query),
'related': await related_terms_service.find(query)
}
return QuerySuggestions(**suggestions)
# フロントエンド側での実装例
const handleQueryChange = debounce(async (query) => {
if (query.length > 2) {
const suggestions = await api.suggestQueryImprovements(query);
showSuggestions(suggestions);
}
}, 300);
5. 検索結果の説明可能性
class ExplainableSearch:
def explain_results(self, query: str, results: List[SearchResult]) -> SearchExplanation:
"""検索結果の根拠説明"""
explanations = []
for result in results[:5]: # Top 5の説明
explanation = {
'memory_id': result.memory.id,
'score': result.score,
'reasons': [
f"'{term}'が{count}回出現" for term, count in self.count_terms(query, result.memory),
f"意味的類似度: {result.semantic_score:.2f}",
f"タグ一致: {', '.join(self.matching_tags(query, result.memory))}"
],
'highlighted_text': self.highlight_matches(query, result.memory.value)
}
explanations.append(explanation)
return SearchExplanation(
query=query,
total_results=len(results),
explanations=explanations
)
実験・検証計画
A/Bテスト設計
# 現在の実装 vs 改善版の比較
class SearchExperiment:
async def run_comparison(self, test_queries: List[str]) -> ExperimentResults:
"""検索精度の比較実験"""
results = {
'current': [],
'improved': []
}
for query in test_queries:
# 現在の実装
current_results = await current_search_service.search(query)
# 改善版実装
improved_results = await improved_search_service.search(query)
# 精度評価(手動ラベリングデータと比較)
current_score = self.evaluate_relevance(query, current_results)
improved_score = self.evaluate_relevance(query, improved_results)
results['current'].append(current_score)
results['improved'].append(improved_score)
return ExperimentResults(
improvement_rate=self.calculate_improvement(results),
statistical_significance=self.ttest(results)
)
評価指標
- 適合率: 関連性の高い結果の割合
- 再現率: 関連する全結果の取得率
- nDCG: 順位を考慮した精度指標
- ユーザー満足度: クリック率・滞在時間
実装スケジュール
Phase 1: クエリ前処理強化 (1週間)
- 同義語辞書構築
- 正規化ルール実装
- 重み付け機能追加
Phase 2: 文脈理解向上 (1週間)
- 意図解析機能
- クエリ拡張機能
- リアルタイム提案
Phase 3: 説明可能性・評価 (1週間)
- 結果説明機能
- A/Bテスト基盤
- 精度測定システム
期待効果
- 検索精度: 20-30%の向上
- ユーザー体験: より直感的な検索
- 発見性: 関連情報の能動的提案
- 学習効果: ユーザーフィードバックによる継続改善
Comments
コメント機能は現在実装されていません。
GitHub API の comments エンドポイントを統合する予定です。
🤖 AI分析
分類結果
✨ 新機能
77%
🟡 中
92%
67 スコア
カテゴリ 40
優先度 27
0 適用されたルール
Enhanced Feature Request Detection
77%
• Body contains keyword: "suggestion"• Has matching label: "enhancement"
suggestion
Details
Assignees:
None
Milestone:
None
Created:
2025/8/5
Updated:
2025/8/5