Skip to main content

keyword-search

순차 검색

실습 데이터 열기

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