Membuat Model Logistic Regression di Apache Spark

Danau Data
3 min readMar 24, 2019

--

Pada tutorial ini akan dibahas tentang bagaimana membuat model Logistic Regression yang simple menggunakan Apache Spark. Untuk use case, kita akan menggunakan dataset Breast Cancer untuk memprediksi keganasan kanker (Benign / Malign).

Meretrieve Dataset Breast Cancer

Dataset breast cancer sangat mudah ditemukan. Pilihannya, anda bisa mengunduhnya dari web terkait data analytics populer seperti Kaggle ataupun UCI machine learning. Setelah diunduh, agar bisa dibaca oleh cluster Spark, ada baiknya kita copy file csv tersebut dari local file system ke HDFS. Anda bisa melakukannya dengan bantuan WebHdfs, ataupun command hdfs dengan parameter -copyFromLocal.

Membaca File csv Menjadi sebuah Spark DataFrame

File dataset breast cancer diunduh dalam format csv, kita dapat dengan mudah membaca file tersebut dengan command berikut ini.

data = spark.read.format('csv').option("header", "true").load('hdfs://localhost:8020/user/ilmuwan/datasets/breast-cancer_csv.csv')

Variabel data pada potongan kode di atas merupakan Spark Data Frame yang menampung dataset breast cancer.

Attribute Transformation

Dikarenakan atribut pada dataset breast cancer yang diunduh tersedia dalam bentuk string dengan skala katagorikal, kita harus mentransformasi atributnya menjadi bentuk numerik, masih dengan skala katagorikal. Pada Spark, kita bisa menggunakan class StringIndexer, seperti di bawah ini

from pyspark.ml.feature import StringIndexer
from pyspark.ml import Pipeline, PipelineModel
indexers = [StringIndexer(inputCol=column, outputCol=column+"_index").setHandleInvalid("keep").fit(data) for column in list(set(data.columns))]pipeline = Pipeline(stages=indexers)
data_transformed = pipeline.fit(data).transform(data)

Potongan kode di atas mentransformasi semua atribut dan kelas target (Class) menjadi tipe data numerik.

Hasil transformasi fitur menggunakan Class StringIndexer

Konversi Feature Menjadi Vector Space

Library Machine Learning Spark tidak bisa secara langsung membaca atribut yang ada pada Spark Dataframe menjadi fitur pada model machine learning. Atribut yang ada pada Spark Data Frame harus diubah menjadi sebuah vektor. Untuk itu, kita perlu menggunakan class VectorAssembler, output dari transformasi ini ditampung pada sebuah atribut baru pada dataframe, kita namakan dengan features.

vectorAssembler = VectorAssembler()
vectorAssembler = vectorAssembler.setInputCols(columns).setOutputCol("features")

Model Predictive menggunakan Logistic Regression

Model Logistic Regression (source: scikit-learn)

Tujuan dari logistic regression adalah untuk memprediksi kelas target dengan output berupa probabilitas (interval 0.0 sampai dengan 1.0).

from pyspark.ml.classification import LogisticRegression
lr = LogisticRegression().setMaxIter(10)
trainingData, testData = data_transformed2.randomSplit([0.7, 0.3], splitSeed)
model = lr.fit(trainingData)
model.transform(testData)

Menyimpan Model hasil Training ke Sebuah File

It’s so easy. Kita simpan menjadi sebuah file bernama ‘prediction_lr.model’

model.save('prediction_lr.model')

Memanggil Model untuk Memprediksi Data Baru

Langkah yang dibutuhkan untuk memanggil model yang sudah disimpan tidaklah terlalu panjang, hanya beberapa baris untuk membaca file yang disimpan untuk kemudian digunakan memprediksi data baru.

from pyspark.ml.classification import LogisticRegressionModel
from pyspark.ml.feature import VectorAssembler
import pandas as pd
lr = LogisticRegressionModel.load("/home/ilmuwan/Projects/lr_model.spark")test_data = {"irradiat_index":[1.0],
"node-caps_index":[2.0],
"inv-nodes_index":[3.0],
"deg-malig_index":[2.0],
"tumor-size_index":[4.0],
"age_index":[2.0],
"menopause_index":[1.0],
"breast-quad_index":[2.0],
"breast_index":[1.0]}
df_test_data = pd.DataFrame(test_data)
sdf_test_data = spark.createDataFrame(df_test_data)
vectorAssembler = VectorAssembler()
vectorAssembler = vectorAssembler.setInputCols(sdf_test_data.columns).setOutputCol("features")
sdf_test_data_transformed = vectorAssembler.transform(sdf_test_data)
result = lr.transform(sdf_test_data_transformed)
result.toJSON().collect()[0]#Result:
'{"irradiat_index":1.0,"node-caps_index":2.0,"inv-nodes_index":3.0,"deg-malig_index":2.0,"tumor-size_index":4.0,"age_index":2.0,"menopause_index":1.0,"breast-quad_index":2.0,"breast_index":1.0,"features":{"type":1,"values":[1.0,2.0,3.0,2.0,4.0,2.0,1.0,2.0,1.0]},"rawPrediction":{"type":1,"values":[2.0500292241730844,0.875004683334415,-2.9250339075074994]},"probability":{"type":1,"values":[0.7600404282434374,0.23470914954173316,0.005250422214829439]},"prediction":0.0}'

--

--

Danau Data
Danau Data

No responses yet