Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

입력 텍스트 내의 빈도 정보를 활용한 미등재어 추정 #166

Open
bab2min opened this issue May 18, 2024 · 0 comments
Open

Comments

@bab2min
Copy link
Owner

bab2min commented May 18, 2024

핵심적인 단어, 키워드는 글 전체에서 여러 번 사용되는 경향이 있음. 핵심 키워드가 종종 미등재어나 신조어인 경우가 있는데, 이 때 글 내에서 여러 번 등장하는 키워드들이 형태소 분석 과정에서 서로 다 다른 조합으로 분해되는 경우가 많다. 이런 경우 빈도 정보를 통해 자주 반복되는 키워드를 미리 신조어 취급하여 분석하면 해당 키워드들에 대해 일관적인 결과를 얻을 수 있지 않을까?

예시: 알리오올리오가 핵심 단어인 글(총 3회 등장)
시작은 드라마 〈파스타〉였다. 많은 내 또래들이 이 드라마를 통해 ‘알리오올리오’에 입문했으리라. 드라마를 보던 당시, 나는 취업을 준비하던 백수였고 집에 올리브유와 마늘쯤은 있었다. 이름을 처음 접했던 페퍼론치노는 청양고추로 맛을 내면 될 일. 한번 따라 해 보자는 마음으로 알리오올리오를 가볍게 만들어 봤다. 역시나 맛이 없었다. 모든 재료들이 겉도는 밍밍한 맛과 이빨에 들러붙을 정도로 딱딱한 면의 식감에 고개가 갸우뚱. 제대로 된 알리오올리오는 얼마나 맛있길래

이 글을 Kiwi v0.17.1에서 분석하면 다음과 같은 결과가 나온다.

[ ...
  Token(form='통하', tag='VV', start=34, len=2),
  Token(form='어', tag='EC', start=35, len=1),
  Token(form='‘', tag='SSO', start=37, len=1),
  Token(form='알리오올리오', tag='NNG', start=38, len=6), # NNG로 추출
  Token(form='’', tag='SSC', start=44, len=1),
  Token(form='에', tag='JKB', start=45, len=1),
  Token(form='입문', tag='NNG', start=47, len=2),
  ...
  Token(form='마음', tag='NNG', start=150, len=2),
  Token(form='으로', tag='JKB', start=152, len=2),
  Token(form='알리', tag='VV', start=155, len=2), # 동사+어미로 분해
  Token(form='오', tag='EC', start=157, len=1),
  Token(form='올리', tag='VV', start=158, len=2),
  Token(form='오', tag='EC', start=160, len=1),
  Token(form='를', tag='JKO', start=161, len=1),
  Token(form='가볍', tag='VA-I', start=163, len=2),
  Token(form='게', tag='EC', start=165, len=1),
  ...
  Token(form='제대로', tag='MAG', start=239, len=3),
  Token(form='되', tag='VV', start=243, len=1),
  Token(form='ᆫ', tag='ETM', start=243, len=1),
  Token(form='알리', tag='VV', start=245, len=2), # 동사+어미로 분해
  Token(form='오', tag='EC', start=247, len=1),
  Token(form='올리', tag='VV', start=248, len=2),
  Token(form='오', tag='EC', start=250, len=1),
  Token(form='는', tag='JX', start=251, len=1),
  Token(form='얼마나', tag='MAG', start=253, len=3),
  ...],
