下品なモデルの着実な美しさ

KDPVにはタイタニックはありません、彼はdr死しました

-統計モデルを作成していただけますか?

-喜んで。 あなたの履歴データを見てもいいですか?

-まだデータがありません。 しかし、モデルはまだ必要です。



なじみのある会話ですね。 さらに、2つのシナリオが可能です。



A.「その後、データが表示されます」オプションは些細なものとはみなされません。

B.「最も重要だと思う要因を教えてください。」この記事の残りの部分では、これについて説明します。



カットの下には、不適切なモデルとは何か、その美しさが持続可能である理由、およびそのコストについての物語があります。 すべては、タイタニックの乗客の生存に関する長期にわたる苦痛のデータセットの例です。



なぜそんな奇妙な名前



仲間のRobyn M. Dawesによる、意思決定における不適切な線形モデルのロバストな美しさによる記事から。



まともな線形モデルとは、結果の線形結合が最適な方法で関心のある量を予測するように重みが割り当てられているモデルです。 例は、最小二乗法によって適合された通常の線形回帰です。 [...]



不適切な線形モデル-重みが非最適に決定されるモデル。 たとえば、直観や以前の経験に基づいて割り当てられたり、統一と見なされたりします。


典型的な線形モデルは次のようになります。



ŷ=β0 +β1 x 1 +β2 x 2 + ... +βm x m



ここで、ŷは従属変数の推定値、β0は自由項、β1 ...βmは回帰係数、x 1 ... x mは独立変数です。



β1 ...βmの値を決定するためのデータがないため、自発的に行動します:+1(プラスの効果)、-1(マイナスの効果)、および0(効果なし)の値を割り当てます。



耳かけの例



記事の冒頭で説明した統計モデルの典型的な例は、消費者貸し出し(クレジットのクライアントによる深刻な遅延または不返還の可能性を予測する)、応答モデル(購入または購読する申し出に応答する顧客の可能性を予測する)製品)、流出モデル(クライアントが競合他社に行く可能性を予測)など。



この記事では、より単純なデータセットを使用します。このデータセットは、機械学習リーダーのトピックに興味のあるすべての人に既に知られている可能性があります。タイタニック号の乗客のリストです。 Habréの以前の記事では、すでにそれを見ました。





競合他社





どのように比較しますか



乗客リストを2つの部分に分割します。1つはモデルをカスタマイズし、もう1つは作業の品質をチェックします。



奇跡は存在せず、知識がなければ説明モデルを構築できません。 この場合、ギャラントリーはそのような知識になります-女性と子供はボートに乗るときに前進することを許可されました。 これに基づいて、単位重量を使用した回帰の事前知識に基づいて、 female



変数を+1に、 age



変数を-1に割り当てます。 さらに、ホールド内にキャビンがある2 pclass



チケットをお持ちのお客様は引き続きボートに向かってpclass



ます。したがって、 pclass



変数にweight -1 pclass



割り当てます。



2回起きないように、すぐに正規化します-トレーニングサンプルの標準偏差で除算します。 これは、独立変数を同等のスケールにするために必要です。 範囲に分割して、同様の結果を得ることができます。



単位重量モデルでは 、スケーリングのために独立変数の標準偏差のみを使用して誰が生存し、誰がdrれたかに関する情報を使用しなかったこと注意してください。



実験を数千回繰り返し、結果を確認します。 モデルの品質は、Gini係数( G1 )を使用して測定されます。



ステップごとのコメント付きのRコード
 install.packages("pROC") install.packages("randomForest") library(pROC) library(randomForest)
      
      





ここから入手可能なソースデータを読み取ります: titanic3.csv





 data <- read.csv('~/habr/unit_weights/titanic3.csv')
      
      





従属変数がsurvived





 data$survived <- as.factor(data$survived)
      
      





通常の分析には異なる値が多すぎる変数を除外します

 data$name <- NULL data$ticket <- NULL data$cabin <- NULL data$home.dest <- NULL data$embarked <- NULL
      
      





将来の変数を使用しないでください

 data$boat <- NULL data$body <- NULL
      
      





欠損値を平均で置き換えます

 data$age[is.na(data$age)] <- mean(data$age, na.rm=TRUE) data$fare[is.na(data$fare)] <- mean(data$fare, na.rm=TRUE)
      
      





性別を指標変数に変換する

 data$female <- 0 data$female[which(data$sex == 'female')] <- 1 data$sex <- NULL
      
      





