Quick Reference · machine learning extensions · Sebastian Raschka

mlxtend cheat sheet

A grab-bag of 13 subpackages — but in 2026 the only question that matters is: which parts has scikit-learn absorbed, and which parts are still the only game in town? Market-basket mining, decision-region plots, bias-variance decomposition and the model-comparison hypothesis tests have no sklearn equivalent. Most of the rest does. This sheet is organised around exactly that split.

foundations & the overlap map frequent patterns — market basket feature selection ensembles & stacking evaluate & plot trap most common

Distilled & cross-checked against: rasbt.github.io/mlxtend (official API docs + User Guide, v0.25) · github.com/rasbt/mlxtend (source & CHANGELOG) · scikit-learn.org · source papers (Agrawal 1994 · Han 2000 · Dietterich 1998) · re-verified 2026-08-28 against mlxtend 0.25.0 (6 Jun 2026; requires Python ≥ 3.11, sklearn ≥ 1.4)

The only map you need — what's still unique vs. what scikit-learn absorbed
STILL INDISPENSABLE — NO SKLEARN EQUIVALENT SUPERSEDED — PREFER SKLEARN mlxtend 13 subpackages v0.25 pip install mlxtend frequent_patterns apriori · fpgrowth · fpmax · hmine · association_rules plotting.plot_decision_regions the single most-used function in the library evaluate — model comparison mcnemar · paired_ttest_5x2cv · cochrans_q · bootstrap_.632 evaluate.bias_variance_decomp decompose test error into bias² + variance SFS — the FLOATING variants SFFS / SBFS · sklearn has no floating option StackingCVClassifier / Regressor → sklearn.ensemble.StackingClassifier (0.22+) EnsembleVoteClassifier → sklearn.ensemble.VotingClassifier SFS — the non-floating variants → sklearn.feature_selection.SequentialFeatureSelector PCA · LDA · Kmeans · LogisticRegression → educational reimplementations. Use sklearn's. plot_confusion_matrix → sklearn.metrics.ConfusionMatrixDisplay mlxtend.image — REMOVED dropped entirely (dlib support). Don't import it. IMPORT these and only these mlxtend earns its place in ~5 imports. The rest is history you can skip. Its educational estimators taught a generation — but they were never meant for production.

Foundations & the overlap verdict

mlxtend predates half of modern scikit-learn. Knowing which half saves you from importing a slower, less-maintained version of something you already have.

01Install & the Subpackages13 modules
  • pip install mlxtend # or conda -c conda-forge
    Pulls numpy, scipy, pandas, scikit-learn, matplotlib, joblib.
  • from mlxtend.frequent_patterns import apriori, fpgrowth, fpmax, hmine, association_rules
    The flagship. Market-basket mining. No sklearn equivalent, and none coming.
  • from mlxtend.preprocessing import TransactionEncoder
    Turns a list-of-lists of transactions into the boolean matrix the miners require. Also here: standardize, minmax_scaling, DenseTransformer.
  • from mlxtend.plotting import plot_decision_regions
    Probably the single most-used line in the library. Plus heatmap, scatterplotmatrix, ecdf, plot_learning_curves, plot_pca_correlation_graph.
  • from mlxtend.evaluate import bias_variance_decomp, mcnemar, paired_ttest_5x2cv
    The statistics module sklearn never shipped. Cards 10–11.
  • from mlxtend.feature_selection import SequentialFeatureSelector, ExhaustiveFeatureSelector, ColumnSelector
    Worth it only for the floating variants — card 07.
  • from mlxtend.data import iris_data, wine_data, mnist_data
    Toy datasets. Also: classifier, regressor, cluster, feature_extraction, text, file_io, math, utils.
  • from mlxtend.image import extract_face_landmarksremoved
    mlxtend.image was deleted (dlib no longer builds cleanly). Any tutorial using it is stale.
