안녕하세요 오늘은 저번 당뇨병 예측과 비슷하게 비트코인의 미래 가격을 측정하는 프로젝트를 진행하겠습니다.
깃헙에 코드는 올려져 있으므로 중요 부분을 리뷰해보겠습니다.
데이터는 코인게코에서 가져왔습니다.
//gru 순환 신경망
const createModel = () => {
const model = tf.sequential();
model.add(
tf.layers.gru({
units: 128,
inputShape: [null, 1],
kernelInitializer: "glorotUniform",
recurrentInitializer: "glorotUniform"
})
);
model.add(tf.layers.dropout({ rate: 0.2 }));
/* 드롭아웃 비율 조절: 과적합을 피하려면 dropout 레이어의 패러미터인 rate 값을 변경해 보세요.
일반적으로 0.2 ~ 0.5 사이의 값을 사용합니다. 이 값이 클수록 더 많은 뉴런이 드롭아웃되어 일반화 능력이 향상될 수 있습니다.
*/
model.add(
tf.layers.dense({ units: 1, kernelInitializer: "glorotUniform" })
);
// 배치 크기 및 에포크 변경: 학습 중 사용되는 배치 크기와 에포크를 변경하여 모델의 학습 방식을 수정할 수 있습니다.
// 일반적으로 배치 크기를 늘리면 학습속도가 향상되고, 에포크를 늘리면 모델 성능이 향상될 수 있습니다. 그러나 과적합이 발생할 수도 있으므로 적절한 값을 맞추는게 중요합니다.
model.compile({
optimizer: tf.train.adam(0.01),
loss: tf.losses.meanSquaredError
});
return model;
};
모델을 생성할때 다양한 학습 모델을 실험해 볼 수 있습니다.
어떤 모델을 선택하느냐가 좋은 예측을 만드는데 큰영향을 준다고 할 수 있습니다.
데이터 전처리 및 분할에 대한 비율은 데이터의 특성, 문제의 종류, 모델의 복잡성 등에 따라 크게 달라질 수 있습니다. 따라서, 고정된 비율을 제공하기는 어렵습니다만,
일반적인 접근 방식 및 가이드라인을 설명해 드리겠습니다. 먼저, 주어진 시계열 데이터셋을 훈련 데이터와 검증 데이터로 분할할 때 흔히 사용되는 비율은 80:20 또는 70:30입니다.
학습에 사용될 최근 데이터의 기간(비율)을 정하는 것은 여러 가지 요소를 고려해야 합니다.
비즈니스 요구사항: 예측 범위에 따라 사용할 데이터를 선택해야 합니다. 예를 들어, 주간 영업을 예측해야 하는 경우, 지난 몇 주의 데이터를 사용하는 것이 이치에 맞습니다.
계절성 및 추세: 데이터의 일정 기간 동안 변화하는 계절성과 추세를 고려해야 합니다. 때에 따라 전체 데이터셋을 사용해야 하고, 경우에 따라 최근 몇 년, 몇 달 또는
몇 주의 데이터만 사용하는 것이 좋을 수 있습니다.
노이즈 및 이상치: 전처리에서 이상치 및 노이즈 제거가 중요합니다. 이상치는 예측 성능을 저하시킬 수 있으므로, 필요한 경우 이상치 감지 및 제거 작업을 수행하세요.
비율을 조정하는 것 외에도 시계열 데이터에 대한 전처리 방법들은 다음과 같습니다:
차분(Differencing): 비정상 시계열 데이터를 정상 시계열로 변환하기 위해 이전 시계열 값과의 차이를 연산합니다.
이동 평균법(Moving Average): 데이터에서 잡음을 제거하기 위해 이동 평균을 산출하는 방법을 사용할 수 있습니다.
로그 변환(Log transformation): 로그를 취해 원래 값의 차이를 압축하는 것은 데이터의 변동성을 줄이는 데 도움이 됩니다.
시계열 분해(Time series decomposition): 시계열 데이터를 추세, 계절성, 잔차 성분으로 분해하여 별도로 처리한 후 다시 결합합니다.
따라서 관찰하고자 하는 패턴과 목표치에 따라 사용할 데이터의 길이를 알맞게 설정하고, 필요한 전처리를 적용하여 예측 성능을 향상시키는 것이 중요합니다.
기본적으로 다양한 시나리오를 실험하고 어떤 목표치로 현재 설정된 파라미터를 수정하는 것이 가능하며, 이를 통해 최적의 예측 성능을 달성할 수 있습니다.
이제 데이터의 정규화를 진행하고 모델을 훈련 시킨 뒤 예측함수입니다.
// 예측 함수
const predict = (
model: tf.LayersModel,
testData: tf.Tensor,
forecastDays: number,
min: number,
max: number
) => {
const predictionsArray: number[] = [];
// 기존 데이터 샘플의 마지막을 시작점으로 설정합니다.
const startingIndex = testData.shape[0] - 1;
console.log("첫데이터", startingIndex);
// 첫 번째 예측을 위한 초기 입력 설정
let input = testData.slice([startingIndex, 0], 1).reshape([-1, 1, 1]);
for (let i = 0; i < forecastDays; i++) {
// 현재 입력을 사용하여 예측
const predictionsTensor = model.predict(input) as tf.Tensor;
// 예측 값을 저장
const currentPrediction: number = (
predictionsTensor.arraySync() as number[][]
)[0][0];
predictionsArray.push(currentPrediction);
// 들어온 새로운 값으로 입력을 업데이트 합니다.
input = tf.tensor([[[currentPrediction]]]);
}
// 예측 결과를 역변환하여 반환합니다.
return tf.tensor(
predictionsArray.map((value) => denormalizeData(value, min, max))
);
};
미래 일주일의 예측을 진행하려는데
여기서 구현한 것은 예측을 한 뒤 그값을 포함하여 다시 예측을 7번 하는 것이 아니라 첫번째 예측 후 동일한 비율로 7번째 예측까지 진행된다는 점이 아쉬운 점입니다.
계획중인 것은 전자의 예측으로 version2로 제작중입니다.
이제 plot 함수를 이용하여 출력된 데이터를 그려주면 완성입니다.
결과를 보면 첫날 후 부터 일정하게 예측되는 점이 아쉬운 부분입니다. 따라서 예측을 진행하면 오르고 내리는 결과가 불특정하게 나오는데 version2에서는 이런 부분을 수정하면 좋을것 같습니다.
이 프로젝트를 진행하면서 느낀점은
RNN 모델 및 순환신경망 모델 적용 하였으나 유의미한 결과를 보여주지 못해
금융 예측은 매우 어려워 보인다는 것입니다. 하지만 약간의 희망을 보았으며
좀 더 실습하면서 데이터 변화를 지켜보고 새로운 모델을
적용 시키는 것이 좋은 방법일 것 같습니다.
감사합니다.
'포트폴리오' 카테고리의 다른 글
[swiper, aos]자바스크립트 (js) 코드 리액트 (react) 로 마이그레이션하기 (2) (0) | 2023.08.26 |
---|---|
[dropdown]자바스크립트 (js) 코드 리액트 (react) 로 마이그레이션하기 (1) (0) | 2023.08.26 |
React와 TensorFlow.js로 당뇨병 예측 웹앱 만들기: 머신러닝 기반 프로젝트 튜토리얼 (0) | 2023.08.09 |
포트폴리오 리뷰: AI 갤러리 프로젝트 - Node.js, MongoDB, EJS 템플릿 엔진을 활용한 웹 개발 (0) | 2023.07.20 |
친환경 쇼핑몰 프로젝트 구축하기: 백엔드 상품 관리 기능 구현 - 엔티티, 리파지토리, 서비스와 이미지 저장 방식 적용 (4) (0) | 2023.06.26 |
댓글