观点
Go或Golang是2007年在Google设计的,语法类似于C语言,但具有内存安全、垃圾回收和结构类型等特点。除了其极快的性能外,Go还可以像C++或Java一样轻松地进行并发,这与Python不同。并发允许多个程序或算法(包括ML的算法)异步执行,而不会影响最终结果。
照片来自Unsplash,作者为Fotis Fotopoulos
有了这个想法,我计划比较使用Golang构建简单ML流水线的优缺点。我将同时使用Python作为参考点。我还将提供关于语言的个人看法,并评估Go在AI/ML社区中是否有未来。那么,让我们开始吧。
注意: 在继续之前,本文将不涉及如何在你的机器上安装和设置Go。如果你尚未这样做,请按照这些详细的说明进行操作。
目录:
- 设置
- DataFrame
- 数据操作
- Go中的机器学习
设置
首先,我们需要在终端中安装以下软件包。
- 安装DataFrame和GoNum软件包及其依赖项。DataFrame和GoNum类似于Python的NumPy,经常用于操作DataFrame对象。
$ go get -u github.com/kniren/gota/dataframe
$ go get -u github.com/gonum/matrix
$ go get -u gonum.org/v1/gonum/...
- 安装GoLearn软件包。GoLearn是一个在GoLang中类似于Python的sklearn的机器学习库。它允许轻松的矩阵操作、ML算法构建、模型拟合,甚至是用于训练/评估过程的数据拆分。
$ g++ --version # make sure you have a G++ compiler$ go get github.com/gonum/blas$ go get -t -u -v github.com/sjwhitworth/golearn
$ cd $GOPATH/src/github.com/sjwhitworth/golearn
$ go get -t -u -v ./...
现在,我们已经完成了艰难的部分,让我们进入更有趣的部分!
DataFrame
我们将使用描述不同类型鸢尾花的IRIS数据集。你可以通过在终端中运行以下命令来获取IRIS数据集:
$ wget https://raw.githubusercontent.com/sjwhitworth/golearn/master/examples/datasets/iris_headers.csv
确保将.CSV文件放在你当前工作的文件夹中,也就是你的_main.go_文件所在的位置。
我们需要将以下软件包导入到_main.go_程序文件中。
现在我们有了所有的导入,让我们编写main()函数来加载CSV数据并将它们漂亮地打印出来。
你将获得以下漂亮的数据摘要,描述了行数(150)、属性数(5)、属性摘要(包括数据类型)以及前几行的摘要视图。
IRIS Dataframe Summary (Image From Author)
非常好!到目前为止,大多数操作与在Python中编码的方式相似。
数据操作
现在让我们探索如何在Go中执行数据操作。
1. 子集
在Python中,最简单的子集操作之一是使用**df.head()**操作。我们可以类似地在Go中执行此函数。
head := df.Subset([]int{0, 3})
fmt.Println(head)
你将看到DataFrame的前两行。
Subsetting a Dataframe in Go (Image From Author)
个人而言,该操作不像在Python中那样冗长。如果没有先前对Go中数据类型的了解,你将很难理解这个函数。
2. 过滤
现在假设你只想探索Iris-versicolor物种的属性。你可以使用Filter()函数过滤行。
versicolorOnly := df.Filter(dataframe.F{
Colname: " Species",
Comparator: "==",
Comparando: "Iris-versicolor"
})
fmt.Println(versicolorOnly)
你将仅检索Iris-versicolor物种的行!
Filtering by Species name (Image From Author)
你还可以将_Comparator_属性与>、≥、<或≤进行交换。
我个人并不介意语法的变化,因为到目前为止,这些操作似乎相当直观。但是,这些程序的单词数量要比Python中的多得多,如下所示。
versicolorOnly = df[df[" Species"] == "Iris-versicolor"]
3. 列选择
除了子集和行过滤之外,你还可以通过执行以下简单操作来子集列。
attrFiltered := df.Select([]string{"Petal length", "Sepal length"}) fmt.Println(attrFiltered)
还有一堆其他数据整理操作,包括连接、聚合、函数应用程序(回忆一下pandas中的.apply()?)等。
总的来说,我仍然更喜欢Python,但可能是因为我没有足够的Go实践。然而,Go的冗长可能会阻止我继续追求前者。
Go中的机器学习
现在,我们已经掌握了如何在Go中操作Dataframe,我们可以开始构建一个简单的机器学习流水线。对于这个例子,让我们构建一个简单的KNN分类器,以确定IRIS的物种类型,给定其属性集合(例如花瓣长度、花瓣宽度等)。
0. 重新加载数据
在main()函数中,让我们重新加载我们的CSV数据集。
fmt.Println("Load our csv data")
rawData, err := base.ParseCSVToInstances("iris_headers.csv", true)if err != nil {
panic(err)
}
1. 初始化KNN分类器
在这里,我们从GoLearn的_knn子包_中初始化了一个新的KnnClassifier。然后,我们将必要的属性传递给新的分类器类:使用_euclidean_作为距离函数,使用_linear_作为其算法核心,以及_2_作为选择的邻居数。
fmt.Println("Initialize our KNN classifier")
cls := knn.NewKnnClassifier("euclidean", "linear", 2)
2. 训练-测试拆分
像往常一样,我们执行训练/测试数据拆分(各50%)。到目前为止,一切都与我们在Python的sklearn库中所做的相同。## 3. 训练分类器
任何机器学习流程的主要部分都是训练分类器。但是,如果你熟悉 Python 的 sklearn 包,那么在 Go 中的流程类似,如果不是完全相同的话。
cls.Fit(trainData)
4. 总结指标
训练步骤完成后,我们可以使用保留的测试数据执行评估并检索性能摘要。
fmt.Println("Print our summary metrics")
confusionMat, err := evaluation.GetConfusionMatrix(testData, predictions)
if err != nil {
panic(fmt.Sprintf("Error: %s",err.Error()))
}
fmt.Println(evaluation.GetSummary(confusionMat))
如果一切顺利,你会在终端中看到以下内容!
我们的 KNN 分类器的评估摘要(作者提供的图片)
不错!我们的新训练的 KNN 分类器达到了 97.73% 的准确率。尝试实现你能在 GoLearn 中找到的其他类型的分类器吧!
最后,你可以在下面的代码片段中找到完整的代码!
结论
总的来说,我发现用 Go 语法构建机器学习流程是相当直观的。然而,我发现 Go 的机器学习社区规模比 Python 的要小。这使得故障排除有时会很繁琐,甚至令人沮丧。此外,这些包中许多缺乏 GPU 支持,这可能会妨碍你的 AI 开发过程。不仅如此,不同的与机器学习相关的包之间似乎很少有互操作性。例如,GoLearn 包实现了它自己的 Dataframe “Instance” 类,这可能无法很好地与本机 GoNum 类或甚至 GoTA 的 DataFrame 对象配合使用。
尽管如此,拥有出色的速度和并发性的 Go,有潜力在机器学习应用中超越 Python;但是它需要足够数量的 AI 开发人员才能做到这一点(即关键质量)。
参考文献
[1] https://en.wikipedia.org/wiki/Go_(programming_language)
[2] GoNum: https://github.com/gonum/gonum
[3] GoLearn: https://pkg.go.dev/github.com/Soypete/golearn
[4] GoTA: https://github.com/go-gota/gota
译自:https://towardsdatascience.com/golang-for-machine-learning-bd4bb84594ee
评论(0)