Python: сделать UMAP быстрым (er)

Я использую UMAP (https://umap-learn.readthedocs.io/en/latest/#), чтобы уменьшить размер моих данных. Мой набор данных содержит 4700 образцов по 1,2 миллиона функций в каждом (которые я хотел бы уменьшить). Однако это занимает довольно много времени, несмотря на использование 32 процессоров и 120 ГБ оперативной памяти. В частности, построение вложения происходит медленно, и подробный вывод не изменился за последние 3,5 часа:

      UMAP(dens_frac=0.0, dens_lambda=0.0, low_memory=False, n_neighbors=10,
     verbose=True)
Construct fuzzy simplicial set
Mon Jul  5 09:43:28 2021 Finding Nearest Neighbors
Mon Jul  5 09:43:28 2021 Building RP forest with 59 trees
Mon Jul  5 10:06:10 2021 metric NN descent for 20 iterations
     1  /  20
     2  /  20
     3  /  20
     4  /  20
     5  /  20
    Stopping threshold met -- exiting after 5 iterations
Mon Jul  5 10:12:14 2021 Finished Nearest Neighbor Search
Mon Jul  5 10:12:25 2021 Construct embedding

Есть ли способы ускорить этот процесс. Я уже использую разреженную матрицу (scipy.sparse.lil_matrix), как описано здесь: https://umap-learn.readthedocs.io/en/latest/sparse.html . Кроме того, я установил pynndescent (как описано здесь: https://github.com/lmcinnes/umap/issues/416). Мой код выглядит следующим образом:

      from scipy.sparse import lil_matrix
import numpy as np
import umap.umap_ as umap

term_dok_matrix = np.load('term_dok_matrix.npy')
term_dok_mat_lil = lil_matrix(term_dok_matrix, dtype=np.float32)

test = umap.UMAP(a=None, angular_rp_forest=False, b=None,
     force_approximation_algorithm=False, init='spectral', learning_rate=1.0,
     local_connectivity=1.0, low_memory=False, metric='euclidean',
     metric_kwds=None, n_neighbors=10, min_dist=0.1, n_components=2, n_epochs=None, 
     negative_sample_rate=5, output_metric='euclidean',
     output_metric_kwds=None, random_state=None, repulsion_strength=1.0,
     set_op_mix_ratio=1.0, spread=1.0, target_metric='categorical',
     target_metric_kwds=None, target_n_neighbors=-1, target_weight=0.5,
     transform_queue_size=4.0, unique=False, verbose=True).fit_transform(term_dok_mat_lil)

Есть ли какие-нибудь уловки или идеи, как ускорить вычисления? Могу я изменить некоторые параметры? Помогает ли то, что моя матрица состоит только из нулей и единиц (что означает, что все ненулевые элементы в моей матрице равны единице).

2 ответа

Решение

Имея 1,2 миллиона функций и всего 4700 образцов, вам будет лучше просто предварительно вычислить полную матрицу расстояний и передать ее с помощью metric="precomputed". В настоящее время он проводит много работы по вычислению ближайших соседей этих 1,2 миллиона длинных векторов. Просто грубая сила будет намного лучше.

Вы можете выполнить PCA для набора данных. Максимальное количество ПК — 4700. Это намного лучше, чем 1,2 миллиарда.

После этого вы можете рассчитать precomputed_knn как:

      import umap
from umap.umap_ import nearest_neighbors

precomputed_knn = nearest_neighbors(
        data_pca, n_neighbors = 3000, metric="euclidean",
        metric_kwds=None, angular=False, random_state=1)

затем:

      umap.UMAP(precomputed_knn=precomputed_knn)
Другие вопросы по тегам