Sklearn SGDClassifier调用.fit()报ValueError问题咨询
SGDClassifier训练报错"setting an array element with a sequence"问题解析
问题描述
训练Sklearn的SGDClassifier时,将数组类型的name和age作为输入特征预测color,调用.fit()方法时出现"setting an array element with a sequence"错误,但当name和age为单个元素而非数组时无报错。需明确该错误含义,以及SGDClassifier是否支持嵌套数组作为输入。
复现代码
from sklearn.model_selection import train_test_split import pandas as pd import numpy as np a=np.array([0, 2, 5, 2]) b=np.array( [0, 5, 0, 2]) c=np.array([2,2,0,0]) d=np.array([5,2,5,0]) age_a=np.array([5, 10, 7, 6]) age_b=np.array([3, 7, 11,8]) age_c=np.array([15, 10, 17, 2]) age_d=np.array([2, 8, 12,7]) data2={'name':[a,b,c,d],'age':[age_a, age_b, age_c, age_d],'color':[0,1,0,1]} new2 = pd.DataFrame.from_dict(data2) x = new2.loc[:, new2.columns != 'color'] y = new2.loc[:, 'color'] x=np.array(x,dtype=object) y=np.array(y) x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=42) from sklearn.linear_model import SGDClassifier sgd_clf=SGDClassifier(random_state=42) sgd_clf.fit(x_train, y_train) sgd_clf.predict(x_test)
报错信息
TypeError Traceback (most recent call last) TypeError: float() argument must be a string or a real number, not 'list' The above exception was the direct cause of the following exception: ValueError Traceback (most recent call last) Cell In[117], line 25 21 print(y_test) 24 clf = SGDClassifier(loss="hinge", penalty="l2", max_iter=5) 25 clf.fit(x_train, y_train) 26 #SGDClassifier(max_iter=100) 28 clf.predict([[2., 2.]]) ValueError: setting an array element with a sequence.
错误含义
这个错误的核心原因是:输入特征矩阵不符合Sklearn模型要求的标准二维数值数组格式。Sklearn期望输入的X是形状为[n_samples, n_features]的二维数组,其中每个元素都是单一的数值类型(如int、float)。而你的name和age列每个元素都是数组/序列,导致整个特征矩阵变成了嵌套的对象数组,模型无法将其转换为统一的数值矩阵,因此抛出错误。
SGDClassifier对输入的要求
SGDClassifier(以及所有Sklearn监督学习模型)不能直接接受嵌套数组作为输入特征。所有模型的输入特征必须是"扁平"的二维数值数组,每个样本对应一行,每个特征对应一列,且每个特征值为单个数值,不能是序列或数组。
解决方案
针对嵌套数组特征,有两种常见的处理方式:
1. 展开嵌套数组为多个特征
将每个嵌套数组中的元素拆分为单独的特征列,让特征矩阵变成标准的二维数值结构。示例代码如下:
from sklearn.model_selection import train_test_split import pandas as pd import numpy as np from sklearn.linear_model import SGDClassifier # 原始数据定义 a=np.array([0, 2, 5, 2]) b=np.array( [0, 5, 0, 2]) c=np.array([2,2,0,0]) d=np.array([5,2,5,0]) age_a=np.array([5, 10, 7, 6]) age_b=np.array([3, 7, 11,8]) age_c=np.array([15, 10, 17, 2]) age_d=np.array([2, 8, 12,7]) data2={'name':[a,b,c,d],'age':[age_a, age_b, age_c, age_d],'color':[0,1,0,1]} new2 = pd.DataFrame.from_dict(data2) # 展开name数组为4个特征列 new2['name_0'] = new2['name'].apply(lambda x: x[0]) new2['name_1'] = new2['name'].apply(lambda x: x[1]) new2['name_2'] = new2['name'].apply(lambda x: x[2]) new2['name_3'] = new2['name'].apply(lambda x: x[3]) # 展开age数组为4个特征列 new2['age_0'] = new2['age'].apply(lambda x: x[0]) new2['age_1'] = new2['age'].apply(lambda x: x[1]) new2['age_2'] = new2['age'].apply(lambda x: x[2]) new2['age_3'] = new2['age'].apply(lambda x: x[3]) # 选择展开后的特征,丢弃原始嵌套列 x = new2.drop(['color', 'name', 'age'], axis=1) y = new2['color'] # 拆分数据集并训练 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=42) sgd_clf=SGDClassifier(random_state=42) sgd_clf.fit(x_train, y_train) print(sgd_clf.predict(x_test))
2. 提取嵌套数组的统计特征
如果不需要保留嵌套数组的每个元素,可以提取数组的统计量(如均值、最大值、最小值、方差等)作为单个特征。示例代码如下:
from sklearn.model_selection import train_test_split import pandas as pd import numpy as np from sklearn.linear_model import SGDClassifier # 原始数据定义 a=np.array([0, 2, 5, 2]) b=np.array( [0, 5, 0, 2]) c=np.array([2,2,0,0]) d=np.array([5,2,5,0]) age_a=np.array([5, 10, 7, 6]) age_b=np.array([3, 7, 11,8]) age_c=np.array([15, 10, 17, 2]) age_d=np.array([2, 8, 12,7]) data2={'name':[a,b,c,d],'age':[age_a, age_b, age_c, age_d],'color':[0,1,0,1]} new2 = pd.DataFrame.from_dict(data2) # 提取name数组的统计特征 new2['name_mean'] = new2['name'].apply(lambda x: np.mean(x)) new2['name_max'] = new2['name'].apply(lambda x: np.max(x)) new2['name_min'] = new2['name'].apply(lambda x: np.min(x)) # 提取age数组的统计特征 new2['age_mean'] = new2['age'].apply(lambda x: np.mean(x)) new2['age_std'] = new2['age'].apply(lambda x: np.std(x)) new2['age_median'] = new2['age'].apply(lambda x: np.median(x)) # 选择统计特征,丢弃原始嵌套列 x = new2.drop(['color', 'name', 'age'], axis=1) y = new2['color'] # 拆分数据集并训练 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=42) sgd_clf=SGDClassifier(random_state=42) sgd_clf.fit(x_train, y_train) print(sgd_clf.predict(x_test))
内容的提问来源于stack exchange,提问作者Ash Ketchump
相关产品推荐
相关产品推荐

