Text mining

Jämförelse av svenska BERT-modeller för textklassificering i KNIME

december 17th, 2020

Johan Tornborg

Datasetet

Som ett första steg så behövde vi hitta lämpligt data för vårt experiment. Vi sökte data som innehåller text kopplat till olika kategorier, kategorier som kan vara uteslutande varandra och vissa fall även vara delvis överlappande. Vi sökte efter texter som innehåller exempel på både korta och långa stycken, och med en variation av stil, med och utan slang. Så vi bestämde oss för att skrapa ett populärt svenskt forum som heter Flashback (https://www.flashback.org/). Detta är ett forum som har funnits länge (> 10 år gammalt) och är fortfarande aktivt. Vi förutsatte att forumet bör innehålla en ansenlig mängd inlägg kategoriserade inom en mängd olika kategorier.

Inläggen i Flashback är indelade i olika kategorier som har definierats av webbplatsen (t.ex. hem, kultur, politik osv.). Varje huvudkategori kan ha flera underkategorier och den lägsta nivån är olika forumtrådar där användarna laddar upp sina inlägg. Vi extraherade det första inlägget i varje tråd tillsammans med huvudkategorin. Vi lyckades få cirka 143 000 inlägg på detta sätt. Detta är en stor datamängd, så vi krympte den genom att filtrera bort tomma och korta inlägg (mindre än 100 ord). Vi antog att det första inlägget i tråden skulle vara det mest relevanta och samtidigt tillräckligt långt för att kunna träna en modell. Vi tog just det första inlägget i tråden eftersom vi antog att den som initierar en tråd kan beskriva innehållet på ett tillräckligt bra sätt. Efter filtrering hade vi omkring 24 000 inlägg för träning och test av modellerna.

Figure 1. Översikt över workflow (Länk: https://kni.me/w/iyRcnV5iZXwFNjQ3)

Modellerna

I workflow som vi byggde använde vi 3 olika modeller (Länk till workflow: https://kni.me/w/iyRcnV5iZXwFNjQ3)

Vi refererar vidare till dessa modeller som AF, KB and Multi. Alla dessa modeller har samma format så att vi kan dra slutsatsen att det är korrekt att jämföra prediktionerna från dessa modeller när allt annat är lika. Skillnaden mellan modellerna ligger i det corpus som de är baserade på. Vi har också Multi-modellen med i jämförelsen. Det är en flexibel modell som är tränad av Google på flera språk. Multi är alltså inte specifik för svenska språket.

Figure 2. Konfigurering för BERT Model Selector. BERT-modellerna kan hämtas från TensorFlow Hub eller från HuggingFace som sedan sparas i den angivna katalogen. När den är inläst och sparad läses BERT-modellen in i KNIME. En användare kan välja en BERT-modell från en dropplista med verifierade modeller.

Konceptet transfer learning

För att träna modellerna använder vi en speciell BERT-extension i KNIME. Det är en lösning som inte kräver någon kodning. Nyckelordet här är transfer learning – först ska modellen tränas på en stor mängd data, sedan bygger vi en enklare klassificering ovanpå den modellen och finjusterar den kombinerade modellen på en mycket mindre datamängd. I vårt fall är BERT den initiala modellen som redan är tränad på en stor volym av text, och den enklare modellen genereras av en KNIME-nod som genererar det neurala nätverket som kan användas för det den specifika klassificeringen. Vi finjusterar modellen baserat på Flashback-datasetet som vi tidigare läst in. Det här sättet att jobba på är mycket enklare och billigare än att behöva träna modellen från grunden. Själva träningsprocessen görs med fördel med hjälp av grafikprocessor (GPU). Det går också att träna enbart med CPU men med betydligt längre exekveringstid som följd.

Träningsprocessen

För att träna och utvärdera en modell så gör vi det enligt ett speciellt mönster. Data delas upp i en träningsdel och del som används för att utvärdera modellen.  Vi kommer också att ha en annan datamängd för validering under träningsprocessen, detta är extremt användbart för att förstå hur många epoker som behövs för att få en robust modell.

MeanMedianMinMax
216.56165.01001000
Tabell 1. Utdata i flödet visar statistik över längden på texterna i corpus.

När vi väl har valt modellerna med BERT-model selector så delar vi data i tre delar, en för träning, en för validering och en för en slutlig utvärdering av den färdiga modellen. När vi har läst in BERT-modellen och data till BERT Classification Learner kan vi ställa in de olika parametrarna för träning. För att jämföra modellerna använder vi samma inställning för parametrarna. Den första är en modellparameter – maximal sekvenslängd sattes till 256 tokens. Detta värde valdes eftersom vi beräknade statistik för orden i inläggen. Vi fick medelvärde=216 och medianen=165. På så sätt kan vi vara säkra på att för mer än hälften av texterna så används hela textens längd. Längre texter kommer dock att trunkeras.

Nästa parametrar gäller träningsprocessen: antal epoker och batchstorlek. Antalet epoker definierar hur många gånger vi ska processa träningsdata. Man kan i huvudsak säga att resultat tenderar att bli bättre med flera epoker. Det finns dock ofta en gräns då modellen blir övertränad och alltför anpassad till tränningsdata.

Själva idén om “transfer learning” innebär att modellen vi finjusterar redan har kunskap om språket i fråga. Genom att finjustera modellen så kan vi kan vi ytterligare förbättra modellen för det specifika användningsfallet.

I detta exempel så tränade vi bara modellen med 2 epoker. Fler epoker visade sig inte ge bättre resultat och gjorde modellen övertränad i förhållande till träningsdatat.

Parametern för batchstorlek bör ställas in från fall till fall beroende av hårdvaran som används för träning, mestadels tillgängligt RAM- eller GPU-RAM och den maximala sekvenslängden. Konfigurera denna parameter baserat på hårdvara och övriga inställningar så att du inte får OutOfMemory-fel, som indikerar att texterna som omvandlas till BERT-embeddings inte passar i tillgängligt minne. Vi använde värde 12 för den här parametern och vi hade 8 GB video-RAM.

Det finns ytterligare en parameter, en kryssruta som heter ”Fintune BERT”. Den parametern styr i vilken grad modellen ska tränas. För bästa resultat så ska denna parameter kryssas i. Om fintuning inte är aktiverad kommer träningsprocessen att gå mycket snabbare. Samtidigt kommer det att kräva ett större antal epoker och modellen skulle troligen vara mindre korrekt. Så det här är en slags kompromiss, men vi rekommenderar att du aktiverar det här alternativet för att få den bästa modellen. Oftast räcker det med att träna bara 2-3 epoker för att få ett bra resultat.

Övriga inställningar påverkar optimeraren. Här kan du välja vilken optimering som helst från Keras-biblioteket. I vårt experiment använde vi Adam optimizer med inlärningshastighet = 1E-5. Vi använder defaultvärden för övriga parametrar.

Utvärdering av modeller

När modellerna har tränats kan vi enkelt testa modellen med hjälp av BERT Predictor-noden. Vi använder testdatat som vi filtrerade ut i början av processen. Modellen som bygger på träningsdata används sedan vidare för utvärdering baserat på testdatat. I vårt workflow har vi skapat en komponent kallad “missclassification analysis”. Med hjälp av komponenten kan vi välja kolumner med den verkliga klassificeringen och prediktionen från modellen. På detta sätt kan man skapa en dynamisk “confusion matrix”.

Figur 4. Konfigurationen av komponenten för “missclassification”.

Komponenten skapar en panel som visar flera egenskaper för modellerna. Längst upp till vänster på instrumentpanelen hittar du förhållandet mellan innehållet i klasserna (blå) och förhållandet mellan felklassificeringar för den här klassen baserat på det totala antalet klassificeringar. På höger sida finns en plot för tränings- och valideringsförluster, så denna plot är till hjälp för att definiera antalet epoker. Regeln är ganska enkel här: du måste hitta den punkt där två rader börjar divergera, vanligtvis kommer träningslinjen (grön) alltid att gå ner, medan valideringen (gul) kan gå upp, vilket innebär att modellen blir övertränad.

Sedan fortsätter tabellen med genomsnittliga värden för modellen för alla klasser följt av tabellen med de exekveringstide för träning och applicering av modell. Slutligen visar tabellerna felklassificering för varje kategori och en dynamisk “confusion matrix” som kan konfigureras i den tillhörande dialogen till komponenten.

Figur 5. Visualiseringar som visas i komponenten för missklassificeringar: statistik över modellens prestanda, träningsprocessen, felklassificering och exekveringstid.

Slutsats

Figur 6. Tabell som visar de olika modellerna med tillhörande statistik. Det bästa resultatet erhålls med KB-modellen.

Vi tränade och utvärderade tre modeller och kan vi dra slutsatsen att den bästa är KB’s modell med Acc: 88%, F1: 87% och Kappa: 85%. Det är ett bra resultat för en modell baserat på 7 olika kategorier. Detta kan vi se  i diagrammet, som visar statistiken från alla de tre modellerna.

Från den felklassificeringsanalys som vi gjorde kan vi se att vissa kategorier verkar överlappa varandra, vi kan anta att de mest oklara ämnena var ”Vetenskap & Humaniora” och ”Övrigt” som oftast klassificerades felaktigt som ”Hem, bostad & familj” och vice versa. Dessutom var ämnet ”Övrigt” ofta felklassificerat med resten av ämnena. Detta betyder att ”Övrigt” är ett extremt brett ämne, vilket är lätt att förstå. Hur som helst var det ett bra exempel som visade att BERT hanterar även sådana komplexa problem på ett bra sätt.

Ett mer grundligt arbete kan säkert förbättra modellen, men det faller utanför denna artikel. Att använda BERT tillsammans med Knime kräver inga färdigheter i programmering. Bara genom grundläggande kunskaper om Knime och maskininlärning kan en klassificering göras. Modellerna som är framställda på detta vis sparas i Knime-format och kan återanvändas för andra flöden.

Installation

För att använda BERT-extension måste du också installera KNIME TensorFlow2-extension. KNIME Analytics Platform version 4.2 eller senare är ett krav. I “KNIME-preferences” skapas en Deep Learning-miljö för Python. Därefter måste du installera ytterligare paket för den här miljön. Här är listan över paket som är kompatibla med noder och deras versioner:

  • bert==2.2.0
  • bert-for-tf2==0.14.4
  • Keras-Preprocessing==1.1.2
  • numpy==1.19.1
  • pandas==0.23.4
  • pyarrow==0.11.1
  • tensorboard==2.2.2
  • tensorboard-plugin-wit==1.7.0
  • tensorflow==2.2.0
  • tensorflow-estimator==2.2.0
  • tensorflow-hub==0.8.0
  • tokenizers==0.7.0
  • tqdm==4.48.0
  • transformers==3.0.2