02Do You Still Need mlxtend?the honest audit
Written in 2014, when sklearn had no stacking, no sequential selection and no decision-region plots. Most of that gap has closed. Here's what's left.
Keep using mlxtendUse sklearn instead
frequent_patterns — the whole module. Nothing else in the ecosystem does this as cleanly. StackingClassifier / StackingRegressor — sklearn's are CV-safe, maintained, and pipeline-native.
plot_decision_regions — still unmatched for teaching and debugging. VotingClassifier — same idea as EnsembleVoteClassifier, better supported.
bias_variance_decomp — the only easy way to actually measure the tradeoff. SequentialFeatureSelectorunless you need floating=True, which sklearn lacks.
mcnemar · paired_ttest_5x2cv · cochrans_q — "is model A significantly better?" PCA, LDA, KMeans, LogisticRegression — mlxtend's are teaching code.
bootstrap_point632_score · lift_score · create_counterfactual ConfusionMatrixDisplay, LearningCurveDisplay — native plotting now exists.
The verdict: mlxtend is no longer a framework — it's a toolbox of four or five things sklearn still doesn't do. Import those, ignore the rest, and you'll never be bitten by a stale tutorial.
03Adaline · Perceptron · SoftmaxRegressionteaching code, not tools
These exist because they're the worked examples from Raschka's Python Machine Learning. They are excellent for understanding gradient descent — and a poor choice for anything you ship.
  • from mlxtend.classifier import Adaline, Perceptron, MultiLayerPerceptron, SoftmaxRegression
    Readable, hackable, plottable. minibatches, eta, epochs — all exposed so you can watch them converge.
  • from mlxtend.classifier import OneRClassifier
    Genuinely useful: the "one rule" classifier — picks the single best feature and thresholds it. A legitimate interpretable baseline. If your deep model can't beat OneR, something is wrong.
  • mlxtend.classifier.LogisticRegression()use sklearn
    No regularisation options, no solvers, no multiclass strategies. It's a lesson, not a library.

Frequent patterns — market basket analysis

The reason most people install mlxtend. Three steps, always: transactions → boolean matrix → frequent itemsets → rules. Get the boolean matrix wrong and everything downstream silently misbehaves.

04TransactionEncoderstep 1 — the boolean matrix
The miners do not take a list of baskets. They take a one-hot boolean DataFrame — one row per transaction, one column per item.
  • dataset = [['Milk', 'Eggs'], ['Milk', 'Beer'], …]

    te = TransactionEncoder()
    ary = te.fit(dataset).transform(dataset)
    df = pd.DataFrame(ary, columns=te.columns_)
    Memorise this four-liner. te.columns_ holds the item vocabulary, in sorted order.
  • te.transform(dataset, sparse=True)
    pd.DataFrame.sparse.from_spmatrix(...)
    For large vocabularies. All four miners accept sparse DataFrames.
  • te.inverse_transform(ary)
    Boolean matrix back to lists of items.
  • # values must be bool or 0/1ValueError
    Passing counts (a quantity of 3) raises ValueError in current mlxtend (older versions only warned, then silently misbehaved — worse). Binarise first: df = df > 0. The old pandas SparseDataFrame has been unsupported since 0.17.2.
05The Four Minersstep 2 — frequent itemsets
Same signature, same output, wildly different speed. All return a DataFrame of ['support', 'itemsets'], where each itemset is a frozenset.
  • fpgrowth(df, min_support=0.6, use_colnames=True)
    The default choice. Builds an FP-tree — no candidate generation, so it's dramatically faster than apriori on anything real. Same results, always.
  • apriori(df, min_support=0.6, use_colnames=True, max_len=3, low_memory=True)
    The classic. Exponential candidate generation — fine for teaching, painful past a few hundred items. max_len caps itemset size (a big speedup); low_memory trades speed for RAM.
  • fpmax(df, min_support=0.6, use_colnames=True)
    Returns only maximal itemsets — those with no frequent superset. A much smaller, non-redundant result set. But its output is generally unsuitable for association_rules, which needs the subset supports.
  • hmine(df, min_support=0.6, use_colnames=True)
    H-Mine. Newer addition; can beat FP-Growth on sparse data.
  • use_colnames=False # the default!gotcha
    You get column indicesfrozenset({3, 7}) — instead of item names. Almost never what you want. Always pass use_colnames=True.
  • min_support=0.01 # on 10k itemshangs
    Support is a fraction, not a count. Set it too low and the itemset count explodes combinatorially. Start high (0.5), lower gradually, and cap max_len.
