🔹 Περιγραφή του συνόλου δεδομένων

Το επιλεγμένο σύνολο δεδομένων περιέχει πληροφορίες σχετικά με διάφορα μοντέλα φορητών υπολογιστών, τις προδιαγραφές τους και τις αντίστοιχες τιμές τους. Είναι χρήσιμο για την ανάλυση του τρόπου με τον οποίο διάφορα χαρακτηριστικά (όπως η μάρκα, το μέγεθος της οθόνης, η μνήμη RAM και ο επεξεργαστής) επηρεάζουν την τιμή ενός φορητού υπολογιστή. Αυτό το σύνολο δεδομένων μπορεί να βοηθήσει τις επιχειρήσεις, τους καταναλωτές και τους αναλυτές να κατανοήσουν τις τάσεις της αγοράς και τις στρατηγικές τιμολόγησης.

Link for the dataset(Kaggle.com)

🔹 Προετοιμασία του συνόλου δεδομένων

  1. Μετατροπή των Inches και RAM.
    Στο αρχικό Dataset, τα attributes Inches, Weight και RAM ήταν τύπου Categorical, παρά το γεγονός ότι ήταν νούμερα.
    Έγινε η μετατροπή τους σε Numeric για την καλύτερη ερμηνεία του συνόλου.

  2. Μετατροπή των τιμών.
    Οι τιμές των φορητών υπολογιστών ήταν εκφρασμένες σε Ρουπία Ινδίας.
    Αυτές μετατράπηκαν σε ευρώ και έγινε στρογγυλοποίηση των 2 δεκαδικών στοιχείων για καλύτερη κατανόηση του συνόλου.

  3. Έλεγχος και χειρισμός ελλιπών τιμών.
    Τα αντικείμενα του συνόλου δεδομένων ήταν 1303.
    Μετά τον έλεγχο για διπλότυπα και την αφαίρεση των ελλιπών τιμών,
    έμειναν 1273 αντικείμενα.

    Εικόνα 1: OpenRefine Preproccesing Steps
    Εικόνα 1: OpenRefine Preproccesing Steps

🔹 Χαρακτηριστικά του συνόλου δεδομένων

kable(df, format = "html", align = "c", escape = FALSE) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, position = "center") %>%
  column_spec(3, bold = TRUE)
Χαρακτηριστικό Περιγραφή Τύπος
Εταιρεία Η μάρκα του φορητού υπολογιστή (π.χ. Dell, HP, Apple). Categorical
TypeName Η κατηγορία/ο τύπος του φορητού υπολογιστή (π.χ. Gaming, Ultrabook, Notebook). Categorical
Inches Το μέγεθος της οθόνης του φορητού υπολογιστή σε ίντσες. Numeric
ScreenResolution Η ανάλυση της οθόνης (π.χ. 1920x1080, 4K). Categorical
CPU Τα στοιχεία του επεξεργαστή (π.χ. Intel Core i5, AMD Ryzen 7). Categorical
RAM Η ποσότητα της μνήμης τυχαίας προσπέλασης (RAM) σε gigabytes (GB). Numeric
Μνήμη Ο τύπος και το μέγεθος του αποθηκευτικού χώρου (π.χ. 256 GB SSD, 1 TB HDD). Categorical
GPU Η μονάδα επεξεργασίας γραφικών (π.χ. NVIDIA GTX 1650, Intel HD Graphics). Categorical
Βάρος Το βάρος του φορητού υπολογιστή σε κιλά(kg). Numeric
Λειτουργικό Σύστημα Το λειτουργικό σύστημα του φορητού υπολογιστή (π.χ. Windows, macOS, Linux). Categorical
Τιμή Η τιμή του φορητού υπολογιστή σε Ευρώ. Numeric
IsExpensive Κατηγοριοποιεί τα λάπτοπ σε ακριβά και μη ακριβά εάν η τιμή τους ξεπερνάει τα 800 ευρώ Boolean

🔹 Διαχωρισμός του συνόλου σε Train και Test

Για τον διαχωρισμό του συνόλου δεδομένων χρησιμοποίησα την μεταβλητή IsExpensive. Το training set είναι το 65% της βάσης με seed 953.

library(caTools)
set.seed(953)

split <- sample.split(laptopData$IsExpensive,SplitRatio=0.65)

dataTrain = subset(laptopData, split == TRUE)
dataTest = subset(laptopData, split == FALSE)

Παρατηρώ ότι οι καταχωρήσεις στο Train-set είναι:

nrow(dataTrain)
## [1] 827

ενώ στο Test-set:

nrow(dataTest)
## [1] 445

🔹 Μοντέλο λογιστικής παλινδρόμησης

Για την δημιουργία του μοντέλου λογιστικής παλινδρόμησης μετέτρεψα τις κατηγορικές μεταβλητές σε factors και επειδή αυτές είχαν πολλά επίπεδα, κράτησα μόνο τα 5 δημοφιλέστερα επίπεδα κάθε κατηγορίας και τα υπόλοιπα μπήκαν στο επίπεδο “Other” κάθε μεταβλητής.

