Python 3.8 中针对 Python 新手的 6 项新特性
Python 初学者
请做好准备,因为 Python 2 不再受支持
照片由普里西拉·杜·普里兹在 Unsplash 上拍摄
语言会变。语言会适应。21 世纪 20 年代不再支持 Python 2。
鉴于数据科学的兴起,Python 是 2019 年最受欢迎的编程语言。然而,对于要学的东西太多,感到有点不知所措是正常的。语法不断变化。每次更新都会添加许多新形式的表达式。很难跟踪 Python 中的变化。有些特征我希望我能早点知道。
超越 lambda、map 和 filter 的 Python 技巧
towardsdatascience.com](/5-python-features-i-wish-i-had-known-earlier-bc16e4a13bf4)
如果你也有同样的感觉,那么对你来说是个坏消息。Python 3.8 最近发布了。不要害怕。我总结了 Python 3.8 的 6 个新特性,每个 Python 初学者都应该学习。
1.赋值表达式—可读性
也被称为 walrus 操作符,它是一个新的操作符,语法:=
允许你给变量 赋值,作为一个更大的表达式的一部分。这可以说是 Python 3.8 中讨论最多的新特性。这里来一个例子。
赋值表达式b := a**2
将变量b
赋值为a
的平方,在本例中为 36,然后检查b
的值是否大于 0。
赋值表达式有时可以让你的代码更加紧凑,并且可读性更好。注意不要滥用它,因为在某些情况下,它可能会使您的代码比必要的更难理解。
# **DON'T DO THIS!**
a = 5
d = [b := a+1, a := b-1, a := a*2]
这个操作符已经存在于其他(更老的)编程语言中,我希望许多转到 Python 的程序员会(ab)使用这个新特性。在它无处不在之前熟悉它。这是一只海象。
2.参数类型—鲁棒性
Python 函数中的参数可以接受两种类型的参数。
- 按位置传递的位置参数
- 关键字由关键字提供的参数
在下面的例子中,参数a
和b
的值可以由位置或关键字参数提供。灵活。
def my_func(a, b=1):
return a+bmy_func(5,2) # both positional arguments
my_func(a=5,b=2) # both keyword arguments
Python 的新版本提供了一种方法,通过使用语法/
和*
进行分隔,来指定只能接受位置参数或关键字参数的参数。
*后一种语法*
在 Python 3.8 中并不新鲜
在下面的例子中,前两个参数a
和b
是仅位置的,中间两个c
和d
可以是位置的或关键字的,最后两个e
和f
是仅关键字的。
由 Austin Distel 在 Unsplash 上拍摄
你为什么决定牺牲灵活性?当参数名无用或任意时,应该排除关键字参数。如果函数中的参数名在将来****被更改,也可以避免破坏您的代码。它有助于更健壮的代码。
3.f-string 2.0 —调试
Python f-string 是游戏改变者。这是一个可读的优雅的字符串格式化语法**,它在字符串中嵌入了表达式。这是通过语法f'{expr}'
完成的,其中表达式被 f 字符串中的花括号括起来,引号前有一个f
。**
新的更新支持使用等号** =
作为语法为f'{expr=}'
的 f 字符串内表达式的格式说明符。输出字符串将包括变量名及其值,在=
之间有一个等号,如下所示。**
出于文档或调试的目的,我们经常想要打印出变量值。这使得用最小的努力调试变得容易。
4.可逆字典—顺序
字典现在可以在中重复,使用[reversed()](https://docs.python.org/3/library/functions.html#reversed)
反转插入顺序。
5.新模块—元数据
有一个新的importlib.metadata
模块允许你从第三方包中读取元数据。您可以在您的脚本中提取包的版本号**。**
6.继续——终于
由于实现的问题,在finally
子句中使用continue
语句曾经是非法的**。不再是了。**
汉娜·雅各布森在 Unsplash 上拍摄的照片
外卖
注意,我没有提到一些高级特性,这些特性与普通程序员如何为小项目编写代码没有什么关系。包括多处理共享内存、新 Pickle 协议等。对感兴趣的人来说。
这就是 6 个新的 Python 特性,即使是 Python 初学者也能从中受益。在进入 Python 3.8 之前,请确保您熟悉一些基本的 Python 特性。你可以注册我的时事通讯来接收我的新文章的更新。如果您对 Python 感兴趣,以下文章可能会有用:
** [## 我希望我能早点知道的 5 个 Python 特性
超越 lambda、map 和 filter 的 Python 技巧
towardsdatascience.com](/5-python-features-i-wish-i-had-known-earlier-bc16e4a13bf4) [## 每个 Python 初学者都应该学习的 4 个 NumPy 技巧
编写可读代码的技巧
towardsdatascience.com](/4-numpy-tricks-every-python-beginner-should-learn-bdb41febc2f2)
今天就开始用 Python 3.8 编码吧!**
鲁棒目标检测的 6 个障碍
您的探测器有多耐用?
你的物体探测器能探测到下图中的人和马吗?
同样的图像旋转 90 度会怎么样?它能探测到人和马吗?
或者这些图像中的猫?
最左侧(照片由埃里克-扬·勒辛克在 Unsplash 上拍摄)、中间(照片由克里斯塔·曼古松在 Unsplash 上拍摄)、最右侧(照片由鲁德梅乌拉·费尔南德斯在 Unsplash 上拍摄)
我们在计算机视觉的进步方面已经走了很长的路。使用人工智能的物体检测算法在某些任务中已经超过了人类。但是,为什么如果图像旋转 90 度,检测一个人,如果一只猫躺在一个不常见的位置,或者如果只有一部分是可见的,检测一个物体仍然是一个挑战。
自 2012 年 AlexNet 以来,已经为对象检测和分类创建了很多模型,它们在准确性和效率方面越来越好。然而,大多数模型都是在理想的场景中训练和测试的。但是在现实中,使用这些模型的场景并不总是理想的:背景可能是杂乱的,对象可能是变形的,或者可能是被遮挡的。以下面的猫的图片为例。任何被训练来检测猫的物体检测器将会无故障地检测到左边图像中的猫。但对于右边的图像,大多数检测器可能无法检测到猫。
左(在 Unsplash 上由 Edgar Edgar 拍摄)、右(在 Unsplash 上由 Krista Mangulsone 拍摄)
对于人类来说被认为是琐碎的任务在计算机视觉中无疑是一个挑战。我们人类很容易识别一个人,无论是任何方位的图像还是不同姿势的猫,或者从任何角度看的杯子。
让我们来看看 6 个这样的障碍,以稳健地检测对象。
1.视点变化
一个物体从不同的角度看可能会完全不同。以一个简单的杯子为例(参见下图),第一个图像显示了一个装有黑咖啡的杯子的俯视图,与第二个图像(装有卡布奇诺的杯子的侧视图和俯视图)和第三个图像(杯子的侧视图)完全不同。
不同视角的杯子。左(在 Unsplash 上杰克·卡特拍照)、中(在 Unsplash 上 Pablo Merchán Montes 拍照)、右(在 Unsplash 上诺德伍德主题拍照)
这是对象检测的挑战之一,因为大多数检测器仅使用来自特定视点的图像进行训练。
2.变形
许多感兴趣的物体不是刚体,并且可以以极端的方式变形。举个例子,让我们看看下面瑜伽练习者不同姿势的图片。如果对象检测器被训练来检测具有仅包括坐着、站着或行走的人的训练的人,则它可能不能检测这些图像中的人,因为这些图像中的特征可能与它在训练期间学习到的关于人的特征不匹配。
左(照片由阿维·理查兹在 Unsplash 上拍摄)、右(照片由凯西·PHAM在 Unsplash 上拍摄)
3.闭塞
感兴趣的对象可以被遮挡。有时只能看到物体的一小部分,少到只有几个像素。
拿着杯子的女人(照片由亚里沙·安东在 Unsplash 上拍摄)
例如,在上面的图像中,物体(杯子)被拿着杯子的人挡住了。当我们只看到一个物体的一部分时,在大多数情况下,我们可以立即识别它是什么。然而,对象检测器并不执行相同的操作。
遮挡的另一个例子是一个人拿着移动电话的图像。在这些图像中检测手机是一项挑战:
人们拿着手机。左(照片由梅根·舍里克拍摄于 Unsplash ),中(照片由威廉·艾文拍摄于 Unsplash ),右(照片由普里西拉·杜·普里兹拍摄于 Unsplash )
4.照明条件
照明对像素级别的影响非常大。物体在不同的光照条件下呈现不同的颜色。例如,室外监控摄像机整天暴露在不同的光照条件下,包括明亮的日光、傍晚和夜间光线。在这些不同的照明下,行人的图像看起来是不同的。这影响了检测机稳健检测物体的能力。
不同光照条件下的小巷。左(由色谱仪在 Unsplash 上拍照)、中(由奥米德阿明在 Unsplash 上拍照)、右(由斯拉万 V 在 Unsplash 上拍照)
5.杂乱或纹理背景
感兴趣的物体可能融入背景中,使它们难以识别。例如,下图中的猫和狗用它们坐着/躺着的地毯伪装起来。在这些情况下,物体检测器将面临检测猫和狗的挑战。
6.类内变异
感兴趣的对象通常可以是相对宽泛的,例如房子。这些物体有许多不同的类型,每一种都有自己的外观。下面所有的图片都是不同类型的房子。
房子。左(由杰西·罗伯特在 Unsplash 上拍照)、中(由拉尔夫·凯登在 Unsplash 上拍照)、右(由大卫·维克斯列尔在 Unsplash 上拍照)
房子。左(由伊恩·基夫在 Unsplash 上拍照)、中(由皮克斯夸在 Unsplash 上拍照)、右(由斯蒂芬·贝彻在 Unsplash 上拍照)
一个好的检测器必须足够健壮,以检测所有这些变化的叉积,同时还保持对类间变化的灵敏度。
解决方法
为了创建鲁棒的对象检测器,确保对于不同的视点、照明条件和不同背景中的对象,训练数据有良好的变化。如果您无法找到所有变化的真实世界训练数据,请使用数据扩充技术来合成您需要的数据。
您使用了哪些技术来增强物体检测器的鲁棒性? 在下面留下你的想法作为评论。
原载于*【www.xailient.com/blog】。*
希望在树莓派上实现实时人脸检测?看看这个帖子。
更多故事:
关于作者
Sabina Pokhrel 在 Xailient 工作,这是一家计算机视觉初创公司,已经建立了世界上最快的边缘优化物体探测器。
参考文献:
这是一个介绍性的讲座,旨在向人们介绍计算机视觉以外的图像…
compsci697l.github.io](https://compsci697l.github.io/notes/classification/) [## 了解图像识别及其用途
说到识别图像,我们人类可以清楚地识别和区分物体的不同特征…
www.einfochips.com](https://www.einfochips.com/blog/understanding-image-recognition-and-its-uses/)
Pahuja,a .,Majumder,a .,Chakraborty,a .,和 Venkatesh Babu,R. (2019 年)。通过注意力增强显著对象分割。 arXiv 预印本 arXiv:1905.11522 。
迈尔,w .,埃谢,m .,,施泰因巴赫,E. (2011 年 9 月)。镜面环境中变化光照下基于图像的目标检测。在 2011 年第 18 届 IEEE 国际图像处理会议(第 1389–1392 页)。IEEE。
蔡,杨,杜,丁,张,文,王,吴,杨,刘(2019)。无人机目标探测和计数的引导注意力网络。 arXiv 预印本 arXiv:1909.11307 。
萧,e .,,赫伯特,M. (2014)。任意视点下目标检测的遮挡推理。 IEEE 模式分析与机器智能汇刊, 36 (9),1803–1815。*
你应该知道的 6 个熊猫技巧来加速你的数据分析
一些最有用的熊猫把戏
阿尔瓦罗·雷耶斯在 Unsplash 上拍摄的照片
在这篇文章中,你将学习一些最有用的熊猫技巧来加速你的数据分析。
- 按数据类型选择列
- 将字符串转换为数字
- 检测和处理缺失值
- 将连续数字特征转换为分类特征
- 从剪贴板创建数据帧
- 从多个文件构建数据框架
源代码请查看我的 Github repo 。
1.按数据类型选择列
以下是泰坦尼克号数据帧的数据类型
df.dtypesPassengerId int64
Survived int64
Pclass int64
Name object
Sex object
Age float64
SibSp int64
Parch int64
Ticket object
Fare float64
Cabin object
Embarked object
dtype: object
假设您需要选择数字列。
df.select_dtypes(**include='number'**).head()
这包括 int 和 float 列。您还可以使用此方法来
- 仅选择对象列
- 选择多种数据类型
- 排除某些数据类型
# select just object columns
df.select_dtypes(**include='object'**)# select multiple data types
df.select_dtypes(**include=['int', 'datetime', 'object']**)# exclude certain data types
df.select_dtypes(**exclude='int'**)
2.将字符串转换为数字
在 Pandas 中有两种方法将字符串转换成数字:
astype()
法to_numeric()
方法
让我们创建一个示例数据帧来看看区别。
df = pd.DataFrame({ 'product': ['A','B','C','D'],
'price': ['10','20','30','40'],
'sales': ['20','-','60','-']
})
价格 和 销售 列存储为字符串,因此产生对象列:
df.dtypesproduct object
**price object
sales object**
dtype: object
我们可以使用第一种方法astype()
对 价格 列进行如下转换
# Use Python type
df['price'] = df['price']**.astype(int)**# alternatively, pass { col: dtype }
df = df.**astype({'price': 'int'})**
但是,如果我们试图在 sales 列中使用它,就会导致错误。为了解决这个问题,我们可以使用带有参数errors='coerce'
的to_numeric()
df['sales'] = **pd.to_numeric(df['sales'], errors='coerce')**
现在,无效值-
被转换为NaN
,数据类型为 float 。
3.检测和处理缺失值
检测缺失值的一种方法是使用info()
方法并查看列 非空计数 。
df.info()RangeIndex: **891 entries**, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
**5 Age 714 non-null** float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
**10 Cabin 204 non-null** object
**11 Embarked 889 non-null** object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
当数据集很大时,我们可以计算缺失值的数量。df.isnull().sum()
返回每列缺失值的数量
df.**isnull().sum()**PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
df.isnull().sum().sum()
返回缺失值的总数。
df.**isnull().sum().sum()**886
此外,我们还可以通过运行df.isna().mean()
找出缺失值的百分比
ufo.isna().mean()PassengerId 0.000000
Survived 0.000000
Pclass 0.000000
Name 0.000000
Sex 0.000000
Age 0.198653
SibSp 0.000000
Parch 0.000000
Ticket 0.000000
Fare 0.000000
Cabin 0.771044
Embarked 0.002245
dtype: float64
删除丢失的值
如果存在任何 NaN 值,则删除行
df.dropna(**axis = 0**)
如果存在任何 NaN 值,则删除列
df.dropna(**axis = 1**)
删除缺少 10%以上值的列
df.dropna(**thresh=len(df)*0.9**, **axis=1**)
替换丢失的值
用标量替换所有 NaN 值
df.fillna(**value=10**)
用前一行中的值替换 NaN 值。
df.fillna(**axis=0**, **method='ffill'**)
用前一列中的值替换 NaN 值。
df.fillna(**axis=1**, **method='ffill'**)
同样,您也可以用下一行或下一列中的值替换 NaN 值。
# Replace with the values in the next row
df.fillna(**axis=0**, **method='bfill'**)# Replace with the values in the next column
df.fillna(**axis=1**, **method='bfill'**)
另一种常见的替换是用平均值替换 NaN 值。例如,用平均值替换列 Age 中的 NaN 值。
df[**'Age'**].fillna(value=**df['Age'].mean()**, inplace=True)
有关 Pandas 中缺失值的更多信息,请查看使用 Pandas 中缺失值的。
4.将连续数字特征转换为分类特征
在数据准备的步骤中,组合或转换现有要素以创建更有用的要素是很常见的。最流行的方法之一是从连续的数字特征创建分类特征。
让我们看看泰坦尼克号数据集中的 年龄 列
df['Age'].head(8)0 22.0
1 38.0
2 26.0
3 35.0
4 35.0
5 NaN
6 54.0
7 2.0
Name: Age, dtype: float64
年龄 是一个连续的数字属性,但是如果要将其转换为分类属性,比如将年龄转换为年龄范围的组:≤12,青少年(≤18),成年(≤60),老年(> 60)怎么办
最好的方法是使用 Pandas cut()
功能:
import sysdf['ageGroup']=pd.cut(
**df['Age'],**
**bins=[0, 13, 19, 61, sys.maxsize],**
**labels=['<12', 'Teen', 'Adult', 'Older']**
)
并且在 年龄组 栏上调用head()
也应该显示该栏信息。
df['ageGroup'].head(8)0 Adult
1 Adult
2 Adult
3 Adult
4 Adult
5 NaN
6 Adult
7 <12
**Name: ageGroup, dtype: category**
**Categories (4, object): [<12 < Teen < Adult < Older]**
5.从剪贴板创建数据帧
Pandas read_clipboard()
函数是一种非常方便的方法,可以尽快将数据转换成数据帧。
假设我们有以下数据,并希望根据这些数据创建一个数据框:
product price
0 A 10
1 B 20
2 C 30
4 D 40
我们只需要选择数据并将其复制到剪贴板。然后,我们可以使用函数将它读入数据帧。
df = **pd.read_clipboard()**
df
6.从多个文件构建数据框架
数据集可能分布在多个文件中,但您希望将数据集读入单个数据帧中。
一种方法是将每个文件读入其自己的数据帧,将它们组合在一起,然后删除原始的数据帧,但这将是内存低效的。
更好的解决方案是使用内置的glob
模块(感谢数据学校熊猫诡计)。
在这种情况下,glob()
在数据目录中查找以单词“ data_row_ ”开头的所有 CSV 文件。glob()
以任意顺序返回文件名,这就是为什么我们使用sort()
函数对列表进行排序。
对于行方式的数据
假设我们的数据集按行分布在两个文件中,data _ row _ 1 . CSV和data _ row _ 2 . CSV
从这两个文件创建一个数据帧。
files = sorted(glob('**data/data_row_*.csv**'))
pd.concat((pd.read_csv(file) for file in files), **ignore_index=True**)
sorted(glob('**data/data_row_*.csv'**))
返回文件名。之后,我们使用read_csv()
读取每个文件,并将结果传递给concat()
函数,该函数将这些行连接成一个数据帧。此外,为了避免索引中的重复值,我们告诉concat()
忽略索引(**ignore_index=True**
),而使用默认的整数索引。
对于按列排列的数据
假设我们的数据集以列方式分布在两个文件中,data _ col _ 1 . CSV和data _ col _ 2 . CSV。
从这两个文件创建一个数据帧。
files = sorted(glob('data/data_col_*.csv'))
pd.concat((pd.read_csv(file) for file in files), **axis=1**)
这一次,我们告诉concat()
函数沿着列轴连接。
好了
感谢阅读。
请在我的 Github 上查看笔记本的源代码。
如果你对机器学习的实用方面感兴趣,请继续关注。
构建数据科学职业生涯的 6 个播客
从建立你的品牌和面试技巧到基本的技术技能
安琪丽可·雷德梅克斯的照片来自重拍
网络上有很多免费资源可以帮助你成为更好的数据科学家。其中之一就是播客。播客是向在该领域有经验的专业人士、技术黑客学习或习惯数据科学术语的有用来源。大多数剧集都在 30-60 分钟之间,因此,是你日常工作或大学旅行的绝佳伴侣,无论是在健身时还是在两者之间。
你可以在媒体上找到一些关于数据科学、工程和商业的最好的播客。虽然我发现其中一些播客技术性很强,通常涵盖小众项目,但我喜欢听那些明确致力于数据科学职业发展和个人成长的演讲。
以下是我经常收听的 6 个播客,主要讲述如何在数据科学领域取得成功,以及如何在职业生涯中取得进步:
1.在数据科学领域建立职业生涯
在这个相当新的播客中(自 2020 年 9 月起),Jaqueline Nolis 和 Emily Robinson 将他们新出版的同名书籍带入生活。这不是印刷版的音频版本,而是对他们书中涵盖的主题的补充聊天,如开始职业生涯、获得第一份工作和在数据科学中成长。
他们是我名单上的第一个,因为 Jaqueline 和 Emily 是我下面列出的大多数节目的常客,证明了他们是数据科学职业发展中值得信赖的专家。此外,两人都有有趣的背景,他们有很多可以分享的东西,并以有趣的方式分享(我指的是介绍歌曲!!!).在第一期发布的剧集中,您将了解数据科学中的各种工作描述,根据雇主规模的不同而不同的职责,或者讨论博士与训练营选项。
在可用:Spotify、苹果播客、谷歌播客、Pocket casts,或者这里。
迄今为止最喜欢的一集:第二章——数据科学公司
2.数据科学的艺术家们
在《数据科学的艺术家》中,Harpreet Sahota 采访了专业人士和学者,探讨他们在数据科学领域的职业发展和工作经历。我非常喜欢这个播客,因为 Harpreet 将他的播客完全奉献给了个人成长。他听起来也很有趣,看起来总是 100%投入到节目中。
此外,他每周发布几集,使他成为我名单上最频繁的播客,有很多内容可供学习。在他的采访旁边,Harpreet 记录了所谓的每周“办公时间”,你可以注册并询问与数据科学相关的问题。我推荐听或者报名那些集听听别人的问题或者问自己的问题。
在上可用:Spotify、谷歌播客、苹果播客,或者这里。
到目前为止最喜欢的一集:和斯科特·h·杨一起成为一名超级赢家
3.超级数据科学
与上面介绍的相当新的播客相反,在过去的四年里,基里尔·叶列缅科每周都为 SuperDataScience 发布播客。由同名学习平台赞助,Kiril 与来自该领域的经验丰富的专业人士讨论数据相关的话题,从数据可视化到掌握工作面试,再到更好地远程工作。
我喜欢这个播客,因为 Kirill 也涉及个人成长话题,如生产力、冥想或骗子综合症。他找到了技术和自我发展谈话的正确结合。此外,每周五,基里尔都会发布一个“周五五分钟”集,要么简要解释 p 值等技术概念,要么分享职业发展的技巧和想法。对我来说,特别是那些小插曲是灵感的巨大来源。
在上可用:Spotify、Listen Notes、Soundcloud,或者这里。
到目前为止最喜欢的一集:SDS 399——为社区做贡献,SDS 303——对每个领域进行适当的假设检验
4.走向数据科学播客
走向数据科学播客是著名媒体出版物的官方播客系列。它专门分享关于数据科学的一般想法,还涵盖职业建议、自学故事和行业趋势。我喜欢这个播客系列,尽管它有时取决于谁是主持人。每当杰里米·哈里斯主持节目,我相信他是主要主持人,都值得收听!
在上可用:Spotify、谷歌播客、苹果播客,或此处。
迄今为止最喜欢的一集:爱德华·哈里斯——掌握数据科学求职
5.数据框架
由 Hugo Bowne-Anderson 主持的 DataFramed 播客是学习平台 Datacamp 的播客系列。像 TDS 播客一样,DataFramed 不仅仅致力于职业发展;然而,有几集讲述了个人发展和职业生涯。我觉得雨果喋喋不休,但值得一听,直到最后讨论最令人兴奋的事情。在这里,我学到了一些很棒的东西!
我无法确定的一件事是每集播放的片段。一个片段有时是为了广告,有时是为了简要解释一个重要的统计概念,如 AB 测试。这些片段往往超级有趣,但也完全断章取义。
在可用:Spotify、谷歌播客、苹果播客,或者这里。
迄今为止最喜欢的一集 : #55 获得你的第一份数据科学工作
尤其是对女士来说…
6.数据科学中的女性
在她的播客“数据科学中的女性”中,Margot Gerritsen 教授只采访了在许多不同行业和部门应用数据科学的女性。这些都是来自有影响力的个人的真正鼓舞人心的故事。在整个节目中,你将了解到数据可以影响的众多领域,并聆听女性在 STEM 相关工作中的个人经历。
在上可用:Spotify、谷歌播客、苹果播客、Stitcher,或者这里。
迄今为止最喜欢的一集:徐亚——用数据为全球劳动力的所有成员创造经济机会
快乐聆听!
如果你认为我的列表缺少一个在数据科学领域建立职业生涯的好播客,请留下评论!
机器学习爱好者提出的 6 个问题
我提供的答案
在我的人工智能学习之旅的开始,我希望我有一些导师可以指引我正确的方向。
我在学习机器学习的方法上需要指导,尤其是当我购买的第一本学习机器学习的书是一个相当强大的敌人的时候。
两年时间和大量的 model.fit()之后,我现在是一名专业的 ML/计算机视觉工程师。
开始人工智能之旅或只是寻求建议的个人可以通过 LinkedIn 联系我并提出问题。我知道尝试在人工智能的世界中导航有多难,所以我总是尽力回答通过 LinkedIn 或电子邮件发给我的所有问题。
这篇文章包含六个机器学习相关的问题,涵盖了机器学习的学术、职业和技术方面。
也许你想问一些问题。看看下面的问题,也许你会找到一些指导。
如果我提供的答案没有一个对你有用,那么向下滚动到结论部分,找出如何直接问我你的问题。
由 Unsplash 上的制作者 NESA 拍摄
说到这里,让我们开始吧。
学术问题
Joshua Hoehne 在 Unsplash 上拍摄的照片
问题#1 :
你会推荐数据科学硕士(大多数大学都提供)或某个专业领域的硕士吗?请从各自领域工作机会的角度给出建议。
回答:
如果你确信自己只对数据科学领域的就业机会感兴趣,我建议你获得数据科学硕士学位。
尽管当前的疫情和一些行业正在经历的困难,对数据科学家的需求似乎仍然很高。
与此同时,数据科学家的供应也在增加,这意味着更多的角色竞争。
处于行业顶端的杰出数据科学家能够非常迅速地找到角色。
然而,如果你知道自己的兴趣和热情所在,你可能会想在更专业的领域攻读硕士学位。
如果你对计算机视觉、自然语言处理或机器人等领域感兴趣,那么攻读更专业的理学硕士学位似乎是一个合理的选择。
由于它们更具技术性和专业性,当比较数据科学领域的职位时,工作职位的竞争可能不会那么激烈。
另一个关键点是,你从计算机视觉或 NLP 专业学位获得的一些技能可以转移到一般的数据科学职位上。因此,你可以拥有计算机视觉等技术领域的硕士学位,同时还拥有数据科学家的相关技能。
以我为例,即使我学习了机器学习和计算机视觉的硕士学位,我仍然拥有申请数据科学工作所必需的技能。
在我得到计算机视觉工程师的工作之前,我的前几次面试是为了数据科学的职位。
问题 2:
学习自主领域有哪些相关课程和见解?
回答:
我在自主领域的经验和知识非常有限。
尽管如此,我还是会提供一些我通过网上研究和直觉找到的有用信息。
自主领域将与自主车辆和机器人相一致。自动驾驶汽车的主要领域将是传感器和基于视觉的方法,自动驾驶汽车使用这些方法来获得对环境的感知和理解。
自动驾驶汽车研究的其他领域是导航系统和地图规划。
因此,以下是一些需要考虑进一步探索的领域:
- 自动驾驶汽车中的深度学习
- 自主车辆和机器人中的激光雷达传感器
- 机器人或车辆中的导航和路径规划。
作为起点,看一看这个课程,看看它是否符合你的学习要求。
自主机器人和车辆在人类的技术未来中占有一席之地。
看看挤满了自主机器人的亚马逊仓库。在未来 5-10 年内,一些运输系统将采用自动导航机器人。
特斯拉最近刚刚发布了他们全自动驾驶系统的测试版,甚至计划将其扩展到更多的城市。
我住在英国,我看到一些公司在繁忙的城市地区测试送货机器人。
职业问题
安妮·斯普拉特在 Unsplash 上的照片
问题 3:
你能告诉我申请深度学习/计算机视觉工程师的工作需要什么条件吗?
回答:
大多数 ML/CV 工程角色需要精通至少两种编程语言的人,而 Python 是业界最受欢迎的。
此外,使用云计算服务提供商的经验,如 GCP 、 AWS 、 Azure 也很受欢迎,但他们往往是一个可取的要求。
拥有使用 PyTorch、TensorFlow 或 Keras 等机器学习库的经验是大多数(如果不是全部)ML 工程师职位广告的标准要求。
以下是深度学习/计算机视觉角色的一般要求:
- 编程语言知识(Python,JavaScript,Java,C 等。).
- 软件工程经验。
- 了解深度学习架构,如 CNN、RNN 和 DNN。
- 使用 PyTorch、Keras 或 TensorFlow 等机器学习库的经验。
- 拥有 GCP 和 AWS 等云服务的经验。
- 经验建设应用程序,以解决常见的计算机视觉任务,如对象检测,姿态估计,人脸检测等。
技术问题
布莱克·康纳利在 Unsplash 上拍摄的照片
问题 4:
人工智能目前对视频的分析有多好,人工智能视频分析的未来是什么样的?
回答:
直接回答你的问题,深度学习技术一般可以很好地分析视频。
深度学习技术已经足够好,能够描述视频的内容和背景。
例如,人工智能非常擅长在连续的视频帧中跟踪多个个体,还可以对视频进行面部识别,而人类可能甚至无法做到这一点。
姿势估计的深度学习解决方案能够从视频数据中实时检测人体关节的位置。
人工智能视频分析的前景非常光明。在未来,我们可能会看到视频分析应用于大多数形式的现场娱乐,如足球比赛、流媒体音乐会等等。
对我来说,这似乎是合乎逻辑的一步。
描绘一个场景,目前,当我们看足球或任何运动时,我们听人类评论员。我相信在未来的十年或二十年内,我们会看到人工智能评论员的出现。
看看这个视频总结了分析真人打网球视频的研究工作,然后生成令人印象深刻的网球比赛游戏。
问题 5:
在计算机视觉和人工智能领域,线性代数和微积分有多重要?作为一名初学者,我应该在这些数学分支领域中涵盖哪些主题?
回答:
从学术角度来看,理解线性代数对于深入了解计算机视觉和深度学习中的特定主题至关重要。
在深度学习和卷积神经网络出现之前,许多计算机视觉技术利用了大量严重依赖数学的启发式直觉和算法。
一个简单的例子是使用数学函数将图像数据从一种状态转换到另一种状态的典型转换或增强算法。
如果我们转向计算机视觉中更高级的主题,如深度学习,那么理解微积分对于理解神经网络如何学习的一些基本概念是必不可少的。
反向传播和优化算法的主题是基于数学的。
从学术角度来看,理解与机器学习相关的所有数学领域将为你的研究提供优势。
问题 6:
你是否利用了许多预先训练好的模型/库,等等。?
回答
在专业环境中,你倾向于利用许多预先训练好的模型。
简单来说,你很少会从零开始开发算法或神经网络(除非你在 ML research 工作)。
在看实用的 AI 时,更强调软件工程和 ML 模型集成。
库方面, TensorFlow 在实际用例中使用,特别是配合 TFlite 库。TensorFlow Lite 专注于边缘设备上的 ML 配置。PyTorch 和 Keras 也是行业标准。
不太需要开发新的算法或技术来解决已经解决的问题。
一些标准的机器学习库已经有性能良好的 ML 和深度学习架构方法和类可用。
结论
作为一名学者或专业人士,试图掌握人工智能是相当具有挑战性的。
对我们来说幸运的是,一般的人工智能和数据科学社区在某种程度上是有帮助的,并且愿意帮助那些刚开始使用 CUDA 或者似乎无法修复 CUDA 内存不足错误的人!
如果本文包含的问题没有一个适用于你,或者你想问我更多与机器学习相关的问题,那么请在本文的评论部分随意提问。
我会尽我所能回应。或者其他读者可能有你想问的问题的答案。
正如我所说的,我们有一个反应灵敏、乐于助人的人工智能社区。
我希望这篇文章对你有用。
要联系我或找到更多类似本文的内容,请执行以下操作:
一个值得追求的想法?
towardsdatascience.com](/how-im-using-smartwatch-sensors-to-limit-covid-19-infection-51abe04f81f9) [## 专注于技术深度学习的文章
发现解释卷积神经网络,算法,计算机视觉的内部工作的文章…
towardsdatascience.com](/technical-deep-learning-focused-articles-7ad3b0fe3b5a)
加入人工智能创业公司之前,你需要问的 6 个问题
意见
评估人工智能工作真正由一家初创公司完成的程度
克拉克·斯坦利(来源:维基共享)
克拉克·斯坦利,也被称为“响尾蛇之王”,是 19 世纪末的一位著名企业家。斯坦利从牛仔变成了医生,他是第一个开始销售“蛇油”作为治疗多种疾病的灵丹妙药的商人。在芝加哥一次研讨会上的一次臭名昭著的演示中,斯坦利拿了一条活响尾蛇,把它切开,放入沸水中,撇去浮在表面的脂肪,以显示他的蛇油的真实性。公众欣然接受。他的蛇油大受欢迎。
但是有一些问题。大的。
1)史丹利的蛇油并没有做到它宣称的那样。它没有声称的治疗疾病的功效。
2)此外,与所有营销噱头一样,你看到的并不总是你得到的。在卖了 20 多年“斯坦利的蛇油”后,当局终于检查了他的神奇药水。他们在里面发现了矿物油、牛肉脂肪、辣椒和松节油!没有发现任何蛇油的迹象。
这场欺诈是斯坦利精心策划的,持续时间如此之长,以至于直到今天,“蛇油推销员”这个委婉的说法都是指欺诈性的推销和与事实相去甚远的说法。
那么为什么我在 AI 的背景下谈论蛇油推销员呢?
有人说过一句名言,“数据是新的石油”。确实如此。但你知道新的“蛇油”是什么吗?人工智能!
请允许我解释。今天,无论你看向哪里,都有人在做某事(或许多事!)用人工智能。AI 无处不在。到处都是。虽然在很多方面都是如此——我们确实在生活的很多很多方面使用人工智能——但问题在于这个术语的解释有多松散。就像闪光的不都是金子,计算机做的一切都不是人工智能。非常简单地说,人工智能指的是机器变得智能,以复制人类的行动和/或决策来实现既定目标。(更多详情还可以在这里 )阅读我关于解码 AI 的文章。
这种欺骗性的人工智能主导的营销对初创公司生态系统的影响是深远的。
全球各地的初创公司都在吹捧许多事情是由人工智能驱动的,但实际上几乎没有真正的人工智能。由于大多数人几乎不理解人工智能到底是什么,他们没有自己的过错,他们陷入了所有的噱头。2019 年进行的一项调查发现,在欧洲近 2900 家人工智能初创公司中,有 40%没有以任何实质性的形式使用人工智能。
人工智能和机器学习等术语已经成为全球风投的诱饵,这一事实无助于这项事业。投资者排队购买任何远称人工智能邻近的东西。事实上,上面引用的同一项调查得出结论,声称从事人工智能工作的初创公司比其他软件公司吸引的资金多 15%至 50%。因此,初创公司有一个几乎合理的理由试图不择手段地在人工智能生态系统中定位自己。
如果有一个利益相关者群体为初创公司快速松散地使用人工智能术语付出了沉重的代价,那就是潜在的员工。有成千上万的年轻专业人士,有些刚刚大学毕业,正在寻找在新兴的数据科学和人工智能领域工作的梦想。他们被打造下一个人工智能独角兽的承诺以及获得解决最前沿分析问题的机会所吸引。然而现实可能与此相去甚远,这将导致全面的失望和遗憾。员工感觉被欺骗了,公司不得不处理高员工流动率的问题,这需要知识转移,甚至重新启动开发工作(这总是一个昂贵的提议!).
因此,作为一家人工智能创业公司的潜在员工,你必须提出正确的问题,并评估该公司正在做或计划做的事情的深度。作为一家人工智能或人工智能初创公司的创始人,你最好提前告诉潜在的团队成员,数据科学团队应该做什么。
在过去 15 年多的时间里,我一直在数据科学、人工智能和机器学习领域工作,我遇到了许多幻想破灭的年轻人,他们以为自己注册了一份光荣的职业,但却发现他们的大部分时间都花在了清理或标记数据集上。以下是我一直建议他们在面试人工智能初创公司的工作时应该问的问题。这不仅有助于潜在员工更好地理解他/她正在从事的工作,也向创始人表明你理解其中的细微差别。
1.服务还是产品?
这是一个重要的区别。一个人在人工智能服务公司所做的工作将与在产品公司非常不同。虽然服务通常会提供更多的多样性,但是构建一个产品会更深入。
2.如果是服务,那么是什么样的服务?
在大多数情况下,服务工作类似于咨询,即向客户提供人工智能解决方案或模型,以解决特定的问题陈述。因此,重要的是要问清楚,初创公司为其客户处理的是什么样的问题陈述?问题陈述是否有很大的差异,或者它们是否有一个定义明确的集合?
此外,您希望参与服务交付的哪一部分—数据聚合/清理、模型构建、手动训练集创建等。?重要的是要意识到总会有繁重的工作要做,但是要对实际模型开发、技术研究等所花费的时间比例有所了解。总是有帮助的。
3.如果是产品,那么是什么样的产品?
绝大多数人工智能初创公司都会落入产品类别。但并不是所有的产品都一样。能够更多地了解初创公司正在构建的产品类型,可以提供对可能涉及的数据科学或机器学习工作的深入了解。下面是创业公司通常会涉及的产品类型的大致指南。
图 1:人工智能产品类型
一旦你理解了正在构建的人工智能产品的类型,深入挖掘,找出你将参与产品开发的哪个具体方面?理解中长期产品愿景也很有帮助——初创公司的创始人通常会(希望如此!)对他们如何设想他们的产品的发展有一个公平的想法。
4.正在使用的技术堆栈是什么?
这个问题很重要,原因有二。首先,它将帮助你对产品愿景有所了解。其次,如果你加入这家公司,它还会帮助你评估是否有你可能需要学习或温习的特定技能或语言。
5.他们通常会使用什么类型的数据来构建和测试模型?
这个问题之所以重要,是因为它有助于区分小麦和谷壳。深度致力于人工智能优先战略的初创公司将非常了解他们用于产品开发的数据。例如,一家公司希望开发一种产品,该产品使用计算机视觉技术,让机器通过分析 ct 扫描图像来预测癌症的发生,该公司需要访问大型图像库来训练和建立模型。
如果你得到了这个问题的可靠答案,你通常可以放心,这家初创公司的基础相对来说是比较牢固的。
6.创始团队的背景?
你可能不需要明确地问这个问题,相反,你可以自己做研究来找出答案。这个问题很重要,因为人工智能在很大程度上是一个技术领域。这也是一个动态的、快速发展的领域。拥有人工智能领域经验的创始人(或创始团队的一部分)对于确保更高的成功概率至关重要,因为他们非常了解挑战,能够指导团队,引导初创公司朝着正确的方向发展。
人工智能和数据科学领域无疑是当今最令人兴奋的领域之一。我们集体刚刚开始触及一切可能的表面——视野是无限的。人工智能的扩散将对世界产生的影响,预计将比工业革命更具戏剧性。
因此,任何足够早进入这个领域的人,随着这个领域的进一步发展,都会有巨大的机会。做出明智的选择,做出明智的选择。当全球各地存在无数真实而令人兴奋的创业机会时,不要陷入白日梦。
Seaborn (Python)中更漂亮和定制的情节的 6 个简单技巧
数据可视化
初学者指南,轻松个性化您的情节
在本帖中,我们将看看一些简单的方法来定制你的情节,使它们在美学上更令人愉悦。希望这些简单的小技巧能帮你得到更好看的剧情,节省你调整个别剧情的时间。
由 Kelli Tungay 在 Unsplash 上拍摄的照片
基线图📊
本帖中的脚本是在 Jupyter Notebook 的 Python 3.8.3 中测试的。
让我们使用 Seaborn 内置的企鹅数据集作为样本数据:
# Import packages
import matplotlib.pyplot as plt
import seaborn as sns# Import data
df = sns.load_dataset('penguins').rename(columns={'sex': 'gender'})
df
我们将使用默认图表设置构建一个标准散点图,并将其用作基线:
# Plot
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
我们将会看到这个情节是如何随着每个提示而改变的。
技巧🌟
您将看到前两个提示是针对单个图的,而剩下的四个提示是针对所有图表的默认设置的。
📍技巧 1:分号
您注意到上一个图中图表正上方的文本输出了吗?抑制该文本输出的一个简单方法是在绘图结束时使用;
。
# Plot
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender');
通过在代码末尾添加;
,我们得到了更清晰的输出。
📍技巧 2: plt.figure()
调整大小通常有利于绘图。如果我们想调整大小,我们可以这样做:
# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender');
当我们调整大小时,图例移到了左上角。让我们将图例移到图表之外,这样它就不会意外覆盖数据点:
# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.2, 1));
如果你想知道如何知道对figsize()
或bbox_to_anchor()
使用什么数字组合,你需要反复试验哪个数字最适合这个图。
📍技巧 3: sns.set_style()
如果我们不喜欢默认样式,此功能有助于更改绘图的整体样式。这包括轴线颜色和背景的美感。让我们将样式更改为白色网格并查看绘图外观如何变化:
# Change default style
sns.set_style('whitegrid')# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.2, 1));
这里有更多的其他选项可以尝试:'darkgrid'
、'dark'
和'ticks'
来找到你更喜欢的一个。
📍技巧 4: sns.set_context()
在前面的图中,标签尺寸看起来很小。使用sns.set_context()
,如果我们不喜欢默认设置,我们可以更改上下文参数。我使用这个函数主要是为了控制图中标签的默认字体大小。通过更改默认值,我们可以节省时间,因为不必为各个图的不同元素(如轴标签、标题、图例)调整字体大小。我们把上下文换成'talk'
再看剧情:
# Change default context
sns.set_context('talk')# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1));
它更容易辨认,不是吗?另一个可以尝试的选项是:'poster'
,这将进一步增加默认大小。
📍技巧 5: sns.set_palette()
如果你想将默认调色板定制成你喜欢的颜色组合,这个功能很方便。我们可以使用 Matplotlib 中的颜色图。这里是可供选择的 Matplotlib 颜色图列表。我们把调色盘换成'rainbow'
再看剧情:
# Change default palette
sns.set_palette('rainbow')# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1));
如果你找不到你喜欢的 Matplotlib 颜色图,你可以手工选择颜色来创建你自己独特的调色板。🎨创建自己调色板的一种方法是将颜色名称列表传递给函数,如下例所示。这里是颜色名称列表。
# Change default palette
sns.set_palette(['green', 'purple', 'red'])# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1));
如果颜色名称不能很好地表达您的需求,您可以使用十六进制颜色构建自己的调色板,以获得更广泛的选项(超过 1600 万种颜色!).这里是我最喜欢的查找十六进制自定义调色板的资源。让我们看一个例子:
# Change default palette
sns.set_palette(['#62C370', '#FFD166', '#EF476F'])# Plot
plt.figure(figsize=(9, 5))
sns.scatterplot(data=df, x='body_mass_g', y='bill_length_mm',
alpha=0.7, hue='species', size='gender')
plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1));
📍技巧 6: sns.set()
根据前面的三个技巧,我希望你能找到你最喜欢的组合(在某些情况下,可以保持默认设置不变)。如果我们要更新图表的默认设置,最好是在导入可视化软件包之后进行。这意味着我们在脚本的开头会有这样一个片段:
# Import packages
import matplotlib.pyplot as plt
import seaborn as sns# Change defaults
sns.set_style('whitegrid')
sns.set_context('talk')
sns.set_palette('rainbow')
使用sns.set()
可以更简洁地更新多个默认值。下面是相同代码的简洁版本:
# Import packages
import matplotlib.pyplot as plt
import seaborn as sns# Change defaults
sns.set(style='whitegrid', context='talk', palette='rainbow')
Voila❕:这是六条建议。以下是调整前后的曲线图对比:
您想访问更多这样的内容吗?媒体会员可以无限制地访问媒体上的任何文章。如果您使用 我的推荐链接 ,成为会员,您的一部分会费将直接用于支持我。
我希望你学会了一些简单的方法来调整你的情节,而不必花太多时间。我希望这篇文章已经给了你一些开始个性化你的情节的想法,并使它们在视觉上更令人愉悦。如果你感兴趣,这里有我的一些帖子的链接:
◼️python 中的探索性文本分析
◼️️ 给熊猫用户的 5 个提示
◼️️ 熊猫中数据聚合的 5 个提示
◼️️ 在熊猫中编写 5 个常用 SQL 查询
◼️️ 在熊猫中编写高级 SQL 查询
再见🏃💨
每个数据科学家都应该知道的 6 个 SQL 技巧
提高分析效率的 SQL 技巧的第 1 部分
数据科学家/分析师应该了解 SQL,事实上,所有从事数据和分析工作的专业人士都应该了解 SQL。在某种程度上,SQL 是一种被低估的数据科学技能,因为它被认为是从数据库中提取数据的必要而不酷的方式,以提供给 pandas 和{tidyverse} —争论数据的更好的方式。
然而,随着行业中每天收集和产生大量数据,只要数据驻留在符合 SQL 的数据库中,SQL 仍然是帮助您调查、过滤和聚合以彻底了解您的数据的最熟练的工具。通过对 SQL 进行切分,分析人员可以识别出值得进一步研究的模式,这常常会导致重新定义分析群体和变量,使之比初始范围小得多。
因此,分析的第一步不是将庞大的数据集转移到 Python 或 R 中,而是使用 SQL 从我们的数据中获得信息性的见解。
在现实世界的关系数据库中,SQL 不仅仅是 SELECT、JOIN、ORDER BY 语句。在这篇博客中,我将讨论 6 个技巧(和一个额外的技巧),让你的 SQL 分析工作更有效,并与 Python 和 r 等其他编程语言集成。
在本练习中,我们将使用 Oracle SQL 处理下面的玩具数据表,该数据表包含多种类型的数据元素,
玩具数据表(带有变量定义)
- COALESCE()记录空/缺失数据
当谈到重新编码丢失的值时,COALESCE()函数是我们的秘密武器,在这种情况下,它将 NULL 值重新编码为第二个参数中指定的任何值。对于我们的例子,我们可以将 NULL_VAR 重新编码为一个字符值‘MISSING’,
这段代码片段返回,
COALESCE()记录空值
然而,一个重要的注意事项是,在数据库中, 缺失值 可以用除 NULL 之外的各种方式编码。例如,它们可以是空字符串/空格(例如,我们表中的 EMPTY_STR_VAR),或者字符串“NA”(例如,我们表中的 NA_STR_VAR)。在这些情况下,COALESCE()不起作用,但是可以用 CASE WHEN 语句来处理它们,
何时对空或 NA 重新编码
以下情况下的输出
***更新 2022:你也可以在我的频道这里看这个博客的视频版,
2。计算运行总频率和累计频率
当我们对给定点的总和(而不是单个值)感兴趣时,运行总计对于潜在分析人群细分和异常值识别非常有用。
下面展示了如何计算变量 NUM_VAR 的累计和累计频率,
累积频率的输出
这是我们的输出(在左边)。
这里有两个技巧,(1)SUM overROWS UNBOUNDED previous将计算到该点的所有先前值的总和;(2)创建一个 JOIN_ID 来计算总和。
我们使用窗口函数进行计算,根据累积频率,不难发现最后一条记录是异常值。
3。查找没有自连接的极值记录
所以我们的任务是返回每个惟一 ID 的 NUM_VAR 值最大的行。直观的查询是首先使用 group by 找到每个 ID 的最大值,然后对 ID 和最大值进行自连接。然而一种更简洁的方式是,
具有最大值的记录
这个查询应该给出下面的输出,显示具有按 ID 分组的最大数量变量的行,
具有最大 NUM_VAR 值的记录输出
4。条件 WHERE 子句
大家都知道 SQL 中用于 subsetting 的 WHERE 子句。事实上,我发现自己更经常地使用条件 WHERE 子句。例如,对于玩具表,我们只想保持满足以下逻辑的行,
—如果 SEQ 变量 in (1,2,3) & diff(日期变量 2,日期变量 1)≥ 0
— elif SEQ 变量 in (4,5,6) & diff(日期变量 2,日期变量 1) ≥1
— else diff(DATE_VAR2,DATE_VAR1) ≥2
现在条件 WHERE 子句就派上用场了,
条件 where 子句
条件 where 子句的输出
前面提到的逻辑应该消除 ID = 19064 的序列 4,5,因为 date2 和 date1 之间的差= 0,这正是上面查询返回的结果。
5。Lag()和 Lead()处理连续行
Lag(查看前一行)和 Lead(查看下一行)可能是我日常工作中最常用的两个分析函数。简而言之,这两个函数允许用户一次查询多行,而无需自连接。更详细的解释可以在这里找到。
假设,我们想要计算两个连续行(按序列排序)之间的 NUM_VAR 差异,
LAG()函数返回前一行,如果没有(即每个 ID 的第一行),PREV_NUM 被编码为 0,以计算如下所示的 NUM_DIFF 之差,
滞后的输出( )
6。将 SQL 查询与 Python 和 R 集成
将 SQL 查询集成到 Python 和 R 中的先决条件是通过 ODBC 或 JDBC 建立数据库连接。由于这超出了本博客的范围,我将不在这里讨论它,然而,关于如何(创建 ODBC 或 JDBC 连接)的更多细节可以在这里找到。
现在,假设我们已经将 Python 和 R 连接到我们的数据库,那么在 Python 中使用 query 的最直接的方法就是将它复制并粘贴为一个字符串,然后调用 pandas.read_sql(),
my_query = "SELECT * FROM CURRENT_TABLE"
sql_data = pandas.read_sql(my_query, connection)
好吧,只要我们的查询是简短的,并且没有进一步的修改,这种方法工作得很好。但是,如果我们的查询有 1000 行,或者我们需要不断地更新它,该怎么办呢?对于这些场景,我们会希望阅读*。sql* 文件直接导入 Python 或者 R .下面演示如何用 Python 实现一个 getSQL 函数,R 中的思路也是一样的,
这里,第一个 arg sql_query 包含一个独立的*。容易维护的 sql* 文件,像这样,
“ID_LIST”是我们将要放入的值的占位符字符串,可以使用下面的代码调用 getSQL()。
额外提示,SQL 中的正则表达式
尽管我并不总是在 SQL 中使用正则表达式,但它有时对于文本提取来说很方便。例如,下面的代码展示了如何使用 REGEXP_INSTR()查找和提取数字的简单示例(更多细节请参见,
我希望这篇博客对你有所帮助,完整的代码和玩具数据集可以在我的 github 中找到。😀
想要更多数据科学和编程技巧?使用 我的链接 注册 Medium,获得我所有内容的全部访问权限。
还订阅我新创建的 YouTube 频道 【数据与 Kat 对话】
此外,请阅读本迷你系列的第 2 部分,了解更多 SQL 分析技巧。
* [## 每个数据科学家都应该知道的额外 4 个 SQL 技巧
充分利用 SQL 加快您的分析工作
towardsdatascience.com](/extra-4-sql-tricks-every-data-scientist-should-know-d3ed7cd7bc6c)*
阻止你的项目脱轨的 6 个步骤
如何撰写能够按时交付的项目计划
rossrail 是欧洲最大的基础设施项目。这是一条 73 英里长的铁路线,直通伦敦市中心。它本应在 2018 年底完工并投入运行。现在预计它将于“2021 年末”开业。这一延迟预计将导致13.5 亿亿的收入损失。
横梁。项目规划的噩梦,失控的螺旋上升…
考虑到与项目超支相关的成本,你可能会认为管理者更擅长于编写他们实际上可以坚持的计划。然而,一次又一次,时间表被打破,预算被抹杀。Stephen J. Dubner(因《魔鬼经济学》而出名)探讨了这一现象,规划谬误——过度乐观和未能从经验中学习的有害混合,导致糟糕的规划,进而导致糟糕的项目结果。
“计划谬误是一种倾向,它低估了完成一个项目所需的时间,而知道类似的项目在过去通常需要更长的时间。因此,这是对一个特定案例的乐观预测与更普遍的知识的结合,而更普遍的知识会提出不同的看法……”——罗杰·布勒教授
即使我们中的大多数人不必担心在一个主要的欧洲城市下面挖掘一条巨大的隧道的复杂性,我们也远远不能避免日常生活中的规划谬误(这就是为什么你的新花园平台仍然没有建设,靠在你房子的一侧)。
准备失败,准备失败
我现在生活中有一个大项目。
我正在完成一门数据科学的课程,一旦毕业,我将搬到一个新的城市,并试图给自己找一份闪亮的新工作。坦白地说,我不能让这个项目对我产生任何负面影响,所以我需要一个无懈可击的项目计划。
尽管我们在这篇博客中关注的是一个相对较小的单人项目,但以下几点适用于规划几乎任何范围的任何项目;与一个 30 人的团队在你的公司推出一个新产品,与一个商业伙伴一起发展一个新公司,或者,事实上,自己在你的花园里建造一个新的平台。管理这些示例项目的主要区别在于实际的实现过程中。
现在,让我们深入我们的六步计划,更好地进行项目规划!
1.定义您的项目范围
这听起来是显而易见的,但是一个真正可靠的项目定义将会为你以后省去一大堆痛苦。为了确保项目定义良好,可以使用 SMART 原则。这通常是在设定目标时部署的(例如,为了职业发展),但它在项目管理中有很多适用性。
- 特异。 深入了解你的项目的产出实际上会是什么的具体细节。“我要搬到伦敦去找份工作”不具体。“我将在伦敦 2 区租一套公寓,并在一家科技公司获得一个数据科学职位”情况开始好转。在这一点上,知道你的项目将而不是实现什么也是值得的。这将有助于防止“范围蔓延”——原始计划中没有考虑到的不可预见的项目增加(因此将导致超支)。
- **可测。你知道你的项目实际上什么时候完成吗?有没有一个可测量的条件或标准能说明这一点?
- 可分配。我们应该能够将项目任务分配给实际上有能力完成它们的人(这对于更大的项目更有意义)。稍后我们将更详细地讨论责任分配。
- 现实主义。尽管有这样一句老话:如果你用心去做,就能做任何事情,但是“用心去做”在一个项目计划中是很难解释的,所以要确保这个项目实际上是可行的。
- 有时限。有没有可能给这个项目设定一个结束日期?如果没有,那么我们会让自己很难“按时”完成…
2.列出项目需要的一切
我指的是 一切 。
虽然“搬到一个新的城市”听起来像是一个独立的“行动”,但这并不是一项简单的任务。事实上,这相当令人生畏——你甚至从哪里开始呢?我之前写了一篇博客,谈到“MECE”问题树是分解复杂分析问题的一种方式。我会在这里采取类似的方法。
如何撰写假设和进行分析,让你的老板刮目相看
towardsdatascience.com](/the-key-question-for-all-data-scientists-so-what-25139fb352c6)
让我们举一个移动城市的例子,并依次将大的、可能势不可挡的行动分解成它们的组成部分。
这个过程只花了我五分钟,但我已经把“移动城市”分解成十个更小、更易管理的任务。我们总是可以进一步推进这个过程(例如,“打包物品”可以分解到房子的不同房间,我们可能希望在不同的日子处理这些物品)。事实上,在这一点上你越细化,你的最终计划就可能越精确。
无论哪种方式,这十个子任务都是需要填充您的项目计划的项目——而不是我们开始时的高级行动。值得注意的是,每个子任务也应该符合 S.M.A.R.T .框架。
3.分配责任
不管你的项目有多大,这一步都很重要。对于我们在上面定义的每项任务,确切地决定谁:
- 将会完成这项任务
- 对完成任务负有责任
这些可能不是同一个人!
当然,你应该确保每项任务都分配给既有能力又有时间完成任务的人。如果一个人被另一个经理拉去做别的事情,那么把任务分配给这个人是没有好处的。
即使你在计划一个人的项目,你也应该完成这一步。看看你列出的所有子任务(并分配给自己)。这对你来说是一个合理的工作量吗?你能自己完成所有的任务吗?注意——如果你需要学习一些东西(例如研究一个特定的 Python 库),那么这个“学习行为”需要成为你计划中的一个单独的项目!
4.对时机要非常诚实
这是成功的项目计划的关键。接受你在第二阶段定义的单个任务,并对每个任务独立完成的时间做一个诚实的评估。
不要把整个项目的最后期限 考虑在内。这将扭曲你对每项任务的判断,并导致你低估它们需要多长时间(这是计划谬误的关键因素之一)。
5.创建关键路径
我们的项目可能会包含必须依次完成的各种任务序列,一个接一个。以我们的“移动城市”为例,这样的顺序可以是:研究居住区域->联系这些区域的房地产经纪人->安排看房->参加看房->选择公寓->支付公寓定金,等等…
当然,我们可以构建另一个序列,在城市之间转移我们的财产。注意,调查搬家公司并不一定要求我事先安排好看房。
项目的 关键路径 是总工期最长的单个序列。下面的视频展示了关键路径计算的数学(比数学更有逻辑性和横向思维!)
本练习的主要收获是:
- 关键路径精确地定义了整个项目需要多长时间
- 不在关键路径中的任务具有一定的灵活性,但会有开始和结束日期的范围,这直接取决于它们对关键路径中其他任务的依赖性
如果关键路径表明你的项目要超支了,你该怎么办?也许给你三个月完成的项目看起来要花四个月…
- 重新检查项目的范围。你想做得太多了吗?
- 增加你花在项目上的活跃天数——你能在其中加入几个周末吗?
- 增加项目的人员配备(使用项目计划草案作为您需要它的证据!)
- 作为最后的手段,试着推迟整个项目的截止日期
你当然应该而不是做的是回去减少你在第四阶段设定的时间估计。请记住,我们在设定这些估计值时是诚实的。现在就改变它们,简单地把所有事情塞进一个任意的时间框架里,就相当于在你开始之前就屈服于计划谬误。
一般来说,你也应该试着为项目建立一个“缓冲区”(计划末尾的空白空间),以便在令人沮丧的可能情况下,出现问题或花费的时间比计划的长。
甘特图可能是可视化项目任务排序的最佳方式。微软 Excel 是一个非常适合手工制作的地方,尽管有软件解决方案可以自动生成它们(如果 Python 是你的障碍,那么 Plotly 有很好的甘特图功能)。
以甘特图表示的项目计划示例。注意紫色的关键路径、职责分配和项目结束时设置的缓冲期,以防万一…
6.实际使用你的计划
你已经花时间写了一个杀手级的项目计划。用吧!
当然,一个项目计划如何实施取决于项目的规模和参与的人数。这不是深入研究scrum 和 sprint的时间和地点,但是,有一些经验法则是适用于所有领域的。
- **根据计划定期检查。**根据项目的规模,可以是每天、每周或每两周一次。确保每个人都充分了解他们应该做什么,并确保这些事情确实在做。
- **保持诚实。**如果你落后于计划,试着理解原因,并解决它。不要把计划藏在抽屉里,忘记它曾经存在过。
- **如果需要,更新计划。如果你低估了某些任务需要的时间,或者其他事情出了大问题,那么你需要修改计划——这没什么不好意思的。理想情况下,你可以吃掉你在第 5 阶段建立的缓冲区。然而,如果这是不可能的,你可能需要以某种方式缩小项目范围。
感谢一路阅读到博客结尾!当然,项目管理还有许多其他方面可以帮助您的项目取得成功,但我希望这已经给了您一个良好的开端。我很想听到对上述建议的任何评论,或者这篇文章涉及的任何概念。欢迎在下方随意留言,或者通过LinkedIn联系我。
关于数据科学,雇主不想让你知道的 6 件事
办公时间
但是你绝对应该了解他们
介绍
由于我的轶事类文章得到了大量的支持,我又写了另一篇。
这一次,我想揭示作为一名数据科学家的黑暗面。这篇文章并不是要打击你,但是像任何其他工作一样,数据科学作为一个职业也有其失败之处。我认为重要的是,你要意识到这些事情,这样当你在生活中遇到它们时,它不会像卡车一样撞上你(就像我一样!).
根据你的个性和兴趣,你可能根本不会发现这些失败,这是一件好事!也就是说,这里有 6 件关于数据科学的事情是雇主不想让你知道的。
1.一个模糊的术语,像“数据科学”,意味着模糊的责任。
你对数据科学了解得越多,你就越会意识到数据科学有多广泛。事实上,它是如此广泛,以至于有专门针对不同类型的数据科学工作的文章(数据科学家、数据分析师、决策科学家、研究科学家、应用科学家、数据工程师、数据专家……你懂的)。
此外,由于它是一个多学科领域,术语“数据科学”涵盖了各种各样的技能,很可能超出了您一生所能完善的范围。
因此,在您的数据科学之旅中,请牢记这些事情…
- 保持开放的心态,尽量不要停留在数据科学迷人的部分。例如,如果您发现自己在查询表或处理数据架构,而不是处理机器学习模型,请不要气馁。任何与数据相关的技能都是需要了解的有价值的技能,将来很可能会派上用场!
- 和第一点类似,数据科学没有固定的路径。因此,抓住任何机会,从每个机会中尽可能多的学习。你获得的经验越多,你将来的选择就越多。
- 最后,最重要的是,不要对你想做的事情设定如此严格的期望,直到你有足够的经验和知识去做。乞丐不能挑肥拣瘦!
TLDR:在数据科学之旅中保持开放的心态。这不仅仅是建造模型。
2.您使用 SQL 的次数很可能比您想象的要多得多。
刚开始职业生涯的时候,我一直认为 SQL 是只有数据分析师才会用的技能。因为我一开始就有这种心态,所以我从来没有重视过我在 SQL 方面的知识。
这绝不是你思考 SQL 的方式!
如果你从事的是与数据相关的工作,不管是不是数据科学的工作,SQL 永远不会离开你。
作为一名数据科学家,如果你想建立机器学习模型,你将需要数据,这意味着你要么必须查询你的数据,要么如果数据尚不存在,你必须建立管道。非常重要的一点是,您要很好地了解 SQL,这样您的数据才是健壮的和可伸缩的。
TLDR: SQL 永远是你最好的朋友,所以一定要花时间精通它。
3.现实世界中的数据比你想象的还要混乱。
如果你曾经在 Kaggle 上处理过数据,那么现实世界是完全不同的。在 Kaggle 上,数据通常是干净的,每个表都有描述,每个列和特性名称都相当直观。
现实世界并非如此。你不仅不可能拥有我上面列出的任何东西,而且你可能没有可靠的数据来开始。
我写了 10 篇关于的文章,我不得不处理非常混乱的数据,但只是举几个例子:
- 处理不同拼写的类别,例如美国、美国、美国、美利坚合众国
- 在逻辑受损的地方处理数据。例如,如果有记录显示某个用户卸载了同一个应用程序两次,而没有在两次卸载之间重新安装它……哎呀。
- 处理不一致的数据。例如,一个表可能告诉我,我们的月收入是 50,000 美元,但另一个具有类似信息的表可能说我们的月收入是 50,105 美元。
TLDR:你的大部分时间将用于清理你的数据。你不太可能直接进入模特行业。
4.很大一部分时间花在理解手头的业务问题上。
不管你喜不喜欢,数据科学家在很大程度上是一名业务分析师。为什么?因为你需要对你工作的领域和手头的业务问题有一个全面的了解。没有这一点,您将会错过关键的关系、假设和变量,这些可能是 65%准确模型和 95%准确模型之间的差异。
例如,如果你是营销部门的数据科学家,你必须完全了解每种类型的营销渠道,它的用途,它在营销漏斗中的位置,它通常吸引什么类型的用户,以及使用什么指标来评估给定的渠道。
举个例子,商展一般比联盟营销贵很多( CAC 的更高)。然而,从商展中获得的客户的 LTV 也更高。如果你建立了一个只关注 CAC 的模型,你可能会给出不完整的信息,导致不再通过商展进行营销。
TLDR:在投入任何模型构建之前,应该花相当一部分时间来理解业务问题和你正在工作的领域。
5.你不需要知道所有的工具,但是你知道的越多越好。
在以前的一篇文章中,我说过最好专注于几个工具并真正擅长它们。我仍然坚持这一观点,但可悲的现实是,你的雇主很可能希望你不断进步,学习更多的工具。
你应该非常了解你的基本工具。这意味着 Python、SQL 和 Git,以及包括 Pandas、NumPy、scipy、scikit-learn 等几个 Python 库…
然而,如果你的雇主抛出新工具让你尽快学习,不要感到惊讶,比如 Airflow、Hadoop、Spark、TensorFlow、Kubernetes 等等。
此外,如果你在职业生涯中换了雇主,你可能需要学习一套新的工具,因为每个公司都有自己想要的技术,所以在选择新雇主时要小心。
TLDR:学习永无止境。如果你不喜欢这种说法,数据科学可能不适合你。
6.沟通技巧是你最好的朋友。
这本书更适合那些认为成为一名数据科学家意味着你可以整天躲在房间里构建模型的人。无论任何雇主告诉你什么,即使他们说你可以全天候在家工作或作为一个团队工作,你也需要与其他利益相关者合作和交流。
即使你是一个人的团队,你也必须与高层管理人员就你正在做的工作及其带来的切实业务影响进行沟通。您可能还需要与其他团队和业务分析师合作,来构建我们之前讨论过的领域知识。
TLDR:数据科学需要比你想象的更多的交流,这对成为一名成功的数据科学家很有帮助。
感谢阅读!
通过阅读这篇文章,我希望我能够给你一些(更多)见解和有用的建议,这将有助于消除你的一些误解,并使你的数据科学之旅比我的顺利得多!
我收到了对我更有见解的数据科学文章的非常好的反馈,这就是我写这篇文章的原因。像往常一样,如果你不同意我说的任何话,请有所保留。但是如果你喜欢它,请让我知道你还想让我写些什么。
我一如既往地祝你们在数据科学之旅中一切顺利!
不确定接下来要读什么?我为你挑选了另一篇文章:
到目前为止,我在数据科学之旅中学到的见解
towardsdatascience.com](/5-things-i-wish-i-knew-when-i-started-learning-data-science-24d6f9a2d1e0)
特伦斯·申
- 如果你喜欢这个, 跟我上 Medium 了解更多
- 报名我的邮箱列表 这里 !
- 我们连线上LinkedIn
- 有兴趣合作?查看我的 网站 。
我在脸书教 R 学到的 6 件事
格雷格·布拉在 Unsplash 上的照片
在工作场所有效使用 R 的技巧
B2018 年至 2019 年间,我在脸书工作,担任数据科学家——在此期间,我参与开发和教授一个面向 R 初学者的课程。这是一个为期两天的课程,大约一个月一次,大约有 15-20 名学生参加,目标是让他们能够在日常工作中使用 R。
这篇文章分享了我在教授这些课程中学到的一些东西,重点是对学生有效的东西。希望这六个建议对任何使用 R 的人都有用,尤其是那些刚刚开始旅行的人。
但是首先,我个人学习 R 的经历
我最初是在伯克利读统计学本科时学到 R 的。在大学里,我鄙视使用 R,并把它作为完成项目和习题集的一种手段,这样我就可以毕业了。
一旦我进入职场,开始从同事那里学习 R,我对这门语言的看法开始转变。我意识到在大学里如何教授 R 有一些关键的差距——主要是我们在课堂环境中学习 R,这不能很好地转化为工作环境。
大学毕业后,我开始完全接受 R——我在脸书和 Doordash 开发过 R 包,在脸书教过 R,也参加过几次 R 会议。由于我的背景不清楚,我想分享一些技巧和建议给那些在日常生活中使用 R 的人。
注意:我是 2015 年大学毕业的,所以课程可能会有所改进,所以我的个人经历可能与最近的大学毕业生不太相关。
1.r 不仅仅是数据科学家的专利,有一个使用这种语言的理由会让学习变得更容易
在教授 R 之前,我假设我们的大部分学生都是数据科学家,希望通过将 R 引入他们的 SQL/Excel 工作流来增加他们的影响力。然而,我真的对参加这些课程的人的多样性感到惊讶。我们有软件工程师、数据科学家、数据工程师、研究人员和财务/运营人员,仅举几例。
照片由普里西拉·杜·普里兹在 Unsplash 上拍摄
对于数据科学家来说,他们参加这门课的主要原因很清楚——他们经常与数据打交道,学习 R 将为他们提供一种更有效、更灵活的数据处理方式。此外,学习 R 会更自然,因为他们有很多机会练习语言,同时对他们的工作产生直接影响。
当试图了解为什么其他一些学生报名参加该课程时,有各种各样的原因,例如:
- 希望提高数据修改和可视化能力的工程师。
- 运营和财务部门正在寻找每天/每周重复更新 Excel 的替代方案。
- 已经熟悉 R,但想在脸书大学更新知识并学习如何有效使用它的人。
在上面的三个例子中,我们看到了非数据科学家可以从学习 R 中获得价值的方法。一般来说,如果您不是数据科学家/分析师,您希望成为这两类人中的一员:
- 你已经在做一些事情了,通过学习 R,你可以做得更好/更快
- 你想做一些事情,但是如果不知道 R (或者其他一些编程语言),那将会非常困难/不可能
关于这个话题的最后一点——有时 R 并不是工作的最佳工具。例如,如果您已经知道如何使用 SQL+Excel,那么您就已经拥有了聚合、分析和可视化数据的致命工具组合。在我自己使用 R 大约 7 年之后,我经常发现自己求助于 SQL + Excel,仅仅是因为它更快,更容易共享。所以,如果你花了很多时间学习 R,不要觉得你需要把它用在所有事情上,因为有时它实际上会比你使用你已经是专家的工具花费两倍的时间。
2.蒂德维斯是国王
资料来源:tidyverse.org
什么是****?tidy verse 是专为数据科学设计的 R 包的自以为是的集合。所有的包共享一个底层的设计哲学、语法和数据结构。
tidy verse 中最流行和最有用的两个包是:
资料来源:tidyverse.org
为了使这一部分简明扼要: Tidyverse 是在 R 中聚集和修改数据的最快和最直接的方法。不仅如此,它使学习 R 变得更加有趣和容易。我第一次在没有 Tidyverse 的情况下学习 R,这是一次悲惨的经历,其他以类似方式学习 R 的人分享了我的观点。Tidyverse 在 R 用户中变得如此普遍,以至于我不建议学习/教授没有它的 R。
如果你从未使用过 Tidyverse,它的设置非常简单,我强烈建议你开始使用它(网上有很多资源可以学习)
# This is all you need to install tidyverse:install.pacakges('tidyverse')
library(tidyverse)
注: 我在本文后面引用了一些软件包,如果你曾经需要安装一个新的软件包,你可以使用上面的函数来这样做。安装后,使用library()
将其加载到 R 中
3.备忘单,备忘单,备忘单
这与前一个主题非常吻合,因为 Tidyverse 独特的语法和长长的函数列表让学习 tidy verse 的人望而生畏。幸运的是,RStudio 团队已经创建了一堆备忘单。对于我们的面授课程,我们会确保为所有学生打印备忘单,这样他们就不必不停地切换标签来搜索功能。如果你可以的话,我强烈推荐你打印和层压你自己的小抄供个人使用。即使已经使用这种语言超过 5 年,我仍然会参考我的小抄。
该网站包含 RStudio 团队发布的清单。这里的一些主题更高级,但我想说下面是两个入门的基本备忘单:
来源:https://rstudio.com/resources/cheatsheets/
来源:https://rstudio.com/resources/cheatsheets/
4.通过使用内部数据集进行学习
在上课的第一个小时内,我们让学生将内部数据库中的数据查询到 r 中。在脸书,这就像使用我们的内部软件包并编写以下代码一样简单:
df <- presto("SELECT * from example_table limit 10000")
我建议使用内部数据集学习有两个主要原因:
- 能够直接在简历中查询内部数据增强了你使用公司数据的能力。如果您不能将内部数据直接查询到 R 中,您必须采取某种变通办法,例如将数据导出到 csv 文件中,然后将其读入 R 中。这浪费了大量时间,因此我会尽可能早地熟悉如何将数据直接导入 R 中,即使这意味着额外的一两个小时的初始设置/获得正确的权限。
- ****公司的数据是其最有价值的资源之一。如果你在脸书工作,那么你应该利用你拥有世界上最丰富、最有趣的数据集这一事实。这同样适用于任何其他公司——优步的乘车数据,Airbnb 的预订数据,Medium 的商品数据。许多在线资源会让你使用通用数据集,所以我会尝试采取额外的步骤,在可能的情况下引入关键的公司数据集来帮助你学习。通过这样做,你已经有了将 R 放松到你的工作流程中的想法。
5.导入和导出数据的重要性
R 是分析数据的一个很好的工具,但是如果你不能把数据输入或输出 R,那就真的是一个很大的问题。前一节稍微提到了这一点,所以这一节更实用,回顾了一些将不同类型的数据输入/输出 r 的主要方法。
通过关注这些方法,你应该能够几乎 100%地导入/导出必要的东西。当然,还有一个备忘单,你可能会发现对这很有帮助:
来源:https://rstudio.com/resources/cheatsheets/
用于导入数据:
- Csv:
read_csv()
(Tidyverse) - Excel:
read_excel()
(Tidyverse) - Google Sheets: 与上面类似,但是对于私有工作表可能需要额外的步骤。你想用谷歌工作表的软件包。最坏的情况是,你将谷歌表单导出为 csv 格式,并使用
read_csv()
读取 - ****内部数据库:使用 SQL 将数据直接导入 r。您需要咨询您的数据团队,看看是否有内部包来完成这项工作。在脸书,
presto("SELECT * FROM tbl")
是你从表格中抓取数据所需要的全部。在较小的公司,将 R 连接到内部数据库可能需要一些额外的步骤,但是至少建立 ODBC 连接应该可以让你获取数据。
用于导出数据:
- 复制到剪贴板:
clipr
包中的write_clip()
将数据帧直接复制到您的剪贴板中。如果你的公司使用 Google Sheets,这是获取数据的最快方式,所以这是你可以学习的最有用的功能之一。本质上,它减少了从Export df to csv -> Open csv and copy contents -> Paste into Sheets
到Copy df to clipboard -> Paste into Sheets
的步骤 - 复制一个 plot/graph: 当你在 R 中做了一个 graph,最简单的分享出来的方法就是复制/粘贴。简单地放大一个图,使它进入自己的窗口,你可以右键单击并复制图像。
- ****直接从 R 截图:如果你想更非正式地分享出一张小桌子(即 Slack),给你的 R 主机截图大概是最好的选择。如果你想变得更有趣,你可以使用
knitr
包中的kable()
功能来清理你的桌子,以便更容易阅读。
# Format the iris table to be a little neateriris %>% head %>% kable
这就是结果
- 写入 CSV:
- ****写入内部数据库:这通常比从内部数据库读取要复杂得多,但是如果您认为您会经常这样做,那么肯定会与您的数据团队讨论。
6.保持简单,专注于基础
你可以用 R 做很多事情,一开始可能会有点不知所措。例如,仅在备忘单链接中,您就已经看到了 R 能够处理的如此多的主题/包,甚至这还只是皮毛。不要被这个暗示。
我们发现专注于基本面是学习 R 的最好方法:
- 如何导入数据
- 用
dplyr
修改数据进行分析 - 使用
ggplot2
创建可视化效果 - 导出结果以与您的队友共享
如果你能做好这些,那么你就有了用 r 做很多事情的坚实基础。
结束语
我想写这篇文章是因为我喜欢在脸书教授 R 课程,并且认为我作为一名教师的独特经历可以对那些没有机会接触这类课程或者正在寻找在自己的工作中更有效地使用 R 的建议的人有所帮助。
掌握 K-均值聚类需要知道的 6 件事
了解最流行的聚类方法之一
亚历山大·安德鲁斯在 Unsplash 上拍摄的照片
市场上有多少种类型的客户?NBA 有多少种类型的球员?常春藤盟校有多少种学生?
现实生活中有很多这样的问题——这些问题试图理解特定环境中的人(以及物体)的类型。通过了解我们对什么类型的人感兴趣,我们可以制定相应的策略来满足我们的特殊需求。
例如,我们假设市场研究发现市场上有两种类型的客户——一种对价格上涨更敏感,另一种对价格上涨不太敏感。通过研究你产品的顾客,你可以决定是否要提高产品价格来弥补增加的成本。假设你的大多数顾客对价格敏感,那么如果你决定提价,你应该更加小心潜在的销售下降。
这只是一个说明聚类分析实际应用的小例子。这是来自维基百科页面的聚类定义。
聚类分析或聚类是对一组对象进行分组的任务,使同一组中的对象(称为聚类)比其他组(聚类)中的对象彼此更加相似(在某种意义上)。
与上面给出的例子相关,为你的产品识别客户类型的过程是进行聚类分析。需要注意的是,聚类方法有很多种,最常用的一种叫做 K-means 聚类。在本文中,我将回顾 K-means 的一些关键方面,并希望您对这种流行的聚类方法有更好的理解。
在我们开始研究 K-means 之前,下图直观地向您展示了一个常见的 K-means 如何通过多次迭代来达到最终的聚类结果。
来自 K-means 维基百科(由 Chire 创作,授权: CC BY-SA 4.0 )
1.K-means 是基于原型的。
第一个问题是我们如何确定聚类,或者我们如何确定一个特定的样本应该被分配到哪个聚类。有几种可用的聚类方法,包括基于连接性的(即分层的)、基于网格的、基于分布的、基于密度的和基于原型的。其中 K-means 聚类属于基于原型的范畴。
为了概念化基于原型的聚类方法,您可以认为对于每个聚类,都有一个原型数据点,它表示特定聚类的典型成员应该是什么样子。应该注意的是,原型数据点是从属于该聚类的数据点估计的,并且不必是原始数据集的实际情况。
然而,一些算法要求原型数据点必须是实际的数据点,这被称为 K-medoid 聚类。在大多数涉及连续特征的应用中,K 均值指的是使用质心作为原型数据点。
2.聚类分配和迭代
使用如上所示的动画图像作为例子,假设我们已经为聚类选择了三个质心作为初始种子。我们如何确定应该将样本分配给哪个组?
要指定一个数据点,我们需要计算该数据点和我们刚才选择的每个质心之间的距离。距离被认为是数据点之间的相似性-数据点与质心之间越接近越相似。最常用的度量是平方欧几里德距离(sed),如上所示。如果考虑一个二维特征,它基本上是我们最熟悉的笛卡尔平面上两个数据点之间的距离。
截图来自维基百科
通过计算这些距离,我们能够将数据点分配给产生最小 SED 的聚类。一旦分配了每个数据点,我们就能够为我们的聚类获得更新的质心,并计算每个聚类中所有适用 SED 的误差平方和(SSE)。如果你熟悉机器学习的术语。您可以将类内 SSE 视为 K 均值聚类试图最小化的成本函数的输出,这使得 K 均值或多或少成为一个优化问题。
在下一次迭代中,我们将数据点分配给更新后的质心,并再次计算 SSE 以查看它是否减少。直到没有进一步的改进(上证指数已经变得足够小和稳定),我们可以得出结论,K 均值聚类已经完成。
3.您必须事先指定聚类的数量。
当我们运行 K-means 聚类分析时,我们必须指定聚类的数量,先验。这有时被认为是 K-means 方法的一个缺点,因为对于某些数据集,我们不知道有多少个聚类是合理的。毕竟,我们没有关于我们的数据点所属的聚类的基本事实,否则,如果我们有,它就变成了一个监督学习任务。
如果我们只处理 2 维或 3 维数据,我们可以将数据可视化,以获得一些关于聚类数量的假设。然而,对于更高的维度,以人类可理解的方式可视化数据是不太可能的。因此,您最好使用相关的背景内容专业知识,并对您的数据的大概聚类数进行有根据的猜测。以此为起点,看看您的集群效果如何。
但是突出的问题是 当我们有不同数量的聚类时,我们如何评估哪一个聚类性能比其他的好。
4.聚类评估和肘方法
我们已经在第 2 节中讨论了使用 SED 的数据点聚类分配和使用 SSE 的迭代优化。在迭代结束时,我们得到了一个 SSE 最少的模型(所有成员的特定集群分配)。
通过改变同一数据集的每次聚类分析的聚类数,我们可以得出每个模型的 SSE 值。有了这些数据,我们可以绘制一个线图,作为聚类数和 SSE 值的函数,后者通常被称为失真。下面显示了一个假设聚类模型的简单示例。
肘法(作者自创)
如图所示,当簇数为 3 时,有一个急转弯。这意味着除了这三种聚类方法之外,我们的聚类性能没有任何有意义的提高(没有多少降低)。因此,说 3 是一个很好的聚类数是有意义的。
请注意,除了肘方法,我们还可以使用侧影图来评估不同聚类数的模型之间的性能。如果你感兴趣,这里有一篇关于这个话题的极好的中型文章。
5.你需要标准化你的数据点。
当 K-means 聚类有多个特征时,这些特征的初始数据集可能有不同的尺度。例如,让我们说一个尺度是以米为单位测量的学生身高,另一个尺度是以千克为单位测量的体重。正如您所料,这些尺度的方差绝对值可能会非常不同。
对于身高,方差可能在小数值水平,然而,体重可以有大得多的方差。当我们的 K-means 聚类迭代优化模型时,它会尽最大努力更多地依赖于减少权重贡献的 SSE。看到问题了吗?通过或多或少地忽略来自高度尺度的贡献,优化将走捷径。
解决方案是,我们应该通过将单个尺度带到相同或相似的范围水平来标准化数据点。通常,我们可以运行 Z 分数归一化,并对每个要素使用标准化的 Z 分数。或者,您也可以运行最小-最大缩放。请注意,这两种方法的性能将取决于数据集,并且没有关于哪一种方法一定比另一种方法更好的固定规则。
6.初始化很重要
当我们运行 K-means 聚类分析时,我们从随机选取的质心开始。通过多次迭代,我们将能够得到一个 SSE 达到最小值的模型——这个最小值可能与随机选取的初始质心直接相关。如前所述,质心迭代更新,每次迭代都建立在前一次迭代的结果上。
因此,我们将得到的最终模型将与第一次迭代之前选取的质心相关。换句话说,质心的初始化直接影响我们得到的最终模型。
因此,在实践中,例如,在 scikit-learn 实现中,我们通常多次运行 K-means 聚类分析,并在这些模型中挑选最佳表现者。虽然我们可以随机选择初始质心,但更好的方法是使用所谓的 K-means++初始化方法。简而言之,K-mean++不是随机选择质心,而是一种使用概率分布来挑选初始质心的算法,这提高了 K-means 聚类的性能。
顺便提一下,在 scikit-learn K-means 实现中,默认的初始化方法是 K-means++方法,所以我们不需要担心初始质心的选择。
结论
总之,本文回顾了进行 K-means 聚类分析的一些关键方面。下面是一个典型的 K 均值聚类分析步骤的快速概述。
- 使用 K-means++初始化方法选取初始质心,其数量与指定的聚类数匹配(请注意,我们可以使用 elbow 方法来确定特定数据集的聚类数)
- 使用平方欧几里得距离(SED)将数据集的每个数据点分配到最近的质心
- 用每个簇中的所有成员更新质心
- 通过最小化组内误差平方和(SSE)重复前两步
- 在指定的迭代次数之后,或者模型没有更好的改进(例如,SSE 中的变化),我们得到了最终的模型
寻找新数据科学项目的 6 个技巧
当你陷入困境时的想法
由 Unsplash 上的absolute vision拍摄
如今很难找到新的项目创意,灵感也不总是在我们需要的时候出现。你可能会发现自己盯着天花板,等待一个新的想法出现在你的脑海里。然而,它可能永远不会到来。想法和灵感对每个人来说都不容易,对于数据科学家来说,问题也不例外。
当开始一个新项目时,大多数数据科学家都想尝试一些从未听说过的东西,甚至可能是革命性的东西。他们可能会想到这个疯狂的、开箱即用的项目,但一旦他们开始研究它,他们会发现以前有人做过,甚至可能比他们想象的还要好。
很多时候,似乎所有好的项目想法都被采纳了。也许你应该在此期间求助于 Kaggle 数据挑战?您可以利用这一实践来磨练您刚刚从在线课程中学到的新数据科学工具和技能。但通常这些挑战已经为你准备了很多东西,你可能想自己收集数据。所以你要回到起点。
寻找灵感
新思想不能被制造或强迫。也许通过一场激烈的头脑风暴,你会找到灵感,但通常灵感来自最不可能的地方,最不可能的时间。以下是一些帮助你的大脑思考新的数据科学项目想法的提示:
詹姆斯·庞德在 Unsplash 上拍摄的照片
提示 1:考虑小问题
不要把问题当成新项目。是的,一个新项目是你需要做的事情,但是不要让它成为你的主要焦点。相反,把你的注意力集中在你日常生活中遇到的一些问题上。你在浏览互联网时有哪些小的不便?也许可以写一个程序来解决这个问题。你希望你能自动化你每天做的一个简单的任务吗?写一个程序来实现这一点。
不要让你的注意力集中在改变整个世界上,而是集中在更小的事情上,让你自己的世界变得更好。
秘诀 2:不要限制自己
数据科学是一个广泛的学科,可以应用于多个不同的学科和行业。也许你是那种关注科技世界的人,因为这是你所知道的。这种关注的一个潜在问题是,现在你只能想到与技术相关的问题。这可能是一个问题,因为你现在过于狭隘地专注于一个主题。
将你的关注点转向更广泛的话题和行业。也许其他行业也需要你的帮助。有时候,他们需要的只是一个不在现场的人的新观点。当你扩展你的关注点时,你会变得对这些主题的其他观点更加开放。你可能会解决一个新的问题,这个问题是你以前过于专注时从未遇到过的。
约翰·施诺布里奇在 Unsplash 上的照片
技巧 3:询问他人
朋友、家人和熟人可能是一大资源。询问他们的想法,因为他们会有完全不同的观点。每个人都有自己独特的障碍,与你的不同。您可以用您的数据科学技能帮助他们克服这些障碍。
他们也可以帮助你头脑风暴出新的想法。人多力量大,独自做事并不是寻找灵感的最佳方式。
Artem Beliaikin 在 Unsplash 上拍摄的照片
秘诀 4:退后一步,继续你的一天
有时候你只需要退后一步,把项目搁置起来。做好你的一天,也许你会想到一个主意。假装你没有项目要做,也许你会想到一个项目的主意。去看一部新的电视节目或电影。也许你的新项目想法隐藏在一些随机的节目或互联网视频中。
也许拖延这个项目正是你需要做的。然而,你应该注意不要拖延太久。给自己一个足够长的休息时间,让你的大脑重新定位,然后也许一个新的想法就会出现。
克里斯蒂安·威迪格在 Unsplash 上拍摄的照片
技巧 5:搜索互联网
也许为一个项目寻找新想法的最简单的方法之一就是在网上浏览多个不同的论坛。谷歌是你的朋友。只需搜索“ ”数据科学项目创意 ”,多个结果和创意展现在你面前。
这种方法的唯一问题是,这些项目中的大多数可能不会引起你的兴趣。另一个问题是,他们也缺乏原创性,因为有许多其他数据科学家已经做了和正在做同样的项目。如果你采取这种方法,你将很难从人群中脱颖而出。
米格尔·安德拉德在 Unsplash 上的照片
技巧 6:增加普通项目的趣味
寻找那些简单或常见的数据科学项目,并使它们变得更复杂。采用项目中的提示,并在其中添加一些内容。收集原始数据,而不是通过抓取其他网站来使用提供的数据集。在提示中添加另一个问题,这可能会使您不得不改变整个项目方法。基本上是让事情变得更难,让自己与众不同。
即使你可能会使用一个其他人已经有过的项目想法,你也会通过改变一些东西来使它变得独一无二。在对最初的项目想法做了足够多的改变后,你甚至可能最终得到一个完全不同的项目。
开始您的项目
一旦你找到了你的项目想法,那么你就可以开始开发你的数据科学项目。为这个项目提出一个想法是一个困难的方面,但它不是这个过程的唯一部分。展望未来,你将不得不考虑你完成这个项目的方法。你将从哪里获得数据?需要如何处理?诸如此类的问题会在项目开发过程中出现。但这些问题是好的,这意味着你作为一名数据科学家,正在自己的发展中取得进步。
当您继续进行未来的数据科学项目时,我们希望您会发现这些提示对您探索数据科学项目想法很有用!
可解释主题模型的 6 个技巧
关于调整 LDA 主题模型以获得易于理解的输出的 Python 实践教程。
随着如此多的文本在数字平台上输出,自动理解关键主题趋势的能力可以揭示巨大的洞察力。例如,企业可以从了解客户围绕其品牌和产品的对话趋势中受益。提取关键主题的一种常用方法是潜在狄利克雷分配(LDA)。然而,输出通常很难解释为有用的见解。我们将探索提高可解释性的技术。
什么是潜在狄利克雷分配(LDA)?
潜在狄利克雷分配(LDA)是一种生成统计模型,有助于在不同数据部分的集合中提取相似性。在主题建模中,每个数据部分是一个 word 文档(例如产品页面上的单个评论),文档集合是一个语料库(例如产品页面上的所有用户评论)。重复出现的相似单词集合可能指示主题。
LDA 假设每个文档由固定数量的主题分布表示,每个主题是单词分布。
近似这些分布的算法的高级关键步骤:
- 用户选择 K,即当前主题的数量,调整到适合每个数据集。
- 浏览每份文件,并随机将每个单词分配到 K 个主题中的一个。由此,我们有了计算主题 p 的文档分布(主题 t |文档 d) 、文档 d 中分配给主题 t 的单词的比例的起点。我们还可以计算单词 p 的主题分布(单词 w |主题 t) 、单词 w 在分配给主题 t 的所有文档单词中的比例。由于随机性,这些将是较差的近似。
- 为了提高近似性,我们遍历每个文档。对于每个文档,浏览每个单词并重新分配一个新主题,其中我们根据上一轮的分布以概率 p(主题 t |文档 d)÷p(单词 w |主题 t) 选择主题 t。这本质上就是题目 t 生成单词 w 的概率。从这些新作业中重新计算 p(题目 t |文档 d)和 p(单词 w |题目 t)。
- 不断迭代,直到主题/单词分配达到稳定状态,不再有太大变化,(即收敛)。使用最终分配来估计每个文档的主题混合(该文档中分配给每个主题的单词的百分比)和与每个主题相关的单词(该单词分配给每个主题的总次数)。
数据准备
我们将探索在亚马逊 Office 产品评论上使用 LDA 优化可解释性的技术。为了准备评论数据,我们使用典型的文本清理步骤来清理评论文本:
- 删除非 ascii 字符,例如à∅
- 将单词转换为最基本的形式,如“running”和“ran”到“run ”,以便它们被识别为同一个单词
- 删除标点符号
- 删除非英语注释(如果有)
教程中的所有代码都可以在这里找到,这里清理的函数位于 clean_text.py,整个过程的主笔记本是 topic_model.ipynb 。
优化可解释性的步骤
提示 1:通过 n 元语法识别短语,过滤名词型结构
我们想要识别短语,以便主题模型能够识别它们。二元词是包含两个词的短语,例如“社交媒体”。同样,三元组是包含 3 个单词的短语,例如“Proctor and Gamble”。有很多方法可以检测 n-gram,这里解释这里。在本例中,我们将使用*点态互信息(PMI)得分。*这衡量了单词比独立出现时更有可能同时出现。该度量对罕见的单词组合敏感,因此它与出现频率过滤器一起使用,以确保短语相关性。下面的二元模型示例(三元模型代码包含在 Jupyter 笔记本中):
**# Example for detecting bigrams** bigram_measures = nltk.collocations.BigramAssocMeasures()finder =nltk.collocations.BigramCollocationFinder\
.from_documents([comment.split() for comment in\ clean_reviews.reviewText])**# Filter only those that occur at least 50 times** finder.apply_freq_filter(50)
bigram_scores = finder.score_ngrams(bigram_measures.pmi)
此外,我们过滤带有名词结构的二元或三元模型。这有助于 LDA 模型更好地聚类主题,因为名词是正在谈论的主题的更好指示符。我们使用 NLTK 包来标记词性并过滤这些结构。
***# Example filter for noun-type structures bigrams* def** bigram_filter(bigram):
tag = nltk.pos_tag(bigram)
**if** tag[0][1] not in ['JJ', 'NN'] and tag[1][1] not in ['NN']:
return False
**if** bigram[0] in stop_word_list or bigram[1] in stop_word_list:
return False
**if** 'n' in bigram or 't' in bigram:
return False
**if** 'PRON' in bigram:
return False
**return** True***# Can eyeball list and choose PMI threshold where n-grams stop making sense
# In this case, get top 500 bigrams/trigrams with highest PMI score*** filtered_bigram = bigram_pmi[bigram_pmi.apply(lambda bigram:\ bigram_filter(bigram['bigram'])\
and bigram.pmi > 5, axis = 1)][:500]bigrams = [' '.join(x) for x in filtered_bigram.bigram.values\
if len(x[0]) > 2 or len(x[1]) > 2]
最后,我们将这些短语连接成一个单词。
**def** replace_ngram(x):
**for** gram **in** bigrams:
x = x.replace(gram, '_'.join(gram.split()))
**for** gram **in** trigrams:
x = x.replace(gram, '_'.join(gram.split()))
**return** xreviews_w_ngrams = clean_reviews.copy()
reviews_w_ngrams.reviewText = reviews_w_ngrams.reviewText\
.map(lambda x: replace_ngram(x))
提示 2:过滤名词的剩余单词
在“商店很好”这个句子中,我们知道这个句子是在说“商店”。句子中的其他单词提供了关于主题(“商店”)本身的更多上下文和解释。因此,对名词进行过滤可以提取出对主题模型更具解释力的单词。另一种方法是过滤名词 和动词 。
**# Tokenize reviews + remove stop words + remove names + remove words with less than 2 characters**
reviews_w_ngrams = reviews_w_ngrams.reviewText.map(lambda x: [word for word in x.split()\
if word not in stop_word_list\
and word not in english_names\
and len(word) > 2])**# Filter for only nouns
def** noun_only(x):
pos_comment = nltk.pos_tag(x)
filtered =[word[0] for word in pos_comment if word[1] in ['NN']]
**return** filteredfinal_reviews = reviews_w_ngrams.map(noun_only)
提示#3:通过连贯性测量优化主题数量的选择
LDA 要求指定主题的数量。我们可以通过优化预测似然性、困惑度和一致性等指标来调整这一点。许多文献表明,最大化一个被命名为Cv【1】的一致性度量,会导致更好的人类可解释性。我们可以测试许多主题并评估 Cv 衡量标准:
coherence = []
for k in range(5,25):
print('Round: '+str(k))
Lda = gensim.models.ldamodel.LdaModel
ldamodel = Lda(doc_term_matrix, num_topics=k, \
id2word = dictionary, passes=40,\
iterations=200, chunksize = 10000, eval_every = None)
cm = gensim.models.coherencemodel.CoherenceModel(\
model=ldamodel, texts=final_reviews,\
dictionary=dictionary, coherence='c_v')
coherence.append((k,cm.get_coherence()))
绘制此显示:
在 15 个主题后,改善停止。Cv 最高的地方并不总是最好的,所以我们可以尝试多个来找到最好的结果。我们在这里尝试了 15 和 23,23 产生了更清晰的结果。添加主题有助于揭示更多的子主题。尽管如此,如果相同的单词开始出现在多个主题中,那么主题的数量就太多了。
提示#4:调整 LDA 超参数
Lda2 = gensim.models.ldamodel.LdaModel
ldamodel2 = Lda(doc_term_matrix, num_topics=23, id2word = dictionary, passes=40,iterations=200, chunksize = 10000, eval_every = None, random_state=0)
如果您的主题仍然没有意义,尝试增加遍数和迭代次数,同时将 chunksize 增加到您的内存可以处理的范围。
**chunksize**
是每次训练要加载到内存中的文档数。**passes**
是通过整个语料库的训练迭代次数。**iterations**
是每个文档达到收敛的最大迭代次数——限制这意味着一些文档可能无法及时收敛。如果训练语料有 200 个文档,**chunksize**
为 100,**passes**
为 2,**iterations**
为 10,算法经过这几轮:
第一轮:文件 0–99
第二轮:文件 100–199
第三轮:文件 0–99
第四轮:文件 100–199
每一轮将迭代每个文档的概率分布分配最多 10 次,如果已经达到收敛,则在 10 次之前移动到下一个文档。这基本上是前面解释的算法的关键步骤 2-4,重复**passes**
的数量,而步骤 3 重复 10 **iterations**
或更少。
在每个**chunksize**
和每个**passes**
之后,更新整个语料库的主题分布。增加**chunksize**
到你的内存可以处理的程度将会提高速度,因为主题分布更新是昂贵的。然而,增加**chunksize**
需要增加**passes**
的数量,以确保足够的语料库主题分布更新,特别是在小语料库中。**iterations**
还需要足够高,以确保大量文档在继续前进之前达到收敛。当主题仍然没有意义时,我们可以尝试增加这些参数,但是日志记录也可以帮助调试:
import logging
logging.basicConfig(filename='gensim.log',
format="%(asctime)s:%(levelname)s:%(message)s",
level=logging.INFO)
在日志中查找如下所示的行,它将重复您设置的**passes**
的数量:
2020-07-21 06:44:16,300 - gensim.models.ldamodel - DEBUG - 100/35600 documents converged within 200 iterations
在**passes**
结束时,大部分文档应该已经收敛了。如果没有,增加**passes**
和**iterations**
。
提示 5:使用 pyLDAvis 可视化主题关系
Python 中的 pyLDAvis 包给出了两条重要的信息。圆圈代表每个主题。圆圈之间的距离显示了主题的关联性。这些通过对每个主题的概率分布之间的距离进行降维(PCA/t-sne)映射到 2D 空间。这表明我们的模型是否开发了不同的主题。我们希望调整模型参数和主题数量,以最小化圆圈重叠。
主题距离也显示了主题的相关程度。专题 1、2、13 讨论电子产品(打印机、扫描仪、电话/传真)。象限 3 中的主题如 6、14、19 是关于办公文具(包装材料、便利贴、文件管理器)。此外,圆圈大小代表主题流行度。例如,主题 1 构成了文档中被谈论的主题的最大部分,构成了标记的 17.1%。
提示#6:调整相关性分数,以优先考虑更专属于某个主题的术语
代表给定主题的单词可以排名较高,因为它们在语料库中是全局频繁的。相关性分数有助于优先考虑更专门属于给定主题的术语,使主题更加明显。术语 w 与主题 k 的相关性被定义为:
其中,ϕ_kw 是单词 w 在主题 k 中的概率,ϕ_kw/p_kw 是术语在主题中的概率相对于其在整个语料库中的边际概率的提升(这有助于丢弃全局频繁出现的术语)。λ越低,第二项(ϕ_kw/p_kw)越重要,第二项越重要,主题排他性越重要。为此我们可以再次使用 pyLDAvis。例如,当将λ降低到 0.6 时,我们可以看到主题 13 对与电话主题更相关的术语进行了排序。
调整λ以获得最有意义的结果,并应用最佳λ值以获得输出:
all_topics = {}
lambd = 0.6 ***# Adjust this accordingly***
**for** i **in** range(1,22): ***#Adjust number of topics in final model***
topic = topic_data.topic_info[topic_data.topic_info\
.Category == 'Topic'+str(i)]
topic['relevance'] = topic['loglift']*(1-lambd)\
+topic['logprob']*lambd
all_topics['Topic '+str(i)] = topic.sort_values(by='relevance\
, ascending=False).Term[:10].values
决赛成绩
从这里,我们可以围绕这些主题关键词进一步分析情感(例如,搜索相关的形容词或评论星级)。在业务应用程序中,这提供了对客户认为重要的主题的洞察,以及他们对此的感受。这使得有针对性的产品开发和客户体验的改善成为可能。这个例子包含了各种各样的产品,但是每个产品的单独主题模型可能揭示了客户关心的方面。例如,这一分析已经开始揭示计算器(主题 21)的重要方面,如显示器、易按按钮、电池、重量。然后,销售者需要确保在他们的产品描述中突出这些特征,或者提高这些方面的竞争力。
来源:
[1]迈克尔·罗德尔、安德里亚斯都、亚历山大·欣内堡、 探索话题连贯的空间措施)
[2]卡森·西维尔,肯尼斯·e·雪莉,LDAvis: 一种可视化和解释主题的方法
DS/ML Gods 无需尝试即可提高精确度的 6 种方法
通过使用这些简单的技巧,轻松提高你的准确度!
(手 src =http://www.pngplay.com/image/18115
介绍
机器学习是一个复杂多样的话题,对于新的数据科学家来说,这肯定会令人望而生畏。通常很难让你的模型达到令人满意的 98%的精确度,初学者肯定会努力让他们的模型更精确。幸运的是,对于大多数数据科学家来说,您可以做大量的事情来潜在地缓解这样的问题,因此,有时找到高精度的方法更多地涉及到找出您的模型需要什么样的数据。
№1:特征缩放
使用连续模型时,提高精度的最简单、最有效的方法之一是缩放模型的要素。存在几种不同类型的特征缩放器,其中一些甚至可能对机器学习没有好处。这些标量中最重要的很可能是标准标量。标准缩放器、z 分数缩放器或正态缩放器使用正态分布来归一化数据。这提高了准确性,因为偏离正常影响的数字与正常情况相比减少了。这样做的好处是你不会丢失数据,但它对你的准确性仍然很有价值。还有另外两个可以用在机器学习中,均值归一化和单位长度缩放。然而,这些通常不会被很好地使用,在大多数情况下,你最好使用标准的定标器。
为了计算正态分布,我们将取一组数字中的每个数字,在除以标准偏差之前减去平均值。在代码中,它看起来有点像这样:
using Lathe.stats: mean, std
array = [5,10,15,20]
q = std(array)
mu = mean(array)
[i = (i-mu) / q for i in array]
我们会得到一些类似这样的数字:
假设这个数组的平均值是 13.5 是安全的,所以 13.5 实际上在我们的正态分布上等于 0。然而,这有点误导,因为如果我们的数据中有 13.5,它将移动分布中的零。
你可能遇到的另一个缩放器是均值规格化器。为了根据平均值对数据进行标准化,我们用平均值减去每个样本,然后用最小值减去最大值。在代码中,这看起来像这样:
avg = mean(array)
a = minimum(array)
b = maximum(array)
[i = (i-avg) / (b-a) for i in array]
请注意结果中的细微差异:
№2:移除异常值
另一个令人难以置信的简单且令人惊讶的提高模型准确性的方法是去除数据中的异常值。从数据中移除异常值有多种方法,其中一种很好的方法是使用 z 值。另一种方法是去掉数据中第三个四分位数以上的值。我们这样做的原因是,这些值当然会影响我们对数据的数学表示,如均值或标准差。这几乎肯定会导致模型(很可能根据平均值和标准偏差等值工作)根据您的杂散数据预测低或高。
从这类数据中移除异常值的最简单方法是用平均值替换任何有问题的值。首先,我们将获得第三个四分位数的数据。或者,你可以得到高于平均值的所有数据的平均值。
对于这个例子,我们将切换到 Python。在本文中,我将同时使用这两种语言,因为它们非常相似,同时使用这两种语言将使双方的开发人员更容易理解。考虑以下数据帧:
如果我们要为这些数据拟合一个模型,那么无论我们决定为我们的功能使用哪一列,都会有一些非常激进的异常值,这肯定会在将来给我们带来一些问题。为了删除它们,我们将从 scipy.stats 中获取 z_score,并使用条件掩码来过滤不符合条件的值,以从根本上抑制高于正态分布中心的值:
from scipy import stats
import numpy as np
z_scores = stats.zscore(df)abs_z_scores = np.abs(z_scores)
filtered_entries = (abs_z_scores < 2).all(axis=1)
new_df = df[filtered_entries]
现在如果我们显示 new_df,我们可以看到我们的异常值消失了!
№3:移除不良特征
通过修改数据来轻松提高精度的另一个好方法是移除不良要素。这太常见了—您有正确的模型,但没有正确的数据。尽管很多时候一些特性看起来很重要,但它们未必如此。经常有一些功能可能根本不会提高你的分数,事实上,它们甚至会使你的准确度更差。所以不好的功能肯定是要小心的!
但是你如何避免它们呢?
避免在模型中使用不良特征的最佳方法是使用统计测试来衡量该特征对目标的统计显著性。另一个很好的方法是获取特性的重要性,这在某些情况下可能有点困难,但是如果不是,这肯定比统计测试简单得多。
№4:一个热编码器->顺序编码器
使用分类变量进行机器学习的最广泛使用的预处理方法之一可能是 one hot 编码器。one hot coder 获取您的数据,并将其转换为给定列中所有类别的真或假二进制批处理。one hot encoder 非常有用,因为它能够将分类特征转化为数字数据,便于数学算法进行分析。
虽然一个热编码很好,但在很多情况下,顺序编码器会给你更好的准确性。顺序编码本质上涉及到将唯一的标签映射到整数值。另一个可能有用的编码器是标签编码器。
№5:特征工程
解决这类问题的一个更困难的方法是特征工程。特征工程允许您从可用的特征中创建新的特征,以获得更高的精度。虽然特性工程有时可能很难做到,但它肯定可以在很多时候创造出很高的准确性,如果特性很重要,从长远来看,它肯定是一项有益的投资。
№6:集成算法
我认为在这个领域有一点被稍微低估了,那就是样本提升和引导汇总的能力。这可能是数据科学家提高准确性的最常见方式之一。
Bootstrap aggregating 也称为 bagging,是一种集成元算法。使用 bootstrap aggregating 的一个好处是,它还减少了数据的方差,从而大大减少了像过度拟合这样的偏差问题。另一方面,Boosting 通常涉及使用许多模型来一起解决一个问题。它还可以减少方差,并有助于减少偏差和防止过度拟合。
结论
虽然数据科学肯定是一门很难的学科,随着你继续从事它,你将需要学习越来越多的东西,但你可以做一些相当简单和容易的事情来使你的模型更好,并创建更好的算法。这些不仅难以置信的简单,而且很多可以提高你 10%以上的准确率。不用说,使用这些方法当然是一个伟大的想法!
让您的数据科学项目脱颖而出的 6 种方法
提高您的数据科学项目并获得关注的简单步骤
全球新冠肺炎疫情让许多人有大量的时间来处理他们的数据科学项目组合。每个人都在申请工作,你如何确保你的工作脱颖而出?请继续阅读,寻找答案。
1.使用更多独特的数据
兰迪·法特在 Unsplash 上的照片
Iris,Galton,Titanic,Northwind Traders,Superstore,Go 数据仓库。当您在学校学习数据科学时,您无疑会遇到至少一个这样的数据集。这是有原因的,它们有助于演示诸如聚类、回归、逻辑回归、数据库结构、数据可视化或构建报告等概念。每个数据集都很干净,很小,但这并不是它们所有的共同点:每个人都使用过这些数据集。没有新的或令人兴奋的项目建立在训练数据集上。没有招聘人员会看着你的泰坦尼克号项目(Kaggle 上最受欢迎的数据集之一)说,我们的团队需要这个人。
没有新的或令人兴奋的项目建立在训练数据集上
我们生活在数据时代,这意味着不缺少可以轻松下载的数据集。从比 Kaggle 或你在其上学习机器学习的数据更令人兴奋的地方获取你的数据。拓展业务的好地方是 Data.gov。2013 年,奥巴马总统签署了一项行政命令,将开放和机器可读数据作为政府信息的新默认。这意味着有大量可搜索的信息可以从 Data.gov 下载。联邦学生贷款计划数据、联邦对各州的援助数据和意外药物相关死亡数据只是可供您使用的 200,000 多个数据集的一小部分。请务必查看文件中提供的元数据,以便理解您正在处理的内容。
想让事情变得更私人一点吗?用自己的数据!你做的任何事情都可以变成数据。许多健身房在“呆在家里”命令期间关闭,也许你在家工作。你正在做的所有练习都可以被追踪。看看你做了多少次,你在锻炼哪些肌肉群,以及哪天你在锻炼。使用你自己的数据的最大好处是你是主题专家。您可能最终会处理一些较小的数据集,但是您将对它是如何被捕获的有更深刻的理解,并且可以控制向它添加新的变量或维度。
这些听起来都不够先进吗?看看网页抓取。网络搜集是从互联网上收集非结构化数据的自动化过程。您将不得不用诸如 R 或 python 之类的语言编写代码来捕获数据。你必须自己研究你获得的价值,以及你抓取的网站是如何获得这些价值的。最终结果将更加独特,但也将产生更多的工作来了解数据和清理您收集的数据。
2.做一个数据清理项目
说到数据清理,真实世界的数据很恶心,使用它的时候一定要戴上口罩。玩笑归玩笑,当有人要求一个使用数据来预测客户流失的模型时,几乎从来没有一个干净的、现成的数据源来构建这个模型。大多数课程不会让您准备好处理组织可用的各种脏数据。这是一项关键技能,你需要在至少一个项目中展示出来。
说到数据清理,真实世界的数据很恶心
有许多任务可以与清理数据相关联。理解数据是一个很好的起点。政府和公共可用数据通常有一个数据字典,其中包含数据中每个维度、度量、观察和表的描述。这将帮助您了解收集了哪些数据、何时收集的以及由谁收集的。
理解你在看什么是数据验证的关键。一旦你知道什么是变量,你就可以使用数据字典、常识或主题专家来确定哪些值没有意义。例如,温度应该落在某个数值范围内。如果是温度数据,并且数据字典将测量单位指定为开尔文,则任何 0 或负值都是可疑的。如果这是来自百慕大的温度数据,气温升高是有道理的。在这里,任何太热或太冷的东西都是可疑的。对于像制造焊接温度这样的事情,你可能想找一位教授或工程系学生给你更多的指导。这一步的关键是找到看起来不对的值。
另一个需要研究的领域是如何处理缺失值。像数据验证一样,在处理缺失值时,上下文也很重要。如果您正在查看汽车的金融贷款数据,并且贷款信誉良好,并且收楼状态的值缺失,您不会担心该值缺失。如果你的项目涉及心理评估,而你错过了很多问题的答案,你可能会采取不同的行动,比如消除观察。有时缺失值在您的上下文中是有意义的。与数据验证一样,与您的主题专家和同行合作,了解如何处理丢失的值。
有时缺失值在您的上下文中是有意义的
3.使用版本控制
在做数据科学项目时,你可能会花很多时间与其他人一起工作,这只是使用版本控制的众多原因之一。如果您不熟悉版本控制,它将所有代码保存在一个地方,并允许多人同时使用它。每个人都可以添加他们的贡献,并审查他人的代码。如果有人离开公司,将最新的代码转移到其他人的机器上不会与 IT 部门发生冲突。所有代码都存在于一个集中的、有组织的存储库中。
所有代码都存在于一个集中的、有组织的存储库中
另一个困扰学生的问题是命名文件的版本。再也不会有 20 个版本的“project_02_final.py”与“project _ 12 _ final _ done _ finished . py”不同了。有了版本控制,每个版本都有注释,您可以与任何其他版本的代码进行逐行比较,以查看删除了什么和添加了什么。您甚至不必担心旧版本被删除,您总是可以回滚到旧版本的代码。
版本控制软件最好的一点是,一旦你开始使用,它就很容易使用。它可以是一个独立的程序,可以集成到您喜欢的集成开发环境(IDE)中,也可以通过命令行界面使用。许多系统都有额外的功能,允许您基于您的存储库创建一个网站,测试您的代码的构建,并通过将代码嵌入到其他地方来共享您的代码。这不仅是一种让你的项目有条理的方法,也可以用来开始展示你的项目。
4.构建您的表示层
亚历克斯·利特温在 Unsplash 上的照片
数据科学家这个术语仍然相对较新,高管不完全理解数据概念的情况并不少见。无论他们是否对数据科学和机器学习有深刻的理解,他们都需要一种方法来快速获得您的项目必须提供的最重要的信息。这是你的表示层。
大多数有抱负的数据科学家没有足够重视沟通技巧。解释如何在云中使用并行计算来训练和测试一个模型,然后使用自定义 API 部署给其他人使用,不会引起任何人的注意。管理层不会总是对你如何做这件事感兴趣,而是对你为什么做这件事感兴趣。这并不是说技术方面不重要,而是要记住你的观众。业务方面将希望了解您的模型对底线的影响,而 it 方面将更关心 IT 的实际实现。
大多数有抱负的数据科学家对沟通技巧关注不够
您的表示层可以采用许多不同的形式。再次强调,记住你的听众。有些人只想要电子表格和表格,而有些人想要图表和颜色。一些人希望通过电子邮件发送,另一些人希望在同一页上看到不同地区的所有数据。利用您可以使用的工具,针对不同的受众创建不同的表示层。
5.尝试各种技术
大学一毕业,我经历的最困难的事情之一就是看到我想去的公司有职位空缺,却没有任何相关的技术技能。许多公司都在努力解决入职和内部培训的问题。对他们来说,雇佣一个已经知道他们需要什么的人要容易得多。熟悉更广泛的技术将有助于你的搜索。许多组织甚至将多种技术结合在一起,以拼凑他们的数据管道和数据科学环境。
有一个老笑话说,数据科学 80%是准备数据,20%是建立模型。这是有道理的。我曾经和一些数据科学家一起工作过,他们在一个项目上花费了大量的时间让代码在服务器上而不是在他们的桌面上正确运行。我曾在一些小公司面试过,在这些公司里,数据科学家需要与数据工程师密切合作,构建数据结构来收集数据并支持他们的模型。使用多种语言和软件包来构建数据科学项目的不同部分有巨大的好处。
数据科学 80%是准备数据,20%是构建模型
外面有大量的资源,学习一门新技术或编程语言并不一定很难或很贵。当然,有专业指导的培训,费用可能超过 1500 美元,但也有几乎任何东西的免费视频,学生们只需拥有一个. edu 电子邮件地址,就可以免费享受许多昂贵软件包的许可和培训。在他们的网站上搜索,看看有什么。一旦你学会了一种软件或语言,学习另一种类似的软件或语言通常不会太难。如果你能使用强力 BI,Tableau 并不难用。
6.将所有内容整合到一个管道中
罗曼·彭丁在 Unsplash 上拍摄的照片
说到多种工具,为什么不一起使用它们呢?作为一名学生,很多时候你会得到简单格式的数据,例如. csv。这不是不可能得到的。csv 文件,但数据通常不会以这种方式存储。数据将来自多个来源,具有多个转换和存储层,并且会涉及许多不同的技术。你的项目的一个小管道表明你理解这些部分如何一起工作。
每个人都知道如何阅读. csv 文件
管道可以非常简单,只需将文件加载到数据库中,选择数据并将其导入分析工具,然后将结果发送到表示层。它不一定要漂亮或完全自动化,它只需要展示你对数据管道如何工作的理解。每个人都知道如何阅读. csv 文件,但不是每个人都可以将数据、分析和演示过程集成到一个连贯的项目中,以反映组织是如何做的。
摘要
这绝不是一个全面的列表,但会给你一些如何让你的数据科学项目引起注意的想法!请记住,数据科学项目是您技能的直接反映。通过将这些技能应用到反映真实世界数据科学复杂性的项目中,展示您擅长的东西。确保使用有趣的数据,清理数据,使用版本控制来保持有序,有效地传达您的信息,使用各种技术,并将一切结合在一起,以实现真正全面的数据科学项目。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
realdrewdata.medium.com](https://realdrewdata.medium.com/membership)
测试您对 Python 列表的了解的 60 个问题
通过掌握列表基础知识粉碎算法问题
我最近做了很多算法问题,发现我并没有像应该的那样理解列表
这是我为评估自己的知识而写的 60 个问题的汇编。
我希望你会发现它对我和写作一样有用。
问题 1–10:
1.检查列表是否包含元素
如果列表中有特定的元素,那么in
操作符将返回 True。
li = [1,2,3,'a','b','c']'a' in li
#=> True
2.如何同时遍历 2+个列表
您可以使用zip()
列表,然后遍历zip
对象。zip
对象是元组的迭代器。
下面我们同时迭代 3 个列表,并将值插入到一个字符串中。
name = ['Snowball', 'Chewy', 'Bubbles', 'Gruff']
animal = ['Cat', 'Dog', 'Fish', 'Goat']
age = [1, 2, 2, 6]z = zip(name, animal, age)
z #=> <zip at 0x111081e48>for name,animal,age in z:
print("%s the %s is %s" % (name, animal, age))
#=> Snowball the Cat is 1
#=> Chewy the Dog is 2
#=> Bubbles the Fish is 2
#=> Gruff the Goat is 6
3.什么时候你会使用列表而不是字典?
列表和字典通常有稍微不同的用例,但是有一些重叠。
我得出的算法问题的一般规则是,如果你可以两者都用,那就用字典,因为查找会更快。
列表
如果你需要存储一些东西的顺序,使用一个列表。
即:数据库记录的 id,按照它们将被显示的顺序排列。
ids = [23,1,7,9]
从 python 3.7 开始,列表和字典都是有序的,列表允许重复值,而字典不允许重复键。
字典
如果你想计算某事的发生次数,就用字典。比如家里宠物的数量。
pets = {'dogs':2,'cats':1,'fish':5}
每个键在字典中只能存在一次。注意,键也可以是其他不可变的数据结构,如元组。即:{('a',1):1, ('b',2):1}
。
4.列表是可变的吗?
是的。请注意,在下面的代码中,与内存中相同标识符关联的值没有发生变化。
x = [1]
print(id(x),':',x) #=> 4501046920 : [1]x.append(5)
x.extend([6,7])
print(id(x),':',x) #=> 4501046920 : [1, 5, 6, 7]
5.一个列表需要同质吗?
不可以。不同类型的对象可以混合在一个列表中。
a = [1,'a',1.0,[]]
a #=> [1, 'a', 1.0, []]
6.追加和扩展有什么区别?
.append()
在列表末尾添加一个对象。
a = [1,2,3]
a.append(4)
a #=> [1, 2, 3, 4]
这也意味着追加列表会将整个列表作为单个元素添加,而不是追加它的每个值。
a.append([5,6])
a #=> [1, 2, 3, 4, [5, 6]]
.extend()
将第二个列表中的每个值作为自己的元素相加。所以用另一个列表扩展一个列表会合并它们的值。
b = [1,2,3]
b.extend([5,6])
b #=> [1, 2, 3, 5, 6]
7.python 列表是存储值还是指针?
Python 列表本身并不存储值。它们存储指向存储在内存中其他地方的值的指针。这使得列表是可变的。
这里我们初始化值1
和2
,然后创建一个包含值1
和2
的列表。
print( id(1) ) #=> 4438537632
print( id(2) ) #=> 4438537664a = [1,2,3]
print( id(a) ) #=> 4579953480print( id(a[0]) ) #=> 4438537632
print( id(a[1]) ) #=> 4438537664
注意链表是如何拥有自己的内存地址的。但是列表中的1
和2
与我们之前定义的1
和2
指向内存中相同的位置。
8.“del”是做什么的?
del
从给定索引的列表中删除一个项目。
这里我们将删除索引 1 处的值。
a = ['w', 'x', 'y', 'z']
a #=> ['w', 'x', 'y', 'z']del a[1]a #=> ['w', 'y', 'z']
注意del
没有返回被移除的元素。
9.“移除”和“弹出”有什么区别?
.remove()
删除匹配对象的第一个实例。下面我们去掉第一个b
。
a = ['a', 'a', 'b', 'b', 'c', 'c']
a.remove('b')
a #=> ['a', 'a', 'b', 'c', 'c']
.pop()
根据索引删除对象。
pop
和del
的区别在于pop
返回弹出的元素。这允许使用类似堆栈的列表。
a = ['a', 'a', 'b', 'b', 'c', 'c']
a.pop(4) #=> 'c'
a #=> ['a', 'a', 'b', 'b', 'c']
默认情况下,如果没有指定索引,pop
会删除列表中的最后一个元素。
10.从列表中删除重复项
如果你不关心维护一个列表的顺序,那么转换成一个集合再转换回一个列表就可以实现这个目的。
li = [3, 2, 2, 1, 1, 1]
list(set(li)) #=> [1, 2, 3]
问题 11–20:
11.查找第一个匹配元素的索引
例如,您想在水果列表中找到第一个“苹果”。使用.index()
方法。
fruit = ['pear', 'orange', 'apple', 'grapefruit', 'apple', 'pear']
fruit.index('apple') #=> 2
fruit.index('pear') #=> 0
12.从列表中删除所有元素
我们可以用.clear()
从现有列表中清除元素,而不是创建一个新的空列表。
fruit = ['pear', 'orange', 'apple']print( fruit ) #=> ['pear', 'orange', 'apple']
print( id(fruit) ) #=> 4581174216fruit.clear()print( fruit ) #=> []
print( id(fruit) ) #=> 4581174216
或者用del
。
fruit = ['pear', 'orange', 'apple']print( fruit ) #=> ['pear', 'orange', 'apple']
print( id(fruit) ) #=> 4581166792del fruit[:]print( fruit ) #=> []
print( id(fruit) ) #=> 4581166792
13.遍历列表中的值及其索引
将计数器添加到作为参数传递的列表中。
下面我们遍历列表,将值和索引传递给字符串插值。
grocery_list = ['flour','cheese','carrots']for idx,val in enumerate(grocery_list):
print("%s: %s" % (idx, val))
#=> 0: flour
#=> 1: cheese
#=> 2: carrots
14.如何连接两个列表
+
操作符将连接两个列表。
one = ['a', 'b', 'c']
two = [1, 2, 3]one + two #=> ['a', 'b', 'c', 1, 2, 3]
15.如何用列表理解操作列表中的每个元素
下面我们返回一个新的列表,每个元素加 1。
li = [0,25,50,100][i+1 for i in li]
#=> [1, 26, 51, 101]
16.统计列表中特定对象的出现次数
count()
方法返回一个特定对象出现的次数。下面我们返回字符串的次数,“fish”
存在于一个名为pets
的列表中。
pets = ['dog','cat','fish','fish','cat']
pets.count('fish')
#=> 2
17.如何浅层复制一个列表?
.copy()
可以用来浅层复制一个列表。
下面我们创建一个round1
的浅层副本,给它分配一个新名字round2
,然后移除字符串sonny chiba
。
round1 = ['chuck norris', 'bruce lee', 'sonny chiba']**round2 = round1.copy()**
round2.remove('sonny chiba')print(round1) #=> ['chuck norris', 'bruce lee', 'sonny chiba']
print(round2) #=> ['chuck norris', 'bruce lee']
18.为什么要创建一个列表的浅层副本?
基于前面的例子,如果我们不创建浅层拷贝,修改round2
将会修改round1
。
round1 = ['chuck norris', 'bruce lee', 'sonny chiba']**round2 = round1**
round2.remove('sonny chiba')print(round1) #=> ['chuck norris', 'bruce lee']
print(round2) #=> ['chuck norris', 'bruce lee']
没有浅拷贝,round1
和round2
只是内存中指向同一个链表的名字。这就是为什么看起来改变一个的值会改变另一个的值。
19.如何深度复制一个列表?
为此我们需要导入copy
模块,然后调用copy.deepcopy()
。
下面我们创建一个名为round2
的列表的深层副本round1
,更新round2
中的值,然后打印两者。在这种情况下,round1
不受影响。
round1 = [
['Arnold', 'Sylvester', 'Jean Claude'],
['Buttercup', 'Bubbles', 'Blossom']
]import copy
**round2 = copy.deepcopy(round1)**round2[0][0] = 'Jet Lee'print(round1)
#=> [['Arnold', 'Sylvester', 'Jean Claude'], ['Buttercup', 'Bubbles', 'Blossom']]print(round2)
#=> [['Jet Lee', 'Sylvester', 'Jean Claude'], ['Buttercup', 'Bubbles', 'Blossom']]
上面我们可以看到,改变round2
中的嵌套数组并没有更新round1
。
20.深抄和浅抄有什么区别?
在前一个例子的基础上,创建一个浅层副本,然后修改它,会影响原始列表…
round1 = [
['Arnold', 'Sylvester', 'Jean Claude'],
['Buttercup', 'Bubbles', 'Blossom']
]import copy
**round2 = round1.copy()**round2[0][0] = 'Jet Lee'print(round1)
#=> [['Jet Lee', 'Sylvester', 'Jean Claude'], ['Buttercup', 'Bubbles', 'Blossom']]print(round2)
#=> [['Jet Lee', 'Sylvester', 'Jean Claude'], ['Buttercup', 'Bubbles', 'Blossom']]
为什么会这样?
创建一个浅层副本确实会在内存中创建一个新的对象,但是它会填充上一个列表中已有对象的引用。
创建深层副本会创建原始对象的副本,并指向这些新版本。因此新列表完全不受旧列表更改的影响,反之亦然。
照片由瓦莱里娅·博尔特涅娃从派克斯拍摄
问题 21-30:
21.列表和元组的区别是什么?
元组在创建后无法更新。添加/移除/更新现有元组需要创建新元组。
列表创建后可以修改。
元组通常表示一个对象,如从数据库中加载的记录,其中元素具有不同的数据类型。
列表通常用于存储特定类型对象的有序序列(但不总是如此)。
两者都是序列,并且允许重复值。
22.返回列表的长度
len()
可以返回一个列表的长度。
li = ['a', 'b', 'c', 'd', 'e']
len(li)
#=> 5
但是请注意,它对顶级对象进行计数,因此几个整数的嵌套列表将只被计为单个对象。下面,li
的长度是 2,不是 5。
li = [[1,2],[3,4,5]]
len(li)
#=> 2
23.列表和集合的区别是什么?
列表是有序的,而集合不是。这就是为什么使用 set 在一个列表中寻找唯一值,像list( set([3, 3, 2, 1]) )
失去了顺序。
列表通常用于跟踪顺序,而集合通常用于跟踪存在。
列表允许重复,但是根据定义,集合中的所有值都是唯一的。
24.如何检查一个元素是否不在列表中?
为此,我们使用了in
操作符,但是在它前面加上了not
。
li = [1,2,3,4]
5 not in li #=> True
4 not in li #=> False
25.用 map 函数将列表中的每个元素乘以 5
.map()
允许迭代一个序列,并用另一个函数更新每个值。
返回一个地图对象,但是我已经用一个列表理解包装了它,所以我们可以看到更新的值。
def multiply_5(val):
return val * 5a = [10,20,30,40,50][val for val in map(multiply_5, a)]
#=> [50, 100, 150, 200, 250]
26.用 zip 函数将两个列表合并成一个元组列表
zip()
将多个序列组合成一个元组迭代器,其中相同序列索引处的值组合在同一个元组中。
alphabet = ['a', 'b', 'c']
integers = [1, 2, 3]list(zip(alphabet, integers))
27.在现有列表中的特定索引处插入值
insert()
方法接受一个要插入的对象和索引。
li = ['a','b','c','d','e']
li.insert(2, 'HERE')li #=> ['a', 'b', 'HERE', 'c', 'd', 'e']
请注意,先前位于指定索引处的元素被向右移动,而不是被覆盖。
28.用 reduce 函数从第一个元素中减去列表中的值
reduce()
需要从functools
导入。
给定一个函数,reduce
遍历一个序列,并对每个元素调用该函数。当前一个元素调用函数时,前一个元素的输出作为参数传递。
from functools import reducedef subtract(a,b):
return a - bnumbers = [100,10,5,1,2,7,5]reduce(subtract, numbers) #=> 70
上面我们从 100 减去了 10,5,1,2,7 和 5。
29.用 filter 函数从列表中删除负值
给定一个函数,filter()
将从序列中删除该函数不返回True
的任何元素。
下面我们去掉小于零的元素。
def remove_negatives(x):
return True if x >= 0 else False
a = [-10, 27, 1000, -1, 0, -30][x for x in filter(remove_negatives, a)]
#=> [27, 1000, 0]
30.将列表转换成字典,其中列表元素是键
为此我们可以用字典理解。
li = ['The', 'quick', 'brown', 'fox', 'was', 'quick']
d = {k:1 for k in li}
d #=> {'The': 1, 'quick': 1, 'brown': 1, 'fox': 1, 'was': 1}
凯文·梅纳江摄于 Pexels
问题 31-40:
31.用 lambda 函数修改现有列表
让我们将之前编写的map
函数转换成带有lambda
的一行程序。
a = [10,20,30,40,50]list(map(lambda val:val*5, a))
#=> [50, 100, 150, 200, 250]
我可以把它作为一个 map 对象,直到我需要迭代它,但是我把它转换成一个列表来显示里面的元素。
32.移除列表中特定索引后的元素
使用 slice 语法,我们可以返回一个新的列表,其中只包含特定索引之前的元素。
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,10]li[:10]
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
33.移除列表中特定索引前的元素
slice 语法还可以返回一个新列表,其中包含指定索引之后的值。
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,10]li[15:]
#=> [16, 17, 18, 19, 10]
34.移除列表中两个索引之间的元素
或者在两个指数之间。
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,10]li[12:17]
#=> [13, 14, 15, 16, 17]
35.返回列表中两个索引之间的第二个元素
或者在特定间隔的索引之前/之后/之间。
这里,我们使用 slice 语法返回索引 10 和 16 之间的每第二个值。
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,10]li[10:16:2]
#=> [11, 13, 15]
36.按升序对整数列表进行排序
sort()
方法将一个列表改变为升序。
li = [10,1,9,2,8,3,7,4,6,5]li.sort()
li #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
37.按降序对整数列表进行排序
通过添加参数reverse=True
,也可以用sort()
进行降序排序。
li = [10,1,9,2,8,3,7,4,6,5]li.sort(reverse=True)
li #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
38.用列表理解从列表中过滤出偶数值
您可以在列表理解中添加条件逻辑,以按照给定的模式过滤出值。
这里我们过滤掉能被 2 整除的值。
li = [1,2,3,4,5,6,7,8,9,10][i for i in li if i % 2 != 0]
#=> [1, 3, 5, 7, 9]
39.统计列表中每个值的出现次数
一种选择是遍历一个列表并将计数添加到一个字典中。但是最简单的选择是从collections
导入Counter
类,并将列表传递给它。
from collections import Counterli = ['blue', 'pink', 'green', 'green', 'yellow', 'pink', 'orange']Counter(li)
#=> Counter({'blue': 1, 'pink': 2, 'green': 2, 'yellow': 1, 'orange': 1})
40.获取列表中每个嵌套列表的第一个元素
列表理解非常适合迭代其他对象的列表,并从每个嵌套对象中获取一个元素。
li = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]][i[0] for i in li]
#=> [1, 4, 7, 10, 13]
来自 Pexels 的 Lisa Fotios 的照片
问题 41–50:
41.对于一个列表,插入、查找、删除的时间复杂度是多少?
插入的是 O(n) 。如果在开头插入一个元素,所有其他元素都必须右移。
通过索引查找是 O(1) 。但是 find by value 是 O(n ),因为需要迭代元素直到找到值。
删除是 O(n) 。如果一开始就删除了一个元素,那么所有其他元素都必须左移。
42.将列表中的元素组合成一个字符串。
这可以通过join()
功能完成。
li = ['The','quick','brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']
' '.join(li)
#=> 'The quick brown fox jumped over the lazy dog'
43.一个列表乘以一个整数会有什么影响?
将一个列表乘以一个整数称为多重串联,其效果与将一个列表串联 n 次相同。
下面我们将列表乘以 5。
['a','b'] * 5
#=> ['a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b']
这与相同。
['a','b'] + ['a','b'] + ['a','b'] + ['a','b'] + ['a','b']
#=> ['a', 'b', 'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b']
44.如果列表中的任何值可以被 2 整除,则使用“any”函数返回 True
如果返回的列表中有任何值的计算结果为True
,我们可以将any()
与列表理解结合起来返回True
。
在第一个列表下面,理解返回True
,因为列表中有一个2
,它可以被2
整除。
li1 = [1,2,3]
li2 = [1,3]any(i % 2 == 0 for i in li1) #=> True
any(i % 2 == 0 for i in li2) #=> False
45.如果列表中的所有值都是负数,则使用“all”函数返回 True
与any()
函数类似,all()
也可以与列表理解一起使用,仅当返回列表中的所有值都是True
时才返回True
。
li1 = [2,3,4]
li2 = [2,4]all(i % 2 == 0 for i in li1) #=> False
all(i % 2 == 0 for i in li2) #=> True
46.你能对一个包含“无”的列表进行排序吗?
您不能对包含None
的列表进行排序,因为比较运算符(由sort()
使用)不能将整数与None
进行比较。
li = [10,1,9,2,8,3,7,4,6,None]li.sort()
li #=> TypeError: '<' not supported between instances of 'NoneType' and 'int'
47.列表构造函数将从现有列表中创建什么样的副本?
list 构造函数创建一个传入列表的浅表副本。也就是说,这比使用.copy()
要简单得多。
li1 = ['a','b']
li2 = list(li1)
li2.append('c')print(li1) #=> ['a', 'b']
print(li2) #=> ['a', 'b', 'c']
48.颠倒列表的顺序
可以用reverse()
方法将一个列表改变成相反的顺序。
li = [1,2,3,4,5,6,7,8,9,10]
li.reverse()
li #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
请注意,这将改变对象,而不是返回一个新的对象。
49.反和反的区别是什么?
reverse()
原地反转列表。reversed()
以逆序返回列表的 iterable。
li = [1,2,3,4,5,6,7,8,9,10]
list(reversed(li))
#=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
50.sort 和 sorted 有什么区别?
sort()
就地修改列表。sorted()
返回一个逆序的新列表。
li = [10,1,9,2,8,3,7,4,6,5]
li.sort()
li #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]li = [10,1,9,2,8,3,7,4,6,5]
sorted(li) #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
问题 51–60:
51.返回列表中的最小值
min()
函数返回列表中的最小值。
li = [10,1,9,2,8,3,7,4,6,5]
min(li)
#=> 1
52.返回列表中的最大值
max()
函数返回列表中的最大值。
li = [10,1,9,2,8,3,7,4,6,5]
max(li)
#=> 10
53.返回列表中数值的总和
sum()
函数返回列表中所有值的总和。
li = [10,1,9,2,8,3,7,4,6,5]
sum(li)
#=> 55
54.将列表用作堆栈
你可以使用append()
和pop()
把一个列表当作一个堆栈。堆栈按照后进先出法运行。
stack = []stack.append('Jess')
stack.append('Todd')
stack.append('Yuan')print(stack) #=> ['Jess', 'Todd', 'Yuan']print(stack.pop()) #=> Yuanprint(stack) #=> ['Jess', 'Todd']
堆栈的一个好处是可以在 O(1)时间内添加和删除元素,因为列表不需要迭代。
55.找到两个列表的交集
我们可以通过使用带“与”符号的set()
来做到这一点。
li1 = [1,2,3]
li2 = [2,3,4]set(li1) & set(li2)
#=> {2, 3}
56.找出一个集合和另一个集合的区别
我们不能减去列表,但我们可以减去集合。
li1 = [1,2,3]
li2 = [2,3,4]set(li1) - set(li2)
#=> {1}set(li2) - set(li1)
#=> {4}
57.用列表理解展平列表列表
与 Ruby 不同,Python3 没有显式的 flatten 函数。但是我们可以使用列表理解来简化列表列表。
li = [[1,2,3],[4,5,6]][i for x in li for i in x]
#=> [1, 2, 3, 4, 5, 6]
58.生成两个值之间所有整数的列表
我们可以创建一个介于两个值之间的范围,然后将其转换为一个列表。
list(range(5,10))
#=> [5, 6, 7, 8, 9]
59.将两个列表合并成一个字典
使用zip()
和list()
构造函数,我们可以将两个列表合并成一个字典,其中一个列表成为键,另一个列表成为值。
name = ['Snowball', 'Chewy', 'Bubbles', 'Gruff']
animal = ['Cat', 'Dog', 'Fish', 'Goat']dict(zip(name, animal))
#=> {'Snowball': 'Cat', 'Chewy': 'Dog', 'Bubbles': 'Fish', 'Gruff': 'Goat'}
60.使用 slice 语法反转列表的顺序
虽然我们可以用reverse()
和reversed()
反转一个列表,但也可以用 slice 语法来完成。
这将通过从头到尾遍历列表返回一个新列表。
li = ['a','b',3,4]
li[::-1]
#=> [4, 3, 'b', 'a']
结论
做完这些后,我觉得更有准备去解决算法问题,而不用去猜测具体的列表方法。
去除持续的谷歌搜索可以为更高层次的思考释放能量,比如让一个功能做它应该做的事情,以及降低功能的复杂性。
同样,我希望您发现这也很有用。
你可能对我之前发表的关于字符串问题的文章感兴趣,或者对我已经开始发表的关于算法问题的每周系列文章感兴趣。