Julia — это новейший IT-язык, поэтому я решил его попробовать. Вопрос в том, стоит ли добавлять его в арсенал специалиста по данным?
Установка
Первое, что стоит знать о Julia — его очень легко скачать и использовать (я говорю про Mac, пользователям Windows желаю удачи). Также очень легко устанавливается ядро для работы с Jupyter.
Синтаксис
В отличие от Python Julia не является объектно-ориентированным языком, поэтому от некоторых весьма опрятных подходов в стиле Python придётся отказаться.
В Julia нет классов, поэтому приходится довольствоваться структурами, как и в MATLAB. Опять же как и MATLAB, Julia использует прекрасный встроенный внутрь языка синтаксис для линейной алгебры. Вместо модуля NumPy используется более интуитивно понятный синтаксис: A*x
, x'
и ./
для умножения, комплексного сопряжения и точечного деления.
Ещё одна вещь, требующая к себе внимания в Julia, — завершение функций и циклов ключевым словом end
. Однако вам приятно будет услышать, что причиной тому нечувствительность Julia к пробелам, поэтому вам никогда не встретится ошибка “несовместимое использование табуляции и пробелов в отступе”.
Типизация
Технически Julia всё ещё является языком с динамической типизацией. Это означает, что вам не нужно говорить ему, какой тип имеет та или иная переменная, так же как и в Python.
Тем не менее Julia поддерживает типизацию, что может привести к тому, что, в отличие от Python, переменная будет определённого типа. Это очень удобно по двум причинам:
- Код Julia работает быстрее, чем полностью динамические языки; если тип переменной определён, нет необходимости проверять его перед выполнением вычислений.
- Отладка становится проще, поскольку нельзя случайно назначить другой тип переменной. Чтобы добиться того же эффекта в Python, придётся потратить немало времени на реализацию операторов
assert
в каждой функции, и даже после этого что-то может пойти не так.
Поддержка Unicode!
Одна из самых привлекательных фич Julia.
При реализации математических выражений в MATLAB или Python часто встречаются такие переменные, как x_hat
или sigma
. А в Julia можно использовать символы Unicode в качестве переменных, в результате получив x̂
и σ
!
“А как я смогу запомнить комбинацию клавиш для x̂
или σ
? Не буду же я гуглить её каждый раз!”
Это серьёзное затруднение, но разработчики Julia находятся на шаг впереди нас. Для x̂
просто пишем x\hat ⇥
, а для σ
— \sigma ⇥
, точно так же, как в LaTex.
Циники могут подумать, что эта функция бесполезна, но я думаю, что она делает код гораздо более читаемым. Как сказано в Дзене Python: “Читаемость имеет значение”.
Каково писать на Julia?
Давайте посмотрим, как выглядит регрессионная логистическая модель в Julia.
function σ(x::Array{Float64,2})
return 1.0 ./ (1.0 .+ exp.(-x))
end
function fit(
X::Array{Float64,2},
y::Array{Float64,1},
epochs::Int64=100,
μ::Float64=0.0001
)
ε::Float64 = 0.00001
loss = []
X = vcat(X, ones(1,size(X)[end]))
dims, n_data_points = size(X)
w = randn(1,dims) for i in 1:epochs
X̂ = w*X
ŷ = σ(X̂)
cost = -sum(y'.*log.(ŷ .+ ε) .+ (1 .- y').*log.(1 .- ŷ .+ ε))
dc_dw = -sum((y' .- ŷ).*X,dims=2)'
w = w .- dc_dw * μ
append!(loss,cost)
end
return w,loss
end
function predict(X::Array{Float64,2},w::Array{Float64,1})
X = vcat(X, ones(1,size(X)[end]))
X̂ = w*X
ŷ = σ(X̂)
return ŷ
end
В этой реализации видим прекрасный пример того, как символы Unicode в Julia делают код более читаемым. Встроенная поддержка линейной алгебры упрощает код, убирая np.
каждый раз при выполнении сложения или умножения. Кроме того, типизированы вводы функций для проверки валидности типа и размерности входных данных .
Скорость!
Происхождение от C и типизация позволяют Julia улучшить скорость в сравнении с медлительным Python. И добиться этого можно без каких-либо значительных улучшений производительности кода.
Давайте вычислим первые 10,000 простых чисел с помощью простой функции Python:
def n_primes(n:int)->list:
primes = []
i = 2
while len(primes) < n:
prime_bool = True
for j in range(2,i//2+1):
if i%j == 0:
prime_bool = False
if prime_bool == True:
primes.append(i)
i += 1
return primes
Выполнение занимает 2 минуты 42 секунды. Давайте сравним с типизацией в Julia:
function n_primes(n::Int64)
primes = Int64[]
i::Int64 = 2
while size(primes)[1] < n
prime_bool::Bool = true
for j = 2:i÷2
if i%j == 0
prime_bool = false
end
end
if prime_bool == true
append!(primes,i)
end
i += 1
end
return primes
end
>> @time n_primes(10000)
7,55 секунд!
Julia компилируется в бинарный файл… и это довольно круто!
Для тех смельчаков, что хотят развёртывать код в дикой природе, компиляция в бинарный файл весьма полезна.
Разработчикам Python не чужды проблемы определения зависимостей и борьба с pip
для уверенности в совместимости пакетов. Изящное решение Julia состоит в компилировании в один бинарник. Во-первых, развёртывание приложения сопоставимо по простоте с запуском сервиса из бинарника, помещённого в контейнер Docker; во-вторых, запуск сопровождается теми же улучшениями в безопасности, что и в Go.
Но мне просто нравится Python…
Не позволяйте Julia вас остановить, непосредственно в него встроен интерпретатор Python, поэтому использовать Python так же просто, как Pycall.
using Pycall
packagename = pyimport(“packagename”)
Это действительно настолько просто! Pycall позволяет использовать все встроенные фичи и функции пространства имён (даже использование менеджеров контекста).
Пока всё звучит прекрасно, в чём же подвох?
Отладка не настолько проста, как в Python; возможно, это из-за того, что я знаком с диагностикой ошибок в Python, или Python просто более информативен в сообщениях об ошибках.
Вот простой пример для иллюстрации. Python:
… и Julia:
Мне кажется, один из них значительно чище другого…
Ещё одна проблема Julia — отсутствие поддержки библиотек машинного обучения, возможно, из-за его относительной молодости; но эта особенность весьма разочаровывает. У Julia есть врапперы для Pandas, TensorFlow и Sklearn, но они не помогают в получении предварительно обученной модели ResNet 50 или модели Берта, поэтому для их написания скорее всего будет использован Python.
Но сообщество Julia активно растёт, новые библиотеки, такие как Lathe and MLJ, создаются почти ежедневно, так что у нас ещё есть надежда!
Отсутствие объектов, основанных на классах, может сделать использование этих библиотек вне Python несколько громоздким. Например, Pandas df.loc[]
становится loc!(df, )
.
Наконец, в базовом пространстве имён Julia слишком много функций. С одной стороны, это позволяет добиться удобства и простоты написания кода на уровне MATLAB. С другой стороны, это снижает читаемость кода, поскольку зачастую сложно понять, существует ли функция по умолчанию, определена ли пользователем или импортирована из другого модуля.
Так стоит ли учить Julia?
Мой ответ да! Что вы теряете? Писать промышленный код бывает сложно из-за отсутствия доступных библиотек. Но Julia предлагает простой в освоении синтаксис, невероятную скорость выполнения кода, встроенный интерпретатор Python и множество других потенциальных улучшений в работе специалиста по данным. Учитывая растущую популярность, возможно, в будущем возникнет необходимость перехода, или ваш следующий проект будет жёстко ограничен в производительности. Julia может стать подходящим решением.
Читайте также:
- Улётные пакеты Julia для машинного обучения - мечта программиста!
- В поисках лучшей среды для Julia: Juno или Jupyter?
- Стоит ли заменить Python на Julia?
Перевод статьи Alexander Bailey: Should you learn Julia?