Το dataset που χρησιμοποιείται σε αυτή την ανάλυση προέρχεται από το Kaggle.com. Περιλαμβάνει πληροφορίες για 45 χαρακτήρες από το σύμπαν της Marvel, προσφέροντας μια συναρπαστική ματιά στους ήρωες, κακούς και αντιήρωες που πρωταγωνιστούν στις επικές ιστορίες της Marvel. Το dataset αποτελείται από τις εξής στήλες:
Αυτό το dataset επιλέχθηκε λόγω της πλούσιας πληροφορίας που παρέχει για τους χαρακτήρες της Marvel, επιτρέποντας την εξερεύνηση μοτίβων και τη δημιουργία προβλέψεων για τη δυναμική των ομάδων και των ρόλων τους στο σύμπαν της Marvel.
Αυτή η αναφορά εξετάζει ένα ερώτημα στο σύμπαν της Marvel: Ποιοι χαρακτήρες είναι πιθανό να ανήκουν σε ελίτ ομάδες,Θεωρούμε ως «ελίτ» ομάδες τις Avengers, X-Men, και Guardians of the Galaxy, καθώς είναι οι πιο εμβληματικές και ισχυρές ομάδες στο Marvel σύμπαν.Η ένταξη σε μια ελίτ ομάδα όπως οι Avengers απαιτεί ξεχωριστές δυνάμεις και συγκεκριμένους ρόλους (π.χ., οι Ήριδες είναι πιο πιθανό να επιλεγούν). Αυτός ο σκοπός είναι ευφάνταστος, καθώς εξετάζει την «καταλληλότητα» για υψηλού κύρους ομάδες, κάτι που δεν υπάρχει ρητά στο dataset αλλά μπορεί να συναχθεί από το Affiliation. Είναι σχετικό με το Marvel σύμπαν, καθώς οι ελίτ ομάδες είναι κεντρικές στις ιστορίες. Χρησιμοποιώντας λογιστική παλινδρόμηση, προβλέπουμε αν ένας χαρακτήρας είναι μέλος μιας τέτοιας ομάδας με βάση τις Δυνάμεις (Powers) και τον Ρόλο (Role). Το dataset περιλαμβάνει 45 χαρακτήρες με πληροφορίες για Όνομα, Πραγματικό Όνομα, Ομάδα, Δυνάμεις, Ρόλο και Επίπεδο Ισχύος. Στόχος μας είναι να αποκαλύψουμε τα χαρακτηριστικά που καθιστούν έναν χαρακτήρα κατάλληλο για τις πιο εμβληματικές ομάδες της Marvel και να παρουσιάσουμε τα ευρήματα με δημιουργικό και ευανάγνωστο τρόπο.
Το dataset περιλαμβάνει:
Ορίζουμε:
Οι στήλες Character, Real Name και Power Level αποκλείονται (Power Level σταθερό).
# Φόρτωση του dataset
data <- read.csv("marvel_characters_dataset.csv")
# Δημιουργία εξαρτημένης μεταβλητής
elite_teams <- c("Avengers", "X-Men", "Guardians of the Galaxy")
data$Elite_Team <- ifelse(data$Affiliation %in% elite_teams, 1, 0)
# Σύντομη περίληψη
str(data)## 'data.frame': 45 obs. of 7 variables:
## $ Character : chr "iron man" "captain america" "thor" "black widow" ...
## $ Real.Name : chr "Tony Stark" "Steve Rogers" "Thor Odinson" "Natasha Romanoff" ...
## $ Affiliation: chr "Avengers" "Avengers" "Avengers" "Avengers" ...
## $ Powers : chr "Powered Armor, Genius-level intellect" "Super Soldier, Enhanced strength" "God of Thunder, Weather manipulation" "Superhuman strength, Espionage" ...
## $ Role : chr "Hero" "Hero" "Hero" "Hero" ...
## $ Power.Level: chr "Low" "Low" "Low" "Low" ...
## $ Elite_Team : num 1 1 1 1 1 1 1 0 1 1 ...
## Character Real.Name Affiliation Powers Role Power.Level
## 0 0 0 0 0 0
## Elite_Team
## 0
# Επιλογή στηλών και μετατροπή σε παράγοντες
model_data <- data %>%
select(Elite_Team, Powers, Role) %>%
mutate(Powers = factor(Powers),
Role = factor(Role))
# Φιλτράρισμα σπάνιων κατηγοριών για Powers
powers_counts <- table(model_data$Powers)
model_data <- model_data %>%
filter(Powers %in% names(powers_counts[powers_counts >= 2]))
# Επανακαθορισμός επιπέδων
model_data$Powers <- factor(model_data$Powers)
model_data$Role <- factor(model_data$Role)
# Έλεγχος μεγέθους δεδομένων
cat("Συνολικές εγγραφές μετά το φιλτράρισμα:", nrow(model_data), "\n")## Συνολικές εγγραφές μετά το φιλτράρισμα: 13
Διαχωρίζουμε το dataset σε σύνολα εκπαίδευσης (65%) και δοκιμής (35%) με seed 999.
# Ορισμός seed
set.seed(999)
# Διαχωρισμός δεδομένων
split <- sample.split(model_data$Elite_Team, SplitRatio = 0.65)
train <- subset(model_data, split == TRUE)
test <- subset(model_data, split == FALSE)
# Εξασφάλιση συνεπών factor levels
all_powers_levels <- levels(model_data$Powers)
all_role_levels <- levels(model_data$Role)
train$Powers <- factor(train$Powers, levels = all_powers_levels)
test$Powers <- factor(test$Powers, levels = all_powers_levels)
train$Role <- factor(train$Role, levels = all_role_levels)
test$Role <- factor(test$Role, levels = all_role_levels)
# Αφαίρεση από το test set κατηγοριών που δεν υπάρχουν στο train set
test <- test %>%
filter(Powers %in% levels(train$Powers)[table(train$Powers) > 0])
# Έλεγχος ενεργών επιπέδων στο train set
cat("Powers levels in train:", paste(levels(train$Powers)[table(train$Powers) > 0], collapse = ", "), "\n")## Powers levels in train: Flight, Superhuman strength, Cosmic energy, Magical powers, Superhuman strength, Durability, Superhuman strength, Regeneration
cat("Role levels in train:", paste(levels(train$Role)[table(train$Role) > 0], collapse = ", "), "\n")## Role levels in train: Hero, Villain
# Αριθμός εγγραφών
nrow_train <- nrow(train)
nrow_test <- nrow(test)
cat("Εγγραφές στο train set:", nrow_train, "\n")## Εγγραφές στο train set: 8
## Εγγραφές στο test set: 1
Το σύνολο εκπαίδευσης περιλαμβάνει 8 εγγραφές, και το σύνολο δοκιμής 1 εγγραφές.
Οπτικοποιούμε την κατανομή των χαρακτήρων που ανήκουν ή όχι σε ελίτ ομάδες.
# Έλεγχος δεδομένων για το διάγραμμα
if (nrow(train) == 0) stop("Το train set είναι κενό, δεν μπορεί να δημιουργηθεί διάγραμμα.")
ggplot(train, aes(x = factor(Elite_Team), fill = factor(Elite_Team))) +
geom_bar() +
labs(title = "Κατανομή Μελών Ελίτ Ομάδων στο Train Set",
x = "Μέλος Ελίτ Ομάδας (1 = Ναι, 0 = Όχι)", y = "Αριθμός Χαρακτήρων") +
scale_fill_manual(values = c("#999999", "#1f77b4"), labels = c("Μη Μέλος", "Μέλος")) +
theme_minimal() +
theme(legend.title = element_blank(),
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
axis.title = element_text(size = 12))Το διάγραμμα δείχνει την αναλογία χαρακτήρων που ανήκουν σε ελίτ ομάδες, αποκαλύπτοντας πιθανή ανισορροπία που μπορεί να επηρεάσει το μοντέλο.
Δημιουργούμε το μοντέλο, εξασφαλίζοντας ότι όλες οι μεταβλητές έχουν τουλάχιστον δύο ενεργά επίπεδα.
# Έλεγχος για επαρκή επίπεδα
active_powers <- levels(train$Powers)[table(train$Powers) > 0]
active_role <- levels(train$Role)[table(train$Role) > 0]
if (length(active_powers) < 2) stop("Η μεταβλητή Powers έχει λιγότερα από 2 επίπεδα: ", paste(active_powers, collapse = ", "))
if (length(active_role) < 2) stop("Η μεταβλητή Role έχει λιγότερα από 2 επίπεδα: ", paste(active_role, collapse = ", "))
# Δημιουργία μοντέλου
model <- glm(Elite_Team ~ Powers + Role,
data = train,
family = binomial(link = "logit"))
# Περίληψη μοντέλου
summary(model)##
## Call:
## glm(formula = Elite_Team ~ Powers + Role, family = binomial(link = "logit"),
## data = train)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 21.566 29232.438 0.001 0.999
## PowersMagical powers 19.051 36613.646 0.001 1.000
## PowersSuperhuman strength, Durability -42.380 32495.242 -0.001 0.999
## PowersSuperhuman strength, Regeneration -1.257 33129.251 0.000 1.000
## RoleVillain -40.617 22045.944 -0.002 0.999
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 10.5850 on 7 degrees of freedom
## Residual deviance: 2.7726 on 3 degrees of freedom
## AIC: 12.773
##
## Number of Fisher Scoring iterations: 20
Η περίληψη δείχνει συντελεστές και p-values. Σημαντικές μεταβλητές (p < 0.05) συνδέονται ισχυρά με την πιθανότητα ένταξης σε ελίτ ομάδες.
Παράδειγμα: Αν το RoleHero έχει p-value < 0.05,
υποδηλώνει ισχυρή σχέση με την ένταξη σε ελίτ ομάδες.
Οπτικοποιούμε όλους τους συντελεστές του μοντέλου για να κατανοήσουμε τη συμβολή κάθε μεταβλητής.
# Εξαγωγή συντελεστών
coef_data <- tidy(model)
# Έλεγχος δεδομένων για το διάγραμμα
if (nrow(coef_data) == 0) stop("Δεν υπάρχουν συντελεστές για οπτικοποίηση.")
ggplot(coef_data, aes(x = reorder(term, estimate), y = estimate, fill = p.value < 0.05)) +
geom_bar(stat = "identity") +
coord_flip() +
labs(title = "Συντελεστές Λογιστικής Παλινδρόμησης",
x = "Μεταβλητή", y = "Συντελεστής") +
scale_fill_manual(values = c("#999999", "#1f77b4"), labels = c("p ≥ 0.05", "p < 0.05")) +
theme_minimal() +
theme(legend.title = element_blank(),
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
axis.title = element_text(size = 12))Οι μπλε μπάρες υποδεικνύουν σημαντικούς συντελεστές, βοηθώντας στην κατανόηση των πιο επιδραστικών παραγόντων.
Προβλέπουμε τις πιθανότητες ένταξης σε ελίτ ομάδες στο test set.
# Πρόβλεψη πιθανοτήτων
predictTest <- predict(model, newdata = test, type = "response")
# Εμφάνιση πρώτων προβλέψεων
head(predictTest)## 1
## 5.323298e-09
Οι τιμές του predictTest δείχνουν την πιθανότητα κάθε
χαρακτήρα να είναι μέλος μιας ελίτ ομάδας. Τιμές κοντά στο 1 υποδηλώνουν
υψηλή καταλληλότητα, ενώ κοντά στο 0 χαμηλή. Αυτές οι πιθανότητες
εντοπίζουν χαρακτήρες που θα μπορούσαν να λάμψουν σε ομάδες όπως οι
Avengers.