这是你的男孩。
我目前正在与scikit-learn FeatureUnion和Pipeline组合中的一些诡计苦苦挣扎。
1)我有功能和目标
的.csv数据2)另外,我有已加载并转换为np.arrays的np.array的图像数据
3)我已将它拆分为train(train_idx和img_train)并使用StratifiedShuffleSplit测试(test_idx和img_test)。
要调用.csv数据的列车特征,我输入train_idx [0],其形状为(792,192)。
要调用图像数据的列车特征,我输入img_train [0],其形状为(792,4816)。
作为目标的train_idx [1]和img_train [1]的相应形状是(792,)和(792,)
这里的任务是将PCA()应用于img_train并保留train_idx,然后将它们传递给RandomForestClassifier。首先,它们应该存储在np.matrix中。我的代码如下:
# define functions that pass columns of matrix to FeatureUnion
def select_col_idx(matrix, cols):
return X_train[:, cols]
def select_col_img(matrix, cols):
return X_train[:, cols]
A_train = np.matrix((train_idx[0].T, train_idx[1], img_train[0].T, img_train[1]))
A_train的形状为(1,4)。这很奇怪吗?
无论如何,下面的代码显示了我的管道:
subpipe = Pipeline([('caller', FunctionTransformer(select_col_img, validate=False, kw_args={'cols': [2, 3]})),
('pca', PCA(n_components=4, random_state=RANDOM_SEED))])
subpipe_2 = Pipeline([('caller', FunctionTransformer(select_col_idx, validate=False, kw_args={'cols': [0, 1]})),
('none', None)])
features = FeatureUnion([('subpipe', subpipe), ('subpipe2', subpipe_2)])
pipe = Pipeline([('features_union', features), ('rf', rf)])
然后,我尝试pipe.fit(A_train)
这不起作用。
说实话,我甚至不能适应subpipe.fit(A_train)
因为我收到'设置一个带序列的数组元素'错误。
我知道数据提取存在问题,但我花了好几个小时试图解决它。我甚至尝试在简单的np.array上执行相同的操作,而不是np.matrix,但仍然没有运气。
我感到筋疲力尽......
提前感谢您所有事情Q(^,^ Q)
P.S。我们真的需要python Class
来提取列吗?
发表编辑:
正如我已经写过的那样,subpipe.fit(A_train)
不起作用。错误的完整回溯如下:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/komplett/.local/lib/python3.6/site-
packages/sklearn/pipeline.py", line 270, in fit
self._final_estimator.fit(Xt, y, **fit_params)
File "/home/komplett/.local/lib/python3.6/site-
packages/sklearn/decomposition/pca.py", line 307, in fit
self._fit(X)
File "/home/komplett/.local/lib/python3.6/site-
packages/sklearn/decomposition/pca.py", line 346, in _fit
copy=self.copy)
File "/home/komplett/.local/lib/python3.6/site-
packages/sklearn/utils/validation.py", line 382, in check_array
array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: setting an array element with a sequence.
但是,我可以将第二个子管道设为subpipe_2.fit(A_train)
,这样可以完全正常拟合:
Pipeline(steps=[('caller', FunctionTransformer(accept_sparse=False,
func=<function select_col_idx at 0x7fc954345b70>,
inv_kw_args=None, inverse_func=None, kw_args={'cols': [0, 1]},
pass_y=False, validate=False)), ('none', None)])
后后编辑
好的,如果我执行X = select_col_idx(A_train, cols=[0, 1])
,它将返回两个矩阵的矩阵,其中X[:, 0]
是要素(train_idx [0] .T),X[:, 1]
是目标(train_idx [ 1])。请注意,[X.dtype == object]
为[true]
。
尽管如此,如果我尝试按下面提到的那样调整FunctionTransformer,我会收到上面的回溯错误,即带有'设置带序列的数组元素'的错误:
X = FunctionTransformer(select_col_img, kw_args={'cols': [2, 3]})
X.fit_transform(A_train)
# output is the traceback error
我使用'select_col_idx'函数收到同样的错误。
所以,我在想的是我需要修复提取方法。它应该将矩阵矩阵划分为两个不同的变量,它们作为 X 和 y 以任意方式传递给任何.fit,因为简单.fit( X)不起作用并返回'设置数组...'错误。对我来说似乎是'好'的逻辑,但它很麻烦。
为什么有人会告诉我首先将数据存储在np.matrix中!无论如何,是否可以修复此方法?
修改后的帖子
train_idx看起来像这样:
[array([[ 0.001953, 0. , 0. , ..., 0.010742, 0. ,
0.017578],
[ 0.003906, 0.005859, 0.074219, ..., 0.02832 , 0. ,
0.051758],
[ 0.013672, 0.005859, 0.019531, ..., 0. , 0.024414,
0.029297],
...,
[ 0.011719, 0.013672, 0.048828, ..., 0.017578, 0. ,
0.019531],
[ 0.027344, 0.044922, 0.009766, ..., 0. , 0.024414,
0.051758],
[ 0.046875, 0.10742 , 0.015625, ..., 0.008789, 0.006836, 0.
]]), array([ 4, 6, 56, 29, 94, 22, 94, 16, 0, 53, 87, 67, 51, 97, 5, 98, 44,
43, 66, 81, 80, 67, 42, 67, 40, 34, 91, 88, 0, 13, 53, 89, 32, 72,
22, 79, 26, 84, 79, 3, 25, 19, 87, 18, 48, 5, 2, 28, 66, 2, 83,
22, 10, 84, 58, 55, 76, 52, 3, 84, 44, 65, 9, 51, 9, 58, 52, 44, ... 6, 28, 25])]
img_train相同,但第一个数组如下所示:
[array([[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
...,
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
所以第一个train_idx数组是特征,第二个是目标。更确切地说,这些特征是树叶的宽度,边缘,长度等特征(据我所知)。目标是这种叶子的类别(它们的生物学名称)。 img_train的第一个数组是先前已经标准化的输入图像的像素。我已经加载了以下函数:
def load_img(path):
img_data = []
for i in range(1, 101):
flist = glob.glob(path + str(i) + '.png')
for j in flist:
img_data.append(scipy.misc.imread(j))
return np.array(img_data)
然后,我在img_data上应用了StratifiedShuffle。
再次感谢您的回复,Vivek!
答案 0 :(得分:0)
好。
在考虑了一些问题之后,我实际上想出了一个解决方案,但数据存储在np.array
中,而不是必需的np.matrix
格式。请注意rf = RandomForestClassifier()
:
A_train = np.array((train_idx[0].T, train_idx[1],
img_train[0].T, img_train[1]))
def select_train_cols(X_train, cols):
return X_train[cols].T
def megapipe():
subpipe = Pipeline(
[('caller', FunctionTransformer(select_train_cols, validate=False, kw_args={'cols': 0})),
('none', None)])
subpipe_2 = Pipeline(
[('caller', FunctionTransformer(select_train_cols, validate=False, kw_args={'cols': 2})),
('pca', pca)])
fu = FeatureUnion([('subpipe', subpipe),
('subpipe_2', subpipe_2)])
megapipe = Pipeline([('fu', fu),
('rf', rf)])
return megapipe
因此可以实现不会产生错误的megapipe.fit(A_train, train_idx[1])
!
似乎实施np.matrix
方法只是不切实际和不合适......或者至少我希望如此。
感谢。
<强>被修改强>
因此,使用np.concatenate()
实际上有一个解决方案:
A_train = np.concatenate((train_idx[0], img_train[0]), axis=1)
A_test = np.concatenate((test_idx[0], img_test[0]), axis=1)
def select_col_idx(X, col_idx=[1]):
return X[:, col_idx]
然后,您将致电FunctionTransformer
以获取 train_idx 数据,如下所示:
FunctionTransformer(select_col_idx, kw_args={'col_idx': np.arange(0, 192)}
要将PCA()
应用于 img_train ,您只需获取其余数据列,然后按照前面所述在管道中传递。
适合和预测适用于.fit(A_train, *labels)
和.predict(A_test, *labels)
从现在开始,这个主题可能被认为是多余的。
谢谢。