사전 용어 빈도
알고리즘

용어 빈도

gabury1고친 사람 github-actions[bot]

용어 빈도는 한 낱말이 한 문서에 몇 번 나왔는지를 세어 줍니다. 많이 나올수록 그 문서가 그 낱말을 두고 쓴 글일 가능성이 큽니다. 검색 엔진이 문서에 점수를 매길 때 바탕으로 삼는 값입니다.

쉽고 빠른 이해

용어 빈도는 낱말이 글에 몇 번 나왔는지 센 숫자입니다. 「파이썬」이 어떤 글에 세 번 나오면 그 글에서 「파이썬」의 용어 빈도는 3 입니다.

이 숫자가 없으면 검색 엔진은 낱말이 글에 들었는지만 압니다. 「파이썬」이 든 글이 백 개면 백 개가 모두 같은 줄에 섭니다. 파이썬을 다룬 글과 한 번 스친 글을 가르지 못합니다.

  1. 글을 낱말 단위로 쪼갭니다
  2. 낱말마다 나온 횟수를 셉니다
  3. 검색할 때 그 횟수를 점수에 보탭니다

대가가 있습니다. 긴 글일수록 횟수가 쉽게 쌓입니다. 같은 낱말을 일부러 되풀이한 글도 점수를 얻습니다. 그래서 검색 엔진은 횟수를 다듬어서 씁니다.

제목처럼 짧은 글에서는 이 숫자가 힘을 못 씁니다. 낱말이 거의 다 한 번씩만 나와서 모두 1 이 되기 때문입니다. 글자가 다른 같은 뜻의 낱말도 못 셉니다. 「자동차」로 찾으면 「차량」만 쓴 글은 0 입니다.

상세

용어 빈도는 낱말 하나와 문서 하나를 받아 횟수 하나를 돌려줍니다. 그 낱말이 그 문서에 몇 번 나왔는지가 답입니다. 줄여서 TF(Term Frequency)라고 적습니다. 낱말 빈도나 단어 빈도도 같은 값을 가리킵니다.

「파이썬 설치 파이썬 버전 파이썬」이라는 짧은 문서를 봅시다. 「파이썬」의 TF 는 3, 「설치」는 1 입니다. 문서에 없는 「자바」는 0 입니다. 이 문서 하나만 보고 세므로 다른 문서는 볼 필요가 없습니다.

횟수는 그 문서가 무엇을 다루는지 알려 줍니다. 파이썬 설치를 다룬 글은 「파이썬」을 여러 번 씁니다. 다른 주제를 쓰다가 파이썬을 스친 글은 한두 번 쓰고 맙니다. 검색 엔진은 이 차이로 더 맞는 글을 위에 올립니다.

「단어 빈도」라는 이름은 다른 값에도 쓰입니다. 언어학에서는 분석하려고 모아 둔 글 전체, 곧 말뭉치에서 낱말이 몇 번 나왔는지 센 값을 그렇게 부릅니다. 낱말이 얼마나 흔한지 잴 때 쓰는 값입니다. 이 항목의 용어 빈도는 그와 달리 문서 하나 안의 횟수입니다.

한 용어로 세는 단위

횟수를 세려면 먼저 문서를 쪼개서 무엇을 「한 낱말」로 칠지 정해야 합니다.

검색에서 용어는 문서를 쪼개고 다듬은 뒤 남은 조각 하나를 말합니다. 이 항목이 낱말이라 부르는 것이 이 용어입니다. 쪼개는 일을 토큰화라고 부릅니다. 띄어쓰기를 기준으로 자르는 것이 가장 단순한 방법입니다.

다듬는 방식이 횟수를 바꿉니다. 「Python」과 「python」을 다른 낱말로 보면 같은 언어가 두 칸에 나뉘어 셉니다. 그래서 대소문자를 하나로 맞춘 뒤 셉니다.

한국어는 조사가 붙어서 문제가 더 큽니다. 「파이썬을」·「파이썬은」·「파이썬」을 띄어쓰기로만 자르면 세 낱말이 됩니다. 형태소 분석으로 조사를 떼어 내야 셋이 모두 「파이썬」 하나로 셉니다.

