MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

เจนเฉˆเจฒเฉ‹, Khabrovsk เจจเจฟเจตเจพเจธเฉ€. เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจฒเจฟเจ–เจฟเจ† เจนเฉˆ, เจ‡เจธ เจฎเจนเฉ€เจจเฉ‡ OTUS เจ‡เฉฑเจ• เจตเจพเจฐ เจตเจฟเฉฑเจš เจฆเฉ‹ เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจ•เฉ‹เจฐเจธ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจฐเจฟเจนเจพ เจนเฉˆ, เจ…เจฐเจฅเจพเจค เจ…เจงเจพเจฐ ะธ เจ‰เฉฑเจจเจค. เจ‡เจธ เจธเจฌเฉฐเจง เจตเจฟเฉฑเจš, เจ…เจธเฉ€เจ‚ เจ‰เจชเจฏเฉ‹เจ—เฉ€ เจธเจฎเฉฑเจ—เจฐเฉ€ เจธเจพเจ‚เจเฉ€ เจ•เจฐเจจเจพ เจœเจพเจฐเฉ€ เจฐเฉฑเจ–เจฆเฉ‡ เจนเจพเจ‚.

เจ‡เจธ เจฒเฉ‡เจ– เจฆเจพ เจ‰เจฆเฉ‡เจธเจผ เจธเจพเจกเฉ‡ เจชเจนเจฟเจฒเฉ‡ เจ…เจจเฉเจญเจต เจฌเจพเจฐเฉ‡ เจ—เฉฑเจฒ เจ•เจฐเจจเจพ เจนเฉˆ MLflow.

เจ…เจธเฉ€เจ‚ เจธเจฎเฉ€เจ–เจฟเจ† เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจพเจ‚เจ—เฉ‡ MLflow เจ‡เจธเจฆเฉ‡ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจคเฉ‹เจ‚ เจ…เจคเฉ‡ เจ…เจงเจฟเจเจจ เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจฆเฉเจนเจฐเจพเจ“ เจจเฉ‚เฉฐ เจฒเฉŒเจ— เจ•เจฐเฉ‹เฅค เจซเจฟเจฐ เจ…เจธเฉ€เจ‚ UDF เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ MLflow เจจเจพเจฒ เจœเฉ‹เฉœเจจ เจฆเจพ เจ†เจชเจฃเจพ เจ…เจจเฉเจญเจต เจธเจพเจ‚เจเจพ เจ•เจฐเจพเจ‚เจ—เฉ‡เฅค

เจชเฉเจฐเจธเฉฐเจ—

เจ…เจธเฉ€เจ‚ เจ…เฉฐเจฆเจฐ เจนเจพเจ‚ เจ…เจฒเจซเจผเจพ เจธเจฟเจนเจค เจ…เจธเฉ€เจ‚ เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจ…เจคเฉ‡ เจจเจ•เจฒเฉ€ เจฌเฉเฉฑเจงเฉ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจฒเฉ‹เจ•เจพเจ‚ เจจเฉ‚เฉฐ เจ‰เจจเฉเจนเจพเจ‚ เจฆเฉ€ เจธเจฟเจนเจค เจ…เจคเฉ‡ เจคเฉฐเจฆเจฐเฉเจธเจคเฉ€ เจฆเจพ เจšเจพเจฐเจœ เจฒเฉˆเจฃ เจฒเจˆ เจธเจฎเจฐเฉฑเจฅ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจ‡เจธ เจฒเจˆ เจฎเจธเจผเฉ€เจจ เจฒเจฐเจจเจฟเฉฐเจ— เจฎเจพเจกเจฒ เจธเจพเจกเฉ‡ เจฆเฉเจ†เจฐเจพ เจตเจฟเจ•เจธเจฟเจค เจ•เฉ€เจคเฉ‡ เจ—เจ เจกเฉ‡เจŸเจพ เจธเจพเจ‡เฉฐเจธ เจ‰เจคเจชเจพเจฆเจพเจ‚ เจฆเฉ‡ เจ•เฉ‡เจ‚เจฆเจฐ เจตเจฟเฉฑเจš เจนเฉเฉฐเจฆเฉ‡ เจนเจจ, เจ…เจคเฉ‡ เจ‡เจธเฉ‡ เจ•เจฐเจ•เฉ‡ เจ…เจธเฉ€เจ‚ MLflow, เจ‡เฉฑเจ• เจ“เจชเจจ เจธเฉ‹เจฐเจธ เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ เจตเฉฑเจฒ เจ–เจฟเฉฑเจšเฉ‡ เจ—เจ เจœเฉ‹ เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจœเฉ€เจตเจจ เจšเฉฑเจ•เจฐ เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจชเจนเจฟเจฒเฉ‚เจ†เจ‚ เจจเฉ‚เฉฐ เจ•เจตเจฐ เจ•เจฐเจฆเจพ เจนเฉˆเฅค

MLflow

MLflow เจฆเจพ เจฎเฉเฉฑเจ– เจŸเฉ€เจšเจพ เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ‡ เจธเจฟเจ–เจฐ 'เจคเฉ‡ เจ‡เฉฑเจ• เจตเจพเจงเฉ‚ เจชเจฐเจค เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจจเจพ เจนเฉˆ เจœเฉ‹ เจกเฉ‡เจŸเจพ เจตเจฟเจ—เจฟเจ†เจจเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจฒเจ—เจญเจ— เจ•เจฟเจธเฉ‡ เจตเฉ€ เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€ (h2o, เจ•เฉ‡เจฐเจธ, mleap, เจชเจพเจˆเจŸเจฐเฉˆเจš, sklearn ะธ tensorflow), เจ‰เจธเจฆเฉ‡ เจ•เฉฐเจฎ เจจเฉ‚เฉฐ เจ…เจ—เจฒเฉ‡ เจชเฉฑเจงเจฐ 'เจคเฉ‡ เจฒเฉˆ เจ•เฉ‡ เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆเฅค

