TowardsDataScience 博客中文翻译 2016~2018(五十)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

用 d3 构建共现矩阵分析学位论文中的重叠主题

原文:https://towardsdatascience.com/building-a-co-occurrence-matrix-with-d3-to-analyze-overlapping-topics-in-dissertations-fb2ae9470dee?source=collection_archive---------4-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Thanks Min An!

我硕士学位研究的目标是在不同领域的研究人员之间激发新的合作机会。但在此之前,我需要后退一步,看看是否有任何合作已经发生。酷,但是如何开始做这件事呢?

当作者为他们的作品写摘要时,他们也会添加一些关键词。我的第一个猜测是,通过这些关键词,我可以开始看到来自不同知识领域的论文是如何相互作用的。

于是我把自己大学(2016)的所有学位论文都找来,构建了一个矩阵,把关键词重叠的作品可视化。

我有两项主要工作:获取数据构建 d3 可视化

1️⃣——获取数据

每次学生拿到学位,她都需要把最终论文发到这个网站:http://repositorio.ufpe.br/。为了从这些论文中获取关键词,我必须:

  1. 获取所有学位论文的列表
  2. 下载 pdf 文件
  3. 提取文本并获得每篇论文的关键词

🎓1 —获取所有论文的列表

多亏了 Scrapy,这部分比我想象的要容易得多。为了用框架从网站中提取数据,我们需要编写一个蜘蛛。

“蜘蛛是你定义的类,Scrapy 用它从一个网站(或一组网站)抓取信息。”来源

在 Spider 类中,我们定义了基本 URL,Scrapy 应该如何处理分页,还定义了将要提取的数据。

我得到了这个元数据:

{            
'author',
'title',
'date':            
'abstract',            
'research_field',            
'url_to_pdf'     
}

📁2-下载 pdf

我构建了一个 python 脚本,使用请求一个优雅而简单的 Python HTTP 库,为人类而建

with open(new_file_name, 'wb') as pdf:
    temp = requests.get("[http://repositorio.ufpe.br](http://repositorio.ufpe.br)" + link, stream=True)
    for block in temp.iter_content(512):
        if not block:
            breakpdf.write(block)

🔡3 —提取文本并获得每篇论文的关键词

对于这个任务,我使用了 PyPDF2空间。通常作者把关键词放在摘要下面,所以我浏览 PDF 的页面,如果我找到像“关键词”和“ palavras-chave ”(在葡萄牙语中是关键词的意思)这样的词,我会把内容保存在一个 txt 文件中。

我使用 spaCy 来标记文本,因为 PDF 提取并不完美。

在这个过程之后,我得到了包含“关键词”的每一页的文本。为了只得到关键词本身,我遍历单词,得到所有跟在“关键词”后面的单词,因为它们通常是页面中的最后一项。然后,我最后将数据加载到 dataframe 中进行一些转换,并将其保存到 csv 文件中。

关键词对我想做的事情有好处吗?

我注意到的一件事是,关键字可能非常普通。如果我的目标是检查不同研究领域的主题如何相互作用,我应该分析摘要,因为在那里有更多的机会找到相互作用的点。

让我们举一个真实的例子来说明一下。对于本论文:“农民工大学生适应中的认知和非认知方面”的关键词是:

  • 学术经历
  • 弹性
  • 执行职能
  • 论证
  • 大学生

但在阅读摘要时,我发现了这个:

“为了实现这些目标,进行了以下分析:描述性统计、T 检验、方差分析(ANOVA)、相关探索性双变量分析、探索性因子分析和多元线性回归。”

这篇论文来自认知心理学的研究生项目,但它的主题来自统计学,也可能来自计算机科学,对吗?关键字不能显示这一点。因此,我的下一步将是利用摘要中的文本建立一个深度学习模型。

但是我们需要从某个地方开始,所以我做了一些简单的事情:从每个研究领域得到前 10 个关键词,我假设这些词可以用来描述这个领域。

首先去做,然后做对,然后做得更好——艾迪·osmani‏

好了,现在我们准备开始构建可视化。

2️⃣——构建可视化

我们将使用迈克·博斯托克 悲惨世界共现矩阵作为我们的“模板”。让我们首先创建一个矩形,并将其添加到背景中:

var margin = {
        top: 285,
        right: 0,
        bottom: 10,
        left: 285
    },
    width = 700,
    height = 700;
var svg = d3.select("graph").append("svg").attr("width", width).attr("height", height);svg.append("rect")
    .attr("class", "background")
    .attr("width", width - margin.right)
    .attr("height", height - margin.top)
    .attr("transform", "translate(" + margin.right + "," + margin.top + ")");svg.append("rect")
    .attr("class", "background")
    .attr("width", width)
    .attr("height", height);

现在我们可以深入了解 d3 的魔力了。

1-转换数据

数据看起来像这样:

{
    "nodes": [{
            "group": "humanas",
            "index": 0,
            "name": "ADMINISTRAÇÃO"
        },
        {
            "group": "humanas",
            "index": 1,
            "name": "ANTROPOLOGIA"
        },
        [...]
    ],
    "links": [{
            "source": 0,
            "target": 0,
            "value": 0.0
        }, {
            "source": 0,
            "target": 1,
            "value": 2.0
        }, 
        [...]
    ]
}

我们将逐行构建矩阵。首先,我们读取数据并为每一行创建一个数组。

d3.json("data/data.json", function(data) {
    var matrix = [];
    var nodes = data.nodes;
    var total_items = nodes.length;// Create rows for the matrix
    nodes.forEach(function(node) {
        node.count = 0;
        node.group = groupToInt(node.group);matrix[node.index] = d3.range(total_items).map(item_index => {
            return {
                x: item_index,
                y: node.index,
                z: 0
            };
        });
    });
    // Fill matrix with data from links and count how many times each item appears
    data.links.forEach(function(link) {
        matrix[link.source][link.target].z += link.value;
        matrix[link.target][link.source].z += link.value;
        nodes[link.source].count += link.value;
        nodes[link.target].count += link.value;
    });});

因为我们将逐行构建方块,所以我们需要浏览每一行,然后浏览每一列。

2-放置正方形并添加颜色

为了将每个方块放置在正确的位置,我们将使用 d3.scaleBand()标尺。这个 scale 的作用是获得一个包含值的数组,然后为每个数组项分配一个坐标。每个项目的所有坐标加上带宽值加起来就是总宽度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

How d3.scaleBand() words

这个规模令人敬畏,因为我们不需要手工计算。

要给每个方块添加颜色,您可以使用 d3.schemeCategory20 标度。

这是大量的新代码,让我们来看看:

d3.json("data/data.json", function(data) {[...] //transform the datavar matrixScale = d3.scaleBand().range([0, width]).domain(d3.range(total_items));
var opacityScale = d3.scaleLinear().domain([0, 10]).range([0.3, 1.0]).clamp(true);
var colorScale = d3.scaleOrdinal(d3.schemeCategory20);// Draw each row (translating the y coordinate) 
    var rows = svg.selectAll(".row")
        .data(matrix)
        .enter().append("g")
        .attr("class", "row")
        .attr("transform", (d, i) => {
            return "translate(0," + matrixScale(i) + ")";
        });var squares = rows.selectAll(".cell")
        .data(d => d.filter(item => item.z > 0))
        .enter().append("rect")
        .attr("class", "cell")
        .attr("x", d => matrixScale(d.x))
        .attr("width", matrixScale.bandwidth())
        .attr("height", matrixScale.bandwidth())
        .style("fill-opacity", d => opacityScale(d.z)).style("fill", d => {
            return nodes[d.x].group == nodes[d.y].group ? colorScale(nodes[d.x].group) : "grey";
        })
        .on("mouseover", mouseover)
        .on("mouseout", mouseout);
});

我们还创建了一个比例来设置每个方块的不透明度。在我们的例子中,不透明度值是有至少一个关键字匹配的论文的数量。一个关键词匹配意味着一个关键词同时出现在两篇论文中。

3-添加列

我们对行做了同样的事情,但是现在我们旋转它们:

d3.json("data/data.json", function(data) {

   [...] //transform the data [...] //place the squares and add colorvar columns = svg.selectAll(".column")
        .data(matrix)
        .enter().append("g")
        .attr("class", "column")
        .attr("transform", (d, i) => {
            return "translate(" + matrixScale(i) + ")rotate(-90)";
        });
});

4-添加文本标签

为了添加占位符,我们使用行和列选择来添加一个 svg 文本元素。

d3.json("data/data.json", function(data) {

    [...] //transform the data [...] //place the squares and add color [...] //add columnsrows.append("text")
        .attr("class", "label")
        .attr("x", -5)
        .attr("y", matrixScale.bandwidth() / 2)
        .attr("dy", ".32em")
        .attr("text-anchor", "end")
        .text((d, i) => capitalize_Words(nodes[i].name));

    columns.append("text")
        .attr("class", "label")
        .attr("y", 100)
        .attr("y", matrixScale.bandwidth() / 2)
        .attr("dy", ".32em")
        .attr("text-anchor", "start")
        .text((d, i) => capitalize_Words(nodes[i].name));
});

5-添加排序功能

重新组织矩阵行有助于分析。在我们的例子中,我们可以按照字母顺序、每个项目(即研究领域)的连接数量以及每个知识领域的聚类来组织它们。使用 d3.scaleBand()矩阵很容易做到这一点。

数组的每一项都对应一个程序 id,所以如果我们以不同的方式对数组排序,我们会得到每个矩阵方块不同的坐标。

// Precompute the orders.
var orders = {
    name: d3.range(total_items).sort((a, b) => {
        return d3.ascending(nodes[a].name, nodes[b].name);
    }),
    count: d3.range(total_items).sort((a, b) => {
        return nodes[b].count - nodes[a].count;
    }),
    group: d3.range(total_items).sort((a, b) => {
        return nodes[b].group - nodes[a].group;
    })
};

然后,我们向 html select 标记添加功能:

d3.select("#order").on("change", function() {
    changeOrder(this.value);
});function changeOrder(value) {
        matrixScale.domain(orders[value]);
        var t = svg.transition().duration(2000);

        t.selectAll(".row")
            .delay((d, i) => matrixScale(i) * 4)
            .attr("transform", function(d, i) {
                return "translate(0," + matrixScale(i) + ")";
            })
            .selectAll(".cell")
            .delay(d => matrixScale(d.x) * 4)
            .attr("x", d => matrixScale(d.x));

        t.selectAll(".column")
            .delay((d, i) => matrixScale(i) * 4)
            .attr("transform", (d, i) => "translate(" + matrixScale(i) + ")rotate(-90)");
    }

为了增加一个好的效果,我们还添加了一个动画的转换。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The final result

就是这样!现在我们只是添加一些白线,并为每个方块添加一个工具提示。你可以在这里看到最终结果或者在这里查看最终代码

这只是一个开始,现在我需要做的是如何显示关键词和论文。当然,我会回到这里与你分享,哈哈

感谢阅读!😁

你觉得这篇文章有帮助吗?我尽力每个月写一篇深入的文章,当我发表新的文章时,你可以收到电子邮件。

在 Keras 中构建卷积神经网络(CNN)

原文:https://towardsdatascience.com/building-a-convolutional-neural-network-cnn-in-keras-329fbbadc5f5?source=collection_archive---------0-----------------------

深度学习正成为机器学习的一个非常受欢迎的子集,因为它在许多类型的数据上具有高水平的性能。使用深度学习对图像进行分类的一个很好的方法是建立一个卷积神经网络(CNN)。Python 中的 Keras 库使得构建 CNN 变得非常简单。

计算机使用像素来看图像。图像中的像素通常是相关的。例如,某一组像素可以表示图像中的边缘或一些其他图案。卷积用这个来帮助识别图像。

卷积将像素矩阵与滤波器矩阵或“内核”相乘,并对乘积值求和。然后卷积滑动到下一个像素,并重复相同的过程,直到覆盖了所有的图像像素。这个过程如下图所示。(关于深度学习和神经网络的介绍,可以参考我的深度学习文章这里)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CNN (image credit)

在本教程中,我们将使用流行的 mnist 数据集。该数据集由 70,000 张 0-9 的手写数字图像组成。我们将尝试通过 CNN 确认他们的身份。

加载数据集

mnist 数据集是作为 Keras 库的一部分方便地提供给我们的,因此我们可以轻松地加载数据集。在数据集中提供的 70,000 幅图像中,60,000 幅用于训练,10,000 幅用于测试。

当我们加载下面的数据集时,X_train 和 X_test 将包含图像,y_train 和 y_test 将包含这些图像所代表的数字。

from keras.datasets import mnist#download mnist data and split into train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()

探索性数据分析

现在让我们来看看数据集中的一幅图像,看看我们正在处理什么。我们将绘制数据集中的第一幅图像,并使用“shape”函数检查其大小。

import matplotlib.pyplot as plt#plot the first image in the dataset
plt.imshow(X_train[0])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#check image shape
X_train[0].shape

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

默认情况下,mnist 数据集中每个图像的形状都是 28 x 28,所以我们不需要检查所有图像的形状。当使用真实世界的数据集时,你可能没有这么幸运。28 x 28 也是一个相当小的尺寸,所以 CNN 可以很快地浏览每张图片。

数据预处理

接下来,我们需要在训练模型时将数据集输入(X_train 和 X_test)调整为模型预期的形状。第一个数字是图像的数量(X_train 为 60,000,X_test 为 10,000)。然后是每个图像的形状(28x28)。最后一个数字是 1,表示图像是灰度的。

#reshape data to fit model
X_train = X_train.reshape(60000,28,28,1)
X_test = X_test.reshape(10000,28,28,1)

我们需要“一次性编码”我们的目标变量。这意味着将为每个输出类别创建一个列,并为每个类别输入一个二进制变量。例如,我们看到数据集中的第一个图像是 5。这意味着数组中的第六个数字将是 1,而数组的其余部分将填充 0。

from keras.utils import to_categorical#one-hot encode target column
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)y_train[0]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

构建模型

现在我们已经准备好构建我们的模型了。代码如下:

from keras.models import Sequential
from keras.layers import Dense, Conv2D, Flatten#create model
model = Sequential()#add model layers
model.add(Conv2D(64, kernel_size=3, activation=’relu’, input_shape=(28,28,1)))
model.add(Conv2D(32, kernel_size=3, activation=’relu’))
model.add(Flatten())
model.add(Dense(10, activation=’softmax’))

我们将使用的模型类型是顺序的。顺序是在 Keras 中建立模型的最简单的方法。它允许你一层一层地建立模型。

我们使用“add()”函数向模型中添加层。

我们的前两层是 Conv2D 层。这些卷积层将处理我们的输入图像,这些图像被视为二维矩阵。

第一层中的 64 和第二层中的 32 是每层中的节点数。根据数据集的大小,这个数字可以调高或调低。在我们的例子中,64 和 32 工作得很好,所以我们现在坚持使用它。

