예제 #1
0
    def pca_prune(self, meshes):
        """
        PCA on TriMeshes features.

        Parameters:
            meshes (list of TriMesh): meshes to be PCA

        Return:
            PCA model
        """
        # process mesh files to have the same number of points
        meshes = self.analyse_meshes(meshes)

        pca_model = PCAModel(samples=meshes, verbose=True)
        n_comps_retained = int(sum(pca_model.eigenvalues_cumulative_ratio() < self.n_components)) if \
            self.n_components >= 1 else self.n_components
        if self.verbose:
            print(
                '\nRetaining {:.2%} of eigenvalues keeps {} components'.format(
                    self.n_components, n_comps_retained))
        pca_model.trim_components(self.n_components)
        print(
            "Final PCA Model:\n# of components: {}\n# of points for each mesh (3 dims total): {}\n"
            "eigen value accumulative ratios: {}".format(
                str(pca_model.components.shape[0]),
                str(pca_model.components.shape[1]),
                str(pca_model.eigenvalues_cumulative_ratio())))
        return pca_model
def test_pca_init_from_covariance():
    n_samples = 30
    n_features = 10
    n_dims = 2
    centre_values = [True, False]
    for centre in centre_values:
        # generate samples list and convert it to nd.array
        samples = [
            PointCloud(np.random.randn(n_features, n_dims))
            for _ in range(n_samples)
        ]
        data, template = as_matrix(samples, return_template=True)
        # compute covariance matrix and mean
        if centre:
            mean_vector = np.mean(data, axis=0)
            mean = template.from_vector(mean_vector)
            X = data - mean_vector
            C = np.dot(X.T, X) / (n_samples - 1)
        else:
            mean = samples[0]
            C = np.dot(data.T, data) / (n_samples - 1)
        # create the 2 pca models
        pca1 = PCAModel.init_from_covariance_matrix(C,
                                                    mean,
                                                    centred=centre,
                                                    n_samples=n_samples)
        pca2 = PCAModel(samples, centre=centre)
        # compare them
        assert_array_almost_equal(pca1.component_vector(0, with_mean=False),
                                  pca2.component_vector(0, with_mean=False))
        assert_array_almost_equal(
            pca1.component(7).as_vector(),
            pca2.component(7).as_vector())
        assert_array_almost_equal(pca1.components, pca2.components)
        assert_array_almost_equal(pca1.eigenvalues, pca2.eigenvalues)
        assert_array_almost_equal(pca1.eigenvalues_cumulative_ratio(),
                                  pca2.eigenvalues_cumulative_ratio())
        assert_array_almost_equal(pca1.eigenvalues_ratio(),
                                  pca2.eigenvalues_ratio())
        weights = np.random.randn(pca1.n_active_components)
        assert_array_almost_equal(
            pca1.instance(weights).as_vector(),
            pca2.instance(weights).as_vector())
        weights2 = np.random.randn(pca1.n_active_components - 4)
        assert_array_almost_equal(pca1.instance_vector(weights2),
                                  pca2.instance_vector(weights2))
        assert_array_almost_equal(pca1.mean().as_vector(),
                                  pca2.mean().as_vector())
        assert_array_almost_equal(pca1.mean_vector, pca2.mean_vector)
        assert (pca1.n_active_components == pca2.n_active_components)
        assert (pca1.n_components == pca2.n_components)
        assert (pca1.n_features == pca2.n_features)
        assert (pca1.n_samples == pca2.n_samples)
        assert (pca1.noise_variance() == pca2.noise_variance())
        assert (pca1.noise_variance_ratio() == pca2.noise_variance_ratio())
        assert_almost_equal(pca1.variance(), pca2.variance())
        assert_almost_equal(pca1.variance_ratio(), pca2.variance_ratio())
        assert_array_almost_equal(pca1.whitened_components(),
                                  pca2.whitened_components())
예제 #3
0
def test_pca_init_from_covariance():
    n_samples = 30
    n_features = 10
    n_dims = 2
    centre_values = [True, False]
    for centre in centre_values:
        # generate samples list and convert it to nd.array
        samples = [PointCloud(np.random.randn(n_features, n_dims))
                   for _ in range(n_samples)]
        data, template = as_matrix(samples, return_template=True)
        # compute covariance matrix and mean
        if centre:
            mean_vector = np.mean(data, axis=0)
            mean = template.from_vector(mean_vector)
            X = data - mean_vector
            C = np.dot(X.T, X) / (n_samples - 1)
        else:
            mean = samples[0]
            C = np.dot(data.T, data) / (n_samples - 1)
        # create the 2 pca models
        pca1 = PCAModel.init_from_covariance_matrix(C, mean,
                                                    centred=centre,
                                                    n_samples=n_samples)
        pca2 = PCAModel(samples, centre=centre)
        # compare them
        assert_array_almost_equal(pca1.component_vector(0, with_mean=False),
                                  pca2.component_vector(0, with_mean=False))
        assert_array_almost_equal(pca1.component(7).as_vector(),
                                  pca2.component(7).as_vector())
        assert_array_almost_equal(pca1.components, pca2.components)
        assert_array_almost_equal(pca1.eigenvalues, pca2.eigenvalues)
        assert_array_almost_equal(pca1.eigenvalues_cumulative_ratio(),
                                  pca2.eigenvalues_cumulative_ratio())
        assert_array_almost_equal(pca1.eigenvalues_ratio(),
                                  pca2.eigenvalues_ratio())
        weights = np.random.randn(pca1.n_active_components)
        assert_array_almost_equal(pca1.instance(weights).as_vector(),
                                  pca2.instance(weights).as_vector())
        weights2 = np.random.randn(pca1.n_active_components - 4)
        assert_array_almost_equal(pca1.instance_vector(weights2),
                                  pca2.instance_vector(weights2))
        assert_array_almost_equal(pca1.mean().as_vector(),
                                  pca2.mean().as_vector())
        assert_array_almost_equal(pca1.mean_vector,
                                  pca2.mean_vector)
        assert(pca1.n_active_components == pca2.n_active_components)
        assert(pca1.n_components == pca2.n_components)
        assert(pca1.n_features == pca2.n_features)
        assert(pca1.n_samples == pca2.n_samples)
        assert(pca1.noise_variance() == pca2.noise_variance())
        assert(pca1.noise_variance_ratio() == pca2.noise_variance_ratio())
        assert_almost_equal(pca1.variance(), pca2.variance())
        assert_almost_equal(pca1.variance_ratio(), pca2.variance_ratio())
        assert_array_almost_equal(pca1.whitened_components(),
                                  pca2.whitened_components())
def pca_and_weights(meshes, retain_eig_cum_val=0.997, verbose=False):
    model = PCAModel(meshes, verbose=verbose)
    n_comps_retained = (model.eigenvalues_cumulative_ratio() <
                        retain_eig_cum_val).sum()
    if verbose:
        print('\nRetaining {:.2%} of eigenvalues keeps {} components'.format(
            retain_eig_cum_val, n_comps_retained))
    model.trim_components(retain_eig_cum_val)
    if verbose:
        meshes = print_progress(meshes, prefix='Calculating weights')
    weights = (np.vstack([model.project(m)
                          for m in meshes]) / np.sqrt(model.eigenvalues))
    return model, weights