机器学习使用Julia和它的生态系统
分析玻璃数据集- 1
朱莉娅快速,可以像一种解释语言一样使用,具有高度的可组织性,但不是面向对象的。它具有快速增长的生态系统,有助于典型ML工作流程的所有方面。
教程概述
这是教程的第一部分,该教程将展示如何轻松地组合Julia的特定语言特性和其生态系统中的各种高质量包,以便在典型的ML工作流中使用。
- 第一部分“分析谷歌眼镜数据集"专注于如何使用类似的包对数据进行预处理、分析和可视化
ScientificTypes
,dataframes.
,StatsBase
和attsplots.
. - 第二部分“使用决策树“专注于ML工作流程的核心:如何选择模型以及如何将其用于培训,预测和评估。这部分主要依赖于包装
MLJ
(=米ydF4y2Baachinel收入在Julia.). - 第三部分“如果东西还没有准备好使用,解释了如果可用的包不能提供您需要的所有功能,那么用几行代码创建您自己的解决方案是多么容易。
介绍
每个ML工作流都从分析和预处理用于训练模型的数据开始。这些第一步包括理解应用程序领域中的数据,检查数据质量和识别其统计属性(使用可视化和统计度量)。
在这个tutorial我们将使用“玻璃”数据集。这是一个用于教育目的的数据集。它是Weka,可从不同的网站下载(例如:在这里).该数据集的特征包含关于玻璃不同变体的信息(比如用于其生产和光学特性的材料),目标变量是生成的玻璃变体(见下面的摘录)。
数据以调用的文件格式出现ARFF(属性-关系文件格式);Weka工具包使用的格式。因此,我们需要一个带有函数的Julia包来读取这种格式:ARFFFiles.jl
.因为我们想要将数据转换为DataFrame
这个包DataFrames.jl
也需要。ScientificTypes.jl
增强了标准的朱莉娅类型,使用ML特定的功能和最后但并非最不重要的类型Downloads.jl
用于从网站下载数据的功能包。
所以代码使用这些包,从上面提到的网站下载数据,从磁盘读取它并将它转换成DataFrame
(和使用ScientificTypes
)的格式如下:
数据集的第一个概述
为了获得数据集的第一个概述,我们从中获取一些基本信息:
深圳=大小(玻璃)
给了我们维度:(214年,10)
也就是说,它有214行和10列。- 与
col_names =名字(玻璃)
我们得到了列的列名DataFrame
:
10-element向量{}字符串:
“扶轮”、“Na”、“毫克”,“基地”、“如果”、“K”、“Ca”、“Ba”、“铁”,“类型”
- 和
模式(玻璃)
(从ScientificTypes
)给了我们所有列的数据类型。类型
Julia的数据类型是什么scitypes
抽象层是由ScientificTypes
.这里我们可以看到所有的特征都是连续
目标变量是一个名义值(有7个不同的条目)。
模式(玻璃)——>
┌───────┬───────────────┬──────────────────────────────────┐
│名称│scitypes│类型│
├───────┼───────────────┼──────────────────────────────────┤
│RI│连续│Float64│
│Na│连续│Float64│
│mg│连续│float64│
│al│连续│float64│
│Si│连续│Float64│
│K│连续│Float64│
│Ca│连续│Float64│
│ba│连续│float64│
│fe│连续│float64│
│类型│Multiclass{7}│CategoricalValue{String, UInt32}
└───────┴───────────────┴──────────────────────────────────┘
目标变量
现在让我们仔细看看目标变量的特征。glass_types =独特(glass.Type)
的惟一值的列表类型
专栏:
6-element向量{}字符串:
“构建风浮动”
“车辆风浮动”
“餐具”
“建造风非浮动”
“车头灯”
“容器”
我们假设,数据集中有6种不同类型的玻璃。但这只是事实的一部分。使用水平(glass.type)
从ScientificTypes
揭示了实际上有7种不同的玻璃类型:
7元素矢量{string}:
“构建风浮动”
“建造风非浮动”
“车辆风浮动”
“车辆风非浮动”
“容器”
“餐具”
“车头灯”
其中只有6个出现在玻璃数据集中(计数为> 0)'车辆风非浮动'不发生。关于其存在的知识存储在ARFF-File中,并由所建立的类型系统保留ScientificTypes
.在这个例子中,我们可以看到使用这种类型系统而不是仅仅依赖于语言的本地类型系统的附加价值(在这个例子中,本地类型系统会欺骗我们)。
在下一步中,呼叫countmap
(从StatsBase
)告诉我们,每种类型在目标变量中会发生频率。因此,我们了解他们的分销:建筑物中使用的窗户的玻璃变体是最常见的类型,然后用于前照灯的玻璃型:
type = countmap(glass.Type)——>dict {categoricalArrays.categoricalValue {String,UInt32},Int64}具有6个条目:
“车辆风浮子”=> 17
“餐具”=> 9
" build wind non-float " => 76
" build wind float " => 70
“前照灯”= > 29
“容器”= > 13
当然,图表比一列数字更能提供信息。我们用条形图来形象化一下情节
包:
Bar (type_count, group = glass_types, legend = false,
Xlabel =“玻璃类型”,xrotation = 20,
ylabel =“计数”)
这里我们也注意到,来自ScientifcTypes
已使用,因而显示“风vehic non-float”零计数。
详细的特性
现在来看特征变量:第一个特征ri.是所谓的折射率,一种光学特性,它告诉我们光线如何穿过材料。其他特征给出不同元素的百分比,如钠(=拉丁纳trium),镁(米) 或者艾尔Uminium (Uminium),用于生产玻璃。
这些价值合理吗?
让我们首先检查这些特性的值从技术角度来看是否合理。调用描述
从dataframes.
在其他信息中,给我们一个关于数据集中值范围的印象:
- ri.在1.5左右略有变化。从上面提到的维基百科页面,我们了解到这种典型ri.不同种类的玻璃的值在1.49…1.69之间。因此,ri.“玻璃”数据集中的值似乎是相当合理的。
- 其他功能是百分比。例如,它们必须在0…100的范围内,这适用于我们的数据。
- 硅是玻璃中最重要的成分(这里是> 70%),其次是钠和钙。
我们可以对百分比进行另一种质量检查。每个玻璃组合物应加入高达100%。我们使用转变
函数dataframes.
并在每一行中添加特性的所有值纳...菲.结果存储在一个名为sumpct
:
glass_wsum =变换(玻璃,
(:NA,:FE)=> BYRow(+)=>:Sumpct)
看看这个新列并使用最大
和最低
函数从StatsBase
显示大多数行的和不是完全100%,但它们在该值附近有少量变化。这可以通过测量和舍入误差来解释。所以这对我们来说是可以的。
最大(glass_wsum.sumpct),最小(glass_wsum.sumpct)——>(100.09999999999998,99.02)
统计数据和可视化
因为所有的特性属性都是类型的连续
,可以计算一些统计数据,并且可以绘制其分发的图以获得更多的洞察力。
峰度和偏态
- 偏态是对分布对称性(或者说不对称性)的一种度量。负值表示它的左尾巴更长(而且相当平坦),质量集中在右边。我们说到左偏斜或left-tailed分布。另一方面,正值表示A右偏态分配。
- 峰度是测量分布的“尾部”。它表示尾巴向左或向右伸出的距离。正态分布的峰度为3。所以其他分布的峰度通常与这个值和所谓的过度峰度计算。它表示考虑分布的峰度超过正态分布的峰度。这也是我们从
峰度
函数的StatsBase
包中。
下面的表达式为' glass '数据集的所有特性创建了这些度量的列表:
[(atr,偏态(玻璃(:,atr)),峰度(玻璃(:,atr)))
对于col_names[1:end-1]中的atr
这样的表达在茱莉亚身上被称为“理解”。它是一个数组,其初始值是通过迭代计算的。对于col_names[1:end-1]中的atr
的列名(从第一个到第二个,但最后一个)遍历玻璃
.对于每个列名(atr
),它会创建一个包含三个元素的元组:列名atr
本身以及偏斜度(偏态(玻璃(:,atr))
)及峰度(Kurtosis(玻璃[:,ATR])
),从而产生下列输出:
9-element Vector{Tuple{String, Float64, Float64}}:
(“RI”,1.6140150456617635,4.7893542254570605)
(“Na”,0.4509917200116131,2.953476583500219)
(毫克,-1.1444648495986702,-0.42870155798810883)
(“基地”,0.9009178781425262,1.9848317746238253)
(“SI”,-0.7253172664513224,2.8711045971453464)
(“K”,6.505635834012889,53.392326556204665)
(“Ca”,2.0326773755262484,6.498967959876067)
(“Ba”,3.392430889440864,12.222071204852575)
(“铁”,1.7420067617989456,2.5723175586721645)
从这些数字中,我们已经看到了例如。分布K和英航它们很不对称,尾巴很长。但在大多数情况下,如果我们把分布形象化,我们会得到更多的信息。
特征ri.
让我们从特性开始ri..小提琴图,可以使用小提琴
函数的attsplots.
包裹,显示它的分布方式看起来像。小提琴(玻璃。ri.,legend = false)
产生以下情节:
一个直方图,其条形图根据目标值着色,此外还显示了特征值与生成的玻璃类型之间的关系。为此,我们可以使用柱状图
函数(也来自attsplots.
;请参阅图表下方的Julia代码):
特性纳...菲
我们可以为剩下的功能做同样的事情纳...菲.一个很好的替代小提琴图来描述分布的方法是箱形图.有时小提琴情节给出了更多的洞察力,有时是一个盒子。所以我们最好创造两者。如果我们并排每个特征绘制所有三种图表,我们可以轻松比较它们,从而导致以下网格网格:
茱莉亚代码用于生成这个地块网格如下:
前三条线具有类似的结构:每条线创建一个图表数组(首先是小提琴图,然后是箱线图,最后是直方图)。同样,我们使用一个“理解”来达到这个目的:我们从2迭代到9,因为我们想要一个2到9列的图表玻璃
数据帧。对于每一列,我们都创建了各自的图表(与上面描述feature的方法相同)ri.)和适当的参数(每个图都得到例如特征名称作为它的包含
).
的情节
函数(绘制整个网格;第7行)将一个子图数组作为它的参数,并根据布局
参数(这里是8 x 3网格)。因此,我们必须创建一个适当的数组,其中包含正确顺序的子图(即,对于每种材料,是小提琴绘图的小提琴绘图),应用以下步骤(第5行的代码):
hcat
连接三个数组小提琴
,盒子
和组织
这样就创建了一个8 x 3矩阵的图表(每种图表都有一列)- 因为Julia矩阵是按列优先顺序处理的,所以我们用
超薄的im
创建3 x 8矩阵(所以三个图表纳第一列是什么米在第二列,以此类推) - 最后,我们必须将矩阵“压平”到数组(根据需要
情节
)使用vec
.
相关性
当处理数值属性时,如果和他们相关的强烈,他们始终非常重要,因为某些模型不适用于强烈相关的属性。
除此之外,两个属性之间的强相关性表明其中一个属性可能是多余的,因为它没有携带太多的额外信息。这些知识可以用来减少特征的数量,从而使训练和评估模型的计算更加可行。
相关矩阵
功能cor
(从statsplots)
以矩阵的形式给出我们想要的信息,其中包含每对特征(所谓的相关矩阵):
一如既往,可视化使数字更加可理解。在这种情况下,热图是适当的图表(我们创建使用热线图
从attsplots.
).由于相关矩阵是对称的,因此可视化它的下半部分(可以使用LowerTriangular
从LinearAlgebra
包;参见图表下面的Julia代码)。颜色的比例: tol_sunset
热图用的是什么colorschemes.
包中。
heatmap(lowertriangle (cor_mat), yflip = true,
seriescolor =: tol_sunset,
Xticks = (1:9, col_names[1:9]),
yticks =(1:9,col_names [1:9]))
从heatmap(和相关矩阵)可以看出,不同玻璃属性之间最强的正相关为:
- Ca / RI→0.810403
- Ba / Al→0.479404
- Ba / Na→0.326603
- 0.325958 K / Al→
因此,当我们看到数字时,只有前两个才是真正的“强势”。
可以观察到明显的负相关:
- SI / RI = -0.542052
- Ba / Mg = -0.492262
- 铝/毫克= -0.481798
- 钙/镁= -0.443750
相关图和角线图
下面的图表更详细地揭示了不同属性配对之间的相关性:
- 的相关图图的下半部分显示散点图(每个散点图都有相应的SD线),上半部分显示热图。散点图中蓝色为正相关,红色为负相关,黄色为中性相关。
- 的cornerplot(这里是它的紧凑形式)显示了与相关图在图的下半部分。此外,它在顶部和右边缘上显示每个属性的直方图。
每个图都是用一行Julia代码创建的,使用了from的函数attsplots.
如下:
@df玻璃corrplot(关口(1:9)
@df玻璃角线图(cols(1:9), compact = true)
结论
上面的示例显示了如何使用几行代码来执行典型ML工作流程的重要步骤。本教程的第II部分继续进行这段旅程,重点关注培训,预测和评估等步骤。
它也明确了不同Julia包的功能如何很容易结合起来,以及它们在一起的工作程度如何,即使它们已经独立开发。本教程的第三部分将解释这种可塑性的内在工作。所以保持调整!
当然,这些例子只能触及表面。有关更多信息,请参见下面给出的参考资料。
进一步的信息
- 在朱莉娅进行数据分析及以后, Stefan Karpinski (Julia的创造者之一)解释了Julia的主要优势和设计背后的理由。在为什么朱莉娅?-对Julia编程的特性和好处的高级描述通过蒂姆圣洁,您可以获得更深入的处理同一主题。
- Bogumil Kaminski教授给出了一个全面的教程DataFrames在Juliaccon 2021.他是包裹的主要作者。
- plot的文档和教程。可以找到Jl包在这里.有几个像statsplots.jl等附加包.