Euromind
  • Javascript
    • Javascript

      Historiske administrative geografier i Google Maps

      20. april, 2022

      Javascript

      Kierkegaard injiceret med Javascript

      15. april, 2022

      Javascript

      Dansk evighedskalender

      7. december, 2020

      Javascript

      API til Statistikbanken

      21. september, 2019

      Javascript

      IntersectionObserver

      9. august, 2019

  • CSS/SCSS
    • CSS/SCSS

      Kierkegaard injiceret med Javascript

      15. april, 2022

      CSS/SCSS

      Dansk evighedskalender

      7. december, 2020

      CSS/SCSS

      Variable fonte med dansk tegnsæt i open source

      11. august, 2019

      CSS/SCSS

      Progressbar for dokumentposition

      31. juli, 2019

      CSS/SCSS

      Media Query i 2019

      18. juli, 2019

  • C#
    • C#

      Historiske administrative geografier i Google Maps

      20. april, 2022

      C#

      Authentication for IOS og Android med Firebase i…

      4. oktober, 2019

      C#

      Andersen, Grundvig, Kierkegaard og ML.NET – del 3

      5. september, 2019

      C#

      Hurtig eksport til Excel

      4. september, 2019

      C#

      Andersen, Grundtvig, Kierkegaard og ML.NET – del 2

      2. september, 2019

  • Javascript
    • Javascript

      Historiske administrative geografier i Google Maps

      20. april, 2022

      Javascript

      Kierkegaard injiceret med Javascript

      15. april, 2022

      Javascript

      Dansk evighedskalender

      7. december, 2020

      Javascript

      API til Statistikbanken

      21. september, 2019

      Javascript

      IntersectionObserver

      9. august, 2019

  • CSS/SCSS
    • CSS/SCSS

      Kierkegaard injiceret med Javascript

      15. april, 2022

      CSS/SCSS

      Dansk evighedskalender

      7. december, 2020

      CSS/SCSS

      Variable fonte med dansk tegnsæt i open source

      11. august, 2019

      CSS/SCSS

      Progressbar for dokumentposition

      31. juli, 2019

      CSS/SCSS

      Media Query i 2019

      18. juli, 2019

  • C#
    • C#

      Historiske administrative geografier i Google Maps

      20. april, 2022

      C#

      Authentication for IOS og Android med Firebase i…

      4. oktober, 2019

      C#

      Andersen, Grundvig, Kierkegaard og ML.NET – del 3

      5. september, 2019

      C#

      Hurtig eksport til Excel

      4. september, 2019

      C#

      Andersen, Grundtvig, Kierkegaard og ML.NET – del 2

      2. september, 2019

Euromind
C#

Stylometri i C# – del 3

af Per Lindsø Larsen 2. juli, 2019
skrevet af Per Lindsø Larsen 2. juli, 2019
Stylometri i C# – del 3

De næste årtier var der forholdsvis stille i stylometriens verden. Det var svært at komme i kølvandet på Mendenhall for forskere, der for de fleste vedkommende nok i almindelig havde en mere magelig tilgang til tingene.  Men i 1935 beskrev lingvisten George Zipf nogle karakteristika ved hyppigheden af de forskellige ords optræden i en given tekst, der senere er almindelig kendt som Zipfs Lov. Mens Hendenhall havde en forkærlighed for at tælle længden på ord, så koncentrerede Zipf sig om at tælle, hvor hyppigt de forskellige ord optræder i teksten. Verden er i sandhed fuld af lystige mennesker. Zipf havde endda et par ordlystne studentermedhjælpere til at tælle med.

Zipfs lov postulerer at i en større tekst-korpus er hyppigheden af et ord omvendt proportionel med dets placering i en rangeret frekvensliste. – Det lød flot, men jeg er ikke sikker på, at jeg selv helt forstod det. Jeg prøver igen: Tæller man hvor hyppigt de forskellige ord findes i en tekst og derefter placerer dem på en liste, hvor det hyppigste ord står øverst, det næsthyppigste som nummer 2, det tredjehyppigste nummer tre, und so weiter, så siger Zipf’s lov, at det hyppigste ord optræder dobbelt så hyppigt som det næsthyppigste ord, tre gange så hyppigt som nummer tre på listen – og sådan fortsætter det indtil det sidste ord er sagt – eller rettere talt med. Plotter man derfor en graf med rangplacering på x-aksen og hyppighed på y-aksen, så får man en hyperbel. Den er kedelig at se på, så derfor laver man i stedet et zipf-plot, en log-log graf, hvor istedet tages logaritmen til rangen og logaritmen til hyppighed. Det giver en tilnærmelsesvis lige streg, hvis Zipfs lov dur, og det gør den sædvanligvis. Den halter dog ofte lidt ved en håndfuld af de øverstplacerede ord på listen og en smule i bunden.

