Wstęp

Celem mojego projektu jest dokonanie analizy zbioru danych na temat składu chemicznego win i zbadanie korelacji między zmiennymi. Dane zawieraja wiele informacji na temat składu chemicznego poszczególnych win, a moim celem jest znalezienie tych najistotniejszych, ktore świadczą o dobrej jakości wina.

W tym celu posłużę się redukcją wymiarów (ograniczenia liczby zmiennych do dwóch wymiarów), konkretnie metodą PCA (Analizy Składowych Głównych). PCA sprawdza się przy analizowaniu danych numerycznych (jak w moim zbiorze danych) i polega na szukaniu najistotniejszych kierunków zmienności, na przykład na podstawie macierzy wariancji. Dane, sprowadzone zazwyczaj do 2-3 wymiarów, są reprezentowane na 2 osiach będącymi kombinacjami najważniejszych zmiennych. Zastosowałam ta metodę podczas analizy tego zbioru danych, gdyż pokaże z jakimi właściwoścami chemicznymi koreluje jakość i w jaki sposób.

library(dplyr)
## 
## Dołączanie pakietu: 'dplyr'
## Następujące obiekty zostały zakryte z 'package:stats':
## 
##     filter, lag
## Następujące obiekty zostały zakryte z 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggfortify)
## Warning: pakiet 'ggfortify' został zbudowany w wersji R 4.5.2
## Ładowanie wymaganego pakietu: ggplot2
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(gridExtra)
## Warning: pakiet 'gridExtra' został zbudowany w wersji R 4.5.2
## 
## Dołączanie pakietu: 'gridExtra'
## Następujący obiekt został zakryty z 'package:dplyr':
## 
##     combine
library(psych)
## Warning: pakiet 'psych' został zbudowany w wersji R 4.5.2
## 
## Dołączanie pakietu: 'psych'
## Następujące obiekty zostały zakryte z 'package:ggplot2':
## 
##     %+%, alpha
library(ClusterR)

Przygotowanie danych

Zbiór danych pobrałam z serwisu Kaggle. Zawierają 1143 obserwacji oraz 13 zmiennych informujących o stężeniu poszczególnych substancji chemicznych. Ostatnia kolumna “quality” informuje o jakości w skali 1-10.

wine0 <- read.csv("WineQT.csv", sep = ",", dec = ".", header = TRUE) 
head(wine0)    
##   fixed.acidity volatile.acidity citric.acid residual.sugar chlorides
## 1           7.4             0.70        0.00            1.9     0.076
## 2           7.8             0.88        0.00            2.6     0.098
## 3           7.8             0.76        0.04            2.3     0.092
## 4          11.2             0.28        0.56            1.9     0.075
## 5           7.4             0.70        0.00            1.9     0.076
## 6           7.4             0.66        0.00            1.8     0.075
##   free.sulfur.dioxide total.sulfur.dioxide density   pH sulphates alcohol
## 1                  11                   34  0.9978 3.51      0.56     9.4
## 2                  25                   67  0.9968 3.20      0.68     9.8
## 3                  15                   54  0.9970 3.26      0.65     9.8
## 4                  17                   60  0.9980 3.16      0.58     9.8
## 5                  11                   34  0.9978 3.51      0.56     9.4
## 6                  13                   40  0.9978 3.51      0.56     9.4
##   quality Id
## 1       5  0
## 2       5  1
## 3       5  2
## 4       6  3
## 5       5  4
## 6       5  5
dim(wine0) 
## [1] 1143   13

Ze zbioru danych usunęłam ostatnią kolumnę “Id”, która zawierała numery wierszy. Pozostałe zmienne zawierają dane numeryczne, wyrażające natężenie poszczególnych właściwości i substancji chemicznych oraz jakość.

wine <- wine0 [,-13]

Wykonanie PCA

