0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初心者向けPyTorch篇:5.二値分類

Last updated at Posted at 2024-12-28

以下は、PyTorchを使用して人事データを基に二値分類モデルを構築するコードの解説です。
人事のデータを用いて離職するかを推定する。

データダウンロード:https://www.kaggle.com/datasets/fahadrehman07/hr-comma-sep-csv?resource=download

データのleftのカラムが離職を表しています。

PyTorchを使った分類モデル構築の手順

以下は、PyTorchを使用して人事データを基に二値分類モデルを構築するコードの解説です。

必要なライブラリのインポート

import torch
import pandas as pd
import numpy as np
from torch import nn
from torch.utils.data import TensorDataset, DataLoader
from sklearn.model_selection import train_test_split

モデルの定義

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.liner_1 = nn.Linear(20, 64)
        self.liner_2 = nn.Linear(64, 64)
        self.liner_3 = nn.Linear(64, 1)
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.liner_1(x)
        x = self.relu(x)
        x = self.liner_2(x)
        x = self.relu(x)
        x = self.liner_3(x)
        x = self.sigmoid(x)
        return x
  • nn.Linear: 全結合層。入力特徴数と出力特徴数を指定します
    • nn.Linearの引数:nn.Linear(20, 64)では、入力データが20次元で、64次元の出力を生成される。最初の層の入力はデータのカラム数と一致する必要があります(入力データは20個のカラムがある)
  • ReLU: 活性化関数。非線形性を加えるため
  • Sigmoid: 出力を0〜1に制限します。二値分類でよく使われています

モデルとオプティマイザの取得

def get_model():
    model = Model()
    opt = torch.optim.Adam(model.parameters(), lr=0.0001)
    return model, opt
  • Adam: 学習率が動的に調整される最適化手法

データの読み込みと前処理

data = pd.read_csv('HR_comma_sep.csv')

salary_one_hot = pd.get_dummies(data.salary).astype(int)
part_one_hot = pd.get_dummies(data.part).astype(int)

data = data.join(salary_one_hot)
data = data.join(part_one_hot)
del data['salary']
del data['part']

Y_data = data.left.values.reshape(-1, 1)
X_data = data[[c for c in data.columns if c != "left"]].values
train_x, test_x, train_y, test_y = train_test_split(X_data, Y_data)
  • データをCSVから読み込みます
  • 「salary」と「part」の列をOne-Hotエンコーディングし、元データと入れ替える
  • 目的変数「離職(left)」と特徴量を分けます

One-Hotエンコーディングとは:機械学習アルゴリズムが理解できる数値形式です。各カテゴリを1つの次元で「1」、他を「0」にする。

データのTensor化とデータローダーの作成

train_x = torch.from_numpy(train_x).type(torch.float32)
train_y = torch.from_numpy(train_y).type(torch.float32)
test_x = torch.from_numpy(test_x).type(torch.float32)
test_y = torch.from_numpy(test_y).type(torch.float32)

train_dataset = TensorDataset(train_x, train_y)
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataset = TensorDataset(test_x, test_y)
test_dataloader = DataLoader(test_dataset, batch_size=64)
  • torch.from_numpy: Numpy配列をPyTorchのTensorに変換
  • DataLoader: バッチサイズ指定とシャッフル機能付きのデータローダー
  • shuffle: 訓練データに対してシャッフルを行うことで、モデルの学習の安定性を向上させるためです。テストデータはモデルのパフォーマンスを評価するためシャッフルする意味がありません

学習ループ

model, optim = get_model()
loss_fn = nn.BCELoss()

batch_size = 64
batch_num = len(data) // batch_size
epochs = 1000

for epoch in range(epochs):
    for x, y in train_dataloader:
        y_pred = model(x)
        loss = loss_fn(y_pred, y)
        optim.zero_grad()
        loss.backward()
        optim.step()
    with torch.no_grad():
        epoch_accuracy = accuracy(model(train_x), train_y)
        epoch_loss = loss_fn(model(train_x), train_y).data

        epoch_test_accuracy = accuracy(model(test_x), test_y)
        epoch_test_loss = loss_fn(model(test_x), test_y).data
        print(f"echo: {epoch}, loss: {round(epoch_loss.item(), 3)}, accuracy: {round(epoch_accuracy.item(), 3)}, test loss: {round(epoch_test_loss.item(), 3)}, test accuracy: {round(epoch_test_accuracy.item(), 3)}")
  • loss_fn: 損失関数
  • optim.step: 勾配更新
  • torch.no_grad: 評価時に勾配計算を無効化

学習結果と考察

echo: 0, loss: 0.566, accuracy: 0.762, test loss: 0.566, test accuracy: 0.761
echo: 1, loss: 0.565, accuracy: 0.762, test loss: 0.565, test accuracy: 0.761
echo: 2, loss: 0.562, accuracy: 0.762, test loss: 0.562, test accuracy: 0.761
echo: 3, loss: 0.572, accuracy: 0.762, test loss: 0.572, test accuracy: 0.761
echo: 4, loss: 0.562, accuracy: 0.762, test loss: 0.562, test accuracy: 0.761
echo: 5, loss: 0.558, accuracy: 0.762, test loss: 0.558, test accuracy: 0.761
...
echo: 995, loss: 0.181, accuracy: 0.937, test loss: 0.189, test accuracy: 0.933
echo: 996, loss: 0.176, accuracy: 0.939, test loss: 0.186, test accuracy: 0.932
echo: 997, loss: 0.185, accuracy: 0.932, test loss: 0.192, test accuracy: 0.928
echo: 998, loss: 0.176, accuracy: 0.94, test loss: 0.186, test accuracy: 0.934
echo: 999, loss: 0.176, accuracy: 0.94, test loss: 0.186, test accuracy: 0.933

訓練とテストデータの損失と精度の推移を見てみると、最初のエポックから徐々に損失が減少し、精度が向上していく様子が確認できます。最終的に、訓練データでの精度は約94%、テストデータでの精度も93%程度となり、モデルはかなり高い予測精度を達成しています。
最後の数エポックでは、訓練データとテストデータの精度がほぼ一致しており、過学習(オーバーフィッティング)の兆候は見られません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?