Методы уменьшения размерностей

Методы уменьшения размерностей

https://t.me/data_analysis_ml
library(tidyverse)

Методы уменьшения размерностей – это эксплораторные методы, которые позволяет использовать меньше переменных для того, чтобы найти связи в данных и связи между переменными. Немножко жаргона: размерность здесь является прямым аналогом размерности в описании физических объектов (например, 2-ухмерное, 3-ехмерное, 4-ехмерное и т. д. пространство). Важно понимать, что каждая переменная в любом датасете можно воспринимать как отдельную размерность, так что каждая строчка в датасете mtcars – объект в 11-мерном пространстве просто потому что в этом датасете 11 переменных.


18.1 Визуализация многомерных пространств

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

  • много диаграмм рассеяния
library(GGally)
ggpairs(mtcars)


  • радиальная диаграмма (радар, паук)
mtcars %>% 
  mutate(car_names = rownames(mtcars)) %>% 
  pivot_longer(names_to = "variables", values_to = "values", mpg:carb) %>%
  mutate(variables = factor(variables, levels = colnames(mtcars))) %>%   
  ggplot(aes(variables, values, color = car_names, group = car_names))+
  geom_point()+
  geom_polygon(fill = NA)+
  ggproto("CordRadar", CoordPolar, theta = "x", r = "x", start = 0, direction = 1, is_linear = function(coord) TRUE)


Не очень видно. Давайте нормализуем переменные:

mtcars %>% 
  mutate_all(scale) %>% 
  mutate(car_names = rownames(mtcars)) %>% 
  pivot_longer(names_to = "variables", values_to = "values", mpg:carb) %>% 
  mutate(variables = factor(variables, levels = colnames(mtcars))) %>%   
  ggplot(aes(variables, values, color = car_names, group = car_names))+
  geom_point()+
  geom_polygon(fill = NA)+
  ggproto("CordRadar", CoordPolar, theta = "x", r = "x", start = 0, direction = 1, is_linear = function(coord) TRUE)


Все равно не очень хорошо видно, давайте сделаем фасетизацию:

mtcars %>% 
  mutate_all(scale) %>% 
  mutate(car_names = rownames(mtcars)) %>% 
  pivot_longer(names_to = "variables", values_to = "values", mpg:carb) %>% 
  mutate(variables = factor(variables, levels = colnames(mtcars))) %>%   
  ggplot(aes(variables, values, group = car_names, color = car_names))+
  geom_point(show.legend = FALSE)+
  geom_polygon(fill = NA, show.legend = FALSE)+
  facet_wrap(~car_names)+
  ggproto("CordRadar", CoordPolar, theta = "x", r = "x", start = 0, direction = 1, is_linear = function(coord) TRUE)


18.2 Простой пример: из двумерного пространства в одномерное пространство

Мы уже рассматривали связь между количество слов в рассказе и количеством слов и в рассказах М. Зощенко:


Мы уже смотрели коэффициент корреляции между этими переменными (r = 0.83).

Представим, что я перешел к новой системе координат:


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

zo %>% 
  select(n, n_words) %>% 
  prcomp(scale. = TRUE) %>% 
  broom::augment(zo) %>% 
  pivot_longer(names_to = "type", values_to = "value", n:n_words) %>% 
  mutate(type = recode(type, n = "количество и", n_words = "количество слов")) %>% 
  group_by(type) %>% 
  mutate(cor = str_c("r = ",round(cor(.fittedPC1, value), 2)),
         max = max(value)- sd(value)) %>% 
  ggplot(aes(.fittedPC1, value))+
  geom_point()+
  geom_label(aes(label = cor, y = max), x = -1.5)+
  facet_wrap(~type, scales = "free")+
  labs(x = "новая переменная", y = "старые переменные")


18.3 Многомерное шкалирование (MDS)

Многомерное шкалирование – преобразование из многомерного пространства в n-мерное пространство (чаще всего смотрят на n равное 2), которое старается как можно меньше исказить расстояния между наблюдениями.

iris %>% 
  select(-Species) %>% 
  dist() %>% 
  cmdscale() %>% 
  as_tibble() %>% 
  bind_cols(iris) %>% 
  ggplot(aes(V1, V2, color = Species))+
  geom_point()


Если по какой-то причине вы хотите использовать большую размерность итогового пространства, можно использовать аргумент k функции cmdscale() (по умолчанию он 2). Как видно из кода, я использовал функцию dist(), которую мы видели в предыдущем разделе: мы можем использовать любую другую матрицу расстояний, которую мы посчитаем (существует множество метрик расстояния, которые можно посмотреть в справке ?dist). Давайте, например, посмотрим на многомерное шкалирование расстояний Левинштейна-Димерау между стопсловами русского языка:

library(stringdist)
library(stopwords)

stringdistmatrix(stopwords("ru")) %>% 
  cmdscale() %>% 
  as_tibble() %>% 
  mutate(words = stopwords("ru")) %>% 
  ggplot(aes(V1, V2, label = words))+
  geom_text()


Как интерпретировать получившийся график? Часто мы не можем придать никакого значения получившимся осям, однако расстояния между точками на графике призвано отражать расстояние в многомерном пространстве. Так что, используя многомерное шкалирование

  • можно обнаружить, есть ли кластеры в многомерных данных
  • можно обнаружить, есть ли связь между наблюдениями, в том числе невыраженная переменными, которые есть в датасете. Например, из графика со стопсловами, видна “скрытая” переменная – длина слова.

В датасет записаны частотности некоторых слов в рассказах А. Чехова и М. Зощенко. Постройте многомерное шкалирование используя все переменные, и раскрасьте рассказы в зависимости от авторства. Делятся ли рассказы на кластеры? Как вы думаете почему?

18.4 Метод главных компонент (PCA)

Метод главных компонент – преобразование из многомерного пространства в n-мерное пространство (чаще всего смотрят на n равное 2), которое старается как можно меньше исказить корреляции между переменными.

library(broom)
iris %>% 
  select(-Species) %>%
  prcomp() %>% 
  augment(iris) %>% 
  ggplot(aes(.fittedPC1, .fittedPC2, color = Species))+
  geom_point()


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

Так как метод главных компонент старается сохранить как можно больше дисперсии из всех данных, в результате этот метод (да и многомерное шкалирование) очень чувствителен к дисперсии переменных. Это значит, что данный метод будет давать разные результаты в зависимости того, в метрах исследуемая переменная или в километрах. Чтобы предотвратить этот крен в сторону переменных с большей дисперсией, следует добавлять в функцию prcomp() аргумент scale. = TRUE, которые, соответственно нормализует переменные перед применением алгоритма:

iris %>% 
  select(-Species) %>%
  prcomp(scale. = TRUE) %>% 
  augment(iris) %>% 
  ggplot(aes(.fittedPC1, .fittedPC2, color = Species))+
  geom_point()


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

iris %>% 
  select(-Species) %>%
  prcomp(scale. = TRUE) %>% 
  summary()
Importance of components:
                          PC1    PC2     PC3     PC4
Standard deviation     1.7084 0.9560 0.38309 0.14393
Proportion of Variance 0.7296 0.2285 0.03669 0.00518
Cumulative Proportion  0.7296 0.9581 0.99482 1.00000

Ученые (к счастью) не договорились относительно порога, начиная с которого процент объясненной дисперсии является хорошим. Я обычно радуюсь значением больше 0.7 (т. е. при переходе к новым осям мы выкинули всего 30% дисперсии).

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

gospels <- read_csv("https://raw.githubusercontent.com/agricolamz/2019_data_analysis_for_linguists/master/data/gospel_freq_words.csv")
Parsed with column specification:
cols(
  word = col_character(),
  John = col_double(),
  Luke = col_double(),
  Mark = col_double(),
  Matthew = col_double()
)
gospels

word

<chr>

John

<dbl>

Luke

<dbl>

Mark

<dbl>

abide0.00206270630.00041614650.0002449780abraham0.00165016500.00194201690.0002449780abroad0.00041254130.00055486200.0009799118accusation0.00020627060.00027743100.0002449780accuse0.00041254130.00055486200.0002449780adultery0.00041254130.00041614650.0007349339afraid0.00082508250.00069357750.0017148457afterward0.00020627060.00055486200.0004899559amen0.00020627060.00013871550.0002449780andrew0.00103135310.00013871550.0009799118Next

123456...48

Previous

1-10 of 472 rows | 1-4 of 5 columns

PCA <- prcomp(gospels[,-1], scale. = TRUE)
row.names(PCA$x) <- gospels$word

library(ggfortify)
autoplot(PCA,
         shape = FALSE,
         loadings = TRUE,
         label = TRUE,
         loadings.label = TRUE)


Косинус угла между стрелочками соответствует коэффиценту корреляции между ними

cor(gospels[,-1])
             John      Luke      Mark   Matthew
John    1.0000000 0.5560482 0.6357893 0.6397344
Luke    0.5560482 1.0000000 0.7277001 0.7962913
Mark    0.6357893 0.7277001 1.0000000 0.7916982
Matthew 0.6397344 0.7962913 0.7916982 1.0000000

Мы точно так же можем работать не только с данными, но и с матрицей расстояния:

st_words <- tibble(words = stopwords("ru"))

stringdistmatrix(st_words$words) %>% 
  prcomp(scale. = TRUE) %>% 
  augment(st_words) %>% 
  ggplot(aes(.fittedPC1, .fittedPC2, label = words))+
  geom_text()


stringdistmatrix(st_words$words) %>% 
  prcomp(scale. = TRUE) %>% 
  summary()

18.5 Другие методы уменьшения размерности

Существуют и другие методы уменьшения размерности:

  • CA, MCA
  • LDA (Linear Discriminant Analysis), DCA (Discriminant Correspondence Analysis)
  • tSNE (t-Distributed Stochastic Neighbor Embedding)
  • и другие…



Report Page