Ως financial analysts, αναλύουμε τα τριμηνιαία κέρδη ανά μετοχή (EPS) της Johnson & Johnson για την περίοδο 1960-1980, με στόχο την πρόβλεψη των επόμενων 3 ετών (12 τριμήνων). Η ανάλυση περιλαμβάνει εποχική αποσύνθεση, έλεγχο στασιμότητας, και σύγκριση τριών forecasting μοντέλων: Seasonal Naïve, Holt-Winters, και ARIMA.
# Φόρτωση δεδομένων
data("JohnsonJohnson")
jj <- JohnsonJohnson
# Βασικά χαρακτηριστικά
cat("Τύπος αντικειμένου:", class(jj), "\n")## Τύπος αντικειμένου: ts
## Έναρξη: 1960 1
## Λήξη: 1980 4
## Συχνότητα: 4 (τριμηνιαία)
## Μήκος: 84 παρατηρήσεις
## Πρώτα 12 τρίμηνα:
## Qtr1 Qtr2 Qtr3 Qtr4
## 1960 0.71 0.63 0.85 0.44
## 1961 0.61 0.69 0.92 0.55
## 1962 0.72 0.77 0.92 0.60
autoplot(jj) +
ggtitle("Johnson & Johnson: Τριμηνιαία Κέρδη ανά Μετοχή (1960-1980)") +
xlab("Έτος") +
ylab("EPS ($)") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))Η χρονοσειρά των κερδών της J&J εμφανίζει:
Από επιχειρηματική σκοπιά, η J&J δείχνει σταθερή και επιταχυνόμενη ανάπτυξη, υποδηλώνοντας ισχυρή αγορά, καλή διαχείριση και πιθανή επέκταση σε νέα προϊόντα/αγορές.
p1 <- ggseasonplot(jj, year.labels = TRUE, year.labels.left = TRUE) +
ggtitle("Seasonal Plot: J&J Earnings") +
ylab("EPS ($)") +
theme_minimal()
p2 <- ggsubseriesplot(jj) +
ggtitle("Subseries Plot: J&J Earnings") +
ylab("EPS ($)") +
theme_minimal()
grid.arrange(p1, p2, ncol = 1)Από τα παραπάνω διαγράμματα:
Επιχειρηματική εξήγηση:
# Υπολογισμός εύρους διακύμανσης ανά έτος
year_ranges <- sapply(1960:1980, function(y) {
year_data <- window(jj, start = c(y, 1), end = c(y, 4))
max(year_data) - min(year_data)
})
year_means <- sapply(1960:1980, function(y) {
year_data <- window(jj, start = c(y, 1), end = c(y, 4))
mean(year_data)
})
df_analysis <- data.frame(
Year = 1960:1980,
Range = year_ranges,
Mean = year_means
)
ggplot(df_analysis, aes(x = Mean, y = Range)) +
geom_point(size = 3, color = "steelblue") +
geom_smooth(method = "lm", se = TRUE, color = "red") +
ggtitle("Σχέση Μέσου Όρου και Εύρους Διακύμανσης") +
xlab("Μέσος Όρος Κερδών") +
ylab("Εύρος Εποχικής Διακύμανσης") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))Αποδείξεις:
Στο additive μοντέλο, η εποχική συνιστώσα θα ήταν σταθερή σε απόλυτη τιμή. Εδώ βλέπουμε ότι η εποχικότητα είναι αναλογική (%) του επιπέδου της σειράς.
jj_decomp <- decompose(jj, type = "multiplicative")
autoplot(jj_decomp) +
ggtitle("Multiplicative Decomposition: J&J Earnings") +
theme_minimal()Trend Component:
Seasonal Component:
Random (Remainder):
jj_log <- log(jj)
p1 <- autoplot(jj) +
ggtitle("Αρχική Σειρά") +
ylab("EPS ($)") +
theme_minimal()
p2 <- autoplot(jj_log) +
ggtitle("Log-Transformed Σειρά") +
ylab("log(EPS)") +
theme_minimal()
grid.arrange(p1, p2, ncol = 2)Τι αλλάζει:
Το log transformation είναι ιδανικό για αυτή τη σειρά.
# Train: 1960 Q1 - 1978 Q4 (76 παρατηρήσεις)
train <- window(jj, end = c(1978, 4))
# Test: 1979 Q1 - 1980 Q4 (8 παρατηρήσεις)
test <- window(jj, start = c(1979, 1))
cat("Train set:", length(train), "παρατηρήσεις\n")## Train set: 76 παρατηρήσεις
## Test set: 8 παρατηρήσεις
## Train period: 1960 1 to 1978 4
## Test period: 1979 1 to 1980 4
## === ADF Test: Αρχική Σειρά ===
##
## Augmented Dickey-Fuller Test
##
## data: train
## Dickey-Fuller = 0.85296, Lag order = 4, p-value = 0.99
## alternative hypothesis: stationary
##
## === ADF Test: Log Σειρά ===
##
## Augmented Dickey-Fuller Test
##
## data: train_log
## Dickey-Fuller = -1.4415, Lag order = 4, p-value = 0.8035
## alternative hypothesis: stationary
# First difference
train_log_diff <- diff(train_log)
cat("\n=== ADF Test: Log + 1st Difference ===\n")##
## === ADF Test: Log + 1st Difference ===
##
## Augmented Dickey-Fuller Test
##
## data: train_log_diff
## Dickey-Fuller = -4.339, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary
# Seasonal difference (lag = 4 για τρίμηνα)
train_log_diff_seasonal <- diff(train_log_diff, lag = 4)
cat("\n=== ADF Test: Log + 1st Diff + Seasonal Diff ===\n")##
## === ADF Test: Log + 1st Diff + Seasonal Diff ===
##
## Augmented Dickey-Fuller Test
##
## data: train_log_diff_seasonal
## Dickey-Fuller = -6.3584, Lag order = 4, p-value = 0.01
## alternative hypothesis: stationary
Χρειαζόμαστε d=1 (first difference) και D=1 (seasonal difference) για στασιμότητα.
p1 <- ggAcf(train_log_diff_seasonal, lag.max = 40) +
ggtitle("ACF: Differenced Series") +
theme_minimal()
p2 <- ggPacf(train_log_diff_seasonal, lag.max = 40) +
ggtitle("PACF: Differenced Series") +
theme_minimal()
grid.arrange(p1, p2, ncol = 2)ACF:
PACF:
Αυτά θα καθοδηγήσουν την auto.arima() στην επιλογή
(p,d,q)(P,D,Q)₄.
# (α) Seasonal Naïve - Baseline
fit_snaive <- snaive(train, h = 8)
cat("=== Seasonal Naïve Model ===\n")## === Seasonal Naïve Model ===
##
## Forecast method: Seasonal naive method
##
## Model Information:
## Call: snaive(y = train, h = 8)
##
## Residual sd: 0.8214
##
## Error measures:
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 0.5884722 0.8214427 0.5920833 14.27463 14.77554 1 0.6642405
##
## Forecasts:
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 1979 Q1 11.88 10.827279 12.932721 10.270002 13.49000
## 1979 Q2 12.06 11.007279 13.112721 10.450002 13.67000
## 1979 Q3 12.15 11.097279 13.202721 10.540002 13.76000
## 1979 Q4 8.91 7.857279 9.962721 7.300002 10.52000
## 1980 Q1 11.88 10.391227 13.368773 9.603119 14.15688
## 1980 Q2 12.06 10.571227 13.548773 9.783119 14.33688
## 1980 Q3 12.15 10.661227 13.638773 9.873119 14.42688
## 1980 Q4 8.91 7.421227 10.398773 6.633119 11.18688
# (β) Holt-Winters - Multiplicative
fit_hw <- hw(train, h = 8, seasonal = "multiplicative")
cat("\n=== Holt-Winters Model ===\n")##
## === Holt-Winters Model ===
##
## Forecast method: Holt-Winters' multiplicative method
##
## Model Information:
## Holt-Winters' multiplicative method
##
## Call:
## hw(y = train, h = 8, seasonal = "multiplicative")
##
## Smoothing parameters:
## alpha = 0.197
## beta = 0.1082
## gamma = 1e-04
##
## Initial states:
## l = 0.5902
## b = 0.0072
## s = 0.8267 1.0468 1.0827 1.0439
##
## sigma: 0.1337
##
## AIC AICc BIC
## 174.6172 177.3444 195.5938
##
## Error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.0420402 0.3595992 0.2602222 0.5285725 9.289055 0.4395027
## ACF1
## Training set 0.1282904
##
## Forecasts:
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 1979 Q1 12.83495 10.636472 15.03343 9.472669 16.19723
## 1979 Q2 13.76326 11.303396 16.22312 10.001224 17.52529
## 1979 Q3 13.74580 11.122117 16.36949 9.733221 17.75839
## 1979 Q4 11.19950 8.872544 13.52645 7.640730 14.75826
## 1980 Q1 14.57307 11.235132 17.91102 9.468132 19.67802
## 1980 Q2 15.56606 11.610776 19.52135 9.516974 21.61515
## 1980 Q3 15.48923 11.116368 19.86209 8.801514 22.17695
## 1980 Q4 12.57631 8.637829 16.51479 6.552923 18.59970
# (γ) ARIMA - Automatic με log transformation
fit_arima <- auto.arima(train, lambda = 0, seasonal = TRUE)
fc_arima <- forecast(fit_arima, h = 8)
cat("\n=== ARIMA Model ===\n")##
## === ARIMA Model ===
## Series: train
## ARIMA(2,0,0)(1,1,0)[4] with drift
## Box Cox transformation: lambda= 0
##
## Coefficients:
## ar1 ar2 sar1 drift
## 0.3131 0.2432 -0.2970 0.0386
## s.e. 0.1244 0.1300 0.1285 0.0046
##
## sigma^2 = 0.008377: log likelihood = 71.78
## AIC=-133.56 AICc=-132.65 BIC=-122.18
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.001523642 0.3596867 0.2419193 -0.16328 6.770657 0.4085899
## ACF1
## Training set -0.1186641
##
## Ljung-Box test
##
## data: Residuals from ARIMA(2,0,0)(1,1,0)[4] with drift
## Q* = 3.7985, df = 5, p-value = 0.5788
##
## Model df: 3. Total lags used: 8
Ljung-Box Test:
Ερμηνεία white noise:
autoplot(train) +
autolayer(test, series = "Πραγματικά", size = 1.2) +
autolayer(fit_snaive$mean, series = "Seasonal Naïve", linetype = "dashed") +
autolayer(fit_hw$mean, series = "Holt-Winters", linetype = "dashed") +
autolayer(fc_arima$mean, series = "ARIMA", linetype = "dashed") +
ggtitle("Σύγκριση Προβλέψεων: J&J Earnings (Test Period)") +
xlab("Έτος") +
ylab("EPS ($)") +
scale_color_manual(
values = c("Πραγματικά" = "black",
"Seasonal Naïve" = "red",
"Holt-Winters" = "blue",
"ARIMA" = "darkgreen")
) +
guides(color = guide_legend(title = "Μοντέλο")) +
theme_minimal() +
theme(legend.position = "bottom")# Υπολογισμός accuracy για κάθε μοντέλο
acc_snaive <- accuracy(fit_snaive, test)
acc_hw <- accuracy(fit_hw, test)
acc_arima <- accuracy(fc_arima, test)
# Δημιουργία πίνακα σύγκρισης (Test set μόνο)
comparison <- data.frame(
Model = c("Seasonal Naïve", "Holt-Winters", "ARIMA"),
RMSE = c(acc_snaive[2, "RMSE"], acc_hw[2, "RMSE"], acc_arima[2, "RMSE"]),
MAE = c(acc_snaive[2, "MAE"], acc_hw[2, "MAE"], acc_arima[2, "MAE"]),
MAPE = c(acc_snaive[2, "MAPE"], acc_hw[2, "MAPE"], acc_arima[2, "MAPE"])
)
# Ταξινόμηση κατά RMSE
comparison <- comparison[order(comparison$RMSE), ]
cat("=== ACCURACY COMPARISON (Test Set) ===\n\n")## === ACCURACY COMPARISON (Test Set) ===
## Model RMSE MAE MAPE
## 3 ARIMA 0.8136629 0.7225012 5.419212
## 2 Holt-Winters 1.0865532 1.0427583 7.763851
## 1 Seasonal Naïve 2.7765401 2.5425000 17.899110
##
## 🏆 Νικητής: ARIMA
## RMSE: 0.814
# Διαφορά από baseline
baseline_rmse <- comparison$RMSE[comparison$Model == "Seasonal Naïve"]
winner_rmse <- comparison$RMSE[1]
improvement <- ((baseline_rmse - winner_rmse) / baseline_rmse) * 100
cat("Βελτίωση από Seasonal Naïve:", round(improvement, 2), "%\n")## Βελτίωση από Seasonal Naïve: 70.7 %
# Επανεκπαίδευση νικητήριου μοντέλου σε όλα τα δεδομένα
# (Υποθέτουμε ότι ARIMA νίκησε - προσάρμοσε αν χρειάζεται)
final_model <- auto.arima(jj, lambda = 0, seasonal = TRUE)
final_forecast <- forecast(final_model, h = 12)
cat("=== FINAL MODEL (Trained on All Data) ===\n")## === FINAL MODEL (Trained on All Data) ===
## Series: jj
## ARIMA(2,0,0)(1,1,0)[4] with drift
## Box Cox transformation: lambda= 0
##
## Coefficients:
## ar1 ar2 sar1 drift
## 0.2686 0.2855 -0.2695 0.0382
## s.e. 0.1137 0.1214 0.1212 0.0042
##
## sigma^2 = 0.007793: log likelihood = 82.47
## AIC=-154.95 AICc=-154.14 BIC=-143.04
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set -0.00516599 0.4009399 0.273459 -0.1504525 6.505327 0.389751
## ACF1
## Training set -0.2525095
# Οπτικοποίηση με prediction intervals
autoplot(final_forecast) +
ggtitle("J&J Earnings: Πρόβλεψη για τα επόμενα 3 χρόνια (1981-1983)") +
xlab("Έτος") +
ylab("EPS ($)") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, face = "bold"))##
## === ΠΡΟΒΛΕΨΕΙΣ ΓΙΑ ΤΑ ΕΠΟΜΕΝΑ 12 ΤΡΙΜΗΝΑ ===
## Point Forecast Lo 80 Hi 80 Lo 95 Hi 95
## 1981 Q1 18.51527 16.53479 20.73297 15.57364 22.01253
## 1981 Q2 17.06041 15.17457 19.18062 14.26218 20.40766
## 1981 Q3 18.88704 16.68561 21.37892 15.62610 22.82850
## 1981 Q4 13.46536 11.87766 15.26528 11.11443 16.31355
## 1982 Q1 21.59675 18.40188 25.34630 16.90664 27.58795
## 1982 Q2 19.83398 16.84548 23.35265 15.45032 25.46140
## 1982 Q3 21.89227 18.51659 25.88334 16.94573 28.28271
## 1982 Q4 15.68610 13.25288 18.56606 12.12155 20.29887
## 1983 Q1 25.12898 20.58554 30.67519 18.52304 34.09080
## 1983 Q2 23.10456 18.87243 28.28574 16.95557 31.48350
## 1983 Q3 25.52715 20.77142 31.37172 18.62382 34.98935
## 1983 Q4 18.26814 14.84986 22.47328 13.30742 25.07811
# Μέσος ετήσιος growth rate προβλεπόμενων ετών
forecast_values <- as.numeric(final_forecast$mean)
# Υπολογισμός ετήσιων μέσων
year_1981 <- mean(forecast_values[1:4])
year_1982 <- mean(forecast_values[5:8])
year_1983 <- mean(forecast_values[9:12])
cat("Προβλεπόμενα μέσα ετήσια κέρδη:\n")## Προβλεπόμενα μέσα ετήσια κέρδη:
## 1981: 16.982
## 1982: 19.752
## 1983: 23.007
# Growth rates
growth_81_82 <- ((year_1982 - year_1981) / year_1981) * 100
growth_82_83 <- ((year_1983 - year_1982) / year_1982) * 100
avg_forecast_growth <- mean(c(growth_81_82, growth_82_83))
cat("Προβλεπόμενοι ρυθμοί ανάπτυξης:\n")## Προβλεπόμενοι ρυθμοί ανάπτυξης:
## 1981-1982: 16.31 %
## 1982-1983: 16.48 %
## Μέσος: 16.4 %
# Ιστορικός growth rate
historical_annual <- sapply(1961:1980, function(y) {
mean(window(jj, start = c(y, 1), end = c(y, 4)))
})
historical_growth <- diff(historical_annual) / head(historical_annual, -1) * 100
avg_historical_growth <- mean(historical_growth)
cat("Ιστορικός μέσος ετήσιος ρυθμός ανάπτυξης (1961-1980):",
round(avg_historical_growth, 2), "%\n\n")## Ιστορικός μέσος ετήσιος ρυθμός ανάπτυξης (1961-1980): 17.62 %
# Σύγκριση
if (abs(avg_forecast_growth - avg_historical_growth) < 5) {
cat("✅ Η πρόβλεψη είναι ΡΕΑΛΙΣΤΙΚΗ - συνάδει με το ιστορικό growth rate\n")
} else if (avg_forecast_growth > avg_historical_growth) {
cat("⚠️ Η πρόβλεψη είναι ΑΙΣΙΟΔΟΞΗ - υψηλότερη από το ιστορικό\n")
} else {
cat("⚠️ Η πρόβλεψη είναι ΣΥΝΤΗΡΗΤΙΚΗ - χαμηλότερη από το ιστορικό\n")
}## ✅ Η πρόβλεψη είναι ΡΕΑΛΙΣΤΙΚΗ - συνάδει με το ιστορικό growth rate
# Automatic ETS model selection
fit_ets <- ets(train)
fc_ets <- forecast(fit_ets, h = 8)
cat("=== ETS Model ===\n")## === ETS Model ===
## ETS(M,A,A)
##
## Call:
## ets(y = train)
##
## Smoothing parameters:
## alpha = 0.16
## beta = 0.1018
## gamma = 0.3989
##
## Initial states:
## l = 0.6253
## b = 4e-04
## s = -0.1882 0.1782 -0.0081 0.0181
##
## sigma: 0.092
##
## AIC AICc BIC
## 117.2365 119.9638 138.2131
##
## Training set error measures:
## ME RMSE MAE MPE MAPE MASE
## Training set 0.0492013 0.418255 0.2614132 1.321354 7.079831 0.4415143
## ACF1
## Training set 0.02747311
# Accuracy comparison
acc_ets <- accuracy(fc_ets, test)
cat("\n=== ETS vs Holt-Winters Comparison ===\n")##
## === ETS vs Holt-Winters Comparison ===
## ETS Test RMSE: 1.1671
## HW Test RMSE: 1.0866
if (acc_ets[2, "RMSE"] < acc_hw[2, "RMSE"]) {
cat("\n✅ ETS νικάει το Holt-Winters\n")
} else {
cat("\n❌ Holt-Winters νικάει το ETS\n")
}##
## ❌ Holt-Winters νικάει το ETS
##
## Ερμηνεία ETS notation:
## Πρώτο γράμμα (Error): A=Additive, M=Multiplicative
## Δεύτερο γράμμα (Trend): N=None, A=Additive, M=Multiplicative, Ad=Additive damped
## Τρίτο γράμμα (Seasonal): N=None, A=Additive, M=Multiplicative
Η τάση της Johnson & Johnson είναι εκθετική, όχι γραμμική. Συγκεκριμένα:
Επιχειρηματικά, αυτό υποδηλώνει σύνθετη ανάπτυξη (compound growth), τυπική για επιτυχημένες φαρμακευτικές εταιρίες με επέκταση portfolio και reinvestment κερδών.
Το 4ο τρίμηνο (Q4) εμφανίζει συστηματικά τα υψηλότερα κέρδη.
Επιχειρηματικές εξηγήσεις:
Η εποχικότητα είναι MULTIPLICATIVE.
Τεκμηρίωση:
Σε additive μοντέλο, οι εποχικές διαφορές θα ήταν σταθερές (+$X κάθε Q4), ανεξάρτητα από το επίπεδο. Εδώ βλέπουμε αναλογική εποχικότητα.
## Το μοντέλο που νίκησε (με το χαμηλότερο RMSE) είναι: ARIMA
## RMSE Νικητή: 0.8137
## RMSE Seasonal Naïve: 2.7765
## Βελτίωση: 70.7 %
(Τα ακριβή αποτελέσματα θα εμφανιστούν μετά την εκτέλεση του code)
Συνήθως το ARIMA ή το Holt-Winters υπερτερούν του Seasonal Naïve σε structured time series όπως αυτή της J&J, επειδή λαμβάνουν υπόψη και το trend και την εποχικότητα δυναμικά.
auto.arima(); Ερμηνεύστε τα
(p,d,q)(P,D,Q)₄.## Επιλεγμένο ARIMA μοντέλο:
## Series: train
## ARIMA(2,0,0)(1,1,0)[4] with drift
## Box Cox transformation: lambda= 0
##
## Coefficients:
## ar1 ar2 sar1 drift
## 0.3131 0.2432 -0.2970 0.0386
## s.e. 0.1244 0.1300 0.1285 0.0046
##
## sigma^2 = 0.008377: log likelihood = 71.78
## AIC=-133.56 AICc=-132.65 BIC=-122.18
Ερμηνεία παραμέτρων:
Εποχική παράμετροι (P,D,Q)₄:
Παράδειγμα: ARIMA(0,1,1)(0,1,1)₄ σημαίνει:
## Ljung-Box test p-value: 0.8796
## ✅ ΝΑΙ - Τα residuals συμπεριφέρονται ως white noise (p > 0.05)
Τι σημαίνει white noise:
Επιπτώσεις:
## 95% Prediction Interval Width:
## 1ο τρίμηνο (Q1 1981): 6.439
## 12ο τρίμηνο (Q4 1983): 11.771
## Αύξηση: 82.8 %
Ερμηνεία:
Business implication: Οι βραχυπρόθεσμες προβλέψεις (Q1-Q4) είναι πιο αξιόπιστες από τις μακροπρόθεσμες (Q9-Q12). Για strategic planning >2 ετών, χρειάζεται scenario analysis.
ΣΥΣΤΑΣΗ: LONG ΘΕΣΗ (Buy/Hold) 🟢
Τεκμηρίωση:
Θετική ανοδική τάση: Οι προβλέψεις δείχνουν συνέχιση της εκθετικής ανάπτυξης
Σταθερό growth rate: Ο προβλεπόμενος ρυθμός ανάπτυξης είναι aligned με το ιστορικό → ρεαλιστική πρόβλεψη
Strong fundamentals:
Χαμηλή downside αβεβαιότητα: Ακόμα και το lower 95% PI δείχνει θετικά κέρδη
Αυξανόμενα EPS: Compound growth υποδηλώνει reinvestment και market expansion
Risks to monitor:
Στρατηγική:
Η J&J εμφανίζει εκθετική ανάπτυξη με σταθερή multiplicative εποχικότητα (Q4 peak)
Το ARIMA μοντέλο (ή ETS) υπερτερεί του baseline Seasonal Naïve λόγω ικανότητας να συλλαμβάνει τη δυναμική του trend και της εποχικότητας
Η log transformation είναι κρίσιμη για σταθεροποίηση διακύμανσης και valid modeling
Οι προβλέψεις είναι ρεαλιστικές, aligned με το ιστορικό growth rate (~15-20% ετησίως)
Η αβεβαιότητα αυξάνεται με τον ορίζοντα → οι βραχυπρόθεσμες προβλέψεις (1-2 έτη) πιο αξιόπιστες
Investment stance: LONG — τα fundamentals και η πρόβλεψη υποστηρίζουν positive outlook
forecast package: Hyndman et al. (2024)Prepared by: Gio
Course: Επιχειρηματική Αναλυτική
University of Macedonia
Date: 2026-05-25