Výukový program Python: Fuzzy algoritmy zodpovedajúce názvu

Blog

Ako sa vyrovnať s variabilitou a komplexnosťou premenných mien osôb používaných ako identifikátory.



Toto je piaty článok našej cesty do sveta prieskumu údajov Pythonu. Zoznam publikovaných článkov, ktoré môžete nájsť tu (a zdrojový kód tu ). Začnime teda.






Metódy priradenia mien

V súboroch štatistických údajov získavaných z verejných zdrojov sa s menami (osoby) často zaobchádza rovnako ako s metadátami pre iné pole, ako je e -mail, telefónne číslo alebo identifikačné číslo. To je prípad našich ukážkových sád:



Keď sú názvy jediným zjednocujúcim údajovým bodom, správna zhoda s podobnými názvami nadobúda na dôležitosti, avšak ich variabilita a zložitosť robia z priraďovania mien jedinečne náročnú úlohu. Prezývky, chyby v preklade, viacnásobné hláskovanie s rovnakým názvom a ďalšie môžu mať za následok zmeškané zápasy. ( rosette.com )

S touto situáciou sa teraz stretávame:



Náš súbor údajov twitter obsahuje a názov premennú, ktorú si nastavuje samotný používateľ Twitteru. V závislosti od preferencií osoby to môže byť






  • úplné umelé meno
  • priezvisko, priezvisko (alebo naopak)
  • iba priezvisko
  • skratka isté meno, skratka stredné meno, priezvisko
  • jeho úplné meno, ale omylom urobil niekoľko preklepov
  • atď. atď. atď.

To nám ponecháva určité problémy s kvalitou údajov a normalizáciou, ktoré musíme riešiť, aby sme ich mohli používať názov atribút ako zodpovedajúci identifikátor.

Niektoré z výziev - ako aj naša stratégia, ako ich chceme riešiť - sú popísané v nasledujúcej tabuľke. Každá z metód použitých na riešenie výzvy bude vysvetlená v tomto článku a je súčasťou Zdrojový kód tutoriálu Github .

Začnime teda riešením výzvy Tituly a honorifikáty , Chýbajúce komponenty, a najskôr niektoré ďalšie anomálie.

Sme šťastní, že náš zoznam je zvládnuteľný z hľadiska mnohých záznamov, tj. Môžeme vykonať manuálnu kontrolu anomálií a názvov použitých v atribúte Name.

Názov Cleanser Step

Náš prieskum kvality ukazuje, že pole Názov má zrejme dobrú kvalitu (nepoužívajú sa žiadne atrapy ani prezývky). Našli sme však niektoré anomálie, ako je uvedené nižšie:

reagovať natívny rozbaľovací zoznam

Tieto anomálie v našom programe opravujeme v prvom kroku čistenia. Aby sme zostali generickí, znova použijeme náš konfiguračný súbor yaml a pridáme ďalšie dva parametre.

  • twitterNameCleaner Skladá sa zo zoznamu kľúčových slov, ktoré je potrebné odstrániť z ľubovoľného názvu účtu twitter
  • twitterNamesExpander ktorý rozšíri každý podreťazec skratky názvu účtu Twitter na reťazec celého mena.

Náš súbor yaml pre konkrétnu krajinu je rozšírený o nasledujúce položky.

pytest

Krok čistenia sa nazýva nižšie uvedená metóda, ktorá hodnotí každý riadok našej twitterovej tabuľky (jeho integrácia do programu je vysvetlená neskôr)

def test_double_metaphone(self): tp1 = double_metaphone(u'LilianeMauryPasquier') tp2 = double_metaphone(u'liliane Maury Pasquier') assert True == double_metaphone_compare(tp1,tp2,Threshold.STRONG) tp1 = double_metaphone(u'L. Maury Pasquier') tp2 = double_metaphone(u'liliane Maury Pasquier') assert False == double_metaphone_compare(tp1,tp2,Threshold.STRONG) tp1 = double_metaphone(u'Marta Flückiger-Bäni') tp2 = double_metaphone(u'Marta Fluckiger-Bani') assert True == double_metaphone_compare(tp1,tp2,Threshold.STRONG) tp1 = double_metaphone(u'Marta Flückiger-Bäni') tp2 = double_metaphone(u'Marta Flükger-Bäni') assert True == double_metaphone_compare(tp1,tp2,Threshold.NORMAL)

