Spaczz ให้การจับคู่ฟัซซี่และฟังก์ชั่นการจับคู่ Regex เพิ่มเติมสำหรับ Spacy ส่วนประกอบของ Spaczz มี API ที่คล้ายกันกับเครื่องรางของพวกเขาและส่วนประกอบไปป์ไลน์ Spaczz สามารถรวมเข้ากับท่อส่งสัญญาณที่สามารถบันทึก/โหลดเป็นรุ่นได้
การจับคู่ Fuzzy กำลังดำเนินการกับผู้จับคู่จากโมดูล Fuzz ของ Rapidfuzz และการจับคู่ Regex ในปัจจุบันขึ้นอยู่กับไลบรารี Regex Spaczz มีอิทธิพลเพิ่มเติมจากห้องสมุดและทรัพยากรอื่น ๆ อย่างแน่นอน สำหรับรายละเอียดเพิ่มเติมดูส่วนการอ้างอิง
รองรับ Spacy> = 3.0
Spaczz ได้รับการทดสอบบน Ubuntu, MacOS และ Windows Server
v0.6.0 หมายเหตุการเปิดตัว:
python<=3.11,>=3.7 พร้อมกับ rapidfuzz>=1.0.0"spaczz_" preprended SpaczzRuler inticment init อาร์กิวเมนต์ init นอกจากนี้ขออภัยที่ทำสิ่งนี้โดยไม่มีวงจรการเสื่อมราคาMatcher.pipe Methods ซึ่งเลิกใช้แล้วตอนนี้จะถูกลบออกspaczz_span ที่กำหนดเองซึ่งเลิกใช้แล้วตอนนี้จะถูกลบออกโปรดดูการเปลี่ยนแปลงสำหรับบันทึกย่อรุ่นก่อนหน้า ในที่สุดจะถูกย้ายไปที่หน้าอ่านเอกสาร
สามารถติดตั้ง Spaczz ได้โดยใช้ PIP
pip install spaczz คุณสมบัติหลักของ Spaczz คือ FuzzyMatcher , RegexMatcher และ " TokenMatcher " Fuzzy "ที่ทำหน้าที่คล้ายกับ Matcher ของ Spacy และ PhraseMatcher และ SpaczzRuler ซึ่งรวมตัวจับคู่ Spaczz เข้ากับ EntityRuler ของ Spaczy
การใช้งานขั้นพื้นฐานของตัวจับคู่ฟัซซี่นั้นคล้ายคลึงกับ PhraseMatcher ของ Spacy ยกเว้นว่าจะส่งคืนอัตราส่วนฟัซซี่และรูปแบบที่จับคู่พร้อมกับ ID จับคู่ข้อมูลเริ่มต้นและสิ้นสุดดังนั้นอย่าลืมรวมตัวแปรสำหรับอัตราส่วนและรูปแบบเมื่อเปิดผลลัพธ์
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
text = """Grint M Anderson created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )])
matcher . add ( "GPE" , [ nlp ( "Nashville" )])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) NAME Grint M Anderson 80 Grant Andersen
GPE Nashv1le 82 Nashville
ซึ่งแตกต่างจากการจับคู่ Spacy, spaczz matchers ถูกเขียนใน Pure Python ในขณะที่พวกเขาจะต้องมีคำศัพท์ Spacy ที่ส่งผ่านไปยังพวกเขาในระหว่างการเริ่มต้นสิ่งนี้มีความสอดคล้องอย่างหมดจดเนื่องจากตัวจับคู่ spaczz ไม่ได้ใช้ในปัจจุบันใช้คำศัพท์ Spacy นี่คือเหตุผลที่ match_id ด้านบนเป็นเพียงสตริงแทนค่าจำนวนเต็มเช่นใน spacy matchers
Spaczz Matchers ยังสามารถใช้ประโยชน์จากกฎการแข่งขันผ่านฟังก์ชั่นการโทรกลับ การโทรกลับในการแข่งขันเหล่านี้จำเป็นต้องยอมรับตัวจับคู่เองเอกสารที่จับคู่ถูกเรียกใช้ดัชนีการจับคู่และการจับคู่ที่ผลิตโดยผู้จับคู่
import spacy
from spacy . tokens import Span
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
text = """Grint M Anderson created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
def add_name_ent ( matcher , doc , i , matches ):
"""Callback on match function. Adds "NAME" entities to doc."""
# Get the current match and create tuple of entity label, start and end.
# Append entity to the doc's entity. (Don't overwrite doc.ents!)
_match_id , start , end , _ratio , _pattern = matches [ i ]
entity = Span ( doc , start , end , label = "NAME" )
doc . ents += ( entity ,)
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )], on_match = add_name_ent )
matches = matcher ( doc )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Grint M Anderson', 0, 3, 'NAME')
เช่นเดียวกับ EntityRuler ของ Spacy มีการใช้ตรรกะการอัปเดตเอนทิตีที่คล้ายกันมากใน SpaczzRuler SpaczzRuler ยังดูแลการจัดการการแข่งขันที่ทับซ้อนกัน มันถูกกล่าวถึงในส่วนต่อมา
ซึ่งแตกต่างจากการจับคู่ของ Spacy กฎที่เพิ่มเข้ามาใน Spaczz Matchers มีอาร์กิวเมนต์คำหลักที่เป็นตัวเลือกที่สามารถแก้ไขพฤติกรรมการจับคู่ได้ นำตัวอย่างการจับคู่ฟัซซี่ด้านล่าง:
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
# Let's modify the order of the name in the text.
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )])
matches = matcher ( doc )
# The default fuzzy matching settings will not find a match.
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern )ต่อไปเราเปลี่ยนพฤติกรรมการจับคู่ที่คลุมเครือสำหรับรูปแบบในกฎ "ชื่อ"
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
# Let's modify the order of the name in the text.
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )], kwargs = [{ "fuzzy_func" : "token_sort" }])
matches = matcher ( doc )
# The default fuzzy matching settings will not find a match.
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) NAME Anderson, Grint 83 Grant Andersen
รายการทั้งหมดของอาร์กิวเมนต์คำหลักที่มีอยู่สำหรับการตั้งค่าการจับคู่ฟัซซี่รวมถึง:
ignore_case (บูล): ไม่ว่าจะเป็นข้อความที่ต่ำกว่าก่อนที่จะจับคู่ ค่าเริ่มต้นเป็น Truemin_r (int): ต้องการอัตราส่วนการจับคู่ขั้นต่ำthresh (int): หากอัตราส่วนนี้เกินในการสแกนเริ่มต้นและ flex > 0 จะไม่มีการปรับให้เหมาะสม ถ้า flex == 0 , thresh ไม่มีผล ค่าเริ่มต้นคือ 100fuzzy_func (STR): ชื่อคีย์ของฟังก์ชั่นการจับคู่ฟัซซี่ที่จะใช้ ฟังก์ชั่นการจับคู่ RapidFuzz ทั้งหมดพร้อมการตั้งค่าเริ่มต้นจะพร้อมใช้งาน ฟังก์ชั่นการจับคู่ฟัซซี่เพิ่มเติมสามารถลงทะเบียนโดยผู้ใช้ ค่าเริ่มต้นคือ "simple" :"simple" = ratio"partial" = partial_ratio"token" = token_ratio"token_set" = token_set_ratio"token_sort" = token_sort_ratio"partial_token" = partial_token_ratio"partial_token_set" = partial_token_set_ratio"partial_token_sort" = partial_token_sort_ratio"weighted" = WRatio"quick" = QRatio"partial_alignment" = partial_ratio_alignment (ต้องการ rapidfuzz>=2.0.3 )flex (int | ตัวอักษร ['default', 'min', 'max']): จำนวนโทเค็นเพื่อย้ายขอบเขตการจับคู่ซ้ายและขวาในระหว่างการปรับให้เหมาะสม สามารถเป็น int ที่มีค่าสูงสุดของ len(pattern) และนาที 0 , (จะเตือนและเปลี่ยนแปลงหากสูงขึ้นหรือต่ำลง) "max" , "min" หรือ "default" ก็ใช้ได้เช่นกัน ค่าเริ่มต้นคือ "default" : len(pattern) // 2min_r1 (int | none): การควบคุมเม็ดเล็ก ๆ ต่ออัตราส่วนการจับคู่ขั้นต่ำที่จำเป็นสำหรับการเลือกในระหว่างการสแกนเริ่มต้น ถ้า flex == 0 , min_r1 จะถูกเขียนทับโดย min_r2 ถ้า flex > 0 , min_r1 ต้องต่ำกว่า min_r2 และ "ต่ำ" โดยทั่วไปเนื่องจากขอบเขตการจับคู่จะไม่งอในขั้นต้น ค่าเริ่มต้นคือ None ซึ่งจะส่งผลให้ min_r1 ถูกตั้งค่าเป็น round(min_r / 1.5) การใช้งานขั้นพื้นฐานของเครื่องจับคู่ Regex นั้นค่อนข้างคล้ายกับ PhraseMatcher ของ Spacy มันยอมรับรูปแบบ regex เป็นสตริงดังนั้นธงจะต้องเป็นแบบอินไลน์ Regexes ถูกรวบรวมด้วยแพ็คเกจ Regex ดังนั้นจึงรองรับการจับคู่ "ฟัซซี่" โดยประมาณ เพื่อให้การเข้าถึงผลลัพธ์การจับคู่ "ฟัซซี่" เหล่านี้ผู้จับคู่จะส่งคืนอัตราส่วนฟัซซี่ที่คำนวณได้และรูปแบบการจับคู่พร้อมกับ ID จับคู่ข้อมูลเริ่มต้นและสิ้นสุดดังนั้นตรวจสอบให้แน่ใจว่าได้รวมตัวแปรสำหรับอัตราส่วนและรูปแบบเมื่อแกะผลลัพธ์
import spacy
from spaczz . matcher import RegexMatcher
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = RegexMatcher ( nlp . vocab )
# Use inline flags for regex strings as needed
matcher . add (
"ZIP" ,
[ r"bd{5}(?:[-s]d{4})?b" ],
)
matcher . add ( "GPE" , [ r"(usa){d<=1}" ]) # Fuzzy regex.
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) ZIP 55555-1234 100 bd{5}(?:[-s]d{4})?b
GPE US 80 (usa){d<=1}
Spaczz Matchers ยังสามารถใช้ประโยชน์จากกฎการแข่งขันผ่านฟังก์ชั่นการโทรกลับ การโทรกลับในการแข่งขันเหล่านี้จำเป็นต้องยอมรับตัวจับคู่เองเอกสารที่จับคู่ถูกเรียกใช้ดัชนีการจับคู่และการจับคู่ที่ผลิตโดยผู้จับคู่ ดูตัวอย่างการใช้งาน Matcher Fuzzy ด้านบนสำหรับรายละเอียด
เช่นเดียวกับตัวจับคู่ฟัซซี่ตัวจับคู่ Regex มีอาร์กิวเมนต์คำหลักเสริมที่สามารถแก้ไขพฤติกรรมการจับคู่ได้ นำตัวอย่างการจับคู่ Regex ด้านล่าง
import spacy
from spaczz . matcher import RegexMatcher
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.""" # Spelling errors intentional. Notice 'USA' here.
doc = nlp ( text )
matcher = RegexMatcher ( nlp . vocab )
# Use inline flags for regex strings as needed
matcher . add (
"STREET" , [ "street_addresses" ], kwargs = [{ "predef" : True }]
) # Use predefined regex by key name.
# Below will not expand partial matches to span boundaries.
matcher . add ( "GPE" , [ r"(?i)[U](nited|.?) ?[S](tates|.?)" ], kwargs = [{ "partial" : False }])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print (
match_id , doc [ start : end ], ratio , pattern
) # comma in result isn't ideal - see "Roadmap" STREET 555 Fake St, 100 street_addresses
รายการทั้งหมดของอาร์กิวเมนต์คำหลักที่มีอยู่สำหรับการตั้งค่าการจับคู่ Regex รวมถึง:
ignore_case (บูล): ไม่ว่าจะเป็นข้อความที่ต่ำกว่าก่อนที่จะจับคู่ ค่าเริ่มต้นเป็น Truemin_r (int): ต้องการอัตราส่วนการจับคู่ขั้นต่ำfuzzy_weights (STR): ชื่อวิธีการถ่วงน้ำหนักสำหรับการแทรก Regex, การลบและจำนวนการเติม วิธีการถ่วงน้ำหนักเพิ่มเติมสามารถลงทะเบียนโดยผู้ใช้ ค่าเริ่มต้นคือ "indel""indel" = (1, 1, 2)"lev" = (1, 1, 1)partial : (บูล): การจับคู่บางส่วนควรขยายไปยัง Token หรือ Span ขอบเขตใน doc หรือไม่ ตัวอย่างเช่น regex ตรงกับส่วนหนึ่งของ Token หรือ Span ใน doc ค่าเริ่มต้นเป็น Truepredef (String): ไม่ว่าจะเป็นสตริง Regex ควรตีความว่าเป็นกุญแจสำคัญในรูปแบบ regex ที่กำหนดไว้ล่วงหน้าหรือไม่ ผู้ใช้สามารถลงทะเบียนรูปแบบ Regex ที่กำหนดไว้ล่วงหน้าเพิ่มเติมได้ ค่าเริ่มต้นเป็น False."dates""times""phones""phones_with_exts""links""emails""ips""ipv6s""prices""hex_colors""credit_cards""btc_addresses""street_addresses""zip_codes""po_boxes""ssn_numbers" การใช้งานขั้นพื้นฐานของตัวจับคู่ความคล้ายคลึงกันนั้นคล้ายคลึงกับ PhraseMatcher ของ Spacy ยกเว้นว่าจะส่งคืนอัตราส่วนความคล้ายคลึงกันของเวกเตอร์และรูปแบบที่ตรงกันพร้อมกับ ID จับคู่ข้อมูลเริ่มต้นและจุดสิ้นสุดดังนั้นตรวจสอบให้แน่ใจว่าได้รวมตัวแปรสำหรับอัตราส่วนและรูปแบบเมื่อเปิดผลลัพธ์
ในการสร้างผลลัพธ์ที่มีความหมายจากตัวจับคู่ความคล้ายคลึงกันรูปแบบของเครื่องเทศที่มีเวกเตอร์คำ (เช่นโมเดลภาษาอังกฤษขนาดกลางหรือขนาดใหญ่) จะต้องใช้ในการเริ่มต้นเครื่องจับคู่ประมวลผลเอกสารเป้าหมายและประมวลผลรูปแบบใด ๆ ที่เพิ่มเข้ามา
import spacy
from spaczz . matcher import SimilarityMatcher
nlp = spacy . load ( "en_core_web_md" )
text = "I like apples, grapes and bananas."
doc = nlp ( text )
# lowering min_r2 from default of 75 to produce matches in this example
matcher = SimilarityMatcher ( nlp . vocab , min_r2 = 65 )
matcher . add ( "FRUIT" , [ nlp ( "fruit" )])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) FRUIT apples 70 fruit
FRUIT grapes 73 fruit
FRUIT bananas 70 fruit
โปรดทราบว่าแม้กระทั่งสำหรับ Spaczz Pure-Python ส่วนใหญ่กระบวนการนี้ช้ามากในปัจจุบันดังนั้นจงคำนึงถึงขอบเขตที่ใช้ การเปิดใช้งานการสนับสนุน GPU ใน Spacy (ดูที่นี่) ควรปรับปรุงความเร็วค่อนข้างมาก แต่ฉันเชื่อว่ากระบวนการจะยังคงคอขวดในอัลกอริทึมการค้นหา Pure-Python จนกว่าฉันจะพัฒนาอัลกอริทึมการค้นหาที่ดีขึ้นและ/หรือวางการค้นหาลงในรหัสระดับล่าง (เช่น C C)
นอกจากนี้ในฐานะที่เป็นคุณสมบัติการทดลองค่อนข้างผู้จับคู่ความคล้ายคลึงกันไม่ได้เป็นส่วนหนึ่งของ SpaczzRuler และไม่มีไม้บรรทัดแยกต่างหาก หากคุณต้องการเพิ่มการจับคู่ความคล้ายคลึงกันกับเอนทิตีของ Doc คุณจะต้องใช้การโทรกลับในการแข่งขันในขณะนี้ โปรดดูตัวอย่างการเรียกกลับมาจับคู่แบบฟัซซี่บนการแข่งขันด้านบนสำหรับแนวคิด หากมีความสนใจเพียงพอในการรวม/สร้างไม้บรรทัดสำหรับตัวจับคู่ความคล้ายคลึงกันสามารถทำได้
รายการทั้งหมดของอาร์กิวเมนต์คำหลักที่มีอยู่สำหรับการตั้งค่าการจับคู่ที่คล้ายคลึงกันรวมถึง:
ignore_case (bool): ไม่ว่าจะเป็นข้อความส่วนล่างก่อนที่จะจับคู่ฟัซซี่ ค่าเริ่มต้นเป็น Truemin_r (int): ต้องการอัตราส่วนการจับคู่ขั้นต่ำthresh (int): หากอัตราส่วนนี้เกินในการสแกนเริ่มต้นและ flex > 0 จะไม่มีการปรับให้เหมาะสม ถ้า flex == 0 , thresh ไม่มีผล ค่าเริ่มต้นคือ 100flex (int | ตัวอักษร ['default', 'min', 'max']): จำนวนโทเค็นเพื่อย้ายขอบเขตการจับคู่ซ้ายและขวาในระหว่างการปรับให้เหมาะสม สามารถเป็น int ที่มีค่าสูงสุดของ len(pattern) และนาที 0 , (จะเตือนและเปลี่ยนแปลงหากสูงขึ้นหรือต่ำลง) "max" , "min" หรือ "default" ก็ใช้ได้เช่นกัน ค่าเริ่มต้นคือ "default" : len(pattern) // 2min_r1 (int | none): การควบคุมเม็ดเล็ก ๆ ต่ออัตราส่วนการจับคู่ขั้นต่ำที่จำเป็นสำหรับการเลือกในระหว่างการสแกนเริ่มต้น ถ้า flex == 0 , min_r1 จะถูกเขียนทับโดย min_r2 ถ้า flex > 0 , min_r1 ต้องต่ำกว่า min_r2 และ "ต่ำ" โดยทั่วไปเนื่องจากขอบเขตการจับคู่จะไม่งอในขั้นต้น ค่าเริ่มต้นคือ None ซึ่งจะส่งผลให้ min_r1 ถูกตั้งค่าเป็น round(min_r / 1.5)min_r2 (int | none): การควบคุมเม็ดเล็ก ๆ ที่เป็นตัวเลือกต่ออัตราส่วนการจับคู่ขั้นต่ำที่จำเป็นสำหรับการเลือกระหว่างการเพิ่มประสิทธิภาพการจับคู่ จะต้องสูงกว่า min_r1 และ "สูง" โดยทั่วไปเพื่อให้แน่ใจว่าการจับคู่คุณภาพจะถูกส่งคืนเท่านั้น ค่าเริ่มต้นคือ None ซึ่งจะส่งผลให้ min_r2 ถูกตั้งค่าเป็น min_r หมายเหตุ: Matcher ของ Spacy รองรับการจับคู่ฟัซซี่ดังนั้นหากคุณไม่ต้องการคุณสมบัติเฉพาะจาก TokenMatcher ของ Spaczz ขอแนะนำให้ใช้ Matcher ที่เร็วกว่าของ Spacy
การใช้งานขั้นพื้นฐานของ Token Matcher นั้นคล้ายกับ Matcher ของ Spacy มันยอมรับรูปแบบที่มีป้ายกำกับในรูปแบบของรายการพจนานุกรมที่แต่ละรายการอธิบายรูปแบบแต่ละรูปแบบและแต่ละพจนานุกรมอธิบายโทเค็นแต่ละตัว
Token Matcher ยอมรับแอตทริบิวต์โทเค็นเดียวกันทั้งหมดและรูปแบบไวยากรณ์เนื่องจากเป็นเครื่องสแปส แต่เพิ่มการรองรับฟัซซี่และฟัซซี่-เรกซ์
"FUZZY" และ "FREGEX" เป็นตัวเลือกรูปแบบโทเค็น Spacy เพิ่มเติมสองตัว
ตัวอย่างเช่น:
[
{ "TEXT" : { "FREGEX" : "(database){e<=1}" }},
{ "LOWER" : { "FUZZY" : "access" , "MIN_R" : 85 , "FUZZY_FUNC" : "quick_lev" }},
]ตรวจสอบให้แน่ใจว่าใช้คีย์พจนานุกรมตัวพิมพ์ใหญ่ในรูปแบบ
รายการทั้งหมดของอาร์กิวเมนต์คำหลักที่มีสำหรับการตั้งค่าการจับคู่โทเค็นรวมถึง:
ignore_case (บูล): ไม่ว่าจะเป็นข้อความที่ต่ำกว่าก่อนที่จะจับคู่ สามารถตั้งค่าได้ที่ระดับรูปแบบเท่านั้น สำหรับรูปแบบ "ฟัซซี่" และ "Fregex" ค่าเริ่มต้นเป็น Truemin_r (int): ต้องการอัตราส่วนการจับคู่ขั้นต่ำ สำหรับรูปแบบ "ฟัซซี่" และ "Fregex"fuzzy_func (STR): ชื่อคีย์ของฟังก์ชั่นการจับคู่ฟัซซี่ที่จะใช้ สามารถตั้งค่าได้ที่ระดับรูปแบบเท่านั้น สำหรับรูปแบบ "ฟัซซี่" เท่านั้น ฟังก์ชั่นการจับคู่ RapidFuzz ทั้งหมดที่มีการตั้งค่าเริ่มต้นมีอยู่อย่างไรก็ตามฟังก์ชั่นที่ใช้โทเค็นใด ๆ ไม่ได้ให้ยูทิลิตี้ในระดับโทเค็นแต่ละตัว ฟังก์ชั่นการจับคู่ฟัซซี่เพิ่มเติมสามารถลงทะเบียนโดยผู้ใช้ รวมและมีประโยชน์ฟังก์ชั่นคือ (ค่าเริ่มต้น simple ):"simple" = ratio"partial" = partial_ratio"quick" = QRatio"partial_alignment" = partial_ratio_alignment (ต้องการ rapidfuzz>=2.0.3 )fuzzy_weights (STR): ชื่อวิธีการถ่วงน้ำหนักสำหรับการแทรก Regex, การลบและจำนวนการเติม วิธีการถ่วงน้ำหนักเพิ่มเติมสามารถลงทะเบียนโดยผู้ใช้ ค่าเริ่มต้นคือ "indel""indel" = (1, 1, 2)"lev" = (1, 1, 1)predef : ไม่ว่าจะเป็นการตีความ Regex เป็นกุญแจสำคัญในรูปแบบ regex ที่กำหนดไว้ล่วงหน้าหรือไม่ สามารถตั้งค่าได้ที่ระดับรูปแบบเท่านั้น สำหรับรูปแบบ "Fregex" เท่านั้น ค่าเริ่มต้นเป็น False import spacy
from spaczz . matcher import TokenMatcher
# Using model results like POS tagging in token patterns requires model that provides these.
nlp = spacy . load ( "en_core_web_md" )
text = """The manager gave me SQL databesE acess so now I can acces the Sequal DB.
My manager's name is Grfield"""
doc = nlp ( text )
matcher = TokenMatcher ( vocab = nlp . vocab )
matcher . add (
"DATA" ,
[
[
{ "TEXT" : "SQL" },
{ "LOWER" : { "FREGEX" : "(database){s<=1}" }},
{ "LOWER" : { "FUZZY" : "access" }},
],
[{ "TEXT" : { "FUZZY" : "Sequel" }, "POS" : "PROPN" }, { "LOWER" : "db" }],
],
)
matcher . add ( "NAME" , [[{ "TEXT" : { "FUZZY" : "Garfield" }}]])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) DATA SQL databesE acess 91 [{"TEXT":"SQL"},{"LOWER":{"FREGEX":"(database){s<=1}"}},{"LOWER":{"FUZZY":"access"}}]
DATA Sequal DB 87 [{"TEXT":{"FUZZY":"Sequel"},"POS":"PROPN"},{"LOWER":"db"}]
NAME Grfield 93 [{"TEXT":{"FUZZY":"Garfield"}}]
แม้ว่าตัวจับคู่โทเค็นสามารถแทนที่ตัวแบบดรอปอินสำหรับ Matcher ของ Spacy แต่ก็ยังแนะนำให้ใช้ Matcher ของ Spacy หากคุณไม่ต้องการความสามารถของ Fuzzy Token Token ของ Spaczz - มันจะช้าลงโดยไม่จำเป็น
การเตือนความจำ: ตอนนี้ Matcher ของ Spacy รองรับการจับคู่ฟัซซี่ดังนั้นหากคุณไม่จำเป็นต้องมีคุณสมบัติเฉพาะจาก TokenMatcher ของ Spaczz ขอแนะนำอย่างยิ่งให้ใช้ Matcher ที่เร็วกว่าของ Spacy
ไม้บรรทัด Spaczz รวมตัวจับคู่วลีฟัซซี่และ Regex และผู้จับคู่โทเค็น "ฟัซซี่" เป็นองค์ประกอบหนึ่งไปป์ที่สามารถอัปเดต Doc.ents คล้ายกับ EntityRuler ของ Spacy
รูปแบบจะต้องเพิ่มเป็นแบบวนซ้ำของพจนานุกรมในรูปแบบของ {label (str), รูปแบบ (str หรือ list), ประเภท (str), kwargs เสริม (dict) และ id เสริม (str)}
ตัวอย่างเช่นรูปแบบวลีฟัซซี่:
{'label': 'ORG', 'pattern': 'Apple' 'kwargs': {'min_r2': 90}, 'type': 'fuzzy'}
หรือรูปแบบโทเค็น:
{'label': 'ORG', 'pattern': [{'TEXT': {'FUZZY': 'Apple'}}], 'type': 'token'}
import spacy
from spaczz . pipeline import SpaczzRuler
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.
Some of his favorite bands are Converg and Protet the Zero.""" # Spelling errors intentional.
doc = nlp ( text )
patterns = [
{
"label" : "NAME" ,
"pattern" : "Grant Andersen" ,
"type" : "fuzzy" ,
"kwargs" : { "fuzzy_func" : "token_sort" },
},
{
"label" : "STREET" ,
"pattern" : "street_addresses" ,
"type" : "regex" ,
"kwargs" : { "predef" : True },
},
{ "label" : "GPE" , "pattern" : "Nashville" , "type" : "fuzzy" },
{
"label" : "ZIP" ,
"pattern" : r"b(?:55554){s<=1}(?:(?:[-s])?d{4}b)" ,
"type" : "regex" ,
}, # fuzzy regex
{ "label" : "GPE" , "pattern" : "(?i)[U](nited|.?) ?[S](tates|.?)" , "type" : "regex" },
{
"label" : "BAND" ,
"pattern" : [{ "LOWER" : { "FREGEX" : "(converge){e<=1}" }}],
"type" : "token" ,
},
{
"label" : "BAND" ,
"pattern" : [
{ "TEXT" : { "FUZZY" : "Protest" }},
{ "IS_STOP" : True },
{ "TEXT" : { "FUZZY" : "Hero" }},
],
"type" : "token" ,
},
]
ruler = SpaczzRuler ( nlp )
ruler . add_patterns ( patterns )
doc = ruler ( doc )
for ent in doc . ents :
print (
(
ent . text ,
ent . start ,
ent . end ,
ent . label_ ,
ent . _ . spaczz_ratio ,
ent . _ . spaczz_type ,
ent . _ . spaczz_pattern ,
)
) ('Anderson, Grint', 0, 3, 'NAME', 83, 'fuzzy', 'Grant Andersen')
('555 Fake St,', 9, 13, 'STREET', 100, 'regex', 'street_addresses')
('Nashv1le', 17, 18, 'GPE', 82, 'fuzzy', 'Nashville')
('55555-1234', 20, 23, 'ZIP', 90, 'regex', '\b(?:55554){s<=1}(?:(?:[-\s])?\d{4}\b)')
('USA', 25, 26, 'GPE', 100, 'regex', '(?i)[U](nited|\.?) ?[S](tates|\.?)')
('Converg', 34, 35, 'BAND', 93, 'token', '[{"LOWER":{"FREGEX":"(converge){e<=1}"}}]')
('Protet the Zero', 36, 39, 'BAND', 89, 'token', '[{"TEXT":{"FUZZY":"Protest"}},{"IS_STOP":true},{"TEXT":{"FUZZY":"Hero"}}]')
เราเห็นในตัวอย่างข้างต้นว่าเรากำลังอ้างอิงแอตทริบิวต์ที่กำหนดเองซึ่งอธิบายไว้ด้านล่าง
สำหรับตัวอย่าง SpaczzRuler เพิ่มเติมดูที่นี่ โดยเฉพาะอย่างยิ่งสิ่งนี้ให้รายละเอียดเกี่ยวกับกระบวนการจัดเรียงของไม้บรรทัดและพารามิเตอร์การจับคู่ที่คลุมเครือ
Spaczz เริ่มต้นแอตทริบิวต์ที่กำหนดเองบางอย่างเมื่อนำเข้า สิ่งเหล่านี้อยู่ภายใต้ Spacy's ._. แอตทริบิวต์และมีการเตรียมการเพิ่มเติมด้วย spaczz_ ดังนั้นจึงไม่ควรขัดแย้งกับคุณลักษณะที่กำหนดเองของคุณเอง หากมี spaczz จะบังคับให้เขียนทับพวกเขา
แอตทริบิวต์ที่กำหนดเองเหล่านี้ถูกตั้งค่าผ่านไม้บรรทัด Spaczz ในระดับโทเค็นเท่านั้น แอตทริบิวต์รุ่นและเอกสารเหล่านี้คือ getters ที่อ้างอิงแอตทริบิวต์ระดับโทเค็น
คุณลักษณะ Token ต่อไปนี้มีอยู่ ทั้งหมดไม่แน่นอน:
spaczz_token : default = False บูลีนที่หมายถึงว่าโทเค็นเป็นส่วนหนึ่งของเอนทิตีที่กำหนดโดยผู้ปกครอง Spaczzspaczz_type : default = None สตริงที่แสดงว่าเครื่องจับคู่ใดผลิตเอนทิตีโดยใช้โทเค็นspaczz_ratio : default = None หากโทเค็นเป็นส่วนหนึ่งของเอนทิตีที่ตรงกันมันจะส่งคืนอัตราส่วนฟัซซี่spaczz_pattern : default = None หากโทเค็นเป็นส่วนหนึ่งของเอนทิตีที่ตรงกันมันจะส่งคืนรูปแบบเป็นสตริง (รูปแบบ JSON สำหรับรูปแบบโทเค็น) ที่สร้างการแข่งขัน แอตทริบิวต์ Span ต่อไปนี้อ้างอิงแอตทริบิวต์โทเค็นที่รวมอยู่ในช่วง ทั้งหมดไม่เปลี่ยนรูป:
spaczz_ent : default = False บูลีนที่หมายถึงว่าโทเค็นทั้งหมดในช่วงเป็นส่วนหนึ่งของเอนทิตีที่กำหนดโดยผู้ปกครอง Spaczzspaczz_type : default = None สตริงที่แสดงว่าตัวจับคู่ใดผลิตเอนทิตีโดยใช้โทเค็นรวมspaczz_types : default = set() ชุดที่แสดงว่าตัวจับคู่ที่ผลิตเอนทิตีโดยใช้โทเค็นที่รวมอยู่ ช่วงเอนทิตีควรมีเพียงประเภทเดียว แต่สิ่งนี้ช่วยให้คุณเห็นประเภทที่รวมอยู่ในช่วงใด ๆspaczz_ratio : default = None หากโทเค็นทั้งหมดในช่วงเป็นส่วนหนึ่งของเอนทิตีที่ตรงกันมันจะส่งคืนอัตราส่วนฟัซซี่spaczz_pattern : default = None หากโทเค็นทั้งหมดในช่วงเป็นส่วนหนึ่งของเอนทิตีที่ตรงกันมันจะส่งคืนรูปแบบเป็นสตริง (รูปแบบ JSON สำหรับรูปแบบโทเค็น) ที่สร้างการแข่งขัน แอตทริบิวต์ Doc ต่อไปนี้อ้างอิงแอตทริบิวต์โทเค็นที่รวมอยู่ในเอกสาร ทั้งหมดไม่เปลี่ยนรูป:
spaczz_doc : default = False บูลีนที่หมายถึงถ้าโทเค็นใด ๆ ใน DOC เป็นส่วนหนึ่งของนิติบุคคลที่กำหนดโดยผู้ปกครอง Spaczzspaczz_types : default = set() ตั้งค่าที่แสดงว่าผู้จับคู่ที่ผลิตเอนทิตีในเอกสาร SpaczzRuler มีวิธีการเป็นของตัวเองถึง/จากดิสก์/ไบต์และจะยอมรับพารามิเตอร์ config ที่ส่งผ่านไปยัง spacy.load() นอกจากนี้ยังมีจุดเริ่มต้นของโรงงาน Spacy ของตัวเองดังนั้น Spacy จึงตระหนักถึง SpaczzRuler ด้านล่างเป็นตัวอย่างของการประหยัดและโหลดไปป์ไลน์ spacy ด้วยรุ่นภาษาอังกฤษขนาดเล็ก EntityRuler และ SpaczzRuler
import spacy
from spaczz . pipeline import SpaczzRuler
nlp = spacy . load ( "en_core_web_md" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.
Some of his favorite bands are Converg and Protet the Zero.""" # Spelling errors intentional.
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Anderson, Grint', 0, 3, 'ORG')
('555', 9, 10, 'CARDINAL')
('Apt 5', 14, 16, 'PRODUCT')
('Nashv1le', 17, 18, 'GPE')
('TN 55555-1234', 19, 23, 'ORG')
('USA', 25, 26, 'GPE')
('Converg', 34, 35, 'PERSON')
('Zero', 38, 39, 'CARDINAL')
ในขณะที่ Spacy ทำงานได้ดีในการระบุว่าเอนทิตีที่มีชื่อมีอยู่ในตัวอย่างนี้เราสามารถปรับปรุงการแข่งขันได้อย่างแน่นอนโดยเฉพาะอย่างยิ่งกับประเภทของฉลากที่ใช้
มาเพิ่มผู้ปกครองเอนทิตีสำหรับการจับคู่ตามกฎบางอย่าง
from spacy . pipeline import EntityRuler
entity_ruler = nlp . add_pipe ( "entity_ruler" , before = "ner" ) #spaCy v3 syntax
entity_ruler . add_patterns (
[{ "label" : "GPE" , "pattern" : "Nashville" }, { "label" : "GPE" , "pattern" : "TN" }]
)
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Anderson, Grint', 0, 3, 'ORG')
('555', 9, 10, 'CARDINAL')
('Apt 5', 14, 16, 'PRODUCT')
('Nashv1le', 17, 18, 'GPE')
('TN', 19, 20, 'GPE')
('USA', 25, 26, 'GPE')
('Converg', 34, 35, 'PERSON')
('Zero', 38, 39, 'CARDINAL')
เรากำลังคืบหน้า แต่แนชวิลล์สะกดผิดในข้อความดังนั้นผู้ปกครองนิติบุคคลไม่พบมันและเรายังคงมีหน่วยงานอื่น ๆ ในการแก้ไข/ค้นหา
ลองเพิ่มไม้บรรทัด Spaczz เพื่อปัดท่อนี้ออกมา นอกจากนี้เรายังจะรวมแอตทริบิวต์ spaczz_span ที่กำหนดเองในผลลัพธ์เพื่อแสดงว่าเอนทิตีใดถูกตั้งค่าผ่าน Spaczz
spaczz_ruler = nlp . add_pipe ( "spaczz_ruler" , before = "ner" ) #spaCy v3 syntax
spaczz_ruler . add_patterns (
[
{
"label" : "NAME" ,
"pattern" : "Grant Andersen" ,
"type" : "fuzzy" ,
"kwargs" : { "fuzzy_func" : "token_sort" },
},
{
"label" : "STREET" ,
"pattern" : "street_addresses" ,
"type" : "regex" ,
"kwargs" : { "predef" : True },
},
{ "label" : "GPE" , "pattern" : "Nashville" , "type" : "fuzzy" },
{
"label" : "ZIP" ,
"pattern" : r"b(?:55554){s<=1}(?:[-s]d{4})?b" ,
"type" : "regex" ,
}, # fuzzy regex
{
"label" : "BAND" ,
"pattern" : [{ "LOWER" : { "FREGEX" : "(converge){e<=1}" }}],
"type" : "token" ,
},
{
"label" : "BAND" ,
"pattern" : [
{ "TEXT" : { "FUZZY" : "Protest" }},
{ "IS_STOP" : True },
{ "TEXT" : { "FUZZY" : "Hero" }},
],
"type" : "token" ,
},
]
)
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ , ent . _ . spaczz_ent )) ('Anderson, Grint', 0, 3, 'NAME', True)
('555 Fake St,', 9, 13, 'STREET', True)
('Apt 5', 14, 16, 'PRODUCT', False)
('Nashv1le', 17, 18, 'GPE', True)
('TN', 19, 20, 'GPE', False)
('55555-1234', 20, 23, 'ZIP', True)
('USA', 25, 26, 'GPE', False)
('Converg', 34, 35, 'BAND', True)
('Protet the Zero', 36, 39, 'BAND', True)
สุดยอด! รุ่นภาษาอังกฤษขนาดเล็กยังคงทำผิดพลาดการจดจำเอนทิตีที่มีชื่อ ("5" ใน "Apt 5" เป็น CARDINAL ) แต่เราก็พอใจโดยรวม
มาบันทึกไปป์ไลน์นี้ลงในดิสก์และตรวจสอบให้แน่ใจว่าเราสามารถโหลดกลับได้อย่างถูกต้อง
import tempfile
with tempfile . TemporaryDirectory () as tmp_dir :
nlp . to_disk ( f" { tmp_dir } /example_pipeline" )
nlp = spacy . load ( f" { tmp_dir } /example_pipeline" )
nlp . pipe_names ['tok2vec',
'tagger',
'parser',
'attribute_ruler',
'lemmatizer',
'entity_ruler',
'spaczz_ruler',
'ner']
เรายังสามารถตรวจสอบให้แน่ใจว่ารูปแบบไม้บรรทัดทั้งหมดยังคงมีอยู่
spaczz_ruler = nlp . get_pipe ( "spaczz_ruler" )
spaczz_ruler . patterns [{'label': 'NAME',
'pattern': 'Grant Andersen',
'type': 'fuzzy',
'kwargs': {'fuzzy_func': 'token_sort'}},
{'label': 'GPE', 'pattern': 'Nashville', 'type': 'fuzzy'},
{'label': 'STREET',
'pattern': 'street_addresses',
'type': 'regex',
'kwargs': {'predef': True}},
{'label': 'ZIP',
'pattern': '\b(?:55554){s<=1}(?:[-\s]\d{4})?\b',
'type': 'regex'},
{'label': 'BAND',
'pattern': [{'LOWER': {'FREGEX': '(converge){e<=1}'}}],
'type': 'token'},
{'label': 'BAND',
'pattern': [{'TEXT': {'FUZZY': 'Protest'}},
{'IS_STOP': True},
{'TEXT': {'FUZZY': 'Hero'}}],
'type': 'token'}]
เหตุผลหลักสำหรับความเร็วที่ช้ากว่าของ Spaczz คือ C ในชื่อของมันไม่ได้เป็นตัวพิมพ์ใหญ่เหมือนอยู่ใน Spa C y Spaczz เขียนด้วย Pure Python และในปัจจุบันผู้จับคู่ไม่ได้ใช้คำศัพท์ภาษา Spacy ซึ่งหมายถึงการติดตามตรรกะของมันควรเป็นเรื่องง่ายสำหรับผู้ที่คุ้นเคยกับ Python อย่างไรก็ตามนี่หมายความว่าส่วนประกอบของ Spaczz จะทำงานช้าลงและน่าจะใช้หน่วยความจำได้มากกว่าเครื่องรางของพวกเขาโดยเฉพาะอย่างยิ่งเมื่อมีการเพิ่มรูปแบบมากขึ้นและเอกสารจะยาวขึ้น ดังนั้นจึงขอแนะนำให้ใช้ส่วนประกอบ Spacy เช่น EntityRuler สำหรับเอนทิตีที่มีความไม่แน่นอนเพียงเล็กน้อยเช่นข้อผิดพลาดในการสะกดคำที่สอดคล้องกัน ใช้ส่วนประกอบ Spaczz เมื่อไม่มีทางเลือกในการใช้พื้นที่
ตอนนี้ฉัน ไม่ได้ ทำงานเกี่ยวกับการเพิ่มประสิทธิภาพประสิทธิภาพให้กับ Spaczz แต่ยินดีต้อนรับคำแนะนำอัลกอริทึมและการเพิ่มประสิทธิภาพ
วิธีการหลักในการเร่งความเร็ว FuzzyMatcher และ SimilarityMatcher คือการลดพารามิเตอร์ flex เป็น 0 หรือถ้า flex > 0 เพิ่มพารามิเตอร์ min_r1 ไปยังค่าของ min_r2 และ/หรือลดพารามิเตอร์ thresh ไปยัง min_r2 โปรดทราบว่า "ความเร็ว" ทั้งหมดเหล่านี้มาพร้อมกับค่าใช้จ่ายโอกาสของการแข่งขันที่ดีขึ้น
ดังที่ได้กล่าวไว้ในคำอธิบาย SimilarityMatcher การใช้ GPU อาจช่วยเพิ่มความเร็วในการจับคู่กระบวนการ
ฉันมักจะเปิดกว้างและเปิดกว้างต่อการร้องขอ แต่เพียงระวังตัวในฐานะเดี่ยวที่มีเหลืออยู่มากมายในการเรียนรู้การพัฒนาสามารถเคลื่อนไหวได้ช้า ต่อไปนี้เป็นแผนงานของฉันสำหรับ Spaczz เพื่อให้คุณสามารถดูว่าปัญหาที่เกิดขึ้นอาจเหมาะสมกับลำดับความสำคัญปัจจุบันของฉัน
หมายเหตุ: ในขณะที่ฉันต้องการให้ spaczz ทำงานได้ แต่ฉัน ไม่ได้ พัฒนาอย่างแข็งขัน ฉันพยายามตอบสนองต่อปัญหาและคำขอ แต่โครงการนี้ไม่ได้เป็นจุดสนใจของฉันในปัจจุบัน
ลำดับความสำคัญสูง
การปรับปรุง
ยินดีต้อนรับการร้องขอและผู้มีส่วนร่วม
Spaczz เป็นผ้าสำลีด้วย Flake8 ที่จัดรูปแบบด้วยสีดำที่ตรวจสอบประเภทด้วย mypy (แม้ว่าสิ่งนี้จะได้รับประโยชน์จากความจำเพาะที่ได้รับการปรับปรุง) ทดสอบด้วย pytest อัตโนมัติด้วย NOx และสร้าง/บรรจุด้วยบทกวี มีเครื่องมือการพัฒนาอื่น ๆ อีกสองสามรายที่มีรายละเอียดใน noxfile.py พร้อมด้วยตะขอล่วงหน้าของ Git
เพื่อมีส่วนร่วมในการพัฒนาของ Spaczz ให้แยกพื้นที่เก็บข้อมูลจากนั้นติดตั้ง Spaczz และมันก็ขึ้นอยู่กับการพึ่งพาบทกวี หากคุณสนใจที่จะเป็นผู้สนับสนุนปกติโปรดติดต่อฉันโดยตรง
poetry install # Within spaczz's root directory.ฉันเก็บ NOX และล่วงหน้าก่อนสภาพแวดล้อมบทกวีของฉันซึ่งเป็นส่วนหนึ่งของสภาพแวดล้อม Python Toolchain ของฉัน ด้วยการติดตั้งล่วงหน้าล่วงหน้าคุณอาจต้องเรียกใช้ด้านล่างเพื่อทำการเปลี่ยนแปลง
pre - commit install แพ็คเกจอื่น ๆ เท่านั้นที่จะไม่ได้รับการติดตั้งผ่านบทกวี แต่ใช้สำหรับการทดสอบและตัวอย่างในเอกสารคือโมเดลภาษาอังกฤษขนาดกลาง Spacy ( en-core-web-md ) สิ่งนี้จะต้องติดตั้งแยกต่างหาก คำสั่งด้านล่างควรทำเคล็ดลับ:
poetry run python - m spacy download "en_core_web_md"