残っているものを見ます:

  survived pclass age sibsp 0:809 Min. :1.000 Min. : 0.1667 Min. :0.0000 1:500 1st Qu.:2.000 1st Qu.:22.0000 1st Qu.:0.0000 Median :3.000 Median :29.8811 Median :0.0000 Mean :2.295 Mean :29.8811 Mean :0.4989 3rd Qu.:3.000 3rd Qu.:35.0000 3rd Qu.:1.0000 Max. :3.000 Max. :80.0000 Max. :8.0000 parch fare female Min. :0.000 Min. : 0.000 Min. :0.000 1st Qu.:0.000 1st Qu.: 7.896 1st Qu.:0.000 Median :0.000 Median : 14.454 Median :0.000 Mean :0.385 Mean : 33.295 Mean :0.356 3rd Qu.:0.000 3rd Qu.: 31.275 3rd Qu.:1.000 Max. :9.000 Max. :512.329 Max. :1.000
      
      





実験を数千回繰り返します

 im.gini = NULL pm.gini = NULL lr.gini = NULL rf.gini = NULL set.seed(42) for (i in 1:1000) {
      
      





乗客を2つのサンプルに分割します-70%がトレーニングサンプルに送られ、残りの30%でモデルの品質が測定されます。

  data$random_number <- runif(nrow(data),0,1) development <- data[ which(data$random_number > 0.3), ] holdout <- data[ which(data$random_number <= 0.3), ] development$random_number <- NULL holdout$random_number <- NULL
      
      





シングルウェイトモデル

  beta_pclass <- -1/sd(development$pclass) beta_age <- -1/sd(development$age ) beta_female <- 1/sd(development$female) im.score <- beta_pclass*holdout$pclass + beta_age*holdout$age + beta_female*holdout$female im.roc <- roc(holdout$survived, im.score) im.gini[i] <- 2*im.roc$auc-1
      
      





通常のモデルは、同じ独立変数を使用したロジスティック回帰です。

  pm.model = glm(survived~pclass+age+female, family=binomial(logit), data=development) pm.score <- predict(pm.model, holdout, type="response") pm.roc <- roc(holdout$survived, pm.score) pm.gini[i] <- 2*pm.roc$auc-1
      
      





すべての変数を含むロジスティック回帰

  lr.model = glm(survived~., family=binomial(logit), data=development) lr.score <- predict(lr.model, holdout, type="response") lr.roc <- roc(holdout$survived, lr.score) lr.gini[i] <- 2*lr.roc$auc-1
      
      





みんなのお気に入り(理由もなく)RandomForest

  rf.model <- randomForest(survived~., development) rf.score <- predict(rf.model, holdout, type = "prob") rf.roc <- roc(holdout$survived, rf.score[,1]) rf.gini[i] <- 2*rf.roc$auc-1 }
      
      





結果を出力する

 bpd<-data.frame(ImproperModel=im.gini, ProperModel=pm.gini, LogisticRegression=lr.gini, RandomForest=rf.gini) png('~/habr/unit_weights/auc_comparison.png', height=700, width=400, res=120, units='px') boxplot(bpd, las=2, ylab="Gini", ylim=c(0,1), par(mar=c(9,5,1,1)+ 0.1), col=c("red","green","royalblue2","brown")) dev.off() mean(im.gini) mean(pm.gini) mean(lr.gini) mean(rf.gini) mean(im.gini)/mean(rf.gini) mean(pm.gini)/mean(rf.gini) mean(lr.gini)/mean(rf.gini) mean(rf.gini)/mean(rf.gini)
      
      







結果



モデル ジニ 最高の割合
ImproperModel 0.639 90.4%
適切なモデル 0.667 94.3%
ロジスティック回帰 0.679 96.0%
ランダムフォレスト 0.707 100%




広範囲にわたる結論



悲観論者は、この比較で単位重量を持つモデルが最後の場所を占めたと言うでしょう。これは本当です。 しかし、 履歴データを使用せずに最高の結果の90%を獲得し、同じ独立変数を使用した通常のロジスティック回帰に4%しか遅れていないことも事実です。



なぜこれが起こっているのですか



珍しいタイトル「 線形モデルでの係数の推定:決して気にしないで」の記事でその著者(Howard Weiner)は次の等しい重みの定理を与えています:



平均値と単位分散がゼロのk個の線形独立変数x i (i = 1、...、k)を使用して変数yを予測し、変数yも平均値と単位分散がゼロにスケーリングされ、標準化された最小二乗回帰係数βi(i = 1、...、k)は区間[0.25、0.75]に均一に分布しているため、等しい重み(0.5)になると、モデルで説明される従属変数の分散割合の減少はk / 96未満になります。 x iが互いに相関している場合、損失はさらに少なくなります。


上記の例では、回帰はロジスティックですが、効果はまだ見えています。



さらに同じ記事で、著者は、特にトレーニングセット内の外れ値の影響を受けず、オーバートレーニングできないため、単位重量を持つモデルは安定していると述べています。



All Articles