금융공학 실험실

Choi Munseok's Blog on Quantitative Investing and Machine Learning

📎 MMPT GitHub 저장소 바로가기

Many-to-Many Pairs Trading(MMPT) 프로젝트 리뷰

참고: 보고서 디자인은 Qraft Technology 리서치 시리즈에서 영감을 받아 구성했습니다. 실전 운용기관 스타일의 포맷을 따르고 싶었습니다.

나름 입대 2일 전까지 신경 써서 진행한 프로젝트이지만 부족한 점이 많다고 생각되어 프로젝트 전체적으로 다시 돌아보기 위한 글입니다.


1. 프로젝트 배경

  • 이전 페어트레이딩 프로젝트: 상관계수 기반 군집 → 군집 내 1:1 페어 구성 → z-score 진입
  • 이후 학교 선배님이 모 증권사 퀀트 연구원에게 보고서를 전달해 주셔서 피드백을 받았습니다.

주요 피드백 요약

  1. 상관계수 기반 군집은 직관성 부족 → 실전 적용 어려움
  2. 1:1 구조보단 군집 전체 활용 Many-to-Many 구조 제안
  3. 평균회귀 안 하고 반대로 터지는 경우 고려 필요

→ 이 피드백을 반영해 MMPT 전략 설계하였습니다.


더 읽어보기 »

2023년 8월, 2학년 여름방학이 끝나갈 즈음 컴퓨터공학을 전공하는 동아리 선배가 대회에 함께 참가하자고 제안하여 진행하게 된 프로젝트입니다. 당시에는 OpenAI에서 ChatGPT 서비스를 시작한 지 얼마 되지 않았던 터라, 대규모 언어 모델이나 프롬프트 엔지니어링 같은 개념이 상대적으로 생소하였습니다. (참고로 저는 식품자원경제학을 전공하고 있습니다.) 그야말로 맨땅에 헤딩하는 방식으로 프로젝트를 진행하였습니다.

지금 돌아보면, AI 파트를 2명이 맡고 프론트 1명, 백엔드 1명이 함께했다면 예선을 통과할 수 있었을 것 같지만, 당시에는 개강이 얼마 남지 않아 팀원을 구하기가 어려웠습니다. 프로젝트 막바지에 프론트엔드 개발 가능하신 분이 한 분 합류해주셔서 간신히 완성할 수 있었습니다. 결과는 예선 탈락이었지만, 많은 것을 배우는 소중한 경험이었습니다.

프로젝트 소개

시연영상

📎 GitHub 저장소 바로가기

📄 공모전 요강 보기

해당 프로젝트는 국민은행의 AI 금융 전문가 역할을 수행하는 서비스인 KB FinExpert를 개발하는 것이 목표였습니다. 이 서비스는 양질의 금융 콘텐츠가 존재함에도 불구하고 고객에게 접근성이 떨어지는 문제를 해결하고자 기획되었습니다. 디지털 시대의 도래로 인해 문해력이 저하되고, 정보에 대한 피로도가 증가하는 사회적 현상을 반영하였습니다.

KB 국민은행의 자산관리 전문가 칼럼 중 세무 정보, 부동산 정보, 재테크 정보를 선별하여 임베딩하고 이를 Vector DataBase에 저장하였습니다. Text-embedding-ada-002 모델과 Chroma DB를 사용하였고, 각기 다른 프롬프트를 가진 LLM이 해당 DB를 참조하여 추천 질문 생성기, 챗봇 시스템, 마인드맵 생성기의 역할을 수행하도록 하였습니다. 많은 토큰을 처리하기 위해 GPT-3.5-turbo-16k 모델을 사용하였습니다.

이러한 AI 기능을 통해 사용자가 질문을 추천받고, 질문에 대한 답변을 받고, 주요 내용을 마인드맵 형태로 요약해보는 사용자 경험을 설계하였습니다.

더 읽어보기 »

수치적분관련 간단한 방법들의 시뮬레이션을 진행해봄.
기본 내용은 James Stewart의 Calculus 참고했고, 더 자세한 내용은 Unified Proofs of the Error Estimates for the Midepoint, Trapezoidal, and Simpson’s Ruls 참고하였음.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import numpy as np
from tabulate import tabulate

# 정의역 설정
a = 0
b = np.pi

k = 6 # 소수점 k번째 까지 잘라서 출력

# Simpson's Rule 떄문에 n을 홀수로 설정해야됨.
n_values = [5, 11, 21, 51, 101]
approximations = []
errors = []

for n in n_values:
h = (b - a) / (n - 1)
x = np.linspace(a, b, n)
f = np.sin(x)

# Left Riemann sum
I_riemannL = h * sum(f[:n-1])
err_riemannL = 2 - I_riemannL

# Right Riemann sum
I_riemannR = h * sum(f[1:])
err_riemannR = 2 - I_riemannR

# Midpoint Rule
I_mid = h * sum(np.sin((x[:n-1] + x[1:]) / 2))
err_mid = 2 - I_mid

# Trapezoidal Rule
I_trap = (h / 2) * (f[0] + 2 * sum(f[1:n-1]) + f[n-1])
err_trap = 2 - I_trap

# Simpson's Rule
I_simp = (h / 3) * (f[0] + 2 * sum(f[2:n-2:2]) + 4 * sum(f[1:n-1:2]) + f[n-1])
err_simp = 2 - I_simp

# 근사값이랑 에러 저장
approximations.append([
n, round(I_riemannL, k), round(I_riemannR, k),
round(I_mid, k), round(I_trap, k), round(I_simp, k)
])
errors.append([
n, round(err_riemannL, k), round(err_riemannR, k),
round(err_mid, k), round(err_trap, k), round(err_simp, k)
])

# 표 헤더 저장
approx_headers = [
"n", "L Riemann", "R Riemann", "Midpoint", "Trapezoid", "Simpson"
]
error_headers = [
"n", "L Error", "R Error", "Mid Error", "Trap Error", "Simp Error"
]

# 표 출력
print("Approximations Table:")
print(tabulate(approximations, headers=approx_headers, tablefmt="grid"))

print("\nErrors Table:")
print(tabulate(errors, headers=error_headers, tablefmt="grid"))

더 읽어보기 »

2023년 우리나라가 수출한 농·축·임산물 합계는 91억 5700만 달러임.

동기간 김 수출액은 7억 9000만 달러로 비중이 8.627%에 달함.

세계 김 시장의 1위는 한국임(시장 점유율 약 70%)

2023년 해조류 양식업 호조로 1억원 이상 고소득을 올린 어가도 역대 최대인 2510곳에 달함.

이는 김 가격과 수출의 폭발적인 성장 때문임.

1. 배경지식

김 생산은 10월~5월까지 이루어지며, 특히 주 생산시기는 12월에서 4월까지로 전체 생산량의 90%이상을 차지함.

예를들어 2023년 2월에서 9월까지 인공종묘를 하고 쭉쭉 길러서 2023년 10월에서 2024년 5월까지 채취한 김을 2024년 김 생산량(1)으로 잡음.

김 가격은 중도매인 판매가격 기준으로 월별로 가격 차이가 상당하다고 할 수 있음. 예를들어 2024년 2월의 경우 7,809원/속이였고 4월의 경우 10,413원/속임. 따라서 생산가치(P*Q)와 생산량(Q)를 잘 구분하는게 중요하다고 생각함.(당연한 말이지만)

더 읽어보기 »

Learning Deconvolution Network for Semantic Segmentation(Hyeonwoo Noh, Seunghoon Hong, Bohyung Han, 2015) 요약입니다.

1. Abstract

  • Deconvolution Network 학습을 통한 새로운 semantic segmentation 알고리즘 제안함.
  • VGG-16 layer에서 채택된 Conv layer위에 네트워크를 학습함.
  • Deconv Net는 Deconv와 unpooling layer로 구성 → 픽셀별 레이블을 식별하고 segmentation mask를 예측.
  • Proposals는 이미지 내에서 관심 있는 객체나 영역을 식별하기 위해 제안된 후보영역을 의미함.
  • Trained network를 input image의 각 proposal에 적용함. 그리고 모든 proposal의 결과를 간단하게 결합하여 최종 semantic segmentation map을 구성.
  • deep deconv net와 proposal-wise prediction을 결합함으로서 FC net 기반의 기존 방법의 한계를 완화.

2. Introduction

  • FCN(fully convolutional network) : 구조화된 픽셀별 라벨링 문제를 해결하기 위해 고안됨. → 단순한 deconv는 이중 선형 보간으로 구현. CRF(Conditional Random Field)는 선택적으로 세밀한 분할을 위해 출력 맵에 적용됨.
  • FCN기반의 semantic segmantation은 몇가지 한계를 가짐. (1) 고정된 크기의 수용필드 → 수용 필드보다 훨씬 크거나 작은 객체는 조각나거나 잘못 라벨이 뭍을 수도. (2) 객체의 세부구조를 잃거나 부드러워짐. Deconv layer의 input인 label map이 너무 coarse하고 Deconv 절차가 지나치게 단순하기 때문. But, 최근 방법들은 CRF를 통해 이 문제를 개선
  • 이러한 한계를 극복하기 위해, 전혀 다른 전략을 사용 (1) Deconv, Unpooling, ReLU 계층으로 구성된 다층 Deconv Layer 학습. (2) 훈련된 네트워크는 개별 객체 Proposal에 적용되어 인스턴스별 분할을 얻으며, 이는 최종 semantic segmentation을 위해 결합됨. (3) PASCAL VOC 2012 데이터셋에서만 훈련된 Deconv 네트워크를 사용하여 뛰어난 성능을 달성함.

3. System Architecture

3.1. Architecture

  • Figure 2는 전체 네트워크의 자세한 구성을 보여줌. 우리가 훈련시킨 네트워크는 (1) 컨볼루션 (2) 디컨볼루션 네트워크로 구성됨.
  • 컨볼루션 네트워크는 입력 이미지를 다차원 특성 표현으로 변환하는 특성 추출기에 해당됨.
  • 디컨볼루션 네트워크는 컨볼루션 네트워크에서 추출한 특성으로부터 객체 분할을 생성하는 형태 생성기임.
  • 네트워크의 최종 출력은 입력 이미지와 같은 크기의 확률 맵으로, 각 픽셀이 사전 정의된 클래스중 하나에 속할 확률을 나타냄.

    3.2. Deconvolution Network for Segmentation

3.2.1. Unpooling

더 읽어보기 »

해당 게시물은 평균 분석 최적화(MVO) 공부하면서 제가 이것저것 실험해본 것들입니다.

평균 분산 최적화와 제약조건

단일 기간 분석에서, 다음과 같이 최적화 문제를 정의하겠습니다.

m개의 위험자산: i = 1, 2, …, m

단일 기간 수익률: m-variate random vector

평균과 분산/수익률의 공분산:

포트폴리오: m-vector of weights indicating the fraction of portfolio wealth held in each asset

포트폴리오 수익률:

는 다음과 같은 확률 변수를 가집니다:

포트폴리오의 평균-분산 쌍인 $(\alpha{\mathbf{w}}, \sigma{\mathbf{w}}^2)$을 사용하여 다양한 포트폴리오 $\mathbf{w}$를 평가합니다. 이때 선호되는 것은:

더 읽어보기 »

Log returns

금융 분야에서 로그 수익률을 사용하는 이유는 보통 3가지 입니다. 이번 포스팅에서는 그 세가지 이유를 정리해보겠습니다. 우선 로그 수익률과 일반적인 수익률은 다음과 같이 정의 됩니다.

1. Normal returns

어떤 자산의 가격이 100원에서 130원이 되었다가 다시 100원으로 왔다고 가정해봅시다. 100원에서 130원이 될 때는 단순 수익률이 +30%이지만, 130원에서 100원이 될 때는 단순 수익률이 -30%가 아닌 -23%가 되는 문제가 발생합니다. 이는 연속시간에 대한 복리효과 때문입니다. 로그 수익률은 이를 보정하여 주가 변동 수익률의 합계가 최종 수익률과 같아지게 합니다.

2. Infinite support and Normality

1
2
3
4
5
6
7
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = yf.download('VTI', start="2013-01-01")
df['Return'] = df['Adj Close'].pct_change()
df['Log_Return'] = np.log(df['Adj Close'] / df['Adj Close'].shift(1))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from scipy.stats import lognorm
import scipy.stats as stats
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(10, 5))
plt.hist(df['Adj Close'].dropna(), bins=200, alpha=0.6, color='b', density=True)

