갈루아의 반서재

 

본 포스팅에서는 최근 각광을 받고 있는 spaCy 패키지를 사용하여 NLP 의 기본내용을 코드 실행을 통해 살펴본다. spaCy 는  Explosion AI Matt Honnibal 에 의해 개발된 것으로 “Industrial strength NLP in Python” 을 모토로 삼고 있다. 생산환경에서 주로 사용되며, 사용자 친화성과 객체 기반 접근방식을 통해 문자열이나 배열 대신 객체를 결과값으로 반환한다. 

NLTK 보다 나은 점

  • Cython 로 작성되어 엄청 빠른 속도를 선보인다
  • 의존 구문 분석 
  • 커스토마이징이 손쉬운 대규모의 워드 벡터 접근 가능
  • 통합된 워드 벡터 
  • GPU 가속 지원
  • 사용자 정의 딥러닝 네트워크 지원
  • 하지만, NTNL 에 비해 매우 느린 문장 토큰화 속도

 

Prerequisites

다음과 같이 pip 또는 conda 를 이용하여 spacy 를 설치한다. 

(AnnaM) founder@hilbert:~/annam$ conda install -c conda-forge spacy
Collecting package metadata: done
Solving environment: done

## Package Plan ##

  environment location: /home/founder/anaconda3/envs/AnnaM

  added / updated specs:
    - spacy


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    ca-certificates-2019.11.28 |       hecc5488_0         145 KB  conda-forge
    catalogue-0.0.8            |             py_0          10 KB  conda-forge
    certifi-2019.11.28         |           py37_0         148 KB  conda-forge
    cymem-2.0.3                |   py37he1b5a44_0          41 KB  conda-forge
    cython-blis-0.4.1          |   py37h516909a_0         4.3 MB  conda-forge
    importlib_metadata-1.2.0   |           py37_0          40 KB  conda-forge
    more-itertools-8.0.0       |             py_0          33 KB  conda-forge
    murmurhash-1.0.0           |   py37he1b5a44_0          16 KB  conda-forge
    openssl-1.1.1d             |       h516909a_0         2.1 MB  conda-forge
    plac-0.9.6                 |             py_1          18 KB  conda-forge
    preshed-3.0.2              |   py37he1b5a44_1         121 KB  conda-forge
    spacy-2.2.3                |   py37hc9558a2_0         9.1 MB  conda-forge
    srsly-0.2.0                |   py37he1b5a44_0         212 KB  conda-forge
    thinc-7.3.0                |   py37hc9558a2_0         1.7 MB  conda-forge
    wasabi-0.4.0               |             py_0          19 KB  conda-forge
    ------------------------------------------------------------
                                           Total:        17.9 MB

The following NEW packages will be INSTALLED:

  catalogue          conda-forge/noarch::catalogue-0.0.8-py_0
  cymem              conda-forge/linux-64::cymem-2.0.3-py37he1b5a44_0
  cython-blis        conda-forge/linux-64::cython-blis-0.4.1-py37h516909a_0
  importlib_metadata conda-forge/linux-64::importlib_metadata-1.2.0-py37_0
  more-itertools     conda-forge/noarch::more-itertools-8.0.0-py_0
  murmurhash         conda-forge/linux-64::murmurhash-1.0.0-py37he1b5a44_0
  plac               conda-forge/noarch::plac-0.9.6-py_1
  preshed            conda-forge/linux-64::preshed-3.0.2-py37he1b5a44_1
  spacy              conda-forge/linux-64::spacy-2.2.3-py37hc9558a2_0
  srsly              conda-forge/linux-64::srsly-0.2.0-py37he1b5a44_0
  thinc              conda-forge/linux-64::thinc-7.3.0-py37hc9558a2_0
  wasabi             conda-forge/noarch::wasabi-0.4.0-py_0
  zipp               conda-forge/noarch::zipp-0.6.0-py_0

The following packages will be UPDATED:

  ca-certificates    anaconda::ca-certificates-2019.11.27-0 --> conda-forge::ca-certificates-2019.11.28-hecc5488_0

The following packages will be SUPERSEDED by a higher-priority channel:

  certifi                                          anaconda --> conda-forge
  openssl                anaconda::openssl-1.1.1-h7b6447c_0 --> conda-forge::openssl-1.1.1d-h516909a_0


Proceed ([y]/n)? y


Downloading and Extracting Packages
spacy-2.2.3          | 9.1 MB    | ##################################### | 100%
srsly-0.2.0          | 212 KB    | ##################################### | 100%
preshed-3.0.2        | 121 KB    | ##################################### | 100%
thinc-7.3.0          | 1.7 MB    | ##################################### | 100%
plac-0.9.6           | 18 KB     | ##################################### | 100%
certifi-2019.11.28   | 148 KB    | ##################################### | 100%
cython-blis-0.4.1    | 4.3 MB    | ##################################### | 100%
catalogue-0.0.8      | 10 KB     | ##################################### | 100%
importlib_metadata-1 | 40 KB     | ##################################### | 100%
ca-certificates-2019 | 145 KB    | ##################################### | 100%
cymem-2.0.3          | 41 KB     | ##################################### | 100%
openssl-1.1.1d       | 2.1 MB    | ##################################### | 100%
wasabi-0.4.0         | 19 KB     | ##################################### | 100%
murmurhash-1.0.0     | 16 KB     | ##################################### | 100%
more-itertools-8.0.0 | 33 KB     | ##################################### | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
(AnnaM) founder@hilbert:~/annam$
(AnnaM) founder@hilbert:~/annam$
(AnnaM) founder@hilbert:~/annam$
(AnnaM) founder@hilbert:~/annam$
(AnnaM) founder@hilbert:~/annam$
(AnnaM) founder@hilbert:~/annam$

spaCy 라이브러리에는 포함되어 있지 않으므로 별도로 모델을 설치해야한다. 아래와 같이 영어 모델이 크기에 따라 3종류가 있으므로, 골라서 설치한다. 실습을 위해서는 small 이나 medium 모두 가능하다.

  • en_web_core_sm => Small (11MB)
  • en_web_core_md => Medium (91MB)
  • en_web_core_lg => Large (789MB)
(AnnaM) founder@hilbert:~/annam/clear-the-fundamentals-of-nlp-with-code$ python -m spacy download en_core_web_md
Collecting en_core_web_md==2.2.5 from https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.2.5/en_core_web_md-2.2.5.tar.gz#   egg=en_core_web_md==2.2.5
  Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_md-2.2.5/en_core_web_md-2.2.5.tar.gz (96.4MB)
     |████████████████████████████████| 96.4MB 724kB/s
Requirement already satisfied: spacy>=2.2.2 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from en_core_web_md==2.2.5) (2.2.3)
Requirement already satisfied: thinc<7.4.0,>=7.3.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_we   b_md==2.2.5) (7.3.0)
Requirement already satisfied: wasabi<1.1.0,>=0.4.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_w   eb_md==2.2.5) (0.4.0)
Requirement already satisfied: srsly<1.1.0,>=0.1.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_we   b_md==2.2.5) (0.2.0)
Requirement already satisfied: blis<0.5.0,>=0.4.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_web   _md==2.2.5) (0.4.1)
Requirement already satisfied: murmurhash<1.1.0,>=0.28.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_c   ore_web_md==2.2.5) (1.0.0)
Requirement already satisfied: cymem<2.1.0,>=2.0.2 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_we   b_md==2.2.5) (2.0.3)
Requirement already satisfied: setuptools in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_web_md==2.2   .5) (41.4.0)
Requirement already satisfied: catalogue<1.1.0,>=0.0.7 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_cor   e_web_md==2.2.5) (0.0.8)
Requirement already satisfied: preshed<3.1.0,>=3.0.2 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_   web_md==2.2.5) (3.0.2)
Requirement already satisfied: numpy>=1.15.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_web_md==   2.2.5) (1.16.5)
Requirement already satisfied: requests<3.0.0,>=2.13.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_cor   e_web_md==2.2.5) (2.22.0)
Requirement already satisfied: plac<1.2.0,>=0.9.6 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from spacy>=2.2.2->en_core_web   _md==2.2.5) (0.9.6)
Requirement already satisfied: tqdm<5.0.0,>=4.10.0 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from thinc<7.4.0,>=7.3.0->spa   cy>=2.2.2->en_core_web_md==2.2.5) (4.36.1)
Requirement already satisfied: importlib-metadata>=0.20; python_version < "3.8" in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (   from catalogue<1.1.0,>=0.0.7->spacy>=2.2.2->en_core_web_md==2.2.5) (1.2.0)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from requests<3.0.0,>=2.13.   0->spacy>=2.2.2->en_core_web_md==2.2.5) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from requests<3.0.0,>=2.13.0->   spacy>=2.2.2->en_core_web_md==2.2.5) (2019.11.28)
Requirement already satisfied: idna<2.9,>=2.5 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from requests<3.0.0,>=2.13.0->spac   y>=2.2.2->en_core_web_md==2.2.5) (2.8)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from requ   ests<3.0.0,>=2.13.0->spacy>=2.2.2->en_core_web_md==2.2.5) (1.25.6)
Requirement already satisfied: zipp>=0.5 in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from importlib-metadata>=0.20; python_v   ersion < "3.8"->catalogue<1.1.0,>=0.0.7->spacy>=2.2.2->en_core_web_md==2.2.5) (0.6.0)
Requirement already satisfied: more-itertools in /home/founder/anaconda3/envs/AnnaM/lib/python3.7/site-packages (from zipp>=0.5->importlib-metadata   >=0.20; python_version < "3.8"->catalogue<1.1.0,>=0.0.7->spacy>=2.2.2->en_core_web_md==2.2.5) (8.0.0)
Building wheels for collected packages: en-core-web-md
  Building wheel for en-core-web-md (setup.py) ... done
  Created wheel for en-core-web-md: filename=en_core_web_md-2.2.5-cp37-none-any.whl size=98051305 sha256=30b179ade6ad729f301bbd8a75d621f0845e3ea785   afecdbbf5dabbf9e75c480
  Stored in directory: /tmp/pip-ephem-wheel-cache-iwh551n6/wheels/df/94/ad/f5cf59224cea6b5686ac4fd1ad19c8a07bc026e13c36502d81
Successfully built en-core-web-md
Installing collected packages: en-core-web-md
Successfully installed en-core-web-md-2.2.5
✔ Download and installation successful
You can now load the model via spacy.load('en_core_web_md')

모델에 관한 더욱 자세한 정보는 아래 링크에서 확인가능하다.

 

English · spaCy Models Documentation

spaCy is a free open-source library for Natural Language Processing in Python. It features NER, POS tagging, dependency parsing, word vectors and more.

spacy.io

 

Data Types: Doc, Span, Tokens

  • Doc object 은 텍스트와 관련된 모든 정보를 담는다. 

Source: spaCy.io

  • doc의 일부를 span objects 라고 부른다. 그리고 그 구성요소를 Token objects 라고 부르고, 이는 주소와 포인트를 포함하고 있으며 포인터처럼 작동한다.

Source: Datacamp.com

 

1. Tokenization

NLP 에서 가장 먼저 진행해야할 단계는 토큰화(tokenize)이다. 텍스트를 단어, 문장부호 등의 토큰으로 분류하는 과정을 말한다. 이 결과는 Doc object 에 저장된다.

# spacy import convention
import spacy

# load the english model into nlp object.
nlp=spacy.load('en_core_web_md')
# Sample text
text="""Success isn't easy, and that's a good thing - at least in business. \
If it was easy, everybody would be doing it and your competition would be outrageous!"""

# returns doc container with many attributes.
doc=nlp(text)
# loop through doc and return tokens with .text attribute
# using list comprehension
tokenized=[token.text for token in doc]
# print result.
print(tokenized)

['Success', 'is', "n't", 'easy', ',', 'and', 'that', "'s", 'a', 'good', 'thing', '-', 'at', 'least', 'in', 'business', '.', 'If', 'it', 'was', 'easy', ',', 'everybody', 'would', 'be', 'doing', 'it', 'and', 'your', 'competition', 'would', 'be', 'outrageous', '!']

 

2. Stop Words

“a, is, on, for, my, also, any, only, now..etc” 와 같은 불용어(Stop words)는 문장의 의미와는 직접적으로 관련이 없으므로, 본격적인 처리에 앞서 버리기로 하자. 

# To know about Default stopwords in english model
# create a object and load stopwords.
spacy_stopwords=spacy.lang.en.stop_words.STOP_WORDS

print(spacy_stopwords)
print("="*60)

print("Total number of stopwords in spacy are {}".format(len(spacy_stopwords)))

{'throughout', '‘s', 'did', 'towards', 'using', 'first', 'always', 'third', 'wherever', 'everything', '’ll', '‘ve', 'himself', 'yourselves', 'they', 'keep', 'else', 'enough', 'not', 'under', 'amongst', '’d', 'ever', 'here', 'whatever', 'whether', 'none', 'whither', 'both', 'out', 'whom', 're', 'due', 'though', 'just', 'became', 'more', 'last', 'hers', '‘m', 'everyone', 'him', 'something', 'why', 'fifty', 'i', 'whereas', "'d", 'is', 'empty', 'until', 'those', 'themselves', 'thereupon', 'several', 'become', 'were', 'per', 'hence', 'very', 'whoever', "'ll", '‘ll', 'then', 'could', 'anyway', 'her', 'unless', 'in', 'down', 'make', 'them', 'somehow', 'at', 'had', 'a', 'anywhere', 'it', 'between', 'someone', 'sixty', 'within', '’m', 'beyond', 'by', 'she', 'along', 'already', 'as', 'behind', 'than', 'twenty', 'what', 'whereafter', 'other', 'anything', 'elsewhere', 'whence', 'get', 'myself', 'against', 'twelve', 'alone', 'since', 'will', 'others', 'made', 'through', 'was', 'perhaps', '’ve', 'you', 'over', 'almost', 'quite', 'ca', 'three', 'thru', 'nothing', 'being', 'everywhere', "n't", 'wherein', 'but', 'rather', 'among', 'namely', 'therein', 'one', 'many', 'be', 'does', 'while', 'go', 'too', 'these', 'thus', 'show', 'still', 'its', 'up', 'their', 'however', 'n’t', 'sometime', 'please', 'an', 'would', 'full', 'via', 'nobody', "'re", 'have', 'same', 'can', 'us', 'anyhow', 'so', 'are', 'who', 'ten', 'may', 'and', 'onto', 'back', 'hereby', 'on', 'below', 'really', 'no', 'moreover', 'hereafter', 'nevertheless', 'next', 'five', 'yours', 'herein', 'hereupon', 'or', 'move', 'whole', 'another', 'noone', 'top', 'doing', 'thereafter', 'eleven', 'often', 'besides', 'serious', 'bottom', 'ourselves', 'even', 'might', "'ve", 'without', 'indeed', 'must', 'around', 'again', 'itself', 'name', 'amount', 'former', 'seems', 'toward', 'two', 'herself', 'that', 'where', 'used', 'how', 'latterly', 'once', 'well', 'meanwhile', 'all', 'say', 'which', 'from', 'when', 'n‘t', 'above', 'because', 'eight', 'during', 'own', 'my', 'never', 'side', 'only', 'further', 'he', 'every', "'m", 'we', 'done', 'for', 'do', 'except', 'nowhere', 'mine', 'nor', 'thence', 'nine', 'has', 'front', 'forty', 'of', 'four', 'off', 'few', 'hundred', '‘re', 'otherwise', 'becomes', 'each', 'call', 'thereby', 'the', 'beside', 'most', '’s', 'although', 'there', 'fifteen', 'after', 'to', 'across', 'various', 'afterwards', 'if', 'also', 'am', 'me', 'less', 'yet', 'neither', 'our', 'much', 'cannot', 'ours', '‘d', 'see', 'such', 'beforehand', 'latter', 'sometimes', 'now', 'should', 'part', 'regarding', 'therefore', 'yourself', 'with', 'his', 'your', 'six', 'whereupon', 'upon', 'this', 'into', 'about', 'somewhere', 'been', 'either', 'some', 'mostly', 'seem', 'becoming', 'whereby', 'seeming', '’re', 'put', "'s", 'give', 'any', 'together', 'whose', 'before', 'take', 'formerly', 'least', 'seemed', 'whenever', 'anyone'} ============================================================

