logo
작성일

CH2. The Term Vocabulary and Postings Lists

Authors
  • avatar
    Name
    seren-wib
    Twitter
Contents

2. The term vocabulary and postings lists

2.1 Documents

문서가 뭔지 정의하는건 생각보다 어려운 질문이다

  1. ch1에서는 문서가 뭔지 알고, 읽을 수 있다는 것을 가정하고 넘어갔다.

  2. 현실에서는 문서 파싱(parsing a document)이 쉽지 않다.

    • 정해야 할 것이 3개 있다.
    정할 것예
    형식(format)pdf, word, excel, html
    언어(language)영어, 한국어, 프랑스어
    문자 집합(character set)UTF-8, EUC-KR. 같은 바이트도 인코딩 따라 다른 글자

    셋 다 분류(classification)문제이다.

    대안은 휴리스틱(heuristics)이다.

  3. 복잡한 경우(Complications)

    • 색인 하나에 여러 언어 term이 섞여 있는 경우
    • 문서 하나 안에서도 섞여 있는 경우
    • 색인 단위(document unit)을 뭘로 할지
    • 결론: 문서가 뭐냐는 질문은 답이 정해진 것이 아닌 설계 결정이다.

2.2 Terms

문서 → token → term으로 바꾸는 과정에서 생기는 문제들

용어뜻예
word텍스트에 나온 그대로의 글자열Windows, U.S.A.
term정규화된 word. 같은 걸로 치는 word 묶음(동치류)usa (U.S.A., USA)
token문서에 실제로 한 번 나온 것 하나"the the" → token 2개
type대부분 term과 같음. 같은 token 묶음"the the" → type 1개

General + Non-English

  1. 정규화(Normalization)

    • USA = U.S.A로 보기
  2. 언어에 따라 같은 단어도 다른 의미

  3. 토큰화(Tokenization): 어떤 token을 내보낼지

    • O'Neill → oneill? o'neill? o + neill?
  4. 한 단어인지 두 단어인지

    • 하이픈에서 끊을지말지, 띄어쓰기 했는데 같은 단어로 볼지
  5. 숫자

    • 3/20/91, 20/3/91, Mar 20, 1991은 전부 같은 날짜
    • 옛날 IR은 숫자를 색인 안했는데 대체로 하는게 유용하다.
  6. 띄어쓰기가 없는 언어: 어디서 끊냐?

  7. 악센트, 발음 기호

English

  1. 대소문자 통일(Case folding): 전부 소문자로 내리기

  2. 불용어(Stop words): 너무 흔해서 문서 고르는데 도움 안되는 단어

    • and, a, by 같은 것들
    • 예전에는 빼는게 표준이었는데 구문 질의에 필요해서 요새는 넣음
  3. 다른 동치류: 발음이 같거나 유의어

  4. 표제어 추출(Lemmatization)

    • 굴절·변형된 꼴 → 사전에 올라가는 기본형(lemma)
    • "제대로 된(proper)" 축소
    • 굴절(inflectional): 품사는 그대로, 꼴만 바뀜. cutting → cut
    • 파생(derivational): 품사까지 바뀜. destruction → destroy
  5. 어간 추출(Stemming)

    • 단어 끝을 대충 잘라내는 휴리스틱
    • 표제어 추출이 언어 지식으로 하려는 걸 대충 흉내냄
    • 언어마다 다르고, 굴절이랑 파생 둘 다 자른다
    • 예: automate, automatic, automation → 전부 automat. 결과가 사전에 없는 단어여도 상관없다.
    LemmatizationStemming
    방식언어 지식으로 기본형 찾기끝을 규칙으로 잘라내기
    결과사전에 있는 단어 (be, car)사전에 없을 수도 (automat, poni)
    정확도높음대충
    예am, are, is → beautomation → automat
  6. 포터 알고리즘(Porter algorithm)

    • 영어 어간 추출에서 제일 흔한 알고리즘
    • 규칙(convention) + 5단계(phase)를 순서대로 적용. 단계마다 명령(command) 여러 개가 있다
    • 명령 예: ement로 끝나고 떼고 남는 게 1글자보다 길면 뗌. replacement → replac / cement → cement (c 한 글자라 안 뗌)
    • 규칙 예: 복합 명령 안에선 가장 긴 접미사에 맞는 규칙 선택
    규칙예
    SSES → SScaresses → caress
    IES → Iponies → poni
    SS → SScaress → caress
    S → (삭제)cats → cat
    • caresses엔 SSES도 S도 맞지만 더 긴 SSES 선택 → caress (S면 caresse)

    스테머 3개 비교 (같은 문장 일부)

    원문PorterLovinsPaice
    analysisanalysianalysanalys
    featuresfeaturfeaturfeat
    easilyeasilieaseasy
    picturepicturpicturpict
    interpretationinterpretinterpresinterpret
    • 스테머마다 결과 다름. Porter가 제일 덜 자름 (Lovins는 the → th, Paice는 picture → pict까지)
  7. 어간 추출이 효과를 높이는가?

    • 질의에 따라 달라진다.
    • good case: [sightseeing tour san francisco] → {tour, tours}
    • bad case: [operational AND research] (운영 연구) → porter는 전부 oper로 묶기 때문에 operating, operative도 문서에 걸린다.
    • 묶어서 좋은 건 재현율(더 많이 찾기)이고 손해는 정밀도(엉뚱한 것도 찾기)이다.

