SKLearn ValueError:使用序列设置数组元素
Posted
技术标签:
【中文标题】SKLearn ValueError:使用序列设置数组元素【英文标题】:SKLearn ValueError: setting an array element with a sequence 【发布时间】:2019-11-20 15:10:22 【问题描述】:作为项目的一部分,我正在尝试使用 Python 的 SKLearn 库中的随机森林分类器。我一直使用本教程作为指导:https://chrisalbon.com/machine_learning/trees_and_forests/random_forest_classifier_example/.
我的代码逐行遵循本教程,但唯一的主要区别是数据的结构。在教程中,有 4 个特征(数据表中的 4 列),每列中的每个条目都是一个数字。在我的代码中,我有 1 个功能(数据表中的 1 列),列中的每个条目都是一个 numpy 数组。当我调用 fit() 函数时,出现以下错误: ValueError: 使用序列设置数组元素。
这是我的代码:
import pandas as pd
import numpy as np
import random
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import confusion_matrix
trainingData = [[[0, 0, 3], 0.77], [[24, 0, 5], 30], [[0, 0, 4], 0.77], [[0, 0, 0], 0.77]]
vectors_train = []
for i in range (0, len(trainingData)):
vectors_train.append(trainingData[i][0])
testingData = [[[1, 0, 0], 0.77], [[30, 0, 5], 30], [[0, 0, 0], 0.77], [[0, 0, 0], 0.77]]
vectors_test = []
for i in range (0, len(testingData)):
vectors_test.append(testingData[i][0])
dataframe_training = pd.DataFrame(trainingData)
dataframe_training['is_train'] = True
dataframe_testing = pd.DataFrame(testingData)
dataframe_testing['is_train'] = False
frames = [dataframe_training, dataframe_testing]
dataframe = pd.concat(frames)
dataframe.rename(index = str, columns = 0: 'Vector', 1: 'Label', 2: 'is_train')
train, test = dataframe[dataframe['is_train']==True], dataframe[dataframe['is_train']==False]
features = dataframe.columns[:1]
labels_train, uniques = pd.factorize(train[1], sort = True)
clf = RandomForestClassifier()
clf.fit(train[features], labels) # Value error occurs here
我对错误的实际含义感到困惑。什么数组元素被设置为一个序列,这个序列在哪里?我也知道train[features]
是一个DataFrame 对象,fit() 函数接受两个参数,这两个参数都必须是类数组。 labels
是一个数组,错误具体指向第一个参数是问题,所以我需要进行数据类型转换吗?
当我用clf.fit(vectors_train, labels)
替换行clf.fit(train[features], labels)
时,错误消失了。但是,我想知道为什么当我使用与教程相同的策略时它不起作用,以及如何让它以类似的方式工作。
任何帮助将不胜感激。谢谢!
【问题讨论】:
【参考方案1】:您遇到此错误是因为您调用fit
方法时数据的格式不正确。
您的输入是列表的 DataFrame(一列),但 fit
方法需要一个 numpy 数组。
如果你这样做,它应该可以工作:
X = np.array(train[features][0].tolist())
clf.fit(X, labels_train)
所以 X 是一个包含 4 个示例的数组,每个示例包含 3 个特征。
【讨论】:
谢谢,这行得通!作为一个快速的后续问题:假设我想添加另一个功能 - 量级。所以表格的第一列是我原始问题中的向量列,第二列是幅度(每个条目只是一个数字)。我是否必须添加另一行,如Y = np.array(train[features][1].tolist())
,我传递给 fit() 函数的第一个参数是什么?我尝试添加这一行并将 [X, Y] 传递给 fit(),但出现错误:ValueError: could not broadcast input array from shape (80,2) into shape (80).
如果 X 和 Y 都是特征矩阵,那么您需要将它们堆叠起来。因此,如果X
的形状为(n_examples, n_features_X)
而Y
的形状为(n_examples, n_features_Y)
,则需要创建一个形状为(n_examples, n_features_X+n_features_Y)
的新特征矩阵。例如,你可以只做Z = np.hstack([X,Y])
在我当前的代码中,X 的形状为 (80, ),Y 的形状为 (80, 2)。当我执行Z = np.hstack([X,Y])
时出现错误:ValueError:所有输入数组必须具有相同的维数。这是否意味着 n_features_X 必须与 hstack() 函数的 n_features_Y 值相同?
这是因为 X 是一维向量。 Z = np.hstack([X.reshape(-1,1),Y])
应该可以工作【参考方案2】:
删除features
变量并制作最后一行:
clf.fit(train[0].tolist(), labels)
上面的代码没有出现错误。
您的代码不起作用,因为 columns
和 column[:1]
一样返回一个包含一列的序列,但是 column[0]
不会,如果您将该 int 提供给 cls.fit
使用 train[features]
columns[0]
和 features
一样,它仍然不能工作,因为它需要一个列表或数组,所以 train[features].tolist()
也可以工作。
【讨论】:
这对我很有帮助,谢谢。即使我有一个 numpy 数组,但仍然需要像列表一样对待它。我实际上是在尝试将 word2vec 嵌入的平均值输入到引发此序列错误的分类器中。 这对我很有帮助,谢谢。即使我有一个 numpy 数组,但仍然需要像列表一样对待它。我实际上是在尝试将 word2vec 嵌入的平均值输入到引发此序列错误的分类器中。以上是关于SKLearn ValueError:使用序列设置数组元素的主要内容,如果未能解决你的问题,请参考以下文章
sklearn SVM fit() "ValueError: setting an array element with a sequence"