06association_rulesstep 3 — the rules
Turns frequent itemsets into A → C implications, scored by a dozen interestingness metrics.
  • rules = association_rules(
      frequent_itemsets,
      metric="lift",
      min_threshold=1.2)
    Default metric is "confidence" at 0.8. Filter on lift, sort by confidence is the usual idiom.
  • rules[rules['antecedents'].apply(len) == 1]
    antecedents/consequents are frozensets, so filter with apply(len) or >= set operations — not string matching.
  • return_metrics=['support', 'confidence', 'lift']
    Only compute what you need — the default computes all twelve.
  • support_only=True
    For cropped/incomplete itemset frames where subset supports are missing. Fills the other metrics with NaN.
  • TypeError: association_rules() missing 1 required
    positional argument: 'num_itemsets'
    v0.23.2
    A real regression that broke every existing script. Fixed in later releases (num_itemsets is now optional, default 1). If you hit it: upgrade, or pass num_itemsets=1.
  • fpmax(...) association_rules(...)wrong
    Maximal itemsets omit their own subsets — so support(A) is missing and confidence can't be computed correctly. Use apriori or fpgrowth for rule mining.
07Reading the Metricswhat "interesting" means
Given A → C. The independence baseline is the thing to anchor on — a rule is only interesting if it beats chance.
MetricFormula & reading
supportsupp(A∪C) · [0,1]
How often the rule fires at all. Frequency, not strength.
confidencesupp(A∪C) / supp(A) · [0,1]
P(C | A). Directional — conf(A→C) ≠ conf(C→A).
liftconf(A→C) / supp(C) · [0,∞]
= 1 → independent. >1 positive association, <1 negative. The one to filter on.
leveragesupp(A∪C) − supp(A)·supp(C) · [−1,1]
= 0 → independent. Lift's additive cousin; less inflated by rare items.
conviction(1−supp(C)) / (1−conf(A→C)) · [0,∞]
= 1 → independent; inf when confidence is 1.
zhangs_metric[−1,1] · measures association AND dissociation — the only one that cleanly flags "A actively suppresses C".
+ 6 morejaccard · certainty · kulczynski · representativity · antecedent/consequent support.
The classic mistake: sorting by confidence alone. A rule "→ Kidney Beans" can hit 100% confidence simply because everyone buys kidney beans. Lift ≈ 1 exposes it as worthless. Always check lift before you believe a rule.

The market-basket pipeline

Three transformations, and one interpretive trap. The lift panel is the part people skip — and it's the part that decides whether a rule means anything.

transactions → boolean matrix → itemsets → rules

Each step has a fixed shape. The miners never see your raw baskets — they only ever see the boolean matrix.

1 · raw baskets [['Milk','Eggs','Beer'],  ['Milk','Eggs'],  ['Milk','Beer'],  ['Eggs','Beer']] list of lists · ragged TE 2 · boolean matrix Beer Eggs Milk True True True False True True True False True True True False must be bool / 0-1 fpgrowth 3 · frequent itemsets support itemsets 0.75 (Milk) 0.75 (Eggs) 0.75 (Beer) 0.50 (Milk, Eggs) itemsets are frozensets rules 4 · association rules A → C conf lift Milk → Eggs 0.67 0.89 Eggs → Milk 0.67 0.89 Beer → Eggs 0.67 0.89 lift < 1 → all worthless! FILTER ON LIFT not confidence apriori · fpgrowth · hmine all produce step 3 identically — fpmax does NOT (it drops subsets, breaking step 4)

✗ high confidence, useless rule

Kidney Beans appear in every basket. So anything → Kidney Beans scores 100% confidence — and tells you precisely nothing.

