Sample Weights - jaeaehkim/trading_system_beta GitHub Wiki
Motivation
- ๋ง์ ๋จธ์ ๋ฌ๋ ๋ฌธํ์ ๋ฐ์ดํฐ๊ฐ IID ๋ผ๋ ๊ฐ์ ํ์์ ์งํํ๋๋ฐ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ฉด ์ด๋ฐ ๊ฐ์ ์ ๋นํ์ค์
- ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ Data Structures, Labeling ์ ํตํด ํด๊ฒฐํ๊ณ ์ ํ์
issue
-
Labeling ์์ ์ ์ํ Triple Barrier๋ฅผ ํ์ฉํ ๋๋ฉด Overlapping outcomes ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋จ
-
i์ j ๋ ๊ฐ์ ๊ตฌ๊ฐ์์ ๊ฐ๊ฐ feature(X), label(y)์ด ์๋ค๊ณ ๊ฐ์ .
- ์์ ๊ฐ์ ์กฐ๊ฑด์์ y_i, y_j๋์์ return์ ์ข
์๋๊ฒ ๋จ. ์ฆ y_i๊ฐ i={1... I} ๊น์ง ์์ ๋ ์ฐ์ ๊ฒฐ๊ณผ์์ ์ค์ฒฉ์ด ์ง์์ ์ผ๋ก ๋ฐ์ํ ์ ์๋ค๋ ์๊ธฐ์ด๊ณ ์ด๋ ๋ฐ์ดํฐ๊ฐ IID์ ๋ฉ์ด์ง๋ค๋ ๊ฒ์ ์๊ธฐํจ.
- ์๋ฐํ๊ฒ๋ ํ๋์ ์ค์ฒฉ๋ง ์์ด๋ IID๊ฐ ์๋.
solution
- sol(1) : ๋ฒ ํ
๊ฐ๋ฅํ horizon์ ์ ํํ๋ ๋ฐฉ๋ฒ
- ์ค์ฒฉ๋ง์ ์ํด ์ผ๋ถ train data๋ฅผ ์ ๊ฑฐํ๋ค๋ ๊ฒ์ ๊ฐ๋จํ์ง๋ง ์ด์ ์ ๋ฐ์ดํฐ์ ๊ดํ ์ฌ๋ ๊น์ ์ ์ฒ๋ฆฌ ์์ ๋ค์ ํฐ ํด๋ฅผ ๋ผ์น๋ฏ๋ก ์ข์ ๋ฐฉ๋ฒ์ ์๋.
- sol(2) : ํ๊ท ๊ณ ์ ์ฑ(average uniqueness) ํ์ฉ
- train data์ ๋ชจ๋ row๋ฅผ ํ์ฉํด์ model์ ๋ฃ์ด์ฃผ๋ ๊ฒ์ด ์๋๋ผ average uniqueness๋ฅผ ๊ณ์ฐํ์ฌ ํด๋น ๋น์จ๋งํผ sampling ํ์ฌ ์ค์ฒฉ ํจ๊ณผ๋ฅผ ์ค์ด๋ ๋ฐฉ์
- sol(3) : ์์ฐจ์ ๋ถํธ์คํธ๋ฉ(sequential bootstrap) ํ์ฉ
- train data์ row๋ฅผ samplingํ ๋ ์์ฐจ์ ์ผ๋ก ์งํํ๋ฉฐ 1ํ ์งํํ ๋๋ง๋ค ๋๋จธ์ง row๋ค์ ๋ํ ์ถ์ถ ํ๋ฅ ๋ถํฌ๋ฅผ ๋ณ๊ฒฝํด๊ฐ๋ฉด์ ๋ค์ ์ถ์ถ์ ์ด์ด๋๊ฐ๋ ๋ฐฉ์.
Number of Concurrent Labels
Concept
- ๊ณต์กด(Concurrent)์ ์ ์ : ๋ ๊ฐ์ label์ด ํ๋์ ์ค์ฒฉ ์์ต๋ฅ ์ ๊ฐ์ง๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํจ. ์์์ ์ค๋ช
ํ๋ ์๊ฐ ๊ตฌ๊ฐ์ด ์๋ฒฝํ๊ฒ ๋์ผํ์ง ์์๋ ๋๊ณ ์ค์ฒฉํ๊ธฐ๋ง ํ๋ฉด ๊ณต์กดํ๋ค๊ณ ํํ.
- ๊ณต์กด(Concurrent)์ ์์ ํํ
- t๋ ์๊ฐ ํฌ์ธํธ๋ฅผ ์๋ฏธํ๊ณ i๋ ๋ ์ด๋ธ(train data์ row)์ ๋๋ฒ๋ง์ ์๋ฏธํ๋ค. t์i๋ฅผ ๊ตฌ๋ณํ์ฌ ์๊ฐํ๋ ๊ฒ์ด ์ค์.
- i์๋ triple barrier๋ฅผ ์ํ [์์์ ์๊ฐ, ๋์ ์๊ฐ]์ด ์์ฌ์๊ณ t๋ i์ ์์ฌ์๋ ์๊ฐ์ ํ๋์ ๋ฆฌ์คํธ๋ก flatํ๊ฒ ๋ง๋ ํ sortํ ์งํฉ์ ์์
- {1_(t,i)}_ i๋ผ๋ ์ด์ง ํ๋ ฌ(T x I)์ ๊ตฌ์ฑํ๊ณ ๋ฒกํฐ 1_(t,i) (1 X T) ๋ [t_(i,0) , t_(i,1)]๊ณผ [t-1, t]๊ฐ ์ค์ฒฉํ๋ ๊ฒฝ์ฐ(=triple barrier์ ์๊ฐ ๊ตฌ๊ฐ)์๋ ํด๋น i th ์ด์ง ํ ๊ฐ์ 1์ ๋ถ์ฌํ๊ณ ์ค์ฒฉํ์ง ์์ผ๋ฉด 0์ ๋ถ์ฌํ๋ค. ๋ฒกํฐ ๊ฐ์ ์ค์ ํ๋ ๊ฒฝ์ฐ์ i๊ฐ ๊ณ ์ ๋์ด ์๊ณ t๊ฐ 1-T๊น์ง ๋ณํ๋ฉด์ ์ฒดํฌ
- ํ๋ ฌ{1_(t,i)} :
- ํ๋ ฌ{1_(t,i)} :
- ์์ ์์ ์ ํ๊ณ ๋๋ฉด I๊ฐ์ ๋ฒกํฐ๊ฐ ๋ง๋ค์ด์ง๊ณ ์ด๊ฒ์ ํ์ฉํด '๊ณต์กด ๋ ์ด๋ธ ๊ฐ์(the number of labels concurrent)'๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ์ (ํ๋ ฌ์ ํ์ ํฉ)
- ์์ t ํ๋์ ๋ํด์ ๊ทธ ์๊ฐ์ triple barrier๊ฐ ๋ช๊ฐ๊ฐ ๋์์ ๊ณต์กดํ๊ณ ์๋ ์ง๋ฅผ ๋ํ๋ด๊ณ ์ด๋ C_(t=10) = 4 ์ด๋ฐ ์์ด ๋ ๊ฒ์ด๋ค. t=1~T๊น์ง๋ C_t ๋ฒกํฐ๊ฐ ๋๋ค. (compute c_t for t in price.index)
- t๋ ์๊ฐ ํฌ์ธํธ๋ฅผ ์๋ฏธํ๊ณ i๋ ๋ ์ด๋ธ(train data์ row)์ ๋๋ฒ๋ง์ ์๋ฏธํ๋ค. t์i๋ฅผ ๊ตฌ๋ณํ์ฌ ์๊ฐํ๋ ๊ฒ์ด ์ค์.
Code
def mpNumCoEvents(priceIdx, tl, molecule):
"""
refer to the explanation on Snippet 4.1
:param priceIdx:
:param tl: time limit
:param molecule: events.index if numThreads=1 or subset otherwise
:return: compute c_t for t in price.index
"""
tl = tl.fillna(priceIdx[-1])
tl = tl[tl >= molecule[0]]
tl = tl.loc[:tl[molecule].max()]
iloc = priceIdx.searchsorted(np.array([tl.index[0], tl.max()]))
count = pd.Series(0, index=priceIdx[iloc[0]:iloc[1]+1])
for tIn, tOut in tl.iteritems():
count.loc[tIn:tOut] += 1
return count.loc[molecule[0]:tl[molecule].max()]
Average Uniqueness of a Label
Concept
-
'๊ณต์กด(Concurrent)'์ ๊ฐ๋ ์ ์ ์ํ๊ณ ์ด๋ฅผ ์ ๋ํํ์๋ค. ๋ชฉ์ ์ train data์ ์ค์ฒฉ์ฑ์ด ์กด์ฌํ๊ณ ์ด ์ค์ฒฉ์ฑ์ '๊ณต์กด ๋ ์ด๋ธ ๊ฐ์(the number of labels concurrent)'๋ก ํํํ๋ค. ์ด๊ฒ์ ์๊ฐ t, ๋ ์ด๋ธ i์์์ '๊ณ ์ ์ฑ(Uniqueness)'์ ํํํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ ์ ์๋ค.
-
- u_(t,i) & 1_(t,i) ๋ scalar, c_t๋ vector
-
triple barrier ๊ตฌ๊ฐ ์์์ ์ฌ๋ฌ ๊ฐ์ u_(t,i)๊ฐ ์กด์ฌํ๋ฏ๋ก ์ด๋ฅผ 'ํ๊ท ๊ณ ์ ์ฑ(Average Uniqueness)'์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ํํ ํ ์ ์๋ค.
-
issue
- ํ๊ท ๊ณ ์ ์ฑ์ ๊ณ์ฐํ๋ ๊ณผ์ ์์ ๋ฏธ๋์ ์ ์ ์๋ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๊ฒ ๋จ
- ๋ฌธ์ ๊ฐ ๋์ง ์๋ ์ด์ : 1) training set์์๋ง ํ์ฉ๋๊ณ test set์์ ์ฌ์ฉ๋๋ ๊ฒ์ ์๋. 2) ํ๊ท ๊ณ ์ ์ฑ์ด ๋ ์ด๋ธ ์์ธก์ ์ง์ ์ฌ์ฉ๋์ง ์์.
- ์ ๋ง ์์ ๋์(leakage)๊ฐ ์๋ ๊ฑธ๊น? ๊ฐ์ธ์ ์ผ๋ก ๊ทธ๋ ์ง ์๋ค๊ณ ๋ด. but ๋ฐ์ดํฐ๋ฅผ ์ต๋ํ IIDํ ํ ๊ฒ + ์ถํ์ ๋ฐฑํ ์คํธ๋ฅผ ํ ๋ ํผ์ง-์ ๋ฐ๊ณ (purge-embargo)๋ฅผ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ทธ ์ํฅ๋๊ฐ ์ ๊ธฐ์ ๋ฌด์ํด๋ ๋๋ค๋ก ํด์.
- ํ๊ท ๊ณ ์ ์ฑ์ ๊ณ์ฐํ๋ ๊ณผ์ ์์ ๋ฏธ๋์ ์ ์ ์๋ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๊ฒ ๋จ
Code
def mpSampleTW(tl, numCoEvents, molecule):
"""
:param tl: events['tl']
:param numCoEvents: pd.Series with index
:param molecule: events.index if numThreads=1 or subset otherwise
:return: compute u_i_bar for i in events.index
"""
wght = pd.Series(index=molecule)
for tIn, tOut in tl.loc[wght.index].iteritems():
wght.loc[tIn] = (1./numCoEvents.loc[tIn:tOut]).mean()
return wght
- ๋น๊ต : price.index vs event.index(=molecule) vs tl (triple barrier : [[t1,t2],[t3,t4]....]
- numCoEvents.loc[tIn:tOut]
- .mean()
Bagging Classifiers and Uniqueness
Application of average uniquensess
- Bagging ์๊ณ ๋ฆฌ์ฆ : n ํฌ๊ธฐ์ train set 'A'๊ฐ ์๋ค๊ณ ๊ฐ์ . m๊ฐ์ ์ํ์ ๋ณต์ ์ถ์ถ ์งํ. ์ถ์ถํ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ท ๋ฑ ํ๋ฅ ๋ถํฌ๋ฅผ ๊ฐ์ ํ์ฌ A_i ํฌ๊ธฐ n' (n' < n)์ ๊ฐ๋ train set m๊ฐ ์์ฑ. m๊ฐ์ train set์ผ๋ก m๊ฐ์ model์ ์์ฑํ๊ณ ์ด๋ฅผ averaging(regression case)/voting(classification case) ํ์ฌ ์ต์ข
๊ฒฐ๊ณผ ๊ฐ์ ์ฐ์ถ
- Issue
- ์์์ ์๊ธฐํ๋ Bagging ์๊ณ ๋ฆฌ์ฆ์ ๋ํ ์ค๋ช ์ ML์ชฝ์์ ๋ฐ์ดํฐ๋ค์ด IIDํ๋ค๋ ๊ฐ์ ์ ํ๊ณ ์ด์ผ๊ธฐํ๋ค. ์๋ก ๋ค๋ฅธ ๋ชจ๋ธ์ด์ง๋ง ๊ทผ์์ ์ผ๋ก ๊ฐ์ source์ธ A์์ ๋์จ bootstrap sample์ ์ด์ฉํ ๊ฒ์ด๋ฏ๋ก '์ค๋ณต์ฑ'์ด ๋ฐ์ํ๊ฒ ๋๋ค.
- ๋ค๋ง, source๊ฐ IID ํ ๋๋ 100๊ฐ์ ๋ชจ๋ธ์ ๋ง๋ค์ด๋ ์ค๋ณต์ฑ์ด ์ฌ๊ฐํ์ง ์์ง๋ง source๊ฐ IID์ ๋ฉ์ด์ง ์๋ก ์์์ ๋ชจ๋ธ๋ก๋ง์ผ๋ก๋ ์ด๋ฏธ ์ค๋ณต์ฑ์ด ์ฌ๊ฐํด์ง๊ณ ์ฌ์ฉํ๋ ์ฐ์ฐ๋์ ๋นํด ์ต์ข output ๊ฐ์ ์ ํจ์ฑ์ ๋ณํ๊ฐ ์๊ฒ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ณด์ ํ๊ณ ์๋ train set์ ๊ทน๋ํ ์์ผ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ train set์ ์ต๋ํ IIDํ ์ํ๋ก ๋ง๋ค์ด ๋๋ ๊ฒ์ด ํต์ฌ.
- Solution
- ํ๊ท ๊ณ ์ ์ฑ(average uniqueness)์ ํ์ฉํ 1์ฐจ์ ์ธ ํด๊ฒฐ์ฑ ๋ณด์ ํ๊ณ ์๋ train set์ ํ๊ท ์ ์ธ ๊ณ ์ ์ฑ์ ์์นํํ ํ ํด๋น ๋น์จ์ ํฌ๊ธฐ๋ก๋ง bootstrap sample์ ๋ง๋ค์ด ๋ด๋๋ก ์ ํํ๋ ๊ฒ์ด๋ค.
- ์๋ฅผ๋ค๋ฉด, sklearn์ BaggingClassifier์ ํ๋ผ๋ฏธํฐ ์ค max_samples(๋น์จ)์ ๊ฐ์ผ๋ก ํ๊ท ๊ณ ์ ์ฑ(average uniqueness)์ ํ์ฉํ๋ ๊ฒ์ด๋ค. sklearn.ensemble.BaggingClassifier ์ฐธ๊ณ ๋งํฌ
- Issue
Code
self._model = self.model_generator.model(type=self._config['model_type'],
n_estimators=self._config['n estimators'],
max_samples=self.model_generator.sampleTw.mean(), oob_score=True,
random_state=self._config['bagg random state'],
base_random_state=self._config['base random state'], base_n_estimators=self._config['base n estimators'])
- model์ bagging๊ณผ ๋น์ทํ ์๊ณ ๋ฆฌ์ฆ ๋ชจ๋๊ฐ ํด๋น.
- max_samples ๋ถ๋ถ์ self.model_generator.sampleTw.mean()์ ํตํด ํด๋น source์ ํ๊ท ๊ณ ์ ์ฑ์ ๋์
Sequential Bootstrap
- Concept
- ํต์ฌ์ train set์ IIDํ ํ๊ณ train set์์ bootstrap sample ๊ฐ์ ์ค๋ณต์ฑ์ ์ต๋ํ ๋ฎ์ถฐ ๋๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํ๋ค. ์ด๋ค model์ ์ฌ์ฉํ ๊ฒ์ธ์ง๋ ๊ทธ ๋ค์ ๋ฌธ์ ์ด๋ค. ์์ ํด๊ฒฐ์ฑ ์ '๊ท ๋ฑ ํ๋ฅ ๋ถํฌ'๋ฅผ ์ ์งํ๋ฉด์ 'max_samples'๋ฅผ ์ ํํ๋ ์์ด์ง๋ง Sequential Bootstrap์ ๊ทผ๋ณธ์ ์ผ๋ก 'ํ๋ฅ ๋ถํฌ'๋ฅผ ์ ๋ณด๋ ๋ฐฉ๋ฒ์ด๋ค.
- Sequential Bootstrap Process
- ์ด๊ธฐ Bootstrap sampling์ ๊ท ๋ฑํ๋ฅ ๋ถํฌ์์ ์์ํด์ผ ํจ. i์ ํ๋ฅ ์ 1/I๋ก ์์
- i ์ถ์ถ๋ก ์ธํด ๋์ ์ค์ฒฉ์ฑ์ ๋ณด์ด๋ ์์์ X_j Bootstrap์ ํ๋ฅ ์ ๋ฎ์ถ๋ ค๊ณ ํจ. (๋ฌผ๋ก , ๊ฐ์ฅ ๋์ ์ค์ฒฉ์ฑ์ ๋ณด์ด๋ ๊ฒ์ j=i์ผ๋)
- sampling sequence๋ฅผ ๊ธฐ๋กํ๊ธฐ ์ํด phi๋ฅผ ์ ์
- ์์์ j์ ๋ํด ์ถ์ถ๋ i์ ์ ๋ณด๋ฅผ ๋ฐ์ํ์ฌ ๊ณ ์ ์ฑ๊ณผ ํ๊ท ๊ณ ์ ์ฑ์ ๊ณ์ฐ (์ด์ ๋ํ ์ค๋ช ์ ์์ ๋ชฉ์ฐจ๋ฅผ ์ฐธ๊ณ )
- ์์์ j์ ํ๊ท ๊ณ ์ ์ฑ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฅ ๋ถํฌ ์ ๋ฐ์ดํธ ๋ฐ ์ค์ผ์ผ๋ง
- ๋ ๋ฒ์งธ ๊ฐฑ์ ๋ ํ๋ฅ ๋ถํฌ๋ฅผ ํ์ฉํ์ฌ ์ถ์ถ ์งํ
- ์ด Bootstrap Sample์ด I๊ฐ๊ฐ ๋ ๋๊น์ง ์งํ
- issue : Sequential Bootstrap๋ ์ฌ์ ํ ์ค์ฒฉ ๊ฐ๋ฅ์ฑ์ ์กด์ฌํ์ง๋ง ํ๋ฅ ์ ์ผ๋ก ๊ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋์์ ๊ฐ์ค์ ์ธ ์ธก๋ฉด์์ ๋ ์ข์ ๋ฐฉ๋ฒ์.
- MonteCarlo ์คํ์ ํตํด์ 2,3๋ฒ Solution๊ฐ์ ๊ณ ์ ์ฑ ํผํฌ๋จผ์ค๋ฅผ ๋น๊ตํ ์ ์์.
- issue : Sequential Bootstrap๋ ์ฌ์ ํ ์ค์ฒฉ ๊ฐ๋ฅ์ฑ์ ์กด์ฌํ์ง๋ง ํ๋ฅ ์ ์ผ๋ก ๊ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋์์ ๊ฐ์ค์ ์ธ ์ธก๋ฉด์์ ๋ ์ข์ ๋ฐฉ๋ฒ์.
Code
def getIndMatrix(barIx, tl):
"""
refer to chapter 4.5.3 a numerical example
:param barIx: price.index
:param tl: events['tl']
:return:
"""
indM = pd.DataFrame(0, index=barIx, columns=range(tl.shape[0]))
for i, (t0, t1) in enumerate(tl.iteritems()):
indM.loc[t0:t1, i] = 1
return indM
def getAvgUniqueness(indM):
c = indM.sum(axis=1)
u = indM.div(c, axis=0)
avgU = u[u>0].mean()
return avgU
def seqBootstrap(indM, sLength=None):
"""
refer to Chapter 4.5.3 numerical example!
"""
if sLength is None:
sLength = indM.shape[1]
phi = []
while len(phi) < sLength:
avgU = pd.Series()
for i in indM:
indM_ = indM[phi+[i]]
# ์๋ก ๋ฃ์ i column์ ๋ํ AvgUniqueness๋ getAvgUniquenses์ ์ํด return๋๋ series์ ๋งจ ๋ ๊ฐ์ ์์!
avgU.loc[i] = getAvgUniqueness(indM_).iloc[-1]
prob = avgU / avgU.sum()
phi += [np.random.choice(indM.columns, p=prob)]
print(phi)
return phi
Return Attribution
- Concept
- IID์ ๊ทผ์ ํ Bootstrap sample์ ํ๋ค๋ ๊ฐ์ ํ์ ์ด๋ฅผ ๋ฐ๋ก Model์ ํ๋ จ ์ํฌ ์๋ ์๊ฒ ์ง๋ง ํ ๋ฒ ๋ ์ฒ๋ฆฌ๋ฅผ ํจ์ผ๋ก์จ Model ํ์ต์ ์ ํจ์ฑ์ ๋ ๋์ผ ์ ์๋ค. ์ด๋ฒ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๊ฐ์ค์ "๋ชจ๋ ํ๋ณธ์ ์ค์์ฑ์ด ๋์ผํ์ง ์๋ค"๋ฅผ ๋ฐํ์ผ๋ก ํ๋ค.
- ์ฆ, ํน์ ๋ ์ด๋ธ ํ์ ์ ๋ ์์ต๋ฅ ์ ํฌ๊ธฐ๊ฐ ํฐ ๊ฒฝ์ฐ๊ฐ ์๊ณ , ๋ค๋ฅธ ํ์ ์์ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ, ์ ๋ ์์ต๋ฅ ์ ํฌ๊ธฐ๊ฐ ํฐ ๊ฒฝ์ฐ์ ์ง์คํด์ ํ์ตํ๋๊ฒ ๋ฐ๋์งํ๋ค๊ณ ๋ณผ ์ ์๋ค.
- ์๋ฅ ๊ธฐ์ถ ๋ฌธ์ ์์ ๋ฐฐ์ ์ด ํฐ ํญ๋ชฉ์ ์ค์ ์ ์ผ๋ก ๊ณต๋ถํ๋๊ฒ ํจ์ฌ ์ค์ํ๋ค๋ ๋ป๊ณผ ์ผ๋งฅ์ํตํ๋ค. Return Attribution์ ์์ต๋ฅ ์ ํฌ๊ธฐ๋ฅผ ์ ๋ํํ์ฌ ํ๋ณธ ๊ฐ์ค๊ฐ์ ์ค์ ํ๋ ๋ฐฉ์์ด๋ค.
- Mathematical Expression
- triple barrier๋ฅผ ํตํด Labeling์ ์งํํ๊ณ ์ด๋ life span์ด ์กด์ฌํ๊ณ ์ด๋ฅผ t_(i,0),t_(i,1)๋ก ์ ์ํ๊ณ ํด๋น label์ ํ๊ท ๊ณ ์ ์ฑ(average uniqueness)๊ณผ ์ค์ผ์ผ๋ง์ ๋ฐ์ํ์ฌ w_i๋ฅผ ์ ์ํ ์ ์๋ค.
- ๋๋ถ๋ถ์ ML model ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ๋ชจ๋ธ์ ํ๋ณธ ๊ฐ์ค ๊ฐ์ ๋์ผํ๊ฒ default๋ก ์ ๊ณตํ๋๋ฐ ํด๋น vector๋ฅผ parameter๋ก ๋ฃ์ด์ค์ ๋ฐ๋ผ ์ด๋ฅผ ๋ฐ์ํ ์ ์๋ค.
Code
def mpSampleW(tl, numCoEvents, price, molecule):
"""
:param tl: events['tl']
:param numCoEvents: c_t for t in price.index
:param price: volume / dollar bar price
:param molecule: events.index if numThreads=1 or subset otherwise
:return: compute \tilde{w_i} for i in events.index (refer to formula right before snippet 4.10)
"""
ret = np.log(price).diff()
wght = pd.Series(index=molecule)
for tIn, tOut in tl.loc[wght.index].iteritems():
wght.loc[tIn] = (ret.loc[tIn:tOut] / numCoEvents[tIn: tOut]).sum()
return wght.abs()
fit = clf.fit(train_input, train_label, sample_weight=train_weight) # train_weight = mpSampleW์ output
- ํ๊ท ๊ณ ์ ์ฑ๋ง returnํ๋ ํจ์๋ฅผ ๋ณํํ์ฌ ํ๊ท ๊ณ ์ ์ฑ+์์ต๋ฅ ๊ฐ์ค์ ๊ณ ๋ คํ ๋ฒกํฐ๋ฅผ ์ฐ์ถํ๋ ํจ์
Time Decay
- Concept
- Adaptive Markets (Lo, A. 2017) ์ ๊ฐ์ค์ธ "๊ณผ๊ฑฐ์ ์์ ๋ ์๋ก์ด ๊ฒ๋ณด๋ค ์ฐ๊ด์ฑ์ด ๋จ์ด์ง๋ค"๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ์ค๊ฐ์ ํ ๋ฒ ๋ ์ค ์ ์๋ค. ๊ฐ๋จํ ๋ชจํ์ธ ์ ํ-๊ฐ์ ๋ชจ๋ธ์ ํ์ฉํ๋ค.
- Issue
- ๋ฐ์ดํฐ๋ฅผ IIDํ ํ์ฌ ๋ง๋๋๋ฐ Time-Decay๋ฅผ ๊ณ ๋ คํ๋ค๋ ๊ฑด ๋ชจ์์ด ์๋๊ฐ?
- ์ง์ ํ IID๋ผ๋ ๊ฒ์ ์๊ณ preprocessing์ ํตํด์ ์ต๋ํ stationaryํ๊ฒ ๋ง๋ค์ด IID์ค๋ฝ๊ฒ ๋ง๋๋ ๊ฒ์ผ ๋ฟ์ด๋ค. IID์ ์ ์๋ฅผ ์๊ฐํด๋ณด๋ฉด ๊ธ์ต ๋ฐ์ดํฐ์ source๋ฅผ ๋ณด๊ฑด๋ ์ง์ ํ IID๋ฅผ ๋ง๋ค ์ ์๋ค.
- ๋ค๋ง, ๋ชจ๋ธ์ ํจ์จ์ ์ด๊ณ ์ ํจํ ํ์ต๊ณผ output์ ์์ ์ฑ์ ์ํด์ ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ์ด๋ค. ์ด๋ฅผ ๊ณ ๋ คํด๋ณด๋ฉด, ์์ง ๋ ์ฒ๋ฆฌ๋ ๋ถ๋ถ์ด ๋จ์์์ ๊ฒ์ด๊ณ ์ด๋ฌํ ๋ถ๋ถ์ time-dependentํ ๋ถ๋ถ์ด ์๋ค. ์ด ๋ถ๋ถ์ ๊ดํด์ Time-Decay๋ฅผ ํตํด์ ๊ฐ์ ํ ์ ์๋ค๊ณ ๋ณธ๋ค.
- ์ค์ application ์ธก๋ฉด์์ sample ๊ฐ์์ ๋ฐ๋ผ weights๊ฐ ๊ณ์ ๋ฐ๋๊ฒ ๋๊ธฐ ๋๋ฌธ์ walk-forwardํ๊ฒ model์ ์
๋ฐ์ดํธ ํ๋ ๊ฒฝ์ฐ์ reproducibility๋ฅผ ๋ง์กฑ์ํค๊ธฐ ์ฝ์ง ์๋ค. ์ฆ, ๋ชจ๋ํฐ๋ง ๊ฒฐ๊ณผ์ ์ค์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๊ฒ ๋ง๋ค๋ ค๋ฉด ๊ธฐ์ ์ ์ผ๋ก ๋ ๋ง์ ์์
์ด ์๊ตฌ๋๋ค.
- ๊ณ ๋ฏผํด๋ณด๋ฉด DB ์ค๊ณ๋ฅผ ํ ๋ ์ด๋ฅผ ์ํ ๋ถ๋ถ์ ๋ง๋ค์ด์ผ ํ๊ณ ์ผ์ ์๊ฐ ๋จ์๋ก weights ์ ๋ณด table์ ๊ณ์ ์์์ผ ํ๋ค.
- ๋ฐ์ดํฐ๋ฅผ IIDํ ํ์ฌ ๋ง๋๋๋ฐ Time-Decay๋ฅผ ๊ณ ๋ คํ๋ค๋ ๊ฑด ๋ชจ์์ด ์๋๊ฐ?
Code
def __getTimeDecay(self, tW, clfLastW=1.):
clfW = tW.sort_index().cumsum()
slope = (1-clfLastW) / clfW.iloc[-1] if clfLastW >= 0 else 1./((clfLastW+1)*clfW.iloc[-1])
const = 1 - slope*clfW.iloc[-1]
clfW = const + slope*clfW
clfW[clfW < 0] = 0
print(f'constant: {const:.2f}, slope: {slope:.2f}, look back sample : {len(clfW[clfW!=0])} total : {len(clfW)}')
return clfW
Class Weights
- Concept
- ํ๋ณธ ๊ฐ์ค๊ฐ(sample weights) vs ๋ถ๋ฅ,ํด๋์ค ๊ฐ์ค๊ฐ (class weights)๋ฅผ ๊ณ ๋ฏผํด๋ณด์. ํน์ class๊ฐ ๋ช ๋ฒ ๋์ค์ง ์๋ ๊ฒฝ์ฐ์ ์ ์ฉํ๋ค.
- ํธ๋ ์ด๋ฉ ์ธก๋ฉด์์ long(1), short(-1) ๋๊ฐ์ ๋ถ๋ฅ๊ฐ ์๊ฑฐ๋ ํน์ ์ค๋ฆฝ(0)๊น์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํด๋ณผ ๋, ๋ ์ด๋ธ์ด 1,-1๋ง ์๋ค๋ฉด ๊ตณ์ด class weights๋ฅผ ๊ณ ๋ คํ ํ์๊ฐ ์์ด๋ณด์ธ๋ค. ์ค์ ๊ฒฝํ์ 0์ ๊ฐ๋ labelingํ๋ค ๋์ค๋๋ฐ 0์ ๊ดํด์ class weight๋ฅผ ๋ฎ๊ฒ ์ฃผ๋ ๋๊ฒ ์ฃผ๋ ์์ ์ ํ ์ ์์ ๊ฒ์ด๋ค.
- ์ค์ ์์ ์ผ๋ง๋ ์ ์ฉํ ์ง๋ ์๋ฌธ.