Prediksi dengan pipeline scikit-learn kustom

Logo Colab Jalankan tutorial ini sebagai notebook di Colab Logo GitHub Lihat notebook di GitHub

Tutorial ini menunjukkan cara menggunakan AI Platform Prediction untuk men-deploy pipeline scikit-learn yang menggunakan transformer kustom.

pipelines scikit-learn memungkinkan Anda membuat beberapa estimator. Misalnya, Anda dapat menggunakan transformator untuk melakukan prapemrosesan data dan meneruskan data yang ditransformasi ke pengklasifikasi. scikit-learn menyediakan banyak transformer dalam paket sklearn.

Anda juga dapat menggunakan class FunctionTransformer atau TransformerMixin scikit-learn untuk membuat transformer kustom Anda sendiri. Jika ingin men-deploy pipeline yang menggunakan transformer kustom ke AI Platform Prediction, Anda harus menyediakan kode tersebut ke AI Platform Prediction sebagai paket distribusi sumber.

Tutorial ini menyajikan contoh soal yang melibatkan data Sensus untuk memandu Anda melalui langkah-langkah berikut:

  • Melatih pipeline scikit-learn dengan transformer kustom di Pelatihan AI Platform
  • Men-deploy pipeline terlatih dan kode kustom Anda ke AI Platform Prediction
  • Menyalurkan permintaan prediksi dari deployment tersebut

Set data

Tutorial ini menggunakan Set Data Sensus Pendapatan Amerika Serikat yang disediakan oleh Repositori UC Irvine Machine Learning. Set data ini berisi informasi tentang orang-orang dari database Sensus tahun 1994, termasuk usia, pendidikan, status perkawinan, pekerjaan, dan apakah penghasilan mereka lebih dari $50.000 per tahun atau tidak.

Data yang digunakan dalam tutorial ini tersedia di bucket Cloud Storage publik: gs://cloud-samples-data/ai-platform/sklearn/census_data/

Tujuan

Tujuannya adalah untuk melatih pipeline scikit-learn yang memprediksi apakah seseorang menghasilkan lebih dari $50.000 per tahun (label target) berdasarkan informasi Sensus lain tentang orang tersebut (fitur).

Tutorial ini lebih berfokus pada penggunaan model ini dengan AI Platform Prediction daripada desain model itu sendiri. Namun, penting untuk selalu memikirkan potensi masalah dan konsekuensi yang tidak diinginkan saat membangun sistem machine learning. Lihat latihan Kursus Singkat Machine Learning tentang keadilan untuk mempelajari sumber bias dalam set data Sensus, serta keadilan machine learning secara lebih umum.

Biaya

Tutorial ini menggunakan komponen Google Cloud yang dapat ditagih:

  • AI Platform Training
  • AI Platform Prediction
  • Cloud Storage

Pelajari harga Pelatihan AI Platform, harga Prediksi AI Platform, dan harga Cloud Storage, dan gunakan Kalkulator Harga untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda.

Sebelum memulai

Anda harus melakukan beberapa hal sebelum dapat melatih dan men-deploy model pada AI Platform Prediction:

  • Menyiapkan lingkungan pengembangan lokal Anda.
  • Siapkan project Google Cloud dengan penagihan dan API yang diperlukan telah diaktifkan.
  • Buat bucket Cloud Storage untuk menyimpan paket pelatihan dan model yang Anda latih.

Menyiapkan lingkungan pengembangan lokal

Anda memerlukan hal berikut untuk menyelesaikan tutorial ini:

  • Python 3
  • Virtualenv
  • Google Cloud SDK

Panduan Google Cloud untuk Menyiapkan lingkungan pengembangan Python menyediakan petunjuk mendetail untuk memenuhi persyaratan ini. Langkah-langkah berikut memberikan serangkaian petunjuk ringkas:

  1. Instal Python 3.

  2. Instal virtualenv dan buat lingkungan virtual yang menggunakan Python 3.

  3. Aktifkan lingkungan tersebut.

  4. Selesaikan langkah-langkah di bagian berikut untuk menginstal Google Cloud SDK.

