빈도수(Frequency)

애늙은이·2023년 8월 27일
0

NLP 여행기

목록 보기
8/13
post-thumbnail
post-custom-banner

코퍼스 데이터를 처리하다보면 빈도수를 활용하는 경우가 많습니다. 자주 사용되는 단어가 무엇인지 알면 해당 데이터의 경향성을 파악할 수 있기 때문이죠.

단어의 빈도수를 측정하는 대표적인 방법으로는 count() 메소드를 사용하는 경우와 NLTK의 FreqDist를 사용하는 경우가 있습니다.

📈 빈도수 측정하기

count() 메소드를 활용하여 토큰화된 리스트 내 특정 단어의 개수를 알 수 있습니다.

from nltk.tokenize import word_tokenize

text = """
Panic on the brain, world has gone insane
Things are starting to get heavy, mm
I can't help but think I haven't felt this way
Since I asked you to go steady
Wonderin', would you be, my little quarantine?
Or is this the way it ends?
'Cause I told you my level of concern
But you walked by like you never heard
And you could bring down my level of concern
Just need you to tell me we're alright, tell me we're okay
Panic on the brain, Michael's gone insane
Julie starts to make me nervous
I don't really care what they would say
I'm asking you to stay
My bunker underneath the surface
Wonderin', would you be, my little quarantine?
Or is this the way it ends?
'Cause I told you my level of concern
But you walked by like you never heard
And you could bring down my level of concern
Just need you to tell me we're alright, tell me we're okay, yeah
Tell me we're alright, tell me we're okay, yeah
Tell me we're alright, tell me we're okay
Bring down my level of concern
Just need you to tell me we're alright, tell me we're okay, yeah
""" # lyrics of 「level of concern」 by twenty one pilots

text = text.lower()
token_lst = word_tokenize(text)

print(token_lst.count('quarantine'))


# 결과
# 2

NLTK 내 FreqDist 클래스를 활용하여 단어 별 빈도수를 알 수도 있습니다. FreqDist를 사용하기 위해서는 토큰화된 텍스트를 인자로 넘겨줘야 합니다.

from nltk.tokenize import word_tokenize
from nltk import FreqDist

text = """
Panic on the brain, world has gone insane
Things are starting to get heavy, mm
I can't help but think I haven't felt this way
Since I asked you to go steady
Wonderin', would you be, my little quarantine?
Or is this the way it ends?
'Cause I told you my level of concern
But you walked by like you never heard
And you could bring down my level of concern
Just need you to tell me we're alright, tell me we're okay
Panic on the brain, Michael's gone insane
Julie starts to make me nervous
I don't really care what they would say
I'm asking you to stay
My bunker underneath the surface
Wonderin', would you be, my little quarantine?
Or is this the way it ends?
'Cause I told you my level of concern
But you walked by like you never heard
And you could bring down my level of concern
Just need you to tell me we're alright, tell me we're okay, yeah
Tell me we're alright, tell me we're okay, yeah
Tell me we're alright, tell me we're okay
Bring down my level of concern
Just need you to tell me we're alright, tell me we're okay, yeah
""" # lyrics of 「level of concern」 by twenty one pilots

text = text.lower()
tokens = word_tokenize(text)

freq = FreqDist(tokens) # 토큰화 결과를 FreqDist에 넘겨줍니다.

print(dict(freq)) # dict 자료형으로 변환하여 단어 별 빈도수를 확인할 수 있습니다.
print(freq.most_common(10)) # 빈도수가 높은 상위 10개의 토큰과 빈도수를 반환합니다.

이뿐만 아닌 FreqDist에서 제공하는 여러 메소드를 통해 전체 토큰수와 샘플수를 알 수 있고, 그래프로도 시각화할 수 있습니다. 더 자세한 내용은 FreqDist 클래스의 코드를 살펴보시길 바랍니다.

from nltk.tokenize import word_tokenize
from nltk import FreqDist

text = "Change will not come if we wait for some other person or some other time. We are the ones weve been waiting for. We are the change that we seek."

text = text.lower()
tokens = word_tokenize(text)
frequency = FreqDist(tokens)

print(frequecy.N()) # 전체 토큰수를 반환합니다. len(tokens)와 같습니다.
print(frequency.B()) # 전체 샘플수를 반환합니다. len(freq)와 같습니다.
print(frequency.freq("change")) # 특정 샘플의 빈도가 텍스트에서 차지하는 비율을 구해줍니다.
print(frequency.plot(title="text frequency")) # 샘플 별 빈도수를 그래프로 보여줍니다. 인자를 설정하여 그래프 모양이나 값 등을 조정할 수 있습니다.

🔥 빈도수 활용하기

토큰화, 품사 태깅, 불용어 처리, 표제어 추출, 빈도수를 활용하여 빈도 분석을 진행해보겠습니다. 사용한 텍스트는 성냥팔이 소녀입니다.

from nltk.tokenize import RegexpTokenizer
from nltk.tag import pos_tag
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from nltk import FreqDist

# 성냥팔이 소녀 전문을 텍스트 파일로 저장하여 진행하였습니다.
with open("./the_little_match_girl.txt", "r", encoding='utf-8') as f:
    text = f.read()

text = text.lower() # 대소문자를 통일합니다.

tokenizer = RegexpTokenizer('[\w]+') # 정규표현식을 활용할 수 있는 RegexpTokenizer를 사용했습니다. 
tokens = tokenizer.tokenize(text) # 단어 토큰화

stopword_lst = stopwords.words('english')
removed_tokens = [token for token in tokens if token not in stopword_lst] # 불용어 처리

pos_tags = pos_tag(removed_tokens) # 품사 태깅

lemmatizer = WordNetLemmatizer()
lemma_result = []

# 표제어 추출을 진행합니다.
for token, tag in pos_tags:
    if tag.startswith('N'):
        lemma = lemmatizer.lemmatize(token, pos='n') 
    elif tag.startswith('V'):
        lemma = lemmatizer.lemmatize(token, pos='v')
    elif tag.startswith('J'):
        lemma = lemmatizer.lemmatize(token, pos='a')
    elif tag.startswith('R'):
        lemma = lemmatizer.lemmatize(token, pos='r')
    else:
        lemma = lemmatizer.lemmatize(token)

    lemma_result.append(lemma)

freq = FreqDist(lemma_result)
print(freq.most_common(10)) # 상위 10개에 해당하는 토큰과 빈도수를 구합니다.


# 결과
# [('little', 15), ('match', 13), ('one', 11), ('girl', 10), ('cold', 9), ('burn', 7), ('hand', 6), ('go', 6), ('warm', 6), ('wall', 6)]

RegexpTokenizer는 정규 표현식을 활용하여 토큰화를 진행할 수 있는 토크나이저 클래스입니다. 정규 표현식은 특정 문자열을 걸러내거나 추출할 수 있는 문자열 패턴입니다. 위의 코드에서는 ., ,, \n 등의 특수문자를 토큰화 과정에서 제외하기 위해 사용하였습니다. 정규 표현식에 관한 자세한 내용은 정규 표현식 시작하기이나 정규 표현식 정리를 보시면 이해하기 편할 거라 생각합니다.

profile
글쓰는 개발자입니다.
post-custom-banner

0개의 댓글