spaCy Ruled Based Matching

Dibandingkan dengan regular expressions pada raw text, spaCy rule based matching selain membantu mencari kata atau frase, kita juga dapat mengakses token dan relasinya.

Ini berarti kita dapat mengakses dan menganalisis token-token lainnya, menggabungkan span menjadi single tokens atau menambahkan entri kedalam named entities pada doc.ents.

Token Matcher

Tool yang digunakan untuk rule-matching adalah Matcher. Dengan Matcher, kita dapat membuat token patterns. Lalu melakukan proses matching patterns terhadap Doc object, yang akan mengembalikan list matches yang ditemukan.

Untuk menggunakan matcher, kita harus import terlebih dahulu librarynya.

import spacy
nlp = spacy.load('en_core_web_sm')

# import matcher library
from spacy.matcher import Matcher
matcher = Matcher(nlp.vocab)

Membuat Pattern

Berikut contoh membuat pattern untuk mencari kata solar power.

  • Pattern1: mencari single token dengan kata solarpower
  • Pattern2: mencari dua token dengan urutan solar dan power
  • Pattern3: mencari tiga token dengan urutan solar, tanda baca dan power.
pattern1 = [{'LOWER': 'solarpower'}]
pattern2 = [{'LOWER': 'solar'}, {'LOWER': 'power'}]
pattern3 = [{'LOWER': 'solar'}, {'IS_PUNCT': True}, {'LOWER': 'power'}]

matcher.add('SolarPower', None, pattern1, pattern2, pattern3)

Menggunakan Pattern

Matcher akan mengembalikan list of tuples. Setiap tuple berisi ID match, start & end tokens.

doc = nlp(u'The Solar Power industry continues to grow as demand \
for solarpower increases. Solar-power cars are gaining popularity.')

found_matches = matcher(doc)
for match_id, start, end in found_matches:
    string_id = nlp.vocab.strings[match_id]  # string representation
    span = doc[start:end]                    # matched span
    print(match_id, string_id, start, end, span.text)
8656102463236116519 SolarPower 1 3 Solar Power
8656102463236116519 SolarPower 10 11 solarpower
8656102463236116519 SolarPower 13 16 Solar-power

Token Attribute Pattern

AttributeDeskripsi
‘ORTH’Kata yang persis sama
‘LOWER’Lowercase dari kata
‘LENGTH’Panjang dari kata
‘IS_ALPHA’, ‘IS_ASCII’, ‘IS_DIGIT’Memeriksa token berisi alphanumeric, ascii, digit.
‘IS_LOWER’, ‘IS_UPPER’, ‘IS_TITLE’Memeriksa token berisi lowercase, uppercase atau titlecase.
‘IS_PUNCT’, ‘IS_SPACE’, ‘IS_STOP’Memeriksa token berisi punctuation, space atau stop word.
‘LIKE_NUM’, ‘LIKE_URL’, ‘LIKE_EMAIL’Token menyerupai angka, url (alamat web) atau email
‘POS’, ‘TAG’, ‘DEP’, ‘LEMMA’, ‘SHAPE’Token merupakan POS, TAG, DEP, LEMMA, SHAPE
‘ENT_TYPE’Token entity label

Operator dan Quantifier

OPDeskripsi
!Negasi pattern, harus 0 match.
?Pattern optional, 0 atau 1 match.
+Pattern harus match 1 kali atau lebih.
*Pattern dapat match 0 atau lebih.
pattern1 = [{'LOWER': 'solarpower'}]
pattern2 = [{'LOWER': 'solar'}, {'IS_PUNCT': True, 'OP':'*'}, {'LOWER': 'power'}]

# buang pattern sebelumnya
matcher.remove('SolarPower')

# tambahkan pattern baru
matcher.add('SolarPower', None, pattern1, pattern2)

found_matches = matcher(doc)
for match_id, start, end in found_matches:
    string_id = nlp.vocab.strings[match_id]  # get string representation
    span = doc[start:end]                    # get the matched span
    print(match_id, string_id, start, end, span.text)
8656102463236116519 SolarPower 1 3 Solar Power
8656102463236116519 SolarPower 10 11 solarpower
8656102463236116519 SolarPower 13 16 Solar-power

PhraseMatcher

Alternative lain yang lebih efisien, adalah melakukan match terhadap list terminologi. Dapat dilakukan dengan menggunakan PhraseMatcher untuk membuat Doc object dari list frase.

import spacy
nlp = spacy.load('en_core_web_sm')

# Import PhraseMatcher library
from spacy.matcher import PhraseMatcher
matcher = PhraseMatcher(nlp.vocab)

with open('../TextFiles/reaganomics.txt', encoding='utf8') as f:
    doc3 = nlp(f.read())

# create list of match phrases
phrase_list = ['voodoo economics', 'supply-side economics', 'trickle-down economics', 'free-market economics']

# convert each phrase to a Doc object:
phrase_patterns = [nlp(text) for text in phrase_list]

# Pass each Doc object into matcher (note the use of the asterisk!):
matcher.add('VoodooEconomics', None, *phrase_patterns)

# Build a list of matches:
found_matches = matcher(doc3)

# print the matches
for match_id, start, end in found_matches:
    string_id = nlp.vocab.strings[match_id]  # get string representation
    span = doc[start:end]                    # get the matched span
    print(match_id, string_id, start, end, span.text)
3473369816841043438 VoodooEconomics 41 45 supply-side economics
3473369816841043438 VoodooEconomics 49 53 trickle-down economics
3473369816841043438 VoodooEconomics 54 56 voodoo economics
3473369816841043438 VoodooEconomics 61 65 free-market economics
3473369816841043438 VoodooEconomics 673 677 supply-side economics
3473369816841043438 VoodooEconomics 2984 2988 trickle-down economics

Untuk dokumentasi ruled-based matching silakan kunjungi https://spacy.io/usage/rule-based-matching

Sharing is caring: