def main(): sphere = Hypersphere(dimension=2) data = sphere.random_von_mises_fisher(kappa=10, n_samples=1000) n_clusters = 4 clustering = OnlineKMeans(metric=sphere.metric, n_clusters=n_clusters) clustering = clustering.fit(data) plt.figure(0) ax = plt.subplot(111, projection="3d") visualization.plot(points=clustering.cluster_centers_, ax=ax, space='S2', c='r') plt.show() plt.figure(1) ax = plt.subplot(111, projection="3d") sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) for i in range(n_clusters): cluster = data[clustering.labels_ == i, :] sphere_plot.draw_points(ax=ax, points=cluster) plt.show()
def main(): """Plot an Agglomerative Hierarchical Clustering on the sphere.""" sphere = Hypersphere(dim=2) sphere_distance = sphere.metric.dist n_clusters = 2 n_samples_per_dataset = 50 dataset_1 = sphere.random_von_mises_fisher( kappa=10, n_samples=n_samples_per_dataset) dataset_2 = - sphere.random_von_mises_fisher( kappa=10, n_samples=n_samples_per_dataset) dataset = gs.concatenate((dataset_1, dataset_2), axis=0) clustering = AgglomerativeHierarchicalClustering( n_clusters=n_clusters, distance=sphere_distance) clustering.fit(dataset) clustering_labels = clustering.labels_ plt.figure(0) ax = plt.subplot(111, projection='3d') plt.title('Agglomerative Hierarchical Clustering') sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) for i_label in range(n_clusters): points_label_i = dataset[clustering_labels == i_label, ...] sphere_plot.draw_points(ax=ax, points=points_label_i) plt.show()
def main(): """Compute pole ladder and plot the construction.""" base_point = SPACE.random_uniform(1) tangent_vec_b = SPACE.random_uniform(1) tangent_vec_b = SPACE.projection_to_tangent_space(tangent_vec_b, base_point) tangent_vec_b *= N_STEPS / 2 tangent_vec_a = SPACE.random_uniform(1) tangent_vec_a = SPACE.projection_to_tangent_space(tangent_vec_a, base_point) * N_STEPS / 4 ladder = METRIC.ladder_parallel_transport(tangent_vec_a, tangent_vec_b, base_point, n_steps=N_STEPS, return_geodesics=True) pole_ladder = ladder['transported_tangent_vec'] trajectory = ladder['trajectory'] fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection='3d') sphere_visu = visualization.Sphere(n_meridians=30) ax = sphere_visu.set_ax(ax=ax) t = gs.linspace(0, 1, N_POINTS) t_main = gs.linspace(0, 1, N_POINTS * 4) for points in trajectory: main_geodesic, diagonal, final_geodesic = points sphere_visu.draw_points(ax, main_geodesic(t_main), marker='o', c='b', s=2) sphere_visu.draw_points(ax, diagonal(-t), marker='o', c='r', s=2) sphere_visu.draw_points(ax, diagonal(t), marker='o', c='r', s=2) sphere_visu.draw_points(ax, final_geodesic(-t), marker='o', c='g', s=2) sphere_visu.draw_points(ax, final_geodesic(t), marker='o', c='g', s=2) tangent_vectors = gs.stack([tangent_vec_b, tangent_vec_a, pole_ladder], axis=0) / N_STEPS base_point = gs.to_ndarray(base_point, to_ndim=2) origin = gs.concatenate( [base_point, base_point, final_geodesic(gs.array([0]))]) ax.quiver(origin[:, 0], origin[:, 1], origin[:, 2], tangent_vectors[:, 0], tangent_vectors[:, 1], tangent_vectors[:, 2], color=['black', 'black', 'black'], linewidth=2) sphere_visu.draw(ax, linewidth=1) plt.show()
def main(): """Compute pole ladder and plot the construction.""" base_point = SPACE.random_uniform(1) tangent_vec_b = SPACE.random_uniform(1) tangent_vec_b = SPACE.to_tangent(tangent_vec_b, base_point) tangent_vec_b = tangent_vec_b / gs.linalg.norm(tangent_vec_b) rotation_vector = gs.pi / 2 * base_point rotation_matrix = ROTATIONS.matrix_from_rotation_vector(rotation_vector) tangent_vec_a = gs.dot(rotation_matrix, tangent_vec_b) tangent_vec_b *= 3.0 / 2.0 ladder = METRIC.ladder_parallel_transport(tangent_vec_a, tangent_vec_b, base_point, n_rungs=N_STEPS, return_geodesics=True) pole_ladder = ladder["transported_tangent_vec"] trajectory = ladder["trajectory"] fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection="3d") sphere_visu = visualization.Sphere(n_meridians=30) ax = sphere_visu.set_ax(ax=ax) t = gs.linspace(0.0, 1.0, N_POINTS) t_main = gs.linspace(0.0, 1.0, N_POINTS * 4) for points in trajectory: main_geodesic, diagonal, final_geodesic = points sphere_visu.draw_points(ax, main_geodesic(t_main), marker="o", c="b", s=2) sphere_visu.draw_points(ax, diagonal(-t), marker="o", c="r", s=2) sphere_visu.draw_points(ax, diagonal(t), marker="o", c="r", s=2) tangent_vectors = ( gs.stack([tangent_vec_b, tangent_vec_a, pole_ladder], axis=0) / N_STEPS) base_point = gs.to_ndarray(base_point, to_ndim=2) origin = gs.concatenate( [base_point, base_point, final_geodesic(0.0)], axis=0) ax.quiver( origin[:, 0], origin[:, 1], origin[:, 2], tangent_vectors[:, 0], tangent_vectors[:, 1], tangent_vectors[:, 2], color=["black", "black", "black"], linewidth=2, ) sphere_visu.draw(ax, linewidth=1) plt.show()
def main(): """Plot the result of a KNN classification on the sphere.""" sphere = Hypersphere(dim=2) sphere_distance = sphere.metric.dist n_labels = 2 n_samples_per_dataset = 10 n_targets = 200 dataset_1 = sphere.random_von_mises_fisher(kappa=10, n_samples=n_samples_per_dataset) dataset_2 = -sphere.random_von_mises_fisher( kappa=10, n_samples=n_samples_per_dataset) training_dataset = gs.concatenate((dataset_1, dataset_2), axis=0) labels_dataset_1 = gs.zeros([n_samples_per_dataset], dtype=gs.int64) labels_dataset_2 = gs.ones([n_samples_per_dataset], dtype=gs.int64) labels = gs.concatenate((labels_dataset_1, labels_dataset_2)) target = sphere.random_uniform(n_samples=n_targets) neigh = KNearestNeighborsClassifier(n_neighbors=2, distance=sphere_distance) neigh.fit(training_dataset, labels) target_labels = neigh.predict(target) plt.figure(0) ax = plt.subplot(111, projection="3d") plt.title("Training set") sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) for i_label in range(n_labels): points_label_i = training_dataset[labels == i_label, ...] sphere_plot.draw_points(ax=ax, points=points_label_i) plt.figure(1) ax = plt.subplot(111, projection="3d") plt.title("Classification") sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) for i_label in range(n_labels): target_points_label_i = target[target_labels == i_label, ...] sphere_plot.draw_points(ax=ax, points=target_points_label_i) plt.show()
def main(): points = SPHERE2.random_von_mises_fisher(kappa=KAPPA, n_samples=N_POINTS) centers, weights, clusters, n_steps = METRIC.optimal_quantization( points=points, n_centers=N_CENTERS, n_repetitions=N_REPETITIONS) plt.figure(0) ax = plt.subplot(111, projection="3d", aspect="equal") visualization.plot(points=centers, ax=ax, space='S2', c='r') plt.show() plt.figure(1) ax = plt.subplot(111, projection="3d", aspect="equal") sphere = visualization.Sphere() sphere.draw(ax=ax) for i in range(N_CENTERS): sphere.draw_points(ax=ax, points=clusters[i])
def plot_and_save_video( geodesics, loss, size=20, fps=10, dpi=100, out="out.mp4", color="red" ): """Render a set of geodesics and save it to an mpeg 4 file.""" FFMpegWriter = animation.writers["ffmpeg"] writer = FFMpegWriter(fps=fps) fig = plt.figure(figsize=(size, size)) ax = fig.add_subplot(111, projection="3d") sphere = visualization.Sphere() sphere.plot_heatmap(ax, loss) points = gs.to_ndarray(geodesics[0], to_ndim=2) sphere.add_points(points) sphere.draw(ax, color=color, marker=".") with writer.saving(fig, out, dpi=dpi): for points in geodesics[1:]: points = gs.to_ndarray(points, to_ndim=2) sphere.draw_points(ax, points=points, color=color, marker=".") writer.grab_frame()
def main(): r"""Compute and visualize a geodesic regression on the sphere. The generative model of the data is: :math:`Z = Exp_{\beta_0}(\beta_1.X)` and :math:`Y = Exp_Z(\epsilon)` where: - :math:`Exp` denotes the Riemannian exponential, - :math:`\beta_0` is called the intercept, - :math:`\beta_1` is called the coefficient, - :math:`\epsilon \sim N(0, 1)` is a standard Gaussian noise, - :math:`X` is the input, :math:`Y` is the target. """ # Generate noise-free data n_samples = 50 X = gs.random.rand(n_samples) X -= gs.mean(X) intercept = SPACE.random_uniform() coef = SPACE.to_tangent(5.0 * gs.random.rand(EMBEDDING_DIM), base_point=intercept) y = METRIC.exp(X[:, None] * coef, base_point=intercept) # Generate normal noise normal_noise = gs.random.normal(size=(n_samples, EMBEDDING_DIM)) noise = SPACE.to_tangent(normal_noise, base_point=y) / gs.pi / 2 rss = gs.sum(METRIC.squared_norm(noise, base_point=y)) / n_samples # Add noise y = METRIC.exp(noise, y) # True noise level and R2 estimator = FrechetMean(METRIC) estimator.fit(y) variance_ = variance(y, estimator.estimate_, metric=METRIC) r2 = 1 - rss / variance_ # Fit geodesic regression gr = GeodesicRegression(SPACE, center_X=False, method="extrinsic", verbose=True) gr.fit(X, y, compute_training_score=True) intercept_hat, coef_hat = gr.intercept_, gr.coef_ # Measure Mean Squared Error mse_intercept = METRIC.squared_dist(intercept_hat, intercept) tangent_vec_to_transport = coef_hat tangent_vec_of_transport = METRIC.log(intercept, base_point=intercept_hat) transported_coef_hat = METRIC.parallel_transport( tangent_vec=tangent_vec_to_transport, base_point=intercept_hat, direction=tangent_vec_of_transport, ) mse_coef = METRIC.squared_norm(transported_coef_hat - coef, base_point=intercept) # Measure goodness of fit r2_hat = gr.training_score_ print(f"MSE on the intercept: {mse_intercept:.2e}") print(f"MSE on the coef, i.e. initial velocity: {mse_coef:.2e}") print(f"Determination coefficient: R^2={r2_hat:.2f}") print(f"True R^2: {r2:.2f}") # Plot fitted_data = gr.predict(X) fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection="3d") sphere_visu = visualization.Sphere(n_meridians=30) ax = sphere_visu.set_ax(ax=ax) path = METRIC.geodesic(initial_point=intercept_hat, initial_tangent_vec=coef_hat) regressed_geodesic = path( gs.linspace(0.0, 1.0, 100) * gs.pi * 2 / METRIC.norm(coef)) regressed_geodesic = gs.to_numpy(gs.autodiff.detach(regressed_geodesic)) size = 10 marker = "o" sphere_visu.draw_points(ax, gs.array([intercept_hat]), marker=marker, c="r", s=size) sphere_visu.draw_points(ax, y, marker=marker, c="b", s=size) sphere_visu.draw_points(ax, fitted_data, marker=marker, c="g", s=size) ax.plot( regressed_geodesic[:, 0], regressed_geodesic[:, 1], regressed_geodesic[:, 2], c="gray", ) sphere_visu.draw(ax, linewidth=1) ax.grid(False) plt.axis("off") plt.show()
def main(): """Plot a Kernel Density Estimation Classification on the sphere.""" sphere = Hypersphere(dim=2) sphere_distance = sphere.metric.dist n_labels = 2 n_samples_per_dataset = 10 n_targets = 200 radius = np.inf kernel = triangular_radial_kernel bandwidth = 3 n_training_samples = n_labels * n_samples_per_dataset dataset_1 = sphere.random_von_mises_fisher( kappa=10, n_samples=n_samples_per_dataset) dataset_2 = - sphere.random_von_mises_fisher( kappa=10, n_samples=n_samples_per_dataset) training_dataset = gs.concatenate((dataset_1, dataset_2), axis=0) labels_dataset_1 = gs.zeros([n_samples_per_dataset], dtype=gs.int64) labels_dataset_2 = gs.ones([n_samples_per_dataset], dtype=gs.int64) labels = gs.concatenate((labels_dataset_1, labels_dataset_2)) target = sphere.random_uniform(n_samples=n_targets) labels_colors = gs.zeros([n_labels, 3]) labels_colors[0, :] = gs.array([0, 0, 1]) labels_colors[1, :] = gs.array([1, 0, 0]) kde = KernelDensityEstimationClassifier( radius=radius, distance=sphere_distance, kernel=kernel, bandwidth=bandwidth, outlier_label='most_frequent') kde.fit(training_dataset, labels) target_labels = kde.predict(target) target_labels_proba = kde.predict_proba(target) plt.figure(0) ax = plt.subplot(111, projection='3d') plt.title('Training set') sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) colors = gs.zeros([n_training_samples, 3]) for i_sample in range(n_training_samples): colors[i_sample, :] = labels_colors[labels[i_sample], :] sphere_plot.draw_points(ax=ax, points=training_dataset, c=colors) plt.figure(1) ax = plt.subplot(111, projection='3d') plt.title('Classification') sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) colors = gs.zeros([n_targets, 3]) for i_target in range(n_targets): colors[i_target, :] = labels_colors[target_labels[i_target], :] sphere_plot.draw_points(ax=ax, points=target, c=colors) plt.figure(2) ax = plt.subplot(111, projection='3d') plt.title('Probabilistic classification') sphere_plot = visualization.Sphere() sphere_plot.draw(ax=ax) colors = target_labels_proba @ labels_colors sphere_plot.draw_points(ax=ax, points=target, c=colors) plt.show()