Na podstawie pliku sport.csv, zawierającego wyniki pewnej ankiety, zamodelować sieć Bayesowską (uczenie struktury, estymacja parametrów), w której węzłami będą zmienne losowe zawarte w poniższej tabeli.
Zmienna losowa | Wartość | Opis |
---|---|---|
A | a | Badany ćwiczy regularnie. |
b | Badany ćwiczy nieregularnie. | |
c | Badany nie ćwiczy. | |
B | a | Aktywny członek klubu sportowego. |
b | Bierny członek klubu sportowego. | |
c | Badany nie należy do klubu sportowego. | |
C | a | Dieta przygotowana przez dietetyka. |
b | Badany samodzielnie dba o zdrową dietę. | |
c | Badany nie odżywia się zdrowo. | |
D | a | Utrata wagi powyżej 5 kg. |
b | Utrata wagi poniżej 5 kg. | |
c | Brak utraty wagi. | |
E | a | Wiek <= 20 lat. |
b | Wiek 21-39 lat. | |
c | Wiek >= 40 lat. |
Wczytujemy dane
sport <- read.csv("C:/Users/r_nal/Seafile/Moja biblioteka/Wnioskowanie w warunkach niepenwości/Pro_3/sport.csv")
head(sport)
## X A B C D E
## 1 1 c c c a c
## 2 2 c c b b b
## 3 3 a c a a c
## 4 4 b a a b a
## 5 5 c c a c c
## 6 6 c c a c b
colnames(sport)
## [1] "X" "A" "B" "C" "D" "E"
Pierwsza kolumna “X” zawiera numer porządkowy. Nie będzie ona nam do niczego potrzebna, dlatego usuwam ją z tabeli.
sport2 <- sport[,c(2,3,4,5,6)]
head(sport2)
## A B C D E
## 1 c c c a c
## 2 c c b b b
## 3 a c a a c
## 4 b a a b a
## 5 c c a c c
## 6 c c a c b
Instalowanie pakietów
install.packages("bnlearn")
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install(c("graph", "RBGL", "Rgraphviz"))
a
install.packages("gRain", dependencies=TRUE)
Ładowanie pakietow.
library(bnlearn)
library(gRain)
## Warning: pakiet 'gRain' został zbudowany w wersji R 4.3.3
## Ładowanie wymaganego pakietu: gRbase
## Warning: pakiet 'gRbase' został zbudowany w wersji R 4.3.3
##
## Dołączanie pakietu: 'gRbase'
## Następujące obiekty zostały zakryte z 'package:bnlearn':
##
## ancestors, children, nodes, parents
Wszystkie algorytmy akceptuja niepelne dane. Więcej informacji można znaleźć szukając structure-learning
Polecenie siechc <- hc(sport2)
nie zadziała, ponieważ
dane są tekstowe, a nie numeryczne. Musimy zamienić kolumny na czyniki
(ang. factor).
sport2$A <- as.factor(sport2$A)
sport2$B <- as.factor(sport2$B)
sport2$C <- as.factor(sport2$C)
sport2$D <- as.factor(sport2$D)
sport2$E <- as.factor(sport2$E)
siechc <- hc(sport2)
graphviz.plot(siechc)
## Ładowanie wymaganej przestrzeni nazw: Rgraphviz
score(siechc,data=sport2,type="bic")
## [1] -20846.79
siec <- pc.stable(sport2)
graphviz.plot(siec)
siec1 <- set.arc(siec, "E", "B")
siec1 <- set.arc(siec1, "B", "A")
graphviz.plot(siec1)
Wyniki dopasowania danych do sieci
score(siec1,data=sport2,type="bic")
## [1] -20846.79
siec2 <- set.arc(siec, "B", "E")
siec2 <- set.arc(siec2, "B", "A")
graphviz.plot(siec2)
Wyniki dopasowania danych do sieci
score(siec2,data=sport2,type="bic")
## [1] -20846.79
Sieci rownoważne (kierując się kryterium BIC)
siec3 <- set.arc(siec, "E", "B")
siec3 <- set.arc(siec3, "A", "B")
graphviz.plot(siec3)
Wyniki dopasowania danych do sieci
score(siec3,data=sport2,type="bic")
## [1] -21144.31
Wynik sieci pogorszy sie jesli zmienimy luk skierowany.
siechc <- hc(sport2)
graphviz.plot(siechc)
zmianakierunku <- set.arc(siechc, "D", "C")
score(zmianakierunku,data=sport2,type="bic")
## [1] -21644.15
graphviz.plot(zmianakierunku)
sieclista <- pc.stable(sport2,
whitelist = matrix(c("D","E"),
ncol = 2, byrow = TRUE))
graphviz.plot(sieclista)
sieclista1 <- set.arc(sieclista, "A", "B")
score(sieclista1,data=sport2,type="bic")
## [1] -20890.46
Wynik gorszy niż na początkowej sieci.
Innym kryterium statystycznym używanym przez algorytmy w trakcie uczenia struktury jest warunkowy test niezależności.
Warunkowy test niezależności skupia się na obecności poszczególnych łuków. Łuk sieci reprezentuje zależność (w sensie probabilistycznym) pomiędzy węzłami. Warunkowy test niezależności może zostać wykonany w celu oceny czy zależność pomiędzy wezłami (w sensie probabilistycznym) jest wspierana przez dane.
Interpretacja testu \(\chi^2\)
Interpretacja:
Testowanie dla pojedynczych zmiennych:
ci.test(zmienna1,zmienna2,warunek,test="x2", data=dane)
Przy użyciu tego testu możemy rozważać dodanie łuku do sieci lub przeanalizować, czy łuk powinien zostać usunięty z sieci (ponieważ jego istnienie nie jest wspierane przez dane).
graphviz.plot(siechc)
ci.test("B","D",test="x2", data=sport2)
##
## Pearson's X^2
##
## data: B ~ D
## x2 = 571.13, df = 4, p-value < 2.2e-16
## alternative hypothesis: true value is greater than 0
Nie ma podstaw do odrzucenia hipotezy, że zmienne B oraz D są niezależne. Czyli zmienne B i D uznajemy za zależne.
Rozważmy dodanie łuku pomiędzy B i D.
ci.test("B","D",c("A"),test="x2", data=sport2)
##
## Pearson's X^2
##
## data: B ~ D | A
## x2 = 12.449, df = 12, p-value = 0.4104
## alternative hypothesis: true value is greater than 0
Duża p-value oznacza zależność pomiędzy B i D nie jest istotna (w zadanej już strukurze). Oznacza to, że nie trzeba dodawać łuku pomiędzy B i D w istniejącej już sieci.
ci.test("A","D",c("C"), test="x2", data=sport2)
##
## Pearson's X^2
##
## data: A ~ D | C
## x2 = 4311.6, df = 12, p-value < 2.2e-16
## alternative hypothesis: true value is greater than 0
Mała p-value oznacza, że zmienne sa zależne(pod warunkiem rodziców), więc łuk jest dobrze wspierany przez dane.
Skorzystamy z gotowej funkcji. Ponieważ kolumny zostały już zmienione na czynniki, będzie ona działać.
rozkladprawdopodobienstw<- bn.fit(siechc, sport2)
rozkladprawdopodobienstw
##
## Bayesian network parameters
##
## Parameters of node A (multinomial distribution)
##
## Conditional probability table:
## a b c
## 0.3266 0.3330 0.3404
##
## Parameters of node B (multinomial distribution)
##
## Conditional probability table:
##
## A
## B a b c
## a 0.84507042 0.43903904 0.09518214
## b 0.03306797 0.21141141 0.09753231
## c 0.12186160 0.34954955 0.80728555
##
## Parameters of node C (multinomial distribution)
##
## Conditional probability table:
## a b c
## 0.7638 0.1916 0.0446
##
## Parameters of node D (multinomial distribution)
##
## Conditional probability table:
##
## , , C = a
##
## A
## D a b c
## a 0.79635499 0.09565217 0.07585139
## b 0.10855784 0.79130435 0.11996904
## c 0.09508716 0.11304348 0.80417957
##
## , , C = b
##
## A
## D a b c
## a 0.18791946 0.88000000 0.27164179
## b 0.10738255 0.04000000 0.49253731
## c 0.70469799 0.08000000 0.23582090
##
## , , C = c
##
## A
## D a b c
## a 0.45205479 0.29333333 0.14666667
## b 0.17808219 0.44000000 0.34666667
## c 0.36986301 0.26666667 0.50666667
##
##
## Parameters of node E (multinomial distribution)
##
## Conditional probability table:
##
## B
## E a b c
## a 0.60272767 0.27447552 0.18004640
## b 0.29960405 0.27447552 0.31090487
## c 0.09766828 0.45104895 0.50904872
graphviz.chart(rozkladprawdopodobienstw)
library(lattice)
## Warning: pakiet 'lattice' został zbudowany w wersji R 4.3.3
bn.fit.barchart(rozkladprawdopodobienstw$A, main="Zmienna A - cwiczenia")
bn.fit.barchart(rozkladprawdopodobienstw$B, main="Zmienna B - czlonek klubu sportowego")
bn.fit.barchart(rozkladprawdopodobienstw$C, main="Zmienna C - dieta")
bn.fit.barchart(rozkladprawdopodobienstw$D, main="Zmienna D - utrata wagi")
bn.fit.barchart(rozkladprawdopodobienstw$E, main="Zmienna E - wiek")
Ze struktury sieci możemy odczytać bezpośrednie i pośrednie związki pomiędzy węzłami. Jeżeli zmienne są zależne bezpośrednio, jest pomiędzy nimi łuk. Jeżeli zależność jest pośrednia, jest pomiędzy nimi kilka łuków przechodzących przez węzły, które „pośredniczą” w relacji. Graficzna niezależność implikuje niezależność probabilistyczną (tzn. jeżeli nie ma ścieżki „zablokowanej” pomiędzy węzłami to zmienne są (warunkowo) niezależne –czyli istotne są kierunki łuków). Implikacja w drugą stronę nie zawsze jest prawdziwa (tzn. nie każda warunkowa niezależność jest widoczna w grafie). Przeanalizujemy kilka relacji pomiędzy zmiennymi (analiza d-separacji).
dsep(siechc,x="A",y="B")
## [1] FALSE
Jeżeli istnieje bezpośredni łuk to zmienne są zależne.
dsep(siechc,x="A",y="E")
## [1] FALSE
dsep(siechc,x="A",y="E",z="B")
## [1] TRUE
Zmienne A i E są połączone łukiem, więc sa zależne. Trzeci argument jest warunkiem. Jeżeli sprawdzimy niezależność pomiędzy zmiennymi A i E pod warunkiem B, to okazuje się, że są niezależne.
dsep(siechc,x="B",y="D")
## [1] FALSE
dsep(siechc,x="B",y="D",z="A")
## [1] TRUE
Zmienne B i D są zależne, ale B i D są niezależne pod warunkiem A.
dsep(siechc,x="A",y="C")
## [1] TRUE
dsep(siechc,x="A",y="C",z="D")
## [1] FALSE
Zmienne A i C są niezależne (zwróćmy uwagę, że droga między nimi jest „zablokowana”). Jeżeli znamy wartość jaką przyjmuje zmienna D, ulega zmianie rozkład obu zmiennych A i C i w ten sposób zmienne stają się zależne.
library(gRain)
junction <-compile(as.grain(rozkladprawdopodobienstw))
querygrain(junction, nodes = "C")$C
## C
## a b c
## 0.7638 0.1916 0.0446
W ten sposób obliczyliśmy prawdopodobieństwo całkowite zmiennej losowej C. Możemy > z niej odczytać, że prawdopodobieństwo, że losowo wybrana osoba:
- korzysta z diety przygotowanej przez dietetyka wynosi 0.7638
- samodzielnie dba o zdrową dietę wynosi 0.1916
- nie odżywia się zdrowo 0.0446
Podkreślam, że nic więcej o tej losowej osobie nie wiemy.
querygrain(junction, nodes = c("A","B","C","D","E"), type="joint")
## , , D = a, C = a, E = a
##
## B
## A a b c
## a 0.101185102 0.0018030748 0.004358669
## b 0.006437882 0.0014117272 0.001531130
## c 0.001131382 0.0005279404 0.002866450
##
## , , D = b, C = a, E = a
##
## B
## A a b c
## a 0.013793392 0.0002457923 0.0005941668
## b 0.053258841 0.0116788341 0.0126666170
## c 0.001789431 0.0008350078 0.0045336712
##
## , , D = c, C = a, E = a
##
## B
## A a b c
## a 0.012081803 0.0002152925 0.0005204381
## b 0.007608406 0.0016684049 0.0018095167
## c 0.011994961 0.0055972460 0.0303902216
##
## , , D = a, C = b, E = a
##
## B
## A a b c
## a 0.005989595 0.0001067320 0.000258009
## b 0.014857532 0.0032580254 0.003533586
## c 0.001016385 0.0004742789 0.002575095
##
## , , D = b, C = b, E = a
##
## B
## A a b c
## a 0.0034226259 6.098971e-05 0.0001474337
## b 0.0006753424 1.480921e-04 0.0001606175
## c 0.0018428958 8.599562e-04 0.0046691284
##
## , , D = c, C = b, E = a
##
## B
## A a b c
## a 0.0224609825 0.0004002450 0.0009675336
## b 0.0013506847 0.0002961841 0.0003212350
## c 0.0008823562 0.0004117366 0.0022355221
##
## , , D = a, C = c, E = a
##
## B
## A a b c
## a 0.0033539467 5.976588e-05 0.0001444753
## b 0.0011528287 2.527974e-04 0.0002741787
## c 0.0001277416 5.960847e-05 0.0003236439
##
## , , D = b, C = c, E = a
##
## B
## A a b c
## a 0.0013212517 2.354413e-05 5.691449e-05
## b 0.0017292431 3.791961e-04 4.112680e-04
## c 0.0003019347 1.408928e-04 7.649766e-04
##
## , , D = c, C = c, E = a
##
## B
## A a b c
## a 0.0027441382 4.889936e-05 0.0001182070
## b 0.0010480261 2.298158e-04 0.0002492534
## c 0.0004412892 2.059202e-04 0.0011180427
##
## , , D = a, C = a, E = b
##
## B
## A a b c
## a 0.0502971201 0.0018030748 0.007526568
## b 0.0032001442 0.0014117272 0.002643961
## c 0.0005623878 0.0005279404 0.004949798
##
## , , D = b, C = a, E = b
##
## B
## A a b c
## a 0.0068564233 0.0002457923 0.001026010
## b 0.0264739202 0.0116788341 0.021872766
## c 0.0008894909 0.0008350078 0.007828762
##
## , , D = c, C = a, E = b
##
## B
## A a b c
## a 0.006005626 0.0002152925 0.0008986946
## b 0.003781989 0.0016684049 0.0031246809
## c 0.005962459 0.0055972460 0.0524779600
##
## , , D = a, C = b, E = b
##
## B
## A a b c
## a 0.0029773098 0.0001067320 0.0004455309
## b 0.0073853865 0.0032580254 0.0061018101
## c 0.0005052249 0.0004742789 0.0044466848
##
## , , D = b, C = b, E = b
##
## B
## A a b c
## a 0.0017013199 6.098971e-05 0.0002545891
## b 0.0003356994 1.480921e-04 0.0002773550
## c 0.0009160672 8.599562e-04 0.0080626703
##
## , , D = c, C = b, E = b
##
## B
## A a b c
## a 0.0111649117 0.0004002450 0.001670741
## b 0.0006713988 0.0002961841 0.000554710
## c 0.0004386019 0.0004117366 0.003860309
##
## , , D = a, C = c, E = b
##
## B
## A a b c
## a 1.667181e-03 5.976588e-05 0.0002494805
## b 5.730484e-04 2.527974e-04 0.0004734529
## c 6.349784e-05 5.960847e-05 0.0005588697
##
## , , D = b, C = c, E = b
##
## B
## A a b c
## a 0.0006567682 2.354413e-05 9.828018e-05
## b 0.0008595726 3.791961e-04 7.101794e-04
## c 0.0001500858 1.408928e-04 1.320965e-03
##
## , , D = c, C = c, E = b
##
## B
## A a b c
## a 0.0013640570 4.889936e-05 0.0002041204
## b 0.0005209531 2.298158e-04 0.0004304117
## c 0.0002193562 2.059202e-04 0.0019306407
##
## , , D = a, C = a, E = c
##
## B
## A a b c
## a 0.0163964180 0.0029630146 0.012323350
## b 0.0010432188 0.0023199084 0.004328992
## c 0.0001833335 0.0008675709 0.008104371
##
## , , D = b, C = a, E = c
##
## B
## A a b c
## a 0.0022351336 0.0004039134 0.001679899
## b 0.0086302647 0.0191919694 0.035812574
## c 0.0002899662 0.0013721785 0.012818137
##
## , , D = c, C = a, E = c
##
## B
## A a b c
## a 0.001957781 0.0003537928 0.001471445
## b 0.001232895 0.0027417099 0.005116082
## c 0.001943709 0.0091980221 0.085922869
##
## , , D = a, C = b, E = c
##
## B
## A a b c
## a 0.0009705768 0.0001753940 0.0007294738
## b 0.0024075709 0.0053539525 0.0099905756
## c 0.0001646989 0.0007793882 0.0072806168
##
## , , D = b, C = b, E = c
##
## B
## A a b c
## a 0.0005546153 0.0001002251 0.0004168422
## b 0.0001094350 0.0002433615 0.0004541171
## c 0.0002986298 0.0014131765 0.0132011183
##
## , , D = c, C = b, E = c
##
## B
## A a b c
## a 0.0036396629 0.0006577275 0.0027355267
## b 0.0002188701 0.0004867230 0.0009082341
## c 0.0001429803 0.0006766118 0.0063205354
##
## , , D = a, C = c, E = c
##
## B
## A a b c
## a 5.434862e-04 9.821399e-05 0.0004084777
## b 1.868087e-04 4.154250e-04 0.0007751908
## c 2.069974e-05 9.795532e-05 0.0009150448
##
## , , D = b, C = c, E = c
##
## B
## A a b c
## a 2.141006e-04 3.869036e-05 0.0001609155
## b 2.802131e-04 6.231375e-04 0.0011627862
## c 4.892665e-05 2.315308e-04 0.0021628332
##
## , , D = c, C = c, E = c
##
## B
## A a b c
## a 4.446706e-04 0.0000803569 0.0003342090
## b 1.698261e-04 0.0003776591 0.0007047189
## c 7.150818e-05 0.0003383911 0.0031610639
Przykładowo \(P(A = a, B = a, C = a, D = a, E = a) = 0.101185102\) (trzeba odnaleźć odpowiednią tabelkę). Oznacza to, że prawdopodobieństwo, że losowo wybrana osoba:
- ćwiczy regularnie,
- jest aktywnym członkiem klubu sportowego,
- korzysta z diety przygotowanej przez dietetyka,
- utraciła powyżej 5 kg wagi,
- ma co najwyżej 20 lat,
wynosi 10.12%. W prostych słowach, co 10-ta osoba z grupy badanych spełnia te warunki.
warunek <- setEvidence(junction,nodes=c("C"),states=c("a"))
querygrain(warunek, nodes = "B")$B
## B
## a b c
## 0.4546 0.1144 0.4310
Otrzymany wynik interpretuję następująco:
- w 45.46% jestem aktywnym członkiem klubu,
- w 11.44% jestem biernym członkiem klubu,
- w 43.10% nie należę do klubu.
warunek1 <- setEvidence(junction,nodes=c("A","B","C"), states=c("b","b","b"))
querygrain(warunek1, nodes = "D")$D
## D
## a b c
## 0.88 0.04 0.08
Zatem prawdopodobieństwo, że osoba spełniające powyższe warunki nie utraciła wagi wynosi 8%.
cwiczy <- setEvidence(junction,nodes=c("A"), states=c("a"))
I wśród tych osób rozważam różne rodzaje prawdopodobieństw:
querygrain(cwiczy, nodes = c("C","D"),type="joint")
## C
## D a b c
## a 0.60825594 0.03600537 0.020161644
## b 0.08291648 0.02057450 0.007942466
## c 0.07262758 0.13502013 0.016495890
querygrain(cwiczy, nodes = c("C","D"),type="marginal")
## $D
## D
## a b c
## 0.6644230 0.1114334 0.2241436
##
## $C
## C
## a b c
## 0.7638 0.1916 0.0446
querygrain(cwiczy, nodes = c("C","D"),type="conditional")
## D
## C a b c
## a 0.91546497 0.74408973 0.32402253
## b 0.05419044 0.18463484 0.60238229
## c 0.03034459 0.07127542 0.07359519