Блог им. elogunov

Как писать эффективный код на языке R

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

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

Начинающие же могут глянуть инфу в википедии, скачать дистрибутив и удобную среду для разработки.

1. Измеряем время, требуемое для выполнения некоторого куска кода 

Начинать надо с самого простого :)

Как писать эффективный код на языке R

2. Следим за деятельностью Garbage Collector

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

Чтобы включить вывод информации при срабатывании GC, нужно выполнить команду gcinfo(verbose=TRUE).

Как писать эффективный код на языке R

Расшифровку формата см. в справке: ?base::gc

3. Как найти части кода с наихудшей производительностью

В языке R есть встроенный профилировщик: ?utils::Rprof, ?utils::summaryRprof.

Что про него можно сказать? Он просто работает, хотя иногда бывает непросто разобраться в том, откуда взялась какая-нибудь анонимная функция.

Создатели IDE RStudio разработали пакет profvis, который упрощает задачу анализа результатов Rprof:
https://rstudio.github.io/profvis/ 
https://support.rstudio.com/hc/en-us/articles/218221837-Profiling-with-RStudio


4. Ускоряем чтение CSV файлов

Для примера возьмём минутные данные, скачанные с сайта Финама, а именно, данные по обыкновенным акциям Сбербанка.

Чтение этого файла размером 105 мегабайт с SSD-диска Samsung 850 Pro занимает 7.8 секунд. Тут явно что-то не так!
Как писать эффективный код на языке R

Посмотрим внимательно на файл...
Как писать эффективный код на языке R

… и избавимся от лишних преобразований в процессе чтения файла:
Как писать эффективный код на языке R

Чуть лучше, но не идеально!

5. Экономим место на дисках и ускоряем чтение маркетдаты из сетевых папок и других медленных хранилищ

При командной работе над стратегиями зачастую нет смысла дублировать данные на каждом из используемых компьютеров. Кроме того, некоторые типы данных (full order log) сами по себе могут занимать немало места, поэтому иногда имеет смысл немного оптимизировать их размер.

Данные в формате CSV зачастую очень хорошо сжимаются gzip и xz. В частности, файл из предыдущего примера можно сжать со 105 МБ до 11 МБ.

R может читать данные из различных источников и разжимать их на лету:

Как писать эффективный код на языке R

Более подробно — см. справку по команде ?base::connections

6. Пересохраняем данные в бинарном формате со сжатием

Если данные изменяются редко, а читать их нужно часто — есть смысл сохранить данные в бинарном формате RData вместо текстового CSV. Формат поддерживает сжатие (gzip, bzip2, xz) и имеет весьма неплохую совместимость между различными версиями R.

Как писать эффективный код на языке R

Экономия времени по сравнению с CSV — почти 75%. Размер сжатого файла составляет 8.6 МБ, что на 92% лучше оригинального CSV, и на 23% лучше, чем CSV + сжатие при помощи XZ.

7. Ускоряем XZ сжатие при сохранении данных в формате RData

Начиная с версии 5.2 утилита xz поддерживает распараллеливание при сжатии файлов. Соответственно, можно сохранить данные в формате RData без сжатия, сжать полученный файл с распараллеливанием и сменить расширение файла на ".RData". R сумеет прочитать полученный файл.

Как писать эффективный код на языке R

Для обеспечения надежности и кросс-платформенности кода рекомендую также добавить:
1. Вызов команды "xz --robot --version" с проверкой успешности выполнения (установлен ли xz?);
2. Разбор атрибута "XZ_VERSION" (поддерживает ли установленная версия сжатие? описание вывода с ключом --robot можно посмотреть в man xz);
3. Оценку потребления памяти для выбранного кол-ва потоков и степени сжатия (man xz? man xz!).

8. Как скормить всю свободную память линейной регрессии

Воспользуемся ранее считанными данными, чтобы построить линейную регрессию (иллюстративный пример, не ищите в модели глубокого смысла):
Как писать эффективный код на языке R

