Inledning

Statistik är vetenskapen om att samla in, analysera, tolka och presentera data. Den hjälper oss att identifiera mönster, fatta välgrundade beslut och dra slutsatser utifrån osäker information. Oavsett om vi undersöker vetenskapliga resultat, ekonomiska trender eller vardagliga fenomen, ger statistiken oss verktyg för att organisera och förstå världen vår omvärld.

Datorn är det främsta hjälpmedlet vid statistisk analys. R är ett programmeringsspråk och en av världens mest använda plattformar för statistisk analys. RStudio är ett användarvänligt gränssnitt för R.

Denna bok utgör en grundkurs i tillämpad statistik, inklusive övningsuppgifter med fokus på analys i RStudio.

Om R och RStudio

Att arbeta i RStudio

När vi öppnar RStudio ser vi tre fönster.

Det vänstra fönstret kallas console. Här kan vi skriva kommandon och direkt se resultaten av våra analyser. Console-fönstret kör kommandon omedelbart och är användbart för snabba tester. Genom att välja File -> New File och sedan R Script öppnas ett scriptfönster. Det är en god rutin att använda scriptfönstret både för att samla och spara alla kommandon som används i projektet samt för att föra loggbok över analysen. Skript kan köras vid behov och gör det lätt att återanvända koden.

I det övre högra fönstret finns Environment, som visar en översikt av alla variabler, datafiler, modeller och andra objekt som är aktiva i arbetsminnet. Här kan du också hålla koll på minnesanvändning och hantera objekt.

I det nedre högra fönstret hittar vi flera viktiga verktyg, bland annat en filhanterare för att navigera i dina projektfiler, pakethantering där du kan installera och uppdatera R-paket, samt Help-sektionen där du kan läsa dokumentation om funktioner och paket. Det är även i detta fönster som vi ser diagram och figurer som genereras av vår kod, och dessa kan enkelt exporteras för vidare användning.

Paket

Ett paket (engelska package) är en samling funktioner som vi kan ladda ned och använda för att ytterligare effektivisera vårt arbete. Det finns ett mycket stort antal paket och vi identifierar paket som vi kan ha nytta av när vi söker på nätet eller i hjälpfiler efter lösningar.

Att installera ett paket

Paket behöver bara installeras en enda gång och vi gör då på följande sätt.

  1. Gå till den nedre högra panelen i RStudio, välj fliken Packages och klicka på Install.

  1. Skriv namnet då det paket som du önskar installera.

  2. Klicka på Install.

Att aktivera ett paket

När ett paket finns installerat ska vi aktivera det. Aktivering behöver göras varje gång vi öppnar RStudio på nytt:

library(namn på paket)

Vi läser in de paket som vi behöver:

  • tidyverse, för databearbetning, visualisering och deskriptiv statistik

  • janitor, för att bilda frekvenstabeller

  • gmodels, för att bilda korstabeller

# Load tidyverse
library(tidyverse)
# Load janitor,
library(janitor)
# Load gmodels
library(gmodels)

Datafiler

Övningsuppgifterna baseras på Excelfilen data.xlsx. Följande datafiler ingår.

used_cars innehåller annonspris, ålder, körsträcka, utrustningsnivå och färg för ett stickprov av bilar av en viss modell.

mcdonalds visar näringsinformation om menyn.

spotify innehåller ett stickprov av låtar från Spotify.

santa_monica visar webbplatstrafik från City of Santa Monicas hemsida.

browserspeed ger resultatet av en enkätundersökning av vilken webbläsare man föredrar och upplevd hastighet.

titanic innehåller passagerarlistan från fartyget Titanic.

vasaloppet är en sammanställning av data från deltagarna vid en omgång av Vasaloppet.

data_AB visar resultatet av ett test av en webbsida, där två olika designer (A och B) testats mot varandra.

studytime innehåller data från en undersökning bland studenter vid ett lärosäte.

studytime_and_results ger resultatet av en tentamen.

pay_per_click visar data från en studie av en webbshop.

data_GA visar resultatet av ett test där tre designer (A, B och C) ställts mot varandra.

gasprice är en tidsserie över priset på bensin (kronor/liter) per månad.

pageviews är en tidsserie över antalet sidvisningar (i tusental) per vecka under 18 veckor.

panelists visar data från en webbpanel.

election_result är en fil med resultatet av Riksdagsvalet år 2014.


Grunddefinitioner

Population

Den grupp av individer som vår analys syftar till att dra slutsatser om kallas för en population. Populationen definieras av frågeställningen. Några exempel på populationer är de röstberättigade i ett land, eller alla som är anställda vid ett företag. Antalet individer i populationen betecknas ofta N.

Stickprov

I praktiken är det sällsynt att man kan samla in data om alla individer i populationen. Istället drar vi ett stickprov: vi gör ett slumpmässigt urval ur populationen. Slumpen hjälper oss att åstadkomma ett stickprov som är representativt för populationen. Med det menar vi att individerna i stickprovet har samma åsikter och egenskaper som individerna i populationen.

Det finns olika metoder för att dra stickprov ur en population - olika urvalsdesigner - och den vanligaste kallas obundet slumpmässigt urval (OSU). Idén bakom OSU är att alla individer i populationen ska ha samma chans att ingå i stickprovet. Detta går i praktiken att åstadkomma på olika sätt. Ett vanligt sätt att dra OSU är genom slumpmässigt urval ur ett register. Med RStudio drar vi ett OSU ur vår datafil genom att se till att vi aktiverat paketet tidyverse och sedan skriva följande kommandot:

urval <- sample_n(datafile)

Antalet individer i stickprovet betecknas med n.

Variabel

När vi samlar in data gör vi det om en eller flera variabler. Man skiljer på två typer av variabler: kvantitativa och kvalitativa variabler.

En kvantitativ variabel är en variabel som mäts i siffror. Exempel på kvantitativa variabler är inkomst, vikt, session duration och revenue.

En kvalitativ variabel är en variabel som inte mäts i siffror. Exempel på kvalitativa variabler är kön, yrke, bounce och device.

Oavsett typ av variabel så betecknas den med X. x1, x2 och så vidare betecknar variabelns värden.

I RStudio anropar vi en variabel genom datafil$variabel. datafil pekar RStudio mot rätt datafil, och variabel anger vilken variabel inom datafilen som ska analyseras.


Statistisk analys

Följande figur illustrerar stegen i en statistisk analys. När vi ställs inför en frågeställning börjar vi alltid med att definiera vad variabeln som ska analyseras representerar, samt om den är kvantitativ eller kvalitativ. Det hjälper oss att avgöra vilken analysmetod som lämpar sig.

Därefter funderar vi över frågeställningen. Tillsammans svarar de första två stegen i analyskedjan på vad vi vet och vad vi vill komma fram till.

I det följande behandlas de nästkommande stegen i analyskedjan.


Visualisering

Visualisering betyder att vi studerar variabelns fördelning. En variabels fördelning är en sammanställning över vilka värden som variabeln antar, och frekvensen för varje värde.

Det finns två huvudsakliga skäl till varför vi alltid visualiserar som en del av varje statistisk analys. Dels hjälper det oss att kvalitetssäkra data genom att upptäcka och ha möjlighet att rätta felaktiga variabelvärden. Dels lär oss visualiseringen mycket om variabeln som vi vill dra slutsatser om.

Vi använder olika metoder för att visualisera kvantitativa respektive kvalitativa variabler.

Visualisering av kvantitativ variabel

För en kvantitativ variabel lämpar sig histogram ofta bäst. Histogrammet påminner om stapeldiagram men bygger på att den kvantitativa variabeln först delas upp i intervall, som sedan visualiseras. Histogram skapas i RStudio genom att använda paketet tidyverse och kommandot ggplot:

ggplot(data = datafile) +

aes(x = variable name) +

geom_histogram()

Visualisering av kvalitativ variabel

En kvalitativ variabel kan vi antingen visualisera som en frekvenstabell eller ett stapeldiagram.

Frekvenstabeller kan i sin enklaste form skapas med kommandot table. För att även få med andelar används paketet janitor och kommandot tabyl.

För att skapa ett stapeldiagram skriver vi

ggplot(data = datafile) +

aes(x = variable name) +

geom_bar()

Om vi vill studera samvariationen mellan två kvalitativa variabler använder vi korstabeller. Kommandot för detta, baserat på paketet gmodels, är CrossTable(datafile$row_variable, datafile$column_variable).

Andra diagramtyper

Det finns förstås många typer av diagram. Utforska den lista över tillgängliga diagram som vi får upp genom att skriva geom_ i kommandot för visualisering. I de följande övningarna får du testa att använda några av dessa.

Uppgift vis.1

  1. Läs in filen mcdonalds.

  2. Skapa en frekvenstabell över variabeln Category. Tabellen ska innehålla både absoluta och relativa frekvenser.

Uppgift vis.2

Använd filen mcdonalds.

  1. Visualisera variabeln Category.

  2. Visualisera variabeln Grams.

Uppgift vis.3

Använd filen mcdonalds.

Visualisera produkternas vikt fördelat på variabeln Category i ett stapeldiagram.

Uppgift vis.4

Använd filen mcdonalds.

  1. Visualisera produkternas vikt fördelat på variabeln Category i ett lådagram.

  2. Visualisera produkternas vikt fördelat på variabeln Category i en violin plot.

Uppgift vis.5

Läs in filen titanic.

Skapa en korstabell mellan variablerna sex och survived. Hur stor andel av kvinnorna respektive männen överlevde förlisningen? survived = 1 betyder att passageraren överlevde.

Uppgift vis.6

Läs in filen data_AB.

  1. Visualisera variabeln revenue.

  2. Visualisera variabeln revenue fördelat på design.

Uppgift vis.7

Filen studietid innehåller data från en undersökning om hur mycket tid programstudenter vid ett lärosäte ägnar åt sina studier per vecka.

  1. Visualisera variabeln hours.

  2. Visualisera variabeln hours fördelat på vid vilket campus som man studerar.


Deskriptiv statistik

Deskriptiv statistik syftar till att sammanfatta den information som finns i en variabel i ett eller flera nyckeltal. Vi skiljer på lägesmått respektive spridningsmått. Lägesmåttet talar om för oss var tyngdpunkten är i variabelns fördelning, medan spridningsmåttet anger hur stor spridning det finns i variabelns värden.

Deskriptiv statistik för kvantitativ variabel

För en kvantitativ variabel använder vi medelvärdet som lägesmått. Det är här viktigt att tänka i termer av population och stickprov.

Populationsmedelvärdet är det sanna medelvärdet i populationen och.

\(\mu = \frac{1}{N} \sum_{i=1}^{N} x_i\)

Vi skulle vilja veta populationsmedelvärdet men kan inte räkna ut det eftersom vi inte har data för alla individer i populationen. Vår bästa uppskattning av populationsmedelvärdet får vi fram genom att beräkna stickprovsmedelvärdet. Stickprovsmedelvärdet betecknas med \(\bar{x}\):

\(\bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i\)

I RStudio beräknas medelvärdet genom kommandot mean(datafile$variable).

Som komplement till medelvärdet behöver vi också ett mått på den spridning som finns i de värden som den kvantitativa variabeln antar. Standardavvikelsen är det spridningsmått som används. Stickprovsstandardavvikelsen betecknas med \(s\) och beräknas enligt

\(s = \sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (x_i - \bar{x})^2}\)

I RStudio beräknas standardavvikelsen med kommandot sd(datafile$variable).Den kvantitativa variabelns minsta och största värde hjälper oss också att bedöma datakvaliteten.

Det är ofta intressant att studera en kvantitativ variabeln största (max(datafile$variable)) och minsta (min(datafile$variable)) värde. Ibland har vi också nytta av medianen (median(datafile$variable) och kvartiler (quantile(datafile$variable)).

Deskriptiv statistik för kvalitativ variabel

För en kvalitativ variabel fungerar andelar som både lägesmått och spridningsmått. Återigen tänker vi i termer av population och stickprov. Populationsandelen är den okända sanna andelen av individerna i populationen som har en viss egenskap. Populationsandelen betecknas \(\pi\). Vår bästa uppskattning av populationsandelen är andelen invidider i stickprovet med egenskapen, stickprovsandelen. Den betecknas \(p\).

Andelar tar vi i RStudio fram genom att bilda en frekvenstabell (se kapitlet om visualisering).

Uppgift desk.1

Använd filen mcdonalds.

  1. Variabeln Grams anger produkternas vikt. Vad väger den lättaste produkten på menyn? Vad väger den tyngsta?

  2. Vilken är den lättaste produkten på menyn? Vilken är den tyngsta?

Uppgift desk.2

Använd filen mcdonalds.

  1. Beräkna produkternas medelvikt (variabel Grams).

  2. Beräkna standardavvikelsen för produkternas medelvikt.

  3. Beräkna medianen och kvartilerna för produkternas vikt.

Uppgift desk.3

Använd filen mcdonalds.

Beräkna deskriptiv statistik (medelvärde, standardavvikelse och antal) över produkternas vikt fördelat på variabeln Category.

Uppgift desk.4

Läs in filen spotify.

  1. Hur många låtar finns det inom respektive genre (variabel playlist_genre)?

  2. Hur många unika artister (variabel track_artist) finns det i datafilen?

Uppgift desk.5

Använd filen spotify.

Beräkna deskriptiv statistik (variabel duration_ms, som anger låtens längd i millisekunder) för respektive genre. Den resulterande tabellen ska sorteras i fallande ordning efter låtarnas medellängd.

Uppgift desk.6

Använd filen spotify.

Beräkna låtarnas medellängd fördelat på variablerna playlist_genre och playlist_subgenre.

Uppgift desk.7

Använd filen titanic. Filen visar passagerarlistan (dock ej fullständig) från förlisningen av Titanic.

  1. Hur många passagerare finns det i passagerarlistan?

  2. För hur många av passagerarna finns det information om hemstad? Variabeln heter home_dest.

  3. Hur många bortfall finns det i variabeln home_dest?

Uppgift desk.8

Filen data_AB visar resultatet av ett så kallat A/B-test mellan två designalternativ för en webbplats. Läs in filen och beräkna deskriptiv statistik för variabeln revenue fördelat på design.

Uppgift desk.9

Använd filen studietid.

  1. Beräkna den genomsnittliga studietiden per vecka.

  2. Beräkna den genomsnittliga studietiden per vecka fördelat på vid vilket campus man studerar. Går det att dra några slutsatser?


Sannolikhetsteori

En sannolikhet är ett värde mellan 0 och 1 som anger hur troligt det är att en händelse inträffar. 0 betyder en omöjlig händelse och 1 en säker händelse. På så vis är en sannolikhet samma sak som en andel \(p\), och andelar beräknar vi genom att bilda frekvenstabeller (se kapitlet om visualisering).

I kapitlet om visualisering behandlades introducerades också begreppet fördelning som en sammanställning över vilka värden som en variabel antar och frekvensen för varje värde. Vissa fördelningar förekommer så ofta att de fått egna namn. Genom att lära oss att utläsa om en variabel följer någon av dessa vanligt förekommande sannolikhetsfördelningar kan vi lösa svåra problem. De vanligaste sannolikhetsfördelningarna är binomialfördelningen och normalfördelningen.

Binomialfördelning

Binomialfördelning används när vi är intresserade av sannolikheten för att en händelse ska inträffa ett visst antal gånger på ett givet antal försök. Följande förutsättningar gäller för binomialfördelningen:

  • vi är intresserade av en händelse som antingen inträffar eller också inte inträffar (detta kallas för att utfallet är binärt)

  • sannolikheten för att händelsen ska inträffa är samma varje gång försöket upprepas

Låt \(k\) beteckna antalet gånger händelsen inträffar på \(n\) försök. Binomialformeln säger då

\(P(X = k) = \binom{n}{k} p^k (1 - p)^{n-k}\)

där \(p\) betecknar sannolikheten för att händelsen ska inträffa vid vart och ett av de \(n\) försöken.

Sannolikheter för en binomialfördelad variabel beräknas enligt

dbinom(x = count, size = sample size, prob = probability)

Exempel:

Vad är sannolikheten för att få sexa exakt en gång på 10 tärningskast?

Antingen blir det sexa när vi kastar tärningen, eller också inte. Utfallet är alltså binärt. Sannolikheten för sexa är samma varje gång som tärningen kastas, och den sannolikheten är 1/6. Vi har därför att

dbinom(x = 1, size = 10, prob = 1/6)
## [1] 0.3230112

Sannolikheten för en sexa bland 10 tärningskast är 32.3 procent.

Normalfördelning

Normalfördelningen identifieras genom att ett histogram över variabeln får formen av en kyrkklocka. Sannolikheter beräknas enligt

pnorm(value, mean = mean, sd = standard deviation)

Exempel:

Utgå från datafilen studytime och variabeln hours. Vad är sannolikheten för att en slumpmässigt vald student spenderar mindre än 30 timmar per vecka på sina studier?

Vi börjar med att visualisera variabeln.

ggplot(data = studytime) +
  aes(x = hours) + 
  geom_histogram()

Histogrammet är klockformat varför variabeln kan betraktas som normalfördelad. Vi räknar nu ut variabelns medelvärde och standardavvikelse:

# Compute the mean
mean(studytime$hours, na.rm = TRUE)
## [1] 35.242
# Compute the standard deviation
sd(studytime$hours, na.rm = TRUE)
## [1] 10.21294

Vi kan nu räkna ut den sökta sannolikheten:

pnorm(30, mean = 35.242, sd = 10.21294)
## [1] 0.3038811

Sannolikheten för att en slumpmässigt vald studenter spenderar mindre än 30 timmar per vecka på sina studier är 30.4%.

t-fördelning

t-fördelningen används för att lösa liknande typer av problem som normalfördelningen, men lämpar sig när stickprovet är relativt litet. t-fördelningen är precis som normalfördelningen symmetrisk. En viktig egenskap hos t-fördelningen är att den blir allt mer lik normalfördelningen ju större stickprovet är.

t-fördelningen definieras av antalet frihetsgrader, eller enklare uttryckt antalet oberoende observationer. Antalet frihetsgrader bestäms baserat på stickprovsstorleken och vilken metod som används.

Vi kommer att stöta på praktiska tillämpningar av t-fördelningen i senare kapitel.

Uppgift sann.1

Använd filen spotify.

Vi väljer slumpmässigt en låt. Vad är sannolikheten för att den är en rocklåt?

Uppgift sann.2

En webbsida visar slumpmässigt och med

• sannolikhet 25% variation A

• sannolikhet 25% variation B

• sannolikhet 25% variation C

• sannolikhet 25% variation D

  1. Vad är sannolikheten för att en person som besöker webbsidan får se variation A eller variation B?

  2. Vad är sannolikheten för att en person som besöker webbsidan med två olika enheter båda gångerna får se variation A?

  3. Vad är sannolikheten för att en person som besöker webbsidan med två olika enheter först får se variation A och sedan en annan variation?

Uppgift sann.3

Konverteringsgraden för en sida är 10%. Under en timme har sidan 30 besökare.

  1. Vad är det förväntade antalet konverteringar under timmen?

  2. Vad är sannolikheten för att färre än 2 konverterar under timmen?

Uppgift sann.4

Vi studerar en webbshop för vilken vi vet att intäkten per månad går att betrakta som normalfördelad med medelvärde 150 000 kr och standardavvikelse 20 000 kr.

  1. Vad är sannolikheten för att intäkten nästa månad understiger 140 000 kr?

  2. Vad är sannolikheten för att intäkten nästa månad överstiger 170 000 kr?

Uppgift sann.5

Betrakta filen used_cars. Om vi betraktar data som ett representativt urval ur populationen av bilar av den aktuella modellen, och drar ett stickprov om 10 bilar, vad är då sannolikheten:

  1. För att ingen är röd

  2. För att alla 10 är röda

  3. För att färre än 3 av bilarna är röda

  4. För att 3 eller fler av bilarna är röda


Statistisk inferens om en population

Att för den kvantitativa variabeln använda stickprovsmedelvärdet som en uppskattning av populationsmedelvärdet, eller för den kvalitativa variabeln använda stickprovsandelen som en uppskattning av populationsandelen, kallas för att vi gör en punktskattning. En punktskattning innebär alltså att vi använder ett nyckeltal från stickprovet för att uppskatta motsvarande nyckeltal i populationen.

En punktskattning blir med stor risk missvisande. Det beror på att punktskattningen inte tar hänsyn till den osäkerhet som finns i data. Osäkerheten består av två delar: spridningen i variabeln samt stickprovsstorleken. Ju större spridning det är i variabeln, desto svårare är det att dra säkra slutsatser om populationen. Och ju mindre stickprov vi har, desto större blir osäkerheten.

Statistisk inferens är ett samlingsnamn för metoder som används för att dra slutsatser om en population baserat på ett stickprov draget ur populationen.

Vi skiljer på två huvudmetoder inom den statistiska inferensen: hypotesprövning och konfidensintervall.

Generellt om hypotesprövning för statistisk inferens om en population

Syftet med hypotesprövning är att testa ett påstående om populationen. Hypotesprövning genomförs i fyra steg.

Steg 1: Formulera hypoteser

Alternativhypotesen Ha är det påstående som vi vill testa. Nollhypotesen H0 är motsatsen till påståendet. Det betyder att nollhypotesen och alternativhypotesen tillsammans täcker in alla möjliga utfall.

Steg 2: Beräkna testvariabeln

Beräkning av testvariabeln innebär att vi jämför påståendet med information från stickprovet, samtidigt som vi tar hänsyn till den osäkerhet som finns i stickprovet. Med osäkerhet avses stickprovsstorleken samt standardavvikelsen. Testvariabeln beräknas av RStudio.

Steg 3: Beräkna p-värdet

RStudio beräknar sannolikheten för att erhålla den testvariabel som beräknats under antagandet att nollhypotesen är sann. Ju lägre denna sannolikhet är, desto mer benägna är vi att tro på alternativhypotesen.

Beslutsregeln är att om p-värdet är lägre än den osäkerhet som vi är beredda att acceptera (signifikansnivån), normalt 5%, så tror vi mer på alternativhypotesen. Vi kallar det för att nollhypotesen förkastas.

Steg 4: Dra slutsats

I det sista steget tolkar vi resultatet av hypotesprövningen.

  • Om nollhypotesen förkastas, och signifikansnivån är 5%, så är vi 95% säkra på att alternativhypotesen är sann.

  • Om nollhypotesen däremot inte kan förkastas, så kan vi inte dra någon entydig slutsats av hypotesprövningen. Det följer ur att vi inte kan vara säkra på om nollhypotesen är sann, eller om vi har för litet stickprov för att kunna visa att nollhypotesen ska förkastas.

Typ I-fel, typ II-fel, signifikansnivå och styrka

Målet med hypotesprövning är att dra slutsatser om den population som stickprovet dragits ur. Det gör att vi kan tänka oss följande tabell.

Kolumnerna i tabellen representerar den okända sanningen om populationen: antingen är nollhypotesen H0 eller alternativhypotesen Ha sann. Raderna visar de möjliga slutsatserna hypotesprövningen kan leda oss fram till: att H0 förkastas eller att H0 ej kan förkastas.
H0 sann Ha sann
Förkasta H0 Typ I-fel Korrekt slutsats
Förkasta ej H0 Korrekt slutsats Typ II-fel

Om hypotesprövningen leder oss till slutsatsen att H0 ska förkastas och Ha faktiskt är sann, så har vi dragit rätt slutsats. Det har vi också om hypotesprövningen ger att H0 ej kan förkastas när H0 är sann.

Att förkasta H0 trots att H0 är sann kallas för att göra typ I-fel. Innebörden är att vi säger att resultatet är signifikant, fast så inte är fallet. Risken för typ I-fel går att styra: det är signifikansnivån och den väljer vi normalt till 5%.

Att inte förkasta H0 trots att Ha är sann innebär att vi gör typ II-fel. Typ II-fel innebär att vår analys leder oss till slutsatsen att det inte finns någon signifikans, trots att det gör det.

Det råder ett motsatsförhållande mellan risken för typ I- och typ II-fel. Om vi skulle minska risken för typ I-fel genom att sänka signifikansnivån, så ökar risken för typ II-fel. En anledning till att man ofta väljer signifikansnivån till 5% är att det ger en bra balans mellan typerna av fel.

Om vi beräknar ett minus risken för typ II-fel, så får vi ett mått som kallas för styrka. Styrkan i ett test innebär sannolikheten att förkasta H0 när Ha är sann, det vill säga att förkasta nollhypotesen när nollhypotesen ska förkastas.

Kom ihåg att vi aldrig kan veta om hypotesprövningen leder oss till fel slutsats, eftersom vi ju faktiskt inte vet sanningen om populationen. Hade vi gjort det, hade vi inte behövt göra någon hypotesprövning!

Generellt om konfidensintervall för statistisk inferens om en population

Konfidensintervallet utgår från punktskattningen men ger oss dessutom en undre och en övre gräns, som vi med önskad säkerhet (normalt 95%), vet att det sanna populationsmedelvärdet (för en kvantitativ variabel) eller den sanna populationsandelen (för en kvalitativ variabel) finns inom. Den säkerhet vi väljer i konfidensintervallet kallas för konfidensnivå.

Hypotesprövning för populationsmedelvärde

Hypotesprövning för populationsmedelvärde används för att testa påståenden om det sanna medelvärdet i populationen.

Minnesregler:

  • en population

  • kvantitativ variabel

  • vi vill testa ett påstående

Hypoteser:

Det finns tre möjliga alternativhypoteser:

Ha: populationsmedelvärdet är lägre än ett visst värde (less)

Ha: populationsmedelvärdet är högre än ett visst värde (greater)

Ha: populationsmedelvärdet är inte lika med ett visst värde (two.sided)

De två första typerna av alternativhypotes kallas enkelsidiga, den tredje kallas dubbelsidig. Värdet som jämförs med hämtas från påståendet som vi testar. Nollhypotesen formuleras som motsatsen till alternativhypotesen.

Testvariabeln beräknas enligt

\(t = \frac{\bar{x} - \mu_0}{\frac{s}{\sqrt{n}}}\)

\(t\) anger att testvariabeln följer sannolikhetsfördelningen t-fördelning och jämförs med denna för att avgöra om resultatet är statistiskt signifikant.

Kommandot för att beräkna testvariabeln och erhålla p-värdet är

t.test(datafile$variable, mu = value, alternative = "less"/"greater"/"two.sided")

Förutsättningar:

  • representativt stickprov

  • stickprovet består av minst 30 observationer

Exempel hypotesprövning för populationsmedelvärde

Vi studerar filen used_cars. Vi vill nu testa följande påstående: det sanna genomsnittliga annonspriset bland bilar av denna modell är högre än 215000 kronor.

Vi definierar variabeln som annonspris i kronor.

Variabeln är kvantitativ, och vi vill testa ett påstående om populationen av bilar av denna modell. Metoden är därför hypotesprövning för populationsmedelvärde.

Steg 1:

Hypoteserna formuleras enligt

H0: populationsmedelvärdet är högst 215000 kronor

Ha: populationsmedelvärdet är högre än 215000 kronor

Steg 2 - 3:

Eftersom vi vill pröva om populationsmedelvärdet är högre än ett visst värde väljer vi kommandot greater.

t.test(used_cars$price_sek, mu = 215000, alternative = "greater")
## 
##  One Sample t-test
## 
## data:  used_cars$price_sek
## t = 4.0127, df = 408, p-value = 3.571e-05
## alternative hypothesis: true mean is greater than 215000
## 95 percent confidence interval:
##  218233.2      Inf
## sample estimates:
## mean of x 
##  220487.8

Steg 4:

p-värdet är 3.571e-05 = 0.00003571 vilket är lägre än signifikansnivån 0.05. Slutsatsen blir att H0 förkastas. Vi är 95% säkra på att det sanna genomsnittliga annonspriset för bilmodellen är högre än 215000 kronor.

Vi konstaterar att stickprovet består av minst 30 observationer. Fundera också alltid på om stickprovet är representativt för populationen.

Konfidensintervall för populationsmedelvärde

Konfidensintervall för populationsmedelvärde används för att tolka och beskriva det sanna medelvärdet i populationen.

Minnesregler:

  • en population

  • kvantitativ variabel

  • vi vill tolka och beskriva variabeln

Konfidensintervallet beräknas enligt

\(\bar{x} \pm t_{1-\alpha/2} \cdot \frac{s}{\sqrt{n}}\)

där \(t_{1-\alpha/2}\) hämtas från t-fördelningen, och styr vilken konfidensnivå vi önskar.

Kommandot i RStudio är

t.test(datafile$variable, conf.level = 0.95, alternative = "two.sided")

Förutsättningar:

  • representativt stickprov

  • stickprovet består av minst 30 observationer

Exempel konfidensintervall för populationsmedelvärde

Vi använder filen used_cars. Hypotesprövningen visade att det sanna genomsnittliga annonspriset bland bilar av denna modell sannolikt är högre än 215000 kronor. Ett konfidensintervall ger oss en undre och övre intervallgräns för det sanna genomsnittliga annonspriset. Vi har att

Variabeln är annonspris i kronor.

Variabeln är kvantitativ, och vi vill bilda ett konfidensintervall för populationen av bilar av denna modell. Metoden är därför konfidensintervall för populationsmedelvärde.

t.test(used_cars$price_sek, conf.level = 0.95, alternative = "two.sided")
## 
##  One Sample t-test
## 
## data:  used_cars$price_sek
## t = 161.22, df = 408, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  217799.4 223176.2
## sample estimates:
## mean of x 
##  220487.8

Med 95% säkerhet är det sanna genomsnittliga annonspriset bland bilar av denna modell mellan 217799 och 223176 kr.

Vi konstaterar att stickprovet består av minst 30 observationer. Fundera också alltid på om stickprovet är representativt för populationen.

Hypotesprövning för populationsandel

Hypotesprövning för populationsandel används för att testa påståenden om den sanna andelen individer i populationen som har en viss egenskap.

Minnesregler:

  • en population

  • kvalitativ variabel

  • vi vill testa ett påstående

Hypoteser:

Det finns tre möjliga alternativhypoteser:

Ha: populationsandelen är lägre än ett visst värde (less)

Ha: populationsandelen är högre än ett visst värde (greater)

Ha: populationsandelen är inte lika med ett visst värde (two.sided)

Värdet som jämförs med hämtas från påståendet som vi testar. Nollhypotesen formuleras som motsatsen till alternativhypotesen.

Testvariabeln beräknas enligt

\(z = \frac{{p} - p_0}{\sqrt{\frac{p_0(1 - p_0)}{n}}}\)

Testvariabeln jämförs med normalfördelningen för att avgöra om resultatet är statistiskt signifikant.

Kommandot i RStudio är

prop.test(x = count, n = sample size, p = probability of success, alternative = "less"/"greater"/"two.sided")

Förutsättningar:

  • representativt stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5

Exempel hypotesprövning för populationsandel

Använd filen used_cars och testa följande påstående på 5% signifikansnivå: den sanna andelen vita bilar av den aktuella modellen är lägre än 25%.

Variabeln vi studerar är händelsen att bilen är vit.

Variabeln är kvalitativ, och vi vill dra testa ett påstående om populationen av bilar av denna modell. Metoden är därför hypotesprövning för populationsandel.

Steg 1:

Hypoteserna formuleras enligt

H0: populationsandelen vita bilar är minst 25%

Ha: populationsandelen vita bilar är lägre än 25%

Steg 2 - 3:

Vi börjar med att ta fram en frekvenstabell för att få fram antalet vita bilar i stickprovet, samt stickprovsstorleken.

table(used_cars$color)
## 
## black  blue   red white 
##    94   107   111    97

Totalt finns 97 vita bilar i stickprovet, och stickprovsstorleken är 409. Eftersom vi vill pröva om populationsandelen är lägre än ett visst värde väljer vi kommandot less.

prop.test(x = 97, n = 409, p = 0.25, alternative = "less")
## 
##  1-sample proportions test with continuity correction
## 
## data:  97 out of 409, null probability 0.25
## X-squared = 0.29421, df = 1, p-value = 0.2938
## alternative hypothesis: true p is less than 0.25
## 95 percent confidence interval:
##  0.0000000 0.2746898
## sample estimates:
##         p 
## 0.2371638

Steg 4:

p-värdet är 0.2938 vilket är högre än signifikansnivån 0.05. Slutsatsen blir att H0 ej kan förkastas. Vi kan därför inte dra någon entydig slutsats av hypotesprövningen.

Kontrollberäkning av förutsättningarna ger stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) = 409 * 97/409 * (1 - 97/409) = 74, vilket är högre än de 5 som krävs. Fundera också alltid på om stickprovet är representativt för populationen.

Konfidensintervall för populationsandel

Konfidensintervall för populationsandel används för att tolka och beskriva den sanna andelen individer i populationen som har en viss egenskap.

Minnesregler:

  • en population

  • kvalitativ variabel

  • vi vill tolka och beskriva variabeln

Konfidensintervallet beräknas enligt

\({p} \pm z_{1-\alpha/2} \cdot \sqrt{\frac{{p}(1 - {p})}{n}}\)

där \(z_{1-\alpha/2}\) hämtas från normalfördelningen, och styr vilken konfidensnivå vi önskar.

Formel:

prop.test(x = count, n = sample size, conf.level = 0.95, alternative = "two.sided")

Förutsättningar:

  • representativt stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5

Exempel konfidensintervall för populationsandel

Använd filen used_cars. Beräkna ett 95% konfidensintervall för den sanna andelen av bilarna av den aktuella modellen som har den högsta utrustningsnivån.

Variabeln definieras enligt händelsen att bilen har högsta utrustningsnivån.

Variabeln är kvalitativ, och vi vill bilda ett konfidensintervall för populationen av bilar av denna modell. Metoden är därför konfidensintervall för populationsandel.

Vi börjar med att bilda en frekvenstabell för att studera antalet bilar i stickprovet med högsta utrustningsnivån, samt stickprovsstorleken.

table(used_cars$equipment)
## 
##   high    low medium 
##     51    103    255

51 bilar i stickprovet om 409 bilar har den högsta utrustningsnivån.

prop.test(x = 51, n = 409, conf.level = 0.95, alternative = "two.sided")
## 
##  1-sample proportions test with continuity correction
## 
## data:  51 out of 409, null probability 0.5
## X-squared = 228.94, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.09504873 0.16158826
## sample estimates:
##         p 
## 0.1246944

Med 95% säkerhet är den sanna andelen bilar av den aktuella modellen som har den högsta utrustningsnivån mellan 9.5% och 16.2%.

Kontrollberäkning av förutsättningarna ger

stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) = 409 * 51/409 * (1 - 51/409) = 45, vilket är större än de 5 som krävs. Fundera också alltid på om stickprovet är representativt för populationen.

Uppgift enpop.1

Vid ett användartest av en webbsajt noterar vi att 84 av 500 besökare scrollar ned mer än halva sidan.

  1. Bilda ett 95% konfidensintervall för den sanna andelen besökare som scrollar ned mer än halva sidan.

  2. Om stickprovsstorleken hade varit 1000 individer, hade felmarginalen blivit större eller mindre?

  3. Om konfidensnivån hade varit 80%, hade felmarginalen blivit större eller mindre?

  4. Om andelen som scrollar ned mer än halva sidan var 50%, hade felmarginalen blivit större eller mindre?

Uppgift enpop.2

Vi fortsätter att arbeta med användartestet från föregående uppgift.

Undersök om den sanna andelen besökare som scrollar ned mer än halva sidan är högre än 15%. Formulera hypoteser, genomför hypotesprövningen och dra slutsatser med ord. Använd 5% signifikansnivå.

Uppgift enpop.3

Utgå från filen santa_monica.

  1. Hur många observationer finns det för respektive år?

  2. Visualisera hur variabeln pageviews har utvecklats över studieperioden.

  3. Visualisera variabeln pageviews fördelat på år.

  4. Beräkna deskriptiv statistik över variabeln pageviews fördelat på år.

Uppgift enpop.4

Använd filen santa_monica.

Beräkna, baserat på data från år 2019, ett 95% konfidensintervall för det sanna genomsnittliga antalet pageviews per dag.

Uppgift enpop.5

Använd filen santa_monica.

Pröva, baserat på data från år 2019, om det sanna genomsnittliga antalet pageviews per dag överstiger 500. Välj 5% signifikansnivå.

Uppgift enpop.6

Använd filen santa_monica.

  1. Skapa, baserat på hela datafilen, en ny variabel som för varje rad anger om hemsidan haft mer än 800 pageviews eller ej.

  2. Beräkna ett 95% konfidensintervall för den sanna andelen av dagarna som hemsidan har mer än 800 pageviews.

  3. Pröva om den sanna andelen dagar som hemsidan har mer än 800 pageviews är lägre än 20%. Välj 5% signifikansnivå.

Uppgift enpop.7

Använd filen vasaloppet.

  1. Pröva på 5% signifikansnivå följande påstående: den sanna genomsnittliga sluttiden bland Vasaloppsåkare är mer än 30000 sekunder. Variabeln heter finish_time_seconds.

  2. Beräkna ett 95% konfidensintervall för den sanna genomsnittliga sluttiden bland vasaloppsåkare.

Uppgift enpop.8

Använd filen vasaloppet.

Beräkna 95% konfidensintervall för den sanna genomsnittliga sluttiden (variabel finish_time_seconds) bland Vasaloppsåkare separat för kvinnor och män.

Uppgift enpop.9

Använd filen data_AB.

Beräkna ett 95% konfidensintervall för sitens sanna genomsnittliga intäkt.

Uppgift enpop.10

Hur många timmar per vecka studerar du i genomsnitt?

Denna fråga ställdes till ett slumpmässigt urval om 500 heltidsstuderande programstudenter vid ett lärosäte. Enligt en överenskommelse som de flesta europeiska länder har skrivit under (Bologna) ska heltidsstudier för högskolor och universitet innebära 40 timmar per vecka.

Men vi är lite generösare och vill pröva följande påstående: den sanna genomsnittliga studietiden per vecka för programstudenter vid lärosätet är minst 35 timmar.

Data finns i filen studytime.


Statistisk inferens för jämförelse av populationer

Statistisk inferens för jämförelse av populationer betyder att vi har två populationer, som vi önskar jämföra. Om vi har en kvantitativ variabel så vill vi jämföra populationsmedelvärden, och är variabeln kvalitativ så handlar det om jämförelse av populationsandelar.

Men eftersom vi inte har information om alla individer i populationen, så gör vi jämförelsen baserat på stickprov dragna ur respektive population. För en kvantitativ variabel blir en punktskattning vid jämförelse av populationsmedelvärden skillnaden mellan stickprovsmedelvärdena. För en kvalitativ variabel blir punktskattningen skillnaden mellan populationsandelarna.

Precis som vid statistisk inferens om en population har vi två huvudverktyg: konfidensintervall och hypotesprövning. Konfidensintervall används för att tolka och beskriva skillnaden mellan populationerna, medan hypotesprövning används för att testa påståenden om skillnaden mellan populationerna.

Generellt om hypotesprövning för jämförelse

Syftet med hypotesprövning för jämförelse är att testa ett påstående om skillnaden mellan de två populationerna. Hypotesprövning genomförs i fyra steg.

Steg 1: formulera hypoteser

Alternativhypotesen Ha är det påstående som vi vill testa. Nollhypotesen H0 är motsatsen till påståendet. Det betyder att nollhypotesen och alternativhypotesen tillsammans täcker in alla möjliga utfall.

Steg 2: beräkna testvariabeln

Beräkning av testvariabeln innebär att vi jämför skillnaden i stickprovsmedelvärde/stickprovsandel mellan stickproven, samtidigt som vi tar hänsyn till den osäkerhet som finns i stickproven. Med osäkerhet avses stickprovsstorleken samt standardavvikelsen i respektive stickprov. Testvariabeln beräknas av RStudio.

Steg 3: beräkna p-värdet

RStudio beräknar sannolikheten för att erhålla denna testvariabel under antagandet att nollhypotesen är sann. Ju lägre denna sannolikhet är, desto mer benägna är vi att tro på alternativhypotesen.

Beslutsregeln är att om p-värdet är lägre än den osäkerhet som vi är beredda att acceptera (signifikansnivån), normalt 5%, så tror vi mer på alternativhypotesen. Vi kallar det för att nollhypotesen förkastas.

Steg 4: dra slutsats

I det sista steget tolkar vi resultatet av hypotesprövningen. Om nollhypotesen förkastas, och signifikansnivån är 5%, så är vi 95% säkra på att alternativhypotesen är sann. Om nollhypotesen däremot inte kan förkastas, så kan vi inte dra någon entydig slutsats av testet. Det följer ur att vi inte kan vara säkra på om nollhypotesen är sann, eller om vi har för små stickprov för att kunna visa att nollhypotesen ska förkastas.

Generellt om konfidensintervall för jämförelse

Punktskattningen av en jämförelse görs för en kvantitativ variabel genom att beräkna differensen i stickprovsmedelvärde mellan stickproven, och för en kvalitativ variabel genom att beräkna differensen i stickprovsandel mellan stickproven. Observera att vi själva bestämmer i vilken ordning vi vill mata in stickproven i analysen. Slutsatsen blir samma oavsett.

Konfidensintervallet utgår från punktskattningen men ger oss dessutom en undre och övre gräns, som vi med önskad säkerhet (normalt 95%), vet att den sanna skillnaden i populationsmedelvärde (för en kvantitativ variabel) eller den sanna skillnaden i populationsandel (för en kvalitativ variabel) finns inom. Den säkerhet vi väljer i konfidensintervallet kallas för konfidensnivå. Osäkerheten som återstår, 5% i ett konfidensintervall med konfidensnivå 95%, kallas för signifikansnivå.

Det finns tre möjliga resultat vid konfidensintervall för jämförelse.

  1. Om både den undre och den övre intervallgränsen är positiva är det populationen som vi matade in först “vinnare”: det är den som har högst populationsmedelvärde/populationsandel.

  2. Om både den undre och den övre intervallgränsen är negativa är det populationen som vi matade in som andra “vinnare”: det är den som har högst populationsmedelvärde/populationsandel.

  3. Om den undre intervallgränsen är negativ och den övre intervallgränsen är positiv finns ingen statistiskt säkerställd skillnad i populationsmedelvärde/populationsandel mellan populationerna.

Hypotesprövning för jämförelse av populationsmedelvärden

Hypotesprövning för jämförelse av populationsmedelvärden används för att testa påståenden om skillnad i sant medelvärde mellan två populationer.

Minnesregler:

  • två populationer

  • kvantitativ variabel

  • vi vill testa ett påstående om skillnad mellan populationerna

Hypoteser:

Det finns tre möjliga alternativhypoteser:

Ha: populationsmedelvärdet i den första populationen är lägre än populationsmedelvärdet i den andra populationen (less)

Ha: populationsmedelvärdet i den första populationen är högre än populationsmedelvärdet i den andra populationen (greater)

Ha: populationsmedelvärdet är inte samma i den första och den andra populationen (two.sided)

De två första typerna av alternativhypoteser kallas enkelsidiga och den tredje dubbelsidig. Nollhypotesen formuleras som motsatsen till alternativhypotesen.

Testvariabeln beräknas enligt

\(t = \frac{\bar{x_1} - \bar{x_2}}{\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}}\)

Testvariabeln jämförs med t-fördelningen för att avgöra om resultatet är statistiskt signifikant.

Kommandot i RStudio är

t.test(subset(datafile$variable, datafile$groupvariable=="group 1"), subset(datafile$variable, datafile$groupvariable=="group 2"), alternative = "less"/"greater"/"two.sided")

Förutsättningar:

  • representativa stickprov

  • båda stickproven består av minst 30 observationer

Exempel hypotesprövning för jämförelse av populationsmedelvärden

Använd filen used_cars. Pröva på 5% signifikansnivå följande påstående: det sanna genomsnittliga annonspriset bland bilar med utrustningsnivå high är högre än bland bilar med utrustningsnivå low.

Vi studerar variabeln annonspris i kronor.

Variabeln är kvantitativ, och vi vill testa ett påstående för att jämföra två populationer. Metoden är därför hypotesprövning för jämförelse av populationsmedelvärden.

Steg 1:

Vi testar hypoteserna

H0: populationsmedelvärdet är ej högre för utrustningsnivån high än low

Ha: populationsmedelvärdet är högre för utrustningsnivån high än low

Steg 2 - 3:

Eftersom vi vill pröva om populationsmedelvärdet är högre i den första populationen än i den andra väljer vi kommandot greater.

t.test(subset(used_cars$price_sek, used_cars$equipment=="high"), subset(used_cars$price_sek, used_cars$equipment=="low"), alternative = "greater")
## 
##  Welch Two Sample t-test
## 
## data:  subset(used_cars$price_sek, used_cars$equipment == "high") and subset(used_cars$price_sek, used_cars$equipment == "low")
## t = 10.49, df = 73.196, p-value < 2.2e-16
## alternative hypothesis: true difference in means is greater than 0
## 95 percent confidence interval:
##  49522.17      Inf
## sample estimates:
## mean of x mean of y 
##  256243.1  197371.8

Steg 4:

p-värdet är 2.2e-16 vilket är lägre än signifikansnivån 0.05. Slutsatsen blir att H0 förkastas. Vi är 95% säkra på att det sanna genomsnittliga annonspriset bland bilar med utrustningsnivå high är högre än de med utrustningsnivå low.

Vi konstaterar att vardera stickprovet består av minst 30 observationer. Fundera också alltid på om stickproven är representativa för respektive population.

Konfidensintervall för jämförelse av populationsmedelvärden

Konfidensintervall för jämförelse av populationsmedelvärden används för att tolka och beskriva den sanna skillnaden i medelvärde mellan två populationer.

Minnesregler:

  • två populationer

  • kvantitativ variabel

  • vi vill tolka och beskriva skillnaden mellan populationerna

Konfidensintervallet beräknas enligt

\((\bar{x_1} - \bar{x_2}) \pm t_{1-\alpha/2} \cdot \sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}\)

där \(t_{1-\alpha/2}\) hämtas från t-fördelningen, och styr vilken konfidensnivå vi önskar.

I RStudio beräknas konfidensintervallet genom

t.test(subset(datafile$variable, datafile$groupvariable=="group 1"), subset(datafile$variable, datafile$groupvariable=="group 2"), conf.level = 0.95, alternative = "two.sided")

Förutsättningar:

  • representativa stickprov

  • båda stickproven består av minst 30 observationer

Exempel konfidensintervall för jämförelse av populationsmedelvärden

Använd filen used_cars. Vi har kunnat visa att bilar med utrustningsnivån high i genomsnitt har högre annonspris än de med utrustningsnivå low. Beräkna ett 95% konfidensintervall för den sanna skillnaden i genomsnittligt annonspris beroende på om utrustningsnivån är high eller low.

Vi studerar variabeln annonspris i kronor.

Variabeln är kvantitativ och vi vill bilda ett konfidensintervall för att jämföra två populationer. Metoden är därför konfidensintervall för jämförelse av populationsmedelvärden.

t.test(subset(used_cars$price_sek, used_cars$equipment=="high"), subset(used_cars$price_sek, used_cars$equipment=="low"), conf.level = 0.95, alternative = "two.sided")
## 
##  Welch Two Sample t-test
## 
## data:  subset(used_cars$price_sek, used_cars$equipment == "high") and subset(used_cars$price_sek, used_cars$equipment == "low")
## t = 10.49, df = 73.196, p-value = 3.085e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  47687.25 70055.34
## sample estimates:
## mean of x mean of y 
##  256243.1  197371.8

Med 95% säkerhet är annonspriset mellan 57687 och 70055 kronor högre för bilar med utrustningsnivå high jämfört med low.

Vi konstaterar att vardera stickprovet består av minst 30 observationer. Fundera också alltid på om stickproven är representativa för respektive population.

Hypotesprövning för jämförelse av populationsandelar

Hypotesprövning för jämförelse av populationsandelar används för att testa påståenden om skillnad i sann andel individer med en viss egenskap mellan två populationer.

Minnesregler:

  • två populationer

  • kvalitativ variabel

  • vi vill testa ett påstående om skillnad mellan populationerna

Det finns tre möjliga alternativhypoteser:

Ha: populationsandelen i den första populationen är lägre än populationsandelen i den andra populationen (less)

Ha: populationsandelen i den första populationen är högre än populationsandelen i den andra populationen (greater)

Ha: populationsandelen är inte samma i den första och den andra populationen (two.sided)

Nollhypotesen formuleras som motsatsen till alternativhypotesen.

Testvariabeln beräknas enligt

\(z = \frac{p_1 - p_2}{\sqrt{\frac{p_1(1-p_1)}{n_1} + \frac{p_2(1-p_2)}{n_2}}}\)

där \(z\) hämtas från normalfördelningen, och styr vilken konfidensnivå vi önskar.

I RStudio beräknas konfidensintervallet enligt

prop.test(x = c(count sample 1, count sample 2), n = c(sample size 1, sample size 2), alternative = "less"/"greater"/"two.sided")

Förutsättningar:

  • representativa stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5 för båda stickproven

Exempel hypotesprövning för jämförelse av populationsandelar

Använd filen used_cars. Vit är standardfärg på denna bilmodell, och vi misstänker att bilar med hög utrustningsnivå också ofta är påkostade med en annan exteriörfärg. Testa därför följande påstående på 5% signifikansnivå: den sanna andelen vita bilar är lägre för utrustningsnivå high än för medium.

Vi definierar variabeln som händelsen att bilen är vit.

Variabeln är kvalitativ och vi vill testa ett påstående för att jämföra två populationer. Metoden är därför hypotesprövning för jämförelse av populationsandelar.

Steg 1:

Vi testar hypoteserna

H0: populationsandelen vita bilar är ej lägre för utrustningsnivå high än för medium

Ha: populationsandelen vita bilar är lägre för utrustningsnivå high än för medium

Steg 2 - 3:

Vi börjar med att ta fram en korstabell över bilarnas färger fördelat på utrustningsnivå i stickprovet.

CrossTable(used_cars$color, used_cars$equipment, prop.r = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Col Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  409 
## 
##  
##                 | used_cars$equipment 
## used_cars$color |      high |       low |    medium | Row Total | 
## ----------------|-----------|-----------|-----------|-----------|
##           black |        17 |        23 |        54 |        94 | 
##                 |     0.333 |     0.223 |     0.212 |           | 
## ----------------|-----------|-----------|-----------|-----------|
##            blue |        12 |        36 |        59 |       107 | 
##                 |     0.235 |     0.350 |     0.231 |           | 
## ----------------|-----------|-----------|-----------|-----------|
##             red |        16 |        17 |        78 |       111 | 
##                 |     0.314 |     0.165 |     0.306 |           | 
## ----------------|-----------|-----------|-----------|-----------|
##           white |         6 |        27 |        64 |        97 | 
##                 |     0.118 |     0.262 |     0.251 |           | 
## ----------------|-----------|-----------|-----------|-----------|
##    Column Total |        51 |       103 |       255 |       409 | 
##                 |     0.125 |     0.252 |     0.623 |           | 
## ----------------|-----------|-----------|-----------|-----------|
## 
## 

Vi utläser att det i stickprovet för utrustningsnivå high finns 6 vita bilar bland 51, och för utrustningsnivå medium 64 vita bilar bland 255. Eftersom vi vill pröva om populationsandelen är lägre i den första populationen än i den andra väljer vi kommandot less.

prop.test(x = c(6, 64), n = c(51, 255), alternative = "less")
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  c(6, 64) out of c(51, 255)
## X-squared = 3.5601, df = 1, p-value = 0.02959
## alternative hypothesis: less
## 95 percent confidence interval:
##  -1.00000000 -0.03495761
## sample estimates:
##    prop 1    prop 2 
## 0.1176471 0.2509804

Steg 4:

p-värdet är 0.02959 vilket är lägre än signifikansnivån 0.05. Slutsatsen blir att H0 förkastas. Vi är 95% säkra på att den sanna andelen vita bilar av den aktuella modellen med utrustningsnivå high är lägre än de med medium.

Vi kontrollerar att stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5 för båda stickproven:

51 * 6/51 * (1 - 6/51) = 5.3

255 * 64/255 * (1 - 64/255) = 47.9

Fundera också alltid på om stickproven är representativa för respektive population.

Konfidensintervall för jämförelse av populationsandelar

Konfidensintervall för jämförelse av populationsandelar används för att tolka och beskriva skillnaden i den sanna andelen individer som har en viss egenskap mellan två populationer.

Minnesregler:

  • två populationer

  • kvalitativ variabel

  • vi vill tolka och beskriva skillnaden mellan populationerna

Formeln för konfidensintervallet är

\(\left( p_1 - p_2 \right) \pm z_{1-\alpha/2} \sqrt{\frac{p_1(1 - p_1)}{n_1} + \frac{p_2(1 - p_2)}{n_2}}\)

där \(z_{1-\alpha/2}\) hämtas från normalfördelningen, och styr vilken konfidensnivå vi önskar.

I RStudio görs beräkningen enligt

prop.test(x = c(count sample 1, count sample 2), n = c(sample size 1, sample size 2), conf.level = 0.95, alternative = "two.sided")

Förutsättningar:

  • representativa stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5 för båda stickproven

Exempel konfidensintervall för jämförelse av populationsandelar

Vi har kunnat visa att vita bilar är ovanligare för utrustningsnivå high än medium. Men hur stor är skillnaden? Det kan vi undersöka genom ett konfidensintervall. Variabeln vi studerar är händelsen att bilen är vit.

Variabeln är kvalitativ, och vi vill bilda ett konfidensintervall för att jämföra två populationer. Metoden är därför konfidensintervall för jämförelse av populationsandelar.

Korstabellen från föregående analys visade att det i stickprovet för utrustningsnivå high finns 6 vita bilar bland 51, och för utrustningsnivå medium 64 vita bilar bland 255.

prop.test(x = c(6, 64), n = c(51, 255), conf.level = 0.95, alternative = "two.sided")
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  c(6, 64) out of c(51, 255)
## X-squared = 3.5601, df = 1, p-value = 0.05918
## alternative hypothesis: two.sided
## 95 percent confidence interval:
##  -0.24830143 -0.01836524
## sample estimates:
##    prop 1    prop 2 
## 0.1176471 0.2509804

Slutsatsen är att den sanna andelen vita bilar är mellan 1.8 och 24.8 procentenheter lägre för utrustningsnivå high jämfört med medium.

Förutsättningarna för analysen är samma som för hypotesprövning för jämförelse av populationsandelar, och har redan kontrollerats.

Stickprovsdimensionering

En viktig del i planeringen av datainsamling är hur stort stickprov som behövs. Är stickprovet för stort slösar vi tid och resurser. Är stickprovet däremot för litet har vi ingen chans att visa att det finns en signifikant skillnad mellan populationerna, även om det egentligen gör det. Principen är att definiera vilken variabel som är viktigast i studien, och vilken sorts analys som ska göras för denna variabel. Enklast och därför vanligast är att utnyttja hypotesprövning för jämförelse av populationsandelar. Då gör vi på följande sätt för att beräkna vilken stickprovsstorlek som behövs ur respektive population. Kommandot är

power.prop.test(p1=expected proportion group 1, p2=expected proportion group 2, alternative = "one.sided")

Lägg märke till alternative = “one.sided”. Det instruerar RStudio att vi vill undersöka om den sanna andelen är högre i den ena populationen än i den andra. Det är ovanligt att vi vill testa dubbelsidiga alternativhypoteser.

Exempel stickprovsdimensionering

En webbsida har ett formulär där besökaren kan registrera sig för att ta emot nyhetsbrev. Statistiken visar att cirka 5% av besökarna idag registrerar sig. Vi tror att vi kan öka denna andel till 6% genom att designa om formuläret. Hur stora stickprov behöver vi för att kunna visa att vårt omdesignade formulär är bättre?

Vår variabel är händelsen att besökaren registreras sig för nyhetsbrev.

Variabeln är kvalitativ och vi vill jämföra två populationer (det gamla och det nya formuläret).

power.prop.test(p1 = 0.05, p2 = 0.06, power = 0.8, sig.level = 0.05, alternative = "one.sided")
## 
##      Two-sample comparison of proportions power calculation 
## 
##               n = 6425.722
##              p1 = 0.05
##              p2 = 0.06
##       sig.level = 0.05
##           power = 0.8
##     alternative = one.sided
## 
## NOTE: n is number in *each* group

Resultatet visar att vi behöver stickprov om cirka 6425 besökare vardera för det gamla respektive det nya formuläret, för att kunna visa att den nya designen gett en uplift om 1 procentenhet.

Uppgift tvåpop.1

Vi genomför en mailkampanj och prövar två olika mailrubriker. Rubriken “Kampanj!” används till 5000 respondenter varav 1250 öppnar mailet. Rubriken “Erbjudande!” används till 4000 respondenter varav 900 öppnar mailet.

Pröva på 5% signifikansnivå om rubriken Kampanj ger högre andel som öppnar mailet.

Uppgift tvåpop.2

Vi fortsätter att arbeta med informationen från föregående uppgift.

Beräkna ett 99% konfidensintervall för skillnaden i resultat av mailkampanjen baserat på informationen i föregående uppgift.

Uppgift tvåpop.3

Använd filen vasaloppet.

Pröva på 5% signifikansnivå följande påstående: det finns statistiskt säkerställd skillnad i sluttid beroende på om åkaren tillhör en skidklubb eller ej.

Uppgift tvåpop.4

Använd filen santa_monica.

Pröva på 10% signifikansnivå följande påstående: den sanna genomsnittliga avg page load time är lägre år 2019 än år 2018.

Uppgift tvåpop.5

Använd filen data_AB.

Pröva på 5% signifikansnivå följande påstående: den sanna genomsnittliga revenue är högre för design B än för design A.

Uppgift tvåpop.6

Använd filen data_AB.

Bilda ett 95% konfidensintervall för den sanna skillnaden i genomsnittlig revenue mellan design A och design B.

Uppgift tvåpop.7

Använd filen studytime.

Testa följande påstående på 5% signifikansnivå: den genomsnittliga studietiden per vecka skiljer sig mellan programstudenter registrerade i Västerås respektive Eskilstuna.

Uppgift tvåpop.8

Använd filen studytime.

Beräkna ett 95% konfidensintervall för skillnaden i sann genomsnittlig studietid mellan programstudenter registrerade i Västerås respektive Eskilstuna.

Uppgift tvåpop.9

En landningssida har i genomsnitt 15 000 träffar per månad och konverteringsgraden 4%.

Vi utvecklar en alternativ landningssida som vi hoppas ska höja konverteringsgraden till 5%.

Hur länge bör A/B-testet pågå för att vi med 95% säkerhet ska kunna säkerställa att den alternativa landningssidan har högre konverteringsgrad än den ursprungliga?


Analys av frekvenstabeller

Ibland vill vi undersöka om de värden som en kvalitativ variabel antar förekommer med samma frekvens. Vi använder då chitvåtest för analys av frekvenstabell.

Minnesregler:

  • en population

  • en kvalitativ variabel

  • vi vill undersöka om variabelvärdena förekommer med samma frekvens

Hypoteser:

H0: variabelvärdena förekommer med samma frekvens

Ha: variabelvärdena förekommer ej med samma frekvens

Formeln för testvariabeln är

\(\chi^2 = \sum \frac{(O - E)^2}{E}\)

där \(O\) representerar de observerade och \(E\) de förväntade frekvenserna. Testvariabeln jämförs med \(\chi^2\)-fördelningen.

Kommandot i RStudio för att beräkna testet är

chisq.test(x = c(observed frequencies), p = (expected frequencies))

Förutsättningar:

  • representativt urval

  • förväntade frekvenser högre än 5 (se eventuella varningar när kommandot körs)

Exempel chitvåtest för frekvenstabell

Använd filen used_cars och pröva följande påstående: svarta, vita, blå och röda bilar är inte lika vanligt förekommande. Variabeln bilens färg är kvalitativ och vi vill undersöka om variabelvärdena är lika vanligt förekommande. Metoden är därför chitvåtest för frekvenstabell.

Steg 1:

H0: de olika färgerna är lika vanligt förekommande

Ha: de olika färgerna är inte lika vanligt förekommande

Steg 2-3:

Vi börjar med att ta fram en frekvenstabell för variabeln:

table(used_cars$color)
## 
## black  blue   red white 
##    94   107   111    97

Vi har därmed de observerade förväntade frekvenserna för varje variabelvärde. De förväntade frekvenserna för varje variabelvärde beräknas under antagandet att nollhypotesen är sann. Om färgerna är lika vanligt förekommande, och det finns fyra färger, så bör en fjärdedel av bilarna ha respektive färg.

chisq.test(x = c(94, 107, 111, 97), p = c(1/4, 1/4, 1/4, 1/4))
## 
##  Chi-squared test for given probabilities
## 
## data:  c(94, 107, 111, 97)
## X-squared = 1.9046, df = 3, p-value = 0.5924

Steg 4:

p-värdet är 0.5924, vilket är högre än den vanliga signifikansnivån 0.05. Vi kan inte dra någon entydig slutsats av testet, men det finns heller inga tecken på att de skillnader i frekvens mellan färgerna som observerats i stickprovet inte bara beror på slumpen.

Inga varningar gavs vilket visar att vi har tillräckligt med data för analysen. Fundera som alltid om stickprovet är representativt för populationen.

Uppgift frek.1

Använd filen data_AB.

Vi vill undersöka om trafiken slumpmässigt fördelats mellan design A och B på ett korrekt sätt. Pröva följande påstående på 5% signifikansnivå: vardera designvariationen har visats med sannolikheten 0.5.

Uppgift frek.2

Använd filen santa_monica.

  1. Gör en tabell över antalet mätningar som gjorts per månad (variabeln month). Tabellen ska uttryckas i absoluta och relativa frekvenser.

  2. Pröva på 5% signifikansnivå följande påstående: det finns skillnad i frekvens av antalet mätningar per månad.


Samband mellan kvalitativa variabler

Sambandsanalys handlar om att studera samvariationen mellan två variabler. Fokus är i första hand att genom hypotesprövning undersöka om det föreligger ett samband, och i andra hand att tolka vad sambandet innebär. Olika ansatser används beroende på om variablerna som ska analyseras är kvalitativa eller kvantitativa.

Chitvåtest

Chitvåtest används för att analysera samband mellan två kvalitativa variabler.

Minnesregler:

  • en population

  • två kvalitativa variabler

  • vi vill undersöka om det finns samband mellan variablerna

Hypoteser:

H0: det finns inget samband mellan variablerna

Ha: det finns samband mellan variablerna

Formeln för testvariabeln är

\(\chi^2 = \sum \frac{(O - E)^2}{E}\)

där \(O\) representerar de observerade och \(E\) de förväntade frekvenserna. Testvariabeln jämförs med \(\chi^2\)-fördelningen.

Kommandot i RStudio för att beräkna testet är

CrossTable(datafile$row_variable, datafile$column_variable, expected = TRUE, chisq = TRUE)

Förutsättningar:

  • representativt urval

  • förväntade frekvenser högre än 5 (se eventuella varningar när kommandot körs)

Exempel chitvåtest

Använd filen used_cars och testa följande påstående: det finns ett samband mellan utrustningsnivå och bilens färg.

Variablerna utrustningsnivå och färg är kvalitativa. Vi vill undersöka om det finns ett samband mellan variablerna. Metoden är därför chitvåtest.

Steg 1:

H0: det finns inget samband mellan utrustningsnivå och bilens färg

Ha: det finns samband mellan utrustningsnivå och bilens färg

Steg 2-3:

CrossTable(used_cars$equipment, used_cars$color, prop.c = FALSE, prop.t = FALSE, expected = TRUE, chisq = TRUE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |              Expected N |
## | Chi-square contribution |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  409 
## 
##  
##                     | used_cars$color 
## used_cars$equipment |     black |      blue |       red |     white | Row Total | 
## --------------------|-----------|-----------|-----------|-----------|-----------|
##                high |        17 |        12 |        16 |         6 |        51 | 
##                     |    11.721 |    13.342 |    13.841 |    12.095 |           | 
##                     |     2.377 |     0.135 |     0.337 |     3.072 |           | 
##                     |     0.333 |     0.235 |     0.314 |     0.118 |     0.125 | 
## --------------------|-----------|-----------|-----------|-----------|-----------|
##                 low |        23 |        36 |        17 |        27 |       103 | 
##                     |    23.672 |    26.946 |    27.954 |    24.428 |           | 
##                     |     0.019 |     3.042 |     4.292 |     0.271 |           | 
##                     |     0.223 |     0.350 |     0.165 |     0.262 |     0.252 | 
## --------------------|-----------|-----------|-----------|-----------|-----------|
##              medium |        54 |        59 |        78 |        64 |       255 | 
##                     |    58.606 |    66.711 |    69.205 |    60.477 |           | 
##                     |     0.362 |     0.891 |     1.118 |     0.205 |           | 
##                     |     0.212 |     0.231 |     0.306 |     0.251 |     0.623 | 
## --------------------|-----------|-----------|-----------|-----------|-----------|
##        Column Total |        94 |       107 |       111 |        97 |       409 | 
## --------------------|-----------|-----------|-----------|-----------|-----------|
## 
##  
## Statistics for All Table Factors
## 
## 
## Pearson's Chi-squared test 
## ------------------------------------------------------------
## Chi^2 =  16.12121     d.f. =  6     p =  0.01311796 
## 
## 
## 

Steg 4:

p-värdet 0.01311796 är lägre än signifikansnivån 0.05. Med 95% säkerhet finns ett samband mellan utrustningsnivå och bilens färg.

Närmare granskning av korstabellens radprocent visar att svart färg är överrepresenterade bland bilar med hög utrustningsnivå, och att blå färg är vanligast bland bilar med låg utrustningsnivå.

Inga varningar gavs vilket visar att vi har tillräckligt med data för analysen. Fundera som alltid om stickprovet är representativt för populationen.

Uppgift kvalsamb.1

Vi genomför en undersökning med popup-ruta på en webbplats i syfte att få svar på följande frågor.

Fråga 1: Vilken webbläsare använder du?
( ) Chrome ( ) Safari ( ) Edge ( ) Annan

Fråga 2: Upplever du webbplatsen som snabb?
( ) Ja ( ) Nej

Data finns i filen browserspeed.

Pröva på 5% signifikansnivå om det finns ett samband mellan valet av webbläsare och om webbplatsen upplevs som snabb.

Uppgift kvalsamb.2

Kom du in på ditt förstahandsval?

Även denna fråga ställdes till programstudenterna i datafilen studytime.

Pröva följande påstående på 5% signifikansnivå: det finns ett samband mellan studieort och om man kom in på sitt förstahandsval.


Prediktiv modell med kvantitativ responsvariabel och en förklaringsvariabel

Minnesregler:

  • en population

  • vi vill undersöka samband

  • en kvantitativ responsvariabel

  • en förklaringsvariabel

För att analysera samband mellan två kvantitativa variabler följer vi en analyskedja i nio steg. Vi studerar dessa baserat på ett exempel där vi använder filen used_cars. Undersök om det finns ett sambandet mellan bilens pris och dess ålder. Om det finns ett samband, tolka vilken effekt som åldern har på bilens pris. Gör slutligen en prediktion av det förväntade priset hos bilar som är 16 månader gamla.

Steg 1: Definiera variabelroller

Responsvariabeln (y) är den variabel som vi vill förstå och förklaringsvariabeln (x) är den variabel som vi tror har ett samband med responsvariabeln. I detta fall är responsvariabeln bilens pris och förklaringsvariabeln är bilens ålder.

Steg 2: Visualisera

Sambandet visualiseras genom spridningsdiagram:

ggplot(data = datafile) +

aes(x = xvariable, y = yvariable) +

geom_point()

Var observant på om prickarna i spridningsdiagrammet följer en tänkt rät linje. Om ej, avbryt analysen.

ggplot(data = used_cars) +
  aes(x = age_months, y = price_sek) +
  geom_point()

Prickarna följer en rät linje med negativ lutning.

Steg 3: Beräkna korrelationskoefficienten

Korrelationskoefficienten är ett nyckeltal som anger hur starkt sambandet mellan variablerna är:

cor(datafile$yvariable, datafile$xvariable, use = "pairwise.complete.obs")

En generell skala för tolkning av korrelationskoefficienten är enligt följande.

Korrelationskoefficient Tolkning
Högre än \(\pm 0.85\) Mycket starkt samband
Mellan \(\pm 0.65\) och \(\pm 0.85\) Starkt samband
Mellan \(\pm 0.35\) och \(\pm 0.65\) Måttligt samband
Upp till \(\pm 0.35\) Svagt samband

Om korrelationen är nära 0 indikeras att det inte finns något samband och vi bör avbryta analysen.

cor(used_cars$price_sek, used_cars$age_months, use = "pairwise.complete.obs")
## [1] -0.7780863

Korrelationen är -0.78 vilket visar att sambandet är negativt och starkt. Ju äldre bilen är, desto lägre är priset. Det är rimligt.

Steg 4: Anpassa modell

Modellen, som kallas för enkel linjär regressionsmodell, syftar till att anpassa en rät linje till observationerna. Modellen har följande form.

\(y = \beta_0 + \beta_1 x + \varepsilon\)

\(\beta_0\) anger linjens nivå och \(\beta_1\) dess lutning. \(\varepsilon\) fångar den variation i responsvariabeln som modellen inte förklarar.

I RStudio anpassas modellen genom följande kommando:

model <- lm(yvariable ~ xvariable, data = datafile, na.action = na.exclude)

summary(modellnamn)

Modellnamnet är godtyckligt.

model1 <- lm(price_sek ~ age_months, data = used_cars, na.action = na.exclude)
summary(model1)
## 
## Call:
## lm(formula = price_sek ~ age_months, data = used_cars, na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -53701 -11067    -10   8973  66373 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 270681.34    2185.00  123.88   <2e-16 ***
## age_months   -1788.57      71.57  -24.99   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 17390 on 407 degrees of freedom
## Multiple R-squared:  0.6054, Adjusted R-squared:  0.6044 
## F-statistic: 624.5 on 1 and 407 DF,  p-value: < 2.2e-16

Steg 5: Testa om det finns samband mellan variablerna

Vi testar hypoteserna

H0: det finns inget samband

Ha: det finns ett samband

p-värdet tolkas enligt den vanliga beslutsregeln.

p-värdet < 2e-16 är lägre än signifikansnivån 0.05 varför nollhypotesen förkastas. Med 95% säkerhet finns ett statistiskt säkerställt samband mellan variablerna ålder och pris.

Steg 6: Tolka förklaringsgraden

Förklaringsgraden är ett mått på hur stor andel av variationen i responsvariabeln som modellen förklarar. I RStudio anges förklaringsgraden som Multiple RSquare.

Förklaringsgraden visar att 61% av variationen i bilarnas pris förklaras av deras ålder. Detta indikerar att det finns fler faktorer som påverkar priset än bara ålder. Exempel på detta skulle kunna vara körsträcka och extrautrustning.

Steg 7: Utvärdera modellen

Modellen utvärderas genom residualanalys. Residualer är avvikelserna mellan vad vi observerat för värden för responsvariabeln, och vad modellen förutspår att responsvariabelns värde bör vara.

Residualerna beräknas och läggs till i datafilen genom följande kommando:

datafile$residuals <- resid(model)

Regressionsmodellen bygger på följande förutsättningar:

  • konstant varians bland residualerna. Förutsättningen kan betraktas uppfylld om residualerna är slumpmässigt spridda kring 0 i ett spridningsdiagram där förklaringsvariabeln ligger på x-axeln och residualerna på y-axeln.

  • normalfördelade residualer. Antagandet om normalfördelning kontrolleras genom att rita ett histogram över residualerna, och bedöma om detta uppvisar normalfördelningens karaktäristiska klockform.

Residualerna sparas till datafilen:

used_cars$residuals <- resid(model1)

Vi ritar ett spridningsdiagram med residualerna på den stående axeln (y-axeln) och förklaringsvariabeln på x-axeln.

ggplot(data = used_cars) +
  aes(x = age_months, y = residuals) +
  geom_point()

Residualerna fördelar sig förhållandevis slumpmässigt kring 0 vilket indikerar att antagandet om konstant varians är uppfyllt.

Vi ritar också ett histogram över residualerna:

ggplot(data = used_cars) +
  aes(x = residuals) +
  geom_histogram()

Residualerna förefaller acceptabelt normalfördelade.

Ibland kan det underlätta modellutvärderingen för modeller med en förklaringsvariabel om man ritar in den anpassade linjen i spridningsdiagrammet:

ggplot(data = used_cars) +
        aes(x = age_months, y = price_sek) +
        geom_point() +
        geom_line(data = fortify(model1), aes(x = age_months, y = .fitted), color = "red")

Steg 8: Tolka modellen

Vi sätter ord på vilken effekt som förklaringsvariabeln har på responsvariabeln genom att bilda ett konfidensintervall. Kommandot för ett 95-procentigt konfidensintervall är confint(modellnamn, level = 0.95).

confint(model1, level = 0.95)
##                  2.5 %     97.5 %
## (Intercept) 266386.038 274976.638
## age_months   -1929.266  -1647.868

Tolkningen blir att med 95% säkerhet sjunker priset på bilen med i genomsnitt mellan 1648 kr och 1929 kr per månad.

Steg 9: Använd modellen för prediktion

Vi kan nu använda modellen för att predicera (förutsäga) värden för responsvariabeln för valfria värden för förklaringsvariabeln. Vi börjar med att ange det värde som vi vill göra en prediktion för:

prediction <- data.frame(xvariable = value)

Vi beräknar sedan prediktionen i form av ett intervall. Två typer av intervall finns att välja emellan, beroende på frågeställningen.

  • konfidensintervall (confidence) för prediktion används när vi vill dra slutsatser om det genomsnittliga värdet på responsvariabeln bland alla individer i populationen som har det variabelvärde som vi gör prediktionen för

  • prediktionsintervall (predict) används när vi vill dra slutsatser om en enskild individ i populationen som har det variabelvärde som vi gör prediktionen för

Analysen görs enligt

predict(model, prediction, interval = "confidence"/"predict")

Vi vill beräkna det förväntade priset bland bilar av denna modell som är 16 månader. Eftersom vi är ute efter snittpriset bland alla bilar väljer vi intervall av typen confidence.

new_data <- data.frame(age_months = 16)
predict(model1, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 242064.3 239668.5 244460.1

Värdet för 16 månader gamla bilar punktskattas till 242 064 kr. Med 95% säkerhet är det genomsnittliga priset för 16 månader gamla bilar mellan 239 696 kr och 244 460 kr.

Uppgift kvansamb.1

Använd filen vasaloppet.

Vi vill bygga en modell för att predicera sluttiden (responsvariabel, finish_time_seconds) baserat på åkarens sluttid förra gången (förklaringsvariabel, last_race_finish_time_seconds).

  1. Visualisera och tolka sambandet. Överväg/motivera om några observationer bör exkluderas.
  2. Beräkna korrelationskoefficienten.
  3. Anpassa den enkla linjära regressionsmodellen.
  4. Pröva på 5% signifikansnivå om det finns ett signifikant samband mellan variablerna.
  5. Tolka modellens förklaringsgrad. Är modellen välanpassad?
  6. Utvärdera modellen genom residualanalys.
  7. Tolka effekten av förklaringsvariabeln på responsvariabeln med ett 95% konfidensintervall.
  8. Gör en prognos (inklusive lämpligt osäkerhetsintervall) av förväntad sluttid för en åkare som förra gången hade sluttiden 30 000 sekunder.

Uppgift kvansamb.2

Vi vill baserat på datafilen santa_monica utreda sambandet mellan avg_page_load_time (förklaringsvariabel) och bounce_rate (responsvariabel).

  1. Visualisera och tolka sambandet. Överväg/motivera om några observationer bör exkluderas.
  2. Beräkna korrelationskoefficienten.
  3. Anpassa den enkla linjära regressionsmodellen.
  4. Pröva på 5% signifikansnivå om det finns ett signifikant samband mellan variablerna.
  5. Tolka modellens förklaringsgrad. Är modellen välanpassad?
  6. Utvärdera modellen genom residualanalys.
  7. Tolka effekten av förklaringsvariabeln på responsvariabeln med ett 95% konfidensintervall.
  8. Gör en prognos (inklusive lämpligt osäkerhetsintervall) av genomsnittlig förväntad bounce_rate om avg_page_load_time är 5 sekunder.

Uppgift kvansamb.3

Läs in filen pay_per_click. Vi är intresserade av sambandet mellan revenue (responsvariabel) och spend (förklaringsvariabel).

  1. Visualisera och tolka sambandet. Överväg/motivera om några observationer bör exkluderas.
  2. Beräkna korrelationskoefficienten.
  3. Anpassa den enkla linjära regressionsmodellen.
  4. Pröva på 5% signifikansnivå om det finns ett signifikant samband mellan variablerna.
  5. Tolka modellens förklaringsgrad. Är modellen välanpassad?
  6. Utvärdera modellen genom residualanalys.
  7. Tolka effekten av förklaringsvariabeln på responsvariabeln med ett 95% konfidensintervall.
  8. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) genomsnittlig revenue om spend är 50.

Uppgift kvansamb.4

Läs in filen data_AB. Vi är intresserade av sambandet mellan revenue (responsvariabel) och sessions (förklaringsvariabel).

  1. Visualisera och tolka sambandet. Överväg/motivera om några observationer bör exkluderas.
  2. Beräkna korrelationskoefficienten.
  3. Anpassa den enkla linjära regressionsmodellen.
  4. Pröva på 5% signifikansnivå om det finns ett signifikant samband mellan variablerna.
  5. Tolka modellens förklaringsgrad. Är modellen välanpassad?
  6. Utvärdera modellen genom residualanalys.
  7. Tolka effekten av förklaringsvariabeln på responsvariabeln med ett 95% konfidensintervall.
  8. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) genomsnittlig revenue om antalet sessions är 1, 10 respektive 50.

Uppgift kvansamb.5

Läs in filen valresultat. Välj väljarstödet för ett politiskt parti som responsvariabel och en socioekonomisk variabel som förklaringsvariabel.

  1. Visualisera och tolka sambandet. Överväg/motivera om några observationer bör exkluderas.
  2. Beräkna korrelationskoefficienten.
  3. Anpassa den enkla linjära regressionsmodellen.
  4. Pröva på 5% signifikansnivå om det finns ett signifikant samband mellan variablerna.
  5. Tolka modellens förklaringsgrad. Är modellen välanpassad?
  6. Utvärdera modellen genom residualanalys.
  7. Tolka effekten av förklaringsvariabeln på responsvariabeln med ett 95% konfidensintervall.
  8. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) väljarstödet för ditt parti för några olika värden för förklaringsvariabeln som du valt.

Prediktiv modell med kvantitativ responsvariabel och flera förklaringsvariabler

Minnesregler:

  • en population

  • vi vill undersöka samband

  • en kvantitativ responsvariabel

  • flera förklaringsvariabler

För att analysera samband mellan en kvantitativ responsvariabel och flera förklaringsvariabler, som antingen kan vara kvalitativa eller kvantitativa, följer vi en analyskedja i tolv steg. Vi exemplifierar med filen used_cars där vi vill veta om det finns samband mellan bilens pris, ålder och utrustningsnivå. Predicera sedan det förväntade priset hos bilar som är 16 månader gamla och som har utrustningsnivå medium.

Steg 1: Definiera variabelroller

Responsvariabeln (y) är den variabel som vi vill förstå. Förklaringsvariablerna kallar vi för x1, x2 och så vidare. Kvalitativa variabler kodas av RStudio automatiskt om till indikatorvariabler. För en kvalitativ variabel som antar två olika variabelvärden skapas en indikatorvariabel. Om den kvalitativa variabeln antar tre olika variabelvärden skapas två indikatorvariabler. Den generella regeln är att det skapas en indikatorvariabel färre än antalet värden som den kvalitativa variabeln antar. Det variabelvärde som ej får en indikatorvariabel kallas referenskategori.

För exemplet är responsvariabeln bilens pris och förklaringsvariablerna är ålder (kvantitativ) samt utrustningsnivå (kvalitativ).

Steg 2: Utforska sambanden

För att utforska sambanden använder vi visualisering (om båda variablerna är kvantitativa) och deskriptiv statistik (om förklaringsvariabeln är kvalitativ).

Sambanden mellan samtliga modellens kvantitativa variabler visualiseras genom spridningsdiagram:

ggplot(data = datafile) +

aes(x = xvariable, y = yvariable) +

geom_point()

Var observant på om det råder ett linjärt samband mellan respektive förklaringsvariabel och responsvariabeln.

Samband mellan kvalitativa variabler och responsvariabeln studeras bäst genom att ta fram deskriptiv statistik för den kvalitativa variabeln fördelat på respektive variabelvärde för den kvalitativa variabeln (se kapitlet om deskriptiv statistik).

Vi har tidigare (se kapitlet som prediktiv modell med kvantitativ responsvariabel och en förklaringsvariabel) studerat sambandet mellan bilens ålder och körsträcka, och funnit att det är linjärt och negativt. För utrustningsnivån beräknar vi deskriptiv statistik:

used_cars %>%
  group_by(equipment) %>%
  summarise(mean = mean(price_sek, na.rm = TRUE),
            standard_deviation = sd(price_sek, na.rm = TRUE),
            count = n())
## # A tibble: 3 × 4
##   equipment    mean standard_deviation count
##   <chr>       <dbl>              <dbl> <int>
## 1 high      256243.             36213.    51
## 2 low       197372.             24401.   103
## 3 medium    222674.             15916.   255

Vi konstaterar att prisnivån i genomsnitt är högre ju mer utrustning bilen har. Det är rimligt.

Steg 3: Beräkna korrelationskoefficienten

Vi beräknar korrelationskoefficienten mellan samtliga kvantitativa variabler.

cor(datafile$yvariable, datafile$xvariable, use = "pairwise.complete.obs")

Skalan för tolkning är samma som i fallet med en förklaringsvariabel.

Korrelationen mellan bilens pris och ålder beräknades i kapitlet om prediktiv modell med kvantitativ responsvariabel och en förklaringsvariabel till -0.78 vilket indikerar ett starkt negativt samband. Ju äldre bilen är, desto lägre är priset.

Steg 4: Anpassa initial modell

Den initiala modellen innehåller de variabler som vi baserat på visualisering och korrelationsberäkning bedömer är betydelsefulla. Modellen, som kallas för en multipel linjär regressionsmodell, anpassas genom

model <- lm(yvariable ~ xvariable1 + xvariable2 + ..., data = datafile, na.action = na.exclude)

summary(model)

Eftersom både körsträcka och utrustningsnivå förefaller betydelsefulla för bilens pris bygger vi modellen enligt följande.

model2 <- lm(price_sek ~ age_months + equipment, data = used_cars, na.action = na.exclude)
summary(model2)
## 
## Call:
## lm(formula = price_sek ~ age_months + equipment, data = used_cars, 
##     na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -43910  -8757   -962   7597  85135 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     282039.15    2499.90 112.820   <2e-16 ***
## age_months       -1440.96      71.52 -20.146   <2e-16 ***
## equipmentlow    -32051.27    2943.61 -10.888   <2e-16 ***
## equipmentmedium -20917.23    2434.42  -8.592   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15330 on 405 degrees of freedom
## Multiple R-squared:  0.6949, Adjusted R-squared:  0.6926 
## F-statistic: 307.5 on 3 and 405 DF,  p-value: < 2.2e-16

Vi lägger märke till att utrustningsnivå high är referenskategori.

Steg 5: Undersök modellens övergripande signifikans

Här testas hypoteserna

H0: ingen av förklaringsvariablerna har samband med responsvariabeln

Ha: åtminstone en av förklaringsvariablerna har samband med responsvariabeln

Testets p-värde finner vi på sista raden i utskriften (F-statistic).

p-värdet är lägre än 0.05 vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att åtminstone en av modellens förklaringsvariabler har samband med responsvariabeln.

Steg 6: Undersök signifikansen hos de enskilda förklaringsvariablerna

Här testar vi

H0: den första förklaringsvariabeln har inget samband med responsvariabeln

Ha: den första förklaringsvariabeln har samband med responsvariabeln

och så vidare för samtliga modellens förklaringsvariabler. p-värdet finner vi i sista kolumnen i tabellen Coefficients.

För exemplet undersöks

H0: age_months har inget samband med priset

Ha: age_months har samband med priset

p-värdet är lägre än 0.05 vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att age_months har samband med responsvariabeln.

H0: utrustningsnivå_low har inget samband med responsvariabeln

Ha: utrustningsnivå_low har samband med responsvariabeln

p-värdet är lägre än 0.05 vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att utrustningsnivå_low har samband med responsvariabeln.

H0: utrustningsnivå_medium har inget samband med responsvariabeln

Ha: utrustningsnivå_medium har samband med responsvariabeln

p-värdet är lägre än 0.05 vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att utrustningsnivå_medium har samband med responsvariabeln.

Steg 7: Undersök förklaringsgrad och justerad förklaringsgrad

Förklaringsgraden är ett mått på hur stor andel av variationen i responsvariabeln som modellen förklarar. I RStudio anges förklaringsgraden som Multiple RSquare.

När vi funderar på vilka förklaringsvariabler som ska ingå i en modell kan vi inte använda förklaringsgraden. Det beror på att den alltid är högre för en modell som innehåller fler förklaringsvariabler. För att kunna jämföra modeller med varandra presenterar därför RStudio också Adjusted R-squared (justerad förklaringsgrad), som vi kan använda för modelljämförelse.

69% av variationen i bilarnas pris förklaras av ålder och utrustningsnivå. Den modell vi nu arbetar med är bättre än den som endast innehöll ålder som förklaringsvariabel. Det ser vi på att den justerade förklaringsgraden ökat från 60.44% (se kapitlet om prediktiv modell för kvantitativ responsvariabel och en förklaringsvariabel) till 69.26%.

Steg 8: Kontrollera rimligheten i modellen

Med att bedöma rimligheten avses att kontrollera om de slutsatser vi drog från visualisering och korrelationsberäkning också går att utläsa från regressionsmodellen. Vi kunde under steg 2 och 3 konstatera att det råder ett negativt samband mellan bilens ålder och dess pris, och att bilar med högre utrustningsnivå i genomsnitt har högre pris.

Enligt modellen är effekten av bilens ålder på dess pris negativ. Det är rimligt.

utrustningsnivå_low och utrustningsnivå_medium har båda negativ effekt. Det är vad vi förväntar oss, eftersom den deskriptiva statistiken visade att bilar med utrustningsnivå high är dyrast.

Steg 9: Utveckla modellen och upprepa steg 5-8

Då samtliga förklaringsvariabler är signifikanta och modellen verkar rimlig, finns inget behov av utveckling.

Steg 10: Utvärdera modellen

Residualerna beräknas och läggs till i datafilen genom följande kommando:

datafile$residuals <- resid(model)

Vi sparar också predicerade värden för varje observation:

datafile$prediction <- fitted(model)

Regressionsmodellen bygger på följande förutsättningar:

  • konstant varians bland residualerna. Förutsättningen kan betraktas uppfylld om residualerna är slumpmässigt spridda kring 0 i ett spridningsdiagram där förklaringsvariabeln ligger på x-axeln och residualerna på y-axeln.

  • normalfördelade residualer. Antagandet om normalfördelning kontrolleras genom att rita ett histogram över residualerna, och bedöma om detta uppvisar normalfördelningens karaktäristiska klockform.

Residualerna sparas till datafilen:

used_cars$residuals <- resid(model2)
used_cars$predicted <- fitted(model2)

Vi ritar ett spridningsdiagram med residualerna på den stående axeln (y-axeln) och de predicerade värdena på x-axeln.

ggplot(data = used_cars) +
  aes(x = predicted, y = residuals) +
  geom_point()

Residualerna fördelar sig förhållandevis slumpmässigt kring 0 vilket indikerar att antagandet om konstant varians är uppfyllt.

Vi ritar också ett histogram över residualerna:

ggplot(data = used_cars) +
  aes(x = residuals) +
  geom_histogram()

Residualerna förefaller acceptabelt normalfördelade.

Den multipla regressionsmodellen kommer att bli opålitlig om det råder allt för starka samband mellan modellens förklaringsvariabler. Detta problem kallas för multikollinearitet och vi kan undersöka risken för detta genom att beräkna ett nyckeltal som kallas för VIF:

library(car)

vif(model)

Om det högsta vif-värdet är högre än 10 indikerar detta att denna förklaringsvariabel är allt för högt korrelerad med någon eller några andra förklaringsvariabler. Vi måste då ta bort denna variabel ur modellen och bygga modellen på nytt.

library(car)
vif(model2)
##                GVIF Df GVIF^(1/(2*Df))
## age_months 1.285238  1        1.133683
## equipment  1.285238  2        1.064746

Samtliga VIF-värden är lägre än 10 varför multikollinearitetsproblem ej finns i denna modell.

Observera att vi för en modell med flera förklaringsvariabler inte kan rita in modellen i ett spridningsdiagram, så som var möjligt när vi hade bara en förklaringsvariabel.

Steg 11: Tolka modellen

Vi beräknar konfidensintervall för effekten av varje förklaringsvariabel:

confint(model2, level = 0.95)
##                      2.5 %     97.5 %
## (Intercept)     277124.755 286953.554
## age_months       -1581.567  -1300.354
## equipmentlow    -37837.938 -26264.599
## equipmentmedium -25702.897 -16131.554

Skattningen för age_months visar att bilarna med 95% säkerhet sjunker med mellan 1300 och 1582 kronor per månad.

Bilar med låg utrustningsnivå kostar med 95% säkerhet mellan 26264 och 37838 kronor mindre än referenskategorin (hög utrustningsnivå), medan bilar med utrustningsnivå medium med 95% säkerhet kostar mellan 16132 och 25703 kronor mindre än de med hög utrustningsnivå.

Steg 12: Använd modellen för prediktion

Vi kan nu använda modellen för att predicera (förutsäga) värden för responsvariabeln för givna värden för förklaringsvariabeln. Vi börjar med att ange det värde som vi vill göra en prediktion för:

prediction <- data.frame(xvariable1 = value, xvariable2 = value, ...)

Vi beräknar sedan prediktionen i form av ett intervall. Två typer av intervall finns att välja emellan, beroende på frågeställningen.

  • konfidensintervall (confidence) för prediktion används när vi vill dra slutsatser om det genomsnittliga värdet på responsvariabeln bland alla individer i populationen som har det variabelvärde som vi gör prediktionen för

  • prediktionsintervall (predict) används när vi vill dra slutsatser om en enskild individ i populationen som har det variabelvärde som vi gör prediktionen för

Analysen görs enligt

predict(model, prediction, interval = "confidence"/"predict")

Vi är intresserade av det förväntade priset hos bilar som är 16 månader gamla och som har utrustningsnivå medium. Vi väljer därför confidence:

new_data <- data.frame(age_months = 16, equipment = "medium")
predict(model2, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 238066.6 235654.3 240478.8

Värdet för 16 månader gamla bilar med utrustningsnivå medium punktskattas till 238 067 kr. Med 95% säkerhet är priset mellan 235 654 kr och 240 479 kr.

Uppgift mulkvansamb.1

Läs in filen pay_per_click. Vi är intresserade av sambandet mellan revenue (responsvariabel) och spend, clicks samt display (förklaringsvariabler).

  1. Utforska sambanden på lämpligt sätt.

  2. Beräkna korrelationen mellan de kvantitativa variablerna.

  3. Anpassa en multipel linjär regressionsmodell till variablerna.

  4. Undersök den anpassade modellens övergripande signifikans. Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  6. Tolka modellens förklaringsgrad och notera den justerade förklaringsgraden.

  7. Kontrollera modellens rimlighet.

  8. Ser du några behov av att utveckla modellen? Om så, gör det.

  9. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  10. Beräkna och tolka VIF. Verkar det föreligga multikollinearitetsproblematik?

  11. Tolka med hjälp av ett 95% konfidensintervall effekten av varje förklaringsvariabel.

  12. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) förväntad revenue vid en viss tidpunkt när spend = 50, clicks = 500 och display = yes.

Uppgift mulkvansamb.2

Läs in filen data_GA. Vi är intresserade av sambandet mellan revenue (responsvariabel) och transactions, AvgSessionDuration samt design (förklaringsvariabler).

  1. Filtrera bort alla rader där Revenue = 0.

  2. Utforska sambanden på lämpligt sätt.

  3. Beräkna korrelationen mellan de kvantitativa variablerna.

  4. Anpassa en multipel linjär regressionsmodell.

  5. Undersök den anpassade modellens övergripande signifikans. Formulera hypoteser, tolka p-värdet och dra slutsats.

  6. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  7. Tolka modellens förklaringsgrad och notera den justerade förklaringsgraden.

  8. Kontrollera modellens rimlighet.

  9. Utveckla modellen.

  10. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  11. Beräkna och tolka VIF. Verkar det föreligga multikollinearitetsproblematik?

  12. Tolka med hjälp av ett 95% konfidensintervall effekten av varje förklaringsvariabel.

  13. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) genomsnittlig förväntad revenue om transactions = 5, AvgSessionDuration = 900 och Design = C.

Uppgift mulkvansamb.3

Läs in filen studytime_och_results. Vi är intresserade av sambandet mellan resultatet på tentamen (responsvariabel) och studentens ålder, studieort samt antalet studietimmar per vecka (förklaringsvariabler).

  1. Utforska sambanden på lämpligt sätt.

  2. Beräkna korrelationen mellan de kvantitativa variablerna.

  3. Anpassa en multipel linjär regressionsmodell.

  4. Undersök den anpassade modellens övergripande signifikans. Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  6. Tolka modellens förklaringsgrad och notera den justerade förklaringsgraden.

  7. Kontrollera modellens rimlighet.

  8. Utveckla modellen.

  9. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  10. Beräkna och tolka VIF. Verkar det föreligga multikollinearitetsproblematik?

  11. Tolka med hjälp av ett 95% konfidensintervall effekten av varje förklaringsvariabel.

  12. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) förväntat tentamensresultat för en 25-årig Västerås-student som lägger i genomsnitt 38 timmar per vecka på sina studier.

  13. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) förväntat genomsnittligt tentamensresultat bland 25-åriga Västerås-studenter som lägger i genomsnitt 38 timmar per vecka på sina studier.

Uppgift mulkvansamb.4

Använd filen vasaloppet. Vi vill predicera åkarens sluttid baserat på de variabler som finns i datafilen.

  1. Utforska sambanden på lämpligt sätt.

  2. Beräkna korrelationen mellan de kvantitativa variablerna.

  3. Anpassa en multipel linjär regressionsmodell.

  4. Undersök den anpassade modellens övergripande signifikans. Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  6. Tolka modellens förklaringsgrad och notera den justerade förklaringsgraden.

  7. Kontrollera modellens rimlighet.

  8. Utveckla modellen.

  9. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  10. Beräkna och tolka VIF. Verkar det föreligga multikollinearitetsproblematik?

  11. Tolka med hjälp av ett 95% konfidensintervall effekten av varje förklaringsvariabel.

  12. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) förväntad sluttid för en kvinnlig åkare som inte är medlem i skidklubb, har åkt Vasaloppet 2 gånger tidigare och som senaste gången genomförde loppet på 40 000 sekunder.

Uppgift mulkvansamb.5

Använd filen valresultat. Välj väljarstödet för ett politiskt parti som responsvariabel och flera socioekonomiska variabler som förklaringsvariabler.

  1. Utforska sambanden på lämpligt sätt.

  2. Beräkna korrelationen mellan de kvantitativa variablerna.

  3. Anpassa en multipel linjär regressionsmodell.

  4. Undersök den anpassade modellens övergripande signifikans. Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  6. Tolka modellens förklaringsgrad och notera den justerade förklaringsgraden.

  7. Kontrollera modellens rimlighet.

  8. Utveckla modellen.

  9. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  10. Beräkna och tolka VIF. Verkar det föreligga multikollinearitetsproblematik?

  11. Tolka med hjälp av ett 95% konfidensintervall effekten av varje förklaringsvariabel.

  12. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) väljarstödet för ditt politiska parti utifrån några olika värden för de socioekonomiska faktorer som du valt.

Uppgift mulkvansamb.6

Använd filen used_cars. Bilens pris är responsvariabel och dess körsträcka förklaringsvariabel.

  1. Utforska sambandet på lämpligt sätt.

  2. Anpassa en multipel linjär regressionsmodell.

  3. Undersök signifikansen hos de enskilda förklaringsvariablerna. Formulera hypoteser, tolka p-värdet och dra slutsats.

  4. Tolka modellens förklaringsgrad.

  5. Kontrollera modellens rimlighet.

  6. Ta fram modellens residualer, visualisera dem och utred om förutsättningarna är uppfyllda.

  7. Tolka effekten av bilens körsträcka på dess pris.

  8. Använd modellen för att predicera (inklusive lämpligt valt osäkerhetsintervall) genomsnittspriset för bilar av denna modell som gått 2000 mil.

Uppgift mulkvansamb.7

Använd filen used_cars. Bilens pris är responsvariabel.

  1. Filtrera bort bilar med låg utrustningsnivå.

  2. Visualisera sambandet mellan bilens ålder och dess priset fördelat på utrustningsnivå.

  3. Bygg en modell med ålder och utrustningsnivå samt interaktionen mellan ålder och utrustningsnivå som förklaringsvariabler.

  4. Tolka modellen.


Prediktiv modell med kvantitativ responsvariabel och tidsserie

Minnesregler:

  • en population

  • vi vill studera en variabels utveckling över tiden

  • en kvantitativ responsvariabel

En vanlig tillämpning av den prediktiva analysen är att förklara en variabels utveckling över tiden, och förutsäga framtida värden för variabeln. Arbetsgången är densamma som för de prediktiva modeller som behandlats i de två föregående kapitlen, men ytterligare kontroll av modellen krävs.

Utgå från filen gasprice, som visar priset i kronor per liter för bensin. Tidsserien börjar med januari år 1. Bygg en modell för att förklara bensinpriset per månad, och predicera det förväntade bensinpriset månad 125, 126 och 127.

Steg 1: Definiera variabelroller

För exemplet är responsvariabeln literpriset bensin i kronor och förklaringsvariabel är tidsindexet som representerar månaderna. Om tidsindex inte finns i datafilen kan detta skapas genom

datafil$tidsindex <- seq.int(nrow(datafil))

Steg 2: Utforska sambanden

För en tidsserie använder vi gärna linjediagram för att visualisera variabelns utveckling.

ggplot(data = datafil) +

aes(x = tidsindex, y = responsvariabel) +

geom_line()

ggplot(data = gasprice) +
  aes(x = month, y = SEK_per_liter) +
  geom_line()

Vi konstaterar att priset rört sig upp och ned under studieperioden, men att trenden pekar uppåt. Svängningarna ser dramatiska ut men lägg märke till y-axelns skala. Genom att tvinga denna att börja på 0 får vi en rättvisare visualisering av tidsserien:

ggplot(data = gasprice) +
  aes(x = month, y = SEK_per_liter) +
  geom_line() +
  ylim(0, NA)

Steg 3: Beräkna korrelationskoefficienten

Korrelationen mellan tidsindexet och responsvariabeln beräknas:

cor(gasprice$SEK_per_liter, gasprice$month, use = "pairwise.complete.obs")
## [1] 0.4774804

Korrelationen är 0.48, vilket kan betraktar som måttligt.

Steg 4: Anpassa initial modell

Vi bygger regressionsmodellen för sambandet mellan tidsindexet och bensinpriset.

model3 <- lm(SEK_per_liter ~ month, data = gasprice, na.action = na.exclude)
summary(model3)
## 
## Call:
## lm(formula = SEK_per_liter ~ month, data = gasprice, na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.1804 -0.6589  0.1356  0.6575  1.8805 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 16.47639    0.16280 101.206  < 2e-16 ***
## month        0.01357    0.00226   6.002 2.06e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.901 on 122 degrees of freedom
## Multiple R-squared:  0.228,  Adjusted R-squared:  0.2217 
## F-statistic: 36.03 on 1 and 122 DF,  p-value: 2.055e-08

Steg 5: Undersök modellens övergripande signifikans

Eftersom modellen endast innehåller en förklaringsvariabel, ger testet av modellens övergripande signifikans samma information som signifikansen hos förklaringsvariabeln.

Steg 6: Undersök signifikansen hos de enskilda förklaringsvariablerna

Här testar vi

H0: tidsindexet har inget samband med bensinpriset

Ha: tidsindexet har samband med bensinpriset

p-värdet är lägre än 0.05 vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att tidsindexet har ett samband med bensinpriset. Det kan vi tolka som att det finns en signifikant trend i bensinpriset.

Steg 7: Undersök förklaringsgrad och justerad förklaringsgrad

22.8% av variationen i bensinpris förklaras av tidens gång. Det är en förhållandevis låg förklaringsgrad, men det är inte ovanligt när man arbetar med en tidsserie.

Steg 8: Kontrollera rimligheten i modellen

Effekten av tiden på bensinpriset är positiv (0.01357). Det är rimligt, sett till linjediagrammet.

Steg 9: Utveckla modellen och upprepa steg 5-8

Då förklaringsvariabeln är signifikant och modellen verkar rimlig, finns inget behov av utveckling.

Steg 10: Utvärdera modellen

För en tidsserie blir det extra intressant att visualisera den anpassade modellen:

ggplot(data = gasprice) +
        aes(x = month, y = SEK_per_liter) +
        geom_line() +
        geom_line(data = fortify(model3), aes(x = month, y = .fitted), color = "red")

Modellen tycks sammanfatta den övergripande trenden i tidsserien.

Residualerna sparas till datafilen:

gasprice$residuals <- resid(model3)

Vi ritar ett spridningsdiagram med residualerna på den stående axeln (y-axeln) och de tidsindexet på x-axeln.

ggplot(data = gasprice) +
  aes(x = month, y = residuals) +
  geom_point()

Vi noterar att residualerna uppvisar ett mönster, vilket ej är i enlighet med förutsättningarna. När denna typ av mönster finns i en tidsserie, kallas det autokorrelation och följer ur att observationerna i tidsserien inbördes har en samvariation. Det är naturligt att på varandra följande observationer, exempelvis bensinpriset månad för månad, hänger ihop med varandra. Det kan handla om variation inom året, eller konjunkturförändringar. Vi kan kontrollera om autokorrelationen är så kraftig att den påverkar modellens prediktiva förmåga på följande sätt:

library(car)

durbinWatsonTest(modellnamn)

Beslutsregeln är att om testvariabeln (D-W Statistic) är lägre än 1 eller högre än 3 föreligger autokorrelation, och då är modellen inte optimal. Vi undersöker:

library(car)
durbinWatsonTest(model3)
##  lag Autocorrelation D-W Statistic p-value
##    1       0.9137964     0.1586407       0
##  Alternative hypothesis: rho != 0

Vi noterar att testvariabeln är 0.16, det vill säga lägre än 1. Modellen har därför allt för hög autokorrelation för att duga. Detta framgår också om vi ritar in den anpassade modellen i visualiseringen:

ggplot(data = gasprice) +
        aes(x = month, y = SEK_per_liter) +
        geom_line() +
        geom_line(data = fortify(model3), aes(x = month, y = .fitted), color = "red")

Modellen behöver utvecklas. En väg att gå skulle kunna vara att skapa indikatorvariabler för årets månader och undersöka om det förbättrar modellen. Gör det som en övning!

Vi ritar också ett histogram över residualerna:

ggplot(data = gasprice) +
  aes(x = residuals) +
  geom_histogram()

Residualerna förefaller acceptabelt normalfördelade.

Steg 11: Tolka modellen

Vi tolkar modellen genom konfidensintervall:

confint(model3, level = 0.95)
##                    2.5 %      97.5 %
## (Intercept) 16.154109904 16.79866744
## month        0.009092875  0.01804204

Med 95% säkerhet så ökar bensinpriset med mellan 0.009 och 0.018 kronor per månad.

Steg 12: Använd modellen för prediktion

Vi är intresserade av bensinpriset i tidpunkt 125, 126 och 127. Vi väljer därför predict:

new_data <- data.frame(month = c(125, 126, 127))
predict(model3, new_data, interval = "predict")
##        fit      lwr      upr
## 1 18.17232 16.35991 19.98473
## 2 18.18589 16.37278 19.99900
## 3 18.19946 16.38564 20.01327

Resultatet visar punktskattning samt undre och övre intervallgräns i 95-procentiga intervall.

Uppgift tid.1

Utgå från filen pageviews.

  1. Gör ett linjediagram med antal sidvisningar på y-axeln och vecka på x-axeln.

  2. Beräkna korrelationskoefficienten mellan antal sidvisningar och vecka.

  3. Anpassa en modell som beskriver hur antalet sidvisningar förändrats i snitt mellan veckorna under studieperioden.

  4. Undersök om det finns ett signifikant samband mellan antal sidvisningar och vecka.

  5. Utvärdera om modellen är välanpassad genom att studera modellens förklaringsgrad, genomföra en residualanalys och bedöma graden av autokorrelation mellan modellens residualer.

  6. Tolka modellen.

  7. Predicera antalet sidvisningar vecka 19, 20, 21 och 22. Prediktionerna ska uttryckas med 95-procentiga osäkerhetsintervall av lämplig typ.

Uppgift tid.2

Utgå från filen santa_monica.

  1. Skapa ett tidsindex med värdet 1 på den första observationen.

  2. Gör ett linjediagram med pageviews på y-axeln och tidsindexet på x-axeln.

  3. Beräkna korrelationskoefficienten mellan tidsindexet och pageviews.

  4. Anpassa en modell för sambandet mellan pageviews och tidsindexet.

  5. Undersök om det finns ett signifikant samband mellan antal sidvisningar och vecka.

  6. Utvärdera om modellen är välanpassad genom att studera modellens förklaringsgrad, genomföra en residualanalys och bedöma graden av autokorrelation mellan modellens residualer.

  7. Tolka modellen.

  8. Predicera pageviews för den 1 januari 2020. Prediktionen ska uttryckas med 95-procentigt osäkerhetsintervall av lämplig typ.

Uppgift tid.3

  1. Gå till www.kiaindex.se och ladda ned webbplatstrafik för valfri webbsida.

  2. Läs in data i RStudio.

  3. Konvertera variabel av intresse till månadsformat.

  4. Anpassa en modell som beskriver hur variabeln förändrats i snitt mellan månaderna under studieperioden. Tolka med ord.

  5. Utvärdera om modellen är välanpassad genom att studera modellens förklaringsgrad, genomföra en residualanalys och bedöma graden av autokorrelation mellan modellens residualer. Tolka med ord.

  6. Predicera variabeln för de kommande fem månaderna. Prediktionerna ska uttryckas med 95-procentiga osäkerhetsintervall av lämplig typ.


Prediktiv modell med binär responsvariabel

Minnesregler:

  • en population

  • vi vill undersöka samband

  • en kvalitativ responsvariabel som antar två olika värden

  • en eller flera förklaringsvariabler

Om responsvariabeln är kvalitativ måste vi använda en annan typ av modell än den linjära regressionsanalysen. Vi studerar arbetsgången genom filen used_cars, där vi vill studera variabeln quicksale. Den anger om bilen sålts inom en vecka (kodat som 1) eller ej (kodat som 0). Finns det något samband mellan denna variabel och vilken typ av växellåda (automat eller manuell) som bilen har? Om ett samband finns, ska vi predicera sannolikheten för att en bil som har automatisk växellåda ska säljas inom en vecka.

Steg 1: Definiera variabelroller

Som vanligt definierar vi responsvariabeln som den variabel vi vill förstå och förklaringsvariabel som den eller de variabler som vi tror påverkar responsvariabeln. Här vill vi förstå variabeln quicksale (kvalitativ variabel) och som förklaringsvariabel används gear (kvalitativ variabel).

Steg 2: Utforska sambanden

Eftersom responsvariabeln endast antar två olika värden blir inte ett spridningsdiagram informativt. För att utforska sambanden använder vi därför korstabell (om båda variablerna är kvalitativa) och deskriptiv statistik (om förklaringsvariabeln är kvalitativ).

För exemplet använder vi korstabell:

CrossTable(used_cars$quicksale, used_cars$gear, prop.r = FALSE, prop.chisq = FALSE, prop.t = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Col Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  409 
## 
##  
##                     | used_cars$gear 
## used_cars$quicksale | automatic |    manual | Row Total | 
## --------------------|-----------|-----------|-----------|
##                   0 |        23 |       211 |       234 | 
##                     |     0.434 |     0.593 |           | 
## --------------------|-----------|-----------|-----------|
##                   1 |        30 |       145 |       175 | 
##                     |     0.566 |     0.407 |           | 
## --------------------|-----------|-----------|-----------|
##        Column Total |        53 |       356 |       409 | 
##                     |     0.130 |     0.870 |           | 
## --------------------|-----------|-----------|-----------|
## 
## 

Vi utläser att bland bilar som har automatisk växellåda säljs 56.6% inom en vecka, medan motsvarande siffra för de med manuell växellåda är 40.7%.

Steg 3: Anpassa modell

Den modell som används när responsvariabeln är kvalitativ och antar två olika värden kallas binär logistisk regressionsmodell. Modellen anpassas genom

modellnamn <- glm(responsvariabel ~ förklaringsvariabel, family = binomial, data = datafil)

summary(modellnamn)

Vi använder modellen för exemplet:

model4 <- glm(quicksale ~ gear, family = binomial, data = used_cars)
summary(model4)
## 
## Call:
## glm(formula = quicksale ~ gear, family = binomial, data = used_cars)
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)  
## (Intercept)   0.2657     0.2771   0.959   0.3377  
## gearmanual   -0.6408     0.2974  -2.155   0.0312 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 558.45  on 408  degrees of freedom
## Residual deviance: 553.76  on 407  degrees of freedom
## AIC: 557.76
## 
## Number of Fisher Scoring iterations: 4

Steg 4: Testa om det finns samband mellan variablerna

Vi testar hypoteserna

H0: det finns inget samband

Ha: det finns ett samband

Tolkningen sker genom p-värdet för förklaringsvariabeln:

p-värdet är lägre än 0.05, vilket betyder att nollhypotesen förkastas. Vi är 95% säkra på att det finns ett samband mellan variablerna.

Steg 5: Tolka modellen

För att tolka modellen på enklaste sätt skriver vi följande kommando:

exp(coef(modellnamn))

Effekten av förklaringsvariabeln på responsvariabeln presenteras då i termer av en oddskvot. Oddset för en händelse är sannolikheten för att händelsen ska inträffa dividerat med sannolikheten för att händelsen inte ska inträffa. Exempelvis är oddset för att få sexa vid ett tärningskast

(1/6) / (5/6) = 1/5

Det ska tolkas som att för varje gång vi förväntar oss att få en sexa, förväntar vi oss att inte få en sexa fem gånger.

Oddskvoten är ett mått som används för att beskriva förhållandet mellan två odds. Om vi till exempel har två grupper och vill jämföra deras odds för ett visst utfall, använder vi oddskvoten. Exempelvis är som vi just sett oddset för att få sexa vid tärningskast 1/5. På samma sätt är oddset för att få en prick vid tärningskast också 1/5. Om vi jämför oddset för att få sexa mot att få etta, är oddskvoten

(1/5) / (1/5) = 1

Detta betyder att chansen att få en sexa är samma som chansen att få en etta.

En oddskvot på 1 betyder att oddsen är lika, en oddskvot större än 1 betyder att oddsen är högre i den första gruppen, och en oddskvot mindre än 1 betyder att oddsen är lägre i den första gruppen.

Vi beräknar oddskvoten för att bilen säljs inom en vecka fördelat på om växellådan är automatisk eller manuell:

exp(coef(model4))
## (Intercept)  gearmanual 
##   1.3043478   0.5268562

Oddskvoten är 0.53, vilket tolkas som att oddset för att en bil med manuell växellåda ska säljas inom en vecka är 100% - 53% = 47% lägre än oddset för att en bil med automatisk växellåda ska säljas inom en vecka.

Steg 6: Utvärdera modellen

Modellen utvärderas genom att vi jämför observerade med predicerade värden för varje rad i datafilen. Vi börjar med att spara predicerade värden:

datafil$predicerade <- predict(modellnamn, datafil, type = "response")

Vi kategoriserar sedan de predicerade värdena som att händelsen förväntats inträffa om den predicerade sannolikheten är högre än 0.5:

datafil <- datafil %>%

mutate(predicerade = ifelse(predicerade > 0.5, 1, 0))

Nu kan vi utvärdera genom att bilda en korstabell mellan observerade och predicerade värden:

CrossTable(datafil$responsvariabel, datafil$predicerade, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)

Den resulterande korstabellen får följande utseende:

Predicerat 0 Predicerat 1
Observerat 0 Sann negativ Falsk positiv
Observerat 1 Falsk negativ Sann positiv

Modellens klassificeringsgrad beräknas enligt:

(sann positiv + sann negativ) / (sann positiv + sann negativ + falsk positiv + falsk negativ)

Vi utvärderar modellen för sambandet mellan om bilen sålts inom en vecka och växellådan:

used_cars$predicted <- predict(model4, used_cars, type = "response")

used_cars <- used_cars %>%
mutate(predicted = ifelse(predicted > 0.5, 1, 0))

CrossTable(used_cars$quicksale, used_cars$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  409 
## 
##  
##                     | used_cars$predicted 
## used_cars$quicksale |         0 |         1 | Row Total | 
## --------------------|-----------|-----------|-----------|
##                   0 |       211 |        23 |       234 | 
## --------------------|-----------|-----------|-----------|
##                   1 |       145 |        30 |       175 | 
## --------------------|-----------|-----------|-----------|
##        Column Total |       356 |        53 |       409 | 
## --------------------|-----------|-----------|-----------|
## 
## 

Vi utläser att 145 bilar som observerats som quicksale = 1 predicerats som 0 (falsk negativ), och att 23 bilar som observats som quicksale = 0 predicerats som 1 (falsk positiv). Klassificeringsgraden beräknas till

(30 + 211) / (30 + 211 + 23 + 145) = 59%

Ju högre procentsatsen är, desto bättre är modellen.

Steg 7: Använd modellen för prediktion

Modellen kan nu användas för prediktion genom följande kommandon:

prognosdata <- data.frame(förklaringsvariabel = variabelvärde)

predict(modellnamn, prognosdata, type="response")

Vi predicerar sannolikheten för att en bil med automatisk växellåda ska säljas inom en vecka:

new_data <- data.frame(gear = "automatic")
predict(model4, new_data, type = "response")
##         1 
## 0.5660377

Sannolikheten för att en bil med automatisk växellåda ska säljas inom en vecka är 57%.

Uppgift binlog.1

Använd filen titanic.

  1. Vi är intresserade av om passagerarens kön(förklaringsvariabel) påverkar chansen för överlevnad. Utforska sambandet på lämpligt sätt.

  2. Anpassa en binär logistisk regressionsmodell.

  3. Finns det ett signifikant samband? Formulera hypoteser, tolka p-värdet och dra slutsats.

  4. Tolka modellen med ord.

  5. Utred om modellen är välanpassad.

  6. Använd modellen för att predicera sannolikheten för överlevnad för en kvinnlig respektive manlig passagerare.

Uppgift binlog.2

Fortsätt arbeta med filen titanic.

  1. Bygg bästa möjliga modell för att förklara händelsen överlevnad.

  2. Utvärdera modellanpassningen.

  3. Ställ upp några olika scenarier (exempelvis ensam kvinnlig resenär om 40 år i klass 2) och predicera sannolikheten för överlevnad.

Uppgift binlog.3

Utgå från filen data_GA.

  1. Skapa en ny variabel som antar värdet 1 om konvertering skett (transactions > 0) och 0 annars.

  2. Vi är intresserade av om antalet sessions (förklaringsvariabel) påverkar händelsen konvertering. Utforska sambandet på lämpligt sätt.

  3. Anpassa en binär logistisk regressionsmodell.

  4. Finns det ett signifikant samband? Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Tolka modellen med ord.

  6. Utred om modellen är välanpassad.

  7. Använd modellen för att predicera sannolikheten för konvertering om antalet sessions är 1, 5 respektive 10.

Uppgift binlog.4

Fortsätt arbeta med filen data_GA.

  1. Bygg bästa möjliga modell för att förklara om konvertering skett.

  2. Utvärdera modellanpassningen.

  3. Ställ upp några olika scenarier (exempelvis att besökaren mött design_A och har spenderat i genomsnitt 200 sekunder på siten under 5 sessioner) och predicera sannolikheten för konvertering.

Uppgift binlog.5

Utfå från filen valresultat.

  1. Skapa en ny variabel som anger om det råder borgerlig majoritet i kommunen (kodat som 1) eller inte (kodat som 0).

  2. Vi är intresserade av om medelinkomsten (förklaringsvariabel) påverkar händelsen borgerlig majoritet. Utforska sambandet på lämpligt sätt.

  3. Anpassa en binär logistisk regressionsmodell.

  4. Finns det ett signifikant samband? Formulera hypoteser, tolka p-värdet och dra slutsats.

  5. Tolka modellen med ord.

  6. Utred om modellen är välanpassad.

  7. Använd modellen för att predicera sannolikheten för borgerlig majoritet i en kommun med medelinkomst 250 000 kr.

Uppgift binlog.6

Fortsätt arbeta med filen election_result.

  1. Bygg bästa möjliga modell för att förklara om borgerlig majoritet råder.

  2. Utvärdera modellanpassningen.

  3. Ställ upp några olika scenarier och predicera sannolikheten för borgerlig majoritet i en kommun.


Beslutsträd

Minnesregler:

  • en population

  • vi vill undersöka vad som förklarar en variabel

  • en kvalitativ responsvariabel som antar två eller flera olika värden

  • en eller flera förklaringsvariabler

Beslutsträd ger på ett visuellt och lättkommunicerat sätt information om samband och mönster i data samt kan användas för prediktiv analys. Den främsta fördelen med beslutsträd är att de kräver ytterst lite förberedande databearbetning.

Vi exemplifierar med filen used_cars och där målet är att förstå vad som får en bil att bli såld inom en vecka (quicksale = 1). Vårt mål med analysen är att predicera sannolikheten för att en bil som gått 1500 mil, är 12 månader gammal, har utrustningsnivå medium, automatisk växellåda, kostar 300 000 kronor är vit blir såld inom en vecka?

Steg 1: Definiera variabelroller

För exemplet är responsvariabeln quicksale. Som förklaringsvariabler använder vi alla tillgängliga variabler i datafilen.

Steg 2: Anpassa modellen

Vi (installerar och) aktiverar de paket som behövs:

library(rpart)

Beslutsträdet kan nu anpassas genom:

modellnamn <- rpart(responsvariabel ~ förklaringsvariabel1 + förklaringsvariabel2 + ..., data = datafil, method = 'class')

library(rpart)
model5 <- rpart(quicksale ~ distance_10_km + age_months + equipment + gear + price_sek + color, data = used_cars, method = "class")

Steg 3: Utvärdera modellen

Vi utvärderar modellanpassningen genom att spara modellens predicerade värden till datafilen

datafil$predicerade <- predict(modellnamn, datafil, type = 'class')

varpå vi kan bilda en korstabell:

used_cars$predicted <- predict(model5, used_cars, type = "class")
CrossTable(used_cars$quicksale, used_cars$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  409 
## 
##  
##                     | used_cars$predicted 
## used_cars$quicksale |         0 |         1 | Row Total | 
## --------------------|-----------|-----------|-----------|
##                   0 |       198 |        36 |       234 | 
## --------------------|-----------|-----------|-----------|
##                   1 |        77 |        98 |       175 | 
## --------------------|-----------|-----------|-----------|
##        Column Total |       275 |       134 |       409 | 
## --------------------|-----------|-----------|-----------|
## 
## 

Vi beräknar modellens klassificeringsgrad till

(198 + 98) / (198 + 98 + 36 + 77) = 72.4%

Steg 4: Rita beslutsträdet

Vi ritar beslutsträdet genom att (installera och) aktivera

library(rpart.plot)

rpart.plot(modellnamn, type = 4, extra = 101)

library(rpart.plot)
rpart.plot(model5, type = 4, extra = 101)

Överst i beslutsträdet ser vi fördelningen för responsvariabeln. Av de totalt 409 bilarna i datafilen var quicksale = 0 det vanligaste värdet. Närmare bestämt var det 234 bilar som tog mer än en vecka att bli sålda och 175 såldes inom en vecka.

Den viktigaste faktorn för att skilja quicksale 1 från 0 är bilens pris. 79% av bilarna kostar mindre än 238 000 kr och bland dem blev endast 127 sålda snabbare än en vecka. Bland de bilar som kostar mindre än 238 000 kr och som inte blev sålda inom en vecka är den näst viktigaste faktorn bilens ålder. Om bilen är mer än 37 månader gammal är risken stor att den inte blir såld inom en vecka. Om den däremot är mindre än 37 månader gammal måste vi också ta hänsyn till körsträckan.

Nederst i beslutsträdet summerar antalet bilar också till 409, om vi kontrollräknar. 0 eller 1 betyder vilket utfall som är vanligast längs just den grenen.

Ofta är det intressant att titta på de grenar som har högst antal. Om vi vore bilhandlare och ska köpa in en bil för att sälja den så snabbt som möjligt, vad ska vi då titta efter för egenskaper? Träddiagrammet indikerar att vi ska välja en bil som kostar mindre än 238 000 kr, som är mer än 38 månader gammal, som är röd eller blå och som gått som mest 4516 mil.

Lägg märke till att alla förklaringsvariabler som tas med i modellen ej nödvändigtvis kommer att ingå i beslutsträdet.

Steg 5: Använd modellen för prediktion

Modellen kan nu användas för prediktiv analys:

prognosdata <- data.frame(förklaringsvariabel1 = variabelvärde, förklaringsvariabel2 = variabelvärde, ...)

predict(modellnamn, prognosdata, type = "prob")

Vad är sannolikheten för att en bil som gått 1500 mil, är 12 månader gammal, har utrustningsnivå medium, automatisk växellåda, kostar 300 000 kronor är vit blir såld inom en vecka? Vi predicerar:

new_data <- data.frame(distance_10_km = 1500, age_months = 12, equipment = "medium", gear = "automatic", price_sek = 300000, color = "white")
predict(model5, new_data, type = "prob")
##           0         1
## 1 0.6666667 0.3333333

Det är 33% sannolikhet för att bilen blir såld inom en vecka, och 67% sannolikhet att den inte blir det.

Uppgift besltr.1

Läs in filen panelists. Filen är ett register över en panel, med följande variabler:

- exit ”yes” om panelisten avregistrerat sig från panelen, ”no” annars
- number_of_years antal år panelisten ingått i panelen
- more_than_five ”yes” om panelisten besvarat mer än fem undersökningar det senaste året, ”no” annars
- gender juridiskt kön ”female” eller ”male”
- panelistens ålder

Vårt mål är att undersöka vilka variabler som påverkar händelsen exit = yes.

  1. Utforska sambandet mellan varje variabel och exit.

  2. Anpassa ett beslutsträd.

  3. Utred om beslutsträdet är välanpassat till data.

  4. Tolka beslutsträdet med ord.

  5. Predicera sannolikheten för exit för en kvinna, 43 år som ingått i panelen i 4 år och som besvarat mer än 5 undersökningar det senaste året.

  6. Predicera sannolikheten för exit för en kvinna, 20 år som ingått i panelen i 2 år och som ej besvarat några undersökningar det senaste året.

Uppgift besltr.2

Utgå från filen titanic.

  1. Utred vilka variabler som kan vara relevanta för att förstå händelsen överlevnad.

  2. Anpassa ett beslutsträd.

  3. Utred om beslutsträdet är välanpassat till data.

  4. Tolka beslutsträdet med ord.

  5. Predicera sannolikheten för överlevnad för en 20-årig man som reser ensam i tredje klass. Han betalade 7 pund för sin biljett och steg på i Southampton.

  6. Predicera sannolikheten för överlevnad för en 17-årig kvinna som reser med sin mor och (blivande) make i första klass. Hon steg också på Southampton och biljetten kostade 200 pund.

Bygg ett beslutsträd för att förstå vilka passagerare som hade störst sannolikhet att överleva. Ställ sedan upp några scenarier och predicera sannolikheten för överlevnad.


Databearbetning

Här följer blandade övningar med fokus på att bearbeta data.

Uppgift data.1

Använd filen mcdonalds.

  1. Skapa en ny datafil som endast består av produkterna som hör till kategorin Breakfast.

  2. Baserat på den nya datafilen, exkludera variablerna Calories, Fat och Sugar.

Uppgift data.2

Ta bort den datafil som du just skapade.

Uppgift data.3

Använd filen spotify.

  1. Vilken är den vanligaste genren (variabel playlist_genre)? Vilken är ovanligast?

  2. Vilken artist har flest låtar?

  3. Variabeln duration_ms anger låtens längd i millisekunder. Skapa en ny variabel som anger låtens längd i minuter istället. Den nya variabeln ska heta duration_min_s.

  4. Presentera deskriptiv statistik över låtarnas längd i minuter fördelat på genre.

Uppgift data.4

Använd filen spotify.

Byt namn på variabeln duration_min_s till duration_min.

Uppgift data.5

Använd filen spotify.

  1. Skapa en ny variabel som anger om en låt tillhör kategorin pop eller ej. Låt den nya variabeln heta poplåt.

  2. Ta bort variabeln poplåt.

Uppgift data.6

Dra ett obundet slumpmässigt urval (OSU) om 50 låtar ur filen spotify.

Uppgift data.7

  1. Skapa en datafil som består av variabeln id som antar värdena 1, 2, 3, 4 och 5 samt variabeln x som antar värdena 10, 20, 30, 40 och 50. Kalla datafilen data1.

  2. Skapa en datafil som består av variabeln id som antar värdena 1, 2, 3, 4 och 6 samt variabeln y som antar värdena 10, 20, 30, 40 och 60. Kalla datafilen data2.

Uppgift data.8

Merga samman filerna data1 och data2.

Uppgift data.9

Fortsätt arbeta med data1 och data2.

Skapa en ny datafil (kalla den för stacked_data) som innehåller variabeln id i en kolumn och data från variablerna x och y i en annan kolumn. Detta kallas för att stapla data och är användbart när vi ska slå samman flera datafiler som innehåller samma variabler, exempelvis när data samlas in i omgångar.

Uppgift data.10

Använd filen stacked_data.

Exportera datafilen till Excelformat.

Uppgift data.11

  1. Skapa en ny datafil som innehåller en variabel som antar värden mellan 1 och 100.

  2. Använd funktionen cut_interval() för att dela in data i 5 lika stora intervall.

  3. Använd funktionen cut_number() för att dela in data i 5 intervall som innehåller lika många observationer.

  4. Använd funktionen cut_width() för att dela in data i intervall med bredden 5.


Lösningsförslag

Lösning vis.1

  1. Använd Import Dataset -> Excel.

Frekvenstabeller skapas med paketet janitor.

tabyl(mcdonalds$Category)
##  mcdonalds$Category  n    percent
##         Beef & Pork 15 0.05769231
##           Beverages 27 0.10384615
##           Breakfast 42 0.16153846
##      Chicken & Fish 27 0.10384615
##        Coffee & Tea 95 0.36538462
##            Desserts  7 0.02692308
##              Salads  6 0.02307692
##  Smoothies & Shakes 28 0.10769231
##      Snacks & Sides 13 0.05000000

Ett alternativt tillvägagångssätt är att använda tidyverse:

mcdonalds %>%
  group_by(Category) %>%
  summarise(antal = n()) %>%
  mutate(andel = antal/sum(antal))
## # A tibble: 9 × 3
##   Category           antal  andel
##   <chr>              <int>  <dbl>
## 1 Beef & Pork           15 0.0577
## 2 Beverages             27 0.104 
## 3 Breakfast             42 0.162 
## 4 Chicken & Fish        27 0.104 
## 5 Coffee & Tea          95 0.365 
## 6 Desserts               7 0.0269
## 7 Salads                 6 0.0231
## 8 Smoothies & Shakes    28 0.108 
## 9 Snacks & Sides        13 0.05

Lösning vis.2

ggplot(data = mcdonalds) +
  aes(x = Category, y = ..prop.., group = 1) +
  geom_bar() +
  theme(axis.text.x = element_text(angle = 90))

Category är en kvalitativ variabel varför vi väljer stapeldiagram. y = ..prop.., group = 1 ger relativa frekvenser och theme(axis.text.x = element_text(angle = 90)) roterar axelrubrikerna på x-axeln 90 grader. Dessa kommandon är ej nödvändiga men underlättar tolkningen.

ggplot(data = mcdonalds) +
  aes(x = Grams) +
  geom_histogram()

Grams är en kvantitativ variabel varför vi väljer histogram.

Lösning vis.3

basis_for_graph <- mcdonalds %>%
  group_by(Category) %>%
  summarize(mean_weight = mean(Grams))

ggplot(data = basis_for_graph) +
  aes(x = Category, y = mean_weight) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 90)) +
  geom_text(aes(label = round(mean_weight, 2)), vjust = -0.5, size = 3)

Här löste vi uppgiften i två steg. Först skapades ett nytt datamaterial underlag_för_graf med medelvikten per produktkategori. I nästa steg skapas ett stapeldiagram med produktkategori på x-axeln och medelvikt på y-axeln. Lägg märke till geom_col. Här kan vi inte använda geom_bar, då detta kommando endast tillåter oss att ha frekvenser på y-axeln

geom_text(aes(label = round(medelvikt, 2)), vjust = -0.5, size = 3) lägger till dataetiketter (med två decimaler) ovanför respektive stapel. Kommandot är ej nödvändigt men underlättar tolkningen.

Lösning vis.4

ggplot(data = mcdonalds) +
  aes(x = Category, y = Grams) +
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 90))

theme(axis.text.x = element_text(angle = 90)) är inte nödvändig men gör att axeltexterna blir snedställda och därmed mer lättlästa. Lägg märke till prickarna i lådagrammet. Prickarna representerar observationer som avviker med mer än 1.5 gånger lådans längd från tredje kvartilen.

ggplot(data = mcdonalds) +
  aes(x = Category, y = Grams) +
  geom_violin() +
  theme(axis.text.x = element_text(angle = 90))

Lösning vis.5

Båda variablerna är kvalitativa.

CrossTable(titanic$sex, titanic$survived, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##              | titanic$survived 
##  titanic$sex |         0 |         1 | Row Total | 
## -------------|-----------|-----------|-----------|
##       female |       127 |       339 |       466 | 
##              |     0.273 |     0.727 |     0.356 | 
## -------------|-----------|-----------|-----------|
##         male |       682 |       161 |       843 | 
##              |     0.809 |     0.191 |     0.644 | 
## -------------|-----------|-----------|-----------|
## Column Total |       809 |       500 |      1309 | 
## -------------|-----------|-----------|-----------|
## 
## 

72.7% av kvinnorna och 19.1% av männen överlevde. Lägg märke till kommandona prop.c = FALSE, prop.t = FALSE samt prop.chisq = FALSE. Dessa mått är standardinställda att visas (se hjälpfilen för kommandot CrossTable), men genom att ändra dem till FALSE blir tabellen kompaktare och lättare att läsa.

Lösning vis.6

Variabeln revenue är kvantitativ.

ggplot(data = data_AB) +
  aes(x = revenue) +
  geom_histogram()

ggplot(data = data_AB) +
  aes(x = revenue) +
  geom_histogram() +
  facet_wrap(~design)

Lösning vis.7

Variabeln hours är kvantitativ.

ggplot(data = studytime) +
  aes(x = hours) +
  geom_histogram(aes(y = ..density..)) +
  stat_function(fun = dnorm, args = list(mean = mean(studytime$hours), sd = sd(studytime$hours)), color = "red", size = 1)

Denna gång ritades ett histogram som visar relativa frekvenser (genom aes(y = ..density..)) samt med tillägg av normalfördelningskurva (raden som börjar med stat_function). Ett vanligt histogram går förstås också bra att visualisera.

ggplot(data = studytime) +
  aes(x = hours) +
  geom_histogram(aes(y = ..density..)) +
  facet_wrap(~campus)

Fördelningen är mer förskjuten åt högre värden i Västerås, vilket indikerar att man i genomsnitt studerar mer tid per vecka där.

Även denna gång lägger vi till aes(y = ..density..). Detta då stickprovsstorlekarna är olika mellan populationerna, vilket annars skulle ha försvårat tolkningen.

Lösning desk.1

Variabeln vikt är kvantitativ.

min(mcdonalds$Grams)
## [1] 28
max(mcdonalds$Grams)
## [1] 907

Den lättaste produkten väger 28 gram och den tyngsta 907 gram.

# Lowest weight
mcdonalds %>%
  arrange(Grams)
## # A tibble: 260 × 6
##    Category       Item                        Calories   Fat Sugars Grams
##    <chr>          <chr>                          <dbl> <dbl>  <dbl> <dbl>
##  1 Desserts       Chocolate Chip Cookie            160   8       15    28
##  2 Desserts       Oatmeal Raisin Cookie            150   6       13    28
##  3 Desserts       Kids Ice Cream Cone               45   1.5      6    28
##  4 Beverages      1% Low Fat Milk Jug              100   2.5     12    28
##  5 Beverages      Fat Free Chocolate Milk Jug      130   0       22    28
##  6 Snacks & Sides Apple Slices                      15   0        3    34
##  7 Snacks & Sides Kids French Fries                110   5        0    37
##  8 Breakfast      Hash Brown                       150   9        0    57
##  9 Chicken & Fish Chicken McNuggets (4 piece)      190  12        0    65
## 10 Snacks & Sides Small French Fries               230  11        0    74
## # ℹ 250 more rows
# Highest weight
mcdonalds %>%
  arrange(desc(Grams))
## # A tibble: 260 × 6
##    Category     Item                                 Calories   Fat Sugars Grams
##    <chr>        <chr>                                   <dbl> <dbl>  <dbl> <dbl>
##  1 Coffee & Tea Regular Iced Coffee (Large)               270     9     45   907
##  2 Coffee & Tea Caramel Iced Coffee (Large)               260     9     42   907
##  3 Coffee & Tea Hazelnut Iced Coffee (Large)              250     9     41   907
##  4 Coffee & Tea French Vanilla Iced Coffee (Large)        240     9     39   907
##  5 Coffee & Tea Iced Coffee with Sugar Free French …      160     9      2   907
##  6 Beverages    Coca-Cola Classic (Large)                 280     0     76   850
##  7 Beverages    Diet Coke (Large)                           0     0      0   850
##  8 Beverages    Dr Pepper (Large)                         270     0     70   850
##  9 Beverages    Diet Dr Pepper (Large)                      0     0      0   850
## 10 Beverages    Sprite (Large)                            280     0     74   850
## # ℹ 250 more rows

Den lättaste produkten är Chocolate Chip Cookie. Den tyngsta produkten är Coffee & Tea Regular (Large) (flera smaker).

Lösning desk.2

mean(mcdonalds$Grams, na.rm = TRUE)
## [1] 362.9923

Medelvikten bland produkterna är 363 gram.

sd(mcdonalds$Grams, na.rm = TRUE)
## [1] 200.0148

Standardavvikelsen, vilket är ett mått på spridningen i en variabel, är 200 gram.

# Median
median(mcdonalds$Grams, na.rm = TRUE)
## [1] 340
# Quartiles
quantile(mcdonalds$Grams, na.rm = TRUE)
##     0%    25%    50%    75%   100% 
##  28.00 192.25 340.00 454.00 907.00

Medianvikten är 340 gram (medianen är samma sak som den 50:e percentilen). Kvartiler betyder att datamaterialet delas upp i fyra lika stora delar. Den första kvartilen (25:e percentilen) är 192 gram. Det betyder att en produkt som väger 192 gram väger mer än 25% av alla produkter. Den tredje kvartilen (75:e percentilen) är 454 gram. Det betyder att en produkt som väger 454 gram väger mer än 75% av alla produkter.

Lösning desk.3

mcdonalds %>%
  group_by(Category) %>%
  summarize(average = mean(Grams, na.rm = TRUE),
            standard_deviation = sd(Grams, na.rm = TRUE), 
            count = n())
## # A tibble: 9 × 4
##   Category           average standard_deviation count
##   <chr>                <dbl>              <dbl> <int>
## 1 Beef & Pork           194.               53.7    15
## 2 Beverages             493.              231.     27
## 3 Breakfast             202                90.4    42
## 4 Chicken & Fish        243.              110.     27
## 5 Coffee & Tea          498.              149.     95
## 6 Desserts              100                76.5     7
## 7 Salads                272.               55.2     6
## 8 Smoothies & Shakes    429.              138.     28
## 9 Snacks & Sides        108.               39.4    13

Den produktkategori som i genomsnitt är tyngst är beverages (493 gram). Den produktkategori som i genomsnitt är lättast är desserts (100 gram). Spridningen i vikt är störst inom produktkategorin beverages (standardavvikelse 231 gram). Den produktkategori som innehåller flest produkter är coffee & tea (95 produkter).

Lösning desk.4

Variabeln genre är kvalitativ.

tabyl(spotify$playlist_genre)
##  spotify$playlist_genre    n   percent
##                     edm 6043 0.1840526
##                   latin 5155 0.1570067
##                     pop 5507 0.1677276
##                     r&b 5431 0.1654128
##                     rap 5746 0.1750069
##                    rock 4951 0.1507934
spotify %>%
  summarise(count = n_distinct(track_artist))
## # A tibble: 1 × 1
##   count
##   <int>
## 1 10693

Lösning desk.5

Variabeln låtens längd är kvantitativ.

spotify %>%
  group_by(playlist_genre) %>%
  summarise(average = mean(duration_ms, na.rm = TRUE),
            standard_deviation = sd(duration_ms, na.rm = TRUE),
            count = n()) %>%
  arrange(desc(average))
## # A tibble: 6 × 4
##   playlist_genre average standard_deviation count
##   <chr>            <dbl>              <dbl> <int>
## 1 rock           248577.             65477.  4951
## 2 r&b            237599.             57849.  5431
## 3 edm            222541.             69244.  6043
## 4 pop            217768.             45313.  5507
## 5 latin          216863.             48401.  5155
## 6 rap            214164.             60265.  5746

Lösning desk.6

average_per_genre <- spotify %>%
  group_by(playlist_genre, playlist_subgenre) %>%
  summarise(average = mean(duration_ms, na.rm = TRUE))

Lösning desk.7

titanic %>%
  summarise(count = n())
## # A tibble: 1 × 1
##   count
##   <int>
## 1  1309
titanic %>%
  summarise(count = sum(!is.na(home.dest)))
## # A tibble: 1 × 1
##   count
##   <int>
## 1   745
titanic %>%
  summarise(missing = sum(is.na(home.dest)))
## # A tibble: 1 × 1
##   missing
##     <int>
## 1     564

Lösning desk.8

Variabeln revenue är kvantitativ.

data_AB %>%
  group_by(design) %>%
  summarise(average = mean(revenue, na.rm = TRUE),
            lowest = min(revenue, na.rm = TRUE),
            highest = max(revenue, na.rm = TRUE),
            count = n())
## # A tibble: 2 × 5
##   design average lowest highest count
##   <chr>    <dbl>  <dbl>   <dbl> <int>
## 1 A        2009.   30.4   9942.  4989
## 2 B        2064.   93.1   9988.  5011

Lösning desk.9

Variabeln hours är kvantitativ.

mean(studytime$hours, na.rm = TRUE)
## [1] 35.242

I genomsnitt studerar programstudenterna 35.2 timmar per vecka.

studytime %>%
  group_by(campus) %>%
  summarise(average = mean(hours, na.rm = TRUE))
## # A tibble: 2 × 2
##   campus     average
##   <chr>        <dbl>
## 1 Eskilstuna    33.2
## 2 Västerås      36.3

I genomsnitt studerar programstudenter i Eskilstuna 33.2 timmar och i Västerås 36.3 timmar.

Lösning sann.1

tabyl(spotify$playlist_genre)
##  spotify$playlist_genre    n   percent
##                     edm 6043 0.1840526
##                   latin 5155 0.1570067
##                     pop 5507 0.1677276
##                     r&b 5431 0.1654128
##                     rap 5746 0.1750069
##                    rock 4951 0.1507934

Sannolikheten är cirka 15% att en slumpmässigt vald låt tillhör genren rock.

Lösning sann.2

  1. Låt

A vara händelsen att en variation är A

B vara händelsen att en variation är B

Sannolikheten för händelsen A och B är vardera 0.25

Sannolikheten för att en person som besöker webbsidan får se design A eller B är därför 0.25 + 0.25 = 0.5

  1. Låt

A vara händelsen att första visningen är variation A (sannolikhet 0.25)

B vara händelsen att andra visningen är variation A (sannolikhet 0.25)

Sannolikheten för att en person som besöker webbsidan med två olika enheter båda gångerna får se variation A är 0.25 * 0.25 = 0.0625

  1. Låt

A vara händelsen att första visningen är variation A (sannolikhet 0.25)

B vara händelsen att andra visningen är en annan variation (sannolikhet 0.75)

Sannolikheten för att en person som besöker webbsidan med två olika enheter först får se variation A och sedan en annan variation är 0.25 * 0.75 = 0.1875

Lösning sann.3

Vi studerar variabeln händelsen att användaren konverterat.

Antingen har en användare konverterat eller ej, och sannolikheten för att en användare ska konvertera påverkas inte av om en annan gör det. Vi har därför att variabeln är binomialfördelad med stickprovsstorlek 30 och andel 0.1.

  1. Vi beräknar väntevärdet:

    E(X) = 30 * 0.1 = 3

  2. Vi söker Pr(X < 2) = Pr(X = 0) + Pr(X = 1)

dbinom(0, size = 30, prob = 0.1) +  dbinom(1, size = 30, prob = 0.1)
## [1] 0.183695

Lösning sann.4

Vi definierar variabeln intäkt per månad.

Variabeln är normalfördelad med medelvärde 150000 och standardavvikelse 20000.

a.

Vi söker Pr⁡(X<140000)

pnorm(140000, mean = 150000, sd = 20000)
## [1] 0.3085375
  1. Vi söker Pr⁡(X>170000)
pnorm(170000, mean = 150000, sd = 20000, lower.tail = FALSE)
## [1] 0.1586553

Lösning sann.5

Vi studerar variabeln bilens färg. Variabeln är kvalitativ och vi börjar därför med att ta fram en frekvenstabell för att visualisera dess fördelning:

tabyl(used_cars$color)
##  used_cars$color   n   percent
##            black  94 0.2298289
##             blue 107 0.2616137
##              red 111 0.2713936
##            white  97 0.2371638

Tabellen visar att sannolikheten för en röd bil är 0.27.

Antingen är bilen röd eller ej, och sannolikheten för att en bil är röd påverkas inte av om en annan är det. Vi har därför att variabeln är binomialfördelad med stickprovsstorlek 10 och andel 0.27.

  1. Sannolikheten för att ingen av de 10 bilarna är röd:
dbinom(0, size = 10, prob = 0.27)
## [1] 0.04297626
  1. Sannolikheten för att alla 10 bilarna är röda:
dbinom(10, size = 10, prob = 0.27)
## [1] 2.058911e-06
  1. Sannolikheten för att färre än 3 av bilarna är röda:
dbinom(0, size = 10, prob = 0.27) + dbinom(1, size = 10, prob = 0.27) + dbinom(2, size = 10, prob = 0.27)
## [1] 0.4664888
  1. Sannolikheten för att 3 eller fler av bilarna är röda:
1 - (dbinom(0, size = 10, prob = 0.27) + dbinom(1, size = 10, prob = 0.27) + dbinom(2, size = 10, prob = 0.27))
## [1] 0.5335112

Lösning enpop.1

Variabeln händelsen att besökaren scrollar ned mer än halva sidan är kvalitativ. Vi vill dra slutsatser om en population genom konfidensintervall. Metoden är därför konfidensintervall för populationsandel.

prop.test(x = 84, n = 500, alternative = "two.sided", conf.level = 0.95)
## 
##  1-sample proportions test with continuity correction
## 
## data:  84 out of 500, null probability 0.5
## X-squared = 219.12, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1368728 0.2043432
## sample estimates:
##     p 
## 0.168

Med 95% säkerhet är den sanna andelen besökare som scrollar ned mer än halva sidan mellan 13.7% och 20.4%.

Kontrollera förutsättningar:

  • representativt urval

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5

  1. Större stickprovsstorlek ger mindre felmarginal.

  2. Lägre konfidensnivå ger mindre felmarginal.

  3. När vi arbetar med andelar blir osäkerheten som störst vid p = 0.5. Detta inses genom att beräkna p(1-p) för olika värden mellan 0 och 1 för p och konstatera att det blir högst (0.25) vid p = 0.5. Svaret är därför större.

Lösning enpop.2

Variabeln händelsen att besökaren scrollar ned mer än halva sidan är kvalitativ. Vi vill pröva ett påstående om en population. Metoden är därför hypotesprövning för populationsandel.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna andelen är högst 15%

Ha: den sanna andelen överstiger 15%

Steg 2: beräkna testvariabeln

prop.test(x = 84, n = 500, alternative = "greater", p = 0.15)
## 
##  1-sample proportions test with continuity correction
## 
## data:  84 out of 500, null probability 0.15
## X-squared = 1.1333, df = 1, p-value = 0.1435
## alternative hypothesis: true p is greater than 0.15
## 95 percent confidence interval:
##  0.1413714 1.0000000
## sample estimates:
##     p 
## 0.168

Steg 3: kan H0 förkastas?

p = 0.1298 > 0.05. H0 kan ej förkastas.

Steg 4: dra slutsats

Vi finner på 5% signifikansnivå inga belägg för att den sanna andelen besökare som scrollar ned mer än halva sidan är större än 15%. Ingen slutsats kan dras av testet.

Kontrollera förutsättningarna:

  • representativt urval

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5

Lösning enpop.3

  1. Bilda en frekvenstabell för variabeln year.
tabyl(santa_monica$year)
##  santa_monica$year   n  percent
##              Y2018 358 0.559375
##              Y2019 282 0.440625

2018 har vi 358 observationer och 2019 bara 282.

  1. Linjediagram är ett bra sätt att visualisera en variabels utveckling över tiden.
ggplot(data = santa_monica) +
  aes(x = date, y = pageviews) +
  geom_line()

Ur linjediagrammet kan vu utläsa en svagt nedåtgående trend. Det är också tydligt att det saknas mycket data under år 2019.

  1. Lådagram (boxplot) lämpar sig för att jämföra en kvantitativ variabel mellan grupper.
ggplot(data = santa_monica) +
  aes(x = year, y = pageviews) +
  geom_boxplot()

santa_monica %>%  
group_by(year) %>%
summarise(average = mean(pageviews, na.rm = TRUE),
standard_deviation = sd(pageviews, na.rm = TRUE),
count = n())
## # A tibble: 2 × 4
##   year  average standard_deviation count
##   <chr>   <dbl>              <dbl> <int>
## 1 Y2018    550.               293.   358
## 2 Y2019    550.               226.   282

Lösning enpop.4

Variabeln antal pageviews per dag är kvantitativ. Vi vill bilda konfidensintervall för en population. Metoden är därför konfidensintervall för populationsmedelvärde.

Börja med att filtrera fram år 2019 och spara data i en ny fil.

# Extract data from 2019
santa_monica2019 <- santa_monica %>%
filter(year == "Y2019")

# Compute the confidence interval
t.test(santa_monica2019$pageviews, alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  santa_monica2019$pageviews
## t = 40.848, df = 281, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  523.0201 575.9799
## sample estimates:
## mean of x 
##     549.5

Med 95% säkerhet är det sanna antalet pageviews i genomsnitt mellan 523 och 576 per dag.

Kontrollera förutsättningar:

  • representativt urval

  • minst 30 observationer

Lösning enpop.5

Variabeln antal pageviews per dag är kvantitativ. Vi vill pröva ett påstående om en population. Metoden är därför hypotesprövning för populationsmedelvärde.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: populationsmedelvärdet är högst 500

Ha: populationsmedelvärdet är högre än 500

Steg 2: beräkna testvariabeln

t.test(santa_monica2019$pageviews, mu = 500, alternative = "greater")
## 
##  One Sample t-test
## 
## data:  santa_monica2019$pageviews
## t = 3.6797, df = 281, p-value = 0.0001399
## alternative hypothesis: true mean is greater than 500
## 95 percent confidence interval:
##  527.2999      Inf
## sample estimates:
## mean of x 
##     549.5

Steg 3: kan H0 förkastas?

p = 0.0001399 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet överstiger det sanna genomsnittliga antalet pageviews per dag 500.

Kontrollera förutsättningar:

  • representativt urval

  • minst 30 observationer

Lösning enpop.6

santa_monica <- santa_monica %>%
mutate(fler_än_800 = ifelse(pageviews > 800, "ja", "nej"))

tabyl(santa_monica$fler_än_800)
##  santa_monica$fler_än_800   n  percent
##                        ja 110 0.171875
##                       nej 530 0.828125

Variabeln händelsen att antal pageviews överstiger 800 under en dag är kvalitativ. Vi vill dra slutsatser om en population baserat på konfidensintervall. Metoden är därför konfidensintervall för populationsandel.

110 av de 640 dagarna har det varit mer än 800 pageviews.

prop.test(x = 110, n = 640, alternative = "two.sided", conf.level = 0.95)
## 
##  1-sample proportions test with continuity correction
## 
## data:  110 out of 640, null probability 0.5
## X-squared = 274.31, df = 1, p-value < 2.2e-16
## alternative hypothesis: true p is not equal to 0.5
## 95 percent confidence interval:
##  0.1439011 0.2038685
## sample estimates:
##        p 
## 0.171875

Med 95% säkerhet är den sanna andelen dagar med mer än 800 pageviews mellan 14.4% och 20.4%.

Variabeln händelsen att antal pageviews överstiger 800 under en dag är kvalitativ. Vi vill pröva ett påstående om en population. Metoden är därför hypotesprövning för populationsandel.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna andelen är högre än eller lika med 20%

Ha: den sanna andelen är lägre än 20%

Steg 2: beräkna testvariabeln

prop.test(x = 110, n = 640, p = 0.2, alternative = "less")
## 
##  1-sample proportions test with continuity correction
## 
## data:  110 out of 640, null probability 0.2
## X-squared = 2.9907, df = 1, p-value = 0.04187
## alternative hypothesis: true p is less than 0.2
## 95 percent confidence interval:
##  0.0000000 0.1985949
## sample estimates:
##        p 
## 0.171875

Steg 3: kan H0 förkastas?

p = 0.03764 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet är den sanna andelen dagar som antalet pageviews överstiger 800 lägre än 20%.

Förutsättningar:

  • representativt urval

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5

Lösning enpop.7

Variabeln sluttid i sekunder är kvantitativ. Vi vill testa ett påstående om en population. Metoden är därför hypotesprövning för populationsmedelvärde.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: populationsmedelvärdet är högst 30000

Ha: populationsmedelvärdet är högre än 30000

Steg 2: beräkna testvariabeln

t.test(vasaloppet$finish_time_seconds, mu = 30000, alternative = "greater")
## 
##  One Sample t-test
## 
## data:  vasaloppet$finish_time_seconds
## t = 6.0075, df = 12621, p-value = 9.682e-10
## alternative hypothesis: true mean is greater than 30000
## 95 percent confidence interval:
##  30271.07      Inf
## sample estimates:
## mean of x 
##  30373.29

Steg 3: kan H0 förkastas?

p = 9.682e-10 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet överstiger den sanna genomsnittliga sluttiden 30000 sekunder.

Kontrollera förutsättningar:

  • representativt urval

  • minst 30 observationer

Variabeln sluttid i sekunder är kvantitativ. Vi vill bilda konfidensintervall för en population. Metoden är därför konfidensintervall för populationsmedelvärde.

t.test(vasaloppet$finish_time_seconds, alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  vasaloppet$finish_time_seconds
## t = 488.81, df = 12621, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  30251.49 30495.09
## sample estimates:
## mean of x 
##  30373.29

Med 95% säkerhet är den sanna genomsnittliga sluttiden bland Vasaloppsåkare mellan 30251 och 30495 sekunder.

Lösning enpop.8

Vi fortsätter att arbeta med den kvantitativa variabeln sluttid i sekunder.

Först skapas två separata datafiler.

kvinnor <- vasaloppet %>%
  filter(sex == "F")
män <- vasaloppet %>%
  filter(sex == "M")

Sedan genomförs analyserna. Variabeln är kvantitativ och vi vill dra slutsatser om en population baserat på konfidensintervall. Metoden är därför konfidensintervall för populationsmedelvärde.

t.test(kvinnor$finish_time_seconds, alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  kvinnor$finish_time_seconds
## t = 230.91, df = 1641, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  34681.23 35275.45
## sample estimates:
## mean of x 
##  34978.34
t.test(män$finish_time_seconds, alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  män$finish_time_seconds
## t = 454.66, df = 10968, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  29554.96 29810.90
## sample estimates:
## mean of x 
##  29682.93

Kvinnor: med 95% säkerhet är den sanna genomsnittliga sluttiden mellan 34681 och 35275 sekunder.

Män: med 95% säkerhet är den sanna genomsnittliga sluttiden mellan 29555 och 29811 sekunder.

Kontrollera förutsättningar:

  • representativt urval

  • minst 30 observationer

Lösning enpop.9

Variabeln revenue är kvantitativ. Vi vill dra slutsatser om en population baserat på konfidensintervall. Metoden är därför konfidensintervall för populationsmedelvärde.

t.test(data_AB$revenue, alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  data_AB$revenue
## t = 127.31, df = 9999, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
##  2005.202 2067.917
## sample estimates:
## mean of x 
##  2036.559

Med 95% säkerhet är den sanna genomsnittliga revenue bland handlande besökare mellan 2005 kr och 2068 kr.

Metoden förutsätter ett representativt urval samt minst 30 observationer.

Lösning enpop.10

Variabeln hours är kvantitativ. Vi vill testa ett påstående om en population. Metoden är därför hypotesprövning för populationsmedelvärde.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: populationsmedelvärdet är högst 35 timmar

Ha: populationsmedelvärdet är högre än 35 timmar

Steg 2: beräkna testvariabeln

t.test(studytime$hours, mu = 35, alternative = "greater")
## 
##  One Sample t-test
## 
## data:  studytime$hours
## t = 0.52985, df = 499, p-value = 0.2982
## alternative hypothesis: true mean is greater than 35
## 95 percent confidence interval:
##  34.48934      Inf
## sample estimates:
## mean of x 
##    35.242

Steg 3: kan H0 förkastas?

p = 0.2982 > 0.05

H0 kan ej förkastas.

Steg 4: dra slutsats

Vi kan ej dra någon entydig slutsats.

Kontrollera förutsättningar:

  • representativt urval

  • minst 30 observationer

Lösning tvåpop.1

Variabeln händelsen öppnat mail är kvalitativ.

Vi vill testa ett påstående för jämförelse av två populationer och väljer därför hypotesprövning för jämförelse av populationsandelar.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna andelen som öppnar “kampanj” är lägre än eller lika med den sanna andelen som öppnar “erbjudande”

Ha: den sanna andelen som öppnar “kampanj” är högre än den sanna andelen som öppnar “erbjudande”

Steg 2: beräkna testvariabeln

prop.test(x = c(1250, 900), n = c(5000, 4000), alternative = "greater")
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  c(1250, 900) out of c(5000, 4000)
## X-squared = 7.5019, df = 1, p-value = 0.003082
## alternative hypothesis: greater
## 95 percent confidence interval:
##  0.009962753 1.000000000
## sample estimates:
## prop 1 prop 2 
##  0.250  0.225

Steg 3: kan H0 förkastas?

p = 0.002856 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet är den sanna andelen som öppnar mail med rubriken kampanj högre än andelen som öppnar mail med rubriken erbjudande.

Förutsättningar:

  • två representativa stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5 för båda stickproven

Lösning tvåpop.2

Variabeln händelsen öppnat mail är kvalitativ.

Vi vill jämföra två populationer med konfidensintervall och använder därför konfidensintervall för jämförelse av populationsandelar.

prop.test(x = c(1250, 900), n = c(5000, 4000), alternative = "two.sided", conf.level = 0.99)
## 
##  2-sample test for equality of proportions with continuity correction
## 
## data:  c(1250, 900) out of c(5000, 4000)
## X-squared = 7.5019, df = 1, p-value = 0.006163
## alternative hypothesis: two.sided
## 99 percent confidence interval:
##  0.001579124 0.048420876
## sample estimates:
## prop 1 prop 2 
##  0.250  0.225

Med 99% säkerhet är den sanna andelen som öppnar mail med rubriken kampanj mellan 0.2 och 4.8 procentenheter högre än de som öppnar mail med rubriken erbjudande. Kom ihåg att differensen mellan två procenttal uttrycks som en skillnad i procentenheter.

Förutsättningar:

  • två representativa stickprov

  • stickprovsstorlek * stickprovsandel * (1 - stickprovsandel) är större än 5 för båda stickproven

Lösning tvåpop.3

Variabeln sluttid är kvantitativ. Vi vill jämföra två populationer med hypotesprövning. Metoden är därför hypotesprövning för jämförelse av populationsmedelvärden.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna genomsnittliga sluttiden är samma mellan åkare som tillhör respektive inte tillhör en skidklubb

Ha: den sanna genomsnittliga sluttiden är inte samma mellan åkare som tillhör respektive inte tillhör en skidklubb

Steg 2: beräkna testvariabeln

t.test(subset(vasaloppet$finish_time_seconds, vasaloppet$member_of_club == "yes"), subset(vasaloppet$finish_time_seconds, vasaloppet$member_of_club == "no"), alternative = "two.sided")
## 
##  Welch Two Sample t-test
## 
## data:  subset(vasaloppet$finish_time_seconds, vasaloppet$member_of_club == "yes") and subset(vasaloppet$finish_time_seconds, vasaloppet$member_of_club == "no")
## t = -0.31305, df = 9859.4, p-value = 0.7543
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -294.2475  213.2068
## sample estimates:
## mean of x mean of y 
##  30357.69  30398.21

Steg 3: kan H0 förkastas?

p = 0.7543 > 0.05

H0 kan ej förkastas.

Steg 4: dra slutsats

Det går inte att dra någon entydig slutsats av testet.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.4

Variabeln antal pageviews är kvantitativ. Vi vill jämföra två populationer med hypotesprövning. Metoden är därför hypotesprövning för jämförelse av populationsmedelvärden.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.10

H0: den sanna avg page load time är inte lägre år 2019 än år 2018

Ha: den sanna avg page load time är lägre år 2019 än år 2018

Steg 2: beräkna testvariabeln

t.test(subset(santa_monica$avg_page_load_time, santa_monica$year == "Y2019"), subset(santa_monica$avg_page_load_time, santa_monica$year == "Y2018"), alternative = "less")
## 
##  Welch Two Sample t-test
## 
## data:  subset(santa_monica$avg_page_load_time, santa_monica$year == "Y2019") and subset(santa_monica$avg_page_load_time, santa_monica$year == "Y2018")
## t = -1.3789, df = 615.75, p-value = 0.08421
## alternative hypothesis: true difference in means is less than 0
## 95 percent confidence interval:
##       -Inf 0.1017773
## sample estimates:
## mean of x mean of y 
##  4.539184  5.062011

Steg 3: kan H0 förkastas?

p = 0.08421 < 0.10

H0 förkastas.

Steg 4: dra slutsats

Vi är 90% säkra på att avg page load time är lägre år 2019 än år 2018.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.5

Variabeln revenue är kvantitativ. Vi vill jämföra två populationer med hypotesprövning. Metoden är därför hypotesprövning för jämförelse av populationsmedelvärden.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna genomsnittliga revenue är inte högre för design B än för design A

Ha: den sanna genomsnittliga revenue är högre för design B än för design A

Steg 2: beräkna testvariabeln

t.test(subset(data_AB$revenue, data_AB$design == "A"), subset(data_AB$revenue, data_AB$design == "B"), alternative = "less")
## 
##  Welch Two Sample t-test
## 
## data:  subset(data_AB$revenue, data_AB$design == "A") and subset(data_AB$revenue, data_AB$design == "B")
## t = -1.7274, df = 9995.7, p-value = 0.04206
## alternative hypothesis: true difference in means is less than 0
## 95 percent confidence interval:
##       -Inf -2.636592
## sample estimates:
## mean of x mean of y 
##  2008.867  2064.130

Steg 3: kan H0 förkastas?

p = 0.04206 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Vi är 95% säkra på att den sanna genomsnittliga revenue är högre för design B än för design A.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.6

Variabeln revenue är kvantitativ. Vi vill jämföra två populationer med konfidensintervall. Metoden är därför konfidensintervall för jämförelse av populationsmedelvärden.

t.test(subset(data_AB$revenue, data_AB$design == "A"), subset(data_AB$revenue, data_AB$design == "B"), alternative = "two.sided", conf.level = 0.95)
## 
##  Welch Two Sample t-test
## 
## data:  subset(data_AB$revenue, data_AB$design == "A") and subset(data_AB$revenue, data_AB$design == "B")
## t = -1.7274, df = 9995.7, p-value = 0.08412
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -117.97468    7.44716
## sample estimates:
## mean of x mean of y 
##  2008.867  2064.130

Konfidensintervallets undre gräns är negativ och den övre gränsen är positiv. Det betyder att vi inte finner någon statistiskt säkerställd skillnad i sann genomsnittlig revenue mellan design A och design B. Hur kan det bli så, när vi i förra uppgiften fick ett signifikant resultat? Det beror på att hypotesprövningen var enkelsidig: vi kunde visa att sann genomsnittlig revenue är högre för design B än för design A. Konfidensintervallet är däremot dubbelsidigt. Översatt i hypotesprövningstermer, svarar konfidensintervallet på om det finns skillnad i sann genomsnittlig revenue mellan design A och design B. Detta visar tydligt varför det är så viktigt att skilja på enkelsidig och dubbelsidig hypotesprövning.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.7

Variabeln hours är kvantitativ. Vi vill jämföra två populationer med hypotesprövning. Metoden är därför hypotesprövning för jämförelse av populationsmedelvärden.

Vi börjar med att visualisera data.

ggplot(data = studytime) +
  aes(x = campus, y = hours) +
  geom_violin()

Det finns indikationer på att studietiden är högre i Västerås.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: den sanna genomsnittliga studietiden är samma i Västerås och Eskilstuna

Ha: den sanna genomsnittliga studietiden är inte samma i Västerås och Eskilstuna

Steg 2: beräkna testvariabeln

t.test(subset(studytime$hours, studytime$campus == "Västerås"), subset(studytime$hours, studytime$campus == "Eskilstuna"), alternative = "two.sided")
## 
##  Welch Two Sample t-test
## 
## data:  subset(studytime$hours, studytime$campus == "Västerås") and subset(studytime$hours, studytime$campus == "Eskilstuna")
## t = 2.9996, df = 296.02, p-value = 0.002933
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  1.039536 5.005740
## sample estimates:
## mean of x mean of y 
##  36.26970  33.24706

Steg 3: kan H0 förkastas?

p = 0.002933 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Vi är 95% säkra på att det finns skillnad i sann genomsnittlig studietid mellan Västerås och Eskilstuna.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.8

Variabeln hours är kvantitativ. Vi vill jämföra två populationer med konfidensintervall. Metoden är därför konfidensintervall för jämförelse av populationsmedelvärden.

t.test(subset(studytime$hours, studytime$campus == "Västerås"), subset(studytime$hours, studytime$campus == "Eskilstuna"), alternative = "two.sided")
## 
##  Welch Two Sample t-test
## 
## data:  subset(studytime$hours, studytime$campus == "Västerås") and subset(studytime$hours, studytime$campus == "Eskilstuna")
## t = 2.9996, df = 296.02, p-value = 0.002933
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  1.039536 5.005740
## sample estimates:
## mean of x mean of y 
##  36.26970  33.24706

Med 95% säkerhet är den sanna genomsnittliga studietiden mellan 1.0 och 5.0 timmar per vecka högre i Västerås jämfört med Eskilstuna.

Förutsättningar:

  • två representativa stickprov

  • båda stickproven består av minst 30 observationer

Lösning tvåpop.9

Stickprovsdimensionering

power.prop.test(p1=0.04, p2 = 0.05, power = 0.8, sig.level = 0.05, alternative = "one.sided")
## 
##      Two-sample comparison of proportions power calculation 
## 
##               n = 5312.862
##              p1 = 0.04
##              p2 = 0.05
##       sig.level = 0.05
##           power = 0.8
##     alternative = one.sided
## 
## NOTE: n is number in *each* group

Se till att få minst 5313 träffar per design, det vill säga cirka 10 600 träffar totalt.

Givet cirka 15 000 träffar i månaden har vi 15000/31 = 484 träffar per dygn.

Det betyder att testet behöver pågå under minst 10600/484 = 22 dygn.

Lösning frek.1

Vi vill undersöka om det finns skillnad i frekvens mellan variabelvärdena för en kvalitativ variabel. Metoden är chitvåtest för analys av frekvenstabell.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: det finns ingen skillnad i frekvens mellan design A och B

Ha: det finns skillnad i frekvens mellan design A och B

Steg 2: beräkna testvariabeln

tabyl(data_AB$design)
##  data_AB$design    n percent
##               A 4989  0.4989
##               B 5011  0.5011
chisq.test(x = c(4989, 5011), p = c(0.5, 0.5))
## 
##  Chi-squared test for given probabilities
## 
## data:  c(4989, 5011)
## X-squared = 0.0484, df = 1, p-value = 0.8259

Steg 3: kan H0 förkastas?

p = 0.8259 > 0.05

H0 kan ej förkastas.

Steg 4: dra slutsats

Vi kan ej dra någon slutsats av testet. Det innebär också att vi inte ser några tecken på att testet inte skulle ha fungerat som det ska.

Förutsättningar:

  • oberoende mellan grupperna

  • förväntade frekvenser större än 5

Lösning frek.2

tabyl(santa_monica$month)
##  santa_monica$month  n   percent
##               april 56 0.0875000
##             augusti 52 0.0812500
##            december 50 0.0781250
##            februari 49 0.0765625
##             januari 55 0.0859375
##                juli 41 0.0640625
##                juni 58 0.0906250
##                 maj 59 0.0921875
##                mars 56 0.0875000
##            november 54 0.0843750
##             oktober 54 0.0843750
##           september 56 0.0875000

Chitvåtest för analys av frekvenstabell

H0: det finns inga skillnader i frekvens mellan månaderna

Ha: det finns skillnader i frekvens mellan månaderna

chisq.test(x = c(56, 52, 50, 49, 55, 41, 58, 59, 56, 54, 54, 56), p = c(1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12, 1/12))
## 
##  Chi-squared test for given probabilities
## 
## data:  c(56, 52, 50, 49, 55, 41, 58, 59, 56, 54, 54, 56)
## X-squared = 4.925, df = 11, p-value = 0.9347

p = 0.9347 vilket är högre än signifikansnivå 0.05 och H0 kan ej förkastas. Vi finner ingen statistiskt säkerställd skillnad i frekvens mellan månaderna.

Metoden förutsätter

  • oberoende mellan cellerna

  • alla förväntade frekvenser större än 5

Lösning kvalsamb.1

Vi vill undersöka samband mellan två kvalitativa variabler. Metoden är chitvåtest för analys av korstabell.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: det finns inget samband mellan val av webläsare och upplevd hastighet

Ha: det finns samband mellan val av webläsare och upplevd hastighet

Steg 2: beräkna testvariabeln

CrossTable(browserspeed$Q1, browserspeed$Q2, expected = TRUE, chisq = TRUE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |              Expected N |
## | Chi-square contribution |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1533 
## 
##  
##                 | browserspeed$Q2 
## browserspeed$Q1 |        No |       Yes | Row Total | 
## ----------------|-----------|-----------|-----------|
##          Chrome |       107 |       545 |       652 | 
##                 |   184.159 |   467.841 |           | 
##                 |    32.328 |    12.726 |           | 
##                 |     0.164 |     0.836 |     0.425 | 
##                 |     0.247 |     0.495 |           | 
##                 |     0.070 |     0.356 |           | 
## ----------------|-----------|-----------|-----------|
##            Edge |       117 |       141 |       258 | 
##                 |    72.873 |   185.127 |           | 
##                 |    26.721 |    10.518 |           | 
##                 |     0.453 |     0.547 |     0.168 | 
##                 |     0.270 |     0.128 |           | 
##                 |     0.076 |     0.092 |           | 
## ----------------|-----------|-----------|-----------|
##           Other |        47 |        31 |        78 | 
##                 |    22.031 |    55.969 |           | 
##                 |    28.298 |    11.139 |           | 
##                 |     0.603 |     0.397 |     0.051 | 
##                 |     0.109 |     0.028 |           | 
##                 |     0.031 |     0.020 |           | 
## ----------------|-----------|-----------|-----------|
##          Safari |       162 |       383 |       545 | 
##                 |   153.937 |   391.063 |           | 
##                 |     0.422 |     0.166 |           | 
##                 |     0.297 |     0.703 |     0.356 | 
##                 |     0.374 |     0.348 |           | 
##                 |     0.106 |     0.250 |           | 
## ----------------|-----------|-----------|-----------|
##    Column Total |       433 |      1100 |      1533 | 
##                 |     0.282 |     0.718 |           | 
## ----------------|-----------|-----------|-----------|
## 
##  
## Statistics for All Table Factors
## 
## 
## Pearson's Chi-squared test 
## ------------------------------------------------------------
## Chi^2 =  122.318     d.f. =  3     p =  2.444444e-26 
## 
## 
## 

Steg 3: kan H0 förkastas?

p = 2.44e-26 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet finns ett statistiskt säkerställt samband mellan val av webläsare och upplevd hastighet. Särskilt noteras:

  • fler upplever Chrome snabb (545) än förväntat (467.841)

  • färre upplever Edge snabb (141) än förväntat (185.127)

Förutsättningar:

  • oberoende mellan celler

  • alla förväntade frekvenser större än 1

  • max 20% av de förväntade frekvenserna mindre än 5

Lösning kvalsamb.2

Vi vill undersöka samband mellan två kvalitativa variabler. Metoden är chitvåtest för analys av korstabell.

Steg 1: välj signifikansnivå och formulera hypoteser

Signifikansnivå 0.05

H0: det finns inget samband mellan studieort och om man kom in på sitt förstahandsval

Ha: det finns samband mellan studieort och om man kom in på sitt förstahandsval

Steg 2: beräkna testvariabeln

CrossTable(studytime$campus, studytime$first_choice, expected = TRUE, chisq = TRUE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |              Expected N |
## | Chi-square contribution |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  500 
## 
##  
##                  | studytime$first_choice 
## studytime$campus |        ja |       nej | Row Total | 
## -----------------|-----------|-----------|-----------|
##       Eskilstuna |       101 |        69 |       170 | 
##                  |    90.100 |    79.900 |           | 
##                  |     1.319 |     1.487 |           | 
##                  |     0.594 |     0.406 |     0.340 | 
##                  |     0.381 |     0.294 |           | 
##                  |     0.202 |     0.138 |           | 
## -----------------|-----------|-----------|-----------|
##         Västerås |       164 |       166 |       330 | 
##                  |   174.900 |   155.100 |           | 
##                  |     0.679 |     0.766 |           | 
##                  |     0.497 |     0.503 |     0.660 | 
##                  |     0.619 |     0.706 |           | 
##                  |     0.328 |     0.332 |           | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       265 |       235 |       500 | 
##                  |     0.530 |     0.470 |           | 
## -----------------|-----------|-----------|-----------|
## 
##  
## Statistics for All Table Factors
## 
## 
## Pearson's Chi-squared test 
## ------------------------------------------------------------
## Chi^2 =  4.250954     d.f. =  1     p =  0.03922829 
## 
## Pearson's Chi-squared test with Yates' continuity correction 
## ------------------------------------------------------------
## Chi^2 =  3.869903     d.f. =  1     p =  0.04915936 
## 
## 

Steg 3: kan H0 förkastas?

p = 0.039 < 0.05

H0 förkastas.

Steg 4: dra slutsats

Med 95% säkerhet finns ett statistiskt säkerställt samband mellan campus och om man kom in på sitt förstahandsval. Särskilt lägger vi märke till:

  • i Västerås är det ungefär 50% som kom in på förstahandsvalet och 50% som inte gjorde det

  • i Eskilstuna kom 59% in på sitt förstahandsval

Förutsättningar:

  • oberoende mellan celler

  • alla förväntade frekvenser större än 1

  • max 20% av de förväntade frekvenserna mindre än 5

Lösning kvansamb.1

ggplot(data = vasaloppet) +
  aes(x = last_race_finish_time_seconds, y = finish_time_seconds) +
  geom_point()

Sambandet är linjärt, positivt och starkt. Inga uppenbara datakvalitetsproblen syns.

cor(vasaloppet$finish_time_seconds, vasaloppet$last_race_finish_time_seconds, use = "pairwise.complete.obs")
## [1] 0.8879286

Korrelationskoefficienten är 0.89: korrelationen är stark.

model_kvansamb1 <- lm(finish_time_seconds ~ last_race_finish_time_seconds, data = vasaloppet, na.action = na.exclude)
summary(model_kvansamb1)
## 
## Call:
## lm(formula = finish_time_seconds ~ last_race_finish_time_seconds, 
##     data = vasaloppet, na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -13454.8  -1641.0   -274.4   1432.0  19199.8 
## 
## Coefficients:
##                                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                   5.527e+03  1.448e+02   38.18   <2e-16 ***
## last_race_finish_time_seconds 8.229e-01  5.127e-03  160.50   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2899 on 6913 degrees of freedom
##   (8431 observations deleted due to missingness)
## Multiple R-squared:  0.7884, Adjusted R-squared:  0.7884 
## F-statistic: 2.576e+04 on 1 and 6913 DF,  p-value: < 2.2e-16

H0: det finns inget samband mellan variablerna

Ha: det finns samband mellan variablerna

p < 2e-16 < 0.05

H0 förkastas. Med 95% säkerhet finns ett samband mellan variablerna.

Multiple R-squared = 0.7884

79% av variationen i sluttiden för Vasaloppet förklaras av modellen. Förklaringsgraden är mycket hög.

# Save the residuals
vasaloppet$residuals <- resid(model_kvansamb1)

# Scatter chart
ggplot(data = vasaloppet) +
  aes(x = last_race_finish_time_seconds, y = residuals) +
  geom_point()

# Histogram
ggplot(data = vasaloppet) +
  aes(x = residuals) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Antagandet om konstant varians bland residualerna förefaller vara uppfyllt utifrån den förhållandevis slumpmässiga spridning av prickarna som vi ser i spridningsdiagrammet över residualerna mot förklaringsvariabeln. Histogrammet för residualerna uppvisar klockform, vilket gör att normalfördelningsantagandet kan betraktas som uppfyllt. Modellen förefaller bra sett till residualerna.

confint(model_kvansamb1, level = 0.95)
##                                      2.5 %       97.5 %
## (Intercept)                   5243.0854707 5810.6126286
## last_race_finish_time_seconds    0.8128899    0.8329924

Med 95% säkerhet innebär varje sekund högre sluttid i förra loppet mellan 0.81 och 0.83 sekunder högre sluttid i det senaste loppet.

Vi vill göra prognos för en specifik åkare, och väljer därför prognosintervall.

new_data <- data.frame(last_race_finish_time_seconds = 30000)
predict(model_kvansamb1, new_data, interval = "predict")
##        fit      lwr      upr
## 1 30215.08 24532.05 35898.11

Vi förväntar oss sluttiden 30 215 sekunder för en åkare som förra gången gjorde loppet på 30 000 sekunder.

Lösning kvansamb.2

ggplot(data = santa_monica) +
  aes(x = avg_page_load_time, y = bounce_rate) +
  geom_point()

Sambandet är inte helt tydligt. Förmodligen är ett linjärt samband det “minst dåliga” sättet att sammanfatta observationerna. Sambandet är positivt. Det finns en del orimliga nollvärden. Man bör i en praktisk situation utreda om dessa är felaktiga och om de i så fall kan rättas, alternativt filtreras bort.

cor(santa_monica$avg_page_load_time, santa_monica$bounce_rate, use = "pairwise.complete.obs")
## [1] 0.39843

Korrelationskoefficienten är 0.4: korrelationen är svag till måttlig.

model_kvansamb2 <- lm(bounce_rate ~ avg_page_load_time, data = santa_monica, na.action = na.exclude)
summary(model_kvansamb2)
## 
## Call:
## lm(formula = bounce_rate ~ avg_page_load_time, data = santa_monica, 
##     na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -32.944  -3.349   1.618   4.711  22.639 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        30.05170    0.59892   50.18   <2e-16 ***
## avg_page_load_time  0.94512    0.08614   10.97   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.9 on 638 degrees of freedom
## Multiple R-squared:  0.1587, Adjusted R-squared:  0.1574 
## F-statistic: 120.4 on 1 and 638 DF,  p-value: < 2.2e-16

H0: det finns inget samband mellan bounce rate och avg page load time

Ha: det finns samband mellan bounce rate och avg page load time

p < 2e-16 < 0.05

H0 förkastas. Med 95% säkerhet finns ett samband mellan variablerna.

Multiple R-squared = 0.1587

Knappt 16% av variationen i bounce rate förklaras av avg page load time. Förklaringsgraden är låg.

# Save the residuals
santa_monica$residuals <- resid(model_kvansamb2)

# Scatter chart
ggplot(data = santa_monica) +
  aes(x = avg_page_load_time, y = residuals) +
  geom_point()

# Histogram
ggplot(data = santa_monica) +
  aes(x = residuals) +
  geom_histogram()

Antagandet om konstant varians bland residualerna kan ej betraktas som helt uppfyllt, eftersom residualerna ej fallet slumpmässigt kring 0. Inte heller normalfördelningsantagandet är uppfyllt. Modellen måste tolkas och användas med försiktighet.

confint(model_kvansamb2, level = 0.95)
##                         2.5 %    97.5 %
## (Intercept)        28.8756081 31.227797
## avg_page_load_time  0.7759779  1.114271

Med 95% säkerhet innebär varje enhets ökning i avg page load time att bounce rate ökar med mellan 0.78 och 1.11 enheter.

new_data <- data.frame(avg_page_load_time = 5)
predict(model_kvansamb2, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 34.77732 33.93109 35.62355

Med 95% säkerhet förväntar vi oss bounce rate mellan 33.9 och 35.6 när avg page load time är 5 sekunder.

Lösning kvansamb.3

ggplot(data = pay_per_click) +
  aes(x = spend, y = revenue) +
  geom_point()

Sambandet är positivt. Ju mer pengar som spenderas, desto högre är revenue.

cor(pay_per_click$revenue, pay_per_click$spend, use = "pairwise.complete.obs")
## [1] 0.789455

Korrelationskoefficienten är 0.79, vilket innebär att sambandet är starkt.

model_kvansamb3 <- lm(revenue ~ spend, data = pay_per_click, na.action = na.exclude)
summary(model_kvansamb3)
## 
## Call:
## lm(formula = revenue ~ spend, data = pay_per_click, na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -175.640  -56.226    1.448   65.235  210.987 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  15.7058    35.1727   0.447    0.658    
## spend         5.2517     0.6624   7.928 1.42e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 93.82 on 38 degrees of freedom
## Multiple R-squared:  0.6232, Adjusted R-squared:  0.6133 
## F-statistic: 62.86 on 1 and 38 DF,  p-value: 1.415e-09

H0: det finns inget samband mellan spend och revenue

Ha: det finns samband mellan spend och revenue

p < 1.42e-09 < 0.05

H0 förkastas. Med 95% säkerhet finns ett samband mellan variablerna.

Multiple R-squared = 0.6232

62% av variationen i revenue förklaras av spend. Förklaringsgraden är hög.

# Save the residuals
pay_per_click$residuals <- resid(model_kvansamb3)

# Scatter chart
ggplot(data = pay_per_click) +
  aes(x = spend, y = residuals) +
  geom_point()

# Histogram
ggplot(data = pay_per_click) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0. Normalfördelningsantagandet är någorlunda uppfyllt.

confint(model_kvansamb3, level = 0.95)
##                  2.5 %    97.5 %
## (Intercept) -55.497519 86.909128
## spend         3.910796  6.592694

Med 95% säkerhet innebär varje enhets ökning i spend att revenue med mellan 3.9 och 6.6 enheter.

new_data <- data.frame(spend = 50)
predict(model_kvansamb3, new_data, interval = "confidence")
##       fit      lwr      upr
## 1 278.293 248.1605 308.4256

Vi är 95% säkra på att revenue är mellan 248 och 308 enhet när spend är 50.

Lösning kvansamb.4

ggplot(data = data_AB) +
  aes(x = sessions, y = revenue) +
  geom_point()

Sambandet är positivt. Ju fler sessions, desto högre revenue.

cor(data_AB$revenue, data_AB$sessions, use = "pairwise.complete.obs")
## [1] 0.6094088

Korrelationskoefficienten är 0.61, vilket innebär att sambandet är måttligt till starkt.

model_kvansamb4 <- lm(revenue ~ sessions, data = data_AB, na.action = na.exclude)
summary(model_kvansamb4)
## 
## Call:
## lm(formula = revenue ~ sessions, data = data_AB, na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3870.4  -806.9  -167.2   628.5  6422.4 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  800.084     20.487   39.05   <2e-16 ***
## sessions      99.449      1.294   76.86   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1268 on 9998 degrees of freedom
## Multiple R-squared:  0.3714, Adjusted R-squared:  0.3713 
## F-statistic:  5907 on 1 and 9998 DF,  p-value: < 2.2e-16

H0: det finns inget samband mellan sessions och revenue

Ha: det finns samband mellan sessions och revenue

p < 2e-16 < 0.05

H0 förkastas. Med 95% säkerhet finns ett samband mellan variablerna.

Multiple R-squared = 0.3714

37% av variationen i revenue förklaras av antalet sessions. Förklaringsgraden är måttlig.

# Save the residuals
data_AB$residuals <- resid(model_kvansamb4)

# Scatter chart
ggplot(data = data_AB) +
  aes(x = sessions, y = residuals) +
  geom_point()

# Histogram
ggplot(data = data_AB) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller någorlunda slumpmässigt kring 0. Normalfördelningsantagandet är uppfyllt.

confint(model_kvansamb4, level = 0.95)
##                 2.5 %   97.5 %
## (Intercept) 759.92485 840.2429
## sessions     96.91301 101.9860

Med 95% säkerhet innebär varje enhets ökning i sessions att revenue med mellan 96.9 och 102.0 enheter.

new_data <- data.frame(sessions = c(1, 10, 50))
predict(model_kvansamb4, new_data, interval = "confidence")
##         fit       lwr       upr
## 1  899.5334  861.3339  937.7328
## 2 1794.5788 1768.9608 1820.1968
## 3 5772.5584 5674.0804 5871.0364

Konfidensintervallen visar förväntad revenue när antalet sessions är 1, 10 respektive 50.

Lösning kvansamb.5

Här exemplifieras med väljarstödet för M som responsvariabel och inkomst som förklaringsvariabel.

ggplot(data = election_result) +
  aes(x = Inkomst, y = M) +
  geom_point()

Sambandet är positivt. Ju högre inkomst, desto högre väljarstöd för M.

cor(election_result$M, election_result$Inkomst, use = "pairwise.complete.obs")
## [1] 0.7374919

Korrelationskoefficienten är 0.74, vilket innebär att sambandet är starkt.

model_kvansamb5 <- lm(M ~ Inkomst, data = election_result, na.action = na.exclude)
summary(model_kvansamb5)
## 
## Call:
## lm(formula = M ~ Inkomst, data = election_result, na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -21.6157  -3.0259  -0.0615   3.2842  17.8310 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -3.319e+01  2.900e+00  -11.44   <2e-16 ***
## Inkomst      2.190e-04  1.182e-05   18.53   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4.854 on 288 degrees of freedom
## Multiple R-squared:  0.5439, Adjusted R-squared:  0.5423 
## F-statistic: 343.4 on 1 and 288 DF,  p-value: < 2.2e-16

H0: det finns inget samband mellan inkomst och väljarstöd för M

Ha: det finns samband mellan inkomst och väljarstöd för M

p < 2e-16 < 0.05

H0 förkastas. Med 95% säkerhet finns ett samband mellan variablerna.

Multiple R-squared = 0.5439

54% av variationen i revenue förklaras av antalet sessions. Förklaringsgraden är måttlig.

# Save the residuals
election_result$residuals <- resid(model_kvansamb5)

# Scatter chart
ggplot(data = election_result) +
  aes(x = Inkomst, y = residuals) +
  geom_point()

# Histogram
ggplot(data = election_result) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0. Normalfördelningsantagandet är uppfyllt.

confint(model_kvansamb5, level = 0.95)
##                     2.5 %        97.5 %
## (Intercept) -3.889759e+01 -2.748016e+01
## Inkomst      1.957739e-04  2.423008e-04

Med 95% säkerhet innebär varje kronas ökning i medelinkomst i kommunen att väljarstödet för M ökar med mellan 0.0196 och 0.0242 procentenheter.

Låt oss predicera förväntat väljarstöd för M i kommuner med medelinkomst 250 000 kr. Eftersom vi vill uttalas oss om inte bara en kommun, utan alla kommuner med medelinkomst 250 000 kr, väljer vi intervall av typen confidence.

new_data <- data.frame(Inkomst = 250000)
predict(model_kvansamb5, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 21.57047 20.99349 22.14744

Med 95% säkerhet är förväntat väljarstöd mellan 20.99% och 22.15% i kommuner med medelinkomst 250 000 kr.

Lösning mulkvansamb.1

# revenue against spend
ggplot(data = pay_per_click) +
  aes(x = spend, y = revenue) +
  geom_point()

# revenue against clicks
ggplot(data = pay_per_click) +
  aes(x = clicks, y = revenue) +
  geom_point()

# revenue against display
pay_per_click %>%
  group_by(display) %>%
  summarise(medel = mean(revenue, na.rm = TRUE))
## # A tibble: 2 × 2
##   display medel
##   <chr>   <dbl>
## 1 no       222.
## 2 yes      315.

Det råder positiva samband mellan spend och revenue samt mellan clicks och revenue. Revenue är högre när display = yes.

# revenue against spend
cor(pay_per_click$revenue, pay_per_click$spend, use = "pairwise.complete.obs")
## [1] 0.789455
# revenue against clicks
cor(pay_per_click$revenue, pay_per_click$clicks, use = "pairwise.complete.obs")
## [1] 0.8242745

Båda korrelationerna är starka.

model_mulkvansamb1 <- lm(revenue ~ spend + clicks + display, data = pay_per_click, na.action = na.exclude)
summary(model_mulkvansamb1)
## 
## Call:
## lm(formula = revenue ~ spend + clicks + display, data = pay_per_click, 
##     na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -141.54  -56.21   16.42   52.91  115.25 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -33.45454   30.44702  -1.099 0.279159    
## spend        -0.04452    2.25341  -0.020 0.984346    
## clicks        0.90222    0.36641   2.462 0.018723 *  
## displayyes   95.44083   23.47543   4.066 0.000249 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 73.29 on 36 degrees of freedom
## Multiple R-squared:  0.7822, Adjusted R-squared:  0.764 
## F-statistic: 43.09 on 3 and 36 DF,  p-value: 5.299e-12
  1. Vi testar hypoteserna

    H0: det finns inget samband

    Ha: det finns ett samband

    p-värdet är 5.299e-12 vilket är lägre än 0.05. Nollhypotesen förkastas.

  2. H0: det finns inget samband mellan spend och revenue

    Ha: det finns ett samband mellan spend och revenue

p-värdet är 0.984346 vilket är högre än 0.05. Nollhypotesen kan ej förkastas.

H0: det finns inget samband mellan clicks och revenue

Ha: det finns ett samband mellan clicks och revenue

p-värdet är 0.018723 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan display och revenue

Ha: det finns ett samband mellan display och revenue

p-värdet är 0.000249 vilket är lägre än 0.05. Nollhypotesen förkastas.

  1. Förklaringsgraden är 0.7822, vilket innebär att 78% av variationen i revenue förklaras av modellen. Den justerade förklaringsgraden är 76.4%.

  2. Effekten av spend är negativ. Det är inte rimligt, eftersom vi sett i visualiseringen och genom korrelationsberäkningen att sambandet är positivt.

  3. Med anledning av att effekten av spend inte blir rimlig bör den uteslutas ur modellen:

model_mulkvansamb1 <- lm(revenue ~ clicks + display, data = pay_per_click, na.action = na.exclude)
summary(model_mulkvansamb1)
## 
## Call:
## lm(formula = revenue ~ clicks + display, data = pay_per_click, 
##     na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -141.89  -55.92   16.44   52.70  115.46 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -33.63248   28.68893  -1.172 0.248564    
## clicks        0.89517    0.08308  10.775 5.76e-13 ***
## displayyes   95.51462   22.86126   4.178 0.000172 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 72.29 on 37 degrees of freedom
## Multiple R-squared:  0.7822, Adjusted R-squared:  0.7704 
## F-statistic: 66.44 on 2 and 37 DF,  p-value: 5.682e-13

Denna modell får högre justerad förklaringsgrad samtidigt som att alla kvarvarande förklaringsvariabler är signifikanta. Modellen är bättre.

# Save residuals and predicted values
pay_per_click$residuals <- resid(model_mulkvansamb1)
pay_per_click$predicted <- fitted(model_mulkvansamb1)

# Scatter chart
ggplot(data = pay_per_click) +
  aes(x = predicted, y = residuals) + 
  geom_point()

# Histogram
ggplot(data = pay_per_click) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0 men normalfördelningsantagandet är ej helt uppfyllt.

library(car)
vif(model_mulkvansamb1)
##   clicks  display 
## 1.000061 1.000061

VIF indikerar inga multikollinearitetsproblem.

confint(model_mulkvansamb1, level = 0.95)
##                   2.5 %     97.5 %
## (Intercept) -91.7617751  24.496825
## clicks        0.7268456   1.063498
## displayyes   49.1932963 141.835942

Med 95% säkerhet innebär varje enhets ökning i clicks att revenue ökar med mellan 0.73 och 1.06.

Om displaykampanj pågår är med 95% säkerhet revenue mellan 49 och 142 enheter högre än om kampanj ej pågår.

new_data <- data.frame(clicks = 500, display = "yes")
predict(model_mulkvansamb1, new_data, interval = "predict")
##       fit      lwr      upr
## 1 509.468 354.9996 663.9363

Med 95% säkerhet är förväntad revenue mellan 355 och 664 enheter vid det tillfälle som clicks är 500 och displaykampanj pågår. Eftersom spend inte ingår i modellen ingår den heller inte i prediktionen.

Lösning mulkvansamb.2

data_GA_filter <- data_GA %>%
  filter(Revenue > 0)
# revenue against transactions
ggplot(data = data_GA_filter) +
  aes(x = Transactions, y = Revenue) +
  geom_point()

# revenue against avgsessionduration
ggplot(data = data_GA_filter) +
  aes(x = AvgSessionDuration, y = Revenue) +
  geom_point()

# revenue against Design
data_GA_filter %>%
  group_by(Design) %>%
  summarise(medel = mean(Revenue, na.rm = TRUE))
## # A tibble: 3 × 2
##   Design   medel
##   <chr>    <dbl>
## 1 Design_A 2188.
## 2 Design_B 2230.
## 3 Design_C 2237.

Det råder ett positiva samband mellan transactions och revenue. Sambandet mellan AvgSessionDuration och revenue är ej tydligt. Revenue är i ungefär samma storleksordning oavsett design.

# revenue against spend
cor(data_GA_filter$Revenue, data_GA_filter$Transactions, use = "pairwise.complete.obs")
## [1] 0.5435692
# revenue against clicks
cor(data_GA_filter$Revenue, data_GA_filter$AvgSessionDuration, use = "pairwise.complete.obs")
## [1] -0.01244014

Korrelationen. mellan transactions och revenue är måttlig. Det tycks inte finnas något samband mellan AvgSessionDuration och revenue.

model_mulkvansamb2 <- lm(Revenue ~ Transactions + AvgSessionDuration + Design, data = data_GA_filter, na.action = na.exclude)
summary(model_mulkvansamb2)
## 
## Call:
## lm(formula = Revenue ~ Transactions + AvgSessionDuration + Design, 
##     data = data_GA_filter, na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -19050  -1091   -241    598 111025 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        -1.678e+02  3.022e+01  -5.551 2.86e-08 ***
## Transactions        6.673e+02  5.184e+00 128.720  < 2e-16 ***
## AvgSessionDuration  8.404e-02  9.673e-03   8.688  < 2e-16 ***
## DesignDesign_B      2.619e+01  2.628e+01   0.997    0.319    
## DesignDesign_C      2.074e+01  2.630e+01   0.789    0.430    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2126 on 39279 degrees of freedom
## Multiple R-squared:  0.2968, Adjusted R-squared:  0.2968 
## F-statistic:  4145 on 4 and 39279 DF,  p-value: < 2.2e-16

Design_A är referenskategori.

  1. Vi testar hypoteserna

    H0: det finns inget samband

    Ha: det finns ett samband

    p-värdet är <2.2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

  2. H0: det finns inget samband mellan transactions och revenue

    Ha: det finns ett samband mellan transactions och revenue

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan avgsessionduration och revenue

Ha: det finns ett samband mellan avgsessionduration och revenue

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan design b och revenue

Ha: det finns ett samband mellan design b och revenue

p-värdet är 0.319 vilket är högre än 0.05. Nollhypotesen kan ej förkastas.

H0: det finns inget samband mellan design c och revenue

Ha: det finns ett samband mellan design c och revenue

p-värdet är 0.430 vilket är högre än 0.05. Nollhypotesen kan ej förkastas.

  1. Förklaringsgraden är 0.2968, vilket innebär att knappt 30% av variationen i revenue förklaras av modellen. Den justerade förklaringsgraden är också 29.68%.

  2. Samtliga förklaringsvariabler är signifikanta. Men det förvånar att AvgSessionDuration är så starkt signifikant, när den inte visar något tydligt samband med revenue i visualiseringen och har så låg korrelation med revenue.

  3. Med anledning av att AvgSessionDuration inte blir rimlig bör den uteslutas ur modellen:

model_mulkvansamb2 <- lm(Revenue ~ Transactions + Design, data = data_GA_filter, na.action = na.exclude)
summary(model_mulkvansamb2)
## 
## Call:
## lm(formula = Revenue ~ Transactions + Design, data = data_GA_filter, 
##     na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -18989  -1091   -243    601 110980 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     -25.127     25.397  -0.989    0.322    
## Transactions    663.254      5.168 128.338   <2e-16 ***
## DesignDesign_B   24.840     26.305   0.944    0.345    
## DesignDesign_C   18.267     26.325   0.694    0.488    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2128 on 39280 degrees of freedom
## Multiple R-squared:  0.2955, Adjusted R-squared:  0.2954 
## F-statistic:  5492 on 3 and 39280 DF,  p-value: < 2.2e-16

Den justerade förklaringsgraden sjunker något. Design-variablerna är dock fortfarande inte signifikanta varför även de exkluderas:

model_mulkvansamb2 <- lm(Revenue ~ Transactions, data = data_GA_filter, na.action = na.exclude)
summary(model_mulkvansamb2)
## 
## Call:
## lm(formula = Revenue ~ Transactions, data = data_GA_filter, na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -18987  -1091   -244    599 110983 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   -10.836     20.420  -0.531    0.596    
## Transactions  663.290      5.168 128.352   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2128 on 39282 degrees of freedom
## Multiple R-squared:  0.2955, Adjusted R-squared:  0.2954 
## F-statistic: 1.647e+04 on 1 and 39282 DF,  p-value: < 2.2e-16

Trots sin enkelhet tycks denna modell vara den bästa.

# Save residuals and predicted values
data_GA_filter$residuals <- resid(model_mulkvansamb2)
data_GA_filter$predicted <- fitted(model_mulkvansamb2)

# Scatter chart
ggplot(data = data_GA_filter) +
  aes(x = predicted, y = residuals) + 
  geom_point()

# Histogram
ggplot(data = data_GA_filter) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller förhållande slumpmässigt kring 0 men normalfördelningsantagandet är ej helt uppfyllt.

  1. Eftersom modellen endast innehåller en förklaringsvariabel finns inga multikollinearitetsproblem.

confint(model_mulkvansamb2, level = 0.95)
##                 2.5 %    97.5 %
## (Intercept)  -50.8593  29.18778
## Transactions 653.1606 673.41849

Med 95% säkerhet innebär varje enhets ökning i transactions att revenue ökar med mellan 653 och 673.

Om displaykampanj pågår är med 95% säkerhet revenue mellan 49 och 142 enheter högre än om kampanj ej pågår.

new_data <- data.frame(Transactions = 5)
predict(model_mulkvansamb2, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 3305.612 3278.812 3332.413

Med 95% säkerhet är förväntad revenue mellan 3279 och 3332 kr om transactions = 5. Eftersom AvgSessionDuration och Design inte ingår i modellen ingår de heller inte i prediktionen.

Lösning mulkvansamb.3

# result against hours per week
ggplot(data = studytime_and_results) +
  aes(x = hours_per_week, y = result) +
  geom_point()

# results against campus
studytime_and_results %>%
  group_by(campus) %>%
  summarise(medel = mean(hours_per_week, na.rm = TRUE))
## # A tibble: 2 × 2
##   campus     medel
##   <chr>      <dbl>
## 1 Eskilstuna  45.8
## 2 Västerås    43.5
# results against age
ggplot(data = studytime_and_results) +
  aes(x = age, y = result) +
  geom_point()

Sambandet är positivt mellan resultat och timmar per vecka. Resultaten är något högre bland studenter som läser vid campus Eskilstuna. Resultaten ser ut att sjunka med studentens ålder.

# results against hours per week
cor(studytime_and_results$result, studytime_and_results$hours_per_week, use = "pairwise.complete.obs")
## [1] 0.8649719
# results against age
cor(studytime_and_results$result, studytime_and_results$age, use = "pairwise.complete.obs")
## [1] -0.4630895

Korrelationen mellan resultat och timmar per vecka är stark. Korrelationen mellan resultat och ålder är måttlig.

model_mulkvansamb3 <- lm(result ~ hours_per_week + campus + age, data = studytime_and_results, na.action = na.exclude)
summary(model_mulkvansamb3)
## 
## Call:
## lm(formula = result ~ hours_per_week + campus + age, data = studytime_and_results, 
##     na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -19.8203  -4.9753   0.0107   4.4914  22.9483 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    14.25880    2.42661   5.876 7.73e-09 ***
## hours_per_week  0.66928    0.01984  33.728  < 2e-16 ***
## campusVästerås -1.24235    0.63092  -1.969   0.0495 *  
## age            -0.35165    0.06986  -5.033 6.76e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 6.993 on 494 degrees of freedom
## Multiple R-squared:  0.7632, Adjusted R-squared:  0.7618 
## F-statistic: 530.7 on 3 and 494 DF,  p-value: < 2.2e-16
  1. Vi testar hypoteserna

    H0: det finns inget samband

    Ha: det finns ett samband

    p-värdet är <2.2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

  2. H0: det finns inget samband mellan resultat och timmar per vecka

    Ha: det finns ett samband mellan resultat och timmar per vecka

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan resultat och campus

Ha: det finns ett samband mellan resultat och campus

p-värdet är 0.0495 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan resultat och ålder

Ha: det finns ett samband mellan resultat och ålder

p-värdet är 6.76e-07 vilket är lägre än 0.05. Nollhypotesen förkastas.

  1. Förklaringsgraden är 0.7632, vilket innebär att 76% av variationen i revenue förklaras av modellen. Den justerade förklaringsgraden är 76.18%.

  2. Effekten av timmar per vecka på resultatet är positiv. Det stämmer med visualisering och korrelationsberäkning. Effekten av campus Västerås på resultatet är negativ. Det stämmer med den deskriptiva statistiken som visade att resultaten är något högre i Eskilstuna. Effekten av ålder på resultatet är negativ. Det stämmer med visualisering och korrelationsberäkning.

  3. Det finns inget behov av att utveckla modellen.

studytime_and_results$residuals <- resid(model_mulkvansamb3)
studytime_and_results$predicted <- fitted(model_mulkvansamb3)

ggplot(data = studytime_and_results) +
  aes(x = predicted, y = residuals) + 
  geom_point()

ggplot(data = studytime_and_results) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0 och histogrammet över residulerna uppvisar normalfördelning.

library(car)
vif(model_mulkvansamb3)
## hours_per_week         campus            age 
##       1.208182       1.013396       1.218418

VIF indikerar inga multikollinearitetsproblem.

confint(model_mulkvansamb3, level = 0.95)
##                     2.5 %       97.5 %
## (Intercept)     9.4910488 19.026547580
## hours_per_week  0.6302873  0.708263768
## campusVästerås -2.4819594 -0.002736484
## age            -0.4889168 -0.214385607

Med 95% säkerhet innebär varje ytterligare studietimme per vecka att resultatet ökar med mellan 0.63 och 0.71 poäng.

Västeråsstudenter har i genomsnitt mellan 0.003 och 2.5 poäng lägre tentamensresultat än Eskilstunastudenter.

Med 95% säkerhet sjunker resultatet med mellan 0.21 och 0.49 poäng för varje år äldre studenten är.

new_data <- data.frame(hours_per_week = 38, campus = "Västerås", age = 25)
predict(model_mulkvansamb3, new_data, interval = "predict")
##        fit      lwr      upr
## 1 29.65764 15.88102 43.43427

Med 95% säkerhet är förväntat resultat mellan 15.9 och 43.4 poäng för denna student.

new_data <- data.frame(hours_per_week= 38, campus = "Västerås", age = 25)
predict(model_mulkvansamb3, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 29.65764 28.64961 30.66568

Med 95% säkerhet är genomsnittligt förväntat resultat mellan 28.6 och 30.7 poäng för 25-åriga Västeråsstudenter som lägger 38 timmar i vecka på sina studier.

Lösning mulkvansamb.4

# finish_time_seconds against sex
vasaloppet %>%
  group_by(sex) %>%
  summarise(medel = mean(finish_time_seconds, na.rm = TRUE))
## # A tibble: 3 × 2
##   sex    medel
##   <chr>  <dbl>
## 1 F     34978.
## 2 M     29683.
## 3 <NA>  31382.
# finish_time_seconds against member_of_club
vasaloppet %>%
  group_by(member_of_club) %>%
  summarise(medel = mean(finish_time_seconds, na.rm = TRUE))
## # A tibble: 2 × 2
##   member_of_club  medel
##   <chr>           <dbl>
## 1 no             30398.
## 2 yes            30358.
# finish_time_seconds against num_previous_races
ggplot(data = vasaloppet) +
  aes(x = num_previous_races, y = finish_time_seconds) +
  geom_point()

# finish_time_seconds against last_race_finish_time_seconds
ggplot(data = vasaloppet) +
  aes(x = last_race_finish_time_seconds, y = finish_time_seconds) +
  geom_point()

Åkare som tillhör skidklubb har marginellt lägre snittid. Det tycks inte finnas något samband mellan antalet tidigare genomförda lopp och sluttid, men kan också vara en effekt av att prickarna överlappar varandra i spridningsdiagrammet. Däremot råder ett tydligt positivt samband med sluttiden föregående lopp.

# finish_time_seconds against num_previous_races
cor(vasaloppet$finish_time_seconds, vasaloppet$num_previous_races, use = "pairwise.complete.obs")
## [1] -0.1812451
# finish_time_seconds against last_race_finish_time_seconds
cor(vasaloppet$finish_time_seconds, vasaloppet$last_race_finish_time_seconds, use = "pairwise.complete.obs")
## [1] 0.8879286

Vi vederlägger att det inte finns något samband mellan antalet tidigare genomförda lopp och sluttid. Korrelationen med sluttiden föregående lopp är stark.

modell_mulkvansamb4 <- lm(finish_time_seconds ~ sex + member_of_club + num_previous_races + last_race_finish_time_seconds, data = vasaloppet, na.action = na.exclude)
summary(modell_mulkvansamb4)
## 
## Call:
## lm(formula = finish_time_seconds ~ sex + member_of_club + num_previous_races + 
##     last_race_finish_time_seconds, data = vasaloppet, na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -13412.3  -1638.5   -299.5   1375.9  19316.9 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                    5.843e+03  2.091e+02  27.942  < 2e-16 ***
## sexM                          -5.519e+02  1.260e+02  -4.380  1.2e-05 ***
## member_of_clubyes             -6.407e+01  7.637e+01  -0.839    0.402    
## num_previous_races             4.601e+01  5.528e+00   8.323  < 2e-16 ***
## last_race_finish_time_seconds  8.219e-01  5.218e-03 157.514  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2883 on 6905 degrees of freedom
##   (8436 observations deleted due to missingness)
## Multiple R-squared:  0.7908, Adjusted R-squared:  0.7907 
## F-statistic:  6527 on 4 and 6905 DF,  p-value: < 2.2e-16
  1. Vi testar hypoteserna

    H0: det finns inget samband

    Ha: det finns ett samband

    p-värdet är <2.2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

  2. H0: det finns inget samband mellan finish_time_seconds och sex

    Ha: det finns ett samband mellan finish_time_seconds och sex

p-värdet är 1.2e-05 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan finish_time_seconds och member_of_club

Ha: det finns ett samband mellan finish_time_seconds och member_of_club

p-värdet är 0.402 vilket är högre än 0.05. Nollhypotesen kan ej förkastas.

H0: det finns inget samband mellan finish_time_seconds och num_previous_races

Ha: det finns ett samband mellan finish_time_seconds och num_previous_races

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan finish_time_seconds och last_race_finish_time_seconds

Ha: det finns ett samband mellan finish_time_seconds och last_race_finish_time_seconds

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

  1. Förklaringsgraden är 0.7908, vilket innebär att 79% av variationen i finish_time_seconds förklaras av modellen. Den justerade förklaringsgraden är 79.07%.

  2. Effekten av kön man på tiden är negativ. Det stämmer med vad den deskriptiva statistiken visade. Variabeln member_of_club är inte signifikant, och därför bedömer vi inte dess effekt på responsvariabeln. Effekten av num_previous_races är positiv. Det förvånar, då visualiseringen inte visade på något samband med responsvariabeln och korrelationen var negativ. Effekten av last_race_finish_time_seconds är positiv, vilket stämmer med visualisering och korrelationsberäkning.

  3. Variabeln member_of_club bör exkluderas, eftersom den inte är signifikant:

model_mulkvansamb4 <- lm(finish_time_seconds ~ sex + num_previous_races + last_race_finish_time_seconds, data = vasaloppet, na.action = na.exclude)
summary(model_mulkvansamb4)
## 
## Call:
## lm(formula = finish_time_seconds ~ sex + num_previous_races + 
##     last_race_finish_time_seconds, data = vasaloppet, na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -13421.7  -1637.6   -304.3   1372.9  19356.9 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                   5806.11595  204.35520  28.412  < 2e-16 ***
## sexM                          -547.85179  125.89372  -4.352 1.37e-05 ***
## num_previous_races              45.25574    5.45461   8.297  < 2e-16 ***
## last_race_finish_time_seconds    0.82164    0.00521 157.715  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2883 on 6906 degrees of freedom
##   (8436 observations deleted due to missingness)
## Multiple R-squared:  0.7908, Adjusted R-squared:  0.7907 
## F-statistic:  8703 on 3 and 6906 DF,  p-value: < 2.2e-16

I denna modell är samtliga förklaringsvariabler signifikanta, och effekterna ser rimliga ut. Vi konstaterar också att den justerade förklaringsgraden är samma som i förra modellen. Det indikerar att beslutet att exkludera member_of_club var korrekt.

vasaloppet$residuals <- resid(model_mulkvansamb4)
vasaloppet$predicted <- fitted(model_mulkvansamb4)

ggplot(data = vasaloppet) +
  aes(x = predicted, y = residuals) + 
  geom_point()

ggplot(data = vasaloppet) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0 och histogrammet över residulerna uppvisar normalfördelning.

library(car)
vif(model_mulkvansamb4)
##                           sex            num_previous_races 
##                      1.049599                      1.015022 
## last_race_finish_time_seconds 
##                      1.043190

VIF indikerar inga multikollinearitetsproblem.

confint(model_mulkvansamb4, level = 0.95)
##                                      2.5 %       97.5 %
## (Intercept)                   5405.5169131 6206.7149926
## sexM                          -794.6422029 -301.0613808
## num_previous_races              34.5630365   55.9484514
## last_race_finish_time_seconds    0.8114287    0.8318539

Med 95% säkerhet är snittiden för en manlig åkare mellan 301 och 795 sekunder snabbare jämfört med övriga kön (kvinnor eller NA).

För varje ytterligare tidigare lopp man åkt, är med 95% säkerhet snittiden mellan 35 och 56 sekunder högre.

Med 95% är snittiden mellan 0.81 och 0.83 sekunder högre för varje sekund snabbare man åkte förra gången.

new_data <- data.frame(sex = "F", num_previous_races = 2, last_race_finish_time_seconds = 40000)
predict(model_mulkvansamb4, new_data, interval = "predict")
##        fit      lwr      upr
## 1 38762.28 33105.66 44418.89

Med 95% säkerhet är förväntad sluttid mellan 33106 och 44419 sekunder.

Lösning mulkvansamb.5

Vi exemplifierar med väljarstödet för M som responsvariabel och inkomst, andel högskoleutbildade och region som förklaringsvariabler.

# M against income
ggplot(data = election_result) +
  aes(x = Inkomst, y = M) +
  geom_point()

# M against proportion of high school graduates
ggplot(data = election_result) +
  aes(x = Högskola, y = M) +
  geom_point()

# M against region
election_result %>%
  group_by(Region) %>%
  summarise(medel = mean(M, na.rm = TRUE))
## # A tibble: 3 × 2
##   Region   medel
##   <chr>    <dbl>
## 1 Götaland  21.6
## 2 Norrland  13.3
## 3 Svealand  22.3

Det råder positiva linjära samband mellan inkomst och M och mellan andel högskoleutbildade och M. Väljarstödet för M är högst i Svealand och lägst i Norrland.

# M against income
cor(election_result$M, election_result$Inkomst, use = "pairwise.complete.obs")
## [1] 0.7374919
# M against proportion of high school graduates
cor(election_result$M, election_result$Högskola, use = "pairwise.complete.obs")
## [1] 0.6872908

Korrelationerna är starka.

model_mulkvansamb5 <- lm(M ~ Inkomst + Högskola + Region, data = election_result, na.action = na.exclude)
summary(model_mulkvansamb5)
## 
## Call:
## lm(formula = M ~ Inkomst + Högskola + Region, data = election_result, 
##     na.action = na.exclude)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -11.8708  -2.6062  -0.4732   2.5555  16.2896 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -1.695e+01  2.960e+00  -5.727 2.59e-08 ***
## Inkomst         1.373e-04  1.444e-05   9.510  < 2e-16 ***
## Högskola        2.881e-01  4.522e-02   6.370 7.54e-10 ***
## RegionNorrland -6.727e+00  6.281e-01 -10.709  < 2e-16 ***
## RegionSvealand -8.519e-01  5.289e-01  -1.611    0.108    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.893 on 285 degrees of freedom
## Multiple R-squared:  0.7097, Adjusted R-squared:  0.7056 
## F-statistic: 174.2 on 4 and 285 DF,  p-value: < 2.2e-16
  1. Vi testar hypoteserna

    H0: det finns inget samband

    Ha: det finns ett samband

    p-värdet är <2.2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

  2. H0: det finns inget samband mellan inkomst och väljarstöd för M

    Ha: det finns ett samband mellan inkomst och väljarstöd för M

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan andel högskoleutbildade och väljarstöd för M

Ha: det finns ett samband mellan andel högskoleutbildade och väljarstöd för M

p-värdet är 7.54e-10 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan region Norrland och väljarstöd för M

Ha: det finns ett samband mellan region Norrland och väljarstöd för M

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan region Svealand och väljarstöd för M

Ha: det finns ett samband mellan region Svealand och väljarstöd för M

p-värdet är 0.108 vilket är högre än 0.05. Nollhypotesen kan ej förkastas.

  1. Förklaringsgraden är 0.7097, vilket innebär att 71% av variationen i väljarstödet för M förklaras av modellen. Den justerade förklaringsgraden är 70.56%.

  2. Effekten av inkomst är positiv. Det stämmer med vad den deskriptiva statistiken visade. Effekten av andelen högskoleutbildade på väljarstödet för M är också positiv, vilket är rimligt sett till vad data visade. Region Norrland är signifikant skild från referenskategorin Götaland, medan Svealand och Götaland inte är signifikant skilda. Detta är i enlighet med den deskriptiva statistiken.

  3. Ingen revision av modellen behövs.

election_result$residuals <- resid(model_mulkvansamb5)
election_result$predicted <- fitted(model_mulkvansamb5)

ggplot(data = election_result) +
  aes(x = predicted, y = residuals) + 
  geom_point()

ggplot(data = election_result) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller slumpmässigt kring 0 och histogrammet över residulerna uppvisar normalfördelning.

library(car)
vif(model_mulkvansamb5)
##              GVIF Df GVIF^(1/(2*Df))
## Inkomst  2.319752  1        1.523073
## Högskola 2.216444  1        1.488773
## Region   1.085942  2        1.020826

VIF indikerar inga multikollinearitetsproblem.

confint(model_mulkvansamb5, level = 0.95)
##                        2.5 %       97.5 %
## (Intercept)    -22.778660745 -11.12655546
## Inkomst          0.000108883   0.00016572
## Högskola         0.199082050   0.37711626
## RegionNorrland  -7.962816613  -5.49021680
## RegionSvealand  -1.892947234   0.18924173

Med 95% säkerhet ökar väljarstödet för M med mellan 0.01 och 0.02 procentenheter för varje ytterligare krona i medelinkomst i kommunen.

För varje ytterligare procentenhet högskoleutbildade i kommunen, så ökar väljarstödet för M med 95% säkerhet med mellan 0.2 och 0.4 procentenheter.

Väljarstödet för M är med 95% säkerhet mellan 5.5 och 8.0 procentenheter lägre i Norrland jämfört med referenskategorin Götaland.

Det finns som tidigare konstaterats ingen statistiskt säkerställd skillnad i väljarstöd för M mellan Svealand och referenskategorin Götaland.

Låt oss predicera väljarstödet för en viss kommun i Götaland med medelinkomst 250 000 kr, 30% högskoleutbildade. Eftersom vi vill dra slutsatser om en viss kommun väljer vi intervall av typen predict.

new_data <- data.frame(Inkomst = 250000, Högskola = 30, Region = "Götaland")
predict(model_mulkvansamb5, new_data, interval = "predict")
##        fit      lwr      upr
## 1 26.01574 18.27518 33.75631

Med 95% säkerhet är förväntat väljarstöd för M mellan 18 och 34 procent i kommunen.

Lösning mulkvansamb.6

ggplot(data = used_cars) +
  aes(x = distance_10_km, y = price_sek) +
  geom_point()

Det finns en antydan till att sambandet mellan bilens körsträcka och pris inte är linjärt. Bäst beskriv sannolikt sambandet med ett polynom av andra graden.

  1. Vi skapar en ny variabel enligt bilens körsträcka i kvadrat.
used_cars$distance_10_km_sq <- used_cars$distance_10_km^2

Nu kan vi anpassa modellen med både distance_10_km och distance_10_km_sq som förklaringsvariabler.

model_mulkvansamb6 <- lm(price_sek ~ distance_10_km + distance_10_km_sq, data = used_cars, na.action = na.exclude)
summary(model_mulkvansamb6)
## 
## Call:
## lm(formula = price_sek ~ distance_10_km + distance_10_km_sq, 
##     data = used_cars, na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -38407 -12432  -2078   9475  82565 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)        2.522e+05  1.944e+03 129.737  < 2e-16 ***
## distance_10_km    -1.333e+01  8.734e-01 -15.262  < 2e-16 ***
## distance_10_km_sq  5.070e-04  7.651e-05   6.626  1.1e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 19310 on 406 degrees of freedom
## Multiple R-squared:  0.5147, Adjusted R-squared:  0.5124 
## F-statistic: 215.3 on 2 and 406 DF,  p-value: < 2.2e-16
  1. Vi testar hypoteserna

H0: det finns inget samband mellan distance_10_km och price_sek

Ha: det finns ett samband mellan distance_10_km och price_sek

p-värdet är <2e-16 vilket är lägre än 0.05. Nollhypotesen förkastas.

H0: det finns inget samband mellan distance_10_km_sq och price_sek

Ha: det finns ett samband mellan distance_10_km_sq och price_sek

p-värdet är 1.1e-11 vilket är lägre än 0.05. Nollhypotesen förkastas.

  1. Förklaringsgraden är 0.5147, vilket innebär att 51% av bilarnas pris förklaras av körsträckan.

  2. Effekten av distance_10_km är negativ, vilket är rimligt. Effekten av distance_10_km_sq är positiv, vilket också är rimligt. Det innebär att effekten av körsträckan avtar ju längre bilen gått. Det stämmer med visualiseringen.

used_cars$residuals <- resid(model_mulkvansamb6)
used_cars$predicted <- fitted(model_mulkvansamb6)

ggplot(data = used_cars) +
  aes(x = predicted, y = residuals) + 
  geom_point()

ggplot(data = used_cars) +
  aes(x = residuals) +
  geom_histogram()

Residualerna faller hyfsat slumpmässigt kring 0 och histogrammet över residulerna uppvisar normalfördelning. Vi studerar också spridningsdiagrammet över körsträcka mot pris med modellen inritad:

ggplot(data = used_cars) +
        aes(x = distance_10_km, y = price_sek) +
        geom_point() +
        geom_line(data = fortify(model_mulkvansamb6), aes(x = distance_10_km, y = .fitted), color = "red")

Modellen förefaller välanpassad.

  1. För att tolka effekten av förklaringsvariabeln på responsvariabeln i en polynommodell måste vi derivera den anpassade modellen med avseende på responsvariabeln:

\(\frac{d y}{d x} = \frac{d}{d x} \left( \beta_0 + \beta_1 x + \beta_2 x^2 \right) = \beta_1 + 2 \beta_2 x\)

För vår modell har vi därför att effekten av körsträckan på bilens pris ges av uttrycket:

\(-1.333e+01+2\cdot5.070e-04\)

  1. Eftersom vi vill dra slutsatser om snittpriset bland bilar som gått 2000 mil väljs konfidensintervall:
new_data <- data.frame(distance_10_km = 2000, distance_10_km_sq = 2000^2)
predict(model_mulkvansamb6, new_data, interval = "confidence")
##        fit      lwr      upr
## 1 227555.8 225536.9 229574.8

Med 95% säkerhet är förväntat pris bland bilar av denna modell som gått 2000 mil mellan 225 537 kr och 229 575 kr.

Lösning mulkvansamb.7

  1. En ny fil used_cars_filt skapas baserat på villkoret att equipment inte får vara low.
used_cars_filt <- used_cars %>%
  filter(equipment != "low")
  1. Visualiseringen görs med spridningsdiagram och tillägget color, så att prickarna får olika färg beroende på om utrustningsnivån är medium eller high.
ggplot(data = used_cars_filt) + 
  aes(x = age_months, y = price_sek, color = equipment) +
  geom_point()

Det förefaller som att bilar med utrustningsnivå high dels i genomsnitt har högre prisnivå, dels en något brantare värdeminskningskurva.

model_mulkvansamb7 <- lm(price_sek ~ age_months + equipment + age_months * equipment, data = used_cars_filt)
summary(model_mulkvansamb7)
## 
## Call:
## lm(formula = price_sek ~ age_months + equipment + age_months * 
##     equipment, data = used_cars_filt)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -40677  -8474   -422   7361  50519 
## 
## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                295124.0     3008.3  98.104  < 2e-16 ***
## age_months                  -2171.9      132.3 -16.416  < 2e-16 ***
## equipmentmedium            -45818.6     3733.2 -12.273  < 2e-16 ***
## age_months:equipmentmedium   1173.8      153.0   7.673 2.33e-13 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 13250 on 302 degrees of freedom
## Multiple R-squared:  0.702,  Adjusted R-squared:  0.699 
## F-statistic: 237.1 on 3 and 302 DF,  p-value: < 2.2e-16
  1. Allt annat lika sjunker bilarnas värde med i genomsnitt 2172 kronor per månad. Bilar med utrustningsnivå medium kostar i genomsnitt 45819 kronor mindre än de med utrustningsnivå high. För varje månads ökning i ålder, när utrustningsnivån är medium istället för high, minskar bilens värde med 2171.9 – 1173.8 = 998.1 kronor. Det innebär att ålderns negativa effekt på bilens värde är mindre för bilar med utrustningsnivå medium jämfört med de som har utrustningsnivå high. Med andra ord är värdeminskningen inte lika brant för bilar med utrustningnivå medium.

Lösning tid.1

ggplot(data = pageviews) +
  aes(x = week, y = pageviews) +
  geom_line()

Det föreligger en tydlig positiv trend i antalet sidvisningar över tiden.

cor(pageviews$pageviews, pageviews$week, use = "pairwise.complete.obs")
## [1] 0.986415

Korrelationen är mycket stark.

model_tid1 <- lm(pageviews ~ week, data = pageviews, na.action = na.exclude)
summary(model_tid1)
## 
## Call:
## lm(formula = pageviews ~ week, data = pageviews, na.action = na.exclude)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.3990 -0.6514 -0.1111  0.3409  3.5607 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 18.93464    0.81481   23.24 9.36e-14 ***
## week         1.80805    0.07528   24.02 5.59e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.657 on 16 degrees of freedom
## Multiple R-squared:  0.973,  Adjusted R-squared:  0.9713 
## F-statistic: 576.9 on 1 and 16 DF,  p-value: 5.59e-14
  1. Vi testar

H0: det finns inget samband mellan vecka och antal sidvisningar

Ha: det finns samband mellan vecka och antal sidvisningar

p-värdet 5.59e-14 är mindre än 0.05 varför nollhypotesen förkastas. Vi är 95% säkra på att det finns ett samband.

  1. Förklaringsgraden 0.973 visar att 97% av variationen i antalet sidvisningar förklaras av tidens gång. Vi studerar modellens residualer:
pageviews$residuals <- resid(model_tid1)

ggplot(data = pageviews) +
  aes(x = week, y = residuals) +
  geom_point()

ggplot(data = pageviews) +
  aes(x = residuals) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Residualerna faller slumpmässigt kring 0 men uppvisar ej normalfördelning. Det är dock inte förvånande med så liten stickprovsstorlek.

Vi kontrollerar också om det föreligger autokorrelation bland residualerna:

library(car)
durbinWatsonTest(model_tid1)
##  lag Autocorrelation D-W Statistic p-value
##    1      0.02806797      1.937122   0.704
##  Alternative hypothesis: rho != 0

Teststatistikan D-W Statistic är nära 2, vilket indikerar att autokorrelation ej föreligger. Sammantaget förefaller modellen välanpassad.

confint(model_tid1, level = 0.95)
##                 2.5 %    97.5 %
## (Intercept) 17.207314 20.661967
## week         1.648472  1.967627

Med 95% säkerhet ökar antalet sidvisningar med mellan 1.6 och 2.0 (tusental) per vecka.

  1. Eftersom vi vill dra slutsatser om enskilda veckor används intervall av typen predict.
new_data <- data.frame(week = c(19, 20, 21, 22))
predict(model_tid1, new_data, interval = "predict")
##        fit      lwr      upr
## 1 53.28758 49.37332 57.20185
## 2 55.09563 51.11684 59.07442
## 3 56.90368 52.85510 60.95226
## 4 58.71173 54.58836 62.83510

De 95-procentiga intervallen visar undre och övre gräns för antalet sidvisningar per vecka.

Lösning tid.2

  1. Eftersom tidsserien redan är sorterad från den äldsta till den nyaste observationen skapar vi tidsindexet direkt:
santa_monica$t <- seq.int(nrow(santa_monica))
ggplot(data = santa_monica) +
  aes(x = t, y = pageviews) +
  geom_line()

Det finns en antydan till positiv trend men tycks också ha skett förändringar i variabeln under studieperioden. Det finns också långa perioder med saknade data.

cor(santa_monica$pageviews, santa_monica$t, use = "pairwise.complete.obs")
## [1] -0.002580524

Korrelationen är väldigt svag.

model_tid2 <- lm(pageviews ~ t, data = santa_monica, na.action = na.exclude)
summary(model_tid2)
## 
## Call:
## lm(formula = pageviews ~ t, data = santa_monica, na.action = na.exclude)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -540.7 -231.9   63.4  209.7  444.6 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 550.915361  21.024090  26.204   <2e-16 ***
## t            -0.003704   0.056832  -0.065    0.948    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 265.6 on 638 degrees of freedom
## Multiple R-squared:  6.659e-06,  Adjusted R-squared:  -0.001561 
## F-statistic: 0.004249 on 1 and 638 DF,  p-value: 0.9481
  1. Vi testar

H0: det finns inget samband mellan tidsindexet och pageviews

Ha: det finns samband mellan tidsindexet och pageviews

p-värdet 0.948 är högre än 0.05 varför nollhypotesen ej kan förkastas. Det tycks ej finnas något samband.

  1. Förklaringsgraden är mycket låg. Vi studerar modellens residualer:
santa_monica$residuals <- resid(model_tid2)

ggplot(data = santa_monica) +
  aes(x = t, y = residuals) +
  geom_point()

ggplot(data = santa_monica) +
  aes(x = residuals) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Residualerna faller slumpmässigt kring 0 men uppvisar ej normalfördelning.

Vi kontrollerar också om det föreligger autokorrelation bland residualerna:

library(car)
durbinWatsonTest(model_tid2)
##  lag Autocorrelation D-W Statistic p-value
##    1       0.5528422     0.8907884       0
##  Alternative hypothesis: rho != 0

Teststatistikan D-W Statistic är lägre än 1, vilket indikerar att autokorrelation föreligger. Sammantaget är modellen ej välanpassad.

confint(model_tid2, level = 0.95)
##                   2.5 %      97.5 %
## (Intercept) 509.6305819 592.2001399
## t            -0.1153038   0.1078951

Då förklaringsvariabeln ej har ett signifikant samband med responsvariabeln är tolkning ej möjligt.

  1. Den 1 januari 2020 har tidsindex 641. Eftersom vi vill dra slutsatser om en enskild tidpunkt används intervall av typen predict.
new_data <- data.frame(t = 641)
predict(model_tid2, new_data, interval = "predict")
##        fit      lwr      upr
## 1 548.5409 25.30572 1071.776

Modellen predicerar att antalet sidvisningar den 1 januari 2020 är mellan 25 och 1072. Modellen är dock ej välanpassad vilket gör att resultat måste användas med stor försiktighet. Det har också fått konsekvenser i hur brett intervallet är.

Ledtråd tid.3

Informationen i datafilen börjar inte längst upp till vänster (i cell A1) i Excelfilen. Det kan vi enkelt hantera genom att be RStudio att ignorera de två första raderna: i rutan Import Options ändrar vi Skip till värdet 2.

För att konvertera variabeln från veckoformat till månadsformat kan vi (installera och) aktivera paketet lubridate och sedan skriva följande kommando:

data <- data

%>% mutate(Datum = ISOweek::ISOweek2date(paste0(År, "-W", sprintf("%02d", Vecka), "-1")))

Detta skapar en ny variabel (Datum) i datafilen. Vi extraherar sedan månad ur datumvariabeln:

data <- data %>% mutate(month = floor_date(Datum, "month"))

Nu kan vi beräkna summan av variabelvärdet inom respektive månad:

data_per_manad <- data %>%

group_by(month) %>% summarise(total = sum(variabel))

Lösning binlog.1

  1. Eftersom båda variablerna är kvalitativa visualiserar vi med en korstabell:
CrossTable(titanic$survived, titanic$sex, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##                  | titanic$sex 
## titanic$survived |    female |      male | Row Total | 
## -----------------|-----------|-----------|-----------|
##                0 |       127 |       682 |       809 | 
##                  |     0.157 |     0.843 |     0.618 | 
## -----------------|-----------|-----------|-----------|
##                1 |       339 |       161 |       500 | 
##                  |     0.678 |     0.322 |     0.382 | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       466 |       843 |      1309 | 
## -----------------|-----------|-----------|-----------|
## 
## 

Vi utläser att bland de överlevande var 67.8% kvinnor och 32.2% män.

model_binlog1 <- glm(survived ~ sex, family = binomial, data = titanic)
summary(model_binlog1)
## 
## Call:
## glm(formula = survived ~ sex, family = binomial, data = titanic)
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)   0.9818     0.1040   9.437   <2e-16 ***
## sexmale      -2.4254     0.1360 -17.832   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1741.0  on 1308  degrees of freedom
## Residual deviance: 1368.1  on 1307  degrees of freedom
## AIC: 1372.1
## 
## Number of Fisher Scoring iterations: 4
  1. Vi testar hypoteserna

H0: det finns inget samband

Ha: det finns ett samband

p-värdet är <2e-16, vilket är lägre än 0.05. H0 förkastas och vi är därför 95% säkra på att det finns ett samband mellan kön och överlevnad.

exp(coef(model_binlog1))
## (Intercept)     sexmale 
##  2.66929134  0.08843935

Oddset för överlevnad för en manlig passagerare är 1 - 0.088 = 91.2% lägre än för en kvinnlig passagerare.

titanic$predicted <- predict(model_binlog1, titanic, type = "response")

titanic <- titanic %>%
mutate(predicted = ifelse(predicted > 0.5, 1, 0))

CrossTable(titanic$survived, titanic$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##                  | titanic$predicted 
## titanic$survived |         0 |         1 | Row Total | 
## -----------------|-----------|-----------|-----------|
##                0 |       682 |       127 |       809 | 
## -----------------|-----------|-----------|-----------|
##                1 |       161 |       339 |       500 | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       843 |       466 |      1309 | 
## -----------------|-----------|-----------|-----------|
## 
## 

Klassificeringsgraden är

(339 + 682) / 1309 = 0.78 = 78%

new_data <- data.frame(sex = "female")
predict(model_binlog1, new_data, type="response")
##         1 
## 0.7274678
new_data <- data.frame(sex = "male")
predict(model_binlog1, new_data, type="response")
##         1 
## 0.1909846

Sannolikheten för överlevnad för en kvinna prediceras till 72.7% och för en man till 19.1%.

Lösning binlog.2

Relevanta förklaringsvariabler förefaller vara pclass, sex, age, sibsp, parch samt embarked.

# survived mot pclass
CrossTable(titanic$survived, titanic$pclass, prop.r = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Col Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##                  | titanic$pclass 
## titanic$survived |         1 |         2 |         3 | Row Total | 
## -----------------|-----------|-----------|-----------|-----------|
##                0 |       123 |       158 |       528 |       809 | 
##                  |     0.381 |     0.570 |     0.745 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##                1 |       200 |       119 |       181 |       500 | 
##                  |     0.619 |     0.430 |     0.255 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##     Column Total |       323 |       277 |       709 |      1309 | 
##                  |     0.247 |     0.212 |     0.542 |           | 
## -----------------|-----------|-----------|-----------|-----------|
## 
## 
# survived mot sex
CrossTable(titanic$survived, titanic$sex, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##                  | titanic$sex 
## titanic$survived |    female |      male | Row Total | 
## -----------------|-----------|-----------|-----------|
##                0 |       127 |       682 |       809 | 
##                  |     0.157 |     0.843 |     0.618 | 
## -----------------|-----------|-----------|-----------|
##                1 |       339 |       161 |       500 | 
##                  |     0.678 |     0.322 |     0.382 | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       466 |       843 |      1309 | 
## -----------------|-----------|-----------|-----------|
## 
## 
# survived mot age
titanic %>%
  group_by(survived) %>%
  summarise(medel = mean(age, na.rm = TRUE))
## # A tibble: 2 × 2
##   survived medel
##      <dbl> <dbl>
## 1        0  30.5
## 2        1  28.9
# survived mot sibsp
titanic %>%
  group_by(survived) %>%
  summarise(medel = mean(sibsp, na.rm = TRUE))
## # A tibble: 2 × 2
##   survived medel
##      <dbl> <dbl>
## 1        0 0.522
## 2        1 0.462
# survived mot parch
titanic %>%
  group_by(survived) %>%
  summarise(medel = mean(parch, na.rm = TRUE))
## # A tibble: 2 × 2
##   survived medel
##      <dbl> <dbl>
## 1        0 0.329
## 2        1 0.476
# survived mot embarked
CrossTable(titanic$survived, titanic$embarked, prop.r = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Col Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1307 
## 
##  
##                  | titanic$embarked 
## titanic$survived |         C |         Q |         S | Row Total | 
## -----------------|-----------|-----------|-----------|-----------|
##                0 |       120 |        79 |       610 |       809 | 
##                  |     0.444 |     0.642 |     0.667 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##                1 |       150 |        44 |       304 |       498 | 
##                  |     0.556 |     0.358 |     0.333 |           | 
## -----------------|-----------|-----------|-----------|-----------|
##     Column Total |       270 |       123 |       914 |      1307 | 
##                  |     0.207 |     0.094 |     0.699 |           | 
## -----------------|-----------|-----------|-----------|-----------|
## 
## 

Överlevnaden var högre i passagerarklass 1 än 2, och högre i 2 än 3. Bland de överlevande var 67.8% kvinnor och 32.2% män. Snittåldern bland de överlevande var cirka 1.6 år lägre än bland de förolyckade. De överlevande hade i genomsnitt färre syskon men fler barn med sig. 55.6% av resenärerna som steg på i Cherbourg klarade sig, medan motsvarande siffror för Queenstown och Southampton var 35.8% respektive 33.3%.

Vi bygger en initial modell:

model_binlog2 <- glm(survived ~ pclass + sex + age + sibsp + parch + embarked, family = binomial, data = titanic)
summary(model_binlog2)
## 
## Call:
## glm(formula = survived ~ pclass + sex + age + sibsp + parch + 
##     embarked, family = binomial, data = titanic)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  5.272416   0.454390  11.603  < 2e-16 ***
## pclass      -1.025480   0.117082  -8.759  < 2e-16 ***
## sexmale     -2.611172   0.179165 -14.574  < 2e-16 ***
## age         -0.037760   0.006628  -5.697 1.22e-08 ***
## sibsp       -0.344923   0.107580  -3.206  0.00135 ** 
## parch        0.055971   0.101061   0.554  0.57969    
## embarkedQ   -1.452586   0.444703  -3.266  0.00109 ** 
## embarkedS   -0.689774   0.206976  -3.333  0.00086 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1411.03  on 1043  degrees of freedom
## Residual deviance:  954.87  on 1036  degrees of freedom
##   (265 observations deleted due to missingness)
## AIC: 970.87
## 
## Number of Fisher Scoring iterations: 5

Variabeln parch är inte signifikant och vi tränar om modellen utan denna.

model_binlog2 <- glm(survived ~ pclass + sex + age + sibsp + embarked, family = binomial, data = titanic)
summary(model_binlog2)
## 
## Call:
## glm(formula = survived ~ pclass + sex + age + sibsp + embarked, 
##     family = binomial, data = titanic)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  5.303066   0.451164  11.754  < 2e-16 ***
## pclass      -1.023951   0.116939  -8.756  < 2e-16 ***
## sexmale     -2.630039   0.176216 -14.925  < 2e-16 ***
## age         -0.037892   0.006624  -5.721 1.06e-08 ***
## sibsp       -0.327067   0.102440  -3.193 0.001409 ** 
## embarkedQ   -1.471988   0.444063  -3.315 0.000917 ***
## embarkedS   -0.692134   0.206933  -3.345 0.000824 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1411.03  on 1043  degrees of freedom
## Residual deviance:  955.18  on 1037  degrees of freedom
##   (265 observations deleted due to missingness)
## AIC: 969.18
## 
## Number of Fisher Scoring iterations: 5

I denna modell är samtliga förklaringsvariabler signifikanta och förefaller rimliga, sett till den deskriptiva statistiken:

  • effekten av pclass är negativ, vilket indikerar att passagerarklass 2 har sämre överlevnadschans än passagerarklass 1 och att passagerarklass 3 har sämre överlevnadschans än passagerarklass 2

  • män har lägre chans att överleva

  • överlevnadschansen sjunker med passagerarens ålder

  • ju fler syskon, desto sämre chans för överlevnad

  • Cherbourg är referenskategori, och överlevnadschansen bland passagerare som steg ombord där är högre än för övriga hamnar

titanic$predicted <- predict(model_binlog2, titanic, type = "response")

titanic <- titanic %>%
mutate(predicted = ifelse(predicted > 0.5, 1, 0))

CrossTable(titanic$survived, titanic$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  1044 
## 
##  
##                  | titanic$predicted 
## titanic$survived |         0 |         1 | Row Total | 
## -----------------|-----------|-----------|-----------|
##                0 |       528 |        91 |       619 | 
## -----------------|-----------|-----------|-----------|
##                1 |       128 |       297 |       425 | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       656 |       388 |      1044 | 
## -----------------|-----------|-----------|-----------|
## 
## 

Klassificeringsgraden är

(297 + 528) / 1044 = 0.79 = 79%

Lägg märke till hur lite klassificeringsgraden förbättrades jämfört med modellen i uppgift 1.

  1. Vi predicerar överlevnadschansen för en kvinnlig passagerar om 40 år i klass 2, som reste ensam och steg på i Southampton.
new_data <- data.frame(sex = "female", age = 40, pclass = 2, sibsp = 0, embarked = "S")
predict(model_binlog2, new_data, type="response")
##         1 
## 0.7402672

Sannolikheten för överlevnad prediceras till 74.0%.

Lösning binlog.3

data_GA <- data_GA %>%
  mutate(conversion = ifelse(Transactions > 0, 1, 0))
  1. Eftersom responsvariabeln konvertering är kvalitativ och förklaringsvariabeln sessions är kvantitativ tar vi fram deskriptiv statistik:
data_GA %>%
  group_by(conversion) %>%
  summarise(mean = mean(Sessions, na.rm = TRUE))
## # A tibble: 2 × 2
##   conversion  mean
##        <dbl> <dbl>
## 1          0  3.91
## 2          1  4.87

Antalet sessioner är i genomsnitt högre när konvertering sker.

model_binlog3 <- glm(conversion ~ Sessions, family = binomial, data = data_GA)
summary(model_binlog3)
## 
## Call:
## glm(formula = conversion ~ Sessions, family = binomial, data = data_GA)
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -2.764984   0.014560 -189.90   <2e-16 ***
## Sessions     0.249401   0.002864   87.07   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 216868  on 248317  degrees of freedom
## Residual deviance: 208995  on 248316  degrees of freedom
## AIC: 208999
## 
## Number of Fisher Scoring iterations: 4
  1. Vi testar hypoteserna

H0: det finns inget samband

Ha: det finns ett samband

p-värdet är <2e-16, vilket är lägre än 0.05. H0 förkastas och vi är därför 95% säkra på att det finns ett samband mellan sessions och konvertering.

exp(coef(model_binlog3))
## (Intercept)    Sessions 
##  0.06297711  1.28325627

Oddset för konvertering ökar med 28% för varje ytterligare session.

data_GA$predicted <- predict(modell_dataga, data_GA, type = "response")

data_GA <- data_GA %>%
mutate(predicted = ifelse(predicerade > 0.5, 1, 0))

CrossTable(data_GA$konvertering, data_GA$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)

Vi noterar att modellen aldrig predicerar värdet 1 (händelsen konvertering). Det indikerar att modellen inte passar bra.

new_data <- data.frame(Sessions = c(1, 5, 10))
predict(model_binlog3, new_data, type = "response")
##          1          2          3 
## 0.07477294 0.17975918 0.43266755

Sannolikheten för konvertering prediceras till 7.4% vid en session, 18.0% vid fem sessioner och 43.3% vid tio sessioner.

Lösning binlog.4

  1. De förklaringsvariabler som bör kunna vara relevanta är Design, Sessions samt AvgSessionDuration. Vi inleder med att utforska sambanden:
# konvertering mot design
CrossTable(data_GA$conversion, data_GA$Design, prop.r = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Col Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  248318 
## 
##  
##                    | data_GA$Design 
## data_GA$conversion |  Design_A |  Design_B |  Design_C | Row Total | 
## -------------------|-----------|-----------|-----------|-----------|
##                  0 |     70062 |     69677 |     69295 |    209034 | 
##                    |     0.843 |     0.841 |     0.841 |           | 
## -------------------|-----------|-----------|-----------|-----------|
##                  1 |     13025 |     13148 |     13111 |     39284 | 
##                    |     0.157 |     0.159 |     0.159 |           | 
## -------------------|-----------|-----------|-----------|-----------|
##       Column Total |     83087 |     82825 |     82406 |    248318 | 
##                    |     0.335 |     0.334 |     0.332 |           | 
## -------------------|-----------|-----------|-----------|-----------|
## 
## 
# konvertering mot sessions
data_GA %>%
  group_by(conversion) %>%
  summarise(mean = mean(Sessions, na.rm = TRUE))
## # A tibble: 2 × 2
##   conversion  mean
##        <dbl> <dbl>
## 1          0  3.91
## 2          1  4.87
# konvertering mot AvgSessionDuration
data_GA %>%
  group_by(conversion) %>%
  summarise(mean = mean(AvgSessionDuration, na.rm = TRUE))
## # A tibble: 2 × 2
##   conversion  mean
##        <dbl> <dbl>
## 1          0  279.
## 2          1 1520.

Konverteringsgraden är mycket lika mellan designerna. Antalet sessioner är i genomsnitt högre när konvertering sker. AvgSessionDuration är i genomsnitt 1520 sekunder vid konvertering och 279 sekunder när det ej sker konvertering.

Vi bygger en initial modell:

model_binlog4 <- glm(conversion ~ Design + Sessions + AvgSessionDuration, family = binomial, data = data_GA)
summary(model_binlog4)
## 
## Call:
## glm(formula = conversion ~ Design + Sessions + AvgSessionDuration, 
##     family = binomial, data = data_GA)
## 
## Coefficients:
##                      Estimate Std. Error  z value Pr(>|z|)    
## (Intercept)        -4.3558394  0.0230060 -189.335  < 2e-16 ***
## DesignDesign_B      0.0340290  0.0172291    1.975  0.04826 *  
## DesignDesign_C      0.0548498  0.0172383    3.182  0.00146 ** 
## Sessions            0.2854301  0.0035371   80.697  < 2e-16 ***
## AvgSessionDuration  0.0020474  0.0000103  198.847  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 216868  on 248317  degrees of freedom
## Residual deviance: 140778  on 248313  degrees of freedom
## AIC: 140788
## 
## Number of Fisher Scoring iterations: 6

Samtliga förklaringsvariabler är signifikanta.

data_GA$predicted <- predict(model_binlog4, data_GA, type = "response")

data_GA <- data_GA %>%
mutate(predicted = ifelse(predicted > 0.5, 1, 0))

CrossTable(data_GA$conversion, data_GA$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)

Klassificeringsgraden är

(17259 + 202215) / 248318 = 0.884 = 88.4%

  1. Vi predicerar sannolikheten för konvertering för en besökare som mött design_A och har spenderat i genomsnitt 200 sekunder på siten under 5 sessioner:
new_data <- data.frame(Design = "Design_A", Sessions = 5, AvgSessionDuration = 200)
predict(model_binlog4, new_data, type = "response")
##          1 
## 0.07452205

Sannolikheten för konvertering prediceras till 7.5%.

Lösning binlog.5

election_result <- election_result %>%
  mutate(borgerlig_majoritet = ifelse(M + C + FP + KD > 50, 1, 0))
  1. Eftersom responsvariabeln borgerlig_majoritet är kvalitativ och förklaringsvariabeln inkomst är kvantitativ tar vi fram deskriptiv statistik:
election_result %>%
  group_by(borgerlig_majoritet) %>%
  summarise(mean = mean(Inkomst, na.rm = TRUE))
## # A tibble: 2 × 2
##   borgerlig_majoritet    mean
##                 <dbl>   <dbl>
## 1                   0 240488.
## 2                   1 294400.

Medelinkomsten är högre i kommuner med borgerlig majoritet.

model_binlog5 <- glm(borgerlig_majoritet ~ Inkomst, family = binomial, data = election_result)
summary(model_binlog5)
## 
## Call:
## glm(formula = borgerlig_majoritet ~ Inkomst, family = binomial, 
##     data = election_result)
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -2.413e+01  3.747e+00  -6.440 1.19e-10 ***
## Inkomst      8.121e-05  1.332e-05   6.095 1.09e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 145.554  on 289  degrees of freedom
## Residual deviance:  73.596  on 288  degrees of freedom
## AIC: 77.596
## 
## Number of Fisher Scoring iterations: 7
  1. Vi testar hypoteserna

H0: det finns inget samband

Ha: det finns ett samband

p-värdet är 1.09e-09, vilket är lägre än 0.05. H0 förkastas och vi är därför 95% säkra på att det finns ett samband mellan inkomst och borgerlig majoritet.

exp(coef(model_binlog5))
##  (Intercept)      Inkomst 
## 3.302258e-11 1.000081e+00

Oddset för borgerlig majoritet ökar med 0.008% för varje ytterligare krona i medelinkomst i kommunen.

valresultat$predicted <- predict(model_binlog5, valresultat, type = "response")

valresultat <- valresultat %>%
mutate(predicted = ifelse(predicerade > 0.5, 1, 0))

CrossTable(valresultat$borgerlig_majoritet, valresultat$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)

Klassificeringsgraden är (11 + 268) / 290 = 0.96 eller 96%.

new_data <- data.frame(Inkomst = 250000)
predict(model_binlog5, new_data, type="response")
##          1 
## 0.02120133

Sannolikheten för borgerlig majoritet i en kommun med medelinkomst 250 000 är bara 2.1%.

Lösning besltr.1

# exit (kvalitativ) mot number_of_years (kvalitativ)
CrossTable(panelists$exit, panelists$number_of_years, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  15000 
## 
##  
##                | panelists$number_of_years 
## panelists$exit |      1 to 3 |   3 or more | less than 1 |   Row Total | 
## ---------------|-------------|-------------|-------------|-------------|
##             no |        3475 |        9834 |         176 |       13485 | 
##                |       0.258 |       0.729 |       0.013 |       0.899 | 
## ---------------|-------------|-------------|-------------|-------------|
##            yes |         481 |          32 |        1002 |        1515 | 
##                |       0.317 |       0.021 |       0.661 |       0.101 | 
## ---------------|-------------|-------------|-------------|-------------|
##   Column Total |        3956 |        9866 |        1178 |       15000 | 
## ---------------|-------------|-------------|-------------|-------------|
## 
## 
# exit (kvalitativ) mot more_than_five (kvalitativ)
CrossTable(panelists$exit, panelists$more_than_five, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  15000 
## 
##  
##                | panelists$more_than_five 
## panelists$exit |        no |       yes | Row Total | 
## ---------------|-----------|-----------|-----------|
##             no |       173 |     13312 |     13485 | 
##                |     0.013 |     0.987 |     0.899 | 
## ---------------|-----------|-----------|-----------|
##            yes |      1223 |       292 |      1515 | 
##                |     0.807 |     0.193 |     0.101 | 
## ---------------|-----------|-----------|-----------|
##   Column Total |      1396 |     13604 |     15000 | 
## ---------------|-----------|-----------|-----------|
## 
## 
# exit (kvalitativ) mot gender (kvalitativ)
CrossTable(panelists$exit, panelists$gender, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  15000 
## 
##  
##                | panelists$gender 
## panelists$exit |    female |      male | Row Total | 
## ---------------|-----------|-----------|-----------|
##             no |      6831 |      6654 |     13485 | 
##                |     0.507 |     0.493 |     0.899 | 
## ---------------|-----------|-----------|-----------|
##            yes |       733 |       782 |      1515 | 
##                |     0.484 |     0.516 |     0.101 | 
## ---------------|-----------|-----------|-----------|
##   Column Total |      7564 |      7436 |     15000 | 
## ---------------|-----------|-----------|-----------|
## 
## 
# exit (kvalitativ) mot age (kvantitativ)
panelists %>%
  group_by(exit) %>%
  summarise(medel = mean(age, na.rm = TRUE))
## # A tibble: 2 × 2
##   exit  medel
##   <chr> <dbl>
## 1 no     49.7
## 2 yes    34.6
library(rpart)
model_besltr1 <- rpart(exit ~ number_of_years + more_than_five + gender + age, data = panelists, method = 'class')
panelists$predicted <- predict(model_besltr1, panelists, type = 'class')
CrossTable(panelists$exit, panelists$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  15000 
## 
##  
##                | panelists$predicted 
## panelists$exit |        no |       yes | Row Total | 
## ---------------|-----------|-----------|-----------|
##             no |     13347 |       138 |     13485 | 
## ---------------|-----------|-----------|-----------|
##            yes |       189 |      1326 |      1515 | 
## ---------------|-----------|-----------|-----------|
##   Column Total |     13536 |      1464 |     15000 | 
## ---------------|-----------|-----------|-----------|
## 
## 

Klassificeringsgraden är

(1326 + 13347) / (1326 + 13347 + 138 + 189) = 0.9782 = 97.8%

  1. Beslutsträdet visualiseras:
library(rpart.plot)
rpart.plot(model_besltr1, type = 4, extra = 101)

Den viktigaste variabeln för att förklara att man avregistrerat sig är om man deltagit i mer än fem undersökningar under det senaste året. Bland de som inte deltagit i mer än fem undersökningar sig är antal år som panelist den viktigaste variabeln.

Bland de som deltagit i mer än fem undersökningar sig hittar vi en viss skillnad sett till ålder. Åldern är en kvantitativ variabel, och här har trädet brutit vid 35 år.

new_data <- data.frame(gender = "female", age = 43, number_of_years = "3 or more", more_than_five = "yes")
predict(model_besltr1, new_data, type = "prob")
##          no        yes
## 1 0.9866348 0.01336519

Sannolikheten för att panelisten ska avregistrera sig är 1.3%.

new_datra <- data.frame(gender = "female", age = 20, number_of_years = "1 to 3", more_than_five = "no")
predict(model_besltr1, new_data, type = "prob")
##          no        yes
## 1 0.9866348 0.01336519

Sannolikheten för att panelisten ska avregistrera sig är 91.3%.

Lösning besltr.2

  1. De variabler som förefaller relevanta för att förstå händelse survived är pclass, sex, age, sibsp, parch, fare och embarked.
library(rpart)
model_besltr2 <- rpart(survived ~ pclass + sex + age + sibsp + parch + fare + embarked, data = titanic, method = 'class')
titanic$predicted <- predict(model_besltr2, titanic, type = 'class')
CrossTable(titanic$survived, titanic$predicted, prop.r = FALSE, prop.c = FALSE, prop.t = FALSE, prop.chisq = FALSE)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |-------------------------|
## 
##  
## Total Observations in Table:  1309 
## 
##  
##                  | titanic$predicted 
## titanic$survived |         0 |         1 | Row Total | 
## -----------------|-----------|-----------|-----------|
##                0 |       732 |        77 |       809 | 
## -----------------|-----------|-----------|-----------|
##                1 |       151 |       349 |       500 | 
## -----------------|-----------|-----------|-----------|
##     Column Total |       883 |       426 |      1309 | 
## -----------------|-----------|-----------|-----------|
## 
## 

Klassificeringsgraden är

(349 + 732) / (349 + 732 + 77 +151) = 0.826 = 82.6%

  1. Beslutsträdet visualiseras:
library(rpart.plot)
rpart.plot(model_besltr2, type = 4, extra = 101)

Den viktigaste variabeln för överlevnad är passagerarens kön. Bland män är sedan åldern (över eller under 9.5 år) viktigast. Därefter följer hur många syskon/partners man reste tillsammans med. För kvinnor spelar passagerarklass följt av biljettens pris störst roll.

jack <- data.frame(pclass = 3, sex = "male", age = 20, sibsp = 0, parch = 0, fare = 7, embarked = "S")
predict(model_besltr2, jack, type = "prob")
##           0         1
## 1 0.8291457 0.1708543

Sannolikheten för att passageraren ska överleva är 17%.

rose <- data.frame(pclass = 1, sex = "female", age = 17, sibsp = 1, parch = 1, fare = 200, embarked = "S")
predict(model_besltr2, rose, type = "prob")
##       0     1
## 1 0.068 0.932

Sannolikheten för att passageraren ska överleva är 93.2%.

Lösning data.1

frukost <- mcdonalds %>%
  filter(Category == "Breakfast")

Vi använder kommandot filter för att exkludera alla produktkategorier utom breakfast.

frukost %>%
  select(Category, Item, Grams)
## # A tibble: 42 × 3
##    Category  Item                                                          Grams
##    <chr>     <chr>                                                         <dbl>
##  1 Breakfast Egg McMuffin                                                    136
##  2 Breakfast Egg White Delight                                               136
##  3 Breakfast Sausage McMuffin                                                111
##  4 Breakfast Sausage McMuffin with Egg                                       162
##  5 Breakfast Sausage McMuffin with Egg Whites                                162
##  6 Breakfast Steak & Egg McMuffin                                            184
##  7 Breakfast Bacon, Egg & Cheese Biscuit (Regular Biscuit)                   150
##  8 Breakfast Bacon, Egg & Cheese Biscuit (Large Biscuit)                     164
##  9 Breakfast Bacon, Egg & Cheese Biscuit with Egg Whites (Regular Biscuit)   153
## 10 Breakfast Bacon, Egg & Cheese Biscuit with Egg Whites (Large Biscuit)     167
## # ℹ 32 more rows

Vi använder kommandot select för att välja ut önskade variabler.

Lösning data.2

rm(frukost)

Kommandot rm tar bort en datafil ur Environment.

Lösning data.3

  1. Import Dataset -> Excel.
tabyl(spotify$playlist_genre)
##  spotify$playlist_genre    n   percent
##                     edm 6043 0.1840526
##                   latin 5155 0.1570067
##                     pop 5507 0.1677276
##                     r&b 5431 0.1654128
##                     rap 5746 0.1750069
##                    rock 4951 0.1507934

Kommandot tabyl från paketet janitor skapar snygga frekvenstabeller med absoluta (antal) och relativa (andelar) frekvenser.

spotify %>%
  group_by(track_artist) %>%
  summarise(antal = n()) %>%
  arrange(desc(antal))
## # A tibble: 10,693 × 2
##    track_artist              antal
##    <chr>                     <int>
##  1 Martin Garrix               161
##  2 Queen                       136
##  3 The Chainsmokers            123
##  4 David Guetta                110
##  5 Don Omar                    102
##  6 Drake                       100
##  7 Dimitri Vegas & Like Mike    93
##  8 Calvin Harris                91
##  9 Hardwell                     84
## 10 Kygo                         83
## # ℹ 10,683 more rows
spotify <- spotify %>%
  mutate(duration_min_s = duration_ms/60000)

Kommandot mutate gör ändringar i datafilen. Millisekunder räknas om till minuter genom att dividera med 60000.

spotify %>%
  group_by(playlist_genre) %>%
  summarise(medellängd = mean(duration_min_s),
            standardavvikelse = sd(duration_min_s),
            antal = n())
## # A tibble: 6 × 4
##   playlist_genre medellängd standardavvikelse antal
##   <chr>               <dbl>             <dbl> <int>
## 1 edm                  3.71             1.15   6043
## 2 latin                3.61             0.807  5155
## 3 pop                  3.63             0.755  5507
## 4 r&b                  3.96             0.964  5431
## 5 rap                  3.57             1.00   5746
## 6 rock                 4.14             1.09   4951

Lösning data.4

spotify <- spotify %>%
  rename(duration_min = duration_min_s)

Kommandot rename byter namn enligt nytt variabelnamn = gammalt variabelnamn.

Lösning data.5

spotify <- spotify %>%
  mutate(poplåt = fct_recode(playlist_genre,
                             "pop" = "pop",
                             "other" = "edm",
                             "other" = "latin",
                             "other" = "r&b",
                             "other" = "rap",
                             "other" = "rock"))

Uppgiften hade också kunnat lösas med kommandot ifelse. Ännu en alternativ lösning hade varit kommandot fct_collapse:

spotify <- spotify %>%
  mutate(poplåt2 = fct_collapse(playlist_genre,
                                pop = "pop",
                                other = c("edm", "latin", "r&b", "rap", "rock")))
spotify$poplåt <- NULL

Lösning data.6

urval <- spotify %>%
  sample_n(50)

Lösning data.7

data1 <- data.frame(id = c(1, 2, 3, 4, 5), x = c(10, 20, 30, 40, 50))
data2 <- data.frame(id = c(1, 2, 3, 4, 6), y = c(10, 20, 30, 40, 60))

Lösning data.8

Här presenteras tre möjliga sätt att merga filerna.

Left join innebär att det är vi vill inkludera alla id-nummer från data.1 och fylla på med data för de id-nummer från data.2 som också finns i data.1.

data_left_join <- left_join(data1, data2, by = "id")

Right join innebär att det är vi vill inkludera alla id-nummer från data.2 och fylla på med data för de id-nummer från data.1 som också finns i data.2.

data_right_join <- right_join(data1, data2, by = "id")

Full join innebär att det är vi vill inkludera alla id-nummer som finns antingen i data.1 eller data.2.

data_full_join <- full_join(data1, data2, by = "id")

Lösning data.9

stacked_data <- bind_rows(data1, data2)

Lösning data.10

library(writexl)
write_xlsx(stacked_data, path = "~/Desktop/excelfil.xlsx")

Lösning data.11

data <- data.frame(x = 1:100)
data$interval <- cut_interval(data$x, n = 5)
data$number <- cut_number(data$x, n = 5)
data$width <- cut_width(data$x, width = 5, boundary = 1)