Статистическое программирование на R: Часть 2. Функциональное программирование и анализ данных (исходники)Источник: IBM developerWorks Россия Девид Мертц (David Mertz)
R - мощный функциональный язык программирования и среда анализа наборов статистических данных. Будучи средой анализа, R позволяет создавать различные графические представления данных из командной строки. Читайте первую часть этой серии статей и статью Камерона Лэйрда об R - из них можно больше узнать об R, о платформах, на которых может работать R, а также о наборе доступных для нее пакетов. Как и интерактивные оболочки Python, Ruby, Эта статья - вторая часть рассказа об R. Первая статья знакомит читателя с некоторыми базовыми типами данных R, включая векторы и многомерные массивы (2-мерные массивы еще называют матрицами), массивы данных для "умных" таблиц, списки для гетерогенных коллекций и т.д. В прошлой статье были также выполнены базовый статистический анализ и построение графиков для большого массива данных, собранного одним из соавторов (Брэдом): эти данные - годичная история изменения температуры вокруг дома Брэда, собранная с трехминутными интервалами времени. Подобно большинству реальных данных, эти температурные данные содержат дефекты и погрешности измерения - и в этой статье мы будем пытаться обнаружить подозрительные данные. Наша статья решает две задачи. Во-первых, мы продолжим анализ данных, рассматривавшихся в предыдущей статье, чтобы подробнее рассмотреть возможности самого языка R. Во-вторых, мы исследует общие закономерности данных и покажем, как находить их, используя R. R как язык программированияРаспространяемый по лицензии GPL язык программирования R имеет двух предков: S/S-PLUS и Scheme (Lisp). Особенно следует подчеркнуть связь со Scheme, так как основные особенности функционального программирования в R унаследованы от Scheme. Внимательные читатели могли отметить примечательное отсутствие в предыдущей статье одного существенного аспекта - управления выполнением программы! В этой статье мы по-прежнему не затрагиваем эту тему. На самом деле в R есть отличные команды Объявляйте то, что вам нужноПолностью в духе функционального программирования в R можно сделать практически все с помощью простых декларативных операторов. В R есть две особенности, которые в большинстве случаев делают управление выполнением излишним. Во-первых, вы уже видели, что большинство операций над объектами коллекций работают поэлементно. Чтобы сделать что-то над элементами вектора данных, не требуется цикл, так как можно просто выполнить операцию сразу со всеми элементами вектора: Листинг 1. Поэлементные операции в R
Также можно оперировать только элементами с определенными индексами, используя "индексный массив": Листинг 2. Использование индексных массивов для выбора элементов
Или, что, возможно, лучше всего, можно использовать синтаксис, похожий на списочные выражения языков Haskell или Python, и оперировать только над элементами, имеющими требуемое свойство: Листинг 3. Использование предикативного выбора элементов
Внимательные читатели могут заметить, что в этих примерах используется присваивание с помощью знака Анализируем данные о температуреВ первой статье мы с помощью функции При первоначальном исследовании температурных данных была замечена аномалия в гистограммах. Она проявляется большим пиком наружной температуры вблизи 24 градусов Цельсия. Наше первое предположение заключалось в том, что эти пики отражают рассинхронизацию при записи, когда температура из внутреннего помещения записывалась в данные внешнего помещения (и, соответственно, наоборот). Чтобы проиллюстрировать возможности R, посмотрим, можно ли доказать или опровергнуть это предположение. Поиск аномалийПервый шаг в исследовании аномалий - это их нахождение. А именно, точечная аномалия должна характеризоваться большими скачками температуры с обеих сторон от точки данных. Еще конкретнее, мы можем ожидать, что 2 соседние с аномалией точки будут обычно намного выше или намного ниже, чем точка потенциальной аномалии. Например, простая последовательность температур (с трехминутным интервалом) "20, 16, 13" демонстрирует необычно быстрое падение температуры, но не порождает подозрения на одноточечную ошибку в среднем отсчете. Конечно, нельзя априори исключить существование других типов ошибок или погрешностей, затрагивающих не только единичные отсчеты данных. Наши первые идеи по идентификации неправильных измерений были довольно сложны. Можно обратить внимание на высокочастотные компоненты преобразования Фурье наших последовательностей. Или можно взять производные векторов температуры (возможно, вторые производные, чтобы найти изгибы графика). Можно попытаться выполнить свертки температурных векторов. Все эти операции встроены в R. Но потом мы оставили высокие помыслы и спустились на землю. Мы ищем простую закономерность - это отсчеты температур, имеющие большие скалярные разности с соседними измерениями. Другими словами, нам достаточно простого вычитания. Чтобы найти все разности между соседними точками данных, мы создадим таблицу данных, колонки которой будут соответствовать предыдущим, текущим и следующим точкам данных. Это позволит нам фильтровать всю таблицу данных, выбирая интересующие ряды. Листинг 4. Поиск одиночных погрешностей в данных уличной температуры
Итак, что мы имеем после фильтрации? Давайте посмотрим: Листинг 5. Просмотр погрешностей в данных уличной температуры
Эти данные говорят о том, что имеются точки с сильным отличием относительно соседних измерений. Но большая часть из них не выглядит как кандидаты на ошибки синхронизации. Например, в интервале времени 79501 температура 6.2 окружена двумя явно более высокими температурами. Однако ни одна из них не выглядит похожей на температуру внутри дома, скорее уж это очень холодный порыв ветра. С другой стороны, похоже, что мы имеем перестановки около временных интервалов 117059 и 12670. Средние значения температур близки к внутренней (24 градуса), а соседние измерения значительно ниже - хотя это и не мороз. Может быть, это измерения, сделанные весной. Оформление полезных операций в функциюТеперь нам нужно узнать, имеют ли наши кандидаты на перестановку соответствия в других отсчетах. Если мы найдем подходящие данные уличной температуры в одном из наборов данных температур внутри дома, это подтвердит нашу гипотезу. Но мы не хотим заново набирать программу, меняя везде Листинг 6. Оформление процесса обнаружения отклонений в функцию
Имея функцию, значительно проще обрабатывать различные наборы данных и устанавливать пороги отклонений. Запуск функции Листинг 7. Огромные температурные колебания в лаборатории
Показаний такого сорта мы не ожидали. Может быть, лучшее объяснение - это то, что Брэд открывал окно лаборатории в жестокий мороз. Если так, то Дэвид поражается эффективности камина Брэда, восстанавливающего тепло всего за 3 минуты вентиляции комнаты. Правильное объяснениеВозможно, просмотр полных данных по интересующим нас моментам времени разъяснит ситуацию: Листинг 8. Полный набор записей температур вблизи шага 47063
Во-первых, заметим, что отметки времени, возвращаемые функцией И все-таки, что же насчет загадки, начавшей наши исследования? Почему появляются пики около 24 градусов в измерении уличной температуры? Может быть, необходимо посмотреть на гистограмму более внимательно? В частности, можно использовать предикативный критерий для индексирования вектора и сузить гистограмму до интересующего нас температурного диапазона: Листинг 9. Сужение температурного диапазона
Рисунок 1. Гистограмма для улицы в суженной температурной области Посмотрев подробнее на локализованные температурные пики, можно обнаружить отдельные впадины справа от каждого пика. Они видны, если посмотреть на отклонения в десятые доли для промежутка рядом со значением 24.7 градуса. Наиболее вероятно, что это является следствием погрешности округления термометра. Отлично, но все же мы еще не уверены. Даже после некоторого сглаживания небольшой пик все-таки остается. Промежуточный статистический анализОдна из сильных сторон R - это способность рассчитывать линейные и нелинейные модели регрессий. Рассмотрим простой пример. Создадим два вектора: Листинг 10. Создание вектора регрессии
Можно подобрать прямую для этих значений: Листинг 11. Подбор линейной регрессии
Знак "~" означает формулу. Это действие указывает R найти коэффициенты A и B, которые минимизируют формулу Возможно, лучше было бы использовать аппроксимацию синусами и косинусами с периодами 1 день и 1 год. Такую модель можно попробовать, изменив формулу на следующую: Листинг 12. Попытка приближения тригонометрическими кривыми
Синтаксис этой формулы очень хитер: внутри вызовов Листинг 13. Результаты тригонометрической регрессии
Остаточная ошибка все еще велика (5.377), но утешим себя тем фактом, что погода в Колорадо исключительно непредсказуема. R предоставляет множество инструментов для анализа временных данных. Например, мы можем построить график функции автокорреляции для температуры в гостиной: Листинг 14. Функция автокорреляции температуры в гостиной
Рисунок 2. График функции автокорелляции температуры в гостиной Встроенная функция ЗаключениеИтак, мы использовали R для анализа структуры и аномалий в наборах данных, которые имеют точно такие же недостатки и потенциальные проблемы, как и практически все реальные научные данные. В этой статье мы также увидели, как стиль функционального программирования, реализованный в R, помогает быстро исследовать закономерности, данные и аналитические сценарии. В третьей части этой серии мы продолжим поиск закономерностей в больших наборах данных, используя более сложные статистические методы (но все равно затрагивая лишь малую часть богатейших возможностей R). |