์๊ณ์ด ์์ฐ์ฌ๊ณ ์์ธก ์ฉ ์๊ณ์ด ๋ชจ๋ธ ์นด๋
๋ชจ๋ธ ์ธ๋ถ์ฌํญ
๋ชจ๋ธ ์ค๋ช
์ด ๋ชจ๋ธ์ ์๊ณ์ด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ ์กฐ ํ๊ฒฝ์์ ์ฌ๊ณ ์์ค์ ์์ธกํ๊ธฐ ์ํด ์ค๊ณ๋์์ต๋๋ค. Conv1D ๋ ์ด์ด๋ฅผ ์ฌ์ฉํ์ฌ ์๊ณ์ด ๋ฐ์ดํฐ์์ ๋ก์ปฌ ํน์ง์ ์ถ์ถํ๊ณ , BiLSTM ๋ ์ด์ด๋ฅผ ์ฌ์ฉํ์ฌ ์๊ฐ์ ์์กด์ฑ์ ์บก์ฒํฉ๋๋ค. ์ด ๋ชจ๋ธ์ ์ญ์ฌ์ ์ฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ จ๋์ด ๋ฏธ๋์ ์ฌ๊ณ ์์ค์ ์์ธกํฉ๋๋ค.
- Developed by: ๋ค์ด๋ฐ๊ถ ์์์ฐ๊ตฌ์
- Funded by: 4INLAB INC.
- Shared by: None
- Model type: Conv1D + BiLSTM, LSTM, GRU, Transformer ๋ฑ ์๊ณ์ด ๋ชจ๋ธ
- Language(s): Python
- License: Apache 2.0, MIT
๊ธฐ์ ์ ์ ํ์ฌํญ
- ์ด ๋ชจ๋ธ์ ๊ณผ๊ฑฐ์ ์ฌ๊ณ ํจํด์ ์ฌ์ฉํ์ฌ ๋ฏธ๋์ ์ฌ๊ณ ์์ค์ ์์ธกํ๋ค๊ณ ๊ฐ์ ํ์ง๋ง, ์ญ์ฌ์ ํธ๋ ๋์์ ๊ทน๋จ์ ์ธ ํธ์ฐจ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ฑ๋ฅ์ด ์ข์ง ์์ ์ ์์ต๋๋ค.
- ๋ชจ๋ธ์ด ์ ์ ํ ํ๋๋์ง ์์ผ๋ฉด ๊ณผ์ ํฉ์ด ๋ฐ์ํ ์ ์์ผ๋ฉฐ, ํนํ ์์ ๋ฐ์ดํฐ์ ์์ ๊ทธ ์ํ์ด ํฝ๋๋ค.
ํ์ต ์ธ๋ถ์ฌํญ
Hardware
- CPU: Intel Core i9-13900K (24 Cores, 32 Threads)
- RAM: 64GB DDR5
- GPU: NVIDIA RTX 4090Ti 24GB
- Storage: 1TB NVMe SSD + 2TB HDD
- Operating System: Windows 10/11
๋ฐ์ดํฐ์ ์ ๋ณด
์ด ๋ชจ๋ธ์ ์๊ณ์ด ์ฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ จ๋ฉ๋๋ค. ์ด ๋ฐ์ดํฐ๋ ์ฌ๊ณ ์์ค, ๋ ์ง ๋ฐ ๊ธฐํ ๊ด๋ จ ํน์ฑ์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ Conv1D์ BiLSTM ๋ ์ด์ด์ ์ ํฉํ๋๋ก MinMax ์ค์ผ์ผ๋ง์ ์ฌ์ฉํ์ฌ ์ ์ฒ๋ฆฌ๋๊ณ ์ ๊ทํ๋ฉ๋๋ค.
Data sources: https://huggingface.co/datasets/quandao92/stock-prediction-training
Training size:
File Number_of_Rows Number_of_Columns Missing_Values Mean Std Min Max Column_Types 37510-P0100_์ฌ๊ณ ๋.csv 1445 4 0 {'Input': 109.58546712802769, 'Output': 101.29411764705883, 'Stock': -2785.61937716263} {'Input': 296.68724811803355, 'Output': 128.93657312491547, 'Stock': 3673.0239542642976} {'Input': 0.0, 'Output': 0.0, 'Stock': -12332.0} {'Input': 1729.0, 'Output': 895.0, 'Stock': 1415.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 37596-P4000_์ฌ๊ณ ๋.csv 1444 4 0 {'Input': 243.54570637119113, 'Output': 193.6045706371191, 'Stock': 65925.12603878116} {'Input': 561.4023180438826, 'Output': 267.2823694340497, 'Stock': 23051.799134789908} {'Input': 0.0, 'Output': 0.0, 'Stock': 822.0} {'Input': 3144.0, 'Output': 1781.0, 'Stock': 84493.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 42778765_์ฌ๊ณ ๋.csv 774 4 0 {'Input': 157.62119576526158, 'Output': 134.12325678375972, 'Stock': 21012.84792653769} {'Input': 309.7029075361264, 'Output': 205.82601027621517, 'Stock': 8195.925470131109} {'Input': 0.0, 'Output': 0.0, 'Stock': 0.0} {'Input': 1957.0, 'Output': 1111.0, 'Stock': 54371.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55421-AAAA0_์ฌ๊ณ ๋.csv 1200 4 0 {'Input': 125.32457616887791, 'Output': 97.88425219845885, 'Stock': 20212.689789475586} {'Input': 256.1219037042129, 'Output': 183.9228577283981, 'Stock': 11837.50158296252} {'Input': 0.0, 'Output': 0.0, 'Stock': 1350.0} {'Input': 1804.0, 'Output': 1200.0, 'Stock': 29582.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55421-AABA0_์ฌ๊ณ ๋.csv 1250 4 0 {'Input': 98.34576759722834, 'Output': 70.54873633255685, 'Stock': 16385.024626397156} {'Input': 213.2654482193094, 'Output': 142.22319426176325, 'Stock': 9579.189939026907} {'Input': 0.0, 'Output': 0.0, 'Stock': 1125.0} {'Input': 1740.0, 'Output': 1040.0, 'Stock': 27895.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55421-N9000_์ฌ๊ณ ๋.csv 1445 4 0 {'Input': 85.21289544065527, 'Output': 82.34580005067112, 'Stock': 9456.364574084605} {'Input': 217.3122037461521, 'Output': 141.24411875413377, 'Stock': 5892.23272801921} {'Input': 0.0, 'Output': 0.0, 'Stock': 300.0} {'Input': 1204.0, 'Output': 876.0, 'Stock': 23148.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55421-N9050_์ฌ๊ณ ๋.csv 1210 4 0 {'Input': 312.7681487750148, 'Output': 279.5602341694698, 'Stock': 42335.17973164216} {'Input': 423.5547606438498, 'Output': 217.1073984704094, 'Stock': 18953.32711711572} {'Input': 0.0, 'Output': 0.0, 'Stock': 880.0} {'Input': 3087.0, 'Output': 1605.0, 'Stock': 76533.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55422-AABA0_์ฌ๊ณ ๋.csv 1180 4 0 {'Input': 65.2345562187494, 'Output': 50.45123576220381, 'Stock': 9232.392694569597} {'Input': 171.0524036426813, 'Output': 111.47922267422175, 'Stock': 4921.795351820058} {'Input': 0.0, 'Output': 0.0, 'Stock': 560.0} {'Input': 1253.0, 'Output': 675.0, 'Stock': 21143.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 55432-AR000_์ฌ๊ณ ๋.csv 1380 4 0 {'Input': 103.78255213511757, 'Output': 93.34193353827462, 'Stock': 5032.346523768436} {'Input': 212.26512201649207, 'Output': 143.27490752827104, 'Stock': 7647.890356211703} {'Input': 0.0, 'Output': 0.0, 'Stock': 850.0} {'Input': 1572.0, 'Output': 860.0, 'Stock': 20115.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 60005413_์ฌ๊ณ ๋.csv 772 4 0 {'Input': 578.6904145077721, 'Output': 3.312176165803109, 'Stock': -155098.99222797927} {'Input': 1310.3599375858219, 'Output': 36.298012893342275, 'Stock': 143702.6483818438} {'Input': 0.0, 'Output': 0.0, 'Stock': -341943.0} {'Input': 6019.0, 'Output': 764.0, 'Stock': 102122.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 62421-59000_์ฌ๊ณ ๋.csv 1594 4 0 {'Input': 8.989335006273526, 'Output': 8.554579673776663, 'Stock': 142.7904642409034} {'Input': 69.94193995489978, 'Output': 57.03142684688043, 'Stock': 412.6341468153742} {'Input': 0.0, 'Output': 0.0, 'Stock': -637.0} {'Input': 888.0, 'Output': 600.0, 'Stock': 1277.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 62422-AR000_์ฌ๊ณ ๋.csv 743 4 0 {'Input': 216.86271870717274, 'Output': 218.25330750569382, 'Stock': 1828.890223547734} {'Input': 660.9764647303546, 'Output': 171.5429683741239, 'Stock': 14663.755822690066} {'Input': 0.0, 'Output': 0.0, 'Stock': -10588.0} {'Input': 5389.0, 'Output': 2445.0, 'Stock': 48551.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 62431-59000_์ฌ๊ณ ๋.csv 1630 4 0 {'Input': 9.530674846625766, 'Output': 8.221472392638036, 'Stock': 1286.2036809815952} {'Input': 70.29446075739038, 'Output': 61.33528025808465, 'Stock': 616.5563598411729} {'Input': 0.0, 'Output': 0.0, 'Stock': 1.0} {'Input': 743.0, 'Output': 740.0, 'Stock': 2824.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 62441-AR000_์ฌ๊ณ ๋.csv 1469 4 0 {'Input': 182.52212389380531, 'Output': 92.61538461538461, 'Stock': -67074.5901974132} {'Input': 538.5965745495109, 'Output': 114.81806391548116, 'Stock': 41312.24229452366} {'Input': 0.0, 'Output': 0.0, 'Stock': -130309.0} {'Input': 3336.0, 'Output': 684.0, 'Stock': 2780.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} 62456-AR000_์ฌ๊ณ ๋.csv 1468 4 0 {'Input': 186.05735554008376, 'Output': 112.28379613804371, 'Stock': 22810.539147026034} {'Input': 608.1109490482561, 'Output': 150.0210573567845, 'Stock': 22782.16359247917} {'Input': 0.0, 'Output': 0.0, 'Stock': -21432.0} {'Input': 4209.0, 'Output': 946.0, 'Stock': 113546.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} B5110-CN000_์ฌ๊ณ ๋.csv 1733 4 0 {'Input': 92.54991344489325, 'Output': 20.79919215233699, 'Stock': -66490.28967109059} {'Input': 309.9338591928675, 'Output': 61.683063312208745, 'Stock': 43044.891729171395} {'Input': 0.0, 'Output': 0.0, 'Stock': -121809.0} {'Input': 2826.0, 'Output': 650.0, 'Stock': 1967.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} BU110-GI900_์ฌ๊ณ ๋.csv 297 4 0 {'Input': 411.05387205387206, 'Output': 373.5656565656566, 'Stock': 4327.20202020202} {'Input': 648.276402767596, 'Output': 516.147871154793, 'Stock': 2672.106758087619} {'Input': 0.0, 'Output': 0.0, 'Stock': 560.0} {'Input': 3846.0, 'Output': 1851.0, 'Stock': 12782.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} V_6000-5218_45_์ฌ๊ณ ๋.csv 627 4 0 {'Input': 42.39712918660287, 'Output': 1.0446570972886762, 'Stock': -2920.3317384370016} {'Input': 94.78046025788936, 'Output': 8.666039405615116, 'Stock': 7392.24161303543} {'Input': 0.0, 'Output': 0.0, 'Stock': -16030.0} {'Input': 1114.0, 'Output': 135.0, 'Stock': 9820.0} {'TransactionDate': dtype('O'), 'Input': dtype('float64'), 'Output': dtype('float64'), 'Stock': dtype('float64')} Features: Historical inventory data
Time-step: 1 day
๋ชจ๋ธ ์ํคํ ์ฒ
Input Layer: Conv1D layer with 128 filters and kernel size of 3.
Hidden Layers:
- Conv1D followed by MaxPooling1D.
- Bidirectional LSTM layer with 128 units.
- Dropout layers to prevent overfitting.
- A second Bidirectional LSTM layer with 64 units.
- A Dense layer for the final prediction.
Optimizer: Adam optimizer.
Loss Function: Mean Squared Error (MSE).
Metrics: Mean Absolute Error (MAE), SMAPE.
ํ์ต ํ๋ฆฌ๋ฏธ
- Learning rate: 0.001
- Batch size: 64
- Epochs: 50
- Time step: 30
- Dropout: 0.1
- Early stopping: Enabled with a patience of 10 epochs
ํ๊ฐ ์งํ
- Accuracy: Percentage of correct predictions.
- MAE (Mean Absolute Error): Measures the average magnitude of errors in the predictions.
- SMAPE (Symmetric Mean Absolute Percentage Error): Measures prediction accuracy in percentage.
ํ์ต ์ฑ๋ฅ ๋ฐ ํ ์คํธ ๊ฒฐ๊ณผ ์์
๋ชจ๋ธ ์ด๋ ฅ ๊ด๋ฆฌ
1์ฐจ๋
๋์ ๊ตฌ์ถํ ์์ฐ์ฌ๊ณ ์์ธก ๋ชจ๋ธ์ ์ฑ๋ฅ์ ์ด๊ธฐ ๊ฐ๊ณต์ด๋ ฅ ๊ธฐ๋ฐ ๋จ๋ณ๋ ์์ธก ์์ค์ ๋จธ๋ฌผ๋ ๊ณ , ์ค์ ์ด์ ์ ์ฉ ์ ์ ํ๋ ํธ์ฐจ์ ๋ชจ๋ธ ์ ํ ๊ธฐ์ค์ ๋ถ๋ช
ํ์ฑ์ด ์กด์ฌํ์ต๋๋ค.
์ด์ ๋ฐ๋ผ 2์ฐจ๋
๋์๋ ๋ค์ํ ๋ฅ๋ฌ๋ ์๊ณ ๋ฆฌ์ฆ ์คํ(CNN-BLSTM, Bi-LSTM, LSTM, GRU, Transformer)์ ํตํด ์ ํ๋ ๊ณ ๋ํ, ๋ชจ๋ธ ์์ ์ฑ ํ๋ณด, ํ์ต ์ด๋ ฅ ๊ด๋ฆฌ์ฒด๊ณ ๊ตฌ์ถ์ ๋ชฉํ๋ก ๊ณ ๋ํ๋ฅผ ์ํํ์ต๋๋ค.
์ฌํ์ต ์ด๋ ฅ ๋ฐ ์ฑ๋ฅ ์ถ์ด
๋์ผํ ์ ์ฒ๋ฆฌ ๊ท๊ฒฉ(MinMaxScaler, window=30), ๊ณตํต ๋ฌ๋๋ ์ดํธ(0.001), Optimizer=Adam ๊ธฐ์ค.
๊ฐ ์คํ์ ๋์ผ Seed๋ก 1ํ ์ธก์ (ํ์ ์ 3ํ ํ๊ท ๊ถ์ฅ).
์ฌํ์ต ์ผ์ ๋ชจ๋ธ ๋ฒํธ ์๊ณ ๋ฆฌ์ฆ ์ ํ๋(%) Epoch ์ Learning Rate Optimizer ํน์ด์ฌํญ 2025-09-07 3 Transformer 92.10 500 0.001 Adam ์์ ์ ์ฑ๋ฅ ์ ์ง 2025-08-28 2 Transformer 92.30 700 0.001 Adam ์ฅ๊ธฐ ์์ ํ ๊ตฌ๊ฐ 2025-08-15 1 Transformer 90.70 600 0.001 Adam Tranformer ๋ชจ๋ธ ๋ณ๊ฒฝ 2025-07-23 9 CNN-BLSTM 91.50 600 0.001 Adam ์ ์ง์ฑ ๊ฒ์ฆ ์ฌํ์ต 2025-07-03 8 CNN-BLSTM 90.70 600 0.001 Adam LSTM ๊ณ์ด ๋น๊ต ํ ์คํธ 2025-06-17 7 CNN-BLSTM 91.10 600 0.001 Adam ์์ธก ์์ ์ ์ง 2025-05-25 6 CNN-BLSTM 91.90 700 0.001 Adam ์ต๊ณ ์ฑ๋ฅ(์๋ฐ๊ธฐ) 2025-05-03 2 GRU 91.30 500 0.001 Adam ๋จ๊ธฐ ์์น์ธ 2025-04-25 17 Bi-LSTM 90.10 600 0.001 Adam ์์ ์ ์๋ ด 2025-04-08 16 Bi-LSTM 89.70 600 0.001 Adam LSTM ๋๋น ๋ฏธ์ธ ํฅ์ 2025-03-17 6 LSTM 88.60 600 0.001 Adam ๊ธฐ๋ณธ LSTM ๋ชจ๋ธ ํ ์คํธ 2025-03-08 4 GRU 86.20 600 0.001 Adam ์ ํ๋ ์ผ์์ ํ๋ฝ 2025-02-26 14 Bi-LSTM 88.50 600 0.001 Adam ์ผ๋ฐ ํ์ต ๋จ๊ณ 2025-02-15 12 Bi-LSTM 87.50 700 0.001 Adam ํ์ต ์์ ํ ์ค 2025-02-04 11 Bi-LSTM 87.20 600 0.001 Adam ์ ์ฒ๋ฆฌ ํ๋ผ๋ฏธํฐ ๋ณ๊ฒฝ 2025-01-26 5 CNN-BLSTM 88.10 500 0.001 Adam ์ด๊ธฐ ํ ์คํธ(baseline)
๋ถ์ ์์ฝ
- ์ ํ๋ ๋ถํฌ: 86.2% ~ 92.3% (ํ์ ๊ธฐ์ฌ๋ 17ํ ๊ธฐ์ค) โ ์ ๋ฐ์ ์ผ๋ก ์์ ์
- Epoch ์์ ์ ํ๋ ๊ฐ ์ง์ ์๊ด๊ด๊ณ๋ ๋ฏธ์ฝ
- CNN-BLSTM/GRU๊ฐ ๋จ๊ธฐ ์์ธก ์ ํ๋์์ ์ฐ์ ๊ฒฝํฅ
ํ์ต ์ค์ ์์ฝ (๊ณตํต ํ๋ผ๋ฏธํฐ ๊ธฐ์ค)
- ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ: MinMaxScaler(ํผ์ฒ๋ณ), ๊ฒฐ์ธก์น 0๊ฑด ๊ธฐ์ค / ์๊ณ์ด ์๋์ฐ
time_step=30 - ๋ชจ๋ธ ๊ตฌ์กฐ:
Conv1D โ MaxPool1D โ (Bi-LSTM or LSTM/GRU) ร 1~2 โ Dropout โ Dense(Output) - Optimizer: Adam (
lr=0.001) - Loss: MSE (ํ๊ท ๊ธฐ์ค)
- Metrics: MAE, sMAPE, (์ด์์งํ) Accuracy%
- ํ์ต ์ค์ผ์ค:
epochs=500~700,batch_size=64, EarlyStopping(patience=10) - ๊ฒ์ฆ ์ ๋ต: Train/Val/Test = 70/15/15, ๋์ผ Seed ๊ณ ์ , ๋์ผ Split ์ฌ์ฌ์ฉ
- ์ฌํ์ฑ/์์นด์ด๋ธ:
artifacts/<algo>/<yyyymmdd_modelNo>/์metrics.json, loss_curve.png, run_config.yaml, weights(sha256)์ ์ฅ- README์ ํ๋
metrics.json์ ๊ธฐ์ค์ผ๋ก ์ฃผ๊ธฐ์ ์ ๋ฐ์ดํธ
์ด์ ๋ฐ์ ์, ๊ฐ์ฅ ์ต์ ์ **์์ ํ(CNN-BLSTM ๊ณ์ด)**์ ๊ธฐ๋ณธ ์ ํํ๋,
๋จ๊ธฐ ๊ธ๋ณ ๊ตฌ๊ฐ(ํ๋ก๋ชจ์ /๊ณ์ ์ ํ)์๋ GRU ๋ณด์กฐ ๋ชจ๋ธ์ A/B ํ ์คํธ ์ต์ ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
์ค์น ๋ฐ ์คํ ๊ฐ์ด๋ผ์ธ
์ด ๋ชจ๋ธ์ ์คํํ๋ ค๋ฉด Python๊ณผ ํจ๊ป ๋ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค:
- pandas: ๋ฐ์ดํฐ ์กฐ์ ๋ฐ ๋ถ์.
- numpy: ์์น ์ฐ์ฐ.
- matplotlib: ๋ฐ์ดํฐ ์๊ฐํ (์: ํ๋ จ ๋ฐ ๊ฒ์ฆ ์์ค ๊ทธ๋ํ).
- scikit-learn: ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ ๋ฐ ํ๊ฐ ์งํ.
- keras: ๋ฅ๋ฌ๋ ๋ชจ๋ธ (Conv1D + BiLSTM) ๊ตฌ์ถ ๋ฐ ํ๋ จ.
- tensorflow: Keras์ ๋ฐฑ์๋.
- gputil: GPU ์ํ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ธ.
- psutil: ์์คํ ๋ฐ ํ๋ก์ธ์ค ์ ํธ๋ฆฌํฐ (๋ชจ๋ํฐ๋ง์ฉ ์ ํ ์ฌํญ).
- torchsummary: ๋ชจ๋ธ ์์ฝ ์ถ๋ ฅ (์ ํ ์ฌํญ
๋ชจ๋ธ ์คํ ๋จ๊ณ:
1. ํ์ํ ํจํค์ง ์ค์น
pip์ ํตํด ํ์ํ ํจํค์ง๋ฅผ ์ค์นํ ์ ์์ต๋๋ค:
pip install pandas numpy matplotlib scikit-learn keras tensorflow gputil psutil torchsummary
2. ๋ฐ์ดํฐ ๋ก๋
- pandas ๋๋ ์ ์ ํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ์ ๋ก๋ํ์ธ์.
3. ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
- MinMaxScaler๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ค์ผ์ผ๋งํ๊ณ ์ฌ๊ณ ๊ฐ์ 0๊ณผ 1 ์ฌ์ด๋ก ์ ๊ทํํฉ๋๋ค.
- Conv1D-BiLSTM ๋ชจ๋ธ์ ์ฌ์ฉํ ์๊ฐ ๋จ๊ณ๋ณ ๋ฐ์ดํฐ์ ์ ๋ง๋ญ๋๋ค.
4. ์คํฌ๋ฆฝํธ ์คํ
- ๋ฐ์ดํฐ๋ฅผ ํ๋ จ ์ธํธ์ ํ ์คํธ ์ธํธ๋ก ๋ถํ ํฉ๋๋ค.
- LSTM ๋ชจ๋ธ์ ๋ง๊ฒ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ณํํฉ๋๋ค.
- ๋ชจ๋ธ์ ๋น๋ํ๊ณ ํ๋ จ์ํต๋๋ค.
- ํ ์คํธ ๋ฐ์ดํฐ์์ ๋ชจ๋ธ์ ํ๊ฐํ๊ณ ์ฑ๋ฅ์ ์๊ฐํํฉ๋๋ค.
์คํ์์ค ๋ผ์ด๋ธ๋ฆฌ ๋ณด์ยท๋ผ์ด์ ์ค ๊ด๋ฆฌ
๊ฐ์
๋ณธ ํ๋ก์ ํธ๋ Python ๊ธฐ๋ฐ ๋ฅ๋ฌ๋ ํ๋ ์์ํฌ(TensorFlow, Keras, scikit-learn, NumPy, Pandas ๋ฑ) ์คํ์์ค๋ฅผ ํ์ฉํ์ฌ ๊ฐ๋ฐ๋์์ต๋๋ค.
๋ด๋ถ๋ง(On-premise) ํ๊ฒฝ์์๋ ์คํ์์ค์ ๋ณด์ ์ทจ์ฝ์ (CVE) ๋ฐ ๋ผ์ด์ ์ค ์๋ฌด ๋ถ์ดํ์
๋ฒ์ ๋ถ์ ๋ฐ ์๋น์ค ์ค๋จ์ผ๋ก ์ด์ด์ง ์ ์์ผ๋ฏ๋ก, ์๋์ ๊ฐ์ ๊ด๋ฆฌ์ฒด๊ณ๋ฅผ ์ ์ฉํฉ๋๋ค.
1. ์ํ ์ง์ (Risk Statement)
- ๋ณด์ ์ํ: ์ธ๋ถ ์คํ์์ค ํจํค์ง์์ ๋ฐ๊ฒฌ๋๋ ์ทจ์ฝ์ (CVE)์ ์ํด
์ ์ฑ ์ฝ๋ ์คํ, ๋ฐ์ดํฐ ์ ์ถ, ๋ชจ๋ธ ๋ฌด๊ฒฐ์ฑ ํผ์ ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํจ. - ๋ฒ์ ์ํ: Apache 2.0, MIT ๋ฑ ๋ผ์ด์ ์ค ๊ณ ์ง๋ฅผ ๋๋ฝํ๊ฑฐ๋ GPL ๊ณ์ด ๋ผ์ด์ ์ค๋ฅผ ์ค์ฉํ ๊ฒฝ์ฐ,
์์ค ๊ณต๊ฐ ์๊ตฌยท๋ฐฐํฌ ์ ํยท๋ฒ์ ๋ถ์ ๋ฐ์ ์ํ. - ์ด์ ์ํ: SBOM(์ํํธ์จ์ด ๊ตฌ์ฑ ๋ช
์ธ์) ๋ฏธ๋น, ๋ฒ์ ๊ด๋ฆฌ ๋ถ์ฌ๋ก ์ธํ
์ฌํ ๋ถ๊ฐ, ๋ณด์ ๊ฐ์ฌ ๋์ ์คํจ, ๊ณต๊ธ๋ง ์ํ(Supply Chain Attack) ๊ฐ๋ฅ์ฑ.
2. ์ ์ฉ ๋ฒ์ (Scope)
| ๊ตฌ๋ถ | ๋ฒ์ |
|---|---|
| ์ฝ๋ | ํ์ต/์ถ๋ก ํ์ดํ๋ผ์ธ, ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์คํฌ๋ฆฝํธ |
| ๋ชจ๋ธ | Conv1D + BiLSTM ํ์ต ๊ฒฐ๊ณผ(๊ฐ์ค์น, ์ฒดํฌํฌ์ธํธ, ๋ชจ๋ธ ํ์ผ) |
| ๋ฐ์ดํฐ | ์์ฒ ์ฌ๊ณ ์๊ณ์ด ๋ฐ์ดํฐ ๋ฐ ์ ์ฒ๋ฆฌ ์ฐ์ถ๋ฌผ |
| ํ๊ฒฝ | ๋ด๋ถ๋ง ์๋ฒ(ํ์ต/์ถ๋ก ), ํ๋ซํผ UI ๋ฐ ๋ฐฐ์น ์๋ฒ |
| ๋ฌธ์ | ๋ชจ๋ธ ์นด๋, ๋งค๋ด์ผ, ๋ฐฐํฌ ๊ธฐ๋ก, ๋ผ์ด์ ์ค ๊ณ ์ง ํ์ผ |
3. ๊ฑฐ๋ฒ๋์ค ์ ์ฑ (Governance Policy)
- ๋ผ์ด์ ์ค ํ์ฉ ๊ธฐ์ค
| ๊ตฌ๋ถ | ๋ผ์ด์ ์ค | ํ์ฉ ์ฌ๋ถ | ์ฃผ์ ์๋ฌด |
|---|---|---|---|
| โ | MIT, BSD-2/3, Apache-2.0 | ํ์ฉ | ์ ์๊ถ/๋ผ์ด์ ์ค ๊ณ ์ง, Apache-2.0์ NOTICE ํฌํจ |
| โ ๏ธ | MPL-2.0, EPL-2.0, LGPL | ์กฐ๊ฑด๋ถ ํ์ฉ | ์์ ํ์ผ ๊ณต๊ฐ ๋ฒ์ ๊ฒํ |
| โ | GPL-2.0/3.0, AGPL-3.0 | ๊ธ์ง | ๋ด๋ถ ์๋น์ค๋ผ๋ ๊ณต๊ฐ ์๋ฌด ๊ฐ๋ฅ |
| โ ๏ธ | CC-BY, CC-BY-SA | ์กฐ๊ฑด๋ถ | ์ถ์ฒ ํ๊ธฐ, ๋์ผ์กฐ๊ฑด๋ฐฐํฌ(ShareAlike) ํ์ธ |
- ๋ฐ์
์ ์ฐจ
- ํจํค์ง/๋ฐ์ดํฐ/๋ชจ๋ธ ๋ฐ์ ์ โ ๋ด๋ถ ์น์ธ ์์ฒญ
- SCA(Software Composition Analysis) ์ค์บ ์ํ (์: OSV-Scanner, Trivy)
- ๊ฒฐ๊ณผ ๊ธฐ๋ก ๋ฐ โํ์ฉ/์กฐ๊ฑด๋ถ/๊ฑฐ์ โ ๊ฒฐ์
- ์น์ธ๋ ๋ฒ์ ๋ง ๋ด๋ถ๋ง ์ ์ฅ์(PyPI Mirror)์ ๋ฑ๋ก
4. Library requirements.txt ๋ฒ์ ์ด๋ ฅ ๊ด๋ฆฌ
๋ณธ ํ๋ก์ ํธ๋ ์์กด์ฑ ์ฌํ์ฑ๊ณผ ๊ณต๊ธ๋ง ๋ณด์์ ์ํด requirements.in โ requirements.txt(ํด์ ํฌํจ) โ SBOM ์์ผ๋ก
์ ๊ธ(lock) + ์ด๋ ฅ(History) + ๊ฐ์ฌ(Traceability) ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
1) ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ
/configs/dependency/
โโ base/
โ โโ requirements.in
โ โโ requirements.txt # ํด์ ํฌํจ (pip-compile ์์ฑ)
โโ dev/
โ โโ requirements-dev.in
โ โโ requirements-dev.txt
โโ constraints.txt # ํ ๊ณตํต ์ ์ฝ(์ถฉ๋ ๋ฐฉ์ง/์ยทํํ)
โโ CHANGELOG_requirements.md # ์์กด์ฑ ๋ณ๊ฒฝ ์ด๋ ฅ
2) ๋ธ๋์น/ํ๊ทธ ๊ท์น
- ๋ธ๋์น:
dep/upgrade-YYYYMMDD(์:dep/upgrade-20251021) - ํ๊ทธ:
deps-vMAJOR.MINOR.PATCH(์:deps-v1.4.2) - ์ปค๋ฐ ๋ฉ์์ง ๊ท์น:
deps(lock): pin versions (TF 2.15.0, numpy 1.26.4) + hashesdeps(upgrade): pandas 2.2.1 โ 2.2.2 (CVE-XXXX fix)deps(revert): rollback to deps-v1.3.0 due to perf regression
3) ์ด๋ ฅ(CHANGELOG) ํ๊ธฐ
/configs/dependency/CHANGELOG_requirements.md ์ ๊ธฐ๋ก:
| ๋ ์ง | ํ๊ทธ | ๋ณ๊ฒฝ ์ ํ | ์ฃผ์ ๋ณ๊ฒฝ | ๊ทผ๊ฑฐ/๋งํฌ | ์ํฅ |
|---|---|---|---|---|---|
| 2024-09-25 | deps-v0.1.0 | pin / initial lock | requirements.in โ requirements.txt ์์ฑ (--generate-hashes)tensorflow 2.8.0, numpy 1.22.4, pandas 1.4.2 ๋ฑ ๊ธฐ๋ณธ ์์กด์ฑ ๊ณ ์ ๋ฐ ํด์ ํฌํจ |
๋ด๋ถ ๋ณด์์ ์ฑ (์ด๊ธฐ ์ ๊ธ) | ์์กด์ฑ ์ฌํ์ฑ ํ๋ณด, ๋น๋ ์์ ํ |
| 2024-10-23 | deps-v0.1.1 | upgrade | pandas 1.4.2 โ 1.4.4, urllib3 1.26.x ๋ณด์ ํจ์น ์ ์ฉ, scikit-learn 1.1.3 โ 1.1.4 ์ ๋ฐ์ดํธ | SCA ๋ฆฌํฌํธ 2024-10 | CVE ๋์, ์ค๋ชจํฌ ํ ์คํธ ํ์ |
| 2024-11-21 | deps-v0.2.0 | upgrade | tensorflow 2.8.0 โ 2.9.1 (๋ณด์ํจ์น ํฌํจ), requests 2.28.1 โ 2.31.0, joblib 1.2.0 โ 1.3.0 | OSV Scanner ๊ฒฐ๊ณผ 2024-11 | ๋ณด์์ทจ์ฝ์ ํด๊ฒฐ, ํธํ์ฑ ๊ฒ์ฆ ํ์ |
| 2025-01-15 | deps-v0.3.0 | pin / constraints ์ถ๊ฐ | constraints.txt ๋์
(protobuf <5, grpcio <2 ์ ์ฝ)requirements-dev.txt ๋ถ๋ฆฌ, dev์ฉ ํจํค์ง ์ ์ |
๋ด๋ถ ์์กด์ฑ ์ถฉ๋ ๋ถ์ | Dev/Staging ํ๊ฒฝ ์ผ๊ด์ฑ ํ๋ณด |
| 2025-02-12 | deps-v0.4.0 | upgrade | numpy 1.22.x โ 1.23.5 ์
๊ทธ๋ ์ด๋ scikit-learn 1.1.4 โ 1.3.2, pandas 1.4.4 โ 2.1.0 |
SCA ๋ณด๊ณ ์ 2025-02 | CVE-2025-XXXX ๋์, ์ฑ๋ฅ ์ฝ๊ฐ ํฅ์ |
| 2025-03-18 | deps-v1.0.0 | upgrade (major) | tensorflow 2.10.0์ผ๋ก ๋ฉ์ด์ ์
๊ทธ๋ ์ด๋ pip-tools 7.x ์ ์ฉ, SBOM ์์ฑ ํ๋ก์ธ์ค ์ถ๊ฐ |
OSV/Trivy 2025-03 ๊ฒฐ๊ณผ | ๋ณด์ยท์ฑ๋ฅ ๋์ ๊ฐ์ , ํ์ต ํ๊ฒฝ ๋ณ๊ฒฝ |
| 2025-05-21 | deps-v1.1.0 | revert / stabilization | numpy 2.x โ 1.26.4 ํ๊ท, tensorflow 2.10.0 ์ ์ง pandas 2.1.0 โ 2.2.1 ์ ๋ฐ์ดํธ, ํด์ ์ฌ์์ฑ |
์ฑ๋ฅ ํ๊ท ํ ์คํธ (ํ๋ จ ์๋ ์ ํ) | ๋ชจ๋ธ ํ์ต ์๊ฐ ๋จ์ถ, ์์ ํ ์๋ฃ |
| 2025-07-23 | deps-v1.2.0 | pin / maintenance | tensorflow 2.10.0 ์ ์ง, scikit-learn 1.5.1 ํ์ , cyclonedx 3.x SBOM ๊ฐฑ์ deps ๋ฌธ์(SBOM, LICENSE NOTICE) ์ ๋ฐ์ดํธ |
๋ด๋ถ ์ ๊ธฐ ์ ๊ฒ (2025-07) | ๋ณด์ยท๋ฒ์ ๊ฐ์ฌ ๋์ ์ค๋น ์๋ฃ |
์์น: ๋ชจ๋ ๋ณ๊ฒฝ์ ์ ๋ฐ๊พธ์๋์ง(๊ทผ๊ฑฐ) ์ ์ํฅ๋ ๋ฅผ ๊ฐ์ด ๋จ๊น๋๋ค.
4) ์น๊ฒฉ(DevโStagingโProd) ์ํฌํ๋ก
- Dev ์ ๊ธ:
pip-compile --generate-hashes -o base/requirements.txt base/requirements.in - SCA ์ค์บ: OSV-Scanner/Trivy๋ก CVE ํ์ธ โ ๊ฒฐ๊ณผ ์ฒจ๋ถ
- Staging ๊ฒ์ฆ: ์ฌํ์ต ์ค๋ชจํฌ ํ
์คํธ(์ํ ๋ฐ์ดํฐ),
pip check๋ฌด๊ฒฐ์ฑ ํ์ธ - SBOM ์์ฑ:
cyclonedx-py -o sbom_cyclonedx.json - Prod ์น๊ฒฉ: ํ๊ทธ(
deps-vX.Y.Z) ๋ฌ๊ณ CHANGELOG ๊ธฐ๋ก, ์ํฐํฉํธ ๋ณด๊ด
5) ๋กค๋ฐฑ ์ ์ฑ
- ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ๋ฐ๋ก ์ด์ ํ๊ทธ์ lockfile๋ก ๋๋๋ฆฝ๋๋ค.
- ์คํ:
git checkout tags/deps-v1.3.0 -- configs/dependency/base/requirements.txt pip install --require-hashes -r configs/dependency/base/requirements.txt
6) ์์ฑ/์ ๊ทธ๋ ์ด๋ ์ปค๋งจ๋
# ๋๊ตฌ ์ค์น
pip install pip-tools==7.4.1
# (์ ํ) ์ ์ฝ ํ์ผ ์ฌ์ฉ
# constraints.txt ๋ด ๊ณตํต ์ ์ฝ ๊ด๋ฆฌ (์: protobuf<5)
# 1) ์ ๊ธํ์ผ ์์ฑ(ํด์ ํฌํจ)
pip-compile \
--generate-hashes \
--resolver=backtracking \
--output-file configs/dependency/base/requirements.txt \
configs/dependency/base/requirements.in
# 2) ์ค์น ์ ํด์ ๊ฒ์ฆ
pip install --require-hashes -r configs/dependency/base/requirements.txt
# 3) ์์กด์ฑ ์ถฉ๋ ๊ฒ์ฌ
pip check
# 4) SBOM ์์ฑ (๊ฐ์ฌ/๊ฐ๋ฆฌ ๋์)
cyclonedx-py -o artifacts/sbom/sbom_cyclonedx_$(date +%F).json
5. SBOM ๋ฐ NOTICE
๐ SBOM ํ๋
| ํญ๋ชฉ | ์์ ๊ฐ |
|---|---|
| Name | tensorflow |
| Version | 2.15.0 |
| License | Apache-2.0 |
| Hash | sha256:d2b8f9f7a18fef2d7f6a08db5a7... |
| Supplier | Google LLC |
| Download URL | https://pypi.org/project/tensorflow/2.15.0/ |
๐ THIRD_PARTY_NOTICES.txt ์์
This product includes third-party software components:
- TensorFlow 2.15.0 โ Apache-2.0
- Keras 2.15.0 โ Apache-2.0
- NumPy 1.26.4 โ BSD-3-Clause
- Pandas 2.2.2 โ BSD-3-Clause
- scikit-learn 1.5.1 โ BSD-3-Clause
- Matplotlib 3.8.x โ PSF License All rights reserved by their respective owners.
6. ์ทจ์ฝ์ ๋ฐ ๋ฒ์ ๋ฆฌ์คํฌ ๋์ ์๋๋ฆฌ์ค
| ์๋๋ฆฌ์ค | ์ํฅ | ๋์ ์กฐ์น | ์ฆ์ |
|---|---|---|---|
| ๊ณ ์ํ CVE ํฌํจ | ๋ณด์ ์นจํด, ๋ฐ์ดํฐ ๋ ธ์ถ | ๋ฒ์ ์ /๊ต์ฒด, ์ํฅํ๊ฐ ๋ณด๊ณ ์ ์์ฑ | SCA ๊ฒฐ๊ณผ ๋ฐ ํจ์น ๋ก๊ทธ |
| GPL/AGPL ์ฝ๋ ํผ์ | ์์ค ๊ณต๊ฐ ์๊ตฌ, ์๋น์ค ์ค๋จ | ๋์ฒด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ต์ฒด, ๋ฒ๋ฌด ๊ฒํ | ๋ผ์ด์ ์ค ๋ถ์์ |
| ๋ฐ์ดํฐ ์ฝ๊ด ์๋ฐ | ๋ฒ์ ๋ถ์, ๋ฐฐํฌ ๊ธ์ง | ์ฌ์ฉ ์ค๋จ, ์ถ์ฒ ๋ช ์, ๋์ฒด ๋ฐ์ดํฐ ํ๋ณด | ์ฝ๊ด ์ฌ๋ณธ, ์ฌ์ฉ๋ด์ญ ๋ก๊ทธ |
| SBOM ๋ฏธ์์ฑ | ๊ฐ์ฌยทRCA ๋ถ๊ฐ | SBOM ์ฆ์ ์์ฑ ๋ฐ ๊ด๋ฆฌ ์ ์ฐจ ๊ฐํ | SBOM ํ์ผ, ์น์ธ ๋ด์ญ |
7. ๊ฐ๋ฐ์ ์ฒดํฌ๋ฆฌ์คํธ (Developer Checklist)
- [โ]
requirements.txt๋ฒ์ ๋ฐ ํด์ ๊ณ ์ ์๋ฃ - [โ] SBOM ํ์ผ ์์ฑ ๋ฐ ์ ์ฅ
- [โ] SCA/๋ผ์ด์ ์ค ์ค์บ ํต๊ณผ ๋ฆฌํฌํธ ์ฒจ๋ถ
- [โ] LICENSE / NOTICE / THIRD_PARTY_NOTICES ํฌํจ
- [โ] ๋ฐ์ดํฐยท๋ชจ๋ธ ์ถ์ฒ ํ๊ธฐ ๋ฐ ๊ถ๋ฆฌ ๋ช ์
- [โ] ์ด์ ๋ก๊ทธ์ ๋ฒ์ /ํด์ ๊ธฐ๋ก ์๋ฃ
8. ์ฑ ์ ๋ฐ ์ญํ (Roles & Responsibility)
| ์ญํ | ์ฑ ์ |
|---|---|
| ๊ฐ๋ฐํ | ๋ผ์ด์ ์ค ์ค์, SCA ๊ฒฐ๊ณผ ๊ด๋ฆฌ, SBOM ์์ฑ |
| ๋ณด์๊ด๋ฆฌ์ | ์ทจ์ฝ์ ์ ๊ฒ ๋ฐ ํจ์น ๊ฒํ |
| ๋ฒ๋ฌดํ | ๋ผ์ด์ ์ค ํด์, ๋ถ์ ๋์ |
| ์ด์ํ | ๋ก๊ทธ ๊ด๋ฆฌ, ๋ฐฐํฌ ์์ ๊ฒ์ฆ |

