Skip to main content
compute_features extracts one row of native summaries per series. compare_feature_coverage fits a scaler, PCA projection, and grid on the retained real reference panel, then projects each synthetic corpus into that same space. Adding another corpus leaves existing scores unchanged under these defaults. Corpus size still affects occupancy; compare matched sizes. The twelve-feature schema is native_v1. Its feature names, order, definitions, normalization, and undefined-value rules are fixed; changes to those contracts require a new schema identifier. Period and window settings remain explicit extraction parameters, recorded with the schema. Raw-input coverage metadata records both the requested and effective window size. These are SynForecast definitions, not a reproduction of an external feature package. The first two PCA components keep only part of the real-feature variance: 54–84% on the M4 panels we evaluated, with visible losses for spike and variance-shift differences. Treat the map as a two-dimensional diagnostic, not as comprehensive feature-space coverage. Full-feature nearest-neighbour distances agree with the map on the aggregate ordering of corpora but often disagree on individual series, and grid boundaries alone can move a score noticeably. Report full-feature distances and real-calibrated coverage alongside the map; neither a single radius nor a grid score establishes general fidelity.

Choosing a period and window

Extraction never reads timestamps: declare the period yourself, either in observations (seasonal_period) or through freq, which uses the same convention as the preset pools (hourly 24, daily 7, weekly 52, monthly 12, quarterly 4, yearly none). Without either, no seasonality is declared, the two seasonal features are zero for every series, and compare_feature_coverage drops them as constant columns and logs a warning. A period of 1 means no seasonality. An availability check of all 100,000 M4 training series supports the following settings, using at most the last 512 observations: All M4 series are finite in all twelve features under these settings. Weekly uses M4’s nonseasonal convention: its two seasonal features are constant and annual seasonality is unmeasured. A 52-week period excludes 65 of the 359 Weekly series, which lack two full cycles; report that as a separate eligible population. Daily’s seven-day cycle is an explicit assumption (M4 metadata declares it nonseasonal), and Hourly’s 24-hour period covers only that cycle.
Feature frames preserve the input dataframe engine and ID dtype, with a fresh index for pandas. Observations are sorted by ID and time. Raw targets must be finite, IDs/times non-null, and timestamps unique within each series. n_jobs sets the native worker threads; the default -1 uses all CPUs and honours RAYON_NUM_THREADS, as in the generators.

Native feature contracts

All features require at least three observations. Every feature is computed on the series normalized to zero mean and unit population variance, so none depends on the input scale or offset. Constant input maps to zero; normalization scales by the maximum absolute value first to avoid overflow. When a declared period cannot fit two cycles, the three decomposition-based features (trend_strength, seasonal_strength, spike) are NaN, so a panel of mixed lengths never mixes two decomposition definitions. Without a declared period, the decomposition uses a trend window near one tenth of the series length. For lumpiness and shift features, window_size can explicitly set the width (at least 2). The default is the declared period, or 10 without one; at least two full windows are required. window_size does not change the decomposition or seasonal ACF. For short nonseasonal panels, a fixed window_size=5 keeps series of 10 to 19 observations that a ten-observation window would exclude. Record the width with cached features and use the same setting for real and synthetic corpora. ACF uses the full mean-centered sum of squares in its denominator at every lag and returns zero if that sum is at most machine epsilon. Crossing counts and other estimates remain length-dependent, so match length distributions as well as sample sizes.

Reading the scores

  • miscoverage: uncovered real cells divided by all grid cells.
  • reverse_miscoverage: synthetic-only cells divided by all grid cells, restricted to the grid’s bounding box.
  • uncovered_real_cell_fraction: uncovered real cells divided by occupied real cells.
  • uncovered_real_series_fraction: retained real series in uncovered cells divided by all retained real series.
  • synthetic_out_of_range_fraction: synthetic series outside the box divided by all retained synthetic series, including those outside it.
