0. 유사도 모델(Euclidean, Vector)

# Euclidean Distance - 단어와 문서안의 단어의 수를 가지고 유사도를 구한다. (단점: 문서가 너무 길면 아무리 좋은 문서도 유사도가 낮다.)
# Vector - 거리를 구하는 것이 아닌 경향성 방향성을 보고 유사도를 구한다. ( BoW => TF-IDF )
# Vector의 내적을 구하는 방법 - Cos@
# Vector의 내적 외적으로 만듦

 

 

Ngram 모델 => 빈도가 작다보니 확률이 0이 될 수가 있음

=> 차라리 단어의 패턴을 찾는데에 사용을 하자

 

=> 욕설제거 => chunk를 만듦 => 형태소 분석기를 사용 => tag_set으로 품사를 분석 => 단어의 길이나 빈도로 정규화( zipf의 법칙을 통해 중간 영역이 필요하다는 것을 알 수 있었음 ) 

 

Collocation => 쌍들이 갖는 정보가 없을까 해서

- pmi, chi_sq 를 통해 정보를 봄

 

=> WordClude를 가지고 데이터를 출력해줌

 

 

정보 검색이란(information retrieval)

- 자동으로 정보를 획득하기 위해 사용

- relevant, 사용자의 니드를 찾음

 

1) full-text indexing

- vector로 표현

- linear한 정보가 없음

 

 

TREC 

- 텍스트 검색 컨퍼런스

- 누가 더 검색을 잘하는 지

 

Page Link

- 알아보기

 

Back word model

 

https://www.cs.virginia.edu/~hw5x/Course/IR2015/_site/lectures/

 

 

1. TDM 만들기

- 단어의 빈도수 표현

from konlpy.corpus import kobill

# 제목이 매칭되지 않았기 때문에 어떤 문서인지 알 수 없기 때문에 문서 제목을 저장하는 형태로 변경
DTM = defaultdict(lambda: defaultdict(int))
for idx in kobill.fileids():
    for term in kobill.open(idx).read().split():
        DTM[idx][term] += 1
    
TDM = defaultdict(lambda: defaultdict(int))
for idx, termList in DTM.items():
    for term, freq in termList.items():
        TDM[term][idx] = freq
        
TWM = defaultdict(lambda:defaultdict(float))
N = len(DTM)
for idx, termList in DTM.items():
    maxTF = max(termList.values())
    for term, freq in termList.items():
        TF =  freq/maxTF
        IDF = log2(N/len(TDM[term]))
        TWM[term][idx] = TF*IDF

 

 

2. TWM (TF-IDF) 

-TF-IDF로 해당 단어의 중요도를 표현

 

from konlpy.corpus import kobill
from konlpy.tag import Komoran
from math import sqrt

ma = Komoran()

# 제목이 매칭되지 않았기 때문에 어떤 문서인지 알 수 없기 때문에 문서 제목을 저장하는 형태로 변경
DTM = defaultdict(lambda: defaultdict(int))
for idx in kobill.fileids():
    for term in kobill.open(idx).read().split():
        for token in ma.pos(term):
            DTM[idx]["/".join(token)] += 1
    
TDM = defaultdict(lambda: defaultdict(int))
for idx, termList in DTM.items():
    for term, freq in termList.items():
        TDM[term][idx] = freq
        
TWM = defaultdict(lambda:defaultdict(float))
N = len(DTM)
DVL = defaultdict(float)
for idx, termList in DTM.items():
    maxTF = max(termList.values())
    for term, freq in termList.items():
        # 데이터 벡터
        TF =  freq/maxTF
        IDF = log2(N/len(TDM[term]))
        TWM[term][idx] = TF*IDF
        DVL[idx] += TWM[term][idx]**2

for idx, length in DVL.items():
    DVL[idx] = sqrt(length)

 

 

3. Query의 중요도 표현

query = "국방의 의무와 보편적 의무에 대한 의무를 찾아주세요."

TQM = defaultdict(int)
QTWM = defaultdict(float)

for term in query.split():
    for token in ma.pos(term):
        TQM["/".join(token)] += 1
        
alpha = 0.5
maxTF = max(TQM.values())
for term, freq in TQM.items():
    TF = alpha + (1-alpha)*(freq/maxTF)
    #IDF = LEN(TWM[TERM])
    DF = len(TWM[term]) if len(TWM[term]) else 1
    IDF = log2(N/DF) # Smoothing IDF
    QTWM[term] = TF*IDF

 

4. 문서와 Query의 유사도
candidateList = defaultdict(float)
for term, weight1 in QTWM.items():
    for doc, weight2 in TWM[term].items():
        innerProduct = weight1 * weight2
        candidateList[doc] += innerProduct

for doc, sim in candidateList.items():
    candidateList[doc] = sim/DVL[doc]

 

 

5. 출력

from nltk.tokenize import sent_tokenize
K = 5
for doc, sim in sorted(candidateList.items(), key=lambda x:x[1], reverse=True)[:K]:
    print("문서이름:{0} / 유사도:{1:.4f}".format(doc, sim))
    print(sent_tokenize(kobill.open(doc).read())[:3])
    print()

 

 

+ Recent posts