Kaosteori indebærer som bekendt at en sommerfugls slag med vingen teoretisk set kan udløse orkan på den anden side af kloden. Sikkert er det i hvert fald, at sommerfugle i Malaysia har påvirket den stylometriske forskning helt andre steder.
I 1943 fremsatte den engelske statistiker R. A. Fischer en model, der kunne sandsynliggøre – på baggrund af allerede kendte sommerfuglearter i Malaysia – hvor mange nye arter, der ville blive fundet i Malaysia, hvis et givent antal summerfugle-jægere blev sendt afsted med en givent antal sommerfugle-fælder. Den spændende model fik nogle tankebaner til at kortslutte for de to amerikanske statistikere, Efron og Thisted, der undfangede følgende stylometriske tanke:
Hvis vi betragter ordene i en forfatters kendte værker som allerede kendte sommerfugle-arter, så kan det med Fischer’s model beregnes hvor mange nye sommerfugle-arter – læs: nye ord – der kan forventes at blive fundet i en ukendt tekst, såfremt den formodede forfatter virkelig er forfatter til denne tekst. Ord, som forfatteren allerede kender, men endnu ikke har brugt. En snurrig teori, hvis bagvedliggende ræsonnement jeg aldrig har haft kapacitet til at tænke helt til ende.
Det blev så igen William Shakespeare, der måtte holde for i stylometriens tjeneste. Efron og Thisted afprøvede deres teori på et anonymt digt, der er blevet tillagt Shakespeare. Modellen forventede, at der – hvis Shakespeare var forfatteren – ville blive fundet syv nye ord, som Shakespeare ikke tidligere havde brugt. Næsten rigtigt. Der blev fundet ni nye ord. Shakespeare brugte i alt 31.534 ord i sit forfatterskab og forskerne beregnede sig til, at han på den baggrund har kendt ca. 35.000 ord. Altså ca. 3.500 ord, som Shakespeare ikke nåede at få fyret af, inden han døde. – Og vi andre mangler bare ord!
Argumentets slagkraft blæser – som sommerfugle – i vinden og en senere forsker antydede da også, at ”perhaps the Efron-Thisted Test diverge too far from reality to yield meaningful results”.
Under alle omstændigheder, så henleder Efron-Thisted opmærksomheden på, at stylometri ikke blot handler om, hvad der står i teksten, men også hvad der ikke står – eller sjældent står. Tages H.C. Andersens “Mit Livs Eventyr” som eksempel, så er mere end hvert 15. ord i bogen et såkaldt hapax legomenon – et ord, som kun optræder én gang i. teksten. Tælles alene bogens forskellige ord – dem er der godt 20.000 af – så er 57% af dem hapax legomena. Det er der ikke noget overraskende i. Sædvanligvis ligger det mellem 40% og 60%. Yderligere godt 15% er hapax dislegomena – ord, der optræder to gange i hele bogen.

Omfanget af hapax legomena er helt tilbage til 1920’erne blevet anset som en variabel, der kan yde et bidrag til identifikation af forfattere. Sammenlignet med Mit Livs Eventyr ses det, at hyppigheden af hapax legomena er lavere hos Kierkegaard (49%), men sammenligningen er ikke helt fair, da tekstlængderne er forskellige. Det er som med kedelige familie-festtaler: jo længere de bliver, desto større risiko er der for at forfatteren begynder at gentage sig selv og “ødelægge” det ene hapax legomenon efter det andet. For at gøre konkurrence mere sportslig, vil jeg derfor i det følgende hugge værkerne op i lige store tekstblokke, der således på et ensartet grundlag kan sammenlignes. Det ser også mulighed for at se, hvor stabile variablerne er gennem hele værket.
[Serializable] public class ShortSummary { public int Cluster { get; set; } public int Textlength { get; set; } public int WordsCount { get; set; } public int StopWordsCount { get; set; } public int DifferentWordsCount { get; set; } public double Herdan { get; set; } public double Guiraud { get; set; } public double Uber { get; set; } public int LongWordsCount { get; set; } public int HapaxLegomena { get; set; } public int HapaxDisLegomena { get; set; } public int HapaxTrisLegomena { get; set; } public ShortSummary(TextInfo info, string text, int decimals = 3) { var words = GetWords(text, false); var sentences = GetSentences(text); var wordfreq = GetWordFrequencyList(words, decimals); Cluster = 0; Textlength = text.Length; WordsCount = words.Count; StopWordsCount = WordsCount - GetWords(text, true).Count; DifferentWordsCount = words.Distinct().Count(); HapaxLegomena = wordfreq.Count(x => x.Antal == 1); HapaxDisLegomena = wordfreq.Count(x => x.Antal == 2); HapaxTrisLegomena = wordfreq.Count(x => x.Antal == 3); LongWordsCount = words.Count(x => x.Length > 6); Herdan = CalculateHerdan(WordsCount, DifferentWordsCount, decimals); Guiraud = CalculateGuiraud(WordsCount, DifferentWordsCount, decimals); Uber = CalculateUber(WordsCount, DifferentWordsCount, decimals); } } public static List<ShortSummary> SummarizeWordClusters(TextInfo info, int ClusterSize, int decimals = 3) { var summary = new List<ShortSummary>(); var preProcessedText = Stylo.PreProcessText(Path.Combine(@"..\..\Tekster\", info.Filename), Encoding.UTF8, true); var clusters = Stylo.getWordClusters(preProcessedText, ClusterSize, false); int counter = 1; foreach (var cluster in clusters) { var s = new Stylo.ShortSummary(info, cluster, decimals); s.Cluster = counter; counter++; summary.Add(s); } return summary; }
Ud over hapax legomena – og brødrene dis og tris – hentes nogle supplerende mål for den leksikale rigdom i teksterne: Herdan, Uber og Guiraud Index.
public static double CalculateHerdan(int wordsCount, int differentWordsCount, int decimals = 6) { return Math.Round(Math.Log(differentWordsCount) / Math.Log(wordsCount), decimals); } public static double CalculateUber(int wordsCount, int differentWordsCount, int decimals = 2) { return Math.Round(Math.Pow(Math.Log(wordsCount), 2) / (Math.Log(wordsCount) - Math.Log(differentWordsCount)),decimals); } public static double CalculateGuiraud(int wordsCount, int differentWordsCount, int decimals = 2) { return Math.Round(differentWordsCount / Math.Sqrt(wordsCount), decimals); }
Sammen med tidligere beskrevne funktioner kan nu genereres de nødvendige Excel-tabeller for lige store ord-klynger fra de tre bøger. I eksemplet vælges 25 ordklynger af 3000 ord. Det er det antal, som den korteste af teksterne “Verdens Krønike” tillader.
List<TextInfo> source = new List<TextInfo>() { new TextInfo(){Title = "Enten-Eller",Filename = "enteneller.txt" }, new TextInfo(){Title = "Mit Livs Eventyr",Filename = "hca.txt" }, new TextInfo(){Title = "Verdens Krønike",Filename = "gv5.txt" } }; int clusterSize = 4000; int clusterCount = 20; //Opret Excel-fil var excel = new Export.Excel("wordclusters.xlsx"); //Tilføj Excel-ark til filen var sheet = excel.AddSheet("Ordfrekvensliste", true); string xAxisTitle = $"Klynge ({clusterSize} ord)"; string YAxisTitle = "Antal"; var hapaxchart = sheet.AddChart("Hapax Legomena", eChartType.LineMarkers, XLabel: xAxisTitle, YLabel: YAxisTitle); var differentwordschart = sheet.AddChart("Antal forskellige ord", eChartType.LineMarkers,XLabel:xAxisTitle, YLabel:YAxisTitle); var herdanchart = sheet.AddChart("Herdan Index", eChartType.LineMarkers, XLabel: xAxisTitle, YLabel: YAxisTitle); var longwordschart = sheet.AddChart("Antal lange ord", eChartType.LineMarkers, XLabel: xAxisTitle, YLabel: YAxisTitle); foreach (var book in source) { var summaries = Stylo.SummarizeWordClusters(book, clusterSize, 3); sheet.AddTable($"{book.Title}", summaries.Take(clusterCount)); sheet.AddSeries(differentwordschart, "Cluster", "DifferentWordsCount"); sheet.AddSeries(hapaxchart, "Cluster", "HapaxLegomena"); sheet.AddSeries(herdanchart, "Cluster", "Herdan"); sheet.AddSeries(longwordschart, "Cluster", "LongWordsCount"); } //Gem fil og åben automatisk i Excel excel.Save(true);

Af de tre er Søren Kierkegaard’s bog også den, der har det laveste LIX-tal. Overraskende, måske. Det ville han ikke bryde sig om at vide, den gamle sjover.
Stylometri i C# del 1, del2 og del 3.