Natural Language Toolkit - การรวม Taggers

การรวม Taggers

การรวมแท็กเกอร์หรือการเชื่อมโยงแท็กเกอร์เข้าด้วยกันถือเป็นคุณสมบัติที่สำคัญอย่างหนึ่งของ NLTK แนวคิดหลักที่อยู่เบื้องหลังการรวมแท็กเกอร์คือในกรณีที่ผู้ติดแท็กไม่รู้วิธีแท็กคำก็จะถูกส่งต่อไปยังผู้ติดแท็กที่ถูกล่ามโซ่ เพื่อให้บรรลุวัตถุประสงค์นี้SequentialBackoffTagger ให้เรา Backoff tagging ลักษณะเฉพาะ.

Backoff Tagging

อย่างที่บอกไปก่อนหน้านี้การติดแท็กแบ็คออฟเป็นหนึ่งในคุณสมบัติที่สำคัญของ SequentialBackoffTaggerซึ่งช่วยให้เราสามารถรวมแท็กเกอร์ในลักษณะที่หากผู้ติดแท็กไม่รู้วิธีแท็กคำคำนั้นจะถูกส่งต่อไปยังแท็กเกอร์ถัดไปและอื่น ๆ จนกว่าจะไม่มีแบ็กออฟแท็กเกอร์เหลือให้ตรวจสอบ

มันทำงานอย่างไร?

อันที่จริงทุกคลาสย่อยของ SequentialBackoffTaggerสามารถใช้อาร์กิวเมนต์คำหลัก 'backoff' ค่าของอาร์กิวเมนต์คำหลักนี้เป็นอีกตัวอย่างหนึ่งของSequentialBackoffTagger. เมื่อใดก็ตามที่เป็นเช่นนี้SequentialBackoffTaggerเริ่มต้นคลาสแล้วรายการภายในของ backoff taggers (โดยมีตัวเองเป็นองค์ประกอบแรก) จะถูกสร้างขึ้น ยิ่งไปกว่านั้นหากมีการระบุ backoff tagger รายการภายในของ backoff taggers จะถูกต่อท้าย

ในตัวอย่างด้านล่างเรากำลังใช้ DefaulTagger ในฐานะผู้ติดแท็กแบ็คออฟในสูตร Python ด้านบนซึ่งเราได้ฝึกฝนไฟล์ UnigramTagger.

ตัวอย่าง

ในตัวอย่างนี้เรากำลังใช้ไฟล์ DefaulTaggerเป็นผู้ติดแท็กแบ็คออฟ เมื่อใดก็ตามที่UnigramTagger ไม่สามารถติดแท็กคำ backoff tagger เช่น 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

จากผลลัพธ์ข้างต้นคุณสามารถสังเกตได้ว่าการเพิ่ม backoff tagger ความแม่นยำจะเพิ่มขึ้นประมาณ 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 และ TrigramTaggerคลาสย่อยทีละคลาสเหมือนกับที่เราทำกับคลาสย่อย UnigramTagger ทั้งคู่ทำงานได้แย่มาก ให้เราดูในตัวอย่างด้านล่าง:

ใช้ BigramTagger Subclass

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 Subclass

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 taggers

จากตัวอย่างข้างต้นจะเห็นได้ชัดว่าผู้ติดแท็ก Bigram และ Trigram สามารถมีส่วนร่วมได้เมื่อเรารวมเข้ากับการแท็กแบ็กออฟ ในตัวอย่างด้านล่างเรากำลังรวม Unigram, Bigram และ Trigram taggers เข้ากับ backoff tagging แนวคิดนี้เหมือนกับสูตรก่อนหน้าในขณะที่รวม UnigramTagger กับ backoff tagger ข้อแตกต่างเพียงอย่างเดียวคือเรากำลังใช้ฟังก์ชันชื่อ backoff_tagger () จาก tagger_util.py ที่ระบุด้านล่างสำหรับการดำเนินการ backoff

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%