전체 불용어의 수는 326개이다. 구두점은 그대로 남아있게 된다. 개행문자, 특수문자와 기호 등은 수동으로 삭제해야한다.

 

3. Stemming and Lemmatization

어간추출(Stemming) 와 원형복원(Lemmatization)은 모든 단어를 root form과 base form으로 다운스케일하는 텍스트 정규화 작업의 하나이다.

예: Plays Playing Played ==> Play (root form)

==> Stemming : 단어에서 접두사 또는 접미사를 잘라내는 방법으로, 정확한 base form 을 제공하지 못해 불분명한 단어를 내놓기도 한다. spacy는 이런 어간추출 기능은 지원하지 않는다.

예제 : Studies 는 접미사를 제거하면 studi 가 된다. 어떤 경우에는 Studyingstudy 가 되기도 한다.

==> Lemmatization 은 입력된 텍스트를 다운스케일링하는 과정에서 형태학적 분석과 딕셔너리를 활용하여 실질적인 어근을 제공한다. 기본형 lemma 를 반환한다.

# Sample text
text="Tesla founder Elon Musk has launched tech startup Neuralink."

# returns doc container with attributes 
doc=nlp(text)
# loop through doc
# return tokens with lemmas_ (actual english language word)
tokenized=[(token.text,token.lemma_) for token in doc]
# print result.
print(tokenized)

[('Tesla', 'Tesla'), ('founder', 'founder'), ('Elon', 'Elon'), ('Musk', 'Musk'), ('has', 'have'), ('launched', 'launch'), ('tech', 'tech'), ('startup', 'startup'), ('Neuralink', 'Neuralink'), ('.', '.')]

위의 결과에서 보는 바와 같이 “has”==> “have” 로, 그리고 “launched” ==> “launch” 로 변환되었다.

 

4. Dependency Parsing

주어, 목적어, 동사 등 각 단어간의 관계에 대한 보다 나은 이해를 위한 syntactic dependency labels 을 보여준다. spaCy 라이브러리는 dispaCy라는 뛰어난 시각화 툴을 제공하는데,  이를 통해 의존성 라벨을 그래프처럼 보여준다. 문법적인 오류를 찾아내는 의미분석에서 사용된다. 

# loop through doc
# return tokens with lemmas_ (actual english language word)
tokenized=[(token.text,token.dep_) for token in doc]
# print result.
tokenized

[('Tesla', 'compound'), ('founder', 'compound'), ('Elon', 'compound'), ('Musk', 'nsubj'), ('has', 'aux'), ('launched', 'ROOT'), ('tech', 'compound'), ('startup', 'compound'), ('Neuralink', 'dobj'), ('.', 'punct')]

# But what 'aux' means, the output of has.use spacy.explain command
spacy.explain('aux')

'auxiliary'

'explain' 함수를 이용하여 이해하지 못하는 단어를 찾아낼 수 있다..

# Rather than see in bare text visualize it as a graph with displacy.
from spacy import displacy

doc=nlp(text)
# specifying style is dep will render dependency_parser.
displacy.render(doc,style='dep',manual=False)

이것은 doc 또는 span objects 에서만 유효하고, 리스트의 형태인 토큰화된 결과에는 작동하지 않는다.

# you can access head and multiple childrens.
family_tokens=[(token.text,token.head) for token in doc]
family_tokens

[('Tesla', founder), ('founder', Musk), ('Elon', Musk), ('Musk', launched), ('has', launched), ('launched', launched), ('tech', startup), ('startup', Neuralink), ('Neuralink', launched), ('.', launched)]

 

