初めに
- 本記事は、python・機械学習等々を独学している小生の備忘録的な記事になります。
- 「自身が気になったコードを写経しながら勉強していく」という、きわめてシンプルなものになります。
- 建設的なコメントを頂けますと幸いです(気に入ったら
LGTM
&ストック
してください)。
お題:IBM HR Analytics Employee Attrition & Performance
- 今回のお題は、IBM HR Analytics Employee Attrition & Performanceです。kaggleに記載のあった説明によると、**「従業員の退職理由」**を探る問題のようです。
- 今回、以下のyoutubeの動画を見つつ写経していきました。
Link:Predict Employee Attrition Using Machine Learning & Python
データはkaggleから取ってきました。
Link:IBM HR Analytics Employee Attrition & Performance
分析はyoutubeの動画にある通り、Google Colaboratryを使用しました(便利な時代になったものです)。
Step 1:データ読み込み~内容確認
それではやっていきたいと思います。
1.1: ライブラリのインポート
# ライブラリの読み込み
import numpy as np
import pandas as pd
import seaborn as sns
基本となるライブラリを読み込みます。必要なライブラリはこの後も適宜追加していく感じになります。
次にデータの読み込みですが、kaggleのサイトからダウンロードしたcsvファイルをgoogle colabで読み込みます。
1.2: Google Colabへのファイルのアップロード
# データのアップロード
from google.colab import files
uploaded = files.upload()
これをすることによって、ローカルに保存してあるファイルをgoogle colab上に取り込むことができます。
普段はGoogle Driveにファイルのアップロードしてから、Google Driveを連携させて読み込んでいたので、こっちのほうが楽でいいですね。
1.3: pandasでの読み込み
アップロードしたデータを読み込んでいきます。
# データの読み込み
df = pd.read_csv('WA_Fn-UseC_-HR-Employee-Attrition.csv')
# データの確認
df.head(7)
おなじみのコードですね。次からはデータの中身を確認していきます。
データの中身の確認
以下のコードは(実際には)それぞれ別々に実行していますが、ここでは纏めて書いておきます。
# データフレームの行・列の数確認
df.shape
# それぞれの列の中身のデータ型を確認
df.dtypes
# 欠損値の確認
df.isna().sum()
df.isnull().values.any()
#基礎統計量の確認
df.describe()
# 退職者と在籍者数の数の確認(被説明変数の数の把握)
df['Attrition'].values_counts() #図1
# 退職者と在籍者数の可視化
sns.countplot(df['Attrition'])
# 年齢別の退職者数と在籍者数の可視化
import matplotlib.pyplot as plt
plt.subplots(figsize=(12,4))
sns.countplot(x='Age', hue='Attrition', data=df, palette='colorblind') #図2
ここまではいつもやるようなデータの確認です。まずしっかりデータの中身を確認することはやはり必要だと思います。
1.4: object型のユニーク値の確認
次に、先ほど確認したデータ型のうちobject型の列のユニーク値を確認します。
for column in df.columns:
if df[column].dtype == object:
print(str(column) + ':' + str(df[column].unique()))
print(df[column].value_counts())
print('___________________________________________')
- 1行目:forループでそれぞれの列を繰り返しとってくる
- 2行目:取ってきた列がobject型か判定
- 3行目:カラム名 + そのカラムのユニーク値を出力
- 4行目:各ユニーク値の個数を出力
1.5: 不要行の削除
_.drop()
_で予測するのに意味をなさない列を削除します。
df = df.drop('Over18', axis=1)
df = df.drop('EmployeeNumber', axis=1)
df = df.drop('StandardHours', axis=1)
df = df.drop('EmployeeCount', axis=1)
これは説明不要ですね。退職する理由にならないものをdfの中から外します。
1.6: 列間の相関の確認
これもお馴染みの処理だと思います。各列間の相関(correlation
)を確認し、_heatmap
_可視化します。
df.corr()
plt.figure(figsize=(14, 14))
sns.heatmap(df.corr(), annot=True, fmt='.0%')
今回、heatmapを作成する際に指定しているのは以下の2つです。
Item | Description |
---|---|
annot | True に設定すると、セルに値を出力します。 |
fmt | annot=True に設定した場合、またはデータセットを指定した場合の出力フォーマットを文字列で指定 |
1.7: sklearnでカテゴリカル(non numerical)データにラベリング
from sklearn.preprocessing import LabelEncoder
for column in df.columns:
if df[columen].dtype == np.number:
continue
df[column] = LabelEncoder().fit_transform(df[column])
ここでは、sklearnのLabelEncoderを使ってobject型だったデータに数値データに置き換える(「分類器にかける前に文字データを離散値(0, 1, ・・・)に変換」)。
置き換えが終わったら、dfの列の順番を入れ替え分析しやすい形にします。
# Ageを新しい列に複製
df['Age_Years'] = df['Age']
# Age列を落とす
df = df.drop('Age', axis=1)
Step2: sklearnで分析
ここからが本番ですね(前処理が重要なのは言うまでもないですが)。
# dfをデータを説明変数と被説明変数に分割
X = df.iloc[:, 1:df.shape[1]].values
Y = df.iloc[:, 0].values
# 訓練データ、教師データのテストデータサイズ(25%)で分割
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.25, ramdom_state = 0)
# ランダムフォレストによる分類
from sklearn.ensemble import RandomForestClassifier
forest = RandomForestClassifier(n_estimators = 10, criterion = 'entropy', random_state = 0)
forest.fit(X_train, Y_train)
上から見ていきましょう。
- _
iloc[]
_を使って説明変数と被説明変数を分離します。 - sklearnの_
train_test_split
_を使って訓練データとテストデータの分割。
train_test_splitの引数は以下の通りです。
Item | Description |
---|---|
arrays | 分割対象の同じ長さを持った複数のリスト、Numpy の array, matrix, Pandasのデータフレームを指定。 |
test_size | 小数もしくは整数を指定。小数で指定した場合、テストデータの割合を 0.0 〜 1.0 の間で指定します。整数を指定した場合は、テストデータに必ず含めるレコード件数を整数で指定します。指定しなかった場合や None を設定した場合は、train_size のサイズを補うように設定します。train_size を設定していない場合、デフォルト値として 0.25 を用います。 |
train_size | 小数もしくは整数を指定。小数で指定した場合、トレーニングデータの割合を 0.0 〜 1.0 の間で指定します。整数を指定した場合は、トレーニングデータに必ず含めるレコード件数を整数で指定します。指定しなかった場合や None を設定した場合は、データセット全体から test_size を引いた分のサイズとします。 |
random_state | 乱数生成のシードとなる整数または、RandomState インスタンスを設定します。指定しなかった場合は、Numpy のnp.random を用いて乱数をセットします。 |
(参照: scikit-learn でトレーニングデータとテストデータを作成する) |
- ランファムフォレストを使って分類をします。ここでの引数は、
n_estimators: 木の数の指定(デフォルトは100)
criterion: gini
or entropy
を指定(デフォルトはgini
)
この後、forest.fit(...)
でモデルを学習させます。
それでは精度を見ていきましょう。
forest.score(X_train, Y_train)
この後、confusion_matrix
(混合行列)を使ってAccuracy
を計算してます。
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(Y_test, forest.predict(X_test)) #cm: confusion_matrix
TN = cm[0][0]
TP = cm[1][1]
FN = cm[1][0]
FP = cm[0][1]
print(cm)
print('Model Testing Accuracy = {}'.format( (TP + TN) / (TP + TN + FN + FP)))
以上で、簡単ではありますがskleanを使って二値分類の写経になります。
## 最後に
内容的にはそこまで難しいものではないにせよ、まだまだ理解していない箇所があることが認識できましたので、引き続き勉強していきたいと思います。
以上。