Skip to content
Permalink
Browse files

Working tPCA with sklearn API

  • Loading branch information...
ninamiolane committed Aug 28, 2019
1 parent fc41752 commit 4e4cc2af98c014adefc8dada45eb6a32806ea29d
@@ -0,0 +1,59 @@
"""
Compute the mean of a data set of 3D rotations.
Performs tangent PCA at the mean.
"""

import matplotlib.pyplot as plt
import numpy as np

import geomstats.visualization as visualization

from geomstats.learning.pca import TangentPCA

from geomstats.special_orthogonal_group import SpecialOrthogonalGroup

SO3_GROUP = SpecialOrthogonalGroup(n=3)
METRIC = SO3_GROUP.bi_invariant_metric

N_SAMPLES = 10
N_COMPONENTS = 2


def main():
fig = plt.figure(figsize=(15, 5))

data = SO3_GROUP.random_uniform(n_samples=N_SAMPLES)
mean = METRIC.mean(data)

tpca = TangentPCA(metric=METRIC, n_components=N_COMPONENTS)
tpca = tpca.fit(data, base_point=mean)
tangent_projected_data = tpca.transform(data)
print(
'Coordinates of the Log of the first 5 data points at the mean, '
'projected on the principal components:')
print(tangent_projected_data[:5])

ax_var = fig.add_subplot(121)
xticks = np.arange(1, N_COMPONENTS+1, 1)
ax_var.xaxis.set_ticks(xticks)
ax_var.set_title('Explained variance')
ax_var.set_xlabel('Number of Principal Components')
ax_var.set_ylim((0, 1))
ax_var.plot(xticks, tpca.explained_variance_ratio_)

ax = fig.add_subplot(122, projection="3d")
plt.setp(ax,
xlim=(-3, 3), ylim=(-3, 3), zlim=(-3, 3),
xlabel="X", ylabel="Y", zlabel="Z")

ax.set_title('Data in SO3 (black) and Frechet mean (color)')
visualization.plot(data, ax, space='SO3_GROUP', color='black')
visualization.plot(mean, ax, space='SO3_GROUP', linewidth=3)
ax.set_xlim((-2, 2))
ax.set_ylim((-2, 2))
ax.set_zlim((-2, 2))
plt.show()


if __name__ == "__main__":
main()
@@ -0,0 +1,8 @@
from ._template import TemplateEstimator
from ._template import TemplateClassifier
from ._template import TemplateTransformer

from ._version import __version__

__all__ = ['TemplateEstimator', 'TemplateClassifier', 'TemplateTransformer',
'__version__']
@@ -0,0 +1,203 @@
"""
This is a module to be used as a reference for building other modules
"""
import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin, TransformerMixin
from sklearn.utils.validation import check_X_y, check_array, check_is_fitted
from sklearn.utils.multiclass import unique_labels
from sklearn.metrics import euclidean_distances


class TemplateEstimator(BaseEstimator):
""" A template estimator to be used as a reference implementation.
For more information regarding how to build your own estimator, read more
in the :ref:`User Guide <user_guide>`.
Parameters
----------
demo_param : str, default='demo_param'
A parameter used for demonstation of how to pass and store paramters.
"""
def __init__(self, demo_param='demo_param'):
self.demo_param = demo_param

def fit(self, X, y):
"""A reference implementation of a fitting function.
Parameters
----------
X : {array-like, sparse matrix}, shape (n_samples, n_features)
The training input samples.
y : array-like, shape (n_samples,) or (n_samples, n_outputs)
The target values (class labels in classification, real numbers in
regression).
Returns
-------
self : object
Returns self.
"""
X, y = check_X_y(X, y, accept_sparse=True)
self.is_fitted_ = True
# `fit` should always return `self`
return self

def predict(self, X):
""" A reference implementation of a predicting function.
Parameters
----------
X : {array-like, sparse matrix}, shape (n_samples, n_features)
The training input samples.
Returns
-------
y : ndarray, shape (n_samples,)
Returns an array of ones.
"""
X = check_array(X, accept_sparse=True)
check_is_fitted(self, 'is_fitted_')
return np.ones(X.shape[0], dtype=np.int64)


class TemplateClassifier(BaseEstimator, ClassifierMixin):
""" An example classifier which implements a 1-NN algorithm.
For more information regarding how to build your own classifier, read more
in the :ref:`User Guide <user_guide>`.
Parameters
----------
demo_param : str, default='demo'
A parameter used for demonstation of how to pass and store paramters.
Attributes
----------
X_ : ndarray, shape (n_samples, n_features)
The input passed during :meth:`fit`.
y_ : ndarray, shape (n_samples,)
The labels passed during :meth:`fit`.
classes_ : ndarray, shape (n_classes,)
The classes seen at :meth:`fit`.
"""
def __init__(self, demo_param='demo'):
self.demo_param = demo_param

def fit(self, X, y):
"""A reference implementation of a fitting function for a classifier.
Parameters
----------
X : array-like, shape (n_samples, n_features)
The training input samples.
y : array-like, shape (n_samples,)
The target values. An array of int.
Returns
-------
self : object
Returns self.
"""
# Check that X and y have correct shape
X, y = check_X_y(X, y)
# Store the classes seen during fit
self.classes_ = unique_labels(y)

self.X_ = X
self.y_ = y
# Return the classifier
return self

def predict(self, X):
""" A reference implementation of a prediction for a classifier.
Parameters
----------
X : array-like, shape (n_samples, n_features)
The input samples.
Returns
-------
y : ndarray, shape (n_samples,)
The label for each sample is the label of the closest sample
seen during fit.
"""
# Check is fit had been called
check_is_fitted(self, ['X_', 'y_'])

# Input validation
X = check_array(X)

closest = np.argmin(euclidean_distances(X, self.X_), axis=1)
return self.y_[closest]


class TemplateTransformer(BaseEstimator, TransformerMixin):
""" An example transformer that returns the element-wise square root.
For more information regarding how to build your own transformer, read more
in the :ref:`User Guide <user_guide>`.
Parameters
----------
demo_param : str, default='demo'
A parameter used for demonstation of how to pass and store paramters.
Attributes
----------
n_features_ : int
The number of features of the data passed to :meth:`fit`.
"""
def __init__(self, demo_param='demo'):
self.demo_param = demo_param

def fit(self, X, y=None):
"""A reference implementation of a fitting function for a transformer.
Parameters
----------
X : {array-like, sparse matrix}, shape (n_samples, n_features)
The training input samples.
y : None
There is no need of a target in a transformer, yet the pipeline API
requires this parameter.
Returns
-------
self : object
Returns self.
"""
X = check_array(X, accept_sparse=True)

self.n_features_ = X.shape[1]

# Return the transformer
return self

def transform(self, X):
""" A reference implementation of a transform function.
Parameters
----------
X : {array-like, sparse-matrix}, shape (n_samples, n_features)
The input samples.
Returns
-------
X_transformed : array, shape (n_samples, n_features)
The array containing the element-wise square roots of the values
in ``X``.
"""
# Check is fit had been called
check_is_fitted(self, 'n_features_')

# Input validation
X = check_array(X, accept_sparse=True)

# Check that the input is of the same shape as the one passed
# during fit.
if X.shape[1] != self.n_features_:
raise ValueError('Shape of input is different from what was seen'
'in `fit`')
return np.sqrt(X)
@@ -0,0 +1 @@
__version__ = "0.0.3"

0 comments on commit 4e4cc2a

Please sign in to comment.
You can’t perform that action at this time.