
북마크한 페이지에서 의미 있는 키워드를 자동으로 추출해야 한다.
서비스 초기에는 데이터가 부족하기 때문에, 이러한 환경에서도 원활하게 키워드를 추출할 수 있어야 한다.
또한, 키워드 추출 속도가 너무 느리지 않도록 최적화해야 한다.
향후에는 사용자가 선택한 키워드의 기록을 학습하여, 점점 더 사용자 맞춤형 키워드를 제공하는 시스템으로 발전시키고자 한다.
데이터가 없는 환경에서는 비지도 학습 기반의 키워드 추출 방법이 효과적이다.
입력 데이터와 정답 데이터가 충분하면 지도 학습을 사용할 수 있지만,
프로젝트 초기에는 이러한 데이터가 부족하기 때문에 비지도 학습을 활용하는 것이 적합하다.
비지도 학습 기반의 알고리즘을 적용하여, 사용자의 개입 없이 자연스럽게 중요한 단어를 선별하는 방식을 선택했다.
처음 키워드 추출 알고리즘으로 선택한 것은 TF-IDF(Term Frequency-Inverse Document Frequency) 알고리즘이다.
이 알고리즘은 단어 빈도(TF) × 역문서 빈도(IDF)를 계산하여,
문서에서 상대적으로 중요한 단어를 찾는 비지도 학습 기법이다.
단어 빈도(TF): 특정 단어가 문서에서 얼마나 자주 등장하는지를 나타낸다.
역문서 빈도(IDF): 특정 단어가 여러 문서에서 얼마나 희귀한지를 나타낸다.
위 두 값을 곱하여 문서 내 단어들의 중요도를 평가한다.
TF-IDF를 활용한 키워드 추출 방식은 졸업 작품의 요구사항과도 잘 맞았다.
졸업 작품에서는 프로젝트만의 독창적인 알고리즘을 만들어야 하는 요구사항이 있었다.
이를 위해,
1. TF-IDF를 활용하여 문서에서 주요 키워드를 추출한 후,
2. 사용자가 북마크 생성 시 입력한 키워드의 가중치를 높여,
3. 사용자의 기록이 쌓일수록 맞춤형 키워드를 추천하는 방식을 설계했다.
이를 통해, 단순한 TF-IDF를 넘어 사용자의 행동 데이터를 반영한 개선된 키워드 추출 방식을 구현할 수 있을 것으로 기대했다.
TF-IDF를 효과적으로 적용하려면 텍스트를 문단 단위로 분할하는 과정이 필수적이었다.
이를 해결하기 위해, HTML에서 문단 단위로 구분하는 과정을 추가했다.
하지만, 블로그마다 문단을 구분하는 방식이 다르기 때문에 태그 기반 분할 방식이 불완전했다.
RecursiveCharacterTextSplitter 활용HTML 태그를 기반으로 나누는 대신,
RecursiveCharacterTextSplitter를 사용하여 텍스트를 유연하게 분할하는 방식을 선택했다.
이 방식은 다음과 같은 단계를 거친다.
\n\n 기준)로 우선 분할 \n)로 추가 분할 .) 기준으로 다시 나누기 chunk_size 이하가 될 때까지 재귀적으로 분할 이를 통해, 문서 내 적절한 크기의 의미 단위를 유지하면서 문장을 나눌 수 있었다.
TF-IDF를 적용한 후, 한국어와 영어가 혼합된 문서에서 문제 발생
nltk 라이브러리에서 기본적인 불용어 목록 제공 → 손쉽게 적용 가능 konlpy의 형태소 분석기를 활용하여 한국어 명사만 추출 nltk.word_tokenize()를 사용하여 분할 최종적으로, 한국어 & 영어가 자연스럽게 포함된 키워드를 추출할 수 있도록 개선했다.
TF-IDF는 문서 간 상대적인 중요도를 측정하는 방식이지만, 다음과 같은 한계가 있다.
TF-IDF 외의 비지도 학습 기반 알고리즘 테스트
향후 강화학습을 활용하여 추천 시스템 고도화
현재 키워드 추출 속도는 5~10초가 소요됨.
async 기능 활용하여 동시에 여러 문서 처리 가능 multiprocessing.Pool() 또는 ThreadPoolExecutor를 활용한 병렬 처리 적용 현재 TF-IDF 기반 키워드 추출을 적용하여 기본적인 기능을 구현했지만,
성능 최적화와 문맥 이해를 고려한 키워드 추출 개선이 필요하다.
향후, 비지도 학습을 활용한 다른 알고리즘을 도입하고,
사용자의 피드백을 반영하는 강화학습 기반 추천 시스템으로 발전시키는 것이 목표다.