Docela jednoduché pomocou reťazca nahradiť metódu

  • odstránime každé kľúčové slovo nájdené v súbore twitterNameCleaner zoznam z názov atribút (nahraďte ho „“)
  • nahrádzame každú skratku nachádzajúcu sa v twitterNamesExpander slovník prostredníctvom jeho celého názvu.

Pre náš ďalší normalizačný krok predstavujeme prístup, ktorý má svoj pôvod v čase, keď bola Amerika pred 100 rokmi konfrontovaná s obrovskou vlnou prisťahovalcov.

Algoritmus dvojitého metafónu

Princíp algoritmu siaha do minulého storočia, vlastne do roku 1918 (keď bol prvý počítač vzdialený roky).

Rovnako ako vedľajšie informácie (ak by ste sa niekedy zúčastnili milionárskej kvízovej show), prvý počítač bol vzdialený 23 rokov

Z3 bol nemecký elektromechanický počítač navrhnutý Konradom Zuseom. Bol to prvý pracovný programovateľný, plne automatický digitálny počítač na svete. Z3 bol vyrobený s 2 600 relémi, ktoré implementovali 22-bitovú dĺžku slova a pracovali na taktovacej frekvencii asi 4–5 Hz. Programový kód bol uložený na dierovaný film. Počiatočné hodnoty boli zadané ručne ( Wikipedia )

Takže späť do roku 1918, v tom roku Robert C. Russell z amerického úradu pre sčítanie ľudu vynašiel algoritmus Soundex, ktorý je schopný indexovať anglický jazyk spôsobom, že len zbežným pohľadom je možné nájsť viacero hláskovaní s rovnakým názvom.

Imigranti do USA mali rodný jazyk, ktorý nevychádzal z rímskych znakov. Pri písaní svojich mien, mien svojich príbuzných alebo miest, z ktorých prišli, museli prisťahovalci čo najlepšie odhadnúť, ako vyjadriť svoj symbolický jazyk v angličtine. Vláda Spojených štátov si uvedomila potrebu byť schopná kategorizovať mená súkromných osôb spôsobom, ktorý umožní zoskupenie viacerých hláskovaní rovnakého mena (napr. Smith a Smythe). (prečítajte si celý príbeh tu )

Algoritmus Soundex je založený na fonetickej kategorizácii písmen abecedy. Russell vo svojom patente popisuje stratégiu priradenia číselnej hodnoty každej kategórii. Napríklad Johnson bol mapovaný na J525, Miller na M460 atď.

Algoritmus Soundex sa v priebehu času vyvíjal v kontexte účinnosti a presnosti a bol nahradený inými algoritmami.

Väčšinou boli všetky nahradené výkonným indexovacím systémom tzv Dvojitý metafón . Algoritmus je k dispozícii ako open source a jeho posledná verzia bola vydaná okolo roku 2009.

Našťastie existuje knižnica Pythonu k dispozícii , ktoré používame v našom programe. Okolo algoritmu napíšeme niekoľko malých obalových metód a implementujeme porovnávaciu metódu.

The doublemetafón metóda vráti n -ticu dvoch kľúčov znakov, ktoré sú fonetickým prekladom odovzdaného slova. Náš porovnať metóda ukazuje celkom obmedzenú schopnosť poradia algoritmu.

twitterNameCleaner: ['Dr.','Zürich'] twitterNamesExpander: - abbreviation: 'Chr.' name: 'Christophe' 

Vykonajme niekoľko overovacích kontrol na vyhodnotenie účinnosti algoritmu zavedením test_class.py ktorý je založený na Pythone pytest rámec.

| _+_ | framework uľahčuje písanie malých testov, ale škály na podporu komplexného funkčného testovania aplikácií a knižníc. ( Odkaz )

Jeho použitie je jednoduché a implementáciu testovacej triedy môžete vidieť nižšie

def __calculate_name_matching(self, row): name = row['Name'] for clean in self.__cfg['twitterNameCleaner']: name = name.replace(clean ,'') for expand in self.__cfg['twitterNamesExpander']: name = name.replace(expand.get('abbreviation'), expand.get('name')) 

