Main Ecosystems
HomePython CorePandas ReferenceNumPy ScientificFastAPI & PydanticDjango Enterprise
More Ecosystems
Environment & SetupRequests & HTTPAsyncIO ConcurrencyObject-Oriented OOPPyTorch Deep LearningScikit-Learn MLFlask FrameworkWeb ScrapingDatabase & ORMDevOps & Docker

ValueError: could not convert string to float in Scikit-Learn

Verified FixPython 3.10+Scikit-Learn 1.4+Silo: scikit-learn

Quick Fix / Solution Rapide

Transform categorical string features into numerical arrays using OneHotEncoder or OrdinalEncoder within a ColumnTransformer.

Root Cause Analysis

This error occurs when Python tries to train a Scikit-Learn estimator on a feature matrix containing raw text strings that cannot be implicitly converted into floating-point numbers.

1. Scikit-Learn Numeric Input Contract

Scikit-Learn algorithms expect numerical feature matrices X of numeric dtypes (such as float64 or float32). When estimator.fit(X, y) is called, Scikit-Learn converts inputs using check_array(X, dtype=np.float64). If any column contains text strings like 'high', 'France', or 'Male', the conversion raises ValueError: could not convert string to float: 'high'.

2. Common Causes in Tabular Datasets

This error arises when: (1) unencoded categorical columns are passed directly to model.fit(); (2) numeric columns contain currency symbols or commas (e.g. '$1,200'); or (3) header row names are accidentally included as data rows.

3. Resolving Categorical Columns

Apply OneHotEncoder (for nominal data) or OrdinalEncoder (for ordinal rankings) to transform categorical strings into valid numeric feature matrices.

4. Structuring Pipelines with ColumnTransformer

Use ColumnTransformer to apply StandardScaler to numerical columns and OneHotEncoder to categorical columns in a single, leak-free pipeline.

Reproduction Code (MCVE)

Example: Bug Reproduction
import numpy as np
from sklearn.ensemble import RandomForestClassifier

# Feature matrix with unencoded categorical string 'high'
X = np.array([[10.0, 'high'], [20.0, 'low'], [30.0, 'medium']], dtype=object)
y = np.array([0, 1, 0])

# ValueError: could not convert string to float: 'high'
clf = RandomForestClassifier(random_state=42)
clf.fit(X, y)

Solution 1: Transform Categorical Columns with OrdinalEncoder

Encode string columns into numeric integers using OrdinalEncoder before passing features to the estimator.

Example: Recommended Solution
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import OrdinalEncoder

X_raw = np.array([[10.0, 'high'], [20.0, 'low'], [30.0, 'medium']], dtype=object)
y = np.array([0, 1, 0])

# Encode categorical column (index 1)
encoder = OrdinalEncoder()
X_encoded = X_raw.copy()
X_encoded[:, 1] = encoder.fit_transform(X_raw[:, [1]]).ravel()
X_numeric = X_encoded.astype(float)

clf = RandomForestClassifier(random_state=42)
clf.fit(X_numeric, y)
print('Model fitted successfully. Feature importances:', clf.feature_importances_)

Solution 2: Use ColumnTransformer with OneHotEncoder

Build a modular ColumnTransformer that handles numeric scaling and one-hot encoding simultaneously.

Example: Alternative Solution
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline

df = pd.DataFrame({
    'age': [25, 45, 35],
    'tier': ['silver', 'gold', 'bronze'],
    'target': [0, 1, 0]
})
X = df[['age', 'tier']]
y = df['target']

preprocessor = ColumnTransformer(transformers=[
    ('num', StandardScaler(), ['age']),
    ('cat', OneHotEncoder(sparse_output=False), ['tier'])
])

pipeline = Pipeline([
    ('pre', preprocessor),
    ('clf', LogisticRegression())
])
pipeline.fit(X, y)
print('Pipeline trained successfully.')

A common bug is calling pd.get_dummies() separately on train and test datasets, which leads to differing column sets if a category is missing in the test split. Always use sklearn.preprocessing.OneHotEncoder(handle_unknown='ignore') inside a Pipeline to ensure robust column alignment. Contrast this ValueError with ValueError: Unknown label type: 'unknown', which occurs on target vector y rather than feature matrix X. Sanitize currency and formatted string columns with .str.replace(',', '').astype(float) before preprocessing.