logo

키워드 검색

순차 검색

실습 데이터 열기

import pandas as pd
df = pd.read_csv('neurips.zip')
df.head()

natural language 검색

query = {'natural', 'language'}

import re
def tokenize(text):
    text = text.lower() # 소문자로 변환
    return re.findall(r'\w{2,}', text) # 2글자 이상 단어 추출

표의 각 행에서 순서대로 검색어가 있는지 확인

%%time
results = []
for row in df.itertuples():
    words = set(tokenize(row.abstract))
    if query < words: # 검색어가 부분집합이면
        results.append(row.Index)

조건에 맞는 행 번호

len(results)

조건에 맞는 행 보기

df.loc[results].head()

리스트와 사전

a = list(range(1000000))

리스트에서 999999를 검색하는데 걸리는 시간 측정 리스트의 뒤로 갈 수록 검색이 오래 걸림

%%time
a.index(999999)
b = dict(zip(a, a))

검색 시간이 0에 가까움

%%time
b[999999]

인덱싱

from collections import defaultdict
index = defaultdict(set)

for row in df.itertuples():
    words = tokenize(row.abstract)
    for word in words:
        index[word].add(row.Index)

단어 language를 포함하는 모든 행 번호

len(index['language'])

natural과 language의 교집합(&)

%%time
results = list(index['natural'] & index['language'])

BM25

패키지 설치

!pip install langchain rank_bm25 kiwipiepy

파일 열기

import pandas as pd
books = pd.read_csv('science_books.csv')

토큰화 함수: 일반 명사, 고유명사, 영어, 동사, 형용사만 추출

from kiwipiepy import Kiwi
kiwi = Kiwi()

def tokenize(sent):
    for token in kiwi.tokenize(sent):
        if token.tag in {'NNG', 'NNP', 'SL', 'VV', 'VA'}:
            yield token.form, token.tag

인덱싱

from langchain.retrievers import BM25Retriever
bm25 = BM25Retriever.from_texts(
    texts=books['제목'],
    metadatas=None,
    preprocess_func=tokenize
)

IDF 보기

import pandas as pd
idf_table = pd.DataFrame(
    bm25.vectorizer.idf.items(), 
    columns=['token', 'idf'])
idf_table.sort_values('idf')

검색

query = '살아남은 것이 다정하다'
bm25.invoke(query)

검색 결과의 수 설정 (기본값 4)

bm25.k
Previous
BERT를 이용한 키워드 추출