tabpfn-graph 0.2.0__tar.gz

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.
@@ -0,0 +1,26 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .mypy_cache/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .coverage
7
+ htmlcov/
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+ .venv*/
12
+ .benchmark-deps/
13
+ .env
14
+ .env.*
15
+ !.env.example
16
+ *.key
17
+ *.pem
18
+ credentials.json
19
+ .DS_Store
20
+ .idea/
21
+ .vscode/
22
+ data/
23
+ benchmark-results/
24
+ logs/
25
+ *.whl
26
+ *.tar.gz
@@ -0,0 +1,79 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0
4
+
5
+ Breaking changes are listed first. The package had not been published, so no
6
+ deprecation cycle is provided.
7
+
8
+ ### Breaking
9
+
10
+ - `approximation_nodes` is replaced by `approximation_pivots`. Approximate
11
+ descriptors no longer build a random induced subgraph; they estimate the
12
+ whole-graph quantity (pivot-sampled betweenness, sampled-source distances,
13
+ rescaled triangle counts, truncated-spectrum heat traces).
14
+ - WL initial labels default to the categorical node/edge attributes discovered
15
+ during `fit` (`wl_node_attributes="auto"`). Pass `None` for the previous,
16
+ purely structural behavior.
17
+ - The WL vocabulary is pruned by document frequency and capped
18
+ (`wl_min_graph_count`, `wl_max_features`), so the table width no longer grows
19
+ with the training set.
20
+ - Spectral descriptors default to the normalized Laplacian (`laplacian=`), so
21
+ the NetLSD time grid is comparable across graph sizes and
22
+ `spectral__algebraic_connectivity` is the normalized spectral gap.
23
+ - `motifs__average_clustering` and `motifs__core_number__*` are removed; those
24
+ quantities were exact duplicates of `local_profile` columns.
25
+ - Histogram boundaries are deduplicated, so discrete attributes get fewer bins
26
+ instead of structurally empty ones, and bin column counts change.
27
+ - `networkx>=3.5` is required, and `transform` refuses to run under a different
28
+ NetworkX feature release than the one used at `fit`.
29
+ - Python 3.11 is the minimum supported version. NetworkX 3.5 is 3.11+ only, so
30
+ the 3.10 support claimed by earlier metadata was not installable.
31
+
32
+ ### Added
33
+
34
+ - Edge weight support: `edge_weight`, `edge_weight_agg`, and
35
+ `edge_weight_semantics`. Weighted strength profiles, weighted clustering,
36
+ weighted PageRank/betweenness/assortativity/shortest paths, and a weighted
37
+ Laplacian spectrum.
38
+ - Direction-aware columns whenever any training graph is directed: reciprocity,
39
+ in/out degree summaries and correlation, strongly connected components,
40
+ largest-SCC fraction, acyclicity, and PageRank on a direction-preserving
41
+ projection of the native arcs.
42
+ - `motifs__square_clustering` and `basic__is_bipartite`, so bipartite datasets
43
+ are not described entirely by identically-zero triangle columns.
44
+ - Largest-component path descriptors (`paths__lcc_*`) and component size
45
+ summaries, which stay defined for disconnected graphs.
46
+ - `undefined="nan"` to stop conflating an undefined descriptor with a genuine
47
+ zero.
48
+ - `diagnostics_` plus `fit`-time warnings for ignored edge weights, mixed
49
+ directedness, extreme size heterogeneity, all-bipartite datasets, and
50
+ aggressive WL pruning.
51
+ - `tabpfn_graph.column_report` and `prune_uninformative=True`, which drops
52
+ constant and exactly duplicated columns as a fit-learned schema decision.
53
+ - `docs/graph-types.md`, covering which graph families need a non-default
54
+ configuration.
55
+
56
+ ### Fixed
57
+
58
+ - Mixed directed/undirected batches produced silent NaN columns, or dropped the
59
+ in/out degree columns entirely, depending on which graph came first. The
60
+ schema now depends only on fitted state.
61
+ - Directed PageRank read the native graph with the literal key `"weight"`, so a
62
+ configured `edge_weight` under any other name silently fell back to the
63
+ unweighted computation. It now runs on a direction-preserving projection that
64
+ normalizes the attribute onto the canonical key and aggregates parallel arcs.
65
+ - Negative edge weights under `edge_weight_semantics="distance"` were converted
66
+ into infinite traversal costs, which silently removed the edge from path and
67
+ betweenness descriptors, leaked `inf` into the feature table with a `__valid`
68
+ flag of 1, and left the edge present in the degree and clustering
69
+ descriptors. Negative weights are now rejected under both semantics, during
70
+ `fit` and `transform`. A zero distance is treated as free traversal rather
71
+ than as an unreachable edge.
72
+ - `build-system.requires` allowed hatchling 1.25/1.26, which cannot build the
73
+ PEP 639 license metadata this project declares.
74
+ - Removed the deprecated `License ::` classifier, which PyPI rejects alongside
75
+ a license expression, and added `[project.urls]`.
76
+
77
+ ## 0.1.0
78
+
79
+ Initial internal release.
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
@@ -0,0 +1,7 @@
1
+ tabpfn-graph
2
+ Copyright 2026 tabpfn-graph contributors
3
+
4
+ This product is licensed under the Apache License, Version 2.0.
5
+ TabPFN model checkpoints and third-party datasets are not part of this work and
6
+ are subject to their respective terms.
7
+
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.5
2
+ Name: tabpfn-graph
3
+ Version: 0.2.0
4
+ Summary: Stable graph-to-table features for TabPFN and scikit-learn estimators
5
+ Project-URL: Homepage, https://github.com/m-herre/tabpfn-graph
6
+ Project-URL: Repository, https://github.com/m-herre/tabpfn-graph
7
+ Project-URL: Issues, https://github.com/m-herre/tabpfn-graph/issues
8
+ Project-URL: Changelog, https://github.com/m-herre/tabpfn-graph/blob/main/CHANGELOG.md
9
+ Author: tabpfn-graph contributors
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ License-File: NOTICE
13
+ Keywords: graphs,networkx,scikit-learn,tabpfn
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Requires-Python: <3.15,>=3.11
23
+ Requires-Dist: joblib>=1.3
24
+ Requires-Dist: networkx>=3.5
25
+ Requires-Dist: numpy>=1.24
26
+ Requires-Dist: pandas>=2.0
27
+ Requires-Dist: scikit-learn>=1.4
28
+ Requires-Dist: scipy>=1.10
29
+ Requires-Dist: tabpfn>=2.0
30
+ Provides-Extra: bench
31
+ Requires-Dist: catboost>=1.2; extra == 'bench'
32
+ Requires-Dist: ogb>=1.3; extra == 'bench'
33
+ Requires-Dist: torch-geometric>=2.5; extra == 'bench'
34
+ Requires-Dist: xgboost>=2; extra == 'bench'
35
+ Provides-Extra: client
36
+ Requires-Dist: tabpfn-client>=0.1; extra == 'client'
37
+ Provides-Extra: dev
38
+ Requires-Dist: build>=1.2; extra == 'dev'
39
+ Requires-Dist: hatch>=1.12; extra == 'dev'
40
+ Requires-Dist: mypy>=1.10; extra == 'dev'
41
+ Requires-Dist: pandas-stubs>=2.0; extra == 'dev'
42
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
43
+ Requires-Dist: pytest>=8; extra == 'dev'
44
+ Requires-Dist: ruff>=0.7; extra == 'dev'
45
+ Requires-Dist: twine>=5; extra == 'dev'
46
+ Requires-Dist: types-networkx>=3.5; extra == 'dev'
47
+ Provides-Extra: fast
48
+ Requires-Dist: networkit>=11; extra == 'fast'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # tabpfn-graph
52
+
53
+ `tabpfn-graph` turns a collection of graphs into a schema-stable pandas table and applies
54
+ TabPFN or any scikit-learn-compatible estimator. It targets single-target, graph-level
55
+ classification and regression.
56
+
57
+ ```python
58
+ from tabpfn_graph import GraphClassifier, GraphRegressor
59
+
60
+ clf = GraphClassifier().fit(graphs_train, y_train)
61
+ predictions = clf.predict(graphs_test)
62
+
63
+ reg = GraphRegressor(estimator=my_pipeline).fit(graphs_train, y_train)
64
+ ```
65
+
66
+ The representation uses established graph descriptors: Local Degree/Topological Profile
67
+ statistics, Weisfeiler–Lehman subtree hashes over categorical node/edge labels, attribute
68
+ distribution aggregation, and optional centrality, paths, motifs, Laplacian, and NetLSD
69
+ summaries. This follows the graph-level descriptor evidence from
70
+ [LTP](https://arxiv.org/abs/2305.00724) and [MOLTOP](https://arxiv.org/abs/2407.12136). The
71
+ broader graph-to-table foundation-model pattern has also been explored for node tasks by
72
+ [G2T-FM](https://arxiv.org/abs/2508.20906) and [TabPFN-GN](https://arxiv.org/abs/2512.08798);
73
+ those papers do not imply that this package implements their node-level methods.
74
+
75
+ Weighted, directed, bipartite, disconnected, and size-heterogeneous graphs each need a
76
+ different configuration, and `fit` warns when the training data looks like a mismatch.
77
+ `docs/graph-types.md` in the source repository states what each family needs.
78
+
79
+ ## Install
80
+
81
+ ```bash
82
+ pip install tabpfn-graph
83
+ ```
84
+
85
+ Python 3.11–3.14 is supported. The standard installation includes TabPFN, NetworkX (3.5 or
86
+ newer, because WL subtree hashes changed in that release), NumPy, pandas, SciPy,
87
+ scikit-learn, and joblib. Optional extras are:
88
+
89
+ ```bash
90
+ pip install 'tabpfn-graph[fast]' # Networkit for compatible primitives
91
+ pip install 'tabpfn-graph[client]' # use hosted clients as user-supplied estimators
92
+ pip install 'tabpfn-graph[dev]' # tests, lint, typing, packaging
93
+ ```
94
+
95
+ The first local TabPFN fit may require accepting the checkpoint terms and downloading model
96
+ weights. Package source code is Apache-2.0; TabPFN checkpoints have separate terms. More detail
97
+ is available in `docs/model-access.md` in the source repository.
98
+
99
+ ## NetworkX quickstarts
100
+
101
+ Classification with the default local TabPFN:
102
+
103
+ ```python
104
+ import networkx as nx
105
+ from tabpfn_graph import GraphClassifier
106
+
107
+ graphs = [nx.path_graph(5), nx.cycle_graph(5), nx.star_graph(4), nx.complete_graph(5)]
108
+ y = [0, 1, 0, 1]
109
+
110
+ clf = GraphClassifier(random_state=0).fit(graphs, y)
111
+ labels = clf.predict([nx.path_graph(7), nx.cycle_graph(7)])
112
+ probabilities = clf.predict_proba([nx.path_graph(7), nx.cycle_graph(7)])
113
+ ```
114
+
115
+ Regression uses the same extraction contract:
116
+
117
+ ```python
118
+ from tabpfn_graph import GraphRegressor
119
+
120
+ reg = GraphRegressor(random_state=0).fit(graphs, [1.2, 2.5, 0.8, 4.1])
121
+ values = reg.predict(graphs)
122
+ ```
123
+
124
+ The default local estimators are created lazily during `fit`, with TabPFN's local text
125
+ transformation enabled. Importing or constructing `GraphClassifier()` does not access model
126
+ weights.
127
+
128
+ ## PyTorch Geometric datasets
129
+
130
+ PyG is intentionally optional. Pass a homogeneous iterable of `torch_geometric.data.Data`
131
+ objects when it is installed:
132
+
133
+ ```python
134
+ from torch_geometric.datasets import TUDataset
135
+ from tabpfn_graph import GraphClassifier
136
+
137
+ dataset = TUDataset(root="data/TU", name="MUTAG")
138
+ graphs = [data for data in dataset]
139
+ y = [int(data.y.item()) for data in dataset]
140
+ model = GraphClassifier().fit(graphs[:150], y[:150])
141
+ prediction = model.predict(graphs[150:])
142
+ ```
143
+
144
+ PyG's common doubled-edge representation is recognized: if every non-loop arc has a reciprocal
145
+ arc with matching multiplicity, each pair is collapsed into one undirected logical edge.
146
+
147
+ ## Standalone feature extraction
148
+
149
+ ```python
150
+ from tabpfn_graph import GraphFeatureExtractor
151
+
152
+ extractor = GraphFeatureExtractor(features="balanced", n_jobs=-1, random_state=0)
153
+ X_train = extractor.fit_transform(graphs_train)
154
+ X_test = extractor.transform(graphs_test)
155
+
156
+ assert list(X_train.columns) == list(X_test.columns)
157
+ ```
158
+
159
+ `X_train` and `X_test` are pandas DataFrames. Numeric values remain numeric, graph-level
160
+ categoricals use pandas categorical dtype, and semantic documents use pandas string dtype.
161
+
162
+ ## Custom estimators
163
+
164
+ No text encoding is inserted for custom estimators. For numeric-only feature tables:
165
+
166
+ ```python
167
+ from sklearn.ensemble import RandomForestClassifier
168
+ from tabpfn_graph import GraphClassifier
169
+
170
+ model = GraphClassifier(
171
+ features="balanced",
172
+ estimator=RandomForestClassifier(n_estimators=500, random_state=0),
173
+ ).fit(graphs_train, y_train)
174
+ ```
175
+
176
+ XGBoost and CatBoost-style estimators work the same way:
177
+
178
+ ```python
179
+ from xgboost import XGBClassifier
180
+
181
+ model = GraphClassifier(
182
+ features="balanced",
183
+ estimator=XGBClassifier(n_estimators=500, random_state=0),
184
+ ).fit(graphs_train, y_train)
185
+ ```
186
+
187
+ CatBoost can consume categorical/text columns when configured with their column names or
188
+ indices. Hosted TabPFN clients can be passed through `estimator=`; the package does not require a
189
+ particular client API beyond sklearn-style `fit` and `predict`.
190
+
191
+ For a text-aware sklearn pipeline, explicitly select and transform the document column:
192
+
193
+ ```python
194
+ from sklearn.compose import ColumnTransformer
195
+ from sklearn.feature_extraction.text import TfidfVectorizer
196
+ from sklearn.linear_model import LogisticRegression
197
+ from sklearn.pipeline import make_pipeline
198
+ from sklearn.preprocessing import StandardScaler
199
+ from tabpfn_graph import GraphClassifier, GraphFeatureExtractor
200
+
201
+ extractor = GraphFeatureExtractor(
202
+ features=("basic", "text"),
203
+ text_attributes=("node.description",),
204
+ )
205
+ preprocess = ColumnTransformer([
206
+ ("text", TfidfVectorizer(), "node_attr__description__document"),
207
+ ("numeric", StandardScaler(), ["basic__n_nodes", "basic__n_edges_native"]),
208
+ ])
209
+ estimator = make_pipeline(preprocess, LogisticRegression(random_state=0))
210
+ model = GraphClassifier(feature_extractor=extractor, estimator=estimator)
211
+ ```
212
+
213
+ ## Weighted and directed graphs
214
+
215
+ Structural descriptors ignore edge weights unless you name the attribute, because a weight has
216
+ no universal meaning. Path and betweenness descriptors need a traversal cost, so the semantics
217
+ are explicit rather than guessed:
218
+
219
+ ```python
220
+ extractor = GraphFeatureExtractor(
221
+ edge_weight="weight",
222
+ edge_weight_semantics="similarity", # cost = 1 / w; use "distance" when w is a length
223
+ )
224
+ ```
225
+
226
+ That switches strength profiles, weighted clustering, PageRank, betweenness, assortativity,
227
+ shortest paths, and the Laplacian spectrum to their weighted definitions. When `edge_weight` is
228
+ left unset but the training graphs carry numeric edge attributes, `fit` warns.
229
+
230
+ Directed input additionally gets reciprocity, in/out degree summaries and their correlation,
231
+ strongly connected components, acyclicity, and PageRank on a direction-preserving projection of
232
+ the native arcs; PageRank on the
233
+ undirected projection is close to a rescaled degree. Mixed batches are supported and yield one
234
+ schema, with undirected graphs described as their own symmetrization.
235
+
236
+ ## Diagnostics
237
+
238
+ ```python
239
+ extractor = GraphFeatureExtractor().fit(graphs_train)
240
+ extractor.diagnostics_ # sizes, directedness, bipartiteness, WL vocabulary, versions
241
+ ```
242
+
243
+ `fit` warns about ignored edge weights, mixed directedness, extreme size heterogeneity,
244
+ all-bipartite datasets, and aggressive WL pruning. `fit_transform` also records how many
245
+ columns are constant or exactly duplicated on the training data, available standalone as
246
+ `tabpfn_graph.column_report(frame)`. Setting `prune_uninformative=True` turns that into a
247
+ fit-learned schema decision and drops those columns.
248
+
249
+ ## Feature selection
250
+
251
+ Presets are `fast`, `balanced` (default), and `comprehensive`:
252
+
253
+ - `fast`: native/basic topology and node, edge, graph metadata, and text aggregation.
254
+ - `balanced`: fast plus clustering/core/LDP profiles and two-iteration hashed WL counts.
255
+ - `comprehensive`: balanced plus centrality, paths, motifs, Laplacian, and NetLSD summaries.
256
+
257
+ Or select groups directly:
258
+
259
+ ```python
260
+ extractor = GraphFeatureExtractor(features=("basic", "wl", "spectral"))
261
+ ```
262
+
263
+ Valid groups are `basic`, `local_profile`, `attributes`, `text`, `wl`, `centrality`, `paths`,
264
+ `motifs`, and `spectral`. Expensive groups preflight against `max_exact_nodes=2000`. To make the
265
+ change in semantics explicit, larger graphs require either a raised exact limit or
266
+ `allow_approximate=True`, which switches to pivot-sampled betweenness, sampled-source
267
+ distances, rescaled triangle counts, and a truncated-spectrum heat trace — estimators of the
268
+ whole-graph quantity, recorded per graph in `approx__active`.
269
+
270
+ ## Scope
271
+
272
+ Single-target graph-level classification and regression on homogeneous NetworkX or PyG batches.
273
+ Heterogeneous graphs (`HeteroData`), temporal graphs, and multilabel targets are out of scope.
274
+
275
+ This is an alpha release. The descriptors are established ones and the schema contract is
276
+ tested, but the package is not backed by a broad benchmark study; treat it as a descriptor
277
+ baseline rather than a method shown to beat tuned GBDT-on-descriptors or GNNs.
278
+
279
+ Detailed feature semantics, graph-family guidance, evaluation guidance, and reproducible
280
+ benchmarks are kept in the source repository under `docs/` and `benchmarks/`. Benchmark code is
281
+ not part of the published wheel or source distribution.