tabpfn-time-series 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tabpfn_time_series/__init__.py +3 -1
- tabpfn_time_series/defaults.py +6 -4
- tabpfn_time_series/predictor.py +9 -8
- tabpfn_time_series/tabpfn_worker.py +132 -97
- {tabpfn_time_series-0.1.1.dist-info → tabpfn_time_series-0.1.3.dist-info}/METADATA +25 -9
- tabpfn_time_series-0.1.3.dist-info/RECORD +11 -0
- tabpfn_time_series-0.1.1.dist-info/RECORD +0 -11
- {tabpfn_time_series-0.1.1.dist-info → tabpfn_time_series-0.1.3.dist-info}/WHEEL +0 -0
- {tabpfn_time_series-0.1.1.dist-info → tabpfn_time_series-0.1.3.dist-info}/licenses/LICENSE.txt +0 -0
tabpfn_time_series/__init__.py
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
from .feature import DefaultFeatures, FeatureTransformer
|
2
2
|
from .predictor import TabPFNTimeSeriesPredictor, TabPFNMode
|
3
|
+
from .defaults import TABPFN_TS_DEFAULT_QUANTILE_CONFIG
|
3
4
|
|
4
5
|
__version__ = "0.1.0"
|
5
6
|
|
6
7
|
__all__ = [
|
7
8
|
"DefaultFeatures",
|
8
|
-
"FeatureTransformer",
|
9
|
+
"FeatureTransformer",
|
9
10
|
"TabPFNTimeSeriesPredictor",
|
10
11
|
"TabPFNMode",
|
12
|
+
"TABPFN_TS_DEFAULT_QUANTILE_CONFIG",
|
11
13
|
]
|
tabpfn_time_series/defaults.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
"
|
4
|
-
|
1
|
+
TABPFN_TS_DEFAULT_QUANTILE_CONFIG = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
|
2
|
+
TABPFN_TS_DEFAULT_CONFIG = {
|
3
|
+
"tabpfn_internal": {
|
4
|
+
"model_path": "2noar4o2",
|
5
|
+
},
|
6
|
+
"tabpfn_output_selection": "median", # mean or median
|
5
7
|
}
|
tabpfn_time_series/predictor.py
CHANGED
@@ -3,8 +3,8 @@ from enum import Enum
|
|
3
3
|
|
4
4
|
from autogluon.timeseries import TimeSeriesDataFrame
|
5
5
|
|
6
|
-
from tabpfn_time_series.tabpfn_worker import TabPFNClient, LocalTabPFN
|
7
|
-
from tabpfn_time_series.defaults import
|
6
|
+
from tabpfn_time_series.tabpfn_worker import TabPFNClient, LocalTabPFN, MockTabPFN
|
7
|
+
from tabpfn_time_series.defaults import TABPFN_TS_DEFAULT_CONFIG
|
8
8
|
|
9
9
|
logger = logging.getLogger(__name__)
|
10
10
|
|
@@ -12,6 +12,7 @@ logger = logging.getLogger(__name__)
|
|
12
12
|
class TabPFNMode(Enum):
|
13
13
|
LOCAL = "tabpfn-local"
|
14
14
|
CLIENT = "tabpfn-client"
|
15
|
+
MOCK = "tabpfn-mock"
|
15
16
|
|
16
17
|
|
17
18
|
class TabPFNTimeSeriesPredictor:
|
@@ -22,11 +23,12 @@ class TabPFNTimeSeriesPredictor:
|
|
22
23
|
def __init__(
|
23
24
|
self,
|
24
25
|
tabpfn_mode: TabPFNMode = TabPFNMode.CLIENT,
|
25
|
-
|
26
|
+
config: dict = TABPFN_TS_DEFAULT_CONFIG,
|
26
27
|
) -> None:
|
27
28
|
worker_mapping = {
|
28
|
-
TabPFNMode.CLIENT: lambda: TabPFNClient(
|
29
|
-
TabPFNMode.LOCAL: lambda: LocalTabPFN(
|
29
|
+
TabPFNMode.CLIENT: lambda: TabPFNClient(config),
|
30
|
+
TabPFNMode.LOCAL: lambda: LocalTabPFN(config),
|
31
|
+
TabPFNMode.MOCK: lambda: MockTabPFN(config),
|
30
32
|
}
|
31
33
|
self.tabpfn_worker = worker_mapping[tabpfn_mode]()
|
32
34
|
|
@@ -34,14 +36,13 @@ class TabPFNTimeSeriesPredictor:
|
|
34
36
|
self,
|
35
37
|
train_tsdf: TimeSeriesDataFrame, # with features and target
|
36
38
|
test_tsdf: TimeSeriesDataFrame, # with features only
|
37
|
-
quantile_config: list[float] = TABPFN_DEFAULT_QUANTILE_CONFIG,
|
38
39
|
) -> TimeSeriesDataFrame:
|
39
40
|
"""
|
40
41
|
Predict on each time series individually (local forecasting).
|
41
42
|
"""
|
42
43
|
|
43
44
|
logger.info(
|
44
|
-
f"Predicting {len(train_tsdf.item_ids)} time series with config{self.tabpfn_worker.
|
45
|
+
f"Predicting {len(train_tsdf.item_ids)} time series with config{self.tabpfn_worker.config}"
|
45
46
|
)
|
46
47
|
|
47
|
-
return self.tabpfn_worker.predict(train_tsdf, test_tsdf
|
48
|
+
return self.tabpfn_worker.predict(train_tsdf, test_tsdf)
|
@@ -2,13 +2,15 @@ import logging
|
|
2
2
|
from abc import ABC, abstractmethod
|
3
3
|
from joblib import Parallel, delayed
|
4
4
|
|
5
|
+
from tqdm import tqdm
|
5
6
|
import pandas as pd
|
6
7
|
import numpy as np
|
8
|
+
import torch
|
7
9
|
from scipy.stats import norm
|
8
10
|
from autogluon.timeseries import TimeSeriesDataFrame
|
9
11
|
|
10
12
|
from tabpfn_time_series.data_preparation import split_time_series_to_X_y
|
11
|
-
from tabpfn_time_series.defaults import
|
13
|
+
from tabpfn_time_series.defaults import TABPFN_TS_DEFAULT_QUANTILE_CONFIG
|
12
14
|
|
13
15
|
logger = logging.getLogger(__name__)
|
14
16
|
|
@@ -16,17 +18,16 @@ logger = logging.getLogger(__name__)
|
|
16
18
|
class TabPFNWorker(ABC):
|
17
19
|
def __init__(
|
18
20
|
self,
|
19
|
-
|
21
|
+
config: dict = {},
|
20
22
|
num_workers: int = 1,
|
21
23
|
):
|
22
|
-
self.
|
24
|
+
self.config = config
|
23
25
|
self.num_workers = num_workers
|
24
26
|
|
25
27
|
def predict(
|
26
28
|
self,
|
27
29
|
train_tsdf: TimeSeriesDataFrame,
|
28
30
|
test_tsdf: TimeSeriesDataFrame,
|
29
|
-
quantile_config: list[float],
|
30
31
|
):
|
31
32
|
predictions = Parallel(
|
32
33
|
n_jobs=self.num_workers,
|
@@ -36,9 +37,8 @@ class TabPFNWorker(ABC):
|
|
36
37
|
item_id,
|
37
38
|
train_tsdf.loc[item_id],
|
38
39
|
test_tsdf.loc[item_id],
|
39
|
-
quantile_config,
|
40
40
|
)
|
41
|
-
for item_id in train_tsdf.item_ids
|
41
|
+
for item_id in tqdm(train_tsdf.item_ids, desc="Predicting time series")
|
42
42
|
)
|
43
43
|
|
44
44
|
predictions = pd.concat(predictions)
|
@@ -53,8 +53,9 @@ class TabPFNWorker(ABC):
|
|
53
53
|
item_id: str,
|
54
54
|
single_train_tsdf: TimeSeriesDataFrame,
|
55
55
|
single_test_tsdf: TimeSeriesDataFrame,
|
56
|
-
quantile_config: list[float],
|
57
56
|
) -> pd.DataFrame:
|
57
|
+
# logger.debug(f"Predicting on item_id: {item_id}")
|
58
|
+
|
58
59
|
test_index = single_test_tsdf.index
|
59
60
|
train_X, train_y = split_time_series_to_X_y(single_train_tsdf.copy())
|
60
61
|
test_X, _ = split_time_series_to_X_y(single_test_tsdf.copy())
|
@@ -64,15 +65,21 @@ class TabPFNWorker(ABC):
|
|
64
65
|
if train_y_has_constant_value:
|
65
66
|
logger.info("Found time-series with constant target")
|
66
67
|
result = self._predict_on_constant_train_target(
|
67
|
-
single_train_tsdf, single_test_tsdf
|
68
|
+
single_train_tsdf, single_test_tsdf
|
68
69
|
)
|
69
70
|
else:
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
tabpfn = self._get_tabpfn_engine()
|
72
|
+
tabpfn.fit(train_X, train_y)
|
73
|
+
full_pred = tabpfn.predict(test_X, output_type="main")
|
74
|
+
|
75
|
+
result = {"target": full_pred[self.config["tabpfn_output_selection"]]}
|
76
|
+
result.update(
|
77
|
+
{
|
78
|
+
q: q_pred
|
79
|
+
for q, q_pred in zip(
|
80
|
+
TABPFN_TS_DEFAULT_QUANTILE_CONFIG, full_pred["quantiles"]
|
81
|
+
)
|
82
|
+
}
|
76
83
|
)
|
77
84
|
|
78
85
|
result = pd.DataFrame(result, index=test_index)
|
@@ -81,20 +88,13 @@ class TabPFNWorker(ABC):
|
|
81
88
|
return result
|
82
89
|
|
83
90
|
@abstractmethod
|
84
|
-
def
|
85
|
-
self,
|
86
|
-
train_X: pd.DataFrame,
|
87
|
-
train_y: pd.Series,
|
88
|
-
test_X: pd.DataFrame,
|
89
|
-
quantile_config: list[float],
|
90
|
-
) -> pd.DataFrame:
|
91
|
+
def _get_tabpfn_engine(self):
|
91
92
|
pass
|
92
93
|
|
93
94
|
def _predict_on_constant_train_target(
|
94
95
|
self,
|
95
96
|
single_train_tsdf: TimeSeriesDataFrame,
|
96
97
|
single_test_tsdf: TimeSeriesDataFrame,
|
97
|
-
quantile_config: list[float],
|
98
98
|
) -> pd.DataFrame:
|
99
99
|
# If train_y is constant, we return the constant value from the training set
|
100
100
|
mean_constant = single_train_tsdf.target.iloc[0]
|
@@ -102,12 +102,14 @@ class TabPFNWorker(ABC):
|
|
102
102
|
|
103
103
|
# For quantile prediction, we assume that the uncertainty follows a standard normal distribution
|
104
104
|
quantile_pred_with_uncertainty = norm.ppf(
|
105
|
-
|
105
|
+
TABPFN_TS_DEFAULT_QUANTILE_CONFIG, loc=mean_constant, scale=1
|
106
106
|
)
|
107
107
|
result.update(
|
108
108
|
{
|
109
109
|
q: np.full(len(single_test_tsdf), v)
|
110
|
-
for q, v in zip(
|
110
|
+
for q, v in zip(
|
111
|
+
TABPFN_TS_DEFAULT_QUANTILE_CONFIG, quantile_pred_with_uncertainty
|
112
|
+
)
|
111
113
|
}
|
112
114
|
)
|
113
115
|
|
@@ -117,108 +119,141 @@ class TabPFNWorker(ABC):
|
|
117
119
|
class TabPFNClient(TabPFNWorker):
|
118
120
|
def __init__(
|
119
121
|
self,
|
120
|
-
|
122
|
+
config: dict = {},
|
121
123
|
num_workers: int = 2,
|
122
124
|
):
|
123
|
-
super().__init__(
|
125
|
+
super().__init__(config, num_workers)
|
124
126
|
|
125
127
|
# Initialize the TabPFN client (e.g. sign up, login, etc.)
|
126
128
|
from tabpfn_client import init
|
127
129
|
|
128
130
|
init()
|
129
131
|
|
132
|
+
def _get_tabpfn_engine(self):
|
133
|
+
from tabpfn_client import TabPFNRegressor
|
134
|
+
|
135
|
+
return TabPFNRegressor(**self.config["tabpfn_internal"])
|
136
|
+
|
137
|
+
|
138
|
+
class LocalTabPFN(TabPFNWorker):
|
139
|
+
def __init__(
|
140
|
+
self,
|
141
|
+
config: dict = {},
|
142
|
+
num_workers_per_gpu: int = 4, # per GPU
|
143
|
+
):
|
144
|
+
self.num_workers_per_gpu = num_workers_per_gpu
|
145
|
+
|
146
|
+
# Only support GPU for now (inference on CPU takes too long)
|
147
|
+
if not torch.cuda.is_available():
|
148
|
+
raise ValueError("GPU is required for local TabPFN inference")
|
149
|
+
|
150
|
+
super().__init__(
|
151
|
+
config, num_workers=torch.cuda.device_count() * self.num_workers_per_gpu
|
152
|
+
)
|
153
|
+
|
130
154
|
def predict(
|
131
155
|
self,
|
132
156
|
train_tsdf: TimeSeriesDataFrame,
|
133
157
|
test_tsdf: TimeSeriesDataFrame,
|
134
|
-
quantile_config: list[float],
|
135
158
|
):
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
159
|
+
total_num_workers = torch.cuda.device_count() * self.num_workers_per_gpu
|
160
|
+
|
161
|
+
# Split data into chunks for parallel inference on each GPU
|
162
|
+
# since the time series are of different lengths, we shuffle
|
163
|
+
# the item_ids s.t. the workload is distributed evenly across GPUs
|
164
|
+
# Also, using 'min' since num_workers could be larger than the number of time series
|
165
|
+
np.random.seed(0)
|
166
|
+
item_ids_chunks = np.array_split(
|
167
|
+
np.random.permutation(train_tsdf.item_ids),
|
168
|
+
min(total_num_workers, len(train_tsdf.item_ids)),
|
169
|
+
)
|
170
|
+
|
171
|
+
# Run predictions in parallel
|
172
|
+
predictions = Parallel(n_jobs=len(item_ids_chunks), backend="loky")(
|
173
|
+
delayed(self._prediction_routine_per_gpu)(
|
174
|
+
train_tsdf.loc[chunk],
|
175
|
+
test_tsdf.loc[chunk],
|
176
|
+
gpu_id=i
|
177
|
+
% torch.cuda.device_count(), # Alternate between available GPUs
|
140
178
|
)
|
179
|
+
for i, chunk in enumerate(item_ids_chunks)
|
180
|
+
)
|
141
181
|
|
142
|
-
|
182
|
+
predictions = pd.concat(predictions)
|
143
183
|
|
144
|
-
|
145
|
-
|
146
|
-
train_X: pd.DataFrame,
|
147
|
-
train_y: pd.Series,
|
148
|
-
test_X: pd.DataFrame,
|
149
|
-
quantile_config: list[float],
|
150
|
-
) -> pd.DataFrame:
|
151
|
-
from tabpfn_client import TabPFNRegressor
|
184
|
+
# Sort predictions according to original item_ids order
|
185
|
+
predictions = predictions.loc[train_tsdf.item_ids]
|
152
186
|
|
153
|
-
|
154
|
-
tabpfn.fit(train_X, train_y)
|
155
|
-
full_pred = tabpfn.predict_full(test_X)
|
187
|
+
return TimeSeriesDataFrame(predictions)
|
156
188
|
|
157
|
-
|
158
|
-
|
189
|
+
def _get_tabpfn_engine(self):
|
190
|
+
from tabpfn import TabPFNRegressor
|
159
191
|
|
160
|
-
|
192
|
+
if "model_path" in self.config["tabpfn_internal"]:
|
193
|
+
config = self.config["tabpfn_internal"].copy()
|
194
|
+
config["model_path"] = self._parse_model_path(config["model_path"])
|
161
195
|
|
162
|
-
|
163
|
-
if (
|
164
|
-
"optimize_metric" not in self.tabpfn_config
|
165
|
-
or self.tabpfn_config["optimize_metric"] is None
|
166
|
-
):
|
167
|
-
return "mean"
|
168
|
-
elif self.tabpfn_config["optimize_metric"] in ["rmse", "mse", "r2", "mean"]:
|
169
|
-
return "mean"
|
170
|
-
elif self.tabpfn_config["optimize_metric"] in ["mae", "median"]:
|
171
|
-
return "median"
|
172
|
-
elif self.tabpfn_config["optimize_metric"] in ["mode", "exact_match"]:
|
173
|
-
return "mode"
|
174
|
-
else:
|
175
|
-
raise ValueError(f"Unknown metric {self.tabpfn_config['optimize_metric']}")
|
196
|
+
return TabPFNRegressor(**config, random_state=0)
|
176
197
|
|
198
|
+
def _parse_model_path(self, model_name: str) -> str:
|
199
|
+
return f"tabpfn-v2-regressor-{model_name}.ckpt"
|
177
200
|
|
178
|
-
|
179
|
-
def __init__(
|
201
|
+
def _prediction_routine_per_gpu(
|
180
202
|
self,
|
181
|
-
|
203
|
+
train_tsdf: TimeSeriesDataFrame,
|
204
|
+
test_tsdf: TimeSeriesDataFrame,
|
205
|
+
gpu_id: int,
|
182
206
|
):
|
183
|
-
#
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
207
|
+
# Set GPU
|
208
|
+
torch.cuda.set_device(gpu_id)
|
209
|
+
|
210
|
+
all_pred = []
|
211
|
+
for item_id in tqdm(train_tsdf.item_ids, desc=f"GPU {gpu_id}:"):
|
212
|
+
predictions = self._prediction_routine(
|
213
|
+
item_id,
|
214
|
+
train_tsdf.loc[item_id],
|
215
|
+
test_tsdf.loc[item_id],
|
216
|
+
)
|
217
|
+
all_pred.append(predictions)
|
189
218
|
|
190
|
-
|
219
|
+
# Clear GPU cache
|
220
|
+
torch.cuda.empty_cache()
|
191
221
|
|
192
|
-
|
193
|
-
self,
|
194
|
-
train_X: pd.DataFrame,
|
195
|
-
train_y: pd.Series,
|
196
|
-
test_X: pd.DataFrame,
|
197
|
-
quantile_config: list[float],
|
198
|
-
) -> pd.DataFrame:
|
199
|
-
from tabpfn import TabPFNRegressor
|
222
|
+
return pd.concat(all_pred)
|
200
223
|
|
201
|
-
tabpfn = TabPFNRegressor(**self.tabpfn_config)
|
202
|
-
tabpfn.fit(train_X, train_y)
|
203
|
-
full_pred = tabpfn.predict_full(test_X)
|
204
224
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
225
|
+
class MockTabPFN(TabPFNWorker):
|
226
|
+
"""
|
227
|
+
Mock TabPFN worker that returns random values for predictions.
|
228
|
+
Can be used for testing or debugging.
|
229
|
+
"""
|
210
230
|
|
211
|
-
|
212
|
-
|
213
|
-
result.update({q: criterion.icdf(logits, q) for q in quantile_config})
|
231
|
+
class MockTabPFNRegressor:
|
232
|
+
TABPFN_QUANTILE = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
|
214
233
|
|
215
|
-
|
234
|
+
def __init__(self, *args, **kwargs):
|
235
|
+
pass
|
216
236
|
|
217
|
-
|
218
|
-
|
219
|
-
import importlib.util
|
237
|
+
def fit(self, *args, **kwargs):
|
238
|
+
pass
|
220
239
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
240
|
+
def predict(self, test_X, output_type="main", **kwargs):
|
241
|
+
if output_type != "main":
|
242
|
+
raise NotImplementedError(
|
243
|
+
"Only main output is supported for mock TabPFN"
|
244
|
+
)
|
245
|
+
|
246
|
+
return {
|
247
|
+
"mean": np.random.rand(len(test_X)),
|
248
|
+
"median": np.random.rand(len(test_X)),
|
249
|
+
"mode": np.random.rand(len(test_X)),
|
250
|
+
"quantiles": [
|
251
|
+
np.random.rand(len(test_X)) for _ in self.TABPFN_QUANTILE
|
252
|
+
],
|
253
|
+
}
|
254
|
+
|
255
|
+
def __init__(self, *args, **kwargs):
|
256
|
+
super().__init__(*args, **kwargs)
|
257
|
+
|
258
|
+
def _get_tabpfn_engine(self):
|
259
|
+
return self.MockTabPFNRegressor()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: tabpfn_time_series
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: Zero-shot time series forecasting with TabPFN
|
5
5
|
Project-URL: Homepage, https://github.com/liam-sbhoo/tabpfn-time-series
|
6
6
|
Project-URL: Bug Tracker, https://github.com/liam-sbhoo/tabpfn-time-series/issues
|
@@ -10,26 +10,36 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
12
12
|
Requires-Python: >=3.10
|
13
|
-
Requires-Dist: autogluon-timeseries
|
14
|
-
Requires-Dist:
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
13
|
+
Requires-Dist: autogluon-timeseries>=1.2
|
14
|
+
Requires-Dist: datasets>=3.3.2
|
15
|
+
Requires-Dist: gluonts>=0.16.0
|
16
|
+
Requires-Dist: pandas<2.2.0,>=2.1.2
|
17
|
+
Requires-Dist: tabpfn-client>=0.1.1
|
18
|
+
Requires-Dist: tabpfn>=2.0.0
|
17
19
|
Requires-Dist: tqdm
|
18
20
|
Provides-Extra: dev
|
19
21
|
Requires-Dist: build; extra == 'dev'
|
22
|
+
Requires-Dist: jupyter; extra == 'dev'
|
20
23
|
Requires-Dist: pre-commit; extra == 'dev'
|
21
24
|
Requires-Dist: ruff; extra == 'dev'
|
22
25
|
Requires-Dist: twine; extra == 'dev'
|
23
26
|
Description-Content-Type: text/markdown
|
24
27
|
|
25
|
-
# Time Series Forecasting with TabPFN
|
28
|
+
# Zero-Shot Time Series Forecasting with TabPFN
|
26
29
|
|
30
|
+
[](https://badge.fury.io/py/tabpfn-time-series)
|
27
31
|
[](https://colab.research.google.com/github/liam-sbhoo/tabpfn-time-series/blob/main/demo.ipynb)
|
28
32
|
[](https://discord.com/channels/1285598202732482621/)
|
29
|
-
[](https://arxiv.org/abs/2501.02945)
|
30
34
|
|
35
|
+
## 📌 News
|
36
|
+
- **27-01-2025**: 🚀 Ranked _**1st**_ on [GIFT-EVAL](https://huggingface.co/spaces/Salesforce/GIFT-Eval) benchmark<sup>[1]</sup>!
|
37
|
+
- **10-10-2024**: 🚀 TabPFN-TS [paper](https://arxiv.org/abs/2501.02945) accepted to NeurIPS 2024 [TRL](https://table-representation-learning.github.io/NeurIPS2024/) and [TSALM](https://neurips-time-series-workshop.github.io/) workshops!
|
31
38
|
|
32
|
-
|
39
|
+
_[1] Last checked on: 10/03/2025_
|
40
|
+
|
41
|
+
## ✨ Introduction
|
42
|
+
We demonstrate that the tabular foundation model **[TabPFN](https://github.com/PriorLabs/TabPFN)**, when paired with minimal featurization, can perform zero-shot time series forecasting. Its performance on point forecasting matches or even slightly outperforms state-of-the-art methods.
|
33
43
|
|
34
44
|
## 📖 How does it work?
|
35
45
|
|
@@ -50,10 +60,16 @@ For more details, please refer to our [paper](https://arxiv.org/abs/2501.02945)
|
|
50
60
|
- **Point and probabilistic forecasting**: it provides accurate point forecasts as well as probabilistic forecasts.
|
51
61
|
- **Support for exogenous variables**: if you have exogenous variables, this method can seemlessly incorporate them into the forecasting model.
|
52
62
|
|
53
|
-
On top of that, thanks to [tabpfn-client](https://github.com/automl/tabpfn-client) from [Prior Labs](https://priorlabs.ai)
|
63
|
+
On top of that, thanks to **[tabpfn-client](https://github.com/automl/tabpfn-client)** from **[Prior Labs](https://priorlabs.ai)**, you won’t even need your own GPU to run fast inference with TabPFN. 😉 We have included `tabpfn-client` as the default engine in our implementation.
|
54
64
|
|
55
65
|
## How to use it?
|
56
66
|
|
57
67
|
[](https://colab.research.google.com/github/liam-sbhoo/tabpfn-time-series/blob/main/demo.ipynb)
|
58
68
|
|
59
69
|
The demo should explain it all. 😉
|
70
|
+
|
71
|
+
## 📊 GIFT-EVAL Benchmark
|
72
|
+
|
73
|
+
We have submitted our results to the [GIFT-EVAL](https://huggingface.co/spaces/Salesforce/GIFT-Eval) benchmark. Stay tuned for results!
|
74
|
+
|
75
|
+
For more details regarding the evaluation setup, please refer to [README.md](gift_eval/README.md).
|
@@ -0,0 +1,11 @@
|
|
1
|
+
tabpfn_time_series/__init__.py,sha256=brJLLVOis4tBGOmNk6PCjyk_RaOvFITZgaYChOTVqSo,353
|
2
|
+
tabpfn_time_series/data_preparation.py,sha256=iNW7sAnRkTgmzzOEHBhkkTwm_lQ3p_Q9xgAQ5PbkOts,5416
|
3
|
+
tabpfn_time_series/defaults.py,sha256=u2_JnwxiZ5NNibzyNpsE63KuP3TcmOL1iAP8llZ2rJk,238
|
4
|
+
tabpfn_time_series/feature.py,sha256=_9FxfQfgPOOO1MiT8hB8523eZ3Nc5oKuoY7vcohKZZc,2531
|
5
|
+
tabpfn_time_series/plot.py,sha256=bwSYcWBanzPrUxXKFsbqG8fyGsOJZfgU2v3NsxzTSXo,6571
|
6
|
+
tabpfn_time_series/predictor.py,sha256=JzuV34zERf1XDLacGzSFJb-o077qd7GlKC6lvD62EPk,1457
|
7
|
+
tabpfn_time_series/tabpfn_worker.py,sha256=zvFwg4Dc01_m5emqmVITBr6W_cNZ04tMyntmj40pyPE,8299
|
8
|
+
tabpfn_time_series-0.1.3.dist-info/METADATA,sha256=KQZBVKZgMX4e3uxk2LTCuSwruATLowUmgrP6wbcLMB8,4158
|
9
|
+
tabpfn_time_series-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
+
tabpfn_time_series-0.1.3.dist-info/licenses/LICENSE.txt,sha256=iwhPL7kIWQG6gyLZZwIMDItGrNgxMDIq9itxkUSMapY,11345
|
11
|
+
tabpfn_time_series-0.1.3.dist-info/RECORD,,
|
@@ -1,11 +0,0 @@
|
|
1
|
-
tabpfn_time_series/__init__.py,sha256=atVNap8tQLI0t5COkkCop-wbY3y1FdVxIMfvCf6VDsQ,257
|
2
|
-
tabpfn_time_series/data_preparation.py,sha256=iNW7sAnRkTgmzzOEHBhkkTwm_lQ3p_Q9xgAQ5PbkOts,5416
|
3
|
-
tabpfn_time_series/defaults.py,sha256=C9HiD7Zm0BzVfE9e2f8nhpiPQSYx79hWozvzb-93L40,165
|
4
|
-
tabpfn_time_series/feature.py,sha256=_9FxfQfgPOOO1MiT8hB8523eZ3Nc5oKuoY7vcohKZZc,2531
|
5
|
-
tabpfn_time_series/plot.py,sha256=bwSYcWBanzPrUxXKFsbqG8fyGsOJZfgU2v3NsxzTSXo,6571
|
6
|
-
tabpfn_time_series/predictor.py,sha256=YfJIe8KsyzkwgX4EFAHR8dDp-mqSv9WK88_qO_EXlws,1505
|
7
|
-
tabpfn_time_series/tabpfn_worker.py,sha256=3xInPzzQtmIBPjbc_5TaQsX3-Bl3WOlxttqj3KZlC9Q,7395
|
8
|
-
tabpfn_time_series-0.1.1.dist-info/METADATA,sha256=EK_9xSO0-EiE-YzlGietFOwOdD7gt5zFI5gqkzo1IMk,3147
|
9
|
-
tabpfn_time_series-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
10
|
-
tabpfn_time_series-0.1.1.dist-info/licenses/LICENSE.txt,sha256=iwhPL7kIWQG6gyLZZwIMDItGrNgxMDIq9itxkUSMapY,11345
|
11
|
-
tabpfn_time_series-0.1.1.dist-info/RECORD,,
|
File without changes
|
{tabpfn_time_series-0.1.1.dist-info → tabpfn_time_series-0.1.3.dist-info}/licenses/LICENSE.txt
RENAMED
File without changes
|