Rule: Onion → Kidney Beans confidence 1.00 supp(Beans) 1.00 lift = 1.00 / 1.00 = 1.00 → INDEPENDENT Buying onions tells you nothing about beans. Everyone buys beans.

✓ modest confidence, real signal

Lower confidence — but the consequent is rare, so co-occurrence is far above chance. This is the rule worth acting on.

Rule: Diapers → Beer confidence 0.60 supp(Beer) 0.20 lift = 0.60 / 0.20 = 3.00 → 3× ABOVE CHANCE Diaper buyers are 3× more likely to buy beer — a shelf-layout decision.

Feature selection & ensembles

Both areas sklearn has largely caught up on — with one exception each that keeps mlxtend on the shelf: floating selection, and the get_metric_dict() introspection that makes SFS actually plottable.

08SequentialFeatureSelectorfour algorithms, two flags
Two booleans give you four classical algorithms. This 2×2 is the whole API — see the diagram below.
  • sfs = SFS(knn,
      k_features=4,
      forward=True, floating=False,
      scoring='accuracy', cv=5)
    sfs.fit(X, y)
    SFS — greedily add the best feature, one at a time.
  • forward=True, floating=True # SFFS
    The reason to use mlxtend here. After each addition, try removing already-selected features — this escapes the "nesting effect", where a feature added early becomes redundant later but can never be dropped. sklearn has no floating option.
  • k_features=(3, 8) # or 'best' / 'parsimonious'
    A range → evaluates every size in it and keeps the best. 'best' → highest CV score at any size. 'parsimonious'smallest subset within one std-err of the best. Also not in sklearn.
  • sfs.k_feature_names_ · sfs.k_score_ · sfs.subsets_
    sfs.get_metric_dict()
    Full history of every subset tried, with CV mean/std/CI. Feed it straight to plot_sequential_feature_selection.
  • ExhaustiveFeatureSelector(clf, min_features=1, max_features=4)
    Tries every combination. Guaranteed optimal, combinatorially explosive — 2ⁿ−1 subsets. Fine below ~15 features; never above.
  • # SFS wraps a model and cross-validates. It is SLOW.cost
    SFS on d features fits roughly d²/2 × cv models. Use n_jobs=-1, and prefer a cheap estimator inside the wrapper.
09Stacking & Votingmostly superseded
mlxtend pioneered these — and then sklearn shipped its own. Prefer sklearn's unless you need a niche flag. Included here because the CV distinction is still worth understanding.
  • StackingCVClassifier(classifiers=[clf1, clf2],
      meta_classifier=lr, cv=5,
      use_probas=True)
    The CV variant is the correct one. Meta-features come from out-of-fold predictions, so the meta-learner never sees predictions the base models made on their own training data.
  • StackingClassifier(...) # the NON-CV oneoverfits
    Trains the meta-learner on predictions the base models made on the data they were fit on. Those predictions are optimistically good, so the meta-learner learns to trust an overfit base model. Use StackingCVClassifier, or sklearn's StackingClassifier (which cross-fits by default).
  • use_probas=True · use_features_in_secondary=True
    Feed the meta-learner probabilities rather than hard labels (usually better), and optionally the original features too.
  • EnsembleVoteClassifier(clfs=[c1, c2, c3],
      weights=[2, 1, 1], voting='soft')
    use sklearn
    'soft' averages probabilities, 'hard' takes the majority label. Functionally VotingClassifier. Its one edge: fit_base_estimators=False lets you ensemble pre-fitted models.
  • StackingCVRegressor(regressors=[...], meta_regressor=ridge)
    The regression twin. Same CV logic, same advice.
