Spark'ta ONNX Çıkarımı

Bu örnekte bir LightGBM modeli eğitecek ve modeli ONNX biçimine dönüştürebilirsiniz. Dönüştürüldükten sonra, Spark'ta bazı test verilerini çıkarsamak için modeli kullanırsınız.

Bu örnekte aşağıdaki Python paketleri ve sürümleri kullanılır:

  • onnxmltools==1.7.0
  • lightgbm==3.2.1

Önkoşullar

  • Not defterinizi bir göle ekleyin. Sol tarafta Ekle'yi seçerek mevcut bir göl evi ekleyin veya bir göl evi oluşturun.
  • Bir kod hücresine ekleyip !pip install onnxmltools==1.7.0 hücreyi çalıştırarak yüklemeniz onnxmltools gerekebilir.

Örnek verileri yükleme

Örnek verileri yüklemek için not defterinizdeki hücrelere aşağıdaki kod örneklerini ekleyin ve hücreleri çalıştırın:

from pyspark.sql import SparkSession

# Bootstrap Spark Session
spark = SparkSession.builder.getOrCreate()

from synapse.ml.core.platform import *
df = (
    spark.read.format("csv")
    .option("header", True)
    .option("inferSchema", True)
    .load(
        "wasbs://publicwasb@mmlspark.blob.core.windows.net/company_bankruptcy_prediction_data.csv"
    )
)

display(df)

Çıkış aşağıdaki tabloya benzer görünmelidir, ancak değerler ve satır sayısı farklı olabilir:

Faiz Kapsamı Oranı Net Gelir Bayrağı Özkaynak sorumluluğu
0.5641 1.0 0.0165
0.5702 1.0 0.0208
0.5673 1.0 0.0165

Modeli eğitmek için LightGBM kullanma

from pyspark.ml.feature import VectorAssembler
from synapse.ml.lightgbm import LightGBMClassifier

feature_cols = df.columns[1:]
featurizer = VectorAssembler(inputCols=feature_cols, outputCol="features")

train_data = featurizer.transform(df)["Bankrupt?", "features"]

model = (
    LightGBMClassifier(featuresCol="features", labelCol="Bankrupt?")
    .setEarlyStoppingRound(300)
    .setLambdaL1(0.5)
    .setNumIterations(1000)
    .setNumThreads(-1)
    .setMaxDeltaStep(0.5)
    .setNumLeaves(31)
    .setMaxDepth(-1)
    .setBaggingFraction(0.7)
    .setFeatureFraction(0.7)
    .setBaggingFreq(2)
    .setObjective("binary")
    .setIsUnbalance(True)
    .setMinSumHessianInLeaf(20)
    .setMinGainToSplit(0.01)
)

model = model.fit(train_data)

Modeli ONNX biçimine dönüştürme

Aşağıdaki kod eğitilen modeli bir LightGBM güçlendiricisine dışarı aktarır ve ardından ONNX biçimine dönüştürür:

import lightgbm as lgb
from lightgbm import Booster, LGBMClassifier


def convertModel(lgbm_model: LGBMClassifier or Booster, input_size: int) -> bytes:
    from onnxmltools.convert import convert_lightgbm
    from onnxconverter_common.data_types import FloatTensorType

    initial_types = [("input", FloatTensorType([-1, input_size]))]
    onnx_model = convert_lightgbm(
        lgbm_model, initial_types=initial_types, target_opset=9
    )
    return onnx_model.SerializeToString()


booster_model_str = model.getLightGBMBooster().modelStr().get()
booster = lgb.Booster(model_str=booster_model_str)
model_payload_ml = convertModel(booster, len(feature_cols))

Dönüştürme işleminden sonra, ONNX yükünü içine ONNXModel yükleyin ve model girişlerini ve çıkışlarını inceleyin:

from synapse.ml.onnx import ONNXModel

onnx_ml = ONNXModel().setModelPayload(model_payload_ml)

print("Model inputs:" + str(onnx_ml.getModelInputs()))
print("Model outputs:" + str(onnx_ml.getModelOutputs()))

Model girişini giriş veri çerçevesinin sütun adına (FeedDict) eşleyin ve çıkış veri çerçevesinin sütun adlarını model çıkışlarıyla (FetchDict) eşleyin.

onnx_ml = (
    onnx_ml.setDeviceType("CPU")
    .setFeedDict({"input": "features"})
    .setFetchDict({"probability": "probabilities", "prediction": "label"})
    .setMiniBatchSize(5000)
)

Çıkarım için modeli kullanma

Modelle çıkarım yapmak için aşağıdaki kod test verileri oluşturur ve ONNX modeli aracılığıyla verileri dönüştürür.

from pyspark.ml.feature import VectorAssembler
import pandas as pd
import numpy as np

n = 1000 * 1000
m = 95
test = np.random.rand(n, m)
testPdf = pd.DataFrame(test)
cols = list(map(str, testPdf.columns))
testDf = spark.createDataFrame(testPdf)
testDf = testDf.union(testDf).repartition(200)
testDf = (
    VectorAssembler()
    .setInputCols(cols)
    .setOutputCol("features")
    .transform(testDf)
    .drop(*cols)
    .cache()
)

display(onnx_ml.transform(testDf))

Çıkış aşağıdaki tabloya benzer görünmelidir, ancak değerler ve satır sayısı farklı olabilir:

Dizin oluşturma Özellikler Tahmin Olasılık
1 "{"type":1,"values":[0.105... 0 "{"0":0.835...
2 "{"type":1,"values":[0.814... 0 "{"0":0.658...