Calm Hill My Random Thoughts

Machine Learning from Disaster with Titanic (3)

ဒုတိယပိုင်းမှာ ရှိပြီးသား Data တွေကို Method အမျိုးမျိုးနဲ့ အစားထိုးပြီးတော့ စမ်းသပ်ကြည့်ခဲ့တယ် Performance လည်း ရသင့်သလောက်လည်း ရလာခဲ့ပါတယ် ဒီတခါတော့ ရှိပြီးသား Data ကို ဘယ်လောက် ပိုကောင်းအောင် လုပ်လို့ရနိုင်လဲ ပြန်စဉ်းစားကြည့်မယ်။ ပထမပိုင်းမှာ ရေးခဲ့စဉ်ကတည်းက အရေးအကြီးဆုံးဖြစ်တဲ့ Age မှာ Missing Data (NAs) တွေ အတော်များတယ်လို့ ကြိုပြီးတော့ရေးခဲ့တယ် Training Data 891 မှာ NAs က 177 ခုပါနေတဲ့အတွက် 20% နီးနီးပျောက်နေတယ် Training မှာတင် မဟုတ်ပါဘူး Testing မှာလည်း ဖြစ်နေတာပါ။ အရင်ကတော့ ပျောက်နေတဲ့ တန်ဖိုးတွေကို Mean value နဲ့ အစားထိုးပြီးသုံးနေတာ အကယ်၍များ Mean ထက် ပိုပြီးတော့ ကောင်းတဲ့ တန်ဖိုးတခုခုကို ခန့်မှန်းပေးနိုင်ရင် အဖြေတွေဟာ ပိုကောင်းလာနိုင်တယ်ဆိုတဲ့ ယူဆချက်ကို အခြေခံပြီးတော့ ဒီတခါစမ်းကြည့်မယ်။

 > summary(train$Age)
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    0.42   20.12   28.00   29.70   38.00   80.00     177
 > summary(test$Age)
    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
    0.17   21.00   27.00   30.27   39.00   76.00      86

အသက်ကိုမှန်းရတာက နည်းနည်းခက်တယ် Data ထဲမှာ Personal Data ဆိုလို့ SibSp, Parch ၂ ခုပဲ အသုံးဝင်နိုင်တာပါတယ် အဲဒီ ၂ ခုနဲ့တော့ အသက်ကိုမှန်းတာ ကောင်းပါ့မယ်လို့ အာမခံဖို့လည်းခက်တယ်။ Data တွေကို အသေးစိတ် လိုက်ကြည့်မယ်ဆိုရင် Name တွေဟာ “Family Name, Title. First Name” ဆိုတဲ့ Format မျိုးနဲ့ ရေးထားတာရှိတယ်။ Title ဟာ Age အတွက် အသုံးတည့်ကောင်းတည့်နိုင်တယ် ဥပမာဆိုရင် Mrs, Ms နဲ့ Miss မှာဆိုရင် ယေဘုယျအားဖြင့် Ms ဟာ Mrs ထက် အသက်ငယ်ဖို့များပါလိမ့်မယ် Exception ဖြစ်နေတာမျိုးကတော့ မတတ်နိုင်ဘူး Error ထဲကို ထည့်ရတော့မှာပေါ့လေ Miss ကတော့ အငယ်ဆုံးဖြစ်မယ်။ Name ကို တစစီခွဲထုတ်ပြီးတော့ ထွက်လာတဲ့ Data တွေကို ကြည့်လိုက်တော့ အတော်လေး အသုံးဝင်နိုင်မယ် ယူဆမိတယ်။

 > train$FamilyName = as.factor(sapply(train$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][1]}))
 > test$FamilyName = as.factor(sapply(test$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][1]}))
 > train$Title = as.factor(sapply(train$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][2]}))
 > test$Title = as.factor(sapply(test$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][2]}))
 > table(train$Title)

          Capt           Col           Don            Dr      Jonkheer          Lady         Major 
             1             2             1             7             1             1             2 
        Master          Miss          Mlle           Mme            Mr           Mrs            Ms 
            40           182             2             1           517           125             1 
           Rev           Sir  the Countess 
             6             1             1
 > table(test$Title)

     Col    Dona      Dr  Master    Miss      Mr     Mrs      Ms     Rev 
       2       1       1      21      78     240      72       1       2

