Datorövning 3 Statistisk teori med tillämpningar Simulering i SAS Syfte Att simulera data är en metod som ofta används inom forskning inom ett stort antal ämnen, exempelvis nationalekonomi, fysik, miljövetenskap eller olika samhällsvetenskapliga ämnen. Inom statistisk forskning används simulering bland annat för att utvärdera modeller och för att få fram skattningar på parametrar när det inte är möjligt att hitta en analytisk lösning. Datorövning 3 (D3) går igenom hur man kan dra slumptal från olika kända sannolikhetsfördelningar och hur man kan jämföra dessa med förväntade resultat, både numeriskt och grafiskt. D3 förutsätter att man har gått igenom och förstått Datorövning 1 och 2. Målet för D3 är att studenterna ska kunna följande: Dra slumptal från olika sannolikhetsfördelningar med hjälp av SAS På olika sätt jämföra simulerade resultat med de som förväntas enligt en teoretisk modell. Exempel Likformig fördelning All slumptalsdragning i SAS sker inuti ett DATA-steg. Vi börjar med att dra ett slumptal från en likformig (uniform) fördelning. Använd PROC PRINT för att se resultatet. 1
data uni; seed=4997; /* sets the starting value for the algorithm. Use any number, e.g. the last four digits of your phone number */ x=ranuni(seed); /* draw 1 random number from U[0,1] distribution */ seed= anger ett startnummer till SAS slumptalsgenerator. Detta gör det möjligt att upprepa försök som bygger på slumptalsdragning; om man använder samma startnummer kommer man att dra samma slumptal. I nedanstående exempel och uppgifter ska varje grupp använda olika startnummer (men det går bra att använda samma startnummer till flera uppgifter). Använd exempelvis de fyra sista siffrorna i en gruppmedlems telefonnummer. x=ranuni(seed) drar ett slumptal från en likformig [0,1] - fördelning och lägger värdet i variabeln x. För att dra flera slumptal kan man givetvis upprepa flera datasteg (med olika startnummer) och sedan slå ihop dataseten, men det är inte speciellt praktiskt om man behöver så många som 100 eller 1000 olika slumptal. Då kan man istället använda sig av en loop. Nedan visas ett exempel på hur man drar 10 slumptal från en U[0, 1]-fördelning. data several; seed=110202; do i=1 to 10; /*We want 10 ~ U[0,1] numbers */ x=ranuni(seed); drop i seed; proc print; Normalfördelningen För att dra slumptal från standard normalfördelningen (N(0, 1)) kan man använda kommandot rand och sedan specificera normalfördelningen och dess parametrar. Exempel: 2
data normal; seed=4997; do i=1 to 10; x=rand('normal',0,1); drop i seed; På motsvarande sätt kan man generera slumptal från de flesta fördelningar genom att specifiera deras namn (eller de fyra första bokstäverna i deras namn) samt önskade parametrar. Transformationer Ibland kan man vilja dra slumptal från en fördelning som är en transformering av en slumpvariabel med en känd fördelning, exempelvis från en U[2, 5]- fördelning. Detta görs genom att dra ett slumptal från U[0, 1]-fördelningen, multiplicera med 3 och addera 2, som i nedanstående exempel. data uniform25; seed=110202; do i=1 to 10; /*We want 10 ~ U[0,1] numbers */ x=2+3*ranuni(seed); /*Theta1=2, theta2=5 */ drop i seed; Använd som vanligt PROC PRINT för att se resultatet och till exempel PROC UNIVARIATE för att se deskriptiv statistik och rita ett histogram. Tabell över SAS-kommandon för några vanliga fördelningar Som ett alternativ till att dra slumptal med rand( fördelning,...) enligt exemplet med normalfördelningen ovan, har några fördelningar egna kommandon. Nedanstående tabell innehåller SAS-kommandon för några vanliga sannolikhetsfördelningar. 3
Fördelning SAS-kommando parametrar binomial ranbin(seed,n,p) n, p exponential ranexp(seed)*b b = β likformig ranuni(seed) θ 1 = 0, θ 2 = 1 normal rannor(seed) µ = 0, σ = 1 poisson ranpoi(seed, a) λ = a Dubbelloopar I en del situationer vill man upprepa en loop flera gånger. Lösningen på detta är att lägga in loopen i ännu en loop. Det fungerar på precis samma sätt som en enkel-loop, förutom att man måste hålla koll på två "räknare" och avslutande. Nedanstående exempel kan användas för att illustrera centrala gränsvärdessatsen (CGS), det vill säga att för "stora" stickprov följer stickprovsmedelvärden en normalfördelning, oavsett vilken fördelning den undersökta variablen har). I det första steget drar vi ett stickprov om 30 och upprepar detta 500 gågner. För att lättare hålla ordning på vilken "räknare" som är vilken har den ena, som drar 30 observationer döpts till obs, medan den som sköter upprepningen döpts till stickprov (eftersom den räknar antalet "stickprov"). data loopex4; do stickprov =1 to 500; /*Upprepa stickprovsdragning 500 ggr */ do obs =1 to 30; /* dra ett stickprov om 30 obs */ x=ranuni(0); /* Fördelningen vi drar stickprovet ifrån är U~[0,1]. */ drop obs; Efter det här steget bör man titta i loggen. Om simuleringen har fungerat bra så ska datasetet nu ha 30*500 = 15000 observationer. Tips: Om man ska programmera en dubbelloop är det bäst att börja med den "inre" loopen, i det här fallet att dra 30 observationer, och se till att det fungerar innan man börjar upprepa. I nästa steg räknar vi ut medelvärdet i varje "stickprov" med hjälp av PROC MEANS. Vi använder PROC UNIVARIATE för att rita ett histogram 4
som vi sedan kan jämföra med normal- respektive likformig fördelning. proc means data=loopex4 noprint; by stickprov; /* Ta ut medelvärdet för varje stickprov */ var x; output out=cgs_ill mean(x)=x_medel; proc print data=cgs_ill(obs=10); /* titta på de 10 första observationerna i vårt nya dataset. */ proc univariate data=cgs_ill noprint; histogram x_medel/ normal Övningar I nedanstående övningar är n = gruppens nummer. Om man inte kommer ihåg nummret kan man exempelvis använda den sista siffran i någon gruppmedlems telefonnummer. 1. Antag att n % av alla datachip som tillverkas av en viss maskin är defekta. Antag sedan att maskinen producerar n + 10 datachip per timma. Sannolikheten att ett chip är defekt är oberoende av huruvida övriga chip är defekta eller felfria. (a) Skriv upp sannolikhetsmodellen för antalet felaktiga chip tillverkade under en timme (på papper eller i ordbehandlare). (b) Använd SAS för att simulera antalet felaktiga chip för varje timme under ett dygn (=24 timmar). (c) Använd PROC MEANS för att jämföra medelvärde och varians för den simulerade datan. Jämför med de teoretiska värdena. 2. Under ett år sker i genomsnitt n trafikolyckor på en viss vägsträcka. Låt Y vara antalet trafikolyckor under ett slumpvis utvalt år. Antag att antalet olyckor är oberoende av antalet olyckor under övriga år. (a) Definiera och skriv ner en sannolikhetsmodell för Y. 5
(b) Använd SAS för att simulera antalet olyckor under 20 år (c) Jämför resultatet med de teoretiska värdena. 3. Medellivslängden för ett visst märke på glödlampor är 10n timmar. Låt X vara livslängden för en slumpvis utvald glödlampa. (a) Föreslå en sannolikhetsmodell för X och skriv ner den. (b) Simulera livslängden för i)10 ii)100 och iii)1000 glödlampor. Jämför simulerade medelvärden och varianser med de teoretiska. (c) Plotta din data i tre histogram. Rita kurvan för den teoretiska sannolikhetfördelningen ovanpå histogrammet. Jämför resultaten i i), ii) och iii). Vad blir slutsatsen? 4. Antag att du har 10 glödlampor av samma märke som ovan. De tre glödlamporna är seriekopplade i en ljusslinga, det vill säga när en av dem slocknar så slocknar hela ljusslingan. Simulera livslängden hos 100 ljusslingor på följande vis: (a) Skriv en loop som simulerar livslängden hos 10 glödlampor (= en ljusslinga) (b) Skriv en loop som upprepar loopen ovan 100 gånger. (c) Använd PROC MEANS för att ta ut den glödlampa med kortast livslängd i varje ljusslinga. (d) Beskriv din data numeriskt och grafiskt. Ser resultatet ut som du väntat dig? Vilken fördelning borde ljusslingans livstid ha? Borde medelvärde och varians vara högre eller lägre än för en enskild glödlampa? 6