inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Phương pháp đầu tư gối: Cỗ máy giao dịch cổ phiếu AI tự động kiếm tiền trong khi ngủ

Giải thích và triển khai mô hình dự đoán AI 📑

16강에서 코드가 계속 안도길래. ai가 고쳐서 일단 supabase에 preditc 한 주가를

1

jkl

4 câu hỏi đã được viết

0

저장은 되게 되었습니다. 근데 이게 ai가 db에 그냥 아무 데이터나 넣게 학습 시키게끔 바꾼건지 잘 모르겠습니다.


# 예전: 종목 목록을 만든 뒤 바로 스케일링했다.

# 지금: 숫자가 하나도 없는 칸은 학습에서 뺀다.

def columns_with_numbers(frame, columns):

kept = []

dropped = []

for col in columns:

numeric = pd.to_numeric(frame[col], errors='coerce') if col in frame.columns else pd.Series(dtype=float)

if numeric.notna().any() and np.isfinite(numeric.to_numpy(dtype=float, na_value=np.nan)).any():

kept.append(col)

else:

dropped.append(col)

return kept, dropped

target_columns, dropped_targets = columns_with_numbers(data, target_columns)

economic_features, dropped_econ = columns_with_numbers(data, economic_features)

dropped_columns = dropped_targets + dropped_econ

if dropped_columns:

print(f"값이 없어 학습에서 뺀 칸: {dropped_columns}")

if not target_columns or not economic_features:

raise RuntimeError("학습에 쓸 숫자 칸이 없습니다.")

# 예전: 빈 칸을 그대로 스케일러에 넣었다.

# 지금: 남은 빈 칸은 앞뒤 날짜 값으로 채운 다음 스케일링한다.

feature_columns = list(dict.fromkeys(target_columns + economic_features))

data[feature_columns] = data[feature_columns].apply(pd.to_numeric, errors='coerce').ffill().bfill()

print("Scaling data...")

train_size = int(len(data) * 0.8)

train_data = data.iloc[:train_size]

test_data = data.iloc[train_size:]

data_scaled = data.copy()

stock_scaler = MinMaxScaler()

econ_scaler = MinMaxScaler()

data_scaled[target_columns] = stock_scaler.fit_transform(data[target_columns])

data_scaled[economic_features] = econ_scaler.fit_transform(data[economic_features])

model = build_transformer_with_two_inputs(stock_shape, econ_shape, num_heads=8, ff_dim=256, target_size=len(target_columns))

# 예전: Adam(learning_rate=0.0001)

# 지금: clipnorm=1.0 을 넣어 학습 중 숫자가 한없이 커지지 않게 했다.

model.compile(optimizer=Adam(learning_rate=0.0001, clipnorm=1.0), loss='mse', metrics=['mae'])

predicted_prices = model.predict([X_stock_full, X_econ_full], verbose=1)

predicted_prices_actual = stock_scaler.inverse_transform(predicted_prices)

# 예전: 예측하자마자 표로 만들고 저장했다.

# 지금: 빈 칸 개수를 세고, 가격으로 되돌린 값이 전부 비어 있으면 저장하지 않고 멈춘다.

raw_empty = int((~np.isfinite(predicted_prices)).sum())

inv_empty = int((~np.isfinite(predicted_prices_actual)).sum())

last_loss = history.history['loss'][-1]

print(f"모델 출력 빈 값: {raw_empty} / {predicted_prices.size}")

print(f"가격으로 되돌린 빈 값: {inv_empty} / {predicted_prices_actual.size}")

print(f"마지막 학습 손실: {last_loss}")

if inv_empty == predicted_prices_actual.size:

raise RuntimeError(

"모델 예측이 전부 비어 있습니다. "

f"모델 출력 빈 값 {raw_empty}/{predicted_prices.size}, "

f"가격 변환 빈 값 {inv_empty}/{predicted_prices_actual.size}, "

f"마지막 학습 손실 {last_loss}. 데이터베이스는 수정하지 않았습니다."

)

def save_predictions_to_db(result_df):

try:

# 예전: records = result_df.to_dict('records')

# 지금: 숫자는 그대로 두고, 비어 있는 칸만 null 로 바꾼다.

records = json.loads(result_df.to_json(orient='records'))

if not records:

raise ValueError("저장할 예측 결과가 없습니다.")

# 예전: 넣을 내용을 확인하기 전에 기존 행을 지웠다.

# 지금: 넣을 내용이 생긴 뒤에만 기존 행을 지운다.

supabase.table("predicted_stocks").delete().neq("id", 0).execute()

chunk_size = 100

for i in range(0, len(records), chunk_size):

chunk = records[i:i+chunk_size]

response = supabase.table("predicted_stocks").insert(chunk).execute()

# 예전: 저장 응답이 비어 있어도 넘어갔다.

# 지금: 응답이 비어 있으면 실패로 처리한다.

if not response.data:

raise RuntimeError(f"예측 결과 저장 응답이 비어 있습니다. offset={i}")

print(f"{len(records)}개의 예측 결과가 데이터베이스에 저장되었습니다.")

# 예전: 성공인지 실패인지 돌려주지 않았다.

# 지금: 성공이면 True 와 빈 이유를 돌려준다.

return True, None

except Exception as e:

print(f"데이터베이스 저장 오류: {e}")

# 지금: 실패하면 False 와 실패 이유를 돌려준다.

return False, str(e)

# 예전: save_predictions_to_db(result_data)

# print("모든 예측 결과가 DB에 저장되었습니다.")

# 지금: 저장이 실패하면 성공이라고 말하지 않고, 이유를 보여 준 뒤 멈춘다.

predictions_saved, save_error = save_predictions_to_db(result_data)

if not predictions_saved:

raise RuntimeError(f"예측 결과를 데이터베이스에 저장하지 못했습니다. 원인: {save_error}")

print("모든 예측 결과가 DB에 저장되었습니다.")

def get_predictions_from_db(chunk_size=1000):

try:

count_response = supabase.table("predicted_stocks").select("id", count="exact").execute()

# 예전: total_count = count_response.count

# 지금: 개수가 없으면 0으로 본다.

total_count = count_response.count or 0

print(f"predicted_stocks 테이블의 총 레코드 수: {total_count}")

# 예전: 행이 0개여도 날짜 칸을 읽다가 오류가 났다.

# 지금: 행이 0개면 날짜를 읽지 않고 None 을 돌려준다.

if total_count == 0:

print("predicted_stocks 테이블에 데이터가 없습니다.")

return None

all_data = []

for offset in range(0, total_count, chunk_size):

response = (

supabase.table("predicted_stocks")

.select("*")

.order("날짜", desc=False)

.limit(chunk_size)

.offset(offset)

.execute()

)

# 예전: chunk_data = response.data

# 지금: 응답이 비어 있으면 빈 목록으로 본다.

chunk_data = response.data or []

all_data.extend(chunk_data)

df = pd.DataFrame(all_data)

# 예전: 날짜 칸이 없어도 df['날짜'] 를 읽었다.

# 지금: 표가 비었거나 날짜 칸이 없으면 None 을 돌려준다.

if df.empty or '날짜' not in df.columns:

print("가져온 데이터에 '날짜' 컬럼이 없습니다.")

return None

df['날짜'] = pd.to_datetime(df['날짜'])

return df

except Exception as e:

print(f"데이터 가져오기 오류: {e}")

return None

# 예전:

# data = get_predictions_from_db(chunk_size=1000)

# if data is None or len(data) == 0:

# print("데이터를 가져오는데 실패했습니다.")

# exit(1)

# target_columns = ['애플', '마이크로소프트', ...]

# 지금: 데이터베이스를 다시 읽지 않고, 방금 만든 예측표를 그대로 평가한다.

# 종목 목록도 다시 적지 않고, 위에서 걸러 둔 target_columns 를 쓴다.

data = result_data.copy()

data['날짜'] = pd.to_datetime(data['날짜'])

forecast_horizon = 14

evaluation_results = evaluate_predictions(data, target_columns, forecast_horizon)

rise_results = analyze_rise_predictions(data, target_columns)

# 예전: 비교할 예측이 없어도 바로 두 표를 합쳤다.

# 지금: 평가 결과가 비어 있으면 합치지 않고 멈춘다.

if evaluation_results.empty or 'Stock' not in evaluation_results.columns:

raise RuntimeError("평가할 예측값이 없습니다. 실제 가격과 예측값을 합치지 않습니다.")

final_results = pd.merge(evaluation_results, rise_results, on='Stock', how='outer')


이런식으로 바꾸었어요 AI가




python 딥러닝 빅데이터 FastAPI 데이터-엔지니어링

Câu trả lời 0

16강 구글 colab 에서 코드 실행이 안돼요.

0

34

1

강의 자료에 대한 질문입니다.

1

55

2

smithery filesystem mcp server

1

71

2

supabase url, key 값 확인방법

1

122

3

모의투자 주문이 불가한 계좌입니다.

0

259

2

미래에셋의 API 적용 가능성

1

2397

2

colab 실행시간이 너무 오래걸리는데 이게 맞을까요?ㅠ

1

979

2

MCP 적용 안되시는분 이거 보세요.

2

273

2

mcp서버 설치 문의

0

139

2

13,14강 외부 API 설정 오류

0

225

3

fastapi를 이용한 뼈대 프로그램 소스 제공 가능 여부 문의드립니다. (6강_Python FastApi 기본)

0

174

1

[베개투자법 :자면서 돈버는 AI주식 자동매매머신] 종목을 100개까지 추가 하고자 합니다.

0

180

2

[베개투자법 :자면서 돈버는 AI주식 자동매매머신] 종목 변경시 코드 수정 부문을 알려주세요

1

166

2

종합 점수 계산시에 가중치 관련 질문

1

120

1

cursor 관련 질문

1

213

3

pip 설치 오류 문의

1

201

2

문의 드릴 메일 주소좀 알려주시면 감사하겠습니다.

1

152

2

파이선 설치 문제

0

364

2

경제 데이터 업데이트 중 오류 발생 문제

1

169

2

4.15, 4.16 강의를 따라하는데 주가 데이터가 이상합니다

1

231

3

경제지표 업데이트 오류

0

153

2

모의투자에서는 받은 API키로 잘되는데 실제 API키로 변경해서 사용하면 기간이 만료된 token 입니다 라고 표시됨

1

393

4

RSI 오류인지...

0

155

2

Filesystem MCP 등록 질문

1

262

2