Kod poniżej uruchamia algorytm PCA na wybranym zbiorze danych oraz pokazuje jaką część zmienności wyjaśnia uwzględnienie poszczególnych wymiarów. Stosując metodę PCA konieczna jest standaryzacja danych (poniżej za pomocą funkcji “scale” wewnątrz kodu wykonującego PCA), gdyż ten algorytm jest bardzo wrazliwy na odchylenia.

pca1 <- prcomp(scale(wine), center = FALSE, scale. = FALSE)

fviz_eig(pca1)
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.

summary(pca1)
## Importance of components:
##                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
## Standard deviation     1.7826 1.4949 1.2986 1.1026 0.98356 0.81616 0.76590
## Proportion of Variance 0.2648 0.1862 0.1405 0.1013 0.08062 0.05551 0.04888
## Cumulative Proportion  0.2648 0.4510 0.5916 0.6929 0.77348 0.82899 0.87787
##                            PC8     PC9   PC10    PC11    PC12
## Standard deviation     0.70117 0.63828 0.5765 0.41923 0.24168
## Proportion of Variance 0.04097 0.03395 0.0277 0.01465 0.00487
## Cumulative Proportion  0.91884 0.95279 0.9805 0.99513 1.00000

Wykres “scree plot” powyżej pokazuje, w jakim stopniu uwzględnienie w wizualizacji kolejnych wymiarów wyjaśnia zmienność. Z każdym kolejnym dodanym wymiarem zmienność, którą on wyraża, maleje. Zaś dwa pierwsze wymiary wyjasniają 45% zmienności i podczas wykonywania wizualizacji pozostane przy tej liczbie wymiarów.

Wizualizacja

Poniższy wykres ukazuje tzw. eigenwektory, czyli kierunki zmienności poszczególnych zmiennych oraz to, w jakim stopniu zostały przedstawione na wykresie. Zmienne oznaczone czarnym kolorem zostały wyrażone niemal w całości, a im kolor jest jasniejszy, tym mniej zmienności danej kolumny wykres przedstawia. Wyraża to także długość strzałki.

fviz_pca_var(pca1, col.var = "cos2",
             gradient.cols = c("steelblue", "blue", "black"),
             repel = F) 
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
##   Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Na wykresie najlepiej są wyrażone dane dotyczące odczynu wina, gęstości, jakości oraz zawartości alkoholu. Znaczenie osi zaś pokazują dwa poniższe wykresy.

fviz_contrib(pca1, choice = "var", axes = 1)

Żeby zinterpretować to, jakie zmienne wyjaśnia dana oś, należy skupić się na kolumnach, których wartości mieszczą sie powyżej czerwonych linii. Na tym wykresie, przedstawiającym skład osi 1 (poziomej), takie wartości osiagają zmienne dotyczące odczynu i kwasowości, a w mniejszym stopniu także gestości. Możemy więc stwierdzić, że ta oś przedstawia zmienność odczynu wina. Na przykład zmienna pH koreluje negatywnie z kwasem cytrynowym (citric.acid) oraz ogólną kwasowością (fixed.acidity), gdyż im wyższe jest pH, tym odczyn jest bardziej zasadowy. Oś ta nie wyjaśnia jednak znaczenia danych dla jakości.

fviz_contrib(pca1, choice = "var", axes = 2)

Skład osi 2 (pionowej) wyjaśnia wykres powyżej. Powyżej czerwonej linii przede wszystkim są zmienne dotyczące zawartości alkoholu i jakości oraz w mniejszym stopniu poziomu kwasowości lotnej (czyli zawartości kwasowości octowej w destylacie), zawartości dwutlenku siarki i gęstości.

Wnioski

Wykresy pokazują, że z jakością koreluje pozytywnie przede wszystkim zawartość alkoholu - jego wyższa zawartość przekłada się na lepszą jakość wina. Negatywnie zaś koreluje zawartośc dwutlenku siarki - ich strzałki są zwrócone w odrtotna stronę co jakość. Z nią zaś nie korelują wszystkie zmienne ortogonalne (prostopadłe w stosunku do jakości), czyli przede wszystkim odczyn i poziom kwasowości.