Výsledky testov sú uvedené nižšie. Použili sme dva názvy (A+B) a pomocou niektorých zmenených názvov (A1/A2+B1/B2/B3) sme kontrolovali účinnosť algoritmu.

  • A1+B1 prešlo kontrolou silných zápasov. Zdá sa teda, že chýbajúce medzery a náhrady ü/ä za u/a neovplyvňujú generovanie kľúča dvojitého metafónu
  • B2 prechádza normálnym zápasom. Algoritmus zahŕňa aj pravopisné chyby
  • A2 + B3 zlyhávajú. A2 používa skratku časti názvu, s ktorou sa nedá vyrovnať. Toto správanie sme museli očakávať a rozhodli sme sa zaviesť algoritmus expandéra mien (pozri vyššie). B3 zlyhal z dôvodu chýbajúceho -. Toto bolo neočakávané, ale toto správanie pokrývame krokom čistenia druhého mena.

Názov Cleanser Krok 2

Náš malý testovací beh ukázal, že nasledujúce ďalšie kroky čistenia sú prospešné:

  • Musíme sa zbaviť akéhokoľvek špeciálneho charakteru, ktorý by mohol viesť k zlyhaniu
  • Komponenty mimo poradia, tj. Priezvisko pred krstným menom ovplyvňuje generovanie fonetického kľúča. Na zvýšenie presnosti párovania je preto najlepšie zoradiť komponenty podľa abecedy.

Okrem toho, že sa zbavíme akéhokoľvek špeciálneho znaku, rozhodneme sa odstrániť akýkoľvek znak Unicode, tj. Vo Švajčiarsku sa používa viacnásobná nemecká (ä, ö, ü), francúzska (à, é, è) alebo talianska prehláska a chceme sa zbaviť aj z nich.

Nižšie normalize_unicode_to_ascii metóda používa unicodedata libraryto previesť názov na ASCII a potom zmeniť všetky znaky na malé písmená. Potom sa pomocou dvoch regulárnych výrazov odstránia špeciálne znaky, ako aj viac medzier.

Operácie s regulárnym výrazom sú výkonným mechanizmom, ale pre nováčikov nie sú ľahko pochopiteľné. Môžete pracovať prostredníctvom nasledujúci návod aby ste získali prvý dojem z tohto silného prístupu.

  • Len jedno vysvetlenie, výraz regulárneho výrazu „[^ A-Za-z0–9] +“ znamená, že z odovzdaného reťazca je vylúčený ľubovoľný počet znakov medzi „A-Z“ + „a-z“ + „0–9“ + „“. ^[]+ sú špeciálne znaky v regulárnom výraze. Sekvenciu výrazu je možné preložiť, aby bol reťazec zbavený akéhokoľvek špeciálneho znaku.
# -*- coding: utf-8 -*- from metaphone import doublemetaphone from enum import Enum 

class Threshold(Enum):
WEAK = 0
NORMAL = 1
STRONG = 2

def double_metaphone(value):
print(doublemetaphone(value))
return doublemetaphone(value)

#(Primary Key = Primary Key) = Strongest Match
#(Secondary Key = Primary Key) = Normal Match
#(Primary Key = Secondary Key) = Normal Match
#(Alternate Key = Alternate Key) = Minimal Match
def double_metaphone_compare(tuple1,tuple2,threshold):
if threshold == Threshold.WEAK:
if tuple1[1] == tuple2[1]:
return True
elif threshold == Threshold.NORMAL:
if tuple1[0] == tuple2[1] or tuple1[1] == tuple2[0]:
return True
else:
if tuple1[0] == tuple2[0]:
return True
return False

Metóda krásy Krása dátového rámca

V oboch triedach založte metódu __calculate_name_matching

Teraz máme všetky naše metódy čistenia názvov, normalizácie a fonetického kľúča k dispozícii (súčasťou balíka namemachting.py modul) a môže konečne vytvoriť naše metódy vytvárania identifikátorov zodpovedajúcich identifikátorom __ count_name_matching pre naše dve triedy govAPI a GovernmentSocialMediaAnalyzer.

Obe triedy dostanú novú metódu, ktorú aplikujeme na ich dátové rámce Panda a každá metóda vytvorí tri nové atribúty identifikátora ( col_match1, col_match2, col_match3 ). Tri stĺpce potom možno použiť na zlúčenie dvoch dátových rámcov.

Metóda pre našich GovernmentAPI trieda vyzerá nasledovne:

# -  - coding: utf-8 -  -  
import pytest
from name_matching import double_metaphone,double_metaphone_compare, Threshold

class TestClass(object):

|_+_|

Takže pre našich govAPI triedy nasledovne. Je to implementovaná metóda v našej abstraktnej triede. Metóda sa používa pre akúkoľvek implementovanú podtriedu (pozrite si továrenské riešenie vysvetlené v našom článku predchádzajúci návod )

# -  - coding: utf-8 -  -  
import re
import unicodedata

