2017.03.30 Thu |

Kaggleデータをあさってみる1(Human Resource Analysis)

shutterstock_513585007

今回は、Kaggleデータをあさってみます。kaggleやUCI DataRepositoryにはたくさんデータがあるとわかっていても、いちいち何があるのか確かめに行くのは面倒ですよね。。面倒でない好奇心旺盛な方は、データサイエンティストの資質抜群だと思います。ちなみに、kaggleとUCI DataRepositoryのURLは

kaggle
https://www.kaggle.com/datasets

UCI DataRepository
https://archive.ics.uci.edu/ml/datasets.html

です。

今回は上から順に見ていって一番面白そうだった、Human Resource Analysisのデータにしました。
human-resourcehttps://www.kaggle.com/ludobenistant/hr-analytics

このデータの内容は、各列の変数ごとに説明しますと、
Employee satisfaction level(従業員の満足レベル:0-1スケールで1が最大)
Last evaluation(最後の評価0-1スケールで1が最大)
Number of projects(プロジェクトの数)
Average monthly hours(平均の月労働時間)
Time spent at the company(会社で過ごした時間)
Whether they have had a work accident(仕事で事故に合ったことはことはあるか)
Whether they have had a promotion in the last 5 years(5年間で昇格はあったかどうか)
Department(部署)
Salary(給料)
Whether the employee has left(従業員はやめたかどうか:1がやめた、0がやめていない)

このデータセットの目的は、”次にやめる有能な従業員はだれか?”を突き止めることだそうです。
それができたら面白そうですね。

いろいろ確認しながらできることをやっていきたいと思います。

まずデータを読み込みます。
データをダウンロード(ダウンロードにはKaggleアカウントをとることが必要です。誰でも簡単に取れます。)しましょう。そして、ファイルを開いて、workディレクトリにファイルを配置しましょう。そのあとで、read.csv関数を用いて読み込みます。列名はあるのでheader=Tです。

#データの読み込み
t=read.csv(“HR_comma_sep.csv”,header=T)
#データの構造確認
str(t)
データの中身確認本来Factor化されているべきものがされてないような気がする(number_project, time_spent_company, Work_accident, left, promotion_last_5years)ので、plotしてみましょう。

plot(t)
plot

plotしてみた結果、ほぼ間違いなく量的変数なのは、1,2,4列目であり、質的変数の疑いがあるのは、3,5,6,7,8列目です。9,10列目はもともと、Factor型となっているので質的変数です。

3,5,6,7,8列目に関して、table関数で集計してみて、質的変数であることを確定させましょう。

#number_project列
table(t[,3])
#time_spent_company列
table(t[,5])
#Work_accident列
table(t[,6])
#left
table(t[,7])
#promotion_last_5years
table(t[,8])

2017-03-30_01h06_09

ということで、やはり、質的変数でした。プロジェクト数や、会社で過ごした時間は大小関係があるから質的変数にするのはおかしい、という方もいらっしゃるとは思いますが、ここでは個人的な考えとして、特定のプロジェクト数または、特定の会社で過ごした時間が、目的変数に影響することも考えられるので、数量化理論I・Ⅱの立場から、今回は質的変数でやってみます。ただ量的変数の方が正しい可能性もあるので理想的には両方やってみるのが望ましいでしょう。

ということで、質的変数をFactor化します(Pythonメインの方はダミー変数の作成とご理解ください)。

#質的変数のFactor化
i=0
d=t
for (i in c(3,5,6,7,8)){
d[,c(i)]=as.factor(t[,c(i)])
}
str(d)
dのサマリ
それでは、学習器構築により、目的変数leftに影響を与える変数を特定しましょう。
またせっかくなので、どの学習器が予測性能が良いか、テストしてみましょう。
今回は4分の3を学習に使い残りの4分の1でテストします。
まずデータを学習用と、テスト用に分割します。
#サンプル数
n=nrow(d)
n
#sample関数用の乱数の種をまく
set.seed(123)
#整数1~nから75%の整数を取り出す。
ind=sample(n,floor(n*0.75))
head(ind)
#学習用(train)とテスト用(test)にデータを分割する。
train=d[ind,]
test =d[-ind,]
#データ数の確認
dim(train)
dim(test)

