<jupyter_start><jupyter_text>SageMakerなし<jupyter_code>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xgboost as xgb
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

"""XGBoost で二値分類するサンプルコード"""
# 乳がんデータセットを読み込む
dataset = datasets.load_breast_cancer()
x, y = dataset.data, dataset.target
# データセットを学習用とテスト用に分割する
train_x, test_x, train_y, test_y = train_test_split(x, y,
                                                    test_size=0.2,
                                                    shuffle=True,
                                                    random_state=42,
                                                    stratify=y)
# さらに学習用データを学習用とvalid用に分割する
tr_x, va_x, tr_y, va_y = train_test_split(train_x, train_y,
                                                    test_size=0.2,
                                                    shuffle=True,
                                                    random_state=42,
                                                    stratify=train_y)
# XGBoost が扱うデータセットの形式に直す
dtrain = xgb.DMatrix(tr_x, label=tr_y)
dvalid = xgb.DMatrix(va_x, label=va_y)
dtest = xgb.DMatrix(test_x)
# 学習用のパラメータ
xgb_params = {
    # 二値分類問題
    'objective': 'binary:logistic',
    # 評価指標
    'eval_metric': 'logloss',
}
# モデルを学習する
# バリデーションデータもモデルに渡し、学習の進行とともにスコアがどう変わるかモニタリングする
# watchlistには学習データおよびバリデーションデータをセットする
watchlist = [(dtrain, 'train'), (dvalid, 'eval')]
model = xgb.train(xgb_params,
                dtrain,
                num_boost_round=50,  # 学習ラウンド数は適当
                evals=watchlist
                )
# 予測：検証用データが各クラスに分類される確率を計算する
pred_proba = model.predict(dtest)
# しきい値 0.5 で 0, 1 に丸める
pred = np.where(pred_proba > 0.5, 1, 0)
# 精度 (Accuracy) を検証する
acc = accuracy_score(test_y, pred)
print('Accuracy:', acc)<jupyter_output>[0]	train-logloss:0.469816	eval-logloss:0.491902
[1]	train-logloss:0.335088	eval-logloss:0.373947
[2]	train-logloss:0.248404	eval-logloss:0.299573
[3]	train-logloss:0.18724	eval-logloss:0.253465
[4]	train-logloss:0.143523	eval-logloss:0.215149
[5]	train-logloss:0.113522	eval-logloss:0.198511
[6]	train-logloss:0.090464	eval-logloss:0.178499
[7]	train-logloss:0.073264	eval-logloss:0.170306
[8]	train-logloss:0.061057	eval-logloss:0.16866
[9]	train-logloss:0.051617	eval-logloss:0.161906
[10]	train-logloss:0.044053	eval-logloss:0.161001
[11]	train-logloss:0.038528	eval-logloss:0.15977
[12]	train-logloss:0.033695	eval-logloss:0.159252
[13]	train-logloss:0.029831	eval-logloss:0.160112
[14]	train-logloss:0.026945	eval-logloss:0.156529
[15]	train-logloss:0.024568	eval-logloss:0.160408
[16]	train-logloss:0.022406	eval-logloss:0.160971
[17]	train-logloss:0.020436	eval-logloss:0.16223
[18]	train-logloss:0.019104	eval-logloss:0.160814
[19]	train-logloss:0.017892	eval-logloss:0.155377
[20]	train-log[...]<jupyter_text>SageMakerでの実行<jupyter_code>#!/usr/bin/env python
# -*- coding: utf-8 -*-

import xgboost as xgb
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

"""XGBoost で二値分類するサンプルコード"""
# 乳がんデータセットを読み込む
dataset = datasets.load_breast_cancer()
x, y = dataset.data, dataset.target
# データセットを学習用とテスト用に分割する
train_x, test_x, train_y, test_y = train_test_split(x, y,
                                                    test_size=0.2,
                                                    shuffle=True,
                                                    random_state=42,
                                                    stratify=y)
# さらに学習用データを学習用とvalid用に分割する
tr_x, va_x, tr_y, va_y = train_test_split(train_x, train_y,
                                                    test_size=0.2,
                                                    shuffle=True,
                                                    random_state=42,
                                                    stratify=train_y)

##### ここから異なる ####################################################
import pandas as pd
### 最初の列に目的変数を挿入
tr = np.insert(tr_x, 0, tr_y, axis=1)
va = np.insert(va_x, 0, va_y, axis=1)

# ローカルにcsv作成(ヘッダなし)
pd.DataFrame(tr).to_csv('train.csv', header=False, index=False)
pd.DataFrame(va).to_csv('validation.csv', header=False, index=False)

### S3にアップ
import sagemaker
from sagemaker import get_execution_role

# default_bucket=None　を任意で指定することも可能
# https://sagemaker.readthedocs.io/en/stable/session.html
sagemaker_session = sagemaker.Session()

# バケット: sagemaker-<region>-<アカウントID> に保存される。(上記で指定しなかったため)
input_train = sagemaker_session.upload_data(path='train.csv', key_prefix='sagemaker/xgb-breast-cancer')
input_validation = sagemaker_session.upload_data(path='validation.csv', key_prefix='sagemaker/xgb-breast-cancer')

### content_typeを指定する
from sagemaker.session import s3_input

s3_input_train = s3_input(s3_data=input_train, content_type='text/csv')
s3_input_validation = s3_input(s3_data=input_validation, content_type='text/csv')


sagemaker_session
### SageMaker XGboostのコンテナパス取得
import boto3
from sagemaker.amazon.amazon_estimator import get_image_uri
container = get_image_uri(boto3.Session().region_name, 'xgboost')

### estimatorの設定
role = get_execution_role() # sagemaker ノートブックインスタンス、Studioからのみ有効

sess = sagemaker.Session()

xgb = sagemaker.estimator.Estimator(container,
                                    role, 
                                    train_instance_count=1, 
                                    train_instance_type='ml.m4.xlarge',
                                    sagemaker_session=sess)
### ハイパーパラメータの設定
### num_roundはここでしか宣言できない
xgb.set_hyperparameters(
    objective='binary:logistic',
    eval_metric='logloss',
    num_round=50
)

### トレーニングジョブの実行
xgb.fit({'train': s3_input_train, 'validation': s3_input_validation})


### エンドポイントのデプロイ（予測を実施するサーバを作成）
xgb_predictor = xgb.deploy(initial_instance_count = 1, instance_type = 'ml.m4.xlarge')

from sagemaker.predictor import csv_serializer

xgb_predictor.content_type = 'text/csv'
xgb_predictor.serializer = csv_serializer
xgb_predictor.deserializer = None

### 予測の実行
pred_proba_sagemaker = xgb_predictor.predict(test_x).decode('utf-8')

### 整形
pred_proba_sagemaker_arr = np.fromstring(pred_proba_sagemaker[0:], sep=',')

##### ここまで。以後同じ ####################################################
pred_sagemaker = np.where(pred_proba_sagemaker_arr > 0.5, 1, 0)

# 精度 (Accuracy) を検証する
acc_sagemaker = accuracy_score(test_y, pred_sagemaker)
print('Accuracy:', acc_sagemaker)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1233567716294711, 'fraction_numerical': 0.05564047691837359, 'mean_word_length': 2.8151603498542275, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 12, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '89919', 'license': 'MIT', 'n_tokens_mistral': 2841, 'n_tokens_neox': 2626, 'n_words': 352, 'path': 'trans-xgboost/breast-cancer.ipynb', 'repo_name': 'yito0427/sagemaker-prototypes', 'size': '6542'}