KMean和PCA连接

时间:2014-02-28 07:35:51

标签: java python c++ opencv pca

据我了解模式识别,PCA用于删除数据集中不必要的数据,这样当数据集将在KMean中使用时,它将执行的数据集少于不是PCA的数据集。所以,我可以使用这样的代码(伪代码):

 assign .csv to var DATA
 PCA_DATA = PCAcompute(DATA)
 result = Kmean(PCA_DATA)
 plotToGraph(result)

我说错了吗?

我一直在寻找导入csv的示例程序,然后在PCA上进行几乎一个月的聚类。我需要做的是使用虹膜数据集将Kmean结果的输出与PCA的Kmean结果进行比较。

2 个答案:

答案 0 :(得分:0)

我很难理解你的陈述。

首先,PCA是主成分分析。这是一个获取高维数据并试图找到数据(几乎)所在的低维(超)平面的过程。因此,它删除了不必要的维度。

使用KMean,您可能意味着k-means clustering。在低维空间中,它可以更快地运行 ,因此PCA是减少维数的可行方法。

(程序请求在Stack Overflow上偏离主题)

答案 1 :(得分:0)

我没有使用KMean,但我使用PCA进行神经网络训练数据以减少功能。它在OpenCV的C ++接口中。让我们从阅读csv文件开始。我的csv文件就像:

im_path_1;label1  
im_path_2;label2

所以要读取csv文件,我的函数:

void read_csv(const string& filename, vector& images, vector& labels, char separator = ';') 
{
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file) 
    {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(1, error_message);
    }
    string line, path, classlabel;
    while (getline(file, line)) 
    {
        stringstream liness(line);

        getline(liness, path, separator);
        getline(liness, classlabel);

        if(!path.empty() && !classlabel.empty()) 
        {
            Mat im = imread(path, 0);

            images.push_back(im);
            labels.push_back(atoi(classlabel.c_str()));
        }
    }
}

它在Mat变量的向量中保存数据。 OpenCV的PCA要求数据作为Mat变量中的行向量滚动。要做到这一点:

Mat rollVectortoMat(const vector<Mat> &data)
{
   Mat dst(static_cast<int>(data.size()), data[0].rows*data[0].cols, CV_32FC1);
   for(unsigned int i = 0; i < data.size(); i++)
   {
      Mat image_row = data[i].clone().reshape(1,1);
      Mat row_i = dst.row(i);                                       
      image_row.convertTo(row_i,CV_32FC1, 1/255.);
   }
   return dst;
}

此功能的简单用法:

int main()
{

    PCA pca;

    vector<Mat> images_train;
    vector<int> labels_train;

    read_csv("train1k.txt",images_train,labels_train);

    Mat rawTrainData = rollVectortoMat(images_train);   

    int pca_size = 500;

    Mat trainData(rawTrainData.rows, pca_size,rawTrainData.type());
    Mat testData(rawTestData.rows,pca_size,rawTestData.type());


    pca(rawTrainData,Mat(),CV_PCA_DATA_AS_ROW,pca_size);

    for(int i = 0; i < rawTrainData.rows ; i++)
        pca.project(rawTrainData.row(i),trainData.row(i));

    cout<<trainData.size()<<endl;

    return 0;
}

trainData变量是火车组的简化版本。对于pca_size变量;而不是将其用作500;您可以将pca提供给0.95以保留%95差异。我希望这有助于PCA部分。我用这个简化的数据来训练神经网络。