5. Part-of-Speech tagging

문장내 각 단어에 대해 noun, adverb, adjective 와 같은 태그를 붙여준다. 서로 다른 맥락에 있는 동일한 토큰의 의미를 파악하는데 도움이 된다. 

Example: What next? and other sentence She was sitting next her,

첫 번째 next 는 부사이고, 두 번째 것은 전치사이다.

# Sample text
text="Success isn't easy, and that's a good thing"

# returns doc container with attributes 
doc=nlp(text)
# loop through doc and return tokens with .text
tokenized=[(token.text,token.pos_,token.tag_) for token in doc]

pos_ 는 part-of-speech, tag_ 는 원래 태그네임의 두문자어이다.

# print result.
tokenized

[('Success', 'NOUN', 'NN'), ('is', 'AUX', 'VBZ'), ("n't", 'PART', 'RB'), ('easy', 'ADJ', 'JJ'), (',', 'PUNCT', ','), ('and', 'CCONJ', 'CC'), ('that', 'DET', 'DT'), ("'s", 'AUX', 'VBZ'), ('a', 'DET', 'DT'), ('good', 'ADJ', 'JJ'), ('thing', 'NOUN', 'NN')]

POS 태그를 표현하는 방식에는 .pos_ attribute 와  .tag_ attribute 2가지가 있다.

 

6. Chunking

Chunking 은 문장에 통사론적 구조와 의미를 더하는 것이다. POS 태그가 동사, 부사, 형용사 등을 나타내지만 실제 의미를 보여주지는 않는데 비해 청킹은 POS 태그를 입력으로 사용하여 개체명 인식 Named Entity Recognition 에 사용되는 사용하기 위한 명사구와 동사구의 그룹을 뽑아내는 청크 chunk 를 아웃풋으로 내놓는다.

# Sample text
text="""Success isn't easy, and that's a good thing - at least in business. 
If it was easy, everybody would be doing it and your competition would be outrageous!"""

# returns doc container with attributes 
doc=nlp(text)
# loop through doc and return tokens with .text
# token.root access the actual noun.
tokenized=[(token.text,token.root) for token in doc.noun_chunks]
# print result (noun phrases)
tokenized

[('Success', 'NOUN', 'NN'), ('is', 'AUX', 'VBZ'), ("n't", 'PART', 'RB'), ('easy', 'ADJ', 'JJ'), (',', 'PUNCT', ','), ('and', 'CCONJ', 'CC'), ('that', 'DET', 'DT'), ("'s", 'AUX', 'VBZ'), ('a', 'DET', 'DT'), ('good', 'ADJ', 'JJ'), ('thing', 'NOUN', 'NN')]

 

7. Named Entity Recognition

Named entity recognition (개체명 인식, Ner)은 실제 세계의 객체를 사전 정의된 카테고리 (이름, 장소, 사물, 조직, 양, 숫자 등)로 라벨링하는 것을 말한다. spacy 통계 모델은 광범위한 개체를 인식할 수 있으며, 대규모 데이터 훈련을 통해 커스텀 카테고리를 추가하여 사용할 수도 있다. 

# Sample text
text="The Microsoft hub brings you all the latest Microsoft news on Windows 10, Office 365, Surface hardware, and Microsoft's iOS and Android apps like Outlook, Skype, Office, and many more."

# returns doc container with attributes 
doc=nlp(text)
# loop through doc and return tokens with .text
# .ents entities of doc
tokenized=[token.text for token in doc.ents]
# print result.
from spacy import displacy

displacy.render(doc,style="ent",jupyter=bool)

spacy.explain('ORG')

'Companies, agencies, institutions, etc.'

 

8. Word Vector Similarity

사람은 개와 고양이가 같은 동물 카테고리에 속한다는 사실을 쉽게 파악할 수 있지만, 기계는 그러지 못한다. 이를 위한 것으로 유사성을 찾기 위해 단어를 벡터로 변환하는 과정이 필요하다. 이 기법은 문장이나 문서 단위에서도 활용이 가능하며, 워드 임베딩이라고 불리기도 한다.

# can access vector from of as word
nlp.vocab["how"].vector
array([-2.3205e-01,  4.7468e-01, -3.8264e-01,  2.2248e-03, -1.0493e-01,
        1.1612e-01, -5.0251e-02,  1.2927e-01,  8.7639e-02,  2.6391e+00,
       -3.7071e-01, -2.9460e-01, -1.2722e-01, -3.7028e-02, -1.3964e-01,
       -9.8518e-02, -2.2704e-01,  1.2254e+00, -4.3827e-01, -4.2383e-01,
        4.9285e-01, -2.3314e-01,  9.7892e-02, -2.7542e-01, -2.6583e-01,
        1.4518e-01, -1.0652e-02,  1.1067e-01,  1.6126e-01, -4.2688e-01,
       -3.0968e-01,  1.2774e-01,  9.5535e-02, -5.0221e-02,  2.6677e-01,
        1.4821e-01,  1.7805e-01,  8.8508e-02, -3.6138e-01, -2.1068e-01,
       -2.6420e-01, -3.0030e-01,  1.7674e-01, -2.0741e-01,  2.3360e-01,
        2.6663e-02, -2.7939e-01, -1.4522e-02, -3.0973e-02,  4.3729e-02,
       -3.0191e-01,  9.3855e-02, -2.0135e-01, -1.4267e-01,  3.3124e-01,
        9.8036e-02,  3.6001e-02, -5.7850e-02,  1.2101e-01,  4.1569e-02,
       -3.8834e-02, -6.6843e-02, -2.4738e-01,  1.4838e-01,  4.1011e-01,
       -3.0283e-01,  9.4704e-02,  3.2583e-01,  3.1955e-01, -4.3357e-02,
        2.0606e-01, -9.6981e-02,  4.5202e-01, -2.4532e-01,  2.6683e-01,
        2.6141e-01,  1.2174e-01, -3.9941e-01, -1.2916e-01,  2.2634e-01,
        1.2218e-01,  1.6536e-01, -5.2466e-02, -8.6235e-02,  1.2232e-02,
       -3.9760e-01, -2.5987e-01, -6.4113e-01,  2.4669e-01,  2.9575e-02,
       -2.9733e-01, -2.5994e-01, -6.1239e-01,  3.2332e-01,  2.2375e-01,
        2.1916e-01, -1.0905e-02, -7.2927e-02, -3.2219e-01, -6.5715e-02,
       -1.7247e-01,  4.0714e-02,  1.6625e-01, -1.8120e-01, -1.8531e-01,
       -1.1575e+00, -4.7285e-02,  2.4866e-02,  4.0405e-03, -6.1920e-02,
        8.7754e-02, -4.1669e-01,  8.6682e-02, -3.7720e-01,  1.6166e-01,
       -1.2879e-01, -1.6494e-01, -1.1212e-02, -1.4810e-01,  9.9342e-02,
        1.5603e-01, -2.8030e-01, -9.5092e-02,  7.7952e-02,  8.8172e-02,
        2.2930e-01, -1.0321e-01, -3.8966e-01,  1.9519e-01, -8.7815e-02,
       -1.5861e-01,  1.1627e-01,  8.8138e-02,  1.1262e-01,  1.8212e-01,
        1.8005e-02, -5.5187e-02, -3.8818e-02,  1.6536e-01, -2.5814e-01,
       -1.8516e+00, -2.9996e-01,  3.3106e-02,  3.2293e-01, -1.6417e-01,
       -2.7445e-01,  5.1582e-02,  3.4203e-01, -4.3025e-01, -4.5816e-02,
        2.3542e-01,  1.8271e-01, -8.9827e-02, -2.0280e-02, -1.0056e-02,
       -7.5604e-02,  1.5922e-02,  1.5616e-01, -3.8949e-01, -5.8165e-02,
       -4.3763e-01,  2.4587e-01, -2.3169e-01, -1.4508e-01,  3.5845e-01,
        1.2437e-01,  2.2588e-01, -1.8963e-02,  7.9287e-02,  1.6775e-01,
       -1.2729e-01, -3.2950e-01,  3.1048e-01, -1.6959e-01,  5.7082e-02,
       -9.8536e-02, -1.1715e-02,  3.9690e-01,  1.0493e-01,  1.9083e-01,
        1.3871e-01, -1.8307e-02, -7.8323e-02, -4.5149e-02,  6.6471e-02,
        1.7835e-01, -4.3998e-02, -1.9136e-01, -8.8387e-02,  4.2414e-01,
        1.1562e-01,  8.0458e-02, -1.0350e-01, -1.8200e-01, -2.0045e-01,
        1.9755e-01,  3.8457e-02, -1.1081e-01,  2.2978e-01,  3.5781e-01,
       -1.6376e-01, -2.3062e-01, -2.4412e-01, -7.3929e-02, -1.2747e-01,
        1.4730e-01,  2.5954e-01,  1.8571e-01,  2.7923e-01,  1.8186e-01,
       -1.4550e-01, -2.5523e-01, -2.3418e-01, -2.3684e-01,  5.7909e-02,
        1.3913e-01, -1.4280e-01,  9.8092e-02, -2.4884e-01, -2.2587e-01,
        2.2812e-01,  2.3718e-01, -6.6049e-02,  6.3126e-02, -3.4434e-03,
        2.6542e-01, -4.3094e-02,  9.1002e-02, -2.9563e-02,  1.3626e-01,
       -2.2368e-01,  1.4869e-01,  1.7428e-02,  2.6551e-01, -2.0984e-01,
       -1.6786e-01,  2.1192e-01,  1.2735e-01,  1.6441e-01,  3.3131e-01,
        1.0661e-01, -2.1155e-01,  2.8474e-02, -9.9419e-02,  3.4635e-01,
       -4.0166e-01, -1.9083e-01, -2.8156e-01, -8.1996e-02,  2.4322e-01,
        3.0341e-01, -1.4984e-01, -2.9952e-01, -2.8089e-01, -8.2551e-02,
       -3.5457e-01,  8.3108e-02,  7.3193e-02,  5.8555e-02,  4.7347e-02,
        3.3200e-01,  1.5465e-01, -6.5075e-02,  6.3738e-03,  2.6690e-01,
       -3.3819e-01, -2.1204e-01,  2.2368e-01,  6.2783e-01,  7.0440e-01,
       -2.2196e-01, -1.0377e-01,  6.9900e-02, -1.3201e-01, -2.6255e-01,
       -1.9671e-02, -1.1906e-01,  3.2839e-02, -3.1207e-02,  2.5083e-01,
       -1.4702e-01,  4.4411e-01, -2.1465e-01,  4.5018e-02, -1.4012e-01,
        4.6586e-02,  2.4790e-01, -1.3205e-01,  1.4456e-01, -1.8638e-01,
       -8.6773e-02,  1.3312e-01,  1.8741e-03,  4.4091e-02,  2.8882e-01,
       -9.0016e-02, -1.8108e-01,  3.3178e-01,  3.1545e-01,  3.7972e-01],
      dtype=float32)
# check for other word that don't have vector form 
nlp.vocab["jupyter"].vector
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)

작업에 앞서 해당 단어가 vector form 을 갖고 있는지부터 확인해야 한다. 2개의 문장 유사도를 테스팅해보면 91%로 나옴을 알 수 있다. 추천시스템이나 기계번역 등의 어플리케이션에서 많이 활용된다. 

# check with existence of vector with .vector_form attribute
nlp.vocab["how"].has_vector, nlp.vocab["jupyter"].has_vector

(True, False)

 

# Two Sample sentences
text="how are you"
text1="how you doing"

# returns doc containers 
doc=nlp(text)
doc1=nlp(text1)
# similarity between sentences
doc.similarity(doc1)

0.9106663802758767

 

원문보기

 

Clear the Fundamentals of NLP with Code.

Getting hands-on experience in the basics of NLP using spacy.

towardsdatascience.com