Анализ основных компонентов (PCA), возможно, является очень трудной для понимания темой для новичков в машинном обучении. Здесь я изо всех сил постараюсь интуитивно объяснить, что это такое, как алгоритм делает то, что делает. В этом посте предполагается, что у вас есть очень базовые знания о линейной алгебре, такой как умножение матриц и векторы.

Что такое СПС?

PCA - это метод уменьшения размерности, используемый для преобразования больших наборов данных с сотнями тысяч функций в более мелкие наборы данных с меньшим количеством функций, сохраняя при этом как можно больше информации о наборе данных.

Прекрасным примером может быть:

Обратите внимание, что в исходном наборе данных было пять функций, которые можно было сократить до двух. Эти две функции обобщают функции слева.

Визуализация идеи PCA.

Чтобы составить картину происходящего, воспользуемся нашим предыдущим примером. Двумерная плоскость, показывающая соотношение размера и количества комнат в доме, может быть сжата до элемента одного размера, как показано ниже:

Если мы спроецируем дома на черную линию, мы получим что-то вроде этого:

Поэтому нам нужно уменьшить эту ошибку проекции (величину синих линий), чтобы сохранить максимум информации.

Предпосылки к пониманию алгоритма PCA.

Я объясню некоторые концепции интуитивно, чтобы вы лучше понимали алгоритм.

Иметь в виду

Среднее значение любого набора данных относится к равновесию набора данных. Представьте стержень, на котором шарики размещены на некотором расстоянии x от стены:

Суммирование расстояния между шарами от стены и деление на количество шаров дает точку равновесия, в которой стержень уравновешивает стержень.

Дисперсия

Среднее говорит нам о равновесии набора данных, дисперсия - это показатель, который говорит нам о разбросе набора данных от его среднего. В одномерном наборе данных дисперсию можно проиллюстрировать как:

Мы возьмем квадрат каждого расстояния, чтобы не получить отрицательных значений!

Для двухмерного набора данных просто возьмите дисперсию после ее проецирования на каждую ось (показано ниже).

Ковариация

В двух и более измерениях два очень разных набора данных могут иметь одинаковую дисперсию, что приводит к неправильной интерпретации данных. Например, оба набора данных ниже имеют одинаковую дисперсию, хотя они совершенно разные.

Обратите внимание, что дисперсия одинакова для совершенно разных наборов данных. Также обратите внимание, как рассчитываются дисперсия по оси x и дисперсия по оси y путем проецирования данных на каждую ось.

Ковариация отображает корреляцию набора данных. Это величина, описывающая дисперсию, а также направление спреда. Это поможет нам различать два вышеуказанных набора данных.

Чтобы получить ковариацию, просто добавьте произведение координат каждой точки. Например, в красном наборе данных. (-2, -1) приводит к 2, так же как и (2, 1).

Ковариационная матрица - это линейное преобразование, которое преобразует данные в другую форму. Мы увидим это позже. В 2D это матрица (2 x 2).

Для набора данных в приведенном выше примере после вставки значений будет показана приблизительная оценка ковариационной матрицы. Чтобы понять использование этой матрицы, нам сначала нужно понять линейные преобразования.

Линейное преобразование - это преобразование, которое преобразует любую точку в 2D-плоскости в другую точку в той же плоскости с помощью матрицы преобразования.

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

Это преобразование дает нам два очень особых вектора - собственные векторы.

Эти собственные векторы являются особенными, потому что на них не влияет преобразование (их направление остается прежним), они только увеличиваются по величине. Ниже представлены два вектора красного и бирюзового цветов.

Говоря абстрактно, это векторы, на которые мы будем проецировать наши данные, что поможет нам уменьшить размеры.

Возникает вопрос: какой собственный вектор выбрать?

Позвольте мне сказать вам, что вы умный человек, если выбрали красную, потому что я совершенно не имел ни малейшего понятия!

