基尼指数与信息熵
关于杂质测量和信息增益,您需要了解的一切
简介:
对数据科学家来说,杂质/信息增益的度量,尤其是基尼指数和熵,是有趣且实用的概念。下面我们将通过简单易懂的例子来深入探讨这些概念。
目录
- 背景
- 基尼直觉
- 熵直觉
- 使用 python 进行可视化
- 信息增益比较
- 实用的外卖
背景:
决策树根据目标变量的纯度递归分割特征。该算法旨在找到最具预测性特征的最佳点,以便将 1 个数据集分成 2 个数据集。这两个新数据集的目标变量将比原始数据集的更纯。
然而,“纯粹”是这里的关键词。这个词到底是什么意思?在一般意义上,“纯洁”可以被认为是一个群体的同质化程度。但是同质性可能意味着不同的东西,这取决于你的决策树运行在哪个数学主干上。决策树的决策的两个最受欢迎的支柱是基尼指数和信息熵。
下面这三个例子应该能让大家明白这一点:
如果我们有 4 个红色口香糖球和 0 个蓝色口香糖球,那么这 4 个口香糖球就是 100%纯的。
如果我们有 2 个红色和 2 个蓝色,那么这个组是 100%不纯的。
如果我们有 3 个红色和 1 个蓝色,如果我们分别使用基尼系数或熵,则该组的纯度为 75%或 81%。
为什么这很重要?根据使用的杂质测量,树分类结果可能会有所不同。这可能对您的模型产生很小(有时很大)的影响。
基尼指数直觉:
让我们从基尼指数开始,因为它更容易理解。根据维基百科,目标是*“测量从集合中随机选择的元素被错误标记的频率”[1]。*
为了形象化,让我们回到口香糖的例子。如果我们决定任意将 4 个口香糖球都标记为红色,其中一个口香糖球被错误标记的频率是多少?
4 红色和 0 蓝色:
杂质测量值为 0,因为我们永远不会错误地标记这里的 4 个红色口香糖球中的任何一个。如果我们任意选择将所有的球标为“蓝色”,那么我们的指数仍然是 0,因为我们总是错误地给口香糖球标上标签。
无论你选择哪个阶层的概率,基尼系数总是一样的,因为在上面的公式中,基尼系数总是等于 0。
基尼系数为 0 是最纯粹的分数。
2 红 2 蓝:
杂质测量值为 0.5,因为我们有一半时间会错误地给口香糖球贴上错误的标签。因为该指数用于二元目标变量(0,1),0.5 的基尼指数是最不纯粹的分数。一半是一种类型,一半是另一种类型。将基尼系数除以 0.5,有助于直观理解该系数代表什么。0.5/0.5 = 1,意味着分组尽可能不纯(在只有 2 个结果的组中)。
3 红色和 1 蓝色:
这里的杂质测量值是 0.375。为了更直观的理解,如果我们将此除以 0.5,我们将得到 0.75,这是错误/正确标记的概率。
熵直觉:
由于等式中的对数,熵的计算量更大。像基尼一样,基本思想是通过目标变量来衡量一个群体的无序程度。这种方法不是利用简单的概率,而是采用概率的对数基数 2(然而,只要你是一致的,你可以使用任何对数基数)。熵方程使用对数,因为它有许多有利的性质。主要优点是它提供的附加性能。这些麻省理工学院的讲座笔记将有助于更清楚地掌握这个概念(pg8) [2]。
让我们用同样的口香糖场景来想象熵是如何工作的:
4 红色和 0 蓝色:
不出所料,熵的杂质测量值也是 0。这是使用信息熵的最大纯度分数。
2 个红色和 2 个蓝色:
此处的杂质测量值为 1,因为这是可获得的最大杂质。
3 红色和 1 蓝色:
这里的纯度/杂质测量值是 0.811,比基尼系数差一点。
形象化
让我们用 python 中的一些代码来可视化基尼和熵曲线:
基尼系数:
下面我们制作一个函数来自动计算基尼系数。
#Gini Function
#a and b are the quantities of each class
def gini(a,b):
a1 = (a/(a+b))**2
b1 = (b/(a+b))**2
return 1 - (a1 + b1)
与我们的口香糖主题保持一致,让我们做一个循环,计算任何可以想象的红色和蓝色口香糖彩车组合的基尼系数,加到 4。我们将对上述基尼函数进行 10,000 次迭代,以便稍后绘制基尼曲线。
#Blank lists
gini_list = []
blue_list = []
red_list = []
blue_prob_list = []#Looping Gini function on random blue and red float amounts
for x in range (10000):
blue = random.uniform(0, 4)
red = abs(4-blue)
a = gini(red,blue)
b = blue/(blue+red)
gini_list.append(a)
blue_list.append(blue)
red_list.append(red)
blue_prob_list.append(b)#Dataframe of amount of blue, red, Probability of blue, and gini score
df = pd.DataFrame({“Blue”: blue_list, “Red”: red_list,”Gini Score”: gini_list, “Probability of Blue”: blue_prob_list})
df = df[[‘Red’, ‘Blue’, ‘Probability of Blue’, ‘Gini Score’]]
df
数据帧的开头在下面。其他 9994 行装不下。
现在我们将绘制我们的曲线:
plt.scatter(blue_prob_list,gini_list)
plt.xlabel(‘Probability of Blue Gumball %’)
plt.ylabel(‘Gini’)
plt.title(‘Gini Curve’)
熵:
#Gini Function
#a and b are the quantities of each class. Base is the log base input.
def entropy(base,a,b):
try:
var = abs(((a)/(a+b)) * log(((a)/(a+b)),base)) - (((b)/(a+b)) * log(((b)/(a+b)),base))
return var
except (ValueError):
return 0#Blank lists
ent_list = []
blue_list = []
red_list = []
blue_prob_list = []#Loop with log base 2
for x in range (10000):
blue = random.uniform(0, 4)
red = abs(4-blue)
a = entropy(2,red,blue)
b = blue/(blue+red)
ent_list.append(a)
blue_list.append(blue)
red_list.append(red)
blue_prob_list.append(b)df = pd.DataFrame({"Blue": blue_list, "Red": red_list,"Entropy": ent_list, "Probability of Blue": blue_prob_list})
df = df[['Red', 'Blue', 'Probability of Blue', 'Entropy']]
df
对比:
基尼是蓝色的,熵是橙色的。在下一节中,您将看到这些差异是如何在信息增益中体现出来的!
信息增益
信息增益是杂质如此重要的原因。一旦我们获得了数据集的杂质,我们就可以看到当我们沿着树向下并测量节点的杂质时获得了多少信息。
Source [3]
在下面的例子中,我们通过一个特定的属性(比如口香糖的大小)来分割口香糖偏好。它给出了父/子节点关系:
基尼系数信息增益(根据上面的等式)
#Defining Gini info gain function:def gini_info_gain(pa,pb,c1a,c1b,c2a,c2b):
return (gini(pa,pb))-((((c1a+c1b)/(pa+pb))*gini(c1a,c1b)) + (((c2a+c2b)/(pa+pb))*gini(c2a,c2b)))#Running Functiongini_info_gain(22,13,18,2,4,11)
= 0.196 基尼信息增益
0.196/0.467 = 41.97%的增益
熵信息增益(来自上面的等式)
#Defining Entropy info gain function:def entropy_info_gain(base,pa,pb,c1a,c1b,c2a,c2b):
return (entropy(base,pa,pb))-((((c1a+c1b)/(pa+pb))*entropy(base,c1a,c1b)) + (((c2a+c2b)/(pa+pb))*entropy(base,c2a,c2b)))#Running Functionentropy_info_gain(2,22,13,18,2,4,11)
= 0.325 熵信息增益
0.325/0.952 = 34.14%的增益
对于这个例子,基尼具有更高的信息增益测量。
最终要点:
- 基尼的最大杂质是 0.5,最大纯度是 0
- 熵的最大杂质是 1,最大纯度是 0
- 不同的决策树算法利用不同的杂质度量:CART 使用 GiniID3 和 C4.5 使用熵。在您的模型中使用决策树/随机森林之前,这是值得研究的。
*本出版物中的所有代码都可以在我的 github 上找到这里
来源:
[1]https://en . Wikipedia . org/wiki/Decision _ tree _ learning # Gini _ infinity
[2]http://web.mit.edu/6.02/www/f2011/handouts/2.pdf
[3]f . Provost 和 t . Fawcett(2013 年)。商业数据科学:你需要了解的数据挖掘和数据分析思维。加利福尼亚州科隆:奥赖利。
考虑通过我的推荐链接加入 Medium:https://andrewhershy.medium.com/membership
如果您觉得这很有帮助,请订阅。如果你喜欢我的内容,请查看其他几个项目:
Git 基础
Photo by Yancy Min on Unsplash
Git 被用作版本控制软件——用于维护软件的多个版本。
但是现在,它的用途远不止于此——与他人协作、代码版本控制、共享、将代码从本地机器部署到临时服务器,即“将代码部署到云”等等。
Git 是做什么的?
- 假设从代码的第一个版本开始,Git 不仅允许我们访问我们代码的最新版本,而且所有添加/删除的代码行都被跟踪,我们知道我们项目的所有历史。
- Git 非常擅长在不同的人之间同步代码。Git 将代码存储在一个远程服务器中,因此我们的合作伙伴可以访问相同的代码。当多人对代码进行更改时,Git 会保留一个更新的代码版本,该版本合并了所有更改,因此团队中的每个人都在同一页面上。
- Git 非常擅长测试代码。在对代码进行修改和测试以查看其工作情况时,Git 允许我们维护代码的原始副本。我们可以在测试完新代码后恢复它,或者如果对新代码满意,用原来的代码替换它。因此,Git 在允许恢复到旧版本的代码方面做得很好。
Git 与之通信的远程服务器是什么?
Git 与托管存储库(保存所有代码和跟踪变更的中央存储位置)的远程服务器通信。许多 Git 托管站点包括 Github、Bitbucket、Gitlab、Beanstalk 等,它们用于在互联网上存储 Git 存储库,以便进行软件开发版本控制。我们可以将我们的存储库“推”到远程服务器,这样我们的合作者和互联网上的其他人也可以看到并参与这些项目。同样,我们可以“克隆”我们想要工作的项目的存储库。
Git 命令
- 存储库的 url 托管在 Github/Bitbucket 或任何其他远程服务器上——我们希望将它下载到我们的计算机上
git add <filename>
:这个文件是我们下次保存存储库副本时想要跟踪的文件。请记住,我们必须位于包含要添加的文件的目录中。git add *
:添加所有未保存的文件,这显然比 git 添加单个文件要快。然而,将添加和提交分开使我们能够控制我们的存储库,并使我们能够指定我们想要跟踪的变更。git commit -m "message"
:这个命令只是保存对存储库所做的更改。-m 代表方法。该消息应该描述我们在“提交”中所做的任何更改。这非常有用,因为我们可以返回到描述一系列变化的消息列表。git status
:告诉我们我们的知识库中当前正在发生什么
我们如何将我们在本地所做的任何更改发送到托管站点?
- 将代码从我们的电脑上传到储存在互联网上的知识库中。结果,主机端,例如 GitHub,现在能够跟踪它了。
git pull
:该命令用于在本地计算机上下载最新版本的存储库。
合并冲突——Git 将尝试合并所有的更改。但是,当对一个特定文件的相同行进行了多次更改时,可能会出现冲突,这会导致我们试图运行git pull
时出现冲突。在这种情况下,因为合并不能发生,所以拉不能发生。出现一条消息,显示*“自动合并失败。您需要解决冲突,然后提交结果。”在决定要保留哪些修改后,必须进行修改。*
git log
:显示所有提交的历史记录。每个提交都可以通过唯一的提交哈希来区分。git reset --hard <commit hash>
:将存储库重置回提交哈希指定的版本。git reset --hard origin/master
:origin/master
表示存储库的版本,它是我们从中获得它的存储库的来源。
注意:对我们计算机上的存储库所做的任何更改都不会影响主机站点上正在进行的在线操作,除非我们对它进行了那些更改。
暂时就这样吧!点击此处获取更多 Git !
饭桶
Git:什么,为什么,怎么做。
每个参与计算机科学/软件/编程世界的人无疑都听说过 Git 。但是我们真的知道 Git 是什么吗,以及我们为什么要使用它吗?它的基本理念是什么?Git、 Github 、 GitLab 和其他类似 Bitbucket 的平台有什么区别?
如果你想学习所有这些东西,请继续阅读。我们将讨论 Git 的历史、它的目的和理念,然后在构建一个真实项目的同时,更深入地了解它的主要功能和特性。
不要感到不知所措,在这篇文章结束时,你会完全理解什么是 git,为什么它在软件开发中如此重要,以及你如何利用它为我们服务。让我们继续吧!
介绍
Logo of git
Git 是世界上最流行的版本控制系统(VCS)。
什么是 VCS?非常简单:VCS 是一个软件,它帮助管理随着时间的推移对特定代码所做的更改。
如果您有一个名为 CatImageDetector.py 的文本文档,并且您一直在对其进行更改,如果使用得当,VCS 将跟踪这些更改,这样,如果您想返回到与您编辑的上一个版本不同的版本(例如,因为代码不再正常工作),您可以轻松地做到这一点。
上一段有一些值得强调的内容:像 Git 这样的 VCS 被认为是为了跟上变化并存储文本文档。它们不是用来存储数据的;为此,我们有许多其他平台。因此,有时他们很难跟上 Jupyter 笔记本等格式的变化。
Git 背后的理念与通常的本地文档重写形成对比,我们做所有的事情——我们编辑一个文档,但只能看到它的最后一张图片——如果我们想回到以前的版本,我们可能做不到。
这种系统(VCS)在和不同的人一起工作时也非常有价值。假设你和另外两个同事一起做一个项目:你们都在修改相同的文档,并且希望这种协作尽可能有效。正如我们将在后面看到的,Git 允许您以尽可能好的方式做到这一点(如果遵循某些准则的话)。
我认为,这两点是 Git T1 背后的主要思想:允许用户管理他们的软件项目,以便在每一个期望的变更后备份代码,并保护项目免受团队协作时可能出现的一些不一致的影响。
Git 也有一些特殊性,使它更加引人注目,比如它的分布式特性,它是跟踪文档不同版本的方式(使用 Deltasδ:相邻版本之间的变化),它的性能或者它的安全性,但是这些问题将在后面讨论,或者超出了本文的范围。
让我们继续,简单看看 Git 是如何诞生的。
Git 的历史
Logos of Linux and git
Git 的历史与 Linux 的历史紧密相连。Linux 操作系统内核的起源——来自世界各地的开发人员都在为这个项目做贡献——要求存在一个有效的版本控制系统,让每个人都能以有序和系统的方式工作。
2005 年,这些开发人员在工作中使用的 VCSBitKeeper从免费变成了收费,因此寻找新 VCS 的竞赛开始了,最好是一个分布式的。
这个项目的首席开发人员 Linus Torvalds 过了一段时间后决定,如果他找不到适合未来任务的完美 VCS,他就自己造一个。git 就是这样诞生的。
您可能想知道 git 实际上代表什么。这个答案起初并不明显,一旦我们知道了它,并且知道了它被创造出来的目的之后,它就变得明显了。 GIT 代表“全球信息跟踪者”。
**酷吧?**好吧,让我们更专业一点。
Git 基础——使用组
如前所述,Git 的优点之一是它有效地允许我们与来自世界各地的人们一起工作。然而,为了这种合作的成功,我们不能只是以我们认为合适的方式使用 git,并希望我们的同事理解我们所做的,并相应地推动他们的行动;必须遵循一些指导方针。
但是首先,在定义这些准则之前,让我们描述一下 git 的一些基本元素:存储库和分支。
存储库和分支
一个存储库,尽管它的名字很长,最好理解为一个文件夹,就像我们电脑中的文件夹一样,我们正在处理的所有元素都存储在那里。
在同一个项目中工作的人将从同一个存储库中进行修改、上传文档和下载文档。
分支是促进自组织和协作工作的工具。项目通常从称为主分支的初始分支开始,并从那里构建多个其他分支,形成树状结构。
Repositories tree-like structure
**为什么要这样做?**想象一下,你正在和 4 到 5 个不同的人一起做一个项目,他们和你一样修改相同的脚本,但是实现不同的功能。如果你们都不断地上传对主分支上相同内容的修改,一切很快就会变得混乱。相反,每个人都应该在他们自己的分支上工作,在那个分支上实现变更,并且当所有的事情都在他们自己的分支上完美地工作时,这些变更应该被小心地合并。
指南和 Git-Flow
现在我们知道了什么是*(存储库的简称)和分支,让我们看看正确使用它们的指导方针。上一段的描述只是一个简单的例子来说明什么是分支,但是使用它们不仅仅是为每个开发人员/特性创建一个分支,然后将它们组合在一起那么简单。*
我们已经谈到了主分支,说它是任何项目的根或主要分支,但是我们没有给予它应有的重要性。主分支是存储项目的最新工作或生产代码的分支,只应在上传将要实际使用的经过全面测试的代码时使用。这里上传的任何东西都应该可以投入生产了。
如果我们不能触及主要分支,那么我们如何构建代码呢?简单:我们创建另一个分支,通常称为 develop,,这是我们实际开发代码的地方,也是我们不断进行更改的地方。
等等,当上述情况发生时会发生什么,例如,我们有许多人在同一代码库的不同功能上工作?你可能会猜到答案:我们从 develop 分支出分支,并在那里工作,一旦我们完成工作,就将更改上传到 develop,并检查与其他开发人员的代码没有冲突。
Image from: https://nvie.com/posts/a-successful-git-branching-model/
然而,当只有少数开发人员接触开发分支上的相同代码时,可能没有必要从它创建多个分支。此外,有时我们可能希望从存储库中的某个点开始创建一个分支,以便从那里为产品的不同版本或发布开发新的特性。
当来自开发的代码已经被测试、测试、再测试,是的,再测试,然后我们可以上传变更到我们的主分支。
最普遍接受的方法是通过所谓的Git-Flow**完成,您可以在这里找到:**
在这篇文章中,我将展示我为自己的一些项目(包括工作和私人项目)介绍的开发模型…
nvie.com](https://nvie.com/posts/a-successful-git-branching-model/)
现在我们知道了如何有效地处理分支,让我们简单地看一下主要的 git 命令,然后展示一个实际的例子。
Git 命令
我不打算描述所有的 git 命令及其输出,只是为了能够使用 git 来管理项目的代码,您 100%需要了解并熟悉的命令。
- status:
git status
该命令显示您的存储库的当前状态,说明哪些文件已经被修改,哪些文件已经被添加或提交。 - branch :
git branch
返回我们存储库的分支,突出显示我们当前正在处理的分支。
Output of the git branch command
- add:
git add document.py
告诉 git 您想要在下一次提交中包含在 document.py 中所做的更改。
Returns of the git status command before and after adding a file
- commit:
git commit -m "message"
commit 命令基本上记录了您所做的更改,并将其添加(使用之前的命令)到您的本地存储库中。commit 命令有一条消息,通常描述已进行的更改以及通过 commit 上传的更改。
Output of the commit command
我们在文章中提到了 git 的分布式本质,这是它最早的特性之一,但我们并没有真正描述这意味着什么。它被称为分布式,因为每个 git 工作目录都包含一个完整的存储库,其中包含该树的完整历史。
您通常有一个远程存储库(可以配置),从中上传和下载代码,但是 git 的性质并不要求您这样做。
- push:
git push
该命令将您在本地 repo 中所做的更改(通过提交)发送到您已经配置的远程存储库。
Output of the push command
- **拉:**拉是推的兄弟命令。它将远程存储库下载到您的本地机器上。
最后,我们将看到允许我们使用分支的命令:
- checkout:
git checkout branch
就是我们如何从我们所在的分支切换到另一个分支。分支是这个命令是我们想要切换到的分支。checkout 命令也可以用来创建新的分支。使用命令git checkout -b newly_created_branch
我们创建一个新的分支并切换到它。
Switching from master to develop
- 合并:
git merge branchToMergeFrom
我一直在说上传,但实际上合并两个分支的词是合并。这意味着将您在一个分支中所做的更改移动到您所在的分支。通常的做法是这样的:想象我们想把我们的变更从开发变成主控。首先,如果我们在开发中,我们必须签出到主节点,然后git merge develop
将我们的开发分支中所做的更改传递到我们的主节点分支。请记住,只有当代码已经可以使用并经过测试时,才可以这样做。
Merging from develop to master
这些是使用 git 时需要知道的主要命令。现在您已经了解了它们,让我们探索一下 git 和使用它的各种服务之间的区别!
Git vs GitHub 和其他平台
什么是 GitHub,GitLab,BitBucket,Azure repos 等等?他们和 git 是什么关系?
git and GitHub
我们在这篇文章中多次提到,git 的关键特征之一是它的去中心化特性。这意味着一组用户在他们的本地机器上有 git,知道其他用户的 IP 地址,并使用其对应的凭证建立 HTTP 或 SSH 隧道,一切都可以从他们的伙伴的本地机器推送或向他们的伙伴的本地机器拉取回购。
然而,对于商品来说,如果我们只使用 git 来管理协作,那将会是建立一个远程服务器,让每个人从那里进行推和拉。这难道不会使 git 集中化吗?嗯,从技术上来说不是,因为这个远程服务器不会构成网络的单点故障:如果代码在远程服务器上,这意味着它已经在用户的本地机器上,因此我们可以从那里恢复它。
像 Github、GitLab、或 Bitbucket 这样的服务提供的只是一种高效、有组织、简单的方式来做到这一点,同时还增加了额外的功能,如拉请求和一个闪亮的基于 web 的用户界面。在这种情况下, Git(一个 VCS)是被各种基于 c 语言的服务使用的工具,比如 Github 。Git 是一个管理源代码的开源工具,而 Github 是一个在线服务,git 用户可以通过连接上传或下载资源。Git 是核心,GitHub 和其他服务提供了围绕它的层。
为了让你的代码进入 GitHub,看看这里。最后,让我们看一个简单快捷的例子,展示如何使用 git 来管理 Github 上的一些代码及其工作流。
使用 Github 的 Git 示例
好了,现在我们已经涵盖了所有的理论,让我们来看看一个非常简单的 Github 使用示例。许多现代的 ide,如 Sublime Text、Visual Studio 或 Pycharm,都内置了 git 插件,这样我们就可以轻松地将代码上传到我们之前提到的某个平台上。在我们的例子中,我们将使用 Pycharm。
首先,我们将创建一个新项目,并为它指定我们想要的名称: *Git_for_Noobs。*然后,在名为 Git_for_medium.py 的脚本中,我们将编写以下代码:
print("Hello Medium!")
保存它,然后继续添加到我们的本地 git repo,并使用消息"*First commit of the Git _ for _ Noobs repo "*进行第一次提交,如下面的视频所示。
git add and then commit
但是,如果我们现在尝试推送到远程回购,它会给我们一个错误,因为我们还没有配置。首先,我们需要进入项目的 VCS 选项,并创建一个 GitHub 存储库。一旦我们完成了这些,工具可能会为我们推送第一次提交,如果我们正在使用 GitHub,我们会看到一个新的存储库已经创建,如下图所示。
Repository Git_for_Noobs with our first commit
Content for the Git_for_medium.py file
好了,现在我们已经创建了我们的回购并上传了我们的第一个文件,让我们创建一个新的分支并做一些更改。首先,让我们变得更加外向一些,将代码改为如下所示:
print("Hello Internet!")
之后,让我们使用git checkout -b develop
创建一个名为 develop 的新分支(默认情况下,当创建一个新的 repo 时,第一个分支将被称为 master ),并将我们的文件 Git_for_medium.py 添加到其中*。*
Creating a new branch called develop and adding it
最后,让我们提交这些更改,然后将它们推送到 GitHub。
Commit and push
如您所见,push 命令给了我们一个错误,因为我们在远程 repo 中没有一个名为 develop 的分支(它只是在本地创建的),并且它不知道将我们的代码放在哪里。使用- git--set-upstream origin develop
我们告诉它将更改推送到 GitHub repo 中一个新的分支,名为 develop。让我们来看看变化吧!
We now have two branches, master and develop.
现在我们有两个分支,master 和 develop,它们都有不同的代码,因为我们的第二个提交只被推送到 develop 而不是 master。
Contents of the develop and master branches
让我们对我们的脚本做最后的修改,并推动它发展。现在我们已经完全进入外向模式,想和每个人打个招呼。这段代码现在将成为编程社区中最著名的一句话:
print("Hello world!")
现在,一如既往,我们按照这个顺序添加、提交和推送。
add, commit and push changes in our file
在下图中,我们可以看到 develop 分支中代码的最后一种格式(顶部),以及我们对 repo 所做的所有提交,独立于它们所在的分支(底部)。
Last change to our Git_for_medium.py on develop and all the history of commits to our repo
作为最后一步,让世界知道我们现在是一个更加外向的人,并且更新我们在开发分支中所做的改变以掌握。这可以通过checkout
命令(移动到母版)完成,然后合并开发,如下图所示。
Merging from develop to master
在内部,合并工作就像任何其他提交一样,所以在这之后我们还必须使用git push
推送我们的远程回购。现在,如果我们看一下主分支,我们有与开发分支相同的代码!酷吧?
Last state of our Master branch after the merge
结论
Git 是一个非常有用的软件开发工具。我们已经看到了它的用途,它不应该用于什么,它的哲学,起源以及与使用它的服务的区别。
更多类似这样的帖子请在 Medium 上关注我,敬请关注!
就这些,我希望你喜欢这个帖子。请随时在 LinkedIn 上与我联系,或者在 Twitter 上关注我。还有,你可以看看我在数据科学和机器学习上的帖子这里 。好好读!
额外资源
如果你想了解更多一点,澄清你从这篇文章中学到的东西,或者深入这个主题,我在这里留下了一些信息,我认为可能会很有用。
[## 什么是 Git:使用本指南成为 Git 专家| Atlassian Git 教程
到目前为止,当今世界上使用最广泛的现代版本控制系统是 Git。Git 是一个成熟的、积极的…
www.atlassian.com](https://www.atlassian.com/git/tutorials/what-is-git)
Git 工作流是如何使用 Git 以一致且高效的方式完成工作的诀窍或建议…
www.atlassian.com](https://www.atlassian.com/git/tutorials/comparing-workflows)
- 关于如何使用 git 在团队中工作的博客文章
不知道命令做什么就停止记忆命令!
blog.hipolabs.com](https://blog.hipolabs.com/how-to-work-in-a-team-version-control-and-git-923dfec2ac3b)
Git 和 GitHub 一样吗?肯定不是。自从微软……以来,Git 和 GitHub 的比较越来越频繁
www.theserverside.com](https://www.theserverside.com/video/Git-vs-GitHub-What-is-the-difference-between-them)
- 在 h 上发布如何开始使用 git
在开始使用 Git 之前,您必须让它在您的计算机上可用。即使已经安装了,也是…
git-scm.com](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
尽情享受,有任何疑问随时联系我!**
20 分钟后准备好!
当我开始我的数据科学之旅时,一位密友兼导师建议我熟悉 git。这似乎是一种干扰,但我想,“这是一个版本控制系统。我肯定能在 2-3 天内学会,并回到 Python 的美丽世界。”我大错特错了。我离开 Python 两天的短暂旅行变成了三个月的假期。我当然不后悔花费的时间,因为不可否认学习 git 的重要性。git 对于每个程序员的重要性已经在几个优秀的博客中有很好的描述,我在这里不打算重复了。
对于像我这样没有编程背景的初学者来说,一开始可能看起来有些吓人。在花了大量时间试图理解 git 的底层概念和内部结构之后,我意识到它真的没有尽头。然而,它可以分阶段学习。如果你从来没有使用过 git,并且一直把它放在后面,我强烈建议你至少开始使用它。它并不像看起来那么复杂,您可以随时随地学习更多功能。到本文结束时,您将对 git 的功能有一个大致的了解,用 GitHub 创建了一个帐户,采取了安全措施,创建了一个存储库,并检入了一些代码——所有这些都有望在 20 分钟内完成!
让我们从几个关键概念开始。
吉特
Git 是一个版本控制系统;分布式的。版本控制系统(VCS)记录关于代码文件的变更内容、变更时间、变更地点和变更人的信息。与其他 VCS 不同,git 是“分布式”的*,即*。,它不是由中央服务器管理的。Git 以快照的形式存储数据。当您保存一个文件的状态(在 git 术语中称为 commit)时,git 获取文件的一系列快照,并为它分配一个惟一的 40 个字符的键。在下一次提交期间,它会再次拍摄一系列快照。如果进行了任何更改,将生成一个新的密钥。如果没有,则使用相同的键引用该文件。因此,在其核心,git 只不过是一个键值数据存储。
git 的核心是一个 键值 数据存储。持久化地图。
GitHub
Git 协议由几个服务提供商托管,例如 GitHub、Bitbucket 和 Codebase。GitHub——最近被微软收购,是最流行的 git 托管平台之一。现在你知道为什么不能互换使用术语 git 和 GitHub 了。
储存库
git 存储库是与项目相关的所有文件和文件夹的集合。简单地说,存储库就像一个包含文件夹、子文件夹和文件的目录。GitHub 允许你创建无限数量的公共和私有库。顾名思义,公共存储库是公开的,可以查看和复制;而用户可以展示对其私有储存库的访问控制。
SSH 密钥
SSH 或安全 Shell 允许使用加密技术在主机和客户端之间建立安全连接。SSH 密钥的生成本质上是公钥-私钥对的生成。使用安全 Shell 身份验证的动机是大大增强双方(在本例中是您的计算机和 GitHub)之间信息传输的安全性。为了更好的理解 SSH 协议,请参考 ssh.com的
命令行界面
CLI 允许您通过命令与计算机进行交互。与使用鼠标点击图形图标的图形用户界面(GUI)不同,使用 CLI 的交互更快、更可靠,并允许高级操作。如果您以前从未使用过终端,现在是时候开始了。这个阶段只需要几个命令。如果您熟悉使用 CLI,请随意跳过这一部分。打开终端窗口,键入以下命令以了解如何在文件夹和文件中导航。在光标处键入命令,然后按 Return 键执行命令。
ls
列出目录的内容。您的目录可能包含文件和文件夹。一旦您键入“ls”并按下 return 键,所有内容都会列出来。
ls –a
列出内容,包括隐藏的文件和文件夹。
cd <folder_name>
cd 代表“更改目录”。键入您希望导航到的文件夹/目录的名称(不要键入<>)。如果目标文件夹不在当前目录中,您需要键入目标文件夹的完整路径。或者使用命令 cd…
cd ..
在目录中向上导航一步。
pwd
打印当前目录的路径
clear
清除所有以前命令的屏幕
cp <source/filename> <destination>
cp 代表复制。要将文件从一个位置复制到另一个位置,请使用上述格式。
这就足够开始了。我在这里假设您使用的是基于 MacOS 或 Unix 的系统。您熟悉基本的终端命令,并且能够导航到所需的目录。
创建 GitHub 账户
通过注册使用 GitHub 创建一个帐户。现阶段可以选择免费计划。验证电子邮件地址将引导您进入主页。
生成 SSH 密钥
如果愿意,您可以在 GitHub 中使用现有的 SSH 密钥,在这种情况下,您可以直接进入下一步——添加 SSH 密钥。要生成新的 SSH 密钥,请转到终端,执行命令**ssh-keygen**
。将提示“正在生成公钥/私钥对”的消息。只需点击返回接受默认位置和文件名。如果。ssh 目录不存在,系统会为您创建一个。出现提示时,输入并重新输入密码。执行命令**ls –a**
列出名为. ssh 的隐藏文件夹。ssh 通过**ls**
命令。将列出三个文件,其中 id_rsa 包含私钥, id_rsa.pub 包含公钥。通过执行命令 **cat id_rsa.pub**
在屏幕上显示公钥,并从终端窗口复制密钥。
添加 SSH 密钥
在线访问您的 GitHub 帐户。单击个人资料图标旁边的下拉菜单。点击设置并导航至 SSH 和 GPG 键。单击新建 SSH 密钥按钮,添加一个标题(例如:id_rsa.pub)并粘贴从终端窗口复制的公钥。请注意,您不应该共享您的私钥。现在您已经启用了 SSH 访问来安全地管理 GitHub 的 git 操作。
Add new SSH key on GitHub
创建存储库
导航到 GitHub 主页。在左侧面板中,单击链接到创建新存储库。为您的存储库指定一个名称,例如:“my-python-notebooks”,并提供一行描述。选择 Public ,Initialize Repository with a ReadMe,点击 Create Repository 按钮。
Create a repository on GitHub
克隆你的仓库
您刚刚在 GitHub 上创建的存储库位于一个远程位置。为了能够在离线模式下使用它,您需要克隆存储库。这使您能够在本地计算机上创建存储库的副本,并在两个位置之间进行同步。在 GitHub 上,在资源库名称下,点击 Clone 或 download。在使用 SSH 克隆部分,复制存储库的克隆 URL。
Clone your repository
转到终端,将工作目录更改为要保存克隆存储库的目录。键入**git clone**
,然后粘贴你之前复制的网址并点击回车键。GitHub 上的资源库现在已经克隆到您的计算机上了。
git 添加
现在,您的本地计算机中已经有了存储库,您可以将任意数量的文件夹和/或文件复制到其中。例如:使用cp
命令复制一个现有的 Jupyter 笔记本 filename.ipynb 。一旦在本地存储库中有了 filename.ipynb,就执行**git add <filename.ipynb>**
。git add 命令拍摄文件快照,为版本控制做准备。请注意,此文件尚未“版本化”。此步骤为提交“暂存”文件。
git 提交
要提交转移文件,请执行以下命令:
git commit –m“The file contains basic Python datatypes.”
引号内的注释是关于文件内容或用户所做修改的描述性消息。此步骤将文件快照永久记录在版本历史记录中。
git 推送
执行git push
命令将提交上传到 GitHub。现在,您可以刷新浏览器,并确认 GitHub 上的存储库中的文件版本。
恭喜你!!!
您已经成功地创建了第一个存储库,并签入了要由 git 跟踪的文件。
下一步是什么?
我建议您扎实地创建存储库,添加和/或编辑更多文件,并提交修改。接下来,您应该能够在本地计算机上的现有目录中启动 git 跟踪。此外,理解分支、合并、拉请求和部署的概念。这些过程是在与开发团队协作的同时实现的。
数据科学家的 GIT 存储和分支
数据科学项目中的连续过程
Photo by Kristopher Roller on Unsplash
数据科学家,分析数据,做预处理,建立模型,测试模型,部署模型。但是在所有这些步骤中,肯定应该用 R 或 Python 编程。通常一个人或一组人在同一个项目上工作,这需要整合,这样每个人都应该在同一页上。为了进行这种集成,版本控制成为大多数数据科学家使用 GIT 作为版本控制的一种方式。
在这篇文章中,我将关注我们在 GIT 上面临的主要挑战。它们主要是存储和分支。
隐藏
让我们假设您正在构建一个模型,并且收到了另一个变更请求。您需要快速保存当前的变更,并在其他变更请求工作完成后将它们应用到存储库中。
为了做到这一点,GIT 提供了一个有用的命令 git stash ,它允许你保存你的更改并返回到干净的工作目录。
创建一个仓库
假设您已经完成了数据预处理,并且想要临时保存您的更改并返回到工作目录。下面的命令将帮助你做到这一点。
git stash “preprocessing done”
列出所有藏匿处
您刚刚创建了一个仓库,如果您想查看所有现有的仓库,可以使用下面的命令。
git stash list
输出
stash@{0}: preprocessing done
stash@{1}: get the data
最新的存储将在顶部,索引为 0。
应用存储
到目前为止,您已经创建了 stash,并假设您已经完成了新的工作或者收到了变更请求。现在您必须取回您保存的更改,这可以通过应用创建的存储来完成。
git stash apply stash@{0}
这将应用更改,但存储不会从列表中删除。为此,我们必须使用下面的命令。
git stash drop stash@{0}
分支
数据科学家永远不会以构建单一模型而告终,而是继续尝试其他预处理技术或算法。因此,为了不干扰现有的分支,我们去创建分支。当工作是实验性的或者添加新的特性来封装变更时,我们创建分支。
在这里,我将指导您如何从现有的分支创建一个分支,删除一个分支,列出所有分支以及合并分支。
列出所有分支
在我们开始创建和删除分支之前,让我们尝试用下面的命令列出所有现有的分支。
git branch -a
-a 指定我们希望看到本地系统和远程存储库中的所有分支。
从主控形状创建分支
要从主服务器创建本地分支,可以使用以下命令。
git checkout -b new-branch master
您可以添加、修改、删除任何文件并提交更改。
git add <filename> git commit -m “New features created”
如果您想将这个分支推到远程,可以使用下面的命令。
git push origin new-branch
合并分支
到目前为止,我们已经创建了新的分支,假设我们已经在新的分支中实现了一些特性。下一个任务是将这个分支合并到主分支中。我们可以使用下面的命令来实现这一点。
git checkout master
git merge new-branch
结帐主,指定您正在切换到主分支
稍后您可以将这些更改推送到存储库中。
删除本地和远程分支
数据科学项目包含许多功能和变更请求。我们不断地创造我们想要的分支,它们会堆积起来。为了摆脱它们,我们需要删除它们。
删除一个本地分支
git branch -d <branch name>
使用上面的命令,分支将在您的本地系统中被删除,但不会在远程系统中被删除。
删除一个远程分支
git push <remote name> :<branch name>
上述命令将删除存储库中的分支。
N **注意:**我从主节点获取了创建或合并分支,但是它可以是任何现有的分支。
希望你喜欢它!!敬请期待!!!请对任何疑问或建议发表评论!!!
git——版本控制系统
你为什么需要版本控制软件——你做了一些东西,现在你想在它被破坏或删除之前把它保存在某个地方,这样你就可以从你停止的地方继续工作。
有道理吗?
好了,我们再深入一点,我对做个人网站很感兴趣。我研究了它的代码,花了几天时间。但是我的系统不支持挂起,或者硬盘可能已经崩溃,或者我错误地修改了我的代码,我无法返回到以前的状态。
这种事过去也发生在我身上,令人沮丧。
这就是 Git 的用武之地,它通过跟踪你当前的项目和你所做的所有修改,而不是在你的系统上用不同的名字保存每一个版本,把你从所有的麻烦和挫折中解救出来。
有很多软件可以跟踪你的工作,但是这里我们只讨论 Git。Git 是一个版本控制软件,它跟踪对代码的修改。
因为每个公司都需要它,所以你的简历上会多一项技能。我猜这是有道理的?
好吧!也许你对它不满意。也许你喜欢把每个文件都保存在本地。
我再给你一个答案然后就说得通了。
现在,我正计划与我的朋友合作,为我的网站有许多技能,这将有利于网站,为此,我需要更多的人。但是把它放在本地会让工作有点困难。因为每次你们都应该一起工作,而不是远程工作。
Git 可用于合并来自不同用户的已有版本的新版本,并清楚地了解在哪里以及由谁进行了哪些更改。
饭桶
Git 是一个分布式版本控制系统,每个用户都可以对他们系统上的整个存储库进行修改。它使用命令行,通过 git,可以很容易地来回撤销更改,并精确解释所做的更改。它具有以下能力:
- 跟踪变化,即同一文件的不同版本。
- 它还记录了项目中存在的所有文件。
- 比较和分析不同的代码并给出详细的解释。
现在你知道为什么 Git 但是如何使用它了吧?
开始在 Git 环境中工作的基本步骤是拥有一个本地存储库和一个远程存储库。
**本地存储库:**本地存储库是您在本地计算机上创建的路径或目录,它是一个工作目录。您在这个私有的存储库中编写代码,直到您将它推送到远程存储库中。
**远程存储库:**远程存储库是一个公共目录,或者是一个托管您的网站的公共平台,如 Github 或 Bitbucket。使用 Git,可以很容易地将一段代码或整个项目推到远程目录。
现在你的朋友也可以做出改变了。😃
Cloud Repositories: Github, Bitbucket, Gitlab
安装指南
现在是时候将它安装到您的系统上了。请看看这个链接来安装它。-> 安装指南
关键概念
让我们试着理解这里的一些关键术语:
- **版本控制系统:**该工具维护不同版本的代码。也称为源代码管理器。
- **提交:**当您进行更改时,在将更改发送到临时区域/临时索引并随后发送到远程存储库之前,这些更改应该保存在本地存储库中。这将您的代码保存到 Git 中。如果你想了解更多关于提交的信息,请点击链接 git commit 。
- **签出:**当存储库中的内容被复制到工作目录时。
- SHA(安全哈希算法):给每个提交一个唯一的 ID。
- **分支:**当你偏离了发展主线,继续做工作而不弄乱发展主线的时候。
配置 Git
使用 cd 命令,您可以转到您的工作目录,并为您的本地和远程存储库设置用户凭证。这些凭证用于将代码推送到远程存储库中。
- 使用此命令,您可以输入用户名和用户电子邮件 id。
使用 $ git config -l ,您可以检查所做的更改是否得到了反映。
Git 上的本地存储库
首先,存储库应该存在于本地系统中。这个存储库将用于存储当前项目,它可以在以后被推送到 GitHub 上。我们使用命令行来探索存储库。使用命令 cd,转到路径并使用 mkdir 命令创建一个目录。
- git init :一旦创建了目录,使用 git init 命令初始化它。git init 命令创建了一个新的 git 存储库,现在是主分支。存储库是一个版本控制系统,用于存储源代码和其他开发项目。
您可以通过简单地复制文件夹或使用命令行将代码文件或任何文本文件保存到该路径。
使用 git branch 命令“git branch -m master oldmaster”。您也可以更改主分支。
- **git 状态:**使用 git 状态很容易看到存储库中所做的更改。比方说,我使用 git status 命令向 git 显示的分支添加了一个新文件。使用此命令可以看到所做的任何更改。这并不意味着已经做出并存储了更改。
3。git add: 所做的更改应该在提交之前添加。使用 git add 命令将代码或任何文件添加到临时区域。
为了一次添加多个文件,我们使用命令 git add -A. 将本地存储库中所有修改过的文件移动到暂存区。
4。 git commit: 用于将文件从暂存区存储到存储库中。
在本地克隆存储库
您可能希望在 GitHub 或任何远程环境中现有的存储库上工作。可以使用 git clone 命令克隆这个存储库,并将其存储在本地系统上以进一步增强代码。克隆存储库的命令是现有存储库>的 git clone < path。
克隆存储库时,请记住命令行并不指向另一个存储库。
查看提交历史的命令
在处理代码时,您可能希望回滚所做的更改,或者对代码进行任何更改,以查看以前所做的更改。有命令可以查看过去发生了什么变化。
- git log :查看在存储库上进行的所有提交。我们使用 git log 命令。在命令中添加 SHA 键,我们可以看到一个特定的提交,后面跟着其他提交。为了只检查作为变更描述的一行,使用命令 git — oneline 。
2。git — stat :这个命令用于查看被修改的文件,以及添加或删除了多少行代码。
3。git log -p: 查看所做的实际更改,即可以使用该命令显示添加或删除的行。p 代表补丁。
在所有这些命令中,您都可以传递 SHA 键,这在查看特定提交时会很有用。
GitHub 上的远程存储库
可以使用 Git 将代码推送到 GitHub。为此,应该在 GitHub 上做个交代。其次,应该在 GitHub 上创建一个新的存储库,方法是单击“+”然后单击“New Repository”按钮。
一旦你点击了新的存储库,它将引导你到一个页面,在那里你给出了你正在工作的项目的细节。回购的名称和描述。如果你不想分享你的回购,你可以选择私人选项。如果您愿意,以后可以更改它。
创建存储库后,它会将您转到下一页,您可以在这里选择是创建新的 repo,然后将代码推送到远程,还是将代码推送到现有的存储库中。
如果您已经在本地创建了 repo,那么您可以使用 SSH 将代码推送到 GitHub。
将主分支推送到 GitHub
因为我们已经在本地创建了 repo,所以我们将代码直接推送到 GitHub repo。当进行修改时,你将需要 GitHub 帐户的凭证。
—关于分支的更多信息—
创建新分支
不要直接对主分支进行更改,应该习惯在不同的分支中进行更改。但是,如果新的更改不起作用,您可以返回到以前的提交,但是在组织中这会导致业务损失。
相反,最好是在一个新的分支中工作,测试所做的更改,然后将其转移到生产环境中。
使用命令git branch添加一个指向主节点的分支。但是如果要对一个现在不是主节点的提交进行修改,那么使用git branchSHA。 SHA 告诉您在哪个提交之后应该放置新分支。
使用**git check out命令,我们将主分支移动到一个名为 branch-name 的新分支。现在,您可以通过使用与我们对旧的主分支所做的相似的步骤来添加和提交对这个分支的更改。然后将您的分支推送到远程存储库:git Push-u origin**
如果成功,使用**git merge将代码与旧的主分支合并。**但是在运行 merge 命令之前,您需要使用 git checkout 命令切换回原来的主分支。
还可以使用 git 命令重命名、删除、比较分支:
- 重命名:git branch-m
- 删除:git branch-d
- 比较分支:git diff
结论
Git 是免费和开源的。它易于使用,速度更快。它允许你在云上运行你的代码,并跟踪所有以前对项目的修改,即完整的变更历史。每次提交都包含作者的姓名、提交的描述、提交的时间戳和前一次提交的 SHA1 散列。
Git 在团队在偏远地区工作的情况下非常有用。因为任何个人都可以进行更改,只要授予对远程存储库的访问权限。
您可以将本地存储库与任何远程存储库(如 GitHub、GitLab、Bitbucket 等)链接起来。
带有机器学习的 Github 自动完成
作者óscar d . Lara Yejas和 Ankit Jha
作为数据科学家,软件开发是更贴近我们的领域之一,因为毕竟我们是各种帮助我们构建模型的软件包和框架的狂热用户。
GitHub 是支持软件开发生命周期的关键技术之一,包括跟踪缺陷、任务、故事、提交等等。在一个大型的开发组织中,可能会有多个团队(即小队)承担特定的职责,例如性能小队、安装小队、 UX 小队和文档小队等。当创建一个新的工作条目时,这会带来挑战,因为用户可能不知道一个任务或者缺陷应该被分配给哪个团队,或者谁应该是它的所有者。但是机器学习能有帮助吗?答案是是的,特别是,如果我们有一些来自 GitHub 库的历史数据。
问题陈述
我们在本文中试图解决的问题是:我们是否可以创建一个 ML 模型,根据 GitHub 工作项的标题和其他特征来建议团队和所有者?
工具
在本文中,我们将使用 R 编程语言。需要以下 R 包:
suppressWarnings({
**library**(tm)
**library**(zoo)
**library**(SnowballC)
**library**(wordcloud)
**library**(plotly)
**library**(rword2vec)
**library**(text2vec)
**library**("reshape")
**library**(nnet)
**library**(randomForest)
})
数据集
GitHub 提供了不同的工作项特征,如 id 、标题、类型、严重性、小队、作者、状态、日期等。标题将是我们的主要数据源,因为它总是需要的,并且可能具有最高的相关性;不难想象,比如工作项标题为*“尝试部署 Docker 实例时安装程序失败”的话,很可能应该分配给安装程序小队。或者,一个标题,如“特征 XYZ 的文档丢失”*,表明该工作项可能被分配给文档团队。下面是 GitHub 数据集的一个例子。
# Load the dataset from a CSV file
workItems <- **read.csv**('../github-data.csv')# Show the dataset
**show**(workItems)
Table 1: Sample GitHub dataset
注意,无论是小队还是受让人(即主人),都是地面真相,在历史资料中给出。这意味着,我们可以把它当作一个分类问题。现在,由于工作项标题是以自由文本的形式给出的,所以可以使用一些自然语言处理技术来获得一些特性。
自然语言处理(NLP)基础知识
让我们介绍一些 NLP 术语:
- 我们的数据集(工作条目标题的集合)将被称为语料库。
- 每个工作项标题都是一个文档。
- 语料库中所有不同单词的集合就是词典。
从自由文本中提取特征的一个非常简单的方法是计算词频 (TF),即计算字典中的每个单词在每个文档中出现的次数。出现的次数越高,这个词的相关性就越强。这产生了一个文档-术语矩阵(DTM) ,每个文档有一行,列数与字典中的单词数一样多。该矩阵的位置【T10(I,j)】表示单词 j 在标题 i 中出现的次数。
您可以立即看到,得到的特征集将非常稀疏(即,具有大量零值),因为字典中可能有数千个单词,但每个文档(即,标题)将只包含几十个单词。
TF 的一个常见问题是诸如“the”、“a”、“in”等词。倾向于非常频繁地出现,然而它们可能并不相关。这就是为什么 TF-IDF 通过将一个单词除以它在整个语料库中的频率函数,从而将该单词在文档中的频率归一化。这样,最相关的单词将是出现在文档中但在整个语料库中不常见的单词。
数据监管
现在,在应用任何 NLP 技术之前,需要进行一些文本处理。这包括删除停用词(例如,介词、冠词等。)、大小写、标点符号和词干,这是指将词形变化/派生的单词简化为它们的基本或词根形式。下面的代码执行所需的文本预处理:
preprocess <- **function**(text) {
corpus <- VCorpus(VectorSource(tolower(text)))
corpus <- tm_map(corpus, PlainTextDocument)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords('english'))
corpus <- tm_map(corpus, stemDocument)
data.frame(text=unlist(sapply(corpus, `[`, "content")),
stringsAsFactors=F)
}curatedText <- preprocess(workItems$TITLE)
Table 2: Results of text curation after removing stop words, punctuation, and case, as well as stemming the documents.
特征提取
以下代码将通过将 TF-IDF 应用于我们的策划文本来创建功能。生成的 DTM 在字典中每个单词都有一列。
# Create a tokenizer
it <- itoken(curatedText$text, progressbar = **FALSE**)# Create a vectorizer
v <- create_vocabulary(it) %>%
prune_vocabulary(doc_proportion_max = 0.1, term_count_min = 5)vectorizer <- vocab_vectorizer(v)# Create a document term matrix (DTM)
dtmCorpus <- create_dtm(it, vectorizer)
tfidf <- TfIdf$new()
dtm_tfidf <- fit_transform(dtmCorpus, tfidf)
featuresTFIDF <- as.data.frame(as.matrix(dtm_tfidf))# Add prefix to column names since there could be names starting
# with numbers
colnames(featuresTFIDF) <- paste0("word_", colnames(featuresTFIDF))# Append the squad and type to the feature set for classification
featureSet <- cbind(featuresTFIDF,
"SQUAD"=workItems$SQUAD,
"TYPE"=workItemsCurated$TYPE)
Feature set example.
现在我们有了一个特性集,其中每行是一个工作项,每列是它的 TF-IDF 分数。我们也有工作项目的类型(例如,任务或者缺陷)和基本事实(例如,团队)。
文本分类
接下来,我们将为训练集和测试集创建拆分:
random <- runif(nrow(featureSet))train <- featureSet[random > 0.2, ]
trainRaw <- workItemsFiltered[random > 0.2, ]test <- featureSet[random < 0.2, ]
testRaw <- workItemsFiltered[random < 0.2, ]
随机森林
r 提供了 randomForest 包,它允许训练一个随机森林分类器,如下所示:
# Train a Random Forest model
> model <- randomForest(SQUAD ~ ., train, ntree = 500)# Compute predictions
> predictions <- predict(model, test)# Compute overall accuracy
> sum(predictions == test$SQUAD) / length(predictions)
[1] 0.59375
音符准确度低于 60%,这在大多数情况下是非常糟糕的。然而,仅仅根据标题来预测一个工作项目应该被分配到哪个组是一项非常具有挑战性的任务,即使对人类来说也是如此。因此,让我们为用户提供两到三个关于给定工作项的最可能团队的建议。
为此,让我们使用由 randomForest 提供的每个单独类的概率。我们需要做的就是对这些概率进行排序,并选择具有最高值的类。下面的代码正是这样做的:
# A function for ranking numbers
ranks <- function(d) {
data.frame(t(apply(-d, 1, rank, ties.method='min')))
}# Score the Random Forest model and return probabilities
rfProbs <- predict(model, test, type="prob")# Compute probability ranks
probRanks <- ranks(rfProbs)cbind("Title" = testRaw$TITLE,
probRanks,
"SQUAD" = testRaw$SQUAD,
"PRED" = predictions)rfSquadsPreds <- as.data.frame(t(apply(probRanks,
MARGIN=1,
FUN=function(x)
names(head(sort(x,
decreasing=F), 3)))))# Compute accuracy of any of the two recommendations to be correct
> sum(rfSquadsPreds$V1 == rfSquadsPreds$SQUAD |
rfSquadsPreds$V2 == rfSquadsPreds$SQUAD) / nrow(rfSquadsPreds)
[1] 0.76# Compute accuracy of any of the three recommendations to be correct
> sum(rfSquadsPreds$V1 == rfSquadsPreds$SQUAD |
rfSquadsPreds$V2 == rfSquadsPreds$SQUAD |
rfSquadsPreds$V3 == rfSquadsPreds$SQUAD) / nrow(rfSquadsPreds)[1] 0.87
请注意,有两个建议,其中任何一个正确的概率是 76%,而有三个建议,这个概率变成 87%,这使得模型更加有用。
其他算法
我们还探讨了逻辑回归、XGBoost、Glove 和 RNNs/LSTMs。然而,结果并不比随机森林好多少。
特征重要性
Feature importance (Given by XGBoost)
部署
为了将这个模型投入生产,我们首先需要导出(1)模型本身和(2)TF-IDF 转换。前者将用于评分,而后者将提取用于训练的相同特征(即单词)。
导出资产
# Save TF-IDF transformations
saveRDS(vectorizer, "../docker/R/vectorizer.rds")
saveRDS(dtmCorpus,"../docker/R/dtmCorpus_training_data.rds")# Save DTM
saveRDS(model, "squad_prediction_rf.rds")
码头工和管道工
Docker 是一个非常有用的工具,可以将我们的资产转化为容器化的应用程序。这将帮助我们在任何地方发布、构建和运行应用程序。
对于大多数软件服务来说,API 端点是消费预测模型的最佳方式。我们探索了像 OpenCPU 和 plumbr 这样的选项。Plumber 看起来更简单,但却非常强大,可以流畅地读取 CSV 文件和运行分析,因此它是我们的选择。
Plumber 的代码风格(即使用 decorators)也更加直观,这使得管理端点 URL、HTTP 头和响应有效负载变得更加容易。
docker 文件示例如下:
FROM trestletech/plumber# Install required packages
RUN apt-get install -y libxml2-dev# Install the randomForest package
RUN R -e ‘install.packages(c(“tm”,”text2vec”,
”plotly”,”randomForest”,”SnowballC”))’# Copy model and scoring script
RUN mkdir /model
WORKDIR /model# plumb and run server
EXPOSE 8000ENTRYPOINT [“R”, “-e”, \“pr <-
plumber::plumb(‘/model/squad_prediction_score.R’);
pr$run(host=’0.0.0.0', port=8000)”]
评分文件 squad_prediction_score 的一个片段。R 如下图:
x <- c(“tm”,”text2vec”,”plotly”,”randomForest”,”SnowballC”)
lapply(x, require, character.only = TRUE)# Load tf-idf
vectorizer = readRDS(“/model/vectorizer.rds”)dtmCorpus_training_data =
readRDS(“/model/dtmCorpus_training_data.rds”)tfidf = TfIdf$new()tfidf$fit_transform(dtmCorpus_training_data)# Load the model
squad_prediction_rf <- readRDS(“/model/squad_prediction_rf.rds”)#* @param df data frame of variables
#* @serializer unboxedJSON
#* @post /score
score <- function(req, df) {
curatedText <- preprocess(df$TITLE)
df$CURATED_TITLE <- curatedText$text
featureSet <- feature_extraction(df)
rfProbs <- predict(squad_prediction_rf, featureSet,type=”prob”)
probRanks <- ranks(rfProbs)
rfSquadsPreds <- as.data.frame(t(apply(probRanks, MARGIN=1,
FUN=function(x) names(head(sort(x, decreasing=F), 3))))) result <- list(“1” = rfSquadsPreds$V1,
“2” = rfSquadsPreds$V2,
“3” = rfSquadsPreds$V3)
result
}#* @param df data frame of variables
#* @post /train
train <- function(req, df) {
...
}preprocess <- function(text) {
...
}feature_extraction <- function(df) {
...
}
现在,要针对您自己的存储库运行该模型,您只需要构建您自己的 docker 映像并点击端点:
docker build -t squad_pred_image .
docker run — rm -p 8000:8000 squad_pred_image
一旦 docker 映像准备就绪,示例 API 调用将如下所示:
curl -X POST \
[http://localhost:8000/score](http://localhost:8000/score) \
-H ‘Content-Type: application/json’ \
-H ‘cache-control: no-cache’ \
-d ‘{
“df”: [{
“ID”: “4808”,
“TITLE”: “Data virtualization keeps running out of
memory”,
“TYPE”: “type: Defect”
}]
}’
API 调用输出示例如下:
{
“1”: “squad.core”,
“2”: “squad.performance”,
“3”: “squad.dv”
}
自己试试
您是否希望使用 GitHub 帮助您的开发组织提高工作效率?用你自己的数据集试试我们的代码。让我们知道你的结果。
关于作者
scar D. Lara Yejas 是高级数据科学家,也是 IBM 机器学习中心的创始人之一。他与世界上一些最大的企业密切合作,将 ML 应用于他们的特定用例,包括医疗保健、金融、制造、政府和零售。他还为 IBM 大数据产品组合做出了贡献,特别是在大规模机器学习领域,是 Apache Spark 和 Apache SystemML 的贡献者。
scar 拥有南佛罗里达大学的计算机科学和工程博士学位。他是《人类活动识别:使用可穿戴传感器和智能手机》一书的作者,并发表了大量关于大数据、机器学习、以人为中心的传感和组合优化的研究/技术论文。
Ankit Jha 是一名从事 IBM Cloud Private For Data platform 的数据科学家。他也是平台的可维护性团队的一员,使用 ML 技术进行日志收集和分析。Ankit 是一位经验丰富的软件专业人士,他还拥有辛辛那提大学的分析硕士学位。
使用 GitHub API 的 GitHub 用户洞察—数据收集和分析
探索 GitHub API
Photo by Yancy Min on Unsplash
当我使用 GitHub 页面时,我决定在上面放一些关于我的 GitHub 项目的统计数据。因此,我决定使用 GitHub 自己的 API 来获得洞察力。因为这对其他人可能也有用,所以我决定将它作为一个项目创建并发布在 GitHub 上。查看下面的存储库:
https://github.com/kb22/GitHub-User-Insights-using-API
这个项目有两个部分:
- 数据收集——我使用 GitHub 的 API,使用我的凭证获取我的存储库和一些关于它们的关键信息。
- 数据分析——利用上面收集的数据,我从数据中得出一些见解。
您也可以将该项目用于您自己的数据收集。
将您的凭证添加到文件credentials.json
中。如果您的用户名是userABC
,密码是passXYZ
,那么 json 文件应该是这样的:
{
"username": "userABC",
"password": "passXYZ"
}
一旦对 json 文件进行了更改,保存该文件。然后,只需运行文件get_github_data.py
从您的个人资料中获取数据,并将其保存到文件repos_info.csv
和commits_info.csv
。使用以下命令运行 Python 文件:
python get_github_data.py
数据收集
导入库和凭据
我首先将我的凭证保存在credentials.json
文件中。
在读取凭证文件后,我使用用户名和密码创建了用于 GitHub API 认证的authentication
变量。在访问我们自己的帐户时进行身份验证允许我们每小时打 5000 个电话。
用户信息
我将使用https://api.github.com/users/<USERNAME>
API 为我的帐户获取数据。
回应中有几个关键。从 json 中,我将提取用户信息,如name
、location
、email
、bio
、public_repos
和public gists
。我还会将一些 URL 放在手边,包括repos_url
、gists_url
和blog
。
在撰写本文时,我有 36 个公共存储库和 208 个公共 gists。
仓库
我现在将使用repos_url
来获取所有的存储库。然而,该 url 将每批的最大存储库数量限制在 30 个。因此,我必须处理它。
我调用端点,如果返回的存储库数量是 30,这意味着可能有更多的存储库,我应该检查下一页。我在 API 中添加了一个名为page
的参数,其值设置为 2,3,4…基于我所指的页面。如果返回的存储库小于 30,这意味着没有更多的存储库,我结束循环。
因为我有 36 个存储库,所以我能够在两个 API 调用中获取它们并将结果保存在repos_data
中。
为了获得更多的信息,我不得不看一下回复。所以,我检查了第一个存储库信息。
正如我们所看到的,每个存储库都有很多信息。
我决定为每个存储库选择以下内容:
1。id:存储库的唯一 id。
2。名称:存储库的名称。
3。描述:存储库的描述。
4。created_at:首次创建存储库的时间和日期。
5。updated_at:上次更新存储库的时间和日期。
6。登录:存储库所有者的用户名。
7。许可证:许可证类型(如果有)。
8。has_wiki:一个布尔值,表示存储库是否有 wiki 文档。
9。forks_count:存储库的总分叉数。
10。open_issues_count:存储库中打开的问题总数。
11。stargazers_count:储存库中的恒星总数。
12。watchers_count:监视存储库的用户总数。
13。url:存储库的 url。
14。commits_url:存储库中所有提交的 url。15。languages_url:存储库中所有语言的 url。
对于提交 url,我删除了大括号内的结束值(包括大括号)。我自己从存储库 url 创建了 languages_url。
数据框架repos_df
现在有了我需要的所有存储库信息。然而,我想更进一步,决定提取这里的所有语言,并将其附加到 dataframe 中。
每个存储库的语言可以有多个值,所以我决定以逗号分隔列表的形式组合所有语言。
完成后,我将数据帧保存到一个文件repos_info.csv
。
承诺
我还可以访问每个存储库的提交 url。我决定可以收集每个存储库的提交,并将它们保存到自己的文件中。
就像 repositories API 一样,commits API 也被限制为一次调用只能提交 30 次。因此,使用与使用page
参数相同的技术,我检索了所有提交。我看了一下 json 的回复。
对于每次提交,我保存了 git 提交所属的存储库 Id、提交的 sha 值、提交的日期和提交的消息。
我将 dataframe 数据保存到文件commits_info.csv
。
数据分析
既然有了完整的数据,我决定从这些数据中得出一些见解。
基本分析
我注意到我有 36 个存储库和 408 个提交(T2)。然后我决定用describe()
的方法来看一看分叉、观察者、问题和星星。我注意到以下几点:
- 我的最大分叉数是 67,最小分叉数是 0。
- 观察者的数量和星星的数量是成正比的。
- 我没有在任何存储库中报告过问题。
我还观察到我用过的两个最常见的提交消息是 Update README.md 和 Initial commit。看来有时我确实倾向于在 GitHub 上更新自述文件,并使用它的默认消息作为提交消息。
每个存储库的提交
接下来,我想看看提交是如何在我的各种存储库中分配的。我根据存储库 id 组合了两个数据集(repos 和 commits ),并创建了一个图。
Commits per repository
从上面的图中,我们可以清楚地看到我在 IEEE MyEvent App 中获得了最大提交量,这是一个用于事件管理的 Android 应用。第二个最受关注的存储库是与 IBM 的应用数据科学顶点课程相关的存储库,名为 Coursera_Capstone。
年度分析
从开始做项目,推到 GitHub,已经很久了。我在 2018 年和 2019 年工作得最多,希望在年度分析中看到同样的情况。
Commits in each year
尽管现在才六月,我已经完成了今年最大的承诺。第二名是 2016 年。当时我正在攻读计算机科学学士学位,我已经开始从事自己的项目,因此提交的数量很高。我预计在 2018 年的年会有更多的提交,但是我开始的比较晚,所以可能提交的总数会比较少**。**
现在让我们来分解一下 2019 年,看看我在那里是如何进步的。
2019 年月度分析
我把一年分成几个月,并把数据可视化在柱状图上。
Commits in each month of 2019
似乎我在三月达到了最大提交量。六月还有 6 天,但它已经占据了第二的位置。T21 最少的犯罪发生在一月份。
让我们进一步分解 2019 年 3 月。
2019 年 3 月每日分析
让我们看看三月份的提交历史。
Commits in March, 2019
我在 2019 年 3 月 2 日进行了最大次数的提交。
最流行的语言
随着我对数据科学兴趣的增长,我使用 Python 参与了许多项目。因此,Python 将是最占优势的语言。
Language distribution amongst all repositories
我使用过各种语言,包括 HTML、CSS、C++、Java 等等。不过最常见的还是 Jupyter 笔记本。我在 Jupyter 笔记本中的代码是用 Python 3 编写的,因此 Python 是我所有项目中最常用的语言。
结论
在本文中,我讨论了为我的个人资料收集 GitHub 数据的步骤,然后使用这些数据得出见解。
希望你喜欢这个。请分享你的想法、观点和建议。我很乐意收到你的来信。
误差在十亿年左右
根据来自星系物理学公共数据库 Leda 的数据,对宇宙的年龄进行 DIY 估计。
作为搭建交易平台、的一部分,我在自学数据科学。我的女儿劳拉正在做一个关于哈勃定律的项目,所以我们想利用这个机会出去玩玩。劳拉做了她的报告,我做了一个 Jupyter 笔记本 旁边生成了 图像 并练习了我公认的非常初级的数据科学技能。
你将从阅读中获得的是:
- 好的星系数据集
- 方程式使用
- 单位使用
- 代码用于生成结果和图像
我们从奥斯陆大学的天体物理学家彼得·劳尔森那里得到了很多帮助,并从 Reddit 帖子和 R 代码中获得了灵感。
请注意,这是实际可执行 Jupyter 笔记本的镜像,可用 这里用 。
下面我们将使用来自星系物理学数据库的数据,来验证哈勃定律:
换句话说,一个星系的距离和它相对于我们的速度之间存在线性关系——或者说它遵循正常线性方程的结构:
有了这些知识,我们可以计算出宇宙的年龄
获取数据
询问
以下查询被传递到达乐数据库接口:
***SELECT objname, v3k, mod0 WHERE (objtype='G') AND (v3k>3000) AND (v3k<30000) AND (mod0 IS NOT NULL) AND (v3k IS NOT NULL)***
我们正在剔除不是星系的物体,(objtype='G '),速度非常低(v3k > 3000)的物体,因为它们的局部速度和旋转扭曲了结果,速度非常高的物体(v3k < 30000) because the light we are getting from them only reflects their velocities in the early universe when the accelleration was significantly different.
***import pandas as pdimport numpy as np
from numpy import log10,sqrtimport matplotlib.pyplot as pltfrom astropy import units as u
from astropy.cosmology import Planck15
import astropy.constants as ccfrom scipy.optimize import curve_fit***
The results were saved in a text file called, 【 locally and then loaded into a pandas dataframe in Python.
***# Load Leda data
df = pd.read_csv('leda.txt')***
The first five lines look like this:
***df.head()***
Tidy the data
***# Remove empty column at the end
df = df.iloc[:,0:3]# Remove rows with missing values
df = df.dropna()# Remove whitespace from the headers
df = df.rename(columns=lambda x: x.strip())# Rename the objname column to galaxy
df = df.rename(columns={'objname':'galaxy'})# Display a sample of the dataframe
df.head()***
Luminosity Based Distance
Convert the magnitude ( 【 ) to 光度-距离秒差距:
***df['dl_mpc'] = 10**((df['mod0']+5)/5) / 1000000
df.head()***
物理距离
光度距离没有考虑光子从光源到我们身边时,速度差异和重力效应所造成的红移和时间膨胀。
为了得到合适的距离,我们首先需要红移因子, 𝑧 ,它是通过将速度除以光速(cc.c)得到的:
***df[‘z’] = df[‘v3k’] / cc.c***
然后我们用红移因子 1+ 𝑧 除光度距离 𝑑𝑙 :
***df['d_mpc'] = df['dl_mpc'] / (1+df['z'])***
导出整齐的数据集
***# Save to file
df.to_csv('galaxies.csv')***
最佳线性拟合
***def lin(x, a):
return a * xcoeff, cov= curve_fit(lin, df['d_mpc'], df['v3k'])# The slope of the best linear fit
a = coeff[0]
a***
结果:
***66.59753735677145***
宇宙的年龄
秒
***# Convert a from mpc based to km based
a_km = a / 1000000 / 30856775814913.67
age_sec = (1/a_km)
age_sec = age_sec
age_sec***
结果:
***4.6333208463264954e+17***
年
***# Age of the universe in years
age_year = age_sec / (60*60*24*365)
"{:,}".format(int(age_year))***
结果:
***'14,692,164,023'***
容忍
共方差
***cov[0][0]***
结果:
***0.20239139101111292***
𝑅^2
***# Residual sum of squares (ss_tot)
residuals = df['v3k'] - lin(df['d_mpc'], coeff)
ss_res = np.sum(residuals**2)# Total sum of squares (ss_tot)
ss_tot = np.sum((df['v3k']-np.mean(df['v3k']))**2)# R squared
r_squared = 1 - (ss_res / ss_tot)
r_squared***
结果:
***0.7590999713188041***
情节
***# Store the distance in mpc in an array
x = df['d_mpc'].values# Store the velocity in km/s in an array
y = df['v3k'].values # v3k# Least Square Best Fit line
f = lambda x: a * x# Initialize plot and subplot
fig2 = plt.figure(figsize=(25,20))
g2 = fig2.add_subplot(1, 1, 1)# Set background color to black
g2.set_facecolor((0, 0, 0))# Plot dataset
g2.scatter(df['d_mpc'], df['v3k'], c='yellow', s=5)# Plot best fit line
g2.plot(x,f(x), c="white", label="fit line", linewidth=0.2)# Add labels
g2.set_title('Speed / Distance')
g2.set_xlabel('Distance from Earth in mpc')
g2.set_ylabel('Speed relative to Earth in km/s')# Show plot
plt.show()***
结论
与科学界的共识相反,劳拉和我发现宇宙已经有 147 亿岁了。
相差十亿年😬
链接
- Leda——星系物理学数据库
- 维基百科上的宇宙年龄
- Reddit 帖子
- Python 代码的 Jupyter 笔记本
- 笔记本 PDF
- Gihub 知识库
给你的关键词搜索一些语义上的爱!
Image source: https://ebiquity.umbc.edu
起初,搜索引擎 (Google,Bing,Yahoo 等。)是*词汇:*搜索引擎寻找与查询词匹配的字面,而不理解查询的意思,只返回包含精确查询的链接。但是,随着机器学习和自然语言理解领域的新技术(NLU)的出现,很快就发现语义 搜索是前进的方向。
语义搜索是一种搜索技术,它不仅基于关键字返回结果,而且在获取相关结果时还会考虑上下文含义和用户的意图。
随着 2013 年蜂鸟更新,谷歌彻底改变了搜索引擎优化(SEO)流程。他们将重点从关键词搜索转移到理解上下文含义和用户意图的搜索,使用收集的搜索数据和 NLU 的概念,如词性标注、命名实体识别、单词嵌入等,扩展他们已经令人印象深刻的知识图。
虽然所有这些真的很令人兴奋,但我想写这篇博客的原因是为了展示两种简单的方法来为关键字搜索添加语义。我不会谈论知识图,仅仅是因为它是一个完全不同的概念,因此超出了本文的范围。
在这个练习中,我们将使用百万新闻标题数据集。标题已经被清理过了,所以除了将标题分成单词标记和删除停用词之外,不需要任何文本预处理。我已经创建了一个 50,000 个标题的小样本,我将它存储在 sample_data.parquet 中,我将使用它来节省计算时间,但是可以随意使用整个数据集。
样本数据集如下所示:
我想谈的两种方法是—
- 余弦相似性
- 平滑逆频率
余弦相似性
从数学上来说,余弦相似度是内积空间的两个非零向量之间相似度的度量,度量它们之间角度的余弦。0 的余弦为 1,对于区间(0,π] 弧度中的任意角度都小于 1。因此,这是对方向和而非大小的判断:具有相同方向的两个向量的余弦相似度为 1,相对于彼此成 90°方向的两个向量的相似度为 0,而完全相反的两个向量的相似度为-1,与它们的大小无关。
这种方法相当简单。我们将首先在数据集中创建每个标题的嵌入,然后,找到搜索标题和标题嵌入之间的余弦相似性,以找到相似的标题。对于预训练的单词嵌入模型,我们将使用fast text crawl-300d-2M-子单词,并使用我最近遇到的一个新模块 pymagnitude 加载它。如果你还没听说过可塑性的大小,我强烈推荐你在这里看看。它们提供了一个高度优化的库来读取和查询单词嵌入,即使模型非常大,并且它们支持几乎所有预训练的模型,包括 ELMo 。
现在我们已经加载了模型,是时候为数据集中的每个标题创建嵌入了。
text2vec 函数获取标题词标记,在预训练的模型中找到这些标记,并添加对找到的标记的嵌入。它还记录有多少单词被找到,然后被用于平均出最终的标题嵌入。我们做一个平均,因为标题和搜索标题将是可变长度的,这种方法在稍后阶段给出两者之间更好的成对比较。 get_docs_embedding 函数只返回所有标题嵌入的列表。
在我们开始看到结果之前,我们将添加一个名为 get_relevant_words 的函数。该功能将让我们提取在搜索的标题和匹配的标题之间匹配的语义相关的关键词。该函数从搜索的标题和我们正在查找相似性的标题中创建唯一的标记,并使用词对之间的余弦相似性来查找相关的词。
厉害!现在所有的部分都已经准备好了,让我们创建一个名为 semantic_search_cossim 的最终函数。这个函数将把搜索的标题、标题的嵌入、嵌入模型和返回的结果数作为输入,并返回一个带有结果的数据帧。我们开始吧。
以下是一些搜索及其结果:
如上所述,结果是很有希望的。这种方法通常被认为是一种基线方法,可以在此基础上进行改进以获得更好的结果。
平滑逆频率
如在第一种方法中所做的,取嵌入在句子中的单词的平均值,倾向于给予语义上完全不相关的单词太多的权重。平滑逆频试图用两种方式解决这个问题:
- 加权:像 TF-IDF 一样,SIF 对句子中嵌入的单词进行加权平均。每个单词嵌入都由
a/(a + p(w))
加权,其中a
是通常设置为0.001
的参数,p(w)
是该单词在参考语料库中的估计频率。 - 公共成分去除:接下来,SIF 为一组句子计算结果嵌入的主成分。然后,它从这些句子中减去嵌入在它们的第一主成分上的投影。这应该移除与语义上不太相关的频率和语法相关的变化。
我们来直观的看一下。根据a/(a + p(w)),
,出现频率高的单词的权重较低,因为p(w)
对于这些单词来说较大。我们通过移除我们生成的句子嵌入的第一主成分并从每个单独的句子嵌入中减去它来进一步增强句子嵌入。因此,由于 PCA 中的第一个成分是具有最大方差的成分,因此来自杂散字的大多数变化通过该操作被平滑。你可以从上面链接的文章中读到更多,但是现在,我们将使用 SIF 在我们的数据集上进行语义搜索。
我们将使用具有 SIF 优化实现的 fse 库。该库已经由 Oliver Brochers 开发,你可以在这里阅读它的实现。对他大吼一声!
注意: fse 与 gensim 库一起工作,因为两者使用相同的 cython 实现。同样,对于这种方法,我们不会删除停用词,因为 SIF 会自己处理常用词。对于文本处理,我们只是将标题分割成空间上的单词标记。
我用的是 glove.42B.300d ,可以从这里下载。
功能 glove_to_w2v 将手套模型转换成 gensim 模型,然后与 fse 兼容。这个函数只需要调用一次。函数 init_model 加载并返回新转换的模型。
一旦我们加载了模型,我们将所有的标题分割成空间上的单词标记,并调用 fse 的 IndexedList 函数。
IndexedList 函数给出了下面的输出——每个标题都被标记化,并分配了一个索引号。
(['drug', 'test', 'records', 'destroyed', 'landis'], 0)
(['grains', 'council', 'awaits', 'awb', 'restructure', 'details'], 1)
(['plan', 'to', 'move', 'year', '7', 'to', 'high', 'school'], 2)
(['teen', 'jailed', 'over', 'after', 'boy', 'brain', 'damaged'], 3)
(['awb', 'drops', 'plan', 'to', 'boost', 'directors', 'pay'], 4)
这样,我们就可以训练我们的 SIF 模型了。一旦完成训练,您可以使用 pickle 保存模型,然后只需加载 SIF 模型并进行搜索。在此之后,除非有新的数据集进入,否则不需要上面提到的任何步骤。
这里的最后一个函数是 semantic_search_sif ,它将搜索到的标题、sif 模型、数据、预训练的嵌入模型、索引标题作为输入,并返回一个数据帧作为输出。注意 SIF 模型的相似逐句功能。该函数的输出是一个包含元素的元组(<句子>、<句子的索引>、<相似度得分>)。例如
(['anchina', 'attack'], 41199, 0.7434917688369751)
这就是为什么我们考虑索引 1、2,因为它们分别代表标题的索引和相对于被搜索标题的相似性得分。
SIF 模型的结果如下:
结论
在这篇博客中,我们研究了什么是语义搜索,以及可以用来实现语义搜索的几种基本方法。现在,关键字搜索已经成为过去,每个搜索引擎都应该足够聪明,能够理解用户查询的上下文,并相应地返回结果。自然语言理解刚刚开始展示它的力量,不可思议的事情还在后头。
成为一名数据记者,给自己一个优势
Photo by Web Hosting on Unsplash
当你试图在网上搜索如何成为一名数据科学家时,会弹出许多项目,如数据科学、数据分析、商业分析等热门数据科学项目的名称。事实上,在线数据科学相关课程泛滥成灾。
然而,如果你已经在媒体行业工作,并希望进一步发展你的职业生涯,学习如何成为一名数据记者听起来更有吸引力。
为什么我决定成为一名数据记者
我在威斯康星大学麦迪逊分校主修传播艺术。但我想不通困扰大多数学生的问题:毕业后该做什么?
有这么多不同的机会可以考虑,我不知道该选择什么。
#1:在硅谷一家科技公司的工作经历
毕业后,我在硅谷做了一年的质量保证专家,以 NDA 的名义在库比蒂诺的一家财富 100 强公司进行桌面和移动应用软件测试。我通过定制的错误跟踪软件从用户体验中收集数据,以确保产品的质量,同时与其他测试人员、制作人员和开发人员合作。然而,我总是渴望得到一份与媒体相关的工作,尽管我热爱我的工作和我出色的同事。
#2:付不起我的房租
旧金山是众所周知的薪水最高的城市。
Image: Bloomberg, May 20, 2019
但是最高工资只针对 工程师 ,租金设置为 工程师工资。 而且说真的,比纽约市的房租还要贵。
Image: MarketWatch, May 22, 2016
我再也付不起在湾区的房租了(一间工作室每月大约 3500 美元)。当时我意识到,如果我想继续存钱,我必须找到一份与编码相关的工作。我还发现,与技术相关的工作增加了高薪留在美国的机会。
此外,我的公司教了我一些编程,他们建议我学习另一种编程语言,如 Python、Java 或 C 语言。我的同事已经工作了三年多,已经熟悉了至少一种编程语言。有时候在公司工作也要用终端,但当时听起来没什么意思。
#3:仍然想和媒体一起工作,但是作为一名“精通技术”的记者
这就是为什么我决定成为一名数据记者,用媒体的背景知识分析数据,根据分析的数据制作图表,通过媒体渠道展示见解。我认识到,美国许多与技术相关的工作仍然需要更多的人,媒体行业也需要更多的人。所以,我决定学习数据分析/数据科学和可视化。
我从专家那里学到了什么,我现在学到了什么?
我在 LinkedIn 上搜索了数据科学家的简介,以检查我必须学习哪些技能。我给著名的数据科学家发了消息和问题,他们中的一些人回答了问题。此外,我还可以从媒体中获得关于数据科学领域的非常有用的信息,我最喜欢的是 Adam Thomas 关于数据新闻的文章。他在文章中介绍了这样一个伟大的环节’datajournalism.com’。
人们还分享了他们获得数据科学家工作的经验或技巧。从他们的文章中,我意识到我的期望(DS =世界上最性感的工作)和现实(我要学的真正的东西比如 Python,SQL,机器学习等等)不匹配。这就是为什么我经常阅读这个领域的书籍。我全心全意地推荐彭凯莉的文章,它帮助我建立了一个强大的心态,因为这真的很重要。
现在我知道我至少要学习 Python、R、SQL 等一门编程语言,甚至线性代数等数学。为了可视化,我必须学习 Tableau、熊猫或 MATLAB/Seaborn。事实上,我目前正在学习和使用 Python,MySQL,Tableau,Pandas 和 MATLAB。是的,这真的很难。但是每个人都知道入门——学习软件的用户界面——是最难的部分。现在,我越来越熟悉使用这些技能,而且变得越来越有趣。
对于想在数据相关领域开始职业生涯的新手,我希望这篇文章有助于你了解这个领域。我会继续写我的经验、项目和关于数据科学的想法。
在 Expedia 面试了 60 名候选人后,给出了一些数据科学面试的技巧
Courtesy of www.superdatascience.com
在过去的一年里,我面试了很多人申请 Expedia 集团的数据科学职位,从初级到高级,有些是硕士/博士研究生,有些来自其他公司(如微软、亚马逊、Spotify、Twitter),我想在这里分享我的经验,以便对申请数据科学职位的人有用,并就可能遇到的问题给你们一些提示。
面试候选人帮助我认识了具有广泛背景和技能的人,从 CS/ECE、统计/数学到土木/机械工程,我有机会与几位杰出的人交谈。
在我进入更多细节之前,我想提一下,近年来“数据科学家”有了更好的名字,如“机器学习科学家”和“应用科学家”。虽然在一些公司,这些职位所指的任务/技能略有不同,但对大多数公司来说,这三个头衔或多或少指的是同一件事。所以在这篇文章中,我所说的“数据科学”指的是上面所有的标题。
虽然每个人都有他/她自己独特的一套技能,可用于解决一些问题,但大多数公司都希望数据科学候选人具备一套基本技能,我将把这些技能分为以下几类,然后详细讨论。根据公司和职位级别的不同,您可能会从以下一个或多个项目中得到问题,因此您可能希望提高您在这些方面的背景知识:
- 关于你的简历和以前作品的问题
- 通用机器学习(和深度学习)知识
- 普通统计和数学知识
- 编程和软件工程技能
- 统计建模技巧
- 计算机视觉、自然语言处理和定价主题
- 沟通和表达技巧
- 行为问题
- 系统设计技巧(视职位级别而定)
- 管理和领导技能(取决于职位级别)
1。关于你的简历和以前作品的问题
你的简历在面试中会被问到的问题中起着至关重要的作用。所以,确保你对简历中提到的任何东西都足够熟悉,从课程和研究项目到编程语言。像“告诉我更多关于你自己和你的背景”,或者“告诉我你在你现在的公司的工作”这样的一般性问题很常见,但是你也会得到关于你简历的更详细的问题。
例如,如果你在简历中提到几个以前与 NLP 相关的项目,你应该对 NLP 主题有很好的理解,并且很有可能会得到一些关于 NLP 的技术问题,以评估你在这方面的技术深度。因此,如果你在一个项目上做了一些合作,但对工作贡献很小,我建议你让自己更熟悉那个项目的技术方面。
或者,如果你提到 Python 或 Scala 是你最喜欢的编程语言,请确保你了解这些语言的细节(至少了解数据科学职位所需的程度),以及每种语言中的一些机器学习相关的库。我看到许多候选人在简历中提到 Scala/Python,但是当我问他们一个关于这些语言的简单问题时,他们对此一无所知,这将给我一个负面的信号。如果你对这些语言的经验非常有限,最好诚实地告诉面试官这一点,我相信大多数面试官不会因为你没有足够经验的事情来评判你。
2。通用机器学习(和深度学习)知识
虽然不同公司的数据科学工作可能涉及广泛的问题和技能(包括数据提取和预处理,运行 SQL 查询,简单的数据分析,到深度学习,NLP 和计算机视觉),机器学习是一个基本概念,是当今大多数顶级公司对“数据科学候选人”的期望。因此,如果你申请的是数据科学职位,请确保你对以下机器学习概念有很好的理解。像“统计学习的要素”[1]和“模式识别和机器学习”[2]这样的书对这些主题很有用。
- 监督和非监督算法
- 经典分类算法,如 SVM、逻辑回归、决策树、随机森林、XGboost
- 经典回归算法:线性回归、LASSO、随机森林、前馈神经网络、XGboost
- 聚类算法,如 K 均值和谱聚类
- 降维技术,如 PCA、LDA 和自动编码器。
- 偏差-方差权衡
- 过拟合以及如何避免过拟合(例如正则化、特征选择、丢失(对于神经网络))
- 著名的深度学习模型,如卷积神经网络(CNN)、递归神经网络(RNN)和 LSTMs、自动编码器、残差架构、序列到序列模型、GANs
- 评估指标,如分类准确度、精确度、召回率、F1 值、均方误差、平均绝对偏差
- 流行的损失函数,如交叉熵、MSE、三重损失、对抗性损失、利润最大化损失等
- 反向传播
- 也许还有强化学习和深度 Q 学习(更多研究型岗位)
- 线下和线上(A/B)指标对比?
上面列出的项目涵盖了一些与数据科学职位相关的高级机器学习概念,但您也可能会被问及一些关于上述主题的更详细的问题,例如,您可能会被问到:
- SVM 和逻辑回归分类的比较
- 生成模型和判别模型之间的差异
- 消失渐变问题背后的根本原因以及避免该问题的一些常见做法
- 批量梯度下降时使用动量的优势
3。普通统计和数学知识
今天的许多数据科学家曾经是统计学家和分析人员,许多 ML 模型只是(重新标记的)统计学习模型(如线性回归、岭回归、LASSO、logistic 回归)。所以毫不奇怪,许多面试官喜欢问一些关于统计或数学的问题。
对于统计和概率,如果你熟悉以下概念会更好:
- 模型的偏差和方差以及如何计算
- 从分布中抽样
- 置信分数和给定置信分数所需的样本数量
- 均值、方差、相关性(统计意义上和经验意义上)
- 随机过程,随机漫步(金融公司数据科学职位)
- 如何求某事件的概率
- P 值
- R 平方(决定系数)解释
对于数学问题,您可能会被问到以下主题的问题:
- 一些需要思考的脑筋急转弯问题
- 如何计算特定损失函数的梯度
- 关于损失函数或优化算法的一些详细问题
4。编程和软件工程技能
任何数据科学家都需要进行某种程度的编程。在初创公司(员工人数较少),数据科学家可能需要自己做大量的软件工程工作,例如数据提取和清理,以及模型部署。相比之下,在较大的公司中,有其他人负责数据工程和模型部署,数据科学家主要处理特定产品的培训和测试模型。作为一名数据科学家,你还需要了解数据工程角色所需的一些术语和任务,比如 ETL(提取、转换、加载)。在这里,我将介绍数据科学家使用的一些最广泛的编程语言、库和软件。
像 Gayle Laakmann McDowell [3]写的《破解编码面试》这样的书对准备软件工程和算法问题非常有帮助。也有一些很棒网站,它们有很好的软件工程问题数据库,比如 leetcode、hackerrank 和 geeksforgeeks。
4.1 编程语言
在编程语言方面、 Python、、 SQL 、 R 似乎是人们使用最多的语言,但我也见过有人使用其他语言如 Java、【c++】、 Matlab (虽然不是编程语言)。
4.2 有用的 Python 库
在这里,我将提到一些与数据科学职位最相关的 Python 包:
- 对于机器学习和数值计算, Scikit-learn、XGboost、LIB-SVM、Numpy、Scipy 是应用最广泛的软件包。
- 深度学习方面, Tensorflow,PyTorch,Keras 应用广泛。
- 对于数据可视化来说, Matplotlib、Seaborn、ggplot 是最受欢迎的(尽管还有很多其他有用的包)。
- 对于计算机视觉来说, OpenCV 和 PIL 都很有用。
- 对于 NLP 来说, NLTK、GENSIM、Spacy、Torchtext 等包都很棒。
- 对于处理数据库, Pandas,PySpark 是 Python 中两个比较流行的库,我个人觉得很有用。
4.3 云服务
根据您要处理的数据规模,您可能需要在云服务上运行代码,如 AWS、Azure 或 Google Cloud。因此,有一些在云中运行代码的经验可能是一个额外的收获。您肯定不需要了解所有不同的云服务,但是对 AWS 中的 EC2 之类的计算服务有所了解会更好。
一些公司也可能在 AWS 或 Azure 的基础上使用其他大数据服务,如 Databricks 和 Qubole,但我不认为需要有使用它们的经验,因为这些非常容易学习。
4.4 部署工具
在您为一个任务训练了您的模型(例如一个推荐系统,或者一个审核模型)之后,理论上您希望在生产中使用它。因此,有人(可能是您,或者您正在工作的工程团队)需要将您的模型部署到生产环境中。为此,熟悉 Python 中的 Docker 和 Flask 可能会有所帮助。如果您想在 AWS 等云服务上部署您的模型,熟悉 Sagemaker 可能会有所帮助。我个人并不认为熟悉部署工具是入门级数据科学职位的必要条件。
5。统计建模技巧
作为一名数据科学家,你需要为各种产品/问题建立数学和 ML 模型,因此你可能会在面试中遇到一些建模问题。这些问题通常与公司的领域有关。目标是看你是否能把概念上的知识应用到一个具体的问题上。您可能会遇到的一些示例问题包括:
- 你会如何建立一个机器学习模型来检测我们网站上的欺诈交易?
- 你会如何建立一个机器学习模型来向我们的客户推荐个性化的商品?
- 你将如何构建一个模型来检测我们网站上的虚假产品评论?
- 如何使用 ML 模型检测有害评论/推文?
- 你会如何建立一个模型来预测我们产品的价格?
- 你会如何建立一个模型来自动标记社交网络中用户上传的图片?
- 运行 A/B 测试时的在线指标?
根据您的回答,您还可能会得到一些后续问题,如您需要的数据类型、您将如何评估您的模型,或者如何随着时间的推移改进您的模型。如果你想了解更多的问题,像 https://medium.com/acing-ai/acing-ai-interviews/这样的网站很有用。
这里重要的是你的思维过程和你看到为一个产品建立一个 ML 模型的不同方面的能力。你绝对不需要给出最好或最花哨的答案;只要你对问题的高层次理解是合理的,你就是好的。
6.关于计算机视觉、NLP 和定价主题的问题
根据你所申请的团队的产品重点,你也可能会得到一些关于计算机视觉、NLP 或定价的问题。所以在面试之前,一定要对你申请的团队做一些研究,更好地了解他们的关注点。一些面试官可能会问你非常高级的 NLP 或视觉概念,而其他一些面试官可能会问更具挑战性的问题。
以下是一些你可能会遇到的与 NLP 相关的问题:
- 什么是词干化和词汇化?
- 什么是包话?TF-IDF 怎么样?
- 你如何发现两个单词之间的距离?有哪些著名的字符串距离度量?
- 什么是命名实体识别,您如何评价 NER 系统的性能?
- 如何训练 CRF 模型进行词性标注?
- 什么是公报功能,它们何时有用?
- 你会如何构建一个神经机器翻译模型?你如何评价它的性能?
- word 2 vec 相比经典的一键编码有哪些优势?
- 你会如何建立一个问答系统?
- 你如何在一组文档中发现潜在的主题?
- 你如何看待顾客评论的情绪(极性)?
- 关于正则表达式的一些问题
这里有几个你可能会遇到的计算机视觉问题:
- 你如何将网站上的图片分成不同的类别(如电子产品、服装等)。)?
- 如何构建一个模型来自动标记图像中的不同人脸?
- 如何检测图像/视频的质量并过滤掉模糊的部分?
- 什么是超分辨率,您如何评价超分辨率模型的性能?
- 如何检测图像中的不同物体?
- 您如何检测图像中的文本区域?
- 你会如何创建一个自动图像标记系统?
以下是您可能会遇到的一些与定价相关的问题:
- 如何将用户分为活跃组和非活跃组?
- 如何设计亚马逊商品的折扣算法?
- 在有限的营销预算下,你如何设计一个竞价系统?
- 你如何为优步开发一个动态定价算法,以确保乘客总能收到快速方便的提货服务?
- 如何设计个性化的定价算法(虽然有些国家可能不允许)?
- 假设您为亚马逊商品开发了一个新的定价服务。在 A/B 测试中,要跟踪的最佳指标是什么?
- 假设你可以在你的平台/网站上展示一些广告。你如何开发一个广告评分或广告排名服务,使用户点击最大化?如果想收益最大化呢?
- 你如何决定在你的网站上向用户显示广告的最佳数量?
- 你如何估计客户的终身价值?
7 .。沟通和表达技巧
数据科学职位通常涉及大量的沟通和演示。这可能是为了与产品经理讨论一个新项目,或者向你的团队展示你的模型。因此,能够与其他人(包括技术人员和非技术人员)交流你的工作和想法是非常重要的。
有时你可能需要以非常专业的方式向你的同事或经理传达你的发现,而有时你可能需要说服产品经理你的模型对他们有用,而不需要太多的专业知识。
面试官通常不需要问你一个具体的问题来评估你的沟通和表达能力,他们可以在面试过程中很好地了解这些技能。我的建议是:
- 试着首先给面试官一个你的解决方案的高层次描述,然后进入细节。通过这样做,你可以得到一个反馈,如果你的高层次方法是正确的。
- 你可以明确地问面试官你的答案是否是他们想要的。如果结果不是他们感兴趣的,他们可以为你澄清问题,并给你一些建议。
- 尝试将一个建模问题分解成几个部分,然后分别关注每个部分。对于许多 ML 建模问题,您可以将它们分解为相关的数据提取、数据清理、特征提取、预测建模、评估和可能的改进。
8.行为问题
有些人可能还会在面试时问一些行为方面的问题。这些问题可以从你过去的工作经历(为了了解你是否具备工作所需的技能)到你的个人兴趣。这些问题也可以关注你过去是如何处理各种工作情况的。你对这些问题的回答可以揭示你的技能、能力和个性。下面是一些可能会问你的问题:
- 你更喜欢哪种职位,是涉及研究和 R&D 开发的职位,还是更喜欢将现有模型应用于公司内部数据并围绕它构建数据驱动的解决方案的职位?
- 你喜欢单独工作,还是与一群人合作解决同一个问题?
- 举一个你实现的目标的例子,告诉我你是如何实现的,你面临的挑战是什么?
- 举例说明一个你没有达到的目标,以及你是如何处理的?
- 告诉我,如果你需要交付一个模型来满足产品的最后期限,你会如何在压力下工作?
9。系统设计技能(取决于职位级别)
根据你所申请职位的级别,你还可能会得到一些系统设计面试(SDI)的问题,这些问题大多是关于“设计大型分布式系统”的问题。
由于缺乏开发大规模系统的足够经验,以及没有标准答案的设计问题的开放性,这些问题可能具有挑战性。
我不会在这里谈论太多关于 SDI 的问题,因为这不是这篇文章的重点,但是我会提供一些示例问题,以及一些有用的资源,如果你想在这方面得到更多的实践。
以下是一些系统设计问题示例:
- 你会如何设计像 Youtube 或网飞这样的视频流媒体服务?
- 你会如何设计 Facebook Messenger 或 WhatsApp?
- 你会如何为客户服务设计聊天机器人?
- 设计 Quara 还是 Reddit?
- 设计 Snapchat 这样的 app?
- 你会如何设计像 Dropbox 或 Google Drive 或 Google Photos 这样的全球存储和共享服务?
- 你会如何设计像 Twitter 或脸书这样的服务?
- 你会如何为谷歌或 Expedia 设计一个预输入系统?
以下是面试设计问题的一些有用资源:
- https://github.com/checkcheckzz/system-design-interview
- http://blog . gain lo . co/index . PHP/category/system-design-interview-questions/
- https://hacker noon . com/top-10-system-design-interview-questions-for-software-engineers-8561290 f 0444
10。管理和领导技能(取决于职位级别)
如果你申请数据科学经理职位(有时甚至是高级或主要职位),面试官将需要评估你的管理和领导技能,并了解你以前的管理经验。
这位候选人的理想背景是在机器学习和预测建模等领域拥有强大的理论背景,以及良好的软件工程技能。要成为一个有效的领导者,候选人还需要有很好的沟通技巧,以及良好的规划技巧,能够以一种考虑到构建数据驱动产品所带来的许多风险的方式进行优先排序和规划。
我不打算深入探讨管理技能,但我会在这里提供一些示例问题:
- 你管理过的最大的团队是什么,你面临的挑战是什么?
- 假设你的团队已经建立了一个在测试集上达到 90%准确率的模型。为了决定模型性能是否可靠,需要知道什么?
- 讨论一个可以影响我们公司的数据驱动型产品
- 当你想为你的团队雇人时,你会考虑什么?
- 你会如何吸引顶尖人才加入你的团队?
- 你认为一名数据科学家必备的技能是什么?
- 什么是大数据,您熟悉大数据架构吗?
- 你如何在工作中保持最新状态?
- 你如何判断与另一个团队的合作是否成功?
在这篇文章中,我试图提供一些提示,以及一些你在 DS 面试中可能会遇到的高层次问题。鉴于数据科学角色的范围不断扩大,当然有一些主题和问题没有在这里讨论。但是我试图涵盖一些对于数据科学面试来说很重要的一般性话题。
我最后的建议是对你申请的团队/公司做更多的研究,更好地了解他们正在解决的问题。然后,您可以将主要精力放在准备与该团队相关的主题上。
参考
[1]https://web.stanford.edu/~hastie/ElemStatLearn/
http://www.crackingthecodinginterview.com/
滑向基于模型
逻辑直观的解释
由于术语和复杂的数学公式,强化学习(RL)对于该领域的新手来说可能是一个令人畏惧的领域。然而,其背后的原理比最初想象的更直观。让我们想象 RL 是一个新的尚未发行的塞尔达游戏,发生在遥远的未来,2119 年。
林克在 2119 年的任务是从里顿豪斯那里拯救人类,这是一个位于 2019 年的秘密机构,拥有强大的人工智能和时间机器。因为里顿豪斯是邪恶的,他们设计了一个在 2119 年毁灭人类的计划,并及时派遣他们的特工去完成任务。
游戏开始时,林克降落在一个荒凉的小岛上,他必须在那里找到人类文明的第一个迹象,并警告他们里顿豪斯的特工即将到来。当他降落在一座塔的顶部时,一位年长的智者出现并送给他一个滑翔伞作为礼物。林克现在的任务是滑翔伞,并找到一个人类文明的城镇,以警告他们里顿豪斯。
林克是一个电脑外星人,可以在他的大脑中安装任何软件。他不知道如何玩滑翔伞。在 Ritten-House 的代理到达那里之前,你的目标是编写一个程序来教 Link 滑翔伞和所有的技巧,他尽可能快地到达人类文明,并尽可能避免 Ritten-House。你的计划是在里顿豪斯的特工来阻止他之前把这个模拟发送给林克,这样他就会知道如何保护自己。
你的计划是在未来通过光波向你发送这个程序。
为了设计这个程序,你需要知道一种叫做强化学习的东西。在强化学习中,有一个代理正在与环境交互。
我们基于称为马尔可夫决策过程 (MDP)的数学框架,对代理与环境的交互进行建模。每个代理从状态“X”开始,在每个时间步采取一个动作“A”,得到奖励“R”,并进入下一个状态“Xt+1”,重复这个循环,直到代理达到目标状态“X`”。
现在,在你正在制作的模拟中,Link 作为滑翔伞是一个在天空中处于初始状态 X 的代理。在每个时间步,Link 从一组可能的动作中采取一个动作。在这里,向左或向右操纵他的风筝被认为是他可能的行动,他去了天空中一个新的状态或新的地方。他的目标是降落在目标州 x `,这是未来的几个州,在那里他可以找到人类文明。
在每一个时间步,基于他采取的每一个动作,他将在空间中处于不同的位置。例如,如果他把他的风筝转向右边,他会在一个不同的地方,当他把他的风筝转向左边。
然而,并非所有这些可能的行动都是同样有利的。他的目标是找到一系列最佳行动来实现他的目标。
这意味着你想让林克选择一条最有效的路线去接近人类。为了做到这一点,我们最好使用基于模型的方法。在基于模型的方法中,为了采取最优的行动,Link 还需要预测理想的未来状态,因此可以选择到达那里的最佳路线。
当 Link 在滑翔伞飞行时,他想知道他应该如何操纵他的风筝以便不坠落(即,找到最佳动作)。但是,他也想避开敌人并降落在最佳位置,如城镇所在的位置(即,预测下一个最佳状态)。
对未来状态的预测以及在哪里着陆才是正确的,这反过来会影响林克在当前时刻如何操纵他的风筝。你想根据他对未来状态的预测找到最佳行动。
林克可以预测敌人会在某个地点,为了避开敌人,他应该把风筝转向其他方向。
对未来状态的预测解释了环境是如何变化的。环境相对于当前状态和动作的这种变化被描述为一个函数,我们将这个函数称为模型。
你的目标是教林克学习这个模型。
模型的输入是当前状态 x 和动作 u 、,目标是预测未来状态 x t+1 。我们可以这样写:x t+1 =f(xt,ut)
我们称选择行动顺序直到剧集结束的过程为策略。直觉上,政策意味着林克如何在每一个时间点选择最佳方式来驾驶他的风筝,直到他最终到达城镇拯救人类。我们可以用下面的符号来描述策略:ut= лθ(xt)。这意味着在每个状态 xt,策略лθ告诉 Link 最佳动作 ut 是什么。
成本或奖励函数
我们使用成本函数或回报函数来寻找最优策略,或者换句话说,轨迹上的最优行动。根据不同的设置,我们使用成本或回报函数。
请注意,奖励只是成本函数的负值。我们试图最小化成本或最大化回报。在这个设置中,我们使用一个成本函数 c(xt,ut)。
寻找最佳行动与预测未来状态有什么关系?换句话说,最优策略与模型有什么关系?
在回答这个问题之前,我想让你想象一个世界,在这个世界里,这些功能中只有一个起作用。
你认为会发生什么?
第一种情况,模型能够预测下一个状态,但不能采取好的行动。
这里绿色是最佳的未来状态,模型有绿色和红色的预测。
这意味着,即使林克能够预测未来状态,他知道敌人在哪里,但他不能根据他对未来状态的了解采取好的行动。他不知道如何驾驶他的滑翔伞,并且向里顿豪斯坠落或消失,因为他不知道如何驾驶他的风筝。
现在,想象相反的场景,林克能够采取好的行动,并且是滑翔伞专家,但是他不能预测他的行动将带他去哪里。他知道如何驾驶他的风筝,但是他不知道去哪里。这也可能让他陷入困境。
这意味着他对未来没有任何预测。他可能会花很多时间根据他当前的情况和需要采取行动,而不是根据对未来状态的预测,也可能会随机搜索整个区域,直到他找到有人居住的城镇。这类似于许多无模型环境。预测使林克成为一个聪明的人,他能预测自己行为的后果,并根据这些预测做出决定。这也是理性的人类会做的。
再次以滑翔伞为例,林克能够在给定的时刻控制他的风筝不落下,但是他不记得敌人在哪里,结果,他不断地遇到他们,结果,他不清楚环境如何变化,他不能确切地知道哪个方向会把他带到城镇。
林克不仅需要知道如何驾驶他的风筝,还需要预测他应该去哪里,并根据他的预测驾驶他的风筝。现在,你可能对这两个函数为什么相关有了更好的直觉。
让我们从数学角度更详细地阐述这一点。
这是总损失的计算公式,我们正努力使其最小化。注意,这个损失由两个函数组成。
1.代价函数:c(xt,ut)。
2.,我们的模型~转移函数:f(xt-1,ut-1)
代替 c(xt,ut)中的 xt,我们可以把 x 写成它之前状态和它动作的转移函数。c(f(xt-1,ut-1),ut)。我们可以将上述公式改写如下:
因为我们有一系列的步骤,所以我们试图将每一步的成本降到最低。因此,总损失是每个时间步的成本总和。
这直观地意味着,林克想要在任何时刻采取好的行动,而且是针对整个领域,直到他接触到人类。
该模型的承诺基于我们如何基于转移函数 f(xt,ut)找到预测未来状态 x t+1 的最优策略лθ之间的关系。
因此,现在我们要优化整个序列的总损失函数,包括两个函数:每个时间步的成本函数和转移函数。我们希望找到一种优化技术,使这两个函数的损失最小化。我们可以使用线性或非线性优化。我们可以使用神经网络来最小化总成本函数。
如果我们的环境是可区分的,我们可以通过反向传播进行优化。为了计算总损失,我们需要下列导数:
这部分就是我们所说的模型。我们想了解关于状态和动作的模型:
这部分是我们的成本。我们想了解状态和行为的成本:
世界模型
到目前为止,您已经了解了基于模型的方法,我们可以使用基于模型的方法之一——世界模型——作为 Link 模拟软件背后的核心机制。
这里,MD-RNN 类似于用于预测未来状态的转移函数 x t+1 =f(xt,ut)。然而,它只是与我们所学的略有不同。MD-RNN 增加了自己的隐藏状态来预测未来状态和 ht+1。
你可能还记得,之前我们讨论过根据设置,我们使用成本或回报函数。世界模型使用奖励而不是成本函数。这里,控制器网络充当奖励函数,其目标是找到在整个推广过程中最大化累积奖励的策略。控制器的输入是 zt 和 ht,输出是 at 的最优动作。ht 是控制器网络用来预测最佳动作的附加变量。我鼓励你自己阅读《世界模型》。
谢谢你救了林克·❤
Apache Spark 3.0 一瞥[早期访问]
图沙尔·卡普尔😦【https://www.tusharck.com/】T2
Apache 继续保持强势地位,展示了其针对大数据科学的 Spark 3.0 预览版。根据预告, Spark 即将推出几大重要功能。
你可以从这个链接下载预览版:https://archive.apache.org/dist/spark/spark-3.0.0-preview/
让我们看看它的一些主要功能,这些功能为其大数据统一分析的目标注入了活力。
**火花图:**密码脚本&属性图
Spark 3.0 中加入了流行的图查询语言 Cypher,它通过属性图模型 a directed multigraph 进行耦合。图形查询将遵循与 SparkSQL 相似的原则,它自己的催化剂为数据帧提供完全支持。
点击查看 Databricks 在 Spark 3.0 图形 API 上的会话。
Python 3,Scala 2.12 和 JDK 11
- Spark 3.0 有望完全迁移到 Python3。
- Scala 版本升级到 2.12。
- 它将全力支持 JDK 11 号。
深度学习:增加 GPU 支持
这是每个数据工程师和科学家都在寻找的东西,而 Spark 3.0 符合他们的期望。带 NVIDIA 的 Spark 3.0 提供 GPU 加速,可以跨多个 GPU 运行。它支持 AMD、Intel 和 Nvidia 等异构 GPU。对于 Kubernetes,它提供了执行程序 pod 级别的 GPU 隔离。除此之外,我们还得到了:
- 熊猫 UDF 的 GPU 加速。
- 您可以指定 RDD 操作中的 GPU 数量。
- 为了轻松指定深度学习环境,有 YARN 和 Docker 支持推出带 GPU 的 Spark 3.0。
日志丢失:支持
您还可以设置您的指标的物流损耗。
val evaluator = new MulticlassClassificationEvaluator() .setMetricName("**logLoss**")
二进制文件
您可以使用二进制文件作为 spark 数据帧的数据源,但是,现在不允许二进制的写操作。我们可以期待在未来的版本中。
val df = spark.read.format(**BINARY_FILE**).load(dir.getPath)
库伯内特斯
现在,在最新 Kubernetes 版本的支持下,您将能够通过 Kubernetes 托管集群。它在运行时提供 spark-submit 变化的 web-hooks 配置修改窗格。它还改进了 Kubernetes 的动态分配。此外,我们得到:
- 支持 GPU 调度。
- Kubernetes 后端的 spark.authenticate secret 支持。
- Kubernetes 资源管理器现在支持 Kerberos 身份验证协议。
考拉:熊猫的星火尺度
考拉是 Apache Spark 上的熊猫 API,它使数据工程师和科学家在与大数据交互时更有效率。随着 3.0 功能发布,考拉现在可以扩展到分布式环境,而不需要单独读取 Spark 3.0 数据帧,这与以前的单节点环境不同。
import databricks.koalas as ks
import pandas as pd
pdf = pd.DataFrame({'x':range(3), 'y':['a','b','b'], 'z':['a','b','b']})
# Create a Koalas DataFrame from pandas DataFrame
df = ks.from_pandas(pdf)
# Rename the columns
df.columns = ['x', 'y', 'z1']
# Do some operations in place:
df['x2'] = df.x * df.x
以上例子摘自考拉吉特回购。
卡夫卡流:包括磁头
现在你可以在Kafkastreaming(git)中读取标题了。
val df = spark .readStream .format("kafka") .option("kafka.bootstrap.servers", "host1:port1,host2:port2") .option("subscribe", "topic1")
**.option("includeHeaders", "true")**
.load()df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)", **"headers"**) .as[(String, String, Map)]
纱线特征
纱线还获得了一组新特征,主要是:
- Spark 3.0 框架现在可以自动发现集群或系统上的 GPU。
- 可以调度 GPU。
你可以在这里查看 YARN 的 GPU 配置:https://Hadoop . Apache . org/docs/r 3 . 1 . 0/Hadoop-YARN/Hadoop-YARN-site/using GPU . html
分析缓存数据
现在您可以分析 Spark 3.0 中的缓存数据,这是 Spark ( git )最想要的特性之一。
withTempView("cachedQuery") {
sql("""CACHE TABLE cachedQuery AS
| SELECT c0, avg(c1) AS v1, avg(c2) AS v2
| FROM (SELECT id % 3 AS c0, id % 5 AS c1, 2 AS c2 FROM range(1, 30))
| GROUP BY c0
""".stripMargin)
**// Analyzes one column in the cached logical plan**
sql("**ANALYZE** TABLE cachedQuery COMPUTE STATISTICS FOR COLUMNS v1") **// Analyzes two more columns**
sql("**ANALYZE** TABLE cachedQuery COMPUTE STATISTICS FOR COLUMNS c0, v2")
动态分区剪枝
它通过在散列连接中重用维度表广播结果,在运行时提供优化的执行。这有助于 Spark 3.0 更有效地处理基于星型模式的查询,从而消除了 ETL 非规范化表的需要。
点击查看 Databricks 关于 Apache Spark 中动态分区修剪的会话。
三角洲湖
Delta Lake 是一个开源存储层,为 Apache Spark 3.0 带来了 ACID 事务,并且由于其易于实施和升级到任何现有 Spark 应用程序,它为数据湖带来了可靠性。
参见三角洲湖泊快速启动:【https://docs.databricks.com/delta/quick-start.html
更多功能:
- SparkML 中的决策树。
- 改进了查询执行期间的优化器。
- 可插拔目录集成。
- 执行器内存的度量。
- 动态分配。
上面提到的功能并不是 Spark 3.0 的唯一功能。毫无疑问,Spark 3.0 正在帮助数据科学家利用附加功能做更多事情,等待 Spark 3.0 的最终发布。
发展中地区的全球变暖和疟疾:Python 中的分析
气候变化预计会对尼日利亚、海地和也门等发展中国家产生不利影响。这些影响包括因昆虫和害虫增加造成的食物短缺、人口迁移和疾病传播。世界卫生组织将气候变化描述为疾病的威胁倍增器:
它应对现有的威胁——无论是霍乱爆发、寨卡病毒向新地理区域的传播,还是干旱带来的严重营养不良——并增强这些威胁。风险是熟悉的,但它们的影响在频率和严重性上被放大了。气候变化会扩大传染病的分布,特别是由蚊子和其他媒介传播的疾病,并引发其他疾病的出现。尼帕病毒和汉坦病毒作为人类病原体的出现被追溯到极端天气事件,这些事件迫使动物宿主离开它们的生态位并入侵人类住区。
有很好的历史证据表明气候条件和传染病之间的联系。具体而言,疟疾是一种病媒传播的疾病,预计将受到全球变暖的显著影响。
在之前的一篇文章中,我们研究了气候变化如何影响水稻和小麦等作物的产量。在本帖中,我们将对由数据中心提供的公共气候变化数据和由ourworldindata.org提供的全球疟疾死亡数据进行简单的探索性分析。
我们从导入 python 库 Pandas 开始:
import pandas as pd
我们要查看的第一个数据集是年度全球气温数据。我们可以将数据读入 dataframe 并打印前五行:
df_global_temp = pd.read_csv("annual_temp.csv")
print(df_global_temp.head())
接下来,我们可以过滤我们的数据,以便我们只获得与 NASA GISTEMP 源相对应的记录:
df_global_temp = df_global_temp[df_global_temp['Source'] == 'GISTEMP'].reset_index()[["Source", "Year", "Mean"]]
print(df_global_temp.head())
接下来,我们可以绘制年平均温度与时间的关系图。接下来,我们导入 python 可视化软件包“seaborn ”,并绘制时间序列的线图:
import seaborn as sns
sns.set()
sns.lineplot(df_global_temp['Year'], df_global_temp['Mean'])
plt.ylabel("Mean")
plt.title("Average Global Mean Temperature")
接下来我们可以看看 ourworldindata.org 提供的每 1000 人中疟疾的平均发病率。让我们将“incidence-of-malaria.csv”数据读入一个数据帧,并查看前五行:
pd.set_option('display.max_columns', None)
df_malaria = pd.read_csv("incidence-of-malaria.csv")
print(df_malaria.head())
我们还可以观察一组独特的区域:
from collections import Counter
print(set(df_malaria['Entity'].values))
print("NUMBER OF REGIONS: ", len(set(df_malaria['Entity'].values)))
数据集仅包括每个区域 4 个点,共有 127 个区域。每个地区的数据都不多,所以任何分析都应该持保留态度。知道发展中地区更容易遭受气候变化带来的风险,缩小我们的范围将是有益的。《时代》杂志称,尼日尼亚、海地、也门、菲律宾和斐济将面临气候变化带来的最严重后果。
考虑到这一点,我们可以从尼日利亚的疟疾发病率开始:
df_malaria = pd.read_csv("incidence-of-malaria.csv")
df_malaria = df_malaria[df_malaria['Entity']=='Nigeria'].reset_index()[["Entity", "Code", "Year", 'Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)']]
print(df_malaria.head())
接下来我们可以绘制 2000 年至 2015 年尼日利亚的疟疾发病率:
sns.lineplot(df_malaria['Year'], df_malaria['Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)'])
plt.ylabel("Malaria incidents in Nigeria (per 1,000 population at risk)")
plt.title("Malaria incidents in Nigeria")
接下来,我们可以叠加全球年平均气温(为清晰起见,以 100 为因子)和尼日利亚的疟疾发病率:
df_global_temp = df_global_temp[df_global_temp['Year'] <= 2015]
sns.set()
sns.lineplot(df_global_temp['Year'], df_global_temp['Mean']*100)
plt.ylabel("Mean")
sns.lineplot(df_malaria['Year'], df_malaria['Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)'])
plt.ylabel("Malaria Incidence (Orange)/Global Mean Temperature Scaled by 100 (Blue)")
plt.title("Malaria Incidence in Nigeria and Global Mean Temperature")
虽然我们可以看到随着平均气温的上升,疟疾发病率的下降开始趋于平稳,但气候变暖与疟疾发病率平稳之间的联系并不令人信服。
我们也可以看看海地:
df_malaria = df_malaria[df_malaria['Entity']=='Haiti'].reset_index()[["Entity", "Code", "Year", 'Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)']]
print(df_malaria.head())
sns.set()
sns.lineplot(df_malaria['Year'], df_malaria['Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)'])
plt.ylabel("Malaria Incidence in Haiti (per 1,000 population at risk)")
plt.title("Malaria Incidence in Haiti")
海地的数据更不令人信服。我们可以叠加温度和疟疾数据:
df_global_temp = df_global_temp[df_global_temp['Year'] <= 2015]
sns.set()
sns.lineplot(df_global_temp['Year'], df_global_temp['Mean']*100)
plt.ylabel("Mean")
sns.lineplot(df_malaria['Year'], df_malaria['Incidence of malaria (per 1,000 population at risk) (per 1,000 population at risk)'])
plt.ylabel("Malaria Incidence in Haiti (per 1,000 population at risk)/Global Mean Temperature Scaled by 100 (Blue)")
plt.title("Malaria Incidence in Haiti and Global Mean Temperature")
在这一点上,从数据中得出任何结论都需要更详尽的分析。我们将在这里结束我们的分析,但请随意查看其他地区的疟疾发病率以及 datahub 上提供的一些其他气候变化数据。这篇文章中的数据集和代码可以在 GitHub 上找到。感谢您的阅读!