И сравним размер исходного набора данных с размером модели:
Как писать эффективный код на языке R

К встроенной функции расчёта линейной регрессии вопросов нет — она считает всё и сразу. Но если вы попробуете использовать её в бэктесте парного трейдинга — я вам не завидую.

Выход? В некоторых случаях лучше вручную сосчитать то, что вам реально нужно. Например, коэффициенты и остатки линейной регрессии.
Как писать эффективный код на языке R
Таким образом, вместо 320 МБ памяти нам потребовалось всего 11 МБ.

9. Заглядываем внутрь объекта...

Иногда возникает необходимость заглянуть внутрь объекта, чтобы выявить причины чрезмерного расхода памяти, либо чтобы получить доступ к какому-то атрибуту, до которого иначе не добраться. Для этого можно воспользоваться функцией str(). Посмотрим на примере линейной регрессии, сосчитанной в предыдущем пункте:

Как писать эффективный код на языке R

10.… и находим вовсе не драгоценные минералы :(

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

Дело в том, что при сериализации объектов (вызов функции serialize(); сохранение в файл Rdata функцией save(); передача на кластер, созданный при помощи пакета parallel), содержимое таких ссылок захватывается в большинстве случаев. Последствия? Гигантские RData файлы, излишние затраты времени на передачу объектов на кластер, нехватка памяти и т.д.

Разумеется, если вы не сохраняете объект с множеством ссылок на диск и не передаёте его на кластер — проблем со ссылками на environment'ы не будет. Всё-таки R написан весьма умными людьми, и не будет лишний раз копировать данные, когда это не нужно.

Как писать эффективный код на языке R

Вот так одна маленькая ссылка на environment может превратить объект размером 168 байт в объект размером 123 мегабайта (при сериализации). А ещё этого не видно при помощи функции object.size().

Если вы используете функцию new.env() или возвращаете функцию из функции — можно очень легко захватить ссылку на environment, содержащую какую-нибудь большую переменную. Иногда есть смысл убрать лишние ссылки, присваивая им значение, возвращаемое emptyenv().

11. Об environment'ах, list'ах и присваиваниях

Объекты большинства типов в R являются неизменяемыми. Что это означает на практике? Если вы присваиваете значение элементу большого объекта — происходит создание измененной копии объекта.

Есть несколько исключений из правила неизменяемости объектов, одним из которых являются переменные типа environment.

Допустим, мы накапливаем результаты расчётов и складываем их переменную:

Как писать эффективный код на языке R

В случае с переменной типа list будет происходить копирование набора ссылок на элементы списка, а в случае с переменной типа environment этого происходить не будет. Если списки, с которыми вы имеете дело, содержат большое количество элементов — постоянное копирование будет бить по производительности.

12. Циклы, *apply() и здравый смысл

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

Плохо:
Как писать эффективный код на языке R

Хорошо:
Как писать эффективный код на языке R

«Мы научим мир тормозить»:
Как писать эффективный код на языке R

Во многих случаях циклы можно заменить на вызов функций:
1. lapply(): обрабатывает vector или list, возвращает list (см. часть 10: накапливать результаты в list самостоятельно — медленно);
2. sapply(): обрабатывает vector или list, и может упростить результат до вектора или матрицы;
3. mapply(): аналог sapply(), пригодный для функций нескольких переменных;
4. eapply(): обрабатывает environment, возвращает list (см. часть 10);
5. Vectorize(): векторизует функцию по выбранному аргументу;
6. Map(), Reduce(), …: см. map, reduce.

Как писать эффективный код на языке R

13. Вновь о линейных регрессиях

Вернёмся к коду из части 8:
Как писать эффективный код на языке R

Посмотрите внимательно на расчёт коэффициентов регрессии. Два транспонирования, три умножения, одно обращение.

К счастью, в R есть функции, быстро вычисляющие t(x) %*% y и x %*% t(y): crossprod() и tcrossprod(). С их помощью код можно переписать следующим образом:
Как писать эффективный код на языке R

Также можно сосчитать псевдоинверсию матрицы regr.x через SVD-разложение:
Как писать эффективный код на языке R

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

14. Быстрые сборки R

Компания Revolution Analytics, впоследствии купленная Microsoft, проделала огромную работу по оптимизации R. Их продукт Revolution R теперь известен как Microsoft R Open.

Одним из преимуществ этой сборки является использование библиотеки Intel Math Kernel Library, которое значительно ускоряет матричные операции (заметно при работе с большими матрицами).

Где скачать: https://mran.microsoft.com/download
Инструкция по установке: https://mran.microsoft.com/documents/rro/installation

Если всё сделано правильно, после установки вы увидите нечто подобное:
Как писать эффективный код на языке R

Бенчмарки: https://mran.microsoft.com/documents/rro/multithread
Как писать эффективный код на языке R

15. JIT-компилятор

Во времена версии 2.13 интерпретатора R один из его ведущих разработчиков создал пакет compiler, который значительно улучшил производительность R при исполнении кода с циклами. Эффект от его использования порой настолько ощутим, что в настоящее время пакет включен в стандартную поставку R, а для всех стандартных функций байткод генерируется на этапе сборки соответствующих пакетов.

Как писать эффективный код на языке R

Если вы запускаете скрипты с большим кол-вом циклов и ветвлений — попробуйте включить JIT-компиляцию командами:

Как писать эффективный код на языке R

Подробнее о функциях пакета можно посмотреть в справке: ?compiler::cmpfun.

Функция, которая подверглась компиляции, приобретает дополнительный атрибут «bytecode»:
Как писать эффективный код на языке R

Если вы оформляете свой код в виде пакетов — включить генерацию байткода при сборке пакета можно добавив строчку "ByteCompile: yes" в файл "DESCRIPTION".

16. Невыполненные обещания

Интерпретатор языка R предпочитает не выполнять обещания, если это не имеет последствий. О чём я вообще? Да об объектах типа "promise".

Изобразим подобие логгера:
Как писать эффективный код на языке R
Как писать эффективный код на языке R
Логгер этот не имеет ни малейшего понятия о том, будет ли реально записано сообщение, или же можно даже не надрываться, склеивая его кусочки. Поэтому я прибегнул к хитрости, выполнив склеивание кусочков сообщения в значении по умолчанию одного из аргументов функции log.write.msg(). И если реального обращения к этому аргументу не произойдет — значение по умолчанию вычислено не будет.

Можете мне поверить: если ваш код пишет многие миллионы записей уровня TRACE в лог, а в продакшене вы используете уровень сообщений DEBUG, под который попадает пара тысяч строчек лога — экономия на склеивании кусочков сообщений составит десятки минут, если не часы.

17. Объектно-ориентированное программирование в R

Язык R содержит несколько встроенных моделей для ООП, и ещё большее их количество реализовано в различных пакетах.

Итак:
1-3: S3, S4, reference classes;
4: Эмуляция объектов на основе замыканий (closures);
5: R.oo;
6: R6.
(это только то, что с ходу вспомнилось и нашлось)

На мой взгляд, ни одна из встроенных моделей (1-3) не отличается ни хорошим быстродействием, ни удобством.

Если вам не требуется наследование — можно реализовывать объекты на основе замыканий:
Как писать эффективный код на языке R

В остальных случаях — мой выбор за R6. Быстрый, удобный, с минимальными накладными расходами. Возможностей поменьше, чем в C++, но это даже хорошо! :)