2.3 Skip pointers

  1. 필요한 이유

    • ch1의 교집합은 리스트 길이에 선형이다 O(x+y)
    • 포스팅 리스트가 수백만개 짜리도 있어서 선형도 느릴 수 있다.
    • skip pointer은 결과에 안 들어갈 포스팅을 건너뛰게 해줘서 교집합이 더 빨라진다
    • 정할 것 두가지: skip을 어디에 둘지, 건너뛰어도 결과가 틀리지 않게 하려면 어떻게 할지
  2. 기본아이디어 skip pointer를 타고 19, 23을 건너뛰는 교집합 과정
    • 그림에서: 회색 화살표 = skip pointer, 노란 화살표 = 확인했지만 안 탐(대상이 상대보다 큼), 초록 화살표 = 탐
    • 예: p1이 16, p2가 41 → 16 < 41, skip(16) = 28 ≤ 41 → 28로 점프. 19, 23은 비교도 안 함
    • 일부 포스팅에 몇 칸 뒤로 바로 가는 포인터를 하나 더 단다.
    • 필수조건: skip이 가리키는 값 ≤ 상대 docID일 때만 점프. 상대보다 큰 데로 점프하면 그 사이에 일치를 놓칠수도 있기 때문에.
  3. 알고리즘(IntersectWithSkips)

    1. 두 docID가 같으면: answer에 추가, 둘 다 한 칸 전진 (ch1과 같음)
    2. 다르면 작은 쪽을 옮김
      • 작은 쪽에 skip이 있고 skip 대상 ≤ 상대 docID면: 조건이 맞는 동안 skip을 계속 탐 (while, 여러 번 연속 가능)
      • 아니면: 한 칸만 전진 (ch1과 같음)
    3. 한쪽이 끝나면 answer 반환
    • <가 아니라 <=: 같은 값으로 점프하면 그게 일치라서 손해 없음
    IntersectWithSkips(p1, p2)
     1 answer <- < >
     2 while p1 != nil and p2 != nil
     3 do if docID(p1) = docID(p2)
     4      then Add(answer, docID(p1))
     5           p1 <- next(p1)
     6           p2 <- next(p2)
     7      else if docID(p1) < docID(p2)
     8           then if hasSkip(p1) and (docID(skip(p1)) <= docID(p2))
     9                  then while hasSkip(p1) and (docID(skip(p1)) <= docID(p2))
    10                       do p1 <- skip(p1)
    11                  else p1 <- next(p1)
    12           else if hasSkip(p2) and (docID(skip(p2)) <= docID(p1))
    13                  then while hasSkip(p2) and (docID(skip(p2)) <= docID(p1))
    14                       do p2 <- skip(p2)
    15                  else p2 <- next(p2)
    16 return answer
    
  4. skip를 어디에 둘지

    skip 하나가 건너뛰는 양쓸 수 있는 빈도
    skip 많이 (간격 좁게)조금자주. 대신 비교 횟수·저장 공간 늘어남
    skip 적게 (간격 넓게)많이드물게. 대상이 상대보다 커서 못 쓰는 경우 많음
    • 휴리스틱: 길이 P 리스트에 √P개를 같은 간격으로. P = 16 → 4개, 4칸마다
    • 질의 term 분포는 무시함
    • 정적 색인이면 쉬움, 동적(문서 추가·삭제)이면 skip을 다시 놔야 해서 어려움
  5. 예전엔 도움 많이 됐는데, 요샌 CPU가 좋아서 크게 도움 안됨.

