[서평] 데이터로 경험을 디자인하라
데이터로 경험을 디자인하라 도서에 대해 리뷰해보자 :)
Embedding에 대해 알아보자 :)
모델 | 특징 | 적합성 |
1️⃣ Ko-SBERT (klue-roberta-base-sentence) | 한국어 문장 의미 기반 임베딩 | 🔼 요약/질문 응답 일치도 기반 검색에 적합 |
2️⃣ Korean-ELECTRA / KoBERT | 단어-문장 수준 의미 임베딩 | 🔼 규칙적 텍스트에 적합 |
3️⃣ OpenAI Embedding (text-embedding-3-small) | 긴 문서 + QA용에 최적화, 영어보다 성능 우수 | 🔼 QA 리트리버 구성에 유리 |
4️⃣ FastText / Word2Vec (도메인 커스터마이징) | 자체 학습 기반, 커스터마이징 가능 | 🔼 용어 특화 (예: "영업표지", "가맹본부") |
from transformers import BertTokenizer, BertModel import torch # 모델과 토크나이저 로딩 tokenizer = BertTokenizer.from_pretrained('klue/roberta-base') model = BertModel.from_pretrained('klue/roberta-base') # 예시 문장 sentence = "제이피토탈의 상호명은 무엇인가요?" # 토큰화 inputs = tokenizer(sentence, return_tensors='pt', padding=True, truncation=True, max_length=512) # 모델 실행 with torch.no_grad(): outputs = model(**inputs) # 문장 임베딩 sentence_embedding = outputs.last_hidden_state.mean(dim=1) print(sentence_embedding)
from transformers import ElectraTokenizer, ElectraModel import torch # 모델과 토크나이저 로딩 tokenizer = ElectraTokenizer.from_pretrained('monologg/kobert') model = ElectraModel.from_pretrained('monologg/kobert') # 예시 문장 sentence = "구포국수의 사업자등록일은 언제인가요?" # 토큰화 inputs = tokenizer(sentence, return_tensors='pt', padding=True, truncation=True, max_length=512) # 모델 실행 with torch.no_grad(): outputs = model(**inputs) # 문장 임베딩 sentence_embedding = outputs.last_hidden_state.mean(dim=1) print(sentence_embedding)
import openai # OpenAI API 키 설정 openai.api_key = 'your-api-key' # 예시 텍스트 text = "제이피토탈의 상호명은 무엇인가요? 구포국수의 영업표지는 어떤 것인가요?" # Embedding 요청 response = openai.Embedding.create( model="text-embedding-ada-002", # text-embedding-3-small 모델 사용 input=text ) # 임베딩 출력 embedding = response['data'][0]['embedding'] print(embedding)
import fasttext # 학습된 FastText 모델 로딩 (도메인에 맞는 모델을 미리 학습해야 합니다) model = fasttext.load_model('domain_specific_model.bin') # 예시 단어 word = "영업표지" # 단어 임베딩 word_embedding = model.get_word_vector(word) print(word_embedding)
설계안 | 구조 설명 | 특징 및 기대 효과 | 적합 활용 사례 |
1️⃣ 계층형 벡터 구조 (Hierarchical Fusion) | * 원문 → 문단 → 문장 → QA 단위로 임베딩 생성 * 벡터 간 계층 연결 및 문맥적 연관성 보존 | - 계층 구조로 문맥 정보 풍부 - QA 정확도 향상 - 상세 검색 가능 | 긴 민원 문서, 복합 질문 대응 |
2️⃣ Chunk + QA 벡터 혼합 구조 | Chunk 단위로 원문 분할하여 벡터화 + 요약 or QA 응답도 벡터화하여 저장 및 검색 활용 | - Chunk는 문맥 제공 - QA 벡터는 정밀 매칭용 - 효율적 검색 및 응답 최적화 | 짧은 민원, 실시간 질의응답 시스템 |
from sentence_transformers import SentenceTransformer import numpy as np # 모델 로드 model = SentenceTransformer('klue/roberta-base') # 원문 예시 document = "제이피토탈은 다양한 프랜차이즈 브랜드를 운영하고 있습니다. 구포국수는 그 중 하나로 유명합니다." paragraphs = document.split(". ") # 문단 단위로 분할 sentences = [p.split(". ") for p in paragraphs] # 문단을 문장으로 분할 # 문서 임베딩 document_embedding = model.encode([document], convert_to_tensor=True) # 문단 임베딩 paragraph_embeddings = model.encode(paragraphs, convert_to_tensor=True) # 문장 임베딩 sentence_embeddings = [] for p in sentences: sentence_embeddings.append(model.encode(p, convert_to_tensor=True)) # QA 임베딩 예시 (질문에 대한 답) qa_pairs = [ ("제이피토탈의 상호명은 무엇인가요?", "제이피토탈입니다."), ("구포국수의 특징은 무엇인가요?", "구포국수는 전통적인 맛을 자랑하는 국수집입니다.") ] qa_embeddings = [model.encode(pair, convert_to_tensor=True) for pair in qa_pairs] # 결과 확인 print("Document Embedding:", document_embedding) print("Paragraph Embeddings:", paragraph_embeddings) print("Sentence Embeddings:", sentence_embeddings) print("QA Embeddings:", qa_embeddings)
Chunk 단위로 나누어 벡터화하고, QA 응답을 각각 벡터화하여 이를 결합한 구조로 검색 및 응답 최적화# 문서 예시 (긴 민원 문서) long_document = """ 민원인이 요청한 사항은 다음과 같습니다. 첫 번째, 제이피토탈의 사업자 등록 정보를 확인하고 싶습니다. 두 번째, 구포국수의 매장 위치와 영업시간에 대해 문의드립니다. 마지막으로, 제이피토탈의 배달 서비스에 대한 정보도 필요합니다. """ # 문서를 Chunk 단위로 분할 (500자 단위) chunk_size = 500 chunks = [long_document[i:i+chunk_size] for i in range(0, len(long_document), chunk_size)] # Chunk 임베딩 생성 chunk_embeddings = model.encode(chunks, convert_to_tensor=True) # 각 Chunk에 대해 QA 벡터 생성 qa_pairs = [ ("제이피토탈의 사업자 등록일은 언제인가요?", "제이피토탈의 사업자 등록일은 2017년 2월 6일입니다."), ("구포국수의 영업시간은 언제인가요?", "구포국수는 오전 10시부터 오후 8시까지 운영됩니다."), ("제이피토탈의 배달 서비스는 어떻게 이용하나요?", "제이피토탈은 배달의 민족과 요기요 앱을 통해 배달 서비스를 제공합니다.") ] qa_embeddings = [model.encode(pair, convert_to_tensor=True) for pair in qa_pairs] # Chunk와 QA 벡터 통합 후 유사도 계산 import numpy as np similarities = [] for chunk in chunk_embeddings: for qa in qa_embeddings: similarity = np.dot(chunk.numpy(), qa.numpy()) / (np.linalg.norm(chunk.numpy()) * np.linalg.norm(qa.numpy())) similarities.append(similarity) # 유사도 출력 print("Similarity between chunks and QA pairs:", similarities)