《 Julia 数据科学应用》各章思考题答案

第2章

1.如果你以前没有用过 Julia,那么 Juno 是最安全的选择。如果不使用 Juno,那么带有最新 Julia 内核(在 IJulia 界面右上方)的 IJulia 也可以达到同样的效果。

2.最常用的选择是使用 JuliaBox。如果你没有 Google 账户,或者你不想让 Google 访问你的代码,那么可以使用 tutorialspoint.com 上的 Julia IDE。

3.IDE 相对于 REPL 的优点在于:加载/保存脚本文件(.jl 文件)的能力,更加用户友好的界面,更容易组织代码,更容易清理代码,如果 Julia 崩溃可以保留代码,具有像文件管理器之类的内置功能,颜色代码使得代码更加易读。

IJulia 相对于 IDE 的优点在于:更容易与非程序员的普通用户共享脚本,绘图通常与代码位于同一区域,可以采用多种方式输出代码(如 .jl 脚本文件、.ipynb 笔记本文件、.html 网页文件、.pdf 文件)。如果你有 Python 或 Graphlab 背景,则更容易使用,可以对相关文本进行格式化。

4.内部原因:辅助函数可以让你在更高的高度上以功能划分的方式来组织思维。它们可以使建立解决方案的过程更加有效,并使调试过程更加快速直接。

外部原因:辅助函数可以使其他代码用户更快地理解代码功能,从而提高代码的可用性(辅助函数在其他应用中也可以独立使用)。它们还可以使主程序更简单(使用户在更高的层次上理解程序功能)。

5.包装器函数是一个将多个辅助函数组合(包装)在一起来完成较大目标的函数。如果只有一个包装器函数,那么它通常称为主函数。很多复杂的程序和扩展包中经常使用包装器函数。

6.sqrt():返回一个数值的平方根。它使用非负数值型变量作为输入,可以应用在由非负数值型变量组成的数组上,也可以应用在复数上(非实数型数值变量)。

indmin():返回一个数值型数组的最小索引值,使用数组作为参数,维度不限,也可用于其他集合类型。

length():返回集合类型中的元素数量,或者字符串中字符的数量。它使用数组、字典、范围或抽象字符串作为参数,总是返回一个整数。

7.假设 y 和 z 具有同样的大小,那么表达式总是会返回一个0和1之间(包括0和1)的浮点数。表达式的第一部分(sum(y==z))返回一个0和 n 之间的数,这里的 n 是 y 中元素的数量,n 也是表达式后一部分(length(y))的值。表达式的值是这两部分的值的比值,所以它一定在0和1之间。

8.可以保存在路径 d:\data\中的 Array A.csv 文件中,使用命令 writecsv("d:\data\Array A.csv",A)。

9.先找出最重要的变量,假设为 A、B 和 C,并确定数据文件名称,比如是“workspace-Friday afternoon.”然后加载 JLD 扩展包:

using JLD

然后,运行以下命令:

f = open("workspace - Friday afternoon.jld", "w")
@write f A
@write f B
@write f C
close(f)

如果你想加入路径,就可以对第一个命令做下修改,像前一个问题一样。

10.Max()用于比较一对数值,使用两个数值类型作为输入。Maximum()是 max()的扩展,用于一系列数值,它只有一个输入:由这些数值组成的数组。如果想看看 a 和 b 中哪个最大(这里 a,b<:Number),就应该使用前者:max(a,b)。

11.以如下的方式使用 Pkg.add("NMF"):

Pkg.update()
using NMF

12.不能。kNN 和其他所有分类器一样,不能处理文本数据。分类器的核心功能是距离计算,只能使用数值型数据。不过,kNN 通过恰当的特征工程还是可以用来进行文本分析的,参见第6章。

13.完成这个任务最快的方法是将 kNN()函数中引用的 distance()函数修改为曼哈顿距离。如果你不知道什么是曼哈顿距离,你可以修改一下 distance()函数,将这行代码:

dist += (x[i] - y[i])^2 

替换为:

dist += abs(x[i] - y[I])