核大小是我们卷积的滤波器矩阵的大小。因此,内核大小为 3 意味着我们将有一个 3×3 的滤波器矩阵。回头参考介绍和第一张图片来复习一下。

激活是层的激活功能。我们将为前两层使用的激活函数是 ReLU,或修正线性激活。这种激活函数已被证明在神经网络中工作良好。

我们的第一层也接受一个输入形状。这是前面看到的每个输入图像的形状,28,28,1,1 表示图像是灰度的。

在 Conv2D 层和密集层之间,有一个“展平”层。展平用作卷积层和致密层之间的连接。

“密集”是我们将在输出图层中使用的图层类型。密集是一种标准图层类型,在许多情况下用于神经网络。

我们的输出层将有 10 个节点,每个节点对应一个可能的结果(0–9)。

激活是“softmax”。Softmax 使输出总和达到 1,因此输出可以解释为概率。然后,该模型将根据哪个选项的概率最高来进行预测。

编译模型

接下来,我们需要编译我们的模型。编译模型需要三个参数:优化器、损失和指标。

优化器控制学习速率。我们将使用“亚当”作为我们的优化器。在许多情况下,Adam 通常是一个很好的优化器。adam 优化器在整个训练过程中调整学习率。

学习率决定了计算模型最佳权重的速度。较小的学习率可能会导致更准确的权重(直到某一点),但计算权重所需的时间会更长。

我们将使用‘分类交叉熵’作为损失函数。这是最常见的分类选择。分数越低,表示模型的性能越好。

为了使事情更容易解释,当我们训练模型时,我们将使用“准确性”度量来查看验证集的准确性分数。

#compile model *using accuracy to measure model performance*
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

训练模型

现在我们将训练我们的模型。为了进行训练,我们将对我们的模型使用带有以下参数的“fit()”函数:训练数据(train_X)、目标数据(train_y)、验证数据和历元数。

对于我们的验证数据,我们将使用我们的数据集中提供给我们的测试集,我们已经将它分为 X_test 和 y_test。

历元数是模型在数据中循环的次数。在一定程度上,我们运行的时代越多,模型就会改进得越多。此后,模型将在每个时期停止改进。对于我们的模型,我们将把历元的数量设置为 3。

#train the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

经过 3 个时期后,我们在验证集上达到了 97.57%的准确率。这是一个非常好的开始!恭喜你,你现在已经建立了一个 CNN!

使用我们的模型进行预测

如果您想要查看我们的模型对测试数据做出的实际预测,我们可以使用 predict 函数。预测函数将给出一个包含 10 个数字的数组。这些数字是输入图像代表每个数字(0-9)的概率。编号最高的数组索引表示模型预测。每个数组的总和等于 1(因为每个数字都是一个概率)。

为了显示这一点,我们将显示测试集中前 4 幅图像的预测。

注意:如果我们有新数据,我们可以将新数据输入到 predict 函数中,以查看我们的模型对新数据做出的预测。由于我们没有任何新的未知数据,我们现在将使用测试集显示预测。

#predict first 4 images in the test set
model.predict(X_test[:4])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,我们的模型预测了前四幅图像的 7、2、1 和 0。

我们来对比一下这个和实际结果。

#actual results for first 4 images in test set
y_test[:4]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实际结果显示,前四个图像也是 7、2、1 和 0。我们的模型预测正确!

感谢阅读!本教程的 Github 库可以在这里找到!

建立带有张量流对象检测的定制掩模 RCNN 模型

原文:https://towardsdatascience.com/building-a-custom-mask-rcnn-model-with-tensorflow-object-detection-952f5b0c7ab4?source=collection_archive---------3-----------------------

用数据做酷事!

您现在可以使用 Tensorflow 对象检测库构建一个自定义的遮罩 RCNN 模型!掩模 RCNN 是一个实例分割模型,可以逐个像素地识别任何对象的位置。本文是我广受欢迎的帖子的第二部分,在这里我解释了 Mask RCNN 模型的基础知识,并在视频上应用了一个预先训练好的 Mask 模型。

训练掩模模型比训练对象检测模型稍微复杂一些,因为在训练时也需要对象掩模。我花了一些迭代来弄清楚这个过程,我在这里分享了关键的细节。我在一个玩具上训练了一个面具 RCNN 模型。参见下面的演示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Custom Mask RCNN Model on a toy

你可以在我的 Github repo 上找到代码。

如果你有一个有趣的项目需要帮助,请联系我在 priya.toronto3@gmail.com

1)收集数据并创建掩码

常规的对象检测模型要求您使用边界框来注释图像中的对象。然而,蒙版模型的输入是带有蒙版的 PNG 文件。请参见下面的示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Object Mask — Toy

利用这个二进制掩模图像,模型可以提取边界框的坐标以及对象的像素位置。

我用来创建蒙版的工具是像素注释工具。这个工具的输出是 API 想要的格式的 PNG 文件。您可以在注释工具中打开图像,并使用画笔给玩具“上色”。将外部着色并标记为感兴趣区域之外也很重要。我花了大约 20 秒的时间来着色和保存每一张还不错的蒙版图片。如果你想让蒙版非常精确,那么在边缘使用精细的笔刷。通过我的实验,我观察到训练一个掩模 RCNN 模型比训练一个更快的 RCNN 模型需要更少的图像来达到相同的精度。

2。生成 TF 记录

Tensorflow 对象检测模型的输入是一个 TFRecord 文件,您可以将其视为图像、边界框、遮罩等的压缩表示,以便在训练模型时将所有信息放在一个地方。创建这个文件最简单的方法是使用一个类似的脚本,该脚本可用于 pet 数据集的 TFRecord,并针对我们的情况对其进行一点修改。我已经分享了我在 Github repo 上使用的脚本。

您还需要创建一个 label.pbtxt 文件,用于将标签名称转换为数字 id。对我来说,这很简单

item {
 id: 1
 name: ‘toy’
}

3。选择模型超参数

现在你可以选择你想要使用的遮罩模型。Tensorflow API 提供了 4 个模型选项。我选择了掩模 RCNN 盗梦 V2,这意味着盗梦 V2 被用作特征提取器。该模型在推理时间上是最快的,尽管它可能不具有最高的准确性。模型参数存储在配置文件中。我为相同类型的 coco 模型使用了配置文件,并更新了类的数量和路径,使大多数模型参数保持不变。

4。训练模型

锁定输入文件和参数后,您可以开始培训。我能够在几个小时内在 CPU 上训练这个模型。您可以同时在两个独立的终端上启动培训作业和评估作业。启动 tensorboard 监控性能。当我看到损失趋于平稳时,我停止了训练。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Tensorboard 中最酷的事情是,随着训练的进行,它允许你在测试集的样本图像上可视化预测。下面的 gif 显示了随着训练的进行,模型变得确定其遮罩和边界框预测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5。在您的定制视频上测试模型

为了测试模型,我们首先选择一个模型检查点(通常是最新的)并将其导出到一个冻结的推理图中。这个脚本也在我的 github 上。我在我的 Iphone 上录制的新视频中测试了这个模型。正如在我的上一篇文章中,我使用 Python moviepy 库将视频解析成帧,然后在每一帧上运行 object detector,并将结果整理回视频中。

后续步骤

未来的额外探索

  • 我想将这个模型扩展到同一张图片中的多个类别的物体。TFRecord creator 脚本需要一些修改,这样它才能正确地为每个对象分配正确的标签和掩码
  • 正如我提到的,我在这个项目中使用了最轻量级的模型。我很想看看该套件中速度较慢的其他型号在检测准确性方面的表现

给我一个❤️,如果你喜欢这个职位:)希望你拉代码,并尝试自己。

我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/来看看我们吧。

你也可以在 https://medium.com/@priya.dwivedi 的看到我的其他作品

如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我

参考文献:

为交互式群组分析构建仪表板

原文:https://towardsdatascience.com/building-a-dashboard-for-interactive-cohort-analysis-6a9d904bcbda?source=collection_archive---------2-----------------------

我们如何留住不同的用户群?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Pixabay

介绍

群组是指具有共同定义特征的一组受试者。我们可以观察一个群体在不同时间的表现,并与其他群体进行比较。群组用于医学、心理学、计量经济学、生态学和许多其他领域,以在时间上的间隔进行交叉分析(比较受试者之间的差异)。(来源)

在这篇文章中,我们将重点观察用户在使用 Jupyter 笔记本的产品中的行为。

产品业务中保留的重要性从延续到之前的,在那里我们模拟了产品使用数据,可以总结为三个数字:

  • 95% =重新吸引用户与获得新用户的成本差异 ( 来源)
  • 5% =可将收入提高至 95%的留存额增加量 ( 来源)
  • 77% =前三天每日活跃用户流失的平均百分比 ( 来源)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Trying to grow a product without being able to retain users

检查留存率的关键问题是如何快速、方便地调查不同用户群在产品上平均花费了多少时间。为了做到这一点,可视化需要是交互式的,我们可以通过构建一个仪表板来实现。

我们从上一篇文章中模拟的数据集开始(略有改动),该数据集由 10.000 个用户组成,具有三个分类变量:国家(值为 NL、FR 和 AU)、平台(值为 iOS 和 Android)和 user_registered(值为 True 和 False)。小的调整和解释包含在笔记本中。

这篇文章中的所有代码都可以在 GitHub 上的笔记本中找到。

代码

我们从导入所有必需的依赖项开始:

接下来,我们打开包含所有产品使用数据的 CSV:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Preview of all_user_data_df

我们列出了所有三个变量的值,稍后我们将根据这些值对用户进行细分:

细分用户

下一步是细分用户。我们选择想要分割的特性的值:

这方面的一个例子是对 iOS 平台上未注册的荷兰用户进行细分:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Segmentation example

构建群组

第一步

之后,我们在分割的数据帧上建立群组。第一步是创建一个函数,为每个用户定义一个群组(当用户开始使用产品时):

然后,我们对分段数据帧使用函数:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二步:

我们将所有事件和用户分组:

我们将该函数应用于现有数据框:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第三步:

我们基于 usage_period 为每个群组定义群组周期:

Cohort_period 0 对应的是使用产品第一个月的用户数和事件数。群组周期 1
对应于使用产品的第二个月的相同数据,以此类推。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第四步:

我们重新索引数据帧,并设置群组组和群组周期作为索引。我们还计算了每个群组第一个月的用户数量。这两者对于
在下一步计算保留都是必要的:

我们将其应用于群组数据帧:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Number of users in each cohort

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Sum of all events with unique users in each cohort period for the cohort group 2016–02

第五步:

然后我们计算每个群体的保持率。我们在 cohort_group(索引为 0 的第一列)上拆分,将索引中的唯一值透视到各个列中。然后,我们将每个群组中开始使用该产品的用户数量除以每个相应月份中继续使用该产品的用户数量(1 =第二个月,2 =第三个月,…)。

值~ 0.2658 对应于 2016–02 年群组中在第二个月使用该产品的用户数除以在第一个月使用该产品的用户数。它回答了这样一个问题:在 2016 年至 2002 年期间,有多少用户在使用产品的第二个月继续使用该产品?(26.6%)

值~ 0.2658 对应于 2016–02 年群组中在第二个月使用该产品的用户数除以在第一个月使用该产品的用户数。它回答了这样一个问题:在 2016 年至 2002 年期间,有多少用户在使用产品的第二个月继续使用该产品?(26.6%)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Cohort reindex and group size

我们将上述 5 个群组步骤中的所有函数合并为一个函数,稍后用于交互式可视化。
它的输入是细分数据,输出是每个群组的用户留存率:

静态可视化

然后,我们使用所有群组函数构建的 user_retention 数据框架用于可视化不同的用户群组如何随着时间的推移保留在产品中。

保留曲线

首先,我们可视化保留曲线。每条线对应不同的组群。每条曲线上方的空间越小,保留的用户百分比就越高。或者相反,曲线越快下降到低值,我们在吸引用户继续使用产品方面就越不成功。

我们使用蓝色色图,用更深的蓝色来显示后面的群组。我们看不出不同人群的记忆有任何明显差异。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Visualization — retention curves

热图

接下来,我们用热图来直观显示保留情况。这一次我们使用了二进制颜色图,其中较深的颜色对应于特定群组在特定群组期间保留的较高百分比的用户

我们可以再次看到,保持率不会随着时间的推移而发生很大变化。25%的用户在使用后的第二个月内缓慢但持续地流失(这也可以在上面的 user_retention 数据框中看到)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Visualization — heatmap

交互式可视化

最后一步包括组合所有已构建的功能,并以这样一种方式进行组合,即我们可以根据指定的变量值同时对用户进行细分,构建群组,并通过曲线和热图直观显示保留情况。

通过使用 interact 函数,我们可以选择要分段的变量值。这提供了一个交互式的重新计算和可视化,因此我们可以比较我们的用户的不同部分的保留。

我们可以在下面的例子中观察到,与 Android 用户相比,iOS 用户的保留率更低,这是通过上述调整(包含在笔记本中)模拟的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Dashboard for interactive cohort analysis

已用资源

部分队列分析主要基于格雷戈·瑞达的帖子。如果您想更深入地了解数据建模部分,推荐阅读本书。

用 Dash (plotly)、AWS 和 Heroku 构建仪表板

原文:https://towardsdatascience.com/building-a-dashboard-with-dash-plotly-aws-and-heroku-jean-michel-d-d102e26ac8c1?source=collection_archive---------9-----------------------

你可以在这个 Github 库 中找到这个仪表盘的模板。而你在我的 网站 上还有一些其他的代码样本。

你好,在这篇文章中,我将解释我创建一个显示一些个人信息的仪表板的过程。为了实现这个项目,我决定使用 Dash 一个由 Plotly 一家加拿大公司开发的 Python 框架,该公司开发了 Plotly 库来实现交互式数据可视化。

在这篇文章中,我将解释:

  • 所涉及的数据
  • 这个项目的后端(以及一些自己制作的技巧)
  • 仪表板、他的部署和组件

tha 数据简介

在我们的日常生活中,我们会产生大量的数据,作为一名数据科学家,我喜欢摆弄数据。就我而言,我有一些智能设备,如智能体重秤或智能手环,我每天都在使用,我有一些应用程序来监控我生活的某些方面,如 Strava,在这种情况下,我对以下数据源感兴趣:

  • 我来自诺基亚设备的智能秤数据
  • 我在 Strava 的跑步训练
  • 我的交叉训练

对于前两个数据源,我有一个应用程序来跟踪不同指标的演变

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这很好,但是一个服务/设备=一个应用程序,对发生的事情进行快速监控不是很有效。但是,谁说应用程序说潜在的开发者应用编程接口,在这种情况下,有一个(诺基亚和斯特拉发)。

最后一个数据源更像是一个“老派”数据源,因为它只是一个谷歌电子表格,我每周都会用我在 crossfit 会议期间完成的不同练习来填充它。我发现这是一个很好的和有效的方法来跟踪我在盒子上做了什么,并看到进展。有一个 API 为我提供了访问这个数据源的可能性。