データ分割それでは次に、randomForest関数を用いて、ランダムフォレストをしていきましょう。
#ランダムフォレストの実行
library(randomForest)
#ハイパーパラメータmtryのtuning
h_mtry=tuneRF(train[,c(1,2,3,4,5,6,8,9,10)],train[,7])
h_mtry
h_mtry1h_mtry2ということで、ハイパーパラメータmtryは6がよいことがわかりました。
rf_result=randomForest(left~.,data=train,importance=T, mtry=6)
#結果
rf_result
rf_result1Confusion matrixを見る感じかなり精度良いかなと思います(正しく判別できているもの8539+2613,間違って判別したもの20+77)。
#ハイパーパラメータntreeの確認
plot(rf_result)
ntree
ntreeの数を見た感じ、ntree=500で十分に収束しているので、ntreeはデフォルト設定のままで大丈夫そうです。
では、このモデルでどれくらい、testデータを予想できるか試してみましょう。
#予測
pred=predict(rf_result,test[,c(1,2,3,4,5,6,8,9,10)])
head(pred)
table(pred,test[,7])
rf_result2正しく予測できているものが2861+854個、間違って予測したものが、8+27個ということで、まずまずのモデルになったと思います。

それでは、説明変数の重要度を見てみましょう。
varImpPlot(rf_result)
varImpPlotRのrandomForestパッケージは、各説明変数を一つずつシャッフリングして目的変数への影響を算出したものと、各変数を消したうえで目的変数への影響を算出した、2つの”説明変数の重要度”を算出します。
良いモデルほど、二つの結果は一致するという個人的な経験則があります。

今回は、かなり一致しているので、それなりに良いモデルなのでしょう。
さて結果ですが、
1,satisfaction_level
2,number_projectまでが共通していて、
3位以下、last_evaluation、time_spend_company、average_monthly_hoursが重要なようです。
それでは、ひとつずつ、plotしていきましょう。
1,satisfaction_levelと退職有無(left)のplot
plot(d[,7],d[,1],xlab=”left(1)orNot(0)”,ylab=”satisfaction_level”)
1-exp仕事への満足度が低い方が、より退職していますね。まあ、当たり前ではありますが、満足度が70-90%の人が退職者の25%を占めることも見過ごせません。本来、このクラスターをとってきて詳細に解析すべきなんでしょう。今は全体を見ることに集中していますが。

2,number_project(2,3,4,5,6,7)と退職有無(left)の集計
table(d[,7],d[,3])
number_pro抱えているプロジェクトが2つの人がアッという的にやめている人数は多いですが、プロジェクト数が、5,6,7と増えていくにつれ、やめる割合は大きくなっていることに注目です。つまり、優秀な人材をやめさせないようにする対策の一つとして、プロジェクトを抱えすぎないようにする制度が必要ということになります。

3,last_evaluationと退職有無(left)のplot
plot(d[,7],d[,2],xlab=”Left(1)orNot(0)”,ylab=”last_evaluation”)
last_evalu仕事をやめるグループの方が全体的に、最後の業績評価が高くついている傾向がありますね。これは会社としては由々しき事態でしょう。

4,time_spend_companyと退職有無(left)の集計
table(d[,7],d[,5])
time_spent_companies退職した人(1)の方が退職していない人(0)より、合計勤務時間が少ないことがわかります。
一定期間務めると、退職のピークがあり、時間がさらに立つと退職者数は緩やかに減少するようです。
5,average_monthly_hours(月の平均労働時間)と退職有無(left)のplot
plot(d[,7],d[,4],xlab=”Left(1)orNot(0)”,ylab=”average_monthly_hours”)
average_monthly_time仕事をやめた人(1)の方が、月の平均勤務時間が長いことがわかります。

ということで、以上を総合すると、この会社では、優秀な人材が、流出する傾向があることがわかりました。
まだまだ、全体を俯瞰したに過ぎないのですが、とりあえず、今回はこの辺で終わりにしたいと思います。

鈴木瑞人
東京大学大学院 新領域創成科学研究科 メディカル情報生命専攻 博士課程1年
東京大学機械学習勉強会代表
NPO法人Bizjapan

2024.9  
未経験者必見!『キャリアリターン採用』開始しました  詳しく