Как писать эффективный код на языке R

Но есть и нюансы, обусловленные тем, что было изложено в части 10.
1. Желательно отключать клонирование объектов. Оно реально редко нужно, но увеличивает memory footprint мелких объектов в 5 раз.
2. Нужно аккуратно подходить к выбору environment'а в котором создаются генераторы объектов (результат деятельности функции R6Class; экземпляры класса создаются путём вызова метода $new() у генератора). Идеальный случай — когда генераторы размещены внутри пакета, тогда они почти наверняка ничего лишнего не захватят из global environment.

18. Распараллеливание вычислений между несколькими экземплярами интерпретатора

Ядро интерпретатора R (core и унаследованные от него версии, такие как Microsoft R Open) является однопоточным, поэтому для простейшего распараллеливания требуется запуск нескольких его экземпляров, а также механизм для взаимодействия между процессами.

Задачу написания удобного механизма для параллельных вычислений в R пыталось решать немало людей (поищите слово «parallel» в списке пакетов), однако наиболее качественное (на мой взгляд) решение получилось у Revolution Analytics. Их пакет foreach способен работать с несколькими бэкендами:
1. предоставляемым стандартным пакетом parallel;
2. предоставляемым пакетом doSNOW (он был взят за основу при создании пакета parallel);
3. предоставляемым пакетом doParallel;
4. предоставляемым пакетом doMC.

В целом сочетание parallel+foreach можно использовать из коробки и получать ускорение вычислений.

parallel позволяет создавать кластер двумя способами — fork'ом процессов (?parallel::makeForkCluster) или запуском экземпляров Rscript (?parallel::makePSOCKcluster). Плюсы и минусы этих вариантов:
1. Fork cluster:
+ Мгновенный запуск;
+ Все данные с мастер-ноды сразу после запуска присутствуют на всех нодах кластера;
+ Не нужно тратить время на загрузку пакетов на нодах кластера;
— При срабатывании GC на нодах кластера существенно растет расход памяти в системе; если память закончится — кластер упадёт (или мастер-нода, как повезёт);
— Не работает под Windows;
2. PSOCK cluster:
+ Работает на всех ОС;
+ Максимальная гибкость в раздаче данных на ноды кластера и в подгрузке пакетов;
— Расходуется время на запуск кластера, раздачу данных и подгрузку пакетов;
— «Из коробки» нестабильно запускает кластер более чем из 16 нод; требуется специальная обёртка вокруг Rscript, которая будет ожидать появления слушателя у порта, прежде чем дать мастер-ноде к нему коннектиться;
— Требуется доработка напильником для распараллеливания раздачи данных (скинуть данные во временный файл и прочитать его параллельно на всех нодах).

И о других способах.

1. doMPI + Rmpi: из коробки не удалось заставить работать достаточно быстро.
2. SparkR: сложен в установке, модель вычислений подойдет не для всякой задачи.

19. Распараллеливание вычислений внутри интерпретатора

Вот как выглядел вызов кода на C++ из R лет 10 назад. Залезаешь в чёрную-чёрную консоль, колдуешь "R CMD SHLIB bla-bla-bla", делаешь dyn.load() полученного бинарника, и пытаешься чего-нибудь повызывать функциями .C(), .Call(), .External(). А чтобы взаимодействовать с R'овскими объектами — приходилось лезть в исходники интерпретатора и читать R Internals.

Теперь это всё практически не нужно, потому что появился пакет Rcpp. Для работы этого пакета потребуется установить Rtools  — тулчейн, используемый для сборки интерпретатора R.

Для распараллеливания кода удобно использовать пакет RcppParallel, в основе которого лежит библиотека Intel Thread Building Blocks. К сожалению, к ядру интерпретатора R нельзя обращаться из разных потоков, поэтому в определенных случаях вам потребуется самостоятельно реализовывать некоторые функции или подключать сторонние библиотеки. Для работы с векторами и матрицами я рекомендую использовать RcppArmadillo (документация к Armadillo); в некоторых случаях сгодится RcppEigen.

Разумеется, скорость разработки на C++ получается ниже, чем на R, однако в вычислительных задачах сочетание библиотек Rcpp+RcppParallel+RcppArmadillo позволяет выжать из железа практически всё.

