Beispiel #1
0
void PCA<T>::InitFromPointMatrix(DenseMatrix<T> &B)
{
    const UINT PointCount = B.ColCount();
    const UINT Dimension = B.RowCount();

    Console::WriteLine(String("Initializing PCA, ") + String(B.ColCount()) + String(" points, ") + String(B.RowCount()) + String(" dimensions"));
	
    _Means.Allocate(Dimension);
	_Means.Clear(0.0);
	for(UINT PointIndex = 0; PointIndex < PointCount; PointIndex++)
	{
		for(UINT DimensionIndex = 0; DimensionIndex < Dimension; DimensionIndex++)
		{
            _Means[DimensionIndex] += B.Cell(DimensionIndex, PointIndex);
		}
	}
	for(UINT DimensionIndex = 0; DimensionIndex < Dimension; DimensionIndex++)
	{
		_Means[DimensionIndex] /= PointCount;
	}
	for(UINT PointIndex = 0; PointIndex < PointCount; PointIndex++)
	{
        for(UINT DimensionIndex = 0; DimensionIndex < Dimension; DimensionIndex++)
		{
		    B.Cell(DimensionIndex, PointIndex) -= _Means[DimensionIndex];
        }
	}

    DenseMatrix<T> C;
	Console::WriteLine("Building correlation matrix...");
	DenseMatrix<T>::MultiplyMMTranspose(C, B);
	DenseMatrix<T>::MultiplyInPlace(C, T(1.0) / T(PointCount));
    InitFromCorrelationMatrix(C);
}
void SpectralClustering::MakeLaplacian(const DenseMatrix<double> &S, Method method, DenseMatrix<double> &L)
{
    const UINT pointCount = S.RowCount();
    Vector<double> weightSums(pointCount, 0.0);
    for(UINT outerPointIndex = 0; outerPointIndex < pointCount; outerPointIndex++)
    {
        for(UINT innerPointIndex = 0; innerPointIndex < pointCount; innerPointIndex++)
        {
            weightSums[outerPointIndex] += S(outerPointIndex, innerPointIndex);
        }
    }

    if(method == Unnormalized || method == RandomWalk)
    {
        L = S;
        for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
        {
            L(pointIndex, pointIndex) = weightSums[pointIndex] - L(pointIndex, pointIndex);
        }
        if(method == RandomWalk)
        {
            for(UINT outerPointIndex = 0; outerPointIndex < pointCount; outerPointIndex++)
            {
                for(UINT innerPointIndex = 0; innerPointIndex < pointCount; innerPointIndex++)
                {
                    L(outerPointIndex, innerPointIndex) /= weightSums[outerPointIndex];
                }
            }
        }
    }
    if(method == Symmetric)
    {
        Vector<double> weightInvSqrts(pointCount);
        for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
        {
            weightInvSqrts[pointIndex] = sqrt(1.0f / weightSums[pointIndex]);
        }
        for(UINT outerPointIndex = 0; outerPointIndex < pointCount; outerPointIndex++)
        {
            for(UINT innerPointIndex = 0; innerPointIndex < pointCount; innerPointIndex++)
            {
                L(outerPointIndex, innerPointIndex) = S(outerPointIndex, innerPointIndex) * weightInvSqrts[outerPointIndex] * weightInvSqrts[innerPointIndex];
            }
        }
    }
}
Beispiel #3
0
void PCA<T>::InitFromCorrelationMatrix(const DenseMatrix<T> &C)
{
    const UINT Dimension = C.RowCount();
	const bool OutputMatlabAndExit = false;
    if(OutputMatlabAndExit)
    {
        Console::WriteLine("Outputting MATLAB matrix and exiting...");
        C.SaveToMATLAB("C:\\MATLAB7\\work\\PCA.txt");
        _Means.SaveToASCIIFile("C:\\JReaderData\\RawMeanVector.txt");
        exit(0);
    }
    else
    {
        Console::WriteLine("Computing eigensystem...");
        C.EigenSystem(_Eigenvalues, _Eigenvectors);
        Console::WriteLine(C.EigenTest(_Eigenvalues, _Eigenvectors));

        //_Eigenvectors.SaveToMATLAB("C:\\MATLAB7\\work\\MyEigenvectors.txt");
        //_Eigenvalues.SaveToASCIIFile("C:\\MATLAB7\\work\\MyEigenvalues.txt");
    }

    FinalizeFromEigenSystem();
}
void SpectralClustering::Cluster(const DenseMatrix<double> &S, UINT kMeansClusters, UINT reducedDimensionCount, Method method, Vector<UINT> &clusterIDs, SpectralClusteringCache *cache)
{
    const UINT pointCount = S.RowCount();
    
    Console::WriteLine("Spectral clustering on " + String(pointCount) + " points, " + String(kMeansClusters) + " clusters, " + String(reducedDimensionCount) + String(" dimensions"));
    
    DenseMatrix<double> L(pointCount, pointCount);
    MakeLaplacian(S, method, L);

    Vector<double> eigenvalues;
    DenseMatrix<double> eigenvectors;
    {
        if(cache != NULL && cache->eigenvalues.Length() == pointCount)
        {
            Console::WriteString("Loading eigensystem from cache...");
            eigenvalues = cache->eigenvalues;
            eigenvectors = cache->eigenvectors;
        }
        else
        {
            Clock timer;
            Console::WriteString("Solving eigensystem...");
            L.EigenSystemTNT(eigenvalues, eigenvectors);
            Console::WriteLine(String(timer.Elapsed()) + "s");
        }
        if(cache != NULL)
        {
            cache->eigenvalues = eigenvalues;
            cache->eigenvectors = eigenvectors;
        }
    }

    //
    // Note that the eigensystem is sorted in decreasing order.
    //
    const bool useLargestEigenvector = (method == RandomWalk || method == Symmetric);
    
    Vector<VecNf> points(pointCount);
    for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
    {
        VecNf &curPoint = points[pointIndex];
        curPoint.v.Allocate(reducedDimensionCount);
        for(UINT dimensionIndex = 0; dimensionIndex < reducedDimensionCount; dimensionIndex++)
        {
            if(useLargestEigenvector)
            {
                curPoint[dimensionIndex] = float(eigenvectors(pointIndex, pointCount - dimensionIndex - 1));
            }
            else
            {
                curPoint[dimensionIndex] = float(eigenvectors(pointIndex, dimensionIndex));
            }
            
        }
    }

    if(method == Symmetric)
    {
        for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
        {
            points[pointIndex] = VecNf::Normalize(points[pointIndex]);
        }
    }

    KMeansClustering<VecNf, VecNfKMeansMetric> clustering;
    clustering.Cluster(points, kMeansClusters, 100);
    
    clusterIDs.Allocate(pointCount);
    for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
    {
        clusterIDs[pointIndex] = clustering.QuantizeToNearestClusterIndex(points[pointIndex]);
    }
}