データの確認をしながらグラフについてまとめる

第4回のデータコンペで行ったデータの確認や可視化、そこから考えれる予測についてやり直したいと思います。

真似していきながらコツをつかんでいければと思います。参考にする記事と説明変数はほぼ一緒ですがデータの内容が少し異っています。

参考にしていく記事はこちら。

コンペ概要

債務不履行リスクの軽減

データ

  • 学習用データ (train.csv)
  • テスト用データ (test.csv)
  • サンプルファイル (submit.csv)

課題種別:分類
学習データサンプル数: 242150
説明変数の数:9
欠損値:不明

カラム ヘッダ名称 説明
0 id 顧客ID(インデックスとして使用)
1 loan_amnt 借入総額
2 term 返済期間
3 interest_rate 金利
4 grade グレード
5 employment_length 勤続年数
6 purpose 借入の目的
7 credit_score 信用スコア
8 application_type 借入時の申請方式
9 loan_status 返済状況(目的変数)

情報公開ポリシー

モデル  : 公開可
分析結果 : 公開可

グラフの使い分け

まずはあやふやになっている主要なグラフの使い分けから勉強していきます。

棒グラフ

縦棒グラフ


横軸に年や月など同じ尺度で量の大小を表します。階級など順序要素があれば使いやすそうではあります。

横棒グラフ

ランキングなどを表す際は有用。だがあまりデータ分析では使うことはなさそうかも?

積み上げ棒グラフ

縦棒グラフの内訳を表示した感じになります。

100%で積み上げると内訳を比較できる。比較しない場合は円グラフでいいかもしれないです。

折れ線グラフ

変化の傾向や方向性を表すのに適しています。縦棒グラフと同様横軸には順序属性が欲しいところ。 2つ以上比較する際は縦棒グラフより折れ線グラフを2つ重ねたほうが見やすいです。

帯グラフ・円グラフ


内訳を示す。前述したとおり比較する場合は100%積み上げ棒グラフが見やすいです。

データ分析ではそんなに使ってるところはみたことないかもしれません。

ヒストグラム


頻度を表すグラフ。データ分析ではよく使う気がします。

2つくらいまでなら比較はできる。

箱ひげ図


頻度をより視覚的にわかりやすくしたグラフ。3つ以上の頻度を比べるなら箱ひげ図のほうが適しているかもしれません。

散布図


データ間の相関関係を表す。
複数のデータ間の相関係数を表せるヒートマップもよく使われる。ヒートマップのほかの用途は知らないがほかにあったりするのでしょうか。

変数の確認

グラフの使い方を学んだところでデータをみていきます。

loan_status

返済状況(目的変数)

不均衡なデータのため何かしらの処理や工夫が必要。

df_train["loan_status"] = np.where(df_train["loan_status"]=="ChargedOff",1,0)
df_train["loan_status"].value_counts()
#loan_status
#0    199794
#1     42356

FullyPaid:0、ChargedOff:1に変換。forで回していたら時間かかったが、numpyだと一瞬で処理が終わった。スゴイ

id

顧客ID(インデックスとして使用) 特になし

loan_amnt

借入総額

借りるなら500や1000の倍数などのきりのいい金額に山ができていきそうですが、変なところに山ができています。

ほかの国のデータを日本円に直している可能性もありえるかもしれません。

term

返済期間

df_train[df_train["term"]=="3 years"]["loan_status"].mean()
#0.14163160195274033

df_train[df_train["term"]=="5 years"]["loan_status"].mean()
#0.2958498364043396

2つしか期間がない。普通は10年など長期のローンもあると思うが2種類のローンしか組んでいない謎。
また機関が5年のほうがデフォルトの割合が2倍ほど高い。 長期で組むことの不確実性の問題かもしれません。といっても2年しか変わりないが。

df_train["term"] = df_train["term"].apply(lambda x: x.split(" ")[0]).astype("int64")
df_train["term"].dtype
#dtype('int64')

object属性になっていたのでint属性に変換しておきます。

interest_rate

金利

金利が高すぎる。27%って。日本だと借入額によって異なるが上限は15~20%らしいです。


金利の上昇とともにデフォルトする割合も上がっているのが確認できます。

grade

グレード

所々跳ね上がるところはあるが基本的にはグレードが下がるにつれてデフォルトの割合も上がっています。

順序属性と判断して数値属性に変換しました。

employment_length

勤続年数

10のラベルに値が集中しています。おそらくではあるが10年以上勤続している場合、ここにまとめられているのでしょう。

勤続年数によってのデフォルト率はそこまで大きく差が開いているわけではないので、何かと組み合わせたりして使う必要がありそうな変数です。

df_train["employment_length"] = df_train["employment_length"].apply(lambda x: x.split(" ")[0]).astype("int64")

数値属性に変換しておきます。

purpose

借入の目的

houseの金額がそこまで大きくないのが不思議です。3000万円とか組みそうですが高くても2500万円です。母数が少ない(4)ので下振れかもしれません。

carの分布は1000以下に大半が収まっている一方外れ値もかなりの数あります。 似た箱ひげ図が複数見つかります。傾向も似ている可能性がありますね。
debt_consolidationとcredit_cardで大半を占めている。借金の整理でローンを組む人は普通にデフォルトしそうだなと感じます。

以外にも割合が大きいのはmajor_purchase。ですが母数が少ない当たりブレているだけかもしれません。

credit_score

信用スコア

こちらも山が複数ある。正規分布?に近い形をしていそうなものですが。

最低の値が650ちかくであることから足切りラインなのかもしれません。

credit_scoreが上昇していくとデフォルトの割合が下がっていきます。

application_type

借入時の申請方式

おそらく対面か、アプリでの申請かという変数。アプリでの申請割合がかなり小さく不均衡極まりない。

df_train["application_type"].value_counts()
#Individual    240368
#Joint App       1782


デフォルトの割合を確認してみるとそこまで差はなく、application_typeひとつだとそこまで有用な変数としては扱いきれなさそうです。

相関係数の確認


gradeinterest_rate相関係数が0.77と、とても高い。おそらくgradeからinterest_rateを決めているということが考えられます。

仮説

  • interest_rateがデフォルト率に影響を与えてそうです。同じくgradeも下がれば(数値的には上がれば)デフォルトの確率に影響を与えてそうですが、相関係数0.77と高いので多重共線性を避けるためにもどちらかを目的変数に採用。
  • termは未来の不確実性や高い金利の影響で長いとデフォルト率が高まる。
  • credit_scoreは高いほどデフォルト率が低くなる。

さいごに

これをいつもやれるようになりたいですね。matplotlibをはじめseabornの使い方もよくわかっていなかったのでいい勉強の機会になりました。時間はかかりまくりました;;。

ベースライン作成後、詳細なデータを確認するタイミングでやっていきたいと思います。