20. Переупаковка объектов

Этот вопрос я рассмотрю на примере класса timeSeries из пакета timeSeries.

Допустим, у нас есть экземпляр такого класса, в столбцах которого содержатся цены некоторых инструментов, и мы хотим к каждому столбцу применить 100 раз экспоненциальную среднюю скользящую. Записать это можно примерно таким образом:
Как писать эффективный код на языке R

Если вы обратили внимание на часть 3, то рано или поздно вы обнаружите, что немало времени уходит на создание объектов типа timeSeries. Но ведь объект создается один раз, в самом начале — спросите вы. А вот и нет. Заглянем в вариант функции apply(), который будет вызываться для класса timeSeries:
Как писать эффективный код на языке R

Видим, что объект разбирается на атрибуты, преобразуется в матрицу (?timeSeries::getDataPart), обрабатывается, а затем преобразуется обратно в объект класса timeSeries. Если избавиться от лишних преобразований типов — код будет работать быстрее:

Как писать эффективный код на языке R

Пока что на этом всё. Если я вспомню ещё какие-то интересные детали, а также увижу интерес к теме — будет продолжение.
★32
Отлично, но статья для хабра
avatar

Ray Badman

Интересно, но меня интересует чисто практический вопрос по возможностям R по сравнению  с alglib. Реализованы ли в R в виде вызываемых функций 

1. Многомерная линейная регрессия методом наименьших модулей и других робастных статистик?
2. Многомерная линейная регрессия методом включения-исключения в том числе посредством робастных статистик? 

Просто в alglib реализован только МНК, в принципе написать программу включения-исключения с МНК, используя регрессию с МНК, несложно. Но  использование недифферинцируемых оптимизируемых статистик (например, модуль) — это уже «гемморой». 
avatar

А. Г.

А. Г., Конкретные методы нужно искать, но на тему многомерных робастных линейных регрессий уж точно есть чего посмотреть.

www.rdocumentation.org/packages/robustbase/versions/0.93-5/topics/lmrob
cloud.r-project.org/web/packages/robustbase/robustbase.pdf (MM-estimators)

cloud.r-project.org/web/packages/gamreg/gamreg.pdf (L1, elasticnet, ridge regressions)
cloud.r-project.org/web/packages/elasticnet/elasticnet.pdf (lasso, elasticnet)
cloud.r-project.org/web/packages/lmridge/lmridge.pdf (ridge regression)
cloud.r-project.org/web/packages/DetR/DetR.pdf 

Forward-backward selection видел только для обычного МНК: 
stat.ethz.ch/R-manual/R-patched/library/MASS/html/stepAIC.html
avatar

Eugene Logunov

Eugene Logunov, спасибо, но первая две ссылка совсем не то: это взвешенный МНК, где самому надо задавать веса. Со второй надо разбираться, буду читать.
avatar

А. Г.

А для Матлаба такое будет? 
avatar

Kot_Begemot

Kot_Begemot, о май гад, вы серьезно, есть ещё и люди, использующие *это*?
avatar

MadQuant

MadQuant, шучу, конечно, сам-то я на Qlua пишу и на MQL c Visual Basic-ом.
avatar

Kot_Begemot

MadQuant, есть, причем они есть в вполне себе топ-командах. естественно, что  тренд такой, что (по факту) использование ограничено.
да, просто, удовлетворите интерес: у Вас может к каким-то конкретным элементам матлабовой среды коммент относится?
avatar

flextrader

flextrader, из того, что помню — работа со строками ужасная, ООП реализован через ж… у, в принципе синтаксис древний и неповоротливый а-ля Паскаль-лайк
avatar

MadQuant

flextrader, ещё прошу прощения, топ-команды — это например кто? У нас вот топ-команда вроде даже на международном уровне, и про матлаб многие даже не слышали полагаю, и уж подавно никто не использует.
avatar

MadQuant

