[Из песочницы] Корреляционный анализ или Почему существуют странные корреляции
На данный опус меня навела публикация «Деньги, товар и немного статистики. Часть вторая», в которой автор исследовал зависимости между ценами на различные товары. Несколько смутило то, что несмотря на мастерское обращение с MatLab’ом, автор ни разу не упомянул об уровне значимости полученных корреляций. Ведь, связь между двумя величинами может и существовать, но если она статистически не значима, говорить о ней мы можем лишь в контексте рассуждений и домыслов.Пощупать данные «руками» долго не получалось, но вот выдался свободный час, и я, вооружившись R, двинулся в путь.
d = read.csv («data.csv», sep = »;») # загружаем данные names (d) <- c("time","oil", "gold", "iron", "logs", "maize", "beef", "chicken", "gas", "liquid_gas", "tea", "tobacco", "wheat", "sugar", "soy", "silver", "rice", "platinum", "cotton", "copper", "coffee", "coal", "aluminum") # присваиваем удобочитаемые имена
# в своем посте автор использовал среднее геометрическое (СГ) — я пошел проторенной им тропой. # так как в базовой комплектации R нет функции для расчета СГ, набросал свою: gm_mean = function (x, na.rm=TRUE){ exp (sum (log (x[x > 0]), na.rm=na.rm) / length (x)) }
d.gm = apply (d[,2:23], 2, gm_mean) # получаем значение СГ для всех групп товаров d.t = d[,2:23]/d.gm # получаем относительные цены apply (d.t, 2, shapiro.test) # проверяем нормальность распределения cor.m = cor (d.t, method = «spearman») # строим корреляционную матрицу Немаловажный момент — распределение нормированных цен на все товары отличалось от нормального (р-значение для критерия Шапиро-Уилка значительно меньше 0.001), что неумолимо приводит нас к тому, что использование относительно «доброго» для поиска взаимосвязей коэффициента корреляции Пирсона не представляется возможным. К счастью, существует его непараметрический аналог — тест Спирмена.
Итак, корреляционная матрица получена. Взглянем на нее:
Окей, корреляции имеют место быть, хотя значения rho уже поменьше. Найдем наиболее высокие уровни и проверим их значимость:
out <- data.frame(X1 = rownames(cor.m)[-1], X2 = head(colnames(cor.m), -1), Value = cor.m[row(cor.m) == col(cor.m) + 1])
for (x in 1: length (out$X1)) { print ( cor.test ( d.t[as.character (out[x,1])][[1]], d.t[as.character (out[x,2])][[1]], method = «sp»)$p.value) } Для экономии места скажу, что для всех обнаруженных корреляционных взаимосвязей р-значение было меньше 0.0001, что говорит о статистически значимом явлении. Корреляционная матрица представлена ниже:
1 gold oil 0.24514022 iron gold 0.25038733 logs iron 0.24462004 maize logs 0.25476675 beef maize 0.23984186 chicken beef 0.23853017 gas chicken 0.24810308 liquid_gas gas 0.25447529 tea liquid_gas 0.236790710 tobacco tea 0.241666411 wheat tobacco 0.255393512 sugar wheat 0.250564113 soy sugar 0.244092014 silver soy 0.258997415 rice silver 0.240304816 platinum rice 0.241810517 cotton platinum 0.234392318 copper cotton 0.249854519 coffee copper 0.232189120 coal coffee 0.248222621 aluminum coal 0.2423581
Как видим, полученные rho не превышают 0.3, что указывает на слабую силу связи (согласно шкале Чеддока). Фактически, оперировать такими данными можно, но всегда нужно понимать, что колебания цен одного товара будет не боле чем на 10% сказываться на цене своего «партнера» по корреляции.
Хотелось бы отметить, что похожая линия рассуждений должна использоваться при анализе других странных корреляций. Цифры могут играть с нами злые шутки.
Спасибо jatx за то, что дал повод поиграть с цифрами!