Menyiapkan project Google Cloud Anda

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  3. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  4. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  5. Menginstal Google Cloud CLI.
  6. Untuk initialize gcloud CLI, jalankan perintah berikut:

    gcloud init
  7. Di konsol Google Cloud, pada halaman pemilih project, pilih atau buat project Google Cloud.

    Buka pemilih project

  8. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  9. Enable the AI Platform Training & Prediction and Compute Engine APIs.

    Enable the APIs

  10. Menginstal Google Cloud CLI.
  11. Untuk initialize gcloud CLI, jalankan perintah berikut:

    gcloud init

Mengautentikasi akun GCP Anda

Untuk menyiapkan autentikasi, Anda harus membuat kunci akun layanan dan menetapkan variabel lingkungan untuk jalur file ke kunci akun layanan.

  1. Buat akun layanan:

    1. Di konsol Google Cloud, buka halaman Buat akun layanan.

      Buka Create service account

    2. Di kolom Nama akun layanan, masukkan nama.
    3. Opsional: Di kolom Deskripsi akun layanan, masukkan deskripsi.
    4. Klik Create.
    5. Klik kolom Pilih peran. Di bagian Semua peran, pilih AI Platform > AI Platform Admin.
    6. Klik Add another role.
    7. Klik kolom Pilih peran. Di bagian All roles, pilih Storage > Storage Object Admin.

    8. Klik Selesai untuk membuat akun layanan.

      Jangan tutup jendela browser Anda. Anda akan menggunakannya pada langkah berikutnya.

  2. Membuat kunci akun layanan untuk autentikasi:

    1. Di konsol Google Cloud, klik alamat email untuk akun layanan yang telah dibuat.
    2. Klik Kunci.
    3. Klik Tambahkan kunci, lalu Buat kunci baru.
    4. Klik Create. File kunci JSON akan didownload ke komputer Anda.
    5. Klik Close.
  3. Tetapkan variabel lingkungan GOOGLE_APPLICATION_CREDENTIALS ke jalur file JSON yang berisi kunci akun layanan Anda. Variabel ini hanya berlaku untuk sesi shell Anda saat ini. Jadi, jika Anda membuka sesi baru, tetapkan variabel kembali.

Membuat bucket Cloud Storage

Tutorial ini menggunakan Cloud Storage dalam beberapa cara:

  • Saat mengirim tugas pelatihan menggunakan Cloud SDK, Anda mengupload paket Python yang berisi kode pelatihan ke bucket Cloud Storage. AI Platform Training menjalankan kode dari paket ini.

  • Dalam tutorial ini, AI Platform Training juga menyimpan model terlatih yang dihasilkan dari tugas Anda di bucket yang sama.

  • Untuk men-deploy pipeline scikit-learn yang menggunakan kode kustom ke AI Platform Prediction, Anda harus mengupload transformer kustom yang digunakan pipeline Anda ke Cloud Storage.

Saat membuat resource versi Prediction AI Platform yang menyajikan prediksi, Anda menyediakan pipeline scikit-learn terlatih dan kode kustom Anda sebagai URI Cloud Storage.

Tetapkan nama bucket Cloud Storage sebagai variabel lingkungan. Nama ini harus unik di semua bucket Cloud Storage:

BUCKET_NAME="your-bucket-name"

Pilih region tempat AI Platform Training dan AI Platform Prediction tersedia, lalu buat variabel lingkungan lainnya. Contoh:

REGION="us-central1"

Buat bucket Cloud Storage di region ini, lalu gunakan region yang sama untuk pelatihan dan prediksi. Jalankan perintah berikut untuk membuat bucket jika belum ada:

gsutil mb -l $REGION gs://$BUCKET_NAME

Membuat aplikasi pelatihan dan kode pipeline kustom

Buat aplikasi untuk melatih pipeline scikit-learn dengan data Sensus. Dalam tutorial ini, paket pelatihan juga berisi kode kustom yang digunakan pipeline yang dilatih selama prediksi. Ini adalah pola yang berguna, karena pipeline umumnya didesain untuk menggunakan transformer yang sama selama pelatihan dan prediksi.