# 로그정규 분포의 파라미터 추정
shape, loc, scale = stats.lognorm.fit(df['Adj Close'])

# 추정된 파라미터를 사용하여 분포 객체 생성
dist = stats.lognorm(shape, loc=loc, scale=scale)

# 확률 밀도 함수를 그리기 위한 x 값 생성
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)

# PDF 계산 및 그래프에 표시
pdf = dist.pdf(x)
plt.plot(x, pdf, 'r-', linewidth=2, label='Log-normal distribution')

plt.title('Probability Distribution of Returns for VTI Price')
plt.xlabel('Daily Price')
plt.ylabel('Probability Density')
plt.legend()
plt.grid(True)
plt.show()

로그 수익률에 대한 일반적인 주장은, 가격이 로그 정규 분포인 경우 로그 수익률이 정규분포를 따른다는 것입니다. $zt=log(p_t)−log(p{t−1})$ 이므로, 로그 수익률은 두 정규 확률 변수의 합이기 때문입니다.(제 개인적인 생각은, $Pt$와 $P{t-1}$이 독립이 아니기 떄문에 말이 안되는 것 같습니다.)
그렇다면, 가격이 로그 정규분포를 따른다고 가정하는 것이 타당할까요? Vanguard Total Stock Market Index Fund ETF(VTI) 가격의 히스토 그램을 최적의 로그 정규분포와 함께 표시했습니다. 로그 정규 분포가 첫 번째 근사로 무리는 아니지만 데이터에 대한 좋은 모델은 아닌듯 합니다.

1
2
3
4
5
6
7
8
9
10
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(10, 6))
sns.kdeplot(df['Return'].dropna(), bw_adjust=0.5, color='b')
plt.title('Probability Distribution of Simple Returns for VTI')
plt.xlabel('Daily Return')
plt.ylabel('Probability Density')
plt.grid(True)
plt.show()
더 읽어보기 »

Chapter 9. Convolutional Networks

9.1. The histroy of NN(Neural Network), CNN(Convolutinoal Neural Network)

(추후 추가 예정)

9.2. Convolutional Layer

Fully Connected Layer(이하 FC)를 사용하여 이미지를 처리하는 경우를 살펴보겠습니다. 32x32x3 사이즈의 이미지가 있을때(3은 RGB chanel입니다.) 이를 길게 늘려서 3072x1형태의 matrix로 만듭니다. 그리고 이를 10x3072 size의 weights와 내적하여 10x1크기의 activation matrix를 도출하게 됩니다. 이런식의 이미지 처리방식은 이미지의 공간적 구조를 보존하지 못한다는 단점이 있습니다.

Convolutional Layer(이하 conv)는 이미지의 공간적 구조를 보존한다는 특징이 있습니다. 32x32x3 size의 image가 input으로 주어졌을 때, 5x5x3 filter를 사용하여 합성곱 연산을 수행합니다. 필터를 가지고 이미지를 슬라이딩 하면서 공간적으로 내적을 수행하게 됩니다. filter의 depth인 3은 image의 depth와 같게되어 activation maps는 28x28x1 size가 됩니다. filter의 개수만큼 새로운 activation map을 도출할 수 있습니다. 각 필터를 가지고 전체 이미지에 convolution 연산을 수행한다고 요약할 수 있습니다. 이런식으로 간단한 linear layer로 된 nural network를 만들 수 있습니다. 그림1에서 해당 과정을 시각적으로 나타내고 있습니다.

그림1, Source : CS231n; Deep Learning for Computer Vision, Lecture 5-33

image 하나의 특징을 추출하는 과정이기에 filter와 image의 depth는 같습니다. 엄밀하게 여기서의 합성곱 연산은 신호처리 분야에서의 합성곱 연산과는 다릅니다. CNN에서의 합성곱연산은 합성곱의 의미적 요소만 가져온 것입니다.
*필터와 필터 크기에 맞는 이미지를 내적하는 것은 FC에서의 내적과정과 동일하다고 볼 수 있습니다.

