Julia是一种相对较新的编程语言,在机器学习领域越来越受欢迎。这篇文章将解析为什么以及如何使用Julia进行机器学习。
本文来自《数据黑客》,登录官网可阅读更多精彩资讯和文章。
与其他机器学习语言相比,Julia的主要优势是速度。Julia的速度优势来源于两点:第一,它是一种编译语言;第二,它是为并行而设计的。
尽管具有速度优势,但是Julia的语法并不是很复杂,它更像脚本语言,从Python或R切换到Julia相对容易。
Julia越来越受欢迎,并且变得越来越成熟,社区也在高速发展。尽管其规模仍然远小于Python社区,但这是一个很好的信号,表明社区和三方库的数量都在增长。
与Python和R一样,可以在Jupyter Notebook中直接运行Julia。
以下是将Julia安装到Jupyter Notebook的方法:
using Pkg
Pkg.add("IJulia")
在进入机器学习部分之前,要先导入和准备数据。这里我将介绍三个基本步骤:导入csv文件,对分类变量进行独热编码,拆分训练集和检验集。
使用Julia的第一步是导入数据,我们使用经典的Iris数据集。要将csv文件作为数据框导入,需要添加库“CSV”和“ DataFrames”,如下所示。然后,使用“ CSV.File”函数读取csv文件,并使用DataFrame函数将其转换为数据框。
# import a csv file
import Pkg; Pkg.add("CSV")
import Pkg; Pkg.add("DataFrames")
using CSV, DataFrames
iris = DataFrame(CSV.File("mypath//iris.csv"))
部分模型要求对分类变量进行独热编码(one-hot encoding)。可以使用“Lathe”库实现,它提供了OneHotEncode函数,这个函数会将数据框转换为OneHotEncoded数据框,然后使用“select”函数删除原始列。
import Pkg; Pkg.add("Lathe")
using Lathe
scaled_feature = Lathe.preprocess.OneHotEncode(iris,:variety)
iris = select!(iris, Not([:variety]))
first(iris,5)
为了评估模型的预测性能,需要将数据集拆分为训练集和检验集。我们使用“Random”库实现这一点,选择一个随机的索引子集并将其视为训练集,而未选择的索引则作为测试集:
using Random
sample = randsubseq(1:size(iris,1), 0.75)
train = iris[sample, :]
notsample = [i for i in 1:size(iris,1) if isempty(searchsorted(sample, i))]
test = iris[notsample, :]
Julia的机器学习资源分布在不同的软件包中。Julia未能像其他机器学习编程语言(如Python和R)一样受欢迎,有时查找特定的模型需要一些额外的工作。
令人备受鼓舞的是,有团队正在重组机器学习模型。到目前为止,有两个软件包正在争夺成为Julia的首选机器学习工具箱:MLJ和Scikit Learn。
这两个库都很棒,但是还没有完全完成。因此,有必要先介绍两个较小的库:“GLM”(广义线性模型)和“ DecisionTree”(构建以决策树为基础的模型),然后再介绍更全面的软件包。
以下示例将使用GLM库在iris数据集上拟合三个逻辑回归模型。GLM使用“公式(formula)”接口,该接口在面向统计的库中很常见。我们可以指定一个族(例如Binomial)和一个链接类型(Logit Link),以创建所需的GLM模型。
import Pkg; Pkg.add("StatsModels")
import Pkg; Pkg.add("GLM")
using DataFrames, GLM
fm_setosa = @formula(Setosa ~ sepallength + sepalwidth + petallength + petalwidth)
lm_setosa = glm(fm_setosa, train, Binomial(), LogitLink())
pred_setosa = predict(lm_setosa, test)
fm_virginica = @formula(Virginica ~ sepallength + sepalwidth + petallength + petalwidth)
lm_virginica = glm(fm_virginica, train, Binomial(), LogitLink())
pred_virginica = predict(lm_virginica, test)
fm_versicolor = @formula(Versicolor ~ sepallength + sepalwidth + petallength + petalwidth)
lm_versicolor = glm(fm_versicolor, train, Binomial(), LogitLink())
pred_versicolor = predict(lm_versicolor, test)
preds = hcat(pred_setosa, pred_virginica, pred_versicolor)
以下是联合预测概率(“preds”变量):
将每行的三个预测概率转换为每行一个类别的预测,采用三个概率值中的最高值:
# Reclass by maximum predicted probability
preds_cat = String[];
for i in 1:nrow(DataFrame(preds))
if pred_setosa[i] >= pred_virginica[i] && pred_setosa[i] >= pred_versicolor[i]
preds_cat = vcat(preds_cat ,"Setosa")
elseif pred_versicolor[i] >= pred_virginica[i] && pred_versicolor[i] >= pred_setosa[i]
preds_cat = vcat(preds_cat ,"Versicolor")
elseif pred_virginica[i] >= pred_versicolor[i] && pred_virginica[i] >= pred_setosa[i]
preds_cat = vcat(preds_cat ,"Virginica")
end
end
preds_cat
经过重新分类的“preds_cat”数组:
最后使用简单的for循环计算测试集的预测精度:
# Compute Accuracy of GLM
correct = 0
actual = orig_col[notsample]
n=length(actual)
for i in 1:n
if actual[i] == preds_cat[i]
correct = correct + 1
end
end
println(correct / n)
接下来是拟合决策树模型。首先,重新导入iris数据集,因为决策树支持使用分类变量。然后,创建DecisionTreeClassifier实例,使用一个超参数max_depth。最后是使用预测函数对测试集进行预测,计算模型的预测精度。
import Pkg; Pkg.add("DecisionTree")
# re import iris, because RandomForests will handle the categorical variable
iris = DataFrame(CSV.File("C://Users//jkorstan//Desktop//iris.csv"))
train = iris[sample, :]
notsample = [i for i in 1:size(iris,1) if isempty(searchsorted(sample, i))]
test = iris[notsample, :]
X_train = convert(Array, train[:, 1:4]);
y_train = convert(Array, train[:, 5]);
X_test = convert(Array, test[:, 1:4]);
y_test = convert(Array, test[:, 5]);
# Fit the model
using DecisionTree
model = DecisionTreeClassifier(max_depth=5)
fit!(model, X_train, y_train)
# Predict
dectree_pred = DecisionTree.predict(model, X_test)
# Compute accuracy
correct = 0
n=length(y_test)
for i in 1:n
if actual[i] == dectree_pred[i]
correct = correct + 1
end
end
println(correct / n)
随机森林模型的应用方式与决策树相似,乍一看可能会觉得混淆,但随机森林模型是DecisionTree.jl库的一部分。
using DecisionTree
# Fit the model
rf = RandomForestClassifier()
fit!(rf, X_train, y_train)
# Predict on the test set
rf_pred = DecisionTree.predict(rf, X_test)
# Compute the accuracy
correct = 0
n=length(y_test)
for i in 1:n
if actual[i] == rf_pred[i]
correct = correct + 1
end
end
println(correct / n)
在认识了GLM和DecisionTree这两个小型库后,开始介绍主要软件包。如前所述,有两个主要的软件包可以选择:Scikit Learn和MLJ,让我们深入研究。
相信大多数人都是通过Python才了解到Scikit-learn,它是 Python机器学习的“标准”软件包。Julia也拥有这个软件包实在太棒了,如果可以使用与Python相同的语法,则建模的工作量将大大减少。
先看一个使用Julia的Scikit Learn的示例,首先导入Scikit Learn库,然后加载想要的模型(这里使用Logistic回归),并在训练集拟合模型。最后在测试集检验预测精度。
# Import the library
import Pkg; Pkg.add("ScikitLearn")
# Import the model you want to use
using ScikitLearn
@sk_import linear_model: LogisticRegression
# Fit the model
log_reg = fit!(LogisticRegression(), X_train, y_train)
# Predict on the test set
sklearn_pred = log_reg.predict(X_test)
# Compute the accuracy
correct = 0
n=length(y_test)
for i in 1:n
if y_test[i] == sklearn_pred[i]
correct = correct + 1
end
end
println(correct / n)
在Julia中使用Scikit Learn有一些缺点,例如,Julia的Scikit Learn库的很大一部分是Python的包装,Julia模型使用了Pycall来调用Python代码。
如果我们要切换到Julia,必然是为了获得Julia的优势,例如比Python快得多的速度,因此调用Python代码不是我们想要的结果。如果Julia的Scikit Learn仅仅是Python代码的装饰器,还不如直接使用Python的Scikit Learn。
MLJ是Scikit Learn的竞争对手,它有望解决分类变量问题,用纯Julia编写。它还获得了Alan Turing基金会的大力支持,这意味着该软件包有望进一步完善。
让我们看一个用MLJ建模的示例。与上面介绍的几个软件包不同,在MLJ中,机器的创建是一种语法选择,其次要加载模型而不是导入软件包。
# Import the packages that you need (this depends on the model you use)
import Pkg; Pkg.add("MLJ")
import Pkg; Pkg.add("LIBSVM")
import Pkg; Pkg.add("MLJModels")
# load the model
using MLJ
svc_model = @load SVC verbosity=1
# create a so-called machine
svc = machine(svc_model, X_train, categorical(y_train))
# fit the model
MLJ.fit!(svc);
# predict on the test set
yhat = MLJ.predict(svc, X_test);
#compute the accuracy
correct = 0
n=length(y_test)
for i in 1:n
if actual[i] == yhat[i]
correct = correct + 1
end
end
println(correct / n)
排除语法上的差异,MLJ库与其它机器学习库没有根本区别。MLJ不仅易于学习,而且提供了全面和丰富的API文档。
在本文中,我们介绍了Julia机器学习领域的四个常用软件包。
在Julia中调用Scikit Learn的语法与Python非常相似,这是一个巨大优势,但它仅仅是装饰了Python代码令其丧失了Julia真正的优势 – 速度。MLJ具有称霸Julia机器学习领域的巨大潜力,它的语法有点新,但区别不是那么大,目前MLJ的真正挑战是如何获得更多的信任和普及。
来源:Medium
作者:Joos Korstanje
翻译校对:数据黑客
原文标题:Machine Learning in Julia
数据黑客:专注金融大数据,聚合全网最好的资讯和教程,提供开源数据接口。
我们聚合全网最优秀的资讯和教程:
我们提供开源数据接口: