You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KNN分类器执行特征缩放后报ValueError: Unknown label type: 'continuous'

解决KNN特征缩放后出现ValueError的问题

问题背景

为提升KNN模型的准确率,尝试用MinMaxScaler执行特征缩放,但调用model.fit()训练模型时抛出ValueError,未执行特征缩放时模型可正常运行。

原代码

import pandas as pd
from sklearn.preprocessing import LabelEncoder
import sklearn
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import MinMaxScaler

path = "/content/cirrhosis.csv"
data = pd.read_csv(path)

data = data.loc[0:311]
data.head()

for col in data.columns:
  if data[col].dtype == 'int64' or data[col].dtype == 'float64':
    data[col].fillna(data[col].mean(), inplace=True)

  elif data[col].dtype == 'object':
    data[col].fillna(data[col].mode(), inplace=True)

label_encoder = LabelEncoder()
for column in data.columns:
    if data[column].dtype == 'object':
        data[column] = label_encoder.fit_transform(data[column])
print(data)

scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data)
data = pd.DataFrame(scaled_data, columns=data.columns)

inputs = data.drop(['ID', 'Stage'],axis=1)
output = data.drop(['ID', 'N_Days', 'Status', 'Drug', 'Age', 'Sex', 'Ascites', 'Hepatomegaly', 'Spiders', 'Edema', 'Bilirubin', 'Cholesterol', 'Albumin', 'Copper', 'Alk_Phos', 'SGOT', 'Tryglicerides', 'Platelets', 'Prothrombin'], axis=1)
print(inputs)
print(output)

x_train, x_test, y_train, y_test = train_test_split(inputs, output, train_size=0.8)

model =  KNeighborsClassifier(n_neighbors=31)
model.fit(x_train,y_train)
y_pred = model.predict(x_test)

报错信息

/usr/local/lib/python3.10/dist-packages/sklearn/neighbors/_classification.py:215: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples,), for example using ravel().
  return self._fit(X, y)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-73-f656e2af91bb> in <cell line: 2>()
      1 model =  KNeighborsClassifier(n_neighbors=31)
----> 2 model.fit(x_train,y_train)
      3 y_pred = model.predict(x_test)
      4 print(y_pred)
      5 print(y_test)

2 frames
/usr/local/lib/python3.10/dist-packages/sklearn/utils/multiclass.py in check_classification_targets(y)
    216         "multilabel-sequences",
    217     ]:
---> 218         raise ValueError("Unknown label type: %r" % y_type)
    219 
    220 

ValueError: Unknown label type: 'continuous'

错误原因分析

  1. 标签被错误缩放:你用MinMaxScaler对整个数据集(包括分类标签Stage列)做了缩放,导致原本是离散类别的标签变成了0-1之间的连续值。而KNeighborsClassifier是分类模型,要求标签必须是离散的类别,无法识别连续值标签,因此抛出Unknown label type: 'continuous'错误。
  2. 标签维度问题:output是DataFrame的单列,作为传入模型的标签是列向量形式,不符合sklearn分类模型要求的一维数组格式,因此触发DataConversionWarning。

修复方案

  • 仅对特征数据做缩放:拆分出特征(inputs)和标签(output)后,只对特征部分执行MinMaxScaler缩放,标签保持原始离散值不变。
  • 调整标签维度:将标签转换为一维数组,可通过ravel()方法实现。

修改后完整代码

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import MinMaxScaler

path = "/content/cirrhosis.csv"
data = pd.read_csv(path)

data = data.loc[0:311]

# 缺失值填充
for col in data.columns:
    if data[col].dtype in ['int64', 'float64']:
        data[col].fillna(data[col].mean(), inplace=True)
    elif data[col].dtype == 'object':
        data[col].fillna(data[col].mode()[0], inplace=True)  # 修正mode()返回Series的问题

# 类别特征编码
label_encoder = LabelEncoder()
for column in data.columns:
    if data[column].dtype == 'object':
        data[column] = label_encoder.fit_transform(data[column])

# 提前拆分特征和标签,避免标签被缩放
inputs = data.drop(['ID', 'Stage'], axis=1)
output = data['Stage']  # 直接提取单列,更简洁

# 仅对特征数据做缩放
scaler = MinMaxScaler()
inputs_scaled = scaler.fit_transform(inputs)
inputs = pd.DataFrame(inputs_scaled, columns=inputs.columns)

# 划分训练测试集
x_train, x_test, y_train, y_test = train_test_split(inputs, output, train_size=0.8)

# 训练模型,将标签转为一维数组
model = KNeighborsClassifier(n_neighbors=31)
model.fit(x_train, y_train.ravel())  # 使用ravel()转为一维数组

# 预测并评估
y_pred = model.predict(x_test)
print(f"准确率: {accuracy_score(y_test, y_pred)}")

额外说明

  • 原代码中data[col].fillna(data[col].mode(), inplace=True)存在小问题:mode()返回的是Series,直接填充会导致部分缺失值未被正确填充,修改为mode()[0]取第一个众数。
  • 提取标签时直接用data['Stage']比通过drop大量列更简洁且不易出错。

内容的提问来源于stack exchange,提问作者Akshay Basutkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:21:06