初学者指南,建立自己的面部识别系统,让你的朋友溜出来
人脸识别系统正稳步进入我们的日常生活。基于人工智能,它们可以(以不同程度的准确性)从人群中挑出你,并将你识别为导致各种后果的个体。根据你生活在世界的哪个地方,他们可以解锁你的手机屏幕,支付你的鸡肉,让你被捕,让你远离泰勒斯威夫特和找到你的梦中情人。
A toilet paper dispenser at a public toilet in Beijing deploys facial recognition to stop toilet paper thieves (Image source: AFP)
Poster for Metropolitan Police Facial Recognition trial in Central London (Image Source: Metropolitan Police)
Dating app Badoo showing profile matches for Jake Gyllenhall and Kendall Jenner (Image Source: Badoo)
但是这些系统实际上是如何工作的,它们有多精确,谁有权限部署它们?为了找到答案,让我们用免费的开源软件和朋友的照片自己做一个。
设置它——下载程序运行所需的一切
- 下载文本编辑器 Sublime Text ,完成后,打开它并遵循安装说明。我们将在这里编写代码,这些代码将成为程序。
- 查看您的计算机上是否已经安装了 Python 3。这是我们将要编写的编程语言。要为 MAC 打开终端(在应用程序的“实用工具”文件夹中)或 Windows 打开命令提示符(按 Windows + X 并选择命令提示符)执行此操作。然后键入以下内容并按 enter 键:
python3 -- version
如果它说 Python 3.7.3,忽略步骤 3。否则继续。
3.下载 Python 3 。对于 Windows,下载完成后,打开 python.exe 文件,在“修改”菜单下,确保勾选“pip”和“将 Python 添加到环境变量”,然后按“安装”。
4.再次进入终端或命令提示符,键入以下命令,在每一行后按 enter 键,安装我们需要的软件包。第四行“dlib”可能需要一段时间。
pip3 install cmake
pip3 install face_recognition
pip3 install numpy
pip3 install dlib
pip3 install opencv-python
如果最后一个命令要求您安装 Xcode(适用于 MAC),请前往 App Store 并安装。这可能需要一段时间,因为它非常大。然后重新输入最后一行(pip3 install opencv-python)并回车。
制作和运行程序
1.将这段开源代码复制并粘贴到 Sublime 文本中。点击图片底部的“查看原始数据”可能更容易做到这一点。
2.将此文件以 recognise _ face.py 的名称保存在计算机的桌面文件夹中,并创建一个名为 known_people 的文件夹(确保该文件夹也在桌面文件夹中)。
3.现在,我们可以通过在 known_people 文件夹中保存他们的面部图像来添加我们希望识别的人的照片。确保这个人面向前方,并且是照片中的唯一一个人(如果需要的话,修剪)。我们将每个文件命名为这个人的名字,因为我们希望它出现在屏幕上。在这种情况下,只有。将使用 jpg 文件。
4.现在,我们可以通过返回到终端(Mac)或命令提示符(Windows)来运行程序,编写以下内容并按 enter 键
cd Desktop
python3 recognise_face.py
如果出现错误消息,请尝试:
python recognise_face.py
在选择终端窗口的情况下按 Ctrl + c 将退出程序。
这里发生了什么事?
这篇由 Adam Geitgey 撰写的博客文章详细解释了这个系统是如何工作的(而且非常好)。
总而言之,人脸识别过程可以分为四个步骤。
- 检测帧中出现的任何人脸。
A Visualisation of a History of Gradients (HOG) algorithm for detecting faces
2.定位面部的特定点,例如鼻尖和每只眼睛的角落,以创建遮罩。然后移动蒙版,使其面向正前方,只使用保持原始形状的变换,如旋转和缩放。
Face goes through transforms to become aligned
3.编码。这一阶段是关于识别面部的关键部分(通过计算机的眼睛),对于同一个人的任何照片,这些关键部分都是相似的,而对于其他任何人的图像,这些关键部分都是不同的。对于人类来说,这可能是眼睛的颜色、发型、鼻子的形状等,但对于计算机视觉来说,有一个非常有效的 128 个测量值的集合,称为嵌入。这些测量是使用机器学习通过比较成千上万张标记人脸的图像发现的。然后,我们可以访问由该过程生成的预训练网络,以找到我们需要的测量值。
128 measurements to identify my face
4.将步骤 1 中检测到的人脸的 128 个测量值与 known_people 文件夹中图像的所有测量值进行比较。如果在这个文件夹中找到足够相似的一组测量值,那就是匹配!
这有多准确?
对于一组大约 30 张要识别的人脸,这种方法仍然有效。但是如果你刮下你所有脸书朋友的照片呢?由于普通用户有 338 个,这是一个更大的比较集,肯定会导致歧义?在下一篇博文中,我们将对此进行测试,考虑制作和利用这种应用程序的合法性,并进一步研究人脸识别技术的当前应用。
商业仪表板初学者指南
说到仪表板,你可能会想到飞机或汽车的仪表板,驾驶员通过仪表组对主要功能进行监控。在商业智能领域,业务仪表板也有类似的作用。他们使用数据可视化随时显示关键业务运营的指标和执行情况,帮助管理者做出科学决策。
1.什么是业务仪表板?
业务仪表板是各种指标的图形显示,实时反映企业的运营状态,并将收集的数据可视化。
From FineReport
简而言之,业务经理可以在业务仪表板上看到他们做出决策所需的所有重要数据。就像飞机的仪表盘一样,通过各种常见的图表(速度计、量柱、预警雷达、雷达球等)显示公司运营的关键绩效指标。),让管理者可以直观的监控企业经营情况,对异常指标进行预警和数据挖掘分析。
From FineReport
2.业务仪表板的功能
因此,可以看出业务仪表板应该具有以下特征:
- 富指示器系统
- 直观显示系统
- 数据的及时性和真实性
- 完整的系统架构
3.业务仪表板的类型
那么,我们如何规划业务仪表板呢?
通常,仪表板的显示有特定的主题或分类。从战略的角度来看,从上到下有三种类型的业务仪表板:战略仪表板、分析仪表板和运营仪表板。
3.1 战略仪表板
战略仪表板的作用是让用户快速掌握公司的运营情况,并在此基础上做出决策,总结过去或制定未来的战略目标。这里的操作主要是过去发生过的操作。因此,战略仪表板不需要实时数据显示,而是对关键任务信息进行简单的可视化显示。这些简单直观的信息有助于管理者快速做出决策,定位和诊断不良运营中的问题。
战略仪表板可以帮助管理者随时报告结果,以便部门和公司能够朝着正确的方向努力实现目标。它类似于汽车和飞机的驾驶舱工具,使管理者随时清楚地知道他们在所驾驶的企业中采取了什么步骤。
From FineReport
3.2 分析仪表板
通过分析仪表板,管理者不仅可以看到表面信息,还可以调查表面现象的原因。通过数据钻取、联动、过滤等。,可以从现象入手,沿着数据脉络寻找原因。比如为什么销售业绩在下降,付款时间长的原因是什么?**分析仪表板更多的是服务于中层管理者,他们实施战略到战术执行。**因此,仪表板的设计需要直接反映问题,并按顺序对其进行分类,并将要采取的行动关联起来。
分析仪表板可以是战略性的,也可以是操作性的。主要区别在于信息化程度。它包含多个因素和变量之间基于时间的详细信息的比较。
From FineReport
3.3 操作仪表板
操作仪表板强调连续、实时的信息报告,因此其上数据的时效性相对较高。它用于监控每天的进度和产出,以确保预期计划与实现的实际绩效相匹配,即确保战略目标被分解为每天的任务。这样的仪表板允许我们在问题变成棘手的大风险之前及时解决问题,并帮助逐步提高性能。
运营仪表板的设计需要从业务需求出发,实现业务运营的提醒、监控和预警功能。
- KPI 监控:对关键绩效指标的监控可以确保我们对整体运营的控制。运营仪表板通过图形、表格等在显示器前显示业务、风险和绩效领域的核心指标。
- 阈值预警:伴随 KPI 监控的另一个因素必然是预警因素。可以通过用醒目的颜色(如红色、绿色、蓝色)突出背景、转速表等发出警报。
- 实时数据监控:部分行业的仪表盘要求对关键指标进行实时监控,如交易量监控、航班监控、地铁线路运营监控等。
From FineReport
4.业务仪表板模板
不同的行业和角色有不同的业务仪表板模板。不同层级的管理者关注的关键信息是不一样的。销售主管关注销售管理仪表板,财务主管关注资本运营仪表板。从行业来看,制造业、零售业、运输业、政府机构、电信、餐饮业的仪表盘设计也各不相同。
FineReport Demo 提供了多种常用的分析思路和模板。可以根据不同行业、不同角色、不同场景即时访问企业数据。您可以学习业界最佳的数据分析实践,并快速构建业务仪表盘。
教育行业模板
From FineReport
IOT 产业模板
From FineReport
金融主题模板
From FineReport
From FineReport
终于
如果你想学习制作业务仪表板,这里有一个数据可视化仪表板设计指南。而且你最好使用像 FineReport 这样的易用工具。它的个人版本是完全免费的。你也可以去它的官网查看更多的业务仪表盘模板!
您可能也会对…感兴趣
原载于 2019 年 7 月 10 日http://www.finereport.com。
卷积神经网络初学者指南
什么是卷积?
卷积是滤波器修改输入的方式。在卷积网络中,采用多个滤波器来分割图像,并逐个映射它们,学习输入图像的不同部分。想象一下,一个小滤镜从左到右从上到下滑过图像,移动的滤镜正在寻找,比如说,一个黑色的边缘。每次找到一个匹配,它就被映射到输出图像上。
https://www.cs.columbia.edu/education/courses/course/COMSW4995-7/26050/
例如,有一张 Eileen Collins 的照片,红色箭头上方的矩阵用作卷积来检测暗边缘。因此,我们看到的图像只强调了暗边。
请注意,图像的宽度和高度是二维的。如果图像是彩色的,它被认为具有 RGB 颜色的多一个维度。因此,2D 卷积通常用于黑白图像,而 3D 卷积用于彩色图像。
2D 卷积
让我们从没有填充的(4 x 4)输入图像开始,我们使用(3 x 3)卷积滤波器来获得输出图像。
第一步是用滤镜将输入图像中的黄色区域相乘。每个元素都与相应位置的一个元素相乘。然后你把所有的结果相加,就是一个输出值。
数学上是(2 * 1)+(0 * 0)+(1 * 1)+(0 * 0)+(0 * 0)+(0 * 0)+(0 * 0)+(0 * 1)+(1 * 0)= 3
然后,重复相同的步骤,将过滤器移动一列。你得到第二个输出。
请注意,您只移动了一列过滤器。滤光器滑过图像的步长称为步幅。这里,步幅是 1。重复相同的操作以获得第三个输出。步幅大于 1 将总是缩小图像。如果大小为 1,图像的大小将保持不变。
最后,您将得到最终的输出。
我们看到输出图像的尺寸小于输入图像的尺寸。事实上,大多数情况下都是如此。
3D 卷积
3D 卷积就像 2D,除了你要做 3 次 2d 工作,因为有 3 个颜色通道。
https://twitter.com/martin_gorner
通常,输出的宽度会变小,就像 2D 案例中输出的大小一样。
https://twitter.com/martin_gorner
如果您想要保持输出图像的宽度和高度不变,而不减小滤镜大小,您可以使用零向原始图像添加填充,并对图像进行卷积切片。
https://twitter.com/martin_gorner
我们可以应用更多的填充!
https://twitter.com/martin_gorner
完成后,结果如下所示:
https://twitter.com/martin_gorner
当您添加更多滤镜时,它会增加输出图像的深度。如果输出图像的深度为 4,则使用 4 个滤镜。每一层对应于一个滤波器,并学习一组权重。当它在图像上滑动时,它不会在各步之间改变。
https://twitter.com/martin_gorner
卷积的输出通道被称为特征图。它对其检测到的特征的存在与否和存在程度进行编码。注意,与之前的 2D 滤波器不同,每个滤波器连接到每个输入通道的**。(问题?与 2D 不同,每个滤波器连接到每个输入通道是什么意思?)这意味着它们可以计算复杂的特征。最初,通过查看 R、G、B 通道,但是之后,通过查看诸如各种边缘、形状、纹理和语义特征的学习特征的组合。**
平移不变量
另一个有趣的事实是,CNN 在某种程度上抵抗平移,例如图像移动一点,这将具有与移动前相似的激活图。这是因为卷积是一个特征检测器,如果它检测的是暗边缘,并且图像被移动到底部,那么暗边缘将不会被检测到,直到卷积被向下移动。
特例——1D 卷积
1D 卷积包括在这里,因为它通常解释不足,但它有值得注意的好处。
https://github.com/GoogleCloudPlatform/tensorflow-without-a-phd
它们用于减少深度(通道数)。在这种情况下,宽度和高度保持不变。如果要减少水平维度,可以使用池,增加卷积的步幅,或者不添加填充。1D 卷积计算输入通道或特征的加权和,这允许选择某些对下游有用的特征组合。1D 卷积压缩,因为只有一个它有相同的效果
联营
请注意,池化是与卷积分开的一个步骤。池用于减少图像的宽度和高度。请注意,深度由通道的数量决定。顾名思义,它所做的就是在一定大小的窗口中选择最大值。尽管它通常在空间上用于减少图像的 x,y 维度。
最大池
最大池用于通过取窗口中元素的最大值,将给定窗口的大小映射到单个结果来减小图像大小。
http://cs231n.github.io/convolutional-networks/
平均池
它与 max-pooling 相同,只是它对窗口进行平均,而不是选择最大值。
http://cs231n.github.io/convolutional-networks/
普通设置
为了实现 CNN,大多数成功的架构使用一个或多个具有 relu 激活的卷积+池层堆栈,然后是平坦层,然后是一个或两个密集层。
随着我们在网络中移动,要素地图在空间上变得更小,在深度上变得更深。要素变得越来越抽象,失去了空间信息。例如,网络知道图像包含一只眼睛,但不确定它在哪里。
这是一个典型的美国有线电视新闻网在喀拉斯的例子。
这是你做 model.summary()时的结果
让我们将这些层分解开来,看看我们如何获得这些参数值。
Conv2d_1
过滤器尺寸(3 x 3) *输入深度(1) *过滤器数量(32) +偏差 1/过滤器(32) = 320。这里,输入深度是 1,因为它是针对 MNIST 黑白数据的。请注意,在 tensorflow 中,默认情况下,每个卷积层都添加了偏差。
最大池 2d 1
池图层没有参数
Conv2d_2
过滤器尺寸(3 x 3) *输入深度(32) *过滤器数量(64) +偏差,每个过滤器 1(64)= 18496
扁平化 _1
它将上面的卷拆分成一个数组。
https://github.com/GoogleCloudPlatform/tensorflow-without-a-phd
密集 _1
输入维度(128) *输出维度(10) +每个输出神经元一个偏置(10) = 1290
摘要
卷积神经网络(CNN)是一种深度神经网络(DNN ),广泛用于计算机视觉或 NLP。在训练过程中,为了使网络达到最佳性能并尽可能准确地对图像和对象进行分类,网络的构建模块被反复改变。
来源
本教程基于约书亚·戈登在哥伦比亚大学的应用深度学习课程的讲座。令人惊叹的 3d 图像来自马丁·戈纳。
使用 GeoPandas 和 Matplotlib 在 Python 中创建 Choropleth 地图的初学者指南
在搜索和展示重要见解时,数据可视化是一项重要的技能。有许多视觉效果可以用来展示你的数据。最有趣的数据图像之一是 choropleth 地图。
什么是 choropleth 地图?
choropleth map (源自希腊语χῶρος“区域/地区”和πλῆθος“大众”)是一种专题地图,其中区域根据地图上显示的统计变量(如人口密度或人均收入)的测量值成比例地进行阴影化或图案化。【https://en.wikipedia.org/wiki/Choropleth_map】来源:T4
Google Image search — choropleth
为什么这是如此有趣的视觉效果?a)它很漂亮,b)它告诉我们我们感兴趣的数据的确切位置,以及 c)它很漂亮!
介绍完毕后,让我们开始编写代码(以及代码的准备工作)。
第一步:安装所需的 Python 库
让我们安装几个在这个练习中需要的包。GeoPandas 是一个令人惊叹的包,它允许解析地理空间数据,从而将pandas
的数据框架提升到了一个新的水平。它将使用笛卡尔坐标生成 Matplotlib 图。
pip install descartes
pip install geopandas
pip install matplotlib
pip install numpy
pip install pandas
第二步:获取数据
在这个练习中,我们需要两种数据:
- 数据将被映射到位置/区域/地区等。我们可以免费使用大量的开放数据,其中一个来自维基百科(数据的准确性和有效性没有保证,但对于这个学习练习来说,没问题!).在这个练习中,我们将使用印度尼西亚每个省的城市和地区的数量。如果你愿意,你可以在这里检查它,但是我建议你只从我的 Github repo 下载它,因为需要一些手工操作(改变列名,数据格式等)。)这个我们就懒得在这里讨论了。
- 第二个数据是我们想要制作的地图的 shapefile。它基本上是一个几何位置列表(点、线或多边形)。由于我们想要绘制印度尼西亚的省份地图,我们将在这里下载印度尼西亚的行政区域,或者再次在我的 Github repo 中下载。
第三步:开始编码
现在,让我们直接进入代码
- 加载必要的库
import pandas as pd
import numpy as np
import geopandas as gpd
import matplotlib.pyplot as plt
2.加载并查看 shapefile 数据
fp = "IDN_adm/IDN_adm1.shp"
map_df = gpd.read_file(fp)
# check the GeoDataframe
map_df.head()
好的,如你所见,我们在下载的 shapefile 中有几个数据字段。我们感兴趣的是列NAME_1
(省名)和geometry
(省的形状)。您也可以看到,shapefile 以多边形的形式存储位置信息。让我们画出来,好吗
map_df.plot()
所以我们有印度尼西亚的地图,但是它看起来太小了,让我们调整它的大小
plt.rcParams['figure.figsize'] = [50, 70] #height, width
map_df.plot()
好多了,
3.加载省数据
province = pd.read_csv("data_province.csv", sep=";")
province.head()
如你所见,我们有各省、2015 年人口、城市数量和其他几个有趣的数字。我们现在要做的就是将数据与 shapefile 合并,然后我们就可以开始可视化这些数字了
4.合并并显示地图
# join the geodataframe with the csv dataframe
merged = map_df.merge(province, how='left', left_on="NAME_1", right_on="province")
merged = merged[['province', 'geometry', 'population_2015', 'area_km2', 'population_density_per_km2', \
'cities_regencies', 'cities', 'regencies']]merged.head()
酷,我们有了最清晰的数据格式,让我们来绘图
# set the value column that will be visualised
variable = 'cities_regencies'# set the range for the choropleth values
vmin, vmax = 0, 50# create figure and axes for Matplotlib
fig, ax = plt.subplots(1, figsize=(30, 10))# remove the axis
ax.axis('off')# add a title and annotation
ax.set_title('# of Cities per each Region', fontdict={'fontsize': '25', 'fontweight' : '3'})
ax.annotate('Source: Wikipedia - [https://en.wikipedia.org/wiki/Provinces_of_Indonesia', xy=(0.6,](https://en.wikipedia.org/wiki/Provinces_of_Indonesia',xy=(0.6,) .05), xycoords='figure fraction', fontsize=12, color='#555555')# Create colorbar legend
sm = plt.cm.ScalarMappable(cmap='Blues', norm=plt.Normalize(vmin=vmin, vmax=vmax))# empty array for the data range
sm.set_array([]) # or alternatively sm._A = []. Not sure why this step is necessary, but many recommends it# add the colorbar to the figure
fig.colorbar(sm)# create map
merged.plot(column=variable, cmap='Blues', linewidth=0.8, ax=ax, edgecolor='0.8')
很好,对吧?但还可以更好。例如,我们知道哪些位置的每个区域的城市数量多,哪些位置的每个区域的城市数量少。为了让情节更清晰,我们给它加上省份标签。在上述代码的底部添加以下代码。
# Add Labels
merged['coords'] = merged['geometry'].apply(lambda x: x.representative_point().coords[:])
merged['coords'] = [coords[0] for coords in merged['coords']]for idx, row in merged.iterrows():
plt.annotate(s=row['province'], xy=row['coords'],horizontalalignment='center')
好吧,这样更好。如果我们仔细看看,我们可以看到,根据维基百科,与其他省份相比,贾瓦人腾格里省每个地区的城市数量非常多。
我们可以做的另一个调整是将彩色地图图例的方向改为水平,以防您希望上面的空间集中在地图上。
只要修改这个代码
fig.colorbar(sm)
对此
fig.colorbar(sm, orientation="horizontal", fraction=0.036, pad=0.1, aspect = 30)
Final tweak
5.省省吧!
既然我们已经制作了 choropleth 地图,我们需要做的最后一件事就是以友好的流行格式保存它,比如。png
fig.savefig(‘map.png’, dpi=300)
就这些了,希望这个帖子有用。
你自己试试
你可以在我的 Github repo 这里下载这个练习的笔记本文件以及清理过的省份数据和印度尼西亚 shapefiles。
信用
这篇文章的灵感来自本杰明·库利的文章。
[## 让我们做一张地图吧!利用 Geopandas、pandas 和 Matplotlib 制作 Choropleth 地图
所以你想用 Python 做地图。我们开始吧!
towardsdatascience.com](/lets-make-a-map-using-geopandas-pandas-and-matplotlib-to-make-a-chloropleth-map-dddc31c1983d)
我对进一步学习和做一些事情很感兴趣,并且喜欢这些结果,因此我在这里分享它。😃
项目组合管理过程中的数据科学初学者指南
随着对工作中的统计计算的深入理解,投资组合优化变得简单。
Photo by Markus Spiske on Unsplash
一位潜在客户打电话来,要求投资 10,000,000 美元。投资组合经理/顾问如何决定股票、债券、现金、黄金、比特币或其他资产的适当组合?这位经理如何确保她所做的事情比猴子向镖靶投掷飞镖所取得的结果更好,或者更重要的是,更适合她的客户?
这些都是数据科学可以帮助回答的问题!
在投资组合管理过程的开始,投资组合经理需要理解他们客户的目标和约束,以便构建适当的资产分配。审查客户的目标和限制包括了解她的风险/回报偏好、流动性需求、投资时间范围、税收情况(资产位置可能是一个强有力的工具!)、特殊情况以及任何当前的法律问题。有了对这些目标和约束的坚实理解,项目组合的构建就可以开始了。
分析诸如流动性需求(无、当前、未来等)等分类输入。)、时间跨度(短期、长期等。),或者税收(纳税或者不纳税)在决策过程中融合在一起不在本博客讨论范围之内。相反,我写这篇博客的目的是探索关键的静态计算,如均值、协方差、相关性和标准差,它们与适当的投资组合构建/优化密切相关。
一个双资产投资组合的例子
考虑两只股票:A 和 B。管理投资组合 Z 是通过购买价值 60,000 美元的 A 和价值 40,000 美元的 B 构建的。我们如何使用我们对 A 和 B 的了解来预测 Z 的未来表现?暂且忽略风险,这很简单。
让我们将 A 和 B 的预期收益(分别表示为 E(A)和 E(B ))定义为 A 和 B 的总体均值。换句话说,E(A)等于自 A 首次公开发行以来 A 的平均回报率。
我们如何利用这些信息来预测我们管理的投资组合的预期回报,我们知道我们投资组合的权重是 60% A 和 40% B?公式是:
E(Z)= WA * E(A)+WB * E(B);其中 WX 是资产 X 在投资组合中的权重百分比。
为了便于说明,我们假设 E(A) = 15%,E(B) = 17.5%,这样我们管理的投资组合的预期回报率为 16%。
现在让我们关注风险。我们将使用标准差作为投资组合风险的代表。要理解标准差,我们首先需要理解什么是相关系数。相关系数是对两个数据集(在我们的示例 A 和 B 的性能中)之间线性关系强度的度量,其范围从-1 到 1。相关系数为 1 意味着存在完全正的线性关系(随着 A 的增加,B 也会增加),相关系数为-1 意味着存在完全负的线性关系(随着 A 的增加,B 会减少)。中间某处的相关值表示与指示方向的符号的线性关系的强度(或缺乏强度)。
那么,相关系数是怎么计算的呢?如果我们将相关系数表示为 p,则 p 计算如下:
p(x,y) = cov(x,y) / (std_x * std_y)
值得一提的是,cov(x,y)是随机变量 x 和 y 之间的协方差的缩写。根据符号,协方差显示 x 和 y 之间的线性关系的趋势(即变量显示相似的行为)。通过除以(std_x*std_y),我们对协方差进行标准化,以使其具有可比性(即,我们更关心线性关系的强度,而不是关系的趋势)。
一旦我们有了 p,求解我们投资组合的标准差(通过求方差的平方根)就很简单了。我们将投资组合的标准差表示为 rZ,因此投资组合的方差为:
r Z = Wx * r x+Wy * r y+2(Wx * rx)(Wy * ry)p(x,y)
为了便于说明,我们假设 A 的标准偏差为 20%,B 的标准偏差为 10%,A 和 B 的相关性为 0.85。使用我们上面的 rZ 公式,我们计算出我们管理的投资组合的预期标准差为 15.5%。
如果你有两项以上的资产呢?
买电脑。手工很难做到。也就是说,我们应该理解一个计算机程序在幕后做什么。
下面是在有效边界生成投资组合背后的方法,Investopedia 将其定义为:
…一组风险资产的最优投资组合,它们在规定的风险水平下提供最高的预期回报,或者在给定的预期回报水平下提供最低的风险。
让我们首先定义我们的输入参数:
- stock _ price _ data= m×n(读作“m 乘 n”)m 只股票的 m 个收盘价的矩阵
Matrix by Varun Divakar
- avg_stock_price =每只股票平均价格的 1 X n 矩阵。
Matrix by Varun Divakar
3.股票 _ 贬低 =单个股票价格的 m×n 矩阵减去该股票的平均价格。这给了我们一个衡量每个数据点离均值有多远的标准。
Matrix by Varun Divakar
4.协方差 _ 矩阵= m×n 矩阵,即股票 _ 降级矩阵乘以其转置的乘积。我们只关心结果矩阵的对角线(从左上到右下)。
Matrix by Varun Divakar
注:协方差矩阵从左上到右下的对角线代表个股的方差,如下图所示。
Matrix by Varun Divakar
- asset_weights =每个风险资产的分配权重的 n×1 矩阵
Matrix by Varun Divakar
计算投资组合的预期收益和预期风险
使用我们上面定义的输入,我们可以使用以下公式(z =投资组合)通过一些矩阵乘法计算预期投资组合回报和预期投资组合方差:
E(z) = MW*
r z = Wt (协方差矩阵) W;其中 Wt =的转置
rz = sqrt(r z)
现在,我们已经计算了投资组合的预期收益和预期标准差,我们可以通过改变矩阵 W 中的各个权重来生成数万个投资组合,并将这些投资组合绘制在散点图上,如下图所示:
Graph by Varun Divakar
使用上面的散点图,投资组合经理可以很容易地获得最符合其客户风险/回报目标的投资组合权重。最后,需要注意的是,寻求最佳风险调整回报的积极型经理应该关注上面用红星标出的投资组合(夏普比率最高的投资组合)。
一锤定音
投资组合的构建/优化起初看起来令人望而生畏。然而,通过对数学的扎实理解,人们可以轻松地理解什么是适当的分配。
来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
使用 Matplotlib 进行数据可视化的初学者指南
如何创建和解释基本的数据可视化
介绍
本文的目的是简要介绍如何使用 Matplotlib,这是 Python 中最常用的绘图库之一。在本演练结束时,您将知道如何制作几种不同的可视化效果,以及如何处理一些情节的美感。本教程中使用的数据可以在这里找到。这个特定的数据集来自世界卫生组织收集的数据,它包含用于计算特定国家幸福得分的信息,如一个国家的 GDP、预期寿命和人民对该国政府腐败程度的看法。
在创建图表之前,让我们导入必要的库并检查数据集:
import pandas as pd
import matplotlib.pyplot as pltdf = pd.read_csv('WorldHappiness2018_Data.csv')
df.head()
由此,我们看到数据集是根据该国在幸福指数方面的总体排名排序的。“得分”之后的其余几栏,包括“残差”在内(此处未显示),相加得出一个国家的幸福总分。那么,期望每一栏中的值越高,通常表明一个国家的总体幸福指数越高,这是有道理的。
曲线图
线图可能是使用 Matplotlib 创建的最简单的图形。让我们创建一个图表来看看一个国家的排名和他们的幸福得分之间的关系。我们预计,排名最高的国家(排名最接近 1)幸福指数最高,排名最低的国家幸福指数最低。我们可以用四行简单的代码创建这个可视化。
rank = df['Rank']
score = df['Score']
这两行代码是数据帧的子集。第一个创建了一个只包含每个国家总体排名的序列。第二个创建了一个只包含每个国家幸福指数的序列。因为这些信息是从数据帧中提取的,所以您可以假设所有数据都将保存在它们的原始索引中,然后这些数据将正确地排列起来。
plt.plot(rank, score)
plt.show()
接下来的两行代码创建了实际的绘图。plt.plot()
命令创建一个折线图,传入的参数告诉函数使用什么数据。第一个,排名,将绘制在 x 轴上,第二个,得分,将绘制在 y 轴上。需要调用plt.show()
才能将图形实际打印到屏幕上。运行时,输出如下:
创建这个图表非常简单,它向我们展示了我们期望看到的东西。然而,这个图表有几个问题。如果你不是创建它的人,或者如果你在创建它一段时间后回头看它,你将不知道这个图表实际上显示的是什么。幸运的是,添加标题和轴标签非常简单。
plt.plot(rank, score)
plt.title('Happiness Score vs World Rank')
plt.xlabel('Country Rank')
plt.ylabel('Country Score')
plt.show()
这些命令非常简单明了,结果比第一个图表更容易理解。
向原始线图添加标签和标题非常简单,并且极大地改善了它的外观。有一个带标签的图表不仅更专业,而且更容易理解图表向我们展示了什么,几乎不需要额外的上下文或额外的解释。现在,如果我们想在同一张图表上考察多个变量与一个国家排名的关系,会发生什么呢?您所要做的就是用您想要作为 x 值的参数传递的两个不同的系列调用plt.plot()
两次,如下所示:
gdp = df['GDP_Per_Capita']
lifeExp = df['Healthy_Life_Expectancy']plt.plot(rank, gdp)
plt.plot(rank, lifeExp)
plt.show()
此代码输出以下视觉效果:
就像我们制作的第一张图表一样,我们并不知道这张图表告诉了我们什么。此外,我们不知道哪一行代表我们传入的哪个 x 参数。有两种可能的方法来处理这个问题。第一个将添加一个图例来告诉我们什么颜色的线代表哪个变量。
# Option 1
plt.plot(rank, gdp)
plt.plot(rank, lifeExp)
plt.title('World Rank vs GDP and Life Expectancy')
plt.xlabel('Country Rank')
plt.legend()
plt.show()# Option 2 plt.plot(rank, gdp, color = 'green')
plt.plot(rank, lifeExp, color = 'blue')
plt.title('World Rank vs GDP and Life Expectancy')
plt.xlabel('Country Rank')
plt.legend()
plt.show()
注意:为了获得两个输出,这些选项应该彼此分开运行。
现在我们知道哪条颜色线代表哪个变量。无论您是否选择为每个变量设置颜色,在可视化中包含一个图例几乎总是一个好主意,以便您可以快速识别哪条线代表哪个变量。从这个图表中,我们还可以直观地识别一个趋势。当我们进入较低的国家行列时,人均国内生产总值和预期寿命的值都较低,这对一个国家的整体幸福得分有所贡献。此外,我们可以看到,很多时候,当一个国家的人均国内生产总值达到峰值时,这个国家的预期寿命也会达到峰值。人均 GDP 和预期寿命的下降也是如此。
散点图
散点图是可视化两个变量之间关系的一种很好的方式,而没有我们可能从线形图中得到的疯狂趋势线的可能性。就像折线图一样,在 Matplotlib 中创建散点图只需要几行代码,如下所示。
plt.scatter(gdp, score)
plt.title('GDP vs Happiness Score')
plt.xlabel('GDP per Capita')
plt.ylabel('Happiness Score')
plt.show()
如果不添加标题和轴标签,只需两行代码就可以创建一个散点图。此代码创建以下散点图:
正如我们所料,人均 GDP 得分越高,某个国家的幸福指数越高。然而,这个图表有一个小问题。按照惯例,图表轴应该总是从 0 开始,只有少数例外。正如我们在这里看到的,这个图的最低 y 刻度为 3,这是误导。幸运的是,这很容易解决。我们所要做的就是在调用 plt.show()
之前添加一行 plt.ylim(0, 8)
,这个问题就解决了,如下所示:
这个图表给我们的理解与我们构建的第一个散点图略有不同。我们可以在人均 GDP 为 0 的情况下拥有幸福指数 3。如果你不注意第一张图中的 y 轴,你可能会认为人均 GDP 接近 0 意味着幸福指数接近 0,但事实并非如此。这告诉我们,影响一个国家幸福得分的还有其他因素,也是应该考察的。
散点图有助于识别数据中存在的线性关系。然而,在 Matplotlib 中,在散点图上添加回归线并不容易。我的下一篇文章将告诉您如何使用 Seaborn 轻松做到这一点。
直方图
直方图显示了数据的特定特征的分布。更简单地说,它向我们展示了有多少个观察值取某个值。就像线形图和散点图一样,基本的直方图很容易创建。
plt.hist(score)
plt.title('Happiness Score Distribution')
plt.xlabel('Happiness Score')
plt.ylabel('Frequency')
plt.show()
这个直方图是用五行简单的代码创建的。它告诉我们有多少个国家有各自的幸福指数。因为幸福指数是一个连续的数值范围,所以我们不能只看它就得到精确的数据,但是我们可以得到一个大概的概念。例如,大约有 15 个国家的幸福指数在 3 到 4 之间,幸福指数在 4.5 左右的国家数量最多(大约 25 个)。换个方式说,最常见的幸福分值是 4.5 左右的数值。
条形图
在 Matplotlib 中构建条形图比您想象的要稍微困难一些。这可以用几行代码来完成,但是理解这段代码在做什么很重要。
roundedHappinessScore = score.apply(int)
count = roundedHappinessScore.value_counts()
hapScore = count.indexplt.bar(hapScore, count)
plt.title('Happiness Scores')
plt.xlabel('Score')
plt.ylabel('Count')
plt.show()
最后五行代码非常简单,但是前三行发生了什么呢?第一行将所有的幸福分数转换成一个整数,这样幸福分数只能取几个离散值。第二行得到每个分数出现的次数。该计数将用作我们的条形图的高度。然后,第三行得到与每个计数相关的分数,它需要作为我们图表的 x 轴。运行时,此代码会生成以下条形图:
这个图表给出了一个与我们上面创建的柱状图略有不同的故事。解释起来要容易得多,我们在这里可以看到,有最多的观察结果的幸福指数为 5。因为我们使用 int() 函数进行了“四舍五入”,这意味着分数 5 可以是范围 5 ≤ x < 6 中的任何值。
结论
正如您所看到的,Matplotlib 是一种非常快速地创建简单可视化的好方法。大多数图形只需要几行代码就可以创建,并且可以通过美学上的修改使它们变得更好。有关 Matplotlib 的更多信息,请点击这里查看 API。本文使用的所有代码都可以在我的 Github 中找到。本文是关于创建数据可视化的简短系列文章的第一篇,请继续关注关于使用 Seaborn 和 Plotly 创建可视化的教程。
入门级数据科学面试初学者指南
利用数据洞察的机会从未像现在这样多。然而,在这一点上,我们没有足够的熟练员工来帮助我们理解这一切。因此,如果你想成为一名数据科学家,在未来的 10-15 年里与数据打交道,那么这就是你的机会。去赢得那些工作吧!
本博客将简要介绍你在参加数据科学入门级面试之前必须了解的概念。在整个博客中,我将涵盖一系列有助于入门级数据科学面试的主题、你需要掌握的领域知识以及额外收获:围绕我的面试主题的问题!!!
传统上,数据科学侧重于编程、数学、计算机科学和机器学习领域的知识,而我们恰恰会接受这些知识!
对于一个数据科学家来说,有无数的机会,这是我给一个新手数据科学家的指南。
1.编程语言
到目前为止,Python 和 R 是我在数据科学领域看到的最流行的。然而,一个好的 C/C++和 Java 的工作知识从来没有伤害!
计算机编程语言
大多数数据科学家对 Python 有一种隐藏的喜爱,因为 Python 有一些令人惊叹的库,如 NumPy、SciPy、Pandas、StatsModel、Matplotlib、Seaborn、Plotly,使工作变得更容易。Scikit-learn、TensorFlow、PyTorch 等机器学习模块是一些值得了解的好资源。
稀有
对于 R,把 ggplot 当做你的英雄!对于这里的所有数据分析师来说,R 很容易实现数据可视化,R 是您想要了解的可视化内容。如果你的数据可视化首选语言是 R,那么像 ggplot、Latttice、Highcharter、Plotly、heat、dygraphs 这样的软件包在面试中,或者当你解释如何用 R 可视化热图时,肯定会很方便。
问题:
- 告诉我一些 Python 中可以用于逻辑回归的库?
- 如果你有两个变量 x 和 y,你怎么知道它们的相关性?
- 你怎么知道一个变量是否独立?
- 用 Python 写一个代码来查看一个数据集的前 10 条记录
2.数学
现在,数学可能不是每个人的强项,但作为一名数据科学家,你需要在统计、线性代数、概率和微积分方面表现出色。就是这样!
统计数字
统计学是一个数学领域,您通常会使用它来分析和可视化数据,以便从数据中发现、推断和提出有用的见解。箱线图、散点图、密度图、条形图、直方图帮助。然而,R 使任务更容易可视化和导出关系,而不是在移动计算器上计算 120 个记录的平均值:/
线性代数
线性代数主要用于机器学习和深度学习,用于理解算法在后端如何工作。基本上,它都是关于向量和矩阵运算,通过矩阵和向量空间的数据表示。我不太喜欢有人在面试中问数学问题,但你必须回答你必须回答的问题。
结石
机器学习中的微积分(以及深度学习)主要用于制定用于训练数据模型和算法的函数,以完成目标、计算损失/成本/目标函数并导出标量/向量关系。
可能性
贝叶斯定理。作为一名数据科学家,即使在睡梦中你也会知道这个问题的答案。然后,一些随机变量和概率分布
我被要求在一张纸上写下贝叶斯定理!
3.数据库管理
对于那些整天与数据打交道的数据科学家来说,数据库知识是必备的。数据科学家通常会选择两条不同的道路:数学或数据库管理。双重嵌套的 SQL 查询可能是你在一次噩梦般的面试中被要求写的东西。
也就是说,了解一些查询优化、关系数据库模式、数据库管理、评估成本、索引是很重要的。SQL 和 noSQL 系统的工作知识有助于面试。
出于一些奇怪的原因,在我的三次面试中,我被问到一个类似的关于数据库索引的问题。
问题:
- 假设,你有一个包含 56000 个公民记录的数据集,你必须找到年龄为 80 岁的公民。你会怎么做?
- 你知道数据库管理系统中的 ACID 属性吗?
- 什么是关联查询?
4.机器学习
对于初学数据的科学家来说,理解机器学习是数据科学的一部分是一个起点。它从统计学和算法中提取一些方面来处理从多种资源中生成和提取的数据。当你访问任何一个网站时,你都会生成数据,接下来会发生的是,大量的数据被生成,然后被处理。这就是机器学习开始发挥作用的时候。
机器学习是系统在没有人类偏见的情况下自主学习和处理数据集的能力。这是通过构建复杂的算法和技术来实现的,如回归、监督学习、聚类、朴素贝叶斯等。
首先要考虑的主题:
- 分类
- 回归
- 强化学习
- 深度学习
- 使聚集
- 分割
- 推荐系统(也许)
- 维度建模
对上述主题的初步了解将有助于开始。你总能想到使用机器学习算法的例子/应用。比如,网飞推荐系统或垃圾邮件过滤、欺诈和风险检测、高级图像识别等等…
5.基本定义
有时,像普通概念这样的基本概念可能会引发详细的对话。所以,在我与百事公司的面试中,有人问我是否可以在*上说通过数据讲故事。*我从直观结果的可视化数据的角度来看待它,接下来的 15 分钟是讨论数据可视化、基础知识、数据清理和数据感知。
我建议了解以下数据术语的确切含义,这样当出现一个与此相关的问题时,您就可以开始提问了!
a.数据分析
数据分析是一个学习、探索、检查、转换和建模数据的过程,目的是发现有用的信息并得出有洞察力的结果。数据分析对企业来说是最重要的,因为它可以根据事实智能、快速地做出决策,以支持公司地位的可视化表示。
b.数据争论
数据争论是将数据从原始数据形式转换和映射为更好的格式的过程,目的是使其更容易理解、更合适,并为各种下游目的(如分析)的进一步处理做好准备。
c.数据清理
顾名思义,数据清理就是
- 删除不寻常的数据出现(在一年的经验字段中不寻常的大量)
- 检测数据类型中的错误(比如性别输入字段中写的 127)
- 从记录集或数据库中更正损坏或不准确的记录($#@%而不是 34325)
- 填写不完整、不正确、不准确或不相关的数据部分(性别字段中缺少数据)
- 替换、修改或删除有噪声或粗糙的数据
d.探索性数据分析
EDA 是一种将数据简化为更小的汇总变量集的方法,并使用这些结果来:
- 最大化数据集的洞察力
- 揭示变量之间的潜在关系
- 提取对可视化重要的变量
- 检测异常值和异常值(非常重要!)
- 测试潜在的假设
- 确定最佳模型结构
除了所有这些知识之外,您还必须了解您所使用的 ide 和工具。
集成驱动电子设备
- 皮查姆
- 朱皮特
- Google CoLab
- Spyder
- r 工作室
工具
- (舞台上由人扮的)静态画面
- PowerBI
- 斯堪的纳维亚航空公司
- 阿帕奇火花
- 矩阵实验室
- 张量流
- 自动警报系统
- 蔚蓝的
你可能不一定知道所有的事情,但是要确保你知道的是那个袋子里的最后一粒。入门级数据科学面试要求你具备所有必需的知识。我的建议是建立正确的基础,关注基础。
为了练习,让自己在网上可见。写博客,创建回复,参与数据挑战和黑客马拉松,为开源做贡献。根据你想要的工作和你的热情,加上你刚刚阅读的面试指南,我相信你会得到最好的工作!
感谢您的阅读!如果你喜欢这篇文章,点击鼓掌按钮,让我知道我被问到的问题的答案!数据帐篷快乐!
了解你的作者
Rashi 是一名研究生,也是一名数据分析师、用户体验分析师和顾问、技术演讲者和博客作者!她渴望建立一个组织,将商界女性与资源海洋联系起来,让她们对工作和世界充满热情,无所畏惧。请随意给她留言这里!
卡格尔泰坦尼克号问题初学者指南
Image source: Flickr
因为这是我的第一篇文章,这里简单介绍一下我一直在做的事情:
我是一名软件开发人员,后来变成了数据爱好者。我最近开始了解数据科学的本质。当我开始通过 Udemy、Coursera 等网站上的视频和课程学习时,最突出的挑战之一就是。这让我变得被动,我听得更多,做得更少。我没有实践经验,尽管我能理解大部分理论。
就在那时,我遇到了 Kaggle,这是一个由多家大型科技公司(如谷歌)主办的网站,提供一系列数据科学问题和竞赛。在世界范围内,Kaggle 以其有趣、具有挑战性和非常非常令人上瘾的问题而闻名。其中一个问题是泰坦尼克号数据集。
总而言之,泰坦尼克号问题是基于 1912 年初“不沉之船”泰坦尼克号的沉没。它给你提供关于多人的信息,比如他们的年龄、性别、兄弟姐妹数量、登机点以及他们是否在灾难中幸存。基于这些特征,你必须预测泰坦尼克号上的任意一名乘客是否能在沉没中幸存。
听起来很简单,对吧?
没有。
问题陈述仅仅是的冰山一角。
使用的库
- 熊猫
- 海生的
- Sklearn
- WordCloud
铺设土地
初始阶段处理完整数据集的特征。在这里,我没有试图塑造或收集这些特征,只是观察它们的品质。
1.聚合
我最初聚集了来自训练和测试数据集的数据。得到的数据集有 1309 行和 12 列。每一行代表了 RMS 泰坦尼克号上的一个独特的乘客,每一列描述了每个乘客不同的有价值的属性。
*trd = pd.read_csv('train.csv')
tsd = pd.read_csv('test.csv')td = pd.concat([trd, tsd], ignore_index=True, sort = False)*
2.缺少值
数据集有几列缺少值。“Cabin”属性缺少 1014 个值。描述通勤者登机点的列“已登机”总共有 2 个缺失值。属性“Age”有 263 个缺失值,列“Fare”有一个缺失值。
*td.isnull().sum()sns.heatmap(td.isnull(), cbar = False).set_title("Missing values heatmap")*
3.种类
此外,为了理解分类和非分类特性,我查看了每一列中唯一值的数量。属性“性别”和“幸存”有两个可能的值,属性“上船”和“Pclass”有三个可能的值。
*td.nunique()PassengerId 1309
Survived 2
Pclass 3
Name 1307
Sex 2
Age 98
SibSp 7
Parch 8
Ticket 929
Fare 281
Cabin 186
Embarked 3
dtype: int64*
特征
在对数据集的不同方面有了更好的理解后,我开始探索这些特征以及它们在旅行者的生存或死亡中所起的作用。
1.幸存
第一个特写报道了一个旅行者的生死。一项比较显示超过 60%的乘客已经死亡。
2.Pclass
此功能呈现乘客分区。游客可以选择三个不同的区域,即一级、二级和三级。第三类的通勤人数最多,其次是第二类和第一类。三等舱的游客人数比一等舱和二等舱的乘客人数加起来还多。一级旅行者的生存机会高于二级和三级旅行者。
3.性
大约 65%的游客是男性,其余 35%是女性。然而,女性幸存者的比例高于男性幸存者。超过 80%的男性通勤者死亡,相比之下,约 70%的女性通勤者死亡。
4.年龄
船上最小的旅行者大约两个月大,最大的旅行者 80 岁。船上游客的平均年龄不到 30 岁。显然,10 岁以下儿童存活的比例比死亡的比例大。或其他年龄组,伤亡人数高于幸存者人数。20 至 30 岁年龄组中有超过 140 人死亡,而同年龄组中只有大约 80 人幸存。
5.SibSp
SibSp 是船上一个人的兄弟姐妹或配偶的数量。最多有 8 名兄弟姐妹和配偶与其中一名旅行者同行。超过 90%的人独自或与他们的兄弟姐妹或配偶之一一起旅行。如果一个人和两个以上的兄弟姐妹或配偶一起旅行,生存机会会急剧下降。
6.烤
与 SibSp 类似,该功能包含每位乘客同行的父母或孩子的数量。最多有 9 名父母/子女与其中一名旅行者同行。
我添加了“Parch”和“SibSp”值的数量,以存储在名为“Family”的新列中
*td['Family'] = td.Parch + td.SibSp*
此外,当一个旅行者独自旅行时,生存的机会会直线上升。创建了另一列,Is_Alone,如果“Family”列中的值为 0,则赋值为 True。
*td['Is_Alone'] = td.Family == 0*
7.票价
通过把车费分成四类,很明显,费用和生存之间有很强的联系。游客支付的费用越高,生存的机会就越大。
我将分离的费用存储到一个新的列 Fare_Category 中
*td['Fare_Category'] = pd.cut(td['Fare'], bins=[0,7.90,14.45,31.28,120], labels=['Low','Mid', 'High_Mid','High'])*
8.从事
apollowed 暗示旅行者从哪里出发。Embark 有三个可能的值— 南安普敦、瑟堡和皇后镇。超过 70%的人是从南安普敦上船的。不到 20%的乘客从瑟堡登机,其余的从皇后镇登机。从瑟堡登船的人比从南安普敦或皇后镇登船的人有更高的生还机会。
值得注意的是,我们没有使用“Ticket”列。
数据插补
数据插补是用一些替代值替换缺失数据的做法。可以使用多种替代方法。我用它们中的一些来弥补缺失的值。
1.从事
由于“登船”只有两个缺失值,并且从南安普敦登船的通勤者人数最多,因此从南安普敦登船的概率更高。所以,我们用南安普敦来填充缺失的值。然而,我们不是手动输入 Southampton,而是找到 apollowed 列的模式并用它替换丢失的值。众数是一个序列中出现频率最高的元素。
*td.Embarked.fillna(td.Embarked.mode()[0], inplace = True)*
2.小木屋
因为“小屋”一栏有很多缺失的数据。我决定将所有缺失的数据归为不同的类别。我把它命名为 NA。我用这个值给所有缺失的值赋值。
*td.Cabin = td.Cabin.fillna('NA')*
3.年龄
年龄是最难填写的一栏。年龄有 263 个缺失值。我最初是根据人们的称呼来给他们分类的。一个基本的 Python 字符串分割足以从每个名字中提取标题。有 18 个不同的标题。
*td['Salutation'] = td.Name.apply(lambda name: name.split(',')[1].split('.')[0].strip())*
然后,我将这些标题按照性别和类别进行了分类。
*grp = td.groupby(['Sex', 'Pclass'])*
然后在缺失的行中替换该组的中间值。
*grp.Age.apply(lambda x: x.fillna(x.median()))
td.Age.fillna(td.Age.median, inplace = True)*
编码
由于字符串数据不适合机器学习算法,我需要将非数字数据转换成数字数据。我用 LabelEncoder 对“性别”一栏进行了编码。标签编码器会用某个数字代替“男性”值,用某个不同的数字代替“女性”值。
*td['Sex'] = LabelEncoder().fit_transform(td['Sex'])*
对于其他分类数据,我使用熊猫的假人。它添加对应于所有可能值的列。因此,如果有三个装载值——Q、C、S,get_dummies 方法将创建三个不同的列,并根据装载点分配值 0 或 1。
*pd.get_dummies(td.Embarked, prefix="Emb", drop_first = True)*
删除列
此外,我删除了预测中不需要的列以及通过创建虚拟列而编码的列。
*td.drop(['Pclass', 'Fare','Cabin', 'Fare_Category','Name','Salutation', 'Deck', 'Ticket','Embarked', 'Age_Range', 'SibSp', 'Parch', 'Age'], axis=1, inplace=True)*
预言;预测;预告
这是一个分类问题的例子,我试着用两种算法预测—
- 随机森林
- 高斯朴素贝叶斯
我对结果感到惊讶。高斯朴素算法表现不佳,而另一方面,随机森林的预测准确率始终在 80%以上。
*# Data to be predicted
X_to_be_predicted = td[td.Survived.isnull()]
X_to_be_predicted = X_to_be_predicted.drop(['Survived'], axis = 1)
# X_to_be_predicted[X_to_be_predicted.Age.isnull()]
# X_to_be_predicted.dropna(inplace = True) # 417 x 27#Training data
train_data = td
train_data = train_data.dropna()
feature_train = train_data['Survived']
label_train = train_data.drop(['Survived'], axis = 1)##Gaussian
clf = GaussianNB()
x_train, x_test, y_train, y_test = train_test_split(label_train, feature_train, test_size=0.2)
clf.fit(x_train, np.ravel(y_train))
print("NB Accuracy: "+repr(round(clf.score(x_test, y_test) * 100, 2)) + "%")
result_rf=cross_val_score(clf,x_train,y_train,cv=10,scoring='accuracy')
print('The cross validated score for Random forest is:',round(result_rf.mean()*100,2))
y_pred = cross_val_predict(clf,x_train,y_train,cv=10)
sns.heatmap(confusion_matrix(y_train,y_pred),annot=True,fmt='3.0f',cmap="summer")
plt.title('Confusion_matrix for NB', y=1.05, size=15)*
*##Random forest
clf = RandomForestClassifier(criterion='entropy',
n_estimators=700,
min_samples_split=10,
min_samples_leaf=1,
max_features='auto',
oob_score=True,
random_state=1,
n_jobs=-1)
x_train, x_test, y_train, y_test = train_test_split(label_train, feature_train, test_size=0.2)
clf.fit(x_train, np.ravel(y_train))
print("RF Accuracy: "+repr(round(clf.score(x_test, y_test) * 100, 2)) + "%")result_rf=cross_val_score(clf,x_train,y_train,cv=10,scoring='accuracy')
print('The cross validated score for Random forest is:',round(result_rf.mean()*100,2))
y_pred = cross_val_predict(clf,x_train,y_train,cv=10)
sns.heatmap(confusion_matrix(y_train,y_pred),annot=True,fmt='3.0f',cmap="summer")
plt.title('Confusion_matrix for RF', y=1.05, size=15)*
*RF Accuracy: 78.77%
The cross validated score for Random forest is: 84.56*
最后,我创建了一个提交文件来存储预测的结果。
*result = clf.predict(X_to_be_predicted)
submission = pd.DataFrame({'PassengerId':X_to_be_predicted.PassengerId,'Survived':result})
submission.Survived = submission.Survived.astype(int)
print(submission.shape)
filename = 'Titanic Predictions.csv'
submission.to_csv(filename,index=False)
print('Saved file: ' + filename)*
下面的代码行特别重要,因为如果幸存值不是 int 数据类型,Kaggle 会认为预测是错误的
*submission.Survived = submission.Survived.astype(int)*
Submission result
完整的实现 Jupyter 笔记本可以在我的 GitHub 或者 Kaggle 上找到。提交的作品让我进入了前 8%的参赛者。这并不容易,我尝试了 20 多次才到达那里。我会说关键是要善于分析,玩转分析,凭直觉去尝试一切,不管这听起来有多荒谬。
神经网络初学者指南
用每个非技术人员都能理解的术语进行分解
Photo by Fré Sonneveld on Unsplash
“神经网络是一种技术,它不是一种算法,而是一个有权重的网络,你可以调整权重,以便它学习。你通过试验来教授它。”—霍华德·莱茵戈德
Ai 来了,AI 来了。
这就是这些天我们所听到的,以及它将如何严重影响每个人的生活。工作将会失去,人类将会被各行各业的机器所取代,还有许多其他在杂志和博客上写的末日预言。
有多少人知道世界上有哪些人工智能?
这篇文章将涵盖其中的一个方面,神经网络初学者指南。我们将看看什么是神经网络,它们如何运作,有哪些不同的类型,以及它们如何能够并将如何影响我们的生活。
让我们先来看看这些网络是什么。
什么是神经网络
人工神经网络 (ANN)是受构成动物大脑的生物神经网络启发但又不完全相同的计算系统。这种系统通过考虑例子来“学习”执行任务,通常没有用特定于任务的规则来编程。
他们通过观察一个物体的例子来学习,比如一只猫或一幅画,并识别某些特征,这样他们就可以在其他图像中确定这个物体。这些网络不需要知道它们正在分析的对象的任何信息。他们足够聪明,可以查看一些例子,并快速对事物进行分类,做出预测等。
现在你知道什么是神经网络,让我们看看它们是如何工作的。
它们是如何工作的?
神经网络由神经元驱动,神经元是排列在一系列相互连接的层中的微小单元。其中一层被称为输入单元,它被设计用来从外界接收不同形式的信息,然后进行识别、解释和分类。另一个单元是输出,位于网络的另一端,等待处理的结果。在输入和输出之间是隐藏的单元,它们执行大部分工作,决定如何处理输入的信息。
一个单位和另一个单位之间的联系称为权重,可以是正的,也可以是负的。每个单元从其左侧的单元接收输入,这些输入乘以它们所经过的连接的权重。每个单元将它接收到的所有输入相加,如果总和超过某个阈值,该单元就会“触发”并触发它所连接的单元。
神经网络通过接收反馈并告诉它是对还是错来学习。根据反馈,网络将进行调整以纠正错误。想想棒球中的一名击球手面对一名投手,他挥棒三振出局。他将回到休息区,思考他做错了什么。下次他站起来面对投手时,他会记得自己做错了什么,并做出相应的调整。
神经网络具有极强的适应性,学习能力强,并且有多种多样的类型,我们接下来会讲到。
神经网络的类型
根据原理、参数和数学运算,神经网络有许多不同的类型。他们每个人都有自己的长处和短处,学习的东西也不一样。我们探索当今最常用的类型以及它们的用途。
1.前馈神经网络–这可能是最简单的网络,也最容易理解。数据从输入端只向一个方向前进,直到到达输出端。在此过程中,计算输入和权重的乘积之和。最终结果被传递到输出端进行处理。
这些主要用于面部识别和计算机视觉,并被配备来处理包含大量噪声的数据。
2.递归神经网络(RNN)长短期记忆——这个网络保存特定层的输出,并将其反馈到输入中。第一层以与前馈神经网络相同的方式形成,计算输入和权重的总和。然而,在之后的层中,循环过程开始了。
在每一步中,节点将记住它在前一步中拥有的一些信息。它在计算和执行操作时充当存储单元。神经网络开始时与前馈网络一样,但记住信息以备后用。
这种类型的神经网络在语音到文本转换技术中非常有效。
3.径向基函数神经网络–该网络考虑了任意点相对于中心的距离。它们有两层,内层和外层。内层具有结合径向基函数的特征。径向基函数是实值函数,其值取决于输入和某个固定点(原点或中心)之间的距离。接下来,在下一时间步计算相同的输出时,考虑这些特征的输出。
径向基函数神经网络主要用于电力恢复系统。多年来,电力系统变得越来越大,越来越复杂,使得这个网络更加复杂。
可以看到,径向基函数神经网络和递归神经网络以相同的方式处理项目。
4.卷积神经网络(CNN)——这些网络的主要目的是从输入图像中提取特征。卷积通过使用输入数据的小正方形来学习图像特征,从而保留像素之间的空间关系。它由一个或多个卷积层和使用绑定权重和池层的完全连接层组成。
这些网络用于计算机视觉应用、物体识别应用,如机器视觉和自动驾驶车辆。
5.感知器–是一种二进制分类器的监督学习算法,使神经元能够一次一个地学习和处理训练集中的元素。换句话说,它执行计算来检测特征,并决定输入是否属于某个特定的类别。感知器主要有两种:单层感知器和多层感知器。它们都被归类为前馈神经网络,因为它们只向一个方向移动。
a. 单层感知器–不具有任何输入的先验知识,因此初始权重是随机分配的。感知器将所有加权输入相加,如果总和高于阈值,则认为感知器被激活。将输入值呈现给感知器,如果预测输出与期望输出相同,则认为性能令人满意,并且不对权重进行改变。但是,如果输出与所需输出不匹配,则需要更改权重以减少误差。
b. 多层感知器——结构与单层相同,但增加了一个或多个隐藏层。该算法由两个阶段组成:前向阶段,其中激活从输入层传播到输出层;后向阶段,其中输出层中观察到的实际值和请求的标称值之间的误差向后传播,以便修改权重和偏差值。
这些神经网络是如何使用的?
我们上面讨论的所有神经网络都是为发现数据中的模式而设计的。整理这些模式的具体任务是聚类、分类和预测。所有这些任务都解决了可用于许多领域的特定问题,例如财务、销售、营销和安全。
从预测股市每天的表现到使用面部识别软件抓住罪犯,一切都是通过神经网络来完成的。
这些网络可以利用聊天机器人、目标营销和市场细分等工具用于营销目的。我在前面的文章中提供了一些真实世界的例子,以及在哪里实现它。
在接下来的几年里,神经网络将在生物医学系统中实现,用于追踪疾病或预测一个人有多大比例可能倾向于某种遗传特征或异常。
结论
就像保罗·里维尔(Paul Revere)著名的骑马警告人们英国人来了一样,人工智能不仅在路上,而且就在这里。但是不像红色外套的到来,没有人会担心他们的生命。
这是对这些不断发展的技术的介绍,它告诉你什么是神经网络,它们是如何工作的,不同的类型以及它们今天是如何被使用的。我们都应该从这些网络所提供的东西中受益,而不要害怕一些我们不熟悉的技术的影响。
使用 NLP 预处理文本数据的初学者指南
用于预处理从 Twitter 获得的推文的代码
Source: https://www.blumeglobal.com/learning/natural-language-processing/
下面我概述了我用来预处理自然语言处理项目的代码。这个代码主要用于分类者从 Twitter 上获得的 tweets。我希望本指南能够帮助有抱负的数据科学家和机器学习工程师,让他们熟悉一些非常有用的自然语言处理工具和步骤。
要导入的包
from nltk.stem import LancasterStemmer, SnowballStemmer, RegexpStemmer, WordNetLemmatizer
#this was part of the NLP notebookimport nltk
nltk.download('punkt')#import sentence tokenizer
from nltk import sent_tokenize#import word tokenizer
from nltk import word_tokenize#list of stopwords
from nltk.corpus import stopwordsimport string
处理表情符号
import emoji#checking if a character is an emoji
def char_is_emoji(character):
return character in emoji.UNICODE_EMOJI#does the text contain an emoji?
def text_has_emoji(text):
for character in text:
if character in emoji.UNICODE_EMOJI:
return True
return False#remove the emoji
def deEmojify(inputString):
return inputString.encode('ascii', 'ignore').decode('ascii')
删除标点符号
punct =[]
punct += list(string.punctuation)
punct += '’'
punct.remove("'")def remove_punctuations(text):
for punctuation in punct:
text = text.replace(punctuation, ' ')
return text
下面的函数被用来为我工作的分类器项目对 tweets 进行大量的预处理。这应该同样适用于您可能正在从事的其他 NLP 项目。上面的功能会在下面辅助。
函数完成了大部分预处理工作,为了便于理解,已经将其注释掉了
def nlp(df):
# lowercase everything
# get rid of '\n' from whitespace
# regex remove hyperlinks
# removing '>'
# check for emojis
# remove emojis
# remove punctuation
# remove ' s ' from removing punctuation # lowercase everything
df['token'] = df['tweet'].apply(lambda x: x.lower())
# get rid of '\n' from whitespace
df['token'] = df['token'].apply(lambda x: x.replace('\n', ' '))
# regex remove hyperlinks
df['token'] = df['token'].str.replace('http\S+|[www.\S+'](http://www.\S+'), '', case=False)
# removing '>'
df['token'] = df['token'].apply(lambda x: x.replace('>', ''))
# Checking if emoji in tokens column, use for EDA purposes otherwise not necessary to keep this column
df['emoji'] = df['token'].apply(lambda x: text_has_emoji(x))
# Removing Emojis from tokens
df['token'] = df['token'].apply(lambda x: deEmojify(x))
# remove punctuations
df['token'] = df['token'].apply(remove_punctuations)
# remove ' s ' that was created after removing punctuations
df['token'] = df['token'].apply(lambda x: str(x).replace(" s ", " ")) return df
使用空间的词汇化
import spacy
from spacy.lemmatizer import Lemmatizer
from spacy.lookups import Lookupssp = spacy.load('en')
lookups = Lookups()
lemm = Lemmatizer(lookups)
创建和执行一个引理函数
def lemma_function(text):
dummy = []
#this is just a test to see if it works
for word in sp(text):
dummy.append(word.lemma_) return ' '.join(dummy)df['lemmatized'] = df['token'].apply(lambda x: lemma_function(x))
在对推文进行词汇化后,我发现“-PRON-”出现在我的文本中,这是在你使用 spacy 对代词进行词汇化后出现的“短语”。这对于通知我一条推文的内容并不重要,所以我也删除了这个“-PRON-”短语。
df['lemmatized'] = df['lemmatized'].apply(lambda x: x.replace('-PRON-', ' '))
标记我的数据
df['final_text'] = df['lemmatized'].apply(word_tokenize)
从我的令牌中删除停用字词
from nltk.corpus import stopwords
my_stopwords = set(stopwords.words('english'))df['final_text'] = df['final_text'].apply(lambda text_list: [x for x in text_list if x not in stopwords.words('english')])
从我的标记化文本数据中移除数字
df['final_text'] = df['final_text'].apply(lambda list_data: [x for x in list_data if x.isalpha()])
既然你的 tweet 数据已经被预处理了,你的数据现在应该更干净了。除了上述内容之外,您还有更广泛的考虑事项。在我的分类器项目中,我还使用了 TextBlob 来自动更正我的语料库中的任何拼写错误。但是请注意,TextBlob 的计算开销很大。此外,一旦您对数据进行了充分的预处理,并准备好创建单词包(计数矢量器)或 TF-IDF 矢量器,您就可以调整参数,以满足您对机器学习问题的要求。
我希望这篇指南能加速你的下一个 NLP 项目的文本数据的预处理。请随意留下任何想法和见解。
Q-Learning 初学者指南
决定性的反思
无模型强化学习
一旦你的狗犯了错误,你是否曾经责备或惩罚它?或者你有没有训练过一只宠物,你要求的每一个正确的命令都会奖励它?如果你是宠物主人,可能你的答案会是“是”。你可能已经注意到,一旦你从它年轻的时候就经常这样做,它的错误行为就会一天天地减少。同样,它会从错误中学习,训练自己。
作为人类,我们也经历了同样的事情。你还记得吗,在我们上小学的时候,一旦我们把功课做好了,老师就会奖励我们星星。😄
这正是在强化学习(RL) 中发生的事情。
强化学习是人工智能中最美的分支之一
RL 的目标是 通过响应动态环境 采取一系列行动来最大化代理人的报酬。
There are 4 basic components in Reinforcement Learning; agent, environment, reward and action.
强化学习是利用经验做出最佳决策的科学。分解一下,强化学习的过程包括以下简单的步骤:
- 观察环境
- 使用某种策略决定如何行动
- 相应地行动
- 接受奖励或惩罚
- 吸取经验教训,完善我们的战略
- 迭代直到找到最优策略
Source: [link](http://H. Nguyen and H. La, “Review of Deep Reinforcement Learning for Robot Manipulation,” in 2019 Third IEEE International Conference on Robotic Computing (IRC), Naples, Italy, 2019, pp. 590–595)
有两种主要类型的 RL 算法。分别是和 无模型 。
无模型 算法是一种不使用或估计环境的动态性(转移和奖励函数)而估计最优策略的算法。然而,基于 模型的 算法是使用转移函数(和回报函数)来估计最优策略的算法。
进入 Q-Learning
**Q-学习**是一种 无模型 强化学习算法。
Q-learning 是一种基于 值的 学习算法。基于值的算法基于等式(尤其是贝尔曼等式)更新值函数。而另一种类型, 基于策略的 利用从上次策略改进中获得的贪婪策略来估计值函数。
Q-learning 是一个 非策略学习者 。意味着它独立于代理的行为学习最优策略的值。另一方面, 基于策略的学习器 学习代理正在执行的策略的值,包括探索步骤,并且考虑到策略中固有的探索,它将找到最优的策略。
这个‘Q’是什么?
Q-learning 中的“Q”代表质量。质量在这里代表了一个给定的行为在获得未来回报中的有用程度。
Q-学习定义
- Q(s,a) 是在状态 s 下做 a,然后遵循最优策略的期望值(累计贴现报酬)。*
- Q-learning 使用时间差异(TD) 来估计 Q(s,a)的值。时间差异是一个主体在事先没有环境知识的情况下通过片段从环境中学习。*
- 代理维护一个 Q[S,A] 表,其中 S 是状态的集合, A 是动作的集合。
- Q[s,a]表示其对 Q(s,a)的当前估计。*
q-学习简单示例
在本节中,Q-learning 已经通过演示进行了解释。
假设一个智能体必须沿着一条有障碍的路径从起点移动到终点。智能体需要以最短的路径到达目标,而不碰到障碍物,并且他需要沿着障碍物覆盖的边界前进。为了方便起见,我在一个定制的网格环境中做了如下介绍。
Agent and its Environment
介绍 Q 表
Q-Table 是用于计算每个状态下行动的最大预期未来回报的数据结构。基本上,这张表将指导我们在每个状态下的最佳行动。为了学习 Q 表的每个值,使用 Q 学习算法。
Q 功能
Q 函数使用贝尔曼方程并接受两个输入:状态(s)和动作(a)。
Bellman Equation. Source: link
q-学习算法过程
Q-learning Algorithm
步骤 1:初始化 Q 工作台
首先要建立 Q 表。有 n 列,其中 n=动作的数量。有 m 行,其中 m=状态数。
在我们的例子中,n =向左、向右、向上和向下,m=开始、空闲、正确路径、错误路径和结束。首先,让我们将值初始化为 0。
Initial Q-table
第二步:选择一个动作
步骤 3:执行一个动作
步骤 2 和 3 的组合执行不确定的时间量。这些步骤会一直运行,直到训练停止,或者训练循环按照代码中的定义停止。
首先,基于 Q 表选择状态中的动作(a)。注意,如前所述,当剧集开始时,每个 Q 值都应该是 0。
然后,使用上面陈述的贝尔曼方程更新在起点和向右移动的 Q 值。
ε贪婪策略 的概念在这里发挥了出来。开始时,ε比率会更高。代理将探索环境并随机选择行动。这在逻辑上是这样发生的,因为代理对环境一无所知。当代理探索环境时,ε速率降低,代理开始利用环境。
在探索的过程中,代理在估计 Q 值时逐渐变得更有信心。
在我们的代理示例中,当代理的训练开始时,代理完全不知道环境。因此,让我们说,它采取了一个随机行动,其’正确’的方向。
Action : Agent follows ‘right’
现在,我们可以使用贝尔曼方程更新位于起点并向右移动的 Q 值。
Updated Q-table
第四步:衡量奖励
现在我们已经采取了一项行动,并观察到了一个结果和奖励。
第五步:评估
我们需要更新函数 Q(s,a)。
这个过程反复重复,直到学习停止。这样,Q 表被更新,并且值函数 Q 被最大化。这里 Q(state,action)返回该状态下该行为的预期未来回报。
Bellman Equation Explanation for the episodes
在示例中,我输入了如下奖励方案。
当离目标更近一步时奖励= +1
击中障碍物时的奖励=-1
空闲时奖励=0
Figure (a) Positive Reward, (b) & © Negative Rewards
最初,我们探索代理的环境并更新 Q 表。当 Q 表准备好时,代理开始利用环境并开始采取更好的行动。最终 Q 表可能如下所示(例如)。
Example final Q-table
以下是培训后代理实现目标的最短路径的结果。
Agent’s navigation towards the goal
**
Plotting the results for the number of steps (a) Episode via steps, (b) Episode via cost
履行
请投邮件掌握 python 实现代码的概念解释。
参考
[1] H. Nguyen 和 H. La,“机器人操纵的深度强化学习综述”,载于 2019 年第三届 IEEE 机器人计算国际会议(IRC) ,意大利那不勒斯,2019 年,第 590–595 页。
[3]https://courses . cs . ut . ee/mtat . 03.292/2014 _ spring/uploads/Main/Q-learning . pdf
[4]https://towards data science . com/introduction-to-variable-reinforcement-learning-algorithms-I-q-learning-sarsa-dqn-ddpg-72 a5 E0 CB 6287
[5]https://blog.dominodatalab.com/deep-reinforcement-learning/
希望你通过这篇博文对 Q-learning 有一个清晰的认识。如果你对这篇博文有任何问题或评论,请在下面留下你的评论。
干杯,学习愉快!
Rasa NLU 意图分类和命名实体识别初学者指南
Image taken from https://givemechallenge.com/wp-content/uploads/2017/01/rasa-NLU.png
本文的目的是探索使用 Rasa NLU 进行意图分类和命名实体识别的新方法。从版本 1.0.0 开始,Rasa NLU 和 Rasa 核心已经合并到一个框架中。因此,培训流程和可用功能有一些小的变化。首先也是最重要的是, Rasa 是一个开源的机器学习框架,用于自动化基于文本和语音的对话。换句话说,你可以使用 Rasa 来建立类似于智能聊天机器人的上下文和分层对话。在本教程中,我们将专注于框架的自然语言理解部分,以捕捉用户的意图。
截至 2020 年 10 月,Rasa 已正式发布 2.0 版本(Rasa 开源)。与版本 1 相比,数据训练格式发生了显著变化。查看我关于聊天机器人和 Rasa 2.0 新功能的最新文章,了解更多信息。
本教程有 5 个部分:
- 设置和安装
- 数据准备和格式
- 培训和测试
- 运行 NLU 服务器
- 结论
[第 1 节]设置和安装
我使用的是安装在 Windows 操作系统虚拟环境中的 Python 3.6.7。建议将其安装在干净的虚拟环境中,因为有相当多的 python 模块需要安装。
Python 模块
为了简单起见,我们将只安装一个可用于所有语言的标准管道。在官方文档中,团队建议使用 spaCy 管道,但我们将使用基于 Tensorflow 的监督嵌入管道。激活虚拟环境并运行以下命令:
pip install rasa
模块安装和升级可能需要一段时间。完成后,指向您选择的目录并运行以下命令:
rasa init --no-prompt
您将能够看到使用默认数据的 nlu 和 core 的培训过程。将创建以下文件:
- init。py :一个空文件,帮助 python 找到你的动作。
- actions.py :定制动作的代码
- config.yml :您的 NLU 和核心机型的配置
- credentials.yml :连接其他服务的详细信息
- data/nlu.md :你的 nlu 训练数据
- data/stories.md :你的故事
- domain.yml :您助手的域
- endpoints.yml :连接端点通道详情
- 型号/ <时间戳> .tar.gz :你的初始型号。时间戳的格式为 YYYYMMDD-hhmmss。仅限 NLU 的型号前面会有 nlu 前缀。
其实你已经训练出了一个完整的模型,可以用于意图分类。让我们继续下一部分,了解更多有关培训数据格式的信息。
[第二节]数据准备和格式
如果您想使用自己的定制数据来训练它,您可以准备 markdown 或 json 格式的数据。我将在本教程中使用 markdown,因为它是最简单的。请参考下面的链接,了解所有可用培训数据格式的更多信息。打开数据/nlu.md 数据,根据自己的用例开始修改内容。
目的
您可以使用## intent:name_of_intent 指定意图,后跟一个意图问题列表(每个意图之间有空格):
## intent:goodbye
- bye
- goodbye
- see you around
- see you later
- talk to you later## intent:ask_identity
- who are you
- what is your name
- how should i address you
- may i know your name
- are you a bot
实体
您可以指定每个问题中的实体,如下所示值:
## intent:ask_shop_open
- does the shop open on [monday](weekday)
- does the shop open on [wednesday](weekday)
- does the shop open on [friday](weekday)
在这种情况下,weekday 是实体的名称,而 monday 是值。为了抓住实体,你需要提供大量的例子。请注意上盒和下盒影响精度。星期一和星期一不一样。因此,建议在评估过程中,将所有数据训练为小写,并将输入数据解析为小写。
查找表
如果单个实体有一个很长的值列表,建议包括一个查找表,而不是作为例句填写所有的值。有两种方法可以做到。第一种是将它们包含在内:
## lookup:weekday
- monday
- tuesday
- wednesday
- thursday
- friday
第二种方法是在一个文本文件中列出它,并内嵌路径。让我们用一个名为“国家”的新实体来试试:
## lookup:countries
path/to/countries.txt
在 countries.txt 中,你可以在新的一行中指定每个元素如下:
singapore
malaysia
vietnam
indonesia
thailand
就像 weekday 实体一样,你必须提供几个例子让它进行概括。
## intent:inform_country_of_origin
- i am from [malaysia](countries)
- i am from [vietnam](countries)
- i came from [thailand](countries)
同义词
Rasa 还提供了一种识别同义词并将其映射回单个值的方法。第一种方法是像synonym1一样内联添加它:
## intent:ask_eaten
- what did you have for [breakfast](meal)
- what did you have for [break fast](meal:breakfast)
- what did you have for [breakfat](meal:breakfast)
第二种方法如下:
## synonym:breakfast
- brekfast
- brokefast
synonym 与查找表的不同之处在于,synonym 将实体的值映射到单个值(本例中为早餐)。换句话说,同义词是捕捉拼写错误和首字母缩略词的好方法,而查找表是概括例子的好方法。
正则表达式
还有一个支持正则表达式的特性叫做 regex。
## intent:inform_zipcode
- my zipcode is [12345](zipcode)
- my zipcode is [33456](zipcode)
- my zipcode is [94056](zipcode)## regex:zipcode
- [0-9]{5}
我附上了一个示例文本文件供您参考:
转换数据格式
Markdown 可以说是初学者创建数据的最安全的选择。然而,可能存在训练数据是自动的或来自其他来源的情况,例如 LUIS 数据格式、WIT 数据格式、Dialogflow 数据格式和 json。Rasa 还为您提供了一种转换数据格式的方法。查看以下链接了解更多。确保虚拟环境已激活,并运行以下命令(它将 md 转换为 json):
rasa data convert nlu --data data/nlu.md --out data/nlu.json -f json
- -数据是包含拉莎·NLU
数据的文件或目录的路径。 - - out 是以 Rasa 格式保存训练数据的文件名。
- -f 是训练数据应该转换成的输出格式
。接受 json 或 md。
一旦你有了所有需要的数据,将它移动到数据文件夹并删除任何现有的。让我们继续下一部分。
[第 3 节]培训和测试
培训模式
要训练 nlu 模型,您只需运行以下命令:
rasa train nlu
如官方文件所述,它将在数据文件夹中查找 NLU 训练数据文件,并将一个训练好的模型保存在模型文件夹中。记住从数据文件夹中移除任何不必要的数据文件。模型的名称将以 nlu-为前缀,以表明这是一个仅 nlu 的模型。话虽如此,您可以使用- data 参数指定路径。完整的参数列表可在处找到。
测试模型
您可以通过以下命令运行交互式 shell 模式来测试模型:
rasa shell nlu
如果您有多个 nlu 模型,并且想要测试一个特定的模型,请使用下面的命令。
rasa shell -m models/nlu-20190515-144445.tar.gz
检查以下链接,了解更多关于附加参数的信息。你可以输入你的文本并按回车键。shell 将返回一个 json 来表明意图和可信度。
[第 4 节]运行 NLU 服务器
运行服务器
Rasa 还为您提供了一种启动 nlu 服务器的方法,您可以通过 HTTP API 调用该服务器。运行以下命令(相应地修改模型的名称):
rasa run --enable-api -m models/nlu-20190515-144445.tar.gz
您应该会看到以下输出:
Starting Rasa Core server on http://localhost:5005
您可以通过在命令中一起指定参数来修改一些设置。查看以下链接了解更多信息。对于 cors 参数,它接受 URL 列表。它允许跨源资源共享,即告诉浏览器让在一个源(域)上运行的 web 应用程序有权访问来自不同源的服务器的选定资源。您可以使用“*”将所有域列入白名单。
rasa run --enable-api -m models/nlu-20190515-144445.tar.gz --cors "*"
在撰写本文时,似乎没有办法停止或中断服务器。我确实试过 Ctrl+C,但它只是偶尔有效。如果你遇到这样的问题,唯一的办法就是终止进程。只需点击关闭命令提示符,并重新运行它。一旦服务器开始运行,您就可以使用 curl 测试结果。打开一个新的命令提示符并运行以下行:
curl localhost:5005/model/parse -d '{"text":"hello"}'
您应该能够获得一个 json 结果,表明如下所示的意图和置信度:
{"intent":{"name":"greet","confidence":0.9770460725},"entities":[],"intent_ranking":[{"name":"greet","confidence":0.9770460725},{"name":"mood_unhappy","confidence":0.0257926807},{"name":"ask_identity","confidence":0.0009481288},{"name":"mood_great","confidence":0.0},{"name":"inform_identity","confidence":0.0},{"name":"goodbye","confidence":0.0}],"text":"hello"}
HTTP API
Rasa 还附带了自己的 HTTP API,如果您打算通过 AJAX 调用它,这个 API 会很有用。请参考完整的名单这里。在本教程中,我们将只关注一个 API 调用,它用于预测发送到端点的消息的意图和实体。您只需将 POST 呼叫发送到以下 URL:
[http://localhost:5005/model/parse](http://localhost:5005/model/parse)
下面是一个通过 AJAX POST 调用的例子:
最新的框架取消了在单个服务器中调用多个模型的能力。在前面的框架中,我们可以指定自己的模型作为参数,以指示哪个模型用于分类。现在,它正式成为每台服务器一个型号。
[第五节]结论
就这样,伙计们!让我们回顾一下,我们已经学习了如何使用 Rasa NLU 来训练我们自己的意图分类和实体提取模型。下一步是微调和进行进一步的培训,以优化当前的模型。如果您打算拥有一个基于故事进行回复的羽翼丰满的聊天机器人框架,您也可以选择查看 Rasa Core。另一方面,如果你已经为你的聊天机器人使用了其他框架,那么只使用 NLU 可以为你提供更大的灵活性。如果你有兴趣在信息平台中建立聊天机器人,请点击下面的链接。感谢您的阅读,祝您愉快!
参考
- http://rasa.com/docs/rasa/user-guide/installation/
- http://rasa.com/docs/rasa/user-guide/rasa-tutorial/
- http://rasa.com/docs/rasa/api/http-api/
- http://rasa.com/docs/rasa/user-guide/command-line-interface
- 【http://rasa.com/docs/rasa/nlu/training-data-format/
- http://rasa.com/docs/rasa/nlu/using-nlu-only/
- http://rasa . com/docs/rasa/user-guide/messaging-and-voice-channels/
使用石头剪刀布和 Tensorflow.js 进行强化学习的初学者指南
Tensorflow.js 刚刚发布,我刚刚参加了一个关于它在浏览器中的用例的讲座。我有在 Python 中广泛使用 Tensorflow 的经验,但我很好奇在浏览器中构建一个小型强化学习示例有多困难,在这个示例中,您可以看到一个代理随着时间的推移而学习。
我选择了石头剪子布,出于简洁和懒惰的原因,从现在开始它将被称为 RPS,因为它的游戏规则很简单,并且因为我知道学习只需要很少的例子。
本教程面向谁:任何对强化学习(RL)和神经网络的直观非数学教程感兴趣的人。他们应该有 JavaScript 和 html 的基本知识来理解代码,但这不是理解概念部分所必需的。
目标是:构建一个能够使用强化学习和神经网络来学习 RPS 规则的代理。这意味着如果用户选择剪刀,我们希望代理能够选择石头。
强化学习直观上可以描述如下:
循环:基于信念做某事→获得积极或消极的奖励→基于奖励更新信念
因此,当构建强化学习问题时,你必须记住上面的循环。所以我们可以用同样的方式分解 RPS 游戏。
- 当用户选择一步棋时,代理有一些关于它应该选择哪一步棋的信念。即,当用户选择纸张时,代理认为它应该选择石头。
- 用户对代理选择的移动给予积极或消极的奖励。
- 当用户选择纸张时,代理更新它关于是否应该选择石头的信念。
记住这一点,本教程分为两个部分:
- script.js,它将包含执行强化学习周期的代码。
- index.html 将允许用户与学习代理交互,并实时可视化学习。
我们将从 script.js 开始。
Choose Move
学习周期的开始是“根据代理的信念做一些事情”。在这个上下文中,这意味着根据用户的移动选择一个移动。
第 6–12 行:在评估阶段,我们想看看代理学得有多好。因此,选择的移动是具有最高值的移动。即代理最有信心的移动。这是借助神经网络完成的。
旁白:神经网络
神经网络是一种可以调整的功能。它接受一些输入,对输入做一些事情,然后输出一些结果。
Function
在 RL 和 RPS 的上下文中,使用神经网络来表示代理的信念。网络的输入是用户的移动,输出是代理在选择石头、布、剪刀时的信心。
Neural Network for Agent’s Beliefs
从上面可以看出,用户的举动是摇滚。代理人 0.7 自信应该选剪刀,0.1 自信选石头,0.2 自信选纸。如果我们处于评估阶段,代理将选择价值最高/最有信心的行动。即剪刀。
第 8–12 行:将移动转换为神经网络可以理解的格式,向网络请求其输出,然后选择具有最高值的移动。
第 14–16 行:在训练阶段,不是基于信念选择移动,而是随机选择移动。这使得代理可以探索所有的移动,而不是总是选择相同的移动。
Update beliefs
强化循环的下一阶段是从用户那里获得奖励,奖励将在 index.html 处理。收到奖励后,代理可以更新它的信念。
第 5–7 行:处理获取代理对用户移动应该选择的移动的信心
第 10-12 行:用奖励更新代理的信念。这是使用神经网络完成的。
旁白:更新神经网络
Updating a Neural Network
在这个场景中,用户选择了石头,代理选择了剪刀。用户给出了-100 的奖励,因为这一步棋是错误的。然后将-100 加到 0.7 上,并送回网络。这将告诉网络 0.7 的值太高,应该降低一些。这个过程叫做反向传播。这是更新代理人信念的行为。在这种情况下,代理应该对选择剪刀不太有信心,而对选择石头或布更有信心。
第 13 行:一旦网络被更新,新的信念就被绘制出来。
Plot the beliefs of the Agent
这种方法遍历用户可以选择的所有移动,并为用户的每个移动绘制代理的信念。
第 10 行:应用一个函数使神经网络的输出总和为 1。这使得用户能够更容易地理解神经网络的输出。
第 25 行:使用 Plotly.js 绘制 index.html 每个 div 中的数据集
Example output of the Network
现在我们已经完成了强化循环和可视化部分的所有部分。接下来我们将描述 index.html。这需要做几件事:
- 允许用户选择移动。
- 用户应该能够说出代理的移动是好是坏。
- 在学习代理随机选择移动和选择它最有信心的移动之间切换的能力。
- 可视化代理的信念,这意味着当用户选择一个移动时,显示代理在选择一个特定移动时有多自信
以下节选自 index.html,反映了上述观点。
User interface
第 1–3 行:有三个按钮是用户移动的,单击它们将调用 chooseMove 函数并向它传递按钮的值。这将使代理选择并返回一个移动。
第 5–6 行:当用户决定代理选择的移动是好是坏时,这些按钮将调用训练功能。这将告诉代理积极或消极地更新它的信念。
第 8–11 行:切换代理是正在学习还是正在评估其所学内容
第 13-17 行:包含 div,这些 div 将用于描绘代理对每个动作的信念。
至此,本教程到此结束。要查看所有代码,请访问这个库。你可以随意克隆它并使用代码。克隆完成后,在浏览器中打开 index.html。您将看到下图所示的设置。
最上面的按钮是用户的移动。一旦您选择了移动,代理将随机选择一个移动。然后,用户可以点击正面奖励或负面奖励按钮,信念将实时更新。单击新的移动并重复该过程。一旦你对学习到的行为感到满意,将开关从训练切换到评估,然后代理选择的移动将是每个直方图中最高值的移动。
我希望本教程对您有所帮助,并让您直观地了解如何构建强化学习问题,以及如何使用神经网络来帮助解决这个问题。
请继续关注神经网络和强化学习基础的进一步教程。
感谢阅读。
用 Gensim Word2Vec 模型嵌入单词的初学者指南
单词嵌入是自然语言处理(NLP)中最重要的技术之一,其中单词被映射到实数的向量。单词嵌入能够捕获文档中单词的含义、语义和句法相似性以及与其他单词的关系。它还被广泛用于推荐系统和文本分类。本教程将简要介绍 genism word2vec 模型,并给出一个为 vehicle make 模型生成单词嵌入的例子。
目录
- 1。Word2vec 简介
- 2。Gensim Python 库介绍
- 3。用 Gensim Word2Vec 模型实现单词嵌入
- 3.1 数据预处理:
- 3.2。Genism word2vec 模型训练
- 4。计算相似度
- 5。T-SNE 可视化技术
1.Word2vec 简介
Word2vec 是使用两层神经网络学习单词嵌入的最流行的技术之一。它的输入是一个文本语料库,输出是一组向量。通过 word2vec 嵌入单词可以使自然语言变得计算机可读,然后对单词进一步执行数学运算可以用来检测它们的相似性。一组训练有素的单词向量会将相似的单词彼此靠近地放置在那个空间中。例如,单词“女人”、“男人”和“人类”可能聚集在一个角落,而“黄色”、“红色”和“蓝色”则聚集在另一个角落。
word2vec 有两种主要的训练算法,一种是连续单词包(CBOW),另一种叫做 skip-gram。这两种方法的主要区别在于 CBOW 使用上下文来预测目标单词,而 skip-gram 使用单词来预测目标上下文。通常,与 CBOW 方法相比,skip-gram 方法可以具有更好的性能,因为它可以捕获单个单词的两种语义。例如,它将有两个代表苹果的向量,一个代表公司,另一个代表水果。关于 word2vec 算法的更多细节,请查看这里。
2.Gensim Python 库简介
Gensim 是一个用于自然语言处理的开源 python 库,由捷克自然语言处理研究员拉迪姆·řehůřek开发和维护。Gensim 库将使我们能够通过在自定义语料库上训练我们自己的 word2vec 模型来开发单词嵌入,或者使用跳格算法的 CBOW。
首先,我们需要安装 genism 包。Gensim 可以在 Linux、Windows 和 Mac OS X 上运行,并且应该可以在任何其他支持 Python 2.7+和 NumPy 的平台上运行。Gensim 依赖于以下软件:
- Python > = 2.7(用 2.7、3.5、3.6 版本测试)
- >= 1 . 11 . 3
- >= 0 . 18 . 1****
- 六 > = 1.5.0
- smart _ open>= 1 . 2 . 1
有两种安装方式。我们可以在终端上运行下面的代码来安装 genism 包。
**pip install --upgrade gensim**
或者,对于 Conda 环境:
**conda install -c conda-forge gensim**
3.用 Gensim Word2Vec 模型实现单词嵌入
在本教程中,我将通过一个具体的例子展示如何使用 genism 生成单词嵌入。我在本教程中使用的数据集来自 Kaggle 数据集。
该车辆数据集包括汽车的品牌、型号、年份、发动机和其他属性等特征。我们将使用这些特征来为每个制造模型生成单词嵌入,然后比较不同制造模型之间的相似性。完整的 python 教程可以在这里找到。
**>>> df = pd.read_csv('data.csv')
>>> df.head()**
3.1 数据预处理:
由于本教程的目的是学习如何使用 genism 库生成单词嵌入,为了简单起见,我们将不为 word2vec 模型进行 EDA 和特性选择。
Genism word2vec 要求用于训练的“列表列表”格式,其中每个文档都包含在一个列表中,并且每个列表都包含该文档的标记列表。首先,我们需要生成一个“列表列表”的格式来训练 make 模型单词嵌入。更具体地说,每个制造模型都包含在一个列表中,每个列表都包含该制造模型的特征列表。
为了实现这一点,我们需要做以下事情:
a.为制作模型创建新列
**>>> df['Maker_Model']= df['Make']+ " " + df['Model']**
b.为每个品牌车型生成一个具有以下特征的“列表列表”格式:发动机燃料类型、变速器类型、从动轮、市场类别、车辆尺寸、车型。
**# Select features from original dataset to form a new dataframe
>>> df1 = df[['Engine Fuel Type','Transmission Type','Driven_Wheels','Market Category','Vehicle Size', 'Vehicle Style', 'Maker_Model']]# For each row, combine all the columns into one column
>>> df2 = df1.apply(lambda x: ','.join(x.astype(str)), axis=1)# Store them in a pandas dataframe
>>> df_clean = pd.DataFrame({'clean': df2})# Create the list of list format of the custom corpus for gensim modeling
>>> sent = [row.split(',') for row in df_clean['clean']]# show the example of list of list format of the custom corpus for gensim modeling
>>> sent[:2]
[['premium unleaded (required)',
'MANUAL',
'rear wheel drive',
'Factory Tuner',
'Luxury',
'High-Performance',
'Compact',
'Coupe',
'BMW 1 Series M'],
['premium unleaded (required)',
'MANUAL',
'rear wheel drive',
'Luxury',
'Performance',
'Compact',
'Convertible',
'BMW 1 Series']]**
3.2.Genism word2vec 模型培训
我们可以使用自己的自定义语料库训练 genism word2vec 模型,如下所示:
**>>> model = Word2Vec(sent, min_count=1,size= 50,workers=3, window =3, sg = 1)**
让我们试着去理解这个模型的超参数。
size :嵌入的维数,默认为 100。
窗口:目标单词与其周围单词的最大距离。默认窗口是 5。
min_count :训练模型时要考虑的最小字数;出现次数少于此计数的单词将被忽略。min_count 的默认值为 5。
工人:培训时分区数量,默认工人为 3。
sg :训练算法,CBOW(0)或 skip gram(1)。默认的训练算法是 CBOW。
在训练 word2vec 模型之后,我们可以直接从训练模型中获得单词嵌入,如下所示。
**>>> model['Toyota Camry']array([-0.11884457, 0.03035539, -0.0248678 , -0.06297892, -0.01703234,
-0.03832747, -0.0825972 , -0.00268112, -0.09192555, -0.08458661,
-0.07199778, 0.05235871, 0.21303181, 0.15767808, -0.1883737 ,
0.01938575, -0.24431638, 0.04261152, 0.11865819, 0.09881561,
-0.04580643, -0.08342388, -0.01355413, -0.07892415, -0.08467747,
-0.0040625 , 0.16796461, 0.14578669, 0.04187112, -0.01436194,
-0.25554284, 0.25494182, 0.05522631, 0.19295982, 0.14461821,
0.14022525, -0.2065216 , -0.05020927, -0.08133671, 0.18031682,
0.35042757, 0.0245426 , 0.15938364, -0.05617865, 0.00297452,
0.15442047, -0.01286271, 0.13923576, 0.085941 , 0.18811756],
dtype=float32)**
4.计算相似度
现在,我们甚至可以通过调用 model.similarity()并传入相关单词,使用 Word2vec 来计算词汇表中两个 Make 模型之间的相似性。例如,model . similarity(’ Porsche 718 Cayman ‘,’ Nissan Van ')这将为我们提供 Porsche 718 Cayman 和 Nissan Van 之间的欧几里得相似性。
**>>> model.similarity('Porsche 718 Cayman', 'Nissan Van')
0.822824584626184>>> model.similarity('Porsche 718 Cayman', 'Mercedes-Benz SLK-Class')
0.961089779453727**
从上面的例子中,我们可以看出保时捷 718 Cayman 比日产 Van 更像奔驰 SLK 级。我们还可以使用内置函数 model.most_similar()来获得一组基于欧氏距离的最相似的 make 模型。
**>>> model1.most_similar('Mercedes-Benz SLK-Class')[:5][('BMW M4', 0.9959905743598938),
('Maserati Coupe', 0.9949707984924316),
('Porsche Cayman', 0.9945154190063477),
('Mercedes-Benz SLS AMG GT', 0.9944609999656677),
('Maserati Spyder', 0.9942780137062073)]**
然而,欧几里德相似性不能很好地用于高维单词向量。这是因为欧几里德相似性会随着维数的增加而增加,即使嵌入这个词代表不同的意思。或者,我们可以使用余弦相似性来度量两个向量之间的相似性。在数学上,它测量的是在多维空间中投影的两个向量之间的角度余弦。余弦相似度捕捉单词向量的角度,而不是幅度。在余弦相似度下,没有相似度被表示为 90 度角,而总相似度 1 处于 0 度角。
以下函数显示了如何基于余弦相似度生成最相似的 make 模型。
**def cosine_distance (model, word,target_list , num) :
cosine_dict ={}
word_list = []
a = model[word]
for item in target_list :
if item != word :
b = model [item]
cos_sim = dot(a, b)/(norm(a)*norm(b))
cosine_dict[item] = cos_sim
dist_sort=sorted(cosine_dict.items(), key=lambda dist: dist[1],reverse = True) ## in Descedning order
for item in dist_sort:
word_list.append((item[0], item[1]))
return word_list[0:num]# only get the unique Maker_Model
>>> Maker_Model = list(df.Maker_Model.unique()) # Show the most similar Mercedes-Benz SLK-Class by cosine distance
>>> cosine_distance (model,'Mercedes-Benz SLK-Class',Maker_Model,5)[('Mercedes-Benz CLK-Class', 0.99737006),
('Aston Martin DB9', 0.99593246),
('Maserati Spyder', 0.99571854),
('Ferrari 458 Italia', 0.9952333),
('Maserati GranTurismo Convertible', 0.994994)]**
5.T-SNE 可视化
很难直接将嵌入这个词形象化,因为它们通常有 3 个以上的维度。T-SNE 是一种有用的工具,通过降维来可视化高维数据,同时保持点之间的相对成对距离。可以说,T-SNE 正在寻找一种新的数据表示方法,在这种方法中,邻域关系被保留下来。下面的代码显示了如何用 T-SNE 图绘制单词 embedding。
**def display_closestwords_tsnescatterplot(model, word, size):
arr = np.empty((0,size), dtype='f')
word_labels = [word]close_words = model.similar_by_word(word)arr = np.append(arr, np.array([model[word]]), axis=0)
for wrd_score in close_words:
wrd_vector = model[wrd_score[0]]
word_labels.append(wrd_score[0])
arr = np.append(arr, np.array([wrd_vector]), axis=0)
tsne = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
Y = tsne.fit_transform(arr)x_coords = Y[:, 0]
y_coords = Y[:, 1]
plt.scatter(x_coords, y_coords)for label, x, y in zip(word_labels, x_coords, y_coords):
plt.annotate(label, xy=(x, y), xytext=(0, 0), textcoords='offset points')
plt.xlim(x_coords.min()+0.00005, x_coords.max()+0.00005)
plt.ylim(y_coords.min()+0.00005, y_coords.max()+0.00005)
plt.show()>>> display_closestwords_tsnescatterplot(model, 'Porsche 718 Cayman', 50)**
该 T-SNE 图以二维空间展示了与保时捷 718 Cayman 相似的前 10 款车型。
关于我
我是旧金山大学数据科学专业的硕士生。我热衷于使用机器学习来解决商业挑战。也可以通过 Linkedin 找到我。
XGBoost 初学者指南
这篇文章会有树…很多树
Trees… lots of them
想获得灵感?快来加入我的 超级行情快讯 。😎
XGBoost 是一个开源库,提供了梯度提升决策树的高性能实现。底层的 C++代码库与顶层的 Python 接口相结合,构成了一个极其强大而又易于实现的包。
XGBoost 的性能不是开玩笑的——它已经成为赢得许多 Kaggle 比赛的首选库。它的梯度增强实现是首屈一指的,随着该库继续获得好评,只会有更多的实现。
在这篇文章中,我们将介绍 XGBoost 库的基础知识。我们将从梯度增强如何实际工作的实际解释开始,然后通过一个 Python 例子来说明 XGBoost 如何使它变得如此快速和简单。
助推树木
对于常规的机器学习模型,如决策树,我们只需在数据集上训练一个模型,并使用它进行预测。我们可能会对参数稍加改动或增加数据,但最终我们仍然使用单一模型。即使我们建立了一个集合,所有的模型都被单独训练和应用于我们的数据。
**助推,另一方面,**采取一种更加迭代的方法。从技术上来说,这仍然是一种合奏技术,因为许多模型被组合在一起以完成最终的一个,但采用了一种更聪明的方法。
boosting 不是孤立地训练所有模型,而是连续训练模型,每个新模型都被训练来纠正前一个模型所犯的错误。模型按顺序添加,直到不能再进一步改进。
这种迭代方法的优点是,添加的新模型专注于纠正由其他模型引起的错误。在标准的集成方法中,模型是独立训练的,所有的模型最终可能会犯同样的错误!
梯度推进特别是一种训练新模型来预测先前模型的残差(即误差)的方法。我在下面的图表中概述了这种方法。
XGBoost 入门
让我们开始使用这个强大的库— XGBoost。
我们要做的第一件事是安装库,这是通过 pip 最容易做到的。在 Python 虚拟环境中这样做也可能更安全。
pip install xgboost
用 XGBoost 设置数据
在余下的教程中,我们将使用鸢尾花数据集。我们可以使用 Scikit Learn 将它加载到 Python 中。同时,我们还将导入新安装的 XGBoost 库。
*from* sklearn *import* datasets
*import* xgboost *as* xgb
iris = datasets.load_iris()
X = iris.data
y = iris.target
让我们把所有的数据都准备好。我们将从创建一个训练测试分割开始,这样我们就可以看到 XGBoost 执行得有多好。这次我们要 80%-20%的分成。
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.2)
为了让 XGBoost 能够使用我们的数据,我们需要将它转换成 XGBoost 能够处理的特定格式。这种格式被称为数据矩阵。将 numpy 数组的数据转换为 DMatrix 格式非常简单:
D_train = xgb.DMatrix(X_train, label=Y_train)
D_test = xgb.DMatrix(X_test, label=Y_test)
定义 XGBoost 模型
现在我们的数据都加载了,我们可以定义我们的梯度推进系综的参数。我们在下面设置了一些最重要的,让我们开始。对于更复杂的任务和模型,可能的参数的完整列表可以在官方 XGBoost 网站上获得。
param = {
'eta': 0.3,
'max_depth': 3,
'objective': 'multi:softprob',
'num_class': 3}
steps = 20 # The number of training iterations
最简单的参数是 max_depth (被训练的决策树的最大深度) objective (正在使用的损失函数),以及 num_class (数据集中的类的数量)。 eta 算法需要特别注意。
从我们的理论来看,梯度推进包括顺序地创建决策树并将其添加到集成模型中。创建新的树来校正来自现有集合的预测中的残留误差。
由于集合的性质,即,将几个模型放在一起形成本质上非常大的复杂模型,使得该技术易于过度拟合。 eta 参数为我们提供了一个防止过度拟合的机会
eta 可以更直观地认为是一个学习率*。不是简单地将新树的预测添加到具有全权重的集合中,而是将 eta 乘以所添加的残差以减少它们的权重。这有效地降低了整个模型的复杂性。*
通常具有 0.1 至 0.3 范围内的小值。这些残差的较小权重仍将帮助我们训练一个强大的模型,但不会让该模型陷入更可能发生过度拟合的深度复杂性。
培训和测试
我们最终可以像使用 Scikit Learn 那样训练我们的模型:
model = xgb.train(param, D_train, steps)
现在让我们进行评估。同样,该过程与 Scikit Learn 中的培训模型非常相似:
*import* numpy *as* np
*from* sklearn.metrics *import* precision_score, recall_score, accuracy_score
preds = model.predict(D_test)
best_preds = np.asarray([np.argmax(line) *for* line *in* preds])
print("Precision = {}".format(precision_score(Y_test, best_preds, average='macro')))
print("Recall = {}".format(recall_score(Y_test, best_preds, average='macro')))
print("Accuracy = {}".format(accuracy_score(Y_test, best_preds)))
厉害!
如果到目前为止你已经遵循了所有的步骤,你应该得到至少 90%的准确率!
XGBoost 的进一步探索
这就概括了 XGBoost 的基本知识。但是,还有一些更酷的功能可以帮助您充分利用您的模型。
- gamma 参数也有助于控制过度拟合。它指定了在树的叶节点上进行进一步划分所需的损失的最小减少量。也就是说,如果创建一个新节点不能减少一定数量的损失,那么我们根本不会创建它。
- 助推器参数允许你设置你将在构建合奏时使用的模型类型。默认的是 gbtree ,它构建了一个决策树集合。如果你的数据不太复杂,你可以使用更快更简单的 gblinear 选项,它构建了一个线性模型集合。
- 设置任何 ML 模型的最佳超参数都是一项挑战。那么为什么不让 Scikit Learn 帮你做呢?我们可以很容易地将 Scikit Learn 的网格搜索与 XGBoost 分类器结合起来:
*from* sklearn.model_selection *import* GridSearchCV
clf = xgb.XGBClassifier()
parameters = {
"eta" : [0.05, 0.10, 0.15, 0.20, 0.25, 0.30 ] ,
"max_depth" : [ 3, 4, 5, 6, 8, 10, 12, 15],
"min_child_weight" : [ 1, 3, 5, 7 ],
"gamma" : [ 0.0, 0.1, 0.2 , 0.3, 0.4 ],
"colsample_bytree" : [ 0.3, 0.4, 0.5 , 0.7 ]
}
grid = GridSearchCV(clf,
parameters, n_jobs=4,
scoring="neg_log_loss",
cv=3)
grid.fit(X_train, Y_train)
如果你有时间的话,只在大数据集上这样做——进行网格搜索本质上是多次训练决策树的集合!
- 一旦您的 XGBoost 模型经过训练,您就可以将它的可读描述转储到一个文本文件中:
model.dump_model('dump.raw.txt')
这是一个总结!
喜欢学习?
在 twitter 上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上与我联系!
MapReduce 初学者入门
很多时候,作为数据科学家,我们必须处理海量数据。在这种情况下,许多方法都不起作用或不可行。大量的数据是好的,非常好,我们希望尽可能地利用这些数据。
这里我想介绍 MapReduce 技术,这是一种用于处理大量数据的广泛技术。MapReduce 的实现有很多,包括著名的 Apache Hadoop。这里,我就不说实现了。我将尝试以最直观的方式介绍这个概念,并给出玩具和现实生活中的例子。
让我们从一些简单的任务开始。给你一个字符串列表,你需要返回最长的字符串。在 python 中这很容易做到:
def find_longest_string(list_of_strings):
longest_string = None
longest_string_len = 0 for s in list_of_strings:
if len(s) > longest_string_len:
longest_string_len = len(s)
longest_string = s return longest_string
我们一个接一个地检查字符串,计算长度并保留最长的字符串,直到我们完成。
对于小列表,它的工作速度相当快:
list_of_strings = ['abc', 'python', 'dima']%time max_length = print(find_longest_string(list_of_strings))OUTPUT:
python
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: **75.8 µs**
即使对于包含 3 个以上元素的列表,它也能很好地工作,这里我们尝试使用 3000 个元素:
large_list_of_strings = list_of_strings***1000**%time print(find_longest_string(large_list_of_strings))OUTPUT:
python
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: **307 µs**
但是如果我们尝试 3 亿个元素呢?
large_list_of_strings = list_of_strings***100000000**
%time max_length = max(large_list_of_strings, key=len)OUTPUT:
python
CPU times: user 21.8 s, sys: 0 ns, total: 21.8 s
Wall time: **21.8 s**
这是一个问题,在大多数应用中,20 秒的响应时间是不可接受的。改善计算时间的一个方法是购买更好更快的 CPU。通过引入更好更快的硬件来扩展您的系统被称为“垂直扩展”。这当然不会永远有效。不仅找到一个工作速度快 10 倍的 CPU 不是一件小事,而且,我们的数据可能会变得更大,我们不想每次代码变慢时都升级我们的 CPU。我们的解决方案不可扩展。相反,我们可以进行“水平扩展”,我们将设计我们的代码,以便它可以并行运行,当我们添加更多处理器和/或 CPU 时,它将变得更快。
为此,我们需要将代码分解成更小的组件,看看如何并行执行计算。直觉如下:1)将我们的数据分成许多块,2)对每个块并行执行find_longest_string
函数,3)在所有块的输出中找到最长的字符串。
我们的代码非常具体,很难破坏和修改,所以我们不使用find_longest_string
函数,而是开发一个更通用的框架,帮助我们在大数据上并行执行不同的计算。
我们在代码中做的两件主要事情是计算字符串的len
,并将其与迄今为止最长的字符串进行比较。我们将把代码分成两步:1)计算所有字符串的len
,2)选择max
值。
%%time# step 1:
list_of_string_lens = [len(s) for s in list_of_strings]
list_of_string_lens = zip(list_of_strings, list_of_string_lens)#step 2:
max_len = max(list_of_string_lens, key=lambda t: t[1])
print(max_len)OUTPUT:
('python', 6)
CPU times: user 51.6 s, sys: 804 ms, total: 52.4 s
Wall time: 52.4 s
(我正在计算字符串的长度,然后zip
将它们放在一起,因为这比在一行中计算并复制字符串列表要快得多)
在这种状态下,代码实际上比以前运行得更慢,因为我们不是对所有的字符串执行一次,而是执行两次,首先计算len
,然后找到max
的值。为什么这对我们有好处?因为现在我们的“步骤 2”得到的输入不是原始的字符串列表,而是一些预处理过的数据。这允许我们使用另一个“步骤二”的输出来执行步骤二!我们稍后会更好地理解这一点,但首先,让我们给这些步骤起个名字。我们称“第一步”为“映射器”,因为它将一些值映射到另一些值,我们称“第二步”为缩减器,因为它得到一个值列表并产生一个值(在大多数情况下)。以下是映射器和缩减器的两个辅助函数:
mapper = lendef reducer(p, c):
if p[1] > c[1]:
return p
return c
映射器就是len
函数。它获取一个字符串并返回它的长度。缩减器获取两个元组作为输入,并返回长度最大的一个。
让我们使用map
和reduce
重写我们的代码,在 python 中甚至有内置函数(在 python 3 中,我们必须从functools
导入它)。
%%time#step 1
mapped = map(mapper, list_of_strings)
mapped = zip(list_of_strings, mapped)#step 2:
reduced = reduce(reducer, mapped)print(reduced)OUTPUT:
('python', 6)
CPU times: user 57.9 s, sys: 0 ns, total: 57.9 s
Wall time: 57.9 s
代码做完全相同的事情,它看起来有点花哨,但它更通用,将帮助我们并行化。让我们更仔细地看看它:
步骤 1 使用 mapper 函数将我们的字符串列表映射到元组列表中(这里我再次使用zip
以避免重复字符串)。
步骤 2 使用 reducer 函数,检查来自步骤 1 的元组并逐个应用它。结果是一个具有最大长度的元组。
现在,让我们将输入分成块,并在进行任何并行化之前理解它是如何工作的(我们将使用chunkify
将一个大列表分成大小相等的块):
data_chunks = chunkify(list_of_strings, number_of_chunks=30)#step 1:
reduced_all = []
for chunk in data_chunks:
mapped_chunk = map(mapper, chunk)
mapped_chunk = zip(chunk, mapped_chunk)
reduced_chunk = reduce(reducer, mapped_chunk)
reduced_all.append(reduced_chunk)
#step 2:
reduced = reduce(reducer, reduced_all)print(reduced)OUTPUT:
('python', 6)
在第一步中,我们检查我们的块,并使用 map 和 reduce 找到该块中最长的字符串。在第二步中,我们获取第一步的输出,这是一个缩减值的列表,并执行最终的缩减以获得最长的字符串。我们使用number_of_chunks=36
是因为这是我机器上的 CPU 数量。
我们几乎可以并行运行我们的代码了。我们唯一可以做得更好的是将第一个reduce
步骤添加到单个映射器中。我们这样做是因为我们想把我们的代码分成两个简单的步骤,因为第一个reduce
在单个块上工作,我们也想把它并行化。它看起来是这样的:
def chunks_mapper(chunk):
mapped_chunk = map(mapper, chunk)
mapped_chunk = zip(chunk, mapped_chunk)
return reduce(reducer, mapped_chunk)%%timedata_chunks = chunkify(list_of_strings, number_of_chunks=30)#step 1:
mapped = map(chunks_mapper, data_chunks)#step 2:
reduced = reduce(reducer, mapped)print(reduced)OUTPUT:
('python', 6)
CPU times: user 58.5 s, sys: 968 ms, total: 59.5 s
Wall time: 59.5 s
现在我们有了一个好看的两步代码。如果我们按原样执行它,我们将获得相同的计算时间,但是,现在我们可以通过使用pool.map
函数而不是常规的map
函数,使用multiprocessing
模块来并行化步骤 1:
from multiprocessing import Poolpool = Pool(8)data_chunks = chunkify(large_list_of_strings, number_of_chunks=8)#step 1:
mapped = pool.map(mapper, data_chunks)#step 2:
reduced = reduce(reducer, mapped)print(reduced)OUTPUT:
('python', 6)
CPU times: user 7.74 s, sys: 1.46 s, total: 9.2 s
Wall time: 10.8 s
我们可以看到它运行速度快了两倍!这不是一个巨大的改进,但好消息是我们可以通过增加进程的数量来改进它!我们甚至可以在多台机器上进行,如果我们的数据非常大,我们可以使用几十台甚至几千台机器,使我们的计算时间尽可能短(几乎)。
我们的架构是使用两个函数构建的:map
和reduce
。每个计算单元映射输入数据并执行初始归约。最后,某个集中式单元执行最终的归约并返回输出。看起来是这样的:
这种架构有两个重要优势:
- 它是可扩展的:如果我们有更多的数据,我们唯一需要做的就是添加更多的处理单元。不需要更改代码!
- 它是通用的:这种架构支持各种各样的任务,我们可以用几乎任何东西代替我们的
map
和reduce
函数,这样就可以以可扩展的方式计算许多不同的东西。
需要注意的是,在大多数情况下,我们的数据会非常大并且是静态的。这意味着每次分割成块是低效的,实际上是多余的。因此,在现实生活中的大多数应用程序中,我们从一开始就将数据存储在块(或碎片)中。然后,我们将能够使用 MapReduce 技术进行不同的计算。
现在来看一个更有趣的例子:字数!
假设我们有一个非常大的新闻文章集,我们想找到不包括停用词的前 10 个常用词,我们该如何做呢?首先,让我们得到数据:
from sklearn.datasets import fetch_20newsgroups
data = news.data*10
在这篇文章中,我把数据放大了 10 倍,这样我们就可以看到不同之处。
对于数据集中的每个文本,我们希望对其进行标记化、清理、删除停用词,并最终计算单词数:
def clean_word(word):
return re.sub(r'[^\w\s]','',word).lower()def word_not_in_stopwords(word):
return word not in ENGLISH_STOP_WORDS and word and word.isalpha()
def find_top_words(data):
cnt = Counter()
for text in data:
tokens_in_text = text.split()
tokens_in_text = map(clean_word, tokens_in_text)
tokens_in_text = filter(word_not_in_stopwords, tokens_in_text)
cnt.update(tokens_in_text)
return cnt.most_common(10)
让我们看看不使用 MapReduce 需要多长时间:
%time find_top_words(data)OUTPUT:[('subject', 122520),
('lines', 118240),
('organization', 111850),
('writes', 78360),
('article', 67540),
('people', 58320),
('dont', 58130),
('like', 57570),
('just', 55790),
('university', 55440)]CPU times: user 51.7 s, sys: 0 ns, total: 51.7 s
Wall time: 51.7 s
现在,让我们写出我们的mapper
、reducer
和chunk_mapper
:
def mapper(text):
tokens_in_text = text.split()
tokens_in_text = map(clean_word, tokens_in_text)
tokens_in_text = filter(word_not_in_stopwords, tokens_in_text)
return Counter(tokens_in_text)def reducer(cnt1, cnt2):
cnt1.update(cnt2)
return cnt1def chunk_mapper(chunk):
mapped = map(mapper, chunk)
reduced = reduce(reducer, mapped)
return reduced
mapper
获取一个文本,将它分割成记号,清理它们,过滤无用的单词和非单词,最后,它计算这个文本文档中的单词数。reducer
函数获取 2 个计数器并将它们合并。chunk_mapper
得到一个块,并对其进行 MapReduce 操作。现在,让我们使用我们构建的框架来运行它,看看:
%%timedata_chunks = chunkify(data, number_of_chunks=36)#step 1:
mapped = pool.map(chunk_mapper, data_chunks)#step 2:
reduced = reduce(reducer, mapped)print(reduced.most_common(10))OUTPUT:
[('subject', 122520),
('lines', 118240),
('organization', 111850),
('writes', 78360),
('article', 67540),
('people', 58320),
('dont', 58130),
('like', 57570),
('just', 55790),
('university', 55440)]CPU times: user 1.52 s, sys: 256 ms, total: 1.77 s
Wall time: **4.67 s**
这快了 10 倍!在这里,我们能够真正利用我们的计算能力,因为任务要复杂得多,需要更多。
综上所述,MapReduce 是一种令人兴奋的、对于大型数据处理来说必不可少的技术。它可以处理大量的任务,包括计数、搜索、监督和非监督学习等等。今天有很多实现和工具可以让我们的生活更加舒适,但我认为理解基础知识非常重要。