因为在处理其他数据集的时候你还可能再次使用欧氏距离,所以你可以将原来的代码保留为注释(即在前面加一个“#”)。

第3章

1.是的,我看了。

2.多数情况下 Julia 函数是你的最佳选择。然而,如果你有一个用 C 语言实现的函数,那么就应该用这个函数,因为在很多情况下它能提高一点性能。

3.最合适的数据结构是字典(dict)。

4.如果你知道要做什么,并且不想和其他用户分析这个函数的话,这样做是有意义的。但是,如果你偶然使用其他类型来调用这个函数的话,Julia 会抛出异常或错误。此外,函数性能肯定会受到一点影响。

第4章

1.可以,使用 Julia 语言的多分派特性就可以。如果函数 awesome_fun(A::Array)用来计算数组 A 中的熵,那么你可以通过再写一个函数 awesome_fun(f::ASCIIString)来扩展它的功能,计算一个文件 f 中内容的熵。这样,在两种情况下,你都可以无缝运行 awesome_fun()函数。

2.hdist()函数使用抽象字符串作为输入参数,‘a’和‘b’都是字符变量。

3.可以。利用多分派特性。

4.答案为:

function word_counter(text::AbstractString)
   words = split(text, " ")
   word_count = length(words)
   return word_count
end
text = "Data science is the coolest field today."
println(word_counter(text)) # yields the number 7

5.答案为:

function non_space_characters_prop(text::AbstractString)
   chars = split(text, "")
   N = length(chars)
   n = sum(chars .!= " ")
   return n / N
end
text = "Data science is the coolest field today."
non_space_characters_prop(text) # yields the number 0.85

6.主函数为 digit_freg()。函数 convert_to_string()和 find_ most_popular_item()为辅助函数。

  function convert_to_string(A::Array{Float64, 1})
     temp = string(A)
     return temp[2:(end-1)]
  end
  function find_most_popular_item(D::Dict)
     ind = indmax(values(D))
     temp = collect(keys(D))
     return temp[ind]    
  end
  function digit_freq(A::Array{Float64, 1})
     temp = convert_to_string(A)
     freqs = Dict{Char,Int64}()

     for character in temp
      if character in "1234567890"
      if haskey(freqs, character)
        freqs[character] += 1
      else
        freqs[character] = 1
      end
     end
    end
    digit = find_most_popular_item(freqs)
    return digit
  end

对于大的数值型样本,‘1’应该是出现次数最多的数字(本福德定律)。

第5章

1.数据工程是数据科学流程中的一个阶段,它为数据分析准备好数据。数据工程包括数据准备、数据探索和数据表示。数据工程通常称为“数据整理”,它是数据科学中最基本的环节之一。

2.数据准备非常重要,因为它要为数据探索准备好数据、处理缺失值、找出潜在问题、清理数据、对数据进行标准化,多数情况下还要去除一些异常值。

3.数据科学流程面向的是复杂的甚至是混乱的数据,它的目的是创建一种对未来具有实际意义的数据产品。其他数据分析过程更注重得到一些过去或现在的摘要信息或有趣的结论。此外,其他数据分析过程中的数据一般更简单,也更整洁标准。

4.我们可以按照如下方式进行清理和转换:

变量 Text:"The customer appeared to be dissatisfied with product 1A2345 released last May"

变量 RelatedProduct:1A2345

5.数据探索通过检查变量的分布、变量之间的联系以及它们与目标变量之间的联系来理解数据集。所有这些工作都通过研究特征空间的结构以及各种数据可视化手段来实现。

6.数据表示需要使用最合适的数据类型对数据进行编码。在多数情况下,还包括从数据中提取特征(特别是对于文本数据)。

7.数据发现是与在数据中发现模式和联系相关的所有工作,这些发现通常可以直接用于随后的数据学习阶段。

8.数据学习的任务是使计算机从我们在前几个阶段中准备好的数据集中进行学习。包括对数据进行智能化的分析,以及使用回归、分类、聚类和其他技术来进行某种类型的泛化或得到一些实用的知识。

9.数据产品创建是将前阶段创建的模型部署到生产环境中的过程。这个过程通常需要开发一些 API、一个应用程序或一个仪表盘系统。它的目标是使数据科学与工程团队之外的那些用户(通常是产品所属公司的客户)也可以使用模型。

10.在这个阶段,会创建一些可视化产品和报告。这些产品和报告是给管理层看的,有时是给流程所属企业的其他部门看的,它们不同于数据产品,数据产品的受众更广,价格比较高,或者有促销目的。知识、交付物和可视化产品阶段也会包括从数据产品阶段产生的结果和洞见(如这个数据产品有多么成功,从用户那里得到了什么反馈),它是评价整个数据科学项目的必备条件。从某种意义上说,它是重新回到了起点,经常会引起新的一轮项目循环。

11.它是高度非线性的,因为经常会有新的任务,或者意料之外的事情,使得流程不能按照“正常”的顺序来进行。

12.比如一个根据日常活动计算出你的平均卡路里消耗的 APP,或者一个社交媒体推荐系统,或者一个潜在客户风险评估系统。[1]

13.最后阶段中的可视化产品更成熟,可以表示出更高级的信息。

14.是的,因为每个流程阶段或者对数据进行转换,或者进行分析,或者进行提炼,在数据逐渐转换为信息的过程中都有贡献。在某种情况下,可以省略某个阶段(例如,在数据非常标准,完全满足分析需要的情况下),但很少有这种情况。

第6章

1.数据工程是非常重要的,因为它可以使你识别出数据中信息最丰富的部分,并将数据准备好以进行更深层次的分析。

2.数据框可以处理缺失值(编码为 NA)。此外,还可以在同一个数据框中保存各种类型的数据。

3.可以打开这个文件,然后使用 JSON 扩展包来进行解析:

f = open("file.json")
X = JSON.parse(f)
close(f)

4.有3种主要的策略:

a)在集群或云环境中处理数据。

