TowardsDataScience 博客中文翻译 2020(五百六十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

k 近邻计算复杂度

原文:https://towardsdatascience.com/k-nearest-neighbors-computational-complexity-502d2c440d5?source=collection_archive---------7-----------------------

了解 kNN 算法的计算成本,并提供案例研究示例

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

kNN 算法的可视化(来源)

算法介绍

kNN (k 最近邻)是最简单的最大似然算法之一,通常在入门课程中作为第一批算法之一讲授。它相对简单但非常强大,尽管很少有人花时间去理解它的计算复杂性和实际问题。它可以以相同的复杂度用于分类和回归,因此为了简单起见,我们将考虑 kNN 分类器。

kNN 是一种关联算法-在预测过程中,它会搜索最近的邻居,并将他们的多数投票作为样本的预测类别。训练阶段可能存在,也可能不存在,一般来说,我们有两种可能性:

  1. 蛮力方法——计算从新点到训练数据矩阵 X 中每个点的距离,对距离进行排序并取 k 个最近的,然后进行多数投票。不需要单独训练,所以只考虑预测复杂度。
  2. 使用数据结构-将 X 中的训练点组织到辅助数据结构中,以实现更快的最近邻查找。这种方法使用额外的空间和时间(用于在训练阶段创建数据结构)来进行更快的预测。

我们关注 Scikit-learn 中实现的方法,这是 Python 中最流行的 ML 库。它支持蛮力,k-d 树和球树数据结构。这些方法相对简单、高效,非常适合 kNN 算法。这些树的构造源于计算几何,而不是机器学习,与我们没有太大关系,所以我将在概念层面上更详细地介绍它。关于这方面的更多细节,请参见文章末尾的链接。

在下面的所有复杂性中,计算距离的时间被省略,因为与算法的其余部分相比,它们在大多数情况下是可以忽略的。此外,我们标记:

  • n:训练数据集中的点数
  • d:数据维度
  • k:我们考虑投票的邻居数量

暴力破解法

训练时间复杂度:

训练空间复杂度: O(1)

预测时间复杂度: O(k * n * d)

预测空间复杂度: O(1)

训练阶段在技术上是不存在的,因为所有的计算都是在预测过程中完成的,所以我们在时间和空间上都有O(1)

正如方法名所示,预测阶段是一个简单穷举搜索,在伪代码中是:

Loop through all points k times:
    1\. Compute the distance between currently classifier sample and 
       training points, remember the index of the element with the 
       smallest distance (ignore previously selected points)
    2\. Add the class at found index to the counterReturn the class with the most votes as a prediction

这是一个嵌套循环结构,其中外部循环执行k步,内部循环执行n步。第三点是O(1),第四点是O(# of classes),所以他们比较小。此外,我们必须考虑维度的数量d,更多的方向意味着更长的向量来计算距离。因此,我们有了O(n * k * d)时间复杂度。

至于空间复杂度,我们需要一个小向量来统计每个类的投票数。它几乎总是非常小并且是固定的,所以我们可以把它当作一个O(1)空间复杂度。

k-d 树方法

训练时间复杂度: O(d * n * log(n))

训练空间复杂度: O(d * n)

预测时间复杂度: O(k * log(n))

预测空间复杂度: O(1)

在训练阶段,我们必须构建 k-d 树。这个数据结构拆分了 k 维空间(这里 k 是指空间的 k 维,不要把这个和 k 混淆为最近邻的个数!)并允许更快地搜索最近的点,因为我们“知道在那个空间中去哪里看”。你可能会认为它是 BST 在许多维度上的推广。它使用轴对齐的切割来“切割”空间,将点分成子节点中的组。

构建 k-d 树本身不是机器学习任务,因为它源于计算几何领域,所以我们不会详细讨论这一点,只在概念层面上讨论。时间复杂度通常是O(d * n * log(n)),因为插入是O(log(n))(类似于常规 BST)并且我们有来自训练数据集的n点,每个点有d个维度。我假设数据结构的有效实现,即它在O(n)中找到最佳分割点(维度中的中值),这对于中位数算法是可能的。空间复杂度是O(d * n) —注意,它取决于维度d,这是有意义的,因为更多的维度对应更多的空间划分和更大的树(除了同样原因的更大的时间复杂度)。

至于预测阶段,k-d 树结构自然支持“k 最近点邻居查询”操作,这正是我们对于 kNN 所需要的。简单的方法是只查询k次,删除每次找到的点——因为查询需要O(log(n)),所以总共是O(k * log(n))。但是由于 k-d 树已经在构造过程中减少了空间,所以在一次查询之后,我们大概知道在哪里寻找——我们可以搜索该点周围的“环境”。因此,k-d 树的实际实现支持一次查询整个k邻居,并且具有复杂度O(sqrt(n) + k),这对于机器学习中非常常见的更大维度要好得多。

以上复杂度为平均复杂度,假设 k-d 树平衡。对于不平衡的树,上面假定的O(log(n))时间可能降低到O(n),但是如果在树构造期间使用中间值,我们应该总是得到具有大约O(log(n))插入/删除/搜索复杂度的树。

球树法

训练时间复杂度: O(d * n * log(n))

训练空间复杂度: O(d * n)

预测时间复杂度: O(k * log(n))

预测空间复杂度: O(1)

球树算法采用另一种方法来划分训练点所在的空间。与用中间值“切割”划分空间的 k-d 树相反,球树将点分组为组织成树结构的“球”。它们从最大的(根,有所有的点)到最小的(叶,只有几个甚至 1 个点)。它允许快速最近邻查找,因为附近的邻居在相同的或至少接近的“球”中。

在训练阶段,我们只需要构建球树。构造球树的算法有几种,但与 k-d 树(为此称为“k-d 构造算法”)最相似的是O(d * n * log(n)),与 k-d 树相同。

由于树构建的相似性,预测阶段的复杂性也与 k-d 树相同。

在实践中选择方法

总结一下复杂度:蛮力是大 O 记法中最慢的,而 k-d 树和球树都有同样低的复杂度。那我们怎么知道用哪一个呢?

为了得到答案,我们必须同时考虑训练和预测时间,这就是为什么我提供了两者。蛮力算法只有一个复杂度,对于预测,O(k * n)。其他算法需要首先创建数据结构,因此对于训练和预测,它们得到O(d * n * log(n) + k * log(n)),没有考虑空间复杂性,这可能也是重要的。因此,在频繁构建树的情况下,训练阶段可能会超过其更快的最近邻查找的优势。

应该用 k-d 树还是球树?这取决于数据结构-相对均匀或“表现良好”的数据将更好地利用 k-d 树,因为空间的切割将很好地工作(在所有切割之后,近点将在树叶中接近)。对于更聚类的数据,来自球树的“球”将更好地反映结构,因此允许更快的最近邻搜索。幸运的是,Scikit-learn 支持“auto”选项,它会自动从数据中推断出最佳的数据结构。

让我们通过两个案例来看看这一点,这两个案例是我在学习和工作中遇到的。

案例研究 1:分类

kNN 更“传统”的应用是数据分类。它通常有相当多的点,例如 MNIST 有 60k 的训练图像和 10k 的测试图像。分类是离线完成的,这意味着我们首先进行训练阶段,然后在预测过程中使用结果。因此,如果我们要构造数据结构,我们只需要这样做一次。对于 10k 测试图像,让我们比较蛮力(每次计算所有距离)和 3 个邻居的 k-d 树:

蛮力(O(k * n) ): 3 * 10,000 = 30,000

k 线树(O(k * log(n)) ): 3 * log(10,000) ~ 3 * 13 = 39

对比:39 / 30,000 = 0.0013

如您所见,性能提升是巨大的!数据结构方法只使用了蛮力时间的很小一部分。对于大多数数据集,这种方法是一个明显的赢家。

案例研究 2:实时智能监控

机器学习通常用于图像识别,通常使用神经网络。它对于实时应用非常有用,在实时应用中,它通常与摄像机、警报器等集成在一起。神经网络的问题是,它们经常检测同一个对象两次或更多次——即使是像 YOLO 这样最好的架构也有这个问题。实际上,我们可以通过最近邻搜索用一种简单的方法来解决这个问题:

  1. 计算每个边界框(矩形)的中心
  2. 对于每个矩形,搜索其最近的邻居(1NN)
  3. 如果点比选定的阈值更近,则合并它们(它们检测到相同的对象)

关键部分是寻找另一个包围盒的最近中心(点 2)。这里应该使用哪种算法?通常我们只有几个运动物体在摄像机上,可能多达 30-40 个。对于这样一个小数字,使用数据结构进行快速查找所带来的加速可以忽略不计。每一帧都是一个独立的图像,所以如果我们想要构建一个 k-d 树,我们必须对每一帧都这样做,这可能意味着每秒 30 次——总的来说是一个巨大的成本。因此,对于这种情况,简单的强力方法工作最快,并且具有最小的空间需求(对于重型神经网络或对于相机中的嵌入式 CPU,这可能是重要的)。

总结

kNN 算法是机器学习中一种流行、简单且有用的技术,我希望在阅读完这篇文章后,你能理解它的复杂性以及你可以在哪里以及如何使用这种方法的真实场景。

参考资料:

6 步 k 近邻

原文:https://towardsdatascience.com/k-nearest-neighbors-in-6-steps-efbcbebce54d?source=collection_archive---------15-----------------------

使用 scikit-学习 python

本书旨在成为一个应用指南,介绍如何利用 K 近邻(KNN)方法来解决 python 中的商业问题。KNN 最流行的用例是在分类中。有趣的是,它也适用于 KNN 回归。

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

法比奥Unsplash 上的照片

这个概念

从 KNN 分类器模型的基础开始。KNN 分类器模型在 3 个主要步骤中工作,以预测前所未有的特征值(不在训练数据中)的标签。

  1. 它会记住整个训练测试集——特别是哪个特征产生了哪个 y 标签。
  2. 它定义了 K 个最近的最相似实例,其中 K 是用户定义的整数。对于给定的数据点,它会查看最近的要素及其各自的标注。
  3. 它根据最近邻居的标签来预测新标签。通常,这是多数票。

回到 KNN 回归:不同之处在于,KNN 回归模型从前所未有的特征值的连续分布中预测新值。从概念上讲,它如何获得预测值与 KNN 分类模型类似,只是它将采用其 K 个最近邻的平均值。

k 近邻分类器

包裹

让我们首先导入所需的包:

  1. numpy 和pandas:python 中的数据和数组操作
  2. *来自 matplotlib 库的 pyploy 模块:*数据可视化
  3. sklearn 模块用于创建列车测试分割,并创建 KNN 对象。
# Packages
%matplotlib notebook
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import MinMaxScaler

数据

数据集有 59 行和 7 列,前 10 行如下所示。为了简单起见,我们不会使用所有的特性;我们的目的是使用质量宽度来预测标签水果 _ 标签

#import data
fruits = pd.read_table('readonly/fruit_data_with_colors.txt')feature_names_fruits = ['height', 'width', 'mass', 'color_score'] #x variable names
X_fruits = fruits[feature_names_fruits] #setting the col names
y_fruits = fruits['fruit_label'] #setting the col names
target_names_fruits = ['apple', 'mandarin', 'orange', 'lemon'] #potential classesfruits.head(10)

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

水果.头(10)

1.特征工程

丢弃不需要的要素和标注。您将对数据集执行的要素工程的范围在很大程度上取决于您所操作的业务环境。

# setting up the 2 dimensional array of height and width predictors. other x vars discarded
X_fruits_2d = fruits[['height', 'width']]
y_fruits_2d = fruits['fruit_label'] #labels

2.列车测试分离

现在,我们将使用 75/25 的训练测试拆分来拆分 59 个条目,其中 75%的数据用于训练 KNN 分类模型,剩余的 25%从模型中“隐藏”出来,用于验证结果。75/25 分割是由 train_test_split 执行的默认分割。

#75 / 25 train test split
X_train, X_test, y_train, y_test = train_test_split(X_fruits, y_fruits, random_state=0)

3.特征最小-最大缩放

查看质量宽度特征,我们注意到它们都在不同的尺度上:质量值的范围是两位数和三位数,而宽度值的范围通常是个位数。如果值的范围太大,目标函数可能无法正常工作,因为一些特征可能会无意中对预测产生更大的影响。

最小-最大缩放是一种相对简单的方法,类似于对分布应用 Z 分数归一化。相对于要素最小值和最大值,值被重新调整到-1 和 1 之间的范围内。

scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
# we must apply the scaling to the test set that we computed for the training set
X_test_scaled = scaler.transform(X_test)

4.创建适合的 KNN 对象

我们可以用第一行创建一个“空的”KNN 分类器模型。此外,n _ neighbors参数允许控制我们的‘K’值。接下来,模型将根据训练数据集中缩放后的 X 要素及其对应的 Y 标注进行拟合。

knn = KNeighborsClassifier(n_neighbors = 5) #setting up the KNN model to use 5NN
knn.fit(X_train_scaled, y_train) #fitting the KNN

5.评估绩效

类似于如何使用 R 平方度量来评估简单线性模型的拟合优度,我们可以使用 F 值来评估 KNN 分类器。 F 值衡量模型正确预测标签的准确性。我们可以观察到,该模型在 95%的训练数据时间和 100%的保留测试数据集时间上预测标签是正确的。

#Checking performance on the training set
print('Accuracy of K-NN classifier on training set: {:.2f}'
     .format(knn.score(X_train_scaled, y_train)))
#Checking performance on the test set
print('Accuracy of K-NN classifier on test set: {:.2f}'
     .format(knn.score(X_test_scaled, y_test)))

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

6.做一个预测

最后,我们想用这个模型来做预测。给定一个质量、宽度、高度和 color_score 分别为 5.5、2.2、10 和 0.70 的水果,这是什么水果?在适当的最小-最大缩放之后,模型预测它是普通话。

example_fruit = [[5.5, 2.2, 10, 0.70]]
example_fruit_scaled = scaler.transform(example_fruit)
#Making an prediction based on x values
print('Predicted fruit type for ', example_fruit, ' is ', 
          target_names_fruits[knn.predict(example_fruit_scaled)[0]-1])

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

7.测绘

让我们看看如何使用 matplotlib 库可视化数据。我们还可以进一步检查数据集在不同 K 值下的表现。下面我绘制了 K = 1,5,11。

通常,我们可以观察到,K 值越低,训练数据的过度拟合程度越高。该模型尝试使用较低的 K 值更准确地预测每个点。结果,我们可以观察到分类区域之间的边界是锯齿状的,并且随着局部变化而剧烈变化。

查看 K = 11 的 KNN,我们可以看到分类区域之间的边界相对更平滑。这种 KNN 模型在捕捉全球趋势方面变得相对更好,并允许它更通用于一个持续的测试集。

from adspy_shared_utilities import plot_two_class_knnX_train, X_test, y_train, y_test = train_test_split(X_C2, y_C2,
 random_state=0)plot_two_class_knn(X_train, y_train, 1, ‘uniform’, X_test, y_test)
plot_two_class_knn(X_train, y_train, 5, ‘uniform’, X_test, y_test)
plot_two_class_knn(X_train, y_train, 11, ‘uniform’, X_test, y_test)

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

K = 1,5,11

尾注

我通过由 Coursera 主办的密歇根大学 MOOC“Python 中的应用机器学习”了解到了这一点。

如果你有问题或者想讨论后新冠肺炎世界,请随时联系我,LinkedIn !

我希望我能够以这样或那样的方式帮助您学习数据科学方法!

这是另一篇数据科学文章!

[## 使用 scikit-learn 进行线性回归

本文应该足以涵盖如何在 python 中运行构造一个简单的线性回归;它还将包含…

medium.com](https://medium.com/python-in-plain-english/linear-regressions-with-scikitlearn-a5d54efe898f)

k 近邻(KNN)算法

原文:https://towardsdatascience.com/k-nearest-neighbors-knn-algorithm-23832490e3f4?source=collection_archive---------8-----------------------

寻找最近邻居的算法

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

图片来自 Unsplash 的 Joshua J. Cotten

目录:

  1. 什么是 KNN?
  2. KNN 算法的工作原理
  3. K 变了会怎样?
  4. 如何选择合适的 K?
  5. KNN 的局限性
  6. KNN 的实际应用
  7. 结论

1.什么是 KNN?

k 近邻(KNN)是一种有监督的机器学习算法。监督机器学习算法的目标是学习一个函数,使得 f(X) = Y,其中 X 是输入,Y 是输出。KNN 既可用于分类,也可用于回归。在本文中,我们将只讨论分类。虽然对于回归来说,只是一个微小的变化。

KNN 的特性在于它是一种懒惰的学习算法和一种非参数方法。

懒学习是指算法学习时间几乎为零,因为它只存储训练部分的数据(没有学习一个函数)。然后,存储的数据将用于评估新的查询点。

非参数方法是指不假设任何分布的方法。因此,KNN 不必为分布寻找任何参数。而在参数方法中,模型发现新的参数,这些参数又将用于预测目的。KNN 唯一的超参数(由用户提供给模型)是 K,这是为了比较需要考虑的点数。

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

k-最近邻居。来源

上图中,黄色是查询点,我们想知道它属于哪一类(红色还是绿色)。

K=3 时,考虑黄点的 3 个最近邻点,并且基于多数将类分配给查询点(例如,2 个绿色和 1 个红色-则它属于绿色类)。类似地,对于 K=5,5 个最近邻被考虑用于比较,并且大多数将决定查询点属于哪个类。这里需要注意的一点是,如果 K 的值是偶数,那么在进行多数表决时可能会产生问题,因为数据具有偶数个类(即 2 个)。因此,当数据具有偶数个类时,选择 K 作为奇数,当数据具有奇数个类时,选择偶数。

2.KNN 算法的工作原理

在训练阶段,模型将存储数据点。在测试阶段,计算从查询点到来自训练阶段的点的距离,以对测试数据集中的每个点进行分类。可以计算各种距离,但最流行的是欧几里德距离(用于较小维度的数据)。

查询点(q)和训练数据点§之间的欧几里德距离被定义为

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

点 p 和 q (n 维点)之间的欧几里德距离。来源

也可以根据数据使用其他距离度量,如 Manhattan、Hamming 和 Chebyshev 距离,这超出了本文的范围。

让我们用一个例子来学习它:

我们有 500 个 N 维点,300 个是 0 类,200 个是 1 类。

计算查询点类别的步骤是:

  1. 从查询点开始计算所有 500 个点的距离。
  2. 基于 K 的值,K 个最近邻被用于比较目的。
  3. 假设 K=7,7 个点中有 4 个是 0 类,3 个是 1 类。然后基于多数,查询点 p 被分配为类别 0。

3.K 变了会怎样?

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

分离红色和蓝色类的决策表面,k=1(左)和 k=5(右)。作者图片

K=1 意味着它将采用一个最近邻,并基于此对查询点进行分类。划分类别的表面将非常不平坦(许多顶点)。

这里出现的问题是,如果数据中存在异常值,决策面会将其视为数据点。因此,KNN 将在训练数据集上表现出色,但会在测试数据集(看不见的数据)上对许多点进行错误分类。这被认为是过度拟合,因此,KNN 对异常值很敏感。

随着 K 值的增加,表面变得平滑,不会将异常值视为数据点。这也将在测试数据集上更好地概括模型。

如果 K 值非常大,模型将会欠拟合,并且将无法对新的数据点进行分类。例如,如果 K 等于数据点的总数,则无论查询点位于何处,模型都会根据整个数据集的多数类对查询点进行分类。

选择正确的 K 值将给出准确的结果。但是如何选择呢?

4.如何选择合适的 K?

在实际问题中,数据集分为三个部分,即训练、验证和测试数据。在 KNN,训练数据点被存储,并且没有学习被执行。验证数据是用来检验模型性能的,测试数据是用来预测的。

要选择最佳 K,请在训练数据集和验证数据集上绘制模型的误差(误差= 1-精度)。最佳 K 是验证误差最低的地方,并且训练和验证误差彼此接近。

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

错误率和 K. 来源

5.KNN 的局限性

时间复杂度和空间复杂度是巨大的,这是 KNN 的一大劣势。时间复杂度指的是模型评估查询点的类别所花费的时间。空间复杂度是指算法使用的总内存。如果我们在训练中有 n 个数据点,并且每个点是 m 维的。那么时间复杂度是 O(nm)量级,如果我们有更高维的数据,这将是巨大的。因此,KNN 不适合高维数据。

另一个缺点是,如果数据点远离存在的类(没有相似性),KNN 将分类该点,即使它是一个离群值。为了克服时间复杂性的问题,可以使用 KD-Tree 和 LSH(Locality Sensitive Hashing,Locality Sensitive Hashing)等算法,这不在本文讨论范围之内。

6.KNN 的实际应用

  1. KNN 可以用于推荐系统。虽然在现实世界中,推荐系统使用更复杂的算法。KNN 不适合高维数据,但 KNN 是一个很好的系统基线方法。许多公司为其消费者提供个性化推荐,如网飞、亚马逊、YouTube 等。
  2. KNN 可以搜索语义相似的文档。每个文档都被视为一个向量。如果文档彼此靠近,这意味着文档包含相同的主题。
  3. KNN 可以有效地用于检测异常值。一个这样的例子是信用卡欺诈检测。

7.结论

K-最近邻(KNN)是在给定 k 值的情况下识别最近邻。它是一种懒惰学习和非参数算法。KNN 在低维数据集上工作,而在处理高维数据时面临问题。

k-最近邻(kNN)-解释

原文:https://towardsdatascience.com/k-nearest-neighbors-knn-explained-cbc31849a7e3?source=collection_archive---------6-----------------------

详细的理论解释和 scikit-learn 实现

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

图像来源

k-最近邻(kNN)是一种受监督的机器学习算法,可用于解决分类和回归任务。我认为 kNN 是一种来自现实生活的算法。人们往往会受到周围人的影响。我们的行为受到从小一起长大的朋友的指导。我们的父母也在某些方面塑造了我们的性格。如果你和热爱运动的人一起长大,你很可能最终也会热爱运动。当然也有例外。kNN 的工作原理类似。

一个数据点的价值是由其周围的数据点决定的。

  • 如果你有一个非常亲密的朋友,并且大部分时间都和他/她在一起,你们最终会分享相似的兴趣和享受相同的东西。也就是 k=1 的 kNN。
  • 如果你总是和一群 *5 人在一起,*这个群体中的每个人都会对你的行为产生影响,你最终会成为 5 人中的平均水平。那就是 kNN,其中 k=5

kNN 分类器通过多数表决原则确定数据点的类别。如果 k 设置为 5,则检查 5 个最近点的类。根据多数类进行预测。类似地,kNN 回归取 5 个最近点的平均值。

我们观察接近的人,但是数据点是如何确定接近的?测量数据点之间的距离。测量距离的方法有很多。欧几里德距离(闵可夫斯基距离与 p=2)是最常用的距离度量之一。下图显示了如何计算二维空间中两点之间的欧几里德距离。它是使用点的 x 和 y 坐标之差的平方来计算的。

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

在上面的例子中,欧几里德距离是(16 + 9)的平方根,也就是 5。二维中的欧几里得距离让我们想起了著名的勾股定理

对于二维空间中的两个点来说,这似乎非常简单。每个维度代表数据集中的一个未来。我们通常有许多具有许多特征的样品。为了能够清楚地解释这个概念,我将回顾一个二维空间中的例子(即 2 个特征)。

你可以访问这个 github repo 中的所有代码。放心用吧!

让我们从导入库开始:

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

Scikit-learn 提供了许多有用的功能来创建合成数据集,这对实践机器学习算法非常有帮助。我将使用make _ blobs函数。

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

此代码创建了一个数据集,包含 100 个样本,分为 4 类,特征数为 2。使用相关参数可以轻松调整样本、特征和类别的数量。我们还可以调整每个集群(或类)的分布程度。让我们想象一下这个合成数据集:

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

对于任何有监督的机器学习算法,将数据集划分为训练集和测试集是非常重要的。我们首先训练模型,并使用数据集的不同部分对其进行测试。如果这种分离没有完成,我们基本上是用模型已经知道的一些数据来测试模型。我们可以使用 train_test_split 函数轻松实现这种分离。

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

我们可以分别使用 train_sizetest_size 参数指定有多少原始数据用于训练或测试集。训练集的默认分离度为 75%,测试集的默认分离度为 25%。

然后我们创建一个 kNN 分类器对象。为了显示 k 值的重要性之间的差异,我创建了 k 值为 1 和 5 的两个分类器。然后使用训练集训练这些模型。 n_neighbors 参数用于选择 k 值。默认值为 5,因此不必显式写入。

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

然后我们预测测试集中的目标值,并与实际值进行比较。

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

为了查看 k 值的影响,让我们可视化 k=5 和 k=1 的测试集和预测值。

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

结果似乎非常相似,因为我们使用了一个非常小的数据集。然而,即使在小数据集上,不同的 k 值对某些点的预测也是不同的。

如何找到最佳 k 值

  • k=1 :模型太具体,没有很好的概括。它对噪音也很敏感。该模型在训练集上实现了高精度,但是在新的、以前看不到的数据点上将是差的预测器。因此,我们很可能以一个过度拟合的模型而告终。
  • k=100 :该模型过于一般化,在训练集和测试集上都不是一个好的预测器。这种情况被称为欠适配。

我们如何找到最佳的 k 值?Scikit-learn 提供了 GridSearchCV 函数,使我们能够轻松检查 k 的多个值。让我们使用 scikit-learn datasets 模块下的数据集来查看一个示例。

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

在导入所需的库并加载数据集之后,我们可以创建一个 GridSearchCV 对象。

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

我们不需要分割数据集,因为 cv 参数分割数据集。cv 参数的缺省值是 5,但是我明确地写了它来强调为什么我们不需要使用 train_test_split。

cv=5 基本上将数据集分成 5 个子集。GridSearchCV 进行 5 次迭代,每次使用 4 个子集进行训练,1 个子集进行测试。通过这种方式,我们能够将所有数据点用于训练和测试。

我们可以使用 best_params_ 方法检查哪些参数能给出最佳结果:

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

在这种情况下,k 的最佳值是 12。

k 近邻的利弊

优点

  • 简单易懂
  • 不做任何假设,因此可以在非线性任务中实现。
  • 适用于多个类别的分类
  • 处理分类和回归任务

缺点

  • 随着数据点数量的增加,会变得非常慢,因为模型需要存储所有的数据点。
  • 内存效率不高
  • 对异常值敏感。离群也有一票!

感谢您的阅读。如果您有任何反馈,请告诉我。

我关于机器学习算法的其他帖子

用于异常检测的 k-最近邻(kNN)

原文:https://towardsdatascience.com/k-nearest-neighbors-knn-for-anomaly-detection-fdf8ee160d13?source=collection_archive---------1-----------------------

用于异常值和异常检测的小数据科学

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

妮娜·斯特雷尔在 Unsplash拍摄的照片

k-最近邻

kNN 是一种监督 ML 算法,经常用于数据科学中的分类问题(有时也用于回归问题)。这是一种最简单但被广泛使用的算法,有很好的使用案例,如构建推荐系统、人脸检测应用等。

最近邻族的基本假设是相似的观测值彼此接近,异常值通常是孤立的观测值,远离相似观测值的聚类。

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

kNN 概念图(图片:作者)

由于本文的目的是讨论一个用例——异常检测,所以我不会深入讨论 kNN 的更多细节。但是如果你感兴趣的话,可以看看所有最近邻算法的文档,网上有很多描述 kNN 如何工作的资料。如果你在评论中留言,我可以提供一些有用的资源。

用于异常检测的 kNN

虽然 kNN 是一种有监督的 ML 算法,但当涉及到异常检测时,它采用一种无监督的方法。这是因为在该过程中没有实际的“学习”,并且在数据集中没有预先确定的“异常值”或“非异常值”的标记,相反,它完全基于阈值。数据科学家任意决定截止值,超过该值的所有观察结果都被称为异常(我们将在后面看到)。这也是为什么没有训练测试数据分割或准确性报告。

今天的文章是我的异常、异常值和欺诈检测算法系列的继续,并附有实际操作的示例代码。我之前的 8 篇文章谈到了异常检测领域中可用的不同工具和技术,如果您有兴趣了解它们,请访问以下链接:

现在让我们继续用 Python 编程语言做一个 kNN 算法的简单演示。

步骤 1:导入库

这个演示只需要很少的库:pandasnumpy用于处理数据,matplotlib用于可视化(可选),而sklearn用于导入 kNN 算法。

# import libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors

第二步:数据准备

我正在使用来自 Github repo 的著名的虹膜数据集,所以你可以跟着练习,不用担心从哪里得到数据,如何清理它。

# import data
data = pd.read_csv("[https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv](https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv)")# input data
df = data[["sepal_length", "sepal_width"]]

现在,让我们将选择用于建模的两个变量可视化。

# scatterplot of inputs data
plt.scatter(df["sepal_length"], df["sepal_width"])

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

数据准备的最后一步是将特征列转换为数组。

# create arrays
X = df.values

第三步:建模

像大多数机器学习实现一样,实际建模只需很少的努力。首先,用您选择的参数实例化模型,然后使模型适合您的数据。就是这样!

kNN 中的关键参数是 n_neighbors ,它决定了用于计算测量点距离的邻居数量。

# instantiate model
nbrs = NearestNeighbors(n_neighbors = 3)# fit model
nbrs.fit(X)

步骤 4:异常检测

既然我们已经拟合了模型,接下来是提取模型输出的时候了—(a)数据点之间的距离和(b)相关的指数值—这些输出可用于检测异常。

# distances and indexes of k-neaighbors from model outputs
distances, indexes = nbrs.kneighbors(X)# plot mean of k-distances of each observation
plt.plot(distances.mean(axis =1))

绘制数据集中每个观测值的平均距离。

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

正如我们所看到的,距离度量中有一些尖峰,这些尖峰是数据集中潜在的异常或异常值。

现在,数据科学家面临一个最重要的决策——确定过滤异常的截止值。

如上图所示,一些截止值可能是-0.25、0.20、0.15 (y 轴),每个值过滤的异常值数量越来越多。

对于这个演示,让我们慷慨地选择 0.15 作为临界值,以获得更多的异常值。慷慨的原因是能够进一步检查数据,这样我们就不会遗漏异常值。

# visually determine cutoff values > 0.15
outlier_index = np.where(distances.mean(axis = 1) > 0.15)
outlier_index

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

# filter outlier values
outlier_values = df.iloc[outlier_index]
outlier_values

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

绘图 5(可选):绘制异常

我们已经在步骤 4 中识别了异常数据点,但是我们可以采取额外的步骤来可视化异常数据点。

# plot data
plt.scatter(df["sepal_length"], df["sepal_width"], color = "b", s = 65)# plot outlier values
plt.scatter(outlier_values["sepal_length"], outlier_values["sepal_width"], color = "r")

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

摘要

在本文中,我演示了如何实现 kNN——一种机器学习算法——来识别数据集中的异常。目的是展示一些简单的步骤来建立直觉,但是当然,现实世界的实现需要更多的实验来找出对于特定的环境和行业什么是有效的,什么是无效的。例如,在本演示中,我们停在了第 4 步,但现实世界中的数据科学家会更进一步,检查并重新检查过滤器数据点,以便与其他工具或领域专家进行双重检查。

感谢关注,要了解更多关于我的工作,你可以在 TwitterLinkedIn 上关注我

k-最近邻解释-第 2 部分

原文:https://towardsdatascience.com/k-nearest-neighbour-explained-part-2-f23d14fcb8c?source=collection_archive---------38-----------------------

了解最近邻的距离计算是如何进行数学计算的!

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

来源:U 形数据上的 KNN

在这个故事中,我们将讨论用于计算两个向量之间距离的不同类型的距离测量指标。这个度量的应用是在 K-NN 算法中寻找最近的邻居。我们将研究这些距离在 Python 中的实现。

这篇文章是以前写的关于 K-NN 的第 1 部分的延续。如果你还没有读过,读一读再回来。

[## k-最近邻解释-第 1 部分

KNN 算法背后的科学解释!

medium.com](https://medium.com/analytics-vidhya/k-nearest-neighbour-explained-part-1-5e5e9192050)

欧几里得距离

这是一种距离测量技术,通过直接将空间中的两点首尾相连来计算它们之间的距离。让我们看看下图所示的 2D 平面,平面上有点 p(p1,p2)q(q1,q2) 。现在我们需要找到这些点之间的距离,所以我们使用毕达哥拉斯定理来计算两点之间的距离,这就是欧几里得距离。

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

来源:维基百科上的欧几里德距离

对于点 p(p1,p2)q(q1,q2) 我们有二维向量,因此使用以下公式计算距离:

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

现在,以同样的方式,我们应用坐标为 p(p1,p2,p3)q(q1,q2,q3) 的三维向量

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

因此,如果我们在空间中有一个 n 维向量(我们不能直接可视化),那么使用相同的模式,我们将计算两点之间的距离,

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

因此,作为一个结论,空间中任意两点之间的距离是通过使用一条称为欧几里德距离的直线直接将这些点首尾相连来计算的。

Python3.7 中 3D 矢量实现的欧几里德距离

曼哈顿距离

第二个令人惊叹的距离计算方法是曼哈顿距离,也称为 【出租车距离】 因为就像出租车穿过城市的街道到达城市中的一个点一样,曼哈顿距离是通过计算绝对距离的总和来计算的。

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

来源:维基百科上的曼哈顿距离

那么,为什么它被称为曼哈顿呢?曼哈顿距离被命名为 曼哈顿 是因为当我们从卫星上看纽约市的曼哈顿区域时,道路和车道看起来完全像是对称网格图案因此,对于出租车来说,要在城市内从一个点行驶到另一个点,它必须遵循在 x 轴上移动一个动作和在 y 轴上移动一个动作的策略,这就是绝对行驶路径。

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

来源:纽约曼哈顿谷歌地图

曼哈顿距离可以使用 L1 范数的概念来计算,其中 p(p1,p2,…,pn)q(q1,q2,…,qn) 是 n 维向量。

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

汉娩距

有一种惊人的距离查找技术叫做 【汉明距离】 它通常用于查找两个字符串之间的对称距离,计算方法是找出两个字符串中所有位置的不相等字符,然后将它们相加,计算出总的不相等字符值。

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

来源:汉明距离维基百科

为什么叫海明距离?汉明距离是以理查德·汉明的名字命名的,他在关于汉明码的基础论文中介绍了这个概念。

为了找出两个字符串 S1 和 S2 之间的距离,我们开始同时从左到右一个接一个地探索两个字符串中的所有字符,每当第一个字符串中的字符与第二个字符串中相同位置的字符不相等时,我们就将距离的计数增加 1,这仅仅意味着只有当两个字符串中的字符不匹配时,计数才增加。

“汉明距离只在两个弦的长度完全相同时有效.”

例如,“ karolin ”和“ kathrin ”之间的距离是 3,因为第一个字符串的位置 3、4 和 5 处的字符对于第二个字符串是不同的,这使距离值增加了 1。

汉明距离在 Python 3.7 中的实现

余弦距离或余弦相似度

余弦相似度是在两个向量 X1 和 X2 之间测量的角距离,这意味着 X1 和 X2 之间的角度的。角度越小,其 cos(角度) 越高,因此其余弦相似度越高。**

“余弦相似性表示两个向量之间的方向相似性”

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

来源:奥雷利两个项目之间的余弦相似度

例如,角度为 0 的两个向量具有 cos(0 )=1 ,这是最高的相似度,而角度为 90 的向量给出 cos(90 )=0 ,从而给出向量之间的‘0’相似度。同样,当两个向量之间的角度达到 180 时,相似度甚至变成’-1’

给定两个向量 X1 和 X2,它们的 Cos-Sim 可以计算为:

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

余弦相似距离在 Python 3.7 中的实现

由 Paras Varshney 撰写的关于数据科学的更多文章:

** [## 如何评价 Python 中机器学习模型性能?

一个实用的方法来计算模型的性能和在 Python 中的实现,涵盖了所有数学…

medium.com](https://medium.com/@pv009/how-to-evaluate-machine-learning-model-performance-in-python-135b4ae27f7e) [## 如何建立一个能让你找到工作的数据科学投资组合?

学会制作一个关于你的强有力的作品集!

medium.com](https://medium.com/datadriveninvestor/how-to-build-a-data-science-portfolio-that-can-get-you-a-job-9f8d113739b3) [## “正态分布”的功效

理解钟形曲线背后的科学!

medium.com](https://medium.com/analytics-vidhya/the-powers-of-normal-distribution-4cbb06e4a955)

更多数据科学和机器学习相关文章关注我上 。想给我买杯咖啡吗?在 LinkedIn 上和我连线。

谢谢!**

k 近邻(kNN)算法:常见问题和 Python 实现

原文:https://towardsdatascience.com/k-nearest-neighbours-knn-algorithm-common-questions-and-python-implementation-14377e45b738?source=collection_archive---------14-----------------------

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

妮娜·斯特雷尔上 Unsplash

测试数据科学家关于 kNN 算法及其 Python 实现的问题

k 近邻被认为是最直观的机器学习算法之一,因为它易于理解和解释。此外,直观地演示一切是如何进行的也很方便。然而,kNN 算法仍然是一种常见的非常有用的算法,用于各种分类问题。如果你是机器学习的新手,请确保测试自己对这个简单而又精彩的算法的理解。关于它是什么以及它是如何工作的,有很多有用的资料来源,因此我想以我个人的观点来看一下你应该知道的 5 个常见或有趣的问题。

k-NN 算法在测试时间而不是训练时间上做更多的计算。

那绝对是真的。kNN 算法的思想是找到一个 k 长的样本列表,该列表接近我们想要分类的样本。因此,训练阶段基本上是存储训练集,而在预测阶段,算法使用存储的数据寻找 k 个邻居。

为什么需要为 k-NN 算法缩放数据?

假设一个数据集有 m 个“示例”和 n 个“特征”。有一个特征维度的值正好在 0 和 1 之间。同时,还有一个从-99999 到 99999 不等的特征维度。考虑到*欧几里德距离的公式,*这将通过给予具有较高幅度的变量较高的权重来影响性能。

阅读更多:KNN 和 K-Means 为什么需要缩放?

k-NN 算法可用于输入分类变量和连续变量的缺失值。

这是真的。在处理缺失值时,k-NN 可以用作许多技术中的一种。通过确定训练集中“最接近”的样本来估算新样本,并对这些要估算的邻近点进行平均。scikit 学习库提供了一种使用这种技术快捷方便的方法。

注:在计算距离时,NaNs 被省略。

示例:

from sklearn.impute import KNNImputer
# define imputer
imputer = KNNImputer() #default k is 5=> *n_neighbors=5*
# fit on the dataset
imputer.fit(X)
# transform the dataset
Xtrans = imputer.transform(X)

因此,缺失值将被其“邻居”的平均值所替代。

欧氏距离总是这样吗?

虽然欧几里德距离是最常用和教授的方法,但它并不总是最佳决策。事实上,仅仅通过查看数据很难得出正确的指标,所以我建议尝试一组数据。但是,也有一些特殊情况。例如,汉明距离用于分类变量的情况。

阅读更多: 每个数据科学家都应该知道的 3 个文本距离

为什么我们不应该对大型数据集使用 KNN 算法?

以下是 KNN 算法中出现的数据流的概述:

  1. 计算到训练集中所有向量的距离并存储它们
  2. 对计算的距离进行排序
  3. 存储 K 个最近的向量
  4. 计算 K 个最近向量显示的最频繁类别

假设你有一个非常大的数据集。因此,存储大量数据不仅是一个糟糕的决定,而且不断计算和排序所有值的计算成本也很高。

Python 实现

我将把实施分为以下几个阶段:

  1. 计算到训练集中所有向量的距离并存储它们
  2. 对计算的距离进行排序
  3. 计算 K 个最近向量显示的最频繁类别,并进行预测

计算训练集中所有向量的距离并存储它们

值得注意的是,有大量不同的选项可供选择作为衡量标准;但是,我想用欧几里德距离作为例子。这是计算向量间距离最常用的度量,因为它简单明了,易于解释。一般公式如下:

欧几里德距离= sqrt(sum I to N(x1 _ I-x2 _ I))

因此,让我们用下面的 Python 代码来总结一下。 注意:不要忘记从“数学”模块导入 sqrt()。

对计算出的距离进行排序

首先,我们需要计算单个测试样本和我们训练集中所有样本之间的所有距离。获得距离后,我们应该对距离列表进行排序,并通过查看它们与测试样本的距离,从我们的训练集中挑选“最近”的 k 个向量。

C 计算 K 个最近向量显示的最频繁类别并进行预测

最后,为了做一个预测,我们应该通过调用我在上面附上的函数来得到我们的 k 个“最近的”邻居。因此,剩下的唯一事情就是计算每个标签出现的次数,并选择最频繁的一个。

让我们通过将所有的函数组合成一个单独的类对象来总结一切。这里有一个更一般化的代码版本,请花些时间浏览一下。

比较

让我们将我们的实现与 scikit learn 提供的实现进行比较。我将使用一个简单的玩具数据集,它包含两个预测值,即年龄薪水。因此,我们希望预测客户是否愿意购买我们的产品。

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

显示前 5 个条目的表格

我将跳过预处理,因为这不是我想关注的;然而,我使用了一种训练测试分割技术,并在之后应用了一个标准缩放器。不管怎样,如果你感兴趣,我会在 Github 上提供源代码。

最后,我将定义两个模型并拟合我们的数据。请参考上面提供的 KNN 实现。我选择 5 作为我们的默认 k 值。注意,对于后一种模型,默认度量是闵可夫斯基,并且 p=2 相当于标准欧几里德度量。

model=KNN(5) *#our model* 
model.fit(X_train,y_train) predictions=model.predict(X_test)*#our model's predictions***from** **sklearn.neighbors** **import** KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski', p = 2)*#The default metric is minkowski, and with p=2 is equivalent to the standard Euclidean metric.*
classifier.fit(X_train, y_train)

y_pred = classifier.predict(X_test)

结果

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

上图显示,两种型号表现出相同的性能。精度结果是 0.93,这是一个相当好的结果。下图是我们测试集结果的可视化。我提供一个单一的数字,因为两个模型是相同的。然而,我个人建议使用已经提供的实现,因为我们的实现简单而低效。此外,不要每次都写完全相同的代码会更方便。

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

我们测试集结果的可视化

摘要

总之,K-最近邻被认为是最直观的机器学习算法之一,因为它易于理解和解释。此外,直观地演示一切是如何进行的也很方便。在本文中,我们回答了以下问题:

  • k-NN 算法在测试时间而不是训练时间上做更多的计算。
  • 为什么需要为 k-NN 算法缩放数据?
  • k-NN 算法可用于输入分类变量和连续变量的缺失值。
  • 欧氏距离总是这样吗?
  • 为什么我们不应该对大型数据集使用 KNN 算法?

此外,我提供了 KNN 算法的 python 实现,以便加深您对内部发生的事情的理解。完整的实现可以在我的 Github 上找到。

有用的资源

[## 为什么 KNN 和 K-Means 需要缩放?

KNN 和 K-Means 是最常用和最广泛使用的机器学习算法之一。KNN 是监督学习…

medium.com](https://medium.com/analytics-vidhya/why-is-scaling-required-in-knn-and-k-means-8129e4d88ed7) [## 每个数据科学家都应该知道的 3 种文本距离

无论您是刚刚开始接触数据科学,还是已经在该领域工作了很长时间,您都需要了解这三个文本…

towardsdatascience.com](/3-text-distances-that-every-data-scientist-should-know-7fcdf850e510) [## 基于 K-最近邻算法的机器学习基础

k-最近邻(KNN)算法是一个简单,易于实现的监督机器学习算法,可以…

towardsdatascience.com](/machine-learning-basics-with-the-k-nearest-neighbors-algorithm-6a6e71d01761)

虹膜数据集上的 k-NN

原文:https://towardsdatascience.com/k-nn-on-iris-dataset-3b827f2591e?source=collection_archive---------12-----------------------

k-最近邻(k-NN)是一种基于实例的监督学习算法,它通过将一个新实例与在训练中已经看到的存储器中已经存储的实例进行比较来对该新实例进行分类。

使用以下步骤计算未知实例的类:

  1. 计算未知实例和所有其他训练实例之间的距离。
  2. k 个最近邻居被识别。
  3. k 个最近邻居的类别标签被用于通过使用像多数投票这样的技术来确定未知实例的类别标签。

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

k-NN 分类示例(图像源)

例如,在上面的图像中,如果 k 值为 3,分类器可以将未知实例分类为 B 类,如果 k 值为 7,则分类为 A 类。

这篇文章关注的是使用 Iris 数据集进行 kNN 的超参数调优。然后,使用最佳超参数对测试集实例进行分类,并计算模型的最终精度。实现是从零开始的,不依赖于现有的 python 数据科学库。

调整的超参数有:

  1. 距离度量:欧几里德、归一化欧几里德和余弦相似性
  2. k 值:1、3、5 和 7

欧几里德距离 欧几里德空间中两点 p 和 q 之间的欧几里德距离计算如下:

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

(图像来源)

归一化欧几里德距离
归一化欧几里德距离是指点经过归一化后,点与点之间的欧几里德距离。

余弦相似度 余弦相似度是两个非零向量之间的相似性度量。两个向量 A 和 B 之间的余弦相似度计算如下:

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

(图片来源)

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

(图片来源)

现在,让我们进入用 Python 实现的分类器。为了便于理解,本节分为不同的步骤。

第一步

加载所需的库。

**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **operator**
**import** **matplotlib.pyplot** **as** **plt**

第二步。

将虹膜数据集加载到 Jupyter 笔记本中。数据集是 csv 格式的,可以很容易地使用熊猫库读入数据帧。数据集有四个属性萼片长度、萼片宽度、花瓣长度和花瓣宽度,以及每个实例的类标签。

data = pd.read_csv('iris.data', header=**None**, names=['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class'])

数据帧可以显示如下:

print(data)

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

第三步。

将数据集分为开发集和测试集。它可以通过随机化索引然后根据索引分割数据帧来划分。

indices = np.random.permutation(data.shape[0])
div = int(0.75 * len(indices))
development_id, test_id = indices[:div], indices[div:]

development_set, test_set = data.loc[development_id,:], data.loc[test_id,:]
print("Development Set:**\n**", development_set, "**\n\n**Test Set:**\n**", test_set)

计算开发集和测试集的平均值和标准偏差,以计算归一化的欧几里德距离。

mean_development_set = development_set.mean()
mean_test_set = test_set.mean()
std_development_set = development_set.std()
std_test_set = test_set.std()

从开发和测试集中检索“class”列,并将其存储在单独的列表中。

test_class = list(test_set.iloc[:,-1])
dev_class = list(development_set.iloc[:,-1])

第四步。

定义计算距离度量值的函数:欧几里德、归一化欧几里德和余弦相似性

**def** euclideanDistance(data_1, data_2, data_len):
    dist = 0
    **for** i **in** range(data_len):
        dist = dist + np.square(data_1[i] - data_2[i])
    **return** np.sqrt(dist)

**def** normalizedEuclideanDistance(data_1, data_2, data_len, data_mean, data_std):
    n_dist = 0
    **for** i **in** range(data_len):
        n_dist = n_dist + (np.square(((data_1[i] - data_mean[i])/data_std[i]) - ((data_2[i] - data_mean[i])/data_std[i])))
    **return** np.sqrt(n_dist)

**def** cosineSimilarity(data_1, data_2):
    dot = np.dot(data_1, data_2[:-1])
    norm_data_1 = np.linalg.norm(data_1)
    norm_data_2 = np.linalg.norm(data_2[:-1])
    cos = dot / (norm_data_1 * norm_data_2)
    **return** (1-cos)

定义返回 k 个最近邻的函数

**def** knn(dataset, testInstance, k, dist_method, dataset_mean, dataset_std): 
    distances = {}
    length = testInstance.shape[1]
    **if** dist_method == 'euclidean':
        **for** x **in** range(len(dataset)):
            dist_up = euclideanDistance(testInstance, dataset.iloc[x], length)
            distances[x] = dist_up[0]
    **elif** dist_method == 'normalized_euclidean':
        **for** x **in** range(len(dataset)):
            dist_up = normalizedEuclideanDistance(testInstance, dataset.iloc[x], length, dataset_mean, dataset_std)
            distances[x] = dist_up[0]
    **elif** dist_method == 'cosine':
        **for** x **in** range(len(dataset)):
            dist_up = cosineSimilarity(testInstance, dataset.iloc[x])
            distances[x] = dist_up[0]
    *# Sort values based on distance*
    sort_distances = sorted(distances.items(), key=operator.itemgetter(1))
    neighbors = []
    *# Extracting nearest k neighbors*
    **for** x **in** range(k):
        neighbors.append(sort_distances[x][0])
    *# Initializing counts for 'class' labels counts as 0*
    counts = {"Iris-setosa" : 0, "Iris-versicolor" : 0, "Iris-virginica" : 0}
    *# Computing the most frequent class*
    **for** x **in** range(len(neighbors)):
        response = dataset.iloc[neighbors[x]][-1] 
        **if** response **in** counts:
            counts[response] += 1
        **else**:
            counts[response] = 1
    *# Sorting the class in reverse order to get the most frequest class*
    sort_counts = sorted(counts.items(), key=operator.itemgetter(1), reverse=**True**)
    **return**(sort_counts[0][0])

第五步。

使用开发数据集,迭代所有开发数据实例,并计算每个 k 值和每个距离度量的类。

*# Creating a list of list of all columns except 'class' by iterating through the development set*
row_list = []
**for** index, rows **in** development_set.iterrows():
    my_list =[rows.sepal_length, rows.sepal_width, rows.petal_length, rows.petal_width]       
    row_list.append([my_list])
*# k values for the number of neighbors that need to be considered*
k_n = [1, 3, 5, 7]
*# Distance metrics*
distance_methods = ['euclidean', 'normalized_euclidean', 'cosine']
*# Performing kNN on the development set by iterating all of the development set data points and for each k and each distance metric*
obs_k = {}
**for** dist_method **in** distance_methods:
    development_set_obs_k = {}
    **for** k **in** k_n:
        development_set_obs = []
        **for** i **in** range(len(row_list)):
            development_set_obs.append(knn(development_set, pd.DataFrame(row_list[i]), k, dist_method, mean_development_set, std_development_set))
        development_set_obs_k[k] = development_set_obs
    *# Nested Dictionary containing the observed class for each k and each distance metric (obs_k of the form obs_k[dist_method][k])*
    obs_k[dist_method] = development_set_obs_k
*#print(obs_k)*

计算开发集的准确性

*# Calculating the accuracy of the development set by comparing it with the development set 'class' list created earlier*
accuracy = {}
**for** key **in** obs_k.keys():
    accuracy[key] = {}
    **for** k_value **in** obs_k[key].keys():
        *#print('k = ', key)*
        count = 0
        **for** i,j **in** zip(dev_class, obs_k[key][k_value]):
            **if** i == j:
                count = count + 1
            **else**:
                **pass**
        accuracy[key][k_value] = count/(len(dev_class))

*# Storing the accuracy for each k and each distance metric into a dataframe*
df_res = pd.DataFrame({'k': k_n})
**for** key **in** accuracy.keys():
    value = list(accuracy[key].values())
    df_res[key] = value
print(df_res)

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

绘制条形图以比较超参数的性能。

*# Plotting a Bar Chart for accuracy*
draw = df_res.plot(x='k', y=['euclidean', 'normalized_euclidean', 'cosine'], kind="bar", colormap='YlGnBu')
draw.set(ylabel='Accuracy')

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

注意 :如果 k=1 的精度值为 100%,则忽略 k=1,因为这通常意味着过拟合。将其替换为 numpy.nan. 的值

df_res.loc[df_res['k'] == 1.0, ['euclidean', 'normalized_euclidean', 'cosine']] = np.nan

第六步。

找到最佳超参数。

*# In case the accuracy is the same for different k and different distance metric selecting the first of all the same*
column_val = [c **for** c **in** df_res.columns **if** **not** c.startswith('k')]
col_max = df_res[column_val].max().idxmax(1)
best_dist_method = col_max
row_max = df_res[col_max].argmax()
best_k = int(df_res.iloc[row_max]['k'])
**if** df_res.isnull().values.any():
    print('**\n\n\n**Best k value is**\033**[1m', best_k, '**\033**[0mand best distance metric is**\033**[1m', best_dist_method, '**\033**[0m. Ignoring k=1 if the value of accuracy for k=1 is 100%, since this mostly implies overfitting')
**else**:
    print('**\n\n\n**Best k value is**\033**[1m', best_k, '**\033**[0mand best distance metric is**\033**[1m', best_dist_method, '**\033**[0m.')

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

第七步。

使用测试集和最佳超参数来计算最终精度。

*# Creating a list of list of all columns except 'class' by iterating through the development set*
row_list_test = []
**for** index, rows **in** test_set.iterrows(): 
    my_list =[rows.sepal_length, rows.sepal_width, rows.petal_length, rows.petal_width]       
    row_list_test.append([my_list])
test_set_obs = []
**for** i **in** range(len(row_list_test)):
    test_set_obs.append(knn(test_set, pd.DataFrame(row_list_test[i]), best_k, best_dist_method, mean_test_set, std_test_set))
*#print(test_set_obs)*

count = 0
**for** i,j **in** zip(test_class, test_set_obs):
    **if** i == j:
        count = count + 1
    **else**:
        **pass**
accuracy_test = count/(len(test_class))
print('Final Accuracy of the Test dataset is ', accuracy_test)

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

使用余弦相似性作为距离度量并且 k 值为 5,实现了大约 97%的最终精度。这个模型给出了非常好的结果。

完整的代码可以在 GitHub 中找到。

https://stack overflow . com/questions/18424228/Cosine-Similarity-between-2-number-lists

https://machine learning mastery . com/tutorial-to-implement-k-nearest-neighbors-in-python-from-scratch/

数据科学/大数据实验室——第 4 部分,共 4 部分:3 节点集群中的 Kafka 和 Zookeeper over Ubuntu

原文:https://towardsdatascience.com/kafka-and-zookeeper-over-ubuntu-in-a-3-node-cluster-a-data-science-big-data-laboratory-part-4-of-4-47631730d240?source=collection_archive---------46-----------------------

实验室数据

使用 Hadoop、Spark、Hive、Kafka、Zookeeper 和 PostgreSQL 在 Raspberry Pi 4 或 VMs 集群中组建数据科学/大数据实验室

这段文字可以用来支持在任何 Ubuntu 20.04 服务器集群中的安装,这就是设计良好的分层软件的妙处。此外,如果您有更多的节点,您可以随意分发软件。本文假设您知道 Linux 命令行,包括 ssh、vim 和 nano。

我不建议从少于三个树莓开始,因为你需要设置通信,并且 Zookeeper 和 Kafka 都需要奇数个节点。如果您尝试使用单个节点,可以使用本指南。尽管如此,性能可能会令人失望——对于单节点,我建议虚拟机具有合理数量的 RAM 和处理器。

由于篇幅原因,我不得不将教程分成四部分:

*所有配置文件均可在【1】:*获得

[## ptaranti/RaspberryPiCluster

Hadoop+Spark+Hive+Kafka+Postgresql raspberry 集群(ubuntu 20.04)的配置文件

github.com](https://github.com/ptaranti/RaspberryPiCluster)

免责声明 : 此文免费提供给大家使用,风险自担。我小心地引用了我所有的资料来源,但是如果你觉得遗漏了什么,请给我发个短信。由于不同的软件版本可能会因其依赖性而表现出不同的行为,我建议使用我在第一次尝试中使用的相同版本。

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

6.卡夫卡

Kafka(https://kafka.apache.org/)是一个健壮的消息代理,广泛用于实例化管道。它的保留功能可以处理激增的信息或让消费者离线进行维护的需求。

此外,与几乎所有大数据解决方案一样,Kafka 可以快速从单个节点升级到具有复制功能的完整集群。

学习卡夫卡的主要文献是《卡夫卡:权威指南》一书2。该电子书可在以下网址免费获得

[## 阿帕奇卡夫卡:权威指南

什么是卡夫卡,它是如何工作的?在这本全面的电子书中,你会得到阿帕奇卡夫卡的全面介绍…

www.confluent.io](https://www.confluent.io/resources/kafka-the-definitive-guide/)

非常感谢合流!

卡夫卡一天可以轻松处理从千兆字节到甚至千兆字节的数据。这远远超出了我的实验室集群能力。然而,我决定安装 Kafka 最初作为一个单一的节点,然后分发它以允许使用数据管道,例如从 Tweeter 收集实时信息。

6.1 动物园管理员

第一步是安装 zookeeper 服务器,因为 Kafka 依赖它来分发元数据。我在以下站点安装了最新的稳定版本:

https://zookeeper.apache.org/releases.html

https://downloads . Apache . org/zookeeper/zookeeper-3 . 6 . 1/Apache-zookeeper-3 . 6 . 1 . tar . gz

pi@pi3:~/tmp$ wget [https://downloads.apache.org/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz](https://downloads.apache.org/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz)
pi@pi3:~/tmp$ tar -xzvf apache-zookeeper-3.6.1-bin.tar.gz
pi@pi3:~/tmp$ sudo mv apache-zookeeper-3.6.1-bin /opt/zookeeper
pi@pi3:~/tmp$ cd /opt/
pi@pi3:/opt$ ls
**hadoop  hadoop_tmp  hive  zookeeper**
pi@pi3:/opt$ sudo chown -R pi:pi zookeeper
[sudo] password for pi:
pi@pi3:/opt$
pi@pi3: /opt$ sudo mkdir /opt/zookeeper_data
pi@pi3: /opt$ sudo chown -R pi:pi zookeeper_data

创建文件:

/opt/zookeeper/conf/zoo . conf

现在,您可以在单个节点中启动 zookeeper:

pi@pi3:/opt$ /opt/zookeeper/bin/zkServer.sh startZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

检查服务:

pi@pi3:/opt$ sudo netstat -plnt | grep 2181
tcp6  0  0 :::2181  :::*  LISTEN  2511/java

现在我们在 pi3 上本地运行 zookeeper。接下来,我们将安装卡夫卡。

6.2 卡夫卡

卡夫卡安装成单个音符就没那么麻烦了。我按照书上的说明做了,但是把安装文件夹改为/opt,我的用户是 pi。

我下载了最新的稳定版本

卡夫卡 _ 2.13–2 . 5 . 0 . tgz:

[## Apache 下载镜像

Apache 软件基金会主页

www.apache.org](https://www.apache.org/dyn/closer.cgi?path=/kafka/2.5.0/kafka_2.13-2.5.0.tgz)

和往常一样,我把它保存在 /home/pi/tmp

以下命令用于提取文件、将其发送到/opt 并调整文件夹和访问权限:

pi@pi3:~/tmp$ tar -xzvf kafka_2.13-2.5.0.tgz
pi@pi3:~/tmp$ sudo mv kafka_2.13-2.5.0 /opt/kafka
pi@pi3:~/tmp$ cd /opt/
pi@pi3:/opt$ ls
hadoop  hadoop_tmp  hive  kafka  zookeeper  zookeeper_data
pi@pi3:/opt$ sudo chown -R pi:pi kafkapi@pi3:/opt$ sudo mkdir /opt/kafka-data
pi@pi3:/opt$ sudo chown -R pi:pi  /opt/kafka_data

编辑文件

/opt/Kafka/config/server . propertys,

c 悬挂以下参数:

log.dirs=/opt/kafka_data

开始卡夫卡:

pi@pi3:/opt$ /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.properties

注意:如果你没有指明另一种方式,卡夫卡和动物园管理员需要一个开放的终端。启动这些服务时。最初为每个服务使用一个终端/远程会话。之后教程将展示如何以透明的方式做到这一点。

检查端口 9092:

pi@pi3:/opt$ sudo netstat -plnt | grep 9092
tcp6  0  0 :::9092  :::*   LISTEN  3014/java

以下命令将允许您确保 Kafka 正常运行:

第一次启动动物园管理员:

pi@pi3:~$ /opt/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

现在,您可以启动 Kafka,用生产者和消费者创建一个 Kafka 主题并测试它:

pi@pi3:~$ /opt/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/config/server.propertiespi@pi3:~$ /opt/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
Created topic test.pi@pi3:~$ /opt/kafka/bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test
Topic: test     PartitionCount: 1       ReplicationFactor: 1    Configs:
        Topic: test     Partition: 0    Leader: 0       Replicas: 0     Isr: 0pi@pi3:~$ /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
>message test 1
>message test 2pi@pi3:~$ /opt/kafka/bin/kafka-console-consumer.sh  --bootstrap-server localhost:9092 --topic test --from-beginning
message test 1
message test 2
^C Processed a total of 2 messages

6.3 将 Zookeeper 和 Kafka 改为集群

注意:卡夫卡和动物园管理员都建议你有奇数个节点。我用了 3 个,没问题。

pi1

pi@pi1:~$  sudo mkdir /opt/zookeeper_data
pi@pi1:~$ sudo mkdir /opt/zookeeper
pi@pi1:~$ sudo mkdir /opt/kafka
pi@pi1:~$ sudo mkdir /opt/kafka_datapi@pi1:~$ sudo chown -R pi:pi /opt/zookeeper_data
pi@pi1:~$ sudo chown -R pi:pi /opt/zookeeper
pi@pi1:~$ sudo chown -R pi:pi /opt/kafka
pi@pi1:~$ sudo chown -R pi:pi /opt/kafka_data

pi2

pi@pi2:~$  sudo mkdir /opt/zookeeper_data
pi@pi2:~$ sudo mkdir /opt/zookeeper
pi@pi2:~$ sudo mkdir /opt/kafka
pi@pi2:~$ sudo mkdir /opt/kafka_datapi@pi2:~$ sudo chown -R pi:pi /opt/zookeeper_data
pi@pi2:~$ sudo chown -R pi:pi /opt/zookeeper
pi@pi2:~$ sudo chown -R pi:pi /opt/kafka
pi@pi2:~$ sudo chown -R pi:pi /opt/kafka_data

pi3

pi@pi3:/opt$ rsync -vaz  /opt/zookeeper/   pi2:/opt/zookeeper/
pi@pi3:/opt$ rsync -vaz  /opt/kafka/   pi2:/opt/kafka/
pi@pi3:/opt$ rsync -vaz  /opt/zookeeper/   pi1:/opt/zookeeper/
pi@pi3:/opt$ rsync -vaz  /opt/kafka/   pi1:/opt/kafka/

编辑删除以前的注释(pi1、pi2、pi3)

/opt/zookeeper/conf/zoo . conf

创建文件:

/opt/zookeeper_data/myid

该文件应该只有 zookeeper 节点的 id(参见 GitHub)

pi1 ->1,

pi2 ->2,

pi3 ->3,

对于卡夫卡,我们需要编辑(在所有节点中):

/opt/Kafka/config/server . properties

更改参数:

**broker.id=1   # 2, 3 acoording to the node**

(1 用于 pi1,2 用于 pi2,3 用于 pi3

并且:

**zookeeper.connect= pi1:2181, pi2:2181, pi3:2181**

现在卡夫卡是动物园管理员将作为一个集群运行。您需要在所有节点中启动它。

6.3.1 监控您的 Kafka 集群

有一些监控 Kafka 集群的工具。我认为有一个完整环境的外观和感觉是很好的。

正文[3]:

[## Apache Kafka 集群的 UI 监控工具概述

阿帕奇卡夫卡最好的监控工具有哪些?

medium.com](https://medium.com/@giorgosmyrianthous/overview-of-ui-monitoring-tools-for-apache-kafka-clusters-9ca516c165bd)

概述一些可用的工具。卡夫卡本身没有这样的工具。

o 选择安装 Kafka 工具。个人使用是免费的,这是我的情况。Kafka 工具可以安装在 windows、mac 和 Linux 上。我选择将它安装在我的 windows 笔记本上,以减少我的覆盆子的工作量。

[## 卡夫卡工具

Kafka Tool 是一个 GUI 应用程序,用于管理和使用 Apache Kafka 集群。它提供了直观的用户界面,允许…

www.kafkatool.com](https://www.kafkatool.com/)

下面我展示了我与分布式节点的实际接口:

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

最后,下面的帖子提供了关于 Kafka 工具的额外信息[4]:

[## Apache Kafka 的 GUI

概观

medium.com](https://medium.com/enfuse-io/gui-for-apache-kafka-e52698b00c42)

7.启动集群

我为每个节点编写了一个脚本来启动所有服务——因为我有时会忘记启动特定的服务。您将在 pi 用户的主文件夹中找到名为 cluster-start.sh 的脚本。该脚本使用 ssh 连接来启动其他节点中的服务,我将它复制到我的所有节点中。

/归位/pi/集群启动。嘘

您可以使用 Hadoop、Yarn、Hive 和 Kafka 工具的 web UI 来检查集群状态。

我的最终架构如下图所示:

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

服务的分布如下表所示:

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

我还在笔记本上用了一个超过 VirtualBox 的 Ubuntu 虚拟机,有 RStudio,R,Anaconda,TensorFlow。

结论

我祝贺你完成了所有的安装。我知道解脱和快乐的感觉!😄

现在你有一个完整的环境来试验和训练!

我要感谢我引用的所有作者。

我授权任何人在引用出处之前复制本教程的部分内容。如果一个实质性的部分是必要的,请只链接它。

欢迎任何评论和问题!

1 P. G .塔兰蒂。https://github.com/ptaranti/RaspberryPiCluster

2 N. Narkhede 等人卡夫卡:权威指南:大规模实时数据和流处理。奥莱利媒体公司(2017 年)

[3] G. Myrianthous。Apache Kafka 集群 UI 监控工具概述 (2019)

[4]欧·格里戈里安。阿帕奇卡夫卡的图形用户界面 (2019)

Apache Kafka: Docker 容器和 Python 中的例子

原文:https://towardsdatascience.com/kafka-docker-python-408baf0e1088?source=collection_archive---------2-----------------------

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

罗斯·索科洛夫斯基在 Unsplash 上的照片

如何使用 Docker 安装 Kafka 并在 Python 中产生/消费消息

A pache Kafka 是一个流处理软件平台,最初由 LinkedIn 开发,2011 年初开源,目前由 Apache Software Foundation 开发。是用 Scala 和 Java 写的。

汇流流简介

卡夫卡的关键概念

Kafka 是一个分布式系统,由服务器客户端组成。

  • 一些服务器被称为代理,它们构成了存储层。其他服务器运行 Kafka Connect 以事件流的形式导入和导出数据,从而将 Kafka 与您现有的系统持续集成。
  • 另一方面,客户端允许您创建读取、写入和处理事件流的应用程序。客户可以是生产者或消费者。生产者向 Kafka 写入(产生)事件,而消费者从 Kafka 读取并处理(消费)事件。

服务器和客户端通过高性能的 TCP 网络协议进行通信,并且完全解耦,互不可知。

但是什么是事件?在 Kafka 中,事件是一个有键、值和时间戳的对象。或者,它可以有其他元数据头。你可以把一个事件看作一个记录或一条信息。

一个或多个事件被组织在主题中:生产者可以编写不同主题的消息/事件,消费者可以选择读取和处理一个或多个主题的事件。在 Kafka 中,您可以配置一个主题的事件应该保留多长时间,因此,它们可以在需要时被读取,并且在消费后不会被删除。

消费者以自己的速度消费一个主题的事件流,并可以提交其位置(称为偏移)。当我们提交偏移量时,我们设置了一个指向消费者使用的最后一条记录的指针。

在服务器端,主题被划分和复制。

  • 出于可扩展性原因,主题被分区。它的活动分散在不同的卡夫卡经纪人那里。这允许客户同时从/向许多代理读取/写入。
  • 为了可用性和容错性,每个主题也可以被复制。这意味着不同数据中心的多个代理可能拥有相同数据的副本。

关于卡夫卡如何工作的详细解释,请查看其官网

介绍够了!让我们看看如何安装 Kafka 来测试我们的示例 Python 脚本!

使用 Docker 安装 Kafka

作为数据科学家,我们通常会发现 Kafka 已经安装、配置好了,随时可以使用。为了完整起见,在本教程中,让我们看看如何安装一个 Kafka 实例进行测试。为此,我们将使用 Docker ComposeGit 。如果没有安装,请在您的系统上安装它们。

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

图片作者。卡夫卡 docker 知识库。

在您的工作目录中,打开一个终端并克隆 Apache Kafka 的 docker 映像的 GitHub 存储库。然后更改存储库文件夹中的当前目录。

git clone https://github.com/wurstmeister/kafka-docker.git 
cd kafka-docker/

kafka-docker 中,创建一个名为docker-compose-expose . yml的文本文件,包含以下内容(您可以使用您最喜欢的文本编辑器):

version: '2'
services:
  zookeeper:
    image: wurstmeister/zookeeper:3.4.6
    ports:
     - "2181:2181"
  kafka:
    image: wurstmeister/kafka
    ports:
     - "9092:9092"
    expose:
     - "9093"
    environment:
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_CREATE_TOPICS: "topic_test:1:1"
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock

现在,您已经准备好使用以下命令启动 Kafka 集群:

docker-compose -f docker-compose-expose.yml up

如果一切正常,你应该会看到动物园管理员和卡夫卡的日志。

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

图片作者。动物园管理员和卡夫卡的日志。

万一你想停下来,就跑吧

docker-compose stop

在 kafka-docker 文件夹中的一个单独的终端会话中。

关于 Kafka docker 的连通性的完整指南,请查看这是 wiki

Python 中的生产者和消费者

为了用 Python 为 Kafka 创建第一个生产者/消费者,我们需要安装 Python 客户机。

pip install kafka-python

然后,用下面的代码创建一个名为 producer.py 的 Python 文件。

from time import sleep
from json import dumps
from kafka import KafkaProducerproducer = KafkaProducer(
    bootstrap_servers=['localhost:9092'],
    value_serializer=lambda x: dumps(x).encode('utf-8')
)for j in range(9999):
    print("Iteration", j)
    data = {'counter': j}
    producer.send('topic_test', value=data)
    sleep(0.5)

在上面的代码块中:

  • 我们已经创建了一个 KafkaProducer 对象,它连接到我们的本地 Kafka 实例;
  • 我们已经定义了一种方法来序列化我们想要发送的数据,将它转换成 json 字符串,然后编码成 UTF-8;
  • 我们每 0.5 秒发送一个事件,主题名为“topic _ test**”**,迭代的计数器作为数据。除了 couter,你可以发送任何东西。

现在我们准备启动生成器:

python producer.py

该脚本应该每半秒钟打印一次迭代次数。

[...]
Iteration 2219
Iteration 2220
Iteration 2221
Iteration 2222
[...]

让生产者终端会话保持运行,并在一个单独的名为 consumer.py 的 Python 文件中用下面几行代码定义我们的消费者。

from kafka import KafkaConsumer
from json import loads
from time import sleepconsumer = KafkaConsumer(
    'topic_test',
    bootstrap_servers=['localhost:9092'],
    auto_offset_reset='earliest',
    enable_auto_commit=True,
    group_id='my-group-id',
    value_deserializer=lambda x: loads(x.decode('utf-8'))
)for event in consumer:
    event_data = event.value
    # Do whatever you want
    print(event_data)
    sleep(2)

在上面的脚本中,我们定义了一个 KafkaConsumer,它联系服务器“localhost:9092”并订阅主题“topic_test”。由于在生产者脚本中消息是 jsonfied 和编码的,这里我们通过使用 value_deserializer 中的 lambda 函数对其进行解码。此外,

  • auto_offset_reset 是设置 OffsetOutOfRange 错误时重置偏移量的策略的参数;如果我们设置了“最早”,那么它将移动到最早的可用消息,如果设置了“最新”,那么它将移动到最近的消息;
  • enable_auto_commit 是一个布尔型参数,表示是否会在后台定期提交偏移量;
  • group_id加入的消费群的名称。

在循环中,我们每 2 秒钟打印一次事件的内容。除了打印,我们可以执行任何任务,比如将它写入数据库或执行一些实时分析。

此时,如果我们跑

python consumer.py

我们应该收到类似于以下内容的输出:

{'counter': 0}
{'counter': 1}
{'counter': 2}
{'counter': 3}
{'counter': 4}
{'counter': 5}
{'counter': 6}
[...]

Python 生产者/消费者类参数的完整文档可以在这里找到。

现在你已经准备好用 Python 写卡夫卡了!

参考

联系人:LinkedIn|Twitter

卡夫卡,为了你的数据管道?为什么不呢?

原文:https://towardsdatascience.com/kafka-for-your-data-pipeline-why-not-5a14b50efe7f?source=collection_archive---------13-----------------------

使用 Docker、Kafka 和 Kafka Connect 创建流管道

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

我们在这个项目中所建造的

Kafka 于 2011 年由 LinkedIn 开发并开源,此后它迅速从消息队列发展成为一个成熟的流媒体平台,拥有丰富的生态系统。除了 LinkedIn 之外,许多科技公司,如 Airbnb、Spotify 或 Twitter,都将 Kafka 用于其关键任务应用程序。

Kafka 可以用于很多事情,从消息传递、web 活动跟踪到日志聚合或流处理。从我作为数据专业人士的角度来看,Kafka 可以用作数据流管道的核心组件,以支持实时用例,如欺诈检测、预测性维护或实时分析。

有整本书都是关于卡夫卡的,开始阅读可能会让人望而生畏。然而,在这个项目中,我将向您展示使用 Docker、Kafka 和 Kafka Connect 创建流数据管道是多么容易。

商业问题

让我们定义一些要努力解决的业务问题。

假设你是一名数据工程师,在一家不断有用户注册的电子商务网站工作。营销团队希望向每一位注册的客户发送一封个性化的电子邮件。新提出的功能有一些问题:

  • 注册服务与电子邮件服务相结合。换句话说,每次市场需求发生变化,你都必须对注册服务做出改变,如果你不小心的话,这可能会导致整个事情的发生。
  • 市场营销要求电子邮件应该在用户注册时立即发送。用工程术语来说,他们指的是从客户注册开始的 5 秒钟内。
  • 个性化模型与您的注册服务托管在不同的网络上。

与客户数据相关的另一个业务问题是,您的 CEO 希望每个员工都知道当前的客户数量以及他们从哪里注册。她让管理团队在办公室中央安装几个大显示器,而您的团队必须创建一个将在这些显示器上显示的仪表板。

  • 您当前的数据仓库每天只获取用户数据,因此您不能使用现有的批处理管道。
  • 仪表板服务也在不同的网络上,因此您不能直接查询生产数据库。

在研究了几个选项后,您意识到使用 Kafka 和运行在 Docker 上的 Kafka Connect 似乎是解决您的问题的最佳选项。以下是你研究后的发现。

卡夫卡是什么?

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

图像信用

Kafka 是一个用 Scala 和 Java 编写的开源流处理平台。根据 Kafka 网站的说法,流媒体平台有三个关键能力:

  • 发布和订阅记录流,类似于消息队列或企业消息传递系统。
  • 以容错的持久方式存储记录流。
  • 在记录流出现时处理它们。

Kafka 通常用于构建对数据流做出反应的实时应用程序,或者可靠地在系统或应用程序之间获取数据的实时数据管道。在我们的用例中,我们需要将生产系统(Postgres DB)中的数据传输到 se 团队正在开发的一个单独的电子邮件服务(MySQL DB ),以及数据团队的数据湖 S3。

关于卡夫卡,这里有一些你应该熟悉的概念:

  • Broker: Kafa broker 接收来自生产者的消息,并通过惟一偏移量存储它们。代理还允许消费者通过主题、分区和偏移量获取消息。
  • 消息:是卡夫卡中的一个数据单位。您可以将每条消息视为数据库中的一条记录。
  • 主题和分区:每个主题都是一个命名的消息流。一个主题由一个或多个分区组成。分区允许 Kafka 通过跨代理分发数据来进行水平扩展。

卡夫卡连线?

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

形象信用

Kafka Connect ,Kafka 的一个开源组件,是一个将 Kafa 与数据库、键值存储、搜索索引、文件系统等外部系统连接起来的框架。以下是一些与 Kafka Connect 相关的概念:

  • 连接器:连接器是一个逻辑作业,负责管理 Kafka 和其他系统之间的数据复制
  • 源连接器:将数据从系统复制到 Kafka 的连接器
  • 接收器连接器:将数据从一个或多个 Kafka 主题复制到系统的连接器
  • 任务:每个连接器实例协调一组任务,将数据从一个系统复制到 Kafka,反之亦然

Docker 和 docker-compose?

Docker 是一种容器技术,它允许我们将一个应用程序打包成它需要的所有部分,比如库和依赖项。您可以使用 Docker 在本地计算机上快速有效地部署这些服务,而不必在本地计算机上安装 Kafka、Kafka Connect 和所有数据库。

Docker-compose 是一个高级命令,它允许您使用 YAML 配置文件,通过一个命令来部署 Docker 容器。

建筑

抛开所有术语,让我们来看看这个解决方案的架构。

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

我们解决方案的架构

对于我们的示例,我们将使用 Kafka connect 从本地生产数据库中捕获 Users 表中的更改,并写入 Kafka 主题。两个连接器将订阅上面的主题,并将任何更改写入我们的电子邮件服务的 MySQL 数据库以及我们的数据湖 S3。

有趣的部分

现在,这是有趣的部分!让我们开始吧。

克隆我的回购

首先,通过在您的终端上键入以下命令来克隆我的回购:

[g](https://github.com/tuanchris/kafka-pipeline)it clone [https://github.com/tuanchris/kafka-pipeline](https://github.com/tuanchris/kafka-pipeline)
cd kafka-pipeline

[## 图安克里斯/卡夫卡管道

Kafka 最近越来越受欢迎,因为企业依赖它来驱动任务关键型应用程序和数据…

github.com](https://github.com/tuanchris/kafka-pipeline)

安装 Docker 和 docker-compose

我们将在这个项目中使用 Docker 和 docker-compose ,你可以快速查找如何为你的操作系统安装它们。

创造环境

假设您已经安装了conda,那么您可以创建一个新的 env 并通过运行以下命令来安装所需的包:

conda create -n kafka-pipeline python=3.7 -y
conda activate kafka-pipeline
pip install -r requirements.txt

我们将需要 PostgreSQL 来连接到我们的源数据库(Postgres)并生成流数据。在 Mac OS 上,您可以通过运行以下命令使用 Homebrew 安装 PostgreSQL:

brew install postgresql
pip install psycopg2

你可以谷歌一下如何为其他平台安装 PostgreSQL

启动生产数据库(Postgres)

我们使用 docker-compose 以最小的努力启动服务。您可以使用以下命令启动 Postgres 生产数据库:

docker-compose -f docker-compose-pg.yml up -d

您的 Postgres 数据库应该运行在端口 5432 上,您可以通过在终端上键入docker ps来检查容器的状态。

生成流数据

我写了一个简短的脚本来使用 Faker 库生成用户数据。该脚本将在我们的 Postgres 数据库中每秒生成一条记录,模拟一个生产数据库。您可以使用以下命令在单独的终端标签中运行脚本:

python generate_data.py

如果一切设置正确,您将看到如下输出:

Inserting data {'job': 'Physiotherapist', 'company': 'Miller LLC', 'ssn': '097-38-8791', 'residence': '421 Dustin Ramp Apt. 793\nPort Luis, AR 69680', 'username': 'terri24', 'name': 'Sarah Moran', 'sex': 'F', 'address': '906 Andrea Springs\nWest Tylerberg, ID 29968', 'mail': 'nsmith@hotmail.com', 'birthdate': datetime.date(1917, 6, 3), 'timestamp': datetime.datetime(2020, 6, 29, 11, 20, 20, 355755)}

据此,我们模拟了每秒钟都有新客户数据的生产数据库。很整洁,是吧?

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

您可以使用 SQL 客户机(如 DataGrip 或 DBeaver)连接到 Postgres 数据库,以双重检查数据是否正在写入 Users 表。连接字符串应该是jdbc:postgresql://TEST:password@postgres:5432/TEST

开始我们的卡夫卡经纪人

很好,现在我们已经有了一个运行着数据流的生产数据库,让我们开始模拟的主要组件。我们将运行以下服务:

  • Kafka broker: Kafa broker 接收来自生产者的消息,并按唯一偏移量存储它们。代理还允许消费者通过主题、分区和偏移量获取消息。
  • Zookeeper: Zookeeper 跟踪 Kafka 集群节点以及 Kafka 主题和分区的状态
  • Schema registry: Schema registry 是一个获取和服务元数据(关于数据的数据)的层,比如数据类型、精度、小数位数…并提供不同服务之间的兼容性设置。
  • Kafka Connect: Kafka Connect 是一个框架,用于连接 Kafka 与外部系统,如数据库、键值存储、搜索索引和文件系统。
  • Kafdrop: Kafdrop 是一个开源的 web UI,用于查看 Kafka 主题和浏览消费群体。这将使检查和调试我们的消息更加容易。

我们可以通过运行以下命令来启动所有这些服务:

docker-compose -f docker-compose-kafka.yml up -d

等待几分钟,让 docker 下载图像并启动服务,然后您可以继续下一步。您可以使用以下命令查看上一个命令完成后的日志输出:

docker-compose -f docker-compose-kafka.yml logs -f

配置源连接器

接下来,我们将使用 Kafka connect rest API 配置我们的生产数据库(Postgres)的源连接器。将以下内容粘贴到您的终端:

curl -i -X PUT http://localhost:8083/connectors/SOURCE_POSTGRES/config \
     -H "Content-Type: application/json" \
     -d '{
            "connector.class":"io.confluent.connect.jdbc.JdbcSourceConnector",
            "connection.url":"jdbc:postgresql://postgres:5432/TEST",
            "connection.user":"TEST",
            "connection.password":"password",
            "poll.interval.ms":"1000",
            "mode":"incrementing",
            "incrementing.column.name":"index",
            "topic.prefix":"P_",
            "table.whitelist":"USERS",
            "validate.non.null":"false"
        }'

当您看到HTTP/1.1 201 Created时,连接器已成功创建。这个命令的作用是向 Kafka Connect 实例发送一个包含我们的配置的 JSON 消息。我将在这里解释一些配置,但是您可以在这里参考配置的完整列表

  • connector.class:我们使用 JDBC 源连接器连接到我们的生产数据库并提取数据。
  • connection.url:我们源数据库的连接字符串。由于我们用的是 Docker 的内网,所以数据库地址是 Postgres。如果要连接到外部数据库,请用数据库的 IP 替换 Postgres。
  • connection.user & connection.password:我们数据库的凭证。
  • poll.interval.ms:轮询新数据的频率。我们每秒都在轮询。
  • mode:轮询时更新每个表的模式。我们使用增量键(索引),但是我们也可以使用时间戳或批量更新来更新。
  • topic.prefix:向卡夫卡写数据的题目前缀。
  • table.whitelist:要在我们的数据库中查找的表名列表。您还可以设置一个query参数来使用自定义查询。

随着 Kafdrop 实例的运行,您可以打开浏览器并转到localhost:9000来查看我们的P_USERS主题。你可以进入主题,看看我们主题的一些示例消息。

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

就这样,你就有了流向卡夫卡的用户数据流。

创建 MySQL 接收器连接器

先从 Mysql 说起吧。通过运行以下命令启动 Mysql 数据库:

docker-compose -f docker-compose-mysql.yml up -d

这是我们的配置:

curl -i -X PUT http://localhost:8083/connectors/SINK_MYSQL/config \
     -H "Content-Type: application/json" \
     -d '{
       		"connector.class":"io.confluent.connect.jdbc.JdbcSinkConnector",
       		"tasks.max":1,
       		"topics":"P_USERS",
           "insert.mode":"insert",
       		"connection.url":"jdbc:mysql://mysql:3306/TEST",
       		"connection.user":"TEST",
       		"connection.password":"password",
       		"auto.create":true
     	}'

就是这样。您生成的数据现在应该从 Postgres 流到 Mysql。让我们回顾一下 Mysql sink 连接器的属性:

  • insert.mode:如何将数据插入数据库。你可以在insertupsert之间选择。
  • topics:从中读取数据的主题
  • connection.url:接收器连接 URL
  • connection.user & connection.password:汇凭证
  • auto.create:不存在时自动创建表格

让我们查询 MySQL 数据库,看看我们的数据是否在那里。我们可以看到记录计数和最大时间戳都在更新!

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

通过查询 SQL 数据库,我们可以实时看到新的数据

创建 S3 水槽连接器

要将数据写入 S3,同样简单明了。您需要在docker-compose-kafka.yml文件中设置环境变量:AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY。之后,您可以使用以下配置创建 S3 连接器:

curl -i -X PUT -H "Accept:application/json" \
    -H  "Content-Type:application/json" http://localhost:8083/connectors/SINK_S3/config \
    -d '
{
    "connector.class": "io.confluent.connect.s3.S3SinkConnector",
    "s3.region": "ap-southeast-1",
    "s3.bucket.name": "bucket-name",
    "topics": "P_USERS",
    "flush.size": "5",
    "timezone": "UTC",
    "tasks.max": "1",
    "value.converter.value.subject.name.strategy": "io.confluent.kafka.serializers.subject.RecordNameStrategy",
    "locale": "US",
    "format.class": "io.confluent.connect.s3.format.json.JsonFormat",
    "partitioner.class": "io.confluent.connect.storage.partitioner.DefaultPartitioner",
    "internal.value.converter": "org.apache.kafka.connect.json.JsonConverter",
    "storage.class": "io.confluent.connect.s3.storage.S3Storage",
    "rotate.schedule.interval.ms": "6000"
}'

一些值得注意的配置:

  • s3.region:你的 S3 桶的区域
  • s3.bucket.name:写入数据的桶名
  • topics:读取数据的主题
  • format.class:数据格式。您可以从JSONAvroParquet中选择

管道

瞧,你的管道现在完成了。通过几个 docker-compose 配置文件和连接器配置,您已经创建了一个支持近实时数据分析功能的流管道。相当强大的东西!

后续步骤

现在用户数据在 Kafka 和我们的水槽中。电子邮件服务可以实时获取客户数据,轮询推荐 API,并在 2 秒钟内向客户发送欢迎电子邮件。同样,利用数据湖中的数据,您可以为您的 CEO 创建一个实时仪表板。

但是您不必就此止步,因为 Kafka 及其组件是可横向扩展的。您可以使用 Kafka 为大部分(如果不是全部)管道供电。一些公司运行 Kafka 集群,拥有数千个生产者和订户。当然,在这样的规模下,除了简单的概念验证设置之外,还有更多工作要做。但是有一些托管的 Kafka 服务,你可以开箱即用,比如 AWS 上的 MSK,或者 Confluent(多平台)。您还可以添加更多组件来处理实时数据,如 Spark Streaming、KSQL、Beam 或 Flink。

打扫

如果您没有运行任何其他 docker 容器,您可以使用以下命令关闭这个项目的 docker 容器:

docker stop $(docker ps -aq)

或者,您可以通过运行以下命令来清理本地下载的 docker 映像:

docker system prune

结论

在这个项目中,我们使用 Docker、Kafka 和 Kafka Connect 构建了一个流数据管道,这让我们的营销团队和首席执行官非常高兴。有了我们构建的东西,其他团队可以很容易地从那里得到它,交付我们的涉众所要求的东西。

如果你以前从未使用过 Kafka,我鼓励你自己尝试这个项目。如果你有兴趣阅读类似的东西,neptune.ai 的人写了一篇关于如何用 Kedro 构建数据科学管道的优秀文章。

快乐学习:)

卡夫卡在行动:用 Python 和融合的卡夫卡构建分布式多视频处理管道

原文:https://towardsdatascience.com/kafka-in-action-building-a-distributed-multi-video-processing-pipeline-with-python-and-confluent-9f133858f5a0?source=collection_archive---------7-----------------------

实时大规模数据处理和机器学习。

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

我们将会建造什么

介绍

试图通过建立一个项目来学习任何主题是一种有趣而直观的方式来加强我们的理解。在这篇文章中,我们将通过这样做来探索卡夫卡。

我们将会建造什么

想象一下这样一个场景,我们有多个来源生成视频流,我们需要近乎实时地处理和存储数据(如上图)。卡夫卡是这种情况下的完美契合。

先决条件

  1. 对卡夫卡有基本的了解会有所帮助,但是如果你觉得舒服,你可以随时随地探索和学习。
  2. 你需要在你的系统中安装 docker ,因为我们将使用它来运行应用程序,然而,安装软件包的二进制版本也可以。

我们开始吧

开始卡夫卡

我们将使用夏羽·马瑞克的惊人项目kafka-stack-docker-compose在 Docker 中运行 Kafka。首先,您需要克隆回购:

git clone [https://github.com/simplesteph/kafka-stack-docker-compose.git](https://github.com/simplesteph/kafka-stack-docker-compose.git)

然后,根据集群配置,您可以运行所需的 docker-compose 文件。在本文中,我们将保持简单,用一个 zookeeper 和一个 kafka 服务器运行一个集群。假设您已经启动了 Docker,运行:

cd kafka-stack-docker-compose
docker-compose -f zk-single-kafka-single.yml up

我们现在已经通过两个简单的步骤启动了 Kafka 集群!

正在启动 MongoDB

我们将使用 MongoDB 来存储处理后的数据。同样,我们将使用 Docker 来运行 MongoDB。首先,我们需要创建一个docker volume ,这个将帮助我们在磁盘中持久保存数据,即使我们停止并移除容器。要创建体积管路,请执行以下操作:

docker volume create data-mongodb

data-mongodb 是我们卷的名称。接下来,我们将启动 MongoDB 服务器实例,并在其上挂载data-mongodb卷。运行:

docker run -v data-mongodb:/data/db -p 27017:27017 --name mongodb -d mongo

这将自动提取 MongoDB 映像并启动容器。

好吧!现在我们已经有了 Kafka 和 MongoDB,让我们开始研究这个项目。

卡夫卡在行动

我们将要使用的代码可以在这个 repo 中找到。将 repo 克隆到工作区中。

git clone [https://github.com/wingedrasengan927/Distributed-Multi-Video-Streaming-and-Processing-with-Kafka.git](https://github.com/wingedrasengan927/Distributed-Multi-Video-Streaming-and-Processing-with-Kafka.git)

接下来安装必要的依赖项。最好为项目创建一个单独的虚拟环境,然后安装。

cd Distributed-Multi-Video-Streaming-and-Processing-with-Kafka
pip install -r requirements.txt

卡夫卡主题

我们要做的第一件事就是创造一个卡夫卡式的话题。要创建主题运行:

python create_topic.py

创建卡夫卡主题

这里我创建了一个名为multi-video-stream的主题,复制因子为 1 和 3 个分区。您可以试验复制因子和分区数量,但是要记住相应地更改Admin Client(第 6 行)中的服务器配置,还要注意副本的数量不能超过集群中服务器的数量。

卡夫卡制片人

Producer 应用程序从视频中读取帧,并将它们发布到 Kafka 主题。让我们浏览一下代码。

生产者应用

在开始时,我已经提到,我们将与多个来源产生视频流。我们需要一种在本地环境中模拟这种情况的方法。我们可以通过使用并发性并在一个线程中处理每个视频来做到这一点。

Kafka Producer 是线程安全的——我们可以创建单个 Producer 实例,并在多个线程间共享它。

在上面的代码中,我将所有的函数打包成一个类,当我们实例化这个类时,我们创建了一个 Kafka Producer。

方法publishFrame负责从视频中读取帧并将它们发布到卡夫卡主题。我们在这里使用opencv进行视频操作。在对 produce 方法的调用中,我们传递了以下参数:

  • **主题:**我们要将数据发送到的主题的名称。请记住,我们之前已经创建了主题。
  • **值:**这是实际的视频帧数据,被序列化为字节。
  • on_delivery: 生产方法是异步的。它不会等待确认消息是否已经传递。我们传入一个回调函数,该函数记录关于所产生的消息或错误(如果有的话)的信息。回调作为调用pollflush方法的副作用被执行和发送。
  • **时间戳:**给出数据时间属性信息的值。注意,这里我传递的是帧数,而不是绝对时间,因为它更相关。
  • headers: Headers 包含我们想要发布到主题的任何关联元数据。请注意,回调函数不会记录标头。

还要注意,我们每三帧发布一次,每一帧后等待一段时间。这是因为在现实世界中,我们以特定的 fps 从源获得帧,并且在每个连续帧之间没有太多的信息差异,尤其是在机器学习的背景下。这也有助于减少 Kafka 服务器上的负载。

start方法将每个视频映射到一个线程,并发运行应用程序。

要启动 Producer 应用程序,将您的视频放入video文件夹,在第 47 行相应地更改扩展名,然后运行:

python producer_app.py

这将同时开始向 Kafka 主题发布视频帧。您应该会看到关于所记录的生成消息的信息。

现在让我们看看另一面。

卡夫卡消费者

消费者应用程序订阅 Kafka 主题来接收数据。我们通过图像分类模型对数据进行推理,然后将结果存储到 MongoDB 数据库中。让我们浏览一下代码。

消费者应用

消费者在一个消费者群体中运作。组中的每个消费者从独占分区读取数据。如果一个组中的消费者数量超过了分区的数量,一些消费者将处于非活动状态。

在我们的消费者应用程序中,我们有多个属于同一个组的消费者同时从 Kafka 主题中读取数据。注意,与生产者不同,消费者不是线程安全的,每个线程需要有一个单独的消费者实例。

我们用run方法完成从接收数据到处理和存储数据的所有操作。首先,我们对来自主题的数据进行轮询,如果没有错误并且消息有效,我们将继续进行进一步的处理。

注意,消费者从主题中一次轮询一批消息,并将它们存储在内部缓冲区中,并从那里读取。

一旦我们收到消息,我们就对它进行解码,从中提取时间戳和元数据,并将其附加到一个数组中。

批量操作

如果你观察,我们不是一个接一个地处理消息,而是批量处理数据并对数据执行操作。这提高了效率和吞吐量。

一旦数据批次形成,我们就将其传递给图像分类模型,在我们的情况下,该模型是在 ImageNet 上训练的 ResNet50 模型。该模型每帧输出标签及其相应的置信度。我们只挑选最上面的标签和它的置信度并存储它。

接下来,我们将获得的结果插入 MongoDB 数据库。数据在数据库中的组织方式是,我们将每个视频作为一个集合,在每个集合中,我们都有包含该帧信息的记录或文档。该文档具有帧号、帧标签和置信度作为其字段,使得查询数据变得容易。此外,请注意,正如我们之前讨论的那样,我们正在向数据库中执行批量插入。

在这之后,我们完成了数据的处理,我们想把同样的事情告诉卡夫卡。Kafka 使用偏移量来跟踪消费者轮询的数据记录的位置,因此即使消费者倒下了,Kafka 也能够从它停止的地方读回来。我们希望如何提交偏移量以及遵循哪种交付语义由我们决定。这里,我们在数据处理完成后提交偏移量。这遵循了至少一次交货的语义。

**注意:**因为我们手动提交偏移量,所以在配置文件中我们必须将enable.auto.commit属性设置为False

**注意:**在至少一次交付语义中,如果消费者停止使用或处理出错,消息有可能被再次处理。为了避免重复的消息,我们必须维护幂等系统。例如,在我们的例子中,我们确保将一个惟一的文档插入到一个集合中,这样即使再次处理一个消息,数据库中也不会有任何重复。

好吧,让我们回到代码上。要运行消费者应用程序,请在第 108 行设置主题,在第 124 行更改视频名称(注意:这些名称必须与我们通过生产者发布的视频名称相匹配,并且这些名称也将是数据库中的集合名称),确保消费者的数量不超过第 128 行中的分区数量,然后运行:

python consumer_app.py

如果您同时启动生产者应用程序和消费者应用程序,它看起来会像这样并排:

左:制片人;右图:消费者

还可以可视化存储在 MongoDB 中的数据。 Robo3T 是一个很好的工具:

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

在 Robo3T 中可视化文档

在生产中部署

生产中的事情会变得更加复杂。幸运的是,我们在云平台上有托管服务,如谷歌云发布/订阅(T1)或 T2 亚马逊 kine sis(T3),这让我们的工作变得更容易。最好在生产中使用它们。

此外,在本文中,我们没有讨论生产者和消费者的配置,但是基于用例对它们进行调优是非常重要的。例如,在某些情况下,延迟可能是高优先级,我们可能不关心数据丢失或数据顺序,而在其他情况下,数据可能被赋予高优先级。需要相应地配置生产者和消费者。

对于生产中的机器学习,最佳实践是使用 Tensorflow 服务 API ,而不是在消费者应用中初始化模型。

此外,最好使用云中的托管数据库来存储数据。

结论

这让我们走到了尽头!Kafka 正在大量的项目中使用,并且还在继续增长。这一点非常重要。下面我提到了一些额外的资源,可以帮助你加深对卡夫卡的了解。

希望这篇文章是有帮助的。如果您有任何反馈或想与我取得联系,请在ms.neerajkrishna@gmail.com 给我留言。

推特上连线吧!

额外资源

  • 夏羽·马瑞克在《我的世界》上的精彩课程
  • 汇合者拥有关于卡夫卡的惊人的文档和博客。

Kaggle 第一名得主作弊,10,000 美元奖金宣布不可收回

原文:https://towardsdatascience.com/kaggle-1st-place-winner-cheated-10-000-prize-declared-irrecoverable-bb7e1b639365?source=collection_archive---------3-----------------------

一个团队如何获得私人数据,构建一个假的人工智能模型,并从一个收养被忽视的宠物的平台上获得资金

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

骗子们从一个收养无家可归和被忽视的宠物的平台 Petfinder.my 上偷东西。像素图像

Kaggle 刚刚宣布第一名队伍 Bestpetting【1】,因作弊被取消 Petfinder.my 比赛资格。该团队爬上宠物收养网站收集私人排行榜答案,并将这些数据隐藏在他们的提交材料中,以赢得 2019 年 4 月 9 日的第一名。一等奖从 25,000 美元的奖金池中拿出 10,000 美元。在这篇文章中,你会发现 Kaggle 的背景,其竞争的黑暗面,以及相关资源的链接。

链接

什么是卡格尔比赛

Kaggle(谷歌的子公司)是一个围绕比赛建立的在线社区,旨在建立机器学习模型。该平台的奖金高达 150 万美元,吸引了形形色色的追随者。此类竞赛提供了一个数据集,以及将用于决定获奖作品的指标。竞争者分析给定的数据,构建模型以匹配期望的结果,并提交他们的结果(通常与他们的代码一起)。为了防止作弊,机器学习比赛包括没有标记的数据,并在两个阶段使用:

  • 当比赛结束时,数据集的“私人”部分(竞争者仅拥有未标记的数据)用于选择获胜者。这些数据理想地代表了模型在从未见过的数据上的表现。
  • 为了在比赛期间对参赛者进行排名,团队提交的内容将根据“排行榜”专用数据集的一部分进行评分。像“私人”测试数据一样,竞争对手也有这些数据,但没有标签。仅针对排行榜指标进行优化的团队往往会因为不适合数据集的“私有”部分而失败。

用私人数据作弊

这种竞赛形式的结果是,如果一个团队获得了私有测试数据集的真实答案,那么它就一定会赢。作弊团队制作的模型将是无效的,使比赛无效。

在这种情况下,作弊者将私人答案和提交的答案打包在一起。其他攻击可能更难检测。其中一种方法是使用完整的数据集优化超参数,创建一个似乎巧合地更有效的模型。也许作弊团队选择了一种更容易被发现的方法,因为他们根本没有能力创建一个值得登上排行榜的模型,或者他们太厚颜无耻了。

缓解这些问题的方法是将私有数据完全排除在竞争之外。提交的内容必须包括提供 API 来生成预测的代码。这也将防止竞争者知道特征在私人和排行榜数据中的分布。

卡格尔的黑暗面

Kaggle 竞赛有许多潜在的问题。我在一次检测信用卡欺诈的比赛中偶然发现了一个例子。一个流行的模型正在使用来自未来的信息进行训练,这将使它在实践中无法使用——银行没有水晶球。许多模型以产生更高分数的方式使用数据集,但是使模型对竞赛组织者无用。这些模特仍然可以赢得比赛,因为他们没有违反任何规则。

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

卡格尔模型中不切实际的一个例子

由于这些漏洞和潜在的无用结果,竞赛组织者必须格外警惕和小心他们的数据和规则。有些要求在多轮比赛中获胜,有些则在大量的顶级作品中平均分配奖金。

惯犯

这不是帕维尔第一次违背卡格尔比赛的宗旨,或者被指控作弊。看来卡格尔过去没有谴责和采取这些策略。

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

帕维尔·普莱斯科夫承认在另一场比赛中刮伤。

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

一个谴责 Kaggle 作弊的帖子,Pavel Pleskov 评论为“垃圾邮件”。

这些疑虑不仅仅被卡格尔忽略了,从卡格尔制作的采访中可以看出,帕维尔是一位著名的大师。

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

结果

除了被剥夺他的奖金并被禁止进入 Kaggle 平台,我还联系了帕维尔的雇主 H2O.ai,请他发表评论。这是英格丽·伯顿的回答:

今天早些时候,我们已经知道了这个情况。他不再隶属于 H2O.ai,立即生效。我们还将联系 Petfinder.my,看看我们如何帮助他们。

我没有找到关于费多尔·多布里扬斯基的进一步信息,他也被禁止进入 Kaggle。根据 Kaggle 的调查,他们选择不禁止 Narek Maloyan。

卡格尔更光明的未来

Kaggle 一直是推动机器学习成为可能的巨大力量。获奖的作品通常会展示最佳的工具和实践,并激发人们发明新的技术。尽管不切实际的模型和作弊伤害了竞赛组织者、Kaggle 品牌和整个生态系统,但好处和潜力远远大于坏处。

也许这是 Kaggle 新篇章的标志。如果他们想重建对平台及其社区失去的信任,他们还有很多事情要做。推动可重复、公平和有用的模型构建竞赛,正是机器学习所需要的。让我们希望我们得到它。

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

[ pixabay 图像

1最佳团队包括:帕维尔·普莱斯科夫纳雷克·马洛扬和费多尔·多布里扬斯基。

编辑 2020–06–05—pet finder . my 于 2020–01–28 宣布 Bestpetting 团队发布道歉并返还被盗资金

Kaggle 第三名解决方案— Jigsaw 多语言毒性评论分类

原文:https://towardsdatascience.com/kaggle-3rd-place-solution-jigsaw-multilingual-toxic-comment-classification-e36d7d194bfb?source=collection_archive---------23-----------------------

方法、知识和代码

我最近参加了 Kaggle 的拼图多语言毒性评论分类挑战赛,我们的团队(ACE 团队)在最终的排行榜上获得了第三名。在这篇博客中,我描述了问题陈述,我们的方法,以及我们从竞赛中学到的东西。我还在博客末尾提供了我们全部代码的链接。

问题描述

比赛的目标是检测在线互动期间用户评论中的毒性(例如粗鲁、不尊重或威胁)。这是一个非常现实的问题,因为最近社交媒体上的钓鱼和仇恨越来越多。

该问题被设置为一个普通的文本分类问题,其中人们必须预测(文本)评论有毒的概率,并根据 ROC AUC 指标对提交的内容进行评估

问题中最有趣的部分是——必须用 6 种不同的语言来识别毒性,其中 3 种语言根本没有训练数据,其余 3 种语言的训练数据也很少。

该比赛由谷歌公司 Jigsaw 组织,该公司开发工具来处理在线内容中的毒性、虚假信息、骚扰和激进化等问题。这是 Jigsaw 举办的第三次毒性检测竞赛(尽管是第一次多语言竞赛)。

为什么问题具有挑战性?

检测毒性不仅仅是检测文本中的辱骂性词语。作为一个例子,考虑下面的评论,它没有任何辱骂的话,但仍然是有毒的

我只想找点乐子,扫兴船长。我猜你年轻的时候从来没有生活过。那可能有 100000000000000000 岁了

除此之外,如果你试图解决跨多种语言的问题,它会变得相当棘手。

解决方案概述

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

上图高度概括了我们最终解决方案的各个组件,以及它们各自的得分(ROC)和权重,最终得分为 0.9523。

最终的解决方案是以各种方式训练的不同基础模型的混合。上图中的“罗伯塔”代表从罗伯塔·XLM 架构派生的模型,而单声道 Bert 代表根据特定语言的文本预先训练的 Bert 基础模型。

技术概述

下面的流程图提供了我们解决方案的高级技术概述。我将在接下来的部分分享各种细节

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

训练数据/预处理

我们在竞赛中使用以下数据集进行模型训练:

  • 由组织者从过去的比赛中提供的有标签的英语数据
  • 每种目标语言的标记英语数据的翻译版本
  • 组织者以目标语言提供的小型验证数据
  • 打开字幕数据,使用伪标签生成标签
  • 带有伪标签的测试数据集*

使用分层抽样从上述项目中准备列车数据,以确保等级平衡。

将标记的英文数据翻译成目标语言有助于缺少目标语言的标记数据,但不如目标语言本身的数据好,因为翻译过程去除了文本的一些微妙之处,而这些微妙之处有时对检测毒性很重要。

预训练模型

自 2018 年以来,基于 Transformer 架构的预训练(迁移学习)模型在 NLP 中非常流行。从概念上讲,它们是在大量(万亿字节)文本数据上训练的深度学习模型,因此它们学习语言(单词、文本)的非常好的数字表示。这些表示在各种下游任务中很有用。你可以在我的早期博客中阅读更多关于变形金刚和转移学习的细节

罗伯塔·XLM 是谷歌的伯特在架构方面的变体,预先接受了 100 多种语言的培训,是比赛中的主力。它的表现出人意料地好,甚至在其他语言上只有英语训练数据的情况下也表现不错。

除了上面描述的多语言模型,我们还使用了针对感兴趣的特定语言预先训练的 Bert 模型。正如人们所预料的那样,与多语言模型相比,这些单语模型对于它们被训练的单种语言表现得更好(对于给定的模型容量,每种语言的性能随着我们增加语言的数量而下降)。但是这种方法在实践中稍显逊色,因为如果处理大量语言,在生产中维护特定于语言的模型会很麻烦。

模特培训

这是很多艺术和经验发挥作用的地方。我们使用各种策略进行模型训练:

  • **多阶段训练:**在逐渐变难的任务上训练模型,在刚刚标记的英语数据上进行示例训练,然后逐渐移动到更难的任务,示例伪标签,然后在验证数据上进行最后一轮(时期)训练,因为这接近于测试数据
  • 针对特定领域数据的无监督训练:【RoBERTa 等庞大的语言模型通常是在新闻、维基百科等通用数据集上训练的——这可能与你的特定任务数据的内容/结构/词汇有很大不同。虽然获得标记数据总是一个昂贵的提议,但通常有更大的未标记数据(在这种情况下只是原始文本数据)的可用性,这些数据可用于预训练。这有助于稍后进行特定任务监督训练时的表现
  • 多重平均:将我之前描述的所有不同类型的数据集放在一起的训练样本数量达到了数百万。我们观察到,模型在训练期间很快饱和,并在大约 200,000 个样本后停止改善。我们使用数据的随机子集训练各种模型,并使用这些模型对测试数据集的预测进行平均

预测和混合/集成

众所周知,混合各种不同模型的预测往往优于潜在的单个模型预测,并且通常是改善最终预测的最佳方式。

如“解决方案概述”中所述,我们的最终解决方案融合了 4 个模型系列的预测。我们在每个家庭内训练了多倍模型(对不同数据子集的训练)最终得到大约 30(!!)奇款。

我们对每个系列内的多倍预测进行了直接平均,并对不同系列模型的预测进行了加权平均。我们没有真正的质量数据集,底层模型看不到,来提供整个家庭的权重,所以我们使用一些直觉,领导委员会的反馈和实验来确定这些权重。

测试时间增强(TTA)是一种技术,在这种技术中,我们不仅对测试示例进行预测,还对它的一些变体进行预测,以获得更好的最终预测。我们在一些底层模型中采用了这种技术,它给了我们一个小小的提升,下面是它的工作原理:

  • 对测试数据集中的原始注释进行预测
  • 对原始评论的各种语言翻译进行预测
  • 对原始评论及其翻译的预测进行加权平均

五金器具

深度学习模型在 GPU 上运行比在 CPU 上运行快得多已经不是什么秘密,但是谷歌的 TPU 甚至比 GPU 还要快。它们在内存(允许更大的批量)和速度(允许快速实验)方面都是非凡的,并使训练过程不那么痛苦。

我们在比赛期间广泛使用了 Kaggle 和 Google Colab 提供的免费 TPU 配额来训练我们的模型。

密码

这是到我们完整代码的链接

ka ggle/学术与现实世界数据科学分析

原文:https://towardsdatascience.com/kaggle-academic-vs-real-world-data-science-analytics-b4c08fed580c?source=collection_archive---------37-----------------------

(初学者 40 分钟阅读。文末免费指导链接)

“被《哈佛商业评论》、IBM 等公司的报告所吸引,我将职业生涯转向了数据科学。我已经完成了数据科学的整个在线专业。我擅长 Python。我已经建立了像……这样的机器学习模型。…在我的 Kaggle 项目中。我非常擅长构建 ML 模型。尽管数据科学有很多机会,但我仍然发现很难找到第一份工作。为什么招聘人员对雇佣有相关实习/工作经验的数据科学家更感兴趣?”

如果这些是你问自己的问题,你今天来对地方了。现实世界中的数据科学与技术课程和学术项目所教授的完全不同。这是唯一的原因,也是为什么招聘人员希望你在招聘前在个人资料中加入过去的数据科学实习/经验。拥有强大的数据科学技术背景总是有帮助的,但现实世界的经验更是锦上添花。

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

时代广场:纽约市(演员表:Self)

在本文中,我们将使用一个非常常见的客户流失(客户保留)建模分析问题来理解学术项目和现实项目之间的差异。如果你擅长讲故事,你或许可以在简历中展示一个学术项目,作为一个真实世界的行业赞助项目,并在下一次面试中显得更有前途。

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

图一

分析流程:(针对客户流失预测数据科学项目)

1)定义问题:

卡格尔:

阅读客户流失的问题陈述。浏览各列以了解数据。跳入数据中。

现实世界:

管理层的问题陈述非常含糊。我们必须最后确定我们正在处理的到底是什么问题。在项目的后期过程中,问题陈述不能改变。

首先,我们需要定义客户流失。流失可能是永久流失,也可能是临时流失(其中客户会在一定时间后返回),具体取决于领域。

流媒体服务提供商(如网飞)有暂时的流失现象。我们需要定义一个停用天数的阈值,称之为流失。比如说 D+15,D+30(D+X =停用后的天数)。这个定义需要大量的头脑风暴、领域知识以及最终管理层的批准。

在暂时搅动问题中,可能发生订户搅动多次的情况。而在永久性流失问题中,客户永远不会回来。暂时的和永久的流失有不同的方法。

任何流失项目的问题陈述将是识别高风险流失客户并试图留住他们。

2)检查可行性。例如,所需数据和其他资源的可用性:

卡格尔:

必须足够可行,才能上传到这个平台上。所有的数据集都是可用的。不需要外部数据,没有外部数据可能会使问题变得不可行。

真实世界:

解决这个问题可行吗?我们是否拥有所需的数据和资源?有可能实现吗?

我们能想到一些可能导致客户流失的因素吗,包括客户人口统计、客户产品特征、外部变量?这些因素的数据可以利用吗?

如果模型准备好了,有可能实现吗?(可能不总是)。

实施的成本是多少?我们真的获利了吗?

例如,对于贷款流失(余额转移)的银行领域问题,即使我们使用机器学习获得了高风险客户,因为所有贷款条款都是固定的,所以你无法为客户提供任何东西来留住他/她。即使利率是可变的,并且联系客户告知他们有资格获得更低的利率,所有的误报都会导致银行的巨大损失。因此,在这种情况下,做客户流失建模可能没有意义。

3)估算 ROI,预期收益:

卡格尔:

不需要。没问过。

现实世界:

解决这个问题值得吗?

对于像流失这样的预测建模项目,关联每个真阳性、真阴性的近似收益和每个假阳性和假阴性的损失,我们可以估计 ROI。它包含了执行项目、实施项目等的所有费用。如果投资回报率更低,这个项目就没有意义。

**4)问题分类:**描述性/预测性/规定性:预测性

【Kaggle 和现实世界:

由于我们预测客户流失的可能性,这是一个预测分析项目**。**如果问题是确定哪种产品的流失率最高,那么它就是一个描述性分析项目,如果问题是找到流失率最低的最佳销售价格,那么它就是一个说明性分析项目。为了能够选择必要的工具和资源,将问题分类到合适的箱中是很重要的。

4.2)预测:

让我们直接讨论预测分析,因为我们正在处理客户流失建模。

a)再检查一下,简单的特征分析是否能让你找到高危人群?

卡格尔:

这不是我们被要求提交的。

现实世界:

用目标变量客户流失对每个变量进行二元可视化,我们可以知道每个变量对客户流失的影响。使用一些重要的变量,我们可以获得高风险的概况/特征,并使用简单的 SQL 查询找到它们的提升。例如,年龄在 30-35 岁之间、居住在纽约市、年份为 3 年的客户流失的可能性是其他客户的 2.6 倍。找到一些高风险的特征并只针对它们,可以节省我们在机器学习上投入的时间和资源。在进入机器学习之前,我们需要比较这两种方法的投资回报率。

b)决定分析单位、目标变量和要包含的行

卡格尔:

每行的主键是分析单位。我们希望找到每一行的预测。目标变量列已经可用。因此,分析单位和目标变量都被设置为包括在模型库中。

真实世界:

让我们讨论一下流媒体服务公司(比如网飞)的临时流失问题。

我们必须问一个问题,我们到底在预测什么?这并不像看起来那么简单。我们只是预测客户流失的可能性吗?令人惊讶的不是。概率随着时间而变化。客户 A 在 2020 年 1 月流失的概率可能不同于 2019 年 10 月。我们预测客户在特定的时间流失的概率。我们希望找到导致客户流失的高风险特征,而不是导致客户流失的高风险客户。因此,模型库中的一行将对应于某一时刻的客户简档。如果我们以月为单位考虑时间,则对于同一客户,模型库将有“n”个条目/行,其中“n”是客户的年份(以月为单位的网络年龄)。因此,

分析单位= {客户,时间(月)}

目标变量的定义应该与第 1 部分的问题陈述中的定义完全相同。假设我们定义了:失活+15 天作为目标变量(流失)

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

表 1:理解分析单元

在这种情况下,模型库中的行不应该只表示最新的客户数据,还应该表示与时间(这里是月)相关的客户数据。

我们举个例子。

我在 2018 年 1 月加入了流媒体订阅。充值日期为每月 1 日(假设不是自动充值)。

如果我在 1 日之前没有充值,我将从 2 日起被取消激活。如果我在那个月的 15 号之前没有充值,我会被认为在那个月被“搅了”。

因此目标变量也可以定义为,

一个月内搅动=“停用至一个月的 15 日”

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

表 2:每月 2 日的我的数据和每月最后一天的目标变量

比如,我在 2019 年 1 月搅拌,2019 年 3 月返回,2019 年 5 月再次搅拌,2019 年 8 月返回。如果我停用(4 月 1 日不充值),2020 年 4 月我会流失的概率有多大?

这是我的数据行在模型库中的样子。它由我每月的数据组成。同样,所有客户都有历史数据。因此,我们预测的是客户在特定时间流失的可能性。

仅选择相关的观察结果:

在选择要包含在模型库中的观测值之前,我们应该考虑一下模型部署。比方说,该公司正计划给高风险客户打电话,向他们提供折扣以留住他们。他们也想给活跃客户打电话吗?没道理。他们只想给在月 1 日没有充值的客户打电话,这些客户目前已经停用,以防止他们在 D+15(流失)后再次充值。话虽如此,我们只想找到一个去激活的客户流失的概率,而不是活跃的客户。这使得我们从模型库中排除了在当月 1 日进行充值的那些月份的客户资料(客户一直处于活动状态),仅考虑停用情况。(这是使用“第一次充电”变量确定的)

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

表 3:样本客户(me)在模型库中的最终行

c)手动进行特征工程,创建新特征,修改现有特征

卡格尔:

除了要素编码之外,从现有要素创建新要素、修改现有要素的范围较小。

现实世界:

现实世界的问题完全依赖于特征工程。没有填鸭式的特征。我们必须从多个来源获取数据,将其转换为可用的形式,并从中创建新的功能以包含在模型库中。这需要大量使用数据操作、连接。等等。与 Python/R 相比,NoSQL SQL 更适合执行此任务。在流媒体服务的流失预测问题中,我们可以创建如下变量:

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

表 4:变量和来源

我们必须有创造性。这与其说是科学,不如说是艺术。我们必须了解这个领域,以便能够创建新的变量。

我们也可以将多个变量组合成一个新的变量。或者修改现有变量以增加其预测能力。

d)探索性数据分析

卡格尔:

几个图来理解 Python/R 上的数据,查看分布。等等。没有演示要点,专注于更好地调整模型。

现实世界:

管理层想要一个带有切片器的仪表板,显示所有的变量关系。他们不会相信你给他们展示了多少形象化的东西。每次都会请求许多特别报告。交流结果是这项工作的重要组成部分,如果没有充分的探索性数据分析和数据挖掘,这是不可能的。一般来说,像 Excel,Tableau,PowerBI 等工具。在 EDA 行业中使用。

e)去除多重共线性,进行特征选择:

【Kaggle 和现实世界:

两者都涉及平等的工作。

f)尝试不同的 ML/DL 算法,在验证和测试数据上评估模型:

卡格尔:

尝试很多算法。做超参数调整。使用最复杂的算法。切换到 DL。你所要做的就是尽量减少误差。注重准确性!!超越记分牌。

现实世界:

准确很重要,但钱更重要。努力使投资回报最大化(后面会讲到)。建立一个能带来更多利润的模型。管理层不会理解和批准暗箱操作。使用简单的可解释算法,如逻辑回归、分类、树、正则化等。避免深度学习。

ghij)模型部署和实施、自动化、跟踪和更新:

卡格尔:

项目结束了。只需上传结果。专注于记分牌。

现实世界:

如果模型没有正确实现,预测就没有用。制定模型部署策略需要大量的头脑风暴和领域专业知识。要联系多少人?怎么联系?联系谁?什么时候联系?预期收益是否超过实施成本?

让我们以银行贷款的客户流失模型为例。机器学习给我们每个客户下个月流失(余额转移)的概率。

要联系多少人口?

针对多少高风险客户?我们需要设置一个增益最大的概率阈值。

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

要设置一个概率阈值,我们必须考虑与 TP、FP、TN、FN 相关的成本停在收益最大的概率。

回报=每个 TP 和 TN 的预期利润-每个 FP 和 FN 的预期损失

如何联系?

交流方式。用什么来留住他们?较低的利率,或任何其他好处。

联系谁

我们是否只考虑流失概率来确定目标人群?我们还必须包括这种变动带来的财务损失。客户流失的可能性很低,但如果流失,损失会很大,必须联系他。

什么时候联系?

EMI 付款日期前几天?紧接着?或者任何时候。

预期收益是否超过实施成本?

如果向高风险客户提供较低的利率来留住他们,假阳性将会给银行造成巨大损失。我们还有足够的利润吗?如果没有,一切都是徒劳。

在所有这些都完成之后,在需要的时候,自动化模型来对新数据进行评分。这是通过使用一组在云上定期运行的 python 脚本来生产模型代码来实现的。通常,每个月都会对客户进行评分。一个月后,我们需要跟踪模型性能,计算我们为公司节省了多少。可以使用各种方法,如测试和控制、A/B 测试来跟踪实际新数据的模型性能。实施部分似乎比预测建模部分更具挑战性。如果模型的性能开始每月逐渐下降,这可能是因为自变量和因变量之间的关系随时间而变化。这个模型需要翻新。在高度动态的情况下,模型经常需要翻新。

希望你能感受到现实世界中的事情有多复杂。

注意:本文无意批评学术课程或 Kaggle 平台。

感谢读者的耐心。

参考:

自己

注意:我正在完成数据科学的硕士学位,想在美国找一份数据科学分析的全职工作。感谢任何线索。

【https://www.linkedin.com/in/kashyap-bhuva/ 号

kbvbhuva@gmail.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值