저번 시간에는 인공지능 모델을 만들어 봤는데요.
이번 시간에는 모델을 통해 얻은 데이터를 리액트와 연동시켜보는 시간을 가져보겠습니다.
NodeJS와 같은 서버 역할을 하게 됩니다.
설치를 하기 위해서 VScode에서 서버 디렉토리에서 터미널을 엽니다.
를 입력해서 설치해줍니다.
다음은 중요한 포인트인 CORS설정입니다.
포트가 다를 때 포트 접근을 허용해주는 정책입니다.
이렇게 코드를 추가하면 CORS설정이 끝이납니다.
from flask import Flask, request, jsonify
import pandas as pd
import numpy as np
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
# 데이터 로드
pill_data = pd.read_csv('Final_Pill_Standardization_Content_Dataset.csv', header=0, encoding='cp949')
food_data = pd.read_csv('food_dataset.csv', encoding='cp949')
daily_intake_data = pd.read_csv('연령별_일일_섭취량_데이터셋.csv', header=0, encoding='cp949')
child_pill_index = [2,33,40,50,63,69,85,87,89,106,129,142,143,148,161,164,
166,168,182,188,191,200,210,225,232,235,237,238,245,246,258,265,266,
269,271,274,296,304,308,315,343,348,350,353,376,383,386,394,395,397,
413,423,424,428,430,435,440,455,457,484,488,493,502,536,539,544,545,
594,604,614,617,621,624,639,647,648,649,665,678,679,684,701,712,725,
731,747,749,750,791,804,811,821,849,850,851,868,879,888,897,901,912,
921,933,937,946,962,974,999,1026,1030,1039,1040,1044,1061,1079,1086,
1095,1106,1107,1113,1118,1122,1126,1140,1144,1147,1173,1174,1176,1192,
1193,1195,1204,1212,1237,1240,1242,1245,1251,1258,1260,1266,1278,1281,
1286]
# 제외할 영양제 인덱스
except_list_index = [6,15,35,41,67,77,79,80,89,90,109,115,121,126,142,164,
202,213,237,255,259,276,277,278,285,290,298,319,324,333,336,337,339,341,
342,345,346,349,355,366,391,403,411,421,443,448,475,484,491,497,536,600,
608,627,629,632,634,636,644,647,648,649,651,655,656,660,668,689,690,701,
723,728,745,746,747,753,755,756,760,782,789,792,828,841,852,857,862,868,
869,874,879,885,886,904,916,935,946,968,974,1044,1061,1072,1073,1106,1109,
1113,1114,1115,1134,1147,1148,1153,1164,1169,1186,1188,1209,1226,1230,1231,
1240,1254,1263,1264,1266,1271,1286,1291]
# 임의로 정한 권장 섭취량 정보
recommended_intake = {
'1인분칼로리(kcal)': 300.0,
'탄수화물(g)': 80,
'단백질(g)': 5,
'지방(g)': 1.0,
'콜레스트롤(g)': 0.0,
'식이섬유(g)': 0.0,
'나트륨(g)': 230.0,
}
# BMI 계산 함수
def bmicalc(x):
if x < 18.5:
y = "저체중"
elif 18.5 <= x < 23:
y = "정상 체중"
elif 23 <= x < 25:
y = "과체중"
elif 25 <= x < 30:
y = "경도 비만"
else:
y = "고도 비만"
return y
def get_nutrient_info(food_name):
nutrient_info = food_data[food_data['음식명'] == food_name].iloc[:, 1:].fillna(0).squeeze()
return nutrient_info.to_dict() if not nutrient_info.empty else {}
# 부족한 영양소 찾는 함수
def find_deficient_nutrients(diet, recommended_intake):
deficient_nutrients = {}
for nutrient, intake in recommended_intake.items():
if nutrient in diet:
diff = intake - diet[nutrient]
if diff > 0:
deficient_nutrients[nutrient] = diff
return deficient_nutrients
# 영양제 추천 함수
def recommend_pills(diet, recommended_intake):
difference = {}
for nutrient, intake in recommended_intake.items():
difference[nutrient] = diet.get(nutrient, 0) - intake
pill_distance_list = []
for i in range(len(pill_data)):
pill_distance_list.append(distance(pill_data.iloc[i], difference))
recommendation = {}
for idx, distance_val in sorted(enumerate(pill_distance_list), key=lambda x: x[1])[:3]:
if idx not in child_pill_index and idx not in except_list_index:
recommendation[f'pill_{idx}'] = distance_val
return recommendation
# 거리 계산 메소드
def distance(x, y):
x_values = x.values
y_values = np.array(list(y.values()) + [0.0] * (len(x_values) - len(y)))
a = np.linalg.norm(x_values - y_values)
return a
# BMI 계산 메소드
def calc(vJson):
height = vJson['height']
height = int(height) / 100
weight = vJson['weight']
weight = int(weight)
age = vJson['age']
age = int(age)
BMI = weight / (height * height)
bmi_string = bmicalc(BMI)
vJson['BMI'] = {
'value': round(BMI, 2),
'status': bmi_string
}
return vJson
@app.route('/recommendation', methods=['POST'])
def get_recommendation():
data = request.get_json()
food_name = data['food_name']
intake_amount = get_nutrient_info(food_name)
deficient_nutrients = find_deficient_nutrients(intake_amount, recommended_intake)
recommendation = recommend_pills(intake_amount, recommended_intake)
response = {
'food_name': food_name,
'intake_amount': intake_amount,
'deficient_nutrients': deficient_nutrients,
'recommendation': recommendation
}
return jsonify(response)
if __name__ == '__main__':
app.run(debug=True)
전체 코드입니다. 저번에 만든 모델에서 코드가 조금 추가되었습니다.
/recommendation에 대한 Post 요청에 관한 코드입니다.
음식 이름, 섭취량, 부족한 영양소, 추천 영양제를 클라이언트에 넘겨줍니다.
그럼 Flask 서버를 실행시켜 봅시다.
이렇게 입력하면 됩니다.
저 같은 경우는 Python apps.py 이렇게 입력해야합니다.
터미널에 이런 메세지가 뜨면 실행에 성공한 겁니다.
다음은 데이터를 가져올 페이지를 만들어 줍니다.
임의로 chatGPT를 이용해서 만들었습니다.
인풋창에 식단을 입력하면 식단에 대한 영양제 추천 로직을 적용하여 페이지에 적용합니다.
이때 엔드포인트는 Flask 서버 기본주소 + 만든 엔드포인트 입니다.
CSS를 하나도 신경 안썼지만 데이터 확인만 하면 되므로 입력해봅시다.
음식에 관한 로직을 적용하여 클라이언트로 데이터를 성공적으로 넘겨준 것을 확인할 수 있습니다.
오늘은 Flask를 사용해서 데이터를 넘겨오는 작업을 해봤습니다.
앞으로는 모델을 구체화하고 페이지의 UI도 개선할 예정입니다.