CoverageResult.summary() returns these scores with the retained counts as a flat dict. Results compare by identity, since several fields are arrays. The default real-range grid adds one percent padding per axis. It excludes out-of-range synthetic points rather than clipping them onto edge cells. Out-of-range is evidence of extrapolation in the displayed coordinates, not proof of unrealistic data. Differences in discarded dimensions may be hidden; inspect explained variance and the features themselves. Zero miscoverage is not evidence of predictive fidelity or privacy. missing="raise" rejects undefined feature values. Explicit missing="drop" evaluates complete cases, logs exclusions, and returns retained/dropped IDs and reasons. Counts and fractions describe the retained population. A column is constant when its range in the fitting population is at most 1e-12, scaled by its magnitude when that exceeds one. Real-constant columns cannot enter reference PCA; synthetic deviations from those reference values are counted separately. At least two retained real series and one variable feature are needed for the default fit. Rank-one PCA uses a zero second coordinate. Result metadata stores fitted parameters, a space identifier, and a reference fingerprint. A shared space identifier does not make different reference samples or sample sizes interchangeable. Persist extraction settings with cached native feature frames; precomputed frames do not carry an implicit native schema, and precomputed=True rejects the extraction keywords rather than ignoring them. fit="pooled" and grid_range="pooled" provide a joint-fitting sensitivity case. Synthetic outliers can shift that space and its bin widths. Optional t-SNE requires embedding="tsne", fit="pooled", seed=..., scikit-learn, and more than 30 retained series for its fixed perplexity of 30. It fits all declared points jointly and does not project new points. Pooled PCA uses the same occupancy measure but does not reproduce Kang’s t-SNE experiment.

API

compute_features

Return one row of native features per series in the caller’s engine. The native_v1 schema fixes feature definitions and order. Every feature is computed on the series normalized to zero mean and unit variance, so none depends on the input scale. Features depend on observation counts, not on the calendar of time_col. crossing_points is a raw count and therefore grows with series length, so compare panels of comparable length. Short series yield NaN for undefined features and one summary log warning; invalid raw inputs raise. Parameters: Returns:

feature_coverage

Compare one synthetic corpus; see :func:compare_feature_coverage for the protocol.

compare_feature_coverage

Compare synthetic corpora using a common feature space and grid. Defaults fit the scaler, PCA, constant-column selection, and padded grid on retained real data only, so synthetic corpora cannot shift that space and adding a corpus leaves existing scores unchanged. Corpus size still affects occupancy; compare matched sizes. Features are computed per series from observation counts alone, so the frequency and calendar of time_col are never compared across corpora, and crossing_points is a raw count that grows with series length. Generate synthetic series at lengths comparable to the real panel; the preset pools default to fixed lengths that may not match yours. Parameters: Returns:

CoverageDiagnostics

Series retained or excluded from a corpus, in embedding row order. drop_reasons maps each dropped ID to the names of its non-finite features. Instances compare by identity, not by value.

CoverageDiagnostics.drop_reasons

CoverageDiagnostics.dropped_ids

CoverageDiagnostics.n_input

CoverageDiagnostics.retained_ids

CoverageResult

Occupancy scores and the parameters needed to interpret them. miscoverage divides uncovered real cells by all grid cells; uncovered_real_cell_fraction divides by occupied real cells instead. reverse_miscoverage counts synthetic-only cells within the grid. Out-of-range synthetic points are excluded from occupancy, but included in the denominator of synthetic_out_of_range_fraction. These scores describe retained series; inspect the diagnostics before comparing corpora. explained_variance is None for t-SNE. metadata holds the fitted parameters and the reference_id fingerprint of the retained real features; each result owns its copy. Instances compare by identity, since several fields are arrays; compare summary() values instead.

CoverageResult.constant_features_dropped

CoverageResult.embedding

CoverageResult.explained_variance

CoverageResult.features_used

CoverageResult.fit

CoverageResult.grid_edges

CoverageResult.grid_range

CoverageResult.metadata

CoverageResult.miscoverage

CoverageResult.n_bins

CoverageResult.n_synthetic_out_of_range

CoverageResult.plot

Plot occupied cells and uncovered real points; import matplotlib lazily. Points outside the grid are omitted from this view and counted in the title. Out-of-range means outside the observed projected reference box, not necessarily unrealistic. Returns the matplotlib axes.

CoverageResult.real_diagnostics

CoverageResult.real_embedding

CoverageResult.real_occupancy

CoverageResult.reverse_miscoverage

CoverageResult.space_id

CoverageResult.summary

Return the scalar scores and retained counts as a flat dict. pd.DataFrame({name: r.summary() for name, r in results.items()}).T tabulates the output of :func:compare_feature_coverage.

CoverageResult.synthetic_constant_feature_deviations

CoverageResult.synthetic_diagnostics

CoverageResult.synthetic_embedding

CoverageResult.synthetic_occupancy

CoverageResult.synthetic_out_of_range_fraction

CoverageResult.uncovered_real_cell_fraction

CoverageResult.uncovered_real_ids

CoverageResult.uncovered_real_series_fraction