TowardsDataScience 博客中文翻译 2020(二百)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

分类特征编码技术

原文:https://towardsdatascience.com/categorical-encoding-techniques-93ebd18e1f24?source=collection_archive---------7-----------------------

Python 中分类特征的编码方法

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

照片由 v2oskUnsplash 上拍摄

分类数据是一种常见的非数值型数据,它包含标签值而不是数字。一些例子包括:

  • 颜色:红色、绿色、蓝色
  • 城市:纽约、奥斯汀、丹佛
  • 性别:男,女
  • 排名:第一,第二,第三

根据维基百科,“分类变量是一个可以取有限的,通常是固定数量的可能值的变量。”

通常将分类变量的可能值称为级别。

有几种不同类型的分类数据,包括:

  • 二进制:只有 2 个值的变量。例如,对/错或是/否。
  • 序数:一个变量,它有一些相关的顺序,就像我们上面的 place 例子。
  • 名义:没有数值重要性的变量,例如颜色或城市。

许多机器学习算法不能直接处理分类数据。它们要求数据是数字。因此,了解如何对分类变量进行编码至关重要。

数据

我们将使用来自 Kaggle 的分类特征编码挑战 II 的数据。这个挑战的特点是数据集只有分类变量,这使得它非常适合探索不同的分类编码方法。

数据集包含二进制、名义和序数要素。我们将探索对每种类型的特征进行编码的方法。

完整的笔记本可以在这里找到。

二进制特征编码

二元特征是那些只有两个可能值的特征。

我们的数据集中有五个二元要素。正如我们在下面看到的,前三个已经是数字,不需要任何操作,bin_3bin_4是需要编码的字符串。

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

编码前的二进制特征

因为这些是二进制特征,我们可以用熊猫的T2 对它们进行编码:

df['bin_3'] = df['bin_3'].replace({'T':1}, 'F':0})
df['bin_4'] = df['bin_4'].replace({'Y':1, 'N':0})

这里我们将一个字典传递给replace(),以当前值作为键,以所需值作为值。下面我们可以看到我们的二进制特征编码。(现在,我们将忽略空值。)

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

编码后的二进制特征

对于二元特征,使用replace()非常有帮助,但是如果我们有更多类别的分类特征呢?

序数特征编码

序数特征是那些具有某种顺序的特征。我们可以从下面的有序特征样本中看出,这些特征有一个可能很重要的顺序。

从 Kaggle 的排名系统中,我们知道特级大师的位置高于新手或贡献者。

机器学习模型可能能够使用订单信息来做出更好的预测,我们希望保留它。

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

编码前的序数特征。

对于序数特征,我们使用整数编码。要对数据进行整数编码,我们只需将标签转换为整数值。

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

标签编码。

虽然整数编码有许多方法,但我们将在这里讨论两种:

  • Sklearn 的LabelEncoder()
  • 熊猫的map()

我们可以用 Sklearn 的 LabelEncoder()来标注编码数据:

from sklearn.preprocessing import LabelEncoder#label encoder can't handle missing values
ordinal_features['ord_1'] = ordinal_features['ord_1'].fillna('None')# Label encode ord_1 feature
label_encoder = LabelEncoder()
ordinal_features['ord_1'] = label_encoder.fit_transform(ordinal_features['ord_1'])# Print sample of dataset
ordinal_features.head()

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

ord _ 1 编码的序数特征。

上面我们看到了编码特征ord_1。我们可以看到值特级大师用整数 2 编码,新手用整数 5 编码,用整数 4 编码。

虽然使用LabelEncoder()非常快速和简单,但它可能不是这里的最佳选择:我们的编码顺序并不完全正确。此外,在能够使用它之前,我们必须处理我们的空值。

LabelEncoder()的另一个缺点是,文档声明它应该用于编码目标值(y ),而不是输入值(x)。让我们探索一种不同的方法来编码我们的序数特征。

这里的另一个选项是使用map()

熊猫的 map()用另一个指定值替换每个值,类似于我们上面用的replace()。在这里,我们用我们想要的映射创建一个字典,并将映射应用到我们的系列:

# create dictionary of ordinal to integer mapping
ord_2 = {'Freezing':1, 
            'Cold':2, 
            'Warm':3, 
            'Hot':4, 
            'Boiling Hot':5, 
            'Lava Hot':6}# apply using map
df['ord_2'] = df.ord_2.map(ord_2)

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

ord _ 1 和 ord _ 2 使用 map 编码的序号要素。

使用map()允许我们指定分类特征中值的顺序,以确保它们处于有意义的排列中。

这些方法应该只用于顺序特征,因为顺序很重要。对于顺序不重要的特性,我们必须探索其他技术。

名义特征

名义特征是没有数字重要性的分类特征。顺序并不重要。

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

编码前的名义特征。

当顺序不重要时,一键编码是一种更好的技术。例如,在特征nom_1中,我们有形状。这里没有明显的顺序。一种形状并不比另一种好。

在这种情况下,顺序并不重要,整数编码可能会导致模型性能下降,因此不应该使用。

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

一个热编码

在一个热编码中,为分类变量中的每个唯一值创建一个新的二进制(虚拟)变量。在上图中,我们有三种独特的颜色,所以我们创建了三个新的特征,每种颜色一个。如果值为真,则将整数 1 放入字段中,如果值为假,则放入 0。

这里我们可以使用熊猫的 get_dummies()对我们的名义特征进行一次热编码。

该方法将分类变量转换为虚拟变量,并返回数据帧。drop_first参数有助于通过移除第一级来获得 k-1 个假人。

nominal_features = pd.get_dummies(nominal_features, drop_first=True)

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

编码后的名义特征。

我们可以从上面的一个热编码的名义特征的例子中看到,这种类型的编码可以大大增加我们的列数。我们输入 10 列,编码后现在有超过 5000!

在高基数特性的情况下,那些具有许多可能值的特性,我们可能需要在编码之前做一些操作。例如,对于只出现很少一部分时间的值,我们可以将它们归入“其他”类别。

其他技术

删除分类变量

另一种方法是从数据集中删除分类变量。虽然移除特征始终是一种选择,但它可能不是处理分类变量的最佳方式,因为我们会丢失潜在的重要信息。

由于我们一直在处理的数据集只包含分类特征,这显然不是这种情况下的一个选项!

结论

我们探索了根据类型对分类变量进行编码的基本技术:

  • 二进制的
  • 序数
  • 名义上的

虽然回顾的技术决不是编码分类变量的唯一选择,但它们是一个很好的起点。

在以后的文章中,我们将探索其他分类编码技术。

通过卡方进行分类特征选择

原文:https://towardsdatascience.com/categorical-feature-selection-via-chi-square-fc558b09de43?source=collection_archive---------7-----------------------

分析和选择用于创建预测模型的分类特征

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

照片由 Siora 摄影Unsplash 上拍摄

在我们日常的数据科学工作中,我们经常会遇到分类特征。有些人会对如何处理这些特性感到困惑,特别是当我们想要创建一个预测模型,而这些模型基本上是一个接受数字的方程时;不是一个类别。

一种方法是使用 OneHotEncoding 方法对所有 category 变量进行编码(将所有 category 类编码为数值 0 和 1,其中 0 表示不存在,1 表示存在)。

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

一种热编码方法的例子

许多人更喜欢这种方法,因为信息仍然存在,并且很容易理解概念。当我们拥有许多高基数的分类特征时,一个酒店编码过程后的特征数量将是巨大的。为什么我们不希望我们的训练数据集中有很多特征?这是因为维度的诅咒。

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

虽然增加特征可以减少我们的预测模型中的误差,但它只会减少到一定数量的特征;之后,误差会再次增大。这就是维数灾难的概念。

有很多方法可以缓解这个问题,但我的一个方法是通过卡方独立性测试进行特征选择。

独立性卡方检验

独立性卡方检验用于确定两个分类(名义)变量之间是否存在显著关系。这意味着独立性的卡方检验是一个假设检验,有两个假设;零假设和替代假设。假设写在下面。

零假设(H0): 变量之间没有关系

替代假设(H1): 变量之间有关系

就像任何统计测试一样,我们根据我们选择的 p 值(通常是 0.05)进行测试。如果 p 值显著,我们可以拒绝零假设,并声称研究结果支持替代假设。我不会过多地讨论统计理论,因为本文的目的是展示使用卡方检验的特征选择在实际应用中是如何工作的。

例如,我将使用来自 Kaggle 的贷款数据集来解决分类问题。这里,数据集包括各种数值、序数和名义变量,如下所述(出于文章目的,我将删除所有实际上需要另一次分析的空值)。

import pandas as pd
loan = pd.read_csv('loan_data_set.csv')#Dropping the uninformative feature
loan.drop('Loan_ID')#Transform the numerical feature into categorical feature
loan['Loan_Amount_Term'] = loan['Loan_Amount_Term'].astype('object')
loan['Credit_History'] = loan['Credit_History'].astype('object')#Dropping all the null value
loan.dropna(inplace = True)#Getting all the categorical columns except the target
categorical_columns = loan.select_dtypes(exclude = 'number').drop('Loan_Status', axis = 1).columnsloan.info()

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

在卡方检验中,我们以交叉列表(应急)格式显示数据,每行代表一个变量的水平(组),每列代表另一个变量的水平(组)。让我们尝试在性别和 Loan_Status 列之间创建一个交叉制表表。

pd.crosstab(loan['Gender'], loan['Loan_Status'])

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

交叉标签示例

现在,让我们尝试使用卡方独立性检验来测试这两个特征之间的关系。幸运的是 python 库 scipy 已经包含了测试函数供我们使用。

# Import the function
from scipy.stats import chi2_contingency#Testing the relationship
chi_res = chi2_contingency(pd.crosstab(loan['Loan_Status'], loan['Gender']))print('Chi2 Statistic: {}, p-value: {}'.format(chi_res[0], chi_res[1]))

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

独立性结果的卡方检验

如果我们选择 p 值水平为 0.05,由于 p 值测试结果大于 0.05,我们无法拒绝零假设。这意味着,基于独立性的卡方检验,性别和贷款状态特征之间没有关系。

我们可以尝试在所有分类特征都存在的情况下使用这个测试。

chi2_check = []
for i in categorical_columns:
    if chi2_contingency(pd.crosstab(loan['Loan_Status'], loan[i]))[1] < 0.05:
        chi2_check.append('Reject Null Hypothesis')
    else:
        chi2_check.append('Fail to Reject Null Hypothesis')res = pd.DataFrame(data = [categorical_columns, chi2_check] 
             ).T 
res.columns = ['Column', 'Hypothesis']
print(res)

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

对所有分类特征进行独立卡方检验的结果

事后测试

独立性的卡方检验是一个综合检验,这意味着它将数据作为一个整体进行检验。如果我们在一个类别中有多个类,并且卡方表大于 2×2,那么我们将无法轻易辨别哪个类的要素负责这种关系。为了确定哪个类是负责任的,我们需要一个事后测试。

为了进行多重 2×2 卡方独立性测试,我们需要对每个测试的特征进行重新分组,使其成为一个相对于其他类别的类别。为此,我们可以对每个类应用 OneHotEncoding,并针对另一个特性创建一个新的交叉表。

例如,让我们试着对 Property_Area 特性做一个事后测试。首先,我们需要对 Property_Area 特性进行 OneHotEncoding。

property_dummies = pd.get_dummies(data = loan[['Property_Area', 'Loan_Status']], columns = ['Property_Area'])

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

接下来,我们根据目标 Loan_Status 为每个 Property_Area 类创建交叉表。

#Example
pd.crosstab(property_dummies['Loan_Status'], property_dummies['Property_Area_Rural'])

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

然后我们可以对这一对进行卡方检验。

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

但是,有一点要记住。将多个类别相互比较意味着每次测试的假阳性错误率。例如,如果我们选择 p 值水平为 0.05 的第一个测试,意味着有 5%的机会出现假阳性;如果我们有多个类,那么之后的测试会使错误增加,有 10%的机会成为假阳性,等等。每进行一次后续测试,错误率都会增加 5%。在我们上面的例子中,我们有 3 个成对的比较。这意味着我们的卡方检验会有 15%的错误率。这意味着我们测试的 p 值等于 0.15,这相当高。

在这种情况下,我们可以使用 Bonferroni 调整方法来校正我们使用的 p 值。我们通过想要进行的成对比较的数量来调整我们的 P 值。公式为 p/N,其中 p=原始测试的 p 值,N=计划的成对比较的次数。例如,在我们的例子中,我们在 Property_Area 特性中有 3 个类;这意味着如果我们根据 Loan_Status 特性测试所有的类,我们将有 3 个成对的比较。我们的 P 值是 0.05/3 = 0.0167

使用调整后的 P 值,我们可以测试所有以前的重要结果,以查看哪个类负责创建重要的关系。

check = {}
for i in res[res['Hypothesis'] == 'Reject Null Hypothesis']['Column']:
    dummies = pd.get_dummies(loan[i])
    bon_p_value = 0.05/loan[i].nunique()
    for series in dummies:
        if chi2_contingency(pd.crosstab(loan['Loan_Status'], dummies[series]))[1] < bon_p_value:
            check['{}-{}'.format(i, series)] = 'Reject Null Hypothesis'
        else:
            check['{}-{}'.format(i, series)] = 'Fail to Reject Null Hypothesis'res_chi_ph = pd.DataFrame(data = [check.keys(), check.values()]).T
res_chi_ph.columns = ['Pair', 'Hypothesis']
res_chi_ph

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

在这里,我还包括了用于成对比较的二元特性。正如我们所看到的,许多类实际上并不重要。甚至在事后测试导致所有类之前显著的 Loan_Amount_Term 也不显著。

预测模型

这种特征选择技术的目的是看它如何影响我们的预测模型。让我们用最简单的模型;作为基准的逻辑回归。首先,我会使用所有的数据,并在初始阶段查看模型性能。在这里,我将所有分类数据视为名义数据(甚至是序数数据)。

#OneHotEncoding all the categorical variable except the target; Also drop_first = True to avoid multicollinearity for Logistic Regressiondata_log = pd.get_dummies(data = loan, columns = loan.select_dtypes(exclude = 'number').drop('Loan_Status', axis =1).columns, drop_first =True)#Change the class into numerical valuedata_log['Loan_Status'] = data_log['Loan_Status'].apply(lambda x: 0 if x == 'N' else 1)#Splitting the data into Training and Test datafrom sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data_log.drop('Loan_Status', axis =1), data_log['Loan_Status'], test_size = 0.30, random_state = 101)#Creating the prediction model
from sklearn.linear_model import LogisticRegression
log_model = LogisticRegression(max_iter = 1000)
log_model.fit(X_train, y_train)#Performance Check
from sklearn.metrics import classification_report, confusion_matrix, roc_curve,auc, accuracy_scorepredictions = log_model.predict(X_test)
print(accuracy_score(y_test, predictions))
Out: 0.7708333333333334print(classification_report(y_test,predictions))

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

#Creating the ROC-AUC plotpreds = log_model.predict_proba(X_test)[:,1]
fpr, tpr, threshold = roc_curve(y_test, preds)
roc_auc = auc(fpr, tpr)
plt.figure(figsize=(10,8))
plt.title('Receiver Operator Characteristic')
plt.plot(fpr, tpr, 'b', label = 'AUC = {}'.format(round(roc_auc, 2)))
plt.legend(loc = 'lower right')
plt.plot([0,1], [0,1], 'r--')
plt.xlim([0,1])
plt.ylim([0,1])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()

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

将所有数据作为训练数据的模型的 ROC-AUC

以上是我们使用所有数据时的模型性能,让我们将其与我们通过独立性卡方检验选择的数据进行比较。

#Get the list of all the significant pairwisesignificant_chi = []
for i in res_chi[res_chi['Hypothesis'] == 'Reject Null Hypothesis']['Pair']:
    significant_chi.append('{}_{}'.format(i.split('-')[0],i.split('-')[1]))#Drop the data with duplicate informationfor i in ['Married_No', 'Credit_History_0.0']:
    significant_chi.remove(i)#Including the numerical data, as I have not analyze any of this featurefor i in loan.select_dtypes('number').columns:
    significant_chi.append(i)print(significant_chi)Out: ['Married_Yes', 'Credit_History_1.0','Property_Area_Semiurban',
 'ApplicantIncome','CoapplicantIncome', 'LoanAmount']

以前,如果我们使用所有的数据,我们最终会得到 21 个独立变量。通过功能选择,我们只有 6 个功能可以使用。我不会再次进行训练测试分割,因为我想用相同的训练数据和测试数据来测试数据。让我们看看我们的模型性能如何与这些选定的功能。

#Training the model only with the significant features and the numerical featureslog_model = LogisticRegression(max_iter = 1000)
log_model.fit(X_train[significant_chi], y_train)#Metrics check
predictions = log_model.predict(X_test[significant_chi])
print(accuracy_score(y_test, predictions))Out: 0.7847222222222222print(classification_report(y_test,predictions))

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

具有唯一选定特征的 ROC-AUC

结论

就度量标准而言,具有所选特征的模型比使用所有特征训练的模型表现稍好。从理论上讲,这是可能发生的,因为我们消除了数据中的所有噪声,只得到最重要的模式。虽然,我们还没有分析可能也很重要的数字数据。总的来说,我已经表明,通过卡方独立性检验,我们最终只能得到最重要的分类特征。

如果你喜欢我的内容,并想获得更多关于数据或作为数据科学家的日常生活的深入知识,请考虑在这里订阅我的时事通讯。

如果您没有订阅为中等会员,请考虑通过我的推荐订阅。

CatBoost 中的分类特征参数

原文:https://towardsdatascience.com/categorical-features-parameters-in-catboost-4ebd1326bee5?source=collection_archive---------9-----------------------

掌握你不知道存在的参数

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

分类特征示例:猫的脸型

CatBoost 是一个开源的渐变增强库。CatBoost 和其他梯度增强库的区别之一是它对分类特性的高级处理(事实上,包名中的“Cat”并不代表🐱但对于“绝对的”)。

CatBoost 可以很好地处理现成的分类数据。然而,它也有大量的训练参数,这些参数提供了对分类特征预处理的精细控制。在本教程中,我们将学习如何更好地使用这些参数。本教程分为以下几个部分:

  1. 简介:机器学习中的分类特征
  2. CatBoost 中的分类特征处理
  3. 实验:分类特征设置如何影响预测旧车价格的准确性

1.简介:机器学习中的分类特征

с类别特征是一个具有一组离散值的特征,这些离散值被称为类别,这些类别不能通过<或>相互比较。在现实世界的数据集中,我们经常处理分类数据。分类要素的基数,即要素可以采用的不同值的数量,在要素和数据集之间变化很大-从几个到数千甚至数百万个不同的值。分类特征的值可以几乎均匀地分布,并且可能存在频率相差数量级的值。要在梯度提升中使用分类特征,需要将其转换为决策树可以处理的某种形式,例如转换为数字。在下一节中,我们将简要介绍将分类特征值转换为数字的最流行的机器学习方法。分类特征预处理的标准方法

  • 一键编码包括为每个类别创建一个二进制特征。该方法的主要问题是具有巨大基数的特征(例如用户 id)导致大量特征。
  • 标签编码映射每个类别,即一个分类特征可以取为一个随机数的值。这难道不是很有道理吗?它在实践中也不太管用。
  • 哈希编码使用哈希函数将字符串类型特征转换为固定维度向量。
  • 频率编码包括用数据集中类别的频率替换分类特征值。
  • 目标编码用一个数字替换分类特征的值,该数字根据分类变量的特定值的目标值的分布计算得出。有时被称为贪婪目标编码的最直接的方法是对属于该类别的对象使用目标的平均值。但是,这种方法会导致目标泄漏和过拟合。这些问题的一个可能的解决方案是维持目标编码 —训练数据集的一部分用于计算每个类别的目标统计数据,而训练是在其余的训练数据上执行的。它解决了目标泄露问题,但需要我们牺牲一部分宝贵的训练数据。为此,实践中最流行的解决方案是 K 倍目标编码留一目标编码。K 折叠目标编码背后的思想非常类似于 K 折叠交叉验证-我们将训练数据分成几个折叠,在每个折叠中,我们用在其他折叠上计算的类别的目标统计来替换分类特征值。留一目标编码是 K 重编码的特例,其中 K 等于训练数据的长度。k 倍编码和留一目标编码也可能导致过拟合。考虑以下示例:在训练数据集中,我们有一个具有单个值的单一分类特征,以及 5 个类 0 对象和 6 个类 1 对象。显然,只有一个可能值的特征是无用的,然而,如果我们对所有类别 0 的对象使用具有均值函数的留一目标编码,特征值将被编码成 0.6,而对所有类别 1 的对象,特征编码值将是 0.5。这将允许决策树分类器选择 0.55 的分割,并在训练集上实现 100%的准确性。

2.CatBoost 中的分类特征处理

CatBoost 支持一些传统的分类数据预处理方法,比如一键编码和频率编码。然而,这个包的一个特征是它的分类特征编码的原始解决方案。

CatBoost 分类特征预处理背后的核心思想是有序目标编码:执行数据集的随机排列,然后仅使用放置在当前对象之前的对象,对每个示例执行某种类型的目标编码(例如,仅计算该类别对象的目标平均值)。

通常,在 CatBoost 中将分类特征转换为数字特征包括以下步骤:

  1. 随机排列训练对象。
  2. 量化即根据任务类型将目标值从浮点转换为整数:
  • 分类-目标值的可能值为“0”(不属于指定的目标类)和“1”(属于指定的目标类)。
  • 多分类-目标值是目标类的整数标识符(从“0”开始)。
  • 回归-对标注值执行量化。在启动参数中设置桶的模式和数量。位于单个存储桶内的所有值都被分配一个标签值类—一个由公式定义的范围内的整数:<存储桶 ID — 1 >。

3.编码分类特征值。

CatBoost 创建了训练对象的四种排列,对于每种排列,都会训练一个单独的模型。三个模型用于树结构选择,第四个用于计算我们保存的最终模型的叶子值。在每次迭代中,随机选择三个模型中的一个;该模型用于选择新的树结构,并计算所有四个模型的树叶值。

使用几种模型进行树结构选择增强了分类特征编码的鲁棒性。如果在一个排列中,一个对象靠近数据集的开始,并且在另外两个排列中对少量对象计算编码统计,则它可能更靠近数据集的结尾,并且许多对象将用于计算统计。

另一个要点是 CatBoost 可以结合现有的分类特征创建新的分类特征。并且它实际上会这样做,除非你明确地告诉它不要这样做:)原始特征和创建的特征的处理可以分别由设置simple_ctrcombinations_ctr单独控制(我们将详细讨论它们)。

3.分类特征参数在实际中的应用:旧车价格预测

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

丘特尔斯纳普Unsplash 上拍照

资料组

对于本教程中的实验,我们将使用https://www.kaggle.com/lepchenkov/usedcarscatalog

该数据集由旧汽车的描述及其特征组成,既有数字的,如里程、生产年份等,也有分类的,如颜色、制造商名称、型号名称等。

我们的目标是解决回归任务,即预测一辆旧车的价格。

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

让我们看看每个分类变量有多少个唯一值:

df[categorical_features_names].nunique()manufacturer_name      55
model_name           1118
transmission            2
color                  12
engine_fuel             6
engine_type             3
body_type              12
state                   3
drivetrain              3
location_region         6

目标值分布如下:

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

首先,我们将粗略估计完成这项任务所需的树的数量和学习率。

0:	learn: 5935.7603510	test: 6046.0339243	best: 6046.0339243 (0)	total: 73.2ms	remaining: 6m 5s
2000:	learn: 1052.8405096	test: 1684.8571308	best: 1684.8571308 (2000)	total: 19.5s	remaining: 29.2s
4000:	learn: 830.0093394	test: 1669.1267503	best: 1668.7626148 (3888)	total: 41.4s	remaining: 10.3s
4999:	learn: 753.5299104	test: 1666.7826842	best: 1666.6739968 (4463)	total: 52.7s	remaining: 0usbestTest = 1666.673997
bestIteration = 4463

现在,我们将编写一个简单的函数,在给定参数的情况下测试 CatBoost 在三重交叉验证上的性能,并返回最后一个模型的完整参数列表。可选地,该函数将模型的度量与用默认分类特征参数训练的模型的结果进行比较。

我们将估计器的数量固定为 4500,学习率为 0.1。

CatBoost 中编码参数的分类特征

CatBoost 中与分类特征处理相关的参数数量庞大。下面是一个完整的列表:

  • one_hot_max_size (int) -对所有具有小于或等于给定参数值的不同值的分类特征使用一键编码。对这些特征不进行复杂的编码。回归任务的默认值为 2。
  • model_size_reg(从 0 到 inf 浮动)-模型大小正则化系数。该值越大,模型尺寸越小。详情参见“模型尺寸正则化系数”部分。只有具有分类特征的模型(其他模型很小)才需要这种正则化。如果分类特征具有大量值,则具有分类特征的模型可能会有数百亿字节或更多。如果正则项的值不为零,则使用分类要素或具有大量值的要素组合会产生不利影响,因此在生成的模型中使用的分类要素或要素组合较少。默认值为 0.5
  • max_ctr_complexity -可以组合的最大特征数量。每个结果组合由一个或多个分类特征组成,并且可以选择包含以下形式的二进制特征:“数字特征>值”。对于 CPU 上的回归任务,默认值为 4。
  • has_time (bool) -如果true,分类特征处理的第一步,置换,不执行。当数据集中的对象按时间排序时非常有用。对于我们的数据集,我们不需要它。默认值为
  • simple_ctr -简单分类特征的量化设置。
  • combinations_ctr -分类特征组合的量化设置。
  • per_feature_ctr -分类特征的每特征量化设置。
  • counter_calc_methodCounter决定是否使用验证数据集(通过fit方法的参数eval_set提供)来估计类别频率。默认情况下,它是Full,使用验证数据集中的对象;传递SkipTest值以忽略验证集中的对象
  • ctr_target_border_count -用于分类特征目标量化的最大边界数。回归任务的默认值为 1。
  • ctr_leaf_count_limit -具有分类特征的叶子的最大数量。默认值为无,即没有限制。
  • store_all_simple_ctr -如果先前的参数在某一点上梯度推进树不再能够通过分类特征进行分割。默认值等于False时,限制适用于原始分类特征和 CatBoost 通过组合不同特征创建的特征。如果该参数设置为True,只有组合特征上的分割数量受到限制。

三个参数simple_ctrcombinations_ctrper_feature_ctr是控制分类特征处理的第二和第三步骤的复杂参数。我们将在接下来的章节中详细讨论它们。

默认参数

首先,我们测试现成的 CatBoost 分类特征处理。

last_model_params = score_catboost_model({}, True)
R2 score: 0.9334(0.0009)
RMSE score: 1659(17)

我们将保存具有默认分类特征参数的模型的度量,以供进一步比较。

一键编码最大尺寸

我们尝试的第一件事是让 CatBoost 对我们所有的分类特征使用一键编码(我们数据集中的最大分类特征基数是 1118 < 2000). The documentation says, that for the features for which one-hot encoding is used no other encodings are computed.

默认值是:

  • 如果在 CPU 上以成对计分模式进行训练,则不适用
  • 255 如果在 GPU 上执行训练,并且所选 Ctr 类型需要在训练期间不可用的目标数据
  • 10 如果在分级模式下进行训练
  • 2 如果以上条件都不满足
model_params = score_catboost_model({'one_hot_max_size' : 2000})R2 score: 0.9392(0.0029) +0.6% compared to default parameters
RMSE score: 1584(28) -4.5% compared to default parameters

模型尺寸正则化

如果训练数据具有分类特征,该参数会影响模型大小。

关于分类特征的信息对模型的最终大小有很大的贡献。为模型中使用的每个分类特征存储从分类特征值散列到一些统计值的映射。特定要素的映射大小取决于该要素采用的唯一值的数量。

因此,当选择树中的分裂以减小模型的最终尺寸时,可以在最终模型中考虑分类特征的潜在权重。选择最佳分割时,会计算所有分割分数,然后选择分数最高的分割。但是在选择具有最佳分数的分割之前,所有分数根据以下公式变化:

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

s_new 是根据某个分类特征或组合特征进行分割的新得分, s_old 是根据该特征进行分割的旧得分, u 是该特征的唯一值的数量, U 是所有特征中所有值的最大值, Mmodel_size_reg参数的值。

这种正则化在 GPU 上的工作方式略有不同:特性组合的正则化程度比在 CPU 上更高。因为组合的 CPU 成本等于训练数据集中存在的这些组合中不同特征值的数量。在 GPU 上,一个组合的成本等于该组合所有可能的不同值的数量。例如,如果组合包含两个分类要素 c1 和 c2,则成本将为 c1 中的#categories * C2 中的# categories,即使该组合中的许多值可能不在数据集中。

让我们尝试将模型大小正则化系数设置为 0——因此我们允许我们的模型使用尽可能多的分类特征及其组合。

model_params = score_catboost_model({'model_size_reg': 0})R2 score: 0.9360(0.0014) +0.3% compared to default parameters
RMSE score: 1626(26) -2.0% compared to default parametersmodel_params = score_catboost_model({'model_size_reg': 1})R2 score: 0.9327(0.0020) -0.1% compared to default parameters
RMSE score: 1667(30) +0.5% compared to default parameters

为了检查此设置如何影响模型的大小,我们将编写一个函数,给定参数字典将训练一个模型,将其保存在一个文件中,并返回模型的权重:

model_size_reg_0 = weight_model({'model_size_reg': 0})model_size_reg_1 = weight_model({'model_size_reg': 1})model_size_reg_0/model_size_reg_112.689550532622183

正如我们可以看到的,具有强正则化的模型几乎比没有正则化的模型小 13 倍。

组合的功能数量

组合的功能数量

特征组合:注意,几个分类特征的任何组合都可以被认为是一个新的组合。例如,假设任务是音乐推荐,我们有两个分类特征:用户 ID 和音乐流派。比如说,一些用户更喜欢摇滚乐。当我们将用户 ID 和音乐流派转换为数字特征时,我们会丢失这些信息。两个功能的组合解决了这个问题,并提供了一个新的强大功能。然而,组合的数量随着数据集中分类特征的数量呈指数增长,因此不可能在算法中考虑所有的组合。当为当前树构造新的分裂时,CatBoost 以贪婪的方式考虑组合。对于树中的第一次拆分,不考虑任何组合。对于接下来的分割,CatBoost 将当前树中存在的所有组合和分类特征与数据集中的所有分类特征相结合。组合值被动态转换成数字。CatBoost 还以下列方式生成数字和分类特征的组合:树中选择的所有拆分都被视为具有两个值的分类,并以与分类相同的方式用于组合。

可以组合的最大特征数。每个结果组合由一个或多个分类特征组成,并且可以选择性地包含以下形式的二进制特征:“数字特征>值”。对于 CPU 上的回归任务,默认值为 4。

虽然文档中没有提到,但该参数值必须小于或等于 15。(因为此参数应小于最大梯度推进树深度)。

model_params = score_catboost_model({'max_ctr_complexity': 6})R2 score: 0.9335(0.0016) +0.0% compared to default parameters
RMSE score: 1657(24) -0.2% compared to default parametersmodel_params = score_catboost_model({'max_ctr_complexity': 0})R2 score: 0.9286(0.0041) -0.5% compared to default parameters
RMSE score: 1716(30) +3.4% compared to default parameters

正如我们在数据集上看到的,模型的准确性差异并不显著。为了检查模型的大小是如何受到影响的,我们将使用我们的函数对模型进行加权。

model_size_max_ctr_6 = weight_model({'max_ctr_complexity': 6})model_size_max_ctr_0 = weight_model({'max_ctr_complexity': 0})model_size_max_ctr_6/model_size_max_ctr_06.437194589788451

可以看出,可以组合多达 6 个特征的模型比根本不组合特征的模型重 6 倍。

有时间

启用此设置后,在将分类特征转换为数字特征的过程中,我们不会执行随机排列。当数据集的对象已经按时间排序时,这可能很有用。如果时间戳类型的列出现在输入数据中,则它用于确定对象的顺序。

model_params = score_catboost_model({'has_time': **True**})R2 score: 0.9174(0.0029) -1.7% compared to default parameters
RMSE score: 1847(29) +11.3% compared to default parameters

simple_ctrcombinations_ctr

simple_ctrcombinations_ctr都是提供分类特征编码类型规则的复杂参数。虽然simple_ctr负责处理最初出现在数据集中的分类要素,但是combinations_ctr会影响新要素的编码,这些新要素是 CatBoost 通过组合现有要素创建的。可用的编码方法以及simple_ctrcombinations_ctr的可能值都是相同的,所以我们不打算分开来看。但是当然,你可以在你的任务中分别调整它们!

无目标量化的编码

目标量化正在使用一些边界将浮点目标值转换为整数目标值。我们将首先考虑不需要这种转换的目标编码方法。

FloatTargetMeanValue(仅限 GPU)

第一个选项 FloatTargetMeanValue 是最直接的方法。分类变量的每个值被替换为放置在当前对象之前的相同类别的对象的目标平均值。

model_params = score_catboost_model(
{'simple_ctr' : 'FloatTargetMeanValue', 'combinations_ctr' : 'FloatTargetMeanValue', 'task_type' : 'GPU'})R2 score: 0.9183(0.0022) -1.6% compared to default parameters
RMSE score: 1837(32) +10.7% compared to default parameters

FeatureFreq(仅限 GPU)

第二个选项是 FeatureFreq 。分类特征值被替换为数据集中类别的频率。同样,只使用放置在当前对象之前的对象。

model_params = score_catboost_model(
{'simple_ctr' : 'FeatureFreq', 'combinations_ctr' : 'FeatureFreq', 'task_type' : 'GPU'})R2 score: 0.9170(0.0019) -1.8% compared to default parameters
RMSE score: 1852(12) +11.6% compared to default parameters

计数器

我们已经在“默认参数”一节中讨论了 Counter 方法,因为默认情况下,该方法用于创建特性编码。值得注意的是,如果我们直接将Counter传递给simple_ctr和/或combinations_ctr,CatBoost 将只使用计数器特性编码。

model_params = score_catboost_model({'simple_ctr' : 'Counter', 'combinations_ctr' : 'Counter'})R2 score: 0.9288(0.0014) -0.5% compared to default parameters
RMSE score: 1715(12) +3.3% compared to default parameters

CtrBorderCount参数

假设我们已经计算了分类变量的编码。这些编码是浮动的,它们是可比较的:在Counter的情况下,较大的编码值对应于更频繁的类别。但是,如果我们有大量的类别,相近类别编码之间的差异可能是由噪声引起的,我们不希望我们的模型区分相近的类别。出于这个原因,我们将浮点编码转换为 int 编码𝑖∈[0,𝑙]i∈[0,l].默认情况下CtrBorderCount=15设置意味着𝑙=14(15−1)l=14(15−1).我们可以尝试使用一个更大的值:

model_params = score_catboost_model({'combinations_ctr': 
                               ['Counter:CtrBorderCount=40:Prior=0.5/1'],
                                     'simple_ctr':                  ['Counter:CtrBorderCount=40:Prior=0.5/1']})R2 score: 0.9337(0.0013) -0.0% compared to default parameters
RMSE score: 1655(13) +0.2% compared to default parameters

二值化目标平均值

第二种方法BinarizedTargetMeanValue非常类似于目标编码,除了我们使用 beans 值的和而不是精确目标值的和。其对应于以下公式:

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

其中:

  • countInClass 是该分类特征的标签值整数之和与最大标签值整数 k 的比值。
  • totalCount 是特征值与当前值匹配的对象总数。
  • 先验是一个由起始参数定义的数(常数)。
model_params = score_catboost_model(
{'combinations_ctr':'BinarizedTargetMeanValue', 'simple_ctr': 'BinarizedTargetMeanValue'})R2 score: 0.9312(0.0008) -0.2% compared to default parameters
RMSE score: 1685(20) +1.6% compared to default parameters{k:v **for** k, v **in** model_params.items() **if** k **in** ctr_parameters}{'combinations_ctr': ['BinarizedTargetMeanValue:CtrBorderCount=15:CtrBorderType=Uniform:TargetBorderCount=1:TargetBorderType=MinEntropy:Prior=0/1:Prior=0.5/1:Prior=1/1'],
 'simple_ctr': ['BinarizedTargetMeanValue:CtrBorderCount=15:CtrBorderType=Uniform:TargetBorderCount=1:TargetBorderType=MinEntropy:Prior=0/1:Prior=0.5/1:Prior=1/1']}

在使用BinarizedTargetMeanValue方法的同时,我们还可以微调PriorCtrBorderCount(用于量化类别特征编码的边界数量)。默认情况下,CtrBorderCount =15,0、0.5 和 1 Prior值用于构建三种不同的编码。

目标量化编码

桶和边框

现在我们继续设置需要目标量化的编码方法。首选是BordersvsBuckets。这两者之间的区别非常简单。两者都由以下公式描述:

对于Borders的【0, k -1】中的 iBuckets的【0, k 中的 i :

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

其中 k 是由参数TargetBorderCount调节的边界数量,

totalCount 是同一类别的对象数量。之前的由参数prior定义。唯一不同的是对于Borders countInClass 是离散化目标值大于 i 的类别的对象数,而对于Buckets countInClass 是离散化目标值等于i 的类别的对象数。

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

让我们看一个小例子:我们有两类物体显示为太阳和月亮。我们将计算边界和桶的分类特征编码。

边框:我们有两个边框(对应于TargetBorderCount=2),所以需要计算 2 个编码。假设我们的先验是 0.5

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

桶:【0,】k 中的 i 创建 k +1 个桶。因此,如果我们选择Buckets,相同的参数值TargetBorderCount=2会从每个分类特征中创建更多的特征。

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

重要提示!这个例子只是用来说明 *Borders* *Buckets* 的区别,整个数据集用来计算 countInClass 和 totalCount。实际上,CatBoost 仅使用在使用当前对象之前放置的对象。

让我们看看它在实践中是否有所不同:

model_params = score_catboost_model({'combinations_ctr': 'Borders',
                                     'simple_ctr': 'Borders'})R2 score: 0.9311(0.0017) -0.2% compared to default parameters
RMSE score: 1688(40) +1.7% compared to default parametersmodel_params = score_catboost_model({'combinations_ctr': 'Buckets',
                                     'simple_ctr': 'Buckets'})R2 score: 0.9314(0.0048) -0.2% compared to default parameters
RMSE score: 1682(49) +1.4% compared to default parameters

细心的读者可能记得,默认情况下,CatBoost 使用Borders分割创建一些特征,也使用Counter方法创建一些特征。当我们显式传递Borders选项时,不使用Counter方法。

一般情况下,建议使用Borders进行回归任务,使用Buckets进行多分类任务。

缺失值和新类别的处理

  • 如果测试集中有一个新类别从未出现在训练集中,会发生什么?答案是,由于𝑐𝑜𝑢𝑛𝑡𝐼𝑛𝐶𝑙𝑎𝑠𝑠𝑐𝑜𝑢𝑛𝑡𝐼𝑛𝐶𝑙𝑎𝑠𝑠等于零,先验被用于计算编码:

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

  • 同时,分类特征中缺失的值被替换为"None"字符串。那么具有丢失特征值的所有对象被视为一个新的类别。

边界数量

边界或桶的数量可通过TargetBorderCount参数控制。默认情况下,我们只有一个边框,让我们看看有更多的边框是否有帮助:

