В последние годы машинное обучение становится популярным. Поскольку данные большинства предприятий хранятся в Db2 для z/OS, мы покажем вам, как выполнять машинное обучение с использованием данных Db2 для z/OS и функции машинного обучения Spark. На простом примере мы опишем, как построить модель, обучить ее, протестировать и сохранить с помощью Scala. В части 1 мы будем использовать VectorAssembler для создания объектов в качестве входных данных для нашей модели. В Части 2 мы будем использовать формулу R.

(Примечание: примерно через 3 месяца после публикации этого блога, 1 января 2017 г., IBM анонсировала IBM Machine Learning для z/OS, которые позволяют создавать, развертывать и управлять моделями с помощью графического интерфейса. См. эту ссылку Больше подробностей.)

Задний план

Предположим, у нас есть группа людей с разным возрастом, полом, артериальным давлением (максимальное значение), соотношением холестерина, уровнем натрия, уровнем калия и лекарствами, которые они принимают. Мы хотим построить модель для предсказания препарата (наркотика Y, наркотика C или наркотика X), который они принимают.

+---+------+------+------------------+----------+----------+-----+
|AGE|GENDER|BP_TOP| CHOLESTEROL_RATIO|    SODIUM| POTASSIUM| DRUG|
+---+------+------+------------------+----------+----------+-----+
| 23|     F| 139.0|               5.1|     0.793|     0.031|drugY|
| 47|     M|  90.0|               5.5|     0.739|     0.056|drugC|
| 47|     M|  90.0|               4.9|     0.697|     0.069|drugC|
| 28|     F| 120.0|               4.8|     0.564|     0.072|drugX|
| 61|     F|  90.0|               5.2|     0.559|     0.031|drugY|
| 22|     F| 115.0|               4.3|     0.677|     0.079|drugX|
| 49|     F| 119.0|               4.3|     0.790|     0.049|drugY|
| 41|     M|  90.0|               4.8|     0.767|     0.069|drugC|
| 60|     M| 120.0|               4.7|     0.777|     0.051|drugY|
| 43|     M|  90.0|               2.2|     0.526|     0.027|drugY|
+---+------+------+------------------+----------+----------+-----+

Предварительное условие

  1. Db2 для z/OS (я использую Db2 11 для z/OS)
  2. JAR-файл драйвера JDBC Db2: db2jcc4.ar, db2jcc_license_cisuz.jar (файл лицензии требуется только в том случае, если сервер Db2 for z/OS не активирован)
  3. Java 1.7 или выше
  4. Спарк (использую Спарк 2.1.0). Вы можете загрузить готовую версию с https://spark.apache.org/downloads.html.

Обзор шагов

  1. Создать и заполнить таблицу
  2. Запустите Spark и подключитесь к DB2.
  3. Предварительно обработайте входные данные (функции) нашей модели.
  4. Найдите подходящие алгоритмы машинного обучения
  5. Обучите и протестируйте модель
  6. Сохраните модель

Для шагов со 2 по 6 мы следуем шагам, описанным в https://spark.apache.org/docs/2.0.2/ml-classification-regression.html#decision-tree-classifier.

Шаг 1: Создайте и заполните таблицу

Вы можете использовать подходящий инструмент (например, SPUFI, TEP3, Data Studio, CLP и т. д.) для создания и заполнения таблицы.

Ниже приведена таблица операторов DDL и SQL (примечание: я использую # в качестве терминатора SQL ниже).

drop table t1#
create table t1(age int, gender char(1), BP_top double, cholesterol_ratio double, sodium double, potassium double, drug varchar(5))#
insert into t1 values(23, 'F', 139, 5.1, 0.793, 0.031, 'drugY')#
insert into t1 values(47, 'M', 90,  5.5, 0.739, 0.056, 'drugC')#
insert into t1 values(47, 'M', 90,  4.9, 0.697, 0.069, 'drugC')#
insert into t1 values(28, 'F', 120, 4.8, 0.564, 0.072, 'drugX')#
insert into t1 values(61, 'F', 90,  5.2, 0.559, 0.031, 'drugY')#
insert into t1 values(22, 'F', 115, 4.3, 0.677, 0.079, 'drugX')#
insert into t1 values(49, 'F', 119, 4.3, 0.790, 0.049, 'drugY')#
insert into t1 values(41, 'M', 90,  4.8, 0.767, 0.069, 'drugC')#
insert into t1 values(60, 'M', 120, 4.7, 0.777, 0.051, 'drugY')#
insert into t1 values(43, 'M', 90,  2.2, 0.526, 0.027, 'drugY')#

Шаг 2. Запустите Spark и подключитесь к DB2.

а. После загрузки двоичного файла Spark разархивируйте сжатый файл в каталог, например, c:\Spark210.

б. Откройте окно командной строки Window в режиме администратора («Запуск от имени администратора»)

Установите следующую среду (вы можете настроить ее в соответствии с вашей средой)

Set HADOOP_HOME=C:\Hadoop
set SPARKBIN=C:\Spark210\spark-2.1.0-bin-hadoop2.7\bin
SET PATH=C:\Program Files\IBM\Java70\bin;%SPARKBIN%;%PATH%

в. Запустите оболочку Spark scala следующим образом (после настройки следующего, чтобы указать точное местоположение банок jcc)

C:\Spark210\spark-2.1.0-bin-hadoop2.7\bin\spark-shell.cmd --driver-class-path C:\jcc_home\jccbuilds\jcc411\db2jcc4.jar;C:\jcc_home\jccbuilds\jcc411\db2jcc_license_cisuz.jar

Устранение неполадок: если вы получаете исключение NullPointerException, вы можете исправить его в соответствии с http://stackoverflow.com/questions/32721647/how-to-start-spark-applications-on-windows-aka-why-spark- терпит неудачу с нулевым указателем

Для успешного запуска вы должны увидеть примерно следующее:

Welcome to
 ____              __
/ __/__  ___ _____/ /__
_\ \/ _ \/ _ `/ __/  '_/
/___/ .__/\_,_/_/ /_/\_\   version 2.1.0
/_/
Using Scala version 2.11.8 (IBM J9 VM, Java 1.7.0)
Type in expressions to have them evaluated.
Type :help for more information.
scala>

д. Импорт необходимых классов

import org.apache.spark.ml.classification.DecisionTreeClassifier
import org.apache.spark.ml.feature.{IndexToString, StringIndexer, VectorIndexer, VectorAssembler,OneHotEncoder,SQLTransformer}
import org.apache.spark.ml.{Pipeline, PipelineModel}
import org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator
import org.apache.spark.ml.classification.DecisionTreeClassificationModel
import org.apache.spark.sql.SparkSession

е. Создайте сеанс Spark (начиная со Spark 2.0, используйте SparkSession вместо sqlContext)

val spark = SparkSession.builder().appName("JaneMLExample").getOrCreate()

ф. Получить данные из Db2 (настроить в соответствии с вашими настройками)

val DB2Data = spark.read.format("jdbc").options(Map("url" -> "jdbc:db2://hostname:port/location:currentSchema=schema;user=user;password=password;","driver" -> "com.ibm.db2.jcc.DB2Driver", "dbtable" -> "SYSADM.T1")).load()

Шаг 3: Предварительно обработайте входные данные (функции) нашей модели.

а. Преобразование выходной строки (drugX, DrugY, DrugC) в двойную

Поскольку мы хотим предсказать лекарство по другим атрибутам, столбец DRUG строкового типа данных является выходом нашей модели. Для вычислений нам нужно изменить строковое значение (drugX, DrugY, DrugC) столбца DRUG на двойное (drugLabel) с помощью StringIndexer.

// Метки индекса, добавление метаданных в столбец меток.

// Подходит для всего набора данных, чтобы включить все метки в индекс.

val labelIndexer = new StringIndexer().setInputCol("DRUG").setOutputCol("drugLabel").fit(DB2Data)

б. Преобразовать входную строку в двойную.

Точно так же нам нужно преобразовать наш ввод GENDER char (1) в double

val genderIndexer = new StringIndexer().setInputCol("GENDER").setOutputCol("genderIndex")
val genderEncoder = new OneHotEncoder().setInputCol("genderIndex").setOutputCol("genderVec")

в. Создайте вектор объектов в качестве входных данных для нашей модели

val assembler = new VectorAssembler().setInputCols(Array("AGE", "genderVec", "BP_TOP", "CHOLESTEROL_RATIO", "SODIUM", "POTASSIUM")).setOutputCol("features")

д. Разделите данные на обучающую и тестовую выборки (30% отведено для тестирования).

val Array(trainingData, testData) = DB2Data.randomSplit(Array(0.7, 0.3))

Шаг 4: Найдите подходящие алгоритмы машинного обучения

Spark предоставляет множество алгоритмов машинного обучения (https://spark.apache.org/docs/2.1.0/ml-classification-regression.html). В этом примере, поскольку мы собираемся прогнозировать препарат на основе пола, возраста, артериального давления и т. д. человека, мы выбираем дерево решений.

а. Обучите модель DecisionTree.

Входные данные для DecisionTreeClassifier() передаются через setLabelCol() и setFeaturesCol(), то есть drugLabel из шага 3 а) и функции из шага 3 в) соответственно.

val dt = new DecisionTreeClassifier().setLabelCol("drugLabel").setFeaturesCol("features")

Выходные столбцы по умолчанию: prediction, rawPrediction и probability.

б. Преобразовать проиндексированную метку (prediction в двойном формате) обратно в исходные метки, такие как DrugX, DrugY, DrugC (вывод в predictedLabel)

val labelConverter = new IndexToString().setInputCol("prediction").setOutputCol("predictedLabel").setLabels(labelIndexer.labels)

Шаг 5. Обучите и протестируйте модель

а. Сцепите все шаги (например, индексаторы, дерево) в конвейере.

val pipeline = new Pipeline().setStages(Array(labelIndexer, genderIndexer, genderEncoder, assembler, dt, labelConverter))

б. Обучите модель с помощью trainingData (70% данных в таблице). Это также запускает индексаторы.

val model = pipeline.fit(trainingData)

в. Делайте прогнозы, используя testData (30% данных в таблице).

val predictions = model.transform(testData)

д. Выберите строки примеров для отображения.

Столбец DRUG — это исходный столбец в таблице, а predictedLabel — это столбец, предсказанный нашей моделью.

predictions.select("DRUG", "predictedLabel", "drugLabel", "features").show()
+-----+--------------+---------+--------------------+
| DRUG|predictedLabel|drugLabel|            features|
+-----+--------------+---------+--------------------+
|drugX|         drugX|      2.0|[22.0,0.0,115.0,4...|
|drugC|         drugC|      1.0|[47.0,1.0,90.0,4....|
|drugY|         drugY|      0.0|[49.0,0.0,119.0,4...|
+-----+--------------+---------+--------------------+

Чтобы увидеть все столбцы:

predictions.show(false)
+---+------+------+------------------+------------------+--------------------+-----+---------+-----------+-------------+------------------------------------------------------------+-------------+-------------+----------+--------------+
|AGE|GENDER|BP_TOP|CHOLESTEROL_RATIO |SODIUM            |POTASSIUM           |DRUG |drugLabel|genderIndex|genderVec    |features|rawPrediction|probability  |prediction|predictedLabel|
+---+------+------+------------------+------------------+--------------------+-----+---------+-----------+-------------+------------------------------------------------------------+-------------+-------------+----------+--------------+
|22 |F     |115.0 |4.3               |0.6769999999999999|0.079               |drugX|2.0      |1.0        |(1,[],[])    |[22.0,0.0,115.0,4.3,0.6769999999999999,0.079]               |[0.0,0.0,1.0]|[0.0,0.0,1.0]|2.0       |drugX         |
|47 |M     |90.0  |4.8999999999999995|0.697             |0.069               |drugC|1.0      |0.0        |(1,[0],[1.0])|[47.0,1.0,90.0,4.8999999999999995,0.697,0.069]              |[0.0,2.0,0.0]|[0.0,1.0,0.0]|1.0       |drugC         |
|49 |F     |119.0 |4.3               |0.7899999999999999|0.048999999999999995|drugY|0.0      |1.0        |(1,[],[])    |[49.0,0.0,119.0,4.3,0.7899999999999999,0.048999999999999995]|[4.0,0.0,0.0]|[1.0,0.0,0.0]|0.0       |drugY         |
+---+------+------+------------------+------------------+--------------------+-----+---------+-----------+-------------+------------------------------------------------------------+-------------+-------------+----------+--------------+

е. Выберите (прогноз, истинная метка) и вычислите ошибку теста.

val evaluator = new MulticlassClassificationEvaluator().setLabelCol("drugLabel").setPredictionCol("prediction").setMetricName("accuracy")
val accuracy = evaluator.evaluate(predictions)
accuracy: Double = 1.0
println("Test Error = "+ (1.0 — accuracy))
Test Error = 0.0

Как видите, мы получаем очень хороший результат.

Шаг 6: Сохраните модель

а. Теперь мы можем при желании сохранить настроенный пайплайн на диск

model.write.overwrite().save("C:/Jane/Work/DB2/socialMedia/machineLearning/DB2Model1")

(примечание: если вы используете Spark 1.6.2, приведенное выше утверждение НЕ будет работать)

б. И загрузить его обратно во время производства

val sameModel = PipelineModel.load("C:/Jane/Work/DB2/socialMedia/machineLearning/DB2Model1")
val predictionAgain = sameModel.transform(testData)
predictionAgain.select("DRUG", "predictedLabel", "drugLabel", "features").show()
+-----+--------------+---------+--------------------+
| DRUG|predictedLabel|drugLabel|            features|
+-----+--------------+---------+--------------------+
|drugX|         drugX|      2.0|[22.0,0.0,115.0,4...|
|drugC|         drugC|      1.0|[47.0,1.0,90.0,4....|
|drugY|         drugY|      0.0|[49.0,0.0,119.0,4...|
+-----+--------------+---------+--------------------+

Вывод

В этом блоге мы обсудили, как выполнять машинное обучение для данных Db2 for z/OS с помощью возможностей машинного обучения Spark. Мы передавали входные данные с помощью VectorAssembler и алгоритма дерева решений для построения/обучения/тестирования нашей модели. Во второй части мы будем использовать RFormula.

Ресурсы

Первоначально опубликовано на https://www.ibm.com. По состоянию на 30 декабря 2019 года получено 27 430 просмотров.