MadQuant, матлаб в узко специфичных командах видел.
avatar

Андрей К

MadQuant, только православный VBA в Экселе! 
avatar

Анрил

Kot_Begemot, Не, по матлабу такое не выдам) У меня на нём полгода опыта едва наберётся.
avatar

Eugene Logunov

Eugene Logunov, 
avatar

Kot_Begemot

Начинающие же могут глянуть инфу в википедии

Начинающим лучше сразу учить питон, а не это доисторическое чудо лечить плясками с бубном, чтобы, написав 10 строк кода вместо одной, заставить его работать чуть быстрее или жрать меньше памяти)
avatar

MadQuant

MadQuant, физики до сих пор пишут на фортране и прекрасно себя чувствуют. 
avatar

SergeyJu

SergeyJu, пишут на том, что смогли нормально выучить. Либо для поддержания имеющеся инфраструктуры. Мне, как человеку, знающему  и Питон, и Р, в голову не придет разрабатывать что-либо с нуля на Р. Так же, как и людям, знающим Си, не придет в голову начинать новый проект на фортране.
avatar

MadQuant

MadQuant, люблю «специалистов» на СЛ:  Python -  1991 год. 
avatar

Glk

Glk, угу, а язык S — 1976 год, поэтому даже базовый синтаксис R не соответствует никаким современным стандартам
avatar

MadQuant

MadQuant, си — тоже архаичный в своей основе язык. На мой взгляд, неудобный с самого Карниган-Ричи. Мой опыт общения с Питоном отрицательный. Чтобы заставить его работать быстро, пришлось переписывать все трудоемкие вычисления на си. И нафига козе баян? 
avatar

SergeyJu

SergeyJu, ну здесь надо идти от того, что вам от языка нужно — скорость работы, или скорость и удобство разработки и мэинтенса. Если первое — это Си без вариантов. Если второе — то скриптовые языки, типа Питона. Я так понял, вы захотели решить задачу номер 1 на питоне — и, конечно, не получилось.
Возможно, вам подойдут варианты «между» — Ява или C#
avatar

MadQuant

MadQuant, идти, конечно, нужно от задачи. Физикам, особенно теоретикам,  обычно нах не нужно ООП, зато нужна молотилка для чисел. И тут фортран лучше Си, не зря он так и называется — транслятор формул. Что лучше подходит для обработки ценовых рядов можно поспорить, конечно, но скорее всего нет универсально наилучшего решения.
avatar

SergeyJu

MadQuant, Ты ведь не говоришь учить Ассемблер, бедет еще быстрее чем на С. ПО сути С через лет 10 станет как ассемблер лет 10 назад, никому не нужный, кроме специфических задач по декодингу. 
avatar

Gravizapa

Gravizapa, я не говорю учить ассемблер, но если реально нужна скорость — люди пишут на сях, а никак не на питоне. А хфт-конторы критические участки кода и на ассемблере пишут
avatar

MadQuant

MadQuant, Ну так вот именно, если скорость, то ассемблер. Си это уже элемент абстракции., но его выбирают из за существенно более высокой скорости написания.  Питон еще более высокий уровень. И с ростом сложности задач от СИ откажутся как от Ассемблера в свое время. Конечно в узких задачах останется, но не более.
avatar

Gravizapa

Gravizapa, вы ударились в философию. Пока такое время еще не наступило — C/C++ по-прежнему в топе по использованию (в отличие от Р): https://blog.newrelic.com/technology/most-popular-programming-languages-of-2019/
avatar

MadQuant

MadQuant, а много здесь людей, у которых всё идеально, но из-за скорости ТС сливает/недополучает? ) Я думаю, что если ТС в принципе рабочая, довести её до ума по скорости — не такая большая проблема. В конце концов, если скорость это единственная причина недополученной прибыли, можно инвестировать в профессионала.
avatar

Dmitryy

