# app.py
from flask import Flask, request, jsonify
app = Flask(__name__) # Flask 애플리케이션 객체 생성
# 루트 URL ('/')로 GET 요청이 오면 실행될 함수
@app.route('/')
def home():
return "Hello, Flask!"
# '/greet' URL로 GET 요청이 오고, 'name' 파라미터가 있으면 실행
@app.route('/greet', methods=['GET'])
def greet():
name = request.args.get('name', 'Guest') # URL 파라미터에서 'name' 값 가져오기
return f"Hello, {name}!"
# '/predict' URL로 POST 요청이 오면 실행 (JSON 데이터 예상)
@app.route('/predict', methods=['POST'])
def predict_example():
if request.is_json:
data = request.get_json() # POST 요청의 JSON 데이터 가져오기
# 여기서 data를 사용하여 모델 예측 수행 (예시)
number = data.get('number', 0)
prediction = number * 2
return jsonify({'input_number': number, 'prediction': prediction}) # JSON 형태로 응답
else:
return jsonify({'error': 'Request must be JSON'}), 400 # 400 Bad Request
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000) # 개발 서버 실행
# debug=True: 코드 변경 시 자동 재시작, 디버깅 정보 제공 (운영 환경에서는 False)
# host='0.0.0.0': 모든 네트워크 인터페이스에서 접속 허용
# port=5000: 사용할 포트 번호
먼저, 학습된 머신러닝 모델이 파일 형태로 저장되어 있어야 합니다. (예: pickle, joblib 사용)
여기서는 간단한 Scikit-learn 모델을 예시로 사용합니다.
# train_model.py (모델 학습 및 저장 - 별도 파일로 실행)
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
import joblib # 또는 pickle
# 1. 데이터 로드 및 모델 학습 (간단 예시)
iris = load_iris()
X, y = iris.data, iris.target
# 간단화를 위해 두 개의 클래스만 사용 (0, 1)
X_binary = X[y != 2]
y_binary = y[y != 2]
model = LogisticRegression(solver='liblinear')
model.fit(X_binary, y_binary)
print("모델 학습 완료!")
# 2. 모델 저장
joblib.dump(model, 'iris_binary_model.pkl')
print("모델 저장 완료: iris_binary_model.pkl")
# (선택) 스케일러 등 전처리기도 함께 저장해야 할 수 있음
# from sklearn.preprocessing import StandardScaler
# scaler = StandardScaler()
# X_scaled = scaler.fit_transform(X_binary)
# model.fit(X_scaled, y_binary)
# joblib.dump(scaler, 'iris_scaler.pkl')
# joblib.dump(model, 'iris_binary_model_scaled.pkl')
위 train_model.py를 먼저 실행하여 iris_binary_model.pkl 파일을 생성합니다.
# flask_api.py
from flask import Flask, request, jsonify
import joblib
import numpy as np
app = Flask(__name__)
# 모델 로드 (애플리케이션 시작 시 한 번만 로드)
try:
model = joblib.load('iris_binary_model.pkl')
print("모델 로드 성공!")
# scaler = joblib.load('iris_scaler.pkl') # 스케일러 사용 시 함께 로드
except FileNotFoundError:
model = None
# scaler = None
print("저장된 모델 파일을 찾을 수 없습니다. 'train_model.py'를 먼저 실행하세요.")
except Exception as e:
model = None
# scaler = None
print(f"모델 로드 중 오류 발생: {e}")
@app.route('/')
def home():
return "Iris Binary Classification API"
@app.route('/predict_iris', methods=['POST'])
def predict_iris():
if model is None:
return jsonify({'error': '모델이 로드되지 않았습니다.'}), 500
if request.is_json:
try:
data = request.get_json()
# 입력 데이터 형식 가정: {"features": [sepal_length, sepal_width, petal_length, petal_width]}
features = data.get('features')
if features is None or not isinstance(features, list) or len(features) != 4:
return jsonify({'error': '입력 데이터 형식이 올바르지 않습니다. "features" 키에 4개의 숫자 리스트를 제공해야 합니다.'}), 400
# 입력 데이터를 NumPy 배열로 변환
input_array = np.array(features).reshape(1, -1) # (1, 4) 형태
# (선택) 스케일링 적용 (학습 시 사용한 스케일러와 동일하게)
# if scaler:
# input_array_scaled = scaler.transform(input_array)
# prediction_proba = model.predict_proba(input_array_scaled)[0] # 각 클래스에 대한 확률
# prediction = model.predict(input_array_scaled)[0] # 예측 클래스
# else:
prediction_proba = model.predict_proba(input_array)[0]
prediction = model.predict(input_array)[0]
class_names = ['setosa', 'versicolor'] # 이진 분류 클래스 이름 (0, 1)
return jsonify({
'input_features': features,
'predicted_class_id': int(prediction),
'predicted_class_name': class_names[int(prediction)],
'probabilities': {'setosa': float(prediction_proba[0]), 'versicolor': float(prediction_proba[1])}
})
except Exception as e:
return jsonify({'error': f'예측 중 오류 발생: {str(e)}'}), 500
else:
return jsonify({'error': 'Request must be JSON'}), 400
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5001) # 다른 포트 사용