所以所有的数据都可以用于我的项目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在让我们看看后端的结构,它将为仪表板公开数据。

后端描述

对于这个项目,后端托管在 Amazon Web Services 上。有一个项目后端的图解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个后端围绕两个元素构建,一个是用于从不同 API 收集数据的数据管道,另一个是提供预测体重和脂肪比率可能性的 API。

构建数据管道

对于数据的收集,管道托管在 Amazon Web Services 中,我有一个 EC2 实例(来自 AWS 自由层的实例)定期(每 3 小时)收集不同来源推送的新数据。收集的数据被清理并发送到 3 个不同的 DynamoDB 表中。

管道非常简单,对于 DynamoDB 表的配置,我设置了 2 个单位的非常小的写入容量,但是对于读取,我决定使用自动缩放功能,根据流量设置 10 到 50 个单位之间的动态读取容量。

部署预测模型

免责声明:这不是一个超级高效的模型,但至少它存在

这个模型非常简单,但不是非常有效,我目前有一个体重模型和另一个脂肪比例模型。

这是一个简单的 KNN 模型,在每种情况下,它接受以下输入:

  • 距离在一周内跑完
  • 时间在一周中流逝
  • 交叉健身的次数
  • 交叉体能训练中携带的平均重量(带重量)

该模型将预测体重和脂肪比率的每周变化。

该模型将每周更新,并发送一个 S3 桶。为了直接从仪表板访问模型,我创建了一个带有 Flask 的 API,我将它部署在一个带有 Zappa 包的 Lambda 中,我在 messenger chatbot 上的文章中使用了这个包。

没什么特别的,但一切都正常。现在让我们关注项目的数据收集部分,以填充 Dynamodb 表。

数据收集

正如我前面说过,有三个 API 连接到我们的后端:

  • 诺基亚 API
  • 斯特拉发 API
  • Google drive API

让我们看看每个数据源。

诺基亚 API

有了这个 API,我从 2017 年 2 月开始收集数据,从 2014 年 7 月开始使用智能手环,从 2014 年 11 月开始使用智能体重秤,我喜欢这些设备,它们的设计很好,应用也很好。我希望所有关于诺基亚的谣言都是错误的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我创建了一个调用带有 GET 请求的 API 的脚本(就长度而言非常长),老实说,我认为诺基亚的 API 是我迄今为止使用的最具技术性的 API(相比之下,Netatmo 是我最容易使用的 API),但至少在过去的一年里它一直在工作。

为了这个项目,我试图做一些调整,我打破了一切,所以我决定使用这个 GitHub 库来管理与 API 的连接,它工作得很好!!

斯特拉发 API

我从 2016 年 9 月开始使用 Strava,之前我是一名 Runkeeper 和 Runstatic guy,但我在 2017 年到达英国时决定转换。

老实说,Strava 的 API 非常容易使用,只需创建一个应用程序获取您的访问令牌,并在 API 文档中发出以下 get 请求

交叉拟合数据(Google drive API)

我目前从 2017 年 8 月开始练习 crossfit,正如我之前所说,我在谷歌工作表的电子表格中监控我的训练。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是一种老式的方法,但我发现它比应用程序收集数据更有效。

我正在使用 Google Drive API 和 Twillio 制作的这个教程来设置一个将收集数据的 python 脚本。另一种方法是使用 Sheetsu ,因为我有一些谷歌信用,我决定不使用这项服务(我过去曾使用 Alexa 技能,它很棒)。

数据存储(DynamoDB 和 Boto3)

收集完所有这些数据后,用 boto3 连接 DynamoDB 表就非常容易了。

现在我们有了后端的数据,让我们对它进行一些分析。

分析学

就像我之前说过的,对于这个数据源,我将把重点放在秤的数据上,参数是体重和脂肪比率

下图显示了我过去一年的体重历史数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如您所看到的,在过去一年中,权重的演变中有很多噪声,因此我将对信号应用滚动平均函数,使其看起来更好,并保持行为趋势。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最有趣的窗口似乎是 7 天窗口,因为它保留了局部变化,但不受会破坏数据分析的滞后效应的影响。

脂肪率变化的结论是相同的。

要分析的另一个元素可以是指标的每周变化,以说明好的和坏的一周,并可能检测有趣的时期(例如,肌肉或脂肪的增加)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

脂肪增加和体重增加之间存在线性关系,但我不想展示它,因为我知道在某些阶段,你可以增加体重,但减少脂肪(增加肌肉),所以这种关系并不存在。

让我们看看斯特拉发的数据。

运行数据

我基本上每周跑步一次,平均不到一小时跑 10 公里左右。

这个数据源的有趣指标是:

  • 距离
  • 平均速度
  • 立面图
  • 时间流逝了

一些非常简单的条形图可以显示这些参数的演变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有趣的一点是把距离、平均速度和海拔高度交叉在一起,看最后一个参数对速度的影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到海拔对我平均速度的影响。但是说实话,这个数据源并不令人兴奋(我也在收集跑步会话的细节,比如会话期间的速度等等,但是我目前对这些数据什么也没做)。

我们来看看 crossfit 的数据。

交叉拟合数据

我从 2017 年 8 月开始练习 crossfit,每周 3 次,我绝对不是专业人士。下图显示了一次训练中的总重量与重复次数的函数关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个数字很好地说明了 crossfit 中可能发生的各种情况,有些情况下你可以负重很多,但不需要太多的重复,相反,有些情况下你可以重复很多,但不需要太多的重量。

另一个有趣的部分是观察一次锻炼期间体重的变化(是的,我有一点进步)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,数据的质量取决于我在电子表格中正确书写的动机,但信息量是相当有趣的。

现在是时候创建显示所有这些信息的仪表板了。

仪表板的设计

对于这个仪表板,我对应用程序的要求是:

  • 易于部署且成本低廉
  • 访问仪表板的身份验证流程

我看到人们说“哦,你应该用 R Shiny 来创建你的应用程序,因为…”我会说。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

老实说,我不是 R 的忠实粉丝,我知道如何使用它,但当我想做更多与数据分析无关的高级计算时,我发现它非常有限。

而且我想写一篇关于 dash 的文章,那我们就 Dash 吧。

对我来说,仪表板上有以下部分很重要:

  • 数据概述(如最后一个值和一些快速统计数据)
  • 每个数据源的一个部分
  • 我可以使用一点 ML 的预测部分

我邀请你使用这个 Github 库 中的代码和环境来启动。

仪表板演示

在这一节中,我将描述并展示他的最新版本的仪表板(在最后的 css“政变”之前)。

对于应用程序的风格,我使用了以下资源:

概述部分

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这一节中,我们的想法是向用户提供一个非常清晰和简单的不同指标的概述,并快速了解它们的演变。

第一部分显示了一些关于体重和脂肪比例的信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每个参数都有:

  • 最后一次测量(以及他发生的时间)
  • 不同时期(自上周、上月和去年以来)的指标演变

我发现这部分信息非常丰富,很容易理解,你可以看到趋势(对我父母来说太完美了)

这一节后面是另一节,包含最后一个运行的会话,更简单。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有一些关于距离、平均速度和海拔的信息,并与之前的比赛进行了比较。

对于本节的其余部分,它是一个包含上次 crossfit 会话练习的表格,因此没有什么真正令人兴奋的,不需要缩放。

重量和跑步部分

对于下面的两个部分,基本上是一些非常基本的数字,我从这篇文章中提取了可视化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用户可以选择想要用 inputs 元素可视化的时间段和参数。他可以使用下拉面板和日期范围选择器选择参数和数据范围

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

布局超级简单,但很实用。

交叉部分

在这一部分中,我选择交叉前面部分的指标索引和输入选项。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

您可以选择练习并获得一些快速统计数据:

  • 携带的最大重量
  • 重复执行的次数
  • 每次重复的平均重量
  • 重复次数与重量的关系图

这很简单,但非常有用,当我想快速找到我的 1 rep 最大重量。

预测部分

在这个部分中,基本上是控制面板调用包含模型的 API。

用户可以选择预测周期和每周训练设置,并了解预测周期结束时体重和脂肪比率的变化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也许不准确,但至少它在这里,它肯定会随着更多的数据变得更好(该模型是在 30 点上训练的)。

现场演示

现在是时候更新最终的 css 了,瞧

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

没有什么疯狂的,但它的功能(可能有点慢)和易于使用。

结论和下一步措施

因此,原型运行良好,并部署在 Heroku 上(如果你想访问,可以联系我)。我花了 2 周的时间来做这件事(周末和午休),所以我对此很满意。

你可以在Github repo中找到所有代码(至少是 app 的骨架)。

接下来的步骤是:

  • 尝试用 Flask 和 D3.js 做一个替代
  • 添加更多的数据,也许是食物指数
  • 实现运行会话细节的可视化(传单可能是一个好的开始)
  • 找到一些其他要显示的指标
  • 从用户那里得到一些反馈

原载于 2018 年 2 月 26 日【the-odd-dataguy.com

与 CDAP 一起在 GCP 建立一个数据湖

原文:https://towardsdatascience.com/building-a-data-lake-on-gcp-with-cdap-6271c264f22e?source=collection_archive---------5-----------------------

首先看看谷歌收购的木桶的开源平台

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Visit Cask Product page to know more on CDAP

众所周知,传统的数据分析平台(如数据仓库)难以扩展且成本高昂,难以满足当前的数据存储和计算需求。如果在内部部署,为处理大数据而专门构建的平台通常需要大量的前期和持续投资。或者,云计算是以经济的方式扩展和容纳如此大量数据的完美工具。虽然经济性是正确的,但企业迁移其内部数据仓库或在云中构建新的仓库或数据湖的过程中会面临许多挑战。这些问题包括构建网络、保护关键数据、拥有使用所选云技术的合适技能,以及找出合适的工具和技术来创建加载、转换和混合数据的操作工作流。

技术什么都不是。重要的是你对人们有信心,他们基本上是善良和聪明的,如果你给他们正确的工具,他们会和他们一起做美好的事情。——乔布斯

企业比以往任何时候都更加依赖数据。拥有合适的工具集授权给合适的人可以使数据随时可用,从而更好、更快地做出决策。在将数据仓库迁移到云中或在云中构建数据仓库的过程中,最重要的步骤之一是选择合适的工具集,使集成变得简单,并使他们能够专注于解决业务挑战,而不是专注于基础设施和技术。

在这篇博文中,我们将讨论【CDAP】(木桶数据应用平台) 如何与 谷歌云平台(GCP) 技术无缝集成,构建云中的数据湖。我们将了解 CDAP 如何帮助数据管理专业人士通过使用 CDAP 集成更多数据来实现他们在 GCP 迁移或构建数据湖的业务目标,从而最大化他们在 GCP 的投资价值。

CDAP 管道(工作流)是一种移动、转换、混合和丰富数据的数据编排功能。CDAP 管道管理所有管道活动的调度、协调和监控,并处理故障情况。CDAP 管道提供了数百个预建连接器的集合、基于开源流媒体引擎的简化流处理,以及与 BigTable、BigQuery、谷歌云存储、谷歌 PubSub 和其他 GCP 技术的新的开箱即用连接。因此,它们使用户能够在谷歌云环境中的任何地方集成几乎任何数据。

治理是任何数据湖或数据仓库的重要需求,无论是部署在内部还是云中。自动捕获和索引 CDAP 境内任何管道的技术、业务和运营元数据的能力,使发现数据集、执行影响分析、跟踪数据集的谱系和创建审计跟踪变得非常容易。

因此,让我们来看看 CDAP 最近添加的一些功能,以与谷歌云平台技术集成。

数据准备和与 GCS 的管道集成

有了木桶,优化宏观用户流程的无缝工作流程在处理复杂技术的同时提供了完整而有趣的体验。根据客户的第一手观察,这样做可以提高效率,降低运营成本,减少用户的挫折感,并最终实现数据访问的民主化,从而更快地从数据中获得更大的价值。本着实现更高效率的精神,让我们首先将 CDAP 的数据准备功能与谷歌云存储集成起来。

谷歌云存储(GCS) 是统一对象存储,支持内容分发、备份和归档、灾难恢复、大数据分析等领域的各种非结构化数据。您可以使用 CDAP 管道将数据移入和移出 GCS,以用于分析、应用和各种用例。借助 CDAP,您可以快速可靠地简化工作流程和操作,或者使用相同的流程将您的客户或供应商数据从亚马逊 S3、Azure ADLS 或 WASB 转移到谷歌云存储中。

CDAP 管道提供了用于与 GCS 本地集成的插件,无论您使用的是结构化数据还是非结构化数据。它们还提供了与 CDAP 数据准备功能的无缝集成,使您可以轻松创建与项目的 GCS 连接、浏览 GCS 并立即处理您的数据,而无需使用代码或移动到另一个控制台。

观看下面的截屏,了解 CDAP 数据准备和 CDAP 管道和气体控制系统的集成流程。

This flow from the start (Configuring GCS) to finish (Pipeline Deployed) takes around ~ 2 minutes to build, and not a single line of code was written

除了与 CDAP 数据准备集成之外,以下 CDAP 插件也可用于 GCS:

  • GCS 文本文件源— 一个源插件,允许用户读取存储在 GCS 上的纯文本文件。文件可以是 CSV、制表符分隔、行分隔 JSON、固定长度等。
  • GCS 二进制文件源— 一个源插件,允许用户以 blobs 形式读取存储在 GCS 上的文件。可以读取 XML、AVRO、Protobuf、图像和音频文件等文件。

CDAP 数据准备自动确定文件类型,并根据文件扩展名和文件内容类型使用正确的源。下面是一个简单的管道和配置相关的 GCS 文本文件源,供您参考。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Google BigQuery 集成

Google 云平台的另一个重要组成部分是 Google BigQuery 。Google BigQuery 是一个无服务器、完全托管的 Pb 级数据仓库,它使企业能够以高度并发的方式执行所有数据仓库操作。通过 CDAP 的原生 Google BigQuery connector,Spark、Spark Streaming 和 MapReduce 作业可以用来将大量数据快速加载到 BigQuery 中。CDAP 对嵌套模式和复杂模式的支持允许在 BigQuery 中高效地分析不同的数据类型。在配置插件时,数据集表的模式无缝地对用户可用。数据集内的新表无需额外工作即可创建。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的管道读取纽约 Trips 数据集(在 Google BigQuery 上作为公共数据集提供),对集群执行一些转换和计算,并将结果写回 Google BigQuery。这个例子可能与真实用例不太相关,因为您可以使用 BigQuery SQL 来完成这里所做的事情,但是这个管道仅用于演示目的,以显示 Google BigQuery 的源和接收器可以读取和写入。

这些 BigQuery 插件简化了从 BigQuery 导入元数据,并根据管道模式自动创建表和正确的模式。

Google PubSub 集成

Google PubSub 是一个完全托管的实时消息服务,让你将来自传感器、日志和点击流的数据摄取到你的数据湖中。CDAP 对 Spark Streaming、Kafka、MQTT 的支持,以及对 Google PubSub 的原生连接,使得将历史数据与实时数据相结合变得容易,从而获得对您的客户的完整的 360 度视图。它还可以轻松地在内部和云之间移动数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是一个简单的实时 CDAP 数据管道,用于将数据从内部 Kafka 实时推送到 Google 云平台 PubSub。发布的数据可立即用于进一步的转换和处理。

用例

EDW 卸载| Oracle CDC 到 Google BigTable

在过去的几十年中,企业已经为数据仓库安装了设备和其他预配置的硬件。这些解决方案通常需要在专有技术上进行大量投资,其目标是让管理和分析数据变得更容易。然而,最近开源技术的进步提供了存储和处理大量数据的更便宜的方法,打破了企业的围墙,使企业质疑昂贵硬件的成本。这一次,企业不再用新硬件替换旧系统,而是寻求在对他们有意义的时候迁移到云来构建他们的数据湖。但是,需要正确的工具来支持云中数据仓库的许多可能的用例。高效、可靠地将数据从本地数据仓库卸载到云需要四件事情:

  • 易于加载数据和保持数据更新
  • 支持对小型和大型数据集进行快速查询的查询工具
  • 支持高并发性而不降低性能
  • 自定义报告和仪表板工具。

Google BigTable 结合 Google BigQuery 提供了支持批量加载的能力,以及查询大规模加载的数据的能力。对于报表和仪表板, Google Data Studio 或任何其他流行的 BI 工具可以与 Google Query 结合使用,以满足许多报表需求。

现在,主要问题是企业如何有效地将数据从其内部仓库卸载到 BigTable 中,并保持 BigTable 中的数据同步。为了支持 EDW 卸载到 BigTable 用例,CDAP 提供了在关系数据库和数据管道上执行变更数据捕获 (CDC)的能力,以及用于消费变更数据事件和更新相应的 Google BigTable 实例以保持数据同步的插件。变更数据捕获解决方案可以使用三种方法之一来捕获源数据库中的变更:

  1. 通过 Oracle Golden Gate 进入源表的交易日志
  2. 通过 Oracle 日志挖掘器
  3. 使用变更跟踪来跟踪 SQL Server 的变更

第一个解决方案读取数据库事务日志,并将所有 DDL 和 DML 操作发布到 Kafka 或 Google PubSub 中。实时 CDAP 数据管道使用 Kafka 或 Google PubSub 中的这些变更集,使用 CDC BigTable Sink 插件对 BigTable 进行规范化并执行相应的插入、更新和删除操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下面是一个管道,它从流源读取变更集,并将它们写入 BigTable,重新创建所有的表更新,并使它们保持同步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要从 BigQuery 查询,请将表作为外部表添加。点击 了解更多操作方法信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在云之间移动|从亚马逊到谷歌,反之亦然

企业可能出于多种原因决定从一个公共云平台迁移到另一个公共云平台,或者选择多个云提供商。一个原因可能是不同的公共云提供商提供了比当前提供商更好的价格,或者在提供的服务方面更匹配。另一个常见的情况是,一家企业最近经历了一次合并,收购方已经优先选择了他们的公共云提供商。不管原因是什么,简化迁移或支持多个云的一种方法是从与云环境集成的多云数据管理平台开始。通过使用多云数据管理解决方案,如 CDAP,您可以无缝地创建一个抽象,隐藏底层云的差异,并允许工作流和数据的简单迁移。在混合云环境中,从一开始就采用这样的平台是非常有价值的,在混合云环境中,您可能要管理本地(托管)私有云和公共云。

借助 CDAP 管道,构建能够高效、可靠地将数据从一个公共云存储迁移到另一个公共云存储的工作流非常简单。下面是一个例子,展示了如何将亚马逊 S3 的数据迁移到 GCS 中,并在迁移过程中转换和存储到 Google BigQuery 中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

管道执行后,管道的执行结果可以在 GCS 和 BigQuery 中获得。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

人工智能集成|使用谷歌语音翻译器翻译音频文件

转录是将你录制的音频转换成高度准确、可搜索和可读的文本的最佳方式;能够索引和搜索音频内容非常有用,因为这有助于用户找到相关内容。它可以用来提高有机流量,改善可访问性,还可以通过转录音频文件来增强您的人工智能,从而为您的客户提供更好的服务。

假设您有一家提供客户支持服务的公司,您正在记录随机的客户对话以提高服务质量,从而更好地了解代表如何处理电话。改善服务的第一步是将录制的音频文件转录成数字化的可读文本。此外,文本可以通过各种 AI / ML 工作流来确定呼叫的情绪、客户情绪、解决延迟等。

Google Cloud Speech API利用强大的神经网络模型将音频转换为文本。它识别超过 110 种语言和变体,以支持您的全球用户群。

简化录制的大量音频文件的转录,谷歌云平台技术和 CDAP 一起为用户提供了一个集成的,可扩展的和无代码的方式来转录音频文件。这种集成使用户可以在几分钟到几小时内,而不是几周或几个月内,为任何生产部署构建可以轻松安排和监控的管道。

下面是一个简单的 CDAP 管道,它获取存储在谷歌云存储上的原始音频文件,通过谷歌语音翻译插件传递,并将转录的文本写入谷歌云存储上的另一个位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

谷歌语音翻译 CDAP 插件已经准备好根据被录制文件的类型进行少量的设置。在上面的例子中,应用于原始音频文件的翻译生成一个 JSON 输出,它描述了被转录的文件,并计算了转录的置信度。

{
 "path": "/audio/raw/audio.raw", 
 "speeches": [
    {
      "confidence": 0.9876289963722229, 
      "transcript": "how old is the Brooklyn Bridge" 
    } 
  ]
}

资源

案例研究:数据湖XML 转换数据发现信息安全智能分析

导读:卡夫卡消费推特数据数据处理同流程 & 水槽

代码示例:Twitter sensingMovieRecommenderNetlensWise

教程:诈骗 ML 分类迁移 S3 到 ADLSEDW 优化

API : CDAP API 和依赖包

如果您正在使用或评估 GCP,并且正在寻找提高您在 GCP 上的集成的方法,您可能想要 试用 CDAP 并安装来自木桶市场的 GCP 连接器。同样,如果你是开发人员或数据工程师/科学家,你可以下载 CDAP 本地沙盒

原载于blog . cdap . io

为圣保罗地铁运营构建数据集

原文:https://towardsdatascience.com/building-a-dataset-for-the-são-paulo-subway-operation-2d8c5a430688?source=collection_archive---------11-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Rafael De Nadai on Unsplash

你坐过拥挤的地铁吗?我知道大多数大城市都会出现这种情况,但在圣保罗,情况可能是这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is what a crowded subway station may look like here in SP

现在,作为一名巴西人和一名保利斯塔诺,我能做些什么呢?(这是葡萄牙语中“住在圣保罗的人”的意思)

Metr 地铁公司的透明网页提供了关于乘客需求的数据,但粒度较低,对每条地铁线工作日和周末的平均条目进行了分组。这还不错,但我们可以做得更好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The transparency webpage for the Metrô subway company provides data on the passenger demand but with low granularity

我知道 ViaQuatro 公司的网页提供了所有地铁线路的(几乎)实时运营状态,该公司与政府有一个地铁线路运营联合体:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The ViaQuatro company webpage provides operation status for all of the subway lines, as highlighted in red

每天乘坐 SP 地铁的人直观地知道,一个 正常 运行状态不足以推断车站不会拥挤,但是一个 减速瘫痪 状态可能与第一张图中所示的混乱有关。

不幸的是,这些数据没有被存储。至少对我们这些普通公民来说不是这样,所以我们可以对它进行访问、监控、评估、展示等等。我们为什么不使用 Python 来解决这个问题呢?

本文剩余部分显示的步骤是一个教导性的,尽管是项目的完全功能性演示。万一你是开发者或者想直奔最终结果,可以随意探索 Github 资源库

所以…

我们的目标是以非侵入性的方式持续存储圣保罗地铁线的运营状态历史,并使任何公民都可以方便地使用。

为了达到这个目标,我们将编写一个能够请求 ViaQuatro 网页,提取操作状态和时间戳并存储它的自治 web scraper。

为此,我们将需要requests包来下载网页,并需要BeautifulSoup来轻松处理网页:

>>> import requests
>>> from bs4 import BeautifulSoup

好了,要下载这个页面,我们需要做的就是

>>> vq_home_request = requests.get('http://www.viaquatro.com.br')

如果请求成功,我们就有了 HTML 代码

>> vq_home_content = vq_home_request.text 
>> vq_home_content'\r\n<!DOCTYPE HTML>\r\n<html lang="pt-BR">\r\n<head>\r\n\t<meta charset="UTF-8">\r\n    **<title>ViaQuatro | Seja Bem-vindo</title>**\r\n\t<meta name="description" content="ViaQuatro - Informa&#231;&#245;es sobre rotas, tarifas, esta&#231;&#245;es e muito mais." /> \r\n\t<meta name="keywords" content="" />\r\n    <meta http-equiv="X-UA-Compatible" content="IE=edge" >\r\n\t<script src="/Content/js/3rd/modernizr.custom.97134.js"></script>\r\n    <!-- Use Zepto for best performance on WebKit based browser -->\r\n\t\t<!-- <script src="js/zepto/zepto.js" type="text/javascript" charset="utf-8"></script> -->\r\n\t<link rel="stylesheet" type="text/css" href="/Content/css/default.css" media="all" /> **<!-- pra ser carregado em todas as páginas -->**\r\n
(...)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

We do have the HTML inside our environment!

现在让我们使用 BeautifulSoup 来浏览 DOM 并提取标题页面,以检查我们是否在 BeautifulSoup 对象中组织了 HTML 元素:

>>> soup = BeautifulSoup(vq_home_content, 'html.parser')
>>> soup.title
<title>ViaQuatro | Seja Bem-vindo</title>

现在到了困难的部分——提取真正重要的东西。使用开发工具检查 HTML,我们看到显示地铁线路当前状态的“操作”面板由一个<section class="operacao">元素组成。里面有我们需要的所有数据。因此,让我们把它拉出来,这样我们就可以对它进行以下查询:

>> operation_column = soup.find(class_= "operacao")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

We need to inspect the page code in order to find out what element contains the data we want

让我们也使用 字典理解 : 初始化一个字典来存储行状态

>> lines_metro = ['azul', 'verde', 'vermelha', 'amarela', 'lilás', 'prata']>> lines_cptm  = ['rubi', 'diamante', 'esmeralda', 'turquesa', 'coral', 'safira', 'jade']>> all_lines = lines_metro + lines_cptm>> **extracted_status = {line:'' for line in all_lines}**>> extracted_status
{'amarela': '', 'vermelha': '', 'diamante': '', 'turquesa': '', 'coral': '', 'prata': '', 'lilás': '', 'esmeralda': '', 'safira': '', 'rubi': '', 'verde': '', 'azul': '', 'jade': ''}

继续我们的调查,我们看到 Amarela(黄色)地铁线的状态包含在一个带有名为状态的css 类的 span 标签中。

>> status_amarela = operation_column.find(class_="status").text
>> extracted_status['amarela'] = status_amarela

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The operation status for the Amarela (yellow) subway line is wrapped around a span tag with acss class called status

对于所有其他线路,数据被分成三个标签<div class="linhas">,每个标签代表一家参与城市铁路系统的公司。在每一个div中,我们都有一个无序列表标签,其中每一个条目都包含行号、其名称和当前在另一个看起来像<div class="info">的 div 中的操作状态。

为了提取所有这些内容,我们将遍历<div class="linhas">div,然后遍历每个<div class="info"> div,以获得我们真正想要的内容:操作状态和行名:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

we will iterate over the <div class="linhas"> divs and then iterate over each <div class="info"> div to get what we really want

>> lines_containers = operation_column.find_all(class_ = "linhas")>> for container in lines_containers:
       line_info_divs = container.find_all(class_ = "info")
       for div in line_info_divs:
           line_title  = ''
           line_status = ''
           spans = div.find_all("span")
           line_title = spans[0].text.lower()
           line_status = spans[1].text.lower()
           extracted_status[line_title] = line_status>> extracted_status
{'safira': 'normal', 'prata': 'normal', 'rubi': 'normal', 'azul': 'normal', 'turquesa': 'normal', 'amarela': 'Operaç\xe3o Normal', 'lilás': 'normal', 'esmeralda': 'normal', 'coral': 'normal', 'verde': 'normal', 'diamante': 'normal', 'jade': 'normal', 'vermelha': 'normal'}

现在我们有了字典中所有行的操作状态!另一个重要信息是该数据的时间戳。它显示在“操作”面板中,就在标题的右边。这是页面中唯一的<time>元素。让我们把它拉出来:

>> time_data = soup.find('time').text
>> time_data
'18/08/2018 23:11'

终于,我们有了所有的数据!我承认我需要一点时间来欣赏这一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Web scraping is so cool! Source

此时,我们可以简单地将extracted_statustime_data写入本地系统中的一个文件,或者利用互联网的魔力将其存储在任何地方。

但是让我们更进一步,使用 Google Sheets ,因为它非常受欢迎,非开发人员也可以访问,并且提供了一个有良好文档记录的 API。最重要的是, gspread 包为我们包装了所有的请求,并且 oauth2client 使用我们的 API 凭证处理令牌获取过程。

我知道有很多隐藏的东西,但是能够用这么少的代码做这么多的事情是用 Python 这样的语言编程的美妙之处之一。

简单地说,我们需要做的是:

  • 获取我们的谷歌证书,以便以后使用它们进行授权(这是手动的,只需要做一次)
  • 通过我们的代码使用凭据获得授权
  • 通过我们的代码将数据写入公共电子表格

要获得证书,我们可以按照 gspread 文档提供的这个逐步指南进行操作。在这个过程结束时,您得到的是一个类似如下的client_secret.json文件:

{
    "private_key_id": "2cd … ba4",
    "private_key": "-----BEGIN PRIVATE KEY-----\nNrDyLw … jINQh/9\n-----END PRIVATE KEY-----\n",
    "client_email": "473000000000-yoursisdifferent@developer.gserviceaccount.com",
    "client_id": "473 … hd.apps.googleusercontent.com",
    "type": "service_account"
}

这很重要:我们需要与我们的 API 用户共享我们将要使用的电子表格。否则,在尝试写入数据时,我们会收到拒绝访问错误。这个用户由 json 文件中的 client_email 字段表示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is important: we need to share the spreadsheet we will be using with our API user

回到代码,让我们导入 gspreadoauth2client 并从。json 文件到我们的环境中:

>> import gspread
>> from oauth2client.service_account import ServiceAccountCredentials>> scope = ['https://spreadsheets.google.com/feeds',
            'https://www.googleapis.com/auth/drive']
>> creds = ServiceAccountCredentials.from_json_keyfile_name(
           'client_secret.json',
           scope)