쪼개고 다듬는 일을 묶어 맡는 부품을 분석기라고 부릅니다. 같은 문서라도 분석기가 다르면 TF 가 달라집니다.

「그리고」처럼 어디에나 있는 낱말을 아예 빼고 세는 분석기도 있습니다. 이렇게 빼는 낱말을 불용어라 합니다. 흔하기만 하고 주제를 알려 주지 않는 낱말이 횟수를 차지하지 않게 하려는 것입니다.

세는 절차와 비용

용어로 쪼갠 다음에는 세기만 하면 됩니다. 짧은 코드 한 토막으로 절차와 드는 비용을 봅니다.

용어마다 칸을 하나씩 둔 표를 만듭니다. 문서를 앞에서부터 읽습니다. 용어를 만날 때마다 그 칸에 1 을 더합니다. 끝까지 읽으면 표의 각 칸이 그 용어의 TF 입니다.

아래 코드는 앞의 짧은 문서를 이렇게 셉니다. 띄어쓰기로만 쪼개는 가장 단순한 분석기를 썼습니다. 각 줄 오른쪽 주석이 돌려받는 값입니다.

Python
from collections import Counter

doc = "파이썬 설치 파이썬 버전 파이썬"
tf = Counter(doc.split())

tf["파이썬"]  # 3
tf["버전"]    # 1
tf["자바"]    # 0

Counter 는 용어마다 횟수를 담는 표입니다. 문서에 없는 「자바」를 물으면 오류 대신 0 을 돌려줍니다.

표는 흔히 해시테이블로 둡니다. 해시테이블은 칸이 많아져도 칸 하나를 찾는 시간이 평균적으로 거의 늘지 않는 표입니다. 그래서 용어 하나를 더하는 비용은 평균 O(1) 입니다.

문서의 용어 수를 n 이라 하면 문서 하나를 다 세는 데 O(n) 이 듭니다. 글이 두 배로 길면 세는 시간도 두 배라는 뜻입니다. 표가 차지하는 공간은 그 문서에 든 서로 다른 용어의 수만큼입니다.

역색인에 함께 적어 두는 값

검색할 때마다 문서를 다시 열어 세면 너무 느립니다. 그래서 TF 는 미리 세어 담아 둡니다.

검색 엔진은 문서를 받을 때 TF 를 한 번 세어 역색인에 적어 둡니다. 역색인은 용어마다 그 용어가 든 문서 번호를 적어 둔 목록입니다. 책 뒤의 찾아보기가 낱말마다 쪽 번호를 적어 둔 것과 같은 꼴입니다.

목록의 한 칸을 포스팅이라고 부릅니다. 용어 하나의 목록 전체가 포스팅 리스트입니다. 포스팅에는 문서 번호와 함께 그 문서에서의 TF 를 적습니다. 그러면 검색할 때 목록만 읽어도 횟수를 압니다.

아래 그림은 용어 둘의 포스팅 리스트입니다. 칸은 화살표를 따라 이어집니다. 칸마다 문서 번호와 TF 가 들어 있습니다.

flowchart TD
    A["용어 · 파이썬"] --> A1["문서 3 · TF 5"]
    A1 --> A2["문서 8 · TF 1"]
    A2 --> A3["문서 12 · TF 2"]
    B["용어 · 설치"] --> B1["문서 3 · TF 1"]
    B1 --> B2["문서 20 · TF 4"]

「파이썬」의 목록은 세 칸입니다. 문서 3 에 다섯 번, 문서 8 에 한 번 나왔다는 것을 문서를 열지 않고 읽습니다.

횟수만 쓰면 생기는 문제

날것의 횟수를 바로 점수로 쓰면 세 군데서 어긋납니다.

첫째는 문서 길이입니다. 백 낱말짜리 글과 만 낱말짜리 글이 같은 주제를 다룬다고 합시다. 긴 글은 같은 낱말을 훨씬 많이 품습니다. 횟수만 보면 긴 글이 늘 앞섭니다.

둘째는 횟수가 끝없이 효과를 낸다는 것입니다. 스무 번 나온 낱말이 열 번 나온 낱말의 두 배 점수를 받습니다. 열 번 나왔으면 이미 그 낱말을 두고 쓴 글입니다. 열 번 더 나온다고 두 배 더 맞는 글이 되지는 않습니다.