Gunakan langkah-langkah berikut untuk membuat direktori dengan tiga file di dalamnya yang cocok dengan struktur berikut:

census_package/
    __init__.py
    my_pipeline.py
    train.py

Pertama, buat direktori census_package/ kosong:

mkdir census_package

Dalam census_package/, buat file kosong bernama __init__.py :

touch ./census_package/__init__.py

Hal ini memungkinkan untuk mengimpor census_package/ sebagai paket di Python.

Membuat transformer kustom

scikit-learn menyediakan banyak transformer yang dapat Anda gunakan sebagai bagian dari pipeline, tetapi juga memungkinkan Anda menentukan Transformer kustom Anda sendiri. Transformer ini bahkan dapat mempelajari status tersimpan selama pelatihan yang akan digunakan nanti selama prediksi.

Perluas sklearn.base.TransformerMixin untuk menentukan tiga transformer:

  • PositionalSelector: Dengan daftar indeks C dan matriks M, metode ini akan menampilkan matriks dengan subset kolom M, yang ditunjukkan oleh C.

  • StripString: Dengan mempertimbangkan matriks string, fungsi ini akan menghapus spasi kosong dari setiap string.

  • SimpleOneHotEncoder: encoder one-hot sederhana yang dapat diterapkan ke matriks string.

Untuk melakukannya, tulis kode berikut ke file bernama census_package/my_pipeline.py.

import numpy as np
from sklearn.base import BaseEstimator, TransformerMixin

class PositionalSelector(BaseEstimator, TransformerMixin):
    def __init__(self, positions):
        self.positions = positions

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return np.array(X)[:, self.positions]