Det finurlige er, at den er gældende for tekster på vidt forskellige sprog. Denne graf fra Wikipedia viser Zipfs-plot for tekster på 30 forskellige sprog:

I det følgende vil jeg efterprøve, om Zipfs lov også gælder for det litterære triumvirat: Kierkegaaard, H.C. Andersen og Grundtvig – eller de er underkastet en guddommelig undtagelse.

Med undgangspunkt i de tre valgte værker (Enten-Eller I-II af Kierkegaard, Mit Livs Eventyr af H.C.Andersen og Verdens Krønike af Grundtvig) vil jeg forsøge at generere en rangordnet ord-frekvensliste for hver og indsat som tabel i Excel – og samtidig få lavet et zipf-plot på de tre lister.

Teksterne hentes ind og omdannes til en liste af ord med funktioner beskrevet i en tidligere blog-post. Herefter kan ord-frekvenslisten dannes med f.eks:

        [Serializable]
        public class WordRank
        {
            public int Rank { get; set; } = 0;
            public string Ord { get; set; } = "";
            public int Antal { get; set; } = 0;
            public double Pct { get; set; } = 0;
            public double Accumulated { get; set; } = 0;
        }


        public static List<WordRank> GetWordFrequencyList(List<string> words, int decimals)
        {
            var res = new List<WordRank>();
            var dictionary = new Dictionary<string, int>();
            foreach (var w in words)
            {
                if (dictionary.ContainsKey(w))
                    dictionary[w]++;
                else
                    dictionary.Add(w, 1);
            }
            var totalWords = dictionary.Sum(p => p.Value);
            int counter = 1;
            foreach (var item in dictionary.OrderByDescending(o => o.Value))
            {
                WordRank rank = new WordRank();
                rank.Rank = counter;
                rank.Antal = item.Value;
                rank.Ord = item.Key;
                rank.Pct = Math.Round(item.Value * 100 / (double)totalWords, decimals);
                rank.Accumulated = res.Sum(p => p.Pct) + rank.Pct;
                res.Add(rank);
                counter++;
            }
            return res;
        }