Dmitryy, все торгуют по-разному. Даже моя простая система на российском рынке загружает данные по 100+ бумагам. Правда, торгует она только раз в месяц. А если бы я захотел сделать систему, торгующую раз в минуту, и не на российском рынке, а на американском (несколько тысяч тикеров) — Питон бы уже по скорости близко не справился.
avatar

MadQuant

SergeyJu, а что вы такое писали? Numpy пробовали?
avatar

Михаил

Михаил, не пробовал.
avatar

SergeyJu

SergeyJu, без него никто не пишет на питоне математические расчеты — по сути это внутри библиотека на C для операций над многомерными тензорами.  
avatar

Михаил

Михаил, я и не писал, писал мой сотрудник. Я на 99,9% уверен, что подобные библиотеки он использовал. Аспирант ВМК, причем на редкость продвинутый. 
avatar

SergeyJu

MadQuant, Вы как человек знающий и Р и Питон, если что-то на коленке нужно проверить всегда выбираете Питон? Я, например, до интереса к финансовым рынкам знал только .Net/C# и JS, сделал выбор в пользу R, потому что мне понравился формат работы с векторами и матрицами, там это все-таки не просто массивы, а именно тип данных. И меня вдохновила возможность вызова обычных функций с одним параметров типа:

> sqrt(4)
[1] 2
> sqrt(c(4, 16, 36))
[1] 2 4 6


Возможно Питон тоже так умеет?
avatar

Dmitryy

Dmitryy, да — есть поддержка векторных операций над любым многомерным тензером. Для этого существует Numpy, если есть GPU то PyTorch. А также Pandas — изначально написал AQR Capital Management  специально для быстрых операций с рядами котировок. Основной объект — таблица с заголовками столбцов (например тикерами) и строк (например даты). Можно проводить любые операции над всеми элементами сразу. Операции агрегации в скользящем и расширяющемся окне (в одну операцию считаются всякие индикаторы вроде скользящих средних и т.д.).
avatar

Михаил

Михаил, интереса ради гугланул про Pandas, похоже его можно и в RStudio использовать. Но в целом, с практической точки зрения, у Питона несомненно больше плюсов. В конце концов, если не получится с финансами, всегда можно стать бекенд или ML разработчиком :)
avatar

Dmitryy

Михаил, 
векторных операций
надо отметить наверно, что не только типовых линейных, но и  как раз (отмеченных Вами) т.н. «агрегативных» — всего комплекса стат.операций, например, или, экстремумов, сортировок (в 1строку).
avatar

flextrader

flextrader, сделать можно действительно многое, все не перечислишь — еще выбирать любые данные по номеру в измерении, по метке, условию, логическому массиву и SQL-like операции по объединению данных из нескольких DataFrame. Не даром Pandas основной инструмент для операции с данными, если они в память влезают. 
avatar

Михаил

Dmitryy, конечно умеет,
4**0.5
а для второго numpy подключаете и пишете
np.power([14, 16, 36], 0.5)
avatar

MadQuant

О недостатках R можно писать много и долго. Это один большой недостаток, начиная с самого языка и заканчивая системой пакетов.
После того, как 3-4 года назад прекратил какие-либо отношения с ним, чувствую себя намного лучше.
С Удавом Каа все  тоже самое, и гораздо больше,  решается гораздо проще, лучше и быстрее.
avatar

3Qu

3Qu, Среди всех языков, которыми я владею, я не могу назвать ни одного, который не имел бы недостатков.
avatar

Eugene Logunov

Eugene Logunov, беда R не в том, что у него есть недостатки, а в том, что у него нет достоинств.
avatar

3Qu

3Qu,
у него нет достоинств
А если найду? :D

