Sådan udtrækkes nøgleord fra tekst med TF-IDF og Pythons Scikit-Learn

Tilbage i 2006, da jeg skulle bruge TF-IDF til nøgleordsekstraktion i Java, endte jeg med at skrive al koden fra bunden. Hverken datalogi eller GitHub var noget dengang, og bibliotekerne var bare begrænsede.

Verden er meget anderledes i dag. Du har adskillige biblioteker og open-source kodelager på Github, der giver en anstændig implementering af TF-IDF. Hvis du ikke har brug for meget kontrol over, hvordan TF-IDF-matematikken beregnes, anbefaler jeg stærkt, at du genbruger biblioteker fra kendte pakker som Sparks MLLib eller Pythons scikit-learning.

Det eneste problem , jeg bemærkede med disse biblioteker, er at de er ment som et forløb for andre opgaver som klyngedannelse, emnemodellering og tekstklassificering. TF-IDF kan faktisk bruges til at udtrække vigtige nøgleord fra et dokument for at få en fornemmelse af, hvad der karakteriserer et dokument. For eksempel, hvis du har at gøre med Wikipedia-artikler, kan du bruge tf-idf til at udtrække ord, der er unikke for en given artikel. Disse nøgleord kan bruges som et meget simpelt resume af et dokument og til tekstanalyse, når vi ser på disse nøgleord samlet.

I denne artikel vil jeg vise dig, hvordan du kan bruge scikit-lær til at udtrække nøgleord fra dokumenter ved hjælp af TF-IDF. Vi gør specifikt dette på et stackoverløbsdatasæt. Hvis du vil have adgang til den fulde Jupyter Notebook , skal du gå over til min repo.

Vigtig note: Jeg antager, at folk, der følger denne tutorial, allerede er fortrolige med begrebet TF-IDF. Hvis du ikke er det, skal du gøre dig bekendt med konceptet, før du læser videre. Der er et par videoer online, der giver en intuitiv forklaring på, hvad det er. For en mere akademisk forklaring vil jeg anbefale min ph.d.-rådgivers forklaring.

Datasæt

I dette eksempel bruger vi et Stack Overflow-datasæt, der er lidt støjende og simulerer, hvad du måske har at gøre med i det virkelige liv. Du kan finde dette datasæt i min tutorial repo.

Bemærk, at der er to filer . Den større fil stackoverflow-data-idf.jsonmed 20.000 indlæg bruges til at beregne den inverse dokumentfrekvens (IDF). Den mindre fil stackoverflow-test.jsonmed 500 indlæg ville blive brugt som et testsæt for os til at udtrække nøgleord fra. Dette datasæt er baseret på den offentligt tilgængelige Stack Overflow-dump fra Googles Big Query.

Lad os kigge på vores datasæt. Koden nedenfor læser en json-streng pr. Linje data/stackoverflow-data-idf.jsonind i en pandadataramme og udskriver dens skema og det samlede antal indlæg.

Her lines=Truebetyder det simpelthen, at vi behandler hver linje i tekstfilen som en separat json-streng.

Bemærk, at dette Stack Overflow-datasæt indeholder 19 felter inklusive posttitel, body, tags, datoer og andre metadata, som vi ikke har brug for til denne tutorial. Til denne tutorial er vi mest interesserede i kroppen og titlen. Disse bliver vores tekstkilde til nøgleordsudtrækning.

Vi opretter nu et felt, der kombinerer begge dele, bodyog titleså har vi de to i et felt. Vi udskriver også den anden tekstindtastning i vores nye felt bare for at se, hvordan teksten ser ud.

Åh, dette ser ikke særlig læsbart ud! Nå, det er på grund af al rengøringen, der fortsatte pre_process(..). Du kan gøre en masse flere ting i pre_process(..), såsom at fjerne alle kodeafsnit og normalisere ordene til dens rod. For enkelheds skyld udfører vi kun en mild forbehandling.

Oprettelse af ordforråd og ordtælling for IDF

Vi er nu nødt til at oprette ordforrådet og starte tællingsprocessen. Vi kan bruge CountVectorizer til at oprette et ordforråd ud fra al tekst i vores df_idf['text'], efterfulgt af antallet af ord i ordforrådet:

Resultatet af de sidste to linjer fra koden ovenfor er en sparsom matrixrepræsentation af optællingerne. Hver kolonne repræsenterer et ord i ordforrådet. Hver række repræsenterer dokumentet i vores datasæt, hvor værdierne er ordtællinger.

Bemærk, at antallet af ord med denne repræsentation kan være 0, hvis ordet ikke vises i det tilsvarende dokument.

