본문 바로가기
Python/Data Analysis

[파이썬, Python] 형태소 분석 - KoNLPy

by coding-choonsik 2023. 6. 13.
728x90
반응형
SMALL

1. 자연어란 ❓

  • 일상에서 사용하는 언어
  • 컴퓨터는 자연어를 직접적으로 이해할 수 없음 ➡ 컴퓨터가 자연어의 의미를 분석해 처리할 수 있도록 하는 일을 "자연어 처리(Natural Language Processing)"

 

 

2. 토크나이징

  • 문장을 의미가 있는 가장 작은 단어들로 나움
  • 나눠진 단어들을 이용해 의미를 분석
  • 가장 기본이 되는 단어들을 '토큰'이라고 부름
  • 문장 형태의 데이터를 처리하기 위해 제일 처음 수행해야 하는 기본적인 작업
  • 토크나이징을 어떻게 하느냐에 따라 성능의 차이가 날 수 있음

 

 

3. 형태소 분석

  • 자연어의 문장을 형태소라는 최소 단위로 분할하고 품사를 판별하는 작업
  • 영어 형태소 분석은 형태소마다 띄어쓰기를 해서 문장을 구성하는 것이 기본(분석이 쉬운편)
  • 아시아 계열의 언어분석은 복잡하고 많은 노력이 필요
  • 한국어 형태소 분석 라이브러리: KoNLPy

 

 

4. KoNLPY

  •  기본적인 한국어 자연어 처리를 위한 파이썬 라이브러리
    • 명사, 대명사, 수사, 동사, 형용사, 관용사, 부사, 조사, 감탄사
  • 분석기
    •  Hannanum: 한나눔. KAIST Semantic Web Research Center에서 개발
    •  Kkma: 꼬꼬마. 서울대학교 IDS 연구실에서 개발
    •  Komoran: 코모란. Shineware에서 개발
    •  Okt(Open Korean Text): 오픈소스 한국어 분석기. 과거 트위터 형태소 분석기

 

4-1. KoNLPY 설치

!pip install KoNLPy

 

4-2. 대한민국 헌법 텍스트 파일 살펴보기

# KoNLPy에는 kolaw(대한민국 헌법 텍스트 파일)를 제공
from konlpy.corpus import kolaw
# 파일 이름 알아보기
kolaw.fileids()

>>> ['constitution.txt']

 

# txt 파일 열기
law = kolaw.open('constitution.txt').read()
law

 

 

4-3. 국회법안 텍스트 파일 살펴보기

# KoNLPy에는 kobill(국회법안 파일)를 제공
from konlpy.corpus import kobill

# 파일 이름 알아보기
kobill.fileids()

>>>
['1809895.txt',
 '1809892.txt',
 '1809893.txt',
 '1809899.txt',
 '1809897.txt',
 '1809896.txt',
 '1809891.txt',
 '1809890.txt',
 '1809898.txt',
 '1809894.txt']
 
# 파일 읽어들이기
bill = kobill.open('1809895.txt').read()
bill


5. 분석기 

# 분석기 임포트
from konlpy.tag import *

# 각 분석기 객체 생성
hannanum = Hannanum()
kkma = Kkma()
komoran = Komoran()
okt = Okt()

 

# 헌법 50번째 인덱스까지 가져오기
law[:50]

>>> 대한민국헌법

유구한 역사와 전통에 빛나는 우리 대한국민은 3·1운동으로 건립된 대한민국임

 

5-1. nouns()

  • 명사를 추출
  • 각 분석기마다 추출된 명사들이 다를 수 있음
hannanum.nouns(law[:50])

>>> ['대한민국헌법', '유구', '역사', '전통', '빛', '우리', '대한국민', '3·1운동', '건립', '대한민국임']

kkma.nouns(law[:50])

>>> ['대한',
 '대한민국',
 '대한민국헌법',
 '민국',
 '헌법',
 '유구',
 '역사',
 '전통',
 '우리',
 '국민',
 '3',
 '1',
 '1운동',
 '운동',
 '건립',
 '대한민국임',
 '임']
 
 
 komoran.nouns(law[:50])
 
 >>> ['대한민국', '헌법', '역사', '전통', '국민', '운동', '건립', '대한민국', '임']
 
 
 okt.nouns(law[:50])
 
 >>> ['대한민국', '헌법', '유구', '역사', '전통', '우리', '국민', '운동', '건립', '대한민국', '임']

5-2. morphs()

  • 모든 품사를 추출
hannanum.morphs(law[:50])

>>> ['대한민국헌법',
 '유구',
 '하',
 'ㄴ',
 '역사',
 '와',
 '전통',
 '에',
 '빛',
 '나는',
 '우리',
 '대한국민',
 '은',
 '3·1운동',
 '으로',
 '건립',
 '되',
 'ㄴ',
 '대한민국임']

5-3. pos()

  • 모든 형태소를 부착, 어떤 형태소의 종류인지 같이 알려줌
  • 튜플 형식
hannanum.pos(law[:50])

>>> 
[('대한민국헌법', 'N'),
 ('유구', 'N'),
 ('하', 'X'),
 ('ㄴ', 'E'),
 ('역사', 'N'),
 ('와', 'J'),
 ('전통', 'N'),
 ('에', 'J'),
 ('빛', 'N'),
 ('나는', 'J'),
 ('우리', 'N'),
 ('대한국민', 'N'),
 ('은', 'J'),
 ('3·1운동', 'N'),
 ('으로', 'J'),
 ('건립', 'N'),
 ('되', 'X'),
 ('ㄴ', 'E'),
 ('대한민국임', 'N')]
 
 
 okt.pos(law[:50])
 
 >>> 
 [('대한민국', 'Noun'),
 ('헌법', 'Noun'),
 ('\n\n', 'Foreign'),
 ('유구', 'Noun'),
 ('한', 'Josa'),
 ('역사', 'Noun'),
 ('와', 'Josa'),
 ('전통', 'Noun'),
 ('에', 'Josa'),
 ('빛나는', 'Verb'),
 ('우리', 'Noun'),
 ('대', 'Modifier'),
 ('한', 'Modifier'),
 ('국민', 'Noun'),
 ('은', 'Josa'),
 ('3', 'Number'),
 ('·', 'Punctuation'),
 ('1', 'Number'),
 ('운동', 'Noun'),
 ('으로', 'Josa'),
 ('건립', 'Noun'),
 ('된', 'Verb'),
 ('대한민국', 'Noun'),
 ('임', 'Noun')]

5-4. tagset

  • 부착되는 품사태그와 기호에 대한 의미를 반환
  • 딕셔너리 형태
okt.tagset

>>> {'Adjective': '형용사',
 'Adverb': '부사',
 'Alpha': '알파벳',
 'Conjunction': '접속사',
 'Determiner': '관형사',
 'Eomi': '어미',
 'Exclamation': '감탄사',
 'Foreign': '외국어, 한자 및 기타기호',
 'Hashtag': '트위터 해쉬태그',
 'Josa': '조사',
 'KoreanParticle': '(ex: ㅋㅋ)',
 'Noun': '명사',
 'Number': '숫자',
 'PreEomi': '선어말어미',
 'Punctuation': '구두점',
 'ScreenName': '트위터 아이디',
 'Suffix': '접미사',
 'Unknown': '미등록어',
 'Verb': '동사'}

 

✅ 문장에 대한 형태소 분석을 해보자.

from konlpy.tag import Okt
okt = Okt() # 객체 생성

text='아버지가방에들어가신다'
okt.pos(text)  # 어떤 형태소 종류인지 튜플로 반환
 
>>> [('아버지', 'Noun'), ('가방', 'Noun'), ('에', 'Josa'), ('들어가신다', 'Verb')]

text='아버지가 방에 들어가신다'
okt.pos(text)

>>> [('아버지', 'Noun'),
 ('가', 'Josa'),
 ('방', 'Noun'),
 ('에', 'Josa'),
 ('들어가신다', 'Verb')]
 
 
 okt.pos('오늘 날씨가 참 좋네욬ㅋㅋ')
 >>> [('오늘', 'Noun'),
 ('날씨', 'Noun'),
 ('가', 'Josa'),
 ('참', 'Verb'),
 ('좋네욬', 'Noun'),
 ('ㅋㅋ', 'KoreanParticle')]


# norm:True -> 각 형태소에 대한 원형으로 처리
okt.pos('오늘 날씨가 참 좋네욬ㅋㅋ', norm=True)
>>> [('오늘', 'Noun'),
 ('날씨', 'Noun'),
 ('가', 'Josa'),
 ('참', 'Verb'),
 ('좋네요', 'Adjective'),
 ('ㅋㅋ', 'KoreanParticle')]
 
 
 # stem=True -> 원형 글자로 변경
okt.pos('오늘 날씨가 참 좋네욬ㅋㅋ', norm=True, stem=True)
>>> 
[('오늘', 'Noun'),
 ('날씨', 'Noun'),
 ('가', 'Josa'),
 ('차다', 'Verb'),
 ('좋다', 'Adjective'),
 ('ㅋㅋ', 'KoreanParticle')]

 

 

728x90
반응형
LIST