카테고리
Submission Archivesubmission
코드와 해설을 함께 읽는 학습 문서
Code Detail
Signal Processing + Statistics 중심의 Octave 학습 예제
ex-recv/02/02_lsh/main_02_lsh.m
코드를 복사해 Octave에서 바로 실행할 수 있습니다.
function header_names = get_csv_header_name(filepath)
219 lines
######################################################################################################################
% 주제: 하나의 데이터 세트를 읽어서 대표값과 특징을 계산하고 그리는 연습을 합니다.
% 1. 구글의 2024년도 주가 데이터를 준비하라.
% 1) 첨부 파일: google_data_2024.csv
% 2. 1년치 데이터의 종가에 대해 통계 항목을 계산하라.
% 1) 통계 항목: mean, variance, standard deviation, rms
% 2) 정의식에 의해 직접 계산하고 함수를 작성하라.
% 3) Octave가 제공하는 함수를 사용하여 계산하라.
% 4) 두 계산 결과를 비교하라.
% 3. 같은 데이터에서 30일째 이후부터 직전 30일에 대해서 통계 항목을 계산하고 차트를 그려라.
% 1) 가로축은 날짜 또는 정수 인덱스를 사용한다.
% 2) 직접 만든 함수를 사용하라.
% 주문 1:
% - Octave 프로그램을 작성하여 제출
% - 수신: <sunggyu.won@ecoe.kr>
% - 기간: 2025-03-25 ~ 2025-04-01
% - 이메일 제목에 [Octave] 포함
% - 압축 파일 이름 02_wsg.zip (wsg는 이름 이니셜)
% - 메인 파일 이름은 main_02_wsg.m (wsg는 이름 이니셜)
% 주문 2:
% - 프로그램 작성 순서
% 1. 프로그램 상단에 주석 작성
% 1. 프로그램 설명. 작성자. 작성 날짜
% 2. 입력 변수 준비
% 1. csv 파일을 읽는 함수를 작성
% 3. 연산 실행
% 1. mean, variance, standard deviation, rms를 계산하는 함수를 작성
% 4. 플로팅 변수 준비
% 5. 플로팅 실행
% - 체크 포인트
% - 함수
% - 직접 계산하는 내용은 굳이 함수로 작성하고 호출하라.
% - 작성된 함수에 함수 설명, 입력 목록, 출력 목록을 주석으로 기록하라.
% - 루프 풀어쓰기는 가능하면 벡터 연산으로 축약하라.
% - 변수
% - 연산 결과를 변수에 저장하라.
% - 플로팅 변수로서 임시 변수(행렬의 슬라이스, 연산식)를 사용하지 말라.
% - 지금 사용하지 않을 대량의 데이타는 메모리 변수가 아니라 파일에 저장하라.
######################################################################################################################
# 작성자 : 이성한Y
# 작성 완료 날짜 : '25.03.26 (수)
# 설명 : csv 데이터를 읽고 통계를 계산합니다. 통계는 나만의 통계함수와 octave 내장 통계함수 사용가능.
# csv 데이터는 컬럼별로 데이터를 별도로 저장하나, 현 데이터는 첫번째 컬럼 Dates 규칙이 어긋나 예외처리.
# Window size와 Stride를 주면 Rolling 작업을 하여 시간 흐름에 따른 통계 변화를 plot합니다.
# (Function의 경우, 별도의 m파일로 빼내서 쓰진 않았음)
########################################################################################################################################
# 1. 데이터 준비
% Prefare dataset
pkg load signal
work_path = pwd; % 파일 경로 설정, 알맞게 변경하기 (print work directory: 작업 디렉토리 반환)
filename = 'google_data_2024.csv';
fullpath = fullfile(work_path, filename); % 파일경로 완성용
name_pattern = "2024stock_%s.m";
fid = fopen(fullpath, "r");
# Function description : get csv file's header name
function header_names = get_csv_header_name(filepath)
# target input : Header 포함된 csv file (Header 존재 여부 체크 하는건 별도로 안달았음, 필요하면 만들기)
# target output : Header_name (class : cell)
fid = fopen(filepath, "r"); % file identifier 축약 : fid , 열리지 않을 시, -1 반환
if fid == -1
error("파일을 열 수 없습니다 : %s", filepath)
end
header_line = fgetl(fid); % 공백 아닌 첫 1줄 읽기
fclose(fid);
header_names = strsplit(header_line, ",");
end
cols_name = get_csv_header_name(fullpath); % (Price, Close, High, Low, Open, Volume), Price는 잘못 표기되었고, Dates가 맞음. 별도처리
% Price data
stock_data = dlmread(filename, ",", 3, 0);
price_data = stock_data(:,2:end);
% Date (String 별도 읽기 필요한 것으로 보임, dlmread는 날짜가 허수로 읽어짐)
str_data = textscan(fid, "%s %f %f %f %f %f", 'Delimiter', ',', 'Headerlines', 3); # Headerlines : 3행 건너뛰고 읽기
stock_dates = str_data{1}; % 첫 번째 컬럼은 날짜 (문자열 형식)
% Save separated price data by columns
for i = 1:columns(price_data)
output_filename = sprintf(name_pattern, cols_name{i+1});
dlmwrite(output_filename, price_data(:, i), "precision", 10); % precision : 데이터 숫자 자릿수 저장 옵션, 10 : 자릿수 어디까지 저장할지지
end
% 파일 저장은 Dates 컬럼 예외처리를 위해 별도로 함수 제작 x, 필요시 제작.
% Load Close Price Data
target_col = cols_name{2}; # cols_name : {Price, Close, High, Low, Open, Volume}
target_filename = fullfile(work_path, sprintf(name_pattern, target_col)); % 파일 경로 + 이름
target_price = load(target_filename);
########################################################################################################################################
# 2. 종가 통계 계산
% 1) Calculate stats Using handmade func.(mean, var, std, rms)
function output = my_mean(data)
% target input : numerical type data (integer, double, complex etc...)
% target output : mean
output = sum(data)/length(data);
end
function output = my_var(data)
% target input : numerical type data (integer, double, complex etc...)
% target output : variance
output = sum((data-my_mean(data)).^2)/(length(data)-1); # 모분산, 표본분산 보정 (N 대신 N-1)
end
function output = my_std(data)
% target input : numerical type data (integer, double, complex etc...)
% target output : standard deviation
output = sqrt(my_var(data));
end
function output = my_rms(data)
% target input : numerical type data (integer, double, complex etc...)
% target output : Root mean square
output = sqrt(sum(data.^2)/length(data));
end
hand_mean = my_mean(target_price);
hand_var = my_var(target_price);
hand_std = my_std(target_price);
hand_rms = my_rms(target_price);
fprintf("\nmy mean : %.2f, \nmy var : %.2f, \nmy std: %.2f, \nmy rms : %.2f\n", hand_mean, hand_var, hand_std, hand_rms);
% 2) Calculate stats Using Octave func. (mean, var, std, rms)
oct_mean = mean(target_price);
oct_var = var(target_price);
oct_std = std(target_price);
oct_rms = rms(target_price);
fprintf("\noct mean : %.2f, \noct var : %.2f, \noct std: %.2f, \noct rms : %.2f\n", oct_mean, oct_var, oct_std, oct_rms); % var, std 차이 확인
########################################################################################################################################
# 3. Rolling stats plot
window_size = 30; # Rolling할 window size값
stride=1; # Data 건너뛸 간격 설정
num_rows = floor((length(target_price) - window_size) / stride) + 1;
stats_data = zeros(num_rows, 4); % 유효 데이터 사이즈 계산 및 지정
% close_price의 첫 번째 30개의 값을 제외하고 루프 실행
row_idx = 1
for i = window_size:stride:length(target_price)
window_data = target_price(i-window_size+1:i);
cal_mean = my_mean(window_data);
cal_var = my_var(window_data);
cal_std = my_std(window_data);
cal_rms = my_rms(window_data);
stats_data(row_idx, :) = [cal_mean, cal_var, cal_std, cal_rms];
row_idx = row_idx + 1;
end
# Plot 변수
rolling_dates = stock_dates(30:end);
my_rollmean = stats_data(:,1);
my_rollvar = stats_data(:,2);
my_rollstd = stats_data(:,3);
my_rollrms = stats_data(1:4);
# Plot Decoration
figure("Name", "My Rolling Stats Plot", "NumberTitle", "off");
plot(my_rollmean,';my rolling mean;');
hold on;
grid on;
plot(my_rollvar,';my rolling var;');
plot(my_rollstd,';my rolling std;');
plot(my_rollrms,';my rolling rms;');
title(sprintf('Rolling stats plot (window size = %d, Stride = %d, use data = %s)',window_size , stride, target_col), "FontSize", 16);
hold off;
ex-recv/01/01-CJW-20250321/수치미분.m
ex-recv/01/01-CJW-20250321/main_cjw.m
ex-recv/01/01-JKH-20250319/main-my_diff.m
ex-recv/01/01-KSG-20250318/hw_1_kim-gpt.m
ex-recv/01/01-KSG-20250318/hw_1_kim.m
ex-recv/01/01-LSH-20250319/[Octave] HW#1.m
ex-recv/01/01-MJY-20250319/Octave_Moon_250319.m
ex-recv/01/01-PJM-20250319/Octave01_Park,jm_250319.m