Her sender vi to parametre til CountVectorizer max_dfog stop_words. Den første er bare at ignorere alle ord, der er vist i 85% af dokumenterne, da disse kan være uvigtige. Det senere er en brugerdefineret liste over stopord. Du kan også bruge stopord, der er hjemmehørende i sklearn, ved at indstille stop_words='english'. Stopordslisten, der bruges til denne vejledning, kan findes her.

Den resulterende form af word_count_vectorer (20000,124901), da vi har 20.000 dokumenter i vores datasæt (rækkerne) og ordforrådets størrelse er 124.901.

I nogle applikationer til tekstudvinding, såsom klyngedannelse og tekstklassificering, begrænser vi typisk ordforrådets størrelse. Det er virkelig nemt at gøre dette ved at indstille, max_features=vocab_sizenår CountVectorizer startes. Lad os til denne vejledning begrænse vores ordforrådsstørrelse til 10.000:

Lad os nu se på 10 ord fra vores ordforråd:

['serializing', 'private', 'struct', 'public', 'class', 'contains', 'properties', 'string', 'serialize', 'attempt']

Søde, disse er for det meste programmeringsrelaterede.

TfidfTransformer til beregning af IDF

Det er nu tid til at beregne IDF-værdierne.

I koden nedenfor tager vi i det væsentlige den sparsomme matrix fra CountVectorizer ( word_count_vector) for at generere IDF, når du påberåber sig fit(...):

Ekstremt vigtigt punkt : IDF skal altid være baseret på et stort korpus og skal være repræsentativt for tekster, du vil bruge til at udtrække nøgleord. Jeg har set flere artikler på Internettet, der beregner IDF ved hjælp af en håndfuld dokumenter. Du vil besejre hele formålet med IDF-vægtning, hvis det ikke er baseret på et stort korpus som:

  1. dit ordforråd bliver for lille, og
  2. du har begrænset evne til at observere opførelsen af ​​ord, som du kender til.

Beregning af TF-IDF og udpakning af nøgleord

Når vi har beregnet vores IDF, er vi klar til at beregne TF-IDF og derefter udtrække topnøgleord fra TF-IDF-vektorerne.

I dette eksempel udtrækker vi de bedste nøgleord for spørgsmålene i data/stackoverflow-test.json. Denne datafil har 500 spørgsmål med felter identiske med dem, data/stackoverflow-data-idf.jsonsom vi så ovenfor. Vi starter med at læse vores testfil, udtrække de nødvendige felter - titel og brødtekst - og få teksterne til en liste.

Det næste trin er at beregne tf-idf-værdien for et givet dokument i vores testsæt ved at påkalde tfidf_transformer.transform(...). Dette genererer en vektor af tf-idf scores.

Derefter sorterer vi ordene i vektoren i faldende rækkefølge af tf-idf-værdier og gentages derefter for at udtrække top-n-nøgleordene. I eksemplet nedenfor udtrækker vi nøgleord til det første dokument i vores testsæt.

Den sort_coo(...)metode, som er sorterer værdierne i vektoren samtidig bevare søjleindekset. Når du først har kolonneindekset, er det virkelig nemt at slå den tilsvarende ordværdi op, som du ville se, extract_topn_from_vector(...)hvor vi gør feature_vals.append(feature_names[idx]).

Nogle resultater!

I dette afsnit vil du se stack overflow-spørgsmålet efterfulgt af de tilsvarende udpakkede nøgleord.

Spørgsmål om Eclipse Plugin-integration

Ud fra ovenstående nøgleord, de øverste nøgleord faktisk giver mening, den taler om eclipse, maven, integrate, war, og tomcat, som alle er unikke for dette specifikke spørgsmål.

Der er et par nøgleord, der kunne have været fjernet, som possibilityog måske endda project. Du kan gøre dette ved at tilføje flere almindelige ord til din stopliste. Du kan endda oprette dit eget sæt stopliste, meget specifikt for dit domæne.

Lad os nu se på et andet eksempel.

Spørgsmål om SQL-import

Selv med alle html-tags er vi i stand til at udtrække nogle smukke søgeord på grund af forbehandlingen her. Det sidste ord appropriatelyville være et stopord. Du kan fortsætte med at køre forskellige eksempler for at få ideer til, hvordan du finjusterer resultaterne.

Voilà! Nu kan du udtrække vigtige nøgleord fra enhver type tekst!

Ressourcer

  • Fuld kildekode og datasæt til denne tutorial
  • Stak overløbsdata på Googles BigQuery

Følg min blog for at lære mere Text Mining, NLP og Machine Learning fra et anvendt perspektiv.

Denne artikel blev oprindeligt offentliggjort på kavita-ganesan.com.