library(forcats)
# Ομαδοποίηση: κρατάμε τα top 5 και τα υπόλοιπα πάνε σε "Other"
dataTrain$Gpu <- fct_lump(as.factor(dataTrain$Gpu), n = 5)
dataTrain$Cpu <- fct_lump(as.factor(dataTrain$Cpu), n = 5)
dataTrain$Company <- fct_lump(as.factor(dataTrain$Company), n = 5)
dataTrain$OpSys <- fct_lump(as.factor(dataTrain$OpSys), n = 5)
dataTrain$TypeName <- fct_lump(as.factor(dataTrain$TypeName), n = 5)
dataTrain$ScreenResolution <- fct_lump(as.factor(dataTrain$ScreenResolution), n = 5)
dataTrain$Memory <- fct_lump(as.factor(dataTrain$Memory), n = 5)

# Λογιστική Παλινδρόμηση με όλες τις ανεξάρτητες μεταβλητές
laptopmodel <- glm(IsExpensive ~ . - Price - Unnamed..0, 
                   data = dataTrain, family = "binomial")

library(car)
Anova(laptopmodel, type = "II") 
## Analysis of Deviance Table (Type II tests)
## 
## Response: IsExpensive
##                  LR Chisq Df Pr(>Chisq)    
## Company             7.988  5   0.156910    
## TypeName           48.766  5  2.478e-09 ***
## Inches              0.042  1   0.837084    
## ScreenResolution   19.666  5   0.001444 ** 
## Cpu                12.455  5   0.029060 *  
## Ram                47.009  1  7.066e-12 ***
## Memory             35.292  5  1.316e-06 ***
## Gpu                49.860  5  1.480e-09 ***
## OpSys              16.524  5   0.005497 ** 
## Weight              2.817  1   0.093254 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
laptopmodel_updated <- glm(IsExpensive ~ Ram + ScreenResolution, 
                   data = dataTrain, family = "binomial")

Παρατηρώ ότι, βάση του significance, οι μεταβλητές ScreenResolution και Ram έχουν ισχυρή συσχέτιση με την εξαρτημένη IsExpensive, οπότε αυτές θα χρησιμοποιηθούν για την δημιουργία διαγράμματος λογιστικής παλινδρόμησης παρακάτω:

ggplot(dataTrain, aes(x = Ram, y = IsExpensive, color = ScreenResolution)) + 
  geom_point() +
  geom_smooth(method = "glm", method.args = list(family = "binomial")) +
  labs(title = "Logistic Regression Plot for variables Ram and ScreenResolution",
       x = "Independent Variable (RAM)",
       y = "Probability") +
  theme_minimal()

🔹 Πρόβλεψη τιμών test set

Για την πρόβλεψη των τιμών του test set, αρχικά πραγματοποιήθηκαν οι ίδιες μετατροπές στις κατηγορικές μεταβλητές όπως και στο train set. Στη συνέχεια, δημιουργήθηκε το μοντέλο πρόβλεψης predictTest, το οποίο βασίζεται στο μοντέλο laptopmodel_updated και χρησιμοποιεί τις μεταβλητές με τη μεγαλύτερη συσχέτιση για να κάνει προβλέψεις στο test set.

# Επικαιροποίηση του test set ανάλογα με το train set
dataTest$Gpu <- fct_other(dataTest$Gpu, keep = levels(dataTrain$Gpu))
dataTest$Cpu <- fct_other(dataTest$Cpu, keep = levels(dataTrain$Cpu))
dataTest$Company <- fct_other(dataTest$Company, keep = levels(dataTrain$Company))
dataTest$OpSys <- fct_other(dataTest$OpSys, keep = levels(dataTrain$OpSys))
dataTest$TypeName <- fct_other(dataTest$TypeName, keep = levels(dataTrain$TypeName))
dataTest$ScreenResolution <- fct_other(dataTest$ScreenResolution, keep = levels(dataTrain$ScreenResolution))
dataTest$Memory <- fct_other(dataTest$Memory, keep = levels(dataTrain$Memory))

predictTest <- predict(laptopmodel_updated, newdata = dataTest, type = "response")

# Επιλέγουμε τυχαία 10 θέσεις από το test set
sample_indices <- sample(1:length(predictTest), 10)

# Εμφανίζουμε τις αντίστοιχες τιμές
predictTest[sample_indices]
##         244         118         626         346        1203         527 
## 0.731379427 0.731379427 0.789180710 0.003665497 0.403692022 0.227792911 
##         530         942        1147         282 
## 0.403692022 0.056808559 0.056808559 0.001945437
# Δημιουργία threshold
predictedClass <- ifelse(predictTest > 0.75, 1, 0)

# Εξάλειψη των γραμμών που έχουν NA στην πρόβλεψη
valid <- !is.na(predictedClass) & !is.na(dataTest$IsExpensive)

# Υπολογισμός της ακρίβειας χωρίς τις NA τιμές
mean(predictedClass[valid] == dataTest$IsExpensive[valid])
## [1] 0.7977528

Παραπάνω εμφανίζονται οι πιθανότητες, από τυχαίες εγγραφές του dataset, τα λάπτοπ να είναι ακριβά. Ορίζοντας ως threshold το 0.75, θεωρούμε ότι ένα λάπτοπ προβλέπεται ως “ακριβό” όταν η πιθανότητα να ανήκει στην κατηγορία των ακριβών είναι μεγαλύτερη η ίση με 0.75. Αντίστοιχα, αν η πιθανότητα είναι μικρότερη από 0.75, το λάπτοπ προβλέπεται ως “μή ακριβό”. Τέλος, η ακρίβεια του μοντέλου για το συγκεκριμένο test-set είναι 79,7%, όπως φαίνεται και παραπάνω.