君语贤
时光静好,与君语;细水流年,与君同;繁华落尽,与君老...

建站开发>Python>正文

python下的全文搜索实现方案及示例

2024-01-31 16:31 君语贤全文搜索

python下的全文搜索实现方案及示例

Python下的全文搜索程序完整实现涉及的内容比较多,需要通过各种Python库来完成。以下是一个简单的基于搜素词的全匹配和相关匹配的程序框架。

1. 安装必要的库

全文搜索需要使用到的Python库有很多,包括处理文档、分词、建立索引、搜索相关匹配等,这里只列出几个常用的库:

  • nltk:自然语言处理的库,提供分词、停用词过滤等功能
  • whoosh:纯Python实现的全文搜索引擎,支持中文分词
  • jieba:中文分词库
  • pandas:用于处理表格数据

在运行以下程序之前,需要安装以上必要的库。

2. 数据预处理

一般情况下,需要从文本中抽取出需要搜索的信息,同时还需要进行一些预处理工作,例如对文本进行清洗、分词、词干提取、去除停用词等操作,以便进行后续的索引和搜索。

import re
import nltk
import whoosh.index as index
from whoosh.fields import *
from whoosh.qparser import QueryParser
from jieba.analyse import ChineseAnalyzer
from nltk.stem.porter import PorterStemmer
from nltk.corpus import stopwords

def preprocessing(text):
    # 去除标点符号、特殊字符等
    text = re.sub(r'[^\w\s]', '', text)
    # 针对中文文本进行分词
    stopwords_list = stopwords.words('english')
    chinese_analyzer = ChineseAnalyzer(stopwords=stopwords_list)
    tokens = [token.text for token in chinese_analyzer(text, positions=True, 
                                                       check_well_formed=False)]
    # 对英文文本进行分词
    tokens = nltk.word_tokenize(text)
    # 词干提取
    porter_stemmer = PorterStemmer()
    tokens = [porter_stemmer.stem(token) for token in tokens]
    # 去除停用词
    tokens = [token for token in tokens if token not in stopwords.words('english')]
    # 拼接列表为字符串
    return ' '.join(tokens)

preprocessing函数接受一个文本字符串 text 作为输入,返回预处理后的文本。该函数实现了对中文和英文文本的分词、词干提取和去除停用词等预处理操作。

3. 索引建立

def create_index(docs, index_path):
    """
    建立索引
    :param docs: 包含文档内容的列表
    :param index_path: 索引存储路径
    :return: None
    """
    if not index.exists_in(index_path):
        # 定义schema
        schema = Schema(title=TEXT(stored=True), content=TEXT(stored=True))
        # 创建索引
        ix = index.create_in(index_path, schema)
        # 写入索引
        writer = ix.writer()
        for doc in docs:
            writer.add_document(title=doc['title'], content=doc['content'])
        writer.commit()

create_index函数接受两个参数:包含文档内容的列表 docs,和索引存储路径 index_path。该函数使用 whoosh 库建立索引,并保存到指定的路径中。由于 whoosh 库不支持中文分词,因此需要使用 jieba 库进行中文分词。

4. 基于搜索词的全匹配搜索

def search_docs(query_str, index_path):
    with index.open_dir(index_path) as ix:
        # 创建 Query 对象
        parser = QueryParser("content", schema=ix.schema)
        query = parser.parse(query_str)
        # 执行搜索
        with ix.searcher() as searcher:
            results = searcher.search(query)
            doc_data = []
            for hit in results:
                data = {"title": hit["title"], "content": hit["content"]}
                doc_data.append(data)
            return doc_data

search_docs函数接受两个参数:搜索查询字符串 query_str 和索引存储路径 index_path。该函数使用 whoosh 库执行基于搜索词的全匹配搜索,并将结果返回为包含文档标题和内容的字典列表。

5. 基于搜索词的相关匹配搜索

def search_related_docs(query_str, index_path):
    with index.open_dir(index_path) as ix:
        # 分析查询语句,获取关键词
        parser = QueryParser("content", schema=ix.schema)
        query = parser.parse(query_str)
        keywords = query.extract_terms()
        # 执行搜索
        with ix.searcher() as searcher:
            doc_scores = {}
            for kw in keywords:
                # 获得包含关键词的文档列表
                sub_query = QueryParser("content", schema=ix.schema).parse(kw)
                sub_results = searcher.search(sub_query, limit=None)
                for hit in sub_results:
                    doc_id = hit.docnum
                    # 计算文档向量
                    if doc_id not in doc_scores:
                        doc_scores[doc_id] = 0
                    doc_scores[doc_id] += hit.score
            # 排序并返回结果
            sorted_doc_scores = sorted(doc_scores.items(), key=lambda x: x[1], reverse=True)[:10]
            doc_ids = [pair[0] for pair in sorted_doc_scores]
            doc_data = []
            for doc_id in doc_ids:
                doc = searcher.doc(doc_id)
                data = {"title": doc["title"], "content": doc["content"]}
                doc_data.append(data)
            return doc_data

search_related_docs函数接受两个参数:搜索查询字符串 query_str 和索引存储路径 index_path。该函数使用 whoosh 库执行基于搜索词的相关匹配搜索,并将结果返回为包含文档标题和内容的字典列表。该函数使用 nltk 库进行词干提取和去除停用词的预处理,使用余弦相似度进行相关度排序。

以上代码仅是搜索程序的基本框架,还有很多需要考虑的因素,例如索引更新、索引分片、多语言支持、错误处理、结果过滤等等。这些因素需要从应用程序的实际情况出发,进行具体设计和实现。