どうも、solobochiのbochiです。
昨年、データサイエンティスト協会主催のデータサイエンティスト養成講座を受講し、その中でRを使ったデータ分析手法を学んだのでその復習兼ねてまとめておきます。
前回記事↓の続きです。
目次
-
- 概要(※前回記事参照)
- データセット(※前回記事参照)
- データ分析(※前回記事参照)
- 前処理
- モデル構築(※別記事参照)
- 改善(※別記事参照)
- 評価(※別記事参照)
4.前処理
データ分析で最も労力を割く部分であり、データ分析の90%ともいわれるデータの前処理。
具体的には、以下のような作業。
・欠損(システム的な欠損(N/A)だけでなく業務的な欠損(unknownや一律0など)も含む)
・負値
・重複
・変数の加工(※型変換、10倍、1/10倍、平均を取るなどして使いやすい形に加工する)
・変数の作成(※閾値を設けてダミー変数もしくは数値データに変換、パーセンタイル点を境にダミー変数化など)
・変数の作成(※複数条件を設定して条件に合致するか否かでダミー変数化、カテゴリ変数の文字列先頭に応じて数値データ化など)
・ダミー変数化(カテゴリ変数に対して使用して、そのvalueの分だけダミー変数の列を自動的に作成する)
まず欠損について確認。
table(is.na(train_data))
👉N/AがあればTRUEの件数が表示されるため、今回はN/Aはないことがわかる
N/Aではなく、unknownのデータがどの列に存在するかを確認する。
table(is.na(train_data))
👉3列目:job、5列目:education、10列目:contact、17列目:poutcomeにunknownのデータがあることがわかる
具体的には、
・job
・education
・contact
👉特に有用そうでもなく全体の25%ほどが欠損なのでこのカラムは使わない
・poutcome
👉全体の80%近くが欠損のためこのカラムは使わないとするか、successだった時の成約率の高さに注目してsuccessかどうかのダミー変数に加工して使うかはトライアンドエラーで。
続いて負値補正。
summary(train_data)
使ったコマンド summary
使用目的:基本統計量の取得
使用方法:summary(dataframe)
👉pdaysに負値が存在するので補正する。
train_data_pre2$pdays[train_data_pre2$pdays < 0] <- 0 summary(train_data) summary(train_data_pre2)
👉pdaysの負値を補完
次に、分析しやすいように変数を加工する。
・age
train_data_pre2$age_range <- trunc(train_data_pre2$age/10)*10 train_g2 <- dplyr::group_by(train_data_pre2,age_range) dplyr::summarise(train_g2,n=n(),mean=mean(y)) train_g2
👉若年層と高齢層で成約率が高そう
使ったコマンド summarise
使用目的:統計量を算出する、事前にgroupbyでグループ化しておくとグループごとの集計で算出できる
使用方法:dplyr::summarise(dataframe, xxx(mean,min,max,median))
・balance
train_data_pre2 <- train_data_pre2 %>% dplyr::mutate(balance_range = ifelse(balance<0,0, ifelse(balance<100,1, ifelse(balance<200,2, ifelse(balance<500,3, ifelse(balance<1000,4, ifelse(balance<2000,5, ifelse(balance<5000,6,7))))))))
👉保有資産について、0、100、200、500、1000、2000、5000を閾値としてラベリング。
👉資産が増加するほど成約率も上がっていて正の相関が見られる。
👉グルーピングしてラベリングすることで、少数の特異値による影響を抑えることができて傾向が掴めるようになる。データ数が限定的な場合に有効な手法。
・day
train_data_pre2$day_range = ifelse(train_data_pre2$day<11,1, ifelse(train_data_pre2$day<21,2,3)) select(.data=train_data_pre2,day,day_range)
train_g2 <- dplyr::group_by(train_data_pre2,day_range) dplyr::summarise(train_g2,n=n(),mean=mean(y)) train_g2
👉上旬(1日〜10日)、中旬(11日〜19日)、下旬(20日〜31日)にラベリング。
使ったコマンド select
使用目的:データフレームの列を抽出する
使用方法:dplyr::summarise(dataframe, xxx(mean,min,max,median))
・month
train_data_pre2 <- train_data_pre2 %>% dplyr::mutate(month_label = ifelse(month=="jan",1, ifelse(month=="feb",2, ifelse(month=="mar",3, ifelse(month=="apr",4, ifelse(month=="may",5, ifelse(month=="jun",6, ifelse(month=="jul",7, ifelse(month=="aug",8, ifelse(month=="sep",9, ifelse(month=="oct",10, ifelse(month=="nov",11, ifelse(month=="dec",12,0))))))))))))) train_g2 <- dplyr::group_by(train_data_pre2,month_label) dplyr::summarise(train_g2,n=n(),mean=mean(y))
👉7月、8月に比べて3月、4月、9月、10月の方が成約率が高い傾向にある
成約率でソートした結果がこちら↓
そこで、各月の上旬、中旬、下旬を表す変数を作成します。
train_data_pre2 <- train_data_pre2 train_data_pre2$month_BME = ifelse(train_data_pre2$month_label==3 && train_data_pre2$day_range==1,1, ifelse(train_data_pre2$month_label==3 && train_data_pre2$day_range==2,2, ifelse(train_data_pre2$month_label==3 && train_data_pre2$day_range==3,3, ifelse(train_data_pre2$month_label==12 && train_data_pre2$day_range==1,4, ifelse(train_data_pre2$month_label==12 && train_data_pre2$day_range==2,5, ifelse(train_data_pre2$month_label==12 && train_data_pre2$day_range==3,6, ifelse(train_data_pre2$month_label==9 && train_data_pre2$day_range==1,7, ifelse(train_data_pre2$month_label==9 && train_data_pre2$day_range==2,8, ifelse(train_data_pre2$month_label==9 && train_data_pre2$day_range==3,9, ifelse(train_data_pre2$month_label==10 && train_data_pre2$day_range==1,10, ifelse(train_data_pre2$month_label==10 && train_data_pre2$day_range==2,11, ifelse(train_data_pre2$month_label==10 && train_data_pre2$day_range==3,12, ifelse(train_data_pre2$month_label==4 && train_data_pre2$day_range==1,13, ifelse(train_data_pre2$month_label==4 && train_data_pre2$day_range==2,14, ifelse(train_data_pre2$month_label==4 && train_data_pre2$day_range==3,15, ifelse(train_data_pre2$month_label==2 && train_data_pre2$day_range==1,16, ifelse(train_data_pre2$month_label==2 && train_data_pre2$day_range==2,17, ifelse(train_data_pre2$month_label==2 && train_data_pre2$day_range==3,18, ifelse(train_data_pre2$month_label==8 && train_data_pre2$day_range==1,19, ifelse(train_data_pre2$month_label==8 && train_data_pre2$day_range==2,20, ifelse(train_data_pre2$month_label==8 && train_data_pre2$day_range==3,21, ifelse(train_data_pre2$month_label==6 && train_data_pre2$day_range==1,22, ifelse(train_data_pre2$month_label==6 && train_data_pre2$day_range==2,23, ifelse(train_data_pre2$month_label==6 && train_data_pre2$day_range==3,24, ifelse(train_data_pre2$month_label==11 && train_data_pre2$day_range==1,25, ifelse(train_data_pre2$month_label==11 && train_data_pre2$day_range==2,26, ifelse(train_data_pre2$month_label==11 && train_data_pre2$day_range==3,27, ifelse(train_data_pre2$month_label==1 && train_data_pre2$day_range==1,28, ifelse(train_data_pre2$month_label==1 && train_data_pre2$day_range==2,29, ifelse(train_data_pre2$month_label==1 && train_data_pre2$day_range==3,30, ifelse(train_data_pre2$month_label==7 && train_data_pre2$day_range==1,31, ifelse(train_data_pre2$month_label==7 && train_data_pre2$day_range==2,32, ifelse(train_data_pre2$month_label==7 && train_data_pre2$day_range==3,33, ifelse(train_data_pre2$month_label==5 && train_data_pre2$day_range==1,34, ifelse(train_data_pre2$month_label==5 && train_data_pre2$day_range==2,35, ifelse(train_data_pre2$month_label==5 && train_data_pre2$day_range==3,36,0)))))))))))))))))))))))))))))))))))) colnames(train_data_pre2)
変数加工の続き、カテゴリ変数のダミー変数化。
train_data_ohe2 <- train_data_pre2 train_data_ohe2 <- dummies::dummy.data.frame(train_data_pre2,sep="_",names = c("job","marital","education","default","housing","loan")) str(train_data_ohe2)
👉カテゴリ変数がダミー変数化された。
使ったコマンド select 使用目的:データフレームの列を削除する(データフレームの特定の列以外を抽出) dummies::dummy.data.frame
使用目的:データフレームの列を抽出する
使用方法:select(dataframe,xxx(変数))
使用方法:select(-c(xxx(変数),xxx(変数),,,))
使用目的:カテゴリ変数をダミー変数化する
使用方法:dummies::dummy.data.frame(dataframe , sep = "_" , names = c("xxx(変数)","xxx(変数)",,,) )
このあと機械学習アルゴリズムを用いてのモデル構築、評価と続く。
また少し長くなったので続きは別記事で。
ー
以上