Красный - лучший выбор, потому что он сохранит максимальную дисперсию исходного набора данных, что означает сохранение максимальной информации.

Интересная часть: код!

Мы применим алгоритм к вложениям слов, которые являются векторным представлением очень многомерных слов. Визуализация TensorFlow для 10000 слов в 200 измерениях выглядит примерно так:

Вместо этого мы будем использовать набор данных с вложениями в 300 измерениях.

Процесс выглядит следующим образом:

  1. Унизить данные (центрировать их так, чтобы каждая функция имела нулевое среднее);
def compute_pca(X, n_components=2):
    """
    Input:
        X: of dimension (m,n) where each row corresponds to a word vector
        n_components: Number of components you want to keep.
    Output:
        X_reduced: data transformed in 2 dims/columns + regenerated original data
    """
    # mean center the data (axis=0 because taking mean along columns)
    X_demeaned = X - np.mean(X, axis=0, keepdims=True) # normalize each feature of dataset

2. Вычислить ковариационную матрицу.

# calculate the covariance matrix, rowvar=False because our features are in columns, not rows
    covariance_matrix = np.cov(X_demeaned, rowvar=False)

3. Вычислите и отсортируйте собственные векторы и собственные значения от наивысшей к наименьшей величине (собственные значения), помните, что нам нужны собственные векторы с высокими собственными значениями, чтобы сохранить максимальную дисперсию (информацию) наших вложений слов.

    # calculate eigenvectors & eigenvalues of the covariance matrix,           both are returned in ascending order
    eigen_vals, eigen_vecs = np.linalg.eigh(covariance_matrix)
    # sort the eigen values (highest - lowest)
    eigen_vals_sorted = np.flip(eigen_vals)
    
    # sort eigenvectors (highest - lowest)
    eigen_vecs_sorted = np.flip(eigen_vecs, axis=1)

4. Выберите n собственных векторов, соответствующих собственным значениям, в порядке убывания.

    # select the first n eigenvectors (n is desired dimension
    # of rescaled data array, or dims_rescaled_data), each      eigenvector is a column in eigen_vecs matrix.
    eigen_vecs_subset = eigen_vecs_sorted[:, :n_components]

5. Умножьте это подмножество собственных векторов на уменьшенные данные, чтобы получить преобразованные данные!

   # transform the data by multiplying the demeaned dataset with the    first n eigenvectors
    X_reduced = np.dot(X_demeaned, eigen_vecs_subset)
    return X_reduced

Давайте визуализировать!

Давайте попробуем этот алгоритм на некоторых данных.

words = ['oil', 'gas', 'happy', 'sad', 'city', 'town',
         'village', 'country', 'continent', 'petroleum', 'joyful'] #11 words
# given a list of words and the embeddings, it returns a matrix with all the embeddings
X = get_vectors(word_embeddings, words)
X.shape # returns (11, 300)

Применяя наш алгоритм для уменьшения с 300 измерений до 2 измерений!

# We have done the plotting for you. Just run this cell.
result = compute_pca(X, 2)
plt.figure(figsize=(12,8))
plt.scatter(result[:, 0], result[:, 1])
for i, word in enumerate(words):
    plt.annotate(word, xy=(result[i, 0] - 0.05, result[i, 1] + 0.1), )
plt.show()

Вывод: слова, выражающие эмоции (грусть, радость, счастье), близки друг к другу, город / деревня / город также близки друг к другу, потому что они очень связаны!

Теперь мы сократили 300 вложений измерений до вложения двух измерений! Вот почему мы можем это визуализировать!

Надеюсь, я все объяснил легко и дружелюбно :)

До скорого!

Примечание. Все слайды, показанные в этой статье, принадлежат YouTube-каналу Луиса Серрано. Его видео, объясняющее PCA, было потрясающим, и вот ссылка на его канал: https://www.youtube.com/channel/UCgBncpylJ1kiVaPyP-PZauQ