2.4 Phrase queries

  1. 구문질의(phrase queries)가 뭐고 왜 필요한지

    • [stanford university]는 두 단어가 붙어서, 그 순서대로 나와야 할 때
    • "The inventor Stanford Ovshinsky never went to university"는 둘 다 있지만 맞으면 안된다.
    • 웹 질의 중 상당수가 구문 질의.
    • 결론: 포스팅에 docID만 있으면 부족하다.
    • 해결책: biword 색인, positional 색인.
  2. Biword 색인

    • 붙어 있는 두 단어 쌍을 term 하나로 색인한다.
    • 예: Friends, Romans, Countrymen → friends romans, romans countrymen
    • 두 단어 구문은 바로 답할 수 있다.
    • 긴 구문: "stanford university palo alto" → "stanford university" AND "university palo" AND "palo alto"
      • 셋 다 있어도 네 단어가 이어져 있다는 보장 없음 → false positive → 결과를 다시 걸러야 함(post-filtering)
    • 잘 안 쓰이는 이유: false positive, 사전 폭발(index blowup)
  3. Positional 색인

    • biword보다 효율적인 대안
    positional 색인: 문서 교집합 후 문서 안에서 위치 비교
    • 그림에서: 위 표 = 1단계(docID 교집합, 행 하나가 포스팅 하나), 아래 = 2단계(4번 문서 안에서 to 위치 + 1 = be 위치 찾기)
    포스팅 하나
    보통 색인docID
    positional 색인docID + 그 문서 안에서 나온 위치 목록
    to, 993427:
      1: <7, 18, 33, 72, 86, 231>
      2: <1, 17, 74, 222, 255>
      4: <8, 16, 190, 429, 433>
      5: <363, 367>
    be, 178239:
      1: <17, 25>
      4: <17, 191, 291, 430, 434>
      5: <14, 19, 101>
    
    • to, 993427: 993427 = df / 4: <8, 16, ...> = 4번 문서의 8번째, 16번째 단어가 to
    • 질의 "to be or not to be" 처리
      1. docID 교집합 (ch1과 같음) → 둘 다 있는 문서가 후보
      2. 후보 문서 안에서 위치 비교: to가 i면 be는 i+1
      3. 4번 문서: to 429, be 430, to 433, be 434 → 429부터 to be or not to be → match
  4. 근접 검색(Proximity search)

    • positional 색인이 있으면 Westlaw의 /k도 가능
    • employment /4 place: 두 단어가 4단어 이내
      • "Employment agencies that place healthcare workers ..." → hit (1번째, 4번째: 거리 3)
      • "Employment agencies that have learned to adapt now place ..." → hit 아님 (1번째, 9번째: 거리 8)
    • 단순한 방법은 두 단어 위치를 모든 쌍으로 비교(cross-product) → the 같은 흔한 단어면 너무 느림
    • 문서 목록만이 아니라 맞은 위치까지 돌려줘야 한다 (검색 결과 요약 문장 만들 때 씀)
  5. PositionalIntersect(p1, p2, k)

    한 문서 안에서 pp1, pp2, l이 움직이며 k 이내 위치 쌍을 찾는 과정
    • p1, p2 = 문서(docID) 가리키는 포인터 / pp1, pp2 = 그 문서 안의 위치 목록 가리키는 포인터
    • 그림에서: 초록 띠 = pp1 위치 ± k 범위, l = 띠 안에 들어온 term 2 위치들, answer = (term 1 위치, term 2 위치) 쌍
    • 바깥은 ch1 Intersect 그대로, 같은 문서를 찾으면 안에서 위치끼리 비교
    • l = 지금 pp1 위치에서 k 이내인 pp2 위치 목록 (창문처럼 씀)
    • pp2를 밀면서 k 이내면 l에 넣고, pp1보다 너무 뒤로 가면 멈춤
    • pp1이 앞으로 가면 k보다 멀어진 l 앞쪽 값을 버림
    • l에 남은 것마다 (docID, pp1 위치, pp2 위치)를 answer에 추가
  6. Combination scheme

    • biword + positional 섞어 쓰기
    • 아주 자주 나오는 biword(Michael Jackson, Britney Spears)만 term으로 색인 → 위치 비교 없이 바로 답해서 빠름
    • 나머지 구문은 positional 교집합
    • Williams et al. (2004): positional보다 빠르고 공간은 26% 더 씀
  7. 구글에서 positional 질의는 비싸다

    • 포스팅마다 위치 목록까지 읽어야 하고, docID 교집합 뒤에 위치 비교를 한 번 더 해야 해서