ABIS Infor - 2016-06
Perl Text Analytics
Samenvatting
Op het Internet vinden we enorme hoeveelheden (tekst)gegevens: zeer belangrijk en nuttig om er "iets" mee te doen, ook in de context van "business intelligence", als we niet het risico willen lopen iets essentieels te missen. Alleen... de grote volumes en enorme diversiteit van deze data maken het bijzonder moeilijk om zinvol aan Text Analytics te doen. Misschien biedt de programmeertaal Perl hier een interessante meerwaarde?
Text analytics en Big Data
Iedereen is tegenwoordig aan de slag met "Big Data", maar wat velen niet weten is dat de term niet zozeer slaat op grote datavolumes dan wel op het snel kunnen opzetten van data-analyse, vooral als de binnenkomende data niet beantwoorden aan een vooraf opgezette formele (database-)structuur, en/of variabel & variërend zijn in structuur, of aan hoog tempo binnenkomen en daarom niet kunnen worden opgeslagen.
Wie meer wil weten over wat precies Big Data is, verwijzen we naar onze cursus "Big Data Concepten"1.
Een populair speciaal geval van data-analyse betreft de analyse van (doorlopende) tekst, b.v. Twitter-berichten, web-blogs, krantenartikels, emails, noem maar op. Tekst-analytics beogen meestal het (snel) extraheren van relevante elementen uit de tekst, b.v. het detecteren van gemoedsgesteldheden (boos, enthousiast, ...), het rubriceren van de tekst, of het samenvatten van de essentiële informatie. Dit wordt NLP (natural language processing) genoemd.
Perl en het verwerken van datastromen
Perl is een bijzondere programmeertaal: enerzijds kan een Perl-programma zeer efficiënt een aantal "low-level" operaties uitvoeren, op het niveau van het besturingssysteem: bestanden en datastomen lezen/schrijven, subprocessen lanceren, system calls uitvoeren; anderzijds is de syntax verrassend "high-level": datastructuren zoals dynamische lijsten, associatieve arrays en hiërarchische structuren; en programma-structuren (iteraties, conditionele uitvoering, functie-oproepen) kunnen op een zeer "natuurlijke" manier geformuleerd worden, bijna als een natuurlijke taal. Niet toevallig is de bedenker van Perl, Larry Wall, een linguïst!
Het inlezen en continu verwerken van een datastroom, al dan niet reeds voor-gesegmenteerd in regels (dus End-Of-Line gescheiden blokken) is zo'n standaard activiteit. Perl maakt het syntactisch zeer eenvoudig om dit leesbaar te formuleren, terwijl anderzijds de "runtime" zo efficiënt is alsof het in assembler zou uitgeschreven zijn.
Een eenvoudig voorbeeld: weerhoud alleen de voldoende lange regels van de invoer (b.v. degene langer dan 20 tekens):
while (<>) { print if (length > 20); }
Een interessanter voorbeeld: schrijf de woordlengtes uit van alle woorden uit een tekst (b.v. om daarmee een histogram te maken van woordlengtes, b.v. ter voorbereiding van schrijfstijl-analyse):
$/ = ' '; while (<>) { print length . "\n"; }
Of nog beter, dadelijk de aantallen woorden van een bepaalde lengte (het histogram zelf dus) door Perl laten genereren:
$/=' '; while(<>){$c{length($_)}++;} foreach (keys %c) {print "$_\t$c{$_}\n";}
De eerste toekenning herdefinieert de "record separator" zodat nu per woord gelezen wordt. Eigenlijk is dit te beperkt, want tekst bevat niet altijd één enkele spatie tussen twee woorden. De tekst zou dus eerst voorverwerkt moeten worden door een ander Perl-programma dat alle "woord-separatoren" (groepje blanco's of leestekens) vervangt door één enkele spatie:
while (<>) { s/\W+/ /g; print; }
Regular expressions
De "\W+" hierboven is alvast een goed voorbeeld van een zogenaamde reguliere expressie: een beschrijving van een "tekstpatroon", in dit geval: "één of meer spaties of leestekens". De "RegExp"-taal is zeer krachtig, zij het nogal cryptisch voor de leek. Reguliere expressies kunnen ook buiten Perl op veel plaatsen gebruikt worden. Het mooie is, vergeleken met die andere RegExp-gebruikers, dat deze 'taal' ingebouwd is in Perl, en dus zeer efficiënt afgehandeld wordt. In een Text Analytics context zijn reguliere expressies onmisbaar voor het snel en flexibel 'parsen' van binnenkomende data.
Een relatief simpel voorbeeld: we willen weten of een tekst datums bevat. Nu zijn er natuurlijk veel mogelijke manieren om een datum te schrijven, maar stel dat we ons beperken tot de formaten 15 jun 2016, 15/06/2016 en 2016-06-15. Het volgende Perl-programma meldt "datum gevonden" indien dit zo is, en zwijgt anders:
@mnd = qw('jan feb mar apr may jun jul aug sep oct nov dec');
while (<>) { &found if ( m!\b[0-3]\d/[01]\d/20\d\d\b! or m!\b20\d\d-[01]\d-[0-3]\d\b!); foreach $m (@mnd) { &found if (m/\b[0-3]\d $m 20\d\d\b/i); } } sub found { print 'datum gevonden'; exit 0; }
Op gelijkaardige manieren kan er relatief eenvoudig en efficiënt gezocht worden naar andere "patronen" zoals gemoedsgesteldheden (op basis van een "woordenboek" van gevoelstermen, en een minimale syntactische parser die woorden als "niet", "vooral", "zelden" enz. naar waarde kan schatten). Het benodigde Perl-programma wordt al snel een stuk complexer, maar blijft zeer efficiënt en toch nog altijd zeer leesbaar dankzij de mooie, compacte syntax van Perl.
Meer over Perl in onze basiscursus "Programmeren in Perl"2.
Perl als bindmiddel
Naast de mogelijkheid van het volledig in Perl implementeren van een (text analytics) algoritme, is Perl vooral zeer geschikt om bestaande software aan elkaar te lijmen: waarom het wiel terug uitvinden, als iemand dit al op een optimale manier gedaan heeft? Het praktische probleem is dan meestal het met elkaar doen "praten" van verschillende oplossingen voor deelproblemen: zoals b.v. Hadoop voor data-opslag en Map-Reduce; R voor statistische visualisatie; Google Earth voor geografische visualisatie, en noem maar op. Elk van deze tools verwacht input in een bepaald formaat, verwacht te kunnen draaien in een bepaalde "setup", schrijft z'n resultaten weg op een zeer specifieke manier, ...
Perl is dan de ideale partner: één of meer kleine Perl-programmaatjes linken de verschillende componenten aan elkaar, streamen de data tussen data-verwerkers, en converteren waar nodig van het ene formaat naar het andere.
Ook die iets complexere functionaliteit die je binnen Perl wil afhandelen, hoef je meestal niet zelf te implementeren: Perl heeft een zeer uitgebreide bibliotheek (bestaande uit zgn. modules) die van CPAN3 kunnen gedownloaded worden. Eén van de interessantste Perl-modules in de context van data-processing is DBI: de ODBC-style Database Interface (die we in onze cursus "ODBC met Perl"4 behandelen), waarmee relationele databases maar ook b.v. CSV-files kunnen gelezen en gewijzigd worden. Verder zijn er modules die alvast een aantal Text Analytics functionaliteiten aanbieden, zoals b.v. Search::QueryParser die toelaat een tekst te doorzoeken met flexibele "ongeveer"-zoektermen zoals die van Google Search.
Besluit
Vergeet zeker Perl niet bij het uitbouwen van uw Big Data infrastructuur, vooral dan wanneer Text Analytics aan de orde is!
Referenties: