Blog

Block 1 och lite annat

Denna vecka kommer jag avsluta första delen på den statistikkurs jag går. Jag kommer då att ha gått igenom grundläggande begrepp vad gäller undersökningsmetodik och deskription.

Ett av de grundläggande koncepten man måste ha koll på är samband. Bara för att där finns ett samband så behöver det inte betyda att en variabel orsakar ett visst utfall. Och finns ett orsakssamband så måste man ha koll på vad som orsakar ett utfall. Ett enkelt exempel på detta är att man skulle kunna se ett samband mellan glassförsäljning och soligt väder. Det är ju inte att glassförsäljningen går bra som orsakar soligt väder! Sedan kan man se att när glassförsäljning går bra är det också många som badar. Men det är inte glassförsäljning som gör att folk badar. Det råkar bara sammanfalla med att det är soligt väder. Så de korrelerar med varandra.

Jag kommer börja använda ett open-source program denna vecka för att göra statistiska analyser. Det heter Jamovi. Jag kommer använda det för att göra lite övningsuppgifter.

I helgen så har jag inte ägnat någon tid till statistik, så det blir mer av det i veckan. Nej, snarare så har jag ägnat tid till programmering, eller snarare web design. Jag har efter lite fram och tillbaka med css och visat sambon kommit fram till att jag först behöver en målbild innan jag sitter och prövar olika färger och css-funktioner. Så istället har jag suttit med Adobe XD och tagit fram ett koncept. Det tog ett tag men jag gillar färgerna och presentationen som jag fått fram.

Så när jag eventuellt får lite tid över efter bebisar och statistik så kommer jag köra lite CSS med lite grid och flex.


Beskriva en fördelning

Det finns fem enkla värden som på ett enkelt och ofta rättvist sätt kan beskriva hur data fördelas bland en population. Här kommer dem: minimum, Q1, M, Q2, och maximum.

Minimum anger den lägsta datapunkten i hela underlaget. I bland kan vissa outliers exkluderas, då anger minimum det lägsta värdet för underlaget som inte har sorterats bort.

Q1, M och Q3 är olika punkter för andel av befolkningen som uppnått ett visst värde. M är känd som medianen och anger den punkt i ett storleksordnat underlag där hälften av dataunderlaget sorteras under den, och hälften sorteras över den. Den undre hälften kan på motsvarande sätt delas ytterligare i hälften vid den punkt som benämns Q1, vilket då utgör första kvartilen. Vice versa gäller för den övre hälften från medianen, vilket benämns Q3.

Sedan har vi maximum som anger den högsta datapunkten i hela underlaget, bortsett från eventuella outliers. I figuren nedan samlas alla fem punkterna i ett boxdiagram. Vi kan föreställa oss att figuren är ett exempel på längdfördelningen bland alla aktiva fotbollsspelare i fantasi fotboll. Kortaste spelaren är en älva på 10 cm. Längsta spelaren är en ork på 280 cm. Vi har en medianlängd runt 160 cm. Det verkar som att 50% av spelare har en längd mellan 140 – 190 cm.

Det finns få mått som på ett bättre sätt kan beskriva en fördelning bättre än dessa fem. Om man skulle ha något emot median, så kan man använda medelvärdet. Men medelvärdet är inte så motståndskraftigt när det kommer till extrema värden. På samma sätt gäller det för standard deviation som mått på fördelning, eller hur mycket i snitt värden skiljer sig från medelvärdet.

Detta var kort om att beskriva datafördelning. Nu är det fredag och åter helg! Denna helg kommer jag sätta mig ned lite med No Man’s Sky. Initiala intrycket säger mig att det är en färgglad presentation av rymdutforskning som kommer med en hel del av slöjd och skaparmöjligheter. Jag har spelat Elite: Dangerous en del under hösten, men detta ger en något lättare och kanske mer varierad upplevelse.


Statistikens grundläggande steg

Statistik är ett förenklat sätt att beskriva verkligheten. Men ibland (och ganska ofta) är statistik det enda som kan ge en uppfattning om sakers tillstånd. Statistik omfattar metoder för att samla in data samt bearbeta och analysera det. I detta inlägg tänkte jag beskriva statistiska metoder övergripligt utifrån de grundläggande stegen.

Innan någon statistisk undersökning påbörjas måste först ett problem identifieras. Jag skriver problem men menar egentligen något som innebär en kunskapslucka. Det är en frågeställning som för närvarande inte har fått något svar. Om frågeställningen är av sådan karaktär att statistiska metoder är tillämpliga kan nästa steg tas. Exempel på ett sådant problem är: ”Hur stor är arbetslösheten i Stockholm?”.

Vilka objekt är det som undersöks och hur kan man precisera dem? Här är det arbetslöshet som ska studeras, så det begreppet behöver operationaliseras. SCB operationaliserar begreppet enligt följande: ”en person som är utan arbete, kan ta ett arbete och aktivt sökt arbete eller som avvaktar ett arbete som börjar inom tre månader” (SCB, 2019). Detta ger oss ytterligare två begrepp att förhålla oss till; variabler och population. En variabel är en egenskap som undersöks. Genom operationaliseringen av det objekt som vi hade som exempel så fick vi fram ”person utan arbete”, detta kan vi beteckna som en variabel. Population utgör den tänkta målgrupp som studeras. I exemplet har vi ”arbetslöshet i Stockholm”. Det innebär att populationen är boende i Stockholm. Men även detta kan preciseras ytterligare; det skulle kunna vara personer från 18 år och uppåt som är folkbokförda i Stockholms län. Det är en ganska stor population så i nästa steg behöver vi fundera på om det är hanterbart att inkludera alla i studien eller om vi kan göra ett urval.

Svaret är att vi i exemplet behöver göra ett urval. Urvalet kan med fördel göras som ett obundet slumpmässigt urval. Det innebär att man drar slumpmässigt ett visst antal personer ur ett register, det som utgör ramen för undersökningen. När personerna dras har alla personer i registret lika hög sannolikhet att dras som vem som helst annars i samma register. Hur många personer som ska ingå i urvalet beror på population och vilken signifikansnivå man vill ha. Det går jag inte in på här utan det får jag återkomma till.

Stratifierat urval. Population delas in i grupper och urval görs ur varje grupp.
Exempel på en typ av urval: stratifierat urval.

Nästa steg innebär datainsamling. Vilken metod ska man använda för att få in svar? Det kan vara enkätundersökning eller intervjuer; på internet, över epost, brev eller telefon. Oavsett metod så finns olika typer av fallgropar man får se upp för och redovisa. En bra statistisk undersökning ska förhålla sig sakligt till den valda metoden.

Sedan kommer några steg, som jag bara kommer nämna här och återkomma till i senare inlägg. Det är databearbetning, vilket omfattar granskning och kodning av dataunderlaget följt av registrering. Dataunderlaget sammanställs sedan i tabeller. Därefter kommer analys och slutsats följt av publicering av den statistiska undersökningen. Detta är några viktiga steg, som jag ännu inte kommit till i min kurs. Så, på återseende kära databearbetning och analys!

Källa
SCB (2019). Arbetslös – inte samma sak hos SCB och Arbetsförmedlingen. Statistiska centralbyrån: www.scb.se [hämtat 2019-11-04]


Histogram vs stapeldiagram

Som jag varit inne på tidigare så kan man i stort dela in data i två kategorier: kategoriska (kvalitativa) och kvantitativa. Kvalitativ data kan man dela in i två underkategorier; de som kan delas in i storleksordning och de som inte kan det. Det vill säga nominal och ordinal data. Sedan har vi kvantitativ data som kan delas in i intervallskala och kvotskala. Intervallskala är likt ordinal data men den har egenskapen ekvidistans, så det går att avgöra hur långt det är mellan två punkter på skalan. Kvotskalan har ytterligare egenskap att det går att avgöra hur mycket större ett värde är än ett annat, så som att det kan vara dubbelt så stort/varmt/högt/med mera.

Histogram är ett bra verktyg att använda när man jobbar med kvantitativ data och vill förenkla data så det blir meningsfullt att visualisera. Det kan vara att presentera längd på alla som spelar fotboll i allsvenskan. Man skapar då intervall som är lika stora och presenterar dem i ett histogram.

Exempel på ett histogram

Detta påminner om hur stapeldiagram ser ut, men de har olika användningsområden. Stapeldiagram visualiserar hur nominal data kan fördelas. Här kommer ett exempel på vilket husdjur en klass skolelever skulle välja:

Exempel på stapeldiagram med katt, hund och kanin.

Ovanstående exempel hade även kunnat representeras som andelar i ett cirkeldiagram.

Denna vecka fortsätter jag med statistik, och jag kommer gå igenom hur en statistisk undersökning går till: från problemformulering till slutsats.

Slutligen måste jag medge att det funnits tillfällen då jag återgått till min programmering. Jag har börjat justera presentationen av Bokarenan med hjälp av CSS Grid. Det har varit enklare att programmera i 20 minuter än att plugga när jag är trött. Vi får se om det blir ytterligare programmering gjort denna veckan.


Vad en tabell är

Så inledningsvis är statistik-kursen ganska enkel. Jag har börjat läsa i kurslitteraturen och den kommer med många exempel och övningar. Tyvärr tycker jag boken inte är tillräckligt tydlig med när den går över till exempel. Första avsnittet bestod till nästan 40% av exempel och 10% av övningar. 50% var alltså det huvudsakliga kunskapsbidraget som boken erbjöd. Men det behöver inte vara negativt i sig, och är dessutom antagligen förbehållet de inledande avsnitten.

Ett av de koncepten som introducerades inledningsvis var vad en tabell är. Jag vet vad en tabell är, så det avsnittet hade jag kunnat bara överblicka. Det är något som jag får bli bättre på. Har man, som jag, jobbat mot databaser; då vet man vad en tabell är.

Utöver tabeller så har jag tagit del av vilka olika typer av data det finns. I huvudsak är det om dataunderlaget är kategoriskt eller kvantitativt. Det vill säga om det beskriver till exempel yrke eller lön. Härnäst så ska jag läsa vidare om grafisk presentation av statistik.

Så går vi över till helg. I nöjesväg så fick jag inte ut mycket ut av spelet Hellblade: Senua’s sacrifice. Det var alldeles för deppigt och påfrestande för mig. Jag går istället över (och tillbaka) till Horizon: Zero Dawn. Jag slipar på tekniken att fälla Frostclaws.

Trevlig helg, allihopa!


Nu drar det igång med statistik

Tidigare inlägg har varnat om det och nu är det dags; här är mitt första inlägg om statistik. Så jag påbörjar en grundläggande kurs i statistik denna vecka. Jag går den med syfte att uppdatera mig om metodiken för att kunna tillämpa det inom mina intresseområden. Jag har gått tidigare kurs i ”kvantitativa metoder”, men det var 2010. Mycket av den kunskapen finns kvar någonstans och jag behöver hjälp att ta fram det. Jag hoppas trots det att jag lär mig lite nytt. Jag hoppas kunna göra regressionsanalyser och presentera resultat på ett spårbart och enkelt sätt. Kanske finns det möjligheter att göra kopplingar till Bokarenan i framtagning av exempelvis läsrekommendationer. Svårigheten att göra det på Bokarenan kan ju ses i det dataunderlag som finns. För närvarande har applikationen endast EN användare.

Denna veckan kommer jag läsa igenom lite grundläggande begrepp inom statistik. Det handlar om medelvärde, median, standardavvikelse, kvartiler, med mera.

Image of a dice.

Vad är sannolikheten att jag ska få en femma när jag kastar en tärning? Svaret har att göra med sannolikhet. Sannolikheten för att få ett värde av sex möjliga är alltså: 1/6.

Vad är sannolikheten att jag ska få en femma om båda gångerna om jag kastar en tärning två gånger? Jo, det är:

Alltså är sannolikheten för två femmor på raden lika med 1/36, vilket är knappt 3%.

För att beräkna sannolikheten för på varandra oberoende händelser så kan man använda det som kallas sannolikhetslärans multiplikationssats. Det var detta som jag precis gjorde.

Till nästa gång kommer jag att ha börjat tugga på Practice of statistics for business and economics av Alwan Layth. Det är en nästan 1000 sidor tjock bok och utgör kursens enda litteratur. Det ser jag fram emot. Den har många bilder!


Sökfunktion och DQL

Denna veckan blir antagligen den sista på ett tag med uppdateringar om Bokarenan och programmering. Jag påbörjar en kurs om statistik och kommer använda Femte Arenan för att beskriva de lärdomar jag drar av det. Så jag passar på att beskriva det senaste jag gjort i programmeringsväg över helgen.

Jag lämnade förra veckan med en fundering på om jag skulle hinna få på plats en sökfunktion. När jag gjorde en sökfunktion till den nuvarande Bokarenan så svalde jag efter för mycket. Jag gjorde så att användaren kunde söka efter varje detalj i varje liten entitet. Det gjorde sökfunktionen lite svår att använda. Istället har jag gjort sökfunktionen till ett textfält som alltid finns tillhands i navigationsfältet och det man söker efter är BÖCKER. Jag har för närvarande gjort så att man kan söka efter författare eller boktitel, men sökresultatet är alltid BÖCKER. Inte författare eller något annat. Jag är rätt nöjd med resultatet. Det var också rätt så enkelt att implementera med hjälp av Doctrine och dess queryBuilder.

Så efter att ha fått på plats sökfunktionen så kände jag att jag var på rull. Därnäst så implementerade jag ett navigationsträd för böcker. I navigationsfältet har användaren en länk som heter Böcker. Klickar man på den så kommer man till sida för att välja böcker enligt genrer. Genrer är uppbyggda hierarkiskt, så att till exempel thriller är en underkategori till skönlitteratur. Klickar man på Skönlitteratur så får man upp en ny lista på genrer inom skönlitteratur samt de populäraste böckerna associerade med genren skönlitteratur.

Implementeringen av genrer i kombination med lista på populära böcker innebar att jag hade att hantera tre olika entiteter: Book, BookAnalysis och Genre. Tidigare har jag helt enkelt använt den repository som var lämplig. Jag försökte mig på att använda repository för BookAnalysis med förhoppning att kunna använda den Book-referens som den entiteten har. Book har i sin tur referens till Genre-entitet. Jag vred och vände men fick inte till det. Jag hade några alternativ kvar, som tur var. Nuvarande Bokarena använder sig av SQL-kod som jag skrivit. Nackdelen med att använda det är att jag inte får tillbaka entitets-objekt, utan det är något som jag fått initialisera ”manuellt”. Men jag behöver inte göra på samma sätt här. Jag kan använda DQL (Doctrine Query Language) istället. Det innebär att jag blir lika flexibel som om jag skrev SQL men jag får fördelen med att få tillbaka de rätta entiteterna. Med följande sats så blev det inte så komplicerat trots allt:
"SELECT a FROM App\Entity\BookAnalysis a JOIN a.book b WHERE b.genre = $id ORDER BY a.numReviews DESC, a.avgRate DESC"

Ha en sån trevlig vecka. Nästa gång skriver jag om data i stora mängder.


Favoriter på framsidan

Så till slut kan jag säga att jag har uppnått veckans mål; att få fram en lista med rekommenderade recensioner och en lista på de böcker som fått bäst betyg. Resan hit tog en liten omväg. Hur lång? – Inte särskilt lång!

Respektive bok har inte ett betyg, men däremot har de recensioner som boken är associerad med ett betyg. För att kunna ta fram exempelvis de fem bästa böckerna behöver jag hämta alla böckers respektive recensioner, sedan ordna böckerna i fallande ordning utefter de genomsnittliga betygen. Därefter skulle jag kunna presentera resultatet för användarna. Detta tyckte jag verkade som ganska mycket jobb att göra varje gång någon laddar framsidan. Den lösning som jag tagit fram är istället att ordna en ny entitet: BookAnalysis. Denna entitet innehåller såväl genomsnittliga betyg för respektive bok som antal användare som har boken som ”att läsa”. Denna entitet kan innehålla fler fält, men vi börjar med detta. Idén är att bara administratörer kan komma åt kontrollen för BookAnalysis och därigenom aktivera en analys av databasens recensioner och böcker. På framsidan kan jag därför presentera de 5 bästa böckerna genom att hämta toppresultatet från BookAnalysis. Nackdelen är att användarna inte får det absolut senaste resultatet, men fördelen är att servern inte behöver genomföra beräkningar som bara kommer växa och bli större och tynga ner processorerna. Kanske är det så att beräkningarna inte skulle bli så tunga, men eftersom jag har en loop inom en loop så vill jag undvika risken.

Nu har jag fått ganska mycket på plats, men jag saknar någon sök-funktion. Detta skulle jag vilja få plats härnäst. Men! Frågan är om jag kommer ha någon tid över till det den närmaste tiden. Nästa vecka börjar jag en kurs om statistik och det kommer också synas på denna sidan. Och innan vi lämnar denna vecka så vill jag gå in på lite nöje!

