1. 기본 흐름
기본적으로 전체적인 서비스 흐름을 익히기 위해 간단한 샘플코드를 만들어 보도록 하겠습니다. 기본 흐름은 아래와 같습니다.
1. 트레이닝 데이터를 이용하여 모델을 학습 시키고, 예측하고, 정확도를 측정한다.
2. 학습된 모델을 저장한다 (S3 에 업로드한다)
3. 서버에 모델을 다운로드하여 Python3+Flask 서비스에 로드한다.
4. Python3+Flask 를 이용하여 요청에 대한 예측값을 RestFul API 를 통해 서비스한다.
5. 클라이언트가 머신러닝을 이용한다.
2. 학습데이터 및 모델 만들기
이번 예제에서 사용할 머신러닝 라이브러리는 scikit-learn & pandas 로 파이썬 라이브러리(텐서플로, 케라스 등) 중 가장 많이 사용하는 머신러닝 라이브러리입니다.
우선 모델을 학습시키기 위해 주피터 노트북을 사용합니다. 윈도우 PC에 개발에 필요한 기본 항목들을 설치합니다. (기존에 작성한 내용을 참고하세요 - https://theserverside.tistory.com/223?category=837694 )
참고 : 그냥 주피터 노트북만 사용하고 싶다면, AWS 의 SageMaker 를 통해서 주피터 노트북을 간단하게 생성하여 사용하실수 있습니다. (아래 캡쳐)
로컬 환경에서 모델을 이용하여 웹서비스를 개발을 해야 하기 때문에 기본적인 환경셋팅을 하고 로컬에 있는 주피터 노트북을 사용하는것이 더 편합니다.
이번 핸즈온은 버섯의 데이터를 입력해서 식용이 가능한지 여부에 대한 결과를 리턴하는 예제를 진행하려고 합니다. 교사(지도) 학습 (Supervised learning) 중 분류에 해당하는 랜덤포레스트 알고리즘을 적용하도록 하겠습니다. 교사(지도) 학습은 데이터와 답을 같이 학습시켜 특정 데이터의 값을 예측하게 하는 방법입니다. (참고 : https://theserverside.tistory.com/230?category=837694)
우선, 아래와 같이 샘플데이터를 만들어서 example-data.csv 로 저장하시고, 아래 파이썬 코드를 주피터 노트북에 작성한 후 Run 시켜보겠습니다. 샘플 데이터의 내용은 status (식용 가능/불가능) 를 도출하기 위해서 height, weight, color 라는 데이터를 조합해서 만들어 놓은 트레이닝(학습) 데이터 입니다. 다시 정리하면 height가 7이고, weight 가 2이며, color 가 1이면, status 는 p(식용가능) 이라는 내용입니다. 각 요소(height, weight, color) 는 기준을 잡아 정리하면 됩니다. 예를 들어 color 1은 검정색, 2는 흰색 등등 이러한 방식으로 구성하면 됩니다. 그리고, 학습데이터가 많으면 많을수록 정확도는 높아지게 됩니다. 우선, 몇 안되는 적은 데이터로 학습을 시키고, 계속 데이터를 추가 입력하면서 정확도를 높이는것이 좋습니다. 초기 데이터가 충분하다면 상관없지만, 적은 데이터는 정확하지 않은 결과값을 도출할 가능성이 많기 때문에 충분한 데이터를 확보하고, 적용시키는것이 무엇보다도 중요합니다.
[모델을 만들기 위한 파이썬 코드]
import pandas as pd
from sklearn.externals import joblib
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
from sklearn.model_selection import train_test_split
# 데이터 읽어 들이기
mr = pd.read_csv("example-data.csv", header=0)
# 데이터를 label 과 data 로 분리
label = []
data = []
for row_index, row in mr.iterrows():
label.append(row.iloc[0])
row_data = []
for v in row.iloc[1:]:
row_data.append(v)
data.append(row_data)
# 학습 전용과 테스트 전용 데이터로 나누기
data_train, data_test, label_train, label_test = train_test_split(data, label)
# 데이터 학습시키기
clf = RandomForestClassifier()
clf.fit(data_train, label_train)
# 모델 저장
joblib.dump(clf, 'example-data.pkl')
# 데이터 예측하기
predict = clf.predict(data_test)
#print(data_test)
# 결과 테스트하기
ac_score = metrics.accuracy_score(label_test, predict)
print("정확도 =", ac_score)
print("predict =\n", predict)
위의 코드에서 joblib.dump() 를 이용하여 pkl 의 확장자를 가진 모델을 저장합니다. 추후에 웹서비스에 사용할 모델 파일입니다. 원하는 정확도에 도달하기 위해 반복적으로 작업을 진행한 후 최종 모델 파일(example-data.pkl)을 AWS S3 의 특정 폴더에 업로드 해놓습니다. AWS S3에 올려 놓는 이유는 웹서비스에 사용되는 모델파일을 지속적으로 업데이트하기 위해서 S3 에 올려놓고, 서버에서 자동으로 다운로드 받도록 하기 위함입니다. 웹서비스가 있는 서버에 직접 올려도 상관은 없습니다. 이번 핸즈온에서는 웹서비스 서버의 model 폴더에 모델 파일을 위치시켜 놓고 진행하겠습니다.
3. 웹서비스를 위한 Flask 설정
로컬에 파이썬과 텐서플로우가 설정 되어 있다는 전제하에 파이썬 개발을 위한 PyCharm IDE 무료버전을 다운로드받아 설치합니다. (https://www.jetbrains.com/pycharm/download/#section=windows )
설치가 완료되었으면, PyCharm 에서 Flask 기반 프로젝트를 생성합니다. 패키지 의존성 관리 파일인 requirements.txt 에 아래와 같이 의존성을 작성합니다.
Flask==1.0.2
numpy==1.15.4
pandas==0.23.4
scikit-learn==0.20.3
의존성 설치를 위해 PyCharm Terminal 에서 아래와 같이 명령어를 실행시킵니다.
pip install -r requirements.txt
관련 라이브러리가 설치가 완료되면 웹서비스에 필요한 main.py 파일을 만들어 보겠습니다.
4. 웹서비스 개발
model 파일 (example-data.pkl) 을 위치시킬 model 폴더를 만듭니다. 그리고, 웹서비스에 필요한 main.py 파일을 생성한후 아래의 같이 작성합니다.
[웹서비스를 만들기 위한 파이썬 코드 - main.py]
import sys
import os
import shutil
import time
import traceback
from flask import Flask, request, jsonify
from urllib.request import urlopen
import urllib.request
from sklearn.externals import joblib
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
app = Flask(__name__)
# 모델 경로
model_directory = 'model'
model_file_name = '%s/example-data.pkl' % model_directory
clf = None
# 웹서비스
@app.route('/predict', methods=['POST'])
def predict():
if clf:
try:
param = request.json
prediction = list(joblib.load(model_file_name).predict(param))
return jsonify({'prediction': prediction})
except Exception as e:
return jsonify({'error': str(e), 'trace': traceback.format_exc()})
else:
print('train first')
return 'no model here'
# 구동 메인
if __name__ == '__main__':
try:
port = int(sys.argv[1])
except Exception as e:
port = 9090
try:
clf = joblib.load(model_file_name)
print('model loaded')
except Exception as e:
print('No model here - Train first')
print(str(e))
clf = None
app.run(host='0.0.0.0', port=port, debug=True)
main.py 파일이 완료되었으면, PyCharm Terminal 에서 아래와 같이 웹서비스를 구동시킵니다.
python main.py 9090
구동이 완료되었으면, Postman 에서 테스트 해보도록 하겠습니다. 접속 포트는 9090 입니다.
웹서비스 ( http://localhost:9090/predict ) 에 POST 로 아래의 데이터를 전송합니다. (height : 1, weight : 2, color : 3)
[
[1,2,3]
]
결과값으로 아래와 같은 데이터가 반환됩니다.
{
"prediction": [
"e"
]
}
위의 코드를 설명하면 height 가 1이고, weight가 2이며 , color 가 3인 버섯은 식용불가(e) 라는 예측 데이터를 알수 있습니다.
참고 URL : https://github.com/amirziai/sklearnflask
지금까지 머신러닝 맛보기 4탄 - 핸즈온 이였습니다.
'AI' 카테고리의 다른 글
머신러닝 맛보기 8탄 (0) | 2019.05.27 |
---|---|
머신러닝 맛보기 7탄 (0) | 2019.05.09 |
머신러닝 맛보기 6탄 (0) | 2019.05.02 |
머신러닝 맛보기 5탄 (0) | 2019.04.18 |
머신러닝 맛보기 3탄 (0) | 2019.03.19 |
머신러닝 맛보기 2탄 (0) | 2019.03.19 |
머신러닝 맛보기 1탄 (0) | 2019.03.18 |
AWS SageMaker 로 머신러닝 맛보기 1탄 (1) | 2019.03.07 |
댓글