Natural Language Toolkit-빠른 가이드
자연어 처리 (NLP) 란 무엇입니까?
인간이 말하고 읽고 쓸 수있는 도움으로 의사 소통하는 방법은 언어입니다. 즉, 우리 인간은 자연어로 생각하고, 계획하고, 결정을 내릴 수 있습니다. 여기서 큰 질문은 인공 지능, 기계 학습 및 딥 러닝 시대에 인간이 컴퓨터 / 기계와 자연 언어로 의사 소통 할 수 있다는 것입니다. 컴퓨터에는 구조화 된 데이터가 필요하기 때문에 NLP 응용 프로그램을 개발하는 것은 우리에게 큰 도전입니다. 반면에 인간의 음성은 구조화되지 않고 종종 모호합니다.
자연어는 컴퓨터 과학, 특히 AI의 하위 분야로, 컴퓨터 / 기계가 인간 언어를 이해, 처리 및 조작 할 수 있도록합니다. 간단히 말해서 NLP는 힌디어, 영어, 프랑스어, 네덜란드어 등과 같은 인간의 자연어에서 의미를 분석, 이해 및 도출하는 기계의 방법입니다.
어떻게 작동합니까?
NLP의 작업에 깊이 들어가기 전에 인간이 언어를 사용하는 방법을 이해해야합니다. 매일 우리 인간은 수백, 수천 개의 단어를 사용하고 다른 인간은 그것을 해석하고 그에 따라 대답합니다. 인간을위한 단순한 의사 소통이지 않습니까? 그러나 우리는 단어가 그보다 훨씬 더 깊이 있다는 것을 알고 있으며 항상 우리가 말하는 것과 말하는 방식에서 컨텍스트를 도출합니다. 그렇기 때문에 NLP는 음성 변조에 초점을 맞추기보다 상황에 맞는 패턴을 사용한다고 말할 수 있습니다.
예를 들어 이해합시다.
Man is to woman as king is to what?
We can interpret it easily and answer as follows:
Man relates to king, so woman can relate to queen.
Hence the answer is Queen.
인간은 어떤 단어가 무엇을 의미하는지 어떻게 압니까? 이 질문에 대한 답은 우리가 경험을 통해 배우는 것입니다. 그러나 기계 / 컴퓨터는 어떻게 똑같이 학습합니까?
다음과 같은 쉬운 단계로 이해합시다.
먼저 기계가 경험을 통해 배울 수 있도록 충분한 데이터를 기계에 공급해야합니다.
그런 다음 기계는 이전에 공급 한 데이터와 주변 데이터에서 딥 러닝 알고리즘을 사용하여 단어 벡터를 생성합니다.
그런 다음 이러한 단어 벡터에 대해 간단한 대수 연산을 수행함으로써 기계는 인간으로서 답을 제공 할 수 있습니다.
NLP의 구성 요소
다음 다이어그램은 자연어 처리 (NLP)의 구성 요소를 나타냅니다.
형태 학적 처리
형태 학적 처리는 NLP의 첫 번째 구성 요소입니다. 여기에는 언어 입력 청크를 단락, 문장 및 단어에 해당하는 토큰 세트로 나누는 것이 포함됩니다. 예를 들어, 다음과 같은 단어“everyday” 다음과 같이 두 개의 하위 단어 토큰으로 나눌 수 있습니다. “every-day”.
구문 분석
두 번째 구성 요소 인 구문 분석은 NLP의 가장 중요한 구성 요소 중 하나입니다. 이 구성 요소의 목적은 다음과 같습니다.
문장의 형식이 올바른지 확인합니다.
다른 단어 간의 구문 관계를 보여주는 구조로 나누는 것입니다.
예 : 같은 문장 “The school goes to the student” 구문 분석기에서 거부됩니다.
의미 분석
Semantic Analysis는 텍스트의 의미를 확인하는 데 사용되는 NLP의 세 번째 구성 요소입니다. 그것은 정확한 의미를 그리는 것을 포함하거나 텍스트에서 사전 적 의미를 말할 수 있습니다. 예 : "뜨거운 아이스크림입니다."와 같은 문장. 의미 분석기에 의해 폐기됩니다.
실용적인 분석
실용적 분석은 NLP의 네 번째 구성 요소입니다. 여기에는 각 컨텍스트에 존재하는 실제 객체 또는 이벤트를 이전 구성 요소, 즉 의미 분석에서 얻은 객체 참조와 맞추는 것이 포함됩니다. 예 : 같은 문장“Put the fruits in the basket on the table” 두 가지 의미 해석을 가질 수 있으므로 실용적인 분석기는이 두 가지 가능성 중에서 선택합니다.
NLP 애플리케이션의 예
신기술 인 NLP는 오늘날 우리가 보았던 다양한 형태의 AI를 파생합니다. 오늘날과 미래의 점점 더 인지도가 높아지는 애플리케이션의 경우, 인간과 기계 간의 원활한 상호 작용 인터페이스를 만드는 데 NLP를 사용하는 것이 계속 최우선 순위가 될 것입니다. 다음은 NLP의 매우 유용한 응용 프로그램 중 일부입니다.
기계 번역
기계 번역 (MT)은 자연어 처리의 가장 중요한 응용 프로그램 중 하나입니다. MT는 기본적으로 하나의 소스 언어 또는 텍스트를 다른 언어로 번역하는 프로세스입니다. 기계 번역 시스템은 이중 언어 또는 다국어가 될 수 있습니다.
스팸 퇴치
원하지 않는 이메일이 엄청나게 증가함에 따라 스팸 필터가이 문제에 대한 첫 번째 방어선이기 때문에 중요해졌습니다. 위양성 및 위음성 문제를 주요 이슈로 고려하여 NLP의 기능을 활용하여 스팸 필터링 시스템을 개발할 수 있습니다.
N-gram 모델링, Word Stemming 및 Bayesian 분류는 스팸 필터링에 사용할 수있는 기존 NLP 모델 중 일부입니다.
정보 검색 및 웹 검색
Google, Yahoo, Bing, WolframAlpha 등과 같은 대부분의 검색 엔진은 기계 번역 (MT) 기술을 NLP 딥 러닝 모델을 기반으로합니다. 이러한 딥 러닝 모델을 사용하면 알고리즘이 웹 페이지의 텍스트를 읽고 그 의미를 해석하고 다른 언어로 번역 할 수 있습니다.
자동 텍스트 요약
자동 텍스트 요약은 긴 텍스트 문서를 짧고 정확하게 요약하는 기술입니다. 따라서 더 짧은 시간에 관련 정보를 얻는 데 도움이됩니다. 이 디지털 시대에 우리는 인터넷을 통해 멈추지 않을 정보가 넘쳐나 기 때문에 자동 텍스트 요약이 절실히 필요합니다. NLP와 그 기능은 자동 텍스트 요약을 개발하는 데 중요한 역할을합니다.
문법 교정
맞춤법 교정 및 문법 교정은 Microsoft Word와 같은 워드 프로세서 소프트웨어의 매우 유용한 기능입니다. 이러한 목적으로 자연어 처리 (NLP)가 널리 사용됩니다.
질문 답변
자연어 처리 (NLP)의 또 다른 주요 응용 프로그램 인 질문 응답은 사용자가 게시 한 질문에 자연어로 자동 응답하는 시스템 구축에 중점을 둡니다.
감정 분석
감정 분석은 자연어 처리 (NLP)의 다른 중요한 응용 프로그램 중 하나입니다. 이름에서 알 수 있듯이 감정 분석은 다음과 같이 사용됩니다.
여러 게시물 사이의 감정을 파악하고
감정이 명시 적으로 표현되지 않은 감정을 식별합니다.
Amazon, ebay 등과 같은 온라인 전자 상거래 회사는 감정 분석을 사용하여 온라인에서 고객의 의견과 감정을 식별합니다. 고객이 제품과 서비스에 대해 어떻게 생각하는지 이해하는 데 도움이됩니다.
음성 엔진
Siri, Google Voice, Alexa와 같은 음성 엔진은 NLP를 기반으로 구축되어 자연어로 소통 할 수 있습니다.
NLP 구현
위에서 언급 한 응용 프로그램을 구축하려면 언어를 효율적으로 처리 할 수있는 언어와 도구에 대한 이해도가 높은 특정 기술이 필요합니다. 이를 위해 다양한 오픈 소스 도구를 사용할 수 있습니다. 그들 중 일부는 오픈 소스이고 다른 일부는 자체 NLP 애플리케이션을 구축하기 위해 조직에서 개발합니다. 다음은 일부 NLP 도구 목록입니다.
자연어 도구 키트 (NLTK)
Mallet
GATE
NLP 열기
UIMA
Genism
Stanford 툴킷
이러한 도구의 대부분은 Java로 작성되었습니다.
자연어 도구 키트 (NLTK)
위에서 언급 한 NLP 도구 중 NLTK는 개념에 대한 사용 용이성과 설명 측면에서 매우 높은 점수를 받았습니다. Python의 학습 곡선은 매우 빠르며 NLTK는 Python으로 작성되었으므로 NLTK도 매우 좋은 학습 키트를 가지고 있습니다. NLTK는 토큰 화, 형태소 분석, 기본형 화, 구두점, 문자 수 및 단어 수와 같은 대부분의 작업을 통합했습니다. 매우 우아하고 작업하기 쉽습니다.
NLTK를 설치하려면 컴퓨터에 Python이 설치되어 있어야합니다. www.python.org/downloads 링크로 이동하여 Windows, Mac 및 Linux / Unix와 같은 OS의 최신 버전을 선택할 수 있습니다 . Python에 대한 기본 자습서는 www.tutorialspoint.com/python3/index.htm 링크를 참조 할 수 있습니다 .
이제 컴퓨터 시스템에 Python을 설치했으면 NLTK를 설치하는 방법을 이해하겠습니다.
NLTK 설치
다음과 같이 다양한 OS에 NLTK를 설치할 수 있습니다.
Windows에서
Windows OS에 NLTK를 설치하려면 다음 단계를 따르십시오.
먼저 Windows 명령 프롬프트를 열고 pip 폴더.
다음으로 NLTK를 설치하려면 다음 명령을 입력하십시오-
pip3 install nltk
이제 Windows 시작 메뉴에서 PythonShell을 열고 NLTK의 설치를 확인하기 위해 다음 명령을 입력합니다.
Import nltk
오류가 발생하지 않으면 Python3이있는 Windows OS에 NLTK를 성공적으로 설치 한 것입니다.
Mac / Linux에서
Mac / Linux OS에 NLTK를 설치하려면 다음 명령을 작성하십시오.
sudo pip install -U nltk
컴퓨터에 pip가 설치되어 있지 않은 경우 아래 지침에 따라 먼저 설치하십시오. pip −
먼저 다음 명령을 사용하여 패키지 색인을 업데이트하십시오.
sudo apt update
이제 다음 명령을 입력하여 설치하십시오. pip 파이썬 3-
sudo apt install python3-pip
아나콘다를 통해
Anaconda를 통해 NLTK를 설치하려면 다음 단계를 따르십시오.
먼저 Anaconda를 설치하려면 www.anaconda.com/distribution/#download-section 링크로 이동 한 다음 설치해야하는 Python 버전을 선택합니다.
컴퓨터 시스템에 Anaconda가 설치되면 명령 프롬프트로 이동하여 다음 명령을 작성하십시오.
conda install -c anaconda nltk
출력을 검토하고 'yes'를 입력해야합니다. NLTK는 Anaconda 패키지에 다운로드되어 설치됩니다.
NLTK의 데이터 세트 및 패키지 다운로드
이제 컴퓨터에 NLTK가 설치되어 있지만이를 사용하려면 사용 가능한 데이터 세트 (코퍼스)를 다운로드해야합니다. 사용 가능한 몇 가지 중요한 데이터 세트는 다음과 같습니다.stpwords, guntenberg, framenet_v15 등등.
다음 명령의 도움으로 모든 NLTK 데이터 세트를 다운로드 할 수 있습니다.
import nltk
nltk.download()
다음과 같은 NLTK 다운로드 창이 나타납니다.
이제 다운로드 버튼을 클릭하여 데이터 세트를 다운로드합니다.
NLTK 스크립트를 실행하는 방법?
다음은 Porter Stemmer 알고리즘을 사용하여 구현하는 예입니다. PorterStemmernltk 클래스. 이 예제를 통해 NLTK 스크립트를 실행하는 방법을 이해할 수 있습니다.
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 PorterStemmer Porter Stemmer 알고리즘을 구현하기위한 클래스.
from nltk.stem import PorterStemmer
다음으로 다음과 같이 Porter Stemmer 클래스의 인스턴스를 만듭니다.
word_stemmer = PorterStemmer()
이제 줄기를 원하는 단어를 입력하십시오. −
word_stemmer.stem('writing')
산출
'write'
word_stemmer.stem('eating')
산출
'eat'
토큰 화란 무엇입니까?
텍스트 조각을 문장이나 단어와 같은 작은 부분으로 나누는 과정으로 정의 할 수 있습니다. 이러한 작은 부분을 토큰이라고합니다. 예를 들어, 단어는 문장의 토큰이고 문장은 단락의 토큰입니다.
NLP는 감정 분석, QA 시스템, 언어 번역, 스마트 챗봇, 음성 시스템 등과 같은 애플리케이션을 구축하는 데 사용된다는 것을 알고 있으므로이를 구축하기 위해서는 텍스트의 패턴을 이해하는 것이 중요합니다. 위에서 언급 한 토큰은 이러한 패턴을 찾고 이해하는 데 매우 유용합니다. 토큰 화를 형태소 분석 및 구조화와 같은 다른 레시피의 기본 단계로 고려할 수 있습니다.
NLTK 패키지
nltk.tokenize 토큰 화 프로세스를 달성하기 위해 NLTK 모듈에서 제공하는 패키지입니다.
문장을 단어로 토큰 화
문장을 단어로 나누거나 문자열에서 단어 목록을 만드는 것은 모든 텍스트 처리 활동의 필수 부분입니다. 에서 제공하는 다양한 기능 / 모듈의 도움으로 이해합시다.nltk.tokenize 꾸러미.
word_tokenize 모듈
word_tokenize모듈은 기본 단어 토큰 화에 사용됩니다. 다음 예제는이 모듈을 사용하여 문장을 단어로 분할합니다.
예
import nltk
from nltk.tokenize import word_tokenize
word_tokenize('Tutorialspoint.com provides high quality technical tutorials for free.')
산출
['Tutorialspoint.com', 'provides', 'high', 'quality', 'technical', 'tutorials', 'for', 'free', '.']
TreebankWordTokenizer 클래스
word_tokenize 위에서 사용 된 모듈은 기본적으로 tokenize () 함수를 인스턴스의 인스턴스로 호출하는 래퍼 함수입니다. TreebankWordTokenizer수업. 문장을 단어로 분할하기 위해 word_tokenize () 모듈을 사용하는 동안 얻은 것과 동일한 출력을 제공합니다. 위에서 구현 된 동일한 예제를 보겠습니다.
예
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 TreebankWordTokenizer 단어 토크 나이저 알고리즘을 구현하는 클래스-
from nltk.tokenize import TreebankWordTokenizer
다음으로 다음과 같이 TreebankWordTokenizer 클래스의 인스턴스를 만듭니다.
Tokenizer_wrd = TreebankWordTokenizer()
이제 토큰으로 변환하려는 문장을 입력하십시오.
Tokenizer_wrd.tokenize(
'Tutorialspoint.com provides high quality technical tutorials for free.'
)
산출
[
'Tutorialspoint.com', 'provides', 'high', 'quality',
'technical', 'tutorials', 'for', 'free', '.'
]
완전한 구현 예
아래에서 전체 구현 예제를 보겠습니다.
import nltk
from nltk.tokenize import TreebankWordTokenizer
tokenizer_wrd = TreebankWordTokenizer()
tokenizer_wrd.tokenize('Tutorialspoint.com provides high quality technical
tutorials for free.')
산출
[
'Tutorialspoint.com', 'provides', 'high', 'quality',
'technical', 'tutorials','for', 'free', '.'
]
토크 나이저의 가장 중요한 규칙은 수축을 분리하는 것입니다. 예를 들어, 이러한 목적으로 word_tokenize () 모듈을 사용하면 다음과 같이 출력됩니다.
예
import nltk
from nltk.tokenize import word_tokenize
word_tokenize('won’t')
산출
['wo', "n't"]]
이런 종류의 컨벤션 TreebankWordTokenizer용납 할 수 없습니다. 그래서 두 개의 대체 단어 토크 나이저가 있습니다.PunktWordTokenizer 과 WordPunctTokenizer.
WordPunktTokenizer 클래스
모든 구두점을 별도의 토큰으로 분할하는 대체 단어 토크 나이저입니다. 다음의 간단한 예를 들어 이해합시다.
예
from nltk.tokenize import WordPunctTokenizer
tokenizer = WordPunctTokenizer()
tokenizer.tokenize(" I can't allow you to go home early")
산출
['I', 'can', "'", 't', 'allow', 'you', 'to', 'go', 'home', 'early']
텍스트를 문장으로 토큰 화
이 섹션에서는 텍스트 / 단락을 문장으로 나눌 것입니다. NLTK는sent_tokenize 이 목적을 위해 모듈.
왜 필요한가요?
우리 마음 속에 떠오른 분명한 질문은 단어 토크 나이저가있을 때 왜 우리가 문장 토크 나이저가 필요하거나 텍스트를 문장으로 토큰 화해야 하는가하는 것입니다. 문장에서 평균적인 단어를 세어야한다고 가정 해 봅시다. 어떻게 할 수 있습니까? 이 작업을 수행하려면 문장 토큰 화와 단어 토큰 화가 모두 필요합니다.
다음의 간단한 예제를 통해 문장과 단어 토크 나이저의 차이점을 이해해 보겠습니다.
예
import nltk
from nltk.tokenize import sent_tokenize
text = "Let us understand the difference between sentence & word tokenizer.
It is going to be a simple example."
sent_tokenize(text)
산출
[
"Let us understand the difference between sentence & word tokenizer.",
'It is going to be a simple example.'
]
정규식을 사용한 문장 토큰 화
단어 토크 나이저의 출력이 허용되지 않는다고 생각하고 텍스트를 토큰 화하는 방법을 완전히 제어하려는 경우 문장 토큰 화를 수행하는 동안 사용할 수있는 정규 표현식이 있습니다. NLTK는RegexpTokenizer 이를 달성하기 위해 클래스.
아래 두 가지 예를 통해 개념을 이해하겠습니다.
첫 번째 예에서는 영숫자 토큰과 작은 따옴표를 일치시키기 위해 정규식을 사용하여 다음과 같이 축소하지 않도록합니다. “won’t”.
예 1
import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer("[\w']+")
tokenizer.tokenize("won't is a contraction.")
tokenizer.tokenize("can't is a contraction.")
산출
["won't", 'is', 'a', 'contraction']
["can't", 'is', 'a', 'contraction']
첫 번째 예에서는 정규 표현식을 사용하여 공백을 토큰 화합니다.
예 2
import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer('/s+' , gaps = True)
tokenizer.tokenize("won't is a contraction.")
산출
["won't", 'is', 'a', 'contraction']
위의 출력에서 구두점이 토큰에 남아 있음을 알 수 있습니다. 매개 변수 gaps = True는 패턴이 토큰화할 간격을 식별 할 것임을 의미합니다. 반면에 gaps = False 매개 변수를 사용하는 경우 패턴은 다음 예에서 볼 수있는 토큰을 식별하는 데 사용됩니다.
import nltk
from nltk.tokenize import RegexpTokenizer
tokenizer = RegexpTokenizer('/s+' , gaps = False)
tokenizer.tokenize("won't is a contraction.")
산출
[ ]
그것은 우리에게 빈 출력을 줄 것입니다.
자체 문장 토크 나이저를 훈련시키는 이유는 무엇입니까?
이것은 NLTK의 기본 문장 토크 나이저를 가지고 있다면 왜 문장 토크 나이저를 훈련해야 하는가에 대한 매우 중요한 질문입니다. 이 질문에 대한 답은 NLTK의 기본 문장 토크 나이저의 품질에 있습니다. NLTK의 기본 토크 나이 저는 기본적으로 범용 토크 나이저입니다. 매우 잘 작동하지만 비표준 텍스트, 아마도 우리의 텍스트 또는 고유 한 서식이있는 텍스트에는 적합하지 않을 수 있습니다. 이러한 텍스트를 토큰 화하고 최상의 결과를 얻으려면 자체 문장 토크 나이저를 훈련해야합니다.
구현 예
이 예에서는 웹 텍스트 코퍼스를 사용합니다. 이 말뭉치에서 사용할 텍스트 파일은 아래에 표시된 대화 상자 형식의 텍스트를 가지고 있습니다.
Guy: How old are you?
Hipster girl: You know, I never answer that question. Because to me, it's about
how mature you are, you know? I mean, a fourteen year old could be more mature
than a twenty-five year old, right? I'm sorry, I just never answer that question.
Guy: But, uh, you're older than eighteen, right?
Hipster girl: Oh, yeah.
이 텍스트 파일을 training_tokenizer라는 이름으로 저장했습니다. NLTK는PunktSentenceTokenizer이를 통해 원시 텍스트를 학습하여 맞춤형 문장 토크 나이저를 생성 할 수 있습니다. 파일에서 읽거나 NLTK 코퍼스에서 원시 텍스트를 얻을 수 있습니다.raw() 방법.
더 많은 통찰력을 얻기 위해 아래 예제를 보겠습니다.
먼저 가져 오기 PunktSentenceTokenizer 수업에서 nltk.tokenize 패키지 −
from nltk.tokenize import PunktSentenceTokenizer
이제 가져 오기 webtext 말뭉치 nltk.corpus 꾸러미
from nltk.corpus import webtext
다음으로 raw() 메서드에서 원시 텍스트를 가져옵니다. training_tokenizer.txt 다음과 같이 파일-
text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')
이제 인스턴스를 만듭니다. PunktSentenceTokenizer 다음과 같이 텍스트 파일에서 토큰 화 문장을 인쇄하십시오-
sent_tokenizer = PunktSentenceTokenizer(text)
sents_1 = sent_tokenizer.tokenize(text)
print(sents_1[0])
산출
White guy: So, do you have any plans for this evening?
print(sents_1[1])
Output:
Asian girl: Yeah, being angry!
print(sents_1[670])
Output:
Guy: A hundred bucks?
print(sents_1[675])
Output:
Girl: But you already have a Big Mac...
완전한 구현 예
from nltk.tokenize import PunktSentenceTokenizer
from nltk.corpus import webtext
text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')
sent_tokenizer = PunktSentenceTokenizer(text)
sents_1 = sent_tokenizer.tokenize(text)
print(sents_1[0])
산출
White guy: So, do you have any plans for this evening?
NLTK의 기본 문장 토크 나이저와 자체 훈련 된 문장 토크 나이저의 차이점을 이해하기 위해 동일한 파일을 기본 문장 토크 나이저 인 sent_tokenize ()로 토큰 화하겠습니다.
from nltk.tokenize import sent_tokenize
from nltk.corpus import webtext
text = webtext.raw('C://Users/Leekha/training_tokenizer.txt')
sents_2 = sent_tokenize(text)
print(sents_2[0])
Output:
White guy: So, do you have any plans for this evening?
print(sents_2[675])
Output:
Hobo: Y'know what I'd do if I was rich?
출력의 차이를 통해 자체 문장 토크 나이저를 훈련하는 것이 왜 유용한 지 개념을 이해할 수 있습니다.
불용어는 무엇입니까?
텍스트에는 있지만 문장의 의미에 기여하지 않는 몇 가지 일반적인 단어입니다. 이러한 단어는 정보 검색 또는 자연어 처리 목적에 전혀 중요하지 않습니다. 가장 일반적인 불용어는 'the'와 'a'입니다.
NLTK 불용어 말뭉치
실제로 Natural Language Tool 키트에는 여러 언어에 대한 단어 목록이 포함 된 불용어 코퍼스가 함께 제공됩니다. 다음 예제를 통해 사용법을 이해하겠습니다.
먼저, nltk.corpus 패키지 에서 불용어 copus를 가져옵니다.
from nltk.corpus import stopwords
이제 우리는 영어의 불용어를 사용할 것입니다
english_stops = set(stopwords.words('english'))
words = ['I', 'am', 'a', 'writer']
[word for word in words if word not in english_stops]
산출
['I', 'writer']
완전한 구현 예
from nltk.corpus import stopwords
english_stops = set(stopwords.words('english'))
words = ['I', 'am', 'a', 'writer']
[word for word in words if word not in english_stops]
산출
['I', 'writer']
지원되는 언어의 전체 목록 찾기
다음 Python 스크립트의 도움으로 NLTK 불용어 코퍼스에서 지원하는 전체 언어 목록을 찾을 수 있습니다.
from nltk.corpus import stopwords
stopwords.fileids()
산출
[
'arabic', 'azerbaijani', 'danish', 'dutch', 'english', 'finnish', 'french',
'german', 'greek', 'hungarian', 'indonesian', 'italian', 'kazakh', 'nepali',
'norwegian', 'portuguese', 'romanian', 'russian', 'slovene', 'spanish',
'swedish', 'tajik', 'turkish'
]
Wordnet은 무엇입니까?
Wordnet은 Princeton이 만든 대규모 영어 어휘 데이터베이스입니다. NLTK 말뭉치의 일부입니다. 명사, 동사, 형용사 및 부사는 모두 합성 집합, 즉인지 동의어로 그룹화됩니다. 여기서 각 synset 집합은 고유 한 의미를 나타냅니다. 다음은 Wordnet의 몇 가지 사용 사례입니다.
- 단어의 정의를 찾는 데 사용할 수 있습니다.
- 단어의 동의어와 반의어를 찾을 수 있습니다.
- Wordnet을 사용하여 단어 관계 및 유사점을 탐색 할 수 있습니다.
- 여러 용도와 정의가있는 단어에 대한 단어 감각 명확화
Wordnet을 가져 오는 방법?
다음 명령을 사용하여 Wordnet을 가져올 수 있습니다.
from nltk.corpus import wordnet
더 간결한 명령을 사용하려면 다음을 사용하십시오.
from nltk.corpus import wordnet as wn
Synset 인스턴스
Synset은 동일한 개념을 표현하는 동의어 단어의 그룹입니다. Wordnet을 사용하여 단어를 검색하면 Synset 인스턴스 목록이 표시됩니다.
wordnet.synsets (단어)
Synset 목록을 얻으려면 Wordnet에서 다음을 사용하여 단어를 찾을 수 있습니다. wordnet.synsets(word). 예를 들어, 다음 Python 레시피에서 Synset의 일부 속성 및 메서드와 함께 'dog'에 대한 Synset을 조회 할 것입니다.
예
먼저 다음과 같이 wordnet을 가져옵니다.
from nltk.corpus import wordnet as wn
이제 Synset을 찾고자하는 단어를 입력하세요.
syn = wn.synsets('dog')[0]
여기서, 우리는 Synset을 직접 얻는데 사용할 수있는 synset의 고유 한 이름을 얻기 위해 name () 메소드를 사용하고 있습니다.
syn.name()
Output:
'dog.n.01'
다음으로 우리는 단어의 정의를 제공하는 definition () 메소드를 사용합니다.
syn.definition()
Output:
'a member of the genus Canis (probably descended from the common wolf) that has
been domesticated by man since prehistoric times; occurs in many breeds'
또 다른 방법은 examples ()라는 단어와 관련된 예제를 제공합니다.
syn.examples()
Output:
['the dog barked all night']
완전한 구현 예
from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.name()
syn.definition()
syn.examples()
Hypernyms 받기
Synset은 다음과 같은 구조와 같은 상속 트리로 구성됩니다. Hypernyms 더 추상적 인 용어를 나타내는 반면 Hyponyms보다 구체적인 용어를 나타냅니다. 중요한 것 중 하나는이 트리가 루트 하이퍼 니즘까지 추적 될 수 있다는 것입니다. 다음 예제를 통해 개념을 이해하겠습니다.
from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.hypernyms()
산출
[Synset('canine.n.02'), Synset('domestic_animal.n.01')]
여기에서 canine과 domestic_animal이 '개'의 동의어임을 알 수 있습니다.
이제 우리는 다음과 같이 '개'의 hyponyms를 찾을 수 있습니다.
syn.hypernyms()[0].hyponyms()
산출
[
Synset('bitch.n.04'),
Synset('dog.n.01'),
Synset('fox.n.01'),
Synset('hyena.n.01'),
Synset('jackal.n.01'),
Synset('wild_dog.n.01'),
Synset('wolf.n.01')
]
위의 출력에서 'dog'은 'domestic_animals'의 많은 hyponyms 중 하나 일뿐임을 알 수 있습니다.
이 모든 것의 루트를 찾으려면 다음 명령을 사용할 수 있습니다.
syn.root_hypernyms()
산출
[Synset('entity.n.01')]
위의 출력에서 루트가 하나만 있음을 알 수 있습니다.
완전한 구현 예
from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
syn.hypernyms()
syn.hypernyms()[0].hyponyms()
syn.root_hypernyms()
산출
[Synset('entity.n.01')]
Wordnet의 기본형
언어학에서는 단어의 정식 형태 또는 형태 학적 형태를 기본형이라고합니다. 단어의 동의어 및 반의어를 찾기 위해 WordNet에서 기본형을 조회 할 수도 있습니다. 방법을 살펴 보겠습니다.
동의어 찾기
lemma () 메서드를 사용하여 Synset의 동의어 수를 찾을 수 있습니다. 이 방법을 'dog'synset에 적용 해 보겠습니다.
예
from nltk.corpus import wordnet as wn
syn = wn.synsets('dog')[0]
lemmas = syn.lemmas()
len(lemmas)
산출
3
위의 출력은 'dog'에 세 개의 기본형이 있음을 보여줍니다.
다음과 같이 첫 번째 기본형의 이름 얻기-
lemmas[0].name()
Output:
'dog'
다음과 같이 두 번째 기본형의 이름 얻기-
lemmas[1].name()
Output:
'domestic_dog'
다음과 같이 세 번째 기본형의 이름 얻기-
lemmas[2].name()
Output:
'Canis_familiaris'
실제로 Synset은 모두 유사한 의미를 갖는 기본형 그룹을 나타내고 기본형은 별개의 단어 형식을 나타냅니다.
반의어 찾기
WordNet에서 일부 기본형에는 반의어도 있습니다. 예를 들어 'good'이라는 단어에는 총 27 개의 시넷이 있으며, 그중 5 개에는 반의어가있는 기본형이 있습니다. 반의어 ( 'good'가 명사로 사용되고 'good'가 형용사로 사용되는 경우)를 찾아 봅시다.
예 1
from nltk.corpus import wordnet as wn
syn1 = wn.synset('good.n.02')
antonym1 = syn1.lemmas()[0].antonyms()[0]
antonym1.name()
산출
'evil'
antonym1.synset().definition()
산출
'the quality of being morally wrong in principle or practice'
위의 예는 명사로 사용될 때 'good'이라는 단어에 첫 번째 반의어 'evil'이 있음을 보여줍니다.
예 2
from nltk.corpus import wordnet as wn
syn2 = wn.synset('good.a.01')
antonym2 = syn2.lemmas()[0].antonyms()[0]
antonym2.name()
산출
'bad'
antonym2.synset().definition()
산출
'having undesirable or negative qualities’
위의 예에서는 'good'이라는 단어가 형용사로 사용될 때 첫 번째 반의어 'bad'가 있음을 보여줍니다.
어간이란 무엇입니까?
어간 법은 단어에서 접사를 제거하여 단어의 기본 형태를 추출하는 데 사용되는 기술입니다. 마치 나무의 가지를 줄기까지 자르는 것과 같습니다. 예를 들어, 단어의 어간eating, eats, eaten 이다 eat.
검색 엔진은 형태소 분석을 사용하여 단어를 색인화합니다. 그렇기 때문에 검색 엔진은 모든 형태의 단어를 저장하는 것이 아니라 줄기 만 저장할 수 있습니다. 이러한 방식으로 형태소 분석은 인덱스 크기를 줄이고 검색 정확도를 높입니다.
다양한 형태소 분석 알고리즘
NLTK에서는 stemmerI, stem()method, interface에는 다음에 다룰 모든 형태소 분석기가 있습니다. 다음 다이어그램으로 이해합시다
포터 스테 밍 알고리즘
기본적으로 잘 알려진 영어 단어의 접미사를 제거하고 대체하도록 설계된 가장 일반적인 형태소 분석 알고리즘 중 하나입니다.
PorterStemmer 클래스
NLTK는 PorterStemmer우리가 어간을 원하는 단어에 대해 Porter Stemmer 알고리즘을 쉽게 구현할 수있는 클래스입니다. 이 클래스는 입력 단어를 최종 어간으로 변환 할 수있는 몇 가지 일반 단어 형식과 접미사를 알고 있습니다. 결과 어간은 종종 동일한 어근 의미를 가진 더 짧은 단어입니다. 예를 봅시다-
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 PorterStemmer Porter Stemmer 알고리즘을 구현하기위한 클래스.
from nltk.stem import PorterStemmer
다음으로 다음과 같이 Porter Stemmer 클래스의 인스턴스를 만듭니다.
word_stemmer = PorterStemmer()
이제 줄기를 원하는 단어를 입력하십시오.
word_stemmer.stem('writing')
산출
'write'
word_stemmer.stem('eating')
산출
'eat'
완전한 구현 예
import nltk
from nltk.stem import PorterStemmer
word_stemmer = PorterStemmer()
word_stemmer.stem('writing')
산출
'write'
Lancaster 형태소 분석 알고리즘
Lancaster University에서 개발되었으며 또 다른 매우 일반적인 형태소 분석 알고리즘입니다.
LancasterStemmer 클래스
NLTK는 LancasterStemmer우리가 어간을 원하는 단어에 대해 Lancaster Stemmer 알고리즘을 쉽게 구현할 수 있습니다. 예를 봅시다-
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 LancasterStemmer Lancaster Stemmer 알고리즘을 구현하는 클래스
from nltk.stem import LancasterStemmer
다음으로 인스턴스를 만듭니다. LancasterStemmer 다음과 같이 클래스-
Lanc_stemmer = LancasterStemmer()
이제 줄기를 원하는 단어를 입력하십시오.
Lanc_stemmer.stem('eats')
산출
'eat'
완전한 구현 예
import nltk
from nltk.stem import LancatserStemmer
Lanc_stemmer = LancasterStemmer()
Lanc_stemmer.stem('eats')
산출
'eat'
정규식 형태소 분석 알고리즘
이 형태소 분석 알고리즘의 도움으로 자체 형태소 분석기를 구성 할 수 있습니다.
RegexpStemmer 클래스
NLTK는 RegexpStemmer정규식 형태소 분석기 알고리즘을 쉽게 구현할 수있는 클래스입니다. 기본적으로 단일 정규식을 취하고 표현식과 일치하는 접두사 또는 접미사를 제거합니다. 예를 봅시다-
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 RegexpStemmer 정규식 형태소 분석기 알고리즘을 구현하는 클래스입니다.
from nltk.stem import RegexpStemmer
다음으로 인스턴스를 만듭니다. RegexpStemmer 클래스와 다음과 같이 단어에서 제거하려는 접미사 또는 접두사를 제공합니다.
Reg_stemmer = RegexpStemmer(‘ing’)
이제 줄기를 원하는 단어를 입력하십시오.
Reg_stemmer.stem('eating')
산출
'eat'
Reg_stemmer.stem('ingeat')
산출
'eat'
Reg_stemmer.stem('eats')
산출
'eat'
완전한 구현 예
import nltk
from nltk.stem import RegexpStemmer
Reg_stemmer = RegexpStemmer()
Reg_stemmer.stem('ingeat')
산출
'eat'
Snowball 형태소 분석 알고리즘
또 다른 매우 유용한 형태소 분석 알고리즘입니다.
SnowballStemmer 클래스
NLTK는 SnowballStemmerSnowball Stemmer 알고리즘을 쉽게 구현할 수있는 클래스입니다. 15 개의 비 영어 언어를 지원합니다. 이 스팀 클래스를 사용하려면 사용중인 언어의 이름으로 인스턴스를 만든 다음 stem () 메서드를 호출해야합니다. 예를 봅시다-
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 SnowballStemmer Snowball Stemmer 알고리즘을 구현하는 클래스
from nltk.stem import SnowballStemmer
지원하는 언어를 살펴 보겠습니다.
SnowballStemmer.languages
산출
(
'arabic',
'danish',
'dutch',
'english',
'finnish',
'french',
'german',
'hungarian',
'italian',
'norwegian',
'porter',
'portuguese',
'romanian',
'russian',
'spanish',
'swedish'
)
다음으로 사용하려는 언어로 SnowballStemmer 클래스의 인스턴스를 만듭니다. 여기서는 '프랑스어'언어에 대한 형태소 분석기를 만들고 있습니다.
French_stemmer = SnowballStemmer(‘french’)
이제 stem () 메서드를 호출하고 파생 할 단어를 입력합니다.
French_stemmer.stem (‘Bonjoura’)
산출
'bonjour'
완전한 구현 예
import nltk
from nltk.stem import SnowballStemmer
French_stemmer = SnowballStemmer(‘french’)
French_stemmer.stem (‘Bonjoura’)
산출
'bonjour'
기본 화란 무엇입니까?
주형 화 기법은 형태소 분석과 같습니다. lemmatization 후 얻을 출력은 'lemma'라고 불리며, 어간 추출의 출력 인 뿌리 줄기가 아닌 어근 단어입니다. lemmatization 후에 우리는 같은 것을 의미하는 유효한 단어를 얻게 될 것입니다.
NLTK는 WordNetLemmatizer 주위에 얇은 래퍼 인 클래스 wordnet신체. 이 클래스는morphy() 기능 WordNet CorpusReader기본형을 찾는 클래스. 예를 들어 이해합시다.
예
먼저 자연어 툴킷 (nltk)을 가져와야합니다.
import nltk
이제 WordNetLemmatizer lemmatization 기술을 구현하는 클래스.
from nltk.stem import WordNetLemmatizer
다음으로 인스턴스를 만듭니다. WordNetLemmatizer 수업.
lemmatizer = WordNetLemmatizer()
이제 lemmatize () 메서드를 호출하고 기본형을 찾고자하는 단어를 입력합니다.
lemmatizer.lemmatize('eating')
산출
'eating'
lemmatizer.lemmatize('books')
산출
'book'
완전한 구현 예
import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
lemmatizer.lemmatize('books')
산출
'book'
형태소 분석과 기본형 화의 차이점
다음 예제를 통해 어간과 기본형의 차이점을 이해하겠습니다.
import nltk
from nltk.stem import PorterStemmer
word_stemmer = PorterStemmer()
word_stemmer.stem('believes')
산출
believ
import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
lemmatizer.lemmatize(' believes ')
산출
believ
두 프로그램의 출력은 형태소 분석과 lemmatization의 주요 차이점을 알려줍니다. PorterStemmer수업은 단어에서 'es'를 잘라냅니다. 반면에WordNetLemmatizerclass는 유효한 단어를 찾습니다. 간단히 말해서 형태소 분석 기법은 단어의 형태 만 보는 반면 lemmatization 기법은 단어의 의미를 살펴 봅니다. lemmatization을 적용하면 항상 유효한 단어를 얻을 수 있다는 의미입니다.
어간 및 lemmatization은 일종의 언어 압축으로 간주 될 수 있습니다. 같은 의미에서 단어 교체는 텍스트 정규화 또는 오류 수정으로 생각할 수 있습니다.
그런데 왜 우리는 단어 교체가 필요합니까? 토큰 화에 대해 이야기하면 수축에 문제가 있다고 가정합니다 (예 : 할 수 없음, 할 수 없음 등). 따라서 이러한 문제를 처리하려면 단어 교체가 필요합니다. 예를 들어, 수축을 확장 된 형태로 바꿀 수 있습니다.
정규식을 사용한 단어 바꾸기
먼저 정규 표현식과 일치하는 단어를 교체합니다. 그러나이를 위해서는 파이썬 re 모듈뿐만 아니라 정규 표현식에 대한 기본적인 이해가 있어야합니다. 아래 예에서 우리는 수축을 확장 된 형태로 대체 할 것입니다 (예 : "ca n't"는 "cannot"로 대체 됨). 모든 것은 정규 표현식을 사용하여 이루어집니다.
예
먼저 정규식 작업에 필요한 패키지를 다시 가져옵니다.
import re
from nltk.corpus import wordnet
다음으로, 다음과 같이 선택한 대체 패턴을 정의하십시오.
R_patterns = [
(r'won\'t', 'will not'),
(r'can\'t', 'cannot'),
(r'i\'m', 'i am'),
r'(\w+)\'ll', '\g<1> will'),
(r'(\w+)n\'t', '\g<1> not'),
(r'(\w+)\'ve', '\g<1> have'),
(r'(\w+)\'s', '\g<1> is'),
(r'(\w+)\'re', '\g<1> are'),
]
이제 단어를 대체하는 데 사용할 수있는 클래스를 만듭니다.
class REReplacer(object):
def __init__(self, pattern = R_patterns):
self.pattern = [(re.compile(regex), repl) for (regex, repl) in patterns]
def replace(self, text):
s = text
for (pattern, repl) in self.pattern:
s = re.sub(pattern, repl, s)
return s
이 Python 프로그램 (예 : repRE.py)을 저장하고 Python 명령 프롬프트에서 실행합니다. 실행 후 단어를 바꾸고 싶을 때 REReplacer 클래스를 가져옵니다. 방법을 살펴 보겠습니다.
from repRE import REReplacer
rep_word = REReplacer()
rep_word.replace("I won't do it")
Output:
'I will not do it'
rep_word.replace("I can’t do it")
Output:
'I cannot do it'
완전한 구현 예
import re
from nltk.corpus import wordnet
R_patterns = [
(r'won\'t', 'will not'),
(r'can\'t', 'cannot'),
(r'i\'m', 'i am'),
r'(\w+)\'ll', '\g<1> will'),
(r'(\w+)n\'t', '\g<1> not'),
(r'(\w+)\'ve', '\g<1> have'),
(r'(\w+)\'s', '\g<1> is'),
(r'(\w+)\'re', '\g<1> are'),
]
class REReplacer(object):
def __init__(self, patterns=R_patterns):
self.patterns = [(re.compile(regex), repl) for (regex, repl) in patterns]
def replace(self, text):
s = text
for (pattern, repl) in self.patterns:
s = re.sub(pattern, repl, s)
return s
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from replacerRE import REReplacer
rep_word = REReplacer()
rep_word.replace("I won't do it")
산출
'I will not do it'
텍스트 처리 전 교체
자연어 처리 (NLP)로 작업하는 동안 일반적인 관행 중 하나는 텍스트 처리 전에 텍스트를 정리하는 것입니다. 이 문제에서 우리는 또한 우리의REReplacer 텍스트 처리 (즉, 토큰 화) 전에 예비 단계로 이전 예제에서 생성 된 클래스.
예
from nltk.tokenize import word_tokenize
from replacerRE import REReplacer
rep_word = REReplacer()
word_tokenize("I won't be able to do this now")
Output:
['I', 'wo', "n't", 'be', 'able', 'to', 'do', 'this', 'now']
word_tokenize(rep_word.replace("I won't be able to do this now"))
Output:
['I', 'will', 'not', 'be', 'able', 'to', 'do', 'this', 'now']
위의 Python 레시피에서 정규식 바꾸기를 사용하지 않는 경우와 사용하는 경우의 단어 토크 나이저 출력의 차이를 쉽게 이해할 수 있습니다.
반복되는 문자 제거
우리는 일상 언어로 엄격하게 문법을 사용합니까? 아니 우리는하지 않습니다. 예를 들어 '안녕'이라는 단어를 강조하기 위해 가끔 'Hiiiiiiiiiiii Mohan'이라고 씁니다. 그러나 컴퓨터 시스템은 'Hiiiiiiiiiiii'가 'Hi'라는 단어의 변형이라는 것을 모릅니다. 아래 예에서는 다음과 같은 클래스를 생성합니다.rep_word_removal 반복되는 단어를 제거하는 데 사용할 수 있습니다.
예
먼저 정규 표현식 작업에 필요한 패키지를 가져옵니다.
import re
from nltk.corpus import wordnet
이제 반복되는 단어를 제거하는 데 사용할 수있는 클래스를 만듭니다.
class Rep_word_removal(object):
def __init__(self):
self.repeat_regexp = re.compile(r'(\w*)(\w)\2(\w*)')
self.repl = r'\1\2\3'
def replace(self, word):
if wordnet.synsets(word):
return word
repl_word = self.repeat_regexp.sub(self.repl, word)
if repl_word != word:
return self.replace(repl_word)
else:
return repl_word
이 파이썬 프로그램 (removerepeat.py)을 저장하고 파이썬 명령 프롬프트에서 실행하십시오. 실행 후 가져 오기Rep_word_removal반복되는 단어를 제거하려는 경우 클래스. 어떻게 볼까요?
from removalrepeat import Rep_word_removal
rep_word = Rep_word_removal()
rep_word.replace ("Hiiiiiiiiiiiiiiiiiiiii")
Output:
'Hi'
rep_word.replace("Hellooooooooooooooo")
Output:
'Hello'
완전한 구현 예
import re
from nltk.corpus import wordnet
class Rep_word_removal(object):
def __init__(self):
self.repeat_regexp = re.compile(r'(\w*)(\w)\2(\w*)')
self.repl = r'\1\2\3'
def replace(self, word):
if wordnet.synsets(word):
return word
replace_word = self.repeat_regexp.sub(self.repl, word)
if replace_word != word:
return self.replace(replace_word)
else:
return replace_word
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from removalrepeat import Rep_word_removal
rep_word = Rep_word_removal()
rep_word.replace ("Hiiiiiiiiiiiiiiiiiiiii")
산출
'Hi'
공통 동의어로 단어 바꾸기
NLP로 작업하는 동안, 특히 빈도 분석 및 텍스트 인덱싱의 경우에는 많은 메모리를 절약하기 때문에 의미를 잃지 않고 어휘를 압축하는 것이 항상 유익합니다. 이를 위해서는 단어와 동의어의 매핑을 정의해야합니다. 아래 예에서는 다음과 같은 클래스를 생성합니다.word_syn_replacer 단어를 공통 동의어로 대체하는 데 사용할 수 있습니다.
예
먼저 필요한 패키지를 가져옵니다. re 정규 표현식으로 작업합니다.
import re
from nltk.corpus import wordnet
다음으로, 단어 대체 매핑을 취하는 클래스를 만듭니다.
class word_syn_replacer(object):
def __init__(self, word_map):
self.word_map = word_map
def replace(self, word):
return self.word_map.get(word, word)
이 파이썬 프로그램 (예 : replacesyn.py)을 저장하고 파이썬 명령 프롬프트에서 실행하십시오. 실행 후 가져 오기word_syn_replacer단어를 공통 동의어로 바꾸려는 경우 클래스. 방법을 살펴 보겠습니다.
from replacesyn import word_syn_replacer
rep_syn = word_syn_replacer ({‘bday’: ‘birthday’)
rep_syn.replace(‘bday’)
산출
'birthday'
완전한 구현 예
import re
from nltk.corpus import wordnet
class word_syn_replacer(object):
def __init__(self, word_map):
self.word_map = word_map
def replace(self, word):
return self.word_map.get(word, word)
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from replacesyn import word_syn_replacer
rep_syn = word_syn_replacer ({‘bday’: ‘birthday’)
rep_syn.replace(‘bday’)
산출
'birthday'
위 방법의 단점은 파이썬 사전에 동의어를 하드 코딩해야한다는 것입니다. CSV 및 YAML 파일 형식의 두 가지 더 나은 대안이 있습니다. 우리는 위에서 언급 한 파일에 동의어 어휘를 저장하고 다음을 구성 할 수 있습니다.word_map그들로부터 사전. 예제의 도움으로 개념을 이해합시다.
CSV 파일 사용
이러한 목적으로 CSV 파일을 사용하려면 파일에 두 개의 열이 있어야합니다. 첫 번째 열은 단어로 구성되고 두 번째 열은 단어를 대체 할 동의어로 구성됩니다. 이 파일을 다음과 같이 저장하겠습니다.syn.csv. 아래 예에서는 다음과 같은 클래스를 생성합니다. CSVword_syn_replacer 확장됩니다 word_syn_replacer 에 replacesyn.py 파일을 구성하는 데 사용됩니다. word_map 사전 syn.csv 파일.
예
먼저 필요한 패키지를 가져옵니다.
import csv
다음으로, 단어 대체 매핑을 취하는 클래스를 만듭니다.
class CSVword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
word_map = {}
for line in csv.reader(open(fname)):
word, syn = line
word_map[word] = syn
super(Csvword_syn_replacer, self).__init__(word_map)
실행 후 가져 오기 CSVword_syn_replacer단어를 공통 동의어로 바꾸려는 경우 클래스. 어떻게 볼까요?
from replacesyn import CSVword_syn_replacer
rep_syn = CSVword_syn_replacer (‘syn.csv’)
rep_syn.replace(‘bday’)
산출
'birthday'
완전한 구현 예
import csv
class CSVword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
word_map = {}
for line in csv.reader(open(fname)):
word, syn = line
word_map[word] = syn
super(Csvword_syn_replacer, self).__init__(word_map)
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from replacesyn import CSVword_syn_replacer
rep_syn = CSVword_syn_replacer (‘syn.csv’)
rep_syn.replace(‘bday’)
산출
'birthday'
YAML 파일 사용
CSV 파일을 사용 했으므로이 목적으로 YAML 파일을 사용할 수도 있습니다 (PyYAML이 설치되어 있어야 함). 파일을 다음과 같이 저장하겠습니다.syn.yaml. 아래 예에서는 다음과 같은 클래스를 생성합니다. YAMLword_syn_replacer 확장됩니다 word_syn_replacer 에 replacesyn.py 파일을 구성하는 데 사용됩니다. word_map 사전 syn.yaml 파일.
예
먼저 필요한 패키지를 가져옵니다.
import yaml
다음으로, 단어 대체 매핑을 취하는 클래스를 만듭니다.
class YAMLword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
word_map = yaml.load(open(fname))
super(YamlWordReplacer, self).__init__(word_map)
실행 후 가져 오기 YAMLword_syn_replacer단어를 공통 동의어로 바꾸려는 경우 클래스. 어떻게 볼까요?
from replacesyn import YAMLword_syn_replacer
rep_syn = YAMLword_syn_replacer (‘syn.yaml’)
rep_syn.replace(‘bday’)
산출
'birthday'
완전한 구현 예
import yaml
class YAMLword_syn_replacer(word_syn_replacer):
def __init__(self, fname):
word_map = yaml.load(open(fname))
super(YamlWordReplacer, self).__init__(word_map)
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from replacesyn import YAMLword_syn_replacer
rep_syn = YAMLword_syn_replacer (‘syn.yaml’)
rep_syn.replace(‘bday’)
산출
'birthday'
반의어 대체
우리가 알다시피 반의어는 다른 단어와 반대의 의미를 가진 단어이고 동의어 대체의 반대는 반의어 대체라고합니다. 이 섹션에서는 반의어 대체, 즉 WordNet을 사용하여 단어를 명확한 반의어로 대체하는 방법을 다룰 것입니다. 아래 예에서는 다음과 같은 클래스를 생성합니다.word_antonym_replacer 두 가지 방법이 있습니다. 하나는 단어를 바꾸는 것이고 다른 하나는 부정을 제거하는 것입니다.
예
먼저 필요한 패키지를 가져옵니다.
from nltk.corpus import wordnet
다음으로, word_antonym_replacer −
class word_antonym_replacer(object):
def replace(self, word, pos=None):
antonyms = set()
for syn in wordnet.synsets(word, pos=pos):
for lemma in syn.lemmas():
for antonym in lemma.antonyms():
antonyms.add(antonym.name())
if len(antonyms) == 1:
return antonyms.pop()
else:
return None
def replace_negations(self, sent):
i, l = 0, len(sent)
words = []
while i < l:
word = sent[i]
if word == 'not' and i+1 < l:
ant = self.replace(sent[i+1])
if ant:
words.append(ant)
i += 2
continue
words.append(word)
i += 1
return words
이 파이썬 프로그램 (예 : replaceantonym.py)을 저장하고 파이썬 명령 프롬프트에서 실행하십시오. 실행 후 가져 오기word_antonym_replacer단어를 명확한 반의어로 바꾸고 싶을 때 수업. 방법을 살펴 보겠습니다.
from replacerantonym import word_antonym_replacer
rep_antonym = word_antonym_replacer ()
rep_antonym.replace(‘uglify’)
산출
['beautify'']
sentence = ["Let us", 'not', 'uglify', 'our', 'country']
rep_antonym.replace _negations(sentence)
산출
["Let us", 'beautify', 'our', 'country']
완전한 구현 예
nltk.corpus import wordnet
class word_antonym_replacer(object):
def replace(self, word, pos=None):
antonyms = set()
for syn in wordnet.synsets(word, pos=pos):
for lemma in syn.lemmas():
for antonym in lemma.antonyms():
antonyms.add(antonym.name())
if len(antonyms) == 1:
return antonyms.pop()
else:
return None
def replace_negations(self, sent):
i, l = 0, len(sent)
words = []
while i < l:
word = sent[i]
if word == 'not' and i+1 < l:
ant = self.replace(sent[i+1])
if ant:
words.append(ant)
i += 2
continue
words.append(word)
i += 1
return words
이제 위의 프로그램을 저장하고 실행하면 다음과 같이 클래스를 가져와 사용할 수 있습니다.
from replacerantonym import word_antonym_replacer
rep_antonym = word_antonym_replacer ()
rep_antonym.replace(‘uglify’)
sentence = ["Let us", 'not', 'uglify', 'our', 'country']
rep_antonym.replace _negations(sentence)
산출
["Let us", 'beautify', 'our', 'country']
말뭉치 란 무엇입니까?
말뭉치는 자연스러운 의사 소통 환경에서 생성 된 기계 판독 가능 텍스트의 구조화 된 형식의 대규모 컬렉션입니다. Corpora라는 단어는 Corpus의 복수형입니다. 코퍼스는 다음과 같이 여러 가지 방법으로 파생 될 수 있습니다.
- 원래 전자적 텍스트에서
- 구어 기록에서
- 광학 문자 인식 등에서
코퍼스 대표성, 코퍼스 균형, 샘플링, 코퍼스 크기는 코퍼스를 설계하는 데 중요한 역할을하는 요소입니다. NLP 작업에 가장 많이 사용되는 코퍼스 중 일부는 TreeBank, PropBank, VarbNet 및 WordNet입니다.
사용자 지정 말뭉치를 구축하는 방법은 무엇입니까?
NLTK를 다운로드하는 동안 NLTK 데이터 패키지도 설치했습니다. 따라서 이미 컴퓨터에 NLTK 데이터 패키지가 설치되어 있습니다. Windows에 대해 이야기하면이 데이터 패키지가 다음 위치에 설치되어 있다고 가정합니다.C:\natural_language_toolkit_data Linux, Unix 및 Mac OS X에 대해 이야기하면이 데이터 패키지가 다음 위치에 설치되어 있다고 가정합니다. /usr/share/natural_language_toolkit_data.
다음 Python 레시피에서는 NLTK에서 정의한 경로 중 하나 내에 있어야하는 사용자 지정 말뭉치를 만들 것입니다. NLTK에서 찾을 수 있기 때문입니다. 공식 NLTK 데이터 패키지와의 충돌을 피하기 위해 홈 디렉토리에 사용자 정의 natural_language_toolkit_data 디렉토리를 생성하겠습니다.
import os, os.path
path = os.path.expanduser('~/natural_language_toolkit_data')
if not os.path.exists(path):
os.mkdir(path)
os.path.exists(path)
산출
True
이제 홈 디렉토리에 natural_language_toolkit_data 디렉토리가 있는지 확인하겠습니다.
import nltk.data
path in nltk.data.path
산출
True
True 출력을 얻었으므로 nltk_data 우리 홈 디렉토리의 디렉토리.
이제 우리는 단어 목록 파일을 만들 것입니다. wordfile.txt corpus라는 폴더에 넣습니다. nltk_data 예배 규칙서 (~/nltk_data/corpus/wordfile.txt) 다음을 사용하여로드합니다. nltk.data.load −
import nltk.data
nltk.data.load(‘corpus/wordfile.txt’, format = ‘raw’)
산출
b’tutorialspoint\n’
코퍼스 독자
NLTK는 다양한 CorpusReader 클래스를 제공합니다. 다음 파이썬 레시피에서 다룰 것입니다.
단어 목록 말뭉치 만들기
NLTK는 WordListCorpusReader단어 목록이 포함 된 파일에 대한 액세스를 제공하는 클래스입니다. 다음 Python 레시피의 경우 CSV 또는 일반 텍스트 파일이 될 수있는 단어 목록 파일을 만들어야합니다. 예를 들어 다음 데이터를 포함하는 'list'라는 파일을 만들었습니다.
tutorialspoint
Online
Free
Tutorials
이제 인스턴스화하겠습니다. WordListCorpusReader 생성 된 파일에서 단어 목록을 생성하는 클래스 ‘list’.
from nltk.corpus.reader import WordListCorpusReader
reader_corpus = WordListCorpusReader('.', ['list'])
reader_corpus.words()
산출
['tutorialspoint', 'Online', 'Free', 'Tutorials']
POS 태그가있는 단어 말뭉치 만들기
NLTK는 TaggedCorpusReader클래스의 도움으로 POS 태그가 붙은 단어 말뭉치를 만들 수 있습니다. 실제로 POS 태깅은 단어의 품사 태그를 식별하는 프로세스입니다.
태그가있는 말뭉치를위한 가장 간단한 형식 중 하나는 갈색 말뭉치에서 발췌 한 다음과 같은 '단어 / 태그'형식입니다.
The/at-tl expense/nn and/cc time/nn involved/vbn are/ber
astronomical/jj ./.
위의 발췌 부분에서 각 단어에는 POS를 나타내는 태그가 있습니다. 예를 들면vb 동사를 의미합니다.
이제 인스턴스화하겠습니다. TaggedCorpusReaderPOS 태그가 붙은 단어를 생성하는 클래스는 파일을 형성합니다. ‘list.pos’, 위의 발췌가 있습니다.
from nltk.corpus.reader import TaggedCorpusReader
reader_corpus = TaggedCorpusReader('.', r'.*\.pos')
reader_corpus.tagged_words()
산출
[('The', 'AT-TL'), ('expense', 'NN'), ('and', 'CC'), ...]
청크 구문 말뭉치 만들기
NLTK는 ChnkedCorpusReader클래스의 도움으로 청크 구문 말뭉치를 만들 수 있습니다. 사실, 청크는 문장의 짧은 문구입니다.
예를 들어, 태그에서 발췌 한 다음은 treebank 말뭉치 −
[Earlier/JJR staff-reduction/NN moves/NNS] have/VBP trimmed/VBN about/
IN [300/CD jobs/NNS] ,/, [the/DT spokesman/NN] said/VBD ./.
위의 발췌에서 모든 청크는 명사구이지만 괄호 안에 있지 않은 단어는 명사구 하위 트리의 일부가 아니라 문장 트리의 일부입니다.
이제 인스턴스화하겠습니다. ChunkedCorpusReader 파일에서 청크 구문을 생성하는 클래스 ‘list.chunk’, 위의 발췌가 있습니다.
from nltk.corpus.reader import ChunkedCorpusReader
reader_corpus = TaggedCorpusReader('.', r'.*\.chunk')
reader_corpus.chunked_words()
산출
[
Tree('NP', [('Earlier', 'JJR'), ('staff-reduction', 'NN'), ('moves', 'NNS')]),
('have', 'VBP'), ...
]
분류 된 텍스트 말뭉치 만들기
NLTK는 CategorizedPlaintextCorpusReader분류 된 텍스트 코퍼스를 만들 수있는 클래스입니다. 큰 텍스트 코퍼스가 있고이를 별도의 섹션으로 분류하려는 경우에 매우 유용합니다.
예를 들어 갈색 말뭉치에는 여러 가지 범주가 있습니다. 다음 Python 코드의 도움으로 그들을 찾아 보자.
from nltk.corpus import brown^M
brown.categories()
산출
[
'adventure', 'belles_lettres', 'editorial', 'fiction', 'government',
'hobbies', 'humor', 'learned', 'lore', 'mystery', 'news', 'religion',
'reviews', 'romance', 'science_fiction'
]
말뭉치를 분류하는 가장 쉬운 방법 중 하나는 모든 범주에 대해 하나의 파일을 갖는 것입니다. 예를 들어, 다음에서 발췌 한 두 가지를 살펴 보겠습니다.movie_reviews 말뭉치 −
movie_pos.txt
얇은 빨간 선은 결함이 있지만 자극합니다.
movie_neg.txt
큰 예산과 광택있는 제작은 TV 쇼에 스며드는 자발성의 부족을 보충 할 수 없습니다.
따라서 위의 두 파일에서 두 가지 범주가 있습니다. pos 과 neg.
이제 인스턴스화하겠습니다. CategorizedPlaintextCorpusReader 수업.
from nltk.corpus.reader import CategorizedPlaintextCorpusReader
reader_corpus = CategorizedPlaintextCorpusReader('.', r'movie_.*\.txt',
cat_pattern = r'movie_(\w+)\.txt')
reader_corpus.categories()
reader_corpus.fileids(categories = [‘neg’])
reader_corpus.fileids(categories = [‘pos’])
산출
['neg', 'pos']
['movie_neg.txt']
['movie_pos.txt']
POS 태깅이란 무엇입니까?
분류의 일종 인 태깅은 토큰 설명을 자동으로 할당하는 것입니다. 우리는 품사 (명사, 동사, 부사, 형용사, 대명사, 접속사 및 하위 범주), 의미 정보 등의 부분 중 하나를 나타내는 설명자를 '태그'라고합니다.
반면 품사 (POS) 태깅에 대해 이야기하면 단어 목록 형태의 문장을 튜플 목록으로 변환하는 과정으로 정의 할 수 있습니다. 여기에서 튜플은 (단어, 태그) 형식입니다. 또한 품사 중 하나를 주어진 단어에 할당하는 프로세스를 POS 태깅이라고 부를 수 있습니다.
다음 표는 Penn Treebank 코퍼스에서 가장 자주 사용되는 POS 알림을 나타냅니다.
Sr. 아니요 | 꼬리표 | 기술 |
---|---|---|
1 | NNP | 고유 명사, 단수 |
2 | NNPS | 고유 명사, 복수 |
삼 | PDT | 사전 결정자 |
4 | POS | 소유 엔딩 |
5 | PRP | 개인 대명사 |
6 | PRP $ | 소유 대명사 |
7 | RB | 부사 |
8 | RBR | 부사, 비교 |
9 | RBS | 부사, 최상급 |
10 | RP | 입자 |
11 | SYM | 기호 (수학적 또는 과학적) |
12 | 에 | ...에 |
13 | 어 | 감탄사 |
14 | VB | 동사, 기본형 |
15 | VBD | 동사, 과거형 |
16 | VBG | 동사, 동명사 / 현재 분사 |
17 | VBN | 동사, 과거 |
18 | WP | Wh- 대명사 |
19 | WP $ | 소유격 wh- 대명사 |
20 | WRB | Wh- 부사 |
21 | # | 파운드 기호 |
22 | $ | 달러 표시 |
23 | . | 문장-최종 구두점 |
24 | , | 반점 |
25 | : | 콜론, 세미콜론 |
26 | ( | 왼쪽 대괄호 문자 |
27 | ) | 오른쪽 대괄호 문자 |
28 | " | 곧은 큰 따옴표 |
29 | ' | 왼쪽 열림 작은 따옴표 |
30 | " | 왼쪽 열림 큰 따옴표 |
31 | ' | 오른쪽 닫는 작은 따옴표 |
32 | " | 오른쪽 열림 큰 따옴표 |
예
파이썬 실험으로 이해합시다.
import nltk
from nltk import word_tokenize
sentence = "I am going to school"
print (nltk.pos_tag(word_tokenize(sentence)))
산출
[('I', 'PRP'), ('am', 'VBP'), ('going', 'VBG'), ('to', 'TO'), ('school', 'NN')]
왜 POS 태깅인가?
POS 태깅은 다음과 같이 추가 NLP 분석의 전제 조건으로 작동하기 때문에 NLP의 중요한 부분입니다.
- Chunking
- 구문 분석
- 정보 추출
- 기계 번역
- 감정 분석
- 문법 분석 및 단어 의미 명확화
TaggerI-기본 클래스
모든 tagger는 NLTK의 nltk.tag 패키지에 있습니다. 이러한 태거의 기본 클래스는TaggerI, 모든 tagger가이 클래스에서 상속됨을 의미합니다.
Methods − TaggerI 클래스에는 모든 하위 클래스에서 구현해야하는 다음 두 가지 메서드가 있습니다.
tag() method − 이름에서 알 수 있듯이이 메서드는 단어 목록을 입력으로 취하고 태그가 지정된 단어 목록을 출력으로 반환합니다.
evaluate() method −이 방법의 도움으로 태거의 정확성을 평가할 수 있습니다.
POS 태깅의 기준
POS 태깅의 기준 또는 기본 단계는 Default Tagging, NLTK의 DefaultTagger 클래스를 사용하여 수행 할 수 있습니다. 기본 태깅은 단순히 모든 토큰에 동일한 POS 태그를 할당합니다. 기본 태깅은 정확도 향상을 측정하기위한 기준을 제공합니다.
DefaultTagger 클래스
기본 태깅은 다음을 사용하여 수행됩니다. DefaultTagging 단일 인수, 즉 적용하려는 태그를받는 클래스입니다.
어떻게 작동합니까?
앞서 말했듯이 모든 태거는 TaggerI수업. 그만큼DefaultTagger 물려받은 SequentialBackoffTagger 하위 클래스입니다 TaggerI class. 다음 다이어그램으로 이해하겠습니다.
의 일부로서 SeuentialBackoffTagger, DefaultTagger 다음 세 가지 인수를 취하는 choose_tag () 메소드를 구현해야합니다.
- 토큰 목록
- 현재 토큰의 인덱스
- 이전 토큰의 목록, 즉 이력
예
import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
exptagger.tag(['Tutorials','Point'])
산출
[('Tutorials', 'NN'), ('Point', 'NN')]
이 예에서는 가장 일반적인 단어 유형이기 때문에 명사 태그를 선택했습니다. 게다가,DefaultTagger 가장 일반적인 POS 태그를 선택할 때도 가장 유용합니다.
정확성 평가
그만큼 DefaultTagger태그 사용자의 정확성을 평가하는 기준이기도합니다. 그것이 우리가 그것을 함께 사용할 수있는 이유입니다evaluate()정확도 측정 방법. 그만큼evaluate() 메소드는 태거를 평가하기위한 금색 표준으로 태그가 지정된 토큰 목록을 사용합니다.
다음은 기본 태거를 사용한 예입니다. exptagger의 하위 집합의 정확성을 평가하기 위해 위에서 만든 treebank 말뭉치 태그 문장 −
예
import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
from nltk.corpus import treebank
testsentences = treebank.tagged_sents() [1000:]
exptagger.evaluate (testsentences)
산출
0.13198749536374715
위의 출력은 NN 모든 태그에 대해 1000 개의 항목에 대해 약 13 %의 정확도 테스트를 달성 할 수 있습니다. treebank 신체.
문장 목록에 태그 달기
한 문장에 태그를 붙이는 대신 NLTK의 TaggerI 수업은 또한 우리에게 tag_sents()방법을 사용하여 문장 목록에 태그를 지정할 수 있습니다. 다음은 두 개의 간단한 문장에 태그를 붙인 예입니다.
예
import nltk
from nltk.tag import DefaultTagger
exptagger = DefaultTagger('NN')
exptagger.tag_sents([['Hi', ','], ['How', 'are', 'you', '?']])
산출
[
[
('Hi', 'NN'),
(',', 'NN')
],
[
('How', 'NN'),
('are', 'NN'),
('you', 'NN'),
('?', 'NN')
]
]
위의 예에서는 이전에 만든 기본 태거 인 exptagger.
문장 태그 해제
문장의 태그를 해제 할 수도 있습니다. NLTK는이를 위해 nltk.tag.untag () 메소드를 제공합니다. 태그가 붙은 문장을 입력으로 받아 태그가없는 단어 목록을 제공합니다. 예를 봅시다-
예
import nltk
from nltk.tag import untag
untag([('Tutorials', 'NN'), ('Point', 'NN')])
산출
['Tutorials', 'Point']
Unigram Tagger는 무엇입니까?
이름에서 알 수 있듯이 유니 그램 태거는 POS (Part-of-Speech) 태그를 결정하는 컨텍스트로 한 단어 만 사용하는 태거입니다. 간단히 말해서 Unigram Tagger는 컨텍스트가 단일 단어 인 Unigram 인 컨텍스트 기반 태거입니다.
어떻게 작동합니까?
NLTK는 UnigramTagger이 목적을 위해. 그러나 그 작동에 깊이 들어가기 전에 다음 다이어그램의 도움으로 계층 구조를 이해합시다.
위의 다이어그램에서 UnigramTagger 물려받은 NgramTagger 하위 클래스입니다 ContextTagger, 상속 SequentialBackoffTagger.
작업 UnigramTagger 다음 단계의 도움으로 설명됩니다-
우리가 보았 듯이 UnigramTagger 상속 ContextTagger, 그것은 context()방법. 이context() 메소드는 다음과 같은 세 개의 인수를 사용합니다. choose_tag() 방법.
결과 context()method는 모델을 만드는 데 더 많이 사용되는 단어 토큰입니다. 모델이 생성되면 토큰이라는 단어도 최고의 태그를 찾는 데 사용됩니다.
이런 식으로, UnigramTagger 태그가 지정된 문장 목록에서 컨텍스트 모델을 구축합니다.
유니 그램 태거 훈련
NLTK UnigramTagger초기화시 태그 된 문장 목록을 제공하여 학습 할 수 있습니다. 아래 예에서는 treebank 말뭉치의 태그가 지정된 문장을 사용합니다. 우리는 그 말뭉치에서 처음 2500 개의 문장을 사용할 것입니다.
예
먼저 nltk에서 UniframTagger 모듈을 가져옵니다.
from nltk.tag import UnigramTagger
다음으로 사용할 말뭉치를 가져옵니다. 여기서 우리는 treebank 말뭉치를 사용하고 있습니다-
from nltk.corpus import treebank
이제 훈련 목적으로 문장을 가져 가십시오. 우리는 훈련 목적으로 처음 2500 문장을 취하고 태그를 붙일 것입니다.
train_sentences = treebank.tagged_sents()[:2500]
다음으로 훈련 목적으로 사용되는 문장에 UnigramTagger를 적용합니다.
Uni_tagger = UnigramTagger(train_sentences)
훈련 목적 즉, 테스트 목적을 위해 2500 개 이하의 문장을 몇 개 가져옵니다. 여기에서 테스트 목적으로 처음 1500 개를 사용합니다.
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sents)
산출
0.8942306156033808
여기서 POS 태그를 결정하기 위해 단일 단어 조회를 사용하는 태거의 정확도는 약 89 %입니다.
완전한 구현 예
from nltk.tag import UnigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Uni_tagger = UnigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)
산출
0.8942306156033808
컨텍스트 모델 재정의
위의 다이어그램에서 UnigramTagger, 우리는 ContextTagger은 자체적으로 학습하는 대신 미리 빌드 된 모델을 사용할 수 있습니다. 이 미리 빌드 된 모델은 단순히 컨텍스트 키를 태그에 매핑하는 Python 사전입니다. 그리고UnigramTagger, 컨텍스트 키는 개별 단어이고 기타 NgramTagger 서브 클래스의 경우 튜플이됩니다.
다른 간단한 모델을 전달하여이 컨텍스트 모델을 재정의 할 수 있습니다. UnigramTagger교육 세트를 통과하는 대신 수업. 아래의 쉬운 예를 통해 이해합시다.
예
from nltk.tag import UnigramTagger
from nltk.corpus import treebank
Override_tagger = UnigramTagger(model = {‘Vinken’ : ‘NN’})
Override_tagger.tag(treebank.sents()[0])
산출
[
('Pierre', None),
('Vinken', 'NN'),
(',', None),
('61', None),
('years', None),
('old', None),
(',', None),
('will', None),
('join', None),
('the', None),
('board', None),
('as', None),
('a', None),
('nonexecutive', None),
('director', None),
('Nov.', None),
('29', None),
('.', None)
]
우리 모델에는 유일한 컨텍스트 키로 'Vinken'이 포함되어 있으므로 위의 출력에서이 단어에만 태그가 있고 다른 모든 단어에는 태그로 None이 있음을 확인할 수 있습니다.
최소 주파수 임계 값 설정
주어진 컨텍스트에 대해 가장 가능성이 높은 태그를 결정하려면 ContextTagger클래스는 발생 빈도를 사용합니다. 컨텍스트 단어와 태그가 한 번만 발생하더라도 기본적으로 수행되지만, 다음을 전달하여 최소 빈도 임계 값을 설정할 수 있습니다.cutoff 가치 UnigramTagger수업. 아래 예에서는 UnigramTagger를 학습 한 이전 레시피의 컷오프 값을 전달합니다.
예
from nltk.tag import UnigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Uni_tagger = UnigramTagger(train_sentences, cutoff = 4)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)
산출
0.7357651629613641
태거 결합
태거를 결합하거나 태거를 연결하는 것은 NLTK의 중요한 기능 중 하나입니다. 타거 결합의 기본 개념은 한 타거가 단어에 태그를 지정하는 방법을 모르는 경우 연결 타거에게 전달된다는 것입니다. 이 목적을 달성하기 위해SequentialBackoffTagger 우리에게 제공 Backoff tagging 특색.
백 오프 태깅
앞서 말했듯이 백 오프 태깅은 SequentialBackoffTagger,이를 통해 한 태거가 단어에 태그를 지정하는 방법을 알지 못하는 경우 해당 단어가 확인해야 할 백 오프 태거가 남지 않을 때까지 다음 태거에게 전달되는 방식으로 태거를 결합 할 수 있습니다.
어떻게 작동합니까?
실제로 모든 하위 클래스 SequentialBackoffTagger'백 오프'키워드 인수를 사용할 수 있습니다. 이 키워드 인수의 값은SequentialBackoffTagger. 이제 언제라도SequentialBackoffTagger클래스가 초기화되면 백 오프 태거의 내부 목록 (자체가 첫 번째 요소)이 생성됩니다. 또한 백 오프 태거가 제공되면이 백 오프 태거의 내부 목록이 추가됩니다.
아래 예에서 우리는 DefaulTagger 위의 Python 레시피에서 백 오프 태거로 UnigramTagger.
예
이 예에서 우리는 DefaulTagger백 오프 태거로. 때마다UnigramTagger 단어, 백 오프 태거에 태그를 지정할 수 없습니다. DefaulTagger, 우리의 경우 'NN'으로 태그를 지정합니다.
from nltk.tag import UnigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Uni_tagger = UnigramTagger(train_sentences, backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)
산출
0.9061975746536931
위의 출력에서 백 오프 태거를 추가하면 정확도가 약 2 % 증가하는 것을 확인할 수 있습니다.
피클을 사용하여 태거 저장
태거를 훈련하는 것은 매우 번거롭고 시간이 걸립니다. 시간을 절약하기 위해 나중에 사용할 수 있도록 훈련 된 태거를 피클 할 수 있습니다. 아래 예에서는 이미 훈련 된 태거 인‘Uni_tagger’.
예
import pickle
f = open('Uni_tagger.pickle','wb')
pickle.dump(Uni_tagger, f)
f.close()
f = open('Uni_tagger.pickle','rb')
Uni_tagger = pickle.load(f)
NgramTagger 클래스
이전 단원에서 설명한 계층 구조 다이어그램에서 UnigramTagger 물려받은 NgarmTagger 클래스의 하위 클래스가 두 개 더 있습니다. NgarmTagger 클래스-
BigramTagger 하위 클래스
실제로 ngram은 n 항목의 하위 시퀀스이므로 이름에서 알 수 있듯이 BigramTagger하위 클래스는 두 항목을 살펴 봅니다. 첫 번째 항목은 이전 태그 단어이고 두 번째 항목은 현재 태그 단어입니다.
TrigramTagger 하위 클래스
같은 메모에 BigramTagger, TrigramTagger 하위 클래스는 세 항목, 즉 두 개의 이전 태그 단어와 하나의 현재 태그 단어를 살펴 봅니다.
실제로 신청하면 BigramTagger 과 TrigramTaggerUnigramTagger 하위 클래스에서했던 것처럼 개별적으로 하위 클래스는 성능이 매우 떨어집니다. 아래 예를 살펴 보겠습니다.
BigramTagger 하위 클래스 사용
from nltk.tag import BigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Bi_tagger = BigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Bi_tagger.evaluate(test_sentences)
산출
0.44669191071913594
TrigramTagger 하위 클래스 사용
from nltk.tag import TrigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Tri_tagger = TrigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Tri_tagger.evaluate(test_sentences)
산출
0.41949863394526193
이전에 사용한 UnigramTagger (약 89 % 정확도 제공)와 BigramTagger (약 44 % 정확도 제공) 및 TrigramTagger (약 41 % 정확도 제공)의 성능을 비교할 수 있습니다. 그 이유는 Bigram 및 Trigram 태거가 문장의 첫 번째 단어에서 문맥을 배울 수 없기 때문입니다. 반면에 UnigramTagger 클래스는 이전 컨텍스트를 신경 쓰지 않고 각 단어에 대해 가장 일반적인 태그를 추측하므로 높은 기준 정확도를 가질 수 있습니다.
ngram tagger 결합
위의 예에서와 같이 Bigram 및 Trigram 태거는 백 오프 태깅과 결합 할 때 기여할 수 있습니다. 아래 예에서는 Unigram, Bigram 및 Trigram 태거를 백 오프 태깅과 결합하고 있습니다. 개념은 이전 레시피와 동일하며 UnigramTagger와 backoff tagger를 결합합니다. 유일한 차이점은 백 오프 작업을 위해 아래에 주어진 tagger_util.py의 backoff_tagger ()라는 함수를 사용하고 있다는 것입니다.
def backoff_tagger(train_sentences, tagger_classes, backoff=None):
for cls in tagger_classes:
backoff = cls(train_sentences, backoff=backoff)
return backoff
예
from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)
산출
0.9234530029238365
위의 출력에서 정확도가 약 3 % 증가하는 것을 볼 수 있습니다.
태거 부착
ContextTagger 하위 클래스의 또 다른 중요한 클래스는 AffixTagger입니다. AffixTagger 클래스에서 컨텍스트는 단어의 접두사 또는 접미사입니다. 이것이 AffixTagger 클래스가 단어의 시작 또는 끝 부분의 고정 길이 부분 문자열을 기반으로 태그를 학습 할 수있는 이유입니다.
어떻게 작동합니까?
그 작업은 접두사 또는 접미사의 길이를 지정하는 affix_length라는 인수에 따라 다릅니다. 기본값은 3입니다. 그러나 AffixTagger 클래스가 단어의 접두사 또는 접미사를 학습했는지 여부를 어떻게 구별합니까?
affix_length=positive − affix_lenght의 값이 양수이면 AffixTagger 클래스가 단어의 접두사를 학습 함을 의미합니다.
affix_length=negative − affix_lenght 값이 음수이면 AffixTagger 클래스가 단어의 접미사를 학습 함을 의미합니다.
더 명확하게하기 위해 아래 예에서는 태그가 지정된 트리 뱅크 문장에 AffixTagger 클래스를 사용합니다.
예
이 예에서 AffixTagger는 affix_length 인수에 대한 값을 지정하지 않기 때문에 단어의 접두사를 학습합니다. 인수는 기본값 3을 사용합니다-
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)
산출
0.2800492099250667
affix_length 인수에 값 4를 제공 할 때 정확도가 무엇인지 아래 예제에서 살펴 보겠습니다.
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences, affix_length=4 )
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)
산출
0.18154947354966527
예
이 예에서 AffixTagger는 affix_length 인수에 음수 값을 지정하므로 단어의 접미사를 학습합니다.
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Suffix_tagger = AffixTagger(train_sentences, affix_length = -3)
test_sentences = treebank.tagged_sents()[1500:]
Suffix_tagger.evaluate(test_sentences)
산출
0.2800492099250667
브릴 태거
Brill Tagger는 변형 기반 태거입니다. NLTK는BrillTagger 하위 클래스가 아닌 첫 번째 태거 클래스 SequentialBackoffTagger. 반대로 초기 태거의 결과를 수정하기위한 일련의 규칙은BrillTagger.
어떻게 작동합니까?
훈련하려면 BrillTagger 사용하는 수업 BrillTaggerTrainer 우리는 다음 함수를 정의합니다.
def train_brill_tagger(initial_tagger, train_sentences, **kwargs) −
templates = [
brill.Template(brill.Pos([-1])),
brill.Template(brill.Pos([1])),
brill.Template(brill.Pos([-2])),
brill.Template(brill.Pos([2])),
brill.Template(brill.Pos([-2, -1])),
brill.Template(brill.Pos([1, 2])),
brill.Template(brill.Pos([-3, -2, -1])),
brill.Template(brill.Pos([1, 2, 3])),
brill.Template(brill.Pos([-1]), brill.Pos([1])),
brill.Template(brill.Word([-1])),
brill.Template(brill.Word([1])),
brill.Template(brill.Word([-2])),
brill.Template(brill.Word([2])),
brill.Template(brill.Word([-2, -1])),
brill.Template(brill.Word([1, 2])),
brill.Template(brill.Word([-3, -2, -1])),
brill.Template(brill.Word([1, 2, 3])),
brill.Template(brill.Word([-1]), brill.Word([1])),
]
trainer = brill_trainer.BrillTaggerTrainer(initial_tagger, templates, deterministic=True)
return trainer.train(train_sentences, **kwargs)
보시다시피이 기능에는 initial_tagger 과 train_sentences. 그것은 걸립니다initial_tagger 인수 및 템플릿 목록. BrillTemplate상호 작용. 그만큼BrillTemplate 인터페이스는 nltk.tbl.template기준 치수. 이러한 구현 중 하나는brill.Template 수업.
변환 기반 태거의 주요 역할은 초기 태거의 출력이 학습 문장과 더 일치하도록 수정하는 변환 규칙을 생성하는 것입니다. 아래의 워크 플로우를 보겠습니다.
예
이 예에서는 combine_tagger 백 오프 체인에서 (이전 레시피에서) 태거를 결합하면서 생성 한 NgramTagger 클래스, as initial_tagger. 먼저 다음을 사용하여 결과를 평가하겠습니다.Combine.tagger 다음으로 사용 initial_tagger 브릴 타거를 훈련시키기 위해.
from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(
train_sentences, [UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger
)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)
산출
0.9234530029238365
이제 평가 결과를 살펴 보겠습니다. Combine_tagger 다음과 같이 사용됩니다. initial_tagger 브릴 타거를 훈련하기 위해-
from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)
산출
0.9246832510505041
우리는 BrillTagger 클래스에 비해 정확도가 약간 증가했습니다. Combine_tagger.
완전한 구현 예
from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)
from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)
산출
0.9234530029238365
0.9246832510505041
TnT 태거
Trigrams'nTags의 약자 인 TnT Tagger는 2 차 Markov 모델을 기반으로하는 통계 태거입니다.
어떻게 작동합니까?
다음 단계를 통해 TnT tagger의 작동을 이해할 수 있습니다.
먼저 훈련 데이터를 기반으로 TnT tegger는 여러 내부 FreqDist 과 ConditionalFreqDist 인스턴스.
그 유니 그램 이후에는 이러한 주파수 분포에 의해 bigram 및 trigram이 계산됩니다.
이제 태그하는 동안 빈도를 사용하여 각 단어에 대해 가능한 태그의 확률을 계산합니다.
이것이 NgramTagger의 백 오프 체인을 구성하는 대신 모든 ngram 모델을 함께 사용하여 각 단어에 가장 적합한 태그를 선택하는 이유입니다. 다음 예제에서 TnT tagger로 정확도를 평가 해 보겠습니다.
from nltk.tag import tnt
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
tnt_tagger = tnt.TnT()
tnt_tagger.train(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
tnt_tagger.evaluate(test_sentences)
산출
0.9165508316157791
Brill Tagger로 얻은 것보다 정확도가 약간 떨어집니다.
전화를해야합니다. train() 전에 evaluate() 그렇지 않으면 0 % 정확도를 얻게됩니다.
NLP에서의 구문 분석 및 관련성
라틴어에서 유래 한 '파싱'이라는 단어 ‘pars’ (즉 ‘part’)는 텍스트에서 정확한 의미 또는 사전 적 의미를 그리는 데 사용됩니다. 구문 분석 또는 구문 분석이라고도합니다. 형식 문법의 규칙을 비교하여 구문 분석은 텍스트의 의미를 확인합니다. 예를 들어 "Give me hot ice-cream"과 같은 문장은 구문 분석기 또는 구문 분석기에서 거부됩니다.
이러한 의미에서 다음과 같이 구문 분석 또는 구문 분석 또는 구문 분석을 정의 할 수 있습니다.
형식 문법의 규칙에 따라 자연어의 기호 열을 분석하는 과정으로 정의 할 수있다.
우리는 다음 사항을 통해 NLP에서 구문 분석의 관련성을 이해할 수 있습니다.
구문 분석기는 구문 오류를보고하는 데 사용됩니다.
일반적으로 발생하는 오류에서 복구하여 나머지 프로그램의 처리를 계속할 수 있습니다.
파서 트리는 파서의 도움으로 생성됩니다.
Parser는 NLP에서 중요한 역할을하는 심볼 테이블을 생성하는 데 사용됩니다.
파서는 IR (intermediate representations)을 생성하는데도 사용됩니다.
깊은 대 얕은 파싱
딥 파싱 | 얕은 파싱 |
---|---|
심층 분석에서 검색 전략은 문장에 완전한 구문 구조를 제공합니다. | 주어진 작업에서 구문 정보의 제한된 부분을 구문 분석하는 작업입니다. |
복잡한 NLP 애플리케이션에 적합합니다. | 덜 복잡한 NLP 애플리케이션에 사용할 수 있습니다. |
대화 시스템과 요약은 딥 파싱이 사용되는 NLP 응용 프로그램의 예입니다. | 정보 추출 및 텍스트 마이닝은 심층 분석이 사용되는 NLP 응용 프로그램의 예입니다. |
전체 구문 분석이라고도합니다. | 청킹이라고도합니다. |
다양한 유형의 파서
논의 된 바와 같이 파서는 기본적으로 문법의 절차 적 해석입니다. 다양한 나무의 공간을 검색하여 주어진 문장에 맞는 최적의 나무를 찾습니다. 아래에서 사용 가능한 파서 중 일부를 살펴 보겠습니다.
재귀 하강 파서
재귀 하강 구문 분석은 가장 간단한 구문 분석 형식 중 하나입니다. 다음은 재귀 하강 파서에 대한 몇 가지 중요한 사항입니다.
하향식 프로세스를 따릅니다.
입력 스트림의 구문이 올바른지 확인하려고 시도합니다.
입력 문장을 왼쪽에서 오른쪽으로 읽습니다.
재귀 하강 파서에 필요한 작업 중 하나는 입력 스트림에서 문자를 읽고이를 문법의 터미널과 일치시키는 것입니다.
시프트-리 듀스 파서
다음은 shift-reduce 파서에 대한 몇 가지 중요한 사항입니다.
간단한 상향식 프로세스를 따릅니다.
문법 생산의 오른쪽에 해당하는 일련의 단어와 구를 찾아서 생산의 왼쪽으로 대체합니다.
위의 단어 시퀀스 찾기 시도는 전체 문장이 줄어들 때까지 계속됩니다.
즉, 시프트-리 듀스 파서는 입력 심볼로 시작하여 시작 심볼까지 파서 트리를 구성하려고합니다.
차트 파서
다음은 차트 파서에 대한 몇 가지 중요한 사항입니다-
자연어 문법을 포함하여 모호한 문법에 주로 유용하거나 적합합니다.
구문 분석 문제에 동적 프로그래밍을 적용합니다.
동적 프로그래밍으로 인해 부분적인 가설 결과는 '차트'라는 구조에 저장됩니다.
'차트'도 재사용 할 수 있습니다.
정규식 파서
Regexp 구문 분석은 가장 많이 사용되는 구문 분석 기술 중 하나입니다. 다음은 Regexp 파서에 대한 몇 가지 중요한 사항입니다.
이름에서 알 수 있듯이 POS 태그가 붙은 문자열 위에 문법 형식으로 정의 된 정규식을 사용합니다.
기본적으로 이러한 정규식을 사용하여 입력 문장을 구문 분석하고 이로부터 구문 분석 트리를 생성합니다.
예
다음은 Regexp 파서의 작동 예입니다-
import nltk
sentence = [
("a", "DT"),
("clever", "JJ"),
("fox","NN"),
("was","VBP"),
("jumping","VBP"),
("over","IN"),
("the","DT"),
("wall","NN")
]
grammar = "NP:{<DT>?<JJ>*<NN>}"
Reg_parser = nltk.RegexpParser(grammar)
Reg_parser.parse(sentence)
Output = Reg_parser.parse(sentence)
Output.draw()
산출
종속성 구문 분석
DP (Dependency Parsing), 현대적인 구문 분석 메커니즘으로, 주요 개념은 각 언어 단위, 즉 단어가 직접 링크를 통해 서로 관련된다는 것입니다. 이러한 직접 링크는 실제로‘dependencies’언어학. 예를 들어, 다음 다이어그램은 문장에 대한 종속성 문법을 보여줍니다.“John can hit the ball”.
NLTK 패키지
우리는 NLTK로 의존성 파싱을하는 두 가지 방법을 따랐습니다-
확률 적, 투영 적 종속성 파서
이것이 NLTK로 의존성 파싱을 할 수있는 첫 번째 방법입니다. 그러나이 파서는 제한된 훈련 데이터 세트로 훈련하는 데 제한이 있습니다.
스탠포드 파서
이것은 NLTK로 의존성 파싱을 할 수있는 또 다른 방법입니다. Stanford 파서는 최첨단 종속성 파서입니다. NLTK에는 주위에 래퍼가 있습니다. 이를 사용하려면 다음 두 가지를 다운로드해야합니다.
스탠포드 CoreNLP 파서 .
원하는 언어에 대한 언어 모델 . 예를 들어 영어 모델입니다.
예
모델을 다운로드하면 다음과 같이 NLTK를 통해 사용할 수 있습니다.
from nltk.parse.stanford import StanfordDependencyParser
path_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser.jar'
path_models_jar = 'path_to/stanford-parser-full-2014-08-27/stanford-parser-3.4.1-models.jar'
dep_parser = StanfordDependencyParser(
path_to_jar = path_jar, path_to_models_jar = path_models_jar
)
result = dep_parser.raw_parse('I shot an elephant in my sleep')
depndency = result.next()
list(dependency.triples())
산출
[
((u'shot', u'VBD'), u'nsubj', (u'I', u'PRP')),
((u'shot', u'VBD'), u'dobj', (u'elephant', u'NN')),
((u'elephant', u'NN'), u'det', (u'an', u'DT')),
((u'shot', u'VBD'), u'prep', (u'in', u'IN')),
((u'in', u'IN'), u'pobj', (u'sleep', u'NN')),
((u'sleep', u'NN'), u'poss', (u'my', u'PRP$'))
]
청킹이란 무엇입니까?
자연어 처리에서 중요한 프로세스 중 하나 인 청킹은 품사 (POS)와 짧은 구를 식별하는 데 사용됩니다. 즉, 청킹을 사용하면 문장의 구조를 얻을 수 있습니다. 그것은 또한 불린다partial parsing.
청크 패턴과 턱
Chunk patterns덩어리를 구성하는 단어의 종류를 정의하는 품사 (POS) 태그의 패턴입니다. 수정 된 정규식의 도움으로 청크 패턴을 정의 할 수 있습니다.
더욱이, 우리는 어떤 종류의 단어가 청크에 포함되어서는 안되는 패턴을 정의 할 수 있으며 이러한 단조로운 단어는 다음과 같이 알려져 있습니다. chinks.
구현 예
아래 예에서 문장을 구문 분석 한 결과와 함께 “the book has many chapters”, 청크와 칙칙 패턴을 결합한 명사구에 대한 문법이 있습니다.
import nltk
sentence = [
("the", "DT"),
("book", "NN"),
("has","VBZ"),
("many","JJ"),
("chapters","NNS")
]
chunker = nltk.RegexpParser(
r'''
NP:{<DT><NN.*><.*>*<NN.*>}
}<VB.*>{
'''
)
chunker.parse(sentence)
Output = chunker.parse(sentence)
Output.draw()
산출
위에서 볼 수 있듯이 청크를 지정하는 패턴은 다음과 같이 중괄호를 사용하는 것입니다.
{<DT><NN>}
그리고 chink를 지정하기 위해 다음과 같이 중괄호를 뒤집을 수 있습니다.
}<VB>{.
이제 특정 구문 유형에 대해 이러한 규칙을 문법으로 결합 할 수 있습니다.
정보 추출
우리는 정보 추출 엔진을 구축하는 데 사용할 수있는 파서뿐만 아니라 태거도 살펴 보았습니다. 기본 정보 추출 파이프 라인을 살펴 보겠습니다.
정보 추출에는 다음과 같은 많은 응용 프로그램이 있습니다.
- 비즈니스 인텔리전스
- 수확 재개
- 미디어 분석
- 감정 감지
- 특허 검색
- 이메일 검사
명명 된 엔티티 인식 (NER)
이름이 지정된 엔티티 인식 (NER)은 실제로 이름, 조직, 위치 등과 같은 가장 일반적인 엔티티를 추출하는 방법입니다. 문장 토큰 화, POS 태깅, 청킹, NER, 위 그림에 제공된 파이프 라인을 따릅니다.
예
Import nltk
file = open (
# provide here the absolute path for the file of text for which we want NER
)
data_text = file.read()
sentences = nltk.sent_tokenize(data_text)
tokenized_sentences = [nltk.word_tokenize(sentence) for sentence in sentences]
tagged_sentences = [nltk.pos_tag(sentence) for sentence in tokenized_sentences]
for sent in tagged_sentences:
print nltk.ne_chunk(sent)
일부 수정 된 명명 된 개체 인식 (NER)은 제품 이름, 생물 의학 개체, 브랜드 이름 등과 같은 개체를 추출하는데도 사용할 수 있습니다.
관계 추출
일반적으로 사용되는 또 다른 정보 추출 작업 인 관계 추출은 다양한 엔티티 간의 서로 다른 관계를 추출하는 프로세스입니다. 상속, 동의어, 유사 등과 같은 다른 관계가있을 수 있으며 정의는 정보 요구에 따라 달라집니다. 예를 들어, 책의 쓰기를 찾고 싶다면 저자는 저자 이름과 책 이름 사이의 관계가 될 것입니다.
예
다음 예제에서는 위의 다이어그램에 표시된 것과 같이 NER (Named-entity relation)까지 사용한 것과 동일한 IE 파이프 라인을 사용하고 NER 태그를 기반으로하는 관계 패턴으로 확장합니다.
import nltk
import re
IN = re.compile(r'.*\bin\b(?!\b.+ing)')
for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
for rel in nltk.sem.extract_rels('ORG', 'LOC', doc, corpus = 'ieer',
pattern = IN):
print(nltk.sem.rtuple(rel))
산출
[ORG: 'WHYY'] 'in' [LOC: 'Philadelphia']
[ORG: 'McGlashan & Sarrail'] 'firm in' [LOC: 'San Mateo']
[ORG: 'Freedom Forum'] 'in' [LOC: 'Arlington']
[ORG: 'Brookings Institution'] ', the research group in' [LOC: 'Washington']
[ORG: 'Idealab'] ', a self-described business incubator based in' [LOC: 'Los Angeles']
[ORG: 'Open Text'] ', based in' [LOC: 'Waterloo']
[ORG: 'WGBH'] 'in' [LOC: 'Boston']
[ORG: 'Bastille Opera'] 'in' [LOC: 'Paris']
[ORG: 'Omnicom'] 'in' [LOC: 'New York']
[ORG: 'DDB Needham'] 'in' [LOC: 'New York']
[ORG: 'Kaplan Thaler Group'] 'in' [LOC: 'New York']
[ORG: 'BBDO South'] 'in' [LOC: 'Atlanta']
[ORG: 'Georgia-Pacific'] 'in' [LOC: 'Atlanta']
위의 코드에서 우리는 ieer라는 이름의 붙박이 말뭉치를 사용했습니다. 이 말뭉치에서 문장은 NER (Named-entity relation)까지 태그가 지정됩니다. 여기서는 우리가 원하는 관계 패턴과 관계가 정의 할 NER의 종류 만 지정하면됩니다. 이 예에서는 조직과 위치 간의 관계를 정의했습니다. 이러한 패턴의 모든 조합을 추출했습니다.
청크를 변환하는 이유는 무엇입니까?
지금까지 우리는 문장에서 청크 나 구를 얻었지만 그것들로 무엇을해야 하는가. 중요한 작업 중 하나는이를 변환하는 것입니다. 그런데 왜? 다음을 수행하는 것입니다-
- 문법 교정 및
- 문구 재정렬
중요하지 않거나 쓸모없는 단어 필터링
구의 의미를 판단하고 싶다면 'the', 'a'와 같이 일반적으로 사용되는 단어가 중요하지 않거나 쓸모가 없다고 가정 해보십시오. 예를 들어, 다음 문구를 참조하십시오-
'영화 좋았다'.
여기서 가장 중요한 단어는 '영화'와 '좋은'입니다. 다른 말로, 'the'와 'was'는 둘 다 쓸모 없거나 중요하지 않습니다. 그것들 없이도 우리는 문구의 동일한 의미를 얻을 수 있기 때문입니다. '좋은 영화'.
다음 파이썬 레시피에서는 쓸모 없거나 중요하지 않은 단어를 제거하고 POS 태그를 사용하여 중요한 단어를 유지하는 방법을 배웁니다.
예
먼저 treebank불용어를위한 말뭉치 우리는 어떤 품사 태그가 중요하고 어떤 태그가 중요하지 않은지 결정해야합니다. 중요하지 않은 단어와 태그의 다음 표를 보겠습니다.
워드 | 꼬리표 |
---|---|
ㅏ | DT |
모두 | PDT |
안 | DT |
과 | CC |
또는 | CC |
그 | WDT |
그만큼 | DT |
위의 표에서 CC 이외의 다른 모든 태그는 DT로 끝나는 것을 볼 수 있습니다. 즉, 태그의 접미사를보고 중요하지 않은 단어를 필터링 할 수 있습니다.
이 예에서는 다음과 같은 이름의 함수를 사용합니다. filter()단일 청크를 취하고 중요하지 않은 태그가 붙은 단어없이 새 청크를 반환합니다. 이 함수는 DT 또는 CC로 끝나는 모든 태그를 필터링합니다.
예
import nltk
def filter(chunk, tag_suffixes=['DT', 'CC']):
significant = []
for word, tag in chunk:
ok = True
for suffix in tag_suffixes:
if tag.endswith(suffix):
ok = False
break
if ok:
significant.append((word, tag))
return (significant)
이제 Python 레시피에서이 함수 filter ()를 사용하여 중요하지 않은 단어를 삭제 해 보겠습니다.
from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])
산출
[('good', 'JJ'), ('movie', 'NN')]
동사 교정
많은 경우 실제 언어에서는 잘못된 동사 형태를 볼 수 있습니다. 예를 들어 '괜찮 으세요?' 정확하지 않습니다. 이 문장에서 동사 형태가 올바르지 않습니다. 문장은 '괜찮 으세요?'여야합니다. NLTK는 동사 수정 매핑을 생성하여 이러한 실수를 수정하는 방법을 제공합니다. 이러한 수정 매핑은 청크에 복수 또는 단수 명사가 있는지 여부에 따라 사용됩니다.
예
Python 레시피를 구현하려면 먼저 동사 수정 매핑을 정의해야합니다. 다음과 같이 두 개의 매핑을 생성 해 보겠습니다.
Plural to Singular mappings
plural= {
('is', 'VBZ'): ('are', 'VBP'),
('was', 'VBD'): ('were', 'VBD')
}
Singular to Plural mappings
singular = {
('are', 'VBP'): ('is', 'VBZ'),
('were', 'VBD'): ('was', 'VBD')
}
위에서 볼 수 있듯이 각 매핑에는 태그가 지정된 다른 동사에 매핑되는 태그가 지정된 동사가 있습니다. 이 예의 초기 매핑은 매핑의 기본을 다룹니다.is to are, was to were, 그 반대.
다음으로, 우리는 verbs(), 부정확 한 동사 형태로 chink를 전달할 수 있으며 수정 된 덩어리를 다시 얻을 수 있습니다. 완료하려면verb() 함수는 다음과 같은 도우미 함수를 사용합니다. index_chunk() 첫 번째 태그가 지정된 단어의 위치를 청크에서 검색합니다.
이러한 기능을 살펴 보겠습니다.
def index_chunk(chunk, pred, start = 0, step = 1):
l = len(chunk)
end = l if step > 0 else -1
for i in range(start, end, step):
if pred(chunk[i]):
return i
return None
def tag_startswith(prefix):
def f(wt):
return wt[1].startswith(prefix)
return f
def verbs(chunk):
vbidx = index_chunk(chunk, tag_startswith('VB'))
if vbidx is None:
return chunk
verb, vbtag = chunk[vbidx]
nnpred = tag_startswith('NN')
nnidx = index_chunk(chunk, nnpred, start = vbidx+1)
if nnidx is None:
nnidx = index_chunk(chunk, nnpred, start = vbidx-1, step = -1)
if nnidx is None:
return chunk
noun, nntag = chunk[nnidx]
if nntag.endswith('S'):
chunk[vbidx] = plural.get((verb, vbtag), (verb, vbtag))
else:
chunk[vbidx] = singular.get((verb, vbtag), (verb, vbtag))
return chunk
이러한 함수를 Python 또는 Anaconda가 설치된 로컬 디렉터리의 Python 파일에 저장하고 실행합니다. 나는 그것을 저장했다verbcorrect.py.
자, 전화합시다 verbs() 태그 된 POS의 기능 is you fine 청크-
from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])
산출
[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]
문구에서 수동태 제거
또 다른 유용한 작업은 구에서 수동태를 제거하는 것입니다. 이것은 동사 주위의 단어를 바꾸는 도움으로 할 수 있습니다. 예를 들면‘the tutorial was great’ 변형 될 수 있습니다 ‘the great tutorial’.
예
이를 달성하기 위해 우리는 eliminate_passive()동사를 피벗 포인트로 사용하여 청크의 오른쪽과 왼쪽을 바꿉니다. 피벗 할 동사를 찾기 위해index_chunk() 위에 정의 된 함수.
def eliminate_passive(chunk):
def vbpred(wt):
word, tag = wt
return tag != 'VBG' and tag.startswith('VB') and len(tag) > 2
vbidx = index_chunk(chunk, vbpred)
if vbidx is None:
return chunk
return chunk[vbidx+1:] + chunk[:vbidx]
자, 전화합시다 eliminate_passive() 태그 된 POS의 기능 the tutorial was great 청크-
from passiveverb import eliminate_passive
eliminate_passive(
[
('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
]
)
산출
[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]
명사 추기경 바꾸기
아시다시피 5와 같은 기본 단어는 청크에서 CD로 태그가 지정됩니다. 이러한 기본 단어는 종종 명사 앞이나 뒤에 발생하지만 정규화를 위해 항상 명사 앞에 두는 것이 유용합니다. 예를 들어, 날짜January 5 다음과 같이 쓸 수 있습니다. 5 January. 다음 예를 통해 이해합시다.
예
이를 달성하기 위해 우리는 swapping_cardinals()명사 바로 뒤에 나오는 추기경을 명사와 바꿉니다. 이것으로 추기경은 명사 바로 앞에 나타납니다. 주어진 태그와 동등 비교를하기 위해 우리가 이름을 지은 도우미 함수를 사용합니다.tag_eql().
def tag_eql(tag):
def f(wt):
return wt[1] == tag
return f
이제 swapping_cardinals ()를 정의 할 수 있습니다.
def swapping_cardinals (chunk):
cdidx = index_chunk(chunk, tag_eql('CD'))
if not cdidx or not chunk[cdidx-1][1].startswith('NN'):
return chunk
noun, nntag = chunk[cdidx-1]
chunk[cdidx-1] = chunk[cdidx]
chunk[cdidx] = noun, nntag
return chunk
자, 전화합시다 swapping_cardinals() 데이트 기능 “January 5” −
from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])
산출
[('10', 'CD'), ('January', 'NNP')]
10 January
다음은 나무를 변형하는 두 가지 이유입니다.
- 깊은 구문 분석 트리를 수정하려면
- 깊은 구문 분석 트리를 평평하게하려면
트리 또는 하위 트리를 문장으로 변환
여기서 논의 할 첫 번째 방법은 트리 또는 하위 트리를 다시 문장 또는 청크 문자열로 변환하는 것입니다. 이것은 매우 간단합니다. 다음 예를 살펴 보겠습니다.
예
from nltk.corpus import treebank_chunk
tree = treebank_chunk.chunked_sents()[2]
' '.join([w for w, t in tree.leaves()])
산출
'Rudolph Agnew , 55 years old and former chairman of Consolidated Gold Fields
PLC , was named a nonexecutive director of this British industrial
conglomerate .'
깊은 나무 평 평화
중첩 된 구문의 깊은 트리는 청크를 훈련하는 데 사용할 수 없으므로 사용하기 전에 평평하게해야합니다. 다음 예제에서는 중첩 된 구문의 깊은 트리 인 세 번째 구문 분석 된 문장을 사용합니다.treebank 신체.
예
이를 위해 다음과 같은 함수를 정의합니다. deeptree_flat()하나의 트리를 가져오고 가장 낮은 수준의 트리 만 유지하는 새 트리를 반환합니다. 대부분의 작업을 수행하기 위해 우리가 명명 한 도우미 함수를 사용합니다.childtree_flat().
from nltk.tree import Tree
def childtree_flat(trees):
children = []
for t in trees:
if t.height() < 3:
children.extend(t.pos())
elif t.height() == 3:
children.append(Tree(t.label(), t.pos()))
else:
children.extend(flatten_childtrees([c for c in t]))
return children
def deeptree_flat(tree):
return Tree(tree.label(), flatten_childtrees([c for c in tree]))
자, 전화합시다 deeptree_flat() 중첩 된 구문의 깊은 트리 인 세 번째 구문 분석 된 문장에서 treebank신체. 이러한 함수를 deeptree.py라는 파일에 저장했습니다.
from deeptree import deeptree_flat
from nltk.corpus import treebank
deeptree_flat(treebank.parsed_sents()[2])
산출
Tree('S', [Tree('NP', [('Rudolph', 'NNP'), ('Agnew', 'NNP')]),
(',', ','), Tree('NP', [('55', 'CD'),
('years', 'NNS')]), ('old', 'JJ'), ('and', 'CC'),
Tree('NP', [('former', 'JJ'),
('chairman', 'NN')]), ('of', 'IN'), Tree('NP', [('Consolidated', 'NNP'),
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC',
'NNP')]), (',', ','), ('was', 'VBD'),
('named', 'VBN'), Tree('NP-SBJ', [('*-1', '-NONE-')]),
Tree('NP', [('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN')]),
('of', 'IN'), Tree('NP',
[('this', 'DT'), ('British', 'JJ'),
('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])
얕은 나무 건물
이전 섹션에서는 가장 낮은 수준의 하위 트리 만 유지하여 중첩 된 구문의 깊은 트리를 평면화했습니다. 이 섹션에서는 얕은 트리를 구축하기 위해 가장 높은 수준의 하위 트리 만 유지합니다. 다음 예에서는 중첩 된 구문의 깊은 트리 인 세 번째 구문 분석 된 문장을 사용할 것입니다.treebank 신체.
예
이를 위해 다음과 같은 함수를 정의합니다. tree_shallow() 상위 하위 트리 레이블 만 유지하여 중첩 된 하위 트리를 모두 제거합니다.
from nltk.tree import Tree
def tree_shallow(tree):
children = []
for t in tree:
if t.height() < 3:
children.extend(t.pos())
else:
children.append(Tree(t.label(), t.pos()))
return Tree(tree.label(), children)
자, 전화합시다 tree_shallow()내포 된 구문의 깊은 트리 인 세 번째 구문 분석 된 문장 에 대한 함수treebank신체. 이러한 함수를 shallowtree.py라는 파일에 저장했습니다.
from shallowtree import shallow_tree
from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2])
산출
Tree('S', [Tree('NP-SBJ-1', [('Rudolph', 'NNP'), ('Agnew', 'NNP'), (',', ','),
('55', 'CD'), ('years', 'NNS'), ('old', 'JJ'), ('and', 'CC'),
('former', 'JJ'), ('chairman', 'NN'), ('of', 'IN'), ('Consolidated', 'NNP'),
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 'NNP'), (',', ',')]),
Tree('VP', [('was', 'VBD'), ('named', 'VBN'), ('*-1', '-NONE-'), ('a', 'DT'),
('nonexecutive', 'JJ'), ('director', 'NN'), ('of', 'IN'), ('this', 'DT'),
('British', 'JJ'), ('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])
우리는 나무의 높이를 구하여 차이를 볼 수 있습니다.
from nltk.corpus import treebank
tree_shallow(treebank.parsed_sents()[2]).height()
산출
3
from nltk.corpus import treebank
treebank.parsed_sents()[2].height()
산출
9
트리 레이블 변환
구문 분석 트리에는 다양한 Tree청크 트리에없는 레이블 유형. 그러나 파스 트리를 사용하여 청커를 훈련하는 동안 일부 트리 레이블을 더 일반적인 레이블 유형으로 변환하여 이러한 다양성을 줄이고 싶습니다. 예를 들어, NP-SBL 및 NP-TMP라는 두 개의 대체 NP 하위 트리가 있습니다. 둘 다 NP로 변환 할 수 있습니다. 다음 예제에서 방법을 살펴 보겠습니다.
예
이를 달성하기 위해 우리는 tree_convert() 그것은 다음 두 가지 인수를 취합니다-
- 변환 할 트리
- 레이블 변환 매핑
이 함수는 매핑의 값을 기반으로 모든 일치 레이블이 교체 된 새 트리를 반환합니다.
from nltk.tree import Tree
def tree_convert(tree, mapping):
children = []
for t in tree:
if isinstance(t, Tree):
children.append(convert_tree_labels(t, mapping))
else:
children.append(t)
label = mapping.get(tree.label(), tree.label())
return Tree(label, children)
자, 전화합시다 tree_convert() 중첩 된 구문의 깊은 트리 인 세 번째 구문 분석 된 문장에서 treebank신체. 이러한 함수를converttree.py.
from converttree import tree_convert
from nltk.corpus import treebank
mapping = {'NP-SBJ': 'NP', 'NP-TMP': 'NP'}
convert_tree_labels(treebank.parsed_sents()[2], mapping)
산출
Tree('S', [Tree('NP-SBJ-1', [Tree('NP', [Tree('NNP', ['Rudolph']),
Tree('NNP', ['Agnew'])]), Tree(',', [',']),
Tree('UCP', [Tree('ADJP', [Tree('NP', [Tree('CD', ['55']),
Tree('NNS', ['years'])]),
Tree('JJ', ['old'])]), Tree('CC', ['and']),
Tree('NP', [Tree('NP', [Tree('JJ', ['former']),
Tree('NN', ['chairman'])]), Tree('PP', [Tree('IN', ['of']),
Tree('NP', [Tree('NNP', ['Consolidated']),
Tree('NNP', ['Gold']), Tree('NNP', ['Fields']),
Tree('NNP', ['PLC'])])])])]), Tree(',', [','])]),
Tree('VP', [Tree('VBD', ['was']),Tree('VP', [Tree('VBN', ['named']),
Tree('S', [Tree('NP', [Tree('-NONE-', ['*-1'])]),
Tree('NP-PRD', [Tree('NP', [Tree('DT', ['a']),
Tree('JJ', ['nonexecutive']), Tree('NN', ['director'])]),
Tree('PP', [Tree('IN', ['of']), Tree('NP',
[Tree('DT', ['this']), Tree('JJ', ['British']), Tree('JJ', ['industrial']),
Tree('NN', ['conglomerate'])])])])])])]), Tree('.', ['.'])])
텍스트 분류 란 무엇입니까?
이름에서 알 수 있듯이 텍스트 분류는 텍스트 또는 문서의 일부를 분류하는 방법입니다. 그러나 여기서 우리가 텍스트 분류기를 사용해야하는 이유에 대한 질문이 생깁니다. 문서 나 텍스트에서 사용되는 단어를 살펴보면 분류자는 어떤 클래스 레이블을 할당할지 결정할 수 있습니다.
이진 분류기
이름에서 알 수 있듯이 이진 분류기는 두 레이블 사이에서 결정합니다. 예를 들어, 긍정 또는 부정. 여기에서 텍스트 또는 문서는 하나의 레이블 또는 다른 레이블 일 수 있지만 둘 다일 수는 없습니다.
다중 레이블 분류기
이진 분류 기와는 반대로 다중 레이블 분류기는 텍스트 또는 문서에 하나 이상의 레이블을 할당 할 수 있습니다.
레이블이있는 대 레이블이없는 기능 세트
기능 이름과 기능 값의 키-값 매핑을 기능 세트라고합니다. 레이블이 지정된 기능 세트 또는 학습 데이터는 나중에 레이블이 지정되지 않은 기능 세트를 분류 할 수 있도록 분류 학습에 매우 중요합니다.
레이블이있는 기능 세트 | 레이블이없는 기능 세트 |
---|---|
(feat, 레이블)처럼 보이는 튜플입니다. | 그것은 그 자체로 위업입니다. |
알려진 클래스 레이블이있는 인스턴스입니다. | 연결된 레이블이 없으면 인스턴스라고 부를 수 있습니다. |
분류 알고리즘 훈련에 사용됩니다. | 일단 학습되면 분류 알고리즘은 레이블이없는 기능 세트를 분류 할 수 있습니다. |
텍스트 특징 추출
이름에서 알 수 있듯이 텍스트 특징 추출은 단어 목록을 분류자가 사용할 수있는 기능 집합으로 변환하는 프로세스입니다. 우리는 텍스트를‘dict’ NLTK (Natural Language Tool Kit)가 예상하기 때문에 스타일 기능 세트 ‘dict’ 스타일 기능 세트.
Bag of Words (BoW) 모델
NLP에서 가장 간단한 모델 중 하나 인 BoW는 텍스트 또는 문서에서 특징을 추출하는 데 사용되므로 ML 알고리즘과 같은 모델링에 사용할 수 있습니다. 기본적으로 인스턴스의 모든 단어에서 단어 존재 기능 집합을 구성합니다. 이 방법의 개념은 단어가 몇 번이나 나오는지 또는 단어의 순서에 대해서는 신경 쓰지 않고 단어 목록에 단어가 있는지 여부 만 신경 쓰는 것입니다.
예
이 예에서는 bow ()라는 함수를 정의합니다.
def bow(words):
return dict([(word, True) for word in words])
자, 전화합시다 bow()단어에 대한 기능. 이 함수를 bagwords.py라는 파일에 저장했습니다.
from bagwords import bow
bow(['we', 'are', 'using', 'tutorialspoint'])
산출
{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}
훈련 분류기
이전 섹션에서는 텍스트에서 기능을 추출하는 방법을 배웠습니다. 이제 분류기를 훈련 할 수 있습니다. 첫 번째이자 가장 쉬운 분류기는NaiveBayesClassifier 수업.
나이브 베이 즈 분류기
주어진 기능 세트가 특정 레이블에 속할 확률을 예측하기 위해 Bayes 정리를 사용합니다. 베이 즈 정리의 공식은 다음과 같습니다.
$$P(A|B)=\frac{P(B|A)P(A)}{P(B)}$$여기,
P(A|B) − 사후 확률이라고도합니다. 즉, 두 번째 이벤트 즉 B가 발생한 경우 첫 번째 이벤트 즉 A가 발생할 확률입니다.
P(B|A) − 첫 번째 이벤트, 즉 A가 발생한 후 두 번째 이벤트 즉 B가 발생할 확률입니다.
P(A), P(B) − 사전 확률, 즉 첫 번째 사건 즉 A 또는 두 번째 사건 즉 B가 발생할 확률이라고도합니다.
Naïve Bayes 분류기를 훈련하기 위해 movie_reviewsNLTK의 말뭉치. 이 말뭉치에는 두 가지 범주의 텍스트가 있습니다.pos 과 neg. 이러한 범주는 훈련 된 분류기를 이진 분류기로 만듭니다. 말뭉치의 모든 파일은 두 가지로 구성되며, 하나는 긍정적 인 영화 리뷰이고 다른 하나는 부정적인 영화 리뷰입니다. 이 예에서는 분류기를 학습하고 테스트하기 위해 각 파일을 단일 인스턴스로 사용합니다.
예
훈련 분류기의 경우 레이블이 지정된 기능 세트 목록이 필요합니다.이 목록은 [(featureset, label)]. 여기featureset 변수는 dict label은 알려진 클래스 레이블입니다. featureset. 이름이 지정된 함수를 만들 것입니다.label_corpus() 이것은 movie_reviews또한 이름이 지정된 함수 feature_detector, 기본값은 bag of words. {label : [featureset]} 형식의 매핑을 구성하고 반환합니다. 그런 다음이 매핑을 사용하여 레이블이 지정된 학습 인스턴스 및 테스트 인스턴스 목록을 만듭니다.
import collections
def label_corpus(corp, feature_detector=bow):
label_feats = collections.defaultdict(list)
for label in corp.categories():
for fileid in corp.fileids(categories=[label]):
feats = feature_detector(corp.words(fileids=[fileid]))
label_feats[label].append(feats)
return label_feats
위 기능의 도움으로 우리는 매핑을 얻을 것입니다 {label:fetaureset}. 이제 우리는split 에서 반환 된 매핑을 가져옵니다. label_corpus() 각 기능 세트 목록을 레이블이 지정된 학습 및 테스트 인스턴스로 분할합니다.
def split(lfeats, split=0.75):
train_feats = []
test_feats = []
for label, feats in lfeats.items():
cutoff = int(len(feats) * split)
train_feats.extend([(feat, label) for feat in feats[:cutoff]])
test_feats.extend([(feat, label) for feat in feats[cutoff:]])
return train_feats, test_feats
이제 우리 말뭉치, 즉 movie_reviews에서 이러한 함수를 사용하겠습니다.
from nltk.corpus import movie_reviews
from featx import label_feats_from_corpus, split_label_feats
movie_reviews.categories()
산출
['neg', 'pos']
예
lfeats = label_feats_from_corpus(movie_reviews)
lfeats.keys()
산출
dict_keys(['neg', 'pos'])
예
train_feats, test_feats = split_label_feats(lfeats, split = 0.75)
len(train_feats)
산출
1500
예
len(test_feats)
산출
500
우리는 movie_reviews코퍼스, 1000 개의 pos 파일과 1000 개의 neg 파일이 있습니다. 또한 1500 개의 레이블이 지정된 학습 인스턴스와 500 개의 레이블이 지정된 테스트 인스턴스로 끝납니다.
이제 훈련합시다 NaïveBayesClassifier 그것의 사용 train() 클래스 방법-
from nltk.classify import NaiveBayesClassifier
NBC = NaiveBayesClassifier.train(train_feats)
NBC.labels()
산출
['neg', 'pos']
의사 결정 트리 분류기
또 다른 중요한 분류기는 의사 결정 트리 분류기입니다. 그것을 훈련하기 위해 여기에DecisionTreeClassifier클래스는 트리 구조를 생성합니다. 이 트리 구조에서 각 노드는 기능 이름에 해당하고 분기는 기능 값에 해당합니다. 그리고 가지 아래로 우리는 나무의 잎, 즉 분류 라벨에 도달 할 것입니다.
의사 결정 트리 분류기를 훈련하기 위해 동일한 훈련 및 테스트 기능을 사용합니다. train_feats 과 test_feats, 우리가 만든 변수 movie_reviews 신체.
예
이 분류기를 훈련하기 위해 우리는 DecisionTreeClassifier.train() 다음과 같이 클래스 방법-
from nltk.classify import DecisionTreeClassifier
decisiont_classifier = DecisionTreeClassifier.train(
train_feats, binary = True, entropy_cutoff = 0.8,
depth_cutoff = 5, support_cutoff = 30
)
accuracy(decisiont_classifier, test_feats)
산출
0.725
최대 엔트로피 분류기
또 다른 중요한 분류 기준은 MaxentClassifier 일컬어 conditional exponential classifier 또는 logistic regression classifier. 여기에서 그것을 훈련시키기 위해MaxentClassifier 클래스는 인코딩을 사용하여 레이블이 지정된 기능 세트를 벡터로 변환합니다.
의사 결정 트리 분류기를 훈련하기 위해 동일한 훈련 및 테스트 기능을 사용합니다. train_feats과 test_feats, 우리가 만든 변수 movie_reviews 신체.
예
이 분류기를 훈련하기 위해 우리는 MaxentClassifier.train() 다음과 같이 클래스 방법-
from nltk.classify import MaxentClassifier
maxent_classifier = MaxentClassifier
.train(train_feats,algorithm = 'gis', trace = 0, max_iter = 10, min_lldelta = 0.5)
accuracy(maxent_classifier, test_feats)
산출
0.786
Scikit-learn 분류기
최고의 기계 학습 (ML) 라이브러리 중 하나는 Scikit-learn입니다. 실제로 다양한 목적을위한 모든 종류의 ML 알고리즘이 포함되어 있지만 모두 다음과 같이 동일한 맞춤 설계 패턴을 가지고 있습니다.
- 모델을 데이터에 맞추기
- 그리고 그 모델을 사용하여 예측을
scikit-learn 모델에 직접 액세스하는 대신 여기서는 NLTK를 사용합니다. SklearnClassifier수업. 이 클래스는 scikit-learn 모델을 둘러싼 래퍼 클래스로 NLTK의 분류 자 인터페이스를 준수합니다.
우리는 다음 단계를 따라 SklearnClassifier 클래스-
Step 1 − 먼저 이전 레시피에서했던 것처럼 훈련 기능을 생성합니다.
Step 2 − 이제 Scikit-learn 알고리즘을 선택하고 가져옵니다.
Step 3 − 다음으로, 우리는 SklearnClassifier 선택한 알고리즘으로 클래스.
Step 4 − 마지막으로 우리는 SklearnClassifier 교육 기능으로 수업.
아래 Python 레시피에서 이러한 단계를 구현해 보겠습니다.
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
sklearn_classifier = SklearnClassifier(MultinomialNB())
sklearn_classifier.train(train_feats)
<SklearnClassifier(MultinomialNB(alpha = 1.0,class_prior = None,fit_prior = True))>
accuracy(sk_classifier, test_feats)
산출
0.885
정밀도 및 리콜 측정
다양한 분류기를 훈련하는 동안 우리는 그 정확성도 측정했습니다. 그러나 정확도와는 별도로 분류자를 평가하는 데 사용되는 다른 메트릭이 많이 있습니다. 이러한 측정 항목 중 두 가지는precision 과 recall.
예
이 예에서는 이전에 학습 한 NaiveBayesClassifier 클래스의 정밀도와 재현율을 계산할 것입니다. 이를 달성하기 위해 우리는 두 개의 인수를받는 metrics_PR ()이라는 함수를 만들 것입니다. 하나는 훈련 된 분류 자이고 다른 하나는 레이블이 지정된 테스트 기능입니다. 두 인수 모두 분류 자의 정확도를 계산하는 동안 전달한 것과 동일합니다.
import collections
from nltk import metrics
def metrics_PR(classifier, testfeats):
refsets = collections.defaultdict(set)
testsets = collections.defaultdict(set)
for i, (feats, label) in enumerate(testfeats):
refsets[label].add(i)
observed = classifier.classify(feats)
testsets[observed].add(i)
precisions = {}
recalls = {}
for label in classifier.labels():
precisions[label] = metrics.precision(refsets[label],testsets[label])
recalls[label] = metrics.recall(refsets[label], testsets[label])
return precisions, recalls
Let us call this function to find the precision and recall −
from metrics_classification import metrics_PR
nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats)
nb_precisions['pos']
Output
0.6713532466435213
Example
nb_precisions['neg']
Output
0.9676271186440678
Example
nb_recalls['pos']
Output
0.96
Example
nb_recalls['neg']
Output
0.478
Combination of classifier and voting
Combining classifiers is one of the best ways to improve classification performance. And voting is one of the best ways to combine multiple classifiers. For voting we need to have odd number of classifiers. In the following Python recipe we are going to combine three classifiers namely NaiveBayesClassifier class, DecisionTreeClassifier class and MaxentClassifier class.
To achieve this we are going to define a function named voting_classifiers() as follows.
import itertools
from nltk.classify import ClassifierI
from nltk.probability import FreqDist
class Voting_classifiers(ClassifierI):
def __init__(self, *classifiers):
self._classifiers = classifiers
self._labels = sorted(set(itertools.chain(*[c.labels() for c in classifiers])))
def labels(self):
return self._labels
def classify(self, feats):
counts = FreqDist()
for classifier in self._classifiers:
counts[classifier.classify(feats)] += 1
return counts.max()
Let us call this function to combine three classifiers and find the accuracy −
from vote_classification import Voting_classifiers
combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier)
combined_classifier.labels()
Output
['neg', 'pos']
Example
accuracy(combined_classifier, test_feats)
Output
0.948
From the above output, we can see that the combined classifiers got highest accuracy than the individual classifiers.