dny1010 commited on
Commit
f1d604f
Β·
verified Β·
1 Parent(s): 3a2fe1d

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +139 -0
  2. ligthGBM(end).ipynb +1 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import altair as alt
4
+
5
+ # ===============================
6
+ # 1️⃣ 데이터 뢈러였기
7
+ # ===============================
8
+
9
+ past_path = '/content/2018-2024.xlsx'
10
+ future_path = '/content/μ˜ˆμƒμˆ˜μš”λŸ‰_2025예츑.xlsx'
11
+
12
+ past_df = pd.read_excel(past_path)
13
+ future_df = pd.read_excel(future_path)
14
+
15
+ past_df['μ›”'] = past_df['μ›”'].astype(int)
16
+ future_df['μ›”'] = future_df['μ›”'].astype(int)
17
+
18
+ past_df = past_df.rename(columns={'νŒλ§€λŸ‰(kg)': 'y'})
19
+ future_df = future_df.rename(columns={'μ˜ˆμƒμˆ˜μš”λŸ‰': 'y'})
20
+
21
+ past_df['y'] = past_df['y'].astype(int)
22
+ future_df['y'] = future_df['y'].round().astype(int)
23
+
24
+ # ===============================
25
+ # 2️⃣ νŽ˜μ΄μ§€ μ„€μ • & μŠ€νƒ€μΌ
26
+ # ===============================
27
+
28
+ st.set_page_config(page_title="과일 μˆ˜μš”λŸ‰ λŒ€μ‹œλ³΄λ“œ", layout="wide")
29
+
30
+ st.markdown("""
31
+ <style>
32
+ /* 타이틀을 더 μ•„λž˜λ‘œ λ‚΄λ €μ„œ 헀더와 κ²ΉμΉ˜μ§€ μ•Šκ²Œ */
33
+ .main > div:first-child {
34
+ padding-top: 50px !important;
35
+ }
36
+ .title {
37
+ font-size: 30px;
38
+ font-weight: 700;
39
+ margin-top: 25px;
40
+ margin-bottom: 20px;
41
+ }
42
+ </style>
43
+ """, unsafe_allow_html=True)
44
+
45
+ # νŽ˜μ΄μ§€ 타이틀
46
+ st.markdown("<div class='title'>🍎 과일 μˆ˜μš”λŸ‰ λŒ€μ‹œλ³΄λ“œ (κ³Όκ±° + 2025 예츑)</div>", unsafe_allow_html=True)
47
+
48
+ # ===============================
49
+ # 3️⃣ 데이터 선택
50
+ # ===============================
51
+
52
+ data_type = st.sidebar.radio("πŸ“‚ μ‚¬μš©ν•  데이터", ["κ³Όκ±° 데이터", "2025λ…„ 예츑 데이터"])
53
+ selected_df = past_df if data_type == "κ³Όκ±° 데이터" else future_df
54
+
55
+ # ===============================
56
+ # 4️⃣ 년도 선택 (2025λ…„ μ˜ˆμΈ‘μ€ μˆ¨κΉ€)
57
+ # ===============================
58
+
59
+ if data_type == "κ³Όκ±° 데이터":
60
+ available_years = sorted(selected_df['년도'].unique())
61
+
62
+ selected_years = st.multiselect(
63
+ "πŸ“… μ‘°νšŒν•  년도",
64
+ available_years,
65
+ default=[] # κΈ°λ³Έ 선택 μ—†μŒ
66
+ )
67
+
68
+ df_filtered = selected_df[selected_df['년도'].isin(selected_years)]
69
+ else:
70
+ df_filtered = selected_df.copy() # 2025λ…„λ§Œ 쑴재 β†’ μžλ™ κ³ μ •
71
+
72
+ # ===============================
73
+ # 5️⃣ 과일 선택 (κΈ°λ³Έ 선택 μ—†μŒ)
74
+ # ===============================
75
+
76
+ fruits = sorted(df_filtered['과일쒅λ₯˜'].unique())
77
+
78
+ selected_fruits = st.multiselect(
79
+ "🍊 ν‘œμ‹œν•  과일 선택",
80
+ fruits,
81
+ default=[] # κΈ°λ³Έ 선택 μ—†μŒ
82
+ )
83
+
84
+ df_chart = df_filtered[df_filtered['과일쒅λ₯˜'].isin(selected_fruits)]
85
+
86
+ # ===============================
87
+ # 6️⃣ κ·Έλž˜ν”„ μ˜μ—­
88
+ # ===============================
89
+
90
+ st.subheader("πŸ“ˆ 월별 μˆ˜μš”λŸ‰ κ·Έλž˜ν”„")
91
+
92
+ if len(df_chart) > 0:
93
+
94
+ if data_type == "κ³Όκ±° 데이터":
95
+ years = sorted(df_chart['년도'].unique())
96
+ else:
97
+ years = [2025]
98
+
99
+ for y in years:
100
+ st.markdown(f"### πŸ“Œ {y}λ…„")
101
+
102
+ df_year = df_chart[df_chart['년도'] == y]
103
+
104
+ chart = (
105
+ alt.Chart(df_year)
106
+ .mark_line(point=True)
107
+ .encode(
108
+ x=alt.X('μ›”:O', title='μ›”', axis=alt.Axis(labelAngle=0)),
109
+ y=alt.Y('y:Q', title='μˆ˜μš”λŸ‰'),
110
+ color='과일쒅λ₯˜:N',
111
+ tooltip=['년도', '과일쒅λ₯˜', 'μ›”', 'y']
112
+ )
113
+ .properties(height=350)
114
+ )
115
+
116
+ st.altair_chart(chart, use_container_width=True)
117
+
118
+ else:
119
+ st.info("κ·Έλž˜ν”„μ— ν‘œμ‹œν•  과일을 μ„ νƒν•˜μ„Έμš”.")
120
+
121
+ # ===============================
122
+ # 7️⃣ ν…Œμ΄λΈ” μ˜μ—­
123
+ # ===============================
124
+
125
+ st.subheader("πŸ“Š 상세 데이터")
126
+
127
+ selected_fruits_table = st.multiselect(
128
+ "πŸ“‹ ν…Œμ΄λΈ” ν‘œμ‹œ 과일",
129
+ fruits,
130
+ default=[]
131
+ )
132
+
133
+ df_table = df_filtered[df_filtered['과일쒅λ₯˜'].isin(selected_fruits_table)]
134
+
135
+ if len(df_table) > 0:
136
+ df_show = df_table[['년도', 'μ›”', '과일쒅λ₯˜', 'y']].rename(columns={'y': 'μˆ˜μš”λŸ‰'})
137
+ st.dataframe(df_show, use_container_width=True)
138
+ else:
139
+ st.info("ν…Œμ΄λΈ”μ— ν‘œμ‹œν•  과일을 μ„ νƒν•˜μ„Έμš”.")
ligthGBM(end).ipynb ADDED
@@ -0,0 +1 @@
 
 
1
+ {"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"gpuType":"T4"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"},"accelerator":"GPU"},"cells":[{"cell_type":"code","execution_count":27,"metadata":{"id":"mTYOtWHZk2rH","executionInfo":{"status":"ok","timestamp":1764141390285,"user_tz":-540,"elapsed":23,"user":{"displayName":"이호","userId":"08153557084945698455"}}},"outputs":[],"source":["import warnings\n","warnings.filterwarnings('ignore')"]},{"cell_type":"code","source":["import pandas as pd\n","import numpy as np\n","import joblib\n","import lightgbm as lgb\n","from lightgbm import LGBMRegressor\n","from sklearn.model_selection import RandomizedSearchCV\n","from scipy.stats import randint, uniform\n","from sklearn.metrics import mean_squared_error, r2_score\n","\n","# ===============================\n","# 데이터 λ‘œλ“œ 및 μ „μ²˜λ¦¬\n","# ===============================\n","file_path = '/content/2018-2024.xlsx'\n","df = pd.read_excel(file_path)\n","\n","cols = [\"과일쒅λ₯˜\", \"κ³„μ ˆ\", \"κ΅­λ‚΄μˆ˜μž…\"]\n","for c in cols:\n"," df[c] = df[c].astype(\"category\")\n","\n","x = [\"년도\", \"μ›”\", \"과일쒅λ₯˜\", \"ν‰κ· κΈ°μ˜¨\", \"κ°•μˆ˜λŸ‰\", \"μΌμ‘°μ‹œκ°„\", \"κ³„μ ˆ\", \"κ΅­λ‚΄μˆ˜μž…\"]\n","y = \"νŒλ§€λŸ‰(kg)\"\n","\n","train_df = df[df[\"년도\"] <= 2023]\n","valid_df = df[df[\"년도\"] == 2024]\n","\n","X_train = train_df[x]\n","y_train = train_df[y]\n","X_valid = valid_df[x]\n","y_valid = valid_df[y]"],"metadata":{"id":"WVNBN0qslHfI","executionInfo":{"status":"ok","timestamp":1764141390995,"user_tz":-540,"elapsed":666,"user":{"displayName":"이호","userId":"08153557084945698455"}}},"execution_count":28,"outputs":[]},{"cell_type":"code","source":["param_dist = {\n"," 'num_leaves': randint(20, 300),\n"," 'max_depth': randint(3, 20),\n"," 'learning_rate': uniform(0.01, 0.2),\n"," 'n_estimators': randint(200, 1500),\n"," 'subsample': uniform(0.5, 0.5),\n"," 'colsample_bytree': uniform(0.5, 0.5),\n"," 'min_child_samples': randint(5, 100),\n"," 'reg_alpha': uniform(0, 1),\n"," 'reg_lambda': uniform(0, 1)\n","}\n","\n","# 초기 λͺ¨λΈ 생성\n","base_model = LGBMRegressor(\n"," objective='regression',\n"," random_state=42,\n"," verbose=-1\n",")\n","\n","# RandomizedSearchCV μ‹€ν–‰\n","grid = RandomizedSearchCV(\n"," estimator=base_model,\n"," param_distributions=param_dist,\n"," n_iter=50,\n"," cv=3,\n"," scoring='neg_root_mean_squared_error',\n"," verbose=2,\n"," random_state=42,\n"," n_jobs=-1\n",")\n","\n","grid.fit(X_train, y_train)\n","\n","# 졜적 νŒŒλΌλ―Έν„° κ°€μ Έμ˜€κΈ°\n","best_params = grid.best_params_\n","print(\"졜적 νŒŒλΌλ―Έν„°:\", best_params)\n","\n","# 졜적 νŒŒλΌλ―Έν„° 적용\n","model = LGBMRegressor(objective='regression', random_state=42, **best_params)\n","callbacks = [\n"," lgb.early_stopping(stopping_rounds=50),\n"," lgb.log_evaluation(period=10)\n","]\n","evals_result = {}\n","\n","model.fit(\n"," X_train, y_train,\n"," eval_set=[(X_train, y_train), (X_valid, y_valid)],\n"," eval_metric=[\"rmse\", \"mae\"],\n"," callbacks=callbacks\n",")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":1000},"id":"_L58W68tBV3U","executionInfo":{"status":"ok","timestamp":1764141462810,"user_tz":-540,"elapsed":71810,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"67f14eaf-ca9b-4f41-c0bc-7c0ec1ffa12a"},"execution_count":29,"outputs":[{"output_type":"stream","name":"stdout","text":["Fitting 3 folds for each of 50 candidates, totalling 150 fits\n","졜적 νŒŒλΌλ―Έν„°: {'colsample_bytree': np.float64(0.6668543055695109), 'learning_rate': np.float64(0.038573363584388155), 'max_depth': 5, 'min_child_samples': 26, 'n_estimators': 969, 'num_leaves': 211, 'reg_alpha': np.float64(0.9922115592912175), 'reg_lambda': np.float64(0.6174815096277165), 'subsample': np.float64(0.8058265802441404)}\n","Training until validation scores don't improve for 50 rounds\n","[10]\ttraining's rmse: 8364.92\ttraining's l1: 6685.02\ttraining's l2: 6.99719e+07\tvalid_1's rmse: 9149.05\tvalid_1's l1: 7129.23\tvalid_1's l2: 8.37051e+07\n","[20]\ttraining's rmse: 7500.46\ttraining's l1: 6005.36\ttraining's l2: 5.62568e+07\tvalid_1's rmse: 8285.08\tvalid_1's l1: 6453.63\tvalid_1's l2: 6.86426e+07\n","[30]\ttraining's rmse: 6124.22\ttraining's l1: 4893.36\ttraining's l2: 3.75061e+07\tvalid_1's rmse: 6931.29\tvalid_1's l1: 5333.86\tvalid_1's l2: 4.80428e+07\n","[40]\ttraining's rmse: 5415.69\ttraining's l1: 4294.89\ttraining's l2: 2.93297e+07\tvalid_1's rmse: 6241.32\tvalid_1's l1: 4739.57\tvalid_1's l2: 3.89541e+07\n","[50]\ttraining's rmse: 4892.09\ttraining's l1: 3832.33\ttraining's l2: 2.39325e+07\tvalid_1's rmse: 5717.96\tvalid_1's l1: 4296.36\tvalid_1's l2: 3.26951e+07\n","[60]\ttraining's rmse: 4368.95\ttraining's l1: 3381.43\ttraining's l2: 1.90877e+07\tvalid_1's rmse: 5198.29\tvalid_1's l1: 3861.53\tvalid_1's l2: 2.70222e+07\n","[70]\ttraining's rmse: 4068.56\ttraining's l1: 3107.26\ttraining's l2: 1.65532e+07\tvalid_1's rmse: 4873.44\tvalid_1's l1: 3586.68\tvalid_1's l2: 2.37504e+07\n","[80]\ttraining's rmse: 3823.93\ttraining's l1: 2890.24\ttraining's l2: 1.46224e+07\tvalid_1's rmse: 4624.21\tvalid_1's l1: 3388.92\tvalid_1's l2: 2.13834e+07\n","[90]\ttraining's rmse: 3537.65\ttraining's l1: 2653.08\ttraining's l2: 1.2515e+07\tvalid_1's rmse: 4337.74\tvalid_1's l1: 3168.92\tvalid_1's l2: 1.8816e+07\n","[100]\ttraining's rmse: 3226.14\ttraining's l1: 2416.54\ttraining's l2: 1.0408e+07\tvalid_1's rmse: 4047.12\tvalid_1's l1: 2953.25\tvalid_1's l2: 1.63792e+07\n","[110]\ttraining's rmse: 3089.18\ttraining's l1: 2301.08\ttraining's l2: 9.54306e+06\tvalid_1's rmse: 3902.17\tvalid_1's l1: 2842.47\tvalid_1's l2: 1.5227e+07\n","[120]\ttraining's rmse: 2904.52\ttraining's l1: 2151.46\ttraining's l2: 8.43623e+06\tvalid_1's rmse: 3723.83\tvalid_1's l1: 2697.01\tvalid_1's l2: 1.38669e+07\n","[130]\ttraining's rmse: 2849.22\ttraining's l1: 2100.04\ttraining's l2: 8.11803e+06\tvalid_1's rmse: 3668.66\tvalid_1's l1: 2653.01\tvalid_1's l2: 1.34591e+07\n","[140]\ttraining's rmse: 2769.92\ttraining's l1: 2041.05\ttraining's l2: 7.67246e+06\tvalid_1's rmse: 3581.28\tvalid_1's l1: 2591.87\tvalid_1's l2: 1.28255e+07\n","[150]\ttraining's rmse: 2649.8\ttraining's l1: 1952.2\ttraining's l2: 7.02141e+06\tvalid_1's rmse: 3455.61\tvalid_1's l1: 2498.66\tvalid_1's l2: 1.19412e+07\n","[160]\ttraining's rmse: 2489.63\ttraining's l1: 1836.47\ttraining's l2: 6.19828e+06\tvalid_1's rmse: 3300.54\tvalid_1's l1: 2385.98\tvalid_1's l2: 1.08936e+07\n","[170]\ttraining's rmse: 2428.21\ttraining's l1: 1793.54\ttraining's l2: 5.8962e+06\tvalid_1's rmse: 3238.69\tvalid_1's l1: 2343.36\tvalid_1's l2: 1.04891e+07\n","[180]\ttraining's rmse: 2352.9\ttraining's l1: 1740.28\ttraining's l2: 5.53615e+06\tvalid_1's rmse: 3165.15\tvalid_1's l1: 2294.37\tvalid_1's l2: 1.00181e+07\n","[190]\ttraining's rmse: 2247.03\ttraining's l1: 1664.47\ttraining's l2: 5.04913e+06\tvalid_1's rmse: 3042.88\tvalid_1's l1: 2212.82\tvalid_1's l2: 9.25912e+06\n","[200]\ttraining's rmse: 2212.71\ttraining's l1: 1640.04\ttraining's l2: 4.89607e+06\tvalid_1's rmse: 3008.1\tvalid_1's l1: 2186.6\tvalid_1's l2: 9.04868e+06\n","[210]\ttraining's rmse: 2128.53\ttraining's l1: 1580.72\ttraining's l2: 4.53065e+06\tvalid_1's rmse: 2911.36\tvalid_1's l1: 2119.08\tvalid_1's l2: 8.47601e+06\n","[220]\ttraining's rmse: 2054.54\ttraining's l1: 1527.52\ttraining's l2: 4.22112e+06\tvalid_1's rmse: 2825.49\tvalid_1's l1: 2060.53\tvalid_1's l2: 7.98337e+06\n","[230]\ttraining's rmse: 2006.75\ttraining's l1: 1494.26\ttraining's l2: 4.02705e+06\tvalid_1's rmse: 2770.28\tvalid_1's l1: 2018.88\tvalid_1's l2: 7.67443e+06\n","[240]\ttraining's rmse: 1985.38\ttraining's l1: 1480.37\ttraining's l2: 3.94172e+06\tvalid_1's rmse: 2749.38\tvalid_1's l1: 2005.93\tvalid_1's l2: 7.55909e+06\n","[250]\ttraining's rmse: 1957.92\ttraining's l1: 1461.36\ttraining's l2: 3.83346e+06\tvalid_1's rmse: 2721.79\tvalid_1's l1: 1987.55\tvalid_1's l2: 7.40814e+06\n","[260]\ttraining's rmse: 1934.47\ttraining's l1: 1444.69\ttraining's l2: 3.74218e+06\tvalid_1's rmse: 2704.81\tvalid_1's l1: 1975.49\tvalid_1's l2: 7.31598e+06\n","[270]\ttraining's rmse: 1911.46\ttraining's l1: 1428.17\ttraining's l2: 3.65369e+06\tvalid_1's rmse: 2678.44\tvalid_1's l1: 1956.16\tvalid_1's l2: 7.17403e+06\n","[280]\ttraining's rmse: 1894.5\ttraining's l1: 1415.4\ttraining's l2: 3.58912e+06\tvalid_1's rmse: 2664.93\tvalid_1's l1: 1946.11\tvalid_1's l2: 7.10184e+06\n","[290]\ttraining's rmse: 1871.2\ttraining's l1: 1399.21\ttraining's l2: 3.50141e+06\tvalid_1's rmse: 2649.51\tvalid_1's l1: 1938.69\tvalid_1's l2: 7.01991e+06\n","[300]\ttraining's rmse: 1857.24\ttraining's l1: 1389.15\ttraining's l2: 3.44932e+06\tvalid_1's rmse: 2636.69\tvalid_1's l1: 1930.23\tvalid_1's l2: 6.95214e+06\n","[310]\ttraining's rmse: 1839.42\ttraining's l1: 1377.01\ttraining's l2: 3.38346e+06\tvalid_1's rmse: 2626.18\tvalid_1's l1: 1924.25\tvalid_1's l2: 6.8968e+06\n","[320]\ttraining's rmse: 1823.22\ttraining's l1: 1364.5\ttraining's l2: 3.32413e+06\tvalid_1's rmse: 2617.33\tvalid_1's l1: 1921.18\tvalid_1's l2: 6.8504e+06\n","[330]\ttraining's rmse: 1809.69\ttraining's l1: 1354.89\ttraining's l2: 3.27498e+06\tvalid_1's rmse: 2614.48\tvalid_1's l1: 1921.37\tvalid_1's l2: 6.83549e+06\n","[340]\ttraining's rmse: 1795.71\ttraining's l1: 1345.9\ttraining's l2: 3.22458e+06\tvalid_1's rmse: 2610.11\tvalid_1's l1: 1920.8\tvalid_1's l2: 6.81267e+06\n","[350]\ttraining's rmse: 1781.91\ttraining's l1: 1336\ttraining's l2: 3.1752e+06\tvalid_1's rmse: 2610.18\tvalid_1's l1: 1920.98\tvalid_1's l2: 6.81302e+06\n","[360]\ttraining's rmse: 1767.5\ttraining's l1: 1326.89\ttraining's l2: 3.12406e+06\tvalid_1's rmse: 2600.29\tvalid_1's l1: 1915.84\tvalid_1's l2: 6.76149e+06\n","[370]\ttraining's rmse: 1762.85\ttraining's l1: 1323.65\ttraining's l2: 3.10763e+06\tvalid_1's rmse: 2598.81\tvalid_1's l1: 1914.59\tvalid_1's l2: 6.75382e+06\n","[380]\ttraining's rmse: 1748.76\ttraining's l1: 1314.27\ttraining's l2: 3.05816e+06\tvalid_1's rmse: 2596.89\tvalid_1's l1: 1912.65\tvalid_1's l2: 6.74385e+06\n","[390]\ttraining's rmse: 1742.3\ttraining's l1: 1310.36\ttraining's l2: 3.03562e+06\tvalid_1's rmse: 2597.62\tvalid_1's l1: 1913.54\tvalid_1's l2: 6.74762e+06\n","[400]\ttraining's rmse: 1732.25\ttraining's l1: 1303.56\ttraining's l2: 3.0007e+06\tvalid_1's rmse: 2593.31\tvalid_1's l1: 1910.44\tvalid_1's l2: 6.72528e+06\n","[410]\ttraining's rmse: 1722.75\ttraining's l1: 1297.03\ttraining's l2: 2.96787e+06\tvalid_1's rmse: 2587.27\tvalid_1's l1: 1907.05\tvalid_1's l2: 6.69395e+06\n","[420]\ttraining's rmse: 1713.85\ttraining's l1: 1291.03\ttraining's l2: 2.93729e+06\tvalid_1's rmse: 2582.19\tvalid_1's l1: 1904.36\tvalid_1's l2: 6.66769e+06\n","[430]\ttraining's rmse: 1702.76\ttraining's l1: 1283.44\ttraining's l2: 2.89938e+06\tvalid_1's rmse: 2575.94\tvalid_1's l1: 1900.19\tvalid_1's l2: 6.63547e+06\n","[440]\ttraining's rmse: 1695.19\ttraining's l1: 1278.47\ttraining's l2: 2.87366e+06\tvalid_1's rmse: 2573.5\tvalid_1's l1: 1899.14\tvalid_1's l2: 6.62291e+06\n","[450]\ttraining's rmse: 1687.66\ttraining's l1: 1273.32\ttraining's l2: 2.84818e+06\tvalid_1's rmse: 2566.99\tvalid_1's l1: 1895.87\tvalid_1's l2: 6.58942e+06\n","[460]\ttraining's rmse: 1682.54\ttraining's l1: 1269.91\ttraining's l2: 2.83093e+06\tvalid_1's rmse: 2564.24\tvalid_1's l1: 1893.87\tvalid_1's l2: 6.57531e+06\n","[470]\ttraining's rmse: 1679.41\ttraining's l1: 1267.85\ttraining's l2: 2.82043e+06\tvalid_1's rmse: 2562.32\tvalid_1's l1: 1892.87\tvalid_1's l2: 6.56546e+06\n","[480]\ttraining's rmse: 1675.22\ttraining's l1: 1265.58\ttraining's l2: 2.80635e+06\tvalid_1's rmse: 2559.72\tvalid_1's l1: 1891.06\tvalid_1's l2: 6.55217e+06\n","[490]\ttraining's rmse: 1665.02\ttraining's l1: 1257.69\ttraining's l2: 2.7723e+06\tvalid_1's rmse: 2555.62\tvalid_1's l1: 1886.9\tvalid_1's l2: 6.53119e+06\n","[500]\ttraining's rmse: 1655\ttraining's l1: 1250.27\ttraining's l2: 2.73904e+06\tvalid_1's rmse: 2549.84\tvalid_1's l1: 1882.13\tvalid_1's l2: 6.50169e+06\n","[510]\ttraining's rmse: 1649.45\ttraining's l1: 1246.43\ttraining's l2: 2.72067e+06\tvalid_1's rmse: 2547.85\tvalid_1's l1: 1879.99\tvalid_1's l2: 6.49156e+06\n","[520]\ttraining's rmse: 1639.5\ttraining's l1: 1239.3\ttraining's l2: 2.68797e+06\tvalid_1's rmse: 2547.81\tvalid_1's l1: 1878.84\tvalid_1's l2: 6.49131e+06\n","[530]\ttraining's rmse: 1634.08\ttraining's l1: 1235.49\ttraining's l2: 2.67021e+06\tvalid_1's rmse: 2544.23\tvalid_1's l1: 1876.96\tvalid_1's l2: 6.47309e+06\n","[540]\ttraining's rmse: 1627.56\ttraining's l1: 1231.22\ttraining's l2: 2.64895e+06\tvalid_1's rmse: 2543.3\tvalid_1's l1: 1876.22\tvalid_1's l2: 6.4684e+06\n","[550]\ttraining's rmse: 1618.42\ttraining's l1: 1224.92\ttraining's l2: 2.61928e+06\tvalid_1's rmse: 2543.54\tvalid_1's l1: 1877.58\tvalid_1's l2: 6.46961e+06\n","[560]\ttraining's rmse: 1611.13\ttraining's l1: 1219.67\ttraining's l2: 2.59574e+06\tvalid_1's rmse: 2544.18\tvalid_1's l1: 1877.5\tvalid_1's l2: 6.47287e+06\n","[570]\ttraining's rmse: 1604.4\ttraining's l1: 1214.6\ttraining's l2: 2.57411e+06\tvalid_1's rmse: 2542.77\tvalid_1's l1: 1875.64\tvalid_1's l2: 6.46569e+06\n","[580]\ttraining's rmse: 1598.63\ttraining's l1: 1210.18\ttraining's l2: 2.55563e+06\tvalid_1's rmse: 2542.94\tvalid_1's l1: 1875.54\tvalid_1's l2: 6.46656e+06\n","[590]\ttraining's rmse: 1595.65\ttraining's l1: 1208.2\ttraining's l2: 2.54609e+06\tvalid_1's rmse: 2541.76\tvalid_1's l1: 1874.34\tvalid_1's l2: 6.46056e+06\n","[600]\ttraining's rmse: 1591.39\ttraining's l1: 1205.42\ttraining's l2: 2.53253e+06\tvalid_1's rmse: 2541.58\tvalid_1's l1: 1874.83\tvalid_1's l2: 6.45961e+06\n","[610]\ttraining's rmse: 1586.06\ttraining's l1: 1201.82\ttraining's l2: 2.51558e+06\tvalid_1's rmse: 2540.3\tvalid_1's l1: 1875.46\tvalid_1's l2: 6.45314e+06\n","[620]\ttraining's rmse: 1580.41\ttraining's l1: 1198\ttraining's l2: 2.4977e+06\tvalid_1's rmse: 2537.25\tvalid_1's l1: 1874.71\tvalid_1's l2: 6.43763e+06\n","[630]\ttraining's rmse: 1573.54\ttraining's l1: 1192.47\ttraining's l2: 2.47601e+06\tvalid_1's rmse: 2533.61\tvalid_1's l1: 1873.28\tvalid_1's l2: 6.41917e+06\n","[640]\ttraining's rmse: 1570.13\ttraining's l1: 1189.95\ttraining's l2: 2.4653e+06\tvalid_1's rmse: 2531.27\tvalid_1's l1: 1872.71\tvalid_1's l2: 6.40734e+06\n","[650]\ttraining's rmse: 1565.64\ttraining's l1: 1185.96\ttraining's l2: 2.45121e+06\tvalid_1's rmse: 2530.26\tvalid_1's l1: 1872.78\tvalid_1's l2: 6.40224e+06\n","[660]\ttraining's rmse: 1560.09\ttraining's l1: 1181.17\ttraining's l2: 2.43388e+06\tvalid_1's rmse: 2529.62\tvalid_1's l1: 1874.1\tvalid_1's l2: 6.39897e+06\n","[670]\ttraining's rmse: 1555.27\ttraining's l1: 1177.08\ttraining's l2: 2.41886e+06\tvalid_1's rmse: 2530.15\tvalid_1's l1: 1875.23\tvalid_1's l2: 6.40166e+06\n","[680]\ttraining's rmse: 1552.74\ttraining's l1: 1174.87\ttraining's l2: 2.41101e+06\tvalid_1's rmse: 2531.37\tvalid_1's l1: 1876.21\tvalid_1's l2: 6.40782e+06\n","Early stopping, best iteration is:\n","[638]\ttraining's rmse: 1570.25\ttraining's l1: 1189.97\ttraining's l2: 2.46568e+06\tvalid_1's rmse: 2530.95\tvalid_1's l1: 1872.4\tvalid_1's l2: 6.40571e+06\n"]},{"output_type":"execute_result","data":{"text/plain":["LGBMRegressor(colsample_bytree=np.float64(0.6668543055695109),\n"," learning_rate=np.float64(0.038573363584388155), max_depth=5,\n"," min_child_samples=26, n_estimators=969, num_leaves=211,\n"," objective='regression', random_state=42,\n"," reg_alpha=np.float64(0.9922115592912175),\n"," reg_lambda=np.float64(0.6174815096277165),\n"," subsample=np.float64(0.8058265802441404))"],"text/html":["<style>#sk-container-id-7 {\n"," /* Definition of color scheme common for light and dark mode */\n"," --sklearn-color-text: #000;\n"," --sklearn-color-text-muted: #666;\n"," --sklearn-color-line: gray;\n"," /* Definition of color scheme for unfitted estimators */\n"," --sklearn-color-unfitted-level-0: #fff5e6;\n"," --sklearn-color-unfitted-level-1: #f6e4d2;\n"," --sklearn-color-unfitted-level-2: #ffe0b3;\n"," --sklearn-color-unfitted-level-3: chocolate;\n"," /* Definition of color scheme for fitted estimators */\n"," --sklearn-color-fitted-level-0: #f0f8ff;\n"," --sklearn-color-fitted-level-1: #d4ebff;\n"," --sklearn-color-fitted-level-2: #b3dbfd;\n"," --sklearn-color-fitted-level-3: cornflowerblue;\n","\n"," /* Specific color for light theme */\n"," --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n"," --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n"," --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n"," --sklearn-color-icon: #696969;\n","\n"," @media (prefers-color-scheme: dark) {\n"," /* Redefinition of color scheme for dark theme */\n"," --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n"," --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n"," --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n"," --sklearn-color-icon: #878787;\n"," }\n","}\n","\n","#sk-container-id-7 {\n"," color: var(--sklearn-color-text);\n","}\n","\n","#sk-container-id-7 pre {\n"," padding: 0;\n","}\n","\n","#sk-container-id-7 input.sk-hidden--visually {\n"," border: 0;\n"," clip: rect(1px 1px 1px 1px);\n"," clip: rect(1px, 1px, 1px, 1px);\n"," height: 1px;\n"," margin: -1px;\n"," overflow: hidden;\n"," padding: 0;\n"," position: absolute;\n"," width: 1px;\n","}\n","\n","#sk-container-id-7 div.sk-dashed-wrapped {\n"," border: 1px dashed var(--sklearn-color-line);\n"," margin: 0 0.4em 0.5em 0.4em;\n"," box-sizing: border-box;\n"," padding-bottom: 0.4em;\n"," background-color: var(--sklearn-color-background);\n","}\n","\n","#sk-container-id-7 div.sk-container {\n"," /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n"," but bootstrap.min.css set `[hidden] { display: none !important; }`\n"," so we also need the `!important` here to be able to override the\n"," default hidden behavior on the sphinx rendered scikit-learn.org.\n"," See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n"," display: inline-block !important;\n"," position: relative;\n","}\n","\n","#sk-container-id-7 div.sk-text-repr-fallback {\n"," display: none;\n","}\n","\n","div.sk-parallel-item,\n","div.sk-serial,\n","div.sk-item {\n"," /* draw centered vertical line to link estimators */\n"," background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n"," background-size: 2px 100%;\n"," background-repeat: no-repeat;\n"," background-position: center center;\n","}\n","\n","/* Parallel-specific style estimator block */\n","\n","#sk-container-id-7 div.sk-parallel-item::after {\n"," content: \"\";\n"," width: 100%;\n"," border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n"," flex-grow: 1;\n","}\n","\n","#sk-container-id-7 div.sk-parallel {\n"," display: flex;\n"," align-items: stretch;\n"," justify-content: center;\n"," background-color: var(--sklearn-color-background);\n"," position: relative;\n","}\n","\n","#sk-container-id-7 div.sk-parallel-item {\n"," display: flex;\n"," flex-direction: column;\n","}\n","\n","#sk-container-id-7 div.sk-parallel-item:first-child::after {\n"," align-self: flex-end;\n"," width: 50%;\n","}\n","\n","#sk-container-id-7 div.sk-parallel-item:last-child::after {\n"," align-self: flex-start;\n"," width: 50%;\n","}\n","\n","#sk-container-id-7 div.sk-parallel-item:only-child::after {\n"," width: 0;\n","}\n","\n","/* Serial-specific style estimator block */\n","\n","#sk-container-id-7 div.sk-serial {\n"," display: flex;\n"," flex-direction: column;\n"," align-items: center;\n"," background-color: var(--sklearn-color-background);\n"," padding-right: 1em;\n"," padding-left: 1em;\n","}\n","\n","\n","/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n","clickable and can be expanded/collapsed.\n","- Pipeline and ColumnTransformer use this feature and define the default style\n","- Estimators will overwrite some part of the style using the `sk-estimator` class\n","*/\n","\n","/* Pipeline and ColumnTransformer style (default) */\n","\n","#sk-container-id-7 div.sk-toggleable {\n"," /* Default theme specific background. It is overwritten whether we have a\n"," specific estimator or a Pipeline/ColumnTransformer */\n"," background-color: var(--sklearn-color-background);\n","}\n","\n","/* Toggleable label */\n","#sk-container-id-7 label.sk-toggleable__label {\n"," cursor: pointer;\n"," display: flex;\n"," width: 100%;\n"," margin-bottom: 0;\n"," padding: 0.5em;\n"," box-sizing: border-box;\n"," text-align: center;\n"," align-items: start;\n"," justify-content: space-between;\n"," gap: 0.5em;\n","}\n","\n","#sk-container-id-7 label.sk-toggleable__label .caption {\n"," font-size: 0.6rem;\n"," font-weight: lighter;\n"," color: var(--sklearn-color-text-muted);\n","}\n","\n","#sk-container-id-7 label.sk-toggleable__label-arrow:before {\n"," /* Arrow on the left of the label */\n"," content: \"β–Έ\";\n"," float: left;\n"," margin-right: 0.25em;\n"," color: var(--sklearn-color-icon);\n","}\n","\n","#sk-container-id-7 label.sk-toggleable__label-arrow:hover:before {\n"," color: var(--sklearn-color-text);\n","}\n","\n","/* Toggleable content - dropdown */\n","\n","#sk-container-id-7 div.sk-toggleable__content {\n"," max-height: 0;\n"," max-width: 0;\n"," overflow: hidden;\n"," text-align: left;\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-0);\n","}\n","\n","#sk-container-id-7 div.sk-toggleable__content.fitted {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-0);\n","}\n","\n","#sk-container-id-7 div.sk-toggleable__content pre {\n"," margin: 0.2em;\n"," border-radius: 0.25em;\n"," color: var(--sklearn-color-text);\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-0);\n","}\n","\n","#sk-container-id-7 div.sk-toggleable__content.fitted pre {\n"," /* unfitted */\n"," background-color: var(--sklearn-color-fitted-level-0);\n","}\n","\n","#sk-container-id-7 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n"," /* Expand drop-down */\n"," max-height: 200px;\n"," max-width: 100%;\n"," overflow: auto;\n","}\n","\n","#sk-container-id-7 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n"," content: \"β–Ύ\";\n","}\n","\n","/* Pipeline/ColumnTransformer-specific style */\n","\n","#sk-container-id-7 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n"," color: var(--sklearn-color-text);\n"," background-color: var(--sklearn-color-unfitted-level-2);\n","}\n","\n","#sk-container-id-7 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n"," background-color: var(--sklearn-color-fitted-level-2);\n","}\n","\n","/* Estimator-specific style */\n","\n","/* Colorize estimator box */\n","#sk-container-id-7 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-2);\n","}\n","\n","#sk-container-id-7 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-2);\n","}\n","\n","#sk-container-id-7 div.sk-label label.sk-toggleable__label,\n","#sk-container-id-7 div.sk-label label {\n"," /* The background is the default theme color */\n"," color: var(--sklearn-color-text-on-default-background);\n","}\n","\n","/* On hover, darken the color of the background */\n","#sk-container-id-7 div.sk-label:hover label.sk-toggleable__label {\n"," color: var(--sklearn-color-text);\n"," background-color: var(--sklearn-color-unfitted-level-2);\n","}\n","\n","/* Label box, darken color on hover, fitted */\n","#sk-container-id-7 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n"," color: var(--sklearn-color-text);\n"," background-color: var(--sklearn-color-fitted-level-2);\n","}\n","\n","/* Estimator label */\n","\n","#sk-container-id-7 div.sk-label label {\n"," font-family: monospace;\n"," font-weight: bold;\n"," display: inline-block;\n"," line-height: 1.2em;\n","}\n","\n","#sk-container-id-7 div.sk-label-container {\n"," text-align: center;\n","}\n","\n","/* Estimator-specific */\n","#sk-container-id-7 div.sk-estimator {\n"," font-family: monospace;\n"," border: 1px dotted var(--sklearn-color-border-box);\n"," border-radius: 0.25em;\n"," box-sizing: border-box;\n"," margin-bottom: 0.5em;\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-0);\n","}\n","\n","#sk-container-id-7 div.sk-estimator.fitted {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-0);\n","}\n","\n","/* on hover */\n","#sk-container-id-7 div.sk-estimator:hover {\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-2);\n","}\n","\n","#sk-container-id-7 div.sk-estimator.fitted:hover {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-2);\n","}\n","\n","/* Specification for estimator info (e.g. \"i\" and \"?\") */\n","\n","/* Common style for \"i\" and \"?\" */\n","\n",".sk-estimator-doc-link,\n","a:link.sk-estimator-doc-link,\n","a:visited.sk-estimator-doc-link {\n"," float: right;\n"," font-size: smaller;\n"," line-height: 1em;\n"," font-family: monospace;\n"," background-color: var(--sklearn-color-background);\n"," border-radius: 1em;\n"," height: 1em;\n"," width: 1em;\n"," text-decoration: none !important;\n"," margin-left: 0.5em;\n"," text-align: center;\n"," /* unfitted */\n"," border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n"," color: var(--sklearn-color-unfitted-level-1);\n","}\n","\n",".sk-estimator-doc-link.fitted,\n","a:link.sk-estimator-doc-link.fitted,\n","a:visited.sk-estimator-doc-link.fitted {\n"," /* fitted */\n"," border: var(--sklearn-color-fitted-level-1) 1pt solid;\n"," color: var(--sklearn-color-fitted-level-1);\n","}\n","\n","/* On hover */\n","div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",".sk-estimator-doc-link:hover,\n","div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",".sk-estimator-doc-link:hover {\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-3);\n"," color: var(--sklearn-color-background);\n"," text-decoration: none;\n","}\n","\n","div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",".sk-estimator-doc-link.fitted:hover,\n","div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",".sk-estimator-doc-link.fitted:hover {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-3);\n"," color: var(--sklearn-color-background);\n"," text-decoration: none;\n","}\n","\n","/* Span, style for the box shown on hovering the info icon */\n",".sk-estimator-doc-link span {\n"," display: none;\n"," z-index: 9999;\n"," position: relative;\n"," font-weight: normal;\n"," right: .2ex;\n"," padding: .5ex;\n"," margin: .5ex;\n"," width: min-content;\n"," min-width: 20ex;\n"," max-width: 50ex;\n"," color: var(--sklearn-color-text);\n"," box-shadow: 2pt 2pt 4pt #999;\n"," /* unfitted */\n"," background: var(--sklearn-color-unfitted-level-0);\n"," border: .5pt solid var(--sklearn-color-unfitted-level-3);\n","}\n","\n",".sk-estimator-doc-link.fitted span {\n"," /* fitted */\n"," background: var(--sklearn-color-fitted-level-0);\n"," border: var(--sklearn-color-fitted-level-3);\n","}\n","\n",".sk-estimator-doc-link:hover span {\n"," display: block;\n","}\n","\n","/* \"?\"-specific style due to the `<a>` HTML tag */\n","\n","#sk-container-id-7 a.estimator_doc_link {\n"," float: right;\n"," font-size: 1rem;\n"," line-height: 1em;\n"," font-family: monospace;\n"," background-color: var(--sklearn-color-background);\n"," border-radius: 1rem;\n"," height: 1rem;\n"," width: 1rem;\n"," text-decoration: none;\n"," /* unfitted */\n"," color: var(--sklearn-color-unfitted-level-1);\n"," border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n","}\n","\n","#sk-container-id-7 a.estimator_doc_link.fitted {\n"," /* fitted */\n"," border: var(--sklearn-color-fitted-level-1) 1pt solid;\n"," color: var(--sklearn-color-fitted-level-1);\n","}\n","\n","/* On hover */\n","#sk-container-id-7 a.estimator_doc_link:hover {\n"," /* unfitted */\n"," background-color: var(--sklearn-color-unfitted-level-3);\n"," color: var(--sklearn-color-background);\n"," text-decoration: none;\n","}\n","\n","#sk-container-id-7 a.estimator_doc_link.fitted:hover {\n"," /* fitted */\n"," background-color: var(--sklearn-color-fitted-level-3);\n","}\n","</style><div id=\"sk-container-id-7\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LGBMRegressor(colsample_bytree=np.float64(0.6668543055695109),\n"," learning_rate=np.float64(0.038573363584388155), max_depth=5,\n"," min_child_samples=26, n_estimators=969, num_leaves=211,\n"," objective=&#x27;regression&#x27;, random_state=42,\n"," reg_alpha=np.float64(0.9922115592912175),\n"," reg_lambda=np.float64(0.6174815096277165),\n"," subsample=np.float64(0.8058265802441404))</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-7\" type=\"checkbox\" checked><label for=\"sk-estimator-id-7\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>LGBMRegressor</div></div><div><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>LGBMRegressor(colsample_bytree=np.float64(0.6668543055695109),\n"," learning_rate=np.float64(0.038573363584388155), max_depth=5,\n"," min_child_samples=26, n_estimators=969, num_leaves=211,\n"," objective=&#x27;regression&#x27;, random_state=42,\n"," reg_alpha=np.float64(0.9922115592912175),\n"," reg_lambda=np.float64(0.6174815096277165),\n"," subsample=np.float64(0.8058265802441404))</pre></div> </div></div></div></div>"]},"metadata":{},"execution_count":29}]},{"cell_type":"code","source":["# 과적합 확인\n","results = model.evals_result_\n","import matplotlib.pyplot as plt\n","\n","plt.plot(results['training']['rmse'], label='Train RMSE')\n","plt.plot(results['valid_1']['rmse'], label='Valid RMSE')\n","plt.legend()\n","plt.show()\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":430},"id":"3OOW7AJAnN92","executionInfo":{"status":"ok","timestamp":1764141463009,"user_tz":-540,"elapsed":193,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"606037ad-2a2a-4aa7-e868-d8ab2902c2ed"},"execution_count":30,"outputs":[{"output_type":"display_data","data":{"text/plain":["<Figure size 640x480 with 1 Axes>"],"image/png":"iVBORw0KGgoAAAANSUhEUgAAAjkAAAGdCAYAAADwjmIIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAXHFJREFUeJzt3XecVNX9//HX9O0F2ApLEZAOUhSwJxDBjkEjBgUFJRpQicbYYokNA4mxRCUmUfT3tSdiFBREEFBciijSpCgICOwusGxvU+7vj7sz7FAXmLLl/Xw85jEz956585kbvu77e+4551oMwzAQERERaWKs0S5AREREJBwUckRERKRJUsgRERGRJkkhR0RERJokhRwRERFpkhRyREREpElSyBEREZEmSSFHREREmiR7tAuIJp/Px65du0hMTMRisUS7HBEREakHwzAoLS0lOzsbq/XI/TXNOuTs2rWLnJycaJchIiIiJ2DHjh20adPmiPubdchJTEwEzJOUlJQU5WpERESkPkpKSsjJyQn8HT+SZh1y/JeokpKSFHJEREQamWMNNdHAYxEREWmSFHJERESkSVLIERERkSapWY/JERGRxsHr9eJ2u6NdhkSIzWbDbref9PIuCjkiItKglZWV8dNPP2EYRrRLkQiKi4sjKysLp9N5wsdQyBERkQbL6/Xy008/ERcXR1pamhZubQYMw6CmpoY9e/awdetWOnfufNQF/45GIUdERBost9uNYRikpaURGxsb7XIkQmJjY3E4HGzbto2amhpiYmJO6DgaeCwiIg2eenCanxPtvQk6RgjqEBEREWlwFHJERESkSVLIERERaQTat2/P008/He0yGhWFHBERkRCyWCxHfTz88MMndNwVK1YwYcKEk6rt/PPPD9QRExPDqaeeypQpU4Km5//4449YLBZsNhs7d+4M+vzu3bsD69f8+OOPge0zZ85k0KBBJCcnk5iYSI8ePZg8eXJg/4wZMw57Lk50QHF9aXZVOHw2BcoL4Px7ISE92tWIiEgE7d69O/D67bff5sEHH2Tjxo2BbQkJCYHXhmHg9Xqx24/95zgtLS0k9d1000088sgjVFdXs2DBAiZMmEBKSgq33HJLULvWrVvz2muvce+99wa2vfrqq7Ru3Zrt27cHts2fP5+rr76axx9/nMsuuwyLxcL69euZN29e0PGSkpKCzgOEf0C5enLCYeUr8NXLUJoX7UpERJoUwzCoqPFE5VHfxQgzMzMDj+TkZCwWS+D9hg0bSExM5OOPP6Z///64XC6++OILfvjhBy6//HIyMjJISEjg9NNP59NPPw067sGXqywWC//617+44ooriIuLo3PnznzwwQfHrC8uLo7MzEzatWvHDTfcQO/evQ8JJABjx47llVdeCdr2yiuvMHbs2KBtH374IWeddRZ33XUXXbp04dRTT2XEiBE8//zzQe3qngf/IyMj45j1ngz15ISDKwnK8qG6JNqViIg0KZVuL90fnBuV717/yDDinKH5s3nPPffwl7/8hVNOOYXU1FR27NjBRRddxOOPP47L5eK1117j0ksvZePGjbRt2/aIx/nTn/7E1KlTmTZtGs899xyjR49m27ZttGjR4pg1GIbBF198wYYNG+jcufMh+y+77DKmT5/OF198wdlnn80XX3zB/v37ufTSS3n00UcD7TIzM3njjTdYu3YtPXv2PLETEibqyQmHmCTzuUohR0REDvXII4/wi1/8go4dO9KiRQv69OnDb37zG3r27Ennzp159NFH6dix4zF7Zq6//nquueYaOnXqxBNPPEFZWRnLly8/6mdeeOEFEhIScLlcnHvuufh8Pm677bZD2jkcDq699lpefvllAF5++WWuvfZaHA5HULtbb72V008/nV69etG+fXtGjRrFyy+/THV1dVC74uJiEhISgh4XXnhhfU7XCVNPTji4akOOenJEREIq1mFj/SPDovbdoTJgwICg92VlZTz88MPMnj2b3bt34/F4qKysDBr7cji9e/cOvI6PjycpKYmCgoKjfmb06NHcf//97N+/n4ceeogzzzyTM88887Btx40bx5lnnskTTzzBu+++S25uLh6PJ6hNfHw8s2fP5ocffuCzzz5j6dKl3HnnnTzzzDPk5uYSFxcHQGJiIl9//XXQZ8O9irVCTjioJ0dEJCwsFkvILhlFU3x8fND73//+98ybN4+//OUvdOrUidjYWK688kpqamqOepyDe1UsFgs+n++on0lOTqZTp04AvPPOO3Tq1IlBgwYxdOjQQ9r26tWLrl27cs0119CtWzd69uzJqlWrDnvcjh070rFjR2688Ubuv/9+Tj31VN5++21uuOEGwFzB2P+9kaLLVeEQ6Mkpjm4dIiLSKCxZsoTrr7+eK664gl69epGZ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\n"},"metadata":{}}]},{"cell_type":"code","source":["from sklearn.metrics import mean_absolute_error\n","\n","# ===============================\n","# μ„±λŠ₯ 평가\n","# ===============================\n","y_train_pred = model.predict(X_train)\n","y_valid_pred = model.predict(X_valid)\n","\n","# R2\n","r2_train = r2_score(y_train, y_train_pred)\n","r2_valid = r2_score(y_valid, y_valid_pred)\n","\n","# RMSE\n","rmse_train = np.sqrt(mean_squared_error(y_train, y_train_pred))\n","rmse_valid = np.sqrt(mean_squared_error(y_valid, y_valid_pred))\n","\n","# MAE ⭐ μΆ”κ°€!\n","mae_train = mean_absolute_error(y_train, y_train_pred)\n","mae_valid = mean_absolute_error(y_valid, y_valid_pred)\n","\n","print(f\"Train RΒ² : {r2_train:.3f}, Valid RΒ² : {r2_valid:.3f}\")\n","print(f\"Train RMSE: {rmse_train:.3f}, Valid RMSE: {rmse_valid:.3f}\")\n","print(f\"Train MAE : {mae_train:.3f}, Valid MAE: {mae_valid:.3f}\") # ⭐\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"74uJqhUdloxG","executionInfo":{"status":"ok","timestamp":1764141463251,"user_tz":-540,"elapsed":239,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"afe8007e-86be-454f-d57f-5f7791e7b3ce"},"execution_count":31,"outputs":[{"output_type":"stream","name":"stdout","text":["Train RΒ² : 0.978, Valid RΒ² : 0.950\n","Train RMSE: 1570.247, Valid RMSE: 2530.951\n","Train MAE : 1189.966, Valid MAE: 1872.400\n"]}]},{"cell_type":"code","source":["# ===============================\n","# λͺ¨λΈ μ €μž₯\n","# ===============================\n","model_path = \"LightGBM_model_2025.pkl\"\n","joblib.dump(model, model_path)\n","print(f\" λͺ¨λΈ μ €μž₯ μ™„λ£Œ: {model_path}\")\n","\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"8-UIG7OllqHe","executionInfo":{"status":"ok","timestamp":1764141463420,"user_tz":-540,"elapsed":166,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"d1bbae17-cc31-4be0-bb7f-504638c40e17"},"execution_count":32,"outputs":[{"output_type":"stream","name":"stdout","text":[" λͺ¨λΈ μ €μž₯ μ™„λ£Œ: LightGBM_model_2025.pkl\n"]}]},{"cell_type":"code","source":["# ===============================\n","# 2025λ…„ μ˜ˆμƒμˆ˜μš”λŸ‰ 예츑 ν›„ μ—‘μ…€ μ €μž₯\n","# ===============================\n","future_df = valid_df.copy()\n","future_df[\"년도\"] = 2025\n","X_future = future_df[x]\n","future_df[\"μ˜ˆμƒμˆ˜μš”λŸ‰\"] = model.predict(X_future)\n","\n","output_path = \"μ˜ˆμƒμˆ˜μš”λŸ‰_2025예츑.xlsx\"\n","future_df.to_excel(output_path, index=False)\n","print(f\" 2025λ…„ 예츑 κ²°κ³Ό μ—‘μ…€ μ €μž₯ μ™„λ£Œ: {output_path}\")"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"fLDumEI6lrUW","executionInfo":{"status":"ok","timestamp":1764141835454,"user_tz":-540,"elapsed":93,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"b066c5c1-3009-4549-b527-b869d889a35f"},"execution_count":40,"outputs":[{"output_type":"stream","name":"stdout","text":[" 2025λ…„ 예츑 κ²°κ³Ό μ—‘μ…€ μ €μž₯ μ™„λ£Œ: μ˜ˆμƒμˆ˜μš”λŸ‰_2025예츑.xlsx\n"]}]},{"cell_type":"code","source":["from google.colab import drive\n","drive.mount('/content/drive')"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"QY2tFyV71THG","executionInfo":{"status":"ok","timestamp":1764141843817,"user_tz":-540,"elapsed":2728,"user":{"displayName":"이호","userId":"08153557084945698455"}},"outputId":"b892adf0-f5ee-40d4-8c71-f8d9adda3b1d"},"execution_count":41,"outputs":[{"output_type":"stream","name":"stdout","text":["Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n"]}]},{"cell_type":"markdown","source":["# lightGBM\n","\n","* lightGBM(R) μ˜ˆμƒμˆ˜μš”λŸ‰ 2025λ…„μ˜ˆμΈ‘.xlsx 파일 μ½”λ ™ 폴더에 λ„£κΈ°\n","* ngrok_key ν—ˆμš©ν•˜κΈ°\n","\n"],"metadata":{"id":"JtZyQGKT0xxs"}},{"cell_type":"code","source":["!pip install -q streamlit\n","!pip install -q pyngrok"],"metadata":{"id":"-K5D1Bu-enr5","executionInfo":{"status":"ok","timestamp":1764141855391,"user_tz":-540,"elapsed":8616,"user":{"displayName":"이호","userId":"08153557084945698455"}}},"execution_count":42,"outputs":[]},{"cell_type":"markdown","source":["## μŠ€νŠΈλ¦Όλ°‹"],"metadata":{"id":"Xm0BiioeZ1rd"}},{"cell_type":"code","source":["%%writefile app.py\n","import streamlit as st\n","import pandas as pd\n","import altair as alt\n","\n","# ===============================\n","# 1️⃣ 데이터 뢈러였기\n","# ===============================\n","\n","past_path = '/content/2018-2024.xlsx'\n","future_path = '/content/μ˜ˆμƒμˆ˜μš”λŸ‰_2025예츑.xlsx'\n","\n","past_df = pd.read_excel(past_path)\n","future_df = pd.read_excel(future_path)\n","\n","past_df['μ›”'] = past_df['μ›”'].astype(int)\n","future_df['μ›”'] = future_df['μ›”'].astype(int)\n","\n","past_df = past_df.rename(columns={'νŒλ§€λŸ‰(kg)': 'y'})\n","future_df = future_df.rename(columns={'μ˜ˆμƒμˆ˜μš”λŸ‰': 'y'})\n","\n","past_df['y'] = past_df['y'].astype(int)\n","future_df['y'] = future_df['y'].round().astype(int)\n","\n","# ===============================\n","# 2️⃣ νŽ˜μ΄μ§€ μ„€μ • & μŠ€νƒ€μΌ\n","# ===============================\n","\n","st.set_page_config(page_title=\"과일 μˆ˜μš”λŸ‰ λŒ€μ‹œλ³΄λ“œ\", layout=\"wide\")\n","\n","st.markdown(\"\"\"\n"," <style>\n"," /* 타이틀을 더 μ•„λž˜λ‘œ λ‚΄λ €μ„œ 헀더와 κ²ΉμΉ˜μ§€ μ•Šκ²Œ */\n"," .main > div:first-child {\n"," padding-top: 50px !important;\n"," }\n"," .title {\n"," font-size: 30px;\n"," font-weight: 700;\n"," margin-top: 25px;\n"," margin-bottom: 20px;\n"," }\n"," </style>\n","\"\"\", unsafe_allow_html=True)\n","\n","# νŽ˜μ΄μ§€ 타이틀\n","st.markdown(\"<div class='title'>🍎 과일 μˆ˜μš”λŸ‰ λŒ€μ‹œλ³΄λ“œ (κ³Όκ±° + 2025 예츑)</div>\", unsafe_allow_html=True)\n","\n","# ===============================\n","# 3️⃣ 데이터 선택\n","# ===============================\n","\n","data_type = st.sidebar.radio(\"πŸ“‚ μ‚¬μš©ν•  데이터\", [\"κ³Όκ±° 데이터\", \"2025λ…„ 예츑 데이터\"])\n","selected_df = past_df if data_type == \"κ³Όκ±° 데이터\" else future_df\n","\n","# ===============================\n","# 4️⃣ 년도 선택 (2025λ…„ μ˜ˆμΈ‘μ€ μˆ¨κΉ€)\n","# ===============================\n","\n","if data_type == \"κ³Όκ±° 데이터\":\n"," available_years = sorted(selected_df['년도'].unique())\n","\n"," selected_years = st.multiselect(\n"," \"πŸ“… μ‘°νšŒν•  년도\",\n"," available_years,\n"," default=[] # κΈ°λ³Έ 선택 μ—†μŒ\n"," )\n","\n"," df_filtered = selected_df[selected_df['년도'].isin(selected_years)]\n","else:\n"," df_filtered = selected_df.copy() # 2025λ…„λ§Œ 쑴재 β†’ μžλ™ κ³ μ •\n","\n","# ===============================\n","# 5️⃣ 과일 선택 (κΈ°λ³Έ 선택 μ—†μŒ)\n","# ===============================\n","\n","fruits = sorted(df_filtered['과일쒅λ₯˜'].unique())\n","\n","selected_fruits = st.multiselect(\n"," \"🍊 ν‘œμ‹œν•  과일 선택\",\n"," fruits,\n"," default=[] # κΈ°λ³Έ 선택 μ—†μŒ\n",")\n","\n","df_chart = df_filtered[df_filtered['과일쒅λ₯˜'].isin(selected_fruits)]\n","\n","# ===============================\n","# 6️⃣ κ·Έλž˜ν”„ μ˜μ—­\n","# ===============================\n","\n","st.subheader(\"πŸ“ˆ 월별 μˆ˜μš”λŸ‰ κ·Έλž˜ν”„\")\n","\n","if len(df_chart) > 0:\n","\n"," if data_type == \"κ³Όκ±° 데이터\":\n"," years = sorted(df_chart['년도'].unique())\n"," else:\n"," years = [2025]\n","\n"," for y in years:\n"," st.markdown(f\"### πŸ“Œ {y}λ…„\")\n","\n"," df_year = df_chart[df_chart['년도'] == y]\n","\n"," chart = (\n"," alt.Chart(df_year)\n"," .mark_line(point=True)\n"," .encode(\n"," x=alt.X('μ›”:O', title='μ›”', axis=alt.Axis(labelAngle=0)),\n"," y=alt.Y('y:Q', title='μˆ˜μš”λŸ‰'),\n"," color='과일쒅λ₯˜:N',\n"," tooltip=['년도', '과일쒅λ₯˜', 'μ›”', 'y']\n"," )\n"," .properties(height=350)\n"," )\n","\n"," st.altair_chart(chart, use_container_width=True)\n","\n","else:\n"," st.info(\"κ·Έλž˜ν”„μ— ν‘œμ‹œν•  과일을 μ„ νƒν•˜μ„Έμš”.\")\n","\n","# ===============================\n","# 7️⃣ ν…Œμ΄λΈ” μ˜μ—­\n","# ===============================\n","\n","st.subheader(\"πŸ“Š 상세 데이터\")\n","\n","selected_fruits_table = st.multiselect(\n"," \"πŸ“‹ ν…Œμ΄λΈ” ν‘œμ‹œ 과일\",\n"," fruits,\n"," default=[]\n",")\n","\n","df_table = df_filtered[df_filtered['과일쒅λ₯˜'].isin(selected_fruits_table)]\n","\n","if len(df_table) > 0:\n"," df_show = df_table[['년도', 'μ›”', '과일쒅λ₯˜', 'y']].rename(columns={'y': 'μˆ˜μš”λŸ‰'})\n"," st.dataframe(df_show, use_container_width=True)\n","else:\n"," st.info(\"ν…Œμ΄λΈ”μ— ν‘œμ‹œν•  과일을 μ„ νƒν•˜μ„Έμš”.\")\n"],"metadata":{"id":"RQ_UPIpt0RnQ","executionInfo":{"status":"ok","timestamp":1764141858637,"user_tz":-540,"elapsed":36,"user":{"displayName":"이호","userId":"08153557084945698455"}},"colab":{"base_uri":"https://localhost:8080/"},"outputId":"0dcbe25c-17fc-475b-e4da-1dd3043ca47f"},"execution_count":43,"outputs":[{"output_type":"stream","name":"stdout","text":["Writing app.py\n"]}]},{"cell_type":"code","source":["!streamlit run app.py &> /dev/null &"],"metadata":{"id":"7oexQzyIev2f","executionInfo":{"status":"ok","timestamp":1764141859866,"user_tz":-540,"elapsed":109,"user":{"displayName":"이호","userId":"08153557084945698455"}}},"execution_count":44,"outputs":[]},{"cell_type":"code","source":["from google.colab import userdata\n","\n","# ngrok.com 인증 토큰 μ‚¬μš©\n","NGROK_AUTH_TOKEN = userdata.get('ngrok_key')"],"metadata":{"id":"c2evQp4Fez3g","executionInfo":{"status":"ok","timestamp":1764141861584,"user_tz":-540,"elapsed":1214,"user":{"displayName":"이호","userId":"08153557084945698455"}}},"execution_count":45,"outputs":[]},{"cell_type":"code","source":["from pyngrok import ngrok\n","\n","# 인증 ν† ν°μœΌλ‘œ ngrok ꡬ성\n","ngrok.set_auth_token(NGROK_AUTH_TOKEN)\n","\n","# Streamlit 포트\n","port = 8501\n","\n","# ngrok 터널 μ—΄κΈ°\n","public_url = ngrok.connect(port)\n","print(f\"Streamlit 앱에 μ ‘μ†ν•˜λ €λ©΄ λ‹€μŒ URL을 ν΄λ¦­ν•˜μ„Έμš”: {public_url}\")"],"metadata":{"id":"igDTBvVrez5_","executionInfo":{"status":"ok","timestamp":1764141861932,"user_tz":-540,"elapsed":343,"user":{"displayName":"이호","userId":"08153557084945698455"}},"colab":{"base_uri":"https://localhost:8080/"},"outputId":"86cdae71-5b59-4545-a791-34f6cd2666ed"},"execution_count":46,"outputs":[{"output_type":"stream","name":"stdout","text":["Streamlit 앱에 μ ‘μ†ν•˜λ €λ©΄ λ‹€μŒ URL을 ν΄λ¦­ν•˜μ„Έμš”: NgrokTunnel: \"https://kadence-prewilling-scintillatingly.ngrok-free.dev\" -> \"http://localhost:8501\"\n"]}]}]}