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 pengubah kustom.

Pipeline scikit-learn memungkinkan Anda menyusun beberapa estimator. Misalnya, Anda dapat menggunakan pengubah untuk memproses data dan meneruskan data yang diubah ke pengklasifikasi. scikit-learn menyediakan banyak pengubah dalam paket sklearn.

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

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

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

Set data

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

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

Tujuan

Tujuannya adalah melatih pipeline scikit-learn yang memprediksi apakah seseorang menghasilkan lebih dari $50.000 per tahun (label target) berdasarkan informasi sensus lainnya 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 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 AI Platform Prediction, dan harga Cloud Storage, serta gunakan Kalkulator Harga untuk membuat estimasi biaya berdasarkan proyeksi penggunaan Anda.

Sebelum memulai

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

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

Menyiapkan lingkungan pengembangan lokal Anda

Anda memerlukan hal berikut untuk menyelesaikan tutorial ini:

  • Python 3
  • virtualenv
  • Google Cloud SDK

Panduan Google Cloud untuk Menyiapkan lingkungan pengembangan Python memberikan petunjuk mendetail untuk memenuhi persyaratan ini. Langkah-langkah berikut memberikan kumpulan 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

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init

Mengautentikasi akun GCP Anda

Untuk menyiapkan autentikasi, Anda perlu 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 Buat akun layanan

    2. Di kolom Nama akun layanan, masukkan nama.
    3. Opsional: Di kolom Deskripsi akun layanan, masukkan deskripsi.
    4. Klik Buat.
    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 Semua peran, 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 Buat. 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 dengan beberapa cara:

  • Saat mengirimkan 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 pengubah kustom yang digunakan pipeline ke Cloud Storage.

Saat membuat resource versi AI Platform Prediction yang menayangkan prediksi, Anda memberikan pipeline scikit-learn yang telah dilatih dan kode kustom Anda sebagai URI Cloud Storage.

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

BUCKET_NAME="your-bucket-name"

Pilih region tempat Pelatihan AI Platform dan Prediksi AI Platform 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:

gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION

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 terlatih selama prediksi. Ini adalah pola yang berguna, karena pipeline umumnya dirancang 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 Anda mengimpor census_package/ sebagai paket di Python.

Membuat pengubah 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.

Luaskan sklearn.base.TransformerMixin untuk menentukan tiga transformator:

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

  • StripString: Dengan matriks string, tindakan 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:

  • Fungsi ini mendownload data pelatihan dan memuatkannya ke DataFrame pandas yang dapat digunakan oleh scikit-learn.
  • Fungsi ini menentukan pipeline scikit-learn yang akan dilatih. Contoh ini hanya menggunakan tiga fitur numerik ('age', 'education-num', dan 'hours-per-week') dan tiga fitur kategoris ('workclass', 'marital-status', dan 'relationship') dari data input. Fungsi ini mengubah fitur numerik menggunakan StandardScaler bawaan scikit-learn dan mengubah fitur kategoris dengan encoder one-hot kustom yang Anda tentukan di my_pipeline.py. Kemudian, model ini menggabungkan data yang telah diproses sebelumnya sebagai input untuk pengklasifikasi.
  • Terakhir, kode ini 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 AI Platform Training

Gunakan gcloud untuk mengirimkan tugas pelatihan ke Pelatihan AI Platform. Perintah berikut akan memaketkan 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 masih 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 menayangkan prediksi

Untuk menayangkan prediksi dari AI Platform Prediction, Anda harus men-deploy resource model dan resource versi. Model 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 perlu 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.

Memaketkan transformer kustom

Jika Anda men-deploy versi tanpa memberikan kode dari my_pipeline.py, AI Platform Prediction tidak akan dapat mengimpor pengubah kustom (misalnya, mp.SimpleOneHotEncoder) dan tidak akan dapat menayangkan 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",
      )

Kemudian, 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:

gcloud storage 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'

Kemudian, 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 Anda (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

Menayangkan prediksi online

Coba deployment Anda dengan mengirimkan 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 mengosongkan resource individual 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
gcloud storage rm gs://$BUCKET_NAME/custom_pipeline_tutorial --recursive

Langkah selanjutnya