Library / SDK
alteryx/featuretools avatar
alteryx/featuretools

Featuretools and Deep Feature Synthesis: what the library generates, and what it costs you

An open source python library for automated feature engineering

7,676 stars916 forksPythonBSD-3-Clause

At a glance

What is it?
Featuretools turns a set of related tables into one wide feature matrix by stacking aggregation and transform primitives across relationships. It is a fit for relational, timestamped data with a declared schema, and a poor fit for a single flat CSV.
Who is it for?
Adopt Featuretools when your data is genuinely relational and you can declare the relationships yourself: customers, sessions, transactions, with a time index that makes cutoff times meaningful. Do not adopt it for a single flat table, where it has nothing to traverse and you are paying a dependency for a groupby.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem is the traversal, not the aggregation

Most feature engineering on relational data is mechanical. You group transactions by customer, sum the amounts, count the rows, take the max. Then you group sessions by customer and do it again, and then you aggregate over the aggregated values, because the average session total per customer is more informative than the average transaction. The arithmetic is trivial. Remembering to do it, and doing it consistently between training and scoring, is not. Featuretools exists to generate that set of columns from the relationships you declare, rather than from a list you maintain by hand. The README frames the goal with a quote from Pedro Domingos: automating feature engineering is "one of the holy grails of machine learning." The library's answer is Deep Feature Synthesis, abbreviated DFS. It is aimed at data scientists working with multi-table data who already know which column is the target and which columns are the time index, and who want the derived columns produced systematically instead of ad hoc.

What DFS actually produces: nested primitives over declared relationships

The mechanism visible in the README is stacking. You build an EntitySet, which holds several dataframes plus the relationships between them. DFS then walks those relationships and applies primitives. Aggregation primitives run when moving from a child table up to a parent, so transactions collapse into per-customer values. Transform primitives run within a single table, so a timestamp becomes a year, a day, or a session start. The depth parameter controls how many times this repeats, which is where the long column names come from. The README's example output includes SUM(transactions.amount) at the first level, then SUM(sessions.MIN(transactions.amount)) and MAX(sessions.SKEW(transactions.amount)) at the next. Read those names as a call stack: for each customer, take each session, compute the minimum transaction amount inside it, then sum those minima. The feature matrix is returned together with a features_defs object listing the definitions, which is what makes the generated columns reproducible rather than a one-off dataframe. The README also shows es.plot(), which renders the entity set as a diagram, and that diagram is the honest picture of what DFS will traverse.

Installation and the add-on split

The base install is a single command: python -m pip install featuretools. Conda users have the equivalent through conda-forge with conda install -c conda-forge featuretools. Optional capability is packaged as extras. python -m pip install "featuretools[complete]" pulls everything at once. The individual extras are featuretools[premium] for the primitives in the premium-primitives repository, featuretools[nlp] for the natural language primitives in nlp-primitives, and featuretools[dask] for Dask support. The README is explicit about what the Dask extra is for: running DFS with njobs greater than 1. That single sentence is the most useful line in the installation section, because it tells you the parallelism story is opt-in and tied to a specific execution backend, not a default. If you plan to run DFS over a large entity set, decide on the Dask extra before you benchmark anything.

The generated column names are the maintenance surface

Look again at the header row in the README example. Beyond COUNT(transactions) and MODE(sessions.device) there are entries like STD(sessions.SUM(transactions.amount)) and NUM_UNIQUE(sessions.DAY(session_start)). These names are self-describing in the sense that they encode the full computation, which is a real benefit for auditing. They are also long, and they grow with depth. Every downstream artifact that touches them inherits that length: model coefficients, feature importance tables, monitoring dashboards, and any hand-written SQL that tries to reproduce the same column for a scoring path. This is the cost that the library's framing tends to understate. DFS gives you breadth cheaply and gives you legibility expensively. A team that generates a few hundred columns and then cannot explain to a reviewer what SUM(sessions.MEAN(transactions.amount)) means in business terms has traded a manual task for an interpretation task, and the second one is harder to delegate.

Where DFS is the wrong tool

Two cases stand out. The first is a single flat table. DFS operates on relationships between dataframes; with one table there is nothing to traverse, and the transform primitives it can apply are the ones you would write yourself in a few lines. Paying an install and an API surface for that is not a good trade. The second case is any workflow where the feature set must be stable and hand-audited, such as a regulated credit decision where each input needs a documented rationale. DFS will happily produce columns whose provenance is a depth setting. The features_defs return value helps here, but it documents the computation, not the reason. There is also a subtler failure mode: leakage. DFS is fast enough that it is easy to generate features across a time boundary you did not intend to cross, and the README example does not show cutoff_time being used. The library supports time-aware feature construction, but nothing in the material presented here demonstrates the guardrails, so treat that as something you must verify in the documentation before trusting a generated matrix in a temporal setting.

How this differs from tsfresh and from scikit-learn pipelines

The nearest comparison is tsfresh, which also generates features automatically, but from a different starting point. tsfresh takes a set of time series and computes a fixed catalogue of characterisation statistics per series, then lets you filter them by relevance. Featuretools takes a relational schema and composes primitives across the relationships, so the interesting output is the nesting: an aggregation over a transform over an aggregation. If your data is one series per entity, tsfresh's model matches the shape of the problem more directly. If your data is orders, line items, and shipments in separate tables, Featuretools is the one that knows how to walk between them. The other comparison is a scikit-learn Pipeline with a ColumnTransformer, which is the manual baseline. That approach gives you exact control and exact names, and it costs you the discovery of combinations you did not think to write. Featuretools is a breadth generator; a pipeline is a precision instrument. Most production systems end up wanting both, with DFS used to propose candidates and a hand-written transformer used to freeze the winners.

Version cadence, licence, and what to check before adopting

The release history shows v1.29.0 and v1.30.0 both landing in February 2024, followed by v1.31.0 in May 2024. That is a modest cadence on the 1.x line, and it means the API you learn today is likely to remain recognisable, but it also means you should not expect rapid movement on open issues. The licence is BSD-3-Clause, which is permissive and permits commercial use and modification provided the copyright notice and disclaimer are retained; that is a summary of the identifier, not legal advice, and your counsel should confirm it against the LICENSE file in the repository. The repository is not archived, so it is maintained rather than abandoned. Before adopting, confirm three things against the current documentation: whether the primitives you need exist in the base install or require one of the extras, how cutoff_time is specified for your time index, and what the memory profile of DFS looks like on your largest entity set with and without the Dask extra. The demo loader, ft.demo.load_mock_customer(return_entityset=True), is the cheapest way to run all three checks before you touch your own tables.

Editorial conclusion

Adopt Featuretools when your data is genuinely relational and you can declare the relationships yourself: customers, sessions, transactions, with a time index that makes cutoff times meaningful. Do not adopt it for a single flat table, where it has nothing to traverse and you are paying a dependency for a groupby. Before committing, run ft.demo.load_mock_customer(return_entityset=True), call ft.dfs on it, and count the columns that come back. If the names are unreadable to the people who will maintain the model, the feature matrix is a liability rather than an asset.

Official sources

  1. alteryx/featuretools on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Community notes

Community notes