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)

上面的代码没有出现错误。

您的代码不起作用,因为 columnscolumn[: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"

了解 scikit-learn ValueError:由于数据形状而设置具有序列的数组元素

Python SVM 设置具有序列错误的数组元素

ValueError:使用序列设置数组元素

Python:ValueError:使用序列设置数组元素

sklearn(错误的输入形状)ValueError