现在让我们使用我们的凭据获得授权,并初始化电子表格。要初始化电子表格,我们需要它的 ID,它显示在我们用来在浏览器中访问它的 URL 中:

https://docs.google.com/spreadsheets/d/1 wiki 6 sucqaauf 9 qojog _ tme OSA _ lm _ kjm 83 qwxf 9 dsg

>> client = gspread.authorize(creds)>> SPREADSHEET_ID = "1WiKE6SUCqAaUF9qOJOg_tMeOSA_lm_kjm83qwXF9dSg">> data_sheet = client.open_by_key(SPREADSHEET_ID).worksheet("data")

注意,我们不直接使用电子表格对象,而是使用其中的工作表,因此我们需要指定它的名称。

让我们写我们的数据! append_row 方法确实如其名,我们只需要传递一个列表,其中每个元素将被写入该行的不同列。

>> for line in all_lines:
    data_sheet.append_row([time_data, line, extracted_status[line]])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

We can actually see the data being stored in real time!

为了拥有一个不会让你的电脑一直开着的自主刮刀,我们必须组织这段代码,并让它在云服务上运行。针对异常的一些保护也很重要,但是这些超出了本文的范围。如果你想了解更多的细节,可以随意看看 github 的回购。

我将在以后的文章中分析这些数据。我们看看会有什么结果!

【编辑】保罗做了一个很棒的分析!看这里

在 TensorFlow 中构建软决策树

原文:https://towardsdatascience.com/building-a-decision-tree-in-tensorflow-742438cb483e?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

20X magnification of the somatosensory cortex (by Robert CudmoreCC BY-SA 2.0)

介绍

深度学习产品在行业内引起了越来越多的兴趣。虽然计算量很大,但在处理自然语言或图像处理等非结构化数据的分类方面,它们已被证明是有效的。

高价值数据科学产品的目标不仅在于其高价值交付,还在于其被业务接受。因此,可解释性仍然是一个重要因素。

Google Brain 最近发布了一篇论文,提议实现软决策树。

在这篇博客中,我从他们的论文中摘录了一些要点,并举例说明了神经网络是如何模仿树形结构的。

目标

  1. 什么是数据科学中的决策树?
  2. 神经网络怎么会有树状结构?
  3. 在 TensorFlow 中实现软决策树

软决策树

为了不拘泥于形式,在数据科学中,树由三个主要成分组成:

  • 分割条件
  • 修剪条件
  • 离开

分割条件将数据分割到叶子上。修剪条件决定了分区停止的时间。最后,也是最重要的,树叶包含预测的目标值,该值已被拟合到分区内的数据。

如图 1 所示,每个分割条件都是特性的函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1: Basic Tree. Each data-point travels through the tree until one of the leafs. The path is determined by the split conditions, which are functions of the features. The leafs determine the prediction target.

每个内部节点中的分裂和叶子的目标输出由损失函数的优化来确定。为每个数据点分配一个预测成本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在哪里

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

是数据点 x 的目标

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

是叶的目标类的概率。我们还表示了叶选择器:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个符号将在下一节中阐明。

神经网络

神经网络由一组对其输入特征的平滑操作组成。所谓平滑,我的意思是每个操作在其变量中是连续可微的。

可微性是一个至关重要的因素,因为最佳变量是使用损失和操作的梯度计算的。起初这似乎是个问题,如果我们想把树设计成树的每个内部节点,基于分割条件分配它的一个孩子的每个数据点。

因此,我们用神经网络构建树的第一步是通过允许数据在每次分裂时以一定的概率向左和向右移动来消除分裂条件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2: The hard split-condition of the tree is replaced by split-probability.

因此,每个数据点在树中没有唯一的路径。它们现在属于树的每一片叶子,具有一定的概率,即路径概率。

让我们表示从树根到第 n 个(内部)节点的路径概率,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以回顾一下我们之前写的损失函数,对于每个数据点 x :

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这只不过是对分类交叉熵的加权,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

x 的概率属于一片树叶,这就是路径概率。

正规化

我们现在已经重写了分割条件。叶输出可以保持概率,例如 softmax。

最后一个问题仍然存在,但是,优化将收敛到一个适当的局部最小值?

内部节点权重的更新取决于损失的梯度,因此也取决于路径概率

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们仔细看看它在一些内部节点 j:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们立即看到了这里的一个问题。如果某片叶子的概率

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于大量数据来说很小,那么权重在下一步中几乎不被更新。更有甚者,在这次更新之后,这种可能性仍然很小。因此,我们的模型可能会收敛并陷入这些无用的局部极小值。

一棵性能树不仅有最大纯度的叶子,而且在叶子上尽可能均匀地分布数据。如果我们的模型陷入这些局部极小值,我们就只能得到一些高度密集的叶子和许多稀疏的叶子。在这种情况下,我们失去了树的用处,我们最终得到一个逻辑回归模型的小集合。

谷歌大脑的团队提出了一个解决这个问题的方法,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这种正则化有利于均匀的二进制分裂,并且不利于内部节点级别上的早期净化。衰减率 gamma 在树的早期内部节点中增加了重点。

现在一切都设置好了,我们可以讨论 TensorFlow 实现了。

TensorFlow 实现

TensorFlow 是 Google Brain 的一个流行的开源软件库,主要用于深度学习模型的开发。用户在静态计算图上定义操作,并根据需要运行图的不同部分。

让我们用一些基本公式来总结不同的成分:

  • 拆分条件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 修剪条件:让我们坚持一个简单的最大深度
  • 叶片输出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 每个数据点 x 的损失

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将工作分成三类:

  • TreeProperties :包含模型的所有超参数相关属性。
  • 节点:定义所有节点级的操作,如内部节点转发如下所示的概率,叶子节点转发 softmax:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 软决策树:为每个数据点建立所有的内节点、叶子并输出预测目标。

让我们仔细看看!

如第 3.2.2 节所示,超参数 self.decay_penaltyself . regularization _ penalty分别对应于衰减率γ和权重λ。

下一节课更有趣。

在实例化时,我们定义节点分裂概率的权重和偏差。在构建节点时,我们首先转发节点的输出,要么是 softmax 预测概率,要么是内部节点分裂的概率。

损失也在节点级别上更新。内部节点仅通过前面描述的正则化来增加损失。

最后,所有的节点被组合成一棵树。目标的输出预测和节点的概率分布组合成自输出自叶分布

对 MNIST 进行测试

最后,让我们对 MNIST 进行一些测试。使用以下超参数构建树:

max_depth = 7
regularisation_penality=10.
decay_penality=0.9

并且选择训练批量为 32,验证批量为 256。我们得出以下结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

还不错。当然没有 CNN 那么有竞争力,但是我们看到了很多有前途的想法!

请务必查看的完整实现

我写了更多精彩的东西!

@ 调整超参数(第一部分):successful halving

@tensor flow 中的自定义优化器

@XGBOOST 回归预测区间

使用 Keras 构建深度学习模型

原文:https://towardsdatascience.com/building-a-deep-learning-model-using-keras-1548ca149d37?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A Neural Network (image credit)

深度学习是机器学习中越来越受欢迎的子集。深度学习模型是使用神经网络构建的。神经网络接受输入,然后使用训练期间调整的权重在隐藏层中处理这些输入。然后模型给出一个预测。调整权重以找到模式,从而做出更好的预测。用户不需要指定要寻找什么样的模式——神经网络会自己学习。

Keras 是一个用 Python 编写的用户友好的神经网络库。在本教程中,我将使用 Keras 检查两个深度学习模型:一个用于回归,一个用于分类。我们将建立一个回归模型来预测员工的每小时工资,我们将建立一个分类模型来预测患者是否患有糖尿病。

注意:我们将使用的数据集相对干净,因此我们不会执行任何数据预处理来为建模准备数据。您将在未来项目中使用的数据集可能不那么清晰-例如,它们可能会有缺失值-因此您可能需要使用数据预处理技术来改变您的数据集以获得更准确的结果。

读入训练数据

对于我们的回归深度学习模型,第一步是读入我们将用作输入的数据。对于这个例子,我们使用的是“小时工资”数据集。首先,我们将使用 Pandas 读入数据。我不会详细介绍熊猫,但如果你想进一步深入数据科学和机器学习,这是一个你应该熟悉的库。

“df”代表数据帧。熊猫以数据帧的形式读入 csv 文件。“head()”函数将显示数据帧的前 5 行,以便您可以检查数据是否已正确读入,并初步了解数据的结构。

Import pandas as pd#read in data using pandas
train_df = pd.read_csv(‘data/hourly_wages_data.csv’)#check data has been read in properly
train_df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将数据集分成输入和目标

接下来,我们需要将数据集分成输入(train_X)和目标(train_y)。我们的输入将是除“每小时工资”之外的每一列,因为“每小时工资”是我们将试图预测的。因此,“每小时工资”将是我们的目标。

我们将使用 pandas 'drop ‘函数从数据帧中删除’ wage_per_hour ‘列,并将其存储在变量’ train_X '中。这将是我们的投入。

*#create a dataframe with all training data except the target column*
train_X = train_df.drop(columns=['wage_per_hour'])

*#check that the target variable has been removed*
train_X.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将在目标变量(train_y)中插入“每小时工资”列。

*#create a dataframe with only the target column*
train_y = train_df[['wage_per_hour']]

*#view dataframe*
train_y.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

构建模型

接下来,我们必须建立模型。代码如下:

**from** **keras.models** **import** Sequential
**from** **keras.layers** **import** Dense*#create model*
model = Sequential()

*#get number of columns in training data*
n_cols = train_X.shape[1]

*#add model layers*
model.add(Dense(10, activation='relu', input_shape=(n_cols,)))
model.add(Dense(10, activation='relu'))
model.add(Dense(1))

我们将使用的模型类型是顺序的。顺序是在 Keras 中建立模型的最简单的方法。它允许你一层一层地建立模型。每一层都有与其下一层相对应的权重。

我们使用“add()”函数向模型中添加层。我们将添加两个层和一个输出层。

“密集”是图层类型。密集是适用于大多数情况的标准图层类型。在密集层中,前一层中的所有节点都连接到当前层中的节点。

我们在每个输入层中有 10 个节点。这个数字也可以是数百或数千。增加每层中的节点数量会增加模型容量。稍后,我将进一步详细介绍增加模型容量的效果。

“激活”是该层的激活功能。激活函数允许模型考虑非线性关系。例如,如果你预测病人患糖尿病,从 10 岁到 11 岁和从 60 岁到 61 岁是不同的。

我们将使用的激活函数是 ReLU 或整流线性激活。虽然它是两个线性部分,但已被证明在神经网络中工作良好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ReLU Activation Function (image credit)

第一层需要一个输入形状。输入形状指定输入中的行数和列数。输入中的列数存储在’ n_cols '中。逗号后面没有任何东西表示可以有任意数量的行。

最后一层是输出层。它只有一个节点,是给我们预测的。

编译模型

接下来,我们需要编译我们的模型。编译模型需要两个参数:optimizer 和 loss。

优化器控制学习速率。我们将使用“亚当”作为我们的优化器。在许多情况下,Adam 通常是一个很好的优化器。adam 优化器在整个训练过程中调整学习率。

学习率决定了计算模型最佳权重的速度。较小的学习率可能会导致更准确的权重(直到某一点),但计算权重所需的时间会更长。

对于我们的损失函数,我们将使用‘均方误差’。它是通过计算预测值和实际值之间的平均平方差来计算的。对于回归问题,这是一个流行的损失函数。这个值越接近 0,模型的表现就越好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mean Squared Error (image credit)

*#compile model using mse as a measure of model performance*
model.compile(optimizer='adam', loss='mean_squared_error')

训练模型

现在我们将训练我们的模型。为了训练,我们将在我们的模型上使用具有以下五个参数的‘fit()’函数:训练数据(train_X)、目标数据(train_y)、验证分割、历元和回调的数量。

验证分割将随机分割数据用于训练和测试。在训练期间,我们将能够看到验证损失,它给出了我们的模型在验证集上的均方误差。我们将验证分割设置为 0.2,这意味着我们在模型中提供的 20%的训练数据将被留出用于测试模型性能。

历元数是模型在数据中循环的次数。在一定程度上,我们运行的时代越多,模型就会改进得越多。此后,模型将在每个时期停止改进。此外,纪元越多,模型运行的时间就越长。为了对此进行监控,我们将使用“提前停止”。

如果模型停止改进,提前停止将在达到时期数之前停止模型的训练。我们将我们的提前停止监视器设置为 3。这意味着在连续 3 个时期模型没有改善之后,训练将停止。有时,验证损失可以停止改善,然后在下一个时期改善,但是在验证损失没有改善的 3 个时期之后,它通常不会再次改善。

**from** **keras.callbacks** **import** EarlyStopping*#set early stopping monitor so the model stops training when it won't improve anymore*
early_stopping_monitor = EarlyStopping(patience=3)*#train model*
model.fit(train_X, train_y, validation_split=0.2, epochs=30, callbacks=[early_stopping_monitor])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据新数据做出预测

如果您想使用这个模型对新数据进行预测,我们可以使用’ predict()'函数,传入我们的新数据。输出将是“每小时工资”预测。

#example on how to use our newly trained model on how to make predictions on unseen data (we will pretend our new data is saved in a dataframe called 'test_X').test_y_predictions = model.predict(test_X)

恭喜你。你在 Keras 建立了深度学习模型!它还不是非常准确,但可以通过使用大量的训练数据和“模型容量”来改善。

模型容量

随着模型中节点和层数的增加,模型容量也会增加。增加模型容量可以产生更精确的模型,直到某个点,在该点模型将停止改进。通常,您提供的训练数据越多,模型就应该越大。我们只使用了极少量的数据,所以我们的模型非常小。模型越大,需要的计算能力就越大,训练的时间也就越长。

让我们使用与先前模型相同的训练数据创建一个新模型。这次,我们将添加一层,并将每层中的节点增加到 200 个。我们将训练模型,看看增加模型容量是否会提高我们的验证分数。

*#training a new model on the same data to show the effect of increasing model capacity*

*#create model*
model_mc = Sequential()

*#add model layers*
model_mc.add(Dense(200, activation='relu', input_shape=(n_cols,)))
model_mc.add(Dense(200, activation='relu'))
model_mc.add(Dense(200, activation='relu'))
model_mc.add(Dense(1))

*#compile model using mse as a measure of model performance*
model_mc.compile(optimizer='adam', loss='mean_squared_error')*#train model*
model_mc.fit(train_X, train_y, validation_split=0.2, epochs=30, callbacks=[early_stopping_monitor])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,通过增加模型容量,我们已经将验证损失从旧模型中的 32.63 提高到新模型中的 28.06。

分类模型

现在让我们继续构建我们的分类模型。由于许多步骤都是以前模型的重复,我将只讨论新概念。

对于下一个模型,我们将预测患者是否患有糖尿病。

*#read in training data*
train_df_2 = pd.read_csv('documents/data/diabetes_data.csv')

*#view data structure*
train_df_2.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

*#create a dataframe with all training data except the target column*
train_X_2 = train_df_2.drop(columns=['diabetes'])

*#check that the target variable has been removed*
train_X_2.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在分离目标列时,我们需要调用“to _ categorical()”函数,以便对列进行“一键编码”。目前,没有糖尿病的患者在糖尿病列中用 0 表示,而有糖尿病的患者用 1 表示。对于一键编码,整数将被删除,每个类别将输入一个二进制变量。在我们的情况下,我们有两个类别:没有糖尿病和糖尿病。没有糖尿病的患者将由[1 0]表示,患有糖尿病的患者将由[0 1]表示。

**from** **keras.utils** **import** to_categorical*#one-hot encode target column*
train_y_2 = to_categorical(train_df_2.diabetes)

*#vcheck that target column has been converted*
train_y_2[0:5]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

*#create model*
model_2 = Sequential()

*#get number of columns in training data*
n_cols_2 = train_X_2.shape[1]

*#add layers to model*
model_2.add(Dense(250, activation='relu', input_shape=(n_cols_2,)))
model_2.add(Dense(250, activation='relu'))
model_2.add(Dense(250, activation='relu'))
model_2.add(Dense(2, activation='softmax'))

我们模型的最后一层有两个节点——每个节点对应一个选项:患者有糖尿病或没有糖尿病。

激活是“softmax”。Softmax 使输出总和达到 1,因此输出可以解释为概率。然后,该模型将根据哪个选项的概率更高来进行预测。

*#compile model using accuracy to measure model performance*
model_2.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

我们将使用‘分类交叉熵’作为损失函数。这是最常见的分类选择。分数越低,表示模型的性能越好。

为了使事情更容易解释,我们将使用“准确性”度量来查看每个时期结束时验证集的准确性分数。

*#train model*
model_2.fit(X_2, target, epochs=30, validation_split=0.2, callbacks=[early_stopping_monitor])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

恭喜你。你现在正在 Keras 中构建令人惊叹的深度学习模型!

感谢阅读!本教程的 github 库可以在这里找到。

在 Google Sheets 中构建深度神经网络

原文:https://towardsdatascience.com/building-a-deep-neural-net-in-google-sheets-49cdaf466da0?source=collection_archive---------2-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我想告诉你深度卷积神经网络并不像听起来那么可怕。我将通过展示我在 Google Sheets 中制作的一个实现来证明这一点。这里有这里有。复制它(使用左上方的文件→制作副本选项),然后你可以摆弄它,看看不同的杠杆如何影响模型的预测。

本文的其余部分将是一个简短的介绍,以了解卷积神经网络(CNN)背后的高级直觉,然后是一些推荐的资源以获得更多信息。

在继续之前,我想对 FastAI 大声疾呼。我最近完成了他们精彩的深度学习课程,所有的灵感和功劳真的都归于他们。出色的讲师杰瑞米·霍华德和他的联合创始人雷切尔·托马斯向全班展示了在 Excel 中制作 CNN 的想法。但据我所知,该电子表格无法在网上获得,也似乎没有完全完成网络。我正在对他们的工作做一个小小的扩展,并把它放在 Google Sheets 上,这样每个人都可以更容易地玩。

我是怎么造出来的?

我在 MNIST 数据集上训练了一个(非常)简单的 CNN,这是一堆手写数字的黑白图像。每个图像是 28x28 像素。每个像素被表示为一个介于 0(无油墨)和 1(最大油墨)之间的数字。这是一个可以使用的经典数据集,因为它足够小,足够快,但又足够真实,可以显示机器学习的复杂性。模型的工作是确定图像的编号。每个图像总是恰好是一个数字 0-9。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example image from MNIST. 28x28 pixels. Note: I added conditional formatting in Sheets so pixels with more “ink” show up more red.

我使用一个名为 Keras 的流行深度学习库来训练这个模型(参见这里的代码),然后将我的模型中训练好的权重放入工作表中。训练出来的权重只是数字。把它放到表中,这意味着从我的模型中复制并粘贴一堆数字到表中。最后一步是添加公式来复制模型所做的事情,这只是常规的乘法和加法。让我重申一下:复制深度学习模型预测的数学止于乘法和加法 [1]。

模型的每一层都有权重(也称为“参数”)。任何机器学习模型都会自动学习权重。这个模型大约有 1000 个砝码。更复杂的模型可以轻松拥有数亿个。您可以在下面看到该型号的所有 1000 个重量:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

何时使用卷积神经网络?

你使用 CNN 在序列数据中寻找模式,在这些数据中你有非常肯定的模式存在,但是你发现很难将这些模式用语言表达出来,或者通过简单的规则提取出来。美国有线电视新闻网认为秩序很重要。

例如,对图片进行分类是 CNN 的主要用例,因为像素在逻辑上是连续的,任何人都很清楚有大量的模式。然而,只要试着把猫和吉娃娃的确切区别用语言表达出来,你就会明白为什么 CNN 是有用的。

另一方面,如果你有两支球队之间的最新棒球统计数据,并且你想预测获胜者,那么 CNN 将是一个奇怪的选择。你所拥有的数据(例如赢的次数,输的次数,或者球队的平均击球率)本质上并不是连续的。顺序在那里并不重要,我们已经提取了我们认为有用的模式。所以 CNN 的不会有帮助。

CNN 背后的直觉

为了理解这些野兽,让我们把深度卷积神经网络分解成它的组成部分“深度”、“卷积”和“神经网络”。

回旋

想象一下你是盲人。但是你的工作是找出这个手写图像是什么数字。你可以和看到图像的人说话,但是他们不知道数字是什么。所以你只能问他们简单的问题。你能做什么?

你可以采取的一种方法是问这样的问题,“它在顶部是不是大部分都是直的?”,“对角线从右到左?”等。有了足够多这样的问题,你实际上可以很好地猜测它是 7,或者 2,或者其他什么。

直觉上,这就是卷积的作用。计算机是盲目的,所以它做它能做的,并且问许多小的模式问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Box 1 is multiplied by box 2. Sum the result, and you get box 3. That’s a convolution.

要问这些问题,图像中的每个像素都要通过一个函数(也称为“卷积”)来产生相应的像素,从而回答这些小模式问题中的一个。卷积使用过滤器来寻找模式。例如,请注意上面的滤镜(截图中的 2 号)如何在右侧变得更红,而在左侧变得更少。该过滤器将主要寻找左边缘。

为什么它会找到左边界可能不太明显,但是摆弄一下电子表格,你会亲眼看到数学是如何计算出来的。滤镜发现看起来像自己的东西。CNN 通常会使用数百个过滤器,所以你会得到每个像素的许多小“分数”,有点像左边缘分数、上边缘分数、对角线、角等。

深的

好吧,问边很酷,但是更复杂的形状呢?这就是“深层”多层事物出现的地方。因为现在我们已经有了图像的“左边缘”、“上边缘”和其他简单的“过滤器”,我们可以添加另一个层,并在所有先前的过滤器上运行卷积,并组合它们!因此,结合 50/50 的左边缘和上边缘可以给你一个圆角。很酷吧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The second convolution takes corresponding pixels from the previous convolution layer and multiplies each by it’s own filter. Just like before, we sum the result, and that produces a new corresponding pixel for the second convolution layer.

严肃的 CNN 将会有许多层,这允许模型建立越来越抽象和复杂的形状。甚至在仅仅 4 或 5 层之后,你的模型就可以开始发现脸、动物和各种有意义的形状。

神经网络

现在,您可能会问自己,“这一切都很好,但要想出所有正确的过滤器听起来真的很乏味。”“最后呢?我如何将这些过滤器中的所有答案组合成有用的东西?”。

首先,有必要认识到,在高层次上,我们的 CNN 实际上有两个“部分”。第一部分,卷积,为我们在图像数据中找到有用的特征。第二部分,电子表格末尾的“密集”层(如此命名是因为每个神经元都有如此多的权重),为我们进行分类。一旦你有了这些特征,密集层实际上与运行一系列线性回归并将它们组合成每个可能数字的分数没有什么不同。最高分是模特的猜测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Matrix 1 is the output from our convolutions. Then every pixel from matrix 1 is multiplied by a corresponding number in matrix 2 . The summation of that produces number 3. You repeat that process again for the boxes in green. You end up with 8 outputs, or “neurons” in deep learning jargon.

计算出所有正确的权重用于过滤器和最后的密集层将是非常烦人的。幸运的是,自动计算这些权重是神经网络的全部内容,所以我们不需要担心这个。但如果你很好奇,你应该谷歌一下“反向传播”。

摘要

每个 CNN 大致有两个部分。卷积总是在开始时寻找图像中有用的特征,最后的层通常称为“密集”层,根据这些特征对事物进行分类。

为了对它们有一个真实的感受,我会鼓励你去玩电子表格。从头到尾跟踪一个像素。弄乱过滤器,看看会发生什么。我还在电子表格的注释中解释了更多的技术细节。

资源

要了解更多信息,我推荐以下资源:

交互式卷积——一个关于卷积的杀手级交互式教程(即只有 C 部分,没有 NN 部分)作者维克多·鲍威尔。

程序员实用深度学习 —来自 Fast 的课程。我参加了 AI,并从中学到了很多。它是在线的,而且完全免费。

展示 CNN 基础知识的精彩视频 —这是来自杰瑞米·霍华德(FastAI 创始人)的一段 20 分钟的视频。太棒了。视频嵌入在该页面中。从打开视频的第 21 分钟开始。

笔记

[1]—训练CNN 所需的数学包括微积分,所以它可以自动调整权重。但是一旦模型被训练,它实际上只需要乘法和加法来做预测。实际上,微积分是由你正在使用的深度学习库来处理的。

构建深度神经网络玩 FIFA 18

原文:https://towardsdatascience.com/building-a-deep-neural-network-to-play-fifa-18-dce54d45e675?source=collection_archive---------1-----------------------

游戏中的人工智能机器人通常是通过手工编写一系列赋予游戏智能的规则来构建的。在很大程度上,这种方法在让机器人模仿人类行为方面做得相当好。然而,对于大多数游戏来说,仍然很容易区分机器人和真人游戏。如果我们想让这些机器人的行为更像人类,不使用手工编码的规则来构建它们会有帮助吗?如果我们简单地让机器人通过观察人类的游戏方式来学习,从而理解游戏,会怎么样?

探索这一点需要一个游戏,在开发游戏本身之前,有可能收集玩游戏的人的这种数据。FIFA 就是这样一款让我探索这一点的游戏。能够玩游戏并记录我在游戏中的行动和决定让我能够训练一个端到端的基于深度学习的机器人,而不必硬编码游戏的单个规则。

这个项目的代码以及训练好的模型可以在这里找到:【https://github.com/ChintanTrivedi/DeepGamingAI_FIFA.git】

玩游戏的机制

构建这种机器人的底层机制需要在不访问任何游戏内部代码的情况下工作。好消息是,这个机器人的前提是我们不想看到任何这样的游戏内信息。一个简单的游戏窗口截图就可以输入机器人的游戏引擎。它处理这些视觉信息,并输出它想要采取的动作,这些动作通过按键模拟与游戏进行交流。冲洗并重复。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们已经有了一个框架来为机器人提供输入,并让它的输出控制游戏,我们来到了有趣的部分:学习游戏智能。这通过两个步骤来完成:( 1)使用卷积神经网络来理解屏幕截图图像,以及(2)使用长短期记忆网络来基于对图像的理解来决定适当的动作。

步骤 1:训练卷积神经网络(CNN)

众所周知,CNN 能够高精度地检测图像中的对象。除了更快的 GPU 和智能网络架构,我们还有一个可以实时运行的 CNN 模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了让我们的机器人理解输入的图像,我使用了一个非常轻量级和快速的 CNN,叫做 MobileNet。从这个网络中提取的特征地图代表了对图像的高级理解,比如玩家和其他感兴趣的对象在屏幕上的位置。该特征图然后与单镜头多框一起使用,以检测球场上的球员以及球和球门。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第二步:训练长短期记忆网络(LSTM)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们已经理解了这个图像,我们可以继续下去,决定我们要做什么。然而,我们不想只看一个画面就采取行动。我们更愿意看看这些图像的一小段序列。这就是 LSTMs 发挥作用的地方,因为众所周知,LSTMs 能够对数据中的时间序列进行建模。在我们的序列中,连续的帧被用作时间步长,并且使用 CNN 模型为每个帧提取特征图。这些然后被同时输入两个 LSTM 网络。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第一个 LSTM 执行学习玩家需要做什么动作的任务。因此,这是一个多类分类模型。第二个 LSTM 得到相同的输入,并且必须决定采取什么动作:传中、穿过、传球和射门:另一个多类分类模型。这两个分类问题的输出然后被转换成按键来控制游戏中的动作。

这些网络已经在通过手动玩游戏并记录输入图像和目标按键而收集的数据上被训练。少数几个收集标签数据不像是一件苦差事的例子之一!

评估机器人的性能

除了让它出去玩游戏之外,我不知道用什么精确度来判断机器人的性能。仅仅经过 400 分钟的训练,机器人已经学会了向对手的球门跑去,向前传球,并在探测到球门时射门。在 FIFA 18 的初学者模式中,它已经在大约 6 场比赛中打入 4 球,比保罗·博格巴在截至本文撰写时的 17/18 赛季中的进球多 1 球。

机器人与内置机器人比赛的视频剪辑可以在我的 YouTube 频道上找到,视频嵌入在下面。

结论

我对这种构建游戏机器人的方法的最初印象当然是积极的。经过有限的训练,这个机器人已经掌握了游戏的基本规则:向球门移动,然后把球踢进网窝。我相信,通过更多小时的训练数据,它可以获得非常接近人类水平的性能,这对于游戏开发者来说是很容易收集的。此外,扩展模型训练以从真实世界的比赛镜头中学习将使游戏开发者能够使机器人的行为更加自然和真实。现在,如果 EA sports 的任何人正在阅读这篇文章…

我发表了这个项目的后续文章,使用强化学习。在此链接处查看。谢谢!

用 Python 构建可部署的 ML 分类器

原文:https://towardsdatascience.com/building-a-deployable-ml-classifier-in-python-46ba55e1d720?source=collection_archive---------4-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如今,由于问题的复杂性和大量的相关数据,机器学习已经完全成为寻找问题解决方案的必要、有效和高效的方法。在大多数资源中,机器学习模型是在结构化数据中开发的,只是为了检查模型的准确性。但是,在开发机器学习模型时,实时的一些主要要求是在构建模型、模型中的参数调整以及将模型保存到文件系统以供以后使用或部署时处理不平衡的数据。在这里,我们将看到如何用 python 设计一个二进制分类器,同时处理上面指定的所有三个需求。

在开发机器学习模型时,我们通常会将所有的创新放在标准的工作流程中。涉及的一些步骤是获取数据,对数据进行特征工程,通过迭代训练和测试建立具有适当参数的模型,并在生产中部署建立的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Machine Learning Work Flow

我们将通过构建一个二元分类器来完成这个工作流程,该分类器根据可用的特征来预测红酒的质量。数据集在 UCI 机器学习库中公开。 Scikit 学习库在这里用于分类器设计。对于源代码, github 链接是-

[## sambit 9238/机器学习

机器学习——它代表了机器学习在不同场景中的一些实现。

github.com](https://github.com/sambit9238/Machine-Learning/blob/master/WineQuality.ipynb)

首先,我们需要导入所有必要的依赖项并加载数据集。在任何 ml 模型设计中,我们总是需要 numpy 和 pandas,因为它们都涉及到数据帧、矩阵和数组操作。

import numpy as np
import pandas as pd
df = pd.read_csv("winequality-red.csv")
df.head()

数据集看起来像-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这里可以看出,质量是用数字 3 到 8 来表示的。为了使它成为二进制分类问题,让我们把质量> 5 看作是好的,否则就是坏的。

df["quality_bin"] = np.zeros(df.shape[0])
df["quality_bin"] = df["quality_bin"].where(df["quality"]>=6, 1)
#1 means good quality and 0 means bad quality

来获得数据描述的摘要—

df.describe()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从快照中可以看出,数据值在某些属性上有很大偏差。将这些值标准化是一个很好的做法,因为这将使差异达到一个合理的水平。此外,由于大多数算法在背景中使用欧几里德距离,因此在模型建立中具有缩放特征更好。

from sklearn.preprocessing import StandardScaler
X_data = df.iloc[:,:11].values
y_data = df.iloc[:,12].values
scaler = StandardScaler()
X_data = scaler.fit_transform(X_data)

这里使用了 fit_transform,这样标准缩放器将适合 X_data 并转换 X_data。如果你需要在两个不同的数据集上进行拟合和变换,你也可以分别调用拟合和变换函数。现在,我们总共有 1599 个数据实例,其中 855 个质量差,744 个质量好。这里的数据显然是不平衡的。因为数据实例的数量较少,所以我们将进行过采样。 **但是需要注意的是,重采样应该总是只在训练数据上进行,而不是在测试/验证数据上。**现在,让我们将数据集分为训练数据集和测试数据集进行建模。

from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3, random_state=42) 
#so that 30% will be selected for testing data randomly

除了训练和测试分割,你还可以采用被认为是更有效的交叉验证方法。现在我们有 588 个质量差的和 531 个质量好的实例用于训练。剩下 267 个质量差的和 213 个质量好的测试实例。是时候对训练数据进行重新采样,以便平衡数据,使模型不会有偏差。这里我们将使用 SMOTE 算法进行过采样。

from imblearn.over_sampling import SMOTE
#resampling need to be done on training dataset only
X_train_res, y_train_res = SMOTE().fit_sample(X_train, y_train)

经过过采样后,在训练集中有 588 个好的和坏的葡萄酒样本。现在是选择模型的时候了。我在这里采用了随机梯度分类器。但是,你现在可以检查几个模型并比较它们的准确性来选择合适的。

from sklearn.linear_model import SGDClassifier
sg = SGDClassifier(random_state=42)
sg.fit(X_train_res,y_train_res)
pred = sg.predict(X_test)
from sklearn.metrics import classification_report,accuracy_score
print(classification_report(y_test, pred))
print(accuracy_score(y_test, pred))

结果看起来像-

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Classification Report

得到的准确率为 65.625%。学习率、损失函数等参数。在模型的性能中起主要作用。使用 GridSearchCV 可以有效地为模型选择最佳参数。

#parameter tuning 
from sklearn.model_selection import GridSearchCV
#model
model = SGDClassifier(random_state=42)
#parameters
params = {'loss': ["hinge", "log", "perceptron"],
          'alpha':[0.001, 0.0001, 0.00001]}
#carrying out grid search
clf = GridSearchCV(model, params)
clf.fit(X_train_res, y_train_res)
#the selected parameters by grid search
print(clf.best_estimator_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Best Parameters for the Classifier

正如这里可以看到的,这里只提供了损失函数和 alpha,用于寻找最佳选项。其他参数也可以这样做。损失函数的最佳选项似乎是“铰链”红外线性 SVM,α值似乎是 0.001。现在,我们将使用网格搜索选择的最佳参数建立一个模型。

#final model by taking suitable parameters
clf = SGDClassifier(random_state=42, loss="hinge", alpha=0.001)
clf.fit(X_train_res, y_train_res)
pred = clf.predict(X_test)

现在,我们选择了模型,调整了参数,因此是时候在部署之前验证模型了。

print(classification_report(y_test, pred))
print(accuracy_score(y_test, pred))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Classification Report

从这里可以看出,调整参数后,指标值提高了 2–3%。准确率也从 65.625%提高到了 70.625%。如果你仍然对这个模型不满意,你也可以通过一些训练和测试迭代来尝试其他算法。现在,既然模型已经构建好了,就需要将它保存到文件系统中,以便以后使用或部署到其他地方。

from sklearn.externals import joblib
joblib.dump(clf, "wine_quality_clf.pkl")

当您需要分类器时,可以使用 joblib 简单地加载它,然后传递特征数组以获得结果。

clf1 = joblib.load("wine_quality_clf.pkl")
clf1.predict([X_test[0]])

恭喜你。现在你已经准备好设计一个可部署的机器学习模型了。😄

参考资料:-

[## 重击

重击

SMOTEwww.cs.cmu.edu](https://www.cs.cmu.edu/afs/cs/project/jair/pub/volume16/chawla02a-html/node6.html) [## 3.2.调整估计器的超参数-sci kit-了解 0.19.1 文档

请注意,这些参数的一个小子集通常会对预测或计算产生很大影响…

scikit-learn.org](http://scikit-learn.org/stable/modules/grid_search.html) [## 功能缩放的重要性-sci kit-了解 0.19.1 文档

通过标准化(或 Z 分数标准化)进行特征缩放对于许多应用程序来说是一个重要的预处理步骤

scikit-learn.org](http://scikit-learn.org/stable/auto_examples/preprocessing/plot_scaling_importance.html)

用 D3.js 和 Svidget.js 构建圆环图小部件

原文:https://towardsdatascience.com/building-a-donut-chart-widget-with-d3-js-and-svidget-js-8c150ccb01ae?source=collection_archive---------1-----------------------

D3.js 是一个非常著名和受人尊敬的 JavaScript 库,可以让你创建复杂的数据可视化,比如图表和图形。它已经成为 web 数据可视化的同义词。 Svidget.js 是一个 JavaScript 框架,允许您在纯 SVG 中创建数据可视化小部件。从表面上看,这两个公司似乎是在相互竞争,但实际上恰恰相反。通过使用 D3 来输出一些惊人的数据可视化,并使用 Svidget.js 来简化部署和重用的包装,我们可以创建非常棒的可视化组件,可以轻松地嵌入到任何地方。简单来说,Svidget 就是汉堡小圆面包,D3 就是肉饼。

首先,让我们从小部件的角度考虑一个圆环图。它的属性或参数是什么?我们可以调用什么动作或方法?小部件会触发什么事件?Svidget 小部件由 3 个构件组成— 参数动作事件。定义这些工件是widget 化的第一步。(关于构建小部件的完整介绍,包括这些概念,可以在 svidget.com 上找到。)

三者中最难的是计算参数。为了获得一些灵感,我们可以看看现有的实现,如charist . jsGoogle Charts 。请记住,我们通常不想提供所有类型的配置,而是提供一个很好的抽象概念,让消费者快速启动并运行。根据最初的发现,我想出了:

  • 数据—小部件的数据,以数组形式表示
  • maxSlices —将剩余数据分组到“其他”切片之前的最大切片数
  • 开始角度—图表开始的角度,以度为单位,通常为 0 度
  • 排序—如何对图表进行排序:“无”、“asc”或“desc”
  • 颜色—为切片着色的颜色数组
  • 宽度-圆环的宽度(终点-起点半径)

注意:最终的小部件可能还包含样式参数,我们将在后面介绍。

对于小部件操作,图表几乎不需要暴露什么。图表相对被动。但是出于演示的目的,让我们添加一个名为 animate 的动作,它将强制图表在被调用时自动显示。(第一次加载图表时会播放相同的动画。)

对于小部件事件,有两个有用的事件——一个是选择事件,它告诉我们何时通过鼠标悬停(或在移动设备上点击)选择了切片或片段;另一个是激活事件,它告诉我们用户何时点击了切片(在移动设备上,他们将点击以选择,然后再次点击以激活)。

既然我们已经弄清楚了所有的小部件工件,让我们把它们放在一起。在 Svidget 中,您可以在 SVG 中用 XML 声明性地定义所有这些内容。有关这方面的更多信息,请从 GitHub repo 下载 svidget.xsd 模式。综上所述,小部件 SVG 最初看起来如下:

<svg ae kl" href="http://www.w3.org/2000/svg" rel="noopener ugc nofollow" target="_blank">http://www.w3.org/2000/svg"
  xmlns:svidget="[http://www.svidget.org/svidget](http://www.svidget.org/svidget)" 
  width="400" height="400" viewBox="0 0 400 400" svidget:version="0.3.4"><svidget:params>
  <svidget:param name="data" />
  <svidget:param name="maxSlices" />
  <svidget:param name="startAngle" />
  <svidget:param name="sort" />
  <svidget:param name="colors" />
  <svidget:param name="width" />
</svidget:params><svidget:actions>
  <svidget:action name="animate" binding="animate">
    <svidget:actionparam name="duration" type="number" />
  </svidget:action>
</svidget:actions><svidget:events>
  <svidget:event name="sliceSelect" />
  <svidget:event name="sliceActivate" />
</svidget:events>

接下来,让我们布局我们的 SVG。这只是一个框架,D3 会处理剩下的部分。

<g id="chart" transform="translate(200 200)"></g>

最后,让我们对肉进行编码——使用 D3 填充甜甜圈图。

// set up
var outerRadius = CHART_RADIUS;
var innerRadius = outerRadius — _width;
var widget = svidget.$; // get an instance to the current widget// params
// note: data in form of [['Item 1', 3], ['Item 2', 6]]
var data = widget.param('data').value();
var startAngle = widget.param('startAngle').value();
var sort = widget.param('sort').value();
var colors = widget.param('colors').value();// colors
var colorRange = d3.scale.ordinal().range(colors);// pie layout — for layout out arcs as a pie/donut chart
var pie = d3.layout.pie()
 .startAngle(toRadians(startAngle))
 .endAngle(toRadians(startAngle + 360))
 .sort(sortDataFunc(sort))
 .value(function(d) { 
   return numIt(d[1]); /* second element in data inner array */ 
 });// the main arc object
var arc = d3.svg.arc()
 .outerRadius(outerRadius)
 .innerRadius(innerRadius);// create chart and slices
var chart = d3.select('#chart');
var slices = chart.selectAll('.slice')
 .data(pie(data))
 .enter()
 .append('g');
var paths = slices.append('path');// draw slices
paths.attr('stroke', '#fff')
 .attr('stroke-width', 2)
 .attr('d', arc)
 .style('fill', function(d, i) { 
   return colorRange(i); 
 });// draw labels
slices.append('text')
 .attr('dy', '.35em')
 .style('text-anchor', 'middle')
 .attr('transform', function(d) { 
   return 'translate(' + arc.centroid(d) + ')'; 
 })
 .text(function(d) { 
   d.data[0]; // d.data == ['Label', 0]
 });

既然我们的 donutChart.svg 小部件文件已经完成并准备就绪,在网站上嵌入就变得容易了。只需使用 HTML 标签,传递您想要的参数值:

<object id="donutChart" role="svidget" data="path/to/donutChart.svg" type="image/svg+xml" width="400" height="400">
  <param name="data" value="[['banana', 7], ['apple', 6], ['cherry', 2], ['orange', 10], ['grape', 3.5]]" />
  <param name="maxSlices" value="-1" />
  <param name="startAngle" value="0" />
  <param name="sort" value="none" />
  <param name="colors" value="['#ffb244','#ed723c','#da3333','#b01111','#7a0000']" />
  <param name="width" value="60" />
</object>

最后的结果是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The resulting donut chart

完整的工作示例代码可以在这里找到

虽然我们使用 D3 创建了一个圆环图小部件,但是它的使用潜力远远超过了图表。事实是,像 Chartist 这样的图书馆做图表做得非常好。我们可以将 Chartist 图表包装成一个 Svidget 小部件,类似于我们使用 D3 生成图表的方式,但是对于熟练的 JavaScript 开发人员来说,其优势可能并不明显。但是对于其他人来说,抽象出使用复杂库 D3 的实现细节是非常有益的。

有人问我,为什么要创建 Svidget.js 库?简单来说,它用交互式 SVG 解决了生产者-消费者抽象问题。在我的行业中,我们在数据中心运营的实时可视化仪表板中使用 SVG 小部件。消费者可以通过选择这些小部件并将它们连接到数据上来构建任何一个仪表板。相反,一个独立的制作团队可以构建通用的、可重用的小部件。这些小部件远远不止是简单的图表——它们可以代表冷却风扇、发电机、电路,甚至门。

同样,任何人都可以使用 Svidget 让非技术人员将复杂的 SVG 插图嵌入到他们的网站中。

乔·阿格斯特是基础层的首席软件工程师。编码是我众多努力中的一项。我还写了一部科幻小说《最后的六天》(T7),现在可以在 Kindle 上阅读。

用 Zeppelin Spark 和 Neo4j 构建图形数据管道

原文:https://towardsdatascience.com/building-a-graph-data-pipeline-with-zeppelin-spark-and-neo4j-8b6b83f4fb70?source=collection_archive---------3-----------------------

向 Zeppelin 添加网络支持

交互式笔记本如今非常流行。无论您是在数据工程(数据处理)中使用它们,还是在数据科学项目(数据分析/ML)中使用它们,它们都是“事实上的”标准,并且正在许多组织中取代幻灯片演示。除了 Jupyter 笔记本之外,Apache Zeppelin 的应用也很广泛,特别是因为它与 Apache Spark 和其他大数据系统集成得很好。

从我在不同环境下使用 Zeppelin 和 Neo4j 的经验开始,我开发了 Zeppelin 解释器,它连接到 Neo4j,以便直接在笔记本中查询和显示图形数据(图形和表格格式)。这个解释器现在是 zeplin 0.8的一部分,所以你可以开箱即用来查询和可视化你的图形数据!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本文将展示如何在 Docker 环境中使用 Zeppelin、Spark 和 Neo4j 来构建简单的数据管道。
我们将使用芝加哥犯罪数据集,它涵盖了自 2001 年以来发生的犯罪。整个数据集包含大约 600 万起犯罪和关于它们的元数据,例如位置、犯罪类型和日期等等。

在本例中,我们将使用由so crata API返回的 1000 个犯罪构成的数据集子集。

步骤 1:配置容器

你应该已经安装了 DockerDocker-Compose

不幸的是 Zeppelin 在嵌入式版本上有一个 bug ,我们需要解决它,使它像容器一样工作。为此,我们创建了自己的 docker 文件:

这是我们的合成文件。基本上将官方的 Neo4j 容器和我们的 Zeppelin 容器合并为两个服务。

对于您的本地设置,只需更改 *neo4j-zeppelin.yml* 的第 22 行和第 23 行,以便提供正确的路径。

现在让我们运行这个示例代码来加速我们的堆栈:

docker-compose -f neo4j-zeppelin.yml up -d

现在我们有两个可到达的服务:

步骤 2:配置 Zeppelin

如果您从我的 GitHub 存储库中下载并执行 compose 文件,那么一切都是预先配置好的。

但是我们来看一些**隐藏配置。**右上角有一个菜单

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击解释器,然后按“火花”筛选列表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如您所见,用黄色突出显示的是 Neo4j-Spark-Connector 连接 Neo4j 所需的三个属性。

现在,如果您将解释器过滤器更改为“neo4j ”,您会发现:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该页面包含 Neo4j 解释器的属性,尤其是 auth 信息。

第三步:我们的数据处理笔记本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The notebook in action

我们已经配置了 Zeppelin / Spark / Neo4j 堆栈,现在让我们享受一下数据分析的乐趣。

在 Zeppelin 中,每个笔记本由段落或块组成,每个段落或块包含处理特定任务的代码块。

在我们的笔记本中,第一个块用于从 Spark-Packages 存储库中下载我们项目中所需的依赖项:Neo4j-Spark-Connector

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在第二个块中,我们下载数据集并存储到我们的文件系统中

正如我在介绍中所说,我们将使用芝加哥犯罪数据集的一个小子集。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在第三个块中,我们将数据集从文件系统读入 Spark 数据集

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第四块中,我们使用

crimeDF.printSchema

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这个模式开始,我们将像这样构造一个图模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Graph Schema

我们有 4 个节点:

  • Beat(警区)带**beat**属性;
  • Crime具有**id, description, case_number, point** 属性;
  • CrimeType带有**primary_type**性质;
  • CrimeDate具有**parsed_date****date**属性

和 3 种关系:

  • ON_BEAT**Beat**开始,到**Crime**结束;
  • IS_TYPE从 a **Crime**开始,到 a **CrimeType**结束;
  • ON_DATE从 a **Crime**开始,到 a **CrimeDate**结束;

第五块中,我们将创建新列,以便添加解析日期地理空间参考。顺便说一下,从 Neo4j 3.4 开始,数据库本身支持日期和空间数据,但不幸的是 Neo4j-Spark-Connector 还不支持它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第六块中,我们通过使用 Zeppelin 上下文 API 简单地探索我们的数据集:

z.show(exendedCrimeDF)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在让我们跳到第七个模块中,在这里我们使用 Neo4j-Spark-Connector 获取数据。我们使用提供方法的Neo4jDataFrame:

Neo4jDataFrame.mergeEdgeList(sc: SparkContext,
    dataFrame: DataFrame,
    source: (label,Seq[prop]),
    relationship: (type,Seq[prop]),
    target: (label,Seq[prop]))

要将数据帧合并回 Neo4j 图形:

  • 两个节点按顺序由第一个属性合并;
  • 两个节点之间的关系被合并,序列中的所有属性都将在该关系上设置;
  • 序列中的属性名用作数据框的列名,目前没有名称转换;
  • 结果以 10000 为一批发送到图表中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

到目前为止,我们只在齐柏林飞艇和火花乐队工作。现在图形数据已经导入到 Neo4j 中,我们可以使用 Neo4j 解释器从 Zeppelin 查询 Neo4j。
要使用 Neo4j 解释器,我们必须使用特定的解释器绑定

%neo4j

接下来是我们的密码查询:

MATCH (crime:Crime)-[is:IS_TYPE]->(type:CrimeType),
 (crime)-[on:ON_DATE]->(date:CrimeDate)
RETURN crime, is, type, on, date
LIMIT 10

结果将显示为图形,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A Neo4j query block with graph query and visualization

该科分为五个不同的领域:

  • 红色:用于编写密码查询的区域;
  • 黄色:显示最新 Zeppelin 发行版中可用的新图形可视化的按钮;
  • 绿色:关于图形的一般信息;节点、边等…
  • 蓝色:用于呈现图形可视化的区域
  • 紫色:当你点击一个节点/边时,相关数据将会显示的区域

此外,结果图也将作为一个扁平的表格。因此,所有其他可视化(图表等)也是可用的,您可以通过单击相应的按钮在它们之间简单地切换。

图形可视化附带设置,以便提供一些配置:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The graph visualization settings

例如,通过这些设置,您可以自定义显示为节点标题的属性。

使用鼠标滚轮,您可以放大/缩小图表,以显示如下所示的标题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

利用 Zeppelin 动态表单

Neo4j 解释器可以利用 Zeppelin 动态表单来构建参数化查询,就像这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

好处:增加地理空间可视化

Zeppelin 有一个名为 Helium 的可插拔架构,可以轻松添加新的可视化内容。在右上方的菜单中点击氦气条目,然后在氦气页面中启用 zeplin-Leaflet 作为,如图所示。然后,您的密码查询结果也可以在地图上可视化。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以直接从 GitHub 下载整个笔记本代码。我很想得到你对 Apache Zeppelin 的 Neo4j 和图形解释器的反馈,请在评论或我的 GitHub 问题中告诉我。此外,如果你有 Zeppelin 和 Spark 的很酷的图形用例,也请分享它们,这样更多的人可以了解图形的力量。

用 Scikit-learn 构建 k-近邻模型

原文:https://towardsdatascience.com/building-a-k-nearest-neighbors-k-nn-model-with-scikit-learn-51209555453a?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

k-NN (Image credit)

k-近邻(k-NN)是一种有监督的机器学习模型。监督学习是指模型从已经标记的数据中学习。监督学习模型接受一组输入对象和输出值。然后,该模型根据这些数据进行训练,以学习如何将输入映射到所需的输出,这样它就可以学习根据看不见的数据进行预测。

k-NN 模型通过获取一个数据点并查看“k”个最接近的标记数据点来工作。然后,给数据点分配“k”个最接近点中大多数的标签。

例如,如果 k = 5,3 个点为“绿色”,2 个点为“红色”,那么所讨论的数据点将被标记为“绿色”,因为“绿色”占大多数(如上图所示)。

Scikit-learn 是一个用于 Python 的机器学习库。在本教程中,我们将使用 Scikit-learn 构建一个 k-NN 模型来预测患者是否患有糖尿病。

读入训练数据

对于我们的 k-NN 模型,第一步是读入我们将用作输入的数据。对于这个例子,我们使用糖尿病数据集。首先,我们将使用 Pandas 读入数据。我不会详细介绍熊猫,但如果你想进一步深入数据科学和机器学习,这是一个你应该熟悉的库。

import pandas as pd#read in the data using pandas
df = pd.read_csv(‘data/diabetes_data.csv’)#check data has been read in properly
df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来,我们来看看我们有多少数据。我们将在数据帧上调用“shape”函数,查看数据中有多少行和多少列。行表示患者的数量,列表示特征(年龄、体重等)的数量。)在数据集中。

#check number of rows and columns in dataset
df.shape

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,我们有 768 行数据(潜在的糖尿病患者)和 9 列数据(8 个输入特征和 1 个目标输出)。

将数据集分成输入和目标

现在让我们把数据集分成输入(X)和目标(y)。我们的输入将是除“糖尿病”之外的每一列,因为“糖尿病”是我们将试图预测的。因此,“糖尿病”将是我们的目标。

我们将使用 pandas 'drop ‘函数从数据帧中删除列’ diabetes ‘,并将其存储在变量’ X '中。这将是我们的投入。

*#create a dataframe with all training data except the target column*
X = df.drop(columns=[‘diabetes’])*#check that the target variable has been removed*
X.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将把数据集的“糖尿病”列插入到目标变量(y)中。

#separate target values
y = df[‘diabetes’].values#view target values
y[0:5]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将数据集拆分为训练和测试数据

现在,我们将数据集分为训练数据和测试数据。训练数据是模型将从中学习的数据。测试数据是我们将用来查看模型在看不见的数据上表现如何的数据。

Scikit-learn 有一个我们可以使用的名为“train_test_split”的函数,它使我们可以很容易地将数据集分成训练和测试数据。

from sklearn.model_selection import train_test_split#split dataset into train and test data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1, stratify=y)

“train_test_split”接受 5 个参数。前两个参数是我们之前分开的输入和目标数据。接下来,我们将“测试大小”设置为 0.2。这意味着 20%的数据将用于测试,剩下 80%的数据作为模型学习的训练数据。将“random_state”设置为 1 可以确保我们每次都能获得相同的分割,这样我们就可以重现我们的结果。

将“分层”设置为 y 会使我们的训练分割表示 y 变量中每个值的比例。例如,在我们的数据集中,如果 25%的患者患有糖尿病,75%的患者没有糖尿病,将“分层”设置为 y 将确保随机拆分有 25%的糖尿病患者和 75%的非糖尿病患者。

构建和训练模型

接下来,我们必须建立模型。代码如下:

from sklearn.neighbors import KNeighborsClassifier# Create KNN classifier
knn = KNeighborsClassifier(n_neighbors = 3)# Fit the classifier to the data
knn.fit(X_train,y_train)

首先,我们将创建一个新的 k-NN 分类器,并将“n_neighbors”设置为 3。概括地说,这意味着如果与新数据点最近的 3 个点中至少有 2 个是没有糖尿病的患者,那么新数据点将被标记为“没有糖尿病”,反之亦然。换句话说,一个新的数据点由 3 个最近点的多数标记。

我们将“n_neighbors”设置为 3 作为起点。我们将在下面更详细地讨论如何更好地为“n_neighbors”选择一个值,以便模型可以提高其性能。

接下来,我们需要训练模型。为了训练我们的新模型,我们将使用“fit”函数并传递我们的训练数据作为参数,以使我们的模型符合训练数据。

测试模型

一旦模型训练完毕,我们就可以使用模型上的“预测”功能对测试数据进行预测。如前面检查“y”时所见,0 表示患者没有糖尿病,1 表示患者有糖尿病。为了节省空间,我们将只显示测试集的前 5 个预测。

#show first 5 model predictions on the test data
knn.predict(X_test)[0:5]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,该模型预测测试集中的前 4 名患者“没有糖尿病”,而第 5 名患者“患有糖尿病”。

现在让我们看看我们的模型在整个测试集上有多精确。为此,我们将使用“score”函数,并传入我们的测试输入和目标数据,以查看我们的模型预测与实际结果的匹配程度。

#check accuracy of our model on the test data
knn.score(X_test, y_test)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的模型具有大约 66.88%的准确度。这是一个好的开始,但我们将在下面看到如何提高模型性能。

恭喜你。你现在已经建立了一个惊人的 k-NN 模型!

k 倍交叉验证

交叉验证是指数据集被随机分成“k”个组。其中一组用作测试集,其余的用作训练集。该模型在训练集上被训练,并在测试集上被评分。然后重复该过程,直到每个唯一的组都被用作测试集。

例如,对于 5 重交叉验证,数据集将被分成 5 组,模型将被训练和测试 5 次,因此每组都有机会成为测试集。这可以从下图中看出。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5-fold cross validation (image credit)

我们之前使用的训练-测试-拆分方法称为“保持”。交叉验证比使用维持方法更好,因为维持方法的得分取决于如何将数据拆分为定型集和测试集。交叉验证为模型提供了在多个拆分上进行测试的机会,因此我们可以更好地了解模型在看不见的数据上的表现。

为了使用交叉验证来训练和测试我们的模型,我们将使用交叉验证值为 5 的“cross_val_score”函数。“cross_val_score”将我们的 k-NN 模型和我们的数据作为参数。然后,它将我们的数据分成 5 组,并对我们的数据进行 5 次拟合和评分,每次都将准确度分数记录在一个数组中。我们将准确性分数保存在“cv_scores”变量中。

为了计算 5 个分数的平均值,我们将使用 numpy 的 mean 函数,传入“cv_score”。Numpy 是 Python 中一个有用的数学库。

from sklearn.model_selection import cross_val_score
import numpy as np#create a new KNN model
knn_cv = KNeighborsClassifier(n_neighbors=3)#train model with cv of 5 
cv_scores = cross_val_score(knn_cv, X, y, cv=5)#print each cv score (accuracy) and average them
print(cv_scores)
print(‘cv_scores mean:{}’.format(np.mean(cv_scores)))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用交叉验证,我们的平均分数约为 71.36%。与我们之前使用维持方法进行的测试相比,这更准确地展示了我们的模型在未知数据上的表现。

使用 GridSearchCV 超调模型参数

当建立我们的初始 k-NN 模型时,我们将参数“n_neighbors”设置为 3 作为起点,该选择背后没有真正的逻辑。

超调参数是指通过一个过程来为您的模型找到最佳参数,以提高精度。在我们的例子中,我们将使用 GridSearchCV 来寻找‘n _ neighbors’的最优值。

GridSearchCV 通过在我们指定的参数范围内多次训练我们的模型来工作。这样,我们可以用每个参数测试我们的模型,并找出最佳值以获得最佳精度结果。

对于我们的模型,我们将为“n_neighbors”指定一个值范围,以查看哪个值最适合我们的模型。为此,我们将创建一个字典,将’ n_neighbors '设置为键,并使用 numpy 创建一个值从 1 到 24 的数组。

我们使用网格搜索的新模型将采用新的 k-NN 分类器、我们的 param_grid 和交叉验证值 5,以便找到‘n _ neighbors’的最佳值。

from sklearn.model_selection import GridSearchCV#create new a knn model
knn2 = KNeighborsClassifier()#create a dictionary of all values we want to test for n_neighbors
param_grid = {‘n_neighbors’: np.arange(1, 25)}#use gridsearch to test all values for n_neighbors
knn_gscv = GridSearchCV(knn2, param_grid, cv=5)#fit model to data
knn_gscv.fit(X, y)

训练之后,我们可以检查我们测试的‘n _ neighbors’的哪个值表现最好。为此,我们将在模型上调用‘best _ params _’。

#check top performing n_neighbors value
knn_gscv.best_params_

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,14 是“n_neighbors”的最佳值。当“n_neighbors”为 14 时,我们可以使用“best_score_”函数来检查我们的模型的准确性。best_score_ '输出通过交叉验证获得的分数的平均准确度。

#check mean score for the top performing value of n_neighbors
knn_gscv.best_score_

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过使用网格搜索为我们的模型找到最佳参数,我们已经将我们的模型精度提高了 4%以上!

感谢阅读!本教程的 GitHub 库(jupyter 笔记本和数据集)可以在这里找到。

如果你想了解我的机器学习内容,请关注我:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值