Conv Layer를 Brain Neuron의 관점에서 살펴보겠습니다. 뉴런과 Conv Layer의 가장 큰 차이점은 뉴런은 Local Connectivity를 가지고 있다는 것입니다. Conv Layer처럼 슬라이딩을 하는 것이 아니라 특정 부분에만 연결되어 있습니다. 하나의 뉴런은 한 부분만 처리하고, 그런 뉴런들이 모여서 전체 이미지를 처리하는 것입니다. 그래서 여러개의 필터를 사용하여 해당 부분을 구현합니다. 각 필터가 하나의 뉴런과 비슷하게 작동하는 것입니다. 다양한 필터들이 다른 종류의 특징을 감지할 수 있도록 학습되기 때문입니다. 5x5 필터가 있다고 할 때, 한 뉴런의 “Receptive filed”가 5x5라고 이해할 수 있는 것입니다. “Receptive filed”란 한 뉴런이 한 번에 수용할 수 있는 영역을 의미합니다.

더 읽어보기 »

Fully Convolutional Networks for Semantic Segmentation(Jonathan Long, Evan Shelhamer, Trevor Darrell, 2015) 요약입니다.

1. FCN

FCN(Fully Convolutional Networks for Semantic Segmentation)은 Semantic Segmentation 문제를 위해 제안된 딥러닝 모델이다. Semantic Segmentation은 직역하자면 의미론적 분할이라는 뜻이다. 딥러닝에서 해당 용어는 이미지의 모든 픽셀들을 보여지는 객체에 해당시켜 레이블하는 것을 뜻한다. FCN은 Semantic Segmentation을 위해 기존 image classification에서 우수한 성능을 보인 CNN기반 모델(AlexNet, VGG16, GoogLeNet)을 목적에 맞춰 변형시킨 것이다.

Image classification 모델들은 목적에 맞게 출력층이 FC-layer로 구성되어 있다. 그런데, FC-layer를 사용하게 되면 이미지의 위치 정보가 사라지고, 입력 이미지 크기가 고정되는 문제가 있다. (Dense layer 가중치 고정 → 바로 앞 Feature Map 크기 고정 → … → Input Image 크기 고정)

이러한 FC-layer의 한계를 보완하기 위해 FC-layer를 Conv-layer로 대체. 마지막 FC-layer의 경우, 채널 차원을 클래스 수에 맞춘 1x1 Conv Layer로 변환한다. Convolutionalization을 통해 출력된 Feature map은 원본이미지 내포 가능. 그러나 최종 목적인 픽셀 단위 예측과 비교했을 때, FCN의 출력 Feature map은 너무 coarse하다. 따라서, coarse map을 원본 이미지 크기에 가까운 Dense map으로 변환해줄 필요가 있다. 물론 Pooling을 사용하지 않거나, Pooling의 stride를 줄임으로써 Feature map의 크기가 작아지는 것을 처음부터 피할 수도 있다. 그러나, 이 경우 필터가 더 세밀한 부분을 볼 수는 있지만 Receptive Field가 줄어들어 이미지의 컨텍스트를 놓치게 된다. 또한 이렇게 되면 파라미터수가 급격히 증가하고 더 많은 학습시간을 요구하게 된다.

2. Deconvolution

Bilinear Interpolation(선형 보간)

선형보간법(Linear interpolation)은 끝점의 값이 주어졌을 때 그 사이에 위치한 값을 추정하기 위하여 직선 거리에 따라 선형적으로 계산하는 방법이다. 다음과 같이 Feature map의 빈 영역을 추정한다.

더 읽어보기 »

Chapter1. Introduction

1.1 딥러닝의 의미

