TowardsDataScience-博客中文翻译-2016-2018-二十六-

龙哥盟 / 2024-10-13 / 原文

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

糖尿病数据的机器学习工作流程:第 2 部分

原文:https://towardsdatascience.com/machine-learning-workflow-on-diabetes-data-part-02-11262b7f7a5c?source=collection_archive---------3-----------------------

在本系列的上一篇文章中,我们讨论了关于糖尿病数据集的机器学习工作流。并讨论了诸如数据探索、数据清洗、特征工程基础和模型选择过程等主题。你可以在下面找到之前的文章。

[## 糖尿病数据的机器学习工作流程:第 1 部分

“医疗环境中的机器学习可以帮助显著增强医疗诊断。”

towardsdatascience.com](/machine-learning-workflow-on-diabetes-data-part-01-573864fcc6b8)

选择模型后,我们能够确定逻辑回归比其他选择的分类模型表现更好。在本文中,我们将讨论机器学习工作流的下一阶段,高级特征工程和超参数调整。

第 5 阶段—特征工程(再次访问)

并非所有的功能都必须是赢家。大多数时候,有些特性并不能改善模型。这种情况可以通过进一步分析与模型相关的特征来发现。"一个高度预测的特征可以弥补 10 个哑弹"。

正如在阶段 3 中提到的,在模型选择之后,应该进一步讨论特征工程。因此,我们将分析选择的逻辑回归模型,以及特征重要性如何影响它。

Scikit Learn 提供了有用的方法,通过这些方法我们可以进行特征选择,并找出影响模型的特征的重要性。

  1. 单变量特征选择 :统计检验可以用来选择那些与输出变量关系最强的特征。
  2. 递归特征消除 :递归特征消除(或 RFE)的工作原理是递归地删除属性,并在那些保留的属性上建立一个模型。它使用模型精度来确定哪些属性(和属性组合)对预测目标属性贡献最大。
  3. 主成分分析 :主成分分析(或称 PCA)利用线性代数将数据集转换成压缩形式。通常这被称为数据简化技术。PCA 的一个特性是可以选择变换结果中的维数或主分量。
  4. 特征重要性:随机森林和额外树等袋装决策树可以用来估计特征的重要性。

在本教程中,我们将使用递归特征消除作为特征选择方法。

首先,我们导入 RFECV,它带有内置的交叉验证特性。与分类器模型相同,RFECV 具有 fit()方法,该方法接受特性和响应/目标。

逻辑回归—特征选择

from sklearn.feature_selection import RFECVlogreg_model = LogisticRegression()rfecv = RFECV(estimator=logreg_model, step=1, cv=strat_k_fold, scoring='accuracy')
rfecv.fit(X, y)

拟合后,它会显示一个属性 grid_scores_ ,该属性会返回每个所选特征的精度分数列表。我们可以用它来绘制一个图表,以查看给定模型的最大精确度的特征数量。

plt.figure()
plt.title('Logistic Regression CV score vs No of Features')
plt.xlabel("Number of features selected")
plt.ylabel("Cross validation score (nb of correct classifications)")
plt.plot(range(1, len(rfecv.grid_scores_) + 1), rfecv.grid_scores_)
plt.show()

Fig — Feature importance of Logistic Regression

通过查看该图,我们可以看到,将 4 个特征输入到模型中会得到最佳的准确度分数。RFECV 展示了 support_ ,这是找出对预测贡献最大的特征的另一个属性。为了找出选择了哪些特性,我们可以使用下面的代码。

feature_importance = list(zip(feature_names, rfecv.support_))new_features = []for key,value in enumerate(feature_importance):
    if(value[1]) == True:
        new_features.append(value[0])

print(new_features)

['妊娠','葡萄糖','身体质量指数','糖尿病血糖功能']

我们可以看到,给定的特征最适合预测响应类。我们可以对具有原始特征RFECV 选定特征的模型进行比较,以查看准确性得分是否有所提高。

# Calculate accuracy scores 
X_new = diabetes_mod[new_features]initial_score = cross_val_score(logreg_model, X, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Initial accuracy : {} ".format(initial_score))fe_score = cross_val_score(logreg_model, X_new, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Accuracy after Feature Selection : {} ".format(fe_score))

初始精度:0.7764400711728514
特征选择后的精度:0.2676486766

通过观察精度,在将所选特征输入模型后,精度会略有提高。

梯度增强-要素选择

我们还可以分析我们拥有的第二个最佳模型,即梯度增强分类器,以查看特征选择过程是否提高了模型准确性,以及在该过程之后它是否优于逻辑回归。

我们遵循与逻辑回归相同的程序

gb_model = GradientBoostingClassifier()gb_rfecv = RFECV(estimator=gb_model, step=1, cv=strat_k_fold, scoring='accuracy')
gb_rfecv.fit(X, y)plt.figure()
plt.title('Gradient Boost CV score vs No of Features')
plt.xlabel("Number of features selected")
plt.ylabel("Cross validation score (nb of correct classifications)")
plt.plot(range(1, len(gb_rfecv.grid_scores_) + 1), gb_rfecv.grid_scores_)
plt.show()

Fig — Feature importance of Gradient Boost

我们可以看到,拥有 4 个输入特征可以产生最高的精度。

feature_importance = list(zip(feature_names, gb_rfecv.support_))new_features = []for key,value in enumerate(feature_importance):
    if(value[1]) == True:
        new_features.append(value[0])

print(new_features)

['葡萄糖','身体质量指数','糖尿病胰岛素功能','年龄']

以上 4 个特征最适合模型。我们可以比较特征选择前后的准确率。

X_new_gb = diabetes_mod[new_features]initial_score = cross_val_score(gb_model, X, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Initial accuracy : {} ".format(initial_score))fe_score = cross_val_score(gb_model, X_new_gb, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Accuracy after Feature Selection : {} ".format(fe_score))

初始精度:0.764091206294081
特征选择后的精度:0.2666766667

我们可以看到,在特征选择之后,准确度有所提高。

然而逻辑回归比梯度推进更准确。因此,我们将在参数调整阶段使用逻辑回归。

阶段 6 —模型参数调整

Scikit Learn 为模型提供了合理的默认参数,从而给出了不错的准确度分数。它还为用户提供了调整参数的选项,以进一步提高精度。

在分类器中,我们将选择逻辑回归进行微调,其中我们更改模型参数,以便可能提高特定数据集模型的准确性。

我们可以使用 GridSearchCV 轻松执行穷举搜索,而不必手动搜索最佳参数,它会执行“对估计器的指定参数值进行穷举搜索”

这显然是一个非常方便的工具,但当要搜索的参数很高时,它会带来计算成本的代价。

重要提示:在使用 GridSearchCV 时,有些模型的参数相互之间不兼容。由于 GridSearchCV 使用所有给定参数的组合,如果两个参数不能相互配合,我们将无法运行 GridSearchCV。

如果发生这种情况,可以提供一个参数网格列表来克服给定的问题。建议您阅读您正在尝试微调的的类文档,以了解参数之间的相互作用。

首先我们导入 GridSearchCV。

from sklearn.model_selection import GridSearchCV

逻辑回归模型有一些超参数,这些超参数不能相互作用。因此,我们提供了一个具有兼容参数的网格列表来微调模型。通过反复试验,找到了以下兼容参数。

逻辑回归类文档可以在这里找到。

# Specify parameters
c_values = list(np.arange(1, 10))param_grid = [
    {'C': c_values, 'penalty': ['l1'], 'solver' : ['liblinear'], 'multi_class' : ['ovr']}, {'C': c_values, 'penalty': ['l2'], 'solver' : ['liblinear', 'newton-cg', 'lbfgs'], 'multi_class' : ['ovr']}
]

然后,我们将数据拟合到 GridSearchCV,GridSearchCV 针对给定的参数组合对数据执行 K 重交叉验证。这可能需要一段时间才能完成。

grid = GridSearchCV(LogisticRegression(), param_grid, cv=strat_k_fold, scoring='accuracy')grid.fit(X_new, y)

在训练和评分完成之后,GridSearchCV 提供了一些有用的属性来寻找最佳参数和最佳估计量。

print(grid.best_params_)
print(grid.best_estimator_)

Fig — Best attributes of the Logistic Regression

我们可以观察到最佳超参数如下。

{'C': 1, 'multi_class': 'ovr', 'penalty': 'l2', 'solver': 'liblinear'}

我们可以将最佳参数输入逻辑回归模型,并观察其准确性是否有所提高。

logreg_new = LogisticRegression(C=1, multi_class='ovr', penalty='l2', solver='liblinear')initial_score = cross_val_score(logreg_new, X_new, y, cv=strat_k_fold, scoring='accuracy').mean()
print("Final accuracy : {} ".format(initial_score))Final accuracy : 0.7805877119643279

我们可以得出结论,超参数调整并没有增加它的准确性。也许我们选择的超参数并不具有指示性。但是,欢迎您尝试添加更多的参数组合。

最重要的方面是进行超参数调整的过程,而不是结果本身。在大多数情况下,超参数调谐提高了精度。

我们设法实现了 78.05%的分类准确率,可以说这是非常好的。

结论

我们已经到了文章系列的结尾。在这个系列中,我们经历了整个机器学习工作流程。我们讨论了完成分类任务所需的理论和实践知识。

我们讨论了机器学习的工作流程步骤,如数据探索、数据清理步骤、特征工程基础和高级特征选择、模型选择和使用 Scikit Learn library 的超参数调整。

现在轮到你了!现在,您应该能够使用这些知识来尝试其他数据集。

创建这篇文章的源代码可以在下面找到。

[## LahiruTjay/用 Python 学习机器

这个库包含了各种用 Python 完成的机器学习的例子。

github.com](https://github.com/LahiruTjay/Machine-Learning-With-Python/blob/master/Machine Learning Workflow on Diabetes Data.ipynb)

如果你对这篇文章有任何问题,请不要犹豫,在下面留言或者给我发电子邮件:lahiru.tjay@gmail.com

机器学习从零到英雄:第一次在 Kaggle 上竞争所需的一切,循序渐进!

原文:https://towardsdatascience.com/machine-learning-zero-to-hero-everything-you-need-in-order-to-compete-on-kaggle-for-the-first-time-18644e701cf1?source=collection_archive---------1-----------------------

Taken from https://xkcd.com/552/.

我最*偶然看到了瑞秋·托马斯关于写下你所学的东西的重要性和价值的文章,以及 T2 关于为什么以及如何写的建议,因此我决定听从他们的建议,写一篇文章(这是有史以来第一次!).

这篇文章将讲述我希望在一年前就知道的一切,当时我第一次决定学习更多关于数据科学的知识——它是为任何对数据科学感兴趣的人准备的,无论是作为一种爱好还是作为一种潜在的职业。先学习 MOOC 并了解一些基本的 Python 知识将有助于你从本文中获得最大收益,但这并不是必须的。这篇文章不是为了展示什么令人印象深刻的东西(对不起,妈妈、爸爸和潜在的雇主),而是为了复习基础知识,帮助初学者有一个良好的开端。

涵盖话题:

  1. 引言。
  2. Kaggle 概述。
  3. 建立自己的环境。
  4. 预测房价竞赛综述。
  5. 加载和检查数据。
  6. 我们的模型:决策树、偏差-方差权衡和随机森林的解释。
  7. 预处理数据。
  8. 把所有的东西放在一起然后提交。

介绍

现在网上有几个高质量的机器学习教程和 MOOCs 是免费的。一年前,我疯狂阅读了 Udacity 的《ML 简介》( Intro to ML )( T7 ),我发现它非常*易*人,对初学者非常友好,它很好地向我介绍了基本的 ML 概念、几种流行的算法和 scikit-learn 的 API。学完课程后,很兴奋能学到更多东西,但又觉得有点失落。

在进行了一些研究后,我决定接下来最好的事情是查看一下 Kaggle ,这是一个受欢迎的谷歌拥有的预测建模竞赛*台。没有什么比通过实践亲自动手学习更好的了!

第一次在 Kaggle 上竞争是令人生畏的,并且经常令人沮丧(获得一个像样的分数更是如此!),所以这篇文章将关注如何参加你的第一场比赛,并利用 Kaggle 最大限度地提高你的个人成长和成功。

Kaggle —概述

House Prices competition landing page.

如果您已经非常熟悉 Kaggle,请随意跳到下一部分。否则:

最适合初学者的两个 Kaggle 比赛(也是作为 Kaggle 版本的“教程”)是泰坦尼克号(预测生存—二进制分类问题),和房价(预测价格—回归问题)。虽然我强烈建议在这两方面都进行检验和竞争,但本文将重点讨论后者。然而,大部分内容是通用的,同样适用于其他 Kaggle 竞赛和数据科学问题,所以如果你喜欢,可以随意选择泰坦尼克号或其他一些竞赛!

  • 在每个竞赛的“概述”选项卡上,您可以看到一些关于竞赛及其数据集的背景信息、对提交内容进行评分的评估标准(因竞赛而异)以及特定于竞赛的常见问题。
  • 在数据选项卡上,您可以看到数据的简要描述。我们将需要三个文件:train.csvtest.csvdata_description.txt(这是至关重要的,因为它包含了数据的更详细的描述)——把它们放在一个你可以容易访问的文件夹中。
  • “讨论”选项卡就像一个特定于比赛的论坛——但是,不要低估它!在流行的跑步比赛中,它通常包含有价值的信息,因为比赛条款有时要求参与者公开分享他们在讨论板上使用的任何外部信息。例如数据泄露很难避免和处理,在比赛中偶尔发生。一方面,充分利用它对于获得最高分和赢得比赛至关重要,但另一方面,包含数据泄漏的模型对于任何实际目的和比赛的组织者来说通常都是无用的,因为它们包含“非法”信息。通常,一个勤奋的参与者会在讨论板上公开分享泄漏的信息,以*衡竞争环境并消除其竞争优势。除此之外,Kagglers 们经常分享信息,共同努力学习和成长为一个社区。在排行榜上排名靠前的人有时会分享他们的成功方法(通常是在比赛开始时或结束后)。
  • 内核选项卡基本上是讨论板的应用的、基于代码的版本,在我看来是初学者要探索的最重要的选项卡。任何人都可以分享任何脚本或笔记本,连接到任何数据集或比赛,并完成文档,解释,可视化和输出,每个人都可以浏览,投票,复制和粘贴,甚至完全在他们的浏览器中运行!前面提到的两个竞赛都有许多有趣的、漂亮的、非常成功的内核,我强烈建议在亲自尝试过之后再去浏览它们。尽管这是一个相对较新的功能,Kaggle 仍在不断改进内核,甚至有一场 $100,000 的竞赛正在以“仅内核”模式进行。然而,内核常常令人不知所措,缺乏概念上的解释,或者假设有先验知识。换句话说,他们经常展示什么是有效的,但有时不是他们如何到达那里或者为什么它有效。

建立我们自己的环境

我强烈推荐使用 Python 3.6,并在 Jupyter Notebook 环境中使用任何与数据科学相关的东西(最流行的发行版称为' Anaconda ',包括 Python、Jupyter Notebook 和许多有用的库)。然后,您可以随时通过在终端中键入jupyter notebook来启动环境(或者通过 Anaconda GUI)。否则,这里显示的一切都可以在 Kaggle 网站上的私有内核中完成(完全在您的浏览器中),这本质上与 Jupyter 笔记本相同。

在我们开始之前,一些重要的 Jupyter 笔记本提示:

  • 您可以开始键入任何方法名称,然后点击“Tab”来查看所有可能选项的列表。
  • 类似地,选择任何一种方法并按几次“Shift-Tab”将会在你的笔记本中打开它的文档。
  • 在任何语句前输入%time并执行单元格将会打印出执行需要多长时间。
  • 类似地,在任何语句前键入%prun并执行单元格,将通过 Python 的代码分析器运行该语句并打印结果。

关于“魔法”命令的完整列表,请参考文档。前进!

预测房价的逐步指南

目标概述

这是一个监督学习问题——这意味着我们有一个训练集,它包括许多观察值(行)和关于它们的各种信息(列)。其中一列是我们希望能够预测的,通常称为“目标”变量或“因变量”,在分类问题中有时也称为“标签”或“类别”。在我们的情况下,这是销售价格(惊喜惊喜)。其他列通常被称为“独立”变量,或“特征”。我们也有一个测试集,其中也有许多观察值,除了目标变量之外,列完全相同,目标变量将会丢失,我们的工作是预测。因此,理想情况下,我们希望建立一个模型,该模型可以基于训练集学习自变量和因变量之间的关系,然后使用该知识尽可能准确地预测测试集的因变量(或目标变量)。由于目标变量是连续的——销售价格,它可以取任何值——这个问题被称为“回归”问题。

加载数据并查看一下

现在我们已经有了一个 Jupyter 笔记本,我们要做的第一件事是将数据加载到 Pandas 数据框架中。 Pandas 是一个流行而强大的库,它处理 Python 中与数据分析相关的一切,DataFrame 是它用来存储数据的对象的名称。

Opening documentation by hitting ‘Shift-Tab’ a few times.

最后一行使用方便的 Python 3.6 字符串格式将我们从 Kaggle 下载的 CSV 文件(代表“逗号分隔值”,这是一种常见的格式,也可以用任何标准软件如 Excel 直接查看)加载到 Pandas DataFrame 中。既然你会经常用到read_csv,我建议现在浏览一下它的文档。一般来说,如果你不止一次遇到任何方法——浏览它的文档是一个好习惯,如上所述,你也可以直接在笔记本上这样做!第一次加载并查看 DataFrame 时,我注意到数据集中的第一列是Id,表示数据集中该行的索引,而不是一个实际的变量。因此,在将数据加载到 DataFrame 时,我回过头来将index_col=’Id’作为一个参数传递,以确保 Pandas 将它用作索引,而不是将其视为一个列并在它之前添加一个新的索引列——看看阅读文档是如何变得方便的?

现在,让我们看看训练集是什么样的!

A peek into the training set DataFrame.

如我们所见,Id现在被正确应用。此外,训练集总共有 80 列(不包括Id),其中 79 列是自变量,1 列是因变量。因此,我们期望测试集只有 79 列(独立变量),事实确实如此——现在就去检查吧!

这些数字和字符串中的大多数对我们来说还没有多大意义,敏锐的观察者会注意到“Alley”列的值可疑地全部是“NaN”(代表“不是数字”),这意味着这些值是缺失的。别担心,我们最终会解决这个问题的。

下一步是开始考虑我们想要使用什么样的模型。因此,让我们从数据中休息几分钟,谈论一下决策树(当应用于回归问题时,有时被称为‘回归树’)。事后我再来说数据,请大家多多包涵!

建模的简要说明

决策树介绍

这里的基本思想很简单,当学习训练数据(通常称为“拟合”训练数据)时,回归树搜索所有独立变量,然后搜索每个独立变量的所有值,以找到将数据分成两个相似组的最佳变量和值(在数学术语中,树总是选择将两个结果节点的加权*均方差最小化的拆分), 然后计算每个组的分数(基于选择的度量)和因变量的*均值。 然后,该树递归地重复这个过程,直到不再有需要执行的拆分(除非明确指定了 max_depth,如下图所示)。树的最后一级的每个节点被称为“叶子”,并且每个节点与到达该叶子的组中的所有观察值的因变量的*均值相关联。

顺便提一下,这是一个“贪婪”算法的很好的例子——在每次分割时,它都会检查所有选项,然后选择当时看起来最好的选项,希望最终获得一个整体良好的结果。在将树拟合到训练数据之后,我们希望为其预测因变量的值的任何观察都必须遍历树,直到它到达一个叶子(一个结束节点),然后它被赋予该叶子的相应因变量的值。

A visualized example from our dataset, with max_depth set to 3 for ease of visualization.

让我们仔细看看这里显示的树:在每个节点中,第一个元素是该节点的分裂规则(自变量及其值),第二个元素是该节点中所有观测值的均方误差(MSE) ,第三个元素是该节点中的观测值数量('样本')—组的大小。最后一个元素“值”是我们的目标/因变量“销售价格”的自然对数。正如我们所看到的,似乎在每个节点进行局部最佳分裂的贪婪方法确实通常会随着树的扩展而降低 MSE,并且每个叶子都有相关的“销售价格”值。

偏差-方差权衡

让我们回想一下我们在监督学习中的目标。一方面,我们希望我们的模型能够在拟合训练数据时捕捉自变量和因变量之间的关系,以便能够做出准确的预测。但是,模型预测因变量所需的数据必然不同于模型的训练数据。在我们的例子中,它是 Kaggle 测试集。因此,我们希望我们的模型能够捕捉自变量和因变量之间的一般关系,以便它能够推广到看不见的数据并进行良好预测。这有时被称为“偏差——方差权衡”。

Bias —Variance Tradeoff

如果我们的模型没有从训练集中学习到足够的信息,那么它将具有很高的偏差,通常称为“欠拟合”,这意味着它没有捕捉到训练集中可用的所有信息,因此它的预测不会那么好。然而,如果我们的模型对我们的训练数据学习得太好,它将捕获训练集中自变量和因变量之间的特定关系,而不是一般关系,这将具有很高的方差,通常称为“过度拟合”,因此它将很难推广到看不见的数据,其预测也不会很好。显然,我们必须在模型的偏差和方差之间寻求*衡。

决策树过度拟合

想象一下,我们为我们的训练集拟合一棵回归树。这棵树会是什么样子?正如您可能猜到的那样,它将继续分裂,直到每片叶子中只有一个观察点(因为在该点没有更多的分裂可以执行)。换句话说,该树将为训练集中的每个观察值构建唯一的路径,并将为路径末端的叶子提供与其相关联的观察值的相关值。

如果我从我的训练集中删除因变量,并让我的树预测训练集中每个观察值的因变量值,会发生什么?正如您可能想象的那样,它会做得非常完美,基本上达到 100%的准确性和 0 MSE,因为它已经学习了与训练集中的每个观察值相关联的因变量值。

然而,如果我要求树预测未被训练的未被观察的因变量值,它可能会表现不佳,因为任何未被观察的观察结果最终都会从为训练集中的单个特定观察结果构建的叶子中被分配一个因变量值。这就是‘过拟合’的例子。有可能篡改树的参数以减少过度拟合——例如,限制树的 max _ depth——但事实证明有更好的解决方案!

解决方案——随机森林

在 ML 中,我们经常设计元模型,将几个较小模型的预测结合起来,以生成更好的最终预测。这通常被称为‘集合’。具体来说,几个决策树通常以一种集成方法组合在一起,称为‘Bootstrap Aggregating’,或简称为‘Bagging’。由此产生的元模型被称为【随机森林】。

随机森林简单但有效。当适合训练集时,会构建许多决策树,就像上面的一个决策树一样-只有每棵树适合数据的随机子集(“bootstrap sample”,意思是从整个数据集替换而成),并且在每次分裂时只能考虑独立变量(“特征”)的随机子集。然后,为了生成新观察的预测,随机森林简单地对其所有树的预测进行*均,并将其作为预测返回。

但是等等,柳文欢!我们所做的就是建造许多较弱的树,然后取它们的*均值——为什么会这样呢!?

嗯,简单的回答是它非常有效,如果你对统计解释感兴趣,你应该试着多读一些关于随机森林的书。我不太擅长统计学,但我会尝试给出一个基本的解释 bootstrap 采样和特征子集旨在使树尽可能不相关(尽管它们仍然基于相同的数据集和特征集),允许每棵树发现数据中略有不同的关系。这导致它们的*均值比任何单一的树具有更小的方差——更小的过拟合——因此总体上具有更好的泛化和预测能力。

更简单地说,对于一个看不见的观察,每个决策树预测观察结束的叶子的因变量值,这意味着在特定的树空间中最相似的训练集观察的值。正如我们所记得的,每棵树都是根据不同的数据以不同的方式构建的,因此每棵树都会以不同的方式定义相似性,并预测不同的值,因此对于给定的看不见的观察值,所有树的*均值基本上是训练集中与它有些相似的许多观察值的*均值。

此属性的一个结果是,当测试集与训练集有些相似(在相同的值范围内)时,随机森林非常擅长预测,这是通常的情况,但当测试集与训练集在某些基本方面不同(不同的值范围)时,它们在预测方面就很糟糕,例如在时间序列问题中(训练集来自一个时间段,而测试集来自不同的时间段)。

因为在我们的例子中,测试集和训练集具有相同的值范围,所以我们应该可以开始了!

回到比赛

强制预处理

在我们开始随机森林滚动之前,还有最后一件事要做。不幸的是,虽然随机森林理论上能够处理分类特征(非数字,所以是字符串)和缺失数据,但 scikit-learn 实现不支持这两者。现在,我们将使用[pd.interpolate()](https://pandas-docs.github.io/pandas-docs-travis/generated/pandas.DataFrame.interpolate.html#pandas.DataFrame.interpolate)填充缺失值,然后使用[pd.get_dummies()](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)将分类特征转换为数字特征,这使用了一种称为“一键编码”的方案。这个想法很简单——让我们想象一个有 n 个可能值的分类变量。然后,该列被分成 n 个单独的列,每个列对应于一个原始值(本质上相当于 is _ value?对于每一个原始值)。每个观察值之前都有一个分类变量的字符串值,现在在对应于旧字符串值的列中有一个 1 ,在所有其余的列中有一个 0 (这被称为“One-Hot”)。

我们现在准备构建一个模型,使其适合训练数据,使用它在测试集上进行预测,并将预测提交给 Kaggle!

将所有这些放在一起并提交结果

这是将我们的模型预测提交给 Kaggle 所需的全部代码——大约 20 行!我运行了这段代码,然后将结果提交给 ka ggle——分数是 0.14978,目前大约是 63%。5 分钟的编码一点都不差!我们可以在这里看到随机森林的威力。

import pandas as pd
from sklearn.ensemble import RandomForestRegressorPATH = "Oren/Kaggle/Housing Prices/"  #where you put the filesdf_train = pd.read_csv(f'{PATH}train.csv', index_col='Id')
df_test = pd.read_csv(f'{PATH}test.csv', index_col='Id')target = df_train['SalePrice']  #target variabledf_train = df_train.drop('SalePrice', axis=1)df_train['training_set'] = True
df_test['training_set'] = Falsedf_full = pd.concat([df_train, df_test])df_full = df_full.interpolate()
df_full = pd.get_dummies(df_full)df_train = df_full[df_full['training_set']==True]
df_train = df_train.drop('training_set', axis=1)df_test = df_full[df_full['training_set']==False]
df_test = df_test.drop('training_set', axis=1)rf = RandomForestRegressor(n_estimators=100, n_jobs=-1)
rf.fit(df_train, target)preds = rf.predict(df_test)
my_submission = pd.DataFrame({'Id': df_test.index, 'SalePrice': preds})
my_submission.to_csv(f'{PATH}submission.csv', index=False)

说明

在将训练集和测试集加载到单独的数据帧中之后,我保存了目标变量,然后将其从数据帧中删除(因为我想在数据帧中只保留自变量,即特征)。然后,我向训练集和测试集添加了一个新的临时列('training_set'),以区分它们,这样我现在就可以将它们连接起来(将它们放在同一个数据帧中),以后再将它们分开。然后,我继续将它们连接起来,填充缺失的值,并通过一键编码将分类特征转换为数字特征。如前所述,当训练集和测试集具有相似的值时,随机森林(以及一般情况下的大多数算法)工作得更好,因此每当我修改任何东西时,我都会尝试一起修改这两个集。否则,interpolate可能会为训练集和测试集填充不同的值,get_dummies可能会以两种不同的方式对同一分类特征进行编码,这将导致更差的性能。然后,我再次将它们分开,去掉临时列,使用我计算机的所有 CPU 核心(n_jobs=-1)创建一个有 100 棵树的随机森林(一般来说,树越多,结果越好,但训练需要的时间也越多),使用我的训练集拟合它,使用拟合的随机森林预测我的测试集的目标变量,将结果和它们各自的Id放在一个数据帧中,并保存到一个 CSV 文件中。然后我去了 Kaggle 上的比赛页面并提交了 CSV 文件。瞧啊。

下一步是什么?

在接下来的文章中,我们将深入探讨这一竞争,并讨论可视化,这是一种更好的预处理、特征工程、模型验证和超参数调整的方法。作为家庭作业,尝试学习更多关于这些主题的知识,也许阅读一两个 Kaggle 内核,看看你是否可以提高分数并进入前 50%,或者提交你对泰坦尼克号比赛的预测。

推荐资源

  • 文档!熊猫和 Scikit-Learn 都有大量的文档和许多有趣的讨论。
  • 要了解更多关于 Kaggle 成功故事的信息,我推荐 Kaggle 博客,在那里他们经常采访竞赛获胜者,询问他们的方法和途径。
  • 对于数据帧的详细摘要,我推荐查看熊猫-摘要和熊猫-简介。
  • 对于更高级的随机森林用法的精彩解释,我推荐对随机森林的直观解释。
  • 所有相关的 Reddit:r/machine learning, r/learnmachinelearning , r/datascience 。

承认

  • 我要感谢 Udacity 令人难以置信的ML 简介课程,它第一次向我介绍了这个神奇的世界。
  • 我要感谢fast . ai的瑞秋·托马斯和杰瑞米·霍华德教会了我 90%关于机器学习和深度学习的知识。说真的, fast.ai 太神奇了,快去看看吧。除了有趣的博客,他们目前正在免费提供关于深度学习和计算线性代数的顶级 MOOC,不久他们的机器学习 MOOC 也将向公众发布(这一 MOOC 是本文的灵感来源)。如果有人对 ML MOOC 特别感兴趣并且迫不及待,请给我发电子邮件。

机器学习算法:它们如何工作以及每种类型的用例——第一部分,共三部分

原文:https://towardsdatascience.com/machine-learnings-algorithms-how-they-work-and-use-cases-for-each-type-part-i-of-iii-67997c6dda84?source=collection_archive---------6-----------------------

有三种主要类型的机器学习算法:

  1. 监督学习
  2. 无监督学习
  3. 强化学习

在这个系列的第一部分中,我将介绍什么是监督学习算法,它们是如何工作的,以及它们可以应用的几个例子。

什么是监督学习

在监督学习算法中,算法将使用训练数据和来自人类的反馈来学习给定输入集和给定输出之间的关系。

监督学习如何工作

步骤 1:人工标记输入数据并定义输出变量。

步骤 2:然后在数据集上训练算法,以找到输入变量和输出之间的联系。

步骤 3:当算法达到被认为足够的准确率时,训练被认为完成。之后,将该算法应用于新的数据集。

目前,大约有 10 种不同类型的监督学习算法有明确的用例:

请注意:下面定义的用例并不是每种算法的唯一用例。这些示例有助于指导您理解它们的应用领域。

  1. 线性回归 一种标准方法,用于对独立输入变量和非独立输出变量之间的过去关系进行建模,以帮助预测输出变量的未来值。
    用例:
    (一)优化产品级价位。
    (二)估计产品价格弹性。
    (iii)分析产品销售驱动因素,如定价、数量、分销等。

  2. 逻辑回归 与线性回归非常相似,只是输出变量是二元的(真与假),而不是连续的(无限个值)。
    用例: (i)根据银行客户是否会拖欠贷款对其进行分类。(ii)基于一些标准预测皮肤损伤是良性还是恶性。

  3. 线性/二次判别分析 升级逻辑回归处理非线性问题。也就是说,输入变量的变化不会导致输出变量成比例的变化。
    用例:
    (一)预测用户流失。(ii)预测销售线索成交的可能性。

  4. **决策树

    用例: (i)了解消费者在你的网站上的行为,从而导致产品被购买。
    (一)为筛选新的工作候选人提供决策框架。**

  5. AdaBoost
    一种分类或回归技术,使用多种模型做出决策,但根据其预测结果的准确性进行权衡。
    用例:
    (i)检测银行交易中的欺诈活动。
    深度学习是一种更有效的方式来实现这一点,我将在另一篇文章中介绍这一点

  6. 简单的神经网络 模型,其中人工神经元稍后进行输入,一个或多个进行计算的隐藏层,以及一个输出层。
    用例: (一)预测某个产品的某个用户是否会愿意注册该产品的高级版本。
    (ii)预测一个人签订人寿保险单的概率。

  7. 随机森林 分类或回归模型,通过生成多个决策树并对它们进行多数表决来预测输出,该输出是用于分类的连续变量和/或离散变量,从而提高简单决策树的准确性。
    用例: (i)预测餐馆的客流量或人数,以预测人员配备决策。(ii)预测配电网中的用电量。

  8. 支持向量机 一种通常用于分类的技术,但可以转换为执行回归。它尽可能明智地划分了阶级。
    用例: (一)预测某人点击一个在线广告的可能性有多大。
    (ii)预测一家医院在特定时间段内需要服务多少患者

  9. **朴素贝叶斯

    用例: (一)根据分类器将邮件分类为垃圾邮件。
    (ii)基于产品评论分析情感。**

  10. 梯度推进树 顺序生成决策树的分类或回归技术,其中每棵树都专注于纠正先前的树模型。最终输出是所有树的结果的组合。
    用例: (一)预测产品需求和库存。
    (二)根据里程、车龄等预测汽车价格。

在本系列的第二部分中,我将以与本文相同的格式介绍无监督学习算法。

ML 系统的安全概述

原文:https://towardsdatascience.com/machine-learnings-security-layer-an-overview-cfc11841f34e?source=collection_archive---------14-----------------------

这是对机器学习系统安全性的浅显概述。在几个卷轴中,我们将浏览对立的例子,模型盗窃,数据集中毒和数据集保护。

🗡 ️Adversarial 的例子

对立的例子(AE)主题很吸引人,也是一个活跃的研究领域。它提出了与我们当前基于梯度的分类器架构的限制和安全性相关的基本问题。AE 是精心制作的数据,旨在被目标模型错误分类。它们“被设计成使模型出错”( OpenAI ,用对抗性的例子攻击机器学习)。右边的图像是一个对立的例子。

See the complete notebook

最左和最右的狗之间的差异可能是不可感知的。这可能是由于我们的眼睛限制(或您的显示器的位深度)。然而,它们对各种模型都至关重要。最后一个图像实际上是由 Keras 中使用默认训练权重初始化的ResNet50将视为的plane,并且一个 AE 可能会在另一个架构上工作。唯一的区别是小像素值,在第二张图片中放大了。

我们可以注意到ResNet50非常自信地认为左图中的狗是一只golden_retriever (80%),而精心制作的图像是一只可信度更高的`plane`( 99%)。因此,一个模型可能会被欺骗,以我们期望的置信度得分犯错误,我们通常只需要训练它足够长的时间。用任意的置信度分数进行错误分类会有什么影响?

推荐系统也被研究用于对抗性推荐,通过不可辨别的虚假用户影响推荐系统。

安全

在大多数已知的模型中,任何图像都可以被制作成具有任意置信度得分的另一类。所以我们的狗可以被任意准确地错误分类成我们想要的任何东西。事实证明,在现实世界中也是如此,例如,如果我们把它们打印出来。一个著名的例子是欺骗汽车的传感器看到限速而不是停车标志。在某种程度上,模型的输出可以被操纵以做出期望的决策,或者由依赖于它的应用程序生成未处理的行为。

Prediction vs ‘puppeted’ prediction arxiv.org/pdf/1602.02697.pdf (page 3)

到 2017 年底,一些研究表明,在某些情况下,修改一个像素就足够了。如果你想了解更多,你可以阅读论文欺骗深度神经网络的一个像素攻击,欣赏一分钟论文频道的高水*演示或检查这个 Keras 实现。

对抗性的例子是简单的攻击,不需要太多的计算。对于相对较小的图像,一个好的 GPU 可以在不到一分钟的时间内制作一个 AE。这是一个真正的安全问题,这可能是为什么我们可以在一些相关主题论文的末尾看到这些行:

根据合作协议编号 w 911 nf-13–2–0045(ARL 网络安全 CRA 公司),该研究也得到了陆军研究实验室的部分支持,并得到了陆军研究办公室的拨款 w 911 nf-13–1–0421。

不同的威胁级别和技术

我们知道,对立的例子会影响分类器的决策界限。例如,我们可以在图像上添加随机像素,然后改变分类,或者明智地选择那些添加的像素,然后选择分类。根据威胁目标,我们表示:

  • 置信度降低通过降低给定图像的模型置信度来增加类别之间的模糊性。
  • 错误分类将输出类别更改为不同于原始类别的另一个类别。
  • 有针对性的错误分类会强制特定输入的输出成为特定的目标类。

根据对手的知识,有三种方式来设计对抗性的例子。每个人都有自己假定的目标先验知识。了解:

  • 模型整体包括其权重(基于梯度),
  • 只有每个班级的分数(基于分数的),
  • 只有预测(转移型)。

由 Papernot 绘制的简图。在对抗环境中深度学习的局限性(第 3 页)中:

Simplified copy of a diagram by Papernot. et al in The Limitations of Deep Learning in Adversarial Settings (page 3)

基于梯度的攻击的一个例子在于计算图像的损失梯度函数。接着向相反的梯度方向迈一小步。为了保持有效的 RGB 值,图像可能会在 0 到 255 之间被剪切,噪声值在 0 和一个小值 M 之间。这个值 M 决定了原始图像和对手图像之间的最大差异,因此 M 应该小于人类的颜色敏感度(通过监视器)。m 小于 5 应该可以。前一种技术被称为迭代最小可能类方法。存在其他类型的梯度技术,如快速梯度符号方法。你可以阅读这篇论文(第 2 部分,第 3 页)。我们可以注意到,它们都需要完全了解模型及其权重。

基于分数的攻击仅依靠预测模型的分数来估计梯度,然后应用先前的技术。基于传输的攻击完全依赖于输出标签。与基于分数和基于梯度相比,这是一个更真实的场景。您可以在模型盗窃一节中找到基于传输的攻击的示例。

防御

这里我们不会深入探讨,我鼓励你搜索吸引你的关键词,它本身就值得一篇博文。我们可以看到两大类防御:

  • 反应性:目标是一个对抗的例子,在被我们的推理模型调用之前。
  • 主动:目标是让模型更能抵御这种攻击。Nicolas paper not 等人的黑盒攻击。

被动防御的例子:

  • 磁铁由自动编码器组成的“两个网络”模型,能够在送入分类器之前进行重组。这里需要几个自动编码器,所以资源很昂贵。

主动防御的示例:

  • 随机深度符号卷积神经网络
  • 标签*滑(2016)
  • 混搭(2017)
  • 对抗性训练,用对抗性例子的子集重新训练神经网络
  • Logit 配对:这是一个非常新的配对(2018 年),“实现了 ImageNet 上白盒和黑盒攻击的最先进防御”

📡模型盗窃

尝试重建某人的 else 模型或检索用于训练该模型的数据。数据集和/或模型可能因其敏感或商业价值而保密。

模型保密性和公共访问之间的紧张关系激发了我们对模型提取攻击的研究。( 来源 )

我们将简要总结 Nicolas Papernot 等人的黑盒攻击,如果你想深入了解这个主题,你可能会喜欢阅读它。这里描述的主要思想是创建一个用对手制作的替代数据集训练的局部替代神经网络。然后,使用基于梯度的技术,可以产生对立的例子。

不需要带标签的数据集,因为它的制作成本很高。使用远程 DNN 的输出来标注替代数据集。然后,通过一种称为基于雅可比矩阵的数据集扩充的技术对本地数据集进行局部扩充。以下是描述雅可比数据扩充的伪代码(完整代码可从 github 获得)。

def jacobian_augmentation(dataset): 
  """ 
  - get_label: API call on the remote oracle 
  - alpha: step size 
  - jacobian: returns jacobian matrix of the substitute model 
  """ 
  jacobian_dataset = [] 
  for sample in dataset: 
    label = get_label(sample) 
    jacobian_sample = sample + alpha*sign(jacobian(substitute_model,label)) 
    jacobian_dataset.append(jacobian_sample) 
  return jacobian_dataset

基本上,每个例子都是通过在渐变方向上增加一个小的变化来增强的。

他们强调:

[…]该技术不是为了最大化替代 DNN 的准确性而设计的,而是为了确保它用很少的标签查询来逼* oracle 的决策边界。

架构的选择不是很重要,因为我们可以预先假设一些细节。CNN 很有可能被用于图像分类任务。也可以同时训练几个架构。

在 Github 上有一个类似攻击的实现。

💊数据集中毒

数据集中毒攻击的目的是在测试时操纵模型的行为。

毒害 3%的训练集设法降低了 11%的测试准确度。(2017)).

标签翻转攻击目标是最大化损失函数,如果训练样本的标签的子集被翻转,这基本上通过梯度上升来完成:

Ali Shafahi et al. 2018 (Figure 1-b)

攻击者首先从测试集中选择目标实例;成功的中毒攻击会导致此目标示例在测试期间被错误分类。接下来,攻击者从基类中抽样一个基实例,并对其进行难以察觉的更改以创建一个中毒实例;这种毒害被注入到训练数据中,目的是欺骗模型在测试时用基本标签标记目标实例。最后,在中毒数据集(干净数据集+中毒实例)上训练模型。如果在测试期间,模型将目标实例错误地认为在基类中,则中毒攻击被认为是成功的。 毒蛙!针对神经网络 的干净标签中毒攻击

🔑数据集保护

完全同态加密

Fast Homomorphic Evaluation of Deep Discretized Neural Networks eprint.iacr.org/2017/1114.pdf (page 25)

全同态加密是一种通过加解密功能保留对数据操作的加密方案。如果在相加过程中保留该方案,则对总和加密或对加密成员求和将得到相同的结果。这意味着,您可以在本地加密数据并将其发送到服务器,让它仅使用受支持的操作符来执行某项工作,并返回加密结果。你不需要信任服务器,因为它不会理解自己在操纵什么。

ENCDEC分别实现加密和解密功能:

ENC(X1 + X2) = ENC(X1) + ENC(X2) (homomorphism) 
Since X1 + X2 = DEC(ENC(X1+ X2)) 
We have X1 + X2 = DEC(ENC(X1) + ENC(X2))

如果在这个领域你需要追随一个人,那就是克雷格·金特里。他在 2009 年创立了第一个 FHE 计划。

克雷格*期的很多工作,包括《FHE》和《加密多线性地图》,都属于“基于点阵的加密”领域。与 RSA 和椭圆曲线密码等常用的密码体制不同,基于点阵的密码体制不可能(就我们所知)被量子计算机破解。IBM)

这里最重要的部分是,如果有一天这种加密方案存在,我们可以(几乎)不关心我们在远程机器上发送的数据的隐私。如果这台机器是恶意的,它只能给你错误的结果,但不能利用你的数据…除非…如果我们正在谈论一个 FH 加密的机器学习模型试图预测一些东西,没有什么可以保证你的模型一开始是空的,你的对手仍然可以对年轻的模型进行推理(通过观察边界决策等)。你应该看看 CryptoDL 。

数据集盗窃

也可以通过简单地查看模型的输出来恢复训练时使用的数据,针对机器学习模型的成员推理攻击:

给定一个数据记录和对模型的黑盒访问,确定该记录是否在模型的训练数据集中。为了对目标模型执行成员关系推断,我们对抗性地使用机器学习并训练我们自己的推断模型,以识别目标模型对其训练的输入和未训练的输入的预测的差异。

在这里可以找到一个实现。

最初发表于data-soup.github.io/blog/

机器推理:区别特征

原文:https://towardsdatascience.com/machine-reasoning-distinguishing-features-beff5159d957?source=collection_archive---------2-----------------------

辨别事物特征的能力是学习和推理的一个基本方面。鸟有翅膀,汽车有轮子,等等…

“区分”意味着这些特征在描述和分类事物时是有用的。

by Piyushgiri Revagar

在“机器学习的基本模型中,我们用符号模式观察了机器推理,并开始探索区别特征的概念。这是一个起点。我们在这里进一步探索更复杂形式的区别特征。

print(r . distincting(' ABC ')
print(r . distincting(' ABC ',relation='is not '))

[['a'], ['a', 'b'], ['a', 'b', 'c'], ['b'], ['b', 'c'], ['c']]
[['x'], ['x', 'y'], ['y'], ['n']]

我们可以很容易地将它缩小到特征集中最大的掩码:

print(top _ mask(r . distinguished(' ABC '))
print(top _ mask(r . distinguished(' ABC ',relation='is not '))

['a', 'b', 'c']
['x', 'y']

属性‘ABC’的模式确实具有模式‘a b c’,而那些不是‘ABC’的模式具有模式‘x y’。给定提供的模式,这些是事物的区别特征。

一旦你确定了一个新模式的显著特征,确定它是否是一个事物就相对简单了:

s0 = Symbolic(' u o I a b c ')
r . determine(s0,' a b c ')

(True, 'has distinguishing features')

神经网络呢

这与分类中使用的典型人工神经网络相比如何?分类是决定一个输入是否是一个东西的工作,所以这是一个恰当的比较。

在“7 行代码中的深度学习”中,我们使用 Tensorflow 和 tflearn 对几个模式进行了分类,让我们重温一下这个并运行一些实验。

这里是代码,我们将输入以下模式:

features.append([[0, 1, 9, 3, 6], [0,1]])
features.append([[0, 1, 7, 4, 2], [0,1]])
features.append([[0, 1, 5, 0, 9], [0,1]])
features.append([[1, 0, 4, 6, 7], [1,0]])
features.append([[1, 0, 3, 7, 8], [1,0]])

可以看到,符号模式 [0,1] 对应于类[0,1],模式 [1,0] 对应于类[1,0]。让我们尝试对新数据进行分类:

[[0.967603862285614, 0.0323960967361927]]       **# wrong!**
[[0.6647899746894836, 0.33520999550819397]]
[[0.12406770884990692, 0.8759322762489319]]
[[0.9999886751174927, 1.133059231506195e-05]]   **# unclear**
[[0.9999721050262451, 2.794429565255996e-05]]   **# unclear**
[[0.9997043013572693, 0.00029572920175269246]]  **# wrong!**

当符号与训练数据 T26 对齐时,我们的 Tensorflow 2 层神经网络 T25 表现相当好(使用小数据),但在第一次测试数据中[非常]不正确。它非常确信模式[0,1,0,6,2]没有被归类为[0,1],但它被归类为[0,1]。在缺少任何一类区别特征的输入上,它产生了不合理的高概率,并且在最后一个模式上,它错过了偏移区别特征。给定足够的训练数据,卷积网络应该可以克服符号偏移问题——这是另一项实验的成果。

让我们看看我们的符号库是如何对相同的数据进行推理的。笔记本这里是这里是。我们将把相同的模式添加到我们的 Reason 类中,并向它询问区别特征。

0.95668 secs{'is': **[('0', ['_0']), ('1', ['_1'])]**, 
 'is not': **[('1', ['_0']), ('0', ['_1'])]**}

它推理出[0,1]和[1,0]是存在和不存在事物‘foo’的区别特征,并完成了确定先前未见过的模式的简短工作:

(True, 'has distinguishing features')

我们的神经网络不仅弄错了这种模式,它也没有告诉我们为什么对它进行了错误的分类。这是一个关键点——机器决定,特别是在中,推理的过程应该是可解释的(内省的)。有人可能会说,所谓的“T8”快速思考“T9”决策通常是不可解释的,但“T10”不同于“T11”。

将 CNN(卷积)结构应用于这些模式需要更多的实验,然而这将需要更多的训练数据。这是另一个重点——从小数据学习和’一次性学习。

正如在概述中提到的,我们希望能够应用自适应学习。我们需要我们的系统在推理的时候学习,纠正和强化输入。我们需要我们的模型不断发展,而不必随着每个新的输入而重建。

这些推理的特性存在于幼儿和动物的学习过程中。他们在场是因为你今天学到了一些新东西。

与众不同的特征或挑战

通常情况下,一个事物具有一组具有或关系的区别特征,而不是和关系。

东西(a)是一辆汽车——它有一个汽油发动机

东西(b)是一辆汽车——它有一个方向盘和一个汽油发动机

东西(c)是一辆汽车——它有方向盘、挡风玻璃和电动引擎

我们可以推理出“汽车”有方向盘、挡风玻璃和汽油发动机或电动发动机。这个区别特征在‘车’的判定上有或关系。

事实证明,这是一个很难解决的问题。先用我们的神经网络做实验,笔记本这里是这里是。

我们首先定义我们的训练数据,我们将[0,1]和[1,0]模式组合到同一个[0,1]类中,以区分每一个的方式为另一个类提供训练数据。

请注意,类[1,0]的训练示例缺乏显著特征。接下来,我们尝试对新模式进行分类:

[[0.14985743165016174, 0.8501425385475159]]
[[0.0002913394710049033, 0.9997085928916931]]
[[0.6994397640228271, 0.30056023597717285]]      **# wrong**
[[1.0, 1.7667502999322605e-14]]
[[0.15181590616703033, 0.8481840491294861]]      **# wrong**
[[0.019126782193779945, 0.980873167514801]]      **# wrong!**

毫不奇怪,我们的 Tensorflow ANN 不知道[0,1]或[1,0]特征。在最后一次输入中,它对不正确的分类有很高的可信度(可能是因为 0 的存在,但是也不能解释为什么会这样推理。

https://upload.wikimedia.org/wikipedia/commons/e/e8/Juliadim2.png

集合论继续…

在我们的符号库中,我们再次使用集合论,这次是为了确定区别特征的或组合。

我们通过计算模式列表(对于一个属性)的不连续子集的集合,并计算每个子集的区别特征来达到子集的最佳组合。“最佳”是指我们在子集中寻找与其他特征相比最大/最全面的区别特征集合。

生成非连续列表子集的递归函数如下:

例如:

[0, 1] [2, 3, 4]
[0, 2] [1, 3, 4]
[0, 3] [1, 2, 4]
[0, 4] [1, 2, 3]
[1, 2] [0, 3, 4]
[1, 3] [0, 2, 4]
[1, 4] [0, 2, 3]
[2, 1] [0, 3, 4]
...

系列中不连续子集的数量产生了一个雄心勃勃的系列:

2, 3, 10, 15, 41, 63, 162, 255, 637, 1023, 2509, 4095, 9907, 16383, 39202, 65535, 155381, 262143, 616665, 1048575, 2449867, 4194303, 9740685, 16777215, 38754731, 67108863, 154276027, 268435455, 614429671, 1073741823, 2448023842, 4294967295

升级速度相当快。更多关于这个系列的信息可以在这里找到。

回到我们的符号库示例,我们再次提供模式,与之前的运行相同。

1.2334489999999931 secs{'is': [['0'], ['1']], 'is not': None}

它推理出符号[0]和[1]是有区别的特征,这是正确的,然而它需要进一步推理以理解[0,1]或[1,0]是有区别的。为此,我们将使用另一个函数:

r . distinguisingor(' foo ')

16.00546700000001 secs**([('1', ['_0']), ('0', ['_1'])], 
 [('0', ['_0']), ('1', ['_1'])])**

它正确地推理出属性‘foo’中这些模式的区别特征是【1,0】【0,1】,在这种情况下,它们的位置(偏移)也被记录,然而这对于特征的识别是次要的。

不像我们的神经网络,每个输入的位置是关键的,使用这种方法区别特征的相对位置并不重要,例如(在模式前添加随机填充):

{'is': **[['1'], ['0']]**, 'is not': None}

和我们的 OR 函数(带调试):

dis1,dis 2 = r . distinguisingor(' foo ',debug=True)
top_mask(dis1),top_mask(dis2)

31.367725 secs
**0** [('6', ['_0']), ('1', ['_1']), ('0', ['_2']), ('4', ['_3']), ('6', ['_4']), ('7', ['_5'])]
**1** [('8', ['_0']), ('9', ['_1']), ('1', ['_2']), ('1', ['_3']), ('0', ['_4'])]
**2** [('7', ['_0']), ('8', ['_1']), ('0', ['_2']), ('1', ['_3']), ('9', ['_4']), ('3', ['_5']), ('6', ['_6'])]
**3** [('4', ['_0']), ('0', ['_1']), ('1', ['_2']), ('7', ['_3']), ('4', ['_4']), ('2', ['_5'])]
**4** [('2', ['_0']), ('9', ['_1']), ('0', ['_2']), ('1', ['_3']), ('5', ['_4'])]
[0, 1] -> [['1'], ['1'], **['1', '0']**, ['0']]
[2, 3, 4] -> [['0'], **['0', '1']**, ['1']](**['1', '0']**, **['0', '1']**)

简介:在与事物“foo”相关联的 5 个模式中,在所有不连续的子集(最小长度为 2)中,模式组[0,1]和[2,3,4] 产生最大的区别特征集合

换句话说:事物‘foo’的这些子群彼此有最多的共同点,它们的共性由它们的区别性特征来表示。这些是事物的或特征。

https://upload.wikimedia.org/wikipedia/commons/b/b3/Mandel_zoom_07_satellite.jpg

思考绩效

你可能已经注意到在一些例子中显示的运行时间,这是有意包含的。

31.367725 secs

对一个有 5 个图案的东西的区别特征进行推理,每个图案有 5-7 个符号,需要大约 30 秒,这对于计算来说是永恒的。集合论计算的本质是,模式数量或大小的增加将对性能产生非线性影响

让我们快速看一下 10 种模式的不连续子集的数量(最小子集长度为 2):

10770

10,770 个可能的子集中的每一个都需要计算一组区别特征,这本身就涉及额外的集合论工作。

首先让机器运转起来,然后进行优化。

我们在进行实验时遵循这一法则,优化和提高性能的潜力总是存在的,我们首先想了解如何根据模式和表面基本概念进行推理。

这里有几种优化方法:

  • ipython 笔记本相对较慢,但对实验很有帮助,它不是一个性能环境
  • 消除冗余的非连续子集有简单的方法,例如[0,2] [1,3,4]与[1,3,4] [0,2]是冗余的
  • 有一些方法可以避免对子集的整个分支进行计算,例如,如果子集[0,2] 没有产生有意义的区别特征,那么它的所有超集([0,2,1],[0,2,5],[0,2,8]等等。)可以忽略
  • 进程有利于并行化,没有理由为什么单独的线程/进程可以通过不同的集合组工作

直到下一次…

莎士比亚英语的机器翻译

原文:https://towardsdatascience.com/machine-translation-to-shakespearian-english-189c8690b252?source=collection_archive---------4-----------------------

写作风格转换的尝试

背景

如果你一直在关注深度学习的最新发展,你可能会遇到 艺术 风格转移 这是一种使用图像 A 的内容,以图像 b 的风格创建新图像的技术。例如,下面是从康定斯基的一幅画到尼尔·德格拉斯·泰森的一张照片的风格转换结果。

Source: https://research.googleblog.com/2016/02/exploring-intersection-of-art-and.html

深度学习在转移言语风格方面也取得了成功。给定一个一分钟的某人说话的音频剪辑, Lyrebird 能够捕捉到那个人的说话风格,并通过模仿他的声音让他说任何话。

动机

我很好奇风格转移是否也适用于书面文字。这个想法是将英语句子打扮成不同作者的风格,无论是华丽的诗歌还是生硬的散文,同时保留其意义。互联网搜索没有找到任何方法,但我发现我可以让神经机器翻译(NMT)适应我的目的。

我不是在两种不同的语言之间翻译,而是训练一个神经网络从现代英语翻译成莎士比亚的英语。训练数据是莎士比亚的戏剧和在 sparknotes.com 和 enotes.com 可以得到的相应的现代英语翻译。

结果

我把这个翻译应用到泰勒·斯威夫特的新歌《看你让我做了什么》标题翻译过来就是“你让我做了什么?”这是古老的莎士比亚风格,忠实地保留了原来的意思。这是这首流行歌曲完整的第一节和翻译。

Song lyrics                        | Shakespeare translation I do not like your little games.   | i do not like your little dry .
Do not like your tilted stage.     | do not like thy mind .                          
The role you made me play.         | the offence you made me .     
Of the fool, no, I do not like you.| no , no , i am not like you .                   I don't like your perfect crime.   | i do so much as thou art .                      
How you laugh when you lie.        | how thou dost lie .                 
You said the gun was mine.         | you say the seas was mine .                     
Isn't cool, no, I don't like you.  | no cool , no , i protest you .
Oh, look what you made me do       | o , look you , look you , what                              >                                    you make me do ?
Look what you made me do           | what thou hast made me do ? 

方法

谷歌研究博客 5 个月前发表了一篇文章介绍了一个教程,展示了如何在 Tensorflow 中构建一个高质量的翻译模型。用他们的话说,

本教程旨在使这个过程尽可能简单,从 NMT 的一些背景知识开始,通过代码细节来构建一个普通的系统。然后深入到注意力机制[3,4],这是让 NMT 系统处理长句的一个关键因素。最后,本教程详细介绍了如何复制谷歌 NMT (GNMT)系统[5]中的关键特性,以便在多个 GPU 上进行训练。

谷歌兑现了自己的承诺,提供了一个易于理解的教程。假设您有硬件,只需执行几个 python 脚本就可以得到翻译模型。使用它们的默认值,我训练的翻译模型是一个 2 层 LSTM seq2seq 模型,具有 128 维隐藏单元、丢失和注意机制。以下是我从解释 NMT 如何工作这一节中得到的关键信息。

  1. 他们的方法是将整个句子作为一个翻译单位。这与基于短语的翻译不同,基于短语的翻译将句子拆分成短语并独立翻译。因为它考虑整个句子,所以它可以在具有长期依赖性的部分上表现得更好,比如性别一致。
  2. 他们使用编码器-解码器架构。在编码步骤中,网络构建了一个“思维向量”,它将源语言中的单词编码成句子的意思。在解码步骤中,“思维向量”被一次一个单词地投射到目标语言。递归神经网络(RNN)用于编码器和解码器,这是顺序数据的自然选择。

Encoder and decoder RNNs. marks the boundary between encoding and decoding. Source: https://github.com/tensorflow/nmt

3.如果你认为上面的图表有太多的箭头,你并不孤单。对于长句来说更糟,单一固定大小的隐藏状态成为信息瓶颈,性能受到影响。一种解决方法是使用注意机制在目标单词和源单词之间建立直接的快捷连接。注意力通过编码的源向量上的加权分布来捕捉,该加权分布指示与目标单词的相关性。

Attention mechanism. Source: https://github.com/tensorflow/nmt

结论

莎士比亚的译者远非完美,但如果数据可用,这是一个潜在的写作风格转换的途径。它需要用两种不同的写作风格来表达相同内容的两个语料库,这是对可用风格数量的一个主要限制。真正的写作风格转变的过程从来都不是一帆风顺的。

神奇的虫子和在哪里可以找到它们

原文:https://towardsdatascience.com/magical-bugs-and-where-to-find-them-3177a066a3db?source=collection_archive---------5-----------------------

作者加博尔·巴科斯

Magical bugs and where to find them

每个人都想尽可能快。开发功能,然后立即发货,同时获得反馈,收集发现并改进一切。我们 Skyscanner 的移动开发团队也喜欢这样操作,但正如林哥·斯塔尔曾经唱过的,“你知道这来之不易。”

我们的代码库正在快速增长(现在没有外部依赖的 iOS 代码为 496,682 行,没有 XML 的 Android 代码为 526,076 行)。而且,我相信你知道,更大的代码库不支持快速迭代。因此,我们的发布周期变得更慢,并且在从开发分支中分离出来之后,需要花费更多的时间来创建稳定的发布候选版本

寻找解决方案

有两种可能的方法来构建静态代码分析系统。

  1. 被动方式:当你在收集信息,然后试图根据你的发现采取行动。然而,这是一种特别的方法,因为它只是简单地分析项目,所以并不总是完全完整的。作为一种提供系统概述的方式,这是很有用的,但是如果有太多的问题或者项目太大,数据可能是压倒性的,并且最终是无用的。
  2. 主动方式:当你故意寻找问题时,如果有任何违反,你就破坏了这种构建。但是它必须集成到构建过程中,否则开发人员可能会忽略它。例如,如果在创建拉请求的集成期间出现问题,那就太晚了。给出一个清晰而直接的信号是至关重要的。

在理想情况下,这两种方法可以而且应该共存。换句话说,扫描整体健康状况,如果有违规,就中断构建。我们尝试这样做,首先扫描,然后分析项目,但最终有太多的问题,我们无法制定行动要点。甚至不知道从哪里开始,所以我们放弃了这种方法,采用了一种主动的静态代码分析系统。你可以在下面找到主动方法的确切流程。

Flow of the active approach we took

首先,我们只关注 iOS 和 Objective C。我们从 OCLint 等可用选项中选择 Clang 作为我们的框架,因为这是编译器,它已经指出了开箱即用的问题。Clang 带有一个广泛的诊断框架,并有一个广泛的警告标志列表。为了利用这一点,需要为项目修改编译器标志。有一个预定义的警告集已经打开,但我们可以启用新的警告或警告组,最终我们可以将这些警告升级为错误。

修复我们自己的域是范围,所以我们排除了第三方库,只关注我们的内部组件,导致 43 个模块需要配置相同的规则集。我们创建了一个简单的脚本来修改 xcconfig 文件中的“Other C Flags”部分,用于那些模块的目标配置,以及我们希望提升为错误的相关警告数组。如果需要手动更改,可以在 Xcode 的 Targets/Build Settings/Other C Flags 路径中找到它。有了这种方法,开发人员可以专注于错误标记,而不必知道脚本是如何工作的。每个错误应该看起来像下面的模式-Werror= 。所以这些字符串需要添加到配置中。从技术上讲,我们迭代相关的构建目标,并以编程方式将构建的警告标志添加到构建配置中。使用这种方法,Xcode 项目文件在目标和模块之间是一致的。

执行

正如我已经提到的,我们在应用程序中有超过 9000 个警告,当我们启用“每个警告都是错误”标志(-Wall)时,结果是压倒性的。显然,我们无法处理这么多的错误。所以我们创建了一个编译器已经指出的警告列表——这是我们要整理的第一组规则。比如 Clang deprecated-declarations 警告,它指出 Objective-C 方法声明中的 C 样式参数是不推荐使用的。或者 Android ObsoleteLayoutParam,如果给定的 layout_param 不是为给定的布局定义的,则表明该问题,这意味着它不起作用。

五个团队自愿修复所有这些问题,所以我们每周组织一次警告消除会议,每个团队一个人参加四个小时。这段时间过程变化很大。我们挑选了 2-3 个错误,并逐一启用和修复它们。显然,在有些情况下,修复不是一个选项,所以在这些情况下,我们抑制了错误,但这是我们采取的最后一个选项。最大的问题是修复之前修复的问题,以阻止多米诺骨牌效应。

这里我想强调一下反馈回路的重要性。我们尝试了各种错误可视化的方法,比如只签入一种构建类型,或者只在 CI 时间签入,或者在特定的构建时间签入特定的规则集。最终,在构建时启用的所有东西都赢了,因为开发人员及时收到了反馈,而且一点也不麻烦(尽管我们认为可能会有麻烦)。此外,在开发期间检查代码是不够的。在 CI 期间也必须对其进行检查。我们很幸运在编译器中内置了诊断系统——两者都是免费的——但是 CI 时间错误可视化需要一个工具。为此,我们使用了 Danger 插件,这是一个非常棒的工具,可以在创建合并请求时自动执行各种操作。从技术上讲,我们创建了一个关于编译器错误的日志,然后 Danger 对它进行解析,并发回一条关于构建健康的消息,因此我们能够将合并请求中存在的问题作为一条注释来查看。

一旦我们在 iOS 上实现了坚如磐石的框架,我们就转向了我们的 Android 应用。幸运的是,Android 自带了一个简单的静态代码分析工具,叫做 Android Lint。它是开发工具链的一部分,可以作为命令行工具使用,也集成在 Android Studio 中。基本上有一个 lint.xml,您可以在其中修改问题的严重性,您需要做的只是从 gradle 构建脚本启动 lint 检查器。

该工具会生成一份非常详细的报告,说明问题是什么、在哪里找到问题以及问题的严重性。由于描述和元数据非常清晰地阐明了问题,问题的分析变得更快更容易。此外,由于存在问题优先级,所以更容易知道先解决什么,然后再解决什么。可以计算一个警告熵,并配置构建脚本在这个熵变得更高时停止。有了这个功能,最终有可能自然地消除每一个警告。然而,由于我们侧重于主动警告删除,因为我们不需要这个功能。

Hradware ID Usage

未来计划

经过六周的努力,我们启用了 54 个错误警告标志,涵盖了我们所有的 9000 个 Objective-C 编译器警告。因为这是多个团队的努力,对公司文化也有影响。开发人员开始为新发现的问题添加标记,并自己修复这些问题。最初,修复缺陷和重构代码并不是一项受欢迎的任务。例如,有一种情况是,需要对一个模块进行完全重组。所以我们意识到保持团队精神对系统本身同样重要。我们不仅试图促进进展,还试图充分参与每一次迭代。

对于 Android,我们遵循之前的流程。因此,我们创建了一个问题列表,然后将它们一个接一个地提升到错误级别,然后修复它们。项目中的默认警告要少得多,因此我们在 5 周内修复了 1658 个警告,这导致了 52 个问题类型的使用。Android Studio 使用自己的 lint 规则集,可以单独配置。让这些 linters 相互同步是很重要的,以便在开发时而不仅仅是构建时看到新的规则集。

从我们之前的十二个版本中,有五个按时结束了;它们在预定的一周内推出。有了静态代码分析支持的一些过程变更,六个中有五个是准时的,所以我们的发布时间改进了很多,因为稳定期的问题减少了很多。

我们不会就此止步。我们计划在系统中添加新的标志,我们打算删除剩余的非客观警告,并达到零状态。一旦我们到达那里,我们将试验“零警告策略”,即没有拉请求可以与错误旁边的警告合并。也有其他工具可以试验,比如从脸书推断。更不用说符号执行是一个有待发现的广阔的新领域。o 我们将继续我们的旅程,找到那些讨厌的缺陷,使我们的应用程序更容易和更安全。

我们对未来寄予厚望。

喜欢你听到的吗?与我们合作

我们在 Skyscanner 以不同的方式做事,我们正在全球办事处寻找更多的工程团队成员。看看我们的 Skyscanner 职位寻找更多空缺。

关于作者

我叫 Gabor Bakos,是一名移动开发人员,在布达佩斯的应用支持团队工作。我们试图让我们的开发人员的生活更容易,代码质量是我多年来一直关注的一个领域。工作之外,我是一个真正喜欢游戏的 Crossfit 爱好者,也是我 3 岁的 sheltie Merlin 的理想训狗师。

Gabor Bakos

喜鹊数据科学

原文:https://towardsdatascience.com/magpie-data-science-6cde66b95dde?source=collection_archive---------2-----------------------

This behaviour may be a stereotype for magpies, but it’s often observed in humans.

避免被下一个闪亮的东西分心

有一天,当我在办公室的小厨房里煮咖啡时,无意中听到一位同事抱怨一位离职的经理。我的同事说,他只是那些喜鹊经理中的一员。他的语气清楚地表明,做一名“喜鹊经理”即使没有做哈维·韦恩斯坦那么糟糕,也肯定是不可取的。

“喜鹊总管是什么?”我问。

你知道喜鹊是什么吗?“一种用闪亮的东西填满鸟巢的鸟——喜鹊经理是人类的版本。”

这似乎很适合他的描述——一件刚来时受到广泛称赞的办公设备,但现在却闲置着,因为人们又回到了以前使用的状态。可能我们大多数人都有类似的经历,经理们根据看起来最闪亮的东西而不是最有用的东西来做出购买决定。虽然喜鹊不一定是这种行为的罪魁祸首,但很多人肯定是。

在数据科学中,当人们开始采用最新的包或工具时,同样的事情也会发生,只是因为它是最新的或带有最光滑的 UI,而不是因为它解决了一个需要解决的问题。

不幸的是,虽然可能有数据科学以外的经理在几乎没有进步的死水中工作,并且很少关注新的发展,避免受到最新和最闪亮的诱惑,但这对数据科学家来说绝对不是真的。相反,这是生活中的事实,数据科学家需要保持对事物的掌控,保持对新技术的了解。

与此同时,随着如此多的新工具和技术不断被发现和公开,很容易迷失方向。花上几个小时学习新工具独特的语法,就可以很容易地利用醒着的每一分钟来寻找最新最棒的方法,将算法速度提高几毫秒。决定哪些新技术和工具真正值得注意要困难得多。

一个直观的决定方式是寿命。虽然我们谈论的是相对较新的工具和技术,但这并不意味着我们需要在一切可用时立即行动——有机会让其他人先检查一下,看看哪些比其他人更有价值。

虽然人们认为数据科学是一个新的职业,但实际上它所包含的活动通常已经存在了至少十年——甚至深度学习算法在 2000 年代中期才开始在工业应用中获得成功。因此,许多解决特定问题的最成功的方法总是显而易见的。

另一件要做的重要的事情是考虑你投资学习一个新的软件包能得到什么回报。如果仅仅是用稍微华丽一点的界面就能做你已经能做的事情,也许好处并不值得花费。另一方面,如果你深入研究像 R 中的 ggplot2 这样的东西,你不仅仅会得到一种处理老问题的不同方法,你还会学到一种如何可视化数据的不同哲学。

没有时间去学习每一个新的软件包,或者每一项新的技术。一个聪明的数据科学家需要学会识别他们的时间用在哪里是最好的。闪亮不是一个足够好的理由来证明放弃你的时间。

在 leanpub 查看罗伯特德格拉夫正在编写的电子书,t。

专业钱:测试薪资信息对大学专业选择的影响

原文:https://towardsdatascience.com/major-money-testing-the-impact-of-salary-information-on-college-major-selection-8f8deb20ef84?source=collection_archive---------5-----------------------

作者:伊莱·比尔德纳、埃里克·奥利夫、帕拉克·昆杜和瑞安·霍兰德

注:本文描述了斯坦福大学商学院 【实践中的影响衡量】 课程中的一项实验。您可以在这里 找到我们完整的项目数据、项目代码和 R Markdown 输出

都是关于专业的

这些天有很多关于飙升的大学工资溢价的谈论。根据布鲁金斯学会(Brookings Institution)汉密尔顿项目(Hamilton Project)的数据,高中毕业生职业生涯的*均收入为 58 万美元,而学士学位持有者的*均收入是这个数字的两倍多,为 120 万美元。麻省理工学院(MIT)经济学家大卫·奥特(David Autor)的另一项研究发现,美国男性的*均学士学位成本(扣除学费和放弃的工资)为负 59 万美元(T21 为负 30 美元)《纽约时报》记者大卫·莱恩哈特在报道奥托尔的研究时表达得很好:“是的,大学是值得的,而且还差得远呢。”

但是当谈到大学工资溢价时,*均工资掩盖了大量的差异。选择上大学是一个重大的经济决定;事实证明,选择大学专业是一个更大的问题。主修石油工程,你的*均工资是 11 万美元。主修幼儿教育,你的*均收入只有 28,000 美元。

如果选择专业“比决定是否上大学更重要”,正如乔治敦教育和劳动力中心的报告所言,为什么没有更多的学生选择像机械工程(60,000 美元)、计算机科学(83,000 美元)或应用数学(同样是 83,000 美元)这样非常赚钱的项目呢?

作为商学院的学生(因此也是高等教育的“超级用户”——不管是好是坏),我们对这个问题的答案很好奇。所以我们决定设计一个实验。

实验:提供薪资信息会影响学生的专业偏好吗?

有一种假设——在 T2 的几项 T4 研究中得到支持——认为大学在教育学生选择专业方面做得很差。所以有一个问题:如果学生们更多地了解与不同学习课程相关的*均工资,这会影响他们的专业偏好吗?

为了验证这一点,我们在斯坦福大学校园里设计并实施了一项随机实验。因为我们无法接触到一群统一的一年级学生(他们还没有选择专业),所以我们起草了一份调查,询问斯坦福大学的本科生向新入学的同学推荐四个专业——计算机科学、经济学、人类生物学和历史——的可能性有多大。(这四个专业是斯坦福大学最受欢迎的专业之一。)

为了检验我们的假设,我们准备了两个版本的调查。在第一个版本(我们的“控制”)中,我们向学生提供了一个简单的表格,报告(编造的)主要难度和满意度水*,以及(实际)授予的学位数量和所需的总单元数。(我们编造了难度和满意度的数字,这样就不会有一个专业主导所有标准——从而鼓励受访者考虑权衡。)在调查的第二个版本(我们的“处理”)中,我们提供了所有相同的信息——只是增加了一个额外的列,传达了每个专业第一年的*均(*似真实)工资数字。

Survey table: “Control” group

Survey table: “Treatment” group

在两个版本的调查中,我们都问到:“想象一下,一个即将入学的斯坦福学生向你咨询选择哪个专业。你会怎么给这四个专业排名?”作为补充说明,值得一提的是,我们没有要求学生对专业进行“评级”(比如,从 0 到 10),而是要求他们强制排名。我们这样做是为了鼓励受访者仔细考虑权衡,并避免评分者之间的可靠性问题(例如,约翰的“3”与丽莎的“3”相同吗?)

数据收集:这一切都与权力有关(和不知情的斯坦福学生搭讪)

在收集数据之前,我们首先问了一个更基本的问题:我们需要多少调查反馈?用更专业的术语来说,这个问题问的是功率,或者我们的实验能够让我们检测到治疗效果的概率——如果这种效果存在的话。虽然有太多的在线工具和统计软件包来帮助计算所需的功率,但我们转向了一种更手动的技术——一种我们在课堂上学到的技术。

在这种技术中,我们从生成样本(虚拟的)数据开始——在我们的例子中,只是一个主要排名的列表(实验“结果”)。然后,我们将样本数据的行随机分配为“治疗”或“对照”,然后通过从治疗行的*均等级中减去对照行的*均等级(结果)来计算“*均治疗效果”(或 ate)。

通过重复这一过程数千次,我们最终得到了这些(随机)比率的分布。请注意,该分布以零为中心,因为我们样本数据中的“治疗”完全是随机的,所以没有(真实的)*均治疗效果:

最后一步,我们预测我们期望看到的(真实的)治疗效果——或者更确切地说,我们希望检测到的效果。(在我们的例子中,我们预测了 0.2 个排名点的影响。)通过计算这个(预测的)实际 ATE 位于随机分布内的概率,我们得到 p 值。如果这个 p 值低于 0.05(表明在 95%置信水*下的统计显著性),我们的实验应该(或多或少)足够有力。

Random distribution with n = 400 and p-value ≈ 0.036.

使用这一程序,我们确定我们需要大约 400 名学生的样本量来获得具有统计学意义的结果(同样,假设效果大小为 0.2 个排名点)。不幸的是,考虑到项目的时间限制(以及我们需要从商学院毕业),与 400 名斯坦福大学本科生搭讪似乎不是特别可行。幸运的是,测量影响大卫·布鲁克曼教授同情我们,要求我们简单地收集 60 个数据点(每个治疗组 30 个)。至少,这似乎是一个合理的起点(尽管我们需要看到更接* 0.5 个排名点的效果才能在这个样本量上达到显著性)。

大约一个星期后,在学生会和体育馆外(礼貌地)追捕本科生后,我们得到了 60 份调查回复(30 份控制回复和 30 份治疗回复,都是在 Random.org的随机数生成器的帮助下随机分配的)。

Good clean fun.

随机检查:寻找无意义

在考虑我们的待遇(显示工资信息)可能对我们的结果(主要偏好)产生的任何影响之前,我们首先进行了一项随机检查。

简而言之,随机化检查是一种工具,用于验证我们的随机化过程——将受试者分配到治疗组或对照组——是否有效。为了方便起见,我们已经收集了(作为调查的一部分)关于我们实验对象的额外信息——特别是关于他们的性别、斯坦福学年、所选专业和家庭收入的信息。然后,我们对这些协变量(可能预测研究结果的变量)在我们的治疗分配上进行回归,看是否有任何这样的协变量对治疗组有预测作用。如果我们的协变量可以预测治疗组成员,这将告诉我们我们的随机化失败了。虽然我们确实看到了一个协变量(性别)的轻微显著性,但回归的总体 p 值(p = 0.1691)并不显著:

数据分析:回归时间到了

随着我们的随机化验证,我们准备好挖掘数据。为了开始我们的分析,我们首先对每个专业的学生排名进行了回归分析。例如,我们对历史的回归是这样的:

由于在这里没有发现显著性(也没有发现任何其他单独的主要回归),我们尝试了另外两种方法。首先,我们观察了薪水最高的专业(计算机科学)和薪水最低的专业(历史)的相对排名,以及这种差距是否从控制变成了治疗。在第二次回归中,我们观察了我们的待遇对受试者排名第一的专业的工资的影响。

Regression output: Effect of treatment on high-to-low salary ranking differential

Regression output: Effect of treatment on salary of top-ranked major

与直觉相反的是,这一最终回归显示,相对于对照组,治疗组排名第一的专业的*均工资下降了(大约 700 美元)。但是,这两种回归都没有提供任何接*显著的结果。例如,在最后一次回归中,我们 95%的置信区间——或者说,95%可能与真实效应重叠的值的范围——从超过 10,000 美元到正 8,860 美元,标准误差接* 5,000 美元。(我们的协变量虽然也不为零,但也不显著。)

因此,对于薪资信息是否会影响主要偏好这一指导性问题,一个令人失望(但并非完全不可预测)的答案是:我们不知道。

讨论:我们是如何得到如此无聊的结果的?

如果你已经做到了这一步(谢谢你,大卫),你可能会奇怪我们怎么会得到这么无聊的结果。为了回答这个问题,我们将首先引导您进入第 2 部分(“数据收集:一切都与权力有关”)。

我们知道进入实验时,我们可能需要更大的样本量来(显著地)检测效果。我们的主要水*回归导致了 0.001-0.1 个排名点的(非常不显著)效应大小。如果这些效应是真实的,我们将需要成百上千的额外数据来自信地这么说。

另一个可能的陷阱是我们的实验设计:为了传达工资信息(给我们的治疗组),我们将一列工资数据楔入一个已经很忙的表中——一个我们的测试对象可能很容易忽视或忽略的表。如果治疗对象没有注意到关于主要工资的信息,他们不太可能受到它的影响。

为了测试这一点,我们在调查中加入了一个叫做操纵检查的项目。作为最后一个调查问题,我们要求学生估计我们研究的四个专业的工资。(治疗受试者可以在他们的数据表中访问这些信息;对照组没有。)

对于历史和经济,我们的操纵测试似乎通过了;治疗组的受试者给出的答案与我们给出的数字接*,而对照组的受试者给出的数字则非常不同。但是对于人类生物学和计算机科学来说,我们的操纵测试失败了:治疗组并没有比控制组在工资估算上更准确。这表明(至少对这两个专业来说)受试者可能没有注意到我们提供的工资信息——或者他们可能不相信我们的数字,而是利用他们自己对真实工资水*的先入为主的概念。

Manipulation check results (*Denotes statistical significance at the 95% confidence level)

但是还有第三种解释。我们的实验是基于这样一个假设,即学生在选择专业时关心薪水。但也许这是不对的。也许学生更关心其他事情(他们是否喜欢这门学科,父母或朋友是否学习过该专业,该专业是否需要大量工作),而不是工资。

一些现有的学术工作指出了这一解释。例如,Wiswall 和 Zafar 的一篇论文发现,“不同的品味”——而不是“预期收入”——是“选择专业的主导因素。”我会有多喜欢这门课程?课程有多难?我的朋友是专业的吗?这些问题的答案可能比对预期收入的估计更与大学生相关。

我们的实验还有很多地方可能出错。例如,考虑到我们要求受试者向朋友推荐一个专业,而不是自己考虑一个专业,我们的治疗效果可能特别微弱。但是,也许这个——找到一个可靠答案的困难——是我们这个小项目最大和最重要的收获。尽管在实验设计上花了不少精力,走街串巷收集调查反馈,并编写代码分析结果,但我们没有得出有意义的结果。正如我们所知,这通常是实验过程的一部分。改变行为,检测效果——这些事情很难。如果你要设计一个实验,你需要适应不回答的模糊性。

感谢大卫·布鲁克曼,GSB 大学教授和测量实践中的影响的策划者。还要感谢 60 名斯坦福大学的本科生,他们每个人都花了 3 分钟来推动科学的发展(但主要是帮助我们毕业)。

建立法国国家能源消费预测系统

原文:https://towardsdatascience.com/make-a-forecast-system-of-the-french-national-energy-consumption-4f946b91381b?source=collection_archive---------5-----------------------

读者们好,在这篇文章中,我将解释我创建法国(大都市)能源消耗预测系统的方法。这种问题或多或少与我在 EDF Energy 的部分工作有关,但这项工作是我在业余时间完成的,以完成我的机器工程师纳米学位。

在这篇文章中,将会描述这个项目所使用的数据,解释用于进行每日消耗量预测的方法以及半小时版本。

数据集的探索

在这种情况下,创建模型的数据来自:

  • 法国能源网络经理 RTE 他们已经创建了一个开放数据*台来访问网络上的不同数据集
  • GEOFLA 数据集给你这个城市和这个地区居民数量的信息
  • 地下天气。我不得不从网站上删除这个数据源(我将重点放在机场的气象站上),并选择在 RTE 测量的时间段内有足够数据的气象站。我将数据分析的重点放在室外温度和风速上。

对于天气状况,我选择创建一个国家气象数据集,其中基本上每个地区都有相关的气象站,这些气象站根据该地区的人口数量进行加权(该信息来自 GEOFLA 数据集)。为了进行数据分析,我选择将 RTE 消耗的*均功率转换为能量(MWh)。

下图显示了法国过去几年的*均能耗。

该图说明了法国能源消耗的季节性。

之后,为了进行每日规模的预测,我必须汇总数据。在下图中,显示了热图中以不同比例聚合的每日数据。

一年中某一天的小时效应研究

对一年中某个月和一周中某一天的消费的研究。

这两个数字很好地说明了每天的消耗量与一年中的某一时刻和一周中的某一天有关。但是这种认识不足以创建预测模型,用于预测能耗的一种非常流行的方法是研究日*均室外温度函数中的日能耗。这种技术被称为电源温度梯度的 PTG,你可以找到很多基于这种方法的出版物。

下图显示了用于预测的模型。

该模型是分段回归,冬季部分由线性回归表示(包括供暖需求和电器),夏季部分由恒定部分表示(仅电器)。这个模型将成为下一部分的参考模型。

日预报

为了创建模型,数据集将在训练集和测试集之间拆分,为这些集选择的样本将是随机的。这代表着:

  • 训练集的 2337 个样本
  • 测试集的 585 个样本

这是一个回归问题,因此将测试 scikit learn 的以下模型:

这是个人对不同模型的选择,还有很多其他模型可以尝试,但作为开始,我认为这已经足够了。我必须调整不同的模型并找到最佳的参数,我在训练集上使用了 k-fold 方法(我创建了 10 个 fold)来测试不同的参数。我邀请您查看我的报告,了解不同型号的参数选择。

为了测试模型中输入的影响,我测试了不同的输入:

  • 仅室外温度
  • 室外温度和风速
  • 室外温度和一年中的月份以及一周中的日期

为了便于输入的使用,我必须对集合进行归一化。为了评估模型的准确性,我使用了用于回归问题的 r 评分标准。但是这个指标不足以评估算法的质量,我将使用的第二个指标是创建模型的时间。下表显示了 r 分数随所用模型变化的情况。

该表允许给出以下结论:

  • PTG 是一个相当好的模型,对于一个仅基于室外温度的模型,分数是好的,但是基于树的模型和神经网络也提供了好的结果
  • 风速的增加提高了分数,但是增益非常小
  • 这一增加为每一个测试模型的分数提供了一个有趣的增益

但是正如我之前所说的,r 分数是不够的,在下表中,在将时间特征添加到初始输入的情况下,有时间来创建模型。

该表说明 PTG 具有良好的性能,而神经网络在速度方面非常差。多项式回归也应该避免。但是这两个指标不足以评价模型的效率。应该研究训练集大小的影响。下图说明了训练集的影响。

该图向我们表明,训练集的大小对多项式回归器有明显的影响,因此其他模型似乎影响较小(神经网络相当快地显示出良好的效率)。

半小时预报

对于这一部分,我们将使用以前发现的所有结果(本质上是时间特征的使用)。我将测试与每日预测相同的模型,并使用相同的指标。

我的基准模型将是 ARIMA 模型,这种模型在预测时间序列方面非常流行(但不需要随机化集合)。这些套件包括:

  • 训练集的 112176 个样本
  • 测试集的 28080 个样本

在我的问题中,模型的结果是坏的。下表总结了基准模型和其他测试模型的结果。

这张最终表格向我们展示了基准模型是很容易被击败的。神经网络的构建非常缓慢,但两个模型似乎非常适合用于我们的问题:

  • 决策树回归器
  • K *邻

结论

这项工作用于完成我的纳米学位,这是我的方法,不是唯一的方法,我认为有很多东西可以尝试,比如深度学习方法或强化学习方法。

我邀请你使用这个项目的数据集来尝试创建你自己的(更好?!)模型,如果您有任何意见,请写在下面。

原载于 2017 年 10 月 20 日【the-odd-dataguy.com

使用机器学习快速创建一个大规模、可搜索的在线服装店

原文:https://towardsdatascience.com/make-a-massive-searchable-online-clothing-store-quickly-with-machine-learning-f9b09d3c4fa?source=collection_archive---------7-----------------------

https://pixabay.com/en/people-woman-girl-clothing-eye-2563491/

你没有时间学习如何制作机器学习模型,你是一个忙碌的企业家!您需要快速获得最低限度可行的产品,并为您的客户解决一些用例。由于人工智能和机器学习的民主化,你可能会比以前更快地达到 MVP。

让我们假设你在你的网站上卖很多衣服,但是你不一定有时间给每一张新图片贴标签。

人们可能会在 Instagram 上提交他们穿着你的衣服的照片,或者你可能想简单地让编目过程变得容易得多。

这是机器学习的完美用例。这里有一个我会如何解决它的例子。

Training set

  1. 获取尽可能多的你想分类的服装样本图片。例如,我下载了数百张牛仔裤、裤子、衬衫、t 恤、运动衫、裙子、连衣裙和围巾的照片。
  2. 我用的是 startup 的对象识别模型 Tagbox ,因为下载和运行只需要 3 分钟左右。另外,我可以教它它还不知道的东西,让它变得更聪明。
  3. 然后,我使用一个小脚本来迭代我所有的照片,并告诉 Tagbox 它们是什么。
  4. 现在有趣的部分来了。然后我去拿了一套新的完全随机的服装图片。重要的是,这个新的测试集没有任何相同的照片,因为那些用来教 Tagbox。我下载了这一套,运行一个脚本,通过 Tagbox 运行每个新图像,瞧:

A sample of my results

Tagbox 已经正确地将正确的关键字与正确的产品/图片关联起来。我现在可以处理无限数量的服装图片,并提取可搜索的标签来增强我的产品。

底线是我只花了大约一个小时构建基础设施来测试这种能力。这证明了像机器盒子这样的开箱即用机器学习公司带来的人工智能民主化。

通过了解数据可视化的历史和最新趋势,对现实世界产生影响

原文:https://towardsdatascience.com/make-a-real-world-impact-through-data-visualization-by-understanding-its-history-and-recent-trends-4fb0b22072ce?source=collection_archive---------7-----------------------

作者安迪·克拉科夫

可视化数据的想法——也就是说,将数字转换成插图,让所有人都可以获得发现——必须从某个地方开始,对吗?事实上,我们可以指出数据可视化开始的具体时间。

这是第一个出版的条形图,由威廉·普莱费尔于 1786 年为一本苏格兰贸易地图集创作。

First published bar graph, created by William Playfair in 1786 for an atlas on Scottish trade

Playfair 也因提出了线形/趋势图和饼状图的想法而受到好评。对于职业来说还不算太寒酸!

下面的地图也在数据可视化中发挥了重要作用。1854 年,在伦敦索霍区,爆发了一场严重的霍乱,如果不是约翰·斯诺确定是污水——而不是像一些人推测的那样,是糟糕的空气——导致了霍乱,我们也许不会知道。他创建的地图上,每座房子代表一个被霍乱侵袭的个体,这确实改变了我们“看待”疾病的方式(他提到的布罗德大街上的水泵是霍乱爆发的源头)。

Map of pump on Broad St. in London which was the source of the cholera outbreak of 1854

到 20 世纪 50 年代,数据可视化在美国报纸中足够普遍,至少有一家报纸——纽约时报——对数据感到足够舒适,即作为一种常见的方言,将我们今天称为仪表板的图表汇编在一起。

New York Times compilation of graphs which today would be referred to as a dashboard

(你可以在斯图尔特·汤普森的博客文章中看到更多关于 20 世纪 50 年代《纽约时报》图片的内容。

这些是数据可视化在塑造社会变革中发挥重要作用的早期例子。然而,我认为,自这些里程碑事件以来,数据可视化并没有发生很大的变化。是的,现在我们定期生产漂亮的数据交互,会让威廉·普莱费尔头晕目眩。但在更基本的层面上,数据可视化是否被社会部门用作教育和说服的工具?我们制作的地图和图表是否真正提高了人们对问题的认识,为政策决策提供了信息,并赋予了社区权力?

在这一点上,我认为记录有点不稳定。本质上,多年来我们已经认识到与数据交流不是一件容易的事情;你不能只是创建一个简单的图表,并把它放在自动驾驶仪上来执行你的命令。然而,这些天出现了一些重要的趋势,我们可以指出并集体学习。以下是我最*观察到的数据可视化的一些重要进展:

将数据转化为游戏和智力练习

谁说数据总要这么严肃?我注意到一种趋势,即组织将数字转化为游戏(或者智力练习,如果你想更精确地描述它的话)。以《纽约时报》的互动为例,他们邀请你,读者,猜测死亡原因的趋势,首先是艾滋病毒、枪支和车祸,然后是药物过量,然后看看你与猜测线图的移动有多接*。

Screenshot of interactive NYT data visualization which is an example of turning data into intellectual exercises

仔细想想,这个概念真的很基本:毕竟,它只是你正在画的一个趋势图。但关键是你在画它,而不仅仅是观察它,这样做,可能更有可能记住信息。一个简单执行的数据游戏是这个 538 关于枪支的民意测验;另一个是由 Velir 与我们的客户之一——联邦基金——合作创建的,它询问并让用户回答问题如果你们州的医疗保健得到改善对个人意味着什么。所有这些都表明,这种趋势有点超出了我们的舒适区,数据总是如此严重,并将数字转化为一些游戏的机会。

让大量的数字看起来有关联

事实证明,我们人类并不擅长真正理解一个大数字的大小,比如一百万,甚至一万。你可能认为我们会从媒体上如此频繁地阅读这些数字来理解这样一个范围。问题是,我们在日常生活中通常不会“看到”这样的数字。因此,大数字对我们来说就像是抽象概念,我们在智力上理解它们,但并没有真正“感觉”到它们。有鉴于此,数据可视化越来越有助于读者更好地理解大量数据。以《华盛顿邮报》的这个例子为例,你可以点击数字,向下滚动人物页面,看看 1077 名在大规模枪击中丧生的人的真实情况。

Screenshot of interactive data visualization of individuals killed by mass shootings

在一个更有趣的话题上,布丁研究了在纽约市音乐界成名的可能性(不太可能),大约 3000 支乐队在三年时间里在纽约市举办了多场演出。《华尔街日报》通过让读者滚动屏幕上的 2.92 亿个点,向读者展示了赢得彩票的微小几率。当我们构建数据可视化时,重要的是要记住,简单地说一个大数字可能不会产生你想要的影响。“展示”这个庞大的数字可能也是必要的。

动画数据

毫无疑问,我们都遇到过数据以某种方式“移动”的情况——从开始的一年开始构建的趋势图,一次出现一个的条形图。我曾经认为动画数据的概念是一个噱头,但后来我看到了它可能产生的影响。例如,当我在露西尔·帕卡德儿童健康基金会工作时,我曾经展示过一份关于加州各县青少年出生率下降的报告。谷歌让我很容易地制作出一个条形图来显示随着时间的变化(本质上,你正在看一个变大或变小的条形图),我可以在我的演示中告诉人们这个简单的动画“技巧”是如何帮助人们更好地理解和保留数据的。

类似地,当我在加州医疗保健基金会时,我的沟通同事们开始整理总结国家医疗保健支出历史趋势的年度可视化图,许多在医疗保健政策领域工作的人对此很熟悉,甚至有所预期。随着时间的推移,这种可视化趋势变得清晰,也许比这些数据以简单的线形图呈现更清晰。例如,请注意橙色阴影区域,它代表自付费用。你可以看到,从 1961 年到 2016 年,这种下降有多明显。

Screenshot of visualization summarizing historical trends in national health care spending in 1960

Screenshot of visualization summarizing historical trends in national health care spending in 2016

说到医疗保健,这是另一个数据动画的例子,其中动画不是故事的核心,但当你浏览这篇关于为什么美国在医疗保健支出方面领先世界的文章时,你会看到精心设计的*滑的可视化动画如何以更有效的方式讲述这个故事,让读者参与进来。

人性化的数字

另一个需要关注的趋势是人性化数据。从历史上看,我们倾向于将数据和故事分开,就好像你只能拥有其中一个,而不能两个都拥有。但这不是我们处理信息的方式。在某些情况下,我们被事实所说服,而在其他情况下,个人因素——例如,一张令人心酸的照片、一段有助于渲染数据的引言、一个受影响家庭的视频——有助于证明这一点。有鉴于此,重要的是我们用故事元素在更广阔的画布上描绘数据,这有助于使数字人性化。这里没有神奇的公式。一些数据故事以事实作为主要的叙事镜头,效果很好,而另一些故事则占据上风,到处插入数据以帮助增加清晰度。

例如,我所在的组织 Velir 与一家名为 Purpose 的通讯公司合作,展示了有多少美国员工是倒班工人,这意味着他们不知道自己每周的日程安排。我们主要通过数字讲述这个故事,但 Purpose 有引用甚至视频,我们可以将它们插入到包中,以帮助演示轮班工人面临的问题。

Data viz created by Velir for communication firm Purpose showing how many US employees are shift workers

读者输入

我在上面提到了将数据转化为游戏的趋势,这是为了创造一种更具参与性的体验。也有更简单的方法来邀请读者转换数据内容。在这篇 Vox 文章中,例如,读者选择他/她出生的年份是为了改变故事中的数据。

Vox article data viz which allows reader to select year of birth to change data in story

《华盛顿邮报》在这篇关于性别薪酬差距的报道中采取了类似的方法。向下滚动选择一个职业,查看相关数据。通过提供一种精心策划但又量身定制的体验,这些故事让读者更有可能根据信息采取行动,因为他们已经被邀请根据自己的兴趣对信息进行个性化设置。

你可能会对自己说,这些例子中有许多是由主要新闻媒体创造的,这些媒体拥有讲故事的专业知识,并且越来越多地拥有一批他们可以求助的互动艺术家和数据可视化专家。毫无疑问,像《华盛顿邮报》和《纽约时报》等新闻媒体在可视化方面处于领先地位,用数据做其他社会部门组织难以完成的事情。但是我们不应该试图模仿——当我们做不到时,就放弃对数据显示的创造性。相反,我们应该更好地向领导者学习,将这些趋势转化到我们自己的工作中,即使是以最基本的方式。我们总是渴望帮助组织解决他们能做什么的难题,因此欢迎您联系我们。

最后,有一个我们都可以实现的重要趋势:保持实用。例如,在构建之前与用户交谈,以了解他们希望如何处理信息。在 Velir 的数据工作中,我们听到越来越多的客户希望创建可打印的数据视图,例如一个包含上下文信息和图表的单页 PDF 数据表。这里的想法是,虽然漂亮的交互看起来很棒,并且起着重要的作用,但我们的客户也需要一些有形的东西,在会议期间分发给人们,并带回他们的办公室。即使在这个数字时代,仍然很少有什么能比得上与一张纸互动。这可能是更有趣的发展之一——也就是说,我们越是推进数字信封,我们就越可能认识到可靠的方法仍然有重要的地位。

关于作者

Andy Krackov, VP, Data Strategy

Andy Krackov 是 Velir 的数据战略副总裁。他的专长是数据内容战略家,可以将数据翻译给多个受众,以便为决策提供信息,提高公众对问题的认识,赋予社区权力,并实现其他有意义的社会变革。他曾在与数据相关的国家和州委员会任职,在关于有效使用数据的主要会议上发表演讲,并为该主题的多个出版物撰写文章。他最初是《美国新闻与世界报道》的记者,拥有华盛顿大学的历史学学士学位和斯坦福大学的传播学硕士学位。

关于 VELIR

我们是一家完全整合的数字机构,总部位于马萨诸塞州萨默维尔市的波士顿郊外。我们拥有一支由 130 多名数字专业人员组成的团队,以我们为一些世界上最大和最有影响力的非营利组织、会员协会和财富 500 强企业所做的数字工作而闻名。我们在营销技术和数据可视化方面的能力是业内公认的最佳水*,这源于 17 年来对数字战略、创意设计、网络工程和应用程序开发的专注。我们已经完成了复杂的实施和大规模的品牌建设,包括拜耳,罗伯特·伍德约翰逊基金会,大都会艺术博物馆,美国退休人员协会,耶鲁大学和信息。我们被大波士顿商会和萨默维尔商会授予“年度小型企业”荣誉称号,并在波士顿和华盛顿州 DC 设有办事处。更多信息,请访问www.velir.com。

“让业余无线电再次变得酷起来”,人工智能先生说。

原文:https://towardsdatascience.com/make-amateur-radio-cool-again-said-mr-artificial-intelligence-36cb32978fb2?source=collection_archive---------13-----------------------

一个为业余无线电通信建立语音识别系统的项目。

系统设置:

我对着 Baofeng 手持无线电收发器说话,DIY 天线拾取无线电波,SDR 将无线电信号解调为标准音频信号,Google 语音到文本执行语音识别,Smith-Waterman 算法执行序列比对以在数据库中找到最可能的呼号,AJAX 用于本地 httpserver 以输出文本。系统图如下所示。

System diagram for the voice recognition system for amateur radio communication

这是演示。它成功地从数据库中找到最可能的呼号,并捕捉到“监控”消息。

Demo

硬件(天线、SDR 加密狗、调频无线电收发器):

我将 0.5 米(~波长/4)的铜线连接到连接器上,形成我的天线。我从亚马逊购买所有的连接器,从当地的五金店购买铜线。

天线的零件有

  1. 直径为 0.15 毫米的 0.5 米铜线
  2. 超高频母插孔焊料 SO-239
  3. 射频同轴电缆适配器 F 母头至超高频公头 PL-259 连接器
  4. 母到公连接器射频同轴适配器
  5. DHT 电子射频同轴电缆组件 N 公头至 MCX 公头直角 6 "

我用的是手持 FM 无线电收发器(宝丰 UV-5R v2+)进行业余无线电传输。NooElec SDR dongle 用于接收来自天线的信号,并将其发送到我的笔记本电脑。它们都可以在亚马逊上买到。

完整的硬件设置如下所示。

Hardware setup : antenna, SDR dongle, FM radio transceiver

软件定义无线电/数字信号处理:

根据维基百科,

软件定义无线电 ( SDR )是一种无线电 通信系统,其中传统上以硬件实现的组件(例如混频器、滤波器、放大器、调制器 / 解调器、检测器等)。)而是通过个人电脑或嵌入式系统上的软件来实现。

我用 SDRSharp 做所有的信号处理和转换。下面是一个正常工作的 SDRSharp 的屏幕截图

Digital signal processing

语音识别:

我使用谷歌语音转文本 API 进行语音识别。

以下是片段。

Speech recognition

但正如演示中所示,谷歌语音到文本似乎有点挣扎,并产生一些错误。这可能是由于背景中的噪声。我认为,如果一个人可以用从真实的业余无线电谈话中获取的训练集来训练一个深度网络,这可以得到改善。

史密斯-沃特曼算法;

语音识别系统很可能会出错。我通过保存一个呼号数据库来缓解这个问题。数据库可以用来自各种来源的数据来构建。比如飞机无线电通信,dump1090 就是一个很不错的程序,可以通过解码 1090MHz 上发送的消息来捕捉飞机的信息。可选地,可以简单地使用日志,该日志存储经常使用本地中继器的人的呼号。

一旦我们有了呼号数据库,我们就可以使用史密斯-沃特曼比对算法来找到最佳匹配。

以下是片段。

Swith-Waterman algorithm

异步 JavaScript 和 XML(AJAX):

为了实时更新,我使用 AJAX。AJAX 支持从包含呼号/演讲/时间戳的文件中自动获取信息。

我通过在终端中键入以下命令,在本地使用一个简单的 httpserver。

python -m SimpleHTTPServer

网页的代码片段如下所示。

AJAX

网页截图如下图。

Webpage output

最后的话

许多人说业余无线电爱好正在消亡。我觉得这很可悲,因为人们可以用它做很多有趣的事情,尤其是当它与更新的技术(如人工智能)结合在一起时。所以,我决定参与这个项目,并与大家分享。我希望你会觉得有趣。

让信息变得美丽

原文:https://towardsdatascience.com/make-information-beautiful-5c19a09600b7?source=collection_archive---------2-----------------------

我们生活在一个信息过载的世界。每分钟生成、收集和存储的数据量都在呈指数级增长。

虽然我们拥有比以往任何时候都多的信息,但用数据讲述引人入胜的故事并没有变得更容易。

毕竟,数字很无聊。当你开始展示数字和图表的时候,你就失去了你的听众。

数据叙事的挑战催生了信息可视化。统计图表的起源可以追溯到 19 世纪,最初是由威廉·普莱费尔发明的,用来说明复杂的问题,比如英国和其他国家之间的进出口差异。遵循 Playfair 的做法,人们很快意识到信息图表在交流大思想方面的力量。

原因?我们天生就是视觉的。科学已经证明视觉是我们所有感知系统中最强大的认知系统。我们大脑中 90%的输入是视觉的。人们能记住他们看到的 60%,但只能记住他们读到的 40%。

如今不同的是从功能性图表和图形到更漂亮的交互式信息图的转变。无聊的设计越来越不能吸引我们的观众;人们渴望更多艺术般的视觉效果。对于绝大多数非设计师来说,挑战在于努力在美观和功能之间取得*衡。

在我们探索如何理解所有信息的过程中,我们询问了 25 位专家关于如何讲述视觉上引人注目的数据驱动的故事的最佳建议。我们希望这些专家的建议能帮助你以一种引人入胜的方式交流数据驱动的信息。

Created using Visme. An easy-to-use Infographic Maker.

将信息图嵌入到您的网站: <div class = " visme _ d " data-URL = " rx 13 GWP 8–25-expert-tips-on-how-to-make-information-beautiful-7 " data-w = " 800 " data-h = " 13120 " data-domain = " my "【t33

下载信息图 为图片

加雷斯·库克

普利策奖得主记者,《纽约时报》特约撰稿人,畅销书系列最佳美国信息图的编辑,告诉我们讲故事的重要性:“永远不要忽视最重要的问题:你想讲的故事是什么?”

阿尔贝托·开罗

《功能艺术》(The Functional Art)的作者,迈阿密大学传播学院视觉新闻学的 Knight Chair 说:“让信息可视化的关键是首先拥有好的信息:不是推动你的议程或帮助你销售产品的信息,而是有可能改善人们生活的信息。”

阿尔贝托·开罗说,当一个人收集了正确的信息后,剩下的事情就自然而然了。“简单的部分是,信息需要以人类可以理解的方式呈现,选择地图、图表、图形和图表。”

史蒂文·海勒

史蒂文是许多关于设计和视觉文化书籍的作者,包括《信息图设计师速写本。33 年来,他一直是《纽约时报》的艺术总监。他是作为作者部门的 MFA 设计师的联合主席,SVA 总统新项目的特别顾问。他告诉我们:“图片不是文字,但文字应该来源于图片。无论是在文本中还是在思想中,这两者必须齐头并进。"

布莱恩·华莱士

布莱恩是一名信息图学者,也是屡获殊荣的信息图设计机构 Nowsourcing 的创始人。他还是 CMS Wire &搜索引擎杂志的专栏作家,并担任谷歌中小型企业顾问。他的建议是:“视觉叙事艺术是简洁的文字、引人注目的数据和古怪但美丽的设计的正确结合。”

比安卡·伍兹

比安卡是 L&D 设计工作室 Clever Raptor 的联合创始人,也是 BMO Financial 的设计和沟通顾问。她说,可视化信息的重要一点是“保持事情简单:当你试图用视觉简洁地表现数据时,编辑掉任何不会强烈增加整体清晰度的细节。”

蒂亚戈·贝洛索

关于信息图表和数据可视化的领先博客的创始人。他将数据可视化视为一种艺术表达形式:“数据可视化提供了一种主流的跨普遍性,只有音乐等艺术表达才能实现——没有所有艺术形式固有的解释主观性。”

比尔·山德

Bill 是一位著名的视觉传达和数据故事的演讲者和作者。他是总部位于波士顿的数据可视化和信息设计咨询公司 Beehive Media 的创始人。

根据他在知名公司工作的经验,比尔说可视化信息最重要的是知道你真正想说什么。“如果你知道你想强调 X,或者在 A 和 B 之间画一个对比,或者强调主题 Z,你的视觉效果应该 100%集中在主要的沟通目标上。”

朱利叶斯·威德曼

朱利叶斯是《设计与流行文化》的首席执行主编,同时也是 TASCHEN 的设计负责人和数字出版物总监。他主编的书《信息图形》。他的建议是:“人类无时无刻不在用隐喻思考,所以如果你能找到一个或多个隐喻来让复杂的事情变得容易解释,从而让人们理解,你就在正确的道路上。”

王女士

Dona 在金融图形方面有 20 多年的经验。她的职业生涯始于《纽约时报》的商业图形编辑,后来成为华尔街日报的图形部门主管。她是“ 华尔街日报信息图形指南 ”的作者,这是一本关于通过图表和图形进行交流的注意事项的书。她说,视觉化翻译信息的关键是“理解、编辑和简化信息——并以读者为中心进行设计。”

克里斯塔·内赫

Krista 是 Boot Camp Digital 的首席执行官和数字营销专家。她写了本书《傻瓜的视觉社会营销》。谈到在讲故事时使用信息图,尤其是为了营销目的,Neher 说:“视觉效果应该阐明和简化你的故事。正确的视觉效果应该比文字更好更快地讲述你的故事。不是每张图片都抵得上 1000 字。让你的人生有价值。”

科尔·努斯鲍默·克纳弗里奇

科尔是“用数据讲故事:商业人士数据可视化指南”的作者,也是热门博客storytillingwithdata的所有者。她关于在商业环境中使用数据讲述故事的建议是:“永远不要简单地展示数据;相反,让数据成为一个总体故事中的关键点,并利用它来推动你的受众采取行动。”

瑞士出纳员

Swizec 是一个数字流浪者,全栈 web 工程师,也是用 d3.js 实现数据可视化的作者。他说,将数据转化为视觉效果的关键是“在你的数据中找到惊喜,并将其作为标题。”

本杰明·维德凯尔

Benjamin 是瑞士设计工作室 Interactive Things 的主管,专门从事用户体验设计和数据可视化,同时也是瑞士数据可视化和信息图表资源网站https://datavisualization.ch/的编辑。他的建议是:“我们不是为数据而设计,而是为人类而设计。因此,在设计可视化时,我们必须考虑读者和他们的背景。”

西尔维奥·达席尔瓦

Silvio 是一位经验丰富的数字媒体数据设计编辑和创意总监,曾与美联社、汤森路透、NBC 环球等主要新闻网络合作。西尔维奥说:“数据可视化设计描绘了内容和背景——一个只能用数据创造的故事。”

伊娃·阿布舍-尚茨

国家地理儿童媒体视觉识别副总裁 evas。她在创作《数字:110.01 充满统计数据和数字的酷信息图表》中发挥了关键作用,这本书通过引人入胜的视觉效果将世俗知识带给孩子们。

当被问及如何为有视觉倾向的观众完成这样的壮举时,伊娃说:“当视觉信息分层时,它可以为读者创造一个切入点;你的切入点越多,吸引观众的机会就越多。”

兰迪·克鲁姆

Randy 是 InfoNewt 的总裁,info newt 是一家信息图表设计公司,他也是热门博客 Cool Infographics 的所有者,这是信息图表设计灵感的主要来源。他撰写了《酷信息图:数据可视化和设计的有效沟通》一书,这是一本关于如何创建信息图的综合指南。

兰迪强调了颜色的重要性:“使用颜色来突出数据的洞察力,并将读者的注意力吸引到设计的关键信息上。"

斯科特·阿丁顿

斯科特白天是营销总监,晚上是历史迷。作为《T4:第一次世界大战 100:信息图表中的第一次世界大战》一书的作者,他寻找新的、创新的方式,用令人惊叹的视觉效果来讲述历史。

他建议使用视觉效果作为容易忘记和容易记住的内容之间的关键区别:“一条信息的引人注目的视觉效果可能是被忘记的内容和被记住并分享的内容之间的区别。”

米丽娅姆·奎克

Miriam 是一名专门研究信息可视化的研究员。她的作品出现在 BBC.com,英国文化委员会,大卫·麦克坎德斯(informationisbeautiful.net),连线英国。

她从研究的角度谈到了如何选择和表示数据:“理解信息想要采取的形状——这就是你的可视化应该是什么样子。”

他建议使用视觉效果作为容易忘记和容易记住的内容之间的关键区别:“一条信息的引人注目的视觉效果可能是被忘记的内容和被记住并分享的内容之间的区别。”

大卫·麦坎德斯

David 因其数据新闻工作和畅销书“信息是美丽的”而在数据可视化领域广为人知。他的新书“知识是美丽的”以他之前的工作为基础,更深入地探讨了世界如何与可视化数据打交道。

大卫在 Reddit AMA 网站上说,一旦你理解了数据,故事就应该从数据中浮现出来:“当你可视化时,你真的不设计数据。你设计你对数据的理解。”

他在下图中总结了良好可视化的要素:

詹姆斯·鲍尔

詹姆斯是 BuzzFeed 英国和 T2 的特约记者,之前是《卫报》的数据记者。他还撰写了“世界信息图表史”,这本书以美丽的视觉效果带你穿越 138 亿年的历史。

詹姆斯在接受 ichart.net 采访时说:“可视化非常有趣,因为它是关于找出让信息变得令人兴奋的最佳方式。”

佩曼·泰伊

Payman 是拖拽式视觉内容工具 Visme 和网页设计公司 HindSite Interactive 的创始人。根据多年的设计经验,Payman 建议在可视化信息方面,“尝试少即是多的方法。将复杂的数据缩短为一口大小的可吃的内容,并将它们转换为步骤,如阶段。”

弗朗切斯科·弗兰奇

弗朗西斯科是一位获奖的*面设计师、记者和教授。他是两本书的作者:智能生活方式杂志——智能编辑设计、想法和新闻和设计新闻——改变编辑设计和信息图形的世界。

他对我们视觉化翻译信息的建议是:“形式和内容必须协同工作,传递一个令人愉快、有用和信息丰富的想法”。

内森·尤

Nathan 是一个非常受欢迎的数据可视化博客 flowingdata 的作者。他是一名统计学家和信息设计师,经常用个人数据做实验。他还写了本书把这个和的数据点可视化。

他对通过数据尤其是个人数据讲故事的见解是:“我们可以让它人性化,突然之间,人们会听到并理解这些数据是关于他们的。”

艾米·巴利耶特

艾米是黑仔信息图的联合创始人和所有者,这是一家位于西雅图的精品设计机构,为微软、波音、Adobe、尼康、星巴克和联合国等客户设计了 3000 多幅信息图、动画和互动图形。

Amy 分享了她对视觉传播世界发展方向的预见:“我们正朝着一个互动的世界前进,在那里我们将看到更多的视差滚动信息图和动画运动图”。

尼古拉斯·费尔特龙

尼古拉斯是一名信息图 设计师和个人年度报告的作者,该项目自 2013 年以来每年都对他自己的个人数据进行可视化和反思。他是Daytum.com的联合创始人、报告 ap p 的联合创始人,曾是脸书的产品设计团队成员。

关于信息设计,费尔特龙说:“形式、颜色和排版必须一起工作,以达到*衡,并传达你想说的话。”

将信息转化为漂亮的设计可能是一项艰巨的任务。

Visme ,我们致力于让您轻松进行视觉交流。现在,每个人都可以使用拖放 DIY 工具在几分钟内创建交互式演示和信息图。

不需要设计培训。

你可以在我们的 视觉学习中心 查看更多实用的技巧和灵感,或者注册我们的时事通讯,让专家提示发送到你的收件箱。

我们即将推出激动人心的节目,帮助您将枯燥的数据转化为美丽的视觉效果。敬请期待

本帖 原版 最早出现在 Visme 的 视觉学习中心

了解卡尔曼滤波器

原文:https://towardsdatascience.com/make-sense-of-kalman-filter-c59fe5f8202f?source=collection_archive---------3-----------------------

这份材料来自我在 Udacity 自动驾驶汽车项目中获得的知识。特别感谢巴斯蒂安·特龙和奔驰工程师的讲座。

Source: https://www.codeproject.com/Articles/865935/Object-Tracking-Kalman-Filter-with-Ease

什么是卡尔曼滤波器?

长回答:看看这个维基百科链接。想研究一下吗?这个环节。

我的(简短且更普通的用户友好的)回答:
-预测位置和速度,有一些不确定性。
-然后测量实验位置和速度,有些不确定性。
-最后,通过将我们的预测与测量信息相结合,增加我们预测的确定性。

好奇部分 1:为什么我们必须预测然后测量和更新?

确实如此。乍一看,这个过程似乎有点丰富。做出所有的预测,然后回头来衡量我们刚刚预测的东西,这有什么意义呢?直接投入测量,生活就不能更简单吗?

那样生活会简单得多。然而,在我揭示为什么的秘密之前,我必须问你一些事情。

想象你在路上开车,少管闲事,尽量保持 30 英里的时速。然后,在你右边车道上的人发出信号让你超车。因为你是个好人(有着美丽的灵魂),所以你可以接受。这里不谈任何技术问题,在这种情况下,你会怎么做,让那个人安全地走到你前面?

如果那是我,我可以用 2 秒钟做一个完整的观察 汽车在哪里&相对于我的速度 它的速度是多少。我的直觉可以预测它下一步要做什么。那样的话,我要么减速让道,要么加速让道。取决于我的车和另一辆车的位置,我会根据我的最佳判断让另一辆车在不造成任何事故的情况下超车。

假设那辆车成功地变道到了我的前面,我仍然不断地观察那辆车并调整我的速度,这样我的车就能一直保持在安全区域。如果车开慢了,我预测下一秒车还是会慢,我会在后面保持慢速。但是,如果它突然开得很快,我可以加快一点速度(只要在限速之下),更新我的信念。我在那里所做的是一个连续的预测更新的过程。

所以,如果你以我为例,我想我已经给了你卡尔曼滤波器背后的逻辑。但是卡尔曼滤波器没有被发现适用于人类(或者是?>:),它已被用于机器上的各种工程应用,因为机器不具备像人或动物那样根据环境变化进行逻辑思维的能力。

好奇第二部分:为什么我们要把预测和测量结合起来?难道测量本身还不够精确到可以更新吗?

又来了。认为单独使用传感器信息进行更新是正确的做法是有道理的。然而,测量也会有不确定性(等等…什么???).例如,激光雷达用于检测位置,并且它位于汽车外部,可能存在环境影响(雨、雾、灰尘等),这使得测量不太确定。

不要盲目相信一方是一个好习惯,在某个地方总是有不确定的空间。通过组合信息,我们有更多的信息来降低不确定性/协方差,并给出更可靠的最终输出。

结论

传感器就像我们的眼睛,鼻子,耳朵。它们感知事物,并将信息传回大脑进行处理。对于自动驾驶汽车,我们有摄像头,激光雷达和雷达。相机获取图像,使深度学习能够识别物体,甚至预测信息。激光雷达和雷达感测速度和位置,以便机器可以根据卡尔曼滤波器应用做出相应的移动决定。

希望你喜欢这篇短文。如果你喜欢你所读的,请点击分享。我感谢任何反馈。下次见!

使处理大型数据帧变得更容易,至少对您的内存来说是这样

原文:https://towardsdatascience.com/make-working-with-large-dataframes-easier-at-least-for-your-memory-6f52b5f4b5c4?source=collection_archive---------4-----------------------

将数据帧的大小减少多达 90%!

如今,在大数据世界中,我们经常使用大型数据集。虽然有某些工具可以促进对大量数据的处理(如 Spark),但我们仍然在本地做大量工作,例如,我们希望建立一个原型模型(MVP,最小可行产品)。因此,我认为花点时间优化我们处理数据的方式可能是值得的——通过这样做——将其大小减少 90%。是的,可以那么多…

引擎盖下发生了什么?

不会有太多的理论,但还是有必要说几句。在幕后,pandas 将 DataFrame 的相同变量类型(如整数、浮点、对象)的列存储在块中。在表示数值(整数和浮点数)的块的情况下,这些列被组合并以 NumPy 的ndarray的形式存储,这使得访问它们非常快。

因此,让我们看看在 pandas 上可用的数据类型以及它们实际上代表了什么。下表概述了可用的类型及其用途。

Source: http://pbpython.com/pandas_dtypes.html

还值得一提的是表中可见的子类型。举个例子,我们有int8int16int32int64。该数字表示该子类型使用多少位来表示特定值,这些位分别使用 1、2、4 和 8 字节的内存。下表可能更能说明我们实际上可以在这些数字数据类型中存储哪些值。

Source: https://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html

知道uint(无符号整数)和int(有符号整数)之间的区别可能会很方便。两者的存储容量相等,但是无符号整数只允许存储正值。因此,在某些情况下,我们绝对可以利用这一点!

实际例子

在本文中,我将生成一个示例数据框架,用几种不同的数据类型来说明如何优化存储。Pandas通常在检测数据类型时做得很好,但是,有时,例如,当使用read_csv()read_sql()时,数据类型没有以最佳方式分配。我创建数据帧如下:

我人为地将user_idorder_id等变量的类型设置为 string,因为这是实践中经常发生的情况。您还会遇到类型为id123456789的 id,其中删除字符串部分id不会产生任何影响,但会导致所需内存的显著减少。

作为第一步,我检查样本数据帧中存储的变量类型。一切都在意料之中。

>>> df.dtypesuser_id                object
order_id               object
order_date             object
number_of_products      int64
total_amount          float64
day_of_week            object
dtype: object

要查看每列占用多少内存,我们可以使用如下的memory_usage:

>>> df.memory_usage(deep=True) / 1024 ** 2Index                  0.000076
user_id               61.988831
order_id              61.035156
order_date            38.146973
number_of_products     7.629395
total_amount           7.629395
day_of_week           61.171283
dtype: float64

通过设置deep=True,我们获得了确切的内存大小(Mb ),保留默认选项False将提供一个*似值。乍一看很清楚,大部分内存用于存储字符串,这也是我们可以从优化中获得最大收益的地方。为了方便起见,我定义了一个助手函数来评估整个数据帧的大小(以 Mb 为单位)。

def memory_usage(df):
    return(round(df.memory_usage(deep=True).sum() / 1024 ** 2, 2))

让我们看看数据帧总共占用了多少空间:

>>> print('Memory used:', memory_usage(df), 'Mb')Memory used: 237.6 Mb

优化数值变量

首先,检查变量并找出我们正在处理的东西是有好处的。

>>> df.describe()

Summary statistics of numeric variables

结果并不令人惊讶,因为这正是初始化随机数据帧时定义变量的方式。检查完带有子类型的表后,我们可以手动将number_of_products的类型更改为uint8,因为这是适用于该变量的最小数据子类型(只有最大值为< 20 的正值)。当我们在这里处理一个浮动时,我也向下转换了total_amount。由于变量仍然具有很高的精度,在这种情况下我不需要(之前四舍五入到 2 位小数),保持这种方式没有意义,所以我进一步将类型改为float16.

>>> df.number_of_products = df.number_of_products.astype('uint8')
>>> df.total_amount = df.total_amount.apply(pd.to_numeric, downcast='float')
>>> print('Memory used:', memory_usage(df_copy), 'Mb')Memory used: 230.93 Mb>>> type(df.total_amount[0])numpy.float64>>> df.total_amount = df.total_amount.astype('float16')
>>> print('Memory used:', memory_usage(df), 'Mb')Memory used: 225.21 Mb

通过所有这些操作,我们设法将数据帧的大小减少了 10Mb 多一点,这并不是我所承诺的。但还是继续吧!

优化对象变量

Overview of ‘object’ type variables

通过检查类型为object的变量,我们可以看到一些东西。首先,正如所料,id 是唯一的。第二,日期没有太多不同的值。然而,我们希望保持它们的datetime格式,因为这有助于更容易的 EDA。所以我们不会转换它们(这当然是可能的)。最后是day_of_week,它在逻辑上只能接受几个不同的值。我们在这里可以做的是将它转换成不同的变量类型——category.对于任何熟悉 R 的人来说,这将相当于一个factor.。这个想法非常简单,字符串变量被编码为整数,通过使用一个特殊的映射字典可以解码回它们的原始形式。当我们处理有限数量的不同字符串值时(例如重复的星期几、月份等),这是很有用的。).一个有用的经验法则是考虑对唯一值与观察总数的比率低于 50%的变量使用分类数据类型。否则,我们可能会比一开始使用更多的内存。

>>> df.day_of_week = df.day_of_week.astype('category')
>>> df.user_id = df.user_id.astype('uint32')
>>> df.order_id = df.order_id.astype('uint32')>>> print('Memory used:', memory_usage(df_copy), 'Mb')Memory used: 49.59 Mb>>> df_copy.memory_usage(deep=True) / 1024 ** 2Index                  0.000076
user_id                3.814697
order_id               3.814697
order_date            38.146973
number_of_products     0.953674
total_amount           1.907349
day_of_week            0.954408
dtype: float64

我们将数据帧的大小从 237.6 Mb 减少到 49.59 Mb,减少了大约 80%。但是当我们只考虑被修改的变量时,那么结果实际上是 94%!我会说这是一项出色的工作:)

另一个技巧是在通过pandas.read_csv().将数据加载到 Python 时考虑数据的类型。假设我创建的样本数据帧在一个 CSV 文件中,我们可以创建一个包含数据类型信息的字典,并将其传递给函数。

column_dtypes = {'day_of_week': 'category',
                 'user_id': 'uint32',
                 'order_id': 'uint32',
                 'total_amount': 'float16',
                 'number_of_products': 'uint8'}df = pd.read_csv('sample_dataframe.csv', dtype = column_dtypes)

一如既往,我们欢迎任何建设性的反馈。你可以在推特上或者评论里联系我。我希望你喜欢这篇文章,并会发现这些技巧在你的项目中很方便!

利用最*邻分类器制作手写数字识别程序

原文:https://towardsdatascience.com/making-a-handwritten-digit-recogniser-program-using-nearest-neighbour-classifier-d33e76aa17b6?source=collection_archive---------2-----------------------

最*邻分类器是机器学习中最基本的算法之一。本教程描述了一个非常基本的方法,使一个数字识别程序。这里我们不会使用任何 python 机器学习库。所以让我们开始吧

导入所需的库

from sklearn import datasets
import matplotlib.pyplot as plt
import numpy as np

sklearn 的数字数据将用于本教程。

加载数据集

digits = datasets.load_digits()

将数据可视化

digits.data包含线性阵列中的图像(本例中为 64 x 1 ),而digits.images将它们存储在 8 x 8 阵列中。让我们展示一个数字

fig = plt.figure()
plt.imshow(digits.images[23],cmap = plt.cm.gray_r)
txt = "This is %d"%digits.target[23]
fig.text(0.1,0.1,txt)
plt.show()

这将给我们展示索引 23 处的图像

现在让我们看看这个图像作为一个数组是什么样子的。

digits.images[23]

这将给出如下输出

array([[  0.,   1.,   8.,  12.,  15.,  14.,   4.,   0.],
       [  0.,   3.,  11.,   8.,   8.,  12.,  12.,   0.],
       [  0.,   0.,   0.,   0.,   2.,  13.,   7.,   0.],
       [  0.,   0.,   0.,   2.,  15.,  12.,   1.,   0.],
       [  0.,   0.,   0.,   0.,  13.,   5.,   0.,   0.],
       [  0.,   0.,   0.,   0.,   9.,  13.,   0.,   0.],
       [  0.,   0.,   7.,   8.,  14.,  15.,   0.,   0.],
       [  0.,   0.,  14.,  15.,  11.,   2.,   0.,   0.]])

像素越暗,数字越大。如果您将光标移动到阵列上更大的数字上,您可以看到它正在生成一个 3。

训练和测试数据集

我们将选择前 100 幅图像作为我们的训练数据集。

x = 100 #length of training data setX_train = digits.data[0:x]
Y_train = digits.target[0:x]

测试数据集

pred = 813
X_test = digits.data[pred]
print "X_test's real value is %d"%digits.target[pred]

对于我们的程序,我们将找到测试图像与每个训练图像的距离,距离最小的图像就是预测值。我说的距离是 64 维中的欧几里德距离。要计算欧几里得距离,我们只需找到每个索引的数字之间的差异,对它们求*方,将它们相加,然后求*方根。所以,让我们定义dist函数。

def dist(x,y):
 return np.sqrt(np.sum((x-y)**2))

只要 x 和 y 有相同的维数,这个函数对任何维数的数组都有效。(我爱 python 的原因之一:P)。

现在让我们使用dist函数来预测测试数据。

l = len(X_train)
distance = np.zeros(l) 
for i in range(l):
 distance[i] = dist(X_train[i],X_test)
min_index = np.argmin(distance)
print "Preditcted value is ",
print(Y_train[min_index])

这将打印预测值,在本例中为 9。

我们模型的准确性

现在,让我们看看我们的模型预测得有多好。

l = len(X_train)
no_err = 0
distance = np.zeros(l)
for j in range(1697,1797):
 X_test = digits.data[j]
 for i in range(l):
  distance[i] = dist(X_train[i],X_test)
 min_index = np.argmin(distance)
 if Y_train[min_index] != digits.target[j]:
  no_err+=1
print "Total errors for train length = %d is %d"%(x,no_err)

我们的测试数据集有 100 个例子。在 for 循环中,它预测 j 索引处的图像数,并将其与实际值进行比较,然后打印错误总数。当x = 100 14/100 值预测错误,且x = 1696 2/100 值预测错误时。所以我们的模型预测图像有 98%的准确率。

预测自定义输入(如果您想向某人展示:P)

这是本教程的第 2 部分,我们将对自定义输入进行预测。您可以使用任何图像编辑器,这里我们将使用 G.I.M.P.

遵循以下步骤

  1. 打开 GIMP
  2. Ctrl + N
  3. 在下一个窗口中,将高度和宽度都设为 8。由于工作表非常小,您可能需要放大
  4. 现在滚动。如果指针的大小正在改变,则进入下一步,否则按照这个来改变指针的大小。
  5. 将指针的大小减小到最小。
  6. 转到工具→绘画工具→画笔或按 P.
  7. 告诉那个人在文件里画一个数字。
  8. 进入文件→导出并保存你的图像为 test.png。

This is test.png

访问图像 test.png 的 Python 代码

from scipy import misc
image = misc.imread("/path_to_test.png/test.png",flatten = 1)

现在,如果你打印digits.images[0],你会看到白色像素相当于0,值越大,像素越暗,但是如果你打印标准形式的image255代表白色,0代表全黑。因此,我们必须转换它,使白色对应于0,然后我们将重塑图像从 8 x 8 到 64 x 1

image1 = 255 - image
image2 = np.reshape(image1,64)

如果您查看任何 digits.images 示例,您将会看到最黑的像素对应于~15,但是您自定义输入中任何像素的最大值可以是 255,因此为了避免由于这种影响而导致的任何错误,我们将对数据进行标准化(即在 0 和 1 之间重新调整)。为此,我们将找到数组的最大数目,并将每个元素除以该最大数目。

# Training data
for i in xrange(len(X_train)):
 maximum = np.amax(X_train[i])
 X_train[i]/=maximum#Testing data
maximum = np.amax(X_test)
X_test/=maximum

现在我们可以走了。我们来预测一下:)

l = len(X_train)
distance = np.zeros(l) #This will store the distance of test from every training value
for i in range(l):
 distance[i] = dist(X_train[i],X_test)
min_index = np.argmin(distance)
# print X_test
print "Preditcted value is "
print(Y_train[min_index])

这会打印出来

Predicted value is 2

你可以制作更多的图像并预测它们。

所有的代码都可以在这里找到https://github.com/Salil-Jain/DigitRecognizer

谢谢你。

使用 Node.js 制作回复器并关注 Twitter 的 Bot

原文:https://towardsdatascience.com/making-a-replier-and-follow-bot-for-twitter-using-node-js-23e0ba8e4e4f?source=collection_archive---------3-----------------------

如何“明智地”花时间做这个了不起的东西。

在我们开始之前,我想“警告”你,这个活动看起来很乏味,但实际上只是面具后面的儿童游戏。

先决条件:

  • 节点npm 的当前版本。
  • 下载并顺利运行 jQuery 3.0
  • 一个最新版本的自制软件已经安装并运行。
  • 一个演示版的推特账号。
  • 文本编辑器;我建议崇高文字或者原子

我建议创建另一个假的模拟账户,因为我们现在要做的是…这么说吧,推特先生不喜欢这样。

我们将要重复发布推文,每 10 秒发布一次,违反了几乎所有的规则。基本上,破坏了整个系统。所以如果这个账号被封了,你也不会丢失你宝贵的个人资料。

建议阅读 Twitter Bot 文档

序幕

在我们开始之前,让我们检查一下我们的节点npm 是否处于当前版本并且能够正常工作。到你的终端,连续输入这两行。

**$ node** -v
v7.10.0**$ npm** -v
4.2.0

创建文件

打开您喜欢的文本编辑器,创建一个包含两个文件的文件夹——config . jsbot.js 。你可以给它们起任何你想要的名字,但是我更喜欢这两个名字,以便在本教程中更容易理解。

打开您的终端,将目录切换到您计划制作 bot 并存储所有相关文件的文件夹。

Two files bot.js and config.js in a file called NodeJSDemo.

Make sure to install your dependencies and packages in the target folder.

使用所需的包启动节点私有服务器

在命令提示符下输入下面一行来初始化一个名为 package.json 的新 JSON 文件。

**npm** init

系统会提示您填写几个字段。继续填写你的机器人的相关信息。

你可以按回车键跳过一些不必要的。

通过这样做,我们文件夹中的这个文件包含了我们的节点应用程序的简短介绍。关于作者、描述和文档、使用的依赖项、许可证和关键字的信息包含在该文件中。

导入我们的依赖项

打开您的浏览器,打开 npm 网站 ,搜索 Twit 包文档,您会在页面上看到以下内容。

Go click on the first search result you see on the npm search list.

点击文章,进入 Twit 依赖的文档页面。在您的终端或命令行中键入安装命令,并等待它完全完成安装。

Type in the installation command in your command line or terminal

我建议在这个命令的末尾添加一个 - save 标志,这样以后用的时候就不需要重新安装了。它将被本地存储在磁盘上。

**npm** install twit **--save**

在安装 Twit 包时,您会看到在这个目录中有一个名为 node_modules 的文件夹。如果你打开它,它会显示其他更小的文件夹,包含 Twit 运行的依赖项和包,以及里面的 README.md 文件。

最后,我们完成了机器人初始化!现在,在推特网站上创建我们的机器人。

出发去推特吧!

打开你的浏览器,进入 Twitter 网站 。创建一个假的模拟帐户,并设置它。

进入 Twitter 开发者页面 和向下滚动到页脚,点击工具下的管理你的应用

创建一个新的应用程序,并输入必要的信息,如应用程序的名称,描述,网站(如果有的话),以及任何其他我忘记提到的字段。

Fill in these fields. You can ignore the last two if you want. However, if you actually have an OAuth key and a website to host the bot, I urge you to type in your respective credentials

现在我们已经创建了我们的应用程序,我们现在需要获得我们的消费令牌和应用程序机密。转到密钥和访问令牌选项卡,复制这些消费者密钥消费者秘密并将其粘贴到某个地方。我们将很快使用这些值。

如果你向下滚动,你会看到这个按钮叫做创建我的访问令牌。单击此按钮生成自定义访问令牌和访问令牌密码。复制并粘贴这些值。

If you have followed the steps up until this point, you’ll have this show up on your screen. Each bit has its own separate access token and consumer key. Using these values, we’ll be able to communicate with the Twitter databases to extract relevant information about events.

假设您计划发布和开源您的 bot,那么您显然需要隐藏和保护您的消费者密钥和访问令牌,以避免误用和滥用。

为了完成这项工作,我们将从另一个文件初始化我们的机器人: config.js 。这样,我们就不需要在实际的可部署代码体中添加客户端值。

密码。最后…

打开您的 config.js 文件,将您之前复制到 Bot 对象中的访问令牌和消费者密钥的值粘贴为其各自的属性。

Bot object initialisation.

我们刚才写的是我们的机器人初始化脚本。它使用 bot 的模块中的值和参数创建并调用我们的 Bot。

它请求 Twitter 的 API 服务允许它从其数据库中检索相关数据,如 follow、tweet、remote 和其他活动。

调试和运行

要检查我们代码中的错误,请转到您的 bot.js 文件,并键入一个 console.log 命令。我们将运行这个 JS 文件来检查到目前为止提交的任何错误。我们还将添加几行代码来将 Twit 包和我们的 config.js 文件导入到我们的项目中。

This prints out our specifics to terminal.

我们现在将通过使用节点运行时服务器来编译程序。要使用 node 进行编译,我们只需输入:

**node** <program-name>.js

转到命令行或终端,将目录切换到包含我们文件的文件夹。输入上面的命令来运行你的机器人。如果一切运行良好,您将在命令行中看到以下内容:

The contents of the config.js file that was imported earlier is printed out to terminal.

该发微博了!

现在,我们将编写处理实际内容的代码部分。首先我们必须创建一个 Post 对象,并用我们的消息或 tweet 填充它。我们编写了函数 tweetStatus() ,它接受一条消息作为输入参数,并发布这条消息。

We have initialised a new Twit package build model. This helps post/tweet anything and everything you like. The function tweetStatus() has been written to facilitate the posting of a tweet.

通过这个,你可以通过改变 post JSON 中的状态的值来发布任何你喜欢的东西。无论是一个随机的笑话还是一个随机的数字,你都可以张贴任何你喜欢的东西!

编译并运行程序,看看它是否真的会发出“Hello world!”。

如果你查看一下 Twitter 开发者文档,你会发现在我们的 tweet 对象中有大量的参数要写。这让我们可以控制我们想要获得的帖子和想要丢弃的帖子。

运行程序

在我们编写 Twitter 聊天机器人的旅程中,我们已经到达了一个重要的里程碑。我们非常接*我们的目标。现在,我们要编译刚刚写好的程序。编译它将产生消息“Hello world!”发布到网上让全世界看到!按照上面显示的编译步骤,

**node** bot.js

The terminal window should like this after compiling it. If your code crashes with an error, you must have gone wrong somewhere. Don’t worry! Retrace your footsteps and rectify the mistake.

We have successfully tweeted the message Hello World without any error messages or crashes! If you are able to reach this point without banging your head on a wall or crying, Good Job!

这个函数相当简单。它所做的只是指定一个 tweeting 任务。假设有人提到你,跟踪你或者戳你。然后,你会想通过表达感激来回复。要做到这一点,我们可以编写我们的提及函数。

设置事件处理程序

JavaScript 是一种一切都异步发生的语言。类似地,我们将编写几行代码来指定当事件被触发时我们希望机器人做什么。

有一个叫做的特殊事件,它允许我们在发起拉请求时即时捕捉 Twitter 上发生的事情。看起来是这样的:

The stream statement allows us to capture a snapshot of data that’s moving around in Twitter’s databases instantaneously. This helps us detect mentions or follow requests.

这个特殊的函数检测是否有人关注了你的机器人或者在任何地方提到了它。现在让我们编写 followed()tweetEvent() 函数。

我们的探测和反应功能

让我们写下回复任何关注或提及所需的函数,好吗?

它看起来像这样:

The tweetEvent() function detects whether our username was mentioned anywhere on Twitter and replies back. I’ve put in the screen names of my two start-up accounts. You need to add your bot’s username/screen name instead.

if 语句中添加您的屏幕名称。通过这种方式,任何包含屏幕名称的推文都将被我们的机器人注册,并相应地发送回复,感谢他们提到我们。它利用了我们之前编写的 tweetStatus() 函数。简单吧?

现在,我们的接着是()函数:

A fairly simple function, the followed() function registers any follow requests or users that follow our bot account.

我们完了。恭喜你!现在,最期待的时刻到了:运行程序。

运行和测试

对于这一部分,我建议你在另一台设备上再开一个 Twitter 账户。这样,你就可以通过实际跟踪你的机器人并多次提及它来检查机器人是否有响应,而不必每次做某事时都切换帐户。

我在手机上使用 Twitter 来执行测试过程。这使它变得更容易,因为我不需要在我的笔记本电脑上不断跳转帐户。运行程序:

**node** bot.js

It gives detailed information about any follow events or mention events asynchronously. You can open the tweets.json file to look at the various components of a single tweet. It looks aesthetically unpleasing now but you can make it look way better if you add in line breaks and spaces.

使用另一个设备跟踪 bot 帐户。测试 bot 是否有任何可以修复的边缘情况。带它去兜一圈。如果你遇到任何你似乎无法克服的错误,请在下面留下评论,我会尽快回复你。

“每 10 秒发布一次”部分

(这是一个可选的片段,如果你的机器人需要每隔一小段时间(比如一个小时左右)发布一些东西,可以使用这个片段。)

我们谈到每 10 秒左右发布一条推文。为什么不是每个设定的区间!?通过使用 setInterval() 命令,我们可以轻松地执行这个任务。

通过设置一个函数作为输入参数以及以毫秒为单位的时间间隔(1000 毫秒= 1 秒),这个任务可以轻松完成!它看起来像这样:

**setInterval**(*tweetStatus*, *10000*)

简单地

如果有必要就打破它!机器人的目的没有界限!现在全靠你的想象力了。机器人被世界各地的公司和初创企业广泛用于与客户沟通。

当谈到整个客户关系部门的自动化时,机器人真的很有帮助。

利用它令人敬畏的力量来创造一些真正有用和直观的东西!超越并建立下一个超级机器人!在那之前,我们下一集再见!

里沙卜·阿南德的原创文章

让机器人学会移动,第一部分——进化算法

原文:https://towardsdatascience.com/making-a-robot-learn-how-to-move-part-1-evolutionary-algorithms-340f239c9cd2?source=collection_archive---------4-----------------------

自然如何激发工程。

这是一系列文章的第一部分。来个简短的介绍, 看我的介绍帖 。你可以在 这个 GitHub 库 上找到这个项目的代码。

技术和工程从大自然的伟大设计中获取灵感并不罕见。在这篇文章中,我将谈论遗传进化 算法,它们在机器人学以及更广泛的计算机科学中的作用。进化算法的灵感来自于进化自然 选择的自然过程。进化论是一个广为人知的理论,它解释了动物如何适应周围的环境,发展特殊的身体特征,使它们更适合那个环境。当父母混合他们的基因产生后代时,就会发生这种情况。基因也经历随机变化:这意味着新一代的生物可以发展出新的特殊特征,使它们更适应环境。适者生存解释了那些动物倾向于活得更长,繁衍后代,产生具有相同进化基因的新一代。

我们如何利用这个迷人的想法?进化算法基于相同的概念。

假设你有一个问题,你想找到一个解决方案。每一个可能的解决方案都是由一系列参数组成的。我们接着定义一个适应度 函数h ( w )。该函数定义了我们的解决方案有多好,即我们的参数组合。给定初始随机解,我们如何找到更好的解?正如进化所建议的,我们选择组合最好的解决方案,找到一个与两者共享参数的新方案。在这之后,我们在那些参数中做一个小的随机突变。我们重复这些步骤几次,找到新一代的解决方案,并测量这些解决方案使用适应度函数的效果。在一些迭代选择之后,遗传组合和随机变异将产生具有非常高性能的解。很神奇,对吧?

An iteration of a genetic algorithm.

这些算法可以用来为机器人设计一个控制器,即使我们没有关于机器人的物理信息,也可以使机器人高精度地移动。

先简单介绍一下任务:轨迹 跟踪是机器人操作手的常见任务。我们希望手臂的每个关节都及时遵循预定义的轨迹。问题是,我们不知道在这些关节上使用哪个扭矩来使它们精确地遵循这个轨迹,因为由于动力学耦合,移动一个关节可能会干扰另一个关节的运动。那么,我们如何找到一个函数来定义机器人的当前 状态,每个关节的期望运动,以及在该状态下实现该运动所需的扭矩之间的映射呢?数学上定义为 f ( 状态加速度 期望 ) - > τ,,通常由逆动力学模型得到。举个例子,想象一下:你有一个由三个关节组成的机器人手臂。每个关节都有一个特定的角度,假设每个关节都是 0 度。在时间步 t+1,你的期望轨迹希望角度为-1,0,1。因此,你希望第一个有一个负的角加速度,第二个零加速度,第三个正加速度。要实现这一点,你需要提供哪些扭矩作为输入?有人会说,一个负一,零,一个正一。但这并不容易:由于动力学耦合,如果其他关节移动,第二个关节也会移动,所以即使加速度为零,你也需要一个扭矩来*衡动力学效应!

用一系列参数逼*任何非线性函数的一种方法是使用神经网络网络。神经网络可以用一系列权重来逼*任何类型的函数,进行矩阵乘法并使用非线性。但是,我们如何找到正确的权重/参数来实现我们想要的功能呢?通常,使用梯度 下降算法训练神经网络,如反向传播。在我们的例子中,问题在于网络的误差是不可微的:这意味着,当它在输入中接收当前状态和期望的加速度时,它输出特定的扭矩。但是我们不知道应该给系统多大的扭矩。我们没有在经典监督学习中用于计算梯度下降的真实值。这意味着我们不知道如何调整我们的参数,我们不知道通常使用****偏导数使误差更小找到的正确方向。

An example of a neural network.

****选择最优解,结合进化参数,测试新解,保存最优解

这就是进化算法变得非常有用的地方。如上所述,我们可以通过计算机器人的轨迹与期望的轨迹相距多远(基本上,我们在每个时间步长对位置误差的范数进行积分)来了解解决方案有多好(即,我们输出期望扭矩的网络的参数),然后我们可以组合并随机变异最佳性能参数组合的参数,即基因。在每一次迭代中,我们创造新的解决方案,进化出最好的解决方案。然后,我们在机器人身上运行这个遗传控制器,让它跟随我们的轨迹,计算总误差。如果误差比以前低,我们有一个新的最佳解决方案,我们存储并试图进一步发展!每次迭代的步骤都是一样的:选择最佳解,合并进化参数,测试新解,存储最佳解。这样,通过遗传进化,我们找到了神经网络的最佳权重集,从而以生物启发的方式进化出了神经控制器。

有趣的是,一个只有两个隐藏层和大约 80 个神经元的小型神经网络如何能够在大约 50 次迭代中,通过进化算法演变成强大的控制器,而不需要计算一次导数。机器人因此一步一步地进化,发现移动和跟随轨迹的新方法。

在这里,我展示了一个期望的轨迹(蓝色),以及机器人如何使用经典的 PD 控制器,或者使用遗传进化神经网络控制器(红色)来跟随它。注意后者不同的有趣行为。机器人在错误的位置和错误的速度下启动,向相反的方向前进,所以控制器必须转弯。

Genetic controller (up) and classic PD controller (down) trying to follow a trajectory, starting with an error both in position and velocity. Notice how the total error (the real value under the pictures) is an half with the evolved controller.

在这篇文章中,我简要描述了我和我的一个同事如何开发一个机器人的神经控制器,使用生物启发的算法,允许它以精确的方式移动,甚至不知道它自己的动态模型。你可以在这个 GitHub 仓库中找到这个项目的所有代码。

在接下来的文章中,我将展示使用新方法实现相同结果的其他技术。请随意评论或询问任何问题!

让机器人学会如何移动,第 2 部分——在真实的野生世界中强化学习

原文:https://towardsdatascience.com/making-a-robot-learn-how-to-move-part-2-reinforcement-learning-in-the-real-wild-world-9427da7b9b21?source=collection_archive---------2-----------------------

解决物理世界的瓶颈。

这是一系列文章的第二部分。你可以在这里找到 简介第一部分 ,关于 进化 算法 。你可以在 这个GitHub资源库 中找到所描述的算法和实验的代码。

*年来,强化学习得到了重新认可。各种突破和显著的成果获得了整个科学界,甚至流行文化的关注:从 AlphaGoDQN 应用于雅达利,到最*的open ai****DOTA 2bot。

新的算法和架构已经以极高的速度发布,击败了最先进的结果并解决了新的任务。这些算法甚至在模拟的物理世界中表现得非常好,像人形和动物一样的模型学习行走、跳跃、躲避障碍,正如 DeepMind 最*展示的。

A robot dealing with the physical world.

但这些结果中的大多数都有一个共同点:它们需要巨大的计算能力时间,并且它们是在虚拟或模拟世界中执行的。为了获得好的结果,需要几十万集,由于最*高性能计算机的出现,这通常不是问题。但是强化学习遇到时间** 代价现实 世界的问题会怎么样?如果运行这些算法,例如运行一百集,它们会起作用吗?在某种程度上,这就是我们试图在机器人领域分析的。**

[……]我们工作的主要重点是在很短的时间内获得良好的结果。

正如我以前的帖子所解释的,我和我的一个同事试图解决的任务是找到方法使机器人尽可能精确地跟随给定的轨迹,而不知道它的物理参数。我们决定实现智能** 控制算法,将它们与经典的反馈控制器进行比较,首先是一个普通的 PD。所有算法与 PD 反馈控制器并行运行,试图提高其性能,从而创造出更智能的控制器。**

由于机器人不知道它的动力学参数,它不知道哪个是正确的扭矩给它的关节以实现期望的运动。因此,运动中的误差是而不是** 可微,例如,在神经网络等函数逼*器的参数中,正如我在部分 1 中所讨论的。这种问题是强化学习的常见设置,其中代理必须尝试 动作通过感知它们对环境的未知影响来学习,因此我们尝试在其他帖子中讨论的其他技术中实现一些 RL 算法。**

为了使这篇文章更短更易读,我不会介绍零强化学习理论,但是在 Medium 上也有很多资源可以学习。

我们实现了两个主要算法。一个是 Q - 学习,一个离散动作算法,我们用来在机器人移动时实时调整 PD 控制器的增益。第二个是演员** - 评论家,另一个非常流行的算法,用于寻找一个策略,这次是连续动作,控制关节上的扭矩。**

实现的所有细节都在GitHub 库中。

用于动态 PD 调谐的 q 学习。

移动机器人机械手意味着找到输入到关节的正确扭矩,该扭矩在一定范围内具有连续值。另一方面,Q-Learning 是一种算法,它学习一种状态下离散动作的 Q 值, Q(s,a),以执行预期给出最高回报(更准确地说,遵循策略的最高总回报)的动作。它的普通版本不能处理大的动作空间,更不用说连续的动作空间了。但是我们对机器人移动时动态调整 PD 控制器增益的想法很感兴趣。PD 控制器根据期望和实际位置速度之间的误差给出输入扭矩。虽然这种简单的线性控制器可以在固定 P 和 D 增益的情况下给出显著的结果,这些增益通常通过一些试错法进行调整,但其想法是让算法根据机器人的运动实时调整它们,理想情况下使控制器更加通用。经典 PD 是一种广泛使用的控制器,因为它简单且性能良好,但它无论如何都是一种线性反馈控制器,不利用任何关于轨迹或其他数据的信息,而是仅使用最后一个时间步中的误差值。

主要架构如下:动作只是简单地增加或减少 P 和 D 增益而与固定量无关。直觉是使用机器人的当前状态作为一种状态,以及最后步骤中错误的演变。为了逼* Q 函数,我们使用了神经网络:如前所述,输入是状态值,而网络的输出是各种动作的 Q 值。总奖励仅在 10 步的短时间范围内计算,因此算法的主要目标是在该范围内获得最高奖励,选择增益的更新。我们实现的奖励不是位置和速度的负误差(更高的误差- >更低的奖励),而是先前步骤范围中的先前误差和当前误差之间的差。这样做是为了部分地去相关不同步骤范围内的性能:如果算法在特定步骤范围内的学习过程中表现不佳,那么在接下来的步骤中误差也将明显较大,因为机器人连续移动,即使在接下来的步骤中算法选择了一个好的动作,也可能在没有有效理由的情况下受到惩罚。因此,如果我们只考虑短暂的后续情况之间的相对改善(T21 ),我们实际上可以利用好的行动。****

正如我在介绍中所写的,我们的工作重点是在很短的时间内获得好的结果,大约 100 集/完整的轨迹。否则,该算法可能变得对物理世界不可行,并且它被其他控制算法超越,如模型** 预测 控制迭代学习。**

我们进行了大量调整架构和超参数的实验,但最终结果往往是算法不断增加增益。这是有道理的,因为在控制理论中众所周知,更高的增益往往会带来更好的性能,但高增益意味着高功耗,有时会超过电机限制。我们试图让算法学习更多不可预测的实时调整增益的方法,以更低的能量成本获得更好的性能,但这种特定的环境,具有给定的轨迹,并没有真正给出那些结果,同时证实了控制理论中一些已知的经验概念,在没有任何先验知识的情况下通过算法学习。****

确定性政策学习的行动者-批评家

我们实现的第二种类型的算法是行动者-批评家,用来学习确定性的行动策略(然后我们也用随机策略进行了实验)。这个想法很简单:受其他论文的启发,我们决定为每个关节独立开发一个演员-评论家架构,以学习一个确定性的策略,使机器人能够更精确地跟随轨迹,补偿 PD 控制器的弱点。最*的一篇硕士论文展示了使用类似架构的 6R 机器人的有趣结果,其整体性能优于控制理论中的经典学习算法。

为每个关节实现不同的行动者-批评家策略使得算法更具可扩展性,但是在这种分散架构中学习关节的复杂动态耦合也可能更具挑战性。

整体架构如下:为了从机器人状态中提取特征,我们开发了高斯径向基函数的 2D 阵列。高斯数是根据经验选择的,均值和方差也是如此。对于每个关节,这些阵列的输入是位置和速度误差。然后将 RBF 的各种输出作为输入发送到完全连接的层(即加权和),以产生用于关节的扭矩。这些权重然后由算法调整。

作为一个试探性的 信号,添加到 actor 信号中以尝试不同的动作,我们使用了不同频率的正弦和,而不是经典的高斯白噪声,因为由于高次谐波,物理机器人实际上无法产生白噪声扭矩(白色的指的是在频谱中具有所有种类的频率,而物理系统总是低通系统)。**

我们的实验展示了这种算法是如何非常 不稳定,正如 RL 文献中所知的那样。误差向低值的明显收敛会在最后的步骤中爆发。最*的许多论文,如著名的 DDPG 算法,提出了使学习更稳定的技巧,如两个网络用于演员和评论家以不同的时间更新来计算目标,和****情节* 记忆,是最* RL 文献中非常著名的技术,允许通过将经验存储在数据结构中然后在随机结构中使用它们来解相关*******

Look, the error is approaching zero…

…expect for exploding at the next step.

而作为测试,我们的算法能够解决著名的健身房 环境、山地车、机器人上的学习阶段相当不稳定,并且该算法不能在短时间内提高机器人的性能,除了 1 或 2 个关节的机器人。我们尝试了许多不同架构和超参数的实验,但我们无法复制我们分析的论文的结果。我们怀疑,其中一个主要原因是,在那种情况下使用的机器人是由速度控制的,并且有一个内置的低级加速控制器,因此可以自行处理许多与惯性相关的问题,而我们是在没有任何其他低级控制器的情况下直接控制机器人加速的。

Interesting comparison of PD torques (red) and Actor torques (green) that improved performances. Note how the algorithm learns to be in phase with the PD, but also to give negative peaks in the first oscillations to avoid over-shooting.

所有的实验都证实了物理世界对于在模拟中表现良好的算法来说是多么具有挑战性。

我们当时没有进一步探讨这个问题,因为另一种方法,我将在下一篇文章中介绍,在很短的学习时间内产生了显著的效果,但我有兴趣在未来探索这项任务的不同技术。

所有的实验都证实了物理世界对于在模拟中表现良好的算法来说是多么具有挑战性。在机器人上执行实际轨迹所引入的时间延迟是一个瓶颈,当使用模拟的物理世界时,这个瓶颈经常被遗忘。在这些领域有活跃的研究,这通常会导致对学习的研究,即机器人学习新任务和能力的方法,只需几个例子,如最*的 OpenAI 博客和论文。

在下一篇文章中,我将展示一种不同的技术,基于基于反馈的动态模型学习和基函数神经网络,它给出了显著的结果。

你可以在这个 GitHub 资源库里找到所有实验的代码。

让机器人学会如何移动—简介

原文:https://towardsdatascience.com/making-a-robot-learn-of-to-move-intro-2bcf3c3330df?source=collection_archive---------3-----------------------

(或者:人工智能遇到机器人的地方)

ICub, a famous humanoid robot developed at Italian Institute of Technology (IIT), Genova, Italy.

当想到人工智能时,许多人脑海中浮现的流行图像通常是某种类人机器人,可能穿着闪亮优雅的白色身体,正在下棋或做其他事情。在许多著名的案例中,科幻故事将人工智能描述为体现在机器人中,或者更广泛地说,体现在合成体中。这允许人工智能与物理世界互动,移动,执行动作,等等。这也意味着机器人知道如何像人类一样灵巧地移动

在这一系列的帖子中,我将简要地谈谈我在过去一个月中一直在从事的一个项目:如何使用机器学习/人工智能技术来教会一个机器人操纵器移动,尽可能接*地遵循一个期望的轨迹。

在学术文献中,机器人和人工智能通常被视为两个不同的主题,这是有道理的。机器人,在最经典的意义上,处理建模和控制机器人机械手,或移动机器人。在工业环境中,他们经常需要做特定的重复性工作,而且需要非常高的精度。设计实现这些任务的控制架构并不简单,但这些机器人很少被视为智能的,只能完成预编程的任务。另一方面,人工智能是计算机科学的一个分支,研究如何设计模拟智能行为的算法。智能有多种定义,但在本主题中,它通常指基于传感器输入和经验采取行动的能力,以及处理不确定性和意外事件的能力。难怪最*这两个科学领域在有时被称为智能机器人的领域找到了交集。

精心设计的机器学习算法可以通过试错的方式学习移动。

正如我在引言中简要提到的,机器人机械手通常由精确设计的控制算法移动,这些算法基于对机械手的结构和物理参数的准确了解。这些包括关节之间的角度、链接的长度、质量、摩擦力等等。这些参数给得越精确,控制结构的设计就越精确。但是如果不知道这些参数会发生什么呢?这就是机器学习(ML)的由来。ML 允许计算机直接从数据中学习,并且直观地理解为什么它在这种情况下是有用的。就像人类婴儿一样,机器人可以通过移动来学习如何移动。一个精心设计的机器学习算法可以学习以试错的方式移动,进行多次尝试并分析其动作的效果。在我们的例子中,动作是施加在关节上的扭矩,效果是这些关节如何运动。

机器人的动力学模型,即描述输入如何影响每个关节运动的数学模型,可能非常复杂,尤其是在处理具有多个自由度(DOF)的机器人时。链接通常是动态耦合的:一个链接的移动、速度和加速度以复杂的方式影响另一个惯性效应、离心、科里奥利和重力效应、非线性摩擦等等。所有这些都很难用数学建模。那么,问题来了:机器人能学会移动吗?在接下来的一系列文章中,我将展示我和一位同事一起开发的不同方法、技术和算法。你可以在 GitHub 库中找到为这个项目开发的所有代码。

现在读第一部分。

通过设计让人工智能变得可理解

原文:https://towardsdatascience.com/making-ai-intelligible-via-design-837f8631622?source=collection_archive---------5-----------------------

英国诗人威廉·布莱克(William Blake)曾公开谴责伦敦的阿尔比翁面粉厂(Albion Flour Mills),称其为“黑暗的撒旦磨坊”,因为它们的自动化流程威胁到了工业革命前占主导地位的面包制造流程。新技术的破坏在那些生活受到新技术影响的人们心中产生焦虑;似乎在概念上很难,反直觉和疏远。

如今,艾通过科幻小说中的启示录式描绘,在流行文化中创造了一种怀疑的氛围。很多时候,这些问题都围绕着人工智能没有被正确理解,即使是研究人员。我们还没有开发出足够的概念模型来理解它的工作方式,部分原因是因为它还没有,也可能永远不会被完全理解。

复杂性理论是一个框架,为理解物理、生物、生态和社会宇宙提供了全新的方法。它基于这样一种观点,即一切都是由复杂适应系统组成的——从星系间系统和地球天气模式,到人类的中枢神经系统;从宇宙到纳米。人工智能可以被认为是这样一种系统,因为它表现出以下特性:

涌现 —艾不循大叙事;相反,系统中的节点以看似随机的方式相互作用。从这些交互中,模式出现,通知其他节点的行为;因此也是系统本身的问题。由生殖人工智能创造的难以想象的设计展示了这些涌现的过程。

共同进化 ——机器学习能力意味着人工智能系统能够根据节点之间的变化进行适应,并且之前的行动可以为未来的模式设计出更好的预测;因此有了术语预测分析。然而,很快,人工智能的进化将不仅能够描述预测,而且能够指导或未来的运作指明最佳路径。

连接 ——人工智能从不断扩大的传感器阵列中收集数据,监测物理世界的各个方面,如空气质量、交通流量、海浪高度;除了我们自己的电子足迹,如门票销售、在线搜索、博客帖子和信用卡交易,这些系统还可以收集模式并掌握人类大脑无法获得的洞察力。

自组织 ——人工智能通常在分布式分散网络中运行,没有自上而下的控制或等级制度,通过涌现和反馈不断自组织。美国计算机科学家、作家、未来学家和连续创业者杰里·卡普兰(Jerry Kaplan)认为,股票市场的高频交易意味着统计和机器学习技术是目前淘金的最佳工具。

混沌边缘 ——埃隆·马斯克(Elon Musk)是开放人工智能(Open AI)和最* neural ink——一项将人类大脑与人工智能融合的风险投资——的创造者。然而,尽管马斯克参与了人工智能革命,但他警告称,人工智能是“我们最大的生存威胁”。这些观点似乎自相矛盾,在乐观和危险之间摇摆不定。然而,这正是人工智能的本质:在秩序和无政府状态之间保持*衡,处于混乱的边缘。

嵌套系统 ——就像互联网或任何有机体一样,人工智能由网络的网络组成;系统的系统——其中一个级别的代理是下一个级别的代理的构建块。

即使像机器学习算法这样的复杂系统看起来像不可知的黑盒,这也不应该阻止我们与它们一起工作。加州大学设计实验室主任唐·诺曼说:“复杂既是必要的,也是可以控制的。”。

在一个充满人工智能复杂性的世界里,人类对于解释和人性化这些混合信号是必不可少的;没有人比设计师更适合这份工作。“设计师是复杂事物的大师,”开放大学的高级设计讲师 Katerina Alexiou 说;管理大量可变的外部因素,如约束、期望、满足要求、法规、假设可能性和不确定性,以创建展现“广泛的特定领域专家知识”的人工制品和系统。从这个角度来看,面对复杂性是设计过程的一个关键方法。

一旦脱离了对这种社会技术现象的愚蠢、保守的观念,设计师的角色就是加速走向计算机创造力所提供的新奇而有价值的世界。任务不是简单地掌握复杂的概念,而是以一种可理解和吸引人的方式有效地传达它们,赋予它们文化意义。诺曼说,创造意义的关键是解码或理解复杂性,并将其重新编码为概念模型,从而将复杂的现实转化为“可行、可理解的心理概念”。概念模型不应该从复杂系统的特性或能力中抽离,而是应该简化复杂性,以增加理解、可用性和功能性。他总结道,“简单不是复杂的对立面——复杂是世界的事实,而简单存在于头脑中”。

让亚马逊雇佣 AI 不带偏见

原文:https://towardsdatascience.com/making-amazon-hiring-ai-unbiased-129c5a2bef14?source=collection_archive---------17-----------------------

亚马逊招聘算法中性别偏见的新闻传遍了互联网,这为机器学习模型的可解释性主题开辟了一条新线索。让我给你讲一下这个故事的背景。亚马逊拥有至少 575700 名员工。如果员工的*均任期为 3 年,他们需要每年招聘(191900 +人数增加)。如果每 5 个面试的候选人中有 1 个被选中,每 3 份简历中有 1 个被选中,那么即使人数保持不变,他们每年也需要检查 19190035 = 2878500 份简历。这些数字——3 和 5——会因不同的情况而有所不同,因为送货员比工程师更容易雇用,但我们不要让这个计算变得不必要的复杂。重点是衡量这个数字可以有多大,以及在这个数字上花费了多少精力和资源。

如果你曾经参加过面试,你会同意简历筛选有多无聊——尤其是如果这是你的工作。这是一项基于重复模式的工作——这是人工智能非常擅长的。因此,对于像亚马逊这样的创新型大公司来说,理解自己的招聘实践并用算法复制它是完全有意义的。由于简历和工作描述是文本数据,我们需要利用 NLP(自然语言处理)。

如果我必须自己制作算法,我会使用这条管道,这可能也是亚马逊所做的。

  • 预处理简历文本
  • 用 TF-IDF 或 BM25 对文本进行矢量化
  • 为物流和工程中重复性很高的入门级配置文件训练一个监督分类器。如果数据足够,我们也可以对非入门级配置文件进行测试。分类器可以是诸如朴素贝叶斯、随机森林或深度学习序列模型之类的任何东西,并且用于分类的类别被选择和不被选择
  • 预测新简历被选中的概率
  • 过滤超过截止概率如 0.8 的恢复
  • 根据概率选择面试的前 x 个概况,其中 x 取决于我们想要聘用的候选人数量和过去的转换率

另一种方法是通过 Lucene/Elasticsearch 对简历和职位描述进行相似性匹配,并选择具有截止相似性得分的前 k 名结果。最高的结果确保了与 JD 的匹配,而不是他们与角色的适合程度,因此这种方法不是很合适。

问题是

现在让我们深入了解一下新闻:他们的新招聘引擎不喜欢女性。美国顶级科技公司尚未消除招聘中的性别差距,这种差距在软件开发人员等技术人员中最为明显,男性人数远远超过女性。亚马逊的实验性招聘引擎遵循同样的模式,学会惩罚包含“女性”一词的简历,直到公司发现这个问题。

目前人们对新闻的看法是:

  1. 人们的第一反应是人工智能有缺陷。
  2. AI 只会和数据一样有偏差。因此,艾透露,亚马逊的招聘人员可能偏向男性。
  3. 亚马逊是一家勇于披露其模式缺陷的公司。大多数公司不会这么做。

问题的解决方案

现在我想讨论的是如何使算法无偏的部分。问题是出现在女性简历中的词的重要性较低,因为这些词在精选的简历中出现得较少。亚马逊的系统会惩罚包含“女性”一词的简历,比如“女子象棋俱乐部队长”并且降级了两所女子大学的毕业生* 。还可能存在与种族词汇相关的问题。

由于性别和种族词汇不是一个人技能的指标,我们可以将这些词汇映射到一个常见的令牌,如 AAA。所以现在男子棋社队长和女子棋社队长都映射到了 AAA 的棋社队长。所以如果 AAA 的象棋俱乐部队长入选候选人,男性和女性的简历都会对这些词给予同等的重视。此外,这不仅仅是一个词的男性或女性。在完成矢量化的同时,我们还创建了双词和三词特征,在本例中,它们将是“AAA ' s chess”和“AAA ' s chess club”,这在之前包含单词 men 和 women 时会有所不同。

因此,我们所需要的是在矢量化之前的偏差消除文本预处理步骤,在该步骤中,我们将性别/种族单词映射到一个公共标记。可以通过 HR 的观察或从列表中收集此类单词的列表(并非此列表中的所有单词都有用)。在我看来,这个练习和实验并没有证明人工智能有缺陷,而是揭示了一个常识,即人工智能和数据一样好,如果数据没有准备好,它需要处理。

事后思考

令人难过的是,他们解决了偏见,但放弃了该项目,正如文章提到的那样——“亚马逊编辑了程序,使它们对这些特定术语保持中立。但这并不能保证机器不会设计出其他可能被证明具有歧视性的候选人分类方法。”像所有的研究一样,人工智能本质上也是迭代的。亚马逊花了相当多的时间来制作算法,现在这个缺陷被发现并纠正了,它导致了一个更好的算法。只有通过这些循环的改进,我们才有希望实现一个*乎完美的无偏算法。我不知道亚马逊为什么关闭它。

文章还提到,包含“已执行”和“已捕获”等词的简历得分异常高。驯服算法需要对矢量化和分类算法有深入的理解。当 TF-IDF/BM25 在简历中看到一个非常不寻常的词时,它会造成巨大的破坏。罕见词具有高 IDF 值,因此 TF-IDF 值可能变大。分类算法也可以给这些导致奇怪结果的不寻常的单词很高的权重。必须通过文本探索、模型特征重要性和用于解释训练的 ML 模型的算法来找出这样的词。一旦发现,可以手动或通过某种逻辑或通过保持较高的最小文档频率值,将它们从矢量化过程中移除。这有助于减少特征(单词)的数量,并有助于解决过度拟合问题。但这也可能会从模型中删除好的特征,从而降低数据科学家所关注的模型的准确性。

亚马逊擅长的推荐算法也存在类似问题。理想情况下,数据集应该是巨大的+变化的,并且算法应该被健壮地测试。当训练数据较少时,问题就出现了,因此过度拟合和偏差开始起作用。消除这种情况的唯一方法是拥有一个庞大的数据集,该数据集受到其自身雇佣(选定/未选定的候选人)数据的约束。我们需要估计我们可能需要多少数据,以及可能需要多少年来收集。如果所需的年数很长或不确定,关闭项目是有意义的。人们可能会认为人工智能失败了,但这可能是一个数据问题,这就是为什么亚马逊可能会暂时关闭它。还记得为什么几年前深度学习突然开始工作了吗?访问大量的标记数据,更好的计算和算法的改进。

我的看法是,亚马逊可能不仅发现了自己模式的缺陷,还发现了从事人力资源技术的其他公司模式的缺陷。这将导致未来几天更好的人力资源解决方案。

最后,更不用说,随着人工智能越来越多地应用于现实世界的问题,机器学习模型的可解释性变得至关重要。

通过评论或者通过 LinkedIn 让我知道你的想法。

  • https://www . Reuters . com/article/us-Amazon-com-jobs-automation-insight/Amazon-scraps-secret-ai-recruiting-tool-that-show-bias-against-women-iduskcn 1 MK 08g

原载于 2018 年 10 月 12 日【ml-dl.com】

让所有人都可以使用人工智能

原文:https://towardsdatascience.com/making-artificial-intelligence-accessible-to-all-d3b7351a61fa?source=collection_archive---------12-----------------------

我们很荣幸生活在一个让人工智能成为现实绝对必要的数据、计算和深度学习算法都变得丰富的时代。人工智能深度学习的发展导致了几乎所有技术领域令人难以置信的进步,并为未来带来了令人难以置信的前景。更好的医疗保健、无人驾驶汽车、智能飞行汽车、更容易获得的金融资源以及更明智的国家资源分配,只是未来十年可能实现的几个目标。

A Self-Driving Car by Waymo(A Subsidiary of Google). Source: Wikipedia

但就像早期的计算机技术一样,最先进的人工智能的使用被数百万开发者拒之门外。目前,当开发人员需要构建对象检测和识别系统时,即使是最流行的深度学习框架都需要很高的专业知识水*。深度学习算法基础的具体知识仍然是构建复杂人工智能系统的先决条件。因此,深度学习专业知识需要长时间的密集学习,对于大多数迷失在概念海市蜃楼中的新来者来说,这往往令人沮丧。“困惑”是许多新进入者用来描述他们情况的词,他们试图超越简单地训练 MNIST 和 CIFAR10 数据集以获得更好的准确性。

Source: makeuseof.com

同样,开发计算机软件最初需要对计算机和操作系统的整个体系结构有深刻的理解。这让早期的程序员感到沮丧,包括贝尔实验室的传奇开发人员。意识到抽象是工具的低级,许多专家创造了高级编程语言,包括 Fortran、C、C++等。这些语言比汇编语言更容易使用,但仍然需要很高的专业知识才能使用,因此,创新缓慢,计算机编程对大多数人来说遥不可及。几年后,像 Python、Java、.NET、PHP、Javascript 等等,使得这个星球上的每个人和组织都可以使用计算机编程。没有这些高级抽象,我们今天所知的数字世界将不复存在。

Guido Van Rossum created Python, A language that made programming more accessible

Olafenwa Moses 我喜欢把深度学习的当前状态想象成 C++早期的编程方式。

如果每个人都能编码,那么每个人都可以用合适的工具构建 AI。因此,我们都决定致力于创造工具,让任何人,从普通程序员到各个领域的行业专家,都能将人工智能集成到他们构建的每个解决方案中。

只有这样的工具存在,才能保证 AI 惠及所有人。我们设想一个智能的未来,每个应用、设备和系统都注入了人工智能。 获得人工智能是一项基本的基本人权

有鉴于此,我们开始构建 ImageAI,这是一个非常简单易用的 python 计算机视觉库,它允许完全没有 ML 或 DL 经验的开发人员只需几行代码就可以构建最先进的 AI 系统。

[## OlafenwaMoses/ImageAI

ImageAI——一个 python 库,旨在使开发人员能够使用独立的计算机构建应用程序和系统…

github.com](https://github.com/OlafenwaMoses/ImageAI)

在我们发布第一个版本以来的三个月里,ImageAI 已经被全球成千上万的开发者使用,其中许多人是第一次体验人工智能。使用 ImageAI,任何开发人员都可以在仅仅 10 行 python 代码中执行对象检测、提取和识别!,任何开发人员都可以用自己的定制数据集训练图像识别模型,只需 5 行 python 代码!。视频中的物体检测只用了 7 行代码!所有这些都有最先进的 RetinaNet、YoloV3、Resnet、Densenet、InceptionV3 和 Squeezenet 架构支持。

为了感受一下这是如何工作的,我将实际回顾一下其中的一些特性。

首先按照官方文档中的说明安装 ImageAI 及其依赖项。

第一,10 行代码中的物体检测!

下载 yolo.h5 模型文件并将其放在与您的相同的路径中。py 文件。现在,您可以在上面代码中的任何图像“image.jpg”上运行检测。

上面的简单代码会给你这个:

视频中的物体检测用 7 行代码

这会给你这个

ImageAI 还支持许多强大的功能,包括带有间隔回调的高级视频分析。它完全支持从 IP 摄像头和网络摄像头的对象检测。

所有这些惊人的功能都是完全免费和开源的。

可以通过https://imageai . readthe docs . io或者https://imageai-cn . readthe docs . io了解更多(中文版)

我们选择接受的使命是推进人工智能,使其民主化,并让地球上所有规模的个人和企业实体都可以使用人工智能。

我们正在努力构建更多的人工智能工具,并在不久的将来将它们带到更多的*台上。

您可以通过以下网站了解更多有关我们使命的信息

[## AI Commons

致力于改善和普及人工智能

科学](https://commons.specpal.science)

我们可以一起建设一个更美好的世界,人工智能将不断改变我们的生活,并且人人都可以使用。

你可以通过 @johnolafenwa 和 @OlafenwaMoses 联系我们

电子邮件:guymodscientist@gmail.com 和 johnolafenwa@gmail.com

深度学习摇头动画

原文:https://towardsdatascience.com/making-bobblehead-animations-using-deep-learning-1df2cb004429?source=collection_archive---------10-----------------------

多姿态估计目前是计算机视觉中最先进的深度学习方法,用于检测图像中的人类及其关节。在这篇文章中,我简要介绍了如何在德雷克的热线音乐视频上使用勒布朗·詹姆斯的脸制作一个有趣的小摇头 GIF,就像我上面制作的一样。基本上有 4 个主要步骤:

  1. 下载你感兴趣的视频叠加。我选择了德雷克的热线金光闪闪的视频。

2.下载您想要覆盖在视频上的孤立人脸图像。我选择了勒布朗·詹姆斯的脸。如果你的脸部图像不方便地有背景,那么使用一些图像编辑工具来裁剪背景,直到你的图像看起来像这样:

You favourite celebrity’s face without the background

3.在视频的每一帧,检测人类和他们的关节。我用的项目是https://github . com/ZheC/real time _ Multi-Person _ Pose _ Estimation,是多姿态估计的 keras Python 实现。特别是,我们感兴趣的是使用代码来定位图像中人体对象的头部。

Example of using the code from https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation to perform human multi-pose estimation on an image.

4.一旦我们有了视频帧的面部屏幕坐标,我们就在这些坐标处将孤立的面部剪切图像覆盖在视频帧的顶部。

(Left) Original video frame. (Right) Face overlay video frame.

5.对视频中的每一帧重复步骤 3 和 4。之后我用 ffmpeg 把所有的帧组合在一起,做了一个无声视频。你将不得不做更多的工作来添加和同步原始视频剪辑的音频。但是在很大程度上,你现在已经完成了一个摇头娃娃动画的可行演示!

Final demo of a bobblehead animation using multi-pose estimation

让深度学习用户友好,成为可能?

原文:https://towardsdatascience.com/making-deep-learning-user-friendly-possible-8fe3c1220f9?source=collection_archive---------4-----------------------

背景|来自《哈佛商业评论》(2018 年 3 月):尽管学者们做出了许多机器学习的发现,……但公司正在努力部署机器学习来解决实际的商业问题。简而言之,大多数公司的差距不是机器学习不起作用,而是他们努力实际使用它的

在这里,我将介绍正在努力使深度学习(机器学习的一部分)更加用户友好,以便公司更容易使用。希望这些努力将有助于减少公司在深度学习时面临的“斗争”。

那么,有没有可能让深度学习(MLP、CNN、、、甘、……)变得更加用户友好呢?更加人性化,比如从 MS-DOS 升级到 Windows 2.0(还记得 MS-DOS 吗?CP/M 克隆)。或者像从集成开发环境(IDE)到图形编程环境(GPE)。

嗯,一切皆有可能…如果你付出足够的努力。

深度学习已经变得更加容易使用

人们已经做出了很多努力,让深度学习变得更加容易:

  • DL 框架(Theano、Caffe、Tensorflow、MXNet)
  • 元框架或 API (Keras,ONNX?)
  • 可用于迁移学习的开放模型(ResNet、LeNet、VGG16、SqueezeNet、…)
  • Jupyter 笔记本
  • ….

得益于深度学习中无处不在的开源文化,所有这些都是现成的、免费的。现在,开放文化已经转移到 DL 模型,非常高性能的 NN 已经通过深度学习模型动物园提供给所有人。这些让迁移学习变得“轻而易举”。

他们还做出了其他努力,使深度学习的潜力变得非常容易,而无需任何开发工作,也不需要 DS/DL 部门或专门的工程师:

-物体识别网络服务(YOLO……)

-谷歌汽车服务

但是这些提供黑盒服务…实际上是另一个黑盒中的一个黑盒。一些公司可能不在乎,并发现该服务非常有用/经济,但一些公司会在乎,并希望掌握深度学习过程。

用户友好性?酷!!!但是为了什么?

尽管如此,目前,构建深度学习模型涉及到相当多的使用当前深度学习框架(Theano,Tensorflow,PyTorch,CNTK,Caffe2,…)或元 API ( Keras)和编程语言(Python,Java,R,…)之一的编程。这通常由经过专门培训的相当高级的用户来完成。

因此,深度学习的用户友好性可以采取以下形式:

  • 没有编程→更好,尤其是对于不怎么编程或者不知道特定深度学习框架的人
  • 直观的图形编辑器,用于设计/修改深度学习架构→更易于使用,更适合不太高级的用户

采取用户友好方式的其他动机是它可能产生:

  • 更高的工作效率—用户更有效率和创造力
  • 模型更容易理解,更容易修改/维护。

这意味着用户友好性也可能来自:

  • 拥有高效的开发/实验环境
  • 执行模型推理的集成环境,
  • DL 模型性能监控
  • 易于部署训练好的模型
  • 自动管理由 DL 模型构建过程产生的文件。

目标用户

用户友好性带来了构建定制 DL 模型的有限灵活性。如果光标在两个相反的目标之间,即可定制性 & 易用性,被正确定位,它就可以工作。但是光标的位置取决于用户的类型。

谁可能需要用户友好性:

  • 学生/自学者/教师
  • 中小企业公司
  • 希望掌握技术但需要一种工具来提高工作效率的工程师/研究人员

→需要更快地建立新的 DL 模型,并更快地修改它们

→需要进行大量实验:不同的架构、优化超参数、调整数据集……

谁不太可能需要它:

  • 深度学习的研究人员
  • 深度学习工程师,特别是在高级用途和生产环境中

用户友好的深度学习工具

到目前为止,已经有一些尝试让深度学习更加用户友好。在这里,我将介绍三种已经走了很长一段路的方法:

  • 来自深度认知的深度学习工作室
  • 索尼的神经网络控制台
  • IBM 的神经网络建模器(以前的名称:IBM 深度学习 IDE 和 DARVIZ)

所有这些工具都有一个图形编辑器来编辑深度学习模型。它们都允许从 DL 层构建深度学习架构,如 2D 卷积、2D 最大池等

另外两个用户友好的候选项将不会被回顾,因为到目前为止,它们没有提供一个图形编辑器来编辑 DL 模型:

  • NVIDIA 数字
  • 张量板(部分张量流环境)

首先,一点历史

回到过去(90 年代),当神经网络还处于初级阶段时,有一些带有 GUI 的神经网络模拟器,如:

  • 阎乐存参与的 Neuristique(【http://leon.bottou.org/projects/neuristique】)的 SN 神经网络模拟器
  • 斯图加特大学
    并行与分布式高性能系统研究所(IPVR)的 SNNS(http://www.ra.cs.uni-tuebingen.de/SNNS/)
  • 和其他人。

他们已经试图让神经网络建模更加用户友好。实际上,我使用 SNNS 作为我进入 NN 领域的第一步。这是一个很好的开源工具:

SNNS Neural Network simulator

在浅层时代之后,神经网络在深度学习端跳了进来,进入了深度时代。

深度认知深度学习工作室(DLS)

Deep Leaning Studio 是一个非常有趣的*台,它有两种操作模式:云和桌面。

这里有 DLS:http://deepcognition.ai/

深度学习工作室图形编辑器

DLS 有基本的用户友好的成分→深度学习模型编辑器,看起来像:

DL 模型编辑器的基本成分是构成 DL 模型的层(见左图)。要构建 CNN 的卷积部分,可以使用 Convolution2D、MaxPooling2D、BatchNormalization layer 等层。KERAS API 中定义的所有层都是可用的,另外还有一些层。通过将这些层拖放到编辑器工作空间上并定义这些层之间的连接图来构建模型。通过选择层,然后在编辑器屏幕右侧的侧面板中设置值,可以设置每个层的参数。

在这个视频中可以看到一个和 DLS 一起搭建 DL 模型的例子:【https://player.vimeo.com/video/198088116"

每次添加层或改变层的参数时,后台进程检查网络是否“连贯”。通过这种方式,如果你偏离了构建一个“不可能的”模型的轨道,你会在早期得到警告。

因此,深度学习工作室已经具备了让深度学习更加用户友好的条件。

基本特征

  • 使设计/修改 DL 架构变得更容易
  • 提供了 Keras API 的所有 DL 层,加上一些技术层(例如合并)
  • 拖放和复制/粘贴有助于构建大型网络
  • 允许每层的简单配置
  • 自动检查构建的 DL 网络的一致性
  • 预训练的 KERAS 层。提供 SqueezeNet!最后完全连接可以重新培训,使实施转移学习变得容易(添加参考)

高级特性

但是它有更多的特性,不仅仅是提供一个简单的编辑器,还提供了与环境其他部分的紧密集成。其中之一是:

  • 当对数据预处理、体系结构学习超配对进行几次尝试时,恢复模型(实际上是恢复、数据预处理和超配对)非常有用。
  • 集成预先训练的 Keras 模型
  • AutoML(见下文)

DLS 环境

图形编辑器不是单独出现的。在 DLS 环境中还有 4 个零件(可通过选项卡访问):

  • 数据-加载数据集并对其进行预处理
  • 超参数-编辑训练超参数
  • 培训—开始/停止和监控培训
  • 结果—分析和比较几个实验的结果
  • 推断/部署——测试模型并部署它

图形化的 DL 模型编辑器位于 model 选项卡中

所有这些功能都与构建 DL 模型有关

除此之外,环境的其他部分也提供了额外的+,将工具带入另一个维度:

  • 笔记本—使用/编程 Jupiter 笔记本
  • 环境—从命令行管理和使用 ML 环境
  • 部署—管理使用 DLS 构建的已部署 DL 模型

加上一些更注重实用性的部分

  • 项目—浏览和访问项目
  • 文件浏览器—管理环境(云或本地)中的文件
  • 数据集-预处理和加载数据集,以便作为模型输入
  • 论坛—从支持人员和其他 DLS 用户那里获得帮助
  • 视频—访问培训视频
  • 支持——从深层认知中获得支持

所以 DLS 解决方案提供的不仅仅是一个 DL 模型编辑器。这里不是展示整个 DLS 环境的地方。因此,我将仅指出几个经过深思熟虑且非常有用的功能:

  • 让几个项目同时训练,并且仍然能够在其他项目上工作
  • AutoML
  • 提供了 Jupiter 笔记本和“命令行”编程
  • 定义自定义损失函数(目标函数)的可能性
  • 云和桌面是“相同的”(可能只是一些技术上的差异),除此之外,桌面版本是免费的。

AutoML

它自动为特定数据集生成易于训练的 DL 架构。这与谷歌 AutoML(https://TechCrunch . com/2018/01/17/Google-AutoML-lets-you-train-custom-machine-learning-models-without-having-to-code/)的方法不同。我能够在叶子形状识别数据集上测试它,它工作得非常好。

生产时间—单击 REST—API 部署

一旦模型构建完成,DLS 允许将模型部署为 REST API。除了部署 REST API 之外,还生成并部署了一个简单的基于表单的 web 应用程序,用于快速测试和共享。可以从 deployment 菜单管理已部署的模型。

**

Jupiter 笔记本电脑和预配置环境

木星笔记本

DSL 提供了在 Jupyter 笔记本电脑中编程或在所提供的环境(桌面或云)中运行现有笔记本电脑的可能性。

Jupiter Notebook environment provided by DSL (Notebook Panel)

预配置环境

深度认知为深度学习程序员引入了预配置环境。这个特性将 AI 开发者从设置开发环境的头痛中解放出来。这一点尤其重要,因为许多深度学习框架和库需要不同版本的包。这些包版本冲突经常导致调试时间的浪费。

Environment panel in DSL

目前最新版本的 Tensorflow、Keras、Caffe 2、Chainer、PyTorch、MxNet 和 Caffe 已经推出。这些使得开发者能够非常快速地使用各种不同的 github AI 项目。这些环境是隔离的,支持 CPU 和 GPU 计算。

最终,这些将开发人员从 devops 工作中解放出来,帮助他们专注于真正的人工智能模型构建和优化工作。

Deep Learning Studio 中预先配置的环境不仅可以访问终端,还可以访问基于 VS 代码的开源组件的成熟的基于 web 的 IDE。

One programming Environment provided by DSL (Environment panel)

这两个特性(Jupiter 笔记本和预配置环境)是真正的资产。它们使得使用深度认知云和 GPU 来完成任何深度学习、机器学习或数据科学任务成为可能→不会将人们局限在仅编辑的解决方案中。

出来的是什么

  • 以 Keras H5 格式保存的训练模型
  • DLS 模型。yaml 格式,包含模型的 DLS 特定描述

DLS 背后的技术是什么

  • 阿帕奇 MXNet
  • Keras like API

现在还缺少什么

  • 可能加载其他预训练的 Keras 模型→无法使用动物园模型中的模型
  • 将模型的代码导出到 Python/Keras
  • 当存在分类问题时,使用混淆矩阵查看性能
  • 一份详细的文档(这不是一个大问题,因为环境使用起来非常直观)

索尼的神经网络控制台

索尼的神经网络控制台(NNC)似乎最初是一个内部工具,已经与相关的内部 DL 框架神经网络库(https://nnabla.org/)一起被制成产品,在这里https://github.com/sony/nnabla开源发布。因此,NNC 应该从这种内部经验中受益。

这里有 NNC:https://dl.sony.com/

神经网络控制台图形编辑器

DL model GRAPHICAL EDITOR in Neural Network Console

NNC 的模特编辑和 DLS 的编辑工作方式差不多。可以添加到 DL 模型的层特定于索尼的 DL 框架神经网络库(NNL)。

以下是 DLS 的一些特点和差异:

  • 提供了逻辑处理层— LogicalAnd、LogicalOr、…
  • 提供了循环层(但没有提供示例)—可用于构建残差网络和递归神经网络
  • 不同的数据预处理可以通过模型中的图层或数据集选项卡来完成。
  • 超参数可以在配置选项卡中设置
  • 评估选项卡有一个有用的混淆矩阵,用于分类问题

神经网络控制台环境

与 DLS 类似,NNC 提供了一个超越 DL 模型编辑器的环境。

图形编辑器不是单独出现的。还有 4 个面板(在 NNC 环境中:

  • 仪表板—监控资源使用情况
  • 数据集-预处理和加载数据集,以便作为模型输入
  • 作业历史记录—监控已结束的培训作业

NNC 的弊端

  • 底层框架目前是相当“机密”的,几乎没有在索尼之外使用的迹象
  • 层列表是受限制的并且是“非标准的”(正如 Keras 层 API 可能是)
  • 预先训练的 DL 不能作为层使用,所以 transfert 可能不容易设置
  • 无法加载经过训练的 KERAS 模型
  • 没有提供用于轻松部署 DL 模型的机制

关于 NNC 的视频请看:【https://www.youtube.com/watch?v=-lXjnaUSEtM】T2

IBM 的神经网络建模器

神经网络建模器已经有了几个名字:DARVIZ 和 IBM 深度学习 IDE(【https://darviz.mybluemix.net/#/】T4)。精彩的 IBM 营销或者我们应该称之为混乱。它现在是沃森工作室套房的一部分。

NNM 的目的与前两种工具不同。它意味着在最后产生代码(Theano,Tensorflow/Keras,Caffe 1)。现在,该代码将被 Watson Studio suite AFAIU 中的其他工具使用。

在这里有 NNM:https://darviz.mybluemix.net/#/dashboard或者在沃森工作室https://data platform . IBM . com/docs/content/analyze-data/ml _ dla as . html?观众=博士&背景=精炼厂

神经网络建模器图形编辑器

给 NNC 提供了一个不错 DL 模型图形编辑器:

DL model GRAPHICAL EDITOR in Neural Network Modeler

以下是 DLS 的一些特点和差异:

  • 自动最佳架构搜索
  • 不同的数据预处理可以通过模型中的图层或数据集选项卡来完成。
  • 超参数可以通过 Watson Studio 套件中的工具进行优化

NNM 资产

  • 集成到数据科学/机器学习套件中,因此可能会受益于套件的其他功能,如部署机制

NNM 的缺点

  • 仅生成 DL 模型的代码,所有其他功能都在 Watson Studio 套件中的某个地方(您必须拥有并了解该套件)
  • 仅在云上可用(可能很快仅在 Watson Studio 套件中可用?)

有关 NNM 的更多信息,请参见这篇 Medium 文章:https://Medium . com/IBM-Watson/accelerate-your-deep-learning-experiments-with-IBM-neural-network-modeler-DD 0 c 92 FBA 814

关于 DARVIZ(NNM 的旧称)的视频请看:【https://www.youtube.com/watch?v=mmRw_MuMPC4】T2 值得为【孩子】(是的!)呈现出来。出色的沟通和商业技巧!

结论

深度学习的用户友好性即将实现。但是在不久的将来可能会走得更远。

索尼的 NNC 是一个很好的快速建立 DL 模型的解决方案,并提供了一个相当完整的环境。

IBM 的 NNM 是一个更受限制的解决方案,其主要目标是生成代码供其他地方使用。其他地方是 Watson Studio 套件,因此它的效率将取决于 WS 套件的效率以及它在 WS 套件中的集成。

深度认知的 DLS 是一个经过深思熟虑的解决方案,它提供了一个非常完整的环境,并且不局限于深度学习模型的图形编辑。它面向“事实上的”标准,这使得它比索尼基于“机密”框架的 NNC 更有趣。

功能对照表

我已经在 socialcompare.com 网站上创建了一个功能对照表。目的是提供一个易读的表格来总结哪种产品具有哪些特性。其他人也可以做出贡献。

* [## 深度学习编辑器| Tableaux comparatifs-social compare

比较深度学习工作室控制神经网络控制台控制深度学习 IDE 控制 NVIDIA 数字控制注释

socialcompare.com](http://socialcompare.com/fr/comparison/deep-learning-editor-4amg7j1f)

以下是截至 2018 年 4 月底的屏幕截图:

*

伟大假说的形成

原文:https://towardsdatascience.com/making-great-hypothesis-588f93f52206?source=collection_archive---------5-----------------------

比尔和梅林达·盖茨最喜欢的书factfulity将如何超越你的数据科学实践

动机

到目前为止,数据科学教育主要关注数据争论、假设检验和因果推断。我们很少听说前一步——假设形成。

形成错误的假设代价高昂

一旦你开始测试一个假设,你可以花费几个小时、几天、几个月甚至几年的时间来收集数据、清理数据、可视化数据、构建花哨的预测和因果模型,但都无济于事。你最喜欢的假设根本不成立——什么都不重要!

这标志着你身份危机的开始。你开始为你浪费的时间感到抱歉。你人生中第一次开始质疑自己的聪明。“也许我没有我 SAT/GRE/LSAT 第 99 分显示的那么聪明,”你害怕地说。但是你已经投入了这么多。真的可以这么轻易认输吗?你的手指无法抗拒轻微调整设计的冲动,看看 1000 版本是否是符合你理论的神奇设计。你认为你是一个诚实正直的公民。但是在你对意义的执着追求中,你已经把自己置身于 p-hacking 的土地上了。

它发生在我们最好的人身上

问题是:我们怎样才能形成更好的假设?上周偶遇刚好合适的书: Factfulness 它讲述了“我们对世界错误的 10 个理由,以及为什么事情比你想象的要好”。我个人犯了不少单子上的错误。我认为,形成更聪明假说的关键在于深入理解我们的系统性偏见。通过避开这些诱人但被误导的假设,我们可以为自己节省大量时间和痛苦。

免责声明

这个博客帖子是一个备忘单,为自己使用和与朋友分享而创建。如果你觉得有用,我强烈建议你在亚马逊上购买这本书。我简直无法公正地评价我多年来读过的最伟大的*装本。我相信你会对基于数据的精彩故事感到高兴。你甚至可能会发现许多本备忘单中没有的见解。

1.差距本能

定义

通过二元透镜看世界的人类冲动。

例子

最低 x%对最高 y%

巴西最富有的 10%的人赚取了总收入的 41%。令人不安,对吗?听起来太高了。我们很快会想象一个精英阶层从其他人那里窃取资源。媒体用最富有的人——通常不是最富有的 10%,但可能是最富有的 0.1%,即超级富豪——及其船只、马匹和巨大豪宅的图片来支持这种印象。

是的,这个数字高得令人不安。同时,已经很多年没有这么低了。统计数据经常被戏剧性地用于政治目的,但重要的是,它们还能帮助我们驾驭现实……事实上,即使在世界上最不*等的国家之一,也不存在差距。大部分人都在中间。

控制差距本能

  • 当你听到一个缺口的时候,就要识别出来。
  • *均值可能具有欺骗性。尝试绘制分布图(随着时间的推移)。
  • 大多数学者关注*均治疗效果,并使用异质性效果作为稳健性检查。在真实的商业环境中,你也许应该把异质效果放在前面和中间。

2.消极本能

定义

"认为世界正在变得更糟的巨大误解。"

例子

  • 调查显示,人们认为极端贫困已经恶化,犯罪率上升。通过使用来自世界银行和联合国的几十个结果变量,作者表明这是不正确的。(我没有张贴这些情节,因为我可能侵犯了版权。但是我强烈建议你自己去看看。)比如 2017 年的赞比亚比 1891 年的瑞典好。

诱惑

  • “大多数事情过去都是更糟,而不是更好。但是对于人类来说,忘记事情真正的“过去”是什么样子是极其容易的"
  • 选择性报告

如何控制我们的消极本能

  • 认可选择性报告——因为关于逐步改善的故事并不畅销。
  • 更多新闻!=更痛苦。"更多的坏消息有时是由于对苦难的更好监测,而不是世界的恶化."
  • 认识到大多数人都把过去浪漫化了。
  • 不要执着于水*,要好奇改变的方向。绘制一些时间序列数据,看看过去是否真的更好。

3.直线本能

定义

  • 过度依赖线性模型
  • 过度依赖线性外推

例子

“认为‘世界人口正在不断增加’的巨大误解"

诱惑

  • 作者举了许多例子来说明世界上不同收入和职业的人是如何喜欢假设直线的。
  • 个人认为,一个相关的原因是线性模型受到了很多学术上的关注。所以如果你使用线性模型,你可以调用许多花哨的证明和很酷的技术来为你的策略辩护;而非参数仍然相对研究不足。

解药

  • 作者:请注意,数据可以以多种形状分布:直线、S 形弯曲、A 形滑动、驼峰、指数等。他们还谈到不同的社会和经济力量如何产生不同的形状。它们很有趣。自己去看吧:)
  • 我:对产生这些数据的底层力量有了更深入的了解。结构模型 s 虽然复杂而笨拙,但有时却非常有用。

4.恐惧本能

定义

恐惧是有用的,但前提是它指向正确的事物。恐惧本能是理解世界的可怕向导。它让我们把注意力放在我们最害怕的不太可能发生的危险上,而忽略了实际上最危险的东西。

例子

作者绘制了许多关于自然灾害、飞机和汽车事故、战争和冲突等的时间序列。

诱惑

  • 将媒体报道频率误认为真实频率。
  • “风险=危险*暴露”。大多数人忘记了暴露的部分,并且不必要地担心他们很少暴露的事件。

解药

  • f(媒体报道)!=(事件)
  • “风险=危险*暴露”

5.尺寸本能

定义

我们倾向于夸大事情,尤其是当:

  • 它与我们有关
  • 一个统计数据被挑选出来

结果

规模本能的两个方面,加上消极本能,使我们系统地低估了世界上已经取得的进展。

例子

在关于全球比例的测试问题中,人们一致认为大约 20%的人的基本需求得到了满足。大多数情况下,正确答案接* 80%,甚至 90%。同时,我们系统地高估了其他比例。我们国家的移民比例。反对同性恋的人的比例。在每一种情况下,至少在美国和欧洲,我们的解释都比现实更加戏剧化。

解药

将统计数据放在上下文中:不要报告绝对数字,尝试报告百分比。

6.泛化本能

定义

需要进行一些概括。类别对于我们的功能来说是绝对必要的。它们给我们的思想提供了结构。想象一下,如果我们认为每一件物品和每一个场景都是独一无二的——我们甚至不会有一种语言来描述我们周围的世界。”但当我们过度概括时,这就成了一个问题。

负面后果

当你错误地将一组结果推广到另一组时,你就冒了风险

  • 以为有商机,其实没有;
  • 以为有商机就没有商机。

例子

每次怀孕都会导致大约两年的月经不调。如果你是月经垫的制造商,这对生意不好。所以你应该知道,而且应该为全世界每个妇女的婴儿数量下降而感到高兴。你应该知道,而且也应该为越来越多受过教育的女性离家工作感到高兴。因为在过去的几十年里,这些发展已经为你的产品创造了一个爆炸式的市场,在现在生活在 2 层和 3 层的数十亿经期妇女中。

解药

假设你不正常,其他人也不是白痴

  • 寻找更好的方法将人们分类。
  • 跨组:寻找相似之处,但不要将结果从一组归纳到另一组,除非你有足够的证据支持它
  • 组内:寻找差异
  • 注意轶事证据:他们通常是离群值
  • 注意没有数据的英文报告。例如,多数可以是 50.00001%

7.命运本能

定义

声称 X(人、国家、宗教、文化)注定有某种结局,因为这些都是不可改变的特性。

诱惑

  • 事实上,国家、宗教和文化正在缓慢但稳定地转变。有时,人们会把缓慢的变化误认为没有变化。
  • 许多畅销书都在延续这个神话,这也于事无补。

消极后果

刻板印象、歧视和错失的机会。

解药

  • 变化慢!=无变化
  • 已经抛弃了文化/宗教命运的讨论。

8.单一视角本能

定义

当我们在寻找一个能解释一切的解释时。

诱惑

人们,尤其是学者,喜欢简单、优雅的解决方案。

解药

拿个工具箱,而不是锤子

  • 做你自己的魔鬼代言人。试着收集你最喜欢的叙述的反例。
  • 认识到现实是复杂的。由此推论,要提防简单的想法和简单的解决方案。
  • 永远不要相信单一来源——即使那个来源是某个领域的专家。认识到专家只是他们研究领域的专家。调查显示,作者在其他问题上也犯了同样的错误。
  • 小心空想家。甚至民主也不是唯一的解决方案。

9.责备的本能

定义

"为不好的事情发生寻找一个清晰、简单的原因的本能."

例子

不缺例子:)所以我就略过了。

消极后果

  • 夸大任何个人/团体的重要性。
  • 有损于对问题的理解,也不利于提出建设性的解决方案。

解药

忍住责备所有人的冲动。因为问题是当我们识别出坏人时,我们已经不再思考了。如果你真的想改变这个世界,你必须了解它实际上是如何运作的,并且忘记打任何人的脸。

  • “找原因,不找小人。”
  • “找系统,不找英雄。”

10.急迫的本能

定义

“机不可失,时不再来!明天可能就来不及了!特价!仅限今天!”

诱惑

事实证明,这是一个有效的点击诱饵和增长黑客。它触及了我们最原始的恐惧本能。

消极后果

你在做次优的选择:在真正重要的任务上花费更少的时间和精力。

解药

  • “坚持数据”具有相关且准确的紧急程度衡量标准。
  • “当心算命先生,因为任何对未来的预测都是不确定的。”
  • “警惕激烈的行动,”因为副作用可能很难消除。更好的方法是进行小的、渐进的改进,并评估每一步的补救措施。

结束了

您已到达此备忘单的结尾。但从某种意义上来说,这只是一个开始。

在我自己的研究中,我已经发现自己陷入了几个这样的陷阱。我多么希望这本书是在我刚开始攻读经济学博士时写的。实际上,它可以拯救我多年的生命。谢天谢地,认识到自己的错误并从中吸取教训永远不会太晚:)有了这些见解,我就能避开诱人但不真实的假设。

你在实践中遇到过哪些陷阱?请在下面留下你的评论,这样我们就可以互相关注了。

下次见!

相亲:让有视觉障碍的人更容易接触到移动约会*台

原文:https://towardsdatascience.com/making-mobile-dating-platforms-more-accessible-to-individuals-with-visual-impairments-3b77f8f8cbdd?source=collection_archive---------2-----------------------

想象一下,在看不到个体的情况下,在 Tinder 或 Bumble 这个已经疯狂的世界中导航。对于任何不熟悉屏幕阅读器输出的人来说,这听起来可能是这样的:

有人知道查德长什么样吗,他喜欢什么,或者你想在他身上左右滑动吗?不,我不这么认为。

作为一个有视力的人,我从来没有真正想过一个有视力障碍的人在移动约会领域可能会遇到的问题。我的盲人朋友坐在我的办公桌前,把他的手机递给我,让我对个人资料中的个人进行口头描述,这让我意识到使用带有屏幕阅读器的约会*台是一种多么糟糕的用户体验。

我半开玩笑地对我的朋友说,为了让他别来烦我,好让我回去工作,我打算写一个程序,自动为他的个人资料照片加标题。我们笑了几秒钟,然后我们想起我们都是计算机科学的博士生,实际上可以相对容易地完成这一点。让他截屏一个个人资料,将图像发送到服务器,做一些计算机视觉魔术,还有 Viola,这不会太难!,我们可以发送回一个标题,它可以提供更多关于谁实际上在个人资料中的信息。

这个想法是在新学期开始时产生的,我参加了几门机器学习课程,所以我向我的一个小组提议,我们做这个项目作为一个学期的项目。他们喜欢这个想法。

首先,我们决定对大学生进行一项调查,看看人们在约会档案中寻找什么样的信息。对于每个类别,人们可以在 tinder 档案中选择最多三个对他们来说重要的选项。

星号:这项调查的收集方式非常不正式,而且它也涉及一般的大学生群体,而不是更具体的视觉障碍人群。不要把这些图表视为彻底探索的科学结果,而是在他们评估约会档案时对年轻人大脑的简要观察。

Survey results from primarily college students on what they look for when they evaluate a tinder profile. The data is split into 4 graphs that show people are the most interested in seeing an individual’s hair color, body shape, whether they are indoor or outdoor, and if they are smiling or not.

不出所料,调查结果中出现了一些模式。当评估简档时,用户发现简档中关于个人的几个特征是重要的。他们通常想知道头发的颜色和长度,个人是否在微笑,照片是在室内还是室外拍的,以及个人的体型。

由于这是一门关于统计机器学习的课程,教学大纲只是勉强进入深度神经网络,所以我们采取了一种相对幼稚的方法来制作字幕。基本上,我们将任务分成几个二元分类器(长发/短发、浅色/深色头发、室内/室外、微笑/不微笑等),每个小组成员负责一个分类器。下面的视频展示了我们开发的系统:

截屏拍摄后,我们会等待手机接收到一个新的截屏添加到截屏文件夹中的事实,这是一个明显的延迟。正如所展示的,这个系统仍然是一个原型。仍然有大量的错误需要克服和改进,但是我认为我们的系统在演示概念验证方面做得很好。

很明显,下一步是摆脱简单的分类器,而是使用在 image net 上训练的深度神经网络来为图像添加标题。一旦该版本实现,我将更新这篇文章,并给出一些更彻底和明确的结果,甚至可能是一些来自视觉障碍用户的反馈。

因此,不可避免地,你们中的一些人会问一个相对不敏感但并非完全不相关的问题:“这个人的长相到底有什么关系?反正他看不见他们。”这很重要,我保证。从一个人的个人资料中可以收集到比外表更多的信息。你可以从环境中获得信息,乍得,例如,是一个喜欢船和越野车和四轮车的户外运动者,也许这是你的事情,也许不是,但如果不能看到照片,信息是无法访问的。你也可以通过个人资料中的照片暗示个人生活方式的某些方面。如果个人资料包括五张赤膊健身房自拍,而你又不是特别喜欢去健身房,也许这些信息会帮助你决定这个人是否值得一试。

所以我想这个故事的寓意是,可悲的是,可访问性不是设计师在构建技术时通常会考虑的事情。这给许多人带来了挑战,也给技术世界制造了障碍。计算机视觉已经被证明是一种不可思议的工具,可以用来为有视觉障碍的人拆除一些障碍,然而它不应该走到那一步。在我看来,可访问性的最大问题之一就是简单的认知。在我的计算机科学课上,可访问性从未被提及。教授只需花 15 分钟介绍通用设计的概念(即我们应该设计出每个人都可以使用的东西)。

制作音乐:当简单概率胜过深度学习

原文:https://towardsdatascience.com/making-music-when-simple-probabilities-outperform-deep-learning-75f4ee1b8e69?source=collection_archive---------5-----------------------

When a simple contestant competes against a deep army.

概述:我是如何发现一个利用深度学习制作音乐的问题,并通过创建自己的原创模型来解决的。

概述

问题 :我是如何发现使用深度学习技术生成流行音乐的问题的。

解决方案: 我如何构建了一个原创的音乐制作机器,它可以媲美深度学习,但解决方案更简单。

评价: 我是如何创造出一个评价指标,能够从数学上证明我的音乐比深度学习的音乐“听起来更像流行”。

一般化 : 我是如何发现一种方法来一般化我自己的模型,应用于创作音乐以外的情况。

也请查看该项目的 YouTube 版本:

编辑:我已经关闭了网站(EC2),因为我必须继续支付费用。

笑点是

我做了一个简单的概率模型来生成流行音乐。有了客观的衡量标准,我可以说这个模型产生的音乐听起来更像流行音乐,而不是一些由深度学习技术产生的音乐。我是怎么做到的?我这样做,部分是因为我把注意力集中在我认为流行音乐的核心:和声和旋律之间的统计关系。

Melody is the vocals, the tunes. Harmony is the chords, the chord progression. In the piano, the melody is played by the right hand, and the harmony by the left.

问题是

在深入探讨他们的关系之前,我先来定义一下问题。我开始这个项目的简单愿望是利用深度学习(外行人称之为“人工智能”)创作流行音乐。这很快让我想到了 LSTMs(长短期记忆单元),这是一种特殊版本的递归神经网络(RNN),在生成文本和制作音乐方面非常受欢迎。

[## 如何在 Keras 中使用 LSTM 神经网络生成音乐

使用 LSTM 神经网络创作音乐的介绍

towardsdatascience.com](/how-to-generate-music-using-a-lstm-neural-network-in-keras-68786834d4c5)

但是随着我对这个主题了解的越来越多,我开始质疑应用 rnn 和它们的变体来产生流行音乐的逻辑。这个逻辑似乎是基于对(流行)音乐内部结构的几个假设,我并不完全同意。

一个具体的假设是和声和旋律之间的独立关系(以上是对两者的描述)。

以多伦多大学 2017 年的出版物为例:来自 Pi 的歌曲:流行音乐一代的音乐似是而非的网络(初航等)在这篇文章中,作者明确地“假定……和弦是独立的给定的旋律”(3,斜体是我的)。基于这一规范,作者建立了一个复杂的多层 RNN 模型。旋律有自己的生成音符层(键和按键层),它独立于和弦层。除了独立性之外,这种特殊的模式还决定了一代人在旋律上的和谐。这只是意味着和声依赖于音符生成的旋律。

Hang Chu, et al.’s stacked RNN model. Each layer is responsible for addressing different aspect of a song.

这种建模对我来说感觉很奇怪,因为它似乎不太接*人类创作流行音乐的方式。就我个人而言,作为一名受过古典音乐训练的钢琴家,在没有首先考虑和声音符的情况下,我绝不会考虑写下旋律音符。这是因为和声音符定义和限制了我的旋律音符。很久以前,Axis of Awesome 在他们曾经风靡一时的 YouTube 视频中展示了这个想法。

Video demonstrating how different pop melodies are all dependent on the same four chords.

他们的视频展示了西方流行音乐的一个定义属性:和声,或那四个和弦,强烈地决定了旋律将会是什么。在数据科学语言中,我们可以说条件概率调节和解决了和声和旋律之间的统计关系。这是因为旋律音符自然地依赖于和声音符。因此,有人可能会认为和声音符在本质上限制并允许在特定的歌曲中选择旋律音符。

解决方案

我喜欢构建自己的解决方案来解决复杂的问题。因此,我决定构建自己的模型,以自己的方式捕捉音乐数据丰富的底层结构。我开始这样做的时候,关注的是支配不同种类音符之间关系的预定概率命运。一个例子就是我上面提到的——和声和旋律之间的“垂直”关系。

(处理)数据

对于数据,我使用了 20 首不同的 midi 格式的西方流行歌曲(完整的歌曲列表可以在这里找到:www.popmusicmaker.com)。

使用 music21 python 库,我基于马尔可夫过程对这些 midi 文件进行了大量(但不完全)处理。这使我能够提取输入数据中不同类型音符之间的统计关系。具体来说,我计算了音符的转移概率。这基本上意味着,当音符从一个音符过渡到下一个音符时,我们可以得到该过渡发生的概率。(下面有更深入的解释)

midi: a digitized version of a song.

首先,我提取了和声音符和旋律音符之间的“垂直”转换概率。我还根据数据集计算了旋律音符之间所有的“水*”转换概率。我也为和声音符完成了这个任务。下图展示了音乐数据中不同类型音符之间的三种不同过渡矩阵的示例。

Transition Probabilities, examples. Top: between Harmony and Melody notes — Middle: between Melody notes — Bottom: between Harmony notes

模型

使用这三个概率矩阵,我的模型将遵循这些简单的方向。

1.从数据中随机选择一个和声音符。

2.使用上面看到的第一个概率矩阵,根据那个和声音符选择一个旋律音符。

3.使用上面看到的第二个概率矩阵,根据旋律音符选择一个旋律音符。

4.重复步骤 3,直到某一截止线。

Steps 1–4.

5.使用第三概率矩阵基于先前的和声音符选择新的和声音符。

6.重复步骤 1-4,直到某一截止线。

Steps 5–6.

这是这 6 个简单步骤的一个具体例子。

  1. 机器随机选择和声音符 F。
  2. 和声音符 F 有 4 个旋律音符可供选择。使用第一转移矩阵,它可能选择旋律音符 C,因为旋律音符 C 具有相对高的可能性(24.5%的机会被选择)。
  3. 旋律音符 C 将转向第二过渡矩阵以选择下一个旋律音符。它可能会选择旋律音符 A,因为它的概率很高(88%)。
  4. 步骤 3 将继续生成新的旋律音符,直到预设的截止线。
  5. 和声音符 F 将转到第三个过渡矩阵来选择下一个和声音符。它可以基于它们相对高的可能性选择和声音符 F 或和声音符 C。
  6. 将重复步骤 1-4,直到某个预设的截止线。

以下是通过这种架构产生的流行音乐的例子(来自www.popmusicmaker.com):

估价

现在到了困难的部分——如何评估不同的模型。毕竟,我的文章声称简单概率可以胜过神经网络。但是我们如何从一个神经网络模型评估我的模型呢?怎么才能客观的宣称我的音乐“更像流行”而不是人工智能制作的音乐?

要回答这个问题,我们首先要问的是,最初到底是什么定义了流行音乐。我已经给出了第一个定义:和声和旋律之间的统计关系。但是流行音乐还有另一个定义元素。这就是为什么流行音乐有一个清晰的开头、中间和结尾(引子、独唱、过渡、合唱、结尾等等)。)在一首歌曲中重复多次。

例如,“让它去吧,让它去吧,不能再让它回来了…”是在音乐的中间部分,而不是开始和结束。这一段在歌曲中重复了三次。

考虑到这一点,我们可以使用所谓的自相似矩阵。简单地说,自相似矩阵从数学上直观地显示了歌曲的开头、中间和结尾。下面是歌曲的一个自相似矩阵,从电影里慢慢落下一次。

Each tiny block represents every note played in four beats of time in the song. Each big block in 45 degree angle represents a segment of a song.

第一个蓝色集群代表歌曲的开始部分,而下一个黄色集群代表该歌曲的另一个片段。第一个和第三个聚类由于它们的(自)相似性而具有相同的阴影。第二个和第四个聚类由于其自身(相似性)而被相同地着色。

我做了 20 个这样的自相似矩阵,是我用来作为输入数据的 20 首流行歌曲。然后我让我的机器尽可能忠实地复制它们的结构(*均)(更多细节,请在评论中提问!).

结果

结果很说明问题。在自相似矩阵之前,我的机器产生的声音没有内部重复结构。但是在复制了输入数据的结构之后,你可以在我生成的音乐中看到这些边界,如下所示。

Before and after utilizing the self-similarity matrix.

与此相比,多伦多大学神经网络产生的流行音乐的自相似矩阵看起来是这样的:

这就是你如何比较和评估不同的模型——基于它们的自相似矩阵的边界!

一般化

我想解决的最后一个问题是泛化。通过概括,我问:我们如何才能概括我的数据驱动音乐模型,以便它可以应用于制作流行音乐以外的情况?换句话说,有没有另一个人造发明与我的流行音乐制作机有着相同的架构?

经过深思熟虑,我发现还有一种人类文化创造的数据内部也有这种结构——那就是流行歌词!

举个例子我将是爱德华·麦肯。它的一个片段是这样的:

我将是你哭泣的肩膀
我将是爱情的自杀
当我长大后我会变得更好
我将是你生命中最大的粉丝

让我们分解歌词,使用机器学习中相同的生成上下文。我们可以将“I'll be”作为语言模型中的第一个输入单词。这个二元模型会用来生成‘你的’,生成‘哭’,导致‘肩膀’。

接下来是一个非常重要的问题:下一句话的第一个词(另一个‘我会是’)是否依赖于最后一个词‘肩膀’?换句话说,第一句的最后一个字和下一句的第一个字有关系吗?

对我来说,答案是否定的。由于这个句子以‘should’结尾,下一个单词是基于前一个单词‘I’ll be’生成的。这是因为每个句子的第一个词被故意重复,表明每个句子的第一个词之间存在类似的条件关系。这些第一个单词成为下一个单词序列的触发点。

我发现这是一个令人着迷的发现。流行音乐和流行歌词似乎都将这种架构作为其数据的内部结构!是不是超级迷人?

你可以访问我的网站www.popmusicmaker.com来创作流行音乐和流行歌词。

这个项目的 github 在这里:【https://github.com/haebichan/PopMusicMaker

如果您有任何问题,请随时联系我@【hj2444.columbia.edu

我对开源软件的第一个贡献

原文:https://towardsdatascience.com/making-my-first-open-source-software-contribution-8ebf622be33c?source=collection_archive---------8-----------------------

开源软件汇集了许多无私的程序员,他们自由地向世界发布他们的代码。作为一名利用开源软件谋生的程序员,我一直想为开源社区做点贡献。在过去的这个周末,我在全球熊猫文献冲刺中实现了这个目标。

我知道我不必等待这个全球性的事件来做出开源的贡献。事实上,我经常爬上我经常使用的开源软件的发布板。然而,这是我第一次为开源项目做贡献,得到社区的支持和详细的指导真的很有帮助。也给了我一个很具体的任务,也有帮助。

pydata TO group 在多伦多的 hacklab space 举办了一次活动。组织者给我分配了熊猫。DataFrame.all 文档,但在开始之前,我必须设置我的环境。熊猫的网页上有很好的说明,可以在这里找到。

[## 为熊猫做贡献-熊猫 0.22.0 文档

如果你不是开发人员,对文档做出贡献仍然有巨大的价值。你甚至不必…

pandas.pydata.org](http://pandas.pydata.org/pandas-docs/stable/contributing.html#creating-a-python-environment-pip)

我更喜欢用 venv 管理我的虚拟环境,尽管有很多警告,但一切都运行得很好。我现在可以开始写文档了,开始如下:

我运行了下面一行代码来产生文档字符串输出。

python ../scripts/validate_docstrings.py pandas.DataFrame.all

在第一组散列标签下面是文档字符串当前的样子,在第二组下面是当前的错误列表。第一个错误是:

Docstring text (summary) should start in the line immediately after the opening quotes (not in the same line, or leaving a blank line in between)Use only one blank line to separate sections or paragraphs

我得到了一个与这个文档字符串相关的行,当我阅读代码时,遇到了困惑。

我期待的是更接*实际医生的样子。经过一些调查后,我意识到我正在失去装饰者的魔力。appender decorator 追加在 _bool_doc 变量中找到的内容。_bool_doc 变量本身引用了从替换装饰器中给出的参数中插入的变量。

当我跟踪 _bool_doc 变量时,我发现了第一个错误的来源。

%(desc)的变量占位符在左引号后有一个空行。这是不允许的。所以我去掉了这条空行,瞧!我已经排除了第一个错误。

我一直在努力纠正这些错误,然后面临一个挑战。我正在完成 DataFrame.all 的文档,但它实际上与 DataFrame.any 方法共享文档。因此,当我需要放入“另请参阅”和“示例”部分时,我必须向这些文档的实例化函数添加参数。这将允许这两个相关的方法共享它们文档的模板,但是在需要的地方有所不同。

我将示例和 see_also 参数添加到 _make_logical_function 中,并将它们作为变量传入。

这是一个传递给生成文档的参数的变量的例子。

请注意我是如何将 _all_doc、_all_examples 和 _all_see_also 变量添加到 cls.all 对象中的。

这些更改导致新的文档页面如下所示

python make.py -单身熊猫。DataFrame.all

肯定是一个进步。

下一步是准备合并这个分支。包括确保它编译并通过了 pep8 标准。

git diff upstream/master -u -- "*.py" | flake8 --diff

我提交了一个拉取请求,几分钟内就有了评论。评论的范围从风格上的改变到请求添加有关适用于系列数据结构的 all 方法的信息。三个独立的核心熊猫开发者评论了这个分支。虽然我经常在工作中经历这一过程,但和世界各地我从未见过的人一起做这件事真的很酷。

最终在 3 月 11 日上午 10:42,我的分支被合并,我正式成为 0.23.0 版本中熊猫项目的贡献者。

我希望对开源软件做出更多的贡献,也希望对实现细节和更多的文档做出贡献。

https://pixabay.com/en/background-art-wallpaper-panorama-3104413/

让你的神经网络说“我不知道”——使用 Pyro 和 PyTorch 的贝叶斯神经网络

原文:https://towardsdatascience.com/making-your-neural-network-say-i-dont-know-bayesian-nns-using-pyro-and-pytorch-b1c24e6ab8cd?source=collection_archive---------2-----------------------

构建图像分类器已经成为新的“hello world”。还记得你第一次遇到 Python 的那一天,你的打印“hello world”感觉很神奇吗?几个月前,当我跟随py torch 官方教程并为自己构建了一个简单的分类器时,我也有同样的感觉。

我被我的简单分类器的准确性震惊了。如果我没记错的话,在 MNIST 手写数字数据集上,它在测试集上超过 98%。(作为旁注,这显示了当一个高度准确的图像分类器可以在几个小时内建立起来时,我们已经走了多远。ML 社区——是的,包括你——因为这种自由的知识和工具共享而令人敬畏

尽管分类器的准确度很高,但有一个问题一直困扰着我:

神经网络会吐出一个类别,即使我给它完全不相关的图像。

你知道该怎么做。训练一个猫和狗的分类器,扔出一个人的图像,网络会将它分类为猫或狗。(也许——如果网络有些幽默感的话——开心的人当狗,不开心的人当猫)。

Build your model to throw up its (metaphorical) hands when it’s not sure (Photo via Pixabay)

我知道我对分类器的期望是不现实的。它完全按照程序运行。如果我将最终层(softmax)输出解释为概率,那么对于作为输入给出的任何图像,总会有一个具有最大值的类别。该网络根本不知道这样一个概念,即抛出双手说:“这看起来像是我没有接受过的训练。”

但这正是我想要我的神经网络做的。

在几乎所有现实世界的问题中,你想要的不仅仅是一个结果,你还需要对这个结果有信心/确定性的知识。如果你正在制造无人驾驶汽车,你不仅要检测行人,还要表达你对物体是行人而不是交通锥的信心。同样,如果您正在编写一个在股票市场上交易的机器人,您希望它能够识别情况何时超出其舒适区,这样它就可以停止行动,而不会破产。当一个人不确定的时候,很大一部分智慧是不行动的。因此,令人惊讶的是,对于许多 ML 项目来说,表达不确定性并不是它的目标。

Probably one noisy boi (via Tricking Neural Networks: Create your own Adversarial Examples)

我想通过构建一个 MNIST 分类器来探索这一方向,该分类器可以表达输入图像是特定数字的(不)确定性。当你向它展示数字时,这种分类器会有很高的准确性,但当你向它扔不相关的图像时,它会拒绝分类。我的最终分类器对 MNIST 的准确率约为 97%,它拒绝对白噪声和大多数无关(非 MNIST)图像进行分类。你可以在这里访问代码,并且可能想跟随 repo 中包含的 Jupyter 笔记本以及本教程。

贝叶斯神经网络如何工作

我不会在这里介绍贝叶斯分析的全部内容,但是我会提供足够的上下文让你理解,然后修改代码。

关键思想非常简单:在贝叶斯世界观中,每件事都有一个概率分布,包括模型参数(NNs 中的权重和偏差)。在编程语言中,我们有可以取特定值的变量,每次你访问这个变量,你都会得到相同的值。与此相反,在贝叶斯世界中,我们有类似的被称为随机变量的实体,它们在你每次访问它时都会给出不同的值。所以如果 X 是一个代表正态分布的随机变量,每次你访问 X,它都会有不同的值。

这个从随机变量中获取新值的过程被称为采样。得出什么值取决于随机变量的相关概率分布。与随机变量相关的概率分布越宽,其值的不确定性就越大,因为它可以按照(宽)概率分布取任何值。

If your random variable is the sum of digits of two dice throws, at each throw you’ll get a value whose probability depends on the distribution above. This means the most likely sum that you can get is 7, and least likely is 2 and 12. (From Wikipedia)

在传统的神经网络中,你有固定的权重和偏差,它们决定了如何将输入转化为输出。在贝叶斯神经网络中,所有的权重和偏差都有一个概率分布。为了对图像进行分类,你要对网络进行多次运行(正向传递),每次都使用一组新的采样权重和偏差。您得到的不是一组输出值,而是多组输出值,每次运行一组。这组输出值代表输出值的概率分布,因此您可以找出每个输出的的置信度和不确定度。正如您将看到的,如果输入图像是网络从未见过的,对于所有输出类,不确定性将会很高,您应该将网络解释为:“我真的不知道这个图像是关于什么的”。

用 Pyro 和 PyTorch 编写您的第一个贝叶斯神经网络

该代码假设熟悉概率编程和 PyTorch 的基本思想。如果你对这些都不熟悉,我推荐以下资源:

  • 黑客的贝叶斯方法学习贝叶斯建模和概率编程的基础知识
  • 【PyTorch 深度学习:60 分钟闪电战。特别是关于训练分类器的教程。

PyTorch 有一个名为 Pyro 的配套库,它提供了在 PyTorch 编写的神经网络上进行概率编程的功能。这种将神经网络“自动”转换成贝叶斯对等体的过程有两个步骤:

  • 首先,它有助于将概率分布分配给网络中的所有权重和偏差,从而将它们转换为随机变量
  • 其次,它有助于使用训练数据来推断概率分布,这样你就可以用它来对图像进行分类

推理是整个过程中最困难的一步。它基于著名的贝叶斯定理,你可能以前见过。

The deceptively simple equation that rules the world

深入这个等式的本质已经超出了本教程的范围,但是我会试着给你发生了什么的直觉。假设 A 是权重和偏差的初始概率分布(称为先验,通常是一些标准分布,如正态或均匀随机),而 B 是训练数据(图像/标签的输入/输出对)。

你应该记住的贝叶斯定理的关键思想是,我们希望使用数据找出权重和偏差的更新分布 P(A | B) ( 后验)。就像使用初始随机分配的权重和网络偏差一样,参数的初始分布(先验)会给我们错误的结果。只有在使用数据获得参数的更新分布后,我们才能使用网络对图像进行分类。

权重和偏差的概率分布通过贝叶斯定理更新,考虑到它们的初始值 P(A) 和那些初始分布的似然来描述输入数据 P (B|A) (它被理解为给定 A 的 B 的概率)。权重的更新分布 P(A | B) ( 后验)取决于哪一个具有更强的吸引力——先验或可能性。(如果你对 P(B)项感到好奇,在本教程的后面部分你会明白的)。

我知道上面那段话可能会让严格的贝叶斯人吓哭。我知道这些定义并不精确。但是本教程并不是要介绍贝叶斯方法看待数据的全部荣耀。有完整的书籍和课程在上面,我无法在一个教程中对其进行公正的评价。本教程是关于贝叶斯神经网络的实际实现。我绞尽脑汁钻研 Pyro 教程好几天,试图将他们的一个例子转换成分类器。我终于在 IBM Watson 的网站上找到了一个关于在 MNIST 上使用 Pyro 的简短教程。我的代码基于该教程,但我将其扩展到非 MNIST 和白噪声数据,以观察贝叶斯神经网络在面对它们从未见过的输入时是否真的能说“我不知道”。

尽管我将尝试解释 Pyro 的基础知识,但如果你通读他们的前三个教程,你会从本教程中获得很多价值——第一部分,第二部分和第三部分。

准备好了吗?让我们直接进入代码

在导入 PyTorch、Pyro 和其他标准库(如 matplotlib 和 numpy)后,我们定义了一个 1024 个隐层的标准前馈神经网络。我们也加载 MNIST 数据。

在 Pyro 中, model() 函数定义了如何生成输出数据。在我们的分类器中,当我们用展*的 2828 像素图像运行神经网络(在上面的网络变量中初始化)时,生成对应于每个数字的 10 个输出值。在模型()*中,函数 pyro.random_module() 将我们的神经网络的参数(权重和偏差)转换为随机变量,这些随机变量具有由 fc1w_priorfc1b_prioroutw_prioroutb_prior 给出的初始(先验)概率分布(在我们的例子中,正如您所看到的,我们用一个正态分布来初始化这些)最后,通过 pyro.sample(),我们告诉 pyro 这个网络的输出本质上是分类的(即它可以是 0、1、2 等等。)

理解这个部分——由 guide() 函数表示——对我来说是最棘手的事情。很长一段时间,我不明白为什么需要它,特别是因为它看起来非常像模型()函数。解释起来会很难,但我会尽力。(如果你不能理解我的解释,我推荐 Pyro 教程或者下面我提供的关于这个主题的链接)。

再看一下贝叶斯方程:

model() 函数中,我们定义了 P(A) —权重和偏差的先验。方程的 P(B|A) 部分由神经网络表示,因为给定参数(权重和偏差),我们可以对图像、标签对进行多次运行,并找出训练数据的相应概率分布。在训练之前,最初由于权重和先验都是相同的(都是正态分布),对于给定的图像,获得正确标签的高概率的可能性将是低的。

事实上,推理是学习权重和偏差的概率分布的过程,其最大化了获得正确图像、标签对的高概率的可能性

这个推理过程用 P(A |B) 表示,它是给定输入/输出对( B )时参数 A后验概率。我之前写过推论很难。那是因为你在分母中看到的术语 P(B) 。这个术语被称为证据,它只是在所有可能的参数值下观察到数据(输入/输出对)的概率,用它们各自的概率加权。

计算这个总数很难,原因有三:

  • 假设,参数 Aj 的值可以从-无穷大到+无穷大
  • 对于在该范围内的 Aj 的每个值,您必须运行模型,以找到生成您观察到的输入、输出对的可能性(总数据集可能有数百万对)
  • 这种参数可以不是一个而是多个(j >> 1)。事实上,对于我们这种规模的神经网络,我们有大约 800 万个参数(权重数= 10242828*10)。

我上面描述的后验概率的枚举方法类型除了非常琐碎的模型之外,对任何东西都不实用。如果我们可以进行随机抽样,而不是这种网格状的枚举,会怎么样呢?事实上,基于抽样的方法被广泛使用,它们被命名为蒙特卡罗方法。特别地, Metropolis-Hastings 是蒙特卡罗抽样的流行算法。(它包含在 Pyro 和大多数其他概率编程语言中)。

不幸的是,对于复杂的贝叶斯模型,如具有 800 万个参数的神经网络,蒙特卡罗方法仍然收敛缓慢,可能需要数周才能发现完整的后验概率。

令人欣慰的是,有一种越来越受欢迎的方法叫做变分贝叶斯,这种方法似乎非常适合寻找神经网络参数的后验概率,甚至对于大型数据集也是如此。为了理解这种技术背后的直觉,我强烈推荐观看下面的视频(直到前 40 分钟)。

变分贝叶斯方法的要点是,由于我们不能精确地计算后验概率,我们可以找到与它最接*的“表现良好”的概率分布。我所说的“表现良好”是指一种分布(如正态分布或指数分布),它可以用一小组参数(如均值或方差)来表示。因此,在随机初始化“表现良好”的分布中的参数后,您可以进行梯度下降并每次稍微修改分布的参数(如均值或方差),以查看最终的分布是否更接*您想要计算的后验概率。(如果你在想我们如何知道结果分布是否更接*后验分布,如果后验分布正是我们想要计算的,那么你已经理解了这个想法。答案是,令人惊讶的是,我们不需要确切的后验概率来找出它和其他“良好”分布之间的接*程度。观看上面的视频,了解我们实际优化的贴*度:证据下限或 ELBO。我也发现这个系列 的 帖子对题目有用)。

要直观地理解变分贝叶斯,请参见下图:

Via A Beginner’s Guide to Variational Methods: Mean-Field Approximation

蓝色曲线是真正的后验概率,如果你进行我们之前讨论过的长时间(枚举)计算,你会得到它。这条曲线可以采取任意形状,因为它是枚举计算的结果。与此相反,因为它是一个像正态分布一样的良好分布,所以绿色曲线的整个形状可以用一个参数 Z 来描述。变分贝叶斯方法所做的是使用梯度下降方法将 Z 参数的值从初始随机初始化值更改为其结果分布最接*真实后验值的值。在优化结束时,绿色曲线不完全像蓝色曲线,但非常相似。我们可以安全地使用*似的绿色曲线代替未知的真正的蓝色曲线来进行预测。(如果这一切难以理解,我推荐看上面的视频。)

这就是向导功能的用武之地。它帮助我们初始化一个行为良好的分布,稍后我们可以优化它来逼*真实的后验概率。再看一看:

guide() 函数描述了 Z 参数(如权重和偏差的均值和方差),可以对这些参数进行更改,以查看结果分布是否非常接*来自模型()的后验分布。现在,在我们的例子中,模型()看起来与向导()非常相似,但不一定总是如此。理论上, model() 函数可能比 guide() 函数复杂得多。

有了 model()guide() 函数,我们就可以进行推理了。首先,让我们告诉 Pyro 使用哪个优化器来做变分推断。

您会注意到我们正在使用 PyTorch 的 Adam 优化器(要了解它和其他优化算法的更多信息,这里有一个精彩的系列)。我们用于优化的损失函数是 ELBO(这就像在通过反向传播训练非贝叶斯神经网络时使用均方误差或交叉熵损失)。

让我们写优化循环。

你会注意到这个循环差不多就是我们训练一个标准神经网络的方式。有多个时期/迭代(在本例中是 5)。在每一次迭代中,我们都要经历一个小批量的数据(图像、标签的输入/输出对)。变分推理的另一个好处是,我们不必一次输入整个数据集(可能有数百万)。由于优化器需要成千上万个步骤来寻找引导函数参数的最佳值,因此在每个步骤中,我们可以向其提供单独的小批量数据。这极大地加快了推理速度。

一旦损失似乎稳定/收敛到一个值,我们就可以停止优化,看看我们的贝叶斯神经网络有多精确。下面是这样做的代码。

predict() 函数中要注意的第一件事是,我们使用学习过的 guide() 函数(而不是 model() 函数)来做预测。这是因为对于模型(),我们只知道权重的先验,而不知道后验。但是对于优化迭代后的 guide() 来说,参数值给出的分布*似于真实的后验概率,因此我们可以用它来进行预测。

第二件要注意的事情是,对于每个预测,我们对一组新的权重和参数采样 10 次(由 num_samples 给出)。这实际上意味着,我们正在对一个新的神经网络进行 10 次采样,以进行一次预测。正如你将在后面看到的,这使我们能够给出输出的不确定性。在上面的例子中,为了进行预测,我们对给定输入的 10 个采样网络的最终层输出值进行*均,并将最大激活值作为预测数字。这样,我们看到我们的网络在测试集上 89%的时候是准确的。但是请注意,在这种情况下,我们强迫我们的网络在每种情况下做出预测。我们还没有使用贝叶斯定理的魔力来让我们的网络说:“我拒绝在这里做预测”。

这正是我们接下来要用下面的代码做的。

我就不赘述估计不确定性的完整代码了(你可以在笔记本里看到)。本质上,我们正在做的是:

  • 对于输入图像,取 100 个神经网络样本,从最后一层得到 100 个不同的输出值
  • 通过指数运算将这些输出(对数软式最大值)转换成概率
  • 现在,给定输入图像,对于的每个数字,我们有 100 个概率值
  • 我们将这 100 个概率值的中间值(第 50 个百分位数)作为每个数字的阈值概率
  • 如果阈值概率大于 0.2,我们选择该数字作为网络的分类输出

换句话说,我们希望神经网络输出一个数字作为推荐,如果在多个概率样本中,该数字的中值概率至少为 0.2。这意味着对于一些输入,网络可以输出两位数作为分类输出,而对于其他输入,它可以不输出数字(如果我们给它非数字图像,这正是我们想要的)。

MNIST 数据集上的结果

当我在包含 10,000 张图像的整个 MNIST 测试集上运行网络时,我得到了以下结果:

  • 网络拒绝分类的图像百分比:12.5%(10000 张中的 1250 张)
  • 其余 8750 张“已接受”图像的准确率:96%

请注意,当我们给网络一个拒绝分类的机会时,这种 96%的准确性远远高于强制分类时的 88%的准确性。

想象引擎盖下发生了什么。我从 MNIST 测试批次中随机绘制了 100 幅图像。对于这 100 张图片中的大部分,网络分类准确。

上面的图显示的是输入图像的真实标签是 3,对于 10 个数字中的每一个,显示了对数概率的直方图。对于标签 3,中值对数概率实际上接* 0,这意味着该图像为 3 的概率接* 1 (exp(0) = 1)。这就是为什么它用黄色突出显示。由于网络选择的标签与真实标签相同,所以显示“正确”。您还可以看到输入图像的实际样子。

在我对 100 张图像的多次运行中,网络进行预测的准确率为 94–96%。网络通常选择不预测 10-15%的图像,看着网络说“我不太确定”的一些图像很有趣。

连我都很难看出这个数字是“2”。从直方图中可以看出,网络对于 2 个和 3 个标签都具有很高的不确定性。对于这种网络未确定的情况,所有标签的对数概率分布都很宽,而在上图中“3”的准确分类情况下,您会注意到数字 3 的分布很窄,而所有其他数字的分布都很宽(这意味着网络非常确定它是 3)。

又一个网络未定的案例。

你看图像都被搞乱了。传统的神经网络可能会吐出一些东西,但我们的贝叶斯网络拒绝说出任何东西。

随机生成图像的结果

为了观察网络在输入纯白噪声时的表现,我随机生成了 100 张图像。

当这些图像被作为输入时,网络拒绝对其中的 95%做出预测

这是一个典型的随机生成的图像的样子:

非 MNIST 数据集上的结果

我更进一步,下载了非 MNIST 数据集,这是一个字母而不是数字的数据集。看起来是这样的:

对于非 MNIST 测试集,网络拒绝分类约 80%的图像(测试集中总共 459 个中的 363 个)。

下面是一个非 MNIST 图像的例子。

很高兴看到我们的网络在训练内容(MNSIT)上给出了很好的准确性,同时没有被定制设计来愚弄它的数据集所愚弄(不是 MNIST)。

结论和如何使我们的贝叶斯网络更好

在 MNIST 数据集上的最新结果具有 99.8%的准确率。所以我们 96%的准确率(当我们想要做一个预测的时候)与此相差甚远。

有四种方法可以获得更高的精度:

  • 我们使用了一个非常简单的模型:具有 1024 个神经元的单层神经网络。如果我们使用更先进的卷积网络,我相信我们可以提高我们的准确性。
  • 如果我们继续运行我们的优化更长的时间,我们可以提高我们的准确性
  • 如果我们对每幅图像采样更多的数据点(而不是 100 个),结果可能会有所改善
  • 如果我们使我们的接受标准从中值概率最小为 0.2 到可能第 10 百分位概率最小为 0.5,我们的网络将拒绝更多的图像,但是在接受的图像上,它可能具有更高的准确性

总的来说,我对结果很满意。我希望你玩代码:)玩得开心

请随意评论这篇文章,我会尽力回答你的问题。如果你能够改进代码,请在 github 上向我发送一个 pull 请求。如果你在新的数据集或问题上使用 basic 代码,请发邮件给我,地址是 paras1987 gmail com,我很乐意收到你的来信。

感谢 Nirant Kasliwal、Divyanshu Kalra 和 S. Adithya 审阅草稿并提出有益的建议。

PS:我最*制作了一个 20 分钟的视频,讲述是什么让深度学习如此有效。现在就去看!

喜欢这个教程吗?也可以看看我的其他教程:

  • 一个神经网络,多种用途。使用单一模型构建图像搜索、图像字幕、相似文字和相似图像
  • 让深度神经网络作画,了解它们是如何工作的。用 100 行 PyTorch 代码生成抽象艺术,并探索神经网络如何工作
  • 通过机器学习为机器学习项目产生新的想法。使用预先训练的语言模型从 2.5k 句子的小型语料库中生成风格特定的文本。PyTorch 代码
  • 无梯度强化学习:使用遗传算法进化智能体。在 PyTorch 中实现深度神经进化为 CartPole 进化一个 agent 代码+教程]

我发关于深度学习和 AI 的推特。在https://twitter.com/paraschopra跟着我

[## Paras Chopra (@paraschopra) |推特

Paras Chopra 的最新推文(@paraschopra)。如果你想知道宇宙为什么存在,请跟我来…

twitter.com](https://twitter.com/paraschopra)

制作自己的 Spotify Discover 每周播放列表

原文:https://towardsdatascience.com/making-your-own-discover-weekly-f1ac7546fedb?source=collection_archive---------1-----------------------

每周一醒来我都很兴奋。在你认为我是那些喜欢每天去上课的怪人之一之前,让我向你保证,我不是。然而,每周一,Spotify 都会发布一个名为 Discover Weekly 的播放列表。里面装满了我以前没听过的新歌。接下来几周,我几乎总能在上面找到我的新果酱。但是,他们是怎么做到的呢?

索菲亚·乔卡的这篇文章应该会让你对此有更好的理解,

[## Spotify 的 Discover Weekly:机器学习如何找到你的新音乐

个性化音乐推荐背后的科学

hackernoon.com](https://hackernoon.com/spotifys-discover-weekly-how-machine-learning-finds-your-new-music-19a41ab76efe)

但是我想试着弄清楚我是否可以建立我自己的系统来做类似的事情!跟我一起去兜风吧!

如果你想继续,这是我的 Python 笔记本!

[## nab0310/SpotifyML

在 GitHub 上创建一个帐户,为 SpotifyML 的发展做出贡献。

github.com](https://github.com/nab0310/SpotifyML/blob/master/spotify/Final Pretty Spotify Data Classifier.ipynb)

创建您的第一个 Spotify 应用程序并设置您的环境

使用 Spotify API 的第一步是在 Spotify 开发者环境中创建一个应用程序。为此,首先进入 Spotify 开发者页面,登录并导航至“我的应用程序”页面。

[## 我的应用程序| Spotify 开发者

创建和管理 Spotify 应用程序以使用 Spotify Web API。获取凭证以通过 Spotify 进行认证,并…

developer.spotify.com](https://developer.spotify.com/my-applications/#!/applications)

一旦创建了一个新的应用程序,并给它一个漂亮的名字。单击创建屏幕,记下客户端 ID 和客户端密码,我们稍后会用到它们。

The screen after you create an application, take note of the Client ID and Client Secret.

在应用程序创建屏幕上,我们还需要设置重定向 URIs 字段。这是您的应用程序登录 Spotify 成功或失败后的位置。为了方便使用,我只是将它设置为 localhost:8888,这对于我的大多数应用程序来说都很好,但是如果你在一个完整的网站中实现这一点,请确保你有一个为 Spotify 回调定义的路径。

Spotify app 创建完成后,我们就可以开始钻研音乐的奇妙世界了!为了这个项目,我将 Python 与 Jupyter Notebook 结合使用,让我可以轻松地跨计算机开发,并给我一个漂亮的 UI 来查看我的图形。

注意:本文的其余部分我将使用 spotipy,Spotify API 的 python 包装器,以下是它们的文档供您阅读:

[## 欢迎来到 Spotipy!- spotipy 2.0 文档

编辑描述

spotipy.readthedocs.io](https://spotipy.readthedocs.io/en/latest/)

从 Spotify API 开始

在我们进行任何分析之前,我们需要学习如何登录,我是这样做的:

import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy.util as utilcid ="<Client ID from Earlier>" 
secret = "<Client Secret from Earlier>"
username = ""client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret) 
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)scope = 'user-library-read playlist-read-private'
token = util.prompt_for_user_token(username, scope)if token:
    sp = spotipy.Spotify(auth=token)
else:
    print("Can't get token for", username)

这样做的第一件事是初始化一个 client_credentials_manager,它告诉 Spotify 要连接到哪个 Spotify 应用程序。一旦我们知道我们想要连接到哪个应用程序,我们就定义了一个范围。这个范围告诉 Spotify 我们的应用程序需要做什么,查看下面的链接了解更多信息。

[## Web API:使用范围

当您的应用程序寻求访问用户相关数据的授权时,您通常需要指定一个或多个…

developer.spotify.com](https://developer.spotify.com/web-api/using-scopes/)

定义好范围后,我们就可以登录了。如果这行得通,这个脚本应该会把你重定向到一个奇特的 Spotify 登录页面。登录后,它会将您重定向到我们之前定义的重定向 URL。此外,笔记本会要求您将重定向到的 url 粘贴到提示中以继续。一旦你这样做,它接受请求,你就登录到 Spotify!

随着基本的 Spotify 东西的方式,我们可以转向该项目的数据分析部分。

数据采集

这是整个过程中最乏味的部分。我需要收集两个播放列表,一个装满我不喜欢的歌曲,另一个装满我喜欢的歌曲。

找到我喜欢的歌曲相对容易,我只是添加了我保存的所有歌曲和我喜欢的一些播放列表中的所有歌曲。但这只是成功的一半。

你有没有试过找出不好的音乐??相信我:这很痛苦。

我首先拜访了一些音乐品味我不喜欢的朋友,并添加了一些他们最喜欢的歌曲。最终,我没有朋友了。但是,后来我想起来 Spotify 有流派分类播放列表!万岁。我加入了自己不喜欢的流派,还加了一堆歌。这最终让我开始思考我想要多少首歌。

免责声明:我知道这不是收集数据的最佳方式,但我真的不想花时间去获得我不喜欢的歌曲的代表性样本,我只想获得足够好的东西。

所有这些歌曲的收集都涉及到将歌曲从一个播放列表转移到另一个播放列表。下面是将歌曲从一个播放列表转移到另一个播放列表的代码片段:

sourcePlaylist = sp.user_playlist("<source user>", "<Source Playlist ID>")
tracks = sourcePlaylist["tracks"]
songs = tracks["items"] 
while tracks['next']:
    tracks = sp.next(tracks)
    for item in tracks["items"]:
        songs.append(item)
ids = [] 
print(len(songs))
print(songs[0]['track']['id'])
i = 0
for i in range(len(songs)):
    sp.user_playlist_add_tracks("<target user>", "<Target Playlist ID>", [songs[i]["track"]["id"]])

为了移动歌曲,您需要用户和播放列表 id。你可以从播放列表的链接中获得,这里有一个例子:【https://open.spotify.com/user/】T4<用户>/playlist/

边注:在本文的最后,我会在你的好的和不好的播放列表中推荐大约 1500–2000 首歌曲。

数据分析

获取音频功能

现在我们有了好歌和烂歌的播放列表,我们该如何分析它们呢?

幸运的是,Spotify 为我们提供了一种方法——音频功能对象。

这是文档中的对象:

[## 获取音轨的音频特征

获取由唯一的 Spotify ID 标识的单曲的音频特征信息。去找 https://api.spotify.com/v1…

developer.spotify.com](https://developer.spotify.com/web-api/get-audio-features/)

这个对象是我们分析的基石。我们实际上无法访问原始音频波形或其他统计数据(即播放次数,我们听一首歌多长时间,等等。)让我们的分析更好。虽然这并不完美,但它有助于我们对歌曲中我们喜欢的特征得出一些基本的结论。

要获取一首歌的音频特征,我们需要使用 sp.audio_features( )调用。这需要我们传入一个歌曲 ID 来获取该音轨的特性。

问:但到目前为止,我们只有两首好歌和坏歌的播放列表,我们如何获得所有这些歌曲的歌曲 ID?

我明白了。

good_playlist = sp.user_playlist("1287242681", "5OdH7PmotfAO7qDGxKdw3J")good_tracks = good_playlist["tracks"]
good_songs = good_tracks["items"] 
while good_tracks['next']:
    good_tracks = sp.next(good_tracks)
    for item in good_tracks["items"]:
        good_songs.append(item)
good_ids = [] 
for i in range(len(good_songs)- 500):
    good_ids.append(good_songs[i]['track']['id'])

首先,我们通过用户 ID(“1287242681”)和播放列表 ID(“5 odh 7 pmotfao 7 qdgxkdw 3j”)来抓取播放列表。一旦我们有了播放列表,我们需要遍历它来挑选出播放列表中的每首歌曲,然后从那首歌曲中挑选出 id。在这个块结束之后,我们将在 good_ids 数组中有好的歌曲 id。

现在,我们打电话从 Spotify 获取音频功能:

features = []
for i in range(0,len(good_ids),50):
    audio_features = sp.audio_features(good_ids[i:i+50])
    for track in audio_features:
        features.append(track)
        features[-1]['target'] = 1

音频功能调用的唯一奇怪之处是我们一次只能获得 50 首歌曲的功能。所以,我们可以把 id 分成 50 份,一次传递 50 份。在这里,我们将所有的音频特性和一个“目标”字段一起添加到一个数组中,以指定我们是否喜欢这首歌。

剩下的就是对坏的播放列表重复相同的步骤,我们可以开始做一些实际的分析了!

图上的图

为了开始查看我们的图形优势,我们需要做的就是将数据插入到熊猫数据框架中。

trainingData = pd.DataFrame(features)

我使用 matplotlib 进行绘图。以下是我的听力数据中一些有趣的对比。

注:蓝色代表我喜欢的歌,红色代表我不喜欢的歌。

Tempo comparison between songs I like and don’t

Valence comparison between songs I like and don’t

第一张图显示了歌曲的节奏。从图表中,我们可以看到我们不能真正用节奏来可靠地预测我是否会喜欢一首歌。下一张图叫做化合价。效价是衡量一首歌听起来有多快乐的标准。这张图表显示我更喜欢悲伤的歌曲,而不是快乐的歌曲。所有其他音频特性的其余图表可以在笔记本中找到。

现在我们有了一些图表,让我们训练一个分类器,看看它在预测我喜欢的歌曲方面有多好!

使用不同的分类器并观察它们如何执行

在我们开始之前,只需要一点点定义。

分类器:试图根据不同的输入值将数据分类到几个不同的桶中。

这是不同分类器之间的一个很好的比较,以及它们如何围绕不同的数据形成。

[## 分类器比较-sci kit-了解 0.19.1 文档

scikit-learn 中几种分类器在合成数据集上的比较。这个例子的目的是为了说明…

scikit-learn.org](http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html)

如果你还想进一步了解不同类型的分类器,Google 是你的好朋友!

为了使任何分类器工作,我们需要将我们的数据分成训练和测试集,这样我们就有一些数据来训练我们的模型,还有一些数据来测试前面提到的模型。这可以通过一个名为 train_test_split()的 sklearn 函数来实现,该函数根据方法中指定的 test_size 百分比来拆分数据。下面的代码将数据分成 85%训练,15%测试。

from sklearn.model_selection import train_test_split
train, test = train_test_split(trainingData, test_size = 0.15)

在我们分割数据之后,我们将把它放入训练/测试 x 和 y 变量中,以输入到我们的分类器中。

#Define the set of features that we want to look at
features = ["danceability", "loudness", "valence", "energy", "instrumentalness", "acousticness", "key", "speechiness", "duration_ms"]#Split the data into x and y test and train sets to feed them into a bunch of classifiers!
x_train = train[features]
y_train = train["target"]x_test = test[features]
y_test = test["target"]

决策树分类器

决策树分类器是我要看的第一个分类器,因为它最容易可视化。下面的代码片段显示了如何使模型符合训练数据,根据测试数据预测值,然后显示模型的准确性。

c = DecisionTreeClassifier(min_samples_split=100)
dt = c.fit(x_train, y_train)
y_pred = c.predict(x_test)
score = accuracy_score(y_test, y_pred) * 100
print("Accuracy using Decision Tree: ", round(score, 1), "%")

这个分类器配置最重要的部分是 min_samples_split 值。这是基于特征的树分割的值。这是决策树的一小部分。

A snippet of the Decision Tree to show the decisions and number of samples in each bucket

决策树给我的准确率只有 80%,这很好,但我们可以做得更好。

*邻分类器

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(3)
knn.fit(x_train, y_train)
knn_pred = c.predict(x_test)
score = accuracy_score(y_test, knn_pred) * 100
print("Accuracy using Knn Tree: ", round(score, 1), "%")

K-最*邻分类器查看数据点的邻居,以确定输出是什么。因此,在我们的例子中,它接收一首新歌曲的音频特性,绘制它并查看它周围的歌曲,以确定我是否会喜欢它。这种方法只给了我们 80%的准确率,和决策树一样。我对这种类型的分类器不抱太大希望,因为我训练的数据没有很好地按照不同的特征分开。

AdaBoostClassifier 和 GradientBoostingClassifier

from sklearn.ensemble import AdaBoostClassifier
ada = AdaBoostClassifier(n_estimators=100)
ada.fit(x_train, y_train)
ada_pred = ada.predict(x_test)
from sklearn.metrics import accuracy_score
score = accuracy_score(y_test, ada_pred) * 100
print("Accuracy using ada: ", round(score, 1), "%")from sklearn.ensemble import GradientBoostingClassifier
gbc = GradientBoostingClassifier(n_estimators=100, learning_rate=.1, max_depth=1, random_state=0)
gbc.fit(x_train, y_train)
predicted = gbc.predict(x_test)
score = accuracy_score(y_test, predicted)*100
print("Accuracy using Gbc: ", round(score, 1), "%")

这两种分类器的操作方式相似。它们都是从创建一个相对较弱的“学习者”(用来做预测的东西)开始,然后用分类的结果来修改“学习者”,让它更好地预测未来的事情。

AdaBoost 的工作原理是拟合学习者,然后在数据的每次迭代之间,它修改预测的方式,以便尝试以更高的精度对更困难的情况进行分类。当我运行这个分类器时,它有 84.3%的准确率。

梯度增强使用损失函数(预测值与真实值相差多远的度量),并尝试在每次迭代中减少损失函数。当我运行这个分类器时,它有 85.5%的准确率。

免责声明:每次运行分类器时,这些精度值都会发生变化,所以如果您没有得到与我相同的值,请不要担心。

我们现在要做的就是选择对我们的训练数据具有最高准确度的分类器(对我来说是梯度提升),并测量它在现实世界中的表现如何!

结果

为了测试我的分类器,我在我的 Discover Weekly 上运行了 4 周。Discover Weekly 是 30 首歌,所以我总共测试了 120 首歌。为了做到这一点,重复我们加载好的和坏的播放列表的步骤,但之后,只需调用分类器的预测功能。

pred = gbc.predict(playlistToLookAtFeatures[features])i = 0
for prediction in pred:
    if(prediction == 1):
        print ("Song: " + playlistToLookAtFeatures["song_title"][i] + ", By: "+ playlistToLookAtFeatures["artist"][i])
    i = i +1

分类器挑选了 66 首它认为我会喜欢的歌曲。听了所有的歌,我挑出了 31 首我喜欢的歌。分类器和我个人喜欢分享了 23 首歌。因此,我的分类器识别出了 43 首它说我喜欢但不喜欢的歌曲。然而,它只错过了我喜欢的 8 首歌。尽管得到了一堆假阳性,我会称之为我的第一次钻研像这样的成功!

未来

最终我想开始使用谷歌的开源机器学习库 Tensorflow ,并希望用他们提供给我的工具制作一个更好的模型。我最终还想将这个分类器整合到一个更大的系统中,每天为我挑选一个“每周发现”播放列表,这样我就可以不断地寻找新音乐。

如果你喜欢这个,一定要看看我的 Github 或者至少是 Python 笔记本 所有这些代码都是你可以随意摆弄的!此外,如果你认识在Spotify工作的人,我很乐意与你联系!如果你有任何建议或者意识到我做错了什么,一定要在评论里告诉我!

人类计划,上帝大笑:计划谬误

原文:https://towardsdatascience.com/man-plans-god-laughs-the-planning-fallacy-ea9bcacc16f4?source=collection_archive---------1-----------------------

所以你打算看完整篇文章?让我想想…

从前,有一个男孩和一个女孩。他们在悉尼歌剧院有个约会。她像往常一样迟到了——意想不到的事情发生了——她无法立即找到她 100 种化妆品中的一种。(其他时候她找不到其他的,所以结果一样总是不一样。)

by Jovana Đukić

在等待的时候,他谷歌了关于这部歌剧的有趣事实来打动她。这是他在维基百科上找到的:

“悉尼歌剧院原定 4 年,预算 700 万澳元。它最终花了 14 年才完成,耗资 1.02 亿澳元。”

“太酷了!”他想。她听后也这么说。在接下来的几个月里,他们经常使用同一个短语,所以他们决定结婚。(她喜欢他有趣的事实,他喜欢她迟到——所以他有足够的时间去发现它们。)

他与父亲离婚的固执的母亲警告他,他们有 33%到 50%的机会离婚。“不是我们,妈妈。我们非常相爱。”“当然,因为我和你父亲是出于仇恨才结婚的。”

他们还是结婚了,而且比一些婚姻做得更好。

“没有什么能把我们分开。我们可能会再结婚十年。”——伊丽莎白·泰勒,在她和理查德·伯顿宣布离婚的五天前

但比大多数婚姻都糟糕。确切的说,比他们中的 67%到 50%还要差。

她得到的结婚礼物是一个可以存放化妆品的盒子。结果她不再迟到了;所以这家伙没时间去找有趣的事实。谁想在一段婚姻中,最有趣的事实是对你离婚的预测?

“不是我!”她抓起盒子扔在地板上。那天,盒子和婚姻都破裂了。

规划谬误

人们总是迟到,项目花费数百万而不是数千,战争花费数年而不是数月,为什么我妈妈总是带着满满一袋子杂货回家,不管她打算买什么?是规划谬误!

计划谬误的概念是由诺贝尔奖获得者丹尼尔·卡内曼和他的同事阿莫斯·特沃斯基首先提出的。它描述了过于乐观的计划和预测

  • 不切实际地接*最佳情况
  • 可以通过参考类似案例的统计数据进行改进。

by Jovana Đukić

在他的书《思考,快与慢》中,卡尼曼描述了下面的预测故事。他和他的同事正在设计一本在高中教授判断和决策的教科书。在一年中每周会面一次后,他们已经取得了一些进展:写了几个章节,构建了一个教学大纲的大纲,并进行了一些示范课程。

他们只是在讨论如何估计不确定的量,所以卡尼曼提议每个人在完成课本之前写下他们对持续时间的估计。结果集中在两年左右。

然后卡尼曼转向课程专家(两人估计和其他人一样)问他:“构建一个课程通常需要多长时间?”

“七到十年。更不用说之前几乎有一半的群体放弃了,”他回答道。

卡尼曼进一步挖掘道:“与其他群体相比,我们有多优秀?”

“略低于*均水*,”课程专家说。过了一会儿,他扬起眉毛,意识到他的估计有矛盾。低于*均水*的群体如何超过其他人三年以上?

它可以,但假设它会是愚蠢的。

出现这种差异是因为他使用了两种不同的计划策略。当写下他的估计时,他在脑海中搜寻信息,试图想象未来。后来,在卡尼曼的帮助下,他根据来自世界之外的的类似情况的统计数据做出了预测。

内部视图

这是一个小组成员写下他们的评估的策略。该战略关注我们的具体情况,并在我们的经验中寻找证据。这是推断——假设现有的趋势将会继续。有一个问题:

"未来不再是过去的样子了"—约吉·贝拉

“这种(过于乐观的预测)的原因是,我们通过压缩可能的不确定状态的范围(通过减少未知的空间)来低估不确定性,”纳西姆·尼古拉斯·塔勒布在他的畅销书《黑天鹅》中解释道。换句话说,我们低估了我们所不知道的。在卡尼曼的情况下,这些可能是更复杂的章节,疾病,官僚问题…数百件你甚至无法想象的事情。

"意外总是朝着一个方向推进:更高的成本和更长的完成时间."—纳西姆·尼古拉斯·塔勒布

任务越长、越复杂、越独特,预测就越难。想想最基本的,从椅子上站起来。如果你不想再坐着了,你可以预测你什么时候会站起来——除非你的朋友喜欢用胶水恶作剧。

另一边是战争。每场战争都有自己的属性:人员、地形、天气、战术、技术。它们通常持续多年(尽管预测时间较短)。更多的时间意味着更多意想不到的机会。如果日本可以预测他们核武器的发展,他们会攻击美国吗?

即使在今天,战争预测也悲惨地失败了。布什政府低估了伊拉克战争费用超过 30 倍;目前的支出约为 2 万亿美元(最初为 600 亿美元),并且还在增长。

如果说从内心深处可以学到什么,那就是霍夫施塔特定律:

"它总是比你想象的要长,即使你把霍夫施塔特定律考虑在内."道格拉斯·霍夫施塔特

外面的景色

使用类似项目的统计信息是解决规划谬误的方法。一般来说,你会面临和其他人一样多的意想不到的麻烦。

称为参考类预测的方法是由 Flyvbjerg 提出的。它包含三个步骤,我在其中添加了卡内曼故事中的实际例子:

  1. 确定一个合适的参考班:其他课程项目。
  2. 获取参考类的统计数据,生成基线预测 : 7 到 10 年,40%失效率。
  3. 利用案件具体信息调整基线预测:有没有证据表明我们组比其他组好/差?

卡尼曼的团队用了八年时间完成了这个项目,接*最快的项目。那些年,很多事情都变了:他不再是这个团体的一员,对教授决策也没什么兴趣。教科书从来没有出现在学校的长凳上。

在某些情况下,我们已经在某种程度上使用了外部视图。想想寿命预测。通常使用*均寿命,并根据生活方式、遗传和健康状况增加或减少几年。一个人不会看着自己的经历宣布:“我感觉很好,我还没有死,根据这个证据,我会永远活着。”

by Jovana Đukić

乐观偏见

规划谬误还有一个偏见;乐观偏见。总结如下:

“我们中的大多数人认为世界比实际情况更好,我们自己的属性比实际情况更好,我们采纳的目标比他们可能实现的目标更容易实现。”—丹尼尔·卡内曼

我们不对称地感知事件。我们把成功归因于我们的技能,把失败归因于运气不好。但只针对我们自己和与我们密切相关的人,而不是其他人——这创造了虚幻的优越感。

研究人员发现,90%的司机认为自己比普通司机强,大多数学生认为自己比普通学生更聪明。按照这种逻辑,我们为什么不能成为成功的人呢?

因为每个人都认为自己有点特别,但这并不能让任何人特别。

“你有没有注意到,开车比你慢的人是白痴,比你快的人是疯子?”—乔治·卡林

这个刚刚单身的男人出去喝啤酒来治愈他受伤的心灵。他想赢回他的乐观(偏见,但他不承认)。当他转向投篮时,他打偏了。他对未来并不乐观,反而对过去感到悲伤。朋友们还没来得及阻止他(他们正忙着检查手机),手机已经到了他手里。

“我 miz u;“d”是开始把破裂的婚姻粘在一起的信息。(她睡着了,所以没有立即回应——我们都知道谁喜欢等待。)

然而,他们不需要把化妆盒粘在一起。他买下它作为他们再生爱情的标志——这是让她再次说“太酷了”的东西。

对他们来说,“哦,太酷了”离说“我愿意”不远了。

他们计划好了,上帝笑了。

原载于 2017 年 12 月 29 日 新锐

人与机器:理解人工智能的危险

原文:https://towardsdatascience.com/man-vs-machine-understanding-the-perils-of-artificial-intelligence-eb3caf9ce6b0?source=collection_archive---------2-----------------------

当谈到人工智能(AI)的话题时,世界显然分成了两派:一派强烈认为人工智能是件好事,另一派强烈否认这一点。双方都有合理的论据。我个人在这个问题上的观点仍然是,赞成和反对的观点都与环境有关——谁在开发它,用于什么应用,在什么时间框架内,为了什么目的?没有明确的黑与白。这也意味着,随着人工智能领域的进一步发展,有机会主动识别、隔离和解决风险。

这有助于理解争论的双方。所以让我们试着仔细看看反对者说了什么。最常引起争论的担忧可分为三大类:

A. 大规模失业:这可能是在人工智能背景下强调的所有风险中最切实、最广为人知的。技术和机器代替人类做某些类型的工作并不新鲜。我们都知道,由于技术的发展,整个职业正在减少,甚至消失。工业革命也导致了大规模的失业。

然而,尽管人们担心就业,但在过去的 3-4 个世纪里,人们普遍承认,这些技术进步通过创造新的途径、降低价格、增加工资等方式,大大弥补了短期的就业损失。

然而,今天的故事非常不同。请考虑以下情况:

  • 越来越多的经济学家不再相信,从长期来看,技术会对整体就业产生积极影响。
  • 仅在过去十年中,中低技能工作的流失在几个领域都很严重——令人不安的事实是,这些工作大多不是受到人工智能的影响,而只是受到自动化的影响——人工智能的影响预计会更大。
  • 多项研究预测技术进步将导致大规模失业,包括 2016 年的一份联合国报告称,预计发展中国家 75%的工作将被机器取代。

失业,尤其是大规模的失业,是一件非常危险的事情,常常会导致大范围的社会动荡。因此,人工智能在这一领域的潜在影响需要非常仔细的政治、社会学和经济学思考,以有效地应对它。

奇点:奇点的概念是人们想象中只能在未来科幻小说中看到的东西之一。然而,从理论上说,今天这是一个真正的可能性。简而言之,奇点是指人类文明中的一个点,当人工智能达到一个临界点,超过这个临界点,它就会进化为一种超越人类认知能力的超级智能,从而对我们今天所知的人类存在构成潜在威胁。

虽然围绕机器智能爆炸的想法是一个非常中肯和广泛讨论的话题,但与技术驱动的失业不同,这个概念仍然主要是理论性的。围绕这一思路的两个主要问题尚不明确,即

  • 这个临界点在现实中真的能达到吗?
  • 如果是的话,在中短期内可能发生吗?

C. 机器意识:与前两点不同,这两点可以被视为与人工智能进化相关的风险,机器意识方面或许最好被描述为一个伦理难题。这个想法涉及将类似人类的意识植入机器的可能性,使它们超越‘思维’的领域,进入‘感觉、情感和信念’的领域。

这是一个复杂的话题,需要深入研究哲学、认知科学和神经科学的融合。“意识”本身可以有多种解释,集合了过多的属性,如自我意识、心理状态的因果关系、记忆、经验等。要让机器达到类似人类的意识状态,需要复制人脑中神经层面发生的所有活动——这绝不是一项简单的任务。

如果要实现这一目标,就需要世界运作模式的转变。当今社会是一个完善的、结构化的系统,它指导着人们相互交往的方式。这个系统将需要一个重大的重新定义,以纳入与人类共存的具有意识的机器,以及两者之间的相互关系。这在今天听起来有些牵强,但像这样的问题需要现在就思考,以便能够影响我们在人工智能和机器意识方面的发展方向,而事情仍然处于“设计”阶段。

虽然以上都是中肯的问题,但我相信它们不一定会超过人工智能的优势。当然,有必要系统地解决它们,控制人工智能发展的路径,并将不利影响降至最低。在我看来,最大和最迫在眉睫的风险实际上是第四项,在讨论人工智能的陷阱时,并不经常被考虑在内。

D. 寡头:或者换个说法,控制的问题。由于人工智能的本质——它需要在技术和科学上的巨大投资——现实中只有少数组织(私人或政府)能够以可扩展的方式跨越一系列广泛的应用程序,将人工智能纳入主流。

除此之外,开发人工智能最重要的组成部分之一是持续的反馈和学习,这来自于拥有最大量的数据来获得反馈或学习。这是一个自我实现的良性循环——你拥有的数据越多,你的人工智能*台就越好,导致更多用户采用你的人工智能*台,而你获得更多数据进行更多学习。你认为谁会赢得这场比赛?同样,只有少数组织可能做到。无论小型新贵有多聪明,他们都没有多少空间与这些公司大规模竞争。

鉴于我们生活的巨大部分可能将由人工智能机器来控制,那些控制这种“智能”的人将对我们其他人拥有巨大的权力。所有熟悉的短语‘权力越大,责任越大’将有全新的含义——处于普遍可用的人工智能应用前沿的组织和/或个人可能比历史上最专制的独裁者拥有更多权力。这是一个真实的危险,它的某些方面已经成为人们关注的领域,比如围绕隐私的讨论。

总之,像人类历史上所有重大变革事件一样,人工智能肯定会产生广泛深远的影响。但是经过仔细的深思熟虑,这些问题是可以解决的。从短期到中期来看,人工智能在改善我们生活方面的优势可能会超过这些风险。任何广泛触及人类生活的重大概念,如果处理不当,都会带来巨大的危险。我能想到的最好的类比是宗教——如果引导不当,它可能会构成比任何技术进步都更大的威胁。

在早期管理您的数据科学项目结构。

原文:https://towardsdatascience.com/manage-your-data-science-project-structure-in-early-stage-95f91d4d0600?source=collection_archive---------3-----------------------

Jupyter Notebook(或 Colab,databrisk 的 Notebook 等)为在短时间内建立一个项目提供了一个非常有效的方法。我们可以在笔记本中创建任何 python 类和函数,而无需重新启动内核。有助于缩短等待时间。它适合于小规模的工程和实验。然而,这可能不利于长期增长。

“white and multicolored building scale model” by Alphacolor 13 on Unsplash

看完这篇文章,你会明白:

  • 什么时候我们需要一个定义良好的项目文件夹结构?
  • 模块化
  • 建议

什么时候我们需要一个定义良好的项目文件夹结构

概念证明(PoC)

直觉上,速度是我们进行概念验证(PoC)时的主要考虑因素。在之前的一个项目中,我探索了文本摘要技术是否可以应用到我的数据科学问题中。我不打算为我的 PoC 构建任何“美丽”或“结构”,因为我不知道它是否有用。

换句话说,我使用“快速和肮脏”的方式来进行 PoC,因为没有人关心它是否结构良好或性能是否得到优化。从技术角度来看,我可能会在笔记本内部创造功能。好处是我不需要处理任何外部化文件(例如加载其他 python 文件)。

包装解决方案

“four brown gift boxes on white surface” by Caley Dimmock on Unsplash

在多次运行 PoC 后,应确定解决方案。由于多种原因,代码重构从此刻开始是必要的。它不仅组织得很好,而且有利于实现更好的预测。

模块化

“editing video screengrab” by Vladimir Kudinov on Unsplash

首先,你必须让你的实验可重复。当你最终确定(至少是初始版本)时,你可能需要与其他团队成员一起工作来组合结果或构建一个系综模型。其他成员可能需要检查和审查你的代码。如果他们不能复制你的作品,这不是一个好主意。

另一个原因是超参数调整。我不关注早期阶段的超参数调整,因为它可能会花费太多的资源和时间。如果解决方案得到确认,那么在启动预测服务之前,应该是寻找更好的超参数的好时机。不仅在嵌入层的维度上调整神经网络中神经元的数目,还可以进行不同的架构(例如比较 GRU、LSTM 和注意机制)或其他合理的改变。因此,模块化您的处理、培训、度量评估功能是管理这种调整的重要步骤。

此外,你需要将你的代码运送到不同的集群(比如 Spark,或者自建分布式系统)进行调优。由于一些原因,我没有使用 dist-keras (分布式 keras 培训库)。我自己构建了一个简单的集群来加速分布式训练,同时它可以支持 Keras、scikit-learn 或任何其他 ML/DL 库。将实现打包成 python 而不是 notebook 会更好。

建议

在交付了几个项目后,我重温了论文和项目结构模板,并遵循敏捷项目管理策略。我将塑造我的项目结构如下风格。它使我在每个项目迭代或冲刺中拥有组织良好的项目和更少的痛苦。

Rounded rectangle means folder. python code, model file, data and notebook should be put under corresponding folder.

src

存储服务于多种场景的源代码(python、R 等)。在数据探索和模型训练过程中,我们必须为特定目的转换数据。在线预测期间,我们也必须使用相同的代码来传输数据。因此,它更好地将代码从笔记本中分离出来,以服务于不同的目的。

  • 准备:数据摄取,例如从 CSV、关系数据库、NoSQL、Hadoop 等检索数据。我们必须一直从多个来源检索数据,所以我们最好有一个专门的数据检索功能。
  • 处理:作为源数据的数据转换并不总是符合模型的需要。理想情况下,我们有干净的数据,但我从来没有得到它。你可能会说我们应该让数据工程团队帮助我们进行数据转换。但是,在学习数据下,我们可能不知道自己需要什么。一个重要的要求是离线训练和在线预测都应该使用相同的流水线来减少未对准
  • 建模:建模,如解决分类问题。它不仅包括模型训练部分,还包括评估部分。另一方面,我们必须考虑多模型场景。典型的用例是集成模型,如结合逻辑回归模型和神经网络模型。

测试

在 R&D,数据科学侧重于建立模型,但并不确保在意想不到的情况下一切正常。但是,如果将模型部署到 API,这将是一个麻烦。此外,测试用例保证向后兼容的问题,但它需要时间来实现。

  • 断言 python 源代码的测试用例。更改代码时确保没有 bug。自动化测试是成功项目的一个基本难题,而不是使用手工测试。假设测试用例有助于验证代码更改不会破坏以前的用法,团队成员将有信心修改代码。

型号

用于存储本地使用的二进制(json 或其他格式)文件的文件夹。

  • 仅在此存储中间结果。对于长期来说,它应该单独存储在模型库中。除了二进制模型,您还应该存储模型元数据,如日期、训练数据的大小。

数据

用于存储实验子集数据的文件夹。它包括原始数据和临时使用的处理过的数据。

  • raw:存储从“准备”文件夹代码生成的原始结果。我的做法是存储一个本地子集副本,而不是不时地从远程数据存储中检索数据。它保证您有一个静态数据集来执行其余的操作。此外,我们可以将数据*台不稳定问题和网络延迟问题隔离开来。
  • 已处理:为了缩短模型训练时间,保存已处理的数据是一个好主意。它应该从“处理”文件夹中生成。

笔记本

存储所有笔记本,包括 EDA 和建模阶段。

  • eda:探索性数据分析(又名数据探索)是为后面的步骤探索您所拥有的东西的一个步骤。对于短期的目的,它应该显示你探索了什么。典型的例子是显示数据分布。长期存放时,应集中存放。
  • poc:由于某些原因,你不得不做一些 PoC(概念验证)。它可以在这里临时展示。
  • 建模:笔记本包含您的核心部分,其中包括模型建立和培训。
  • 评估:除了建模,评估是另一个重要的步骤,但很多人并不知道。为了获得产品团队的信任,我们必须展示模型有多好。

拿走

要访问项目模板,您可以访问这个 github repo。

  • 前述对中小型数据科学项目有好处。
  • 对于大型数据科学项目,它应包括其他组件,如特征库和模型库。以后会为这部分写博客。
  • 根据你的情况修改了

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和*台相关领域的最新发展。你可以通过媒体博客、 LinkedIn 或 Github 联系我。

参考

微软数据科学项目模板

Cookiecutter 数据科学目录结构

使用 MLflow 管理您的机器学习生命周期—第 1 部分。

原文:https://towardsdatascience.com/manage-your-machine-learning-lifecycle-with-mlflow-part-1-a7252c859f72?source=collection_archive---------1-----------------------

重现性,良好的管理和跟踪实验是必要的,以方便测试他人的工作和分析。在第一部分中,我们将从简单的例子开始学习如何记录和查询实验,包装机器学习模型,以便它们可以在任何使用 MLflow 的*台上重现和运行。

机器学习生命周期难题

机器学习(ML)并不容易,但创建一个良好的工作流,让您可以重现、重新访问并部署到生产中,就更难了。在为 ML 创建一个好的*台或管理解决方案方面已经取得了很多进展。注意,t his 不是数据科学(DS)生命周期,后者更复杂,有很多部分。

ML 生命周期存在于 DS 生命周期中。

您可以在此处查看一些用于创建 ML 工作流的项目:

[## 厚皮动物/厚皮动物

厚皮动物-大规模可再生数据科学!

github.com](https://github.com/pachyderm/pachyderm) [## 燃烧/泄漏

mleap - MLeap:将 Spark 管道部署到生产中

github.com](https://github.com/combust/mleap)

这些包很棒,但是不容易理解。也许解决方案是这三者的混合,或者类似的东西。但在这里,我将向您展示由 Databricks 创建的最新解决方案,名为 MLflow。

MLflow 入门

MLflow 是一个完整的机器学习生命周期的开源*台。

MLflow 设计用于任何 ML 库、算法、部署工具或语言。将 MLflow 添加到您现有的ML 代码中非常容易,因此您可以立即从中受益,并且可以使用您组织中的其他人可以运行的任何 ML 库来共享代码。MLflow 也是一个用户和库开发者可以扩展的开源项目。

安装 MLflow

安装 MLflow 非常简单,您只需运行:

pip install mlflow

这是根据创作者所说的。但是我在安装的时候遇到了几个问题。所以下面是我的建议(如果安装 ignore 后可以在终端中运行 mlflow 的话):

来自 Databricks: MLflow 不能安装在 Python 的 MacOS 系统安装上。我们推荐使用brew install python通过自制包管理器安装 Python 3。(在这种情况下,安装 mlflow 现在是pip3 install mlflow)。

这对我不起作用,我得到了这个错误:

~ ❯ mlflow
Traceback (most recent call last):
  File "/usr/bin/mlflow", line 7, in <module>
    from mlflow.cli import cli
  File "/usr/lib/python3.6/site-packages/mlflow/__init__.py", line 8, in <module>
    import mlflow.projects as projects # noqa
  File "/usr/lib/python3.6/site-packages/mlflow/projects.py", line 18, in <module>
    from mlflow.entities.param import Param
  File "/usr/lib/python3.6/site-packages/mlflow/entities/param.py", line 2, in <module>
    from mlflow.protos.service_pb2 import Param as ProtoParam
  File "/usr/lib/python3.6/site-packages/mlflow/protos/service_pb2.py", line 127, in <module>
    options=None, file=DESCRIPTOR),
TypeError: __init__() got an unexpected keyword argument 'file'

解决这个问题的方法并不容易。我用的是 MacOS btw。为了解决这个问题,我需要更新 protobuf 库。为此,我安装了 Google 的 protobuf 库,其来源为:

[## 谷歌/protobuf

protobuf -协议缓冲区-谷歌的数据交换格式

github.com](https://github.com/google/protobuf/releases)

下载 3.5.1 版本。我之前有过 3.3.1。请遵循以下步骤:

[## 安装协议

使用现代 Haskell 语言和库模式的协议缓冲 API。

google.github.io](http://google.github.io/proto-lens/installing-protoc.html)

或者试着用自制的。

如果您的安装工作正常,运行

mlflow

你应该看看这个:

Usage: mlflow [OPTIONS] COMMAND [ARGS]...Options:
  --version  Show the version and exit.
  --help     Show this message and exit.Commands:
  azureml      Serve models on Azure ML.
  download     Downloads the artifact at the specified DBFS...
  experiments  Tracking APIs.
  pyfunc       Serve Python models locally.
  run          Run an MLflow project from the given URI.
  sagemaker    Serve models on SageMaker.
  sklearn      Serve SciKit-Learn models.
  ui           Run the MLflow tracking UI.

MLflow 快速入门

现在您已经安装了 MLflow,让我们运行一个简单的示例。

**import** **os**
**from** **mlflow** **import** log_metric, log_param, log_artifact

**if** __name__ == "__main__":
    *# Log a parameter (key-value pair)*
    log_param("param1", 5)

    *# Log a metric; metrics can be updated throughout the run*
    log_metric("foo", 1)
    log_metric("foo", 2)
    log_metric("foo", 3)

    *# Log an artifact (output file)*
    **with** open("output.txt", "w") **as** f:
        f.write("Hello world!")
    log_artifact("output.txt")

将其保存到 train.py,然后使用

python train.py

您将看到以下内容:

Running test.py

就这样吗?没有。使用 MLflow,您可以通过编写以下内容轻松访问用户界面:

mlflow ui

您将看到(localhost:默认为 5000):

那么到目前为止我们做了什么?如果你看到代码,你会看到我们使用了两个东西,一个 log_param,log _ metric 和 log_artifact。第一个记录当前运行下传入的参数,如果需要的话创建一个运行,第二个记录当前运行下传入的度量,如果需要的话创建一个运行,最后一个记录一个本地文件或目录作为当前活动运行的工件。

通过这个简单的例子,我们了解了如何在生命周期中保存参数、指标和文件的日志。

如果我们点击运行的日期,我们可以看到更多的信息。

现在,如果我们单击该指标,我们可以看到它在运行过程中是如何更新的:

如果我们单击工件,我们可以看到它的预览:

物流跟踪

MLflow 跟踪组件允许您使用 REST 或 Python 记录和查询实验。

每次运行记录以下信息:

代码版本: Git commit 用于执行运行,如果它是从 MLflow 项目中执行的。

开始&结束:运行的开始和结束时间

源:为启动运行而执行的文件的名称,或者如果运行是从 MLflow 项目中执行的,则为运行的项目名称和入口点。

参数:键值输入你选择的参数。键和值都是字符串。

指标:值为数字的键值指标。在整个运行过程中,可以更新每个指标(例如,跟踪模型的损失函数如何收敛),MLflow 将记录并让您可视化指标的完整历史。

工件:输出任意格式的文件。例如,您可以将图像(例如,png)、模型(例如,腌制的 SciKit-Learn 模型)甚至数据文件(例如,拼花文件)记录为工件。

可以有选择地将运行组织成实验,这些实验将特定任务的运行组合在一起。您可以通过mlflow experiments CLI、使用[**mlflow.create_experiment()**](https://mlflow.org/docs/latest/python_api/mlflow.html#mlflow.create_experiment)或通过相应的 REST 参数创建一个实验。

*# Prints "created an experiment with ID <id>*
mlflow experiments create face-detection
*# Set the ID via environment variables*
export MLFLOW_EXPERIMENT_ID=<id>

然后你开始一个实验:

*# Launch a run. The experiment ID is inferred from the MLFLOW_EXPERIMENT_ID environment variable***with** mlflow.start_run():
    mlflow.log_parameter("a", 1)
    mlflow.log_metric("b", 2)

跟踪示例:

一个使用葡萄酒质量数据集的简单例子:包括两个数据集,分别与来自葡萄牙北部的红葡萄酒和白葡萄酒相关。目标是基于物理化学测试来模拟葡萄酒质量。

首先下载该文件:

https://raw . githubusercontent . com/databricks/ml flow/master/example/tutorial/wine-quality . CSV

然后在文件夹中创建文件 train.py,内容如下:

*# Read the wine-quality csv file*

data = pd.read_csv("wine-quality.csv")

*# Split the data into training and test sets. (0.75, 0.25) split.*
train, test = train_test_split(data)

*# The predicted column is "quality" which is a scalar from [3, 9]*
train_x = train.drop(["quality"], axis=1)
test_x = test.drop(["quality"], axis=1)
train_y = train[["quality"]]
test_y = test[["quality"]]

alpha = float(sys.argv[1]) **if** len(sys.argv) > 1 **else** 0.5
l1_ratio = float(sys.argv[2]) **if** len(sys.argv) > 2 **else** 0.5

**with** mlflow.start_run():
    lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
    lr.fit(train_x, train_y)

    predicted_qualities = lr.predict(test_x)

    (rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)

    print("Elasticnet model (alpha=*%f*, l1_ratio=*%f*):" % (alpha, l1_ratio))
    print("  RMSE: *%s*" % rmse)
    print("  MAE: *%s*" % mae)
    print("  R2: *%s*" % r2)

    mlflow.log_param("alpha", alpha)
    mlflow.log_param("l1_ratio", l1_ratio)
    mlflow.log_metric("rmse", rmse)
    mlflow.log_metric("r2", r2)
    mlflow.log_metric("mae", mae)

    mlflow.sklearn.log_model(lr, "model")

在这里,我们将为 SciKit-Learn 介绍 MLflow 集成。运行后,您将在终端中看到:

Elasticnet model (alpha=0.500000, l1_ratio=0.500000):
  RMSE: 0.82224284976
  MAE: 0.627876141016
  R2: 0.126787219728

然后在包含mlruns目录的同一个当前工作目录中运行 mlflow ui,并在浏览器中导航到 http://localhost:5000 。你会看到:

每次跑步你都会有这个,这样你就可以跟踪你做的每一件事。该模型还有一个 pkl 文件和一个 YAML,用于部署、复制和共享。

敬请关注更多

在下一篇文章中,我将介绍项目和模型 API,我们将能够在生产中运行这些模型,并创建一个完整的生命周期。

请务必查看 MLflow 项目以了解更多信息:

[## 数据块/ml 流

mlflow -完整机器学习生命周期的开源*台

github.com](https://github.com/databricks/mlflow)

感谢你阅读这篇文章。希望你在这里发现了一些有趣的东西:)

如果你有任何问题,请在推特上关注我

[## 法维奥·巴斯克斯(@法维奥·巴斯克斯)|推特

Favio Vázquez 的最新推文(@FavioVaz)。数据科学家。物理学家和计算工程师。我有一个…

twitter.com](https://twitter.com/faviovaz)

还有 LinkedIn。

[## Favio Vázquez —首席数据科学家— OXXO | LinkedIn

查看 Favio Vázquez 在世界上最大的职业社区 LinkedIn 上的个人资料。Favio 有 15 个工作职位列在…

linkedin.com](http://linkedin.com/in/faviovazquez/)

那里见:)

管理深度学习中的实验

原文:https://towardsdatascience.com/managing-experimentation-in-deep-learning-ca6db050b104?source=collection_archive---------8-----------------------

使用深度学习包括运行无数的实验来测试一个人可能有的各种假设,以解决特定的问题,或者通过尝试多个超参数来获得更好的结果。随着时间的推移,这些实验的数量越来越多,管理它们甚至试图反映几周前做了什么可能会有点困难。在这篇文章中,我计划分享一些我使用的技巧或窍门(作为一名全职从事深度学习的研究生),以保持事情有序,防止自己迷失在一堆懒洋洋定义的日志文件中,如 exp0、exp1、newexp。

保持同步

我(我想也有很多其他人)在基于 GPU 的 linux 服务器上运行实验,然后将结果复制回主机进行分析。这种类型的数据可能包括 csv/txt 文件、tensorboard 日志或图像。

我发现 rsync 是一个完美的工具(我以前习惯于 scp ),它的主要优点是只同步源和目的地之间的差异。当培训正在进行中(预计需要很长时间)并且我们想要监控进度时,这是很有帮助的。我通常在生成模型上工作,所以我需要不时地通过浏览各个时期生成的东西来检查我的 GAN 是否变得疯狂了。

最简单的方法是:

rsync -av <username>@remote-host:<path_to_results_folder> .

在这里,-a将递归地传输所有内容,-v代表详细程度。这相当快。此外,如果你的服务器是通过网关,你需要事先登录。

使用 rsync 可以做很多事情,例如,在生产环境中部署模型,或者设置一个 cronjob 以固定的时间间隔提取日志。参考这篇文章来看看后者是如何实现的。

张量板

许多人都不知道 Tensorflow 的惊人可视化工具 Tensorboard 可以作为一个独立的实用程序来绘制几乎任何东西的漂亮的交互式曲线。我通常坚持只绘制标量,以使事情变得更快更轻(传输和加载时间)。APItensor board-py torch在这方面真的很牛逼。我不知道为什么他们称它为“-Pytorch”,因为它很普通。通过pip install tesorboardX安装。

from tensorboardX import SummaryWriter
writer = SummaryWriter(log_dir=<path_to_log>)
for i in range(num_epochs):
    loss = forward_pass()
    writer.add_scalar('loss', loss)

我们结束了。接下来,启动 tensorboard 并查看剧情:tensorboard --logdir <path_to_log>。为了比较来自多个实验的损失(或任何其他度量),<path_to_log>可以是tb_log/<exp_name>,其中tb_log是包含每个实验的子目录的目录。接着,启动 tensorboard 时的logdir标志的值会变成tb_log

如果在远程服务器上,我建议将日志文件拉回到本地,然后从那里启动 tensorboard。上一节中的rsync命令可用于定期更新tb_log中的文件,同时保持 tensorboard 在后台运行。

或者,tensorboard 可以在远程服务器上启动,仪表板可以通过public IP:port(6006 is default)导航。如果远程服务器没有公共 IP 地址,可以使用 SSH 隧道。例如,如果我在默认端口 6006 上的某个 IP 为 10.11.12.13 的服务器上启动 tensorboard,我可以通过以下方式将其传输到我的本地计算机:

ssh -N -f -L localhost:6006:10.11.12.13:6006 username@10.11.12.13

其中localhost:6006:10.11.12.13:6006<destination_address>:<destination_port>:<source_address>:<source_port>

通过 gif 跟踪图像生成进度

为了容易地定性评估模型的进展,可以很容易地创建随时间生成的样本的 gif。

from torchvision import make_grid
import imageio
grid = []
for i in range(num_epochs):
    samples = forward_pass()
    # the following functions are in context of pytorch
    grid.append(make_grid(samples).permute(1, 2, 0).numpy())
imageio.mimsave('generations.gif', grid)

我们需要将生成的形状样本(batch_size,channels,height,width)转换为(height,width,channel ),因此首先将图像连接起来形成一个网格,然后转置维度并转换为 numpy 数组。

这使得人们不必仔细检查和比较为每个时期分别生成和保存的图像。

Source: https://docs.floydhub.com/examples/dcgan/

测井实验

并不是我们运行的所有实验都在 excel 表中,即使这样,也很难在一个紧凑的二维表中捕获所有信息,即与每个实验相关的所有设置和更改。为了确保我过去运行的所有实验都被记录在某个地方,而不需要任何额外的努力(因为我不在乎在凌晨 3 点记录实验),从 bash 文件运行所有实验(并不断注释掉以前运行的实验)。

这也让你可以自由地输入关于这些实验的任何注释或评论。您可以对某些超参数的不同值进行循环,以便一次运行多个实验。如果你的组织使用像 Slurm (像 mine )这样的工作量管理器,那么遵循这种技术也更有意义。

Experiment Logging

我知道有很多令人惊讶的工具专门用来管理这个,比如神圣,但是我更喜欢坚持老派的日志风格。

这些是我每天为了让生活变得更轻松而练习的一些事情。如果你认为这些是次优的,或者你有其他的锦囊妙计,让我知道,我很乐意学习:)

这是我很长一段时间以来的第一篇文章,也是机器学习领域的第一篇文章,我已经为此工作了一段时间。我计划分享我正在学习的和到目前为止学到的东西。反馈将有助于提高未来内容的质量。

曼加甘

原文:https://towardsdatascience.com/mangagan-8362f06b9625?source=collection_archive---------3-----------------------

教电脑用漫画绘制新的和原创的漫画和动画脸

Manga and anime faces generated with a model trained for 100 epochs

漫画和动画因其复杂的艺术风格和引人入胜的故事而受到全世界的赞赏。这个游戏的粉丝群是如此庞大,以至于有成千上万的艺术家在那里绘制原创漫画和动漫角色,也有成千上万的人想要创造它们。然而,绘画需要大量的时间、努力、技巧和创造力。生成漫画和动画角色可以帮助弥补技能差距,并提供创造自定义角色的机会。我最终想实现我自己的 GAN 来绘制行业标准的漫画和动漫人物,但为了这个项目的目的,我想学习更多关于 GAN 的知识,并挑战自己绘制出我能做到的最佳质量的图像,因为现实中人类会接触到许多折衷的风格。

Real samples, some containing false positives before data cleaning

视频游戏行业是第一个开始认真试验使用人工智能生成原始内容的娱乐领域。除了目前计算机游戏和机器学习之间的重叠,鉴于现代 AAA 视频游戏的 3 亿多美元预算,投资视频游戏开发自动化肯定有巨大的成本激励。

数据准备

用大约 143,000 幅图像的数据集来训练这些图像。众所周知,要生成符合行业标准的图像,高质量的图像数据集即使不是最重要的,也是必不可少的。使用的图像是从 Danbooru 抓取的——一个图像板,可以访问大量足够的图像来训练图像生成模型。这些图像板允许上传风格、领域和质量高度不同的图像,并认为这是真人面部和动漫人物面部之间质量差距的重要部分。图像的质量如此多样化,以至于它们可以是抽象的,所以我希望通过产生具有独特风格的更清晰的数据集来继续这个项目。

抓取图像后,我用[python-animeface](https://github.com/nya3jp/python-animeface)来裁剪图像。这个图像级联专门用于检测动画和漫画的人脸,也同样适用。这个过程是多线程的,有 12 个池,但下面是每个映像的基本情况:

import animeface
from PIL import Image

img = Image.open('data/anime_image_usagi_tsukino.png')
faces = animeface.detect(img)
x,y,w,h = faces[0].face.pos
img = img.crop((x,y,x+w,y+h))
img.show() 

我手动检查误报,因为一些图像。我最终消除了 3%的误报。

使用深度卷积生成对抗网络(DCGAN)的目标

人工智能研究人员到底为什么要构建复杂的系统来生成看起来有点不靠谱的卡通人脸图片?

这件事很酷的一点是,它需要理解这些图片才能生成它们——就像艺术家在画一张脸之前需要理解它需要什么一样。

看这张照片:

An anime face. Specifically, Misty from Pokémon, whose one of my favorite anime characters.

对于那些看动漫的人来说,你会立刻知道这是一张动漫脸的图片——一张源自日本的艺术风格的卡通脸。对计算机来说,这只是一个代表像素颜色的数字网格。它不明白这应该是一张动漫脸,更不用说代表什么概念了。

如果我们向计算机展示数以千计的这些日本风格的卡通面孔,在看到这些图片后,计算机能够绘制原始的动漫面孔——包括不同发型、不同眼睛颜色、不同性别、不同视角的面孔,以至于艺术家可以要求它绘制特定类型的面孔,例如“留着蓝色短发、戴着眼镜、戴着猫耳朵、脸上带着微笑的漫画或动漫女孩。”

如果计算机能够用相应的面部特征绘制这些脸,这意味着它们知道如何在没有任何明确指示的情况下绘制新的角色(至少在儿童水*上)。

作为一名开发人员和艺术家,看到研究人员追求这一点是令人兴奋的。这些生成模型让计算机以一种可以转化为前所未见的概念的方式理解数据,而无需理解该概念的含义。我们仍然处于基于机器学习的生成模型的早期,它们的实际用途目前还很有限,但它们非常有趣。看看人工智能是否能为艺术或娱乐业做出贡献,这将是一件有趣的事情。

“我从认知系统中寻找的不仅仅是另一种形式的计算,而是在我们的生活中创造一种存在,并通过这种存在来激励我们。”

—IBM 沃森副总裁兼首席技术官罗布·海

模型是如何工作的?

DCGAN 由两个神经网络组成:一个生成器和一个鉴别器。这是一场看谁能胜过对方的战斗,结果是两个网络都变得更强大。

让我们假设第一个神经网络是一个首席动画师,他正在审查一部新动画的创意。为了防止诉讼,它被训练来识别在以前的展览或书籍中见过的图画。它的工作是观察面孔,看看是否有适合他们节目的新面孔。

一个卷积神经网络在这种情况下起作用,因为我们需要做的只是拆开一幅图像,将它分成几层并处理每一层,识别图像中的复杂特征,并输出一个值来指示图像中是否有真实的动漫脸。第一个网络是鉴别器:

Discriminator Network

接下来,让我们假设第二个网络是一个全新的动画师,他刚刚学会如何绘制新鲜的动画面孔,这样就不会有人因侵犯版权而被起诉。这位动画师将向一家大型动画公司的首席动画师推销一个新的创意。在第二个网络中,这些层被反转为正常的 ConvNet。这个网络不是像第一个网络那样拍一张照片输出一个值,而是取一个值的列表输出一张照片。

第二个网络是发生器:

Generator Network

现在,我们有了一个寻找重复使用的面孔的主动画师(T6 鉴别师),和一个绘制新面孔的新动画师(T8 生成器)。决斗的时候到了!

第一回合

生成器将绘制一个…有趣的动漫脸副本,它不像一个新的行业质量的脸,因为它不知道动漫脸看起来像什么:

The Generator makes the first (…interesting) manga/anime face

但是现在鉴别器在识别图画的工作上同样糟糕,所以它不会知道区别:

The Discriminator think’s it’s a fresh, industry quality face. Maybe for a YouTube show

现在我们必须告诉鉴别者,这实际上是一张不符合我们标准的脸。然后我们给它看一张真实完整的动漫脸,问它和假的有什么不同。鉴别器寻找新的细节来帮助它区分真假。

例如,鉴别者可能会注意到一张完整的动漫脸有一定的比例。利用这些知识,鉴别者学会了如何辨别真伪。它的工作变得更好了:

The Discriminator levels up! It now can spot very bad fake faces

第二轮

我们告诉生成器,它的动画和漫画图像突然被拒绝为假的,所以它需要加强它的游戏。我们还告诉它,鉴别器现在正在寻找人脸上的特定比例,因此混淆鉴别器的最佳方法是在人脸上绘制这些特征:

The Generator produces a slightly better drawn manga/anime face

假面又被认为是有效的了!现在鉴别者不得不再次看真实的脸,并找到一种新的方法来区分它和假的脸。

生成器和鉴别器之间的这种来回博弈会持续数千次,直到两个网络都成为专家。最终,发生器产生了新的、*乎完美的面孔,鉴别器变成了一个动漫鉴赏家和评论家,寻找最细微的错误。

当两个网络都经过足够的训练,使得人类对假图像印象深刻时,我们就可以将假图像用于任何目的。

结果

我在 100 个时代训练了我的网络,并设法绘制了一些具有独特风格的新面孔。我继续致力于我的实现,并计划用 DRAGAN 和不同的数据集进行实验,以提高生成的质量。

观察前四个时期,发生器的输出接*纯噪声。随着发电机学会做得更好,新面孔慢慢开始成形:

随着训练的深入,生成器会给每个角色画出更均匀的比例。下面是使用 IPython 和经过训练的模型生成的一些结果:

Image interpolation by changing the latent z vector

因为这些图片都有自己的标签,所以在运行网络时记住特定的属性会很有趣。我用不同的头发颜色作为参数再次运行了网络。这一次,鉴别器使用头发颜色来区分人脸,生成器在重新绘制人脸时会考虑到这一点:

Characters with green hair

Characters with blue hair

Characters with blonde hair

结论

这是一个有趣的项目,到目前为止,我学到了很多关于训练甘以及如何优化他们。如果你想了解更多关于 GANs 以及如何训练它们,我强烈推荐你访问这篇文章来了解未来的技巧,因为它们对学习过程非常有帮助。训练 GANs 时,回流训练数据肯定是可能发生的事情。通过使用大量的训练数据集和较短的训练时间,有可能减少这种情况发生的几率。这是一个棘手的问题,对它的研究仍在继续,但希望这能成为建立干净数据集以产生高质量结果的动力。

这个项目绝不是提议取代努力工作的动画师和艺术家——这是一门非凡的艺术,这是为了纪念那些献身于掌握这门艺术的人。这是为了找到计算机不仅可以理解如此复杂的概念的方法,并希望激发所有层次的人欣赏艺术并为艺术做出贡献。我希望这个项目刺激更多关于漫画和动画风格图像的生成模型的研究,并最终帮助业余爱好者和专业人士设计和创造艺术,让尽可能多的人享受。

宣言:人类学习的时间到了

原文:https://towardsdatascience.com/manifeto-time-for-humanness-learning-51051befa5f4?source=collection_archive---------7-----------------------

Alan Turing

半兽半机……美在哪里?​

野兽是一种生物机器。那么有什么区别呢?

是什么让机器意识到自己?

是什么让我们成为人类?不是与其他动物相比,而是真正的人?​

我们如何成为人类?人性是遗传的还是习得的?​

人性能像童贞一样失去或像经验一样获得吗?

你觉得这些问题很蠢是因为我们默认是人类吗?

那些在奥斯威辛、布痕瓦尔德和达豪集中营烧死了数百万人的人类呢?

作为人类到底意味着什么?

似乎我们都知道答案,但是我们不能把这些知识用语言表达出来。​

这是一种隐性知识,不是吗?​

精神在哪里?灵魂是什么?

也许,做人终究是一种精神体验?

我们不能确定是否有任何东西存在于我们感觉的膜之外。然而,我们可以操纵我们的感觉,认为我们控制着自然法则或我们周围的神秘力量,或者两者兼而有之。

那么,人性就是傲慢和骄傲吗?我们在动物和机器中都找不到它们。

我们相信人性的意义不止于此。

也许,人性是从母亲抱着婴儿开始讲故事开始的。一个童话。婴儿感受到她温柔的触摸,听到她亲切关怀的声音……在睡眠和现实的边缘,婴儿的大脑开始在母亲大脑神经元跟随母亲说话的节奏放电的相同区域放电。人性的神奇火花闪现…

我们能量化人性吗?我们能评价它吗?​

文明人比野蛮人更有人性吗?​

一个连环杀手和一个无辜的孩子呢?

反社会者是人吗?​

人性可以简化为自然法则吗?​

如果我的脚后跟发痒,我可以选择挠它或者忽略它。我可以用我思想的纯粹力量来控制我身体的生物机器。据我所知,我的身体按照自然法则工作。因此,通过挠我的脚后跟,我用我思想的纯粹力量让自然法则服从我。

寻找人性的源泉就像追逐地*线:你走得越快,它跑得越快。​

我们到底为什么要抓它?​

如果我们相信人类不仅仅是智能生物机器,这是有原因的。​

因为现在从自动驾驶汽车到智能城市等各种各样的例子中发展的人工智能不会自动变成人类。如果不知道是什么让我们成为人类,我们就有可能创造出一个超级聪明的反社会者。或者一群超级聪明,超级强大的反社会者。人工智能不需要一般才会变得危险。

我们也感觉到,我们周围越来越多的人正把他们的人性交给他们的兽性或机器起源。我们不知道是否有不寻常的事情正在发生,或者这只是一个正常的过程,但我们对它的反应也是正常的。我们希望让这些人变得更有人情味。我们希望能尽快完成,以免为时过晚。

我们挖掘人性第一原则的方式是通过在我们暂时称之为人性发展的领域中开发产品。

我们相信,神经科学家已经发现了一些最实用和有效的方法,通过这些方法,人类的记忆和检索在人脑中进行,并在它们之间转移。

我们也相信人工智能领域的科学家已经在机器学习算法中成功地重现了这些手段。​

这些方法可能看起来太简单,甚至很原始,但科学证明它们确实有效。这些手段都是故事。问题是:哪些故事最适合学习人性?怎么才能挑对呢?

对童话和神话的比较系统发育研究,通过追溯从我们的时代到人们刚刚发现语言的时代的相同故事,为我们提供了上述问题的答案。

三条研究路线(神经科学+故事,人工智能+故事,系统发生学+故事)到目前为止基本上是*行的,现在是融合的时候了。作为一门学科,人性学习可能会出现。

自 2016 年 10 月以来,我们一直在秘密开发我们的项目。

是时候让我们走出来,开始建立一个由人工智能科学家、神经科学家、语言学家、游戏开发者、文学史家、电影制片人、作家、企业家组成的社区了——所有这些人都因为发现人类第一原则的热情而团结起来——此外,还因为真正希望为人类和机器提供令人信服的、高效的学习和重新学习人类的工具。

尤里·巴尔佐夫

瓦迪姆·切尔达克

叶卡捷琳娜·马特斯克维奇

谢尔盖·奥尔洛夫斯基

里亚博夫

伊万·苏希

流形学习:背后的理论

原文:https://towardsdatascience.com/manifold-learning-the-theory-behind-it-c34299748fec?source=collection_archive---------11-----------------------

流形学习已经成为几何,尤其是微分几何在机器学习中的一个令人兴奋的应用。但是,我觉得算法背后有很多被忽略的理论,理解它将有助于更有效地应用算法( 见此 )。

我们将从什么是流形学习以及它在机器学习中的应用开始这个相当长的论述。流形学习仅仅是使用高维数据的几何属性来实现以下事情:

  1. 聚类:找到相似点的组。给定{X1,…,Xn},构造一个函数 f : X 到{1,…,k}。两个“接*”的点应该在同一个簇中。
  2. 降维:在低维空间中投影点,同时保留结构。给定 R^D 的{X1,…,Xn},构造一个函数 f : R^D 到 R^D,其中 d
  3. 半监督、监督:给定标记点和未标记点,建立一个标记函数。给定{(X1,Y1),…,(Xn,Yn)},建立 f : X 到 y。两个“接*”的点应该有相同的标签。

其中“接*”的概念使用数据的分布被进一步细化。有几个框架可以实现这一点:

  1. 概率观点:密度缩短了距离
  2. 聚类视点:连通区域中的点共享相同的属性
  3. 流形观点:距离应该“沿着”数据流形测量
  4. 混合版本:两个“接*的”点是那些通过穿过高密度区域的短路径连接的点

我们要讨论的第一个概念是拉普拉斯正则化,它可以在监督和半监督学习中用作正则化器,并通过投影到拉普拉斯的最后一个特征向量来进行降维。

让我们理解拉普拉斯在这个上下文中的意思。拉普拉斯仅仅是度矩阵(这是对每个顶点上有多少条边的度量)减去邻接矩阵(这是对各个顶点如何相互连接的度量)。现在我们已经准备好开始理解第一种方法:拉普拉斯正则化

拉普拉斯正则化

正则化在减少过度拟合和确保模型不会变得太复杂方面非常有用。使用拉普拉斯算子来正则化扩展了首先在吉洪诺夫正则化中使用的思想,吉洪诺夫正则化应用于再生核希尔伯特空间(RKHS)。

我们不需要深入 RKHS 的细微差别,但我们肯定需要了解的主要结果是,在 RKHS,对于函数空间 X 中的每个函数 X,在核中存在唯一的元素 K_x,它允许我们为每个函数定义一个范数||f||表示 RKHS 中函数的复杂性(机器学习情况下的学习映射函数),我们可以使用它来正则化算法。所以问题会变成

这种正则化叫做外在正则化。现在拉普拉斯正则化增加了另一个称为内在正则化的正则化,它考虑了流形的内在几何并使用它来正则化算法。如何定义正则化子有几种选择,但大多数定义都围绕着流形上的梯度。我们希望正则化器惩罚那些不必要的复杂函数(当数据密集时)。换句话说,我们希望函数在数据密集时是光滑的,这也意味着当数据的边际概率密度较大时,函数在流形上的梯度必须较小。这被形式化为

如果我们可以直接计算这个积分,那将是非常棒的,但与大多数机器学习概念一样,实现它需要使用可用数据进行某种形式的估计。在这种情况下,我们需要将数据点视为图上的点,并基于某种距离概念将它们连接起来。这通常是通过实现某个函数并施加一个条件来实现的,如果距离(使用该函数导出)小于某个特定值,则这两个点用一条边连接。一个这样的函数是标准高斯函数:

现在我们需要一个估计积分的方法。进行完整的推导会使这篇文章太长,所以我将概述涉及的主要思想:使用斯托克斯定理和拉普拉斯*似拉普拉斯-贝尔特拉米算子的事实,我们可以推导出大量数据点的积分的*似。因此,正则化可以估计为

其中 f 是数据处的函数的向量值,n 是数据点的数量(标记的和未标记的)。所以现在要解决的最后一个问题变成了

与其他核方法一样,主要缺点是希尔伯特空间可能是无限维的,如果正则化不能显式地找到,就不可能在空间中搜索解。因此,对正则化(严格单调递增的实值函数)施加某些条件,并使用著名的表示定理,我们可以将期望的函数分解成权重为α的有限维空间,使得

现在我们只需要在有限维空间中搜索α的值来求解我们想要的函数。

与 L1 或 L2 正则化相比,这是一种更复杂的正则化,但它与数据的几何关系非常密切,这似乎有助于确保模型不会过度拟合。

拉普拉斯特征映射

拉普拉斯特征映射使用与上述正则化类似的推理,只是它应用于维数减少而不是正则化。我们首先生成一个图,图中的顶点是数据点,并且连接了相距特定距离(准确地说是欧几里得距离)且距离较小的点。然后添加权重,通常是根据热核。最后,计算特征值和特征向量,并且使用最小的特征向量将数据空间嵌入到 m 维空间。形式上,

解决这个特征向量问题

现在,我们可以将数据投影到前 m 个特征向量 f1…fm 上,从而有效地降低数据的维数。

结论

概括地说,我们介绍了什么是流形学习,其中利用数据的几何来使算法更有效(通过减少过拟合或维数)。接下来,我们特别讨论了两个过程,拉普拉斯正则化和拉普拉斯特征映射。它们都基于图论和微分几何,理解它们背后的理论将有助于了解何时部署哪个过程以及某些数据结构如何影响这些过程的效率。

带 TensorFlow 的手动回推:解耦递归神经网络,从 Google Brain 修改 NN,用交互代码实现。

原文:https://towardsdatascience.com/manual-back-prop-with-tensorflow-decoupled-recurrent-neural-network-modified-nn-from-google-f9c085fe8fae?source=collection_archive---------7-----------------------

Photo from Pixel Bay

我喜欢 Tensorflow 及其执行自动微分的能力,但这并不意味着我们不能执行手动反向传播,即使在 Tensorflow 中。对我来说,建立一个神经网络也是一种艺术形式,我想掌握它的每一个部分。所以今天,我将在 TensorFlow 中使用手动反向传播实现简单分类任务的解耦 RNN。并与自动微分模型进行了性能比较。

解耦神经网络最初是在本文中介绍的使用合成梯度解耦神经接口请阅读。我还在解耦的 RNN 上实现了 Numpy 版本的。

最后,请注意这篇文章,我将更加关注 Tensorflow 的实现与 Numpy 的实现有何不同。并说明我喜欢 Tensorflow 实现的原因。

网络架构/前馈/反馈传播

如上所述,网络架构与 RNN 的 Numpy 版本以及前馈/反馈传播操作完全相同。所以我就不深入了。

数据准备\超参数声明

同样,我们将仅对 0 和 1 图像执行简单的分类任务。没什么特别的,但是请看屏幕截图的最后一行,我们正在创建我们的默认图,以便首先制作网络图和训练。(绿色方框区域)

原因一:数学方程实现

Numpy 版本和 TF 版本之间的一个关键区别是每个等式是如何实现的。例如,下面是我如何在 Numpy 中实现 Tanh()的导数。

def d_tanh(x):
   return 1 - np.tanh(x) ** 2

然而,在 Tensorflow 中,我会像下面这样实现它。

def d_tf_tanh(x):
    return tf.subtract(tf.constant(1.0),tf.square(tf.tanh(x)))

乍一看,这可能有点奇怪,但我个人更喜欢张量流的数学符号,主要原因是它让你在实现每个方程之前真正思考。

原因 2:迫使你思考独立的组件是如何组合在一起的。

Hyper Parameter Declaration Part

以上只是声明权重和学习率的部分,仅此而已。张量流迫使你专注于每个部分。

Network Architecture

以上部分迫使我思考网络架构,它让我专注于每一层。并让我思考我添加到网络中的每一层的效果。比如这一层会有怎样的整体效果?如何执行反向传播??这是这层的最佳选择吗?

最后,以上是培训部分,在这一部分,我可以专注于培训我的网络。我被迫只考虑我的训练的批量大小以及许多其他事情,只与训练有关。

原因 3:自动微分之间的切换和比较

如上所述,在声明成本函数的同时,我也可以声明优化方法。所以现在我可以自由地使用自动微分或手动反向传播。

我可以只注释掉输出的一部分,而不注释另一部分。

训练与结果:人工反向传播。

左图是每个训练循环的成本,右图是 20 个测试集图像的结果。现在让我们看看自动微分的结果。

训练和结果:自动分化。

我用的是学习率为 0.1 的随机梯度下降。就速度而言,它快得惊人。我认为代码首先被编译,也许这就是原因。然而,我很监督,它没有做好测试图像。

交互代码

我转移到 Google Colab 获取交互代码!所以你需要一个谷歌帐户来查看代码,你也不能在谷歌实验室运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问交互代码,请点击此链接。

遗言

尽管我很喜欢 tensorflow 的自动微分功能,但我认为仅仅依靠框架来训练模型并不是一个好主意。对我来说,建立神经网络是一种艺术形式,我想掌握它的每一个部分。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 找我。

与此同时,请在我的 twitter 这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。如果你感兴趣,我也在这里做了解耦神经网络的比较。

参考文献

  1. 贾德伯格,m .,Czarnecki,W. M .,奥辛德罗,s .,维尼亚尔斯,o .,格雷夫斯,a .,& Kavukcuoglu,K. (2016)。使用合成梯度的去耦神经接口。 arXiv 预印本 arXiv:1608.05343
  2. Seo,J. D. (2018 年 02 月 03 日)。Only Numpy:解耦递归神经网络,修改自 Google Brain 的 NN,实现用…2018 年 2 月 05 日检索自https://medium . com/swlh/only-Numpy-Decoupled-Recurrent-Neural-Network-modified-NN-from-Google-Brain-Implementation-with-7f 328 e 7899 e 6
  3. 阿洛尼博士(未注明)。丹·阿洛尼的博客。检索于 2018 年 2 月 5 日,来自 http://blog.aloni.org/posts/backprop-with-tensorflow/

多种语言的多种模型

原文:https://towardsdatascience.com/many-models-in-many-languages-620e9e1f3036?source=collection_archive---------5-----------------------

寻找最佳日常数据科学工具之旅。

Be fast, avoid the pitfalls I found! Or try them out anyway.

在过去的几年里,我一直在研究数据科学方法,试图学习机器学习以及如何有效地自动化自己。到目前为止,我在最后一点上还是非常失败,因为你变得越有效率,给你的工作就越多。但是,我没有把这些知识藏起来,而是分享一些,希望它能帮助你或世界上的其他人。

我仍在纠结的一件事是,我的任务应该使用哪种编程语言?也许你面临着同样的挣扎,或者也许你已经想出了你最喜欢的语言?就我个人而言,在这个星球上的学术生涯中,我是伴随着 c/c++和 Matlab 长大的,但我得到的印象是,你不再属于拥有这种特殊技能的“酷人”了。此外,我在工作中接触到许多语言,所以现在是时候提高我的知识了。

实验装置

在偶然发现了多模型范式,也被称为拆分-应用-组合之后,我意识到这就是我每天在工作中所做的事情。因此,我已经开始确定哪种语言最适合这个特定的任务。

首先,用半随机生成的数据创建一个数据集,这可能类似于我每天处理的数据。数据集足够大,以至于当你做错的时候会明显地减慢计算速度。我已经把数据和结果放到了一个 github repo 中。我不会深入建模细节,但本质上我只是想要计算数据中许多组的多元回归的残差。

这相当复杂,所以让我们来看看我的代码需求:

  • 应该是!计算时间很少,不允许喝咖啡。
  • 应该是容易写!节省你,人类,大量的时间。
  • 理想情况下,它看起来优雅易读。这完全是一个有待讨论的问题。

接下来,我将比较这些语言中的多种实现:

  • Matlab (我的专长,但专有)
  • Python (全才)
  • R (数据科学爱好者)
  • 朱丽娅(新来的,承诺速度!)

另外,我也在比较不同的概念:

  • 使用现成的建模包 vs. 手写的线性代数。
  • 自动分割应用方法(在数据帧上)与手动编写循环(在数组上)。

搜索解空间

The timing results of all the various solutions I tried so far.

各种尝试之间的执行时间存在巨大差异。特别是在 Matlab 中,你可能会失败得很惨,这经常发生在没有经验的用户身上,进一步增加了它糟糕的声誉。然而,通过一些好的选择,你可以在 Matlab 中做得很好。

这篇文章的灵感,Hadley Wickam 的 tidyverse 解决方案,在他的书 R for Data Science 中详述,也做得不太好。我是 tidyverse 哲学的忠实粉丝,尤其是用于可视化的 ggplot,但显然不应该因为它的计算效率而选择它。

非常有效的方法是自己写出模型的线性代数,以及一个允许你自动进行分割应用的包。最终,data.table 包和一个矩阵 QR 求解器一起胜出。然而,正如一位同事急切指出的,这本质上是对核心 c/c++代码的包装。因此,也许并不是真正的 R 语言赢了。

我还想回到 Julia,它保证了开发的速度和简易性。它还没有打败 data.table,但是我只需要两次简单的尝试就可以让它表现出色!

最后,还有 Python。我最不喜欢这种语言,这可能解释了为什么我不能让它像其他语言一样在 1 秒内运行。如果你知道谁愿意帮助我,我将不胜感激!

最后,现成的 dataframe 方法通常优于跨阵列的初始 for 循环。如果付出额外的努力,后一种方法可以达到类似甚至更好的性能,但几乎没有回报。另一方面,编写自己的模型显然有助于缩短执行时间,因为上图中所有缓慢的解决方案都使用了通用的建模包。除非速度不成问题,否则我建议定制型号。

诗歌

Comparing the results of my favorite attempts in each language

在编写所有这些脚本和函数的时候,我想用另一种语言一遍又一遍地写同一首诗。每种语言的语法可能看起来不同,但总体概念是完全相同的。在这里,我想向您展示我最喜欢的解决方案的美妙之处。

在定义了残差计算函数之后,一切都在名为*df* 的数据帧(或表格)上运行,该数据帧包含两个组索引、两个预测器*A**B*以及一个估计器*Z*。对你们中的一些人来说,下面显示的片段是微不足道的,对其他人来说,它们可能看起来像黑色的魔法咒语。

我不会在所有语言中展示建模函数,但正如下面 R 中的代码示例所示,这几乎不比通过residuals(lm(Z ~ poly(A,B,degree=3))调用一般的线性建模函数lm更费力,但速度却快了 10 倍:

calc_poly_residuals <- function(A,B,Z) {
  # construct the model matrix
  M <- cbind(A*0+1, A, B, A*B, A^2, A^2*B, B^2, A*B^2, A^3, B^3)
  # calculate residuals after solving M*c = Z
  resid <- Z - M %*% solve(qr(M, LAPACK = TRUE), Z)
}

稀有

下面是 R data.table 解决方案。简短、抽象、快速:

df[,resid:=calc_poly_residuals(A,B,Z), by=.(num_group,cat_group)]

朱莉娅

Julia 解决方案只需要多一点代码:

by(df,[:num_group,:cat_group],df -> DataFrame(resid = calc_poly_residuals(df)))

计算机编程语言

显然,Python 更喜欢面向对象的语法:

df_grouped = df.groupby(['cat_group', 'num_group'])
resid = df_grouped.apply(calc_poly_residuals)

矩阵实验室

Matlab 喜欢在函数调用中使用单独的数组:

G = findgroups(df.num_group,df.cat_group);
resid = splitapply(@calc_poly_residuals,df.A,df.B,df.Z,G);

结论

首先,尝试所有这些语言和概念对我的学习很有帮助。虽然我仍然不知道我更喜欢用哪种语言来执行这些模型,但是现在我已经可以使用它们了。当我与我的雇主的其他数据科学团队互动时,这很方便,他们都有自己喜欢的。

相当惊人的是,手工制作自己的模型或算法回报显著!另一方面,您可以将数据处理留给外部包。这很符合我自己的喜好;忽略数据管理,深入思考算法和见解。

将太阳系映射到你附*的某个地方——这是一个 NatGeo 的火星启发的闪亮网络应用程序

原文:https://towardsdatascience.com/map-the-solar-system-to-a-place-near-you-a-natgeos-mars-inspired-shiny-web-app-a5f7f010ffac?source=collection_archive---------18-----------------------

我最*晋升为父亲。这就是为什么我目前正在休 5 个月的育儿假(感谢出色的团队@ store2be 的配合!).每天早上 5 点左右,我和儿子一起离开卧室去厨房,这样他的妈妈就可以睡上两个小时。正是在这些清晨时分,我最*在网飞观看了国家地理研究所的火星,这启发了我一个小的“数据科学”项目。

沙漠中真实比例的太阳系

在《火星救援》第一季的前几集里,年轻的本·索耶(Ben Sawyer)——注定要去火星的宇航员之一——和他的父亲一起走进沙漠,把弹珠放在棍子上,这样弹珠的大小就会和我们太阳系中行星的大小相匹配,它们之间的距离就会和相同比例的行星之间的距离相匹配。

The Earth the size of a marble. Source: National Geographic (2016).

这启发我开始了一个项目,用 R 构建一个闪亮的 web 应用程序,让我将太阳系映射到给定位置周围的真实世界。也许有一天,我会和我的儿子一起讲述本·索耶和他父亲的故事(如果他对这种事情感兴趣的话)。

表面上看,这很容易做到。只要“获得太阳系的鸟瞰图”并缩小距离和尺寸。但是等等——行星在移动。太阳系的鸟瞰图到底会是什么样子?

我最初的计划是:

  • 在某个坐标系中找到一个行星的 x-y 坐标数据集,该坐标系确实以这种方式存在,并且
  • 将这些 x-y 坐标转换成纬度和经度测量值,以将行星的坐标映射到地球上的某个区域。

空间坐标系统

在谷歌搜索了一番后,我偶然发现了美国国家航空航天局的数据。它提供了从 1959 年到 2019 年我们太阳系中行星的位置。这取决于你选择的坐标系:

  • 太阳黄道
  • 日光惯性
  • 太阳黄道图和日光图

当然可以。里面没有 x 或 y。只是一些介于 0 和 360 之间的纬度/经度变量。也许这和半径上的度数有关?所以我去试着理解这些坐标系到底是什么。这里没有速赢。

(太阳)黄道坐标系

A visualisation of the Earth ecliptic coordinate system.

多亏了维基百科,我了解到黄道坐标系可以有它的“原点[……]可以是太阳或地球的中心,它的主要方向是朝向春分点(北分点),它有一个右手惯例。”对于包括我在内的我们这些不知道“春分(北)点”是什么意思的人来说,春分是指人们可以想象的穿过地球赤道的*面在春天穿过太阳中心的时刻(记住,地球的轴是向着太阳倾斜的)。这种情况在九月再次发生,然后被称为南分日。这张来自维基百科的图片让我明白了一些事情:

日光惯性坐标系

这是一个坐标系统,基本上就像我们在地球上的经纬度系统,但映射到太阳上。如果你对阅读更多感兴趣,你可以从 NASA 这里或者这里找到信息。我很快放弃了使用它(因为我不能足够快地理解它),但也可以随意探索它。

月亮太阳 R 包

在读入任何数据之前,我决定至少快速检查一下是否有任何 R 包可用于行星绘图。幸运的是,原来有一个,Lukasz Komsta 的叫做 moonsun 。答对了。

在最初走进一条死胡同之后(见摘录),它证明允许我做我想做的事情,为我提供所有太阳系行星在地球黄道坐标中的经度数据,并基于给定的日期,以及行星的距离。因为计划是将行星映射到一个*坦的球面上,所以我忽略了行星黄道坐标中的纬度。

这样,我就拥有了绘制所有八大行星,加上冥王星和太阳的位置所需的一切。

#Getting ecliptic latitude and longitude coordinates from a call to the planets() function in the moonsun package and its outputplanets_today <- data.frame(
                      as.ecc(planets(show.moon = FALSE)), 
                      dist = planets(show.moon = FALSE)$dist
                      )planets_today#Output:
#                             long          lat  dist
# 2018-11-24-Sun     241* 41'  2''  0*  0'  0''  0.99
# 2018-11-24-Mercury 247* 55' 57'' -1* 54' 26''  0.69
# 2018-11-24-Venus   205* 59' 15''  0* 12'  2''  0.37
# 2018-11-24-Mars    333* 46' 13'' -2* 35' 33''  0.97
# 2018-11-24-Jupiter 242* 51' 16''  0* 39' 57''  6.35
# 2018-11-24-Saturn  276* 35' 28''  0* 32' 55'' 10.87
# 2018-11-24-Uranus   29* 49' 35'' -1* 27' 12'' 19.05
# 2018-11-24-Neptune 342* 42' 11'' -1*  1' 54'' 29.77
# 2018-11-24-Pluto   280* 46' 14''  2* 28' 57'' 33.38

将行星的坐标映射到地球表面

现在,基于角度方向和距离测量,目标是找到行星在地球上的位置坐标,给定某种比例因子。为了做到这一点,我偶然发现了 geosphere 包,其中就包含了这样一个功能。

destpoint()函数将起始位置、以北纬 0 度为参考的方向角和以米为单位的距离作为输入,并返回您将到达的坐标。瞧啊。

#Pick the location of Earth as a starting point, e.g. the Mojave desert
startingLocationLng <- -115.7863069
startingLocationLat <- 35.0992539#Get angles between Earth and the planets as seen from a top-down-view from the ecliptic north to south pole
planetsAngles <- (-1) * (as.numeric(as.ecc(planets(show.moon = FALSE))$lat) - 360)#Get the distances (in AU and converted to 1 AU = 1,000 m)
planetsDistances <- planets(show.moon = FALSE)$dist * 1000newCoords <- **destPoint**(c(startingLocationLng, startingLocationLat), planetsAngles, planetsDistances)

太阳系绘图应用程序

有了可用的核心组件,所有需要做的就是使用 R 和 RStudio 将这些东西编织在一个基本的闪亮的 web 应用程序中。最终应用的截图可以在下面看到。

The Solar System Mapper web application, built with R & Shiny.

该应用程序提供以下功能:

  • 设置观察的日期
  • 选择地球的位置
  • 选择将天体距离转换为地球距离的比例

基于这些输入,它将计算天体在地图上的位置。它还将为您提供“原始”数据(如坐标和行星大小,单位为厘米),您需要这些数据才能像本·索耶和他的父亲一样真正走进这个世界。

有趣的补充说明:根据本·索耶和他爸爸在电视上的模型中使用的地球和土星的大小,我的应用程序告诉我,他们需要从地球开车大约 2 公里到土星,并应用 1 AU = 0.18 公里的比例。这是基于假设他们的地球直径约为 1.53 厘米,土星直径约为 14.50 厘米。作为日期,我选择了 2016 年 11 月 21 日,这一集在 2016 年首次播出。

【https://pdwarf.shinyapps.io/solar-system-mapper/】自己动手试试这个应用吧

此处 代码可通过 GitHub 获得。

剪辑

由于这个项目对我来说首先是一次学习之旅,我认为看着包括一些我走过的非常死胡同的实际过程是很有趣的。在这个项目的过程中,我总共经历了两次真正错误的转弯:

转错#1:曲解水*坐标系

月亮太阳 R 包的文档中,我看到它可以让你将坐标转换成水*坐标。我(也)简单地阅读了一下,认为我已经找到了我所需要的。这一次,维基百科不是我最好的来源。我完全误读了你在下面看到的图像。对我来说,那时候,图像看起来就像黄道坐标系后来变成的样子。我想我把图像中的地*线误认为地球的赤道。

我想我可以只使用方位角和距离,并且可以用我后来使用黄道经度变量的方式。所以我开始编写一个函数,将方位角和距离转换成*面上的 x-y 坐标。这个函数是这样工作的:

AzimuthToXY <- function(azimuth, distance) {
    if(azimuth > 0 && azimuth < 90) {
        Y = sin(NISTdegTOradian(azimuth)) * distance
        X = cos(NISTdegTOradian(azimuth)) * distance
    }
    else if(azimuth == 90) {
        Y = distance
        X = 0
    }
    else if(azimuth > 90 && azimuth < 180) {
        Y = sin(NISTdegTOradian(azimuth - 90)) * distance
        X = -1 * cos(NISTdegTOradian(azimuth - 90)) * distance
    }
    else if(azimuth == 180) {
        Y = 0
        X = distance
    }
    else if(azimuth > 180 && azimuth < 270) {
        Y = -1 * sin(NISTdegTOradian(azimuth - 180)) * distance
        X = -1 * cos(NISTdegTOradian(azimuth - 180)) * distance
    }
    else if(azimuth == 270) {
        Y = -1 * distance
        X = 0
    }
    else if(azimuth > 270 && azimuth < 360) {
        Y = -1* sin(NISTdegTOradian(-1 * azimuth + 360)) * distance
        X = cos(NISTdegTOradian(-1 * azimuth + 360)) * distance
    }
    else if(azimuth == 360 | azimuth == 0) {
        Y = 0
        X = distance
    }
    return(data.frame(X, Y))
}

但是当我绘制输出时(见下文),我感觉不太对劲,于是我又读了一些。最后,下面的图片,虽然没有维基百科上的漂亮,但更清晰,帮助我理清了事情。

The Horizontal coordinate system explained. Source: Swinburne University (2018).

如果你想知道在某个时间点从哪里观察天空来定位某个天体,水*坐标系是很有用的。它总是基于观测者在地球上的位置,而黄道坐标系是基于地球本身的。

错误转折#2:假设世界是*的

我在上面简要暗示了这个错误。基本上,我想我会在一个*面上得到一些 x-y 坐标,相对于地球所在的 0/0 点,然后把这个*面叠加到地图上。请参见下面的代码和示例输出:

coords <- map2_df(azimuth, distance, AzimuthToXY)plot(coords)
text(x = coords$X, y = coords$Y, labels = planetNames, pos = 1)

My first idea of plotting the planets to a flat Earth.

所以,在谷歌了如何从我的 azimuthytoxy()hustle 中获得目的地坐标之后,我偶然发现了这个 Stackoverflow 线程,标题为“我如何才能从另一个纬度或经度中找到一个距离 X 的纬度或经度?”。它以两种方式让我大开眼界:

  1. 世界不是*的,它是球形的!🤦‍
  2. 有一个叫做 geosphere 的包,它包含了一个函数,这个函数将使我在 AzimuthToXY()函数上的努力变得毫无用处。

正如你在上面的帖子中看到的,这就是我如何走上正轨的。多么有趣的项目——我确实学到了很多。也许这个应用在将来的某个时候会对我有用!

PS:这个项目也是约翰·霍普斯金大学 Coursera 上的在线课程 “开发数据产品”的一部分。我即将完成的是数据科学专业的 9/10 课程。一旦我 10 对 10,我将分享我的经历。

测绘挑战赛获胜解决方案

原文:https://towardsdatascience.com/mapping-challenge-winning-solution-1aa1a13161b3?source=collection_archive---------11-----------------------

了解如何以惊人的精度在卫星图像上检测建筑物。开源实现的 DIY。由 neptune.ml 为您带来,与 deepsense.ai 一起赢得挑战并获得最佳社区贡献者奖🏆。

No cherry picked predictions. 1st column is input image; 2nd column is model’s prediction; 3rd column is model’s prediction superimposed on the input image; 4th column is ground truth superimposed on the input image. Each row is one example.

序言

卫星图像的深度学习越来越成为数据科学家的热门话题。卫星数据展示了在商业和研究领域的一些可能的应用。用例的范围从分类和本地化,到语义或实例分割。最后一个——实例分割——就是检测图像上的一个对象类,然后分割该对象的每个实例(想想:选择图像上的所有猫)。

这篇文章是关于实例分段挑战的获胜解决方案,称为映射挑战🌐在 crowdAI 和 Humanity & Inclusion 的主持下。在这里,我将分享我们的过程,工作方式,解决方案的内部和最终结果。关于技术栈也不会说太多😉

Project dashboard — we were rather busy with our experiments 😃

为什么重要?

卫星图像提供了高质量的地球表面概览。这些数据可以用于公共利益。一个例子是研究项目:“ 结合卫星图像和机器学习预测贫困 ”。来自斯坦福大学和美国国家经济研究局的研究人员使用深度学习方法(特别是迁移学习技术和 VGG 网络架构)来估计发展中国家一些国家的家庭消费和资产。

另一个例子是支持应对人道主义危机或自然灾害。地图挑战赛如何为这一目标做出贡献?

我们正处于一个人道主义危机在规模和数量上都日益增加的时期(……)。通常,准确的地图要么不存在,要么因灾难或冲突而过时。*

尽管它们很重要,但新地图是手工绘制的,因此迫切需要自动化方法来帮助生成准确的实时地图。因此,竞赛的意义可以简单概括如下:

世界上许多地方还没有绘制成地图;尤其是(……)那些最容易遭受自然灾害的人。获得这些潜在危机区域的地图极大地提高了应急(……)行动者的反应能力。*

数据科学家可以实现这一挑战的实际目标是:

(…)探索机器学习如何为自动分析卫星图像以生成(…)地图铺*道路。*

( 2018-09-12 从* 比赛页面 )检索的所有报价

关于比赛的几句话

Example input images

如果你想参加围绕开放数据组织的机器学习挑战,只需前往crowdAI.org并挑选你最喜欢的。前段时间,2018 年 4 月初,我们被贴图挑战赛所吸引。我们专注于基于图像的机器学习,在此之前,我们参加了数据科学碗 2018 ,在那里我们主要与 U-Net 和 Mask R-CNN 架构合作。在 DSB 2018 期间,我们开发了高度可参数化的 U-Net 的干净实现。这个比赛也是关于分割的,但是在这里,我们使用卫星图像,而不是显微镜图像。出于以下几个原因,我们决定参加地图挑战赛:

  • 探索机器学习竞赛的新*台。我们都很了解卡格尔,但是克劳代和 T21 有不同的形象。
  • 为更广泛的公众利益贡献我们的一份力量(参见:为什么重要?)。
  • 通过定制编码器、多路输出和其他修改,进一步改进 U-Net 实施。
  • 扩展我们的开放数据科学项目组合。

团队—数据科学四重奏

数据科学四重奏参加了比赛,分别是:雅各布·查孔、卡米尔·卡什马雷克、安杰伊·皮斯基尔、彼得·塔拉谢维奇(字母顺序)。由于这是整个团队的工作,因此,为了简单起见,我将把进一步的成就提到整个团队,而不是任何特定的人。在这里, neptune.ml 我们坚信,没有强大的团队合作,这一成功是不可能的。我们的 4 人团队,就像四人组(GoF——这四位作者因他们的设计模式书而出名),由热衷于机器学习的爱好者组成。我们来自两家公司:Jakub 和 Kamil 来自 neptune.ml ,Andrzej 和 Piotr 来自 deepsense.ai —机器学习和 ai 咨询公司。

我们是如何工作的?我们是如何设计流程的?

我们有定期的每周计划会议(报告进展和讨论未来的方向),每天的站立会议(让每个人都知道最新的工作),松散的沟通渠道,用于特别的对话和直接在代码中请求评论(当然还有代码审查)😄).

在参加挑战之前,我们有一些原则,我们渴望在我们追求的任何项目中实现。

干净代码 —我们认为单项比赛只是迈向更大目标的一步。因此,我们不会为了在竞争中立于不败之地而牺牲工程质量。具有良好接口的设计良好的实现将在未来的竞争和商业数据科学项目中获得回报。

️team 工作 —根据定义,数据科学项目是团队工作。不断重复新想法(有些效果很好,有些则不太好)的顺利进展是我们在此次竞赛中获得第一名的关键因素之一。任何人都可以提出想法,选择她最喜欢的任务,并思考他们对项目的贡献。这种开放的环境对我们的成功至关重要。

快速实验 —多亏了清洁解决方案开发流程,我们能够顺利地重复想法。从第一天开始,所有实验都在我们的数据科学项目*台 neptune.ml 上运行。与实验相关的所有工件都放在一个地方:结果、输出、保存的模型、代码、图表、超参数——非常方便,并且创建了一个比较结果和查看彼此工作的公共场所。这变得很方便,因为实验的数量很快就超过了 100 次(到目前为止,我们已经进行了超过 1000 次实验,这些实验都是公开的😎).

Single experiment with three interactive charts displayed.

公开分享 — neptune.ml 团队有远见地公开并展示与数据科学项目相关的整个过程。这就是为什么 code base 从第一天起就是开源的。每个人都可以观察它是如何增长的,何时开发新的模型,以及我们如何建立例程来有效地处理竞争数据。这是一个相当大的挑战,因为图像的数量:训练中有 280741 张,验证中有 60317 张,测试集中有 60697 张。此外,每个人都可以观察我们在海王星上运行的实验,浏览图表和结果。最后,我们让每个人都复制我们的结果,因为我们共享完整的信息和指导。我们将我们的想法命名为开放解决方案

从事数据科学项目的实用建议

在这里,我们从团队的角度分享了哪些工作做得很好,以及我们在当前挑战 ( 查看“成功解决方案描述”部分)中继续做的事情:

  • 选择所有实验工件的单一*台(保存的模型、代码、结果、超参数)。当事情变得复杂时,这会节省你大量的时间😉).

neptune.ml dashboard, where we keep all experiments. Notice competition metrics, Precision and Recall in the middle (two green columns).

  • 安排每周计划会议以报告进展并讨论两个主题:接下来做什么(接下来 7 天的行动)和想法。我们的 deepsense.ai 团队成员带来了许多关于损失功能和架构设计的技巧,这是讨论它们的合适场所。
  • 每日同步安排固定时间——15 分钟。这将让每个人都知道现在正在处理什么。
  • 把所有的任务和问题放在同一个地方比如 GitHub issues 和 boards 或者 trello boards 和 cards。这应该由团队领导策划,由团队中的每个人维护。
  • 每个团队成员都在 git 分支工作。一旦完成任务,她就向发布开发分支发布拉请求。一旦增量解决方案完成,发布开发分支将被合并到主开发分支。千万不要碰 master,除非是发布开发分公司的 PR。这确保您在 master 上对您的问题有增量解决方案。它还允许您跟踪项目历史。
  • 实施对等代码审查。团队得到了关于软件工程的一般教育,特别是关于彼此的工作风格。

技术堆栈

硬件

在硬件层面,我们在普通笔记本电脑上开发代码,或者在云中训练模型( neptune.ml 处理与谷歌云*台的通信。用户可以选择她最喜欢的 GCP 机器,配备英伟达 K80 或 P100 GPU)或本地的英伟达 GeForce GTX 1070 GPU。在后一种情况下,我们使用 neptune.ml 来监控我们在本地计算的实验(参见下面的章节“Neptune . ml”了解更多细节)。

软件

我们使用 Python 3.5,这是我们技术堆栈中最基本的部分。我们可以区分几个逻辑层,这将在下一节中描述。

Python 包(有些是特定于项目的)

在顶部,我们有一些 Python 包,我们每天使用它们来简化数据科学中的常见任务。下面列出了最重要的,并简单说明了为什么它们很重要😉。

  • py torch(v 0 . 3 . 1)。我们发现在 PyTorch 中开发深度模型既简单又直观。我们知道有很多博客文章和会议讨论比较了 Keras 和 PyTorch 。我们选择 PyTorch 是因为用户可以直观地开发定制架构。
  • ImgAug —用于图像增强,因为它提供了简单的 API 和大量的增强。看看我们对 ImgAug 的使用: augmentation.py 。
  • 具体来说,在这次挑战中,我们与 pycocotools 合作,计算竞争指标。
  • scikit_image、opencv_python 和 imageio,用于对图像进行操作。

(所有需求都在我们的资源库中requirements . txt)

Steppy 和 steppy-toolkit

Final solution pipeline developed using steppy.

在赢得地图挑战赛之前,我们的团队参加了比赛和商业项目。当时很明显,需要一些简单和干净的接口来构建复杂的机器学习管道。 Steppy 是一个轻量级的 Python 库,支持干净的机器学习流水线设计。它是海王星*台的补充,但在技术上是 100%独立的。 Steppy-toolkit 反过来是一套精心策划的变形金刚,让你的 Steppy 工作更快更有效。

Neptune . ml

它是一个社区友好的*台,支持数据科学家创建和共享机器学习模型。Neptune 促进团队合作、基础设施管理、模型比较和可重复性。我们在 neptune.ml 上运行所有的实验,以确保我们能够重现它们,并在以后进行比较。Neptune 独立于上面提到的所有层,它只适用于任意的 Python 代码。

Mapping Challenge — neptune screen with project description, similar to GitHub README.md.

获奖解决方案描述

数据科学项目中优雅实验的最佳实践(案例研究)

以上是联合 neptune.ml 和 deepsense.ai 对PyData Europe 2018(euro python 2018 的一部分)的贡献的标题,在这里我提出了我们的最佳实验实践。我们将地图挑战的解决方案作为一个用例,因为我们相信我们的想法值得传播(就像 TED 大会😉).值得注意的是,我们是在宣布获奖者之前做的,包括竞赛社区贡献者两个类别😊。在这张海报中,我们从技术的角度全面概述了哪些方法行之有效。

Click on the poster for full size pdf file.

获胜网络是 U-Net 的兴奋剂*

*我第一次观察到这个术语是在 ods.ai 帖子里,他们在那里解释了他们对 DSB 18 的第一名解。

Unet 使用 Resnet34、Resnet101 和 Resnet152 作为编码器,其中 Resnet101 为我们提供了最佳结果。这种方法在 TernausNetV2 论文中有解释(我们的代码💻).也看看我们的可参数化的 U-Net 的实现(代码💻).

1st columns is input image; 2nd column is output from U-Net; 3rd column is prediction superimposed on the input image; 4th column is ground truth superimposed on input image.

损失函数

  • 距离加权交叉熵在著名的 U-Net 论文(我们的代码中解释💻).强烈推荐阅读这篇论文😃
  • 使用软骰子和距离加权交叉熵的线性组合(代码💻).
  • 将由建筑物大小加权的分量(较小的建筑物具有较大的权重)添加到加权交叉熵,该加权交叉熵对属于小对象的像素的错误分类进行惩罚(代码💻).

实践中的损失函数——可视化

前面提到的三点产生了某种复杂的损失函数,因此可能很难理解它在实践中是如何工作的。下面是重量的可视化图,具体如下:

  • 距离权重:高值对应于建筑物之间的像素。
  • 尺寸权重:高值表示小建筑物(建筑物越小,颜色越深)。请注意,没有建筑物固定为黑色。

(对于两种重量:颜色越深表示数值越高)

1st column is input image, 2nd column is mask, 3rd column visualizes distances between buildings (darker color is higher value), 4th column visualizes weight assigned to the roof (smaller roofs are assigned higher values, background is fixed to black).

培养方案

当我们开始使用预训练的模型时,我们获得了最好的结果(*均精度和*均召回率)(这并不奇怪)。训练计划是这样进行的:

  1. 用预先训练的权重初始化模型。
  2. 使用learning rate=1e-4dice weight=0.5在数据集的 50k 个样本上进行训练。
  3. learning rate=1e-4dice weight=0.5在全数据集上训练。
  4. 用较小的learning rate=1e-5dice weight=0.5训练。
  5. 使用增加的dice weight=5.0进行训练,以使结果更加*稳。

为了方便起见,我们将所有的训练超参数放在一个配置文件中: neptune.yaml 。由于这种方法,我们总是有一个单一的位置,在那里我们可以立即对培训有一个高层次的概述。

资源

我收集了一些有用的链接,你可以在那里寻找进一步的信息。

  1. 实验连同输出文件、结果、图表和超参数。
  2. GitHub 上的代码
  3. PyData Europe 2018(euro python 2018 赛道)上展示的海报。
  4. 再现它! —也就是说明如何重现我们的结果,也就是训练模型,使您达到:0.943 Average Precision0.954 Average Recall
  5. crowdAI 上的地图挑战赛页面。

承认

我们要感谢 crowdAI *台和 Humanity & Inclusion 非营利组织的维护者组织和举办了这次挑战。特别感谢来自 crowdAI 的 Sharada Mohanty 在整个比赛过程中给予的大力支持👏。

我们感谢人工智能咨询公司 deepsense.ai 在整个比赛过程中给予的大力支持和建议。

我们要感谢欧洲数据科学协会( EuADS )对顶级社区贡献者奖的赞助。

最后,我们与每一个挑战竞争对手的地图击掌。因为你们,我们真的玩得很开心😄

摘要

映射挑战是一个图像分割挑战,参与者被挑战“使用机器学习构建缺失的地图”。 neptune.ml 与 deepsense.ai 一起开发了获胜的解决方案,该解决方案从比赛的第一天就开始开源。这种开放性让我们获得了最佳社区贡献者奖。我们的主要愿景是开放整个数据科学项目,即代码、任务、规划、实验结果以及机器学习项目中常见的所有内容。

现在怎么办?

测绘挑战还没有结束。我们将在🇮🇹.都灵举行的 IEEE 数据科学和高级分析国际会议上展示我们的解决方案除此之外,我们继续按照上面列出的原则参加机器学习竞赛(参见:一节:我们是如何工作的?我们是如何设计流程的?)。最*的一项活动是盐鉴定挑战,在那里我们进一步提高了我们的深度学习技能。

快乐训练🚀

请随时在评论中给出反馈或提出您的问题。

用 Python 绘制地理数据

原文:https://towardsdatascience.com/mapping-geograph-data-in-python-610a963d2d7f?source=collection_archive---------1-----------------------

在数据科学领域工作时,一个很大的帮助是在地理地图上可视化您的数据,为此,有几个包可以处理它,例如 GeoPandas 。

你可以学习如何使用 GeoPandas,阅读我的文章:圣地亚哥的街道有多安全。

有时安装 Geopandas 包可能很复杂,这取决于您工作的环境。或者,简单地说,你需要控制你的代码!因此,在这篇文章中,我们将探索如何使用“形状文件”和基本的 Python 库来构建我们自己的“地理地图功能”。

1.形状文件

shapefile 格式由 Esri 作为(主要)开放规范开发和管理,在空间上将几何描述为“点”、“折线”或“多边形”。在 OpenStreetMap 术语中,这些可以分别被认为是'节点'、路和'闭路'。每个几何体都有一组关联的属性。概括地说,这些有点像 OSM 的标签。

shapefile 实际上是几个文件的组合,这些文件的格式表示地理数据的不同方面:

  • 。shp —形状格式;特征几何本身。
  • 。shx —形状索引格式;要素几何的位置索引,允许快速向前和向后搜索。
  • 。dbf —属性格式;每个形状的列属性,dBase IV 格式。

还有几个 shapefile 格式的可选文件。其中最重要的是。描述所用坐标系和投影信息的 prj 文件。虽然不是 Esri shapefile 标准的一部分。lyr 文件通常包含在内,因为它包含如何在 ArcGIS 软件中显示数据(颜色、标签等)的规范。

更多信息见 维基百科

2.正在安装 Python 形状文件库(PyShp)

Python Shapefile 库(pyshp)为
Esri Shapefile 格式提供读写支持。Shapefile 格式是由 Esri 创建的一种流行的地理
信息系统矢量数据格式。

要安装 pyshp ,请在您的终端中执行以下指令:

pip install pyshp

3.导入和初始化主 Python 库

import numpy as np
import pandas as pd
import shapefile as shp
import matplotlib.pyplot as plt
import seaborn as sns

初始化虚拟化设置

sns.set(style=”whitegrid”, palette=”pastel”, color_codes=True)
sns.mpl.rc(“figure”, figsize=(10,6))

如果您使用的是 Jupyter 笔记本电脑:

%matplotlib inline

4.打开矢量地图

如 1 中所述。,矢量地图是一组由多个文件组成的文件,其中 name.shp 是主文件,用于保存地理要素。重要的是,所有其他文件如' name.shx ',' name.dbf '等。,必须在同一文件夹中。

在本教程中,我们将使用与城市相关的地图(“Comunas”),它们共同构成了圣地亚哥大都市地区。在 INE(智利国家统计局),可以下载一组与地图相关的 shapefiles,这些文件是为最*一次 2017 年全国人口普查创建的:

  • Comuna.cpg
  • Comuna.shp
  • Comuna.dbf
  • Comuna.shp.xml
  • Comuna.prj
  • Comuna.shx
  • Comuna.sbn
  • Comuna.sbx
shp_path = “./Comunas_RM_Mapas_Vectoriales/Comuna.shp”
sf = shp.Reader(shp_path)

让我们检查一下函数 shp 导入了多少不同的“形状”。读者:

len(sf.shapes())

结果将是:52

这意味着在我们的形状文件中存在 52 个形状,一旦圣地亚哥大都会区有 52 个“comunas”,如下图所示(不要担心,在本文结束之前,您将学习如何直接从您的数据创建这样的地图):

让我们也探索其中一个形状(或“记录”):

sf.records()[1]

结果将是一个包含 6 个元素的数组:

Out:['13',
 '131',
 '13115',
 'REGIÓN METROPOLITANA DE SANTIAGO',
 'SANTIAGO',
 'LO BARNECHEA']

元素[5]是“comuna”的名字,在这种情况下:“LO BARNECHEA”,一个位于安第斯山脉所在城市东部的“comuna”(也是我的家!;-)

你可以直接得到它的名字:

sf.records()[1][5]

圣地亚哥大都会区最中心的“comuna”正是圣地亚哥的 Comuna(小迷糊?),在那里你可以找到大都会歌剧院、拉莫内达总统府(73 年被猛烈轰炸)、巴勃罗·聂鲁达故居等。

但是,让我们结束观光,看看圣地亚哥的 comuna 数据结构(id: 25):

sf.records()[25]

Out[]:

[‘13’,
 ‘131’,
 ‘13101’,
 ‘REGIÓN METROPOLITANA DE SANTIAGO’,
 ‘SANTIAGO’,
 ‘SANTIAGO’]

我们可以看到一些数据发生了变化,最重要的是“comuna”的名称,也就是现在的“SANTIAGO”。

请注意,您可以将本教程中描述内容应用于任何 shapfile。

5.在 Pandas 数据帧上转换 shapefile 数据

在最后一个例子中,我之前知道 Santiago 的 id 是“25”。但是如何找到这样的 id,从一个 comuna 的名字开始?让我们首先创建一个有用的函数,将我们的“shapefile”格式转换为更常见的熊猫数据帧格式:

def read_shapefile(sf):
    """
    Read a shapefile into a Pandas dataframe with a 'coords' 
    column holding the geometry information. This uses the pyshp
    package
    """
    fields = [x[0] for x in sf.fields][1:]
    records = sf.records()
    shps = [s.points for s in sf.shapes()] df = pd.DataFrame(columns=fields, data=records)
    df = df.assign(coords=shps) return df

因此,让我们转换数据帧上的 sf 数据,看看它是什么样子:

df = read_shapefile(sf)
df.shape

数据帧具有(52,7)的形状。这意味着我们每行有 7 个不同的特征(列)。请记住,我们之前看到了其中的 6 个功能。好像现在多加了一个。让我们看一个例子:

df.sample(5)

最后一列是用于创建特定地图形状的每个点的坐标、纬度和经度。

迷惑?让我们再深入挖掘一下。

我们如何定位圣地亚哥·科穆纳的身份?现在用熊猫很简单:

df[df.NOM_COMUNA == ‘SANTIAGO’]

我们可以很容易地看到,25 正好是数据帧索引,也就是我们的 comuna 形状所在的位置。

通过简单的 Pandas 命令,您可以将索引(或 id)与 comuna 的名称相关联:

df.NOM_COMUNAOut:0 LAS CONDES
1 LO BARNECHEA
2 VITACURA
3 HUECHURABA
4 PUDAHUEL…49 ALHUÉ
50 LAMPA
51 TILTIL

6.绘制特定形状

最后,我们将看到什么是真正的形状。为此,我们应该创建一个函数来绘制它。我们将使用 Python MatPlotLib 库:

def plot_shape(id, s=None):
    """ PLOTS A SINGLE SHAPE """
    plt.figure()
    ax = plt.axes()
    ax.set_aspect('equal')
    shape_ex = sf.shape(id)
    x_lon = np.zeros((len(shape_ex.points),1))
    y_lat = np.zeros((len(shape_ex.points),1))
    for ip in range(len(shape_ex.points)):
        x_lon[ip] = shape_ex.points[ip][0]
        y_lat[ip] = shape_ex.points[ip][1] plt.plot(x_lon,y_lat) 
    x0 = np.mean(x_lon)
    y0 = np.mean(y_lat)
    plt.text(x0, y0, s, fontsize=10)
    # use bbox (bounding box) to set plot limits
    plt.xlim(shape_ex.bbox[0],shape_ex.bbox[2])
    return x0, y0

上面的函数做两件事:a)根据 comuna 的坐标绘制形状(多边形), b)计算并返回特定形状的中点(x0,y0)。这个中点也被用来定义在哪里印刷 comuna 的名字。

例如,对于我们著名的圣地亚哥的 comuna:

comuna = 'SANTIAGO'
com_id = df[df.NOM_COMUNA == comuna].index.get_values()[0]
plot_shape(com_id, comuna)

Santiago — Shape only

注意,我们必须知道形状 id(索引)才能绘制它,但是我们输入了 Comuna 的名称:SANTIAGO。使用 Pandas 很容易计算 id,正如您在前面代码的第二行所看到的。

7.绘制完整的地图

绘制单个形状基本上是为了解决这一小部分代码:

sf.shape(id)

现在,我们必须在同一张图上画出数据帧上的所有形状。为此,我们将使用以下函数:

def plot_map(sf, x_lim = None, y_lim = None, figsize = (11,9)):
    '''
    Plot map with lim coordinates
    '''
    plt.figure(figsize = figsize)
    id=0
    for shape in sf.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        plt.plot(x, y, 'k')

        if (x_lim == None) & (y_lim == None):
            x0 = np.mean(x)
            y0 = np.mean(y)
            plt.text(x0, y0, id, fontsize=10)
        id = id+1

    if (x_lim != None) & (y_lim != None):     
        plt.xlim(x_lim)
        plt.ylim(y_lim)

默认情况下,上面的函数在一个给定的“df”文件上绘制所有的形状,包括它中间的形状 id。或者将绘制缩放的地图(无 id)。您可以更改打印或不打印 id 的功能。

绘制全图:

plot_map(sf)

Full Map

绘制地图:

y_lim = (-33.7,-33.3) # latitude 
x_lim = (-71, -70.25) # longitudeplot_map(sf, x_lim, y_lim)

Full Map with Zoom

8.在完整的地图上绘制单个形状

我们可以“合并”前面的两个功能,并在完整的地图中“绘制”一个单一的形状。为此,让我们编写一个新函数,其中形状 id 现在是一个输入参数:

def plot_map2(id, sf, x_lim = None, y_lim = None, figsize=(11,9)):
    '''
    Plot map with lim coordinates
    '''

    plt.figure(figsize = figsize)
    for shape in sf.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        plt.plot(x, y, 'k')

    shape_ex = sf.shape(id)
    x_lon = np.zeros((len(shape_ex.points),1))
    y_lat = np.zeros((len(shape_ex.points),1))
    for ip in range(len(shape_ex.points)):
        x_lon[ip] = shape_ex.points[ip][0]
        y_lat[ip] = shape_ex.points[ip][1]
    plt.plot(x_lon,y_lat, 'r', linewidth=3) 

    if (x_lim != None) & (y_lim != None):     
        plt.xlim(x_lim)
        plt.ylim(y_lim)

密谋圣地亚哥的《红色》中的 comuna:

plot_map2(25, sf, x_lim, y_lim)

Santiago

如果我们想用特定的颜色“填充”一个形状呢?简单!为此,我们可以使用 plt.fill。该功能可以重写:

def plot_map_fill(id, sf, x_lim = None, 
                          y_lim = None, 
                          figsize = (11,9), 
                          color = 'r'):
    '''
    Plot map with lim coordinates
    '''

    plt.figure(figsize = figsize)
    fig, ax = plt.subplots(figsize = figsize) for shape in sf.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        ax.plot(x, y, 'k')

    shape_ex = sf.shape(id)
    x_lon = np.zeros((len(shape_ex.points),1))
    y_lat = np.zeros((len(shape_ex.points),1))
    for ip in range(len(shape_ex.points)):
        x_lon[ip] = shape_ex.points[ip][0]
        y_lat[ip] = shape_ex.points[ip][1]
    ax.fill(x_lon,y_lat, color)

    if (x_lim != None) & (y_lim != None):     
        plt.xlim(x_lim)
        plt.ylim(y_lim)

用绿色(' g ')绘制“Las Condes”(id = 0)的 comuna:

plot_map_fill(0, sf, x_lim, y_lim, color='g')

Las Condes

9.在完整地图上绘制多个形状

我们“艰难的地图之旅”的下一个自然步骤是创建一个选择了几个形状的地图。为此,我们将有一个 id 列表,并使用 For 循环用颜色填充每个 id,而不是用 id 作为输入参数。修改后的函数如下所示:

def plot_map_fill_multiples_ids(title, comuna, sf, 
                                               x_lim = None, 
                                               y_lim = None, 
                                               figsize = (11,9), 
                                               color = 'r'):
    '''
    Plot map with lim coordinates
    '''

    plt.figure(figsize = figsize)
    fig, ax = plt.subplots(figsize = figsize)
    fig.suptitle(title, fontsize=16) for shape in sf.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        ax.plot(x, y, 'k')

    for id in comuna:
        shape_ex = sf.shape(id)
        x_lon = np.zeros((len(shape_ex.points),1))
        y_lat = np.zeros((len(shape_ex.points),1))
        for ip in range(len(shape_ex.points)):
            x_lon[ip] = shape_ex.points[ip][0]
            y_lat[ip] = shape_ex.points[ip][1]
        ax.fill(x_lon,y_lat, color)

        x0 = np.mean(x_lon)
        y0 = np.mean(y_lat)
        plt.text(x0, y0, id, fontsize=10)

    if (x_lim != None) & (y_lim != None):     
        plt.xlim(x_lim)
        plt.ylim(y_lim)

在上面的函数中,“comuna”现在是一个 id 列表:

comuna_id = [0, 1, 2, 3, 4, 5, 6]
plot_map_fill_multiples_ids("Multiple Shapes", 
                            comuna_id, sf, color = 'r')

利用我们以前的 pandas 数据框架,让我们创建一个简单的函数,其中输入是 comuna 的名称,而不是它的 id:

def plot_comunas_2(sf, title, comunas, color):
    '''
    Plot map with selected comunes, using specific color
    '''

    df = read_shapefile(sf)
    comuna_id = []
    for i in comunas:
        comuna_id.append(df[df.NOM_COMUNA == i.upper()]
                         .index.get_values()[0])
    plot_map_fill_multiples_ids(title, comuna_id, sf, 
                                       x_lim = None, 
                                       y_lim = None, 
                                       figsize = (11,9), 
                                       color = color);

绘制圣地亚哥大都市区南部城市:

south = ['alhué', 'calera de tango', 'buin', 'isla de maipo', 'el bosque', 'paine', 'la granja', 'pedro aguirre cerda', 'lo espejo', 'puente alto', 'san joaquín', 'san miguel', 'pirque', 'san bernardo', 'san ramón', 'la cisterna', 'talagante', 'la pintana']plot_comunas_2(sf, 'South', south, 'c')

10.创建“热图”

一种非常有用的贴图类型是用颜色填充特定的形状,其“强度”与给定值成比例。这样,就有可能对特定地理区域的数据分布有一个总体的了解。例如,人口分布。

首先,我们将创建一个函数,一旦接收到一个数据列表,就会将它们拆分到“bin”上。每一颗豆子都会被赋予特定的颜色。就经验而言,通常 5 到 7 个箱对数据分布有很好的感觉。我们将使用 6 个箱子和与这些箱子相关的 4 个不同的调色板。您必须一次选择其中一个媒体夹。

def calc_color(data, color=None):
        if color   == 1: color_sq =  
                        ['#dadaebFF','#bcbddcF0','#9e9ac8F0',
                        '#807dbaF0','#6a51a3F0','#54278fF0']; 
                        colors = 'Purples';
        elif color == 2: color_sq = 
                        ['#c7e9b4','#7fcdbb','#41b6c4',
                        '#1d91c0','#225ea8','#253494']; 
                        colors = 'YlGnBu';
        elif color == 3: color_sq = 
                        ['#f7f7f7','#d9d9d9','#bdbdbd',
                        '#969696','#636363','#252525']; 
                        colors = 'Greys';
        elif color == 9: color_sq = 
                        ['#ff0000','#ff0000','#ff0000',
                        '#ff0000','#ff0000','#ff0000']
        else:            color_sq = 
                        ['#ffffd4','#fee391','#fec44f',
                        '#fe9929','#d95f0e','#993404']; 
                        colors = 'YlOrBr';
        new_data, bins = pd.qcut(data, 6, retbins=True,         labels=list(range(6)))
        color_ton = []
        for val in new_data:
            color_ton.append(color_sq[val]) 
        if color != 9:
            colors = sns.color_palette(colors, n_colors=6)
            sns.palplot(colors, 0.6);
            for i in range(6):
                print ("\n"+str(i+1)+': '+str(int(bins[i]))+
                       " => "+str(int(bins[i+1])-1), end =" ")
            print("\n\n   1   2   3   4   5   6")    
        return color_ton, bins;

函数 plot_comunas()plot _ map _ fill _ multiples _ ids都应该被修改以利用这种新的彩色方案:

def plot_comunas_data(sf, title, comunas, data=None, 
                      color=None, print_id=False):
    '''
    Plot map with selected comunes, using specific color
    '''

    color_ton, bins = calc_color(data, color)
    df = read_shapefile(sf)
    comuna_id = []
    for i in comunas:
        i = conv_comuna(i).upper()
        comuna_id.append(df[df.NOM_COMUNA == 
                            i.upper()].index.get_values()[0])
    plot_map_fill_multiples_ids_tone(sf, title, comuna_id, 
                                     print_id, 
                                     color_ton, 
                                     bins, 
                                     x_lim = None, 
                                     y_lim = None, 
                                     figsize = (11,9));

而且,

def plot_map_fill_multiples_ids_tone(sf, title, comuna,  
                                     print_id, color_ton, 
                                     bins, 
                                     x_lim = None, 
                                     y_lim = None, 
                                     figsize = (11,9)):
    '''
    Plot map with lim coordinates
    '''

    plt.figure(figsize = figsize)
    fig, ax = plt.subplots(figsize = figsize)
    fig.suptitle(title, fontsize=16)for shape in sf.shapeRecords():
        x = [i[0] for i in shape.shape.points[:]]
        y = [i[1] for i in shape.shape.points[:]]
        ax.plot(x, y, 'k')

    for id in comuna:
        shape_ex = sf.shape(id)
        x_lon = np.zeros((len(shape_ex.points),1))
        y_lat = np.zeros((len(shape_ex.points),1))
        for ip in range(len(shape_ex.points)):
            x_lon[ip] = shape_ex.points[ip][0]
            y_lat[ip] = shape_ex.points[ip][1]
        ax.fill(x_lon,y_lat, color_ton[comuna.index(id)])
        if print_id != False:
            x0 = np.mean(x_lon)
            y0 = np.mean(y_lat)
            plt.text(x0, y0, id, fontsize=10)
    if (x_lim != None) & (y_lim != None):     
        plt.xlim(x_lim)
        plt.ylim(y_lim) 

为了测试我们的新函数,让我们以之前圣地亚哥南部地区的形状列表为例,为每个形状关联一个常规值。我们将使用“调色板# 1(‘紫色’):

south = ['alhué', 'calera de tango', 'buin', 'isla de maipo', 'el bosque', 'paine', 'la granja', 'pedro aguirre cerda', 'lo espejo', 'puente alto', 'san joaquín', 'san miguel', 'pirque', 'san bernardo', 'san ramón', 'la cisterna', 'talagante', 'la pintana']data = [100, 2000, 300, 400000, 500, 600, 100, 2000, 300, 400, 500, 600, 100, 2000, 300, 400, 500, 600]print_id = True # The shape id will be printed
color_pallete = 1 # 'Purples'plot_comunas_data(sf, 'South', south, data, color_pallete, print_id)

酷!不是吗?;-)

11.绘制真实数据

为了完成关于如何使用 Python 处理地图的概述,让我们从 2017 年智利人口普查中获取一些真实数据,并应用在第 10 部分开发的那些函数。

读取数据集:

census_17 = pd.read_excel('./data/CENSO_2017_COMUNAS_RM.xlsx')
census_17.shapeOut:
(52,7)

我们的数据集有 52 行,每一行都包含与圣地亚哥的每一个 comunas 相关的数据。

查看数据集:

例如,“人物”一栏与居住在该特定社区的人数有关。“TOTAL_VIV”是那个 comuna 上的住宅总数,以此类推。

绘图:

让我们应用我们的地图功能来分析圣地亚哥大都市区的人口分布情况。

title = 'Population Distrubution on Santiago Metropolitan Region'
data = census_17.PERSONAS
names = census_17.NOM_COMUNAplot_comunas_data(sf, title, names, data, 4, True)

太好了!我们可以看到人口大量分布在都市圈的中心区域!东面(地图右边),人口稀少,这是合乎逻辑的,因为这是伟大的安第斯山脉!西边和南边是农业区。

再来一个!让我们画出圣地亚哥大都会区移民占总人口的百分比:

title = 'Percentual of immigrants over total population'
data = census_17.INM_PERC
names = census_17.NOM_COMUNAplot_comunas_data(sf, title, names, data, 2, True)

12.结论

您可以意识到,最终您可以使用本文开发的 3 个函数,只用一行代码创建一个地图:

plot_comunas_data() .... that calls:plot_map_fill_multiples_ids_tone() ... that calls:calc_color()

本文为 Santiago Matropolitan 地区开发的内容可以很容易地适用于互联网上的任何矢量地图!

例如,你可以去美国人口普查局下载美国各州的地图边界形状文件。继圣地亚哥之后,

shp_path = "./cb_2017_us_state_5m/cb_2017_us_state_5m.shp"
sf = shp.Reader(shp_path)# Continental US
y_lim = (23, 50) # lat 
x_lim = (-128, -65) # longstate_id = [0, 10, 3, 5, 6, 7, 8, 30]
plot_map_fill_multiples_ids("US - States", state_id, sf, x_lim, 
                             y_lim, color = 'r', figsize = (15,9))

您可以绘制:

那都是乡亲们!

希望您对数据科学的奇妙世界有了更多的了解!

Jupyter 笔记本和本文使用的所有数据可以从我的 GitHub 下载。

我的下一篇文章再见!

来自世界南部的 Saludos!

马塞洛

绘制我的脸书数据—第 1 部分:简单的 NLP

原文:https://towardsdatascience.com/mapping-my-facebook-data-part-1-simple-nlp-98ce41f7f27d?source=collection_archive---------13-----------------------

NLP 看看我的写作风格(以及如何处理你自己的脸书数据!)

介绍

不久前,我被自己一天生成的文本数据量深深吸引住了。如果你像我一样,你可能会写很多东西。电子邮件。短信。脸书。也许你还有其他一些创造性的出路。也许你写日记或写音乐什么的。也许你是个学生,有一些写作作业。对我来说,我真的很想深入了解我正在生成的所有这些数据,并认为使用自然语言处理来分析这些数据会很酷。

这个系列将记录我是如何做的,如果你感兴趣的话,你也可以做同样的事情。

查找我的数据

当我仔细思考所有的数据时,我决定关注几个来源。他们是:

  • 我的书面学校作业
  • 我写的日记
  • 我写的歌曲集
  • 我的脸书数据(我的评论、帖子和聊天)

虽然对于我的整个项目,我使用了所有的资料来源,但对于这个系列,我只打算使用我在脸书的数据。

对于大多数数据,我只是把它放在一个文本文件中,然后就收工了。对于脸书的数据,我必须做更多的预处理。

如何获得你的脸书数据

我们如何真正得到我们的脸书数据?实际上,这比你想象的要简单。截至目前(2018 年 8 月 20 日),您可以通过以下方式下载数据:

  • 登录脸书
  • 点击右上角朝下的三角形
  • 单击设置
  • 在左上角,第三个选项是“你的脸书信息”点击这个
  • 下一个菜单中的选项#2 将是“下载您的信息”
  • 从这里,您可以决定想要什么数据,什么时间段,什么格式

我选择下载所有的东西,而且是 JSON 格式的。当我的下载准备好了,我得到了一堆这样的文件夹:

装满了我要求的 JSON。

预处理您的脸书数据

我想下载我所有的脸书数据,但实际上我并不想要这个项目的所有脸书数据。对于这个项目,我只关心我的帖子、评论和聊天记录。为了帮助解决这个问题,我为其中的每一个都编写了一个预处理脚本,以便将我想要的内容转储到文本文件中。

首先,我处理了我的信息:

import os
import json
import datetime

chat_root = 'messages'
writing_dir = 'data/facebook_chat'

for f in os.listdir(chat_root):
    file = os.path.join(chat_root, f, 'message.json')
    data = json.load(open(file, 'r'))

    for msg in data['messages']:
        try:
            if msg['sender_name'] == 'Hunter Heidenreich':
                if msg['content'] != "You are now connected on Messenger.":
                    content = msg['content']
                    ts = datetime.datetime.fromtimestamp(msg['timestamp_ms'] / 1000)

                    filename = os.path.join(writing_dir,
                                            str(ts.year) + '.' + str(ts.month) + '.' + str(ts.day) + '.txt')

                    with open(filename, 'a+') as out_file:
                        out_file.write(content + '\n')
                        print('wrote.')
        except KeyError:
            pass

您将看到,我正在遍历 messages 文件夹中的所有子文件夹。我在那里做的是读取消息 JSON。对于每条可用的消息,我都会检查它是否是我发送的消息。如果不是脸书默认的“您现在已在 Messenger 上连接”那我要了。我给消息打上时间戳,然后将它添加到一个采用year.month.day.txt格式的文件中,这是我给所有文本文件打上时间戳的格式,这样我就可以记录词汇随时间的变化。

如果由于某种原因 JSON 的键不起作用,我就忽略它。

我对我写的两个帖子做了非常相似的事情:

import os
import datetime
import json

in_data = 'posts/your_posts.json'
writing_dir = 'data/facebook_posts'

data = json.load(open(in_data, 'r'))

for post in data['status_updates']:
    try:
        ts = datetime.datetime.fromtimestamp(post['timestamp'])
        post_text = post['data'][0]['post']

        filename = os.path.join(writing_dir, str(ts.year) + '.' + str(ts.month) + '.' + str(ts.day) + '.txt')

        with open(filename, 'a+') as out_file:
            out_file.write(post_text + '\n')
    except KeyError:
        print(post)

我的评论是:

import os
import datetime
import json

comment_path = 'comments/comments.json'
writing_dir = 'data/facebook_comments'

data = json.load(open(comment_path, 'r'))
for comment in data['comments']:
    try:
        for d in comment['data']:
            if d['comment']['author'] == "Hunter Heidenreich":
                ts = datetime.datetime.fromtimestamp(d['comment']['timestamp'])
                com = d['comment']['comment']

                filename = os.path.join(writing_dir, str(ts.year) + '.' + str(ts.month) + '.' + str(ts.day) + '.txt')

                with open(filename, 'a+') as out_file:
                    out_file.write(com + '\n')
    except KeyError:
        print(comment)

从那里,我准备好了我的脸书数据。

加载我们的数据

首先,我们将编写一个简单的函数来获取某个类别中所有文件的列表。这将使我们能够轻松地跟踪哪个是哪个,并且我们将在处理和分析数据时保留这些命名方案。

import os

def get_file_list(text_dir):
    files = []
    for f in os.listdir(text_dir):
        files.append(os.path.join(text_dir, f))
    return files

comments = 'data/facebook_comments'
posts = 'data/facebook_posts'
chats = 'data/facebook_chat'

comment_files = get_file_list(comments)
post_files = get_file_list(posts)
chat_files = get_file_list(chats)

all_files = comment_files + post_files + chat_files

在我们实际读入数据之前,我们将编写一个函数,用几种不同的方式对数据进行预处理。

import string

import nltk
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
from nltk.stem import WordNetLemmatizer

def preprocess_text(lines):

    def _flatten_list(two_list):
        one_list = []
        for el in two_list:
          one_list.extend(el)
        return one_list

    translator = str.maketrans('', '', string.punctuation)
    upd = []
    for line in lines:
        upd.extend(nltk.sent_tokenize(line))
    lines = [line.translate(translator) for line in upd]
    lines = [nltk.word_tokenize(line) for line in lines]
    lines = [[word.lower() for word in line if word not in [
        '\'', '’', '”', '“']] for line in lines]

    raw = lines

    stop = [[word for word in line if word not in set(
        stopwords.words('english'))] for line in raw]

    snowball_stemmer = SnowballStemmer('english')
    stem = [[snowball_stemmer.stem(word) for word in line] for line in stop]

    wordnet_lemmatizer = WordNetLemmatizer()
    lemma = [[wordnet_lemmatizer.lemmatize(
        word) for word in line] for line in stop]

    raw = _flatten_list(raw)
    stop = _flatten_list(stop)
    stem = _flatten_list(stem)
    lemma = _flatten_list(lemma)

    return raw, stop, stem, lemma

我们在这里所做的是产生我们文本的 4 个变体。我们正在生产:

  • 我们的原始数据去掉了标点符号,用了小写字母
  • 删除了停用词的数据
  • 我们的数据来源于
  • 我们的数据被假设了

考虑到这一点,我们现在可以创建一个基本的对象来保存我们的文件数据数据,并允许使用聚合来自脸书的不同来源的写作发生在同一天:

class FileObject:
    def __init__(self):
        self._datetime = None

        self._lines = []

        self._raw = []
        self._stop = []
        self._stem = []
        self._lemma = []

    @property
    def lines(self):
        return self._lines

    def preprocess_text(self):
        self._raw, self._stop, self._stem, self._lemma = preprocess_text(
            self._lines)

现在让我们加载数据并对其进行预处理。我将演示聚合数据上的代码,但它也适用于其他输入文件列表:

all_text = {}

for f in all_files:
    base = os.path.basename(f)

    if base not in all_text:
        all_text[base] = FileObject()

    with open(f, 'r') as in_file:
        all_text[base]._lines += in_file.readlines()

for k, v in all_text.items():
    v.preprocess_text()

这可能需要很短的时间,但当我们完成后,我们将能够开始看看关于我们的文本的一些基本的东西!

我最喜欢的词是什么?

让我们从最基本的开始。我们把这些单词列表加载到各种资源中。让我们做一个统计,看看我们最常用的词是什么。让我们看看我们的 20 强。

我们可以这样写:

from collections import Counter

def file_objects_to_words(fo_text):
    raw, stop, stem, lemma = [], [], [], []
    for key, value in fo_text.items():
        raw.append(value._raw)
        stop.append(value._stop)
        stem.append(value._stem)
        lemma.append(value._lemma)
    return raw, stop, stem, lemma

def top_20_words(list_of_word_lists):
    full_count = Counter()

    for word_list in list_of_word_lists:
        for word in word_list:
            full_count[word] += 1

    return full_count.most_common(20)

raw, stop, stem, lemma = file_objects_to_words(all_text)
print('All words -- raw')
print(top_20_words(raw))
print('All words -- stop')
print(top_20_words(stop))
print('All words -- stem')
print(top_20_words(stem))
print('All words -- lemma')
print(top_20_words(lemma))

print('Chat words -- lemma')
_, _, _, lemma = file_objects_to_words(chat_text)
print(top_20_words(lemma))
print('Post words -- lemma')
_, _, _, lemma = file_objects_to_words(post_text)
print(top_20_words(lemma))
print('Comment words -- lemma')
_, _, _, lemma = file_objects_to_words(comment_text)
print(top_20_words(lemma))

我们将得到一个很好的输出:

All words -- raw
[('i', 47935), ('you', 43131), ('to', 24551), ('and', 20882), ('the', 18681), ('that', 16725), ('a', 15727), ('it', 15140), ('haha', 13516), ('me', 12597), ('like', 10149), ('so', 9945), ('im', 9816), ('but', 8942), ('do', 8599), ('is', 8319), ('of', 8266), ('just', 8154), ('be', 8092), ('my', 8017)]
All words -- stop
[('haha', 13516), ('like', 10149), ('im', 9816), ('na', 6528), ('yeah', 5970), ('dont', 5361), ('okay', 5332), ('good', 5253), ('know', 4896), ('would', 4702), ('think', 4555), ('thats', 4163), ('want', 4148), ('cause', 3922), ('really', 3803), ('get', 3683), ('wan', 3660), ('hahaha', 3518), ('well', 3332), ('feel', 3231)]
All words -- stem
[('haha', 13516), ('like', 10580), ('im', 9816), ('na', 6528), ('yeah', 5970), ('think', 5772), ('want', 5396), ('dont', 5364), ('okay', 5333), ('good', 5261), ('know', 5078), ('would', 4702), ('get', 4535), ('feel', 4270), ('that', 4163), ('caus', 3992), ('go', 3960), ('realli', 3803), ('make', 3727), ('wan', 3660)]
All words -- lemma
[('haha', 13516), ('like', 10207), ('im', 9816), ('na', 6530), ('yeah', 5970), ('dont', 5361), ('okay', 5333), ('good', 5254), ('know', 5038), ('would', 4702), ('think', 4631), ('want', 4419), ('thats', 4163), ('cause', 3934), ('get', 3901), ('really', 3803), ('wan', 3660), ('hahaha', 3518), ('feel', 3358), ('well', 3332)]
Chat words -- lemma
[('haha', 13464), ('like', 10111), ('im', 9716), ('na', 6497), ('yeah', 5957), ('okay', 5329), ('dont', 5316), ('good', 5226), ('know', 4995), ('would', 4657), ('think', 4595), ('want', 4384), ('thats', 4150), ('cause', 3913), ('get', 3859), ('really', 3760), ('wan', 3649), ('hahaha', 3501), ('feel', 3336), ('well', 3299)]
Post words -- lemma
[('game', 68), ('video', 41), ('check', 38), ('like', 36), ('birthday', 36), ('happy', 34), ('im', 33), ('noah', 29), ('song', 28), ('play', 24), ('music', 21), ('one', 20), ('get', 19), ('guy', 18), ('time', 18), ('made', 18), ('evans', 18), ('hey', 17), ('make', 17), ('people', 16)]
Comment words -- lemma
[('noah', 120), ('im', 67), ('like', 60), ('evans', 60), ('thanks', 51), ('game', 50), ('haha', 47), ('cote', 44), ('one', 43), ('coby', 40), ('wilcox', 38), ('would', 33), ('man', 31), ('dont', 29), ('really', 29), ('know', 28), ('think', 28), ('na', 24), ('want', 23), ('get', 23)]

我喜欢只看我的词条,所以这就是为什么我只记录我个人的来源。我觉得有趣的是,我在聊天中经常使用“哈哈”的变体。我的大部分评论都是某人的名字。

我的单个单词用法是什么样的?

那么,如果我们想用图表来表示我们的单个单词,看看我们的用法是如何从顶部单词到底部单词衰减的呢?我们可以编写一个一般的条形图函数,如下所示:

from matplotlib import pyplot as plt

def plot_bar_graph(x, y, x_label='X', y_label='Y', title='Title', export=False, export_name='default.png'):
    plt.bar(x, y)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.title(title)
    plt.xlim(0, len(x))
    plt.ylim(0, max(y))

    if export:
        plt.savefig(export_name)

    plt.show()

从那里,我们可以修改我们的前 20 个函数,并可以将我们的注释引理列表直接输入到图形中:

def aggregate_words_counts(list_of_word_lists):
    full_count = Counter()

    for word_list in list_of_word_lists:
        for word in word_list:
            full_count[word] += 1

    return full_count

counter = aggregate_words_counts(lemma)
word_counts_raw = list(counter.values())
word_counts_sorted = sorted(word_counts_raw)

cap = len(word_counts_raw)

plot_bar_graph(range(len(word_counts_raw[:cap])), word_counts_raw[:cap],
                      x_label='Words', y_label='Counts', title='Word Frequencies (Raw)',
                      export=True, export_name='visualizations/word_freq_bar_raw.png')
plot_bar_graph(range(len(word_counts_sorted[:cap])), word_counts_sorted[-cap:],
                      x_label='Words', y_label='Counts', title='Word Frequencies (Sorted)',
                      export=True, export_name='visualizations/word_freq_bar_sorted.png')

我们得到了两张非常好的图表:

我的数据有哪些基本统计数据?

让我们根据数据生成一些基本的统计数据。让我们设置一个函数来创建一个表:

def plot_table(cell_data, row_labels=None, col_labels=None, export=False, export_name='default.png'):
    _ = plt.figure(figsize=(6, 1))

    _ = plt.table(cellText=cell_data, rowLabels=row_labels,
                  colLabels=col_labels, loc='center')

    plt.axis('off')
    plt.grid(False)

    if export:
        plt.savefig(export_name, bbox_inches='tight')

    plt.show()

然后生成要转储到该函数中的数据:

import numpy as np

def top_k_words(list_of_word_lists, k=10):
    full_count = Counter()

    for word_list in list_of_word_lists:
        for word in word_list:
            full_count[word] += 1

    return full_count.most_common(k)

raw, stop, stem, lemma = file_objects_to_words(all_text)

counter = aggregate_words_counts(lemma)
data = [[len(all_files)],
        [top_k_words(lemma, k=1)[0][0] + ' (' + str(top_k_words(lemma, k=1)[0][1]) + ')'],
        [top_k_words(lemma, k=len(list(counter.keys())))[-1][0] + ' (' + str(top_k_words(lemma, k=len(list(counter.keys())))[-1][1]) + ')'],
        [len(counter.items())],
        [np.mean(list(counter.values()))],
        [sum([len(word_list) for word_list in raw])],
        [sum([sum([len(w) for w in word_list]) for word_list in raw])]]
row_labels = ['Collection size: ', 'Top word: ', 'Least common: ', 'Vocab size: ', 'Average word usage count: ',
              'Total words: ', 'Total characters: ']

plot_table(cell_data=data, row_labels=row_labels,
                  export=True, export_name='visualizations/basic_stats_table.png')

这些只是我认为有趣的一些数据。这次我把所有的数据都放了进去,因为我觉得这是最有趣的。

我们可以看到,我在脸书有 2147 天的文本活动。

我最喜欢的词是“哈哈”(这并不奇怪)。

总共 19,508 个单词

我用了将* 400 万个字符。

这是大量的文本数据!

随着时间的推移,我的 Vocab 使用情况如何?

我想知道随着时间的推移,我的 vocab 使用情况如何变化。我们怎样才能产生这种效果呢?好吧,幸运的是我们给所有的文件都打上了时间戳!

首先,让我们创建我们的绘图函数:

def plot(x, y, x_label='X', y_label='Y', title='Title', export=False, export_name='default.png'):
    plt.plot(x, y)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.title(title)

    if export:
        plt.savefig(export_name)

    plt.show()

现在让我们写一些函数来绘制我们的单词使用情况:

import datetime

def get_datetimes(list_of_files):
    base_files = [os.path.basename(f) for f in list_of_files]
    no_ext = [os.path.splitext(f)[0] for f in base_files]
    splits = [f.split('.') for f in no_ext]
    times = np.array(
        [datetime.datetime(int(t[0]), int(t[1]), int(t[2])) for t in splits])
    return times

def unique_vocab(word_list):
    cnt = Counter()
    for word in word_list:
        cnt[word] += 1
    return cnt

raws = []
names = []
for key, value in all_text.items():
    raws.append(value._raw)
    names.append(key)

raw_wc = [len(word_list) for word_list in raws]
labels = get_datetimes(names)

labels, raw_wc = zip(*sorted(zip(labels, raw_wc)))

plot(labels, raw_wc,
            x_label='Date', y_label='Word Count', title='Word Count Over Time',
            export=True, export_name='visualizations/word_count_by_time.png')

raw_wc_u = [len(list(unique_vocab(word_list).items())) for word_list in raws]
plot(labels, raw_wc_u,
            x_label='Date', y_label='Word Count', title='Unique Word Count Over Time',
            export=True, export_name='visualizations/unique_word_count_by_time.png')

我们开始吧:

我觉得真的很有意思,2013 年年中,我用了很多词。我不太确定我在做什么,但是当你把它分解成独特的词时,在我那天使用的 20,000 个词中,没有多少是非常独特的…

更不用说,在 2017 年后,你肯定可以看到我的脸书使用量下降。

我觉得这真的很酷!

包扎

我们做到了!对我们的一些脸书数据的基本分析。希望你从你的脸书数据中学到了一两个技巧,也许还有一些关于你自己的东西!我知道当我开始分析我自己的时候,我确实是这样想的。如果你有很酷的视觉效果或者你想分享的东西,给我留言吧!很好奇看看别人在自己的数据里发现了什么。

下一次,我想我们会尝试对我们的脸书数据进行一些情绪分析,看看我们是否能从中找到任何有趣的花絮。

如果你喜欢这篇文章,或者发现它在任何方面都有帮助,如果你给我一两美元来资助我的机器学习教育和研究,我会永远爱你!每一美元都让我离成功更*一步,我永远心存感激。

请继续关注更多的脸书 NLP 分析!

最初发布于 hunterheidenreich.com 的。

通过网络搜集 MapMyRun.com 和硒在 R

原文:https://towardsdatascience.com/mapping-physical-activity-with-r-selenium-and-leaflet-ac3002886728?source=collection_archive---------16-----------------------

我们都知道锻炼是我们身心健康最重要的因素之一。随着新的一年即将到来,一个强有力的宣言是锻炼更多!一定会在很多分辨率排行榜上名列前茅。但是要弄清楚如何真正做到这一点是很困难的。虽然一月是开设健身房会员最常见的月份,受健身中心无处不在的新年,新的我的刺激!在一些城市,这样的计划*均每年要花费 800 美元,这让许多美国人望而却步。一些人选择购买他们自己的设备,这种购买在新年达到高峰,但这仍然会带来可观的价格标签。这些障碍限制了锻炼的机会,增加了我们的健康不*等,这已经是世界上最糟糕的健康不*等了。

这些经济限制,加上个人偏好等其他因素,导致许多人转向另一种选择:外出健身。* 6000 万人说他们在 2017 年慢跑或越野跑,比 2006 年增加了 60%,还有 1 亿 T2 人说他们出去散步是为了个人健康。虽然这是对大自然的奇妙利用,但它也带来了另一个问题:并不是所有的户外都同样美丽。大多数美国城市被划分为高贫困和低贫困社区,中间几乎没有。马里兰大学的助理教授拉肖恩·雷博士说,高度贫困地区的人们不太可能锻炼,因为他们遭受犯罪的可能性更大。由于非洲裔美国人和西班牙裔美国人遭受极端贫困的可能性是白人的两倍多,这些邻里差异也导致了我们日益扩大的种族健康差距。

Photo by Kate Trifo on Unsplash

多伦多大学教授理查德·佛罗里达写道,解决这些问题需要“大量投资来改善贫困社区”,但是这种彻底的改变很难实现。与其等待整个社区被彻底改造,我想知道我是否能在高贫困社区内或附*找到“绿洲”,作为居住在附*的个人的运动区。人们通常不知道藏在自家后院的宝藏,这项分析可以解决这个问题。这也有利于那些想要改变锻炼习惯的活跃人群。我在户外锻炼的一个主要原因是探索我所在城市的新领域,但在像巴尔的摩这样的地方,错误的转弯可能是危险的,我经常发现自己坚持自己熟悉的东西。有了这些内部信息,无畏的城市探险者可以更安全地进行他们的冒险。

Photo by Erin White on Unsplash

为了进行这项分析,我计算了在过去的四年里,巴尔的摩地区的每个 GPS 坐标在 MapMyRun 上发布的一项锻炼中被包含的次数。我分析了* 20,000 次锻炼,这些锻炼是我用 Selenium ChromeDriver 刮下来的,在 R 中整理,并在 Kaggle 上分享。然后我使用 Javascript 中的传单库来映射数据。本文将展示如何做到这一点,并提供在另一个城市重复这一过程所需的所有步骤。这篇文章开头的地图绝不是一个成品,如果有传单或 Javascript 经验的人能帮助我扩展它的功能,我将不胜感激。要参与或分享反馈,请发推特给我 @halfinit 或访问该项目的 Github 资源库。

获取数据

我选择使用安德玛旗下的路线追踪应用 MapMyRun 作为我的数据源,因为它有大量用户生成的巴尔的摩市和周边地区的锻炼数据。MapMyRun.com 的路线显示为覆盖在谷歌地图上的红色轨迹。这里有一个例子,2016 年 10 月 26 日发布的随机选择的 7.4 英里跑步。

Run centered in Severna Park, Maryland.

虽然这 20,000 张路线图可以进行很好的罗夏测试,但我们需要的是作为其基础的数据,这些数据包含在一个 GPX 文件中的一列 GPS 坐标中。我们可以手动进入每次跑步的网页下载 GPX 文件,但使用 Selenium ChromeDriver 来自动化这个过程肯定更有效。如果您想按照代码进行操作,您需要在 Linux 虚拟机上运行的 Docker 容器中设置 Selenium。为了进行设置,以及获得浏览器自动化的基本背景,请查看我的教程。对于 webscraping 代码,对 HTML、CSS 和 Javascript 等 web 开发概念的基本理解将对您有所帮助。

在 R 中加载库并启动 Selenium

**# Load the necessary libraries** library(tidyverse)**# Contains many important functions including %>%** library(RSelenium)**# Allows you to call Selenium functions through R** library(rgdal) **# We will use this for reading in GPX files** library(beepr) **# Alerts you when R finishes a long analysis****# Load Selenium in R. You'll need to have started Selenium with the Docker Quickstart Terminal first- See** [**tutorial**](/an-introduction-to-web-browser-automation-with-selenium-and-docker-containers-c1bcbcb91540) **for info!)** **# Tell Selenium to download files to a specific directory in
# the Docker Linux OS.** eCaps <- list(chromeOptions =
 list(prefs = list(
  “profile.default_content_settings.popups” = 0L,
  “download.prompt_for_download” = FALSE,
  “download.default_directory” = “home/seluser/Downloads”
  )
 )
)**# Sets how long the driver should wait when searching for elements.** remDr$setTimeout(type = “implicit”, milliseconds = 100000)**# Sets how long it should wait for the page to load.** remDr$setTimeout(type = “page load”, milliseconds = 100000)**# Set up the remoteDriver as remDr. Include chromeOptions** remDr <- remoteDriver(remoteServerAddr = “192.168.99.100”, browserName= “chrome”, port=4445L, extraCapabilities = eCaps)**#Open remoteDriver** remDr$open()

现在我们在 r 中有一个到 Selenium ChromeDriver 的活动连接,在你的全局环境中,remDr应该是一个object containing active binding

要在 MapMyRun 中做任何事情,我们首先需要登录我们的帐户,我们可以从 MapMyRun 主页访问它。

**#Navigate to MapMyRun homepage** remDr$navigate(“[https://www.mapmyrun.com](https://www.mapmyrun.com)")remDr$screenshot(display = TRUE)

在整个教程中,我使用remDr$screenshot函数来显示浏览器中正在发生的事情。如果你看到一个截图,这意味着它被调用了,尽管为了简洁起见我会把它排除在外。

我们需要点击右上角的 Log in 链接,我们可以通过它的 xpath 来识别它。xpath 只是一个 web 元素的路径。一个绝对 xpath 从网页的根开始,并以/开始,而一个相对 xpath 从任何被选择的节点开始,并以//开始。这里,我使用从 HTML 文档的header开始的相对 xpath,所以我的 xpath 从//header开始。

login <- remDr$findElement(using = “xpath”, “//header/div[2]/nav[2]/ul/li[1]/a”)

The HTML for MapMyRun’s homepage, with the relative xpath to the Log in Link highlighted.

现在我们告诉 ChromeDriver 点击 login 元素。

login$clickElement()

这将把我们带到登录页面,在这里我们需要输入我们的电子邮件和密码。但是它们的输入形式都是输入元素,那么我们如何区分它们呢?幸运的是,web 开发人员已经通过给每个元素赋予自己的属性解决了这个问题。存在许多类型的属性,但是我们将主要使用的三个是名称、ID 和类别。每个网页只使用一次 id,而类可以多次使用。姓名通常用在表单中,就像我们的电子邮件/密码输入表单一样。

The HTML for the input form, with the name and ID of our input elements highlighted.

**# Either name or id will work to select the element.**
email <- remDr$findElement(using = ‘name’, value = “email”)password <- remDr$findElement(using = ‘id’, value = “password”)

使用sendKeysToElement功能输入电子邮件和密码。

email$sendKeysToElement(list(“Example@email.com”))password$sendKeysToElement(list(“Password”))

要单击登录按钮,我们可以通过它的类来选择它,它有多个类。为了处理 RSelenium 中的复合类,我们需要使用css作为我们的选择器。

login <- remDr$findElement(using = 'css', "[class='success-2jB0o button-2M08K medium-3PyzS button-2UrgI button-3ptrG']")login$clickElement()

Some personal information blocked out

我们已经登录,并在我们的主页。要访问发布的路线,我们需要导航到查找路线页面,该页面位于左上方的路线下拉列表中。

我用另一个相对 xpath 选择它。

findRoutes<- remDr$findElement(using = “xpath”,
“//header/div[1]/nav[1]/ul/li[2]/ul/li/a”)

The HTML for our homepage, with the xpath to the Find Routes link highlighted.

findRoutes$clickElement()

我们已经创建了 routes 页面,但是现在我们需要在 Near 部分输入我们的城市。MapMyRun 将为您提供一个默认位置(称为占位符,但这可能是错误的——在我的例子中,它将马里兰州的巴尔的摩与俄亥俄州的哥伦布的邮政编码组合在一起!我们将通过点击它旁边的x来清空它,这是一个带有类“Select-clear”的< span >。

clear <- remDr$findElement(using = “class”, value=”Select-clear”)clear$clickElement()

由于 Near 元素没有惟一的 ID、名称或类,我们转而使用findElements找到页面上的所有元素,选择第二个元素,并使用 tab 键发送我们的城市信息进行自动填充。

**# Find all input elements with findElements.**
inputElements <- remDr$findElements(using = “css”, value=”input”) **# Choose the second one.** city <- inputElements[[2]]**# Send city info and the code for the tab key, uE004.** city$sendKeysToElement(list(“Baltimore, MD, 21231”, “\uE004”))

还有一点:我们希望获得所有上传的活动,而不仅仅是三英里以上的活动。

distance <- remDr$findElement(using = “name”, value = “distanceMinimum”)distance$sendKeysToElement(list(key = “backspace”, “0”))

我们现在可以单击 search 按钮,它有一个复合类。

searchButton <- remDr$findElement(using = "css", "[class = 'primary-xvWQU button-2M08K medium-3PyzS']")searchButton$clickElement()**#Scroll down the page to see the results.** webElem <- remDr$findElement(“css”, “body”)
webElem$sendKeysToElement(list(key = “end”))

HTML 表格中间的每个链接都是指向保存运行数据的网页的链接。

我们需要一个功能,将下载 20 个链接(这是 HTML 元素),按下一步按钮,并重复。我用一个 while 循环来完成这个操作,只要页面底部有一个“上一步”和“下一步”按钮,这个循环就会持续下去,当它下载完所有的锻炼数据时就会结束。由于这些按钮都是带有类pageLink-3961h的元素,我告诉 ChromeDriver 只要有两个这样的元素就继续下载。

**# Initialize a starter matrix** runs <- as.tibble(matrix(nrow = 20))**# Start the while loop** while (length(remDr$findElements(using = ‘xpath’,
  “//a[@class= ‘pageLink-3961h’]/span”)) == 2){**# Find the 20 links on the page that contain “routes/view”.** links <- remDr$findElements(‘xpath’, “//a[contains([@href](http://twitter.com/href), ‘routes/view’)]”)**# Save these in the runs starter matrix** for (i in 1:length(links)){
  runs<- links[[i]]
  runs<- runs$getElementAttribute(“href”)
  runs[i,1] <- paste(runs, sep=””)
}**# Add 20 more empty rows to the matrix to put the next set of links in.** runs <- rbind(as.tibble(matrix(nrow = 20)), runs)**# Click the next button** next<- remDr$findElement(using = ‘xpath’,
“//a[@class= ‘pageLink-3961h’][2]/span”)next$clickElement()**# Wait to make sure the webpage fully loads.** Sys.sleep(10)
}

runs数据框架中,我们现在有一个 20,000 个网址的列表,每个网址都链接到一个跑步者的网页。我们需要另一个循环来告诉 Selenium 打开每个 URL,将其导出为 GPX 文件,然后重复。

for (i in 1:20000){

  **# Navigate to this URL.** remDr$navigate(paste0(runs[i,]))**# Finds the element with the ID “export_this_route”** exportRoute <- remDr$findElement(using = "id", value = "export_this_route")

The web element with ID of “export_this_route”.

点击这个元素应该会打开一个下拉菜单,但是并不总是有效。所以我使用了一个 while 循环:只要下拉菜单(它有 ui_widget_overlay 的类)没有打开,就一直点击。

while(length(remDr$findElements(using= “xpath”,
“//div[[@class](http://twitter.com/class)=’ui-widget-overlay’]”))==0){

  exportRoute$clickElement()
}

The dropdown that appears after clicking “Export This Route”.

我们想点击“下载 GPX 文件”按钮。我们可以通过查看 HTML 来找出它的 ID。

The button has an ID of “export_route_gpx_btn”

gpxButton<- remDr$findElement(
    using = "id", value = "export_route_gpx_btn")gpxButton$clickElement()**# End the for loop** }

这些 GPX 文件将位于您在启动 Selenium 时确定的文件夹中。

结论

下载完这些 GPX 文件后,我对坐标进行了合并、归一化和对数变换。然后,我将数据发送给 Javascript,并使用传单标记集群插件来创建地图。但是这部分的分析将不得不放在另一篇文章中。你可以在 Kaggle 上查看或使用数据集,也可以在这里查看地图。感谢您的阅读,记得关注并发微博给我 @halfinit !

绘制神经科学的图景

原文:https://towardsdatascience.com/mapping-the-landscape-of-neuroscience-s-bc14628e8713?source=collection_archive---------7-----------------------

关于现代神经科学研究,对 100 多万篇文章的分析能告诉我们什么

神经科学是一个多样化的科学领域,由不同的学科组成:生物学、心理学、计算机科学、语言学等等。脑科学的主要目标是了解神经系统。然而,通向这一崇高目标的道路因领域而异。这种多样性源于这样一个事实,即大脑(或一般的神经系统)是已知宇宙中最复杂的器官,包含许多层次的动力学和复杂性。

所有这些多样性使得神经科学的语义界限更加难以界定。我们能不能用一种数据驱动的方法来阐明这样的边界,而不是被动地思考这样的边界可能是什么?

地图

让我们通过重新使用人类最伟大的发明之一:地图来解决这个问题。它们的主要功能是在一个有限的空间内概括感兴趣的世界,而不是像高度详细的卫星图像那样将真实世界复制到最后的细节。换句话说,地图仅仅是*似值,它突出了感兴趣的特定部分,而忽略了不相关的部分。因此,所有的地图都是有目的的。例如,纽约市的地图可能会突出显示街区、地铁系统、自行车路线或旅游景点。虽然这些地图都不是纽约的准确代表,但它们都很有用。

我们能否重新利用绘制城市地图的概念来制作类似“神经科学地图”的东西?自然语言处理(NLP)领域提供了很有前途的工具,可以让我们更进一步,剩下的就交给我们自己的创造力了。

首先,我们应该考虑将自由文本(从 PubMed 神经科学文章数据库中抓取的超过 1M 的文章摘要)转换为更结构化的表示,以便于操作。从技术上来说,我们将通过构建一个文档术语矩阵(DTM) ,把摘要转换成一个向量空间表示。《DTM》的行里有所有的报纸,列里有单项选择。每个单元格的值代表一个单词 j 在文档 I 中出现的次数,因为我们会有一个非常大的词汇量,所以这个矩阵中的大部分值都被设置为零(这使得它成为一个稀疏矩阵)。使用这个矩阵,我们可以应用许多基本的数学技巧来回答我们的一些问题,如找到相似的单词、找到相似的论文、将论文分组(找到子字段)或对单词做同样的事情,等等。

正如我前面提到的,地图是根据一个特定的目标创建的,我有两个不同的目标或者两个地图。第一张地图将把潜在的语义可变性分成一个简单的范围。你可以把第一张地图想象成简单的语义罗盘。第二张图总结了单词相似度结构:什么单词和什么单词最相似,哪组单词和哪组最相似。这两张地图将在解开现代神经科学研究中潜在的语义景观方面相互补充。

故事 1——提取语义指南针

如果你要决定适用于研究领域的最简单(也是最通用)的标准,你可能会从基础研究开始,从应用研究开始。这些行中的数据驱动标准可以帮助我们阐明哪些维度或信息在整个词汇表中最具区分性。

对应分析是一种定量方法,将任何给定单词的信息压缩成简单的频谱,同时保留任何相似单词的映射。

Map 1: Correspondence Analysis results

如果你仔细观察上面的地图,你会发现单词分成两大组:右组和左组。我们可以通过查看这些单词所属的类别来确定这些组的身份。对我来说,右组主要是关于认知成像研究,而左组主要是关于更基本的方法(分子和遗传)。稍微缩小一下,最有鉴别能力的标准可能更多的是关于研究工具,而不是被调查问题的性质(诚然,有时可能很难将两者分开)。

故事 2——揭示底层结构

虽然上面的地图作为一幅大图是有用的(并且在数学上更容易分析),但它没有告诉我们底层的结构。如果我们把最相似的单词放在一起,利用我们所拥有的关于单词共现的信息,我们可能能够展示一个更准确和信息更丰富的画面。

Map 2: A network visualization of most common terms colored by the group they are most connected to.

在这里,我们看到一个更底层的结构。正如我们已经知道的,这个领域可以分成许多子域。也就是说,有一个临床神经科学集群(绿色),一个认知神经科学集群(绿色),一个神经生理学集群(灰色)和一个分子神经科学集群(红色)——以及更精细的集群。请注意,如果我对共现次数使用较低的阈值,可以显示更多的单词,但这可能会使网络更难正确可视化。

Close-ups.

虽然第二张图比前一张图更主观(也更不科学),但它仍然有助于显示构成现代神经科学研究的大的子领域。

乔治·博克斯曾经说过“所有的模型都是错的,但有些是有用的。”根据这个美丽的引用,我们也可以声称,每个可视化的故事只说明了关于要分析的数据的本质的一部分真相。希望这篇文章是有用的和有价值的。

感谢阅读。

描绘真实世界

原文:https://towardsdatascience.com/mapping-the-real-world-bd9a159ce6f8?source=collection_archive---------13-----------------------

Fig 1. Administrative divisions of China and Taiwan on (Left) an equal-area map, and (Right) a Flow-Based Cartogram where areas are proportional to GDP.

我们都认为我们知道世界是什么样子的。但是我们的世界地图总是反映最重要的东西吗?例如,关于中国在过去几十年中惊人的经济增长已经说了很多。然而,图 1(左)中的中国地理地图并没有告诉我们中国不同地区的国内生产总值(GDP)增长程度。

如果我们能制作更多视觉信息的地图会怎么样?

事实证明,我们可以。图 1(右)展示了一幅中国地图,其中各地区根据其各自的 GDP 贡献进行了重新调整。它不仅描绘了人们在经济进步背景下谈论的真实的中国,也展示了该国发展中的严重扭曲和不*等。这是对现实的一个有力的、引人入胜的描述——中国西部和东北实际上没有出现在伟大的中国成功故事中。

如图 1(右)所示的地图被称为地图。常规地图在形状、大小和位置方面优先考虑地理准确性。另一方面,统计图根据统计数据(如人口或 GDP)重新调整地图区域,这对于特定应用程序可能更有意义,同时仍尽可能保持拓扑地理特征。

除了提供震动和警报,在可视化空间数据方面,统计图还提供了优于常规地图的统计优势。下面图 2 中描述 2016 年美国总统选举结果的地图就是一个例子。共和党的唐纳德·特朗普赢得了红色的州。民主党的希拉里·克林顿赢得了蓝色州。

Fig 2. 2016 US presidential election map. Red indicates Republican victory. Blue indicates Democratic victory.

快速浏览一下这张地图,就会发现唐纳德·特朗普(Donald Trump)取得了压倒性胜利。这一错误结论的出现是因为地图上的区域面积没有反映它们所代表的定量数据。例如,爱达荷州和罗德岛州都拥有 4 张选举人票。但是爱达荷州在地图上占据了明显的位置,而罗德岛几乎不引人注意。

相反,如果我们使用基于每个州的选举人票的图表来表示相同的数据,我们将获得更直观的选举结果的代表性描述。这样的图表包括在下面的图 3 中。蓝色和红色区域现在准确地显示了民主党和共和党分别赢得了多少张选举人票。

Fig 3. US presidential election results on a Flow-Based Cartogram. Red indicates Republican victory. Blue indicates Democratic victory.

基于扩散的图表(链接)在很大程度上是使用中最流行的图表。这种图表生成技术在扩散的物理过程中找到了灵感。定义扩散运动的数学已经在科学文献中被仔细研究和记录,并很好地解决了手头的问题。

打个比方,考虑在房间的一个角落喷洒一些香水。几分钟后,你也能在房间的其他地方闻到香味。这是因为气味从高密度区域(最初被喷洒的角落)扩散到低密度区域(房间的其余部分)。同样,地图上的每个区域都可以认为是由粒子组成的。那么,对于人口分布图来说,高人口密度区域的粒子会向外流动并扩散,从而扩大这些区域,进而缩小低人口密度区域。

也就是说,这种图表生成方法相当慢。在当今的硬件上,他们可能需要几十分钟来创建简单的图表,如本文中使用的图表。创建图表的耗时过程是广泛采用这种数据可视化技术的巨大障碍。

为了加速图表生成过程并促进它们的共同使用,我与迈克尔·t·加斯特纳教授和 T2 研究并设计了一种新的算法,来生成我们称之为 T4 的基于流程的图表。请阅读我们在美国国家科学院院刊上发表的研究论文。

总之,在生成图表时,我们希望均衡地图上所有位置的密度。虽然传播是这样做的一种方式,但不是唯一的方式。我们的技术背后的新数学带来了算法效率,并使我们能够将计算分成可以独立完成的小而不相关的部分,从而利用了当今广泛使用的多核处理器。

我们工作的结果是图表生成器的速度提高了 60 倍。本文中展示的每个图表都是在几秒钟内生成的。中国地图用了我们的方法不到 3 秒钟就制作出来了,而美国大选地图用了 1.5 秒。作为另一个例子,下面的图 4(右)中的印度图表,其中各邦根据其各自的 GDP 贡献进行了重新调整,使用我们基于流量的方法需要 2.6 秒来生成。

Fig 4. States and union territories of India on (Left) an equal-area map, and (Right) a Flow-Based Cartogram where areas are proportional to GDP.

图表是一种强有力的工具,可以展示地面真相的有力表示,从而有效地提高广大民众对这些真相的认识。我希望通过我们的研究,我们可以减少创建图表的障碍,从而促进它们的采用。带着这个目标,我们还在 GitHub 上提供了我们的软件,以及如何使用它的说明。请欣赏使用该软件创建的网格世界地图,并根据人口进行缩放,如下图 5 所示。

注意:我正在开发一个 Python 包,让图表生成更加简单。我还计划建立一个 web 应用程序来实现同样的目的。这两个项目都是开源的。如果你想合作,请发电子邮件到 pratyushmore1996@gmail.com找我。

研究论文: PNAS 文章

软件: GitHub

Fig 5. Flow-Based Cartogram of a gridded world map, rescaled according to population.

英国交通事故热点地图

原文:https://towardsdatascience.com/mapping-the-uks-traffic-accident-hotspots-632b1129057b?source=collection_archive---------14-----------------------

Photo by Chris Lawton on Unsplash

在寻找一些有趣的地理数据时,我偶然发现了英国政府发布的道路安全数据。这是一个非常全面的道路事故数据集,包括事件的地理坐标,以及其他相关数据,如当地的天气情况,能见度,警察出勤等。早在 2009 年就有可用的数据,一直到 2016 年,所以这是一个非常有趣的数据集,可以用于地理和机器学习目的。

当我看到这些数据时,我立即想到在地图上可视化它。也许有可能找出交通事故密度较高的地区?由于一年的数据量巨大,仅 2016 年就超过 136,000 个点,将所有的点都转储到交互式地图中的天真方法被证明是不可能的。根据我的经验,这对于一个交互式网络地图来说太多了。这里需要另一种方法,显而易见的想法是为此探索基于密度的聚类算法。

与将整个输入空间划分为互补区域或聚类的其他聚类算法相反,这里我们只关注交通事故密度较高的区域,而将所有其他点作为噪声丢弃。对于这些高密度区域中的每一个,我们将创建一个地理围栏,作为其周围的包络,并使用它作为其中包含的点的图形表示。这种新的地理实体(多边形)可以存储在地理数据库中,以后可以用于在英国非常繁忙的街道上行驶时提供驾驶辅助。想象一下你的车辆 GPS 系统的一个额外功能,它会通知你进入一个道路事故热点,就像它警告你不要靠*高速摄像机一样。我打赌你在那里会试着开车更安全,不是吗?

让我们想象一下,我们的任务是使用来自英国政府的数据来实现这样一个系统。我们必须以某种方式将这一长串地理位置转换成地理围栏,将道路事故地理密度较高的区域圈起来。有了地理围栏——一种用地理坐标表示的多边形——我们可以很容易地测试你的车辆是否正在接*一个这样的热点,如果它已经进入或离开它。

基于密度的聚类

因此,为了检测事故热点,我们必须找到事故位置密度高的区域,并在每个区域周围绘制一个多边形。首先,我们必须澄清我们所说的密度是什么,以及如何测量它。此外,我们必须了解如何处理低密度区域。

基于密度的数据分析技术背后的基本思想是,感兴趣的数据集代表来自未知概率密度函数(PDF)的样本,该函数描述了负责产生观察数据的一种或多种机制。[1]

这里,我们将聚类定义为包围高密度区域的区域,而所有其他点将被视为噪声,因此从分析中丢弃。有几种算法可以处理这种类型的数据,我为本文选择的算法是 DBSCAN [2]。

我们识别聚类的主要原因是,在每个聚类内,我们都有一个典型的点密度,该密度远高于聚类外的密度。此外,噪声区域内的密度低于任何聚类中的密度。[2]

你可以在这里阅读关于这个聚类算法的很好的描述,并且本文中使用的实现是由scikit-learn【3】提供的。注意,有两个非常重要的参数需要设置:聚类点之间的最小距离( eps )和每个聚类的最小点数( minPts )。为了更好地理解这些参数如何工作以及它们如何影响聚类结果,您可以在笔记本单元格上单独设置它们:

这里, minPts 参数被创造性地命名为 num_samples 。这些参数决定了什么属于一个聚类,什么被认为是噪声,因此这些参数将对最终聚类集的数量和大小产生直接影响。

运行 DBSCAN 实际上非常简单:

One-liner for running DBSCAN. See the GitHub repository for more information.

在对数据运行 DBSCAN 之后,我们得到了一个集群及其对应点的集合。噪声点用聚类号-1 标记,并从我们的分析中排除。

气泡

现在是用这些数据做有趣事情的时候了,在本文中,我们将使用每个星团的云的形状来绘制地理围栏。有几种策略可以做到这一点,比如绘制一个凸包或者甚至一个凹包,但是这里我将使用一个非常简单的方法,可以称为“聚结气泡”。这个想法很简单:在每个点周围画一个圆,然后将它们合并在一起。像这样:

The “coalescing bubbles” process of geofence calculation.

这是一个两步的过程,我们首先将所有的位置点“膨胀”成一个给定半径的圆,然后将所有的圆合并成一个多边形。创建圆(缓冲)代码如下:

投影代码需要在米(我们用于圆半径的单位)和地理坐标(纬度和经度对)之间进行转换。至于半径,我们使用一个比 eps 小 0.6 倍的值,以避免出现非常大的圆。

让我们看看这在代码中是如何工作的。首先,我们必须根据聚类标识符对点进行分组。记住噪声点用-1 标记。

现在我们可以开始冒泡过程。为了提高效率,我使用了 shapely 中的 cascaded_union 函数。

Bubble creation process

现在,我们可以使用上面创建的列表创建一个地理数据框架,并简单地绘制它。就像这样简单:

Create a geopandas GeoDataFrame and plot it.

最后,我们可以用两行代码将整个事情发送到一个交互式地图:

Show the interactive map.

完整代码可在相关的 GitHub repo 中获得。尽情享受吧!

London traffic accident hotspots example using data between 2015 and 2016.

所需包

为了运行笔记本,您必须首先安装几个包,即 geopandas 和所有依赖项。这不是一个简单的任务,但幸运的是 Geoff Boeing 在他出色的博客文章在 Windows 上使用 geo pandas中为我们简化了这个任务。

你还需要安装笛卡尔包来渲染地图上的多边形。

最后,你还需要mple leaf,在浏览器上渲染交互式地图。

参考文献

[1] 用于数据聚类、可视化和异常值检测的分层密度估计

[2]sci kit-learn:Python 中的机器学习,Pedregosa 等人,JMLR 12,第 2825–2830 页,2011。

[3] Ester,m .,Kriegel,H.P .等人(1996)一种用于在带有噪声的大型空间数据库中发现聚类的基于密度的算法。KDD,226–231

[4] 用 Python 制作地图,米歇尔·富尔伍德

将旅行时间映射到新加坡的各个地方

原文:https://towardsdatascience.com/mapping-travel-time-to-places-in-singapore-56cbdd2042c7?source=collection_archive---------4-----------------------

今天我正在玩 rmapzen 包来创建一些等时图。

等时线地图描绘了通过不同的交通方式到达特定位置的旅行时间相等的等值线。

在这里,我画出了开车去果园的时间和步行去海湾花园的时间。

Driving time to Ion Orchard

Walking time to Garden By the Bay

可以很好地利用等时线地图:例如,通过将等时线地图与地区/邮政编码 shapefile 重叠来缩小搜索范围,以查找公共交通 x 分钟内的工作场所,或者找出医疗保健设施覆盖最少的区域,教育部门覆盖最多的区域等。我还没有弄清楚是否可以用 rmapzen 创建多个等时线,来描绘到不同位置的旅行距离的轮廓。

这是我的# 100 日项目的第 38 天,在外出旅行几周后,我开始了数据科学和视觉故事讲述。完整的代码在我的 github 上。感谢阅读,欢迎反馈。

用 Word2vec 映射单词嵌入

原文:https://towardsdatascience.com/mapping-word-embeddings-with-word2vec-99a799dc9695?source=collection_archive---------10-----------------------

利用词向量之间的语义和句法关系增强自然语言处理

Word embedding created using Word2vec | Source: https://www.adityathakker.com/introduction-to-word2vec-how-it-works/

介绍

自然语言处理(NLP)是人工智能的一个领域,专注于让计算机理解、处理和分析人类语言。NLP 广泛应用于科技行业,作为搜索引擎、垃圾邮件过滤器、语言翻译等等的主干。NLP 使计算机能够将人类语言转换成它可以阅读和理解的形式,例如向量或离散符号。例如,NLP 可以接收句子So hungry, need food,并将其分解为四个任意符号:so表示为K45hungry表示为J83need表示为Q67food表示为P21,然后所有这些都可以由计算机处理。每个唯一的单词由不同的符号表示;然而,缺点是指定给hungryfood的符号之间没有明显的关系。这阻碍了 NLP 模型使用它所了解到的关于hungry的信息并将其应用到food,这在语义上是相关的。向量空间模型(VSM)通过将单词嵌入向量空间来帮助解决这个问题,在向量空间中,相似定义的单词被映射到彼此附*。这个空间叫做单词嵌入。

Word2vec

Word2vec 是由谷歌的托马斯·米科洛夫领导的一个研究小组的成果,是用于创建单词嵌入的最流行的模型之一。Word2vec 有两种将单词上下文化的主要方法:连续词袋模型(CBOW)和跳过语法模型,我将在本文中总结这两种方法。这两个模型得出了相似的结论,但是采用了几乎相反的途径。

连续词袋模型

CBOW 是两个模型中不太受欢迎的一个,它使用源单词来预测目标单词。例如,以这个实例中的句子I want to learn python**.**为例,目标词是python,而源词是I want to learn。CBOW 主要用于较小的数据集,因为它将句子的上下文视为预测目标单词的单个观察。实际上,当处理大量单词时,这变得非常低效。

跳格模型

Skip-Gram 模型的工作方式与 CBOW 模型相反,使用目标单词来预测周围单词的来源或上下文。考虑句子the quick brown fox jumped over the lazy dog,假设我们对给定单词的上下文使用一个简单的定义作为紧接在它前面和后面的单词。Skip-Gram 模型将把句子分成**(context, target)**对,产生一组格式如下的对:

**([the, brown],quick), ([quick,fox],brown), ([brown,jumped],fox)...**

这些对被进一步筛选成**(input, output)**对,表示每个单词(输入),该单词直接位于其前面或后面。这是必要的,因为 Skip-Gram 模型通过使用目标单词(输入)来预测上下文或输出。这些对表示如下:

**(quick, the), (quick, brown), (brown, quick), (brown, fox)...**

既然每个单词都能够在上下文中表示出来,有趣的事情就开始了。我不会进入数学领域——这个 TensorFlow 教程提供了深入的解释——但是预测给定上下文中每个单词的损失函数可以使用随机梯度下降和迭代数据集中的每一对来优化。从那里,可以使用 t-SNE 降维技术将向量降维为二维。

Skip-Gram model with context defined as the two words immediately before and after the target word. Source: http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/

可视化单词之间的语义和句法关系

一旦单词向量被简化为二维,就有可能看到某些单词之间的关系。语义关系的例子是男性/女性名称和国家/首都关系,而句法关系的例子是过去时和现在时。下图很好地展示了这些关系:

Source: https://www.tensorflow.org/tutorials/representation/word2vec

共享语义或句法关系的单词将由相似大小的向量来表示,并且在单词包含中被映射为彼此非常接*。不再是用任意的离散符号K93表示king,用S83表示queen的情况。相反,kingqueen之间的关系更加明显——事实上,它与分别对应于manwoman,的向量之间的关系完全相同。这允许在向量上执行非常酷和神奇简单的运算。例如:如果从brother的矢量表示中减去boy的矢量,然后加上girl的矢量,就会得到sister

**brother - boy + girl = sister****queen - woman + man = king****biking - today + yesterday = biked**

这为在数据中寻找模式或其他见解开辟了一个全新的可能性维度。

使用 TensorFlow 实现 Word2vec

使用 TensorFlow 教程中展示的示例代码我将演示 word2vec 在实践中是如何工作的。TensorFlow 是由谷歌大脑团队开发的内部使用的机器学习库,于 2015 年向公众开源,旨在加速人工智能的发展。TensorFlow 是一种用于深度学习、逻辑回归和强化学习的强大工具,并且由于其在训练大型数据集时优化计算效率的能力而变得流行。

提供的示例代码读取 50,000 个单词的大型数据集,并训练 skip-gram 模型以上下文方式对单词进行矢量化。然后,它遍历数据 100,000 次,以优化数据集中一批随机流行词的损失函数。首先,流行单词的最*邻居没有显示出与每个单词的任何句法或语义关系。在 100,000 步之后,可以看到清晰得多的关系,并且损失函数降低了 98%以上。

Summary showing 8 nearest neighbors for a random batch of popular words, at 0 and 100,000 steps

如上所述,在训练 skip-gram 模型之前,单词three的八个最*邻是:bissau, zeal, chong, salting, cooperate, quarterfinals, legislatures, ample。当迭代完成时,three的最*邻居是:five, four, seven, six, two, eight, nine, agouti。虽然不完美——据我所知,agouti 是一种热带美洲啮齿动物,而不是一个数字——8 个最*的邻居中有 7 个显示出与单词three有明确的语义关系。

Left: Central American Agouti | Right: Numbers - (Sources: Wikipedia, Google Images)

谷歌翻译中的性别偏见

虽然 word2vec 可以创建说明单词之间的语义和语法关系的单词嵌入,但该模型并非没有一些缺陷。2016 年一项名为 的研究显示,男人对于电脑程序员就像女人对于家庭主妇一样?消除单词嵌入的偏见 (Bolukbasi,Chang,Zou,Saligrama,Kalai)展示了谷歌使用的单词嵌入如何以惊人的速度强化性别陈规定型观念,并确定了解决这一问题的潜在办法。数据科学家和企业家 Emre arbak 使用谷歌翻译进一步强调了单词嵌入算法所显示的性别偏见。精通土耳其语的 arbak 测试了谷歌如何将使用中性代词的土耳其语句子翻译成英语。结果既令人着迷又令人不安。(更多例子)

Source: https://www.facebook.com/photo.php?fbid=10154851496086949&set=a.10150241543551949&type=3&theater

在很大程度上,当一个句子包含陈规定型地归因于女性的描述符(cook, teacher, nurse)时,土耳其中性代词o被翻译成she。相反地,包含诸如hard workinglawyerengineer的句子中,代词被翻译成了男性形式。这不仅仅是谷歌的责任——它的算法是基于包含数十亿数据点的人类词汇语料库,所以谷歌只是反映了已经存在的偏见。然而,谷歌仍在确定数百万人在使用翻译(或搜索、YouTube 和任何其他流行的谷歌*台)时看到了什么。

最终,这很可能是一个强大工具的意想不到的负面后果,但它提出了一个重要问题,即我们有多容易让计算机和人工智能决定我们的想法和看法。NLP 和单词嵌入是必不可少的工具,可以说是人工智能的未来;然而,关于机器学习算法如何做出决策的公开对话非常重要,这样边缘化的声音才不会被拒之门外。

其他资源:

  • TensorFlow Word2vec 教程
  • Word2Vec(跳格模型):第 1 部分——直觉作者 Manish Chablani
  • 克里斯·麦考密克的 Word2Vec 教程——跳格模型
  • TensorFlow Github

三月版:理解如此多的数据

原文:https://towardsdatascience.com/march-edition-making-sense-of-so-much-data-ab82a985c196?source=collection_archive---------10-----------------------

11 篇必读文章

关于机器学习需要知道的 12 件有用的事情

由詹姆斯·勒 — 16 分钟读完

机器学习算法可以通过从示例中进行归纳来找出如何执行重要任务。在手动编程不可行的情况下,这通常是可行的且成本有效的。随着越来越多的数据可用,更多雄心勃勃的问题可以得到解决。

加入我们成为编辑助理 : 随着我们读者群的持续增长,我们将开放 5 个新的编辑助理志愿者职位。立即申请。

多维数据的有效可视化艺术

由迪潘詹·萨卡尔 — 16 分钟读取

描述性分析 是任何与数据科学项目甚至特定研究相关的分析生命周期的核心组成部分之一。数据聚合、汇总和可视化是支持这一数据分析领域的一些主要支柱。

大数据会有偏差,如果我们放任不管

由费德丽卡·佩泽尔 — 7 分钟读完

对于我们这些肩负着使用大数据来帮助解决组织中一些最大的低效、问题或难题的令人兴奋且日益增长的任务的人来说,永久化偏见是一种太容易犯的错误,我们现在都应该熟悉它了。

解释机器学习模型

由 Lars Hulstaert — 8 分钟阅读

不管您的数据科学解决方案的最终目标是什么,最终用户总是更喜欢可解释和可理解的解决方案。此外,作为一名数据科学家,您将始终受益于模型的可解释性,以验证和改进您的工作。

如何构建数据科学管道

由 Balázs Kégl — 5 分钟阅读

从 y 开始。专注于形式化预测问题,建立工作流程,并将其转化为生产,而不是优化您的预测模型。一旦前者做到了,后者就好办了。

如何使用序列对序列模型创造神奇的数据产品

通过哈默尔侯赛因 — 17 分钟读取

我从未想过我会用“神奇”这个词来描述机器学习技术的输出。当我被引入深度学习时,这种情况发生了变化,在深度学习中,你可以完成像识别图片中的物体或分类两吨重的乐高玩具这样的事情。

如何进行数据实验室:针对大型数据集运行笔记本电脑

由郁风克 — 5 分钟读出

将大数据传输到本地计算环境既缓慢又昂贵。在这一集的人工智能冒险中,我们将看到如何将您的笔记本环境应用到您的数据中!

概括 10 种常见的软件架构模式

通过Vijini mallawatarachchi—5 分钟读取

想知道大型企业级系统是如何设计的吗?在主要的软件开发开始之前,我们必须选择一个合适的架构,它将为我们提供期望的功能和质量属性。

数据库— SQL 和 NoSQL

由阿努拉达·维克拉马拉奇 — 4 分钟阅读

SQL 在 1970 年与 E. F. Codd 博士的研究论文“大型共享数据库的关系数据模型”一起使用。是啊!!这是 Boyce-Codd 规范化中的 Codd。

大规模应用开发架构

由查敏·纳林达 — 17 分钟读完

现在,只需一瞥的时间,就可以实时分析卫星从太空发送到地球的数十亿字节的数据。还记得埃隆·马斯克强调的来自人工智能的潜在威胁吗?如果我们不能规范“人工智能”(他认为这非常重要),这种威胁就不远了。

数据科学工作流程

通过 Aakash Tandel — 13 分钟读取

没有解决数据科学问题的模板。路线图会随着每个新数据集和新问题而变化。但是我们确实在许多不同的项目中看到类似的步骤。

我们也感谢最*加入我们的所有伟大的新作家,乌兹玛·巴拉斯卡,克里斯·罗尔斯,凯末尔·图鲁尔,内森·胡本斯,简内·库尔,艾克·奥康科沃,维德雅瑟格·马楚帕里,德里克·姆维蒂,尼克拉斯·东格斯, 扎克·阿基、格雷格·拉弗蒂、阿桑·阿尼斯、杰瑞米·哈里斯、易勒雅斯·哈比卜、文卡特什·帕帕克里什南博士、诺拉·侯赛尼、阿迪蒂亚·阿南瑟拉姆、弗朗切斯科·祖皮奇尼 我们邀请你看看他们的简介,看看他们的工作。

Mario vs . Wario:Python 中的图像分类

原文:https://towardsdatascience.com/mario-vs-wario-image-classification-in-python-ae8d10ac6d63?source=collection_archive---------1-----------------------

使用逻辑回归和卷积神经网络对视频游戏图像进行分类

从我的学龄前时代,我记得花了很多时间在我最喜欢的游戏男孩身上玩游戏。我最喜欢的两个*台游戏是马里奥和瓦里奥。我记得当我的祖母看了一眼我正在玩的游戏,问我那是什么。我解释说是超级马里奥。过了一段时间,当她看到我又在玩游戏时,她看着屏幕说:“又是马里奥?这个游戏有多长?”但这是一场完全不同的比赛,瓦里奥。这种记忆启发我尝试图像识别,并尝试看看我是否可以训练一个分类器来准确识别一些截图的来源。

在本文中,我使用了两种方法。基本的是逻辑回归,比较高级的是卷积神经网络(使用 Keras 配合 TensorFlow 后端)。我并不专注于解释算法背后的逻辑或数学,因为已经有大量关于 Medium 和其他地方的优秀文章。相反,我试图展示一个简单、随机的想法如何快速转化为数据科学项目。

为了简洁起见,我只发布了一些代码片段,而完整的代码可以在我的 GitHub 上找到。

数据准备

本着儿时的回忆,我选择了两款游戏进行这次实验:超级马里奥之地 2: 6 金币瓦里奥之地:超级马里奥之地 3 。我选择这些游戏不仅是因为它们是我当时最喜欢的,而且在检查游戏的图像时,人们可以看到它们在视觉上非常相似,这应该会使任务变得有点困难!

我想知道从这些游戏中获取大量截图的最好方法是什么,于是决定从 Youtube 上的一个视频中“抓取”下来。Python 的pytube库可以帮助完成这项任务。我可以毫不费力地用几行代码下载整个视频。

下一步包括从视频中剪切帧。为此,我迭代所有帧(使用OpenCV库),并且只将每第 n 帧保存到指定的文件夹中。我决定用 10k 的图像(每场 5k)。在这两种方法中,我将使用相同的 80-20 训练测试分割来确保可比性。

当抓取帧时,我跳过了视频的前 60 秒,其中主要包含开场序列和菜单(我没有在视频结尾这样做,所以可能会包含一些噪声,但我们会看到的!).

A sample image from Mario class

A sample image from Wario class

在看了预览后,很明显这些图像的大小不一样。这就是为什么我把它们重新调整为 64x64 像素。此外,对于逻辑回归,我会将图像转换为灰度,以减少模型的特征数量(CNN 将处理 3 个颜色通道)。

64x64 greyscale image for logistic regression

逻辑回归

我将从更简单的模型开始。逻辑回归是一种基本的二元分类器,,使用一组预测器来分配两个类别中的一个。

话虽如此,要使用逻辑回归来解决图像分类问题,我首先需要准备数据。输入应该与从Scikit-Learn开始的其他模型完全相同,即特征矩阵 X 和标签 y

由于本文的目标是展示如何为一个特定的问题构建一个图像分类器,所以我不关注算法的调整,而是使用逻辑回归的默认设置。让我直接跳到结果!

Confusion matrix for logistic regression’s predictions on the test set

上面我给出了测试集的结果,因此模型无法用于训练的部分数据(20%的数据)。这看起来很棒,实际上可能有点好得难以置信。让我们检查几个正确/错误分类图像的例子。

Correctly classified images

Misclassified images

5 张图片中有 4 张被错误分类,这背后的逻辑非常明显。这是一些模型实际上不能做任何事情的转换屏幕。第二个屏幕来自《超级马里奥》中的关卡地图,与游戏的其余部分明显不同(这里不是*台化游戏)。但是,我们也可以看到,该模型正确地分类了另一张地图(正确分类的图像中的图像 3)。

卷积神经网络

这部分显然会比逻辑回归复杂一点。第一步包括以特定的方式存储图像,这样 Keras 就可以施展它的魔法了:

mario_vs_wario/
    training_set/
        mario/
            mario_1.jpg
            mario_2.jpg
            ...
        wario/
            wario_1.jpg
            wario_2.jpg
            ...
    test_set/
        mario/
            mario_1.jpg
            mario_2.jpg
            ...
        wario/
            wario_1.jpg
            wario_2.jpg
            ...

这个目录树显示了我如何为这个特定的项目构建文件夹和文件。下一部分是数据扩充。这个想法是对可用的图像应用一些随机变换,以允许网络看到更多独特的图像用于训练。这将防止过度拟合并导致更好的泛化。我只使用了一些变换:

  • 重新缩放-在进行任何其他处理之前,数据将乘以的值。原始图像由 0-255 范围内的 RGB 系数组成。对于模型来说,这样的值可能太高而无法处理(以典型的学习率),因此乘以 1/255 的因子会将变量重新调整到 0-1 的范围内
  • shear _ range 用于随机应用剪切变换
  • zoom_range —用于随机缩放图片
  • horizontal_flip —用于水*随机翻转一半的图像(当没有水*不对称的假设时相关,例如真实世界的图片)。我决定不使用这个功能,因为在视频游戏截图的情况下,这将毫无意义(数字等)。)

当指定图像的路径时,我还确定了我要输入到神经网络的图像的大小(64x64,与逻辑回归相同)。

下面我展示了一个应用一些变换后的图像的例子。我们看到图像在两侧被拉伸。

现在是时候定义 CNN 了。首先,我初始化 3 个卷积层。在第一个例子中,我还需要指定输入图像的形状(64x64,3 个 RGB 通道)。后来,Keras 自动处理大小。对于所有这些,我使用 ReLU(校正线性单位)激活功能。

卷积层之后是扁*化。由于最后两层基本上是一个常规的人工神经网络分类器,我需要将卷积层的数据转换成 1D 向量。在这两个密集层之间,我还使用了 dropout。简单来说,dropout 在训练过程中忽略指定数量的神经元(随机选择)。这是一种防止过度拟合的方法。最后一个密集图层使用 sigmoid 激活函数,并将返回给定观测值属于其中一个类的概率。最后一步基本上就是逻辑回归所做的。

现在是时候运行 CNN 了(这可能需要一段时间……)。我使用 ADAM 作为优化器,选择二进制交叉熵作为该二进制分类任务的损失函数,并使用准确度来评估结果(不需要使用不同的度量,因为在这种特定情况下,准确度是我感兴趣的)。

那么神经网络表现如何呢?让我们看看!

Confusion matrix for CNN’s predictions on the test set

嗯,精确度低于逻辑回归的情况,但对于这样一个快速建立的模型来说,它仍然是非常好的。可以通过改变卷积/密集层的数量、改变丢失、对图像执行额外的变换等等来微调网络。也可能是转换隐藏了图像中的一些数据(例如图像底部的摘要栏)。事实上,我最初怀疑这个条可能在识别图像中起重要作用,因为它出现在几乎所有的截图中,并且在两个游戏之间略有不同。但是我一会儿会回来。

现在是时候检查几个正确/错误分类图像的例子了。乍一看,不同之处在于,在这种情况下,没有像屏幕转换这样明显的错误分类例子。

Correctly classified images

Misclassified images

用石灰解释分类

作为奖励,我尝试用 LIME(本地可解释模型不可知解释)解释 CNN 的图像分类。模型不可知意味着 LIME 可以应用于任何机器学习模型。它基于修改单个观察的特征值并观察对预测的影响的思想。我强烈推荐介绍这个想法的论文[2]。

下面我展示了应用石灰解释图像的结果。绿色区域表示对预测类别的积极影响,红色表示消极影响。从正确分类的案例中,我们看到角色总是在绿色区域。这是符合逻辑的。然而,对于不真实的负面情况,一些图像也只有一种颜色。这提供了一些见解,但我认为通过额外的修补,甚至可以从石灰解释中提取更多。

LIME explanation for correctly classified images

LIME explanation for misclassified images

结论

在本文中,我介绍了如何将一个随机的想法快速转化为一个图像分类项目。这两种方法在数据集上都表现得很好,我相信 CNN 可以通过一些调整获得更好的成绩。

进一步修补的一些潜在想法:

  • 添加更多游戏(不同的*台游戏或不同的马里奥/瓦里奥系列)来研究模型在多职业环境中的表现
  • 准备数据的不同方法——我可以从当前图像的中间截取更大的图像(128x128,因为两个视频都有更大的分辨率)。这也可以解决底部摘要栏的潜在问题。
  • 在 CNN 的数据生成步骤中添加额外的图像变换
  • 尝试检测图像中的马里奥/瓦里奥(物体检测问题)

我希望你喜欢这篇文章。如果您对框架或模型的潜在改进有任何建议,请在评论中告诉我!你也可以通过 Twitter :)联系我

本文中使用的代码可以在我的 GitHub 上找到。

参考资料:

[1] Keras 在 CNN 上的博文:https://blog . Keras . io/building-powerful-image-class ification-models-using-very-little-data . html

[2]石灰纸:https://arxiv.org/pdf/1602.04938.pdf

免责声明:我不拥有任何与 YouTube 内容或视频相关的视频游戏的权利。

在线零售数据的购物篮分析

原文:https://towardsdatascience.com/market-basket-analysis-on-online-retail-data-24ee7214a762?source=collection_archive---------7-----------------------

你有没有注意到,在杂货店里,面包和牛奶往往离得很远,尽管它们通常是一起购买的?这是为什么呢?这是因为他们想让你逛遍整个商店,注意面包和牛奶之间的其他商品,也许会买更多的商品。这是一个应用市场篮子分析 (MBA)的完美例子。MBA 是一种建模技术,其理论基础是,如果你购买了某一套商品,你或多或少会购买另一套商品。这是一项用于发现关联规则的基本技术,可以帮助增加公司的收入。

在我之前的一篇文章(预处理大型数据集:50 万以上实例的在线零售数据)中,我解释了如何处理 50 万以上观察值的庞大数据集。我将使用相同的数据集来解释 MBA,并找到潜在的关联规则。

正在使用的软件包有:

  • plyr —函数 ddply 所必需的,该函数允许根据指定的标准创建项目集
  • arules——一个非常有用的包,有许多选项,其中一个是函数 apriori ,它可以根据一起购买的商品的频率来查找关系
  • arulesVizarules包的扩展,具有关联规则和频繁项目集的各种可视化技术

已经使用 ddply 功能创建了项目集;对于数据框的每个子集,将应用一个函数,并将结果合并到一个数据框中。我们将按变量发票号进行拆分。物品清单已写入“Items_List.csv”文件,交易已使用 read.transactions 函数扔入“篮子”中。以下是篮子的摘要:

我们可以在上面看到哪些是最常购买的项目,以及项目集长度分布和基本统计数据。挺有用的!人们*均购买 23 件商品。

看看前 15 本畅销书可能会很有意思。可以改变 topN 参数或将类型切换到“相对”状态。

接下来,使用先验函数,我们能够生成规则。我们将支持度设置为 0.005,它应该很小,因为我们有一个大的数据集,否则我们可能会得到很少的规则。置信度设置为 75%。总共生成了 678 条规则:

这些规则已经按照可信度降序排列,在下面的总结中,我们可以看到规则的长度分布(从 2 到 6)。我们也看到最小和最大的支持、信心和提升。我们看到最大升力接* 122%。最小值是 8.691%,这表明这些项目出现的频率比预期的少得多。这两个信息在 MBA 中都非常有用——非常小的提升不应该被忽略!

arulesViz 软件包让我们能够可视化我们的发现。我们在下面看到我们所有规则的散点图。暗红色的点表示高度提升。那些规则往往有较高的可信度,但支持度较低。

我们可以通过在先验函数中指定 maxlen 来轻松控制规则的最大长度。这是在创建 basket_rules2 时完成的。当我们希望规则简洁时,这非常有用。在这种情况下, maxlen 被设置为 3。

另一种可视化规则的方式是下图。我们在图表中看到一些圆圈。圆圈越大,支撑越大。圆圈的颜色与升力有关。大圆圈代表支持度高的规则。

也可以将项目作为目标来生成规则。例如,我们可能对顾客在喝咖啡之前可能会买什么感兴趣。在先验函数中,我们将外观设置为带有 default = "lhs" (左手边)和 rhs = "COFFEE" 的列表。我们发现了 5 种通常与咖啡搭配的食物。

糖之后顾客可能会买什么?让我们来了解一下!

当然是咖啡!😃

MBA 吸引了众多零售公司的目光。零售业本质上是高度以客户为中心的,零售商正在不遗余力地寻找新的方法来更好地了解他们的客户。利用 MBA,零售商不仅可以确定目标市场,还可以通过创造、提供和交流卓越的客户体验来扩大客户群。MBA 允许零售商快速查看客户购物篮的大小、结构、数量和质量,以了解购买产品的模式。然而,MBA 给零售业从业者带来的好处要多得多。

完整的 R 代码,请访问我的 GitHub 简介。

用相似方法进行市场评估

原文:https://towardsdatascience.com/market-evaluation-with-similarity-methods-e50eacca34b9?source=collection_archive---------7-----------------------

探索当前市场状况的一个方法是将今天与历史上类似的时期进行比较,然后观察在那个时期什么成功了,什么失败了。尽管小样本和不断变化的世界存在明显的缺陷,但这种方式的分析仍然是政策、投资和社会努力的有趣起点。

探索这一点的一个策略是收集过去几十年中一系列指标的数据,以表明这两年有多相似,至少在感兴趣的指标方面是如此。国际货币基金组织提供了大量的时间序列数据——这里我只关注美国和国内的数据来源。仅这一项就为国家的金融、宏观经济和社会状况提供了 1500 多项指标,可以通过应用一些启发法来缩小范围:

  • 仅包括以通货膨胀调整值或百分比表示的变量。
  • 不要为同一个概念包含多个变量,以避免多重共线性和特定指标的权重过大。

这些变量被归一化以消除比例效应。宏观经济变量的一个问题是,它们通常是非*稳的,这是一种奇特的说法,即它们受到前几年价值的严重影响。一个明显的例子是国内生产总值,我们预计国内生产总值将只是一个小的(希望是积极的)不同于去年的国内生产总值。一种方法是只考虑 GDP 的变化量,或者一年和前一年的 GDP 差异。这种转换也适用于所有使用的指标。

每个经过处理的指标在给定年份的值被表示为一个向量。

基本上,向量定义了空间中的一个点。为了评估两个点有多相似,我们可以测量这两个点有多接*。通过将指标存储为向量,我们可以使用基于向量的距离度量,例如欧几里德距离,来评估两个向量有多相似。

评估每一对年份之间的相似性可以让我们绘制出相似性如何随时间演变的图表,如下图所示的 2008 年。值得注意的是,其他衰退年份显示出与 2008 年的高度相似性,2008 年本身就是一个衰退年。

或者,我们可以绘制一个相似性热图,尽管这很难解释。

技术札记

变量的非*稳性

变量的非*稳性可以通过变量的自相关来检测,自相关测量变量与不同年份前的过去值的相关程度,其滞后

GDP showing significant autocorrelation, indicative of non-stationarity

差异 GDP 变量的自相关如下所示,其快速下降表明非*稳性已被消除。这使得它的积分阶为 1,即 I(1)。

市场组合建模 101 —第二部分(贡献图)

原文:https://towardsdatascience.com/market-mix-modeling-101-part-2-95c5e147c8a3?source=collection_archive---------4-----------------------

Source: Pixabay

大家好。新年快乐!

在我的上一篇文章中,我已经向您介绍了市场组合建模的概念。如果您想要复习,请点击下面的链接:

https://towards data science . com/market-mix-modeling-mmm-101-3d 094 df 976 f 9

在这篇文章中,我将解释如何解读贡献图,以及应该避免哪些常见的陷阱。

那么,什么是贡献图呢?

贡献图是一种直观的方式来表示哪些营销投入推动了销售,以及每个营销投入的影响有多大。以视觉方式展现市场现实,总是有助于减轻时间紧迫的客户的认知负担。

贡献图表的类型:

贡献图通常以两种方式绘制:

1.总计为 100 的绝对贡献

2.总计为 100 的非绝对贡献

  1. 总计为 100 的绝对贡献

为了解释上面的贡献图,我们假设已经销售了 100 个单位的产品。

在售出的 100 个单位中,即使营销人员不投资任何形式的广告,也会售出 53 个单位。基本上,这 53 个单位的销售是因为品牌在市场上的资产和它在过去在客户心目中创造的意识。类似地,通过电视广告售出 7 台,通过消费者促销和 BTL 促销各售出 3 台。

正确解释价格是理解 MMM 贡献的关键。很多时候,人们被误导了,因为当提到代表价格的负号时。请注意,当我们用价格上的负号对上图中的贡献进行求和时,总和是 44 而不是 100。

如果我们忽略价格上的负号,贡献的总和将是 100。因为大多数品牌的销量和价格呈负相关(该死的苹果!),价格贡献用负号表示,以表示它可能导致的销售损失量。

此处,价格的负号表示由于价格上涨,损失了 28 个销售单位。这是一个概念性的概念,描述了如果价格没有增加,可以获得 28 个额外的销售单位。

除了价格之外,出于同样的原因,竞争对手的活动在贡献上也用负号表示。

2。 非绝对贡献总和为 100

第一种解释贡献的方法对一些人或客户来说有点混乱。因此,有另一种方法可以用来解释结果。

在上面的图表中,我们可以看到总贡献总和为 100%,负号保持不变。

因此,从这张图表中我们可以看出,该品牌售出了 162 件(所有积极贡献的总和)。在售出的 162 个单元中,118 个单元的销售来自基础和分销。电视广告等推动了 17 台的销售。由于价格上涨,已经失去了 62 个销售单位。因此,总销售量为 100 台。

解释贡献图时要避免的陷阱:

1。 仅仅依靠捐款:

市场组合模型用整体方法解释。仅仅使用贡献百分比不是解决市场组合建模问题的正确方法。贡献图之后是计算投资回报率。

可能会有某个变量显示贡献与使用的数据一致,但会显示不稳定的 ROI 数字。在这种情况下,贡献被调整以获得所有的结果。

2。 不将贡献与基准进行比较

建议将模型的贡献与类似品牌/类别的基准数据进行比较,以衡量贡献结果的准确性。这有助于在到达 ROI 计算阶段之前验证结果。从领域的角度来看,可以调整模型以使结果更加准确。

3。 *衡统计和域:

一些 MMM 模型在统计上是稳健的,但可能没有商业意义,反之亦然。领域知识应该与统计数据结合使用,以利用业务洞察力。

所以,这些是在 MMM 上工作时需要考虑的一些事情。当然,MMM 是一个很大的话题,并且有进一步的细微差别。我希望在不久的将来写更多关于这个话题的文章。

如果你喜欢我的文章,给它一些掌声,或者更好地与你的朋友或同事分享。

最*,很多人问我是否做市场组合建模/营销分析方面的咨询。

答案是肯定的。您可以将您的咨询问题发送到https://www.arymalabs.com

领英:https://www.linkedin.com/in/ridhima-kumar7/

推特: @kumar_ridhima

版权所有 2018www.ridhimakumar.com版权所有。

市场组合建模(MMM) — 101

原文:https://towardsdatascience.com/market-mix-modeling-mmm-101-3d094df976f9?source=collection_archive---------1-----------------------

Source: tvba.co.uk

市场组合建模(MMM)是一种技术,有助于量化几种营销投入对销售或市场份额的影响。使用 MMM 的目的是了解每项营销投入对销售额的贡献,以及每项营销投入的花费。

MMM 有助于确定每项营销投入在投资回报方面的有效性。换句话说,投资回报率(ROI)较高的营销投入作为媒介比投资回报率较低的营销投入更有效。

MMM 使用回归技术,通过回归执行的分析进一步用于提取关键信息/见解。

在这篇文章中,我将谈论与理解 MMM 相关的各种概念。

1。 多元线性回归:

如前所述,市场组合建模使用多元线性回归原理。因变量可以是销售额或市场份额。通常使用的独立变量有分销、价格、电视支出、户外活动支出、报纸和杂志支出、线下促销支出和消费者促销信息等。如今,一些营销人员大量使用数字媒体来提高品牌知名度。因此,像数字消费、网站访客等输入。也可用作 MMM 的输入。

因变量和预测变量之间形成一个方程。这个方程可以是线性的,也可以是非线性的,这取决于因变量和各种营销投入之间的关系。有些变量,如电视广告,与销售呈非线性关系。这意味着电视 GRP 的增长与销售额的增长不成正比。我将在下一节中更详细地讨论这一点。

回归分析生成的 betas 有助于量化每个输入的影响。基本上,beta 表示投入值增加一个单位将增加 Beta 单位的销售额/利润,同时保持其他营销投入不变。

Sales Equation

2。 线性和非线性影响的预测因子:

某些变量与销售额呈线性关系。这意味着随着我们增加这些投入,销售额将持续增长。但是像电视 GRP 这样的变量对销售没有线性影响。电视 grp 的增加只会在一定程度上增加销售额。一旦达到饱和点,GRP 的每一个增量单位对销售的影响都将减少。因此,对这种非线性变量进行一些转换,以便将它们包含在线性模型中。

电视 GRP 被认为是一个非线性变量,因为根据营销人员的说法,广告只会在一定程度上引起消费者的注意。超过某一点,增加广告曝光不会在顾客中产生任何进一步的增加的意识,因为他们已经知道该品牌。

因此,为了将 TV GRP 视为建模输入之一,将其转换为 adstock。

电视广告由两部分组成。

a. 收益递减:电视广告的基本原理是,电视广告的曝光在一定程度上在消费者的头脑中创造了意识。除此之外,随着时间的推移,接触广告的影响开始减弱。GRP 的每一个增量对销售或认知度的影响都会降低。因此,增量 GRP 产生的销售额开始减少并保持不变。从上图中可以看出这种影响,其中电视 GRP 和销售额之间的关系是非线性的。这种类型的关系可以通过计算 GRP 的指数或对数来获得。

b. 结转效应或衰减效应:过去的广告对现在销售的影响被称为结转效应。一个称为 lambda 的小部分乘以上个月的 GRP 值。这一部分也被称为衰减效应,因为前几个月的广告影响会随着时间的推移而衰减。

3。 基础销售和增量销售:

在市场组合建模中,销售分为两个部分:

a .基础销售额:基础销售额是营销人员不做任何广告而得到的。这是多年来建立的品牌资产带来的销售额。基本销售额通常是固定的,除非经济或环境因素发生变化。

b .增量销售:电视广告、*面广告、数字消费、促销等营销活动产生的销售。总增量销售额被分割成每个输入的销售额,以计算对总销售额的贡献。

4。 贡献图表:

贡献图是表示每项营销投入的销售额的最简单方法。每个营销投入的贡献是其 beta 系数和投入值的乘积。

例如:报纸贡献= β*报纸支出

为了计算贡献率%,将每个投入的贡献率除以总贡献率。我将在 MMM 101 第 2 部分详细阐述贡献图的解释。

5。 深潜

MMM 结果可进一步用于执行深潜分析。通过深入了解哪些活动或创意比其他活动或创意更有效,可以评估每个活动的效果。它可以用于按类型、语言、渠道等对创意进行复制分析。

从深潜中获得的洞察力被考虑用于预算优化。资金从低绩效渠道或类型转移到高绩效渠道/类型,以增加整体销售或市场份额。

6。 预算优化

对于任何企业来说,预算优化都是出于规划目的而采取的关键决策之一。

MMM 有助于营销人员优化未来支出和最大化效益。使用 MMM 方法,可以确定哪些介质比其他介质效果更好。然后,完成预算分配,将资金从低投资回报率媒介转移到高投资回报率媒介,从而在保持预算不变的同时最大限度地提高销售额。

各位,这是一个关于市场组合建模的简介。

请继续关注 MMM 上的更多文章。

如果你喜欢我的文章,给它一些掌声,或者更好地与你的朋友或同事分享。

页(page 的缩写)最*,很多人问我是否做市场组合建模/营销分析方面的咨询。

答案是肯定的。您可以将您的咨询问题发送到 https://www.arymalabs.com/的

领英:https://www.linkedin.com/in/ridhima-kumar7/

版权所有 2019 www.arymalabs.com 保留所有权利。

Python 中的马尔可夫链蒙特卡罗

原文:https://towardsdatascience.com/markov-chain-monte-carlo-in-python-44f7e609be98?source=collection_archive---------0-----------------------

一个完整的现实世界实现

在过去的几个月里,我在数据科学世界里反复遇到一个术语:马尔可夫链蒙特卡罗。在我的研究实验室里,在播客里,在文章里,每当我听到这个短语时,我都会点头,认为这听起来很酷,只是模糊地知道任何人在谈论什么。有几次我试图学习 MCMC 和贝叶斯推理,但每次我开始阅读这些书籍时,我很快就放弃了。恼怒之下,我求助于学习任何新技能的最佳方法:将它应用于一个问题。

利用我一直想探索的一些睡眠数据和一本基于实践应用的书(黑客贝叶斯方法、网上免费提供),我终于通过一个现实世界的项目学会了马尔可夫链蒙特卡罗。和往常一样,当我把技术概念应用到问题中时,理解它们比把它们作为纸上的抽象概念阅读要容易得多(也更令人愉快)。这篇文章介绍了用 Python 实现马尔可夫链蒙特卡罗,最终教会了我这个强大的建模和分析工具。

这个项目的全部代码和数据在 GitHub 上。我鼓励任何人看一看并将其用于自己的数据。这篇文章的重点是应用和结果,所以有很多高层次的主题,但我试图为那些想了解更多的人提供链接!

简介

我的 Garmin Vivosmart 手表根据心率和运动跟踪我何时入睡和醒来。它不是 100%准确,但真实世界的数据从来都不是完美的,我们仍然可以通过正确的模型从嘈杂的数据中提取有用的知识!

Typical Sleep Data

这个项目的目标是使用睡眠数据创建一个模型,该模型将睡眠的后验概率指定为时间的函数。由于时间是一个连续变量,指定整个后验分布是困难的,我们转向*似分布的方法,如马尔可夫链蒙特卡罗(MCMC)。

选择概率分布

在我们开始使用 MCMC 之前,我们需要确定一个合适的函数来模拟睡眠的后验概率分布。做到这一点的一个简单方法是目视检查数据。我入睡时的观察结果作为时间的函数如下所示。

Sleeping Data

每个数据点表示为一个点,点的强度表示特定时间的观察次数。我的手表只记录我入睡的那一分钟,所以为了扩展数据,我在精确时间的两边的每一分钟都加上了点。如果我的手表显示我在晚上 10:05 睡着了,那么之前的每一分钟都表示为 0(醒着),之后的每一分钟都得到 1(睡着了)。这将大约 60 个晚上的观察扩展为 11340 个数据点。

我们可以看到,我倾向于在晚上 10:00 后入睡,但我们希望创建一个模型,以概率的形式捕捉从清醒到入睡的过渡。我们可以为我们的模型使用一个简单的阶跃函数,它在一个精确的时间从清醒(0)变为睡眠(1),但是这并不代表数据中的不确定性。我不是每晚都在同一时间睡觉,我们需要一个函数来模拟一个渐进的过渡过程,以显示可变性。给定数据的最佳选择是在 0 和 1 之间*滑过渡的逻辑函数。以下是睡眠概率随时间变化的逻辑方程

这里,β (beta)和α (alpha)是我们在 MCMC 期间必须学习的模型参数。具有不同参数的逻辑函数如下所示。

逻辑函数符合数据,因为睡着的概率逐渐变化,捕捉到我睡眠模式的可变性。我们希望能够在函数中插入一个时间 t,并得出睡眠的概率,它必须在 0 和 1 之间。我们可以得到一个概率,而不是对问题“我晚上 10:00 睡着了吗”的直接回答是或否。为了创建这一模型,我们使用数据,通过一种称为马尔可夫链蒙特卡罗的技术,找到最佳的α和β参数。

马尔可夫链蒙特卡罗

马尔可夫链蒙特卡罗是指一类从概率分布中进行抽样的方法,以构建最可能分布。我们不能直接计算逻辑分布,因此我们为函数的参数(α和β)生成数千个值(称为样本),以创建分布的*似值。MCMC 背后的想法是,随着我们产生更多的样本,我们的*似值越来越接*实际的真实分布。

马尔可夫链蒙特卡罗方法有两个部分。蒙特卡洛是指利用重复随机样本获得数值答案的通用技术。蒙特卡洛可以被认为是进行许多实验,每次改变模型中的变量并观察反应。通过选择随机值,我们可以探索参数空间的大部分,变量的可能值的范围。下面显示了使用变量的正态先验的问题的参数空间(稍后将详细介绍)。

显然,我们无法尝试这些图中的每一个点,但通过从高概率区域(红色)随机取样,我们可以为我们的问题创建最可能的模型。

马尔可夫链

一个马尔可夫链是一个下一个状态只依赖于当前状态的过程。(该上下文中的状态指的是给参数赋值)。马尔可夫链是无记忆的,因为只有当前状态是重要的,而不是它是如何到达那个状态的。如果这有点难以理解,考虑一个日常现象,天气。如果我们想预测明天的天气,只需利用今天的天气就可以得到合理的估计。如果今天下雪,我们会查看显示下雪后一天天气分布的历史数据,以估计明天天气的可能性。马尔可夫链的概念是,我们不需要知道一个过程的整个历史来预测下一个输出,这是一种在许多现实世界情况下都适用的*似方法。

将马尔可夫链和蒙特卡罗的思想结合在一起,MCMC 是一种基于当前值重复绘制分布参数的随机值的方法。值的每个样本都是随机的,但是值的选择受到当前状态和假设的参数先验分布的限制。MCMC 可以被认为是逐渐收敛到真实分布的随机游走。

为了得出α和β的随机值,我们需要假设这些值的先验分布。由于我们事先没有关于参数的假设,我们可以使用正态分布。正态或高斯分布由*均值和方差定义,前者显示数据的位置,后者显示分布。具有不同*均值和分布的几种正态分布如下:

我们正在使用的特定 MCMC 算法被称为 Metropolis Hastings 。为了将我们观察到的数据与模型联系起来,每次绘制一组随机值时,算法都会根据数据对它们进行评估。如果它们与数据不一致(我在这里做了一点简化),这些值将被拒绝,模型将保持当前状态。如果随机值与数据一致,则这些值被分配给参数并成为当前状态。这个过程持续特定数量的步骤,模型的精度随着步骤数量的增加而提高。

综上所述,在我们的问题中,马尔可夫链蒙特卡罗的基本过程如下:

  1. 为逻辑函数的参数α和β选择一组初始值。
  2. 根据当前状态,为 alpha 和 beta 随机分配新值。
  3. 检查新的随机值是否与观察值一致。如果没有,则拒绝这些值并返回到以前的状态。如果是,则接受这些值作为新的当前状态。
  4. 重复步骤 2 和 3,重复指定的迭代次数。

该算法返回它为 alpha 和 beta 生成的所有值。然后,我们可以使用这些值的*均值作为逻辑函数中α和β最可能的最终值。MCMC 不能返回“真实”值,而是*似的分布。给定数据的睡眠概率的最终模型将是具有α和β*均值的逻辑函数。

Python 实现

上面的细节在我脑海里过了很多遍,直到我用 Python 应用了它们!亲眼看到结果比阅读别人的描述更有帮助。为了用 Python 实现 MCMC,我们将使用 PyMC3 贝叶斯推理库。它抽象掉了大部分细节,使我们能够创建模型而不会迷失在理论中。

下面的代码用参数alphabeta、概率p和观察值observed创建完整的模型,step变量指的是特定的算法,sleep_trace保存模型生成的所有参数值。

(查看笔记本中的完整代码)

为了了解运行这段代码时会发生什么,我们可以查看模型运行期间生成的所有 alpha 和 beta 值。

这些被称为跟踪图。我们可以看到,每个状态都与之前的状态相关,即马尔可夫链,但值会显著振荡,即蒙特卡洛采样。

在 MCMC 中,通常会丢弃高达 90%的轨迹。该算法不会立即收敛到真实分布,并且初始值通常不准确。参数的后期值通常更好,这意味着我们应该使用它们来构建我们的模型。我们使用了 10000 个样本,并丢弃了前 50%,但一个行业应用可能会使用数十万或数百万个样本。

给定足够的步骤,MCMC 收敛到真实值,但是评估收敛性可能是困难的。我不会在这篇文章中讨论这个话题(一种方法是测量轨迹的自相关),但如果我们想要最精确的结果,这是一个重要的考虑因素。PyMC3 内置了评估模型质量的函数,包括轨迹和自相关图。

pm.traceplot(sleep_trace, ['alpha', 'beta'])
pm.autocorrplot(sleep_trace, ['alpha', 'beta'])

Trace (left) and autocorrelation (right) plots

睡眠模式

最终构建并运行模型后,就该使用结果了。我们将最后 5000 个α和β样本的*均值作为参数的最可能值,这允许我们创建模拟后验睡眠概率的单一曲线:

该模型很好地表示了数据。此外,它还捕捉到了我睡眠模式中固有的可变性。这个模型给了我们一个概率,而不是一个简单的是或否的答案。例如,我们可以查询模型以找出在给定时间我睡着的概率,并找出睡着的概率超过 50%的时间:

**9:30  PM probability of being asleep: 4.80%.
10:00 PM probability of being asleep: 27.44%.
10:30 PM probability of being asleep: 73.91%.****The probability of sleep increases to above 50% at 10:14 PM.**

虽然我试着在晚上 10:00 上床睡觉,但很明显大多数晚上都不会这样!我们可以看到我睡觉的*均时间是晚上 10:14 左右。

这些值是给定数据的最可能的估计值。但是,这些概率存在不确定性,因为模型是*似的。为了表示这种不确定性,我们可以使用所有α和β样本而不是*均值来预测给定时间的睡眠概率,然后绘制结果的直方图。

这些结果更好地说明了 MCMC 模型真正的作用。该方法不会找到单一答案,而是可能值的样本。贝叶斯推理在现实世界中很有用,因为它用概率来表达预测。我们可以说有一个最可能的答案,但更准确的回答是任何预测都有一个取值范围。

尾流模型

我可以利用清醒时的数据为我早上醒来时找到一个相似的模型。我试着总是在早上 6:00 起床,但是我们可以看到这并不总是发生!下图显示了从睡眠到清醒的过渡的最终模型以及观察结果。

我们可以查询这个模型,找出我在给定时间睡着的概率,以及我最有可能醒来的时间。

**Probability of being awake at 5:30 AM: 14.10%. 
Probability of being awake at 6:00 AM: 37.94%. 
Probability of being awake at 6:30 AM: 69.49%.****The probability of being awake passes 50% at 6:11 AM.**

看来我得好好修理一下那个警报器了!

睡眠持续时间

我想创建的最后一个模型——出于好奇和实践——是我的睡眠时间。首先,我们需要找到一个函数来模拟数据的分布。提前,我觉得会很正常,但是我们只能通过检查数据来发现!

正态分布可以工作,但是它不能捕捉到右边的外围点(我严重睡过头的时候)。我们可以使用两个独立的正态分布来表示这两种模式,但我将使用一个偏态正态分布。偏斜正态有三个参数:均值、方差和α,即偏斜度。所有这三个都必须从 MCMC 算法中学习。以下代码创建模型并实现 Metropolis Hastings 采样。

现在,我们可以使用三个参数的*均值来构建最可能的分布。下面是数据顶部的最终偏态正态分布。

看起来很合身!我们可以查询该模型,以找到我至少获得一定量睡眠的可能性以及最可能的睡眠持续时间:

**Probability of at least 6.5 hours of sleep = 99.16%.
Probability of at least 8.0 hours of sleep = 44.53%.
Probability of at least 9.0 hours of sleep = 10.94%.****The most likely duration of sleep is 7.67 hours.**

我对那些结果并不完全满意,但是作为一名研究生你能期待什么呢?

结论

完成这个项目再一次向我展示了解决问题的重要性,最好是有现实应用的问题!在使用马尔可夫链蒙特卡罗构建贝叶斯推理的端到端实现的过程中,我学到了许多基础知识,并在这个过程中乐在其中。我不仅了解了一点我的习惯(以及我需要改进的地方),现在我终于可以理解大家说的 MCMC 和贝叶斯推断是什么了。数据科学就是不断地向您的技能库中添加工具,而最有效的方法就是找到问题并开始行动!

一如既往,我欢迎反馈和建设性的批评。可以通过推特 @koehrsen_will 联系到我。

马尔可夫链——对生活的一种理解

原文:https://towardsdatascience.com/markov-chains-a-take-on-life-35614859c99c?source=collection_archive---------0-----------------------

给定现在,未来独立于过去

在我最*上的另一堂课的第 24 张幻灯片中,有一句看似无关紧要的话,却完全揭示了我们是如何思考和行动的(至少我是这样思考和行动的)。在我开始之前,让我给你简单介绍一下我是如何偶然发现这句话的。我还将冒昧地提供一个小窥视模型的工作原理,其标语可能价值数百万美元。

最*我开始看这些关于强化学习的讲座,由谷歌 deep mindalpha go 团队的首席程序员大卫·西尔弗主讲。对于外行人来说,强化学习是机器学习的一个子领域,它处理基于代理人收到的奖励做出决策的过程。请允许我更清楚地说明这一点:代理人可以实现的任何目标都可以用期望累积报酬的最大化来描述。通俗地说,如果一个代理想要完成它的目标,那么与它为达到目标所采取的行动相关的回报将会最大化。

An example of RL for the robot agent. Image from Safaribooksonline

举个例子,考虑让一个人形机器人学会走路的过程;正奖励可能由机器人到达目的地(或在目的地的方向上迈出每一步)构成,而负奖励可能与机器人摔倒的动作相关联,或采取使其远离目标的动作相关联(这是一个天真的例子,因为如果机器人正在探索更好的全局路径以达到目标,则它可能实际上在远离目标时获得正奖励)。正是通过这些积极和消极奖励的结合,机器人最终学会了如何到达它的潜在目的地。

这种过程可以很容易地通过代理人处于某个状态,并通过考虑所有立即可获得的未来状态的回报并朝着回报最大的状态移动而采取行动来可视化(是的,这听起来有点不真实,但相信我这不是)。不难分析,一个贪婪的代理人会采取一种行动,这种行动对应于从当前状态可能获得的最高回报。

马尔可夫链是强化学习的支柱,因为它们以一种非常简单的方式帮助建立决策的概念;代理已经处于的状态的整个序列可以归结为它的当前状态,即,下一个可到达的状态可以由代理的当前状态来预测,而不管代理已经处于的状态的历史序列。下图简洁地说明了这个想法:

A simple Markov Model

边上的标签表示从当前状态移动到下一个状态的概率。例如,如果今天下雨,明天下雪的概率是 0.02,下雨的概率是 0.8 等等。

另一个解释马尔可夫链的简单例子是:假设你正在访问一个群岛,有桥连接着这些岛屿。这些桥代表了从一个岛移动到另一个岛的可能性。你明天要去的岛是由你今天所在的岛决定的,你以前的职位与这个决定无关。

对于面向数学的,马尔可夫模型的公式可以描述为:

一个状态 S_t+1马尔可夫当且仅当(原谅没有下标) :

解释:在给定代理处于[RHS]的整个状态序列的情况下,移动到下一个状态的概率等于在给定当前状态[LHS]的情况下,移动到下一个状态的概率。换句话说,由于过去状态的所有信息已经浓缩在代理的当前状态中,我们可以假设从当前状态到下一个状态的转移概率完全取决于当前状态。

这也可以表述为:

鉴于现在,未来独立于过去。

正是第一堂课幻灯片中的这一行,让我意识到这句话不仅适用于马尔可夫模型,也适用于我们所有人的生活。塑造我们未来的决定完全取决于我们在当前心态下做出的选择;我们过去的所有经历都隐含在我们现在的状态中,因为它们引导我们走到了今天。

对过去的选择感到遗憾不会改变宇宙中事情将如何发展的更大计划,哀叹只会让我们付出代价,并模糊我们未来的决策过程。所以,让我们试着通过充分利用我们此刻所处的状态来放下过去。

让我们通过分析给定我们当前情况下所有可能行动的回报,来模拟一个理性主体做出最优决策。还有什么比人类一直做出理性决策更好的 AI,我说的对吗!;-)

漫威电影宇宙超级英雄排名:表情可视化

原文:https://towardsdatascience.com/marvel-cinematic-universe-exploratory-data-analysis-an-emoji-visualisation-of-superhero-powers-e815821066d4?source=collection_archive---------11-----------------------

我和其他人一样喜欢好的超级英雄电影。动作场面真正构成了这些电影的大部分。

Photo by Raj Eiamworakul on Unsplash

没有超能力的超级英雄算什么?

有两个主要的超级英雄电影系列:漫威电影宇宙(MCU)和 DC 扩展宇宙(DC 扩展宇宙)。可以说, MCU 正在赢得票房和整体营销游戏。另外,我喜欢《死侍》,我为惊奇队长感到非常兴奋。因此,尽管我欣赏黑暗和坚韧不拔的 DC 扩展宇宙风格,单片机是我目前的最爱。

当我看 MCU 电影,尤其是复仇者联盟电影时,有一个问题一直困扰着我——谁是最强大的 MCU 超级英雄?

当超级英雄面对灭霸时,基于性格和力量的分析并没有太大意义。力量胜过一切,所以最好的超级英雄也应该是最强大的超级英雄。但更大的问题是——权力的数量重要还是权力的类型更重要?

我们来看数据。

一.数据

这个分析使用了上传到 Kaggle 上的超级英雄数据集。这是分析和可视化的代码。数据是 2017 年 7 月从超级英雄 DB 刮来的。这项分析将超级英雄的力量列为 20 个最受欢迎的 MCU 超级英雄之一。我已经使用这篇文章作为参考排名,看看我是否可以根据数据提出一个替代方案。文章从最好到最差对以下 18 位超级英雄进行了排名:

  1. 美国队长
  2. 黑豹
  3. 托尔
  4. 奇异博士
  5. 绿巨人
  6. 蚁人
  7. 瓦尔基里
  8. 视力
  9. 冬季士兵
  10. 猎鹰
  11. 绯红女巫
  12. 蜘蛛侠
  13. 星际领主
  14. 黑寡妇
  15. 战争机器
  16. 鹰眼
  17. 钢铁侠

这份分析中的排名包括了文章中的全部 18 位以及死池和惊奇队长。

二。分析

1.能力

本文中的 20 个超级英雄总共拥有 46 种不同的能力。权力具有以下特征:

  1. 每种能力都有一个奖励点
  2. 他们可能是“极端的”

奖励积分

永生的奖励点数最高,智力和反应能力的奖励点数最低。超级英雄的标准绝对很高,因此我更爱他们。

极端权力

有更少的极端力量,这很好,因为不是所有的超级英雄都是*等的。我的猜测是,拥有最极端力量的超级英雄在战斗中会比那些拥有较少极端力量的超级英雄做得更好。

2.超级英雄和他们的力量

幂的数量

惊奇队长拥有迄今为止最多的权力…

…但是在拥有“极端”力量的超级英雄中,奇异博士拥有最多的“极端”力量。惊奇队长跌至第三,钢铁侠跌至第六。

我们看到钢铁侠在《无限战争》中被摧毁,而雷神继续战斗,所以我同意极端力量比任何力量都重要的假设。

3.超级英雄和奖励积分

每种威能都有加分。如果极端力量是最好的力量,他们应该有更多的加分。让我们来看看极端与非极端奖金点四分位数。

超能力者比非超能力者得分更多。我相信分数是超级英雄整体实力的排名方式。

三。最终排名

从最好到最差,以下超级英雄根据与其能力相关的奖励点数总数进行排名(括号内为参考文章排名):

  1. 《惊奇队长》
  2. 雷神(#3)
  3. 奇异博士(排名第四)
  4. 《死侍》
  5. 猩红女巫(#11)
  6. 钢铁侠(#17)
  7. 战争机器(#15)
  8. 绿巨人(#5)
  9. 水银(#18)
  10. 愿景(#8)
  11. 蜘蛛侠(#12)
  12. 黑豹(排名第二)
  13. 美国队长(#1)
  14. 黑寡妇(第 14 位)
  15. 星际领主(#13)
  16. 鹰眼(#16)
  17. 猎鹰(#10)
  18. 冬日战士(#9)
  19. 瓦尔基里(排名第七)
  20. 蚁人(排名第六)

索尔和奇异博士各上升一位,而《美国队长》和《黑豹》则下降了。

这主要是因为如果一个超级英雄主要拥有像“智力”和“敏捷”这样的无用能力,那么大量的能力并不意味着什么。

此外,在下面的情节中,很明显,像雷神这样的超级英雄与其他 19 个超级英雄相比,只拥有*均数量的力量,但在战斗中,wayyy 比其他人更强大。

令人惊讶的是,浩克的排名在《战争机器》之后。这是因为虽然他们都有相同数量的极端力量,战争机器有更多的力量。所以,极端的权力比简单的更多权力要好。但是如果极端力量相等,拥有更多力量的超级英雄获胜。

四。结论

很多人都在谈论惊奇队长是迄今为止最强的复仇者。虽然根据这个排名这是真的,但如果超级英雄是根据他们的力量值来评分的话,惊奇队长并不比雷神强大多少。但最终,只有当他们面对灭霸时,我们才会知道谁是最强的复仇者。

了不起的女人

原文:https://towardsdatascience.com/marvelous-women-b9a64745fe3b?source=collection_archive---------6-----------------------

关于漫威妇女的机器学习案例研究

权力是个有趣的东西。当考虑谁是特定漫画世界中最强大的时候,我们通常会想到原始力量、神秘能力或宇宙能量。大多数时候,我们在这些对话中也会想到男人。但是,正如我们都逐渐认识到的那样,有许多不同种类的权力和许多不同形式的赋权。

漫威宇宙一直是一个让不可能成为可能的地方,在这里,力量以无数种形式出现,并被用于无数不同的目的。但是我们不要忘记,在一个充满无敌铁人和幻想先生的世界里,616 中一些最强大的生物是女性。

当漫威在 20 世纪 70 年代迅速扩张时,女性超级英雄往往是事后诸葛亮,被冷嘲热讽地创造为品牌延伸:蜘蛛侠诞生了蜘蛛侠,绿巨人诞生了女巨人,等等。

畅销书漫威漫画:不为人知的故事的作者肖恩·豪说:“这是亚当的肋骨效应。“这不仅仅是因为这些角色没有男性角色考虑周全;他们实际上是从他们受欢迎的财产中获得的。”

事实上,一场地震剧变正在发生。新的 Thor(是的,你必须叫她 Thor)比她的前任多卖了 30%——她的公司也不错。三年前,作家凯莉·苏·德康尼克将前漫威女士卡罗尔·丹弗斯提升为惊奇队长,她的冒险经历吸引了一批忠实的粉丝,他们被称为卡罗尔军团。查尔斯·索尔在一个机智的系列中重塑了她,探索了她作为律师的日常工作。最重要的是,有 G Willow Wilson 的新漫威女士,一个叫 Kamala Khan 的 16 岁巴基斯坦裔美国穆斯林。这本书已经成为一种文化现象,被 CNN、《纽约时报》和《科尔伯特报告》报道,并受到旧金山反伊斯兰恐惧症运动者的欢迎,他们在反穆斯林的公交车广告上贴满了卡玛拉贴纸。威尔逊目前正在与玛格丽特·贝内特(Marguerite Bennett)合写一本全女性的《复仇者联盟》(A-Force)。

The A-Force. Courtesy of Marvel.

Ms. Marvel Issue #1. Courtesy of Marvel.

与此同时,漫威的竞争对手 DC Comics 更新了老女性角色,如蝙蝠女侠、蝙蝠女侠、猫女、神奇女侠和有争议的反英雄哈利·奎因。在传统上更加进步的独立漫画世界中,有各种各样的热门系列,如《传奇》、《老鼠皇后》、《伐木工人》和《恶人+神》。

现在超级英雄接管了夏季票房,漫画中发生的事情对主流文化产生了重大影响。这些都是孩子成长过程中的特征。最*几部电影的大男子主义阵容(自 10 年前《猫女》和《埃莱克特拉》失败以来,没有女性主演过漫画电影)使这种类型的电影看起来永远是男性的,但华纳兄弟制作了 DC 原创的女权主义犯罪斗士神奇女侠的精彩展示(如此精彩,我已经看过六遍),而漫威已经计划在 2018 年上映一部惊奇队长电影。也有新的电视节目致力于美国队长的战时同事佩吉·卡特,超能力私人侦探杰西卡·琼斯和超女。

变化的速度甚至让编剧们感到惊讶。Wilson 是一名穆斯林皈依者,他记得当《漫威》的编辑 Sana Amanat 和 Stephen Wacker 找到她要写《漫威女士》时。“[他们说:‘我们想创造一个新的青少年女性美国穆斯林超级英雄,让她出现在自己的书里。’]我想,‘你疯了。你需要雇一个实习生来打开恐吓信。所以当突然之间,每个人都在谈论它的时候,我惊呆了。我相信,如果我们在五年前尝试做完全相同的书,反应会非常不同。它出现在美国漫画史上一个非常特殊的时期。"

惊人的数据

我被迫使用我的编码能力来分解漫威宇宙中的英雄形象,看看这个宇宙是否反映了美国漫画的这种变化。我不仅想按性别,还想按种族、教育程度等来划分代表性。我从漫威的 API 中收集了所有漫威角色的数据。他们的数据库包括 1402 个角色,包括英雄、反派和团队!在把所有的东西汇编成一个数据框架后,我了解到这个数据集包括了 89 个不同的栏目,包括他们的国籍、教育程度、头发颜色、眼睛颜色等等。

像在任何数据集中一样,在某个地方总会有空数据,所以我不得不做更多的清理工作。重新整理数据后,我只剩下 1332 个字符。

为了避免进一步的问题,我去掉了那些没有信息的字符。科学家喜欢拥有大量的数据,这样他们就可以做大量的实验,并得到尽可能准确的结论。但是,经验告诉我们,大多数时候我们无法通过大数据来进行机器学习。我从数据中选择了以下几列:id、姓名、描述、教育、体重、身高、简历、头发颜色、眼睛颜色、国籍和出生地。我只剩下 762 个字符。

'wiki.hair', 'wiki.weight', 'wiki.height', 'wiki.eyes', 'wiki.place_of_birth', 'wiki.education', 'wiki.citizenship', 'wiki.occupation', 'wiki.bio', 'wiki.bio_text', 'wiki.categories', 'name', 'comics.available'

它们可能会提供有用信息,而且它们似乎比我试图使用的其他工具拥有更多的可用数据。

以下是新数据框的一些照片:

First 5 entries of physical data and cultural data

Summaries of physical data and cultural data

基于此,漫威超级英雄的原型是一个来自美国的黑头发、蓝眼睛的冒险家。

有一些有趣的信息。我决定检查一下,看看是否能找到任何女性或非白人的角色——像奈克拉、漫威女士等。原来他们确实有性别分类,也有从属分类(英雄或恶棍),团队分类,等等,但是没有肤色分类。我认为在 API 中性别不是它自己的属性很有趣,但是这是一个开始。为了更好地理解这些信息,我用数据创建了两个新列。

  • 女人:如果角色是女人,则为真,否则为假
  • 恶棍:如果角色是恶棍,则为真,否则为假

经过更多的整形后,我了解到有 199 名女性和 563 名男性识别为男性或女性(我确实用最初的 1402 名进行了复查)。这些女性角色占数据框的 26%(类似于我学校的比例)

如果我们把他们分成英雄和恶棍,有 362 个男英雄,201 个男恶棍,169 个女英雄,30 个女恶棍。

Created with matplotlib

奇妙的机器学习

由于新的女性角色正在崛起,我创建了一个 knn 模型来预测漫威世界的趋势,重点是身体属性和教育。我关注的是身高和体重,因为这两个类别的 NaN 最少。

物理性质

有成群的男人和女人表明他们保持了现实的比例。然而,男性的体重在 150 到 500 磅之间,而女性的最高体重在 250 磅左右。男性角色有更多的身高和体重异常值,而大多数女性角色坚持更现实的比例。

Scatterplot of height (in.) and weight (lbs) between male and female characters

根据训练模型及其数据,下面的散点图预测漫威女性将坚持现实比例。它甚至开始消除男性和女性角色中的异常值,因为有些人重达 1000 磅:

ML vis of height (in.) and weight (lbs) between male and female characters

公民权和教育

那里有很多不同的教育背景,但看到我从我最喜欢的漫威角色中认出的那些是很有趣的!每种教育背景都有,从像 She-Hulk 一样获得 Berkely 的通信学位,到像 Loa 和新的漫威女士这样的高中水*课程,从像螳螂这样的帕马牧师的培训,到像 Meggan 这样通过电视自学,我将他们分为 9 个不同的类别:大学,基础(小学到中学),辅导,高级(研究生学位),军事,特殊(非传统学校环境),未完成,和自学。

第一张图表显示了基于国籍的人物教育水*。标记越不透明,越多的字符接受这种形式的教育。纵观国际角色,很少有角色完成了大学学业,接受了特殊教育,也没有自学成才。然而,在美国,很少有女性完成本科学业,然而更多的女性获得了博士后学位。

Chart showing the education levels of the characters

根据培训模型及其数据,更多的非美国公民漫威女性更有可能获得本科学位、参军、持有高中文凭或接受某种形式的特殊教育。然而,美国公民更有可能拥有高中文凭或接受过某种形式的基础教育。

Chart showing the trends in education based on citizenship

结论

输入两个模型的角色和故事池预测,非美国女性角色更有可能获得高等教育学位,或更有可能获得小学和中学以外的任何其他形式的教育,所有女性角色都可能保持现实的比例。这些预测的结果反映了我们所认为的漫画故事的行业模式:关于富有冒险精神的黑头发、蓝眼睛、受过良好教育的美国男人的故事。

女性角色有潜力创造动态的故事,而不需要 gimickey 的表现。像漫威女士和惊奇队长这样的漫威人物的成功与身份政治没有什么关系,一切都与伟大的故事讲述有关。然而,新的漫威女士是一个普通的青少年,正在与父母和学校以及超级大国的责任进行斗争,这本身仍然很有共鸣。

威尔逊说:“我们不想要一本模范的少数民族书籍,它的全部目的是四处走动,展示在美国的南亚穆斯林是什么样子的。”。"卡玛拉的旅程与任何曾经是青少年的人都有关联。"

这些漫画远非说教,而是以脱离黑发蓝眼冒险家模式的英雄女主角为特色,体现了漫威的一些基本原则。在 20 世纪 60 年代,像蜘蛛侠这样的超级英雄拥有丰富的、不受束缚的生活,有金钱的烦恼和浪漫的焦虑,这让 DC 的超人和蝙蝠侠相形见绌。当神秘的 x 战警在 80 年代初成为一种现象时,克里斯·克雷蒙用反变异的偏执来比喻种族主义和同性恋恐惧症。这些英雄都有不同的感受。几十年后,引入更多的 LGBT 角色和有色人种的超级英雄才有叙事意义。因为超级英雄漫画行业很大程度上依赖于不断重塑几十年前创造的人物,所以它在反映社会变化方面处于独特的有利地位。

“有一点追赶正在进行中,”豪说。“然而,当你看到像《漫威女士》这样的作品时,你会发现漫画也能提升人们超越现状的态度。我很高兴漫威电影没有在漫威漫画充斥着丰胸缩臀的时代找到自己最大的成功。”

“人们在寻找新的故事,”威尔逊说。“像漫威女士这样的书已经改变了工业数学。他们已经改变了女性角色不卖,少数民族角色不卖,新角色不卖的行业教条。我认为这将改变所有层面的思维。我真的很想知道接下来会发生什么。”

上面的结果可能表明,但从绿巨人到漫威女士和新的女性雷神,新一代的英雄正在彻底改变漫画世界,并将性别化的刻板印象历史化。就像威尔逊一样,我很期待接下来会发生什么。

该项目的代码和数据可以在 这里 找到。

掌握文本分析技巧并取得成功

原文:https://towardsdatascience.com/master-the-skill-of-text-analytics-and-be-successful-87ad4a7dfcb0?source=collection_archive---------4-----------------------

介绍

如果您像我们一样在分析或数据科学领域工作,您会熟悉这样一个事实,即数据以令人难以置信的速度到达,数据科学家和分析师接受过处理最具数值性和分类性的表格数据的培训。但是今天,大部分可用的业务数据是非结构化的,并且是大量文本,例如书籍、文章、网站文本、博客帖子、社交媒体帖子等。公司高管制定重要的业务规则,主要是基于潜在客户、客户和合作伙伴提供的自由格式文本字段中的关键字和短语的使用,以及它们的使用频率和彼此之间的接*度。这是我们的梦想和噩梦:可能有太多的数据要处理。

这就是为什么我们写了这篇关于文本分析的文章,来帮助你跟上将文本转化为数字的速度,并实现一些常见的文本挖掘技术。最终,我们希望您能够将强大的算法应用到您组织的大型文档文本数据库中。

Hacker News 是我们最喜欢的网站之一,用来了解技术和创业新闻,但是浏览这个简约的网站有时会很乏味。因此,我在这篇文章中的计划是尽可能以非技术性的方式向您介绍如何分析这个社交新闻网站,并展示一些初步结果,以及一些关于我们下一步将如何发展的想法。

我下载的黑客新闻数据集包含了从 2013 年 9 月到 2017 年 6 月的一百万篇黑客新闻文章标题。

首先,让我们看看黑客新闻标题中最常见的词的可视化。

一些初步的简单探索

Figure 1

图 1 显示了 2013 年 9 月至 2017 年 6 月黑客新闻标题上出现频率最高的词。

在很大程度上,我们认为这是黑客新闻标题中一个相当标准的常用词列表。最上面的词是“hn”,因为“问 hn”、“秀 hn”是社交新闻网站结构的一部分。“google”、“data”、“app”、“web”、“startup”等等出现频率第二高的词,对于一个像黑客新闻这样的社交新闻网站来说,都在我们的预期之内。

如何将这种方法应用到您的业务中?如果您正在对客户故障单进行故障诊断,而不必通读成千上万的故障单,您希望能够搜索故障单特定字段中有计数的常用单词或短语。

简单的情感分析

让我们来谈谈情感分析这个话题。情感分析根据积极或消极来检测文本主体的情感。当使用时,特别是在大规模使用时,它可以向你展示人们对你重要的话题的感受——特别是你的品牌和产品。

我们可以分析对每种情绪有贡献的字数。从黑客新闻文章中,我们发现每个单词对每个情绪有多大的贡献。

Figure 2

马上,我们在这里发现了一些问题,“cloud”和“slack”被我使用的词典归类为否定词。实际上,“云”是“云计算”的意思,“slack”是黑客新闻上下文中的软件公司。因此,我们的领域知识开始发挥作用,并有助于在这种情况下做出最终判断。

Word cloud 是识别趋势和模式的好主意,否则这些趋势和模式在表格格式中是不清楚或难以看到的。我们还可以比较词云中最常见的正面词和负面词。

Figure 3

如何将这种方法应用到您的业务中?客户支持工作的核心是客户的幸福。自然,你希望他们喜欢你的产品或服务。无论您是在分析反馈表格、聊天记录、电子邮件还是社交媒体,情绪分析都将帮助您听到客户的真实声音,以及他们对您的产品或服务的感受。

词语之间的关系

我们经常想了解文档中单词之间的关系。文本中有哪些常见的单词序列?给定一个单词序列,接下来最有可能是哪个单词?哪些词之间的关系最强?因此,许多有趣的文本分析都是基于这些关系。当我们检查两个连续单词对时,它通常被称为“二元模型”。

Figure 4

从图 4 中我们可以看到,黑客新闻数据中最常见的 bigram 的赢家去了“机器学习”,第二名是“硅谷”。

如何申请到你的企业?分析文本数据的挑战在于理解单词的意思。如果与“水”和“学习”相对,那么“深”就有不同的含义。因此,文本数据中单词计数的简单汇总可能会令人困惑,除非在没有假设独立的单词选择过程的情况下,分析将它与同样出现的其他单词相关联。

词汇网络

单词网络分析是一种对文本中单词之间的关系进行编码并构建链接单词网络的方法。这种技术基于这样一种假设,即语言和知识可以被建模为单词的网络以及它们之间的关系。

Figure 5

对于黑客新闻数据,如图 5 所示,我们可以可视化文本结构的一些细节。例如,我们可以看到组成常见短语的成对或三元组(“社交媒体网络”或“神经网络”)。

如何将这种方法应用到您的业务中?这种类型的网络分析主要是向我们展示文本中的重要名词,以及它们之间的关系。由此产生的图表可以用来获得文本的快速视觉摘要,阅读最相关的摘录。

我们认为文本分析是从客户关系管理中诞生的工具和方法。deepPiXEL 已经在将文本分析应用于组织的服务请求内容方面做了一些有益的研究。我们了解到文本分析是一个旅程,我们看到越来越多的组织转向文本分析,以便更长久地留住更多的客户。没有结构化调查数据能更好地预测客户行为以及客户文本评论和消息的实际声音!

我们希望这篇短文对您有所帮助。一旦组织有能力从文本分析中自动获得见解,他们就可以将见解转化为行动。

你在文本分析方面最著名的技巧是什么?请在下面的评论中与我们分享。

使用 OpenAI 的新“在深度 RL 中旋转”包掌握深度强化学习

原文:https://towardsdatascience.com/mastering-deep-reinforcement-learning-with-openais-new-spinning-up-in-deep-rl-package-b86b61ab6e54?source=collection_archive---------8-----------------------

OpenAI Five

强化学习 是一种机器学习方法,用于教会智能体如何通过试错来解决任务。 深度 强化学习 是指强化学习与深度学习的结合。

open ai于 2018 年 11 月 8 日在 Deep RL 发布了他们的深度强化学习教育包 。他们的发布声明似乎对我很有吸引力,其中写道:

“在open AI上,我们相信深度学习总体上——特别是深度强化学习——将在强大的人工智能技术的发展中发挥核心作用。虽然有许多资源可以让人们快速进入深度学习,但深度强化学习更具挑战性。我们设计了 Spinning Up 来帮助人们学习使用这些技术,并发展对它们的直觉。我们还看到,在 RL 中胜任可以帮助人们参与跨学科的研究领域,如【AI 安全 ,这涉及强化学习和其他技能的混合。很多人向我们寻求从头开始学习 RL 的指导,因此我们决定将我们提供的非正式建议正式化。”

Release tweet by OpenAI.

因此,我决定快速浏览整个包,这里有一个简短的游览和对那些希望浏览完整包的人的一点建议。

到底什么是'在深 RL 中向上旋转'

“我们观察到,如果为他们提供正确的指导和资源,对机器学习经验很少或没有经验的人来说,快速成为实践者是可能的。Deep RL 中的 Spinning Up 正是基于这一需求而构建的。”

在深 RL 包装中旋转的整体包括:

RL 简介:

用短视频和适度详细的短笔记简单介绍强化学习。涵盖的主题有 RL 、 RL 算法中的概念【策略优化简介* 。***

我发现对于初学者来说,整个学习材料有点难以理解。关于强化学习基础知识有什么疑问,可以随时参考大卫·西尔弗的 RL 课程 和讲座系列。

Deep-RL 研究论文:

这一领域的一些顶级研究论文是按主题排列的,进一步分为子主题。论文的整体安排是按照一个非常合适的顺序进行的,任何初学者都可以一篇接一篇地轻松阅读。

算法:

一些顶级算法,如普通策略梯度和深度确定性策略梯度,已经在这个包中实现并准备使用。它们都是用 MLP(非递归)演员-评论家实现的,使它们适合于完全观察的、非基于图像的 RL 环境。这些算法的完整文档可以在 这里 找到。

实验和环境:

各种实验和 OpenAI 环境都包含在这个包中。还为超参数调谐提供了一个实验网格。整个实验和环境的交互大部分可以通过命令行(Shell)来控制。

练习:

一旦你完成了教材中面向学习的内容,最后会有几个问题集来测试你的技能。值得注意的是,还有一个为 OpenAI 的长期研究请求做贡献的选项。**

其他实用程序:

记录器绘图仪这样的实用程序随软件包提供,以便更好地监控和研究实验的输出和结果。**

参考资料:

这里的 可以参考官方文档

这个包的 GitHub 库可以在 这里 找到。

建议:

这个包展示了高质量的学习内容,对你成为一个活跃的 RL 社区成员来说是绰绰有余的,主要是应用方面。但是对于强化学习和深度学习领域的初学者来说,其学习内容的许多部分(如研究论文和算法的实现)可能有点难以理解。在开始使用 OpenAI 的 Deep RL 包中的这个之前,最好至少对这些领域的一些基本概念有一点了解。**

我希望你能从 OpenAI 的这个惊人的资源中开始你的深度强化学习之旅。如果你想为 Deep RL 推荐任何其他同样好或更好的学习资源,欢迎在下面的评论中提出来。

强化学习背后的数学,简单的方法

原文:https://towardsdatascience.com/math-behind-reinforcement-learning-the-easy-way-1b7ed0c030f4?source=collection_archive---------2-----------------------

Photo by JESHOOTS.COM on Unsplash

更新:学习和练习强化学习的最佳方式是去http://rl-lab.com

看看这个等式:

Value function of Reinforcement Learning

如果它没有吓倒你,那么你是一个数学通,阅读这篇文章是没有意义的:)

这篇文章不是关于教授强化学习(RL)的,而是关于解释它背后的数学原理。因此,它假设你已经知道什么是 RL,但在理解数学方程时有一些困难。

如果你不知道 RL,你最好在回到本文之前阅读一下。

我们将一步一步地探究上述等式是如何以及为什么会出现的。

状态和奖励

让我们考虑一系列的国家 S1,S2,…,Sn 每个国家都有某种奖励 R1,R2,…,Rn。我们知道一个代理人(例如:机器人)的工作是最大化其总报酬。这意味着它将经过提供最大奖励的州。

假设代理人在 S1 州立大学,应该有办法让它知道什么是最大化其回报的最佳途径。考虑到代理人没有看到其紧邻国家以外的地方。

为此,除了每个状态 s 的奖励之外,我们还将存储另一个值 V,它代表每个状态所连接的其他状态的奖励。
例如,V1 代表与 S1 相连的所有州的总奖励。奖励 R1 不是 V1 的一部分。但是 S2 的 R2 是 S1 的 V1 的一部分。

这样,通过简单地查看下一个状态,代理将知道后面是什么。

存储在状态 s 的值 V(s)是从一个称为“值函数”的函数中计算出来的。价值函数计算未来的回报。
注意,最终状态(也称为终端状态)没有值 V (V = 0 ),因为没有未来状态和未来奖励。

价值函数在计算未来奖励时也使用折旧。
这与金融业的情况类似,你两年后获得的 1000 美元不如你今天获得的 1000 美元有价值。为了表达这个想法,我们将 1000 美元乘以某个折扣因子𝛄 (0≤𝛄 ≤1)的幂 t 其中 t 是收到付款之前的时间步数。

例如,如果您预计两年后有 1000 美元,贴现因子为 0.9,那么这 1000 美元的今天价值就是 1000 * 0.9 = 810 美元

为什么这在 RL 中很重要?

假设最终状态 S(n)具有 R(n) = 1,并且所有中间状态 S(i)具有 R(i)= 0,将每个状态上的 R(n)乘以𝛄的幂 t 将给出比前一状态更低的 v。这将创建一个从起点到终点递增 V 的序列,这构成了对代理的一个提示,即哪个方向的回报最大化。

因此,到目前为止,我们已经确定每个状态都有一个奖励 R(可能为零)和一个代表未来奖励的值 V。换句话说,V(s)是来自其他州的未来回报的函数。

数学上它被写成

其中 St 是所有与 s 直接或间接相连的状态。

然而,用下一个状态来表示 V(s)比仅用回报 R 来表示更容易,这具有当我们知道下一个状态的 V 时计算当前状态的 V 的优点,而不是对所有未来状态的所有回报求和。

公式变成v(s)= r+𝛄 v(s’)*

到目前为止,我们已经假设所有的状态都是按顺序连接的,但是很少出现这种情况,每个状态都可以连接到代理可能移动到的多个其他状态。

假设 S1 连接到 S2、S3、S4 和 S5,S1 的 V 值应该反映这种情况。

v(S1)=(R2+R3+R4+r5+𝛄(v2+v3+v4+V5))/4*
我们这里说的是 V(S1)是它所连接的状态的所有值的*均值。请记住,每个 V 都包含未来回报的值,因此通过对邻居进行*均,我们还可以了解他们之后会发生什么。

这个公式表明,我们可以从 S1 到 S2、S3、S4 和 S5,而没有任何对任何特定州的偏好,然而这是不准确的,因为我们知道有一定的概率去每个相邻州,并且这些概率可能不相同。例如,可能有 50%的机会去 S2,30%的机会去 S3,10%的机会去 S4 和 S5。
让我们分别称这些概率为 p2,p3,p4,p5。

于是 V(S1)就变成了v(S1)= p2 * R2+P3 * R3+P4 * R4+P5 * r5+𝛄(p2 * v2+P3 * v3+P4 * v4+P5 * V5)*。不出所料,这些概率被称为转移概率,因为它们表示从一种状态转移到另一种状态的可能性。

我们也可以把它们表示为一个矩阵 P 其中 Pij 是从一个状态 i 到一个状态 j 的跃迁概率。当没有可能的转换时, Pij 将为零。

让我们把公式安排得更有感染力一点:
v(S1)= p2 (R2+𝛄v2)+p3(r3+𝛄v3)+p4(r4+𝛄*v4)+P5 (r5+𝛄v5).

或者采用以下形式:

其中 P(Sk|S) 是到达状态 Sk 已知我们处于 S1 的概率。

在一般形式下,我们可以把它写成:

注意 k 经过所有状态,这意味着我们在所有状态求和!如果你感到惊讶,不要。正如我们之前所说,转移概率是一个矩阵,它给出了从一个状态转移到另一个状态的概率。因为不是所有的状态都与其他状态相连,所以这个矩阵是稀疏的,包含许多零。

示例让我们考虑前面的示例,其中 s 1 连接到 S2、S3、S4 和 S5,还让我们假设州的总数是 100,所以我们有 S1 到 s 100。做∑(p(sk | s)(r(k)+𝛄 v(sk))**其中 k 从 2 到 100,与做 sum 从 k = 2 到 5 是一样的,因为对于所有的 k ≥ 6 P(Sk|S)=0。

随机奖励

现在深呼吸,因为我们将增加一层新的复杂性!
奖励本身是不确定的,这意味着你不能假设 R 在每个状态下都是精确已知的。事实上,它是概率性的,可以取不同的值。

为了说明这一事实,假设你是一名射手,你正在瞄准一个目标,我们将假设只有三种状态,S1(瞄准)、S2(击中)、S3(未中)。你肯定知道目标是一串同心圆,你击中的内圈越多,你得到的奖励就越多。

假设你是一个相当好的弓箭手,你有 80%的机会击中目标,所以你有 20%的风险错过它。击中中心的奖励是 100,外圈是 50,最外圈奖励是 10。击中中心的概率是 10%,击中外圈的概率是 30%,击中最外侧的概率是 60%。最后,我们还将假设完全错过目标将导致-50。

所以状态 S1 的值将是:
*v(S1)= . 8 (0.1 * 100+. 3 * 50+. 6 * 10+𝛄 v(S2))+. 2 (1 -50+𝛄 v(S3))

由于 S2 和 S3 是终态,那么 V(S1)和 V(S2)都是零,但上面提到它们是为了不断提醒一般公式。
你可以清楚地看到,每个状态下的奖励都乘以各自的概率,然后求和,例如:(. 1 * 100+. 3 * 50+. 6 * 10)(1-50)* ,每个状态都乘以导致它的转移概率例如:. 8 (1 * 100+. 3 * 50+. 6 * 10+𝛄 v(S2))

从上面我们可以推导出通式:

值得澄清的是,表达式 p(si,rj | s)读作从状态 s 过渡到 si 并带有奖励 rj 的概率。
例如 p(S2,100|S1) 读作假设我们在 S1 状态,奖励 100(击中中心)去 S2(击中状态)的概率。答案是. 8 * .1 = .08 (8%)。

如果你还没有注意到,这构成了初始公式的第二部分(在页面的顶部)。
只需将 S 中的 si、rj 替换为S’,将 R 中的 r 替换为R即可得到:

S 是所有状态的集合 R 是所有奖励的集合。
我们接下来将讨论行动和政策 𝜋

行动和政策

到目前为止,我们已经说过,我们是随机地在状态之间转换的。例如,我们有 80%的机会从 S1 转移到 S2,20%的机会从 S1 转移到 S3。但是我们没有说这是怎么做到的!是什么引发了这种转变?答案很简单,就是代理在某个状态下做的某个动作。这个动作可能不是唯一的,在给定的状态下可能有几个可用的动作。到目前为止,我们假设有一个被称为“前进”或“做某事”的隐含动作,它以一定的概率将我们从一个状态带到另一个状态。

似乎随机的奖励是不够的,而且行动是不确定的!你无法保证如果你执行一项行动,你会 100%成功。
我们以弓箭手为例,你的目标是击中正中,得到 100 分,那么你瞄准正中,射出这一箭。然而,有很多因素可能会导致你错过。可能是你不够专注,或者是你放箭的时候手在抖,或者是风太大了。所有这些因素都会影响箭的轨迹。所以你可能会击中中心,或者其中一个外圈,或者你可能会完全错过目标!

让我们考虑另一个例子,你在网格上控制一个机器人。假设你用遥控器命令机器人前进。
动作是“向前移动”,预期状态是机器人前面的方块。然而,遥控器可能坏了,或者可能有一些干扰,或者机器人轮子的位置不正确,机器人不是向前移动,而是向右、向左或向后移动。

底线,在执行动作后,从状态 s 到状态s’并获得奖励 r 的概率不是 100%。这就是为什么我们写 p(s ',r|s,a) 这是在给定一个状态sa** 和一个动作的情况下,跃迁到状态 s' 的概率。

如前所述,每个状态都有几种可用的操作。例如,机器人可能在每个状态(或方块)中都有“向前”、“向左”、“向右”、“向后”。一个猎人在狩猎一个猎物时可能会有不同的动作,比如“开枪”、“射箭”或“投掷长矛”,这些动作中的每一个都会有不同的奖励。指示在特定状态下使用哪个动作的策略被称为策略𝜋。

你猜怎么着!
也是概率性的!我知道生活很艰难:)

所以一个猎人有一些概率使用他的枪,另一个概率使用他的弓,第三个概率使用他的矛。对于一个机器人来说也是一样,它有一定的概率去“前进”,“向左”,“向右”,“向后”。

像往常一样,我们通过对所有这些可能性进行*均,在 V(s)中对此进行量化。
给出以下内容:

【𝜋(a|s】是使用动作 a 遵循策略 𝜋 假设我们处于状态 s.
V𝜋 (s)
是应用
t22】策略 𝜋.时状态 s 的值
f(a,s,r)
在这里是我们在
随机回报部分建立的价值函数 V(s)的简写,另外使用 p(s ',r|s,a) 以反映对动作的依赖。
使用 f(a,s,r) 只是为了减轻复杂性,强调
【𝜋(a|s】的作用。****

所以最后在展开 f(a,s,r) 之后,我们得到了这篇冗长文章的主题的初始公式:

Value function of Reinforcement Learning

结论

希望这篇文章能够揭开强化学习中价值函数背后的数学之谜。

作为本文的一个收获,您可以将状态 s 的价值函数 V(s)理解为在该状态 s (由于某种策略【𝜋)下可用的动作所提供的*均奖励,其中每个动作都有一定的概率将代理转换到状态**

相关文章

  • 理解强化学习数学,面向开发者
  • 面向开发人员的强化学习政策
  • Q vs V 在强化学习中,最简单的方法
  • 数学背后的强化学习,最简单的方法
  • 动态编程在强化学习中的简便方法
  • 蒙特卡洛强化学习中的简单方法
  • TD 在强化学习中,最简单的方法

Python 中从头开始的神经网络

原文:https://towardsdatascience.com/math-neural-network-from-scratch-in-python-d6da9f29ce65?source=collection_archive---------1-----------------------

制作自己的机器学习库。

Photo by Mathew Schwartz on Unsplash

在这篇文章中,我们将从头开始学习机器学习的数学和代码,用 Python,一个小型库来构建具有各种层(全连接、卷积等)的神经网络。).最终,我们将能够以模块化的方式创建网络:

3-layer neural network

我假设你已经有了一些关于神经网络的知识。这里的目的不是解释我们为什么制作这些模型,而是向展示如何进行适当的实现

一层层地

我们需要记住这里的大局:

  1. 我们将输入的数据输入神经网络。
  2. 数据从层流向层,直到我们有了输出
  3. 一旦我们有了输出,我们就可以计算误差,它是一个标量
  4. 最后,我们可以通过减去相对于参数本身的误差的导数来调整给定的参数(权重或偏差)。
  5. 我们重复这个过程。

最重要的一步是第四步。我们希望能够拥有任意多的层,并且是任意类型的。但是,如果我们修改/添加/删除网络中的一层,网络的输出将会改变,这将改变误差,这将改变误差相对于参数的导数。我们需要能够计算导数,不管网络结构如何,不管激活函数如何,不管我们使用的损耗如何。

为了实现这一点,我们必须分别实现每一层

每一层应该实现什么

我们可能创建的每一层(全连接、卷积、最大池、丢弃等。)至少有 2 个共同点:输入输出数据。

正向传播

我们已经可以强调一个要点,那就是:一层的输出是下一层的输入

这被称为正向传播。本质上,我们给第一层输入数据,然后每一层的输出成为下一层的输入,直到我们到达网络的末端。通过比较网络的结果(Y)和期望的输出(假设 Y*),我们可以计算 en 误差 E 。目标是通过改变网络中的参数来最小化该误差。也就是反向传播(backpropagation)。

梯度下降

这是一个快速的提醒,如果你需要学习更多关于梯度下降的知识,互联网上有大量的资源。

基本上,我们想要改变网络中的某个参数(称之为 w ,以便总误差 E 减小。有一个聪明的方法可以做到这一点(不是随机的),如下所示:

其中 α 是我们设置的范围【0,1】内的参数,称为学习率。无论如何,这里重要的是∂e/∂w(e 相对于 w 的导数)。我们需要能够为网络的任何参数找到该表达式的值,而不管其架构如何。

反向传播

假设我们给一个层误差相对于其输出 (∂E/∂Y)的导数,那么它必须能够提供误差相对于其输入 (∂E/∂X).)的导数

记住E是一个标量(一个数)T22XY矩阵

让我们暂时忘掉∂E/∂X 吧。这里的诀窍是,如果我们可以访问∂E/∂Y,我们可以非常容易地计算∂E/∂W(如果该层有任何可训练的参数)而无需了解任何网络架构!我们简单地使用链式法则:

未知的是 ∂y_j/∂w ,这完全取决于该层如何计算其输出。因此,如果每一层都可以访问∂E/∂Y,其中 y 是它自己的输出,那么我们可以更新我们的参数!

但是为什么是∂E/∂X 呢?

别忘了,一层的输出是下一层的输入。这意味着一层的∂E/∂X 是前一层的∂E/∂Y!就是这样!这只是传播错误的一种巧妙方式!同样,我们可以使用链式法则:

非常重要,是理解反向传播的关键!在那之后,我们马上就能从头开始编写一个深度卷积神经网络了!

用于理解反向传播的图表

这就是我之前描述的。第 3 层将使用∂E/∂Y 更新其参数,然后将∂E/∂H2 传递给上一层,即它自己的“∂E/∂Y".”第二层也会这样做,以此类推。

这在这里可能看起来很抽象,但是当我们将它应用到一个特定类型的层时,它会变得非常清晰。说到摘要,现在是写我们第一个 python 类的好时机。

抽象基类:层

所有其他层将继承的抽象类处理简单的属性,即一个输入,一个输出,以及一个向前向后方法。

3-layer neural network

如你所见,backward_propagation中还有一个我没有提到的额外参数,那就是learning_rate。这个参数应该类似于更新策略,或者像 Keras 中所说的优化器,但是为了简单起见,我们将简单地传递一个学习率,并使用梯度下降来更新我们的参数。

全连接层

现在让我们定义和实现第一种类型的层:全连接层或 FC 层。FC 层是最基本的层,因为每个输入神经元都连接到每个输出神经元。

正向传播

每个输出神经元的值可以计算如下:

使用矩阵,我们可以使用点积一次性计算每个输出神经元的公式:

我们完成了向前传球。现在我们来做 FC 层的后向传递。

请注意,我还没有使用任何激活函数,因为我们将在一个单独的层中实现它!

反向传播

如前所述,假设我们有一个矩阵,其中包含误差相对于该层输出的导数(∂E/∂Y).)我们需要:

  1. 误差相对于参数的导数(∂E/∂W,∂E/∂B)
  2. 误差相对于输入的导数(∂E/∂X)

我们来计算∂E/∂W.这个矩阵的大小应该和 w 本身一样:ixj其中i是输入神经元的数量j是输出神经元的数量。我们需要一个梯度对应一个重量:

使用前面陈述的链式法则,我们可以写出:

因此,

就这样,我们有了更新权重的第一个公式!现在让我们来计算∂E/∂B.

同样,∂E/∂B 需要和 b 本身一样大,每个偏差一个梯度。我们可以再次使用链式法则:

并得出结论,

现在我们已经有了 ∂E/∂W∂E/∂B 、我们只剩下 ∂E/∂X 这是非常重要的,因为它将“充当”前一层的∂E/∂Y。

再次使用链式法则,

最后,我们可以写出整个矩阵:

就是这样!我们已经有了 FC 层所需的三个公式!

对全连接层进行编码

我们现在可以编写一些 python 代码来实现这种数学!

活化层

到目前为止,我们所做的所有计算都是完全线性的。用那种模式学东西是没希望的。我们需要通过将非线性函数应用于某些层的输出来将非线性添加到模型中。

现在我们需要为这个新类型的层重做整个过程!

https://gph.is/21pKLjE

别担心,这会快得多,因为没有可学习的参数。我们只需要计算 ∂E/∂X

我们将分别称ff'为激活函数及其导数。

正向传播

正如您将看到的,这非常简单。对于给定的输入X,输出只是应用于X的每个元素的激活函数。也就是说输入输出具有相同的尺寸

反向传播

给定 ∂E/∂Y ,我们要计算 ∂E/∂X

注意,这里我们使用了两个矩阵之间的元素乘法(而在上面的公式中,它是点积)。

激活层编码

激活层的代码非常简单。

你也可以在一个单独的文件中写一些激活函数和它们的导数。这些将被用来创建一个ActivationLayer

损失函数

直到现在,对于一个给定的层,我们假设 ∂E/∂Y 是给定的(由下一层给出)。但是最后一层会发生什么呢?它是如何得到 ∂E/∂Y 的?我们简单地手动给出,这取决于我们如何定义误差。

网络的误差由 you 定义,它衡量网络对于给定输入数据的好坏。定义误差的方法有很多种,其中最广为人知的一种叫做MSE——均方误差

Mean Squared Error

其中y*y分别表示期望输出实际输出。你可以把这种损失想象成最后一层,它把所有的输出神经元挤压成一个神经元。我们现在需要的是,像其他层一样,定义∂E/∂Y。除了现在,我们终于到了E

这只是两个 python 函数,可以放在一个单独的文件中。创建网络时会用到它们。

网络类

快好了!我们将制作一个Network类来创建神经网络,就像第一张图片一样简单!

我几乎注释了代码的每一部分,如果你掌握了前面的步骤,理解起来应该不会太复杂。不过,如果你有任何问题,请留下评论,我会很乐意回答!

构建神经网络

终于!我们可以使用我们的类来创建一个神经网络,我们想要多少层就有多少层!我们将构建两个神经网络:一个简单的异或和一个 MNIST 解算器。

求解异或

从 XOR 开始总是很重要的,因为这是一种简单的方法来判断网络是否正在学习任何东西。

很多东西我觉得不需要强调。只是要小心训练数据,你应该总是有样本维度第一个。例如这里,输入形状是 (4,1,2)

结果

**$ python xor.py** 
epoch 1/1000 error=0.322980
epoch 2/1000 error=0.311174
epoch 3/1000 error=0.307195
...
epoch 998/1000 error=0.000243
epoch 999/1000 error=0.000242
epoch 1000/1000 error=0.000242[
    array([[ 0.00077435]]),
    array([[ 0.97760742]]),
    array([[ 0.97847793]]),
    array([[-0.00131305]])
]

很明显这是有效的,太好了!我们现在可以解决更有趣的事情了,让我们解决 MNIST 吧!

解决 MNIST

我们没有实现卷积层,但这不是问题。我们需要做的只是重塑我们的数据,以便它可以适合一个完全连接的层。

MNIST 数据集由从 0 到 9 的数字图像组成,形状为 28x28x1。目标是预测图片上画的是什么数字。

结果

**$** **python example_mnist_fc.py**
epoch 1/30   error=0.238658
epoch 2/30   error=0.093187
epoch 3/30   error=0.073039
...
epoch 28/30   error=0.011636
epoch 29/30   error=0.011306
epoch 30/30   error=0.010901**predicted values :** 
[
    array([[ 0.119,  0.084 , -0.081,  0.084, -0.068, 0.011,  0.057,  **0.976**, -0.042, -0.0462]]),
    array([[ 0.071,  0.211,  **0.501** ,  0.058, -0.020, 0.175,  0.057 ,  0.037,  0.020,  0.107]]),
    array([[ 1.197e-01,  **8.794e-01**, -4.410e-04, 4.407e-02, -4.213e-02,  5.300e-02, 5.581e-02,  8.255e-02, -1.182e-01, 9.888e-02]])
]
**true values :** 
[[0\. 0\. 0\. 0\. 0\. 0\. 0\. 1\. 0\. 0.]
 [0\. 0\. 1\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]
 [0\. 1\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]]

这是完美的工作!太神奇了:)

https://gph.is/2jzemp3

GitHub 知识库和 Google Colab

您可以在下面的 GitHub 资源库和 Google Colab 文件中找到本文使用的全部工作代码。它还包含其他层的代码,如卷积展*

[## OmarAflak/Medium-Python-神经网络

通过在 GitHub 上创建一个帐户,为 OmarAflak/Medium-Python-Neural-Network 开发做出贡献。

github.com](https://github.com/OmarAflak/Medium-Python-Neural-Network) [## Python 中从头开始的神经网络

请随时联系我

colab.research.google.com](https://colab.research.google.com/drive/10y6glU28-sa-OtkeL8BtAtRlOITGMnMw)

我最*把那篇文章的内容放到了一个精美的动画视频里。你可以在 YouTube 上看看。

Neural Network from Scratch | Mathematics & Python Code — The Independent Code

Convolutional Neural Network from Scratch | Mathematics & Python Code — The Independent Code

如果你喜欢这篇文章——如果你按下鼓掌按钮,我会非常感激👏这对我帮助很大。和*!😎

Q 学习的数学——Python

原文:https://towardsdatascience.com/math-of-q-learning-python-code-5dcbdc49b6f6?source=collection_archive---------5-----------------------

理解贝尔曼方程的由来

Photo by Brett Jordan on Unsplash

q 学习

Q-Learning 是一种 强化学习 是一种机器学习。强化学习最*(通常)被用来教一个 AI 玩游戏(谷歌 DeepMind Atari 等)。我们的目标是理解称为 Q-Learning 的强化学习的简单版本,并编写一个将学习如何玩简单“游戏”的程序。让我们开始吧!

马尔可夫链

马尔可夫链是一种数学模型,它经历具有概率规则的状态转换。

Markov chain — Wikipedia

这里我们有两个状态 EA ,以及从一个状态到另一个状态的概率(例如,从状态 E 开始,有 70%的机会到达状态 A)。

马尔可夫决策过程

马尔可夫决策过程(MDP)是马尔可夫链的扩展,用于模拟更复杂的环境。在这个扩展中,我们增加了在每个状态下做出选择的可能性,这被称为动作。我们还添加了一个奖励,这是从一个状态到另一个状态采取一个行动的环境反馈。

Image by Author

在上图中,我们处于初始状态 不懂 在这里我们有两种可能的行动, 学习不学习 。对于研究动作,根据一个概率规则,我们可能以不同的状态结束。这就是我们所说的随机环境(random),也就是说,对于在同一状态下采取的同一动作,我们可能会有不同的结果( 理解不理解 )。

在强化学习中,这是我们如何模拟一个游戏或环境,我们的目标将是最大化我们从那个环境中获得的 奖励

报酬

回报是来自环境的反馈,它告诉我们做得有多好。例如,它可以是你在游戏中获得的硬币数量。我们的目标是最大化总回报。因此,我们需要把它写下来。

这是我们在某个时间点开始可以得到的总奖励。

例如,如果我们使用上面提到的 MDP。我们最初处于 不了解的状态,我们采取了学习 的行动,从而把我们随机带到了**不了解的状态。因此我们经历了报酬 r(t+1)=-1。现在我们可以决定采取另一个行动,这个行动将给出 r(t+2)等等。总回报是我们在环境中采取行动所获得的所有直接回报的总和。****

以这种方式定义奖励会导致两个主要问题:

  • 这个和有可能达到无穷大,这没有意义,因为我们想最大化它。
  • 我们对未来回报的考虑和对眼前回报的考虑一样多。

解决这些问题的一个方法是对未来的奖励使用递减因子。

设置 γ=1 让我们回到第一个表达式,这里每个奖励都是同等重要的。设置 γ=0 导致只寻找直接的回报(总是为最佳的下一步行动)。将 γ 设置在 01 之间是一种折衷,更多地寻求眼前的回报,但仍然考虑未来的回报。

我们可以用递归的方式重写这个表达式,这在以后会很方便。

政策

策略是一种功能,它告诉在特定状态下采取什么操作。该函数通常表示为 π(s,a) ,并产生在状态 s 下采取行动 a 的概率。我们要找到最大化奖励函数的政策。**

如果我们回到以前的 MDP 为例,政策可以告诉你采取行动的概率当你处于不懂* 的状态时。*****

此外,因为这是一个概率分布,所有可能行动的总和必须等于 1。

记号

我们将开始摆弄一些方程,为此我们需要引入新的符号。

这是通过动作 a 从状态 s 到状态s’的预期即时回报

这是通过动作 a 从状态 s 到状态s’转移概率

Image by Author

在本例中:

  • 从状态不懂** 到状态 不懂 通过行动 不学习 等于 0 。**
  • 从状态 不懂 到状态 通过行动 学习 的概率等于 80%

价值函数

存在两种所谓的“价值函数”。状态值功能,以及动作值功能。这些功能是分别测量“值”或某个状态有多好某个动作有多好的一种方式。

状态值

一个状态的是我们从那个状态开始可以得到的预期总报酬。这取决于告诉我们如何做决定的政策。

价值函数

在某个状态下采取行动的是我们从那个状态开始并采取行动所能得到的预期总回报。也要看政策。

Q 学习的贝尔曼方程

既然我们已经解决了符号问题,我们终于可以开始玩数学了!在计算过程中查看下图可以帮助您理解。

Image by Author

我们将从扩展状态值函数开始。 预期 操作符是 线性

接下来,我们可以扩展动作值函数。

这种形式的 Q 值非常普遍。它处理随机环境,但是我们可以用确定性的来写。也就是说,无论何时你采取行动,你总是在相同的下一个状态结束,并获得相同的奖励。在这种情况下,我们不需要对概率进行加权求和,等式变为:****

其中s’是您在状态 s 中采取行动 a 的最终状态。更正式地说,这是:

贪婪的政策

你可能已经在网上读到过贪婪政策。贪婪策略是指你总是选择最优下一步的策略。

Greedy Algorithm — Wikipedia

贪婪策略上下文中,我们可以写出状态值和动作值函数之间的关系。

因此,将这个代入前面的等式,我们得到在确定性环境中遵循贪婪策略的(状态,动作)对的 Q 值。

或者简单地说,

而这就是 Q-Learning 上下文中的贝尔曼方程!它告诉我们,在某个状态 s 下,一个动作 a 的值是你采取那个动作得到的即时回报,加上你在下一个状态下可以得到的最大预期回报

当你想到它的时候,它实际上是有意义的。

left or right ? — Image by Author

在这里,如果你只看即时奖励,你肯定会选择向左。不幸的是,游戏结束后,你不能得到更多的积分。

如果你加上下一个状态最大期望报酬,那么你很可能会向右走,因为的最大期望报酬等于零,而的最大期望报酬很可能高于 10–5 = 5******

你也可以调整 γ 来指定对下一个奖励有多重要。

Python 代码

这是一个简单的环境,由一个 5 乘 5 的网格组成。一个宝藏(T)放在格子的右下角。代理(O)从网格的左上角开始。

**O....
.....
.....
.....
....T**

代理需要使用 4 个可用的动作到达宝藏:

如果代理采取了一个直接引导他到 T 的行动,他就得到 1 的奖励,否则得到 0 的奖励。

代码被很好地注释了,这就是我们刚刚讨论的内容。现在有趣的部分,Q 学习算法!

我几乎注释了这段代码的每一行,所以希望它容易理解!

运行代码

将上述两个文件放在同一个目录中,并运行:

**python3 medium_qlearning_rl.py**

在纪元编号 40 左右,代理应该已经学会使用最短路径之一(8 步)到达宝藏。

结论

我们已经看到了如何推导统计公式来找到贝尔曼方程,并使用它来教人工智能如何玩一个简单的游戏。请注意,在这个游戏中,可能状态的数量是有限的,这就是为什么构建 Q 表(离散值接* Q 函数真实值的表)仍然是可管理的。图形游戏怎么样,比如 Flappy Bird,Mario Bros,或者 Call Of Duty?游戏显示的每一帧都可以认为是不同的状态。在这种情况下,不可能建立 Q 表,我们所做的是使用神经网络,其目标是学习 Q 函数。该神经网络通常将游戏的当前状态作为输入,并输出在该状态下可能采取的最佳行动。这被称为深度 Q 学习,也正是深蓝或阿尔法围棋这样的人工智能成功击败国际象棋或围棋世界冠军的原因。

我希望你喜欢这篇文章!多待一会儿吧!😎

数学基础:支持向量机+优化

原文:https://towardsdatascience.com/mathematical-underpinnings-svms-optimisation-6495776215c3?source=collection_archive---------9-----------------------

本周我们将看到拉格朗日乘数将如何帮助我们解决 SVM 最优化问题。因此,让我们提醒自己到目前为止已经涵盖了什么。

在第 1 周中,我们定义了学习模型参数的支持向量机 wb ,它们最大化了从决策边界到特征空间中最*点的间隔。此外,我们假设我们的数据点是线性可分的,并且是正确分类的(约束)。

Week 1 optimisation equation and constraints.

然后在第 2 周的中,我们揭示了拉格朗日乘子的原理,用于解决一个受不等式约束的优化问题。让我们回顾一下。

Week 2 Lagrange function.

偏导数 wrt 对 x 恢复*行法线约束,偏导数 wrt λ 恢复约束条件,g(x)= 0。还记得 KKT 条件吗?

KKT conditions.

拉格朗日函数可以扩展到不止一个约束。

使用拉格朗日乘子的 SVM 优化

我们的优化函数是由|| w ||^-1.最大化的这反过来相当于最小化|| w ||。我们的约束条件保持不变。这是二次规划的一个实例;最小化受线性约束的二次函数。我们可以将拉格朗日函数表述如下

Lagrange Function

wb 进行偏导数,我们得到

我们现在将优化拉格朗日对偶表示。

The Lagrangian Dual Problem from R. Berwick slides.

这来自于对偶原理,该原理指出优化问题可以被视为原始的(在这种情况下,最小化超过 wb) 或者对偶的(在这种情况下,最大化超过 a )。对于凸优化问题,原始和对偶有相同的最优解。

拉格朗日对偶表示(通过替换偏导数得到)是:

Dual Representation of the Lagrange function of SVM optimisation, [Bishop — MLPR].

我们现在有一个关于 的优化问题。要求核函数是正定的,这导致了凸优化问题,给出了与原始原始问题相同的解。

我们内核的内积起着非常重要的作用。为了深入了解,回想一下两个向量的点积返回它们之间角度的余弦值。可以算是一种相似度。现在,在两个向量完全不同的情况下,内积为 0,拉格朗日量没有增加任何东西。在两个向量相似且具有相同输出值的情况下,内积为 1,拉格朗日中的第二项将保持为正。这导致拉格朗日量减少,因此该算法降低了做出相同预测的相似向量的等级。在两个向量相似的情况下,预测不同的结果类别,第二项增加了拉格朗日,这些是我们感兴趣的点。区分两个阶级的要点。

稍后,核还将允许我们通过定义非线性核来对非线性可分的点进行分类。

在优化我们的拉格朗日乘数 a 之后,我们可以对新的数据点进行如下分类

回想一下现在关于我们的 SVM 优化问题的 KKT 条件。

因此,我们要么让拉格朗日乘数等于零,要么不等于零。对于所有的零乘数,它们对y()x)的总和没有贡献,因此在新点分类中不起作用。剩余的向量是支持向量,使得

并且它们对应于位于最大边缘超*面上的向量,如下所示。

Support vectors shown in blue, [Bishop — MLPR].

数学家,用数字记录历史

原文:https://towardsdatascience.com/mathematician-the-history-by-numbers-bf17f95a7b0b?source=collection_archive---------7-----------------------

2017 年 9 月中旬,我所在社区的一位成员( datascience.or.id )分享了一个有趣的数据表。它包含了 8000 多名出生或生活在 1980 年之前的数学家的信息,包括性别、国籍、领域等等。这是数据表的完整列,

Table Columns

我们只有有限的栏目,包含 8595 名数学家的出生日期、死亡日期、学位、雇主、博士生导师或学生等信息。让我们看看,我们如何从这个表中进行数据分析,我们可以从中获得什么样的历史。

目标和假设

数据只是以特定方式格式化的一组信息。如果不提出正确的问题并进行分析,这些数据不可能给出我们正在寻找的有价值的见解。假设和熟悉如何收集数据对于限制期望值、获得无偏见的见解以及从目标中得出有意义的答案或故事也很重要。

Define the objective

数据分析的目的或目标在许多情况下是不同的,它可以在获得数据后创建(有时使用另一个支持的附加数据)或收集与目标对应的数据。在数学家数据案例中,我们确实有数据,并试图从数据中获得洞察力,目标如下:

  • 一段时间内的性别构成
  • 数学家的期望年龄
  • 拥有最多数学家的国家公民
  • 数学家最多的数学领域
  • 博士生导师学生社交网络

这个目标是通过检查列生成的,您可以使用整体方法来获得不同的目标。同样,对于“数学家”的分析,假设是:

  1. 数据获得得很好
  2. 95%的出生于 20 世纪 80 年代之前的有影响力的数学家都被记录在案(基于检查我的著名数学家名单的名字)
  3. 其他假设根据每个目标进行调整
  4. (读者理解数学-统计-数据-工程术语)

清理数据

有人说过,80%的数据分析工作都是清理,包括检查数据、指标定义、数据类型检查、匹配数据、缺失值、数据验证、过滤、切片、分组,甚至旋转。清理的难度取决于数据表甚至数据集的“脏”程度。

我不会在这里解释我所做的所有清洁过程,但有几点需要注意。(你可以在这里找到完整的分析

a .唯一性 调查数据的唯一性对于确定表的主键或理解数据是如何读取的很重要。在我们的数据中,我假设“数学家”列是主键。我用 python 来看独特性,我得到了这个

Uniqueness Checking

有两个相同的名字,经过我的调查,他们是父子关系。虽然,在写“Jr”的“职业”上可以看出来。知道这一点后(他们是不同的人),我改变数据如下。

Preprocessing Result

然而,我不是只改变一行,因为我发现事实上有很多行的“职业”都填有“小”(见下一个解释)

b . Value Every columns validation 每列必须为每行提供相同类型的信息,可以是日期、数字、字符串或布尔值。对于我们的情况,就像我上面说的,我发现了这个

Not True Columns

正如您所看到的,表值正在移动,这就是为什么有一个名为“未命名:_29”的列。桌子正在移动,大约像这样,

Shifting Table Column

你必须分割数据,然后移动列名,而不是移动行,然后再连接。这里可以看到详情。

结果

数据分析是为了回答我们制定的目标,并创建另一个目标以获得更深入的见解。

  • 一段时间内的性别构成

为了得到这个,表格应该按照“性别”列分组,并计算“数学家”的数量。

Gender Grouping

正因为如此,只有当单词包含在实体上时,我们才应该将' sex_or_gender '上的实体改为。如果实体不是字符串,我们将其更改为 not_clear_2 (并根据数学家的名字将“[‘h”更改为 male,)。

Gender Grouping After Editing

上面的结果给了我们这样的答案:在 20 世纪 70 年代以前,女数学家只占所有男数学家的 1/10。这可能是由许多因素造成的,尤其是女性在那些年所扮演的角色。你可以越来越深入地了解真正的原因,比如开始创建一个时间表,看看性别加班之间的比例,等等。我不会那样做,因为我们需要更多的数据和信息。无论如何,这只是一个触发的“问题和答案”来开始更广泛地关注问题。

Mathematician Gender Ratio

  • 数学家的期望年龄

另一个让我感兴趣的方面是数学家的年龄预期,因为表中有关于出生和死亡年份的信息。很容易得到这些数学家的年龄,但是表格上的一些“年份”是用字符串写的,比如“1980 年代”。在我清理数据后,我开始查看年龄,并决定过滤年龄超过 20 岁且出生于公元 500 年以上的数学家的数据。这个过滤器将表切割成 4663 个数学家。

Mathematician Age Ditribution

上面的年龄分布给出了数学家的预期年龄在 70-80 岁之间的信息。它的年龄为 72.42 岁,精确的方差根为 14.86 年(你可以做 T-test 来获得置信度,但是对于如此大量的样本,我认为没有必要)。

从那以后,我对男女之间不同的年龄期望感到好奇。由于女数学家的局限性,我将再次过滤数据以进行比较。从表中可以得出结论,女数学家从 19 世纪 50 年代开始被认为是有影响的数学家。

Number of Female Mathematicians over year of birth and age expectation who born that year

这一数字不同于自 17 世纪以来做出贡献并得到认可的男性数学家,也不同于 1900 年至 1950 年间达到顶峰的数学家人数(无论是女性还是男性)。这一现象可能会让我们做出一个假设,即数学是 1900-1950 年世界上最热门或最性感的话题。可以进一步研究或者问历史学家。

Number of Male Mathematicians over year of birth and age expectation who born that year

在我过滤了 1850 年至 1940 年间出生的数学家的数据后,我计算了性别间的*均值和方差。

1850 to 1940 Mathematician Age Calculation

通过 T 检验,我得到男女数学家年龄差异的置信区间为 2.42 岁到 6.14 岁,置信水*为 95%。女数学家似乎比男数学家年龄大,最少有 2.5 年的空闲时间。预计这一条件将适用于 1940 年以后出生的下一位数学家。

  • 国籍和数学领域拥有最多数学家的国家

想象一下,你在一个大行业,你的大老板想知道什么是最有价值的产品或最赚钱的地区,这个部分就像那些问题一样。它很容易生产。

Mathematician Citizenship

此外,你不需要花太多时间来获取数据和创建可视化(尤其是如果你在技术行业)。可以用 python 或者 tableau 做可视化。在我们的例子中,结果会像我上面和下面呈现的那样。

Mathematician Field

可视化使理解数据和回答问题变得更加容易。然而,如果你只是像那样给出可视化会不会很无聊?。有些老板可能会问“从这里我们能看出什么?”尽管对他来说要求很明确。

例如,在我们的例子中,由于上面的可视化,我们目标的答案很容易。美国拥有大多数出生于 1840-1950 年间的数学家,这些数学家大多专注于数学分析。然而,我们可以扩大我们的分析的答案,使更有趣的故事,如果我们告诉“假设”的原因,为什么我们和数学分析将是最。还要解释其他国家或领域之间的显著差异。

  • 博士-导师-学生社交网络

在桌子上,有一个专栏是关于这位数学家和另一位博士导师学生之间的关系。因此,我们可以创建具有直接边缘的社会网络作为指导者和学生之间的连接。

Edge Meaning on The Network

在我们创建了网络之后,我们选择一个数学家或者具有最大出度数的节点,这意味着该数学家已经建议了许多数学家。此外,我们假设以他为根的 bfs 树将给出网络上最大的树。

Top 10 of Outdegree Number

从计算来看,安德雷·柯尔莫哥洛夫和戴维·希尔伯特谁的领先度最大。这个拾取应该已经完成了,因为我想从这个复杂的网络中呈现足够清晰的可视化。它几乎有 3314 个节点(我过滤了表格,只选择了有导师或学生的数学家)和 2838 个连接,这意味着它不是一个连通图。因为复杂性,我想通过网络上最大的 bfs 树来可视化。(可视化中的节点大小取决于其输出度数)

Andrey Kolmogorov bfs-tree

这是一棵相当大的树。同时,这是一棵希尔伯特树。

David Hilbert bfs-tree

从上面的图表中可以构建出许多其他的故事。然而,这里不做解释。
PS:用有限的技巧创造敏锐的网络并不容易。

结论

对于我们的数据,可以很容易地说,数学家有很大的性别差异范基础。假设最低工作年龄为 15 年,那么 1855 年和 1965 年是这一伟大课题最多产的时期。此外,他们中的大多数人拥有美国和欧洲国籍(显然,由于他们对科学的支持),数学分析是主要领域,其次是数论和几何。最后,在这些数学家之间,直到 20 世纪 80 年代末,戴维·希尔伯特和安德雷·柯尔莫哥洛夫是他们那个时代勤奋地给许多数学家出谋划策的人。

这并不难,对吗?不对。

数据分析是一种通过数据获取信息的方法,在我们的例子中,数据是在一张表上形成的。它从目标、假设开始,然后创建假设或直接深入数据。错误的目标和松散的假设会让你得到有偏见的结果,在做这件事的时候要小心谨慎。有许多技术可以用来操作数据或表格以达到目标。我已经在上面演示过了,从简单的社交网络表示的比例问题开始。为了提高你对这个问题的直觉,你必须对多种形式的数据进行大量的练习。它很有用,但需要努力。

人工智能数学:你需要的所有基本数学主题

原文:https://towardsdatascience.com/mathematics-for-ai-all-the-essential-math-topics-you-need-ed1d9c910baf?source=collection_archive---------3-----------------------

机器学习和深度学习的数学主题基本列表。

If AI is the secret sauce to make Pepper smarter! Then math is the air for all the essential ingredients to make that sauce! Photo by Alex Knight on Unsplash

AI 和数学的关系可以总结为:

一个在 AI 领域工作的不懂数学的人,就像一个不知道如何说服的政客。两者都有一个不可逃避的工作领域!

我不会在学习数学对人工智能的重要性上花费更多的时间,而是直接进入这篇文章的主要目标。

学习人工智能数学的一个流行建议是这样的:

  • 学习线性代数,概率,多元微积分,最优化和其他一些话题
  • 然后有一个课程和讲座的列表,你可以跟着去完成同样的任务

虽然上面的方法非常好,但我个人觉得还有另一种方法更好,特别是对于那些 1)没有扎实的定量背景,2)没有时间完成所有数学课程的人。那就是:

不要按主题走,而是按主题走。

例如,在学习多元微积分的时候,你会遇到著名的斯托克斯定理,但事实证明,它很有可能在实践中,甚至在阅读研究论文时,对你没有任何直接的用处。所以,按科目(课程)走可能很耗时,你可能会迷失在浩瀚的数学海洋中。

我建议您:

  • 一个话题接一个话题,先学习基本概念,巩固它们
  • 只有这样,当你在实际实施和阅读文献中遇到其他概念时,你才能去理解它们

以下是每个科目的基本主题列表:

线性代数

  • 向量
    定义、标量、加法、标量乘、内积(点积)、向量投影、余弦相似性、正交向量、正交向量、向量范数、向量空间、线性组合、线性跨度、线性独立性、基向量
  • 矩阵
    定义、加法、转置、标量乘法、矩阵乘法、矩阵乘法性质、hadamard 积、函数、线性变换、行列式、单位矩阵、可逆矩阵、逆矩阵、秩、迹、常见的矩阵类型——对称、对角、正交、正交、正定矩阵
  • 特征值和特征向量
    概念、直觉、意义、如何寻找
  • 主成分分析
    概念、性质、应用
  • 奇异值分解
    概念、性质、应用

结石

  • 功能
  • 标量导数
    定义、直觉、常见的微分法则、链式法则、偏导数
  • 梯度
    概念、直觉、性质、方向导数
  • 向量与矩阵演算
    如何求{标量值,向量值}函数对{标量,向量} - >四种组合的导数-雅可比
  • 梯度算法
    局部/全局最大值和最小值,鞍点,凸函数,梯度下降算法-批处理,小批处理,随机,它们的性能比较

概率

  • 基本规则和公理
    事件、样本空间、频率主义方法、相关和独立事件、条件概率
  • 随机变量-连续和离散,期望,方差,分布-联合和条件
  • 贝叶斯定理,映射,极大似然估计
  • 流行的分布-二项式,伯努利,泊松,指数,高斯
  • 共轭先验

多方面的

  • 信息论-熵,交叉熵,KL 散度,互信息
  • 马尔可夫链-定义,转移矩阵,*稳性

有什么消息来源可循? 任何适合你的资源,无论是 YouTube 视频还是古典教材。
如果你不确定,对每个主题进行简单的谷歌搜索[ <主题名称> +“机器学习”],并阅读顶部链接,以获得广泛的理解。

这个清单可能看起来很长,但它可以节省你很多时间。阅读以上主题会让你有信心潜入 AI 的深层世界,自己探索更多。

如果你喜欢这篇文章,请关注我 Abhishek Parbhakar 获取更多与人工智能、哲学和经济学相关的文章。

机器学习的数学:线性回归和最小二乘回归

原文:https://towardsdatascience.com/mathematics-for-machine-learning-linear-regression-least-square-regression-de09cf53757c?source=collection_archive---------1-----------------------

Mathematics for Machine Learning

机器学习完全是关于数学的,虽然现在有很多库可以通过函数调用来应用复杂的公式,但无论如何都需要学习至少关于它的基础知识,以便更好地理解它。

让我们试着用简单的方法来理解线性回归和最小二乘回归。

什么是线性回归?

线性回归是一种预测算法,它提供了 预测 (称之为【Y’)和输入(称之为【X’)之间的线性关系。

正如我们从基础数学中所知,如果我们绘制一个‘X’,‘Y’图形,线性关系总会出现一条直线。例如,如果我们画出这些值的图表

(Input) X = 1,2,3,4,5
(Prediction) Y = 1,2,3,4,5

这将是一条完美的直线

Linear Straight Line graph

在进一步深入之前,让我们了解一个事实,即在现实生活中,我们不会在输入和预测之间获得如此完美的关系,这就是为什么我们需要机器学习算法

两点间的直线方程

使用y = mx + b写出直线方程,其中m是斜率(梯度)b是 Y 轴截距(直线与 Y 轴相交的地方)。

一旦我们以y = mx + b格式从空间中的 2 个点得到一条直线的方程,我们可以使用相同的方程来预测产生一条直线的x的不同值的点。

在这个公式中,m是斜率,b是 y 截距。

线性回归是一种预测未知输入值'X''Y'值的方法,如1.5, 0.4, 3.6, 5.7甚至-1, -5, 10等。

让我们以一个真实世界的例子来演示线性回归的用法和最小二乘法的用法来减少误差

线性回归与现实世界的例子

让我们举一个真实世界的例子来说明农产品的价格,以及它是如何随着销售地点的不同而变化的。直接从农民手里买的价格会很低,从市区带来的价格会很高。

给定这个数据集,我们可以预测中间位置的产品价格

当数据集用于预测时,它也称为训练数据集

Agricultural Product and its price at point of sale

在本例中,如果我们将输入'X — Axis'视为销售地点,将'Y — Axis'视为价格(想想你熟悉的任何货币),我们可以将图表绘制为

Graph: Agricultural Product and its price at point of sale

问题陈述

给定此数据集,预测农产品的价格,如果它是在农户住宅和市中心之间的中间位置销售的

训练数据集

上面提供的数据集可以被视为上述问题陈述的训练数据集,如果我们将这些输入视为模型的训练数据,我们可以使用该模型来预测以下位置的价格

  • 农民之家——村庄
  • 村庄-城镇
  • 城镇—城市
  • 城市—市中心

我们的目标是,当我们使用直线方程绘制直线时,得到一条直线,使训练数据和预测模型之间的误差最小化。

直线方程(y = mx + b)

数学允许我们在二维图形中的任意两点之间得到一条直线。对于这个例子,让我们把农民的家和价格作为起点,把城市中心作为终点。

起点和终点的坐标将是

(x1,y1) = (1, 4) 
(x2,y2) = (5, 80)

其中x代表位置,y代表价格。

第一步是以y = mx + b的形式提出一个公式,其中x是一个已知值,y是预测值。

为了计算任何输入值x的预测值y,我们有两个未知数m = slope(Gradient)b = y-intercept(also called bias)

斜率(m =的变化/x 的变化)

线的斜率计算为y的变化除以x,的变化,因此计算结果如下

Calculating m = Change in Y / Change in X

应使用公式y-y1 = m(x-x1)计算 y 轴截距/偏差

Finding y = mx + b

一旦我们得到了我们的公式,我们可以通过用x代替用于计算公式的起点和终点来验证它,因为它应该提供相同的y值。

Verifying y = mx + b

现在我们知道我们的公式是正确的,因为我们通过替换x值得到了相同的y值,但是在中间的x的其他值如何呢,也就是2,3,4,让我们找出答案

Predicting Y values for unknown X values

这些值与训练集中实际存在的值不同(可以理解为原始图形不是直线),如果我们对照原始图形绘制此(x,y)图形,则直线将远离x=2,3, and 4图形中的原始点。

Graph: Actual Line Vs Projected Straight Line

然而,第一步是成功的,因为我们成功地预测了未知值XY

最小化误差

误差被定义为实际点和直线上的点之间的差值)。理想情况下。我们希望有一条直线,在这条直线上所有点的误差最小。

有许多数学方法可以做到这一点,其中一种方法叫做最小二乘回归

最小*方回归

最小*方回归是一种最小化误差的方法,其方式是最小化所有*方误差的总和。以下是计算最小二乘回归的步骤。

首先,计算m = slope的公式是

Calculating slope(m) for least squre

注:2 表示正方形,一个 python 语法**

所以让我们计算得出斜率(m)所需的所有值,首先从用x计算值开始

Calculating x — xmean for all X values

现在让我们用y来计算数值

Calculating y— ymean for all Yvalues

这些值的可用性允许我们计算所有

(x — xmean)*(y — ymean)

Calculating Sum of All (x — xmean)*(y — ymean)

现在让我们来计算等式的分母部分,即

Sum of (x — xmean)**2

Calculating Sum Of (x — xmean) square

所以总的计算结果是

Calculating the slope

y 轴截距的计算

使用公式b = ymean — m * xmean计算 y 轴截距

Getting the y-intercept value

总体公式现在可以用y = mx + b的形式写成

Getting y = mx + b

对 X,Y 值使用最小二乘回归

让我们看看当我们对所有 x 值应用y = 19.2x + (-22.4)时,预测y如何变化。

Predicting Y for all X using Least Square

让我们对照标准值绘制这个特殊的直线图。

Graph: Comparing Actual Vs Least Square

我们可以看到,与起点和终点之间的直线值相比,这些值更接*实际的直线。如果我们将它与直线图进行比较,我们就能看到不同之处

Graph: Comparing Actual Vs Least Square Vs Straight Line

为什么这种方法叫最小二乘回归?

该方法旨在减少所有误差值的*方和。误差越小,与原点的整体偏差就越小。我们可以将其与直线产生的误差以及最小二乘回归进行比较

Calculating Sum Square Error of Straight line

Calculating Sum square error of least square

正如我们所看到的,最小二乘法提供了比两点之间的直线计算更好的结果。

最小二乘法并不是机器学习中改进模型的唯一方法,还有其他方法,我会在后面的文章中谈到

感谢阅读…!!!

达克什

matplotlib——让数据可视化变得有趣

原文:https://towardsdatascience.com/matplotlib-making-data-visualization-interesting-8bac1eb3d25c?source=collection_archive---------8-----------------------

Photo by Alex Litvin on Unsplash

数据可视化是理解数据集并从中进行推断的关键步骤。虽然人们总是可以一行一行、一个单元一个单元地仔细检查数据,但这通常是一项单调乏味的任务,并且不能突出显示全局。另一方面,视觉效果以一种只需看一眼就能理解的形式定义数据,并保持观众的参与。

Matplotlib 是一个 Python 2D 绘图库,它以各种硬拷贝格式和跨*台的交互式环境生成出版物质量数字。—matplotlib.org

Matplotlib 是一个基本的库,它为各种绘图提供了选项,并以标签、标题、字体大小等形式提供了广泛的定制。我观看了大量的视频,并在网上阅读了可视化的文章。为了更好地理解 Matplotlib,我从 Kaggle 获取了人口密度数据集,并开始创建自己的可视化效果。本文重点介绍了我绘制的图表,包括我从数据中得出的定制和推论。

完整的工作以 GitHub 知识库的形式呈现,作为使用 Matplotlib 的可视化,以便快速参考。我们开始吧!

导入库

和往常一样,我们首先需要导入所有必需的库。我们导入NumpyPandas库进行数据处理。然后我们导入matplotlib,用它的模块pyplot绘制数据,用cm绘制调色板。语句%matplotlib inline确保所有图形在笔记本中内嵌显示。

导入数据集

不需要文件dataset.csv的前四行,所以我们可以跳过前四行,将数据导入变量dataset。然后我们使用head(5)来检查数据。

我们会立即看到一些与我们无关的栏目。首先,我们可以保留Country Name,但可以删除Country Code。因为我们知道我们正在处理人口密度,我们可以删除列Indicator NameIndicator Code。接下来,年份19602016的列具有NaN值。NaN代表的不是数字,我们应该删除这些列,因为它们不提供任何信息。最后,有一个未命名的列也有NaN值,所以我们也可以删除Unnamed: 61

我们使用dropna方法删除所有可能有空值或 null 值的行,并使用dataset.isnull().sum()检查是否所有列都没有 null 值。我们看到所有都显示空值。

我们现在准备可视化我们的数据。

(英)可视化(= visualization)

Photo by rawpixel on Unsplash

现在,我们将使用 Matplotlib 来创建我们的图,并使用可视化来得出有意义的结论。

线形图

我们首先用线图分析Aruba这些年的人口密度。我们沿 x 轴取年份,沿 y 轴取人口密度。

我们选择 x 值为dataset.columns[1:],这将选择除第一列之外的所有列,因为我们只需要年份,而不需要Country Name列。接下来,我们选择 y 值作为选择第一列的dataset.iloc[0][1:],即国家Aruba和除第一列之外的所有列。可以使用dataset[0][0]获得国家名称。为了绘制图表,我们只需使用plot函数,并将 x 轴和 y 轴的参数分别定义为 x 和 y。

恭喜你!!我们的第一个情节准备好了!!

First Plot

是的,它起了作用,但是很难理解。没有标签,轴值重叠。这就是 matplotlib 的定制能力派上用场的地方。让我们把它变得更容易理解一点。

rcParams允许我们修改图形大小、字体大小等等。然后我们添加一个标题,xlabel 和 ylabel。xticks允许我们定义文本的旋转角度,我们将其设置为 90 度。然后我们再次绘图,并将线的宽度定义为4

Updated Plot

我们现在可以看到,该图更具描述性,只是做了一些修改。

从上面的图中,我们可以看到人口密度在 20 世纪 80 年代之前一直在稳步上升。从 20 世纪 90 年代开始,密度急剧上升,并继续保持同样的增长,直到 2000 年代中期趋于稳定。

我们也可以使用折线图来观察不同国家的趋势。我们选取前 5 个国家,比较它们的人口密度增长。由于我们现在要处理单个图表上的多条线,我们应该为每个国家使用不同的颜色,并且还要定义一个图例,为每个国家分配一种独特的颜色。

这里,我们遍历数据集的前 5 行,并将这些值绘制成线图。我们使用matplotlibcm包及其rainbow方法来选择颜色。在绘图方法中,我们必须指定label参数,因为它确保当图例被启用时,图例名称被显示。使用方法legend()启用图例,其中我指定了一个属性,即24的大小。

Comparing 5 countries based on their Population Density

我们可以看到,阿鲁巴、安道尔、阿富汗、安哥拉和阿尔巴尼亚这五个国家的人口密度都有所上升。

现在,我们已经在一个单独的地块上绘制了所有的线图,很容易看出,与其他 4 个国家相比,阿鲁巴的人口密度一直较高。

条形图

使用带有相关参数的方法bar()可以轻松创建条形图。我们从绘制 2015 年所有国家的人口密度开始。

Bar Plot for Population Density of all countries for 2015

虽然情节确实试图在同一时间提供大量信息,但出于同样的原因,它缺乏提供任何有用的信息。x 轴标签中有太多的重叠,以至于整个绘图变得毫无用处。我们不仅需要可视化我们的数据集,还需要巧妙地可视化数据集的重要部分。如果把密度最大的前 10 个国家排序一下,看一看就更好了。

我们首先使用sort_values方法,根据2015年的人口密度,按照descending的顺序对国家进行排序。然后,我们使用head(10)方法选择前 10 名。然后,我们用这些新数据绘制柱状图。

Top 10 most densely populated countries for 2015

现在信息非常清楚了。数据是等间距的,并用不同的颜色清楚地表示出来。

在 2015 年的数据集中,澳门特区和摩纳哥的人口密度在所有其他可用国家中最高。

散点图

散点图是将数据显示为开放空间中的点的图。散点图非常有用,因为我们可以根据某个值指定每个数据点的大小,并且数据本身可以表示它与其他点的区别。

我们现在分析所有年份*均人口密度低于每*方公里土地面积 10 人的国家。

首先,我使用dataset.sum(axis = 1)对每一行的所有数据求和,然后使用lambda方法对每个最终值除以列数得到*均值。然后,我将这个值与小于或等于 10 的值进行比较,并将其用作数据集的索引。结果是*均人口密度小于或等于 10 的所有国家。我现在再次计算这个值,这次将它存储在变量consolidated_data中。绘制散点图的方法与其他图相似,但有一点小小的变化。我们现在可以使用参数s定义每个数据点的大小。我一直保持大小相当于人口密度。由于值很小,我将每个值乘以 20,这样差异就更明显了。

Countries with average Population Density less than equal to 10

您可以看到,每个数据点都根据其密度值以自己的大小显示在图表上。

在数据集中的所有国家中,格陵兰的*均人口密度似乎最小。

深入分析

现在,我们将更深入地研究数据集,看看能否得出更多结论。

描述性分析

我们可以看到全世界的最大和最小密度值是否有任何变化。因此,我们需要计算值的范围。

我们使用min()max()方法来计算除Country Name之外的每一列的最小值和最大值。然后我们在变量diff中找到范围。然后,我们计算每列最大值的最小值,并将其保存到minOfMax。当我们绘制条形图时,我们将从所有范围中减去该值,这将确保我们将所有范围与最小范围年份进行比较。这是通过在柱状图中使用apply(lambda x: x-minOfMax)方法来确保的。

Range of Population Density

我们看到,2001 年,人口密度最大的国家和人口密度最小的国家之间的差距最大,然后在 2002 年急剧下降。

人口与人口密度

探索人口密度是否确实是一个好的衡量标准,以及它是否也反映了一个国家的人口数量,这将是令人惊讶的。由于这个数据集没有人口或面积,我们需要从其他来源获取它。在这里,我们将使用 BeautifulSoup 从维基百科页面中提取土地面积,并使用它来计算人口。然后我们会比较人口和人口密度。你可以参考我关于网络抓取的文章来快速启动。

最后一组包括 170 个国家,我们有完整的可用信息,包括以公里为单位的土地面积。但是由于一次理解和解释这么多国家是很困难的,我们先来看看前 20 个国家。

我们现在通过并排绘制柱状图来比较 20 个国家的人口和人口密度。我们通过将 2015 年的人口密度乘以area得到Population。我们可以把画布分成多个支线剧情。方法subplot(rows, columns, index)用于定义一个支线剧情。这里,我们创建了一个由 2 行 2 列标识的 4 个图组成的画布。第三个参数告诉我们这里指的是哪个图。我们将 20 个国家的数据绘制在索引为 1 和 2 的两个图表中。

Population vs Population Density

我们可以看到Population Density并不总是描述一个国家Population的正确尺度,比如国家Bahrain

尽管人口密度很高,但孟加拉国的人口比巴林高得多。

结论

在这里,我们使用matplotlib包来设计和创建图,这有助于我们更好地理解我们的数据集。

希望你喜欢我的作品。请分享你的想法和建议。

Seaborn 实际上非常适合数据可视化

原文:https://towardsdatascience.com/matplotlib-seaborn-basics-2bd7b66dbee2?source=collection_archive---------6-----------------------

Seaborn 是一个基于 matplotlib 的 Python 数据可视化库(它是 Python 中绘图的常用库)。Seaborn 提供了一个高级界面,用于绘制有吸引力和信息丰富的统计图形。

1.导入

%matplotlib inlineimport matplotlib.pyplot as plt
import seaborn as sns

2.应用默认的 seaborn 主题、缩放和调色板。

sns.set()

您还可以自定义 seaborn 主题或使用默认主题的六种变体之一。它们被称为深色、浅色、浅色、亮色、深色和色盲。

# Plot color palette
def plot_color_palette(palette: str):
    figure = sns.palplot(sns.color_palette())
    plt.xlabel("Color palette: " + palette)
    plt.show(figure)

palettes = ["deep", "muted", "pastel", "bright", "dark", "colorblind"]
for palette in palettes:
    sns.set(palette=palette)
    plot_color_palette(palette)

使用这个 colab 文件 可以按照自己的步调学习下面的例子。谷歌的合作实验室是一个免费的 Jupyter 笔记本环境,不需要设置,完全在云中运行。

3.加载数据集

我们将在这里使用 tips 数据集,它将帮助我们浏览一些真实的示例。

tips = sns.load_dataset("tips")
tips.head()

4.绘图数据

让我们从使用多个语义变量的散点图开始,来可视化我们正在处理的数据集。

sns.relplot(x="total_bill", y="tip", 
            col="time", # Categorical variables that will determine the faceting of the grid.
            hue="smoker", # Grouping variable that will produce elements with different colors.
            style="smoker", # Grouping variable that will produce elements with different styles.
            size="size", # Grouping variable that will produce elements with different sizes.
            data=tips)

seaborn 中有几种专门的绘图类型,它们针对不同变量(数值和分类)之间的可视化关系进行了优化。可以通过[relplot](https://seaborn.pydata.org/generated/seaborn.relplot.html)访问它们。

我们还可以使用lmplot绘制线性回归模型。

sns.lmplot(x="total_bill", y="tip", 
           col="time", # Categorical variables that will determine the faceting of the grid.
           hue="smoker", # Grouping variable that will produce elements with different colors.
           data=tips)

或者简单地说:

sns.lmplot(x="total_bill", y="tip", data=tips)

sns.lmplot(x="size", y="tip", data=tips)

sns.lmplot(x="size", y="tip", data=tips, x_estimator=np.mean)

tips["big_tip"] = (tips.tip / tips.total_bill) > .15
sns.lmplot(x="total_bill", y="big_tip",
           y_jitter=.03, 
           logistic=True, 
           data=tips)

seaborn 中还有其他几种专门的绘图类型,它们针对可视化分类变量进行了优化。他们可以通过catplot访问。

sns.catplot(x="day", y="total_bill", 
            hue="smoker", # Grouping variable that will produce elements with different colors.
            kind="swarm", # Options are: "point", "bar", "strip", "swarm", "box", "violin", or "boxen"
            data=tips)

或者,我们可以使用核密度估计来表示采样点的基本分布。

sns.catplot(x="day", y="total_bill", 
            hue="smoker", # Grouping variable that will produce elements with different colors.
            kind="violin", # Options are: "point", "bar", "strip", "swarm", "box", "violin", or "boxen"
            split=True, 
            data=tips)

或者您可以显示每个嵌套类别中的唯一*均值及其置信区间。

sns.catplot(x="day", y="total_bill", 
            hue="smoker", # Grouping variable that will produce elements with different colors.
            kind="bar", # Options are: "point", "bar", "strip", "swarm", "box", "violin", or "boxen"
            data=tips)

jointplotpairplot使多情节可视化成为可能。jointplot关注单个关系,而pairplot从更广的角度来看,显示所有成对关系和边际分布,可选地以分类变量为条件。

sns.jointplot(x="total_bill", y="tip", 
              kind="reg", # Options are "scatter", "reg", "resid", "kde", "hex"
              data=tips)

sns.pairplot(hue="smoker", # Grouping variable that will produce elements with different colors.
             data=tips)

并排绘制两幅图像

figure = plt.figure()
figure.add_subplot(1, 2, 1)
plt.imshow(image_grey, cmap='gray'), plt.axis("off")
figure.add_subplot(1, 2, 2)
plt.imshow(image_binarized, cmap='gray'), plt.axis("off")
plt.show()

您甚至可以绘制更复杂的网格,例如:

Subplots. Credit: labri.fr

参考资料:

  1. https://seaborn.pydata.org/tutorial.html
  2. https://seaborn.pydata.org/introduction.html

看看这个故事 colab 文件 ,做些修改,如果觉得有帮助就分享吧。

最后,我创建了一个 3 分钟的调查,以帮助收集您在机器学习项目中最常用的工具和技术的数据。一旦收集到数据(如果您选择与我分享您的电子邮件),我们会与您分享这些数据,目的是确定趋势和最佳实践。

这项调查有助于确定现有工作流程中的改进领域和难点。

请花点时间填写这份调查【http://bit.ly/ml-survey-2019 T4

使用强化学习优化多交易场景中的广告收益

原文:https://towardsdatascience.com/maximize-ads-yield-in-a-multi-exchange-scenario-using-reinforcement-learning-46fa62a0b86?source=collection_archive---------5-----------------------

正如我之前的帖子所暗示的,这篇帖子是关于工作中可以使用 RL 的一些东西。设置如下:

假设你开发了某种网站或者 app。幸运的是,你已经吸引了一个坚实的用户群,现在费用变得足够高,你需要使用广告来赚钱的产品。你会发现有很多广告交易所,谷歌、脸书、Appnexus 等等。,你可以连接到。你如何最大化你的收益?一种方法是使用中介,目前大多数中介都是静态的。中介经常从各种网络中抓取数据来安排订单。另一种方法是使用标题竞价,这种方法不适用于应用程序。最后,我们可以使用服务器端的交叉交换竞价,这需要一个特殊的*台,如 DFP(交换竞价)。我在这里尝试的方法只是使用强化学习来预测您应该向哪个广告交易所发送广告请求。而且稍微有趣一点,应该用什么底价。

因为大多数广告交易不会提供每次请求的获胜价格;这意味着我们不能轻易获得奖励信号。虽然我们可以用每日收入作为信号,但我认为这太稀疏了,因为任何像样的出版商每天都会有数百万的广告请求。我们要使用的解决方法是:设置一组 adunitss,比如说 100 个,每个 adunit 都有一个单独的底价,比如说 1-100。如果一个特定广告单元的广告请求被满足,我们认为报酬是“底价+0.5”(0.5 只是一个使报酬不为 0 的小把戏;实际上,CPM 通常略高于底价)。这显然没有为我们建立完美的环境,但我认为这是一个合理的*似值(记住:DQN 也有过冲)。原因如下:

我用正态分布来模拟中标价格。这里是当分布为 norm(14,1)时的预期收益率分布。最大预期收益率 11.72 美元是在 12 美元的底价下,这意味着如果我们只连接到这一个交易所,我们应该始终使用将底价设置为 12 美元的 adunit。

现在,如果我使用 TensorForce 的 VPG 在相同的设置上运行 RL,我会得到以下结果:

如您所见,它非常接* 11,12 范围(尽管我们必须减去 0.5,因为它是一个人工项)。行动围绕着 12 美元的底价展开。

增加更多的交流让学习变得更难,但没什么好怕的。下面是我们有 5 个交换[[18,5],[4,5],[18,2],[50,5],[6,0]]的场景。每个子列表的第一个数字是正态分布的*均值,第二个是方差。

最后的行动不仅选择最有希望的广告交换,而且选择以 41,42 为中心的底价。假设我们实际上知道模型动态,它几乎与下面的分析结果完全一致。

在这个设置中,我做了一些重要的假设:

  1. (最大的一个)分布是*稳的。虽然我认为具体的分布并不重要(RL 所做的只是最大化*均值,根据 DeepMind 的最新论文,这可能不是最好的方法),但环境绝对必须是静止的。我不相信主流 RL 研究已经破解了非*稳 RL,尽管我知道一些公司如阿里巴巴使用在线 RL 来解决这个问题。一个简单但不完美的解决方法是每天晚上训练模型,这提供了一个相对最新的模型。在这方面,为了节省计算,切尔西·芬恩关于元学习的工作可能会派上用场,这显然是前沿研究(更新:OpenAI 的新论文试图解决非*稳性问题)。
  2. 在实际应用中,对应用程序来说更难,因为客户端应用程序保存数据,不像 web 服务器。通常我们能做的是将数据上传到服务器进行训练,并将学习到的模型发送回客户端执行。这很复杂,但肯定是可行的(因为每个设备上的广告数据不应该那么大)。但是我相信谷歌的联合学习更有前途。
  3. 我已经将环境大大简化为本质上的强盗问题。现实世界肯定有某种连锁效应,例如,用 adunit Y 选择 exchange X 会影响后面选择的性能(想想在 Go 中你的第一步如何影响后面的游戏)。我不知道目前如何最好地模拟这种环境(奖励函数有点难以指定——这是 RL 中的一个大挑战,也是为什么我们需要反向 RL;我可能会在未来更多地探讨这一点),但我认为任何中型/大型出版商都应该有大量的数据作为环境。因此,研究真实数据将是一个更好的方法。顺便说一句,腾讯有人一直在这个问题上挑战我——他认为连锁效应不存在。我可以举的一个例子是:假设有 2 个鞋类广告,一个来自耐克,另一个来自非品牌,首先显示耐克的广告肯定会影响非品牌的点击率。
  4. 此外,我还忽略了“直销”广告。这是故意的。预订购买通常具有更高的优先级,甚至可以在进入这种情况之前处理。

总之,我构建了一个利用 RL 的广告收益最大化的简化模拟(总的来说,我对数据效率不太满意)。我听说一些公司正在做类似的事情,但这肯定不是一种广泛采用的做法。我希望这是一个开始。

这里的代码是。其实超级简单。

深度学习云提供商的最佳交易

原文:https://towardsdatascience.com/maximize-your-gpu-dollars-a9133f4e546a?source=collection_archive---------0-----------------------

AWS、谷歌、Paperspace、vast.ai 等等

我想知道我应该在哪里以最低的成本和最少的麻烦在线训练我的深度学习模型。我没能找到一个比较好的 GPU 云服务提供商,所以我决定自己做一个。

如果你对 GPU 和 TPU 了如指掌,只想要结果,请随意跳到漂亮的图表。

在本文中,我没有考虑服务模型,但是将来我可能会考虑。跟着我,确保你不会错过。

深度学习芯片选项

我们简单看一下可用于深度学习的芯片类型。我将通过与福特汽车进行比较来简化主要产品。

光靠 CPU 做深度学习真的很慢。你不想用它们。它们对许多机器学习任务都很好,只是不适合深度学习。CPU 是深度学习的马车。

Horse and Buggy

对于大多数深度学习计算,GPU 比 CPU 快得多。NVDIA 制造了市场上的大多数 GPU。接下来我们要讨论的几款芯片是 NVDIA GPUs。

一个 NVIDIA K80 大约是你开始深度学习所需的最低要求,并且不会有极其缓慢的训练时间。K80 就像福特 A 型车——一种全新的出行方式。

Ford Model A

英伟达 P4s 比 K80s 快。它们就像福特嘉年华。绝对是对 a 型车的改进。它们并不常见。

Ford Fiesta. Credit; By Rudolf Stricker CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0/), from Wikimedia Commons

P100 是嘉年华的升级版。这是一个相当快的芯片。对于大多数深度学习应用程序来说完全没问题。

Ford Taurus. Credit: ford.com

NVDIA 还制造了许多消费级 GPU,经常用于游戏或加密货币挖掘。这些 GPU 通常工作正常,但在云服务提供商中并不常见。

目前市场上最快的 NVDIA GPU 是特斯拉 V100——与特斯拉汽车公司无关。V100 大约比 P100 快 3 倍。

https://www.nvidia.com/en-us/data-center/tesla-v100/

V100 就像福特野马:速度很快。如果你现在正在使用 PyTorch,这是你最好的选择。

Ford Mustang. Credit: Ford.com

如果你在谷歌云上使用 TensorFlow/Keras,你也可以使用张量处理单元——TPUs。Google Cloud、Google Colab 和 PaperSpace(使用 Google Cloud 的机器)都有 TPU v2。它们就像矩阵计算中的福特 GT 赛车。

Ford GT. Credit: Ford.com

TPU 的 v3 仅在谷歌云上对公众开放。TPU v3 是你今天能找到的最快的深度学习芯片。它们非常适合训练 Keras/TensorFlow 深度学习模型。它们就像一辆喷气式汽车。

Jet car. Credit: By Gt diesel — Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=30853801

如果想加快训练速度,可以增加多个 GPU 或者 TPU。然而,当你增加数量的时候,你将支付更多。

结构

深度学习框架有几种选择。我在这里写了一篇关于哪些最受欢迎和最受欢迎的文章:

[## 深度学习框架 Power Scores 2018

谁在使用、兴趣和受欢迎程度上领先?

towardsdatascience.com](/deep-learning-framework-power-scores-2018-23607ddf297a)

TensorFlow 的市场份额最大。Keras 是由 Google 开发的高级 API,运行在 TensorFlow 和其他几个框架上。PyTorch 是 pythonic,脸书支持的酷小子。FastAI 是 PyTorch 的高级 API,它使得用几行代码训练世界级的模型变得很容易。

使用 PyTorch v1.0 预览版和 FastAI 1.0 对模型进行训练。PyTorch v1.0 Preview 和 FastAI v1.0 是最前沿的,但允许你非常快速地做真正酷的事情。

参赛者们

我测试了配备 GPU 的云提供商,他们对大量深度学习实践者有很强的价值主张。纳入要求:

  • 按小时或更小的增量付费。
  • 安装配置不能差。尽管如此,我还是将 AWS 包括在内,因为它们拥有如此大的市场份额。

事不宜迟,如果你开始深度学习,这里是你需要知道的云提供商。

Google Colab

Google Colab 免费。这是一个带有漂亮 UX 的 Jupyter 笔记本系统。它集成了 GitHub 和 Google Drive。Colab 还允许合作者在笔记本上留下评论。

对于 Keras 或 TensorFlow 来说,Colab 上手速度非常快,这并不奇怪,因为这些开源库都是谷歌自己开发的。Pytorch v1.0 预览版需要进行一些配置,并且有些问题。当使用 Resnet50 和适当大小的分辨率图像时,我不得不关闭 FastAI v1 的并行性以节省内存。

2019 年 1 月 15 日更新。PyTorch 位于 V1,Google Colab 增加了 Docker 容器的共享内存。您现在可以并行运行这个测试了。

Colab 既有 GPU 也有 TPU。在撰写本文时,您不能将 TPUs 与 PyTorch 一起使用。然而,TPU 对 PyTorch(以及 FastAI) 的支持正在进行中——谷歌工程师正在制作原型——截至 2018 年 10 月 25 日。

谷歌云

谷歌云计算引擎是比 Colab 更强大、更可定制的云选项。像 AWS 一样,它需要一些配置,令人沮丧的配额增加,总账单有点难以估计。与 AWS 不同,Google Cloud 接口更容易使用,更容易配置,TPU 可用于 TensorFlow/Keras 项目。

Pricing changes as you change Google Cloud instance settings

可抢占的实例节省了很多钱,但是有被打断的风险——它们对大多数学习任务来说都很好。

如果你有资格获得 $300 初始信用并且不介意一些配置,谷歌云是一个进行深度学习的好地方。如果您进行扩展,他们的价格、安全性、服务器选项和易用性使他们成为领先者。

AWS

AWS EC2 并不是最容易配置的东西,但它太受欢迎了,每个深度学习从业者都应该在某个时候经历配置的阵痛。在我的文章《寻找数据科学家工作列表中最受欢迎的工具》中,AWS 位列前十。

[## 数据科学家最需要的技能

雇主在寻找什么?

towardsdatascience.com](/the-most-in-demand-skills-for-data-scientists-4a4a8db896db)

AWS 的入门级 GPU 产品是 p2 . x large——AWS 称之为具有 4 个 CPU 和 61 个 RAM 的 NVDIA Tesla K80。截至 2018 年 10 月下旬,您可以通过每小时 0.28 美元的现货定价节省资金。尽管存在没有实例可用的风险。几乎每次我尝试以略高于最*的价格购买现货时,都会收到一个。

AWS instance configuration fun

AWS 是可伸缩的、安全的和可靠的。它运行着互联网的大部分。不幸的是,这也是一个痛苦的设置。我建议你不要用 AWS 开始你的深度学习之旅,除非你已经熟悉这项服务,或者是一名经验丰富的程序员。

图纸空间

让 Jupyter 笔记本在纸张空间渐变上运行非常快。用 FastAI v1.0 版设置 PyTorch v1.0 版预览版也很容易。

Paperspace 有谷歌的 TPUv2s,这是除了谷歌之外唯一一家有能力租用它们的公司。这里有一篇关于这个功能的好文章。与谷歌云相比,TPU 的价格有点贵,为 6.50 美元——在谷歌云上,你可以用不到一半的价格买到可抢占的 TPUs。

Paperspace 的网站表明他们非常重视安全性。他们有 SLA。总部位于纽约的 Y-combinator alum 公司最*筹集了 1300 万美元。Paperspace 有自己的服务器,也使用其他人的服务器。他们是合法的。

vast.ai

vast.ai 是 GPU 共享经济选项。这是一个为需要 GPU 的人和在 vast.ai 上列出他们机器的第三方个人匹配的市场。它有一个非常好的仪表板和非常好的价格。

理论上,你使用的第三方机器可以获取你的数据,尽管实际上这并不容易。这里见讨论。

此外,正常运行时间可能会低于云基础架构公司。例如,电源或互联网可能会在源头中断,这可能是某个人的房子。对猫狗分类没问题,对病人病历没问题。

Vast.ai 在仪表盘上显示的机器技术规格信息比我从其他任何云提供商那里看到的都多。我用了一台 GTX 1070 Ti,每小时收费 0.065 美元,预计正常运行时间约为 99.5%。那就是每小时 6.5 美分!安装最新的 PyTorch 版本很快。我不建议以更低的价格竞标,只要以当前价格租赁,否则你很可能会失去你的机器。

vast.ai Options

除了 Kaggle 和 Google Colab 有限的免费选项,vast.ai 是获得体面性能的最低成本选项。

其他选项

我看了很多其他的 GPU 选项。我没有测试我的已知 GPU 云提供商列表上的每一项服务——因为其中许多服务要么不容易快速设置,要么在成本上没有竞争力。

如果你正在学习机器学习,那么你应该花些时间在 Kaggle 上。它有一个很棒的学习社区,有教程、竞赛和大量数据集。Kaggle 提供免费的 K80 GPUs,12GB VRAM,2 个 CPU 内核,6GB RAM,最长 12 小时。我发现这个网站很落后,他们的笔记本没有 Jupyter 笔记本通常有的快捷方式。

此外,在 Kaggle 上上传定制包和处理文件也很困难。我建议你不要用 Kaggle 进行深度学习训练,但要用它做很多其他机器学习的事情。

我试着用了 IBM Watson 和微软 Azure。他们都悲惨地没有通过简单设置测试。我花了 30 分钟和他们每个人在一起,然后决定这已经足够了。当有更好的选择时,生命太短暂了,不必要的复杂。他们也是

许多快速部署的服务有良好的客户服务和良好的 UX,但甚至不提数据安全或数据隐私。VectorDash 和蝾螈都可以快速部署,而且相当划算。 Crestle 部署迅速,但价格较高。FloydHub 要贵得多,K80 每小时的成本超过 1 美元。基本机器的价格不到 0.10 美元,但我在启动时不断出错,聊天帮助在两天后没有回应(尽管他们很快回应了之前的一个问题)。

Amazon SageMaker 比 AWS EC2 更加用户友好,但与列表中的其他选项相比没有成本竞争力。像 p2.xlarge 这样的基本 K80 GPU 设置需要花费 1.26 美元!我发现,它还需要增加配额才能使用,这可能需要几天时间。

每个云公司都应该突出讨论安全性、SLA 和数据隐私。谷歌、AWS 和 PaperSpace 做到了这一点,但许多较小的新公司却没有。

实验

我在 Jupyter 笔记本上使用 FastAI v1.0 在流行的猫与狗图像分类任务上训练了一个深度学习模型。该测试提供了云提供商实例之间有意义的时间差异。我使用 FastAI 是因为它能够用很少的代码快速训练模型达到非常好的验证集精度(一般约 99.5%)。

我使用 %%time 魔法命令来测量时间。比较 Wall time 是因为那是 Google Colab 会输出的时间。对三种操作的壁时间求和:用 fit_one_cycle 训练,用 fit_one_cycle 解冻并再次拟合,以及用测试时间增加预测。 ResNet50 用于迁移学习。请注意,初始训练的时间是在第二次运行时进行的,因此下载 ResNet50 的时间不会包括在时间计算中。我用来训练模型的代码改编自 FastAI 的文档,可在这里获得。

结果

这里有一个图表,显示了机器规格的实例结果。

数据和图表可以在 Kaggle 的这个 Jupyter 笔记本中找到。以下是以图形方式显示的培训成本结果。GCP 是谷歌云*台的简称。

Google Colab 是免费的,但是很慢。那些需要花钱训练的人。vast.ai 是迄今为止性价比最高的。

我花了几天时间查看了 vast.ai 的定价,类似规格的机器一般都能买到。有一天,我测试了一台类似的机器,第一台机器的培训成本为 0.01 美元,而第二台机器的培训成本为 0.008 美元,所以结果非常相似。如果 vast.ai 看到用户需求大幅增长,而用户主机没有类似的大幅增长,价格预计会上涨。

让我们画出每小时的花费和训练时间的关系图。

左下角是您想要的位置—优化成本和培训时间。vast.ai、谷歌云的单一 P100 和谷歌云的单一 V100 是强有力的选择。

如果你真的想要速度,AWS 的 V100 x4 是最快的选择。它的培训成本也是最高的。

如果你真的不想花钱,谷歌 Colab 的 K80 可以完成这项工作,但速度很慢。同样,并行化对于 Colab 来说是不可能的。据推测,这将得到解决,其性能将接* 20 分钟,其中谷歌云的 K80 和 AWS 的 K80 进来。Colab 将是一个更好的选择,但仍然很慢。一旦 TPUs 与 PyTorch Colab 配合使用,对 PyTorch 用户来说应该会更好。

在效率方面,Paperspace 比其他选择稍贵,但它减少了许多设置上的麻烦。Paperspace 也有一个非常非常基本的标准 GPU ,起价每小时 0.07 美元,但规格如此之低(即 512 MB GPU RAM),以至于它不太适合深度学习。Google Colab 有一个更好的免费选择。

远离有效边界的期权被排除在最终图表之外。例如,AWS 的 p2.8xlarge 将位于每小时成本与训练时间图表的中上部分,训练时间超过 16 分钟,spot 实例为每小时 4.05 美元。这不是一个好的值。

如果映像上没有最新的软件包版本,则本实验中报告的时间并不反映 SSH 和安装这些版本的时间。AWS 花了一段时间——至少 10 分钟才能得到一个运行中的 Jupyter 笔记本,即使在我为这个项目做了很多次之后。

Google Cloud 的运行速度要快得多,部分原因是 PyTorch v1.0 预览版和 FastAI V1.0 版的图像是可用的。

vast.ai 需要几分钟的时间来旋转,但随后只需点击一下,你就可以进入一个 vast.ai 在线 Jupyter 笔记本,这非常容易使用。

这项研究的一个限制是,图像分类任务只是一个使用。然而,其他深度学习训练可能会显示类似的结果。

推荐

如果你是这整个领域的新手,想学习深度学习,我建议你先学习 Python,Numpy,Pandas,和 Scikit-learn。我对学习工具的建议在这篇文章中。

如果你已经是一个熟练的程序员,知道如何处理新代码中的 bug,我建议你用 FastAI v1.0 开始深度学习。可运行的文档现已发布。

如果你正在学习 Keras/TensorFlow,Google Colab 是一个很好的起点。它是免费的。如果 Colab 开始提供更好的 PyTorch v1.0 支持,如果您正在学习 FastAI 或 PyTorch,它也可能是一个很好的起点。

2019 年 1 月 15 日更新。PyTorch 位于 V1,Google Colab 增加了 Docker 容器的共享内存。根据 FastAI 的内置时钟,用 FastAI 1.0.40.dev0 训练和测试模型用了 20:10。这将节省超过 1/3 的时间。

如果你正在用 FastAI 或 PyTorch v1.0 构建,并且不需要数据隐私,并且你不是使用 Google Cloud 或 AWS 的专业人士,我建议你从 vast.ai 开始。它的性能很好,非常便宜,而且相对容易设置。我在这里写了一篇用 FastAI 使用 vast.ai 的指南。

如果你在扩展,使用谷歌云。这是一个价格合理、安全可靠的完整产品包。UX 和配置复杂度优于 AWS。GPU、CPU 和 TPU 的定价很容易估算,不会随需求而变化。然而,存储和辅助费用可能很难破译。此外,如果您计划运行更强大的 GPU 或 TPU,您将需要请求增加配额。

法律免责声明:如果你忘记关闭你的实例,不保存你的进度,或者被黑客攻击,我不负任何责任😦。

我希望这篇文章能为您节省一些时间🕐还有钱💵当你建立深度学习模型的时候。

如果你觉得这很有趣,请通过分享来帮助其他人找到这篇文章。

如果你喜欢数据科学、机器学习和深度学习,请关注我。

最大似然估计:工作原理及在 Python 中的实现

原文:https://towardsdatascience.com/maximum-likelihood-estimation-how-it-works-and-implementing-in-python-b0eb2efb360f?source=collection_archive---------5-----------------------

之前,我写了一篇关于使用非参数估计量来估计分布的文章,其中我讨论了估计从未知分布生成的数据的统计属性的各种方法。本文介绍了一种在给定数据的情况下估计概率分布参数的非常有效的方法,称为最大似然估计。

这篇文章是研究投资组合优化的数学框架的系列文章的一部分,并解释了在 OptimalPortfolio 中看到的它的实现。

极大似然估计量

我们首先了解什么是最大似然估计量(MLE ),以及如何用它来估计数据的分布。当特定的分布被指定时,极大似然估计量被认为是参数估计量。

本质上,MLE 的目标是在给定一组概率分布参数的情况下,最大化每个数据点出现的概率。换句话说,找到使数据点的概率(可能性)最大化的概率分布的一组参数。形式上,这可以表示为

优化这个概率和的问题是,它通常涉及参数的非常讨厌的指数,这使得找到最优值更加困难。因此,引入了对数似然的概念。对数似然基本上是数据点出现的概率的对数。形式上,

使用对数似然的好处有两方面:

  1. 概率密度函数中的指数变得更易于管理和优化。
  2. 概率的乘积变成一个和,这使得单个分量最大化,而不是使用 n 个概率密度函数的乘积。

MLE 的概念出奇的简单。困难在于如何有效地应用这种方法来估计给定数据的概率分布参数。在我们讨论实现之前,我们应该开发一些数学基础,看看 MLE 是否在所有情况下都有效。为此,请考虑以下因素:

该函数将被最大化以找到参数。1/n 的附加因子显然不影响最大值,但对我们的证明是必要的。考虑:

这是真实参数下对数似然的期望值。换句话说,在某种意义上这是我们的目标对数可能性。大数定律(LLN)指出,当数据点的数量趋于无穷大时,同独立(iid)随机变量的算术*均值收敛于随机变量的期望值。因此,我们可以证明:

这意味着在给定足够数据的情况下,MLE 是一致的,并且收敛于参数的真值。

学生的最大似然估计

由于最大似然估计的通常介绍性例子总是高斯分布,我想用一个稍微复杂一点的分布来解释,即 Student-t 分布。这也是我的 OptimalPortfolio 实现中使用的发行版。使用高斯分布和 Student-t 分布的区别在于,Student-t 分布不会产生 MLE 的解析解。因此,我们需要研究某种形式的优化算法来解决它。它为我们提供了一个学习期望最大化算法的机会。

EM 算法

EM 算法本质上是在给定数据和参数的先验分布的情况下计算对数似然的期望值,然后在给定这些参数的情况下计算对数似然函数的该期望值的最大值。一般来说,第一步是:

然后:

重复这一过程,直到参数值收敛或达到给定的精度阈值。该算法可以相对容易地应用于 Student-t 分布。重要的事实是注意到 Student-t 分布的参数来自 Gamma 分布,因此,在第一步中计算的期望值如下:

其中 d 为随机变量的维数,M 为马氏距离,定义如下:

一旦计算出来,我们就可以计算 Student-t 分布的对数似然的最大值,它有一个解析解,即:

这个估计和期望值的计算可以迭代直到收敛。在 python 中,它看起来像这样:

import pandas as pd
import numpy as np

def expectation_max(data, max_iter=1000):
    data = pd.DataFrame(data)
    mu0 = data.mean()
    c0 = data.cov()

    for j in range(max_iter):
        w = []
        # perform the E part of algorithm
        for i in data:
            wk = (5 + len(data))/(5 + np.dot(np.dot(np.transpose(i - mu0), np.linalg.inv(c0)), (i - mu0)))
            w.append(wk)
            w = np.array(w)

        # perform the M part of the algorithm
        mu = (np.dot(w, data))/(np.sum(w))

        c = 0
        for i in range(len(data)):
            c += w[i] * np.dot((data[i] - mu0), (np.transpose(data[i] - mu0)))
        cov = c/len(data)

        mu0 = mu
        c0 = cov

    return mu0, c0

结论

分布参数的估计是数据统计建模的核心。这是任何数据科学家和定量分析师的必备技能。对于那些感兴趣的人来说, OptimalPortfolio 是对这些方法如何结合起来优化投资组合的阐述。

五月版:数据可视化

原文:https://towardsdatascience.com/may-edition-data-visualization-7d2c1635b0?source=collection_archive---------10-----------------------

9 篇文章帮助你创造美丽的视觉效果

富有创意和吸引力的可视化效果是将注意力吸引到数据中的关键信息和趋势的最佳方式之一,有助于直观地理解这些信息和趋势。现在有许多不同的工具和资源可以用来创建这些数据可视化。

最*关于数据科学,有几篇很棒的文章强调了可视化数据的有趣方法。对于 5 月份,我们精心挑选了一些热门文章来帮助您了解如何可视化您的数据。

与艾伦·唐尼关于数据科学的坦诚对话

Ryan Louie 的坦诚对话系列的一部分,在这次对话中,Ryan 与 Allen Downey——奥林学院计算机科学教授、作家和博客作者——讨论了对非技术受众的态度如何影响数据科学家的工作,以及如何定义算法偏差。 (8 分钟读取)

捍卫简单,数据可视化之旅

一篇关于数据可视化的重要性以及作者 Irene Ross 在该领域的道路和哲学的介绍性文章。 (7 分钟读取)

十年推特数据可视化

Tanyoung Kim 的这篇文章向你展示了如何可视化 Twitter 数据,以揭示朋友之间的联系、Twitter 的长期使用以及其他行为模式。 (5 分钟读完)

可视化警察杀人

Olagunju Abdul-Hammid 的这篇文章展示了如何使用可视化技术对美国关于警察杀人的数据集进行探索性数据分析。 (4 分钟读取)

市级项目

作为长期项目aitecture.com、罗曼·库丘科夫的一部分,展示了人工智能如何被用于特定的任务,比如以俄罗斯城市为例识别城市模式。 (5 分钟读取)

人工智能帮助医学研究人员发现严重哮喘的基因特征

Devi Ramanan 指导我们通过研究发现了一个 1693 年的基因签名,使用人工智能有意义地区分严重哮喘和非哮喘以及轻中度哮喘。 (6 分钟读取)

最后,我们还推荐阅读汉娜·韩嫣的文章,她目前正在参加关于数据科学和视觉故事的 100 天项目挑战。以下是一些亮点:

20 种安慰食品大学生在有压力、无聊、悲伤或高兴时消耗最多

根据不同的心情,有趣地呈现大学生对食物的偏好。 (2 分钟读完)

哪些航空公司最危险

对 1908 年至 2009 年间记录的 5000 起坠机事件进行分析,试图获得关于承运人选择的明智决策的见解。 (2 分钟读取)

十年全球恐怖主义地理空间可视化

对过去 10 年全球恐怖主义的概述,分析攻击的地理位置以及攻击的类型及其演变。 (3 分钟读取)

我们也感谢最*加入我们的所有伟大的新作家埃里克·勒、尼古拉·贝尼尼、杰森·I·卡特、迪帕克·阿米尔塔·拉杰、克里夫·埃维斯迪克、阿希什·萨马尔、瑞安·路易、卢卡斯·科鲁奇、瑞典人怀特、耶蒂·桑蒂我们邀请你看看他们的简介,看看他们的工作。

Cherie & Inês

五月版:在数据科学领域找到一份工作

原文:https://towardsdatascience.com/may-edition-getting-a-job-in-data-science-125996b1734c?source=collection_archive---------13-----------------------

9 篇必读文章

这就是这么多数据科学家离职的原因

由 Jonny Brooks-Bartlett — 8 分钟阅读

是的,我是一名数据科学家,是的,你确实没看错标题,但总得有人说出来。我们读到了很多关于数据科学是 21 世纪最性感的工作,以及作为数据科学家可以赚到诱人的钱的故事,这似乎是绝对的梦想工作。

Booking.com 一位数据科学家的日记

由西康大乘 — 6 分钟读完

大约两年半前,我作为一名数据科学家加入了Booking.com,此前我在迪拜从事了 3 年的咨询工作。从咨询转向纯粹的数据科学角色是我职业生涯中的一个重大转变,事后看来,我很高兴自己做出了这个选择。

最好的数据科学家没有被发现

由杰瑞米·哈里斯 — 5 分钟阅读

这里有一个有趣的事实:在现实中,并没有很多情况下,一个 ML 工程师的工作实际上需要他们有一个博士学位。那么要一个的真正意义是什么呢?

在 Scout24 担任数据科学家

由扬·扎瓦日基 — 6 分钟阅读

我和 Scout24 数据科学团队正在撰写我的硕士论文,并在这里学到了很多关于实践和组织结构的知识。

激活您的数据科学职业生涯的 45 种方法

由基里尔·叶列缅科 — 8 分钟阅读

我们询问了 LinkedIn 小组成员,他们在成为成熟的数据科学家时面临的最大挑战是什么。一些最常见的挫折是:不知道从哪里开始,缺乏经验,无法形成网络,难以联系到合适的人。

数据科学面试指南

由赛义德·萨达特·纳兹鲁尔 — 12 分钟阅读

数据科学是一个相当大且多样化的领域。因此,做一个万事通真的很难。传统上,数据科学将专注于数学、计算机科学和领域专业知识。

在数据科学领域找份工作会是什么样子

克里斯汀·凯尔勒(Kristen ke hrer)—9 分钟阅读

备选标题:我的人生故事:)我读过一些文章,这些文章指出进入分析和数据科学有多难。这不是我的经历,所以我想分享一下。

获得数据科学家工作的两面性

通过法维奥·巴斯克斯 — 16 分钟阅读

你好!这是一篇我等了很久才写的博客。主要是因为我需要做研究,听听其他人对此的看法。

如何王牌数据科学面试( R & Python 、 SQL 、统计)

卡森·福特 — 27 分钟阅读

对于从事或试图从事数据科学工作的人来说,统计学可能是你需要发展的最大和最令人生畏的知识领域。这篇文章的目标是把你需要知道的东西减少到有限数量的具体想法、技术和方程式。

我们也感谢最*加入我们的所有伟大的新作家,克里斯汀·凯尔赫勒,劳伦·奥尔德加,阿拉娜·鲁德尔,沙拉思·斯里尼,斯科特·伦德伯格,塔尔·佩雷茨,埃尔维斯,阿德蒙德·李,伊利亚·瓦尔查诺夫,瑞安·戈特斯曼 赛义德·萨达特·纳兹鲁尔,谢尔盖·马尔切夫斯基,萨姆·格拉西,本杰明·霍夫曼,雅各布·茨威格,因巴尔·诺尔,布莱恩·约翰逊等等很多人。 我们邀请你看看他们的简介,看看他们的工作。

也许杯子终究是半满的…

原文:https://towardsdatascience.com/maybe-the-glass-is-half-full-after-all-fed6508e985f?source=collection_archive---------5-----------------------

科学家发现,大脑天生就会关注好消息,忽略坏消息。

我们天生乐观吗?

当你思考你的未来时,你相信会发生什么?总的来说,你认为事情会怎样发展?自古以来,青少年杂志、小报和网上性格测试就充斥着测试你是“半杯水”还是“半杯水”的测试。虽然这可能是一个有趣的话题,但乍一看,它似乎不是科学研究中最自然的领域。

然而,无数的研究已经开始研究这个问题:我们天生倾向于乐观还是悲观?30 多年的研究结果如此压倒性地支持一方的论点,以至于出现了被称为“不切实际的乐观主义”的现象。一次又一次,在各种背景下,人们高估了发生在自己身上的积极事件的可能性,同时低估了消极事件的可能性。重度吸烟者低估了他们早死的几率;女性低估了她们患乳腺癌的风险;普通人认为他们比其他人更有可能变得富有。

然而,到目前为止,这一领域的研究在很大程度上涉及到对其中一个结果的某种程度的先验吸引力——即,对我来说,患癌症的可能性越低,结果就越好。这造成了一个复杂的混淆,不清楚是潜在的强化学习偏向于好消息,还是复杂的信念形成和更新过程倾向于那些乐观的个人结果。巴黎认知神经科学实验室最*的一项研究试图解开这个困惑。

最新研究

由 Germain Lefebvre 领导的研究小组探索了这一主题,要求参与者在成对的中性选项中进行选择。以这种方式,在选择之间不可能存在现有的推断的合意性的差异。50 名参与者被展示成对的抽象视觉符号,并被要求选择一个。某些符号与正的、零的或负的金钱回报的高或低的概率相关联,在每个选择后都有反馈。在 24 次试验中,由参与者从经验中学习,哪个符号对应于哪个结果。抽象符号看起来像这样:

Abstract cues were used in the study to avoid participants having any affective association with them before choosing.

参与者被要求按下一个按钮,在左边和右边的符号之间做出选择。一旦做出选择,立即给出反馈,告诉他们是收到了€0.50,没有收到€0.50 还是失去了€0.50。

行为实验中所做选择产生的数据符合两种不同的强化学习(RL)模型。第一个是标准的 RL 模型,它*等地考虑了所有的结果,不管它们是积极的还是消极的。这被称为 Rescorla-Wagner 模型(RW ),可追溯到 20 世纪 70 年代早期。简单地说,该模型计算预测误差—* ,即预期结果与实际结果之间的差异。然后,这个预测误差的某一部分被用于更新下一组期望。用于后续更新的预测误差部分被称为“学习率”,用希腊字母 alpha (α)表示。学习率的界限如下,0 > α > 1,α值越高,表示从以前的经验中学习得越多。第二个模型也被用来拟合数据。这一个,RW 模型,允许正面结果(α+)和负面结果(α-)有不同的α值。该实验旨在观察哪种模型更准确地拟合数据;标准 RW 模型或 RW 模型。*

一些有趣的结果

通过统计分析,Lefebvre 和他的同事发现 RW 模型比 RW 模型更好地解释了数据。假设积极和消极结果的学习率不同,可以改进我们如何从抽象符号中选择的预测。他们发现,积极结果α+的不同学习率明显高于消极结果α-的学习率。在最基本的层面上,我们从产生比预期更好结果的环境中获取的信息比从产生比预期更差结果的环境中获取的信息更多。在 50 名参与者中,发现 21 名具有对称的学习率(α+ = α-),即他们是无偏见的学习者;另外 29 个被发现有不对称的学习率,其中 25 个是“乐观”的学习者(α+ > α-),4 个是“悲观”的学习者(α+ < α-)。

但是等等,还有更多…

尽管这项行为实验的发现很有用,但作者的研究还有一个更有趣的转折。参与者在这些抽象符号之间做出的所有 24 个决定都是在他们躺在核磁共振成像仪里的时候做出的!通过这种方式,研究人员可以看到在做出每个选择和接收反馈时,大脑的哪些确切部分是活跃的。通过将行为数据与 fMRI 时间编码扫描配对,有可能区分出那些乐观的参与者和那些学习速度无偏见的参与者中显示活动增加的精确大脑位置。他们发现,对于乐观的学习者来说,在给予反馈时,纹状体和腹内侧前额叶皮层(vmPFC)的活动明显更多(在神经科学中,这被称为“奖励预测误差编码”)。

Areas of the brain that are activated during choice (left) and outcome (right) for optimistic reinforcement learning, α+.

那么这一切到底意味着什么呢?

这项研究认为,在基本层面上,我们的大脑倾向于偏爱好消息而不是坏消息。但是这是怎么发生的呢?大量研究表明,在日常生活中,乐观主义者往往生活得更好;拥有更健康的心脏,更少压力,拥有更广泛的朋友圈。也许目前的这项研究显示了一种先天的生理偏见,表明乐观,即使不切实际,似乎也赋予了一种进化优势。

所以,下一次,当你发现自己在对需要多长时间的评估过于乐观后,匆忙地完成某件事情,或者在没有带伞后,把自己抖干,记住,这是你大脑的方式,保持乐观实际上符合你的最佳利益,即使这可能在当时提供不了多少安慰。

参考文章:

Lefebvre,g .,Lebreton,m .,Meyniel,f .,Bourgeois-Gironde,s .,和 Palminteri,S. (2017 年)。乐观强化学习的行为和神经特征。自然人类行为,1,67,1–9。

早餐 MBA 市场篮子分析的简单指南

原文:https://towardsdatascience.com/mba-for-breakfast-4c18164ef82b?source=collection_archive---------7-----------------------

Photo by Liene Vitamante on Unsplash

所以最*,我很幸运地参与了一个涉及市场篮子分析的项目,但显然我不能在媒体上讨论我的工作。因此,我试着在 Kaggle.com 的 T2 寻找合适的数据集。我设法在这里找到了一个,并且应用了我所知道的一切来实现它!同时也要感谢李苏珊在 MBA 上的出色表现,点击这里!

那么什么是市场篮子分析呢?根据本书数据库营销:

市场购物篮分析仔细检查客户倾向于一起购买的产品,并使用这些信息来决定哪些产品应该交叉销售或一起促销。这个词源于购物者在购物过程中装满的购物车。

顺便说一下, Market Basket 也是美国新罕布什尔州、马萨诸塞州和缅因州的 79 家连锁超市,总部设在马萨诸塞州的图克斯伯里(维基百科)。

通常 MBA 是从销售系统的角度在客户层面上对交易数据进行的。我们可以利用 MBA 从数据中提取产品之间的有趣关联。因此,它的输出由一系列产品关联规则组成:例如,如果客户购买产品 A,他们也会倾向于购买产品 b。我们将遵循三个最流行的标准来评估关联规则的质量或强度(稍后将回到这一点)。

获得正确的包(Python):

import pandas as pd
import numpy as np 
import seaborn as sns
import matplotlib.pyplot as plt
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
import mlxtend as ml

让我们来看看我们的面包篮的数据:

bread = pd.read_csv(r"D:\Downloads\BreadBasket_DMS.csv")
bread.head(8)

“数据集包含来自一家面包店的 15'010 次观察和超过 6,000 次交易。关于变量的更多信息可以在图中找到。

面包篮有哪些“热门”商品?

sns.countplot(x = 'Item', data = bread, order = bread['Item'].value_counts().iloc[:10].index)
plt.xticks(rotation=90)

Lit items at BreadBasket

咖啡似乎是数据集中最热门的项目,我猜每个人都想在早上喝杯热咖啡。

每天售出多少件商品?

是时候进入 MBA 本身了!克里斯·莫菲特使用 python 编写了令人敬畏的 MBA 指南和教程,值得称赞。

我们将使用 MLxtend 库的 Apriori 算法来提取频繁项集以供进一步分析。apriori函数期望数据在一个热编码的 pandas 数据帧中。因此,您的数据帧应该如下所示:

首先,我们将相应地对bread数据帧进行分组,并显示商品的数量,然后我们需要将商品合并为每行 1 个交易,每个商品 1 个热编码。这将导致上表!

df = bread.groupby(['Transaction','Item']).size().reset_index(name='count')basket = (df.groupby(['Transaction', 'Item'])['count']
          .sum().unstack().reset_index().fillna(0)
          .set_index('Transaction'))#The encoding function
def encode_units(x):
    if x <= 0:
        return 0
    if x >= 1:
        return 1basket_sets = basket.applymap(encode_units)

之后,我们将生成最低支持度至少为 1%的频繁项目集,因为这是一个更有利的支持度,可以向我们显示更多的结果。

frequent_itemsets = apriori(basket_sets, min_support=0.01, use_colnames=True)
rules = association_rules(frequent_itemsets, metric="lift")
rules.sort_values('confidence', ascending = False, inplace = True)
rules.head(10)

Final output

结束了

记得我告诉过你们,我们会回到三个最流行的标准,来评估关联规则的质量和强度。有支撑、信心提升 :
1。支持度是包含特定项目组合的事务相对于数据库中事务总数的百分比。对组合 A 和 B 的支持是,

个人 A 的 P(AB)或 P(A)

2.置信度衡量结果(项目)对
前因(项目)的依赖程度。换句话说,置信度是给定前因后果的条件概率,

专业人员

其中 P(B|A) = P(AB)/P(A)

3.提升(也称为改善或影响)是一种通过支持和信心来克服
问题的措施。Lift 被认为是度量规则的置信度和预期置信度之间的差异——用比率来度量。考虑关联规则“if A then B”。该规则的提升被定义为

P(B|A)/P(B)或 P(AB)/[P(A)P(B)]。

如公式所示,lift 是对称的,因为“如果 A 那么 B”的 lift 与“如果 B 那么 A”的 lift 相同。每个标准都有其优点和缺点,但一般来说,我们喜欢具有高可信度、高支持度和高升力的关联规则。

作为总结,

置信度= P(B|A)

支持= P(AB)

升力= P(B|A)/P(B)

从输出来看,关联规则“if Toast then Coffee”的提升是 1.48,因为置信度是 70%。这意味着购买烤面包的消费者比随机选择的消费者购买咖啡的可能性高 1.48 倍。更大的升力意味着更有趣的规则。高支持度的关联规则是潜在有趣的规则。类似地,高可信度的规则也是有趣的规则。

参考:

Kaggle 数据集:【https://www.kaggle.com/xvivancos/transactions-from-a-bakery】

苏珊李的菜篮子分析:https://towards data science . com/a-gentle-introduction-on-Market-Basket-Analysis-association-rules-fa 4b 986 a40 ce

数据库营销书籍:https://www.springer.com/gp/book/9780387725789

Apriori 算法:http://rasbt . github . io/mlx tend/user _ guide/frequent _ patterns/Apriori/

克里斯莫菲特使用 Python 进行市场篮子分析:http://pbpython.com/market-basket-analysis.html

Kao dim . com:https://www.kaodim.com/

源代码在 Jupyter 笔记本这里!

麦卡洛克-皮茨神经元——人类第一个生物神经元的数学模型

原文:https://towardsdatascience.com/mcculloch-pitts-model-5fdf65ac5dd1?source=collection_archive---------0-----------------------

众所周知,深度神经网络的最基本单元被称为人工神经元/感知器。但是走向我们今天使用的感知机的第一步是由麦卡洛克和皮茨在 1943 年通过模仿生物神经元的功能迈出的。

注:这篇文章的概念、内容和结构都直接来自于Mitesh m . Khapra教授关于NPTEL 深度学习 课程的精彩讲座和材料。看看吧!

生物神经元:一个过于简化的例证

A Biological Neuron — Wikipedia

树突:接收来自其他神经元的信号

体细胞:处理信息

轴突:传递该神经元的输出

突触:与其他神经元的连接点

基本上,一个神经元接受一个输入信号(树突),像 CPU (soma)一样处理它,通过一个类似电缆的结构将输出传递给其他连接的神经元(轴突到突触到其他神经元的树突)。现在,这可能在生物学上不准确,因为外面发生了更多的事情,但在更高的层面上,这是我们大脑中的神经元正在发生的事情——接受输入,处理输入,输出输出。

我们的感觉器官与外部世界互动,并将视觉和声音信息发送给神经元。假设你在看《老友记》。现在,你的大脑接收到的信息被“笑或不笑”的神经元接收,这将帮助你决定是否笑。每个神经元只有在其各自的标准(稍后将详细介绍)得到满足时才会被激发/激活,如下所示。

Not real.

当然,这并不完全正确。事实上,不仅仅是几个神经元在做决策。在我们的大脑中有一个由 10 个神经元(1000 亿个)组成的大规模并行互联网络,它们的连接并不像我上面给你展示的那样简单。它可能看起来像这样:

Still not real but closer.

现在,感觉器官将信息传递给第一层/最底层的神经元进行处理。这个过程的输出以分层的方式传递到下一层,一些神经元会激活,一些不会,这个过程继续下去,直到它产生最终的反应——在这种情况下,就是笑。

这种大规模并行的网络也确保了分工。每个神经元仅在满足其预期标准时触发,即,神经元可以对特定刺激执行特定角色,如下所示。

Division of work

据信,神经元以分层的方式排列(然而,科学家提出了许多有实验支持的可信替代方案),每一层都有自己的角色和责任。为了检测一张脸,大脑可能依赖于整个网络,而不是单一的一层。

Sample illustration of hierarchical processing. Credits: Mitesh M. Khapra’s lecture slides

既然我们已经确定了生物神经元是如何工作的,让我们看看麦卡洛克和皮茨提供了什么。

注意:我对大脑如何工作的了解非常非常有限。以上插图过于简化。

麦卡洛克-皮茨神经元

第一个神经元计算模型是由 Warren MuCulloch(神经科学家)和 Walter Pitts(逻辑学家)在 1943 年提出的。

This is where it all began..

它可以分为两部分。第一部分, g 接受一个输入(咳咳树突咳咳),执行聚合并基于聚合值第二部分, f 做出决定。

假设我想预测自己的决定,是看一场随机的足球比赛还是不看电视。输入都是布尔型的,即{0,1},我的输出变量也是布尔型的{0:会看,1:不会看}。

  • 所以, x_1 可能是ispremierlegueon(我更喜欢英超)
  • x_2 可能是 isItAFriendlyGame (我倾向于不太关心友谊赛)
  • x_3 可能是 isNotHome (跑腿的时候不能看。我可以吗?)
  • x_4 可能是ismanunitedplay(我是大个子曼联球迷。GGMU!)等等。

这些输入可以是兴奋性的或抑制性的。抑制性输入是那些对决策产生最大影响的输入,与其他输入无关,即,如果 x_3 为 1(非原位),那么我的输出将始终为 0,即,神经元将永远不会触发,因此 x_3 是抑制性输入。兴奋性输入并不会让神经元自己放电,但当它们结合在一起时可能会放电。从形式上看,事情是这样的:

我们可以看到 g (x) 只是在做输入的求和——简单的聚合。而这里的θ称为阈值参数。例如,如果我总是在总和变成 2 或更多时观看比赛,那么这里的 theta 是 2。这被称为阈值逻辑。

使用 M-P 神经元的布尔函数

到目前为止,我们已经看到了 M-P 神经元是如何工作的。现在让我们看看这个神经元是如何被用来表示一些布尔函数的。请注意,我们的输入都是布尔的,输出也是布尔的,所以本质上,神经元只是试图学习一个布尔函数。基于适当的输入变量,许多布尔决策问题都可以转化为这个问题——比如是否继续阅读这篇文章,读完这篇文章后是否观看《老友记》等等。可以用 M-P 神经元来表示。

M-P 神经元:一种简洁的表示

这种表示只是表示,对于布尔输入 x_1x_2x_3 如果 g (x)sumtheta,则神经元会触发,否则不会。

和功能

“与”功能神经元只有在所有输入都打开时才会触发,即这里的 g (x) ≥ 3。

或功能

我相信这是不言自明的,因为我们知道,如果任何输入打开,或功能神经元就会激活,即这里的 g (x) ≥ 1。

具有抑制输入的功能

这看起来可能有点棘手,但其实不然。这里,我们有一个抑制输入,即 x_2 ,所以每当 x_2 为 1 时,输出将为0。记住这一点,我们知道 x_1 和!只有当 x_1 为 1 并且 x_2 为 0 时,x _ 2才会输出 1,因此很明显阈值参数应该为 1。

让我们验证一下, g (x)x _ 1+x _ 2仅在三种情况下≥ 1:

情况 1:当x1为 1、x2为 0
情况 2:当
x1为 1、x2为 1
情况 3:当
x1为 0、x2****

但是在情况 2 和情况 3 中,我们知道输出将是 0,因为 x_2 在两者中都是 1,感谢抑制。而且我们还知道 x_1 和!x_2

或非功能

对于要激发的 NOR 神经元,我们希望所有的输入都为 0,因此阈值参数也应该为 0,并且我们将它们都作为抑制性输入。

非功能

对于非神经元,1 输出 0,0 输出 1。因此,我们将该输入作为抑制输入,并将阈值参数设置为 0。有用!

任何布尔函数都可以用 M-P 神经元来表示吗?在你回答这个问题之前,让我们先了解 M-P 神经元在几何上做什么。

M-P 神经元的几何解释

在我看来,这是这篇文章最精彩的部分。让我们从 OR 函数开始。

或功能

由于显而易见的原因,我们已经讨论过 OR 函数的阈值参数θ为 1。输入显然是布尔型的,所以只有 4 种可能的组合— (0,0)、(0,1)、(1,0)和(1,1)。现在将它们绘制在 2D 图上,并利用 OR 函数的聚合方程
x1+x21,使用该方程我们可以绘制决策边界,如下图所示。再次提醒你,这不是一个实数图。

我们刚刚使用了聚合方程,即x1+x2 =1**,以图形方式显示了当通过 OR 函数 M-P 神经元时,其输出位于该线之上或之上的所有输入,以及位于该线之下的所有输入点将输出 0。****

瞧啊。!M-P 神经元刚刚学习了一个线性决策边界!M-P 神经元将输入集分成两类——阳性和阴性。正的(输出 1)是位于决策边界上或之上的那些,负的(输出 0)是位于决策边界之下的那些。

让我们通过看更多的例子来说服自己,M-P 单元对所有的布尔函数都是一样的(如果从数学上还不清楚的话)。

与酌

在这种情况下,决策边界方程为x1+x2 =2**。这里,位于(1,1)之上或之上的所有输入点在通过 AND 函数 M-P 神经元时输出 1。很合适!决策边界起作用了!****

同义反复

Too easy, right?

我想你现在明白了,但是如果我们有两个以上的输入呢?

或具有 3 个输入的功能

让我们通过观察一个 3 输入或功能 M-P 单元来概括这一点。在这种情况下,可能的输入是 8 个点— (0,0,0),(0,0,1),(1,0,0),(1,0,1),…你得到了点。我们可以将这些绘制在 3D 图上,这次我们绘制一个三维的决策边界。

“是一只鸟吗?是飞机吗?”

没错,是飞机!

满足判定边界方程 x_1 + x_2 + x_3 = 1 的*面如下所示:

慢慢来,通过查看上面的图来说服自己,当通过 or 函数 M-P 单元时,位于该*面上或上方(正半空间)的所有点将产生输出 1,而位于该*面下方(负半空间)的所有点将产生输出 0。

仅通过手工编码阈值参数,M-P 神经元就能够方便地表示线性可分的布尔函数。

线性可分性(用于布尔函数):存在一条线(*面),使得产生 1 的所有输入位于该线(*面)的一侧,产生 0 的所有输入位于该线(*面)的另一侧。

M-P 神经元的局限性

  • 非布尔(比如说,实数)输入呢?
  • 我们总是需要手工编码阈值吗?
  • 所有的投入都是相等的吗?如果我们想赋予一些输入更多的重要性呢?
  • 不是线性可分的函数呢?说 XOR 函数。

我希望现在清楚了为什么我们今天不使用 M-P 神经元。1958 年,美国心理学家弗兰克·罗森布拉特克服了 M-P 神经元的局限性,提出了经典的感知模型——强大的人工神经元。它是比麦卡洛克-皮茨神经元更一般化的计算模型,其中权重和阈值可以随着时间的推移而学习。

更多关于感知器以及它如何学习权重和阈值等。在我以后的帖子里。**

结论

在这篇文章中,我们简要地看了一下生物神经元。然后我们建立了 MuCulloch-Pitts 神经元的概念,这是第一个生物神经元的数学模型。我们用 M-P 神经元表示了一系列布尔函数。我们还试图通过 3D 绘图获得模型的几何直觉。最后,我们还建立了一个更一般化模型的动机,唯一的人工神经元/感知器模型。**

感谢您阅读文章。
自己活也让别人活!

通过简单的计算测量两个单词之间的距离

原文:https://towardsdatascience.com/measure-distance-between-2-words-by-simple-calculation-a97cf4993305?source=collection_archive---------2-----------------------

“brown rail train” by Johannes Plenio on Unsplash

在 NLP 中计算单词距离是一项常规任务。每当你想找到最*的单词或度量标准时,单词距离是实现它的方法之一。

在我之前的项目中,从 OCR 结果中识别目标信号是关键部分。为了获取更多有价值的信息,我必须容忍 OCR 结果中的微小误差。否则,我会错过许多重要的信号。

与之前的单词嵌入之间的距离不同,字符串距离是计算从一个单词改变到另一个单词所需的删除、插入或替换的最小数量。有许多方法来计算距离,而我在这次分享中将集中于两个测量。

看完这篇文章,你会明白:

  • 莱文斯坦距离
  • 最长公共子序列距离
  • 拿走

莱文斯坦距离

“black electrical tower” by Shane Rounce on Unsplash

这种方法是 Vladimir Levenshtein 在 1965 年发明的。该值指的是从一个单词转换到另一个单词所需的最小动作数(删除、插入和替换)。

From https://en.wikipedia.org/wiki/Levenshtein_distance

为了计算 Levenshtein 距离,我们必须遍历每一个单词,并使用来自

  • (i-1,j):表示左框(删除)
  • (I,j-1):表示上盒(插入)
  • (i-1,j-1):表示左上框(替换)

在下面的例子中,我将把“edward”转换成“edwin ”,并计算 Levenshtein 距离。

第一步:从 0 到两个单词对应的数字

第二步:由于“e”等于“e”,所以值为 0

第三步:“d”不等于“e”,所以从左(删除)、对角线(替换)、上(插入)求最小数。所以是 0 + 1 = 1

第 4 步:对下面一行重复第 3 步

第五步:“e”不等于“d”,所以从左(删除)、对角线(替换)、上(插入)求最小数。所以是 0 + 1 = 1

第六步:因为“d”等于“d”,所以复制对角线值为 0

第 7 步:对下面一行重复第 3 步

步骤 8:对盒子的其余部分重复步骤 3

步骤 9: Levenshtein 距离是 3(用红色突出显示),这是这个矩阵的最后一个

步骤 10:之后,e 可以向左(删除)或对角(替换),因为两个值都是 2。这次我选对角线。

步骤 11:同样,我们可以向左(删除)或对角(替换),因为两个值相同,都是 1。这次我选对角线。

第 12 步:这一次,最小值是 0(删除)

根据上面的公式,我们通过以下操作将“edward”转换为“edwin”

  1. 用“d”代替“n”
  2. 用“r”代替“I”
  3. 删除“a”
import editdistancedata = ['edward', 'Edward']for record in data:
    dist = editdistance.eval(record, 'edwin')
    print('Edit Distance for %s and %s is %d' % (record, 'edwin', dist))

输出

Edit Distance for edward and edwin is 3
Edit Distance for Edward and edwin is 4

最长公共子序列距离

简而言之,这是 LCS 距离。它与 Levenshtein 距离非常相似,只是 LCS 不包括替换操作。

因此,将“edward”转换为“edwin”时,该值为 5。操作是删除“a”、“r”、“d”,插入“I”和“n”。

拿走

要访问项目模板,您可以访问这个 github repo。

  • 编辑距离是一种简单有效的测量两个单词之间换位的方式。
  • 这是区分大小写
  • 编辑距离可以应用于纠正拼写错误或 OCR 错误
  • 在我这里,容差误差是 2 。如果真正的标签是“edward”,如果是“edweed”,我还是会接受 OCR 结果。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和*台相关领域的最新发展。你可以通过媒体博客、 LinkedIn 或 Github 联系我。

参考

克里斯托弗 D. M .、普拉巴卡尔 r .、欣里奇 S. 信息检索导论。

利用文本网络分析测量话语偏见

原文:https://towardsdatascience.com/measuring-discourse-bias-using-text-network-analysis-9f251be5f6f3?source=collection_archive---------7-----------------------

在这篇文章中,我提出了一种基于文本网络分析的方法和工具来衡量话语中的偏见水*。该度量基于文本的结构,并使用文本图的定量和定性参数来识别其有多强的偏向性。因此,它可以被人类使用,也可以被实现到各种 API 和 AI 中,以执行自动偏差分析。

偏见:好的和坏的

偏见通常被理解为对某种观点的倾向或偏见。有偏见的话语或文本可能有特定的议程或促进特定的意识形态。

在“假新闻”、极端意识形态和各种错误信息技术兴起的时代,重要的是能够识别话语中的偏见程度:无论是社交网络帖子、报纸文章还是政治演讲。

偏见不一定是坏事。有时,它可以使一个意图变得更强,推进一个议程,提出一个观点,说服,劝阻和转变。偏见是变革的动力,然而,当偏见太多的时候,它也可能是破坏性的。当我们衡量偏见时,我们衡量的是一篇文章在意识形态上有多强烈,它有多想提出某种观点。在某些情况下——比如小说或高度激烈的政治演讲——强烈的偏见可能更受青睐。在其他一些情况下——比如新闻和非小说——强烈的偏见可能揭示了一个议程。

目前还没有工具可以测量一篇文章的倾向性。各种文本挖掘 API根据文本的内容和情感对文本进行分类,但没有任何仪器可以测量文本中对某个观点的倾向程度。本文提出的工具和方法可以作为这方面的第一步。我开发的用于文本网络分析的开源在线工具已经可以基于这种方法测量偏见,所以欢迎你在你自己的文本上尝试一下,看看它是如何工作的。下面我描述了偏向指数的工作原理和一些技术细节。

作为动态网络的话语结构

任何话语都可以表示为一个网络:单词是节点,它们的共现是它们之间的连接。由此产生的图表描绘了意义循环的路径。我们可以通过将连接更紧密的节点群集(force-atlas 算法)排列成用特定颜色标记的不同组来使其更具可读性。我们还可以使图中更有影响力的节点变大(具有高介数中心性的节点)。你可以在这篇关于文本网络分析的白皮书中了解更多技术细节。

例如,这里有一个由 Julian Treasure 制作的 TED 演讲的可视化,名为“如何说话让人们愿意听”用这种方法制作。如果你有兴趣看实际的交互图,你可以在这里打开它。

从这个图表中,我们可以清楚地看到,主要的概念是

“人”、“时间”、“世界”、“听”、“声音”等。

这些概念是特定话语中意义循环的连接点。它们连接不同的节点社区(用不同的颜色表示)。

该算法以模拟人类感知的方式工作(遵循横向阅读模型,语义启动的思想,也是常识):如果单词在同一上下文中被频繁提及,它们将在图中形成一个社区。如果它们出现在不同的语境中,就会被彼此推开。如果单词经常被用来连接不同的上下文,它们在图表中会显得更大。

因此,一个文本网络图的结构可以告诉我们很多关于话语结构的信息。

例如,如果图形具有明显的社区结构(几个不同的单词社区),则话语也具有几个不同的主题,这些主题在文本中表达。在我们的示例中,我们至少有 4 个主要主题:

人—听—说(深绿色)
时间—说话—登记(浅绿色)
世界—声音—有力(橙色)
惊艳—声音(粉色)

如果我们以同样的方式分析其他文本,我们会看到产生的图形结构是不同的。例如,这是《夸兰》第一章的图像:

Text network visualization of Quaran made using InfraNodus. The structure of the graph is less diversified and more centralized. There are only a few main concepts, the discourse circulates around them, the rest of the text supports the main concepts.

可以看出它具有不同的网络结构。它更集中,更不多样化。有几个主要概念:

“神”、“人”、“信”、“主”、“给”

整个论述围绕着这些概念展开。所有其他观点都是为了支持主要观点。

我们对 1969 年至 2013 年美国总统的就职演说进行了类似的分析,并可视化了他们的叙事随时间变化的方式:

Visualization of the US presidents’ inauguration speeches made using InfraNodus (TNA) and Gephi (visualization). It can be seen that over time the structure stays more or less the same, however, Obama’s speeches seem to have more distinct influential terms, indicating a more diversified discourse.

可以看出,虽然这些年来话语的结构或多或少保持不变,但每次演讲所强调的概念都发生了变化。这可能表明修辞策略保持不变,而内容多年来发生了变化。奥巴马的演讲似乎具有更高数量的明显有影响力的节点,这可能表明话语更加多元化。

偏见是网络中意识形态的管道

既然我们已经展示了如何将话语表现为一个网络结构,我们可以在网络科学的背景下讨论偏见的概念。我们将使用一些流行病学的概念来演示网络的拓扑结构如何影响信息在节点间的传播速度。

一个网络可以被看作是一段时间内发生的相互作用的表现,一个动态过程留下的轨迹图。如果我们研究一个网络的拓扑结构,我们可以得到许多关于它所代表的动态过程的本质的见解。

在社会科学和医疗保健的背景下,关于网络结构的信息可以为流行病学提供有价值的见解:疾病(病毒、观点或任何其他(错误)信息)传播的速度,传播的距离,最佳免疫策略可能是什么。

已经论证(艾布拉姆森&库伯曼 2001;pastorras&Vespignani 2001)认为,随着网络结构变得更加随机化,其流行病学阈值降低。疾病、病毒、错误信息可以传播得更快,传播到更多的节点。换句话说,随着网络的社区结构越来越不明显,连接的数量增加,网络将信息传播到更多的节点,并且这种传播以非常明显的振荡(感染/未感染)发生。

A figure from the study by Abramson & Kuperman (2001) where they have shown the fraction of infected elements (n) in relation to time (t) for networks with a different degree of disorder (p). The higher the degree of disorder, the more elements get infected, the oscillations get more and more intensified,, but also the time-span of the infection is relatively short.

与此同时,当网络相对互联(小世界网络)时,社区结构明显,节点的“口袋”有助于在网络中更长时间地维持流行病。换句话说,较少的节点可能被感染,但是感染可能持续更长时间(流行状态)。

Representation of network structures: [a] random, [b] scale-free (better pronounced communities) and, [c] hierarchical (less global connectivity) (from Stocker et al. 2001)

在对各种社会网络进行的另一项研究中(斯托克,考恩福斯&博索迈尔 2002 )表明,等级扁*网络(即无序网络)不如无标度网络(即具有更明显社区结构的网络)稳定。换句话说,等级制度可能有利于传递秩序,但无尺度结构更有利于维持某种世界观。

正如我们所看到的,没有一种网络拓扑可以被认为是优先的。事实上,这取决于意图、背景和情况。在某些情况下,如果一个网络能够相对快速地将信息传播到它的所有元素,这可能是件好事。在其他一些情况下,稳定性可能更优先。

总的来说,一个网络的拓扑结构反映了它传播信息的能力,它对新思想的敏感度,新思想是会在短时间内占据整个网络还是会持续更长时间。

当我们研究偏见时,可以采用同样的方法。这里的假设是话语网络是一种传播思想的结构。

如果话语结构以几个有影响力的节点为中心,并且没有明显的社区结构,这意味着话语相当同质,这些节点周围的想法会比外围的想法传播得更好。我们把这样的话语称为有偏见的

另一方面,如果话语网络由几个不同的词/节点社区(无标度小世界网络)组成,这意味着文本中有几个不同的主题,每个主题在话语中被赋予同等的重要性。我们称这样的话语多样化

网络社区结构不仅可以使用图形可视化进行定性识别,还可以通过模块性测量进行识别(参见 Blondel et al 2008 )。模块化程度越高(通常在 0.4 以上),社群结构越明显。

另一个重要的标准是影响力(通过最有影响力的词/节点)在不同社区的分布。为了使话语多样化,最有影响力的节点应该分布在不同的社区之间。我们使用来衡量图中影响的分散程度,并在确定偏差水*时考虑到这一点。我们还检查顶部社区是否包括不成比例的高数量的节点,在这种情况下,多样化分数降低,并且图中的组件数量减少。

因此,我们可以确定我们可以用三个主要标准来确定话语中的偏见程度:

  • 社区结构:它们的不同程度以及属于顶级社区的节点的百分比;
  • 影响力分布:最具影响力的节点/词如何在不同话题/图社区间传播;
  • 图形组件数量:话语的连接程度;

基于语篇结构的倾向性指数

基于上述命题和标准,我们提出了偏倚指数,该指数考虑了语篇结构,具有四个主要参数:

  • 分散(非偏置)
  • 多样化(局部偏向)
  • 聚焦(略偏)
  • 偏置(高度偏置)

第一个价值,分散的,是一个具有高度显著的社区结构(几个不同的主题)的话语,这些社区结构没有很好的联系或者有几个组成部分(因此没有偏见)。我们的测试表明,这种图表通常用于诗歌、个人笔记、精神分裂症患者的推文以及其他各种创造性活动。例如,下面是拜伦的诗《黑暗》(你也可以查看 InfraNodus 上的交互图):

Visualization of Lord Byron’s “Darkness” made using InfraNodus. The discourse structure is identified as Dispersed (see the Analytics pane to the right) because of the high modularity (0.68) and high influence dispersal (the most influential words are spread among the different communities and only 14% of the words are in the top community).

正如我们从图表中看到的,它在视觉上非常稀疏,我们的工具已经将话语结构识别为分散的,因为模块性度量非常高(发音为社区/主题),并且有影响力的节点/词在主要主题中分布非常均匀(80%的分散,顶部社区/主题中只有 14%的词)。如果你阅读这首诗本身,你会发现它有相当丰富的词汇,它唤起了许多不同的形象,而不是试图推动一个特定的议程(也许只是通过诗歌,而不是修辞手段)。

下一个价值,多样化,是一个话语,有一个明显的社区结构,但那里的社区联系良好。通常它表示一种反映几种不同观点的话语,并在全球层面上给予它们或多或少的*等地位(地方偏见)。许多旨在提出若干观点的文章和谈话、研究笔记、报纸标题(取自各种来源)和非小说类文章都有这种结构。例如,这是 2018 年 10 月 4 日的新闻标题(带预告)的可视化效果(请参见此处的交互式可视化效果):

Visualization of the news headlines and teasers (via RSS) made using InfraNodus for the 4th of October 2018 taken from NYT, WSJ, FT, The Guardian and Washington Post. As we can see the selection of news is ranked as Diversified as the modularity measure is relatively high and yet the topics are also connected to each other. The most influential words are spread among the main topical clusters / communities, which indicates that the selection of news was quite diverse.

我们可以看到,话语结构被归类为多样化,这意味着在这个话语中有几个不同的主题,但它们在全球层面上是联系在一起的。

第三个值,聚焦,表示话语对某个主题有软偏向。这通常意味着话语提出了几个观点,但只关注一个,并进一步发展。具有聚焦分数的话语结构是报纸文章、散文、报告的特征,其被设计来提供对某一观点的清晰和简明的表达。例如,下面是本文前三部分的可视化:

The previous three sections of this article visualized as a text graph using InfraNodus. We can see that the discourse structure is ranked as Focused, indicating a slight bias. The community structure is present, but they are not very distinct. Almost all the most influential words are concentrated in one community / topic: “network / structure / discourse” and then there’s a smaller topic with “text / bias / measure”.

最后,第四种类型的话语结构是偏向的,这是具有低社区结构或没有社区结构的文本的特征。主要观点集中在一起,文中使用的所有其他概念都是为了支持主要议程。这种话语结构通常可以在高度意识形态化的文本、政治演讲以及任何其他文本中观察到,它们诉诸修辞来说服人们采取行动。例如,这里有一个***宣言的可视化:

Text network visualization of the Communist Manifesto made using InfraNodus. The community structure is not pronounced and the most influential words belong to the two main topics and are highly interconnected. The rest of the discourse is subjugated towards the main agenda (class struggle).

编后记

在这篇文章中,我提出了一种基于文本网络可视化结构和从图形分析中获得的各种参数的话语偏见的测量方法。

重要的是要注意,我并不声称(还)我提出的命题是科学合理的。对一个更大的数据语料库的全面研究正在进行中(欢迎你加入)。

我的经验表明,这个索引在研究文本时非常有用,并且已经作为一个工作特性在 InfraNodus 文本网络分析和可视化工具中实现。

因此,我邀请您亲自尝试一下,并将您可能有的任何反馈、建议和提议发送给我。请不要客气,在这里留下任何评论,我很想知道你的想法和我们如何进一步发展它。InfraNodus 是一个开源工具,所以非常欢迎你加入并实现你作为一个代码可能有的任何主张。

Dmitry Paranyushkin 是拥有Nodus Labs的研究员,也是文字网络可视化工具InfraNodus的创造者。

你可以通过@ Nodus Labs或通过Nodus Labs关注我并联系我。

测量模型的良好性—第 1 部分

原文:https://towardsdatascience.com/measuring-model-goodness-part-1-a24ed4d62f71?source=collection_archive---------11-----------------------

你的模型有多好并不重要。一点也不。朱莉娅·埃文斯

数据和人工智能正在改变世界各地的商业,从金融、制造和零售到医疗保健、电信和教育。这种转变的核心是将原始数据转化为信息和有用的、可操作的见解的能力。这就是数据科学和机器学习的用武之地。

Machine Learning [Source]

上面的方法虽然滑稽,但肯定是构建机器学习系统的一种方式。然而,如果它需要良好和可靠,我们应该更有条理一点:

  • 了解业务需求
  • 获取和处理相关数据
  • 准确地表述问题
  • 使用正确的机器学习算法构建模型
  • 评估模型,以及
  • 在最终部署之前,验证现实世界中的性能

整个过程被记录为微软的团队数据科学过程(TDSP) ,如下图所示。

TDSP [source]

这篇文章是由两部分组成的系列文章的一部分,主要关注模型的良好性,特别是量化商业价值和转换典型的机器学习性能指标(如精度、召回率、RMSE 等)。)到业务指标。这是模型在现实世界中被验证和接受的典型方式。在上图中,流程的相关阶段以红色突出显示。度量模型的良好性还包括将模型性能与合理的基线进行比较,这也将在本文中讨论。为了说明所有这一切,将考察两大类机器学习问题:

  • 分类:包含在第 1 部分中
  • 回归:包含在第二部分(2018 年 9 月 4 日更新)

分类

分类是预测定性或分类反应的过程[ 来源 ]。这是一种受监督的机器学习技术,它将新的观察结果分类到一组离散的类别中。这是基于包含已知类别的观察值的训练数据来完成的。分类问题可以是有两个目标类别的二元或有两个以上互斥目标类别的多类

A Binary Classification Problem

在这篇文章中,我将以乳腺癌检测为例来研究二元分类问题。我将使用威斯康星开放乳腺癌数据集进行建模和评估。下面讨论的技术可以很容易地扩展到其他二元和多类分类问题。所有用于构建和评估模型的源代码都可以在 Github 这里找到。

让我们首先了解业务上下文和数据。乳腺癌是女性最常见的癌症,也是女性癌症死亡的主要原因[ 来源 ]。癌症类型的早期检测——无论是良性还是恶性——可以通过选择适当的治疗策略来帮助挽救生命。在该数据集中,总共有 569 个病例,其中 357 个是良性的(62.6%),212 个是恶性的(37.4%)。总共有 30 个特征,是从乳腺肿块活检的数字化图像计算出来的。这些特征描述了细胞核的特征,如半径、纹理、周长、光滑度等。癌症类型的检测目前由放射科医师完成,这是耗时的,并且商业需求是加速诊断过程,以便可以尽早开始适当的治疗。在深入建模阶段之前,我们需要了解做出正确/错误预测的价值/成本。该信息可以使用如下所示的价值-成本矩阵来表示:

矩阵中的行表示实际类别,列表示预测类别。第一行/列代表阴性类别(在这种情况下为良性),第二行/列代表阳性类别(在这种情况下为恶性)。以下是矩阵中每个元素所代表的含义:

  • 第 0 行,第 0 列:正确预测负类的值
  • 第 0 行,第 1 列:错误预测正类的成本
  • 第 1 行,第 0 列:错误预测负类的成本
  • 第 1 行,第 1 列:正确预测正类的值

对于乳腺癌检测,我们可以将价值-成本矩阵定义如下:

  • 正确检测良性和恶性病例具有同等的积极价值。尽管恶性肿瘤对患者来说是最糟糕的情况,但目标是早期诊断,开始治疗并治愈这两种类型的癌症。因此,从治疗的角度来看,准确检测这两种情况具有同等的价值。
  • 将恶性病例标记为良性(假阴性)的成本比将良性病例标记为恶性(假阳性)的成本要高得多。因此,假阴性的成本为-4,假阳性的成本为-2。

另一个业务需求是尽可能多地自动化流程。做到这一点的一种方式是使用机器学习模型作为过滤器,以自动检测较简单的良性病例,并且仅标记可能的恶性病例供放射科医师查看。如下图所示。我们可以通过查看需要手工评审的 %的案例(在图中表示为 x )来量化这个业务需求。理想情况下,我们希望一切都自动化,而不需要人参与。这意味着模型应该具有 100%的准确性,并且 x 应该等于正类的实际比例。

正确量化业务需求后,下一步是定义合理的基线来比较我们的模型。

  • 基线 1:随机决定癌症类型是良性还是恶性的随机分类器。
  • 基线 2:多数类分类器,总是挑选多数类。在这种情况下,多数阶级是良性的。如果这些阶层高度不*衡,这种策略会更有意义。

我们可以添加第三个基准,这是放射科医师或企业当前部署的任何其他模型的性能。但是在这个例子中,这个信息是未知的,所以这个基线被删除了。

现在是构建模型的有趣部分。我将在这里掩饰很多细节,因为可能需要一整篇文章来进行探索性分析、建模技术和最佳实践。我使用了一个由特征缩放器、用于特征缩减的 PCA 和最后的随机森林(RF)分类器组成的流水线。进行 5 重交叉验证和网格搜索以确定最佳超参数。完整的源代码可以在这里找到。

一旦模型被训练,下一步就是评估它们。有各种各样的性能指标可以使用,但在这篇文章中,我将回顾以下 6 个指标,因为它们很容易解释、可视化并转化为业务指标。

  • 真阳性(TP) / 真阳性率(TPR) :假设实际类别为阳性,正确的阳性预测数/预测为阳性的概率
  • 假阴性(FN) / 假阴性率(FNR) :假设实际类别为阳性,则错误的阴性预测数/预测为阴性的概率
  • 真阴性(TN) / 真阴性率(TNR) :假设实际类别为阴性,则正确的阴性预测数/预测为阴性的概率
  • 假阳性(FP) / 假阳性率(FPR) :假设实际类别为阴性,则错误阳性预测的数量/预测阳性的概率
  • 精度(P) :预测阳性正确的比例
  • Recall (R) :实际捕获的阳性比例

所有这些指标都是相互关联的。使用 ROC 曲线和混淆矩阵可以很容易地看到前四个。最后两个可以使用精确回忆 (PR)曲线来可视化。让我们首先使用 ROC 和 PR 曲线来可视化模型和基线的性能。

两个图都显示了使用各种阈值来确定正类和负类的模型的性能。可以看出,RF 分类器在各个方面都优于基线。一旦选择了合适的阈值,我们就可以绘制标准化的混淆矩阵,如下所示。这些矩阵显示了给定实际值时预测值的条件概率。我们可以看到基线表现很差,特别是在预测阳性类别时,假阴性率很高。另一方面,RF 分类器似乎获得了更多的正面和负面类别预测,达到了 93%的 TPR 和 97%的 TNR。

既然我们已经确定新的射频模型优于基线,我们仍然需要确保它符合我们的业务目标。即高的正业务价值和更少的手动审查案例。因此,我们需要将上述性能指标转化为以下内容:

  • 模型的总预期价值/成本
  • 需要手动审查的案例百分比

第一个业务指标可以通过取展*的混淆矩阵(通过样本总数标准化, S )与展*的价值成本矩阵的点积来计算。如下所示。

注意 S 是一个标量,等于 TN + FP + FN + TP。期望值实质上是价值/成本的加权*均值,其中权重是预测正类和负类的概率[ 来源。

第二个业务指标可以使用 precision 和 recall 来计算,如下所示。

正类率是从用于评估模型的数据,即测试集得知的。根据业务需求,我们需要决定我们必须准确确定多少正类,即召回。如果我们想检测出所有的阳性病例,目标召回率应该是 100%。然后,我们可以从 PR 曲线中找到相应的精度(和阈值)。对于具有 100%精度和召回率的理想模型,要检查的正面案例的比例将等于实际的正面分类率。这意味着理论上我们可以实现 100%的自动化。

接下来的两个图显示了根据两个关键业务度量对模型良好性的最终评估。

观察结果:

  • 由于高假阴性,两种基线模型都有相当大的成本。随机森林分类器通过获得大量正确的正反例而具有良好的正价值。
  • 对于乳腺癌检测的情况,我们希望捕获所有阳性/恶性病例,即 100%召回。在这个例子中,着眼于 50%或 75%的召回是没有意义的,因为不治疗恶性病例的成本很高。对于其他二元分类问题,例如欺诈检测,只要模型能够标记出高成本节约的欺诈案例,较低的召回率可能是可以接受的。无论如何,我们可以看到随机森林分类器在自动化方面也优于基线。为了捕获 100%的恶性病例,放射科医师只需要检查所有病例的大约 50%,即 13%的额外假阳性,而他/她必须使用基线模型检查几乎所有的病例。

总之,本系列的第一部分已经从业务的角度考察了度量模型的良好性,特别是考察了分类类型的问题。关于这个主题的更多细节,下面的书是很好的参考。在本系列的第二部分也是最后一部分中,我将介绍回归,这需要查看稍微不同的度量标准。

进一步阅读

  • 统计学习的要素,作者 Trevor Hastie,Robert Tibshirani,Jerome Friedman
  • 福斯特·普罗沃斯特和汤姆·福西特的《商业数据科学》
  • 用 Scikit-Learn 和 Tensorflow 进行机器实践学习,作者 Aurélien Géron

这是回归系列的第二部分。

这是从 MSDN 数据洞察博客 这里 交叉发布的。

测量行人可达性

原文:https://towardsdatascience.com/measuring-pedestrian-accessibility-97900f9e4d56?source=collection_archive---------11-----------------------

适宜步行的社区有利于健康、幸福和经济增长。世界各地想要吸引有才华的年轻劳动力的城市越来越注重创造良好的步行体验。我们如何使用数据科学工具来测量和绘制步行性?

这篇博客提出了一种借鉴 Pandana(由 Fletcher Foti 开发的优秀 Python 库)的方法。

这能回答什么问题?

我们将处理沿道路网络的邻*分析。测量商店、办公室和公交车站等设施的密度“直线距离”是微不足道的;密度图可以在地理信息系统软件中制作。但是,如何绘制从城市的每个部分到最*的设施的步行或开车时间呢?或者更好的是,回答诸如“大多数日常差事可以步行完成吗?”为此,我们需要网络约束距离:沿着城市街道到达目的地的米数。

第一步:创建街道网络对象

网络数学的一个分支,图论,是由 Leonard Euler 在试图模拟穿过 Konigsburg 七座桥的路线时发展起来的。我们可以使用相同的节点(在我们的例子中是街道交叉口)和边(街道)术语来模拟道路网络。

由于几位研究人员,特别是 Foti 和 Geoff Boeing,创建了将 OpenStreetMap (OSM)道路转换为有效图形对象的自动化方法,Python 中的道路网络分析变得更加容易。他们的工具 Pandana 和 OSMNx 都通过像删除不代表实际交叉点的点这样的步骤下载和清理 OSM 道路数据(因此在图论意义上不是节点)。

让我们来看看摩洛哥卡萨布兰卡的街道网络:

Network object for central Casablanca

第二步:定位感兴趣的对象

比方说,我们正在开发一个医疗保健项目,希望了解哪些社区缺少获得初级医疗服务的诊所。我们需要所有这些地点的列表,以及它们的位置。让我们列出诊所以及其他一些感兴趣的对象:

Points of interest downloaded from OpenStreetMap for Casablanca (first five records)

Number of POIs by category, downloaded from OSM

第三步:计算距离

这就是用 Python 进行地理分析真正出彩的地方,而不是坐在 GIS 包前。Pandana 是为速度而生的。首先,我们将传递给它一个最大搜索距离。这是加快未来查询速度的关键一步:Pandana 将建立一个网络的精简表示(用 C++实现),允许在每个节点的定义半径内进行快速计算。我们将构建一个从几个交叉点到最*的 5 个兴趣点的距离表。

Distance in meters to five nearest amenities (two sample intersections).

这样,不同选定设施的无障碍分析可以在一秒钟内完成。(在引擎盖下,两种算法使这成为可能:收缩层次结构和 kd 树。)

第四:制作无障碍地图

接下来,我们可以制作可达性地图。让我们做一些!

正如你所看到的,有些区域你必须步行 2 公里以上才能到达最*的学校,而卡萨布兰卡市中心的*均步行距离不到 400 米。

不过,这只是针对学校的。我们可以为诊所、银行或其他在 OSM 标记的设施画出同样的图。

但是什么抓住了“可步行性”的整体概念呢?对我来说,这又回到了“我能步行完成大多数日常任务吗”的问题。解开什么是最有资格的日常任务是一个复杂的问题:我们可以根据生活设施对日常生活的重要性建立一个加权指数(例如,获得医疗保健比获得夜生活更重要);或者我们可以使用人们最常去的娱乐设施的经验数据。

不管怎样,我们使用 Pandana 的工作流程解决了这个问题。简单地列出你感兴趣的事物,并为它们建立一个加权指数。事实上,WalkScore 公司使用了类似的方法来提供美国各地社区质量的基准(你可以在浏览 Zillow 时看到)。

可访问性分数可以很快地被构建来回答一个给定的问题:是获得基本服务,还是吸引年轻工作者的适合步行的社区。现在,让我们*等地衡量所有的便利设施,并想象到第五个最*的便利设施的距离。

plot_nearest_amenity('all',5)

从网络距离到步行时间

让我们为第二个城市做同样的输出:明尼阿波利斯-圣保罗。(那里的人很好,网格状的街道也很直观。)

在这里,我们看到绘制一个可达性的复合测量值(到第五个最*设施的距离)比只绘制到单一最*文化设施(咖啡馆、餐馆或学校)的距离更清楚地显示了哪些社区最适合步行。

为了使结果更易于解释,让我们在道路网络后面构建一个 250 *方米的像元网格,将每个像元连接到其最*的节点,并将距离转换为步行、驾驶或公共交通时间。明尼阿波利斯不是一个非常适合步行的城市,尽管一些市中心街区的情况不错。

Minneapolis: Minutes walk to fifth-nearest amenity

扩展ˌ扩张

这里使用的图书馆是作为加州大学伯克利分校 UrbanSIM 项目的一部分开发的,支持一系列城市规划和房地产用例。可以使用高质量的本地生成的 GIS 数据来代替 OSM(这确实是更好的选择)。

一个重要的扩展:这种方法是房地产价格建模或建筑级预测模型的重要输入。举例来说,特征价格模型假设,购房者支付更多的钱来购买一栋可以方便地步行去星巴克或开车去医院的房子。将税收地块边界(或 OSM 建筑覆盖区)捕捉到网络,就像我们刚才将网格正方形附加到网络上一样,这使我们可以为任何给定的属性获取此数据。

同样,预测犯罪或火灾风险的机器学习模型需要尽可能多的属性来表征每栋建筑在城市结构中的位置。

通过这种框架的快速网络约束查询可以回答许多问题——从上面讨论的可步行性度量开始。

测量机器学习问题的“响应复杂性”

原文:https://towardsdatascience.com/measuring-response-complexity-of-a-machine-learning-problem-a2747b1ea0c6?source=collection_archive---------3-----------------------

没有人会认为加里·卡斯帕罗夫的智力比他的深蓝更复杂,或者李·塞多尔的智力比阿尔法·围棋更复杂。作为一个人,他们把他们大部分的智力用于日常生活。与他们的机器人克星相比,他们拥有不太专业但更复杂的智能。

由于人类大脑的复杂性,它需要花费最多的时间来发展。不太复杂的生物,像我们的宠物,需要更少的时间达到成熟,因为它们有更多的专业技能。蚊子,甚至更少。这一原则在自然和数学中也适用。一个专门的系统必须做出更少的决定才能达到最佳结果。

一个智能系统必然会随着每一项新技能的加入而变得更加复杂。然而随着复杂性的增加,误差也会增加。并且需要更多的训练实例来实现给定技能中的较低错误。

因此,当我们设计一个机器学习解决方案时,问题的复杂性将与你的解决方案的复杂性密切相关。有一些问题比如我的 CNN 应该有多少层?我需要多少训练样本才能达到一定的误差。

响应复杂度是一种计算方法,用于帮助理解给定带标签训练数据的问题的复杂度。

对于具有输入 N 和的一组训练数据,N 的可能输入数为,M 的可能输出数为,M 的可能输出数为,以及输出的方差,其中 n > = 1,m > = 1。

RC =(n—1)σ(m—1)

一些观察

  • 每增加一项技能,网络的复杂性就会增加
  • 如果输出的可能数量为 1,则复杂度为 0。
  • 如果输出的可能数量是无限的,但是方差是 0,那么复杂度是 0。
  • 如果输出的可能数量是无限的,并且输入的数量是 1。复杂度为 0。不可能有明智的反应。
  • 复杂度相对于 m 和 n 线性增加

离别的思绪

我的希望是,对于不同类别的反应,复杂性将表现出不同的最佳机器学习解决方案。例如,给定高于阈值 TRC ,最佳架构将是 CNN 的变体。对于响应复杂性较小的问题,更简单的解决方案会出现。如果我们能够对每个问题的复杂性进行分类,这将使开发者更容易构建 ML 解决方案,甚至机器也可以构建自己的解决方案。

反应复杂性的等式仍然是一个新的等式,我对变量之间的具体关系有许多疑问。我相信添加一个输出比添加一个输入会增加更多的复杂性,但是现在很难确定会增加多少。我应该*方输出吗?记录输入吗?有没有可能用一个等式来统一回归变量和分类器?这是对复杂性理论的调查和对机器学习算法的分析,希望我和其他人能够继续探索。

用 VC 维度量分类器的能力

原文:https://towardsdatascience.com/measuring-the-power-of-a-classifier-c765a7446c1c?source=collection_archive---------3-----------------------

用 VC 维度量算法的表达能力

为数据选择分类器时,一个显而易见的问题是“这个分类器可以分类什么类型的数据?”。例如,如果您知道您的点可以很容易地由一条直线分隔,您可能会选择简单的线性分类器,而如果您知道您的点将在许多独立的组中,您可能会选择更强大的分类器,如随机森林或多层感知器。这个基本问题可以使用分类器的 VC 维度来回答,这是计算学习理论中的一个概念,它正式量化了分类算法的能力。

分类器的 VC 维由 Vapnik 和 Chervonenkis 定义为分类算法可以粉碎 [ 1 的最大点集的基数(大小)。这似乎是一个简单的定义,但很容易被误解,所以我现在将在这里更详细地解释定义中的关键术语。为了简单起见,我们将使用 2-D 例子,但是这些想法推广到任何数量的维度。

打碎一组点

*面上的 N 点的配置就是 N 点的任意放置。为了使的 VC 维数至少为 N ,分类器必须能够粉碎 N 点的单个配置。为了粉碎点的配置,分类器必须能够针对点的正负的每一种可能的分配,完美地划分*面,使得正点与负点分离。对于一个有 N 个点的配置,有个 2^N 个可能的正或负赋值,因此分类器必须能够正确地分离每个点。

在下面的例子中,我们展示了线性分类器的 VC 维至少是 3,因为它可以粉碎这种 3 点的配置。在肯定和否定的 2 = 8 个可能赋值的每一个中,分类器能够完美地分离两个类别。

现在,我们表明线性分类器比 4 低。在这种 4 点配置中,分类器不能在至少一个赋值中分割正类和负类。在这种情况下,需要两条线来分隔这两个类。我们实际上需要证明不存在一个可以被粉碎的 4 点构型,但是同样的逻辑适用于其他构型,所以,为了简洁起见,这个例子已经足够好了。

既然我们现在已经表明线性分类器的 VC 维数是至少是 3,并且低于 4,我们可以最终得出结论,它的 VC 维数是正好是 3。再次记住,为了有一个 VC 维度为 N ,分类器必须只粉碎N 个点的单个配置——可能会有许多分类器不能粉碎的 N 个点的其他配置。

VC 维的应用

既然你已经知道什么是风险资本维度,以及如何找到它,那么理解它的实际含义也是很重要的。在大多数情况下,一个分类器的确切 VC 维并不重要。更确切地说,它更多地用于根据算法的复杂性对不同类型的算法进行分类;例如,简单分类器类可以包括基本形状,如直线、圆形或矩形,而复杂分类器类可以包括诸如多层感知器、提升树或其他非线性分类器的分类器。分类算法的复杂度与其 VC 维直接相关,与偏差和方差之间的权衡相关。

在这张图片中,我们看到了模型复杂性的影响。在底部,每个 S_i 代表一组在 VC 维度或复杂度上相似的模型。在上图中,VC 尺寸在 x 轴上测量为 h 。观察到随着复杂性的增加,你从适应不足过渡到适应过度;增加复杂性直到某一点都是好的,在这之后,你开始过度适应训练数据。

另一种思考方式是通过偏差和方差。低复杂度模型将具有高偏差和低方差;虽然它的表达能力低,导致高偏差,但它也非常简单,因此它具有非常可预测的性能,导致低方差。相反,复杂的模型将具有较低的偏差,因为它具有更多的表达能力,但是将具有较高的方差,因为基于样本训练数据有更多的参数要调整。通常,具有较高 VC 维度的模型将需要更多的训练数据来正确训练,但将能够识别数据中更复杂的关系。

在模型的某种复杂程度上,偏差和方差之间会存在一个理想的*衡,用垂直虚线表示,在这个水*上,你对你的数据既不会欠拟合也不会过拟合。换句话说,你应该选择一个分类器,它的复杂程度对于你的分类任务来说刚好足够——少了会导致欠拟合,多了会导致过拟合。

区块链安全机制

原文:https://towardsdatascience.com/mechanisms-securing-blockchain-data-9e762513ae28?source=collection_archive---------5-----------------------

密码哈希和 Merkle 树保持了公共和私有区块链数据的完整性。

密码散列法

哈希函数是网络安全和比特币等几种主要加密货币协议的重要组成部分。

什么是哈希?

哈希是一种加密方法,可以将任何形式的数据转换为唯一的文本字符串。任何数据都可以被散列,无论其大小或类型如何。在传统的散列法中,不管数据的大小、类型或长度如何,任何数据产生的散列总是相同的长度。哈希旨在充当单向函数,您可以将数据放入哈希算法并获得唯一的字符串,但如果您遇到新的哈希,您将无法破译它所代表的输入数据。一条唯一的数据将总是产生相同的散列。

它是如何工作的?

哈希是一种数学运算,易于执行,但极难逆转。(哈希和加密的区别在于,加密可以使用特定的密钥进行反转或解密。)最广泛使用的散列函数是 MD5、SHA1 和 SHA-256。一些散列过程比其他过程更难破解。例如,SHA1 比 bcrypt 更容易破解。

Some examples of data run through SHA1 hashes. The SHA1 hashes will always be the same for this data.

谁使用哈希算法?

普通用户每天都会遇到密码散列。例如,当您创建电子邮件地址和密码时,您的电子邮件提供商可能不会保存您的密码。相反,提供商通过哈希算法运行密码,并保存密码的哈希。每次您尝试登录您的电子邮件时,电子邮件提供商都会对您输入的密码进行哈希处理,并将该哈希与它保存的哈希进行比较。只有当两个哈希值匹配时,你才有权访问你的电子邮件。

加密货币中的散列法

在比特币区块链中,“挖掘”本质上是通过运行一系列 SHA-256 哈希函数来进行的。在今天的加密货币区块链中,散列被用于写入新的交易,给它们加时间戳,并最终在前一个块中添加对它们的引用。当一组交易被添加到区块链中,并且在不同节点的操作者之间达成共识(验证他们都具有整个分类帐的正确和真实版本)时,由于任何试图篡改区块链的人都需要巨大的计算能力,以及散列的单向性质,所以几乎不可能撤销交易。因此,哈希对于维护区块链的加密完整性至关重要。

哈希和网络安全

当一个组织发现一个*台的密码已经被破坏,这通常意味着黑客已经获得了代表密码的散列。然后,黑客运行常用词的散列和常用词与数字的组合来破译用户保存的一些密码。网络安全行业现在使用一种叫做“加盐”的机制。Salting 包括在哈希之前向密码添加随机数据,然后将“salt 值”与哈希一起存储。这一过程使得黑客更难使用预计算技术和破解他们获得的散列数据的密码。

The Merkle Root is derived from hashing each transaction pair in a block until it is down to a single hash.

Merkle 树

Merkle 树是区块链技术的基础部分。merkle 树是一种允许对大量数据中的内容进行高效和安全验证的结构。这种结构有助于验证数据的一致性和内容。比特币和以太坊都使用 Merkle 树。

Merkle 树是如何工作的?

Merkle 树通过产生整个事务集的数字指纹来汇总块中的所有事务,从而使用户能够验证块中是否包括事务。

Merkle 树是通过重复散列节点对直到只剩下一个散列(这个散列被称为根散列或 Merkle 根)来创建的。它们是自底向上构造的,由单个事务的散列(称为事务 id)构成。

每个叶节点是事务数据的散列,每个非叶节点是其先前散列的散列。Merkle 树是二进制的,因此需要偶数个叶节点。如果事务的数量是奇数,最后一个散列将被复制一次,以创建偶数个叶节点。

The Merkle Tree of transactions A, B, C & D.

让我们来看一个块中有四个事务的示例:A、B、C 和 D。每个事务都经过哈希处理,哈希存储在每个叶节点中,产生哈希 A、B、C 和 D。然后,连续的叶节点对在父节点中汇总,哈希 A 和哈希 B 产生哈希 AB,哈希 C 和哈希 D 分别产生哈希 CD。这两个散列(散列 AB 和散列 CD)然后被再次散列以产生根散列(Merkle 根)。

这个过程也可以在更大的数据集上进行:可以对连续的块进行哈希运算,直到顶部只有一个节点。哈希通常使用 SHA-2 加密哈希函数进行,尽管也可以使用其他函数。

Merkle 根汇总相关事务中的所有数据,并存储在块头中。它维护数据的完整性。如果任何事务中的一个细节或事务的顺序发生变化,Merkle Root 也会发生变化。使用 Merkle 树可以快速简单地测试特定交易是否包含在集合中。

The entire dataset doesn’t need to be downloaded to verify the integrity of Transaction 5.

Merkle 树与哈希表的不同之处在于,使用 Merkle 树,一次可以下载一个分支,并且可以立即验证每个分支的完整性,即使树的其余部分还不可用。这是有利的,因为文件可以被分割成非常小的数据块,使得如果原始版本被损坏,只需要再次下载小的数据块。

用途

使用 Merkle 树可以显著减少可信机构为了验证目的而必须维护的数据量。它将数据的验证与数据本身分开。Merkle 树可以位于本地,也可以位于分布式系统上。

Merkle 树有三大好处:

1.它们提供了一种证明数据完整性和有效性的方法

2.它们需要很少的内存或磁盘空间,因为证明在计算上是容易和快速的

3.他们的证明和管理只需要通过网络传输极少量的信息

证明日志完整且一致的能力对于区块链技术和总账概念至关重要。Merkle 树有助于验证日志的较新版本是否包含早期版本的所有内容,以及所有数据是否按时间顺序记录和显示。要证明日志是一致的,需要表明以前的记录没有被添加、更改或篡改,并且日志从未被分支或分叉。

Merkle 树使区块链的矿工和用户受益。当挖掘器从对等体接收事务时,挖掘器可以渐进地计算散列。用户可以单独验证块的各个部分,并且可以使用树的其他分支的散列来检查各个事务。

简化支付验证(SPV)

简化支付验证(SPV)是一种验证特定交易是否包含在一个块中而无需下载整个块的方法。Merkle 树被 SPV 节点广泛使用。

SPV 节点没有来自块中所有事务的数据。他们只下载块头。Merkle 树使区块链上的 SPV 节点能够检查挖掘者是否已经验证了块中的事务,而无需下载块中的所有事务。这种方法目前被一些轻量级的比特币客户端使用。

以太坊

以太坊在每个块中使用三个不同的 Merkle 根:

1.第一个根是块中的事务

2.第二个词根代表州

3.第三个词根是交易收据

以太坊使用一种特殊类型的哈希树,称为“ Merkle Patricia 树

区块链上不可或缺的工具

许可区块链等创新将进一步提高数据安全性和可访问性。在许可的区块链中,网络的参与者有能力限制谁可以参与区块链的共识机制。此外,许可区块链允许用户分配谁可以访问其数字身份数据的权限。

加密哈希技术长期以来一直在网络安全中发挥着作用,现在已经准备好为即将到来的区块链应用浪潮提供动力。Merkle 树对于区块链的矿工和用户来说是强大且不可或缺的工具。它们非常强大,是 BitTorrent、Git、比特币和以太坊等多个对等网络的核心。

沙恩雷

关注 Lansaar Research on Medium,了解最新的新兴技术和新的商业模式。

[## 沙恩·雷

来自 Shaan Ray 的最新推文(@ShaanRay)。创造新价值和探索新兴技术| ENTJ | #科学…

twitter.com](https://twitter.com/shaanray)

资源

在线哈希生成器。您可以在此处对您的数据运行 MD5、SHA1、SHA-256 和其他散列函数:

  • http://onlinemd5.com
  • http://www.sha1-online.com

默克尔帕特丽夏树:https://github.com/ethereum/wiki/wiki/Patricia-Tree

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

医学院

原文:https://towardsdatascience.com/medicai-school-2c885ad341dc?source=collection_archive---------7-----------------------

2017 年 4 月,我在自己的博客上写了这篇文章,当时我还没有从医学院毕业,还没有开始攻读博士学位。但是我把我所有的帖子都移到了 Medium,所以我在这里转贴。这在某种程度上是我的“我的编程和生物信息学之旅”系列的前传。我也不一定再百分百赞同了;但我坚持下去,因为有人可能会觉得它仍然有趣。

作为未来的医生,我们的教育有了显著的进步。我们在医学院学习的理论知识保持相对稳定,在某些情况下,甚至有所减少,而对自然和生物学的理解却在呈指数增长。

它的核心医学院几十年来没有太大的发展。它从 2-3 年的基础科学开始:(生物)化学,遗传学,解剖学,生理学,药理学等等。在接下来的几年里,这些概念被用于研究疾病的机制:心脏病学、胃肠病学、泌尿学、妇科。在这些有时令人难以置信的科目之间,学生还需要学习病人指导下的护理:沟通、询问病史和体检,不仅关注生物医学问题,还要从生物、心理和社会因素的角度将病人视为一个“整体”。其主要目标之一是整合所有这些知识,以做出准确的(鉴别)诊断。

神经网络

在慕克吉博士写的一篇文章中,医学院最基本的目标之一受到了一个叫做“神经网络”领域的进化的挑战。简单来说,这是一种类似大脑中神经元工作方式的计算策略。通过反复刺激,一些网络得到加强,另一些网络被削弱。摘自文章:

“就像机器使人类的肌肉变得强大一千倍一样,机器也将使人类的大脑变得强大一千倍。[Sebastian]Thrun[计算机科学家]坚持认为,这些深度学习设备不会取代皮肤科医生和放射科医生。他们将增加专业人员,为他们提供专业知识和帮助。”

未来的博士应该学什么?

如果医学诊断过程在 10-20 年内将严重依赖机器,我们需要开始思考我们希望未来的医生学习什么技能。我们需要了解这些技术的基础吗?我记得我学习了线性加速器如何工作的基础知识,核磁共振成像和 CT 机是基于什么概念,超声波机的物理学等等。理解神经网络意味着计算机科学的基础知识,这是当前课程严重缺乏的领域。与其他 STEM 项目相比,我们不学习如何编程或数学/高级统计,如果你想深入基础科学(例如攻读博士学位),这些领域变得越来越重要。下一代测序是一个最好的例子。当我在 2010 年开始接受教育时,人类基因组计划在 2003 年才完成 7 年。快进到另一个 7 年后,无细胞 DNA 是下一件大事。非侵入性妊娠试验已经成为常规的临床实践。循环肿瘤 DNA 正在彻底改变癌症的诊断和治疗。为了理解并从事这一领域的工作,生物信息学的基础知识是必不可少的——这是大多数刚毕业的医生所缺乏的技能(但说实话,大多数医学生不需要知道编程就能成为一名好医生)。

然而,想象一下 30 年后深度学习被整合到日常实践中。医生需要非常详细的病史(更多的数据意味着更准确的诊断),使用他的电子听诊器记录心音(解释心音是算法的任务),并将所有这些数据输入到“神秘盒子”中,以诊断他的病人。根据他病历中的所有参数(包括患者的基因组、转录组、甲基组和代谢组),神秘盒子为其提供最佳治疗建议。医生审核数据,按下“确认”,剩下的时间用来和患者沟通诊断和治疗方案。

另一种未来是,医生了解这个神秘盒子在引擎盖下做什么,准确指出它的优点和缺点,以进一步提高诊断的准确性。了解机器需要哪些数据来优化准确诊断的概率以及为什么。在理解神秘盒子之后,医疗从业者与病人交谈,支持他们,开始治疗,并密切关注可能的副作用。但是为了实现这样的未来,医学院的课程必须进行重大改革。

在编程、大数据分析、生物信息学和神经网络旁边教授内科学和通信的日子不会是明天,但在未来也不是不可想象的。

医学图像分割[第一部分] — UNet:交互式编码卷积网络

原文:https://towardsdatascience.com/medical-image-segmentation-part-1-unet-convolutional-networks-with-interactive-code-70f0f17f46c6?source=collection_archive---------0-----------------------

Gif from this website

最后,我开始了这个系列,医学图像分割。关于这个主题,我的第一篇文章是实现众所周知的体系结构,UNet。如果你想看原文,请点击这里。(或者我也把它链接到下面)。请注意,今天我觉得有点懒,只想使用自动微分。也许在不久的将来,我可以回来为这个网络做人工反向传播。

网络架构(图形/ OOP 形式)

这篇论文在解释网络体系结构方面做得非常出色。我们可以看到网络由卷积运算、最大池、、ReLU 激活、级联和上采样层组成。现在,我知道有些人可能对如何对原始图像进行上采样感到困惑,这可以通过使用转置卷积运算来实现。我不会深入讨论这个材料,但是这篇博文做了一件令人惊奇的工作,解释了我们如何使用它来上采样图像。还有,这里是我们可以使用的 Tensorflow API 。

红框 →代表 U 网左侧
蓝框 →代表 U 网右侧
绿框 →最终瓶颈层。

从实现的角度来看,它非常简单,只需要几个卷积层,再加上最大池和 ReLu()激活。

实验设置/与论文的差异

右图 →原图
中图 →地面真实二值蒙版
左图 →地面真实蒙版叠加原图

这个网络的实验设置非常简单,我们将使用 Kaggle Challenge 超声神经分割 的公开可用数据集。我们将看看我们的模型是否能够从图像中分割出特定的部分。但是,请注意,与原文有三处不同。

  1. 使用了较小的特征图尺寸 →这是由于硬件的限制,我使用的特征图数量是(1、3、6、12、24 和 48)。
  2. 使用了不同的代价函数 →如下图所示,原纸已经使用了带交叉熵损失函数的 softmax】。

然而,我使用了一个均方损失函数,激活了 ReLu()。

3 。用了不同的优化器 →如下图所示,原论文用的是随机梯度下降优化器,我只是用了一个 Adam 优化器。

结果

右图 →原图
中图 →二值掩码
左图 →从网络生成二值掩码

总的来说,与地面真实二进制掩码相比,网络做得令人惊讶地好,网络似乎正确地分割了它周围的区域。下面是在原始图像上叠加地面真实蒙版或生成蒙版时的一些图像。

GIF 格式的结果

显示图像的顺序 → 1。原图→ 2。地面真实二进制掩码→ 3。生成的二进制掩码→ 4。原始图像上的地面真实遮罩叠加→ 5。原始图像上生成的蒙版覆盖。

以上是我根据分割结果制作的 GIF,请注意观看 GIF 的顺序,以下是网络如何加班的汇编。随着训练的持续(从 epoch 来看),我们可以看到生成的掩码变得更加精确。

互动代码/透明度

对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问 Google Colab 上的代码,请点击此处。

  • *注**:我不想在 github 上托管 Kaggles 的数据,因为我可能会违反他们的数据使用政策。所以这段代码不能直接在线运行。
  • 为了让这个实验更加透明,我把我所有的命令输出上传到了我的 github,如果你想看,请点击这里。

遗言

我真的想将我的技能扩展到细分领域,我很高兴最终我能够做到这一点。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。

同时,在我的推特这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. 罗尼伯格,o .,菲舍尔,p .,& Brox,T. (2015 年 10 月)。生物医学图像分割的卷积网络。在医学图像计算和计算机辅助介入国际会议上(第 234-241 页)。斯普林格,查姆。
  2. 超声波神经分割| Kaggle。(2018).Kaggle.com。检索于 2018 年 4 月 2 日,来自https://www.kaggle.com/c/ultrasound-nerve-segmentation
  3. 整流器(神经网络)。(2018).En.wikipedia.org。检索于 2018 年 4 月 2 日,来自https://en . Wikipedia . org/wiki/Rectifier _(neural _ networks)
  4. 面向数据科学的转置卷积上采样。(2017).走向数据科学。检索于 2018 年 4 月 2 日,来自https://towards data science . com/up-sampling-with-transposed-convolution-9 AE 4 F2 df 52d 0
  5. TF . nn . conv 2d _ transpose | tensor flow。(2018).张量流。检索于 2018 年 4 月 2 日,来自https://www . tensor flow . org/API _ docs/python/TF/nn/conv2d _ transpose
  6. 达哈尔,P. (2017 年)。分类和损失评估— Softmax 和交叉熵损失。深度笔记。2018 年 4 月 2 日检索,来自https://deepnotes.io/softmax-crossentropy
  7. j . brown lee(2017 年)。深度学习的 Adam 优化算法的温和介绍-机器学习掌握。机器学习精通。检索于 2018 年 4 月 2 日,来自https://machine learning mastery . com/Adam-optimization-algorithm-for-deep-learning/
  8. 随机梯度下降。(2018).En.wikipedia.org。检索于 2018 年 4 月 2 日,来自 https://en.wikipedia.org/wiki/Stochastic_gradient_descent
  9. Python 中的 DICOM:用 PyDICOM 和 VTK 将医学图像数据导入 NumPy。(2014).PyScience。2018 年 4 月 2 日检索,来自https://pyscience . WordPress . com/2014/09/08/DICOM-in-python-importing-medical-image-data-into-numpy-with-pydicom-and-VTK/
  10. JaeDukSeo/Only_Numpy_Basic。(2018).GitHub。2018 年 4 月 2 日检索,来自https://github . com/JaeDukSeo/Only _ Numpy _ Basic/blob/master/U-net/U-net . txt
  11. 均方差。(2018).En.wikipedia.org。检索于 2018 年 4 月 2 日,来自https://en.wikipedia.org/wiki/Mean_squared_error

医学图像分割[第二部分]——基于交互式编码的扩展全卷积网络的病理肺组织语义分割

原文:https://towardsdatascience.com/medical-image-segmentation-part-2-semantic-segmentation-of-pathological-lung-tissue-with-24482942d65a?source=collection_archive---------4-----------------------

Gif from this website

这是我关于医学图像分割的第二篇文章。今天我们将覆盖这篇论文“ 【扩张全卷积网络的病理肺组织语义分割 ”。今天我又觉得有点懒,所以我就用自动微分来训练我的网络。

网络架构(基本构建模块/完整架构)

Image from paper

所以上图显示了这个网络的基本构建模块,它由卷积运算、归一化、加法和激活函数(ReLU)组成。既然我们已经看到了基本的构造块,那么让我们来看看完整的网络体系结构。

这篇文章确实很好地描述了整个体系结构,网络总共有 13 层,有各种级联层和丢弃层的组合。

实验设置/与论文的差异

右图像 →原始图像
中间图像 →地面真实二值蒙版
右图像→ 地面真实蒙版覆盖在原始图像之上

与原始论文有一些不同之处,这些不同之处是…..
1。数据集:我将使用来自 Kaggle " 超声神经分割的分割数据

2。归一化层/批量大小:原论文使用实例归一化层,然而如下图所示,我将使用批量归一化。同样,原始纸张使用的批量大小为 1,我将使用批量大小为 2。

3。不同数量的特征图:原论文报道每层使用 32 个特征图,由于硬件限制我只使用 3 个特征图。(因此在连接操作中,我们将有 1 + 3 * 10 = 31 个特征地图)

成绩(原网)

即使我用各种超参数训练原始网络,我也不能得到任何好的结果。生成的蒙版只是一个漆黑的图像。所以我决定对网络做三个改变。

原网络改造

红线 →每层增加剩余连接

我做的第一个改变是在每一层增加一个额外的剩余连接,以获得更流畅的信息流。

绿线 →更改辍学率

我改变的第二件事是退学率,我决定不使用退学层。

紫线 →改变成本函数和直接连接

最终的改变是将最终图层直接链接到成本函数,并将成本函数更改为均方误差函数。(本文使用了带交叉熵损失函数的 softmax。

结果(修改后的网络)

右图 →原图
中图 →二进制掩码
左图 →从网络生成二进制掩码

网络很好地分割了感兴趣的区域。然而,我注意到的一件事是生成的蒙版中出现了看起来像正方形的伪像。众所周知,这种有时被称为棋盘状伪像的现象即使在使用去卷积操作时也会发生,本文对此进行了解释。下面是在原始图像上叠加地面真实蒙版或生成蒙版时的一些图像。

GIF 格式的结果

显示图像的顺序 → 1。原图→ 2。地面真实二进制掩码→ 3。生成的二进制掩码→ 4。原始图像上的地面真实遮罩叠加→ 5。原始图像上生成的蒙版覆盖。

以上是我根据分割结果制作的 GIF,请注意观看 GIF 的顺序,以下是网络如何加班的汇编。随着训练的持续(从历元来看),我们可以看到生成的掩模变得更加精确,但是我们可以看到棋盘伪影总是存在。

互动代码/透明度

对于 Google Colab,你需要一个 Google 帐户来查看代码,而且你不能在 Google Colab 中运行只读脚本,所以在你的操场上复制一份。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!

要访问原始型号的代码,请点击此处。
要访问改装车型的代码,请点击此处。

  • *注**:我不想在 github 上托管 Kaggles 的数据,因为我可能会违反他们的数据使用政策。所以这段代码不能直接在线运行。
  • 为了让这个实验更加透明,我上传了我所有的命令输出到我的 github,如果你想看的话,请点击这里。

最后的话

我实现的原始网络要复杂得多。它甚至有 4D SoftMax 层。(点击这里如果你想查看 4D 软最大层。).他们在分割肺部区域方面做得非常出色。

如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你想看我所有写作的列表,请在这里查看我的网站。

同时,在我的 twitter 这里关注我,并访问我的网站,或我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。

参考

  1. 完整的-项目/LungNet。(2018).GitHub。于 2018 年 4 月 3 日检索,来自https://github.com/intact-project/LungNet
  2. Anthimopoulos,m .,Christodoulidis,s .,Ebner,l .,Geiser,t .,Christe,a .,和 Mougiakakou,S. (2018 年)。基于扩展全卷积网络的病理肺组织语义分割。arXiv 预印本 arXiv:1803.06167。
  3. 超声波神经分割| Kaggle。(2018).Kaggle.com。2018 年 4 月 3 日检索,来自https://www.kaggle.com/c/ultrasound-nerve-segmentation
  4. Ioffe,s .,& Szegedy,C. (2015 年)。批量标准化:通过减少内部协变量转移加速深度网络训练。Arxiv.org。2018 年 4 月 3 日检索,来自https://arxiv.org/abs/1502.03167
  5. Ulyanov,d .,Vedaldi,a .,和 Lempitsky,V. (2016 年)。实例规范化:快速风格化缺少的要素。Arxiv.org。检索于 2018 年 4 月 3 日,来自https://arxiv.org/abs/1607.08022
  6. 均方差。(2018).En.wikipedia.org。检索于 2018 年 4 月 3 日,来自 https://en.wikipedia.org/wiki/Mean_squared_error
  7. 奥登纳,a .,杜穆林,v .,和奥拉,C. (2016 年)。去卷积和棋盘伪影。蒸馏,1(10)。doi:10.23915/蒸馏水
  8. Roelants,P. (2018 年)。彼得的笔记。peterroelants . github . io . 2018 年 4 月 3 日检索,来自http://peterroelants . github . io/posts/neural _ network _ implementation _ intermezzo 02/

医学影像遭遇 NIPS:综述

原文:https://towardsdatascience.com/medical-imaging-meets-nips-a-summary-43bf1b0d0c62?source=collection_archive---------6-----------------------

今年,我参加了医学成像与 NIPs 研讨会,并展示了一张海报。该研讨会的重点是汇集来自医学成像和机器学习社区的专业人士。总共有十一个讲座和两个海报会议。在这里,我将回顾研讨会的一些亮点。演讲和海报通常讨论分割、分类和/或图像重建。

分割

在参加这个研讨会之前,我必须承认我没有完全理解图像分割的价值。我的思维过程一直是这样的:为什么你只想勾勒出一幅图像中的某样东西,而不想对它进行分类?这个研讨会改变了我对细分价值的看法。

放射疗法

剑桥大学放射学家、微软研究员 Raj Jena 做了一个关于“像素完美主义——机器学习和适应性放射治疗的演讲。在演讲中,他描述了机器学习如何帮助提供更好的治疗方法和优化工作流程。为了使患者接受适当的放射治疗,精确定位肿瘤的确切边界是很重要的。通过定位肿瘤和健康组织之间的精确边界,治疗可以提供更多的辐射,因为损伤健康组织的风险更小。然而,目前分割是由放射科医生手动完成的。这通常会导致不同放射科医生之间的差异,从而显著影响治疗结果。一致性在衡量与放射联合使用的药物的有效性方面也很重要,因为如果患者接受的放射不同,几乎不可能判断是药物还是更好的放射导致了改善。

机器学习提供了提供一致性和更准确分割的机会。其次,机器学习模型通常可以在几秒钟内运行,而放射科医生通常需要几个小时来手动分割图像。这些时间可以更好地用于规划治疗过程或看更多的病人。Jena 还描述了机器学习如何让他成为一名“超级放射肿瘤学家”

Slide from Jena’s talk. The “Super Radiation Oncologist” uses machine learning to constantly adapt therapy and predict effects of treatment.

Slide from Jena’s talk. Details adaptive radiation therapy.

ML 可以使肿瘤学家更好地使治疗适应健康组织的形状和大小的变化,并帮助肿瘤学家预测放射治疗可能的不利影响。例如,Jena 描述了他如何使用高斯过程等简单方法来预测辐射的潜在副作用。

这是整个研讨会中我最喜欢的演讲之一,我强烈建议大家看看 Jena 的完整报告。

构建质量数据集

整个研讨会的一个共同主题是注释的质量和建立良好的医学成像数据集的困难。在分段任务中尤其如此,在这种任务中,模型只能和它的注释器一样好,而注释器本身必须是熟练的放射科医生。

加速注释过程的一种可能方式是通过主动学习。IBM 的 Tanveer Syeda-Mahmood 在讨论 IBM 在放射学方面的工作时简单地提到了这一点。对于主动学习,可以从一个小的带标签的数据集和几个专业的人类注释者开始。ML 算法很好地学习训练集,使得它可以自己注释简单的图像,而专家注释硬边缘情况。具体而言,分类器得分低于确定性阈值的图像随后被发送给人类进行人工注释。其中一张海报(Girro 等人)还讨论了使用主动学习来帮助有效地训练语义图像分割网络。

主动学习可以解决部分问题,但不能完全解决质量问题。核心问题是,当连专家都不同意界限时,研究人员如何开发准确的数据集。关于这一点,Bjorne Menze 介绍了 BraTS 数据集的构建。BraTS 数据集是最大的脑成像数据集之一。他融合了来自几个不同注释者的数据,以创建“基础事实”自成立以来,BraTS 已经举办了几次不同的挑战。挑战之一是用机器学习算法分割所有肿瘤,最*的挑战集中在预测总生存期上。

定位、检测和分类

对医学图像中发现的疾病进行准确分类是研讨会的一个突出主题。在医学成像中,检测对象/ROI 并对其进行准确分类是一项具有挑战性的任务。这在很大程度上是由于医学图像(即,X 射线 MRI、CT、超声和声谱图)的各种形态(和维度)、图像的大小以及(与分割一样)有限的注释(有时是低质量的)训练数据。因此,演讲者展示了各种有趣的技术来克服这些障碍。

Ivana Igsum 讨论了心脏成像中的深度学习技术。特别是,她描述了自己在精确检测动脉钙化方面的工作。她描述了她和她的团队如何开发出自动计算钙含量并对心血管疾病风险进行分类的方法。为此,她的团队使用了多层 CNN 方法。

Slide from Ivana’s talk (5:46)

当天晚些时候,Yaroslav Nikulin 介绍了数字乳腺摄影挑战赛的获奖方法。

海报

芝加哥大学的 Natalia Antropova,Benjamin Huynh 和 Maryellen Giger 有一张关于使用 LSTM 进行乳腺 DCI-MRI 分类的有趣海报。这包括在应用对比染料后输入多个时间步骤的 3d MRI 图像。然后,他们使用 CNN 从这些图像中提取特征,并将其传送给 LSTM,输出一个预测。总之,这张海报提供了一个 LSTM(和 CNN)处理“4d”医学成像数据的有趣应用。

我的海报重点介绍了我目前正在进行的工作,即使用物体探测器对胸部 X 射线中的多种情况进行精确定位和分类。我的主要目标是研究对象检测算法在有限数据集上的表现,而不是在整个数据集上训练的多标签分类 CNN。我认为,如果配置和训练得当,对象检测器在医学图像中定位和分类疾病/状况方面有很大潜力,但是它们受到缺乏标记包围盒数据的限制,这也是我觉得下面的海报非常有趣的原因之一。

Hiba Chougrad 和 Hamid Zouaki 有一张关于乳腺成像分类的迁移学习的有趣海报。在摘要用于乳腺癌筛查的卷积神经网络:指数衰减的迁移学习中,他们描述了测试几种不同的迁移学习方法。例如,他们比较了微调和利用在 imagenet 上预先训练的 CNN 与随机初始化权重。最后,他们发现最佳技术是使用指数衰减学习率来微调各层。因此,对于底层(即最接* softmax 的层),学习速率最高,而对于上层,学习速率最低。这在直觉上很有意义,因为底层倾向于学习最相关的数据集特征。通过使用这些和相关技术,我们可以(有希望)在没有大型数据集的情况下开发精确的模型。

重建和生成

心流

我通常不会对那些吹捧他们的产品有多棒以及它将如何“革新[插入行业]”的产业宣传印象深刻不过 Heartflow 和他们的 DeepLumen 血管分割算法绝对让我印象深刻。该产品减少了 83%的不必要的血管造影,并获得 FDA 批准。我不会在这里深入讨论细节,但我认为 Heartflow 是机器学习在现实世界环境中产生影响的一个很好的例子。

其他两位演讲者也谈到了重建问题。Igsum 的演讲(前面提到过)讨论了一种从低剂量 CT 构建常规 CT 的方法。帝国理工学院的 Daniel Rueckert 描述了基于 ML 的重建如何在成像中启用更多的时间戳。

海报

我发现其中一个特别有趣的海报是使用循环一致生成对抗网络的 MR-to-CT 合成。在这项工作中,作者(Wolterink 等人)采用了流行的 CycleGAN 算法,并将其用于将 MRI 图像转换为 CT 图像。这是一个潜在的非常有用的应用,可以避免患者必须进行多次成像过程。此外,CT 使患者暴露在辐射中,因此这也有可能减少辐射暴露。

Image from MR-to-CT synthesis article

还有一张由 Virdi 等人制作的海报,主题是来自双生成对抗网络的合成医学图像,以及 Mardani 等人制作的海报,主题是用于压缩感知的深度生成对抗网络(GANCS)自动核磁共振成像。

工具和*台

几位发言者谈到了旨在使临床医生和 ML 研究人员更容易利用机器学习进行医学图像分析的新工具。Jorge Cardoso 描述了 NiftyNet 以及它如何使研究人员更容易地开发医学成像模型。NiftyNet 建立在 Tensorflow 之上,它包括许多简单易用的模块来加载高维输入。

Poster from Makkie et al. on their neuroimaging platform

同样在工具方面,G. Varoquax 在 NILearn,上展示了一个基于 scikit-learn 构建的用于神经成像数据的 Python 模块。正如 scikit-learn 寻求使具有基本编程技能的人能够使用 ML 一样,NILearn 的目标是在脑成像方面做同样的事情。唯一与系统相关的海报来自佐治亚大学的 Makkie 和刘。它专注于他们的大脑倡议*台,用于神经成像,以及它如何融合几种不同的技术,包括 Spark,AWS 和 Tensorflow。最后, DLTK 工具包在大会上有了自己的海报。总之,有一些非常有趣的工具包和*台,应该有助于让每个人都更容易使用机器学习进行医学图像分析。

其他会谈

Wiro Nessen 在 T4 做了一个关于生物医学成像和基因数据融合的有趣演讲。在演讲中,他描述了如何将大型基因和成像数据集结合起来,试图检测图像中的生物标记。这两个领域的综合也有助于早期发现疾病,并找出更有针对性的治疗方法。

公告

  • 在她的演讲结束时,Ivana Igsum 宣布第一届医学成像深度学习或 MIDL 活动将于 7 月在阿姆斯特丹举行。
  • 我不断地在我的机器学习医疗保健策划列表中添加新的论文、会议和工具。然而,这是一个大工程,所以今天就做一个公关并做出贡献吧!
  • 我正在开办一个新的 Slack 频道,致力于医疗保健领域的机器学习。所以如果你感兴趣,请随时加入。
  • 我对 NIPs 的医疗保健机器学习或 ML4H 的总结将在未来几周内发表。这将涵盖从医院运营(如 LOS 预测和手部卫生),到挖掘电子医疗记录,到药物研发,再到分析基因组数据的方方面面。敬请关注。

一如既往地欢迎评论和提问。

媒体分析:愿望清单

原文:https://towardsdatascience.com/medium-analytics-a-wishlist-39120a8c27e9?source=collection_archive---------5-----------------------

慷慨地说,中等分析是简朴的。无论你是个人作家还是出版物,他们给你的信息很少,比如谁看过你的帖子,以及为什么他们成功或不成功。

作为一名作家和编辑,这降低了我对*台的忠诚度。我可以看到这样的事情:

Two weeks after publishing, a sudden 4x in daily views…

但是媒体让我无法发现为什么会这样,谁感兴趣,或者下次我能做些什么来增加我的收视率。我有所有的问题…但没有答案。

中,以下是我的要求:

帮我了解我的听众。

不管是关注者还是读者——或者两者都是——我希望我有更多关于谁在阅读我的作品的信息。我对人口统计数据很好奇——年龄、性别、职业——但也对我确信你有的行为统计数据很好奇。我的读者是活跃的媒体用户吗?我是否真的从使用你的*台中获得了动力,或者我只是通过在 LinkedIn 上发布我的文章来满足你的用户群?

我的读者还会读到什么或为之鼓掌吗?我的朋友读我的作品是因为他们喜欢我,还是我真的接触到了设计师和项目经理的观众?

我的读者中有多少是机器人?当我浏览我的出版物的关注者时,我看到一些空的个人资料。很难说这些人是新媒体用户还是推特式的填充者。

帮助我了解我在中观宇宙中的等级。

环顾中型*台——看到一些点击量为 1.5K 的点击诱饵,以及拥有相同数量的经济学人——我很难理解我获得的关注量是赢还是输。我很想知道一个给定的故事相对于它的同行(具有相似的内容标签和阅读时间,或者由拥有相似粉丝数量的作者)表现如何……或者甚至它与我的历史出版作品相比表现如何。

我可以想出我自己的聪明的主题或图像或格式…我不需要看到什么是流行的媒体整体和试图游戏系统。但是我想知道我和我的写作同行相比如何,这样我可以随着时间的推移改进我的策略和风格。

告诉我媒体是如何帮助我的。

当它第一次出现在我的收件箱时,我真的很兴奋:

…同样,当我点击链接却找不到自己,或者找不到关于人们如何出现在这个页面的解释时,我感到失望。由于如此多的媒介是经过策划的,我不知道这些被标记的页面应该告诉我什么。我的作品会呈现给对设计或数字设计感兴趣的人吗?我在设计标签的前一百篇文章中可见吗?Medium 实际上做了什么来将我的作品展示给其他人?

我相信你做了很多——这也是我写这封公开信的部分原因,我希望在你的策展和分享我的作品时有更多的透明度。

期待继续我们的读者-作者-出版商关系…如果你未来的分析项目需要一些测试人员…你知道在哪里可以找到我。

中型或:我如何学会停止担心,爱上博客

原文:https://towardsdatascience.com/medium-or-how-i-learned-to-stop-worrying-and-love-the-blog-5d6de7a7a20e?source=collection_archive---------7-----------------------

第一个月在介质上写数据文章的经验和收获

Just about every weekend.

我一直想写一个博客,将想法在纸上(或屏幕上)具体化,并钻研短暂的兴趣。

尽管在许多场合,我的文章想法都得到了朋友们的认可,但我发现自己还是陷入了无所作为的状态。

但是后来,发生了。

也许这是一种自信的提升。也许是最*长篇写作的热潮。或者可能是上个月我肩膀脱臼后腾出的时间。

不管怎样,在一个月的时间里,我写了四篇文章,我意识到我是多么享受尝试和写作不同主题的过程。

这里有 5 个外卖:

1.了解你的受众

“写信只是为了取悦一个人。如果你打开一扇窗,向世界做爱,可以说,你的故事会得肺炎。”—库尔特·冯内古特

写完我的第一篇文章后,我不断地质疑内容是否太长,或者是否有人对在线电子表格感兴趣。

就在那时,一位朋友给我发来了上述库尔特·冯内古特的名言。

写给一个人看。

就像你为产品创建 UX 人物角色一样,也为你的目标读者创建一个。我的第一篇文章相当模糊,没有重点。所以对于我的下一篇关于数据争论的文章,我决定为一个对数据可视化感兴趣的刚毕业的学生写,他刚刚开始研究 Python 的功能和包。他/她也将从一个相对干净的数据集开始,该数据集来自一个著名的来源,如经合组织或世界银行。

通过关注你是为谁而写,文章自然会变得更简洁以迎合读者。反过来,听众也能更好地阐述为他们增加的价值。

2.小胜利很重要

"追踪你的小成就,激发大成就."特蕾莎·阿马比尔

你有没有在完成一个个人项目或达到一个个人目标时,同时感到一阵兴奋和轻松?

每当我完成一篇文章时,同样的浪潮就会席卷我。对于我围绕数据分析项目的作品来说尤其如此。

然而,在我调试代码和写作的几周里,我的热情和动力总是下降。对于一个旷日持久的过程来说,这似乎总是一笔不常见的支出。

所以我把完成一篇文章的大“胜利”分解成代表小胜利的多个检查点。它可以像“完成介绍”或“调整正确的数据集”一样精细。

一个接一个的小胜利让我在整个写作过程中都沉浸在微量多巴胺的刺激中。更重要的是,通过积累小胜,我设法建立势头,坚持一个常规,并打破惯性的错觉。

又及——猫迷因的每一次机会都是一次小小的胜利。

3.抽时间

“忙是一种选择。”—安·沃斯坎普

我一直用来证明拖延写作的借口是我很忙,没有时间。我工作很忙。我正忙着建立关系网。我在健身房很忙。

我逐渐意识到,你选择在某些事情上忙碌是因为它们对你很重要,你把它们看得比其他事情更重要。

从“我在做多少不同的事情?”到“我在做多少不同的事情”,这需要重新定义我的优先事项。到“对我来说什么是重要的?”这让我致力于我的第一篇文章。学习掌握新的想法,清楚地表达自己,澄清我的想法,并参与讨论对我来说很重要,这些都是我可以通过写作解决的问题。

所以我优先考虑。我挤出了时间。早餐前的几个小时,午餐后的工作间隙,以及回家的公交车都成了制作内容的宝贵时间。

4.只是运送它

“做得比完美更好”——未知

你总是会回头看一篇发表的文章,看到一些可以改进的地方。

一直都是。

这并不是说任何草稿都应该不经过校对就发表。然而,到了一定程度,担心内容是否足够好或足够容易理解是一种毫无意义的练习。

在撰写一篇关于 P2P 贷款的数据文章时,我确实有这种感觉。这个模型可以有更多的变量。我可以包含更多的外部数据集。我本可以通过特征工程制造出更多的变量。

一天结束时,我想到了三个问题:

  1. 鉴于个人限制(时间、技能水*等),我是否尽了最大努力?)?
  2. 这是我的一个观众会觉得有价值的东西吗?
  3. 我从写这篇文章中学到了什么吗?

三票通过。它上升了。

5.准备好惊喜吧

“生活中几乎所有美好的事情都是我意想不到的,没有计划的。”—卡尔·桑德堡

作为一名新作家,我预计每天会有 10-20 次浏览,主要是朋友和我父亲的重复访问。

想象一下我的反应,一周后检查统计数据,看到总阅读数在一小时内翻了五倍。老实说,这主要是混乱,夹杂着些许惊讶和兴奋。

几天后,我的 CTO 转向我,说“嘿,这不是你在 Python 周刊上发表的文章吗?”。

对于一个写作和编码的新手来说,正是像这样的时刻和随后感谢我写这篇文章的信息提醒了我为什么要在 Medium 上写作。

如果你对出版犹豫不决,因为你怀疑你能提供什么或者你有多少时间来写作,我希望这篇文章能鼓励你迈出这一步。

感谢阅读!

认识人工神经网络

原文:https://towardsdatascience.com/meet-artificial-neural-networks-ae5939b1dd3a?source=collection_archive---------4-----------------------

http://www.extremetech.com/wp-content/uploads/2015/07/neural-net-head.jpg

当听到“神经”这个词时,我首先想到的是大脑中的神经元,这是决策过程的一部分。

这是人类区别于机器人(或常规计算机程序)的主要特征之一。人类可以看到事物,分析它们,并从中学习,以便下次做得更好。

另一方面,常规程序遵循同样的一套指令,它们不会发展自己。我们可以通过编程让它们完成特定的任务,根据它们被编程的方式,我们可以得到一个好的结果。

但是如果我们能让程序学习,我们可以做很多事情。然后他们会随着时间发展自己。这被称为“机器学习”,人工神经网络(ANN)是一种用于机器学习的计算模型,其工作方式类似于生物神经元。

当信息流经神经网络时,它会感知它们,并通过调整网络来学习,以生成一个好的解决方案。通过网络传递尽可能多的数据可以获得更准确的结果。这被称为对神经网络的训练

在使用神经网络之前,我们需要对其进行训练和调整,以便做出正确的决策。为此,我们使用测试数据。它们由网络的输入和相应的预期输出组成。通过适当地喂养它们,我们可以教会网络,然后我们可以用它来对未知数据做出决定。

基本上,人工神经网络用于非线性统计数据建模,其中输入和输出之间存在复杂的关系。训练过程用于发现数据集中的复杂关系和模式。

人工神经网络(ann)或connectionist系统是受构成动物大脑的生物神经网络启发的计算系统。这种系统通过考虑例子来学习任务(逐步提高性能),通常不需要特定任务的编程——维基百科

在需要基于计算机的预测的地方,神经网络是非常常见的。通常,他们能够做出准确的预测。一些应用是股票市场趋势预测、手写识别、语音识别、滑坡预测等。此外,像脸书这样的社交媒体,像谷歌这样的搜索引擎也利用这些来提供丰富的用户体验。

存在许多类型的神经网络。

  • 前馈
  • 复发的
  • 监管反馈
  • 径向基
  • 等等…

“前馈”网络是第一种也是最简单的类型。在这种类型中,数据从输入层传输到隐藏层,最后传输到输出层。没有数据传输的周期或循环。

Neural Network with multiple layers (https://blog.ttro.com/wp-content/uploads/2017/01/TB010-Deep-Neural-Network.jpg)

另一方面,在“循环”网络中,数据向前和向后传播。递归网络输出也用作输入,当预测序列时,使用这种方法。

下面是我在 YouTube(https://www.youtube.com/watch?v=ZzWaow1Rvho)上找到的一个简单的例子,这个例子非常有助于理解这个概念。有红色和蓝色两种花,我们已经给出了一些关于它们的宽度和长度的样本数据。需要使用这些给定的数据,并预测未知花朵的颜色。

Testing Data

这里我们将使用一个前馈神经网络来预测正确的花。我们将使用 Python 和 Numpy 库来实现。你可以通过安装“迷你康达”(【https://conda.io/miniconda.html】T2)来设置这些

我们简单的神经网络有 2 个输入,即花瓣长度和宽度,输出为 0 或 1,表示红色或蓝色。

Our simple neural network

由于网络的最终输出是 0 或 1,我们在这里使用一个特殊的函数,称为“ Sigmoid ,它将任何值压缩到 0,1 的范围内。基于它与 0 或 1 的接*程度,我们进行预测。

S 形函数是具有“S”形曲线的数学函数(S 形曲线)。通常, sigmoid 函数是指逻辑函数的特例

Sigmoid function (https://qph.ec.quoracdn.net/main-qimg-05edc1873d0103e36064862a45566dba)

我们试图通过 **w1 长度+ w2 宽度+ b 对给定数据进行建模,其中 w1、w2 是两个权重,b 是一个偏差。这可用于发现数据中的任何非线性关系。

最初,我们将随机数分配给 w1、w2 和 b,在训练过程中,我们更改这些值,以使模型代表给定的测试数据。这是通过使用期望值和预测值来计算成本值,并尝试使用基本微积分理论来减少成本值来实现的。在训练过程的最后,我们将能够得到一个准确的模型,并且我们将能够使用它来预测未知的数据。

Sample source code

在本例中,我们所做的是,使用链式法则分别对 w1、w2 和 b 的成本函数进行微分,并找到使成本最小的常数。由于这是一个简单的微分手动进行。然而,有一些库可以自动完成这些任务。最后,他们找到了神秘的花的类型。

下图显示了培训结束后成本是如何降低的。它一步一步地减少,以作出更准确的预测。

Cost variation while learning

正如我之前说的,这个例子摘自一个很棒的 YouTube 系列,要了解更多信息,我强烈推荐你去看看这个!(https://www.youtube.com/watch?v=ZzWaow1Rvho

感谢阅读。

干杯!

认识深度学习的英雄

原文:https://towardsdatascience.com/meet-the-heroes-of-deep-learning-648c9083ef10?source=collection_archive---------1-----------------------

Photo by Ricardo Gomez

深度学习

你过得怎么样?我希望你很好,准备好继续学习新的东西,这就是你读书的原因,对吗?我很高兴为你写这篇文章,但是我为什么要写这个呢?几天前,我在看 Andrew NG 做的一系列采访,这些采访可以在 YouTube 上找到,他是作为 deeplearning.ai 课程的一部分做这些采访的。Andrew 的目标是召集一些最伟大的头脑,他们是深度学习领域的先驱,在这个非常惊人的领域做出了巨大的贡献和进步,让每个人都与他人分享他们如何开始研究深度学习和他们的一些动机,并给有兴趣加入该领域的人提供一些建议。有哪些不同的方法可以开始,如果你没有研究过深度学习,也许这是你知道为什么你应该或不应该(不是每个人都愿意付出努力来掌握一些东西)参与的机会。正如你可能猜到的,我觉得有责任与你分享这些,所以我来了。

我认为人们需要理解深度学习正在幕后使许多事情变得更好。深度学习已经在谷歌搜索和图像搜索中发挥作用;它允许你搜索图片,比如“拥抱”—杰弗里·辛顿

关于吴君如

  • Coursera 的联合主席和联合创始人;
  • 斯坦福大学兼职教授。

除了是 Coursera 的联合主席和联合创始人之外;作为斯坦福大学的兼职教授,安德鲁是百度的副总裁兼首席科学家,2011 年,他领导了斯坦福大学主要 MOOC(大规模开放在线课程)*台的开发,并为超过 10 万名学生讲授了在线机器学习课程,从而创立了 Coursera。Ng 的目标是让世界上的每个人都能免费获得良好的教育。今天,Coursera 与世界上一些顶尖大学合作,提供高质量的在线课程,是世界上最大的 MOOC *台。

Ng 还致力于机器学习,重点是深度学习。他创立并领导了“谷歌大脑”项目,该项目开发了大规模深度学习算法。这导致了著名的“谷歌猫”结果,其中一个拥有 10 亿个参数的大规模神经网络从未标记的 YouTube 视频中学习,以检测猫。最*,他继续致力于深度学习及其在计算机视觉和语音方面的应用,包括自动驾驶等应用。

深度学习的英雄

安德烈·卡帕西

  • 特斯拉 AI 总监

绝对是我的最爱之一,我真的很喜欢他关于计算机视觉识别卷积神经网络(Cs231n)的课程。安德烈·卡帕西(Andrej Karpathy)是特斯拉的人工智能总监,目前专注于自动驾驶的感知。此前,他是 OpenAI 的研究科学家,从事计算机视觉、生成建模和强化学习方面的深度学习。他获得了斯坦福大学的博士学位,在斯坦福大学,他与费-李非一起研究卷积/递归神经网络架构及其在计算机视觉、自然语言处理及其交叉领域的应用。在博士期间,他挤出时间在谷歌实习了两次,在那里他从事 YouTube 视频上的大规模特征学习,2015 年,他在 DeepMind 实习,从事深度强化学习。他和飞飞一起设计并教授了一个新的斯坦福班级,关于视觉识别的卷积神经网络(CS231n) 。

在推特上关注

采访安德烈·卡尔帕蒂

伊恩·古德费勒

  • 谷歌大脑的研究科学家

Ian good fellow(2014 年蒙特利尔大学机器学习博士)是谷歌的研究科学家。他的研究兴趣包括大多数深度学习主题,尤其是生成模型和机器学习安全和隐私。他发明了生成对抗网络,是研究对抗例子的有影响力的早期研究者,也是麻省理工出版社教科书《深度学习》的第一作者。他负责机器学习的自组织会议,该会议于 2016 年在 OpenAI 成立。

在 Twitter 上关注

采访伊恩·古德菲勒

约舒阿·本吉奥

  • 计算机科学正教授

Yoshua Bengio 是计算机科学和运筹学系的全职教授,蒙特利尔学习算法研究所(【MILA】)的负责人, CIFAR 机器和大脑学习 CIFAR 项目的联合主任,加拿大统计学习算法研究主席。他的主要研究目标是理解产生智力的学习原理。他教授一门机器学习的研究生课程,并管理一个由研究生和博士后组成的大型团队。他的研究被广泛引用(谷歌学术在 2017 年 4 月发现了超过 65000 次引用,H 指数为 95)。

采访约舒阿·本吉奥

杰弗里·辛顿

  • 多伦多大学教授
  • 谷歌大脑的研究科学家

Geoffrey Everest Hinton 是出生于英国的加拿大认知心理学家和计算机科学家,最著名的工作是人工神经网络。截至 2015 年,他将自己的时间分为在谷歌和多伦多大学工作。他是最早证明使用广义反向传播算法训练多层神经网络的研究人员之一,也是深度学习社区的重要人物。

在推特上关注 ( 剧透:正如他的账户中所述“只是占据这个空间,以防杰夫·辛顿决定发推特”,他不怎么发推特,可能忙着试图理解人类的大脑)。

采访杰弗里·辛顿

鲁斯兰·萨拉胡季诺夫

  • 苹果公司人工智能研究总监
  • 计算机科学教授

我不确定我能不能把“Salakhutdinov”念对,反正这不是关于我的,我们继续吧。Ruslan Salakhutdinov 是加拿大人工智能领域的研究人员。他擅长深度学习、概率图形模型和大规模优化。Ruslan 因开发贝叶斯程序学习而闻名。自 2009 年以来,他已经发表了至少 42 篇关于机器学习的论文,还不忘提到他的研究得到了谷歌、微软和三星的资助。

在 Twitter 上关注

采访鲁斯兰·萨拉赫丁诺夫

林元庆

  • 百度研究负责人

林是计算机视觉和机器学习社区的活跃成员。他拥有清华大学光学工程硕士学位和宾夕法尼亚大学电子工程博士学位。IDL 是百度研究院旗下的三个研究实验室之一。另外两个是亚当·科茨领导的硅谷人工智能实验室和张彤领导的大数据实验室。

在推特上关注

采访林元庆

彼得·阿贝尔

  • 教授, 加州大学伯克利分校 EECSBAIR CHCAI
  • 研究科学家 开放 AI

他获得了比利时鲁汶大学的电气工程学士/硕士学位,并于 2008 年获得了斯坦福大学的计算机科学博士学位。他于 2008 年秋季加入加州大学伯克利分校,在电气工程和计算机科学系任职。他的研究重点是机器人学、机器学习和控制。

Abbeel 教授获得了各种奖项,包括斯隆研究奖学金、空军科学研究办公室青年研究员计划(AFOSR-YIP)奖、大川研究补助金、2011 年 TR35、IEEE 机器人和自动化学会(RAS)早期职业奖和迪克·沃尔茨机器人和自动化最佳美国博士论文奖。他开发了学徒学习算法,使先进的直升机特技飞行成为可能,包括只有出色的人类飞行员才能完成的动作,如抽搐、混沌和自动旋转。他的团队还使一个机器人能够可靠地捡起随机形状的、皱巴巴的衣物并折叠它们。他的作品被许多受欢迎的媒体报道,包括 BBC、《纽约时报》《麻省理工科技评论》、探索频道、SmartPlanet 和 Wired

在推特上关注

采访彼得·阿贝尔

扬·勒村

  • 艾研究总监脸书
  • NYU 数据科学中心创始主任

Yann LeCun 是一名计算机科学家,在机器学习、计算机视觉、移动机器人和计算神经科学方面做出了贡献。他因在光学字符识别和使用卷积神经网络(CNN)的计算机视觉方面的工作而闻名,是卷积网络的创始人。

在推特上关注

最终注释

我希望你喜欢读这篇文章,如果你认为名单中有遗漏的人,请告诉我,也许我还可以更新名单。欢迎在评论中告诉我更多你心目中的英雄。

“人工智能、深度学习、机器学习——不管你在做什么,如果你不懂,就去学吧。因为否则你会在三年内变成恐龙。”——马克·库班

进一步阅读

  • 为什么深度学习会突然改变你的生活
  • 吴恩达:为什么‘深度学习’是人类的使命,而不只是机器的使命

在你走之前!

如果你喜欢这些作品,请留下你的掌声👏推荐这篇文章,让别人也能看到。**

《与❤》作者 j .大卫·福莫!

愿原力与你同在!

见见你的新朋友“大口”

原文:https://towardsdatascience.com/meet-your-new-friend-gulp-b1f991a95616?source=collection_archive---------6-----------------------

什么是吞咽?

在开发应用程序时,你是否厌倦了重复做同样的事情?当我刚接触 JavaScript 框架的时候,我不得不做的最烦人的事情就是当一个改变完成时,一次又一次地重启服务器。后来我顺便找到了【Nodemon】;)

嗯,吞咽是解决这个问题的方法。不仅仅是因为这个。一饮而尽解决的重复问题。开发人员需要反复做的大多数任务都可以通过自动化来简化。因此,Gulp 可以被认为是一个 JavaScript 任务运行器,它可以让开发人员自动完成某些任务。

GULP 是一个工具包,用于自动化开发工作流程中痛苦或耗时的任务

示例任务:

  1. 更改文件时刷新浏览器
  2. 缩小 JavaScript
  3. 将 SASS/LESS 编译成 CSS
  4. 单元测试
  5. 将源代码部署到输出目录(例如:dist 文件夹)

Gulp 非常容易学习,使用它很有趣。你需要知道 Gulp API 中的 4 个基本函数。

  • gulp.task — 用于定义一个新的 gulp 任务
  • gulp.src — 用于指向任务的输入文件所在的位置
  • gulp.dest — 用于指出输出文件需要写入的位置
  • gulp.watch — 用于制作 gulp 来观察文件的变化

不要对这些感到困惑。我会引导你了解每一个人,最终你会完全理解他们。

你需要明白的另一件事是在大口喝。有时候你需要在一项任务中做不止一件事。例如,您可能需要将几个 JavaScript 文件连接成一个文件并缩小它。在这种情况下,管道就派上了用场。使用管道,您可以通过利用流来链接多个任务。在上面的例子中,你需要链接连接和缩小。这些你在玩的时候会更清楚。

让我们动手做一些简单的例子来理解 Gulp 是如何工作的。

简单的吞咽例子

1.设置环境

首先,你需要在你的电脑上安装 node.js ,如果你没有,从这里安装。

这些例子将是完全跨*台的,你不需要担心你的*台。

准备好之后,使用命令全局安装 Gulp,

然后通过运行常规命令 npm init 初始化一个节点项目

导航到您的项目目录,并作为开发依赖项在本地安装 gulp

2.你的第一个任务是吞咽

现在在项目的根级别创建gulpfile.js。我们需要运行的所有任务都将包含在这个文件中。

注意,这个名字“gulpfile . js”是必不可少的,因为这个名字是用来检测文件的。否则,您将得到一个错误,指示 gulpfile 未找到。

现在让我们创建我们的第一个吞咽任务。在此任务中,我们将简单地创建一个控制台日志。

如果您熟悉 node.js,这里的一切都应该很清楚,因为它是不言自明的。首先,我们导入 gulp,因为我们正在创建一个新任务,所以使用了 gulp.task 函数。这里我们需要传递两个参数。首先是任务的名称,然后是定义任务的函数,包括应该执行什么。

要执行任务,在终端运行大口控制台。在命令中,需要执行的任务名称应该跟在 gulp 后面。

如果你的任务名是‘default’,只要在终端执行 gulp 就可以运行。这被称为大口执行默认任务

3.将源文件复制到输出文件夹

现在让我们做一点更有用的工作。在将应用程序部署到服务器之前,我们需要将所有内容复制到输出目录中。

让我们创建一个 src 目录,并在那里添加一个基本的 HTML 文件。在部署我们非常简单的应用程序之前,我们需要将其复制到 dist 文件夹中。让我们用吞咽来做它。

在这个新任务中,我们需要告诉 gulp 输入文件的位置和复制位置。为了做到这一点,我们使用了 gulp.srcgulp.dest. 这里我们指向 src 目录中的所有 HTML 文件。

注意,我们在这里使用管道,因为我们处理从输入源读取和写入目的地。

像我们之前使用命令 gulp copyToDist 一样运行任务。您会注意到,将创建一个 dist 文件夹,其中包含 src 目录中的 HTML 文件。

4.缩小 JavaScript 文件

当缩小一个 JavaScript 文件时,所有的空格都将被删除,包括注释,以使文件更轻量级。

要做到这一点,我们需要安装另一个叫做“吞咽丑陋”的依赖项。首先,使用下面的命令安装它。

然后,在 src 目录下创建一个 js 目录,并添加一个包含一些控制台日志命令的 JavaScript 文件,这些命令由空格和一些注释分隔。现在让我们缩小它,并将其添加到 js 下的 dist 目录中。

这里的一切应该是不言自明的。 uglify() 函数来自我们的新依赖项。您将看到 dist 目录中的新 JavaScript 文件通过删除所有空格和注释而被缩小。

5.将 SASS 编译为 CSS

允许你使用 CSS 中不存在的特性,比如变量、嵌套、继承等等。我们可以使用 gulp 将 SASS 编译成 CSS,方法是安装另一个依赖项,就像我们在前面的任务中所做的那样。

这次是【大口-萨斯】。首先从下面的命令安装它。

与前面类似,在包含 sass 文件的 src 目录中创建一个 sass 目录。让我们编译它并添加到 dist 中的 css 目录中。

你看,这里没有什么神奇的。我们使用管道,因为我们需要链接所有的东西。 sass() 函数会将 sass 编译成 css,并添加了以下部分来处理错误。如果您感到困惑,请遵循 gulp-sass 文档这里的。

6.将所有内容合并到一个命令中

起初,我告诉你 gulp 是为了简化重复。但是如果我们使用单独的命令一个任务接一个任务地运行,那就没有意义了,对吗?

Gulp 允许我们使用一个命令运行多个任务来解决这个问题。我们只需要用需要执行的任务数组替换任务中的函数。

你可以看到我在这里使用的是大口默认任务。因此,我们只需要在终端运行 gulp 。首先,删除项目中当前的 dist 文件夹,并运行上面的命令。您将看到我们指定的所有任务都完美地执行了,并像以前一样在 dist 目录中构建。

现在你可能明白这个简单工具的威力了。我们可以通过让它在我们更改 src 文件时自动执行来让它更有价值。

7.监视文件

现在让我们使用我在开始提到的 Gulp API 中的最后一个基本函数( gulp.watch) 来自动检测并构建对 dist 文件夹的新更改。

gulp.watch 中,我们需要指定在哪里观察,以及当变化发生时应该执行什么任务。例如,需要监视所有的 JavaScript 文件,当其中任何一个文件发生变化时,就会执行 minifyJS 任务。

运行 gulp watch 命令后, gulp 将对指定的文件进行监视,必要的任务将在改变时触发。

现在你应该对 Gulp 和如何使用它有了清晰的概念。它让开发者的生活更加轻松有趣。像我们在这里所做的那样,通过添加第三方依赖项可以完成更多的任务。

希望你喜欢这篇文章。继续读,加油!😃

在追求深度学习的职业生涯中迎接挑战

原文:https://towardsdatascience.com/meeting-challenges-in-pursuing-a-career-in-deep-learning-7cd55c5cf304?source=collection_archive---------13-----------------------

如果你能负担得起这么多小时的 AWS P2 实例,这篇文章可能不适合你阅读。

开场白:

这几段可能不是很重要。但这一部分可以告诉你,找到我下面列出的解决方案对我来说有多重要,这样我就可以继续我在深度学习方面的研究。我于 2013 年毕业于印度领先的科技大学之一卡利卡特国家理工学院,获得信号处理硕士学位。然而,我从未能在我主修的领域找到工作。生活在一个发展中国家,我无法在自己最感兴趣的领域找到工作。因此,我做了一些技术性最差、管理性更强的工作,这些工作机械性强于科学性。然而,在我的职业生涯中,我对数据非常感兴趣。多亏了《用于模式识别的神经网络这本书,这是我硕士期间选修课的一部分,它让我接触到了这个广阔的领域。我还记得我和我的朋友从西安大略大学计算机系提供的课程的讲义中掌握关键概念。我从不满足于我们所学的东西。在那些日子里,我不断在这个地区发现新的东西。

然而,毕业后立即失业以无形的方式粉碎了我。我面临的一个主要挑战是,我不是计算机科学专业的学生。我毕业于电子和电信工程专业。在大师赛的最后几个月里,我确信 Python 在我希望自己从事的任何事情上的影响力。因此,我从 Codeacademy 开始(顺便说一下,他们现在对学生上所有的课非常严格。他们不鼓励跳过某些时段)。不太相信 Codeacademy 语言的力量,我落后于我的计划(肾上腺素!).待在本加卢鲁,尽管非常注意健康,我还是得了伤寒,而且是连续的一次。我完全累了,医生坚持要我搬回喀拉拉邦(那是我的家乡)。心碎,随之而来的是痛苦。Lol!!

然而,数据似乎并没有停止打动我。因此,我被数据营吸引,在它的初期,他们的大部分课程都是免费的。这让我对数据充满热情。我不想争辩说我很擅长处理事情。但是我知道如果我得到一些指导,我会做得更好。据我所知,没有人在数据科学方面提供过这样的指导。所以下一个最好的步骤是找一个能够很好地用 Python 编程的导师。我能找到这样一个机会,对此我非常感激。这让我找到了一份 Python 开发的工作。有几个项目引起了我的兴趣。我非常喜欢的一个项目是使用网络 X 图书馆建立一个推荐系统。这与机器学习没有太大关系。然而,共同点是数据。当我的开发职业走到十字路口,我必须在追求数据科学/ML 工作或继续在 django 或我不感兴趣的事情上发展之间做出选择时,我选择了辞职。我过去和现在都不为此难过。这是我 6 个月前冒的一次险。这个决定让我有这么多时间专注于完成机器学习和深度学习的 MOOCs。

挑战:

现在,谈到挑战,我认为,生活在一个第三世界国家,没有工作,却希望在你感兴趣的领域创造奇迹,这并不轻松。我可以作证。30 岁跑步,未婚,被许多人认为是失败,但内心有追求完美的热情,这不是主流。不是每个人都有。在这 6 个月的失业期间,我做了一些惊人的事情。

  • 我在 Coursera 上完成了机器学习 MOOC
  • 我帮助一个朋友为他的公司应用程序设置了策略。
  • 获得了一笔经济资助,以攻读 Coursera 上 5 门深度学习课程中的第门。我已经申请了第二个。
  • 从喀拉拉邦飞到德里参加 PyData 会议。(激情!).
  • 参加了雅思的学术考试和 GT 考试,并且都获得了 8.0 分。;)
  • 我从 cs231n 开始,我认为这非常有趣。

奖学金:我面临的第一个挑战是在 Udacity 上资助我的数据科学纳米学位。我找不到一笔可以帮我每月支付 12500 印度卢比的固定收入。有段时间我甚至负担不起我的网络费用。所以,Udacity 是不可想象的。我几乎放弃了这个想法。那时,Udacity 提出了另一个深度学习计划。这次我很有野心。我发邮件询问奖学金事宜,令我失望的是,Udacity 没有提供奖学金。这让我很难过。

然而,一周后,教授吴恩达,在 Coursera 上宣布 deeplearning.ai 课程。这似乎是对我失望的一种即时补救。我非常高兴。但是后来,月供又让我烦恼了。因此,我申请了助学金,陈述了理由,在 8 月 23 日,我得到了批准。我一周前完成的。现在,我已经申请了一个资助来完成第二个。我知道我可以同时申请这个系列所有课程的资助。

与此同时, fast.ai 宣布了一个伙伴关系,旨在人工智能领域的多样性。我认为这是非常有希望的。我很高兴知道 fast.ai 已经朝着弥合差距迈出了这样的一步。

Lyft 和 Udacity 一起宣布了一项奖学金,面向任何打算在自动驾驶汽车领域攻读基础纳米学位的人。似乎申请现在已经关闭了。不确定他们是否会再次打开应用程序。

据我所知,这些是奖学金/助学金。我很想知道更多。

我面临的另一个挑战是建立一个 GPU 实例。我想,现在我有解决办法了。AWS 的免费层计划中不包括 GPU 实例。如果你是一名即将上大学的学生,GitHub 提供了一个学生开发者包,里面有价值 150 美元的 AWS 积分,我相信这对你尝试深度学习项目来说足够了。由于我是独立学生,我不能申请同样的服务,因此我自然选择了谷歌云*台,它在注册时提供一年 300 美元的免费积分。不像传言说 FloydHub 提供免费的 GPU 时间,他们没有。他们只免费提供 CPU 实例。除了这些,如果你是一名研究人员,NVDIA 也有兴趣通过一个 GPU 资助计划来帮助你。我还了解到 Azure 女士在注册时提供了 200 美元的信用额度。 Crestle 是另一项免费提供 10 小时 CPU 和 GPU 以及 1 GB 存储的服务。

我发现摆在我面前的另一个巨大障碍是众所周知的工作经验悖论。自从我开始找工作,这就成了一件事。即使现在,当我是一个经验丰富的 Python 程序员,完成了一些 ML/DL mooc 和认证,我也没有得到一个认可。没有公司愿意相信我这种人。我不认为许多人已经克服了这一点。在德里的 PyData 会议上,我们聊天的时候,甚至 Siraj Raval 自己也承认这个悖论挑战着许多灵魂。每次我接到关于工作的电话,在长时间的交谈之前,我都要确保他们知道我缺乏 ML 或 DL 的工业实践经验。这为我节省了时间。我没有解决这个问题的办法,除了 Siraj 给的建议。他对我说,“把拉贝·易卜拉欣做成一个你能卖的品牌”。

这篇文章结合了一些咆哮和一些信息,对那些努力保持热情的人有所帮助,通过它,我寻求一个机会,即使是在一家数据科学公司实习,无论是在线还是离线,这样我就不必再咆哮了。你可以在 LinkedIn 这里找到我。

日安!

Meetup 作为动员的来源:将数据科学工具用于社会科学

原文:https://towardsdatascience.com/meetup-as-a-source-of-mobilization-using-data-science-tools-for-social-science-a3ef4cec68?source=collection_archive---------14-----------------------

使用数据科学工具为社会科学收集数据

对于社会科学来说,收集数据来理解人类、社会和政治行为一直是一个挑战。虽然这种行为就在我们身边,但找到能够准确描述这些现象的数据是很困难的,如果不是代价高昂的话。正因为如此,对社会动态指标的创造性思考一直是社会科学的一部分。以社会学的创始人之一埃米尔·杜尔凯姆为例,他试图通过观察不同社会群体的自杀率来解释社会控制和社会融合等社会力量。涂尔干利用现有的自杀统计数据作为社会群体中缺乏融合的指标,这导致了一种不归属感。尽管他因使用综合数据来解释个人社会行为而受到批评,但他的研究是第一个社会动力学的方法论研究。

由于数据科学工具箱的快速发展,社会科学家越来越容易获得和使用数据源。 Stekmaszak an Hukal (2017) 讨论挖掘和管理新数据源的工具的发展以及使用机器从中学习如何使社会科学受益,同时警告社会调查中仍然存在的挑战。数据科学工具允许我们访问大量的新数据源,但这并不意味着我们不应该思考这些信息是如何定义、记录和传播的,以及在何种社会背景下传播的。

数据从来都不是客观的。虽然很有趣!因此,让我们考虑一个有趣的新数据来源,并学习如何将它用于社会科学。

聚会和社会运动

我是一名对社会和政治运动感兴趣的社会科学家。因此,当我了解到个人为全世界对某项政治或社会事业感兴趣的所有人组织会议的数据时,我自然感兴趣。Meet-up.com 是一个为人们提供一个*台来组织聚会的网站,聚会的话题可以是你能想到的任何话题。这可以是数据科学、小马、瑜伽或环境、女权主义或地方政治等公共事业。它的工作原理是,你可以创建一个会议,或者注册一个,并用相关主题标记会议。这是一个社交网络,它的显著特点是鼓励人们走出去,在真实世界的活动中进行身体接触。你确定一个时间和地点,那些注册的人可以参加这个活动。

对于一个社会科学家来说,这都是非常有趣的数据。你能做的就是去网站上收集关于团体和事件的信息,将它们分类(这是一种爱好,是娱乐还是运动和政治的一部分?)并查看他们的成员列表。或者你可以使用编程语言来自动化这个过程。这被称为网络抓取或数据挖掘。

通过 meetup API 挖掘数据

抓取 web 数据的一种方法是使用网站开发者制作的应用程序编程接口。这是礼貌的方式。API 基本上允许您与应用程序通信,在这种情况下是一个公共网站。我使用 Python 和 meetup.api 包与它通信。

首先,我收集了所有关于类别、城市和主题的信息。为了使用这个 API,你需要在见面会上注册并申请一个密钥。我将所有数据存储在单独的 CSV 文件中,以后可以将这些文件加载到我的环境中。下一步是获取属于这些类别的所有组。我将属于某个类别的所有组存储在一个单独的 CSV 文件中。之后,我确保收集每一个独特的组 ID。这对下一步很重要。

现在最重要的步骤是得到每个组的成员列表。您需要构建一个函数来根据惟一的组 id 获取成员数据。对于每个组,您可以有一个单独的文件,其中包含成员列表。

所有这些都会导致大量数据包含在几个 CSV 文件中。许多工作都与清理和管理数据有关。

数据管理

首先我要把相关数据筛选出来。由于我的研究涉及欧洲政治和社会运动,我最感兴趣的是欧洲的数据以及社会和政治运动的数据。因此,通过先按类别过滤,再按欧洲国家过滤,我的数据集已经变得更易于管理了!

其次,我需要清理我的数据。这需要提取相关的单词串,并将成员聚合到相关的组和主题中。为此,我需要首先创建三个数据框架:一个包含所有(匿名)成员 id 的数据,一个包含所有组的数据,一个包含所有主题的数据。

当然,关于这个数据的一个有趣的方面是,它实际上是关系型的。一个组的成员也可以是另一个组的成员。其中一些组也可能属于不同的主题。为了利用这一点,我创建了一个双模式网络(附属网络)。这意味着只要主题有共同的组成员,它们就被认为是相关的。

可视化数据

在所有这些清理和管理之后,我终于可以处理这些数据了!(这意味着我也从 Python 切换到 R)。想象一下聚会是如何随着时间的推移在欧洲传播的,我们可以清楚地看到一种地理模式。意大利正在蓬勃发展!

让我们来看看最受 meetup 用户欢迎的话题。

除了环境,似乎大多数 meetup 成员都在为贝佩·格里洛动员。此外,贝佩·格里洛在 2009 年至 2017 年发起并领导的政治运动“M5S”也是一个很受欢迎的命名话题。这可以解释在意大利 meetup 的高使用率。

M5S 是一个政治反建制政党,从 2009 年的一场运动中崛起,参加了地区和地方选举。他们在国家议会中没有任何席位,但在 2013 年的全国选举中成为最大的政党。看似突如其来,他们被认为是欧洲历史上发展最快的政党。

五星运动

然而,来自 meetup 的数据显示,从 2005 年起,人们就开始以贝佩·格里洛的名字(粉色)组织聚会。使用社交网络如 meetup 实际上是由贝佩·格里洛的博客建议来组织本地会议的。在“贝佩·格里洛之友”的保护伞下,人们开始使用聚会在贝佩·格里洛的博客上聚在一起讨论话题。虽然贝佩·格里洛仍然更受欢迎,但更普遍地专注于 M5S(蓝色)的聚会仅在 2013 年才开始。2017 年后,贝佩·格里洛辞职,路易吉·迪·梅奥接管了该党的领导权。很容易说这导致了受欢迎程度的大幅下降,但这也为时尚早,因为 2018 年的数据还不完整。然而,更普遍的是,我们可以从这些数据中得出结论,贝佩·格里洛是一个非常受欢迎的领导人,甚至比他所代表的政党更受欢迎。

M5S 动员是为了什么

政治学的一个关键问题是确定政党代表什么样的利益。使用来自 meetup 的数据,我们可以获得一些有趣的见解,了解 M5 的追随者在动员什么。

通过将 M5S 与其他主题的成员重叠表示为纽带(阈值为所有成员的 1%),我们可以看到意大利反建制党的成员正在动员哪些主题。领带颜色越深,话题之间的重叠程度越高,联系越紧密。这个图表告诉我们,M5S 成员动员最多的是环境替代能源,其次是政治地方政治,之后是拯救我们的民主

根据这一分析,你可以推断政治运动的积极追随者一方面主要关心环境问题,另一方面关心民主状况,并对参与(地方)政治感兴趣。虽然这些利益似乎与 M5S 现在在政府中的实际成就形成了鲜明的对比,但他们似乎确实符合 M5S 选民对政治上特别活跃和反建制的描述(帕萨雷利&图尔托 2018 )。

警告:可靠且有代表性的数据

作为一名优秀的社会科学家,你应该经常问自己(至少)两个问题:1)我的数据有多可靠,2)有多有代表性?

首先,当我可能没有度量我想要度量的东西时,可靠性问题就出现了。例如,在线社交网络可能与现实世界中社会动态的展现方式不同。这当然是一种简化。然而, meetup 是一个帮助人们组织真实世界中真实事件的社交网络。然而,也有可能 1)会员实际上并没有参加这些活动,2)组织者分配给活动的主题可能并没有反映出活动实际包含的内容(例如,我看到了许多园艺聚会,尽管我怀疑这是他们真正想要的。)

第二,如果你想推断出一些你的数据没有直接捕捉到的结论,数据的外部验证是一个问题。在这种情况下,很可能是谁在使用 meetups 进行动员方面存在偏见。例如,使用社交网络在年轻人中可能比老年人更普遍。只有那些愿意参加公共辩论或政治集会的人才会成为这种聚会的成员。虽然研究确实表明 M5 的选民大多是 35 岁以下的年轻人,在政治集会和公共辩论中的活跃程度高于*均水*,但并非所有 M5 的追随者都是如此。简而言之,样本总体可能不是实际总体的均衡代表。从可能存在系统性偏差的样本人群中得出结论是很棘手的,需要额外的稳健性测试。

结论

总之, meetup 为社会和政治运动的研究提供了极具价值的新数据来源。这是一个免费的资源,允许研究人员在社会和政治运动出现在更传统的数据源之前研究它们的出现和发展。从民主党到茶党,几位美国政客已经认识到了 Meetup 的力量。在欧洲,你可以清楚地看到贝佩·格里洛和 5 Stelle 运动的崛起,使用社交网络分析可以显示他们的追随者在动员什么话题。尽管如此,数据科学工具的使用并不意味着社会调查的警告应该被忽略。社会科学家仍然应该确保数据的可靠性和代表性,以便得出结论。

权力越大,责任越大。

承认

Reini Schrama 是哥本哈根大学政治科学系的博士后。她的专长是欧洲政治、社交网络分析和社会科学数据科学工具箱的使用。2018 年初,她参加了推进学院(Propulsion Academy)的数据科学训练营(点击这里了解更多信息)。

使用预先训练的 word2vec 进行模因搜索

原文:https://towardsdatascience.com/meme-search-using-pretrained-word2vec-9f8df0a1ade3?source=collection_archive---------5-----------------------

沙巴发展故事#02

模因抵得上千言万语。它们是一种文化。我和我的朋友过去常常用 Giphy 在 Messenger 上发送很多这样的消息。事情是这样的,我们有自己的模因,我们懒得上传到某个地方。与此同时,当你开始在一个文件夹中有很多迷因时,就很难记住它们的文件名了。

Little UI for the search system.

让我们尝试快速构建一个小工具,帮助我们了解哪些模因更有可能对应一个输入的句子。我们会有一个配对列表。每一对都是一个图像 URL(而不是本地路径,对您来说更容易测试)和与之相关的描述。

url_descr = [
    ('[https://tny.im/a13](http://tny.im/a13)['](https://giphy.com/embed/26uTr7qPYM4OHAwBW'), 'we don\'t care'),   
    ('[https://tny.im/a0-](http://tny.im/a0-)['](https://giphy.com/embed/3o6Zt6D0wctP0kpuwg'), 'i love you'),
    ('[https://tny.im/a12](http://tny.im/a12)['](https://giphy.com/embed/aJlKIh8Kh0NLa'), 'relax take it easy'),
    ('[https://tny.im/a16](http://tny.im/a16)['](https://giphy.com/embed/ohyNdetcfoJ9K'), 'that is embarrassing'),
    ('[https://tny.im/a10](http://tny.im/a10)['](https://giphy.com/embed/lwrxYI7f2tNFS'), 'screw you guys')
]

我不会在这里详细解释单词嵌入;已经有关于这个主题的好文章[1,2],没有必要重新发明轮子。但是,我将给出一个高层次的概述,以便每个人都可以遵循。

单词嵌入和 word2vec

单词是离散的符号,表示它们的一种简单方法是一键向量。假设我们有一个大小为 4 的词汇表,每个单词由 4 个元素组成的列表来表示,在当前单词的索引处,除了 1 之外,所有元素都是 0。

vocabulary = ['hello', 'sun', 'desert', 'hi']
hello = [1 0 0 0]
sun = [0 1 0 0]
desert = [0 0 1 0]
hi = [0 0 0 1]

如你所见,这种表示法并不是最好的,因为如果词汇表包含成千上万的单词,那么列表将呈线性增长。但另一件重要的事情是,这种表征没有给我们任何关于单词含义的线索,甚至没有给我们任何单词之间如何联系的线索。在我们的词汇中,“hello”和“hi”有相同的意思,但是我们看不到这种与一个热点向量的关系。这里来了一个名为 word2vec 的文字嵌入算法。

这个想法是将我们的热点向量映射到密集(更密集)的向量,这样我们就可以解决大小问题;理想情况下,我们希望具有相似/相关含义的单词具有彼此接*的向量,就好像向量空间已经编码了单词的语义/上下文表示。

Skip-gram word2vec, a neural network trained to predict a window of words given the focus word as input. The word embedding matrix is the resulting weight matrix after training.

我们要训练一个 word2vec 模型吗?那鸿我们说我们想快速构建这个工具,为此我们将使用预训练的 word2vec 向量,即使我们想训练我们自己的模型,我们也不能,因为我们没有足够的数据来做这件事。

现在,让我们开始编码,我们将从这个 google drive 下载在 Google News 上训练过的预训练 w2v,然后是pip install gensim。Gensim 是一个很棒的库,允许以一种高级的方式处理 NLP。加载预训练的 word2vec 只需要一行代码。

import gensim
model = gensim.models.KeyedVectors.load_word2vec_format(W2V_PATH, binary=True)

现在模型加载完毕,我们可以看看单词是如何表示的:

>>> model.wv['hello'].shape
(300,)
>>> model.wv['hello']
array([-0.05419922, 0.01708984, ..., -0.25], dtype=float32)

向量的大小为 300,而谷歌新闻的词汇量约为 300 万字!我们说过,word2vec 的一个特点是,出现在相同上下文中的单词在距离方面倾向于具有彼此接*的向量,因为从语义上来说,它们可能是接*的。

>>> model.similar_by_word('hello', topn=5)
[('hi', 0.6548984050750732), ('goodbye', 0.639905571937561), ('howdy', 0.6310957074165344), ('goodnight', 0.5920578241348267), ('greeting', 0.5855877995491028)]

你可以看到根据余弦相似度(一种常用的距离度量),“hi”是最接*“hello”的单词。我总是对此感到惊讶;我们现在有了一个更小的向量空间,它似乎对关系进行了编码,而不是一个大的独热向量,它不能告诉我们单词之间的关系。

def cosine_sim(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

Cosine similarity. The closer to one the better

句子呢?

到目前为止,我们一直在谈论单词和它们之间的相似性,但我们需要的是一种方法来衡量两个句子之间的相似性,这似乎很复杂。当然,它是,但是我们正在建立一个小工具,我们想要好的结果而不是完美的。

def avg_sentence(sentence, wv):
  v = np.zeros(300)
  for w in sentence:
    if w in wv:
      v += wv[w]
  return v / len(sentence)

*均单词向量是一种比较两个句子的简单方法,是的,这是一个嘈杂的过程,因为我们丢失了短语中的单词顺序,所以两个单词顺序相反的句子会给出相同的*均向量,但通常意义不同。另外,所有的单词都有相同的权重,而像“a”或“the”这样的单词在理想情况下应该不那么重要。然而,这个技巧非常有效,所以我们将坚持使用它,以使整个事情更简单。这种技巧背后的直觉是,如果两个句子相似,它们的*均向量将在(几乎)相同的位置结束。

>>> inputv = avg_sentence('i like you'.split(), model.wv)
>>> vec2 = avg_sentence('i love you'.split(), model.wv)
>>> vec3 = avg_sentence('screw you guys'.split(), model.wv)
>>> cosine_sim(inputv, vec2)
0.87972317862080773
>>> cosine_sim(inputv, vec3)
0.66992365073780347

所以现在我们有办法知道两个句子是否相似,接下来的步骤非常简单。记住我们有一个配对列表。每一对都是一个图像 URL 和与之相关的描述。
按顺序:

  1. *均输入查询和模因描述
  2. 计算*均输入和*均描述之间的余弦相似度
  3. 按照余弦相似度降序排列列表,这样与输入句子最相似的描述将首先出现。
>>> avgs = list(map(lambda p: p + (avg_sentence(p[1].split, model.wv),), url_descr))
>>> sims = list(map(lambda p: p[:2] + (cosine_sim(inputv, p[2]),), avgs))
>>> most_similar_meme = sorted(sims, key=lambda p: p[2], reverse=True)
>>> most_similar_meme
[('[https://tny.im/a0-'](https://tny.im/a0-'), 'i love you', 0.87972317862080773), ('[https://tny.im/a10'](https://tny.im/a10'), 'screw you guys', 0.66992365073780347), ('[http://tny.im/a13'](http://tny.im/a13'), "we don't care", 0.56639891559620026), ('[https://tny.im/a12'](https://tny.im/a12'), 'relax take it easy', 0.40517121688823338), ('[https://tny.im/a16'](https://tny.im/a16'), 'that is embarrassing', 0.2843743794717129)]

结论

我们看到了如何使用预训练的单词嵌入来构建一个非常基本但还不错的迷因检索系统。然而,它远非完美,例如:

>>> inputv = avg_sentence('i like you'.split(), model.wv)
>>> vec2 = avg_sentence('i love you'.split(), model.wv)
>>> vec3 = avg_sentence('i hate you'.split(), model.wv)
>>> cosine_sim(inputv, vec2)
0.87972
>>> cosine_sim(inputv, vec3)
0.87976

根据这个模型,“恨”比“爱”更像“喜欢”(尽管差别很小)。这可以用这样一个事实来解释,即在训练中,“恨”和“喜欢”在相同的上下文中出现的次数比“爱”和“喜欢”多一点。然而,还有很大的改进空间,可以用来纠正这些缺陷,如句子分类,词频加权(tf-idf)等

我尽了最大努力让这篇文章尽可能简单(例如,我假设语义和上下文是一回事,而它们不是),如果你发现任何错误,请在 Twitter@ eyyub _ s或在评论区告诉我。大大感谢我的 shab@ ImLaaraj

要点

[1]http://mccormickml . com/2016/04/19/word 2 vec-tutorial-the-skip-gram-model/
【2】http://colah . github . io/posts/2014-07-NLP-RNNs-re presentations/

记忆,注意力,顺序

原文:https://towardsdatascience.com/memory-attention-sequences-37456d271992?source=collection_archive---------2-----------------------

我们已经看到分类神经网络的兴起和成功。神经网络的下一个重大步骤是理解来自观察和与现实世界互动的复杂时空数据。我们之前谈过在这个领域运作的新一波神经网络。

但是我们如何利用这些网络来学习现实世界中的复杂任务呢?比如,我该如何告诉我的高级真空清洁机器人:“Roomby:你忘了用吸尘器清理客厅红色沙发下的污点了!”并得到适当的回应?

要做到这一点,我们需要用注意机制来解析时空信息,这样我们才能理解复杂指令以及它们与我们环境的关系。

让我们考虑几个示例应用:文本或视频的摘要。考虑这段文字:

一个穿白色裙子的女人向一个穿蓝色裙子的女人走来。她切了几片苹果。然后她给了穿蓝衣服的女人一片。

为了回答这个问题:“谁提供了一片苹果?”我们需要关注“苹果”、“苹果所有者”、“给予”等词汇和概念。故事的其余部分是不相关的。故事的这些部分需要我们的关注。

类似的情况也发生在视频摘要中,一个长视频可以被摘要为一小组帧序列,在这些帧序列中,重要的动作被执行,并且再次需要我们的注意。想象你在找车钥匙,或者你的鞋子,你会关注视频的不同部分和场景。对于每个行动和每个目标,我们需要把注意力集中在重要的数据上,而忽略其他的。

Example of video summarization

仔细想想,摘要和一组集中的数据对于每个时间序列都很重要,无论是文档的翻译,还是视频中的动作识别,或者是任务的句子描述和环境中的执行的组合。

所有这些任务都需要把数据减少到焦点集中,并注意这个集中以便提供一个答案或行动

注意力是擅长理解序列的神经网络最重要的组成部分之一,无论是视频序列,现实生活中的动作序列,还是输入序列,如语音、文本或任何其他数据。无怪乎我们的大脑在很多层面上实施注意力,为的是只选择重要的信息进行处理,排除掉手头任务不需要的铺天盖地的背景信息。

神经网络中注意力的一个伟大回顾是这里给出。我在这里报告一些重要的图表作为参考:

An attention model is a method that takes n arguments y_1 … y_n and a context c. It returns a vector z which is the summary of the y_i focusing on the information linked to context c. More formally, it returns a weighted arithmetic mean of the y_i and the weights are chosen according the relevance of each y_i given the context c.

Implementation of the attention model. Notice that m_i = tanh(W1 c + W2 y_i), meaning that both y_i and c are linearly combined.

Attention model with dot-products used to define relevance of inputs vs context.

上面最后两个数字都实现了“软”注意力。硬注意是通过随机选取概率为 s_i 的输入 y_i 中的一个来实现的。这是比软注意的*均化更粗略的选择。软注意的使用是首选的,因为它可以通过反向传播来训练。

注意力和记忆系统也在这里用很好的形象化描述。

正如他们在这篇文章中提到的,注意力是有代价的,但实际上这种代价可以通过分级注意力模块来最小化,比如这里实现的。

现在看看 attention 如何能够为翻译实现整个 RNN:

它可以通过堆叠多层注意力模块来实现这一点,并采用如下架构:

Sequence to sequence system: an encoder takes in an input sequence x, and produces an embedding z. A decoder produces an output sequence y, by taking as input the embedding z and the previous output y of t-1.

Module used for attention here. Q = query, K = key, V = values. Q and K are multiplied together and scaled to compute a “similarity metric”. This metric produces a weight that modulates the values V.

在多头注意力中,可以并行使用多个注意力模块:

Multiple attention heads are used in parallel to focus on different parts of a sequence in parallel. Here V,q,K are projected with neural network layers to another space, so they can be scaled and mixed.

整个基于注意力的网络被称为“变压器”网络:

在 RNN,时间被编码在序列中,因为输入和输出一次流一个。在前馈神经网络中,需要表示时间来保存位置编码。在这些注意力驱动的网络中,时间被编码为一个附加的额外输入,一个正弦波。它基本上是一个添加到输入和输出中的信号,用来表示时间的流逝。注意这里的脑电波与神经振荡的生物相似性。

但是为什么我们要使用基于注意力的神经网络,而不是我们到目前为止一直在使用的 RNN/LSTM 呢?因为它们使用的计算量少得多!

如果您阅读论文的表 2,您将会看到这些网络可以节省 2-3 个数量级的操作!这是一些严重的节约!

我相信这种基于注意力网络将会在神经网络的许多应用中慢慢取代 RNN。

在这里你可以找到关于变压器架构和数据流的精彩解释!

记忆

一项重要且有趣的工作是快速加权。这项工作实现了一种神经联想记忆——这是一种短期记忆,位于神经权重(长期)和递归权重(基于输入活动的非常快速的权重)之间。快速权重实现了一种类似于上面看到的神经注意力机制的记忆,其中我们将当前输入与一组存储的先前输入进行比较。这基本上就是上面看到的“点积注意力模型”中发生的事情。

在快速加权中,输入 x(t) 是用于与下图中先前存储的值 h 进行比较的上下文

Fast associative memory implemented in Fast Weights

如果你读了的论文你会发现这种神经网络联想记忆再次胜过 RNN 和 LSTM 网络,同样注意力也能。

我认为,这再次证明,目前由 RNN 执行的许多任务可以被像这样计算成本更低(更不用说使用更少的内存带宽和参数)的算法所取代。

还请再看:注意力递归比较器,也是结合注意力和递归层来了解一个学习单元的细节。

关于作者

我在硬件和软件方面都有将* 20 年的神经网络经验(一个罕见的组合)。在这里看关于我:媒介、网页、学者、 LinkedIn 等等…

捐款

如果你觉得这篇文章有用,请考虑捐赠来支持更多的教程和博客。任何贡献都能有所作为!

男人 vs 女人:媒体最受欢迎帖子的比较

原文:https://towardsdatascience.com/men-vs-women-comparing-mediums-most-popular-stories-by-gender-23e0767252d?source=collection_archive---------6-----------------------

为了好玩,我从网上搜集了 1000 篇今年 3 月至 10 月写的《灵媒》最受欢迎的故事。我使用 Python 的 lxml 包从这些帖子中构建了一个数据集,其中的特征是作者、标签、阅读时间、回复数、点击数和域名。

从作者的名字,我用 R 的性别包确定了他或她的性别。当 R 说不清的时候,我通过查看个人资料图片或阅读帖子来寻找线索。给定数据集,我比较了男性和女性发表的帖子有何不同。

1。计数

男性发表的文章是女性的 3 倍多。73.6%最受欢迎的帖子由男性撰写,22.6%由女性撰写,其余由某个团体或组织撰写,如中等职员。

2。标签

我取了女性和男性帖子中标签数量的比率,并在分子和分母中添加了一个常数 1.01。女性职位比男性职位更有可能是:

 ** Tag Ratio Fcount Mcount**
          Women  16.8     16      0
       The List  15.9     15      0
        Russian  10.9     10      0
 Fat Acceptance   6.9      6      0
  Body Positive   6.9      6      0
       Feminism   5.5     21      3
         Sexism   5.0      4      0
     Brain Body   5.0      4      0
           Rape   4.0      3      0
        Mueller   4.0      3      0

而男性的帖子更有可能被贴上:

 **Tag Ratio Mcount Fcount**
         UX Design  16.8     16      0
             Apple  15.0     44      2
          Business  13.2     52      3
            iPhone  12.9     12      0
      Productivity  11.8     82      6
  Entrepreneurship  10.2    121     11
 Self Driving Cars   9.9      9      0
   Web Development   9.0     53      5
    Product Design   9.0     17      1
 Augmented Reality   8.9      8      0

3。鼓掌次数、响应次数和阅读时间

女性的帖子*均获得的掌声更少。

但是她们的帖子比男性的回复更多。

这些差异在统计学上并不显著,但如果样本量更大,可能会显著。两组的*均阅读时间持*,都在 9 分钟左右。

4。域名

我还计算了男性和女性帖子的域名比例。偏向男性职位的领域往往是出版物。

 **Domain** **Ratio** **MCount FCount**
 journal.thriveglobal.com  21.9     43      1
   medium.com/the-mission  10.0     59      5
              uxdesign.cc   8.9      8      0
          thinkgrowth.org   8.9      8      0
           mondaynote.com   8.9      8      0
                rantt.com   8.9      8      0
               500ish.com   8.9      8      0
       medium.com/incerto   8.9      8      0
    betterhumans.coach.me   6.9      6      0
             uxplanet.org   6.5     12      1

而偏向女性帖子的域名更有可能是作者自己的媒体托管网站。

 **Domain** **Ratio** **FCount MCount**
                 medium.com/@Amy_Siskind  15.9     15      0
                  medium.com/the-hairpin   5.0      4      0
                medium.com/@thefatshadow   4.0      3      0
               medium.com/@girlziplocked   4.0      3      0
                             thelily.com   4.0      3      0
              medium.com/@caityjohnstone   4.0      3      0
              medium.com/behavior-design   3.0      2      0
 medium.com/conquering-corporate-america   3.0      2      0
             medium.com/code-for-america   3.0      2      0
                    medium.com/@krisgage   3.0      2      0

我的直觉是,女性在写博客、写自己、写个人经历和写政治时会采取更内省的方式。相比之下,男性倾向于关注最新的科技热潮或如何制造东西。

圣诞快乐,新年快乐

原文:https://towardsdatascience.com/merry-christmas-and-happy-new-year-2843fe6ee83f?source=collection_archive---------11-----------------------

我们祝你节日快乐,新年快乐🎄

🎁祝圣诞快乐,新年万事如意。我们希望你照顾好自己,和你爱的人一起庆祝这个节日。

向数据科学团队全体成员致以诚挚问候。非常感谢我们忠实的 TDS 读者,感谢我们全年提交出色文章的作者,以及我们热情而勤奋的编辑同事:周宇、朱莉莲·许、大卫·埃林顿、安德鲁·德科蒂斯-毛罗、瑞庚、查敏·纳林达、雷沙马·谢赫、哈姆扎·本德姆拉、 赵,本杰明库利,约书亚弗莱明,赫西琼斯,阿什温哈里哈兰,斯瓦普尼尔维贾伊,蒂尔塔约蒂萨卡尔,弗达奥斯杜卡里。

走向数据科学 2018 ✨

  • 我们非常感谢 Medium 的工作人员和团队,感谢他们一直以来的支持,为我们提供了一个没有广告的良好发布*台。
  • 感谢您参与我们的 TDS 之旅——我们才 2 岁多🎂
  • 今年,TDS 的质量提升到了新的高度。我们会继续倾听您的反馈,每个月,我们都会继续收到更多发生在我们*台上的有趣话题。我们鼓励您查看我们 2018 年 12 月月刊中的 年度最受欢迎帖子
  • 2018 年 12 月,我们出版了 我们的读者指南 来帮助您充分利用您的体验,并介绍了 我们的集合 ,它们是我们的编辑推荐的策划数据科学主题。
  • 在幕后,我们全年都在从事多个项目,我们现在还不能与您分享,但 2019 年将是充满希望的一年,我们将继续建立我们的全球社区,并为您提供新鲜和高质量的内容。
  • 如果你想在这个假日季节了解我们出版物的最新情况,你可以在旅行时在 Twitter 、脸书、 LinkedIn 上关注我们,或者通过 App Store 或 Google Play 在你的智能手机上下载 Medium app 。

我们祝愿您在这个假期拥有和*、爱和慷慨,并祝您的 2019 年 TDS 团队幸福快乐🎄🌅⛱

摆弄德国坦克,或者统计学的基本直觉(以及一般的数据推断问题)

原文:https://towardsdatascience.com/messing-with-german-tanks-or-the-fundamental-intuition-of-statistics-and-data-inference-problems-9599dfc604b2?source=collection_archive---------2-----------------------

统计学中我最喜欢的问题是德国坦克问题,主要是因为它迫使你思考统计学的基本问题——你做了什么和你不知道什么真相,以及如何通过合理的假设将碎片联系起来,并思考你可能出错的方式,并通过它们进行推理。数学的细节在足够多的地方都有涉及,但是,我觉得大多数容易获得的解释在给读者一种关于该方法的直觉以及它对处理数据的一般意义上有些欠缺。这是我填补这一空白的尝试。

统计学的根本问题是,无论何时你不得不处理数据,你都不知道真正的真相。你确实可以接触到数据形式的一小部分事实,但是你不知道事实和数据之间的确切关系。这个,你得猜。在德国坦克问题的情况下,你有一些缴获坦克的序列号。他们怎么说德国人到底生产了多少辆坦克?

一些不切实际的假设是必要的,以保持事情简单,至少在开始的时候。我们可以假设坦克被俘获的过程是随机的,也就是说,德国人有 X 辆坦克,但是,其中,我们只是随机俘获了 n 辆坦克。我们假设所有的德国坦克都有序列号,嗯,是连续的,所以如果我们看到一辆序列号为 100 的坦克,这意味着他们以前一定生产过 99 辆坦克——也就是说,他们至少有 100 辆坦克。

鉴于我们对序列号的假设,我们唯一感兴趣的统计数据是被俘获坦克中最大的序列号。如果最大的数字是 200,那就意味着德军至少要有 200 辆坦克。X < 200 的概率为零。

这告诉我们德国人可能拥有 500 辆、800 辆或 1000 辆坦克的可能性是什么?让我们回到我们的假设,我们是随机捕获德国坦克,或多或少。如果德军真的有 1000 辆坦克,而我们随机拿起 n 辆坦克,我们从没见过大于 200 的序列号的几率有多大?如果德国人有 500 英镑,这种可能性有多大?或者,300?对于 X 的每个可能值,即从大于或等于 200 到无穷大的所有数字,可以计算看不到大于 200 的序列号的条件概率。这是德国人可能拥有的坦克数量的分布函数,条件是我们已经看到了最大序列号 200,并且从 X 中“取样”了 n,这个分布的*均值和方差代表了我们的最佳猜测以及我们对这个猜测有多错误的最佳猜测。值得注意的是,就最大可能性而言,“最好”的猜测是德国人正好有 200 辆坦克——但这并不是最好的猜测,因为分布本来就是倾斜的(如果你向左移动,正好 200 处的高悬崖会一直下降到 0,而右边会有一条很长的尾巴)。

如果我必须自己做数学计算,我会从假设均匀分布开始,计算*似分布函数并积分,但链接的维基百科文章显示了精确的数学计算,所以如果你对技术细节感兴趣,我会向你推荐。我想提出这个问题的主要原因是,像这样的问题代表了如何处理数据的一种更诚实,“更纯粹”的表现,在这种情况下,我们必须从认识到我们不知道的东西开始。我们甚至没有一个很好的猜测,在开始的时候,我们想要知道的关于现实的价值是什么。但是,我们有一个合理的猜测,数据是如何从未知的现实中提取出来的,以及数据从现实的不同可能性中产生的条件几率是多少,这也是通过猜测得出的。一旦我们有了条件赔率,我们就可以把它们加在一起,可以说,形成了对现实的条件最佳猜测,并明确承认了我们假设的所有条件。

这些是我们在每次数据分析中采取的完全相同的步骤,但有一个重要的警告:要解决德国坦克问题,我们必须明确认识到,采样过程遗漏了一大块数据(即 200 和 X 之间的差距,不管这个 X 是什么),但如果我们创造性地使用它,这个差距实际上是帮助我们推断答案的信息部分。很多时候,我们并没有把这种差距看得太重。科学应该是关于现实的,而不是数据。数据只是帮助我们理解现实。如果数据是不完整的,有噪音的,或者有其他问题的,也许这实际上告诉我们一些关于现实的有用的东西,我们应该找到有效利用它们的方法。

R 中的“元”机器学习包

原文:https://towardsdatascience.com/meta-machine-learning-packages-in-r-c3e869b53ed6?source=collection_archive---------4-----------------------

本帖发表于 2018 年年中左右。

还可以查看 2019 年底关于第二代元包的后续帖子。

你还记得在统计学课上学过线性回归吗?恭喜你!你现在是一个由统计学家、数学家、数据科学家、计算机科学家、工程师和许多(许多)使用“机器学习”方法的人组成的多样化社区的幸运成员!管它呢,你甚至可以告诉你的朋友,你正在做一些花哨的“人工智能”。

线性回归只是众多监督模型中的一种。还有数百种其他模型,包括:非线性模型、多项式模型、基于树的模型(如 CART、XGBoost)、SVM、神经网络等。这些监督模型既可以处理连续结果(回归),也可以处理二元和多类结果(分类)。

如果我告诉你,不是看多个包,每个包只关注一个单一的方法/模型,而是有一个单一的包,这里称为“元包”,它将使你能够更容易地访问所有这些依赖的模型。这个元包还可以促进多个模型的并行部署,然后聚合结果。每个模型的各种参数仍然可以仔细控制,但是“元包”在更高的分析层促进了元分析方法,将单个模型的结果包装和捆绑在一起。

事实上,集中在元级别,单个模型可以通过简单地列出被考虑的特定模型的名称来应用,并带有一组它们的缺省参数,如果需要的话可以进行调整。这使得可能不完全熟悉模型细节的用户可以将它作为某种“黑盒”来使用。

在这篇文章中,我将对整个机器学习框架使用汽车力学的类比,对任何多元模型使用汽车引擎的类比。早期性能基本的车,以前都是发动机简单。随着技术的进步,今天的汽车速度更快,也更可靠。简单的传动系统被自动齿轮取代。现代汽车是一个由先进部件组成的复杂系统,每个部件都经过精心设计,并很好地集成到一个更广泛的系统中,很好地同步,最终使汽车能够*稳运行。

不同的编程语言对此方法有不同的实现。这篇文章关注的是我自己探索这个主题的旅程,特别是在 r。

pixabay

旧剧本:

过去,我学到的第一个统计模型是线性回归。这可能是引入预测模型的最基本方法。然而,还有许多其他具有相同范围的模型,包括监督的(分类、回归)和非监督的(聚类),它们曾经(现在仍然)像雨后春笋般涌现。此外,由于该领域本身非常多样化,很难审查数百篇科学论文;每一种都有自己独特的框架和数学符号。然后,大约在 2002 年,我得到了一本很棒的书的参考资料,《统计学习的要素》,作者是这个新兴领域的创始人。这本书的 764 页涵盖了人们需要知道的一切,从线性回归模型到神经网络。它还涵盖了过度拟合、交叉验证和集成的主题。方法用详细一致的数学符号描述,并由说明性的彩色可视化支持。

唉,这本书可能不适合所有人,特别是那些缺乏数学背景的人,包括我自己。看完之后,我真希望能有一本类似的更实用的书。理想情况下,它应该涵盖完全相同的主题,但可能有简化的数学概念,更多的应用示例,以及一些针对真实数据集的实际代码演示。我最大的梦想是代码在 r 中。

我的梦想在 2013 年左右实现了,当时上述书籍原作者的学生和一些原作者写了另一本书,《《统计学习导论》》,目的完全相同。他们甚至能够将其压缩到(仅仅)441 页。

pixabay

森林中的第一步

即使在 R 的早期,也有不止一个包可以做几乎任何事情。然而,我感到无所畏惧。在第二本书的指引下,我感到安全可靠,我确切地知道每个模型应该使用哪个推荐的 R 包。我很高兴了解 GLM、卡特和其他人的特定包。

我对应用单个模型了解得越多,我就越好奇(也越贪婪)去了解更多的新模型,尽管它们通常很容易理解并在我的数据集上实现。我学习和实现更多模型的动机部分是为了实现我的模型和数据集的更高性能(就模型预测的准确性而言)。然而,这场竞争并不是唯一的原因。在 Wolpert 和 Macready 提出的“没有免费的午餐”定理的指导下,我有一个合理的科学理由继续尝试尽可能多的模型,该定理认为没有一个单一的模型总是对任何类型的数据集都具有最佳性能。

pixabay

太早兴奋?

对于有大量文档和示例的基本模型,学习如何应用它们几乎是简单明了的。然而,仍然有许多其他复杂的模型不那么容易应用。对我来说,它们的复杂性通常是由于额外的可调参数,这些参数要么缺乏关于如何使用的具体明确的指南,要么可能是这样做的技术超出了我的理解。例如,为一个惩罚回归、LASSO、通过内部交叉验证技术或其他参数调整方法选择 alpha 和 beta 参数。

在我不断寻找新模型的同时,我经历的另一个挑战是实现处理过度拟合问题的方法,比如交叉验证和引导。尽管有专门处理这些方法的包,但是集成它们并把它们包装在不同的模型/包中并不容易。调谐参数的高级搜索方法和系综(特别是叠加)也是如此。

尽管我认为我已经有了如何在各种模型和包中导航的导航图,但很快还是出现了一些失望。将所有这些方法整合在一起太难了。这些模型中的每一个都很难理解,将多个模型包装在一起,相互嵌套,并与其他“繁重”的方法(如重采样、基准测试、堆叠等)联系在一起,使其变得更加复杂和难以应付。

虽然感到沮丧和疲惫,但我仍然希望有一些有效的方法将它们集成在一起,因为最终,所有这些方法都共享相同的“统计学习”工作流:根据训练集训练/拟合模型,用新的数据集(测试)预测结果,以及测量一些性能指标。事实上,这些包中的每一个都有自己的“方言”,反映了开源 R 开发者社区的不同背景。然而,在上述预测模型的框架下,应该有一种方法来统一和重新格式化每个模型/包的输入和输出,以便它们都可以在同一个罩下,然后聚合在一起。

Photo by Neil Thomas on Unsplash

第(首?)缺少链接:脱字符包

尽管有这些挑战,我仍然感到有决心!我不会让一些数学符号或文档较少的包吓走我,我也没有失去希望。

大约在前一本书的同时,另一本书也出版了,【应用预测建模】,这本书大多只用了一个单独的软件包, 【脱字符号 。这个包试图填补上面的空白,提供我一直在拼命寻找的元方法。它统一了来自许多(目前有 237 个)监督模型(分类和回归)的访问(输入)和返回输出。没有必要从头重新编写这些模型。相反,插入符号包将单个包作为依赖项来调用。

一旦多个模型被统一和集成,开发人员继续在更高的元级别上集成其他高级方法:1。基准测试(包括作为私人案例的调优);2.重采样(交叉验证);第三。整体(装袋、增压和堆叠)。

那时我更加兴奋了!尽管我可能还没有完全理解和欣赏 caret 包的全面功能(也许甚至今天也没有),但我比以往任何时候都更愿意开始使用这个非常高效、运行良好的“机器”。

必须有多个元包才能做到!mlr 和 SuperLearner 软件包:

怀着相似的目标,开发了另外两个元包(我不知道确切的历史和时间。这篇文章仅仅代表了我自己,自我选择性偏见,学习这些软件包的方式)。这些元包各有不同的侧重点。除了监督模型之外, mlr 包还实现了用于非监督(聚类)分析的其他模型组(称为“学习者”)以及事件时间(生存)模型。它还列出了大量性能度量标准,以及非常详细的通用分析工作流文档。super leaner封装强调整体(堆叠)部分和通过多核优化的可扩展性。

pixabay

特征工程:可组合预处理步骤/操作/管道的特定扩展:

预测模型性能成功的关键步骤是“特征工程”。这是在将多变量模型应用于数据之前的早期预处理步骤中完成的。它可能包括数据集的转换、缺失值的插补以及特征或样本/观察值的过滤(早期筛选)。它还可以包括这些运算符的任意组合,以任意顺序排列。一旦编译在一起,它就被集成回学习者/模型。

此步骤的推荐实现是将在训练数据集上完成的任何转换也应用到测试/验证数据集。然而,在交叉验证中嵌套这些步骤并不简单。这不像编写一个包含所有预处理步骤的长函数那么简单。相反,它需要一个更一般化的功能框架,该框架将允许对数据的不同步骤/操作组合在一起,可以以任何顺序的方式集成,并且还允许将转换的特定参数适当地传递到测试/验证部分。这个可组合函数的另一个(明显的)用途是直接应用于实际的原始数据集本身,在嵌套重采样之外,以试错的方式简单地检查数据。

上述元包最*用新的补充包进行了扩展,以便于这种可组合的预处理操作。 recipes 包提供了多个共同的“步骤”,这些步骤通过管道连接在一起,可以在嵌套重采样之外“烘焙”成原始数据。同样的, mlrCPO 扩展 mlrsl3 扩展super loader。最*,脱字符/选择软件包的作者写了一本新书《特征工程和选择:预测模型的实用方法》来讨论这种转换。

这三个元包选哪个?无可争议的

品味是无法解释的。列出每个元包的优点或缺点是不公*的,主要是因为每个元包都在不断更新,并使用最新的新工具进行扩展。尽管如此,这场卓有成效的竞赛也有来自其他编程语言的选手(这里就不一一列举了),他们都瞄准了同一个最终目标。

真正重要的是用户学习每个元包的能力,以及用他们自己的数据集成功实现这些解决方案。这取决于所需的特定解决方案的可用性,以及实施所需的文档和支持的级别。这些元包中的每一个都有不同风格的文档/支持(例如 github issues、stackoverflow 等),或者受其开发者背景(行业、学术界等)的影响,或者只是个人风格。可伸缩性也可能是一个应该关注的关键瓶颈。每个元包都以不同的方式处理它。mlr 提供了自己的云环境 OpenML ,用于部署大型管道。super leaker有一个并行化的框架扩展,叫做

如果你很有动力(像我一样),我会鼓励你尝试这三个包中的每一个。理论上,你应该得到同样的结果。

pixabay

元元包(这不是错别字)。

还不确定选哪个元包?当你可以尝试所有的时候,为什么只妥协于一个元包呢?考虑尝试下一个更高层次的“元”分析:元(多个)“元包”。等等,什么?!?我知道,这个想法乍一看可能很吓人,但是请原谅我。这三个元包中的每一个都为单个模型提供了高级元解决方案。为什么不尝试围绕这三个元包做完全相同的事情呢?我们已经知道需要做什么。它们在单个包中做的是完全相同的事情,但这次是在下一个更高的级别:统一、聚合、比较、堆栈。

事实上,已经有跨元包的功能可以将具有相同目的的对象从一个包渲染到另一个包。例如,mlr 包有一个将插入符号的预处理对象转换成 mlr 的函数。虽然目前只对一个组件进行了这种操作,而且只在一个方向上进行,但我猜想不久将会有更多的跨包对象转换函数可用,对于跨“recipes”、“mlrCPO”和“sl3”的所有可能组合和方向的可组合预处理操作符也是如此。也许这种元-元方法甚至可以扩展到 R 之外,还可以跨不同的编程语言。

pixabay

《两种文化》(oy vey):

到目前为止,我小心翼翼地不想卷入关于【两种文化】的无休止的讨论中,尽管猜测我的血统并不困难。我对这个有争议的话题的理解,用我的车来比喻,不仅是关于一个人制造的汽车/发动机,还关于你用它来驾驶的风格。你是一个谨慎的司机吗?为了安全到达目的地,你会仔细评估你周围的环境吗?或者你愿意超速,错过-遵守一些交通法规,只是为了你可以第一个到达?也许你两者都有一点,要看情况而定。我对此的看法是,至少有一个统一的方法来访问和评估不同的汽车/发动机,允许我们以更好的系统方式回答这些问题。

pixabay

如何设计一个好的复杂系统?有凝聚力的设计:

集成多个模型、比较它们并在重采样中嵌套它们的想法绝对不是新的。然而,将所有这些放在一起是上述每个元包试图实现的目标。如果您曾经试图自己编写交叉验证技术,您可能很快就会面临一些编程设计差距问题(边缘情况或其他错误)和其他计算瓶颈,如可伸缩性。

将输入和输出名称/格式统一成一个单一的公共名称/格式只是一个技术性的语义呈现任务。然而,一旦统一,设计一个有凝聚力的系统,将所有不同的组件很好地结合在一起,编织在一起,以拥有一个强大的良好运转的机器,同时也允许各个组件的独立开发,这一点都不简单。

pixabay

(今天)谁都会开车,但是你知道车坏了怎么修吗?!?

偶尔我会回到上面描述的“旧脚本”,寻找特定模型的一些细节。我为能接触到这些资源而感到幸运,这些资源引导我走过了统计学学习的艰难历程。虽然我仍然不确定我是否也应该感到荣幸,在这条道路出现时跟随它,而不是在未来的某个地方开始,立即获得这些现代工具。毕竟,这些“旧剧本”,实际上并没有那么老。它们是最*才写的。假设我对这个领域一无所知,并且读了这篇评论,一夜之间成为这些元包的专家,我还会拥有我通过漫长而曲折的道路慢慢获得的技能吗?

我们生活在一个激动人心的时代,这样强大的工具唾手可得,开源发行版让所有人都可以免费使用。这些类型的元包允许我们访问一个全面的工具,该工具允许模型、性能测量、预处理步骤和可调参数值等的多种组合的集成。所有这些组合都可以很好地打包成一长串参数组,并在一次基准测试函数运行中进行评估。

使用这些元包,它不再是一个难以完成的任务。复杂的组件可以很容易地分解,拆卸成更简单的子组件,仔细测试他们的行为和对整体性能的影响。它还使初学者能够跳过对这些子组件的方法理解,并把每个子组件作为一组相互关联的黑盒来处理。

回到汽车驾驶的类比。驾驶汽车不需要了解汽车复杂的机械结构。然而,如果司机有兴趣提高汽车的性能,他应该更好地了解引擎盖下发生了什么,或者有机会接触到好的机械师。

在这篇文章中,我描述了自己成为汽车“机械师”的历程。对我来说,是从几本书开始的。希望读完之后,你可能会找到一个更好的起点。在熟悉了这些工具之后,您可能很快就会想要自己修改方法中的某些东西,或者根据您自己的特定需求对其进行裁剪,或者建议对现有方法进行改进。我的朋友,那是你无法再逃避肮脏工作的时刻。现在是时候长吸一口气,学习如何扩展这些方法,并投入进去了。我可以向你保证,你会像我一样在途中学到很多有用的东西。玩得开心!

还可以查看 2019 年底关于第二代元包的后续帖子。

*查看我的博客:【https://medium.com/@drorberel *

点击此处查看更多相关话题:【https://drorberel.github.io/】T4

顾问:目前接受新项目!

Meta 用 Pytorch CNNs 标记鞋子

原文:https://towardsdatascience.com/meta-tagging-shoes-with-pytorch-cnns-7a48c3c108fb?source=collection_archive---------9-----------------------

我一直想尝试的是生成描述图像的文本。当以这种方式提出时,两条路径浮现在脑海中。首先将使用 CNN 的组合进行特征提取,并将这些提取的特征提供给 LSTM,让它通过重复迭代来生成描述。第二种方法是构建多标签分类模型,并让输出节点表示特定的标签。第一种模型适用于您希望为图像生成带有语法结构的标题的情况。多标签分类器适用于感兴趣的标签数量有限的情况。这个数字可能很大,只要有足够的数据,就可以用这种方式训练模型。

在这篇文章中,我试图只用原始图像作为输入,为鞋子生成元数据标签。至于方法,我决定使用多标签分类模型。我不使用 CNN + LSTM 路线的第一个原因是,我并不明确需要那种英国式的结构,而这正是 LSTM 的目标。第二个原因是,我觉得我需要比我愿意手工生成的更多的数据,以使模型很好地为我定制的用例训练。我希望我能够利用预训练的网络快速建立一个模型来生成这些元数据标签。这被证明是部分真实的。

注意,我把为每个图像生成的标签放在该图像的标题中。

Generated Tags: Blue, Boot, Below the Ankle

构建数据集

第一个主要步骤是收集一个小数据集,并对其进行标注以进行多标签分类。为此,我抓取了 220 张图像(训练 200 张/验证 20 张),并在电子表格中标记它们。正如我提到的,我只是想有一些非常简单的分类,所以我选定了 19 个分类,涵盖了原色、款式(*底鞋、高跟鞋、休闲鞋、凉鞋等)。),还有一些是对鞋子的更多描述,比如它们是高、矮、有光泽还是有图案。

Generated Tags: Grey, Boot, Heel, Above the Ankle, Patterned

首先要注意的是…这些可能是不好的类别,或者至少可以做得更好。我只是想有某种结构来填充一个体面的数字,但仍然有限的标签数量。特别是最后几个标签是脚踝上方或下方的标签。我想包括这些,因为我认为看看网络是否会习惯于根据图像来确定鞋子的高度会很有趣。

技术冲刺直入一堵墙

从技术角度来看,这是为这个项目定制 pytorch 数据集生成器类的好机会。这非常简单,因为您需要做的只是向它提供 pytorch dataset 基类并添加函数来生成样本。对我来说,这仅仅意味着添加从项目目录中打开图像的功能,并跟踪适当的目标标签。在这种情况下,目标标签是 1 和 0 的长度为 19 的向量。

查看我用于数据准备和培训的 jupyter 笔记本 以了解实现细节

我后来发现的一个注意事项是,BCEWithLogitsLoss()可能更有用,因为它将 sigmoid 图层与损失函数相结合,因此它返回概率(像 softmax 一样),但每个节点都是独立的(不像 softmax)。这可能有助于清理网络的输出。但是我离题了…回到我的失败。

技术设置完成后,我准备开始测试网络和超参数。显而易见的起点是使用一些标准的预训练网络,并尝试针对这个问题对它们进行定制。我测试的第一个网络是 ResNet 50 模型,在用所有 19 个目标类的 200 个训练样本对其进行训练后,我发现这些模型做得……非常糟糕。

我发现,模特们基本上只是把所有东西都叫做“靴子”,有时当感觉有创意时,就叫做“黑靴子”。

按照我目前的方法,我的第一个想法是,目前的模型表现不佳,我的问题的一个可能的解决方案是投入额外的计算能力。因此,我使用预训练的 ResNet 152 训练了另一个模型,并假设 ResNet 50 可能没有为这个问题提取足够有用的特征。

但即使有 3 倍的层数,一个更强大的模型,和超参数调整,我得到的只是更多的“靴子”。在这一点上,我遇到了一个心理障碍,可以用下面这张 GIF 来概括,GIF 是《英雄 6》中的 Hiro Hamada,他没有想出一个项目主题。

在使用我认为可行的一般方法反复失败后,我真正需要的是后退几步,对我的大脑进行一次硬重置。

I still frequently code to Immortals

寻找新的角度

所以按照《英雄 6》中浜田义的建议,我想我必须试着用不同的方式来看待这个问题。

想想我最后会去散步或者练一会儿武术。这一次,我在木人桩上练习咏春拳。虽然这是一个数据科学帖子,但我会简单地说,在木制假人上练习包括用手、胳膊和脚击打假人,以增强骨骼强度并改善形态。一开始会很痛,但一旦你的骨头变硬,就会很放松。

Donnie Yen practicing on a mook yan jong

我在练习时想出的方法简单得令人痛苦。这并不是模型没有提取有用的特征,而是我的目标空间对于我的数据集的大小来说可能太稀疏了。

对于任何给定的图像,它们往往有 3-4 个标签,因此目标数组几乎全是零。在所有 19 个职业的设置中,模型只会经常看到一些组合,但大多数是罕见的…一个常见的组合是“黑靴子”,这似乎可以解释为什么这是所有模型想要返回的原因。

现在,随着问题的重新架构,我准备从新的角度再次发起攻击。我想我可以把这个问题分解成更小的部分,用一套标签生成模型来解决它。

新角度

因此,我发现我可以使用 3 个小的 ResNet 18 模型,而不是抛出一个试图一次预测所有 19 个类的大模型。三个模型中的每一个都在 19 个节点的子集上进行训练。

第一个模型在 7 个颜色特征上被训练。映射到黑色、白色、红色、蓝色、褐色、灰色、棕色。

Generated Tags: Tan, Boot, Heel, Above the Ankle

第二个模型有 7 种风格。靴子、鞋跟、运动鞋、凉鞋、*底鞋、铆钉鞋和休闲鞋。

Generated Tags: Black, Flat, Below the Ankle, Patterned

Generated Tags: Tan, Studded, Sandal, Above Ankle

第三个模型着眼于五个特征的混合图案(鳄鱼纹理、豹纹、奇怪的字符等,脚踝以上、脚踝以下、闪亮或皮革)。

Generated Tags: White, Flat, Below the Ankle, Patterned

在将原始长度为 19 的向量划分为长度为 7、7 和 5 的三个部分之后,我使用其中的每一个作为目标来训练 3 个 ResNet 18 模型。每个 ResNet 18 在 1080 Nvidia GPU 上完成 25 个纪元的训练可能需要大约 3 分钟。

要生成您在所有图像上看到的标签,我所要做的就是让图像通过所有三个模型,并评估输出向量。现在我所做的就是将数组映射回它们原来的类,并检查哪些类有正值,或者如果所有的类都是负值,我会保留值最高的一个。

速度测试

出于好奇,我用这三个模型对标记生成速度进行了基准测试。对于这个项目,我在 jupyter 笔记本中包含了基本的低效测试循环,所有三个模型的推理速度都是每个图像 0.043 秒,因此在我的整个 220 个图像数据集上运行大约需要 9.5 秒。它包括两个内部 for 循环,这使得它非常慢。作为一个快速的改进,我去掉了一个内部 for 循环,发现所有三个模型的每幅图像都增加到了 0.025 秒,总时间是 5.7 秒。

向前看,这个评估算法可以更好地优化运行速度,但我只是想表明,即使有多个模型,推理速度也相当快。在这种速度下,对于更大规模的任务,比如说 1000 万张图像,这种设置需要 69.4 小时。

限制

考虑到训练集很小,以及我是如何有意识地挑选大部分是白色背景的工作室类型的图像的,模特们在下面这种没有白色背景的情况下挣扎。

Generated Tags: Tan, Brown, Loafer, Above Ankle, Leather

我猜这种情况下工作体面,但它可能不应该被称为这些懒汉…至少顺便说一下,我把类似的项目归类为靴子。

在下一个例子中,模型无法解释由模型的肤色等因素引起的额外变化。你可能会发现这些标签似乎都不正确…图片不是脚踝以上的黑色..

Generated Tags: Black , Heel, Above the Ankle

在我这里展示的这两种情况下,我之前构建的图像分割模型可能会有用。前一篇文章的概念是,应用图像分割模型可以帮助清理输入图像,以便像这些标签生成器 ResNet 18s 这样的第二阶段模型在进行正确分类时不会有太多问题。

前进

虽然我没有演示如何生成大量的标签,但我认为在数据很少的环境中,这种方法可以扩展到相当大量的标签。网络不需要考虑和优化目标的巨大变化,因此它应该不难建立。如果你继续使用这种方法,那就意味着你必须调用大量的网络来生成相当窄的标签,并将它们组合起来,以获得那只鞋的完整标签列表。如果输入图像随时间变化或类似情况,保持多个网络协调可能会变得更加麻烦。

在具有大量数据的环境中,使用单个大目标向量来训练更大的模型以生成标签可能是可行的。我的想法是,只要网络能够接触到足够多的样本,目标的稀疏性就不会那么重要。不过这还有待检验。拥有这些大模型的一个缺点是,添加额外的标签要么需要重新训练大模型,要么可以添加额外的小模型来扩充它。

UI 测试的元编程:抽象组合契约

原文:https://towardsdatascience.com/metaprogramming-for-ui-testing-pbt-abstract-compositional-contracting-ad0bc816e503?source=collection_archive---------16-----------------------

正如在之前的博客中提到的,我们已经实现了能够在 TornadoFX 应用程序中检测 UI 组件。

Input Detection accomplished. Still buggy but accomplished.

由于我们正在重构并将代码库转移到 Gradle,为测试存根的生成做准备,我需要思考那些可以在没有智能的情况下生成,但可以提供足够信息使其值得分析的测试。我和比我聪明得多的人(有过跨多个框架编写测试的经验)参加了一个芝加哥 KUG 会议,讨论是否有可能创建 UI 基于属性的测试(PBT)。

有哪些类型的 UI 测试?

让我们来看一个表单,在这个表单中,我们正在编辑从人员表中选择的人员:

让我们从为这个视图编写测试的角度来考虑这些特征:

  • 接*度&渲染视图的排序 —视图如何相对于彼此进行渲染?它们呈现的顺序是什么?车主field坐在textfield的左边吗?形式above就是button
  • QA 测试 —在运行时探索环境,四处点击等。我输入一些信息,然后点击“保存”。
  • 与视图相关的模型属性——当时间表模型的状态变脏时,是否启用“保存”button?父组件是否反映了对实例的特定子集所做的更改?如果我把约翰·希尔换成无名氏,约翰·希尔就不在另一个View里了吗?

我们如何在不关心模型、改变视图和增加不属于视图的组合动作的情况下,将这些属性定义为可测试的东西?

我们需要将我们对视图的关注提升到一个更高的抽象层次,这样我们就可以将想法归纳为一组规则,或者属性,来描述视图如何在应用程序中协同工作。

什么是基于属性的测试(PBT)?

基于属性的测试可以定义为满足一组属性的测试,与我们定义的特定输入或边缘情况相反。测试让我们努力思考,PBT 让我们更加努力思考。它不能替代基于单元的测试,但是更加努力地思考目标(而不是实现)可以帮助我们编写更强大的测试并降低成本。这意味着更高质量的产品和更少的维护。

PBT 最优雅的例子之一可以通过交换性来检验。

Commutative Properties

向左,我们发现加法运算是可交换的,而减法运算不是。

在数学中,我们可以概括说,如果改变输入的顺序不改变输出,二元运算是可交换的。

同样,我们可以尝试描述通用属性来帮助我们编写 UI 测试。

为什么我要为用户界面创建 PBT?

有很多方法可以创建视图并测试它们。许多人对这些测试应该如何设计和编写非常固执己见,但是这些测试对于算法、数据处理和 API 来说更容易编写。你投入一些资源,你期望一定的产出。但是,如果视图没有被形式化,我们如何描述我们对视图的期望呢?作为一个在我的职业生涯中花了一部分时间做 UI 开发人员的人,我避免尝试编写这样的测试,其他人也和我分享了类似的观点。

如果程序能够为特定的应用程序形式化关于一组检测到的视图的属性,那么元编程只能编写 UI 测试。

这是我们想出的主意。

抽象 UI 树收缩

当我们查看契约测试时,我们正在测试一个流程和另一个流程之间的通信行为。我们正在检查模式、实现的状态以及由消费者契约触发的生产者契约中调用的行为。

这是一种常见的微服务之间的测试和不同 API 之间的通信。我们不关心业务逻辑,也不关心预期调用的结果。我们只关心另一份合同的预期通知已经发出。

让我们从上到下看一个应用程序。在这里,我们有一个登录屏幕,正确的凭证提供了对我们可能能够使用的网格选项工作台的访问。选择一个datagrid项会让位于一个*铺图形用户界面,在这个界面中,我们可以将*铺图形和图像拖放到一个预定义的布局上。

我们可以使用drawer来访问图标。单击瓷砖将显示瓷砖的属性。我们还能够导航回工作台。

之前,我们解析了 Kotlin 语言的抽象语法树 (AST)来概括语言组件,并递归和不可识别地检测 UI 输入。

我们不关心与应用程序相关的业务逻辑,也不关心我们在应用程序中创建和使用的模型。为我们的组件 映射一个组合抽象可以帮助定义我们认为应用程序中作为单个关注点的动作周围的属性:

  • 特定视图在什么上下文中?
  • 视图由哪些节点组成?
  • 在这些节点中,哪些节点有输入?这些输入是布尔型还是多输入型?
  • 那些节点有指向其他节点的指针吗?

创建这个组合的“线框”映射可以帮助我们创建一组自定义的属性,我们可以根据这些属性进行测试。

此时,我们已经有能力检测 UI 控件。我们可以修改我们的扫描视图并注入事件订阅,这些事件订阅将监听任何编程输入并将节点分配给状态。

现在我们有了一组抽象的属性来描述我们的 UI,我们在容器中运行的客户端版本和我们的服务器程序之间创建契约接口,并通过套接字促进通信。

为可能的输入组合创建排列应该不难。每次触发控制事件时,我们可以对状态应用二元运算,并可以对这些节点运行状态检查。如果任何财产被侵犯,那么合同就被破坏。

反过来,当且仅当 状态的二元运算在单个节点 上适当改变时,UI 被称为“工作中” 整体结果存在于先前由其代表性组合图定义的应用程序属性的范围内。

我们能在 PBT 上使用机器学习吗?

在我看来,数据科学是好奇的,而不是固执己见的。我们可以从收集自愿数据开始,例如:

  • 哪些测试失败了
  • 通过什么测试
  • 跟踪测试结果和应用程序崩溃之间的相关性

我不能说我知道我们会发现什么,但我们会让分析检测那些有趣的数据趋势。

一旦用元编程实现了 PBT,下一阶段的重点是让这个应用程序对更广泛的受众和更多的框架可用。敬请期待!

使用细胞神经网络、迁移学习和数据增强的转移检测

原文:https://towardsdatascience.com/metastasis-detection-using-cnns-transfer-learning-and-data-augmentation-684761347b59?source=collection_archive---------17-----------------------

Photo by Lurm on Unsplash

本项目的目标是使用 Kaggle 上托管的 PatchCamelyon 数据集【1】在淋巴结的组织病理学图像上检测癌症转移。

对疾病进展的正确诊断对于选择最合适的治疗方案至关重要,这就是为什么医生依赖于可能存在转移的活检组织的组织病理学图像。在这个项目中,我们将训练一个模型来自动检测恶性肿瘤的证据,以帮助医生做出更好的决定,并有望为癌症患者提供更好的护理。

这里介绍的步骤也可以为任何一般的图像分类问题提供一个强有力的基础:

数据

该数据集是一组 96×96 的图像,其中如果在图像的 32×32 中心部分有恶性肿瘤的证据,则每个图像被标记为 1,否则被标记为 0。

Examples from the training set

增大

为了减少过度拟合并增加模型的泛化能力,我们使用数据扩充,这是应用于图像的随机扰动序列,保留了标签信息。用这些扰动进行训练也使模型对噪声更鲁棒,并增加其对*移和旋转的不变性。

Random Augmentations applied to the same input image

模型

我们使用在 ImageNet 上预先训练的 NasNet mobile(参见迁移学习),因为它速度快,因此可以在 6 小时的时间限制内完全在 Kaggle 内核上训练。

培养

我们使用训练集的一小部分作为验证,然后使用模型检查点 Keras 回调来保存最佳权重,并在我们对排行榜数据进行预测之前加载它们。

预测和后处理

对于测试集的每个图像,我们*均原始图像的预测和水*/垂直翻转版本的预测。

Leaderboard Result

这种方法获得了 0.9709 的 AUC 分数,与最先进的 0.963 的数字病理学旋转等变 CNNs 相当。

可以在 Kaggle 上在线运行模型:https://www . ka ggle . com/cvx tz/CNN-starter-nasnet-mobile-0-9709-lb

github Repo:https://github . com/CVxTz/恶性肿瘤 _ 检测/tree/master/code

[1]https://github.com/basveeling/pcam

METIS 简介

原文:https://towardsdatascience.com/metis-introduction-5e772c8affad?source=collection_archive---------12-----------------------

Metis 的第一周主要关注 Python 库“pandas”的使用,这是数据科学家创建、清理和分析数据框的首选工具。作为一个 python 初学者,pandas 文档很难掌握。我发现自己不断地交叉引用课堂上的材料,以找出如何编写多行代码。

在我们的第一个项目中, Benson,我们研究了纽约市 MTA 十字转门的数据,并得出结论来帮助一个假想的客户。在我们集思广益的那一天,我的团队特别饿,我们开始改善煎饼车的业务,这是纽约街头的一个新的快餐车业务!

本森项目

这个项目的第一步是读入数据。我们通过 MTA 数据网站的一系列链接迭代了 pd.read_csv 命令。

这是导入时数据的格式:

经过一些数据清理(去掉列名,去掉极值,将 dataframe 转换成时间序列),我们决定了我们真正感兴趣的时间段。

由于 Crepe Cart 是一种主要在早餐、午餐和晚餐时间针对忙碌工作人员的食品服务,我们决定查看工作日早餐从[7AM-12PM]、晚餐从[3PM-8PM]的进出数据,以及午餐从早餐到午餐的[11AM-4PM]数据和出口的组合。我们在午餐时使用早餐出口数据的原因是,我们假设在清晨离开十字转门的人在附*的办公室工作,并且在午餐时间仍会在该区域。

然后,我们找到了每个时间段按流量(入口+出口)排名的前 10 个站点。

Average daily total for each station for each time period.

Top 10 B/L/D visualized

找到这些群体后,我们开始想办法量化可丽饼销量。我们最终假设转换率为 0.2%——因此,每 500 人经过一个车站,我们的煎饼车就会卖出 1 个煎饼。如果一个站点在不同的时间段排名发生变化(如下所示),我们必须决定是否值得花费时间/成本将快餐车迁移到一个更拥挤的位置。为此,我们假设在曼哈顿的交通条件下,每英里行驶时间为 10 分钟。

Example of station changing ranking

考虑到这些因素,我们计算了绉纱的销售额。

值得注意的是,尽管 B 路线在午餐时间有更多的可丽饼销售,从 34-Penn 到 34-Herald,如果可丽饼车有 3 辆食品卡车,那么它们的旅行就没有意义。相反,他们可以在 34 街和 34 街分别停一辆车。第四辆卡车会走 e 路。

最后的想法

本森项目很好地介绍了 Metis 的工作情况。这既紧张又费时,但我们在一周的下午有很多时间来合作和研究它。由于我们只有一周的时间来完成,我们无法将大量数据纳入我们的分析中。如果有更多的时间,我们可以查看交通的季节性变化、公交/拼车数据,以获得更全面的交通状况,以及每个车站附*竞争餐馆的密度。

分类中的度量和随机过程

原文:https://towardsdatascience.com/metrics-random-processes-in-classification-fd5bafa79505?source=collection_archive---------2-----------------------

在他的书《机器学习》的介绍中,Tom Mitchell 教授将学习定义如下:

对于某类任务 T性能测量 P ,如果由 P 测量的计算机程序在 T 任务中的性能随着经验 E 而提高,则称该计算机程序从经验 E 中学习

事实上,只有通过预定义的性能指标或指标进行评估时,我们才能谈论算法学习。当执行分类任务时,选择正确的指标可能比调整模型参数更重要。为了说明这一点,我们将回顾现有的最常见的指标,并展示它们的优缺点,然后集中讨论具有潜在随机过程的分类任务的特殊情况,在这种情况下,通常的分类指标都不起作用,并提出一种替代方案。

准确(性)

准确度分数(通常写成 ACC )是人们能想到的最直接的度量标准。它只是简单地计算我们在预测总数中预测正确类别的次数。更正式的说法是:

Notations : p_i is the i-th prediction, y_i the i-th target and N the sample size.

就像任何指标一样,这一指标也有其利弊。从好的方面来说,这很容易理解和解释,因为具有 80%的准确性简单地表明有 80%的机会在看不见的数据上预测正确的类别——当然,前提是我们的模型不会过度拟合和概括得很好。然而,当数据集中的类分布是不*衡的,例如当负目标(0)比正目标(1)多得多时,该度量变得无用。事实上,如果 95%的目标是否定的,那么一个总是预测(0)的非常简单(和糟糕)的模型将实现 95%的准确度分数,尽管完全没有用。在这些情况下——这是相当常见的——其他指标如混淆矩阵就派上用场了。

混淆矩阵

混淆矩阵试图比简单的准确度分数更详细地描述分类器的性能。它可以表示为一个计数表,在给定真实值为正或为负的情况下,计数正预测值和负预测值的数量。例如,如果我们要为之前的坏分类器计算一个混淆矩阵,它看起来像这样:

Notations : T/F for True/False, P/N for Positive/Negative

这里我们选择了 2000 的假设样本量。我们可以看到,数据是高度不*衡的,只有 5%的阳性,95%的阴性(0+1900)/2000),并且分类器总是预测一个负值(“预测值”的“阳性”行为空)。但是,尽管允许我们快速浏览预测的分布,在这种状态下,混淆矩阵并没有真正给我们更多的洞察力。另一种方法是用每一列的总和除以每一列的总和,得到所谓的 T2 归一化混淆矩阵:

Normalized confusion matrix. Notation : R for rate.

由于这种标准化,对角线上的每个成为预测正确类别的经验条件概率。当以真类为正的条件时,这种概率称为真正率或灵敏度,否则称为真负率或特异性。因为这些比率不依赖于类别分布,所以使用混淆矩阵通常比依赖准确度得分更可取。在训练过程中,可以将灵敏度和特异性最大化,以收敛到完美分类器——其混淆矩阵等于同一性,因为它只预测实际上是正确类别的类别。在我们的例子中,我们立即看到了一些错误,因为敏感度为零,因此我们可以得出结论,我们注定是坏的分类器确实是坏的(哈利路亚!).

ROC / AUC

一般来说,为了对样本进行分类,分类器会计算一个介于零和一之间的真实值——或者任何其他可以映射到[0,1]的区间——然后通过使用内部判别 阈值(通常默认设置为 50%)来映射该值,高于该阈值时,它会预测正的和反的。这样一个阈值的选择会极大地影响前面指标显示的结果。事实上,如果我们的模型高度偏向负值,即如果它预测的值分布非常接*零,使用 50%或更高的阈值可能会导致它总是预测负值,而选择更低的阈值可能会导致更多的正值,因此可能会更好地反映分类器的性能。

考虑所有可能阈值的一种方法是依靠 ROC 曲线AUC 分数。ROC 曲线是坐标为(灵敏度,1-特异性)或(TPR,FPR)的点的集合,其中每个点对应于相同分类器的性能,但具有不同的阈值。可以看出,对于足够大的数据集,尽管有鉴别阈值,但完全随机的分类器总是将其坐标放在对角线[(0,0),(1,1)]上,也称为无鉴别线。此外,如果一个点在这条线以上的半*面中,那么下面的不等式成立:

换句话说,混淆矩阵对角线上的每个概率都大于 50%,这意味着我们有超过 50%的机会正确预测每个类别,在这种情况下,我们说我们的分类器表现比随机猜测更好。同样的推理也适用于比随机猜测更差的线下点。然而,如果一个分类器总是在所有阈值的非歧视线以下,简单地翻转它的预测就可以使它在线以上,因此是一个可接受的模型。

当阈值为 T=0 时,所有分类器系统地预测阳性,因此它们都位于 ROC 空间中的(1,1)处。相反,当 T = 1 时,发生相反的事情,并且所有分类器都在(0,0)处。为了说明这一点,这里有两个很好的 ROC 曲线的例子:

但是我们如何使用这个度量来比较模型呢?当给定一组分类器时,在每个给定的特异性值,最好的分类器必须具有最好的灵敏度。因此,选择最佳模型的*似方法是保留 ROC 曲线严格高于所有其他模型的模型。不幸的是,这只有在几条曲线之间有明确的顺序时才能实现。为了解决这个问题,我们可以求助于一个更具聚合性的指标,即 AUC 得分

对于每条 ROC 曲线,曲线下有一个相关的面积或 AUC 得分。该 AUC 直接依赖于 ROC 曲线,但具有一些额外的优点,第一个优点是它允许我们使用真实值客观地比较分类器,而不是依赖于图形的视觉解释。此外,可以表明 AUC 等于分类器对随机选择的正实例的排序高于随机选择的负实例的概率。考虑到这一点,我们看到 AUC 是用于二元分类任务的比任何以前的度量更强大的工具,因为它对不*衡数据集是稳定的,易于解释并且客观地对分类器的性能进行排序。

这些指标中的任何一个(尤其是 AUC)在任何确定性场景中都会发挥很好的作用,比如找出某物是否是热狗。在这些情况下,目标值是一组预测值的确定性函数,并且可以尝试按照通常的例程直接处理分类任务来估计该函数。但是在随机场景中,目标除了确定性函数之外还具有随机不可预测成分,预测类别只是估计概率的一个代理,也是估计概率的结果。例如,如果我们试图预测一次公*的掷硬币的结果,对于一个足够大的数据集,没有一个模型可以达到超过 50%的准确率,无论它有多精确。在这种情况下,潜在的目标和我们唯一希望做的事情是评估过程的概率,并找到最佳模型,即预测总是 50%。

不幸的是到目前为止,我们所看到的指标并没有表达出我们在寻找这些概率方面有多好

事实上,对于公*的掷硬币和足够大的数据集,除了不能实现大于 50%的准确度之外,所有的 ROC 曲线都将在非歧视线上,并且 AUC 分数将总是 50%。这并没有给我们更多关于分类器发生了什么的信息,因此需要一个新的度量标准。在许多情况下,基础过程是随机的,例如:

  • 预测量子力学实验的结果,例如,电子的自旋是向上还是向下。
  • 预测扑克游戏中看不见的牌。
  • 预测一个学生是否会在一项特定的任务中取得成功(我们在 Kwyk 做的事情)

在所有这些情况下,使用简单的分类标准会阻止我们在建模方面前进。那么我们应该使用什么度量标准呢?因为我们想要一个度量来告诉我们在预测每个类的连续概率方面有多好,所以我们将关注一个回归度量****MSE

均方误差

均方差或 MSE 是预测值和实际值之间的*方差的*均值。它可以正式写成:

Notations : p_i is the i-th prediction, y_i the i-th target and N the sample size.

在二元分类的情况下,其中 y 是离散变量(0 或 1)p是成功的预测概率,它也被称为 Brier score

为了公*起见,如果我们选择使用的模型总是对所有样本预测相同的概率,快速查看 MSE 配置文件可以让我们找到最佳模型:

MSE values for a fair coin toss when the predicted probability varies from 0 to 1.

这是一个开始,但是我们看到当模型是最优时,MSE 不为零。事实上,总是预测 50%是我们可以选择的模拟公*抛硬币的最佳模型,因为潜在的过程是 a 伯努利 B(0.5)。但是因为最小均方差是 0.25,我们可以认为还有一个更好的模型,均方差是 0.25。这里,p=0.5 时剩余的 MSE 对应于任务中的固有随机性。事实上,当一个过程具有不确定性时,由于我们试图预测的数据中的不确定性,MSE 中总是存在不可避免的误差。现在让我们注意 0.25 正好是 a B(0.5)的方差,它是我们过程的分布。

使用 MSE 实际上允许我们在一组分类器之间进行区分,并确定最佳选项,但是我们仍然没有一个度量标准来告诉我们离完美模型还有多远。这是使用任何先前度量的确定性任务的情况:对于完美模型来说,准确度分数是 100%,混淆矩阵等于同一性,并且 ROC 曲线是 AUC = 1 的*方。在任何情况下,我们都看到,由于我们感兴趣的随机过程的本质,MSE 不可能为零,但我们也知道一种将随机观察结果与其潜在概率联系起来的方法,这就是大数定律(LLN)

事实上,如果预测的概率有任何意义,并且如果我们为每个预测的概率建立一个组,其中我们收集所有相应的目标,对于一个足够大的组,目标的*均值应该收敛到预测的概率。这是朝着期望的度量迈出的又一步,因为我们可以查看每组中*均目标和预测概率之间的差异,我们的分类器越好,这些差异就应该收敛到零。但是当该过程具有连续分布时,这些组的大小将几乎不会增长,并且 LLN 将无法生效。这个问题的一个解决方案是将不同的预测概率一起分组到 K 个组的每一个 n_k 元素中,并将组内*均成功率(目标的*均值)与组的*均概率进行比较。

让我们看看当我们进行这样的分组时 MSE 会发生什么,这里 BS 代表 Brier Score :

Source : “Two Extra Components in the Brier Score Decomposition”

上述计算表明 Brier 分数/MSE 是 5 项相互作用的结果:

  • 不确定性 (UNC):不确定性显示了在我们的任务中固有的随机性。例如,如果我们预测的目标总是 0 或 1,UNC 就是 0,因为在要预测的数据中没有任何不确定性。相反,对于一个完全随机的实验,比如之前的公*抛硬币,不确定性是最大的,等于 0.25。
  • 可靠性 (REL):可靠性项衡量每组中的*均预测与组中的*均成功率之间的偏差(差异)。这告诉我们,我们的模型是否预测“好”的概率。模型越精确,这一项越趋向于零,如果每个组只有一个目标,我们有 REL=MSE。

注意:REL 术语通常可以使用校准方法来“强制执行”。

  • Resolution(RES):Resolution 项通过计算组内*均成功率与全局成功率的差异来衡量分组的质量。该值不能强制执行,但理想情况下,我们希望它尽可能高。高分辨率意味着分组可以很好地区分病例,当每组只有 1 个目标值时,分辨率最高,分辨率=UNC。
  • 仓内方差 (WBV):这是预测的*均组内方差。当不同的概率组合在一起时,该值会增加,否则会减少。当 REL 减小时,它通常增加,因为对于较大的组,*均预测概率向*均成功率收敛,通过 LLN 减小 REL,,但是因为不同的预测概率混合在一起,所以 WBV 增加。
  • 仓内协方差 (WBC):这是另一个仅由于将不同概率混合在一起而产生的术语。它是预测值和目标值之间的组内协方差,因此显示了两者的联合可变性。这也是唯一一个既可以肯定也可以否定的术语。我们希望它尽可能为正,以补偿当更大的概率值与更大的目标值相关联时发生的 WBV,反之亦然。

注意:WBV 和白细胞都为零,每个组只有一个目标。

为了可视化 MSE 分解,我们可以为 n_k = 1 到 100 个元素的 K 个组绘制公*抛硬币示例的每个项:

Simple case of an MSE decomposition for different groupings

正如公式中的意图,MSE 不依赖于分组,因此它仅在模型(预测概率)改变时改变。首先,WBV 和 WBC 项为零,因为只预测了一个概率,因此既没有方差也没有协方差。我们可以注意到 UNC *台为 0.25,这代表了我们试图预测的数据的非常高(实际上是最大)的不确定性。当 n_k = 1 时,RES 自然最大并等于 UNC,但是当我们将越来越多的不同目标组合在一起时,RES 降低到零。最后但并非最不重要的是,对于最优模型,REL 的行为与预期一样,因为它在每个分组中都是最小值,并且由于大数定律,对于较大的分组,它收敛到零。

现在很明显,在原始的 MSE 度量中发生了很多事情。诚然,当试图评估具有内在随机性的任务的模型时,MSE 本身就足够好了,但分解 MSE=REL-RES+WBV-WBC+UNC 提供了更多关于该模型实际上有多好的预测概率的洞察力,这要归功于 REL 项。但是为了使 REL 能够提供信息,分组应该足够大,以便 LLN 能够生效。同时,太大的分组会使指标产生偏差,因为组内预测的概率会偏离*均值,组内成功率也会偏离*均值。

为了找到最佳分组,我们可以将目标定为最小化 REL + WBV,因为第一项希望组尽可能大,而第二项惩罚太大的组。

通过注意到当*均成功率不同于*均概率时,REL 增长,可以找到这个优化问题的*似解决方案。对于足够大的组,该误差与 1/sqrt(n_k) 的数量级相同。类似地,假设我们从对预测进行排序开始,然后将它们分组到区间中,知道如果区间收敛到单个点,WBV 将减小,我们可以最小化区间长度以最小化 WBV。我们还注意到,假设我们假设预测是均匀分布的,区间长度是N _ k/N——这是一个很大的假设,但这里只是寻找一个*似解。为了补偿优化目标中任何缺失的系数,我们最小化这两项的线性组合:

因此,我们找到了一个依赖于一些参数的*似解决方案,让我们改变这些参数,看看这在一些真实数据上看起来如何。

Kwyk 我们提供在线数学练习,让学生做这些练习,然后利用收集到的数据来预测学生在未来的练习中是否会成功,以校准其复杂性。我们用于此任务的分类器预测每个用户在每次练习中的概率,分布如下:

Histogram of the predicted probabilities of our classifier

使用这些概率,我们可以为不同的组大小绘制目标函数的演化图,并查看最小值出现的位置:

我们看到最佳分组确实符合我们的手工解决方案。我们还可以看到,经验最佳值大致在 N^(2/3) 附*,我们建议将此作为最佳团队规模的经验法则。

结论

总之,我们看到通常的分类标准在随机环境中是没有用的。在这些情况下,我们必须依赖回归度量,并直接评估我们的分类器预测“好”概率的能力。解决这个问题的一个方法是使用 MSE 并观察算法的表现。但是 MSE 是许多术语之间复杂相互作用的结果,每个术语都有特定的含义和目的。在随机设置中,MSE 中最有趣的部分是 REL,但这是假设我们之前已经对预测进行了分组。分组可以用几种方法进行,其中一些方法信息不够丰富。为了解决这个问题,我们必须使组足够大,以使 REL 由于 LLN 而收敛,但又足够小,以避免混合太多不同的预测概率。为此,我们提出了一个经验法则,它包括对概率进行排序,然后将 n_k = N^(2/3 个元素分组,并在此基础上使用 REL 度量来评估模型。

奖金: 我们的模型在预测学生成绩方面表现如何?

这里是我们在 Kwyk 的数据中看到的所有指标。我们已经在 500,000 个样本上训练了我们的分类器,并以 66.30%的全局成功率(目标*均值)预测了 500,000 个不同的样本。这些指标是:

  • 准确度分数(阈值 50%) = 75.34%
  • 混淆矩阵(阈值 50%):

该模型似乎随机预测了负面影响

  • 混淆矩阵(阈值 60%):

现在看起来没问题了…

  • ROC 曲线和 AUC:

这意味着我们的模型有 79%的机会对随机选择的正面实例评分高于随机选择的负面实例。

  • MSE : 0.168(低值,但这并不能让我们对模型有所了解)

使用我们的经验法则,对于 n_k = N^(2/3 的组) :

  • UNC : 0.223(任务非常不确定,最大 UNC 为 0.25)
  • REL : 0.0002(这个模型相当精确)
  • RES : 0.054(知道 maxRES = UNC,分组就很好了)
  • (WBV,WBC) : (0.00001,0.00003)这些值非常低,表明分组概率非常相似。

作者:Hicham EL BOUKKOURI

评估您的机器学习算法的指标

原文:https://towardsdatascience.com/metrics-to-evaluate-your-machine-learning-algorithm-f10ba6e38234?source=collection_archive---------0-----------------------

评估你的机器学习算法是任何项目的重要组成部分。当使用度量标准 评估时,您的模型可能会给你满意的结果,比如 accuracy_score ,但当使用其他度量标准(如 【对数损失】 或任何其他此类度量标准)评估时,您的模型可能会给出糟糕的结果。大多数情况下,我们使用分类准确度来衡量模型的性能,但是这不足以真正判断我们的模型。在本帖中,我们将介绍不同类型的评估指标。

分类准确度

对数损失

混淆矩阵

曲线下面积

F1 分数

绝对*均误差

均方误差

分类精度

当我们使用术语“准确性”时,分类准确性就是我们通常所指的。它是正确预测数与输入样本总数的比率。

只有当属于每个类的样本数量相等时,它才能很好地工作。

例如,考虑在我们的训练集中有 98%的 A 类样本和 2%的 B 类样本。那么我们的模型通过简单预测属于 a 类的每一个训练样本,就可以轻松得到 98%的训练准确率

当同一个模型在一个测试集上用 60%的 A 类样本和 40%的 B 类样本进行测试时,那么测试精度会下降到 60%。分类精度很高,但给我们达到高精度的错觉。

当小类样本的错误分类成本非常高时,真正的问题就出现了。如果我们处理一种罕见但致命的疾病,未能诊断出患者疾病的成本远远高于将健康人送去进行更多测试的成本。

对数损耗

对数损失或对数损失通过惩罚错误的分类来起作用。它适用于多类分类。处理对数损失时,分类器必须为所有样本的每个类别分配概率。假设有属于 M 个类别的 N 个样本,则对数损失计算如下:

在哪里,

y_ij,表示样本 I 是否属于类 j

p_ij 表示样本 I 属于类 j 的概率

对数损失没有上限,它存在于范围[0,∞)内。对数损失越接* 0 表示精度越高,而如果对数损失远离 0 则表示精度越低。

总的来说,最小化日志损失为分类器提供了更高的准确性。

混淆矩阵

顾名思义,混淆矩阵为我们提供了一个矩阵作为输出,并描述了模型的完整性能。

假设我们有一个二元分类问题。我们有一些样本属于两类:是或否。此外,我们有自己的分类器,它预测给定输入样本的类别。在 165 个样本上测试我们的模型,我们得到以下结果。

Confusion Matrix

有 4 个重要术语:

  • 真阳性:我们预测为是,实际输出也为是的情况。
  • 真否定:我们预测 NO 而实际输出 NO 的情况
  • 误报:我们预测的是而实际输出是没有的情况
  • 假阴性:我们预测为否而实际输出为是的情况。

矩阵的精度可以通过取“主对角线”上的值的*均值来计算,即

混淆矩阵构成了其他度量类型的基础。

曲线下面积

曲线下面积(AUC) 是最广泛使用的评估指标之一。它用于二分类问题。分类器的 AUC 等于分类器将随机选择的正例排序高于随机选择的负例的概率。在定义 AUC 之前,让我们理解两个基本术语:

  • 真阳性率(灵敏度):真阳性率定义为 TP/ (FN+TP) 。真阳性率对应于所有阳性数据点中被正确认为是阳性的阳性数据点的比例。

  • 真阴性率(特异性):真阴性率定义为 TN / (FP+TN) 。假阳性率对应于所有阴性数据点中被正确认为是阴性的阴性数据点的比例。

  • 假阳性率:假阳性率定义为 FP / (FP+TN) 。假阳性率对应于阴性数据点相对于所有阴性数据点被错误地认为是阳性的比例。

假阳性率真阳性率都在【0,1】范围内。 FPRTPR 都是在不同的阈值下计算的,例如(0.00,0.02,0.04,…)。1.00)并绘制图表。 AUC【0,1】中不同点的假阳性率对真阳性率的曲线下面积。

显然, AUC 的范围为[0,1]。值越大,我们模型的性能越好。

F1 得分

F1 分数用于衡量测试的准确性

F1 分数是精确度和召回率之间的调和*均值。F1 分数的范围是[0,1]。它告诉您您的分类器有多精确(它正确分类了多少个实例),以及它有多健壮(它不会遗漏大量实例)。

高精度但低召回,给你一个非常准确的,但它错过了大量的实例,难以分类。F1 分数越大,我们模型的性能越好。数学上,它可以表示为:

F1 Score

F1 评分试图在精确度和召回率之间找到*衡。

  • 精度:是正确的阳性结果数除以分类器预测的阳性结果数。

Precision

  • 回忆:是正确阳性结果数除以 所有 相关样本数(本应鉴定为阳性的所有样本)。

Recall

*均绝对误差

*均绝对误差是原始值和预测值之差的*均值。它为我们提供了预测与实际产出的差距。然而,它们不能给我们任何关于误差方向的概念,即我们是低估了数据还是高估了数据。数学上,它表示为:

均方误差

均方误差(MSE)非常类似于*均绝对误差,唯一的区别是 MSE 取原始值和预测值之差的*方的*均值。MSE 的优点是更容易计算梯度,而*均绝对误差需要复杂的线性编程工具来计算梯度。由于我们取误差的*方,较大误差的影响变得比较小误差更明显,因此模型现在可以更多地关注较大误差。

Mean Squared Error

就是这样。

感谢阅读。对于任何建议或疑问,请在下面留下您的评论。

编辑

正如许多人指出的那样,一些术语中几乎没有错误。我想,我应该在发表这篇文章之前仔细阅读它。干杯!

参考文献

[## 理解对数损耗

对数损失,或简称为对数损失,是一种分类损失函数,常用作 kaggle…

www.exegetic.biz](http://www.exegetic.biz/blog/2015/12/making-sense-logarithmic-loss/) [## 混淆矩阵术语简单指南

混淆矩阵是一个表格,通常用于描述分类模型的性能(或…

www.dataschool.io](http://www.dataschool.io/simple-guide-to-confusion-matrix-terminology/) [## API 参考-sci kit-了解 0.19.1 文档

这是 scikit-learn 的类和函数引用。请参阅完整的用户指南了解更多详情,因为…

scikit-learn.org](http://scikit-learn.org/stable/modules/classes.html#sklearn-metrics-metrics) [## 如何解读 F-measure 值?

我想知道如何解释 f 值的差异。我知道 f-measure 是一个*衡均值…

stats.stackexchange.com](https://stats.stackexchange.com/questions/49226/how-to-interpret-f-measure-values) [## AUC 代表什么,是什么?

到处寻找,也没能找到 AUC,如与预测相关的,代表什么或意味着什么。

stats.stackexchange.com](https://stats.stackexchange.com/questions/132777/what-does-auc-stand-for-and-what-is-it)

如果你喜欢这篇文章,请点击👏图标来支持它。这将有助于其他媒体用户找到它。分享一下,让别人也能看。

2015 年大都市家庭装修支出趋势分析和 2017 年预测

原文:https://towardsdatascience.com/metropolitan-trends-analysis-for-home-improvement-spending-in-2015-and-projection-for-2017-ca2a8609ceba?source=collection_archive---------21-----------------------

Python 中的熊猫和 Plotly & Seaborn 中的图形分析

数据集:来自哈佛大学住房研究联合中心。我在之前发表在数据科学的文章中使用了相同数据集的子集。

该数据集中感兴趣的特征:

  • 25 个美国大都市地区
  • 收入中位数:2015 年
  • 房屋价值中位数:2015 年
  • 可自由支配的”(厨房、浴室、房间扩建和外部附件)、“替换”(外部、内部、系统和设备)和“其他”(灾难修复、地段或庭院的改善)家居装修支出类别
  • 2015 年家装总支出
  • 2017 年预计实际年度百分比变化

我的分析的要点:

  • 交互式图表,以便更仔细地查看这些数字
  • 可自由支配支出和替代支出呈现负相关
  • 房屋价值中值和收入中值(显然)高度相关
  • 每位业主的*均支出(房屋装修)和房屋价值中值并不能说明全部情况
  • 2015 年家装支出趋势和 2017 年预测
  • 相关矩阵
  • 附 Jupyter 笔记本在最后看到的原始工作

让我们现在开始深入分析。下面是各种特性的相关矩阵表。有趣的是,中值收入和重置类支出百分比之间呈负相关,而中值收入和可自由支配的家庭装修支出呈正相关。这是否意味着随着收入的增加,越来越多的人喜欢改造他们的厨房/浴室/或者增加一个房间/户外设施?或者替换类别上的项目不需要更改?还是随着收入的增加,房主喜欢让他们的房子现代化?有趣的假设,但我没有分析足够的数据来得出任何结论。

下图显示了相关性的强度。一些负相关让我感到惊讶。例如,房屋价值中位数和重置类支出。这将是一个有趣的调查,如果花在美化厨房或/和增加更多的房间等内部装饰上的支出会推动房屋价值的上升。这超出了我在这篇文章中的分析范围。

第一张图显示了可自由支配支出百分比与替代支出百分比之间明显的负相关关系。可自由支配的支出包括厨房、浴室和户外露台等,而替代支出包括屋顶、窗户和绝缘等项目。从图表来看,房主似乎可以负担得起/选择在其中一个类别上花费,而不是两个都花。

一些大都市地区比其他地区更贵/更值钱。很明显,中等收入水*较高的城市拥有更昂贵的住房。

既然我们刚刚讨论了房屋价值和收入的中位数,那么看看在同一个大都市地区,每位房主在房屋装修上的*均支出会很有意思。从图中可以看出,*均每位业主的支出看起来更低。

上图没有非常清晰地显示出每位车主的*均支出。所以我把它画在下面:

2015 年的家装支出和 2017 年的预测在所有 25 个大都市地区几乎完全重叠。这对企业来说既是好消息也是坏消息。这是一个好消息,因为市场看起来很稳定,没有任何冲击和投机,但另一方面,这也意味着市场额外增长或井喷式增长的可能性较小。

上图迫使我在下图中画出预计的实际年度百分比变化。威斯康星州密尔沃基市和密苏里州堪萨斯市预计增长率最高,而德克萨斯州休斯顿市和佛罗里达州迈阿密市预计增长率为负值。

我的 Jupyter 笔记本展示了数据集和原始作品。

使用 Jupyter 笔记本的 ESP 上的 MicroPython

原文:https://towardsdatascience.com/micropython-on-esp-using-jupyter-6f366ff5ed9?source=collection_archive---------3-----------------------

让我们使用 Jupyter 笔记本在 ESP 上玩 MicroPython,以便从传感器获取数据并在物理世界中采取行动。

1.介绍

在之前的一篇文章中,我们探讨了如何使用 Jupyter 笔记本控制 Raspberry Pi:使用 Jupyter 笔记本进行物理计算

这是一次很棒的体验,一旦项目运行良好,我就想,“在 ESP8266 上(甚至在 ESP32 上)使用 MicroPython 测试 Jupyter Notebook 怎么样?”。

众所周知,Jupyter Notebook 是一个开源的 web 应用程序,允许您创建和共享包含实时代码、等式、可视化和叙述性文本的文档。用途包括数据清理和转换、数值模拟、统计建模、数据可视化、机器学习等等。对于“更多”,我们还探讨了“物理计算”。

到目前为止,在我的项目中,我主要使用由 Arduino IDE 使用其 C/C++类型语言编程的 ESP8266–01、8266–12E(node MCU)和 ESP32 来探索物联网和物理计算项目。但是另一个用于编程这些设备的伟大工具是 MicroPython:

MicroPython 是 Python 3 编程语言的一个精简而高效的实现,它包括 Python 标准库的一个小子集,并针对在微控制器和受限环境中运行进行了优化。它的目标是尽可能与普通 Python 兼容,以允许您轻松地将代码从桌面转移到微控制器或嵌入式系统。

此外,我认为使用 Jupyter Notebook 对使用 MicroPython 的 ESP 设备进行编程是一个很好的工具,可以向孩子们教授物理计算,还可以帮助科学家在获取数据时快速进入真实世界玩传感器。

这是我们将在本教程中尝试完成的任务:

  • 输出数字信号以打开/关闭 LED
  • 从按钮读取数字输入
  • 输出 PWM 信号以使 LED 变暗
  • 使用 PWM 输出控制伺服电机位置
  • 读取模拟信号(使用 LDR 的亮度)
  • 读取温度阀 1 线(DS18B20)
  • 读取温度和湿度(DHT22)
  • 通过 I2C 总线使用有机发光二极管显示数据。

2.安装 MicroPython

对于一个新的 NodeMCU(或 ESP32),要做的第一件事是擦除其内存中加载的内容,“刷新”一个新的固件,这将是 MicroPython 解释器。

A.获取新固件:

进入网站: MicroPython 下载并为您的设备下载相应的固件:

例如,对于 ESP8266,最新版本为:

esp8266-20180511-v1.9.4.bin (Latest 01Jun18)

(你可以在这里找到如何安装固件的细节)

理想的情况是创建一个目录,您将在其中使用 MicroPython。例如,对于 mac,从您的根目录开始:

cd Documents
mkdir MicroPython
cd MicroPython

B.将下载的 ESP8266 固件移动到这个最*创建的目录中。

此时:使用串行 USB 电缆将 NodeMCU 或 ESP32 连接到您的 PC。

C.使用以下命令检查您的设备正在使用的串行端口:

ls /dev/tty.*

就我而言,我得到了:

/dev/tty.SLAB_USBtoUART

D.安装 esptool (用于刷新/擦除设备固件的工具)

pip install esptool

E.擦除 NodeMCU 闪存:

esptool.py --port /dev/tty.SLAB_USBtoUART erase_flash

F.刷新新固件:

esptool.py --port /dev/tty.SLAB_USBtoUART --baud 460800 write_flash --flash_size=detect 0 esp8266-20180511-v1.9.4.bin

安装固件后,您可以在终端上使用命令“Screen”玩 REPL*:

screen  /dev/tty.SLAB_USBtoUART 115200
>>> print (‘hello ESP8266’)
>>> hello ESP8266

如果你在 REPL,使用:

[Ctrl+C]来中断 pgm 和

[Ctrl+A] [K] [Y]退出并返回终端。

  • REPL 代表“读取评估打印循环”,是您可以在 ESP8266 上访问的交互式 MicroPython 提示符的名称。你可以在这里了解更多关于 REPL 的信息。

3.安装 Jupyter MicroPython 内核

为了通过串行 REPL 与 MicroPython ESP8266 或 ESP32 交互,我们需要安装一个特定的 Jupyter 内核。

这只需要做一次。

从 Jupyter 文档网站,我们可以列出所有“社区维护的内核”。在那里,我们将被送到:

Jupyter MicroPython 内核

一旦我们在机器上安装了 Python 3(在我的例子中是 Mac),使用 shell 命令(即在命令行上)将存储库克隆到一个目录中:

git clone https://github.com/goatchurchprime/jupyter_micropython_kernel.git

接下来,使用 shell 命令将库(在可编辑模式下)安装到 Python3 中:

pip install -e jupyter_micropython_kernel

这将在 python/中创建一个指向该目录的小文件../site-packages 目录,并使它能够在以后得到改进时“git update”这个库。

这里可能会出错,如果您安装了大量不同版本的 python,您可能需要“pip3”或“sudo pip”。

使用 shell 命令将内核安装到 Jupyter 中:

python -m jupyter_micropython_kernel.install

这将创建一个小文件”。local/share/jupyter/kernels/micropython/kernel . JSON ”, jupyter 用它来引用它的内核。

要找出您的 kernelspecs 存储在哪里,您可以键入:

jupyter kernelspec list

终端 PrintScreen 显示了我在机器上安装的内核列表。注意,在我的例子中,我使用 PIP3 命令安装了 MicroPython 内核,因此,这个内核与其他内核不在同一个目录中(当我试图使用 PIP 安装我的内核时,出现了一个错误)。

现在运行 Jupyter 笔记本:

jupyter notebook

在笔记本中单击右上角的“新建”按钮,您应该会看到列出的内核显示名称:“MicroPython — USB”。

在第一个单元格中,您需要定义将要使用的端口和波特率(115200 就可以了):

%serialconnect to --port=/dev/tty.SLAB_USBtoUART --baud=115200

作为响应,单元格将返回:

Connecting to --port=/dev/tty.SLAB_USBtoUART --baud=115200
Ready.

就是这样!当“Ready”出现时,您应该能够通过运行单元来执行 MicroPython 命令。

让我们试试:

print ('hello esp8266')

您应该会在储存格的输出上收到 ESP8266 的回应:

hello esp8266

4.LED 闪烁

像往常一样,让我们开始我们的物理计算之旅,“闪烁的 LED”。

低于 NodeMCU 的典型引脚排列(ESP8266–12E 1.0 版):

可用管脚有:0、1、2、3、4、5、12、13、14、15、16,对应的是 ESP8266 芯片的实际 GPIO 管脚数。请注意,许多最终用户板使用自己的专用引脚编号(例如标记为 D0、D1 等)。

在 NodeMCU 引脚 0 (D3)上安装一个 LED 并测试它,打开和关闭它:

# import library to deal with pins:
from machine import Pin# define pin 0 as output
led = Pin(0, Pin.OUT)# define value of "led" as "1" or "True" to turn on the LED
led.value(1)# define value of "led" as "0" or "False" to turn off the LED
led.value(0)# also you can use .on() or .off methods to control the pin:
led.on()
led.off()

现在,让我们导入一个时间库并使 LED 闪烁:

from time import sleepfor i in range(5):
    led.on()
    sleep(0.5)
    led.off()
    sleep(0.5)

5:输入数字信号

你可以在 NodeMCU 上读取的简单传感器数据可以通过一个按钮获得。

让我们如图所示,在 13 号插脚(D7)和 GND 之间安装一个按钮。

我们按钮的连接方式是,引脚 13 的正常状态为“高”(因此我们将使用一个内部上拉电阻来保证这种状态)。按下时,引脚 13 将为“低”。

# define pin 13 as an input and activate an internal Pull-up resistor:button = Pin(13, Pin.IN, Pin.PULL_UP)# Read button state:
print(button.value())

当运行上述单元时(不按按钮),结果将是:

1

按下按钮,再次运行电池:

# Read button state:
print(button.value())

现在的结果是:

0

请注意,停止按下按钮不会将“单元格值”返回到“1”。若要查看“^ 1”,您必须再次运行该单元格。

现在让我们做一个小程序,仅当按钮被按下时才打开 LED:

print (button.value())
if button.value() == 0:
    led.on()
else:
    led.off()

6.脉宽调制

除引脚(16)外,所有引脚都可以使能 PWM。所有通道都有一个单一的频率,范围在 1 到 1000 之间(以 Hz 为单位)。占空比介于 0 和 1023 之间,包括 0 和 1023。

开始调用适当的库:

from machine import Pin, PWM

有几个命令可用:

pwm0 = PWM(Pin(0))      # create PWM object from a pin
pwm0.freq()             # get current frequency
pwm0.freq(1000)         # set frequency
pwm0.duty()             # get current duty cycle
pwm0.duty(200)          # set duty cycle
pwm0.deinit()           # turn off PWM on the pin

或者您可以设置立即配置 pin:

pwm2 = PWM(Pin(2), freq=500, duty=512)

让我们将连接到引脚 0 的 LED 从关闭调光到打开:

from machine import Pin, PWM
pwm0 = PWM(Pin(0), freq=1000, duty=0)
for i in range (0,1023,20):
    pwm0.duty(i)
    sleep(0.1)
    pwm0.duty(0)
    pwm0.deinit()

控制一个伺服电机怎么样?

让我们在 NodeMCU 上安装一个小的爱好伺服,如图所示。请注意,我将伺服 VCC 连接到 NodeMCU +3.3V。这对于本教程来说是可以的,但在实际项目中,您必须将伺服 VCC 连接到外部+5V 电源(不要忘记将 GNDs 连接到 NodeMCU GND)。

伺服数据引脚将连接到 NodeMCU 引脚 14 (D5)。

伺服系统通常以 50Hz 的频率工作,然后在大约 40 和 115 之间的占空比将它们分别从 0 度定位到 180 度。占空比 77 会将伺服定位在其中心值(90 度)。

servo = PWM(Pin(14), freq=50)

在不同位置测试伺服系统:

# Minimum position (angle 0)
servo.duty(40)# Maximun position (angle 180)
servo.duty(40)# center position (angle 90)
servo.duty(40)

您也可以创建一个简单的交换程序来测试您的伺服:

# swipping servo
step = 2
for i in range (40, 115, step):
    servo.duty(i)
    sleep (0.1)
    step = -1*stepfor i in range (115, 40, step):
    servo.duty(i)
    sleep (0.1)
    servo.duty(77)

结果下方:

我在这里不使用声纳,所以我将留给你开发一个代码来使用它。很简单 alheady!试试看!

7.模拟输入(测量亮度)

ESP8266 有一个引脚 A0,可用于读取模拟电压并将其转换为数字值。您可以使用以下公式构建这样一个 ADC 引脚对象:

from machine import ADC
adc = ADC(0)

接下来,您可以使用以下公式读取 A0 引脚的值:

adc.read()

例如,模拟引脚可以用来读取作为分压器的电位计的变量值。这可以被解释为用于调暗 LED 或将伺服移动到特定位置的输出。你可以根据我们目前了解到的情况来尝试一下。

另一个有用的例子是使用 LDR(“光敏电阻”)从模拟传感器捕获数据,如温度(LM35)、紫外线(UV)辐射或光度。

当光度增加时,LDR 会减小其电阻。因此,您可以用 LDR 和电阻创建一个分压器,如图所示。

直接读取电阻上的模拟电压,我们将获得与亮度成正比的信号。

让传感器暴露在光线下,读取 ADC 值。

现在,盖住传感器,得到一个较低的值。

就我而言:

  • 最大亮度==> adc 值> 850
  • 最小亮度==> adc 值< 40

8. Controlling 1-Wire Devices

The 1-wire bus is a serial bus that uses just a single wire for communication (in addition to wires for ground and power). The DS18B20 temperature sensor is a very popular 1-wire device, and here we show how to use the "onewire" module to read from such a device.

For the following code to work you need to have at least one DS18B20 temperature sensor with its data line connected to GPIO 2 (D4).

You must also power the sensors and connect a 4.7k Ohm resistor between the data pin and the power pin as shown in the diagram.

Import the libraries:

import onewire, ds18x20

Define which pin the 1-wire device will be connected. In our case ==>引脚 2 (D4)

dat = Pin(2)

创建单线对象:

ds = ds18x20.DS18X20(onewire.OneWire(dat))

扫描总线上的设备。请记住,同一总线上可以连接多个设备。

sensors = ds.scan()
print('found devices:', sensors)

“传感器”是一个数组,包含所有相连的单线传感器的地址。我们将使用“sensors[0]”来指向我们的传感器。

请注意,您必须执行 convert_temp() 函数来启动温度读数,然后等待至少 750 毫秒再读取数值(不要忘记导入时间库)。要读取该值,请使用:ds . read _ temp(sensors[0]):

ds.convert_temp()
time.sleep_ms(750)
print(ds.read_temp(sensors[0]))

9.使用 DHT 传感器读取温度和湿度

DHT(数字湿度和温度)传感器是低成本的数字传感器,配有电容式湿度传感器和热敏电阻来测量周围的空气。它们具有一个处理模数转换的芯片,并仅使用一根数据线提供数字接口。新型传感器还提供了 I2C 接口。

DHT11(蓝色)和 DHT22(白色)传感器提供相同的数字接口,但 DHT22 需要一个单独的对象,因为它有更复杂的计算。DHT22 的湿度和温度读数都有 1 位小数分辨率。DHT11 有两者的整数。自定义协议用于从传感器获取测量值。有效载荷由湿度值、温度值和校验和组成。

如图所示连接 DHT22。数据引脚将连接到 NodeMCU 引脚 12 (D6)。

要使用 DHT 接口,请构造引用其数据 pin 的对象。开始呼叫图书馆:

from dht import DHT22

定义适当的 pin 并构造对象:

data = DHT22(Pin(12))

获取温度和湿度值:

data.measure()
temp = data.temperature()
hum = data.humidity()print('Temp: {}oC'.format(temp))
print('Hum:  {}%'.format(hum))

为了获得最准确的结果,DHT11 每秒最多只能调用一次,DHT22 每两秒调用一次。传感器精度会随着时间的推移而降低。每个传感器支持不同的工作范围。详情请参考产品数据表。

DHT22 传感器现在以 AM2302 的名称出售,在其他方面是相同的。

10.I2C——使用有机发光二极管显示器

I2C 是用于设备间通信的双线协议。在物理层,它由两条线路组成:

  • SCL 和 SDA,分别是时钟和数据线。

I2C 对象是附加到特定总线上创建的。它们可以在创建时初始化,也可以在以后初始化。

首先,让我们导入库:

from machine import I2C

考虑引脚 4 (SDA)和引脚 5 (SCL)上的器件,让我们创建一个 i2c 对象:

i2c = I2C(scl=Pin(5), sda=Pin(4))

现在,你应该扫描 I2C 总线上的最终设备。下面的函数将完成这项工作,返回连接设备的数量及其地址:

def scanI2c():
    print('Scan i2c bus...')
    devices = i2c.scan() if len(devices) == 0:
        print("No i2c device !")
    else:
        print('i2c devices found:',len(devices)) for device in devices:
        print("Decimal address: ",device," | Hexa address: ",hex(device))

让我们在节点 MCU 上安装一个 I2C·有机发光二极管显示器,如图所示。显示器是固态硬盘 1306 (128 x 64)。

运行扫描功能:

scanI2c()

我们将得到的结果是,在地址 0x3c 找到了 1 个设备。

该地址将用于创建 oled 对象,如下所示:

import ssd1306
i2c = I2C(scl=Pin(5), sda=Pin(4))
oled = ssd1306.SSD1306_I2C(128, 64, i2c, 0x3c)

管理显示的一些方法:

poweroff(), turns off the screen. Convenient for battery operation.contrast(), to adjust the contrastinvert(), invert the colors of the screen (finally white and black!)show(), to refresh the viewfill(), to fill the screen in black (1) or white (0)pixel(), to turn on a particular pixelscroll(), scroll the screen.text(), to display on text at the indicated x, y positionDraw lines hline(), vline() or any line line()Draw a rect rect rectangle() or rectangle filled fill_rect()

让我们测试一下我们的展示:

oled.fill(0)
oled.text("Hello esp8266", 0, 0)
oled.show()

现在,让我们在 put 有机发光二极管上显示 DHT22 传感器数据:

data.measure()
temp = data.temperature()
hum = data.humidity()oled.fill(0)
oled.text("Temp:  " + str(temp) + "oC", 0, 0)
oled.text("Hum:   " + str(hum) + "%",0, 16)
oled.show()

11.更进一步

本文为您提供了构建一个更健壮的项目的一些细节,使用 MicroPython 作为编程语言,使用 Jupyter Notebook 作为快速开发和分析的工具。

当然,如果您想在独立于您的 PC 和 Jupyter 的 NodeMCU 上运行用 MicroPython 编写的程序,您必须在任何文本编辑器中将您的代码保存为“main.py”文件,并使用 Adafruit 开发的实用程序:" Ampy "将其下载到您的设备上,以便通过串行连接与 MicroPython 板进行交互。

Ampy 是一个简单的命令行工具,通过串行连接在 MicroPython 板上操作文件和运行代码。使用 ampy,您可以将文件从您的计算机发送到 MicroPython 板的文件系统,将文件从板下载到您的计算机,甚至将 Python 脚本发送到板来执行。

安装:

sudo pip3 install adafruit-ampy

Ampy 通过其串行连接与 MicroPython 板通信。您需要连接您的主板,并安装任何驱动程序来访问它的串行端口。然后,例如,要列出板上的文件,运行如下命令:

ampy --port /dev/tty.SLAB_USBtoUART ls

为了方便起见,您可以设置一个 AMPY_PORT 环境变量,如果未指定 PORT 参数,将使用该变量。例如在 Linux 或 OSX 上:

export AMPY_PORT=/dev/tty.SLAB_USBtoUART

因此,从现在开始,您可以简化命令:

列出内部节点 MCU 文件:

ampy ls

您可以使用以下命令读取安装在 nodeMCU 上的文件:

ampy get boot.py

一旦使用文本编辑器(例如 nano)创建了一个文件,就可以使用以下命令将其安装到 NodeMCU 上:

ampy put main.py

现在,当您按下 NodeMcu 上的“Reset”按钮时,首先运行的程序是“main.py”。

对于 Windows,请参见此处的 Adafruit 说明。

12.结论

一如既往,我希望这个项目可以帮助其他人找到进入令人兴奋的电子世界的方法!

详情和最终代码请访问我的 GitHub 存管: Pyhon4DS/Micropython

更多项目,请访问我的博客:【MJRoBot.org

来自世界南部的 Saludos!

我的下一篇文章再见!

谢谢你,

马塞洛

微软 Azure 机器学习

原文:https://towardsdatascience.com/microsoft-azure-machine-learning-336f83b0f27b?source=collection_archive---------3-----------------------

什么是机器学习?

我先说什么是机器学习。这就是这个世界,在这个世界里,我们有人类和电脑。我们人类从过去的经验中学习,而计算机通过遵循我们编程的指令来学习。问题是我们能让计算机从过去的经验中学习吗?

答案是肯定的,但这种体验有一个名字,叫做数据,因此计算机从以前的数据中学习,这就是机器学习。

机器学习模型分为两大类:有监督的和无监督的。在监督学习中,用大量数据“训练”模型,然后使用算法从未来输入中预测结果。大多数监督学习模型使用回归算法从一组连续的可能结果中计算出一个结果(例如,您的测试分数),或者使用分类算法从一组有限的可能结果中计算出一个结果的概率(例如,电子邮件是垃圾邮件或者信用卡交易是欺诈性的概率)。在无监督学习中,计算机不是经过训练的,而是呈现给它一组数据,并要求它找出其中的关系。K-Means 聚类是一种常见的无监督学习算法。关于其工作原理的详细解释,请参见 https://blog . intercom . io/machine-learning-way-easy than-it-looks/。

https://how-old.net/#的提供了一个很好的机器学习的例子。该网站由微软创建,使用先进的图像识别技术来分析你上传的照片,然后使用 ML 模型来“预测”照片中人的年龄。

Azure 机器学习是一种基于云的预测分析服务,为所有技能水*的数据科学家提供简化的体验。它伴随着 Azure Machine Learning Studio(ML Studio),这是一个基于浏览器的工具,为构建机器学习模型提供了一个易于使用的拖放界面。它带有一个节省时间的实验库,并具有由微软业务(如 Bing)在现实世界中开发和测试的一流算法。它对 R 和 Python 的内置支持意味着您可以构建定制脚本来定制您的模型。一旦您在 ML Studio 中构建并训练了您的模型,您就可以很容易地将它公开为一个 Web 服务,可以从各种编程语言中使用,或者通过将它放在 Cortana Intelligence Gallery 中与社区共享。

ML Studio 通过提供一个拖放模型来简化机器学习,您可以在该模型中构建工作流。使用 ML Studio 和它为工作流建模提供的各种模块,您通常可以不用编写一行代码就可以构建复杂的模型。但是,它允许您在工作流中的任何地方插入 R 和 Python 代码,为您可以建模的内容提供了无限的灵活性。

ML 从数据开始,数据可以来自多种来源。数据在使用之前通常需要被“清理”, ML Studio 包含了帮助清理的模块。(清理的示例包括删除丢失数据的行、用算法替换丢失的数据、删除重复的行以及删除包含“异常值”的行在实践中,清理数据可能非常耗时,通常会消耗构建模型所需时间的 50%。)一旦数据准备好了,你就选择一个算法,通过允许它迭代数据并在其中找到模式来“训练”模型。之后是对模型的评分和评估,这将告诉你模型预测结果的能力。所有这些都是在 ML Studio 中可视化执行的。一旦模型准备就绪,只需点击几个按钮就可以将其部署为 Web 服务,这样就可以从客户端应用程序调用它。

ML Studio 提供了机器学习中使用的 25 种经典算法的固定实现。它将它们分为四类。

异常检测是对数据集中不符合预期模式的项目、事件或观察结果或其他项目的识别。一个典型的例子是检查代表银行交易的数据集,并检测该组中潜在的欺诈交易。

回归算法寻求建立和量化变量之间的关系。通过在因变量和一个或多个自变量之间建立关系,回归分析能够在给定一组输入的情况下以可量化的准确度预测因变量的值。一个很好的例子可以在https://how-old.net/#看到,这个网站让你上传一张照片,然后以不可思议的准确度猜测你的年龄。该网站使用 Azure 机器学习,并将经典回归与高级图像识别相结合。

分类算法的目的是基于由已经被分类(分配到一个类别)的观察值组成的训练数据来识别观察值所属的类别。一个很好的例子是确定一封电子邮件属于“垃圾邮件”还是“非垃圾邮件”。

聚类寻求以这样的方式对一组对象进行分组,即同一组(称为聚类)中的对象彼此之间比其他组(聚类)中的对象更相似。

Azure ML 备忘单可以帮助你为一个模型选择正确的算法,即使你不是一个训练有素的数据科学家。例如,如果您想要使用一组输入值来预测一组连续值的输出值(例如,一个人的年龄),请使用线性回归。但是,如果您对输出的分布更感兴趣,可以使用快速森林分位数回归。使用后者的一个例子是使用生长图表来评估儿童发育。"艾比的身高占她同龄孩子身高的 10% . "相比之下,分类算法用于从一组离散的值中预测值,例如,将电子邮件分类为垃圾邮件或不是垃圾邮件。链接到备忘单http://aka.ms/MLCheatSheet

一旦部署为 Web 服务,模型就可以通过 HTTP 与简单的 REST 调用一起使用。这使得开发人员能够构建从 ML 中获取智能的“智能应用程序”。在下一个实验中,学生将构建和训练一个 ML 模型,将其部署为 Web 服务,然后编写一个使用它的客户端应用程序。

关于 Azure 机器学习的好书——点击这里获得你的免费书籍

在微软 Azure 机器学习工作室这里创建一个免费账户。

感谢我学习机器学习的 Udacity:)

如果你喜欢你所读的,一定要💚作为一名作家,这意味着整个世界

谢谢你,

阿德什·沙阿

在 Kaggle 上使用 Music21 和 Word2Vec 提取 MIDI 音乐数据

原文:https://towardsdatascience.com/midi-music-data-extraction-using-music21-and-word2vec-on-kaggle-cb383261cd4e?source=collection_archive---------5-----------------------

Kaggle 是一个面向数据科学家和机器学习者的社区网站,它提供了几个功能来支持他们的工作和研究。其中一个功能是脚本和笔记本的在线编辑器,他们称之为“内核”。用户可以在线创建和编辑内核,分享关于机器学习算法或 Python 数据结构等主题的知识。

我在那里看了看,看我是否能找到任何与音乐或 MIDI 文件相关的东西,但是我什么也没找到。几乎没有数据库和内核,大多数都集中在分析音乐推荐和偏好上。

这样我决定在那里创建一个新的内核来学习更多关于 MIDI 文件的知识,并通过和声序列来玩 Word2Vec 。在这篇文章中,我将从高层次上描述我所取得的一些成果。你可以在 我的 Kaggle 内核链接上找到所有代码。

主要目标:计算机辅助音乐分析

有一次,我在读关于使用神经网络生成音乐的文章,想起了另一篇关于可解释的人工智能的文章。由于神经网络有“隐藏层”,因此更难理解为什么机器“选择”使用特定的结构来创作音乐。

然后我想,与其让机器做所有的事情,我们可以用电脑来帮助学音乐的学生更好地理解音乐作品。当然,很多人都有同样的想法。例如,在 Youtube 上你可以找到几个节目视频,显示音乐中正在播放的和弦。

我的想法是创建一个内核,在那里你可以选择一组 MIDI 音乐,分析它们,并提取专注于这些作品的知识。这样我就可以回答诸如“贝多芬在这里会用哪个和弦?”或者“Sega Genesis Sonic 游戏上用得比较多的是哪些调号?”

什么是“MIDI”和“Music21”

通常当我们谈论音乐文件时,我们会想到像 MP3 扩展名这样的文件扩展名,这是数字音频的一种音频编码格式。因为它们代表了要听的音乐的音频最终格式,像“音符”或“和弦”这样的概念变得难以想象。

另一种表现音乐的方式是 MIDI 文件。它们是一种非常简洁的方式来表现不同乐器上使用的一系列音符。如今,从你最喜欢的艺术家那里下载一个 MIDI 文件并开始演奏是相当容易的,可以将钢琴独奏转换成吉他独奏,或者分离出你喜欢的低音部分。

根据压缩配置,通常 MIDI 文件小于 20kb,而 MP3 文件可以超过 4mb。此外,MIDI 文件描述了作品中的所有音符,因此我们可以使用任何 MIDI 编辑器轻松检查音乐结构。最后,在提取任何相关信息后,我们可以从 MIDI 文件导出一个通用的音频文件,并对其应用其他的音频处理技术,将两者的优点结合起来。

A MIDI file about Sonic’s famous Green Hill theme opened on MuseScore, you can easily see all notes and each instrument used there. It starts with a piano arpeggio and Synths starting playing on the second measure.

有几个库可以通过编程来操作 MIDI 文件。Music21 就是其中之一。引用他们网站的定义:

Music 21 是一个基于 Python 的计算机辅助音乐学工具包。

人们使用 music21 来回答使用计算机的音乐学问题,研究大型音乐数据集,生成音乐范例,教授音乐理论基础,编辑乐谱,研究音乐和大脑,以及作曲(包括算法和直接作曲)。

我选择在这个项目中使用它是因为:

  • 它使用 Python 代码
  • 它看起来非常健壮,从 2006 年到现在,一直有人在研究它的代码
  • 它很好地支持 MIDI 文件
  • 它有基于音符序列的音乐分析方法
  • 它可以很容易地画出情节和乐谱

With 4 Python lines you can render things like this using Music21, pretty cool!

使用音乐提取音符 21

Music21 使从 MIDI 文件中提取音符变得容易。您可以从每种乐器中获取所有音符,并随心所欲地处理它们。我用了一个 Sonic 的 Green Hill MIDI 文件来制作接下来的图片:

On my Kaggle Kernel I got all notes (excluding drums) and plotted them using a scatter plot. Compare the blue points with the piano instrument from the previous MuseScore picture and try to discover which color represents each instrument there.

Music21 also provides some plot methods for examples like those ones. The first one shows which notes are more frequently used while the second one shows when they are played, which is useful to detect key signature changes (which doesn’t happen in this case).

这个库提供了很多处理音符序列的方法,在这个项目中我主要使用了一个分析键签名的方法和一个从音符组合中获取和弦的方法。例如,音符序列[C,E,G]将从 c 大调音阶中产生第一个和弦。

使用 Music 减少谐波 21

一首音乐可能有数百个音符,这使得分析它变得更加困难。我们可以根据它的和声来简化它,使它更容易理解,同时丢失一些细节,如旋律。[来自维基百科](https://en.wikipedia.org/wiki/Reduction_(music)):

在音乐中,简化是对现有乐谱或作品的改编或转录,其中复杂性降低以使分析、演奏或练习更容易或更清晰;可以减少声部的数量或者简化节奏,例如通过使用音块和弦。

考虑到被分析的小节的上下文、音乐的当前调号和当前小节的音符集,手动操作有几种方法。在这个项目中,我遵循了以下步骤:

  • 找到音乐调号
  • 对于每个小节,合计每个音符被按下的时间,并选择 4 个最频繁的音符
  • 使用 Music21 根据调号找到和弦及其函数
  • 简化和弦名称以避免类似“bII#86#6#5”的名称,即使这意味着丢失和弦信息

考虑到巴赫的 c 大调前奏曲,我用我的方法得到了下面的序列:

['I', 'ii42', 'vii53', 'I', 'vi6', 'ii42', 'V6', 'i42', ...]

A piano sheet showing the first four measures from Bach`s Prelude. I highlighted the first one measure and the notes which are used there. There are only C, E and G notes, so we have a C-major chord. Since the Prelude is in C-major key, the chord is a “I” as my method found. You can find more details here.

使用 Music21 和 Word2Vec 进行谐波分析

我的方法并不完美,猜错了几个和弦,但现在我们可以用每小节一根弦来描述巴赫的前奏和声。因为前奏有 32 个小节,最后我们得到一个 32 个词的列表来描述它的和声进行。

如果我们能得到所有巴赫的作品,并做同样的事情,我们会以一系列的和声序列结束,我们可以分析并发现一些有趣的关系,比如巴赫会在作品中用另一个和弦替换哪个和弦。

Word2Vec 是一种处理文本的技术,引用本文中的一段话:

Word2Vec 背后的想法非常简单。我们假设一个词的意思可以通过它的同伴来推断。这类似于一句谚语,“让我看看你的朋友,我就能知道你是谁。

如果你有两个单词有非常相似的邻居(意思是:使用它的上下文大致相同),那么这些单词可能在意思上非常相似,或者至少是相关的。例如,震惊惊骇、惊讶这些词通常用在类似的上下文中。

在我的 Kaggle 内核中,我从 Sega Genesis games 下载了 450 个 Sonic MIDI 文件,并为每个文件生成了一个谐波减少序列。然后我训练了一个 word2vec 模型来提取更多关于和弦使用的信息。

Key Signature histograms from Sonic games. A-minor dominates and Sonic 3 has the most diverse plot. Sonic 3 is also the game with more different composers (Six, including Michael Jackson) while other games track were composed by a single person.

有了训练好的模型,我能够回答几个仅基于声音成分的问题,一些例子:

In music theory, chord substitution is the technique of using a chord in place of another in a sequence of chords, or a chord progression. A good way to replace chords is to choose chords which share notes. In this picture is showed an A-minor chord (blue) and a B-minor chord (red). Since they don’t share any note, they aren’t a common chord substitution pair. My model gave “0.50” of similarity score for those chords.

In this picture, A-minor chord specific notes are in red while F-major specific notes are in blue. Since they share 2/3 of their notes (purple), they can be used more easily on substitutions. My model’s output when comparing those chords is “0.80”. When comparing an enharmonic chord it gives “0.95”.

最后,我使用我的模型创建了一个比较几种音乐的方法。word2vec 训练模型将每个谐波减少序列转换为数字向量,我们使用余弦相似度对它们进行比较。我选择了这个绿山 MIDI 文件作为基础,并与所有可用版本进行了比较:

  • 翡翠山主题(索尼克 2)——最相似的版本得分 0.990
  • 水城主题(索尼克 3)——最相似的版本得分 0.991
  • 桑多波利斯(Sonic & Knuckles)——最相似的版本得分为 0.963

那么我们可以说,与绿山主题相比,桑多波利斯主题具有最不同的和声结构。

The desert has no green grass, so it makes sense, right? 😛

最终考虑

我希望你喜欢这篇文章,并了解更多的音乐理论和声波主题。

关于 word2vec 的使用,我需要找到一种好的方法来衡量模型的准确性,但我之前基于音乐理论演示的测试给出了不错的结果。其他方法也有很大的改进空间,当我有更多的空闲时间时,我有几个想法可以更多地利用这些数据。如有问题或反馈,请评论。再见!

迈克·特劳特将在休赛期得到一份终身合同…但是他应该接受吗?

原文:https://towardsdatascience.com/mike-trout-is-going-to-be-offered-a-lifetime-contract-this-offseason-but-should-he-take-it-190555642395?source=collection_archive---------6-----------------------

预测 MLB 未来的薪水能帮助特劳特做决定吗?

2 time AL-MVP Mike Trout

1984 年,魔术师约翰逊为洛杉矶湖人队签下了历史上最赚钱的合同之一:25 年,2500 万美元。本质上,湖人给他提供了有史以来第一份“终身合同”,以显示他们对他的忠诚,并确保他们会锁定他的剩余职业生涯。显然,魔术师不会在他 2009 年结束的合同结束时一直打球(他在 1996 年退役),但在 1984 年,人们不可能想到有人会签下 2500 万美元的合同。

快进到 2018 年,我们认为如果一名运动员签了一份 2500 万美元的合同,那他就弄错了。合同似乎每年都在突破极限,看不到尽头。像斯蒂芬·库里(Steph Curry)和拉塞尔·威斯布鲁克(Russel Westbrook)这样的 NBA 明星每年赚 4000 万美元,MLB 投手扎克·格雷因克(Zach Greinke)和克莱顿·克肖(Clayton Kershaw)每年赚 3000 多万美元,甚至 NFL 也开始向四分卫和外接手发放 2500 万美元的薪水。

因此,当你有一个像迈克·特劳特这样的全宇宙棒球运动员接*自由球员,在过去 150 年里以超过所有人的水*打球,那将是一笔巨大的支票。特劳特已经是 MLB 最高位置的球员,预计在 2020 年前每年可以赚 3225 万美元。似乎这还不够,棒球专家们期待他将成为体育史上第一个签署 4 亿美元总价值合同的球员。

为了留住这一代最伟大的球员,他目前的球队洛杉矶天使队决定向他提供一份终身合同,在可预见的未来锁定他。天使们可以为他提供大量不同的选择,但如果你是迈克·特劳特,你会如何谈判这笔交易?签下合同锁定未来 20 年的职业生涯有意义吗,还是应该看看自由代理能带来什么?

我决定看看历史上 MLB 的最高工资,以预测未来几年 MLB 的工资会是什么样子,以及在自由球员时代,特劳特应该如何评价自己。

对于那些对时间序列分析更感兴趣的人来说,这个项目的代码可以在 https://github.com/anchorP34/MLB-Salary-Predictions 的查看。像往常一样,留下你对这个主题的其他想法或你感兴趣的其他分析的评论。

职业运动员赚的钱多得离谱,但情况并不总是如此。1930 年,贝比·鲁斯是第一个收入超过美国总统的职业运动员。所以当我们回顾 MLB 每年最高工资的历史时,我们真的没有看到财富的大幅增长,直到大约 80 年代和 90 年代

Information provided by https://sabr.org/research/mlbs-annual-salary-leaders-1874-2012

由于预测 2020 年的工资不会受到 19 世纪和 20 世纪初工资的影响,我决定将分析缩减到二战后(1945 年至 2018 年)。

对于任何类型的预测/预测问题,尝试找出任何使预测更容易计算的转换都是重要的一步。从上面的图表中我们可以看出,随着年龄的增长,工资呈指数增长趋势。因此,取指数函数(自然对数)的倒数将得到一个更线性的函数。

这更容易处理。有了线性线,我们可以采用指数*滑预测模型来预测转换后的数据,从而在模型中给出更准确的预测。

Time series analysis using different methods and forecasts

从表面上看,这些模型似乎非常符合这一趋势。然而,告诉某人 2020 年最高工资的自然对数将大约是 17.5 对任何人都没有帮助。因此,我们需要将数据“反转换”回其原始形式,并将模型从自然对数转换回指数形式。

1990 was a good year to test a CAGR model since that is where salaries really started to explode

从图中可以看出,霍尔特指数模型比简单指数模型更激进一些,后者似乎认为工资会趋于*稳。我提出的另一个预测是 1990 年至 2018 年的 CAGR(复合年增长率),这只是该时间段工资的*均复合增长率。CAGR 模型比霍尔特指数预测的斜率更陡,所以我决定使用霍尔特指数模型来预测未来的工资,因为它是其他模型之间的一个很好的分割。

根据 Holt 模型,当 Mike Trout 成为 2021 赛季的自由球员时,MLB 的预测最高工资将为 42,752,450.05 美元/年。

就特劳特谈判他的薪水而言,这意味着什么?首先,2021 年的预测工资比他现在的工资高出大约 1000 万美元。如果天使们给特劳特加薪,我会建议至少给提供预计的 2021 年的。这一年他将能够在自由球员中检验他的价值,所以他们也可以提前几年。每个职业中的每个人都想得到自己的价值,所以从天使的角度来看,在他成为自由球员时支付最高工资将证明适当的忠诚水*。

然而,从特劳特的角度来看,如果他现在就拿这笔钱,而不是等到自由球员时代,会有什么不同吗?很难说在好莱坞生活同时拿着 8 位数的薪水是不可能被击败的,但是特劳特来自东北部,为什么像费城费城人队这样的球队不会为像他这样的球员支付那么多呢?等到自由球员时代或者现在签约,在经济上有很大的不同吗?

计算方法是,从休赛期开始,到 2031 赛季,也就是他 40 岁结束这一年,现值年金为 42,752,450.05 美元。我使用了 3%的贴现率来补偿通货膨胀,因为今天的 100 美元在十年后会超过 100 美元。这就是左侧图表中的终身交易 PV。

没有终身的 PV 涉及到迈克特劳特坚持己见,等待他的合同到期,直到他成为自由球员。那就是取他现在合同的现值,然后取 2021 年到 2031 年的 42,752,450.05 美元的贴现年金。

迈克,现在不要拿钱!

除了因为接受终身合约而没有获得 1000 万美元的加薪而损失一些钱之外,特劳特还将在 13 年内损失 1600 万美元的机会成本。与不签终身合同的 4.38 亿美元现值相比,这仅仅是他终身总工资的 4%左右的增长。在最初几年,是的,1.04 亿美元与 1.2 亿美元相比是一个很大的差异,但 4.38 亿美元到 4.54 亿美元你可以选择你和你的家人将在哪里度过你的余生?**

这甚至不是一个讨论迈克,等着看你能在自由市场赚多少钱。

深度学习的里程碑

原文:https://towardsdatascience.com/milestones-of-deep-learning-1aaa9aef5b18?source=collection_archive---------3-----------------------

深度学习到现在已经有十年左右了。自问世以来,深度学习因其成功而风靡全球(见我的文章“什么是深度学习?“关于深度学习如何通过人工智能进化,以及机器学习)。以下是这些年来深度学习的一些更重要的成就。

Alex net——2012 年

The AlexNet Architecture (Image from the research paper: “ImageNet Classification with Deep Convolutional Neural Networks”)

  • 证明了卷积神经网络确实有效。AlexNet 及其由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey E. Hinton 撰写的研究论文“使用深度卷积神经网络进行 ImageNet 分类”通常被认为是将深度学习引入主流的原因。
  • 以 15.4%的错误率获得 2012 年 ILSVRC (ImageNet 大规模视觉识别挑战赛)冠军。(作为参考,ILSVRC 第二好的条目有 26.2%的错误率)。
  • 8 层:5 层卷积,3 层全连接。
  • 将 ReLU 用于非线性函数,而不是之前使用的传统双曲正切函数。
  • 介绍了漏失层的使用,以及克服过拟合的数据扩充。

研究论文:“使用深度卷积神经网络的图像网络分类”——Alex Krizhevsky、Ilya Sutskever、Geoffrey E. Hinton

ZF 网— 2013

The ZF Net Architecture (Image from the research paper: “Visualizing and Understanding Convolutional Networks”)

  • ILSVRC 2013 的冠军,错误率 11.2%。
  • 类似于 AlexNet 架构,通过一些调整和微调来提高性能。
  • 介绍了解卷积网络(又名 DeConvNet),这是一种观察 CNN 内部工作的可视化技术。

研究论文:“可视化和理解卷积网络”——马修·d·泽勒,罗布·弗格斯

VGG 网— 2014

The VGG Net Architecture (Image from the Keras Blog: https://blog.keras.io)

  • 获得 ILSVRC 2014“分类+本地化”类别(非总赢家),错误率 7.3%。
  • VGG 架构很好地处理了图像分类和定位。
  • 19 层网络,带 3x3 过滤器。(与 AlexNet 的 11x11 滤镜和 ZF Net 的 7x7 滤镜相比)。
  • 证明了简单的深层结构适用于分层特征提取。

研究论文:“用于大规模图像识别的深度卷积网络”——卡伦·西蒙扬,安德鲁·齐塞曼

谷歌网— 2014/2015

The GoogLeNet Architecture (Image from the research paper: “Going Deeper with Convolutions”)

  • ILSVRC 2014 的冠军,错误率 6.7%。
  • 介绍了 Inception 模块,它强调 CNN 的各层并不总是必须按顺序堆叠。

The Inception Module (Image from the research paper: “Going Deeper with Convolutions”)

  • 22 块层(单独考虑时超过 100 层)。
  • 没有完全连接的层。
  • 证明优化的非顺序结构可能比顺序结构工作得更好。

研究论文:“深入了解卷积”——Christian Szegedy、、Jia、Pierre Sermanet、Scott Reed、Dragomir Anguelov、Dumitru Erhan、Vincent Vanhoucke、Andrew Rabinovich、Google Inc .、北卡罗来纳大学教堂山分校、密歇根大学安娜堡分校、Magic Leap Inc .

微软 ResNet — 2015

The ResNet Architecture (Image from the research paper: “Deep Residual Learning for Image Recognition”)

  • 赢得了 ILSVRC 2015。
  • ResNet 的错误率为 3.6%,比人类的准确率更高(据说典型人类的错误率约为 5-10%)。
  • 超深(引用论文作者)架构,152 层。
  • 引入了残差块,以减少过拟合。

The Residual Block (Image from the research paper: “Deep Residual Learning for Image Recognition”)

研究论文:“深度残差学习在图像识别中的应用”,,,,任,,微软研究院

随着深度学习模型开始超越人类的能力,我们可以肯定地看到更多有趣的深度学习模型,以及未来几年的成就。

深度学习只是 CNN 吗?

现在,回头看看我们上面的列表,你可能会想知道“深度学习”是否只是卷积神经网络。

不完全是。

实际上,以下所有模型都被认为是深度学习。

  • 卷积神经网络
  • 深层玻尔兹曼机器
  • 深度信念网络
  • 堆叠自动编码器

但是,在深度学习领域,CNN 是最“定义”的,并且解决了更多相关的问题空间,至少目前是这样。但是,请记住,CNN 并不是深度学习的全貌。

我错过了深度学习的什么里程碑吗?请在下面添加您的评论,不要忘记喜欢这篇文章。

如果你想了解更多关于深度学习的知识,可以看看我的书Build Deep:Deep Learning 初学者指南 ,这本书现在已经在亚马逊上出售了。

也可以看看我的博客,感兴趣的代码,亲身体验深度学习。

另请参见:

什么是深度学习? —深度学习是如何产生的,以及它与机器学习和人工智能的关系(是的,它们的意思略有不同)。

相关链接:

你需要了解的 9 篇深度学习论文——这篇文章激发了我写这篇文章的灵感。

原载于 2017 年 7 月 31 日www.codesofinterest.com

思维编码

原文:https://towardsdatascience.com/mind-coding-99acd368d36d?source=collection_archive---------6-----------------------

神经健康的简单步骤

在重新编码你自己的神经瘤和照顾你的神经瘤中,我讨论了这样一个观点,即思维是我们自己头骨中庞大的、有生命的、复杂的湿技术系统的自然属性;我们的神经瘤,值得我们亲自关心和关注。

它是由数万亿个脉冲和通信分子产生的,这些分子在多个相互连接的反馈回路中工作。

但是,尽管如此,我们在很大程度上忽略了它。我们在一系列不断变化的注意力状态中度过每一天,让它看不见,被我们的情感所吸引。

就像太阳一样,除非是大热天,否则还是看不见的好。

这种不可见性是由于微调。经过数百万年的进化,神经瘤完美地适应了我们的环境。它特别善于发现差异,忽略相同之处。正因为如此,重新编码只是改变我们的环境来上传新的代码。

我们的环境就是我们自己,如果我们身体上发生变化(做和想不同的事情),神经瘤就会改变自己,改变形状,同时改变我们是谁。

为什么要重新编码?

让我们讨论自由意志。这里我想把有意识的选择和强迫都包括进去。

本杰明·里贝特的传统实验表明,当被要求做出选择时,我们对选择的意识比大脑中的行动落后一秒钟。其中的含义,并非没有争议,是选择首先是潜意识的,而“我选择行动”的意识是后来的描述:选择是潜意识的。

我们可能都多少意识到我们没有意识到很多事情

好吧,如果你没有意识到这一点,你可能在别人身上也意识到了。因此,你可以推断出你自己缺乏意识。

那些试图影响我们的人已经知道,从人类有史以来,甚至可能更早,我们就有有限的心理防火墙。我们真的不需要科学。但是这些天来,科学正在帮助我们很好地分析偏见、启动、推动等等。

这对于那些对操纵感兴趣的人来说是有益且有利可图的,对于那些想要辩护的人来说也应该是同样的兴趣。

当心,因为除非你花时间掌握你的防御,否则其他人会为了他们自己的目的操纵你的思想形态。

你的神经系统中保留的模式,你的信仰、习惯和嗜好,都是物质的东西。它们被写在神经元和它们的连接中,作为真正的代码通道。这种对心理的物理本质的理解有助于我们理解为什么不学习无用的想法或习惯如此困难。

如果我是无意识的,这有什么意义?

我们都是无意识的,有意识的。我们都是,一直处于流动的交换中。

意识最大的美和便利就是从那个观察的位置来看我们自己,并进行批判性的评论。

对许多人来说,这种评论本身就带有负面情绪和习惯性。这可能是个问题。但这是一个可以通过认知行为疗法来解决的问题,例如,这种疗法明确寻求提高自我意识和解决习惯问题。

有意识的意识会阻碍我们无意识的选择并说不!

Is it a no?

不!是对冲动、信念、习惯和情感的强有力的逻辑阻挡。

通过变得更有自我意识;通过练习和探索我们自己的行为和信念的根源,通过理解记忆、情感和信念以及它们之间的相互联系,我们可以训练自己更有能力去注意一个选择,在注意中更好地理解它,在理解中更有能力说“不!”。

当“不!”完成了它的工作,意识可以进一步帮助,通过重新编码那些路径,通过清除我们在社会、他人、我们的环境的影响下允许刻在我们自己头脑中的代码。

为了知道我们受到了潜意识的影响,我们必须首先能够注意到选择并怀疑这种影响,然后停止自己,然后重新评估。考虑到我们可能会与自己的情绪冲动作斗争,我们可能会考虑建立一个赢得比赛的能力。

情感至上

你的神经瘤不断沐浴在来自环境的情感信号中。当我说情绪时,我指的是生化物质。这些是调节我们感觉的分子,包括酶和激素,它们构成了我们最古老的电路。

情绪进化成了让我们去关注其他事情的信号。

情绪不是感觉,这些是我们根据上下文赋予情绪的单独标签。例如,恐惧,或担忧,或内疚,或羞耻,都可能有类似的激素含量。这种情绪的描述和体验取决于我们是否受到攻击,或者担心如果我们被发现做了坏事,我们可能会受到攻击。

不幸的是,感觉是如此强大,以至于我们经常忘记它们是其他事情的信号,而是将我们的全部注意力转移到感觉本身上。

在重新编码之前,让我们先看看一些简单的情感描述。

以下是你可能已经感受到的一些事情的例子(感谢一本很棒的书,安吉拉·阿克曼和贝卡·帕格里西的《情感辞典:性格表达作家指南》):

  1. 自信——对自己的能力或品质的自信。
  2. 不确定性——不确定的状态。
  3. 好奇心——学习或寻求任何知识的欲望,求知欲。
  4. 冷漠——冷漠或不感兴趣的状态。
  5. 骄傲——一种适当的自尊和满足感,源于自己或他人的成就,或源于财产或关系的品质。
  6. 羞辱——一种感觉被贬低、羞辱或没有价值的状态。自尊心受挫。
  7. *和——一种没有焦虑的*静状态。
  8. 不知所措——被感情或环境所征服。
  9. 渴望——对即将到来的事情的热情。
  10. 蔑视——缺乏尊重或无视。
  11. 幸福——一种健康的状态;快乐的满足感。
  12. 怨恨——对某个行为、言语或人的愤怒,感觉受到了伤害或侮辱。

这些只是其中的几个。每个都有以下特点:

  1. 身体化学,我们“感觉到它们”。
  2. 信仰,我们相信它们,这是基于;
  3. 回忆,我们记得导致它们的事件,并且倾向于重复那些已经发生了很多次的故事。
  4. 一种延伸的身心反应,一种完整的神经状态。

这些感觉中的每一种都可能是一种强烈的体验,例如怨恨是什么样的?

Contempt

也许头脑中会充满对目标不友好的想法,对不公*或缺乏正义的挫折感,幻想另一个人会垮台,喜怒无常,想独处,专注于一个人或一种情况而损害其他关系,试图通过考虑把其他人带进来而创造一种愤怒的暴民心态。

也许身体会被神经瘤调整,以表现出双臂交叉的怨恨,与他人的物理距离,双手握成拳头,僵硬的姿势,颈部和肩部紧张,不同意地摇头,但什么也不说,走出房间,怒气冲冲,跺着脚上楼,用不必要的力量关门,指指点点和戳空气以示强调。

也许有一张紧闭的嘴,皱眉,抱怨,粗鲁,撅嘴,骂人,音量或强度上升的声音,争吵,低声咕哝或诅咒,扭曲的嘴,酸溜溜的表情,露出牙齿的卷曲嘴唇,轮廓分明的下巴,尖酸的语气,嘲笑别人,在别人背后说话,说闲话,不友善的微笑。

可能会有一个眯着眼睛的*板表情,看过去而不是看他们,一个艰难的表情。

它可能包括拒绝被善意或体贴收买,回避问题的根源,忽视和解的努力,贬低他人的地位或成就,出于受委屈的感觉而破坏他人的项目。

(感谢安吉拉·阿克曼和贝卡·普利西,链接:http://writershelpingwriters . net/the-emotion-thesaurus-a-writers-guide-to-character-expression)。

认出来了吗?

入围的 12 种感觉中的每一种都可以用同样的细节来描述,你会认出它们。然而,没有一点研究和讨论,我们让自己在这些国家的摆布。我们从一个流向另一个,受到我们自己的思想或环境接下来发生的任何刺激的冲击。

是时候收回一些控制权了。防止营销机构操纵我们账户的钱和屏幕上的数据。是时候插入一些防火墙和保护措施了。

回到思维编码

环境是我们神经代码的基础。因为我们总是在当下,环境描述了我们此时此刻所处的物理状态。

这就是为什么正念,它给我们一种方法,让我们更好地适应情感,进入情感背后的物质世界,它是如此有帮助,就像一扇门,通向一个被保护的,或更有选择的心灵。

你可以阅读重新编码你的神经瘤来了解它是如何工作的。下面是一些练习的方法。

1.休息一会儿

当然,你可以去度假,去一个远离通常的环境触发因素的地方。我们都知道这一招,它或多或少有用,取决于你在家庭中的角色。

家庭仍然可以成为感情的主要触发因素,至少你不在工作,新的地点和分散注意力的经历会及时诱导*静。

走开。为了让逃离变得有力量,在你离开之前注意你的状态(写在日记里)。等到你恢复了*静(再写一遍)。注意“远离它”的练习带来的不同。这是滑雪假期的正常冥想。

2.远离技术人员!

远离你的社交媒体。离开你的收件箱。

Walk or cake?

此刻,你可以通过掌控自己来练习“远离它”。如果你“感觉”太多,无法做到,那就离开屏幕 10 分钟或更长时间。把电话留下。不能?上瘾了?

剧烈运动或改变地点的结合会改变浸泡在你的神经细胞中的化学物质。通常这意味着你回来的时候更加敏锐和冷静。你需要以足够快的速度行走或奔跑,以分散注意力,或者有意识地沿着你的路线专注于小说。

有目的地做,每天做几次,每小时做一次。制定一个常规。记下你之前和之后的感受,并记录下不同之处。你将学习如何通过选择创造不同的精神状态。

3.健身拳击

每天一到两次,进行剧烈运动。你喜欢什么都可以,跑步,健走,拳击,骑自行车,旋转。注意任何健康警告,如果你增加血流量,呼吸频率,并从事一些强烈的身体活动,它会推动情绪化学物质并将其清除,同时增加我们从中自然获得的积极激素,并以氧合血的形式增加神经细胞的能量。

期待你的眼睛闪闪发光,你的妙语连珠,一两个笑话出现,让自己和你的处境不那么严肃;足够变得更好。为了让它变得有意识,在日记中写下你以前的样子,花时间注意你现在的样子。通过这种方式,你可以学习如何轻松地产生特定的精神状态。

警觉、放松和准备就绪是正常的状态。去更精确的?只是需要多长时间才能获得收益?如果你以不同的方式尝试事情,例如改变强度、时间、频率,有或没有同伴,会发生什么?在你自己身上实验,一点机器学习,直到你得到它。

4.打开你的意识

为了让你的注意力集中到现在,做几次深呼吸就可以让你意识到现在。

在呼气时,注意如果你的眼睛是静止的,并且你注意周边视觉,你能看到什么。

然后再加上你周边听觉能听到的。

除此之外,还要感受你身体的四周,它的位置,它的重量,任何不适,还有你的呼吸。

只是保持正常呼吸一会儿,尽可能多地用眼睛、耳朵、感觉去注意,保持静止但全神贯注。通常你会发现,只需一点点练习,这将*静内心的声音和感觉,并产生一种通常称为“集中”的状态。

5.像这样引导

如果你是一个领导者,如果你带头鼓励/允许良好的神经习惯,你会从你的团队中获得更多的闪光点和生产力。允许散步,允许技术休息时间,谈论情绪过载,练习自我学习,发展自我意识、掌控力和灵活性,并与团队分享你的经验作为一项关键的软技能。

科学表明,在办公桌前坐两组,每组 5 个小时,中间有短暂的午餐休息时间,这意味着比同样时间有规律的休息所做的事情要少得多。

6.指压

你应该试试指压按摩。我不确定指压按摩期间我的神经瘤会发生什么。这是一个奇怪而神秘的地方,从那里我慢慢地出现并改变了(以一种好的方式)。我只能推荐这段经历,让你们自己记下来。我还在研究这个状态是什么。

明白了吗?

我们经常做的许多事情,已经被社会所接受,比如购买食物,可以用心去做。这意味着选择关注行为的物理性。

通过关注你在活动之前和之后的状态,关注你在活动期间的身体状态——你的呼吸和运动,或者你的外部环境,或者两者兼而有之。

所有这些都很容易做到,每天都是如此,我们已经这样做了,部分是因为我们知道我们需要这样做,而且这样做很有效。在你的日常练习中加入有意识的注意,你会很快建立起一种自我意识,知道你如何改变状态,以及你能为自己做些什么来达到更好的状态。

认为精神状态是一个非常强大的工具。一个人工智能编码员会给他们的眼睛牙齿来生成。就像 SWOT 分析,或者思维导图。

想象一下,如果你掌握了成功所需的五种最强大的精神状态。有了这些工具,你能在生活中取得什么成就?

Somewhat happy robot

然后你甚至可以选择一件家务,知道以某种方式做,会让你心情非常好。

但也许让编码人员将这些状态写入他们的机器学习更容易。然后,你可以在你最新的人工智能中购买一个好的记忆(对你停车的地方),或者一种信心。当然,这不需要你的努力,只需要一些现金。

围绕我们的思维和行为习惯的自律总是有用的。它把一些人标记出来。在一个智能工具将我们的影响扩大到更广的世界里,这甚至更为重要。

像所有的工具一样,纵观历史,智能工具将彻底改变我们的生活。了解我们自己是我们能够保持控制的唯一有意义的方式,而不是奴役其他人,甚至最终奴役人工智能本身。

我很好奇会不会有人专门用 AI/ML 来反思人类的心理健康。如果你是我喜欢聊天的人,请保持联系。

尼克·梅休总经理 www.alembicstrategy.com

用 R 挖掘 Google 档案搜索数据

原文:https://towardsdatascience.com/mining-google-archive-search-data-with-r-51f4f76c2d21?source=collection_archive---------9-----------------------

从你的在线行为中学习

认领你的谷歌数据相对容易。以下是申请谷歌关于你的所有数据的步骤。免责声明——自 2018 年 8 月 7 日起,此处的所有链接和代码都可以使用,但是 Google 对其代码或 URL 的任何修改都可能导致它们停止工作。

1)登录您的 Google 帐户,然后点击隐私。您也可以使用下面的链接。

在这里,您可以找到与您帐户的安全和隐私设置相关的所有信息。如果这是你第一次查看谷歌的隐私设置,这可能会让人不知所措。这有点像所有安全/隐私相关事务的谷歌中心。

  • https://myaccount.google.com/privacy

[## 登录— Google 帐户

编辑描述

myaccount.google.com](https://myaccount.google.com/privacy)

2)找到下载您的数据档案的链接或访问下面的链接。

数据存档的链接可以在你的谷歌账户的隐私设置中找到。

  • 【https://takeout.google.com/settings/takeout

[## 登录— Google 帐户

编辑描述

takeout.google.com](https://takeout.google.com/settings/takeout)

现在,您应该会看到如何开始下载内容的说明。

3)从存档页面—选择所有 Google 产品,为您的数据创建完整的存档。

确保选择所有产品,以便您拥有完整的数据存档。下面的图片只展示了 4 种产品,在我写这篇文章的时候大约有 50 种不同的产品。

4)选择产品后,选择存档文件类型(。zip)。

您还必须选择存档大小。在这种情况下,让我们选择最大归档大小,以确保您的所有帐户数据都在其中。

5)默认的归档交付方式是通过电子邮件。现在,只要等到你收到谷歌发来的邮件,里面有下载数据的链接。

几分钟后(取决于谷歌掌握了你多少数据),会有一封带有下载数据链接的电子邮件。你也可以去管理档案并从那里下载数据。

请记住,在谷歌禁用该链接之前,您只有有限的时间来下载您的数据,并且您必须提出新的请求。

数据准备——提取谷歌搜索信息

解压缩归档文件后,名为📁外卖应该显示所有选定的谷歌产品的数据。接下来我们将挖掘 Google 搜索数据,因此我们需要找到相关的文件夹/文件。搜索数据以 html 文件的形式出现,位于搜索文件夹内的我的活动文件夹中。这个文件被命名为MyActivity.html。 记下文件的位置(路径),因为我们稍后会用到它。

  • 📁外卖 MyActivity.html➔我的活动➔搜索➔

分析工具包:需要 R 包

检查、安装和加载所需的 R 包

[## 哈德利/rvest

R 的简单网页抓取

github.com](https://github.com/hadley/rvest)

帮助您从网页上抓取信息。它旨在与 magrittr 合作,使表达常见的 web 抓取任务变得容易,其灵感来自于像 beautiful soup 这样的库。

[## juliasilge/tidytext

tidy Text——使用 dplyr、ggplot2 和其他 tidy 工具进行文本挖掘…

github.com](https://github.com/juliasilge/tidytext)

提供函数和支持数据集,允许文本与 tidy 格式相互转换,并在 tidy 工具和现有文本挖掘包之间无缝切换。

[## tidyverse/lubridate

lubridate——让在 R 中处理日期变得简单一点

github.com](https://github.com/tidyverse/lubridate)

Lubridate 使 R 用日期时间做的事情变得更容易,并使 R 做不到的事情成为可能。

[## ifellows/wordcloud

这是一个 R 包,可以创建漂亮的单词云,可视化文档之间的差异和相似之处,并且…

github.com](https://github.com/ifellows/wordcloud)

创建漂亮的文字云的功能,可视化文档之间的差异和相似性,并避免在散点图中过度绘制文本。

[## tidyverse/tidyverse

从 tidyverse 轻松安装和加载软件包

github.com](https://github.com/tidyverse/tidyverse)

tidyverse 是一组协调工作的包,因为它们共享公共的数据表示和 API 设计。

代码

数据准备:提取搜索数据

使用 rvest 包,我们可以读取包含相关搜索数据的 html 文档。通过利用正则表达式(regex),我们可以从 HTML 文档中提取相关信息。

从 Html 数据中提取时间戳

从 Html 数据中提取文本

从数据中提取搜索类型

现在让我们使用从 html 文件中提取的数据创建一个 DataFrame。

数据检查

数据分析:可视化谷歌搜索

谷歌搜索者每年的数量

每月谷歌搜索量

每小时谷歌搜索量

每个工作日的谷歌搜索量

每个工作日/小时的谷歌搜索量

我们可以按年份和星期几对搜索数据进行分组,以可视化整体趋势

来自谷歌搜索数据的词云

首先,我们需要提取文本并使用正则表达式对其进行清理

我们会想在常用的 stops_words (ei)中添加相关的单词。我,是,是)。在下面的代码中,我添加了与我的工作/学校相关的单词,因为这些单词很可能会出现得更频繁。现在我们还需要为单词云中出现的单词的最小频率和最大数量设置一个阈值。

最后,使用创建的包含单词计数的数据帧,我们生成一个单词云。

通过访问和了解谷歌等公司从我们的个人账户中维护的数据,我们可以更好地了解如何管理我们经常访问的所有网站的隐私设置,以及检测我们在使用这些服务时的行为模式。我们越能理解,就能越好地保护我们的隐私。

你可以在这里找到完整的脚本 谷歌笔记本。rmd

挖掘 HEP-Inspire 数据库

原文:https://towardsdatascience.com/mining-the-hep-inspire-database-77a68950ef59?source=collection_archive---------5-----------------------

世界上哪些国家对高能物理和数学的研究贡献最大?

Researchers with a Bachelor’s degree from the given country per million inhabitants (from HEP-Inspire database)

在我之前的职业生涯中,我曾在欧洲各地的物理系呆过很长时间。我发现令人震惊的是这些环境似乎享有巨大的文化多样性。大多数情况下,50%到 70%的员工和研究人员来自主办国,而其他职位则由来自世界各地的优秀人才担任。在移居者中,代表最多的国籍是人口众多的大国……加上意大利人。我经常碰到一个笑话,说世界上没有一个高能物理系里没有一个意大利人。有时候,我想,那个人就是我。

这件事引发了我的好奇心,我想量化每个国家向科学界提供研究人员的能力和趋势。显而易见,我应该从 HEP-Inspire 开始搜索,也就是说,这个*台承载了世界上每天产生的大部分高能物理学、宇宙学、天体物理学和数学物理学的文章。

HEP-Inspire 提供了一个大型数据库,其中有研究人员的姓名、统计数据和 bios,任何人都可以访问(我将引用一些用斜体表示的文件)。在该*台注册的 11.5 万名研究人员中,每个人都可以自由分享自己的教育背景信息,包括本科、博士、博士后和教师职位的情况。

我已经开始了我的分析,从 HepNames 数据集中解析每个研究者的标识符,以及他或她获得 UG 和 PHD 的位置。我必须面对的第一个问题是,数据库中的位置存储为大学名称(【a】字段)和标识符(【z】字段),而不是国家,例如:

<子场码= "">华沙 u .</子场码= "">UG
<子场码= " s ">1980
<子场码="t "****

为了绕过这个问题,我检查了第二个名为 Institutions 的数据集,其中包含所有机构的名称、地址和来源国。从这个文件中,我构建了一个字典,以国家名称作为键,以机构代码列表作为值。将机构代码与每个研究人员的“ z ”值进行匹配,我最终成功地获得了两本以国家为关键字、以该国家的 UG/PHD 头衔数为值的字典。这些字典和所有代码都可以在我的 GitHub repo 上找到。

事实证明,这些数据有时是不完整的、非结构化的或者包含错别字。然而,该算法能够识别数据库中 95%的机构和 98%的研究人员。

考虑到结果,我首先感兴趣的是研究每个国家在培养研究人员方面的潜力,这些研究人员在高度理论化、有时甚至是推测性的领域工作,例如高能物理。以欧洲为例,我的结果显示在本文顶部的地图中。按人口单位计算,为科学界提供本科生的能力最强的国家是希腊,每百万人中超过 130 人,其次是英国、瑞士,是的……意大利。与预期相比,表现不佳的国家是法国、荷兰和北欧国家。进一步的见解来自下一批:

Researchers with a Bachelor’s degree from the given country per million inhabitants

在数据集中,不到 12%的研究人员分享了他们的 UG 背景信息,28%的研究人员分享了他们的博士背景信息。不得不做出的主要假设是,所有国家的研究人员都有可能分享他们的教育背景信息,这可能有利于内部竞争激烈的国家。

我关心的第二个方面是了解一个国家从邻国进口/向邻国出口博士生的可能性有多大。为了评估这一点,我选择了欧洲 14 个国家的样本,并绘制了每个国家的 UG/PHD 头衔在样本中所占的百分比,对人口进行了标准化。

In the graph, France accounts for 7% of PHDs in the sample and for 3% of UGs (per million inhabitants)

该图显示了一个众所周知的趋势。瑞士、德国、英国、瑞典、法国和荷兰等高密度经济体倾向于从意大利、希腊、爱尔兰、匈牙利和葡萄牙的研究团队中招聘博士,这些国家高密度的物理学学士提高了候选人的质量和学术潜力。

在这篇文章的结尾,我想分享一下世界上的情况。下面的柱状图包含了一些有代表性的国家。如果你的国家没有出现在那里,你可以在这里看看整套。

失踪的移民发生了什么,他们是谁

原文:https://towardsdatascience.com/missing-migrants-24254bc82474?source=collection_archive---------6-----------------------

2013 年,至少有 368 人死于意大利海岸的两起沉船事故。这使人们更加意识到包括难民在内的移民的死亡,他们通过各种不同的、往往是危险的路线,从未到达目的地。

这篇文章关注的是死亡记录,另一部分是那些从未被发现的人,那些没有记录但可能还活着的人。

完整的连续互动版可以在这里找到。我用 Carto 和 odyssey.js 用 IOM 从 2014 年到 2017 年收集的数据来可视化移民(尤其是难民)。我发现 odyssey.js 作为一个带有地图缩放的讲故事工具很直观,但是,与工作文件相比,它的导出可能会在几帧中丢失一些数据点。

这是我关于数据科学和视觉故事的# 100 天项目的第 39 天。感谢阅读。欢迎新主题的建议和反馈。

密西西比州:2014 年牙科阿片类药物的中心

原文:https://towardsdatascience.com/mississippi-dental-opioid-epicenter-of-2014-ab4d7f68fa49?source=collection_archive---------5-----------------------

美国牙科协会呼吁其成员帮助对抗阿片类药物的流行。虽然牙医开出一小部分阿片类药物,但总体而言,在美国,他们是 10 岁至 19 岁患者的主要处方者。对于 127,338 名牙医中的每一名,医疗保险中心医疗补助服务(CMS)公共数据集包括他们的书面处方中阿片类药物的百分比。

2014 年,处方由 Medicare 部分承保的牙医的阿片类药物处方率中位数为 16.8% 。这些牙医在 2014 年共开出 1,110,725 张阿片类药物处方,占 Medicare 部分承保的所有阿片类药物处方的 1.4%

每个州都有牙医阿片类药物处方率的分布。这些是按照各州中值从最低(图表顶部)到最高(图表底部)的顺序绘制的。对于 20 个州,中位数是零或实际上是零,因为几乎所有的牙医都有极低的阿片类药物处方率,只有少数例外。

沿着图表往下看,在宾夕法尼亚州,离群值看起来开始占上风。从那里开始,接*图表的底部,异常值接管。密西西比州发生了什么,导致它不幸成为这场竞争的赢家,牙医阿片类药物处方率中位数为34.2%;多两倍那个,全国范围内?落后于其他州牙科监管机构,密西西比州牙科检查委员会最*通过了一项法规,要求该州的牙医在密西西比州处方监控计划(PMP)注册,医生长期以来一直被要求参与该计划。

mississpi刚刚提出了针对阿片类药物处方者的更新法规,该法规适用于医疗专业人员,不包括牙医。这些法规将要求医疗服务提供者在开阿片类药物处方之前,通过PMP 检查记录。从理论上讲,这一额外的步骤将使临床医生能够发现可能会购买多种止痛药处方的患者。

来自 2013 年的 CMS 数据显示,虽然外科医生和疼痛专家的比例较高,但家庭诊所和执业护士开出的阿片类药物处方总数最高。因为有如此多的初级保健医生,他们是阿片类药物处方的巨大来源。

States ordered bottom to top by OD death rate and medical specialties ranked left to right by opioid prescription rate.

2014 年的数据显示了类似的模式。除去外科、肿瘤和疼痛专家,以及阿片类药物处方率中位数为 0.0%的专家后,上面的热图显示了其他有趣的趋势。不仅牙医的阿片类药物处方率中值相对较高,而且各州的处方率也各不相同。作为对比,看看急诊医学专家(热图中最右边的一栏)。他们的*均比率高于牙医,但在他们的专业中,各州之间是相似的。

像急诊医学一样,一些初级保健专业(执业护士、全科医生、内科医生、家庭医生)在各州之间差异很小。其他专业(家庭医学、整骨操作医学、医师助理),如牙医,在各州的比率差异很大。这是农村还是城市供应商的问题?我将寻找与 CMS 数据结合的其他数据类型,这可能对此有所帮助。

用于数据操作和数据可视化的代码可以在 my GitHub 中找到。

感谢您的阅读。

我欢迎反馈——您可以“鼓掌”表示赞同,或者如果您有具体的回应或问题,请在此给我发消息。我也有兴趣听听你想在未来的帖子中涉及哪些主题。

阅读更多关于我的作品【jenny-listman.netlify.com】。欢迎随时通过 Twitter@ jblistmanLinkedIn联系我。

注意事项:

  1. 医疗保险 D 部分索赔数据来自:https://data . CMS . gov/Medicare-Claims/Medicare-Part-D-阿片类药物-处方医生-Summary-File-201/e4ka-3n CX/data
  2. 2014 年各州用药过量死亡率(每 100,000 名居民的年龄调整死亡率)数据来自:https://www.cdc.gov/drugoverdose/data/statedeaths.html
  3. 使用 R 中的工具处理和绘制数据
  4. 牙医不包括被列为口腔外科的专家(仅牙医),其阿片类药物处方率是牙医的两倍。与口腔外科牙科专家比例较高的州相比,在口腔外科牙科专家较少的州,被列为牙医的从业者可能会进行更多的外科手术,如拔除智齿。否则,这些牙医将会开出更多的鸦片制剂。然而,我的分析显示,州牙医阿片类药物处方率的中位数与州口腔外科牙科专家与牙医的比率之间没有相关性。

麻省理工 6。S094:自动驾驶汽车的深度学习 2018 讲座 1 笔记

原文:https://towardsdatascience.com/mit-6-s094-deep-learning-for-self-driving-cars-2018-lecture-1-notes-807be1a50893?source=collection_archive---------1-----------------------

你可以在 Twitter @bhutanisanyam1 上找到我,在 Linkedin 上联系我这里
T5 这里和这里是我学习自动驾驶汽车的两篇文章

如果你想阅读更多的教程/笔记,请查看这篇文章

你可以在这里找到降价文件

这些是麻省理工学院第六学期第一课的笔记。S094:自动驾驶汽车的深度学习课程(2018),由莱克斯·弗里德曼教授

第二讲的笔记可以在这里找到
第三讲的笔记可以在这里找到
第四讲的笔记可以在这里找到
第五讲的笔记可以在这里找到

所有图片均来自讲座幻灯片。

深度学习:由于研究和 GPU 能力的进步,*年来对人工智能技术很有效的一套技术。SDC 是可以利用这些的系统。

教官们正在研发能够理解车内外环境的汽车。

竞赛:

  • DeepTraffic:深度强化学习竞赛,代码在浏览器中运行。2.0 版现在允许多代理培训。

  • SegFuse:动态驾驶场景分割比赛。给定原始视频,视频中汽车的运动学(运动)。训练集给了我们地面真实标签、像素级标签、场景分割和光流。目标:在基于图像的分割中表现得比现有技术更好。需求:机器人需要解释、理解和跟踪场景的细节。

  • 深度碰撞:目标:使用深度 RL 避免高速碰撞避免。训练:1000 次跑步,训练一个汽车模型以 30 英里每小时以上的速度行驶,并由单目摄像机输入。

  • DeepTesla:使用大规模网络来训练端到端转向,使用单目视频作为训练的输入。

为什么是自动驾驶汽车?

目标:将数据驱动学习方法应用于自动驾驶汽车。

这是个人机器人的最大整合。

  • 范围广:道路上有大量的车辆。
  • 深刻:汽车和人之间的亲密关系。将你的生命托付给机器人,将控制权“转移”给汽车。该系统的生命临界性质是深刻的,将真正考验该系统的极限。

自主车辆:它是个人机器人,而不是感知控制。在某些情况下,这些系统需要人类通过控制转移来提供帮助。一个真正的感知系统具有与人类同等的动态本质,可能还需要几十年的时间。

认知负荷:一个完全连接的 CNN 接收原始 3D 输入,以分析认知负荷、身体姿势估计和驾驶员的睡意。

辩君:完全自主需要在某些领域达到人类的智能水*。

以人为中心的人工智能方法

建议:在每个算法的设计中考虑人的存在。

  • 感知控制可以处理 90%的情况。
  • 人为控制:在 10%的情况下占主导地位。

为什么要深度学习?

深度学习在处理大量数据时表现非常好。由于人类生活直接依赖于机器,因此需要从真实世界数据中学习的技术。

  • 感知/控制侧
  • 以人为本的协作和互动。

什么是深度学习?

人工智能:完成复杂目标的能力。

理解/推理:将复杂信息转化为简单有用信息的能力。

深度学习(表示学习或特征学习)能够获取没有任何意义的原始信息,并能够构建分层表示,以允许产生洞察力。

人工智能中最有能力的一个分支,能够从数据中推导出结构,从而获得洞察力。

表征学习

  • 代表性很重要。地球中心对太阳中心。

  • 笛卡尔坐标与极坐标区分圆和三角形

  • 使用一个 1 层隐藏神经网络来分离蓝色和红色曲线。使用深度学习来实现函数的学习(使用原始输入来生成输出)
  • 深度学习随着更多的数据而改进。
  • 对边缘案例的概括是深度学习的主要挑战。

神经网络。

灵感大致来自人类生物神经元。

  • 人类神经网络:1000 亿个神经元,1000 万亿个突触

  • 最先进的 ResNet-52: 6 千万个突触。
  • 差别是 7 个数量级的差别。
  • 差异:
  1. 人类神经没有堆叠,神经是堆叠的。
  2. 无订单与有订单
  3. 同步学习与异步学习
  4. 未知学习 Vs 反向投影
  5. 较慢的处理与较快的处理
  6. 功耗更低,效率更低

相似性:两者都是大规模的分布式计算。

一个基本的神经元是简单的,连接单元允许更复杂的用例。

神经元:

  1. 神经元由一组带权重的边的输入组成
  2. 权重成倍增加
  3. 增加了一个偏差
  4. 非线性函数确定神经网络是否被激活。

神经网络的组合:

  1. 前馈神经网络:成功的计算机视觉。
  2. 轮回 NN:反馈到自身,有记忆。在时间序列相关数据方面取得成功,与人类非常相似(因此更难训练)。

普遍性:多个神经网络可以学习仅用一个隐藏网络层来逼*任何函数*

*给出好的算法。

局限性:不在于网络的力量,而在于方法。

数字图书馆的类别

  1. 监督学习:需要人工标注数据。
  2. 增强监督学习:人类+机器方法。
  3. 半监督的
  4. 无监督学习:机器输入。
  5. 强化学习:机器输入。

当前正在使用:1,2

未来和更好的类别:3,4,5。

DL 影响空间:

  1. 定义和解决一个特殊的问题。例如:波士顿房价估计。
  2. 通用智能(或者差不多):强化和无监督学习。

监督学习

训练阶段:1。输入数据 2。标签 3。数据训练

测试阶段:1。新数据 2。输入到学习系统 3。出产量

学问

  • 正向传递:输入数据被送入神经网络,并生成预测。
  • 反向传播:测量与预期输出的偏差并计算误差,根据误差的大小调整用于预测值的参数(超参数)。

我们能做什么 DL?

  1. 一对一映射。
  2. 一对多
  3. 多对多。
  4. 异步多对多。

术语:

  • DL = NN(深度学习=神经网络)。
  • DL 是 ML(机器学习)的子集。
  • MLP:多层感知器。
  • DNN:深度神经网络。
  • RNN:循环神经网络。
  • LSTM:长期短期记忆。
  • CNN:卷积神经网络。
  • DBN:深度信仰网络。

神经网络操作:

  • 盘旋
  • 联营
  • 激活功能
  • 反向传播

激活功能

  1. 乙状结肠。缺点:渐变消失,不是零中心
  2. 坦。缺点:渐变消失。
  3. 雷鲁。缺点:不以零为中心

消失梯度:当神经网络的输出或梯度非常低,导致学习缓慢。

反向传播

神经网络的学习过程。目标:更新权重和偏差以减少损失函数。

子任务:

  1. 向前传递以计算网络输出和错误。
  2. 向后传递以计算梯度。
  3. 从权重中减去权重梯度的一部分。

因为这个过程是模块化的,所以它是可并行的。

学问

学习是一个优化的过程。

目标:通过更新权重和偏差来最小化损失函数。

使用的技术:小批量梯度下降和随机梯度下降。

学习挑战

  • 损失函数是高度非线性的。

  • 消失渐变。

  • Dying ReLU:对于 0 个输入,导数= 0。

  • 鞍点。

  • 过度拟合:神经网络学习训练数据,但未能很好地推广到现实世界的数据。检测者:低训练误差但高测试误差。

正规化:

有助于归纳的技巧。

  • 创建验证集:训练数据的子集
  • 早期停止:保存一个检查点并评估神经网络在测试数据上的表现。

Dropout:随机删除一些节点(以及传入和传出节点)

  • 用保持一个节点的概率(p)表示
  • 输入节点 p 应该高得多。

目标:帮助更好地概括。

正则化权重惩罚:

  • L2 惩罚:被惩罚的*方重量:
  1. 保持较小的权重,除非误差导数很高。
  2. 防止拟合采样误差。
  3. 更*滑的模型。
  4. 对于两个相似的输入,权重被分配。

  • L1 处罚:处罚绝对重量:
  1. 允许重量保持较大。

神经网络游乐场:玩技术和练习

深度学习突破

什么变了?

  1. 计算能力增强。
  2. 可用的大型有序数据集。
  3. GPU 利用中的算法与研究。
  4. 软件和基础设施。
  5. 财政支持。

DL 很难

人类比较:

  1. 人类视觉:发展了 5.4 亿年的数据。
  2. 两足运动:230,000,000 年的数据。
  3. 抽象思维:10 万年的数据。

神经网络:

  1. 给像素数据增加失真,导致不正确的预测。
  2. 视觉问题:照明度,姿势,遮挡,类内变异。

物体识别/分类:

目标:输入图像并预测输出

ImageNet:1400 多万个类别,21.8 万多个类别

竞赛:ILSVRC:

AlexNet (2012)在准确性方面有了显著的提升。

Resnet (2015):人类水*的表现被打败了。

微妙的例子:DL 离“人类概括能力”还很远

相同的架构,许多应用程序:我们可以改变预测层,根据需要对尽可能多的类进行预测。

  • 图像分类。
  • 图像字幕。
  • 对象定位。
  • 图像分割。

FCNN:

每个像素被分配一个类,它输入一个图像并产生另一个图像作为输出。

目标:图像到图像的映射。

使用案例:

  • 像素级全场景分割。

  • 色彩映射。

  • 物体检测。
  • 背景去除。
  • Pix2PixHD:从语义标签地图生成高分辨率的照片级逼真图像。
  • RNN:处理序列

使用案例:

  • 手写生成
  • 图像标题生成。
  • 视频描述生成。
  • 注意力转向建模。
  • 有选择地注意绘画。

重大突破

  • 乒乓对乒乓(2012):迈向 AGI 的一步。
  • AlphaGo (2016):从人类专家游戏中学到的
  • AlphaGo Zero (2017):击败 AlphaGo 和 Co,它在没有任何数据的情况下被训练!(它是通过与自己对抗练习而学会的)。
  • DeepStack (2017):首次击败职业扑克玩家(在单挑扑克中)

当前的缺点

  • 定义好的奖励函数是困难的。(Coast Runner 的例子),结果可能会令人惊讶。
  • 缺乏鲁棒性:向像素添加噪声会导致错误的预测。

当前的挑战:

  • 迁移学习:适用于密切相关的领域。挑战:跨领域迁移学习缺失。理性:对理性的理解或获得理解的能力
  • 需要大量的数据。
  • 需要带注释的数据。
  • 不完全自动化:超参数调整
  • 奖励:定义一个好的奖励函数是困难的。
  • 透明性:神经网络大多是黑盒(即使在我们将引擎盖下的过程可视化之后)。
  • 边缘案例:DL 不擅长处理边缘案例。(特别是涉及到自动驾驶的时候)。

回复:为什么是 DL?

将技术有效地应用于现实世界的问题是一个机会。(而 DL 在这些方面是最有效的)。

你可以在 Twitter @bhutanisanyam1 上找到我,在 Linkedin 上联系我这里
这里和这里是我学习自动驾驶汽车的两篇文章

订阅我的时事通讯,获取深度学习、计算机视觉文章的每周精选列表

减轻预测正义中的算法偏差:人工智能公*性的 4 个设计原则

原文:https://towardsdatascience.com/mitigating-algorithmic-bias-in-predictive-justice-ux-design-principles-for-ai-fairness-machine-learning-d2227ce28099?source=collection_archive---------7-----------------------

算法正被用于给罪犯定罪和决定监禁时间。我们需要确保它们是公*的。

当网飞得到一个电影推荐错误时,你可能会认为这没什么大不了的。同样,当你最喜欢的运动鞋没有被列入亚马逊的推荐商品清单,这可能不是世界末日。但是,当一种算法给你分配一个从 1 到 500 的威胁分数来决定你的监禁时间时,你可能会对预测分析的这种使用产生一些担忧。

人工智能(AI)现在几乎已经渗透到我们生活的方方面面。自然,机器预测不可能总是 100%准确。但是当人工智能在高风险环境中实施时,错误的成本会急剧增加。这可能包括推荐新的癌症治疗方法的药物,或者帮助法官评估嫌疑人再次犯罪可能性的刑事司法。事实上,*年来人工智能最有争议的用途之一是预测性警务。

对于普通观众来说,预测性警务方法最广为人知的可能是 2002 年由汤姆·克鲁斯主演的科幻电影《T2》中的《少数派报告》。这部电影根据菲利普·K·蒂克的短篇小说改编,展现了一个犯罪可以被预测和预防的未来景象。这听起来像是一个牵强的乌托邦场景。然而,预测正义今天已经存在。基于先进的机器学习系统,出现了一波为法院提供预测服务的新公司;例如,以风险评估算法的形式,评估罪犯再次犯罪的可能性,以帮助法官做出决策。

机器能识别未来的罪犯吗?

美国的刑期越来越多地基于有偏见的人工智能预测。例如,在 2013 年被捕后,Eric Loomis 被判处六年监禁,部分原因是基于一个不透明的算法预测,即他会犯下更多罪行。Eric Loomis 的案件中使用的专有软件背后的公司equivant(前身为 Northpointe)声称提供了被告的 360 度视角,以便为司法决策提供详细的算法协助。

这家公司是美国预测司法领域的众多参与者之一。电子隐私信息中心最*的一份报告发现,算法越来越多地在法庭上被用于“设定保释金,决定判决,甚至有助于判定有罪或无罪”。这种在法庭上向更多机器智能的转变,允许人工智能增强人类的判断,对整个司法系统来说可能是极其有益的。

然而, ProPublica 的一份调查报告发现,这些算法往往会强化执法数据中的种族偏见。算法评估倾向于错误地将黑人被告标记为未来的罪犯,其比率几乎是白人被告的两倍。此外,依赖这些风险评估的法官通常不明白分数是如何计算出来的。

这是有问题的,因为机器学习模型只与它们在上接受训练的数据一样可靠。如果基础数据存在任何形式的偏差,那么结构性不*等和不公*的偏差不仅会被复制,还会被放大。在这方面,AI 工程师必须特别警惕他们的盲点和隐含假设;重要的不仅仅是机器学习技术的选择,还有所有关于为人工智能模型寻找、组织和标记训练数据的小决定。

有偏见的数据反馈有偏见的算法

即使很小的不规则和偏差也会在最终的风险评估中产生可测量的差异。关键问题是,像种族偏见和结构性歧视这样的问题在我们周围的世界里根深蒂固。

例如,有证据表明,尽管吸毒率相似,但美国黑人因涉毒指控被捕的比例是白人的四倍。即使工程师忠实地收集这些数据,并用它训练机器学习模型,人工智能仍然会将嵌入偏差作为模型的一部分。

系统性的不*等模式无处不在。如果你看看 2014/2015 年票房最高的电影,你会发现无论是在屏幕时间还是说话时间方面,女性角色都远远不足。新的机器学习模型可以量化这些不*等,但是关于工程师如何主动减轻这些不*等,还有很多未决问题。

谷歌*期快,画! " 实验生动地展示了解决偏见问题的重要性。这个实验邀请了全世界的互联网用户参与一个有趣的绘画游戏。在每一轮游戏中,用户都被要求在 20 秒内画出一个物体。然后,人工智能系统会试图猜测他们的图画描绘了什么。来自 100 个国家的 2000 多万人参加了这个游戏,产生了超过 20 亿张各种各样的图画,包括猫、椅子、明信片、蝴蝶、天际线等等。

但是,当研究人员检查数据集中的鞋的图样时,他们意识到他们面对的是强烈的文化偏见。大量早期用户画出看起来像匡威运动鞋的鞋子。这使得模特选择了运动鞋的典型视觉属性作为“应该是什么样子的原型。因此,看起来不像运动鞋的鞋子,比如高跟鞋、芭蕾舞鞋或木屐,都不被认为是鞋子。

此外,最*的研究表明,如果不加检查,机器学习模型将学习过时的性别刻板印象,例如“医生是男性,“接待员是女性。以类似的方式,根据过去美国总统的图像训练的人工智能模型已经被证明能够预测出只有男性候选人可能赢得总统竞选。

早在 2016 年,我就为 TechCrunch 写过一篇文章,在文章中我解释了机器学习系统只能使用历史数据来对未来做出预测。这就是为什么在用过去(男性)总统的图像训练之后,根据过去美国总统的图像训练的神经网络预测唐纳德·特朗普将赢得即将到来的美国大选。因为数据集中没有女性总统,人工智能无法推断出性别不是该模型的相关特征。实际上,如果这个特定的人工智能要选举下一任总统,它会投票给特朗普。

这些推论产生了越来越确定的推荐系统,它倾向于强化现有的信念和实践,类似于我们社交媒体反馈中的回音壁。我们在日常生活中越依赖个性化算法,它们就越会塑造我们看到的东西、我们阅读的内容、我们与谁交谈以及我们的生活方式。通过坚持不懈地关注现状,对要读的书、要看的电影和要结识的人的新建议会给我们带来更多以前让我们高兴的东西。

当你的过去明确地决定了你的未来,通过自发性、开放的思想和实验的个人发展变得更加困难。这样,算法决定论的概念呼应了温斯顿·邱吉尔曾经对建筑说过的话:我们塑造我们的算法;此后,他们塑造了我们。

人工智能中的公*设计

2018 年 10 月,国际数据保护和隐私专员会议发布了人工智能道德和保护宣言,这是迈向一套人工智能国际治理原则的第一步。该宣言指出“人工智能中使用数据可能导致的非法偏见或歧视应当减少和减轻”。

这一概念的内在含义是,人工智能需要在一套更广泛的伦理和法律标准上进行评估;不仅仅是基于分类准确度和混淆矩阵。扩展这一论点,我提出以下用于预测正义的人工智能公*原则:

1.表现

为了防止不公*的偏见,所有受试者都应该有*等的机会在数据中得到体现。有时,这意味着未被充分代表的人群需要被仔细地添加到任何训练数据集中。有时这也意味着有偏见的机器学习模型需要在不同的数据源上进行大量的重新训练。在谷歌快,画的情况下!实验中,工程团队不得不有意寻找其他鞋类的额外训练示例,如高跟鞋和 crocs 鞋,以弥补代表性的差距。此外,最*的研究提供了新的算法技术到来衡量虚假陈述并帮助减轻机器学习中不必要的偏见。

2.保护

机器学习系统需要避免对个人的不公正影响,特别是与社会和身体脆弱性以及其他敏感属性相关的影响。这些因素可能包括种族、民族、性别、国籍、性取向、宗教和政治信仰。一个算法的整体公*性必须通过它如何影响受其影响的最弱势人群来判断。

然而,简单地从机器学习模型中省略敏感变量并不能解决问题,因为有各种各样的混杂因素可能与它们相关。关于刑事司法,研究显示,从犯罪历史数据中忽略种族仍然会导致种族差异的预测。相反,有早期证据表明,种族差异和其他敏感信息可以通过使用辅助机器学习算法从数据集中删除。希望在未来,这种方法可以帮助工程师建立一个“种族中立的”人工智能系统来预测累犯。

3.管理工作

算法公*不仅仅意味着没有不公*;它代表了在机器学习系统的设计中不断争取公*的积极责任。在这方面,管理精神只能由一个挑战彼此隐含假设的多元化团队来承担。

例如,在常规的无意识偏见消除练习中,团队可以培养对观点多样性的欣赏。包括 ProPublica 和 Privacy International 在内的几个非政府组织也开始倡导在构建大规模人工智能模型的公司中进行多元化管理。因此,只有通过创造包容的文化,公司才能为团队创造合适的条件来解决机器学习中的不公*偏见。

4.真实性

最后的原则不仅指训练数据的真实性,还指人工智能预测的真实性,因为它们被用来为人类决策提供信息。例如,尽管不断努力限制潜在的有害或滥用应用,但令人遗憾的是,机器学习在过去一直被用来通过深度伪造来扭曲现实。在这种情况下,对人工智能的普遍滥用可能会帮助恶意行为者生成虚假视频,其中人们说着他们以前从未说过的话,或者真实生活中从未发生过的场景的虚假图像。在极端情况下,这可能会导致一个世界,法官不再能够确定任何描述的媒体或证据是否符合真相。因此,这导致一些媒体专家得出结论,AI 最大的受害者不会是乔布斯,而是最终彻底消除对你所见所闻的信任。“幸运的是,人工智能研究人员已经在研究有效且可扩展的对策来检测各种形式的操纵媒体。

反对机器偏见的机器

这四个原则可以帮助开始一场关于人工智能公*的对话,特别是在用于预测正义时。公*永远不是机器学习的默认。因此,工程师需要采取主动措施来改变这种默认。如果我们不积极地设计人工智能的公*性,我们就有延续有害偏见和刻板印象的风险。

然而,人工智能最令人印象深刻的事情之一是,算法也可以有效地用于测量和减轻不公*的偏见。展望未来,机器学习工程师有望进一步开发这些技术;扩展它们以有意义地帮助人类决策者进行不带偏见的预测。

本文中表达的观点是我自己的观点,基于我之前在牛津大学的研究。它们不以任何方式代表谷歌的观点。

作者简介: 维亚切斯拉夫·波隆斯基 博士是 UX 谷歌研究员。此前,他是牛津大学的研究员,研究复杂的社会网络和集体行为。他拥有计算社会科学博士学位,之前曾就读于哈佛大学、牛津大学和伦敦政治经济学院。他积极参与了 世界经济论坛 专家网 WEF 全球塑造者 社团。2018 年,《福布斯》杂志将他的工作和研究登上了面向欧洲的 《福布斯 30 Under 30 榜单。他写的是社会学、网络科学和技术的交集。

本文的早期版本出现在 世界经济论坛议程 作为全球未来理事会 2018**WEF 年会的一部分。

Python 中的混合效果随机森林

原文:https://towardsdatascience.com/mixed-effects-random-forests-6ecbb85cb177?source=collection_archive---------0-----------------------

这篇博文介绍了一个开源 Python 包,用于实现混合效果随机森林(MERFs) 。编写这个包的动机来自于我们在 Manifold 建立的模型。我们遇到的大部分数据都是聚类的,例如来自个人的纵向数据、按人口统计学聚类的数据等。在许多情况下,我们发现与普通随机森林相比,使用 MERFs 提供了实质性的改进。

TL;速度三角形定位法(dead reckoning)

如果你的模型有不可忽略的随机效应,MERFs 是很好的,例如集群有很大的特质。您可以通过输入以下命令从 PyPi 安装我们的软件包:

pip install merf

源代码可在这里获得。投稿吧!该软件包基于 HEC 决策科学系的 Larocque 教授和 l'UQAM 营销系的 Ahlem 教授发表的优秀作品。

用例

大量的野外数据有一个聚集的结构。我们看到的最常见的例子是纵向聚类,在这种情况下,对于您希望建模的现象,每个个体都有多个测量值。例如,假设我们想将数学考试成绩建模为睡眠因素的函数,但我们对每个学生都有多个测量值。在这种情况下,特定的学生是一个集群。另一个常见的例子是分类变量导致的聚类。继续上面的例子,一个学生的特定数学老师是一个集群。聚类也可以是分层的。例如,在上面的示例中,有一个包含在教师集群中的学生集群,教师集群包含在学校集群中。在建立这个模型时,我们希望了解睡眠因素对数学考试成绩的普遍影响,但希望考虑学生、老师和学校的特质。

聚类数据有四种合理的建模策略:

  1. 为每个集群制作一个单独的模型。这种策略不令人满意,原因有两个:(a)通过聚类进行分片使得任何给定的模型都没有太多的训练数据,以及(b)该模型不能在整个群体中学习。
  2. 为所有集群创建一个全局模型。使用这种策略,模型可以学习整个群体,但不会学习特定集群的任何特质。例如,不考虑睡眠因素,一些学生可能有更高的数学能力。将这种影响明确地模型化,而不是将其归入睡眠因素,这将是一件好事。
  3. 制作一个全局模型,但是把集群 id 作为一个特征放进去。这是一个明智的策略,但随着集群规模的增长,会出现扩展问题。具体来说,在随机森林中,在分裂决策变得难以处理之前,单个分类变量只能有很小的基数。在 R 中,大约 n_categories = 30。在 H20 中,n_categories = 64。Python Scikit-learn 中的随机森林实现甚至不支持非二进制分类变量。一个热编码集群是一个选项,但正如这篇出色的博客文章中所解释的,这种方法的性能很差(我们将在下面展示)。长话短说,在模型中直接使用高基数分类变量作为特征很糟糕。
  4. 混合效应模型。这才是攻击集群数据的正确方法。在混合效应模型中,每个聚类获得一个随机效应,该随机效应是从先验中学习的,而先验本身是从数据中学习的。如下所述,这并不是一个新的想法,统计学家一直都在这么做。但是混合效果随机森林是新颖的——它们结合了线性混合效果模型的优点和非参数建模的能力,在这种情况下,您不需要理解问题的“物理学”。

混合效果建模的历史

线性混合效果(LME)建模是一个经典的技术。让我们更详细地看看这个,因为它激发了 MERF 模型。LME 模型假设一个生成模型,其形式为:

Linear Mixed Effect Model

在上面的等式中:

  • y 是目标变量。
  • x 是固定效果特征。假设 x 是 p 维的,例如有 p 个特征。
  • z 是随机效应特征。假设 z 是 q 维的,例如有 q 个特征。
  • e 是独立同分布(iid)噪声。它分布为 N(0,sigma_e)
  • a 是固定效应系数。它们对所有集群都是一样的。
  • I 是集群索引。我们假设在训练中有 k 个聚类。
  • bi 是随机效应系数。它们在每个聚类 I 中是不同的,但是被假设为来自相同的分布。在经典的 LME 问题中,这种分布被假设为 N(0,适马 _b),其中适马 _b 从数据中学习。

LME 是更一般的分层贝叶斯模型的一个特例。这些模型假设固定效应系数是未知的常数,但随机效应系数是从一些未知的分布中提取的。使用迭代算法一起学习随机效应系数和先验。然而,本文不是关于层次贝叶斯模型的。如果你想了解更多,这是一个很好的资源。

虽然分层贝叶斯建模是一个成熟的领域,但它们要求你指定回归的函数形式,即你需要知道问题的物理性质。不幸的是,在许多情况下,特别是在复杂的系统中,很难指定一个函数形式。这就是随机森林的闪光点。由于它分割了特征空间,可以作为一个通用的函数逼*器。我们在 Manifold 的工作引导我们寻求将随机森林与混合效果的力量结合起来。

混合效果随机森林

我们在蒙特利尔高等商学院决策科学系拉罗克教授团队的出色工作中找到了答案。在一系列论文中,他们阐述了一种将随机森林与线性随机效应相结合的方法。更重要的是,拉罗克教授非常慷慨地提供反馈,使 MERF Python 包成为现实。

与 LME 相似,MERF 模型假设了一个生成模型,其形式为:

Mixed Effects Random Forest Model

注意,除了线性固定效应 a*X 被一个一般的非线性函数 f(.).在本文中,这个非线性函数是使用随机森林学习的。更一般的,f(。)可以是任何非线性回归模型,如梯度推进树或深度神经网络。

一种期望最大化(EM)技术被用于拟合 MERF。有四个参数需要拟合:

  • f(。)
  • 所有已知集群的 bi。
  • 适马 _b
  • 西格玛 _e

我们不会在这里讨论数学——这篇论文做得更好——但 EM 算法背后的基本直觉是替代优化,例如,优化一个参数,同时保持其他参数不变。你不断重复这样做,直到收敛。具体来说,要适应 MERF,步骤如下:

  1. 固定所有 bi 并将 y计算为 y-bi * z。在所有样本中全局拟合一个随机森林,f(X)到 y
  2. 修正 f(),适马 _b,西格玛 _e .优化找到 bi*。假设线性随机效应和高斯先验,有一个封闭形式的解决方案。
  3. 修正 f(),bi。优化以找到适马 b 和西格玛 e。有一个封闭形式的解决方案,假设线性随机效应和高斯先验。

可以在每次迭代中计算的广义对数似然(GLL)是训练损失的度量。随着 GLL 的下降,合身程度提高。一旦它变*,我们通常可以停止迭代——拟合已经收敛。MERF 没有太多过度适应的危险——不会比经典的随机森林更容易过度适应。

一旦拟合出 MERF 就可以用来预测。对于 MERF 在训练中看到的“已知”聚类中的数据,预测包括随机效应校正:

MERF prediction for known clusters

对于 MERF 在训练中没有看到的“新”聚类中的数据,预测仅包括固定效应:

MERF prediction for new clusters

MERF 蟒蛇皮包

我们的贡献是用 Python 实现了一个 MERF 并将其开源。我们实现了尽可能多的遵守 scikit-learn 模型接口。下面我们用一个例子来说明。这个例子可以作为一个可运行的 Jupyter 笔记本在这里下载。

我们有三个矩阵,包含我们的 n_samples =500 个训练数据:

  • X.包含三个固定效果特征的矩阵。尺寸= 500 x 3。
  • y.包含单个目标变量的向量。尺寸= 500 x 1。
  • 集群。包含每个样本的 cluster_id 的向量。尺寸= 500 x1。我们在训练数据中有 k = 100 个唯一的聚类。

在这个例子中,没有明确的 Z 矩阵。我们创建一个来为每个集群建模一个随机*均值。它是一个维数为 500 x 1 的全 1 矩阵。

给定 X、y、集群和 Z 矩阵,我们可以通过实例化 MERF 模型并运行 fit 方法将 MERF 模型固定到该数据。MERF 模型目前有两个超参数:

  • n _ 估计量。为随机森林训练的树的数量。
  • max_iterations。EM 模型运行的最大迭代次数。

我们最终也计划为 EM 算法实现提前停止。这将增加一个额外的两个超级参数,即是否提前停止和应该有多大的耐心。

下面是 fit 的输出样子。请注意,拟合通常需要一些时间来运行——尤其是如果您运行多次迭代的话。这是不可避免的,因为每次 EM 迭代都需要随机森林拟合。即使对随机森林拟合进行并行化,单个 MERF 拟合也可能需要几分钟。

Training using MERF

一旦模型被训练,我们可以通过两个公共变量访问最终的随机森林和最终的已训练 b_is 矩阵:

mrf.trained_rf
mrf.trained_b

我们可以看看 b 的分布。它看起来像预期的方差为适马 _b 的*似高斯分布:

Final distribution of b_i’s

该模型还拥有 EM 迭代的历史。我们可以查看每一步的广义对数似然性(GLL ),适马 b、西格玛 e 和所有 bi 的估计值。

Convergence of MERF fitting

一旦拟合,该模型可用于预测给定 X、Z 和聚类的新样本。预测代码根据在训练中是否看到新样本的 cluster_id 来处理是否应用随机效应校正。

Predicting using MERF

合成数据性能

我们在合成数据上测试了 MERF 的性能。实验装置模仿了 MERF 发表的论文。我们从这个函数中生成数据:

Data Generating Model

在这个等式中:

  • m 是我们选择的固定常数。
  • bi 取自正态分布 N(0,sigma_b)。对于每个簇 I,它们是常数。sigma_b 是我们选择的固定常数。
  • 误差 e 是从正态分布 N(0,sigma_e)的 IID 得出的。sigma_e 是我们选择的固定常数。

在我们的实验中,我们为 m、sigma_e 和 sigma_b 选择不同的值,并从 100 个不同的不*衡集群中生成 500 个样本。我们在下表中总结了这些值,但是具体的值并不那么重要。重要的是两个派生的参数,总效应方差百分比(PTEV)和随机效应方差百分比(前一个)。本文对它们进行了详细定义,但直观上它们是:

  • PTEV =由于随机噪声导致的总方差的量是而不是。它越高,输出 y 越可预测。
  • PREV =由于随机效应产生的 PTEV 量。它越高,随机效应越大。

我们做了一个实验,将 MERF 与两个竞争对手进行比较:

  • 不考虑随机效应的随机森林,即仅在 x 上拟合随机森林。
  • 包括一个热编码簇 id 作为特征的随机森林,即我们创建 k 个新的热编码特征 X_ohe,并将其与 X 连接,并在组合的[X,X_ohe]特征矩阵上训练随机森林。

我们在实验中改变了 PTEV 和 PREV,并在两个不同的测试集上评估了性能:

  • 测试集由模型训练的已知分类组成
  • 测试集由模型在训练时不知道的新(未知)聚类组成

我们使用 10 次运行的*均均方误差(MSE)作为误差度量。我们将 MERF 增益定义为相对于比较算法的百分比增益:

下面的表格和图表总结了结果。MERF在两个对比车型上都有显著的性能提升——特别是当 PREV 很高(超过 50%!)。此外,在预测新的聚类时,性能损失可以忽略不计。当数据中存在显著的随机效应时,MERF 是一个严格更好的模型。它是一个胜利者。

我们已经将数据生成器作为实用模块包含在 merf 包中。实验的源代码在 Jupyter 笔记本里。检查一下,并运行您自己的实验!

Experimental Results

Gain of MERF over RF and RF-OHE

真实数据上的性能

Manifold 正在为我们的一个客户解决一个热模型问题。问题是根据许多因素,例如前一天的室外温度、室外湿度、室内温度,每天预测建筑物何时将达到其目标温度。我们有按建筑纵向分组的历史数据。集群高度不*衡。对于一些建筑,我们有多年的数据;对其他人来说,我们只有几周时间。这个问题需要一个混合效应模型。我们希望建立一个模型,它可以在整个人群中学习,但同时也要考虑到每栋建筑的特质。

与上面的实验类似,我们将 MERF 与以下对象进行了比较:

  • 不考虑随机效果的随机森林,即仅在固定效果特征上拟合随机森林。
  • 包括一个热编码建筑物 id 作为特征的随机森林,即我们创建 k 个新的热编码特征 X_ohe,并将其与固定效果特征连接,并在组合的[X,X_ohe]特征矩阵上训练随机森林。

由于异常值,我们将误差度量改为中值绝对误差(MAE ),而不是 MSE。我们在一个小的 N~1000 数据集上使用 5 重交叉验证来比较性能。实验结果总结如下。

MERF Gain doing 5-fold cross validation

对于这个数据集,有一个小的 MERF 增益,但它不是那么显著。通过观察 MERF 收敛图,我们得到了一些线索。

MERF Thermal Model Convergence

GLL 是*坦的,即使我们运行 100 次迭代,其他变量也在收敛。不清楚这是什么意思。此外,估计的误差方差 sigma_e 非常显著。数据似乎有一个非常低的 PTEV(因为离群值?).一个热编码(OHE)模型做得很好,因为建筑物的数量很少——k = 15。随着建筑数量的增加,OHE 模型的性能将会受到更大的影响。

所有这些因素,加上没有那么多数据的事实,让这个实验有点不确定。MERF 的表现并不比它的对手差——所以这并没有什么坏处——事实上*均来说还略有增加。这个实验需要更多的分析——当我们完成分析时,我们会在这个博客上公布它们。

结论

混合效应模型是强大的——而且许多数据都有适合使用它们的结构。将它们添加到您的模型清单中。混合效应随机森林(MERFs)是拼图的一部分。他们结合了最佳的随机森林和最佳的混合效果模型。我们希望它们对您有用。更重要的是,我们正在寻求帮助来扩展 MERF 套餐!我们会喜欢更多的贡献者。我们有一堆未解决的问题要处理:

  • 添加提前停止。
  • 添加更多学习器,例如梯度提升树、xgboost 等。
  • 使用 GMERFs 向分类添加概化。参见论文此处。
  • 对使用非线性混合效果而不是纯线性效果进行新的研究。

向我们发送拉取请求!

关于流形

Manifold 是一个 AI 工作室,在硅谷和波士顿都有办公室。当风险很高时,领先的公司会与我们合作开发新的人工智能解决方案。我们加快上市时间,创造新的知识产权,并培养内部能力。Manifold 的团队在构思和部署生产机器学习系统和数据*台方面经验丰富,这些*台位于谷歌、脸书、高通、麻省理工学院和成功的风险投资支持的初创公司。我们的专业领域涵盖电子(消费和工业)、无线、医疗保健和营销。我们有一个广泛的专家网络,我们利用了工业和工程子专业。

想研究这样的东西吗?向 sdey@manifold.com 伸出援手!我们正在招聘数据科学家。

专家与协方差的混合

原文:https://towardsdatascience.com/mixture-of-experts-with-covariance-6d4a167743ad?source=collection_archive---------4-----------------------

在这里,我将继续探索前沿的神经网络设计,以及如何使用协方差来改善训练时间、泛化和对新环境的适应。(我介绍了负协方差的概念,提供了更多的 细节,以及注意的背景和可交代性问题,在前面。)

很复杂:

神经网络结构正变得越来越复杂。现在,多个网络以协调的方式被使用,并且单个网络有时被分割成一个“专家”(MoE)的混合体。专家的混合使用一个非常大的神经网络中的条件路径——当信号通过网络传播时,一个条件层学习激活哪些专家,这样专家的各种组合在不同的情况下是活跃的。当这些专家中的一些决定其他专家的参与时,一个专家层级就形成了。因为只需要几个专家来处理每个输入,这些巨大的网络能够快速有效地处理输入,尽管它们的规模令人难以置信。

DARPA 希望制造能够边走边学的机器,这是对当前神经网络的一个重大转变,目前的神经网络首先被训练,然后被用作静态实体。要达到他们的目标,需要网络架构保留基本的识别能力,并根据新事件添加或更改解释。专家的组合可能是他们所需要的。但是,这些专家如何在旅途中学习呢?

发展新的联系,增加专家:

DARPA 的“终生学习者”将需要改变他们的联系,而不忘记或弄乱他们在过去学到的东西。就像我们的大脑一样,它们需要连贯地建立新的联系。不幸的是,传统的反向传播无法判断何时应该创建新的导线。(特别重要的是,因为训练可以产生与任何事物都没有联系的细胞!“死 ReLU”是一个常见问题。)

一个为终身学习而设计的 MoE 网络必须让现有的专家保持不变,同时让新的专家加入进来。基于协方差的强化允许网络做到这一点。

在使用来自输出层上的损失函数的反向传播来训练的网络中,没有指示新连接应该在处增长的。然而,表现出负协方差的神经元可以被直接识别(正如我在之前的帖子中解释的那样),具有负协方差的神经元是错误检测器。当一个受过训练的 MoE 必须学习新的东西时,它可以在这些错误检测器的下游插入一个神经元集群,并将该集群训练成一个新的专家。我会更详细地解释这一点…

使用负协方差训练新专家:

当您在具有负协方差的神经元的下游插入一个神经元簇时,它们最初具有随机权重。让我们称这些星团为“noobs”。noob 可能离输出层非常远。这对于反向传播来说是一个问题,因为沿着整个网络的训练无法将训练集中在新的集群上。此外,额外的培训会导致现有专家的变化,导致网络过度适应!****

相反,您可以冻结网络的所有参数,除了 noob 权重的,并从 noob 簇中继续呈现负协方差的任何神经元传播梯度。(负协方差作为一个局部损失函数!)通过将错误分类期间的激活与网络成功期间的激活进行比较来测量负协方差。这样,现有的专业知识都不会丢失,整个网络不会变得过拟合,并且训练集中在观察到的错误上。只有新手才会学习,他们只会从错误中学习。

维持一个连贯的现实:

随着负协方差训练连续的 noobs,网络增长以容纳新的信息。noob 成为应对这些错误的专家。而且,因为负协方差是在整个网络中定义的损失函数,这些网络可以无限增长(就像乌贼大脑……)。以这种方式发展起来的庞大网络需要一个坚实的基础。

那个基础,无论你的网络是执行翻译,字幕,NLP,操作机器人,设计组件,提供超分辨率,还是完成部分图像,都是 注定 是 3D+时间

我们将需要一个机械土耳其人的军队:来标记 3D 物体和发生在现实的时间场景中的事件。他们还可以标记对象和事件的质量,以及关系陈述。这些标签对应于名词、动词、形容词和介词。学习这些场景片段的神经网络可以从许多角度、许多位置看到猫和自行车,它们被其他物体部分遮挡,并经历各种动作。这个 3D+T 模型就是相干网络**

连贯性是基础:

翻译句子时,考虑连贯网络的重要性。为了理解一个句子,解释器网络必须消化整个句子,它的上下文来自周围的句子,将这个解释传递给连贯网络。如果连贯网络能够成功地将句子实例化为现实模型,它就声明解释者的选择是“连贯的”。这可以防止解释者犯语法上正确,但物理上无意义的错误。****

我们来看一个例子:“狗睡在天花板上。”语法没有错误发生,但是机器需要识别:由于重力,一只狗不能睡在天花板上。一致性网络将无法实例化该语句,并将它标记为“不一致”**

与此同时,Coherence Network 对“猫跳到了天花板上”这一说法没有异议。物理实例化可能显示一只猫在沙发上,一路跳到天花板上。(在 youtube 上看到的;这是有可能发生的。)此外,Coherence Network 会对“狗睡在屋顶上”这种说法感到满意,因为重力允许这样做。(史努比!)

与一致性网络的对话:

继续解释器-示例:当解释器向连贯网络发送可能的语句时,任何不连贯的翻译都可以被抑制,并寻求二次解释,直到找到连贯的实例。如果没有找到一致的解释,网络可以用“我不确定”来回应陈述不确定性是人机交互的关键,并允许通过与人类用户的对话来学习。

此外,人类可以窥视连贯的网络,看看解释者在想什么。这解决了可解释性的关键问题,并允许人类用户容易地识别错误。否则,没有人知道网络是否做出了合理的判断。

大图:

未来的神经网络很可能是巨大的,有许多专家层的混合物。每一项新任务或特殊情况都将是这些庞大网络中的一个“耳垂”,从一个由菜鸟变成专家的层级中成长起来。企业解决方案和个性化应用程序都可以从同一个大规模网络中发展起来,而不会增加计算成本(因为稀疏 moe 只处理其众多路径中的几条),以及而不需要大规模的再培训(因为你冻结了网络的参数,并且只对错误分类的输入进行培训)。**

最重要的是,如果你的大规模网络正在与 3D+T Coherence 网络(也被训练为 MoE with noobs)进行对话,你可以放心,它正在基于真实世界的实例找到答案,而不是随机的像素相关性。你可以看到网络在想什么,并且很容易纠正它的错误。我希望这有所帮助,国防高级研究计划局!

ML 和 AI 合作拯救灾难受害者:援助组织如何利用它的力量

原文:https://towardsdatascience.com/ml-and-ai-partner-to-save-disaster-victims-how-aid-organizations-can-tap-into-its-power-b8de67e92a09?source=collection_archive---------10-----------------------

2014 年 9 月 5 日,季风暴雨在几分钟内吞噬了印度、中国和巴基斯坦控制的克什米尔村庄,掩埋了 80%的领土。惊慌失措的市民逃到屋顶,许多人将在没有食物和水的情况下等待救援长达一周。#KashmirFlood 标签成为许多人的生命线,因为受害者在推特上发布他们的位置、需求和失踪的亲人,希望得到救助。

其他人就没那么幸运了。对他们来说,几乎两周过去了,互联网连接才恢复。

一旦恢复,人们通过社交媒体向亲人报告他们的状态。

一些人通过推特和脸书寻求失踪人员的信息,希望他们的努力能被分享,亲人能被找到或获救。

在世界的另一端,2014 年 8 月 14 日,在加利福尼亚州的纳帕县,当 6.0 级地震袭击该地区时,受害者拨打了数千个 911 电话。尽管如此,由于电力和通讯线路受损,求救电话无法发出,整个地区都无法获得帮助。问题是:人们的服务是基于先到先得的原则。能够使用必要的电力和通信线路拨打 911 的受害者首先得到服务,剩下那些生存资源较少的人自己照顾自己。

AI 和 ML Power 拯救生命的自然灾害管理
与此同时,斯坦福大学工程系学生 Ahmad Wani,分享他的经验:

在研究生院的一次休息期间,我去克什米尔看望我的父母,当时一场大洪水席卷了这个邦。80%的克什米尔在几分钟内就沦陷了。大多数人在没有食物和水的情况下,在屋顶上呆了长达七天……大部分救援都是随机的,应急重点也是临时的。

但这还不是全部。在他位于第三世界的家园遭受破坏后,他回到了他位于第一世界的母校,发现了具有讽刺意味的类似场景:在受灾严重的海湾地区(尽管是第一世界),FCFS 的灾难管理方法意味着援助工作也是随机进行的,没有优先考虑那些最危险或最需要的人。

在此之前、期间和之后,曼梯·里和艾把灾难受害者变成幸存者
认识到对更好的灾难管理系统的普遍需要,瓦尼的“关注一个问题”的愿景诞生了。作为一种机器学习(ML)和人工智能(AI)驱动的自然响应解决方案,One Concern 为响应者提供了工具和见解,以便在灾难事件之前、期间和之后采取拯救生命和有效的步骤进行全面恢复。几乎实时的甚至是预测性的损害和受灾地区报告有助于急救人员了解哪些需要优先处理,以及在哪里首先分配救生资源、信息和人员。

依赖人工智能和人工智能与灾难受害者同行,这并不是唯一的担忧。其他科技公司,如 IBM Watson 和 WorkFusion,以及政府组织正在依靠 ML 和 AI 解决方案,在灾害管理的每个阶段将受害者转化为幸存者。

ML 和 AI 提供预防性见解,为预防措施铺*道路
甚至在自然灾害来袭之前,ML 和 AI 解决方案,如 One Concern 的电力预测模拟模型,从而培训和准备特定区域的响应团队,以减轻灾害的端到端影响。

例如,美国疾病控制中心(CDC)报告说,全球每年有 5 万人死于流感和流感相关并发症,这种现象尤其影响第三世界国家。为了减少死亡人数并告知市民预防措施,中国深圳 CDC 汇总了有关空气质量、地理布局、经济状况、人口密度和人口流动性的实时数据。然后,他们通过 ML an AI 自动生成洞察,预测哪些地区风险最大,并以基于位置的资源为目标,以准备和控制灾难影响。

人工智能和人工智能在灾难发生时阻止灾难蔓延
在灾难发生时,人工智能和人工智能相结合,可以帮助响应者:

-跟踪和预测灾害轨迹;
-确定基于位置的紧急需求和受影响最大的地区;
-获得对哪些资源需要首先分配以及在哪里分配的预测洞察力;
-收集和揭示用户生成的关于需求、影响、死亡人数和失踪人员的社交媒体报告的趋势;
-向受影响最大或处于危险中的地区发送救生援助;
-向潜在受害者发送有针对性的危险警告;
-发送基于位置的及时安全信息;和
-定位受害者以协调他们的救援。

回到我们的纳帕县地震现场,由 IBM Watson 最*与公共安全通信官员协会的合作伙伴关系提供支持,应急人员本可以取消 FCFS 政策,代之以最紧急、最先响应的政策,从而拯救生命。

通过这种合作,IBM Watson 使用 ML 来分析最紧急的呼叫是如何展开的,然后将这种洞察力传递给调度员和调度培训员。最终结果是:调度员可以识别最紧急的呼叫,区分它们的优先级,并了解呼叫者的位置和可能的需求。反过来,他们可以提供及时的安全信息、资源和响应人员来拯救更多的生命。

人工智能和人工智能加速恢复以减轻创伤
人工智能和人工智能技术品牌还与保险和筹款公司合作,以加速恢复,从而缩短痛苦和创伤的后果。

例如,保险公司 Metlife Japan 致力于为路透社 14 次最致命地震之一和美国过去十年 10 次最致命海啸之一的社区提供服务。为了更好地服务高危人群,大都会人寿与 WorkFusion 合作。

WorkFusion 带来了 AI 和 ML 支持的产品,以实现无人数据库挖掘、索赔政策的自动验证、索赔与政策的事实匹配、自动化决策以及向下游支付的记录系统(SOR)的数据转换。这意味着保险索赔处理时间减少了 80%。翻译:减少受害者的痛苦时间。

位于野火和地震多发的硅谷的 RevUp 使用 ML 和人工智能支持的 WorkFusion 产品,以创纪录的速度和速度将可能的捐赠者与非营利组织进行匹配。然后,他们的组合解决方案激发捐赠者通过社交媒体共享创建相似的捐赠者,从而产生自动化、有针对性和可盈利的效率的连锁反应。最后,他们自动跟踪捐赠,以确保财务目标,从而满足受害者的需求。

人工智能和人工智能帮助人类更好地帮助人类
在灾害管理的每个阶段,人工智能和人工智能解决方案都为灾害响应者提供必要的实时洞察和自动化决策,以更高效、规模更大、影响最大、最先服务的方法取代 FCFS 救灾管理。

作为一个救灾组织,你可能无法跟随像中国深圳疾控中心这样的大型政府实体的脚步,来增强内部的 ML 和 AI 能力。但是像 RevUp 和 Metlife Japan 这样的品牌提供了一条前进的道路:伙伴关系。WorkFusion、IBM Watson 和无数新兴的人工智能和人工智能公司渴望在灾难管理之旅的每个阶段帮助您更有效地拯救和重建生命。

你的作业:简单地联系他们。共同开发商业案例,在人工智能和人工智能的支持下,可以减少自然灾害的死亡人数和创伤影响。

[ML]正式框架—准备工作

原文:https://towardsdatascience.com/ml-formal-framework-preliminaries-e3bb1a61a956?source=collection_archive---------6-----------------------

可以找到相当数量的机器学习论文,它们假设要理解良好的预备知识。另一方面,似乎没有那么多的出版物提供了清晰的初步介绍。

分类器

  • 根据某些参数化将输入元素映射到输出元素的函数

Parametrizable Classifier

输入空间、输出空间和参数空间

Domain

Codomain

Parameters Space, where the Training is performed

典型地,在分类任务中,域的维度比共域的维度高得多,然后共域成为高度语义的空间

数据集

  • 通过对未知分布执行 IID 采样获得的输入-输出对的集合(全球相关)

Training Set of N Elements

Latent World Related Distribution sampling which the Dataset is built

损失函数

使用基础真值为分类结果提供分数的函数,其中零是最高分数(即完美分类)

It compares the Classification Result with the Expected Result from the GT and assigns a score where 0 is perfect classification and it can be upper bounded to some L or go to +\infty

如果这在任何地方都是可微分的(典型地,分类器是可微分的),那么可以使用基于梯度的方法来微调分类器参数,以便最小化训练集(可以是数据集的子集)上的损失

学习机

学习机是以数据驱动的方式执行给定模型的参数拟合(其选择是元参数)的算法,即依赖于训练集、要最小化的损失函数和训练/优化策略

Learning Machine performs the Parameters Fitting of the given parametric model according to the Dataset and the Loss Function

ML 简介 3:物流和定制输出单元

原文:https://towardsdatascience.com/ml-intro-3-logistic-output-units-ec42cc576634?source=collection_archive---------10-----------------------

本帖跟随机器学习入门 2 。我们将把机器学习应用于房屋销售评估。我们将把注意力转向房屋销售建模,让我们探索自定义目标。在机器学习中,我们将探索我们可以通过同一数据集的不同表示来定义的不同目标。这是数据科学家在处理每一个新的机器学习问题时必须做出的共同决定,在这篇文章中,我们探索了一些选项。

此内容旨在介绍关于深度学习的第二次讲座,实现我们在许多情况下都需要的基于非回归的 ML 讨论。

学习目标

这篇文章给出了线性、逻辑和自定义回归目标的真实例子。

听完这堂课后,你应该能熟练使用现成的回归模型以及设计你自己的定制回归目标。

问题设置

假设我们在预测房子需要多长时间才能卖出去。目前,为了激励模型,让我们假设房屋销售市场可以快速卖出一栋房子,以响应低价公告。

在这个模拟的环境中,如果一栋房子的标价非常高,比它的价值低得多,房子几乎会立刻卖出。如果一栋房子以公*价格挂牌出售,它可能会在几周或几个月内卖出,这取决于交易的好坏。如果房子定价过高,房子可能需要几年时间或者永远卖不出去。

数据

在这个问题中,我们输入了关于房屋列表的数据:

  • 房子的*方英尺
  • 位于大城市?(是或否)
  • 离最*城市的距离(英里)
  • 卧室数量
  • 浴室数量
  • 翻新后的年数
  • 索价

这些特征中的每一个看起来都非常简单,我们可以使用我们在之前的会议中学到的知识,从我们的输入中运行回归,以预测房子将出售的时间。

机器学习选项

在这里,我们将讨论不同的机器学习目标,我们可以选择使用来解决这个问题。

经典回归

线性回归学习每个输入要素的乘数。为了进行预测,它将输入乘以乘数,然后将结果相加。我们也可以使用学习特征的线性回归,例如神经网络。

引入逻辑转换

在上一节中,我们讨论了基于元素的非线性转换。它们的工作方式是将单个值作为输入来创建单个输出。一个非常流行的变换是 sigmoid 变换,或逻辑变换。

逻辑单元将从负无穷大到正无穷大的数字映射为输入,将 0–1 映射为输出,如左图所示。

如果我们想要预测 0 和 1 之间的真实概率,或者特别是如果我们想要预测二元(2 级)定性响应变量,这是有价值的。

逻辑回归动机

如果我们只关心预测房子在第一个月会不会卖出去呢?这样,我们的模型应该预测一个介于 0 或 1 之间的数字,0 代表房子没有卖出,1 代表房子在第一周卖出。

我们可以要求我们的预测被解释为置信度或概率。如果它对自己的产出更有信心,那么它的预测应该更接*极限。这样,我们可以将模型的输出解释为房子卖(1)或不卖(0)的概率或信心。

那么如果我们在一个房子里喂食,模型线性输出 3 呢?好吧,看看上面的 sigmoid 曲线,x = 3,曲线的 y 值是 0.95,所以模型有 95%的信心这套房子会在第一周卖出。

所以这就是逻辑回归!它的概念是采用线性回归模型(神经网络或简单的线性回归)并在末尾附加一个逻辑单元。或者像另一个人所说的那样:“逻辑回归不是直接模拟这个响应 Y,而是模拟 Y 属于特定类别的概率”(链接)。

最后一个细节:优化

我骗了你。输出函数并不是逻辑回归不同于线性回归的唯一细节。关于如何实际训练模型,还有第二个区别。

还记得之前的线性回归吗,我们训练模型使其预测的*方误差最小化。但是如果我们对逻辑回归做同样的事情呢?

假设房子挂牌价格低,卖得快,那么它的价值就是一个‘1’。但是让我们假设模型预测。1,估计房子不会在时间框架内出售。那就是 1 - .1 = .9 的线性误差。所以*方误差是 0.81。让我们把它作为参考。

后来,让我们说,模型估计。0001 相同的房子,表明它几乎肯定房子不会出售。在这种情况下,误差仍约为 1,因此误差的*方也是 1。这与. 81 没有太大的不同,即使这个模型现在因为对错误结果的不可思议的信心而可怕地偏离了!

因此,随着模型对错误答案的预测越来越有把握,我们希望对模型进行更多的惩罚。如果正确的值是 1,如果我们的预测接* 0,我们希望我们的损失接*无穷大,反之亦然。这就是逻辑损失的动机,它是预测的对数。当输入接* 0 时,对数接*无穷大,因此我们使用
(Y==1) * log(预测)+(Y = = 0)* log(1-预测)
以便当我们接*关于错误答案的置信度时,我们的损失接*无穷大。

(这个公式也是从最大似然估计中数学推导出来的。有兴趣就去看看吧)

通过我们的 sigmoid 输出函数和对数损失,我们已经详细说明了线性回归和逻辑回归之间的所有差异。

逻辑回归的优点/缺点

逻辑回归的动机是做出是/否的预测。如果我们想在搬进去,而我们所关心的只是是否达到当月销售日期会怎么样?逻辑回归会告诉我们需要知道的一切!

人们经常选择逻辑回归的另一个原因是更容易看到好的结果。例如,所有多年来从未卖出的房子,模型估计它们在第一个月都卖不出去。而且所有在第一天卖出的房子,模型估计他们确实在第一个月卖出!它能准确地估计一切!

这就像接受一个人的图像,并预测这个人的名字。最初,你的准确性很差,所以你改为预测他们的性别,并获得了很高的准确性。

但是我们在那里做了什么?我们并没有更好地解决这些复杂的问题,我们只是建立了一个忽略了其环境的一些细节的模型,通过忽略一些重要的任务就可以得到很高的准确率分数。

线性回归的优点/缺点

对于这个问题,线性回归比逻辑回归更有优势,它可以估计房子出售的日期,而不仅仅是估计是否符合截止日期。它区分了两天和一周,一个月和一年和三年。

另一方面,线性回归解决了具体估计房子何时出售的问题,但它对于这种环境也有重大问题。线性回归的一个问题是,它对 1 天与 11 天之间的差异的影响就像 100 天与 110 天之间的差异一样大。这似乎不合理,因为第一个估计值相差 10 倍,而第二个估计值只相差 10%。对于这个问题,这些应该有不同的损失值。

多类分类

如果我们想预测购房者是年轻的专业人士、中年夫妇还是其他人呢?

现在有三个类需要我们选择,而不是两个,所以我们不能执行逻辑回归!我们如何在一个三选项空间中做决策?我们可以点他们 1,2,3 吗?但是 2 需要在 1 和 3 之间,这在我们的场景中没有意义!

概念检查:多类分类的约束

如果这是课堂设置,请与你的邻座交谈。
你会对模型施加什么约束,使其可以解释为在三个或更多选项之间做出决定?
我们的渐变应该是什么样子,才能帮助我们训练学习分类?它们什么时候最大,什么时候最小?

解决方案:使用交叉熵训练 Softmax 输出层

从统计角度来看,模型需要为每个输出类分配投票的概率质量,每个投票都是非负的,并且概率总和为 1。

我们需要一个损失函数,如果它将一个非常低的概率分配给正确的分类标签,它将严重地惩罚模型(具有大的梯度)。

对于 3 类分类问题,我们使用 3 个输出单元,我们通过 softmax 层。softmax 层通过指数函数映射所有单元,然后除以三个输出的总和,使它们为非负,总和为 1。

例如,对于模型输出 H1,H2,H3,softmax 层计算
o1,o2,o3 = e^(H1,H2,H3)

o '都是正的,但是我们需要它们加到一起,所以我们计算
S1,s2,s3 = [o1,o2,o3]/ (o1 + o2 + o3)将每个单独的值除以三个值的和。

然后,我们用交叉熵损失函数来训练网络,如果我们对一个例子进行了严重的错误分类,该函数会以接* 0 的对数来增加我们的损失。

看看我们如何通过使用 yi(值为 1 的真实 Y 标签)来计算相应的损失-log(yhat_i)来计算上述损失。这样,如果我们的模型预测真实标签的概率 yi 非常小,那么 Loss = log(yi)将非常大。

最后,我们预测具有最大值的输出单元,例如,如果 s2 大于 s1 和 s3,我们将预测 Yhat = S2 的内容,这可能意味着“一对中年夫妇可能会购买这栋房子”

自定义回归

有时我们将线性回归扩展到逻辑回归。但是,通常有更好的定制解决方案。当我们设计一个回归解时,我们需要考虑输出函数和损失函数。

选择输出函数

对于这个房屋销售示例,我们的房子永远不会在负天数内售出,所以让我们选择一个永远不会为负的函数。Softplus 函数怎么样,如果线性回归输出为负,它接* 0,对于正值,它只跟踪回归值。

选择损失函数

也许我们可以用来表示损失的最有意义的方法是估计的百分比误差。这样 1 周 vs 2 周和 1 个月 vs 2 个月的损失是一样的。

总结我们的自定义回归

将上述定制放在一起,我们可以通过使用带有 Softplus 输出函数和估计百分比误差损失函数的回归来预测房子需要多长时间才能卖出。

利用这些新的预测,我们可以确信方向是准确的。具体来说,它们应该在短时间内精确到粒度,在长时间内精确到方向,但不精确到天。

超越传统回归的定制

让我们后退一步,看看我们一直在讨论的内容。我们已经尝试灵活处理我们很聪明的事实,我们可以在我们的回归输出中定制一个损失函数,但是这仍然把我们自己限制在一个回归输出中。

如果你被要求估计,个人而言,房子需要多长时间才能卖出去?有时候你会看着一套房子说“这是一套非常标准的房子,价格合理,肯定会在一周到一个月内卖出去”。其他时候,你可能会看着一栋房子说“这是一栋非常不寻常的房子。我不太确定,它可能会在一周内售出,也可能需要几年才能售出。”

有时你对一个狭隘的预测很有信心,有时则不然。因此,如果我们真的想要一个有意义的可解释模型,让它估计其预测的可信度,就像人类会做的那样

置信估计的实现

我们刚才说什么了?我们刚刚完全改变了这里的游戏。现在,模型不是预测一个输出,而是用一个数字来表示它的估计值,现在模型预测两个数字,预测值和置信水*。

这听起来应该很疯狂!但是不要大惊小怪,我们理解它,所以我们可以实施它。

比方说,对于一栋房子,模型估计销售前的时间为 T 并且置信度为 C 。对于置信度,我们只表示预测的标准差。我们的信心是我们允许我们的误差有多大。

我们在估算房子销量的时候,尽量估算准确,尽量用一个小的置信区间来表达自信的答案。但是我们也不想表现出自信和不自信。

所以我们的失落代表了上述欲望。我们有一个损失函数,它是我们的置信区间的*方,表示“我们想要更自信”。我们有另一个损失函数,这是我们的误差,取决于我们的信心,它说“我们不能比我们的信心更不正确”。

所以损耗= ((Y-T)/C) + C

我们的产量预测和置信度都必须大于 0,所以:

t,C = Softplus(回归(特征))

用置信估计结束回归

所以我们完了!我们接受输入并计算两个回归输出,一个用于预测,一个用于置信区间。我们知道这些必须是正数,所以我们首先通过 Softplus 函数传递我们的回归输出,如上图所示。

我们用一个损失函数来训练它,这个损失函数表示“我们想要信心,但是我们也不想过度表示我们的信心”。

最后,我们通过读取一个输出作为模型的预测来解释输出,另一个预测给我们关于模型的置信度的见解。例如,如果模型输出(21,7),我们将解释房子在大约 3 周内出售,加上或减去一周。

回归解决方案的总结比较

所以我们提出了一个评估房屋销售的问题。

我们可以进行标准回归,这有利于估计我们的输出,标准,如果我们使用纯线性回归,我们可以单独解释参数,如前几篇文章所述。

运行时,我们的模型会生成以下图表:

我们可以做逻辑回归,让我们设定一个模型截止阈值,并解释我们是否会在截止日期前卖掉房子。

我们可以通过定制回归损失函数来强制我们的模型在方向上精确。

我们还可以进一步定制我们的问题,以解决预测销售时间的问题,以及定制估计我们自己的信心,让我们学会尽可能准确地预测房屋销售,并在我们无法建立自信的销售估计时进行有意义的表示。

太棒了。我们做到了。我们学习了逻辑回归,这是一个非常流行的工具,认识到它是一个超越逻辑回归的定制,并学习了如何定制我们自己的回归问题。

展望未来

即使到了最后,我们实际上仍然在轻微地限制自己。我们学会了预测一个分布,但只是一个高斯分布。如果我们想预测任意的多模态、非高斯分布会怎样?在未来的一节课中,我们将讨论能量建模,这将使我们学会预测任意分布。

这个问题展开: ML 前言 2 。

本系列的预期跟进:https://towardsdatascience . com/ml-intro-4-performance-measuring-and-regulatory-c 1973d 96 C5 b 9

对这一条完全理解的人打算跟进的帖子:https://medium . com/@ leetandata/machine-learning-engineering-1-custom-loss-function-for-house-sales-estimation-95 eec6b 12457

对于苦于代码或理解的人可选后续: 本帖代码详细分析:https://medium . com/@ leetandata/machine-learning-python-programming-introduction-for-business-people-10588 e 13 ce 9d

关于 Python 编程的免费综合课程。确保注册,但选择免费的可选项目。所有课堂内容免费提供:
https://www . coursera . org/learn/python-programming-introduction/

一个比这个更复杂的机器学习教程,但比下面的(不是我写的)更容易https://www . ka ggle . com/rochelle Silva/simple-tutorial-for-初学者

软件工程师可选后续岗位: 重数学、重 CS 的详解(上):https://medium . com/@ leetandata/neural-network-introduction-for-Software-Engineers-1611d 382 C6 aa

重数学、重 CS 的详解(下):https://medium . com/@ leetandata/neural-network-for-software-engineers-2-mini-batch-training-and-validation-46ee 0a 1269 a 0

Cho 教授可选数学笔记:
https://github . com/NYU-dl/Intro _ to _ ML _ Lecture _ Note/raw/master/Lecture _ Note . pdf

ML 简介 4:正规化,验证和营销归因

原文:https://towardsdatascience.com/ml-intro-4-performance-measuring-and-regularization-c1973d96c5b9?source=collection_archive---------7-----------------------

Fitting curves to data

本帖跟随机器学习入门 3 。我们将把机器学习应用于模拟数据集,并探索如何测量机器学习的性能。然后我们将探讨正则化的数学概念。最后,我们将探讨如何在营销中使用规范化来提供有意义的见解。

本次会议的代码将张贴在这里。

学习目标

这篇文章给出了一个真实世界的例子,如何使用机器学习获得关于营销影响的见解

听完这个讲座后,你应该明白

  • 我们为什么以及如何判断机器学习系统
  • 多项式回归
  • 如何使用正则化
  • 你如何从读取一个规则化的机器学习系统的输出做出营销决策

(这过于简化,但仍不是我们百事公司的做法,原因有很多,因为我们可以在很多方面做得更好。我们将在未来的会议中讨论其中的一些,其中一些将需要在没有博客帖子的情况下亲自教授。然而,这应该让你对如何解释机器学习来做决策有所体会)

前言问题

我们要讨论的第一个问题是预测一家商店一周会卖出多少香蕉,前提是他们在那一周从当地农民那里购买了多少香蕉。

假设我们只有以下关于历史销售额的数据点:

你可能会认为有上升趋势,如果你买得太多或太少,货架看起来杂乱或稀疏,可能会有额外的复杂性,但也许这只是一个总体的上升趋势。理想情况下,机器应该具有相同的思想。

让我们把预测销售看作一个回归问题。线性回归可以解决这个问题:

卖的香蕉= _ *买的香蕉+_

我们的模型学习了卖出的香蕉= 0.85 *买的香蕉- 10.5,上面可视化了。

这似乎是合理的,它学到了一个积极的关系。但也许它遗漏了一些复杂的东西。

而不是学香蕉卖了= _ *香蕉买了+_:

假设 y 是卖出的香蕉,x 是买入的香蕉。接下来让我们想象一个更复杂的函数,y = _ * x + _ * x + _。这将能够学习更复杂的互动。但是为什么就此打住呢?下面,我们学习

y = _ * x+_ * x+_ * x+_ *x⁴+_ *x⁵+_ *x⁶+_ *x⁷+_ *x⁸+_

模型得知 y = x -178667.84+x * 35887.57+x -3375.53+x⁴ 173.71+x⁵-5.29+x⁶* 0.1+x⁷-0.0+x⁸ 0.0+16.0

哇哦。这些都是巨大的乘数。它完全符合我们的数据点,但对于任何超出这个范围的东西来说似乎都是不现实的。也许模型被赋予了很好地学习数据的能力,并且在预测超出正常范围的不寻常的高值或低值的未来数据点上不会很好地工作。

引入正规化

正则化是一个偏好简单模型的概念。在我们的多项式回归的情况下,正则化意味着我们惩罚大的乘数。有了正则化,我们将有更小的乘数,拟合数据点不那么完美,但有一个更*滑的曲线。

过度正则化

让我们将正则化添加到我们的模型中,乘数为 1。我们可以从 1 开始,并根据需要进行调整。

模型学习到的 y = x * 0.1638+x * 0.0038+x * 0.0001+x⁴* 0.0+x⁵-0.0+x⁶-0.0+x⁷-0.0+x⁸-0.0+16.0

肯定是小得多的乘数,但看看曲线,也许我们应用了太多的正则化,现在预测看起来太*了

欠正则化

现在,我们将正则化乘数从 1 改为 1e-20,以降低正则化程度。

模型学习到 y = x -9944.37+x * 2122.76+x -210.91+x⁴ 11.4+x⁵-0.36+x⁶* 0.01+x⁷-0.0+x⁸ 0.0+16.0

我们可以直观地看出,这个模型看起来需要更多的正则化,因为它的曲线似乎比我们希望的波动更大。

正规的

在 1.0 和 1e-20 之间,我们选择 1e-5 的正则化,这产生了下图。

这个看起来最符合数据的模型学习了

y = x -1.5684+x -0.0823+x * 0.0055+x⁴ 0.0001+x⁵-0.0+x⁶-0.0+x⁷-0.0+x⁸* 0.0+16.0

我们还可以将这条新曲线与之前的其他正则化曲线进行比较,如下所示:

量化这些决策:验证

在上一节中,我们做了大量的曲线分析,以决定哪种模型最适合我们的数据。真实数据集比这更复杂,我们更喜欢自动做出这个决定的方式。

我们使用的算法称为训练和验证,工作原理如下:

假设我们有很多不同的模型,我们认为这些模型可能很好地符合数据。我们首先将数据分为训练集和验证集。我们的每个数据点都被随机映射到这些集合中的一个。

然后,我们选取每个模型,训练它们以适应训练集。一旦它学习了它的参数,我们就计算它在它的验证集上会收到的误差。误差最小的模型似乎对数据建模最好,不是基于它训练的特定数据点,而是基于看不见的数据点。

如果我们看上面,轻正则化模型似乎预测疯狂的值,所以它可能会在看不见的点上有很高的误差。强正则化也会由于忽略一些重要趋势而在看不见的点上具有高误差。因此,我们会选择具有中等正则化的模型,而不看这些曲线。

营销测量的规范化

既然我们已经有了数学概念,让我们谈谈学习有意义的营销见解!

模拟环境

对于这个例子,让我们假设我们想要了解我们的哪些营销行为是最有意义的。在这个模拟环境中,我们有多年的数据,可以了解我们在不同品牌的营销预算上花了多少钱,以及每个品牌的日销售额。

本例中我们的营销预算是“交易支出(Trade)”、“搜索支出(Search)”和“展示支出(Display)”。

我们的两个核心数据表如下所示:

一个表告诉我们什么时候进行促销,我们花了多少钱,另一个表告诉我们每个品牌每天的销售额。

营销归因目标

我们想要模拟的是我们营销活动的增量提升。如果我们能够理解我们的每一个营销活动是如何影响销售额的,我们就可以采取投资(促销支出)回报(增量)最高的营销活动。另一个目标可能是提出新的广告方法,但这超出了本练习的范围。

但问题是,我们不能直接测量增量升力。这是因为对于任何一天,如果我们没有进行促销,我们都不知道会有多少销售额。

营销归因方法

我们能做的是,如果我们没有进行促销活动,就估计销售额,然后用促销活动来估计销售额。我们通过将销售额构建为不含促销的基线预测加上促销增量的函数来实现这一点。

在现实世界的场景中,我们会更智能地模拟基线销售,但在这个场景中,让我们将每个品牌的销售模拟为一个常数,每个促销类型根据花费的金额增加一个增量。

预计销售额=基线(品牌)+提升(营销行动)

可能的次优方法:常数建模

我们可以模拟这些数据的一种方法是忽略不同品牌的投资回报率的差异。我们可以直接将全球销售额建模为每个不同营销领域的全球支出的函数。然而,这样一来,我们就失去了很多关于单个品牌的销售额是否与其特定的支出可变性密切相关的信息。我们看到,我们的全局模型受环境中其他噪声的影响要大得多,并且学习到的全局参数不如品牌或产品级别模型的全局聚集参数准确,这将在下面讨论。

促销-品牌互动

我们可能会想到的一个细节是,不同类型的促销可能对一些品牌有更大的影响,而对另一些品牌影响较小。因此,每个品牌都应该能够从每种营销类型中学习到自己的效果。

然而,如果我们为每个品牌、每个促销类型学习一个单独的乘数,在没有正规化的情况下,我们正在学习很多参数。还记得上面的回归模型吗,我们给香蕉数据集拟合了 8 个参数。如果不进行正则化,该模型很容易过度拟合并预测极值。我们的模型也能够过度拟合我们的数据集,类似于本文前半部分讨论的香蕉示例(我们肯定会在真实世界的数据中看到这种情况)。因此,我们可以假设某些类型的促销对大多数品牌应该有一致的影响,但是一些品牌可以偏离这些全球趋势。

我们通过建模来实现这一点:

提升(营销活动)=(全球投资回报率+品牌偏离)*营销支出

我们允许模型学习每种营销支出的全球投资回报率,但我们应用正则化来迫使我们的品牌水*变化接*于 0,这样大多数品牌采用全球投资回报率作为他们在该营销桶中的投资回报率。

模拟数据分析

如上所述运行线性回归,我们的模型学习以下系数:

现在我们正在进行营销归因测量!我们了解到每个品牌都有一个基准销售价值,并衡量了我们营销活动的投资回报。最上面一行的汇总表示表示每增加一美元的支出,您将获得多少美元的销售增量的总体影响。下面的行表示与这些全局参数的特定偏差,但大多数时候它们应该接*全局 ROI。

为了解释上述内容,我们可以看到显示通常具有最高的投资回报率,其次是搜索和交易。软糖的展示似乎非常低效,投资回报率只有 0.6%。搜索 Sparkle Pop,或显示 Sparkle Pop 或 Sugar Buns,都具有极高的 ROI。

为了生成这些数据,我们进行了回归分析。让我们讨论一下这个回归问题的数据点是什么样子的。举个例子,我们用“Gummies”这个品牌,当时我们在交易上花了 100 美元,在搜索上花了 200 美元,在展示上花了 300 美元。这一天的销售额是 1200 美元。

预计销售额=巨美基线销售额+ 100 *贸易投资回报率+ 100 *巨美贸易投资回报率+ 200 *搜索投资回报率+ 200 *巨美搜索投资回报率+ 300 *展示投资回报率+ 300 *巨美展示投资回报率。

我们尽量让预估销售额接*真实销售额,1200。

我们的目标是学习

  • 全球贸易投资回报率,搜索投资回报率,并显示投资回报率
  • 橡皮糖特定的巨美基线销售、巨美交易投资回报率、巨美搜索投资回报率和巨美展示投资回报率

我们会允许全球参数和基线销售容易波动,但我们应该大力规范巨美的具体投资回报率,这样我们就不会了解不切实际的变化。

如果我们在此设置中过度调整我们的参数,我们会看到所有品牌共享相同的全局 ROI,如果我们在此设置中过度调整我们的参数,我们会看到品牌具有疯狂的 ROI,如+10 甚至负值。

最后,当我们实际训练这些模型时,我们将按如下所述进行训练和验证:

  • 首先,我们分离出 30%的数据作为验证数据。
  • 我们使用剩下的 70%的数据来训练许多模型。
  • 对于我们训练的每个模型,我们在验证数据上验证其准确性。为此,我们计算我们的预测和真实销售之间的*均误差。
  • 我们挑选具有最高验证准确性的模型作为最佳模型。它有特定的正规化乘数。
  • 使用来自我们最佳性能模型的参数,我们在完整数据集上训练最终模型。这些是我们用来为营销决策提供信息的参数。

我们(为将来的会谈)遗漏了什么

在这次会议中,我们遗漏了许多细节。

基线

我们没有讨论在学习 ROI 参数的同时构建智能基线估计。

这一点非常重要,因为我们可以把销售的季节性增长归因于我们在旺季花费更多的习惯。

我们需要学会表示每年和每周的季节性趋势,以及节假日和特定的年度事件,如感恩节、夏季、返校季和亚马逊优惠日。

产品级建模

如果可能的话,我们可以通过对产品级别的销售和支出进行建模来了解更多的价值。通过将产品级 ROI 建模为品牌级 ROI 的变体,我们可以了解产品级的洞察力,更重要的是,通过对粒度细节建模,我们可以了解更准确的品牌级洞察力。

这将是一个更细粒度的细分,类似于我们如何将全球趋势划分为品牌趋势,但现在将每个品牌划分为产品成分。

智能报告

我们可以智能地报告产品和品牌,可能如下:

首先,我们确定影响最大的品牌/支出组合,这些组合具有最高或最低的投资回报率,同时也有大量的支出。

然后,在我们想要增加或减少的品牌/广告类型中,我们可以确定最重要的产品来做出改变。

其他广告类型/渠道

我们展示了 3 个广告渠道的建模。当然,这些模型中的每一个都被模型不知道的其他广告渠道所混淆。通过添加更多的广告信息,该模型将得到改进,并且该模型还可以学习(在以后的帖子中进一步讨论)如何提出新的广告渠道。

时间相关性

我们可能有过去 5 年的数据。我们希望使用所有这些数据,但更关注最*的相关数据。

概述

在本次会议中,我们讨论了三个主题:

正规化

我们讨论了正则化来惩罚具有大值参数的复杂函数。这有助于我们学习简单的模型。

确认

我们讨论了培训与验证。验证有助于我们选择听哪个模型。

使用正则化进行营销归因

我们讨论了使用正则化来学习营销活动的 ROI 参数。

解读营销归因

我们在这节课中学到的主要东西是我们简单营销归因的数学方法背后的动机。通过理解动机,我们还学习了如何解释机器学习的输出以进行营销归因。

这个问题展开: 机器学习入门 3 。

对于完全理解这一条的有意跟进帖子:https://medium . com/@ leetandata/machine-learning-engineering-1-custom-loss-function-for-house-sales-estimating-95 eec6b 12457

对于苦于代码或理解的人可选后续: 本帖代码详细分析:https://medium . com/@ leetandata/machine-learning-python-programming-introduction-for-business-people-10588 e 13 ce 9d

关于 Python 编程的免费综合课程。确保注册,但选择免费的可选项目。所有课堂内容免费提供:
https://www . coursera . org/learn/python-programming-introduction/

一个比这个更复杂的机器学习教程,但比下面这个(不是我写的)简单:https://www . ka ggle . com/rochelle Silva/simple-tutorial-for-初学者

软件工程师可选后续岗位: 重数学、重 CS 的详解(上):https://medium . com/@ leetandata/neural-network-introduction-for-Software-Engineers-1611d 382 C6 aa

重数学、重 CS 的详解(下):https://medium . com/@ leetandata/neural-network-for-software-engineers-2-mini-batch-training-and-validation-46ee 0a 1269 a 0

Cho 教授可选数学笔记:
https://github . com/NYU-dl/Intro _ to _ ML _ Lecture _ Note/raw/master/Lecture _ Note . pdf

ML Intro 5:一个热编码、循环表示和规范化

原文:https://towardsdatascience.com/ml-intro-5-one-hot-encoding-cyclic-representations-normalization-6f6e2f4ec001?source=collection_archive---------10-----------------------

本帖跟随机器学习入门 4 。在之前的帖子中,我们描述了用于营销归因的机器学习。在本帖中,我们将阐明我们在该部分中忽略的一些细节。我们将检查一个关于营销属性的数据集,对我们的品牌进行一次性编码,操纵我们的一次性编码来学习定制的业务洞察力,标准化我们的功能,检查我们的模型输入,并详细解释我们的输出。

本次会议的代码将被张贴在这里,但是是杂乱无章的,因为这个职位不是以编码为重点

学习目标

这篇文章给出了一个真实世界的例子,说明如何表示数据来推动特定的见解,以及如何消除噪声来提高业务见解的准确性。

听完这个讲座后,你应该明白

  • 分类变量热编码之一
  • 时间变量的循环编码
  • 自定义可解释性的特征表示的自由(理解这种自由可以说是帮助商业用户与机器学习工程师合作的最重要的技能)
  • 数学稳定性的数据标准化
  • 如何解释特定操作的一些模型输出,以及检查您是否信任该模型的其他输出。

问题是

在本帖中,我们将再次查看各种模拟品牌的营销支出和销售数据集。我们的目标是优化我们公司的销售。在此之前,我们需要讨论要问什么问题,以及如何对我们的信息建模

数据

我们有每个品牌的销售和支出数据。

我们的核心数据表如下所示:

Data about spend and sales over time

这些数据总结了我们的历史销售和营销活动。

品牌建模

在这篇文章中,我们直接进入细节。参见机器学习介绍 4 获得更慢的解释。

让我们塑造品牌。在这个介绍系列中,品牌是我们的第一个非数字特征,所以我们不应该真正知道如何对它建模。我们怎么告诉模特第一排是品牌 Caffeinos,第二排是品牌糖包子?

介绍一种热门编码

为了对分类变量建模,我们使用一键编码。由于我们有 8 个品牌,我们创建了 8 个“虚拟”变量,它们被设置为 0 或 1。每个虚拟列被分配 8 个类别中的一个,并为该类别的行赋予值“1”,否则为“0”。

这可以通过转换来可视化:

Initial Representation

变成以下内容:

One-hot representation

这种类型的分类变量二进制表示法称为 one-hot,因为每一行都有一个值为 1 的要素,而其他要素的值为 0。当我说这是一种分类变量二进制表示时,它是分类的,因为我们正在编码的变量是分类的,并且每个特征都是二进制的,这意味着它们采用两个值中的一个,0 或 1。在其他上下文中,我们有其他方法来表示分类变量,比如向量表示,但是这种一键表示对我们的应用程序很有用。

包装品牌建模

现在我们有了一个热门的表现,我们可以学习对特定品牌的偏见。如果我们使用这些功能以及营销支出来预测销售,该模型可以学习每个品牌的线性回归系数(one hot 矩阵的列)。该系数将乘以品牌指标来预测销售额。因此,这些系数将了解每个品牌的偏差(由于特定品牌,您的销售预测应该高出多少)。

时间编码

问题是

让我们假设销售随着季节而变化,基线销售在返校季节最高。如果我们不对此进行建模,模型会认为我们在返校季开展的任何促销活动都是超级有效的,而其他季节则是无效的。

我们可以通过给模型一年中的某一天来告诉模型现在是一年中的什么时候。但是从这个角度来看,12 月 31 日和 1 月 1 日是对立的,尽管我们认为它们非常相似。我们希望附*的日期有相似的表示,即使是在端点。

循环时间建模

一种方法是通过循环表示。这是为了将一年中的每一天建模为它们在一个年轮上的点。

通过使用上述圆圈上的 X,Y 位置作为我们模型的输入,我们的模型可以了解一年中销售额高的时间和销售额低的相反时间,这样它就不会错误地将季节性销售趋势归因于促销。

Cyclical Representation For Seasonality

然后,我们可以使用三角学来检查这些特征的回归系数,以了解什么时候是旺季,季节性对销售的影响有多大。这对于检查模型是否像我们预测的那样合理地学习特别有价值。

目标表征操纵

现在我们有了一个热编码和其他特征,我们可以使用回归来学习品牌水*偏差,使用支出特征来学习支出 ROI,使用周期性时间特征来学习季节性。

但是,如果我们想要了解特定品牌的投资回报率和季节性,这是鼓励类似于全球趋势,但也允许根据需要对每个品牌有所不同?

对于每个特征,我们可以使用该特征作为其全局表示,然后我们可以通过将该特征乘以品牌一热变量来构建品牌变化特征。对于营销支出,这将是一个像“显示品牌口香糖的营销支出”的功能。当我们从该特征以及全球“展示营销支出”特征中学习回归系数时,我们正在学习“展示”营销的全球 ROI,以及来自全球 ROI 的巨美变化。作为一种正规化的形式,我们使特定品牌的变化接*于 0。

现在,我们扩展的数据集看起来像这样:

我们有显示、广播和搜索支出等聚合功能,我们有品牌虚拟功能,我们也有组合术语,如“moon drops”的电视广告。请注意,对于除活动品牌之外的所有品牌,所有特定于品牌的功能在一行中均为 0。

目标陈述总结

想想我们上面做的有多酷!我们现在迫使我们的模型学习全局参数,这迫使不同品牌级别的表示相似,同时允许每个品牌在某种程度上学习他们自己的 ROI 参数。我们可以把同样的推理进行得更深入。

暂停,思考,并陶醉于我们的赋权。

请停下来,花些时间想想你希望模型告诉你什么。请随意阅读以下内容,寻找灵感。

也许你想了解产品的具体参数。你只需要把你的特征和产品的一个重要变量相乘,就可以强迫产品的表现和品牌相似。

也许你不想知道某类支出的投资回报率,而是想知道特定支出地区的投资回报率。如果你假设每个产品的“搜索”花费都应该有一个投资回报率,直到某个日常花费,然后在那个点之后显著降低投资回报率会怎么样?你可以让模型告诉你到某个点的投资回报率,告诉你投资回报率下降的截止点,然后学习该点之后的投资回报率。如果我们认为这就是世界的运行方式,并希望了解不同区域 ROI 的数学细节,以及模型切换的位置,我们可以通过组合二元指标变量和适当的支出特征来构建这些特征(尽管这一具体建议还涉及学习分界点,这需要进行额外的讨论才能实现)。

那不觉得授权了吗?

如果我们想知道产品价格是如何影响销售的,但是我们认为下面这个“一旦价格变得太低,人们会认为它非常便宜,再降低也没有任何帮助。超过这一点,价格波动会显著影响销售,直到销售过高,这时用户会认为太贵,价格效应就会饱和”。我们想知道这些不同行为的分界点是什么,以及不同地区的价格波动有多大影响。

如果我们可以基于这些类型的见解采取业务行动,那么我们肯定可以花费精力对它们进行建模,因为它只是结合了线性和二进制特征!

我们说过,在这篇文章的结尾,你应该理解自定义可解释性的特征表示的自由。这是设计我们模型的功能的力量,因为我们已经以我们期望的有商业意义的方式解释了结果。请尝试理解我们描述的定制,并思考如果模型告诉您一些事情,您将能够采取行动的其他见解,并思考模型将如何向您传递这些见解。

正常化

我们已经准备好了所有的数据,现在我们几乎可以训练一个模型了。然而,一个问题是,数学家们并没有像我让你们相信的那样设计出数学最优化。

假设我们为模型提供数据,其中一个输入值在 0-1 之间变化,另一个输入值在 1,000 到 10,000 之间变化。模型需要为每个要素学习一个乘数,乘数是正则化的,因此不允许它们非常大。模型使用小乘数来听大特征,而完全忽略小特征要容易得多。但是也许这个小特性有意义,我们怎么能允许模型包含它呢?

高斯归一化

为了帮助我们的数学算法工作,我们只是执行一个非常简单的技巧,它足够重要和简单,你们都应该理解它。

我们获取每个特征,并计算*均值和标准差(该特征变化了多少)。在训练之前,我们取每个数据点,减去*均值,然后除以训练之前的标准偏差。这迫使我们的模型的均值为 0,标准差为 1,这非常便于数学家构建算法,因为它具有高斯分布的均值和标准差。

我们也对我们的目标(Y)变量执行同样的转换,因为我们的输出常常难以处理大的或小的目标变量。

反规格化

当模型给我们洞察力时,我们需要记住逆转这种正常化。

假设 X 的标准差是 3,Y 的标准差是 7。我们将它们归一化为偏差为 1,然后学习回归系数为. 6。我们真正的投资回报率是多少?

在标准化空间中,我们的投资回报率为 0.6。但是,如果我们的标准化 X 增加了 1,我们的真实 X 增加了 3,所以要产生这种影响,我们需要花费 3 倍的时间。所以投资回报率应该是 0.6/3 = 0.2

但是. 2 是归一化 Y 的 ROI,实际上,归一化 Y 增加 1,真实 Y 增加 7。所以我们的投资回报率真的是. 2 * 7 = 1.4。

所以为了反规格化,我们只需要计算

real_ROI =归一化 _ROI * std(Y) / std(X)

总结特性和可解释性

总结一下,我们的特性和以前一样,除了标准化:

然后,我们可以运行回归,就像我们在之前的课程中了解到的那样。每个特征都有特定的解释。对于支出列,学习系数是累计的*均 ROI。对于品牌栏,这些是每个品牌销售的偏差。对于周期日期列,这些系数应该通过三角函数来告诉我们模型认为该品牌何时销售最好或最差。

应将品牌/特征组合特征添加到共享特征中,以从全球统计数据中了解特定于品牌的变化。

查看我们的模型输出,我们看到:

这为我们提供了消费类型的投资回报率,并建议每个品牌的高峰月份是什么时候。我们可能知道品牌的旺季是什么时候,并使用这些建议来检查我们是否相信这个模型。

没有业务可操作的季节性洞察,因为我们只模拟了季节性销售,而不是季节性支出的投资回报率(在本文中,我们当然可以模拟季节性支出的投资回报率)。

从上面看,我们可能只是想在一些品牌内转移资金。看看月落广告,由于相应的投资回报率(0.76 比 2.5),我们可能希望在展示广告上花更少的钱,在电视广告上花更多的钱

然而,在我们采取行动之前,我们检查了实际曲线,看看我们是否认为该品牌的销售似乎更受电视支出的影响,以确保我们作为人类信任这些疯狂的 ML 系统建议,我们看到了如下图像:

当然,我们看到销售额可能会因为电视消费的小幅增长而大幅上升,所以也许我们应该尝试一下。实际上,我们将对单个产品参数进行建模,我们将看到一个品牌中每个最有影响力的产品的曲线,如上图所示,以了解为什么模型会提出建议。

概述

在本次会议中,我们讨论了三个主题:

独热向量表示法

我们可以用一键向量来表示分类变量。

循环表示

我们可以使用循环表示来捕捉时间周期,如每年或每天的模式。

组合独热矢量和特征

我们可以结合热点向量、特征和其他概念来设计定制模型,以使我们的机器学习系统更加准确,同时还提供定制的可解释性。

这个问题展开: 机器学习入门 4 。

对于完全理解这一条的有意跟进帖子:https://medium . com/@ leetandata/machine-learning-engineering-1-custom-loss-function-for-house-sales-estimating-95 eec6b 12457

对于苦于代码或理解的人可选后续: 本帖代码详细分析:https://medium . com/@ leetandata/machine-learning-python-programming-introduction-for-business-people-10588 e 13 ce 9d

关于 Python 编程的免费综合课程。确保注册,但选择免费的可选项目。所有课堂内容免费提供:
https://www . coursera . org/learn/python-programming-introduction/

一个比这个更复杂的机器学习教程,但比下面这个(不是我写的)简单:https://www . ka ggle . com/rochelle Silva/simple-tutorial-for-初学者

软件工程师可选后续岗位: 重数学、重 CS 的详解(上):https://medium . com/@ leetandata/neural-network-introduction-for-Software-Engineers-1611d 382 C6 aa

重数学、重 CS 的详解(下):https://medium . com/@ leetandata/neural-network-for-software-engineers-2-mini-batch-training-and-validation-46ee 0a 1269 a 0

Cho 教授可选数学笔记:
https://github . com/NYU-dl/Intro _ to _ ML _ Lecture _ Note/raw/master/Lecture _ Note . pdf

ML 简介 6:不可微函数的强化学习

原文:https://towardsdatascience.com/ml-intro-6-reinforcement-learning-for-non-differentiable-functions-c75e1464c6b9?source=collection_archive---------10-----------------------

这篇文章将在系列的之后发表,但是代表了一个重要的转折点。我们现在已经解决了教授监督学习基础知识的问题,并且正在扩展以处理不可微的问题(激发深度强化学习)。

转变的原因有三:

  1. 我们已经总结了前一部分的所有重要细节;如何设计定制的神经网络来使用网络架构、定制的损失函数和学习潜在的共享表示来解决特定的问题。
  2. 我们已经非常关注营销归因的问题,但是营销的概念会强烈地激发行动的需要,这需要强化学习(RL)来建模。
  3. 我正在 NYU 大学给达维·盖格教授的课程视觉遇见机器学习做讲座(也是我将为百事公司内部做的标准企业讲座),因为我以前教过 RL。这将为在课程项目中使用 RL 提供工具。

我应该指出,现在你已经有了 ML 的基本工具,RL 只是继续学习的许多途径之一。学习机器学习的未来步骤可能是学习现有工具集的复杂的实际应用,更深入地理解 ML 的编码/数学,或者通过斯坦福大学在线发布的一些免费讲座/家庭作业学习参数共享(CS231N 用于图像处理,CS224N 用于语言建模)。

强化学习(RL)学习目标

这篇文章介绍了术语、问题类型和可用于解决不可微 ML 问题的 RL 工具。

听完这个讲座后,你应该明白:

  • 术语:环境、状态、主体、行动、模仿学习、匕首、价值函数、政策和奖励
  • ML 在存在不可区分的报酬、学习行动和模拟非确定性环境时的问题。
  • 如何利用专家帮助通过匕首学习?
  • 用政策梯度对不可微报酬建模。
  • 用值函数估计状态值。
  • 通过概率抽样、政策梯度和延迟回报模型学习行动。
  • q-学习同时对状态和价值建模(以及在连续行动空间中这样做的行动者-批评家算法,如营销行动问题)
  • 通过对观测值进行调节来模拟非完全观测的环境。

监督学习不足 0: ML 无数据

对于监督的机器学习,我们需要一个数据集来建模。所以这在一些没有数据的环境中是站不住脚的。

模仿学习:抄袭专家

在学习行动的领域(例如,机器人、游戏或其他交互式决策),我们可以通过模仿专家来学习。如果我们有传感器可以捕捉输入和相应的人类/专家动作,我们可以收集一个数据集,并应用监督学习方法来复制专家的动作。

模仿学习只是模仿专家动作的监督学习。你观察一个代理人在不同的州是如何行动的,然后训练一个模型来复制它。监督学习。

DAgger:交替生成和使用数据

假设我们有一个算法,让人类在模拟环境中行走。我们可以从控制我们行走代理的专家那里训练这个算法,然后训练一个模型来复制专家。但专家永远会走得很完美,我们永远看不到如何改正错误。所以当我们运行我们训练过的模型时,它正确地向前运行,然后一旦偏离正常轨道它不知道该怎么办,所以它很快就崩溃了。

太可怕了!人类/专家知道如何纠正错误。所以我们所做的是让我们的模型控制模拟,并在每一步要求人类采取正确的行动。我们通过训练我们的模型复制新收集的数据来重复,然后向专家寻求更多建议。

那就是 DAgger,只是让你的模型决定如何行动,并从它探索的所有情况中问一个专家如何行动。训练您的模型复制专家的决策,然后使用您更智能的模型运行模拟。

监督学习不足 1:不可区分的奖励

监督学习的工作方式如下:

  1. 预测产量
  2. 计算输出的损失/误差
  3. 更新你的预测系统

如果算法是看到一个物体,然后猜这个物体是什么。例如,你可以看到一个水果,你的输出可能是单词“苹果”。

‘What Fruit is This?’ ‘Apple.’ ‘Wrong!’

如果你猜对了,就给你一个 cookie(或者给定的算法+1)。如果你猜错了,你会被扣分(或者算法给 0 或-1)。

我们未能将此框架为监督学习问题,因为当我们出错时,我们不知道正确的值是什么。我们所能做的就是“当我们把事情做对的时候,多做这类事情”,以及“当我们把事情搞砸的时候,少做这类事情”。

例如,在上面的图片中,假设我们的模型预测了“苹果”,并被惩罚告诉它这是错误的。在监督学习中,我们应该告诉它“在这种情况下,你应该预测到‘西瓜’”,但在这种环境下,我们没有这种监督。我们如何训练模型做得更好?

引入政策梯度

策略梯度让我们在没有可微分损失函数的情况下分配梯度。例如,当我们预测西瓜的标签时,我们实际上预测了可能的单词/标签的概率分布。我们随机抽取了“苹果”这个词,这是错误的。

对于策略梯度,我们为预测“苹果”分配一个负梯度,这使得所有其他预测更有可能。然后,我们执行正常的反向传播,并根据这一损失更新我们的参数。相反,如果我们对“西瓜”取样,并得到正确的预测,我们会给我们的预测分配一个正梯度。

我们可以使用策略梯度来教一个模型去尝试一些事情(随机抽样),并且学会做更多正确的事情,更少的错误。

这是简单的不可微分奖励政策梯度的概念。我们还引入了奖励的概念,即我们从猜测中得到的饼干(+1)或惩罚(-1)。

预算/营销分配的确定性政策梯度(即持续行动的政策梯度)

如果您不想预测一个 Softmax 和样本来执行操作,该怎么办?如果你只想要一个确定性的单个数作为决策呢?政策梯度不能真正做到这一点,因为你不知道在这种情况下,为了获得更好的回报,应该朝哪个方向努力。

我们来提出一个简化的预算分配问题。作为一个州,你有一年中的时间。作为一项行动,你选择了一笔预算支出,作为奖励,你得到了利润(收入减去预算支出)。

对于我们的行动空间,我们不能像在正常政策梯度中那样枚举行动并预测每个行动的 Softmax 概率,但我们可以估计高斯样本的参数。通过这种方式,我们可以预测连续值,因为我们可以从高斯样本中对连续值进行采样,而不需要对每个值进行唯一的概率估计。我们可以学习优化我们的分销以获得更大的利润。这包括首先学习一个估计动作值的函数 f(state,action ),然后我们对该函数进行微分以优化我们的动作生成器。

特别是预算/营销分配的问题是一个持续行动的问题,在我们介绍 Q-Learning 之后,我们将用一个更一般的行动者/批评家算法对此进行进一步的扩展。

监督学习不足 2:行动顺序

现在,我们将通过概率抽样、政策梯度和延迟奖励模型来探索学习行动的概念。

我们来想想象棋和 ML 的博弈。游戏通过开始位置、交替动作和棋盘更新进行,直到僵持或胜利。国际象棋是一种完全可观察的游戏,游戏的所有相关信息都显示在当前的棋盘状态上。

游戏结束时,玩家要么赢(+1),要么输(-1),要么*手(0)。

在 ML 中,我们希望学习最佳的行动策略,以确保无论对手如何打法,我们都能赢得比赛。我们称这种学习为行动的策略,而不是学习一种特定的行动,因为我们不想学习在国际象棋中获胜的最佳行动。例如,要采取的最佳行动取决于当前的棋盘状态,在任何情况下都不存在全局最佳行动。

这就是为什么我们学习策略,这是 RL 中的一个核心概念。策略是根据当前状态选择动作的功能。你可以想象,最好的策略总是在下棋时获胜,因为他们在任何情况下都玩得很完美。在 RL 中,我们经常学习最优策略,这与监督学习不同,在监督学习中,我们试图建立一个观察分布的统计模型。

具体来说,我们将如何编码策略?幸运的是,国际象棋是一个有组织的网格,所以我们可以接受棋盘上的每个位置作为模型的输入,用一个独热向量值表示每个单元格中的棋子(如果有的话)。我们将计算移动哪个棋子的软最大概率,并计算它应该在棋盘上移动的位置的软最大概率,并过滤以仅允许它选择允许的棋子/移动。

但是应该如何训练这个策略呢?在每个序列中我们采取了很多行动,我们的对手也采取了很多行动,然后游戏以+1,-1,或者 0 结束。

让我们具体点。我们的政策是一个函数 f(董事会状态)=行动的概率。然后,如果序列以赢结束,我们可以用正梯度奖励我们的每个行为,如果序列以输结束,我们可以惩罚我们的行为。

折扣延迟奖励

然而,给我们所有的行为分配一个全局的+1 或-1 应该感觉很奇怪。由于动作序列的空间是巨大的,你得到的奖励会很嘈杂,用这样稀疏的奖励训练一般来说是很辛苦的。所以,我们想让奖励更有意义。最直接的方法是避免迅速导致失败的行为(例如,避免接*将死的局面),奖励迅速导致胜利的行为。

我们提出,分配给一个行为的奖励的积极或消极的数量应该随时间呈指数衰减。所以奖励前的最后一个动作应该得到奖励。而在给予奖励前 n 步的行动应该得到较少的奖励,ɣ^n 那里每前一步只得到(0

替代方法:价值函数

我们上面讨论的叫做策略函数优化。我们有一个接收状态并产生动作的函数,我们优化这个函数。

另一种方法是预测每个状态的值,要么通过该状态是否会导致奖励,要么通过它是否会导致良好的未来状态。这个系统特别适合当我们知道一个系统的全部动态时,我们可以从任何状态备份找到精确的最优解。

这是由贝尔曼后备方程式定义的,我们不需要为了这篇文章的目的完全理解它。该等式规定每个状态的值应计算如下:

  1. 迭代每个状态的每个可用动作。
  2. 每个行动的价值是产生的回报加上先前对后续状态的估计值之和。

为了使用这个系统采取行动,我们查看所有我们可能转换到的未来状态,并选择产生最佳未来状态的行动。

考虑行动的价值函数:Q 学习

我们可以结合两个世界的优点,而不是政策函数或价值函数。

Q 函数是评估状态-动作对的函数。Q 函数学习状态-动作对的值,并估计它是报酬加上对未来状态值的估计。在这种情况下,未来状态的值的估计是通过取从该状态可以采取的所有动作的最大值来估计的。

Q-Learning Update Formula

阿尔法可以被视为一个学习率,其余如下。假设 Q 有一个赋值函数 F(s,a) =状态/动作对的值。然后,我们可以根据值的概率软最大值对动作进行采样。

然后我们优化我们的 Q 函数,使其更接*上面的函数值。

深度 Q 学习

深度 Q 学习允许我们将 Q 学习与通用函数逼*器相结合。我们不是更新每个动作的 Q(s,a)值,而是优化神经网络 Q(s,a ),该神经网络使每个状态动作对的值接*所产生的奖励加上未来状态的冻结估计值(以最佳未来动作为条件)。

可惜上面的算法没有一招会不稳定。我们正在优化一个网络,使之等于一个奖励加上它本身。我们可以很容易地优化这两个网络,使它们彼此相等,由奖励抵消,但这似乎产生不太稳定的结果。

取而代之的是,我们冻结我们用来*似我们的回报的内部 Q 函数,并训练外部 Q 函数来*似它。

然后,我们可以定期冻结我们的更新 Q 函数,并将其代入内部 Q 网络,从而允许深度 Q 学习更可靠地训练。

检查点:复制和可计数操作

到目前为止,在 RL 中,我们已经介绍了将衍生工具应用于不可微损失的政策梯度,以及将延迟回报贴现以将损失应用于之前的行动。

我们可以模仿专家,就我们陷入的糟糕情况向专家寻求建议。我们已经讨论了政策(决策过程)、奖励(获胜的 cookies)、价值函数(使国家的价值函数化)和行动(决策)。

我们扩展了价值函数和策略梯度,以建立状态、动作对的 Q 函数。

这些是 RL 的核心构件。剩下的就需要我们理解上面的内容了。

我们如何为不同的 RL 问题建立数据集和训练?

在监督学习中,我们有一个数据集,我们学会了对数据生成分布进行建模。

数据集:模仿学习/匕首

在匕首,我们正在学习复制一个专家。因此,我们收集专家如何决策的数据集。数据集由观察到的状态和专家的行动组成。

数据集:Q 学习

在 Q-Learning 中,我们基于以下奖励和新状态对状态动作对的值进行建模。所以在 Q 学习中,我们的数据集跟踪每个数据点的细节。我们有状态、行动、奖励、在数据收集期间收集的跟随状态组,因为那是我们需要用来训练的。

数据集:策略梯度

在上述强化学习场景中,我们有策略梯度,它可以应用于任何随机监督学习数据集或其他学习问题。

在可行的情况下,我们更喜欢使用我们的监督学习工具,而不是策略梯度,并且我们只在监督学习无法对我们的数据建模时使用策略梯度。我们还可以使用策略梯度来增强监督学习系统,作为辅助奖励。

没有额外数据:我们如何使用策略梯度来增强监督学习系统

想象一下学习生成句子。也许我们有一个监督学习系统,它可以像数据集一样学习生成句子,但起初它会不断生成常见的停用词,如“it it it it it it it it”或“the the the the”。我不会详细解释为什么会经常发生这种情况,但是通过政策梯度,我们可以解决这个问题。我们可以基于真实数据进行训练以建立数据集模型,我们也可以生成完整的句子,并使用策略梯度来惩罚我们自己的重复。例如,如果一个句子在推理过程中重复使用同一个单词(当模型试图自己造句时),我们可以很容易地使用策略梯度来惩罚生成的句子中过度使用的单词的生成。

然后,我们用 actor-critic 算法推广了连续或高维动作空间的 Q 学习。

像预算/营销分配这样的持续行动的学习:行动者-批评家学习

让我们更深入地看看预算分配问题。我们希望在广告上投资,以使我们公司的利润最大化,但现在我们有多种产品销售,多种投资方式,我们希望使全球收入最大化。

  • 状态是每种产品的一年中的某一天、最*的销售和最*的花费。
  • 该活动是每个预算的连续值。
  • 回报是利润的总和。

通过这种方式,我们希望对营销支出如何在不同的状态下产生不同的影响进行建模。

我们知道我们想要更大的回报,但是没有导数告诉我们如何改变我们的行为,所以我们仍然需要用一个批判函数来*似回报曲线。

让我们重申一下 Q 学习更新公式:

Q-Learning Update Formula

上面的 Q 学习算法非常有效,在适当的时候,它是最先进的算法。但是在每一个更新步骤中,它迭代未来状态的所有可能的动作,这在计算上可能是昂贵的。在预测在各种营销活动中投资多少钱的连续值时,从未来状态可以采取无限多的行动,因此我们如何列举所有可能的行动呢?

所以我们想用 Q-learning 的概念,但是不想枚举所有可能的动作。

在不迭代所有可能动作的情况下*似 Q 学习是 actor critic 算法的动机。

Actor Critic Algorithm Visualization

演员评论家算法允许一个函数根据当前状态、未来状态和未来折扣奖励来估计一个连续的动作。该算法通过训练一个单独的 critic 函数来实现这一点,该函数被训练来估计奖励加上贴现的未来奖励(Q 值)。然后我们训练演员最大化评论家的期望值。

监督学习不足 3:部分观察,嘈杂的环境

我们之前提供的工具在部分可观察的环境中仍然会失效。让我们通过假装我们是 FinTech 的黑客来激发这个算法。

假设我们在股票市场上交易股票,我们入侵了一个金融科技数据源以获得关于股票的高频信息,但你的免费交流源并不完美,你错过了所有信息的百分之几(30%),我们获得的信息有一些随机噪声。

在每一个时间点,你可能想根据现有的数据学习交易。你假设你的交易正在影响市场,而且你还模拟了一些一般特征,比如一些股票一起上下波动。

这与 SL 有另一个不同之处,因为我们不能预测市场的运动,我们要选择如何行动。例如,如果我们想成为做市商并避免交易费用,进入和退出市场并不总是成功的。因此,我们需要学会明智地采取行动,这不同于仅仅根据我们预测的市场走势进行交易。

基于模型的 RL 帮助我们在这种环境中行动。我们先建立一个环境的模型,而不是从我们收到的嘈杂数据中进行交易。我们的模型学习什么是最有可能引起我们观察的真实数据,以先前的观察和我们的行动为条件。

观察、状态和环境

在基于模型的 RL 中,我们可以完全定义观察、环境和状态,我们在整个课程中反复使用过。

Forward Propagation Environment Dynamics

观察是我们所感知的。它们可能不准确,但它是我们得到的关于我们环境的任何信息。在股票的例子中,观察值将是我们接入的噪声信号。

状态不同于观察。状态是我们建模的东西,它(希望)给我们做决定所需的所有重要信息。一个简单、全面的状态可以是整个轨迹中所有观察和动作的序列。这种状态是全面的,但是昂贵的。另一个简单的状态是当前观察值,它计算量小,但可能不包括所有相关信息。

Backward looking Environment Dynamics

环境不是观察结果,而是世界上与我们的问题相关的所有事情的综合细节。我们的环境目前可能有一个特定的表示,但我们通常永远不会知道真实的环境状态。通常,有一些控制系统动态的隐藏因素,这些因素控制着系统在旧状态的基础上改变到新状态的可能性(例如,速度继续移动,状态因速度而改变)。我们还可以尝试模拟不同环境状态产生特定观察结果的可能性,或者换句话说,“当环境处于这种状态时,我们将看到什么类型的观察结果”。

包装噪音库存示例:基于模型的 RL:

对于有噪声的股票示例,我们建议基于基于模型的 RL 进行决策。这将涉及建立一个模型,以确定每个环境状态产生不同观察结果的可能性。我们还需要一个模型,来说明我们期望真实的环境在当前状态和我们行动的条件下如何发展。最后,有了定义的模型,我们需要一个模型来接受估计的状态,并选择要采取的行动。这些模型可以是神经网络、高斯模型或我们环境的任何其他概率模型,并且可以是硬编码的或学习的。

基于模型的 RL 如何应用于 Vision Meets ML 项目(使用姿势估计视频进行动作估计)

这个课程项目是关于根据提取的姿势运动来估计视频的内容。我们将此建模为一个代理试图采取什么行动来生成观察结果。把这看作一个 RL 问题,我们有几个选择。

选项 0:

有这样一个环境,它具有规则 P(S+1/S,A ),用于以代理正在采取的动作为条件的状态转移概率。

s 是高维对象,或者可选地,我们可以在三维空间中直接将具有 25 个关节的代理建模为(关节数* (xyz)) = 25*3 =人的 75 维状态,加上额外的 150 来表示当前的速度和加速度。

所以我们模型 P(St+1/St,A)的速度和位置正好等于之前的状态+导数。对于加速度,我们将转移概率作为神经网络(或线性矩阵)(225+1 个输入,75 个输出)来学习,并最小化数据的对数概率,以便尝试我们的连续动作生成功能。我们还可以学习一个残差函数来预测我们的位置和速度的偏差,作为对预测值的调整

我们假设我们的视频/观察是从一些噪声加上我们的状态中采样的,并且我们试图最小化那个(高斯)噪声。

我们还将应用一个损失,该损失着眼于单个动作(环境空间中的预测加速度),以及这些动作作为一个序列发生的状态,并预测损失。它越早预测出正确的损失越好。每个状态预测一个损失,并从正确预测序列的末端获得指数衰减的奖励。

这是专门设计来表示最受物理激励的/简单的方法,用于学习具有 RL 的通用函数逼*器,以解决根据视频的姿态估计来估计动作的问题。

使用这种或类似的方法,我们可以使用 RL 来基于视频中的姿态生成实时动作估计。

总结我们所学的内容,并补充阅读:

在整个会议期间,我们

  • 开始用模仿学习匕首来模仿专家
  • 扩展到策略梯度以学习从离散选项中选择动作,并显示连续动作的变体
  • 讨论了评估状态而非动作的值函数
  • 将我们的策略和价值函数组合成状态和动作的 Q 函数
  • 将 Q 函数推广到连续状态空间的 Actor-Critic 算法中,这样我们就可以在不枚举所有可能行为的情况下获得对未来回报的估计。注意到这恰当地模拟了预算分配问题
  • 讨论了基于模型的 RL ,其中我们构建了一个部分模糊或嘈杂环境的预期模型。我们注意到这种算法的两个版本,它们是视觉与人工智能课程项目的合适模型
  • 讨论了数据收集,并注意到一些 RL 风格如何明确地需要数据收集(如 DAgger),而其他风格(如 policy gradients)可以在现有的监督学习数据集上使用。

我们遗漏了几个核心主题,如果您有兴趣,可以跟进:

  • 有时,我们想故意采取不同于最优的行动,以探索我们可能错误地低估了的新行动。这叫做 勘探/开采权衡
  • 在 RL 有很多新的研究。加州大学伯克利分校慷慨地在网上上传他们的课程视频和家庭作业,最*的是 2017 年的版本,因为他们跳过了 2018 年的版本,这些都可以在T5【这里】T6找到

同系列推荐随访:

https://medium . com/@ leetandata/ml-intro-7-local-connections-and-spatial-parameter-sharing-abstract-convolatile-layers-b 419 e 629 d2d 0

软件工程师可选后续岗位: 重数学、重 CS 的详解(上):https://medium . com/@ leetandata/neural-network-introduction-for-Software-Engineers-1611d 382 C6 aa

重数学、重 CS 的详解(下):https://medium . com/@ leetandata/neural-network-for-software-engineers-2-mini-batch-training-and-validation-46ee 0a 1269 a 0

Cho 教授可选数学笔记:
https://github . com/NYU-dl/Intro _ to _ ML _ Lecture _ Note/raw/master/Lecture _ Note . pdf

[ML]网络培训—了解一些细节

原文:https://towardsdatascience.com/ml-network-training-getting-into-some-details-ad33198626ee?source=collection_archive---------3-----------------------

TL;博士

人工神经网络训练包括一个迭代的正向(推理)和反向(反向传播)过程,目的是调整网络参数,以减少隐含(即采样+噪声)定义的目标函数的相似距离

长版

让我们考虑一个人工神经网络学习传递函数

ANN Transfer Function. X is the Data Space and \Omega the Parameters Space

在监督学习中,训练 ANN 的目的是使网络传递函数逼*目标传递函数,该目标传递函数不是以显式封闭形式而是以隐式采样形式提供,作为一组训练数据点。

此外,不幸的是,样本不仅考虑目标传递函数,还考虑一些附加噪声。我们想让人工神经网络学习尽可能少的噪音,以达到更好的泛化性能

Line1 : Target Function. Line2 : Noise. Line3: Dataset as a collection of Target Function samples with some added Noise

这种目标函数表示提出了两个主要问题

  • 离散与连续信息:人工神经网络传递函数是连续且可微分的(要求能够使用基于梯度的方法),而目标函数表示是离散的,因此人工神经网络本质上应该学会在数据点之间正确插值
  • 噪声:ANN 对噪声了解得越多,它就越不能正确地进行归纳

ANN 训练通常意味着解决网络参数状态空间中的最小化问题,该最小化问题涉及与一些网络参数化相关的 ANN 传递函数和目标之间的相似性度量,因此是我们的噪声目标函数采样。

让我们将这种相似性度量视为关于训练数据点子集定义的目标函数,我们称之为批次作为单个贡献的总和

The Similarity Measure or Error Function is defined with repsect to a Batch of Points as Sum of each single Data-Point Contribution

培训通常包括两种类型的网络信息传播:

  • 前向信息传播,旨在从一些输入(即训练数据)开始执行推理
  • 反向信息传播,旨在根据误差(定义为推断数据与训练数据差异的函数)进行参数拟合

前向信息传播发生在数据空间,而参数空间是固定的

Training Forward Step aimed at computing a specific Data-Point contribution

反向信息传播,称为反向传播,发生在参数空间,而数据空间是固定的

Backpropagation of the Information using Gradient computed on a Batch

训练是一个两级迭代过程:一次迭代包括一个从批量数据到错误的前进步骤和一个从错误到参数更新的后退步骤

  • 第一组迭代旨在覆盖所有训练数据,一批接一批,从而完成一个时期
  • 第二组迭代逐个历元周期地考虑一个历元

当批量大小等于训练集大小时,则使用标准梯度下降方法,并且计算的梯度是真实梯度:相对于所有可用信息计算的梯度。在这种情况下,1 次迭代= 1 个时期。

该算法允许最佳的收敛,但是从内存和计算的角度来看,它都非常昂贵,因为在执行参数更新之前使用了所有可用的信息,因此有可能提高性能。

培训成本随着用于执行更新步骤的信息量的增加而增加。

然后,策略可以是使用减少的信息集来执行更新步骤,从而减少批量大小,并因此计算真实梯度的*似值。

*似梯度相对于真实梯度的差异在于,噪声/信号比将随着*均效应的降低而增加。此外,使用这种方法,完成一个时期的迭代次数将增加,但是从计算和存储的角度来看,它们将变得更便宜。

ML 注释:为什么是最小二乘误差?

原文:https://towardsdatascience.com/ml-notes-why-the-least-square-error-bf27fdd9a721?source=collection_archive---------0-----------------------

免责声明:

这篇博文属于我的“ML 笔记”类别。它的目标是帮助我确保理解 ML 中使用的工具和理论。我相信,从教育学的角度解释我所学的东西,一步一步地消除任何未知,是实现这一目标的最佳方式。

你需要什么?微积分,代数,概率,机器学习(主要是定义)的一点点数学背景。

如果你发现任何错误,请联系。如果错误的信念留在我的脑海里,我会很难过,因为发现它们时已经太晚了,谢谢!

使对数似然显式化

在我的上一篇笔记中,我已经写了许多实践和理论上的原因来解释为什么对数似然法经常被用在 ML 算法中。但是我没有达到一个可以实现的显式表达式。

让我们通过探索这种对数似然思想如何在两个主要的 ML 概念下产生我们所说的最小*方误差(LSE)来进一步挖掘:监督学习(SL)和加性高斯白噪声模型(AWGN)。

我将只从概率的角度探讨 LSE(我不会探讨 LSE 如何从微积分或线性代数中产生/证明)。在文章的最后(备注 5),你会发现一个链接,它的表亲(均方差或 MSE)的许多有趣的属性。

监督学习

在我的上一篇笔记中,我们最终展示了“在给定数据集的情况下最大化模型参数的可能性”等同于“最大化数据记录概率的总和”(考虑到 I.I.D .假设,请参阅上一篇笔记了解更多信息):

Maximum likelihood with log-probabilities in the general case

现在,我想把重点放在我们所谓的监督学习上,其中:

  • 数据“d”是由输入对象“x”和所需输出值“y”组成的一对“{x,y}”
  • 输出“y”取决于“x”
  • 目标是建立一个模型,在给定“x”的情况下预测“y”

让我们将此设置应用于数据的概率:

The probability of a datum in supervised learning

  • (2)来自监督学习中数据的定义
  • (3)是关于条件概率的联合概率的定义
  • (4)源于输入的内在概率不依赖于模型或其参数的事实。

由于“x”的概率不依赖于“θ”,我们可以在(1)中应用(4)并获得:

Maximum likelihood with log-probabilities in supervised learning

因此,为了最大化监督学习中参数的似然性,我们可以关注在给定相应输入的情况下最大化输出对数概率的总和。这很好,因为从程序上来说,这符合函数的定义。

注意:为了完成优化过程,从理论的角度来看,联合概率符号是非常好的,那么为什么要关注条件符号呢?

这也是由于工程上的限制。为了计算联合,您需要构建一个函数,将“x”和“y”作为输入,输出一个概率:联合概率。为了计算整个联合分布,你必须对给定的“x”的所有“y”进行批处理。现在,如果你想做小批量,你必须批处理这些批次的倍数…这导致了大量所需的 GPU 功率。

实现相同结果的优化方法是直接使用我们的模型来*似条件分布:我们可以构建一个只接受一个输入“x”并立即直接计算所有“y”的函数。我们的模型正在逼*条件概率本身的分布。这大大减少了所需操作的数量,从而提高了我们算法的速度🔥

回到现实生活!我们知道我们可以在 TF 中建立一个参数化的函数来表示我们的模型族。它应该把我们的“x”作为输入,输出一些值,这些值可以解释为给定“x”的“y”的条件分布。我们现在有了模型,我们需要的最后一件事是优化(训练)函数参数的方法,这样我们的函数就可以逼*由数据集中的标签定义的分类分布。

所以,我们需要一个目标。这个目标可以是比较 1-hot 向量标签(分类分布)和我们的函数的输出,以减少它们之间对于每个数据的任何差异。但是如何证明任何比较呢?如何比较这些价值才是有效的、稳健的和实际上有助于概括的?应该用绝对差吗?*方误差?其他一些外来的规范?

有无数种可能的方法可以做到这一点,设计目标函数仍然是一个正在进行的活跃的研究领域。那么,我们如何从概率的角度证明 LSE 的使用呢?

加性高斯白噪声模型(【AWGN】

数据集只不过是来自随机过程的大量样本。无论我们的数据集中反映的随机性的原因是什么(要么来自丢失的信息,要么来自测量误差),我们都可以用噪声对其建模。

假设我们的数据集是一致的(参见备注 1),在问题中引入噪声有两种常见方式:

  • 噪声可以独立于我们的数据,我们称之为噪声添加剂。这通常是由于贴标签时的人为错误和/或传感器不准确造成的。
  • 噪声可能依赖于我们的数据,我们称之为乘法噪声。乘性噪声可以模拟丢失的信息,如丢失的感兴趣的输入特征,以预测输出。

那么,我们应该添加什么噪声呢?我们将采用最简单的可能噪声模型(这一选择是由奥卡姆剃刀发起的):加性高斯白噪声模型,它表示:

  • 存在一个将输入与输出相关联的函数,但我们测得的输出会受到加性噪声的影响。

The additive white Gaussian noise model

  • 所有的噪声都是由白高斯分布产生的:*均值是0并且噪声是同分布的
  • 所有噪声随机变量相互独立,并且独立于我们的数据集的数据

White Gaussian distribution

请记住,我们希望在上面的等式中模拟函数“h”。我们将假设我们选择的模型类(所有可以用我们的模型*似的函数)可以*似,以及我们想要的,这个函数“h”。

Approximation of the underlying mutual information relationship

给定我们的数据之间的关系的模型,我们可以滚动一些数学并且明确地写下给定“x”的“y”的概率:

Step by step demonstration to reach the LSE

  • (8)我们正在替换随机变量 Y 的值
  • (9)我们利用“X”给定,随机变量 Z 独立于 X,“θ”和“m”的事实
  • (10 和 11)我们应用(6)并获取日志
  • (12)我们从“argmin”中去掉任何常数。我们只保留 0.5,因为在计算导数时,数学上比较方便。

一个巨大的*方误差出现了!请注意,我们可以除以元素的数量来免费获取均方差(MSE)。

备注 1

t 已经证明了 如果你为监督学习生成一个随机数据集,你总是可以建立一个足够大的模型(就容量而言),它将过度拟合(记忆)数据并达到*0* 的训练损失😨

这很重要,因为这意味着对于任何数据集,你都可以欺骗自己相信你解决了一个实际上只是“硬编码”数据集关系的任务。

这对于必须严谨的数据集创建者来说更加重要:当一个人收集数据集用于监督学习时,他已经在假设所收集的输入和输出数据具有互信息关系(相关)

举个例子,我可以收集一个数据集,把月亮的位置作为输入,把国家彩票的结果作为输出。即使它们明显不相关,您也可以找到一个模型来过度拟合该数据集。

备注 2

当使用 AWGN 时,我们引入了每个样本不可约的随机误差。您知道预测值不能等于噪声输出值,因为这意味着您过度拟合了您的训练集。

*均而言(意味着对于足够多的点),每个预测应该具有等于加性噪声的标准偏差的误差。

特别是,如果你在“足够多的数据”上计算均方误差,我们应该接*噪声的方差(标准差的*方)。在下面的代码部分可以找到一个具体的例子。

备注 3

我们永远不应该忘记使用监督学习的最大似然估计程序和 AWGN 模型的成本。以下是我们为证明 LSE 培训阶段的合理性而做出的假设列表:

  • 我们假设我们在训练集中的数据是独立的。
  • 我们假设在我们的输入和输出之间存在一种交互信息关系
  • 我们假设可以使用我们选择的模型族来*似这种关系。
  • 我们假设只有一个噪声源
  • 我们假设噪声在输出值上是附加的
  • 我们假设这种附加噪声来自白高斯分布
  • 我们假设这种加性噪声是独立的,与我们的数据无关

现在,一系列假设证明了为什么我们的模型应该能够在测试集上具有很高的准确性,并且能够预测新数据:

  • 我们假设测试集中的数据(以及未来的数据)也是独立身份的
  • 我们假设测试集中的数据(以及未来的数据)与训练数据分布相同。例如,现实生活中的概率分布通常不是时间独立的:它们随着时间的推移而演变,有效地打破了这些假设。
  • 我们假设测试集(和未来数据)受到完全相同的噪声源的影响

假设所有这些,我们开发一些巧妙的学习算法,并假装它会工作……很多时候,它真的会工作!🍻

更严重的是,我认为记住这些假设有助于一个人在制作新数据集时非常小心,甚至更好的是,在事后测试它们。

备注 4

关于您可能在野外发现的符号的细微差异的说明:

Difference between conditional probability on multiple r.v. and parametrised function

第一个符号表示“theta”和“m”是随机变量,第二个符号(注意分号)表示“theta”和“m”只是参数(与概率观点无关)。两者都很好,只是解释不同,这影响了你允许自己应用的理论。

在我的例子中,我想说明的是,我们选择了一系列模型及其相应的参数,这些参数是基于一些先验知识,人们可以用概率分布,贝叶斯观点来建模。

在 ML 世界中,符号是非常复杂的,因为这是一个混合了多个数学领域的世界(至少是概率论、线性代数、微积分)。所以请,力求严谨!

备注 5,*方误差的更多性质

我不能在 LSE 上写一篇文章而不提到栈交换上这个关于均方误差(MSE)的可怕问题。

去读吧,里面包含了很多真知灼见!

编码时间到了

让我们用科学的方法,让理论与现实对抗吧!为此,我们将构建一个玩具示例:我们将尝试在给定的时间间隔上*似正弦函数。这在 SL 中被称为回归。

让我们深入代码,一切都在注释里。

以下是培训阶段:

Screenshot of the training phase

下面是结果图:

Results of the experiment

关于实验的一些评论:

  • 我们相当成功地重建了窦功能,即使有很强的附加噪声
  • 我们的优化算法损失确实在不可约误差:0.5 附*波动
  • 当我们降低学习率时,我们有了更细粒度的改进
  • 如果测试集与训练集不一致,它就不起作用!这个例子可能看起来很明显,但是如果您使用图像作为输入,那么当您离训练数据集流形太远时,就很难判断了。

无论如何,如果你读到这里,谢谢你!

干杯!🍺

感谢 Alex Orange 的所有反馈!

ML 笔记系列

  • 为什么对数似然?
  • 为什么是均方差?(这个✍︎)

参考资料:

[## 加性噪声和乘性噪声有什么区别?

回答:让我们考虑一个遵循随机微分方程的变量 x(t)。如果相应的随机…

www.quora.com](https://www.quora.com/What-is-the-difference-between-additive-and-multiplicative-noise) [## 为什么要求差的*方而不是取标准差中的绝对值?

在标准偏差的定义中,为什么我们必须对*均值的差求*方才能得到*均值(E)和…

stats.stackexchange.com](https://stats.stackexchange.com/questions/118/why-square-the-difference-instead-of-taking-the-absolute-value-in-standard-devia) [## 统计学中的正方形事物-一般原理

你为什么在统计中把事情*方?我在数据挖掘和统计课上遇到过很多这样的问题,但是没有人…

stats.stackexchange.com](https://stats.stackexchange.com/questions/127598/square-things-in-statistics-generalized-rationale/128619) [## 监督学习-维基百科

监督学习是从标记的训练数据推断函数的机器学习任务。训练数据…

en.wikipedia.org](https://en.wikipedia.org/wiki/Supervised_learning) [## 加性高斯白噪声-维基百科

AWGN 经常被用作信道模型,在该模型中,对通信的唯一损害是宽带或频带的线性增加

en.wikipedia.org](https://en.wikipedia.org/wiki/Additive_white_Gaussian_noise)

机器学习简介 2:我们的第一个例子

原文:https://towardsdatascience.com/ml-preface-2-355b1775723e?source=collection_archive---------6-----------------------

本帖跟随机器学习简介 1 。我们将把机器学习应用于营销分析,作为一个简单的商业应用用例。我们将调查流行的机器学习方法,并将每种方法应用于市场分析。我们观察到,一些方法在衡量不同营销活动的投资回报率(ROI)时更具解释性,而其他方法提供了更准确的销售预测。参见第一堂课,了解本文中使用的每一种方法的解释。

这个内容是深度学习第一讲的后半部分。

学习目标

这篇文章给出了回归、特征工程和使用神经网络建模数据集的真实例子。它激励并展示了每种方法。

问题设置

在这个问题中,我们是一个虚构的营销组织。我们查看我们的历史支出和销售额,并将每日营销支出映射到每日销售额。

我们的环境经过简化,适合作为入门机器学习的学习工具。在这种设定下,我们有很多天的品牌销售,但是每一天品牌的销售额只取决于公司在那一天花了多少钱。

在这个例子中,有两种类型的营销支出,品牌营销(brand)创造品牌形象,直接面向消费者营销(d2c)推动销售。

我们根据这两种类型的营销都会增加销售额的规则来模拟这些数据,但是如果两者之间存在*衡,它们的贡献最大。支出与销售的图表如下:

单个结果可以像 excel 表格一样可视化,例如:

Table Visualizing Sales

编码活动:数据可视化

我们从导入一些我们需要的包开始

**import** **numpy** **as** **np
import pandas as pd
import** **matplotlib.pyplot** **as** **plt**
**from** **mpl_toolkits.mplot3d** **import** Axes3D

我们设置了一个随机种子,因此如果您在本地计算机上执行此操作,您将会看到与我们在这里看到的相同的随机结果。这对再现性很重要。

np.random.seed(0)

接下来,我们生成数据集

NUM_SAMPLES = int(2e3)
brand_spend = np.random.rand(NUM_SAMPLES)
d2c_spend = np.random.rand(NUM_SAMPLES)
individual_contributions = brand_spend * .01 + d2c_spend * .02
collaboration = np.square(brand_spend) * d2c_spend * 10
sales = individual_contributions + collaboration + np.random.rand(NUM_SAMPLES)/10

最后,对于线性回归部分,我们有一个执行线性回归的函数和另一个绘制结果的函数:

这里,我们将数据集包装到一个数据帧中。这让我们可以像在 python 中查看 excel 表格一样查看数据集。

dataset = pd.DataFrame({
    'brand': brand_spend,
    'd2c': d2c_spend,
    'sales': sales
}).round(5)

可以通过以下方式查看

dataset.head()

Table Visualizing Sales

接下来,我们将数据集分成 X 和 Y,并可视化这些值。

X = dataset.drop('sales', 1)
Y = dataset['sales']
X1 = X['brand']
X2 = X['d2c']
fig = plt.figure(dpi=80, figsize = (10, 4))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X1, X2, Y, c='r', label='real sales', s = 1)
ax.set_xlabel('Brand Marketing')
ax.set_ylabel('Direct to Consumer')
ax.set_zlabel('Sales')
plt.legend()
plt.savefig('images/data.jpg')

概念检查:用 Python 自己建立一个数据集: 用营销活动和销售之间的线性和自定义数学关系建立并可视化一个类似的数据集。

你能看到你在营销活动之间建立的互动吗?

试着在脚本的开始就参数化你的系统,以便于启用或禁用交互。

解决方案:

这是一个备选数据集,其特征略有不同。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
np.random.seed(0)
NUM_SAMPLES = int(2e3)
noise_ratio= 1e-2
brand_spend = np.random.rand(NUM_SAMPLES)
d2c_spend = np.random.rand(NUM_SAMPLES)
geo_mean_mult = 10
exp_brand_spend_mult = 1
contributions =  {'brand':.01, 'd2c':.02}brand_contributions = brand_spend * contributions['brand']
d2c_contributions = d2c_spend * contributions['d2c']
geo_contribution = np.sqrt(brand_spend* d2c_spend) * geo_mean_mult
exp_brand_contribution = np.exp(brand_spend) * exp_brand_spend_multsales = brand_contributions + d2c_contributions + exp_brand_spend_mult + np.random.rand(NUM_SAMPLES) * noise_ratio
dataset = pd.DataFrame({
    'brand': brand_spend,
    'd2c': d2c_spend,
    'sales': sales
}).round(5)
X = dataset.drop('sales', 1)
Y = dataset['sales']
X1 = X['brand']
X2 = X['d2c']
fig = plt.figure(dpi=80, figsize = (10, 4))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X1, X2, Y, c='r', label='real sales', s = 1)
ax.set_xlabel('Brand Marketing')
ax.set_ylabel('Direct to Consumer')
ax.set_zlabel('Sales')
plt.legend()
plt.savefig('demo.jpg')

方法概述

为了了解营销支出的影响,我们将从使用线性回归将营销支出映射到销售额开始。然后,我们将查看我们的损失曲线,并认识到线性回归的不足,鼓励我们执行特征工程。

在手动特征工程之后,为了帮助特征生成过程,我们使用神经网络的隐藏层来提取特征,并将其用于我们的最终回归问题。我们将比较和对比可解释性和性能。

建模线性回归

为了了解销售和营销支出之间的关系,我们首先拟合一个线性回归模型。

这是告诉模型填充以下公式中的空白:

销售= __ *品牌营销+ __ *直接面向消费者+ __

我们的线性回归通过学习参数来*似这条曲线:

销售额= 5.11 *品牌营销+ 3.28 *直接面向消费者-2.45

这是非常有见地的,因为我们可以直接读取每种支出的投资回报率,例如,我们可以将此解读为衡量品牌营销的投资回报率为 5,d2c 的投资回报率为 3。除了我们注意到一个问题!我们可以在下面直观地看到,该模型并没有准确地表示数据。模型学习到的预测显示在下面的蓝色中,显然不适合红色的销售:

Linear Regression estimates vs Sales

以下是一些用于训练线性回归模型和可视化预测的简单代码。

**from** **sklearn.neural_network** **import** MLPRegressor
**from** **sklearn.linear_model** **import** Ridge
**from** **mpl_toolkits.mplot3d** **import** Axes3D
**def** model_sales_regression(dataset, model='Ridge'):
    num_samples = dataset.shape[0]
    cutoff = (num_samples * 3) // 4
    Xtrn = dataset.drop('sales', 1).iloc[:cutoff,:]
    Ytrn = dataset['sales'].iloc[:cutoff]
    Xval = dataset.drop('sales', 1).iloc[cutoff:,:]
    Yval = dataset['sales'].iloc[cutoff:]
    model = Ridge().fit(Xtrn, Ytrn)
    coefs = model.coef_.round(2)
    yhat = model.predict(dataset.drop('sales', 1))
    yhatval = model.predict(Xval)
    loss = np.square(Yval - yhatval).mean()

    print('learned coefficients', list(zip(X.columns, coefs)))
    print('loss:', loss)
    print('intercept', model.intercept_.round(2))

    **return** model, yhat, coefs, loss**def** graph_real_and_predicted(dataset, yhat, fname=**None**):
    X = dataset.drop('sales', 1)
    Y = dataset['sales']
    X1 = X['brand']
    X2 = X['d2c']
    fig = plt.figure(dpi=80, figsize=(10, 4))
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(X1, X2, Y, c='r', label='real sales', s = 1)
    ax.scatter(X1, X2, yhat, c='b', label='estimated sales', s = 1)
    ax.set_xlabel('Brand Marketing')
    ax.set_ylabel('Direct to Consumer')
    ax.set_zlabel('Sales')
    plt.legend()
    **if** fname **is** **not** **None**:
        plt.savefig('images/' + fname + '.jpg')

这是训练线性回归的代码。

model, yhat, coefs, loss = model_sales_regression(dataset)
graph_real_and_predicted(dataset, yhat, 'linear')

误差量化

为了总结我们模型的准确性,我们来看看真实销售额和我们的预测之间的*方误差。我们用这些*方误差的*均值来表示我们的性能。

为什么是*方误差?

这是基于最小化最坏情况的常见默认选择。假设 1 的误差是可以接受的,如果我们经常在预测中误差 1,这并不完美,但我们可以处理它。但是如果我们有一次差了 3 分,那是不可接受的。我们从来不想偏离太多,但是我们可以接受经常偏离很少。误差*方会是 1 比 1 的*方,这没问题,它会是 3 比 9 的*方,这是一个更大的误差。

*方误差是一种常见的误差度量,因为它可以最小化最坏情况下的误差(或者让我们这样想,并在后面列出其他数学原因)。

概念检查:提出两个可供选择的有意义的误差度量。

如果在课堂上阅读,分组讨论。

一些解决方案:

1-*均绝对误差(我们预测的绝对误差的*均值)是有意义的,但是不会随着你犯大的误差而迅速增加。如果我们更关心百分比误差而不是实际误差,那么 2-*均绝对百分比误差(我们*均偏离的百分比)是有意义的。
mean(abs(Y-yhat)/Y)

为了确保我们计算出一个现实的性能衡量标准,我们在模型没有训练的数据点上衡量我们的损失。因此,我们从一些数据开始,用其中一些数据来拟合模型的参数,用其他数据点来测试我们的性能。这接*于衡量模型在未来对未知数据的表现。

使用线性回归,我们的均方误差为 0.89。这还没有意义,但与其他模型相比,以后会有意义。

但是,我们可以清楚地看到,我们的模型没有准确地捕捉销售趋势,因为我们看到了预测和真实销售之间的可预测差异区域。

特征工程

作为一个聪明的专业人士,我们得出结论,从花费的线性回归不能捕捉所有的数据结构。为了扩展我们的模型,我们注意到当两个输入都很大时,显著增加,所以我们可能需要一个特征来捕捉两种花费类型的组合。因此,我们产生了一个特征,即品牌营销的产品*直接面向消费者的营销支出。要让这个功能变大,需要品牌和 d2c 支出都很高。

查看我们的新功能

让我们快速检查一下这个新特性,brand * d2c。

当我们没有钱花的时候会发生什么?该值为 0。如果 brand 是 1,d2c 是 1 呢?值是 1 * 1 = 1。所以它衡量营销支出?

但是如果我们有 10 美元可以花,我们在 d2c 上花了 1 美元,在品牌上花了 9 美元呢?我们有 1 * 9 = 9。好吧,但是如果我们拿同样的一美元,把它分成两类消费,每类 5 美元。我们有 5 * 5 = 25!该特征检测“两种花费类型都有投资的*衡”。

现在,我们的模型学习使用函数更好地逼*曲线:

销售额= 0.68 *品牌— 1.01 * d2c + 8.74 品牌 d2c — 0.29

概念检查:特征工程

在运行线性回归和可视化预测之前,尝试在熊猫数据框架中构建特征品牌* d2c。在过去,这是一项非常有意义、深思熟虑的任务,是 ML 的一大部分。

解决方案:特征工程

以下解决方案:

dataset['brand * d2c'] = dataset['brand'] * dataset['d2c']
model, yhat, coefs, loss = model_sales_regression(dataset)
graph_real_and_predicted(dataset, yhat, 'feature_engineering')

Feature Engineering Approximation

这看起来不错。我们的预测现在更好地跟踪销售,但我们仍然不完美。我们的误差现在是 0.2,低于纯线性回归的 0.9。

看我们的参数,可以看到品牌和 d2c 营销的组合是最强的影响者,系数为 8.74。这只是真实销售额的*似值,但该参数可以这样解释:如果品牌支出为 0,那么增加 d2c 支出将无济于事,因为无论如何,品牌* d2c 都将为 0。

如果品牌为 0,那么从 d2c 到组合期限的投资回报率为 0。

但是,如果品牌支出为 1(千美元),那么随着我们增加 d2c 支出,我们每支出 1 美元将获得 8.74 美元的投资回报。

如果品牌为 1,那么从 d2c 到组合期限的投资回报率为 8.74。

这听起来不太合理,但作为一个*似值,它告诉我们,增加销售的最佳方式是在品牌和 d2c 营销之间取得*衡,因为组合是最大的因素。

此时,我们认识到我们仍然有 0.2 的显著损失,并且仍然有可预测误差的可见区域,并且认为我们仍然可以改进我们的模型。

用于特征提取的小型神经网络

为了添加更多生成的特征而不必定义它们应该是什么,我们考虑一个小型神经网络,它生成 6 个特征,然后使用这些特征来预测销售。

概念检查:编写一个 sklearn 神经网络代码

使用 sklearn.neural_network 中的 MLPRegressor 生成特征,并用 6 个隐藏单元对销售进行建模,然后显示模型学习到的特征。

解决方案:编写一个 sklearn 神经网络

下面是像以前一样分割数据集的代码,但是使用了神经网络。然后,它将系数组合在一起,以报告模型表示。

**def** model_sales_MLP(dataset, hidden, print_coefs = **True**, max_iter= 10000):
    num_samples = dataset.shape[0]
    cutoff = (num_samples * 3) // 4
    Xtrn = dataset.drop('sales', 1).iloc[:cutoff,:]
    Ytrn = dataset['sales'].iloc[:cutoff]
    Xval = dataset.drop('sales', 1).iloc[cutoff:,:]
    Yval = dataset['sales'].iloc[cutoff:]
    model = MLPRegressor(hidden, validation_fraction = 0, solver='lbfgs', max_iter= max_iter).fit(Xtrn, Ytrn)
    coefs = model.coefs_
    yhat = model.predict(X)
    yhatval = model.predict(Xval)
    loss = np.square(Yval - yhatval).mean()
    hiddens = coefs[0].T
    final_mlp = coefs[1].flatten()

    coefs = list(zip([dict(zip(X.columns, h)) **for** h **in** hiddens],
                     [['output mult:', m] **for** m **in**  final_mlp.flatten()], 
                     [['intercept:', i] **for** i **in**  model.intercepts_[0]]))
    print('loss:', loss)
    **if** print_coefs:
        **for** idx, c **in** enumerate(coefs):
            f1, o, i = c
            print('feature', idx, '=', f1['brand'].round(2), '* brand +', 
                  f1['d2c'].round(2), '* d2c', '+', i[1].round(2))
        output = 'yhat = '
        **for** fidx, v **in** enumerate(final_mlp):
            output = output + str(v.round(2)) + ' * feat ' + str(fidx) + ' + '
        output = output + str(model.intercepts_[1][0].round(2))
        print(output)
    **return** model, yhat, coefs, loss

我们从我们的数据集中创建模型并绘制它,用一个 6 个单元的隐藏层

model, yhat, coefs, loss = model_sales_MLP(dataset, [6])
graph_real_and_predicted(dataset, yhat, 'neural_network')

在训练好我们的神经网络之后,我们考察模型的特征:
特征 0 = 2.85 * brand + 1.83 * d2c -2.79
特征 1 = 1.62 * brand -2.15 * d2c -0.03
特征 2 = 0.08 * brand -0.54 * d2c -0.77
特征 3 = 0.55 * brand + 0.16 * d2c -0.81
特征 4 = 3.83 *

然后,在用于如下预测 yhat 之前,对特征进行剪裁以将任何负值设置为零:

如果特征[i]是正的:特征[i]=特征[I]

如果特征[i]为负:feat[i] = 0

Yhat = 3.0 *专长[0] -1.48 *专长[1] + 0.82 *专长[2] -0.2 *专长[3] + 1.6 *专长[4] -1.82 *专长[5]–0.56

哇有那么难解读吗!在后面的讲座中,我们将开始解释神经网络,但我们肯定不会试图去解读每一个单独的特征,那会太乏味了。

但是看看我们的损失,我们下降到 0.12 的损失!此外,我们的图表现在看起来与真实销售额非常接*。

Neural Network Approximation

深度神经网络

最后,让我们假设我们不是试图通过衡量投资回报率来为营销决策提供信息,而只是试图预测每日销售额。在我们的神经网络中,不是 6 个隐藏单元(6 个特征),而是使用 100 个隐藏单元,并使用该隐藏层来计算 100 个单元的新隐藏层,最终用于执行线性回归。

这进一步减少了我们的损失,现在我们几乎完全符合数据集,损失为 0.001。现在想想,这甚至不是训练数据。这不是模型与训练数据的吻合程度,而是模型与训练过程中从未见过的数据的吻合程度。

但是如果我们想解释这个模型呢?我们有一个 100 单位的隐藏层,然后又有一个 100 单位的隐藏层。因此,为了计算第二隐藏层,我们从第一隐藏层为第二隐藏层中的 100 个单元中的每一个计算 100 次乘法。那是它学过的一万次乘法!我们永远无法概念化这么多的相互作用,但我们认识到神经网络已经开发出这些特征来精确地拟合数据。

Deep network appears to fit dataset perfectly

包扎

让我们回顾一下。初始线性回归对数据集进行了建模,但它显然有不太适合的区域。我们执行了一些特征工程,因为我们从对问题的思考中猜出了一些有价值的特征。这帮助我们更好地拟合数据集,我们的模型更准确,但有点难以理解。

接下来,我们在网络中引入了一个隐藏层来学习我们的特征,我们提出了六个特征,以某种方式为我们解决了问题。这些变得更加难以解释,但我们知道这些特征在某种程度上比我们最初的两三个特征更好地理解了模型。

我们最后让一个深度神经网络来解决这个问题。我们观察到这个模型更加精确,但是解释成千上万的乘法运算是不可行的。

代码分析

下面我们将快速重新执行上面的所有分析,同时只报告代码和简要总结。首先,我们导入一些将在以后对我们有帮助的库

**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **matplotlib**
%matplotlib notebook
**import** **matplotlib.pyplot** **as** **plt**
**from** **sklearn.neural_network** **import** MLPRegressor
**from** **sklearn.linear_model** **import** Ridge
**from** **mpl_toolkits.mplot3d** **import** Axes3D

我们设置了一个随机种子,因此如果您在本地计算机上执行此操作,您将会看到与我们在这里看到的相同的随机结果。这对再现性很重要。

np.random.seed(0)

接下来,我们生成数据集

NUM_SAMPLES = int(2e3)brand_spend = np.random.rand(NUM_SAMPLES)
d2c_spend = np.random.rand(NUM_SAMPLES)
individual_contributions = brand_spend * .01 + d2c_spend * .02
collaboration = np.square(brand_spend) * d2c_spend * 10
sales = individual_contributions + collaboration + np.random.rand(NUM_SAMPLES)/10

最后,对于线性回归部分,我们有一个执行线性回归的函数和另一个绘制结果的函数:

**def** model_sales_regression(dataset, model='Ridge'):
    num_samples = dataset.shape[0]
    cutoff = (num_samples * 3) // 4
    Xtrn = dataset.drop('sales', 1).iloc[:cutoff,:]
    Ytrn = dataset['sales'].iloc[:cutoff]
    Xval = dataset.drop('sales', 1).iloc[cutoff:,:]
    Yval = dataset['sales'].iloc[cutoff:]
    model = Ridge().fit(Xtrn, Ytrn)
    coefs = model.coef_.round(2)
    yhat = model.predict(dataset.drop('sales', 1))
    yhatval = model.predict(Xval)
    loss = np.square(Yval - yhatval).mean()

    print('learned coefficients', list(zip(X.columns, coefs)))
    print('loss:', loss)
    print('intercept', model.intercept_.round(2))

    **return** model, yhat, coefs, loss**def** graph_real_and_predicted(dataset, yhat, fname=**None**):
    X = dataset.drop('sales', 1)
    Y = dataset['sales']
    X1 = X['brand']
    X2 = X['d2c']
    fig = plt.figure(dpi=80, figsize=(10, 4))
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(X1, X2, Y, c='r', label='real sales', s = 1)
    ax.scatter(X1, X2, yhat, c='b', label='estimated sales', s = 1)
    ax.set_xlabel('Brand Marketing')
    ax.set_ylabel('Direct to Consumer')
    ax.set_zlabel('Sales')
    plt.legend()
    **if** fname **is** **not** **None**:
        plt.savefig('images/' + fname + '.jpg')

这里,我们将数据集包装到一个数据帧中。这让我们可以像在 python 中查看 excel 表格一样查看数据集。

dataset = pd.DataFrame({
    'brand': brand_spend,
    'd2c': d2c_spend,
    'sales': sales
}).round(5)

可以通过以下方式查看

dataset.head()

Table Visualizing Sales

接下来,我们将数据集分成 X 和 Y,并可视化这些值。

X = dataset.drop('sales', 1)
Y = dataset['sales']
X1 = X['brand']
X2 = X['d2c']
fig = plt.figure(dpi=80, figsize = (10, 4))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X1, X2, Y, c='r', label='real sales', s = 1)
ax.set_xlabel('Brand Marketing')
ax.set_ylabel('Direct to Consumer')
ax.set_zlabel('Sales')
plt.legend()
plt.savefig('images/data.jpg')

这是训练线性回归的代码。

model, yhat, coefs, loss = model_sales_regression(dataset)
graph_real_and_predicted(dataset, yhat, 'linear')

接下来,我们添加一个要素,并从扩充的数据集执行线性回归。

dataset['brand * d2c'] = dataset['brand'] * dataset['d2c']
model, yhat, coefs, loss = model_sales_regression(dataset)
graph_real_and_predicted(dataset, yhat, 'feature_engineering')

转到神经网络,我们定义我们的多层感知器(神经网络的另一个术语)功能。

**def** model_sales_MLP(dataset, hidden, print_coefs = **True**, max_iter= 10000):
    num_samples = dataset.shape[0]
    cutoff = (num_samples * 3) // 4
    Xtrn = dataset.drop('sales', 1).iloc[:cutoff,:]
    Ytrn = dataset['sales'].iloc[:cutoff]
    Xval = dataset.drop('sales', 1).iloc[cutoff:,:]
    Yval = dataset['sales'].iloc[cutoff:]
    model = MLPRegressor(hidden, validation_fraction = 0, solver='lbfgs', max_iter= max_iter).fit(Xtrn, Ytrn)
    coefs = model.coefs_
    yhat = model.predict(X)
    yhatval = model.predict(Xval)
    loss = np.square(Yval - yhatval).mean()
    hiddens = coefs[0].T
    final_mlp = coefs[1].flatten()

    coefs = list(zip([dict(zip(X.columns, h)) **for** h **in** hiddens],
                     [['output mult:', m] **for** m **in**  final_mlp.flatten()], 
                     [['intercept:', i] **for** i **in**  model.intercepts_[0]]))
    print('loss:', loss)
    **if** print_coefs:
        **for** idx, c **in** enumerate(coefs):
            f1, o, i = c
            print('feature', idx, '=', f1['brand'].round(2), '* brand +', 
                  f1['d2c'].round(2), '* d2c', '+', i[1].round(2))
        output = 'yhat = '
        **for** fidx, v **in** enumerate(final_mlp):
            output = output + str(v.round(2)) + ' * feat ' + str(fidx) + ' + '
        output = output + str(model.intercepts_[1][0].round(2))
        print(output)
    **return** model, yhat, coefs, loss

我们对原始销售和支出数据使用我们的函数,没有增强功能。

dataset = pd.DataFrame({
    'brand': brand_spend,
    'd2c': d2c_spend,
    'sales': sales
}).round(5)model, yhat, coefs, loss = model_sales_MLP(dataset, [6])
graph_real_and_predicted(dataset, yhat, 'neural_network')

最后,我们再次调用函数,但是使用更深的神经网络。

model, yhat, coefs, loss = model_sales_MLP(dataset, [100, 100], max_iter = 1000, print_coefs=**False**)
graph_real_and_predicted(dataset, yhat, fname = **None**)

这是从市场归因和评估的实用角度对机器学习的介绍!

上面的代号是: 这里的

此问题展开: ML 前言。

本系列预期跟进:https://towards data science . com/ml-intro-3-logistic-output-units-EC 42 cc 576634

对于完全理解这一条的有意跟进帖子:https://medium . com/@ leetandata/machine-learning-engineering-1-custom-loss-function-for-house-sales-estimating-95 eec6b 12457

对于苦于代码或理解的人可选后续: 本帖代码详细分析:https://medium . com/@ leetandata/machine-learning-python-programming-introduction-for-business-people-10588 e 13 ce 9d

关于 Python 编程的免费综合课程。确保注册,但选择免费的可选项目。所有课堂内容免费提供:
https://www . coursera . org/learn/python-programming-introduction/

一个比这个更复杂的机器学习教程,但比下面的(不是我写的)更容易https://www . ka ggle . com/rochelle Silva/simple-tutorial-for-初学者

软件工程师可选后续岗位: 重数学、重 CS 的详解(上):https://medium . com/@ leetandata/neural-network-introduction-for-Software-Engineers-1611d 382 C6 aa

重数学、重 CS 的详解(下):https://medium . com/@ leetandata/neural-network-for-software-engineers-2-mini-batch-training-and-validation-46ee 0a 1269 a 0

Cho 教授可选数学笔记:
https://github . com/NYU-dl/Intro _ to _ ML _ Lecture _ Note/raw/master/Lecture _ Note . pdf

ML 技术公司帮助执法部门识别儿童性交易受害者和他们的位置,你可以提供帮助

原文:https://towardsdatascience.com/ml-tech-firms-help-law-enforcement-identify-child-sex-trafficking-victims-their-location-and-e47da9066180?source=collection_archive---------7-----------------------

2015 年,Thorn 首席执行官 Julie Cordua 接到了两位国土安全部官员的电话。他们需要帮助来开发一种技术解决方案,以找到一个小女孩,她的性虐待视频已被传播到全球各地。

国土安全部已经找了这个小女孩 8 个多月了,但毫无结果。国家失踪和被剥削儿童中心的数据库里没有她的照片。在她被虐待的视频被上传的两年多时间里,没有人认出她或者寻找她。

朱莉没有太多的答案。尽管如此,她的 Thorn 团队仍然致力于开发一种技术解决方案来寻找这个被虐待的孩子。令人沮丧的是,最终他们的努力没有产生任何结果。

经过五年的虐待,小女孩被找到了,但不是因为先进的技术。她是通过缩小两个虐待视频背景物品的销售和制造地点找到的。然后,根据附*销售地点的发票,官员们在社交媒体上搜索购买了其中一件物品的人的名字,并在她母亲的脸书页面上找到了这名受虐待儿童的照片。从那里,他们找到了她的地址,把她从她母亲的男朋友那里救了出来。

看起来,随着机器学习(ML)、人工智能(AI)、机器视觉、物联网(IoT)和面部识别的出现,新兴技术能力将使解决这一案件变得简单快捷。

儿童救助越来越多地发生在技术和法律的交汇处 尽管如此,还是有好消息:技术品牌正在与执法部门合作,并且他们一起在以创新的方式应用新兴技术方面变得越来越好,如机器学习驱动的认知自动化,以阻止儿童性贩运和儿童性虐待材料的传播。让我们看看科技品牌如何依靠 ML 驱动的技术来解决复杂的案件,以及仍然需要哪些能力。然后,我们将讨论您可以如何提供帮助。

图像匹配工具成为技术和执法合作的主流。 每分钟就有五百张遭受性虐待儿童的图片在网上交易。更糟糕的是,很难停下来。人贩子对照片进行的简单调整——即使是添加一个小标记或调整照片大小——也能创造出清晰的图像来追踪。因此,人贩子知道,微小的变化意味着跨*台跟踪虐待图像的分析师失去了他们的旅程和他们背后的人贩子的踪迹。

直到最*,手动图像分析和匹配工作是跟踪虐待儿童者和他们剥削的儿童的唯一方法。微软数字犯罪部门的高级律师考特尼·格雷瓜尔说:“在这个庞大的宇宙中找到这些已知的儿童性虐待图像就像是大海捞针一样。”。例如,在我们的开篇故事中,执法人员花了两年时间才确定这个孩子是受害者。

为了解决这个问题,微软的 PhotoDNA 成为了一个将修改过的图像与原始图像进行匹配的常用工具。该工具使用认知智能驱动的哈希匹配技术来划分图像,将它们哈希成灰色阴影方块,并对每个网格方块进行编号,从而创建图像 DNA。

然后将未改变的图像部分与国家失踪和被剥削儿童中心(NCMEC)数据库中的图像进行匹配,该工具识别图像变化。从那里,它确定他们在网上出现的位置,从而跟踪他们背后的人贩子的网上足迹。

为了向合格的组织授予免费访问权,微软将 PhotoDNA 上传到了云端。这意味着更多的组织可以参与进来,匹配和跟踪虐待图像,这样就没有孩子忍受虐待而没有人寻找她。

微软与 Thorn 合作以提高协作效率。微软和 Thorn(由阿什顿·库彻和黛米·摩尔创立)的合作伙伴关系已经成为打击儿童性贩子的强大力量。直到 2012 年,如果相同的儿童性虐待图像被上传到几个不同的*台,由于公司分别扫描他们的*台,每个图像都被散列并作为不同的图像报告给 NCMEC 几次。结果是:数据库中一片混乱。最终,受害者援助被推迟,因为冗余的散列必须被清除,这样救援工作才不会混乱和低效。

但是,情况变得更好了:Thorn 的行业哈希共享*台是第一个允许参与组织共同努力阻止儿童性交易的倡议。由于形成了一个集中且可访问的哈希共享数据库,公司可以通过 PhotoDNA Cloud 使用其他公司已经识别的哈希来扫描他们的图像共享*台。

通过这样做,他们可以找到以前确定的性虐待内容,从而帮助跟踪这些内容。但是,如果扫描的图像还没有被散列,PhotoDNA Cloud 会报告它们属于新的受害者。

结果:省时高效。对先前未报告的图像的即时识别会尽快提醒执法部门注意新的受害者。更快地发现受害者意味着,像我们开篇故事中的女孩这样的孩子,在开始寻找他们之前,可能需要忍受更少的虐待。

由于 Thorn-微软的合作伙伴关系、共享数据库和共享技术,在哈希共享计划的第一年,八个美国最受欢迎的照片共享*台加入了进来,包括脸书和谷歌,他们之间共享了 90,000 个哈希,以便更快地识别受害者。

但是,还有更多…

技术匹配图像背景,为执法部门定位受虐儿童。
在我们的开篇故事中,在确认孩子是受害者后,执法人员使用视频背景物品缩小了受虐儿童的位置。这是一个漫长而乏味的过程。一直以来,一个小女孩都生活在噩梦中。自那以后,科技公司正在开发解决方案,使图像背景与位置的匹配过程变得即时。

TrafficCam 是自动缩小实时结果范围的第一步。如果一个孩子在一个酒店房间里被虐待,然后这个图像被用于在线广告,警方可以依靠 ML 和用户生成的酒店内部数据库来匹配酒店房间和位置,而不是缩小图像背景物品的销售位置。

它是这样工作的:TraffickCam 要求消费者拍摄他们所住酒店房间内部的快照,然后上传到酒店图像数据库。到目前为止,已经有数百万张图片被上传,每一张新图片的上传都意味着又一个孩子可以被拯救。因为只有当孩子在酒店时,它才能识别孩子的位置,所以它并不完美。但是,这是一个有希望的开始。

未来的儿童识别技术带来了即时识别受害者和位置的希望。 一项新技术即将问世,它能使受害者身份识别和救援工作立竿见影。卡内基梅隆大学 Cylan 生物识别中心主任 Marios Savvidas 一直在努力开发虹膜扫描功能。

“现在执法部门只有失踪儿童的照片,但是外貌可以改变,”萨维达斯在接受福克斯新闻频道采访时说。虹膜扫描仪优于图像匹配,因为儿童的外貌会随着时间而改变,但他们的虹膜不会。“我们给了他们一种无法改变的生物特征,”他说。

通过这些扫描仪,只需要三秒钟就可以扫描孩子的脸,定位她的虹膜,并获得身份识别读数。Marios 解释说,虽然指纹需要孩子实际触摸一些东西,但扫描的虹膜更有用。它们仍然像指纹一样清晰,但可以在 40 码外被读取,即使孩子在车里。

这个想法是在机场和边境检查站安装虹膜扫描仪。但是,首先,这项技术需要数据来比较扫描。因此,在扫描仪被执法部门使用之前,父母必须扫描他们年幼孩子的虹膜。然后,如果他们被绑架,扫描仪会将他们的虹膜与原始图像进行匹配。

无论是组织的一部分还是作为消费者,你都可以加入战斗。 如今的受害者识别工具可能并不意味着儿童性交易的终结,但它们无疑有助于解救更多的儿童。此外,认知智能意味着他们围绕图像等非结构化元素的表现将随着更多数据而继续提高。

这就是你进来的地方。无论你是一个组织还是个人,你都可以帮助建立智能技术数据库,以提高它们的匹配能力。

如果你代表一个有照片分享*台的机构,联系 NCMEC 参与行业哈希分享*台。此外,如果你需要技术实施方面的帮助,请通过programs@wearethorn.org联系索恩。

如果你是消费者,下载 TraffickCam 应用程序。那么,下次你旅行的时候,一定要拍下你租的任何一家旅馆或汽车旅馆房间的内部照片。然后,只需将它们上传到应用程序。从那里,执法部门可以使用它们来匹配在酒店房间里被虐待的儿童的图像,以确定他们的位置。

最后,将以下文本复制、粘贴并分享到您的社交媒体页面:

233733 (BEFREE):为人口贩运的受害者和幸存者提供帮助或联系当地服务机构。

你的参与可以拯救一个孩子的生命。

m 文学:回归评估(R *方)

原文:https://towardsdatascience.com/mliterature-regression-evaluations-r-squared-ffa48717c56d?source=collection_archive---------4-----------------------

警告:正如在之前的帖子中提到的,标题也很清楚,这个系列只是为了给你一个主题的直觉,让你开始。我将很快添加数学和代码帖子!

当你说“我认为这是最佳解决方案”时,你的经理会有什么反应

所以,当你说一个模型是最优的或者几乎接*最优时,你应该能够评估它并给出一些证明。

一条线性回归拟合线,看起来像下图所示!

给一条直线,“回归线更符合趋势”。我的意思是,在上面的图像中,这条线(通过最大点)几乎完美地捕捉到了人口随时间推移而增长的趋势。

如何做到这一点不是我想在这篇文章中回答的问题。我们要揭开的是为什么一条给定的线比其他可能的线更好。

因此,可以在二维空间中画出无限多条线,如下图所示,但我们想找出为什么一条给定的线最适合显示趋势。

We are not pretty sure which one is correct!

那么,我们如何衡量哪一个更能代表我们的数据呢?

让我们试着理解使用飞镖游戏。

假设给你下图,描绘了一个“绿色”球员和一个“红色”球员拍摄的照片,问题是谁是赢家?

答案似乎很简单。玩家“绿”赢了!

如果我们再深入一点,你实际上做的是找到飞镖与圆心接触点的距离。关键是,你对所有的点都这样做了,然后取*均值。最后你证明了,绿色飞镖的最终*均距离小于红色,因此绿色是赢家!

你在不到一秒的时间内完成了这一切,甚至不知道你做了什么!很酷吧!

记住上面的原则,让我们借助一个图转移到我们想要解决的回归问题!

现在是重新确定我们目标的时候了。

目的:评估所选回归线是否最优。

指标:这是我们用来决定一条线是否最好的标准。(记住,在飞镖的情况下,我们计算每个飞镖离中心的距离并取*均值)

程序:对于回归线,我们不能执行与镖靶相同的程序。不用担心太多的数学证明,让我们理所当然地认为,我们需要一个回归线的图像,我们将使用它作为参考来评估我们的回归线。

上面这条线是用人口的*均值画出来的。

要评估的公式,

R = 1 -(最佳拟合线距离值/*均拟合线距离值)

请记住,在飞镖游戏中,我们试图尽可能地缩短距离,也就是说,离中心的距离越小,结果越好(赢家)。

类似地,这里我们试图最小化" R "也读作 R 的*方,这样我们可以说,这条线是最佳拟合线。

因此,总结这篇文章 w.r.t 到回归线,如果你看上面的公式,我们可以说,‘距离 _ 值 _ 最佳 _ 拟合 _ 线’的值越小,R 的值越接* 1,拟合越好

重要提示:我在上面提到过,我们通过对距离求和并取*均值来找到“最佳拟合线的值”。事实证明,这不是最好的方法,另一个版本称为 SSE(误差*方和是首选)。

这就是这篇文章的内容。我们将在后面的文章中继续数学部分,我们将通过一个例子来看看所有这些是如何工作的。

机器学习快乐!

参考

[## *方和:残差和、总和、解释和

统计定义>残差*方和,总计和解释残差*方和是用来帮助你…

www.statisticshowto.com](http://www.statisticshowto.com/residual-sum-squares/) [## 决定系数-维基百科

R 2 有几种定义,只是有时等价。一类这样的情况包括…

en.wikipedia.org](https://en.wikipedia.org/wiki/Coefficient_of_determination) [## 剩余*方和-维基百科

在统计学中,残差*方和(RSS),也称为残差*方和(SSR)或残差*方和。

en.wikipedia.org](https://en.wikipedia.org/wiki/Residual_sum_of_squares) [## 为什么我们在计算方差和标准时用*方而不用绝对值…

答案(第 1 题,共 20 题):你已经得到了技术性的答案。在迈克尔·霍克斯特的要点中,有一个关键点是最后一点。所以…

www.quora.com](https://www.quora.com/Why-do-we-square-instead-of-using-the-absolute-value-when-calculating-variance-and-standard-deviation) [## 如何计算误差*方和(SSE)

误差*方和(SSE)是一个初步的统计计算,可以得出其他数据值。当你…

www.wikihow.com](http://www.wikihow.com/Calculate-the-Sum-of-Squares-for-Error-(SSE))

数字识别

原文:https://towardsdatascience.com/mnist-with-k-nearest-neighbors-8f6e7003fab7?source=collection_archive---------0-----------------------

介绍

就像在传统编程中,我们首先学习打印"Hello, world!",类似地,在机器学习中,我们首先理解识别手写数字图像的解决方案。此类任务的著名数据集是 MNIST (简称“修改后的国家标准与技术研究院数据库”)。

在这篇文章中,我将使用一个最简单的机器学习算法来解决这个著名的识别手写数字的问题。

MNIST 数据集

MNIST 由 6 万张手写数字图像组成,包括从 0 到 9 的所有数字。每个图像都有其对应的标签号,代表图像中的编号。例如,下图中第一个图像的标签为 5,第二个图像的标签为 4,依此类推。该数据集通常分为三个子集:40,000 个用于训练,10,000 个用于验证,另外 10,000 个用于测试。在本文中,我们将只关注培训和测试。

在 MNIST,每幅图像都包含一个手绘的灰度数字。每个图像都是一个 784 维的浮点数向量(高度和宽度都是 28 个像素),其中每个值代表一个像素的亮度。

那么,KNN 是什么?

k *邻是一种分类算法。它将新数据点(测试数据)分类到某个类别中。为此,它主要查看新数据点与训练集中所有其他数据点的距离。然后,在 k 个最接*的训练数据点中,大多数类被分配给该新的测试数据点。

距离度量的选择取决于为分类任务选择的问题。因为,举例来说,两个程序员的技能之间的距离(比赛中的分数)将不同于两个风筝在空中飞行的距离(3D 空间中的欧几里德距离),等等。我们选择使用由以下公式给出的图像之间的欧几里德距离。

Euclidean distance between two n-dimensional points p and q. Source

这个等式描述了两个 n 维点 p 和 q 之间的欧几里德距离。在我们的例子中,n = 784,因为 MNIST 的每个图像是 784 维的。

这就是关于 k 个最*邻居的全部内容!算法非常简单。现在让我们开始编程

寻找距离

两幅图像之间的距离可以用许多不同的方法计算。但是这里我用了欧几里德距离。其计算方法(此处为图像)是对两幅图像的相应像素之间的 L2 范数求和。

Euclidean Distance

相应像素距离的*方也消除了负距离。另一种方法是找到相应欧几里得距离的绝对值。

多数表决

找到距离并排序后(我们稍后将对其进行排序),是时候在最*的 k 训练点中找到多数类来测试数据点。这里,我们采用最接*的训练点的标签/类别,并找到出现最多的一个,并将其分配给新的测试数据点。这就是分类是如何发生的。

下面的代码描述了多数算法。

Voting for majority

分类手写数字

我们有了对手写数字进行分类所需的一切。我们剩下要做的就是我们在这里的真正目的。

下面的分类代码描述了它自己。

Classifying handwritten digits

我运行我的代码对前 2500 张测试图像进行分类,并获得了 95.32% 的分类准确率,对于这样一个简单的机器学习模型来说,这真的不算太差。可以通过使用分类过程的所有测试图像来检查完整的准确性,但这将花费很长时间(甚至可能一天)。

结论

所以, k *邻是一种简单的分类任务算法。我们用它来对手写数字进行分类,取得了 95.32%T8w 的准确率,对于这样一个简单的分类算法来说已经很不错了。

移动广告点击率预测

原文:https://towardsdatascience.com/mobile-ads-click-through-rate-ctr-prediction-44fdac40c6ff?source=collection_archive---------2-----------------------

Photo credit: Pixabay

在线广告,Google PPC,AdWords 活动,移动广告

在互联网营销中,点击率(CTR)是一种衡量广告客户在每一次展示中获得的点击量的指标。

移动已经与所有渠道无缝连接,移动是推动所有商业的驱动力。预计今年移动广告收入将达到 10.8 亿美元,比去年增长 122%。

在这项研究分析中,Criteo Labs 分享了 10 天的 Avazu 数据,供我们开发预测广告点击率(CTR)的模型。给定用户和他(或她)正在访问的页面。他(或她)点击给定广告的概率是多少?此分析的目标是为 CTR 估计的最精确 ML 算法设定基准。我们开始吧!

数据

数据集可以在这里找到。

数据字段

  • id:广告标识符
  • 单击:0/1 表示非单击/单击
  • 小时:格式为 YYMMDDHH,因此 14091123 表示 UTC 2014 年 9 月 11 日 23:00。
  • C1——匿名分类变量
  • 横幅 _ 位置
  • 站点 id
  • 站点 _ 域
  • 站点 _ 类别
  • app_id
  • app_domain
  • app _ 类别
  • 设备 id
  • 设备 _ip
  • 设备型号
  • 设备类型
  • 设备连接类型
  • C14-C21-匿名分类变量

EDA 和特征工程

训练集包含超过 4000 万条记录,为了能够在本地处理,我们将随机抽取其中的 100 万条。

import numpy as n
import random
import pandas as pd
import gzipn = 40428967  #total number of records in the clickstream data 
sample_size = 1000000
skip_values = sorted(random.sample(range(1,n), n-sample_size))parse_date = lambda val : pd.datetime.strptime(val, '%y%m%d%H')with gzip.open('train.gz') as f:
    train = pd.read_csv(f, parse_dates = ['hour'], date_parser = parse_date, dtype=types_train, skiprows = skip_values)

Figure 1

由于匿名化,我们不知道每个特性中的每个值意味着什么。此外,大多数特征是分类的,并且大多数分类特征具有很多值。这使得 EDA 不太直观更容易混淆,但我们会尽力而为。

特性

我们可以将数据中的所有特征分为以下几类:

  • 目标特征:单击
  • 站点特征:站点 id,站点域,站点类别
  • 应用功能:应用 id、应用域、应用类别
  • 设备特征:设备标识、设备 ip、设备型号、设备类型、设备连接类型
  • 匿名分类特征:C14-C21
import seaborn as sns
import matplotlib.pyplot as pltsns.countplot(x='click',data=train, palette='hls')
plt.show();

Figure 2

train['click'].value_counts()/len(train)

Figure 3

整体点击率约为。17%,而大约。83%没有被点击。

train.hour.describe()

Figure 4

该数据涵盖了从 2014 年 10 月 21 日到 2014 年 10 月 30 日的 10 天点击流数据,即 240 个小时。

train.groupby('hour').agg({'click':'sum'}).plot(figsize=(12,6))
plt.ylabel('Number of clicks')
plt.title('Number of clicks by hour');

Figure 5

每小时的点击模式每天看起来都很相似。然而,有几个高峰时间,一个是在 10 月 22 日中午,另一个是在 10 月 28 日中午。10 月 24 日午夜时分,点击量非常低。

日期时间特征的特征工程

小时

从日期时间特征中提取小时。

train['hour_of_day'] = train.hour.apply(lambda x: x.hour)
train.groupby('hour_of_day').agg({'click':'sum'}).plot(figsize=(12,6))
plt.ylabel('Number of clicks')
plt.title('click trends by hour of day');

Figure 6

一般来说,点击数最高的是 13 和 14 小时(下午 1 点和 2 点),点击数最低的是 0 小时(午夜)。对于粗略估计,这似乎是一个有用的特性。

让我们考虑一下印象。

train.groupby(['hour_of_day', 'click']).size().unstack().plot(kind='bar', title="Hour of Day", figsize=(12,6))
plt.ylabel('count')
plt.title('Hourly impressions vs. clicks');

Figure 7

这里没有什么令人震惊的。

既然我们已经看了点击和印象。我们可以计算点击率(CTR)。CTR 是广告点击与印象的比率。它衡量每个广告的点击率。

每小时一次

import seaborn as snsdf_click = train[train['click'] == 1]
df_hour = train[['hour_of_day','click']].groupby(['hour_of_day']).count().reset_index()
df_hour = df_hour.rename(columns={'click': 'impressions'})
df_hour['clicks'] = df_click[['hour_of_day','click']].groupby(['hour_of_day']).count().reset_index()['click']
df_hour['CTR'] = df_hour['clicks']/df_hour['impressions']*100plt.figure(figsize=(12,6))
sns.barplot(y='CTR', x='hour_of_day', data=df_hour)
plt.title('Hourly CTR');

Figure 8

这里一个有趣的观察是最高的点击率发生在午夜,1,7 和 15。如果你记得的话,午夜前后的浏览量和点击量最少。

星期几

train['day_of_week'] = train['hour'].apply(lambda val: val.weekday_name)
cats = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
train.groupby('day_of_week').agg({'click':'sum'}).reindex(cats).plot(figsize=(12,6))
ticks = list(range(0, 7, 1)) # points on the x axis where you want the label to appear
labels = "Mon Tues Weds Thurs Fri Sat Sun".split()
plt.xticks(ticks, labels)
plt.title('click trends by day of week');

Figure 9

train.groupby(['day_of_week','click']).size().unstack().reindex(cats).plot(kind='bar', title="Day of the Week", figsize=(12,6))
ticks = list(range(0, 7, 1)) # points on the x axis where you want the label to appear
labels = "Mon Tues Weds Thurs Fri Sat Sun".split()
plt.xticks(ticks, labels)
plt.title('Impressions vs. clicks by day of week');

Figure 10

周二的浏览量和点击数最多,周三次之,周四次之。周一和周五的浏览量和点击量最少。

星期几中心

df_click = train[train['click'] == 1]
df_dayofweek = train[['day_of_week','click']].groupby(['day_of_week']).count().reset_index()
df_dayofweek = df_dayofweek.rename(columns={'click': 'impressions'})
df_dayofweek['clicks'] = df_click[['day_of_week','click']].groupby(['day_of_week']).count().reset_index()['click']
df_dayofweek['CTR'] = df_dayofweek['clicks']/df_dayofweek['impressions']*100plt.figure(figsize=(12,6))
sns.barplot(y='CTR', x='day_of_week', data=df_dayofweek, order=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'])
plt.title('Day of week CTR');

Figure 11

虽然周二和周三的点击数和点击数最高,但它们的点击率却是最低的。周六和周日享受最高的 CTR。显然,人们在周末有更多的时间点击。

C1 专题

C1 是匿名分类特征之一。虽然我们不知道它的意义,但我们还是想看看它的分布。

print(train.C1.value_counts()/len(train))

Figure 12

C1 值= 1005 拥有最多的数据,几乎是我们正在使用的所有数据的 92%。让我们看看 C1 的值是否能说明一些关于 CTR 的东西。

C1_values = train.C1.unique()
C1_values.sort()
ctr_avg_list=[]
for i in C1_values:
    ctr_avg=train.loc[np.where((train.C1 == i))].click.mean()
    ctr_avg_list.append(ctr_avg)
    print("for C1 value: {},  click through rate: {}".format(i,ctr_avg))

Figure 13

train.groupby(['C1', 'click']).size().unstack().plot(kind='bar', figsize=(12,6), title='C1 histogram');

Figure 14

df_c1 = train[['C1','click']].groupby(['C1']).count().reset_index()
df_c1 = df_c1.rename(columns={'click': 'impressions'})
df_c1['clicks'] = df_click[['C1','click']].groupby(['C1']).count().reset_index()['click']
df_c1['CTR'] = df_c1['clicks']/df_c1['impressions']*100plt.figure(figsize=(12,6))
sns.barplot(y='CTR', x='C1', data=df_c1)
plt.title('CTR by C1');

Figure 15

重要的 C1 值和 CTR 对有:

C1=1005: 92%的数据和 0.17%的点击率

C1=1002: 5.5%的数据和 0.21%的点击率

C1=1010:数据的 2.2%和 0.095 的点击率

C1 = 1002 比*均 CTR 高得多,C1=1010 比*均 CTR 低得多,这两个 C1 值似乎对预测 CTR 很重要。

横幅位置

听说影响你横幅广告效果的因素有很多,但最有影响的还是横幅位置。让我们看看这是不是真的。

print(train.banner_pos.value_counts()/len(train))

Figure 16

banner_pos = train.banner_pos.unique()
banner_pos.sort()
ctr_avg_list=[]
for i in banner_pos:
    ctr_avg=train.loc[np.where((train.banner_pos == i))].click.mean()
    ctr_avg_list.append(ctr_avg)
    print("for banner position: {},  click through rate: {}".format(i,ctr_avg))

Figure 17

重要的横幅位置有:

位置 0:数据的 72%和 0.16 CTR

位置 1: 28%的数据和 0.18%的 CTR

train.groupby(['banner_pos', 'click']).size().unstack().plot(kind='bar', figsize=(12,6), title='banner position histogram');

Figure 18

df_banner = train[['banner_pos','click']].groupby(['banner_pos']).count().reset_index()
df_banner = df_banner.rename(columns={'click': 'impressions'})
df_banner['clicks'] = df_click[['banner_pos','click']].groupby(['banner_pos']).count().reset_index()['click']
df_banner['CTR'] = df_banner['clicks']/df_banner['impressions']*100
sort_banners = df_banner.sort_values(by='CTR',ascending=False)['banner_pos'].tolist()
plt.figure(figsize=(12,6))
sns.barplot(y='CTR', x='banner_pos', data=df_banner, order=sort_banners)
plt.title('CTR by banner position');

Figure 19

虽然横幅位置 0 具有最高的印象和点击量,但横幅位置 7 享有最高的点击率。增加横幅位置 7 的广告数量似乎是一个好主意。

设备类型

print('The impressions by device types')
print((train.device_type.value_counts()/len(train)))

Figure 20

train[['device_type','click']].groupby(['device_type','click']).size().unstack().plot(kind='bar', title='device types');

Figure 21

设备类型 1 获得最多的展示和点击,其他设备类型仅获得最少的展示和点击。我们可能想要查看关于设备类型 1 的更多细节。

df_click[df_click['device_type']==1].groupby(['hour_of_day', 'click']).size().unstack().plot(kind='bar', title="Clicks from device type 1 by hour of day", figsize=(12,6));

Figure 22

正如所料,大多数点击发生在营业时间,来自设备类型 1。

device_type_click = df_click.groupby('device_type').agg({'click':'sum'}).reset_index()
device_type_impression = train.groupby('device_type').agg({'click':'count'}).reset_index().rename(columns={'click': 'impressions'})
merged_device_type = pd.merge(left = device_type_click , right = device_type_impression, how = 'inner', on = 'device_type')
merged_device_type['CTR'] = merged_device_type['click'] / merged_device_type['impressions']*100merged_device_type

Figure 23

最高的 CTR 来自设备类型 0。

用同样的方法,我探索了所有其他分类功能,如网站功能,应用程序功能和 C14 C21 功能。探索的方式大同小异,详细内容可以在 Github 上找到,在此不再赘述。

建筑模型

哈希简介

一个散列函数是一个将一组对象映射到一组整数的函数。当使用散列函数时,这种映射将任意长度的键作为输入,并输出特定范围内的整数。

我们的精简数据集仍然包含 100 万个样本和~2M 特征值。哈希的目的是最小化功能的内存消耗。

如果你想了解更多,这里有一篇由卢卡斯·伯纳蒂撰写的关于杂凑技巧的优秀文章。

Python 有一个内置函数,它执行一个名为hash()的散列。对于我们数据中的对象,散列并不奇怪。

def convert_obj_to_int(self):

    object_list_columns = self.columns
    object_list_dtypes = self.dtypes
    new_col_suffix = '_int'
    for index in range(0,len(object_list_columns)):
        if object_list_dtypes[index] == object :
            self[object_list_columns[index]+new_col_suffix] = self[object_list_columns[index]].map( lambda  x: hash(x))
            self.drop([object_list_columns[index]],inplace=True,axis=1)
    return self
train = convert_obj_to_int(train)

LightGBM 模型

lightGBM_CTR.py

训练后的最终输出:

Figure 24

Xgboost 模型

Xgboost_CTR.py

它将训练到 eval-logloss 在 20 轮中没有改善。最后的输出是:

Figure 25

Jupyter 笔记本可以在 Github 上找到。周末愉快!

MobileNetV2:反向残差和线性瓶颈

原文:https://towardsdatascience.com/mobilenetv2-inverted-residuals-and-linear-bottlenecks-8a4362f4ffd5?source=collection_archive---------0-----------------------

2017 年 4 月,谷歌的一组研究人员发表了一篇论文,介绍了一种针对移动设备优化的神经网络架构。他们努力寻求一种模型,在保持参数和数学运算尽可能低的同时提供高精度。为了给智能手机带来深度神经网络,这是非常必要的。

被称为 MobileNet 的架构围绕着使用深度方向可分离卷积的思想,它由一个深度方向卷积和一个点方向卷积组成。如果你对这个操作的细节有点模糊,请随意查看我的另一篇文章,它详细解释了这个概念。 MobileNetV2 用两个主要想法扩展了它的前身。

反向残差

残余块用跳过连接来连接卷积块的开始和结束。通过添加这两种状态,网络有机会访问在卷积块中未被修改的早期激活。事实证明,这种方法对于构建深度网络至关重要。

A residual block connects wide layers with a skip connection while layers in between are narrow

当稍微靠*观察跳过连接时,我们注意到原始残差块遵循关于通道数量的宽- >窄- >宽方法。输入具有大量通道,这些通道通过廉价的 1x1 卷积进行压缩。这样,下面的 3×3 卷积的参数就少得多。为了最终增加输入和输出,使用另一个 1x1 卷积再次增加通道的数量。在喀拉斯,它看起来像这样:

def residual_block(x, squeeze=16, expand=64):
  m = Conv2D(squeeze, (1,1), activation='relu')(x)
  m = Conv2D(squeeze, (3,3), activation='relu')(m)
  m = Conv2D(expand, (1,1), activation='relu')(m)
  return Add()([m, x])

另一方面,MobileNetV2 遵循窄->宽->窄的方法。第一步使用 1×1 卷积来加宽网络,因为接下来的 3×3 深度方向卷积已经大大减少了参数的数量。之后,另一个 1x1 卷积挤压网络,以便匹配初始的信道数量。

An inverted residual block connects narrow layers with a skip connection while layers in between are wide

在喀拉斯,它看起来像这样:

def inverted_residual_block(x, expand=64, squeeze=16):
  m = Conv2D(expand, (1,1), activation='relu')(x)
  m = DepthwiseConv2D((3,3), activation='relu')(m)
  m = Conv2D(squeeze, (1,1), activation='relu')(m)
  return Add()([m, x])

作者将这种想法描述为反向剩余块,因为在网络的狭窄部分之间存在跳跃连接,这与原始剩余连接的工作方式相反。当您运行上面的两个代码片段时,您会注意到反向块的参数要少得多。

线性瓶颈

我们在神经网络中使用非线性激活函数的原因是多个矩阵乘法不能简化为单个数值运算。它允许我们建立多层神经网络。同时,通常在神经网络中使用的激活函数 ReLU 丢弃小于 0 的值。这种信息丢失可以通过增加信道数量来解决,以便增加网络的容量。

对于反向残差块,我们做相反的事情,并挤压跳跃连接所链接的层。这损害了网络的性能。作者引入了线性瓶颈的概念,其中剩余块的最后卷积在被添加到初始激活之前具有线性输出。将它写入代码非常简单,因为我们只需丢弃卷积模块的最后一个激活函数:

def inverted_linear_residual_block(x, expand=64, squeeze=16):
  m = Conv2D(expand, (1,1), activation='relu')(x)
  m = DepthwiseConv2D((3,3),  activation='relu')(m)
  m = Conv2D(squeeze, (1,1))(m)
  return Add()([m, x])

ReLU6

上面的片段显示了一个卷积块的结构,它包含了反向残差和线性瓶颈。如果您想尽可能地匹配 MobileNetV2,您还需要另外两个部分。第一个方面只是在每个卷积层后面增加了批量归一化,这是你现在可能已经习惯的。

第二个附加项不太常见。作者使用 ReLU6 而不是 ReLU,这将激活值限制在最大值…嗯…6。只要在 0 到 6 之间,激活就是线性的。

def relu(x):
  return max(0, x)def relu6(x):
  return min(max(0, x), 6)

这在你处理定点推理时很有帮助。它将小数点左边的信息限制为 3 位,这意味着我们可以保证小数点右边的精度。这也在最初的 MobileNet 论文中使用。最后一个构建块看起来像这样:

def bottleneck_block(x, expand=64, squeeze=16):
  m = Conv2D(expand, (1,1))(x)
  m = BatchNormalization()(m)
  m = Activation('relu6')(m)
  m = DepthwiseConv2D((3,3))(m)
  m = BatchNormalization()(m)
  m = Activation('relu6')(m)
  m = Conv2D(squeeze, (1,1))(m)
  m = BatchNormalization()(m)
  return Add()([m, x])

建筑

The MobileNetV2 architecture

现在我们已经了解了 MobileNetV2 的构建块,我们可以看一下整个架构。在表格中,您可以看到瓶颈块是如何排列的。 t 代表通道的膨胀率。如您所见,他们使用了系数 6,而不是我们示例中的系数 4。 c 表示输入通道的数量, n 表示该块重复的频率。最后, s 告诉我们块的第一次重复是否为下采样过程使用了步幅 2。总而言之,这是一个非常简单和常见的卷积块集合。

Performance of MobileNetV2 and other architectures on ImageNet

总结想法

我特别高兴的是 MobileNetV2 提供了与 NASNet 类似的参数效率。NASNet 是几项图像识别任务的最新技术。它的构建模块相当复杂,这使得它为什么工作得这么好变得相当不直观。NASNet 的构建模块不是由人类设计的,而是由另一个神经网络设计的。引入一个简单的架构,比如 MobileNetV2,它表现出了相当的效率,这让我更加相信下一个大的架构可能也是由人类设计的。

使用 Mockito 模仿同一个测试类中的方法

原文:https://towardsdatascience.com/mocking-a-method-in-the-same-test-class-using-mockito-b8f997916109?source=collection_archive---------0-----------------------

在测试驱动开发(TDD)中,单元测试是隐含实现质量的子部分。在使用 junit 进行单元测试时,您会遇到想要模拟类的地方。当您调用具有外部通信(如数据库调用或 rest 调用)的类的方法时,就完成了模仿。通过模仿,您可以显式地定义方法的返回值,而无需实际执行方法的步骤。在这篇文章中,我将讨论在你编写测试用例的同一个测试类中模仿方法。

假设您有一个 Person 类,它有外部通信并相应地返回值。

 public class Person {

  private String name;
  private int age; public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  public boolean runInGround(String location) {
    if(location.equals("ground")) {
      System.*out*.println("The person runs in the " + location);
      return true;
    } else {
      System.*out*.println("The person doesn't run in the " +   location);
      return false;
    }

  }

  public boolean isPlay() {

    if(this.runInGround("ground")) {
      System.*out*.println("The person plays.");
      return true;
    }
    else {
      System.*out*.println("The person doesn't play");
      return false;
    }
  }
}

出于解释的目的,让我们假设 runInGround(字符串位置)方法通过检查数据库值来返回值,这是一个外部通信。这个特殊的方法是在同一个 Person 类的 isPlay()方法中调用的,它影响 isPlay()方法的返回值。

那么如何在不让 runInGround(字符串位置)执行并与数据库对话的情况下测试 isPlay()。

我们可以模仿 PersonTest 类中的 runInGround(字符串位置)方法,如下所示。

 import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;

public class PersonTest{

  @Test
  public void playTest() {
    Person person = new Person("name", 15, "23435678V");

    Person person1 = Mockito.*spy*(person);

    Mockito.*doReturn*(true).when(person1).runInGround("ground");

    Assert.*assertEquals*(true, person1.isPlay());
  }
}

这里我们需要使用 Mockito.spy()来模拟我们正在测试的同一个类,而不是使用 mock(class)。然后我们可以如下模拟我们想要的方法。

Mockito.*doReturn*(true).when(person1).runInGround("ground");

希望这将有所帮助。用单元测试快乐编码:d。

延伸阅读

[1]http://www.vogella.com/tutorials/Mockito/article.html

https://dzone.com/articles/introduction-to-java-tdd

模态测试和核密度估计

原文:https://towardsdatascience.com/modality-tests-and-kernel-density-estimations-3f349bb9e595?source=collection_archive---------6-----------------------

python 中的多模态测试

当处理大量可能具有不同数据分布的数据集时,我们面临以下考虑因素:

  • 数据分布是单峰的吗?如果是,哪种模型最接*它(均匀分布、T 分布、卡方分布、柯西分布等)?
  • 如果数据分布是多模态的,我们能否自动识别模态的数量并提供更细粒度的描述性统计?
  • 如何估计一个新数据集的概率密度函数?

本笔记本处理以下主题:

  • 直方图与概率密度函数*似
  • 核密度估计
  • 最佳带宽的选择:Silverman/ Scott/ Grid 搜索交叉验证
  • 单峰分布的统计检验
  • 单峰性倾斜试验
  • 基于核密度估计的数据分布模式数识别

直方图和 pdf

正如这篇博文中所解释的,https://mgl Lerner . github . io/posts/histograms-and-kernel-density-estimation-kde-2 . html直方图的缺点是在不合适大小的容器中隐藏了实际数据分布的一些细节。

def plotHistogramAndPdf(data, x, pdf):
    ax = plt.gca()
    plt.hist(data, bins = 4, alpha = 0.4, label = 'histogram of input values');
    plt.ylabel('Frequency')
    plt.xlabel('x values')
    ax2 = ax.twinx()
    plt.plot(x, pdf, c = 'red', label = 'probability density function');
    plt.ylabel('PDF')
    [tl.set_color('r') for tl in ax2.get_yticklabels()]
    ax.legend(bbox_to_anchor=(0.4, 1.15))
    ax2.legend(bbox_to_anchor=(1.15,1.15))
    plt.savefig('figures/hist.jpg', bbox_inches='tight')

plotHistogramAndPdf(data, x, true_pdf)

核密度估计

核密度估计依赖于任意带宽,该带宽决定了返回的*似的*滑程度。以下示例说明了各种带宽值的影响:

def getKernelDensityEstimation(values, x, bandwidth = 0.2, kernel = 'gaussian'):
    model = KernelDensity(kernel = kernel, bandwidth=bandwidth)
    model.fit(values[:, np.newaxis])
    log_density = model.score_samples(x[:, np.newaxis])
    return np.exp(log_density)for bandwidth in np.linspace(0.2, 3, 3):
    kde = getKernelDensityEstimation(data, x, bandwidth=bandwidth)
    plt.plot(x, kde, alpha = 0.8, label = f'bandwidth = {round(bandwidth, 2)}')
plt.plot(x, true_pdf, label = 'True PDF')
plt.legend()
plt.title('Effect of various bandwidth values \nThe larger the bandwidth, the smoother the approximation becomes');
plt.savefig('figures/bw.jpg', bbox_inches='tight')

核密度估计最佳带宽的选择方法

为了确定最佳带宽,有几种方法:

  • Silverman 的经验法则:假设未知密度为高斯分布。它不是最佳带宽选择器,但可以用作非常快速、相当好的估计器,或者用作多级带宽选择器中的第一估计器。更精确的求解方程插件规则使用积分*方密度导数泛函的估计来估计最佳带宽。它们需要大量计算来使用迭代方法求解非线性方程。他们用腐烂作为第一估计
  • Scott 的经验法则:对于正态分布数据的随机样本是最佳的,在某种意义上,它最小化了密度估计的积分均方误差。

这两种方法具有计算速度快的优点,但是它们通常给出太少的面元,并且很可能对底层数据分布进行欠拟合。这两种方法都已经在 statsmodels 包中实现,如下图所示。

  • 基于交叉验证的方法:statsmodels 带有一个 cv 带宽参数。或者,我们可以实现网格搜索交叉验证。与前两种方法不同,执行网格搜索可能需要更多的计算,尤其是对于较大的数据集
from statsmodels.nonparametric.bandwidths import bw_silverman, bw_scott, select_bandwidthsilverman_bandwidth = bw_silverman(data)# select bandwidth allows to set a different kernel
silverman_bandwidth_gauss = select_bandwidth(data, bw = 'silverman', kernel = 'gauss')scott_bandwidth = bw_scott(data)def bestBandwidth(data, minBandwidth = 0.1, maxBandwidth = 2, nb_bandwidths = 30, cv = 30):
    """
    Run a cross validation grid search to identify the optimal bandwidth for the kernel density
    estimation.
    """
    from sklearn.model_selection import GridSearchCV
    model = GridSearchCV(KernelDensity(),
                        {'bandwidth': np.linspace(minBandwidth, maxBandwidth, nb_bandwidths)}, cv=cv) 
    model.fit(data[:, None])
    return model.best_params_['bandwidth']cv_bandwidth = bestBandwidth(data)print(f"Silverman bandwidth = {silverman_bandwidth}")
print(f"Scott bandwidth = {scott_bandwidth}")
print(f"CV bandwidth = {cv_bandwidth}")

正如预期的那样,第一个 Silverman 和 Scott 返回了更大的带宽值,这导致了更大的箱,从而丢失了关于数据分布的信息。

Statsmodels 允许基于交叉验证和最大似然运算符自动搜索最佳带宽:

from statsmodels.nonparametric.kernel_density import KDEMultivariate
stats_models_cv = KDEMultivariate(data, 'c', bw = 'cv_ml').pdf(x)

画出不同的*似值

plt.figure(figsize= (14, 6))
plt.plot(x, true_pdf, label = 'True PDF')kde = getKernelDensityEstimation(data, x, bandwidth=silverman_bandwidth)
plt.plot(x, kde, alpha = 0.8, label = f'Silverman bandwidth')kde = getKernelDensityEstimation(data, x, bandwidth=scott_bandwidth)
plt.plot(x, kde, alpha = 0.8, label = f'Scott bandwidth')kde = getKernelDensityEstimation(data, x, bandwidth=cv_bandwidth)
plt.plot(x, kde, alpha = 0.8, label = f'CV bandwidth')plt.plot(x, stats_models_cv, alpha = 0.8, label = f'Statsmodels CV maximum likelihood')plt.legend()
plt.title('Comparative of various bandwidth estimations for KDE');
plt.savefig('figures/comp_bw.jpg', bbox_inches='tight') 

单峰分布的统计检验

有许多统计测试可以解决数据形态问题:

  • 倾斜试验
  • 过量质量测试
  • 地图测试
  • 模式存在测试
  • 矮小测试
  • 跨度测试
  • 马鞍试验

不幸的是,在 python 开源库中实现的并不多。

倾斜试验

以下 python 包https://github.com/BenjaminDoran/unidip提供了倾角测试的实现,以及利用单峰性的哈迪根倾角测试在数据中广泛提取密度峰值的功能。

from unidip import UniDip
import unidip.dip as dipdata = np.msort(data)
print(dip.diptst(data))
intervals = UniDip(data).run()
print(intervals)

确定并绘制 KDE 的局部最大值

一旦我们有了核密度函数的估计,我们就可以确定该分布是否是多峰的,并识别对应于这些模式的最大值或峰值。
这可以通过识别一阶导数改变符号的点来实现。默认情况下,getinflexinpoints 方法可以返回所有拐点(最小值+最大值),或者只返回一个选择(typeOfInflexion = 'max'/ 'min ')。
下图描绘了可能对应于多种数据分布模式的最大值。可以通过基于峰的高度设置阈值来继续分析,以便过滤掉一些不太重要的值。

def getExtremePoints(data, typeOfExtreme = None, maxPoints = None):
    """
    This method returns the indeces where there is a change in the trend of the input series.
    typeOfExtreme = None returns all extreme points, max only maximum values and min
    only min,
    """
    a = np.diff(data)
    asign = np.sign(a)
    signchange = ((np.roll(asign, 1) - asign) != 0).astype(int)
    idx = np.where(signchange ==1)[0]if typeOfInflexion == 'max' and data[idx[0]] < data[idx[1]]:
        idx = idx[1:][::2]

    elif typeOfInflexion == 'min' and data[idx[0]] > data[idx[1]]:
        idx = idx[1:][::2]
    elif typeOfInflexion is not None:
        idx = idx[::2]

    # sort ids by min value
    if 0 in idx:
        idx = np.delete(idx, 0)
    if (len(data)-1) in idx:
        idx = np.delete(idx, len(data)-1)
    idx = idx[np.argsort(data[idx])]
    # If we have maxpoints we want to make sure the timeseries has a cutpoint
    # in each segment, not all on a small interval
    if maxPoints is not None:
        idx= idx[:maxPoints]
        if len(idx) < maxPoints:
            return (np.arange(maxPoints) + 1) * (len(data)//(maxPoints + 1))

    return idx

我们注意到获得的值对应于生成的分布的初始锚。

资源

  • https://jakevdp . github . io/blog/2013/12/01/kernel-density-estimation/
  • https://mglerner . github . io/posts/histograms-and-kernel-density-estimation-kde-2 . html
  • https://en.wikipedia.org/wiki/Multimodal_distribution

Titanic 数据集上的模型比较

原文:https://towardsdatascience.com/model-comparison-on-the-titanic-data-set-867a62ef8bb5?source=collection_archive---------3-----------------------

在为期 12 周的训练营中,我刚刚接触了数据科学的服务,我最喜欢的练习之一是查看模型比较。开始模型选择和 EDA 需要深思熟虑,并为我提供任何合理的见解执行。随着我成为一名数据科学家,我认为划分哪些模型最适合哪些类型的数据非常重要。这需要我自己进行大量的分析和探索。在这一点上,让我们看看泰坦尼克号数据集作为一个例子。

我应该提到,我正试图根据上面列出的几个因素来确定谁幸存了下来。在我深入研究之前,我想通过上面的表格指出,我们可以把性变成一个虚拟变量。接下来,我们应该执行和 EDA 定义我们想要的 X 和 y。

现在,我们应该导入并准备一个训练测试分割,并创建一个名为模型评估的功能,该功能查看准确性分数、混淆矩阵和分类报告。

现在让我们从 K 个最*的邻居开始。

现在 KNN 使用网格搜索。

这给了我们一个 0.636363636363635 的最终分数。现在让我们试试 KNN 装袋!

现在,逻辑回归

现在我们将运行一个决策树,但首先我们要运行一个网格搜索。

在这之后,我们应该在 DT 上使用装袋。

最后是随机森林和多余的树。

现在我们可以开始比较我们的模型了!首先,我们可以使用训练/测试分割来确定哪个模型执行得最好:

代替训练测试分割,我们可以看一个分层的 K 折叠来看模型在那里如何排列。

在这两方面,我认为决策树上的网格搜索包做得最好。使用训练测试分割,它排名很高,虽然它接*分层 k-fold 的下端,但它的误差比一些更高的预成型模型低得多!

通过师生知识蒸馏介绍 PyTorch 模型压缩

原文:https://towardsdatascience.com/model-distillation-and-compression-for-recommender-systems-in-pytorch-5d81c0f2c0ec?source=collection_archive---------11-----------------------

通过知识蒸馏的模型压缩可以节省推理时间、功率效率和模型大小。

Knowledge River Delta

在资源受限的移动和实时系统中服务 ML 模型可能是一个真正的问题。ML 社区一直在开发解决方案来压缩由较大的服务器集群生成的模型的大小。模型压缩承诺节省推理时间、功率效率和模型大小。所有这些都可以让飞行救援无人机在一次充电后覆盖更多的土地表面,同时不会耗尽移动应用用户的电池。

模型知识提炼是一种在不损失太多预测能力的情况下减少模型规模的方法

Geoffrey Hinton 在 2018 年深度学习峰会上关于使用 【知识蒸馏】 (KD)的演讲让我去寻找另一类问题的当前技术状态:推荐系统(RecSys)。

这让我想到了唐嘉熙在 2018 年 KDD 发表的关于 排名蒸馏 (RD)的优秀作品,他在其中讨论了他将知识蒸馏应用于排名任务的相关方法。

在这篇博客中,我在 Movielens 100K 数据集 上复制了这个排名提炼工作的一小部分。在这方面工作是一种领悟。即使 KD 是一个从一个模型到一个小模型提取知识的坚实的概念框架,将它应用于推荐系统的排序任务也不是一个简单的任务。

第一个挑战是我们在一个比常见的 fit/predict API 更低的抽象层次上工作,这些 API 存在于 Scikit-learn 和 Keras 等更高层次的库中。这是因为实现这个 KD 所需的改变是在损失函数公式本身。为了解决这个问题,我跟随第三篇论文的脚步,使用优雅的 PyTorch API 在 RecSys 中构建这个 KD。

第二个挑战是,即使 PyTorch 是一个优雅的库,我们也需要一个更高层次的框架,专门研究带有 PyTorch 的 RecSys。这些天的选择框架似乎是来自库拉的聚焦。我强烈推荐它,API 设计易于使用,它让用户自定义我们这个实验需要的大多数方面。

我们走吧!

定制分级蒸馏反向传播流

目标是从 Movielens 100K 数据集生成 3 个模型:学生模型、带蒸馏的学生模型和教师模型,并比较它们的 MAP@K 指标以及物理磁盘大小。

我们需要解释我们将要使用的策略,从教师模型到学生模型,用蒸馏来教授一些黑暗知识。以下是对培训过程中将要发生的事情的解释:

Flow of data and forward/backward propagation during the knowledge distillation method

在上图中,我们展示了培训流程:

  • 对于学生模型,我们使用传统的方法,使用带有数据标签和单个排名损失的训练数据。
  • 对于教师模型,我们与学生模型类似地对其进行预训练,但我们使用更大的网络规模来实现更高的 K (MAP@K)*均精度。在完成较大模型的训练之后,我们存储预先训练的教师模型。
  • 对于带有蒸馏的学生模型,我们使用带有标签和排名损失的训练数据。然而,在这个例子中,我们使用了教师模型对我们提供给学生模型的数据的预测。更准确地说,除了学生的损失之外,我们还使用教师的损失来计算和反向传播学生模型网络中的梯度。这些额外的信息应该可以提高学生模型的预测能力,同时保持模型大小与没有经过提取的学生模型相同。

结果比较

首先,我们需要一些培训数据,我们用这些数据来建立一个预培训教师模型。我们使用 movielens 100K 数据集,并且只使用电影/用户交互。我们将尝试预测用户最有可能评价的前 5 部电影。

为此,我们将使用 Spotlight 库提供的implicit factorization model。该模型使用基于嵌入的模型结构:

Implicit Factorization Model with a Bi-Linear model structure

对于损失,我们使用类似于下面负对数似然函数的方法。我们对正对和负对进行采样,并要求优化器提高正对中的排序项目(d+)并减少负对中的项目(d-):

Loss function related to the negative logarithmic of the likelihood function.

使用 200 作为 movielens 数据集上每个嵌入层的大小来训练“大型”教学模型,这为我们提供了以下指标:

让我们用一个小得多的模型做同样的尝试,用 2 作为每个嵌入层的大小:

2 次观察:

  • 第一,学生模型本身序列化后的大小更小(0.10 mb vs 6.34)。这与网络的大小一致,因为嵌入的大小要小 100 倍。
  • 第三,学生模型的 MAP@5 低于教师模型(0.050 vs 0.073)。较小的网络可以远离较大的网络。挑战是:我们能在保持模型尺寸不变的情况下做得更好吗?

这是我们接下来要尝试的。我们培训第三个模型,这是一个学生模型,由预先培训的教师模型推动。

为此,我们需要在损失函数中混合从两个模型中获得的两个损失。这就是 PyTorch 闪耀的地方。我们所要做的就是定义一个修正的损失函数,它总结了学生和老师的损失,让梯度下降发挥它的魔力。其核心是,如果您对使用对数 sigmoid 损失的正负损失有所了解,我们通过教师网络传递当前一批数据,获得候选预测,并使用它们来生成教师损失值。我们用于优化的最终损失是 pos/neg/teacher 这三个损失的总和。下面是组合损失函数的一个片段:

我们表现如何?

  • 首先,提取模型的 MAP@5 值更接*教师模型的值,仅使用 2 作为嵌入层的大小(0.070 比 0.073)
  • 第二,大小仍然是 0.10mb,类似于非蒸馏的学生模型。

这里有一个表格,列出了所有这些值以供比较

我们从这次冒险中学到了什么?

  • 我很高兴看到 PyTorch 能够灵活地复制 KDD2018 论文的一小部分。
  • 知识蒸馏真的很酷,也为推荐系统工作。
  • 总的来说,每当两个或更多的人工智能模型之间有互动时,我对它们的结果非常感兴趣。

如果您对这种类型的跨模型交互感兴趣,我邀请您深入研究 KDD2018 论文。我们没有讨论如何通过加权教师的模型损失或仅考虑教师模型的 top-k 建议来改进这种设置。大概是以后的帖子吧。

直到那时!

谢了。

参考资料:

唐佳夕,还有王柯。排名提取:为推荐系统学习高性能的紧凑排名模型。第 24 届 ACM SIGKDD 知识发现国际会议论文集&数据挖掘。ACM,2018。

辛顿·杰弗里、奥里奥尔·维尼亚尔斯和杰夫·迪恩。在神经网络中提取知识。arXiv 预印本 arXiv:1503.02531 (2015)。

2017 年【https://github.com/maciejkula/spotlight】库拉聚光灯T2

2018 年 PyTorch ,https://pytorch.org/

模型评估 I:精度和召回率

原文:https://towardsdatascience.com/model-evaluation-i-precision-and-recall-166ddb257c7b?source=collection_archive---------0-----------------------

source - pexels.com

为了测试像支持向量机这样的分类系统的质量,需要执行一些评估指标。支持向量机是我在内核中简单解释过的分类算法。

一点背景

精确和回忆在信息抽取中都有广泛的应用。Precision 是检索到的*的 文档的编号,Recall 是检索到的相关文档的编号。***

相关性是指所呈现的信息对此刻正在讨论的主题有多有用。

让我们来看一个约翰和乔希之间对话的例子:

如果约翰说“我喜欢冰淇淋”,而乔希回答“我有一个朋友叫约翰·多伊”,那么乔希刚才说的与约翰暗示的毫无关系,但是如果乔希说“我有一个朋友叫约翰·多伊,他也喜欢冰淇淋”,那么乔希的陈述就变得相关,因为它现在与约翰的陈述相关。

精确度和召回率都非常有助于理解呈现了哪组文档或信息,以及这些文档中有多少对于所提问题是实际上有用的。

尽管精确度和召回率有时会被混淆为同义词,但它们不是。

精确度和召回率彼此成反比,因此理解它们的差异对于建立有效的分类系统是重要的。

让我们考虑另一个例子

假设我在谷歌上搜索“什么是精确和召回?”不到一分钟,我就有大约 1560 万个结果。

假设在这 1560 万个结果中,与我的问题相关的链接大约有 200 万个。假设还有大约 600 多万个相关但没有被谷歌返回的结果,对于这样的系统,我们可以说它的精度是 2M/1560 万,召回率是 2M/8 万。

这意味着谷歌的算法检索* e 所有 相关 链接 的概率是 0.25 ( 召回),所有 检索到的链接 相关的概率是 0.13 ( 精度)。*

思考精度和回忆的另一种方式是这样的:

如果有人让你列出你去年圣诞节收到的 5 件礼物的名字,但你记不清这 5 件礼物的名字,所以你随机猜了 7 次。在你记得的 7 个名字中,有 5 个被正确回忆起来,而 2 个是你生日时收到的礼物。即使你有 100%的召回率(5/5),你的准确率也只有 71.4% (5/7)。

现在,我已经让您对精确和回忆有了初步的了解,让我们再深入一点。

第一类和第二类错误

谈精度和回忆而不提I 型& II 型错误 就像叙述穆罕默德·阿里的历史而跳过“拳击”——我

ouch! that punch was precise 😃 — source here

第一类错误

这是一个 零假设(Ho)的不正确拒绝

零假设是一个默认为真的陈述,除非被证明是相反的。

I 型错误导致假阳性 (FP) 例如,当一个文件被搜索引擎返回为“相关”时,结果却是“不相关”。

一个例子是,实际上并没有发生火灾,但火警却响了。这种错误等同于“相信谎言”或“虚惊一场”。

第二类错误

这是一个 零假设(Ho)的不正确保留

这相当于系统忽略了可能没有检索到相关文档的可能性。

这种错误会导致假阴性 (FN)。即没有检索到本应检索到的相关文档。

这种情况的一个例子是发生了火灾,但火警没有响。这种错误等同于“不相信真理”或“失误”。

考虑下表:

Table 1.0 (confusion matrix)

误报和漏报分别是精确度和召回率的两个独特特征。

Source here

减少一个意味着增加另一个

P α 1/R

一些数学公式

在分类任务中,

*Precision P = TP/(TP+ FP)*

即{真阳性(正确检索的文档)数)}/{(检索的文档总数)}

*Recall R = TP/(TP + FN)*

即{真阳性(正确检索的文档)数)}/{(检索的相关文档总数)}

从 Google 搜索的例子来看, perfect Precision 得分为 1.0 意味着搜索引擎检索到的每个结果都是相关的(但没有说明是否检索到了所有相关的文档)

完美回忆得分为 1.0 意味着所有相关文档都从搜索引擎中检索到了(但没有说明检索到的结果中有多少是不相关的)。

这不是一个非此即彼的问题,因为就一个问题作出的决定会自动影响另一个问题。因此,对于每个系统,通常都有一个基准,它被认为是“可接受的”,而不会失去太多的特性。

对于能够实现最大精确度(无假阳性)和最大召回率(无假阴性)的任何系统,需要没有类型 I 和类型 II 错误。

精确度和召回分数不是孤立讨论的。取而代之的是,将一个度量的值与另一个度量的固定水*进行比较(例如,召回水*为 0.75 的精度),或者将两者合并为一个度量。

结合了精确度和召回率的度量的例子是 F-measure

*F = 2 * ((Precision * Recall)/(Precision + Recall))*

这个指标通常被称为 F1 得分,它是精确度和召回率接*时的*均值。这是调和*均数。

其他相关指标有准确度混淆矩阵列联表

继续探索吧!

感谢PelumiHamza阅读本稿。

相关链接

  1. https://en.wikipedia.org/wiki/Null_hypothesis
  2. https://en . Wikipedia . org/wiki/Precision _ and _ recall # F-measure
  3. https://en . Wikipedia . org/wiki/Accuracy _ and _ precision # In _ binary _ class ification
  4. https://en.wikipedia.org/wiki/Confusion_matrix
  5. https://en.wikipedia.org/wiki/Contingency_table

从头开始创建模型概述和代码

原文:https://towardsdatascience.com/model-overviews-and-code-from-scratch-68481b821131?source=collection_archive---------1-----------------------

我最*在一次聚会上与一位数据科学家交谈,他提到他发现从头构建模型在智力上是有益的。注意到这让他对模型的行为有了很好的直觉,也是一个很好的 OOP 项目。我发现,通过在这个项目上花几天时间,我了解了每个模型的新特征,在堆叠、追加和整形 numpy 数组方面变得更加流畅,并且提高了我对优化算法以及使用 numpy 与标准 python 操作的效果的认识。

此外,我最*在深度学习中阅读和学习了大量新概念,我想后退一步,刷新我对常见分类算法的理解。

我决定采用 3 种难度递增的分类模型和一种额外的聚类算法:

  • KNN — 参见完整代码
  • 决策树— 见完整代码
  • 随机福里斯特— 见完整代码
  • Kmeans — 参见完整代码

K-最*邻

kNN 是机器学习中使用最广泛的分类模型之一,也是最容易理解的分类模型之一,因为它的决策过程是透明的。它被认为是一个懒惰的学习者,因为它根本不建立模型——记忆的训练数据集就是模型!为了进行样本外预测,kNN 找到 k 个最相似的训练样本,并对与它们相关联的结果类进行计数。并且通过多数投票或其他投票方案,算法预测未知样本的类别。

正如我提到的,kNN 是一个懒惰的学习者,因为它直到最后一秒——在预测时间——才做任何事情。这有几个影响。首先,这意味着 kNN 需要在预测时间内计算所有训练样本与每个未知点之间的相似度。这通常会导致更大的内存需求,并且可能比构建表示的其他模型更慢,计算量也更大。然而,如果结构适当,这可能是有利的。例如,如果新的训练样本不断生成,旧的样本被删除,那么 kNN 的预测将来自手头“最新”或“最相关”的数据。一个重要的注意事项是,kNN 假设特征被缩放。这是确保在确定相似性时所有特征被*均加权的要求。

超参数是 k 的值、相似性度量和加权度量。k 的值是预测时用于投票的邻居数量。它介于 1 和 n 之间,其中 n 是训练样本的总数。

 **def** find_neighbors(self, new_sample):
        *'''List the k neighbors closest to the new sample.*

 *'''*
        distances = []      
        **for** i **in** range(len(self.X)):
            **if** self.metric == 'euclidean':  
                distance = self.euclidean(self.X[i], new_sample)
            **if** self.metric == 'manhattan':
                distance = self.manhattan(self.X[i], new_sample)
            distances.append((self.y[i],distance))
        distances = sorted(distances,key=operator.itemgetter(1))

        neighbors = []
        **for** i **in** range(self.k):
            neighbors.append(distances[i][0])
        **return** neighbors

相似性度量是根据距离量化未知样本和训练样本之间的关系的数学函数。您可以想象,相似点的排序以及反过来的分类严重依赖于所选择的度量。有许多相似性度量,每一个都有自己的用例。通常,决策基于数据集中的数据类型和一些经验法则。

默认的数字度量是欧几里德距离。它是两点之间的“直线距离”,由*方差之和定义。另一种方法是曼哈顿距离,这是从西 22 街和第三大道走到西 27 街和第五大道所需的距离,它受轴的限制,在数学上由绝对差之和定义。此外,分类数据和二进制数据通常使用汉明距离进行评估,这基本上类似于逻辑 and。它计算点之间相同属性的数量。每个度量标准都会产生不同的点排序,基于这些点它认为与未知点最相似。

def **euclidean**(self, a, b):
    return np.sqrt(((a-b)**2).sum(axis=0))

恰好有一个距离度量来统治它们。它叫做闵可夫斯基距离。我的意思是,当 p = 2 时,它有能力表示欧几里得,当 p = 1 时,它有能力表示曼哈顿,当 p 接* 0 时,它有能力表示*汉明尔。因此,这是您在现成的 kNNs 中看到的最常见的距离度量。

def **minkowski**(self, a, b, p):
    return ((np.abs(a-b)**p).sum(axis=0))**(1/p)

加权超参数旨在基于 k 个邻居在相似性线中的位置来修改对每个 k 个邻居投票的影响。它通常设置为多数投票,这是我在实现中硬编码的,但倒数或等级距离也是其他典型的选项。

 **def** majority_vote(self, neighbors):
        *'''Determine majority class from the set of neighbors.*

 *'''*
        class_votes = {}
        **for** i **in** range(len(neighbors)):
            sample_class = neighbors[i]
            **if** sample_class **in** class_votes:
                class_votes[sample_class] += 1
            **else**:
                class_votes[sample_class] = 1
        sorted_votes = sorted(class_votes.items())
        **if** self.ties:
            sorted_votes = self.tie(sorted_votes)
        **return** sorted_votes[0][0]

kNN 培训:

1.记忆数据

kNN 预测:

  1. 接受新样本
  2. 使用指定的度量计算所有训练点和新样本之间的距离
  3. 基于相似性对所有训练点进行排序。距离越小,相似度越高
  4. 将 k 个最*点定义为排序列表中的前 k 个点
  5. 基于 k 个最*点类的加权集合计算预测值
 **def** predict(self, X_test):
        *'''Predict class for each value in array of new samples.*

 *'''*
        self.tie_count = 0
        y_pred = []
        **for** i **in** range(len(X_test)):
            neighbors = self.find_neighbors(X_test[i])
            pred_class = self.majority_vote(neighbors)
            y_pred.append(pred_class)
        **if** self.ties:
            print('**{}** ties'.format(self.tie_count))
        **return** y_pred

虽然很少,但我也添加了一个警告:当多数投票产生*局时,*局将出现在训练数据中出现频率最高的类中。由于 Iris 数据集很小,这种情况经常发生,但在较大的数据集中就不太常见了。

 **def** tie(self,sorted_votes):
        *'''Determine when ties occur in the the neighbors. Of the tied classes,*
 *choose the class most frequent in the training data.*

 *Print out number of ties.*
 *'''*
        tie = {}
        **for** pair **in** sorted_votes:
            count = pair[1]
            **if** count **in** tie:
                self.tie_count += 1
                *#print('tie')*
                tie[count].append(pair[0])
            **else**:
                tie[count] = [pair[0]]
            *#print(tie)*
        tie_class_frequency = {}
        **if** len(tie[count]) > 1:
            *#print('tie')*
            **for** tie_class **in** tie[count]:
                tie_class_frequency[tie_class] = np.count_nonzero(self.y == tie_class)
            max_class = max(tie_class_frequency, key=tie_class_frequency.get)
            *#print(max_class)*
            sorted_votes = [(max_class,1)]
        **return** sorted_votes

这个练习对我来说是一个很好的方式,可以深入到 kNN 的各个层次。这是从零开始构建更多模型的一个简单的开始,给了我一个解决问题的良好基础。了解从相似性度量到加权选项的众多选项有助于我构建类,以便在我决定做更多事情时允许增量添加。

决策树

决策树是一种流行的机器学习模型,因为它们易于解释并且具有预测能力。然而,它们本身并不常用。相反,它们被用作被认为是最先进模型的集成方法的基础。决策树是通过递归地将数据集一分为二来构建的,直到分支是纯的或者满足停止标准。最后的节点称为叶节点,对应于一个输出类。其余节点表示任意输入要素和分割数据集的要素的值。为了预测新样本的类别,样本简单地沿着分裂逻辑一个节点一个节点地向下遍历树,直到到达叶节点。

 **def** split(self, feat, val, Xy):
        Xi_left = np.array([]).reshape(0,self.Xy.shape[1])
        Xi_right = np.array([]).reshape(0,self.Xy.shape[1])
        **for** i **in** Xy:
            *#print(i.shape)*
            **if** i[feat] <= val:
                Xi_left = np.vstack((Xi_left,i))
            **if** i[feat] > val:
                Xi_right = np.vstack((Xi_right,i))
        **return** Xi_left, Xi_right

树是贪婪的算法,这意味着在每次分裂时,做出最佳决策,希望得到的树将导致全局最大值。然而,这很少偶然发生,通常他们需要许多正则化超参数来减少过拟合。上面提到的停止标准就是这样的例子。最大深度是控制树可以向下生长的总步数的参数,最小样本数是控制发生分裂所需的样本数的参数。通过减少最大深度或增加最小样本数,可以控制树的大小。

任何给定特征的最佳分离由定义纯度的成本函数确定。最常见的是用于连续特征的基尼指数和用于分类特征的信息增益或熵。基尼指数通过所得两组的阶级构成来量化分裂,其中低分意味着接*完美的分裂,高分意味着两组的构成几乎相同。

**def** gini_score(groups,classes):
    n_samples = sum([len(group) **for** group **in** groups])
    gini = 0
    **for** group **in** groups:
        size = float(len(group))
        **if** size == 0:
            **continue**
        score = 0.0
        *#print(size)*
        **for** class_val **in** classes:
            *#print(group.shape)*
            p = (group[:,-1] == class_val).sum() / size
            score += p * p
        gini += (1.0 - score) * (size / n_samples)
        *#print(gini)*
    **return** gini

为了计算最佳分割,模型必须以各种可能的方式计算每个特征分割的基尼系数。例如,以各种可能的方式分割特征[x]上的样本[a,b,c,d,e]将导致[a]和[b,c,d,e],[a,b]和[c,d,e],[a,b,c]和[d,e]以及[a,b,c,d]和[e]。将对每个分割进行评分,并保存最低的基尼系数。那么对特征[y]和[z]也是如此。然后,所有特征中最低的基尼系数将被选为最佳分割,并创建一个节点。对每个节点的所得两组中的每一组重复该过程,直到遇到点点。

 **def** best_split(self, Xy):
        classes = np.unique(Xy[:,-1])
        best_feat = 999
        best_val = 999
        best_score = 999
        best_groups = **None**
        **for** feat **in** range(Xy.shape[1]-1):
            **for** i **in** Xy:
                groups = self.split(feat, i[feat], Xy)
                gini = self.gini_score(groups, classes)
                *#print('feat {}, valued < {}, scored {}'.format(feat,i[feat], gini))*
                **if** gini < best_score:
                    best_feat = feat
                    best_val = i[feat]
                    best_score = gini
                    best_groups = groups
        output = {}
        output['feat'] = best_feat
        output['val'] = best_val
        output['groups'] = best_groups
        **return** output

这个结构是通过使用递归函数快速创建的。只需评估基尼系数,在最佳分割点创建节点,保存结果数据集,然后重复。

 **def** terminal_node(self, group):
        classes, counts = np.unique(group[:,-1],return_counts=**True**)
        **return** classes[np.argmax(counts)]

    **def** split_branch(self, node, depth):
        left_node, right_node = node['groups']
        **del**(node['groups'])
        **if** **not** isinstance(left_node,np.ndarray) **or** **not** isinstance(right_node,np.ndarray):
            node['left'] = node['right'] = self.terminal_node(left_node + right_node)
            **return**
        **if** depth >= self.max_depth:
            node['left'] = self.terminal_node(left_node)
            node['right'] = self.terminal_node(right_node)
            **return**
        **if** len(left_node) <= self.min_num_sample:
            node['left'] = self.terminal_node(left_node)
        **else**:
            node['left'] = self.best_split(left_node)
            self.split_branch(node['left'], depth+1)
        **if** len(right_node) <= self.min_num_sample:
            node['right'] = self.terminal_node(right_node)
        **else**:
            node['right'] = self.best_split(right_node)
            self.split_branch(node['right'], depth+1)

决策树训练:

  1. 基于所有要素上所有可能分割点的最低基尼系数分割输入数据
  2. 基于上述分割创建了两个数据集
  3. 同样,每个新数据集都是根据所有可能的最低基尼系数进行分割的
  4. 在所有特征上分割点
  5. 同样,从每个节点创建两个数据集
  6. 依此类推,直到根据最大深度或最小样本数标准创建叶节点

决策树预测:

  1. 接受新样本
  2. 基于根节点的拆分标准评估样本
  3. 前进到下一个节点
  4. 基于该节点的拆分标准评估样本
  5. 前进到下一个节点
  6. 依此类推,直到到达叶节点
  7. 基于叶节点的类确定预测

决策树要求每个新样本遍历训练数据的学习表示。然后将 n 个样本中的每一个附加到输出中。

 **def** predict_sample(self, node, sample):
        *#print(node)*
        **if** sample[node['feat']] < node['val']:
            **if** isinstance(node['left'],dict):
                **return** self.predict_sample(node['left'],sample)
            **else**:
                **return** node['left']
        **else**:
            **if** isinstance(node['right'],dict):
                **return** self.predict_sample(node['right'],sample)
            **else**:
                **return** node['right'] **def** predict(self, X_test):
        self.y_pred = np.array([])
        **for** i **in** X_test:
            *#print(i)*
            self.y_pred = np.append(self.y_pred,self.predict_sample(self.root,i))
        **return** self.y_pred

从头开始创建决策树算法教会了我很多东西。首先,我从来没有意识到分割搜索是多么详尽,直到我被迫编程。此外,分裂纯洁的概念现在对我来说也更清楚了。显而易见,当你构建决策树时,很容易过度拟合。只有通过创建像最大深度和最小样本数这样的超参数,树才有机会泛化。

在未来,我会跟进一个随机森林和 Kmeans 的解释,敬请期待!

分类模型的模型性能和成本函数

原文:https://towardsdatascience.com/model-performance-cost-functions-for-classification-models-a7b1b00ba60?source=collection_archive---------3-----------------------

分类模型是预测分类的 Y 变量的机器学习模型:

  1. 雇主会离开还是留下来?
  2. 病人到底有没有癌症?
  3. 该客户属于高风险、中等风险还是低风险?
  4. 客户会支付贷款还是违约?

Y 变量只能取 2 个值的分类模型称为二元分类器。

分类模型的模型性能通常在哪个模型性能最相关方面存在争议,尤其是当数据集不*衡时。用于评估分类模型的通常模型性能测量是准确度、灵敏度或召回率、特异性、精确度、KS 统计和曲线下面积(AUC)。

让我们基于一个预测贷款违约的例子来理解一些模型性能测量。贷款违约数据集是不*衡数据集的一个典型例子,其中两个类是贷款违约 Y 和贷款违约 n。贷款违约者的数量通常只占整个数据集的很小一部分,不超过 7–8%。这提供了一个经典的不*衡数据集来理解为什么成本函数在决定使用哪个模型时至关重要。

在我们深入研究如何制定成本函数之前,让我们看看混淆矩阵、假阳性、假阴性和各种模型性能测量的定义的基本概念。

什么是混淆矩阵?

混淆矩阵是包含二进制分类器输出的表格。让我们看看预测贷款违约的二元分类器的混淆矩阵——0 表示客户将支付贷款,1 表示客户将违约。我们进一步讨论的积极类是 1(将违约的客户)。

矩阵的行表示观察到的或实际的类别,列表示预测的类别。

Confusion matrix

Definition of TP, FP, TN, FN

现在,让我们试着理解每个模型性能度量在混淆矩阵的组成部分方面转化为什么。

准确(性)

准确性是模型通过记录总数做出的正确预测的数量。最好的准确度是 100%,表明所有的预测都是正确的。

对于不*衡的数据集,精确度不是模型性能的有效衡量标准。对于默认比率为 5%的数据集,即使所有记录都被预测为 0,该模型仍将具有 95%的准确性。但是这种模式会忽略所有的默认值,对业务非常不利。因此,在这种情况下,准确性不是衡量模型性能的正确标准。

敏感性或回忆

灵敏度(回忆或真阳性率)的计算方法是正确的阳性预测数除以阳性总数。它也被称为回忆(REC)或真阳性率(TPR)。

Sensitivity

特征

特异性(真阴性率)计算为正确阴性预测数除以阴性总数。

Specificity

精确

精度(阳性预测值)的计算方法是正确的阳性预测数除以阳性预测总数。

Precision

KS 统计

KS 统计量是正分布和负分布之间分离程度的度量。KS 值为 100 表示分数对记录进行了精确的划分,一个组包含所有的正数,另一个组包含所有的负数。在实际情况下,高于 50%的 KS 值是理想的。

ROC 图和曲线下面积(AUC)

ROC 图是 X 轴表示特异性,Y 轴表示灵敏度的图。ROC 曲线下的面积是模型性能的度量。随机分类器的 AUC 是 50%,而完美分类器的 AUC 是 100%。对于实际情况,超过 70%的 AUC 是理想的。

精确度与召回率

回忆或敏感度为我们提供了关于模型在假阴性(对将违约的客户的不正确预测)上的表现的信息,而精确度为我们提供了模型在假阳性上的表现的信息。基于预测的结果,精确度或召回率对模型来说可能更重要。

成本函数在决定哪个不正确的预测可能更有害(假阳性或假阴性)时发挥作用(换句话说,哪个性能测量更重要——精确度或召回率)。

净收入函数

净收入或成本函数是通过为每个假阳性和假阴性分配成本并基于正确和不正确的预测得出总收入而得到的。让我们假设此贷款默认数据集的成本和收入如下:

Cost components of a loan default prediction model

Allocation of FP, FN & TP cost

Net revenue

由于假阴性成本最高,最 的最优模型将是假阴性 最小的模型。换句话说,与其他模型相比,具有更高敏感度的模型将获得更高的净收入。

现在我们有了计算净收入的方法,让我们根据混淆矩阵来比较两个模型:

混淆矩阵 A

混淆矩阵 B

模型 B 由于其较低的假阴性被证明是一个更好的模型,因此可以被选择用于预测违约。

总之,在各种成本成分的相当*似的估计可用的商业场景中,基于成本函数的模型性能度量与传统的模型性能度量(如灵敏度、特异性等)相比,将给出对模型选择的更好的洞察。与给出统计术语相比,如果用成本和收入来解释模型,对客户来说也更有意义。

型号选择 101,使用 R

原文:https://towardsdatascience.com/model-selection-101-using-r-c8437b5f9f99?source=collection_archive---------3-----------------------

使用 R 对简单模型选择进行快速标记

我们在做什么?

由于这是一个非常入门的模型选择,我们假设你已经获得的数据已经被清理,擦洗和准备好了。数据清理本身就是一个完整的主题,实际上是任何数据科学家的主要时间接收器。如果您想自己下载数据并跟随学习,请阅读本文末尾!

编辑:我为这篇文章做了一个续集,关于可视化和绘制我们找到的模型,如果你想在读完这篇文章后看看的话!:

[## 可视化模型 101,使用 R

你已经有了一个模型,现在呢?

medium.com](https://medium.com/@peter.nistrup/visualizing-models-101-using-r-c7c937fc5f04)

如果你喜欢这篇文章并想看更多,请务必关注我的简介。

让我们看看管道:

这是我用来创建一个简单的 LM 或 GLM 的框架:

  1. 使用所有可用变量和数据创建一个基础模型
  2. 如果 R 不工作,分解分类变量
  3. 增加相关的电力变换
  4. 添加相关变量交互
  5. 删除无关紧要的变量和相关的测试标准
    ——重复第 3-5 步,直到你用尽所有选择
  6. 删除任何异常数据点
  7. 评估你的模型
  8. 将你的发现可视化

1.创建基础模型

让我们从建立一个工作空间和加载我们的数据开始。在本例中,我们正在处理一个描述女性就业状况的数据集,该数据集基于您是否是外国人、政府补贴金额(对数转换)、年龄、受教育年限和子女数量(分布在两个分类变量【young . children】school.children ):

rm(list=ls()) # “Clear current R environment”setwd(“C:/R/Workspace”) # Setting up your workspace
dat <- read.table(“employment_data.txt”, header=T) # Load that data
str(dat)
summary(dat)

哪些输出:

我们注意到的第一件事是,我们的响应变量是二项式的(显然),这表明我们有一个二项式分布,这意味着我们必须拟合一个 GLM 而不是传统的 LM :

fit.1 <- glm(employed == "yes" ~ ., data = dat, family = binomial)
summary(fit.1)

默认情况下,这种拟合是我们可以使用的最通用的拟合,它使用数据集中的每个变量( ~)来拟合二项式模型( family = binomial )关于具有值“yes”的响应变量“employed”。)给出如下输出:

好的,那么马上就有几个问题,我们不喜欢看到 p 值高于 0.05 ,更不喜欢高于 0.1 ,但是在我们不顾一切地删除它们之前,让我们先检查变量交互和幂变换!

2.分解分类变量

让我们考虑没有任何孩子和实际上有大于零的任何数量的孩子之间存在分类差异的可能性,因此我们添加分类变量,用于有 0 个孩子 : '因子(young.children == 0)''因子(school.children == 0)' 和根本没有任何孩子的组合因子'因子(young . children+school . children = = 0)'

我们可以用新的变量更新我们的拟合:

tempfit <- update(fit.1, .~. + factor(young.children == 0) 
                             + factor(school.children == 0)
                             + factor(young.children + 
                               school.children == 0))
summary(tempfit)

所以我们已经在 AIC 方面对我们的模型进行了一点改进,从 1066.81050.2 !让我们看看连续变量,观察可能的幂变换:

3.添加相关的电源转换

寻找二项分布的潜在幂变换的一个简单方法是使用这个自定义函数:

logit.plot <- function(x, y, h, link=’logit’, xlab=deparse(substitute(x)), yname=deparse(substitute(y)), ylab, rug=T, data, …){
    if(!missing(data)){
        call <- match.call()
        dataPos <- match(“data”,names(call))
        return(invisible(with(data, eval(call[-dataPos]))))
    }
    if (length(levels(factor(y)))!=2) stop(‘y must be binary’)
    succes <- levels(factor(y))[2]
    if (missing(ylab)) ylab <- paste(binomial(link)$link,’ P{‘,yname,’=’,succes,’|’,xlab,’}’, sep=’’, collapse=’’)
    if (is.factor(y)) y <- as.numeric(y==levels(y)[2])
    x.seq <- seq(min(x),max(x),length=101)
    smooth <- binomial(link)$linkfun(ksmooth(x, y, ’normal’, h, x.points=x.seq)$y)
    plot(smooth~x.seq, ylab=ylab, xlab=xlab, type=’l’,…)
    if (rug) rug(x)
    invisible(xy.coords(x = x.seq, y = smooth, xlab = xlab, ylab = ylab))
}

这实际上相当简单,它绘制了链接(E[y|x])x 的关系,其中 E[y|x]使用 Nadaraya-Watson 内核回归估计进行估计:

这需要以下参数:
x —您的解释变量
y —二元结果变量
h—Nadaraya-Watson 核回归估计的带宽
数据 —自我解释
—您想要传递给 plot()的任何附加参数

使用该函数在不同带宽上迭代,我们得到以下类型的图:

for(i in seq(2.5,10,length.out = 6))
    logit.plot(x = age, y = employed == ‘yes’, h = i, data = dat, main = paste0(“bandwidth = “,i))

在这个带有“年龄”的例子中,我们可以看到,该函数在大约 7 的带宽附*开始变得*滑,该图可以*似为 2。或者 3 年。次数多项式,对于“education”和“gov.support”也是如此,但为了简单起见,我们将考虑所有三者的形状都为 2 的情况。次数多项式:

tempfit <- update(tempfit, .~. + I(age^2) 
                               + I(education^2)
                               + I(gov.support^2))
summary(tempfit)

AIC 而言,改进相当大,从 1050.21017.7 !尽管有许多无关紧要的变量!

这是我们对“完整”模型的第一次尝试,所以让我们将其定义为“fit.2 ”,然后继续。

fit.2 <- tempfit

4。添加变量交互

检查变量相互作用的最简单的方法是使用 R 函数'add 1【T1]',这只是定义一个测试范围以及相对于原始模型测试时使用哪个测试的情况。f 检验通常只与 LMAOV 车型相关,因此我们可以“安全地”忽略该检验标准,我们将使用χ-检验** (Chisq 或 Chi)😗*

add1(fit.2, scope = .~. + .^2, test=”Chisq”)

这个范围仅仅是要求测试当前的模型(。~.)加上现有变量之间的相互作用(+。^2),这将输出许多交互,一些具有统计上显著的 p 值,但是手动排序可能会很烦人,所以让对列表进行排序,这样我们就可以在顶部得到最低的 P 值:

add1.test <- add1(fit.2, scope = .~. + .^2, test=”Chisq”)
add1.test[order(add1.test$’Pr(>Chi)’),]

是的,所以看起来外国人和年龄变量之间可能会有交互作用。在简单地添加具有最低 P 值的交互之前,要考虑的一件事是,这在我们当前的模型中是否有意义,现在年龄实际上是我们模型中最重要的变量,因此我们可能会认为添加外国人年龄之间的交互更直观,为了简单起见,我们将坚持使用外国人:年龄交互。

在添加变量交互外国人:年龄之后,让我们测试更多的交互:

add1.test <- add1(update(fit.2, .~. + foreigner:age), scope = .~. + .^2, test=”Chisq”)
add1.test[order(add1.test$’Pr(>Chi)’),]

现在看来在外国人:因素(young . children+school . children = = 0)中有一个重要的互动

经过几轮后,我们最终没有看到新的具有统计意义的交互,到最后我们添加了以下交互:

  • 外国人:年龄
  • 外国人:因素(young . children+school . children = = 0)
    +年龄:school.children
  • 政府支持:因素(young.children == 0)

因此,让我们用新的变量交互来更新我们的拟合,如下所示:

fit.3 <- update(fit.2, .~. 
+ foreigner:age 
+ foreigner:factor(young.children + school.children == 0) 
+ age:school.children 
+ gov.support:factor(young.children == 0))summary(fit.3)

再次对 AIC 进行小改进,从 1017.7 变为 1006.9

5。移除无关紧要的变量

这个过程与步骤 4 中的最后一个非常相似。我们现在将简单地使用 R 中的 drop1 函数,而不是 add1、,并且由于我们寻求移除而不是追加变量,我们寻求最高的 P 值而不是最低的(我们仍将使用 χ -test 作为我们的标准):

drop1.test <- drop1(fit.3, test=”Chisq”)
drop1.test[rev(order(drop1.test$’Pr(>Chi)’)),]

这和我们的模型告诉我们的大部分是一样的——总结,政府支持肯定没有统计上的显著性,所以我们将首先移除它,以此类推,我们最终移除以下变量:

  • 政府支持
  • 青少年
  • 教育
  • 教育

移除这些变量后,我们看到所有剩余变量都具有统计显著性,因此让我们通过移除上面列出的变量来更新我们的拟合:

fit.4 <- update(fit.3, .~. 
— I(gov.support^2) 
— young.children 
— education 
— I(education^2))summary(fit.4)

不错, AIC 的另一个改进虽然微不足道,但这个模型相对于我们之前的模型的主要优势是增加了解释变量数量减少所固有的简单性

有人可能会问“为什么我们不删除gov . support变量?在看我们模型的总结时,这显然是微不足道的!”这是因为边际原则禁止我们移除一个无关紧要的变量,如果该变量与另一个变量有显著的相互作用,如gov . support:factor(young . children = = 0)。

鉴于明显不重要,并且与 young.children == 0 变量的交互仅略微重要( p = 0.435) ,您可能会认为移除 gov.support 将有利于模型的简单性,然而,当进一步检查从模型中移除 gov.support 时,变量交互分裂为两个变量 因此,没有给我们任何额外的简单性, AIC所有其他系数以及零** -和剩余偏差保持完全相同,因此,我关闭它,将其留在模型中。**

对我们新改进的模型进行 add1drop1 测试表明,没有新的显著交互,所有当前变量都是显著的,所以我们完成了!最终拟合为:

glm(employed == “yes” ~ foreigner 
+ gov.support 
+ age 
+ school.children 
+ factor(young.children == 0) 
+ factor(school.children == 0) 
+ factor(young.children + school.children == 0) 
+ I(age^2) 
+ foreigner:age 
+ foreigner:factor(young.children + school.children == 0) 
+ age:school.children 
+ gov.support:factor(young.children == 0), family = binomial, data = dat)

6。移除异常值

现在我们有了一个满意的模型,我们可以寻找对模型有负面影响的异常值。

使用“汽车”包https://www.rdocumentation.org/packages/car/versions/1.0-2我们可以使用 influencePlot()和 outlierTest()函数来查找潜在的异常值:

我们看到数据点 416 在两个测试中都被归类为异常值,我们可以查看一些图中的点,以判断是否要将其移除:

par(mfrow = c(2, 2)) # 2 row(s), 2 column(s)plot(fit.4, col=ifelse(as.integer(rownames(dat))==416, “red”, “black”), pch=20)

这似乎很可能会对我们的模型造成一点影响,请注意,我们实际上应该使用皮尔逊残差来衡量我们的模型拟合度,因此,左上角的图中没有任何接*直线的东西是好的, Q-Q 图也与这种模型无关。

让我们试着去掉这一点,看看新的合身程度:

final.fit <- update(fit.4, data = dat[-c(416),])
summary(final.fit)

从最初的 1067,下降到几乎10001000AIC比较两个不同数据集的 AIC(因为我们移除了点 416)时,我们实际上必须得出结论,416 在初始模型中也是异常值,移除它,然后将没有点 416 的初始模型的 AIC 值与没有点 416 的最终拟合值进行比较

查看另一轮 influencePlot()outlierTest() 我们发现数据点 329 也在发挥作用,但是查看实际的曲线图我们会发现,我们无法像使用 416 那样真正证明删除数据的合理性。这是我们最后的合身衣服。

7.模型评估

现在我们有了一个最终拟合,我们不能自信地添加或删除任何交互变量和其他转换是时候评估我们的模型是否真正符合我们的数据,以及我们的最终拟合和第一次“天真”拟合之间是否有统计学上的显著差异。

让我们先来看看我们的拟合值与皮尔逊残差的对比:

par(mfrow = c(1, 1)) # 2 row(s), 2 column(s)
plot(p.resid ~ fit.val)
lines(ksmooth(y = p.resid, x = fit.val, bandwidth=.1, kernel=’normal’), col=’blue’)
abline(h=0)

这是一个相当不错的拟合,让我们看看主要解释变量的拟合情况:

除了' gov.support '之外,一切看起来都很好,而且' gov.support '弯曲的原因似乎是一个孤立点,与我们所有其他数据点相比,某人获得的支持量要低得多。

检查潜在的过度拟合

过度拟合是所有统计建模的祸根,你如何确保你的模型不仅仅符合你输入的精确数据?我们的目标是建立一个通用的模型,而不仅仅是迎合现有的数据。那么,我们如何测试我们的模型是否过度符合我们的数据呢?

一个流行的测试指标是通过交叉验证生成的 delta 值,我们可以通过使用来自' boot '包的 cv.glm 函数来计算这些值,并将我们的最终拟合与我们的第一次拟合进行比较!

cv.glm(dat[-c(416),], final.fit, K = 13)$delta
cv.glm(dat[-c(416),], update(fit.1, data = dat[-c(416),]), K = 13)$delta

在上面的代码中,我们使用了 k 倍交叉验证k = 13 (因为 13 是 871 的因数,871 是我们在去除异常值后的数据长度)这意味着我们将数据分成 13 个“块”。

delta 值是一个向量,其中第一个分量是预测误差的原始交叉验证估计值,第二个分量是调整后的交叉验证估计值(设计用于补偿不使用穷举测试方法(如*)引入的偏差*****

运行上面的代码会产生以下增量值,请注意,这些值受一些随机变化的影响,因此您可能不会获得完全相同的值:

对于最终拟合,预测误差低于,即使在交叉验证测试时也是如此。因此,我们可以假设我们的模型没有过度拟合我们的数据!

拼图的最后一块

因此,现在我们已经得出结论,我们的模型实际上非常适合我们的数据,但它与没有任何转换和变量交互的“天真”模型相比,在统计上有显著差异吗?为此,我们可以使用 ANOVA 测试,我们只需在两次拟合中删除相同的数据点:

这两种拟合之间肯定有显著的差异,我们可以高兴地得出结论,我们的努力得到了回报!

8.模型可视化

现在我们已经有了一个模型,我们如何真正地可视化解释它所说的关于我们的数据中的关系?

看看下面的走线通道,它使用了与本文相同的数据和型号。:

* [## 可视化模型 101,使用 R

你已经有了一个模型,现在呢?

medium.com](https://medium.com/@peter.nistrup/visualizing-models-101-using-r-c7c937fc5f04)*

结束语

请记住,这纯粹是介绍性的并且这不是详尽的分析或结论!如果我们在追求中更加严格,我们会在我们模型的每个新迭代中加入交叉验证测试和方差分析测试。每当我们增加一个新的变量,交互作用或能量转换。

如果您有任何问题,请随时给我发消息,如果您觉得我错过了什么或做错了什么,请纠正我,请记住,这是对 R 建模的介绍,我很清楚,与更高级的方法相比,这个过程是高度简化的!

如果你想试试这个数据集的运气,试试这里:https://github . com/pela 15 AE/statmod/blob/master/employment _ data . txt

数据是丹麦语,因此要将标题和分类值转换为英语,请运行这段代码:

*names(dat) <- c(“employed”, “foreigner”, “gov.support”, “age”, “education”, “young.children”, “school.children”)
levels(dat$employed)[1] <- “yes”
levels(dat$employed)[2] <- “no”
levels(dat$foreigner)[1] <- “yes”
levels(dat$foreigner)[2] <- “no”*

结束语

如果你想看和了解更多,一定要关注我的 媒体 🔍碎碎念 🐦

*** [## 彼得·尼斯特鲁普-中等

阅读彼得·尼斯特拉普在媒介上的作品。数据科学、统计和人工智能...推特:@PeterNistrup,LinkedIn…

medium.com](https://medium.com/@peter.nistrup)***