model_params = score_catboost_model({'combinations_ctr': 'Borders:TargetBorderCount=4',
                                     'simple_ctr': 'Borders:TargetBorderCount=4'})R2 score: 0.9356(0.0019) +0.2% compared to default parameters
RMSE score: 1631(9) -1.7% compared to default parameters

simple_ctrcombinations_ctr的默认值

默认情况下,CatBoost 使用多种编码技术对每个分类特征进行编码。

  • 首先,它使用带有一个目标边界TargetBorderCount =1 的Borders方法(在我们的示例中,对于每个分类特征,我们只想看看它是否会使汽车更贵)。获得的浮点编码被进一步离散成CtrBorderCount =15 个不同的值。Prior参数的三个值用于创建三种不同的编码:Prior=0/1:Prior=0.5/1:Prior=1/1
  • 同样,对于每个分类特征,我们用Counter方法创建一个编码。分类编码值边界的数量CtrBorderCount也等于 15,并且仅使用一个值Prior=0/1

我们总是可以用get_all_params()方法检查我们的模型所使用的参数。

last_model_params = score_catboost_model({}, True)
last_model_params['simple_ctr']['Borders:CtrBorderCount=15:CtrBorderType=Uniform:TargetBorderCount=1:TargetBorderType=MinEntropy:Prior=0/1:Prior=0.5/1:Prior=1/1',
 'Counter:CtrBorderCount=15:CtrBorderType=Uniform:Prior=0/1']last_model_params['combinations_ctr']['Borders:CtrBorderCount=15:CtrBorderType=Uniform:TargetBorderCount=1:TargetBorderType=MinEntropy:Prior=0/1:Prior=0.5/1:Prior=1/1',
 'Counter:CtrBorderCount=15:CtrBorderType=Uniform:Prior=0/1']

通过per_feature_ctr参数控制个别功能

我想在本教程中谈的下一件事是用参数per_feature_ctr对不同的特性使用不同的编码方法。当您知道您的某个功能比其他功能更重要时,这可能会很有用。例如,我们可以增加模型名称特征的目标边界数量:

model_params = score_catboost_model({'per_feature_ctr': ['1:Borders:TargetBorderCount=10:Prior=0/1'] })R2 score: 0.9361(0.0005) +0.3% compared to default parameters
RMSE score: 1625(28) -2.1% compared to default parameters

其他参数

计数器计算方法

该参数决定是否使用验证数据集(通过fit方法的参数eval_set提供)来估计Counter的类别频率。默认为Full,使用验证数据集中的对象;传递SkipTest值以忽略来自我们score_catboost_model函数中验证集的对象,我们在训练期间根本不给 CatBoost 验证数据集,因此为了检查该方法的效果,我们将使用训练/测试分割。

model = CatBoostRegressor(custom_metric= ['R2', 'RMSE'], learning_rate=0.1, n_estimators=4500, 
                          counter_calc_method='Full')
model.fit(train_pool, eval_set=test_pool, verbose=**False**)
r2_res = r2_score(df_test.price_usd.values, model.predict(test_pool))
rmse_res = mean_squared_error(df_test.price_usd.values, model.predict(test_pool))print('Counter Calculation Method Full: R2=**{:.4f}** RMSE=**{:.0f}**'.format(r2_res, rmse_res))Counter Calculation Method Full: R2=0.9334 RMSE=2817626model = CatBoostRegressor(custom_metric= ['R2', 'RMSE'], learning_rate=0.1, n_estimators=4500, 
                          counter_calc_method='SkipTest')
model.fit(train_pool, eval_set=test_pool, verbose=**False**)
r2_res = r2_score(df_test.price_usd.values, model.predict(test_pool))
rmse_res = mean_squared_error(df_test.price_usd.values, model.predict(test_pool))print('Counter Calculation Method SkipTest: R2=**{:.4f}** RMSE=**{:.0f}**'.format(r2_res, rmse_res))Counter Calculation Method SkipTest: R2=0.9344 RMSE=2777802

目标量化的边界数量

用于分类特征目标量化的最大边界数。回归任务的默认值为 1。

让我们试一试相当多的边界:

model_params = score_catboost_model({'ctr_target_border_count': 10})R2 score: 0.9375(0.0046) +0.4% compared to default parameters
RMSE score: 1606(73) -3.2% compared to default parameters

分类值限制

此参数控制模型使用的最常见分类特征值的数量。如果我们有 n 个唯一类别和ctr_leaf_count_limit = m 个唯一类别,我们只保留最频繁类别中对象的分类特征值。对于剩余类别中的对象,我们用None替换分类特征值。

该参数的默认值是None -所有分类特征值都被保留。

model_params = score_catboost_model({'ctr_leaf_count_limit' : 5})R2 score: 0.8278(0.0236) -11.3% compared to default parameters
RMSE score: 2661(187) +60.4% compared to default parameters

哎呀!在我们的数据集上,它破坏了模型性能。

存储简单的分类特征

如果对之前的参数ctr_leaf_count_limit进行此设置,则只会影响 CatBoost 通过组合初始要素创建的分类要素,而数据集中存在的初始分类要素不会受到影响。当参数ctr_leaf_count_limitNone时,参数store_all_simple_ctr无效。

model_params = score_catboost_model({'store_all_simple_ctr' : **True**, 'ctr_leaf_count_limit' : 5})R2 score: 0.8971(0.0070) -3.9% compared to default parameters
RMSE score: 2060(74) +24.2% compared to default parameters

内部特征重要性

对一个分类特征使用几种编码是很常见的。例如,默认情况下,CatBoost 为每个分类特征创建 4 种不同的编码(参见“simple_ctr 和 combinations_ctr 的默认值”一节)。当我们调用get_feature_importances方法时,我们得到分类特征的所有编码重要性的集合。这是因为在实践中,我们通常只想比较数据集中不同特征的总体有用性。

然而,如果我们想知道哪种编码最适合我们呢?为此,我们需要获得**内部特性重要性。**目前,它仅在命令行版本的 CatBoost 库中可用。你可以在这里找到关于安装的细节,在本教程找到一个如何用命令行版本训练模型的例子。

要使用命令行版本训练模型,我们首先需要创建一个列描述文件:

descr = ['Categ' if i in categorical_features_names else 'Auxiliary' for i in df.columns]
descr[14] = 'Target'
pd.Series(descr).to_csv('train.cd', sep='\t', header=None)

然后训练一个模型:

catboost fit --learn-set cars.csv --loss-function RMSE --learning-rate 0.1 --iterations 4500 --delimiter=',' --has-header --column-description train.cd

然后创建一个内部特征重要性文件:catboost fstr -m model.bin --cd train.cd --fstr-type InternalFeatureImportance -o feature_strength.tsv

在我们的例子中,这个文件的内容如下:

9.318442186    transmission   7.675430604    {model_name} prior_num=1 prior_denom=1 targetborder=0 type=Borders  
3.04782682    {model_name} prior_num=0 prior_denom=1 targetborder=0 type=Borders  
2.951546528    {model_name} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders   
2.939078189    {body_type} prior_num=0 prior_denom=1 targetborder=0 type=Borders   
2.666138982    {state, transmission} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders   
2.431465565    {body_type} prior_num=1 prior_denom=1 targetborder=0 type=Borders   
2.059354431    {manufacturer_name} prior_num=0 prior_denom=1 targetborder=0 type=Counter   
1.946443049    {state} prior_num=1 prior_denom=1 targetborder=0 type=Borders   
1.932116622    {color} prior_num=1 prior_denom=1 targetborder=0 type=Borders   
1.633469855    {color} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders   
1.561168441    {manufacturer_name} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders   
1.419944596    {manufacturer_name} prior_num=0 prior_denom=1 targetborder=0 type=Borders   
1.3323198    {body_type} prior_num=0 prior_denom=1 targetborder=0 type=Counter   1.068973258    {color} prior_num=0 prior_denom=1 targetborder=0 type=Counter   
1.038663366    {manufacturer_name} prior_num=1 prior_denom=1 targetborder=0 type=Borders   
1.001434874    {manufacturer_name, body_type} prior_num=0 prior_denom=1 targetborder=0 type=Counter   
0.9012036663    {body_type} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders   
0.8805961369    {manufacturer_name, body_type} prior_num=1 prior_denom=1 targetborder=0 type=Borders   
0.8796937131    {drivetrain} prior_num=0 prior_denom=1 targetborder=0 type=Borders   
...   
...   
1.476546485e-05    {engine_fuel, engine_type} prior_num=0 prior_denom=1 targetborder=0 type=Borders   
7.417408934e-06    {engine_type, body_type, state, location_region} prior_num=0.5 prior_denom=1 targetborder=0 type=Borders
  • 我们可以看到,最重要的特征是传输;
  • 然后我们有 3 个Borders类型编码用于具有不同先验的model_name分类特征;
  • 然后对body_type特征进行编码;
  • 然后我们有一个 CatBoost 从statetransmission特征的组合中创建的分类特征

一个有趣的观察结果是,对于像model_name这样的一些特征,最有用的是Border类型的编码,而对于其他特征,例如manufacturer_name,最有用的编码是通过Counter方法获得的。

logging_level=Info

了解你的模型如何工作的另一种方法是用logging_level=Info参数进行训练。此设置允许我们查看为每棵树选择的特征分割:

model = CatBoostRegressor(custom_metric= ['R2', 'RMSE'], learning_rate=0.3, n_estimators=5)
model.fit(train_pool, eval_set=test_pool, logging_level='Info')year_produced, bin=47 score 669154.1979
{drivetrain} pr0 tb0 type1, border=10 score 754651.9724
year_produced, bin=56 score 809503.2502
year_produced, bin=51 score 856912.7803
engine_capacity, bin=24 score 888794.1978
{state} pr1 tb0 type0, border=12 score 901338.6173
0:	learn: 5040.7980368	test: 5141.1143627	best: 5141.1143627 (0)	total: 17.9ms	remaining: 71.7msyear_produced, bin=49 score 474289.2398
engine_capacity, bin=14 score 565290.1728
year_produced, bin=54 score 615593.891
year_produced, bin=43 score 638265.472
{state} pr1 tb0 type0, border=10 score 663225.8837
engine_capacity, bin=24 score 667635.803
1:	learn: 4071.9260223	test: 4162.4422665	best: 4162.4422665 (1)	total: 24.9ms	remaining: 37.3msyear_produced, bin=50 score 332853.7156
{body_type} pr2 tb0 type0, border=8 score 403465.931
{manufacturer_name} pr0 tb0 type0, border=7 score 428269.628
year_produced, bin=38 score 458860.027
feature_2, bin=0 score 474315.0996
year_produced, bin=54 score 485594.3961
2:	learn: 3475.0456278	test: 3544.0465297	best: 3544.0465297 (2)	total: 31.3ms	remaining: 20.9msyear_produced, bin=45 score 250517.4612
engine_capacity, bin=13 score 290570.2886
year_produced, bin=55 score 340482.1423
{manufacturer_name} pr1 tb0 type0, border=6 score 352029.1735
feature_1, bin=0 score 368528.2728
year_produced, bin=50 score 376011.7075
3:	learn: 3066.9757921	test: 3128.4648163	best: 3128.4648163 (3)	total: 37.4ms	remaining: 9.35msyear_produced, bin=46 score 184224.3588
feature_6, bin=0 score 214268.3547
{body_type} pr0 tb0 type1, border=5 score 238951.9169
{state} pr1 tb0 type0, border=9 score 260941.1746
transmission, value=1 score 275871.0414
{engine_fuel} pr1 tb0 type0, border=7 score 289133.3086
4:	learn: 2797.0109121	test: 2864.4763038	best: 2864.4763038 (4)	total: 42.8ms	remaining: 0usbestTest = 2864.476304
bestIteration = 4

对于数字特征,格式如下:

特征名称、所选分割的索引、分割分数

示例:year_produced, bin=47 score 669154.1979

分类特征的格式为:

特征名称、先验、目标边界、编码类型、分类特征边界、分割分数

例子:{state} pr1 tb0 type0, border=12 score 901338.6173

为了方便起见,分类特征名称写在括号{}中

二元分类和多元分类任务的参数调整。

在我们的教程中,我们正在进行回归任务,所以我想对二元分类和多分类任务的分类参数调整做一些说明。

  • 对于**二元分类,**参数调整与回归任务非常相似,除了增加TargetBorderCount参数值通常是无用的(除非你传递概率作为目标)。
  • 多分类任务中,我们应该记住,通常我们在类上没有任何自然顺序,所以不推荐使用FloatTargetMeanValueBinarizedTargetMeanValue编码。如果你的训练时间太长,你可以试着将TargetBorderCount设置为一个比默认的 n_classes - 1 更低的值,如果有办法将你的一些类合并的话。

结论

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

恭喜所有读完本教程的人:)正如我们看到的,CatBoost 包中与分类特征处理相关的可调参数的数量令人印象深刻。我们学会了如何控制它们,我非常希望这些知识能够帮助您在涉及分类数据的任务中获得最佳结果!

演练:对欺诈性信用卡交易进行分类

原文:https://towardsdatascience.com/categorizing-fraudulent-credit-card-transactions-8c6490645fd7?source=collection_archive---------49-----------------------

尝试各种分类器模型并深入研究 XG Boost

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

Pexels.com卡罗琳娜·格拉博斯卡的照片

简介:

作为 Metis 数据科学训练营的一名学生,我选择探索欺诈卡交易作为我的第二个个人项目。这个项目有三个需求:用 SQL 从 postgreSQL 数据库中查询数据,开发一个分类模型,以及创建一个交互式可视化。我发现 postgreSQL 和交互式可视化组件相当简单,所以这篇文章的大部分讨论了一个可用模型的开发,但是,我包含了其他两个组件的一些见解和技巧。此外,查看 Github 库了解项目背后的所有代码。

背景:

在寻找一些有趣的数据进行分析后,我在 Kaggle 上偶然发现了这个比赛。电子商务支付解决方案公司 Vesta Corporation 收集了一些信息。包含卡交易信息的 csv 文件,包括交易金额、卡类型、购买浏览器、一些其他各种基本信息,以及该公司设计的但在数据描述中未定义的 300 多项功能。目标包含在名为“isFraud”的列中,用 1 定义欺诈交易,用 0 定义有效交易。与。手里拿着 csv 文件,是时候将它们放入 postgreSQL 数据库并将这些信息转化为见解了。

在深入探讨之前,我想先介绍一下这个项目:

  • SQL 技能(postgreSQL、SQLAlchemy、Psycopg2)
  • 分类建模(逻辑回归、XG Boost、随机森林等等)
  • 交互式可视化(Streamlit)

步骤 1:使用 postgreSQL 🗄

正如我前面提到的,这个项目的一个要求是使用 SQL 来查询数据。将数据放入。csv 文件,我可以将它们转换成数据帧,然后放入 SQL 数据库。

代码如下,我将讨论它的全部含义。首先,我阅读了。csv 文件转换成数据帧,然后创建一个引擎来连接本地 postgreSQL 数据库,我将它命名为“project3”。这个 SQLAlchemy 引擎是整个代码块的关键。它允许 jupyter 笔记本与 postgreSQL 交互,并在给定的数据库中创建表。还有,这些。csv 文件包含多种类型(对象、整型、浮点型等)。),而且 SQLAlchemy 能够解释 DataFrame 并创建具有相应数据类型的列的方式令人惊叹。此外,它使这个过程比使用命令行快得多(更大。csv 文件超过 300 列)。

*# First, turn those csv files into DataFrames.*train_identity = pd.read_csv('../Project-3/train_identity.csv')train_transaction = pd.read_csv('../Project-3/train_transaction.csv')# Create a connection to the project3 postgreSQL database.engine = create_engine(‘postgresql://[USERNAME]:[PASSWORD]@localhost:5432/project3’)# Turn the DataFrames into tables in the postgreSQL databasetable_name = 'train_ident'train_identity.to_sql(table_name,
engine,
*if_exists*='replace',
*index*=False,
*chunksize*=500)table_name = 'train_trans'train_transaction.to_sql(table_name,
engine,
*if_exists*='replace',
*index*=False,
*chunksize*=500)

这是该项目的大部分 SQL 组件。我不会在这方面做更多的讨论,但我会发布连接两个表的更复杂的 SQL 查询来进一步研究数据。

mastercard_full = pd.read_sql(
"""SELECT * FROM train_trans LEFT JOIN train_ident ON train_trans.”TransactionID” = train_ident.”TransactionID” WHERE train_trans.card4=’mastercard’""", *con*=engine)

第二步:分类建模🎯

随着数据成功地存储在 postgreSQL 数据库中,然后查询到 DataFrame 中,我从一些基本的 EDA 开始,并很快理解了我的主要挑战:类不平衡。

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

作者图片

阶级不平衡的问题归结到如何决定模型的成功。如果我只关心准确性,我可以预测所有的交易都是有效的,并且有 97%的准确性。对于未经训练的人来说,97%的准确率看起来非常理想,但这意味着该模型预测欺诈交易的比例为 0%。这个 0%的指标被称为召回。回忆回答了这个问题:在所有欺诈交易中,模型正确预测的百分比是多少?另一方面,有效事务的召回将是 100%,因为所有有效事务都被正确预测为有效。因为大家都知道问题在于类别不平衡,而目标是预测欺诈性交易,所以衡量成功的标准就变成了欺诈性交易的召回率和整体准确性。

那么,我是如何解决阶级不平衡的问题的呢?有几种方法可以解决类不平衡问题,但我选择关注过采样。我探索的三种方法是 RandomOverSampler、SMOTE 和 ADASYN。这些方法中的每一种都采用少数类并对其进行过采样,直到它与多数类平衡。RandomOverSampler 随机复制少数类中的数据点。合成少数过采样技术(SMOTE)在少数类中创建新点,但使用线性插值和 K-最近邻,因此它是一种更高级的过采样技术。最后,自适应合成采样(ADASYN)根据密度分布在少数类中创建新点。

关于代码,实现这些过采样技术非常简单,如下所示。值得注意的是,训练数据是过采样的,然后用于拟合模型,从而得到整体更好的模型。

# RandomOverSampler
ros = RandomOverSampler(*random_state*=0)
X_tr_sam, y_tr_sam = ros.fit_sample(X_train,y_train)# SMOTE
X_smoted, y_smoted = SMOTE(*random_state*=42).fit_sample(X_train,y_train)# ADASYN
X_adasyn, y_adasyn = ADASYN(*random_state*=42).fit_sample(X_train,y_train)

评估二元分类问题的另一个常用指标是 ROC 曲线和曲线下面积(AUC)。下面是三条 ROC 曲线,对应于不同的过度拟合方法和我想要测试的几个分类器模型。很明显,Random Forest 和 XG Boost 是最好的模型,它们也是集合模型,这表明了集合模型在整体上创建更好的模型的卓越质量。

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

作者图片

利用这些视觉效果和度量标准,为前进创造了更清晰的愿景。我决定用随机过采样来研究 XG Boost 分类器。此外,值得注意的是,XG Boost 的性能比随机森林分类器稍差,但是,我选择 XG Boost 是因为 Kaggler 大肆宣传 XG Boost,所以我想更深入地研究这种特定类型的建模。

至于特性和特性工程,最好查看笔记本了解更多信息。关于 XG 增强,我非常兴奋地调整超参数以增加 ROC AUC 分数,从而增加模型召回。为了找到最佳的超参数,我查看了文档,以找到要调整的具体参数。参数 max_depth、min_child_weight 和 gamma 与模型复杂度相关,而 colsample_bytree 和 subsample 与处理噪声的模型相关。在使用 GridSearchCV 之后,我找到了这些参数的最优值。GridSearchCV 是一个非常密集的过程,所以由于计算机的压力,我分别运行我的参数,同时运行所有的参数可能更好。

