用概率编程和 PyMC3 进行 A/B 测试(第二部分)
在我们的上一篇文章中,我们解释了如何使用 PyMC3 对离散变量进行贝叶斯 A/B 测试。在本文中,我们将对连续变量做同样的事情。
这篇文章的结构如下。
1.大约在 2013 年, John Kruschke 发明的最佳方法(贝叶斯取代 t 检验)概述。
2.要进行统计推断,我们需要数据!我们将解释如何使用名为美汤的 Python 包从互联网上抓取数据。在我们的案例中,我们将从 EPSN.com 刮 NBA 的工资来做我们的分析。
3.NBA 球员薪酬最佳方法的一个具体例子。更准确地说,我们将使用第二部分的数据比较不同位置的 NBA 球员的工资。
由于第二部分主要是获取相关数据,那些只想看看最佳作品如何的人可以跳过。我们搜集的数据可以在这个 Github 存储库中找到。
在我们深入细节之前,我们想对我们的分析做一点小小的评论。从我们与奥斯汀·罗奇福德的讨论中,我们了解到薪水和职位之间的关系应该是相关的,而不是因果关系,奥斯汀·罗奇福德是费城 76 人的忠实粉丝。一个特别的原因是,工资完全不是随机的,因为它们取决于过去的表现。我们感谢奥斯汀对我们结果的专业反馈。
第 1 部分:贝叶斯取代了 t 检验
正如我们在第一部分所解释的,经典的 t 检验有几个缺点,尤其是从商业角度来看。为了克服这些问题,2013 年,印第安纳大学的 John Kruschke 从贝叶斯的角度发明了一种新的 A/B 测试程序。
正如我们在第一部分中解释的,经典 t 检验有几个缺点,尤其是从商业角度来看。为了克服这些问题,2013 年,印第安纳大学的 John Kruschke 从贝叶斯的角度发明了一种新的 A/B 测试程序。
在这个过程中,数据由一个学生 t 分布来描述。这种选择无疑比使用正态分布更能提供信息,因为它可以表示带尾部的分布,在我们的例子中就是这样。
我们需要三个参数来描述 Student-t 分布:均值μ、标准差σ和自由度ν。Kruschke 对这些参数使用了以下先验分布。
- μ服从正态分布。
- σ遵循均匀分布
- ν遵循移位指数分布。
请注意,ν参数控制数据的正态性:当ν>30 时,学生 t 分布接近正态分布。然而,如果ν很小,学生 t 分布就有很重的尾部。这就是为什么我们在ν的先验分布中选择参数 1/29:这是正态性的“截止值”。
下面的图形表示总结了上面的描述。
BEST 的图形表示(作者的手绘)
第 1.1 部分。实际等效区域。
实际等价区域(ROPE)是空值周围的区域,其中包含的值与空值的差异可以忽略不计。绳索的选择取决于特定的应用。例如,假设我们怀疑产品描述越简短,人们越有可能购买。在这种情况下,我们可以做一个 A/B 测试来比较这个新策略和旧策略(如何做的过程在我们的上一篇文章中有解释)。在贝叶斯框架中,我们感兴趣的是两个版本的平均订单的平均差异是否合理地接近于 0。如果我们非常有信心新策略会奏效,我们可以选择 0 左右的大绳。另一方面,如果我们不太自信,可以选择小绳子。
关于绳子的更多细节,见本.&text=In%20other%20words%2C%20it%20checks,null%20region%20(the%20ROPE).)。
第 1.2 部分。最高密度区间。
最高密度层段(HDI)的定义相当专业。粗略地说,HDI 是这样一个区间,它包含的点比位于它之外的点具有更高的概率密度。像置信区间一样,我们可以选择人类发展指数覆盖整个人口的程度。通常,我们可以选择覆盖 95%分布的人类发展指数。
贝叶斯世界中一个更一般的概念,直接类似于置信区间,就是可信区间的概念。我们不会详细讨论这个概念;鼓励读者在这里查看详细内容。
第 1.3 部分。最佳决策。
一旦指定了 ROPE 和 HDI,我们就可以使用它们来进行统计决策。
- 如果 ROPE 位于 HDI 之外,那么我们拒绝零假设。
- 如果 ROPE 包含 HDI,那么我们接受零假设。
- 否则,我们保留我们的决定。
在最后一种情况下,最好的测试说,没有足够的证据来做出结论性的决定。在这种情况下,我们有几种选择。例如,我们可以改变绳子和/或 HDI。更实际的是,我们可以获得更多的样品。
第二部分:网络搜集的 NBA 薪资数据
在本节中,我们将解释如何使用 Python 包 Beautiful Soup 从互联网上获取数据。我们将使用 ESPN 网站获取 2019-2020 赛季 NBA 球员的工资。首先,我们需要导入几个包(对于本节,相关的包是 BeautifulSoup、table 和 requests。)
import pandas as pd
import requests
from bs4 import BeautifulSoup
from tabulate import tabulate
import numpy as npimport pymc3 as pm
import scipy.stats as stats
import matplotlib.pyplot as plt
%matplotlib inline
from IPython.core.pylabtools import figsize
import theano.tensor as tt
from scipy.stats.mstats import mquantiles
我们使用下面的函数来获取原始数据。
def get_raw_data(link):
"""
Given a link, get the raw data from ESPN.com
"""
#get the raw data from the website
res = requests.get(link)
soup = BeautifulSoup(res.content,'lxml')
table = soup.find_all('table')[0]
df= pd.read_html(str(table))[0]
#remove irrelevant rows df=df.drop(df[df[1]=='NAME'].index)
#change the name of the columns
df.columns=['RK', 'Name', 'Team', 'Salary']
#Make the RK column be the index
df.set_index('RK', inplace=True)
return df
例如,让我们将这个函数应用于这个链接。
link="http://www.espn.com/nba/salaries/_/seasontype/3"
df1=get_raw_data(link)
df1.head()
结果是
NBA 球员及其工资样本
这不是所有球员及其薪水的完整列表。还有 14 页。幸运的是,当页面在 2–14 之间时,有一个模式。我们可以利用这个事实快速获得数据。
df =df1
for i in range(2,15):
#get the data for page i df_i=get_raw_data(link= f"http://www.espn.com/nba/salaries/_/page/{i}/seasontype/3")
#combine all the data
df=pd.concat([df, df_i], axis=0)
接下来,我们需要清理这些数据。首先,我们必须从这些数据中获得 NBA 球员的位置。正如我们所看到的,这个信息包含在 name 列中。我们可以使用下面的函数来提取它。
def get_position(text):
return text.split(', ')[-1]
其次,薪水有美元符号;我们应该将它们转换成浮点数据类型。为了避免使用大数字,我们将使用百万美元作为单位。下面几行简单的代码完成了这些清理工作。
df['Position']=df['Name'].apply(get_position)df['Salary']=(df['Salary'].apply(convert_string_to_float))/10**6df.head()
NBA 球员的薪水和职位样本
我们可以将数据保存到 CSV 文件中以备将来使用。
df.to_csv('NBA_salary')
第三部分:NBA 不同职位的薪水
我们将使用在第二步中获得的数据来进行分析。我们将采取可视化的方法来帮助读者对我们的分析有一个直观的理解。
首先,让我们得到这个数据集中的所有位置。
figsize(12.5,4)
positions=df['Position'].value_counts()
positions.sort_values(inplace=True)
bar=sns.barplot(x=positions.index, y=positions)
plt.xlabel("Position")
plt.ylabel("Number of players")
plt.title("Number of players by positions")
plt.show()
按位置分列的 NBA 球员人数
有七种不同的位置:
- 得分后卫
- 小前锋
- 大前锋
- c(中间)
- 控卫
- g(防护)
- f(向前)
其中,SF 和 SG 的玩家数量最多。前锋和后卫位置的样本量明显小于其他位置。
让我们比较一下每种职位的平均工资。
figsize(12.5,4)
salary=df.groupby('Position')['Salary'].mean()
salary.sort_values(inplace=True)
bar=sns.barplot(x=salary.index, y=salary)
plt.xlabel("Position")
plt.ylabel("Salary, million dollar")
plt.title("Average salary across different positions")
plt.show()
不同职位的平均工资
我们看到,平均而言,得分后卫和中锋球员收入最高。另一方面,小后卫球员挣得最少。我们也可以使用箱线图来获得一个更广阔的图景。
figsize(16,6)
my_order = df.groupby("Position")['Salary'].median().sort_values(ascending=False).index
sns.boxplot(data=df, x='Position', y='Salary', order=my_order)
plt.title("Salary for different positions")
plt.show()
每个职位的工资箱线图
对于所有职位,工资都有尾部分布。此外,PG 和 Center 的薪资分布非常相似。总的来说,好像 SG 赚的最少。
第 3.1 部分:得分后卫和控卫
在第一部分,我们比较得分后卫和控球后卫的薪水。如上图所示,我们预计,平均而言,控卫球员比 SG 球员挣得多。
首先,我们过滤掉 SG 和 PG 位置的数据。我们还计算混合样本均值和混合样本方差,如[1]所述。
SG=df[df['Position']=='SG']['Salary']
PG=df[df['Position']=='PG']['Salary']
pooled_mean=np.r_[SG, PG].mean()
pooled_std=np.r_[SG, PG].std()
variance=2*pooled_std
我们为均值、方差和自由度变量设置先验分布。
with pm.Model() as model_1:
mu_A=pm.Normal("mu_A", pooled_mean, sd=variance)
mu_B=pm.Normal("mu_B", pooled_mean, sd=variance)
std_A=pm.Uniform("std_A", 1/100, 100)
std_B=pm.Uniform("std_B", 1/100, 100)
nu_minus_1=pm.Exponential("nu-1", 1.0/29)
接下来,我们将数据放入模型中。
with model_1:
obs_A=pm.StudentT("obs_A", mu=mu_A, lam=1.0/std_A**2, nu=nu_minus_1+1, observed=SG)
obs_B=pm.StudentT("obs_B", mu=mu_B, lam=1.0/std_B**2, nu=nu_minus_1+1, observed=PG)
start=pm.find_MAP()
step=pm.Metropolis(vars=[mu_A, mu_B, std_A, std_B, nu_minus_1])
trace_1=pm.sample(25000, step=step)
burned_trace_1=trace_1[10000:]
一旦完成,我们就有了变量后验分布的样本。然后我们可以绘制它们来比较 SG 和 PG 球员的薪水。
首先,我们画出这两个职位的平均工资。
figsize(12.5, 4)
SG_mean=burned_trace_1['mu_A']
PG_mean=burned_trace_1['mu_B']
plt.hist(SG_mean, bins=40, label=r'Posterior distribution of $\mu_{SG}$')
plt.hist(PG_mean, bins=40, label=r'Posterior distribution of $\mu_{PG}$')
plt.title('Posterior distributions of average salaries for SG and PG')
plt.legend()
plt.show()
这个图说明 PG 球员平均收入比 SG 球员高。这些职位的薪资浮动情况如何?
figsize(12.5, 4)
SG_std=burned_trace_1['std_A']
PG_std=burned_trace_1['std_B']
plt.hist(SG_std, bins=40, label=r'Posterior distribution of $\sigma_{SG}$')
plt.hist(PG_std, bins=40, label=r'Posterior distribution of $\sigma_{PG}$')
plt.title('Posterior distributions of standard derivation derived from PyMC3')
plt.legend()
plt.show()
对于 PG 职位,即使平均工资更高,但波动也更大。
让我们应用 ROPE=[-0.1,0.1]和 95% HDI 的最佳值。这最好通过下面的可视化来完成。
figsize(12.5, 4)
difference=PG_mean-SG_mean #difference of the means hdi=pm.stats.hpd(difference, hdi_prob=0.95) #the 95% HDI interval of the differencerope=[-0.1, 0.1] #the ROPE region plt.hist(difference, bins=50, density=True, label='Differene of the mean salaries')
plt.title('Posterior distribution of the the difference of the means')
plt.vlines(hdi[0], 0,0.6, linestyle='--', color='red', label='HDI')
plt.vlines(hdi[1], 0, 0.6, linestyle='--', color='red')
plt.vlines(rope[0], 0, 0.6, linestyle='--', color='black', label='ROPE')
plt.vlines(rope[1], 0, 0.6, linestyle='--', color='black')
plt.title('Posterior distribution of the the difference of the mean salaries for PG and SG')
plt.legend(loc='upper right')
plt.show()
由于绳子完全在 HDI 区间之外,我们拒绝零假设:我们相信,平均而言,PG 球员比 SG 球员挣得多。我们注意到,在这种情况下,人类发展指数
[0.5580346 , 3.57072747]
所以,即使我们取[-0.5,0.5]这样更宽的绳子,仍然可以拒绝零假设。此外,正如上一篇文章中所讨论的,贝叶斯观点允许我们回答更复杂的问题。比如说,我们有多大把握说一个控卫球员比 SG 球员多赚 50%呢?
figsize(12.5, 4)
rel_difference=100*(PG_mean-SG_mean)/SG_mean #difference of the means
prob=len(rel_difference[rel_difference>50])/len(rel_difference)
plt.hist(rel_difference, bins=50, density=True, label='Relative differene of the mean salaries')
plt.title('Posterior distribution of the the relative difference of the means')
plt.vlines(50, 0,0.011, linestyle='--', color='red', label='HDI')
print(f"The probability that a PG player earn 50% more than an SG player is: {prob}")
plt.show()The probability that a PG player earn 50% more than an SG player is: 0.8830833333333333
我们很有信心 PG 球员比 SG 球员多挣 50%。
第 3.2 部分:小前锋和大前锋
我们可以使用上一节中的框架来做类似的分析。
SF=df[df['Position']=='SF']['Salary']
PF=df[df['Position']=='PF']['Salary']
pooled_mean=np.r_[SF, PF].mean()
pooled_std=np.r_[SF, PF].std()variance=2*pooled_std
with pm.Model() as model_2:
mu_A=pm.Normal("mu_A", pooled_mean, sd=variance)
mu_B=pm.Normal("mu_B", pooled_mean, sd=variance)
std_A=pm.Uniform("std_A", 1/100, 100)
std_B=pm.Uniform("std_B", 1/100, 100)
nu_minus_1=pm.Exponential("nu-1", 1.0/29) obs_A=pm.StudentT("obs_A", mu=mu_A, lam=1.0/std_A**2, nu=nu_minus_1+1, observed=SF)
obs_B=pm.StudentT("obs_B", mu=mu_B, lam=1.0/std_B**2, nu=nu_minus_1+1, observed=PF)
start=pm.find_MAP()
step=pm.Metropolis(vars=[mu_A, mu_B, std_A, std_B, nu_minus_1])
trace_2=pm.sample(25000, step=step)
burned_trace_2=trace_2[10000:]
我们绘制了 SF 和 PF 职位平均工资的后验分布直方图。
与之前的比较不同,我们看到两个后验分布重叠更多。我们可以研究这两种分布的区别。首先,我们使用 ROPE=[-0.1,0.1]和 95% HDI 区间。
我们没有足够的证据通过上述决策规则拒绝或接受这些 ROPE 和 HDI 选择的零假设。让我们仔细看看人类发展指数。
array([-0.44822444, 1.34450148])
我们看到,如果我们坚持这个人类发展指数,那么除非我们选择一个非常宽的绳子(因此,接受零假设),我们的数据不足以做出结论性的决定。
第 3.3 部分:中锋 vs 大前锋
通过类似的代码,我们可以比较中锋和大前锋的工资。我们将根据几种选择以及 HDI 和 ROPE 绘制平均工资的差异。
我们看到,如果选择 ROPE=[-0.1,0.1]和 95% HDI 区间,我们的数据无法做出最终决定。然而,假设我们把人类发展指数降低到 80%。在这种情况下,我们有信心中锋球员的平均收入高于大前锋球员。
结论
我们希望读者能从这篇文章中学到一些东西。首先,BEST 提供了一个进行贝叶斯 A/B 测试的通用框架,它可以定制客户的业务方法。其次,BEST 可以方便地用 PyMC3 实现。最后但同样重要的是,对于 NBA 来说,我们很有信心得分后卫球员的平均收入高于得分后卫球员。我们不太有信心说中锋比大前锋挣得多。然而,我们没有足够的证据来区分小前锋和大前锋球员的工资。
参考文献
[1] John K. Kruschke,贝叶斯估计取代了 t 检验
[2] PyMC3 最佳教程,https://docs.pymc.io/notebooks/BEST.html
回溯测试不会帮你赢得下一个客户
回溯测试就像一把双刃剑,通常它制造的模糊多于清晰
什么是回溯测试?
回测是一种采用预测模型并对历史数据进行测试的验证方法。当这样做时,你预测了“未来”,而事实上未来是已知的(但是对模型是隐藏的)。然后,您可以立即检查您的预测和模型的执行情况。
使用历史数据进行回溯测试
假设我们开发了一个预测航班延误的机器学习产品。为了构建产品模型,我们使用了从不同来源收集的历史航班细节,并且我们根据这些数据不断测试我们的模型(交叉验证)。商业模式是将产品销售给机场和航空公司,这样他们可以更好地运营业务,提高乘客满意度。
你向潜在客户推销这一点,向他们展示在省钱、减少总延误和提高乘客满意度方面的潜在价值。一位客户对该产品感兴趣,您的销售经理提议获取潜在客户数据并进行回溯测试,以证明模型的准确性和产品价值。您的销售经理相信,成功的回溯测试会说服潜在客户达成交易。
含糊而非清晰
在开发和测试模型时,回溯测试是内部使用的一个很好的工具。它有助于发现问题并了解你的预测有多准确,但这绝对不是你希望你的潜在客户和客户衡量你的正确方式或唯一方式。这就是为什么你不应该提供回溯测试来释放产品价值的原因:
1.结果很差
大多数航班延误没有被发现,那些被发现的也没有延误。单一预测不理想的原因可能有很多:
- 训练数据有限且缺乏
- 训练数据有偏差
- 你不能投入太多的资源来为一个单一的回溯测试做出正确的调整
- 预测数据有太多例外和异常值(例如,极端天气、瘟疫爆发等。)
无论在这个过程中你给出了多少免责声明,你都将仅仅基于那个单一的预测而被评判。要改变这种印象将会非常困难,而且很可能你将不得不投入更多的资源。
2.结果是模糊的
大约 20%的航班延误没有被发现,另外 35%的航班延误被意外发现,因为事实上他们并没有被发现。
当结果非常好的时候,这是显而易见的,当结果很差的时候也是如此。但是当结果处于中间时,就会产生模糊,很难确定回溯测试是否成功。如果我们优化召回而不是精确或者反过来,也许结果会被认为更好?
在流程的这个阶段向潜在客户解释回溯测试 KPI 并不容易。在大多数情况下,潜在客户不知道如何消化它们,不知道会发生什么,也不知道对他们的业务有什么真正的影响。
3.结果很好
大多数延误都被发现了,有限的航班被错误地标记为延误,而实际上并没有。
你建立了一个惊人的模型,它是如此的精确,以至于客户都不敢相信它有那么好。如果你认为一个回溯测试结果就能建立签署协议所需的信任,那你就再想想吧。
取得如此好的结果后,你的潜在客户可能会问:
- 另一个回溯测试,看看你是否能重现结果
- 附加产品功能
- 看到完整的产品流程,他们才会真正信任你这个供应商
在这一点上,潜在客户往往会非常怀疑,并且在这种情况下可能会认为,既然“未来”是已知的,那么它只是偶然地(或者不是)没有从模型中隐藏起来。
4.结果毫无意义
即使你的预测被发现是正确的,价值和信任也不会因此而产生。你需要一个故事,潜在客户需要一些相关的东西。产品价值是通过许多方面来解锁的,包括集成到现有的工作流、洞察力、预测解释(可解释的 AI)和许多其他方面。非常努力地进行概念验证,但最终无法展示您的整体产品价值,这将无法建立您想要达成交易的信任。
你应该怎么做?
发展与潜在客户的关系,围绕完整的产品价值而非一次性预测来构建产品。由于对潜在客户的数据进行完整的回溯测试需要大量资源,因此最好将这些资源投入到完整的产品体验中。这将有助于潜在客户了解它是如何集成到他们的日常工作流程中的,实际使用它,查看外观和感觉,并根据多个标准(包括一系列预测而非单一标准)对其进行判断。此外,预测现在都附有适当的解释,潜在客户可以了解决策过程,并感受到对其业务和运营的真正影响。
确保密切管理流程。这包括每周会议、反馈收集、模型改进和必要时的变更部署。通过参与和体验建立信任,而不是通过底线。
非常感谢您的阅读!如果你喜欢这篇文章,我希望收到你的来信——分享或留下你的评论。如果你想阅读更多的故事,请在 Medium 或 LinkedIn 上关注我。
初始和探索性数据分析的基本指南
用 Python 写了几个例子
本文最后一次更新是在 2021 年 9 月 1 日。
简介
数据分析师在不同的工作环境中有不同的定义。数据分析师可能参与各种工作,包括管理信息系统、报告、数据工程、数据库管理等。在真实场景中。也不一定不好。但在这里,我们将讨论的是数据分析师的实际工作,而不是公司让他们做什么。数据分析师的字面意思是分析数据的人——不是设计管道让数据流动,也不是维护数据库——只是分析。找出数据的含义。识别趋势。支持业务团队做出更好的决策,提高整体效率。这个角色更倾向于核心统计学,而不是核心计算机科学。
记住这一点,对于数据分析师来说,在开始发现数据的含义之前,完成以下两个步骤是很有用的
- 通过查看不同的数据点及其在给定数据集中的可用性和分布,找出有用的信息。
- 根据可用性找出不同变量之间的相互关系。人们还可以检查数据的质量,这是我们的第一步。
这不是一篇关于你可以用来执行这两个步骤的所有方法的全面综述。只是对其中一些的基本概述。
照片由艾萨克·史密斯在 Unsplash 上拍摄。希望这不是你作为数据分析师要做的分析。对了,这是不是一个很好的图!😃
初始数据分析
使用 可视化数据集的完整性没有遗漏——数据不完整是一个主要问题——无论是基于机器的数据收集还是基于人类的数据收集。这两种方法都容易出错。如果在分析任何给定的数据集之前确定了数据的完整性,那么数据的完整性就不是问题。如果根据不完整的数据做出决策,那将是一场灾难。思考的食粮——考虑没有数据比不完整数据更好的情况,以得出合理合理的结论/推论。
这个想法是为了检查数据的不完整性
**下图显示了数据集中 db 和 tp 的数据稀少,而 tb、sf、和 gen 的数据丰富。
故意 扭曲 肝脏患者数据取自https://archive . ics . UCI . edu/ml/datasets/ILPD+(Indian+Liver+Patient+Dataset)
使用以下方法获得上面的图:
**import** pandas **as** pd
**import** missingno **as** mn
**from** IPython **import** get_ipython
get_ipython().run_line_magic(**'matplotlib'**, **'inline'**)
df = pd.read_csv(**'/Users/mac/Downloads/missingno-ex.csv'**)
mn.matrix(df.sample(500), figsize=(10,6))
这个想法是
确定两个或多个字段的数据可用性之间的相关性
对于大型数据集,从该数据集中随机抽取一个样本并绘制数据,以确定数据丢失的频率。此外,使用以下代码行绘制一个树状图到来确定两个或更多字段的数据可用性之间的相关性:
mn.dendrogram(df, figsize=(10,6))
为了识别两个变量之间的配对差异,绘制一个树状图**。欲知详情,请阅读—http://www . nonlinear . com/support/progenesis/comet/FAQ/v 2.0/dendrogram . aspx**
为了简单起见,使用条形图来可视化数据——在特定变量包含数据的地方显示绝对数字。
mn.bar(df, figsize=(10,6))
绝对数字
既然我们对数据的分布和可用性有了一些了解,我们就可以研究数据了。
人们可能想知道的第一件事是数据集实际上是什么样子。为了得到这个提示,可以打印出数据集中的第一个n
记录。NaN
表示数据不可用。稍后我们将讨论NaN
值。
使用 pandas 数据框架探索数据
探索性数据分析
现在我们对数据的外观有了一些了解,是时候使用 Seaborn 来探索数据了。
这个想法是看数据集中的两个给定变量是如何相互关联的?
*看完数据后,想到的第一个分析问题是*这个数据集中两个相互关联的变量是怎样的?或者说,当某个变量发生变化时,另一个变量的值是如何变化的?或者这两个变量之间是否存在关系。
即使寻找线性回归拟合线可能不是动机,人们可能仍然希望探索数据所承载的价值。重要的是要知道两个变量之间是否存在关系(相关性),如果存在,值如何变化(回归)
使用这个简单的代码得到上面的图表。
**import** matplotlib.pyplot **as** plt
**import** seaborn **as** sns
sns.set_context("**notebook**", font_scale=1.1)
sns.set_style("**ticks**")
sns.lmplot('**alba**', '**tp**',
data=df,
fit_reg=True,
scatter_kws={"marker": "D",
"s": 10})
plt.show()
除了上一个图表的内容之外,为了可视化上一个图表中绘制的这些变量的值的分布,而不是sns.lmplot
,可以使用下面的代码行使用sns.jointplot
:
sns.jointplot(x="total_bill", y="tip", data=tips, kind="reg")
阅读更多关于Pearson r**—https://docs . scipy . org/doc/scipy-0 . 14 . 0/reference/generated/scipy . stats . Pearson r . html**
让我们来看看可视化数据的最有用的 EDA 方法之一——箱线图。
这个想法是研究数据集中变量的分布
箱线图主要用于研究数据集中变量的分布。尽管直方图也可用于此,但相比之下,箱线图在某些情况下提供了更好的数据汇总。箱线图告诉我们数据的形状、可变性和中心。虽然,当我们只热衷于通过某种方式了解分布情况以告诉我们数据偏向了哪一侧时,直方图可以满足我们的目的,使我们免于其他细节。
**import** pandas **as** pd **import** matplotlib.pyplot **as** plt
**import** seaborn **as** sns
df = pd.read_csv(**'/Users/mac/Downloads/missingno-ex.csv'**)
sns.factorplot(x='**alba**',y= '**ab/gr**',data=df,kind='box',aspect=1)
plt.show()
了解更多关于箱形图** —1 的信息。https://flowing data . com/2008/02/15/how-to-read-and-use-a-box-and-whisker-plot/和 2。https://www . nature . com/nmeth/journal/v11/N2/pdf/nmeth . 2813 . pdf**
在 Seaborn 中使用因子点图,可以像这样可视化上面已经可视化的相同数据。
sns.factorplot(x='**alba**',y= '**ab/gr**',data=df,kind='point',aspect=1)
清理数据 —显然,这需要在我们开始分析之前完成,并且是为使用数据做准备的一部分——因此,它是初始数据分析阶段而不是 EDA 的一部分。
当您使用missing no库来可视化数据丢失的位置时,您没有清理数据以供使用。第一部分是从数据集中移除空值。然后删除重复项。
****import** pandas **as** pd **import** matplotlib.pyplot **as** plt
**import** seaborn **as** snsdf = pd.read_csv(**'/Users/mac/Downloads/missingno-ex.csv'**)
# Cleaning the data now
df = df.dropna().drop_duplicates()
sns.factorplot(x='**alba**',y= '**ab/gr**',data=df,kind='box',aspect=1)
plt.show()**
这是用 dropna()和 drop_duplicates()清理后数据的样子。注意最左边一列中缺少的索引——顺便说一下,这不是数据集的一部分。它只代表行号。
经过清理后,这就是保留下来供使用的数据。
这是对您可以在数据分析过程的前两步中使用的几个示例的基本介绍,即,
- 初始数据分析 —对数据的性质及其收集方式的初步探索。这一部分包括清理和管理数据,以便对分析有用。
- 探索性数据分析 —涉及全面的探索,主要是通过可视化的方法,其中一些方法在上面已经提到。
- 建模——为给定数据创建模型,并建立不同变量之间的关系——使用训练数据集。
- 验证 —检查模型是否适用于未用于训练的数据集,即测试数据集。如果模型有效,那么你继续下一步。否则,你回去改进模型。
- 预测 —如果模型得到验证,您可以很有把握地说,数据集中的某个变量相对于数据集中的另一个变量将如何变化。这是最后阶段。
结论
前两步很重要,尤其是在对数据缺乏信任的情况下。这种缺乏信任可能是由各种原因引起的,如您收集数据的方式、数据的来源、数据是否有偏差、数据是否被有意篡改、等等。执行前两个步骤,即初始数据分析和探索性数据分析,很容易识别数据集的问题,而不会花费任何时间来做出错误的和错误的模型和预测。
生成对抗网络的基本介绍
入门
甘是如何工作的?他们为什么这么有趣?
我有机会在甘斯做了 3 个月的研究实习。我读了很多科学论文和博客。在这篇文章中,我试图传达我所学到的和觉得值得分享的基本知识。
目录
1)简介
2)GANs 是如何工作的?
2.1)原理:生成器 vs 鉴别器
2.2)数学上:双人极大极小游戏
3)为什么 GANs 这么有趣?
4)结论和参考文献
图 1 :使用 GANs 从原始图像生成的现实而虚构的名人肖像。来源:英伟达**【4】**。
1)简介
在过去的十年里,可用数据量的爆炸式增长——大数据——算法的优化和计算能力的不断进化,使人工智能 (AI)能够执行越来越多的人类任务。2017 年,Andrey Ng 预测人工智能将像电一样产生深远的影响。
如果我们声称 AI 的目的是模拟人类的智能,那么主要的难点就是创造力。在人工智能领域,我们谈论生成模型,当今最流行的模型之一是 GANs(表示“生成对抗网络”)。在 2016 年的一次研讨会上, Yann LeCun 称 GANs 是“过去 20 年深度学习领域最酷的想法”。
甘斯引入了对抗学习的概念,因为它们存在于两个神经网络之间的竞争中。这些技术使研究人员能够创建看起来逼真但完全由计算机生成的人脸照片。他们还允许制作有争议的“深度造假”视频。实际上,GANs 可以用来模仿任何数据分布(图像、文本、声音等。).
GANs 2018 年的结果示例见图 1** :这些图像是假的,但非常真实。这些虚构的名人肖像的生成,来自 Celeba-HQ 的真实肖像数据库,由 30,000 幅图像组成,耗时 19 天。生成的图像大小为 1024×1024。**
GANs 是如何工作的?
生成对抗网络 (GANs)是一种带有隐式密度估计的生成模型,是无监督学习的一部分,使用两个神经网络。因此,我们理解“生成性对抗网络”中的“生成性”和“网络”这两个术语。
2.1)原理:发生器与鉴别器
图二:发生器和鉴别器的作用。来源:斯坦福 cs 231n【2】。
其原理是一个双人游戏:一个被称为生成器的神经网络和一个被称为鉴别器的神经网络。发生器试图通过生成看起来真实的图像来欺骗鉴别器,而鉴别器试图区分真实和虚假的图像。因此,我们理解“生成对抗网络”中的“对抗”一词。参见图 2** 。**
图 3 :解释:发生器和鉴别器的作用。来源: TensorFlow 。
在图 2** 的左下方,我们可以看到我们的发生器样本来自一个简单的分布:随机噪声。生成者可以解释为艺术家,鉴别者可以解释为艺术批评家。参见图 3 。**
图 4 :发电机和鉴别器培训。来源: TensorFlow 。
在训练过程中,发生器逐渐变得更擅长创建看起来真实的图像,而鉴别器变得更擅长区分它们。当鉴别器不再能够区分真实图像和伪造图像时,该过程达到平衡。参见图 4** 。因此,如果鉴别器训练有素,并且生成器设法生成看起来真实的图像来欺骗鉴别器,那么我们就有了一个良好的生成模型:我们正在生成看起来像训练集的图像。**
在这个训练阶段之后,我们只需要生成器对新的(错误的)真实数据进行采样。我们不再需要鉴别器了。请注意,随机噪声保证了发生器不会总是产生相同的图像(这会欺骗鉴别器)。
请注意,在图 4 中的训练开始时,发生器仅产生一个看起来不像训练数据的随机噪声。****
2.2)数学上:双人极大极小游戏
生成器 G 和鉴别器 D 以双人极大极小游戏的形式联合训练。最小最大目标函数是:
方程式(1)
其中 θ_g 为 G 的参数, θ_d 为 D 的参数。
下面我们简单的把 D_{θ_d} 称为 D ,把 G_{θ_g} 称为 G 。
**根据定义, D 输出真实图像在区间 [0,1]:
D(x)等于 1 (或者接近于 1 )如果 D 认为 x 是真实数据,
D(x)等于0
我们可以证明,在均衡状态下, D 处处输出 1/2 ,因为 D 不知道如何区分虚假生成的数据和真实数据。
因为x∞p _ { data }, x 是实数据。根据 G 的定义, G(z) 是一个假生成的数据。例如, x 将是一只猫的真实图像,而 G(z) 将是一只猫的假生成图像。因此, D(x) 是鉴别器对于真实输入 x 的输出,而D(G(z)】是鉴别器对于伪生成数据 G(z) 的输出。**
在【1】之后,来自等式(1)* 的两人极大极小游戏被写成使得 θ_g 和 θ_d 进化,使得子节 2.1) 中的以下几点为真:
鉴别器 D 试图区分真实数据 x
更准确地说,鉴别器 D 与 θ_d ( θ_g 固定)一起运行,以最大化目标函数,使得 D(x) 接近于 1 ( x 为真实数据),并且使得D(G(z)接近于 0
生成器 G 试图欺骗鉴别器 D 认为其生成的假数据是真实的。
更准确地说,生成器 G 与 θ_g ( θ_d 固定)一起运行,以最小化目标函数,使得D(G(z)】接近于 1 (一个错误生成的数据被鉴别器检测为真)。*
虽然我们是在无监督学习中(数据没有标注),但是我们选择由 G 生成的数据有一个 0 标签为假(不管鉴别器返回什么),真实的学习数据有一个 1 标签为真。因此,我们可以定义一个损失函数。
论文【1】证明了极小极大对策对于 p_g = p_{data} 有一个全局(唯一)最优,其中 p_g 是生成分布, p_{data} 是真实数据分布。然而,在实践中,让 p_g 向 p_{data} 收敛并不容易。
3)为什么甘这么有意思?
生成模型有几个非常有用的应用:彩色化、超分辨率、艺术作品的生成等。一般来说,使用模拟模型优于真实模型的优点是计算速度更快。
Goodfellow 的教程【3】和 Stanford 的讲座【2】中给出了很多有趣的例子。特别是 Goodfellow 在 4:15 到 12:33 的会议“生成性对抗性网络(NIPS 2016 教程)”中给出的例子,让人印象深刻。
图 5 : CycleGAN:用 GANs 把真实的影像转置成现实的虚构影像。来源:柏克莱人工智能研究(BAIR)实验室【5】。**
图 5 给出了一个例子。伯克利大学研究人员开发的 CycleGan 将这些真实图像转换成现实的虚构图像,反之亦然。这个概念被称为图像到图像转换*,是一类视觉和图形问题,其目标是使用对齐图像对的训练集来学习输入图像和输出图像之间的映射。对于 Tensorflow,CycleGAN 上有一个教程。***
图 6 :使用 GANs 的几种图像变换。来源:柏克莱人工智能研究(BAIR)实验室【6】。**
第二个例子如图 6 中的所示。例如,空中转地图功能对谷歌地图或类似的应用程序非常有用,边缘转照片功能可以帮助设计师。****
4)结论
GANs 的应用增长迅速,尤其是在图像方面。我相信 GANs 对公司来说是非常有趣的。例如,GANs 可以生成新医学图像的逼真图像,图像到图像的翻译可以帮助设计人员绘图并更具创造性。此外,当我们只有一百张图像并且希望有更多时,GANs 可以用于数据扩充*。***
GANs 也被开发用于二进制输出(生病与否)或离散输出(四舍五入的血压、四舍五入的体重……)【7】。这项关于表格数据的新研究带来了很多好处,特别是对于隐私的目的。例如,医院可以向他们的合作伙伴发送虚假的真实数据(保持特征之间的相关性),而不是发送 Excel 表格中的机密数据。**
感谢阅读,希望这篇文章对你有用。不要犹豫,在评论中给出反馈。随时联系我 推特 。
参考
***伊恩·古德菲勒、让·普热-阿巴迪、米尔扎、徐炳、戴维·沃德-法利、谢尔吉尔·奥泽尔、亚伦·库维尔和约舒阿·本吉奥。“生成对抗网” NIPS (2014)。
**【2】**费-、和杨威。 CS231n:用于视觉识别的卷积神经网络。第 13 讲|生成模型。斯坦福大学(2017 年春季)。
**【3】**伊恩·古德菲勒。" NIPS 2016 教程:生成对抗网络"ArXiv abs/1701.00160 (2017)。
**【4】**泰罗·卡拉斯、蒂莫·艾拉、s·莱恩和 j·莱蒂宁。为了提高质量、稳定性和多样性而逐步种植甘蔗。ArXiv ABS/1710.10196(2018)。
**【5】**朱俊彦、t·帕克、菲利普·伊索拉和阿列克谢·阿·埃夫罗斯。"使用循环一致对抗网络的不成对图像到图像翻译" 2017 IEEE 计算机视觉国际会议(ICCV)(2017):2242–2251。
*【6】菲利普·伊索拉、、周廷辉和阿列克谢·埃夫罗斯。“用条件对抗网络进行图像到图像的翻译” 2017 年 IEEE 计算机视觉与模式识别大会(CVPR)(2017):5967–5976。
e .崔、s .比斯瓦尔、b .马林、j .杜克、w .斯图尔特和孙。使用生成式对抗网络生成多标签离散患者记录。 MLHC (2017)。
TensorFlow Lite 的基本介绍
介绍 TensorFlow Lite 转换器、量化优化和在边缘运行 Tensorflow Lite 模型的解释器
在本文中,我们将了解在边缘部署深度学习模型所需的功能,什么是 TensorFlow Lite,以及如何使用 TensorFlow Lite 的不同组件在边缘进行推断。
Priscilla Du Preez 在 Unsplash 上拍摄的照片
你正在尝试将你的深度学习模型部署在一个他们没有良好网络连接但仍然需要深度学习模型来提供出色性能的区域。
TensorFlow Lite 可用于这种情况
深度学习模型在边缘进行推理的特征
- **轻量级:**边缘设备在存储和计算能力方面资源有限。深度学习模型是资源密集型的,因此我们在边缘设备上部署的模型应该是轻量级的,具有较小的二进制大小。
- **低延迟:**边缘的深度学习模型应该做出更快的推断,而不管网络连接性如何。由于推断是在边缘设备上进行的,因此将消除从设备到服务器的往返行程,从而使推断更快。
- **安全:**模型部署在边缘设备上,推断在设备上进行,没有数据离开设备或在网络上共享,因此不存在数据隐私问题。
- **最佳功耗:**网络需要大量功率,边缘设备可能没有连接到网络,因此功耗需求较低。
- **预训练:**模型可以在内部或云端进行训练,用于不同的深度学习任务,如图像分类、对象检测、语音识别等。并且可以很容易地部署以在边缘做出推断。
Tensorflow Lite 提供了在边缘进行推理所需的所有功能。
但是 TensorFlow Lite 是什么?
TensorFlow Lite 是一个开源、产品就绪、跨平台的深度学习框架,可以将 TensorFlow 中预先训练的模型转换为一种特殊的格式,可以针对速度或存储进行优化。
特殊格式模型可以部署在边缘设备上,如使用 Android 或 iOS 或 Linux 的移动设备,基于嵌入式设备,如 Raspberry Pi 或微控制器,以在边缘进行推理。
tensor flow Lite(TF Lite)是如何工作的?
选择并训练一个模型
假设您想要执行图像分类任务。第一件事是决定任务的模型。你的选择是
- 创建自定义模型
- 使用预先训练好的模型,如 InceptionNet、MobileNet、NASNetLarge 等。
- 在预先训练的模型上应用迁移学习
使用转换器转换模型
模型定型后,您将把模型转换为 Tensorflow Lite 版本。 TF lite 模型是一种特殊格式的模型,在准确性方面很有效,并且是一种占用空间较少的轻量型模型,这些特性使 TF lite 模型非常适合在移动和嵌入式设备上工作。
TensorFlow Lite 转换流程
来源:https://www.tensorflow.org/lite/convert/index
在从 Tensorflow 模型到 Tensorflow Lite 模型的转换过程中,文件的大小会减小。我们可以选择进一步减小文件大小,同时权衡模型的执行速度。
Tensorflow Lite 转换器将 Tensorflow 模型转换为 Tensorflow Lite 平面缓冲文件()。tflite )。
Tensorflow Lite 平面缓冲文件部署到客户端,在我们的例子中,客户端可以是运行在 iOS 或 Android 上的移动设备或嵌入式设备。
如何将 TensorFlow 模型转换为 TFlite 模型?
训练完模型后,您现在需要保存模型。
保存的模型在单个文件中序列化模型的架构、权重和偏差以及训练配置。保存的模型可以很容易地用于共享或部署模型。
转换器支持使用保存的模型
- tf.keras.Model: 使用 keras 创建并编译模型,然后使用 TFLite 转换模型。
#Save the keras model after compiling
**model.save('model_keras.h5')
model_keras= tf.keras.models.load_model('model_keras.h5')**# Converting a tf.Keras model to a TensorFlow Lite model.
**converter = tf.lite.TFLiteConverter.from_keras_model(model_keras)
tflite_model = converter.convert()**
- SavedModel :一个 SavedModel 包含一个完整的 TensorFlow 程序,包括权重和计算。
#save your model in the SavedModel format
**export_dir = 'saved_model/1'
tf.saved_model.save(model, export_dir)**# Converting a SavedModel to a TensorFlow Lite model.
**converter = lite.TFLiteConverter.from_saved_model(export_dir)
tflite_model = converter.convert()**
export_dir 遵循一个惯例,其中最后一个路径组件是模型的版本号。
SavedModel 是保存在 export_dir, 上的元图,使用 lite 转换为 TFLite 模型。TFLiteConverter 。
- 具体功能: TF 2.0 默认开启急切执行,影响性能和可部署性。为了克服性能问题,我们可以使用 tf.function 来创建图形。图形包含模型结构,以及模型的所有计算操作、变量和权重。
将模型导出为具体函数,然后将具体函数转换为 TF Lite 模型
**# export model as concrete function**
func = tf.function(model).get_concrete_function(
tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype))#Returns a serialized graphdef representation of the concrte function
**func.graph.as_graph_def()**# converting the concrete function to Tf Lite
**converter = tf.lite.TFLiteConverter.from_concrete_functions([func])
tflite_model = converter.convert()**
优化模型
为什么要优化模型?
边缘模型需要重量轻
- 在边缘设备上占用较少的空间。
- 在带宽较低的网络上下载速度更快
- 为模型占用更少的内存,以便更快地做出推断
处于边缘的模型也应该具有运行推理的低延迟。轻量级和低延迟模型可以通过减少预测所需的计算量来实现。
优化减少了模型的大小或改善了延迟。在模型的大小和模型的准确性之间有一个权衡。
tensor flow Lite 中优化是如何实现的?
Tensorflow Lite 通过以下方式实现优化
- 量化
- 权重修剪
量子化
当我们保存 TensorFlow 模型时,它存储为包含计算操作、激活函数、权重和偏差的图形。激活函数、权重和偏差是 32 位浮点。
量化降低了用于表示张量流模型的不同参数的数字的精度,这使得模型重量轻。
量化可以应用于权重和激活。
- 具有 32 位浮点的权重可以转换为 16 位浮点或 8 位浮点或整数,并且将减小模型的大小。
- **权重和激活都可以通过转换为整数来量化,**这将提供低延迟、更小的尺寸和降低的功耗。
权重修剪
正如我们修剪植物以去除植物的非生产性部分,使其更结果实和更健康一样,我们也可以修剪模型的权重。
权重修剪会修剪模型中对模型性能影响很小的参数。
**权重剪枝实现模型稀疏,稀疏模型压缩效率更高。**修剪后的模型将具有相同的大小和运行时延迟,但具有更好的压缩性能,可在边缘实现更快的下载时间。
部署 TF Lite 模型并进行推理
TF lite 模型可以部署在 Android 和 iOS 等移动设备上,以及 Raspberry 和微控制器等边缘设备上。
要从边缘设备进行推断,您需要
- 初始化解释器,并用模型加载解释器
- 分配张量,得到输入和输出张量
- 通过读入张量对图像进行预处理
- 通过调用解释器对输入张量进行推理。
- 通过映射推理的结果来获得图像的结果
# Load TFLite model and allocate tensors.
**interpreter = tf.lite.Interpreter(model_content=tflite_model)
interpreter.allocate_tensors()**#get input and output tensors
**input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()**# Read the image and decode to a tensor
**img = cv2.imread(image_path)
img = cv2.resize(img,(WIDTH,HEIGHT))**#Preprocess the image to required size and cast
**input_shape = input_details[0]['shape']
input_tensor= np.array(np.expand_dims(img,0), dtype=np.float32)**#set the tensor to point to the input data to be inferred
**input_index = interpreter.get_input_details()[0]["index"]
interpreter.set_tensor(input_index, input_tensor)**#Run the inference
**interpreter.invoke()
output_details = interpreter.get_output_details()[0]**
还有其他方法可以改善延迟吗?
Tensorflow lite 使用委托来提高 TF Lite 模型在边缘的性能。 TF lite delegate 是一种将部分图形执行交给另一个硬件加速器的方式,比如 GPU 或 DSP (数字信号处理器)。
TF lite 使用几个硬件加速器来提高速度、准确性和优化功耗,这是在边缘运行推理的重要特性。
结论: TF lite 模型是轻量级模型,可以部署在移动设备、Raspberry Pi 和微控制器等边缘设备上进行低延迟推理。当与硬件加速器一起使用时,TF lite delegate 可用于进一步提高速度、准确性和功耗
参考资料:
www.tensorflow.org](https://www.tensorflow.org/lite/guide)
https://www.tensorflow.org/model_optimization/guide/pruning
www.tensorflow.org](https://www.tensorflow.org/model_optimization/guide/quantization/post_training)
https://www . tensor flow . org/lite/performance/model _ optimization
机器学习项目模板
总结基本 ML 项目中遵循的步骤
每个机器学习项目都有其独特之处。尽管对于每个这样的项目,可以遵循一组预定义的步骤。没有那么严格的流程可循,但是可以提出一个通用的模板。
1.准备问题
不仅仅是 ML,任何项目的第一步都是简单地定义手头的问题。你首先需要了解情况和需要解决的问题。然后设计机器学习如何有效地解决这个问题。一旦你很好地了解了问题,你就可以着手解决它。
加载库
在本文中,我将坚持使用 Python (原因很明显)。第一步是加载或导入获得想要的结果所需的所有库和包。机器学习的一些非常初级且几乎必不可少的包有— NumPy 、 Pandas 、 Matplotlib 和 Scikit-Learn 。
加载数据集
一旦加载了库,就需要加载数据。Pandas 有一个非常简单的函数来执行这个任务— pandas.read_csv 。read.csv 函数不仅限于 csv 文件,还可以读取其他基于文本的文件。其他格式也可以使用熊猫阅读功能来阅读,如 html,json,腌渍文件等。需要记住的一点是,您的数据需要位于与当前工作目录相同的工作目录中,否则您将需要在函数中提供以“/”为前缀的完整路径。
2.汇总数据
好了,数据已经加载完毕,可以开始行动了。但是您首先需要检查数据的外观以及它包含的所有内容。首先,您会希望看到数据有多少行和列,以及每一列的数据类型是什么(pandas 认为它们是什么)。
查看数据类型和形状的快速方法是— 熊猫。DataFrame.info 。这会告诉您数据帧有多少行和列,以及它们包含哪些数据类型和值。
描述统计学
描述统计学,顾名思义,是用统计学的术语来描述数据——均值、标准差、分位数等。获得完整描述的最简单方法是通过熊猫。data frame . description。您可以很容易地判断出您的数据是否需要缩放,或者是否需要添加缺失的值,等等。(稍后将详细介绍)。
数据可视化
数据可视化非常重要,因为这是了解数据和模式的最快方法——不管它们是否存在。您的数据可能有数千个要素,甚至更多实例。不可能对所有的数字数据进行分析。如果你这样做了,那么拥有像 Matplotlib 和 Seaborn 这样强大的可视化软件包还有什么意义呢?
使用 Matplotlib、Seaborn 的可视化可用于检查特征内的相关性以及与目标、散点图数据、直方图和箱线图的相关性,用于检查分布和 偏斜度 等等。甚至 pandas 也有自己的内置可视化库——pandas。DataFrame.plot 包含条形图、散点图、直方图等。
Seaborn 本质上是 matplotlib 的一个变形,因为它建立在 matplotlib 的基础上,使绘图更漂亮,绘图过程更快。热图和 pairplot 是 Seaborn 快速绘制整个数据可视化的例子,以检查多重共线性,缺失值等。
一个非常有效的方法是通过Pandas Profiling获得上述大部分描述性和推断性统计数据。概要分析会生成一个漂亮的数据报告,包含上面提到的所有细节,让您可以在一个报告中进行分析。
3.准备数据
一旦你知道你的数据有什么和看起来像什么,你将必须转换它,以便使它适合算法处理和更有效地工作,以便给出更准确和精确的结果。这本质上是数据预处理,是任何 ML 项目中最重要也是最耗时的阶段。
数据清理
现实生活中的数据并没有被很好地安排和呈现在你面前,没有任何异常。数据通常有许多所谓的异常,如缺失值、许多格式不正确的要素、不同比例的要素等。所有这些都需要手动处理,这需要大量的时间和编码技能(主要是 python 和熊猫:D)!
熊猫有各种功能来检查像熊猫这样的异常。DataFrame.isna 检查带有 nan 等的值。您可能还需要转换数据格式,以便消除无用的信息,例如当存在单独的性别特征时,从姓名中删除“先生”和“夫人”。您可能需要使用函数 pandas 在整个数据帧中以标准格式获取它。DataFrame .使用熊猫替换或删除不相关的功能。DataFrame.drop 。
特征选择
特征选择是选择一定数量的最有用的特征用于训练模型的过程。这样做是为了在大多数特征对总体方差的贡献不足时减少维数。如果你的数据中有 300 个特征,97%的差异是由前 120 个特征解释的,那么用这么多无用的特征来敲打你的算法是没有意义的。减少功能不仅可以节省时间,还可以节省成本。
一些流行的特征选择技术有选择测试,特征消除方法如 RFE (递归特征消除)和嵌入方法如拉索克。
特征工程
所有功能可能都不在最佳状态。意思是——它们可以通过使用一组函数转换到不同的尺度上。这是为了增加与目标的相关性,从而增加准确性/得分。其中一些转换与 缩放 相关,如 StandardScaler、Normalizer、MinMaxScaler 等。甚至可以通过对一些特征进行线性/二次组合来增加特征,以提高性能。对数变换、交互和 Box-Cox 变换是数字数据的一些其他有用的变换。
对于分类数据,有必要将类别编码成数字,这样算法就可以理解它。一些最有用的编码技术是——labelencorder、OneHotEncoder 和 Binarizer。
4.评估算法
一旦你的数据准备好了,继续检查各种回归/分类算法的性能(基于问题的类型)。您可以首先创建一个基础模型来设置一个比较基准。
分离验证数据集
一旦模型被训练,它也需要被验证,以查看它是否真的概括了数据或者它是否过度/不足拟合。手头的数据可以预先分成训练集和验证集。这种拆分有多种技术——训练测试拆分、洗牌拆分等。您还可以在整个数据集上运行交叉验证,以获得更可靠的验证。交叉验证、留一法是最常用的方法。
测试选项和评估指标
模型需要基于一组需要定义的评估指标进行评估。对于回归算法,一些常见的指标是 MSE 和 R 平方。
与分类相关的评估指标更加多样化——混淆矩阵、F1 得分、AUC/ROC 曲线等。对每种算法的这些分数进行比较,以检查哪种算法比其他算法执行得更好。
抽查算法
一旦数据被分割并且评估指标被定义,您需要运行一组算法,比如说,在一个 for 循环中检查哪一个执行得最好。这是一个反复试验的过程,目的是找到一个能很好地解决你的问题的算法列表,这样你就可以加倍努力,进一步优化它们。
可以制作 流水线 ,并且可以设置线性和非线性算法的混合来检查性能。
比较算法
一旦您现场运行了测试线束,您可以很容易地看到哪些线束对您的数据表现最佳。持续给出高分的算法应该是你的目标。然后,您可以选择最优秀的,并进一步调整它们,以提高它们的性能。**
5.提高准确性
有了性能最好的算法后,可以调整它们的参数和超参数,以获得最佳结果。多个算法也可以链接在一起。
算法调整
维基百科声明“超参数调优就是为一个学习算法选择一组最优的超参数”。超参数是未学习的参数,必须在运行算法之前设置。超参数的一些例子包括逻辑回归中的惩罚、随机梯度下降中的损失和 SVM 的核。
这些参数可以在数组中传递,算法可以递归运行,直到找到完美的超参数。这可以通过像网格搜索和随机搜索这样的方法来实现。
合奏
可以将多种机器学习算法结合起来,以建立一个比单一算法更稳健、更优化的模型,从而提供更好的预测。这被称为合奏。
基本上有两种类型的集成— Bagging(自举聚合)和 Boosting 。例如,随机森林是一种 Bagging ensemble,它结合了多个决策树,并对总输出进行汇总。
另一方面,Boosting 通过以一种自适应的方式学习来组合一组弱学习者:集合中的每个模型都被拟合,从而给予数据集中与序列中的先前模型有较大误差的实例更大的重要性。XGBoost、AdaBoost、CatBoost 就是一些例子。
6.最终确定模型
验证数据集的预测
当您获得了具有最佳超参数和集成的最佳性能模型时,您可以在看不见的测试数据集上验证它。
在整个训练数据集上创建独立模型
验证后,对整个数据集运行一次模型,以确保在训练/测试时没有数据点丢失。现在,你的模型处于最佳位置。
保存模型以备后用
一旦您有了准确的模型,您仍然需要保存并加载它,以便在将来需要时可以使用它。最常见的方法是腌制。
这就是本文的全部内容。当然,这并不是机器学习的全部。但是这可以作为一个很好的路线图来遵循。定制,重复的过程将需要为不同类型的数据/问题。如果你知道更好更关键的技术,请在下面评论你的想法或突出显示。
估计收入增长的贝叶斯方法
使用正态-正态模型的一个实例
图片由来自 Pixabay 的洛伦佐·卡法罗提供
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
也许你是一个投资者,正试图决定一只股票是否值得投资。也许你最近才听说贝叶斯推理,并想了解它在现实世界中的应用。也许您是一位经验丰富的分析师,偶然发现了这篇文章,并觉得标题很有趣。不管你来自哪里,我感谢你阅读这篇文章。我将谈论正态-正态模型,贝叶斯统计中的基础模型之一,以及如何使用它来估计公司收入的增长率。这个评估可以用来决定公司是否值得投资。
这篇文章的第一个目的是展示如何使用正态-正态模型将主观叠加纳入数据分析。第二个是提供一些正态-正态模型和贝叶斯推理背后的直觉,而不会陷入太多的机制中。我会在这里和文末反复说,但这一块不构成投资建议。这是有教育意义的。本文中表达的所有信息和选项均以作者的个人身份发布,独立于作者可能与 RobustWealth,Inc .达成的任何雇佣协议。
有了这个免责声明,让我们开始吧!
手头的任务
财务建模通常是指预测一家公司的基本价值,以得出该公司股票的合理价格估计。一些最常用的评估指标是收入、收益和现金流。我们要考察的公司是 MongoDB,一家软件服务公司。它于 2017 年开始公开交易,收入增长巨大。
在 RStudio 中创建;所有的图和表都是在 RStudio 中创建的
考虑到这家公司还很年轻,而且正处于成长阶段,为了给公司估值,关注收入是合理的。该公司 10-K 文件中的数据,即年度财务报告,显示了从 2016 财年开始的季度收入数据。年度数据从 2014 年开始。为了使用比六个年度数字(转化为五个增长数字)多一点的数据,我计算了季度基础上一年的滚动收入增长。该数据如下所示。
在这篇文章的最后,我将比较使用年终数据和季度数据的分析结果。(虽然我没有进行正式的分析,但我认为季度数据中存在一定程度的序列相关性。这对于解释正态-正态模型的概念来说无关紧要,但在实践中肯定是需要注意的。)
预测公司收入的一种常用方法是使用一定时间内的平均历史收入增长率。对于拥有多年数据的公司来说,这不一定是个坏习惯,尤其是如果增长率遵循正态分布的话。鉴于样本数据如此之少,以及我将在下面绘制的数据直方图,在这种情况下,使用样本均值可能是不明智的。
贝叶斯推理在样本量很小的情况下特别有用,在这种情况下,人们会主观地认为样本数据不能恰当地代表更大样本的情况。
为了进行贝叶斯推理,需要一个先验分布和一个抽样模型。在定义这些分布之前,我将回顾一下贝叶斯推理的一些基础知识,以及先验分布和抽样模型是如何发挥作用的。如果你熟悉贝叶斯定理及其在分布中的应用,可以跳过这一部分。
贝叶斯定理和分布
最简单的形式,贝叶斯定理被定义为
这相当于
如果给一个人明确定义的概率来使用,这一切都很好,但是分布使这个过程有点复杂。
首先,我用 θ 代替 A ,用 Y 代替 B 。在这种情况下, Y 指的是样本数据中的点,而 θ 指的是 MongoDB 收入的真实平均增长率。用上述替换重写公式的第二种形式导致
换句话说,我试图建模的分布是给定样本增长率的平均收入增长率的分布。我将用样本数据和一点点判断来定义这个分布 P ( Y | θ )。我还需要平均增长率的先验分布 P ( θ )和数据的边际分布 P ( Y )。分析员有责任定义抽样分布以及定义 θ 的先验分布。一旦有了采样分布P(Y|θ,获得 P ( Y )的正确方法就是求解下面的积分:
在实践中,这可能很难做到,但有一个捷径。由于在这种情况下 Y 仅取决于 θ ,因此 P ( Y )是一个无条件的概率分布,包含了 Y 的所有可能性。这意味着分布下的面积将等于 1(一个事件的所有概率之和等于 1),积分将等于 1 乘以一个归一化常数。该等式可以更简单地表示为,而不是求解该归一化常数
P(θ|Y)∧P(Y|θ)P(θ)
其中∝代表“与…成比例”换句话说,一个人不需要担心 P ( Y )。完成一项任务后,下一步是定义一个抽样分布和一个先验分布。
(注:技术上, Y 是以样本方差为条件的。在这种情况下,方差被假定为已知的常数。因为方差被假定为已知的常数,所以它可以从符号中省略。)
定义抽样模型和先验分布
我将用一个正态模型来描述抽样分布。查看了数据的直方图后,人们可能会认为有更好的分布来表示数据。在这种情况下,我喜欢正态分布,因为它是连续的,并且沿着所有实数都有支持(收入增长理论上可能是负的或正的)。
为了定义这个采样模型,我将计算这个数据集的均值和方差,并将它们用作采样模型的参数。这将采取的形式是
其中第一项代表 MongoDB 收入的未知真实平均增长率,第二项代表增长率的方差;假设这个方差是已知的。人们可以很容易地假设均值是已知的,而方差是未知的,或者两者都是未知的;所有这三类情况都有很好的记录,并有大量关于如何处理它们的文献。正态-正态模型适用于方差已知而均值未知的情况,因此我做出了目前的假设。
接下来,必须定义θ的先验分布。出于同样的原因,我使用正态分布的采样模型(连续,支持正值和负值),我将使用正态分布作为我的先验。必须为变量θ定义均值和方差。我将这个分布定义为
其中第一项是先验均值,第二项是先验方差。有大量的文献致力于选择先验;这篇文章的主要焦点是如何应用正态-正态模型,所以我没有花大力气定义我的先验分布。
为了选择一个先验均值的值,我查看了过去 19 年(multpl.com)标准普尔 500 指数的平均销售收入增长率,然后乘以 MongoDB 的β。在股票领域,β指的是单个股票回报与更广泛的一篮子股票(通常称为指数)回报的协方差除以指数回报的方差。根据 Seeking Alpha 的数据,MongoDB 的β值约为 1.26,Seeking Alpha 是一个研究网站,提供许多股票的新闻、数据和分析。每当观察到β > 1 时,人们可以假设股票比与之比较的指数更不稳定;为此,我将指数的收入增长乘以β。其他方法可能包括关注软件服务行业中稍微老一点的公司,或者其他行业中年龄相近的公司。没有一种方法是完美的,所有可行的方法都有各自的优点。
下一个必须赋值的参数是先验方差。需要明确的是,这不是增长率的假设方差,而是平均增长率的假设方差;这个先验方差是为了反映先验均值的准确性的确定性。如果完全相信这是使用的正确平均值,方差可以设置为非常接近于 0(出于计算目的,实际上不能使用 0,但一个非常小的数如. 00001 就足够了)。另一方面,如果一个人对估计值没有多少信心,可以用一个很大的方差来表示这个确定性水平。在这种情况下,先验平均值约为 4.5%,我不知道自己对这一估计有多大把握。为了定义我的分布,我将使用 10%的标准差。这样,我可以有效地声明,我 95%相信θ的真实值在-15.5%和 24.5%之间(4.5+/-2 个标准偏差)。鉴于 MongoDB 的平均增长率约为 61%,这一估计可能显得非常保守,但这正是贝叶斯推理强大的原因。MongoDB 大部分时间都在牛市中交易,这对软件公司尤其有利。先验分布反映了来自多个市场周期的数据,从而反映了增长和收缩的多个阶段。在经济收缩的可能性、MongoDB 不能有效地执行其战略的可能性以及仅仅由于规模而导致的收入增长放缓之间,我持有一种主观信念,即 MongoDB 的真实平均增长率低于样本数据所显示的水平。我选择的先验分布代表了这种信念。现在,我可以研究分析的输出。
概括地说,这两个模型的表格如下:
太好了,我们继续分析吧!
后验分析和直觉
我将更多地关注这些形式提供的直觉,而不是手动完成推导。任何真正对使用正态-正态模型感兴趣的人都应该研究上述参数的推导。维基百科有一些很好的文档,大多数贝叶斯统计的入门教材都详细介绍了推导过程。
当正态分布与样本均值上的先验分布的正态结合用于抽样模型时,得到的后验分布是两个正态模型的乘积。正态-正态模型的强大之处在于,这些分布的乘积也是正态分布,尽管有更新的参数。在贝叶斯术语中,正态先验分布是共轭先验分布,这意味着它和它产生的后验分布具有相同的形式。后验分布是正态分布这一事实可能看起来没什么大不了的,但根据要建模的数据和要估计的参数,有许多情况下后验分布并不具有如此熟悉的形式。因为这种后验分布是明确定义的,所以可以直接从中取样,从而很容易计算出它的汇总统计量。
下面的符号和重新参数化来自 Peter Hoff 的教科书“贝叶斯统计的第一课”中的第 5 章,这本书是我在第一次本科贝叶斯统计课程中使用的,也是我最近一直在学习的书。
后验分布采用以下形式
其中第一项指的是后验均值,第二项指的是后验方差。计算这些更新参数的公式如下
和
这些公式可能看起来有点吓人,但希望你能看到它们之间的一些相似之处。对于获得对这些公式的直觉来说,一个常见的并且特别有用的实践是从精度而不是方差的角度来看公式。精度是方差的倒数。
在这种情况下,我们需要观察三个相关的精度:
如果将后验方差公式倒过来计算后验精度,可以看到后验精度用标准差表示为
这可以精确地写成
在这种形式中,显然后验精度是先验精度和样本精度之和乘以样本大小。后验均值也可以根据精度重写:
这里,很明显,后验均值是先验均值和样本均值的加权平均值。
对于数据,后验参数为:
这就是最新的参数。平均增长率的后验估计值约为 52.7% —比样本平均值略低,但并不低得离谱。我采用了一种主观信念,用一种分布来表示这种信念,并用这种分布来增强分析。万岁!这就是贝叶斯推理的力量。只要信念可以被定义,它们就可以以一种严格的方式被纳入分析中。让我们多谈一点我拥有的和我没有的。
有了后验标准差,我就可以计算出估计值的可信区间。对于那些不熟悉贝叶斯统计的人来说,可信区间和置信区间不是一回事,尽管它们是以相似的方式计算的。后验均值的 95%可信区间为 0.527+/2∫0.0391.527+/2∫0.0391,得出 44.88%和 60.52%的点。有了这个可信的区间,我可以断言,我 95%确定后验均值的真实值落在这个区间内。即使在这一点上,我也不把这个更新的平均值当作一个已知的实体。此外,我并不是说 52.7%是我对未来一年滚动收入增长率的预测。如果我想在这个框架内进行预测,我会使用后验预测分布。因为那是一个单独的主题,所以我在这里不涉及它,但是推导那个分布的过程类似于推导后验分布。
从这个分析中应该注意到两个关键的含义:第一个是随着样本量的增加,后验均值和后验方差越来越多地由样本数据决定。我不会说有一个明确的截止点,但在一定数量的数据中,增加一个先验并不会使指针移动太多。直觉上,这是合理的。如果您有足够丰富的采样数据,采样数据可能代表数据中的实际结构,您可能看不到利用先验分布的必要性。
为了强调第一点,我严格使用年终数据重新运行了分析,这将提供五个数据点的样本大小。使用相同的先验分布,新的抽样均值和方差约为 59.8%和. 012(或 11.1%标准差),后验均值和方差约为 23%和. 0019(或 4.45%标准差)。均值的后验估计值比第一次迭代中观察到的值低得多;随着样本量的显著减少,先验在输出中扮演着更重要的角色。标准差变化不大,但我可以看到它变大了,尽管第二次采样的标准差变小了。我的估计要低得多,对估计的信心也略低(可信区间更宽)。
该分析的第二个含义是,先验方差越小,先验精度越高,对后验均值和后验方差的影响越大。一个人对先验越有信心,对后验估计的影响就越大。为了说明这一点,我用先前方差的不同值重新运行了原始分析。先前均值的值都是 0.045,抽样均值和方差来自滚动收入数据。下表显示了该实验的结果。
我也会画出分布图。
注意先验方差设为 0.05 的后验分布与先验均值的接近程度。随着我增加先验方差(有效地表示先验均值的置信度降低),后验分布的中心向样本均值移动。此外,虽然后验方差的变化幅度在表中可能没有那么大,但从上面的分布图中,我们可以看到分布是如何逐渐变宽的;换句话说,平均增长真实值的可信区间扩大了。
摘要
简单回顾一下,我分析了一家年轻的公司,并想估计其收入的真实增长率。考虑到我拥有的少量样本数据和平均增长率将低于样本数据所显示的主观信念,我使用贝叶斯推理来增强分析。我为数据定义了一个抽样模型,为反映主观观点的平均增长率定义了一个先验,并利用正态-正态模型得出公司平均增长率的后验估计和区间。我希望这篇贝叶斯推理的简介以及对结果的分析对你有所帮助。我不建议使用这篇文章中的具体数字来对 MongoDB 进行任何评估,但是希望您可以将这些概念应用到自己的分析中。我附加了一个到 GitHub 代码库的链接;没有什么特别复杂的,但我会本着透明和可复制的精神来分享。
https://github.com/vinai-oddiraju/TDS_Blog_Post1.git
最后,我要感谢那些花时间阅读我的草稿并在整个过程中提供反馈的朋友和家人。由于这是我第一次以这种方式写一个项目,他们的支持尤其值得感谢。谢谢,保重!
放弃
本报告中表达的想法和观点仅代表我个人,不一定代表我公司的观点。本报告旨在提供教育,不应被理解为个人投资建议,也不应被理解为购买、出售或持有任何证券或采取任何投资策略的建议。
来源
[1]霍夫,彼得 D. 贝叶斯统计方法的第一课 (2007)。打印。
R/Python 中线性混合模型(LMM)的贝叶斯方法
视频教程
实现这些比你想象的要简单
似乎有一种普遍的误解,认为贝叶斯方法比 T4 的方法更难实现。有时这是真的,但是更多的时候现有的 R 和 Python 库可以帮助简化这个过程。
更简单的实现≠扔进一些数据,看看有什么坚持。(我们已经有了这方面的机器学习。😛)
人们让贝叶斯方法听起来比实际更复杂,主要是因为其中涉及了很多术语(例如*弱先验、后验预测分布、*等)。)这并不直观,除非您以前使用过这些方法。
意识形态的冲突加剧了这种误解——“频繁主义者与贝叶斯主义者之争。”(如果你以前不知道,现在你知道了。)问题是人们,尤其是统计学家,通常会争论哪种方法更有效,而事实上答案是“视情况而定”
证据一:这是一个温和的例子,说明为什么这场争吵毫无意义https://twitter.com/RevBayes/status/506577193804111872
贝叶斯方法,像其他任何方法一样,只是我们使用的工具。它们有优点也有缺点。
因此,随着一些个人的“热点”的方式,让我们继续有趣的东西,并实现一些贝叶斯线性混合(LMM)模型!
一眼
以下是我将要介绍的内容(包括 R 和 Python):
- 选择先验的实用方法(需要定义贝叶斯模型
- 如何使用 R 和 Python 实现贝叶斯 LMM 的分步指南(分别使用
brms
和pymc3
) - 快速 MCMC 诊断有助于您在流程早期发现潜在问题
贝叶斯模型检查、比较和评估方法不在本文讨论范围内。(评价一个模特的方式比 RMSE 多。)我已经发表了一篇 的后续文章,更详细地介绍了这些 。
Python 教程
r 教程
设置
如果你对混动车型不熟悉我推荐你先 复习一下这里覆盖的一些基础 。同样,如果你对贝叶斯推论不是很熟悉的话我推荐 艾林金*的惊人文章 向前看。*
让我们回到我在上一篇文章中提到的营销例子。简而言之,我们的数据集由模拟的网站反弹时间(即客户在网站上花费的时间长度)组成,而的总体目标是找出年轻人在网站上花费的时间是否比老年人多。
该数据集有 613 个观察到的“反弹时间”(bounce_time
,秒),这些时间是在 8 个位置(county
)收集的,每个位置都有一个关联的age
,该关联的【】后来被中心缩放(std_age
)。但是,每个位置的观测值数量各不相同(例如,一个位置有 150 个观测值,而另一个位置只有 7 个)。
步骤 1:探索性数据分析(EDA)
EDA 是数据分析的无名英雄,你不应该认为它只是绘制数据。
(我会远离那些暗示它是“无聊的东西”的帖子,或者那些只是希望自动化它以便你可以直接进入建模的帖子,即使你使用的是 ML 算法。如果你这样做,你就错过了一个非常强大的工具。)就个人而言,我认为这是你的分析工作流程中最关键的步骤之一。它可以作为一个迭代工具来帮助你调整你的建模策略,特别是当你的策略是从简单的开始,逐步建立更复杂的模型时。
EDA 不仅仅是绘制数据,它还是一种迭代工具,可以帮助您调整建模策略。
例如,在我们的例子中,我们可以拟合的最简单的模型是使用sklearn
(Python)或lm
®的基本线性回归,并看看它如何捕捉我们数据中的可变性。
我们也可以考虑更复杂的模型,比如线性混合效应模型。同样,通过一些 EDA,我们看到这种模型可以更好地捕捉群体可变性,因此可能是更好的策略。我们可以使用seaborn.lmplot
或 ggplot2 的geom_smooth
快速构建一些直观的 EDA 图。这里看起来变截距和变截距/变斜率模型可能是很好的研究对象。(我们的 EDA 还揭示了一个辛普森悖论的例子,其中一条全局回归线与单个县的趋势不匹配。)
我们将继续进行三个候选模型:线性回归、随机截距模型和随机截距+斜率模型。
(简单的线性模型被视为基线,有助于举例说明建模过程。)
步骤 2:在一些虚假数据的帮助下选择先验
注意:在这一点上,我假设你熟悉贝叶斯推理,不会深入到它的主要组成部分。如果你不是,停下来,去看看上面推荐的阅读材料。
贝叶斯推理要求我们在完全定义我们的模型之前为我们的参数选择先验分布(“先验”)。与其使用先验信息,还不如选择先验信息。**************
但是你如何定义什么是“弱”先验呢?
好的弱信息先验考虑了你的数据和被问到的问题,以生成可信的数据集。
定义弱信息先验的一个常用策略是根据你的可能性和先验组合创建一个模拟数据的“活页本”。(该程序被称为预先预测检查*。)不要将先验视为独立的(边缘)实体,用它们模拟数据可以让我们了解它们如何与可能性相互作用,以及这对先验是否会生成似是而非的数据点。*
我们的变截距模型和先验的概率定义
例如,让我们尝试为我们的随机截距模型参数* (β0、β1、B0、τ0 和σ)选择弱先验,并模拟一些数据。*
我通过一种迭代策略选择了上述先验,这种策略将 EDA 步骤中关于人口和群体趋势的信息与特定群体的经验均值和方差估计相结合(见下文)。你必须根据你自己的数据和正在考虑的问题来探索一些选择。
R 模拟
Python 模拟
定义弱信息先验的常用策略是创建模拟数据的“翻页书”(也称为先验预测检查)。
下面是一本电子书的例子( 左动画 )。**我们看到大多数模拟数据点都是“合理的”,这意味着我们看到大多数假数据点都在我们当前的反弹率范围内(≈160–250)。其他数据超出了我们的数据范围,但仍在可信范围内(例如,高达 500–600 秒)。相反,如果我们使用通用弱先验***[例如 N(0,100)和 Inv-Gamma(1,100)],我们会看到许多模拟的反弹率< 100 秒。甚至是< 0,这显然是概率较小的( 右 )。*
**
如果你有兴趣了解更多关于如何选择优先的信息,请查看 Stan 开发团队的资源页面。
步骤 3:拟合贝叶斯模型
在前面的步骤中已经选择了一些合理的弱先验*,我们现在可以专注于从步骤 1 构建我们的候选模型。正如我在本文开头提到的,R 和 Python 中有现有的库可以大大简化拟合贝叶斯线性混合模型。*
1) [**brms**](https://paul-buerkner.github.io/brms/index.html)**: an**
运行在 Stan 上的 R 包
如果你熟悉lme4
和lmer
函数的公式生成器,那么你已经成功了 90%。是的,就这么简单!除了一些指定贝叶斯设置的附加选项,brms
提供了简单明了的功能。如果你深入了解它的所有功能——拟合 gam,模拟高斯过程,甚至通过mice
输入数据,这是一个出色的库。我不会在这里讨论这些,但是我鼓励你多读一些。
下面是使用我们的反弹时间数据,用brms
实现变截距模型的例子。首先,该软件包通过内置函数prior
使定义先验变得容易,该函数将分布分配给选定的模型参数类、组或系数(prior(distribution(...), class=..., group=..., coef=...)
)。例如,我们可以将截距的法线先验设置为prior(normal(...), class=Intercept)
。您可以使用内置函数get_prior()
来了解如何设置这些标志。类似地,您可以从广泛的可用分布中选择先验。
接下来,您可以用brm
函数拟合模型,该函数提供了与lmer
类似的公式生成器和选项。你可以进一步修改贝叶斯方法特有的选项比如要运行的 MCMC 链的数量和运行长度。
从模型中提取基本信息很简单。该库提供打印与模型拟合summary()
和后验估计posterior_summary()
相关的模型概要的功能。
注:使用
bounce_time ~ 1 + std_age
公式时,BRMS 假设预测值为均值居中。如果你的预测不是以均值为中心,你应该使用bounce_time ~ 0 + intercept + std_age
来代替。你可以在这里(第 38-39 页)阅读更多内容
2)运行在和上的 PyMC3 : a Python library
尽管有多种库适合贝叶斯模型,但 PyMC3 无疑提供了 Python 中最用户友好的语法。虽然新版本正在开发中(PyMC4 现在运行在 Tensorflow 上),但这个库中的大多数功能将在未来的版本中继续工作。
与 R 中的
**brms**
包相比,P**yMC3**
要求你显式地陈述模型的每个单独的组件——从先验到似然。
完整的规范并不像听起来那么糟糕。一旦您指定了模型(如左图所示),使用上下文管理器来构建就变得简单了。
嗯,大部分时间😉。
对这个包唯一的警告是你的模型的参数化会对它的采样效率有很大的影响。
例如,下面的模型代码使用了与上面所示模型略有不同的参数化(即居中参数化)。
首先,我们用上下文管理器和pm.Model()
方法初始化模型。这将基本上封装一个模型的变量和可能性因素。接下来,我们可以开始使用多种内置分布为我们的每个组件(先验、超先验和似然)分配分布。
建立模型分布很简单。首先通过pm.your_distribution_class()
定义你想要使用的分布类,然后给它分配一个标签并修改它的分布参数,最后把它分配给一个上下文变量* (例如beta1=pm.Normal('std_age', mu=mu0, sigma=tau0)
用标签std_age
和参数mu0
和tau0
把beta1
定义为普通的)。*
一旦你的模型组件被设置好,你只需要设置pm.trace()
函数来存储你的后验样本。与brms
类似,您还可以进一步修改贝叶斯方法的特定选项,例如要运行的 MCMC 链的数量和运行长度。
由于 PyMC3 依赖于arviz
进行事后可视化,因此有必要将模型输出保存为InferenceData
类型,以便以后在模型诊断和事后检查中使用。
上述随机截距模型的输出;alpha 表示特定于县的拦截
步骤 3.a: MCMC 诊断
唷!这是很多信息。然而,没有一些好的诊断,任何建模努力都是不完整的。(注意:模型检查、评估和比较也是这个过程的一部分,但是我会在另一篇文章中更详细地介绍它们。)
传统上,两种诊断可视化方法——MCMC 迹线图和自相关函数(ACF)图——有助于我们了解采样是否存在问题。换句话说,我们的样本以及我们的推论有多可靠?这些工具诉诸于马尔可夫链的一些理论属性,并且是理解马尔可夫链性能的良好的检查。然而,brms
和pymc3
使用先进的 MCMC 方法,这些方法提供了额外的诊断,可以更精确地了解它们的性能。
除了常规诊断之外,其他方法也可用于高级技术,如哈密尔顿蒙特卡罗 (HMC),可以提供更详细的马尔可夫链性能图。
让我们深入了解一个实施传统和 HMC 相关诊断的示例。
传统 MCMC 诊断
上面强调的两个常见的可视化帮助我们理解
在 R 中,您可以使用适合您的模型使用bayesplot
中的mcmc_trace
和mcmc_acf
功能轻松生成这些。
线性回归示例
R 中线性回归模型的跟踪图(左)和自相关图(右)
Python pymc3
中的有一个内置的集成,通过arviz
来可视化这些,你只需要模型中指定的 trace 对象。****
Python 中线性回归模型的追踪图(左)和自相关图(右)
哈密尔顿蒙特卡罗诊断
如上所述,哈密顿蒙特卡罗提供了我们可以使用的额外诊断。pymc3
和brms
都运行在一个叫做不掉头采样的非常高效的 HMC 采样器上。
这里粗一句话,高级总结:
HMC 使用一阶梯度来指导有用方向上的采样,这有助于它比传统的 MCMC 方法更快地收敛到后验,并且 NUTS 动态更新可以影响 HMC 性能的参数(即,步长ε和步数 L)。
坚果,对不对?!(希望大家能原谅不好的双关语)。为了澄清最后一点,考虑一下在类似梯度的更新方面发生了什么,例如,如果你选择的步长太小或步长数太高,你可能会浪费计算时间。虽然这是一个有用的类比,但该算法如何工作的细节更加复杂和优雅。
回到“那又怎样,伙计?”嗯,在链没有混合或者 ACF 显示出对样本的更高依赖性的情况下,很难诊断发生了什么。
然而,如果你使用 HMC 或坚果,你可以看看****发散过渡,这可以帮助你了解你的后臀的几何形状(!!)。当建议的下一步偏离采样器设定的最有效路径时,就会出现这些问题。****
发散是强有力的诊断,它允许你理解后几何。
想象这些可以在两个方面有所帮助:****
- ****检测您的采样器在穿越后部“景观”时遇到困难的“位置”(可能是由于局部高度可变性或弯曲的几何形状)。在这种情况下,您可以考虑重新参数化您的模型,以“平滑”那些高曲率区域。
- 排除“假阳性”偏差(标记的偏差转换与非偏差转换表现相同)
下面的例子说明了发散如何帮助识别链被“卡住”或被错误标记为发散 (绿色) 。在左图和右图中,绿色点或线高度集中的区域表明存在收敛问题(即,您可以在下面的tau
中看到这种漏斗状集中)。在这里,采样器不能充分探索由tau
定义的后部区域,因此我们对tau
的推断是不可靠的。相反,在轨迹被错误地标记为发散但表现得像非发散轨迹的情况下,我们也可以获得其他参数推断的置信度(例如theta1,...,theta8
)。
Gabry,Jonah 等人(2019 年)
要了解更多关于解释这些强有力的诊断图的信息,请查看迈克尔·贝当古的这篇文章。要在 R 中运行该诊断,使用bayesplot
中的 **mcmc_scatter**
功能。
在 Python 中你可以使用plot_parallel
PyMC3 内置函数。
在这种情况下,我们可以看到没有任何像上面看到的发散轨迹,因此我们的链毫无困难地探索了后面的几何形状(即收敛)。
**********
Python(左)和 R(右)中的不同诊断
结论
像pymc3
和brms
这样的软件包极大地简化了贝叶斯模型的拟合。然而,实现更简单并不意味着我们应该忘记建模过程中的关键步骤,这些步骤可以帮助我们构建更好的模型。
我希望你已经学会了一些选择好的先验分布的新方法,如何对贝叶斯混合模型进行故障诊断,以及为什么 EDA 可以是一个强大的工具(不仅仅是在贝叶斯设置中)。
最后,我的希望是让人们不要因为“它们听起来很难”而回避贝叶斯方法,而是为他们提供可以添加到他们的工具集中的新方法。
参考
- Gelman,a .,Carlin,J. B .,Stern,H. S .,Dunson,D. B .,Vehtari,a .,和 Rubin,D. B. (2013 年)。贝叶斯数据分析。CRC 出版社。
- **盖布里、乔纳等人,《贝叶斯工作流程中的可视化》英国皇家统计学会杂志:A 辑(社会中的统计学)182.2(2019):389–402。
如果你喜欢这篇文章,请随意分享!如果您有任何问题,或者您看到任何不正确/有问题的内容,请发表评论或发推文( @ecoronado92 )。
所有的 R 代码都可以在这里找到
所有的 Python 代码都可以在这里找到
***** [## ecoronado 92/走向 _ 数据 _ 科学
报告包含的材料和例子实施贝叶斯线性混合效应(层次模型)模拟…
github.com](https://github.com/ecoronado92/towards_data_science/tree/master/hierarchical_models/bayes_lmm) [## 当混合效应(分层)模型失败时:汇集和不确定性
一个直观和可视化的指南,其中部分池变得麻烦,贝叶斯方法可以帮助量化…
towardsdatascience.com](/when-mixed-effects-hierarchical-models-fail-pooling-and-uncertainty-77e667823ae8) [## 在 R/Python 中评估贝叶斯混合模型
了解“后验预测检查”的含义以及如何直观地评估模型性能
towardsdatascience.com](/evaluating-bayesian-mixed-models-in-r-python-27d344a03016)*****
对神经网络如何工作的初学者友好的解释
五岁儿童理解神经网络基础知识
目录
- 前言
- 人工智能、机器学习和神经网络
- 基本神经网络的机制
- 神经网络的类型
- 神经网络应用
前言
几周前,当我开始学习神经网络时,我发现对于这样一个复杂的主题来说,介绍性信息的质量是不存在的。我经常读到神经网络是模仿大脑的算法,或者具有类似于大脑的结构,这并没有真正帮助我。因此,本文旨在以任何人都可以理解的方式教授神经网络的基础知识,尤其是那些机器学习的新手。
人工智能、机器学习和神经网络
在了解什么是神经网络之前,我们需要先退几步,了解什么是人工智能和机器学习。
人工智能和机器学习
同样,这令人沮丧,因为当你谷歌人工智能的意思时,你会得到类似“它是机器对人类智能的模拟”的定义,尽管这可能是真的,但它可能会对新学习者产生误导。
从最简单的意义上来说,人工智能(AI) 指的是赋予机器或软件基于预定义的规则或模式识别模型做出自己决定的能力的想法。模式识别模型的想法导致了机器学习模型,这是一种基于样本数据建立模型的算法,可以对新数据进行预测。注意,机器学习是人工智能的一个子集。
有许多机器学习模型,如线性回归、支持向量机、随机森林,当然还有神经网络。这让我们回到了最初的问题,什么是神经网络?
神经网络
从根本上来说,神经网络本质上是数学方程的网络。它接受一个或多个输入变量,并通过一个方程式网络,产生一个或多个输出变量。你也可以说一个神经网络接受一个输入向量并返回一个输出向量,但是我不会在本文中讨论矩阵。
基本神经网络的机制
再说一次,我不想太深入地了解其中的机制,但是向您展示一个基本神经网络的结构是什么样子是值得的。
在神经网络中,有一个输入层,一个或多个隐藏层,以及一个输出层。输入层由一个或多个特征变量(或输入变量或独立变量)组成,表示为 x1,x2,…,xn。隐藏层由一个或多个隐藏节点或隐藏单元组成。节点就是上图中的一个圆圈。类似地,输出变量由一个或多个输出单元组成。
给定的层可以有许多节点,如上图所示。
同样,给定的神经网络可以有许多层。通常,更多的节点和更多的层允许神经网络进行更复杂的计算。
上面是一个潜在的神经网络的例子。它有三个输入变量,批量、卧室数量和平均。家庭收入。通过向这个神经网络提供这三条信息,它将返回一个输出,房价。那么它到底是如何做到这一点的呢?
就像我在文章开头说的,神经网络只不过是一个方程网络。神经网络中的每个节点由两个函数组成,一个线性函数和一个激活函数。这是事情变得有点混乱的地方,但是现在,把线性函数想成一些最佳拟合线。另外,把激活功能想象成一个电灯开关,它会产生一个介于 1 或 0 之间的数字。
发生的情况是,输入特征(x)被馈入每个节点的线性函数,产生值 z。然后,值 z 被馈入激活函数,激活函数确定灯开关是否打开(在 0 和 1 之间)。
因此,每个节点最终确定下一层中的哪些节点被激活,直到它到达输出。从概念上讲,这是神经网络的本质。
如果您想了解不同类型的激活函数,神经网络如何确定线性函数的参数,以及它如何像“机器学习”模型一样进行自学,您可以在网上找到专门针对神经网络的完整课程!
神经网络的类型
神经网络发展如此之快,以至于现在有几种类型的神经网络,但下面是你可能经常听说的三种主要类型的神经网络。
人工神经网络
人工神经网络(ann)就像上面图像中的神经网络,它由一组连接的节点组成,这些节点接受一个或一组输入并返回一个输出。这是最基本的神经网络类型,如果你上过课的话,你可能会首先学到。人工神经网络由我们讨论过的所有内容以及传播函数、学习率、成本函数和反向传播组成。
卷积神经网络(CNN)
卷积神经网络(CNN)是一种使用称为卷积的数学运算的神经网络。维基百科将卷积定义为对两个函数进行数学运算,产生第三个函数,表达一个函数的形状如何被另一个函数修改。因此,CNN 在其至少一层中使用卷积而不是一般的矩阵乘法。
递归神经网络(RNN)
递归神经网络(RNNs)是一种人工神经网络,其中节点之间的连接沿着时间序列形成一个有向图,允许它们使用内部存储器来处理可变长度的输入序列。由于这一特性,rnn 在处理序列数据方面表现出色,如文本识别或音频识别。
神经网络应用
神经网络是强大的算法,它带来了一些以前不可能实现的革命性应用,包括但不限于以下内容:
- 图像和视频识别:由于图像识别功能,我们现在有了像安全面部识别和 Bixby 视觉这样的东西。
- 推荐系统:有没有想过网飞总是能够推荐你真正喜欢的节目和电影?他们很可能利用神经网络来提供这种体验。
- 音频识别:如果你没有注意到的话,“OK Google”和 Seri 在理解我们的问题和我们说的话方面已经变得非常好了。这一成功可以归功于神经网络。
- 自动驾驶:最后,我们在完善自动驾驶方面的进步很大程度上要归功于人工智能和神经网络的进步。
摘要
总结一下,以下是要点:
- 神经网络是一种机器学习模型或机器学习的子集,机器学习是人工智能的子集。
- 神经网络是一个方程网络,它接受一个输入(或一组输入)并返回一个输出(或一组输出)
- 神经网络由各种组件组成,如输入层、隐藏层、输出层和节点。
- 每个节点由一个线性函数和一个激活函数组成,最终决定了下一层中的哪些节点被激活。
- 有各种类型的神经网络,如 ann、CNN 和 RNNs
感谢阅读!
特伦斯·申
创始人ShinTwin|我们来连线一下LinkedIn|项目组合这里是。
一个初学者友好的数据科学项目列表
通过做开放数据集的项目来学习数据科学
图片由皮克斯拜的 Gerd Altmann 提供
数据科学和相关领域是世界上增长最快的就业机会之一。他们使用广泛的方法,包括应用机器学习、人工智能、数据挖掘和数据分析。
在大数据时代,数据工程师变得越来越重要,在数据工程领域有许多不同类型的数据科学家。他们可以被视为一种“数据架构师”,负责数据管理、产品管理和数据可视化。数据科学家在大数据应用程序中使用的数据通常来自多个来源,并以优化分析、商业智能和建模的方式进行提取、存储、转换、集成、移动、提取和集成
数据挖掘将算法应用于复杂的数据集,以发现模式,然后用于从数据集中提取有用和相关的数据。数据科学由多个学科的工具组成,用于收集和提取有意义的数据,并为决策目的解释数据集。
统计测量和预测分析用于提取数据,以根据数据显示的情况和过去发生的情况评估未来事件是否可能发生。
数据科学生命周期的自动化使有经验的数据科学家能够专注于该领域更有趣和创新的方面。数据科学在不断发展,编程经验(模型、机器学习和自动化)的结合使行业保持敏捷和创新。
如今,成功的数据专家明白,他们不仅需要提高分析数据的能力,还需要提高分析数据模型、数据结构和数据分析工具的能力
基于项目的学习是学习新事物的最佳方法之一,它促进思想交流和健康合作。你可以在自己家里进行实验来测试假设和想法。更重要的是,第一手经验提供了成为积极参与者的机会,而不仅仅是旁观者。从错误中学习,帮助你从新手变成这方面的专家。
与项目相关的学习促进通过提问和研究开发的批判性思维技能。历史上一些最伟大的思想家是基于项目的学习方法的支持者。
这里是一些初学者友好的数据科学项目列表;
红酒质量
这两个数据集与葡萄牙“Vinho Verde”葡萄酒的红色和白色变种有关。有关更多详细信息,请参考参考文献[Cortez 等人,2009 年]。由于隐私和逻辑问题,只有物理化学(输入)和感官(输出)变量可用(例如,没有关于葡萄类型、葡萄酒品牌、葡萄酒销售价格等的数据。).
这些数据集可以被视为分类或回归任务。等级是有序的,而不是平衡的(例如,普通葡萄酒比优质或劣质葡萄酒多得多)。
项目类型:预测建模|链接到数据集
麦当劳菜单的营养事实
该数据集提供了美国麦当劳菜单上每个菜单项的营养分析,包括早餐、牛肉汉堡、鸡肉和鱼肉三明治、薯条、沙拉、苏打水、咖啡和茶、奶昔和甜点。
项目类型:探索性数据分析|链接到数据集
美国的污染
该数据集处理美国的污染情况。美国的污染情况已由美国环保局详细记录,但下载所有数据并以数据科学家感兴趣的格式对其进行排列是一件很麻烦的事情。因此,我收集了 2000 年至 2016 年每天的四种主要污染物(二氧化氮、二氧化硫、一氧化碳和臭氧)
项目类型:可视化|链接到数据集
世界幸福报告
幸福得分和排名使用了盖洛普世界民意调查的数据。分数是基于对调查中主要生活评价问题的回答。这个问题被称为坎特里尔阶梯(Cantril ladder),要求受访者想象一个阶梯,其中最美好的生活可能是 10 分,最糟糕的生活可能是 0 分,并在这个尺度上对他们目前的生活进行评级。这些分数来自 2013 年至 2016 年的全国代表性样本,并使用盖洛普权重使估计值具有代表性。
项目类型:探索性数据分析|链接到数据集
夏季奥运会奖牌
这个数据集是从 1976 年蒙特利尔到 2008 年北京的所有夏季奥运会奖牌获得者的列表。它包括在此期间颁发的每一枚奖章。这个数据集是为初学者设计的,这样他们可以体验一下高级的 Excel 函数,这可能是成为一名伟大的数据科学家所需的关键技能之一。我也接触过数据集,玩过一些高级的 Excel 函数。此外,该数据集还可以用于预测模型,例如哪个国家可能在特定的运动类别中获得最高数量的金牌(仅仅是一个例子)等。
项目类型:探索性数据分析|链接到数据集
新冠肺炎开放研究数据集挑战(CORD-19)
作为对新冠肺炎疫情的回应,白宫和一个领先的研究团体联盟准备了新冠肺炎开放研究数据集(CORD-19)。CORD-19 是超过 135,000 篇学术文章的资源,包括超过 68,000 篇关于新冠肺炎、新型冠状病毒和相关冠状病毒的全文。
项目类型:探索性数据分析|链接到数据集
数据科学统计学入门指南第一部分
统计的内容、原因和方式
使用 python 中的 WordCloud 创建, Github 代码
什么是统计学?我们为什么需要统计数据?如何用统计学做数据分析?什么是人口?为什么我们有样本?…….这样的例子不胜枚举。嗯,这些是初学者在第一次尝试进入这个领域时会问的少数几个问题。在这篇文章和接下来的文章中,我将以一种超级简单的方式解释统计学的基本概念。敬请关注!!
什么是统计?
根据维基百科,“ 统计学 是一门关于数据收集、分析、解释和呈现的数学科学。”
这是一门从数据中学习并做出决策的科学。不多不少。
我们为什么需要统计数据?
我们生活在数字时代,在每一点上,我们都在产生数据,即信息。这些信息中的大部分都是通过使用统计学进行数学解释的。例如,如果你在谷歌上搜索一个印度人的平均身高,它会显示 5 英尺。怎么会?你认为他们问过所有 13.3 亿人吗?嗯,这很难要求(考虑到时间、金钱和资源)……那他们怎么会说印度人的平均身高是 5 英尺。这都是因为统计学及其各种解读感兴趣人群的方法。
统计学提供了更好地理解数据的工具。如果使用得当,统计数据可以告诉我们过去发生的任何趋势,并有助于预测未来可能发生的事情。
统计学中首要的事情是理解人口和样本的含义,以及它们之间的区别。
- **人群:**通俗地说,人群包括每个人和你感兴趣的每个人。例如,如果您对某个特定国家(比如印度)的平均体重感兴趣,那么该国的每个人都属于您的人口数据。
- **样本:**随机选取的总体子集。统计的唯一目的是发现关于人口的一些重要的东西,但是考虑到人口的规模,获得整个人口的数据是不切实际的,并且需要大量的资源和时间。所以通常我们会收集一个代表总体的样本。
通常,统计分为两部分:
-
描述性统计:描述数据(样本/可见数据)或通过数值计算或图形或表格对数据进行总结的统计部分。举个例子,假设你有一个 100 人的班级在学习物理。现在你可能会对这些学生在期中的整体表现感兴趣。描述统计学允许我们这样做。
然而,描述性统计不允许得出数据以外的结论(关于人口)。它只是简单地说明你有什么数据。通常,有两种类型的统计用于描述数据:
- **集中趋势的测量:**这些是描述数据中心位置的方法,即一个单一的值,它告诉我们数据的中心在哪里。数据的中心位置可以用 表示 、 方式、 和 中值 来描述。
- 分布度量:这些是通过描述数据在集中趋势上的分散程度来总结数据的方法。例如,我们 100 名学生在测试中的平均分数可能是 80 分。但是,并不是所有的学生都会有 80 分。相反,他们的分数会分散开来。有些会高于 80,有些会更低。分布的度量帮助我们总结数据围绕中心趋势的分散程度。为了描述这种差异,可以使用几种统计数据,包括 方差标准差四分位数 等。
2。推断统计:它是统计的一部分,根据从总体中抽取的样本得出关于总体参数的结论,如平均值、众数、中位数。因此,样本准确地代表总体是很重要的。它包括抽样和假设检验。例如,你有 100 名学生学习物理的分数数据。你想总结一个城市所有学习物理的学生的分数,推理统计可以帮助你实现这个目标。
平均值
它是所有数据点的平均值。如果有 n 个数据点 x1,x2,x3,…,xn ,那么数据的平均值将为
样本均值公式
x̅ (x-bar)代表统计中的样本均值。
上述公式也可以用希腊符号σ(sigma)来表示
样本均值公式
同样,当我们计算大小为 N 的总体的平均值时,它被称为总体平均值,用 μ (mu)表示
人口平均数公式
中间值
它是分隔数据样本的上半部分和下半部分的值。排序时,它是数据的中点。
要计算 n 个数据点的平均值,只需对数据进行排序,找到中间的元素。可能有两种不同的情况:
例如:
图片来源:维基百科
与平均值相比,使用中位数描述数据的主要优点是用于偏斜数据(存在异常值的数据,异常值是指与大多数观察值不同的值。这些或者是自然发生的,由于设备故障,或者是由于输入错误。).在数据有偏差的情况下,中位数更准确地描述了数据。
例如,考虑一下美国个人的收入。如果你把比尔·盖茨的收入作为样本中的一个数据点,这个数据是高度倾斜的,因为与美国任何正常人相比,比尔·盖茨的收入都是巨大的,这使得数据高度倾斜。因此,在这种情况下,通过平均值描述您的数据将不是一个近似的选择,因为平均值将主要代表比尔盖茨的工资。因此,收入中值将是代表美国个人收入的更好方式。
模式
它是数据集中最常见的值,即在数据中出现频率更高的值。比如样本[1,3,3,3,3,6,6,6,7,7,7,7,7,12,12,17]的众数是 7。该模式是最容易理解和快速可见的。日常生活中的许多决定都是基于模态概念做出的,比如去大多数人去的地方看电影,或者选择大多数人买的冰淇淋类型。
如果数据包含多个出现频率最高的值,则您有一个多模态分布。如果没有值重复,则数据没有模式。通常,您可以对分类数据、序号数据和离散数据使用该模式。
模式是可用于分类数据(分为不同类别的数据点)的唯一集中趋势测量方法,例如印度最受欢迎的旅游地点。
均值/众数/中位数用哪个?
这完全取决于你有什么类型的数据。如果您的数据是对称的,平均值是描述数据中心的最佳值。如果你的数据是高度倾斜的,使用中位数;如果你的数据是绝对的,使用众数。
差异
它是平均离差的平方。高方差意味着数据高度分散,而小方差意味着数据紧密聚集。总体方差用σ表示,而样本方差用 s 表示。
让我们考虑 n 个元素的样本总体,x1,x2,…,xn。用样本人口的平均值 **x̅.**数据的样本方差是样本均值和每个数据值之间的平均平方距离。
样本总体方差公式
同样,对于人口方差
人口方差公式
为什么有 n-1 个欠样本方差计算?样本方差始终小于总体方差,因此,自由度被视为转换因子。这就是所谓的 贝塞尔修正 。
标准偏差
就像方差一样,标准差也是数据点相对于平均值的分布的度量。唯一的区别是它是方差的平方根。这使得它具有与数据相同的单位,从而便于从洞察力中理解解释。总体标准差用σ表示,而样本标准差用 s 表示。
样本标准差公式
与均值相似,标准差也受异常值和偏斜分布的影响很大。
为什么测量标准差而不是方差?
- 因为标准差与原始 观察值具有相同的单位。
- 它是高斯(正态)分布中传播的自然量度。
目前就这些。请继续关注下一篇文章,了解其他有用的概念。快乐学习😊。
使用 Web APIs 访问数据的初学者指南(使用 Python)
利用 web APIs 的强大功能,为您的数据科学项目挖掘丰富的结构化数据源
文章大纲
- 什么是 API?什么是 web API,它与数据科学有什么关系?
- API 请求的剖析
- 发掘 Reddit 的秘密——使用 Python 的 Reddit web API 演练
- 用开发工具发现隐藏的 API
- API 礼仪和最佳实践
什么是 API?
如果你曾经花时间在编程、数据科学或 web 开发上,你可能会遇到“API”这个术语。即使对一个完全外行的人来说,这个术语也可能耳熟能详。无论您是否熟悉这个概念,您每天都要与 API 进行交互,因为它们在最近几年已经变得无处不在,并且为您可能会发现不可或缺的许多平台和服务提供了便利。
根据字面定义,API 是一个应用程序编程接口。它是一种媒介,不同的应用程序可以通过它以编程的方式相互通信。
举个具体的例子,考虑一下登录一个 app 比如 Medium 的过程。你可以选择使用谷歌或脸书登录。在这种情况下,Medium 应用程序通过谷歌或脸书开发的 API 访问你的用户数据。这种 API 被许多应用程序和平台广泛使用,这减少了应用程序创建者的开发时间,并增加了最终用户的易用性。
API 也有助于数据科学家,因为它们是从各种服务和平台访问大量结构化数据的直接途径。例如,TMDB 的 API 允许用户找到关于电影和表演的信息,而的 Spotify API 给你提供关于他们歌曲的深度信息(比如“danceability”和“valence”),你很难通过其他方式找到这些信息。
还有许多其他有趣的事情可以用 API 来做或自动化,这超出了本文的范围。例如,你可以使用 Spotify 的 API 来编程控制你账户上的音乐播放。您甚至可以将多个 API 连接在一起,让它们协同工作。IFTTT.com网站允许你将 API 链接在一起,以创建基于特定条件触发的小程序。例如,当你收到新的 Twitter 通知时,你可以通过组合相应产品的 API,让你的 Phillips Hue 灯泡改变颜色。
API 请求的剖析
为了利用 web APIs,我们必须发出一个“请求”。这种请求将通过 HTTP 协议进行。请求本质上是您和远程服务器之间的通信,其中您传达了您试图实现的目标(例如,获取一些数据或创建一个新的博客帖子)。收到请求后,服务器会处理您的请求,提供响应,并在后端执行任何额外的过程,这些过程通常对最终用户是不透明的。
有各种类型的 HTTP 请求,但是出于本文的目的,我将把重点放在“获取请求”上,因为我们的目的是使用 API 来获取有用的数据。如果您想了解其他类型请求的更多信息,您可以点击这里查看。
通常,请求将包括以下部分:
- 端点
- 请求类型
- 因素
- 头球
- 响应,响应代码
从广义上讲,当我们提出请求时,我们必须将它指向某个位置。位置或“端点”将由我们试图做的事情或我们请求的信息决定。当我们发出请求时,我们可以传递一组参数,这些参数增加了请求的特定性,还可以传递一些消息头,这将在后面解释。然后,服务器将(希望)提供一个响应(通常以 JSON 形式)和一个响应代码(表明请求是否成功)。
为了更好地说明这个过程,我将使用 Reddit API 和 Python 做一个简单的练习。
使用 Reddit API
Reddit API 是由 Reddit 官方创建和维护的,它允许你做任何你能在网站上正常做的事情,比如浏览热门帖子、写评论和提交新的提交内容。出于我们今天的目的,我们将使用 API 来确定任何给定子编辑的前 5 篇帖子,以及与每个帖子相关的一些元数据。在使用新工具时总是这样,在开始编程之前浏览一下官方文档会很有帮助。
我们需要确定的第一件事是端点,它从本质上定义了我们到底想要请求什么。在这种情况下,我们想要的端点是 https://www.reddit.com/r/{subreddit_name}/top.json 的“”,因为这将返回属于给定子编辑的顶部帖子。我通过浏览文档找到了这个端点,并选择了一个符合我需要的端点。我们实际上可以在浏览器中查看这个 URL,并看到响应正文如下所示。默认情况下,我们得到的是一大堆相对难以解读的文本。我强烈推荐安装一个 JSON 解析器,比如 JSONViewer for Chrome,它有助于清理 JSON,使它更容易访问。
(JSON 是一种数据存储格式,代表 Javascript 对象表示法,虽然不是 Javascript 的专属。本质上,它是一个包含一系列键值对的长字符串,类似于 Python 字典。当通过 web 传输数据时,JSON 通常是首选的媒介)
JSON 响应的前几行
我们看到的是,在属性“儿童”下,我们得到一个帖子列表。这里的每个帖子都是给定子编辑中排名靠前的帖子之一。在每个帖子的数据中,我们可以找到关于该帖子的更多元数据,例如“gilded ”,这表明该帖子在 Reddit 的说法中是否被授予了“gold”、“title ”,这是该帖子的标题,以及“ups ”,这表明收到的支持票数。
现在,我们希望能够使用 Python 发出这个请求,并打印出我们希望看到的数据。
import requests, jsonpayload = {
'limit': 5,
't': 'all'
}headers = {
'User-agent': 'Reddit bot 1.0'
}#For the purposes of demonstration, I will use the /r/funny subredditendpoint = '[https://www.reddit.com/r/funny/top.json'](https://www.reddit.com/r/funny/top.json')r = requests.get(endpoint, headers = headers, params = payload)
r = json.loads(r.content)
首先,我们要定义请求的参数。您可以考虑像“过滤器”这样的参数,它修改我们请求的范围。要确定端点可以接受哪些参数,请查看 API 的文档,因为它还会指定任何其他约束/格式要求。在我们的例子中,我们将“limit”参数设置为 5,这意味着我们在响应中只会得到 5 个结果。我们还将“t”参数设置为“all”,这意味着我们希望看到所有时间的热门帖子。我们将所有参数打包到一个名为“有效载荷”的字典中。
接下来,我们为请求头定义一个类似的字典。HTTP 头实质上允许您向服务器传递关于您的请求的附加信息。在我们的例子中,我们不会对标题做太多改动,但是你可以通过这个链接阅读更多关于它们的内容。然而,最好定义一个用户代理,它可以是您想要的任何东西。这是为了避免使用 requests 模块的默认用户代理,因为许多其他人可能正在使用同一个代理,因此可能会阻止您,因为它会认为您正在发出过多的请求。
一旦我们有了头和参数,我们就可以向给定的端点发出请求(使用 requests 模块),同时使用适当的关键字参数传递头和参数,并将响应存储在名为“r”的变量中。因为响应是 JSON 格式的,所以我们想把它转换成 python 字典,这样我们就可以更容易地操作数据。我们可以使用内置的 json 模块来解析响应内容。
现在我们只剩下一个包含所有 JSON 响应数据的字典。我们现在可以做的是打印每个帖子的一些元数据
for i, sub in enumerate(r['data']['children']):
print(f"{i+1}. {sub['data']['title']}. \n \
was gilded {sub['data']['gilded']} times \n \
and was upvoted {sub['data']['ups']} times \n")\------------------------------------------------------------------1\. My cab driver tonight was so excited to share with me that he’d made the cover of the calendar. I told him I’d help let the world see.
was gilded 7 times
and was upvoted 307860 times
2\. Guardians of the Front Page.
was gilded 17 times
and was upvoted 283481 times
3\. Gas station worker takes precautionary measures after customer refused to put out his cigarette.
was gilded 3 times
and was upvoted 263008 times
4\. The conversation my son and I will have on Christmas Eve..
was gilded 23 times
and was upvoted 236783 times
5\. Printers.
was gilded 6 times
and was upvoted 220424 times
显然,这是一个非常简单的例子。但是根据同样的原理,你可以非常快速地访问大量的数据,并将它们存储在熊猫数据框架中,或者将数据导出为 csv 格式以供将来分析。
发现“隐藏的”API
有大量的功能性的、有用的和有良好文档记录的 API 供您使用。你可以在这个链接看到一些最受欢迎的。然而,有时网站会将 API 用于自己的内部使用,而不是外部用户。这方面的一个例子是 NBA 统计网站。
当你在他们的网站上浏览一个页面,比如这个,你会得到一堆关于一个 NBA 球员的统计数据。访问这些数据的一种方法是编写一个 web scraper,但这是一个更加耗时和脆弱的解决方案。
但是,如果你打开开发者工具(在 Chrome 中:视图→开发者→开发者工具),转到网络选项卡(XHR),然后刷新页面,你会看到网站正在进行一系列 API 调用,以便用相关数据填充页面。
站点在加载时进行的网络调用。如果单击任何给定的请求,还可以查看参数和头,以及其他相关的元数据
其中一项请求如下:
您所看到的基本上是我们在 Reddit 示例中使用的相同的 endpoint + parameters 格式。网站向 https://stats.nba.com/stats/playerdashboardbyyearoveryear 的 T2 发出了一个 API 调用,然后传入了一堆参数(尽管除了 PlayerID 和 Season 之外,它们大部分都是空白的)。
一旦找到这些 API 调用,就可以通过改变参数来尝试编写自己的请求。然而,这种方法的缺点是您需要自己发现所有的端点和参数。幸运的是,至少对于 NBA stats 网站来说,各种在线用户已经为我们记录了端点和参数。
API 礼仪和最佳实践
通常,您希望遵循几个最佳实践。尽量不要向 API 发出过多的请求,因为这样做可能会降低服务速度,并导致自己被阻止。通常,尝试每秒发出少于 1 个请求。
此外,通常最好设置一个描述性的和相关的用户代理头,以便 API 主机可以确定问题可能源自何处,并了解谁正在使用他们的服务。
结论
总之,使用 API 获取数据是数据科学家工具箱中不可或缺的工具。掌握它们可以让你接触到大量的在线数据,使你能够利用更多不同的数据,促进更复杂的分析。我希望这篇文章对你有所帮助,并希望你在编写自己的请求时有乐趣!
使用张量流和 Keras 的人工神经网络初学者指南
使用人工神经网络构建欺诈检测模型&使用 RandomizedSearchCV 微调超参数
凯利·西克玛在 Unsplash 上的照片
介绍
ann(人工神经网络)是深度学习的核心,是机器学习技术的高级版本。人工神经网络涉及以下概念。输入和输出层、隐藏层、隐藏层下的神经元、前向传播和反向传播。简而言之,输入层是独立变量的集合,输出层代表最终输出(因变量),隐藏层由神经元组成,在其中开发方程并应用激活函数。前向传播讨论如何开发方程以实现最终输出,而后向传播计算梯度下降以相应地更新学习率。关于操作过程的更多信息可以在下面的文章中找到。
理解神经网络的概念
towardsdatascience.com](/introduction-to-artificial-neural-networks-for-beginners-2d92a2fb9984)
深度神经网络
当一个 ANN 包含一个很深的隐藏层堆栈时,它被称为一个深度神经网络 (DNN)。DNN 使用多个权重和偏差项,每个权重和偏差项都需要训练。只要两次通过网络,该算法就可以自动计算梯度下降。换句话说,它可以确定如何调整所有神经元的每个权重和每个偏置项以减少误差。该过程重复进行,除非网络收敛到最小误差。
让我们一步一步地运行这个算法:
- 开发训练和测试数据以训练和验证模型输出。因为它遵循参数结构,其中它优化了权重和偏置参数项。所有涉及相关性、异常值处理的统计假设仍然有效,必须进行处理
- 输入层由独立变量及其各自的值组成。一个小批量的数据(取决于批量大小)多次通过完整的训练集。每一遍被称为一个时期。纪元越高,训练时间就越长
- 每个小批量被传递到输入层,输入层将其发送到第一个隐藏层。计算该层中所有神经元的输出(对于每个小批量)。结果传递到下一层,重复这个过程,直到我们得到最后一层的输出,即输出层。这是向前传递:它类似于进行预测,只是所有中间结果都被保留,因为向后传递需要它们
- 然后使用损失函数测量网络的输出误差,该损失函数将期望输出与网络的实际输出进行比较
- 计算每个中子对误差项的科学贡献
- 该算法执行梯度下降以基于学习速率(反向传播)调整权重和参数,并且该过程重复进行
随机初始化所有隐藏层的连接权重是很重要的,否则训练将会失败。例如,如果将所有权重和偏差初始化为零,则给定层中的所有神经元将完全相同,因此反向传播将以完全相同的方式影响它们,因此它们将保持相同。换句话说,尽管每层有数百个神经元,但你的模型将表现得好像每层只有一个神经元:它不会太聪明。相反,如果你随机初始化权重,你会破坏对称性,并允许反向传播来训练一个多样化的神经元团队(Auré lien Gé ron,2017 年,第 290-291 页)
激活功能
激活函数是梯度下降的关键。梯度下降不能在平面上移动,因此有一个明确定义的非零导数以允许梯度下降在每一步都取得进展是很重要的。Sigmoid 通常用于逻辑回归问题,然而,也有其他流行的选择。
双曲正切函数
这个函数是 S 形的,连续的,除了输出范围从-1 到+1 之外可以微分。在训练开始时,每层的输出或多或少以 0 为中心,因此有助于加快收敛。
整流线性单元
在 Z=0 处不可微的连续函数,当 Z<0 时,它的导数为 0。它产生良好的输出,更重要的是有更快的计算。该函数没有最大输出,因此在梯度下降过程中可能出现的一些问题得到了很好的处理。
为什么我们需要一个激活函数?
假设 f(x) = 2x + 5,g(x) = 3x -1。两个不同神经元的方程,其中 x 是输入变量,2 和 3 是权重,5 和-1 是偏差项。在链接这些函数时,我们得到 f(g(x)) = 2(3x -1) + 5 = 6x + 3,这也是一个线性方程。没有非线性类似于在深度神经网络中有一个方程。这种场景下的复杂问题空间是处理不了的。
图一。说明了人工神经网络体系结构中常用的激活函数。作者使用 Excel 开发的图像。
损失函数
在处理回归问题时,我们不需要对输出层使用任何激活函数。训练回归问题时使用的损失函数是均方误差。然而,训练集中的异常值可以使用平均绝对误差来处理。对于基于回归的任务,Huber 损失也是广泛使用的误差函数。
当误差小于阈值 t(通常为 1)时,Huber 损失是二次的,但是当误差大于 t 时,Huber 损失是线性的。当与均方误差相比时,线性部分允许其对异常值不太敏感,并且二次部分允许比平均绝对误差更快的收敛和更精确的数字。
分类问题通常使用二元交叉熵或分类交叉熵或稀疏分类交叉熵。二元交叉熵用于二元分类,而分类或稀疏分类交叉熵用于多类分类问题。你可以在下面的链接中找到更多关于损失函数的细节。
注意: 分类交叉熵用于因变量的一键表示,当标签以整数形式提供时,使用稀疏分类交叉熵。
损失函数的目的是计算模型在训练过程中应该寻求最小化的数量。注意…
keras.io](https://keras.io/api/losses/)
用 Python 开发人工神经网络
我们将使用来自 Kaggle 的信用数据来开发一个使用 Jupyter Notebook 的欺诈检测模型。同样的事情也可以在 Google Colab 中完成。数据集包含欧洲持卡人在 2013 年 9 月的信用卡交易。该数据集显示了两天内发生的交易,其中 284,807 笔交易中有 492 笔欺诈。数据集高度不平衡,正类(欺诈)占所有交易的 0.172%。
import tensorflow as tf
print(tf.__version__)import pandas as pd
import numpy as npfrom sklearn.model_selection import train_test_split
import tensorflow as tffrom sklearn import preprocessingfrom tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, BatchNormalizationfrom sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_score, precision_recall_curve, aucimport matplotlib.pyplot as plt
from tensorflow.keras import optimizersimport seaborn as snsfrom tensorflow import kerasimport random as rnimport os
os.environ["CUDA_VISIBLE_DEVICES"] = "3"
PYTHONHASHSEED=0tf.random.set_seed(1234)
np.random.seed(1234)
rn.seed(1254)
数据集由以下属性组成。时间、主要成分、数量和类别。更多信息请参考 Kaggle 网站。
file = tf.keras.utils
raw_df = pd.read_csv(‘[https://storage.googleapis.com/download.tensorflow.org/data/creditcard.csv'](https://storage.googleapis.com/download.tensorflow.org/data/creditcard.csv'))
raw_df.head()
因为大多数属性是主成分,所以相关性将总是为 0(主成分中正交向量的属性)。唯一可能存在异常值的列是金额。对其的快速描述提供了下面概述的统计数据。
count 284807.00
mean 88.35
std 250.12
min 0.00
25% 5.60
50% 22.00
75% 77.16
max 25691.16
Name: Amount, dtype: float64
图二。说明了数据中所有属性的相关矩阵。作者使用 Jupyter 笔记本开发的图像。
异常值对于检测欺诈至关重要,因为潜在的假设是,较高的交易可能是欺诈活动的迹象。然而,箱线图没有揭示任何特定的趋势来验证上述假设。
图 3。说明了欺诈性和非欺诈性活动的金额的箱线图表示。作者使用 Jupyter 笔记本开发的图像。
准备输入输出和训练测试数据
X_data = credit_data.iloc[:, :-1]y_data = credit_data.iloc[:, -1]X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.2, random_state = 7)X_train = preprocessing.normalize(X_train)
数量和主成分分析变量使用不同的尺度,因此数据集被归一化。归一化在梯度下降中起着重要的作用。标准化数据的收敛速度要快得多。
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
输出:
(227845, 29) #--Number of records x Number of columns
(56962, 29)
(227845,)
(56962,)
开发人工神经网络层
上面的输出表明我们有 29 个独立变量要处理,因此输入层的形状是 29。任何人工神经网络结构的一般结构概述如下。
+----------------------------+----------------------------+
| Hyper Parameter | Binary Classification |
+----------------------------+----------------------------+
| # input neurons | One per input feature |
| # hidden layers | Typically 1 to 5 |
| # neurons per hidden layer | Typically 10 to 100 |
| # output neurons | 1 per prediction dimension |
| Hidden activation | ReLU, Tanh, sigmoid |
| Output layer activation | Sigmoid |
| Loss function | Binary Cross Entropy |
+----------------------------+----------------------------++-----------------------------------+----------------------------+
| Hyper Parameter | Multiclass Classification |
+-----------------------------------+----------------------------+
| # input neurons | One per input feature |
| # hidden layers | Typically 1 to 5 |
| # neurons per hidden layer | Typically 10 to 100 |
| # output neurons | 1 per prediction dimension |
| Hidden activation | ReLU, Tanh, sigmoid |
| Output layer activation | Softmax |
| Loss function | "Categorical Cross Entropy |
| Sparse Categorical Cross Entropy" | |
+-----------------------------------+----------------------------+
密集函数的输入
- 单位-输出的尺寸
- 激活—激活功能,如果未指定,则不使用任何内容
- use _ bias 表示图层是否使用偏置矢量的布尔值
- 内核初始化器——内核权重的初始化器
- bias_initializer —偏差向量的初始值设定项。
model = Sequential(layers=None, name=None)
model.add(Dense(10, input_shape = (29,), activation = 'tanh'))
model.add(Dense(5, activation = 'tanh'))
model.add(Dense(1, activation = 'sigmoid'))sgd = optimizers.Adam(lr = 0.001)model.compile(optimizer = sgd, loss = 'binary_crossentropy', metrics=['accuracy'])
架构概要
model.summary()Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 10) 300
_________________________________________________________________
dense_1 (Dense) (None, 5) 55
_________________________________________________________________
dense_2 (Dense) (None, 1) 6
=================================================================
Total params: 361
Trainable params: 361
Non-trainable params: 0
_________________________________________________________________
让我们试着理解上面的输出(使用两个隐藏层提供输出解释):
- 我们已经创建了一个具有一个输入层、两个隐藏层和一个输出层的神经网络
- 输入层有 29 个变量和 10 个神经元。因此,权重矩阵的形状为 10×29,偏差矩阵的形状为 10×1
- 第 1 层中的参数总数= 10 x 29 + 10 x 1 = 300
- 第一层使用 tanh 作为激活函数,有 10 个输出值。第二层有 5 个神经元,使用 10 个输入,因此权重矩阵是 5×10,偏差矩阵是 5×1
- 第 2 层中的总参数= 5 x 10 + 5 x 1 = 55
- 最后,输出层具有一个神经元,但是它具有来自隐藏层 2 的 5 个不同输入,并且具有偏置项,因此神经元的数量= 5+1=6
model.fit(X_train, y_train.values, batch_size = 2000, epochs = 20, verbose = 1)Epoch 1/20
114/114 [==============================] - 0s 2ms/step - loss: 0.3434 - accuracy: 0.9847
Epoch 2/20
114/114 [==============================] - 0s 2ms/step - loss: 0.1029 - accuracy: 0.9981
Epoch 3/20
114/114 [==============================] - 0s 2ms/step - loss: 0.0518 - accuracy: 0.9983
Epoch 4/20
114/114 [==============================] - 0s 2ms/step - loss: 0.0341 - accuracy: 0.9986
Epoch 5/20
114/114 [==============================] - 0s 2ms/step - loss: 0.0255 - accuracy: 0.9987
Epoch 6/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0206 - accuracy: 0.9988
Epoch 7/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0174 - accuracy: 0.9988
Epoch 8/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0152 - accuracy: 0.9988
Epoch 9/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0137 - accuracy: 0.9989
Epoch 10/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0125 - accuracy: 0.9989
Epoch 11/20
114/114 [==============================] - 0s 2ms/step - loss: 0.0117 - accuracy: 0.9989
Epoch 12/20
114/114 [==============================] - 0s 2ms/step - loss: 0.0110 - accuracy: 0.9989
Epoch 13/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0104 - accuracy: 0.9989
Epoch 14/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0099 - accuracy: 0.9989
Epoch 15/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0095 - accuracy: 0.9989
Epoch 16/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0092 - accuracy: 0.9989
Epoch 17/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0089 - accuracy: 0.9989
Epoch 18/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0087 - accuracy: 0.9989
Epoch 19/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0084 - accuracy: 0.9989
Epoch 20/20
114/114 [==============================] - 0s 1ms/step - loss: 0.0082 - accuracy: 0.9989
评估输出
X_test = preprocessing.normalize(X_test)results = model.evaluate(X_test, y_test.values)1781/1781 [==============================] - 1s 614us/step - loss: 0.0086 - accuracy: 0.9989
使用张量板分析学习曲线
TensorBoard 是一个非常棒的交互式可视化工具,可用于查看训练过程中的学习曲线,比较多次跑步的学习曲线,分析训练指标等等。该工具随 TensorFlow 自动安装。
import os
root_logdir = os.path.join(os.curdir, “my_logs”)def get_run_logdir():
import time
run_id = time.strftime(“run_%Y_%m_%d-%H_%M_%S”)
return os.path.join(root_logdir, run_id)run_logdir = get_run_logdir()tensorboard_cb = keras.callbacks.TensorBoard(run_logdir)model.fit(X_train, y_train.values, batch_size = 2000, epochs = 20, verbose = 1, callbacks=[tensorboard_cb])%load_ext tensorboard
%tensorboard --logdir=./my_logs --port=6006
图 4。说明了人工神经网络运行的张量板输出。作者使用 Jupyter 笔记本开发的图像。
超调模型参数
如前所述,对于有多少隐藏层或多少神经元最适合一个问题空间,没有预定义的规则。我们可以使用 RandomizedSearchCV 或 GridSearchCV 来优化一些参数。可以微调的参数如下:
- 隐藏层数
- 隐藏层中的神经元
- 【计算机】优化程序
- 学习率
- 世
声明开发模型的函数
def build_model(n_hidden_layer=1, n_neurons=10, input_shape=29):
# create model
model = Sequential()
model.add(Dense(10, input_shape = (29,), activation = 'tanh'))for layer in range(n_hidden_layer):
model.add(Dense(n_neurons, activation="tanh"))model.add(Dense(1, activation = 'sigmoid'))
# Compile modelmodel.compile(optimizer ='Adam', loss = 'binary_crossentropy', metrics=['accuracy'])
return model
使用包装类克隆模型
from sklearn.base import clone
keras_class = tf.keras.wrappers.scikit_learn.KerasClassifier(build_fn = build_model,nb_epoch = 100,
batch_size=10)
clone(keras_class)keras_class.fit(X_train, y_train.values)
创建随机搜索网格
from scipy.stats import reciprocal
from sklearn.model_selection import RandomizedSearchCVparam_distribs = {
“n_hidden_layer”: [1, 2, 3],
“n_neurons”: [20, 30],
# “learning_rate”: reciprocal(3e-4, 3e-2),
# “opt”:[‘Adam’]
}rnd_search_cv = RandomizedSearchCV(keras_class, param_distribs, n_iter=10, cv=3)rnd_search_cv.fit(X_train, y_train.values, epochs=5)
检查最佳参数
rnd_search_cv.best_params_{'n_neurons': 30, 'n_hidden_layer': 3}rnd_search_cv.best_score_model = rnd_search_cv.best_estimator_.model
优化器也应该微调,因为它们影响梯度下降、收敛和学习率的自动调整。
- ***Adadelta—***Adadelta 是 Adagrad 的更健壮的扩展,它基于梯度更新的移动窗口来调整学习速率,而不是累积所有过去的梯度
- 随机梯度下降— 常用。需要使用搜索网格来微调学习率
- Adagrad — 对于其他优化器,学习率对于所有参数和每个周期都是恒定的。然而,Adagrad 在处理误差函数的导数时,改变每个参数和每个时间步长“t”的学习速率“η”
- ADAM — Adam(自适应矩估计)与一阶和二阶动量一起工作,以防止跳过局部最小值。亚当保存了过去梯度的指数衰减平均值
图 5。展示了不同优化器之间的收敛性。图片来自 GIPHY。
一般来说,通过增加层数而不是每层神经元的数量可以获得更好的输出。
参考
奥雷连戈罗恩(2017)。用 Scikit-Learn 和 TensorFlow 进行动手机器学习:构建智能系统的概念、工具和技术。塞瓦斯托波尔,加利福尼亚州:奥赖利媒体
关于作者:高级分析专家和管理顾问,帮助公司通过对组织数据的商业、技术和数学的组合找到各种问题的解决方案。一个数据科学爱好者,在这里分享、学习、贡献;可以在LinkedIn和Twitter上联系我。
计算机视觉入门指南
情报的
对人工智能中一个重要领域的友好介绍
“人工智能是一门严格的科学,专注于设计智能系统和机器,使用的算法技术多少受到我们对大脑的了解的启发”
计算机视觉(CV)是事实上的人工智能技术之一,存在于我们遇到的许多人工智能应用中。
面部识别、无人驾驶汽车、增强现实和许多其他应用都以某种形式利用了计算机视觉技术。
过去十年,随着人工智能应用获得更多采用,计算机视觉变得更加突出。
人工智能应用采用的增加导致了计算机视觉相关工作和课程数量的增加
本文将简要介绍计算机视觉在过去五十年中的发展,并探索该领域早期使用的传统 CV 技术。本文将探讨深度学习时代,包括解释从传统的 CV 方法到基于深度学习的方法的转变的原因。
计算机视觉
在我们深入研究各种 CV 技术之前,让我们探索一下计算机视觉试图在功能方面模拟的人体部分。
大多数人类不太重视视觉;这是一种身体机能,很少甚至没有刻意的影响就能自动发挥作用。
人类视觉感觉系统已经发展了几千年,使人类能够从三维世界中物体反射到我们眼睛的光线中推断出景物的含义和背景。
我们的眼睛和大脑可以从反射光中推断出对环境的理解。
我们的视觉系统使我们能够确定物体的距离,在不直接接触的情况下预测物体的纹理,并识别我们环境中的所有类型的模式和事件。
计算机视觉是一个过程,通过这个过程,我们试图给计算机系统配备与人类视觉感官系统相同的能力。
计算机视觉的适当定义如下:
计算机视觉是机器或系统通过调用一个或多个作用于所提供信息的算法来生成对视觉信息的理解的过程。这些理解然后被转化为决策、分类、模式观察等等。
我们的视觉感觉系统由眼睛和大脑组成,尽管我们知道眼睛的每个组成部分,如角膜、晶状体、视网膜、虹膜等。,我们并不完全了解大脑是如何工作的。
为了创建能够从图像中提取上下文信息的算法和系统,必须观察模式的原因。那么解决方案可以从对特定模式的原因和结果的理解中得出。
计算机视觉有很多应用,下面是几个:
左:人脸检测和面部特征跟踪。中间:tensor flow 的姿态估计。右图: Yolo 对象检测网络
人脸检测 :实现能够自动识别和定位图像和视频中人脸的系统的任务。面部检测存在于与面部识别、摄影和动作捕捉相关联的应用中。
对象分类 :识别关联的 a 类目标对象的过程。对象识别和检测是具有相似结果和实现方法的技术,尽管在各种系统和算法中识别过程先于检测步骤。
物体跟踪 :一种在一段时间内,从一系列图像中识别、检测、跟踪感兴趣物体的方法。在许多监控摄像机和交通监控设备中可以找到系统内跟踪的应用。
姿态估计 :从提供的图像、视频或图像序列等数字资产中推断出身体主要关节位置的过程。姿态估计的形式存在于诸如动作识别、人类交互、虚拟现实和 3D 图形游戏的资产创建、机器人等应用中。
自 20 世纪 70 年代以来,研究人员已经花费了大量的时间和精力,创建了高效而健壮的计算机视觉算法和系统,可以用作上面列出的一些应用的解决方案。
在现代,大多数计算机视觉任务都是使用深度学习方法解决的。
为了更好地理解计算机视觉领域的基础,让我们探索一下传统的算法,这些算法具有用于解决典型计算机视觉问题的基于启发式的逻辑。
传统方法
计算机视觉技术的主要目的是提供对图像数据中的上下文的某种形式的理解;然后,这种理解被用于更多定制的目的,例如识别或检测。
算法和传统计算机视觉技术中的几个子程序被开发来从图像中提取场景理解。
传统的计算机视觉管道。作者图片
计算机视觉中的特征被描述为数据形式中的一条可测量和可量化的信息,它定义了观察的某些特征。
边缘检测
边缘是可以用来描述图像内容的图像特征的例子。边缘检测是开发能够提供一些场景理解的算法的最初尝试之一。
边缘检测属于图像处理的主题,但已经成为计算机视觉中的主要工具。
边缘检测算法识别图像中像素强度急剧变化的点。通过连接这些图像亮度急剧变化的点,我们形成了线条,更正式的说法是边缘。
为什么边缘是图像中的重要特征?
从检测到的边缘的分析和组合中可以检索到关于图像的大量信息。例如,仅通过观察检测到的边缘之间的连接和连续性,就可以从边缘信息推断出物体的 3D 组成。
检测到的边缘还暴露了图像的可测量和可量化的属性,例如深度和方向的变化。弯曲的边缘代表方向的变化。
一旦从图像中提取出特征,在这种情况下是边缘,就有可能确定图像中哪些内容是相关的。
下面举几个传统边缘检测算法的例子: Canny 边缘检测器 , Sobel 方法 和 模糊逻辑方法 。
由 JonMcLoone 在英语维基百科,CC BY-SA 3.0,https://commons.wikimedia.org/w/index.php?curid=44894482
识别图像中的特征的重要性在于计算机视觉的基本目标,即理解图像中的内容。
从边缘和线条等衍生特征中,可以构建与图像中对象的基本结构组成相对应的三维对象。
传统的计算机视觉涉及对输入和输出的深入分析。深入的分析揭示了可以从图像中提取哪些数学上可表示的特征,并与有效的算法相结合以产生期望的结果。
封装上述过程的传统计算机视觉技术的一个例子是 Haar-like 特征。
图片来自https://www.researchgate.net/
类哈尔特征用于计算机视觉任务,如物体识别或人脸检测。
它通过使用包含两个相邻矩形的定义窗口来工作,其中每个矩形中像素强度之和之间的差异用于识别面部的片段。
眼睛周围的区域比脸颊周围的相邻区域稍暗,用于眼睛检测的 haar 特征将是所利用的相邻矩形。
可以将计算出的差异与先前确定的阈值进行比较,以识别面部的各个部分,例如眼睛、嘴和鼻子。
另一种用于对象检测的传统计算机视觉技术被称为 SIFT(尺度不变特征变换)。它是在 90 年代后期开发的。
SIFT 技术用于识别图像中的对象,与图像的方向、比例和旋转无关。它主要通过识别图像中感兴趣点并累积它们的梯度来工作;这些信息创建了一个图像描述符。包含关键点的描述符与其他描述符的数据库进行比较和匹配。
传统 CV 技术的功效在于检测和提取的特征的质量。
此外,用于创建场景理解的方法和基于启发式的算法是传统 CV 技术的性能和可靠性的重要组成部分。
更多的研究和努力集中在统一和自动化特征提取、工程、学习和分类的所有过程上。
深度学习方法
艾莉娜·格鲁布尼亚克在 Unsplash 上的照片
计算机视觉从传统到深度学习方法的转变
在撰写本文时,大多数计算机视觉相关任务都是使用最先进的深度学习架构解决的。
传统的计算机视觉方法已经被深度学习和随后的神经网络引入的端到端学习解决方案所取代。
计算机视觉的传统方法需要在特征提取阶段开始之前定义特征结构和组成。
计算机视觉从业者必须定义什么样的特定特征最能描述图像中感兴趣的对象。这种特征工程和描述的方法是不可扩展的,尤其是当感兴趣对象的数量很大时。
深度学习在一个自动化的过程中处理特征工程、提取和分类的任务。
通过向神经网络呈现图像,神经网络内的权重和参数呈现概括所呈现图像内的突出特征和空间模式的值。
将标记的图像作为训练数据呈现给神经网络,可以训练神经网络来识别对应于图像数据中特定对象的模式。
对于需要检测的尽可能多的物体,该过程是可重复的。
深度学习有一些限制和缺点;拥有大量的训练数据以确保神经网络能够很好地推广到看不见的数据是一个问题,这个问题在几年内限制了深度学习策略的采用。
网络容量和对计算资源的访问也可能成为计算机视觉深度学习方法的瓶颈。
在采用深度学习之前,CV 工程师负责定义和选择最能描述图像或对象的特征。现在,在现代,CV 工程师更关心深度学习模型的实现、训练和评估。
深度学习
深度学习是机器学习的一个子领域,它涉及利用人工神经网络(ANN)来解决自然语言和计算机视觉任务,如对象检测、对象识别、人脸检测、姿态估计、语义分割等。
深度学习领域中存在各种各样的 ANN 配置,值得注意的配置是卷积神经网络(CNN)、递归神经网络(RNN)和深度神经网络(DNN)。
深度学习中的“深度”一词指出了这样一个事实,即所提到的 ANN 和其他开发的变体由大量的神经网络层组成。
有些关键词普遍存在于深度学习的各个领域;它们是:
- 神经网络 :以能够保持知识的方式构造的神经元(处理单元)的集合。它们也可以被描述为并行分布式处理器。
- 卷积 :卷积是一个数学术语,描述两组元素之间的点积相乘。在深度学习中,卷积运算作用于卷积层中的过滤器/内核和图像数据阵列。因此,卷积层包含发生在滤波器和通过卷积神经网络的图像之间的卷积运算。
- 卷积神经网络 :这些是利用层内数学卷积运算的神经网络。
- 权重: 这些都是神经元间连接的强度。它们是神经网络中存储知识的关键元素。
利用计算机视觉的深度学习将特征提取、检测、工程和分类的任务全部委托给神经网络。
因此,深度学习计算机视觉管道看起来类似于下图。
深度学习管道。作者图片
结论
到目前为止,我们已经涵盖了解决计算机视觉任务的传统方法和利用深度学习的更现代的方法。
现代和传统的 CV 方法都有更多的概念、想法和技术可以探索。业界的共识是,深度学习是解决计算机视觉任务的主导方法。
对于那些想要探索计算机视觉世界的人来说,深度学习主题和技术是获得实践和专业经验的有利途径。
然而,重温计算机视觉的根源并理解研究人员和工程师在开发传统算法时的直觉总是很有见地的。
很快,我会写一篇文章,更深入地介绍深度学习。
现在,你可以阅读以下文章,了解现代简历工程师的角色是什么样的,以及从事机器学习和计算机视觉研究需要什么。
在一个我几年前都没有涉足的领域呆上半年是什么感觉
towardsdatascience.com](/6-months-as-a-machine-learning-computer-vision-engineer-c05978592368) [## 我从攻读计算机视觉和机器学习硕士学位中学到了什么
如果你打算从事计算机视觉或机器学习方面的任何形式的高级研究,请阅读本文…你可能…
towardsdatascience.com](/what-i-learnt-from-taking-a-masters-in-computer-vision-and-machine-learning-69f0c6dfe9df)
我希望这篇文章对你有用。
要联系我或找到更多类似本文的内容,请执行以下操作: