Dokonując wyboru idealnego wina do obiadu lub próbując znaleźć idealny trunek dla przyjaciela nie zastanawiamy się zwykle, co wpływa na naszą decyzję. Czy dobre wino powinno być mocne? A może przekonała nas jego głęboka barwa? Jaki czynnik sprawił, że postanowiliśmy kupić kolejną butelkę tego samego trunku? Konsumenci zwykle nie zadają sobie takich pytań. Z drugiej strony jednak, odpowiedź na nie jest kluczowa dla producentów.
Jak więc odnaleźć przepis na doskonale sprzedający się produkt? Mając do dyspozycji dane o cechach chemicznych setek gatunków wina, informację o ocenie przyznanej przez krytyków oraz darmowy program typu open source możemy w łatwy sposób wskazać przybliżony wzór na trunek idealny. Z pomocą przyjdzie nam uczenie maszynowe.
Wykorzystana przeze mnie baza danych pochodzi ze strony UCI. Machine Learning Repository.1 Znajduje się w niej zbiór o nazwie Red Wine Quality Data Set. Zawiera on 1599 gatunków czerwonego portugalskiego wina opisywanych przez dwanaście zmiennych. Jest to ogólnodostępna baza, zawierająca cechy fizyczne i chemiczne danego trunku oraz wartość oceny eksperckiej. Zbiór nie zawiera informacji wrażliwych dla sprzedaży i marketingu – nie podano producentów, gatunku wykorzystanych gron ani cen sprzedaży. Jednak zawarte w nim informacje są wystarczające do wyznaczenia cech charakterystycznych dla win ocenionych jako lepsze lub gorsze.
W zbiorze danych zawarto następujące zmienne:
1 - fixed acidity - kwasowość pierwotna wina (stężenie kwasu winowego w gramach na litr)
2 - volatile acidity - kwasowość powstała podczas procesu dojrzewania (stężenie kwasu octowego w gramach na litr)
3 - citric acid - stężenie kwasu cytrynowego (gramy na litr)
4 - residual sugar - zawartość cukru pozostała po procesie fermentacji (gramy/litr)
5 - chlorides – zawartość chlorku sodu (gramy/litr)2
6 - free sulfur dioxide - zawartość wolnego dwutlenku siarki (miligramy/litr)
7 - total sulfur dioxide - całkowita zawartość dwutlenku siarki (miligramy/litr)
8 - density – gęstość wina (gramy/centymetr sześcienny)
9 - pH – odczyn wina wyrażony przez poziom pH (powyżej 7 – zasadowość, poniżej 7 – kwasowość)
10 - sulphates - zawartość siarczanu potasu (gramy/litr)
11 - alcohol - procentowa zawartość alkoholu
12 - quality - wynik oceny eksperckiej wina (w skali 0-10)
dane<-read.csv("winequality-red.csv", sep=";", dec=".", header=TRUE)
#podstawowe statystyki zmiennych w zbiorze
dane.stats <- data.frame(
Min = apply(dane, 2, min), # minimum
Q1 = apply(dane, 2, quantile, 1/4), # pierwszy kwartyl
Med = apply(dane, 2, median), # mediana
Mean = apply(dane, 2, mean), # średnia
Q3 = apply(dane, 2, quantile, 3/4), # trzeci kwartyl
Max = apply(dane, 2, max) # maksimum
)
dane.stats <- round(dane.stats, 1)
dane.stats
## Min Q1 Med Mean Q3 Max
## fixed.acidity 4.6 7.1 7.9 8.3 9.2 15.9
## volatile.acidity 0.1 0.4 0.5 0.5 0.6 1.6
## citric.acid 0.0 0.1 0.3 0.3 0.4 1.0
## residual.sugar 0.9 1.9 2.2 2.5 2.6 15.5
## chlorides 0.0 0.1 0.1 0.1 0.1 0.6
## free.sulfur.dioxide 1.0 7.0 14.0 15.9 21.0 72.0
## total.sulfur.dioxide 6.0 22.0 38.0 46.5 62.0 289.0
## density 1.0 1.0 1.0 1.0 1.0 1.0
## pH 2.7 3.2 3.3 3.3 3.4 4.0
## sulphates 0.3 0.6 0.6 0.7 0.7 2.0
## alcohol 8.4 9.5 10.2 10.4 11.1 14.9
## quality 3.0 5.0 6.0 5.6 6.0 8.0
Powyższy zbiór danych jest bardzo często wykorzystywany do przedstawiania zastosowań i zalet uczenia maszynowego. Dotychczasowe analizy zwykle polegają na dokonaniu regresji na zebranych danych i próbach prognozowania ludzkiej oceny wina o danych właściwościach. Czasami przeprowadzona jest nienadzorowana klasyfikacja gatunków win w mniejsze podgrupy, a następnie analizowane są statystyki opisowe uzyskanych skupień.3
W tej pracy chciałabym jednak podejść do tematu nieco inaczej. Przeprowadzę zatem analizę głównych składowych. Dzięki temu przekonam się, które konkretnie charakterystyki decydują o późniejszej ocenie wina. Nie poprzestanę jednak na standardowym PCA. Dla uzyskania lepszych rezultatów wykorzystam procedurę MFA oraz jej rozszerzenie – Dual MFA. Analiza zostanie wykonana za pomocą języka R. Wszystkie wykorzystane komendy będą pochodziły z pakietu FactoMineR.4
PCA – Principal Component Analysis
Analiza głównych składowych jest metodą umożliwiającą zredukowanie wymiarowości zbioru danych. Dokonuje się to poprzez utworzenie syntetycznych zmiennych, składających się z kombinacji oryginalnych charakterystyk zestawu danych. Przyglądając się zawartościom uzyskanych składowych, wprawny badacz może nadać im uogólniające etykiety. Dzięki temu uzyskuje się bardziej przejrzystą i przyjazną w analizie strukturę danych. Główne składowe tworzone są w taki sposób, aby pierwsza tłumaczyła możliwie największą część wariancji, a każda kolejna miała malejący udział w pozostałej jej części. PCA jest szczególnie przydatne podczas analizowania wielowymiarowych danych, dla których mnogość zmiennych uniemożliwia przedstawienie ich na przejrzystym wykresie i przez to ogranicza możliwość ich analizy przez niewprawnego badacza.
Metodę tę zastosuję na początku analizy dla całego zbioru danych.
MFA – Multiple Factor Analysis
Ta metoda rozszerza tradycyjne PCA. Zmienne dzielone są a priori na mniejsze podgrupy. Następnie, w ramach algorytmu, przeprowadzana jest procedura PCA, gdzie do każdej klasy zmiennych przypisywane są wagi. Dzięki temu podobne charakterystyki mogą być traktowane jako jedna, syntetyczna zmienna. Ten algorytm może być pomocny podczas sprawdzania, czy zmienne opisujące podobne charakterystyki zbioru w ten sam sposób wpływają na wartości danych. Może też służyć jako uzupełnienie wcześniejszej analizy z wykorzystaniem PCA – jako poprawa wizualnej prezentacji wyników.
Ta metoda jest stosowana dla jednego zbioru danych oraz kilku typów zmiennych. Podzielę więc zbiór zmiennych na te, zajmujące się kwasowością (fixed acidity, volatile acidity, citric acid oraz pH), typowymi cechami wina widocznymi już przy zakupie (widoczne na pierwszy rzut oka lub opisane na etykiecie, takie jak: residual sugar, density oraz alcohol) oraz mniej oczywistymi właściwościami chemicznymi (chlorides, free sulfur dioxide, total sulfur dioxide oraz sulphates). Dodatkową kategorię utworzę z pojedynczej zmiennej quality.
Dual MFA – Dual Multiple Factor Analysis
Jest to metoda będąca rozszerzeniem MFA. Może być stosowana, gdy zbiór danych jest podzielony na podgrupy (np. podczas wcześniejszej analizy statystycznej i klasyfikacji obserwacji). W tym algorytmie sprawdzane jest znaczenie poszczególnych zmiennych dla konkretnego podzbioru danych. Jeśli dany poziom zmiennej jest wyższy niż wynikający z rozkładu normalnego – jest ona uznawana za interesującą. Następnie zmienne są sortowane od najbardziej do najmniej istotnej dla konkretnej podgrupy. Ogólnie, metoda ta bada stopień odchylenia rozkładu danej zmiennej dla konkretnej populacji od rozkładu normalnego i porównuje te wyniki z rezultatami analizy składowych dla tych podzbiorów.
W tej metodzie wykorzystam manualny podział zbioru danych na cztery podgrupy (ze względu na ocenę ekspercką) a następnie sprawdzę, które czynniki są bardziej istotne dla każdej z nich.
Na początku podzielę zbiór danych na cztery mniejsze podgrupy, ze względu na przydzieloną im ocenę.
#Analiza graficzna zmiennej jakość
par(mfrow=c(1,2))
hist(dane$quality, main="Wykres częstości", col=cols[1])
boxplot(dane$quality, main="Wykres pudełkowy", col=cols[2])
Jak widać na wykresach – większość win (między pierwszym a trzecim kwantylem) otrzymała wynik w granicach 5-6. Najniżej ocenione wino posiada ocenę 3, a najwyżej – ocenę 8. W zbiorze danych znajduje się więc wiele win przeciętnych. Oprócz tego odnajdziemy tam kilka gorszych trunków, oraz trochę więcej tych lepszych.
Dzięki prostej analizie wizualnej mogę podzielić zbiór na segmenty. Pierwszy będzie zawierał wina ocenione słabiej (ocena 3-4). W drugim znajdą się wina średnio gorsze (ocena 5). Kolejny będzie się składał z trunków średnio lepszych (ocena 6). Ostatnią grupą będą wina najlepsze (ocenione na 7 lub 8).
#tworzenie podzbiorów
najgorsze<-dane[dane$quality<5,] #63 obserwacje
gorsze<-dane[dane$quality==5,] #681 obserwacji
lepsze<-dane[dane$quality==6,] #638 obserwacji
najlepsze<-dane[dane$quality>6,] #217 obserwacji
Dodam również zmienną kategoria kodującą przypisanie danego wina do określonego podzbioru pod względem jakości.
dane$kategoria<-"najgorsze"
dane[dane$quality==5,]$kategoria<-"gorsze"
dane[dane$quality==6,]$kategoria<-"lepsze"
dane[dane$quality>6,]$kategoria<-"najlepsze"
dane$kategoria<-as.factor(dane$kategoria)
Przeprowadzając podstawową analizę głównych składowych Chcę zredukować liczbę wymiarów w zbiorze do pięciu. Nie będę wprowadzać dodatkowych ograniczeń. Wykorzystam do tego podstawową komendę PCA, wskazując jedynie zestaw zmiennych oraz liczbę wynikowych składowych.
library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 3.5.2
par(mfrow=c(1,2)) #parametryzacja pola wykresu
pca <- PCA(dane[,1:12], scale.unit=TRUE, ncp=5, graph=T) #graph=TRUE automatycznie generuje wykresy przypisane do komendy
Jak widać, wykres indywidualnych obserwacji jest zupełnie nieczytelny. Jest to spowodowane dużą rozpiętością zbioru. Odrobinę łatwiejszy do analizy jest wykres dla zmiennych.5 Poprawę przejrzystości można uzyskać poprzez zastosowanie komendy fviz_pca_var z pakietu FactoExtra z dodaniem opcji col.var=”contrib”. Dzięki temu zmienne zostaną pocieniowane ze względu na wielkość ich udziału w pierwszych dwóch składowych.
library(factoextra)
## Loading required package: ggplot2
## Welcome! Related Books: `Practical Guide To Cluster Analysis in R` at https://goo.gl/13EFCZ
#rysuję wykres z gradientem, bazującym na udziałach zmiennych
fviz_pca_var(pca, col.var="contrib")+
scale_color_gradient2(low="yellow", mid="red",
high="black", midpoint=10)+theme_bw()
Z wykresu wynika, że najbardziej istotne w pierwszych dwóch wymiarach są zmienne fixed.acidity oraz citric.acid. Dużym udziałem, choć z odwrotnym znakiem, wykazuje się zmienna pH.6 Kolejne istotne zmienne to gęstość oraz zawartość alkoholu. Istotna jest również jakość. Zmienne związane z zawartością siarczanów i chlorków nie są istotne dla pierwszych dwóch składowych.
pca$eig #tabela wartości własnych kolejnych głównych składowych wraz ze wskazaniem tłumaczonej przez nie wariancji
## eigenvalue percentage of variance
## comp 1 3.12116770 26.0097308
## comp 2 2.24188204 18.6823504
## comp 3 1.68291969 14.0243308
## comp 4 1.21502087 10.1251739
## comp 5 0.97326362 8.1105302
## comp 6 0.66259224 5.5216020
## comp 7 0.61831780 5.1526483
## comp 8 0.50587256 4.2156046
## comp 9 0.41130754 3.4275628
## comp 10 0.32791939 2.7326616
## comp 11 0.18021863 1.5018219
## comp 12 0.05951792 0.4959826
## cumulative percentage of variance
## comp 1 26.00973
## comp 2 44.69208
## comp 3 58.71641
## comp 4 68.84159
## comp 5 76.95212
## comp 6 82.47372
## comp 7 87.62637
## comp 8 91.84197
## comp 9 95.26953
## comp 10 98.00220
## comp 11 99.50402
## comp 12 100.00000
Wydruk wartości własnych dla tej analizy pokazuje również, że potrzeba aż dwunastu składowych, by dobrze odwzorować zależności występujące w zbiorze. Pięć kombinacji nie tłumaczy całości wariacji zjawiska. Dodatkowo, warto zauważyć, że dany gatunek wina opisuje pierwsze jedenaście zmiennych. Ostatnia, dwunasta, to zmienna wynikowa – nie koduje cech fizyczno-chemicznych wina, lecz przestawia wynik oceny eksperckiej. W związku z tym, warto wyodrębnić ją podczas analizy.
Ponownie użyję komendy PCA, tym razem jednak wskażę quality jako zmienną dodatkową, by lepiej pokazać zależności między charakterystykami fizyczno-chemicznymi.
par(mfrow=c(1,1))
pca2 <- PCA(dane[,1:11], scale.unit=T, ncp=5, quanti.sup=dane$quality, graph=F) #quanti.sup wskazuje zmienną dodatkową
pca2$eig
## eigenvalue percentage of variance cumulative percentage of variance
## comp 1 1.9600672 39.201343 39.20134
## comp 2 1.2786697 25.573394 64.77474
## comp 3 0.8078586 16.157172 80.93191
## comp 4 0.6536451 13.072903 94.00481
## comp 5 0.2997594 5.995189 100.00000
Dzięki zastosowanej poprawce pięć wymiarów wystarcza do wyjaśnienia całości wariancji zjawiska. Ponadto, pierwsze dwa tłumaczą ponad 64% wariancji. Oznacza to, że na analizowanym wykresie odwzorowana jest większość zależności między cechami fizyczno-chemicznymi wina.
plot(pca2,choix="var")
Powyższy wykres znacząco różni się od poprzedniego. Brak uwzględnienia zmiennej quality zmienia analizę. Widać, że tym razem zmienne sulphates i volatile.acidity mają duży wpływ, ale w odmienych kierunkach. Zmienna alcohol nadal ma dużą wagę, jednak pozostaje mało skorelowana z pozostałymi charakterystykami. Nie jest jednak jasne, w jaki sposób dane charakterystyki wpływają na wysokość oceny ekspertów.
Tu z pomocą przyjdzie nam komenda condes. Jest to funkcja, wbudowana w pakiet FactoMineR, która pozwala opisać jedną zmienną ciągłą przez inne.
opis.quality<- condes(dane, num.var=12, proba=0.05) #zmienne opisujące zmienną quality na poziomie ufności 5%
opis.quality
## $quanti
## correlation p.value
## alcohol 0.47616632 2.831477e-91
## sulphates 0.25139708 1.802088e-24
## citric.acid 0.22637251 4.991295e-20
## fixed.acidity 0.12405165 6.495635e-07
## free.sulfur.dioxide -0.05065606 4.283398e-02
## pH -0.05773139 2.096278e-02
## chlorides -0.12890656 2.313383e-07
## density -0.17491923 1.874957e-12
## total.sulfur.dioxide -0.18510029 8.621703e-14
## volatile.acidity -0.39055778 2.051715e-59
##
## $quali
## R2 p.value
## kategoria 0.9760886 0
##
## $category
## Estimate p.value
## najlepsze 1.6018945 1.061239e-245
## lepsze 0.5189452 2.901644e-52
## najgorsze -1.6397849 1.222652e-80
## gorsze -0.4810548 3.236161e-216
Na wydruku widać, że największy wpływ na ocenę jurorów miały zmienne alcohol, volatile.acidity, sulphates oraz citric.acid. Oznacza to, że mocniejsze wina dostawały zwykle wyższe oceny. Podobnie, lepiej oceniano trunki o wyższej zawartości kwasu cytrynowego oraz związków siarki – obie te charakterystyki powodują, że wino jest świeższe w smaku. Negatywnie na ocenę wpływała zmienna volatile acidity. Jest ona wyznacznikiem kwasowości ‘niezamierzonej’ - powstałej jako skutek uboczny procesu fermentacji i dojrzewania wina, zwykle powodowanej przez bakterie.
Dzięki tej analizie można stwierdzić, że najlepsze wina powinny być mocne, świeże w smaku, ale dojrzewające w kontrolowany sposób – bez dostępu bakterii i zachodzenia dodatkowych procesów fermentacyjnych.
Aby wykorzystać algorytm MFA, muszę na początku przesortować zbiór danych. Zmienne, które mają tworzyć grupy, muszą znajdować się obok siebie.
#przesortowanie kolumn w pierwotnym zbiorze danych
dane2<-dane[,c(1,2,3,9,4,8,11,5,6,7,10,12)]
names(dane2)
## [1] "fixed.acidity" "volatile.acidity" "citric.acid"
## [4] "pH" "residual.sugar" "density"
## [7] "alcohol" "chlorides" "free.sulfur.dioxide"
## [10] "total.sulfur.dioxide" "sulphates" "quality"
Następnie mogę przeprowadzić MFA. Definiuję grupy zmiennych (pierwszą grupę tworzą 4 zmienne, następną trzy…). Ustalam dodatkową grupę, nie braną pod uwagę podczas analizy (zmienna quality w grupie czwartej, nazwanej: ocena). Ponownie chcę uzyskać pięć wymiarów (ncp=5). W parametrze type narzucam sposób normalizowania danych w grupach – „s” oznacza standaryzację, „c” oznacza centralizację. Ten pierwszy typ przyda się do zwykłych zmiennych ciągłych, ten drugi lepiej sprawdzi się do zmiennej quality.
mfa<- MFA(dane2, group=c(4,3,4,1), type=c("s", "s", "s", "c"), ncp=5, name.group=c("kwasowość","przed zakupem","chemiczne","ocena"), num.group.sup=c(4), graph=F)
plot.MFA(mfa, choix="var")
Dzięki nadaniu ograniczeń na zmienne uzyskujemy przejrzysty wykres z kolorystycznym kodowaniem grup. Widać, że zwykle zmienne w podgrupach działają w sposób przeciwstawny (np. residual.sugar i alcohol citric.acid oraz volatile.acidity). Nie więc ma jednoznacznego kierunku oddziaływania w grupie. Może to sugerować niefortunny dobór zmiennych w kategorie (niezgodny z prawidłowym kierunkiem wpływu poszczególnych charakterystyk na jakość wina).
Na wykresie można dostrzec potwierdzenie wcześniejszej obserwacji – na zmienną quality silnie oddziałowują zmienne alcohol, sulphates oraz citric.acid (znajdują się najbliżej niej).
summary(mfa, nbind=0)
##
## Call:
## MFA(base = dane2, group = c(4, 3, 4, 1), type = c("s", "s", "s",
## "c"), ncp = 5, name.group = c("kwasowość", "przed zakupem",
## "chemiczne", "ocena"), num.group.sup = c(4), graph = F)
##
##
## Eigenvalues
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6
## Variance 1.488 1.104 0.857 0.712 0.552 0.352
## % of var. 25.413 18.856 14.642 12.162 9.430 6.016
## Cumulative % of var. 25.413 44.269 58.911 71.073 80.503 86.519
## Dim.7 Dim.8 Dim.9 Dim.10 Dim.11
## Variance 0.277 0.218 0.183 0.083 0.028
## % of var. 4.731 3.724 3.118 1.423 0.485
## Cumulative % of var. 91.250 94.974 98.092 99.515 100.000
##
## Groups
## Dim.1 ctr cos2 Dim.2 ctr cos2
## kwasowość | 0.631 42.426 0.345 | 0.152 13.736 0.020 |
## przed zakupem | 0.593 39.834 0.237 | 0.151 13.708 0.015 |
## chemiczne | 0.264 17.740 0.038 | 0.801 72.556 0.352 |
## Dim.3 ctr cos2
## kwasowość 0.176 20.496 0.027 |
## przed zakupem 0.408 47.630 0.113 |
## chemiczne 0.273 31.874 0.041 |
##
## Supplementary group
## Dim.1 cos2 Dim.2 cos2 Dim.3 cos2
## ocena | 0.001 0.000 | 0.104 0.011 | 0.221 0.049 |
##
## Continuous variables (the 10 first)
## Dim.1 ctr cos2 Dim.2 ctr cos2
## fixed.acidity | 0.764 15.640 0.584 | -0.359 4.642 0.129 |
## volatile.acidity | -0.250 1.681 0.063 | 0.329 3.905 0.108 |
## citric.acid | 0.679 12.360 0.461 | -0.326 3.837 0.106 |
## pH | -0.690 12.745 0.476 | 0.193 1.352 0.037 |
## residual.sugar | 0.366 5.674 0.134 | 0.321 5.860 0.103 |
## density | 0.812 27.846 0.659 | 0.067 0.256 0.004 |
## alcohol | -0.387 6.314 0.149 | -0.365 7.592 0.133 |
## chlorides | 0.469 8.785 0.220 | 0.018 0.017 0.000 |
## free.sulfur.dioxide | 0.063 0.158 0.004 | 0.801 34.527 0.642 |
## total.sulfur.dioxide | 0.188 1.408 0.035 | 0.826 36.668 0.682 |
## Dim.3 ctr cos2
## fixed.acidity -0.017 0.014 0.000 |
## volatile.acidity -0.538 13.485 0.290 |
## citric.acid 0.386 6.944 0.149 |
## pH -0.034 0.054 0.001 |
## residual.sugar 0.143 1.496 0.020 |
## density -0.377 10.416 0.142 |
## alcohol 0.698 35.718 0.487 |
## chlorides -0.008 0.004 0.000 |
## free.sulfur.dioxide 0.391 10.583 0.153 |
## total.sulfur.dioxide 0.262 4.739 0.068 |
##
## Supplementary continuous variable
## Dim.1 cos2 Dim.2 cos2 Dim.3 cos2
## quality | -0.023 0.001 | -0.261 0.104 | 0.380 0.221 |
Niestety poprzez dodanie sztucznych grup, tracimy moc analizy – pierwsze dwie składowe tłumaczą zaledwie 44% wariancji (cumulative % of var. dla Dim. 2). W tej konfiguracji potrzeba aż jedenastu składowych, by wyjaśnić całość zjawiska (czyli dokładnie tyle, ile mamy zmiennych).
W pierwszej składowej największy udział mają grupy kwasowość oraz przed zakupem. Druga składa się w większości z elementu chemiczne.
plot.MFA(mfa, choix="group")
Podobieństwo czerwonej i zielonej kategorii widać również na powyższym wykresie. Ich udział w drugim wymiarze jest zbliżony do udziału zmiennej ocena. Można to interpretować w ten sposób: kwasowość wina oraz zmienne uchwycone w grupie przed zakupem w większym stopniu wpływają na ocenę wina przez próbujących. Są one bardziej istotne dla trunku i łatwiejsze do wychwycenia niż zmienne chemiczne. Jest to jednak dość ryzykowna ocena – poprzednie analizy wykazywały raczej większy wpływ pojedynczych zmiennych na jakość trunku niż ich agregatów (por. przeciwstawny wpływ zmiennych volatile.acidity oraz citric.acid).
W związku z powyższym, ponownie dokonam analizy MFA. Jednak tym razem nie będę wykorzystywać grup utworzonych a priopri w sposób nadzorowany, ale skorzystam z wyników komendy condes.
opis.quality #przypomnienie: wpływ pojednczych zmiennych na zmienną quality
## $quanti
## correlation p.value
## alcohol 0.47616632 2.831477e-91
## sulphates 0.25139708 1.802088e-24
## citric.acid 0.22637251 4.991295e-20
## fixed.acidity 0.12405165 6.495635e-07
## free.sulfur.dioxide -0.05065606 4.283398e-02
## pH -0.05773139 2.096278e-02
## chlorides -0.12890656 2.313383e-07
## density -0.17491923 1.874957e-12
## total.sulfur.dioxide -0.18510029 8.621703e-14
## volatile.acidity -0.39055778 2.051715e-59
##
## $quali
## R2 p.value
## kategoria 0.9760886 0
##
## $category
## Estimate p.value
## najlepsze 1.6018945 1.061239e-245
## lepsze 0.5189452 2.901644e-52
## najgorsze -1.6397849 1.222652e-80
## gorsze -0.4810548 3.236161e-216
Ponownie posortuję zbiór danych, aby odwzorować nowe zależności. Utworzę grupy zmiennych o dużej dodatniej korelacji (w tym przypadku jako dużą korelację rozumiem tę powyżej 0.18).
dane3<-dane[,c(11,10, 3, 2, 7, 1, 4,5,6,8,9,12)]
names(dane3)
## [1] "alcohol" "sulphates" "citric.acid"
## [4] "volatile.acidity" "total.sulfur.dioxide" "fixed.acidity"
## [7] "residual.sugar" "chlorides" "free.sulfur.dioxide"
## [10] "density" "pH" "quality"
mfa2<- MFA(dane3, group=c(3,2,6 ,1), type=c("s", "s", "s", "c"), ncp=5, name.group=c("duży dodatni wpływ","duży ujemny wpływ","prawie obojętne","ocena"), num.group.sup=c(4), graph=F)
plot.MFA(mfa2, choix="var")
Tym razem grupy kolorystyczne są bardziej skoncentrowane (zmienne mają podobny kierunek oddziaływania w grupach), a pierwsze dwa wymiary tłumaczą prawie połowę wariancji (27.12% + 20.10%).
plot.MFA(mfa2, choix="group")
Wykres prezentujący grupy również się zmienił. Kategorie czerwona i zielona są od siebie oddalone (działanie zmiennych tam zawartych jest przeciwstawne). Grupa niebieska znalazła się pomiędzy dwiema pozostałymi (jako kombinacja elementów o różnych kierunkach oddziaływania).
Okazuje się więc, że MFA wykazuje lepsze rezultaty dla wyników poprzedniej analizy PCA niż dla sztucznie utworzonych podgrup. Jednak nadal trudno jest uzyskać tak dobrze skomponowane składowe, jak w przypadku drugiego PCA – z wykorzystaniem pojedynczych zmiennych, bez uwzględniania quality (dla przypomnienia: pierwsze dwa wymiary tłumaczyły wtedy prawie 65% wariancji).
Przed wykonaniem analizy za pomocą bardziej zaawansowanego algorytmu, przedstawię wyniki PCA z poprzedniej części pracy. Tym razem z wykorzystam podział obserwacji według zmiennej kategoria. Sprawdzę dzięki temu, czy między kategoriami występują łatwo widoczne różnice.
par(mfrow=c(1,2))
fviz_pca_ind(pca, habillage=dane$kategoria, label="none", title="PCA z uwzględnieniem zmiennej quality")
fviz_pca_ind(pca2, habillage=dane$kategoria, label="none", title="PCA bez wpływu zmiennej quality")
Widać wyraźnie, że usunięcie zmiennej quality zaburza wykres. Jednak dzięki temu lepiej widać rzeczywiste zależności między gatunkami wina. Trunki najlepsze układają się głównie w drugiej ćwiartce układu współrzędnych. W ich pobliżu występuje chmura punktów, oznaczających wina lepsze. Obserwacje najgorsze znajdują się w czwartej ćwiartce układu. W ich najbliższym utoczeniu widać wiele win gorszych. Chmury punktów gorszych i lepszych są nieco ze sobą wymieszane. Jednak kategorie skrajne są od siebie wyraźnie oddzielone.
Do przeprowadzenia DMFA muszę ponownie przetworzyć zbiór danych tak, aby zmienna przypisująca do podgrup miała numeryczny charakter. Dzięki temu będę w stanie pokonać ograniczenia programistyczne funkcji DMFA.
dane4<-dane[,c(1,2,3,4,5,6,7,8,9,10,11,12)]
dane4$hier<-"1"
dane4[dane$quality==5,]$hier<-"2"
dane4[dane$quality==6,]$hier<-"3"
dane4[dane$quality>6,]$hier<-"4"
Jako zmienną dzielącą obserwacje na podgrupy przyjmuję hier (numeryczny odpowiednik zmiennej kategoria). Standardowo ustawiam quality jako zmienną dodatkową. Po zastosowaniu algorytmu otrzymuję następujące rezultaty.7
#DMFA(dane4, num.fact = c(13), scale.unit = TRUE, ncp = 5, quanti.sup = c(12), graph = TRUE, axes=c(1,2))
Kodowane kolorystycznie strzałki na wykresie korelacji pokazują wyniki PCA dla podgrup oryginalnego zbioru. Jak widać, nie ma między nimi zbyt wielkich różnic.
Można więc powiedzieć, że dla każdego gatunku wina te same cechy, w ten sam sposób, determinują jego późniejszą ocenę. Wszystkie trunki oceniane są pod wpływem tych samych kryteriów. Jedynie ich indywidualna kombinacja wpływa na wysokość zmiennej quality.
Jak pokazały wcześniejsze analizy, na ocenę wina najmocniej wpływają zmienne alcohol, sulphates, citric.acid oraz volatile.acidity.
Tak przedstawia się porównanie tych cech w grupie win najlepszych w stosunku do wszystkich.
#statystyki opisowe dla zmiennych najbardziej wpływających na ocenę wina
dane.stats2
## Min Q1 Med Mean Q3 Max
## alcohol 8.4 9.5 10.2 10.4 11.1 14.9
## sulphates 0.3 0.6 0.6 0.7 0.7 2.0
## citric.acid 0.0 0.1 0.3 0.3 0.4 1.0
## volatile.acidity 0.1 0.4 0.5 0.5 0.6 1.6
najlepsze.stats
## Min Q1 Med Mean Q3 Max
## alcohol 9.2 10.8 11.6 11.5 12.2 14.0
## sulphates 0.4 0.6 0.7 0.7 0.8 1.4
## citric.acid 0.0 0.3 0.4 0.4 0.5 0.8
## volatile.acidity 0.1 0.3 0.4 0.4 0.5 0.9
Wynik tego porównania jest zgodny z poprzednimi rezultatami. Wina najlepsze mają wyższą zawartość alkoholu oraz związków siarki. Mają również średnio niższą zawartość kwasowości „niezamierzonej”.
Zaskakują jednak wyniki dla stężenia kwasu cytrynowego – jak wynikało z analizy korelacji zmiennych pojedynczych ze zmienną quality - wartość citric.acid powinna wzrastać wraz ze wzrostem oceny krytyków. Tu jednak widać, że wina najlepsze charakteryzują się nieco niższą zawartością tego kwasu w porównaniu do całego zbioru.
Analiza głównych składowych oraz badanie korelacji dla cech chemiczno-fizycznych portugalskich win pokazały, że na ocenę trunku najmocniej wpływa zawartość alkoholu, odpowiednio przeprowadzone starzenie (bez wzrastania kwasowości) oraz „świeżość”, odczuwana przez próbującego.
Najlepsze i najłatwiejsze w interpretacji wyniki pochodziły z przeprowadzenia podstawowego algorytmu PCA. Dodanie pojedynczego ograniczenia (na zmienną quality) sprawiło, że analiza stała się pełniejsza i bardziej wiarygodna.
Zastosowanie bardziej zaawansowanych metod analizy (MFA oraz DMFA) nie zmieniło konkluzji uzyskanych wcześniej. Niektóre aspekty zostały doprecyzowane lub potwierdzone, jednak poprawny odczyt wyników pochodzących z tych algorytmów był trudniejszy i mniej oczywisty.
Pakiet FactoMineR został rozwinięty w 2008 roku i nadal pozostaje jednym z najlepszych narzędzi do przeprowadzania redukcji wymiarów danych. Oferuje wiele bardziej zaawansowanych metod, oprócz zwykłego PCA, mimo że do niektórych nadal brakuje odpowiedniej literatury. Badania przeprowadzone przy jego pomocy dowodzą, że z powodzeniem można przeprowadzać procesy uczenia maszynowego w programie typu open source.
Oprócz wniosków dotyczących charakterystyk „idealnego wina”, dochodzimy więc do ogólnych konkluzji związanych z przeprowadzaniem analizy danych. Często prostsze metody, pomimo swoich ograniczeń, prowadzą do uzyskania lepszych rezultatów.
W uczeniu maszynowym zaś ważniejszy jest nie sam dobór metody, ale wyciągnięte z analizy wnioski. A te, bardzo często, są łatwiejsze do uzyskania przy pomocy mniej skomplikowanych algorytmów.
Lichman, Moshe, et al. UCI machine learning repository. 2013.↩
Zawartość chlorków w winie jest cechą charakterystyczną dla różnych odmian winogron i miejsca ich dojrzewania (Coli, Marina Sonegheti, et al. Chloride concentration in red wines: influence of terroir and grape type. Food Science and Technology, 2015, 35.1: 95-99.)↩
Cortez, Paulo, et al. Modeling wine preferences by data mining from physicochemical properties. Decision Support Systems, 2009, 47.4: 547-553. Cortez, Paulo, et al. Using data mining for wine quality assessment. In: International Conference on Discovery Science. Springer, Berlin, Heidelberg, 2009. p. 66-79. Panzone, Luca A.; SIMÕES, Orlando M. The importance of regional and local origin in the choice of wine: Hedonic models of Portuguese wines in Portugal. Journal of Wine Research, 2009, 20.1: 27-44.↩
Lé, Sébastien, et al. FactoMineR: an R package for multivariate analysis. Journal of statistical software, 2008, 25.1: 1-18.↩
Wykresy wyników PCA rysowane są zwykle dla pierwszych dwóch wymiarów - tłumaczą one sumarycznie największą część wariancji i mogą być przedstawione za pomocą przyjaznej w odbiorze grafiki 2D.↩
Jest to zgodne z logiką, gdyż im wyższa kwasowość trunku, tym niższe jego pH.↩
Niestety, programiści pakietu FactoMineR poskąpili informacji na temat działania funkcji DMFA. W publikacji opisującej pakiet tylko pokrótce wyjaśniono schemat działania algorytmu, a na dedykowanej stronie pakietu, opisującej działanie zawartych w nim komend. nie widać opisu działania tej metody. Opis dostępny w pomocy również jest niewystarczający. (http://factominer.free.fr/factomethods/dual-multiple-factor-analysis.html …under construction…) Odnoszę wrażenie, że ta funkcja w pakiecie do tej pory nie została do końca oprogramowana. Źródła internetowe również milczą na temat przykładów jej użycia. Identyczna sytuacja zachodzi dla metody Hierarchical Multiple Factor Analysis (HMFA), którą pierwotnie również chciałam wykorzystać w pracy. http://factominer.free.fr/factomethods/hierarchical-multiple-factor-analysis.html↩