Age ကို ခန့်မှန်းတာက အသက်ရှင်နိုင် မရှင်နိုင်ခန့်မှန်းသလို Classification မဟုတ်ပါဘူး Prediction ဖြစ်တဲ့အတွက် Linear Regression လို Method တွေကိုသုံးပြီးတော့ ခန့်မှန်းရလိမ့်မယ် တခြားသင့်လျော်ရာ Method တွေလည်း သုံးလို့ရနိုင်ပါတယ် ပိုကောင်းချင်လည်း ကောင်းပါလိမ့်မယ် ဒီမှာကတော့ Linear Regression ပဲသုံးပြီးစမ်းကြည့်ထားတယ်။ Age ဟာ Training တင်မဟုတ်ဘူး Testing မှာပါ ပျောက်နေတဲ့အတွက် Dataset ၂ ခုလုံးကို ပေါင်းပြီးတော့ Model Train လုပ်ပြီးတော့ Age ကိုခန့်မှန်းပြီး NA ဖြစ်နေတဲ့ နေရာတွေမှာပဲ ခန့်မှန်းထားတဲ့ တန်ဖိုးကို အစားထိုးပါတယ် ဒီနေရာမှာလည်း SibSp, Parch, Title တွေတင်မကပဲ တခြား Features တွေလည်း ယူသုံးလို့ရမရ စမ်းကြည့်ချင်တယ်ဆိုရင် ဆက်ပြီးတော့လည်း စမ်းကြည့်လို့ရပါတယ်။

 > test$Survived = NA
 > all = rbind(train, test)
 > model = lm(Age ~ Title + SibSp + Parch, all)
 > train$AgePredicted = predict(model, newdata = train)
 > train$Age[is.na(train$Age)] = train$AgePredicted[is.na(train$Age)]
 > test$AgePredicted = predict(model, newdata = test)
 > test$Age[is.na(test$Age)] = test$AgePredicted[is.na(test$Age)]
 > train$AgePredicted = NULL
 > test$AgePredicted = NULL
 > test$Survived = NULL
 > write.csv(train, file = "train_predicted_age.csv", row.names = FALSE)
 > write.csv(test, file = "test_predicted_age.csv", row.names = FALSE)

Age ကို ခန့်မှန်းထားတဲ့ Data တွေကိုသုံးပြီးတော့ Logistic Regression, Decision Tree နဲ့ Random Forest တွေကို Apply ကြည့်တော့ Submission Score တွေက 0.77990, 0.79904 နဲ့ 0.78469 ဆိုပြီးတော့ရှိတော့ Mean Age နဲ့ Data ကိုသုံးစဉ်ကရတဲ့ 0.76555, 0.78469 နဲ့ 0.77033 နဲ့ယှဉ်ကြည့်မယ်ဆိုရင် ခန့်မှန်းထားတဲ့ Age နဲ့ Data ဟာ Mean Age ထက် ပိုကောင်းတာ တွေ့ရလိမ့်မယ်။ ထပ်လုပ်လို့ရတာတွေက Age ကိုခန့်မှန်းတာမှာ ထပ်လုပ်ကြည့်လို့ရတာက တချို့ Title တွေကို ပေါင်းလိုက်ရင် ခန့်မှန်းတာမှာ ပိုအဆင်ပြေလိမ့်မယ် Capt, Col, Don, Dr, Rev, Sir စသည်ဖြင့်တွေကို Mr ထဲထည့် Dona, Lady, the Countess တွေကို Ms ကိုပေါင်း Mlle နဲ့ Miss နဲ့ စသည်ဖြင့် ဆင်တူရာတွေ ပေါင်းလိုက်မယ်ဆိုရင် ခန့်မှန်းတာ ပိုကောင်းလာနိုင်တယ် အရေတွက် သိပ်မများတဲ့အတွက် သိသာချင်မှလည်း သိသာမှာပါ။ နောက်ပြီးတော့ Family Name ကိုလည်း Model ထဲမှာ ယူသုံးကြည့်လို့ ရနိုင်သေးပါသေးတယ် နောက်တခါမှ ထပ်ပြီးတော့ စမ်းကြည့်တာပေါ့။