in graspologic/embed/mds.py [0:0]
def fit(self, X: np.ndarray, y: Optional[Any] = None) -> "ClassicalMDS":
"""
Fit the model with X.
Parameters
----------
X : array_like
If ``dissimilarity=='precomputed'``, the input should be the
dissimilarity matrix with shape (n_samples, n_samples). If
``dissimilarity=='euclidean'``, then the input should be 2d-array
with shape (n_samples, n_features) or a 3d-array with shape
(n_samples, n_features_1, n_features_2).
Returns
-------
self : object
Returns an instance of self.
"""
# Check X type
if not isinstance(X, np.ndarray):
msg = "X must be a numpy array, not {}.".format(type(X))
raise ValueError(msg)
if self.n_components is not None:
n_samples = X.shape[0]
if self.n_components > n_samples:
msg = "n_components must be <= n_samples."
raise ValueError(msg)
# Handle dissimilarity
if self.dissimilarity == "precomputed":
dissimilarity_matrix = check_array(X, ensure_2d=True, allow_nd=False)
# Must be symmetric
if not is_symmetric(dissimilarity_matrix):
msg = "X must be a symmetric array if precomputed dissimilarity matrix."
raise ValueError(msg)
elif self.dissimilarity == "euclidean":
X = check_array(X, ensure_2d=True, allow_nd=True)
dissimilarity_matrix = self._compute_euclidean_distances(X=X)
J = _get_centering_matrix(dissimilarity_matrix.shape[0])
B = J @ (dissimilarity_matrix ** 2) @ J * -0.5
n_components = self.n_components
algorithm: SvdAlgorithmType
if n_components == 1:
algorithm = "full"
else:
algorithm = "randomized"
U, D, V = select_svd(
B,
n_elbows=self.n_elbows,
algorithm=algorithm,
n_components=n_components,
svd_seed=self.svd_seed,
)
self.n_components_ = len(D)
self.components_ = U
self.singular_values_ = D ** 0.5
self.dissimilarity_matrix_ = dissimilarity_matrix
self.n_features_in_ = X.shape[1]
return self