Herefter er det ganske enkelt at få generet Excel-arket med hjælp fra EPPlus-wrapper, beskrevet i en anden blog-post.

           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" }
            };

            //Opret Excel-fil
            var excel = new Export.Excel("Zipf_lov.xlsx");
            //Tilføj Excel-ark til filen 
            var sheet = excel.AddSheet("Ordfrekvensliste", true);
            // Tilføj et XYScatterLines-chart
            var chart = sheet.AddChart("ZIPF's LOV", eChartType.XYScatterLinesNoMarkers,500,500, logaritmic:true);
            // Styling:
            chart.XAxis.Title.Text = "Log (Rank)";
            chart.YAxis.Title.Text = "Log (Hyppighed)";
            chart.Legend.Position = eLegendPosition.Top;
            chart.XAxis.MaxValue = 20000;

            foreach (var book in source)
            {
                //Indlæs tekst
                var text = Stylo.PreProcessText(Path.Combine(@"..\..\Tekster\", book.Filename));
                //Hug det op i ord
                var words = Stylo.GetWords(text,false);
                //Dan ord-frekvensliste
                var wr = Stylo.GetWordFrequencyList(words, 3);
                //Tilføj tabel med ord-frekvenslisten til arket
                sheet.AddTable($"{book.Title}", wr);
                //Tilføj data-serie til grafen
               var s = sheet.AddSeries(chart, "Rank", "Pct");
            }
            //Gem fil og åben automatisk i Excel
            excel.Save(true);

Nedenstående viser resultatet i Excel – her vist de første 25 ord og deres hyppighed i de tre skrifter. Listen kan efter behag udvides med samlet frekvensliste, z-score, Burrows delta – eller hvad man nu eller gerne vil imponere med på den næste date.

Og såmænd om ikke også Zipf’s plot ser ud som det skal. Hvor forskellig i stil og indhold de tre giganten er, så ender de alligevel op med en stor set identisk kurve.

En væsentlig pointe er, at nogle få ord bruges ekstremt meget i sproget og mange ord yderst sjældent. For både Søren Kierkegaard, Grundtvig og H.C. Andersen ses det, at en fjerdedel af deres forfatterskab udgøres af 13 ord – lidt popsmart sagt. Under 25 ord udgør en tredjedel af alle ord i værkerne og 80 ord halvdelen.

Såkaldte funktionsord er fremtrædende i toppen af ordfrekvenslister. Besynderligt navn, for det er ord, der absolut ingen funktion har, bortset fra at binde teksten sammen – før den når til det, som vi alle venter på: indholdsordene. Brugen af de hyppige funktionsord foregår mere ubevidst, og de har vist sig at være en stærk forfatter-signatur, der i betydelig grad har en stabilitet på tværs af genre og over tid.

Stylometri i C# del 1, del 2 og del 4.

Stylometri
0 Kommentarer
4
FacebookTwitterPinterestEmail
forrige post
Registrer Gmail API til brug i javascript
næste post
Serialisering og deserialisering i C#

Relaterede indlæg

Historiske administrative geografier i Google Maps

20. april, 2022

Authentication for IOS og Android med Firebase i...

4. oktober, 2019

Andersen, Grundvig, Kierkegaard og ML.NET – del 3

5. september, 2019

Hurtig eksport til Excel

4. september, 2019

Andersen, Grundtvig, Kierkegaard og ML.NET – del 2

2. september, 2019

Andersen, Grundvig, Kierkegaard og ML.NET – del 1

11. august, 2019

Forbind Visual Studio til IOS devices på 10...

12. juli, 2019

Stylometri i C# – del 4

9. juli, 2019

Serialisering og deserialisering i C#

5. juli, 2019

Stylometri i C# – del 2

7. juni, 2019

Efterlad en kommentar Afbryd svar

Gem mit navn, email, og website i denne browser til senere kommentarer.

Seneste indlæg

  • Historiske administrative geografier i Google Maps

    20. april, 2022
  • Kierkegaard injiceret med Javascript

    15. april, 2022
  • Dansk evighedskalender

    7. december, 2020

Kategorier

  • C#
  • CSS/SCSS
  • Excel
  • HTML
  • Javascript
  • Mobile
  • Webdesign
  • Xamarin

Om mig

Om mig

Per Lindsø Larsen

Freelance fullstack developer bosat i Aarhus.

Du kan hyre mig til korterevarende projekter eller konkrete opgaveløsninger.

Pæn rabat til non-profit organisationer og foreninger.

Når jeg ikke koder, deltager jeg løbende i diverse spændende forskningsprojekter om alt andet end kodning.

Keep in touch

Facebook Twitter Email Github

Tags

Adresser AMP AMP Story Android API Billedformater Billedoptimering Brand C# Codepen Cordova CPR Crome DevTools CSS Debug Ecmascript Excel Fonte Gmail Gulp HTML Ikoner IOS Javascript JsFiddle Machine Learning Mail Mediaquery ML.NET Mobile RegEx SCSS SMTP Stylometri Visual Studio Webdesign Xamarin

Nyhedsbrev

Timeld nyhedsbrev for info om nye blog-indlæg, tips m.v.

  • Facebook
  • Twitter
  • Email
  • Github

@2019 - Euromind.com - Code-To-Go. All Right Reserved.
lindsoe@gmail.com - mobil: 42797273


Tilbage til top
Euromind
  • Javascript
    • Javascript

      Historiske administrative geografier i Google Maps

      20. april, 2022

      Javascript

      Kierkegaard injiceret med Javascript

      15. april, 2022

      Javascript

      Dansk evighedskalender

      7. december, 2020

      Javascript

      API til Statistikbanken

      21. september, 2019

      Javascript

      IntersectionObserver

      9. august, 2019

  • CSS/SCSS
    • CSS/SCSS

      Kierkegaard injiceret med Javascript

      15. april, 2022

      CSS/SCSS

      Dansk evighedskalender

      7. december, 2020

      CSS/SCSS

      Variable fonte med dansk tegnsæt i open source

      11. august, 2019

      CSS/SCSS

      Progressbar for dokumentposition

      31. juli, 2019

      CSS/SCSS

      Media Query i 2019

      18. juli, 2019

  • C#
    • C#

      Historiske administrative geografier i Google Maps

      20. april, 2022

      C#

      Authentication for IOS og Android med Firebase i…

      4. oktober, 2019

      C#

      Andersen, Grundvig, Kierkegaard og ML.NET – del 3

      5. september, 2019

      C#

      Hurtig eksport til Excel

      4. september, 2019

      C#

      Andersen, Grundtvig, Kierkegaard og ML.NET – del 2

      2. september, 2019

Populære indlæg

  • 1

    Stylometri i C# – del 2

    7. juni, 2019
  • 2

    Andersen, Grundvig, Kierkegaard og ML.NET – del 1

    11. august, 2019
  • 3

    Send email fra Javascript med Gmail API

    21. juni, 2019
  • 4

    Gmail, Yahoo og Outlook som SMTP-server

    18. april, 2019
  • 5

    API til Statistikbanken

    21. september, 2019
@2019 - Euromind.com - Code-To-Go. All Right Reserved.
lindsoe@gmail.com - mobil: 42797273

Læs ogsåx

Gmail, Yahoo og Outlook som SMTP-server

18. april, 2019

Serialisering og deserialisering i C#

5. juli, 2019

Historiske administrative geografier i Google Maps

20. april, 2022