MLflow เจคเจฟเฉฐเจจ เจญเจพเจ— เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจฆเจพ เจนเฉˆ:

  • เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— - เจฐเจฟเจ•เจพเจฐเจกเจฟเฉฐเจ— เจ…เจคเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจ‚ เจฒเจˆ เจฌเฉ‡เจจเจคเฉ€เจ†เจ‚: เจ•เฉ‹เจก, เจกเฉ‡เจŸเจพ, เจ•เฉŒเจ‚เจซเจฟเจ—เจฐเฉ‡เจธเจผเจจ เจ…เจคเฉ‡ เจจเจคเฉ€เจœเฉ‡เฅค เจฎเจพเจกเจฒ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจชเฉเจฐเจ•เจฟเจฐเจฟเจ† เจฆเฉ€ เจจเจฟเจ—เจฐเจพเจจเฉ€ เจ•เจฐเจจเจพ เจฌเจนเฉเจค เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจนเฉˆ.
  • เจชเฉเจฐเจพเจœเฉˆเจ•เจŸ - เจ•เจฟเจธเฉ‡ เจตเฉ€ เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ 'เจคเฉ‡ เจšเฉฑเจฒเจฃ เจฒเจˆ เจชเฉˆเจ•เฉ‡เจœเจฟเฉฐเจ— เจซเจพเจฐเจฎเฉˆเจŸ (เจ‰เจฆเจพ. เจธเฉ‡เจœเจฎเฉ‡เจ•เจฐ)
  • เจฎเจพเจกเจฒ - เจตเฉฑเจ–-เจตเฉฑเจ– เจคเฉˆเจจเจพเจคเฉ€ เจธเจพเจงเจจเจพเจ‚ เจฒเจˆ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจœเจฎเฉเจนเจพเจ‚ เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจ†เจฎ เจซเจพเจฐเจฎเฉˆเจŸเฅค

MLflow (เจฒเจฟเจ–เจฃ เจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจ…เจฒเจซเจผเจพ เจตเจฟเฉฑเจš) เจ‡เฉฑเจ• เจ“เจชเจจ เจธเฉ‹เจฐเจธ เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ เจนเฉˆ เจœเฉ‹ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฎเจธเจผเฉ€เจจ เจฒเจฐเจจเจฟเฉฐเจ— เจฒเจพเจˆเจซเจธเจพเจˆเจ•เจฒ เจฆเจพ เจชเฉเจฐเจฌเฉฐเจงเจจ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจชเฉเจฐเจฏเฉ‹เจ—, เจฎเฉเฉœ เจตเจฐเจคเฉ‹เจ‚ เจ…เจคเฉ‡ เจคเฉˆเจจเจพเจคเฉ€ เจธเจผเจพเจฎเจฒ เจนเฉˆเฅค

MLflow เจธเฉˆเฉฑเจŸเจ…เฉฑเจช เจ•เฉ€เจคเจพ เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

MLflow เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจชเจนเจฟเจฒเจพเจ‚ เจ†เจชเจฃเจพ เจชเฉ‚เจฐเจพ Python เจตเจพเจคเจพเจตเจฐเจจ เจธเฉˆเจŸ เจ…เจช เจ•เจฐเจจเจพ เจนเฉ‹เจตเฉ‡เจ—เจพ, เจ‡เจธเจฆเฉ‡ เจฒเจˆ เจ…เจธเฉ€เจ‚ เจตเจฐเจคเจพเจ‚เจ—เฉ‡ PyEnv (เจฎเฉˆเจ• 'เจคเฉ‡ เจชเจพเจˆเจฅเจจ เจ‡เฉฐเจธเจŸเจพเจฒ เจ•เจฐเจจ เจฒเจˆ, เจšเฉˆเฉฑเจ• เจ†เจŠเจŸ เจ•เจฐเฉ‹ เจ‡เฉฑเจฅเฉ‡). เจ‡เจธ เจคเจฐเฉเจนเจพเจ‚ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจตเจฐเจšเฉเจ…เจฒ เจตเจพเจคเจพเจตเจฐเจจ เจฌเจฃเจพ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจœเจฟเฉฑเจฅเฉ‡ เจ…เจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฒเจˆ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€เจ†เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเจพเจ‚เจ—เฉ‡เฅค

```
pyenv install 3.7.0
pyenv global 3.7.0 # Use Python 3.7
mkvirtualenv mlflow # Create a Virtual Env with Python 3.7
workon mlflow
```

เจ†เจ“ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€เจ†เจ‚ เจฒเจพเจ‡เจฌเฉเจฐเฉ‡เจฐเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเฉ€เจเฅค

```
pip install mlflow==0.7.0 
            Cython==0.29  
            numpy==1.14.5 
            pandas==0.23.4 
            pyarrow==0.11.0
```

เจจเฉ‹เจŸ: เจ…เจธเฉ€เจ‚ UDF เจตเจฐเจ—เฉ‡ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฒเจˆ PyArrow เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค PyArrow เจ…เจคเฉ‡ Numpy เจฆเฉ‡ เจธเฉฐเจธเจ•เจฐเจฃเจพเจ‚ เจจเฉ‚เฉฐ เจ เฉ€เจ• เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจฌเจพเจ…เจฆ เจตเจพเจฒเฉ‡ เจธเฉฐเจธเจ•เจฐเจฃ เจ‡เฉฑเจ• เจฆเฉ‚เจœเฉ‡ เจจเจพเจฒ เจŸเจ•เจฐเจพ เจ—เจ เจธเจจเฅค

เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— UI เจฒเจพเจ‚เจš เจ•เจฐเฉ‹

MLflow เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจพเจจเฉ‚เฉฐ Python เจ…เจคเฉ‡ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจ‚ เจจเฉ‚เฉฐ เจฒเฉŒเจ— เจ•เจฐเจจ เจ…เจคเฉ‡ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเฉ€ เจนเฉˆ เจ†เจฐเจพเจฎ APIเฅค เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, เจคเฉเจธเฉ€เจ‚ เจ‡เจน เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจ•เจฟ เจฎเจพเจกเจฒ เจ•เจฒเจพเจคเจฎเจ• เจšเฉ€เจœเจผเจพเจ‚ เจจเฉ‚เฉฐ เจ•เจฟเฉฑเจฅเฉ‡ เจธเจŸเฉ‹เจฐ เจ•เจฐเจจเจพ เจนเฉˆ (เจฒเฉ‹เจ•เจฒเจนเฉ‹เจธเจŸ, Amazon S3, เจ…เจœเจผเฉ‚เจฐ เจฌเจฒเฉŒเจฌ เจธเจŸเฉ‹เจฐเฉ‡เจœ, Google Cloud Storage เจœ SFTP เจธเจฐเจตเจฐ). เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ…เจฒเจซเจผเจพ เจนเฉˆเจฒเจฅ 'เจคเฉ‡ AWS เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจธเจพเจกเฉ€ เจ•เจฒเจพเจคเจฎเจ• เจธเจŸเฉ‹เจฐเฉ‡เจœ S3 เจนเฉ‹เจตเฉ‡เจ—เฉ€เฅค

# Running a Tracking Server
mlflow server 
    --file-store /tmp/mlflow/fileStore 
    --default-artifact-root s3://<bucket>/mlflow/artifacts/ 
    --host localhost
    --port 5000

MLflow เจธเจฅเจพเจˆ เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐเฉ‡เจœ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฆเฉ€ เจธเจฟเจซเจพเจฐเจธเจผ เจ•เจฐเจฆเจพ เจนเฉˆ. เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐเฉ‡เจœ เจ‰เจน เจนเฉˆ เจœเจฟเฉฑเจฅเฉ‡ เจธเจฐเจตเจฐ เจฐเจจ เจ…เจคเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจฎเฉˆเจŸเจพเจกเฉ‡เจŸเจพ เจธเจŸเฉ‹เจฐ เจ•เจฐเฉ‡เจ—เจพเฅค เจธเจฐเจตเจฐ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจฆเฉ‡ เจธเจฎเฉ‡เจ‚, เจฏเจ•เฉ€เจจเฉ€ เจฌเจฃเจพเจ“ เจ•เจฟ เจ‡เจน เจธเจฅเจฟเจฐ เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐ เจตเฉฑเจฒ เจ‡เจธเจผเจพเจฐเจพ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจ‡เฉฑเจฅเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจฒเจˆ เจ…เจธเฉ€เจ‚ เจฌเจธ เจตเจฐเจคเจพเจ‚เจ—เฉ‡ /tmp.

เจฏเจพเจฆ เจฐเฉฑเจ–เฉ‹ เจ•เจฟ เจœเฉ‡เจ•เจฐ เจ…เจธเฉ€เจ‚ เจชเฉเจฐเจพเจฃเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ—เจพเจ‚ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจฒเจˆ mlflow เจธเจฐเจตเจฐ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจพเจ‚, เจคเจพเจ‚ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐเฉ‡เจœ เจตเจฟเฉฑเจš เจฎเฉŒเจœเฉ‚เจฆ เจนเฉ‹เจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆเฅค เจนเจพเจฒเจพเจ‚เจ•เจฟ, เจ‡เจธเจฆเฉ‡ เจฌเจฟเจจเจพเจ‚ เจตเฉ€ เจ…เจธเฉ€เจ‚ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ UDF เจตเจฟเฉฑเจš เจตเจฐเจค เจธเจ•เจฆเฉ‡ เจนเจพเจ‚, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจธเจพเจจเฉ‚เฉฐ เจธเจฟเจฐเจซ เจฎเจพเจกเจฒ เจฒเจˆ เจฎเจพเจฐเจ— เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

เจจเฉ‹เจŸ: เจงเจฟเจ†เจจ เจตเจฟเฉฑเจš เจฐเฉฑเจ–เฉ‹ เจ•เจฟ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— UI เจ…เจคเฉ‡ เจฎเจพเจกเจฒ เจ•เจฒเจพเจ‡เฉฐเจŸ เจ•เฉ‹เจฒ เจ†เจฐเจŸเฉ€เจซเฉˆเจ•เจŸ เจŸเจฟเจ•เจพเจฃเฉ‡ เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจนเฉ‹เจฃเฉ€ เจšเจพเจนเฉ€เจฆเฉ€ เจนเฉˆเฅค เจญเจพเจต, เจ‡เจธ เจคเฉฑเจฅ เจฆเฉ€ เจชเจฐเจตเจพเจน เจ•เฉ€เจคเฉ‡ เจฌเจฟเจจเจพเจ‚ เจ•เจฟ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— UI เจ‡เฉฑเจ• EC2 เจ‰เจฆเจพเจนเจฐเจจ เจตเจฟเฉฑเจš เจฐเจนเจฟเฉฐเจฆเจพ เจนเฉˆ, เจœเจฆเฉ‹เจ‚ MLflow เจธเจฅเจพเจจเจ• เจคเฉŒเจฐ 'เจคเฉ‡ เจšเฉฑเจฒเจฆเจพ เจนเฉˆ, เจฎเจธเจผเฉ€เจจ เจจเฉ‚เฉฐ เจ†เจฐเจŸเฉ€เจซเฉˆเจ•เจŸ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจฒเจฟเจ–เจฃ เจฒเจˆ S3 เจคเฉฑเจ• เจธเจฟเฉฑเจงเฉ€ เจชเจนเฉเฉฐเจš เจนเฉ‹เจฃเฉ€ เจšเจพเจนเฉ€เจฆเฉ€ เจนเฉˆเฅค

MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ
เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— UI เจ‡เฉฑเจ• S3 เจฌเจพเจฒเจŸเฉ€ เจตเจฟเฉฑเจš เจ•เจฒเจพเจคเจฎเจ• เจšเฉ€เจœเจผเจพเจ‚ เจจเฉ‚เฉฐ เจธเจŸเฉ‹เจฐ เจ•เจฐเจฆเจพ เจนเฉˆ

เจšเฉฑเจฒ เจฐเจนเฉ‡ เจฎเจพเจกเจฒ

เจœเจฟเจตเฉ‡เจ‚ เจนเฉ€ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจšเฉฑเจฒ เจฐเจฟเจนเจพ เจนเฉˆ, เจคเฉเจธเฉ€เจ‚ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ‡เจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค

เจ‡เฉฑเจ• เจ‰เจฆเจพเจนเจฐเจจ เจตเจœเฉ‹เจ‚, เจ…เจธเฉ€เจ‚ เจตเจฟเฉฑเจš MLflow เจ‰เจฆเจพเจนเจฐเจจ เจคเฉ‹เจ‚ เจตเจพเจˆเจจ เจธเฉ‹เจง เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจพเจ‚เจ—เฉ‡ เจธเจ•เจฒเจฐเจจ.

MLFLOW_TRACKING_URI=http://localhost:5000 python wine_quality.py 
  --alpha 0.9
  --l1_ration 0.5
  --wine_file ./data/winequality-red.csv

เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจนเฉ€ เจšเจฐเจšเจพ เจ•เจฐ เจšเฉเฉฑเจ•เฉ‡ เจนเจพเจ‚, MLflow เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฎเจพเจกเจฒ เจชเฉˆเจฐเจพเจฎเฉ€เจŸเจฐเจพเจ‚, เจฎเฉˆเจŸเฉเจฐเจฟเจ•เจธ, เจ…เจคเฉ‡ เจ•เจฒเจพเจคเจฎเจ• เจšเฉ€เจœเจผเจพเจ‚ เจจเฉ‚เฉฐ เจฒเฉŒเจ— เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ เจคเจพเจ‚ เจœเฉ‹ เจคเฉเจธเฉ€เจ‚ เจŸเฉเจฐเฉˆเจ• เจ•เจฐ เจธเจ•เฉ‹ เจ•เจฟ เจ‰เจน เจฆเฉเจนเจฐเจพเจ“ เจ‰เฉฑเจคเฉ‡ เจ•เจฟเจตเฉ‡เจ‚ เจตเจฟเจ•เจธเจฟเจค เจนเฉเฉฐเจฆเฉ‡ เจนเจจเฅค เจ‡เจน เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพ เจฌเจนเฉเจค เจฒเจพเจญเจฆเจพเจ‡เจ• เจนเฉˆ เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เจธ เจคเจฐเฉ€เจ•เฉ‡ เจจเจพเจฒ เจ…เจธเฉ€เจ‚ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจจเจพเจฒ เจธเฉฐเจชเจฐเจ• เจ•เจฐเจ•เฉ‡ เจœเจพเจ‚ เจ‡เจน เจธเจฎเจ เจ•เฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจตเจงเฉ€เจ† เจฎเจพเจกเจฒ เจจเฉ‚เฉฐ เจฆเฉเจฌเจพเจฐเจพ เจคเจฟเจ†เจฐ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ•เจฟเจนเฉœเฉ‡ เจ•เฉ‹เจก เจจเฉ‡ เจ•เจฎเจฟเจŸ เจฆเฉ‡ เจ—เจฟเฉฑเจŸ เจนเฉˆเจธเจผ เจฒเฉŒเจ—เจธ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเจพ เจฆเฉเจนเจฐเจพเจ“ เจ•เฉ€เจคเจพ เจนเฉˆเฅค

with mlflow.start_run():

    ... model ...

    mlflow.log_param("source", wine_path)
    mlflow.log_param("alpha", alpha)
    mlflow.log_param("l1_ratio", l1_ratio)

    mlflow.log_metric("rmse", rmse)
    mlflow.log_metric("r2", r2)
    mlflow.log_metric("mae", mae)

    mlflow.set_tag('domain', 'wine')
    mlflow.set_tag('predict', 'quality')
    mlflow.sklearn.log_model(lr, "model")

MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ
เจตเจพเจˆเจจ เจฆเฉเจนเจฐเจพเจ“

เจฎเจพเจกเจฒ เจฒเจˆ เจธเจฐเจตเจฐ เจนเจฟเฉฑเจธเจพ

MLflow เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ, "mlflow เจธเจฐเจตเจฐ" เจ•เจฎเจพเจ‚เจก เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจฒเจพเจ‚เจš เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆ, เจ•เฉ‹เจฒ เจฐเจจ เจจเฉ‚เฉฐ เจŸเจฐเฉˆเจ• เจ•เจฐเจจ เจ…เจคเฉ‡ เจธเจฅเจพเจจเจ• เจซเจพเจˆเจฒ เจธเจฟเจธเจŸเจฎ เจตเจฟเฉฑเจš เจกเฉ‡เจŸเจพ เจฒเจฟเจ–เจฃ เจฒเจˆ เจ‡เฉฑเจ• REST API เจนเฉˆเฅค เจคเฉเจธเฉ€เจ‚ เจตเจพเจคเจพเจตเจฐเจฃ เจตเฉ‡เจฐเฉ€เจเจฌเจฒ โ€œMLFLOW_TRACKING_URIโ€ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจฆเจพ เจชเจคเจพ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹ เจ…เจคเฉ‡ MLflow เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— API เจฒเจพเจ‚เจš เจœเจพเจฃเจ•เจพเจฐเฉ€, เจฒเฉŒเจ— เจฎเฉˆเจŸเฉเจฐเจฟเจ•เจธ, เจ†เจฆเจฟ เจฌเจฃเจพเจ‰เจฃ/เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจ†เจชเจฃเฉ‡ เจ†เจช เจ‡เจธ เจชเจคเฉ‡ 'เจคเฉ‡ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจจเจพเจฒ เจธเฉฐเจชเจฐเจ• เจ•เจฐเฉ‡เจ—เจพเฅค

เจธเจฐเฉ‹เจค: เจกเฉŒเจ•เจธ// เจ‡เฉฑเจ• เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจšเฉฑเจฒ เจฐเจฟเจนเจพ เจนเฉˆ

เจ‡เฉฑเจ• เจธเจฐเจตเจฐ เจจเจพเจฒ เจฎเจพเจกเจฒ เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจจ เจฒเจˆ, เจธเจพเจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจšเฉฑเจฒ เจฐเจนเฉ‡ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ (เจฒเฉŒเจ‚เจš เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจตเฉ‡เจ–เฉ‹) เจ…เจคเฉ‡ เจฎเจพเจกเจฒ เจฆเฉ€ เจฐเจจ ID เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ
ID เจšเจฒเจพเจ“

# Serve a sklearn model through 127.0.0.0:5005
MLFLOW_TRACKING_URI=http://0.0.0.0:5000 mlflow sklearn serve 
  --port 5005  
  --run_id 0f8691808e914d1087cf097a08730f17 
  --model-path model

MLflow เจธเจฐเจตเจฐ เจ•เจพเจฐเจœเจ•เฉเจธเจผเจฒเจคเจพ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจ เจฎเจพเจกเจฒเจพเจ‚ เจฆเฉ€ เจธเฉ‡เจตเจพ เจ•เจฐเจจ เจฒเจˆ, เจธเจพเจจเฉ‚เฉฐ เจธเจฟเจฐเจซเจผ เจจเจฟเจฐเจงเจพเจฐเจฟเจค เจ•เจฐเจ•เฉ‡ เจฎเจพเจกเจฒ เจฌเจพเจฐเฉ‡ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฒเจˆ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— UI เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉ‹เจตเฉ‡เจ—เฉ€ --run_id.

เจ‡เฉฑเจ• เจตเจพเจฐ เจœเจฆเฉ‹เจ‚ เจฎเจพเจกเจฒ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจจเจพเจฒ เจธเฉฐเจชเจฐเจ• เจ•เจฐเจฆเจพ เจนเฉˆ, เจคเจพเจ‚ เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจจเจตเจพเจ‚ เจฎเจพเจกเจฒ เจ…เฉฐเจคเจฎ เจฌเจฟเฉฐเจฆเฉ‚ เจชเฉเจฐเจพเจชเจค เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚เฅค

# Query Tracking Server Endpoint
curl -X POST 
  http://127.0.0.1:5005/invocations 
  -H 'Content-Type: application/json' 
  -d '[
	{
		"fixed acidity": 3.42, 
		"volatile acidity": 1.66, 
		"citric acid": 0.48, 
		"residual sugar": 4.2, 
		"chloridessssss": 0.229, 
		"free sulfur dsioxide": 19, 
		"total sulfur dioxide": 25, 
		"density": 1.98, 
		"pH": 5.33, 
		"sulphates": 4.39, 
		"alcohol": 10.8
	}
]'

> {"predictions": [5.825055635303461]}

เจธเจชเจพเจฐเจ• เจคเฉ‹เจ‚ เจšเฉฑเจฒ เจฐเจนเฉ‡ เจฎเจพเจกเจฒ

เจ‡เจธ เจคเฉฑเจฅ เจฆเฉ‡ เจฌเจพเจตเจœเฉ‚เจฆ เจ•เจฟ เจŸเจฐเฉˆเจ•เจฟเฉฐเจ— เจธเจฐเจตเจฐ เจ…เจธเจฒ เจธเจฎเฉ‡เจ‚ เจตเจฟเฉฑเจš เจฎเจพเจกเจฒเจพเจ‚ เจฆเฉ€ เจธเฉ‡เจตเจพ เจ•เจฐเจจ, เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจธเจฟเจ–เจฒเจพเจˆ เจฆเฉ‡เจฃ เจ…เจคเฉ‡ เจธเจฐเจตเจฐ เจ•เจพเจฐเจœเจ•เฉเจธเจผเจฒเจคเจพ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฒเจˆ เจ•เจพเจซเจผเฉ€ เจธเจผเจ•เจคเฉ€เจธเจผเจพเจฒเฉ€ เจนเฉˆ (เจธเจฐเฉ‹เจค: mlflow // docs // เจฎเจพเจกเจฒ # เจธเจฅเจพเจจเจ•), เจธเจชเจพเจฐเจ• (เจฌเฉˆเจš เจœเจพเจ‚ เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ—) เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจตเฉฐเจก เจฆเฉ‡ เจ•เจพเจฐเจจ เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจตเฉ€ เจธเจผเจ•เจคเฉ€เจธเจผเจพเจฒเฉ€ เจนเฉฑเจฒ เจนเฉˆเฅค

เจ•เจฒเจชเจจเจพ เจ•เจฐเฉ‹ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจธเจฟเจฐเจซเจผ เจ”เจซเจฒเจพเจˆเจจ เจธเจฟเจ–เจฒเจพเจˆ เจฆเจฟเฉฑเจคเฉ€ เจนเฉˆ เจ…เจคเฉ‡ เจซเจฟเจฐ เจคเฉเจนเจพเจกเฉ‡ เจธเจพเจฐเฉ‡ เจกเฉ‡เจŸเจพ เจฒเจˆ เจ†เจ‰เจŸเจชเฉเฉฑเจŸ เจฎเจพเจกเจฒ เจฒเจพเจ—เฉ‚ เจ•เฉ€เจคเจพ เจนเฉˆเฅค เจ‡เจน เจ‰เจน เจฅเจพเจ‚ เจนเฉˆ เจœเจฟเฉฑเจฅเฉ‡ เจธเจชเจพเจฐเจ• เจ…เจคเฉ‡ เจเจฎเจเจฒเจซเจฒเฉ‹ เจšเจฎเจ•เจฆเฉ‡ เจนเจจเฅค

PySpark + Jupyter + Spark เจ‡เฉฐเจธเจŸเจพเจฒ เจ•เจฐเฉ‹

เจธเจฐเฉ‹เจค: PySpark - เจœเฉเจชเฉ€เจŸเจฐ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ‹

เจ‡เจน เจฆเจฟเจ–เจพเจ‰เจฃ เจฒเจˆ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจธเจชเจพเจฐเจ• เจกเฉ‡เจŸเจพเจซเฉเจฐเฉ‡เจฎเจพเจ‚ 'เจคเฉ‡ MLflow เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจ•เจฟเจตเฉ‡เจ‚ เจฒเจพเจ—เฉ‚ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจธเจพเจจเฉ‚เฉฐ PySpark เจจเจพเจฒ เจฎเจฟเจฒ เจ•เฉ‡ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฒเจˆ เจœเฉเจชเฉ€เจŸเจฐ เจจเฉ‹เจŸเจฌเฉเฉฑเจ•เจพเจ‚ เจจเฉ‚เฉฐ เจธเฉˆเจŸ เจ…เจช เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค

เจจเจตเฉ€เจจเจคเจฎ เจธเจฅเจฟเจฐ เจธเฉฐเจธเจ•เจฐเจฃ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเจ•เฉ‡ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ‹ เจ…เจชเจพเจšเฉ‡ เจธเจชเจพเจฐเจ•:

cd ~/Downloads/
tar -xzf spark-2.4.3-bin-hadoop2.7.tgz
mv ~/Downloads/spark-2.4.3-bin-hadoop2.7 ~/
ln -s ~/spark-2.4.3-bin-hadoop2.7 ~/sparkฬ€

เจตเจฐเจšเฉเจ…เจฒ เจตเจพเจคเจพเจตเจฐเจฃ เจตเจฟเฉฑเจš เจชเจพเจˆเจธเจชเจพเจฐเจ• เจ…เจคเฉ‡ เจœเฉเจชเฉ€เจŸเจฐ เจจเฉ‚เฉฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเฉ‹:

pip install pyspark jupyter

เจตเจพเจคเจพเจตเจฐเจฃ เจตเฉ‡เจฐเฉ€เจเจฌเจฒ เจธเฉˆเจŸ เจ…เจช เจ•เจฐเฉ‹:

export SPARK_HOME=~/spark
export PATH=$SPARK_HOME/bin:$PATH
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS="notebook --notebook-dir=${HOME}/Projects/notebooks"

เจจเจฟเจธเจผเจšเจพ เจ•เจฐ เจฒเจฟเจ† notebook-dir, เจ…เจธเฉ€เจ‚ เจ†เจชเจฃเฉ€เจ†เจ‚ เจจเฉ‹เจŸเจฌเฉเฉฑเจ•เจพเจ‚ เจจเฉ‚เฉฐ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ‡ เจซเฉ‹เจฒเจกเจฐ เจตเจฟเฉฑเจš เจธเจŸเฉ‹เจฐ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚เฅค

PySpark เจคเฉ‹เจ‚ เจœเฉเจชเฉ€เจŸเจฐ เจฒเจพเจ‚เจš เจ•เจฐเจจเจพ

เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ…เจธเฉ€เจ‚ เจœเฉเจชเฉ€เจŸเจฐ เจจเฉ‚เฉฐ เจชเจพเจˆเจธเจชเจพเจฐเจ• เจกเจฐเจพเจˆเจตเจฐ เจตเจœเฉ‹เจ‚ เจธเฉฐเจฐเจšเจฟเจค เจ•เจฐเจจ เจฆเฉ‡ เจฏเฉ‹เจ— เจธเฉ€, เจ…เจธเฉ€เจ‚ เจนเฉเจฃ เจœเฉเจชเฉ€เจŸเจฐ เจจเฉ‹เจŸเจฌเฉเฉฑเจ• เจจเฉ‚เฉฐ เจชเจพเจˆเจธเจชเจพเจฐเจ• เจฆเฉ‡ เจธเฉฐเจฆเจฐเจญ เจตเจฟเฉฑเจš เจšเจฒเจพ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚เฅค

(mlflow) afranzi:~$ pyspark
[I 19:05:01.572 NotebookApp] sparkmagic extension enabled!
[I 19:05:01.573 NotebookApp] Serving notebooks from local directory: /Users/afranzi/Projects/notebooks
[I 19:05:01.573 NotebookApp] The Jupyter Notebook is running at:
[I 19:05:01.573 NotebookApp] http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745
[I 19:05:01.573 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 19:05:01.574 NotebookApp]

    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://localhost:8888/?token=c06252daa6a12cfdd33c1d2e96c8d3b19d90e9f6fc171745

MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

เจœเจฟเจตเฉ‡เจ‚ เจ‰เฉฑเจชเจฐ เจฆเฉฑเจธเจฟเจ† เจ—เจฟเจ† เจนเฉˆ, MLflow S3 เจตเจฟเฉฑเจš เจฎเจพเจกเจฒ เจ•เจฒเจพเจ•เฉเจฐเจฟเจคเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจฒเฉŒเจ— เจ•เจฐเจจ เจฒเจˆ เจ‡เฉฑเจ• เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพ เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจœเจฟเจตเฉ‡เจ‚ เจนเฉ€ เจธเจพเจกเฉ‡ เจนเฉฑเจฅเจพเจ‚ เจตเจฟเฉฑเจš เจšเฉเจฃเจฟเจ† เจนเฉ‹เจ‡เจ† เจฎเจพเจกเจฒ เจนเฉเฉฐเจฆเจพ เจนเฉˆ, เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจฎเฉ‹เจกเฉ€เจŠเจฒ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจ‡เจธเจจเฉ‚เฉฐ UDF เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš เจ†เจฏเจพเจค เจ•เจฐเจจ เจฆเจพ เจฎเฉŒเจ•เจพ เจนเฉเฉฐเจฆเจพ เจนเฉˆเฅค mlflow.pyfunc.

import mlflow.pyfunc

model_path = 's3://<bucket>/mlflow/artifacts/1/0f8691808e914d1087cf097a08730f17/artifacts/model'
wine_path = '/Users/afranzi/Projects/data/winequality-red.csv'
wine_udf = mlflow.pyfunc.spark_udf(spark, model_path)

df = spark.read.format("csv").option("header", "true").option('delimiter', ';').load(wine_path)
columns = [ "fixed acidity", "volatile acidity", "citric acid",
            "residual sugar", "chlorides", "free sulfur dioxide",
            "total sulfur dioxide", "density", "pH",
            "sulphates", "alcohol"
          ]
          
df.withColumn('prediction', wine_udf(*columns)).show(100, False)

MLflow เจจเจพเจฒ เจธเจชเจพเจฐเจ• เจจเฉ‚เฉฐ เจตเจงเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ
เจชเจพเจˆเจธเจชเจพเจฐเจ• - เจตเจพเจˆเจจ เจ—เฉเจฃเจตเฉฑเจคเจพ เจฆเฉ€เจ†เจ‚ เจญเจตเจฟเฉฑเจ–เจฌเจพเจฃเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจ†เจŠเจŸเจชเฉเฉฑเจŸ เจ•เจฐเจจเจพ

เจ‡เจธ เจฌเจฟเฉฐเจฆเฉ‚ เจคเฉฑเจ•, เจ…เจธเฉ€เจ‚ เจ‡เจธ เจฌเจพเจฐเฉ‡ เจ—เฉฑเจฒ เจ•เฉ€เจคเฉ€ เจนเฉˆ เจ•เจฟ MLflow เจจเจพเจฒ PySpark เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฟเจตเฉ‡เจ‚ เจ•เฉ€เจคเฉ€ เจœเจพเจตเฉ‡, เจชเฉ‚เจฐเฉ‡ เจตเจพเจˆเจจ เจกเฉ‡เจŸเจพเจธเฉ‡เจŸ 'เจคเฉ‡ เจตเจพเจˆเจจ เจ—เฉเจฃเจตเฉฑเจคเจพ เจฆเฉ€ เจญเจตเจฟเฉฑเจ–เจฌเจพเจฃเฉ€ เจšเฉฑเจฒ เจฐเจนเฉ€ เจนเฉˆเฅค เจชเจฐ เจ‰เจฆเฉ‹เจ‚ เจ•เฉ€ เจœเฉ‡ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจ•เฉ‡เจฒเจพ เจธเจชเจพเจฐเจ• เจคเฉ‹เจ‚ เจชเจพเจˆเจฅเจจ เจเจฎเจเจฒเจซเจฒเฉ‹ เจฎเฉ‹เจกเฉ€เจŠเจฒ เจตเจฐเจคเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ?

เจ…เจธเฉ€เจ‚ เจธเจ•เฉ‡เจฒเจพ เจ…เจคเฉ‡ เจชเจพเจˆเจฅเจจ เจตเจฟเจšเจ•เจพเจฐ เจธเจชเจพเจฐเจ• เจธเฉฐเจฆเจฐเจญ เจจเฉ‚เฉฐ เจตเฉฐเจก เจ•เฉ‡ เจ‡เจธเจฆเฉ€ เจตเฉ€ เจœเจพเจ‚เจš เจ•เฉ€เจคเฉ€เฅค เจญเจพเจต, เจ…เจธเฉ€เจ‚ เจชเจพเจˆเจฅเจจ เจตเจฟเฉฑเจš MLflow UDF เจฐเจœเจฟเจธเจŸเจฐ เจ•เฉ€เจคเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ Scala เจคเฉ‹เจ‚ เจตเจฐเจคเจฟเจ† เจนเฉˆ (เจนเจพเจ‚, เจธเจผเจพเจ‡เจฆ เจธเจญ เจคเฉ‹เจ‚ เจตเจงเฉ€เจ† เจนเฉฑเจฒ เจจเจนเฉ€เจ‚, เจชเจฐ เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจ•เฉ€ เจนเฉˆ)เฅค

เจธเจ•เฉ‡เจฒเจพ เจธเจชเจพเจฐเจ• + MLflow

เจ‡เจธ เจ‰เจฆเจพเจนเจฐเจฃ เจฒเจˆ เจ…เจธเฉ€เจ‚ เจœเฉ‹เฉœเจพเจ‚เจ—เฉ‡ เจคเฉ‹เจฐเฉ€ เจ•เจฐเจจเจฒ เจฎเฉŒเจœเฉ‚เจฆเจพ เจœเฉเจชเฉ€เจŸเจฐ เจตเจฟเฉฑเจš.

เจธเจชเจพเจฐเจ• + เจŸเฉ‹เจฐเฉ€ + เจœเฉเจชเฉ€เจŸเจฐ เจธเจฅเจพเจชเจฟเจค เจ•เจฐเฉ‹

pip install toree
jupyter toree install --spark_home=${SPARK_HOME} --sys-prefix
jupyter kernelspec list
```
```
Available kernels:
  apache_toree_scala    /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/apache_toree_scala
  python3               /Users/afranzi/.virtualenvs/mlflow/share/jupyter/kernels/python3
```

เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจจเฉฑเจฅเฉ€ เจจเฉ‹เจŸเจฌเฉเฉฑเจ• เจคเฉ‹เจ‚ เจฆเฉ‡เจ– เจธเจ•เจฆเฉ‡ เจนเฉ‹, UDF เจธเจชเจพเจฐเจ• เจ…เจคเฉ‡ PySpark เจตเจฟเจšเจ•เจพเจฐ เจธเจพเจ‚เจเจพ เจ•เฉ€เจคเจพ เจ—เจฟเจ† เจนเฉˆเฅค เจ…เจธเฉ€เจ‚ เจ‰เจฎเฉ€เจฆ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจ•เจฟ เจ‡เจน เจนเจฟเฉฑเจธเจพ เจ‰เจนเจจเจพเจ‚ เจฒเจˆ เจฒเจพเจญเจฆเจพเจ‡เจ• เจนเฉ‹เจตเฉ‡เจ—เจพ เจœเฉ‹ Scala เจจเฉ‚เฉฐ เจชเจธเฉฐเจฆ เจ•เจฐเจฆเฉ‡ เจนเจจ เจ…เจคเฉ‡ เจ‰เจคเจชเจพเจฆเจจ เจตเจฟเฉฑเจš เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ เจฎเจพเจกเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเจจเฅค

import org.apache.spark.sql.functions.col
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.{Column, DataFrame}
import scala.util.matching.Regex

val FirstAtRe: Regex = "^_".r
val AliasRe: Regex = "[\s_.:@]+".r

def getFieldAlias(field_name: String): String = {
    FirstAtRe.replaceAllIn(AliasRe.replaceAllIn(field_name, "_"), "")
}

def selectFieldsNormalized(columns: List[String])(df: DataFrame): DataFrame = {
    val fieldsToSelect: List[Column] = columns.map(field =>
        col(field).as(getFieldAlias(field))
    )
    df.select(fieldsToSelect: _*)
}

def normalizeSchema(df: DataFrame): DataFrame = {
    val schema = df.columns.toList
    df.transform(selectFieldsNormalized(schema))
}

FirstAtRe = ^_
AliasRe = [s_.:@]+

getFieldAlias: (field_name: String)String
selectFieldsNormalized: (columns: List[String])(df: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
normalizeSchema: (df: org.apache.spark.sql.DataFrame)org.apache.spark.sql.DataFrame
Out[1]:
[s_.:@]+
In [2]:
val winePath = "~/Research/mlflow-workshop/examples/wine_quality/data/winequality-red.csv"
val modelPath = "/tmp/mlflow/artifactStore/0/96cba14c6e4b452e937eb5072467bf79/artifacts/model"

winePath = ~/Research/mlflow-workshop/examples/wine_quality/data/winequality-red.csv
modelPath = /tmp/mlflow/artifactStore/0/96cba14c6e4b452e937eb5072467bf79/artifacts/model
Out[2]:
/tmp/mlflow/artifactStore/0/96cba14c6e4b452e937eb5072467bf79/artifacts/model
In [3]:
val df = spark.read
              .format("csv")
              .option("header", "true")
              .option("delimiter", ";")
              .load(winePath)
              .transform(normalizeSchema)

df = [fixed_acidity: string, volatile_acidity: string ... 10 more fields]
Out[3]:
[fixed_acidity: string, volatile_acidity: string ... 10 more fields]
In [4]:
%%PySpark
import mlflow
from mlflow import pyfunc

model_path = "/tmp/mlflow/artifactStore/0/96cba14c6e4b452e937eb5072467bf79/artifacts/model"
wine_quality_udf = mlflow.pyfunc.spark_udf(spark, model_path)

spark.udf.register("wineQuality", wine_quality_udf)
Out[4]:
<function spark_udf.<locals>.predict at 0x1116a98c8>
In [6]:
df.createOrReplaceTempView("wines")
In [10]:
%%SQL
SELECT 
    quality,
    wineQuality(
        fixed_acidity,
        volatile_acidity,
        citric_acid,
        residual_sugar,
        chlorides,
        free_sulfur_dioxide,
        total_sulfur_dioxide,
        density,
        pH,
        sulphates,
        alcohol
    ) AS prediction
FROM wines
LIMIT 10
Out[10]:
+-------+------------------+
|quality|        prediction|
+-------+------------------+
|      5| 5.576883967129615|
|      5|  5.50664776916154|
|      5| 5.525504822954496|
|      6| 5.504311247097457|
|      5| 5.576883967129615|
|      5|5.5556903912725755|
|      5| 5.467882654744997|
|      7| 5.710602976324739|
|      7| 5.657319539336507|
|      5| 5.345098606538708|
+-------+------------------+

In [17]:
spark.catalog.listFunctions.filter('name like "%wineQuality%").show(20, false)

+-----------+--------+-----------+---------+-----------+
|name       |database|description|className|isTemporary|
+-----------+--------+-----------+---------+-----------+
|wineQuality|null    |null       |null     |true       |
+-----------+--------+-----------+---------+-----------+

เจ…เจ—เจฒเฉ‡ เจ•เจฆเจฎ

เจนเจพเจฒเจพเจ‚เจ•เจฟ MLflow เจฒเจฟเจ–เจฃ เจฆเฉ‡ เจธเจฎเฉ‡เจ‚ เจ…เจฒเจซเจผเจพ เจธเฉฐเจธเจ•เจฐเจฃ เจตเจฟเฉฑเจš เจนเฉˆ, เจ‡เจน เจ•เจพเจซเจผเฉ€ เจนเฉ‹เจจเจนเจพเจฐ เจฆเจฟเจ–เจพเจˆ เจฆเจฟเฉฐเจฆเจพ เจนเฉˆ. เจธเจฟเจฐเจซเจผ เจฎเจฒเจŸเฉ€เจชเจฒ เจฎเจธเจผเฉ€เจจ เจฒเจฐเจจเจฟเฉฐเจ— เจซเจฐเฉ‡เจฎเจตเจฐเจ• เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃ เจ…เจคเฉ‡ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจธเจฟเฉฐเจ—เจฒ เจเจ‚เจกเจชเฉเจ†เจ‡เฉฐเจŸ เจคเฉ‹เจ‚ เจตเจฐเจคเจฃ เจฆเฉ€ เจฏเฉ‹เจ—เจคเจพ เจธเจฟเจซเจผเจพเจฐเจฟเจธเจผเจ•เจฐเจคเจพ เจชเฉเจฐเจฃเจพเจฒเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจ…เจ—เจฒเฉ‡ เจชเฉฑเจงเจฐ เจคเฉฑเจ• เจฒเฉˆ เจœเจพเจ‚เจฆเฉ€ เจนเฉˆเฅค

เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, MLflow เจกเจพเจŸเจพ เจ‡เฉฐเจœเฉ€เจจเฉ€เจ…เจฐเจพเจ‚ เจ…เจคเฉ‡ เจกเจพเจŸเจพ เจธเจพเจ‡เฉฐเจธ เจฎเจพเจนเจฟเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจฆเฉ‚เจœเฉ‡ เจฆเฉ‡ เจจเฉ‡เฉœเฉ‡ เจฒเจฟเจ†เจ‰เจ‚เจฆเจพ เจนเฉˆ, เจ‰เจนเจจเจพเจ‚ เจตเจฟเจšเจ•เจพเจฐ เจ‡เฉฑเจ• เจธเจพเจ‚เจเฉ€ เจชเจฐเจค เจฐเฉฑเจ–เจฆเจพ เจนเฉˆเฅค

MLflow เจฆเฉ€ เจ‡เจธ เจ–เฉ‹เจœ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจธเจพเจจเฉ‚เฉฐ เจญเจฐเฉ‹เจธเจพ เจนเฉˆ เจ•เจฟ เจ…เจธเฉ€เจ‚ เจ…เฉฑเจ—เฉ‡ เจตเจงเจพเจ‚เจ—เฉ‡ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจธเจพเจกเฉ€เจ†เจ‚ เจธเจชเจพเจฐเจ• เจชเจพเจˆเจชเจฒเจพเจˆเจจเจพเจ‚ เจ…เจคเฉ‡ เจธเจฟเจซเจผเจพเจฐเจฟเจธเจผเจ•เจฐเจคเจพ เจชเฉเจฐเจฃเจพเจฒเฉ€เจ†เจ‚ เจฒเจˆ เจตเจฐเจคเจพเจ‚เจ—เฉ‡เฅค

เจซเจพเจˆเจฒ เจธเจฟเจธเจŸเจฎ เจฆเฉ€ เจฌเจœเจพเจ เจกเจพเจŸเจพเจฌเฉ‡เจธ เจจเจพเจฒ เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐเฉ‡เจœ เจจเฉ‚เฉฐ เจธเจฎเจ•เจพเจฒเฉ€ เจ•เจฐเจจเจพ เจšเฉฐเจ—เจพ เจนเฉ‹เจตเฉ‡เจ—เจพ. เจ‡เจธ เจจเจพเจฒ เจธเจพเจจเฉ‚เฉฐ เจ•เจˆ เจ…เฉฐเจคเจฎ เจฌเจฟเฉฐเจฆเฉ‚ เจฎเจฟเจฒเจฃเฉ‡ เจšเจพเจนเฉ€เจฆเฉ‡ เจนเจจ เจœเฉ‹ เจ‡เฉฑเจ•เฉ‹ เจซเจพเจˆเจฒ เจธเจŸเฉ‹เจฐเฉ‡เจœ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเจจเฅค เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ•เจˆ เจ‰เจฆเจพเจนเจฐเจจเจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเฉ‹ เจชเฉเจฐเฉ‡เจธเจŸเฉ‹ ะธ เจ…เจฅเฉ€เจจเจพ เจ‰เจธเฉ‡ เจนเฉ€ เจ—เจฒเฉ‚ เจฎเฉˆเจŸเจพเจธเจŸเฉ‹เจฐ เจจเจพเจฒ.

เจธเฉฐเจ–เฉ‡เจช เจตเจฟเฉฑเจš, เจฎเฉˆเจ‚ เจกเฉ‡เจŸเจพ เจฆเฉ‡ เจจเจพเจฒ เจธเจพเจกเฉ‡ เจ•เฉฐเจฎ เจจเฉ‚เฉฐ เจนเฉ‹เจฐ เจฆเจฟเจฒเจšเจธเจช เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ MLFlow เจ•เจฎเจฟเจŠเจจเจฟเจŸเฉ€ เจฆเจพ เจงเฉฐเจจเจตเจพเจฆ เจ•เจฐเจจเจพ เจšเจพเจนเจพเจ‚เจ—เจพเฅค

เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ MLflow เจจเจพเจฒ เจ–เฉ‡เจก เจฐเจนเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจธเจพเจจเฉ‚เฉฐ เจฒเจฟเจ–เจฃ เจคเฉ‹เจ‚ เจธเฉฐเจ•เฉ‹เจš เจจเจพ เจ•เจฐเฉ‹ เจ…เจคเฉ‡ เจธเจพเจจเฉ‚เฉฐ เจฆเฉฑเจธเฉ‹ เจ•เจฟ เจคเฉเจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจ•เจฟเจตเฉ‡เจ‚ เจตเจฐเจคเจฆเฉ‡ เจนเฉ‹, เจ…เจคเฉ‡ เจ‡เจธ เจคเฉ‹เจ‚ เจตเฉ€ เจตเฉฑเจง เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจ‰เจคเจชเจพเจฆเจจ เจตเจฟเฉฑเจš เจตเจฐเจคเจฆเฉ‡ เจนเฉ‹เฅค

เจ•เฉ‹เจฐเจธเจพเจ‚ เจฌเจพเจฐเฉ‡ เจนเฉ‹เจฐ เจœเจพเจฃเฉ‹:
เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ. เจฌเฉเจจเจฟเจ†เจฆเฉ€ เจ•เฉ‹เจฐเจธ
เจฎเจธเจผเฉ€เจจ เจธเจฟเจ–เจฒเจพเจˆ. เจเจกเจตเจพเจ‚เจธเจก เจ•เฉ‹เจฐเจธ

เจนเฉ‹เจฐ เจชเฉœเฉเจนเฉ‹:

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