数据科学入门终极指南
我是如何在不到 6 个月的时间里获得数据科学工作机会的
罗伯特·安东尼·卡本摄于佩克斯
我想告诉你一些事情:
数据科学入门的方法不止一种!
进入一个新的领域并不容易,尤其是像数据科学这样复杂和多面的领域。我们生活在一个怪异的时代,甚至数据科学的定义(和期望)也因公司而异。一个数据科学家以前做什么,以前需要了解什么,需要雇佣数据科学家的公司类型都处于快速进化的状态。
为什么世界上只有一条路可走?
老实说,如果你想进入数据科学领域,我想不出更好的开始时间了!
照片由 Pexels 的 Yogendra Singh 拍摄
这个问题(如何开始从事数据科学)的明显答案是:
- 追求(并完成)更高的学位。
- 开始发送简历。
如果你能拿到研究生学位,那就去争取吧!在同等条件下,高等教育是开始从事数据科学工作的最可靠方式。
但这不是唯一的方法,也可能不是最好的方法,而且这种方法肯定不是对每个人都有效。由于我在不到六个月的时间里从零技能到获得工作机会和咨询请求,我想我应该分享我的非传统旅程,以及我们在这里发布的关于走向数据科学的不可思议的故事中的一些最佳信息。
我的建议?
走出自己的路,参与进来!
这是给每一个需要走更少人走的路的人的。
由 Kaboompics 拍摄的照片。来自像素的 com
本文是面向数据科学的问我任何问题系列的一部分。从一开始,我们就收到了一些很棒的问题,这个问题非常突出。
作为一个有幸阅读了许多精彩成功故事(以及一些不太成功的精彩故事)的人,我可以绝对肯定地告诉你,在数据科学中没有单一的入门方法。
我还可以告诉你,在这个过程中,有无数的人想要帮助你。利用这一点!
照片由 Matheus Viana 从 Pexels 拍摄
你想干嘛?
不管有没有学位,你应该做的第一件事就是关注你感兴趣的数据科学的特定领域。
这并不像你想象的那么简单。
与工作机会相关的术语“数据科学”涵盖了非常灵活和广泛的专业领域以及目前可能的职业选择!(可以肯定的是,在一个新的领域找工作是你阅读这篇文章的原因。如果你停下来解析“数据科学”和“数据科学家”的传统定义,请跳到评论部分。)
例如,您可能对某个特定的工作或领域感兴趣,该工作或领域侧重于:
- 商情分析
- 数据分析
- 数据可视化
- 财务分析
- 医疗保健分析
- 推荐系统
- 自然语言处理
- 图像处理
或者很多其他专业。我们正处于一个奇怪的时代,越来越多的公司知道他们需要雇用数据科学家,而不是知道数据科学家具体做什么。利用这一点,找到你的位置!(这里有一篇精彩的文章,讲述了招聘经理和高管想要传达的东西与他们雇佣的人之间的不匹配。)
现在确定做你想做的工作的具体公司。确保你找到了让你兴奋的公司!研究他们以前发布的工作信息,并根据这些要求调整你的学习路径。你可能会发现你需要学习 Python 或 R、SQL,可能还有 AWS、Spark、Hadoop 等等。您将希望了解数据可视化技术和工具。根据你的兴趣,你可能需要学习自然语言处理、图像识别、机器学习技术等概念。你可能还会发现,你想要的工作要求应聘者拥有某个特定领域的硕士或博士学位。这是非常重要的信息!如果你想为之工作的公司使用一种算法来筛选候选人,而你的简历不符合他们的要求,就没有人会看它。
如果你想为一家特定的公司工作,了解他们对成功候选人的要求,列一个清单,并开始检查你所学到的一切。永远不要忘记领域知识的力量!它不会出现在工作岗位上,但可以了解你所关注的行业所面临的具体问题和挑战。软技能也要注意!他们能让你在竞争中脱颖而出。如果你已经有了交流、展示、管理、演讲等方面的经验,你就已经领先了。
如果你觉得自己很勇敢,那就给你想去工作的公司的人发一封电子邮件,告诉他们你即将进入这个领域,你比其他任何地方都想去那里工作。问他们什么会让你成为未来职位的理想候选人!也许他们不会回应,但我敢打赌他们中的一些人会。
如果你得到了回复,不管是什么回复,给他们发一封短信,表达你对他们花时间回复的感激之情。
照片由 sobhan joodi 从 Pexels 拍摄
该不该读博?
如果你能拿到研究生学位,就去做吧!没有什么可以替代高质量的教育和它提供的网络可能性。我们在这里发表了一些令人难以置信的文章,这些人充分利用了他们的教育,并开始征服数据科学、机器学习、人工智能等领域。
但是也许高等教育现在对你没用。没关系!拥有博士学位是一件很棒的事情,毫无疑问,它会为你打开大门。但是拥有一个学位并不能保证你会找到一份工作或者在工作中表现出色。拥有一个高等学位并不能保证你会成为某个特定工作的成功候选人。这是一个很好的视角,它展示了如何成为一名伟大的数据科学家。
也没有说你需要特定的教育水平才能成为数据科学家。有它会有帮助吗?当然啦!但是越来越多的人发现,完成了很棒的在线课程,再加上你自己思考和开发的项目组合,再加上额外的经验(例如,以前的工作经验和开源贡献),与仅仅拥有某个学位一样有效(如果不是更有效的话)。
你可以找到无数优秀的文章,这些文章的作者走了一条稍微不那么传统的道路,他们认为拥有一个高等学位对于现实世界来说是不够的。我们还发表了一些作者的文章,这些作者深入研究了成为数据科学家所需的技能(作者在 2018 年写了这篇文章,并在 2019 年更新了这篇文章),特别是在,你是否需要研究生学位才能从事数据科学。
情况并非总是如此!
长期以来,数据科学家确实是科学家。教育至关重要!然而,现在,随着可用数据的迅猛增长以及企业以有意义的方式处理这些数据的必要性(以及十年前不存在的技术、工具和库的可用性),数据科学领域已经发生了变化。
今天,有很多企业已经了解到他们需要数据科学家,但没有具体的计划或对数据科学团队的具体期望。许多寻找数据科学家的企业确实需要一名数据分析师或业务分析师。一些公司只是需要帮助来理解他们所拥有的大量数据,可能会要求你创建基本的预测模型。有些企业真的是在找数据工程师或者机器学习工程师。因为这个领域正处于一个不断发展和变化的时代,高学历不再是绝对的要求。有能力处理一家公司的数据,分析它,并以有意义的方式交流你的发现,不再需要博士学位。
但是如果你想在这个过程中有一个真正的开端,并且你能做到,那就去接受教育吧!它只能帮助你。
黄色的树林里分出两条路…
不管出于什么原因,如果硕士/博士课程对你不起作用,看看网上的大量课程吧!当然,它们并不都是好的。你会想看看哪些课程教授了你想知道的东西,哪些课程很受欢迎并有很好的评论,哪些课程是该领域的成功人士学过的,等等。
如果你能够专注于这条道路,并致力于此,那么你没有理由不能在今年年底前获得数据科学领域的一个绝佳职位。
首先也是最重要的,想想你的学习风格!有些人通过阅读学得最好,有些人通过听,有些人通过看视频,有些人通过做练习学得最好。有些人需要自己寻找答案,有些人需要别人提供答案,这样他们就可以看到答案并逆向工作。无论你的风格如何,总有一系列的课程等着你!(但是,无论您选择什么,请确保您自己输入了每一行代码。没有替代品。让你的手指工作,以一种令人震惊的有效方式在你的大脑中获得信息!)
我强烈建议免费开始,只是为了确保你喜欢这份工作,而不仅仅是炒作。你可以在网上找到极好的免费资源。这里有一个很棒的免费资源汇编!
编程语言
如果你没有任何编程经验,你可能想看看一些教授你感兴趣的编程语言的在线课程。Python 和 R 是数据科学最受欢迎的选择。选择一个而不是另一个的原因有很多,但是 Python 已经在这个领域领先很多年了,它仍然是明智的首选(当然,除非你已经知道 R 是你感兴趣的职位的要求)。选择适合你的语言!
我建议查看:
- uda city 的 Python 入门课程
- 在 Udemy 上试试这个(这不是免费的,但是 Udemy 的课程一直都在打折。你也可以找到一堆折扣和促销代码。)
- 走过 Codeacademy 的 Python 学习之路,
显然,这是我的学习风格,我选择了学习 Python。如果你有喜欢的课程,请在评论中分享!
如果你想开始学习编程,你可以看看:
- 代码学院
- Udacity (找到他们的免费课程不容易!单击“程序”下拉菜单中的“完整目录”按钮。如果需要,可以搜索特定的主题。在屏幕的左侧,您会看到您可以过滤信息。点击“选择项目详情”,在“类型”下,您可以选择“免费课程”)
- f reeCodeCamp
- 代码大战
- learnpython.org
- Python 如你所愿
- Coursera
- SoloLearn
读,听,看。永远!
确保每天至少阅读一两篇文章和/或收听数据科学播客或观看数据科学视频。如果需要,你可以在浴室里读文章,或者在床上听播客,但要这样做。利用现有的难以置信的知识财富来保持最新,并熟悉数据科学的语言。当然,我推荐这里关于走向数据科学、我们的播客和我们的 YouTube 频道的文章,但是你有很多选择!
我们最近发布了一份伟大的列表,列出了前 20 名数据科学播客。
现在认真学习那些数学技能。你至少要熟悉统计学、线性代数和基础微积分。不要害怕数学!如果你要在这个领域工作,数学技能是至关重要的。在可汗学院重温你的技能,或者利用 Udacity 上的一些免费课程。
这篇文章很好地概述了必要的数据科学数学技能以及如何开始免费学习数据科学!
找数据科学课程!
一旦你开始熟悉你选择的编程语言,并且对统计学有了一点熟悉(至少),就开始学习数据科学课程吧!你不需要成为一个专业的程序员来开始学习介绍性的在线课程。但是基本的熟悉会帮助你避免不知所措。你可能想看看 Coursera 、 Udacity 、 Udemy 和 edX ,或者你可能对 Datacamp 、 Dataquest 、跳板或精英数据科学感兴趣。还有,Coursera 允许你免费旁听课程!你不会得到官方的证明,但是你会不花一毛钱得到信息。(也可以用 Coursera 申请助学金)。
你是那种靠读书学好的人吗?您知道您可以继续学习数据科学吗?我们按主题整理了一些最好的文章,以帮助您按照自己的进度了解更多!
奖学金和折扣!
仍然对从事数据科学感兴趣吗?开始寻找奖学金、挑战和比赛吧!你不会相信通过奖学金项目和挑战得到的信息。我已经通过 Udacity 完成了贝塔斯曼数据科学奖学金挑战,脸书 AI PyTorch 奖学金挑战,以及安全和私人 AI 奖学金挑战,还有很多其他的挑战。这些挑战中的每一个都教授真正有用的信息,并让你免费接触一个令人难以置信的社区。
不要忘记网络!!!
GIF via giphy
确保你在 LinkedIn 上的课程和挑战中与了不起的人联系在一起!当你这么做的时候,确保你的 LinkedIn 个人资料看起来不错。填写您的教育部分、证书、技能,并添加您已经完成的任何项目。写一个高质量的“关于我”部分,展示你是谁以及你如何帮助他人。(你会惊讶地发现,把“我对数据可视化技术很有经验”变成“我可以帮助你用你的数据讲述精彩的故事”会带来多大的变化!认可一些你已经很熟悉的人的技能,他们可能会认可你的一些技能作为回报。
一旦你开始熟悉这些概念,你会发现你需要开始在你的工具箱中增加一些工具。SQL 非常重要。您肯定也想开始熟悉数据可视化技术。当然,在你的在线课程中会用到一些工具,如果你还没有熟悉的画面,你可能也想熟悉一下。这是一个受欢迎的工具,它在可视化交流数据分析方面做得很好,对桌子两边的初学者都有效。你肯定想熟悉 Git 和 GitHub 的工作方式,而且有很多在线课程。(这是一门像样的新手免费课程。这一个专门处理版本控制,倾向于被更强烈地推荐。)
Git 和 GitHub 基础知识,供好奇和完全困惑的人使用(加上最简单的方法来为您的第一次公开…
towardsdatascience.com](/getting-started-with-git-and-github-6fcd0f2d4ac6)
开始看 Kaggle !不是每个人都使用 Kaggle 或参加比赛,但对于那些有兴趣测试他们技能的人来说,它们是非常有用的资源。此外,在 Kaggle 上表现出色可以推动你进入一些有趣的情境和全新的职业生涯。有很多人已经努力收集了他们关于 Kaggle 成功的最佳技巧和诀窍,所以不要觉得你必须自己解决所有问题。
你对黑客马拉松感兴趣吗?我们从那些已经准备好参加黑客马拉松的人那里听到了一些惊人的故事,他们有一些非常令人震惊的经历。
付费玩
还去吗?也许是时候开始考虑付费课程了。我是 Udacity 纳米学位的粉丝,但你可能想投资 Coursera 或 edX 课程。你甚至会决定训练营适合你。
你可能想读 Udacity 的数据科学纳米学位或他们的 T2 机器学习纳米学位。您可能也会对以下项目感兴趣:
我们发布了参加过训练营的人的精彩故事,网址为:
项目时间!
现在是时候专注于你的项目了!清理您的 GitHub 个人资料。如果可以的话,确保你每天都在提交,并展示你的项目中最好的部分。在这一点上,你将已经在你的课程中整合了一些项目,并且应该足够舒适地开始你自己的项目。找一个你真正感兴趣的话题,做一些令人惊奇的事情,或者用一种新的方式看待一些事情!解决一个问题!真正投入进去,把这个项目变成你自己的。你永远不知道一个个人项目会把你带到哪里。
做一些你关心的事情会给你一些东西,你可以用新的方式在新的水平上谈论。这将在你社交和面试时对你有所帮助!
通过 Twitter 使用检测社交媒体中的抑郁症
towardsdatascience.com](/you-are-what-you-tweet-7e23fb84f4ed)
现在开始为开源组织做贡献吧!为 GitHub 上的组织做一些有意义的贡献。GitHub 有一个部分专门介绍对于新贡献者来说很棒的项目!你可以搜索专门为第一次或者初学者友好标记的项目。还有一个可靠的 GitHub 回购致力于出色的首次公关机会值得一试。
找一个你真正能帮助的组织,或者一个你真正感兴趣的组织,并参与其中。大多数开源组织在很少甚至没有预算的情况下运营,并感谢他们所能获得的所有帮助。他们希望你成功!我曾与 NumPy的优秀员工密切合作,他们真诚地希望帮助人们理解为 NumPy 做贡献的过程,这样他们会对长期贡献感到满意。他们不想让你放弃!这不是一个简单的过程,但他们希望你成功并继续做出贡献。
帮助解决已知问题,帮助编写文档,尽你所能提供帮助!如果你找到一个与你和你的兴趣相符的组织,优先考虑帮助他们。你可能会在不知不觉中发现自己加入了他们的团队!
(抬头!你现在正在积累经验,这会让你的简历脱颖而出!)
还有,我以前说过,我再说一遍。开始写!!!
作为一个没有经验或高等学位的全职妈妈,我是如何通过写作来改变职业的
writingcooperative.com](https://writingcooperative.com/youre-weird-use-it-change-your-life-88e54c623cca)
写下你学到的东西。写信分享你的信息并帮助他人。你会惊讶于理解一个概念和充分理解一个概念并写下它之间的差异。此外,技术社区在帮助他人方面投入巨大(看看从开源组织到 Quora 、 Stack Overflow 等等的一切),你想在社区中加入你的声音。
就个人而言:写作无疑是我发现的让初学者受到关注的最好方法!我的文章给我带来的机会令人兴奋。我获得了顾问、演讲、写作和编辑工作、教学和指导职位、数据科学职位等仅仅基于这些文章的职位。
醒醒!
所以现在你有了可以深入谈论的伟大项目,一系列展示你所知和所学的文章,一份可靠的 GitHub 简介,几份你名下的证书,你一直在为开源组织做贡献,你甚至可能已经完成了一两次 Kaggle 比赛或参加了一次黑客马拉松。你有一个优化的 LinkedIn 个人资料,可以展示你的经验、技能和人脉。你也已经(我希望)用项目、技能和开源经验充实了你的简历,并且已经准备好了。
你到底在等什么?
走出去,开始与人交流!尽管盲目地向数百家发布招聘广告并使用算法和招聘人员筛选候选人的机构发送简历很有趣,但你可能会发现,获得聘用的最快(也是最不痛苦的)方式是与某个机构的人进行实际对话!
还记得你在流程开始时发出的那些电子邮件吗?再次向那些人伸出援手,再次感谢他们的帮助。提醒他们你是谁,让他们知道你在这么短的时间内完成了什么。提到如果能和公司里的人交谈,你会有多兴奋。展示你的沟通技巧、听从建议的能力以及自我激励的能力。看你得到什么样的回应!
与你的奖学金和课程中找到好工作的人交谈,看看他们学到了什么。您可能还想与您在开源组织中联系过的人进行一两次交谈。你永远不知道,他们甚至可能会推荐你去一个很酷的职位。LinkedIn 基本就是这么回事!
对于那些内向、自卑、患有严重的冒名顶替综合症的人来说,永远不要忘记,有很多公司会为成功推荐一个职位空缺候选人的人提供推荐奖金。你的一两个朋友可能只是对赚点小钱感兴趣…
另外,记住人们不知道你没有告诉他们的事情。你知道你的 LinkedIn 上有哪些人在找工作吗?你知道那个开源组织中有多少人在积极地寻找工作吗?大概不会!我们喜欢假设人们了解我们的一切,但事实并非如此。大声说!你可能会惊讶地发现,如果可以的话,有多少人愿意伸出援手。
现在怎么办?
停止拖延!走出去,开始在数据科学领域工作!
感谢阅读!一如既往,如果你用这些信息做了什么很酷的事情,请在下面的评论中让每个人都知道,或者随时联系!
想找更多好玩的文章?您可能对这些感兴趣:
* [## 现在如何开始数据科学:10 篇顶级文章和一个想法
今年对于网络来说是艰难的一年。
towardsdatascience.com](/how-to-get-started-in-data-science-now-10-top-articles-and-one-idea-d9d28ee34cca) [## 如何撰写和发表引人注目的文章
创建内容的简单技巧,易于查找,阅读起来令人兴奋
medium.com](https://medium.com/swlh/how-to-write-and-publish-articles-that-get-noticed-60e9701daed4) [## 数据搜集、清理和可视化初学者终极指南
通过清理和预处理您的数据,让您的模型从不起眼到令人惊叹
towardsdatascience.com](/ultimate-beginners-guide-to-scraping-and-cleaning-twitter-data-a64e4aaa9343)**
线性回归终极指南
在这篇文章中,我们将讨论机器学习中使用的线性回归模型。这篇文章的建模将意味着使用机器学习技术从数据中学习一组特征和我们希望预测的之间的关系。让我们引入一些数据来使这个想法更加具体。
from sklearn.datasets import load_boston
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np from sklearn.model_selection
import learning_curve from sklearn.metrics
import make_scorer
%matplotlib inlinenp.random.seed(42)boston_data = load_boston() boston_df = pd.DataFrame(boston_data.data, columns=boston_data.feature_names)
target = boston_data.target
以下是我们数据的一些描述:
- CRIM——城镇人均犯罪率
- ZN——面积超过 25,000 平方英尺的住宅用地比例
- 印度河——每个城镇非零售商业用地的比例。
- CHAS——查尔斯河虚拟变量(1 如果区域边界为河流;否则为 0)
- NOX——氮氧化物浓度(百万分之一)
- RM——每个住宅的平均房间数
- 年龄——1940 年之前建造的业主自用单元的比例
- 到五个波士顿就业中心的 DIS 加权距离
- RAD——放射状公路可达性指数
- 税收—每 10,000 美元的全价值财产税税率
- pt ratio——按城镇分列的学生-教师比率
- B — 1000(Bk — 0.63),其中 Bk 是按城镇划分的黑人比例
- LSTAT——人口的低地位百分比
- 目标——以千美元为单位的自有住房的中值
此数据集的目标是使用要素(除目标之外的所有要素)来预测目标(房屋中值)。
线性回归
我们如何做到这一点?
对于我们的第一遍,让我们简化问题。假设我们只想用 LSAT 来预测目标。
plt.scatter(boston_df['LSTAT'], target)
在 x 轴上,我们有 LSTAT 和 y 轴目标。单看它,似乎有一个负的关系:随着 LSTAT 上升,TARGET 下降。
成本/评估功能
如何解决从 LSTAT 预测目标的问题?开始思考的一个好地方是:假设我们开发了许多模型来预测我们的目标,我们将如何选择最好的一个?一旦我们确定了这一点,我们的目标就是最小化/最大化这个价值。
如果您能够将您的问题简化为一个单一的评估度量,这将是非常有用的,因为这样可以非常容易地迭代模型开发。然而,在工业领域,这可能会很棘手。有时候你并不十分清楚你想要你的模型最大化/最小化什么。但这是另一个帖子面临的挑战。
所以对于这个问题,我会提出以下评价指标:均方误差(MSE) 。为了理解 MSE,让我们定义一些术语:
- 这是我们对第 I 个数据点的预测值
- 这是第 I 个数据点的实际值
- n —数据点的数量
因此,MSE 为:
在英语中,对于每个点,我们从实际值中减去预测值。然后,因为我们不关心误差的方向,所以我们求差的平方。最后,我们取所有这些值的平均值。基本上,我们是说我们希望我们的预测和实际之间的平均距离小一些。
你可能会奇怪,为什么我们平方这个值,而不是取绝对值。事实证明,对于下面的一些数学运算来说,平方这个值效果很好。而且,它是最大似然估计。不过,这确实有在我们的平均值中增加大误差权重的效果,因为我们在平方所有的差异。
我们的模型
现在我们有了成本函数,如何找到最小化它的方法呢?在本帖中,我们将回顾线性回归模型。该模型如下:
其中 j 是我们拥有的预测值的数量,β值是我们的系数,β0是截距。基本上,我们的模型是预测值和截距的线性组合。
现在我们有了一个模型和一个成本函数,我们的挑战变成为我们的模型找到最小化我们数据的 MSE 的 beta 值。对于线性回归,实际上有一个封闭形式的解决方案,称为正常方程。然而,在这篇文章中,我们将使用一种在机器学习中更常见的不同技术——梯度下降。
梯度下降
梯度下降是我们从最优化中借用的一种技术。这是一个非常简单,但功能强大的算法,可用于寻找一个函数的最小值。
- 选择一个随机的起始值
- 在当前点采取与梯度负值成比例的步长
- 重复直到你收敛
如果一个函数是凸的,这种技术将找到全局最小值,如果不是,我们只能证明它将找到局部最小值。
我们需要回答的第一个问题是:我们的成本函数是凸的吗?让我们来看看:
我们上面所做的是为 LSTAT 取一系列系数值,并根据我们的数据计算每个系数值的 MSE。如果我们画出这些,我们会得到上面的曲线——看起来很凸!事实上,我们的线性回归模型的 MSE 函数总是凸的!这意味着我们可以使用梯度下降来找到我们的模型的最佳系数!
梯度下降比机器学习的正常方程更常见的一个原因是,随着我们增加特征的数量,它的规模更大。它也是一种普遍的优化技术,在机器学习中随处可见,因此了解它的工作原理是非常有价值的。
梯度
如果你再看一下梯度下降的伪代码,你会发现我们真正需要做的就是计算梯度。那么,什么是渐变呢?它们只是关于系数的偏导数。对于每个系数,我们需要计算 MSE 对该系数的导数。我们开始吧!
让我们扩展我们的成本,以一个截距和一个变量 LSTAT 为例:
现在,对于这个相对于β0的导数,我们得到(乘以-1):
而对于 beta 1 :
现在,让我们运行梯度下降算法,确认 MSE 确实在下降:
beta_0: 34.553840879456807beta_1: -0.95004935376241229
上面打印的第一张图显示了我们运行梯度下降时的 MSE 值。正如我们期望看到的,随着算法的运行,MSE 随着时间的推移而降低,这意味着我们不断接近最优解。
您还可以从图表中看到,我们本可以更早停止,因为 MSE 在大约 4000 次迭代时基本持平。
运行梯度下降发现最佳截距为 34.55,最佳斜率为-0.95。
上面的图显示了我们的数据上面的那条线,事实上它看起来是最佳拟合的线。
学习率
我们尚未讨论的一个参数是学习率。该速率是一个超参数,用于确定我们离梯度方向有多远。你怎么知道选择什么值?通常,可以尝试许多值,这里有一些我认为是吴恩达建议的值:. 001,. 003,. 01,. 03,. 1,. 3,1,3
选择一个太小的值会导致收敛速度变慢。选择太大的值会导致超过最小值和发散。
也有其他梯度下降优化,更复杂,适应学习率超时为您服务。这也是你可以自己做的事情,随着时间的推移,你会慢慢降低学习速度。
什么时候停止迭代?
在我的代码中,我简单地选择运行循环 10,000 次。为什么是一万?没有真正的原因,除了我很确定它足够长的时间来收敛。这通常不是最佳实践。一些更好的想法是:
- 在每一次循环后监控你的成本,当它的下降小于某个容差时——比如 0.001——停止。
- 使用一个验证集,并在其上跟踪损失,例如,MSE。当它停止减少时,停止。
标准化数据
使用梯度下降时,您希望所有数据都进行归一化。减去平均值,然后除以所有训练特征的标准差。如果您的成本函数不是凸的,这通常会使训练更快,并减少陷入局部最优的机会。
其他类型的梯度下降
我们这里展示的梯度下降是一种普通形式,这意味着每次系数更新都使用所有数据来计算梯度。还有随机梯度下降只使用 1 行数据来更新每个循环中的系数。这更具可伸缩性,因为在更新前您只需一次查看一个数据行,但也更具随机性,因为您试图使用仅在单个数据点上计算的梯度进行导航。
另一种类型的梯度下降是小批量梯度下降。这种形式是两者之间的一种折衷,您可以选择一个批处理大小,比如说 32(或者更好的是一个批处理时间表,它从小批处理开始,随着历元数的增加而增加),并且梯度下降的每次迭代将使用 32 个随机数据行来计算梯度(它使用所有行,然后再次对相同的行进行重新采样)。这提供了一些可伸缩性和一些随机性。这种随机性实际上对于非凸的成本函数(深度学习)是有用的,因为它可以帮助模型摆脱局部最小值。这是非凸成本函数最常用的方法。
我们模型的假设
每当你处理一个模型时,了解它所做的假设是有好处的。我本打算在这里就此写一篇文章,但是杜克已经做得很好了:【http://people.duke.edu/~rnau/testing.htm。
使用 Scikit-Learn
现在我们已经了解了一些理论和实现,让我们转向一个软件库,对我们的数据进行线性回归。这对于学习从头开始编写模型非常有用,但是在实践中,使用一个经过测试并广泛使用的库通常会好得多。
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
请记住扩展您的数据,这非常重要!
scaler = StandardScaler()
scaler.fit(boston_df)
scaled_df = scaler.transform(boston_df)
Scikit-learn 有一个非常好的 API。它提供了许多模型,并且它们都具有拟合和预测功能。您调用对 X 和 y 数据进行拟合来训练模型,然后对新特征进行预测来获得预测值。Scikit-learn 还提供了许多可用于评估的指标,如 MSE。这里我输出根 MSE (RMSE ),因为这让我们回到目标的原始比例,我觉得这更容易理解。
使用我们的 SGDRegressor(使用梯度下降运行线性回归), tol 告诉模型何时停止迭代, eta0 是我们的初始学习率。
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01) linear_regression_model.fit(scaled_df, target)
predictions = linear_regression_model.predict(scaled_df)
mse = mean_squared_error(target, predictions)
print("RMSE: {}".format(np.sqrt(mse)))RMSE: 4.721352143256387
对于使用 scikit-learn 的训练集,我们的 RMSE 最终为 4.72。
多项式变量
如果你记得我们的 LSTAT 对我们的目标的图,看起来有一个多项式关系。线性回归适合线性关系,但是如果添加多项式要素,例如 LSTAT,则可以适合更复杂的关系。SKLearn 让这变得简单:
from sklearn.preprocessing import PolynomialFeaturespoly = PolynomialFeatures(2, include_bias=False)
poly_df = poly.fit_transform(boston_df)
scaled_poly_df = scaler.fit_transform(poly_df) print(scaled_poly_df.shape)(506, 104)linear_regression_model.fit(scaled_poly_df, target)
predictions = linear_regression_model.predict(scaled_poly_df)
mse = mean_squared_error(target, predictions)
print("RMSE: {}".format(np.sqrt(mse)))RMSE: 3.77419484950651
多项式要素命令生成了一个新的要素矩阵,该矩阵由阶数小于或等于指定阶数的要素的所有多项式组合组成(在我们的示例 2 中)。然后,我们对这些数据进行缩放,并将其输入到我们的模型中。我们得到了一个更好的训练 RMSE——3.77。不过,请注意,这些结果只是出于说明的目的,基于我们的训练数据。
分类变量
当您有分类数据时,线性回归是您需要小心使用的模型之一。如果您有一个值为 1、2 和 3 的要素,它们实际上表示男性、女性、无响应,那么即使它们是数字,您也不希望以这种方式将其提供给模型。如果你这样做了,模型会给这个特征分配一个系数——可能是 0.1。这就意味着,女性会将预测提高 0.1%,而无反应会提高 0.2%。但是也许女性应该把分数提高 1.2,而没有反应的分数只提高 0.001。考虑到这一点,您应该将这些值转换为虚拟变量,以便每个值都有自己的权重。你可以看到如何用 scikit 实现这一点——点击了解。
解释你的模型
线性回归是一个伟大的统计模型,已经存在很长时间了。有许多统计技术可以用来评估和解释它。我们不会涵盖所有这些,事实上,我们将主要关注非常简单的方法,这些方法在机器学习中可能比统计学更常见。为了更好地掌握统计技术,请阅读统计学习简介的第 3 章,并看看 statsmodels 包。
首先,让我们看看我们的模型已经学习的系数(从所有的特征):
linear_regression_model.fit(scaled_df, target) sorted(list(zip(boston_df.columns, linear_regression_model.coef_)), key=lambda x: abs(x[1]))[('AGE', -0.15579031087838216), ('INDUS', -0.36890070005440012), ('ZN', 0.61249837977769284), ('TAX', -0.6639660631363058), ('CRIM', -0.7135059713991182), ('CHAS', 0.73578321065548924), ('B', 0.87494012630072004), ('RAD', 1.1142142863056546), ('NOX', -1.2452942744431366), ('PTRATIO', -1.9425283730193659), ('DIS', -2.2549312823672696), ('RM', 3.0623224309690911), ('LSTAT', -3.4699728921831285)]
这些系数是什么?它们表示在保持模型中其他特征不变的情况下,特征变化一个单位的住房价格的平均变化。例如,保持所有其他因素不变,LSTAT 每增加一个单位,我们的目标(房价)就会减少 3.469,RM 每增加一个单位,我们的目标就会增加 3.062。
这真是太好了!我们也许可以说,如果你想增加房子的价值,增加 RM 和减少 LSTAT 可能是一个开始。我说可能是因为线性回归着眼于相关性。在我们的数据中,情况确实如此,但这本身并不意味着这些特征有因果关系。不过,这可能是寻找因果关系的好地方,并且确实代表了数据中出现的关系。
置信区间
通常在机器学习中,在你的估计值周围有一个置信区间是非常有用的。有不同的方法可以做到这一点,但是一个相当通用的方法是使用 bootstrap。
bootstrap 是替换我们数据的随机样本,该样本与原始数据大小相同。这是生成同一数据的多个视图的一种方式。让我们创建 1000 个数据引导。
from sklearn.utils import resample
n_bootstraps = 1000
bootstrap_X = []
bootstrap_y = []
for _ in range(n_bootstraps):
sample_X, sample_y = resample(scaled_df, target)
bootstrap_X.append(sample_X) bootstrap_y.append(sample_y)
然后在每个数据集上,我们可以拟合我们的模型并得到我们的系数:
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01)
coeffs = []
for i, data in enumerate(bootstrap_X):
linear_regression_model.fit(data, bootstrap_y[i])
coeffs.append(linear_regression_model.coef_)coef_df = pd.DataFrame(coeffs, columns=boston_df.columns) coef_df.plot(kind='box') plt.xticks(rotation=90)
该图显示了我们为所有训练模型的每个特征获得的系数值范围。年龄是一个特别有趣的特征,因为系数值既有正的也有负的,这是一个好迹象,表明年龄和我们的目标之间可能没有关系。
此外,我们可以看到 LSTAT 的系数值方差很大,而 PTRATIO 的方差相对较小,这增加了我们对系数估计的信心。
我们甚至可以进一步挖掘 LSTAT 系数:
coef_df['LSTAT'].plot(kind='hist')
coef_df['LSTAT'].describe()count 1000.000000 mean -3.599465 std 0.687444 min -5.825069 25% -4.058086 50% -3.592409 75% -3.120958 max -1.575822 Name: LSTAT, dtype: float64
这太好了!现在我们可以很有信心地说,LSTAT 上的实际系数是负的,几乎肯定在-1.2 到-5.5 之间。
训练/测试分割和交叉验证
到目前为止,我们一直在根据现有的所有数据进行训练。这可能是有意义的,因为我们希望通过使用尽可能多的数据进行训练来最大化数据的效用。然而,另一方面,这使得我们很难评估我们的模型做得有多好。其原因是,如果我们只是使用模型训练的数据来计算我们的 MSE 分数,我们可能会发现,当我们引入未经训练的数据时,它的表现相当差。
这个想法叫做过拟合。基本上,当一个模型在它被训练的数据上比在新数据上表现得更好时,它就过度适应了训练数据所特有的东西,而不是一般化。
这种情况的另一面叫做**偏见。**当一个模型不能很好地拟合数据时,它就有很大的偏差。在这种情况下,对于训练数据和在训练期间没有看到的数据,MSE 都将是高的。
在机器学习中,偏差和方差之间总是有一个权衡。随着模型变得越来越复杂,过度适应训练数据的风险也越来越大。
既然我们知道只看训练数据的 MSE 有问题,我们能做什么来更好地判断概化?以及诊断过度拟合和偏差?通常,我们将数据分成两组:训练集和测试集。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(scaled_df, target, test_size=0.33, random_state=42)
现在我们有了两组独立的数据,我们可以根据我们的训练数据进行训练,并为我们的训练和测试数据计算指标(最佳做法是在调整模型后只使用您的测试数据):
linear_regression_model = SGDRegressor(tol=.0001, eta0=.01) linear_regression_model.fit(X_train, y_train)
train_predictions = linear_regression_model.predict(X_train) test_predictions = linear_regression_model.predict(X_test)
train_mse = mean_squared_error(y_train, train_predictions)
test_mse = mean_squared_error(y_test, test_predictions)
print("Train MSE: {}".format(train_mse))
print("Test MSE: {}".format(test_mse))Train MSE: 23.33856804462054 Test MSE: 21.820947809040835
太棒了。现在我们有了 RMSE 的训练和测试数据。两者都非常接近,这表明我们没有过度拟合的问题。不过,它们都很低吗?这表明有很大的偏见。
研究这个问题的一个方法是绘制学习曲线。学习曲线描绘了我们的误差函数(MSE ),以及用于训练的各种数据量。这是我们的情节:
您可以看到,在不到 50 个训练示例的情况下,训练 MSE 相当好,交叉验证相当差(我们还没有谈到交叉验证,所以暂时把它当作测试)。如果我们那时只有那么多数据,它看起来就像一个高方差问题。
随着我们数据的增加,我们开始提高我们的分数,它们变得非常接近,这表明我们没有高方差问题。通常,在高方差的情况下,该图中的两条线相距较远,如果我们继续添加更多的数据,它们可能会收敛。
这张图看起来更像是我们有一个高偏差问题,因为我们的两条曲线非常接近,并趋于平缓。不过,这很难说,因为我们可能刚刚达到了可能的最佳 MSE。在这种情况下,这不会是一个高偏差问题。如果我们的曲线变得平坦,并且 MSE 高于最优值,这将是一个问题。在现实生活中,你不知道最优的 MSE 是多少,所以你必须从理论上说明你是否认为减少偏差会提高你的分数——或者只是尝试一下!
修复高偏差/高方差问题
那么,现在你已经诊断出了你的偏差或方差问题,你如何解决它们呢?
对于高差异:
- 获取更多培训数据
- 尝试一组较小的功能
- 尝试不太复杂的模型
- 添加正则化
对于高偏置:
- 尝试添加功能
- 尝试更复杂的模型
交叉验证和调整超参数
之前我们提到过这个短语:交叉验证。让我们现在谈论那个。到目前为止,我们已经了解到,将数据分成训练集和测试集是一个好主意,这样可以更好地了解模型的实际运行情况。这很好,但是想象一下我们想要测试多个不同的模型或者测试我们模型的不同参数——例如,不同的学习率或者容忍度。我们如何决定哪个模型或哪个参数是最好的?我们会用训练数据训练一切,用测试数据测试一切吗?希望你能看到这是没有意义的,因为那样的话,我们将基本上处于以前的同一位置,没有办法测试我们对以前从未见过的数据做得有多好。所以——我们希望保持我们的测试集不受污染,也就是说,在一个完美的世界中,我们只会在完成所有实验并认为我们找到了最佳模型之后,才在它上面运行我们的测试。
听起来我们需要第三组数据——验证组。基本上,我们可以做的是将我们的训练数据分成两组:一组训练数据和一组验证数据。所有模型将在训练集上训练,然后在我们的验证集上测试。然后,我们选择验证效果最好的模型,看看它在测试中表现如何。我们的测试结果代表了我们认为我们的模型对看不见的数据有多好——然后我们就完成了。
注意:这里的假设是我们的测试和验证设定了我们总体的代表性样本。例如,如果验证集中的平均房价是 100 万英镑,但总体房价是 30 万英镑,则样本不良。通常,我们随机地将可用的数据分成三组,但是确认这些组是好的表示总是好的。否则,您会发现在验证和测试中运行良好的模型在实践中表现不佳。
在实践中,我们经常使用 k-fold 交叉验证,而不是创建一个单一的验证集。这里我们选择一个 k 值,比如说 3。然后,我们将训练数据分成三份。我们随机选择 2 个折叠进行训练,然后使用剩余的进行测试。然后,我们再重复 2 次,总共 3 次,这样所有的观察结果都用于训练和验证,并且每个观察结果只用于验证一次。然后,我们将所有三个分数(在我们的例子中是 MSE)进行平均,以获得特定模型的分数。然后,我们可以对多个模型重复这一过程,以找到最佳模型。
这里有一个视频更形象地描述了这个过程:https://www.youtube.com/watch?v=TIgfjmp-4BA
使用 sklearn,这个过程非常简单:
from sklearn.model_selection import RandomizedSearchCV
param_dist = {"eta0": [ .001, .003, .01, .03, .1, .3, 1, 3]} linear_regression_model = SGDRegressor(tol=.0001)
n_iter_search = 8
random_search = RandomizedSearchCV(linear_regression_model, param_distributions=param_dist, n_iter=n_iter_search, cv=3, scoring='neg_mean_squared_error')
random_search.fit(X_train, y_train)
print("Best Parameters: {}".format(random_search.best_params_)) print("Best Negative MSE: {}".format(random_search.best_score_))Best Parameters: {'eta0': 0.01} Best Negative MSE: -25.322156767075665
这里我们实际上使用了随机搜索,这通常比搜索所有可能的值要好。通常,你想为许多不同的旋钮尝试许多不同的参数,而网格搜索(尝试每一种可能的组合)不是很有效。通常,你会像我们上面做的那样使用随机搜索(随机选择组合)。但是,因为我们只有少量的值,所以我们通过将 n_iter_search 设置为我们想要尝试的值的数量来强制进行网格搜索。
我们还将 cv=3 设置为 3 倍,并使用负 MSE,因为 scikit-learn 中的 cv 函数试图最大化一个值。
你可以在这里了解更多关于随机搜索和网格搜索:【http://scikit-learn.org/stable/modules/grid_search.html
此外,scikit-learn 还有许多其他 CV 函数,特别是如果您想要测试具有相同折叠的不同模型时,这些函数非常有用。以下是一些文档:http://sci kit-learn . org/stable/modules/cross _ validation . html
正规化
作为解释高方差模型的一种方法,我提到了正则化。您可以将正则化视为一种用于惩罚学习复杂关系的模型的方法。对于线性回归,有三种流行的方法。所有这些方法都围绕着限制我们的特征的系数可以有多大的思想。这个想法是,如果我们高估了一个预测因子(一个大的系数)的影响,很可能我们是过度拟合了。注意:我们仍然可以有大的系数。正则化只是说,MSE 的减少必须证明系数幅度的增加是合理的。
- L1 正则化(Lasso):将系数的绝对值之和添加到成本函数中。这种方法可以将系数强制为零,这可以作为特征选择的一种手段。
- L2 正则化(岭):你把系数的平方和加到成本函数中。
- 弹性网:你将两者相加,并选择它们的重量。
这些方法中的每一种都采用了一个加权因子,该因子告诉您应该对成本函数中的正则化项进行多少加权。在 scikit-learn 中,它被称为 alpha。alpha 值为零不会增加任何损失,而高 alpha 值会因为模型系数大而对模型造成很大损失。您可以使用交叉验证来发现 alpha 的一个好值。
Sklearn 让这变得简单:
from sklearn.linear_model import ElasticNetCV
# l1 ratio of zero is l2 and visa-versa
# alphas are how much to weight regularization
clf = ElasticNetCV(l1_ratio=[.1, .5, .7, .9, .95, .99, 1], alphas=[.1, 1, 10])
clf.fit(X_train, y_train)
train_predictions = clf.predict(X_train)
test_predictions = clf.predict(X_test)
print("Train MSE: {}".format(mean_squared_error(y_train, train_predictions)))
print("Test MSE: {}".format(mean_squared_error(y_test, test_predictions)))Train MSE: 23.500345265727802 Test MSE: 21.60819303537859
这里我们使用了具有内置交叉验证的 ElasticNetCV 函数,以便为 alpha 选择最佳值。l1_ratio 是给予 l1 正则化的权重。剩余的重量应用于 L2。
恭喜你!
如果你能走到这一步,恭喜你!这是一个吨的信息,但我保证,如果你花时间去吸收它,你会有一个非常坚实的了解线性回归和它可以做的许多事情!
此外,你可以在这里找到代码的更好的渲染版本。
R 中关系运算符的最终指南
关系运算符帮助我们了解对象之间的关系。学习你需要知道的一切来征服他们!
相等运算符==
关系操作符,或称比较符,是帮助我们了解一个 R 对象如何与另一个相关的操作符。
例如,您可以使用双等号==
来检查两个对象是否相等(相等)。
通过使用这个查询TRUE == TRUE
,我们可以看到TRUE
的逻辑值是否等于TRUE
的逻辑值。等式查询的结果是一个逻辑值(TRUE or FALSE
)。这种情况下是TRUE
,因为TRUE
等于TRUE
。
反之,TRUE == FALSE
会给我们FALSE
。
除了逻辑变量,我们还可以检查其他类型的相等性,比如字符串和数字。
# Comparing the equality of two strings
"hello" == "goodbye"# Comparing the equality of two numbers
3 == 2
这两个输出都是FALSE
。
让你试试
最基本的比较形式是平等。回想一下,它是由双方程语法表示的,==
。以下是一些等式语句的示例:
3 == (2 + 1)
"ultimate guide" == "r"
TRUE == FALSE
"Rchitect" == "rchitect"
从最后一个表达式注意到 R 是区分大小写:“R”不等于“R”。
尝试以下比较:
- 写 R 代码看
TRUE
是否等于FALSE
。 - 检查
-6 * 14
是否等于17 — 101
。 - 看字符串
"useR"
和"user"
在 r 中是否相等。 - 如果将
TRUE
与数字 1 进行比较,看看会发生什么。
确保不要混淆==
(比较)和=
(赋值),==
用于检查 R 对象的相等性。
解决办法
# Comparison of logicals
TRUE == FALSE# Comparison of numerics
(-6 * 14) == (17 - 101)# Comparison of character strings
"useR" == "user"# Comparison of a logical with a numeric
TRUE == 1
回想一下,真正的胁迫在引擎盖下 1。因此,逻辑真与数字 1 的比较结果为真。
不等式运算符!=
相等运算符的反义词是不等运算符,写为感叹号后跟等号(!=
)。
例如,句子"hello" != "goodbye"
读作:“你好”不等于“再见”。因为这个说法是正确的,所以 R 会输出TRUE
。
不等式运算符也可用于数字、逻辑和其他 R 对象。
# Output FALSE
TRUE != TRUE# Output TRUE
TRUE != FALSE# Output TRUE
"hello" != "goodbye"# Output TRUE
3 != 2
相等运算符的结果与不等运算符的结果相反。
让你试试
不平等比较器只是平等的反义词。以下语句都评估为TRUE
:
3 == (2 + 1)
"intermediate" != "r"
TRUE != FALSE
"Rchitect" != "rchitect"
写出执行以下操作的表达式:
- 检查
TRUE
是否等于FALSE
。 - 检查
— 6 * 14
是否等于而不是等于17 — 101
。 - 检查琴弦
“useR”
和“user”
是否不同。 - 检查
TRUE
和 1 是否相等。
解决办法
# Comparison of logicals
TRUE == FALSE# Comparison of numerics
(-6 * 14) != (17-101)# Comparison of character strings
"useR" != "user"# Compare a logical with a numeric
TRUE == 1
小于和大于运算符< and >
有些情况下,我们需要的不仅仅是等式和不等式运算符。例如,如何检查一个 R 对象是“小于”还是“大于”另一个 R 对象呢?在这种情况下,我们可以使用小于<
和大于>
符号。
在数值的情况下,这是非常简单的。比如 3 小于 5,那么3 < 5
会求值为TRUE
,而 3 大于 5 ( 3 > 5
)会求值为FALSE
。
对于数字来说,这是有意义的。但是这对于字符串和逻辑值是如何工作的呢?
对于字符串,R 使用字母表来排序。因此,"Hello" > "Goodbye"
将计算为TRUE
,因为在字母表中“H”在“G”之后,R 认为它更大。
对于逻辑值,TRUE
对应 1,FALSE
对应 0。那么TRUE
是不是小于FALSE
?不会,因为 1 不小于 0,所以有了FALSE
的结果。
小于等于和大于等于运算符<= and > =
我们还可以检查一个 R 对象是否大于或等于(或者小于或等于)另一个 R 对象。为此,我们可以使用小于号或大于号以及等号。
因此,大于或等于 3 的 5 个5 >= 3
,以及大于或等于 3 的 3 个3 >= 3
将被评估为TRUE
。
让你试试
除了等式运算符(==
和!=
,我们还学习了小于的和大于的运算符:<
和>
。我们还可以加一个等号分别表示小于等于或者大于等于*。例如,以下所有对FALSE
的评价:*
(1+2) > 4
"dog" < "Cats"
TRUE <= FALSE
请记住,对于字符串比较,R 根据字母顺序确定大于的关系。还要记住TRUE
在算术上被当作1
,而FALSE
被当作0
。所以FALSE < TRUE
就是TRUE
。
写 R 表达式检查是否:
-6 * 5 + 2
大于等于-10 + 1
。“raining”
小于或等于“raining dogs”
TRUE
大于FALSE
。
解决办法
# Comparison of numerics
(-6 * 5 + 2) >= (-10 + 1)# Comparison of character strings
"raining" <= "raining dogs"# Comparison of logicals
TRUE > FALSE
关系运算符和向量
从对矢量的介绍到后,我们已经知道 R 非常适合矢量。无需对语法做任何修改,R 的关系运算符也适用于向量。
假设您已经记录了 LinkedIn 个人资料在之前的链接中每天的浏览量,并将它们存储在一个 vector 中,linkedin
。
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
如果我们想知道哪一天的浏览次数超过了 10 次,我们可以直接使用大于号。
linkedin > 10
对于向量中的第一、第三、第六和第七个元素,视图的数量大于 10,因此对于这些元素,结果将是TRUE
。
我们也可以比较矢量和矢量。假设你还记录了你的脸书个人资料在上周的浏览量,并将它们保存在另一个 vector 中facebook
。
facebook <- c(17, 7, 5, 16, 8, 13, 14)
什么时候脸书的浏览量小于或等于 LinkedIn 的浏览量?我们可以用下面的表达式来计算。
facebook <= linkedin
在这种情况下,对向量的每个元素逐一进行比较。例如,在第三天,脸书的浏览量是 5,LinkedIn 的浏览量是 13。比较结果为TRUE
,因为 5 小于或等于 13。这意味着第三天脸书的浏览量小于或等于 LinkedIn 的浏览量。
让你试试
使用上面相同的社交媒体向量,linkedin
和facebook
,包含过去七天的个人资料浏览量,使用关系运算符为以下问题找到逻辑答案(TRUE
或FALSE
):
- LinkedIn 个人资料浏览量在哪些日子超过了 15 次?
- 什么时候你的 LinkedIn 个人资料只被浏览了 5 次或更少?
- 什么时候你的 LinkedIn 个人资料比你的脸书个人资料被访问的次数多?
# The linkedin and facebook vectors
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
解决办法
# The linkedin and facebook vectors
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)# Popular days
linkedin > 15# Quiet days
linkedin <= 5# LinkedIn more popular than Facebook
linkedin > facebook
你的 LinkedIn 个人资料在第六天非常受欢迎,但在第四天和第五天就没那么受欢迎了。
从输出中,我们可以确定以下内容:
- 在第一天和第六天,你的 LinkedIn 个人资料浏览量超过了 15。
- 在第四天和第五天,你的 LinkedIn 个人资料仅被浏览了 5 次或更少。
- 在第二、第三和第六天,你的 LinkedIn 个人资料的访问量超过了你的脸书个人资料。
挑战:比较矩阵
到目前为止,我们已经学习并比较了逻辑、数字、字符串和向量。然而,R 处理不同数据结构进行比较的能力并不仅限于矩阵。矩阵和关系运算符也可以无缝地协同工作!
假设,LinkedIn 和脸书的数据存储在一个名为views
的矩阵中,而不是存储在 vectors 中(就像前面给你尝试的那样)。第一行包含 LinkedIn 信息;第二行是脸书的信息。
# The social data stored in a matrix
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
views <- matrix(c(linkedin, facebook), nrow = 2, byrow = TRUE)
使用您所学的关系运算符,尝试确定以下内容:
- 什么时候视图正好等于 13?使用
views
矩阵返回一个逻辑矩阵。 - 哪几天的浏览量小于或等于 14?同样,让 R 返回一个逻辑矩阵。
解决办法
# The social data
linkedin <- c(16, 9, 13, 5, 2, 17, 14)
facebook <- c(17, 7, 5, 16, 8, 13, 14)
views <- matrix(c(linkedin, facebook), nrow = 2, byrow = TRUE)# When does views equal 13?
views == 13# When is views less than or equal to 14?
views <= 14
本练习总结了关于比较器的指南。你知道如何查询 R 对象之间的关系!
根据输出,我们可以确定:
- 第三天,LinkedIn 有 13 次浏览。在第 6 天,有 13 个脸书视图。
- 在第 2、3、4、5 和 7 天,LinkedIn 的浏览量少于或等于 14 次。在第 2、3、5、6 和 7 天,有少于或等于 14 个脸书视图。
笔记
所有图片,除非特别注明,均归作者所有。横幅图像是使用 Canva 创建的。
SMS 终极指南:使用 Python 的垃圾邮件或火腿分类器
人工智能概念的方法
开发垃圾邮件或火腿分类器的详细报告:第 2 部分
TL;博士从人工智能概念的角度理解垃圾邮件或火腿分类器,使用各种分类算法,选择高精度产生算法,开发 Python Flask 应用。
该博客是博文的系列,如果您还没有阅读垃圾邮件或火腿分类器的理论人工智能概念,请花十分钟阅读,网址:
开发垃圾邮件或火腿分类器的详细报告:第 1 部分
towardsdatascience.com](/the-ultimate-guide-to-sms-spam-or-ham-detector-aec467aecd85)
我们已经在 第一部分 中介绍过
- 关于垃圾邮件或火腿分类器的理论人工智能概念
- 分类算法
我们将在第 2 部分对此进行介绍
- 探索数据源
- 数据准备
- 探索性数据分析
我们将在接下来的 中覆盖第三部分
- 垃圾邮件或火腿背后的朴素贝叶斯
- 绩效衡量标准
- 垃圾邮件检测器的开发
探索数据源
该数据集最初来自巴西圣保罗的圣卡洛斯联邦大学(ufscar)索罗卡巴计算机科学系的 Tiago a . Almeida(talmeida UFSCar . br),并取自 UCI 机器学习【15】。
集合仅由一个文本文件组成,其中每一行都有正确的类,后跟原始消息。
属性存在于原始数据集中 。 图片作者。
数据集有 5 列和 5572 行。在这 5572 个数据点中,747 个中的类型被标记为垃圾邮件,4825 个被标记为“ham ”,并包含 3 个额外的列作为未命名的*: 2/3/4*,这是多余的。如果类型具有值 ham,则意味着该文本或消息不是垃圾邮件,但是如果类型的值是垃圾邮件,则意味着文本是垃圾邮件,并且文本没有按时间顺序排列。
原始数据集中的要素描述。图片作者。
查看原始数据集,很明显,为了开发高精度模型,应该进行一些预处理。
设置
我们将在 Jupyter 笔记本上完成这项工作,我假设您已经对使用 Jupyter 笔记本有了基本的了解。如果没有,请查看我以前的博客,在那里我分享了关于设置和探索性数据分析的初学者指南。
第一次做 EDA!
medium.com](https://medium.com/analytics-vidhya/exploratory-data-analysis-for-beginner-7488d587f1ec)
数据预处理
该数据集已经过预处理并被很好地标记。然而,在研究数据时,该项目发现数据可以进一步清理。我们选择省略未命名的列:2、未命名的列:3、未命名的列:4,因为它们不包含任何值,只会对模型产生干扰。
原始数据集预处理后出现的属性。图片作者。
在这个博客上,我将强调这个发现并解释重要的主题,但不会解释每一行代码。
你可以在 GitHub 上探索代码细节。
数据准备
因为分类算法需要某种数字特征向量来执行分类任务。实际上有许多方法可以将语料库转换为矢量格式。最简单的是单词袋方法。词袋是对象分类中最流行的表示方法之一。其核心思想是将每个提取的关键点量化为一个视觉单词,然后用视觉单词的直方图来表示每幅图像。[16].即文本中的每个唯一单词将由一个相应的数字来表示。为了实现单词袋,该项目需要删除非常常见的单词,如(’ the ‘,’ a '等…).并通过使用标记化概念将文本分割成单独的单词。
由作者设计。来自 unDraw 的插图。
标记化
将字符串转换或分解为单词和标点符号[17]的过程,即,将正常的文本字符串转换为标记列表,也称为词条。
标记化前后。图片作者。
…向量化…
将每个单词拆分后,需要将每个单词(词条)转换为 SciKit 学习算法模型可以使用单词袋模型的向量。为此,该项目使用词袋模型遵循两个步骤:
1.通过 CountVectorizer 计算一个单词在每条消息中出现的次数(称为词频)。
2.对计数进行加权,以使频繁出现的标记获得较低的权重(逆文档频率),并使用 TF-IDF 对术语进行加权和归一化。
计数矢量器
这个模型将把一个文本文档集合转换成一个令牌计数的二维矩阵。其中一维是整个词汇表(每个单词一行),另一维是实际的文档,在本例中是每个文本消息一列
TF-IDF
TF-IDF 代表词频-逆文档频率,而 TF-IDF 权重是信息检索和文本挖掘中经常使用的两个主要关注的权重。
1.用于评估一个单词对集合中的文档有多重要
2.重要性随着单词出现的次数成比例增加
TF-IDF 背后的两个想法:
词频(TF),又名。一个单词在文档中出现的次数,除以该文档中的总单词数,即它衡量一个术语在文档中出现的频率
逆文档频率(IDF),计算为语料库中文档数量的对数除以特定术语出现的文档数量,即它衡量术语的重要性[13]。
TF-IDF 的公式。
在计算 TF 时,所有项都被认为是同等重要的。然而,众所周知,某些术语,如“是”、“的”和“那个”,可能会出现很多次,但并不重要。
探索性数据分析
在探索性数据分析(EDA)周期中,我们看到了数字和非数字的长度特征和分布,还绘制了垃圾邮件和垃圾邮件的前 30 个单词。
EDA 循环一瞥。图片作者。
在预处理、矢量化并从 EDA 中获得一些见解后,该项目开始训练一个模型并使用七种不同的分类算法。
从博客的第一部分开始,我们对算法有了基本的了解,并在笔记本上使用它们,这里是从每个算法中获得的精度。
垃圾短信/垃圾短信分类算法及其准确性。图片作者。
通过使用七种算法,该项目发现朴素贝叶斯分类优于所有算法,因此该项目使用了朴素贝叶斯分类,该分类经验证具有简单性和高准确性[14]。
在下一篇博客文章中,我们将深入探讨垃圾邮件或业余爱好者分类器背后的朴素贝叶斯理论,并研究垃圾邮件或业余爱好者检测器的 python flask 代码。
直接想玩代码,那就请检查 GitHub 。
与最终产品互动
[## 垃圾短信|火腿
这个项目的数据集取自 UCI 机器学习行动执行的 EDA 算法使用 Bagging…
sms-spam-ham-detector.herokuapp.com](https://sms-spam-ham-detector.herokuapp.com/)
如果你对这篇文章有任何疑问,或者想在你的下一个数据科学项目上合作,请在 LinkedIn 上 ping 我。
推荐读物
参考
[13]洛克,E.K.( 2017 年 11 月 25 日)。第 1 集:使用 TF-IDF 从噪声中识别信号。检索于 2020 年 2 月 21 日,来自https://mungingdata . WordPress . com/2017/11/25/episode-1-using-TF-IDF-to-identify-the-signal-from-the-noise/
[14] Taufiq Nuruzzaman,m .,Lee,c .,Abdullah,M.F.A.b .和 Choi,D. (2012),独立移动电话上的简单垃圾短信过滤。安全通信网络,5:1209–1220。doi:10.1002/秒 577
[15]阿尔梅达,T. A .,&伊达尔戈,J. M. G. (2012 年 6 月 22 日)。垃圾短信收集数据集。检索于 2020 年 2 月 19 日,来自https://archive.ics.uci.edu/ml/datasets/sms垃圾邮件收集#
[16]张,杨,金,周,周志华(2010).理解词袋模型:一个统计框架。国际机器学习和控制论杂志,1(1–4),43–52。
[17]史蒂文,b .,克莱因,E. &洛珀,E .(2019 年 9 月 4 日)。用 Python 进行自然语言处理。检索于 2020 年 2 月 21 日,来自https://www.nltk.org/book/ch03.html
SMS 终极指南:使用 Python 的垃圾邮件或火腿分类器
人工智能概念的方法
开发垃圾邮件或火腿分类器的详细报告:第 3 部分
TL;博士从人工智能概念的角度理解垃圾邮件或火腿分类器,使用各种分类算法,选择高精度产生算法,开发 Python Flask 应用。
该博客是博文的一个系列,如果您没有读过垃圾邮件或火腿分类器的理论人工智能概念,也没有在 jupyter notebook 中使用过算法,请访问:
开发垃圾邮件或火腿分类器的详细报告:第 1 部分
towardsdatascience.com](/the-ultimate-guide-to-sms-spam-or-ham-detector-aec467aecd85) [## 短信终极指南:垃圾邮件还是火腿探测器
开发垃圾邮件或火腿分类器的详细报告:第 2 部分
towardsdatascience.com](/the-ultimate-guide-to-sms-spam-or-ham-detector-67c179bc94dc)
我们已经在第 1 部分& 2 中介绍过
- 关于垃圾邮件或火腿分类器的理论人工智能概念
- 分类算法
- 探索数据源
- 数据准备
- 探索性数据分析
我们将在第 3 部分对此进行介绍
- 垃圾邮件或火腿背后的朴素贝叶斯
- 绩效衡量标准
- 垃圾邮件检测器的开发
由作者设计。从展开的图示。
垃圾邮件或火腿背后的朴素贝叶斯
贝叶斯规则最有用的应用之一是所谓的朴素贝叶斯分类器。
朴素贝叶斯算法为 SMS 消息的分类创建了一个概率模型。尽管所有特征都对分类的总体概率有贡献,但朴素贝叶斯算法假设这些特征在统计上彼此独立[10]。虽然这种假设可能并不适用于所有情况,但与其他众所周知的分类算法相比,朴素贝叶斯算法已经显示出有希望的结果。朴素贝叶斯的一个优点是,它只需要少量的训练数据来估计分类所需的参数,并且由于数据集较小,朴素贝叶斯分类器可以胜过更强大的备选方案[18]。因为假设了独立变量,所以只需要确定每类变量的方差,而不是整个协方差矩阵。
贝叶斯法则。图片由尼尔斯雅各布沙
因此,对于垃圾邮件或 ham 中的 SMS 分类,项目想要计算的概率是:
图片由塞巴斯蒂安·拉什卡提供。
其中 x 是包含来自垃圾(或 Ham) SMS 文本的单词的特征向量[11]。
Prior(spam) =“任何新消息是垃圾消息的概率”
火腿 : P(火腿)= 1p(垃圾)
绩效衡量标准
它是正确分类的邮件的相对数量,正确分类的邮件的百分比用作评估过滤器性能的附加度量。然而,已经强调指出,使用准确性作为唯一的性能指标是不够的。必须考虑其他性能指标,如召回率、精确度、ROC 曲线下面积(AUC)和信息检索领域中使用的派生度量,决策理论中使用的假阳性和假阴性也是如此[12]。ROC 曲线及其相关曲线对于探索不同分类器在一系列成本上的权衡非常有用。粗略地说,曲线下的面积越大,性能越好。为了确定其他三个标准,首先项目应该定义一些术语:
真阳性(TP): 被正确分类的合法短信的比率。
误报(FP): 垃圾短信被正确分类的比率。
真阴性(TN): 合法短信被错误分类为垃圾短信的比率。
误报(FN): 垃圾短信被误认为合法短信的比率。
误报错误,它将合法的 SMS 转移为垃圾邮件,通常被认为比误报更严重。
现在,所谓的性能测量标准可以定义为:
模型的性能标准。图片作者。
实际上,召回决定了正确分类的合法消息(文本)的比例,精度决定了所有正确分类的合法消息(文本)的比例,准确性决定了所有正确分类的消息(文本)的比例。
从项目(见代码)上看使用朴素贝叶斯混淆矩阵是:
混淆矩阵值。图片作者。
这表明该项目确实有对称数据集,其中假阳性(14)和假阴性(15)的值几乎相同。因此,该项目不需要查看其他参数来评估模型的性能[19]。然而,出于研究目的,该项目计算了以下矩阵。
模型的性能矩阵。图片作者。
精度:精度是正确预测的正观测值与总预测正观测值之比。这个指标回答的问题是,在所有被标记为垃圾邮件的文本中,有多少实际上是垃圾邮件?高精度与低假阳性率相关。这个模型有 0.99 的精度,相当不错。
精密公式。图片作者。
****召回(灵敏度):召回是正确预测的正面观察值与实际类中所有观察值的比率——是的。回忆回答的问题是:在所有真正垃圾的文本中,模型标记了多少?该模型的召回率为 0.93,这对该模型来说是好的,因为它高于 0.5。
回忆公式。图片作者。
从代理、环境、PEAS 等人工智能概念开始,探索七种二进制分类算法,执行矢量化、TF-IDF、EDA,实现算法并从混淆矩阵、精确度、召回率评估性能,我们创建了基于 web 的 SMS:Spam 或 Ham 检测器。
结论
朴素贝叶斯分类算法是处理分类数据的有效方法。它使用的基本理论是贝叶斯条件概率模型,用于在给定特定条件下寻找后验概率。之所以称之为“天真”,是因为假设数据集中的所有特征(单词集合)都是同等重要和独立的。使用朴素贝叶斯分类算法,该项目根据垃圾邮件包含的单词预测垃圾邮件的准确率超过 98%。为了使预测更加准确,项目需要增加数据集中的数据数量。
我们的工作就此结束。现在,如果你想自己实现代码**,那么请访问我的 GitHub 并克隆这本书并玩它。**
与最终产品互动
**[## 垃圾短信|火腿
这个项目的数据集取自 UCI 机器学习行动执行的 EDA 算法使用 Bagging…
sms-spam-ham-detector.herokuapp.com](https://sms-spam-ham-detector.herokuapp.com/)**
如果你对这篇文章有任何疑问,或者想在你的下一个数据科学项目上合作,请在LinkedIn上 ping 我。
推荐读物
参考文献
[10] Androutsopoulos,I .,Koutsias,j .,Chandrinos,K. V .,Paliouras,g .,和斯皮罗普洛斯特区(2000 年)。对朴素贝叶斯反垃圾邮件过滤的评估。arXiv 预印本 cs/0006013。
[11] Chávez,G.(2019 年 2 月 28 日)“用五个步骤实现用于文本分类的朴素贝叶斯分类器”。检索于 2020 年 2 月 21 日,来自 https://towards data science . com/implementing-a-nave-Bayes-classifier-for-text-categorization-in-five-steps-f 9192 cdd 54 c 3
[12] Dada,例如 Bassi,J. S .,Chiroma,h .,Adetunmbi,A. O .,& Ajibuwa,O. E. (2019 年)。垃圾邮件过滤的机器学习:综述、方法和开放研究问题。Heliyon,5(6),e01802。
[16] P. Domingos 和 M. Pazzani,“零一损失下简单贝叶斯分类器的最优性”,机器学习,第 29 卷,第 2-3 期,第 103-130 页,1997 年
[19] Joshi,R.(2016 年 9 月 9 日)。“准确度、精确度、召回率和 F1 分数:性能指标的解释”。2020 年 3 月 5 日检索,来自https://blog . ex silio . com/all/accuracy-precision-recall-f1-score-interpretation-of-performance-measures/
SMS 终极指南:使用 Python 的垃圾邮件或火腿分类器
人工智能概念的方法
开发垃圾邮件或火腿分类器的详细报告:第 1 部分
TL;DR 从人工智能概念的角度理解 spam 或 ham 分类器,使用各种分类算法,选择高精度的产生算法并开发 Python Flask 应用程序用于 SMS: spam 或 ham 检测器。
最终产品。作者 Gif。
短信息服务(SMS)不仅仅是一种聊天技术。短信技术是从全球移动通信系统标准演变而来的,这是一个国际公认的标准[1]。垃圾邮件是对电子信息系统的滥用,不加选择地大量发送未经请求的消息[2]。虽然最广泛认可的垃圾邮件形式是电子邮件垃圾邮件,但该术语也适用于其他媒体和媒介中的类似滥用。在这种情况下,垃圾短信与电子邮件非常相似,通常是不请自来的带有某种商业利益的群发消息。垃圾短信被用于商业广告和传播钓鱼链接。商业垃圾邮件发送者使用恶意软件发送垃圾短信,因为发送垃圾短信在大多数国家是非法的。从受损机器发送垃圾邮件降低了垃圾邮件发送者的风险,因为它掩盖了垃圾邮件的来源。SMS 可以包含有限数量的字符,包括字母、数字和一些符号。浏览这些信息会发现一个清晰的模式。几乎所有的垃圾短信都要求用户拨打某个号码、回复短信或访问某个网址。通过对垃圾邮件语料库进行简单的 SQL 查询获得的结果可以观察到这种模式[3]。短信网络的低价格和高带宽吸引了大量的垃圾短信[4]。
人们将垃圾短信分为令人讨厌(32.3%)、浪费时间(24.8%)、侵犯个人隐私(21.3%)[5]。
每次垃圾短信到达用户的收件箱时,手机都会提醒用户有新消息。当用户意识到这条信息是不想要的,他或她会感到失望,而且垃圾短信会占用手机的一些存储空间。
垃圾短信检测是识别和过滤垃圾短信的一项重要任务。随着每天传送的 SMS 消息数量越来越多,用户很难记住在上下文中接收的较新的 SMS 消息并将其与先前接收的 SMS 相关联。因此,使用人工智能的知识与机器学习和数据挖掘的融合,我们将尝试开发基于 web 的 SMS 文本垃圾邮件或 ham 检测器。
这是博客系列的三个部分,我们将从人工智能概念的角度来理解垃圾邮件或火腿分类器的进出,并使用 jupyter notebook 中的各种分类算法,并根据性能标准选择一种算法。然后,我们将开发基于 Python web 的 SMS 文本垃圾邮件或 ham 检测器。
我们将在这里讨论什么内容
- 关于垃圾邮件或火腿分类器的理论人工智能概念
- 分类算法
- 探索数据源
- 数据准备
- 探索性数据分析
- 垃圾邮件或火腿背后的朴素贝叶斯
- 绩效衡量标准
- 垃圾邮件检测器的开发
代理描述
正如已经提到的,我们将从人工智能课程概念方面来做这个项目,所以,让我们来理解代理。
由于该项目设计简单,即代理可以根据代理类型将传入的文本(消息)分类为垃圾邮件或垃圾邮件[6];该项目代理属于简单反射代理,因为它仅基于当前环境情况采取行动,即,它将当前感知映射到适当的行动,而忽略感知的历史。映射过程是简单的基于规则的匹配算法,这里是朴素贝叶斯🤭。
垃圾邮件或火腿分类器的简单反射代理。图片作者。
代理功能
一种功能,它规定了代理响应每一个可能的感知序列的动作,即代理功能将感知映射为动作,代理程序与机器体系结构相结合,实现代理功能。
双态分类器中简单反射代理的代理程序功能。图片作者。
垃圾邮件分类代理的决策规则
代理函数**的决策规则。**图片作者。
代理环境
环境是围绕代理的一切,而不是代理本身的一部分。这是代理“生活”或操作的地方,并为代理提供感知的东西和移动的地方。环境类似于现实生活中的世界,具有它的一些特性。环境可以具有来自代理的各种属性[8]。
任务环境
任务环境也被称为 AI 代理的高级描述,可以用助记符 PEAS (性能、环境、执行器 、 【传感器】【9】)来记忆。任务环境及其属性特征对于垃圾短信或火腿分类器给出如下。
垃圾短信或垃圾邮件过滤器任务环境及其特征。图片作者。
**完全可观察:**在这里,代理不需要维护任何内部状态来跟踪世界,因为它基于朴素贝叶斯,假设数据集中的特征是相互独立的,并且不需要维护任何,并且代理传感器使其能够访问环境在任何时间点的完整状态。
**确定性:**因为我们可以预测代理(分类器)的行为,即当我们提供确定无疑的垃圾邮件文本(消息)时,代理的输出将是什么。
**情节性:**许多分类任务是情节性的[6]。代理可以基于每个当前的决定来分类垃圾邮件或 ham,而不管先前的选择,即,当前的决定不影响下一个文本是否是垃圾邮件,并且比顺序的简单得多,因为环境不需要提前考虑。
**静态环境:**作为项目,当代理(分类器)正在考虑动作(垃圾邮件或 ham)时,环境不会发生变化。
**离散:**由于智能体有固定(有限)数量的感知和动作。
**代理:**单个,因为环境中没有任何其他代理进行交互。
豌豆
- 性能指标:人工智能如何知道它正在做它应该做的事情?
- 环境:代理与什么环境交互?
- 致动器:AI 如何影响它的环境?
- 传感器:人工智能如何从环境中获取信息?
分类器的任务环境描述如下:
对垃圾邮件或 Ham 分类器的任务环境的描述。图片作者。
现在,我们对各种人工智能概念有了足够的理解,这些概念有助于我们创建一个机器学习产品。现在,让我们了解不同的分类器算法。
算法描述
机器学习算法可用于识别垃圾邮件或垃圾邮件,方法是为系统配备相应的标签,并使用训练好的模型进行预测或分类,因为项目目标是对垃圾邮件或垃圾邮件中的文本进行分类,这是二进制分类问题,因此项目将使用七种最适合二进制分类的算法[4]。
制袋材料
Bagging 使用了一种简单的方法,这种方法在统计分析中反复出现——通过合并多个估计值来改进一个估计值。Bagging 使用训练数据的引导抽样构建 n 个分类树,然后组合它们的预测以产生最终的元预测。
随机森林
随机森林或随机决策森林是一种用于分类、回归和其他任务的集成学习方法,该方法通过在训练时构建大量决策树并输出作为单个树的类(分类)或均值预测(回归)模式的类来操作[10] [11]。随机决策树纠正了决策树过度适应训练集的习惯[12]。
朴素贝叶斯
顾名思义,该算法假设数据集中的所有变量都是“天真的”,即彼此不相关。它被称为朴素贝叶斯或白痴贝叶斯,因为每个假设的概率计算都被简化了,使它们的计算易于处理[5]。朴素贝叶斯是一种病毒分类算法,主要用于获得数据集的基本准确性[2]。尽管这种算法很简单,但根据概率而不是大量的数据集来对短信信息进行分类要快得多。这有助于减少人工智能系统的负荷,并保持输出的可管理性和有效性。由于朴素贝叶斯分类器不需要经过训练的模型,因此实现起来简单快捷。这允许在真实数据上进行测试,而无需花费大量时间和金钱来开发模型。当它们被应用时,它们就可以做预测了。
额外树分类器
这就像随机森林。它构建了多个树,并使用随机的特征子集来分割节点,但有两个关键区别:它不引导观察值(意味着它在没有替换的情况下采样),并且节点是在随机分割而不是最佳分割时分割的。
支持向量机(SVM)
支持向量机(SVMs,也称为支持向量网络)是具有相关学习算法的监督学习模型,这些算法分析用于分类和回归分析的数据。给定一组训练样本,每个样本被标记为属于两个类别中的一个或另一个,SVM 训练算法建立一个模型,将新样本分配给一个类别或另一个类别,使其成为非概率二元线性分类器[13]。SVM 是二元分类的绝佳选择,因为 SVM 通过寻找将所有数据点与其他类的数据点分开的最佳超平面来对数据进行分类[3]。
由作者设计。从展开的插图。
KNN
基于 k-最近邻的分类是一种懒惰学习,因为它不试图构建一般的内部模型,而是仅存储训练数据的实例。根据每个点的 k 个最近邻的简单多数投票来计算分类。该算法实现简单,对噪声训练数据具有鲁棒性,并且如果训练数据是大量的,则该算法是有用的。然而,缺点是它需要确定 K 的值,并且计算成本高,因为它需要计算每个实例到所有训练样本的距离。
决策树分类
分裂标准的原则是任何决策树分类器智能的基础。决策树类似于具有树形结构的流程图,其中实例根据其特征值进行分类。决策树中的一个节点代表一个实例,测试结果由分支描述,叶节点代表类标签。
因此,我们从人工智能的角度对垃圾邮件或业余爱好者分类器有了一个基本而健康的了解,并了解了不同的二进制分类算法。
第二部 | 第三部
在下一篇博客中,我们将进入数据集,选择最佳算法来制作基于 web 的垃圾邮件或 ham 分类器。
直接想玩代码,那就请检查 GitHub 。
与最终产品互动
[## 垃圾短信|火腿
这个项目的数据集取自 UCI 机器学习行动执行的 EDA 算法使用 Bagging…
sms-spam-ham-detector.herokuapp.com](https://sms-spam-ham-detector.herokuapp.com/)
如果你对这篇文章有任何疑问,或者想在你的下一个数据科学项目上合作,请在LinkedIn上 ping 我。
推荐读物
参考文献
[1] J. Brown,B. Shipman 和 R. Vetter,“SMS:短消息服务”,载于《计算机》,第 40 卷,第 12 期,第 106-110 页,2007 年 12 月。
[2] B .惠特沃思和 e .惠特沃思,“垃圾邮件和社会技术差距”,《计算机》,第 37 卷,第 38-45 页,2004 年。
[3] Hedieh Sajedi,Golazin Zarghami Parast,Fatemeh Akbari。基于机器学习技术的垃圾短信过滤:综述。机器学习研究。第 1 卷,2016 年第 1 期,第 1–14 页。doi:10.11648/j . MLR 2016 01.11
[4] Yoon J,Kim H,Huh J .用于移动通信的混合垃圾邮件过滤。计算机与安全杂志 2010;29(4):446–459.DOI:10.1016/j.cose
[5] Joe I,Shim H .一个使用支持向量机的垃圾短信过滤系统。《未来一代信息技术学报》, 2010 年 12 月;577–584,DOI:10.1007/978‐3‐642‐17569‐5 _ 56。
[6]拉塞尔、斯图尔特·J 和彼得·诺维格。人工智能:现代方法。新泽西州恩格尔伍德克利夫斯出版社,1995 年。打印。
[7] Raschka,S.(2014),朴素贝叶斯和文本分类——介绍和理论,2020 年 2 月 5 日检索自https://sebastianraschka . com/Articles/2014 _ nave _ Bayes _ 1 . html # References
[8]智能代理。(2008).2020 年 3 月 1 日从 http://en.wikipedia.org/wiki/Intelligent_agents检索
[9]人工智能/AI 代理及其环境。2020 年 3 月 1 日检索,来自https://en . wikibooks . org/wiki/Artificial _ Intelligence/AI _ Agents _ and _ their _ Environments
[10] Androutsopoulos,I .,Koutsias,j .,Chandrinos,K. V .,Paliouras,g .,和斯皮罗普洛斯特区(2000 年)。对朴素贝叶斯反垃圾邮件过滤的评估。arXiv 预印本 cs/0006013。
[11] Chávez,G.(2019 年 2 月 28 日)“用五个步骤实现用于文本分类的朴素贝叶斯分类器”。检索于 2020 年 2 月 21 日,来自 https://towards data science . com/implementing-a-nave-Bayes-classifier-for-text-categorization-in-five-steps-f 9192 cdd 54 c 3
[12] Dada,例如 Bassi,J. S .,Chiroma,h .,Adetunmbi,A. O .,& Ajibuwa,O. E. (2019 年)。垃圾邮件过滤的机器学习:综述、方法和开放研究问题。Heliyon,5(6),e01802。
[13]洛克,E.K.( 2017 年 11 月 25 日)。第 1 集:使用 TF-IDF 从噪声中识别信号。2020 年 2 月 21 日检索,来自https://mungingdata . WordPress . com/2017/11/25/episode-1-using-TF-IDF-to-identify-the-signal-from-the-noise/
迁移学习的终极指南
什么是迁移学习?我能在哪里使用它?我为什么要用它?怎么用?请继续阅读,寻找答案!
图片来自 Unsplash
介绍
迁移学习是机器学习领域中广泛使用的技术,主要用于计算机视觉和自然语言处理。
在本帖中,我们将详细解释它是什么,什么时候应该使用它,为什么它是相关的,并展示如何在自己的项目中使用它。
一旦你准备好了,躺下,放松,让我们开始吧!
TL;博士!
- 什么是迁移学习?
- 为什么迁移学习很牛逼?
- 什么时候应该使用迁移学习?
- 如何使用迁移学习?
- 结论和更多资源。
1)什么是迁移学习?
我们将看到该技术的各种定义,从不同的角度阐明它是什么,并便于理解。
从底层开始,仅从名字我们就可以大致了解迁移学习可能是什么:它是指从一些已经学过的先前知识出发,对某项任务的学习。这个先前的知识已经被从第一个任务转移到第二个任务。
还记得你学乘法的时候吗?你的老师可能会说类似“M 乘就是 X 乘以相加”这样的话。
因为你已经知道如何加法,你可以很容易地通过思考’2 乘以 3 就是把 2 乘以 3 相加。二加二等于四。用前面的结果再重复一次,得到三个加法。四加二等于六。这意味着二乘三等于六!我是天才!’
可能不完全是这样,但心理过程可能是相似的。除了学习乘法之外,你还转移了你所学的知识。
与此同时,你可能学过乘法表,这使得你以后可以轻松地进行乘法运算,而不必经历整个加法过程。然而,开始是知道如何求和。
迁移学习的直觉和一个简单的例子。图片作者。
在 Ian Goodfellow 等人的名著 深度学习中,迁移学习是这样描述的。你可以在这里找到这本巨著的精彩评论。
迁移学习和领域适应指的是这样一种情况,即在一种环境中所学的知识被用来提高在另一种环境中的概括能力
正如你所看到的,最后一个解释更加精确,但仍然适用于我们简单的、最初的解释:在一种设置(加法)中学习的一些技能可以用于在另一种设置(乘法)中提高性能或速度。
最后,在我们看到迁移学习为什么如此强大之前,让我们来看一个更正式的定义,关于域( D ) 、任务( T )和一个特征空间 X 以及一个边际概率分布 P(X) *。*事情是这样的:
给定一个特定的域 D = {X,P(X)} ,一个任务由两部分组成:一个标签空间 Y 和一个目标预测函数***,它是从带标签的数据对* {xi,易】 中学习得到的,可以用来预测相应的标签f(t)因此任务可以表示为 T = {y,f(·)}。****
然后,给定一个源域 Ds ,和一个学习任务 Ts ,一个目标域 Dt ,和一个学习任务【TT***,迁移学习旨在帮助提高目标预测函数ft()[1]*
****牛逼!现在,我们已经看到了 3 个不同的定义,按复杂程度递增。让我们看一个快速的例子来完成对什么是迁移学习的理解。
计算机视觉中的迁移学习
计算机视觉是迁移学习使用最广泛的领域之一,因为 CNN 算法如何学习拾取图像的低级特征,这些特征可用于不同范围的任务视觉,还因为训练这些类型的模型在计算上是多么昂贵。
正如我们将在后面看到的,在这个领域有很强的理由使用迁移学习,但让我们先看一个例子。想象一个卷积神经网络,它已经被训练用于对不同的常见对象进行分类,例如上下文中的常见对象(COCO)数据集。想象一下,我们想要建立一个分类器来执行一个更加具体和狭窄的任务,比如识别不同类型的糖果(Kit-Kats,Mars Bars,Skittles,Smarties),对于这些我们只有很少的图像。
然后,我们最有可能采用在 COCO 数据集上训练的网络,使用迁移学习,使用我们的小型糖果数据集对其进行微调,并实现相当好的性能。
使用在 COCO 数据集上训练的网络上的迁移学习来检测不同的糖果。图片来源于 Unsplash 。
好了,在这个简单的例子之后,让我们看看为什么我们要使用迁移学习。
2)为什么迁移学习很牛逼?
在前面的例子中,我们看到了迁移学习的一些好处。许多问题非常具体,很难找到大量数据来解决它们,并取得中等程度的成功。
此外,软件开发中有一个基本概念,我认为如果采用得当,可以节省我们很多时间:
我们不必重新发明轮子!
人工智能社区如此之大,而且有如此多的公共工作、数据集和预先训练的模型,从头开始构建一切几乎没有意义。说到这里,这是我们应该使用迁移学习的两个主要原因:
- 训练一些机器学习模型,特别是处理图像或文本的人工神经网络,会占用大量时间,并且计算量非常大。迁移学习可以减轻这种负担,它给我们一个已经训练好的网络,只需要一些后期微调。
- 获取某些任务的数据集(例如分类糖果图像的数据集,或者自然语言处理问题的特定数据集)是非常昂贵的。迁移学习允许我们在这些狭窄的任务中获得非常好的结果,使用的数据集比我们在没有它的情况下面对问题时所需的数据集要小得多。
不要忘记,迁移学习是一种优化:节省培训时间的捷径,解决一个你无法用现有数据解决的问题,或者只是为了达到更好的表现。
3)什么时候应该使用迁移学习?
****好的,好的!既然我们知道了什么是迁移学习,以及为什么要使用它,那么我们来看看什么时候应该使用 TL!
首先,要使用迁移学习,数据的特征必须是通用的,这意味着它们必须适合源任务和目标任务。这通常发生在计算机视觉中,其中用于训练的算法的输入是图像的像素值,以及它们的特定标签(用于检测的类或边界框)。很多时候这也是自然语言处理中发生的事情。
如果这两个问题没有共同的特征,那么应用迁移学习就会变得更加复杂。这就是为什么具有结构化数据的任务在迁移学习中更难找到,因为特征必须总是匹配。
其次,正如我们之前看到的,当我们有大量数据用于源任务,而很少数据用于后验或目标任务时,迁移学习是有意义的。如果我们在两个任务中有相同数量的数据,那么迁移学习就没有太大的意义。
第三个也是最后一个,初始任务的低级特征必须有助于学习目标任务。如果你试图从一组云数据中使用迁移学习来学习对动物图像进行分类,结果可能不会太好。
简而言之,如果你有一个源任务 A 和一个你想做好的目标任务 B,在下列情况下考虑使用迁移学习:
- 任务 A 和 B 有相同的输入 x。
- 任务 A 的数据比任务 b 多得多。
- 来自任务 A 的低级特征必须对学习任务 b 有帮助。
好吧!既然我们现在知道了什么、为什么和什么时候,那就让我们以如何结束吧。
4)如何使用迁移学习?
使用迁移学习有两个主要的选择:使用预先训练的模型,或者使用初始任务的大量可用数据集建立源模型,然后使用该模型作为第二个感兴趣的任务的起点。
许多研究机构发布大型和挑战性数据集上的模型,这些数据集可能包含在候选模型池中以供选择。正因为如此,网上有很多预先训练好的模型,所以很有可能有一个适合你具体问题的。
如果没有,您可以获取一个可能与您的数据集相似的数据集,使用它来训练初始源模型,然后使用您可用于第二个任务的数据来微调该模型。
无论哪种方式,都需要使用我们的特定数据进行第二个训练阶段,以将第一个模型调整到我们想要执行的确切任务。让我们看看这是如何在人工神经网络环境中发生的:
- 我们用网络的结构和预先训练的权重。
- 我们移除最后一层(输出层)。
- 我们用不同的输出层或不同层的组合来替换该层。
- 我们用第二个任务的数据进行训练。第二次训练可以仅修改新添加的层的权重(如果我们只有非常少的数据,则推荐)或整个网络的权重。
用新的头层替换输出层。来源网络来自 dair.ai
在实践中,我们很少需要手动完成这项工作,因为大多数允许使用迁移学习的框架为我们透明地处理这项工作。如果你想在任何项目中使用迁移学习,这里有一些很棒的资源供你参考:
- Darknet 计算机视觉库。
- 许多使用单词嵌入的 NLP 项目,如 GloVe 和 Word2Vec,允许对特定词汇的嵌入进行微调,这实际上是一种迁移学习的形式。如果你不知道什么是单词嵌入,你可以查看这里的了解它们。
- 用于对象分割的掩模 R-CNN 也使用来自 COCO 数据集的迁移学习。
5)结论和额外资源
就是这样!一如既往,我希望你喜欢这篇文章,并且我设法帮助你理解什么是迁移学习,它是如何工作的,以及它为什么如此强大。
如果你想了解更多关于机器学习和人工智能的知识,可以查看 本资源库 了解更多关于机器学习和 AI 的资源!
如果您想了解有关该主题的更多信息,您可以在这里找到一些附加资源:
- Cafe model Zoo:GitHub 储存库,拥有大量预先训练好的模型。
- Andrews Ng 关于迁移学习的视频。
- 论文:深度迁移学习综述。
- 另一个资源库 有很多关于机器学习和人工智能的进一步资源。
感谢您的阅读,祝您度过美好的一天!
[1] 维基百科:迁移学习
撰写基于数据的报告的终极指南
有效地交流您的数据见解。
数据探索和分析仅仅是开始,真正的业务影响来自交流结果的能力。
介绍
在 Kyso ,我们正在建立一个中央知识中心,数据科学家可以在这里发布报告,这样每个人——我们指的绝对是每个人——都可以从中学习,并将这些见解应用到整个组织中他们各自的角色中。我们以一种所有人都能理解的方式呈现数据团队使用的工具,从而在技术利益相关者和公司其他人之间架起了一座桥梁。
但是,尽管我们为数据工程师、科学家和分析师提供了一个空间来发布他们的报告并在内部传阅,但这些报告是否会转化为商业行动,取决于产生的见解如何呈现并传达给读者。任何数据团队都可以创建分析报告,但并非所有团队都在创建可操作的报告。
本文将讨论任何数据分析报告的最重要的目标,并带您了解在撰写每份报告时需要记住的一些最重要的提示。
报告目标
任何数据探索和分析的最终目标都不是从公司数据中生成有趣但任意的信息,而是发现可操作的见解,并在报告中有效传达,这些报告可随时用于企业,以做出更多基于数据的决策。
为了实现这一点,在编写基于数据的报告时,有三个基本准则需要遵循和不断参考:
- **意图:**这是你对项目的总体目标,你进行分析的原因,并且应该表明你期望分析如何有助于决策。
- **目标:**目标是你为实现上述目标正在采取或已经采取的具体步骤。这些应该很可能构成报告的目录。
- **影响:**您的分析结果必须是可用的——它必须为导致分析的问题提供解决方案,以影响业务行动。任何不会引发行动的信息,不管多小,都是无用的。
现在让我们深入了解细节—如何实际构建和编写最终报告,该报告将在整个企业内共享,供技术和非技术受众使用。
构建报告
与任何其他类型的内容一样,你的报告应该遵循特定的结构,这将有助于读者构建报告的内容&从而便于阅读。该结构应该类似于:
- **介绍:**每一份报告都需要一个强有力的介绍。这是你向读者介绍项目的地方,进行分析的原因&你期望通过这样做达到什么目的。这也应该是你布置目录的地方。
- **方法论:**这不需要技术。简单描述您使用的数据和您进行的分析类型&为什么。
- **结果:**这是报告的主体,可能会根据报告试图回答的各种业务问题分成几个部分&每个问题生成的结果。
- 决策建议:好了,你已经完成了项目,运行分析&生成你的结果。基于这些见解,推荐的业务行动是什么?客观一点。
- **结论:**从项目的起始目标到推荐的决策结果,将整个报告联系起来(如果可能的话,用一个单独的段落)。在这最后一部分,你可以添加自己的个人风格——从你的角度来看,这些结果意味着什么&也许是你对该主题未来分析的建议。
写报告
1.考虑你的目标受众
你的报告是写给谁的?如果是销售线索,强调他们部门评估业绩的核心指标。如果是给首席执行官的,一般来说最好是展示商业亮点,而不是一页页的表格和数字。
记住他们要求报告的原因&尽量不要偏离这个原因。
2。有明确的目标
如前所述,在文章开头就要清楚地解释你的文章将会是关于什么的,以及你所使用的数据。如有必要,提供一些相关主题的背景&解释你为什么要写这篇文章。
3.组织你的写作
确定你的论点的逻辑结构。有开头,有中间,有结尾。提供一个目录,相应地使用标题和副标题,这给读者一个概述,并有助于他们在阅读文章时定位——如果你的内容很复杂,这尤其重要。
通过适当的章节、段落和句子,力求通篇逻辑流畅。保持句子简洁明了。最好在每一段中只阐述一个概念,这个概念可以包含主要观点和支持信息,这样读者的注意力可以立即集中在最重要的东西上。
不要在结论中引入报告中未分析或讨论过的内容。
4.强势开始
写一个强有力的介绍会使报告更容易保持良好的结构。你的介绍应该列出目标、问题定义和采用的方法。
强有力的介绍也会吸引读者的注意力,并诱使他们进一步阅读。
5.客观一点
你报告中的事实和数字应该不言自明,不需要任何夸张。尽可能保持语言的清晰和简洁。
客观的风格有助于你将你发现的见解保持在争论的中心。
6.不要过度
最好是让你的报告尽可能清晰简洁。如果包含更多有用的信息,而这些信息对报告的核心目标来说是不必要的,那么你最核心的论点就会丢失。
如果绝对有必要,附上一个支持附录,或者你甚至可以发表一个系列,每个报告都有自己的核心目标。
7.绘图库
交互式绘图库— Altair、Plotly 和 Bokeh
有许多观想工具可供你使用。对于静态绘图或非常独特或定制的绘图,您可能需要构建自己的解决方案, matplotlib 和 seaborn 是您的答案。
然而,如果你真的想讲述一个故事,并让读者沉浸在你的分析中,互动是一条出路。你的两个主要选项是散景和 plotly 。两者都是非常强大的声明库,值得考虑。
不管你选择哪一个,我们建议选择一个库并坚持使用它,直到有一个令人信服的理由改变。
Altair 是另一个(更新的)声明式轻量级绘图库,值得考虑。点击查看其图库。
虽然 Plotly 已成为交互式可视化的领导者,但由于它存储了用户浏览器会话中生成的每个绘图的数据,并呈现了每个交互式数据点,因此如果您正在处理多个绘图或非常大的数据集,它确实会减慢您的报告的加载时间,这会对读者的体验产生负面影响。
如果您正在生成大量的图表或正在处理非常大的数据集,但希望保持交互性,请使用散景或 Altair。
8.避免过度使用图形
图表、图形和表格是将数据总结成易于记忆的视觉效果的好方法。尽量不要用太多本质上显示同一事物的图形来打断报告的流程。选择最符合该段落的图表、图形或表格,然后继续下一点。
9.记录您的图表!!!
绘制图表时,确保图表上方或下方有说明性文字——向读者解释他们在看什么,并带他们浏览从每次观想中得出的见解和结论。
没有图表标题,没有图例或 y 轴标题。
标记图表中的所有内容,包括轴和色阶。如有必要,创建一个图例。
好的文档带来的不同!
10.隐藏您的代码
当你写一份报告给整个组织中的非技术业务代理使用时,隐藏你的代码。对于这些用户来说,你如何生成你的图表并不重要,重要的是他们展示的视觉效果和洞察力。
代码隐藏。
自然地,如果你正在为你的数据科学家和分析师同事写一个指南或者一个特别的技术文章,其中你经常提到代码,你应该默认显示它。
显示代码。
最后的想法
我们做到了!每次写基于数据的报告时都要遵循的 10 条建议。关于结论的一个注意事项——不要只是在文章的结尾逐渐减少,或者在正文中以最后一点结束。向读者快速总结他们所学到的内容,解释这些见解如何对业务产生影响,以及他们如何在工作中应用这些知识。
确保您的分析对整个公司的其他创建者也是可重复的-在开发数据科学项目或发布研究时,遵循编码最佳实践总是一个好主意,包括使用正确的目录结构、语法、说明性文本(或代码单元格中的注释)、版本控制,最重要的是,确保所有相关文件和数据集都附加到帖子中。号召行动——也许是扩展分析的建议。
最后,同样重要的是,添加适当的标题、描述、标签和预览图片。无论你使用哪种策展系统,这对于组织团队的工作都很重要——展示是关键。
编写更好的 Python 代码的终极指南
让你的软件更快、更易读和更易维护并不需要这么难
让您的 Python 代码更上一层楼。戴维·克洛德在 Unsplash 上的照片
D 尽管有的缺点,Python 仍然是当今编程世界的王者。它的多功能性、初学者友好性和巨大的社区只是促成它在过去几年里巨大增长的几个因素。尽管像 Rust 、 Go 和 Julia 这样的新语言越来越受欢迎,Python 的统治可能会持续几年。
无论您是初学者还是经验丰富的工程师,您都可能经常与 Python 打交道。在这种情况下,稍微升级一下你的游戏是很有意义的。
开发人员不会编写一个东西,然后让它在未来几年保持不变。因此,好的代码不仅仅是关于速度和效率。这也是关于可读性和可维护性。
就像生活中的所有事情一样,没有什么灵丹妙药可以让你的代码达到一流的性能。有一些快速解决办法,比如高效的功能和方便的自动化。然而,要真正让你的代码发光,你还需要养成长期的习惯,比如让你的代码尽可能简单,并与你的风格保持一致。
通过掌握最新的 Python 特性、技术、技巧和诀窍来提高代码的质量…
towardsdatascience.com](/12-python-tips-and-tricks-for-writing-better-code-b57e7eea580b)
使用更高效的功能和结构
用 f 弦避免弦乐打嗝
从处理输入到在屏幕上打印消息,字符串是任何编程语言的重要组成部分。在 Python 中,有三种格式化字符串的方法:原始的%s
-方法、str.format()
,以及从 Python 3.6 开始的 f-字符串。
当你处理简短的表达时,古老的%s
方法很好。你需要做的就是用%s
标记出你想要插入字符串的地方,然后在语句后引用这些字符串。像这样:
>>> name = "Monty"
>>> day = "Tuesday"
>>> "Happy %s, %s. Welcome to Python!" % (day, name)'Happy Tuesday, Monty. Welcome to Python!'
这一切都很好,但是当您同时处理大量字符串时,就会变得混乱。这就是为什么 Python 从 2.6 版本开始引入了str.format()
。
实际上,%s
符号被花括号取代了。像这样:
>>> "Happy {}, {}. Welcome to Python!".format(day, name)
str.format()
的真正好处是你现在能够定义对象,然后在你的格式化语句中引用它们:
>>> greeting = {'name': 'Monty', 'day': 'Tuesday'}
>>> "Happy {day}, {name}. Welcome to Python!".format(day=greeting['day'], name=greeting['name'])
这是一个巨大的进步,但是 f 弦更简单。考虑一下这个:
>>> name = "Monty"
>>> day = "Tuesday"
>>> f"Happy {day}, {name}. Welcome to Python!"
这就更简单了!不过,f 字符串更好的一点是,您可以在其中传递函数:
>>> f"Happy {day}, {name.upper()}. Welcome to Python!"'Happy Tuesday, MONTY. Welcome to Python!'
f 弦的最后一个优点是它们比其他两种方法更快。因为它们非常简单,所以从现在开始使用它们是很有意义的。
让你的代码更有效率。由 Kelly Sikkema 在 Unsplash 上拍摄的照片
使用列表理解
列表理解是一种在保持可读性的同时使代码更加简洁的好方法。考虑这段代码,我们试图将前几个平方数存储在一个列表中:
>>> square_numbers = [0, 1, 2, 3, 4]
>>> for x in range(5):
... square_numbers.append(x**2)
...
>>> square_numbers[0, 1, 2, 3, 4, 0, 1, 4, 9, 16]
这很笨拙,我们必须再次从列表中删除前几项。此外,我们仍然有变量x
浮动并占用内存。有了列表理解,这就变得简洁多了:
>>> square_numbers = [x**2 for x in range(5)]
>>> square_numbers[0, 1, 4, 9, 16]
语法相当简单:
new_list = [**expression** for **item** in **iterable** (if **conditional**)]
所以下次你准备用一个for
循环或者一个if
语句做一个列表的时候,请三思。每次都可以节省几行代码。
快速创建长度为 N 的列表
在 Python 中初始化列表很容易。但是你可以通过使用*
操作符来升级你的游戏,例如像这样的:
>>> four_nones = **[**None**]** * 4
>>> four_nones[None, None, None, None]
如果要创建一个列表列表,可以使用列表串联:
>>> four_lists = [[] for __ in range(4)]
>>> four_lists[[], [], [], []]
当你试图初始化长列表或者列表的列表时,这很方便。不仅更容易阅读和调试,而且也不太可能在列表的单个元素中出现拼写错误。
删除列表元素时要小心
考虑一个列表a
,我们想要删除所有等于bar
的条目。我们可以使用 for 循环来完成这项工作:
>>> a = ['foo', 'foo', 'bar', 'bar']
>>> for i in a:
... if i == 'bar':
... a.remove(i)
...
>>> a['foo', 'foo', 'bar']
但是还剩下一只bar
!发生了什么事?
当我处于位置 0 和 1 时,它正确地认识到这些元素不需要被删除。在i = 2
,它删除了bar
。现在第二个bar
移动到位置2
。但是现在循环已经结束,因为在i = 3
处不再有元素,因此第二个bar
仍然存在。
简而言之,当你从列表中删除项目时,不要使用for
循环。虽然你可以通过一些修正来避免这种错误,但是它们很容易出错。相反,列表理解再次派上了用场:
>>> foos = [value for value in a if value != 'bar']
>>> foos['foo', 'foo']
给你的代码增加一些优雅。照片由妮可·沃尔夫在 Unsplash 上拍摄
优雅地访问字典元素
使用dict.get()
来访问字典的元素既笨拙又容易出错。考虑这个例子:
>>> d = **{**'hello': 'world'}
>>> if d.has_key('hello'):
... print d['hello'] *# prints 'world'*
>>> else:
... print 'default_value'
如果您使用dict.get()
,会简洁得多:
>>> d.get('hello', 'default_value') *# prints 'world'*
>>> d.get('thingy', 'default_value') *# prints 'default_value'*
或者,如果你想更短,你可以写:
>>> if 'hello' in d:
... d['hello']
用*、**和 _
当你有一个列表,但你不需要所有的参数,你会怎么做?为此,您可以使用_
:
>>> numbers = [1, 2, 3]
>>> a, b, _ = numbers
>>> a
1
下划线通常用来告诉程序员这个变量不值得记住。虽然 Python 确实记住了变量,但是使用这种约定增加了代码的可读性。
如果您有一个很长的列表,但您只对前几个或后几个变量感兴趣,您可以这样做:
>>> long_list = [x for x in range(100)]
>>> a, b, *c, d, e, f = long_list
>>> e
98
以*
开头的变量可以包含任意数量的元素。在本例中,我们创建了一个从 0 到 99 的列表,并对前两个和后三个元素进行了解压缩。具体来说,倒数第二个元素e
是 98,这是我们所期望的。
您还可以使用*
操作符向函数传递任意数量的参数:
>>> def printfunction(*args):
... print(args)
>>> printfunction(1,2,3,4,5,6)(1, 2, 3, 4, 5, 6)
最后,您可以使用**
操作符将整个字典传递给一个函数:
>>> def myfriendsfunction(name, age, profession):
... print("Name: ", name)
... print("Age: ", age)
... print("Profession: ", profession)
>>> friendanne = {"name": "Anne", "age": 26, "profession": "Senior Developer"}
>>> myfriendsfunction(**friendanne)Name: Anne
Age: 26
Profession: Senior Developer
这些是访问变量的快速简单的方法,没有太多的麻烦。把它们记在心里!
自动打开和关闭文件
打开文件的传统方式意味着您需要再次关闭它们:
>>> newfile = open("file.txt")
>>> data = newfile.read()
>>> print(data)
>>> newfile.close()
通过使用with open
,您可以节省一行代码和引入 bug 的可能性:
>>> with open('file.txt') as f:
>>> for line in f:
>>> print line
这样,即使在with
块中出现异常,文件也会再次关闭。
使用这些快速提示加快编码速度。安妮·斯普拉特在 Unsplash 上的照片
快速获取信息
在转到 StackOverflow 之前,请使用 help()
如果你想看看一个函数是做什么的,只需使用help()
。如果你原则上知道你在做什么,但是不太确定函数的细节,这是很有用的。
您还可以通过在自己的函数中添加帮助信息来简化您的工作。这很容易做到:
>>> def mynewfunction(arg1, arg2):
... """
... This function does something really cool.
... Hope that helps!
... """
>>> help(mynewfunction)This function does something really cool.
Hope that helps!
这个帮助消息是一个 docstring,作为代码的文档也很有用。在这个例子中,您显然需要向函数添加一个主体,并使消息更加具体。但是你明白了。
使用 dir()了解属性和方法
如果你不太清楚一个对象是如何工作的,dir()
可以帮助你。它返回您希望了解的任何函数、模块、列表、字典或其他对象的属性和方法。
从 Python 2.7 开始,可以使用dir()
函数。所以对于大多数 Python 用户来说,使用这个可能是一个不错的选择。
使用 getsizeof()优化您的内存
如果你的程序运行缓慢,你认为这与内存问题有关,你可以用getsizeof()
检查你的对象,以了解问题的症结所在。这相当容易:
>>> import sys
>>> x = [1, 2, 3, 4, 5]
>>> sys.getsizeof(x)112
因为在我的机器上,x
是一个由五个 24 位整数组成的向量,所以它占用 112 位内存是完全合理的。注意,根据您的机器、架构和 Python 版本,这个数字会有所不同。
使文档更容易
选择您的 docstring 风格并坚持下去
如上所述,将 docstrings 添加到所有的模块、函数、类或方法定义中是一个非常好的主意。
为了使你的代码尽可能的可维护和可读,你应该选择一种 docstring 风格并坚持下去。如果你正在合作一个项目,确保你从一开始就决定了一种风格。这使得以后阅读和添加到文档中变得更加容易。
您代码版本
大多数软件项目都有一个三位数的版本号,例如“Python 3.8.4”。这个系统很简单——如果你做了一些小的改动或错误修正,你可以修改最后一个数字,如果要做更大的改动,你可以修改中间的数字,如果要做更基本的改动,你可以修改第一个数字。
即使您的项目很小,保留所有的旧副本并对它们进行编号也有一些好处。如果你试图修复一个 bug,但是你最终破坏了一些东西,你总是可以回到最新的版本。如果你的项目不是向后兼容的,保留旧的拷贝是至关重要的。此外,这种编号方案创建了一个整洁的更改日志,您可以在以后参考。
在协作时,适当的文档记录是至关重要的。安妮·斯普拉特在 Unsplash 上的照片
定期领取
如果你正在合作或从事一个开源项目,这是必须的:把你的代码放在 Github、Gitlab 或任何你希望你的代码存在的地方。这样,任何人都可以在任何时间访问它。
此外,确保你经常得到它。这不仅让每个人都了解最新情况;这也是你的代码被维护并且仍然相关的标志。
保留变更日志
即使你使用了文档字符串并对你的版本进行了一致的编号,那也不能捕捉到你所做的所有改变。为了保证细节的安全,最好有一个单独的文档来详细解释所有的更改。
即使这几乎与最终用户无关,您的变更日志对您自己和您的同事来说都是一份有价值的文档。人类的大脑忘记得很快,现在对你来说完全显而易见的事情在两周内往往变得相当模糊。
使用长的描述性变量名
你注意到上面的例子了吗?函数和变量的名字几乎总是很长。这不是巧合。
对于一小段代码来说,使用如此多的字符似乎是多余的,但是对于阅读代码来说,这要好得多。此外,编写代码不会花太多时间——大多数编辑器都有自动完成功能。
使用 PEP 8
也许你是那种代码可以运行但格式不规范的开发人员。虽然这听起来可能没那么悲惨,但它会带来一大堆问题。更不用说那些试图阅读你的代码的同事了…
所以帮你自己一个忙,用官方 Python 风格指南 PEP 8 格式化你的代码。别担心,你不需要学习每一个细节,也不需要重构你的每一段代码。您可以自动检查您的代码是否符合pycodestyle
。在您的 shell 中,安装软件包,然后在您的 Python 文件上运行它:
$ pip install pycodestyle
$ pycodestyle my_file.py
这表明您需要在哪里进行调整,以便您的文件符合 PEP 8。如果您想让您的文件自动符合,您可以使用autopep8
:
$ pip install autopep8
$ autopep8 --in-place my_file.py
评论很好
关于评论是好是坏有一个持续的争论。一些程序员认为好的代码可读性很强,你不需要任何注释。其他人希望你评论每一行。
除非你是一个纯粹主义者,否则你至少会时不时地发表评论。无论如何,确保你的评论简明扼要。我喜欢思考,如果有人从来没有看过我的代码,但现在因为他们想改变什么而看了一下,他们会喜欢读什么。这种方法效果很好。
养成好习惯
使线路延续更加稳定
原则上,您可以在每行的末尾用\
、分割多行表达式,就像这样:
>>> big_string = """This is the beginning of a really long story. \
... It's full of magicians, dragons and fabulous creatures. \
... Needless to say, it's quite scary, too."""
然而,这很容易出错,因为如果在\
后面加上一个字符,即使只是一个空格,它也会停止工作。最好这样分:
>>> big_string = (
... "This is the beginning of a really long story. "
... "It's full of magicians, dragons and fabulous creatures. "
... "Needless to say, it's quite scary, too."
... )
然而,大多数时候,多行表达式是你把事情过于复杂的标志。
不要写意大利面条代码
这应该是显而易见的,但令人震惊的是,许多初级开发人员仍然编写单片代码。但是没有人阅读一千行代码…
因此,请确保您定义了函数,并在必要时调用它们。这将使你的代码可读性提高一千倍,你的同事也会因此而感谢你。
从长远来看,保持一些好习惯并改进你的代码。照片由阿里夫·里扬托在 Unsplash 上拍摄
每行只使用一条语句
这是一个类似的方向。不要做这样的事情:
print("one"); print("two")
它可能看起来很复杂,但它不是。当您在某一行中遇到错误时,您会希望确切地知道该行做了什么,以便可以快速地调试它。所以分了吧;各行各业。
使用类型提示
Python 是一种动态类型语言。虽然这对快速生成代码很有好处,但也会使调试变得更加困难。
从 Python 3.5 开始,可以通过添加类型提示来为调试做准备。这不会影响代码,因为解释器会忽略它。但是这对你很有帮助,因为你可以立即看到你是否传递了错误的东西给一个函数。
类型提示的工作方式如下例所示:
>>> def sayhello(day:str, name:str) -> str:
... return f"Happy {day}, {name}. Welcome to Python!"
:str
表示函数的参数应该是字符串,-> str
部分表示函数应该返回一个字符串。
底线是:Python 很棒。更好的 Python 很神奇
不要退而求其次。Python 仍然是通用编程语言中无可争议的王者,这一事实不能成为编写平庸代码的借口。
通过遵循风格惯例、恰当地记录变更并保持代码简洁,您将使您的代码脱颖而出。在某些情况下,这甚至会提高其性能。无论如何,这将使你和你的同事更容易阅读和维护代码。
虽然这个列表包含了大量的提示和技巧,但它肯定不是详尽无遗的。如果我错过了什么,请在评论中告诉我。同时,祝您编码愉快!
编辑:正如 眨眼萨维尔 指出的, *getsizeof()*
的结果各不相同,取决于机器、架构和 Python 版本。现在包括在内了。还有, 奥利弗·法伦 正确的表述了下划线 *_*
确实是一个占用内存的变量。文本现在包括使用下划线,这是一种增加可读性的约定。而正如 迈克尔·弗雷德森 在推特上指出的, *dir()*
功能从 Python 2.7 开始就可用了。这个故事错误地声明它只能从 Python 3 中获得。
终端改造的终极指南
编程;编排
今天你将度过的最好的 16 分钟:程序员的终端提示
背景图片由来自 Unsplash 的 Jackson Hendry 拍摄。使用 teffects new-neon 创建的图像。
【最新更新 2021–12–17,星舰和书呆子字体。]
**Table of Contents**
· [Introduction](#c406)
∘ [Homebrew](#0afc)
· [iTerm2](#8455)
· [Zsh](#35a6)
· [Oh-My-Zsh](#367b)
∘ [Errors](#bdee)
∘ [Shortcut for toggling hidden files](#45d7)
· [Themes](#cf6e)
∘ [Starship (Updated)](#4b05)
∘ [iTerm2 Theme](#2944)
· [Oh-My-Zsh and plugins](#7c2d)
∘ [1\. git plugin](#a84b)
∘ [2\. alias](#597a)
∘ [3\. alias dirs and cd -](#9f2a)
∘ [4\. autojump plugin](#4abb)
∘ [5\. brew plugin](#74b2)
∘ [6\. zsh-syntax-highlighting plugin](#282f)
∘ [7\. zsh-autosuggestions plugin](#1646)
· [Duplicate a tab](#52d9)
· [Shaping up terminal command history](#1d56)
· [Creating aliases](#4d8f)
· [Useful commands](#c7bd)
· [Terminal Shortcuts](#0020)
· [Task management](#09aa)
· [Fun with Terminal](#b787)
∘ [Screensaver](#6474)
∘ [FIGlet](#0918)
∘ [Colors](#0cff)
∘ [Fonts](#2681)
· [Weather reports on your terminal](#5695)
· [macOS/Linux commands](#0d56)
∘ [Terminal calendars](#772c)
∘ [date](#b6b9)
∘ [ditto](#113e)
∘ [Common terminal commands](#b9e2)
· [Conclusion](#2a58)
· [Update Log](#c3ba)
· [Newsletter](#43ce)
介绍
你整天使用你的终端吗?终端是你重启电脑后启动的第一个 app 吗?在本文中,您将发现如何改进您的终端外观和日常工作的实用命令。
**【更新】**你可以用一行代码安装本文中的所有包,见本文。
安装终端是你用新电脑做的第一件事吗?如果是,那么这是给你的。
towardsdatascience.com](/automate-your-terminal-makeover-f3c152958d85)
公司自产自用
公司自产自用
你需要安装自制软件。如果您没有它,您可以通过在终端中运行以下命令来安装它。
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
家酿需要 Xcode 的命令行工具。但是如果你没有,安装会帮你安装。
Xcode 命令行工具
使用文本编辑器(Vim/VSCode/TextEdit)添加以下内容:
# ~/.zshrc
export PATH=$(brew --prefix)/bin:$PATH
然后来源~/.zshrc
:
$ . ~/.zshrc
这将加载~/.zshrc
。
运行brew help
看看是否安装了。
brew 帮助
适合每个开发人员的现代 Linux 命令
towardsdatascience.com](/awesome-rust-powered-command-line-utilities-b5359c38692) [## Rust-Powered 命令行实用程序可提高您的工作效率
您腰带下的现代快速工具
towardsdatascience.com](/rust-powered-command-line-utilities-to-increase-your-productivity-eea03a4cf83a)
iTerm2
iTerm2
iTerm2 是终端的替代品,可以在 MAC 上运行。iTerm2 为终端带来了极具特色的现代外观。
你可以下载 iterm2 或者用自制软件安装 iTerm2。
$ brew install iterm2
Zsh
Zsh 是一个为交互使用而设计的 shell,也是一种强大的脚本语言。
你可以找到你的壳。
$ echo $SHELL
/bin/zsh
找到你的 zsh 版本。
$ zsh --version
zsh 5.8 (x86_64-apple-darwin20.0)
如果你没有,那就用自制软件安装。
$ brew install zsh
如果您的 shell 不是 zsh,运行下面的代码。
$ chsh -s /bin/zsh
echo $SHELL
然后重启 iTerm2 或在 iTerm2 中打开一个新标签。
$ echo $SHELL
/bin/zsh
哦,我的天
哦,我的天
Oh-My-Zsh 是一个开源的、社区驱动的框架,用于管理您的 Zsh 配置。它捆绑了大量有用的功能,助手,插件,主题。
您可以通过在 iTerm 中运行以下命令之一来安装 Oh-My-Zsh。您可以通过命令行用 curl 或 wget 安装它。
经由卷曲
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
via wget
$ sh -c "$(wget -O- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
安装天啊。图片作者。
可以看到终端提示变为~
。
更新 Oh-My-Zsh:
$ omz update
运行 omz 更新。图片作者。
啊呀 Zsh 可能会覆盖~/.zshrc
,你需要添加到brew
的路径。这个时候需要在plugins
之前添加。
使用文本编辑器(Vim/VSCode/TextEdit):
# ~/.zshrc
export PATH=$(brew --prefix)/bin:$PATH
plugins=(git)
错误
你有以下错误吗?
或者
zsh 误差
您需要更改这些文件的访问权限。这些命令将修复它们。
在您的终端上运行以下程序:
$ chmod 755 $(brew --prefix)/share/zsh
$ chmod 755 $(brew --prefix)/share/zsh/site-functions
并打开另一个标签页。
切换隐藏文件的快捷方式
您可以通过 Command + Shift +句点在 Finder 中切换显示隐藏文件。
在 Mac 中切换隐藏文件的快捷方式
提高效率的终端命令
better 编程. pub](https://betterprogramming.pub/9-terminal-commands-you-can-start-using-today-7b9b0e273894) [## 像忍者一样掌握 Mac/Linux 终端快捷键
学习终端忍者的秘密,以提高生产力
better 编程. pub](https://betterprogramming.pub/master-mac-linux-terminal-shortcuts-like-a-ninja-7a36f32752a6)
主题
在这一部分,你会发现星际飞船和物品 2 的主题。你只需要用其中的一个。以前用 iTerm2 主题,现在用 Starship。
星际飞船(更新)
我开始使用星际飞船,我非常喜欢它。星际飞船是一个最小的,超快的,无限可定制的提示。
在安装 iTerm2,Zsh,哦,我的-Zsh 之后,正如我在你安装星际飞船之前所解释的。
例如,如果您是自制软件用户:
$ brew install starship
在~/.zshrc
的结尾增加以下内容:
从您的终端:
$ echo 'eval "$(starship init zsh)"' >> ~/.zshrc
或者如果你懂 Vim(或者初学的 TextEdit):
eval "$(starship init zsh)"
我们将 iTerm2 主题更改为 Minimal。
iTerm2 首选项外观常规中的最小主题。
我们将颜色预设更改为时髦的:
在 iTerm2 首选项颜色预设中选择时髦
$ brew tap homebrew/cask-fonts
$ brew install --cask font-hack-nerd-font
或者您可以使用brew
安装 Fira 代码:
$ brew tap homebrew/cask-fonts && [brew install --cask font-fira-code-nerd-font](https://medium.com/@gerrit.vanderlugt/i-had-to-install-the-fira-code-nerd-font-instead-its-working-now-9e0d3681c91d?source=email-a262a804b78f-1637406995986-activity.response_created)
在 iTerm2 首选项>个人资料>文本下选择黑客呆子字体 Mono:
在 iTerm2 首选项文本字体中选择 Hack Nerd 字体 Mono。
或者选择 FiraCode Nerd 字体 Mono:
在 iTerm2 首选项文本字体中选择 FiraCode Nerd 字体。
在我的一个 npm 包目录中,它用图标显示 Git 状态、repo 版本和节点版本。
显示 Git 状态、repo 版本和节点版本的 Starship。
[!]
是星际飞船 Git 状态选项之一,它告诉你目录被修改了。
星舰的 Git 状态选项。
如果您想知道状态栏中发生了什么,请使用starship explain
命令:
$ starship explain
指挥星舰 explain 的输出解释道
你可以使用星际飞船配置来改变提示。
iTerm2 主题
电力线
iTerm 有 200 多个主题。我最喜欢的主题是钴 2 和大洋下一个。
让我们安装钴 2。
- 下载这个 repo 并将 cobalt2.zsh-theme 文件放到~/中。我的天啊/主题/目录。Command + C 复制文件,Command + Option + V 剪切粘贴。
- 在~/上打开您的 ZSH 偏好设置。并将主题变量改为 ZSH 主题=钴 2。
ZSH_THEME= "钴 2 "
3.安装电力线和必要的字体-一种方法是使用画中画
$ pip3 install --user powerline-status
您可能需要升级 PIP。
$ pip3 install --upgrade pip
4.通过下载或克隆 git 库来安装所有必需的字体。
$ git clone https://github.com/powerline/fonts
$ cd fonts
$ ./install.sh
如果你想删除字体目录。
$ ..
$ rm -rf fonts
电力线字体
5.在 iTerm2 中,访问 Profiles 选项卡上的 Preferences 窗格。
6.在颜色选项卡下,通过颜色预设下拉菜单导入 cobalt2.itermcolors 文件。
iTerm2 配置文件颜色
7.在文本选项卡下,将每种类型(常规和非 ASCII)的字体更改为“电力线的不连续字体”。
iTerm2 首选文本
8.键入 source ~/刷新 ZSH。命令行上的 zshrc。
iTerm2 +电力线字体
VS 代码端子
对于您的 VS 代码终端,您需要在 Setting(JSON)中添加以下内容。
{
"terminal.integrated.fontFamily":"Inconsolata for Powerline",
}
如果你觉得有点冒险,试试 powerlevel10k 主题。
我的天啊和插件
Oh-My-Zsh 有内置命令。
作者图片
哦,我的 Zsh 内置命令在起作用,x 和 take 命令
Oh-My-Zsh 的强大来自它的插件。有超过 260 个插件可用。
1.git 插件
zsh git 插件提供了许多别名和一些有用的函数。要安装它,将git
添加到您的。zshrc 文件。用文本编辑器打开.zshrc
:
plugins=(git)
git 插件别名。作者图片
下面是一个使用 git 插件的示例工作流。
# make a directory and cd into it
$ mkdir -p Datascience/terminal-article && cd $_# create a new git repo
$ git init
Initialized empty Git repository in /Users/shinokada/DataScience/terminal-article/.git/# Add a README.md
$ echo "# Terminal-article" >> README.md# git add .
$ ga .# git commit -m
$ gcmsg "First commit"
[master (root-commit) 128f2b9] First commit
1 file changed, 1 insertion(+)
create mode 100644 README.md# git remote add
$ gra origin git@github.com:shinokada/terminal-article.git
git 插件
# modify a file
$ echo "more fix" >> README.md# git status
$ gst# git add .
$ ga .# git commit and message
$ gcmsg "Update"# git push origin
$ ggp
git 插件在运行
2.别名
你可以使用alias
来查看你所有的别名命令。更多别名请见本页。
3.别名 dirs 和 cd -
dirs 和 cd -,cd -2
你用化名cd -
、cd -2
等。使用dirs
命令,如上图所示。dirs
显示目录堆栈的内容。当前目录总是目录堆栈的“顶部”。cd -2
将目录更改为目录堆栈中的第二个目录。
4.自动跳转插件
[autojump](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/autojump)
插件加载自动跳转导航工具。autojump
是导航文件系统的一种更快的方式。它的工作原理是通过命令行维护一个包含您最常用的目录的数据库。
首先,在你的 Mac OS 上安装它。
$ brew install autojump
# or for port user
$ port install autojump
要使用它,将autojump
添加到您的。zshrc 文件:
# no comma between plugins required
plugins=(git autojump)
将以下内容添加到~/.zshrc
(英特尔 x86_64 或 arm64)的末尾:
[ -f $(brew --prefix)/etc/profile.d/autojump.sh ] && . $(brew --prefix)/etc/profile.d/autojump.sh
重新装弹。在你的终端上通过【zshrc 或者打开一个新的标签页。
通过改变你的目录,autojump
记录目录。你输入目录的前几个字母。例如j Data
。
5.brew 插件
brew 插件为常用的 brew 命令添加了几个别名。
要使用它,请将 brew 添加到。zshrc 文件:
plugins=(git autojump brew)
将brew
添加到插件后,会出现以下消息。
brew 插件消息
可以开始用了。
brew 命令图表。作者图片
创建您自己的别名
英寸 zshrc 添加以下内容。buou
会更新,显示过时和升级。
# brew update && brew outdated && brew upgrade ➡️ buou
alias buou="brew update && brew outdated && brew upgrade && brew cleanup"
6.zsh-语法高亮插件
通过在 oh-my-zsh 的插件目录中克隆存储库来安装zsh-syntax-highlighting:
$ git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
注意,zsh-syntax-highlighting 必须是最后一个来源于的插件。激活~/.zshrc
中的插件:
plugins=(some other plugins **zsh-syntax-highlighting**)
重启 iTerm2,打开一个新标签,或者运行source .zshrc
。
之前:
之后:
7.zsh-自动建议插件
zsh 自我暗示是鱼一样的 zsh 自我暗示。
- 将仓库克隆到
$ZSH_CUSTOM/plugins
(默认为~/.oh-my-zsh/custom/plugins
):
$ git clone [https://github.com/zsh-users/zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
2.将插件添加到~/.zshrc
的插件列表中:
plugins=(git brew zsh-syntax-highlighting zsh-autosuggestions)
3.启动新的终端会话或打开新的终端标签。
$ source ~/.zshrc
行动中的自动建议
复制选项卡
当你按下CMD+T
时,iTerm 会打开一个新的标签页,位置是~
或home
目录。我想用相同的目录复制一个标签。
在 iTerm 上,按CMD+,
打开设置。按键并选择按键绑定。点击左下角的+号,选择你的快捷键,比如Shift+CMD+T
。在操作中选择复制选项卡。
将 Shift+CMD+T 绑定到复制制表符。图片作者。
塑造终端命令历史
历史存储在~/中。zsh_history 或者~/。bash_history 或者~/。历史取决于你的外壳。根据您的系统,历史记录可存储 1000 或 2000 行。你可以找到历史的数字:
$ echo $HISTSIZE
50000
$ echo $HISTFILE
/Users/shinokada/.zsh_history
$ echo $SAVEHIST
10000
HISTSIZE
是会话中保留的最大行数,而SAVEHIST
是历史文件中保留的最大行数。HISTFILE
是系统保存历史的文件名。
您可以通过在. zshrc 中添加以下内容来更改这些数字。
HISTSIZE=5000
SAVEHIST=5000
反向搜索允许你从历史文件中搜索命令。按下CTRL+r
启动它,键入你记得要搜索的任何内容。如果您一直按下CTRL+r
,终端会在历史文件中搜索下一条命令。
反向搜索在起作用。图片作者。
您可以使用 bash 命令history
查看所有的命令历史。
# shows all command history
$ history# shows first 10 commands
$ history | head# shows last 10 commands
$ hisotry | tail# shows less history
$ history | less# Use grep to search your command history
$ history | grep Search-word# Use grep to do a case-insensitive search of your command history
$ hisotry | grep -i search-word
为了从您的历史列表中删除命令,您将以下命令添加到您的.zshrc
:
setopt HIST_IGNORE_SPACE
当命令行的第一个字符是空格时,这将从历史列表中删除命令行。
# This won't work
$ cd ~
# This will work because there is a space before the command
$ cd ~
您可能不希望命令历史中包含常用命令。将以下内容添加到命令历史中的zshrc
阻止ll ls la cd man scp vim nvim less ping open file which whois drill uname md5sum traceroute
命令。
zshaddhistory() {
local line=${1%%$'\n'}
local cmd=${line%% *} # Only those that satisfy all of the following conditions are added to the history
[[ ${#line} -ge 5
&& ${cmd} != ll
&& ${cmd} != ls
&& ${cmd} != la
&& ${cmd} != cd
&& ${cmd} != man
&& ${cmd} != scp
&& ${cmd} != vim
&& ${cmd} != nvim
&& ${cmd} != less
&& ${cmd} != ping
&& ${cmd} != open
&& ${cmd} != file
&& ${cmd} != which
&& ${cmd} != whois
&& ${cmd} != drill
&& ${cmd} != uname
&& ${cmd} != md5sum
&& ${cmd} != pacman
&& ${cmd} != xdg-open
&& ${cmd} != traceroute
&& ${cmd} != speedtest-cli
]]
}zshaddhistory
创建别名
正如我之前用buou
展示的,你可以给.zshrc
文件添加你自己的别名。
# brew update && brew outdated && brew upgrade
alias buou="brew update && brew outdated && brew upgrade && brew cleanup"# npm outdated -g --depth=0 && npm update -g
alias npmou="npm outdated -g --depth=0 && npm update -g"
我已经安装了virtualenv
和virtualenvwrapper
。并且下面的别名允许我使用note
启动一个 Jupyter 环境和 Jupyter 笔记本。lab
将启动环境和 Jupyterlab。
# start jupyter environment
alias wj='workon jupyter'# start jupyter notebook
alias note='workon jupyter && jupyter notebook'# start jupyterlab
alias lab='workon jupyter && jupyter lab'
有用的命令
# Repeat the last command
$ !!
# Clear the screen
$ clear
# Or you can clear the screen with CTRL+l, as well
不使用rm
命令,我建议使用rmtrash
。这将移动文件到 OS X 的垃圾桶,而不是永久删除。您可以使用brew
进行安装:
$ brew install rmtrash
并在您的~/.zshrc
文件中创建一个别名:
alias del="rmtrash"
正在删除下载目录中的文件:
# Using [autojump](#4e7b)
$ j Down
$ del ./*
终端快捷方式
一些 Mac 终端快捷键
你可以在这里找到更多 Mac 的键盘快捷键。
任务管理
你可以从命令行使用任务编辑器来管理你的待办事项列表。
如果你是自制软件用户:
$ brew install task
你可以在本页找到其他操作系统安装。
$ task add Buy milk
Created task 1.$ task list
ID Description
-- -----------
1 Buy milk
使用+
/ -
添加/删除标签。
$ task add Buy cake +shopping -lunch
使用project:
添加项目。
$ task add Update a file project: 'Medium article A'
使用task ID modify
修改列表。
$ task modify 1 Buy milk and bread
完成任务时使用task ID done
。
$ task 1 done
终端的乐趣
屏幕保护程序
运行管道 sh -p4 -t2。图片作者。
[pipes.sh](https://github.com/pipeseroni/pipes.sh#contents)
是一个动画终端屏保。你可以用自制软件安装它:
$ brew install pipes-sh
找出选项:
$ pipes.sh -h
Usage: pipes.sh [OPTION]...
Animated pipes terminal screensaver. -p [1-] number of pipes (D=1).
-t [0-9] type of pipes, can be used more than once (D=0).
-c [0-7] color of pipes, can be used more than once (D=1 2 3 4 5 6 7 0).
-t c[16 chars] custom type of pipes.
-f [20-100] framerate (D=75).
-s [5-15] probability of a straight fitting (D=13).
-r LIMIT reset after x characters, 0 if no limit (D=2000).
-R randomize starting position and direction.
-B no bold effect.
-C no color.
-K pipes keep their color and type when hitting the screen edge.
-h help (this screen).
-v print version number.
您可以使用-p
选项改变管道数量,使用-t
选项改变管道类型,等等。
$ pipes.sh -p4 -t2
当你按下任何一个键,它就会停止。
如果你是黑客帝国电影的爱好者,可以安装cmatrix
。
$ brew install cmatrix# run cmatrix
$ cmatrix
你需要按Ctrl-c
来停止屏保。
运行矩阵屏幕保护程序。图片作者。
菲戈莱特
我用小图创建了标题图像。FIGlet 是一个把普通文本变成大字母的程序。
$ brew install figlet
$ printf "\e[92m" && figlet -f standard "Terminal Tips"
用 FIGlet 创建的图像
另一个例子
颜色;色彩;色调
printf "\e[92m"
设置输出颜色。您可以打印您的终端颜色代码。
$ for code in {30..37}; do \
echo -en "\e[${code}m"'\\e['"$code"'m'"\e[0m"; \
echo -en " \e[$code;1m"'\\e['"$code"';1m'"\e[0m"; \
echo -en " \e[$code;3m"'\\e['"$code"';3m'"\e[0m"; \
echo -en " \e[$code;4m"'\\e['"$code"';4m'"\e[0m"; \
echo -e " \e[$((code+60))m"'\\e['"$((code+60))"'m'"\e[0m"; \
done
终端颜色
现在,您可以使用其中一种颜色来更改颜色。
使用红色
字体
-f standard
设置字体。您可以选择多种字体。
使用“星球大战”字体的小图
你终端上的天气报告
您可以使用[wttr.in](https://github.com/chubin/wttr.in)
在终端上打印天气报告。
$ curl wttr.in/CityName
科尔·wttr.in/Tokyo
如果您想查找您当前位置的天气,请运行curl wttr.in
。
您可以找到更多选项:
$ curl wttr.in/:help
科尔·wttr.in/:help
您可以在您的. zshrc 中添加一个别名。对于 ZSH,您需要添加\
来转义像?
这样的特殊字符。
# weather
alias we='curl wttr.in/Tokyo' #current, narrow, quiet, no Follow
alias we1='curl wttr.in/Tokyo\?1nqF' #+1day, narrow, quiet, no Follow
alias we2='curl wttr.in/Tokyo\?2nqF' #+2days, same as above
we1
macOS/Linux 命令
macOS 基于 Unix 操作系统,拥有与 Linux 几乎相同的命令。我之前已经提到过dir
命令。让我列出更多你经常使用的命令。
终端日历
您可以在终端上显示日历。
# Current month calendar
$ cal# Yearly calendar
$ cal 2020# Current month + 2 months
$ cal -A 2
终端日历
日期
尝试date
显示时间。
日期
同上
ditto
复制文件和文件夹。
常见终端命令
常见的终端命令。作者图片
结论
现在,你知道如何增强你的终端。我希望这篇文章能提高你在终端工作时的效率。你可以玩你的终端或者查看天气预报和日历。
你的包里有什么?zshrc 文件?请分享你的 GitHub 链接。
更新日志
- 2021–12–17,星舰和书呆子字体。
- 2021–011–20,M1 专业芯片和 fira-code-nerd-font
- 2021 年 6 月 11 日,M1 芯片,自动跳转
- 2021–5–23,我的天啊错误,M1 芯片,重复标签
- 2021 年 3 月 30 日,2021 版
- 2021 年 2 月 22 日,终端带来乐趣
- 2021 年 2 月 15 日,天气
通过 成为 会员,可以完全访问媒体上的每个故事。
您应该使用的技巧、提示和快捷方式
towardsdatascience.com](/hands-on-jupyter-notebook-hacks-f59f313df12b) [## 用 Jupyter 笔记本写作的 7 个基本技巧
第一篇数据科学文章指南
towardsdatascience.com](/7-essential-tips-for-writing-with-jupyter-notebook-60972a1a8901) [## 使用 Jupyter 笔记本进行版本控制
Jupytext 分步指南
towardsdatascience.com](/version-control-with-jupyter-notebook-b9630bc5996e) [## Jupyter 用户的生产力提示
使用 Jupyter 笔记本和 JupyterLab 让您的工作流程更加高效
towardsdatascience.com](/stepping-into-intermediate-with-jupyter-f6647aeb1184)