b)可以将数据分解成可以处理的几个部分,然后在本地处理。

c)可以安装相应的扩展包,然后将数据加载到 SFrame 中。

5.根据数据类型的不同,主要包括以下工作:

a)对于数值型数据:消除缺失值,处理异常值。

b)对于文本数据:除去不必要的字符,除去停用词(进行文本分析时)。

6.因为数据类型可以使你更有效地进行资源管理,还可以更有效地表示数据,使得用户和以后阶段中的 Julia 函数更好地利用数据。

7.要对它们进行标准化,最好是让它们的值位于(0,1)之间。位于[0,1]之间的标准化也很好,如果数据集中没有异常值的话。或者,也可以使用均值和标准差来进行标准化。

8.很明显,应该选择抽象字符串类型。但是,一些整数的子类型也是可以的,特别是当你想做频度分析的时候。如果你想做词汇分析或是类似的工作,那么布尔型数据也是非常有用的。在所有情况下,sparsematrixCSC 数据类型都很实用,特别是在处理有大量词汇的数据集时。

9.可以使用 bitarray、布尔数组或 Int8 类型的数组来保存文件。

10.OnlineNewsPopularity:使用相关性来评价。

Spam:可以使用杰卡德相似度、互信息或相似度指数来评价。

第7章

1.考虑一下两个变量与其他变量的相关性以及与目标变量的相似度,从二者中除去一个。

2.永远不能接受原假设。只能在一定的置信度下拒绝原假设。

3.如果目标变量是定序变量,而且各个类别分布得比较均匀的话是可以的。但很少有这种情况,所以最好不要在分类问题中使用相关性。

4.请一定先进行数据准备,尽可能多地使用统计图。有价值的发现包括“变量 A 与变量 B 紧密相关”、“变量 C 应该是目标变量的一个非常好的预测变量”、“变量 D 中有几个异常值”、“变量需要标准化”,等等。

5.可以,尽管 t-检验在服从正态分布的变量上效果最好,但因为很少会有标准的正态分布,所以经常不考虑这一点。

6.不能。为了得出统计上显著的结论,你需要更大的样本。

