WIL

03/15 WIL

네디0318 2024. 3. 15. 21:24

이번주에 한 것

코드카타

실전 프로젝트 발표

스파크 강의 듣기

 

프로젝트와 프로젝트 기간 중 있는 예비군 때문에 체력 소모가 심했는지 주 중반까지 체력이 돌아오질 않다가 수요일, 목요일 쯤 되어서야 원상태로 회복.

거기에다가 새로 만난 조원분들까지 좋아서 더더욱 컨디션과 기분이 좋아진 것 같다. 이대로 최종프로젝트까지 했으면.

학습은...일단 튜터님이  해보라고 하신 파이썬 패키지가 계속 막혀서 하루를 거의 통으로 날렸곸ㅋㅋ 거기에다가 체력이 후달리니 진도를 생각보다 못 나갔다.  이제라도 정신차렸으니 주말에 좀좀따리로 추가 학습할 예정.

 

이제 캠프도 한달 남짓밖에 안 남았다~~~


PYTHON

주가 예측 및 수익률 예측 코드

def showmetheprophet(corp_name, 원화투자금):           #원화 금액 입력하면 환전
  current_datetime = datetime.now().strftime("%Y-%m-%d")
  start_year = datetime.now().year - 5         # 현재 기준 5년 전까지의 데이터 사용
  start_datetime = datetime.now().replace(year=start_year)
  start_date_str = start_datetime.strftime("%Y-%m-%d")
  corp = yf.download(corp_name, start=start_date_str, end=current_datetime) #입력 날짜 기준으로 주식 데이터 다운로드
  corp['ds'] = pd.to_datetime(corp.index, format = '%Y-%m-%d')
  corp['y'] = corp['Adj Close']                           #조정 마감가를 y에 할당
  corp_train = corp[['ds', 'y']][:-251]

  #모델 적합

  model_prophet = Prophet(changepoint_prior_scale = 0.15, daily_seasonality = True, seasonality_mode='multiplicative', n_changepoints=100, seasonality_prior_scale=0.05)

  model_prophet.fit(corp)

  #향후 1년간의 time stamp 생성

  fcast_time_with_weekends = 365 #365일 예측
  corp_forecast = model_prophet.make_future_dataframe(periods=fcast_time_with_weekends, freq='D')

  # 주말을 제외한 날짜 범위 생성
  corp_forecast['exclude_weekend'] = corp_forecast['ds'] + BDay(0)
  corp_forecast = corp_forecast[corp_forecast['ds'].dt.weekday < 5]
  corp_forecast = model_prophet.predict(corp_forecast)
  model_prophet.plot(corp_forecast, xlabel = 'Date', ylabel= 'adj price($)')
  plt.show()

  #투자금에 따른 주식 구매량 및 수익률

  #0)환전
  cc = CurrencyConverter()
  dollor = round(cc.convert(원화투자금, 'KRW', 'USD'), 0)

  #1)입력한 현재 날짜 기준 금액 구하기
  current_price = corp_forecast.query('ds == @current_datetime').iloc[0]['yhat']
  #주문가능 수량 및 잔여금
  amount = dollor//current_price
  purchasable_price = round(amount*current_price, 2)
  residue = round(dollor%current_price,2)
  print("현재 날짜 기준 주문 가능 수량은 약", amount, "개이며, 총", purchasable_price, "달러입니다. 잔여금은", residue, "달러입니다")

  #예상 수익(평균) 및 수익률(평균)
  avg_f_price = corp_forecast.iloc[-1]['yhat']    #yhat칼럼의 맨 마지막 행 값 가져오기
  expected_avg_total_price = round(amount*avg_f_price,2)
  expected_avg_profit = round(expected_avg_total_price-purchasable_price, 2)
  avg_profit_percentage = round((avg_f_price-current_price)/current_price*100, 2)
  print("1년 후 총금액의 예상 평균치는", expected_avg_total_price, '달러이며, 그에 따른 수익은', expected_avg_profit, '입니다. 예상 수익률은', avg_profit_percentage, '% 입니다.' )

  #예상 수익(최대) 및 수익률(최대)
  upper_f_price = corp_forecast.iloc[-1]['yhat_upper']    #yhat칼럼의 맨 마지막 행 값 가져오기
  expected_upper_total_price = round(amount*upper_f_price,2)
  expected_upper_profit = round(expected_upper_total_price-purchasable_price, 2)
  upper_profit_percentage = round((upper_f_price-current_price)/current_price*100, 2)
  print("1년 후 총금액의 예상 최대치는", expected_upper_total_price, '달러이며, 그에 따른 수익은', expected_upper_profit, '입니다. 예상 수익률은', upper_profit_percentage, '% 입니다.' )

  #예상 수익(최저) 및 수익률(최저)
  lower_f_price = corp_forecast.iloc[-1]['yhat_lower']    #yhat칼럼의 맨 마지막 행 값 가져오기
  expected_lower_total_price = round(amount*lower_f_price,2)
  expected_lower_profit = round(expected_lower_total_price-purchasable_price, 2)
  lower_profit_percentage = round((lower_f_price-current_price)/current_price*100, 2)
  print("1년 후 총금액의 예상 최저치는", expected_lower_total_price, '달러이며, 그에 따른 수익은', expected_lower_profit, '입니다. 예상 수익률은', lower_profit_percentage, '% 입니다.' )

  #예측력 테스트
  #기존 데이터의 마지막 1년을 test용으로 할당
  corp_test = corp[-251:]


  # 예측
  future = corp_test[['ds']]  # 테스트 데이터의 날짜 칼럼을 그대로 사용하여 future 데이터프레임 생성
  forecast = model_prophet.predict(future)

  # 평가
  y_pred = forecast['yhat'].values
  y_true = corp_test['y'].values
  mae = mean_absolute_error(y_true, y_pred)
  print('   ')
  print('<예측력 평가 지표 및 Train 데이터-Test데이터 비교 그래프>')
  print('MAE: %.3f' % mae)
  mse = mean_squared_error(y_true, y_pred)
  print('MSE: %.3f' % mse)

  rmse = np.sqrt(mse)
  print('RMSE: %.3f' % rmse)


  plt.plot(y_true, label='Actual')
  plt.plot(y_pred, label='Predicted')
  plt.title('Predictability Test')
  plt.legend()
  plt.show()

 


SQL

 

1280.Students and Examinations 복습

CROSS JOIN, LEFT JOIN 활용

https://leetcode.com/problems/students-and-examinations/description/

 

오답

select e.student_id,
       s.student_name,
       su.subject_name,
       if(count(*) = Null, 0, count(*)) attended_exams
from subjects su join examinations e using(subject_name) join students s using(student_id)
group by 1, 2, 3
order by 1, 3

오답 이유

문제에서 원하는 아웃풋은 아래에서 볼 수 있뜻 count가 0인 것도 테이블에 표시가 되는 거였는데, 위와 같은 방식으로 하면 0인 행은 출력이 되지 않았다. 그래서 if절로 count가 null일 경우 0을 출력하라고 했으나 결과는 마찬가지(0일 경우도 마찬가지)

지난번에 풀었을 때에도 이런식으로 접근했던 것 같은데...암튼

 

정답

select s.student_id,
       s.student_name,
       su.subject_name,
       count(e.subject_name) attended_exams
from students s cross join subjects su left join examinations e using(student_id, subject_name)
group by 1, 2, 3
order by 1, 3

포인트

  1. 크로스 조인과 레프트 조인을 적절히 활용 : 최근에 자주 사용하지 않았더니 쓸 생각을 사실상 안 했던듯 하다..ㅎ
  2. examinations를 left join 하기 위해 칼럼 일치 시킬 때 student_id, subject_name 둘 다 사용할 것! : 안 그러면 아래 테이블처럼 student_id, student_name에 따른 그룹화 및 카운트가 제대로 이루어지지 않음

 

아웃풋

| student_id | student_name | subject_name | attended_exams |
| ---------- | ------------ | ------------ | -------------- |
| 1          | Alice        | Math         | 3              |
| 1          | Alice        | Physics      | 2              |
| 1          | Alice        | Programming  | 1              |
| 2          | Bob          | Math         | 1              |
| 2          | Bob          | Physics      | 0              |
| 2          | Bob          | Programming  | 1              |
| 6          | Alex         | Math         | 0              |
| 6          | Alex         | Physics      | 0              |
| 6          | Alex         | Programming  | 0              |
| 13         | John         | Math         | 1              |
| 13         | John         | Physics      | 1              |
| 13         | John         | Programming  | 1              |