def normalize_unicode_to_ascii(data):
normal = unicodedata.normalize(‘NFKD’, data).encode(‘ASCII’, ‘ignore’)
val = normal.decode(utf-8)
val = val.lower()
# remove special characters
val = re.sub(‘[^A-Za-z0-9 ]+’, ’ ‘, val)
# remove multiple spaces
val = re.sub(’ +', ’ ', val)
return val

def sort_words(words):
words = words.split(' ')
words.sort()
newSentence = ' '.join(words)
return newSentence

Implementácia je jednoduchá, normalizujeme meno osoby v každej tabuľke (z vládneho rozhrania API sme získali tri nezávislé atribúty, z rozhrania Twitter API jeden názov účtu) a potom vypočítame dva reťazce identifikátorov dvojitého metafónu. Všetky tri nové hodnoty, ktoré pripájame k odovzdanému riadku.

Nevolajte nás, my vám hovoríme: hollywoodsky princíp

Jedna otázka je stále otvorená: Ako použijeme naše nové metódy na vylepšenie dátového rámca o tri stĺpce s jeho vypočítanými hodnotami pre každý riadok?

To sa dá celkom ľahko dosiahnuť pomocou Dátový rámec Panda uplatniť metóda, ktorá je definovaná ako:

apply () môže použiť funkciu pozdĺž akejkoľvek osi dátového rámca

Je to pekný a elegantný spôsob, ako vykonať akýkoľvek výpočet v každom riadku alebo stĺpci dátového rámca.

aktivovať locast na roku

Nižšie vidíte vylepšené create_politican_from_govapi_table metóda. Na kódovom riadku 4 novo voláme uplatniť metóda dátového rámca ( df ) a zadajte ako parameter názov našej metódy seba. count_name_matching a dajte pokyn uplatniť metóda na zavolanie našej metódy pre každý riadok ( os = 1 ).

 def __calculate_name_matching(self, row):  
name = row[‘lastName’]+’ ‘+row[‘firstName’]+’ ‘+row[‘middleName’]
norm_name = sort_words(normalize_unicode_to_ascii(name))
tp = double_metaphone(norm_name)
row[‘col_match1’] = norm_name
row[‘col_match2’] = tp[0]
row[‘col_match3’] = tp[1]
return row

Teraz dátový rámec Panda

  • iteruje každým radom údajov, ktorý predstavuje údajový záznam špecializovaného politika
  • volá náš seba. count_name_matching metóda
  • prechádza v dátovom riadku ako parameter a ukladá späť dátový riadok vrátený volaním metódy (ktoré tri nové stĺpce).

Veľmi šikovné nie? Nemuseli sme kódovať žiadne slučky, ktoré načítavajú údaje, kontrolujú podmienky konca slučky a podobne. Práve sme implementovali metódu, ktorú je možné odovzdať do súboru uplatniť metóda.

Tento druh interakcie je dobre známy princíp dizajnu v IT, známy pod názvom Hollywood Principle, ktorý je vynikajúci blogový článok Matthew Meada popisuje nasledovne:

Podstatou tohto princípu je nevolajte nám, my vám zavoláme. Ako viete, toto je odpoveď, ktorú môžete počuť po konkurze na úlohu v hollywoodskom filme. A to je rovnaký koncept aj pre softvérový hollywoodsky princíp. Cieľom je starať sa o múdrosť štruktúrovania a implementácie vašich závislostí.

Zamyslite sa nad našou implementáciou vyššie. Náš __ count_name_matching metóda je úplne oddelená od implementácie dátového rámca pandy. Naša metóda dostane ako vstup iba slovník riadkov, s ktorým môžeme manipulovať a na konci ho môžeme vrátiť ako návratovú hodnotu. Sme si úplne vedomí toho, že existuje rozsiahla implementácia dátového rámca pandy, a nie sme na ňom nijako závislí.

Na svojej najzákladnejšej úrovni ide o zníženie spojky v softvérovom systéme. Vracia sa k známej fráze vo vývoji softvéru: voľné prepojenie a vysoká súdržnosť. Hodiny môžete viesť voľne spojený zabezpečením, že nebudete mať zbytočné referencie a budete správne odkazovať na triedy a iné subsystémy. Aj keď hollywoodsky princíp nediktuje nič o súdržnosti, je tiež dôležitým aspektom. Súdržnosť ide o to, aby vaše triedy boli verné svojmu zámeru a nedovolili, aby sa ich správanie rozšírilo nad rámec svojho hlavného účelu. Rovnako ako vysoká väzba, nízka súdržnosť nemá tendenciu spôsobiť, že systémy budú nestabilné alebo nefungujú správne, ale pravdepodobne povedie k problémom s údržbou softvéru.

