Αυτή η ανάρτηση είναι μια διασκεδαστική άσκηση για την εφαρμογή PCA (τα περισσότερα στο πλαίσιο tidyverse) σε δεδομένα μετοχών από εταιρείες του δείκτη S&P 500. Με την PCA σε δεδομένα μετοχών από τον S&P 500, μπορούμε ενδεχομένως να κάνουμε πολλά ενδιαφέροντα πράγματα, αλλά θα επικεντρωθούμε σε πολύ απλά πράγματα και θα προσπαθήσουμε να δούμε εάν η PCA αποτυπώνει τις γενικές τάσεις της εταιρείας από τα αποτελέσματα της PCA.
Θα χρησιμοποιήσουμε το πακέτο Tidyquant R για να αποκτήσουμε πρόσβαση σε δεδομένα τιμών μετοχών χρησιμοποιώντας το R και θα χρησιμοποιήσουμε το prcomp() για να εκτελέσουμε PCA χρησιμοποιώντας το πλαίσιο tidyverse με τη βοήθεια του πακέτου σκούπας.
Θα ξεκινήσουμε με τη λήψη ημερήσιων δεδομένων τιμών μετοχών για περίπου 500 εταιρείες στον χρηματιστηριακό δείκτη S&P 500 για το έτος 2022. Στη συνέχεια θα εξερευνήσουμε λίγο τα δεδομένα και θα υπολογίσουμε τις ημερήσιες αποδόσεις μετοχών για κάθε εταιρεία.
Στη συνέχεια, θα προχωρήσουμε και θα εφαρμόσουμε PCA στα ημερήσια δεδομένα επιστροφής για το έτος 2022 και θα προσπαθήσουμε να κατανοήσουμε τους υπολογιστές.
Αρχικά, ας φορτώσουμε τα πακέτα που χρειάζονται.
library(tidyquant) library(broom) library(tidyverse) theme_set(theme_bw(16))
Εταιρείες στον δείκτη S&P 500
Ο δείκτης S&P 500 περιέχει συνήθως περίπου 500 εταιρείες στον δείκτη του. Στο τέλος του 2022, υπάρχουν 503 εταιρείες στον δείκτη S&P 500.
Μπορούμε να λάβουμε τη λίστα με όλες τις εταιρείες στον δείκτη S&P 500, χρησιμοποιώντας τη συνάρτηση tq_index() του tidyquant. Καθορίζουμε το όνομα του ευρετηρίου, εδώ „SP500“ ως το όρισμα στο tq_index() του tidyquant. Μας δίνει λεπτομερείς πληροφορίες σχετικά με τις εταιρείες του δείκτη S&P 500, συμπεριλαμβανομένης της επωνυμίας μετοχών, της βαρύτητας των εταιρειών στον δείκτη όπως μετράται με βάση την κεφαλαιοποίηση της αγοράς και τον ευρύ τομέα στον οποίο ανήκει.
# get S&P 500 index coopanies info tq_index("SP500") %>% head()
## Getting holdings for SP500 ## # A tibble: 10 × 8 ## symbol company identifier sedol weight sector shares_held local_currency ## <chr> <chr> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 AAPL Apple Inc. 03783310 2046… 0.0587 Infor… 165455870 USD ## 2 MSFT Microsoft C… 59491810 2588… 0.0520 Infor… 82480670 USD ## 3 AMZN Amazon.com … 02313510 2000… 0.0232 Consu… 98203210 USD ## 4 BRK.B Berkshire H… 08467070 2073… 0.0177 Finan… 19935340 USD ## 5 GOOGL Alphabet In… 02079K30 BYVY… 0.0162 Commu… 66088936 USD ## 6 JNJ Johnson & J… 47816010 2475… 0.0147 Healt… 28960104 USD
Ας αποθηκεύσουμε τις πληροφορίες για τις εταιρείες του S&P 500 σε μια μεταβλητή για μελλοντική χρήση.
stock_list_tbl <- tq_index("SP500") %>% arrange(symbol)
Εξερευνώντας λίγο τα δεδομένα εταιρειών του S&P 500, ας δούμε τον αριθμό των εταιρειών σε κάθε τομέα χρησιμοποιώντας ένα απλό barplot.
stock_list_tbl %>% count(sector, sort=TRUE) %>% ggplot(aes(y=reorder(sector,n), x=n, fill=sector))+ geom_col()+ labs(y=NULL, subtitle= "2022 S&P 500 Companies Count by Sector")+ theme(legend.position = "none") ggsave("SP500_index_company_counts_by_sector.png")

Ακολουθεί μια ματιά στις 15 κορυφαίες εταιρείες του δείκτη S&P 500 με βάση το βάρος τους.
stock_list_tbl %>% arrange(desc(weight))%>% head(15) %>% mutate(company=gsub(" Corporation", "", company), company=gsub(" Inc.","", company), company=gsub(" Limited","", company), company=gsub(" Company","", company), company=gsub(" Inc.","", company), company=gsub(" Incorporated","", company)) %>% ggplot(aes(y=reorder(company,weight), x=weight, fill=sector))+ geom_col()+ labs(y=NULL)+ scale_x_continuous(labels=scales::percent_format()) ggsave("SP500_index_company_weight_top15.png")

Πώς να λάβετε δεδομένα τιμών μετοχών για μια εταιρεία
Μπορούμε να πάρουμε την τιμή της μετοχής οποιασδήποτε εισηγμένης αμερικανικής εταιρείας χρησιμοποιώντας τη συνάρτηση tidyquant tq_get(). Στο παρακάτω παράδειγμα, καθορίζουμε ticker για την Apple και επίσης καθορίζουμε τις ημερομηνίες έναρξης και λήξης που χρειαζόμαστε τα δεδομένα αποθεμάτων. Εδώ λαμβάνουμε τα δεδομένα τιμών μετοχών της Apple για ολόκληρο το έτος 2022.
Για κάθε εταιρεία που καθορίζουμε παίρνουμε την τιμή της μετοχής στο άνοιγμα, την υψηλή, τη χαμηλή και την προσαρμοσμένη τιμή όπως φαίνεται παρακάτω.
tq_get("AAPL", from = "2022-01-01", to="2023-01-01") %>% head() ## # A tibble: 6 × 8 ## symbol date open high low close volume adjusted ## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 AAPL 2022-01-03 178. 183. 178. 182. 104487900 181. ## 2 AAPL 2022-01-04 183. 183. 179. 180. 99310400 179. ## 3 AAPL 2022-01-05 180. 180. 175. 175. 94537600 174. ## 4 AAPL 2022-01-06 173. 175. 172. 172 96904000 171. ## 5 AAPL 2022-01-07 173. 174. 171. 172. 86709100 171. ## 6 AAPL 2022-01-10 169. 172. 168. 172. 106765600 171.
Ας γράψουμε μια μικρή συνάρτηση για να πάρουμε την τιμή της μετοχής μιας εταιρείας. Αντί να λαμβάνουμε όλα τα δεδομένα από τη συνάρτηση tq_get(), κρατάμε μόνο τρεις στήλες από την έξοδο της tq_get().
get_stock_price <- function(ticker = "AAPL"){ tq_get(ticker, from = "2022-01-01", to="2023-01-01") %>% select(symbol, date, adjusted) }
Εδώ είναι μια άλλη συνάρτηση για να λάβετε όλες τις μετοχές για τις εταιρείες του δείκτη S&P 500 χρησιμοποιώντας τη συνάρτηση tq_index() στο πακέτο tidyquant R.
get_stock_tickers <- function(stock_index= "SP500"){ tq_index(stock_index) %>% select(symbol,company,weight) %>% arrange(symbol) }
Επιτρέψτε μας να πάρουμε όλες τις μετοχές από τον δείκτη S&P 500 και να καθαρίσουμε λίγο τα ονόματα των μετοχών.
sp500_tickers <- get_stock_tickers() sp500_tickers <- sp500_tickers %>% mutate(symbol= gsub("\\.","-",symbol))
sp500_tickers %>% head() ## # A tibble: 6 × 3 ## symbol company weight ## <chr> <chr> <dbl> ## 1 A Agilent Technologies Inc. 0.00142 ## 2 AAL American Airlines Group Inc. 0.000280 ## 3 AAP Advance Auto Parts Inc. 0.000290 ## 4 AAPL Apple Inc. 0.0587 ## 5 ABBV AbbVie Inc. 0.00907 ## 6 ABC AmerisourceBergen Corporation 0.000829
Πώς να λάβετε δεδομένα τιμών μετοχών για όλες τις εταιρείες του δείκτη S&P 500
Με όλα τα εταιρικά tickers, είμαστε τώρα έτοιμοι να λάβουμε τα δεδομένα τιμών μετοχών για όλες τις εταιρείες του S&P 500. Και πάλι, θα χρησιμοποιήσουμε τη συνάρτηση tq_get() του tidyquant για να λάβουμε τα δεδομένα μετοχών. Εδώ, αντί για το ticker μιας εταιρείας, θα χρησιμοποιήσουμε όλα τα tickers από τον δείκτη S&P 500.
Καθορίζουμε επίσης την ημερομηνία έναρξης και λήξης για το έτος 2022, αφού θέλουμε τα δεδομένα για ολόκληρο το 2022.
# get SP500 companies stock price data sp500_2022 <- tq_get(sp500_tickers %>% pull(symbol), from = "2022-01-01", to= "2023-01-01")
Εφόσον η tq_get() ανακτά τα δεδομένα μέσω Διαδικτύου χρησιμοποιώντας την υπηρεσία Yahoo, μπορεί να χρειαστεί λίγος χρόνος για να ολοκληρωθεί για να λάβετε τις τιμές μετοχών σε περισσότερες από 500 εταιρείες για ένα χρόνο. Όταν ολοκληρωθεί, τα δεδομένα εξόδου θα φαίνονται ίδια με πριν, αλλά τώρα για όλες τις εταιρείες.
# S&P 500 companyies stock price data sp500_2022 %>% head() ## # A tibble: 6 × 8 ## symbol date open high low close volume adjusted ## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 A 2022-01-03 159 159. 154. 156. 1606300 155. ## 2 A 2022-01-04 155. 156. 150. 151. 2234000 150. ## 3 A 2022-01-05 151. 153. 149. 149. 2370500 148. ## 4 A 2022-01-06 149. 150. 146. 149. 2298300 148. ## 5 A 2022-01-07 149. 150. 145. 145. 2058600 144. ## 6 A 2022-01-10 143. 145. 141. 145. 2548100 144.
Μπορούμε να βεβαιωθούμε ότι έχουμε κατεβάσει όλα τα δεδομένα τιμών μετοχών των εταιρειών.
sp500_2022 %>% dim() 126002 8
Έχουμε πάνω από 120.000 σειρές δεδομένων τιμών μετοχών. Και κοιτάζοντας την ουρά των δεδομένων. Δεδομένου ότι έχουμε ταξινομήσει τα εταιρικά tickers, βλέπουμε δεδομένα από μια εταιρεία που ξεκινά με το Z.
sp500_2022 %>% tail() ## # A tibble: 6 × 8 ## symbol date open high low close volume adjusted ## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 ZTS 2022-12-22 144. 145. 142. 145. 1541800 145. ## 2 ZTS 2022-12-23 145. 146. 144. 146. 1017900 146. ## 3 ZTS 2022-12-27 146. 146. 144. 145. 957900 145. ## 4 ZTS 2022-12-28 145. 147. 144. 144. 1443900 144. ## 5 ZTS 2022-12-29 145. 149. 145. 148. 1298900 148. ## 6 ZTS 2022-12-30 147. 148. 145. 147. 1249500 147.
Πώς να υπολογίσετε τις ημερήσιες αποδόσεις για όλες τις εταιρείες του δείκτη S&P 500
Θα υπολογίσουμε τις ημερήσιες αποδόσεις για κάθε ημέρα και για κάθε εταιρεία χρησιμοποιώντας προσαρμοσμένη τιμή για μια ημέρα με. συνάρτηση tq_transmute() του tidyquant.
Εφαρμόζουμε την tq_transmute() για κάθε εταιρεία στο S&P 500 χρησιμοποιώντας τη συνάρτηση group_by(). Και η tq_transmute() παίρνει τέσσερα ορίσματα όπως φαίνεται παρακάτω. Καθορίζουμε την tq_transmute() να χρησιμοποιεί „προσαρμοσμένη“ τιμή μετοχής για τον υπολογισμό των ημερήσιων αποδόσεων και επίσης μετονομάζουμε τη στήλη επιστροφής σε „daily_return“.
sp500_daily_return <- sp500_2022 %>% group_by(symbol) %>% tq_transmute(select = adjusted, mutate_fun = periodReturn, period = "daily", col_rename = "daily_return")
Και τα δεδομένα ημερήσιας επιστροφής που προκύπτουν είναι μια τακτοποιημένη πλακέτα που μοιάζει με αυτό.
sp500_daily_return %>% head() ## # A tibble: 6 × 3 ## # Groups: symbol [1] ## symbol date daily_return ## <chr> <date> <dbl> ## 1 A 2022-01-03 0 ## 2 A 2022-01-04 -0.0338 ## 3 A 2022-01-05 -0.0171 ## 4 A 2022-01-06 0.00350 ## 5 A 2022-01-07 -0.0266 ## 6 A 2022-01-10 0.0000690
Πώς να υπολογίσετε τις εβδομαδιαίες/μηνιαίες/ετήσιες αποδόσεις για όλες τις εταιρείες στον δείκτη S&P 500
Εάν ενδιαφέρεστε να υπολογίσετε άλλες αποδόσεις όπως, εβδομαδιαία, μηνιαία ή ετήσια, μπορούμε να χρησιμοποιήσουμε τη συνάρτηση tq_transmute() του tidyquant με παρόμοιο τρόπο, αλλά αυτή τη φορά αλλάζουμε το όρισμα «period» σε «εβδομαδιαία» και μετονομάζουμε σωστά τη στήλη επιστροφής.
Ο παρακάτω κωδικός λαμβάνει εβδομαδιαίες αποδόσεις εταιρειών στον δείκτη S&P 500.
sp500_weekly_return <- sp500_2022 %>% group_by(symbol) %>% tq_transmute(select = adjusted, mutate_fun = periodReturn, period = "weekly", col_rename = "weekly_return") sp500_weekly_return %>% head() ## # A tibble: 6 × 3 ## # Groups: symbol [1] ## symbol date weekly_return ## <chr> <date> <dbl> ## 1 A 2022-01-07 -0.0724 ## 2 A 2022-01-14 -0.00324 ## 3 A 2022-01-21 -0.0496 ## 4 A 2022-01-28 -0.00327 ## 5 A 2022-02-04 0.0296 ## 6 A 2022-02-11 -0.0278
Εδώ χρησιμοποιούμε την ίδια στρατηγική χρησιμοποιώντας «period=monthly» και λαμβάνουμε μηνιαίες αποδόσεις εταιρειών στον δείκτη S&P 500.
sp500_monthly_return <- sp500_2022 %>% group_by(symbol) %>% tq_transmute(select = adjusted, mutate_fun = periodReturn, period = "monthly", col_rename = "monthly_return") sp500_monthly_return %>% head() ## # A tibble: 6 × 3 ## # Groups: symbol [1] ## symbol date monthly_return ## <chr> <date> <dbl> ## 1 A 2022-01-31 -0.110 ## 2 A 2022-02-28 -0.0643 ## 3 A 2022-03-31 0.0151 ## 4 A 2022-04-29 -0.0973 ## 5 A 2022-05-31 0.0695 ## 6 A 2022-06-30 -0.0689
Και μπορούμε επίσης να λάβουμε ετήσιες αποδόσεις εταιρειών στον δείκτη S&P 500 με τον ακόλουθο κωδικό.
sp500_annual_return <- sp500_2022 %>% group_by(symbol) %>% tq_transmute(select = adjusted, mutate_fun = periodReturn, period = "yearly", col_rename = "annual_return") sp500_annual_return %>% head() ## # A tibble: 6 × 3 ## # Groups: symbol [6] ## symbol date annual_return ## <chr> <date> <dbl> ## 1 A 2022-12-30 -0.0374 ## 2 AAL 2022-12-30 -0.322 ## 3 AAP 2022-12-30 -0.357 ## 4 AAPL 2022-12-30 -0.282 ## 5 ABBV 2022-12-30 0.240 ## 6 ABC 2022-12-30 0.265
PCA για τις Ημερήσιες Επιστροφές εταιρειών S&P 500
Ας προχωρήσουμε στην εκτέλεση PCA στις ημερήσιες αποδόσεις των εταιρειών στον δείκτη S&P 500. Αρχικά, ας αναδιαμορφώσουμε την τακτοποιημένη/μεγάλη φόρμα ημερήσιας επιστροφής δεδομένων σε ευρεία φόρμα, με εταιρείες σε σειρές και ημερομηνίες σε στήλες. Χρησιμοποιούμε pivot_wider για να αναδιαμορφώσουμε. Και μετατρέπουμε επίσης την πλατιά πλακέτα που προκύπτει σε μήτρα.
sp500_dmat <- sp500_daily_return %>% pivot_wider(names_from="date", values_from = daily_return) %>% select(-`2022-01-03`) %>% column_to_rownames("symbol") %>% as.matrix()
Και ο ημερήσιος πίνακας αποδόσεων του S&P 500 μοιάζει με αυτό.
sp500_mat[1:5,1:5] ## 2022-01-04 2022-01-05 2022-01-06 2022-01-07 2022-01-10 ## A -0.033806308 -0.017130581 0.003499327 -0.0266229247 6.899386e-05 ## AAL 0.014400000 -0.017875920 -0.005888651 0.0382337641 -2.541494e-02 ## AAP 0.001140383 -0.002531108 0.021991956 -0.0147320356 -1.663232e-02 ## AAPL -0.012691475 -0.026600016 -0.016693182 0.0009883834 1.160615e-04 ## ABBV -0.001919791 0.005252839 -0.004710368 -0.0025881284 1.119520e-02
Πριν προχωρήσουμε, ας αφαιρέσουμε τυχόν δεδομένα που λείπουν στον πίνακα επιστροφής. Χωρίς να σταθούμε στους λόγους έλλειψης, απλώς προσδιορίζουμε τις σειρές με τιμές που λείπουν και αφαιρούμε τις σειρές από τον πίνακα επιστροφής SP500.
na_ind <- which(apply(sp500_dmat,1,function(x){sum(is.na(x))})>0) na_ind ## CEG GEHC ## 89 199 sp500_mat <- sp500_dmat[-na_ind,]
dim(sp500_mat) ## [1] 501 250
Αφού αφαιρέσαμε τις δύο εταιρείες με τιμές που λείπουν, έχουμε 501 εταιρείες από τον δείκτη S&P 500 στον πίνακα ημερήσιων δεδομένων επιστροφής.
Στην PCA, μας ενδιαφέρει για τις εταιρείες και όχι για την απόδοση του δείκτη με την πάροδο του χρόνου. Επομένως, μεταφέρετε τον πίνακα πριν εφαρμόσετε τη συνάρτηση scale() για να κεντράρετε και να κλιμακώσετε τα δεδομένα. Μετά την κλιμάκωση εκτελούμε PCA χρησιμοποιώντας τη συνάρτηση prcomp() στο R.
pca_fit <- sp500_mat %>% t() %>% scale() %>% prcomp()
Έχουμε αποθηκεύσει τα αποτελέσματα PCA σε μια μεταβλητή που ονομάζεται pca_fit. Και αυτή είναι η δομή του αντικειμένου αποτελέσματος PCA.
str(pca_fit ) ## List of 5 ## $ sdev : num [1:250] 14.87 5.54 4.68 3.76 3.01 ... ## $ rotation: num [1:501, 1:250] -0.0514 -0.0457 -0.0388 -0.0548 -0.027 ... ## ..- attr(*, "dimnames")=List of 2 ## .. ..$ : chr [1:501] "A" "AAL" "AAP" "AAPL" ... ## .. ..$ : chr [1:250] "PC1" "PC2" "PC3" "PC4" ... ## $ center : Named num [1:501] 3.02e-18 -2.21e-17 1.45e-17 -2.84e-17 6.91e-18 ... ## ..- attr(*, "names")= chr [1:501] "A" "AAL" "AAP" "AAPL" ... ## $ scale : Named num [1:501] 0.0223 0.0354 0.0235 0.0225 0.0141 ... ## ..- attr(*, "names")= chr [1:501] "A" "AAL" "AAP" "AAPL" ... ## $ x : num [1:250, 1:250] -9.27 14.59 -2.85 2.48 4.48 ... ## ..- attr(*, "dimnames")=List of 2 ## .. ..$ : chr [1:250] "2022-01-04" "2022-01-05" "2022-01-06" "2022-01-07" ... ## .. ..$ : chr [1:250] "PC1" "PC2" "PC3" "PC4" ... ## - attr(*, "class")= chr "prcomp"
Οικόπεδο οθόνης από Ημερήσιες Επιστροφές εταιρειών S&P 500
Θα χρησιμοποιήσουμε το πακέτο σκούπας για να εξαγάγουμε τα αποτελέσματα από το PCA. Με τη συνάρτηση broom’s tidy() με όρισμα „pcs“, παίρνουμε την ποσοστιαία διακύμανση που εξηγείται από κάθε υπολογιστή.
library(broom) pca_fit %>% tidy("pcs") %>% head() ## # A tibble: 6 × 4 ## PC std.dev percent cumulative ## <dbl> <dbl> <dbl> <dbl> ## 1 1 14.9 0.441 0.441 ## 2 2 5.54 0.0612 0.502 ## 3 3 4.68 0.0438 0.546 ## 4 4 3.76 0.0282 0.574 ## 5 5 3.01 0.0180 0.592 ## 6 6 2.82 0.0159 0.608
Χρησιμοποιώντας τη διακύμανση που εξηγήθηκε, μπορούμε να κάνουμε μια γραφική παράσταση για να κατανοήσουμε πόσοι υπολογιστές εξηγούν την πλειονότητα της διακύμανσης στα δεδομένα μετοχών του S&P 500.
pca_fit %>% tidy("pcs") %>% filter(PC<50) %>% ggplot(aes(x=PC, y=percent))+ geom_col(fill="dodgerblue", alpha=0.7) + scale_y_continuous(labels=scales::label_percent(), breaks = scales::breaks_pretty(n=6))+ labs(y= "Variance explained", title="Scree plot: 2022 S&P 500 Stock Return data") ggsave("Scree_plot_percent_variance_explained_SP500_data.png")