10plot_decision_regionsthe famous one
One line, any sklearn-compatible classifier, and you can see what your model learned. Nothing else does this as painlessly.
  • plot_decision_regions(X, y, clf=model, legend=2)
    X must be a numpy array (not a DataFrame — pass X.values), y must be integer labels.
  • # it only plots TWO dimensions2-D only
    With >2 features you must pin the rest:
    feature_index=[0, 2]
    filler_feature_values={1: val, 3: val}
    filler_feature_ranges={1: rng, 3: rng}
    The plot then shows a 2-D slice through a higher-dimensional boundary — not the boundary itself. Read it accordingly.
  • X_highlight=X_test · n_jobs=-1
    Circle the test points; parallelise the meshgrid (a real speedup on slow models like SVC).
  • plot_learning_curves(X_tr, y_tr, X_te, y_te, clf)
    plot_sequential_feature_selection(sfs.get_metric_dict(), kind='std_err')
    Train/test error vs training-set size; and CV score vs number of features, with error bars.
  • heatmap · scatterplotmatrix · ecdf · plot_pca_correlation_graph · checkerboard_plot
    The rest of the plotting grab-bag. Handy, though seaborn covers most of it.

Evaluate — the statistics sklearn never shipped

"Model A got 94%, model B got 93%." Is that a real difference, or noise? sklearn will not answer this for you. mlxtend will — and the choice of test matters, because the obvious ones have badly inflated false-positive rates.

11Is A Really Better Than B?pick the right test
SituationTest
2 models, 1 test set
(models already fitted)
mcnemar_table()mcnemar()
Compares the disagreements only. Cheap — no refitting.
2 models, can refitpaired_ttest_5x2cv()
Dietterich's recommendation. The best power/Type-I tradeoff.
3+ models, 1 test setcochrans_q()
An omnibus test. If significant, follow up with pairwise McNemar.
Any statistic, no assumptionspermutation_test() · bootstrap()
  • tb = mcnemar_table(y_target=y_test, y_model1=p1, y_model2=p2)
    chi2, p = mcnemar(ary=tb, corrected=True)
    Use exact=True when the off-diagonal counts are small (< 25).
  • t, p = paired_ttest_5x2cv(estimator1=clf1, estimator2=clf2, X=X, y=y, scoring='accuracy')
    5 repetitions of 2-fold CV. The default recommendation when you can afford to refit.
  • paired_ttest_kfold_cv · paired_ttest_resampledinflated α
    Both violate the independence assumption — training sets overlap across folds — so they report "significant" far more often than they should. mlxtend ships them for completeness; prefer 5×2cv.
12bias_variance_decompmeasure the tradeoff
Everyone talks about the bias-variance tradeoff. This function actually measures it, by bootstrapping the training set and decomposing expected test loss.
  • avg_loss, avg_bias, avg_var = bias_variance_decomp(
      estimator, X_train, y_train, X_test, y_test,
      loss='0-1_loss', num_rounds=200, random_seed=1)
    loss='mse' for regression, where the identity loss = bias² + variance holds exactly. For '0-1_loss' the decomposition is the Kong–Dietterich version and is not a clean sum.
  • # the diagnosis
    High bias, low variance → underfitting. More capacity, better features.
    Low bias, high variance → overfitting. Regularise, prune, bag, get more data.
    This turns "my model is bad" into an actionable statement.
  • bootstrap_point632_score(clf, X, y, method='.632+')
    The .632+ bootstrap — a low-variance accuracy estimate that corrects the optimism of resubstitution. Excellent on small datasets where k-fold CV is itself noisy.
  • feature_importance_permutation(predict_method=clf.predict, X=X_te, y=y_te, metric='accuracy', num_rounds=10)
    Model-agnostic permutation importance. sklearn has this as permutation_importance — prefer that one.
  • lift_score(y_target, y_pred) · create_counterfactual(...)
    Lift for classification (marketing/response models), and a simple counterfactual generator for explainability.