셋째는 일부러 부풀린 글입니다. 검색 결과 위에 오르려고 같은 낱말을 수십 번 되풀이한 글이 있습니다. 이런 수법을 키워드 스터핑이라고 부릅니다. 날것의 횟수는 이런 글에 가장 큰 점수를 줍니다.

횟수를 다듬는 변형

앞의 문제를 누르려고 횟수를 바꿔 쓰는 방법이 여럿입니다. 그중 하나가 로그를 씌우는 것입니다. 로그는 값이 열 배 커질 때마다 결과를 1 씩만 올리는 함수입니다. 밑이 10 일 때 그렇습니다.

무엇으로 바꾸는지와 어느 문제를 고치는지를 표로 모읍니다.

변형 바꾸는 법 고치는 문제
날것 횟수 나온 횟수를 손대지 않고 쓴다 없다. 가장 단순한 꼴
들었는지만 보기 나왔으면 1, 안 나왔으면 0 되풀이로 부풀리기
로그 씌우기 1 + log(TF). 열 배 늘 때 1 씩만 오른다 끝없이 커지는 효과
길이로 나누기 TF 를 문서의 용어 수로 나눈다 긴 문서가 앞서는 것
포화 횟수가 늘수록 한 값에 다가가게 누른다 끝없이 커지는 효과와 부풀리기

들었는지만 보면 부풀리기는 막습니다. 대신 횟수가 주던 정보도 함께 버립니다. 나머지 셋은 횟수를 살리면서 그 효과만 누릅니다.

아래 코드는 로그를 씌운 TF 를 셈합니다. 횟수 1, 10, 100 을 차례로 넣어 봅니다.

Python
import math

def log_tf(tf):
    return 1 + math.log10(tf) if tf else 0

log_tf(1)    # 1.0
log_tf(10)   # 2.0
log_tf(100)  # 3.0

한 번 나온 낱말은 1, 백 번 나온 낱말은 3 입니다. 백 배 더 나와도 점수는 세 배에 그칩니다. 0 에는 로그를 씌울 수 없으므로 안 나온 낱말은 0 을 따로 돌려줍니다.

길이로 나누는 쪽은 문서 길이를 셈에 넣습니다. 문서 A 는 용어 100 개 가운데 「파이썬」이 3 번 나옵니다. 문서 B 는 용어 1000 개 가운데 6 번 나옵니다. 날것 횟수로는 B 가 앞섭니다. 길이로 나누면 A 는 0.03, B 는 0.006 입니다. 이제 A 가 앞섭니다.

포화는 BM25(Best Matching 25)가 쓰는 방식입니다. 횟수가 처음 몇 번 늘 때는 점수가 크게 오릅니다. 어느 선을 넘으면 거의 오르지 않습니다.

BM25 는 문서 길이도 셈에 넣습니다. 다만 용어 수로 그대로 나누지 않고 문서 길이를 평균 길이와 견줍니다. 평균보다 긴 문서일수록 횟수를 더 깎습니다. 앞의 길이로 나누기와 이 방식을 묶어 길이 정규화라 합니다.

다른 값과 짝을 이루는 까닭

TF 는 문서 하나만 보고 셉니다. 그래서 그 낱말이 문서 모음, 곧 검색 엔진이 담아 둔 문서 전체에서 얼마나 흔한지는 모릅니다. 그 빈틈은 다른 값이 메웁니다.

「파이썬 설치 방법」으로 찾는다고 합시다. 「방법」은 거의 모든 설명글에 들어 있습니다. 한 글 안에서도 여러 번 나오기 쉽습니다. TF 만 더하면 「방법」을 여러 번 쓴 엉뚱한 글이 올라옵니다.

그래서 TF 에 낱말이 얼마나 드문지를 곱합니다. 드문 정도는 문서 빈도에서 나옵니다. 문서 빈도는 그 낱말이 든 문서의 개수입니다. 거의 모든 글에 든 「방법」은 문서 빈도가 아주 큽니다.

역문서 빈도는 문서 빈도가 클수록 작아지는 무게입니다. 「방법」은 이 무게가 작아서 TF 가 높아도 점수가 조금만 오릅니다. 「파이썬」처럼 드문 낱말은 무게가 커서 점수에 더 크게 보탭니다.

