test: 扩展12特征非线性日期编码对比

This commit is contained in:
luochen570
2026-06-08 23:48:18 +08:00
parent 2d3d36b47c
commit 284c0e9a3f
2 changed files with 199 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
from pathlib import Path
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import ExtraTreesRegressor, GradientBoostingRegressor, HistGradientBoostingRegressor, RandomForestRegressor
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.svm import SVR
BASE_DIR = Path(__file__).resolve().parent
DATA_PATH = Path('/root/.hermes-web-ui/upload/default/28752a235eb6ef9d.xlsx')
OUT_DIR = BASE_DIR / 'outputs' / 'time_split_experiment'
OUT_DIR.mkdir(parents=True, exist_ok=True)
TARGET = '总骑行量'
BASE_FEATURES = ['', '季节', '', '节假日', '星期', '工作日', '天气', '气温', '体感温度', '湿度', '风速']
BASE_CAT = ['', '季节', '', '节假日', '星期', '工作日', '天气']
def rmse(y_true, y_pred):
return float(np.sqrt(mean_squared_error(y_true, y_pred)))
def add_features(df, min_date):
df = df.copy()
df['日期数值'] = (df['日期'] - min_date).dt.days
df['一年中的第几天'] = df['日期'].dt.dayofyear
df['月内日'] = df['日期'].dt.day
df['周序号'] = df['日期'].dt.isocalendar().week.astype(int)
df['日期_sin'] = np.sin(2 * np.pi * df['一年中的第几天'] / 365.25)
df['日期_cos'] = np.cos(2 * np.pi * df['一年中的第几天'] / 365.25)
df['周序号_sin'] = np.sin(2 * np.pi * df['周序号'] / 52.18)
df['月内日_sin'] = np.sin(2 * np.pi * df['月内日'] / 31)
df['年内进度'] = df['一年中的第几天'] / 365.25
df['季度内月份'] = ((df[''] - 1) % 3) + 1
df['是否月初'] = (df['月内日'] <= 7).astype(int)
df['是否月末'] = (df['月内日'] >= 24).astype(int)
df['日期分箱4'] = pd.qcut(df['日期数值'], q=4, labels=False, duplicates='drop').astype(int)
df['日期分箱8'] = pd.qcut(df['日期数值'], q=8, labels=False, duplicates='drop').astype(int)
return df
def make_pipeline(model_name, estimator, features, categorical):
numeric = [col for col in features if col not in categorical]
need_scale = model_name == 'SVR'
preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(handle_unknown='ignore', sparse_output=False), categorical),
('num', StandardScaler() if need_scale else 'passthrough', numeric),
],
verbose_feature_names_out=False,
)
return Pipeline([('preprocess', preprocessor), ('model', estimator)])
def main():
daily = pd.read_excel(DATA_PATH, sheet_name='每天数据')
future = pd.read_excel(DATA_PATH, sheet_name='预测集')
daily['日期'] = pd.to_datetime(daily['日期'])
future['日期'] = pd.to_datetime(future['日期'])
daily = daily.sort_values('日期').reset_index(drop=True)
future = future.sort_values('日期').reset_index(drop=True)
min_date = daily['日期'].min()
daily = add_features(daily, min_date)
future = add_features(future, min_date)
split_idx = int(len(daily) * 0.8)
train = daily.iloc[:split_idx].copy()
test = daily.iloc[split_idx:].copy()
feature_schemes = {
'12_日期数值': (['日期数值'] + BASE_FEATURES, BASE_CAT),
'12_日期sin': (['日期_sin'] + BASE_FEATURES, BASE_CAT),
'12_日期cos': (['日期_cos'] + BASE_FEATURES, BASE_CAT),
'12_年内第几天': (['一年中的第几天'] + BASE_FEATURES, BASE_CAT),
'12_年内进度': (['年内进度'] + BASE_FEATURES, BASE_CAT),
'12_周序号': (['周序号'] + BASE_FEATURES, BASE_CAT + ['周序号']),
'12_周序号sin': (['周序号_sin'] + BASE_FEATURES, BASE_CAT),
'12_月内日': (['月内日'] + BASE_FEATURES, BASE_CAT + ['月内日']),
'12_月内日sin': (['月内日_sin'] + BASE_FEATURES, BASE_CAT),
'12_季度内月份': (['季度内月份'] + BASE_FEATURES, BASE_CAT + ['季度内月份']),
'12_是否月初': (['是否月初'] + BASE_FEATURES, BASE_CAT + ['是否月初']),
'12_是否月末': (['是否月末'] + BASE_FEATURES, BASE_CAT + ['是否月末']),
'12_日期分箱4': (['日期分箱4'] + BASE_FEATURES, BASE_CAT + ['日期分箱4']),
'12_日期分箱8': (['日期分箱8'] + BASE_FEATURES, BASE_CAT + ['日期分箱8']),
}
models = {
'梯度提升树': lambda: GradientBoostingRegressor(random_state=42, n_estimators=300, learning_rate=0.05, max_depth=3),
'随机森林': lambda: RandomForestRegressor(n_estimators=500, random_state=42, min_samples_leaf=2, n_jobs=-1),
'极端随机树': lambda: ExtraTreesRegressor(n_estimators=500, random_state=42, min_samples_leaf=2, n_jobs=-1),
'HistGBDT': lambda: HistGradientBoostingRegressor(random_state=42, max_iter=300, learning_rate=0.05, max_leaf_nodes=31),
'SVR': lambda: SVR(C=200, gamma='scale', epsilon=50),
}
rows = []
for scheme_name, (features, categorical) in feature_schemes.items():
for model_name, factory in models.items():
pipe = make_pipeline(model_name, factory(), features, categorical)
pipe.fit(train[features], train[TARGET])
pred = pipe.predict(test[features])
future_pred = np.maximum(np.round(pipe.predict(future[features])), 0).astype(int)
rows.append({
'方案': scheme_name,
'模型': model_name,
'RMSE': rmse(test[TARGET], pred),
'MAE': float(mean_absolute_error(test[TARGET], pred)),
'R2': float(r2_score(test[TARGET], pred)),
'未来预测最小值': int(future_pred.min()),
'未来预测最大值': int(future_pred.max()),
'未来预测均值': float(future_pred.mean()),
})
result = pd.DataFrame(rows)
result.to_csv(OUT_DIR / 'extended_12_feature_nonlinear_comparison.csv', index=False, encoding='utf-8-sig')
print('各模型最佳前5')
for model_name, group in result.groupby('模型'):
print('\n[' + model_name + ']')
print(group.sort_values('RMSE').head(5).to_string(index=False, float_format=lambda x: f'{x:.3f}'))
print('\n总体前15')
print(result.sort_values('RMSE').head(15).to_string(index=False, float_format=lambda x: f'{x:.3f}'))
print('\n保存:', OUT_DIR / 'extended_12_feature_nonlinear_comparison.csv')
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,71 @@
方案,模型,RMSE,MAE,R2,未来预测最小值,未来预测最大值,未来预测均值
12_日期数值,梯度提升树,1115.505147894367,754.6104141829828,0.6459076101057781,3884,8023,6177.22
12_日期数值,随机森林,1211.6404640631436,857.2259950393145,0.5822456578217434,3778,7634,5700.92
12_日期数值,极端随机树,1016.4235733532818,804.2402630385485,0.7060165426206524,2681,6504,4381.72
12_日期数值,HistGBDT,1081.1379394711937,734.543109383189,0.667389732676323,3657,8062,5775.15
12_日期数值,SVR,1302.8065606379432,1122.631254189851,0.517015371360585,3203,5408,4553.72
12_日期sin,梯度提升树,1037.9787565353552,864.907988042832,0.6934153789548839,1752,6174,3687.28
12_日期sin,随机森林,1300.1505289996633,1061.3027606571065,0.5189826853858082,1966,5800,3536.75
12_日期sin,极端随机树,1019.3127219314714,823.7222013605436,0.7043428918888557,1914,5888,3584.54
12_日期sin,HistGBDT,1065.2572354517981,863.3337389503802,0.6770893113579488,2111,7633,4194.25
12_日期sin,SVR,1514.2320642644604,1364.971543352133,0.3475333594320331,1813,4998,3673.18
12_日期cos,梯度提升树,1102.1009812913542,934.5573526964807,0.654366194091462,1451,6394,3750.99
12_日期cos,随机森林,1349.2073040509797,1168.881334404296,0.4819987561114465,1960,5927,3613.88
12_日期cos,极端随机树,1167.5748397557088,989.3852519274374,0.6120793570853851,1898,5622,3508.44
12_日期cos,HistGBDT,1207.8821487389928,1031.8720725902147,0.5848332530139425,1864,7623,4161.42
12_日期cos,SVR,1266.5629805240928,1123.6204857013158,0.5435144697239268,1868,5162,3719.4
12_年内第几天,梯度提升树,910.5720267585195,741.091899857133,0.7640597451116528,1626,6348,3648.54
12_年内第几天,随机森林,1125.0275082985734,915.0238153129942,0.6398364829590523,1971,5152,3349.19
12_年内第几天,极端随机树,1010.022890809697,801.2023117913834,0.7097074645417395,1906,5624,3509.47
12_年内第几天,HistGBDT,1015.9546264325356,824.2028863511464,0.7062877500933793,1971,7453,4134.83
12_年内第几天,SVR,1408.7450455752507,1271.6382669589445,0.4352734075175475,1913,4987,3632.62
12_年内进度,梯度提升树,910.5720267585195,741.091899857133,0.7640597451116528,1626,6348,3648.54
12_年内进度,随机森林,1125.0275082985734,915.0238153129942,0.6398364829590523,1971,5152,3349.41
12_年内进度,极端随机树,1010.0228908096968,801.2023117913834,0.7097074645417396,1906,5624,3509.47
12_年内进度,HistGBDT,1015.9546264325356,824.2028863511464,0.7062877500933793,1971,7453,4134.83
12_年内进度,SVR,1408.7450455752507,1271.6382669589445,0.4352734075175476,1913,4987,3632.62
12_周序号,梯度提升树,1069.803614918048,903.2622617081902,0.6743271479086517,2006,6530,3973.86
12_周序号,随机森林,1243.5446976109674,1041.5134963439052,0.5599558665365664,1983,6140,3651.16
12_周序号,极端随机树,1035.7721993969274,826.6126054421767,0.694717481574221,1964,5895,3568.12
12_周序号,HistGBDT,1112.59713175554,920.3983467960975,0.6477513742747558,1935,7559,4098.05
12_周序号,SVR,1292.2405499799693,1150.5398648996525,0.5248177985800409,1860,5149,3786.9
12_周序号sin,梯度提升树,1063.281232768076,882.1390025824226,0.6782861689221613,1934,6414,3830.73
12_周序号sin,随机森林,1292.9475995090163,1061.5729066667654,0.524297664357741,1983,5483,3536.65
12_周序号sin,极端随机树,1014.1497745380785,816.5771680272105,0.7073303876817728,1887,5788,3534.99
12_周序号sin,HistGBDT,1102.938167765176,893.2039949691602,0.6538408885976152,2032,7599,4183.36
12_周序号sin,SVR,1503.9741029680147,1354.4278894326096,0.35634351127843267,1807,5003,3670.59
12_月内日,梯度提升树,1075.2787348073598,910.5418237040739,0.6709851125668345,1823,6745,4072.24
12_月内日,随机森林,1243.6349732406059,1038.4677767446087,0.5598919738542543,1942,6236,3665.28
12_月内日,极端随机树,1022.4506637906521,825.6662979591832,0.7025197362733295,1971,5942,3609.59
12_月内日,HistGBDT,1098.717892872152,907.8006929324015,0.6564849019907664,1965,7569,4085.0
12_月内日,SVR,1295.0430615629316,1151.4692010654137,0.522754486650163,1842,5183,3805.16
12_月内日sin,梯度提升树,1067.22297417614,906.8146759377944,0.6758964657440301,1878,6598,3910.3
12_月内日sin,随机森林,1242.2027167294766,1044.5619603560458,0.5609051081316705,1972,6006,3668.2
12_月内日sin,极端随机树,995.1317369549822,783.5088700680266,0.7182041522270597,1885,5868,3581.37
12_月内日sin,HistGBDT,1105.813282654649,918.9424734351023,0.6520338164721056,1821,7375,4119.0
12_月内日sin,SVR,1294.6875882479544,1143.1041218806386,0.5230164466831182,1735,5223,3787.08
12_季度内月份,梯度提升树,1030.8840120603018,873.0194697266488,0.6975921616220541,1949,6684,3925.74
12_季度内月份,随机森林,1253.0127757589096,1049.3735973230855,0.5532295571774203,1912,6205,3643.17
12_季度内月份,极端随机树,1022.5707998779073,823.3960331065751,0.7024498253900622,1963,6010,3627.72
12_季度内月份,HistGBDT,1104.0353223349737,907.1740751082931,0.6531518582216439,2021,7502,4113.82
12_季度内月份,SVR,1279.4999059696324,1136.644561330494,0.5341415772015901,1813,5170,3795.71
12_是否月初,梯度提升树,1074.707109174901,911.4478533502376,0.6713348327770166,2009,6741,4032.85
12_是否月初,随机森林,1251.1986686370237,1047.3387084749343,0.5545222857849463,1996,6222,3699.8
12_是否月初,极端随机树,1004.7715101011122,798.0876673469379,0.7127182352012016,1952,5982,3692.01
12_是否月初,HistGBDT,1090.5958037531236,900.8674504846922,0.6615448864141861,2005,7533,4136.36
12_是否月初,SVR,1266.2996781493812,1123.4419542652251,0.5437042450965154,1820,5174,3796.87
12_是否月末,梯度提升树,1051.1491771051826,889.5436406255417,0.6855858052834116,1934,6997,4023.66
12_是否月末,随机森林,1252.4058220639308,1048.5324678294116,0.553662279492491,2037,6112,3700.39
12_是否月末,极端随机树,1023.9819170179634,821.4061183673467,0.7016280380651778,1955,5912,3665.4
12_是否月末,HistGBDT,1099.3134078227854,912.4381059898651,0.6561124245479075,1990,7477,4095.89
12_是否月末,SVR,1266.3037333555528,1118.853560743366,0.5437013226029602,1840,5168,3791.36
12_日期分箱4,梯度提升树,1159.7677465407507,959.746334523742,0.6172497448666919,1082,6711,3760.55
12_日期分箱4,随机森林,1354.8648153138981,1127.6347175619164,0.4776454707850357,1242,6317,3767.98
12_日期分箱4,极端随机树,1045.4835916765785,878.4472097505668,0.6889659912708692,1464,5909,3542.3
12_日期分箱4,HistGBDT,1081.9800025011405,878.4483264538926,0.6668714123558845,1264,7770,4128.71
12_日期分箱4,SVR,1416.8450442399799,1279.3344630153172,0.4287606105220405,1600,5424,3788.31
12_日期分箱8,梯度提升树,1132.6317366268574,943.8527579349204,0.6349512308901111,1356,6726,4009.71
12_日期分箱8,随机森林,1303.8402293998106,1094.8299032973075,0.516248650968877,1246,6253,3806.88
12_日期分箱8,极端随机树,1386.534777125338,1147.028979138322,0.4529399894883904,1012,6887,3894.88
12_日期分箱8,HistGBDT,1039.4639834179268,842.3983219405343,0.6925373773716995,1388,7779,4362.77
12_日期分箱8,SVR,1366.5766542260164,1225.520011226714,0.4685756746775356,1775,5362,3841.55
1 方案 模型 RMSE MAE R2 未来预测最小值 未来预测最大值 未来预测均值
2 12_日期数值 梯度提升树 1115.505147894367 754.6104141829828 0.6459076101057781 3884 8023 6177.22
3 12_日期数值 随机森林 1211.6404640631436 857.2259950393145 0.5822456578217434 3778 7634 5700.92
4 12_日期数值 极端随机树 1016.4235733532818 804.2402630385485 0.7060165426206524 2681 6504 4381.72
5 12_日期数值 HistGBDT 1081.1379394711937 734.543109383189 0.667389732676323 3657 8062 5775.15
6 12_日期数值 SVR 1302.8065606379432 1122.631254189851 0.517015371360585 3203 5408 4553.72
7 12_日期sin 梯度提升树 1037.9787565353552 864.907988042832 0.6934153789548839 1752 6174 3687.28
8 12_日期sin 随机森林 1300.1505289996633 1061.3027606571065 0.5189826853858082 1966 5800 3536.75
9 12_日期sin 极端随机树 1019.3127219314714 823.7222013605436 0.7043428918888557 1914 5888 3584.54
10 12_日期sin HistGBDT 1065.2572354517981 863.3337389503802 0.6770893113579488 2111 7633 4194.25
11 12_日期sin SVR 1514.2320642644604 1364.971543352133 0.3475333594320331 1813 4998 3673.18
12 12_日期cos 梯度提升树 1102.1009812913542 934.5573526964807 0.654366194091462 1451 6394 3750.99
13 12_日期cos 随机森林 1349.2073040509797 1168.881334404296 0.4819987561114465 1960 5927 3613.88
14 12_日期cos 极端随机树 1167.5748397557088 989.3852519274374 0.6120793570853851 1898 5622 3508.44
15 12_日期cos HistGBDT 1207.8821487389928 1031.8720725902147 0.5848332530139425 1864 7623 4161.42
16 12_日期cos SVR 1266.5629805240928 1123.6204857013158 0.5435144697239268 1868 5162 3719.4
17 12_年内第几天 梯度提升树 910.5720267585195 741.091899857133 0.7640597451116528 1626 6348 3648.54
18 12_年内第几天 随机森林 1125.0275082985734 915.0238153129942 0.6398364829590523 1971 5152 3349.19
19 12_年内第几天 极端随机树 1010.022890809697 801.2023117913834 0.7097074645417395 1906 5624 3509.47
20 12_年内第几天 HistGBDT 1015.9546264325356 824.2028863511464 0.7062877500933793 1971 7453 4134.83
21 12_年内第几天 SVR 1408.7450455752507 1271.6382669589445 0.4352734075175475 1913 4987 3632.62
22 12_年内进度 梯度提升树 910.5720267585195 741.091899857133 0.7640597451116528 1626 6348 3648.54
23 12_年内进度 随机森林 1125.0275082985734 915.0238153129942 0.6398364829590523 1971 5152 3349.41
24 12_年内进度 极端随机树 1010.0228908096968 801.2023117913834 0.7097074645417396 1906 5624 3509.47
25 12_年内进度 HistGBDT 1015.9546264325356 824.2028863511464 0.7062877500933793 1971 7453 4134.83
26 12_年内进度 SVR 1408.7450455752507 1271.6382669589445 0.4352734075175476 1913 4987 3632.62
27 12_周序号 梯度提升树 1069.803614918048 903.2622617081902 0.6743271479086517 2006 6530 3973.86
28 12_周序号 随机森林 1243.5446976109674 1041.5134963439052 0.5599558665365664 1983 6140 3651.16
29 12_周序号 极端随机树 1035.7721993969274 826.6126054421767 0.694717481574221 1964 5895 3568.12
30 12_周序号 HistGBDT 1112.59713175554 920.3983467960975 0.6477513742747558 1935 7559 4098.05
31 12_周序号 SVR 1292.2405499799693 1150.5398648996525 0.5248177985800409 1860 5149 3786.9
32 12_周序号sin 梯度提升树 1063.281232768076 882.1390025824226 0.6782861689221613 1934 6414 3830.73
33 12_周序号sin 随机森林 1292.9475995090163 1061.5729066667654 0.524297664357741 1983 5483 3536.65
34 12_周序号sin 极端随机树 1014.1497745380785 816.5771680272105 0.7073303876817728 1887 5788 3534.99
35 12_周序号sin HistGBDT 1102.938167765176 893.2039949691602 0.6538408885976152 2032 7599 4183.36
36 12_周序号sin SVR 1503.9741029680147 1354.4278894326096 0.35634351127843267 1807 5003 3670.59
37 12_月内日 梯度提升树 1075.2787348073598 910.5418237040739 0.6709851125668345 1823 6745 4072.24
38 12_月内日 随机森林 1243.6349732406059 1038.4677767446087 0.5598919738542543 1942 6236 3665.28
39 12_月内日 极端随机树 1022.4506637906521 825.6662979591832 0.7025197362733295 1971 5942 3609.59
40 12_月内日 HistGBDT 1098.717892872152 907.8006929324015 0.6564849019907664 1965 7569 4085.0
41 12_月内日 SVR 1295.0430615629316 1151.4692010654137 0.522754486650163 1842 5183 3805.16
42 12_月内日sin 梯度提升树 1067.22297417614 906.8146759377944 0.6758964657440301 1878 6598 3910.3
43 12_月内日sin 随机森林 1242.2027167294766 1044.5619603560458 0.5609051081316705 1972 6006 3668.2
44 12_月内日sin 极端随机树 995.1317369549822 783.5088700680266 0.7182041522270597 1885 5868 3581.37
45 12_月内日sin HistGBDT 1105.813282654649 918.9424734351023 0.6520338164721056 1821 7375 4119.0
46 12_月内日sin SVR 1294.6875882479544 1143.1041218806386 0.5230164466831182 1735 5223 3787.08
47 12_季度内月份 梯度提升树 1030.8840120603018 873.0194697266488 0.6975921616220541 1949 6684 3925.74
48 12_季度内月份 随机森林 1253.0127757589096 1049.3735973230855 0.5532295571774203 1912 6205 3643.17
49 12_季度内月份 极端随机树 1022.5707998779073 823.3960331065751 0.7024498253900622 1963 6010 3627.72
50 12_季度内月份 HistGBDT 1104.0353223349737 907.1740751082931 0.6531518582216439 2021 7502 4113.82
51 12_季度内月份 SVR 1279.4999059696324 1136.644561330494 0.5341415772015901 1813 5170 3795.71
52 12_是否月初 梯度提升树 1074.707109174901 911.4478533502376 0.6713348327770166 2009 6741 4032.85
53 12_是否月初 随机森林 1251.1986686370237 1047.3387084749343 0.5545222857849463 1996 6222 3699.8
54 12_是否月初 极端随机树 1004.7715101011122 798.0876673469379 0.7127182352012016 1952 5982 3692.01
55 12_是否月初 HistGBDT 1090.5958037531236 900.8674504846922 0.6615448864141861 2005 7533 4136.36
56 12_是否月初 SVR 1266.2996781493812 1123.4419542652251 0.5437042450965154 1820 5174 3796.87
57 12_是否月末 梯度提升树 1051.1491771051826 889.5436406255417 0.6855858052834116 1934 6997 4023.66
58 12_是否月末 随机森林 1252.4058220639308 1048.5324678294116 0.553662279492491 2037 6112 3700.39
59 12_是否月末 极端随机树 1023.9819170179634 821.4061183673467 0.7016280380651778 1955 5912 3665.4
60 12_是否月末 HistGBDT 1099.3134078227854 912.4381059898651 0.6561124245479075 1990 7477 4095.89
61 12_是否月末 SVR 1266.3037333555528 1118.853560743366 0.5437013226029602 1840 5168 3791.36
62 12_日期分箱4 梯度提升树 1159.7677465407507 959.746334523742 0.6172497448666919 1082 6711 3760.55
63 12_日期分箱4 随机森林 1354.8648153138981 1127.6347175619164 0.4776454707850357 1242 6317 3767.98
64 12_日期分箱4 极端随机树 1045.4835916765785 878.4472097505668 0.6889659912708692 1464 5909 3542.3
65 12_日期分箱4 HistGBDT 1081.9800025011405 878.4483264538926 0.6668714123558845 1264 7770 4128.71
66 12_日期分箱4 SVR 1416.8450442399799 1279.3344630153172 0.4287606105220405 1600 5424 3788.31
67 12_日期分箱8 梯度提升树 1132.6317366268574 943.8527579349204 0.6349512308901111 1356 6726 4009.71
68 12_日期分箱8 随机森林 1303.8402293998106 1094.8299032973075 0.516248650968877 1246 6253 3806.88
69 12_日期分箱8 极端随机树 1386.534777125338 1147.028979138322 0.4529399894883904 1012 6887 3894.88
70 12_日期分箱8 HistGBDT 1039.4639834179268 842.3983219405343 0.6925373773716995 1388 7779 4362.77
71 12_日期分箱8 SVR 1366.5766542260164 1225.520011226714 0.4685756746775356 1775 5362 3841.55