# Choose the parameters to tunecv_params = {'max_depth': [4,5,6], 'min_child_weight': [1,2,3], 'gamma': [0,1,2]}# Run gridsearchxgbc1 = GridSearchCV(*estimator*=xgb, *param_grid*=cv_params,*scoring*=’roc_auc’)xgbc1.fit(X_tr_sam, y_tr_sam)# Observe the best parametersxgbc1.best_params_
{'gamma': 2, 'max_depth': 6, 'min_child_weight': 1}# Repeat with other parameterscv_params = {'subsample': [0.5,0.75,1], 'colsample_bytree': [0.5,0.75,1]}fix_params = {'gamma': 2, 'max_depth': 6, 'min_child_weight': 1}xgbc = GridSearchCV(*estimator*=XGBClassifier(**fix_params), *param_grid*=cv_params,*scoring*='roc_auc')xgbc.fit(X_tr_sam, y_tr_sam)xgbc.best_params_{'colsample_bytree': 1, 'subsample': 0.75}

随着数据过采样(以对抗阶级不平衡),特征的选择和设计,以及模型参数的调整,是时候看看结果了。下图结合了 ROC 曲线和混淆矩阵。混淆矩阵是另一种轻松查看分类模型结果的方式。首先,AUC 得分为 0.96,比上面 ROC 曲线中显示的任何模型都好。关于混淆矩阵,很容易看出模型哪里工作得好,哪里不理想。至于这个项目的目标,在 1949 个欺诈交易中有 1589 个被正确预测似乎非常好,但是还能做什么呢?

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

大多数(如果不是全部的话)分类模型输出特定预测的概率。通常有一个概率阈值参数,它可以告诉模型在哪里截断正预测。对于 XG Boost,我无法找出一种方法来调整模型中的概率阈值,但使用…

xgb.predict_proba(X_test)

…输出一个概率数组,描述有问题的特定点被分类为欺诈的概率。我将重点放在这个预测概率数组上,作为 Streamlit 应用程序的基础。

第三部分:streamlit 应用

Streamlit 是一个为编程新手创建应用程序的神奇工具。由于我今年才开始大量编写代码,并重点关注 python,因此跳入高级 flask、html、d3 或任何更深入的开发语言和工具似乎有点超出了这个简短分类项目的范围。幸运的是,作为 python 程序员,Steamlit 非常容易使用,生成的应用程序看起来很专业。

该应用程序的代码在这个 python 文件中,但我将贯穿我最终应用程序的基本概念。如果一家银行要使用这个模型,我想提供一个助手来确定这个模型的概率阈值。由于阈值非常低,所有欺诈性交易都会被正确预测,但许多有效交易会被错误地预测为欺诈。另一方面,更高的概率阈值将导致更多的欺诈交易被分类为有效交易。该应用程序允许银行查看在不同阈值下会发生什么,并选择适合其需求的特定阈值。

第一个图表显示了召回率和精确度与阈值之间的关系,金色线条代表所选的阈值。第一张图表下方是召回和通过识别欺诈交易节省的金额。在这些数字的更下方是一个混淆矩阵,提供了一个额外的视觉辅助来帮助确定最佳概率阈值。

作者提供的视频

结论:📗

在处理分类问题时,类不平衡是一个常见的问题,在处理大型(或小型)数据集时,过采样是解决这个问题的一个很好的方法。另外,python 使得用基本代码比较多个模型,然后用 GridSearchCV 调优超参数变得很容易。这些技术对于数据科学家早期学习非常重要,因为有了这些基础知识,模型改进可以很快完成。现在,我觉得有必要回到我的以前的项目,调整超参数并测试更多的模型,以增加该项目的有效性。无论如何,这里有一些关于这个项目的基本要点:

  • 学习 SQL!
  • 总是花时间探索数据
  • 尽早开发一个 MVP,并在该模型的基础上进行构建
  • Streamlit 让创建应用变得简单
  • 给利益相关者一个容易理解的解决方案或解释

查看 Github 仓库以获得关于这个项目的更多信息——我真的喜欢让我的笔记本容易跟随。此外,如果您有任何问题或意见,请联系我们。

我真的很喜欢我的数据科学之旅,并希望继续分享我的学习经历。请随意查看关于我的第二个项目的博客,并在我继续探索数据科学世界时回来获取更多更新。

伸手:
LinkedIn|Twitter

猫与狗——5 分钟内你的第二个端到端 CNN 分类器

原文:https://towardsdatascience.com/cats-vs-dogs-your-second-end-to-end-cnn-classifier-in-5-minutes-9adfbde08a09?source=collection_archive---------53-----------------------

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

Unsplash 上由 Tran Mau Tri Tam 拍照

第二个分类器?!

听起来很奇怪吗?所以,这是我 DIY CNN 模型系列的第二篇博客。你可以在这里查看第一个分类器。如果你没有读过我以前的文章,我强烈建议你读一读,因为我将在它的基础上进行构建。这个博客的格式将保持不变。我会给你一个 Colab 文件,你必须运行它(没有如果没有但是),然后再继续。

所以现在开始吧— 运行它!🏃‍♀️

是的,我知道这需要一些时间来运行。在那之前,请随意阅读。我总是希望你在前进之前运行它的原因是——它让你感觉更依赖于手头的问题陈述,并且倾向于给出更好的见解。所以更多的钱!

猫的人还是狗的人?

猫和狗的数据集没有和 Keras 打包在一起。它是由 Kaggle 在 2013 年的一次计算机视觉比赛中提供的。当时他们能够达到 95%的准确率。很酷,是吧?

在本文中,我们将重点关注 3 种不同的模型和实现更高精度的方法。酷吗?让我们开始吧。

模型 1 —基本模型

结果:~74%准确率

这和我们之前的分类模型一模一样。不过,根据问题的性质,会有一些变化。让我们简单讨论一下。

数据预处理

你有图像,但是模型在矩阵上工作!对!因此,这是几乎所有基于 CNN 的模型都需要的一步。上一篇文章中已经讨论了其中的大部分内容,所以不再赘述。所以:

1。加载图像
2。将 JPEG 内容解码为 RGB 像素网格。
3。将图像大小调整为 150
150 像素(以缩小图像大小)。
4。将像素值(0 到 255 之间)重新缩放到区间(0,1)区间*

Keras 图像数据生成器

通常,我不会深入研究实现逻辑,但这一点需要特别提及。上面的部分可能看起来工作量很大,对吗?!但是,这个美丽的 Keras 构造真的可以帮助你完成你的工作。

它在 Python 生成器上工作。如果你不熟悉它,强烈建议你这么做。简而言之,生成器是一种特殊的迭代器,工作起来很慢。与列表不同,它们不将内容存储在内存中,而是在需要时生成内容。这些迭代器不会阻塞你的内存,而是在需要的时候使用它。很神奇的东西,对吧?

卷积层++

有人可能会说——不,这个模型和之前的不一样。它有 3 层以上的回旋。罪名成立!是的,你能想出一个理由吗?

我们的手写分类器具有[28 * 28]的矩阵大小,而这里我们处理的是[150 * 150]的矩阵大小。所以,因为我们处理更大的图像和更复杂的问题,我们倾向于增加更多的层。这主要是为了在输入到达展平图层时减小输入的大小。

此外,随着越来越深入卷积层,该模型可以检测到更加复杂的模式。因此,这也增加了网络的容量。

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

准确率:~74%

模型 2 —解决过度拟合问题

结果:84%准确率

如果你看到上图中的结果,你会怎么想?这是一个经典的过度拟合案例。随着时间的推移,训练精度呈线性增长,但测试精度却停滞在 70%左右。让我们分析一些处理过度拟合的常用方法。

脱落层

这是一种正则化技术,其中随机选择的神经元在训练过程中被完全忽略。他们只是被随机“丢弃”。因此,一旦训练开始,模型就开始基于所提供的数据学习专门的特征。可能发生的情况是,这些特征对于训练数据可能变得过于具体,并且可能在测试数据上完全失败。因此,为了增加一层随机性并使其更通用,采用了这种方法。

数据扩充

过度拟合通常发生在学习的训练样本太少的时候。因此,我们可以合理地假设,给定无限量的数据,我们的模型永远不会过度拟合,因为它已经通过接触各种图像学习得很好。

因此,通过这种技术,我们试图通过将我们的训练数据随机转换成其他可信的图像来创建更多的训练数据。您可以旋转图像、翻转图像、缩放图像等,并创建一个全新的不同图像,为您的模型提供更多不同的训练数据集。

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

准确度— 84%

模型 3 —预训练的 CNN

结果:94%准确率

为什么要重新发明轮子?!当有人已经做到了,为什么还要从头开始呢?这是这种方法背后的主要直觉。

特征抽出

正如我们前面提到的,表现最好的网络是那些经过无限数据训练的网络。比方说,某个很有权力的人,在 ImageNet 上训练了一个网络(这个数据集包含数百万张动物图片)。我们应该能够直接重用这个在许多动物身上训练的特定模型来检测我们的猫和狗的用例。

但通常情况下,只建议重用卷积层,而不是内部 FC 层。主要原因是在卷积层学习的内核可能有点通用,可以很容易地重用。比方说,检测眼睛和鼻子的能力可以很容易地被我们的系统重用。

但是,在 FC 层中学习的权重可能更具体地针对问题的性质,并且可能对我们的特定用例没有太大价值。比方说,当需要检测 100 类动物时,这些 FC 砝码可能表现良好,但当只需要检测 2 类动物时可能会失败(根据我们的用例)。

微调

随着卷积层深度的增加,检测复杂特征的能力也增加。因此,我们可以说,在初始层中,它可能只是检测一条垂直线或水平线或某种颜色,但随着你向前移动到层中,它可能最终会检测到更复杂的特征,如猫的胡须或狗的尾巴或斑马的鳞片等。

因此,在使用预训练的网络时,而不是复制所有的卷积层,可以认为只是按原样采用初始层,并训练(微调)另一个深度卷积层。复杂的内核可能不适合我们的用例。

比方说,一个内部卷积层,当对数百万只动物进行训练时,学会了一个可以检测斑马纹的内核,但在我们的猫和狗的用例中,我们可能根本不需要它。因此,我们可能应该重复使用初始层,但可以微调内部回旋。

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

准确度— 94%

我希望这给你一个很好的概述,可以部署的想法,以提高 CNN 网络的准确性。今天就到这里吧,伙计们!

大部分内容都受到了《用 Python 进行深度学习》这本书的极大启发。这是一本免费的书。如果有机会,一定要把这本书读完。

Python 中的因果影响 R 包

原文:https://towardsdatascience.com/causal-impact-r-package-in-python-bc005f63f4c2?source=collection_archive---------20-----------------------

因果关系

如何在您的 Python 环境中运行 Google 的 CausalImpact R 包

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

斯蒂芬·菲利普斯-Hostreviews.co.uk 在 Unsplash拍摄的照片

CausalImpact 是 Google 开发的一个 R 包,用于使用贝叶斯结构时间序列模型进行因果推断。这里可以找到 R 版

简而言之,这个软件包所做的是做出反事实的预测。换句话说,如果干预从未发生,在平行宇宙中会发生什么?这里有一个直接来自谷歌网站的快速示例:“给定一个响应时间序列(例如,点击量)和一组控制时间序列(例如,在未受影响的市场上的点击量或在其他网站上的点击量),该软件包构建了一个贝叶斯结构时间序列模型。然后,该模型被用于尝试和预测反事实,即,如果干预从未发生,那么干预后的反应指标将如何演变。”

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

因果影响 1.2.1,Brodersen 等人,《应用统计学年鉴》(2015)。http://google.github.io/CausalImpact/

图像描述:图像(原始)的 A 部分用连续的黑线显示了我们正在监控的事物的时间序列。蓝色虚线部分是反事实预测。垂直灰线是进行干预的时刻。我们可以观察到,从那时起,蓝线和黑线逐渐分开。B 部分(逐点)说明了这些线随时间的差异,这实质上是我们感兴趣的因果效应,而 C 部分(累积)是随时间的累积差异。

我知道您可以使用 R,但是对于 Python 爱好者来说,我不知道有什么等价的包。当然,有一些库实现了原始论文的一部分。通过检查一些 Python 实现,我注意到了结果的不同。长话短说,在这里您可以查看如何从 python 运行这个包。类似地,这种方法可以推广到任何 R 包。

对我有用的是创建一个新的 Conda 环境,预装了 Python 库和 core R 包。这里有一个例子:conda create -n r_env numpy pandas statsmodels r-essentials r-base

创造环境需要一些时间。另外,请注意,Jupyter notebook 需要进一步配置,所以我倾向于在任何编程编辑器中编辑代码,并从命令行运行。

我们还需要的是为我们做所有工作的rpy2。它是 R 语言的 python 接口。pip install rpy2就行。

如下加载所有库:

**#rpy2 lib**
from rpy2.robjects.packages import importr
import rpy2.robjects as robjects
from rpy2.robjects import pandas2ri
from rpy2.robjects import Formula
import rpy2.robjects.packages as rpackages
import rpy2.robjects.vectors as StrVector
from rpy2.ipython.ggplot import image_png**#typical python libs**
import numpy as np
import pandas as pd
import datetime**#arma**
from statsmodels.tsa.arima_process import ArmaProcess

创建一个至少有 3 列的 Pandas dataframe,1 列用于datetime(下面我们将使其成为一个索引),一个预测值x1或更多(x2,x3,x4,…,xn)和一个响应变量y。这假定您已经准备好数据供使用,否则,您可以如下创建一些数据:

**# Creating synthetic data - skip this if you are running it on your # own data - The data generation is taken from #**[**https://github.com/dafiti/causalimpact**](https://github.com/dafiti/causalimpact)ar = np.array([1, 0.9])
ma = np.array([1])
arma_process = ArmaProcess(ar, ma)
X = 100 + arma_process.generate_sample(nsample=100)
y = 1.2 * X + np.random.normal(size=100)
y[70:] += 5base = datetime.datetime.today()
dt = [base - datetime.timedelta(days=x) for x in range(100)]df = pd.DataFrame({'y': y, 'x1': X,'date':dt}, columns=['y', 'x1','date'])

如上所述,确保将datetime作为索引。

**#make datetime an index to the df**
df.set_index('date',inplace=True)

根据dataframe中的索引datetime定义干预前的时间段和干预后的时间段。

**#Set pre and post intervention periods**
pre_period = [0, 69]
post_period = [70, 99]**#R conversion**
pre_period=robjects.FloatVector(pre_period)
post_period=robjects.FloatVector(post_period)

这将为您提供从周期开始到干预(pre_period)和从干预到数据中最后一天(post_period)之间的时间间隔。

**#Load R libraries from within Python - R interface** utils=rpackages.importr('utils')
utils.chooseCRANmirror(ind=1)
packnames=('CausalImpact','bsts') # any other R library required
names_to_install = [x for x in packnames if not rpackages.isinstalled(x)]**#Load package required to install R packages**
from rpy2.robjects.vectors import StrVectorif len(names_to_install) > 0:
    utils.install_packages(StrVector(names_to_install))

这可能需要一些时间;喝点咖啡,再来点。

但是现在我们在这里。准备对我们的数据进行因果推断。

robjects.numpy2ri.activate()
pandas2ri.activate()
rdf=robjects.conversion.py2rpy(df)
causalimpact=importr('CausalImpact')
impact=causalimpact.CausalImpact(rdf,pre_period,post_period)summary_func=robjects.r('function(x) summary(x)')
summary_func(impact)**#Summary with descriptive report**
summary_report_func=robjects.r('function(x) summary(x,"report")')
summary_report_func(impact)**#Create causality plot**
img_file='causalimpact.png'
rstr="""
library(ggplot2)
function(x,y){
p<-plot(x)
ggsave(y,plot=p)
}"""rfunc=robjects.r(rstr)
rfunc(impact,img_file)

有关因果影响包的更多选项和讨论,请参见以下内容:

[## 包含“因果影响”的帖子

搜索类型搜索语法标签[tag]确切的“单词在此”作者用户:1234 用户:我(你的)得分得分:3 (3+)得分:0…

stats.stackexchange.com](https://stats.stackexchange.com/search?q=causalimpact) [## 因果影响

这个包是做什么的?这个 R 包实现了一种方法来估计因果效应的设计…

google.github.io](http://google.github.io/CausalImpact/CausalImpact.html)

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

数据科学家的因果推理备忘单

原文:https://towardsdatascience.com/causal-inference-cheat-sheet-for-data-scientists-a1d97b98d515?source=collection_archive---------35-----------------------

为什么因果洞察力对商业很重要,以及如何使用你的数据来推断因果关系

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

对于任何数据科学团队来说,无论其规模大小,能够做出因果声明都是一个关键的商业价值。快速分析(换句话说,描述性统计)是任何优秀数据分析师的面包和黄油,他们与产品团队一起快速循环,以了解他们的用户。但有时会出现一些需要更精确答案的重要问题。商业价值有时意味着区分什么是真正的洞察力,什么是偶然的噪音。与临时营销材料相比,见解将站得住脚。换句话说因果关系

回答这些问题时,需要绝对的严谨。未能理解关键机制可能意味着错过重要的发现,推出错误版本的产品,并最终使您的企业损失数百万美元或重要的机会。
微软实验团队前主管罗恩·科哈维有一个的著名例子:改变 Amazon.com 上展示信用卡优惠的地方为公司带来了数百万的收入。

在过去的 6 年中,科技行业已经开始接受这一趋势,使得因果推理成为数据科学中的一个热门话题。网飞微软和谷歌都围绕因果方法的一些变体建立了完整的团队。因果分析也是(终于!)在纯 AI 领域获得大量牵引力。因此,了解因果推理方法能为你和你的企业做些什么变得越来越重要。

证据阶梯的因果推理层次

因此,因果推理阶梯小抄!除了对数据科学家本身的价值,我过去还成功地向内部客户展示了这张幻灯片,以解释我们是如何处理数据并得出结论的。

“阶梯”分类解释了每种方法将提供给你的级证据。越高,就越容易确保您的方法得到的结果是真实的和可重复的——缺点是实验的设置会更复杂。例如,设置 A/B 测试通常需要专门的框架和工程资源。
沿着阶梯往下走的方法在设置上需要较少的努力(想想:观察数据),但在分析的严密性上需要更多的努力。确保你的分析有真实的发现,而不仅仅是评论一些噪音(或者更糟,完全是错误的),这是一个叫做稳健性检查的过程。这可以说是任何因果分析方法中最重要的部分。如果我是你的评审,你的方法越靠下,我需要的健壮性检查就越多🙂

我还想强调的是,较低级别的方法并没有降低价值——事实恰恰相反!它们是允许使用观察数据得出结论的卓越方法,如果像过去 10 年中为这些方法做出重大贡献的苏珊·阿塞圭多·因本斯这样的人有一天被授予诺贝尔奖,我也不会感到惊讶!

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

梯级 1 —科学实验

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

阶梯的第一级是典型的科学实验。你可能在中学甚至小学都学过的那种。为了解释科学实验应该如何进行,我的生物老师让我们从一个盒子里取出种子,把它们分成两组,然后把它们种在两个罐子里。老师坚持让两个罐子里的条件完全相同:同样数量的种子,同样湿润的土地,等等。我们的目标是测量光对植物生长的影响,所以我们把一个罐子放在窗户附近,把另一个锁在壁橱里。两个星期后,我们所有靠近窗户的罐子都长出了漂亮的小芽,而我们放在壁橱里的那些几乎没有长出来。
暴露在光线下是这两个罐子的唯一区别,老师解释道,我们被允许得出结论光线不足导致植物无法生长。

听起来够简单吧?当你想确定原因时,这基本上是最严格的了。坏消息是,只有当你对你的治疗组(接受光线的那个)和你的对照组(橱柜里的那个)都有一定程度的控制时,这种方法才适用。足够的控制至少所有的条件都是严格相同的但是你正在试验的一个参数(在这种情况下是光)。显然,这不适用于社会科学,也不适用于数据科学。

那么你可能会问,为什么我要把它放在这篇文章里?因为这是参考方法。所有的因果推断方法在某种程度上都是为了重现这种简单的方法,如果你严格遵守中学老师解释的规则,你就不能得出结论。

梯级 2 —统计实验(又名 A/B 测试)

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

可能是科技界最著名的因果推断方法:A/B 测试,也就是我们生物统计学朋友的随机对照试验。统计实验背后的想法是依靠随机性和样本大小来减轻无法将你的治疗组和对照组置于完全相同的条件下。基本统计定理,如大数定律中心极限定理贝叶斯推理保证了这一点,并提供了一种从您收集的数据中推断估计值及其精度的方法。

可以说,实验平台应该是任何数据科学团队应该投资的第一批项目之一(当然,一旦所有的基础水平都到位)。在科技公司建立实验文化的影响已经被很好地记录下来,并为谷歌、亚马逊、微软等公司带来收益。数十亿美元。

当然,尽管理论上相当可靠,A/B 测试也有自己的一套警告。罗恩·科哈维和微软实验平台的其他创始成员撰写的这份白皮书非常有用。

梯级 3 —准实验

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

尽管 A/B 测试(或 RCT)可能很棒,但在某些情况下,它们就是无法执行。这可能是因为缺乏工具(技术中的一个常见情况是当一个特定的框架缺乏适当的工具来超级快速地建立一个实验,并且测试变得适得其反),道德问题,或者仅仅是因为你想事后研究一些数据。幸运的是,如果你处于其中一种情况,有些方法仍然能够得到一个因素的因果估计。在第三章中,我们谈论了准实验(也称为自然实验)的迷人世界。

准实验是这样一种情况,你的治疗组和对照组被一个自然过程分割,这个过程不是真正的随机的,但可以被认为足够接近于计算估计值。在实践中,这意味着你将有不同的方法,这些方法将对应于关于你有多“接近”A/B 测试情形的不同假设。自然实验的著名例子包括:利用越战征兵彩票来估计成为一名老兵对你收入的影响,或者利用新泽西州和宾夕法尼亚州的边界来研究最低工资对经济的影响。

现在让我给你一个公平的警告:当你开始寻找准实验时,你会很快被它迷住,并开始考虑在不可能的地方聪明地收集数据…现在你不能说你没有被警告过😜我有不少朋友因为对自然实验的热爱而被计量经济学的职业所吸引。

准实验世界中最流行的方法是:差异中的差异(最常见的方法,根据因果推理混合磁带的作者 Scott Cunnigham 的说法);回归不连续设计匹配工具变量(这是一个绝对出色的构造,但在实践中很少有用)。如果你能够观察(即收集数据)解释治疗和控制如何分离的所有因素,那么一个简单的线性回归包括所有因素将会给出好的结果

梯级 4——反事实的世界

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

最后,你有时会想尝试从纯粹的观察数据中发现因果因素。技术领域的一个经典例子是,在没有进行 A/B 测试的情况下,评估一项新功能的效果,并且没有任何一组人没有收到您可以用作对照的功能:

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

略微改编自因果影响的文档

也许你在想:等等……你是说我们可以简单地查看前后的数据,然后做出结论吗?嗯,诀窍在于,通常做一个严格的分析或者甚至计算一个估计都不是那么简单。这里的想法是创建一个模型,允许计算一个反事实控制组。反事实意味着“如果这个特征不存在,会发生什么”。如果你有一个用户数量的模型,你有足够的信心做出一些稳健的预测,那么你基本上拥有了一切

不过有一个问题。当使用反事实方法时,你的预测的质量是关键。在不涉及太多技术细节的情况下,这意味着你的模型不仅要足够准确,还需要“理解”什么潜在因素在驱动你目前观察到的情况。如果一个与你的最新部署无关的混杂因素发生了变化(例如经济气候),你不希望把这种变化归因于你的特性。如果你想做出因果关系的声明,你的模型也需要理解这一点。

这就是为什么在使用反事实时鲁棒性检查如此重要。一些很酷的因果推理库,比如微软的道为什么会自动为你做这些检查😲像在 R 包 tipr 中实现的灵敏度方法对于检查一些假设也非常有用。最后,我怎么能在不提及 DAGs 的情况下写一篇关于因果推理的完整文章呢?它们是一种广泛使用的工具,用来陈述你的假设,尤其是在梯级 4 方法的情况下。

(快速补充说明:现在,由于前所未有的新冠肺炎危机,很可能各种应用中使用的大多数预测模型都已经过时了。显然,那些不能用于反事实的因果分析)

从技术上讲,梯级 4 的方法看起来很像梯级 3 的方法,只是做了一些小的改动。例如, synthetic diff-in-diff 是 diff-in-diff 和 matching 的组合。对于时间序列数据来说, CausalImpact 是一个非常酷的知名 R 包。 causalTree 是另一个值得关注的有趣方法。更一般地说,由领域专家精心制作并经过严格测试的模型是仅使用反事实控制组进行因果推断的最佳工具。

希望这份备忘单能帮助您找到正确的因果分析方法,并对您的业务产生影响!请在我们的 Twitter 上或评论中告诉我们您的最佳#causalwins!

原载于 2020 年 4 月 29 日 http://nc233.com**的

钢铁厂的因果推理

原文:https://towardsdatascience.com/causal-inference-for-a-steel-mill-1e4dff991501?source=collection_archive---------40-----------------------

如何为钢铁厂创建一个结合了人类专业知识和因果推理原理的数据科学产品。

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

照片由 severstal.com 谢维尔斯塔尔拍摄

我们的项目

我想分享我为圣彼得堡附近的谢韦尔钢铁厂创建数据科学产品的经验。我们在这家工厂生产 5 米宽的钢卷。例如,您可以用这种钢制造石油和天然气管道。作为输入,你发送一个 20 吨重的钢板,经过 15-30 次迭代后,钢板就变成了预期厚度的钢板。

下面是您可以观看的视频,以便更深入地了解这一过程:

在我们的项目之前,一个操作员习惯于为每次迭代手动选择一个速度,我们的目标是自动化这个过程。我们的模型现在工作在实时模式下,我们可以观察到模型的速度比人的速度快 5+ %。

为什么不能在每次迭代中选择最大可能的速度?速度越高,发动机上的电流(I)越高,如果电流超过阈值,发动机将停止工作以防止故障。因此,操作员选择速度时要考虑厚度、delta(迭代前后的厚度差)和其他参数。

数据

为简单起见,我们假设我们的数据中只有厚度、增量、速度和电流。

让我们的数据集中有 20000 次迭代。让我们从最小值等于 5、最大值等于 15 的均匀分布中生成厚度,并从最小值等于 1、最大值等于 4 的相同分布中生成增量。这意味着迭代前的金属厚度将在 5 到 15 之间,并且该厚度将在每次迭代中减少 1-4 点。

假设操作员根据以下规则选择速度:

df['speed'] = np.round(25 - 0.1 * df['thickness'] ** 0.9 - 4 * df['delta'] ** 1.1

此外,操作员可以以 5 %的概率选择高 1 个单位的速度,或者以相同的概率选择低 1 个单位的速度。

因此,我们的速度在 4.61–21.47 范围内。

让我们的电流服从这个规则:

df['I'] = 3000 + 1500 * (df['thickness'] ** 0.8 + 5 * df['delta'] ** 1.4) + 2000 * df['speed']

此外,让我们给电流增加一些噪声。噪声取自标准偏差等于 500 的正态分布。

因此,我们可以将数据集分成三个部分:训练集中的 15000 个观察值,2500 个开发,2500 个测试。

让电流过剩从 78647 个单位开始——这是一种罕见的情况,在我们的数据集中频率约为 0.3 %。

我们的研究都准备好了=)

直接法

你可以选择错误的方式来处理这个问题:选择一个强大的算法,在你的数据上训练它。例如,您可以使用梯度推进,训练它,改变速度,以提高生产率,不要超过电流。

我们选择了一个具有 12 个叶子、0.1 学习率和 500 棵树的算法,我们的 RMSE 在所有数据集(训练、开发和测试)上都是 500 50。该度量非常接近实际误差(500),因此我们可以说我们的算法接近完美。

但是只有当我们在同一个发行版中工作时,这才是正确的=)

让我们为测试集中的每个观察值选择一个速度。我们将从我们的分布中以最大速度开始,并且如果我们的电流预测小于临界速度减去三个标准偏差,我们将停止。作为标准差,我们取 600(我们的 500 50 和小保):

我们的新速度比旧速度提高了 30 %以上!伟大的结果!

让我们看看我们的引擎是如何工作的。由于我们知道虚拟世界中速度和电流之间的真实依赖关系,我们可以模拟我们的实验结果:

0.3168

因此,我们有 31.7 %的情况下,我们的电流高于临界,这是 100 倍以上的手动控制期间的频繁事件。这怎么可能呢?当我们训练我们的算法时,它没有任何关于速度和厚度与δ之间因果关系的信息。因此,我们的算法记住了速度、厚度和δ的每种组合的电流。如果我们改变速度,模型仍然看到旧的厚度和增量,并认为一切都会好起来。在这种情况下我们能做什么?

也许我们应该预测一个速度?

我们的目标是加快我们的工厂。我们知道,在类似的情况下,操作员可以做得更好或更差。因此,我们可以根据过去的最佳速度来预测速度!

对于这些类型的问题,k-NN 是一个完美的算法(我们可以通过它从过去准确地选择一个速度):

使用该算法,我们可以在电流过剩率仅为 0.24%的情况下实现 1.2 %的生产率增长:

1.0110062977330752
0.0024

伟大的结果!但是我们能做得更好吗?

因果推理

为了达到比我们从 k-NN 得到的更好的速度,我们应该提取速度和电流之间的真实相关性。当我们的数据集只包含相互依赖的观察值时,我们该如何做呢?我们可以开始一个实验,但是在真正的工厂里这是一个昂贵的方法。然而,我们可以使用因果推理方法来处理相互依赖关系。

我们想演示一种最简单的因果推理方法。这个方法很简单,但也很有效:

1)让我们创建一个模型,通过厚度和增量来预测速度。这个模型不应该太精确,但应该包含变量之间的依赖关系:

2)让我们根据该模型的预测来分割我们的数据集,因此在该数据集的每个部分都将有相似的预测。然后,我们在每个数据集上训练不同的线性回归模型:

3)现在我们的系数更接近 2000 年:它们从 1924 年到 2031 年变化。如果我们创建一个没有这种分裂的线性回归,我们将得到一个等于 1404 的系数,这将导致我们低估速度的影响,结果,电流过剩。为什么这种方法有效?我们可以假设,通过这些箱对我们的原始数据集的分割允许我们检测相对于速度具有相似厚度和增量值的集合。因此,我们可以更好地确定速度和电流之间的关系。

4)现在,我们可以取这些系数的最大值,并根据这些信息选择速度:

0.0004
1 . 56687 . 68686868661

电流过剩比以前少!我们已经实现了 30 %的速度提升!

5)我们看到结果与我们的测试集一致:

0.0008
1 . 58681 . 38686868661

它比直接方法好得多=)

结论

在这个虚拟例子中,我们有一个不公平的优势,因为我们知道速度和电流之间的真实依赖关系,所以我们可以看到当速度增加时,电流实际上会发生什么。在现实世界中,它是未知的。我们可以根据历史数据来测试我们的模型,但是在现实世界中,我们的模型可能会导致电流过剩并使工厂停止运转。所以,我们可以做两件简单的事情来防止风险:

1)我们可以从一小步一小步的速度开始改进。因此,当它明显不同时,我们可以足够接近我们的历史分布和轨迹。

2)此外,我们可以从一个不直接控制磨机速度的推荐系统开始。因此,运营商应在试点的第一阶段确认我们的建议。

在很短的时间内,操作员将开始对所提出的系统有信心,并且它可以随着速度的逐渐增加而转换到全自动化模式。今天,我们工厂的最大速度比一年前提高了约 33 %,平均速度提高了 5 %以上。

对了,如果你想了解更多的因果推断,可以从这个教程开始。

这篇文章的完整代码可以在这里找到。

数据科学家的因果推理:一种怀疑的观点

原文:https://towardsdatascience.com/causal-inference-for-data-scientists-a-skeptical-view-f8c294cfea0?source=collection_archive---------38-----------------------

因果推理如何以及为什么让我们失败

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

UnsplashNeONBRAND 拍摄的照片

介绍

这篇文章的目的是展示为什么因果推理是困难的,它如何让我们失败,以及为什么 DAGs 没有帮助。

机器学习从业者关心的是预测,很少关心解释。这是一种奢侈。我们甚至研究那些没有数据生成过程可以记录下来的问题。没有人相信一个根据莎士比亚戏剧训练出来的 LSTM 模式会奏效,因为它接近莎士比亚。然而它是有效的。

近年来,因果推理的新工具已经为更广泛的受众所用。这些工具承诺帮助非专家不仅预测,而且解释数据中的模式。有向无环图和 do-calculus 是其中最有影响力的。

人们喜欢闪亮的工具,这里面有危险。新工具的出现伴随着采用它们的热潮,伴随着一种处于先锋地位的感觉,伴随着新的机遇。这往往使它们变得不可靠:它们被误用,被更好的理论、设计或数据所替代。

在这篇文章中,我将重点放在有向无环图和 Python 库上,因为 Dag 在机器学习社区中非常流行。我提出的观点同样适用于潜在结果框架,或者任何其他表达因果关系的正式语言。

为什么理论上因果推理很难

因果推理依赖于因果假设。假设是允许从统计关联到因果关系的信念。

随机实验是因果推断的黄金标准,因为治疗任务是随机的,并且是物理操纵的:一组得到治疗,一组没有。这里的假设是简单明了的,通过设计是安全的,并且可以方便地进行辩护。

当无法控制治疗分配时,比如说观察数据,研究人员试图对其建模。这里的建模相当于说“我们假设在对年龄、性别、社会地位和吸烟进行调整后,跑步者和非跑步者彼此如此相似,就好像他们被随机分配到跑步中一样。”然后一个人可以在跑步上回归预期寿命,宣称‘跑步增加了 n %的预期寿命’,然后收工。

这种方法背后的逻辑是笨拙的。它隐含地假设我们确切地知道为什么人们开始跑步或长寿,唯一缺少的是我们试图估计的东西。一个不太可信、有点绕口的故事。此外,一个令人高兴的巧合是,我们模型的所有部分都有可用的经验代理,测量无误。最后,由于没有原则方法来检验选择模型在多大程度上接近真实的分配机制,所以它的所有假设都可以永远争论下去。

Jaas Sekhon [1]很好地总结了这种情况:

“如果没有实验、自然实验、不连续性或其他强有力的设计,再多的计量经济学或统计模型也无法让从相关性到因果关系的转变具有说服力”

为什么因果推理在实践中很难

实际例子更好地说明了上面提出的问题。虽然有很多,但我坚持三个,其中一个来自经济学、流行病学和政治学。

1986 年,罗伯特·拉隆德展示了计量经济学程序如何不能复制实验结果。他利用了一个实验,在这个实验中,个人被随机挑选到工作项目中。随机化让他能够估计一个项目对收入的无偏影响。他接着问:如果没有随机化,我们会得到同样的估计吗?为了模拟观察数据,拉隆德建立了几个非实验对照组。在比较估计值后,他得出结论,计量经济学方法无法复制实验结果[2]。

流行病学也有同样的问题。想想高密度脂蛋白胆固醇和心脏病的故事。人们认为“有益的胆固醇”可以预防冠心病。研究人员甚至宣称观察性研究对协变量调整是稳健的。然而几年后,随机实验证明高密度脂蛋白并不能保护你的心脏。对于流行病学来说,这种情况并不独特,许多流行病学的发现后来被随机对照研究推翻[3]。

民主增长研究是当年政治学的热门话题。研究人员将人均 GDP 或类似的指标放在等式的左边,民主放在右边,为了避免过于简单,他们在左边放了一堆控制指标:预期寿命、受教育程度、人口规模、外国直接投资等等。从 2006 年之前发表的 81 篇论文中的 470 个估计值来看,其中 16%显示了民主对增长的显著和负面影响,20%是负面但不显著的,38%是正面但仍然不显著的,38%的估计值是正面和显著的[4]。

这种模式很明显:无论研究人员对他们的观察研究多么自信,也不一定能让他们更接近真相。

为什么 DAGs 理论上不能解决问题

狗很棒。它们具有强大的表达能力和很好的推理特性:考虑到 do-calculus 的完备性,如果一个效应不能用 do-calculus 来识别,那么它在别处也不是不可定义的,至少在没有额外假设的情况下是如此。它们也是有教育意义的:试着画一个简单的仪器变量设置自己去看。

但这不是重点。关键是,dag 提供的好处发挥得太晚了,无法将我们从观察数据中的因果推断的恐惧中解救出来。的确,给定一个特定的图形,微积分告诉我们什么可以估计,什么不可以。然而,它没有告诉我们如何构建一个有意义的 DAG。

有一句乔治·博克斯的名言[5]:

“既然所有的模型都是错误的,科学家必须警惕什么是严重错误。国外有老虎,关心老鼠是不合适的。”

这里的可怕的老虎有太多可观察的变量来推理,天知道有多少不可观察的变量,我们用噪音测量的东西,我们甚至不能测量的东西。在这种情况下,真实的图形是未知的,当真实的图形是未知的时候,我们的推论是否正确的答案是“不知道”或者“不知道”。

考虑到这一点,当我们添加“如果正确的 DAG 为他们所知”[6],[7]时,关于 DAG 的许多事情变得不那么令人困惑:

“选择一组适当的协变量来控制混杂的任务已经简化为一个简单的“路障”难题,可通过简单的算法进行管理,【如果正确的 DAG 已知】

“如果我们能够从我们的观察数据中生成用于这个图的相同数据,但使其成为因果关系,这不是很好吗?借助现代因果推理方法,我们可以!【如果已知正确的 DAG】

为什么 Dag 在实践中不能解决问题

道为什么是一个伟大的图书馆。作者尽一切努力提醒用户因果推断是困难的。然而,根本问题依然存在。考虑下面的引用:

从概念上讲,DoWhy 是遵循两个指导原则创建的:明确询问因果假设,并测试估计值对违反这些假设的稳健性。

核心假设是所选择的 DAG 是众多可选 DAG 中的正确一个——这个假设没有健壮性检查。也很容易被侵犯。

让我们违反它。我将使用 DoWhy:因果推断的不同估计方法中描述的设置。有 5 个共因 W ,2 个仪器 Z ,一个二元处理 v0 ,其他所有效应都有界在[0,0.5 × βv0 以内,结果 y 完全由可观测变量集合决定。真实治疗效果 βv0 为 10。

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

来自https://Microsoft . github . io/dowhy/dowhy _ estimation _ methods . html

虽然有很多方法可以错误地指定一个模型,但是我将模拟一个非常简单的方法:缺少一个变量 U 。即使少了一个变量,人们也能画出 511 种不同的箭头组合。我将只坚持可能情况的子集: U →结果, U →结果和治疗, U →结果和随机常见原因, U →治疗和随机常见原因 U →随机仪器和治疗, U →随机仪器和结果。

在该教程中,作者使用了六个估计值,并设法通过线性回归、倾向得分分层、倾向得分匹配、倾向得分加权和工具变量五次接近 10。在我的模拟中,我将使用所有五种方法。我将单独分析 IVs,因为它们不依赖于后门标准。

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

后门估计量与未观测协变量 U

首先要注意的是,当违反后门标准时,就像在 U 影响治疗和结果的情况下,所有的估计都有明显的偏差。这并不奇怪——我们不能故意违反一个假设,并期望依赖它的程序能够工作。然而,给定的图离真正的图只有一个节点和两条边。这仍然足以扭曲估计。事实上,这个玩具示例是稳健的:所有其他影响都明显小于治疗影响,一次只有一个共同原因受到影响,只有一个不可观察的变量丢失,一切都测量无误。实际上,这种情况很少见。

另一件要注意的事情是,回归估计比倾向得分估计做得更好。这是因为回归更简单。例如,当治疗和共同原因受 U 影响时,回归是无偏的,因为在治疗和结果之间仍然没有开放路径。这不适用于倾向得分估计,因为倾向得分估计是两阶段过程,需要两组假设。为了估计倾向分数本身,一组可观察值 W 必须满足关于治疗的后门标准。因为在 W 和通过 U 的处理之间有一个开放路径。

现在,让我们转向工具变量。拥有一件好的乐器是很难得的。拥有两种乐器是前所未有的奢侈。在本教程的玩具示例中,有两个有效的乐器: Z0Z1 。我将设置 U 随机影响乐器,即使只有 Z0 用于估算。我还将设置 Z0Z1 为连续。

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

IV 估计量与未观察到的协变量 U

这里,与后门相反,当 U 影响治疗和结果时,估计值不会有显著偏差。IV 估计器如此稳健的原因是只有一个箭头从 Z0 指向 v0 。这有助于满足两个假设:(I)在 Z0v0 之间存在联系,以及(ii)从图中移除 v0 使得 Z0y 之间没有联系。那么,如果 Cov[ UZ0 ] = 0,Cov[ yZ0 ] ≠ 0,那么处理效果就是简单的 Cov[ yZ0 ]/Cov[ v0Z0

然而,如果从 UZ0 的箭头存在,那么 Cov[ UZ0 ] ≠ 0,这违反了排除限制假设(ii)——即 Z0 影响结果的唯一路径是通过治疗。在这个模拟中,这就是当 U 影响仪器 Z0 和结果的情况。

结论

有向无环图和 do-calculus 很可能是最有效的工具。它们不会帮助你从数据中获得因果结论,而这些结论并不存在。

参考

[1] J. S. Sekhon,用于比赛的鸦片制剂:因果推理的匹配方法 (2009),《政治学年度评论》,12,487–508。

[2] R. J. LaLonde,《用实验数据评估培训项目的计量经济学评估》 (1986),《美国经济评论》,604–620 页。

[3] N. Krieger 和 G. Davey Smith,回应:面对现实:我们的流行病学问题、方法和任务之间的生产性紧张 (2016),《国际流行病学杂志》,45(6),1852–1865。

[4] H. Doucouliagos 和 m . a . ulubaolu,民主和经济增长:一项荟萃分析 (2008 年),美国政治科学杂志,52(1),61-83。

[5] G. E. P. Box,科学与统计 (1976),美国统计协会杂志,71 (356),791-799

[6] J. Pearl,因果革命七次火花对机器学习的理论障碍 (2018),arXiv 预印本 arXiv:1801.04016。

[7] A. Kelleher 和 A. Sharma,介绍用于因果推断的 do 采样器 (2019),中

通过因果影响进行因果推理

原文:https://towardsdatascience.com/causal-inference-via-causalimpact-b0551b6dae92?source=collection_archive---------25-----------------------

CausalImpact 简介 Google 的一个开源包

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

图片由 PixaBay 上的 Jarmoluk 拍摄

什么是因果推断?

维基百科对它的定义是,根据一个结果发生的条件,得出一个关于因果联系的结论的过程。简而言之,因果推断是关于确定事件/变化对期望结果指标的影响。例如,如果一个新推出的营销活动对公司的销售产生了影响,或者一项新的法律对人们的行为产生了影响。虽然查看图表并比较前期和后期可以给出一个好主意,但在大多数情况下,这还不够好。尤其是在风险很大的情况下,例如数百万美元的营销预算。在医学或公共政策领域,确定事件的因果影响变得更加重要,因为这样的决定会影响数百万人。

因果推理的局限性:

假设发生了一个事件/处理,例如营销事件。让我们用这个药片来代表它:

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

治疗(由 Kate HliznitsovaUnsplash 拍摄)

通过观察我们知道这是治疗后的结果:

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

快乐的顾客(照片由 Lidya NadaUnsplash 上拍摄)

同样重要的是知道如果事件没有发生会发生什么。让我们用这个来表示否则会发生的结果:

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

悲伤的顾客(照片由马太·亨利Unsplash 上拍摄)

现在,通过比较两种可能的结果,我们可以推断或衡量事件的影响。我们可以说顾客高兴而不是悲伤是治疗的影响。

但现实世界中的问题是,我们如何做到这一点?我们如何同时知道发生了什么和可能发生了什么?在这种情况下,我们如何确定这种事件的因果推断?

让我们通过列表和比较各种场景来使其更加清晰:

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

表 1

假设有两个人,1 和 2,他们都暴露在治疗/事件中。通过让他们都接受治疗,我们也可以观察到所呈现的结果。但是我们不知道否则会有什么样的结果。

因为不可能知道它,我们能做的下一个最好的事情是估计其他可能的结果。

随机对照试验:

随机对照试验是确定治疗对预期结果的影响的科学实验。这通常用于医疗领域,并被视为黄金标准。在 RCT,人们被随机选择并分成两组,一组接受治疗,另一组不接受。由于所涉及的随机性,两组被认为是相似的,结果的任何差异都可以归因于治疗的差异。

再次将上述内容列表,以便更清楚地理解:

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

表 2

现在有四个人,随机抽取,分组。一半接受治疗,另一半不接受。两组的潜在结果是根据另一组的结果来估计的。

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

表 3

这种估计的结果就是通常所说的反事实。

RCT 的局限性:

虽然 RCT 是估计因果推断的最佳方法,但它并不一定适用于所有情况。也许指挥 RCT 太昂贵或太困难了。例如,在一个小国家进行 RCT 可能太困难,因为很难将其分为测试和控制。或者可能根本没有进行 RCT,现在正在进行回顾性研究以了解其影响。

在这种情况下,我们如何估计结果或反事实。

因果影响:

这是谷歌发布的一个库,用于在这种情况下进行因果推理。这个库只在 R 中可用,所以我将介绍它背后的逻辑以及它是如何工作的。它在合成控制的帮助下处理这种情况。

以这张瑞士法郎对欧元的图表为例。在很长一段时间里,瑞士法郎与欧元挂钩,币值稳定。但在 2015 年取消挂钩后,人民币汇率出现了大幅波动。在这种情况下,我们是否需要一个 RCT 来确定瑞士法郎如果没有与美元脱钩会是什么样子?

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

瑞士法郎/欧元

号码

简单地说,它将继续保持相对稳定,波动很小。这就是所谓的合成控制。这是可能的,因为这是一个简单的时间序列。

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

瑞士法郎/欧元

以这张图表为例:

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

这是一个受多种因素影响的更复杂的时间序列图。即使是像 LSTM 这样最先进的技术也很难准确预测。在这种情况下,我们如何预测反事实/合成控制?

协变量:

我们可以利用其他变量或协变量来帮助估计综合控制。这里的技巧是找到与期望指标相关的协变量*,但不受处理*的影响。

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

在上图中,y 是期望的指标,下面的 x1 和 x2 代表两个协变量。

在前期,我们训练并测试一个 ML 模型,以使用协变量预测所需的指标。

在后期,我们使用相同的模型来预测使用协变量的期望指标。预测的结果是这里的合成控制。然后将实际结果与合成对照进行比较,两者之间的差异被估计为事件对结果的影响。

型号选择:

以上就是 Google 的 CausalImpact 的工作原理简而言之。现在,您可以用各种模型进行试验,看看哪种模型有效。这可以通过将数据的前期划分为训练和验证部分以确定最佳模型来实现。

Google 软件包使用贝叶斯结构化时间序列模型。对于那些不知道贝叶斯统计如何工作的人,我写了一篇文章,你可以通过这个链接获得。简而言之,贝叶斯统计的工作原理是结合一个关于事物如何表现的先验信念,并随着时间的推移基于新的数据更新信念。

大多数时间序列模型,只是一个时间序列模型。他们不能考虑影响变化和波动的外部因素。贝叶斯时间序列模型的优势在于,它既考虑了时间序列方面,也考虑了影响结果的外部因素。在这种情况下,它通过将外部因素或协变量作为模型的先验来合并它们。通过这种方式,它可以在预测时考虑时间演变以及外部因素。

演示:

让我们看看 CausalImpact 包和一些虚拟数据的用法。

library(CausalImpact)set.seed(1)
x1 <- 100 + arima.sim(model = list(ar = 0.999), n = 100)
x2 <- 25 + arima.sim(model = list(ma = 0.246), n = 100)

我正在导入包,并在 arima.sim 命令的帮助下模拟两个时间序列。这些将是协变量。

y <- 1.2 * x1 + 0.8*x2 + rnorm(100)
y[71:100] <- y[71:100] + 10

这里我创建了一个新的时间序列 y,它是我们两个时间序列 x1 和 x2 的函数。对于最后的 30 次观察,我在数值上加了一个额外的数值来模拟一个事件/治疗的效果。

time.points <- seq.Date(as.Date("2020-01-01"), by = 1, length.out = 100)data <- zoo(cbind(y, x1, x2), time.points)matplot(data, type = "l")

将日期部分添加到序列中并绘制它。

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

数据图

pre.period <- as.Date(c("2020-01-01", "2020-03-10"))
post.period <- as.Date(c("2020-03-11", "2020-04-09"))impact <- CausalImpact(data, pre.period, post.period)

我根据添加治疗效果的位置定义前期和后期,然后将数据和信息传递给包。

plot(impact)

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

输出

第一个图叠加了原始数据和每个点的预测以及置信区间。

第二个图显示了每个点的原始数据和预测数据之间的差异以及置信区间。

第三个图通过对逐点差异求和来显示治疗的累积效果。

“summary(impact)”命令可用于提供表格形式的概述,而“summary(impact,“report”)则提供调查结果的书面报告。

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

一览表

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

总结报告

从上面我们可以更好的了解治疗的效果以及置信区间。该摘要甚至给出了由于治疗本身引起的变化的概率,以便我们知道它不是任何虚假的关系或变化。

结论:

因果推断是一个棘手的问题,我们数据科学家很少谈论。虽然这可能是因为我们通常不需要处理这个问题,但是知道如何解决这样的问题总是好的。在我们的工具箱里多一件工具,在我们的军火库里多一件武器,总不会有坏处。如果找到不受治疗影响的协变量的条件得到满足,这确实是在这种情况下使用的一种强有力的技术。

奖金:

我在参加 2019 年新加坡国立大学-NUHS 大学-麻省理工学院医疗保健数据马拉松时遇到了这项技术。我们的问题陈述围绕着估计一个事件对结果的影响,即因果推理。通过使用这个软件包,我们能够成功地完成我们的任务,并在数据马拉松比赛中获得第一名。下面是我们由最好的队友组成的团队的照片,没有他们,这一切都是不可能的:

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

你也可以在 LinkedIn 上和我联系。

回归的因果模型

原文:https://towardsdatascience.com/causal-models-for-regression-96270bf464e0?source=collection_archive---------7-----------------------

从相关到因果

回归是社会科学中应用最广泛的统计工具,并且在大多数现成的软件中都很容易得到。因为回归背后的统计数据非常简单,它鼓励新人在确保为他们的数据建立因果模型之前点击运行按钮。然而,理解数学是必要的,但不足以恰当地解释回归输出。事实上,回归从未揭示变量之间的因果关系,而只是解开了相关性的结构。

为了看到这一点,让我们考虑二元回归模型ŷ= a+bx。系数 b 揭示了相关系数 r(Y,X) 的相同信息,并捕获了 YX 之间的无条件关系∂ŷ/∂x
多元回归是一个完全不同的世界。多元系数揭示了 YX 之间的条件关系,即 Y 与其他回归变量的相关性被剔除后,两个变量的剩余相关性。在简单多元回归模型ŷ= a+bx+cz中,系数 b = ∂(Y|Z)/∂X 代表 YX 之间的条件或偏相关关系。我们通常的解释是“在保持 Z 不变的情况下, X 每增加一个单位,Y 就改变 b 个单位”。不幸的是,开始在回归模型中添加回归变量来解释因变量的更多变化是很诱人的。如果我们的目标是预测因变量的值,而不是对自变量和因变量之间的关系做出判断,这是好的——或者有点好,正如我们将看到的那样。逐步回归等算法将选择回归变量的过程自动化,以提高模型的预测能力,但这是以“可移植性”为代价的。通常情况下,所选择的回归变量并不依赖于因果模型,因此它们的解释能力是特定于特定的训练数据集的,并且不容易推广到其他数据集。因此,该模型不是“可移植的”。

偏相关和维恩图

为了理解为什么因果模型如此重要,我们需要理解回归系数是如何计算的。维恩图表示很方便,因为集合可以用来表示每个变量 YXZ 的总变化。对于二元回归,使用代表 YX 共变的区域 Y⋂X 计算系数 b 。两个回归量完全相关的情况是两个集合重叠的情况。
在多变量情况下,使用协变区域的子集 Y⋂X — (Y⋂Z)⋂X )计算回归系数 b 。同样, (Y⋂Z)⋂X 不计入 c 系数的计算中,尽管 YZ 都有这种变化。这是因为三个区域的交集 (Y⋂Z)⋂X 捕捉到了 Y 的总变化量,这是由两个回归量共同解释的*。将接合区归属于任一系数都是任意的。*

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

多元回归的文氏图表示

从这个回归的图解中有两个重要的收获。首先,由两个回归量 bc 解释的 Y 的总变化量不是总相关量 ρ(Y,X)ρ(Y,Z) 之和,而是等于或小于该值。当 (Y⋂Z)⋂X = ∅ 时,等式条件成立,这要求 XZ 不相关。在这种情况下,几乎没有实际可能性,二元回归中的回归系数bŷ= a+bx与多元回归的系数ŷ= a+bx+cz相同。
这让我们想到了维恩图的第二点,也是最重要的一点。回归只是数据集中变量之间静态关系的数学映射。增加模型的复杂性不会“增加”协变区域的大小,而只是决定了它们的哪些部分用于计算回归系数。没有变量之间关系的因果模型,将任何关系解释为因果总是没有根据的。实际上,多元回归中的系数 b 只代表 Y 中被 X 唯一解释的那部分变化。同样,多元系数 c 代表 Y 的变化,这是通过 Z 唯一解释

因果模型

为了从数据关系的静态表示转移到动态解释,我们需要一个因果模型。在社会科学中,因果模型通常是基于对人类行为的某种高级解释的理论。然而,一个因果模型不一定是一个理论,而是可以是任何一个在变量之间施加等级的地图。一个“层次结构”必须是沿着连接目标解释变量 X 和因变量 Y 的路径的变量的时间顺序和逻辑推导。请注意这里的推理哲学与预测哲学的不同之处:在推理中,我们总是对两个个体变量之间的关系感兴趣;相比之下,预测是在给定一组未定义的预测因子的情况下,预测一个变量的值。为了建立这种等级制度,需要解决以下问题(请注意提及的时间顺序):

  1. 在 X 确定之前确定的变量以及对 X 产生影响的变量有哪些?
  2. 在确定 X 的同时确定并对 Y 产生影响的变量有哪些?
  3. X 确定后确定的变量有哪些,对 XY 都有影响?

当定义了三种类型的变量时,因果模型是详尽的(请注意对相关性的引用):

  • *前件:*在 X 之前定义的与 X 相关的所有变量,无论是否与 Y 相关;
  • 调节者:与 X 定义相同且与 XY 都相关的所有变量;
  • 中介:所有在 X 定义后定义的,与 XY 都相关的变量。

调解人和主持人之间的区别有时有点棘手,但我不会在这里讨论它。
使用回归估计 XY 的影响,必须在估计方程中指定 X 的所有前因和所有调节变量;相反,调解人不能被包括在内。指定中介会将 b 折叠成对 XY 的直接影响的估计,这有时很有趣,但不应与 XY 的总体影响混淆。这种效应是通过多种途径产生的,这些途径有助于协方差区域 Y⋂X

因果模型:示例

是时候介绍一个例子了。教育研究人员对学生在标准化考试中成绩的决定因素感兴趣,如 SAT、ACT、GRE、PISA 等。SAT 考试是在 400 到 1600 分之间的连续范围内评估的,特别适合回归分析。一名研究人员可能认为在 12 年级上预科班对 SAT 成绩有积极的影响,并希望验证这一假设。她认为——这是非常需要理论的地方——还有两个潜在的变量驱动着这种关系,父母的收入和 12 年级的班级排名。为了简单起见,她假设父母的收入从出生到 12 年级没有变化。因为班级排名和预科班几乎是同时进行的,所以很难说哪个决定了另一个。在她的模型中,父母收入(图中的 SES)首先被确定,它与其他变量的关系显示在下面的因果模型中(图中的 GitHub 代码)。较高的社会经济地位提供了更多的教学资源,因此决定了班级排名和预科班的参与程度。此外,SES 对 SAT 考试成绩有直接影响,因为早期天赋决定了更高水平的认知能力——如果你对这个主题感兴趣,我建议查看 Hanushek 等人,2015 。因此,收入对 SAT 考试成绩有直接影响,也通过班级排名和考试预科班有间接影响。此外,研究人员假设班级排名影响学生参加预科班的可能性,因为那些对自己的能力越不确定的学生更有可能去上课。在这个模型中,SES 和班级排名是先行变量,因此应该在估计方程中指定。

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

因果模型:示例(1)

第二位研究人员认为,这种关系反过来也是如此。参加预科班的学生更有可能在他们 12 年级的班级中排名更高。SES 仍然是先行词,而班级排名调节预科班对 SAT 考试分数的影响。因此,为了获得预科班对 SAT 成绩的总体影响,班级排名必须从估计方程中忽略。如果班级排名被包括在内——并且假设没有其他的中介变量——研究者将会估计一个直接效应而不是一个总效应。

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

因果模型:示例(2)

这是一个简单的例子,它忽略了教育生产函数中的许多维度。此外,我们还可以有更多的方式来思考这些变量之间的关系,以及支持一个或另一个因果模型的不同理由。然而,这个例子表明,在进行回归分析之前,研究人员将手绑在因果模型上是多么重要。回归只不过是一种工具,用来部分剔除数据中的变异,但并不能说明变量之间关系的本质。

下图比较了两个因果模型确定的协方差区域,作为预科班对 SAT 考试分数影响的因果估计。重要的是,它们不会改变协方差的基本结构,而只是决定哪些部分与推断相关。因此,因果模型是变量之间关系的静态(相关)表示和它们的动态(因果)表示之间的映射。

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

因果模型:文氏图表示法(1)

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

因果模型:文氏图表示法(2)

结论

上面粗略的例子的好处是,它警告从业者不要使用逐步回归算法和其他选择方法进行推理。这些对机器学习来说都重要吗?答案是肯定的,确实如此。尽管回归在机器学习中的典型用途是用于预测任务,但数据科学家仍然希望生成“可移植”的模型(查看约万诺维奇等人,2019 了解更多关于可移植性的信息)。可移植模型是那些不过度特定于给定训练数据并且可以扩展到不同数据集的模型。确保可移植性的最佳方式是在可靠的因果模型上操作,这不需要任何牵强的社会科学理论,只需要一些合理的直觉。

因果影响和 R:分析时间序列干预

原文:https://towardsdatascience.com/causalimpact-and-r-analysing-time-series-interventions-27a5dfaec999?source=collection_archive---------25-----------------------

分析 R 中的时间序列干预

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

来源:图片来自 Pixabay

免责声明:本文是在“原样”的基础上编写的,没有担保。它旨在提供数据科学概念的概述,不应被解释为投资建议或任何其他类型的专业建议。

干预(或独立于时间序列的外部因素)通常会影响所述序列。

例如,营销活动可以影响公司未来的销售额。政府政策的改变会对经济活动产生重大影响。

分析干预的主要问题是,不可能分析如果干预没有发生会发生什么——至少不可能直接分析。

R 中的因果影响库允许通过使用单独的系列(不受干预影响的系列)作为协变量来分析干预效应。

我们的例子

2017 年 11 月,英国央行决定加息。当一个国家的中央银行决定以这种方式操纵利率时——货币的价值可能会受到影响——因为这种决定会影响投资者通过持有特定货币可以获得的收益率。

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

资料来源:tradingeconomics.com

在这方面,我们想研究一下利率上升是否会影响英镑/美元的价值。

为此,选择欧元/美元货币作为协变量——假设该货币不受干预的影响——因为欧洲央行在此期间没有加息。

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

资料来源:tradingeconomics.com

相关数据来自使用 Quandl 的 FRED 数据库。

这是两种货币的曲线图:

set.seed(1)
x1 <- eurusd$Value
y <- gbpusd$Value
data <- cbind(y, x1)dim(data)
head(data)
matplot(data, type = "l")

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

资料来源:RStudio

处理金融时间序列时,通常会将数据转换为对数格式。虽然这在分析具有显著不同价格范围的股票价格时是有意义的,但是在这个例子中数据是“按原样”分析的。

原因是货币数据的规模比大多数其他资产价格小得多,使用对数规模会使这些值非常接近,以至于在使用对数规模时,可以在原始系列中检测到的任何干预都可能无法检测到。

使用该数据,定义了前期后期,然后绘制数据。

pre.period <- c(1, 230)
post.period <- c(231, 249)impact <- CausalImpact(data, pre.period, post.period)
plot(impact)

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

资料来源:RStudio

将生成影响摘要:

> summary(impact)
Posterior inference {CausalImpact}Average           Cumulative     
Actual                   1.3               25.5           
Prediction (s.d.)        1.3 (0.0099)      25.4 (0.1878)  
95% CI                   [1.3, 1.4]        [25.1, 25.8]   

Absolute effect (s.d.)   0.0014 (0.0099)   0.0275 (0.1878)
95% CI                   [-0.018, 0.02]    [-0.349, 0.38] 

Relative effect (s.d.)   0.11% (0.74%)     0.11% (0.74%)  
95% CI                   [-1.4%, 1.5%]     [-1.4%, 1.5%]Posterior tail-area probability p:   0.44186
Posterior prob. of a causal effect:  56%For more details, type: summary(impact, "report")

我们看到,预测值与实际值(平均值)在 1.3 处是相同的,累积值之间只有微小的差异(25.5 比 25.4)。

因果效应的后验概率为 56%。

让我们仔细看看生成的摘要报告。其中一部分指出:

Although the intervention appears to have caused a positive effect, this effect is not statistically significant when considering the entire post-intervention period as a whole. Individual days or shorter stretches within the intervention period may of course still have had a significant effect, as indicated whenever the lower limit of the impact time series (lower plot) was above zero. The apparent effect could be the result of random fluctuations that are unrelated to the intervention. This is often the case when the intervention period is very long and includes much of the time when the effect has already worn off. It can also be the case when the intervention period is too short to distinguish the signal from the noise. Finally, failing to find a significant effect can happen when there are not enough control variables or when these variables do not correlate well with the response variable during the learning period.The probability of obtaining this effect by chance is p = 0.442\. This means the effect may be spurious and would generally not be considered statistically significant.

与 pycausalimpact 的比较 Python 版本

当用 pycausalimpact 分析同一个例子时,结果略有不同。

该模型定义如下:

>>> ci = CausalImpact(data, pre_period, post_period)
>>> print(ci.summary())
>>> print(ci.summary(output='report'))
>>> ci.plot()

下面是生成的输出:

Posterior Inference {Causal Impact}
                          Average            Cumulative
Actual                    1.34               25.46
Prediction (s.d.)         1.32 (0.0)         25.17 (0.08)
95% CI                    [1.32, 1.33]       [25.01, 25.33]Absolute effect (s.d.)    0.02 (0.0)         0.29 (0.08)
95% CI                    [0.01, 0.02]       [0.13, 0.45]Relative effect (s.d.)    1.15% (0.32%)      1.15% (0.32%)
95% CI                    [0.52%, 1.77%]     [0.52%, 1.77%]Posterior tail-area probability p: 0.0
Posterior prob. of a causal effect: 100.0%

与 R 中的模型不同,该模型预测了因果效应的 100%后验概率。

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

来源:Jupyter 笔记本输出

这个库的 R 和 Python 版本在分析干预的方式上有所不同。具体来说,R 更多地依赖于先验概率,从而将先前的知识纳入模型假设中,而 Python 更多地依赖于结构性时间序列组件的分析,以便最大化似然函数。

也就是说,假设先验现在设置为,即先验 _ 级别 _ sd =无

ci = CausalImpact(data, pre_period, post_period, prior_level_sd=None)
print(ci.summary())
print(ci.summary(output='report'))
ci.plot()

结果如下:

Posterior Inference {Causal Impact}
                          Average            Cumulative
Actual                    1.34               25.46
Prediction (s.d.)         1.35 (0.02)        25.57 (0.3)
95% CI                    [1.31, 1.38]       [24.98, 26.15]

Absolute effect (s.d.)    -0.01 (0.02)       -0.11 (0.3)
95% CI                    [-0.04, 0.02]      [-0.7, 0.47]

Relative effect (s.d.)    -0.45% (1.17%)     -0.45% (1.17%)
95% CI                    [-2.72%, 1.86%]    [-2.72%, 1.86%]

Posterior tail-area probability p: 0.37
Posterior prob. of a causal effect: 63.34%

该模型确实预测了比率从 1.34 到 1.35 的变化,但是该模型指出:

The probability of obtaining this effect by chance is p = 36.66%.
This means the effect may be spurious and would generally not be
considered statistically significant.

在这点上,先验的选择可以显著影响模型的假设,从而影响干预最终是否会被检测到。

结论

在本文中,您已经看到:

  • 因果关系在预测干预中的应用
  • R 和 Python 版本之间的区别
  • 先验假设在确定干预检测中的作用
  • 干预分析和总结报告的生成

非常感谢您的阅读,欢迎任何问题或反馈。

参考

因果关系和贝叶斯网络

原文:https://towardsdatascience.com/causality-and-bayesian-networks-fcd959d4c80a?source=collection_archive---------25-----------------------

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

艾莉娜·格鲁布尼亚克在 Unsplash 上的照片

思考因果关系是行动的必要条件,因此可以预测、预测、设计、监督、评估和诊断组织。由此产生的问题是:**因果关系的本质是什么?**因此,我们有一个可能性的宇宙,因果关系描述了必然发生的结果 E ,当某个原因 C 发生时。因此,我们对因果关系有一个确定的和普遍的方法。这种方法受到概率方法和贝叶斯逻辑的挑战。

概率方法:

“澳斯必须能够以此为特征,增加他们 effets 的概率”(德鲁埃,2007)。我不知道原因 c 的发生是否是影响 e 必然发生的必要条件,但是我可以说,以我有限的知识所带来的谨慎“原因 c 增加了其 effet E 的概率,因为条件概率 P(E|C)高于绝对概率 p(E )

我可以在不知道所有原因的情况下分析因果关系,或者假设所有原因的有限集都存在。我们不知道作为一个吸烟者的属性会属于 suffirait 产生肺癌的一组因素。最重要的是,不能保证这样一套存在”

这并不意味着所有的原因都是平等的,而是说它们是有条件的,我们对它们的了解是有限的。

贝叶斯网络的特征

BN 的独创性在于将图(因果)和概率耦合起来。贝叶斯网络由除了单向图之外的东西组成,并且一组箭头在作为图的顶点的一组变量上构成二元关系。在这篇文章中,我提出了进一步的解释:

[## 贝叶斯思维导论:从贝叶斯定理到贝叶斯网络

假设世界上存在一种非常罕见的疾病。你患这种疾病的几率只有千分之一。你想要…

towardsdatascience.com](/will-you-become-a-zombie-if-a-99-accuracy-test-result-positive-3da371f5134)

所以 BN 是:

  • 功能,BN 被顾问、项目负责人、管理者用于诊断或预测;
  • 专注于一个领域和一个功能。BN 允许我们在 effet 推断一组变量的因果关系
  • 一个 因果图(形式对象、逻辑等。)和基于特定人群(RB 的特定方面)的概率目标测试
  • 一个描述性模型,一个 BN 由引用不变量的节点组成,因此是一个宇宙、领域、专业等的描述性模型。它所关注的。这个描述模型由类别、属性、实例、集合关系组成。
  • 基于数据,BR 必然链接到数据源,而数据源又指的是描述性或概念性模型。换句话说,BN 和数据库之间需要一些互操作性;
  • 动态,BN 既是固定模型(机器学习)又是学习模型,在某种意义上,它可以随着时间的推移更好地学习其功能。

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

一个 BN 的例子,由我创作

BN 的优势在哪里?

  • have “因果经济学”:知道一个表示概率分布的无环定向图,可以大大减少定义这个分布所需的参数数量
  • 易读性:贝叶斯图中包含的信息如果用这种图形形式表示,而不是用自然语言表达,会更容易理解。应该注意的是,图形可读性与 BN 的整体形式以及其中确定的因果路径同样相关
  • 原因的可追溯性:[……]在 V 【变量集】中的任何变量,相对于其在 V 中的直接原因集而言,独立于 V 中的所有变量,它不是这些变量的因果祖先。这个假设被称为:因果马尔可夫条件”。这种情况使得通过构建 BN 来追溯原因(因此我提出了术语“可追溯性”)到独立的根本原因成为可能。但是,请注意,路径分析的目的不是首先确定一个变量是否引起另一个变量,而是量化一个变量对它引起的另一个变量的影响”
  • 代表性,BR 各组成部分的值指的是给定的人口(频率方法);
  • 可修改性,尽管具有通用性,但 BR 的组成部分的值可能会随着新数据的出现而改变。它们的外围成分可能也是如此,因为 rbd 是相加的(相对于相减);
  • 原因的共同性:通用描述模型使得将原因与类别和种类联系起来成为可能,这使得有可能通过聚类实现模块化因果方法,从而获得经济性和可读性。这就是你所做的,菲利普,通过将你的 BR 分层;

因果关系

因果关系的概率理论是概念分析。这是一个确定 A 导致 b 意味着什么的问题。

这些概率理论是对因果关系概念的一个方面的分析。换句话说,概率因果理论回答了一个关于一般因果关系的问题。这个问题可以这样来表达: 因果之间的共现关系是什么? 这个问题特别不同于 effet 的因果关系属于哪种现实的问题 (Drouet,2007)。

正如我们刚刚描述的那样,概率因果关系理论主要是作为一般因果关系的理论,而不是作为单一因果关系的理论(Drouet,2007)。一般因果关系和单一因果关系之间的区别是*“吸烟导致肺癌”“彼得的吸烟导致了他的肺癌”*之间的区别,或者是“跌倒导致骨折”和“我今天早上从楼梯上摔下来导致我的右手腕骨折”之间的区别。因此,一般因果关系是属性之间的关系——例如,坠落的属性和骨折的属性。

贝叶斯因果网络专门用于研究一般因果关系,而不是单一因果关系。这意味着 RB 箭头表达了一种通用的因果关系,必须有一组通用的原因和结果,这种通用保证了 RB 在时间上的结构不变性,其组成部分的量化只能用一定量的数据来完成;

使用 BN 建模时的挑战

第一个挑战与数据有关,其结构并不独立于国民银行。BN 相关算法旨在从概率中推断原因,并且独立于任何实验。事实上,通过贝叶斯网络推断因果知识的概率数据是概率观察数据。此外,根据定义,BN 被认为是从特定的前提中得出一般结论,而不管理论假设的形成。正是因为它不是从因果假设的公式化出发,所以 BN 推论可以是演绎的。当 BN 是从先前的一般描述性模型中推断出来时,情况就不是这样了。

所以我们有一个问题:BN、描述性模型和底层数据都是基于对世界的某种概念化的构造。我们并不是为一个特定世界之外的观察者提出一个通过客观数据可获得的 BN,而是为一个明确的行为者提供一个实用的工具。**总之,正确的 BN 背后确实有理论模型。**解决方法可能是将 BN 视为验证建模问题的一般模型的元素之一。BN 然后在这个一般模型设定的界限内,在一个微观宇宙中运作。

下一个挑战涉及 BN 作为有效推理工具必须满足的形式约束,即因果马尔可夫条件(因果关系中的所有变量都独立于所有其他变量,除了它们的父母或后代)。同样,拥有一个抽象的描述模型有助于满足这些约束。伊莎贝尔·德鲁埃(Isabelle Drouet)经过特别深入的逻辑推理,得出以下结论:“[……]使用贝叶斯网络进行因果推理只能有以下含义:将 BN 算法集成到一个假设演绎过程中[……]因果假设的说明最终总是基于理论考虑 s”。

结论

因此,BN 是检验由演绎工作产生的假设的特殊工具。这正是我们所做的:

[## 使用贝叶斯网络进行项目管理评估

这篇文章展示了五篇论文的工作,其中项目管理指标与项目绩效指标相关…

towardsdatascience.com](/using-bayesian-networks-for-project-management-evaluation-13a6eda50605)

因此,BN 并不代表一些倡导者提出的因果革命。然而,它们改变了我们构建和测试人工智能因果模型的方式。

参考书目

这篇文章是我对伊莎贝尔·杜洛埃作品的解读

如果你想继续阅读这样的故事,你可以在这里订阅!

加州消费者隐私法,PII 和 NLP

原文:https://towardsdatascience.com/ccpa-pii-and-nlp-b4165a92dc6d?source=collection_archive---------44-----------------------

CCPA 和隐私的 NLP

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

来源

加州消费者隐私法(CCPA)或 AB 375 于 2020 年 1 月 1 日生效,这是加利福尼亚州保护加州居民个人信息的法律。个人身份信息(PII)是可用于识别用户/客户的任何数据。通用数据保护条例(GDPR) 是 2018 年通过的一项欧盟法律,赋予欧盟居民类似的权利。随着世界各地企业收集用户数据的规模越来越大,我认为世界各地的不同政府将会通过更多这样的法律。

CCPA

CCPA 给予加州居民以下权利(按原样取自此处,第 2 节)→

**(1) The right of Californians to know what personal information is being collected about them.****(2) The right of Californians to know whether their personal information is sold or disclosed and to whom.****(3) The right of Californians to say no to the sale of personal information.****(4) The right of Californians to access their personal information.****(5) The right of Californians to equal service and price, even if they exercise their privacy rights.**

在数据泄露和其他违规的情况下,企业也必须支付罚款。

PII

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

来源

CCPA 的目标之一是保护消费者的 PII 信息,这意味着公司需要开发工具,以安全的方式理解和存储 PII 信息。自然语言处理(NLP)和自然语言理解(NLU)技术将发挥关键作用,因为收集的数据中有很大一部分是文本形式的,如姓名、电子邮件、地址、社会保险号、健康信息等。上图来自 Imperva 展示了 PII 的各种例子。PII 可以进一步细分为 PHI(受保护健康信息)数据和 PCI(支付卡行业)数据。

命名实体识别(NER)

NER 的任务是识别姓名、组织、地点、日期/时间等。NER 可用于识别文本数据中包含的一些个人信息。

Example- John moved from Arizona to California in December. 
Above sentence has below three entities -Person → JohnLocation → Arizona and CaliforniaDate/Time → December

因此,人们可以训练一个深度学习模型,将句子中的每个单词分类为命名实体之一或不是。然而,有几个库提供了用于 NER 任务的预训练模型。识别 PII 信息非常重要,因为它有助于快速检索此类信息、适当保护信息(通过加密等)以及控制对此类信息的访问。以下是一些可用于 NER 的库→

斯坦福核心 NLP

Stanford core NLP 是一个用 Java 编写的流行的 NLP 库,并附带了针对各种 NLP 任务的预训练,如英语和其他几种语言的 POS(词性)、NER 等。还有一个更新的项目 StanfordNLP 是一个 python 库,目前支持 POS、lemmatization 等,但不支持 NER。

空间

Spacy 是一个非常流行的 NLP 库,它的一些核心组件是用 C 语言编写的,这使得它非常快。它还带有针对 NER 的预训练模型以及针对英语和其他几种语言的其他任务。根据您的应用,Spacy 有不同尺寸的型号可供选择。模型在on notes 5 数据集上接受训练。这里我使用的是最大的英语语言模型——en _ core _ web _ LG(让我们看看如何使用 NER 的 Spacy

来源

在识别出实体之后,我们可以屏蔽它们(在上面的例子中,用“xxxx”得到“我的名字是 xxxx xxxx,我住在 xxxx ”),以保存用户的个人信息。基于本体注释 5 的空间预训练模型可以识别以下类型的实体→

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

空间本体注释 5 个实体— 来源

对于电话号码、电子邮件等 spacy 无法识别的信息,可以使用 regex。除了屏蔽 PII 信息,还可以加密以进一步保护它。

Presidio

Presidio 是微软专门为保护 PII 数据开发的库。它检测文本(以及图像)中的 PII 数据,然后通过编辑或加密来匿名化数据。它实际上默认使用空间 NER 模型来检测某些实体,也支持检测信用卡号码等。您还可以创建自定义的 PII 识别器。

来源

特定领域的 NER

然而,当我们想要识别特定领域的实体时,问题就来了,例如,如果您想要识别疾病或药物,在这种情况下,我们必须为自定义 NER 数据训练或微调现有模型。对于仅包含少量单词的实体,简单的查找可能有效,但是拼写错误等仍然会导致该方法失败!定制的 NER 模型可以使用空间天赋来训练。

联合学习

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

来源

联合学习 —联合学习是一种以分布式方式训练模型的技术,同时将原始数据保存在各个设备上以保护数据隐私。例如,在移动电话的情况下,设备下载现有的模型并针对设备特定的数据对其进行微调,因此设备数据永远不会被共享,所有个人训练数据都保留在设备上,并且更新也不会被共享。这也可以用树莓酱或其他设备来完成。分割学习是另一种无需共享任何原始数据即可训练模型的技术,与联合学习的区别在于模型是分割的,一些训练可以在服务器上完成。使用 Coral Edge TPU 或 NVidia Jetson Nano 等边缘设备也有助于保护用户数据的安全。

差分隐私 —差分隐私是一种在不共享用户个人信息的情况下共享数据集的技术。来自维基百科

***an algorithm is differentially private if an observer seeing its output cannot tell if a particular individual’s information was used in the computation***

苹果谷歌等各种公司使用差别隐私技术来保护用户隐私,同时改善用户体验。

露天开采和库

最近,人们对隐私以及如何在不损害用户隐私的情况下使用数据来训练深度学习模型有了很多关注。 Openmined 是一个开源社区,其目标是让每个人都能轻松地进行保护隐私的机器学习。Openmined 开发了 PySyft 库,支持联邦学习差分隐私多方计算,同时支持 Pytorch 和 Tensorflow。OpenMined 还开发了 PyGrid ,这是一个基于 PySyft 构建的 P2P 平台,用于在分布式/云环境中运行 PySyft。

CrypTen —它是一个隐私保护的机器学习框架,来自脸书,构建在 Pytorch 之上。将 CrypTen 与 PySyft 集成的工作正在进行中。

tensor flow Privacytensor flow Privacy是一个开源库,用于训练具有隐私的 ML 模型。

由 Udacity 和脸书提供的免费课程由 Andrew Trask 教授(Trask)——[安全和私人 AI](http://Secure and Private AI)

随着如此多的数据泄露和各种公司收集越来越多的个人信息,对机器学习中的安全和隐私的需求越来越多,尤其是在医疗保健领域。CCPA 现在很活跃,看看它对 2020 年及以后的商业的影响将会很有趣。要了解更多关于自然语言处理和人工智能的信息,你可以在推特上关注我——https://twitter.com/MSuryavansh

[## 用 PyTorch + PySyft 加密深度学习分类

总结:伟大的理论需要伟大的实践。我们在这个博客中展示了如何使用一个私人神经网络来…

blog.openmined.org](https://blog.openmined.org/encrypted-deep-learning-classification-with-pysyft/) [## 一种递归神经网络在树莓 PIs 上的联邦学习

在本教程中,您将学习如何在 Raspberry PI 上设置 PySyft,以及如何训练递归神经…

blog.openmined.org](https://blog.openmined.org/federated-learning-of-a-rnn-on-raspberry-pis/) [## PySyft 上的分裂神经网络

总结:在这个博客中,我们将介绍一种新的分散式学习方法,叫做…

medium.com](https://medium.com/analytics-vidhya/split-neural-networks-on-pysyft-ed2abf6385c0) [## 10 行联合学习

总结:简单的代码示例使学习变得容易。在这里,我们使用 MNIST 培训任务来介绍联合学习…

blog.openmined.org](https://blog.openmined.org/upgrade-to-federated-learning-in-10-lines/) [## 加州消费者隐私法(CCPA):合规所需了解的内容

2018 年 6 月下旬,加利福尼亚州通过了消费者隐私法案 AB 375,这可能会对美国产生更多影响…

www.csoonline.com](https://www.csoonline.com/article/3292578/california-consumer-privacy-act-what-you-need-to-know-to-be-compliant.html) [## 2019 —伯特和变压器年

关于 2019 年 BERT 和 NLP 项目的简短帖子

towardsdatascience.com](/2019-year-of-bert-and-transformer-f200b53d05b9)

CDFs:使用 spacepy 方便地读写数据

原文:https://towardsdatascience.com/cdfs-using-spacepy-to-read-and-write-your-data-conveniently-9490f0bfee4a?source=collection_archive---------46-----------------------

Spacepy python 库是存储和读取复杂文件的有用工具,同时还存储数据的描述。

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

图片来自美国宇航局 Unsplash

任何组织最重要的方面是拥有一种读取和存储数据的机制。存储数据最常见的方式是通过格式。csv ‘,’。tsv ‘或’。’ txt '。虽然这些文件使用标准的稀疏器或定制的分隔符可以方便地读取信息,但是存储多维数据及其相应的信息(关于单位、数据收集方法等)变得很困难。).

存储数据及其信息的一种新方法是使用。文件的 cdf 格式。CDF 代表通用数据格式,它接受最通用的数据类型,而不管其维度和形状。由 Wolfram Research 创建的 CDF 可以轻松存储和传输信息。CDF 文件被许多组织使用,最著名的是 NASA,用来将多维数据存储到分离的、容易理解的符号中。

在本文中,我将指导您一步一步地创建. cdf 文件,以及如何在实践中使用它。同样的详细文档可以在这里找到:https://spacepy.github.io/_modules/spacepy/pycdf.html

导入库

用于此问题的库

用于创建和读取。cdf 文件是 spacepy 库,嵌入了 pycdf 函数。要顺利运行库,请确保您的处理器具有与库相同的体系结构(32 位/64 位)。

样题

在本文中,我们将考虑一个简单的问题。如果你有一个数组或者。csv 文件,存储不等长的尺寸变得很困难。让我们假设,手头的问题是存储 2 年期间的美国原油价格(日平均)和 2 年期间的美国天然气价格(周平均)。因此,在这种情况下,原油和天然气的数据点数量会有所不同,分别为 730 和 104 个点。为了以易于阅读的格式存储数据,我们将使用。cdf 格式。

第一步是生成一些随机数据。我们假设美国原油价格波动超过 20-100 单位,而天然气价格波动超过 5-30 单位(数值是随机选取的,没有相关性)。

我们将变量 tcrude 和 tng 视为时间步长,前者为每日,后者为每周。原油和天然气价格是随机生成的。

随机数据生成

编写一个 CDF 文件

这个问题最关键的一步是正确地编写一个新的 cdf 文件,它包含我们所拥有的所有必需的属性。相同的示例代码如下:

将数据写入. cdf 文件

在上面的步骤中,完成了以下事情:

  1. 我们产生了。使用 pycdf 中的 write 方法的 cdf 文件,指示用于写入新文件的空引号。
  2. 我们存储数据的方式类似于 pandas 数据帧,但是,在这种情况下,数据没有索引,而是存储在一个单独的变量中
  3. 的’。attrs 的方法用于添加关于数据的信息。在本例中,我们添加了以下内容:作者姓名、数据来源、采样方法。除此之外,我们还为数据添加了属性,例如价格的单位。

阅读。cdf 文件

现在我们已经创建了一个. cdf 文件,我们将使用同一个文件作为要读取的输入。这将带我们读一个文件,并验证我们写的数据。

的。cdf 文件有两个方面,我们存储的数字数据和属性。我们希望知道数据文件包含什么,以及作者是否希望传达任何附加信息。这可以通过导入。cdf 为只读,然后打印所需的数据。

写入的 cdf 文件的输出代码

这段代码的输出如下:

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

的输出。cdf 文件,包含所有的变量及其属性。

处理来自。cdf 文件

中处理数据很简单。cdf 文件。这可以通过与熊猫数据帧相同的方式来完成。示例绘图如下所示:

用于从绘制数据的代码。cdf 文件

该图与绘制数组或熊猫数据框的图相同。但是,使用的便利性。cdf 文件的一个优点是,你可以轻松地从同一个文件中取出不同维度的变量。此外,某些属性,如单位和作者姓名,也可以直接从文件中读取,无需任何额外的过滤。

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

示例图来自统一生成的数据,从。cdf 文件。

。cdf 很方便,不是吗?它们是数据帧的完美组合,但是允许不均匀的维度,并且可以使用键轻松地引用它们。唯一的缺点是。cdf 文件的一个缺点是它可能比正常文件大。csv 或。txt 文件,但有一个权衡。这种轻松。cdf 文件提供的很高!

jupyter 的整个笔记本都在这里:https://github . com/yashgokhale/Miscellaneous/blob/master/netcdf _ tutorial . ipynb

CDF 非常有趣。数据分析也是如此。你可以打电话到 ashsgokhale@gmail.comy回复我,以获得任何进一步的澄清或建议,无论是关于这篇文章还是一般的。

参考资料:

[1]https://spacepy.github.io/pycdf.html

[2]https://CDA web . gsfc . NASA . gov/pub/software/CDF/doc/CDF 360/CDF 360 ug . pdf

数据科学家如何获得最被低估的认证

原文:https://towardsdatascience.com/cdmp-exam-d65e1255016b?source=collection_archive---------13-----------------------

数据策略越来越被视为数据科学职业发展的一项关键技能。

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

2020 年,我们数字世界的规模是 40 万亿千兆字节。这比 2010 年增长了 3000%。多兰·埃里克森在 Unsplash 上的照片

认证数据管理专家(CDMP) 考试授予数据策略领域的优秀,这是我们这个数据丰富的世界急需的学科。

考试包含 100 道选择题需在 90 分钟内作答。通过一级考试需要 60% 的分数。可与在线** 监考一起进行开卷。这意味着你可以用你的笔记和 数据管理知识体系(DMBOK) 作为参考。**

CDMP 在当今的就业市场中非常重要。该证书与高级领导职位相关联。商业和政府领域的潜在客户也认为这表明他们对数据管理有很深的了解。如果你刚刚开始与数据相关的职业旅程,CDMP 是一个开始的好地方

2020 年 10 月初,我以 87/100 的分数完成了数据管理基础考试,获得了 CDMP 的认可。在这篇文章中,我将带你浏览我复习 DMBOK 并成功参加考试的步骤。

在本指南中:

  1. 学习小贴士
  2. 动机
  3. 数据科学家的数据策略

免责声明 :本帖非达马国际赞助——所反映观点仅属我个人。我在亚马逊上添加了一个链接到 DMBOK 的附属链接。通过此链接购买您的阅读材料有助于支持我关于数据科学和数据策略的写作以及 CDMP 研究小组的管理。我的目标是帮助数据科学家、分析师、工程师和其他技术人员获得 CDMP 证书,以推进他们的目标预先感谢您的支持。

我推荐的所有为 CDMP 而学习的事情

📘购买 DMBOK 第二版。 此时。考试是开卷并且 DMBOK 作为数据管理工作的参考是非常有用的。DMBOK 占据了我桌子上的首要位置——我经常参考我的要点和便利贴来回答客户的问题。

现在就买 CDMP 考试。您有无限的时间来安排考试日期,并且支付考试费用可以让您访问包含 200 个问题的题库**,模拟真实考试。**

🔖高亮显示并粘贴 DMBOK 和**。好吧,这显然是开卷考试。你肯定想用荧光笔和便利贴来表明关键概念。我把所有的便利贴都放在书的一面,方便参考。我还建议你在标签页上写的东西要横着,这样它们就不会伸出书本太远。**

❗️ 指示每章的开始。使用宽便利贴或特定颜色的笔记来标记每一章的开始。在测试中,这对于快速找到与特定主题相关的内容是非常宝贵的。

🔨使用章节框架**。 DMBOK 的所有章节都遵循以下结构*简介、活动、工具、技术、实施指南、治理、引用/推荐的作品。将学习重点放在概述和技术部分上,相对于实施和组织部分,它们在考试中发挥的作用更大。*

💙按顺序阅读,然后按优先级复习**。 DMBOK 的主题以直观的顺序排列,即您在数据管理项目中评估这些主题的顺序。然而,考试中测试的 14 个主题的比例从数据治理等基础领域的 11%到大数据等高级活动的 2%不等。在你第二次阅读 DMBOK 的时候,我推荐按照本文 中的 优先顺序学习。**

⭐️ 加入 CDMP 学习小组 。使用这个社区来交换意见、提问和寻找学习伙伴。

质量差的数据会威胁到一个组织的生存

—乔·佩帕德,麻省理工学院斯隆管理学院首席研究科学家

动机

对于技术专业人士来说,参加 CDMP 非常简单而且有益。没有技巧性的问题,考试是开卷的,而且只需要 311 美元。希望这篇文章能让你思考获得 CDMP 奖会如何促进你的职业发展——例如:

  • 您是一名数据科学家、数据工程师或软件开发人员,希望进入领导岗位
  • 你是一名顾问,正在寻找一份证书,向你的客户展示你对数据管理有着深刻的理解
  • 您是一名数据科学专业的学生,希望从端到端的角度了解数据相关主题
  • 你是一个被驱使去学习有用的东西的人!

如果你对 CDMP 的好处有任何疑问,考虑一下从 2010 年到 2020 年的十年间,我们数字世界的数据量增长了 3000%,从 1.2 兆字节增长到 40 兆字节。那就是 40 万亿千兆字节

随着时间的推移,组织产生的数据比以往任何时候都多。这创造了重大机遇和巨大风险**。一个强大的数据战略可以支持促进比较优势的实验。薄弱的数据策略会危及组织的生存,将客户、利益相关者和员工置于风险之中。**

急需能够将数据作为战略资产进行管理的专业人士。CDMP 是唯一培训和评估端到端数据战略能力的认证**。**

这些学习小贴士,再说一遍:

  1. 购买第二版的 DMBOK。 为开卷考试
  2. 购买 CDMP 考试获得 200 道练习题
  3. 高亮显示便签并放入 DMBOK
  4. 用特殊的便条纸标明每章的开始
  5. 使用章节框架,重点关注简介、活动、工具、技术
  6. 按顺序阅读章节,然后按优先级复习
  7. 加入 CDMP 学习小组

奖金—数据科学家的数据战略

仍然不相信为什么数据策略对机器学习工程师可能很重要?

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

艾肯金字塔经由 DMBOK

作为一项高级业务职能,数据科学位于艾肯金字塔的顶端。它得到了数据战略基础领域的支持,如果没有这些领域的支持,它就无法取得成功。

提升您的数据战略能力将使您能够在您的组织中倡导更好的数据基础设施**。反过来,这将提高您的数据科学计划的质量。获得 CDMP 不仅能为领导角色提供证书,还能让你获得对知识生成过程的深刻洞察。**

你获得的每一项技能都会让你成功的几率翻倍

——斯科特·亚当斯如何在几乎所有事情上都失败的情况下仍然大获全胜

如果你喜欢阅读这篇文章,请关注我的媒体LinkedInTwitter 以获得更多提升你的数据科学技能的想法。加入 CDMP 考试学习小组。购买 DMBOK

提升技能的其他文章

** [## 10 项被低估的 Python 技能

使用这些技巧来改进您的 Python 编码,以获得更好的 EDA、目标分析和功能,从而提升您的数据科学水平

towardsdatascience.com](/10-underrated-python-skills-dfdff5741fdf) [## 如何不费吹灰之力通过 AWS 云从业者认证

预测:多云,第一次尝试有 100%的机会通过。

nicolejaneway.medium.com](https://nicolejaneway.medium.com/how-to-ace-the-aws-cloud-practitioner-certification-with-minimal-effort-39f10f43146) [## 数据仓库综合指南

了解数据仓库作为分析就绪数据集的主存储库的角色。

towardsdatascience.com](/data-warehouse-68ec63eecf78) [## 你的机器学习模型有可能失败吗?

规划过程中要避免的 5 个失误

towardsdatascience.com](/data-science-planning-c0649c52f867) [## 如何让您的数据科学项目经得起未来考验

ML 模型选择和部署的 5 个关键要素

towardsdatascience.com](/model-selection-and-deployment-cf754459f7ca) [## 5 篇必读的数据科学论文(以及如何使用它们)

让您在数据科学领域保持领先的基本理念。

towardsdatascience.com](/must-read-data-science-papers-487cce9a2020)**

名人脸一代与深卷积甘斯

原文:https://towardsdatascience.com/celebrity-face-generation-with-deep-convolutional-gans-40b96147a1c9?source=collection_archive---------23-----------------------

深度学习

用 DCGANs 生成新的人脸图像

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

约翰·杰克逊Unsplash 上拍照

在本文中,我将带您完成一个有趣的项目,在这个项目中,您将实现一个用于人脸生成的 DCGAN。

我们将利用大规模名人面孔属性(celebA)数据集来训练我们的对抗网络。

如果您不熟悉 GANs 及其工作方式,请阅读这篇关于走向数据科学的文章。

[## 生成对抗网络

用解读甘博弈

towardsdatascience.com](/generative-adversarial-networks-6a17673db367)

大规模名人面孔属性(celebA)数据集

名人脸属性数据集(CelebA) 是一个大规模的人脸属性数据集,拥有超过 200K 张名人图片,每张图片都有 40 个属性标注。

数据可以从这里下载。

我们将使用深度卷积 GANs。如果你想了解 DCGANs,可以看看这篇文章。

[## 深度卷积生成对抗网络

生成对抗网络最有趣的部分之一是生成网络的设计。的…

towardsdatascience.com](/dcgans-deep-convolutional-generative-adversarial-networks-c7f392c2c8f8)

预处理和数据加载

我们不需要注释,所以我们将不得不裁剪图像。这些是彩色图像。因此,深度为 3(RGB-3 个颜色通道)。

我们可以调整和裁剪图像到 32x32 的大小。这可以在以后转换成张量。

注意,我们在这里使用图像文件夹包装函数。

作者代码。

可视化我们的训练数据

我们现在将生成一批数据,并将其可视化。请注意,np.transpose 函数按照指定的顺序转换图像尺寸。例如,在调用以下函数时,形状 3x32x32 的 RGB 图像将转换为 32x32x3:

np.transpose(img,(1,2,0))

我们的批次大小是 128,所以在这种情况下,我们只绘制 20 个图像,而不是绘制一个批次的所有 128 个图像。

作者代码。

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

一批训练图像。图片由作者提供。

缩放图像

缩放图像是很重要的,因为 Tanh 函数的值在-1 到 1 的范围内,所以我们需要将我们的训练图像重新缩放到-1 到 1 的范围。(目前,它们在 0-1 的范围内。)

作者代码。

辅助函数—卷积和转置卷积

为了简化我们的代码,我们将定义帮助函数来定义我们的鉴别器和生成器网络。

这些助手功能的原因是什么?回答——干!😅

卷积辅助函数

注意:要阅读 CNN,请查看下面的斯坦福笔记。

[## 用于视觉识别的 CS231n 卷积神经网络

斯坦福 CS231n 课程材料和笔记:视觉识别的卷积神经网络。

cs231n.github.io](https://cs231n.github.io/)

作者代码。

转置卷积辅助函数

注意:如果你想了解转置卷积,可以看看下面的文章。

[## 转置卷积去神秘化

转置卷积对于图像分割、超分辨率等应用来说是一个革命性的概念

towardsdatascience.com](/transposed-convolution-demystified-84ca81b4baba)

作者代码。

鉴别器架构

我们现在将定义我们的鉴别器网络。正如我们所知,鉴别器负责将图像分类为真或假。因此这是一个典型的分类器网络。

作者代码。

发电机架构

生成器网络负责生成假图像,这些假图像可以欺骗鉴别器网络将其归类为真实图像。随着时间的推移,生成器在欺骗鉴别器方面变得相当不错。

作者代码。

参数初始化

我们将通过从正态分布中抽取随机值来初始化网络的权重和偏差。这导致更好的结果。我们为其定义了一个函数,将一个层作为输入。

对于权重,我使用 0 均值和 0.02 标准差。

对于偏差,我使用 0。

现在这应该被替换,所以函数后面的 _(下划线)也是如此。

作者代码。

损失函数和优化器

我们将使用学习率为 0.002 的 Adam 优化器。这与 DCGANs 的原始研究论文一致。你可以在下面查看一下。

[## 深度卷积生成对抗网络的无监督表示学习

近年来,卷积网络的监督学习(CNN)在计算机视觉领域得到了广泛应用…

arxiv.org](https://arxiv.org/abs/1511.06434)

作者代码。

我们使用 BCEwithLogitsLoss(),它结合了一个 sigmoid 激活函数(我们希望鉴别器输出一个 0–1 的值来指示一个图像是真的还是假的)和二进制交叉熵损失。

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

Binar 交叉熵损失方程。图片由作者提供。

培训阶段

我们将定义一个函数来训练我们的模型。这些参数将是鉴别器、发生器、纪元编号。

作者代码。

策划损失

作者代码。

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

图片由作者提供。

样本生成

现在让我们生成几个样本。重要的是,我们要将这些值重新调整回像素范围(0–255)。

作者代码。

最后,下面是我们生成的人脸。👀

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

生成的图像。图片由作者提供。

嗯,对于一个小型网络来说,这是相当不错的!

外卖食品

  1. 人脸包含多个特征,其中一些特征非常复杂,例如雀斑和胡须。为了生成合适的图像,我们可能需要高分辨率的图像。
  2. 为训练提供了高分辨率图像,我们可能需要建立一个更好、更深的模型,以获得更高的精确度。
  3. 基于输入图像,我们可以进一步增加模型的深度和层数。
  4. 提高分辨率肯定有助于我们改进模型并精确捕捉更多特征。
  5. 生成的样本可以通过调整参数,如学习率、批量大小和更多次数的训练来进一步改进。发电机的损耗是波动的,而不是减少的。
  6. CelebA 数据主要包含不同名人在不同角度和光照条件下的图像。

结论

我们已经看到了如何在 celebA 数据集上使用 DCGAN 实现生成逼真的人脸。通过调整超参数,可以进一步改善生成的图像。你也可以选择比这里更深的层次。然而,这样做将导致参数数量的增加,这又将花费大量时间来训练。现在打开你的 Jupyter 笔记本,执行同样的操作。在下一篇文章中,我将带您浏览使用 SVHN 数据集生成街景房屋号码的过程。下一场见。干杯!

谢谢你。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值