21.06.27
- 위와 같은 화면에서 나이, 성별, 효능을 체크한 뒤에 제품 조회 버튼을 누르면 해당 정보를 Flask로 보낸다.
- 이때 정보를 보낼 때에는 Ajax를 활용한다.
- Flask는 정보를 받으면 학습된 머신러닝 모델에 의해 답을 도출하고, 해당 값을 다시 Ajax에게 보낸다.
- Ajax는 통신이 성공하고, 값을 받으면 쿼리 스트링 형식으로 조회 페이지로 이동한다.
Flask
from flask import Flask
from flask import request
import pandas as pd
from flask_cors import CORS
import pickle
app = Flask(__name__)
# 내가 만든 모델을 "test.pkl"이란 파일에 저장, 해당 모델을 불러온다
test = pickle.load(open('test.pkl', 'rb'))
#POST 방식으로 값을 불러올경우 인코딩 과정 없이 받게 해줌
CORS(app)
@app.route("/", methods = ["GET", "POST"])
def connect():
value="hello"
if request.method == 'POST':
train_tes = []
#POST 형식으로 전송된 값을 value에 저장
value = dict(request.form)
#저장된 값을 DataFrame으로 변환한다.
df = pd.DataFrame(value, index=[0])
#pickle을 통해 불러온 모델에 불러온 값을 학습시켜 모델 값을 받는다.
value = str(int(test.predict(df)))
print(value)
#학습시킨 값을 return.
return value
if __name__ == "__main__" :
app.run()
Flask를 활용하는 전체 코드는 위가 전부다. 3등분해서 하나씩 보자.
from flask import Flask
from flask import request
import pandas as pd
from flask_cors import CORS
import pickle
- 값을 통신하기 위한 Flask, 값을 받기 위한 request를 import
- Pandas는 내가 받은 데이터를 DataFrame형식으로 모델에 학습하기 위해서 필요하다.
- CORS는 Cross-Origin Resource Sharing의 약자로, 다른 Origin과 통신할 때에 나는 에러 중 하나인데, 이에 대한 부분은 좀 더 자세히 알아보자.
- pickle은 내가 학습시킨 모델을 하나의 파일로서 쓰는 방법이다.
- 내가 모델을 쓸 때마다 다시 학습시키고 하지 않아도 된다는 거다!!
app = Flask(__name__)
# 내가 만든 모델을 "test.pkl"이란 파일에 저장, 해당 모델을 불러온다
test = pickle.load(open('test.pkl', 'rb'))
#POST 방식으로 값을 불러올경우 인코딩 과정 없이 받게 해줌
CORS(app)
@app.route("/", methods = ["GET", "POST"])
#=================================================================
if __name__ == "__main__" :
app.run()
- 우선 가운데 나온 def 부분은 짜르고 위와 아랫부분만 리뷰
- app이란 변수에 Flask를 사용하기 위해 할당해주는데, 이때 __name__ 은 해당 모듈의 이름을 반환한다.
- 만일 내가 직접 해당 파일을 실행하면 __name__ 은 __main__을 반환하고, import하는것 처럼 외부에서 불러들여 사용하게 되면 해당 파일의 이름이 출력된다.
- 때문에 아래에 해당하는 __name__ == "__main__" 이 부분은 해당 파일을 직접 실행했느냐를 묻는 부분이라 생각하면 된다.
- pickle은 내가 학습시킨모델을 불러오기 위해 사용하였다. test.pkl 이란 파일에 모델을 저장했고, 해당 파일을 불러오기 위해 'rb' 라는 키워드를 사용한 것.
- pickle을 저장하고, 불러올 때는 바이트 형식으로 이뤄진다.
- rb는 read binary의 약자이며, 내가 만일 모델을 저장하고 싶을 때는 wb라는 키워드를 사용하는데, 뜻은 write binary이다.
- CORS는 내용이 많을것 같으니... 아래에서 다시 다루자
- @는 Decorator라 불리며, 간단하기 말하자면 @ 다음에 나오는 대상을 앞, 뒤로 꾸며줄 수 있게 한다.
- 만일, test라는 이름으로 define했을 때, @test라 하면 그 다음 구문부터 해당 함수에 뭔가 추가할 작업을 입력하는 것.
- 즉, 위의 코드는 @app 으로 내가 Flask를 할당하고 나서, 계속해서 어떤 작업을 행할건지 이어나가 작성하는 것이다.
- 딱 이정도까지만 이해하자 어렵다....
- route안에 첫번째는 경로를 입력하며, 2번째는 내가 통신에 있어 사용할 방식들을 입력하였다.
- / 는 뭐... 최상위 경로랄까?? 웹 페이지에서 내가 사용하는 기본 주소를 나타낸다. : http://localhost:포트번호/
def connect():
value="hello"
if request.method == 'POST':
train_tes = []
#POST 형식으로 전송된 값을 value에 저장
value = dict(request.form)
#저장된 값을 DataFrame으로 변환한다.
df = pd.DataFrame(value, index=[0])
#pickle을 통해 불러온 모델에 불러온 값을 학습시켜 모델 값을 받는다.
value = str(int(test.predict(df)))
print(value)
#학습시킨 값을 return.
return value
- 우선 내가 Ajax로 부터 POST 형식으로 값을 받을 것이다.
- 여기서 request.method는 전송 방식을 리턴해주는 구문인데, Ajax가 POST 형식으로 값을 전송하기 때문에, 위와 같이 조건문을 걸어주었을 때, true를 반환할 것이다.
- 보낸 데이터가 POST 형식일 때, request.form 이란 구문으로 데이터를 받아올 수 있다.
- GET방식인 경우에는, request.args 로 데이터를 받아올 수 있다.
- 아래에 Ajax 관해 쓰겠지만 JSON(객체) 형식으로 데이터를 보냈다. 때문에 받자마자 Dictionary로 변환한다.
- 받은 데이터는 학습시키기 위해서 DataFrame으로 변환해준다.
- index는 딕셔너리로 DF를 만들 때에, 안의 value값들이 모두 Scalar라서 에러가 발생할 수 있어 줬다.
- 안주면 "If using all scalar values, you must pass an index" 라는 에러가 난다. 그래서 일단 아무거나 줬다.
- 만일 저렇게 하기 싫다면 value에 해당하는 값들을 모두 리스트 형식으로 주면 된다.( ex - {1:[2], 3:[4]} )
- 나는 test라는 변수 안에 pickle을 통해 학습된 모델을 담았다.( 위에서 언급했다.) 해당 모델을 통해 predict 값을 가져온다.
- 음... 근데 굳이 int형으로 바꾸고 나서 다시 String으로 바꿔준 이유는 기억이 안나는데..... 무튼 좀 독특했던것 중 하나는 int형 데이터를 return이 안되더라. 어... 이건 모르겠다. 나중에 찾자
위와 같이 작성하여 Ajax를 통해 입력 받은 데이터를 기반으로 내가 만든 모델을 통해 predict 값을 받을 수 있다.
Ajax
var val_test = $('input:checkbox[name=chk1]');
let check_dic = {"나이" : <%=age_t%>};
for (let i = 0; i < val_test.length; i++) {
if ($(val_test[i]).is(':checked')) {
check_dic[$(val_test[i]).val()] = '1';
} else {
check_dic[$(val_test[i]).val()] = '0';
}
}
$.ajax({
type : 'post',
url : 'http://127.0.0.1:5000/',
data : check_dic,
dataType : 'json',
success : function(res) {
window.location.href = "page3.jsp?model=" + res;
},
error : function() {
alert('요청 실패쓰');
}
})
플라스크와 연동하기 위한 부분, 2개로 나눠 리뷰한다.
var val_test = $('input:checkbox[name=chk1]');
let check_dic = {
"나이" : <%=age_t%>
};
for (let i = 0; i < val_test.length; i++) {
if ($(val_test[i]).is(':checked')) {
check_dic[$(val_test[i]).val()] = '1';
} else {
check_dic[$(val_test[i]).val()] = '0';
}
}
- val_test 라는 변수에 타입이 checkbox 인 input 태그 중에서, name 값이 chk1 인걸 전부 담는다.
- check_dic 이란 이름의 객체를 선언해줬다. 나중에 모델의 학습을 위함. 이때 나이의 경우는 text 타입이라 그냥 바로 입력해줬다.
- 반복문을 통해 내가 원하는 방식으로 객체를 만들어 나간다.
- 체크박스를 모두 담았던 val_test의 길이만큼 반복문 실행
- val_test의 i번째가 체크되었는지 안되었는지는, is(':checked')라는 구문을 사용하면 boolean 형태로 받을 수 있다
- 체크되면 1, 아니면 0을 준다.
- check_dic 의 키 값을 val_test의 i번째 값으로 지정한다. 해당 값은 input 태그의 value 값인데, 나는 그 값들을 모두 체크리스트 이름과 동일하게 줬다. ( ex - 피로회복, 눈건강 등등 )
- 객체에 값을 추가하는 방법 중 하나이다.
$.ajax({
type : 'post',
url : 'http://127.0.0.1:5000/',
data : check_dic,
dataType : 'json',
success : function(res) {
window.location.href = "page3.jsp?model=" + res;
},
error : function() {
alert('요청 실패쓰');
}
})
- Ajax의 통신 방법은 post, 연결한 url은 플라스크로 지정해주며, 보낼 데이터는 내가 만든 객체인 check_dic이다.
- 객체를 전송하기 때문에 보낼 데이터의 타입을 json 형태로 지정한다.
- success는 내가 통신에 성공했을 경우의 동작을 지정해주며, function안의 res 는 내가 return 받은 데이터의 이름이다.
- 값을 전송 받으면 바로 다음 페이지로 이동하는데 이때 쿼리 스트링 형식으로 model이란 이름과 함께 리턴 받은 데이터를 전송해주었다.
반응형
'국비교육기관 > 플젝' 카테고리의 다른 글
FireBase - NoSQL과 SQL(관계형 데이터 베이스) (0) | 2021.08.12 |
---|---|
3차 플젝 map 태그와 area (0) | 2021.08.06 |
2차 플젝_Flask연동_CORS와 관련해서 (0) | 2021.06.27 |
1차_프로젝트_21.04.22~04.28 (0) | 2021.05.02 |
댓글