세 값을 나란히 놓으면 차이가 보입니다.

값 세는 것 봐야 하는 범위
용어 빈도 한 문서 안에서 낱말이 나온 횟수 문서 하나
문서 빈도 낱말이 든 문서의 개수 문서 모음 전체
역문서 빈도 문서 빈도가 클수록 작아지는 무게 문서 모음 전체

TF 만 문서 하나로 끝납니다. 그래서 새 문서가 들어와도 다른 문서의 TF 는 바뀌지 않습니다. 나머지 둘은 문서가 들어올 때마다 조금씩 움직입니다.

TF 와 역문서 빈도를 곱한 점수가 TF-IDF(Term Frequency-Inverse Document Frequency)입니다. BM25 도 같은 뼈대에 앞 소절의 포화와 길이 정규화를 더한 셈식입니다. 두 셈식에서 TF 는 「이 문서가 이 낱말을 얼마나 다루나」를 맡습니다.

쓸 때와 안 쓸 때

TF 는 검색 순위 말고도 글을 숫자로 바꾸는 데 씁니다. 그 쓰임에는 TF 가 잘 듣는 경우와 힘을 못 쓰는 경우가 있습니다.

문서 모음의 용어마다 칸을 둡니다. 칸마다 TF 를 적으면 문서 하나가 숫자 목록 하나가 됩니다. 낱말의 순서는 버리고 횟수만 남기는 이 관점이 단어 가방 모델입니다. 이 목록을 텍스트 분류 모델에 넣거나 문서끼리 닮은 정도를 잴 때 씁니다.

한 문서에서 TF 가 높은 낱말을 뽑으면 그 문서가 무엇을 다루는지 대강 보입니다. 이 일을 키워드 추출이라고 부릅니다. 흔한 낱말이 위에 오기 쉬우므로 불용어를 빼거나 역문서 빈도를 곱한 뒤 뽑습니다.

제목이나 태그처럼 짧은 글에서는 TF 가 힘을 못 씁니다. 거의 모든 낱말이 한 번씩만 나와서 TF 가 다 1 입니다. 들었는지만 보는 것과 결과가 거의 같습니다.

TF 는 글자가 같은 낱말만 셉니다. 「자동차」로 찾으면 「차량」만 쓴 글의 TF 는 0 입니다. 뜻이 맞는 글을 찾으려면 임베딩을 씁니다. 임베딩은 글의 뜻을 숫자로 옮깁니다. 그 숫자끼리 가까운 글을 찾는 일이 벡터 검색입니다.

관련 항목

용어 빈도와 짝을 이뤄 점수를 내는 값

문서 빈도 · 역문서 빈도 · 문서 길이 · 길이 정규화 · 로그 함수 · 포화 함수

용어 빈도를 재료로 쓰는 점수 셈식

TF-IDF · BM25 · BM25F · 벡터 공간 모델 · 확률 모델 · 언어 모델 검색 · 순위 모델

용어 빈도를 세기 전에 글을 쪼개는 처리 단계

분석기 · 토큰화 · 형태소 분석 · 불용어 · 어간 추출 · n-gram

용어 빈도를 담아 두는 색인 구조

역색인 · 포스팅 · 포스팅 리스트 · 해시테이블 · 희소 벡터

용어 빈도가 속하는 검색 기법

검색 · 정보 검색 · 전문 검색 · 관련도 · 랭킹 · 불리언 검색

용어 빈도로 푸는 텍스트 작업

단어 가방 모델 · 텍스트 분류 · 키워드 추출 · 문서 군집화 · 코사인 유사도

용어 빈도가 못 잡는 뜻을 메우는 수단

임베딩 · 벡터 검색 · 시맨틱 검색 · 동의어 사전

용어 빈도를 노리는 검색 순위 조작

키워드 스터핑 · 검색 엔진 최적화 · 웹 스팸

말뭉치 전체의 낱말 빈도를 다루는 언어학 개념

지프의 법칙 · 말뭉치 · 말뭉치 언어학

다른 이름: TF · Term Frequency · 낱말 빈도 · 단어 빈도