1. Высокая скорость разработки по сравнению со многими general purpose языками — Java/C#/C++/C/etc. Python — скорее ближе к general purpose языкам, но насчёт его выразительности и скорости разработки на нём я ничего утверждать не буду.
2. Бесплатен в отличие от Maple, MATLAB, Mathcad. Реальным конкурентом для разработки стратегий из этих трёх можно назвать лишь MATLAB.
3. Огромное количество библиотек, реализующих классические и современные методы статистики. Заявляемая высокая производительность языка Julia бесполезна как раз из-за небольшого выбора библиотек.
4. В отличие от языков типа MQL4/MQL5 — на R можно делать бэктесты на более высоком уровне (в терминах return'ов и весов инструментов или позиций), не спускаясь до шевеления ордерами.
avatar

Eugene Logunov

Eugene Logunov, python все это имеет и может. А скорость разработки Питон выше всяких похвал.
Множество пакетов R — так это в основном мусор.
А один из основных недостаток R — полное отсутствие возможностей signal processing.
Питон, также далеко не чемпион по скорости, но где-то раз в 5-10 быстрее R.
Про MQL лучше не будем, здесь кроме мата у меня других слов нет.)
avatar

3Qu

автор молодец, держи плюс
avatar

Glago

Спасибо! Сохранил в избранное, буду перечитывать, узнал много полезного для себя, как например то, что объекты клонируются, не мог о таком даже представить :)
avatar

Dmitryy

Dmitryy, и это при том, что он изначально не писался под распараллеливание и оно там через костыли! Поэтому однозначно matlab/octave :)
avatar

bstone

чувствуется, не один пуд соли съеден =)
avatar

Андрей К

И R и Питон — языки из мира Линукс. На винде они периодически лажают.

И это, главное. Питон — сакс. Решение для нищебродов написанное нищебродами-студентами.


Если в R есть пакет и он должен делать регрессию — он будет делать регрессию. А если в Питоне есть sklearn и он должен делать регрессию, то можно умереть и убиться об стену, но регрессию этот долбаный склёрн не сделает.
avatar

ch5oh

Обалденно.
avatar

tashik

интересно почему в Python не встроят JIT-compiler «из коробки», без доп. строчек кода, либ и танцев с бубном?
avatar

:)

:), Потому что функции в питоне могут менять свое поведение в зависимости от вызова. Поэтому для реализации JIT нужно описывать каждый отдельный кейс
avatar

zerohedge

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

Gravizapa

хороший, годный текст !
если написали сами — респект

Язык R я зауважал после того как он с легкостью обработал таблицу в 8 млн строк и 12 столбцов.
Но как-то кодить на нем у меня не получается…
avatar

Врач-бондиатОр

Кстати, есть еще язык для статистики SAS.
Почему никто его не упоминает? )
avatar

Врач-бондиатОр

Врач-бондиатОр, Сравнения говорят в пользу MATLAB/R/Python:

stanfordphd.com/Statistical_Software.html
www.r-bloggers.com/whats-the-best-statistical-software-a-comparison-of-r-python-sas-spss-and-stata/
www.r-bloggers.com/python-r-vs-spss-sas/

Но наверняка какие-то задачи можно решать и менее популярными пакетами. Годятся ли они как основной инструмент для проведения исследований, вот в чём вопрос.

Среди моих знакомых, насколько мне известно, лишь двое имели дело с SAS. Из знакомых любителей R — многие перешли на Python за последние пару лет, особенно те, кто фанатеет по Deep Learning.
avatar

Eugene Logunov

Eugene Logunov, 
Среди моих знакомых, насколько мне известно, лишь двое имели дело с SAS.

В МГУ на ВМК некоторое время назад на кафедрах, связанных с матстатом, методами мат. прогнозирования и т.д., SAS преподавали много, практикумы на нем были. Связано это с многолетним сотрудничеством факультета и SAS-Россия.
Вот новость какую-то очередную о сотрудничестве сходу нашла
cs.msu.ru/news/1381

Выпускники потом в качестве первого места работы выбирали этот SAS-Россия, а оттуда уже потом в другие места работать. Где действительно R или Matlab уже использовали.
avatar

Анастасия К


....все тэги
UPDONW