7.散点图。

8.对整个数据集进行可视化,在不损失大量信息的情况下,将数据集转换成更低的维度。所以,你可以推测出这种方法可以进行更好地描绘出有意义的模式,比如簇,还可以评估分类的难度。

第8章

1.应该降维,因为对于多数数据分析方法来说,特征数量太多了。任何一种降维方法都可以。如果数据集中有标签,可以使用基于特征评价的方法,因为这种方法非常快速,而且对于这个巨大的数据集来说,不容易引起内存溢出等问题。

2.应该降维,因为这种数量的特征对于很多数据分析方法来说,还是有点多。任何一种降维方法都可以,因为性能的原因,PCA 会更好一些。

3.应该使用基于特征评价的方法,因为这个数据集太小了,PCA 不适合。

4.可能会进行降维,但这不是第一选择。如果使用的数据分析方法效果不好,或者有些特征在数据探索阶段表现为冗余特征的话,可能会使用某种方法进行降维。

5.不会。数据科学项目通常包含大量的特征,这使得全部特征组合的数量极其巨大。应用这种方法会浪费大量资源,而且通过这种方法找出的最优特征集合对性能的提高不见得会比用其他方法得出的次优特征集合好多少。

6.优点是可以使用目标向量(即我们要预测的目标)中包含的额外信息。

7.在这种情况下,ICA 方法是最好的,因为它可以得出统计上独立的元特征。

8.任何一种高级方法都可以。如果你不介意调整参数,那么基于 GA 的方法是最好的。

第9章

1.可以,但只有当数据集中有一个离散型变量而且被用作目标变量时才可以。分层抽样后,你可以将两个输出结合在一起,使用新的矩阵作为样本数据集。

2.分层抽样可以在某种程度上保留少数类别的信息。使用基本抽样方法会导致抽样中少数类别的信息削弱甚至消失。

3.随机抽样。正如多数统计书籍中强调的,这是正确抽样的关键,也是处理样本中潜在偏离的最好方法。

4.可以,尽管你在任何一本数据科学书籍中都不会看到这个定义。要想把总成本标准化到0和1之间,首先要找出最大的可能成本(假设一种最坏的情况,即每种类别中的元素都被误判,这样就可以得到最高的误判成本)。然后使用给定分类总成本与最大成本的比值即可。

5.不能,除非你将问题分解成三个子问题,每个子问题都是二分类问题(例如,“类别1”和“其他类别”)。然后,你可以对每个子问题应用 ROC 曲线。

6.对于任何目标变量没有多个不同值的问题,都可以使用 KFCV。所以,尽管这种方法是为分类问题设计的,但如果目标变量中不同值的数目不多,在理论上也可以用于回归问题。

第10章

1.在聚类和其他基于距离的算法中,距离都是非常重要的。这是因为距离会直接影响这些算法的功能和结果。是否选择了正确的距离度量方式可以影响聚类系统的成败,决定它的结果是否有意义。

2.使用 DBSCAN 方法或者它的变种。

3.因为那些度量方式依赖于目标变量,包含与特征集中数据点无关的信息。在聚类中使用那些度量方式即使不是完全不合适,也会导致混淆。

4.只有数值型数据才可以聚类,非数值型数据需要转换成二值特征后才能聚类。为了获得无偏的结果,所有数据在聚类之前都应该进行标准化。

5.分割聚类并不局限于二维或三维,它的目标是对现有数据进行有意义地分组。t-SNE 的目标是在不显著扭曲数据集结构的前提下,将数据维度限制在可控范围内,使得可以对数据集进行可视化表示。理论上,t-SNE 的输出结果可以用来聚类,但实际上很少这样做。

6.从技术角度来说,不是必须的,因为聚类结果不能直接应用于数据科学流程的其他阶段。但是,对于有一定复杂度的数据集,聚类是非常有用的,因为它可以让我们更好地理解数据集,并做出更有意义的假设。

7.在聚类时,高维度确实是个问题,因为这时数据点之间的距离很难表示出它们之间的相异度(特别是很难表示出相异度的分散程度)。不过,这个问题可以通过降维方法来有效地解决,比如 PCA。

