Features, samples and the shape of X and y

scikit-learn · Essentials · 8 min

Most beginner errors in scikit-learn are shape errors; knowing the convention prevents them.

scikit-learn expects data in a fixed layout. X is a 2-D array-like of shape (n_samples, n_features): one row per example, one column per feature. y is a 1-D array of shape (n_samples,) holding the target for each row: a class label for classification, a number for regression.

X can be a NumPy array, a pandas DataFrame or a SciPy sparse matrix. When you pass a DataFrame, the estimator remembers the column names in feature_names_in_ and warns if you later predict on data with different columns. y is usually a NumPy array or a pandas Series.

The most common error is passing a single feature as a 1-D array. model.fit(df["age"], y) fails with "Expected 2D array, got 1D array instead". Keep it 2-D:

  • df[["age"]] (double brackets) gives a one-column DataFrame,
  • x.reshape(-1, 1) turns a 1-D NumPy array into a column.

The reverse also happens: passing y as a one-column DataFrame or (n, 1) array triggers a DataConversionWarning; use df["target"] or y.ravel().

For prediction you always pass a 2-D X too, even for one sample: model.predict([[5.1, 3.5]]), not model.predict([5.1, 3.5]). All features must be numeric unless the estimator explicitly supports categories, which is why encoding is a separate step.

Example

import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression

df = pd.DataFrame({"area": [50, 80, 120, 65], "rooms": [2, 3, 4, 2],
                   "price": [150, 240, 350, 190]})
X = df[["area", "rooms"]]           # 2-D: (4, 2)
y = df["price"]                     # 1-D: (4,)
print(X.shape, y.shape)             # (4, 2) (4,)

model = LinearRegression().fit(X, y)
print(model.feature_names_in_)      # ['area' 'rooms']

new = pd.DataFrame({"area": [100], "rooms": [3]})
print(model.predict(new).round(1))  # [289.2]

area = np.array([50, 80, 120, 65])
print(area.reshape(-1, 1).shape)    # (4, 1) - a single feature, still 2-D

Remember

  • X is 2-D (n_samples, n_features), y is 1-D (n_samples,)
  • Use df[["col"]] or reshape(-1, 1) for a single feature
  • Predict on 2-D input even for one row

Watch out for

  • Calling fit(df["col"], y) with a 1-D Series as X.

Check yourself

  1. You have a 1-D NumPy array `x` of 100 values as your only feature. What should you pass as X?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: scikit-learn.org/stable/getting_started.html