class StripString(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self

    def transform(self, X):
        strip = np.vectorize(str.strip)
        return strip(np.array(X))

class SimpleOneHotEncoder(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        self.values = []
        for c in range(X.shape[1]):
            Y = X[:, c]
            values = {v: i for i, v in enumerate(np.unique(Y))}
            self.values.append(values)
        return self

    def transform(self, X):
        X = np.array(X)
        matrices = []
        for c in range(X.shape[1]):
            Y = X[:, c]
            matrix = np.zeros(shape=(len(Y), len(self.values[c])), dtype=np.int8)
            for i, x in enumerate(Y):
                if x in self.values[c]:
                    matrix[i][self.values[c][x]] = 1
            matrices.append(matrix)
        res = np.concatenate(matrices, axis=1)
        return res

Menentukan pipeline dan membuat modul pelatihan

Selanjutnya, buat modul pelatihan untuk melatih pipeline scikit-learn Anda pada data Sensus. Bagian dari kode ini melibatkan penentuan pipeline.

Modul pelatihan ini melakukan beberapa hal:

  • Library ini akan mendownload data pelatihan dan memuatnya ke DataFrame pandas yang dapat digunakan oleh scikit-learn.
  • Class ini menentukan pipeline scikit-learn untuk dilatih. Contoh ini hanya menggunakan tiga fitur numerik ('age', 'education-num', dan 'hours-per-week') serta tiga fitur kategori ('workclass', 'marital-status', dan 'relationship') dari data input. Fitur ini mengubah fitur numerik menggunakan StandardScaler bawaan scikit-learn dan mengubah fitur kategoris dengan encoder one-hot kustom yang Anda tentukan dalam my_pipeline.py. Kemudian, kode ini menggabungkan data yang telah diproses sebelumnya sebagai input untuk pengklasifikasi.
  • Terakhir, Scikit-learn akan mengekspor model menggunakan versi joblib yang disertakan dalam scikit-learn dan menyimpannya ke bucket Cloud Storage Anda.

Tulis kode berikut ke census_package/train.py:

import warnings
import argparse
from google.cloud import storage

import pandas as pd
import numpy as np
from sklearn.externals import joblib
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.pipeline import Pipeline, FeatureUnion, make_pipeline
import census_package.my_pipeline as mp
warnings.filterwarnings('ignore')

def download_data(bucket_name, gcs_path, local_path):
    bucket = storage.Client().bucket(bucket_name)
    blob = bucket.blob(gcs_path)
    blob.download_to_filename(local_path)

def upload_data(bucket_name, gcs_path, local_path):
    bucket = storage.Client().bucket(bucket_name)
    blob = bucket.blob(gcs_path)
    blob.upload_from_filename(local_path)

def get_features_target(local_path):
    strip = np.vectorize(str.strip)
    raw_df = pd.read_csv(local_path, header=None)
    target_index = len(raw_df.columns) - 1  # Last columns, 'income-level', is the target

    features_df = raw_df.drop(target_index, axis=1)
    features = features_df.as_matrix()
    target = strip(raw_df[target_index].values)
    return features, target

def create_pipeline():
    # We want to use 3 categorical and 3 numerical features in this sample.
    # Categorical features: age, education-num, and hours-per-week
    # Numerical features: workclass, marital-status, and relationship
    numerical_indices = [0, 4, 12]  # age, education-num, and hours-per-week
    categorical_indices = [1, 5, 7]  # workclass, marital-status, and relationship

    p1 = make_pipeline(mp.PositionalSelector(categorical_indices), mp.StripString(), mp.SimpleOneHotEncoder())
    p2 = make_pipeline(mp.PositionalSelector(numerical_indices), StandardScaler())

    feats = FeatureUnion([
        ('numericals', p1),
        ('categoricals', p2),
    ])

    pipeline = Pipeline([
        ('pre', feats),
        ('estimator', GradientBoostingClassifier(max_depth=4, n_estimators=100))
    ])
    return pipeline

def get_bucket_path(gcs_uri):
    if not gcs_uri.startswith('gs://'):
        raise Exception('{} does not start with gs://'.format(gcs_uri))
    no_gs_uri = gcs_uri[len('gs://'):]
    first_slash_index = no_gs_uri.find('/')
    bucket_name = no_gs_uri[:first_slash_index]
    gcs_path = no_gs_uri[first_slash_index + 1:]
    return bucket_name, gcs_path

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--gcs_data_path', action="store", required=True)
    parser.add_argument('--gcs_model_path', action="store", required=True)

    arguments, others = parser.parse_known_args()

    local_path = '/tmp/adul.data'
    data_bucket, data_path = get_bucket_path(arguments.gcs_data_path)
    print('Downloading the data...')
    download_data(data_bucket, data_path, local_path)
    features, target = get_features_target(local_path)
    pipeline = create_pipeline()

    print('Training the model...')
    pipeline.fit(features, target)

    joblib.dump(pipeline, './model.joblib')

    model_bucket, model_path = get_bucket_path(arguments.gcs_model_path)
    upload_data(model_bucket, model_path, './model.joblib')
    print('Model was successfully uploaded.')

Melatih pipeline di Pelatihan AI Platform

Gunakan gcloud untuk mengirimkan tugas pelatihan ke Pelatihan AI Platform. Perintah berikut mengemas aplikasi pelatihan Anda, menguploadnya ke Cloud Storage, dan memberi tahu AI Platform Training untuk menjalankan modul pelatihan Anda.

Argumen -- adalah pemisah: layanan AI Platform Training tidak menggunakan argumen yang mengikuti pemisah, tetapi modul pelatihan Anda tetap dapat mengaksesnya.

gcloud ai-platform jobs submit training census_training_$(date +"%Y%m%d_%H%M%S") \
  --job-dir gs://$BUCKET_NAME/custom_pipeline_tutorial/job \
  --package-path ./census_package \
  --module-name census_package.train \
  --region $REGION \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --scale-tier BASIC \
  --stream-logs \
  -- \
  --gcs_data_path gs://cloud-samples-data/ai-platform/census/data/adult.data.csv \
  --gcs_model_path gs://$BUCKET_NAME/custom_pipeline_tutorial/model/model.joblib

Men-deploy pipeline dan prediksi penayangan

Untuk menyajikan prediksi dari AI Platform Prediction, Anda harus men-deploy resource model dan resource versi. model ini membantu Anda mengatur beberapa deployment jika Anda mengubah dan melatih pipeline beberapa kali. Versi menggunakan model terlatih dan kode kustom Anda untuk menampilkan prediksi.

Untuk men-deploy resource ini, Anda harus menyediakan dua artefak:

  • Direktori Cloud Storage yang berisi pipeline terlatih Anda. Tugas pelatihan dari langkah sebelumnya membuat file ini saat mengekspor model.joblib ke bucket Anda.
  • Paket distribusi sumber .tar.gz di Cloud Storage yang berisi transformer kustom yang digunakan pipeline Anda. Buat ini di langkah berikutnya.

Mengemas transformer kustom

Jika Anda men-deploy versi tanpa memberikan kode dari my_pipeline.py, AI Platform Prediction tidak akan dapat mengimpor transformer kustom (misalnya, mp.SimpleOneHotEncoder) dan tidak akan dapat menampilkan prediksi.

Buat setup.py berikut untuk menentukan paket distribusi sumber untuk kode Anda:

import setuptools
setuptools.setup(name='census_package',
      packages=['census_package'],
      version="1.0",
      )

Lalu, jalankan perintah berikut untuk membuat dist/census_package-1.0.tar.gz:

python setup.py sdist --formats=gztar

Terakhir, upload tarball ini ke bucket Cloud Storage Anda:

gsutil cp ./dist/census_package-1.0.tar.gz gs://$BUCKET_NAME/custom_pipeline_tutorial/code/census_package-1.0.tar.gz

Membuat resource model dan versi

Pertama, tentukan nama model dan versi:

MODEL_NAME='CensusPredictor'
VERSION_NAME='v1'

Lalu, gunakan perintah berikut untuk membuat resource model:

gcloud ai-platform models create $MODEL_NAME \
  --regions $REGION

Terakhir, buat resource versi dengan memberikan jalur Cloud Storage ke direktori model (yang berisi model.joblib) dan kode kustom (census_package-1.0.tar.gz):

gcloud components install beta

gcloud beta ai-platform versions create $VERSION_NAME --model $MODEL_NAME \
  --origin gs://$BUCKET_NAME/custom_pipeline_tutorial/model/ \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --framework SCIKIT_LEARN \
  --package-uris gs://$BUCKET_NAME/custom_pipeline_tutorial/code/census_package-1.0.tar.gz

Menyajikan prediksi online

Coba deployment Anda dengan mengirim permintaan prediksi online. Pertama, instal Library Klien Google API untuk Python:

pip install --upgrade google-api-python-client

Kemudian, kirim dua instance data Sensus ke versi yang di-deploy:

import googleapiclient.discovery

instances = [
  [39, 'State-gov', 77516, ' Bachelors .  ', 13, 'Never-married', 'Adm-clerical', 'Not-in-family',
   'White', 'Male', 2174, 0, 40, 'United-States', '<=50K'],
  [50, 'Self-emp-not-inc', 83311, 'Bachelors', 13, 'Married-civ-spouse', 'Exec-managerial', 'Husband',
   'White', 'Male', 0, 0, 13, 'United-States', '<=50K']
]

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT_ID, MODEL_NAME, VERSION_NAME)

response = service.projects().predict(
    name=name,
    body={'instances': instances}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])

Versi ini meneruskan data input melalui pipeline terlatih dan menampilkan hasil pengklasifikasi: <=50K atau >50K untuk setiap instance, bergantung pada prediksinya untuk kelompok pendapatan orang tersebut.

Pembersihan

Untuk membersihkan semua resource Google Cloud yang digunakan dalam project ini, Anda dapat menghapus project Google Cloud yang digunakan untuk tutorial.

Atau, Anda dapat membersihkan resource satu per satu dengan menjalankan perintah berikut:

# Delete version resource
gcloud ai-platform versions delete $VERSION_NAME --quiet --model $MODEL_NAME

# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet

# Delete Cloud Storage objects that were created
gsutil -m rm -r gs://$BUCKET_NAME/custom_pipeline_tutorial

Langkah selanjutnya