Ας αποθηκεύσουμε τη διακύμανση που εξηγείται από κάθε υπολογιστή για μελλοντική χρήση στη δημιουργία γραφημάτων PCA.
variance_exp <- pca_fit %>% tidy("pcs") %>% pull(percent)
variance_exp %>% head() [1] 0.44130 0.06117 0.04376 0.02817 0.01804 0.01586
PCA Plot : PC1 vs PC2 – Ημερήσιες επιστροφές εταιρειών S&P 500
Για να κατανοήσουμε γρήγορα τους δύο κορυφαίους υπολογιστές από PCA σε δεδομένα δείκτη S&P 500, κάνουμε μια γραφική παράσταση PCA με PC1 έναντι PC2.
Αρχικά, ας συνδυάσουμε τα αποτελέσματα από το PCA με τα δεδομένα εταιρικών πληροφοριών του S&P 500.
pc_df <- pca_fit %>% tidy("loadings") %>% filter(PC %in% c(1:5)) %>% rename(symbol=column) %>% left_join(stock_list_tbl, by="symbol") %>% mutate(PC=paste0("PC",PC)) %>% pivot_wider(names_from = "PC", values_from = "value")
pc_df %>% head() ## # A tibble: 6 × 13 ## symbol company identifier sedol weight sector shares_held local_currency ## <chr> <chr> <chr> <chr> <dbl> <chr> <dbl> <chr> ## 1 A Agilent Tec… 00846U10 2520… 1.42e-3 Healt… 3289739 USD ## 2 AAL American Ai… 02376R10 BCV7… 2.80e-4 Indus… 7063898 USD ## 3 AAP Advance Aut… 00751Y10 2822… 2.90e-4 Consu… 667858 USD ## 4 AAPL Apple Inc. 03783310 2046… 5.87e-2 Infor… 165455870 USD ## 5 ABBV AbbVie Inc. 00287Y10 B92S… 9.07e-3 Healt… 19567584 USD ## 6 ABC Amerisource… 03073E10 2795… 8.29e-4 Healt… 1792022 USD ## # … with 5 more variables: PC1 <dbl>, PC2 <dbl>, PC3 <dbl>, PC4 <dbl>, ## # PC5 <dbl>
Τώρα κάνουμε το γράφημα PCA, ένα διάγραμμα διασποράς μεταξύ PC1 και PC2. Χρωματίζουμε επίσης τα σημεία στο διάγραμμα διασποράς με βάση τον τομέα που ανήκει στον δείκτη S&P 500.
pc_df %>% ggplot(aes(x=PC1,y=PC2, color=sector))+ geom_point(size=3, alpha=0.7)+ #coord_fixed() + labs(title= "PCA: 2022 S&P 500 Stock Data", x=paste0("PC1: ", round(variance_exp[1]*100), "%"), y=paste0("PC1: ", round(variance_exp[2]*100), "%")) ggsave("PCA_plot_PC1_vs_PC2_SP500_daily_return.png")
Στραβίζοντας λίγο στο οικόπεδο PCA μπορούμε να δούμε κάποια μοτίβα σε επίπεδο τομέα, αλλά όχι εύκολα.
Για να δούμε τι έχει καταγράψει το PC1, φτιάχνουμε ένα πλαίσιο με το PC1 στον άξονα x και τους τομείς του δείκτη S&P 500 στον άξονα y.
Έχουμε παραγγείλει τους τομείς με τις μέσες τιμές PC1.
pc_df %>% ggplot(aes(x=PC1,y=reorder(sector,PC1), color=sector))+ geom_boxplot(size=1)+ labs(title= "PCA: 2022 S&P 500 Stock Data", x=paste0("PC1: ", round(variance_exp[1]*100), "%"), y="Sector")+ #geom_jitter(width=0.05)+ theme(legend.position="none") ggsave("PCA_plot_PC1_vs_SP500_sectors.png")
Μπορούμε να δούμε ξεκάθαρα το μοτίβο που έχει καταγράψει το PC1. Στη μία άκρη του κουτιού έχουμε εταιρείες πληροφορικής και στην άλλη πλευρά έχουμε εταιρείες ενέργειας. Καθώς προχωράμε από τον τομέα IT, που έχει χαμηλές τιμές PC1, στον ενεργειακό τομέα με υψηλή τιμή PC1, μπορούμε επίσης να δούμε άλλους τομείς να έχουν ένα ωραίο αυξανόμενο μοτίβο στις μέσες τιμές PC1 τους.
Επιστρέφοντας στο οικόπεδο PCA μεταξύ PC1 και PC2, ας επαναλάβουμε την πλοκή αυτή τη φορά, επισημαίνοντας μόνο τους τομείς της ενέργειας και της πληροφορικής.
pc_df %>% ggplot(aes(x=PC1,y=PC2))+ geom_point(color="grey", size=3, alpha=0.3)+ geom_point(data=pc_df %>% filter(sector=="Energy"), aes(PC1,PC2, color=sector), size=3, alpha=0.5)+ geom_point(data=pc_df %>% filter(sector=="Information Technology"), aes(PC1,PC2, color=sector), size=3, alpha=0.5)+ #coord_fixed() + labs(title= "PCA: 2022 S&P 500 Stock Data", x=paste0("PC1: ", round(variance_exp[1]*100), "%"), y=paste0("PC1: ", round(variance_exp[2]*100), "%")) #theme(legend.position = "none") ggsave("PCA_plot_PC1_vs_PC2_SP500_sectors.png")
Τώρα, μπορούμε να δούμε ότι τόσο το PC1 όσο και το PC2 φαίνεται να διαχωρίζουν όμορφα αυτούς τους τομείς. Σίγουρα υπάρχει τεράστια διακύμανση εντός των τομέων.

Συνοψίζοντας, σε αυτήν την ανάρτηση, είδαμε πώς να λαμβάνετε δεδομένα τιμών μετοχών χρησιμοποιώντας το tidyquant και να εκτελείτε PCA σε δεδομένα μετοχών S&P 500 χρησιμοποιώντας το πλαίσιο tidyverse. Πραγματοποιήσαμε ένα πρώτο πέρασμα PCA για τα δεδομένα ημερήσιας απόδοσης από εταιρείες του δείκτη S&P 500 για το έτος 2022. Και θα μπορούσαμε να βρούμε ότι οι κορυφαίοι υπολογιστές εξηγούν καλά τη γενική συμπεριφορά της αγοράς στις αποδόσεις. Όπως αναφέρθηκε, αυτή είναι πραγματικά μια πρόχειρη διασκεδαστική ανάλυση, θα είναι ενδιαφέρον να κάνουμε πιο λεπτομερή οικονομική ανάλυση με αυτά τα δεδομένα χρησιμοποιώντας τεχνικές μείωσης διαστάσεων όπως το PCA.