scikit-learn的PCA转换返回了错误的降维特征长度。

3

我尝试在我的代码中应用PCA,当我使用以下代码训练我的数据时:

def gather_train():
    train_data = np.array([])
    train_labels = np.array([])
    with open(training_info, "r") as traincsv:
        for line in traincsv:
            current_image = "train\\{}".format(line.strip().split(",")[0])
            print "Reading data from: {}".format(current_image)
            train_labels = np.append(train_labels, int(line.strip().split(",")[1]))
            with open(current_image, "rb") as img:
                train_data = np.append(train_data, np.fromfile(img, dtype=np.uint8).reshape(-1, 784)/255.0)
    train_data = train_data.reshape(len(train_labels), 784)
    return train_data, train_labels

def get_PCA_train(data):
    print "\nFitting PCA. Components: {} ...".format(PCA_components)
    pca = decomposition.PCA(n_components=PCA_components).fit(data)
    print "\nReducing data to {} components ...".format(PCA_components)
    data_reduced = pca.fit_transform(data)
    return data_reduced

def get_PCA_test(data):
    print "\nFitting PCA. Components: {} ...".format(PCA_components)
    pca = decomposition.PCA(n_components=PCA_components).fit(data)
    print "\nReducing data to {} components ...".format(PCA_components)
    data_reduced = pca.transform(data)
    return data_reduced

def gather_test(imgfile):
    #input is a file, and reads data from it. different from gather_train which gathers all at once
    with open(imgfile, "rb") as img:
        return np.fromfile(img, dtype=np.uint8,).reshape(-1, 784)/255.0

...

train_data = gather_train()
train_data_reduced = get_PCA_train(train_data)
print train_data.ndim, train_data.shape
print train_data_reduced.ndim, train_data_reduced.shape

它会打印预期的 ff,如下所示:
2 (1000L, 784L)
2 (1000L, 300L)

但当我开始缩减我的测试数据时:

test_data = gather_test(image_file)
# image_file is 784 bytes (28x28) of pixel values; 1 byte = 1 pixel value
test_data_reduced = get_PCA_test(test_data)
print test_data.ndim, test_data.shape
print test_data_reduced.ndim, test_data_reduced.shape

输出结果为:
2 (1L, 784L)
2 (1L, 1L)

导致后面出现错误的原因是:

ValueError: X.shape[1] = 1 应该等于300,即训练时的特征数

为什么 test_data_reduced 的形状是 (1,1) 而不是 (1,300)?我已经尝试只对训练数据使用 fit_transform,对测试数据只使用 transform,但仍然出现相同的错误。


1
你的数据长什么样?能否发一些模拟图? 但是你正在错误地应用PCA,你应该在训练数据上进行fit_transform,然后只转换测试数据。当你在测试数据上重新拟合时,本质上是忽略了你的训练数据。此外,你应该发布更完整的代码-你如何定义train_data和test_data呢? - flyingmeatball
@flyingmeatball 我已经添加了更多的代码。这里的流程是train_datatest_data相似,只是test_data是单个条目。 - jowabels
我在train_data上使用了fit_transform,在test_data上使用了transform,但仍然出现相同的错误。 - jowabels
但是在transform的两行之前,您仍然需要使用training数据来fit test数据。 - sietschie
很高兴能够帮忙。我将评论转换为答案,以便问题可以关闭。 - sietschie
显示剩余2条评论
1个回答

1

调用 PCA 的代码应该大致如下:

pca = decomposition.PCA(n_components=PCA_components).fit(train_data)
data_reduced = pca.transform(test_data)

首先在训练数据上调用fit,然后在测试数据上调用transform,以实现降维。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接