8.你可以将这个特征乘以一个大于1的系数。这个系数越大,在聚类算法中这个特征起的作用就越大。

第11章

1.试一下随机森林、贝叶斯网络或者 SVM。如果是个回归问题,也可以选择统计回归。如果维度降低到可控的特征数量,那么也可以使用直推式系统。初始特征彼此独立这个特点很适合使用基于树的方法,贝叶斯网络也会因此受益。

2.任何一种基于树的方法都可以。贝叶斯网络在这种情况下效果也很好。根据数据量和维度的不同,ANN 或直推式系统也是很好的选择。

3.神经网络,因为它可以很好地处理带噪声的数据,适合大数据集,并擅长分类问题。

4.错。即使是一个鲁棒性非常好的监督式学习系统,也会从优秀的特征工程中受益匪浅。

5.基于树的系统,如果是回归问题,广义统计回归模型也可以。

6.神经网络是统计回归的扩展,其中所有工作都是自动进行的。第二层中的所有结点都可以看成是一个统计回归模型的输出,这使得3层 ANN 是某种形式的组合体,其中就包括统计回归系统。

7.维度。使用特征选择技术或者用元特征替代初始特征可以有效地解决这个问题。

8.深度学习系统不是万能灵药。它只在某些特定类型的问题上表现很好,它要求丰富的数据,并需要大量计算资源。对于所有问题都使用深度学习是不合适的,特别是要求解释性的问题。

第12章

1.图可以帮助我们对复杂数据集简单直接地进行建模和可视化,还可以对某些不能用传统数据科学技术建模的数据集(比如社交网络数据)进行建模。

2.如果我们用结点表示特征,用边表示特征之间的相似度(或距离),就可以将特征集合表示成一张图。然后就可以使用基本的图分析技术来检查每个特征的独立程度。此外,如果我们将特征与目标变量关联起来(通过一种合适的度量方式),就可以对各种特征进行评价。所有这些工作都可以帮助我们对数据集的可靠性有个明确的概念。

3.对于某些数据集是可以的。有些数据集可以用图来建模,但使用传统的技术也可以,有时效果会更好。当数据点、特征或类别之间的联系非常重要时,使用图分析通常效果更好。

4.完全没有问题。实际上,几年前 MATLAB 中就实现了这样的系统。但是,这个系统没有进入公众视野,因为还有更加引人注目的新功能。基于 MST 的分类系统可以按以下步骤实现:

a)输入:用于训练的特征集合、用于训练的标签、用于测试的特征集合、距离度量方式。

b)训练:基于训练集中的数据点和距离(使用给定的距离度量方式来计算)为每个类别创建一个 MST,并计算出边上的平均权重。

c)再创建一个 MST,计算出新 MST 边上的平均权重,并与这个类别的初始 MST 进行比较,根据最优改善情况(边上平均权重更小)来分配类别标签。对于测试集中的每一个点和每个类别,都重复这个过程。

你最好自己先尽量实现这个系统,然后再看一下我们提供的代码(MSTC.jl)。当然,我们欢迎你使用我们的代码,只要你正确地引用。

除了简单易行,基于 MST 的分类器功能也很强大,因为它的整体特性(尽管开始时很不明显)。不过,它也继承了基于距离的分类器的弱点,扩展性不好。

5.不能。你必须进行大量预处理工作才能对数据进行建模,这样图分析才有意义。

6.答案是:

function MST2(g, w) # MAXimum Spanning Tree
   E, W = kruskal_minimum_spantree(g, -w)  
   return E, -W
end

7.没有,因为有些与图相关的额外信息没有包含在图对象中,两种扩展包中的图对象都是这样。最重要的是,权重信息没有保存在图数据文件中。

第13章

参见相应的 IJulia 笔记本。


[1] 这应该是第5章思考题中第13题的答案,第12题的答案作者没有给出。以下答案顺延。——译者注

你可能感兴趣的:(《 Julia 数据科学应用》各章思考题答案)