TowardsDataScience 博客中文翻译 2016~2018(三百零四)
使用 BigQuery 的新地理空间函数来插值温度
当我写博文宣布来自全球历史气候网络(GHCN)的天气观测公共 BigQuery 数据集时,我展示了两个查询,一个是在某个边界框内查找气象站,另一个是提取某个气象站的最近天气数据。但是,查找边界框的查询使用了难看的纬度-经度限制检查,并且没有简单的方法将两个查询连接起来,以简单地从最近的气象站提取最近的气象数据(并非气象站数据集中的所有气象站现在都在运行,因此不能只使用限制)。
为什么不容易呢?因为 BigQuery 不支持地理空间功能。但是现在有了!因此,让我们将用例重写为一个单独的查询,并使它变得更好。我们不只是从最近的站获取数据。相反,我们将从附近的站点插入数据。如果您使用过 PostGIS 的 ST_ functions ,那么 BigQuery 中的地理空间函数对您来说会很熟悉。
到点的距离
假设我们在纬度为(41.88,-87.63)的地方有一家比萨饼店,首先计算该点 50 公里范围内所有车站的距离:
#standardSQL
WITH params AS (
SELECT ST_GeogPoint(-87.63, 41.88) AS center,
50 AS maxn_stations,
50 AS maxdist_km
),distance_from_center AS (
SELECT
id,
name,
state,
ST_GeogPoint(longitude, latitude) AS loc,
ST_Distance(ST_GeogPoint(longitude, latitude), params.center) AS dist_meters
FROM
`bigquery-public-data.ghcn_d.ghcnd_stations`,
params
WHERE ST_DWithin(ST_GeogPoint(longitude, latitude), params.center, params.maxdist_km*1000)
)SELECT * from distance_from_center
我设置了三个参数:中心位置、要使用的气象站的最大数量和插值的最大距离。然后,我使用 ST_Distance 计算距离,使用 ST_DWithin 过滤站点。(为什么不在 WHERE 子句中使用计算的距离?因为 DWITHIN 可以进行避免计算距离的优化,并且这样,仅针对足够近的站计算距离)。
此时的结果如下所示:
Distance of stations from our pizza joint
排名超过
50 公里内有 320 个车站。让我们把这个列表删减到前 50 名。我们不能使用 LIMIT,因为 LIMIT 需要硬编码的数字,而我们希望使用上面参数中的 maxn_stations。所以,有一种方法可以做到:
...nearest_stations AS (
SELECT
*,
RANK() OVER (ORDER BY dist_meters ASC) AS rank
FROM
distance_from_center
),nearest_nstations AS (
SELECT
station.*
FROM
nearest_stations AS station, params
WHERE
rank <= params.maxn_stations
)SELECT * from nearest_nstations
现在,结果按距离排序,并限制为 50:
Sorted by distance and limited to closest 50
使用 BigQuery GeoViz 可视化
我们可以用 BigQuery mapper 来实现这一点:
Stations with opacity set by distance
连接表格
现在,让我们通过将上述表格与天气数据表连接起来,并通过 id 将其连接起来,来获取每个站点的最近天气数据:
wxobs AS (
SELECT
wx.date AS date,
IF (wx.element = 'PRCP', wx.value/10, NULL) AS prcp,
IF (wx.element = 'TMIN', wx.value/10, NULL) AS tmin,
IF (wx.element = 'TMAX', wx.value/10, NULL) AS tmax,
station.id AS id,
station.name AS name,
station.dist_meters AS dist
FROM
`bigquery-public-data.ghcn_d.ghcnd_2018` AS wx
JOIN nearest_nstations AS station ON wx.id = station.id
WHERE
DATE_DIFF(CURRENT_DATE(), wx.date, DAY) < 15
),daily_wx AS (
SELECT
date,
MAX(prcp) AS prcp,
MAX(tmin) AS tmin,
MAX(tmax) AS tmax,
id,
MAX(name) AS name,
MAX(dist) AS dist
FROM
wxobs
GROUP BY
date, id
HAVING tmin > -100 AND tmax > -100
ORDER BY
date ASC
)
上面的奇怪之处是因为 gchnd_2018 表中的每条记录只包含一个观测值(tmin、tmax 或 prcp ),因此我们必须合并多行才能获得完整的观测值集。结果现在看起来像这样:
Daily weather from the two(!) stations with temperature data for each day
插入文字
现在,我们可以添加插值代码:
SELECT
date,
ROUND(SUM(tmin/(dist*dist))/SUM(1/(dist*dist)),1) AS tmin,
ROUND(SUM(tmax/(dist*dist))/SUM(1/(dist*dist)),1) AS tmax,
ROUND(SUM(prcp/(dist*dist))/SUM(1/(dist*dist)),2) AS prcp
FROM
daily_wx
GROUP BY date
ORDER BY date desc
这给了我们:
Recent weather, interpolated to our pizza parlor
下面是全查询。试试吧!
离多边形的距离
在上面的查询中,我计算了两点之间的距离。相反,如果您想找到邮政编码方圆 10 公里内的所有气象站,该怎么办呢?这里有一个查询可以做到这一点:
#standardsql
WITH params AS (
SELECT 60626 AS zipcode,
10 AS maxdist_km
),zipcode AS (
SELECT **ST_GeogFromText(WKT)** AS polygon
FROM `cloud-training-demos.demos.zipcode_polygon2017`, params
WHERE ZCTA5CE10 = params.zipcode
),stations AS (
SELECT
id,
name,
ST_GeogPoint(longitude, latitude) AS loc,
**ST_Distance**(ST_GeogPoint(longitude, latitude), zipcode.polygon) AS dist_meters
FROM
`bigquery-public-data.ghcn_d.ghcnd_stations`,
params,
zipcode
WHERE **ST_DWithin**(ST_GeogPoint(longitude, latitude), zipcode.polygon, params.maxdist_km*1000)
)SELECT * from stations
ORDER BY dist_meters ASC
LIMIT 100
需要注意的关键是,zipcodes 的 BigQuery 表包含众所周知的文本(WKT)的几何信息,所以我使用 ST_GeogFromText 来解析它。【注意:不是将列存储为字符串,我可以将它存储为地理类型——这样,我只需解析字符串一次,而不是在每个分析函数中】。一旦我有了多边形几何,我就可以将它传递到 ST_Distance 和 ST_DWithin 函数中,类似于我传递一个点的方式,并可视化结果:
请注意,到前两个站点的距离为零,因为它们在邮政编码范围内。其余的在邮政编码边界 10 公里以内。
尽情享受吧!
使用 CNN 和 RNNs 进行音乐流派识别
用数据做很酷的事情!
音频数据正在成为机器学习的重要组成部分。我们正在使用音频与 Siri 和 Alexa 等智能代理进行交互。音频对于自动驾驶汽车也很重要,这样它们不仅可以“看到”周围的环境,还可以“听到”周围的声音。我想探索音频文件和音乐分析的深度学习技术,这似乎是一个有趣的领域,有很多有前途的研究。在这篇博客中,我研究了结合 CNN 和 RNNs 的架构,将音乐片段分为 8 种不同的类型。我也在不同的 CNN 层中可视化过滤器激活。如果你是深度学习的新手,想了解 CNN 和计算机视觉的深度学习,请查看我的博客这里。
这个项目的代码可以在我的 Github 上找到。我希望这里提到的技术有更广泛的应用,而不仅仅是在音乐上。希望你喜欢!
Music Classification
数据集和转换成 Mel 光谱图
有几个不同的音乐数据集——GTZan和百万首歌曲数据集( MSD )是最常用的两个。但是这两个数据集都有局限性。GTZan 每个流派只有 100 首歌曲,而 MSD 有 100 万首歌曲,但只有它们的元数据,没有音频文件。我决定使用免费音乐存档小数据集。您可以使用他们的 github 链接下载小数据集(8 GB ),其中包含原始音频文件和元数据。我使用的 FMA 小数据集有 8 个流派,每个流派平均分布着 1000 首歌曲。这八个流派是电子、实验、民谣、嘻哈、器乐、国际、流行和摇滚。
将音频数据转换成频谱图
每个音频文件都被转换成频谱图,这是频谱随时间变化的直观表示。常规频谱是音频信号的短期傅立叶变换(STFT)的平方幅度。这种常规频谱使用 mel scale 进行压缩,将 音频转换为人类更容易理解的内容。我使用 librosa 库中的内置函数将音频文件直接转换成 mel-spectogram。变换中使用的最重要的参数是——窗口长度,它表示执行傅立叶变换的时间窗口,以及跳跃长度,它是连续帧之间的样本数。这种变换的典型窗口长度是 2048,转换成大约 10ms,这是人耳能够分辨的最短合理周期。我选择跳长为 512。此外,由 Librosa 产生的 Mel-光谱图由对数函数定标。这将 声音数据映射到正常的对数标度,该标度用于确定以分贝(dB)为单位的响度,因为它与人类感知的音高相关。作为这种变换的结果,每个音频文件被转换成形状为 640,128 的 mel 谱图。
如图 1 所示,不同的流派在他们的 Mel-spectrogram 中有明显的差异,这给了我们使用 CNN 进行分类的信心。
Spectogram — Pop(TL), Instrumental (TR), Experimental (BL) and Folk(BR)
Librosa 使得创建光谱图变得非常容易。一个 3 行代码可以将一个音频文件转换成一个频谱图!
y, sr = librosa.load(filename)
spect = librosa.feature.melspectrogram(y=y, sr=sr,n_fft=2048, hop_length=512)
spect = librosa.power_to_db(spect, ref=np.max)
为了加快训练速度,我将数据集分为训练、测试和验证,将它们各自的音频文件转换为频谱图,并挑选结果,以便这些经过腌制的数据可以直接加载。你可以在驱动链接上找到这些数据。
构建 CNN-RNN 模型
为什么要用 CNN 和 RNNs?
出现的一个问题是,为什么我们需要同时使用 CNN 和 RNNs。频谱图是跨越频率和时间维度的音频的视觉表示。CNN 是有意义的,因为一首歌的频谱有点像一幅图像,每一幅都有自己独特的模式。rnn 通过使时间 t 的隐藏状态依赖于时间 t-1 的隐藏状态,在理解顺序数据方面表现出色。频谱图具有时间成分,并且 RNNs 可以更好地识别歌曲中的短期和长期时间特征。
我尝试了两种有趣的 CNN-RNN 架构——卷积递归模型和并行 CNN-RNN 模型。这两个模型都是用 Keras 编写的,你可以在我的 Github 上找到代码。
卷积递归模型
这个模型的灵感来自于 deep sound 的工作和 Keunwoo Choi 等人的论文,这个模型使用的是 1D CNN,它只在时间维度上执行 卷积运算。每个 1D 卷积层从光谱图的一小片中提取特征。卷积运算后应用 RELU 激活 。完成批量归一化,最后执行 1D 最大池,这降低了图像的空间维度并防止过拟合。这个操作链——1D 卷积——RELU——批量归一化——1D 最大池被执行 3 次。来自 1D 卷积层的输出被馈送到 LSTM,该应该找到歌曲的短期和长期结构。LSTM 使用 96 个隐藏单元。来自 LSTM 的输出被传递到一个由 64 个单元组成的 密集层。模型的最终输出层是具有 Softmax 激活和 8 个隐藏单元的密集层,以将概率分配给 8 个类别。在所有层之间使用了丢弃和 L2 正则化来减少模型的过拟合。下图显示了该模型的整体 架构。
CRNN Model
使用 Adam optimizer 以 0.001 的学习率训练该模型,损失函数是分类交叉熵。该模型被训练 70 个时期,并且如果验证准确度稳定在至少 10 个时期,则学习率降低。
参见下面的训练和验证样品的损失和准确度曲线。正如所看到的,该模型具有低偏差但高方差,这意味着即使在使用了几种正则化技术之后,该模型对于训练来说还是有点过度拟合。
CRNN — Loss and Accuracy
总的来说,这个模型在验证集上达到了大约 53%的准确率。
并行 CNN-RNN 模型
受林芬和刘深兰的作品的启发,我也尝试了一个平行的 CNN-RNN 模式。这个网络背后的关键思想是,即使 CRNN 有 RNNs 作为时间摘要器,它也只能从 CNN 的输出中总结时间信息。在使用 CNN 的操作期间,原始音乐信号的时间关系没有被保留。该模型将输入频谱图并行通过 CNN 和 RNN 层,连接它们的输出,然后通过 softmax 激活的密集层发送,以执行分类,如下所示。
Parallel CNN-RNN Model
该模型的卷积块由 2D 卷积层和随后的 2D 最大汇集层组成。这与使用 1D 卷积和最大池层的 CRNN 模型形成对比。卷积最大池层有 5 个块。最终输出是平坦的,并且是无形状的张量 256。 复发块从池大小为 4,2 的 2D 最大池层开始,以在 LSTM 手术之前减小频谱图的大小。这种特征减少主要是为了加速处理。缩小的图像被发送到具有 64 个单元的双向 GRU。该层的输出是无形状的 张量,128。 来自卷积和递归块的输出然后被连接,产生形状张量,无,384。最后,我们有一个 softmax 激活的密集层。 使用 RMSProp 优化器训练模型,学习率为 0.0005,损失函数为分类交叉熵。该模型被训练 50 个时期,并且如果验证准确度稳定在至少 10 个时期,则学习率降低。
下图显示了该模型的损耗和精度曲线
该模型的验证损失约为 51%。这两个模型具有非常相似的整体精度,这很有趣,但它们的类智能性能非常不同。并行 CNN-RNN 模型对于实验、民谣、嘻哈和器乐流派有更好的表现。这两个模型的组合应该会产生更好的结果。
我问自己的一个问题是,为什么准确率只有 51%左右。我认为这有两个原因:
- 对于从零开始构建深度学习模型来说,1000 个光谱图的样本量实际上是一个非常小的样本。从损失曲线可以看出,两种模型都很快过度拟合。理想情况下,我们有一个更大的训练集,或者可以尝试的一件事是将每首歌曲分成 3 段,每段 10 秒,每个都有相同的标签,并使用它将数据集的大小增加两倍。
- FMA 的数据集很有挑战性,特别是它有几个容易混淆的类,比如实验类和国际类。在 FMA 流派识别挑战赛上的最高分只有 0.63 分左右
使用 Keras 可视化工具包可视化不同层中的激活
我研究了卷积模型的初始层和后续层的特征。对于这个分析,我使用了 Keras 可视化包并选择了并行 CNN-RNN 模型,因为它使用了更容易可视化的 2D CNN 层。
该模型中的第一卷积块具有 16 个滤波器,第五卷积块具有 64 个滤波器。为了理解过滤器关注的是什么,我们来看看什么样的输入最大化了过滤器中的激活。下图显示了第一个卷积块中所有 16 个滤波器与第五个卷积块的前 24 个滤波器的滤波器激活。
Filter Activations for first and fifth convolutional block
我在这里观察到的是,第一层的过滤器相对简单。有在看一个 3,1 的小内核大小。因此,他们主要关注 50-200 db 之间的不同波动模式。在第五个卷积块中,由于卷积和最大池化操作导致特征图缩小,同一滤波器正在查看更大的输入图像 。现在,它能够聚焦于不同的特征,如振幅急剧增加至 250 db,以及振幅非常低的时段显示为黑色区域。
我希望您喜欢这个分析,并尝试自己的代码。
我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请在 deeplearninganalytics.org/的[入住我们的酒店。](deeplearninganalytics.org/)
你也可以在medium.com/@priya.dwiv…看到我的其他作品
如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我
参考
使用联合数据
德瓦希什·迪曼&维克拉姆·德瓦塔
联合分析有助于确定消费者如何评价产品的不同属性。这是一种常用的统计技术,用于模拟新产品发布时的消费决策和产品市场份额。在这里,我们将联合分析的原则应用于 Partworth 的数据,这些数据来自对 7 个知名啤酒品牌的 317 名受访者的调查。以下是我们处理这个话题的方式:
首先,我们探索数据集,以更好地理解应答者的人口统计数据。接下来,我们根据给定的 Partworth 数据对啤酒品牌进行细分,并使用这些数据对每个细分进行个性化。然后,我们尝试判别分析,以检查该模型是否可以用来分类新的反应。我们计算目前的市场份额,以及当一种新啤酒在同一个市场推出时,市场份额如何变化。根据市场份额的变化,我们确定了新啤酒品牌的最佳细分市场。
这里有原始数据:【goo.gl/nP91hF】T2。T… 和 R 是本分析中使用的主要工具。
探索人口统计
数据集中提供了以下人口统计详细信息:
年龄直方图显示,大多数受访者年龄在 30-45 岁之间。年龄变量的箱线图显示它有轻微的偏斜,没有异常值。
大多数受访者收入超过 50,000 美元,没有异常值。尽管该分布显示了左偏斜,但它并没有大到足以保证对数变换。
类别变量(年龄和收入)通过取类别平均值转换成整数对应变量。年龄变量的第一类被假定为“21 岁以下”,而不是数据集中给定的“22 岁以下”。
“每周消费量”直方图显示,大多数受访者在任何给定的一周内消费不到 10 瓶啤酒。箱线图揭示了几个异常值,但考虑到领域(“啤酒”)和数据生成过程(“消费模式”),我们选择不转换数据,并保留异常值。
大多数受访者是大学毕业生,其次是研究生。缺少值(用' 4 '代替)的很少,用'高中'及以下的很少。数据集的男性数量明显多于女性,任何建议都需要牢记这一点。
根据 Partworth 数据对品牌进行细分
我们对 Partworth 数据使用 K-Means 聚类,为不同数量的聚类生成“组内平方和”的 scree 图,如下所示。我们找不到一个显著的弯头来给出最佳分段数的直观感觉。
我们尝试使用 3 个段和 4 个段进行聚类,但我们发现用 2 个段描述数据最好。由于数据集很小,我们使用凝聚层次聚类使用欧几里德距离与病房的方法。我们将树分为两段,如下所示:
导出结果成员数据,以便在 Tableau 中可视化和描述受访者。
拟人化并描述每个片段
我们将人口统计数据与从聚类算法中获得的成员详细信息“连接”在一起,注意如下:
与细分市场 2 中的受访者相比,细分市场 1 中的受访者年龄略小,收入略高,啤酒消费量也更多。进一步按性别区分,我们得到以下结果:
平均而言,在这两个群体中,男性年龄更大,收入更高,每周消费更多瓶啤酒。然而,第二部分的男女平均收入差距大于第一部分,而第一部分的男女平均周消费差距大于第二部分。
基于以上所述,我们将分段 1 命名为“年轻快乐”,分段 2 命名为“年老成熟”。
通过在 Tableau 中可视化按比例缩放的 Partworth 数据,并使用细分成员数据按颜色区分,我们获得以下金字塔图。
我们发现,“老熟”更喜欢价格为 5.49 美元的普通酒体、日本或加拿大啤酒,具有普通卡路里和浓郁的余味,而“年轻和快乐”则倾向于喜欢欧洲的醇厚啤酒,酒体清脆、清澈,余味温和。
我们可以计算每个回答者赋予每个属性的重要性,即。分配给属性级别的 Partworth 实用程序的范围除以总数。将这些数据导入 Tableau 有助于我们直观地了解每个细分对每个属性的相对重要性,如下所示。
虽然这两个部分似乎对所有属性给予了同等的重视,但我们看到年轻和快乐的人比其他部分更重视啤酒中的卡路里数,而年老和成熟的人比其他部分更重视杯子。
执行判别分析
人口统计数据中的描述符可用于基于以上获得的片段执行判别分析。我们尝试了线性判别分析(又名 Fischer 判别)来区分这两个细分市场,并使用该模型来预测新消费者将属于哪个细分市场。人口统计数据与细分成员数据“结合”,然后分成训练和验证数据集(比例为 80:20)。
使用来自 r 中质量包的 lda 函数进行线性判别分析。区段 ID 作为类别变量(因变量), 5 个分类变量(年龄、教育程度、性别、收入和每周消费)作为解释变量。结果如下所示:
下面给出了来自训练集的混淆矩阵:
准确率仅为 69.57%,实际错误率(AER)为 30.43%。然后将 LDA 模型应用于验证数据集,以测试其有效性。获得了以下结果:
准确率仅为 57.81%,实际错误率(AER)为 42.19%。线性判别分析似乎不能很好地处理给定的数据集,我们不建议使用该模型来区分两个细分市场中的新消费者。
计算目前的市场份额
每位受访者对某一属性的重视程度被用来计算他/她消费某一品牌啤酒的可能性。每个啤酒品牌的属性和级别用于创建二元矩阵,如下所示:
每个应答者的 Partworth 效用与上述二进制矩阵交叉相乘,然后取幂。通过计算每个品牌占总和的比率,我们获得了新产品发布前每个品牌的市场份额。
目前的市场份额也按细分市场进行了分析,如下所示
虽然大多数品牌在每个细分市场的份额几乎相同,但我们观察到 HH 和 al 在细分市场 1(年轻和快乐)的渗透率更高,而 BB、BG、MN 和 SA 在细分市场 2(成熟和成熟)的表现可能更好。
计算新的市场份额
如果一个新品牌 NB 被引入市场,那么新产品被插入二元矩阵,如下所示:
可以通过新品牌的潜在渗透率来重新计算市场份额,即每个受访者的 Partworth 效用与二元矩阵相乘,然后取幂。新产品发布后,每个品牌占总市场份额的比率。新的市场份额如下:
市场份额减少情况汇总如下:
选择目标细分市场
按细分市场划分的新市场份额如下所示。
我们还比较了新啤酒品牌发布后的市场份额变化,如下所示:
由于新品牌的出现,HH、BB、AL 和 s a 的细分市场 1(“年轻和快乐”)的市场份额有所下降,而 HH、BB 和 SA 的细分市场 2(“老和成熟”)的市场份额有所下降。新啤酒品牌在“年轻快乐”人群中占有 4.10%的市场份额,在“老年成熟”人群中占有 3.26%的市场份额,这使得瞄准细分市场 1 比细分市场 2 的利润略高。
此外,由于这一部分有较高的平均收入和较高的平均每周消费,这是一个更好的选择给定的两个部分。由于数据集中男性数量明显多于女性,因此上述分析可能更适用于男性。因此,该公司可以将目标锁定为“年轻快乐的男性”,年龄 36 岁,年收入 56-57 万美元,平均每周消费 10 瓶啤酒。
关于我们
在 LinkedIn 上找到我们,地址是www.linkedin.com/in/devashis…和www.linkedin.com/in/vikramde…
参考
Orme,B. (2010 年)。解释联合分析的结果。在 B. Orme,联合分析入门:产品设计和定价研究策略(第 77-88 页)。美国威斯康星州麦迪逊:研究出版有限责任公司。可从这里获得:https://sawtooth software . com/resources/books/getting-started-with-combint-analysis
PPT 实验室。(2014 年 2 月 25 日)。*为什么消费者不买:产品采纳心理学。*从 PPT 实验室检索:http://PPT Lab . com/PPT/Why-Consumers-don-Buy-The-Psychology-of-The-New-Product-Adoption-16
Qualtrics。(2018).什么是联合分析?联合类型&何时使用。2018 年 11 月 5 日检索,来自 qual trics:https://www . qual trics . com/experience-management/research/types-of-connect/
维基百科。(2018 年 10 月 24 日)。联合分析。2018 年 11 月 9 日检索,来自维基百科,免费百科:en.wikipedia.org/wiki/Conjoi…
使用数据分析来预测、检测和监测慢性自身免疫性疾病
根据美国自身免疫性相关疾病协会的数据,自身免疫性疾病是美国最流行的疾病之一,影响着大约 5000 万美国人,即 20%的人口。在研究人员已经确定的 80-100 种不同类型的自身免疫性疾病中,每年的直接医疗费用总计约为1000 亿美元。
从这个角度来看,癌症相关医疗保健的支出实际上更低——根据美国癌症协会的估计,2015 年美国花费了大约 802 亿美元。
众所周知,医疗保健支出在美国经济中发挥着巨大作用,根据医疗保险和医疗补助服务中心的数据,2016 年医疗保健支出达到 3.3 万亿美元。根据 Express Scripts 的 2017 年药物趋势报告,成本只会上升,特别是治疗许多自身免疫疾病所需的专业药物,这些药物占药房福利总支出的 40.8%。
如何解决这些成本?预测和说明性分析的时代已经到来,许多医疗保健领域的趋势表明,当机器学习和人工智能(AI)用于挖掘大型数据集以获得模式,从而实现更快、更准确的决策和更好的结果时,可以产生价值。比如现在有一个 AI 平台,可以利用代谢标志物诊断寨卡病毒等疾病。同样,根据该公司的 2017 年药物趋势报告,Express Scripts 的 SafeGuardRx 正在使用分析来降低处方药成本,使计划节省 3.4 亿美元。以同样的方式,我参与了构建 IQuity 的技术,该技术使用机器学习来通过血液测试检测自身免疫性疾病。
医疗保健分析为医疗专业人员提供了新的信息,这些信息由知识渊博的数据科学家进行处理和验证,以确定准确的诊断和最佳的治疗计划。未来更有希望,因为预测和说明性分析提供了预测和监控疾病的能力,而不仅仅是检测疾病。分析的信息可以从索赔数据、电子病历(EMR)甚至实时健康源(如 Fitbits 和监控体重减轻和睡眠模式的移动应用程序)中收集,从而提供比以往任何时候都更全面的患者视图。
机器学习和人工智能管道可以分析并不断从这些数据源中学习。这些工具可用于获得关于特定患者群体的见解,融入性别、地理、社会经济或生活方式数据等因素,以确定即将被诊断为慢性疾病的患者、被误诊的患者以及被诊断患有疾病的患者的管理效率。
自动化机器学习技术的最新进展使其能够在诊断疾病时加快速度,确定治疗何时有效,何时无效,影响护理提供的监控方式,并优化医疗保健的支付方式,从而共同提高患者生活的质量和长度。它还将降低整个医疗保健连续体的成本:那些面临医疗保健费用风险的人(如自我保险的雇主和付款人)和越来越多地不得不自掏腰包支付自己医疗保健费用的病人。
作为这项技术威力的一个例子,让我们来看看这种方法如何应用于多发性硬化症(MS)等自身免疫性疾病患者的整个诊断和治疗过程。
预测
我们公司最近进行了一项试点研究,分析了纽约 2000 万人的医疗保健索赔。该方法包含 40 亿个数据点,专注于多发性硬化症,预测准确率超过 90 %,在传统方法(包括核磁共振成像、脊椎穿刺和进一步监测症状的等待期)最终结束之前,该患者群体中的个体多发性硬化症发作至少八个月。
尽早了解哪些患者将被诊断为多发性硬化症对所有利益相关者都有好处:
- 提供者可以利用这些信息进行早期、准确的诊断,从而加快治疗速度,减轻这种疾病造成的长期损害。
- 支付者——包括自我保险的雇主和商业保险公司,两者都有成本风险——可以从提供者早期行动中受益,以减轻疾病的严重程度并识别误诊,帮助控制特殊药品成本。
- 拥有更深入信息的护理管理团队可以通过微调护理计划、药物、疗法和其他资源来更好地管理高费用患者,以确保最佳结果。
- 最重要的是,这些信息可以防止患者在治疗过程中出现复发或其他不良事件,从而提高生活质量。患者的费用也将显著降低,因为费用通常在诊断之前就累积,并且在复发或不良事件发生时最大。
根据 MS 脑健康(第 30 页),MS 等疾病的早期检测可以在大脑出现不可逆损伤和并发症之前进行干预。因此,使用数据分析来预测患者的健康状况并相应地根据数据采取行动,可以改善患者的整体健康状况,降低疾病的严重程度,并减少患者一生中的身体损伤。
检测
在我们针对多发性硬化症的试点研究中,我们的团队能够识别出被正确诊断的患者以及被误诊的患者。误诊在患有自身免疫性疾病的患者中并不罕见,因为大约 100 种不同疾病中的每一种都涉及免疫系统攻击身体,这可能导致类似的症状,尤其是在许多这些疾病的早期表现中。
全科医师通常不知道各种类型的自身免疫性疾病是如何相互关联的,而专家尽管知道这些关系,却无法获得能够明确指出自身免疫性疾病的工具,并且经常不得不依靠各种方法以“试错”方式或复杂的排除过程来间接识别自身免疫性疾病。根据美国自身免疫相关疾病协会的说法,“最初的症状往往是间歇性的,不确定的,直到疾病变得急性。”这使得正确诊断患者成为一项困难的任务,尤其是对于最初可能不会怀疑自身免疫并且没有接受过诊断和治疗这些疾病的专门培训的初级保健医生而言。
然而,从卫生保健数据集获得的见解可用于开发诊断平台,帮助提供者达成最终诊断。最初,通过将基因组数据与机器学习技术结合起来,我们公司能够创建算法来分析患者的 RNA 基因表达模式,以确定它们是否符合特定的疾病。我们能够针对各种自身免疫性疾病和相关疾病(包括多发性硬化症和纤维肌痛)修改这项技术,以便为提供者提供关于患者是否患有该疾病的明确答案。
我们的分析平台通过将相同的技术、流程和专业知识应用于更大的人口级数据集,将这一成就向前推进了一步。这使我们能够进一步增强我们的预测能力,仅使用数据在大量患者群体中识别自身免疫性和相关疾病,包括共病。与需要血液样本的基因组测试不同,我们的人口级分析平台能够在患者同意的情况下,通过保险索赔信息、临床观察或电子健康记录中记录的测试结果,以及允许我们收集患者及其环境的完整视图的其他公共或私人数据元素,使用归属于每个患者的数据来预测疾病。将机器学习应用于现有数据,不仅可以检测,还可以预测这些疾病的存在,这为早期治疗和改善结果带来了巨大的希望。
监控
来自多个数据集的见解可用于监测诊断后的患者。预测分析可以确定自身免疫性疾病患者何时可能发病,病情是变好还是变坏,以及患者对特定治疗方案的反应,所有这些都可以为未来的治疗计划决策提供信息,以及如何调整这些决策以确保最佳结果和高总体患者生活质量。
监测患者还可以为护理管理团队提供洞察力,以确定导致更差结果的特征。例如,由于各种原因,药物依从性对于患有自身免疫性疾病的患者来说是一个重大问题,包括特殊药物的成本障碍、订购或获得某些药物的障碍以及患者不想忍受的治疗的常见副作用。当患者不遵循他们的护理提供者的处方药物治疗计划时,治疗通常更加困难和昂贵。
我们的分析策略可以监控这些患者是否有可能降低药物依从性,并为护理人员提供一个改变治疗计划或让患者接受与降低依从性相关的陷阱教育的机会,最终为所有相关利益方带来更好的结果和成本节约。
将所有这些放在一起
美国国立卫生研究院(NIH) 自身免疫疾病研究计划将自身免疫研究称为“最有希望的新发现领域之一”,基于过去十年中取得的创新。在预测分析和各种可用患者数据集的帮助下,我们可以以超乎想象的速度做出这些发现,改善患者的生活,同时降低美国慢性病患者的直接护理成本
或许医疗保健数据分析以及人工智能和机器学习的力量最棒的部分是,像我们正在开发的那些技术,并不局限于任何特定类别的疾病。这种方法可以应用于任何疾病,这种方法改善甚至挽救生命的潜力是不可估量的。
【Chase Spurlock 博士是 IQuity 的首席执行官和联合创始人,IQuity 是一家位于纳什维尔的数据科学公司,使用基因组和专有医疗保健数据集来预测、检测和监测慢性病。更多信息,请访问。
利用数据科学造福社会
在混乱的代码和无情的技术浪潮中,我们很容易忽略我们工作的更大目标。
虽然我们都有不同的动机,但我相信我们都渴望影响我们的工作,并以某种方式做出有意义的贡献。随着我们不断学习和职业发展,我们也在寻求理解如何运用我们的技能进行创造性和批判性思考,以解决现实生活中的问题。
数据科学作为一个领域,往往会被太多的流行语(“AI!”“深度学习!”“大数据!”)这涉及到我们能做什么,而没有太多关于为什么我们会首先这么做。这是一个不断发展的领域,潜力巨大,但我认为改变叙述方式很重要。是的,机器学习,但是为什么呢?是的,大数据,但是为了什么?
我们如何利用数据科学及其多功能工具来解决现实生活中的问题?对社会“好”有什么影响?技术进步和发展,数据变得更加丰富和有用。作为受益于这一势头的数据科学家,我们如何帮助世界其他地区迎头赶上?
由于这似乎是目前网上讨论的一个有限的话题,这里概述了一些可用的投稿途径。为了找到合适的贡献途径,未来的数据科学行善者当然需要更多的主动性,但这并不是不可能的。
面向社会的数据科学项目/组织的志愿者 一些面向社会的数据科学奖学金,通常与非营利组织和地方政府合作提供。这包括芝加哥大学的数据科学社会公益奖学金和 Thorn 创新实验室。这些研究金使人们能够更深入地了解通过应用数据和分析工具可以解决的无数问题。
DataKind 是一家数据科学组织,专门致力于社会公益,并提供各种志愿服务机会,无论是通过指导还是使用您的数据科学技能来帮助解决他们 DataCorps 项目中的一个社会问题。DataKind 还与许多非营利组织合作,举办类似的竞赛和黑客马拉松。
通过竞赛做出贡献 数据科学竞赛的主要目的地, Kaggle 举办了无数旨在测试您的数据科学技能的竞赛。其中一些比赛关注社会问题。
一个更新的、面向社会的竞赛平台, DrivenData 与各种组织合作。这些组织通常是非盈利性的,专注于具有现实影响的社会难题。
Some competitions currently being hosted by DrivenData
开发人员和数据科学家能够贡献解决方案来帮助解决这些问题。他们的解决方案将被合作组织所利用,这样他们就可以更有效地完成他们的使命。
其他组织偶尔也会举办以“做好事”为导向的其他数据科学竞赛和黑客马拉松。
考虑你所遇到的现实世界问题的解决方案 虽然在构思和提出问题时,竞争是有用的,但对于解决问题来说,竞争并不是完全必要的。一个足智多谋的数据科学家可以利用他们可用的数据,自己识别并努力解决社会公益问题。Gap Minder Foundation 是一个很好的数据资源,它提供统计数据来了解全球趋势。Gap Minder 强调客观性,而不是用情绪或戏剧模糊统计数据,以促进对我们世界的真正理解,以便我们能够更好地工作,使它变得更好。
Sample data produced by Gap Minder Foundation, demonstrating the relationship between life expectancy and country’s income level
Data for Democracy 是一个由电子志愿者组成的社区,他们构思并贡献自己的问题解决方案。任何人都可以做出贡献,一切都由社区主导,提交的解决方案有可能推动对各种问题的有效干预。
在你的专业工作中要深思熟虑 从私营部门到公共和非营利部门,数据科学职位在所有行业中都存在并不断涌现。在你的职业生涯中,有很多机会可以产生有意义的社会影响。在私营部门中,肯定有公司为更大的社会问题开发创新的解决方案。例如,医疗保健和其他以科学为导向的领域(见:气候变化)继续快速发展,其增长基本上是由数据和技术驱动的。深度学习和其他分析工具可以帮助改善健康诊断或空气污染解决方案等事情,这将对人口健康产生重大影响。
面向公众利益的组织也可以从事数据科学工作。各国政府开始认识到数据在了解其公民身份方面的重要性,特别是在实施有效的循证干预措施和政策方面的使用。
同样,非营利组织也继续需要数据科学家来帮助实现他们的使命。
在结束这一部分时,我不想忽略两个特别有趣的组织: Bayes Impact 和前面提到的 DataKind。像 DataKind 一样,Bayes Impact 是一个具有社会意识的数据科学组织,利用数据解决世界问题。Bayes Impact 与其他大型非营利组织合作,解决与健康、失业和司法相关的问题。这两个组织都为充实和进步的数据科学职业生涯提供了巨大的机会。
结论 作为数据科学家,我们有能力做重要的事情。我们拥有资源,尽管这些资源看起来可能有些混乱和难以理解,但我们确实有所作为。无论我们的道路通向何方,我相信我们努力成为有思想的公民和数据科学家是不可或缺的,要始终考虑我们的工作如何影响社会。
在日常生活中使用数据科学
我最近为我们社区组织了一次社交聚会。我们通过引入游戏和文化活动来组织这个特殊的聚会,并让达拉斯沃斯堡内的不同城市相互竞争一个总奖杯。由于我们有一个混合的聚会(保守派,自由派,在我们之外出生和长大的人,在美国出生和长大的人,孩子,18 到 50 岁的成年人),组织这个聚会并确保每个人的参与是一个挑战。最后结果是个好玩的活动(至少我是这么认为的!!),尽管中间下雨扫了兴。
聚会结束后不久,反对者们就开始对此议论纷纷。正如任何有着不同背景和品味的大群体一样,每个人都会有自己的看法。因此,我们发出了谷歌调查,以衡量满意度,以确保每个人的声音都被听到和衡量,而不是少数害群之马抹黑我们的努力。
作为一名组织者,衡量更广泛人群的总体满意度对我来说很重要,因此我决定利用我在数据科学、Python 和自然语言处理方面的技能来接受这一挑战..
技术背景
与任何数据科学项目一样,当我们处理结构化和非结构化数据时,大部分工作都花在组织数据、清理数据上。在仔细研究数据后,数据质量/特性工程工作包括以下 1)确保所有满意度度量都是整数(将字符串转换为整数,将 NaN 更改为 0 等)。) 2)删除所有特殊字符(/、@、。等等。)使用正则表达式 3)通过删除所有停用词并将所有词改为小写来清理数据
最后,没有足够的数据来对一些相关性指标得出有意义的结论。我很想使用 NaiveBayes 分类算法,但同样,没有太多的数据可供使用。
Python 库的详细信息 在这个项目中,我们计划衡量各种因素的满意度——总体满意度、与通信、食品、文化活动、体育等相关的满意度。这里是使用的各种 python 库
- 利用 pandas 数据帧读取 CSV 文件并进行数据转换(添加列、测量相关性等。)
- 使用 NLTK — FreqDist 和 NLTK 单词 tokenize 来统计在各种调查问题中使用最频繁的单词
- 使用 matplotlib.pyplot 绘制各种满意度指标的直方图、条形图
- 使用正则表达式( re 和 Lambda 来清理数据和进行转换
- 使用 TextBlob 使用极性测量情绪(积极或消极),使用主观性测量主观性
- 使用 WorldCloud 为非结构化数据生成单词云
- 使用 seaborn 库绘制相关矩阵热图,柱状图
结论 经过分析,我很高兴地得出结论,大多数人喜欢这个活动(满意度指标的综合直方图中,4 分和 5 分表示人们喜欢这个活动)。世界云有助于挖掘非结构化数据,了解人们最关心的是什么。显然,人们最关心食物(事后看来,这是显而易见的:) 所以我们能够科学地压制反对者的声音。
下面是我使用的代码片段和图表。完整的代码在我的 github 库—github.com/yasimk/
##词云表示食品、文化、体育、小吃、奖项和节目被提及最多
##下面的满意度矩阵综合了所有指标。如你所见,大多数分数在 4 或 5 分左右。这一结果证明这次活动是成功的
###还为每个满意度分数创建了单独的直方图(由于缺乏实际资料,此处仅显示总体满意度)
###情感分析的条形图如下所示。如你所见,结果显示没有因小数据集而产生负面情绪。一个丰富而庞大的数据集,如 Twitter 选举反馈,会告诉我们一个不同的故事。我期待着分析 2018 年 11 月中期选举的推特数据
参见下面相关矩阵的热图分析 ##总体满意度与男性体育赛事相关(0.59)。这是有道理的,因为喜欢运动的人是积极的类型,得分与总得分相关。 ##迎送家属满意度与颁奖和结案相关(0.71)。这很直观,因为颁奖典礼将所有团体(女士、男士和小孩)聚集在一起,因此我们为会员提供了见面和问候的机会
##体育赛事男性和女性的相关性最小(0.23),这是有道理的,因为我们分开举办赛事 ##体育赛事男性和见面问候家庭(0.26)的相关性不是那么大。这是有道理的,因为人们参加男性活动,他们不能花足够的时间见面和问候。
##我试图检查特定城市的这些指标,以检查是否有任何相关性。然而,没有足够的数据来得出结论
代码可以重新用于 Twitter 情绪分析或任何非结构化数据分析。
完整代码可在 GitHub—https://GitHub . com/yasi MK/NLP-opinion-analysis-python/blob/master/NLP _ opinion _ analysis _ social _ gathering . ipynb获得
希望您喜欢阅读关于如何在日常生活中使用数据科学的内容。你也可以每天利用数据科学的力量为你带来优势。如有任何问题或反馈,请给我留言。
利用数据科学实现营销效率的成倍增长
在随着技术的出现而改变的所有商业方面中,也许最深刻地受到影响的是营销的作用。营销人员可以简单地通过在杂志上刊登整版广告、在镇上张贴明亮的广告牌,甚至与迷人的名人签约拍电视广告来吸引顾客的日子已经一去不复返了。由于大量客户数据的可用性和数据科学工具的结合,今天的营销人员有能力比过去更加有效。建立对各种可能性的理解将极大地丰富任何营销人员的工具箱。
最根本的变化之一是客户细分观念的转变。我们现在生活在一个 【一个人的一部分】 的时代,每个顾客都是自己的一部分。公司和品牌对目标个人的理解要深刻得多,甚至可以说是亲密得多,这使他们能够个性化地对待每一位顾客。能够有效地做到这一点的第一步是建立对典型客户生命周期的理解。虽然客户生命周期可能有行业特定的细微差别,但大致代表如下:
Image 1: Phases of a Customer Lifecycle
红线代表典型客户将如何经历这些阶段。在获得客户后,他们的消费会随着品牌/产品的加入而增加。在经历“增长”阶段时,It 部门的支出会有一定程度的快速增长,直到客户脱离并走向流失时,支出才开始减少。
绿线是营销人员希望引导这类典型客户的途径,即理想客户生命周期。每个阶段都要求营销人员采取独特的方法来弥合红线和绿线之间的差距。
阶段 1:获取新客户
目标:确定正确的目标潜在客户。通过最有可能对每个人起作用的方式来锁定目标。
作为一个数据问题,获取可能是最棘手的。在这一阶段,你的目标客户尚未与你进行交易,因此还不属于你的数据生态系统。这极大地限制了你对他们的了解。幸运的是,人们可以使用数据库,有时是免费的,但通常是收费的。
一旦你有了可用的数据,就可以挖掘出最符合你的理想客户特征的目标。在这个阶段,由于你几乎没有关于实际购买行为的数据,你必须主要关注人口统计信息。令人欣慰的是,在大多数情况下,基本的人口统计数据能够相当准确地识别目标。人口统计数据可能包括大量参数,如性别、年龄、位置、婚姻状况、家庭规模、教育、职业等。
既然已经确定了目标客户,我们就可以进入第二个关键目标,即寻找目标客户的最佳方式。用更专业的术语来说——我们如何最大化“转化率”。同样,由于现阶段数据有限,人们将不得不依靠代理指标来设计收购活动。一个有效的替代方法是分析对以往收购活动的历史反应,看看哪些措施对微观群体有效。如果没有交易或行为数据,微观群体可能只需要通过人口统计学来定义。例如,如果在过去的某个周末,18-24 岁的男性学生通过外拨电话获得了最高的转化率,那么我们也可以将此用于潜在的营销活动。
阶段 2:新客户入职
目标:深入了解客户。还有,勾住他们,建立忠诚度。
从营销人员的角度来看,这可能是最关键的阶段。到现在为止,你已经成功地争取到了一个新客户,所以你已经迈出了第一步。他们现在需要培育和发展,以便相互关系变得富有成效。把它想象成第一次约会——如果你想有第二次、第三次和第四次约会(作为一名营销人员,你总是希望这样!),那么你最好确保在最初的交流中你把球打出了公园。
为了能够做到这一点,你首先需要了解客户。这可能包括人口统计方面的更多细节,但也包括其他内容,包括:
- 交易细节(Transactional Details):他们买了什么,花了多少钱,如何付款,他们是在网上购买还是在商店购买,等等。
- 行为参数:他们是否倾向于寻找折扣/便宜货,他们一起购买什么类型的商品,他们更喜欢在工作日还是周末购物,等等。
- 体验细节:他们是否谈论过他们的体验(例如在社交媒体上),是积极的还是消极的,他们最近是否与客户支持人员交谈过,等等。
通过捕捉人口统计、交易、购买行为和体验等所有这些方面的细节,营销人员将开始深入了解客户。除此之外,这种做法还有助于确定客户的“钱包大小”——类似于定量评估他们在你销售的产品类型上可能会花多少钱。你也可以开始初步了解是什么让他们这么做的——他们喜欢打折还是免费?他们是只为自己还是家人购买?他们通常买很多小东西还是去大采购?
虽然忠诚度计划本身是一个独立的话题,但有必要提及的是,在入职阶段,将客户注册到忠诚度平台可能非常有用——这不仅能够实现更丰富的数据采集,还有助于建立客户粘性——这是整个入职阶段的主要目标。
第三阶段:增长
目标:最大化每个客户的潜在收入。
市场营销人员最喜欢的客户生命周期阶段!客户已经进来了,他们已经尝试和测试,并喜欢他们所看到的,你们都很好地理解对方,一切都很好。他们会更频繁地购买更多的东西,从而增加他们在你身上的总支出。因此,这一阶段的挑战是,随着客户的成长,如何增加他们自己的支出。
为了实现这一点,营销人员专注于优化他们的营销活动,以便针对每个客户,他们能够击中所有正确的触发器。
Image 2: Getting it Right!
有许多分析方法可以用来设计活动。让我们来关注这样一种方法,它经常被使用并且被发现非常有效——聚类分析。前提很简单:
- 通过某种形式的聚类模型识别行为相似的客户,即构建聚类 DNA
Image 3: Identifying Different Clusters and Cluster DNA
- 将每个个体客户的 DNA 与其集群的 DNA 进行比较,并根据个体客户偏离集群行为的地方采取行动。
Image 4: Cluster DNA vs. Customer Behavior
也可以应用其他模型和方法,以便为每个客户确定正确的触发因素。事实上,一项活动的有效性是通过利用一整套分析技术而不是专注于任何一种方法来最大化的。
阶段 4:衰落和损耗
目的:识别客户流失的**【预警信号】**,并及时采取干预措施,重新吸引流失的客户。
生命周期的这个阶段经常得不到应有的关注,这很不幸。经常被忽视的事实是,重新获得一个失去的客户的成本几乎与获得一个新客户的成本一样高,而挽救一个逐渐消失的客户的成本要低得多。
早期预警信号可以通过多种方式表现出来,理想的目标应该是发出危险信号并进行干预。衰落信号的一些例子:
- 客户总支出下降
- 购买频率降低
- 减少客户购买的典型产品篮
- 负面客户体验
- 类似于过去流失的其他客户的行为
虽然最基本的营销用例仍然是关于获取客户、增加参与度和防止流失,但营销人员当然可以通过利用数据科学或人工智能驱动的应用程序来实现多个其他目标——情感分析、产品捆绑、定价优化、忠诚度分析等。举几个例子。
随着技术工具(如客户关系管理系统、忠诚度平台、活动管理工具、复杂的销售点系统等)的激增。)围绕客户接触点捕获丰富数据的可能性很大。这个数据是营销人员的金矿。使用它,结合强大的数据分析支持的战略,提供了大量的机会来激发组织内营销职能的效力。我们只是触及了表面——可能性是无限的!尤其是一旦机器学习驱动的人工智能应用开始成为营销人员工具包的主流。
利用数据科学帮助女性做出避孕选择
你或你认识的人是否曾花数小时担心什么样的避孕药最适合你,并想知道它们的副作用是什么?你是否浏览过无数的在线论坛,试图了解其他女性对避孕药的感受?我自己也经历过这种情况,所以在为期 4 周的洞察数据科学项目中,我决定开发一个工具来帮助女性做出这些明智的决定!我从波士顿洞察研究员和项目总监那里学到了很多,没有他们我不可能开发出这个应用!
我的 webapp 是为了做三件事而构建的:
- 根据其他女性使用的避孕方法,向女性推荐避孕方法
- 分析其他女性对每种避孕药的副作用的感受
- 显示与避孕药相关的最热门的话题
让我们来分解一下这三个部分。
第一步:建议避孕
我的目标是能够根据其他像她们一样的女性使用的避孕方法向她们推荐避孕方法。为了做到这一点,我使用了全国家庭增长调查中几年的数据。该调查是分批进行的,每一批都跨越 3-4 年的收集数据(2006 年至 2015 年)。这项全国性调查包含来自妇女的报告信息,包括她们的人口统计数据和她们当时使用的避孕药具。一旦我把每次调查的数据合并成一个熊猫的数据框架,我采取了一些步骤来清理它。
数据清理:
- 更改了避孕药的名称,以匹配不同批次的采集。例如,“植入”和“Nexplanon 和 Implanon”被简单地改为“植入”
- 删除各个字段中带有 NAs 的行
清理之后,我只剩下了大约 12000 名女性的数据。
探索性数据分析:
我决定从一些探索性的数据分析(EDA)开始。下面是一些图表,显示了每种避孕药具的使用者人数,以及按年龄组分列的每种避孕药具的直方图。
Number of Users of Each Contraceptive Type
Examples of Contraceptive Use by Age
显然,一些避孕药比其他的更受欢迎,使用更频繁,导致了阶层之间的不平衡。我们可以尝试在项目的建模部分解决这个问题。
特点:
一些特征包括年龄、种族、婚姻状况、伴侣数量等。我对我想要制造的工具想了很久,并且知道除非使用我的工具的妇女输入所有必要的信息,否则我将无法推荐避孕药,并且询问性伴侣的数量将会太具侵犯性。出于这个原因,我选择在我的模型中只包含三个特征:年龄、种族*和婚姻状况。因为有几种类型的婚姻状况(“分居”、“已婚”、“同居”、“丧偶”等)。),我将他们分为三个层次,概括了所有这些类型的关系——单身、已婚或恋爱中。此外,使用 sklearn 预处理对种族进行了一次性编码。
我们准备好做模特了!
*使用这个数据集的一个不幸的限制是只有三个种族——白人、黑人和西班牙裔。要么只有这些种族的妇女被包括在内,要么在调查的原始数据收集中妇女只有这三个种族可供选择。
建模:
最初,我试图创建一个模型,预测女性最有可能使用的避孕药,不管是哪种类型。然后,根据我的 Insight 技术顾问的一些有价值的反馈,我将避孕药分为两个小组——半永久性和非永久性——并为每个小组创建了两个模型。每个亚组有四种避孕药作为预测类,使用 sklearn 的模型选择将数据随机分为 80%的训练集和 20%的测试集。
由于这是一个多类分类问题,我从高斯朴素贝叶斯模型开始,而不是逻辑回归,后者往往在二元分类场景中做得更好。我决定在没有任何过采样或欠采样的情况下开始,看看基线模型会如何。
对于这两个亚组,GNB 模型比随机模型(0.60)具有稍高的准确性,在这种情况下,随机模型每次都会预测多数类(0.57)。然而,GNB 模型假设特征之间完全独立——在这里,我们知道年龄和婚姻状况肯定是相关的。为了考虑特征相关性,我使用的下一个模型是随机森林(RF),它的性能比 GNB (0.65)略好。我选择在产品中实现 RF,因为随着我们添加更多功能,它也可以轻松扩展。下面,你会看到一个半永久群体混淆矩阵的例子。
Confusion Matrix for Semi-permanent Contraceptives
显然,这些阶层是不平衡的。为了减轻这个问题,我使用了合成少数过采样(SMOTE from unbalanced-learn API imb learn;下图)来生成少数类中的一些数据点,以帮助更好地训练模型。SMOTE 通过基于少数类中的 k 邻居生成数据来工作。我考虑过对多数类进行欠采样,但意识到在我已经有限的数据集下,我将在更少的数据上训练我的模型。正如所料,测试集的准确性下降了,召回率没有提高。
An example of SMOTE
您可能会问,为什么我使用准确性作为度量标准来衡量我的模型的性能?我希望这个模型的预测能够反映出女性使用避孕药的真实情况。与欺诈检测和识别乳腺癌等二元分类场景不同,我不希望我的模型针对特定类别的精确度或召回率进行优化。在这种情况下,模型的准确性最好地捕捉了所有类的整体性能。因为这是我的目标,我选择保持我的原始随机森林模型,没有任何过采样。
此外,我注意到测试集的精度(0.65)几乎与训练集的精度(0.66)完全相同,这表明我需要更多的预测功能来提高模型的精度。
前进:
将来,随着手头有更多的时间和资源,我会寻找其他可能更能预测避孕选择的数据来源,如地理上与诊所的距离、收入水平等。我收到的反馈是,纳入对患有某些疾病的人的排除可能是有用的——纳入这一点很好,但我必须小心地在建议工具和医疗建议之间取得平衡。我还可以花时间调整随机森林的额外超参数,如树的深度、一片树叶的最小样本等,这将是更有效的预测功能。
第二步:分析避孕药的副作用
为了了解女性对各种节育方式的感受,我使用 pushshift.io Reddit API 搜集了 r/BirthControl 两年的帖子。这导致了大约 21,000 个职位。从每个帖子的正文开始,我使用了各种工具来清理文本。
正文清理:
- 删除停用词。为了确保围绕避孕药的情绪保持准确,我保留了自然语言工具包(NLTK)语料库中英语停用词集中的“否定”词。
- 通过删除 URL 和其他不必要的字符,但保留标点符号来标准化文本。
Code snippet to Standardize Text
3.使用 NLTK 中的 sent_tokenize 将标记化(分隔)的句子彼此分开。
4.词干单词删除其后缀,以便相同的单词不会被计算多次(即药丸成为药丸)。
一旦我把所有的句子都分离出来,我特别想看看那些提到了上述预测模型中使用的八种避孕方式的句子。我提取了中只有提到上述避孕药的句子,并将其细分到各自的熊猫数据框架中(即所有提到“药丸”的句子都进入“药丸”数据框架)。为了使情感分析尽可能准确,我只提取了提到感兴趣的避孕药的句子。因此,一个提到避孕药和宫内节育器的句子不会出现在避孕药或宫内节育器的数据框架中。虽然这减少了我必须处理的数据量,但它尽可能准确地分析了每个句子的情绪。
提取副作用提及:
我根据 FDA 网站上列出的潜在副作用,以及女性向我提到的其他副作用,列出了一个清单。使用这个列表,我创建了一个新的熊猫数据框架,包括每个句子以及是否提到了特定的副作用(1 或 0)。你可以把这想象成一个定制的“词汇袋”模型,计算某个副作用在某个关于避孕药的句子中被提及的次数。
情感分析:
我将 VADER(效价感知词典和情感推理器)包中的 NLTK 情感强度分析器(SIA)应用于每个句子。这种情绪分析器已经过社交媒体数据的预训练,并使用基于词典的方法,不仅考虑情绪的类型(消极或积极),还通过“极性得分”考虑所表达的情绪的强度。这里有一篇关于这个 SIA 是如何建造的以及它是如何运作的文章。
下面是代码和结果数据集的示例。
我能够:
- 相对于所有提及特定避孕药的句子,计算副作用提及的频率
- 对于每种避孕药,将“极性得分”乘以句子中提到的特定副作用。
这导致了我的最终数据框架,如下:
由此,我能够在 Dash 中使用 Plotly 构建我的应用程序的第二部分。
Screenshot of Side-Effect Portion of WebApp
验证 VADER
Insight 项目的一位主管给了我宝贵的反馈,说我的情感分析器没有经过验证是没有用的。他建议我让和其他洞察力研究员看着同样的句子,并给它们打分,要么肯定,要么否定,要么中立。为此,我首先将 VADER 的极性得分分成三个子集:
- 极性得分> 0.1 = 1(正)
- 极性得分< 0.1 = -1(负)
- 极性得分在-0.1 和 0.1 之间= 0(中性)
基于 VADER 和其他洞察研究员对大约 200 个句子的评价,我能够开发出下面的困惑矩阵:
显然,VADER 在将一个句子正确分类为积极、消极或中性方面做得比机会稍好,这对于以前不知道其他女性对每种避孕药及其副作用的感受的女性来说仍然是有价值的。
向前发展:
我能想到几种方法来改进产品的这一部分:
- 使用命名实体识别的形式来识别副作用,以全面了解所有经历的副作用。
- 从头开始构建情感强度分析器。首先,要让女性给句子贴上积极、消极或中性的标签。有了足够数量的这些带标签的句子,我可以使用分类模型训练一个基本的情感分析器。
步骤 3:提供相关的建议帖子
虽然该产品的前两个方面让女性了解了什么样的避孕药可能对她们有效,以及其他女性的感受,但她们可能仍会在网上论坛上花费数小时,试图更好地了解其他女性对这些避孕药的看法。为了避免这种情况,我决定使用主题建模来提供一些相关的 Reddit 帖子,供女性在应用程序中阅读。
主题建模是如何工作的?
主题建模是一种统计方法,用于发现文本语料库下的抽象“主题”。在这种情况下,特定主题建模技术可以使用 reddit 帖子内和所有 reddit 帖子之间的单词分布来创建主题,并将特定 reddit 帖子归属于特定主题。有一些很棒的文章描述主题建模技术(这里的、这里的和这里的),但是我将简要描述我选择的一个——潜在狄利克雷分配(LDA)。
LDA 是一个概率模型,本质上意味着它给出了一个事件的概率分布。相反,确定性模型会给出事件的单一结果。在主题建模的情况下,LDA 由两个矩阵组成(如下所示)——在主题中选择单词的概率,以及在 reddit 帖子中选择主题的概率。它使用一个词在文章中出现的频率来创建主题。
例如,假设我有三篇非常简单的文章:
- “狗猫香蕉”
- “香蕉香蕉香蕉”
- 《猫猫猫猫》
LDA 将记录单词在三篇文章中出现的概率,并基于这些分布创建主题。这里,主题 1 可以是“狗”,主题 2 可以是“猫”,主题 3 可以是“香蕉”。然后,LDA 会将帖子 1 分配为具有来自主题 1、2 或 3 的相等概率,而其他两个帖子几乎肯定分别来自主题 2 或主题 3。
用 Reddit 帖子实现 LDA
对于 webapp 的这一部分,我需要了解对于每种避孕药,女性中最流行的讨论话题是什么。此外,我需要显示与这个特定主题最相关的帖子。使用 LDA 帮助我提取了每种避孕药最受欢迎的话题,以及与该话题相关的前 3 篇帖子。步骤如下。
- 使用 sklearn 计数矢量器创建一个单词包模型
2.确定主题的数量(因为 LDA 本身不能自动这样做),并从 sklearn.decomposition 运行算法
3.显示生成的主题,指定帖子的数量
这让我可以在我的应用程序上显示来自 Reddit 的相关帖子:
虽然非负矩阵分解也是一个很好的主题建模工具,但当我尝试实现它时,它并没有在这个特定的上下文中产生可理解的主题。
主题建模的缺点:
不幸的是,使用主题建模有一些缺点。首先,你必须指定 k 个主题。我是怎么选择 10 作为题目数量的?老实说,我尝试了各种主题编号,10 产生的主题既不太宽泛也不太具体。第二,你必须给主题贴上标签——我从与宫内节育器相关的帖子中提取的最受欢迎的主题的一个例子是“只是月经来潮”。这在语义上没有什么意义,但我们可以看出它与月经的时间框架和痉挛的副作用有关。标签将帮助我们验证我们的主题建模是否正确地构建了主题并将帖子分组到这些主题中。
向前发展:
我很想在我的应用程序中建立一个反馈功能,允许女性标记主题,或对主题是否对她们有意义进行评级。
摘要
简而言之,我的希望是(在 4 周内)创建一个应用程序,它不仅可以向女性推荐避孕药,还可以分析其他女性对其副作用的看法,并为她们提供其他女性所说的相关信息。你可以点击查看整个 webapp 。我真的很高兴使用数据科学和机器学习来创建这样一个工具,在规模上,它可以帮助女性做出重要的决定。在创建这个 webapp 的过程中,我学到了很多东西,如果没有波士顿 Insight 研究员和项目主管的帮助,这是不可能的!!
如果您有任何问题或建议,请随时发表评论——我希望听到您的反馈!
用数据将用户推向你理想中的 UX
选择指标如何帮助弥合产品的现实 UX 和理想 UX 之间的差距。
产品设计通常是通过理想主义的视角来执行的。你的团队设计的用户界面和 UX 可能源于你脑海中的长期印象——用户如何看待你的产品并与之互动的乌托邦版本。如果你幸运的话,实际开发的版本将非常接近你的设想,尽管在这个过程中几乎总是要做出让步。(特别是关于 UX。)
尽管如此,你脑海中的形象仍在演变,以至于你会为你的产品的生产版本选定一个理想的 UX。无论是转化率、会话时长,还是其他形式的参与,你和你的团队都知道你的用户应该得到什么样的体验。
但是他们的经历并不完全是那样的。
介意差距
用户体验的现实往往与你和你的团队精心设计的理想版本不同。换句话说, r UX(现实版)和 i UX(理想版)之间是有差距的。虽然这种差距的存在并不出人意料,但如果你不确定缩小差距的最佳方式,这种差距可能会令人沮丧、不安,甚至令人生畏。
一旦你意识到存在 UX 差距,对你和你的团队来说,采取一些步骤是很重要的:确定差距实际在哪里(稍后会有更多内容),如果可以的话,确定是什么导致了差距,并开始考虑不同的方法来缩小差距。
例如:
- 是否缺少一项产品功能来弥补这一差距?
- 我们需要考虑一个程序(人,而不是技术)来改变用户的行为吗?
- 如果是这样,我们是推他们…还是轻推他们…让他们做出我们想要的行为?
快速浏览一下上面的选项,你会发现功能开发的成本很高,把你的用户推进一个新的行为模式是有风险的。研究表明后者——轻推你的用户——可能是改变他们的行为并达到 i UX 的最有效方法。
点拨心理
轻推用户是什么意思?本质上,这意味着一点一点地改变他们的行为,这样随着时间的推移,他们会以不同的方式行事——希望对你的产品来说是一种更理想的方式。
关于推动行为的更多信息,请查阅理查德·塞勒和卡斯·桑斯坦的书《推动:改善关于健康、财富和幸福的决定》。
对于马尔科姆·格拉德威尔的眨眼和诺贝尔奖得主丹尼尔·卡内曼的思维快慢的粉丝来说,一个启示性的新…
www.amazon.com](www.amazon.com/Nudge-Impro…)
你希望他们做出的行为重定向可以来自不同的、或许更有限的选择,这些选择将他们引导到更一致的行为模式中,向他们提供或展示一个隐喻性的胡萝卜,将他们(和他们的行为)引向特定的方向,甚至实施更一致的沟通策略,包括入站和出站渠道。
(微调策略的列表是无穷无尽的,对你来说最好的策略都取决于你的产品和你试图缩小的差距。)
试图用一次产品变化来打动你的用户是不明智的。相反,最好的办法可能是一点一点地把他们推向你心目中的理想 UX。
以数据为导向
不管你选择什么样的策略来弥补你的产品的 UX 差距,最好用数据来确定差距到底在哪里。您和您的团队可能对正在发生的事情有很好的感觉,但是使用可量化的指标将确保您将精力集中在正确的地方。
您的 i UX KPI 可能足以弥补您产品 UX 的差距,也可能不足。许多企业家将虚荣心指标视为 KPI,但像“每日活跃用户”或“流失率”这样的东西可能过于宽泛,无法帮助缩小 UX 差距。
你的团队设计的用户界面和 UX 可能源于你脑海中的长期印象——用户如何看待你的产品并与之互动的乌托邦版本。
使用数据来弥补 UX 差距的关键是使用描述你的产品的清晰度指标。清晰度指标是构成顶级虚荣心指标的运营指标。像你的产品每天实际使用的分钟数这样的事情更能说明 UX 差距,可能会给你更多切实的 UX 互动来关注。(又名:哪里轻推你的用户。)
(如果您还没有产品的 i UX 的 KPI,请先建立这些 KPI。这可能需要一些市场研究,以确保您与其他类似产品保持一致,但是拥有良好的清晰性指标 KPI 将允许您测量 UX 差距,并监控您努力缩小差距的有效性)
一旦你使用了正确的清晰度指标来监控 UX 差距,你就可以开始开发一些方法来推动你的用户,从而消除 UX 差距。希望用户每天使用你的产品的时间更长吗?首先要想出种方法来推动他们,让他们多增加 5%的时间。这些推动努力的累积效应——如果集中在正确的地方——将会缩小你的产品的 UX 差距。
有形的外卖
这里有 5 个使用数据将你的用户从你产品的 r UX(现实版)推向 i UX(理想版)的关键。这些要点将帮助您的团队确定工作的优先顺序,并弥补您产品中的 UX 差距:
- 深入表面,定义你的清晰度指标
使用数据识别和弥补产品 UX 差距的真正价值在于产品的清晰度指标。关于清晰度度量值的更多信息,这里有一篇很棒的文章。
- 跟踪测量这些指标所需的数据
为您的产品建立和/或确保正确的清晰度 KPI,并确认您的生产数据库或 SaaS 包含您测量产品 UX 细节所需的数据。
- 优先考虑你的努力
您可能有不止一个 UX 差距需要解决,确定哪个更重要将有助于您确定团队工作的优先级。要决定哪一个是最重要的,比较你的团队定性的想法和通过数据揭示的最大差距。如果关闭/修复,哪个差距会产生最大的影响?(如果“最大的”差距是相对低影响的特性,那么它可能不是最佳选择。)
- 调查你的用户以证实你在数据中看到的
用户研究对产品开发至关重要,虽然它通常发生在产品发布之前,但在产品发布后很长时间内使用相同的程序来证实您通过数据看到的差距非常有用。顺便说一下, 用户研究有多种形式——不仅仅是调查等。
- 选择正确的时间框架
当你开始解决你的产品的 UX 差距时,在一个现实的时间框架内监控有效性是很重要的。这似乎是显而易见的,但很容易太快或太频繁地深入细节。在弥补产品的 UX 缺口时,森林往往比树木更重要。
使用数据可视化快速回答业务问题
学习如何交流从数据中获得的洞察力是你能拥有的最重要的技能之一。通常,交流数据信息的最引人注目的方式是可视化。但是,构建伟大的数据可视化的关键是让它们能够回答你想要回答的问题。
例如,假设我开了一个博客,我想知道我哪个月的流量最大。
我可以使用一个汇总表,基本上列出了每月的流量和数量。就像下面的表格,但是它的问题是,它不能帮助我很容易地比较每个月的流量。
但是这次绘制同样的数据,把它扩展到 12 个月的流量的条形图或帕累托图。显而易见,11 月和 7 月的流量最高。而一月最少。
Bar Chart
Pareto Chart
条形图或帕累托图最好地捕捉了每月的流量分布,尤其是帕累托图。帕累托图按照流量从高到低的顺序排列月份。每个条形代表特定月份的流量。
如果我想知道流量是否随着时间的推移而增加,最好的图表是折线图。
Line Chart
这里显示的是相同的信息,但更容易看到的是,从条形变为线状,整体流量似乎在增加。如果我有多年的数据,折线图也将有助于确定特定月份的流量是高于还是低于其他月份。也许一月总是低的,而十一月总是比一年中的其他月份高。
让我们试着回答更多的商业问题
我有多年的数据,我想知道访问者数量的分布情况,例如:
- 一个月内有超过 200 名访客的频率是多少?
- 最常见的访客人数是多少?
Histogram
无论是从条形图还是折线图来看,这都很难判断。这两个问题都不是为了理解时间成分。我对具体的计数感兴趣。
访问者数量的柱状图有助于更好地了解一个月内的典型访问者数量。条形图的高度告诉我一定数量的访问者出现的频率。
在博客上看到 500 个访问者的情况很少见吗?我能很快看出 500 是很少的。我也能看到总有 200 多的访客,但很少有超过 1167 人的。
最常见的访客数量在 321 到 442 之间。在条形图或帕累托图上很难看到这些观察结果。
同样,由于数据中的时间成分,折线图可能是最好的,但它最终取决于您想要传达的信息。用同样的数据,我只是找到了三种呈现数据的方式。可视化数据的正确方式是最能帮助你回答问题的方式。
分类变量
当观察一段时间内的变量或比较两个定量变量时,用于可视化这些情况的选择被标准化为折线图和散点图。然而,当您将分类变量引入可视化时,更多的选项现在变得可用。以及如何可视化分类变量之间的关系以及分类变量和定量变量之间的关系。
例如,我想知道三个地方的顾客最喜欢的可口可乐产品。为了比较两个分类变量,我可能会使用类似并排条形图的东西,显示一个类别的分组。在这种情况下,芬达、雪碧和可口可乐按照另一个变量的颜色分组,在这种情况下是三个位置。我可以快速识别每个地点最喜欢的汽水。中环芬达,西区雪碧,东区可乐。
Side-by-Side bar chart
如果我有两个以上的变量,比如我想查看不同产品在一段时间内的销售额,这里我有三个变量:销售额、时间和产品。我可能会从折线图开始,因为我在和时间打交道。然后,我可以将每种产品分成不同的系列。给线条着色并添加图例以提供产品名称。现在,我可以看到哪种产品表现良好,这可以帮助我做出更多针对具体产品的决策,而不是只看总体销售额。
Line Chart
在这种情况下,我还可以使用基本堆积面积图或 100%堆积面积图。当您想要显示部分到整体关系随时间的变化时,堆积面积图很有意义。视觉效果提供了基本相同的信息,但在 100%堆积面积图中,每种产品都以占总销售额的比例显示。
与基本堆积面积图不同,100%堆积图结果显示总销售额,以及每个产品线对总销售额的贡献。
Basic Stacked Area Chart
100% Stacked Area Chart
另一种方法是使用按年份排列的堆叠条形图。每个产品在条中都有一种颜色,条的高度就是销售额。
Stack Bar Chart
通过折线图、堆积折线图和堆积条形图,让我们来看看使用每个图表可以轻松回答的一些问题。
问题
- 哪种产品 1-7 月销量增长最快?
这在其他一些图中很难看到,但在折线图中更容易看到。产品 3 和其他产品一样起步缓慢,但在 4 月至 7 月间有所增长。
2.产品 1 在哪一个月的销售额超过 50%?
从百分比堆积面积图中,您可以看到产品 1 在二月份的销售额超过了 50%。同样,选择图表要基于它对你回答问题的帮助程度。
3.总销量曾经超过 100 台吗?
是的在 11 月!基本堆积面积图或堆积条形图都适合这个问题。因为它们清楚地显示了这三种产品每个月的总销售额。
总之,构建信息丰富的数据可视化在很大程度上取决于您对现有绘图类型的理解以及您试图强调的洞察力。您使用的可视化方式还取决于您正在处理的数据类型,以及您希望在单个绘图中查看的数据集中有多少列。
利用深度学习克隆驾驶行为
在我关于自动驾驶汽车和相关的 Udacity Nano degree 项目的上一篇帖子中,我写的是深度神经网络在交通标志分类中的应用。这一次,我将使用深度神经网络方法来模仿人类的驾驶行为(在这种特殊情况下,在模拟器中驾驶汽车)。
项目目标
这里的总体思路是通过在模拟器中驾驶汽车来收集训练数据,然后用这些数据训练深度神经网络,最后让汽车由深度神经网络生成的模型来驾驶。
You can find the simulator git repo here
训练数据分析
Udacity 已经提供了一些预先录制的圈数,但我决定自己用模拟器玩一玩。所以我在赛道的每个方向记录了 5 圈。为了避免深度神经网络偏向于转向道路的左侧,两个方向都是需要的。
该记录产生了 36 534 个捕获的图像。图像包含从汽车上的三个摄像头捕获的数据:左,中,右。
Captured images from left, center and right camera from the car
为了训练的目的,我只使用了中央摄像头,这足以获得非常好的最终效果。为了使模型更通用,建议对汽车使用所有三个摄像机,以便能够更好地处理返回轨道中心的场景。
当使用多个摄像机时,重要的是要记住,左右摄像机的转向角需要用一个常数进行适当调整。
Multiple camera capturing
训练数据还包含 CSV 文件,该文件包含带有时间戳的图像捕获以及转向角、油门、刹车和速度。
CSV file contains the metadata from the training data
由于训练数据包含两个轨道方向上的圈数,因此转向角没有偏差:
80%的数据用于培训,20%用于验证。所有的训练数据都可以在这里找到。
数据扩充和预处理
为了进一步增加训练数据集的大小,我将每张图像都绕水平轴翻转。
在这种情况下,图像的预处理是在模型本身中完成的,因为与 CPU 相比,在 GPU 上完成的成本更低。我从每张图片的顶部裁剪了 50 个像素,从底部裁剪了 20 个像素,以去除图片中不必要的噪声(汽车的前部,天空,树木等)。).
模型架构
我实现了来自英伟达论文的深度神经网络架构:自动驾驶汽车的端到端学习在 Keras 后台运行 TensorFlow 。这是一篇优秀的论文,如果你更了解这种深度神经网络在现实世界中的应用,我建议你通读一下。
以下是 NVidia 在现实生活中基于上面的架构运行相同模型的汽车的短视频:
深度神经网络本身获取输入图像(160 x 320 x 3)。在最开始,它包含标准化和裁剪层。接着是 3 个卷积层,步长为 2x2,内核为 5x5。随后是额外的 2 个无跨距卷积层和 3×3 内核。卷积层连接到三个完全连接的层,从而产生一个输出控制值。用 RELU 函数在所有网络层之间引入非线性。ADAM 用于我们的学习率。
Deep neural network architecure used from NVidia’s paper
辍学层是没有必要的,因为我没有注意到在培训期间任何重大的过度拟合。
培训和最终结果
训练在配备了 GPU 的 Amazon EC2 实例上进行。训练完成后,赛车能够自己完成赛道:
结论
这绝对是本课程迄今为止最有趣的项目。我的计划是将从这个项目中学到的知识应用到现实生活中的遥控汽车上,并在我的公寓里建造一个小型赛车道,在那里我可以训练它自动驾驶。
项目可以在我的 Github repo 上找到:
行为克隆-P3-uda city 行为克隆项目的启动文件
github.com](github.com/bdjukic/Car…)
使用深度学习来估计咖啡收成
我前阵子写过一篇旧文章,讲的是用 OpenCV 检测成熟的水果。虽然简单的颜色检测器是计算机视觉的有趣入门,但有时我们的问题需要更多的复杂性和前瞻性思维。因此,深度学习允许我们开发一种健壮的方法来解决计算机视觉中的大多数问题。我将在本文中使用的算法称为 Mask R-CNN。
Kauai Coffee Company. Source: Hawaii Coffee Association
全球的咖啡果园在很大程度上依赖于手工计算树枝上成熟和未成熟咖啡果的数量,以估计收获时间。根据这个简单的指标,需要大量的专业知识来对何时收割做出更快、更有根据的估计。错误可能会使公司在某一特定领域失去丰收。收获少,钱少。
How many cherries can you count? Now, how long should we wait until harvest?
培训计算机
如果你不熟悉机器学习,对于这种类型的问题,你只需要知道一件事。没有它,我们将不得不手工编码这些咖啡果的每一个特征,以便被程序识别。无论你怎么说,都有太多的代码要写,而且咖啡果不能近似为绿色的圆圈(我也绝对没有这个想法)。
因此,我们采取以下方法:
- 给我们感兴趣的物体拍大约 100 张照片
- 手绘标签/注释~30 张图片
- 把图像输入我们的网络
- 评估模型
- 重复这个过程,直到我们能够以 90%以上的准确率检测到我们的目标。
- 额外收获:让我们的模特给我们贴上新图片标签
屏蔽 R-CNN
这篇文章的目的是面向这种算法的应用,所以如果你对如何网络功能感兴趣,请查阅原始论文。简单来说,这个算法返回对象的位置和组成它的像素。非常适合能够:
- 确定咖啡果的位置/数量(边界框)
- 确定每个咖啡果的颜色(图像分割)。
Network architecture. Source: arxiv.org/abs/1703.06…
VGG 图像注释器(VIA) 可能是我发现的最好的多边形对象注释工具。他们更新了一些功能来保存项目,加载以前的注释等。在这种情况下,注释对象需要长的时间。在这个阶段很容易陷入不确定性:我真的应该注释所有这些图片吗?通常需要这么长时间吗?如果不行呢?
是的。绝对的。忍忍吧。我们打败了苏联,登上了月球,却不知道它会成功。回到注释咖啡果。
This really is the hardest part of the process.
花了大约 4 个小时来注释所有这些图片,这个方法必须有效。对吗?最简单的测试方法是通过迁移学习和其他人对算法的实现。如果需要,可以对模型进行微调和调整。不要感到羞耻。
马特波特的人们有很好的基础可以利用。这里是 github 回购。
结果呢
在与 Amazon Web Services 和包依赖问题进行了无休止的斗争之后,最终结果如下:
Trained model in the wild.
This is art.
一点也不差,尤其是考虑到它工作所需的图片数量很少。下一步将是通过在类似于其应用的设置中拍摄更多照片来完善该模型,并最终将其部署用于一般用途。
如果你喜欢这篇文章,一定要关注我,了解机器学习和计算机视觉在农业中的更多应用。如果您有任何问题,请留言或发电子邮件至 jamesthesken@gmail.com 给我。
—詹姆斯
利用深度学习生成攻击性车牌
将丰富的语料库与 R
如果你已经在互联网上呆了足够长的时间,你就会看到由深度学习算法生成的优质内容。这包括在乐队名称、视频游戏名称和神奇宝贝上训练的算法。作为一名想要跟上该领域现代趋势的数据科学家,我认为没有比找到一个有趣的主题来生成文本更好的方式来学习如何使用深度学习。有了这样做的愿望后,我等了一年才找到合适的数据集来做这件事,
我偶然发现了亚利桑那州禁止牌照的名单。这份名单包含了所有的个性化牌照,人们要求,但被亚利桑那州汽车部门拒绝。这个数据集包含超过 30,000 个车牌,这为深度学习算法提供了一组很好的文本。我将数据作为文本包含在我的 GitHub 库中,这样其他人就可以选择使用它。不幸的是,数据来自 2012 年,但我有一个活动的公共记录请求亚利桑那州更新名单。我强烈建议你看一看,它非常有趣。
下一步是实际了解深度学习是如何工作的,并编写代码。因为我的大部分工作都是在 R 中完成的,所以我希望使用它,谢天谢地,Rstudio 有一个叫“keras”的包,它使这变得很容易。虽然这个工具本身很容易使用,但我不得不通过仔细阅读互联网,自己拼凑出一个关于深度学习的介绍。现在回想起来,我大概应该只买一本书。这篇文章的其余部分是我对我所学到的东西的总结,以便其他人可以阅读它,并找出如何生成他们自己的有趣文本。如果你想看我的实际代码,请查看我的 GitHub 库。
深度学习如何用于文本生成的口语化介绍
当人们谈论使用深度学习来生成文本时,他们几乎总是指的是递归神经网络(RNN)。这是一种特殊形式的人工神经网络,可以很好地处理数据点序列(例如,书中的单词序列)。忽略这背后的数学,想法是给定一个单词序列,例如“这是一个单词序列的无聊例子,”我们可以训练一个模型,根据序列中的单词预测序列中的单词(以及单词的顺序)。因此,在选择下一个单词之前,我们选择少量的前一个单词来考虑。如果我们之前的单词数是 3,那么我们的小序列将创建一个看起来像这样的数据集:
由于递归神经网络不能处理单词,而是需要数字,所以我们任意将每个单词分配给一个数字。例如,a = 1,boring = 2,this = 7,等等。那么我们的数据就变成了:
但不幸的是,即使这样,对 RNN 来说还是太复杂了。我们需要通过将每个数字转换成一个二进制向量来将它表示为一个分类变量。例如,我们可以将 7 个单词中的第 5 个编码为长度为 7 的二进制向量,只有第 5 个元素为 1。(0,0,0,0,1,0,0).如果我们对整个数据集这样做,我们会得到:
这是 RNN 可以研究的数据。该模型将适合它,然后我们可以给它一组前三个单词,让它猜下一个单词是什么。由于有许多可能的下一个单词,最终发生的是模型产生所有可能单词的组合,这些单词具有不同的权重,加起来等于 1。这些代表每个单词成为下一个单词的概率:
An example of a prediction generated from an RNN
为了让生成一个单词序列,我们选择三个单词作为起点,然后从模型预测的每个单词的概率中抽取第四个单词。例如,在上面的示例数据中,如果我们使用预测的下一个单词分布作为一组可能单词的权重,我们可以从样本中提取。如果我们画出与单词“boring”相对应的第二个元素,它将是序列中的下一个单词。然后,我们将它放入序列中,并使用序列中最近的元素来生成第五个单词,依此类推。
设置牌照数据
对于牌照数据,我们必须对这个主要思想进行一些修改。
- 这里的“单词”是指盘子里的字母和数字(不是完整的单词)。
- 由于车牌可能不是全长的,我们想知道何时停止它。因此,我们在每个牌照上附加一个终止字符'+'。因此板块 ABC001 变成了 ABC001+。如果在生成新的牌照时,我们生成了符号“+”,这就意味着我们需要停止这个序列。
- 我们用于训练数据的序列是数据中每个平板的子序列。例如,如果 ABC001+在数据中,我们希望在(A → B,AB →C,ABC →0,…)上训练模型。因为每个训练数据序列的长度必须相同,所以我们在开头填充数据(******A → B,****AB →C, * * * * ABC→0,…)。我们从每个板中生成所有序列,并将它们放入一个大的训练集中。
对张量流使用 R 和 Keras
我最终使用了三种相互叠加的不同技术来运行这个模型。这些术语经常出现,所以最好能清楚地区分每一个:
- TensorFlow(基础技术):TensorFlow 是一组开源的库,用于运行深度学习算法。它非常强大,但是直接部署起来有点麻烦。
- Keras (Python API): Keras 是一个 Python 库,它使得 TensorFlow 更容易使用。它消除了设置和部署 TensorFlow 的所有麻烦,并真正使深度学习对 Python 用户可用。
- keras (R 包):这是 RStudio 的包,允许你在 R 中使用 keras 而不是 Python。这不是 Keras 本身,而是 Keras Python 库之上的一个包装器。好消息是它工作得非常好,遵循现代 R 编程原则,并且易于安装。坏消息是,它是一个包装上的包装,所以有时寻求帮助并不容易。但是据我所知,在 Python Keras 中可以做的任何事情在 R Keras 中也可以做。
通过遵循 keras 包的文本生成示例,我弄清楚了这些东西是如何工作的。我一行一行地运行他们的代码,以了解它是如何工作的,然后为我的车牌项目修改它。要让代码运行起来,你需要安装 TensorFlow 和 Python, Rstudio 包会帮助你。
他们的示例文本生成代码实际上只做了几件关键的事情:
- 加载示例文本数据并进行任何必要的格式化。在我的例子中,我需要添加上一节中的牌照修改。
- 创建单词序列以用作训练数据,并将它们格式化为三维数组 x。数组的维数是:数据来自哪个序列,我们引用序列中的哪个元素,以及哪个单词。元素 X[i,j,k] =1 如果序列 i 在第 j 个字中作为 k. 预测被存储在一个二维数组 y 中。
- 对数据运行 keras 模型。当指定一个模型时,你需要列出不同层的神经元来创建一个人工神经网络。老实说,我几乎不知道如何制定一个“好的”规范,所以对于我的代码,我使用了与 Rstudio 示例相同的规范。为神经网络选择层的艺术感觉是整个过程中最不清楚的部分,我希望了解更多。如果你是第一次尝试编写自己的深度学习代码,我建议借鉴正在解决类似问题的其他人的规范。
- 使用创建的模型生成单词,并从这些单词创建新的序列。
一旦我让模型工作了,我就把一堆随机生成的盘子扔到一个图像里。这个项目总共花了我大约 8 个小时,如果我的代码中没有一些一个接一个的错误,这个时间会更快。我对结果非常满意,并对整个过程的简单明了感到惊讶。如果我知道会这么容易,我几个月前就做了。如果你对深度学习感兴趣,我强烈建议你获取一个文本语料库,并尝试自己生成新文本。它教会了我很多关于这个过程的知识,我觉得自己更有能力将深度学习用于更高级的项目。
代码是 GitHub 上的,如果你对我做过的其他项目感兴趣,请查看推特混搭或我的 F#物联网按钮。
利用深度学习改进 FIFA 18 图形
Comparison of Cristiano Ronaldo’s face, with the left one from FIFA 18 and the right one generated by a Deep Neural Network.
游戏工作室花费数百万美元和数千个开发小时来设计游戏图形,试图使它们看起来尽可能接近现实。虽然图形在过去几年看起来非常逼真,但仍然很容易将它们与现实世界区分开来。然而,随着使用深度神经网络的图像处理领域取得的巨大进步,是时候我们可以利用它来改善图形,同时减少创建图形所需的工作了吗?
让我们试着用游戏 FIFA 18 来回答这个问题…
足球(即英式足球)是我最喜欢的运动,FIFA 成为我所有深度学习实验的自然选择。为了找出深度学习的最新发展是否可以帮助我回答我的问题,我试图专注于使用(in?)著名的 deepfakes 算法。它是一个深度神经网络,可以被训练来学习和生成极其逼真的人脸。我在这个项目中的重点在于从游戏中重新创建玩家的面孔,并改进他们,使他们看起来完全像真正的玩家。
注: 这里的 很好的解释了 deepfakes 算法是如何工作的。TL;博士版本:它可以使用自动编码器和卷积神经网络将视频中任何人的脸与其他任何人的脸交换。
收集培训数据
Unlike the game developers, I could collect all required data from Google search without having to trouble Ronaldo with any motion-capture fancy dress.
让我们先看看 FIFA 18 中设计最好的面孔之一,克里斯蒂亚诺罗纳尔多的面孔,看看我们是否可以改进它。为了收集 deepfakes 算法所需的数据,我只是从游戏中的即时重放选项中记录了玩家的面部。现在,我们想把这张脸换成 c 罗的真实面孔。为此,我从谷歌上下载了一堆图像,这些图像从不同的角度清晰地显示了他的脸。这就是我们开始模型培训过程所需要的全部内容。
模型架构和培训
deepfakes 算法涉及被称为自动编码器的深度神经网络的训练。这些网络用于无监督学习,并具有编码器和解码器,编码器可以将输入编码为称为“编码”的紧凑表示,解码器可以使用该编码来重建原始输入。这种架构迫使网络学习输入的底层分布,而不是简单地鹦鹉学舌般地重复输入。对于作为输入的图像,我们使用卷积网络作为编码器,使用去卷积网络作为解码器。这种结构被训练以最小化无监督学习的重建误差。
对于我们的例子,我们同时训练两个自动编码器网络。一个网络学会从 FIFA 18 图形重现罗纳尔多的脸。另一个网络学会了从罗纳尔多的真实照片中重建面孔。在 deepfakes 中,两个网络共享相同的编码器,但使用不同的解码器进行训练。因此,我们现在有两个网络知道了罗纳尔多在游戏中和现实生活中的样子。
First autoencoder network learning from FIFA graphics
Second autoencoder network from learning actual pictures
当在其他人脸上使用预训练模型进行训练时,在 GTX 1070 上,总损失在 4 小时内从大约 0.06 下降到 0.02。在我的例子中,我在原始的 CageNet 模型上继续训练,该模型已经被训练成生成 Nicolas Cage 的脸。
使用训练好的模型来交换面部
现在有趣的部分来了。该算法能够通过采用一种巧妙的技巧来交换面孔。第二个自动编码器网络实际上由第一个网络的输入馈入。通过这种方式,共享编码器能够从 FIFA face 获得编码,但是解码器使用这种编码来重建真实的 face。瞧,这个设置只是把国际足联的脸转换成了罗纳尔多的脸。
The second network converting FIFA face to real face of Ronaldo
结果
下面的 GIF 显示了在其他玩家脸上运行该算法的结果的快速预览。我认为进步是惊人的,但也许我有偏见,所以你来判断。
Comparison of FIFA 18 vs deepfakes faces for Ronaldo, Morata and Ozil.
更多这样的视频格式的结果可以在我的 YouTube 频道上找到,视频嵌入在下面。如果你喜欢这个视频,请订阅我的频道。
我们可以用这个算法把自己放在游戏里吗?
Me as Alex Hunter. To turn it completely into myself, all that’s needed is the ability to add longer hair, match the skin and make the biceps bigger.
如果你能以自己的身份玩游戏的“旅程”模式,而不是以亚历克斯·亨特的身份玩,会怎么样?你所要做的就是上传一分钟长的视频,然后在几个小时内下载训练好的模型。好了,你现在可以以自己的身份玩全程模式了。这将是下一个层次的沉浸式游戏!
它擅长的地方和需要更多努力的地方
我觉得我们用这种方法得到的最大好处是令人惊讶的逼真的面孔和图形,很难与现实世界区分开来。所有这些只需要几个小时的训练就可以实现,相比之下,游戏设计师用目前的方法需要几年时间。这意味着游戏发行商可以更快地推出新游戏,而不是花费数十年时间进行开发。这也意味着电影公司可以节省数百万美元,这些钱可以用来雇佣像样的故事作家。
到目前为止,最明显的限制是这些人脸是事后生成的,就像电影中的 CGI 一样,而游戏要求它们实时生成。然而,一个很大的区别是,一旦模型被训练,这种方法不需要任何人为干预来生成结果,唯一阻碍它的是生成输出图像所需的计算时间。我相信用不了多久,我们就会有重量轻、不太深的生成模型,可以在不影响输出质量的情况下运行非常快,就像我们现在有 YOLO 和 SSD MobileNets 用于实时对象检测一样,这是 RCNNs 等以前的模型所无法实现的。
结论
如果像我这样没有图形设计经验的人可以在几个小时内做出改进的面孔,我真的相信,如果游戏开发商在这个方向上投入巨资,它可以在不太遥远的未来改变游戏行业的面貌(是的,是有意的)。现在,如果 EA sports 的任何人正在阅读这篇文章…
使用深度学习解决网站所有者的常见问题
作为一名数据科学家,我在一家管理三代网站建设平台的公司工作。这个行业启发我们的是,已经有超过 18 亿个网站,89%的企业家声称网站是吸引客户的最有效工具——比社交媒体或移动应用程序有效得多。
如果你看看这篇文章,你会发现这部分网站仍有很大的增长潜力。增长的因素之一是当前网站建设工具的简单性。这种简单是由技术支持的。
技术对不断增加的网站数量有很大影响。
但是随着技术的过时,用它们建立的网站也会过时。
举个例子。Flash 技术在 21 世纪初被广泛用于网站动画,现在被官方宣布为过时——2020 年甚至被宣布为其“到期日”。采用 HTML5 作为新标准已经三年了,然而,许多网站所有者没有时间将他们的网站升级到 HTML5 和其他现代趋势。
因为企业家必须专注于他们的事业。
考虑到这一点,机器学习、深度学习和人工智能开始改善我们创建、更新和维护网站的方式。
让我们看看 AI 到目前为止取得了什么成就
技术在处理业务相关任务时是否足够高效?尽管我相信你已经知道人工智能变得更高效的例子,但我想强调一下最新的、最令人印象深刻的例子,如图像分类和阅读比赛,它们证明了机器可以超越人类。
今天,人工智能经常被训练来减少你测试设计想法所需的时间。
LogoJoy 是一项服务,它会问你问题,试图了解你的偏好,然后为你生成名片、商标和其他东西的可视化效果,该服务已经声称它帮助了超过 160 万用户。去年, pix2code 展示了设计师可以用一个生成 HTML 代码的工具将他们的草图转化为交互界面。
已经有几十个概念和测试项目可以帮助业余爱好者和设计师创造几乎所有类型的数字对象。我们的同事兼朋友 Yuri Vetrov 收集了一些人工智能在网页设计中的应用实例——请随意查看。
现在想象你有一个商业网站
你肯定想知道你的网站的哪些部分真正吸引了你的访问者的注意力:是菜单、产品描述还是右上角的那张小图片?麻省理工学院的visi importance项目可以通过从网页截图中构建热图来帮助你。它预测访问者的注意力将如何在你的网站上传播。它给了你一些见解,但仍然…
你希望你的访问者和客户对你的网站感到满意。从你的角度来看,你的网站很好,但是其他人会怎么说呢?
即使你的页面是用现代技术开发的,有方便的菜单,高质量的产品图片和描述,还有支持表单——仍然有一个问题:“它是否足够吸引人,或者可能需要重新设计?”
Scores assigned by design professionals for a fee
直到 2018 年,还没有找到普通人的思维方式的选项,你只能使用像 AWWWARDS 这样的网站来询问创意专业人士。但是如果你是当地的中小企业,他们就不是你的客户。为了了解普通人的想法,我们推出了服务,模拟普通用户对名片网站和在线商店的看法。
Free website scoring tool, WebScore AI (machine learning model)
我们已经处理了不同年份在不同平台上创建的 12,000 个网站和在线商店,收集了超过 140,000 个评估员的评估,并继续从 webscore.ai 的访问者那里收集网站示例及其得分。
让我们试着给一个网站打分
一个有好的字体、彩色图片、联系页面和社交网络链接的网站。大多数用户会认为这样的网站是好的。
这一假设是我们开发“手工”功能的基础。
特征提取过程由两部分组成:我们将使用 HTML/CSS 作为源的“手工”特征提取与使用截图作为源的卷积神经网络特征提取相结合。CNN 的特征是用流行的特征提取器 resnet50 获得的。
因此,我们的系统学会了寻找分数和特征之间的对应关系。结果,我们得到了一个平均误差为 0.5 点的模型。比评估员的平均误差要好。
现在任何人都可以检查他们的网站的美丽。但是网络上的人工智能仍然有一些高峰需要攀登
Webscore 项目是迈向 uKit 人工智能技术的一个步骤,这是我们今年的主要目标。
在使用基于人工智能的服务方面,企业有很大的潜力:推荐系统、聊天机器人、个性化设计等等。
但是,正如我之前说过的,数百万的网站已经过时了。聊天机器人不会让它们变得更有效,除非有人或事让这些页面再次变得有吸引力。深度学习也可以在这方面有所帮助——所以我们正在通过使用大数据来实现日常重新设计任务的完全自动化。网络包含大量数据,这些数据应该为企业所用。如果你有同样的感觉,我希望你继续关注我们团队的新闻。
P.S. 基于 2018 年 3 月 16 日 uKits 首席数据科学家 Roman Steinberg 在零售深度学习峰会上的演讲。
在 FIFA 18 中使用深度 Q-Learning 完善任意球艺术
Tensorflow 中的一个代码教程,使用强化学习来踢任意球。
Free-kicks taken by the AI bot, trained through 1000 epochs of the Reinforcement Learning process.
在我的上一篇文章中,我展示了一个使用监督学习技术训练来玩国际足联游戏的人工智能机器人。通过这种方法,机器人很快学会了传球和射门等游戏的基本知识。然而,进一步改进它所需的训练数据很快变得难以收集,并且几乎没有改进,使得这种方法非常耗时。出于这个原因,我决定转向强化学习,就像几乎所有评论那篇文章的人所建议的那样!
Previous article: Building a Deep Neural Network to play FIFA 18
在这篇文章中,我将简要介绍什么是强化学习,以及我如何将它应用到这个游戏中。实现这一点的一个大挑战是我们无法访问游戏的代码,所以我们只能利用我们在游戏屏幕上看到的东西。由于这个原因,我无法在完整的游戏中训练 AI,但可以找到一个变通办法,在练习模式中为技能游戏实现它。在本教程中,我将尝试教机器人踢 30 码的任意球,但你也可以修改它来玩其他技能游戏。让我们从理解强化学习技术和我们如何制定我们的任意球问题来适应这一技术开始。
什么是强化学习(以及深度 Q 学习)?
与监督学习相反,在强化学习中,我们不需要手动标记训练数据。相反,我们与环境互动,并观察互动的结果。我们多次重复这个过程,获得正面和负面经验的例子,作为我们的训练数据。因此,我们通过实验而不是模仿来学习。
假设我们的环境处于一个特定的状态s,当采取一个动作a时,它会改变到状态s’。对于这个特定的动作,你在环境中观察到的直接回报是r。这个行动之后的任何一系列行动都会有它们自己的直接回报,直到你因为一个积极或消极的经历而停止互动。这些被称为未来奖励。因此,对于当前状态s,我们将尝试估计所有可能的行动中,哪个行动将为我们带来最大的当前+未来回报,用称为 Q 函数的Q(s,a)表示。这给了我们Q(s,a) = r + γ * Q(s’,a’),它表示在状态s中采取行动a的预期最终回报。在这里,γ是一个贴现因子,用来考虑预测未来时的不确定性,因此我们希望更多地相信现在而不是未来。
深度 Q 学习是一种特殊类型的强化学习技术,其中 Q 函数由深度神经网络学习。给定环境的状态作为这个网络的图像输入,它试图预测所有可能行动的预期最终回报,如回归问题。具有最大预测 Q 值的行动被选为我们在环境中要采取的行动。因此得名深度 Q-Learning。
将国际足联的任意球视为一个 Q 学习问题
- **状态:**通过 MobileNet CNN 给
128-dimensional flattened feature map处理的游戏截图图片。 - **动作:**四种可能采取的动作
shoot_low, shoot_high, move_left, move_right。 - **奖励:**如果按下射击键,游戏内得分增加超过 200,我们就进了一个球
r=+1。如果我们错过了目标,得分保持不变,所以r=-1。最后,r=0为与向左或向右移动相关的动作。 - **策略:**双层密集网络,以特征地图为输入,预测所有 4 个动作的最终总奖励。
Reinforcement Learning process for the bot interacting with the game environment. The Q-Learning Model is the heart of this process and is responsible for predicting the estimated future reward for all possible actions that the bot can take. This model is trained and updated continuously throughout this process.
**注:**如果我们在 FIFA 的开球模式中有一个像练习模式中那样的性能表,我们可能已经能够为玩完整场比赛制定这个问题,而不是限制我们自己只罚任意球。或者我们需要访问游戏的内部代码,但我们没有。不管怎样,让我们充分利用我们所拥有的。
结果
虽然机器人还没有掌握所有不同种类的任意球,但它已经很好地学会了一些情况。它几乎总是在没有玩家墙的情况下击中目标,但在有玩家墙的情况下却挣扎。此外,当它在训练中没有经常遇到像不面对目标这样的情况时,它会表现得疯狂。然而,随着每个训练时期,这种行为被发现平均减少。
The figure shows, for epoch 1 through 1000, average number of free-kicks that got converted per attempt, calculated over a moving average window of 200 attempts. So, for example, a value of 0.45 at epoch 700 means 45% of attempts got converted to a goal (on an average) around this epoch.
如上图所示,训练 1000 个时代后,平均进球率平均从 30%增长到 50%。这意味着当前机器人的任意球得分约为其尝试的一半(作为参考,人类的平均得分约为 75-80%)。请注意,国际足联倾向于表现出不确定性,这使得学习非常困难。
Good examples of free kicks (model trained till 1000 epochs). The bot almost always scores in absence of the yellow player cutouts blocking the goal. In presence of the player wall, it gives mixed results.
Bad examples of free kicks. In some cases like above, the bot keeps transitioning between two states by alternating between left and right actions, making it stuck in a never ending loop. Probably a weakness of Reinforcement Learning setup.
更多视频格式的结果可以在我的 YouTube 频道、上找到,下面嵌入了视频。如果你想了解我所有的项目,请订阅我的频道。
代码实现
我们将使用深度学习的 Tensorflow (Keras)和 OCR 的 pytesseract 等工具在 python 中实现这一点。下面提供了 git 链接以及存储库描述中的需求设置说明。
[## ChintanTrivedi/DeepGamingAI _ FIFARL
DeepGamingAI_FIFARL -使用强化学习玩 FIFA
github.com](github.com/ChintanTriv…)
出于理解本教程的目的,我推荐下面的代码,因为为了简洁起见,已经删除了一些代码。运行 g it 时,请使用 git 的完整代码。让我们看一下代码的 4 个主要部分。
1.与游戏环境互动
我们没有任何现成的 API 可以让我们访问代码。所以,还是自己做 API 吧!我们将使用游戏的截图来观察状态,模拟按键来在游戏环境中采取行动,光学字符识别来读取我们在游戏中的奖励。在我们的 FIFA 类中有三个主要方法:observe(), act(), _get_reward()和一个额外的方法is_over()来检查任意球是否被罚。
2.收集培训数据
在整个培训过程中,我们希望存储我们所有的经验和观察到的奖励。我们将用它作为 Q-Learning 模型的训练数据。因此,对于我们采取的每一个行动,我们都将经验<s, a, r, s’>和一个game_over标志存储在一起。我们的模型将尝试学习的目标标签是每个行动的最终回报,它是我们回归问题的实数。
3.培训过程
现在,我们可以与游戏进行交互,并将我们的交互存储在内存中,让我们开始训练我们的 Q-Learning 模型。为此,我们将在探索(在游戏中采取随机行动)和开发(采取我们的模型预测的行动)之间取得平衡。通过这种方式,我们可以在游戏中进行试错以获得不同的体验。参数epsilon用于此目的,它是一个平衡勘探和开采的指数递减因子。起初,当我们一无所知时,我们想做更多的探索,但随着时代数量的增加和我们了解的更多,我们想做更多的开发和更少的探索。因此。epsilon参数的衰减值。
在本教程中,由于时间和性能的限制,我只训练了1000 epochs的模型,但在未来,我想把它推到至少 5000 个纪元。
4.模型定义和开始培训过程
Q 学习过程的核心是一个具有 ReLU 激活的 2 层密集/全连接网络。它将 128 维特征图作为输入状态,并为每个可能的动作输出 4 个 Q 值。具有最大预测 Q 值的动作是根据给定状态的网络策略要采取的期望动作。
这是执行这段代码的起点,但你必须确保游戏 FIFA 18 在第二台显示器上以窗口模式运行,并在技能游戏:射门菜单下加载任意球练习模式。确保游戏控件与 FIFA.py 脚本中硬编码的按键同步。
结论
总的来说,我认为结果相当令人满意,尽管它未能达到人类的性能水平。从监督学习转换到强化学习有助于减轻收集训练数据的痛苦。如果有足够的时间探索,它在学习如何玩简单游戏等问题上表现得非常好。然而,强化设置在遇到不熟悉的情况时似乎会失败,这使我相信将其公式化为回归问题不能像在监督设置中公式化为分类问题一样外推信息。也许两者的结合可以解决这两种方法的缺点。也许在那里我们会看到为游戏构建人工智能的最佳结果。以后给我尝试的东西!
致谢
我要感谢这个深度 Q-Learning 教程和这个 git 游戏库提供了大部分代码。除了 FIFA 的“自定义 API ”,大部分代码的主干都来自这些来源。多亏了这些家伙!
感谢您的阅读!如果你喜欢这个教程,请关注我的媒体、 github 或者订阅我的 YouTube 频道。
使用 Docker 在 AWS 上建立深度学习环境
在我之前的文章中,我一步一步地解释了如何在 AWS 上建立深度学习环境。重要的一步是安装 CUDA 工具包和 cuDNN 。然而,这一步非常耗时。在本文中,我将使用 docker,特别是 nvidia-docker 来简化安装过程,从而加快安装过程。
我们将使用与上次相同的亚马逊的 EC2 GPU 实例:
- 图片:ami-b 03 ffedf(Ubuntu Server 16.04 LTS(HVM),SSD 卷类型)
- 区域:欧盟中部-1(欧盟法兰克福)
- 实例类型:g2.2xlarge
- 存储:30 GB(建议至少 20gb 以上)
1.创建新的 EC2 GPU 实例
Select the Ubuntu Server 16.04 LTS AMI.
Take the g2.2xlarge GPU Instance. Alternatively, you could also take the g2.8xlarge if you need more computing power.
Change the standard storage size to 30 GB.
Launch the cluster and assign an EC2 key pair.
2.更新 NVIDIA 驱动程序并安装 docker+nvidia-docker
NVIDIA 驱动程序
更新图形驱动程序:
$ sudo add-apt-repository ppa:graphics-drivers/ppa -y
$ sudo apt-get update
$ sudo apt-get install -y nvidia-375 nvidia-settings nvidia-modprobe
码头工人
安装 Docker 社区版(查看官方指南了解更多关于安装的信息):
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Verify that the key fingerprint is 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ sudo apt-get update
$ sudo apt-get install -y docker-ce
英伟达-Docker
安装 nvidia-docker 及其插件:
$ wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
$ sudo dpkg -i /tmp/nvidia-docker_1.0.1-1_amd64.deb && rm /tmp/nvidia-docker_1.0.1-1_amd64.deb
3.测试您的环境:
现在,我们可以使用 nvidia-docker 来测试一切是否按预期工作:
$ sudo nvidia-docker run --rm nvidia/cuda nvidia-smi
注意:如果您第一次运行该命令,它将首先提取图像。此外,如果您不想作为 *sudo* 运行,那么您需要将 EC2 用户添加到 docker 组 *sudo usermod -a -G docker ubuntu* (更多详细信息,请参见 AWS 指南 )。
这是您应该看到的输出:
你现在可以使用官方 TensorFlow docker 映像或 Theano 映像来启动你的深度学习环境,或者你可以编写自己的docker 文件并将其推送到 docker hub 。
张量流示例:
在 shell 中启动最新的 TensorFlow 容器(对于其他选项,如作为 Jupyter 笔记本运行 TensorFlow 程序,请查看官方 TensorFlow 指南):
$ sudo nvidia-docker run -it tensorflow/tensorflow:latest-gpu bash
在 python 中运行一个简单的示例,检查 TensorFlow 在 GPU 支持下能否正常工作:
import tensorflow as tfa = tf.constant(5, tf.float32)
b = tf.constant(5, tf.float32)with tf.Session() as sess:
sess.run(tf.add(a, b)) # output is 10
这是您应该预期的输出:
结论
在这篇博文中,我用 docker 在 AWS 上搭建了一个深度学习环境。这大大加快了安装过程。这对于家里没有自己的 GPU 的人来说特别有用;)
在推特上关注我: @datitran
使用 FastText 和 SVD 即时可视化单词嵌入
不久前,当我开始学习自然语言处理的基础知识时,我对单词被表示为向量的方式很感兴趣。更吸引人的是单词被标绘在图表上,那些具有相似含义和上下文的单词被组合在一起。因此,我努力生成自己的嵌入,这是一场“斗争”,因为我缺乏计算能力。用于生成向量的 Word2Vec 和用于可视化的 T-SNE 是流行的选择,但是花费了我很多时间。
嗯,到现在也没变。然而,我发现脸书的快速文本让我大吃一惊。过去需要几个小时才能完成的事情,现在只需几秒钟就能完成,而且性能几乎相同。除此之外,我使用了一些线性代数来找出可能是“最快”生成你自己的单词嵌入可视化的方法。让我们现在就开始这个过程,写一些代码。
1。获取数据
我决定从 Whatsapp 获取聊天数据。我占用了我大学的文学和辩论俱乐部(LDC)的数据。这是因为我们已经讨论了广泛的话题,而且数据总量接近 1.1 Mb,对于任务来说已经足够了。
2。一些预处理
有些问题需要注意。首先,如果没有保存联系人姓名,在每一个新行的开头都有联系人的电话号码。此外,在聊天中有一些奇怪的特殊字符代表表情符号,但这对我们的任务来说是一个头痛的问题。所以,我使用了一些正则表达式技巧来清理文本。
3。设置快速文本
现在让我们来看看这个大家伙。设置脸书的快速文本是小菜一碟。你所需要的只是一个现代的 C++编译器(C++ 11)和一个 make 命令。FastText 是用纯 C++编写的,这也是它实现如此之快的另一个原因。
a.去github.com/facebookres…克隆回购。
b.切换到下载的目录,在你的终端上输入 make 命令
c.瞧啊。FastText 可以使用了。
4。对我们的数据使用 fast text
我们现在将使用 fasttext 库为我们清理的数据生成单词向量。为此,在 fasttext 目录中打开您的终端并键入-
'''.' '/fast text skip gram-input LDC _ clean . txt-output model ' ' '
让我给你解释一下这个声明。
。/fasttext —使用我们刚刚编译的 fasttext 模块退一步,咄?
skigram —有两种流行的方法来生成单词的矢量表示。CBOW 和 Skipgram。我们在这里选择 skipgram。
-input ldc_clean.txt —我们将包含文本数据的文件名指定为输入参数。
-output model——它指定了 FastText 将生成的两个输出文件的名称。model.vec是包含单词 vectors 的文本文件,每行一个。model.bin是一个二进制文件,包含模型参数、字典和所有超参数
5。从生成的 model.vec 设置 python 列表
现在,我们在一个. vec 文件中有了单词和向量,但是为了绘制它们并对向量执行 SVD,我们需要将单词转换为一个列表,并将相应的向量转换为另一个列表。在此过程中,我们还需要将向量值从 string 转换为 numpy 的 float32 类型,以实现上述操作。
6。利用奇异值分解降低维数。
当我第一次在谷歌上搜索时,我发现 T-SNE 到处都在通过降低维度来产生一些令人惊讶的可视化效果。毫无疑问,我是它的忠实粉丝。但可悲的是我的计算能力没有。所以,我决定,为什么不用老式的奇异值分解。它非常有效。这也是使用 FastText 的首要目的,也就是说,给出真正快速的结果。
7。有趣的部分。绘制我们的数据以创建有洞察力的可视化
现在,我们需要的东西都有了。一个很好的列表,包含了所有的单词和一个非常简化的表示,我们最初的高维向量表示。我们现在要做的就是使用 Matplotlib 并生成一些视觉效果。
就在那里,伙计们,这可能是你能找到的最快的方法,用脸书的快速文本在几秒钟内训练它生成单词的向量表示,然后做一点线性代数魔法,让可视化完全不实时。
我计划发布一个帖子来解释隐藏在幕后的所有复杂的数学问题。它将讨论 FastText 如何在如此短的时间内实现 SOTA 结果,以及如何帮助它击败现有的竞争对手,如 Word2Vec,特别是在训练时间方面。所以,如果你喜欢这个,你肯定会喜欢那个。所以,敬请期待,继续嵌入!
Who’s up for a debate night?
页(page 的缩写)图像被高度放大,因为视觉化的密度极高。使用 matplotlib 的缩放功能来做到这一点。
使用 GANS 进行半监督学习
在监督学习中,我们有一个输入 x 和类别标签 y 的训练集。我们训练一个以 x 为输入,y 为输出的模型。
在半监督学习中,我们的目标仍然是训练一个以 x 为输入,生成 y 为输出的模型。然而,并非所有的训练示例都有标签 y。我们需要开发一种算法,通过研究标记的(x,y)对和未标记的 x 示例,能够更好地进行分类。
我们将使用 GAN 鉴别器作为 n+1 类鉴别器。它将识别 n 个不同类别的标记数据,以及来自生成器的第(n+1)类伪图像。鉴别器将在真实的标记图像、真实的未标记图像和虚假图像上进行训练。通过利用三个数据源而不是一个数据源,它将比只利用一个数据源训练的传统分类器更好地推广到测试集。
发电机:
输出与真实图像尺寸相同的假图像的典型发生器。
需要注意的事项:
- 由于输出激活是 tanh(值范围从-1 到+1),这意味着当我们训练鉴别器时,我们需要将真实图像缩放到相同的范围。
- 我们对生成器的每一层使用标准卷积转置、批量范数和泄漏 relu。
def generator(z, output_dim, reuse=False, alpha=0.2, training=True, size_mult=128):
with tf.variable_scope('generator', reuse=reuse):
# First fully connected layer
x1 = tf.layers.dense(z, 4 * 4 * size_mult * 4)
# Reshape it to start the convolutional stack
x1 = tf.reshape(x1, (-1, 4, 4, size_mult * 4))
x1 = tf.layers.batch_normalization(x1, training=training)
x1 = tf.maximum(alpha * x1, x1)
x2 = tf.layers.conv2d_transpose(x1, size_mult * 2, 5, strides=2, padding='same')
x2 = tf.layers.batch_normalization(x2, training=training)
x2 = tf.maximum(alpha * x2, x2)
x3 = tf.layers.conv2d_transpose(x2, size_mult, 5, strides=2, padding='same')
x3 = tf.layers.batch_normalization(x3, training=training)
x3 = tf.maximum(alpha * x3, x3)
# Output layer
logits = tf.layers.conv2d_transpose(x3, output_dim, 5, strides=2, padding='same')
out = tf.tanh(logits)
return out
鉴别器:
由于无监督的组件,鉴别器比生成器更复杂。
需要注意的事项:
- 积极和广泛使用辍学。这是因为我们在一小组带标签的训练样本上有一个深度卷积层的大锤(注意,大多数训练样本是无标签的),这使得很难不对训练数据进行过度拟合,并教导鉴别器更好地进行概括。
- 我们不在鉴别器的第一层使用批量标准化,因为鉴别器从真实和虚假数据中查看数据的分布是很重要的。
- 我们在鉴别器的最后一层没有使用批处理规范化。Bn 会将每个特征的平均值设置为 Bnμ参数。该层用于特征匹配损失,仅当鉴别器对数据运行时的平均值与鉴别器对生成器样本运行时的平均值不同时,该层才起作用。
- 与标准 GAN 鉴别器一样,我们对每层使用卷积步长、批量范数和泄漏 relu,并且我们使用卷积步长而不是最大池。
- 对于最后一层,我们使用全局平均池来获取特征,而不是密集层。
- class_logits =不同类上的 softmax 分布。
- gan_logits 使得 P(输入是真实的还是虚假的)= sigmoid(gan_logits)
def discriminator(x, reuse=False, alpha=0.2, drop_rate=0., num_classes=10, size_mult=64):
with tf.variable_scope('discriminator', reuse=reuse):
x = tf.layers.dropout(x, rate=drop_rate/2.5)
# Input layer is 32x32x3
x1 = tf.layers.conv2d(x, size_mult, 3, strides=2, padding='same')
relu1 = tf.maximum(alpha * x1, x1)
relu1 = tf.layers.dropout(relu1, rate=drop_rate)
x2 = tf.layers.conv2d(relu1, size_mult, 3, strides=2, padding='same')
bn2 = tf.layers.batch_normalization(x2, training=True)
relu2 = tf.maximum(alpha * x2, x2)
x3 = tf.layers.conv2d(relu2, size_mult, 3, strides=2, padding='same')
bn3 = tf.layers.batch_normalization(x3, training=True)
relu3 = tf.maximum(alpha * bn3, bn3)
relu3 = tf.layers.dropout(relu3, rate=drop_rate)
x4 = tf.layers.conv2d(relu3, 2 * size_mult, 3, strides=1, padding='same')
bn4 = tf.layers.batch_normalization(x4, training=True)
relu4 = tf.maximum(alpha * bn4, bn4)
x5 = tf.layers.conv2d(relu4, 2 * size_mult, 3, strides=1, padding='same')
bn5 = tf.layers.batch_normalization(x5, training=True)
relu5 = tf.maximum(alpha * bn5, bn5)
x6 = tf.layers.conv2d(relu5, 2 * size_mult, 3, strides=2, padding='same')
bn6 = tf.layers.batch_normalization(x6, training=True)
relu6 = tf.maximum(alpha * bn6, bn6)
relu6 = tf.layers.dropout(relu6, rate=drop_rate)
x7 = tf.layers.conv2d(relu5, 2 * size_mult, 3, strides=1, padding='valid')
# Don't use bn on this layer, because bn would set the mean of each feature
# to the bn mu parameter.
# This layer is used for the feature matching loss, which only works if
# the means can be different when the discriminator is run on the data than
# when the discriminator is run on the generator samples.
relu7 = tf.maximum(alpha * x7, x7)
# Flatten it by global average pooling
features = tf.reduce_mean(relu7, (1, 2))
# Set class_logits to be the inputs to a softmax distribution over the different classes
class_logits = tf.layers.dense(features, num_classes + extra_class)
# Set gan_logits such that P(input is real | input) = sigmoid(gan_logits).
# Keep in mind that class_logits gives you the probability distribution over all the real
# classes and the fake class. You need to work out how to transform this multiclass softmax
# distribution into a binary real-vs-fake decision that can be described with a sigmoid.
# Numerical stability is very important.
# You'll probably need to use this numerical stability trick:
# log sum_i exp a_i = m + log sum_i exp(a_i - m).
# This is numerically stable when m = max_i a_i.
# (It helps to think about what goes wrong when...
# 1\. One value of a_i is very large
# 2\. All the values of a_i are very negative
# This trick and this value of m fix both those cases, but the naive implementation and
# other values of m encounter various problems)
if extra_class:
real_class_logits, fake_class_logits = tf.split(class_logits, [num_classes, 1], 1)
assert fake_class_logits.get_shape()[1] == 1, fake_class_logits.get_shape()
fake_class_logits = tf.squeeze(fake_class_logits)
else:
real_class_logits = class_logits
fake_class_logits = 0.
mx = tf.reduce_max(real_class_logits, 1, keep_dims=True)
stable_real_class_logits = real_class_logits - mx gan_logits = tf.log(tf.reduce_sum(tf.exp(stable_real_class_logits), 1)) + tf.squeeze(mx) - fake_class_logits
out = tf.nn.softmax(class_logits)
return out, class_logits, gan_logits, features
模型损失函数和优化器:
d_loss :鉴频器的损耗为:
- GAN 问题的损失,其中我们最小化二进制真假分类问题的交叉熵:d_loss_real 和 d_loss_fake
- 真实监督数据(带标签)多分类问题的损失:d_loss_class。对于 d_loss_class,我们仅考虑迷你批次中具有标签的样本,但是迷你批次中可能没有样本具有标签,因此以下表达式将为 0/1,并且 d_loss_class 的损失为 0。" TF . reduce _ sum(label _ mask * class _ cross _ entropy)/TF . maximum(1。,tf.reduce_sum(label_mask))"
发电机的损耗是由 Tim Salimans 在 OpenAI 发明的“特征匹配”损耗。这种损失包括最小化数据上的预期特征和生成样本上的预期特征之间的绝对差异。这种损失对于半监督学习比传统的 GAN 损失更有效。随着时间的推移,这将迫使生成器生成与真实数据相似的样本。
请注意,使用生成器的特征损失,生成器样本不会像在传统 DCGAN 中生成的样本一样好,但是这里的目标是使用小的标记数据集和大的未标记数据集来实现多类分类的高鉴别器准确度。
def model_loss(input_real, input_z, output_dim, y, num_classes, label_mask, alpha=0.2, drop_rate=0.):
"""
Get the loss for the discriminator and generator
:param input_real: Images from the real dataset
:param input_z: Z input
:param output_dim: The number of channels in the output image
:param y: Integer class labels
:param num_classes: The number of classes
:param alpha: The slope of the left half of leaky ReLU activation
:param drop_rate: The probability of dropping a hidden unit
:return: A tuple of (discriminator loss, generator loss)
"""
# These numbers multiply the size of each layer of the generator and the discriminator,
# respectively. You can reduce them to run your code faster for debugging purposes.
g_size_mult = 32
d_size_mult = 64
# Here we run the generator and the discriminator
g_model = generator(input_z, output_dim, alpha=alpha, size_mult=g_size_mult)
d_on_data = discriminator(input_real, alpha=alpha, drop_rate=drop_rate, size_mult=d_size_mult)
d_model_real, class_logits_on_data, gan_logits_on_data, data_features = d_on_data
d_on_samples = discriminator(g_model, reuse=True, alpha=alpha, drop_rate=drop_rate, size_mult=d_size_mult)
d_model_fake, class_logits_on_samples, gan_logits_on_samples, sample_features = d_on_samples
# Here we compute `d_loss`, the loss for the discriminator.
# This should combine two different losses:
# 1\. The loss for the GAN problem, where we minimize the cross-entropy for the binary
# real-vs-fake classification problem.
# 2\. The loss for the SVHN digit classification problem, where we minimize the cross-entropy
# for the multi-class softmax. For this one we use the labels. Don't forget to ignore
# use `label_mask` to ignore the examples that we are pretending are unlabeled for the
# semi-supervised learning problem.
d_loss_real = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=gan_logits_on_data,
labels=tf.ones_like(gan_logits_on_data)))
d_loss_fake = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=gan_logits_on_samples,
labels=tf.zeros_like(gan_logits_on_samples)))
y = tf.squeeze(y)
class_cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=class_logits_on_data,
labels=tf.one_hot(y, num_classes + extra_class,
dtype=tf.float32))
class_cross_entropy = tf.squeeze(class_cross_entropy)
label_mask = tf.squeeze(tf.to_float(label_mask))
d_loss_class = tf.reduce_sum(label_mask * class_cross_entropy) / tf.maximum(1., tf.reduce_sum(label_mask))
d_loss = d_loss_class + d_loss_real + d_loss_fake
# Here we set `g_loss` to the "feature matching" loss invented by Tim Salimans at OpenAI.
# This loss consists of minimizing the absolute difference between the expected features
# on the data and the expected features on the generated samples.
# This loss works better for semi-supervised learning than the tradition GAN losses.
data_moments = tf.reduce_mean(data_features, axis=0)
sample_moments = tf.reduce_mean(sample_features, axis=0)
g_loss = tf.reduce_mean(tf.abs(data_moments - sample_moments))pred_class = tf.cast(tf.argmax(class_logits_on_data, 1), tf.int32)
eq = tf.equal(tf.squeeze(y), pred_class)
correct = tf.reduce_sum(tf.to_float(eq))
masked_correct = tf.reduce_sum(label_mask * tf.to_float(eq))
return d_loss, g_loss, correct, masked_correct, g_model
演职员表:来自讲稿:【classroom.udacity.com/nanodegrees…
使用 ggplot 在地理地图上绘制饼图
在这篇文章中,我们将详细介绍在世界地图上绘制饼图的步骤,如下图所示。
Plot showing the leading causes of death in the year 2014 for various countries
当我意识到我需要创造一个和这个一样的东西时,这张图片可能让你和我一样害怕。“我连 R 编程都不擅长,事实上,还是个新手,我该怎么做这件事呢?”你可能正在问自己这个问题,或者你已经问过了。我理解你,但我得到了你。我在做我的第一个地图绘制时挣扎了很久,这就是为什么我将与你分享如何使用 ggplot 一步一步完成它的方法,让你从所有的谷歌搜索和试错中解脱出来。
这样,在我们进行这些步骤时,我们将使用真实世界的数据来回答一个特定的问题。
"每个国家的死亡原因分布有差异吗?"
我设法从kaggle.com获得了一个关于世界上每个国家死亡原因的体面数据,这些数据将用于我们的插图和模拟。
准备数据
我们需要做的第一件事是确保我们的数据是完整的,在绘图之前我们有我们需要的东西。在这种情况下,我们需要每个国家的死亡原因数据以及每个国家的坐标。然后,我们将它加载到我们的工作环境中,如下所示。
一旦我们完成了所有需要的数据,我们将继续决定我们将要做的地图绘制的方法。我们有几个选项用于 ggplot,因为它很容易获得世界地图数据。
Rdocumentation.org 有一个非常友好的文档,包含了大部分 r 包和函数,所以如果你是 r 新手,我真的建议你去看看
其中 map 是 maps 包中提供的地图的名称。map_data("world ")即时获取我们绘制世界地图所需的数据。
其中 database 是要绘制的地图数据(查看 maps::map()以获取可用的地图)。borders("world ")获取数据以创建世界的边界。
最后,使用形状(。shp)文件。我们需要获得我们感兴趣的地图的形状文件。在这种情况下,我研究了一个. shp 文件并使用
其中 dsn 是我们感兴趣的形状文件。从 readOGR 获得的数据还不能用于绘图。我们将使用
其中“模型”是需要转换为数据框的模型或 R 对象。fortify(world)将我们从。shp 文件转换为有用的数据框,以备打印。
我已经决定使用这三个工具,但是你可以在你的项目中选择一个,最简单和最适合你的。
基础地图地块
这些代码的输出看起来很接近。
World map
添加馅饼
为了将饼图添加到地图绘图中,我们将在原始 ggplot 公式中添加一个 geom_scatterpie 函数,如下所示。
World map with the distribution of death causes per country
添加标签、图表标题、轴标题等
为了改善我们可视化的外观,我们将通过向 ggplot 公式添加一些新函数来为图表添加一些附件。
这就对了。我们在世界地图上标出了每个国家的死亡原因分布。我们可以看到,除了白俄罗斯和格鲁吉亚之外,几乎所有这些国家都有相同的分布,因为与其他国家相比,白俄罗斯和格鲁吉亚的循环系统疾病发病率较高。
我上面给你展示的方法只是一种方法。其他可以尝试的地图绘制方法有:tmap 包中的 ggmap 、 mapplot 、 qtm 、传单等。我强烈建议你也试一试。
在这个库中可以获得在这个模拟中使用的所有文件的副本。
原载于 2018 年 10 月 25 日www.spectdata.com。 Marriane Makahiya,作者是 SpectData 的数据科学家。SpectData 是一家数据分析公司,旨在帮助公司更好地利用他们的数据。
从 Git 到 Colab,通过 SSH
如何将 Git 与 Colab 集成,以便克隆您的公共/私有存储库。
当你使用谷歌的联合实验室(Colab)来运行你的深度学习模型时,访问大型数据集最明显的方法是将它们存储在谷歌驱动器上,然后将驱动器安装到 Colab 环境中。但是许多用于研究目的的开源大型数据集都托管在 Github/Gitlab 上。幸运的是,Colab 提供了一种集成 Github 和访问存储库的简单方法。那么,让我们来详细看看这些步骤。
Colab — Git —集成:
我将在两种情况下解释集成:
- 使用公共 Git 存储库(没有 SSH)
- 使用私有 Git 存储库(使用 SSH)
克隆一个公共 Git Repo:(没有 SSH)
集成只是几行代码——当您想要克隆的 git 存储库是一个公共存储库时。
- 将 Google Drive 安装到您的 Colab 环境中。
在执行上面的 2 行代码时,系统会提示您转到所示的 Google Accounts URL 进行身份验证。单击显示在笔记本单元格输出部分的 URL。这将带您进入如下页面:
点击允许按钮。这将把你带到下一页,在那里显示一个授权码(我用红色标出)。
复制此代码并将其粘贴到单元格(如第一个图像所示)中显示“输入您的授权码”的位置,然后单击 Enter。Google Drive 现在已安装,您会收到确认消息。
- 将您的公共 Git repo 克隆到您的驱动器文件夹中。执行上述步骤后,驱动器文件将出现在路径 "/content/drive/My Drive" 中,您可以使用左侧的面板浏览它们。
然后,您可以将任何驱动器文件夹设置为工作目录。然后将公共 git repo 克隆到您的工作目录中。这两个步骤的实现如下:
克隆一个私有 Git Repo:(使用 SSH)
不幸的是,你不能轻易地克隆你的私有库。事实上,在这种情况下,您可以使用一行程序,如下所示:
也就是说,提供您的用户名:密码以及存储库链接来克隆一个私有存储库。这是可行的,但是问题是密码存储在 git/config 和 bash 历史日志中。因此,以上述方式克隆您的私有回购协议是不可取的。相反,我们将使用 SSH 协议将您的私有 github/gitlab repo 连接到 colab。
- 第一步是在本地机器上生成 ssh 密钥对(私有-公共)。你可以通过这篇优秀的文章(文章的第 1 步和第 2 步)来了解如何做到这一点。但是我会马上提供必要的步骤:
ssh-keygen-t RSA-C " your _ email @ your email . com "
#出现提示时输入文件名:~/。ssh/id_rsa_<some_name></some_name>
#输入密码短语:只需按“Enter”(无密码短语)
- 私钥保存在文件: ~/。ssh/id _ RSA *并且公钥保存在文件: *~/。ssh/id_rsa < some_name >。pub 将这两个文件复制到一个文件夹中。我将这两个文件的副本放在一个文件夹中,并将其命名为*‘ssh-colab’*。
- 接下来创建一个配置文件
触摸配置
编辑配置
- 配置文件的内容应该如下所示:
- 现在将配置文件也放在在*‘ssh-colab’*之前创建的文件夹中。然后存档为 'ssh.tar.gz' :
tar-czvf ssh.tar.gz ssh-colab
- 这个包含私钥、公钥和配置文件的归档文件夹必须上传到 Colab。我们马上就会看到这一点。但在此之前,我们先把公钥放在服务器上(Github/Gitlab)。
- 将文件 id_rsa_ < some_name >中的公钥内容复制到剪贴板。发布会
- 登录 Github
- 点击你的个人资料>设置> SSH 和 GPG 键>新建 SSH 键
- 粘贴剪贴板的内容并保存
- 现在是在 Colab 上执行的步骤。首先让我们上传档案文件*‘ssh . tar . gz’。*
- 现在我们需要将密钥对文件和配置文件移动到/root/中。ssh 文件夹。下图详细给出了要执行的 shell 命令:
- 下一步是将私钥加载到本地 ssh-agent 中。这背后的原因在这个 stackoverflow 帖子的标记答案中解释得很清楚。我将在下面给出它的要点:
“您希望在登录时在后台运行
ssh-agent。一旦你登录,这个想法就是运行ssh-add一次并且只运行一次,以便给代理你的密码,解码你的密钥。然后,代理将您的密钥解锁并加载到内存中,随时准备在您每次 ssh 时使用。然后,所有 ssh-family 命令 1 将咨询代理,并自动能够使用您的私钥。”
- 因此,要运行您的 ssh-agent,请使用以下命令
- 在单元的输出部分,您会收到一条警告消息,ssh-agent 开始运行。您会得到一个可以执行 shell 命令的提示。请参见下图,我们在其中添加了私钥,然后检查新密钥是否已保存:
- 在下一步中设置您的 Git 帐户
- 我们现在可以克隆我们的私有 git 存储库了。将工作目录更改为驱动器内的一个文件夹。然后运行 git clone。
仅此而已!我们已经从 Colab SSH-ed 进入我们的 Git 帐户,并克隆了我们的私有存储库。
参考资料:
- https://stack overflow . com/questions/48350226/methods-for-use-git-with-Google-colab
- https://stack overflow . com/questions/10054318/how-to-provide-username-and-password-when-run-git-clone-git remote-git?noredirect=1 & lq=1
谷歌搜索商标的图片。版权分别属于 Colaboratory 和 Github。其他图片是我的作品截图。
原载于 2018 年 6 月 5 日techsupportallbugs.wordpress.com。
使用 Google Apps 脚本从您的 Google Analytics 帐户获取数据
只需点击一个按钮,所有的谷歌分析数据都可以在谷歌工作表中找到,这怎么样?
Photo by Myriam Jessier on Unsplash
谷歌分析无需介绍。绝对是互联网上最受欢迎的网络分析服务,帮助企业收集和分析数据,并使用它们来发展和增强他们的服务或产品。访问 Google Analytics 数据的最常见方式是通过主仪表板和预定义的报告。为了处理数据并提取更有价值的见解,您可以创建标准或自定义报告来呈现您需要的数据,然后通常将它们导出到电子表格中。方法是使用 GA 控制台中提供的导出功能(PDF、Google Sheets、Excel 或 CSV 格式),然后将文件导入 Google 电子表格或任何其他电子表格软件。
Image by Author
但是,如果您需要对多个文件这样做,或者在一段时间内定期这样做(例如,生成定期报告),该怎么办呢?这很痛苦,不是吗?好吧,**谷歌应用程序脚本来拯救!**💪💪
Google 企业应用套件脚本
那么,什么是 Google Apps 脚本呢? Google Apps Script 是一种 JavaScript 云脚本语言,提供了跨 G-Suite 产品和第三方服务自动执行任务以及构建 web 应用的简单方法。简而言之,使用 JavaScript,我们可以增加我们最喜欢的、已经很强大的谷歌应用程序的功能,比如电子表格、文档、日历、邮件等等。在我们的案例中,我们将关注 Google 电子表格和 Google Apps 脚本之间的集成。要访问脚本编辑器,我们可以在其中构建我们的应用程序,我们可以创建一个新的电子表格,并从顶部菜单中单击工具>脚本编辑器。
Image by Author
连接 Google 电子表格和 Google APIs
上述选项将使用脚本编辑器控制台打开一个新标签。使用这个控制台,我们可以构建我们的应用程序,创建脚本文件,连接资源等。在我们的例子中,我们将使用 Google Analytics API 作为资源来获取我们需要的数据。要启用 Google 电子表格和 Google 分析 API 之间的连接,我们必须遵循以下步骤:
- 单击顶部菜单上的“资源”选项。
- 点击“高级谷歌服务…”选项。
- 为我们的项目命名(在这种情况下,我们将命名为“测试项目”)。
- 搜索 Google Analytics API ,点击开关将其打开。
Image by Author
5.先别急着关窗。为了获得完全访问权限,我们还必须在 Google API 控制台中启用我们选择的服务。如果我们点击提供的链接,我们将被直接重定向到 GCP 控制台,通过搜索顶部搜索栏上的“分析 API ”,我们将找到我们选择的服务。
Image by Author
6.点击启用,你就可以开始了!👏
查询浏览器
在处理数据和报告时,最重要的是我们的数据要一致和可信。建立别人对你数据的信任需要很长时间,但失去信任只需一分钟。在这个过程中我们最好的朋友是谷歌的一个非常有用的工具,叫做查询浏览器。Query Explorer 通过使用各种参数进行查询和测试响应来帮助我们处理 Google Analytics 数据。我们可以选择想要查询数据的帐户—属性—视图,只需添加参数(开始日期、结束日期、指标、维度、筛选器、细分等)。然后,我们可以下载 TSV 格式的数据(制表符分隔的文件),或将直接 API 查询 URI 保存到该报告中。通过 Google Apps 脚本查询数据是模拟查询浏览器数据的一种方式,就我个人而言,我总是让查询浏览器在一个选项卡中打开来验证查询。
构建脚本
说够了。让我们开始行动吧。在我们创建了项目并启用了分析 API 之后,下一步是实际构建脚本来获取我们需要的数据。我们将需要 2 个标签不断在点击之外。
- 查询浏览器(构建和验证查询)
- Google Apps 脚本电子表格参考(一个非常详细且写得很好的文档)
为了从谷歌分析中查询数据,我们需要下面的函数。该函数接受 5 个参数作为输入,并返回一个报告作为输出。
function gaGet(tableId, startDate, endDate, metrics, options)
这些论点是:
- tableId: 实际上是我们要查询的视图的 Id。在查询资源管理器中,当我们选择适当的帐户-属性-视图时,会自动设置表 id(格式:“ga:xxxxxxx”)。
- startDate: 查询的开始日期(格式:“yyyy-MM-dd”或 NdaysAgo)。
- **结束日期:**查询的结束日期(格式:“yyyy-MM-dd”或 NdaysAgo)。
- **指标:**保存查询指标的表(例如 ga:用户或 ga:会话)
- **选项:**包含所有其他必要信息的对象(如维度、过滤器、分段、排序等)
上面脚本中我们最应该关心的核心命令是:
return Analytics.Data.Ga.get(tableId, startDate, endDate, metrics, options);
这是实际查询来自 Google Analytics 的数据并返回报告的命令。代码片段的所有其他部分只是为了处理任何可能的错误。
用例
因此,在我们的用例中,我们将获取一些核心指标,如浏览量、平均。我们网站前 5 页的页面时间和跳出率,并写在我们的电子表格中。为此,您需要复制下面的脚本,并将其粘贴到应用程序脚本控制台。
*注意:您需要为工作表(不是电子表格)的名称、要查询的表 id(您可以通过选择“帐户”—“属性”—“视图”)以及查询的开始和结束日期指定您自己的值。
粘贴了上面的脚本并添加了自己的参数后,选择运行>运行函数> main 。如果需要,进行身份验证,瞧!您的数据可以在电子表格中找到。在第一列中,我们看到了页面,接下来的三列分别是页面浏览量、页面平均停留时间和跳出率,正如我们在“指标”数组中声明的那样。
结论
在这篇小文章中,我们看到了一种从 Google Analytics 查询数据并使用应用程序脚本将其写入 Google 电子表格的简单方法。当然,应用程序脚本的能力是无限的,它能做的远不止获取简单的数据。把手弄脏,当你越来越习惯使用 Apps Script 时,你会意识到你能实现多少,你能自动化多少任务和报告。
页(page 的缩写)s:该指南已更新,以适应最近的变化。
如果您需要帮助或希望优化您的跟踪和分析设置,请联系我们!我们支持所有领域和规模的客户取得巨大成功,我们能够展示高质量的结果。我们的程序和经验确保您能够找到、跟踪、测试和分析所有重要的部分,并对您的业务绩效有一个全面的了解。
使用谷歌数据工作室
Simple Explorer Dashboard
谷歌推出谷歌数据工作室已经有一段时间了,并提供免费使用(其中一个版本)。谷歌数据工作室是一个报告和可视化工具。
在设计报告、仪表板和/或演示文稿时,我们应考虑并阐述以下问题:
- 这个仪表板是给谁的?
- 仪表板的用途是什么?
- 我们将回答哪些问题?
- 什么是比较期?
- 理解起来简单吗?
- 信息的处置情况如何?
如果我们回答了这些问题,我们将拥有一个简单的、包含我们需要的信息的仪表板!
这是一个示例仪表板,您可以使用此 Google Data Studio 报告和 Google Analytics 数据源(拥有一个 Google 帐户并为您自己制作一份副本)默认情况下在 Google Analytics 中使用演示 Google 帐户,但您可以使用默认数据按钮更改为您自己的数据。
Data Sources Connectors on Data Studio
Google Data Studio 用户社区现在创建了多个数据源来进一步扩展它的用途!
在我们的左边,你可以看到本地数据源连接器。
有一些超级用户对谷歌分析和谷歌数据工作室的区别感到困惑? 嗯,它们是不同的工具谷歌分析是一个网络分析工具,而谷歌数据工作室是一个报告和仪表板的生成器,谷歌分析是一个数据源,还有其他数据源,如谷歌广告词。
使用谷歌地图的位置历史来计算和可视化我自己的交通拥堵成本
“cars passing through north and south” by Alexander Popov on Unsplash
在阿姆斯特丹自由大学(Vrije Universiteit)工作的一年里,我设计了一个可交易道路许可计划的模型,以应对高峰时段的交通拥堵。现在我从事咨询工作,我成了问题的一部分。我每周开车 4 次去一个离我公寓近 60 公里的客户那里,我亲身经历了“福利损失”,经济学上称之为被拥挤的交通所困扰。但是,当我最近寻找一个免费数据集进行实验时,我的日常通勤证明是派上了用场。当我使用谷歌地图作为我的 GPS 时,我的位置历史包含了我所有的旅行(甚至更多!)而现在它只等着我用在自己的目的上!
我可以用它来计算我在过去 18 个月中经历的福利损失吗?我可以用它来计算我在交通堵塞中花费的总时间吗?我可以用它来调查学校假期或我的出发时间对我的通勤时间有什么影响吗?所有这些问题的答案都是“是的”……或者至少是“在某种程度上”。
谷歌地图数据基本上由坐标、时间戳、精确度和活动变量组成,因此很容易找到你在特定时间点的位置,以及在某种程度上你在做什么。但是后一种方法非常不可靠,尤其是对我来说,因为汽车中的慢速经常被理解为骑自行车甚至走路。因此,我需要做的是将位置快照结合到旅行中,并将我在车上的通勤与其他旅行隔离开来。
我使用了 Python 和 pandas dataframes,这里只显示更关键的代码,但如果需要整个笔记本,请随时联系我。
我的 json 文件产生了将近 800,000 行原始数据。首先,我将时间戳和坐标转换成可以被 datetime 和 geodesic 模块解释的格式。
with open (‘Location History.json’) as f:
data = json.load(f)
df = pd.DataFrame(data[‘locations’])
df = df[[‘accuracy’,’timestampMs’,’latitudeE7',’longitudeE7']].copy()
df[‘timestampMs’] = df[‘timestampMs’].astype(float)/1000
df[‘datetime’] = df[‘timestampMs’].apply(lambda t: dt.datetime.fromtimestamp(t))
df[‘latitudeE7’] = df[‘latitudeE7’]/10**7
df[‘longitudeE7’] = df[‘longitudeE7’]/10**7
现在我已经可以删除 2017 年之前的所有内容了,因为那时我还没有车。通过将时间戳拆分成时间和日期,并应用 datetime.weekday 功能,我可以识别周末,并将它们从数据集中删除。然后,我输入我的公寓和我要去的客户的坐标作为参考点。使用测地线模块,我可以计算出每个时间点我与客户的距离。按天分组,我会选择那些我离客户办公室的最小距离小于 500 米的日子。我 100%确定我在业余时间从来没有经过那里,所以这个属性立即标识了我通勤上班的那一天。
distance_client_by_date = df.groupby('date', as_index = False)['distance_client'].min().apply(lambda x: x)
trip_days = distance_client_by_date.loc[distance_client_by_date['distance_client']<0.5].copy()
df_trips=df.loc[df['date'].isin(trip_days['date'])].copy()
接下来,我定义了两个不同的高峰,一个是早上 7:00 到 9:30 的高峰,另一个是晚上 4:00 到 8:30 的高峰。不在这些时间段内的所有内容都将被删除。早上,确定旅程很容易,因为我的位置要么在家里,要么在车里。没有其他可能性。一旦我离家有了一段距离(> 100 米),这意味着我已经在车上,正在路上。当我离我客户的位置比较近的时候(< 200 米,因为接收不好,所以准确度较低),我就到了。我为行程设置了一个二进制指示器:
np.where((df_trips['distance_home'] > 0.1) & (df_trips_periods['distance_client'] > 0.2) & (df_trips_periods['period']=='Morning'), 1,0 )
具有这些属性的某一天早高峰期间的所有数据点构成一次旅行。 晚上,事情有点复杂,因为到家后,我不一定会呆在家里。我需要确定离开客户办公室后最早的时间点,即我与公寓的距离小于 100 米。否则,再次去 oude kaasblokjes 商店可能会被错误地计入我的通勤时间。因此,我创建了一个到家时的标志,然后选择最早的(“最小”)时间点,这发生在每个晚高峰:
df_trips['arrived'] = np.where((df_trips_periods['smth_dist_home'] < 0.1) & (df_trips_periods['period']=='Evening'), 1,0)df_trips['arrival_time'] = df_trips.loc[df_trips['arrived']==1].groupby('peak')['time'].transform('min')
通过时间增量功能,我计算出高峰旅行中最早和最晚时间点之间的时间增量。在清除了一些奇怪的异常值后,我可以从有趣的部分开始,调查大约 300 次旅行(通过比较谷歌地图在同一天记录的内容,很容易检查异常值。好像有几天我都没有察觉就瞬移了)。我可以运行一些回归模型,但是图片胜于雄辩。
我感兴趣的一件事是,在学校放假期间,我的通勤时间是否会明显减少。主观上,道路感觉更加空旷,但是数据会支持我的直觉吗?我在学校正式放假期间添加了一个标记,并在密度图中绘制了假期和非假期的旅行时间:
图表支持了我的直觉。假期的出行时间分布更窄,峰值更靠左。我似乎在学校假期之外的路上时间更长。但这并不意味着交通流量马上就会减少。也许我在夏天温暖的日子里提早下班,这也是学校假期,因此通过在高峰的早期边缘时段离开来避免高峰交通拥堵(如果读者碰巧是我的雇主:这是一个严格的假设场景,当然我每天都工作直到我崩溃)。
密度图显示我的出发时间与学校假期无关。
出发时间一般对我的旅行时间有影响吗?我预计会出现非线性影响,传播时间一开始会增加,但在大部分峰值过去后,传播时间会再次下降。我使用出发时间作为因变量旅行时间的线拟合的解释变量来选择 regplots。为了验证我对非线性效应的怀疑,我们可以用不同次数的多项式来比较几个图。
在所有情况下,高峰期间的曲线凹度显示了可疑的影响,但鉴于在稍后的出发时间观察到的少数数据点,这不应该太认真——如果你打算这样做的话。我的另一个问题是,一周中有明显的不同吗?在荷兰,周三是典型的“爸爸日”,父母可以休育儿假,交通也更加顺畅。
周三虫群当然有很重的底(这样的语境下用“thicc”可以吗?),表明更多的观察和更短的传播时间,但是更多的观察当然有助于进一步研究差异是否真正显著。 最后,我是否调整了自己的出行行为以避免拥堵?毕竟,经济学家通常期望在更长的时间内建立均衡。我是否从我的日常经验中学到了,现在的旅行时间比我刚开始时短了,而且我对其他通勤者的行为一无所知?
没有。
看不到学习效果。我一次又一次驾驶同一条路线的经验并没有体现出任何避免拥堵的能力。
形象化就说到这里,作为运输经济学家,我当然也对我可怜的灵魂因交通拥堵而遭受的福利损失感兴趣。基于 41 分钟的最短行程时间和 59 分钟的平均行程时间,我得出平均 18 分钟的行程时间是由于交通拥堵造成的额外时间。对所谓的“时间价值”应用 15 欧元的标准值,这是一种在经济学中用财务术语表达时间的方法,可用于成本效益分析,这意味着我每天的福利损失大约为 9 欧元。从项目开始到现在,我进行了大约 300 次旅行,所以我的总福利损失约为 1.300 欧元,我在拥堵中度过了大约 6.000 分钟或 100 小时或 4 天。不在路上。而是纯粹靠因拥堵而多出来的出行时间。 我在车里听有声读物来打发时间,在《智人》中,作者解释道,佛教徒认为所有的痛苦都是由渴望造成的。渴望更多愉快的经历,或者渴望逃避不愉快的经历。因此,我内心隐藏的佛教徒应该克制自己,不要去想在交通拥堵中损失 4 天是否太多,因为这可能会导致对减少拥堵的渴望,最终导致我自己的痛苦。佛教徒很少是优秀的运输经济学家。
利用人性和大数据解决问题
“Pattern Recognition” by Lachlan Hardy is licensed under CC BY 2.0
人类擅长很多事情。其中之一是模式识别,即在大量数据、图片或文本中发现突出部分的能力。
我们非常善于在相当一致的图像中发现事物。我们可以在一堆白点中发现一个星系斑点,或者在一页信中发现一个真实的单词。我们甚至可以 t8k3 a r@nd0m jumbl3 0f numb3r5 和 l3tt3r5 以及其中的 m@k3 s3ns3(我现在就不说那个了)。
人类的心灵是一种美丽而奇妙的东西。它能做这么多,比我们现在知道的还要多。这是有史以来最不可思议的计算机。
想象一下,如果你能让十几个、一百个、一千个甚至上万个人一起工作来发现模式,会有什么样的成就。你可能会有令人难以置信的新发现,发现以前从未被理解的事物,或者发现以前从未见过的事物。
Zooniverse Galaxy 3D project
这是 Zooniverse 项目背后的想法之一。它是“世界上最大、最受欢迎的人力研究平台”。
研究人员创建了一个项目,比如说尝试在恒星图片中寻找星系。他们解释要寻找什么,并提出问题来帮助识别。然后,志愿者们开始着手这项工作,并对他们认为可以处理的尽可能多的数据进行分类。
你让尽可能多的人对随机照片进行分类,希望你能得到一个可验证的数据——比如十几个人说“是的,那个斑点是一个星系,就是这种类型的星系”。然后你可以用望远镜(无论哪种最好)对准那个星系来验证数据,节省随机搜索的时间来验证可能不存在的东西。
它已经被用于旧文件,寻找物种,寻找粒子,当然还有更多的星系搜索。
The Hunt for Planet 9
Zooniverse 说:“21 世纪研究的主要挑战是处理我们现在可以收集的关于我们周围世界的大量信息。计算机可以提供帮助,但在许多领域,人类的模式识别能力——以及我们的惊讶能力——让我们更胜一筹。”
我自己对一些项目进行了分类,与成千上万的其他志愿者一起,项目背后的研究人员能够产生真正的科学,真正的数据,并做出可能需要几十年才能完成的发现。
在志愿者的帮助下,Zooniverse 正在以前所未有的速度拓展理解的边界。
通过机器学习图像分割增加发展中国家对太阳能的采用
这项工作由 Jatinder Singh 和 Iresh Mishra 共同完成。也感谢索拉博·辛格的指导。
过去,我曾写过机器学习如何在清洁能源领域带来一个新时代,以及我们如何利用一个 ML 爱好者社区来构建解决方案。在本文中,我将分享其中一项任务的结果(从卫星图像中识别屋顶)。
由于来自印度(和大多数发展中国家)的卫星图像的质量是低分辨率的,手头的任务的复杂性增加了。类似的解决方案如谷歌天窗项目仅适用于高分辨率图像,不适用于大多数发展中国家。
Satellite images of Delhi
我们的第一步是确定最适合这项任务的算法。
步骤 1:算法的识别
我们最初开始使用计算机视觉的图像分割算法。目标是通过识别屋顶的边缘将图像分割成屋顶和非屋顶。我们的第一次尝试是使用分水岭图像分割算法。当提取图像中的接触或重叠对象时,分水岭算法特别有用。该算法速度很快,计算量小。在我们的例子中,一幅图像的平均计算时间是 0.08 秒。
以下是分水岭算法的结果。
Original image(left). The output from the Watershed model(right)
如你所见,输出不是很好。接下来,我们实现了 Canny 边缘检测。像 Watershed 一样,这种算法也广泛用于计算机视觉,并试图从不同的视觉对象中提取有用的结构信息。在传统的 Canny 边缘检测算法中,有两个固定的全局阈值来滤除伪边缘。然而,随着图像变得复杂,不同的局部区域将需要非常不同的阈值来准确地找到真正的边缘。所以有一种技术叫做 auto canny,自动设置下限和上限。下面是自动报警的 Python 函数:
Canny 边缘检测器处理一幅图像的平均时间约为。0.1 秒,很不错了。其结果优于分水岭算法,但精度仍不足以满足实际应用。
The output from the Canny Edge detection algorithm
上述两种技术都使用图像分割,并且在不理解我们试图检测的对象(即屋顶)的上下文和内容的情况下工作。当我们用物体(即屋顶)的样子来训练算法时,我们可能会得到更好的结果。卷积神经网络是理解图像上下文和内容的最先进技术。
如前所述,我们希望将图像分割成两部分——屋顶或非屋顶。这是一个语义切分问题。语义分割试图将图像划分成语义上有意义的部分,并将每个部分分类到预定的类别之一。
Semantic Segmentation (picture taken from www.jeremyjordan.me/semantic-se…)
在我们的例子中,图像的每个像素都需要被标记为屋顶的一部分或者不是。
We want to segment the image into two segments — roof and not roof(left) for a given input image(right).
步骤 2:生成训练数据
为了训练 CNN 模型,我们需要一个带有印度建筑及其相应面具的屋顶卫星图像的数据集。没有可用于印度建筑物带有面具的屋顶图像的公共数据集。所以,我们必须创建自己的数据集。一组学生标记了图像并创建了蒙版图像(如下)。
Generating dataset by marking the edges
这是屏蔽后的最终输出。
虽然我们知道 U-Net 模型使用较少数量的图像作为数据,但首先,我们的训练集中只有 20 张图像,这远远低于任何模型,甚至我们的 U-Net 也无法提供结果。处理较少数据的最流行的技术之一是数据扩充。通过数据扩充,我们可以使用数据集中的图像生成更多的数据图像,只需在原始图像中添加一些基本的改变。
例如,在我们的例子中,任何屋顶图像当旋转几度或水平或垂直翻转时,将作为新的屋顶图像,假设旋转或翻转是以精确的方式,对于屋顶图像和它们的遮罩。我们在已经标记的图像上使用 Keras 图像生成器来创建更多的图像。
Data Augmentation
步骤 3:预处理输入图像
我们试图锐化这些图像。我们使用了两种不同的锐化滤镜——低/软锐化和高/强锐化。锐化之后,我们应用双边滤波器来减少锐化产生的噪声。下面是一些用于锐化的 Python 代码行
低锐化滤波器:
高锐化滤波器
下面是输出。
我们将单独写一篇关于锐化图像的文章,所以这里将跳过更多的细节。
步骤 4:训练和验证模型
我们生成了 445 幅图像的训练数据。接下来,我们选择使用 U-Net 架构。U-net 最初用于生物医学图像分割,但由于它能够达到良好的效果,U-net 正在应用于各种其他任务。是图像分割的最佳网络架构之一。在我们使用 U-Net 模型的第一种方法中,我们选择使用学习率为 0.0001 的 RMSProp 优化器,具有骰子损失的二元交叉熵(这里的实现来自)。我们运行了 200 个时期的训练,平均(最后 5 个时期)训练骰子系数是. 6750,验证骰子系数是. 7168
以下是我们从验证集(40 幅图像)中获得的第一种方法的结果:
Predicted (left), Target (right)
Predicted (left), Target (right)
正如你所看到的,在预测的图像中,在预测的遮罩的中间和角落有一些建筑物结构的 3D 痕迹。我们发现这是由于骰子的丢失。接下来,我们使用学习速率为 1e-4、衰减速率为 1e-6 的 Adam 优化器来代替 RMSProp。我们使用 IoU 损耗而不是 BCE+Dice 损耗和 Keras 的二进制精度指标。训练进行了 45 个周期。平均(最后 5 个时期)训练精度为:0.862,平均验证精度为:0.793。以下是来自第二种方法的验证集上的一些预测掩码:
这是测试数据的结果
Test data
Test data
我们很高兴看到目前的结果,并希望通过更多的数据进一步改善结果。
最后,我们还要感谢 Abhigyan 和 Aman 提供的训练数据。如果有人想进一步帮助我们,请加入我们的 git 回购或联系 rudradeb@omdena.com