Dosť dizajnu na dnes, keď spustíme náš program, obe sprisahané tabuľky politikov sú vylepšené o 3 nové atribúty, čo nám umožňuje ich konečne spojiť (uff ... dosť koncepčná práca, ktorú sme museli urobiť)


Nakoniec sa pripojte k dátovým rámcom

Teraz musíme spojiť dva dátové rámce, čo je jedna z mnohých možností kombinovania a spájania, ktoré Panda ponúka. Pozrite sa na nasledujúci článok od datacarpentry.org , čo je dobrý úvod do celkovej témy.

Ďalším spôsobom, ako skombinovať dátové rámce, je použiť stĺpce v každej množine údajov, ktoré obsahujú spoločné hodnoty (spoločný jedinečný identifikátor). Kombinácia dátových rámcov pomocou spoločného poľa sa nazýva spájanie. Stĺpce obsahujúce spoločné hodnoty sa nazývajú kľúč (y) spojenia. Pripojenie k DataFrame týmto spôsobom je často užitočné, keď je jeden DataFrame vyhľadávacou tabuľkou obsahujúcou ďalšie údaje, ktoré chceme zahrnúť do druhého.

To sa dosahuje pomocou choď metóda, ktorú je možné použiť na dátový rámec Panda (pozri riadok kódu 23 nižšie). Musíte zadať ako parametre

  • dva dátové rámce
  • zodpovedajúci kľúč (v našom prípade atribút dvojitý metafón col_match2 k dispozícii v oboch dátových rámcoch)
  • a stratégia spojenia ( ako parameter)
def __calculate_name_matching(self, row):  
name = row[‘Name’]
for clean in self.__cfg[‘twitterNameCleaner’]:
name = name.replace(clean ,’')
for expand in self.__cfg[‘twitterNamesExpander’]:
name = name.replace(expand.get(‘abbreviation’), expand.get(‘name’))
norm_name = sort_words(normalize_unicode_to_ascii(name))
tp = double_metaphone(norm_name)
row[‘col_match1’] = norm_name
row[‘col_match2’] = tp[0]
row[‘col_match3’] = tp[1]
return row

Označujeme vonkajšie ľavé spojenie ( ako = vľavo) ktoré je možné vizualizovať nasledovne

Vynechanie ako parameter by mal za následok vnútorné spojenie

Vnútorné spojenie znamená iba prevzatie zodpovedajúcich riadkov, Ľavé spojenie znamená prevzatie VŠETKÝCH riadkov ľavého dátového rámca. Ak neexistuje žiadny zodpovedajúci pravý tabuľkový záznam, vyplňte príslušný záznam hodnotami NaN.

Náš nový stôl Plotly CH-tw-politican-merged-list má taký druh záznamov.

To znamená, že našej stratégii párovania stále chýbajú položky. Porovnajme koláčový graf našej zlúčenej tabuľky s pôvodnou:

Ten pôvodný (pozrite sa na to článok ) minul 51, s našou jednoduchou stratégiou zlúčenia sme mohli identifikovať ďalších 14 záznamov.

Ešte tam nie sme (argh ...), ale na dnes toho dosť, v ďalšej relácii sa pokúsime prispôsobiť našu stratégiu párovania, aby sme ešte raz mohli znížiť neznáme.

Zdrojový kód nájdete v príslušnom Projekt Github , zoznam všetkých ostatných článkov tu .

Pôvodne publikoval Felix Kuestahler na https://towardsdatascience.com

Uč sa viac

Strojové učenie, dátová veda a hlboké učenie s Pythonom

Naučte sa programovať v Pythone: Podrobný návod

Rozpoznanie AWS: Strojové učenie pomocou majstrovskej triedy Python

Strojové učenie pomocou Pythonu - príručka pre začiatočníkov

[2019] Bootcamp s klasifikáciou strojového učenia v Pythone

Machine Learning A-Z ™: Praktický Python a R v dátovej vede

#python #strojové učenie

tlačidlo netgear ac1200 wps

smerom kdatascience.com

Výukový program Python: Fuzzy algoritmy zodpovedajúce názvu

Ako sa vyrovnať s variabilitou a komplexnosťou premenných mien osôb používaných ako identifikátory.