Jag har under veckan haft nöjet att pröva ett spel som min sambo valt ut till mig: Shadow of the Tomb Raider. Spelet påminner mig i delar om Indiana Jones-filmerna och Rovdjuret. Man spelar som Lara Croft, en forskare/äventyrare, som är på jakt för att hämnas sin far. Men jakten uppdagar förebud om världens undergång. Och detta är något som Lara känner stor skuld till eftersom det mycket väl kan ha varit hennes hätska agerande som orsakat det. Så lika mycket som det handlar om hämnd handlar spelet om att försöka med alla medel att stoppa undergången. Jag har haft så himla kul och varit så imponerad av ett spel på länge. Det hänför mig med fantastiska miljöer och påhittiga banor. Jag sitter på spänn när jag hoppar mot en klippkant för att försöka klättra högre. Jag känner mig så grym när jag gömmer mig indränkt i lera mot en klippvägg och inväntar Laras fiender. På resans gång har Lara gått från att vara ett bytesdjur till att bli djungelns jaguar. Det spel jag kommer bita i härnäst är Hellblade: Senua’s Sacrifice. Jag har hört lite grann om spelet och jag är rädd för att det inte kommer ge mig samma tillfredsställelse som Tomb Raider men däremot en resa som kommer vara med mig länge. Vi får se.

Trevlig helg, allihopa!


Lista av recensioner och lista av böcker

Nu har jag i applikationen (Bokarenan) fått till såväl en lista av rekommenderade recensioner såväl som ett urval av de senaste recenserade böckerna. Jag påstod i föregående inlägg att jag denna vecka skulle få till en lista med de böcker med bäst betyg. Det kan fortfarande bli så men jag fokuserade istället på att få till de senaste recenserade böckerna.

För att få till urvalet av de senaste recenserade böckerna så har jag fått gå till Repository-klassen för Review. Där har jag lagt till funktionen findByLatest(int $limit). Genom den funktionen så hämtar jag de senaste x-antal recensionerna. Utifrån den samlingen av recensioner så hämtar jag referenserna till de böcker som de refererar. Eftersom en bok kan recenseras flera gånger så använder jag mig av php-funktionen array_unique(). Därmed så tar jag bort överflödiga referenser och kan presentera en bok inte fler än en gång på framsidan.

Det jag vill göra härnäst är att skapa en personlig lista av böcker att läsa. Och från den listan kan man sedan välja att recensera den bok man vill.


review.review.review

Det som är veckans uppgift är att få till en presentation på välkomstsidan som innehåller två delar. Första delen är en lista av recensioner som har valts av administratörer som lämpliga. Andra delen är en lista av böcker med bäst betyg.

Jag har kommit en bit på vägen med en lista av rekommenderade recensioner. Det har inneburit att jag skapat en ny entitet (RecommendedReview), och gjort det möjligt för de med administratörsrättigheter att lägga till recensioner till listan. Jag har också gjort det möjligt att visa alla de recensioner som finns i rekommendationslistan. Nu återstår att få denna listan till framsidan. Men i utvecklingen av presentationen av listan så har jag råkat göra något hemskt! Genom en template engine (Twig) så låter jag loopa igenom en array och presentera innehållet i en tabell:

{% for review in reviews %}            
<tr>
<td>{{ review.review.id }}</td>
<td>{{ review.review.name }}</td>
<td>{{ review.review.review }}</td>
</tr>
{% endfor %}

Som ni kan se så har jag alltså följande sats: review.review.review. Det är inte hållbart! Det första review står för RecommendedReview och innebär att den relaterar ett recensionsobjekt till det datum när den lades till i listan för rekommenderade recensioner. Det andra review står för ett recensionsobjekt. Det tredje review är ett fält i recensionsobjektet som står för recensionstexten. Det är inte så snyggt eller pedagogiskt att låta en sak betyda tre olika saker. Lämpligen borde jag refaktorera det hela så att jag istället har: recommendedReview.review.text. Det bästa hade varit att göra det rätt från början. Det näst bästa är att göra det rätt nu.

Först går jag till controllern och ändrar variabelnamnet för arrayen med RecommendedReview-objekt från reviews till recommendedReviews. Sedan ändrar jag variabelnamnet för det aktuella RecommededReview-objektet i for-loopen från review till recommendedReview.

Sedan återstår att ändra fältnamnet i Review-entiteten från review till text. Jag gör det, och passar också på att ändra getter– och setter-metoderna i entiteten. Nu har jag gjort ett antal ändringar som kommer bryta vissa referenser i ett antal templates och, framförallt, hur databasen är uppbyggd. Jag kör därför Doctrine:s konsolverktyg för att analysera och åtgärda differensen mellan databasen och entiteterna. Och mycket riktigt så snappar Doctrine upp att jag ändrat namnet på fältet review till text.