사람이 수행하기는 쉽지만 ‘설명하기는 어려운 작업’들이 있습니다. 우리가 직관적으로 해결하고 자동적이라고 느껴지는 것들인데요. 예를들어서 발화를 인식하거나 이미지의 얼굴을 인식하는 것들입니다. 이 책은 이러한 직관적인 문제에 대한 해결책을 다루고 있습니다. 이 해결책은 컴퓨터가 경험에서 배우고, 더 간단한 개념들과의 관계 측면에서 개념의 계층을 통해 세계를 이해하도록 하는 것입니다. 이 접근법은 컴퓨터가 필요로 하는 모든 지식을 인간이 명시할 필요없게 하며, 간단한 것들로부터 복잡한 개념을 구축함으로써 복잡한 개념을 배울 수 있게 합니다. 이러한 개념들이 서로 구축되는 방식을 그래프로 그려보면 그 그래프는 깊고 여러 층을 가지고 있습니다. 이러한 이유로 우리는 이러한 AI접근법을 딥러닝이라고 부릅니다.

AI의 초기 성공들은 상대적으로 청정하고 형식적인 환경에서 이루어졌으며 컴퓨터가 세계에 대해 많은 지식을 가질 필요가 없었습니다. 예를들어서 체스 같은 경우에, 프로그래머가 미리 쉽게 제공할 수 있는 완전히 형식적인 규칙들의 간단한 목록으로 설명될 수 있습니다. 성공적인 체스 전략을 고안하는 것은 엄청난 성취이지만 말이죠. 이런식으로 아이러니하게 인간에게 가장 어려운 정신적 과제 중 하나인 추상적이고 형식적인 작업들이 컴퓨터에게는 가장 쉬운 것들 중 하나입니다.

그러나 사람의 일상생활은 세계에 대한 엄청난 양의 지식을 요구합니다. 이 지식의 대부분은 주관적이고 직관적이라 형식적인 방식으로 표현하기 어렵습니다. 인공지능에서의 주요 도전 과제 중 하나는 이러한 지식을 컴퓨터에 어떻게 넣을 것인가 입니다. 처음 여러 인공지능 프로젝트들은 세계에 대한 지식을 형식적인 언어로 하드코딩하려고 시도했습니다. 세계를 정확하게 묘사할 수 있는 충분한 복잡성을 가진 공식적인 규칙을 고안하는데 어려움을 겪어 실패했습니다.

하드 코딩된 정보를 시스템이 마주하는 것이 어렵기에 AI 시스템이 raw data에서 패턴을 추출해내서 시스템만의 지식을 취득해야 하는 능력이 필요해졌습니다. 이러한 능력을 머신러닝이라고 합니다. 머신러닝의 도입은 컴퓨터가 현실세계의 지식들을 포한하는 문제들을 해결하도록 합니다. 그리고 주관적으로 보이는 결정까지 하도록 합니다. 예를들어 logistic regression은 재왕절개 추천에 이용될 수 있습니다. naive Bayes는 스팸에일에서 합법적인 메일을 분리할 수 있습니다.

1.2 딥러닝과 특징 추출

머신러닝 알고리즘의 성능은 알고리즘이 받는 데이터의 표현에 강하게 의존합니다. 예를들어 AI System은 환자를 직접 검사하지 않습니다. 대신 의사는 시스테에 관련 정보의 조각을 제공해줍니다. 환자의 표현이 포함된 각 정보 조각을 ‘특성’이라고 합니다. Logistic Regression은 이러한 환자의 특성과 다양한 결과와의 관계를 학습합니다. 그러나 Logistic Regression은 특성이 어떤식으로 정의되는지에 영향을 미칠수 없습니다.

이러한 표현에 대한 의존은 컴퓨터과학과 심지어 우리 삶을 통해 보여지는 일반적인 현상입니다. 컴퓨터 과학에서는 데이터의 모음을 검색하는 것으로서의 기능이, 만약 모음이 구조적이라면 그리고 지능적으로 색인이 달아져있다면 지수적으로 빠를 것입니다. 사람들은 아랍 숫자로 산수를하면 빠를거지만 로마 숫자로 산수를 하면 굉장히 느릴 것입니다. 이러한 표현의 선택은 머신러닝 알고리즘의 성능에도 엄청난 영향을 미칩니다. 과업을 위해 추출해야하는 올바른 특징의 모음을 디자인하는 것 그리고 더 나아가 이러한 특징들을 간단한 머신러닝 알고리즘에 제공하는 것으로 많은 인공지능의 일은 해결될 수 있습니다. 하지만 많은 일에서 어떤 특징을 추출해야 하는지가 어려울 수 있습니다.

더 읽어보기 »
0%