13Trapsthe whole list
  • apriori(df) # df holds counts, not booleans
    Raises ValueError. Binarise: df = df > 0.
  • use_colnames=False # the default
    You get integer indices instead of item names. Always set it True.
  • fpmax(...) → association_rules(...)
    Maximal itemsets drop their subsets, so confidence can't be computed. Use fpgrowth.
  • sorting rules by confidence
    Check lift. A universally-bought consequent gives 100% confidence and zero information.
  • plot_decision_regions(X_4d, y, clf)
    Raises. It's 2-D only — pass feature_index + filler_feature_values, and remember you're seeing a slice.
  • StackingClassifier # the non-CV one
    Leaks base-model overfitting into the meta-learner. Use the CV variant.
  • paired_ttest_kfold_cv
    Inflated Type-I error. Use paired_ttest_5x2cv.
  • TypeError: … missing 'num_itemsets'
    The 0.23.2 association_rules regression. Upgrade.
  • from mlxtend.image import …
    Module removed. The tutorial you're reading is out of date.

Two mechanisms worth picturing

The SFS 2×2 is the entire feature-selection API. The stacking panel shows why the CV variant is the only one you should use.

SFS — two flags, four algorithms

Floating is the reason to prefer mlxtend over sklearn here: after each step it back-checks whether an earlier choice has become redundant.

floating=False floating=True forward=True forward=False SFS start empty · add best ∅ → {a} → {a,b} → … sklearn has this SFFS add best, then try removing escapes the nesting effect ★ mlxtend only SBS start full · drop worst {a,b,c} → {a,c} → … sklearn has this SBFS drop worst, then try re-adding best quality · slowest ★ mlxtend only

Stacking — why the CV matters

The meta-learner must be trained on predictions the base models made on data they never saw. Otherwise it learns to trust an overfit base model.

✗ StackingClassifier base fit(X) predict(X) same X — in-sample! predictions look too good ✓ StackingCVClassifier fold 1 fit fold 2 fit fold k fit out-of-fold predictions each row predicted by a model that never saw it meta_classifier sklearn's StackingClassifier cross-fits by default — it's the CV one.

Decision map

Start from what you actually want to do. Most branches end at "use sklearn" — and that's the point of the sheet.

market basket /
association rules
see the decision
boundary
is model A really
better than B?
yes
no — already fitted
3+ models
underfitting or
overfitting
select features
yes — SFFS / SBFS
no
stacking /
voting
PCA / LDA /
KMeans / LogReg
What do you
want to do?
Task?
TransactionEncoder
→ fpgrowth
→ association_rules
Filter on LIFT,
not confidence
plot_decision_regions
2-D only!
Can you
refit?
paired_ttest_5x2cv
mcnemar_table
→ mcnemar
cochrans_q
bias_variance_decomp
Need floating?
mlxtend SFS
floating=True
sklearn
SequentialFeatureSelector
sklearn
StackingClassifier
VotingClassifier
sklearn.
mlxtend's are
teaching code
Ship it

Worth memorizing

TransactionEncoder 4-linerte.fit(data).transform(data)pd.DataFrame(ary, columns=te.columns_)
use_colnames=Truealways — the default gives you column indices, not item names
fpgrowth > apriorisame results, no candidate generation, dramatically faster
fpmax ✗ association_rulesmaximal itemsets drop their subsets → confidence can't be computed
lift = 1 → independentfilter rules on lift; confidence alone flatters universally-bought items
boolean matrix onlycounts raise ValueError in the miners — df = df > 0
plot_decision_regions is 2-D>2 features → feature_index + filler_feature_values, and you're seeing a slice
floating=TrueSFFS/SBFS — the one thing sklearn's SequentialFeatureSelector can't do
k_features='parsimonious'smallest subset within 1 std-err of the best score
StackingCV, not Stackingthe non-CV variant trains the meta-learner on in-sample predictions
paired_ttest_5x2cvDietterich's pick · paired_ttest_kfold_cv has inflated Type-I error
mcnemar for fitted modelscompares disagreements on one test set — no refitting needed
bias_variance_decomphigh bias → underfit · high variance → overfit · mse sums exactly, 0-1_loss doesn't
.632+ bootstraplow-variance accuracy estimate — shines on small datasets
mlxtend.image is GONEremoved entirely · any tutorial using it is stale
~5 imports justify itfrequent_patterns · plot_decision_regions · evaluate · floating SFS. Rest → sklearn.