전체 분석 결과
[Token(form='시작', tag='NNG', start=0, len=2),
  Token(form='은', tag='JX', start=2, len=1),
  Token(form='드라마', tag='NNG', start=4, len=3),
  Token(form='〈', tag='SSO', start=8, len=1),
  Token(form='파스타', tag='NNG', start=9, len=3),
  Token(form='〉', tag='SSC', start=12, len=1),
  Token(form='이', tag='VCP', start=13, len=1),
  Token(form='었', tag='EP', start=13, len=1),
  Token(form='다', tag='EF', start=14, len=1),
  Token(form='.', tag='SF', start=15, len=1),
  Token(form='많', tag='VA', start=17, len=1),
  Token(form='은', tag='ETM', start=18, len=1),
  Token(form='나', tag='NP', start=20, len=1),
  Token(form='의', tag='JKG', start=20, len=1),
  Token(form='또래', tag='NNG', start=22, len=2),
  Token(form='들', tag='XSN', start=24, len=1),
  Token(form='이', tag='JKS', start=25, len=1),
  Token(form='이', tag='MM', start=27, len=1),
  Token(form='드라마', tag='NNG', start=29, len=3),
  Token(form='를', tag='JKO', start=32, len=1),
  Token(form='통하', tag='VV', start=34, len=2),
  Token(form='어', tag='EC', start=35, len=1),
  Token(form='‘', tag='SSO', start=37, len=1),
  Token(form='알리오올리오', tag='NNG', start=38, len=6),
  Token(form='’', tag='SSC', start=44, len=1),
  Token(form='에', tag='JKB', start=45, len=1),
  Token(form='입문', tag='NNG', start=47, len=2),
  Token(form='하', tag='XSV', start=49, len=1),
  Token(form='었', tag='EP', start=49, len=1),
  Token(form='으리라', tag='EF', start=50, len=3),
  Token(form='.', tag='SF', start=53, len=1),
  Token(form='드라마', tag='NNG', start=55, len=3),
  Token(form='를', tag='JKO', start=58, len=1),
  Token(form='보', tag='VV', start=60, len=1),
  Token(form='던', tag='ETM', start=61, len=1),
  Token(form='당시', tag='NNG', start=63, len=2),
  Token(form=',', tag='SP', start=65, len=1),
  Token(form='나', tag='NP', start=67, len=1),
  Token(form='는', tag='JX', start=68, len=1),
  Token(form='취업', tag='NNG', start=70, len=2),
  Token(form='을', tag='JKO', start=72, len=1),
  Token(form='준비', tag='NNG', start=74, len=2),
  Token(form='하', tag='XSV', start=76, len=1),
  Token(form='던', tag='ETM', start=77, len=1),
  Token(form='백수', tag='NNG', start=79, len=2),
  Token(form='이', tag='VCP', start=81, len=1),
  Token(form='었', tag='EP', start=81, len=1),
  Token(form='고', tag='EC', start=82, len=1),
  Token(form='집', tag='NNG', start=84, len=1),
  Token(form='에', tag='JKB', start=85, len=1),
  Token(form='올리브유', tag='NNG', start=87, len=4),
  Token(form='와', tag='JC', start=91, len=1),
  Token(form='마늘', tag='NNG', start=93, len=2),
  Token(form='쯤', tag='XSN', start=95, len=1),
  Token(form='은', tag='JX', start=96, len=1),
  Token(form='있', tag='VV', start=98, len=1),
  Token(form='었', tag='EP', start=99, len=1),
  Token(form='다', tag='EF', start=100, len=1),
  Token(form='.', tag='SF', start=101, len=1),
  Token(form='이름', tag='NNG', start=103, len=2),
  Token(form='을', tag='JKO', start=105, len=1),
  Token(form='처음', tag='NNG', start=107, len=2),
  Token(form='접하', tag='VV', start=110, len=2),
  Token(form='었', tag='EP', start=111, len=1),
  Token(form='던', tag='ETM', start=112, len=1),
  Token(form='페퍼론치노', tag='NNP', start=114, len=5),
  Token(form='는', tag='JX', start=119, len=1),
  Token(form='청양고추', tag='NNG', start=121, len=4),
  Token(form='로', tag='JKB', start=125, len=1),
  Token(form='맛', tag='NNG', start=127, len=1),
  Token(form='을', tag='JKO', start=128, len=1),
  Token(form='내', tag='VV', start=130, len=1),
  Token(form='면', tag='EC', start=131, len=1),
  Token(form='되', tag='VV', start=133, len=1),
  Token(form='ᆯ', tag='ETM', start=133, len=1),
  Token(form='일', tag='NNG', start=135, len=1),
  Token(form='.', tag='SF', start=136, len=1),
  Token(form='한번', tag='MAG', start=138, len=2),
  Token(form='따르', tag='VV', start=141, len=2),
  Token(form='어', tag='EC', start=142, len=1),
  Token(form='하', tag='VV', start=144, len=1),
  Token(form='어', tag='EC', start=144, len=1),
  Token(form='보', tag='VX', start=146, len=1),
  Token(form='자는', tag='ETM', start=147, len=2),
  Token(form='마음', tag='NNG', start=150, len=2),
  Token(form='으로', tag='JKB', start=152, len=2),
  Token(form='알리', tag='VV', start=155, len=2),
  Token(form='오', tag='EC', start=157, len=1),
  Token(form='올리', tag='VV', start=158, len=2),
  Token(form='오', tag='EC', start=160, len=1),
  Token(form='를', tag='JKO', start=161, len=1),
  Token(form='가볍', tag='VA-I', start=163, len=2),
  Token(form='게', tag='EC', start=165, len=1),
  Token(form='만들', tag='VV', start=167, len=2),
  Token(form='어', tag='EC', start=169, len=1),
  Token(form='보', tag='VX', start=171, len=1),
  Token(form='었', tag='EP', start=171, len=1),
  Token(form='다', tag='EF', start=172, len=1),
  Token(form='.', tag='SF', start=173, len=1),
  Token(form='역시', tag='MAG', start=175, len=2),
  Token(form='나', tag='JX', start=177, len=1),
  Token(form='맛', tag='NNG', start=179, len=1),
  Token(form='이', tag='JKS', start=180, len=1),
  Token(form='없', tag='VA', start=182, len=1),
  Token(form='었', tag='EP', start=183, len=1),
  Token(form='다', tag='EF', start=184, len=1),
  Token(form='.', tag='SF', start=185, len=1),
  Token(form='모든', tag='MM', start=187, len=2),
  Token(form='재료', tag='NNG', start=190, len=2),
  Token(form='들', tag='XSN', start=192, len=1),
  Token(form='이', tag='JKS', start=193, len=1),
  Token(form='겉돌', tag='VV', start=195, len=2),
  Token(form='는', tag='ETM', start=197, len=1),
  Token(form='밍밍', tag='XR', start=199, len=2),
  Token(form='하', tag='XSA', start=201, len=1),
  Token(form='ᆫ', tag='ETM', start=201, len=1),
  Token(form='맛', tag='NNG', start=203, len=1),
  Token(form='과', tag='JC', start=204, len=1),
  Token(form='이빨', tag='NNG', start=206, len=2),
  Token(form='에', tag='JKB', start=208, len=1),
  Token(form='들러붙', tag='VV', start=210, len=3),
  Token(form='을', tag='ETM', start=213, len=1),
  Token(form='정도', tag='NNG', start=215, len=2),
  Token(form='로', tag='JKB', start=217, len=1),
  Token(form='딱딱', tag='XR', start=219, len=2),
  Token(form='하', tag='XSA', start=221, len=1),
  Token(form='ᆫ', tag='ETM', start=221, len=1),
  Token(form='면', tag='NNG', start=223, len=1),
  Token(form='의', tag='JKG', start=224, len=1),
  Token(form='식감', tag='NNG', start=226, len=2),
  Token(form='에', tag='JKB', start=228, len=1),
  Token(form='고개', tag='NNG', start=230, len=2),
  Token(form='가', tag='JKS', start=232, len=1),
  Token(form='갸우뚱', tag='MAG', start=234, len=3),
  Token(form='.', tag='SF', start=237, len=1),
  Token(form='제대로', tag='MAG', start=239, len=3),
  Token(form='되', tag='VV', start=243, len=1),
  Token(form='ᆫ', tag='ETM', start=243, len=1),
  Token(form='알리', tag='VV', start=245, len=2),
  Token(form='오', tag='EC', start=247, len=1),
  Token(form='올리', tag='VV', start=248, len=2),
  Token(form='오', tag='EC', start=250, len=1),
  Token(form='는', tag='JX', start=251, len=1),
  Token(form='얼마나', tag='MAG', start=253, len=3),
  Token(form='맛있', tag='VA', start=257, len=2),
  Token(form='길래', tag='EC', start=259, len=2)],

구체적으로 다음과 같은 조건을 사용하여 핵심 키워드인 미등재어를 추출할 수 있지 않을까?

  • substring A가 다음 조건을 만족하면 미등재어인 신조어일 가능성이 높다
    • 입력 텍스트 내에서 A의 출현빈도가 높음
    • A가 Kiwi 형태소 사전에 등재되어 있지 않음
    • 입력 텍스트 내의 A가 여러 형태소로 분해되며, 언어 모델 상 점수가 낮음

이를 구현하기 위해서는 입력 텍스트 내의 모든 substring의 빈도를 조사해야하는데 이는 suffix-array 기반의 FM-index를 구축하면 빠르게 처리할 수 있다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant