장고로 작성한 웹에서 근무년수를 입력하면 예상 연봉이 나올 수 있도록 프로그래밍 하시오.
LinearRegression 사용. Ajax 처리!!!
먼저 요청명을 받는 urls.py 부터 확인
from django.contrib import admin
from django.urls import path
from my_jikwon import views # my_jikwon 어플리케이션 생성
urlpatterns = [
path("admin/", admin.site.urls),
# 요청 시 'show.html'로 render 역할
path("", views.mainFunc),
# 요청 시 회귀분석 결과를 ajax 에게 전달역할
path("predict", views.predictFunc),
]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function predFunc(){
let sendData = {};
let year = $("#year").val();
sendData['year'] = year;
// console.log(sendData);
$(".predPay").empty();
$(".r2s").empty();
$(".listPay").empty();
$.ajax({
url:"predict",
type:"POST", // POST로 요청시 받는 함수 에 @csrf_exempt 적용해주어야한다.
data:sendData,
dataType:"json",
success:function(data){
// console.log(data)
$(".predPay").append(`근무년수 <b>${year}년</b> 에 대한 예상 연봉은 <b>${data.new_pred}</b>`);
$(".r2s").append(data.r2s);
$(".listPay").append(data.pay_jik);
}
});
}
</script>
</head>
<body>
<h2>근무년수에 따른 예상 연봉 알기</h2>
근무 년수 입력 : <input type="text" id="year" size="5" value="1">년
<button onclick="predFunc()">연봉 확인</button>
<br><br>
<div class="predPay"></div>
설명력 : <span class="r2s"></span>
<br>
직업별 연봉 평균 <br>
<div class="listPay"></div>
</body>
</html>
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
import json
from datetime import datetime
from django.http.response import HttpResponse, JsonResponse
import joblib
from my_jikwon.models import Jikwon
# Create your views here.
flag = False
def mainFunc(request):
global flag
# 이렇게 if 문을 걸어주면 처음 브라우저 서비스 시작하면서 모델을 한번만 만들고 계속 사용가능하다.
if flag == False:
makeModel()
flag = True
return render(request, 'show.html')
def makeModel():
# jikwon 테이블에서 근무년수에 대한 연봉을 이용하여 회귀분석 모델을 작성
datas = Jikwon.objects.values('jikwon_ibsail', 'jikwon_pay', 'jikwon_jik').all()
jikdf = pd.DataFrame.from_records(datas)
# print(jikdf.head(3), len(jikdf))
# 근무년수 구하기
for i in range(len(jikdf['jikwon_ibsail'])):
# jikdf['jikwon_ibsail'][i] = int((datetime.now().date() - jikdf['jikwon_ibsail'][i]).days / 365)
jikdf['jikwon_ibsail'][i] = int((datetime.now().date() - jikdf['jikwon_ibsail'][i]).days / 365)
jikdf.columns = ['근무년수', '연봉', '직급']
# print(jikdf.head(3))
# train / test split (8:2)
train_set, test_set = train_test_split(jikdf, test_size=0.2, random_state=12)
print(train_set.shape, test_set.shape)
# (24, 3) (6, 3)
model_lm = LinearRegression().fit(X=train_set.iloc[:,[0]], y=train_set.iloc[:,[1]])
# 성능 확인
test_pred = model_lm.predict(test_set.iloc[:,[0]])
print('연봉 예측값 :', test_pred[:5].flatten())
print('연봉 실제값 :', test_set.iloc[:,[1]][:5].values.flatten())
'''
연봉 예측값 : [6827.05696203 4767.56329114 5282.43670886 3737.8164557 7341.93037975]
연봉 실제값 : [7800 6600 5500 4000 8800]
'''
global r2s
r2s = r2_score(test_set.iloc[:,[1]], test_pred)
print('결정계수(설명력) :', r2s)
#>> 결정계수(설명력) : 0.5523021663542762
# 모델 저장(객체를 저장, 모델을 만들고 저장하는 과정 중요)
joblib.dump(model_lm, 'django16linear/my_jikwon/static/jik_year.model')
# 직급별 연봉 평균
global pay_jik
pay_jik = jikdf.groupby('직급').mean().round(1)
print('pay_jik :', pay_jik)
@csrf_exempt # csrf token 을 적용하지 않음
def predictFunc(request):
year = request.POST.get('year')
# print('year :', year)
new_year = pd.DataFrame({'근무년수':[year]})
# 모델을 읽어 해당 년도에 연봉을 예측하여 클라이언트에게 전송
model = joblib.load('django16linear/my_jikwon/static/jik_year.model')
new_pred = round(model.predict(new_year)[0][0], 2)
print('new_pred : ', new_pred)
context = {'new_pred':new_pred, 'r2s':r2s, 'pay_jik':pay_jik.to_html()}
# return render(request, 'show.html', )
# return HttpResponse(json.dumps(context), content_type='application/json')
return JsonResponse(context)