TowardsDataScience-博客中文翻译-2021-十八-
TowardsDataScience 博客中文翻译 2021(十八)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
用 Matplotlib 和 Plotly 实现基本动画。
原文:https://towardsdatascience.com/basic-animation-with-matplotlib-and-plotly-5eef4ad6c5aa?source=collection_archive---------13-----------------------
使用最流行的 python 绘图库制作简单动画的最短路径。
有时候动画视觉效果是有意义的。动画可以帮助更完整地理解数据。如果你的媒介是屏幕,你可能会发现自己偶尔需要动画。你要问的下一个问题是,“我应该为动画使用哪个工具包。”在这里,我用 Matplotlib 和 Plotly 比较了创建如下基本动画的过程。

数据
如果你不在乎数据,我不会评判你— 跳到动画
我们将使用梯度下降来制作线性回归模型拟合的动画。我选择这个是因为这个动画很简单,但是有两个不同的部分:
- 数据点的散点图
- 可视化拟合过程的动画线
我使用sklearn.datsets.make_regression生成随机数据,如下所示:
from sklearn.datasets import make_regression
X, y = make_regression(n_features = 1, noise=50, random_state=543)
这是我们测试数据的样子。我们将尽可能保持代码简单,所以我不会做任何额外的格式化,尽管这会给我们双方带来痛苦。

回归
我们不能使用 statsmodels 或 sklearn 的 LinearRegression 模型,因为我们需要存储回归的每次迭代,而不仅仅是最终的拟合线。相反,我借用了 Joseph Bautista 文章中的代码,在 10 行代码中使用梯度下降进行线性回归,并对其进行了修改,以返回拟合的每次迭代的斜率和截距列表。
这对于动画来说是不需要理解的,但是这是回归函数。
def linear_regression(X, y, m_current=0, b_current=0, epochs=1000, learning_rate=0.0001):
N = float(len(y))
ms = [m_current] # a place to store our m values
bs = [b_current] # a place to store our b values
for i in range(epochs):
y_current = (m_current * X) + b_current
cost = sum([data**2 for data in (y-y_current)]) / N
m_gradient = -(2/N) * sum(X * (y - y_current))
b_gradient = -(2/N) * sum(y - y_current)
m_current = m_current - (learning_rate * m_gradient)
b_current = b_current - (learning_rate * b_gradient)
ms.append(m_current)
bs.append(b_current)
return ms, bs
预测
为了生成线条拟合动画的数据,我们将我们的X数据输入到linear_regression函数中,并计算出绘制的连续线条。
# run the linear regression and store the m and b values
ms, bs = linear_regression(X.ravel(), y,
epochs=200, learning_rate=0.01)# build the lines, mx + b for all ms X's and b's
y_lines = (ms * X + bs).T # transpose for easier indexing
现在你们一直在等待的…
动画— Matplotlib
matplotlib 的动画 api 很简单,但是如果你在 jupyter 笔记本中,你的动画将不会在 GUI 后端设置为 **inline** 的情况下运行。我将 GUI 后端设置为notebook。还有其他的解决方案。
制作动画的过程是这样的:
1)创造一个开始的情节
- 实例化 matplotlib 图形
- 用
plt.scatter绘制数据 - 绘制初始回归线并保存到
line以便我们以后更新,line后的逗号(,)从plt.plot返回的列表中解包单个Line2D对象。
# we will need the fig object later
fig = plt.figure)# plot our original data
plt.scatter(X,y)# create a line to update
line, = plt.plot(ms[0], bs[0], c='r', linewidth=5)

2)制作线条动画
为了制作线条动画,我们编写了一个函数,用它的set_ydata方法更新line对象中的数据。然后我们使用 Matplotlib 的FuncAnimation方法为动画中的每一帧调用该函数。
from matplotlib.animation import FuncAnimation# update the frames based on the parameter i
def animate(i):
# set the title to indicate the iteration
plt.title(f'Gradient Descent step {i}')
# change the data for the y axis points of the line
line.set_ydata(y_lines[i])return line,# run the animation
animation = FuncAnimation(fig, animate, frames=len(ms), interval=20)
这给了我们这个!多酷啊。

这里使用的FuncAnimation属性是:
fig:应用动画的人物对象func:更新每一帧要调用的函数frames:调用上述函数的总次数。这等于最终动画中的总帧数。interval:帧与帧之间的延迟,单位为毫秒。
3)保存动画
用 matplotlib 保存动画可以说是最令人困惑的部分。因为 matplot 库正在为每一帧生成光栅化图像,我们将把这个绘图保存到 mp4 文件。这些步骤是:
- 实例化一个编写器来定义输出文件参数
- 使用刻录机将 mp4 文件写入光盘
# Set up formatting for the movie files
from matplotlib.animation import writers
Writer = writers['ffmpeg']
writer = Writer(fps=12.5)# save an mp4 of the animation
animation.save('matplotlib.mp4', writer=writer)
还不算太糟。让我们用 Plotly 试试
Plotly
现在我们将通过plotly创建相同的情节。因为我们的动画将由多个图组成(散点图和线图),我们将使用plotly.graph_objects作为我们图形的元素。
1)创建起始情节
- 为我们的散点图创建一个
graph_object—points - 创建一个初始行—
line。这也是用 Plotly 中的Scatter对象完成的 - 创建一个布局对象
layout来设置动画前的标题(可选) - 将以上元素组合成一个图形—
fig
import plotly.graph_objects as go# create the scatter plot
points = go.Scatter(x=X.flatten(), y=y, mode='markers')# create initial line
line = go.Scatter(x=X.flatten(), y=y_lines[0])# create a layout with out title (optional)
layout = go.Layout(title_text="Gradient Descent Animation")# combine the graph_objects into a figure
fig = go.Figure(data=[points, line])
# to see what we have so far
fig.show()

2)制作线条动画
为了制作这条线的动画,我们需要再创建两个对象,一列Frame对象和一个Layout对象。Layout更新了我们的标题,并添加了一个播放按钮,图中的开始动画和设置动画速度。
流程是
- 通过回归线列表(
y_lines)循环创建各自的动画帧。 - 实例化一个添加播放按钮并设置标题的
Layout对象
# create a list of frames
frames = []# create a frame for every line y
for i in range(len(y_lines)): # update the line
line = go.Scatter(x=X.flatten(), y=y_lines[i]) # create the button
button = {
"type": "buttons",
"buttons": [
{
"label": "Play",
"method": "animate",
"args": [None, {"frame": {"duration": 20}}],
}
],
} # add the button to the layout and update the
# title to show the gradient descent step
layout = go.Layout(updatemenus=[button],
title_text=f"Gradient Descent Step {i}") # create a frame object
frame = go.Frame(
data=[points, line],
layout=go.Layout(title_text=f"Gradient Descent Step {i}")
)# add the frame object to the frames list
frames.append(frame)
然后,我们将上述所有内容组合成一个单独的Figure对象
# combine the graph_objects into a figure
fig = go.Figure(data=[points, line],
frames=frames,
layout = layout)
# show our animation!
fig.show()
就这样:

3)保存动画
Plotly 没有将动画保存到电影文件的机制。然而,它有一个非常简单的方法来导出你可以嵌入网页的 html。为了保持我们用播放按钮设置的动画速度,我们必须设置auto_play = False。
# save the figure
fig.write_html("plotly.html", auto_play=False)
3)保存动画
Matplotlib 和 Plotly 采用相似但不同的方法制作动画。我个人觉得 Matplotlib 的FuncAnimation方法更直观,我会将它用于 jupyter 笔记本中的内嵌动画,或者用于 mp4 必须转换为 gif 才能包含的中型文章。
因为 Plotly html 文件使用 javascript 生成矢量图像,所以我们希望 html 文件比从 Matplotlib 导出的电影要小。事实并非如此。Matplotlib mp4 导出为 874 KB,而 Plotly 的 html 导出为 5.2 MB(哇!).在 Plotly html 文件的情况下,大小是由于包含了用于离线渲染的整个 Plotly js 库,这很方便。
最后,我会根据动画出现的位置在 Matplotlib 和 Plotly 之间做出决定。如果动画是在一个网页上,它将受益于互动,我会使用 Plotly。对于不能嵌入 html(比如 Medium)的视频或网站,我会推荐 Matplotlib。
你会选哪个?
Matplotlib 动画文档:https://matplotlib.org/stable/api/animation_api.html
Plotly 动画文档:https://plotly.com/python/animations/
本文的所有代码都可以在:https://github.com/benbogart/matplotlib-plotly-animations获得
自然语言处理(NLP)模型和 Python 实现的基本概念
原文:https://towardsdatascience.com/basic-concepts-of-natural-language-processing-nlp-models-and-python-implementation-88a589ce1fc0?source=collection_archive---------6-----------------------

来源:照片由 Ogelamar 在 Unsplash 上拍摄
在数据科学领域,自然语言处理(NLP)是一个非常重要的组成部分,因为它在各个行业/部门都有广泛的应用。对于一个人来说,理解这种语言是很容易的,但是机器没有足够的能力来轻松识别它。NLP 是一种使机器能够解释和理解人类交流方式的技术。
目前,社交媒体是自然语言的黄金数据矿,无论是来自任何在线网站(亚马逊、谷歌等)的任何类型的评论。),或者只是在 Twitter、脸书、LinkedIn 或电子邮件上发帖。每个领域的业务用例(分类、文本摘要、分类、交互式语音应答(IVR)、语言翻译、聊天机器人)可能不同,但 NLP 定义了这些用例的核心基础解决方案。
自然语言是文本的自由形式,这意味着它在本质上是非结构化的。因此,在开发任何模型时,清理和准备数据以提取特征对于 NLP 之旅非常重要。本文将在下面介绍基本但重要的步骤,并展示我们如何使用不同的包在 python 中实现它们,并开发一个基于 NLP 的分类模型。
A)数据清理
B)标记化
C)矢量化/单词嵌入
D)模型开发
A)数据清理
如上所述,数据清洗是自然语言处理中基本但非常重要的步骤。以下是数据清理的几种方法。让我们考虑下面这条线。
line = ‘Reaching out for HELP. Please meet me in LONDON at 6 a.m xyz@abc.com #urgent’
1。移除停用词:有几个词是人类互动时非常常用的,但这些词没有任何意义,也没有增加任何额外的价值。此外,对于手头给出的业务案例,可能有一些词语是不需要的。所以,这些词需要从数据中删除。
NLTK 包为不同的语言(如英语)定义了一组停用词。在这里,我们将集中讨论“英语”停用词。如果需要,还可以考虑附加的停用词。
import nltkimport refrom nltk.corpus import stopwords# Additional stopwords
extra_list = [“let”, “may”, “might”, “must”, “need”, “apologies”, “meet”]stopword = stopwords.words(“english”)stopword.extend(extra_list)line = ‘ ‘.join([i for i in line.split() if i not in stopword])
2。Make 小写:要求所有的单词都用小写,以保持一致性。
line = line.lower()
3。词汇化:这有助于将单词简化为单一形式。例如:
def lemmatize_text(text):w_tokenizer = nltk.tokenize.WhitespaceTokenizer()lemmatizer = nltk.stem.WordNetLemmatizer()return [lemmatizer.lemmatize(w) for w in w_tokenizer.tokenize(text)]lemmatize_text(line)
4。词干化:这有助于将单词还原成它们的词根形式。例如:
def stem_porter(text):w_tokenizer = nltk.tokenize.WhitespaceTokenizer()ps = nltk.PorterStemmer()return [ps.stem(w) for w in w_tokenizer.tokenize(text)]stem_porter(line)
除了波特斯特默之外,还有两种词干。那些是兰卡斯特炮泥和雪球。雪球是对波特词干的改进。
5。正则表达式的去除:正则表达式有助于识别和去除文本中不需要的不同模式。
line = re.sub(‘\S*@\S*\s?’,” “,line) #email removeline = re.sub(‘\s+’,” “,line) #new line character removeline = re.sub(“\’”,” “,line) #single quote removeline = re.sub(‘_’,” “,line) #underscore removeline = re.sub(‘http\S*\s?’,” “,line) #link removeline = ‘ ‘.join([i for i in line.split() if i.find(‘#’) < 0]) #hasgtag removeline = ‘ ‘.join([i for i in line.split() if i in re.findall(r’\w+’,line)]) #only keep words and numbers
6。词性标注:这有助于识别词性。基于用例,人们可以保留或删除其中的一些。
import spacyfrom spacy.tokenizer import Tokenizernlp = spacy.load(“en_core_web_sm”)tokens_spacy = nlp(line)for token in tokens_spacy:print(token.text, ‘: ‘, token.pos_, ‘: ‘, token.is_stop)
7。命名实体识别(NER): 这有助于识别和分类不同的组,包括名称、地点、货币等。
for ent in tokens_spacy.ents:print(ent.text, ‘: ‘, ent.label_)
B)标记化
这是处理文本数据时的常见做法之一。这有助于将一个短语、句子或段落分成像单词或术语这样的小单元。每个单元称为一个令牌。有不同类型的标记化。我们已经在上面的例子中使用了词干分析、词性标注和 NER。以下是对文本进行标记的不同方法。
str1 = “I am eating pizza and, coke.”
1)使用 split()函数的标记化:返回给定字符串被指定分隔符打断后的字符串列表。默认情况下,分隔符是一个空格。
str1.split()[‘I’, ‘am’, ‘eating’, ‘pizza’, ‘and,’, ‘coke.’]
2)使用正则表达式的标记化:返回基于正则表达式的列表。
re.findall(“[\w]+”,str1)[‘I’, ‘am’, ‘eating’, ‘pizza’, ‘and’, ‘coke’]
3)使用 NLTK 进行标记化:NLTK 包下有不同类型的标记化器,像 word tokenizer (word_tokenize)、regex tokenizer (RegexpTokenizer)、whitespace tokenizer(whitespace tokenizer)等。
3.1)
from nltk import word_tokenizeword_tokenize(str1)[‘I’, ‘am’, ‘eating’, ‘pizza’, ‘and’, ‘,’, ‘coke’, ‘.’]
3.2)
space_tokenizer = nltk.tokenize.WhitespaceTokenizer()space _tokenizer.tokenize(str1)[‘I’, ‘am’, ‘eating’, ‘pizza’, ‘and,’, ‘coke,’]
3.3)
reg_tokenizer = nltk.tokenize.RegexpTokenizer(“[A-Za-z]+”)reg_tokenizer.tokenize(str1)[‘I’, ‘am’, ‘eating’, ‘pizza’, ‘and’, ‘coke’]
此外,我们可以使用这些标记化的形式来计算文本中的单词数或单词在文本中的出现频率。
C)矢量化/单词嵌入
一旦清理和标记化完成,从干净的数据中提取特征是非常重要的,因为机器不理解单词,而是数字。矢量化有助于将单词映射到实数向量,这进一步有助于预测。这有助于提取重要的特征。以下是用于此目的的几种技术:
1。CountVec: 统计特定单词在文档中出现的次数。CountVectorizer 有助于获得这个计数。
from sklearn.feature_extraction.text import CountVectorizercount_vec = CountVectorizer(analyzer=’word’, ngram_range=(1, 3), stop_words = ‘english’)count_vec.fit(str2)count = count_vec.transform(str2)vectors = count_vec.get_feature_names()smatrix = count_vec.transform(str2)dense = smatrix.todense()dense_list = dense.tolist()df_countvec = pd.DataFrame(dense_list,columns=vectors)
2。TF-IDF: 词频逆文档频率(TF-IDF)提供了一个词在文档中的总体权重。TfidfVectorizer 有助于获得这个加权分数。
from sklearn.feature_extraction.text import TfidfVectorizertfidf_vec = TfidfVectorizer (analyzer=’word’, ngram_range=(1, 3), stop_words = ‘english’)tfidf_vec.fit(str2)tfidf = tfidf_vec.transform(str2)vectors = tfidf_vec.get_feature_names()smatrix = tfidf_vec.transform(str2)dense = smatrix.todense()dense_list = dense.tolist()df_ tfidf = pd.DataFrame(dense_list,columns=vectors)
比较: CountVec 可能会提供偏向最常用词的结果。这忽略了可能具有更高重要性的罕见单词。这意味着我们需要惩罚最常用的单词。TF-IDF 启用惩罚效果。它通过测量文档中出现的单词来衡量计数。举个例子,
str2 = [‘I am going to test Covid’,‘It seems ABC hospital is doing the Covid test’,‘Covaxin is still in WIP phase’]

CountVec 输出(图片由作者提供)

TF-IDF 输出(图片由作者提供)
这两种模型都为每个单词提供了一个数字(计数或重量)。但是要理解每个单词的上下文并识别其内容,每个单词一个向量要合适得多。 Word2Vec 通过浏览给定文档,为每个单词提供一个向量,这比简单的单词包或 TF-IDF 更有用。但 Word2Vec 缺乏对这种关系的“本地理解”,这一点由 Glove 回答。Glove 是一种预先训练的矢量化技术,它不仅理解本地上下文,还理解与全局单词的关系。除了 Glove, FastText 是另一种流行的单词嵌入技术,它对罕见单词或未收录单词(OOV)更有效。
说了这么多,单词包或 TF-IDF(主要)至今仍被广泛使用,并且是日常 NLP 问题中非常重要的一部分。由于本文只打算介绍基本的 NLP 概念,Glove 或 FastText 没有详细介绍。
d)模型开发
最后一部分来了!最后,我们有一个基于计数或 TF-IDF 矩阵和因变量(标签)来开发模型。

作者图片
人们可以使用任何分类模型,如逻辑回归、随机森林(RF)、支持向量机(SVM)或任何深度学习模型,如 RNN、LSTM 或最先进的模型,如 BERT、GPT3 来预测标签。作为准确性 ROC、回忆、F1 分数的度量,可以基于手头的问题陈述来使用。
在运行模型之前,让我们将数据分成训练和测试。
X = df.drop(columns=’label’)y = df[‘label’]X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2, random_state=420,stratify=y)
现在,建立数据模型并检查准确性指标。
from sklearn.linear_model import LogisticRegression, RandomForestClassifiermodel = LogisticRegression()#model = RandomForestClassifier()model.fit(X_train, y_train)y_pred_class = model.predict(X_test)print(‘Accuracy: ‘, metrics.accuracy_score(y_test, y_pred_class))print(confusion_matrix(y_test, y_pred_class))
除了分类问题之外,自然语言处理还可以用于文本摘要、问答、主题建模(链接)、文本翻译等。
希望这篇文章能帮助你了解如何解决任何基于 NLP 的问题。在那之前,学习愉快!
免责声明:本文中表达的观点是作者以个人身份发表的意见,而非其雇主的意见
机器学习的基本分子表示
原文:https://towardsdatascience.com/basic-molecular-representation-for-machine-learning-b6be52e9ff76?source=collection_archive---------3-----------------------
思想和理论
从微笑到单词嵌入和图形嵌入

作者图片
机器学习已经应用于化学信息学和生命科学中的许多问题,例如,研究分子性质,开发新药。这些应用的问题解决流程中的一个关键问题是选择适当的分子表示,以表征目标数据集并服务于下游模型。图 1 显示了不同分子表示的概念框架。通常,一个分子由一个线性形式表示为一个微笑串,或者由一个图形式表示为一个相邻矩阵,可能与原子的节点属性矩阵和键的边属性矩阵一起。SMILES 字符串可以进一步转换成不同的格式,比如分子指纹、一键编码或单词嵌入。另一方面,分子表示的图形形式可以被下游模型直接使用或者被转换成用于任务的图形嵌入。

图 1。分子表示的概念框架
本帖描述了在实现上述概念框架时使用的一些代码,包括:
- 阅读、绘图、分析分子,
- 从微笑串生成分子指纹,
- 从 SMILES 字符串生成一位热码编码,
- 从 SMILES 字符串生成单词嵌入,以及
- 在图形中生成分子表示。
阅读、绘制和分析分子
RDKit 是一个用于化学信息学的开源库。图 2 显示了读取咖啡因的微笑字符串并绘制其分子结构的代码。请注意,在微笑字符串中,C 是碳,N 是氮,O 是氧。如图 3 所示,可以显示没有标记碳的分子,或者如图 4 所示,显示有标记碳的分子。
图二。阅读并画出咖啡因的分子。[ 3 ,4]****

图 3。caffeine.png

图 4。咖啡因 _with_prop.png
图 5 显示了显示咖啡因分子中原子和键的代码。
图 5。展示咖啡因分子中的原子和键。【5】
图 6 和图 7 分别显示了咖啡因分子中原子和键的细节。注意事项:
- 术语“芳烃”在下表中可简单视为“环”。图 6 中的 GetIsAromatic 表示原子是否在环中,图 7 中的 GetBondType 表示键是否在环中。
- 图 6 和图 7 可以被视为图 1 所示概念框架中的简单原子属性矩阵和简单键属性矩阵。
- 图 7 中的键列表可以表示分子的图形形式,即邻接矩阵的链表。
****
图 6。咖啡因的原子。
****
图 7。咖啡因的结合。
从微笑字符串生成分子指纹
RDKit 支持几个指纹函数,其输出可用于计算分子相似性或作为下游机器学习模型的输入。图 8 显示了检索 RDKit 指纹和 Morgan 指纹的代码,图 9 显示了这些指纹函数的结果。
图 8。检索 RDKit 指纹和 Morgan 指纹
图九。RDKit 指纹和 Morgan 指纹。
从 SMILES 字符串中生成一位热码
将 SMILES 字符串视为自然语言中的文本,可能 SMILES 字符串最简单的表示方法是字符级的一键编码。图 10 显示了在 SMILES 字符串的字符级生成一键编码的代码。
****图 10。SMILES 字符串字符级的一键编码。【6
注意,一键编码也可以用在原子级或原子/键属性矩阵中。
从 SMILES 字符串生成单词嵌入
在语言建模的背景下,生成分子表示的更复杂的方法是将单词嵌入的方法应用于分子的子结构。图 11 中的代码显示了使用 mol2vec 和 word2vec 为 HIV 数据集中的所有分子生成单词嵌入的过程。数据集中有 41127 个分子(图 12),每个分子被编码为一个 300 维向量(图 13)。注意,代码摘自“ 化学研究中的简单 ML:rd kit&mol 2 vec”,详细解释了预测 HIV 活性的解决方案。
图 11。为艾滋病毒数据集中的分子生成单词嵌入
图 12。HIV 数据集的列和行。
图 13。HIV 数据集中分子的 Mol2vec 嵌入
在图形中生成分子表示
在 RDKit 中操纵分子/原子/键的过程为生成分子表示的图形形式提供了基础。上面的图 5、图 6 和图 7 显示了咖啡因的邻接矩阵、节点属性矩阵和边属性网络。然而,将 RDKit 中的分子转换成 NetworkX (一个用于网络分析的开源库)中的图形,可以利用传统图形算法和现代图形模型的研究来调查分子结构和性质。图 14 显示了将 RDKit 中的分子转换成 NetworkX 中的图形的代码。图 15 显示了由 RDKit 和 NetworkX 绘制的分子图。
图 14。将 RDKit 中的分子转换为 NetworkX 中的图形

图 15。RDKit 和 NetworkX 的分子图
图网络中的一个重要研究领域是图嵌入。一般来说,图嵌入由三个主题组成:节点级嵌入(将图中的节点编码为向量)、边级嵌入(将图中的边编码为向量)、g 图级嵌入(将整个图编码为向量。)在本文中,我们将术语图嵌入视为图级嵌入,它为一个分子找到一个向量,该向量可以用作下游模型的输入。图 16 显示了将 RDKit 中的分子转换为 NetworkX 中的图形,并通过 Graph2Vec 在 KarateClub 下生成其图形嵌入的代码。Graph2Vec 是一个图形嵌入算法,KarateClub 是一个为图形数据提供无监督机器学习模型的包。图 17 显示了 HIV 数据集中分子的 Graph2Vec 嵌入。KarateClub 在库中介绍了几种图形嵌入算法。****
图 16。为 HIV 数据集中的分子生成图形嵌入
图 17 是 HIV 数据集中分子的 Graph2Vec 嵌入图
结论
这篇文章描述了几种分子表示,包括基于字符串的格式,基于图形的格式,以及一些变体,如单词嵌入和图形嵌入。这些分子表示,加上不同的机器学习算法,包括深度学习模型和图形神经网络,可以作为处理分子机器学习问题的基线。
感谢阅读。如果你有任何意见,请随时给我留言。
数据科学的基本概率概念(Stat-08)
原文:https://towardsdatascience.com/basic-probability-concepts-for-data-science-eb8e08c9ad92?source=collection_archive---------23-----------------------
概率有助于预测任何事件的未知结果

莫里茨·金德勒在 Unsplash 上拍摄的照片
动机
概率是最常见的术语之一,不仅在数学中如此,在现实世界中也是如此。我们经常使用概率这个词。大约七年前,我还在读中学,开始接触概率这个术语,这是一个数学话题。那时,我已经解决了许多关于概率的数学问题。不幸的是,我对此不感兴趣。最后,当我在探索垃圾邮件过滤技术时,我惊讶地发现用于检测垃圾邮件过滤的最流行的机器学习算法是朴素贝叶斯分类器。有趣的是,分类器的主要思想来自于概率。所以我开始深入学习概率的概念,发现了这么多数据科学中不可或缺的实际用途。它激励我更实际地学习。现在,是分享知识的时候了。
✪概率
概率是一个数字概念,用于衡量任何特定事件或结果发生的可能性。概率值的范围是从 0 到 1。如果该值更接近 1。那么我们可以假设它发生的概率很高。相反,如果该值更接近 0。那么可以说它消失的概率很大。概率是一种用于非平凡应用的有效技术。诸如
- Gmail 收件箱的垃圾邮件过滤器。
- 用于医学图像分析的图像识别系统。
两种不同的过程被用来寻找概率。
我)。 实验或经验概率。
ii)。 理论概率。
➤ 实验或经验概率
经验概率是通过实验来估计概率的过程。我们考虑一个掷硬币事件;如果我们掷硬币,只会有两种结果正面或反面。假设,我们想知道人头落地的概率。我们可以通过以下步骤找到它。
我)。 起初,我们可以抛几次硬币。我们假设掷硬币 200 次。
ii)。 我们可以数硬币落在头上的次数。我们假设硬币落在头上 79 次。
三世)。 现在我们可以用数字头除以我们抛硬币的总次数的数字。

行政长官在广场拍照
所以得人头的概率= 79/200 = 0.395
为了说明,我们可以考虑另一个现实生活中的例子;你想在市场上推出两种不同类型的新产品。在投放市场之前,你必须了解人们的喜好。
为了进行这个实验,你随机选择数百人,然后你让他们选择他们喜欢的产品。完成后,你发现 85 人更喜欢第一种产品,其余的人选择第二种。所以,第一个乘积的经验概率= 85/100。
我认为你可以理解经验概率。
➤ 理论概率
理论概率是基于推理估计概率的过程。考虑之前抛硬币的例子。我们必须按照下面的步骤找到理论概率。
我)。 首先,我们要知道有利结果的总数。这里,对于 tail,它只有一种可能的结果。
ii)。 最后,我们要知道结果的总数。这里,我们可能有两种可能的结果:头和尾。
所以,理论概率= 1/2= 0.5
让我们假设另一个现实生活中的例子,从一副牌中取出一张红色的牌。如果我们计算一下红起来的概率,会是。
p(红色)= 13/52
这里,获得红色的有利结果的数量是 13。结果的总数是 52。
✪一些基本的概率术语
➤ 结果&事件:我们可以将结果表示为一个事件。实验结果的总数称为一个事件。我们也可以说结果是一个事件所有可能的结果。假设我们想预测下周的天气。可能有不同种类的可能情况。
(I)一周中的所有天都将是晴天、雨天或阴天。
(ii)三天将是雨天、晴天或多云,另外三天将是多云、晴天或雨天。
此外,还会发生更多的情况。
所有可能的结果都被称为结果。给定条件下所有可能的结果统称为事件。
➤ 样本空间:样本空间表示集合中所有可能的结果。假设掷骰子有六种可能的结果。我们可以把所有的结果写成一组。如:{1,2,3,4,5,6}。此外,事件是样本空间的子集。
概率中不同类型事件的✪类型
在这一部分,我们将试图用概率来解释不同种类的事件。
➤ 不可能且确定的事件:如果一个事件发生的可能性为 0,则称之为不可能事件。而如果任何事件发生的可能性为 1,则称之为确定事件。假设你掷一个有六种可能结果的骰子。得到 1-6 之间的数字的几率是 1。这是这个实验的必然结果。但是得到大于 6 的数的可能性是 0。因为可能的结果介于 1–6 之间,所以是不可能事件,这个实验就叫不可能事件。
➤ 简单事件:只有一种可能结果的事件称为简单事件。例如:s={23},这个事件只有一个可能的结果。所以,这是一个简单的事件。
➤ 复合事件:有一个以上可能结果的事件称为复合事件。例如:s={23,34,45},这个事件有三种可能的结果。
➤ 独立和相关事件:如果一个事件不依赖于任何其他事件,或者一个事件完全不受其他事件的影响,则称之为独立事件。受其他事件影响的事件称为相关事件。假设你从一个袋子里一个接一个地抽出两个球。如果你先抽第一个球,再抽第二个球,而没有把第一个球放回去,就会受到第一个球的影响。相比之下,如果你把第一个球放回袋子里,然后抽第二个球。不会受到第一个球的影响。
➤ 互斥事件:互斥事件是指两件事情不能同时发生。它还可以表示任何事件的发生都完全独立于其他事件的发生。比如扔硬币有两个事件 s ={H,T},这两个事件是完全不同的。

图 1:互斥事件的维恩图(图片由作者提供)。

图 2:互不互斥事件的维恩图(图片由作者提供)。
➤ 穷举事件:如果所有的事件一起表示一个样本空间叫做互斥事件。
✪概率中的一些规则
➤ 概率的加法法则
加法规则规定获得 A 或 B 的概率将是获得 A 的概率和获得 B 的概率之和,也用 ' U' 表示。
➣ 互斥事件的加法规则:在这里,两个事件互不影响。该事件的公式为
P(A U B) = P(A) + P(B)
如果事件有两个以上的事件,则公式变为
P(A ∪ B C…..)= P(A) + P(B) + P(C)……..
假设我们从一副牌中拿起一张牌。现在,拿到红卡或黑卡的概率。
p(红色或黑色)= 26/52 + 26/52
在这里,红色和黑色事件并不相互影响。
➣ 非互斥事件的加法法则:这里,两个事件是相互影响的。该事件的公式为
P(A U B) = P(A) + P(B) — P(A ∩ B)。
这里我们必须减去两个同时发生的事件的价值。
假设,我们抽一张有国王或红心的牌。(如果你想了解 52 副牌,请 访问 这个网站。)在这里,可能会发生三种情况。
我) 牌将为王。
ii) 这张牌可能是红心。
iii) 这张牌可能同时是国王和红心。
为了说明概率,我们必须将获得国王的概率和获得红心的概率相加,并减去获得国王和红心的概率。
P(国王 U 红心)= P(国王)+ P(红心)— P(国王∩红心)
= 4/52 + 13/52–1/52

来源:https://commons.wikimedia.org/wiki/File:Piatnikcards.jpg(免费许可证)
这里只有四张牌是王,13 张是红心。还有,普通卡只有一张。我想你能理解这个题目。
➤乘法概率规则
当两个事件相继发生时,这里使用乘法规则。它用“∩”符号表示。
➣ 互斥事件的乘法法则:这里,两个事件相继发生,并且都是独立的。该事件的公式为
P(A ∩ B) = P(A)*P(B)
假设,我们掷骰子两次,想求得到 1 和 3 的概率。
P(1 ∩ 3) = P(1)*P(3)
如果我们每次掷骰子,得到 1 到 6 之间的数字的概率是 1/6。这里,当前事件得到这个范围内的数的概率不依赖于前一个事件。如果我们掷骰子两次、三次或任意次,我们得到的数字在 1 和 6 之间的概率值是相同的。
在这个例子中,
P(1)= 1/6
P(3) = 1/6
所以,P(1 ∩ 3) = 1/6 *1/6
如果你不明白,我想你可以阅读下一部分。所以不用担心!!!!!!!
➣ 非互斥事件的乘法法则:这里,两个事件相继发生,并且都是相互依赖的。假设,你正从一副 52 张牌中拿一张牌。你拿了一张红牌。同样,你拿了一张牌,但没有把红牌放回牌堆。在这里,可能会发生两件事。
i) 当你拿第一张牌的时候,当时牌的总数是 52 张。
ii) 其次,当你拿起第二张牌时,当时总牌数为 51,因为你没有放回这副牌中的第一件物品。
在这个场景中,我们发现这两个事件相互依赖。假设,你想拿两张牌。首先,你要挑一张红牌,然后是一张国王。所以拿到红王和王的概率是
P(R ∩ K) = P(R)*P(K/R),
我们发现一个新的术语 P(K/R),叫做条件概率。我们将在下一部分描述它。它被称为给定 r 的 K 的概率,这意味着我们要计算 K 的概率,它取决于前一个事件。所以,
P(R ∩ K) = 1/52 * 1/51
这里,P(R) = 1/52,因为我们从总共 52 张卡中取出了一张。
P(K/R) = 1/51,因为我们从总共 51 张卡中取出了一张。
我们可以对互斥事件使用条件概率。对于这种情况,
P(A ∩ B) = P(A)*P(B/A)
= P(A)*P(B)这里,事件 B 不依赖于 A
条件概率
当一个事件发生时,它可能与其他事件有关系,称为条件概率。依赖于事件 A 的事件 B 的条件概率的规则是
P(B/A) = P(A ∩ B) /P(A)
假设,两个事件
事件 A: 明天会是晴天。它有 0.5 的概率。
事件 B: 你明天要去逛街。它有 0.7 的概率。
如果这两个事件之间有联系,条件概率就适用。

由 petr sidorov 在 Unsplash 上拍摄的照片
在使用术语预测的地方,概率以某种方式包含在其中。今天的世界是技术的世界,人们喜欢知道未来的结果,预测不同的情况,等等。概率在这方面起着重要的作用。也是数据科学不可回避的话题。
参考:
【1】。https://byjus.com/maths/types-of-events-in-probability/
【2】。https://courses . lumen learning . com/无量-统计/章节/概率-规则/
【3】。https://key differences . com/difference-between-mutual-exclusive-and-independent-events . html
【4】。https://www . statistics show to . com/probability-and-statistics/statistics-definitions/conditional-probability-definition-examples/
关于数据科学统计学的完整系列文章
- 少即是多;采样的‘艺术’(Stat-01)
- 熟悉数据科学最重要的武器~变量(Stat-02)
- 要提高数据分析能力,您必须了解频率分布(Stat-03)
- 通过可视化频率分布找到数据集的模式(Stat-04)
- 比较多个频率分布,从数据集中提取有价值的信息(Stat-05)
- 通过简短的讨论消除你对 Mean 的误解(Stat-06)
- 通过规范化提高您的数据科学模型效率(Stat-07)
- 数据科学的基本概率概念(Stat-08)
- 从朴素贝叶斯定理到朴素贝叶斯分类器的路线图(Stat-09)
- 数据科学爱好者需要知道的假设检验(Stat-10)
- 多组间统计比较用 ANOVA (Stat-11)
- 用卡方检验比较分类变量的相关性(Stat-12)
基于 OpenCV 和 DLIB 的基本微笑检测
原文:https://towardsdatascience.com/basic-smile-detection-using-opencv-and-dlib-aeb22afb9e67?source=collection_archive---------15-----------------------

稳定面部标志上的基本微笑检测(由 Felipe Cunha 制作的 gif)
在本文中,我们将实现一个基于面部标志位置几何的基本微笑检测器。
基本的情绪检测包括分析一个人的面部标志的几何形状。在微笑的情况下,嘴角之间的距离增加。然而,不同的人有不同的嘴的大小,你可以通过除以下巴的距离来标准化这个度量,并获得一个可以用于不同对象的通用比率。
一旦我们检测到面部标志,我们可以通过(landmarks[0]访问坐标。parts()[i]。x,地标[0]。parts()[i]。y),其中 I 是指数,来计算这个比值。下图显示了每个 Dlib 标志在面部的位置。

来自 iBUG 300-W 数据集的 68 个面部标志坐标(来源:https://www.pyimagesearch.com/
在我们的基本检测器中,我们将使用点 49、55、3 和 15 的 x 坐标来计算比率。
稳定阈值是一个实验过程,我尝试了不同的图像,对我有效的是 0.36。你可以让它更敏感或更不敏感,但越敏感就越容易出错。
在下面的要点中,你可以找到代码的解释和下载模型的链接,这样你就可以自己尝试了!

由杰克·纳科斯在 Unsplash 上拍摄的照片
我希望你们喜欢这个关于如何实现微笑检测器的简单教程。你可以使用相同的策略来检测其他事情,例如,如果对象的眼睛是闭着的(车辆安全)或者面部表情与其他感觉有关,如愤怒或厌恶。
每个数据科学家都必须知道的基本统计概念
原文:https://towardsdatascience.com/basic-statistical-concepts-every-data-scientist-must-know-e4f000254f55?source=collection_archive---------28-----------------------
入门
从 python 实现的实际角度来看

斯科特·格雷厄姆在 Unsplash 上拍照
统计在数据科学项目中扮演着重要的角色。它们非常有助于更好地理解数据,也有助于提取见解。这是一个重要的领域,每个数据科学家都必须清楚地了解基本的统计概念。
在本文中,我将向您详细介绍数据科学项目中经常使用的基本统计概念、可以使用它们的场景,以及使用 python 实现它们。本文中使用的脚本和数据可以在下面的 git 存储库中找到这里是
1.取样技术
抽样是统计学中的一个重要概念,当从较大的总体中选择一个数据子集时,这里的总体是指整个数据。为了更直观,让我举一个电子商务公司的例子,该公司希望更好地了解其客户的兴趣。我们可以通过邀请客户参与调查来更好地了解他们,但要求每个客户都参与调查是不可行的,也是可取的,因此我们需要确定目标受众,为此,可以使用合适的抽样技术。有许多采样技术,我们将看到一些流行的方法及其使用 python 的实现
简单随机抽样
简单的随机抽样方法是我们从总体中随机选择数据。简单随机抽样的问题是,我们总是有可能忽略原始数据中存在的类别,因此我们选择的样本可能不能很好地代表总体。
下面是使用 python 实现的简单随机抽样,我们首先确定了总体的原始均值,以便可以将其与样本均值进行比较。当样本的平均值接近实际总体时,可以假设样本的分布足够接近总体
来自数据科学与莎兰的脚本
系统抽样
在这种方法中,我们使用系统的方法来选择样本的元素,比如根据列 id 或记录创建日期选择第 n 个元素。在这种方法中,忽略某个类别的概率较小,但问题是某些类别有可能被过度表示或表示不足。下面是使用 python 对这种采样技术的简单实现,
脚本来自数据科学与莎兰
基于聚类的抽样
这种方法解决了我们在系统抽样方法和简单随机抽样方法中遇到的问题,在这里,我们确保我们包括来自所有类别的数据点,并且我们还确保我们不会过度或不足地代表任何类别。这里唯一的问题是,在现实中,数据可以通过不同的方式进行分类,例如,如果我以人类为例,我们可以根据性别、年龄、国家、教育程度等进行分组。因此,在这些复杂的情况下,使用基于聚类的抽样可能并不适用于所有类别。
脚本来自数据科学与莎兰
分层抽样
这种方法是最常用的技术之一,这种方法确保了总体的分布被保留在样本中。下面是使用 python 的实现,在创建样本后,脚本还会检查与原始数据相比的分布。
脚本来自数据科学与莎兰
这是关于抽样和使用 python 实现的流行方法,一般来说,分层抽样方法最接近实际人口。
2.描述统计学
描述性统计提供了对数据集中存在的各种要素的高级分析。下面是一些常用的描述性统计技术及其 python 实现,供大家参考。
柱状图
直方图有助于了解数据集中要素的分布。了解要素的分布(要素是数据集中的属性)非常重要,因为它在选择预测算法时起着关键作用。例如,当我们使用线性回归算法时,算法的一个假设是特征都是正态分布的。下面是绘制直方图的脚本,
来自数据科学与莎兰的脚本
集中趋势
集中趋势的各种度量是平均值、中间值和众数,这些值用于识别分布中的中心点。一般来说,平均值是识别中心点的一个很好的方法,在倾斜数据的情况下,中位数可能更好,而在有序数据的情况下,中位数或众数将是比平均值更好的选择。

图片来自 codeburst.io 作者天后杜加尔
偏斜度和峰度
偏斜度用于识别分布是对称的(即正态分布)还是不对称的(偏斜分布)。当偏斜度的值为零时,则意味着分布是正态的。负值表示数据呈负偏态,即分布左侧有长尾,正偏态表示分布右侧有长尾。
许多金融数据会被正面扭曲,比如个人财富、住房奖金、支出等。在所有这些情况下,中值和平均值将比众数高得多,因为尽管大多数值都落在众数附近,但也有极少数值非常高的情况,在构建预测模型时,我们不能忽略这些值,同时我们不能原样使用这些特征,因为许多预测模型不能很好地处理有偏差的数据,因此需要适当的数据转换。
另一方面,峰度可以用来估计数据中异常值的数量。峰度值为 0 表示分布是正态的,没有很多异常值,峰度值高表示数据中可能有很多异常值,峰度值低表示数据中的异常值较少。
偏斜度和峰度都有助于更好地理解分布,使得如果在数据集中发现任何偏差,则可以设计治疗计划,例如如果数据高度偏斜或/和具有大量异常值,则可以使用合适的变换,例如对数变换。下面是获取集中趋势度量、偏度和峰度的脚本
脚本来自数据科学与莎兰
可变性测量
统计中的可变性用于衡量数据的分散程度。可用于测量可变性的不同方法有百分位值、标准差和方差。当我们进行比较时,这些可变性测量非常有用。举个例子,假设一家电子商务公司正在进行一些设计更改,以缩短客户完成交易所需的总时间。在这些情况下,使用变更前后的可变性度量来查看变更是否成功。
简单地说,在设计变更之前,假设完成交易的时间为 10 分钟,标准偏差为 2 分钟,而在设计变更之后,完成交易的时间为 9 分钟,标准偏差为 3 分钟。现在,为了检验它是否显著,我们使用一个合适的假设检验。
此外,当我们使用基于距离的算法(如 K-Means 或 KNN)时,预计所使用的特征相对来说具有相似的规模,因此可变性测量也有助于检查数据是否符合要求。下面是使用 python 对上述可变性测量的实现,
来自数据科学与莎兰的脚本
3.基于关系的测量
基于关系的统计度量是相关性和协方差。我见过很多人把相关性误认为因果关系。它们之间有很多差异,作为一名数据科学家,了解这些差异非常重要。
相互关系
两个变量之间的相关性显示了它们之间的关系,即当一个变量增加时,它如何影响另一个变量。当我们说两个变量彼此正相关时,这意味着随着一个变量的增加,另一个变量也增加。当两个变量之间的相关值接近零时,意味着它们之间没有太大的关系。以下是一些具有不同相关性水平的散点图示例

图片来源——皮尔斯,罗德,2019,《数学是有趣的——相关性》,此处可用。
原因
如前所述,许多人假设相关性就是因果关系,也就是说,当变量‘A’和‘B’高度相关时,他们假设 A 导致了 B 的发生,但事实可能并非如此。事实上,相关性并不能解释任何与因果关系相关的事情。解释这一点的一个流行的例子是,随着温度的升高,犯罪数量增加,冰淇淋的销量也增加。所以这里冰淇淋的销售和犯罪数量是正相关的,但是冰淇淋的销售并没有导致犯罪的增加。另一方面,气温的上升导致人们购买冰淇淋,这在某种程度上也导致了犯罪的增加,因此这就是因果关系。
所以永远不要把相关性当成因果关系,即使这很诱人,是的,即使这很诱人,因为很多时候我们很容易把相关性当成因果关系。下面是使用 python 查找相关性和协方差的实现。
脚本来自数据科学与莎兰
4.分配
了解不同的分布是很好的,因为这将有助于更好地理解数据集,也有助于选择合适的预测模型。有许多发行版,但是首先你需要知道至少下面的发行版

图片来自 caladis.org
- 正态分布 —正态分布意味着大多数观察值集中在平均值附近,随着我们远离平均值,观察值的数量减少,并且分布是对称的,即平均值的左侧和右侧是相同的。
- 均匀分布 —在均匀分布的情况下,所有选项出现的概率是一样的就像扔硬币一样,正面和反面的概率都是 50%。
- 二项式分布 —它是有限集合中可能结果的频率分布。示例-两个骰子的掷数总和,可能的值范围在 2 到 12 之间,并且每个值都有一个概率值。
5.中心极限定理(CLT)
中心极限定理是统计学中一个流行的概念,按照 CLT 的说法,当我们从一个分布中抽取更多的样本时,样本平均值将趋向于正态分布,而不管实际的总体分布如何。
为了提到中心极限定理的一个真实的用例,让我们考虑预测选举结果。如果我们让一个小组进行调查,那么结果可能会有偏差,因为他们的目标受众可能不能很好地代表人口,但是当我们让多个独立小组进行调查并组合他们时,根据中心极限定理(CLT)的假设,结果将更接近实际人口。让我们使用下面的代码来测试中心极限定理,我们首先创建均匀分布的随机数据,然后开始挑选样本并计算这些样本的平均值,随着迭代次数的增加,样本平均值趋于形成正态分布。,
脚本来自数据科学与莎兰
下一步是什么?
完成这些基本概念后,你就可以专注于推断统计学的概念,学习如何使用合适的假设检验来得出一个不能基于描述性统计得出的结论。数据科学家通常使用的一些统计测试是,
- z 检验
- t 检验
- f 检验
- 方差分析
- 卡方检验
要了解数据科学所需的基本统计概念,请查看下面播放列表中我的教程视频。
关于我
我是一名拥有超过 10 年经验的数据科学专家,并且已经撰写了 2 本数据科学方面的书籍。我写数据科学相关的内容是为了让它简单易懂。跟我上 中 。我也有一个 YouTube 频道,在那里我教授和谈论各种数据科学概念。如果有兴趣,可以订阅我下面的频道。
https://www.youtube.com/c/DataSciencewithSharan
Python 中的基本文本摘要
原文:https://towardsdatascience.com/basic-text-summarization-in-python-d87df82497b3?source=collection_archive---------28-----------------------
如何使用文本摘要将复杂的书面报告转换为 300 字的压缩摘要

帕特里克·托马索在 Unsplash 上的照片
背景
文本摘要是文本挖掘和自然语言处理的一个子集,旨在获取长的文本语料库,并将其转换为可以轻松快速阅读和理解而不会丢失原始文本含义的摘要。
特别是文本摘要“标记”单词(即将其转换为数据),然后通过查看相对频率和其他因素来评估每个单词的重要性。然后可以将单词重要性分数聚合回句子的值,最重要的句子会出现在摘要的顶部。
如果你想更深入地探索这些原理,这篇文章是一个很好的起点——https://towardsdatascience . com/a-机器学习中的文本摘要快速介绍-3d27ccf18a9f
目标
本文的目标是开发一个基本的交互式文本摘要实用程序来演示这些原理,并提供一种为复杂报告生成基本摘要的方法。
如果摘要传达了源报告的大部分意思,并且能够在很短的时间内被阅读和理解,那么摘要就是成功的。
准备
首先,我们需要导入将要使用的库…
文件操作
我们的文本摘要实用程序的构建块处理允许用户浏览本地文件系统来选择要摘要的文件的工作。
openfile()处理显示文件|打开对话框,选择文件,并返回所选文件的完整路径。
接下来getText获取路径,打开文件并将文件中包含的文本读入一个str。提供的代码可以从。txt 或者。docx 文件。
文本摘要
主要工作通过调用gensim.summarization.summarize函数在一行代码中完成。同样的效果可以通过使用nltk自然语言工具包来实现,但是它会更加复杂,并且需要更低级的工作。
summarise函数提供了实现,它遵循文本摘要中涉及的 3 个基本步骤-
- 预处理和准备文本。
- 执行文本摘要过程。
- 后处理整理结果。
将会有许多严肃的、行业强度的文本处理引擎,它们涉及这 3 个步骤的复杂和全面的实现,但是这是一个很好的例子,它确实提供了我们将会看到的非常有用的摘要。
调用文本摘要
最后几个辅助函数是-
- 它格式化并打印包含标记的文本,给我们一个格式良好的标题。
openLocalFileAndSummarize它调用我们上面定义的函数来选择一个文件并汇总其内容。on_button_clicked它处理按钮点击事件,为笔记本增加交互性,并允许选择几个文件并按顺序汇总。
测试总结
为了测试文本摘要,我从两个公共网站收集了文本,这两个网站发布了关于在线报告和营销主题的免费报告。
用于提供测试数据的两个网站是-
- https://www . sustain ability-reports . com/unleashing-the-power of-online-reporting/
- https://www . McKinsey . com/business-functions/marketing-and-sales/our-insights/was-all-markets-now
运行总结
最后,一行代码创建了一个按钮,可以重复单击该按钮从本地磁盘中选择一个. txt 或. docx 文件,然后该文件将被转换为 300 字的摘要,如下所示。

作者图片
单击该按钮时,会显示一个文件|打开对话框来选择文件-

作者图片
一旦文件被选中,gensim.summarization.summarize开始工作,输出被格式化为单元格输出-
释放在线报告力量的执行摘要. txt
Unleashing the Power of Online Reporting Source: Sustainable Brands, 15 February 2018 Confronted with an ever-growing demand for transparency and materiality, companies need to find an adequate format to publish both financial and pre-financial information to their stakeholders in an effective way.In the real world, they are confronted with a multitude of information sources different in name, type and content, like Annual Report, CSR Report, Financial Statement, Sustainability Report, Annual Review, Corporate Citizenship Report, or Integrated Report.Online integrated reporting to the rescue Research from Message Group among Europe’s 800 largest companies shows that between 2015 and 2017 the number of businesses publishing financial and extra-financial information in one single integrated report increased by 34 percent, while the number of companies publishing separate sustainability and annual reports decreased by 30 percent.Unlike stand-alone annual or sustainability reports, online integrated reporting formats put an organization’s financial performance, business strategy and governance into the social, environmental and economic context within which it operates.Instead of directing readers from a webpage to separate PDF reports and resources located in different online places, Core & More provides all the relevant information on a single multi-layered website.Moreover, it is flexible enough to integrate multiple reporting frameworks, accounting standards and concepts, such as the International Financial Reporting Standard (IFRS) in combination with GRI, <IR>, the TCFD recommendations, or the SDGs.
On top of all this flexibility, a digital reporting format is highly interactive and customizable, allowing the reader to create charts or compile selected content into personal PDF or printed reports.Turning reporting into a powerful communications tool In view of growing demand for ESG disclosure, the related surge in sustainability reporting, and a complex reporting landscape companies are challenged to find a disclosure format for both financial and extra-financial information that has a measurable value for their key stakeholders.
结论
文本摘要可能是一个复杂且涉及预处理、摘要和后处理的过程,并且能够在不丢失原始文本含义的情况下对复杂报告进行摘要的真实世界应用将具有商业价值。
然而,在本文中,我们已经探索了基本概念,并快速构建了一个简单的文本摘要工具。txt 或者。docx 文件,然后根据评估最流行的句子将内容总结为 300 个单词。
对两个公开报告的测试证明了基本的文本摘要过程是有效的,并提供了一个摘要输出的例子。
完整的源代码可以在这里找到-
https://github.com/grahamharrison68/Public-Github/blob/master/Text Mining/Text Summarization Article.ipynb
感谢您的阅读!
如果你喜欢读这篇文章,为什么不看看我在 https://grahamharrison-86487.medium.com/的其他文章呢?
此外,我很乐意听到您对这篇文章、我的任何其他文章或任何与数据科学和数据分析相关的内容的看法。
如果你想联系我讨论这些话题,请在 LinkedIn 上找我—【https://www.linkedin.com/in/grahamharrison1 或者发电子邮件到ghar rison @ Lincoln college . AC . uk。
基础:渐变*输入作为解释
原文:https://towardsdatascience.com/basics-gradient-input-as-explanation-bca79bb80de0?source=collection_archive---------14-----------------------
入门,模型可解释性
简单函数的简单方法。
在这篇文章中,我想了解基于渐变的解释的基础,你如何使用它们,以及它们能做什么或不能做什么。
Gradient*Input 是解释可微分机器学习模型(如神经网络)的一种很好的方式,因为它在概念上很简单,易于实现。计算梯度也非常快,特别是如果你使用现代的 ML 库,像 pytorch 、 TensorFlow 或 JAX ,它们包括自动微分。
Gradient*Input 仅适用于解释相对简单的模型,但它是一个基本概念,对于理解许多其他更加健壮的基于梯度的技术是必要的。
什么是渐变?
你可能在高中或大学课堂上遇到过梯度。这不会是一个严谨的介绍,而只是一个快速的提醒。
首先,我们需要记住什么是 衍生品 。本质上,一个可微函数的导数 f(x): ℝ → ℝ,告诉我们对于任何输入 x,如果我们增加 x 一点,f(x)会改变多少。

蓝色:函数 f(x)。红色箭头:f(x)在两个不同 x 处的导数。导数本身(一个数字)只是箭头的倾斜度。图片作者。
这对于例如凸优化问题是有用的:为了找到最小值,我们只需从任意点开始,进入 f(x)减少最多的方向,重复计算梯度并采取步骤,直到我们到达最小值,即 梯度下降 。
可微函数 f(x): ℝ^d → ℝ的梯度只是 f(x) w.r.t .对 x 的每一个 d 维的(偏)导数的向量

蓝色:函数 f(x1,x2)。红色箭头:f(x1,x2)在两个不同点的梯度。图片作者。
梯度告诉我们,对于任意点(x1,x2 ),当在 d 维输入空间的任意方向上迈出一小步时,f(x1,x2)将改变多少。因此,它也告诉我们 f(x1,x1)在哪个方向上增加最多。
形式上,我们把 f(x) w.r.t. x 的梯度写成∇f(x).
归因看起来像什么?
一大类旨在解释机器学习模型的解释方法被称为归因方法,产生的解释被称为归因。归属的目的是将特定产出的一部分责任归属于相应投入的每个方面。
例如,考虑一只被训练从图像中识别鳄鱼的 DNN。归因方法将为输入的每个像素分配一个分数,表明该像素对最终输出的贡献(鳄鱼或非鳄鱼)。如果我们把这些个人属性放回一个矩阵中,我们通常称之为属性图。我们可以将属性图可视化为图像,指示图像的哪些区域是重要的。

左图:来自 ImageNet2012 数据集的鳄鱼。右图:一张可能的属性图,覆盖在原始图像上。图片作者。
创建属性地图有不同的方法,一般来说,没有事实来告诉我们哪个像素对输出的贡献有多大。这就是为什么没有一种归属方法可以声称它是“正确的”。通常,它们都有不同的属性,可能在不同的应用场景中有用。
什么是渐变*输入?
渐变*输入是一种属性方法,也是最简单有意义的方法之一。这个想法是使用函数(例如我们的模型)的梯度信息,它告诉我们对于每个输入维度,如果我们在这个方向上迈出一小步,函数是否会增加。如果我们的函数输出是,比方说,图像包含鳄鱼的概率,那么梯度基本上告诉我们每个维度增加了多少模型对鳄鱼的预测。
现在,如果我们知道每个维度在这个方向上的一个步骤增加了多少输出,我们只需要将它与输入本身相乘就可以得到一个完整的属性。

这个想法是,梯度告诉我们一个维度的重要性,输入告诉我们这个维度在图像中的表达有多强烈。综上所述,只有在以下情况下,维度的属性才会很高:1)维度似乎对输出很重要;2)维度的值很高。
到目前为止,一切似乎都很合理。只有一个问题:如果我们只迈出一小步,梯度只能告诉我们尺寸的重要性。这是非常局部的信息,当解释复杂的函数时,即使在输入空间中的几个微小的步骤之后,梯度也可以快速改变。这意味着,如果我们在梯度方向上迈出一步,函数可能会上升,但如果我们在相同方向上迈出一大步,函数也可能会下降——这实际上使梯度提供的解释无效。
现在这听起来很令人失望,当然有数据集和模型,梯度*输入比其他输入做得更好。如果你试图解释一个浅薄的神经网络,还是值得一试。
这个问题也有解决的办法,它依赖于与梯度输入相同的原理,但是使它更加健壮。也许最简单的是平滑梯度和综合梯度,但还有无数其他方法更复杂,可能基于不同的原理。
结束语和替代词
梯度*输入的力量,它是如此简单和快速。它也是更复杂的解释方法的坚实的概念基础。
普通梯度作为一种解释方法的缺点是,它们只适合局部地解释一个函数。这意味着,您应该只使用它们来解释相当简单的函数,因为简单性意味着它们在全局和局部的行为是相似的。
在我之前的一篇帖子中,我做了一个基于梯度的解释方法的对比。都是基于梯度*输入,并对其进行适配,使其更适合解释复杂函数。
当然,还有更多的解释方法。最流行的有遮挡分析、 SmoothGrad 、综合渐变、期望渐变、 LRP 、 DeepLIFT 、 Shapley 值。如果你想解释深层神经网络,我建议你转向他们。
希望你学到了有用的东西。
Apache Spark 配置设置的基础
原文:https://towardsdatascience.com/basics-of-apache-spark-configuration-settings-ca4faff40d45?source=collection_archive---------0-----------------------
使用 YARN 作为集群管理框架决定 Pyspark 配置参数
Apache Spark 是最流行的开源分布式计算平台之一,用于内存批处理和流处理。虽然它有望以常规方式快速处理数百万条记录,但如果最初配置不当,可能会导致无法接受的内存和 CPU 使用结果。Spark 应用程序的资源利用率非常重要,尤其是在 AWS 这样的云平台中。不必要的内存和 CPU 资源的使用以及长时间的工作过程可能会大大增加成本。
为了让 Spark 以高性能工作,出现了基于配置级和代码级的两个不同点。前者是在初始阶段正确配置 Spark,而后者是在考虑性能问题的情况下开发/审查代码。在这篇文章中,我的目标是深入了解配置设置。我还打算写另一篇关于编码最佳实践的文章。这篇文章主要是针对以集群模式运行纱线的 Pyspark 应用程序。

迭戈·根纳罗在 Unsplash 上的照片
火花建筑——以简单的方式
在继续讨论之前,我将简要介绍一下 Spark 架构和术语。Spark 使用主/从架构,带有一个名为驱动的中央协调器和一组名为执行器的可执行工作流,它们位于集群中的各个节点。
资源管理器是集群中所有应用之间资源分配的决策单元,是集群管理器的一部分。集群管理器是在集群上以容器的形式控制、管理和保留计算资源的进程。Spark 应用程序有许多集群管理器选项,其中之一是 Hadoop YARN。
当一个 Spark 应用启动时,资源管理器启动应用主机(AM) 并为其分配一个容器。AM 协调其应用程序中所有任务的执行。AM 可以被认为是一个非执行容器,具有向纱线请求容器的特殊能力,占用自己的资源。
一旦 AM 启动,它向资源管理器请求容器和容器的资源请求。成功接收集装箱后, AM 将其投放。在容器内部,它通过驱动运行用户应用程序代码。应用完成后, AM 将资源释放回资源管理器。如果 AM 崩溃或变得不可用,资源管理器可以创建另一个容器,并在其上重启 AM 。
驱动以集群模式放置在 AM 内部,负责将用户应用转换成更小的执行单元,称为任务,然后调度它们在执行器上运行。这些任务在 worker 节点上执行,然后将结果返回给驱动程序。驱动也通知 AM 执行者对应用的需求。它运行在自己的 JVM 中。执行者是工作者节点上的进程(计算单元),其工作是完成分配的任务。一个执行器容器就是一个 JVM。
Spark 上下文是 Spark 功能的主要入口。 Spark Context 还通过定期发送心跳消息来实时跟踪执行者。 Spark 上下文是由驱动为每个 Spark 应用程序创建的,当用户第一次提交时。它存在于 Spark 应用程序的整个生命周期中。火花上下文在火花应用完成后停止工作。
Spark 作业有两种不同的运行模式— 客户端模式和集群模式。区别主要取决于驱动在哪里运行。当它在客户端模式的客户端进程中运行时,它在集群模式的 AM 中运行。在生产中,集群模式是有意义的,客户端可以在初始化应用程序后离开。
纱线相关参数
Spark 的领先集群管理框架之一是 YARN。在纱线术语中,执行器和 AM 在容器内运行。容器就是内存和 CPU 的简单分配。当 Spark 应用在集群模式下通过 YARN 提交时,资源将由资源管理器以容器的形式进行分配。
在 yarn-site.xml 文件中,如果 Spark 作为集群管理框架与 yarn 一起使用,调整以下参数是一个很好的起点。在同一集群中运行火花应用和非火花应用的情况下,首先正确设置这些纱线参数是非常重要的。在某种程度上,这些参数将定义集群中 Spark 应用程序的边界。以下是需要正确设置的基本纱线参数。
yarn . node manager . resource . memory-MB
yarn . scheduler . max-allocation-MB
yarn . scheduler . minimum-allocation-MB
yarn . node manager . resource . CPU-v cores
yarn . scheduler . maximum-allocation-v cores
yarn . scheduler . minimum-allocation-v cores
yarn . node manager . resource . memory-MB简单来说就是单个节点中可以分配给容器的物理内存量。考虑到操作系统守护进程和节点中其他正在运行的进程,它必须低于节点的总 RAM 值。yarn . scheduler . minimum-allocation-MB和yarn . scheduler . maximum-allocation-MB参数分别表示单个容器可以获得的最小和最大内存分配值。
类似的推理也适用于容器的 CPU 分配。yarn . node manager . resource . CPU-vcores确定为单个节点中的所有容器分配的总可用 v cores。并且每个容器在作为下限和上限的yarn . scheduler . minimum-allocation-vcores和yarn . scheduler . maximum-allocation-v cores参数的值内获得 v cores。
Spark 中的内存管理
与 Spark 中的 CPU 利用率相比,内存利用率有点棘手。在深入研究配置调优之前,了解一下内存管理方面的情况会很有帮助。下图很好地总结了 Spark 中的内存管理。

火花记忆化合物
执行器容器(它是一个 JVM)分配一个由三部分组成的内存部分。它们分别是堆内存、堆外内存和开销内存。属性spark . memory . off Heap . enabled .默认禁用堆外内存。要使用堆外内存,可在启用后通过spark . memory . off Heap . size设置堆外内存的大小。关于 Spark 应用程序中堆外内存使用的详细解释,以及利弊可以在这里找到。
内存开销可以用spark . executor . memory overhead属性设置,默认情况下是 10%的 executor 内存,最小 384MB。它基本上涵盖了费用,如虚拟机管理费用,实习字符串,其他本地管理费用等。
有趣的事情开始了。与堆外内存不同,堆内存中的所有对象都由垃圾收集器(GC)绑定。为了简单起见,可以认为它由 3 个不同的区域组成,保留内存、用户内存和包括执行和存储内存的统一区域。保留内存用于存储内部对象。它是硬编码的,等于 300MB。
用户内存是为用户数据结构、Spark 中的内部元数据保留的,并在记录稀少且异常大的情况下防止 OOM 错误。使用 spark.memory.fraction 属性通过下面的公式简单估算。它决定了有多少 JVM 堆空间用于 Spark 执行内存。建议将此属性的默认值设置为 0.6。因此,用户内存等于 JVM 执行器内存(堆内存)的 40%。
User Memory = (Heap Size-300MB)*(1-spark.memory.fraction)# where 300MB stands for reserved memory and spark.memory.fraction propery is 0.6 by default.
在 Spark 中,执行和存储共享一个统一的区域。当不使用执行内存时,存储可以获取所有可用内存,反之亦然。在必要的情况下,执行可能会驱逐存储器,直到由spark . memory . storage fraction属性设置的某个限制。超过这个限制,执行在任何情况下都不能驱逐存储。该属性的默认值为 0.5。这个调整过程被称为动态占用机制。这种统一的内存管理是 Spark 从 1.6 开始的默认行为。执行和存储内存的初始值通过以下公式计算。
Execution memory = Usable Memory * spark.memory.fraction*(1-spark.memory.storageFraction)Storage memory = Usable Memory * spark.memory.fraction*spark.memory.storageFraction
执行内存用于存储混洗、连接、聚合、排序等操作中的临时数据。注意,数据操作实际上是在这一部分中处理的。另一方面,存储内存用于存储缓存和广播数据。正如预期的那样,执行内存优先于存储内存。任务的执行比缓存的数据更重要。如果执行内存不足,整个作业可能会崩溃。此外,重要的是要记住,在调整动态占用机制的参数时,驱逐过程是有代价的。内存回收的成本取决于缓存数据的存储级别,如 MEMORY_ONLY 和 MEMORY_AND_DISK_SER。Spark 中内存管理的清晰解释可以在这里找到。此外,您可以在这里找到另一个关于垃圾收集的内存管理视图。
主要配置设置
在设置相应的纱线参数并了解 Spark 中的内存管理后,我们进入下一部分——设置内部 Spark 参数。
正确设置下面列出的配置参数非常重要,它基本上决定了 Spark 的源消耗和性能。让我们来看看他们。
spark . executor . instances:spark 应用程序的执行者数量。
spark.executor.memory: 运行任务的每个执行器使用的内存量。
spark.executor.cores: 一个执行器可以运行的并发任务的数量。
spark.driver.memory: 数量用于驱动的内存。
spark.driver.cores: 用于驱动程序进程的虚拟内核数量。
spark . SQL . shuffle . partitions:为连接或聚合而重排数据时使用的分区数量。
spark . Default . parallelism:由连接和聚合等转换返回的弹性分布式数据集(rdd)中的默认分区数。
通过一个例子来理解配置设置背后的推理更好。假设我们有一个由 3 个节点组成的群集,具有指定的容量值,如下图所示。

一个火花簇例子
第一步是设置 spark.executor.cores 即多半是一个简单明了的属性。将大量的 vcores 分配给每个执行器会导致执行器数量的减少,从而降低并行性。另一方面,将少量的 vcores 分配给每个执行器会导致大量的执行器,因此可能会增加应用程序中的 I/O 成本。在上述标准的照明中,作为经验法则,一般设置为 5 。
第二步是决定spark . executor . instances属性。为了计算这个属性,我们首先确定每个节点的执行器数量。每个节点可能会为 Hadoop 和 OS 守护程序保留一个 vcore。这不是一条经验法则,您可以向系统管理员寻求帮助来决定这些值。
executor_per_node = (vcore_per_node-1)/spark.executor.coresexecutor_per_node = (16–1)/5 = 3spark.executor.instances = (executor_per_node * number_of_nodes)-1 spark.executor.instances = (3*3)-1 = 8
第三步是决定 spark.executor.memory 属性。为此,首先计算总的可用执行器内存,然后考虑内存开销,并从总的可用内存中减去。类似地,每个节点可能会为 Hadoop 和 OS 守护程序保留 1 GB。请注意,运行内存过多的执行器通常会导致过多的垃圾收集延迟。
total_executor_memory = (total_ram_per_node -1) / executor_per_nodetotal_executor_memory = (64–1)/3 = 21(rounded down)spark.executor.memory = total_executor_memory * 0.9spark.executor.memory = 21*0.9 = 18 (rounded down)memory_overhead = 21*0.1 = 3 (rounded up)
spark.driver.memory 可以设置成和 spark.executor.memory 一样,就像 spark.driver.cores 设置成和spark . executor . cores一样。
另一个突出的性质是spark . default . parallelism,可以借助下面的公式进行估算。建议集群中的每个 CPU 内核执行 2-3 个任务。Spark 在许多任务中重用一个 executor JVM,并有效地支持耗时约 200 毫秒的任务。因此,并行级别可以设置为大于集群中的内核数量。虽然公式的结果给出了一个线索,但鼓励考虑分区大小来调整并行度值。推荐的分区大小约为 128MB。通过使用重新分区和/或合并,可以在洗牌操作期间根据需要定义该属性。如果混洗操作中的数据量非常不同。在 Spark 执行的流程中,Spark . default . parallelism可能不会在会话级别设置
spark.default.parallelism = spark.executor.instances * spark.executor.cores * 2spark.default.parallelism = 8 * 5 * 2 = 80
对于数据帧,spark . SQL . shuffle . partitions可以和spark . default . parallelism属性一起设置。
请注意,所有配置设置方法都是基于最大化可用资源的利用率。然而,如果多个 Spark 应用程序运行在同一个集群上,并且共享一个公共资源池,那该怎么办呢?在那种情况下,利用spark . dynamic allocation . enabled属性可能是一种替代方法。与spark . dynamic allocation . initial executors、spark . dynamic allocation . min executors、和spark . dynamic allocation . max executors 一起使用。从属性名称可以理解,应用程序从初始的执行人编号开始,然后在执行需求高的情况下增加执行人编号,或者在执行人处于上下限内的空闲位置的情况下减少执行编号。
另一个观点可能是对运行多个 Spark 应用程序的环境应用实验方法。为了更好地阐明这一点,从验证工作持续时间等限制的配置开始。例如,计划的 Spark 应用程序每 10 分钟运行一次,预计不会持续超过 10 分钟。然后,只要不违反限制,逐步减少资源。
公平调度程序
如果您有一个运行大量 Spark 应用程序的环境,我也强烈建议您看看 YARN 中的 公平调度器 。它提供了一个更高的抽象来管理多个 Spark 应用程序的资源共享。目标是让所有应用程序在一段时间内获得或多或少相等的资源份额,而不是惩罚执行时间较短的应用程序。它的配置在两个文件中维护: yarn-site.xml 和 fair-schedular.xml 。
在公平调度器中,根据内存和 CPU 使用情况,通过利用队列来进行资源管理。这些队列之间公平地共享资源。队列的主要属性可以被计数为 minResources 、 maxResources 、 weights 和 schedulingPolicy 。为了更清楚起见,让我们假设您有相同的环境来开发新模型和在生产中运行调度应用程序,这是有原因的。可以为开发和生产应用程序定义单独的队列,类似地,可以为不同用户触发的应用程序定义不同的队列。此外,可以为不同的队列分配不同的权重,因此相应队列中的应用程序可以根据权重成比例地获得资源。对于同时使用 fair schedular 和 Spark 配置属性的问题,您可能会得到一个简单的答案。
有用的链接
https://medium.com/@ch.nabarun/apache-spark-optimization-techniques-54864d4fdc0c https://blog.cloudera.com/how-to-tune-your-apache-spark-jobs-part-2/ https://aws.amazon.com/tr/blogs/big-data/best-practices-for-successfully-managing-memory-for-apache-spark-applications-on-amazon-emr/ https://luminousmen.com/post/spark-anatomy-of-spark-application https://spark.apache.org/docs/latest/tuning.html#memory-management-overview
计数矢量器的基础
原文:https://towardsdatascience.com/basics-of-countvectorizer-e26677900f9c?source=collection_archive---------1-----------------------
了解关于 CountVectorizer 的一切信息。

照片由阿里·沙阿·拉哈尼在 Unsplash 上拍摄
机器不能理解字符和单词。所以在处理文本数据时,我们需要用机器能够理解的数字来表示它。Countvectorizer 是一种将文本转换为数字数据的方法。为了向您展示它是如何工作的,让我们举一个例子:
text = [‘Hello my name is james, this is my python notebook’]
文本被转换成如下所示的稀疏矩阵。

我们在文本中有 8 个唯一的单词,因此在矩阵中有 8 个不同的列,每个列代表一个唯一的单词。该行代表字数。因为单词“is”和“my”重复出现了两次,所以我们对这些特定单词的计数为 2,对其余单词的计数为 1。
Countvectorizer 使文本数据可以很容易地直接用于机器学习和深度学习模型,如文本分类。
让我们再举一个例子,但这一次有不止一个输入:
text = [‘Hello my name is james' , ’this is my python notebook’]
我有两个文本输入,所发生的是每个输入被预处理,标记化,并表示为一个稀疏矩阵。默认情况下,Countvectorizer 将文本转换为小写,并使用单词级标记化。

现在我们已经看了一些例子,让我们实际编码!
我们将首先从导入必要的库开始。我们将使用 pandas 库来可视化矩阵,并使用 sk learn . feature _ extraction . text 库来执行矢量化。
import pandas as pdfrom sklearn.feature_extraction.text import CountVectorizer text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer()count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)

参数
- 小写
在标记前将所有字符转换成小写。默认值设置为 true,并采用布尔值。
text = [‘hello my name is james’,‘Hello my name is James’] coun_vect = CountVectorizer(**lowercase=False**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)

现在让我们尝试不使用“小写=假”
text = [‘hello my name is james’,‘Hello my name is James’] coun_vect = CountVectorizer()count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)

- 停 _ 字
停用词是任何语言中对句子没有多大意义的词。它们可以被安全地忽略,而不会牺牲句子的意义。有三种处理停用词的方法:
- 自定义停用字词列表
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer(**stop_words= [‘is’,’to’,’my’]**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)
稀疏矩阵去掉这几个字后是,到和我的:

2.sklearn 内置停用词表
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer(**stop_words=’english’**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)

3.使用 max_df 和 min_df(稍后介绍)
Max_df:
Max_df 代表最大文档频率。类似于 min_df,我们可以忽略频繁出现的单词。这些单词可能就像在每个文档中出现的单词“the ”,不会为我们的文本分类或任何其他机器学习模型提供有价值的信息,因此可以安全地忽略。Max_df 查看有多少文档包含该单词,如果它超过 max_df 阈值,则从稀疏矩阵中消除它。这个参数又可以是 2 种类型的值,百分比和绝对值。
使用绝对值:
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer(**max_df=1**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)
单词“is”、“to”、“james”、“my”和“of”已从稀疏矩阵中删除,因为它们出现在多个文档中。

使用百分比:
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer(**max_df=0.75**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)
如您所见,单词“james”在 5 个文档中出现了 4 个(85%),因此越过了 75%的阈值并从稀疏矩阵中移除

Min_df:
Min_df 代表最小文档频率,与计算单词在整个数据集中出现的次数的术语频率相反,文档频率计算数据集中(也称为行或条目)具有特定单词的文档的数量。当构建词汇表时,Min_df 忽略文档频率严格低于给定阈值的术语。例如,在您的数据集中,您可能有只出现在 1 或 2 个文档中的名称,现在这些名称可以被忽略,因为它们不能提供整个数据集的足够信息,而只能提供几个特定文档的信息。min_df 可以取绝对值(1,2,3..)或表示文档百分比的值(0.50,忽略出现在 50%文档中的单词)
使用绝对值:
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’,‘james of words to try differnt’,‘features of count vectorizer’] coun_vect = CountVectorizer(**min_df=2**)count_matrix = coun_vect.fit_transform(text) count_array = count_matrix.toarray() df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)

- max_features
计数矢量器将选择出现频率最高的单词/特征/术语。它采用绝对值,因此如果您设置“max_features = 3”,它将选择数据中最常见的 3 个单词。
text = [‘This is the first document.’,’This document is the second document.’,’And this is the third one.’, ‘Is this the first document?’,]coun_vect = CountVectorizer(max_features=3)count_matrix = coun_vect.fit_transform(text)count_array = count_matrix.toarray()df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)df
- 双星
通过设置“binary = True”,CountVectorizer 不再考虑术语/单词的频率。如果发生,则设置为 1,否则为 0。默认情况下,binary 设置为 False。这通常在术语/单词的计数不能为机器学习模型提供有用信息时使用。
text = [‘This is the first document. Is this the first document?’ ]coun_vect = CountVectorizer(binary=True)count_matrix = coun_vect.fit_transform(text)count_array = count_matrix.toarray()df = pd.DataFrame(data=count_array,columns = coun_vect.get_feature_names())print(df)
尽管所有的单词在上面的输入中出现了两次,我们的稀疏矩阵只是用 1 来表示它

现在让我们看看我们是否使用了默认值:

- 词汇
它们是稀疏矩阵中单词的集合。
text = [‘hello my name is james’,‘Hello my name is James’]coun_vect = CountVectorizer()count_matrix = coun_vect.fit_transform(text)print(coun_vect.vocabulary_)

这些数字不代表单词的数量,而是代表单词在矩阵中的位置
如果你只是想要没有单词在稀疏矩阵中的位置的词汇表,你可以使用' get_feature_names()'方法。如果您注意到这是我们在创建数据库和设置列时使用的相同方法。
text = [‘Hello my name is james’,‘james this is my python notebook’,‘james trying to create a big dataset’] coun_vect = CountVectorizer()count_matrix = coun_vect.fit_transform(text) print( coun_vect.get_feature_names())

CountVectorizer 只是处理文本数据的方法之一。Td-idf 是一种更好的数据矢量化方法。我建议你查看一下 sklearn 的官方文档以了解更多信息。
希望这有所帮助:)
企业数据驱动转型的指针
原文:https://towardsdatascience.com/basics-of-data-driven-transformation-for-business-38a5033193fa?source=collection_archive---------28-----------------------

约翰·施诺布里奇在 Unsplash 上的照片
什么,为什么,以及共同的挑战
作为一名执行顾问和各种组织高级管理层的顾问,我与全球数十家财富 500 强企业合作,指导和支持他们各种形式的业务和数字化转型。转型的主题各不相同,从销售和收入管理转型、战略规划转型到定价和商业模式改革。然而,在所有这些努力中,一个越来越明显的共同点是在其商业实践中更好地使用数据和技术,无论是商业还是运营,以推动更大的竞争力并实现更远大的业务目标 。
随着关于分析、机器学习(ML)、人工智能(AI)…以及它们与当今企业的互动的流行词汇满天飞,数据驱动的转型的基础对于那些可能有兴趣着手实施的人来说可能并不总是很清楚。这篇文章旨在提供一个关于这个主题的快速入门。
什么是 数据驱动转型是什么意思
当我们说“数据驱动的转型”时,它指的是组织中涉及更多或更好地使用数据的任何计划,分析通常利用引入的新技术。
数据是分析和建模的来源,而分析和建模反过来将支持下游业务洞察提取或运营自动化。根据转换的具体用例、数据要求、数据格式(如时间序列、横截面、文本等)。)多样性(交易、人口统计、社会经济数据等。),体积,粒度,新旧程度都会不一样。
给定数据输入,可以应用传统分析(如描述性统计分析)或高级算法(如 AI/ML)来满足用例的目标,无论是客户获取预测、收入预测、员工流失预测,还是面向运营的用例,如使用 RPA(机器人流程自动化)实现保险索赔流程自动化。
在转型过程中,需要使用数字技术来清理、存储、转换数据和进行预测建模、生成见解或执行运营自动化,这些都是数字技术可以用来完成的最基本和最常见任务的几个例子。
根据转型的目标、变革的范围、所涉及的技术和业务合作伙伴,转型所需要的内容在不同的场景中会有很大的不同。要成功转型,除了技术方面,通常还需要其他方面的变革,如组织结构、文化以及员工的技能和能力。
为什么广受追捧
数据驱动的决策和转型的优势已经在各个领域和行业得到了广泛的见证和证明。麦肯锡全球研究所估计数据和分析如果大规模嵌入,每年可以创造价值 9.5 万亿到 15.4 万亿美元的价值[1]。业务收益可以是短期的,也可以是长期的,表现在以下几个方面:
支持 更好的决策,从而直接提高业务绩效 ,例如使用数据驱动的预测性客户细分和有针对性的营销来增加客户获取、需求增长或其他业务绩效 KPI(关键绩效指标)
推动 更高的生产力和运营效率 ,例如使用 RPA 实现保险索赔流程或仓库库存管理的自动化
其他 更长期的商业利益,如客户满意度、客户参与度或员工保留度 。
常见陷阱
尽管不同设置的转换细节可能会有很大差异,但仍有一些常见的挑战和陷阱:
数据质量和兼容性
然而,这是进行数据驱动的转换时最常见的挑战,也是最容易被忽略的。由于与存储和管理数据相关的任务的基本性质,通常由 IT 部门的初级人员执行,这一方面在组织中的所有“大”或“闪亮”项目中通常投资不足。
也就是说,数据是启动任何数据驱动的转型的输入和“燃料”。 正如我们所说的“垃圾进垃圾出”——如果数据质量不太好,就无法进行质量分析或 AI/ML 建模工作。 在设计转型和评估结果时,对数据状况进行完整而详细的审核应该是一项必不可少的尽职调查项目,这项工作可以在转型的准备阶段就开始进行。在转型的过程中,拥有提高数据质量的路线图通常也是必要的一步。
不同的数据/IT 系统和孤立的组织单位。
数据驱动的转换通常可以跨越组织的多个业务职能。以需求计划数字化转型为例(这是任何产品公司的关键业务操作),对于这种转型,所需的数据将来自相当多的功能:来自供应链的客户需求历史、来自销售的销售计划数据、来自 R&D 的新产品提供数据等等。这些数据集通常位于不同 IT 系统中组织的不同部分,不一定相互连接和同步。
了解来自不同业务部门的数据集的细微差别,收集和协调多个数据源,使它们相互兼容和连接,这是一项艰巨的任务。 然而,这一方面是启动跨职能转变的充分条件。
新技术的采用和整合
在数据驱动的转型中,新技术的引入无疑是不可避免的。由于技术、组织或人的心理的众多障碍因素, 在任何组织中采用一项新技术进入现有的业务流程都绝非易事 。新的数据平台或工具需要集成到现有的 IT 环境中;最重要的是,需要有效和高效地采用平台或工具,但通常很难实现。
专注于技术而不构建总体业务用例
技术可以为业务运营带来革命性的变化,但技术本身并不能创造价值。 如果缺乏足够的支持业务基础设施的变化,那么将会包括转换结果的整体交付——它们可能是过时的业务流程或工人的能力或上游业务操作,等等。再次以商业规划数字化转型为例,成功的端到端规划不仅需要利用人工智能/人工智能技术进行需求预测输入,还需要改进规划业务流程,以适应规划者在新规划工具中的角色;此外,规划师的新技能,如评估 AI/ML 和建立跨职能的人类共识等。也要求完成整个规划改造。
需要新的角色、能力、组织文化和心态变化
即使已经处理了转型中的所有技术方面,为了让转型随着时间的推移产生持续的效益,通常还需要新的角色、能力、组织文化和思维模式。改变组织文化,例如培养一种更加数据驱动的实践(相对于经验和直觉驱动),以及一种使用技术来提高运营效率和创新的思维模式等等。
[1] A. Ghia 、M. Langstaff、 D. Ware 和 Rob Wavra、加速公共部门的数据和分析转型 (2021),麦肯锡&公司
深度学习的基础:反向传播
原文:https://towardsdatascience.com/basics-of-deep-learning-backpropagation-e2aeb435727?source=collection_archive---------26-----------------------
从头开始反向传播的分步实践教程

劳伦·里奇蒙的照片
我现在已经研究深度学习有一段时间了,我成为了 PyTorch 或 TensorFlow 等当前深度学习框架的超级粉丝。然而,随着我越来越习惯这样简单但强大的工具,深度学习中核心概念的基础,如反向传播,开始淡出。我相信回到基础总是好的,我想做一个详细的实践教程来理清事情。
https://colab.research.google.com/drive/10sYc0tB2dw_jsw9D61SwliN1nqugyjP1?usp=sharing
介绍
深度学习的基本过程是使用学习到的权重执行网络定义的操作。比如著名的卷积神经网络(CNN)就是乘法、加法等。像素强度值具有由网络设计的这种规则。然后,如果我们想要分类图片是狗还是猫,我们应该以某种方式得到操作后的二进制结果,以告诉 1 是狗,0 是猫。
当我们训练网络时,我们只是简单地更新权重,以便输出结果变得更接近答案。换句话说,有了一个训练有素的网络,我们可以正确地将图像分类到它真正属于的类别。这就是反向传播的用武之地。我们计算梯度并逐步更新权重以满足目标。目标函数(又名损失函数)是我们如何量化答案和预测之间的差异。通过一个简单且可微的目标函数,我们可以很容易地找到全局最小值。然而,在大多数情况下,这并不是一个微不足道的过程。

图片来源维基百科
链式法则
没有链式法则,你就无法谈论反向传播。链规则使您能够以简单的方式计算局部梯度。

局部梯度的计算(费,2017)

反向传播的例子(费,2017)
这是一个简单的反向传播的例子。正如我们之前讨论的,输入数据是上面的 x 、 y 和 z 。圆形节点是操作,它们构成了功能 f 。由于我们需要知道每个输入变量对输出结果的影响,给定 x 、 y 或 z 的 f 的偏导数就是我们想要得到的梯度。然后,通过链规则,我们可以反向传播梯度,并获得每个局部梯度,如上图所示。

矢量化反向传播示例(费-李非,2017 年)
由于我们将在实际实现中进行更多的矢量化计算,这里有一个例子,函数 f 是 L2 范数。L2 范数的梯度正好是输入值的两倍,即上面的 2q 。那么,给定 W 的 q 的偏导数将是 2q 和 x 转置的内积。还有,同样给定的 x 会是 W 转置和 2q 的内积,而为什么 W 转置是因为 xᵢ 的每个偏导数都给定了 W 的列向量。
激活功能
在深度学习中,如果没有激活函数,层之间的一组线性操作终究只是一个大的线性函数。非线性激活函数进一步增加了模型的复杂性。我将介绍一个基本的激活函数及其导数,来计算我们反向传播的梯度。
乙状结肠的



双曲正切



整流线性单位



目标函数
在训练神经网络时,量化预测与答案的接近程度的有效方法是非常重要的。为了执行反向传播和更新影响输出预测的所有相关权重,需要可微分的目标函数(又名损失函数)。我将介绍两个目标函数,称为均方误差(MSE)和交叉熵损失函数。
均方误差
MSE 是当今最通用的损失项,常用于预测数值。它计算了预测和事实之间的平均平方距离。最终激活层通常遵循线性或 ReLU。

交叉熵
交叉熵通常用于从多个类别中预测单个标签。对于最终激活函数,它通常遵循 softmax,使得输出概率之和为 1,并且它提供了对损失项的非常简单的推导,如下所示。

反向传播

作者图片
对于如上所述的全连接网络,在反向传播中只需要考虑三件事。来自右侧的通过梯度,从激活函数的导数计算的局部梯度,以及关于权重和左侧输入的通过梯度。
第一个梯度来自损失项,通过如上所述的这些项的推导,我们可以开始从右向左传递梯度。从每一层,我们首先计算关于激活层的梯度。然后,该梯度与输入值(z’)的内积将是相对于我们的权重的梯度。此外,权重梯度的内积( w )将是下一个向左通过的梯度。
重复这个简单的过程是我们成功反向传播所需要的!
参考
[1]费-李非, CS231n:用于视觉识别的卷积神经网络,2017
[2] Stacey Ronaghan,深度学习:我应该使用哪些损失和激活函数?,2018
使用 Python 的 Matplotlib 的圆环图基础
原文:https://towardsdatascience.com/basics-of-donut-charts-with-pythons-matplotlib-100cf71b259d?source=collection_archive---------14-----------------------
使用 Matplotlib 绘制甜甜圈的不同方法快速指南
与饼状图有许多相似之处,这种创造性的可视化使其区别于其声名狼藉的表亲。开放的中心使切片看起来像条形,并将比较的焦点从面积和角度改变为长度。

甜甜圈和圆形进度条——作者图片
在本文中,我们将检查用 Matplolib 绘制环形图的两种方法。一种简单的方法是使用饼图和参数楔形图,另一种更复杂的方法是使用极轴和水平条形图。
图片兴趣探测调查
在 Matplotlib 中没有绘制环形图的方法,但是我们可以使用 wedgeprops 快速转换饼图。
让我们从一个简单的馅饼开始。
import matplotlib.pyplot as pltplt.pie([87,13], startangle=90, colors=['#5DADE2', '#515A5A'])plt.show()

饼图—作者图片
现在我们可以添加参数 wedgeprops 并定义边缘的宽度,其中一个意味着边界将一直延伸到中心。
fig, ax = plt.subplots(figsize=(6, 6))
ax.pie([87,13],
wedgeprops={'width':0.3},
startangle=90,
colors=['#5DADE2', '#515A5A'])plt.show()

甜甜圈——作者图片
这很简单。现在我们可以利用中心的空间让我们的数据更加明显。
fig, ax = plt.subplots(figsize=(6, 6))wedgeprops = {'width':0.3, 'edgecolor':'black', 'linewidth':3}ax.pie([87,13], wedgeprops=wedgeprops, startangle=90, colors=['#5DADE2', '#515A5A'])plt.title('Worldwide Access to Electricity', fontsize=24, loc='left')plt.text(0, 0, "87%", ha='center', va='center', fontsize=42)
plt.text(-1.2, -1.2, "Source: ourworldindata.org/energy-access", ha='left', va='center', fontsize=12)plt.show()

带细节的圆环图—图片由作者提供
当我们要显示简单的比较或比例时,圆环图特别有用。在我看来,使用它们的最佳方式就像一个圆形进度条,比如我们突出显示单一比例的例子。
在这些情况下,我们可以进一步简化图表。
fig, ax = plt.subplots(figsize=(6, 6))data = [87, 13]
wedgeprops = {'width':0.3, 'edgecolor':'black', 'lw':3}
patches, _ = ax.pie(data, wedgeprops=wedgeprops, startangle=90, colors=['#5DADE2', 'white'])patches[1].set_zorder(0)
patches[1].set_edgecolor('white')plt.title('Worldwide Access to Electricity', fontsize=24, loc='left')
plt.text(0, 0, f"{data[0]}%", ha='center', va='center', fontsize=42)
plt.text(-1.2, -1.3, "Source: ourworldindata.org/energy-access", ha='left', va='top', fontsize=12)plt.show()

圆形进度条—作者图片
酒吧
尽管这个解决方案比前一个更复杂,但它提供了一些令人兴奋的定制选项。
先说简单的。
from math import pifig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'projection':'polar'})data = 87
startangle = 90x = (data * pi *2)/ 100 # convert x data from percentage
left = (startangle * pi *2)/ 360 # convert start from angleax.barh(1, x, left=left, height=1, color='#5DADE2')
plt.ylim(-3, 3)plt.show()

极轴中的水平条-作者图片
你大概能明白为什么这更复杂了。
现在我们从角度出发。因此,我们必须在将每个元素添加到轴之前转换其 x 位置。
from math import pifig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'projection':'polar'})data = 87
startangle = 90x = (data * pi *2)/ 100
left = (startangle * pi *2)/ 360 #this is to control where the bar startsplt.xticks([])
plt.yticks([])
ax.spines.clear()ax.barh(1, x, left=left, height=1, color='#5DADE2')
plt.ylim(-3, 3)plt.text(0, -3, "87%", ha='center', va='center', fontsize=42)plt.show()

圆形进度条—作者图片
使用这种方法时,您有更多的选择;更容易添加多个进度条,定义它们之间的距离,并向可视化添加细节。
另一方面,文本的定位会变得很棘手。
from math import pi
import numpy as np
from matplotlib.patches import Patch
from matplotlib.lines import Line2Dfig, ax = plt.subplots(figsize=(6, 6))ax = plt.subplot(projection='polar')data = [82, 75, 91]
startangle = 90
colors = ['#4393E5', '#43BAE5', '#7AE6EA']xs = [(i * pi *2)/ 100 for i in data]
ys = [-0.2, 1, 2.2]
left = (startangle * pi *2)/ 360 #this is to control where the bar starts# plot bars and points at the end to make them round
for i, x in enumerate(xs):
ax.barh(ys[i], x, left=left, height=1, color=colors[i])
ax.scatter(x+left, ys[i], s=350, color=colors[i], zorder=2)
ax.scatter(left, ys[i], s=350, color=colors[i], zorder=2)
plt.ylim(-4, 4)# legend
legend_elements = [Line2D([0], [0], marker='o', color='w', label='Group A', markerfacecolor='#4393E5', markersize=10),
Line2D([0], [0], marker='o', color='w', label='Group B', markerfacecolor='#43BAE5', markersize=10),
Line2D([0], [0], marker='o', color='w', label='Group C', markerfacecolor='#7AE6EA', markersize=10)]
ax.legend(handles=legend_elements, loc='center', frameon=False)# clear ticks, grids, spines
plt.xticks([])
plt.yticks([])
ax.spines.clear()plt.show()

多个进度条—作者图片
楔形区的 width 属性是一个简单的参数,它可以使任何饼图更加激动人心,可读性更好。
有其他选项来绘制这种可视化效果也很棒。我看过另一个教程,他们展示了如何在饼图的中心画一个白色的圆圈,将它变成一个甜甜圈,这表明了如何通过数据可视化来获得创意。
感谢阅读我的文章!— 更多 Python DataViz 教程。
资源:
MPL 派;
MPL 楔形;
MPL 极坐标散点示例;
MPL Barh;
基于优化的元学习的少量学习基础
原文:https://towardsdatascience.com/basics-of-few-shot-learning-with-optimization-based-meta-learning-e6e9ffd4775a?source=collection_archive---------16-----------------------
基于优化的元学习中 MAML、FOMAML 和爬虫方法背后的机制概述

凯利·西克玛在 Unsplash 上的照片
元学习方法可以大致分为基于度量、基于优化和基于模型的方法。在这篇文章中,我们将主要关注基于优化的元学习方法背后的数学。
术语。元学习模型用元训练数据集(用一组任务 τ = { τ ₁、 τ ₂、 τ ₃、…})训练,用元测试数据集(任务 τₜₛ )测试。每个任务 τᵢ 由任务训练集(即支持集)dᵢᵗʳt21】和任务测试集(即查询集) Dᵢ ᵗˢ.组成元学习问题的一种类型是N-wayk-shot learning,其中我们在 N 个类之间进行选择,并利用每个类的 k 个示例进行学习。

双向单次示例的元训练、元测试、支持和查询数据集的图示。图片作者。
迁移学习(微调)
在继续讨论元学习之前,我们将简要提及另一种常用的方法——通过微调转移学习,以将知识从基础模型(例如,通过识别许多不同的对象构建)转移到新任务(例如,专门识别狗)。这里的想法是建立在一般任务上预先训练的模型,并在新的特定任务上微调该模型(通过仅更新神经网络中有限的层集合和/或以较慢的学习速率)。我们将在这一节复习数学术语,这样我们就可以与后面要讨论的元学习进行比较和对比。
在微调设置中,我们将首先导出在 D ᵖʳᵉ-ᵗʳ上预训练的一组优化的参数 θ ᵖʳᵉ-ᵗʳ,

在微调过程中,我们将调整使训练集 D ᵗʳ损失最小的参数,

该等式示出了一个梯度步骤,但是实际上这是通过多个梯度步骤来优化的。作为示例,下面显示了参数空间中从预训练参数值 θ ᵖʳᵉ-ᵗʳ到微调参数值 θ 的路径。

微调。图片作者。
在通过微调的迁移学习中,希望基础模型已经学习了基本模式(如形状、对比度、图像中的物体),微调可以更快更容易地适应新的任务。然而,这种方法并不是专门围绕着学习而设计的。新任务可能不会与基本任务重叠,从而导致知识的转移性能不佳。另一方面,元学习是明确围绕构建任务和算法进行设计的,以便进行一般化的学习。
MAML
模型不可知元学习(MAML)是由 Finn 等人在 2017 年提出的。这是一种基于优化的元学习方法。其思想是,我们不是寻找对给定的训练数据集或经过微调的训练集有用的参数,而是寻找经过微调后可推广到其他测试集的最佳参数。
为了一个任务。对于给定的任务,我们将首先在微调步骤中使用支持训练数据集 D ᵗʳ。 D ᵗʳ的最佳参数 ϕ 为,

不同于微调(我们将在此停止),我们想要计算这个最优参数 ϕ 在查询测试数据集 D ᵗˢ上的表现,损失函数为 L ( ϕ , D ᵗˢ).目标是优化初始参数 θ ,使其在给定微调的情况下在查询测试集上表现良好。换句话说,我们在元训练步骤中更新 θ ,

这里我们需要计算∇_θ L ( ϕ , D ᵗˢ),它是损失函数关于 θ 的导数。
我们可以如下说明参数空间中的路径,

MAML 负责一项任务。图片作者。
请注意,我们不是在微调步骤直接更新 θ ,而是根据支持训练和测试数据集(灰色路径)判断最佳参数的方向,并在元训练步骤中更新 θ 。
用于任务集。不仅仅是一个任务,为了对各种任务进行归纳,我们可以通过对一组任务进行平均来执行每一步的元学习 τ = { τ ₁, τ ₂, τ ₃,…}。因此支撑组任务 τᵢ 的最佳参数 ϕᵢ 为:

元训练步骤是,

术语∇_θl(ϕᵢ, Dᵢ ᵗˢ)$可以进一步展开。下面我们将省略下标 i ,但是这种讨论适用于每个任务。对于链式法则,该术语可以表示为:

我们可以扩展早期的路径视觉效果,以包含多项任务,

多重任务的 MAML。图片作者。
在这里,我们对每个任务的最佳参数的方向性有所了解(用不同的颜色),并根据任务的平均值更新 θ (黑色路径)。
一阶 MAML
在 MAML 元学习步骤中,我们需要计算海森矩阵。作为替代,在一阶 MAML (FOMAML)中,可以通过将∇_θl(θ, D ᵗʳ)视为常数并因此忽略二阶导数项来使用一阶近似。这意味着我们将项∇_ θ ϕ 视为单位矩阵 I ,从而得到:

这可以直观地说明如下,

一级 MAML。图片作者。
注意,我们不是通过在计算图中一路展开来执行元梯度计算,而是使用一阶近似∇_ϕt16】l(ϕ, D ᵗˢ)作为更新 θ 的梯度。
爬行动物
爬行动物(OpenAI)是一种替代方法,其性能与 MAML 相当,但在计算和存储方面比 MAML 更有效,因为没有二阶导数的显式计算。
首先,我们将引入一个更新函数 Uᵏ ,它只是 MAML 中微调步骤的一个重新表述(和推广),

其中 k 是 ϕ 更新的次数。
对于爬虫,在每次迭代中,1)任务 τᵢ 被采样,2)在 k 更新后,计算 τᵢ 的最优参数 ϕᵢ ,以及 3)模型参数 θ 被更新为:

不是每个迭代一个任务,而是可以评估多个任务,产生如下的批处理版本,

在哪里

参数路径可以被示意性地可视化为,

爬行动物。图片作者。
将爬行动物与不同任务间平均的规则随机梯度下降区分开来的关键区别是对 ϕᵢ 在kt60】1 步上的估计,并使用ϕᵢθ作为更新 θ 的梯度。在标准随机梯度下降中,在每个梯度步骤之后更新参数( U ,其中 k =1)。作者 Nichol 等人已经表明,当 k > 1 时,这允许算法拾取高阶导数,并且随之而来的行为类似于 MAML,并且与 k =1 时明显不同。
资源
- 芬恩(2020) CS330 讲座
- 快速前进研究(2020)元学习
- Ecoffet (2018)博客文章
- 【翁(2018)博文
- 尼科尔&舒尔曼(2018) OpenAI 博客文章
参考
- 模型不可知的元学习,用于深度网络的快速适应。 ICML 2017。 arXiv
- 一阶元学习算法。 arXiv 2018。 arXiv
原载于 2021 年 8 月 7 日https://boyangzhao . github . io。
马尔可夫链蒙特卡罗算法基础
原文:https://towardsdatascience.com/basics-of-markov-chain-monte-carlo-algorithms-a53a6b3a763d?source=collection_archive---------19-----------------------
这篇文章的目的是给马尔可夫链蒙特卡罗算法一个概念性的理解,以及我们为什么使用它们。
介绍
马尔可夫链蒙特卡罗是一组算法,用于通过从后验分布中取样来绘制后验分布。我们使用这种方法而不是二次近似方法的原因是,当我们遇到具有多个峰值的分布时,该算法可能会收敛到局部最大值,而不会给出后验分布的真实近似。然而,蒙特卡罗算法使用随机性和混沌理论的原理来解决问题,否则这些问题很难(如果不是不可能的话)通过分析来解决。
马尔科夫国王的类比
让我们用一个类比来开始这个讨论,我们可以在遍历不同类型的算法时更新这个类比。假设有 10 个岛屿以环形方式放置,并且有一个国王监管这些岛屿。马尔柯夫国王的受托人建议他,为了避免人民的反叛,他必须定期访问每个岛屿。条件是每个岛屿必须按人口比例参观。
岛的人口分布使得岛 10 的人口是岛 1 的 10 倍,岛 5 的人口是岛 1 的 5 倍,等等;因此,马尔科夫国王将停留在 10 号岛,比他停留在 1 号岛多 10 倍。Markov 国王的一位统计学家解释了一种方法,他可以用这种方法来计划他对这些岛屿的访问,并让他的人民高兴。方法是:
第一步:每周,Markov 王在移动到下一个岛或留在当前岛之间做出决定。
第二步:他抛硬币。如果硬币正面朝上,马尔科夫国王考虑以顺时针方向移动到下一个岛。如果硬币落在一个反面,国王马尔可夫考虑以逆时针方向移动到下一个岛。让我们把这个岛叫做求婚岛。
第三步:如果求婚岛的人口比当前岛的人口多,马尔科夫国王总是接受求婚,并移动到求婚岛。如果提议岛屿的人口少于当前岛屿的人口,那么他以population_proposal/population_current的概率接受提议。因为这是一个概率,这也可能导致国王马尔科夫根本不动,拒绝建议。
下面给出了模拟这种情况的代码。随着周数的增加,你肯定会发现在岛上度过的周数与岛上的相对人口数成正比。
num_weeks <- 1e4
positions <- rep(0,num_weeks)
current<-10
for(i in 1:num_weeks){
##record current position
positions[i] <- current
##flip coin to generate a proposal
proposal <- current + sample(c(-1,1), size = 1)
##This is just to make sure that proposal remains between 1 and 10
if(proposal < 1) proposal <- 10
if(proposal >10) proposal <- 1
#move?
prob_move <- proposal/current
current <- ifelse(runif(1)<prob_move, proposal, current)
}
barplot(prop.table(table(positions)), ylim = c(0,0.2))

在上面给出的代码块中,随着周数的增加,条形图给出了一个稳定增加的分布,说明了每个岛屿的访问量与其人口规模成比例—(图片由作者提供)
大都会算法
这种算法被称为 Metropolis 算法。这是最简单的算法,属于马尔可夫链蒙特卡罗算法类。此外还有 Metropolis-Hastings 算法。
这两种算法的唯一不同之处在于,Metropolis 算法只是随机遍历负对数后验分布,而 Metropolis-Hastings 算法则提出了一个更加合理的建议。这可以参考它的数学这里更详细地理解。
让我们试着把这里的点点滴滴联系起来;你在后验分布上选择一个估计的起点。这是国王旅行开始时所在的岛屿。您生成一个随机数,建议点应该移动的方向。计算建议点和当前点的密度。如果建议点具有比当前更高的后验密度,则移动到建议点。如果它的密度较低,你以density_proposal/density_current的概率移动到提议点。
所以一旦你一遍又一遍地这样做,你最终总会走向后防线的顶峰。沿途采集的样本有助于估计后验分布的形状。
我们使用这种算法的原因是,从后验样本中提取样本来告知我们后验的可能形状,因为如果我们试图找到后验的方程,然后试图优化它,我们将不得不求解一个非常复杂的积分。有时,这些积分甚至是不可解的,这就是为什么从最高密度区域采样给了我们一个更快更精确的关于后验形状的估计。
蒙特国王的类比
让我们假设 Markov 国王有一个叫 King Monte 的兄弟,他监管着边缘陡峭而中间平坦的山谷。为了方便起见,我们假设山谷的形状像一个碗,山谷中的人口分布与地形的陡度成反比。简单来说,在山谷陡峭的边缘周围,人口较低,在山谷平坦的中心周围,人口较高。蒙特国王被告知,就像马尔柯夫国王一样,为了避免他的人民叛变,他必须按照人口密度的比例访问山谷。这个问题比上一个问题稍微复杂一点。与金·马尔科夫的问题不同,我们在这里面对的是一大片连续的待开发土地。国王蒙特坐进他的车,在某个随机的方向上给了他的车一些随机的冲力。当汽车开始上坡时,它的动能开始转化为势能,直到汽车停下来掉头,并向中心移动。在一些预定的时间间隔,国王蒙特停下他的车,会见他所在地区的人;这个过程一遍又一遍地重复。从长远来看,国王蒙特将总是更多地访问人口较高的地区,因为重力将总是迫使他向中心而不是边缘。
让我们试着分析这是如何适用于确定后的形状。到目前为止,我们已经理解,计算后验概率的精确解在计算上过于昂贵;然而,我们能够计算任何单点的概率密度。我们还可以计算任意给定点的后验斜率。这其中的数学可以在这里找到。因此,该算法基本上运行一个动态模拟,接近准确的国王蒙特的汽车如何表现。唯一的区别是,我们的观点是在一个无摩擦的平原上前进。在开始模拟之前,我们还必须定义两件事情。一个是点在停止前应该走的步数,我们称之为跳步、,第二个是步长。这个点以随机的动量被弹向随机的方向。评估下一步的梯度和密度,并考虑能量因素。在我们完成所有的蛙跳步骤后,该点停止并采样其在后部的当前位置。代码可以在这里找到。下图显示了 5 个样本点的路径。

该图显示了马尔可夫链在 HMC 算法中的轨迹。每个点的方向和动量都是随机的。一旦我们增加样本的数量,链将总是从更接近(0,0)的区域中采样更多的样本
哈密顿蒙特卡罗
汉密尔顿并没有创造这个算法,虽然他确实对现代动力学贡献很大。由于 HMC 使用了动力学和能量守恒的原理,毫不夸张地说,达到了后验的顶峰,这种算法就以他的名字命名了。HMC 如此受欢迎的原因是因为与 Metropolis 或 Metropolis-Hastings 算法不同,该提议被拒绝的几率非常低。其原因是,下一个采样点是由一长串事件决定的,这些事件几乎总是导致下一个样本具有比当前样本更大的后验密度。唯一一次提案被拒绝是当系统的能量不守恒时,这通常发生在我们对提案密度的数值近似不好的时候。
然而,使用 HMC 的最大原因不是这个。由于参数数量较少,大都市和 HMC 的工作方式非常相似。HMC 总是更有效率,但结果是一样的。随着你向更高维度移动,后验模式离大多数概率质量存在的地方越来越远。很难想象超过 3 个维度,所以这样想。当参数的数量相对较少时,比如 3,后验模型会给出一个很好的近似值,来表示大部分概率质量的位置。当你有 1000 个参数时,分布的形状变得越来越像一个甜甜圈,大部分的概率质量离模式越远。
这导致 Metropolis 算法比 HMC 算法更频繁地拒绝提案,因此需要更多的时间来收敛。下面显示的图表对此给出了更多的含义。

每个密度上面的数字是维度的数量。随着参数数量的增加,模式离我们想要采样的值越来越远—(图片由作者提供)
摘要
在本文中,我们通过两个流行的 MCMC 方法来从概念上理解它们。在以后的文章中,我将介绍它们在 R 和 Stan 中的实现。本文中用于生成图表和模拟数据的所有代码都可以在这里找到。

照片由丹尼尔·利维斯·佩鲁西在 Unsplash 上拍摄
参考
[1] Richard McElreath,R 和 Stan(2020)【T0【2】斯蒂芬妮·格伦 用实例进行统计再思考。StatisticsHowTo.com中的“Metropolis-Hastings 算法/ Metropolis 算法”:对于我们其他人来说是基本的统计数据!https://www . statistics show to . com/metropolis-Hastings-algorithm/
【3】科林·卡罗尔,https://colind Carroll . com/2019/04/11/哈密顿-蒙特卡罗-从头开始/
基于 Python 的 Matplotlib 的 OHLC 海图基础
原文:https://towardsdatascience.com/basics-of-ohlc-charts-with-pythons-matplotlib-56d0e745a5be?source=collection_archive---------10-----------------------
如何绘制股票分析的基本图表的快速指南

OHLC 图表与卷-图片由作者
历史可以追溯到 18 世纪,开盘-盘高-盘低-收盘(OHLC)图是最受欢迎的金融分析工具之一,通常用于说明股票价格随时间的变化。
在本文中,我们将了解如何使用 Matplotlib 从头开始构建 OHLC 图表,探索这种可视化的优势和局限性,并了解使用 mplfinance 的更直接的方法。
OHLC 图表是如何工作的?
图表由一系列垂直线组成,这些垂直线包含了价格的四个关键变量;一段时间内的最小值、最大值、初始值和结束值,通常以小时、天或周为单位。

OHLC——作者的形象
和蜡烛图有什么区别?
OHLC 与蜡烛图非常相似,因为它们都显示相同的信息,并用于说明一段时间内的价格。通常指股票、货币、债券、商品等。


OHLC 和烛台图表——作者图片
它们在显示数据的方式上略有不同;OHLC 开盘价总是在棍子的左边,收盘价在右边。
烛台的左右两边都没有标记。他们有一个盒子。
盒子的填充代表价格的方向。通常,实心或红色方框意味着价格下跌(熊市),因此开盘价是矩形的顶部。
空的或绿色的方框表示相反的情况(牛市),方框的顶部是收盘价。

烛台——来自 Investopedia
Matplotlib
让我们开始构建我们的 OHLC 图表。首先,我们将导入所需的库。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import math
本例中的数据来自名为 S & P 500 股票数据的 Kaggle 数据集。
df = pd.read_csv('../data/all_stocks_5yr.csv')
df.head()

数据框的前五行-作者提供的图片
这是一个庞大的数据集,我们不会一次绘制所有这些数据,所以在开始之前,让我们选择一个较小的子集。
# filter Apple stocks
df_apple = df[df['Name'] == 'AAPL'].copy()# convert date column from string to date
df_apple['date'] = pd.to_datetime(df_apple['date']) # filter records after 2017
df_apple = df_apple[df_apple['date'].dt.year > 2017] df_apple.reset_index(inplace=True)
现在让我们画出树枝。它们应该从最低价格延伸到最高价格。
我们将为它创建一个 NumPy 数组,而不是使用日期作为 x。该数组的长度将从 0 变为数据帧的长度。操纵数字序列更容易,这将有助于定位棒和开盘价/收盘价的标记。
为了画线,我们将遍历数据框,为每条数据记录绘制一条线。
x = np.arange(0,len(df_apple))
fig, ax = plt.subplots(1, figsize=(12,6))for idx, val in df_apple.iterrows():
plt.plot([x[idx], x[idx]], [val['low'], val['high']])plt.show()

矩形中的彩虹线——作者图片
太棒了,现在我们可以添加标记了。
x = np.arange(0,len(df_apple))
fig, ax = plt.subplots(1, figsize=(12,6))for idx, val in df_apple.iterrows():
# high/low lines
plt.plot([x[idx], x[idx]],
[val['low'], val['high']],
color='black')
**# open marker
plt.plot([x[idx], x[idx]-0.1],
[val['open'], val['open']],
color='black')
# close marker
plt.plot([x[idx], x[idx]+0.1],
[val['close'], val['close']],
color='black')**plt.show()

OHLC 海图—图片由作者提供
在那里!用 Matplotlib 绘制 OHLC 图表非常容易。与烛台不同,你不需要颜色或符号中的不同填充物来理解可视化。
最简单的形式,这个图表是可读的和相对简单的。
颜色;色彩;色调
它们不是必须的,但是可以把我们的视觉带到另一个层次。
我们将在循环的开始添加一个绿色的变量;然后我们将添加一个条件来检查开盘价是否高于收盘价;为真时,我们将颜色改为红色。
x = np.arange(0,len(df_apple))
fig, ax = plt.subplots(1, figsize=(12,6))for idx, val in df_apple.iterrows():
**color = '#2CA453'
if val['open'] > val['close']: color= '#F04730'**
plt.plot([x[idx], x[idx]],
[val['low'], val['high']],
**color=color**)
plt.plot([x[idx], x[idx]-0.1],
[val['open'], val['open']],
**color=color**)
plt.plot([x[idx], x[idx]+0.1],
[val['close'], val['close']],
**color=color**)plt.show()

彩色编码的 OHLC 海图——图片由作者提供
给我们的 OHLC 图表添加颜色使得过去的趋势更加明显,我们的可视化更加有洞察力。
一会儿
我们的可视化看起来已经很棒了,但是 x 轴已经没用了。
使用一个数字序列作为我们的 x 有助于画线和标记,但我们不能像这样告诉日期。
我们将使用 x 来定位我们的记号,并将日期作为标签。我们还需要考虑,如果我们打印每个日期,我们的 x 轴将是不可读的,所以我们将在绘图时跳过一些值。
x = np.arange(0,len(df_apple))
fig, ax = plt.subplots(1, figsize=(12,6))for idx, val in df_apple.iterrows():
color = '#2CA453'
if val['open'] > val['close']: color= '#F04730'
plt.plot([x[idx], x[idx]],
[val['low'], val['high']],
color=color)
plt.plot([x[idx], x[idx]-0.1],
[val['open'], val['open']],
color=color)
plt.plot([x[idx], x[idx]+0.1],
[val['close'], val['close']],
color=color)
# ticks
plt.xticks(x[::3], df_apple.date.dt.date[::3])plt.show()

带有正确 x 轴的 OHLC 图表—作者图片
太好了!现在我们可以给我们的可视化添加一些样式,使它更有吸引力。
x = np.arange(0,len(df_apple))
fig, ax = plt.subplots(1, figsize=(12,6))for idx, val in df_apple.iterrows():
color = '#2CA453'
if val['open'] > val['close']: color= '#F04730'
plt.plot([x[idx], x[idx]], [val['low'], val['high']], color=color)
plt.plot([x[idx], x[idx]-0.1], [val['open'], val['open']], color=color)
plt.plot([x[idx], x[idx]+0.1], [val['close'], val['close']], color=color)
# ticks
plt.xticks(x[::3], df_apple.date.dt.date[::3])
ax.set_xticks(x, minor=True)# labels
plt.ylabel('USD')# grid
ax.xaxis.grid(color='black', linestyle='dashed', which='both', alpha=0.1)# remove spines
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)# title
plt.title('Apple Stock Price', loc='left', fontsize=20)
plt.show()

带细节的 OHLC 图表—图片由作者提供
OHLC 图表是一个很好的分析起点,因为它给了我们一个很好的概述,我们可以在此基础上进行分析。
改进和定制
您可以绘制一些预测价格、置信区间、移动平均线、交易量和更多的变量和统计数据来补充您的可视化。
用 Matplotlib 从头开始构建我们的可视化给了我们很多自由。
x = np.arange(0,len(df_apple))
fig, (ax, ax2) = plt.subplots(2, figsize=(12,8), gridspec_kw={'height_ratios': [4, 1]})for idx, val in df_apple.iterrows():
color = '#2CA453'
if val['open'] > val['close']: color= '#F04730'
ax.plot([x[idx], x[idx]], [val['low'], val['high']], color=color)
ax.plot([x[idx], x[idx]-0.1], [val['open'], val['open']], color=color)
ax.plot([x[idx], x[idx]+0.1], [val['close'], val['close']], color=color)
# ticks top plot
ax2.set_xticks(x[::3])
ax2.set_xticklabels(df_apple.date.dt.date[::3])
ax.set_xticks(x, minor=True)# labels
ax.set_ylabel('USD')
ax2.set_ylabel('Volume')# grid
ax.xaxis.grid(color='black', linestyle='dashed', which='both', alpha=0.1)
ax2.set_axisbelow(True)
ax2.yaxis.grid(color='black', linestyle='dashed', which='both', alpha=0.1)# remove spines
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)# plot volume
ax2.bar(x, df_apple['volume'], color='lightgrey')
# get max volume + 10%
mx = df_apple['volume'].max()*1.1
# define tick locations - 0 to max in 4 steps
yticks_ax2 = np.arange(0, mx+1, mx/4)
# create labels for ticks. Replace 1.000.000 by 'mi'
yticks_labels_ax2 = ['{:.2f} mi'.format(i/1000000) for i in yticks_ax2]
ax2.yaxis.tick_right() # Move ticks to the left side
# plot y ticks / skip first and last values (0 and max)
plt.yticks(yticks_ax2[1:-1], yticks_labels_ax2[1:-1])
plt.ylim(0,mx)
# title
ax.set_title('Apple Stock Price\n', loc='left', fontsize=20)
# no spacing between the subplots
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

OHLC 图表与卷-图片由作者
Matplotlib 金融
在文章的开头,我提到了一种绘制 OHLC 图表的更简单的方法。mplfinance 是一个优秀的财务可视化工具包。
pip install --upgrade mplfinance
让我们来看看它有多容易使用。
数据框应包含以下字段:开盘、收盘、盘高、盘低和成交量。它还应该有一个日期时间索引。
我们的数据有适当的字段,所以我们只需要改变索引。
import mplfinance as mpfdf_google = df[df['Name'] == 'GOOGL'].copy()
df_google['date'] = pd.to_datetime(df_google['date'])
df_google = df_google[df_google['date'] > pd.to_datetime('2017-12-31')]
df_google = df_google.set_index('date')mpf.plot(df_google)

OHLC 海图—图片由作者提供
就这样,我们有了 OHLC 图表!
我们还可以添加移动平均线,并用一行代码可视化体积。
mpf.plot(df_google,type='candle',mav=(3, 5),volume=True, title='Google')

带移动平均线和成交量的 OHLC 图表——图片由作者提供
Matplotlib 财务实用程序比从头开始绘制图表更容易使用,但它们不容易定制。
对于大多数快速分析,您需要一个功能性和可读性强的图表,而 mplfinance 就足够了。
对于其他更具体的约束,当您需要向可视化中添加特定的组件或者定制样式以遵循一些设计标准时,mplfinance 可能会有所欠缺。
在这些情况下,使用 Matplotlib 从头开始绘制图表是值得的。我们可以很容易地添加、修改或删除可视化的任何部分,使它成为一个很好的工具。
感谢阅读我的文章。我希望你喜欢它!
查看更多 Python DataViz 教程。
推荐人:
mpl finance;
mplfinance —样式和定制;
Matplotlib —子情节 grid spec;
Matplotlib —x 坐标, y 坐标;
Matplotlib —右勾;
Matplotlib —棘;
Matplotlib —网格线、W3;
Matplotlib—Lines;
Matplotlib—Bars;
Python 生成器的基础
原文:https://towardsdatascience.com/basics-of-python-generators-a47b3cab1a23?source=collection_archive---------7-----------------------
了解生成器的基础知识并在 Python 中实现它们

博伊图梅洛·菲特拉在 Unsplash 上的照片
什么是 Python 生成器?
Python 生成器函数允许您声明一个行为类似迭代器的函数,允许程序员以一种快速、简单和干净的方式创建迭代器。迭代器是一个可以被迭代或循环的对象。它用于抽象数据容器,使其行为像一个可迭代的对象。更常用的可迭代对象的例子包括列表、字典和字符串。
在本文中,我们将借助一些例子学习在 Python 中创建和使用生成器。
用 Python 实现的简单类迭代器
让我们首先看一个简单的基于类的迭代器来产生奇数:
class get_odds:
def __init__(self, max):
self.n=3
self.max=max
def __iter__(self):
return self
def __next__(self):
if self.n <= self.max:
result = self.n
self.n += 2
return result
else:
raise StopIterationnumbers = get_odds(10)
print(next(numbers))
print(next(numbers))
print(next(numbers))# Output
3
5
7
如你所见,生成了一系列奇数。为了生成这个结果,我们在 get_odds 类中创建了一个自定义迭代器。对于要成为迭代器的对象,它应该实现将返回迭代器对象的 iter 方法,然后 next 方法将返回序列中的下一个值,并可能在没有值要返回时引发 StopIteration 异常。如你所见,创建迭代器的过程是漫长的,这就是我们求助于生成器的原因。同样,python 生成器是实现迭代器的一种简单方式。
生成器函数和常规函数的区别
常规函数和生成器函数之间的主要区别在于,生成器函数的状态是通过使用关键字 yield 来维护的,其工作方式非常类似于使用 return,但它有一些重要的区别。区别在于 yield 保存了函数的状态。下一次调用该函数时,将从停止的地方继续执行,使用让步前的变量值,而 return 语句将完全终止该函数。另一个区别是生成器函数甚至不运行函数,它只创建并返回一个生成器对象。最后,只有在生成器对象上调用 next() 时,生成器函数中的代码才会执行。
Python 中的生成器实现
让我们使用前面的代码实现相同的迭代器,只是使用了 python 生成器。
def get_odds_generator():
n=1
n+=2
yield n
n+=2
yield n
n+=2
yield n
numbers=get_odds_generator()
print(next(numbers))
print(next(numbers))
print(next(numbers))# Output
3
5
7
上面我首先创建了一个生成器函数,它有三个 yield 语句,当我们调用这个函数时,它返回一个迭代器对象的生成器。然后我们调用 next() 方法从这个对象中检索元素。第一个 print 语句给出了第一个 yield 语句的值 3,第二个 print 语句给出了第二个 yield 语句的值 5,最后一个 print 语句给出了第三个 yield 语句的值 7。如您所见,与我们基于类的迭代器相比,生成器函数要简单得多。
现在让我们尝试实现一个循环,让这个 python 生成器返回奇数,直到某个最大数。
def get_odds_generator(max):
n=1
while n<=max:
yield n
n+=2
numbers=get_odds_generator(3)
print(next(numbers))
print(next(numbers))
print(next(numbers))

作者图片
从输出中可以看到,生成了 1 和 3,之后引发了 StopIteration 异常。循环条件(n <=max) is False since max is 3 and n is 5, therefore the StopIteration exception was raised.
When comparing this code with our get_odds class, you can see that in our generator we never explicitly defined the iter method, the next method, or raised a StopIteration exception — these are handled implicitly by generators, making programming much easier and simpler to understand!
Iterators and generators are typically used to handle a large stream of data theoretically even an infinite stream of data. These large streams of data cannot be stored in memory at once, to handle this we can use generators to handle only one item at a time. Next, we will build a generator to produce an infinite stream of Fibonacci numbers. Fibonacci numbers are a series of numbers where the next element is the sum of the previous two elements.
def fibonacci_generator():
n1=0
n2=1
while True:
yield n1
n1, n2 = n2, n1 + n2sequence= fibonacci_generator()
print(next(sequence))
print(next(sequence))
print(next(sequence))
print(next(sequence))
print(next(sequence))# Output
0
1
1
2
3
As you can see from the code above, in defining the fibonacci_generator function, I first created the first two elements of the fibonacci series, then used an infinite while loop and inside it yield the value of n1 and then update the values so that the next term will be the sum of the previous two terms with the line n1,n2=n2,n1+n2. Our print statements gives us the sequence of numbers in the fibonacci sequence. If we had used a for loop and a list to store this infinite series, we would have run out of memory, however with generators we can keep accessing these terms for as long as we want since we are dealing with one item at a time.
Summary
From this article, we have covered the basics of python generators. By the way, we can also create generators on the fly using generator expressions, which you can read more about in this article by Richmond Alake. Thank you for reading and all code is available on my Github%20Generators.ipynb) 😃
推荐系统基础
原文:https://towardsdatascience.com/basics-of-recommender-systems-6f0fba58d8a?source=collection_archive---------13-----------------------
用户相似性,项目相似性,协同过滤,基于内容的模型,潜在空间模型

来自 Pixabay
推荐系统主动向用户推荐相关项目。当宜。“主动”意味着这些项目只是出现——用户不需要搜索它们,甚至不需要意识到它们的存在。“相关”意味着当用户出现时,他们倾向于参与。“与他们接触”的确切含义取决于上下文。对于电影来说,engage 可能意味着看;对于产品购买。“适当的时候”是关键,这也是“智能”的来源。
让我们看几个例子。
- 你在线观看电影、节目和视频。推荐系统被动地观察你的互动。你看什么,你什么时候看,你看某个项目多长。它会推荐其他它认为你会喜欢的视频。如果您正在使用遥控器观看电视,这将非常方便。在这种情况下,浏览(个性化)产品比搜索更方便。
- 你在电子商务网站浏览或购买商品。一个推荐系统监视你的一举一动。和其他买家的信息。然后推荐新的项目给你考虑。
协同过滤
想象你在你的网站上销售商品。很多项目,比如 1000 个。您将购买数据保存在数据库中。你的数据库跟踪购买时间、用户标识、物品标识和数量。用户用户标识在时间购买时间购买数量物品物品标识的实例。
让我们看一个来自虚构数据库的数据示例,总结如下。我们忽略了购买时间。我们已经把其余的数据排列成一个矩阵。行索引用户。列索引项目。
***I1 I2 I3 I4**
**U1** 4 0 5 0
**U2** 6 1 7 0
**U3** 0 0 0 1
**U4** 0 0 1 1
**U5** 3 0 4 0*
在这个数据中,我们有五个用户 U1 到 U5,四个项目 I1 到 I4。Cell (U,I)跟踪用户 U 购买商品 I 的次数(到目前为止)。例如,U1 四次购买 I1。
超出购买频率
虽然在该数据单元(U,I)中记录了用户 U 购买项目 I 的次数,但是更一般地,该单元可以记录我们认为合理地跟踪用户 U 对项目 I 的密切关系的任何数字,例如从 1 到 5 的评级。在评价设置中,许多单元格没有值,因为不是每个用户都对每个项目进行评价。事实上,人们会认为评级矩阵中的大多数单元格都有空值。
我们能从这些数据中挖掘出什么?
在这个例子中,我们可以推断用户 U1 和 U5 是相似的。这是因为他们购买相同物品的次数大致相同。我们从下面的行向量中可以看到这一点。
***U1** 4 0 5 0
**U5** 3 0 4 0*
因此,通过比较矩阵的行向量,我们可以推断出用户之间的相似关系。
现在我们来比较列向量。我们可以推断 I1 和 I3 是相似的。它们被相同的用户购买了大致相同的次数。
*I1 I3
4 5
6 7
0 0
0 1
3 4*
因此,通过比较矩阵的列向量,我们可以推断出项目之间的相似关系。
这是协同过滤的关键点:仅从交易数据我们就可以推断出用户之间的相似关系和项目之间的相似关系。
购物篮
回想一下,我们在前面的部分中描述的矩阵,即从交易中构建的矩阵,是从四元组得到的(购买时间、用户 id* 、物品 id 、数量)。这样的四倍代表个人购买。这就丢失了一条关键信息:哪些商品是在同一次交易中一起购买的,即在同一个购物车中。该信息对于根据“购买了 A 的人也购买了 B”范例操作的某些类型的推荐系统非常有用。当我们谈到这个话题时,我们会更详细地讨论。目前,我们只是把它浮出水面。*
新用户,新物品
一个新用户没有任何交易历史,所以我们无法找到邻居。同样,一个新项目没有任何购买,所以我们无法找到它的邻居。因此,依赖用户邻居的算法对新用户无效,而依赖项目邻居的算法对新项目无效。
我们现在提出这些问题,以便在这篇文章的后面,我们可以看到各种算法如何处理它们。
内容
现在假设,除了交易数据,我们还有描述商品和用户的数据。我们将其称为内容。项目可能有描述、标签、名称、产品品牌、产品类别、价格等。(产品类别的示例有服装、电子产品、家用、…)某些属性可能取决于类别。如智能手机的存储容量和相机分辨率,服装的面料类型。
用户可以选择提供关于他们自己的附加信息。如性别和年龄。甚至可能是价格偏好、喜欢的产品等。
现在我们有了额外的数据,可以帮助我们推断项目之间的相似关系。事实上,甚至可能是比相似性更微妙的关系。比如一个 iPhone 充电器是一个 iPhone 的配件。
内容也可以帮助新用户或新项目。
对用户项目矩阵的第二次传递
在我们已经看到的用户商品矩阵中,单元格(U,I)记录了用户 U 购买商品 I 的次数(到目前为止)。考虑一个值为 0 的单元格(U,I)。我们想区分两种情况:
- 用户 U 知道商品 I,并选择不购买它。
- 用户 U 甚至可能不知道项目 I 的存在。
为什么要区分这两者?第一种情况,我们知道用户不想要 I,所以不应该推荐。
我们可以收集什么样的证据来证明用户有机会查看某个特定的项目。我们可以跟踪这个项目在过去被推荐给用户的次数。我们还可以跟踪用户最终访问项目页面的次数。从搜索开始,或者通过电子商务网站上的导航链接浏览。
代替推荐跟踪购买计数的用户项目矩阵,或者除此之外,我们可以考虑推荐跟踪评级的用户项目矩阵。比方说,这个电子商务网站让用户给商品打分,从 1 到 5。我们到目前为止介绍的概念,加上我们将很快介绍的概念,也适用于这种矩阵。简单地说,只要我们能从两个用户的行向量中量化他们有多相似,或者从他们的列向量中量化两个项目有多相似,我们就很好。事实上,我们甚至不需要能够计算两种类型的相似性。只有用户对用户或项目对项目可能就足够了。见下文。
使用评级代替计数有以下好处。评级是用户对项目好坏的明确反馈。此外,如果单元格的用户没有对单元格的项目进行评级,则评级矩阵中的单元格可以被明确标记为“未评级”。
另一方面,通常来说,评价商品的用户比购买商品的用户少得多。因此,对于相同的用户和商品,用户商品评级矩阵往往比用户商品购买频率矩阵稀疏得多。
总之,评级矩阵具有潜在的更原始的信号(评级),但是它的稀疏性可能抵消一些(或全部)这种优势。
在这篇文章中,我们不会对哪个更好采取立场。通常,如果两种类型的数据都可用,那么在推荐系统中使用购买频率和评级是有意义的。
推荐问题
现在让我们为推荐的实际问题做准备。我们有一个用户 u 和她最近的购买(或其他交互)。我们还拥有所有用户和所有商品的历史交易数据。我们还可能有关于项目和用户的附加内容。
使用所有这些信息,我们将向用户 u 推荐我们认为她会喜欢的商品。
一种方法是先找一些和 u 足够相似的用户,叫他们 v1,…,vk。在纯协同过滤中,这些用户可以通过比较各个用户的行向量与 u's 来发现。然后,我们向你推荐出现在他们的用户向量中的合适的项目。(我们将在后面详述“合适的”。)这叫做基于用户的协同过滤。我们向你推荐基于相似用户口味的商品。
如果条目有可用的内容,我们可以考虑将它们的属性维添加到条目向量中,或者替换它们。所以现在和以前一样,相似的行向量对应相似的用户。这一次,我们将同时考虑交易模式和商品内容。
让我们用一个简单的例子来说明这一点。我们将维度设为
***iPhone6 iPihone7 iPhone8 iPhone10 iPhone12 Brand=Apple Product Family=iPhone***
下面我们在这些维度上看到两个用户向量。
***U1** 1 0 1 0 1 3 3
**U2** 0 1 0 1 0 3 3*
把 iPhone6 到 iPhone12 想象成特定的物品,它们的品牌和产品系列就是内容。尽管 U1 和 U2 没有共同购买的物品,但是内容特征揭示了他们购买的相似性。
人们通常表现出品牌忠诚度。例如,iPhone 用户可能倾向于继续购买(最新的)iPhone。正如我们在上面的例子中所看到的,基于内容的建模可以显示这种趋势,从而提供更好的推荐。简单来说,在观察到某个用户一直在购买较新版本的 iPhone 后,就可以期望向该用户推荐最新的 iPhone 型号。
找到其行向量与特定用户的行向量相似的用户的先决条件是能够定量地比较两个行向量。我们先讨论这个。然后我们将回来讨论建立在此基础上的推荐算法。
测量行向量之间的相似度
有许多方法可以量化两个向量有多相似。不同的方法产生不同的结果。出于这个原因,我们将讨论其中的几个,并检查它们不同的行为。这将有助于读者了解何时使用哪一种。为了便于说明,我们将使用来自推荐设置的示例。
在开始之前,提醒一下用户项矩阵中的一些单元格可能缺少值。考虑一个评级矩阵。并非所有用户和项目的组合都有评级,事实上,很可能没有。很多用户从来懒得给任何东西打分!
在应用下面给出的相似性度量之前,我们将丢弃两个向量中缺少一个或另一个向量值的任何分量。所以下面描述的度量适用于没有丢失值的向量。
好了,我们开始吧。我们的第一个是
点积
这将两个向量按分量相乘,然后对结果项求和。考虑我们前面介绍的例子,为了简洁起见,省略了特性名称。
例 1 : 物品特性的效果
***U1** 1 0 1 0 1 3 3
**U2** 0 1 0 1 0 3 3*
点积是 1 * 0+0 * 1+1 * 0+0 * 1+1 * 0+3 * 3+3 * 3。最后两项用粗体表示,使得点积非常正。因此,我们认为 U1 和 U2 非常相似。在我们的场景中,这是有意义的,因为向量的最后两个组件分别代表品牌和产品系列。由于 U1 和 U2 多次偏向同一品牌和同一产品系列,认为它们相似是有道理的。
现在考虑一个不同的例子。
例 2 : 购买次数与购买与否
***U1** 10 2 3 1
**U2** 3 2 3 1
**U3** 9 0 0 0*
在这种情况下,四个维度代表不同的项目,只能通过标识符(如 SKU 或条形码)来识别。
{U1,U3}的点积比{U1,U2}的点积更正。因此,前一对具有更高的相似性得分。人们可以认为相似性得分应该颠倒。这是因为 U1 和 U2 购买的物品的集合是相同的,而 U3 丢失了 U1 购买的 4 件物品中的 3 件。这真正让我们思考的是,购买数量相对于所购商品的身份有多重要。
缓解这个问题的一个方法是在应用点积之前适当地预处理数据。例如,我们可以将所有正数转换为 1。也就是说,我们只是跟踪某个特定用户是否购买了某件商品。
三个向量的预处理版本变成
***U1** 1 1 1 1
**U2** 1 1 1 1
**U3** 1 0 0 0*
现在,在这种情况下,点积的行为符合预期。
我们正在失去信息。在其他情况下,我们可能会为此付出代价。其实下面这个。
例 3 : 采购盘点事项
***U1** 9 1 2
**U2** 9 1 2
**U3** 1 1 1*
这些向量的二进制版本上的点积将失去辨别 U2 比 U3 更类似于 U1 的能力。
居中点积
好吧,让我们试试不同的方法。让我们将矢量居中而不是二值化它们。将向量居中会从每个分量中减去向量的平均值。这在例 3 中有帮助吗?让我们看看。
首先,我们将复制示例 3,添加一列记录相应行向量的平均值。(本栏为黑体字。)
***U1** 9 1 2 **4
U2** 9 1 2 **4
U3** 1 1 1 **1***
因此,示例 3 中的居中版本的载体是
***U1c** 5 -3 -2
**U2c** 5 -3 -2
**U3c** 0 0 0*
作为健全性检查,我们可以看到上面的每个行向量的总和为 0。这是必须的。
嗯,确实有帮助!U1c 和 U2c 的点积非常正,而 U1c 和 U3c 的点积为 0。
为什么会这样?实际上,居中显示了向量中值的相对差异。点产品能够有效地利用这些相对差异。也就是说,首先居中,然后取点积,这是两个向量协方差的一个很好的度量。
那么这在示例 2 中有效吗?让我们看看。首先,让我们复制下面的例子,像前面一样,添加一列相应行向量的平均值。
***U1** 10 2 3 1 **4
U2** 3 2 3 1 **9/4
U3** 9 0 0 0 **9/4***
居中的版本是
***U1c** 6 -2 -1 -3
**U2c** 3–9/4 2–9/4 3–9/4 1–9/4
**U3c** 9–9/4 -9/4 -9/4 -9/4*
和以前一样,健全性检查显示每行总和为 0。
在这种情况下,居中(单独)没有帮助。{U3c,U1c}的点积还是大于{U2c,U1c}的点积。
潜在的问题是,在我们的设置中,值 0 和 1 之间的差异远远大于 9 和 10 之间的差异。0 表示没有购买物品。1 表示买了。所以,对我们来说,1 和 0 之间的差别,远远大于 10 和 9 之间的差别。
题外话:居中评级向量
在研究我们可以做些什么来解决上一段描述的问题之前,让我们注意到,如果用户向量由评级组成,居中是一个动机良好的操作。居中将评级(通常为 1 到 5 等正等级)转换为明确的正、负或中性评级。正如我们之前看到的,这种转换有助于点积作为更好的相似性度量。
也就是说,当用户使用时,需要小心地进行居中操作。考虑一个刚刚给两个项目分别评分为 4 和 5 的用户。居中的评级分别为-0.5 和+0.5。这有道理吗?
一种可能更好的方法是对用户的平均评级使用贝叶斯估计。下面是它的一个简单(有效)的形式。在用户的实际评分上加上从所有用户中随机抽取的 n 个评分。现在计算这些综合评分的平均值。 n 是这里的一个自由参数,它控制我们先前的信念,即这个用户像一个典型的用户一样评价。如果实际上这个用户没有,那么随着用户进行更多的评级,平均评级将向用户实际评级的平均值移动。
尝试拉伸小数值
让我们回到由购买计数组成的用户向量。
好吧,所以 0 和 1 应该被认为不如 9 和 10 相似。同时,5 和 10 应该被认为不如 9 和 10 相似。
让我们看看是否可以通过“拉伸”小值来实现这一点,这样它们的差异就会被聚合。假设 x 是一个值。考虑一下转型
*f(x) = 1–1/e^x*
这将实现这样的拉伸,因为
*f(x)-f(x-1) = 1–1/e^x — (1–1/e^{x-1})
= 1/e^{x-1} — 1/e^x
= (1/e^{x-1})*(1–1/e)*
我们看到,随着 x 的增加,x 的连续值之间的差值减小。所以我们拉伸了小值,但没有拉伸大值。
或者,使用乙状结肠
我们可以从稍微不同的角度来看这个问题。我们可以从二进制化开始,即将每个正计数截断为 1,并使用类似 sigmoid 的函数(如 tanh)将其软化。我们可以调整双曲正切函数的参数(失调和增益),使 0 映射到接近 0,1 映射到接近 1。此外,它还具有所需的属性,即较高的计数映射到较高的值。
然后使用居中点积
在前面提到的计数的非线性变换之一之后,我们将每个向量居中,并像前面一样取点积。
这样够好了吗?
考虑这个例子。
例 4 : 计数分布
***U1** 1 2 3
**U2** 10 20 30
**U3** 3 2 1*
人们可以认为 U1 和 U2 应该比 U1 和 U3 更相似,因为它们具有相同的相对计数。实际数字之间的差异可以用一个简单的因素来解释:U1 是一个多产的买家。**
接下来,让我们看看如果使用中心点积作为相似性度量,我们会得到什么。
最后一列粗体字包含向量平均值。
***U1** 1 2 3 **2
U2** 10 20 30 **20
U3** 3 2 1 **2***
居中的版本是
***U1c** -1 0 1
**U2c** -10 0 10
U3c 1 0 -1*
{U1c,U2c}的相似性得分高于{U1c,U3c}。很好!如你所愿。
我们运气好吗?这在一般情况下行得通吗?我不会在这里讨论这个问题。相反,我会观察到,如果我们寻求一个基于相对计数的度量,那么一个合理的候选就是将计数归一化为概率向量。然后,我们可以使用合适的概率分布相似性度量。比如相对熵。
下面我们举例说明标准化。
首先,我们复制上面的例子,最后一列包含向量和。
***U1** 1 2 3 **6
U2** 10 20 30 **60
U3** 3 2 1 **6***
接下来,我们将每个向量除以它的和。我们得到了
***U1** 1/6 2/6 3/6
**U2** 1/6 2/6 3/6
**U3** 3/6 2/6 1/6*
我们不会继续解释相对熵和计算值。相反,我们只需观察中心点积在概率向量上的表现。
仔细查看零计数
到目前为止,在我们的示例中,我们已经隐含地将没有购买特定商品的用户视为该(用户、商品)对的负面信号。这种假设应该受到质疑。考虑一个项目数量非常大的设置,比方说至少有几十万个。这在电子商务环境中很常见。用户可能没有购买特定的商品,因为她甚至不知道它的存在。在这样的设置中,即使不是所有的用户向量,也是大部分的用户向量非常稀疏。也就是说,用户将只购买了目录中很小一部分项目。使用零计数作为负信号会放大这种假设的效果。
我们来阐述一下“放大这个假设的效果”。对于任何两个用户 u 和 v,以及我从大量商品中随机挑选的一件商品,很有可能 u 和 v 都不会购买 I。如下图 1 所示,居中的点积将此作为 u 和 v 相似的证据。因为宇宙中的大多数物品都不会被 u 或 v 购买,这样不正确的证据会被放大,如下图所示。
*(u, i) = 0 implies u dislikes i (1)
(v, i) = 0 implies v dislikes i (2)
(1)+(2) contributes evidence towards u and v being similar*
图 1 : 错误的推论被放大
使用评级而不是计数可以避免这个问题,因为我们有办法区分缺失值(没有评级)和实际值。也就是说,忽略购买次数,即只使用评分是没有意义的。前者要丰富得多。他们也给出了一个直接的购买信号。评级可能会有偏差。另一方面,一个项目被购买。也就是说,它是为禁止免费赠送的促销商品而付费的,这些商品可以被过滤掉。
那么我们如何处理零计数呢?我们可以考虑总是将零计数解释为缺失值。在这种解释下,被比较的两个行向量的所有分量将具有正计数。这是因为其中一个或另一个计数为零的组件将被丢弃。这没什么大不了的,所有用户向量现在只有正数!
如果可能的话,一个更好的方法是跟踪更多的数据,以便能够以合理的准确度估计用户是否只是不知道某件商品或者选择不购买它。例如跟踪用户是否访问了该项目的页面。
一个更高级的想法是假设我们有可用的互斥对,即从不一起购买的物品对,更一般的是属性对。如果用户的购买频率向量具有来自这样一对元素中的一个元素的正计数,以及来自另一个元素的零计数,则结合了互斥信息的零计数为用户没有(或不会)购买后者的概念提供了支持。当我们讨论基于项目的协同过滤时,我们将讨论推断互斥对。
Jaccard 系数:测量两组的重叠度
假设我们将用户过去的购买行为表示为购买物品的集合。暂且不说我们正在丢失信息——购买计数——集合表示确实因其简单性而吸引人。
用户的集合可以被一般化,以获取其他布尔值属性。如产品家族= PF* 。在下面的讨论中,为了简单起见,我们将只讨论项目集。*
有一个简单的衡量标准,允许我们根据两个用户的项目集的重叠程度对他们的相似性进行评分。这个度量称为 Jaccard 系数,是两个集合的交集大小与并集大小的比值。
举个例子。假设用户 U 和 V 分别购买了{a,b,c}和{b,c,d}。Jaccard 系数为|{b,c||/|{a,b,c,d}| = 2/4。
这项措施因其简单而吸引人。它也有助于非常快速的得分,尽管我们不会在这篇文章中详细阐述这方面的内容。它还缓解了前面讨论的“零计数”问题。与前面介绍的方法不同,Jaccard 系数忽略了任何一个用户都没有购买的所有商品。也就是说,它避免了图 1 中的错误推断。
也就是说,如果一个商品被其中一个用户购买,而另一个用户没有购买,则该商品总是对 Jaccard 系数产生负信号。这可不好。
多重性
Jaccard 系数可以推广到购买次数中吗?在集合的语言中,我们在问,它能被推广到多重集上的相似性度量吗?
是的。这包括将交集、并集和基数运算从集合推广到多重集合。
两个多重集 X 和 Y 的交集可以定义如下。首先,我们取多重集下面的集合的交集。接下来,对于这个交集中的每个元素 e,我们计算它的重数
*m(e) = min(m(e,X), m(e,Y))*
这里 m(e,Z)表示多重集 Z 中元素 e 的重数。
两个多重集 X 和 Y 的并集也有类似的定义。首先,我们取多重集下面的集合的并集。接下来,对于这个并集中的每个元素 e,我们计算它的重数
*m(e) = max(m(e,X), m(e,Y))*
多重集的基数是其中不同元素的多重数之和。
让我们看一个例子。考虑多重集 X = {3a,3b}和 Y = {2a,2b,1d}。“3a”表示重数为 3 的“a”。X 和 Y 的交点是{2a,2b}。X 和 Y 的并集是{3a,3b,1d}。所以 Jaccard 系数是 4/7,交集的基数除以并集的基数。
雅克卡系数对加权雅克卡系数
让我们称 Jaccard 系数到多重集的扩展为加权 Jaccard 系数。现在两者都有了,就可以问哪个效果更好了。答案是“看情况”。我们来细说一下。
考虑 X = {2a,2b},Y = {2a,2b,c}。加权雅克卡系数给出了⅘.丢弃多重性信息的未加权 Jaccard 系数给出了⅔.直观上,前者更准确地量化了这两个多重集的相似性。到目前为止一切顺利。
接下来,改为考虑 X={4a,4b}和 Y={2a,2b}。加权的 Jaccard 系数给出 4/8 =而未加权的给出 1。哪个更准确?人们可以为未加权的一个,因为 X 和 Y 有相同的项目集。
我们再次看到,根本原因是我们混淆了集合成员和多重性(比如购买计数)。正如我们在前面章节中所做的那样,我们可以通过适当的预处理来分离出这些影响。
基于用户的推荐器
为了重述,让我们首先总结一下到目前为止我们所描述的内容。我们有历史交易数据,可能还会增加内容。后者可以是关于项目的内容、关于用户的内容或者两者都有。根据这些数据,我们以前面描述的方式为每个用户构建一个向量。
基于用户的推荐器首先找到其行向量与 u 的行向量最相似(并且足够相似)的 k 个用户。( k 是自由参数。)我们将这些称为 u 的 k 邻居。
然后,它将这些邻居的行向量与 u 的行向量进行比较,以决定向 u 推荐什么。
让我们看一个简单的例子。将 k 设置为 3。比方说 u 的项目集是{a,b,c,d}。说 u 的三个最近邻的项集是{a,b,d, e },{b,c,d, e },以及{a,c,d, e }。突出的是‘e’出现在所有 u 的邻居的项目集合中,而不是在 u 的项目集合中,所以向 u 推荐‘e’是有意义的。
让我们将这个例子中的观点形式化和一般化,如下所示。
*1\. Find the intersection I of the item sets of the *k* neighbors.
2\. Recommend to *u* the items in I that are not currently in *u*’s item
set.*
当 k 不是很小时,比如说 k = 10,步骤 1 可能太保守了,因为我们取的是很多集合的交集。我们可以通过降低 k 来缓解这种情况。然而,这会影响推荐的质量,因为我们现在基于更少的邻居。一种不同的方法是放宽这种 k 的相交标准。这类似于谷歌对包含许多单词的查询所做的。并非所有这些都需要出现在匹配的文档中。
基于项目的推荐器
考虑一个新用户。到目前为止,这个用户几乎没有与系统交互(如果有的话)。所以没有足够的数据来找到这个用户的邻居。因此,基于用户的推荐器在这里是无效的。
基于项目的推荐器工作方式不同。它识别出在同一购物车中出现的比预期的更频繁的商品集合。这些集合被称为频繁项目集。对于购买了频繁项目集中的一些项目的新用户,可以推荐相同集合中的一些其他项目。
更深入一点,我们从例子开始。考虑下面的一系列交易。
*{a, c}, {a, c}, {a, c}, {b, c}, {d, c}*
a、b、c 和 d 是项目。每一组代表一个交易,想想购物车。在本例中,所有事务每个都有两个项目。我们能从这些交易中收集到什么?首先,对{a,c}是一个频繁项集。更重要的是,关联规则 a → b 是一个很好的规则。我们来阐述一下后者。
关联规则 X → Y 表示
*IF X THEN Y*
在我们的设置中,X 和 Y 是不相交的项目集,关联规则捕获了我们的意图,即如果用户购买了 X,推荐 Y。
不是所有的关联规则都一样好,所以我们需要一个关联规则良好性的概念。(事实上,如果没有这一点,我们将有大量的关联规则需要考虑,我们将一事无成。)
关联规则优度通常沿着两个维度定义:支持度和置信度。关联规则的支持量化了规则的适用范围。规则的可信度量化了规则的结果给定先行结果的可能性。
在形式上,支持度与 P(X+Y)成正比,即 X+Y 中的所有商品都在同一个购物车中的概率。(“+”表示集合并集。)置信度与 P(Y|X)成正比,即假设购物车包含所有 X,购物车包含所有 Y 的概率。
好的关联规则支持度高,可信度高。
让我们把这个应用到我们的例子中。在这个例子中,为了简单起见,我们将把一个项目集的支持定义为它发生的事务的数量。考虑规则 a → c。当{a,c}出现在三个事务中时,它的支持度是 3。它的置信度为 1,因为在 a 发生的每个事务中,c 也发生。现在考虑规则 c → a,它的支持度也是 3。然而,它的信心更低,⅗.这是因为在发生 c 的 5 个事务中,有 3 个也发生了 a。所以规则 a → c 优于规则 c → a,也就是说,当有人买 a 时我们应该推荐 c,而不是相反。
电梯
前面提到过,一个关联规则 X → Y 的置信度是 P(Y|X),Y 在包含 X 的购物车中的概率,现在考虑 P(Y)。如果这也很高呢?就是 Y 里面的物品很受欢迎。仅仅因为这个事实,P(Y|X)就可能很高。也就是说,这个关联规则的高可信度可能主要来自于它的结果非常受欢迎。
一种不同的方法叫做升力,可以更好地解决这个问题。X → Y 的升力定义为 P(Y|X)/P(Y)。如果 Y 在包含 X 的篮子中比在随机篮子中更可能被找到,那么这个提升大于 1。
作为一个关联规则强度的度量,lift 是否总是比 confidence 更有效?不总是。因为提升需要取 Y 的两个概率的比值,所以当 P(Y)很小时,它容易受到噪声的影响,这是经常发生的情况。
例如,假设 P(Y) = 0.001。也就是说,平均 1000 个篮子中有 1 个包含 Y,现在假设有 400 个篮子包含 X,其中一个恰好也包含 Y,给定 X,Y 的升力为 1000/400 = 2.5。
对项目间的负面关联进行建模
考虑一个关联规则 i → j,这个表示:如果用户购买我推荐 j* 。如果我们也对负面联想建模,会有意义吗?即型号如果用户购买我不推荐 j 。*
经历过从推荐系统接收推荐的读者可能倾向于回答是。这是因为他们经常看到推荐的商品对他们购买的商品毫无意义。用数据科学的语言来说,这样的建模可以减少误报。
规则 i → j 的解除可以在这方面帮助我们。远小于 1 的升力表示 j 与 I 负相关。
使用 lift 来推断负面关联应该保守地进行。让我们用一个例子来说明这一点。说 P(j)是 0.001,即。j 平均每 1000 个篮子里出现 1 个。现在考虑包含 I 的篮子,假设这些篮子都不包含 j,我们需要几千个这样的篮子,才能有把握地推断 j 不会出现在包含 I 的篮子里。
混合方法
考虑一个描述“当用户购买 a 时推荐 b”的关联规则 a → b。在基于项目的方法中,支持度和信心同等地衡量所有用户的贡献。我们可以通过了解我们推荐给谁来改进这一点。具体来说,我们会给予被推荐人的邻居的贡献更高的权重。
我们可以将此总结为
*recommend b when user u buys a and many users with tastes similar to those of u also buy b when they buy a.*
用户和物品在同一个空间
考虑物品的特征。如品牌、价格、产品、类别。(还有很多其他的。)说这些特征是已知的。从交易数据中,我们可以推断出用户的喜好投射到这些特征上。我们来细说一下。
假设某个用户一直购买苹果智能手机。由此可以推断出用户对苹果的偏好,至少是对智能手机的偏好。或许与安卓智能手机相反。我们甚至可以选择包含多种功能组合的偏好。喜欢苹果智能手机的用户可能更喜欢运行 Windows 的笔记本电脑。我们可以学习这种多特征偏好。
在同一个空间中把用户和项目都表示为向量是很吸引人的。我们可以使用我们到目前为止讨论过的任何向量相似性度量(例如点积)来查找匹配给定用户向量的项目向量,或者反过来。
用户的向量表示用户喜欢各种属性和组合的程度。例如品牌名称、价格、产品类别等等。项目的向量表示项目的属性。因此,类似于项目向量的用户向量意味着用户的偏好与项目的属性相匹配。
由于这些向量具有透明的解释,推荐者还可以附加一个解释来伴随任何特定的推荐。比如“我们向您推荐这款商品,因为它具备这些特质”。这里,特征是从用户和项目向量中匹配的那些特征中选择的。
潜在空间
对于某些类型的物品,很难手工设计一组好的属性,同时对描述物品的和喜欢或者不喜欢物品的有效。接下来,当然是给每件物品贴上属性标签。**
考虑 Youtube 视频。特定视频的潜在特征是什么,揭示了为什么它会引起某些人的共鸣?如果我们可以推断出这些,我们就可以向这些人推荐其他具有类似特征的视频。
这些特征甚至很难描述。(双关。)即使他们不是,谁会给一个新视频贴上适用于它的特定特征的标签呢?
事实证明,某些算法可以从用户-项目矩阵开始,并以某种方式从中推导出用户和项目都可以投影到的空间。这听起来很难理解。怎么会?
首先,让我们观察到,这个潜在空间通常比我们开始的用户向量或项目向量的维度低得多。用户向量的维度是项目的数量。这可能是数百万。一个项目的维度就是用户的数量。这也可能是数百万。相比之下,潜在空间模拟物品的特征有两个目的,一是描述它们,二是辨别用户的口味。在许多设置中,例如电影,少于一百个特征可能就足够了。当然,我们并没有说这些特征是什么,只是限制了多少“不动产”足以捕捉服务于我们目的的特征。
推断用户和项目向量具有相同的潜在空间
假设我们有可用的评价三元组(u,I,rui ),其中 rui 是用户 u 给予项目 I 的评价(比如从 1 到 5)。在有许多用户和许多项目的设置中,这可以被视为用户 X 项目的高维矩形稀疏矩阵。(稀疏,因为只有一小部分用户项目组合具有评级。)
从这个矩阵中,我们可以推断出低维度潜在空间中的用户和项目向量。推断的用户和项目向量应该使得观察到的评级可以从潜在空间中的相似性计算中预测。
我们所说的“潜在空间中的相似性计算”是什么意思?下面我们来解释一下这个。以我们的三元组数据集{(u,I,rui)}为例。将其随机分为训练集和测试集。比如五五开。从训练集中推断用户和项目向量。使用这些来预测每个三元组(u,I,rui)的评级 rui。如下。
设 latent(u)和 latent(i)表示用户 u 和项目 I 的潜在向量,设点积 latent(u)点 latent(i)作为 rui 的预测。
现在我们来看看训练过程。首先,我们必须选择潜在空间的维度。原则上,这本身可以由训练方法决定。(这将对应于模型选择或网格搜索,将该维度视为超参数。)即便如此,我们也必须选择应该对哪些维度值进行网格搜索。
我们经常跳过超参数调整,只选择看起来合理的值。考虑电影。我能马上想到至少五个特征:动作、喜剧、戏剧、…预料到可能还有其他有用的组合,我可能会选数字 20。当然,这看起来像猜测。我们仍然可以期望得到一个推荐器,它比明显错误的极端值(比如 1 和 100000)有所改进。
好了,现在我们已经选择了潜在空间的维度。接下来,让我们讨论我们寻求优化的标准,以便在这个空间中找到好的用户和项目向量。幸运的是,我们已经在前面的段落中暗示过这一点。用户向量 u 和项目向量 I 应该使得它们在训练集上预测的评级是尽可能最好的,如通过一些损失函数所测量的。通常使用平方损失。形式上,这个优化标准是找到最小化的用户和项目向量
*sum_{triple (u, i, rui) in training set}
(rui — latent(u) *dot* latent(i))²*
通常我们还会添加一个正则项来支持稀疏的用户和项目向量。
让我们用电影的背景来说明这种直觉。假设我们选择 n = 20,因为我们合理地认为我们大约需要这么多的特征来覆盖同一空间中的电影和用户口味的范围。任何特定用户的口味都不可能涵盖所有 20 个方面。更有可能的是,用户的口味涵盖了这 20 种口味中的一小部分(当然我们还不知道是哪一种)。同样,任何一部电影的向量都可能是稀疏的。
好了,还剩下什么。训练算法。在这种情况下,一种流行且有效的选择是一种特殊形式的随机梯度下降。
假设我们已经初始化了各种潜在的用户和项目向量。然后,我们从训练集中的三元组(u,I,rui)开始迭代训练,通过在整个训练集中的一次或多次传递。
考虑任何单一的训练迭代。根据(u,I,rui ),我们首先计算预测误差
*eui = rui — latent(u) *dot* latent(v)*
接下来,我们独立地将 latent(u)和 latent(i)中的每一个推向使 eui 更接近 0 的值。然后在下一组训练中重复。
总结
在这篇文章中,我们讨论了推荐系统的主题。我们研究了我们可以从中学习推荐的数据的性质。具体来说,(I)购买及其数量,以及(ii)用户评级。我们讨论了基于用户间相似性或项目间相似性的协同过滤。在这次讨论中,我们还讨论了各种相似性度量,如点积和 Jaccard 系数,以及各种预处理,如二值化和居中。
我们还讨论了如何利用内容来提高推荐的质量。最后,我们讨论了通过将用户数据和项目数据投影到同一个空间来操作的方法。
延伸阅读
- 基于用户和基于项目的协同过滤推荐服务的比较
- 推荐系统—维基百科
篮子分析
原文:https://towardsdatascience.com/basket-analysis-6be025fa36cd?source=collection_archive---------18-----------------------
确认琐碎,揭开神秘,发掘有用
什么是购物篮分析?

所有这些商品都属于同一个顾客购物篮吗?——朱利叶斯·德罗斯特在 Unsplash 上的照片
篮子分析是一个非常简单的概念。想象顾客在杂货店购物。他们从货架上拿起商品,走到收银台付款。然后,您收集来自客户的所有收据,并逐个客户地创建一个他们购买了什么的列表(即,他们的购物篮或购物车中有什么)。您可能会得到如下结果,其中{…}表示客户购物篮中的商品:
- 顾客 A:
- 顾客 B:
- 顾客 C:
- 顾客 D:
看看这些购物品,有几个明显的联想:
- {花生酱} = > {果冻}有 67%的可能性(即,2/3 装了花生酱的篮子里也有果冻)
- {花生酱} = > {面包}有 67%的可能性(也就是说,2/3 装了花生酱的篮子里也有面包)
- { bread } = > {花生酱}有 100%的可能性(也就是说,每个装面包的篮子里都有花生酱)
- {面包、谷物} = > {牛奶} 100%概率(即,每个有面包和谷物的篮子里也有牛奶)
- {麦片,牛奶} = > {面包}有 67%的可能性(即,有麦片和牛奶的 2/3 篮子里也有面包)
这些被称为关联规则或者简称为关联规则。它们告诉我们哪些产品倾向于一起选择,以及知道一个产品在篮子里将如何预测篮子里可能还有什么。这种类型的信息非常有用(很快会有更多)。
发现关联的挑战在于可能组合的绝对数量。想象一个有 100 种不同产品的商店。购物篮中只有一件商品的顾客可以有 100 种可能的组合。拥有两种产品的客户可以有(100 x 99)/2 = 4,950 种可能的组合。如果项目数增加到 3,则有(1009998)/(32) = 161,700 种可能的组合。有了四种产品,就有了 3921255 种可能的组合。这是一个经典的组合问题,你有一组 N 个项目,并从中选择 R;给出可能组合数的方程是 N!/[R! (N-R)!].组合数学的增长甚至比指数增长还要快得多——这使得分析数据来识别相关产品变得不可能,除非你使用一个聪明的算法;无论你的计算资源如何,试图彻底检查每一个可能的组合都是不可行的。
Apriori 算法
幸运的是,有一个聪明的算法:“Apriori 算法”,它被设计成通过一个简单的先验假设来快速评估非常大的数据集。对于被认为是关联的一组项目,该组必须以足够的频率出现。但是如果一组项目频繁出现,那么这些项目的子集也一定频繁出现。这意味着我们可以简单地通过排除不常出现的子集来排除大量的候选关联。在我们这个微不足道的例子中,只有一个顾客购买了大米,但是有 3 个顾客购买了花生酱。这意味着米饭只出现了 25%,而花生酱出现了 75%。浏览列表,我们看到客户购物篮中的每种产品出现的频率如下:
- 谷物=> 75%
- 牛奶=> 75%
- 花生酱=> 75%
- 果冻=> 50%
- 面包=> 50%
- 大米=> 25%
- 草药=> 25%
- 土豆=> 25%
由于草药和土豆出现的频率相对较低,我们可以将它们排除在考虑范围之外,因为这些项目加上其他项目的组合也很少出现。这将搜索空间从 8 个项目减少到只有 6 个项目,从而将可能的集合数量从 256 个减少到只有 64 个。Apriori 算法将这种假设应用于所有可能的子集(例如,{花生酱、果冻}、{牛奶、谷物}),以快速消除整个潜在关联组,这使得处理大型数据集变得可行。
我真心推荐感兴趣的读者购买带 R 的机器学习,里面有关于 Apriori 算法的精彩章节。在 r 中使用这种技术非常简单。作为一个例子,让我从概念上向您展示应用这种算法需要多少行代码:
library(‘a rules’);data <- read.csv(file=”segment.csv”, sep=”,”)data_xtabs <- as.data.frame.matrix(xtabs(~account_id+segment_name, data));data_xtabs_logical <- as.data.frame(data_xtabs > 0);transactions <- as(data_xtabs_logical, “transactions”);summary(transactions);rules <- apriori(transactions, parameter = list(support = 0.01, confidence = 0.5, minlen = 2));summary(rules);
尽管我强烈建议您在使用 Apriori 算法之前先理解它背后的理论…是的,它确实很容易使用。完全公开我从我的例子中删除了 3-4 行对我们的讨论不重要的代码,但是上面的 R 代码非常有代表性,只有 8 行。在这 8 行代码中,一行用于加载 Apriori 库,四行用于加载数据,两行分别用于打印数据和规则的摘要。您可以看到为什么我是 R 的狂热爱好者,并强烈推荐那些对开发强大的分析功能非常感兴趣的组织习惯于使用 R(或 Python)并远离像 Excel 这样的简单工具。
当使用 Apriori 算法时,有三个关键概念你必须理解:支持、信任和提升。这些很容易理解:
- Support —这是对一组项目出现在数据中的频率的度量。例如,如果花生酱的支持度为 50%,这意味着 50%的顾客在购物篮中放了花生酱。同样,如果{花生酱、果冻}的支持度是 25%,那么每 4 个顾客中就有 1 个顾客的篮子里有的花生酱和果冻。所需的支持度越高,Apriori 算法不考虑的数据就越多。
- 信心——这是对一组相关产品预测能力的衡量。例如,如果{花生酱} =>{果冻}的置信度为 75%,这意味着每个放有花生酱的篮子也有 75%的机会在同一个篮子中放有果冻。类似地,说{面包,谷物} =>{牛奶}的置信度是 100%意味着每个既有面包又有谷物的篮子也有牛奶。所以信心告诉你,你能在多大程度上信任这个协会。置信度越高,您将删除的关联就越多(即,不予考虑)。
- 提升 —这是衡量您对相关产品组合的惊讶程度;不是普通意义上的惊讶,而是统计学意义上的惊讶。例如,假设你有一个篮子,里面有 1 个蓝球和 9 个红球。如果你伸手去抓一个随机的球,你有 10%的几率得到一个蓝球,90%的几率得到一个红球。让我们假设你把手伸进篮子 3 次,随机抓一个球,看看颜色,然后把球放回篮子里。据统计,得到 3 个蓝球的概率只有 0.1%,这意味着每 1000 次尝试中,你应该只有一次得到 3 个蓝球(平均)。如果你继续尝试,在这 1000 次尝试中,最终得到这样的结果 50 次,而不是 1 次或 2 次,那么你应该会非常惊讶。得到 50 次而不是 1 次这样的结果意味着它发生的频率是随机概率预测的 50 倍。所以 lift 基本上是用关联发生的频率除以关联偶然发生的概率(即关联不是真实的)。
在使用 Apriori 算法分析数据时,对于支持度、置信度或升力应该是多少,并没有正确的答案。然而,我喜欢使用一个简单的经验法则:
- 支持 —这应该根据您的数据进行缩放。例如,如果您正在查看客户群相互关联的频率,但只有 10%的客户重复购买,那么您的支持度不能超过 10%,因为 90%的数据都只有一件商品。所以我通常使用一个简单的规则,即支持度应该至少是我期望项目子集出现在数据中的频率的 1%。
- 信心——一个没有预测性的关联是没有用的,所以一般来说,只要有可能,我喜欢看到至少 50%的信心,这样当你使用这个关联时,你往往是“正确的”。
- 升力 —任何升力小于 10x 的尺子都应谨慎使用;我喜欢看到这种提升至少比偶然性高一个数量级,让我觉得这是一种真实的联系,而不仅仅是一种随机的巧合
琐碎的、神秘的、有用的
每当您使用像 Apriori 算法这样的算法来建立关联时,您通常会得到可分为三组的规则:
- 琐碎的事情
- 神秘的
- 有用的
琐碎的规则是显而易见的关联。例如,如果你用这种技巧告诉商业领袖,购买尿布的顾客也购买婴儿配方奶粉,你可能会被他们笑出房间。或者买花生酱的顾客也买果冻。这些都是显而易见的,不需要千兆字节的数据和复杂的算法就能发现。一般来说,您会从大多数业务数据中获得大量“琐碎”的规则。
神秘的规则是数据中出现的关联,但很难解释,即使关联是真实的而不是随机的,也不一定是你会做的事情。例如,假设您发现购买牛奶与购买自动铅笔密切相关。这将是一个令人挠头的规则,因为没有理由——至少我能想到——为什么把牛奶放入购物车的顾客也会放自动铅笔。你可能不会重新布置你的商店,把铅笔和钢笔放在牛奶区。所以我会把这些类型的挠头联想归类为“神秘”——尽管这并不意味着知道它们没有用。你用这些做什么取决于你的策略…这将在稍后讨论。
最后是有用的规则。这些规则并不琐碎,也不“神秘”或“怪异”,而且你实际上可以立即投入使用。你有没有想过,为什么当你走过家得宝或其他大型五金店时,他们会习惯性地在过道上挂一些不相关但看起来合适的产品样品?例如,我注意到我当地的家得宝会在木材区放少量的锤子和钉子…整个过道里的钉子比你需要的还要多,锤子的种类也比大多数人见过的多,但出于某种原因,他们还是在木材区放了一些样品。为什么?这是因为联想。通过人工分析、轶事或使用 Apriori 算法等技术,有人注意到购买木材的人也倾向于购买锤子和钉子。这不是一个微不足道的规则,因为我会假设大多数从木材通道购买木材的人已经至少有一把锤子和大量的钉子,因为木材不是大多数人心血来潮购买的东西。然而,人们仍然倾向于一起购买这些东西…如果你处理木材,也许你永远不会有足够的锤子和钉子?
分析!=策略…是的,我的朋友,你必须思考!
分析师和数据科学家有时会犯错误,认为分析就是一切。那是一个错误。没有战略的分析就像购买大量水泥和木材,然后期待房子自己建造。分析只是一个构建模块…战略实际上是使用这些构建模块来完成一些有用的事情。所以你用 R 写了 8 行代码,发现了一系列神秘而有用的关联(希望你明白我的意思,忽略那些无关紧要的)…现在恭喜你,你打算用这些关联做什么呢?如果你是一名分析师或数据科学家,像商业人士一样思考并问自己这个问题是很重要的:“那又怎样?”
如果你曾经逛过杂货店,你会注意到牛奶区总是在杂货店的后面。这是有目的的:它迫使你在杂货店徘徊,这将增加你购买更多东西而不仅仅是牛奶的机会。这就是策略!让我们考虑一个类似{花生酱} = > {果冻}的琐碎联想。对于这种关联,您可以采取两种基本策略:
- 将花生酱放在远离果冻的另一个通道,迫使购物者四处逛逛,增加他们购买其他东西的机会
- 将花生酱放在同一个过道上,以增加顾客在拿到花生酱时购买果冻的机会
哪种策略更好?没有正确的答案。事实上,我见过一些杂货店使用一种策略,而另一家使用另一种策略。将花生酱和果冻放在远离彼此的地方可能会增加顾客在寻找两种产品时抓住另一种产品的机会,但如果他或她不想玩“捉迷藏”,则可能会有顾客只抓住一种并离开的风险。将花生酱和果冻放在同一个货架上,增加了顾客同时拿到两种产品的机会,并轻松创造更多收入,但如果顾客被迫四处闲逛,他们可能会拿到第三种产品。决定的唯一方法是运行 A/B 测试,比较每个策略产生的收入。如果你想更好地理解 A/B 真正衡量的是什么,我也为写了一篇关于这个的文章。
线性回归的批、小批和随机梯度下降
原文:https://towardsdatascience.com/batch-mini-batch-and-stochastic-gradient-descent-for-linear-regression-9fe4eefa637c?source=collection_archive---------10-----------------------
三种基本梯度下降变体的实现和比较

图片由来自 Pixabay 的 geralt 提供,由作者修改
1.介绍
梯度下降算法是一种迭代一阶优化方法,用于找到函数的局部最小值(理想情况下是全局最小值)。它的基本实现和行为我已经在我的另一篇文章中描述过了。这一个集中在算法用来计算梯度和制作步骤的数据量的三个主要变量上。
这三种变体是:
- 批量梯度下降(BGD)
- 随机梯度下降
- 小批量梯度下降(mBGD)
在本文中,我们将在一个简单的线性回归任务中看到它们的性能。
简单回顾一下——一元线性函数定义为:

它由两个系数参数化:
- a0 -偏差
- a1 -函数的斜率。
出于演示目的,我们定义以下线性函数:

其中 σ 是白(高斯)噪声。下面的代码为我们将要使用的数据集生成了 100 个点。

我们希望最小化的成本函数(指标)是均方误差,定义为:

在一元函数的情况下,它可以明确地写成:

下面的代码计算给定的一组两个参数的 MSE 成本。
注意,对于我们的原始系数,由于随机误差(白噪声),最小成本函数不为 0(它将在每次运行时变化),此时等于:

下图显示了最佳点附近的这个函数。我们可以看到它有一个细长的碗的形状。

围绕全局最小值的成本函数;作者图片
要使用任何梯度下降算法,我们必须计算这个函数的梯度。因为对于一元线性回归,我们的算法最小化 2 个系数,我们必须分别计算它们的导数。让我们注意到:
现在,使用链规则我们获得以下结果:

下一节将关注算法本身。使用的代码可以在我的 GitHub 库上找到。
2.批量梯度下降
在批处理 GD 中,在每一步都使用整个数据集来计算梯度(记住:我们不计算成本函数本身)。下图显示了它在优化过程中的表现。它需要 86 次迭代来找到全局最优值(在给定的容差内)。

批量梯度下降过程的动画;作者图片

批量梯度下降的轨迹;作者图片
批量梯度下降的轨迹看起来很好——每一步都越来越接近最优,横向振荡随着时间的推移越来越小。这是它具有良好收敛速度的原因。
为了准确地找到它的收敛速度,我们必须做一些数学。为了不过分复杂,让我们假设我们的成本函数是强凸的(两次可微的)并且具有一个 Lipschitz 连续梯度,其中 L > 0 定义为:

第二个假设限制了渐变的速度。
如果您可以计算 L,那么您可以导出所谓的“保证进度的界限”,它是保证收敛的步长(学习速率):

然而,你不应该在实践中使用这个值,因为它真的很小而且收敛很慢。找到最佳学习率是一个巨大的话题,适合单独写一篇文章——只需检查一些东西,例如“回溯线搜索”,“阿米霍条件”或“沃尔夫条件”。
假设固定步长收敛速度取决于函数的凸性。
对于简单(弱)凸函数,收敛速度为[1]:

其中 k 是迭代次数。该速率称为“亚线性收敛”,对于给定的容差ε,需要以下迭代次数才能收敛[1]:

对于强凸函数,比率为[1]:

其中 0

Pros and Cons of Batch Gradient Descent:
优点:
- 一个简单的算法,只需要计算一个梯度
- 在训练期间可以使用固定的学习速率,并且可以预期 BGD 收敛
- 如果损失函数是凸的,非常快地收敛到全局最小值(对于非凸函数,非常快地收敛到局部最小值)
缺点:
- 即使使用矢量化实现,当数据集很大时(大数据的情况),速度也可能很慢
- 不是所有的问题都是凸的,所以梯度下降算法不是通用的
典型使用案例:
- 适合计算机内存的小型数据库
- 凸成本函数的问题(如 OLS,逻辑回归等。)
3.随机梯度下降
随机梯度下降的思想不是使用整个数据集来计算梯度,而是仅使用单个样本。目标是加快这一进程。就选择样本而言,有两条主要规则:
- 随机规则—随机选择的样本(可能重复)
- 循环规则—每个样本一次(无重复或重复次数最少)
随机规则更常见。
- 下图显示了 SGD 如何收敛到最终解(示例性运行)。红点表示为给定步长计算选择的样本。

SGS 收敛过程的动画;作者图片
由于其随机性,每次运行需要不同数量的步骤来达到全局最小值。在相同起点(0,0)和相同学习率(0.05)下运行 100 次所需的迭代直方图下方。

收敛所需的迭代次数;作者图片
与批处理 GD 相反,它不会直接收敛到解,因为它每次迭代只使用 1 个样本,这意味着步骤非常嘈杂。但是,它的效率要高得多,CPU/GPU 负载更少。这种影响对于小型数据库(像这样)几乎看不到,但在处理大数据时会对性能产生巨大影响。
下图显示了上例中 SGD 步骤的轨迹。

随机梯度下降的轨迹;作者图片
固定步长随机梯度下降的收敛速度[1]:

这意味着 SGD 不像批量梯度下降那样具有线性收敛速度——仅仅意味着它需要更多的迭代(但不一定需要计算时间)。
随机梯度下降的利与弊:
优点:
- 对于大型数据集,比批量 GD 收敛更快(时间更少)
- 可以逃离局部极小值
缺点:
- 步骤更嘈杂— SGD 可能需要更多迭代才能收敛到限制值
- 它可以在全局最优值附近“跳跃”——它可能需要比批量 GD 更大的容差
典型使用案例:
- 是用于训练人工神经网络的更高级随机算法的基础
4.小批量梯度下降
小批量梯度下降是一种在纯 SGD 和批量梯度下降之间找到良好平衡的方法。想法是使用一个观察子集来更新梯度。每个尺寸所用的点数称为批量,一个批量的每次迭代称为一个时期。下面的动画显示了每个步骤中使用的点的收敛过程(批量大小为 10)。

小批量梯度下降的收敛过程:作者图片
轨迹仍然是嘈杂的,但更稳定地走向最小值。

小批量梯度下降的轨迹;作者图片
该算法的收敛比介于 BGD 和 mBGD 之间,为[1]:

其中 b 是批量大小。
小批量梯度下降的利与弊:
优点:
- BGD 和新加坡元之间在效率方面的良好平衡
- 很容易放入计算机内存
- 可以避开局部最小值
缺点:
- 它仍然可以在全局最优值附近“反弹”——它可能需要比批量 GD 更大的容差,但小于 SGD
- 另一个需要优化的超参数—批量
典型使用案例:
- 这是深度神经网络训练中非常常见的算法
5。总结
我们经历了梯度下降算法的 3 个基本变体。在当代的 ML 中,使用了更先进和更有效的版本,但是仍然使用这里描述的基本思想。进一步的修改包括自适应学习率、各种动量(如内斯特罗夫)、平均等。
一些非常流行的实现有:
- 亚当
- RMSprop
- 阿达格拉德。
有一个正在进行的研究工作,以进一步改善他们的非凸函数(深度神经网络),其中包括各种想法,每个过程的数据。
如果你想了解更多关于本文主题的细节,我强烈建议你查阅这些阅读材料:
- 加州大学伯克利分校 Ryan Tibshirani 的随机梯度下降
- 加州大学伯克利分校 Ryan Tibshirani 的凸优化
- 用不一致随机梯度下降加速深度神经网络训练
- 深度神经网络训练中随机梯度下降的不收敛性
- 带洗牌的分布式随机梯度下降的收敛性分析
Batch Norm 直观地解释了它是如何工作的,以及为什么神经网络需要它
原文:https://towardsdatascience.com/batch-norm-explained-visually-how-it-works-and-why-neural-networks-need-it-b18919692739?source=collection_archive---------0-----------------------
动手教程,直观深度学习系列
一个非常重要的深度学习层的温和指南,用简单的英语

由鲁本·特奥在 Unsplash 上拍摄的照片
Batch Norm 是现代深度学习实践者的工具箱中必不可少的一部分。在批量标准化论文中介绍之后不久,它就被认为在创建可以更快训练的更深层次的神经网络方面具有变革性。
Batch Norm 是现在很多架构中普遍使用的神经网络层。它通常作为线性或卷积块的一部分添加,有助于在训练期间稳定网络。
在本文中,我们将探讨什么是批处理规范,为什么我们需要它,以及它是如何工作的。
你可能也会喜欢阅读我的另一篇关于批处理规范的文章,这篇文章解释了为什么批处理规范如此有效。
如果你对一般的神经网络架构感兴趣,我有一些你可能会喜欢的文章。
- 优化器算法(SGD、Momentum、RMSProp、Adam 等梯度下降优化器使用的基本技术)
- 差分和自适应学习率 ( 优化器和调度器如何用于增强模型训练和调整超参数)
但是在我们讨论批量规范化本身之前,我们先来了解一些关于规范化的背景。
标准化输入数据
当向深度学习模型输入数据时,标准做法是将数据归一化为零均值和单位方差。这意味着什么,我们为什么要这样做?
假设输入数据由几个特征 x1,x2,…xn 组成。每个要素可能有不同范围的值。例如,特性 x1 的值可能在 1 到 5 之间,而特性 x2 的值可能在 1000 到 99999 之间。
因此,对于每个特征列,我们分别获取数据集中所有样本的值,并计算平均值和方差。然后使用下面的公式对这些值进行归一化。

我们如何标准化(作者图片)
在下图中,我们可以看到数据归一化的效果。原始值(蓝色)现在以零为中心(红色)。这确保了所有的特征值现在都在相同的比例上。

标准化数据是什么样子的(图片由作者提供)
为了理解不进行归一化会发生什么,让我们来看一个只有两个比例完全不同的要素的示例。由于网络输出是每个特征向量的线性组合,这意味着网络学习每个特征在不同尺度上的权重。否则,大特性会淹没小特性。
然后在梯度下降过程中,为了“移动指针”以减少损失,网络必须对一个权重进行较大的更新。这可以导致梯度下降轨迹沿着一个维度来回振荡,从而采取更多的步骤来达到最小值。

不同尺度的特征需要更长时间才能达到最小值(图片由作者提供)
在这种情况下,损失景观看起来像一个狭窄的峡谷。我们可以沿着二维分解梯度。沿着一个维度是陡峭的,而沿着另一个维度则平缓得多。
由于梯度较大,我们最终对一个权重进行了较大的更新。这将导致渐变下降反弹到斜坡的另一侧。另一方面,沿着第二方向的较小梯度导致我们进行较小的权重更新,从而采取较小的步骤。这种不均匀的轨迹需要网络更长的时间才能收敛。

狭窄的山谷导致梯度下降从一个斜坡反弹到另一个斜坡(图片由作者提供)
相反,如果要素在相同的比例上,损失景观会像碗一样更加均匀。梯度下降然后可以平稳地进行到最小值。

归一化数据帮助网络更快收敛(图片由作者提供)
如果你想了解更多这方面的内容,请参阅我的《神经网络优化器》,其中详细解释了这一点,以及不同的优化器算法如何发展来应对这些挑战。
批量定额的必要性
既然我们理解了什么是规范化,那么需要批量规范化的原因就开始变得清晰了。
考虑网络的任何隐藏层。来自前一层的激活只是这一层的输入。例如,从下图中第 2 层的角度来看,如果我们“清空”所有之前的层,来自第 1 层的激活与原始输入没有什么不同。
要求我们对第一层的输入进行规范化的逻辑同样适用于每一个隐藏层。

每个隐藏层的输入是来自前一层的激活,也必须被标准化(作者的图像)
换句话说,如果我们能够以某种方式标准化来自每个先前层的激活,那么梯度下降将在训练期间更好地收敛。这正是批处理规范层为我们做的。
批量定额是如何工作的?
Batch Norm 只是插入到一个隐藏层和下一个隐藏层之间的另一个网络层。它的工作是获取第一个隐藏层的输出,并在将它们作为下一个隐藏层的输入传递之前对它们进行归一化。

批处理规范层在激活到达第 2 层之前对第 1 层的激活进行规范化
就像任何网络层的参数(如权重、偏差)一样,批规范层也有自己的参数:
- 两个可学的参数叫做β和γ。
- 两个不可学习的参数(平均移动平均值和方差移动平均值)被保存为批次标准层“状态”的一部分。

一批规范图层的参数(图片由作者提供)
这些参数是每批定额层。因此,如果我们在网络中有三个隐藏层和三个批次范数层,我们将有三个可学习的β和γ参数用于这三个层。移动平均参数也是如此。

每个批次定额层都有自己的参数副本(图片由作者提供)
在训练期间,我们一次向网络提供一小批数据。在转发过程中,网络的每一层都处理这一小批数据。批次定额层按如下方式处理其数据:

批量定额层执行的计算(图片由作者提供)
1。激活
来自前一层的激活作为输入被传递给批量定额。数据中的每个特征都有一个激活向量。
2.计算平均值和方差
对于每个激活向量,分别计算小批量中所有值的平均值和方差。
3.使标准化
使用相应的平均值和方差计算每个激活特征向量的归一化值。这些标准化值现在具有零均值和单位方差。
4.缩放和移位
这一步是 Batch Norm 引入的巨大创新,赋予了它力量。与要求所有归一化值的均值和单位方差为零的输入图层不同,Batch Norm 允许其值被移动(到不同的均值)和缩放(到不同的方差)。这是通过将归一化值乘以系数γ,再加上系数β来实现的。请注意,这是一个元素级乘法,而不是矩阵乘法。
这项创新的巧妙之处在于这些因素不是超参数(即由模型设计者提供的常数)但是是由网络学习的可训练参数。换句话说,每个批次范数层都能够以最佳方式找到自己的最佳因子,因此可以移动和缩放归一化值以获得最佳预测。
5.移动平均数
此外,Batch Norm 还保存平均值和方差的指数移动平均(EMA)的运行计数。在训练期间,它只是计算这个均线,但不做任何事情。在训练结束时,它只是将该值保存为层状态的一部分,供推断阶段使用。
我们将在稍后谈到推论时回到这一点。移动平均计算使用下面用 alpha 表示的标量“动量”。这是一个超参数,仅用于批处理范数移动平均值,不应与优化器中使用的动量相混淆。
向量形状
下面,我们可以看到这些向量的形状。计算特定要素的矢量时涉及的值也以红色突出显示。但是,请记住,所有的特征向量都是在一次矩阵运算中计算出来的。

批量范数向量的形状(图片由作者提供)
向前传球后,我们像平常一样向后传球。对所有层权重以及批标准层中的所有β和γ参数计算梯度并进行更新。
推理过程中的批量规范
正如我们上面讨论的,在训练过程中,批量定额从计算小批量的平均值和方差开始。然而,在推断过程中,我们有一个单一的样本,而不是一个小批量。在这种情况下,我们如何获得均值和方差?
这就是两个移动平均参数的用武之地,它们是我们在训练过程中计算出来并与模型一起保存的。在推断过程中,我们将这些保存的平均值和方差值用于批量定额。

推理时批量定额计算(图片由作者提供)
理想情况下,在训练期间,我们可以计算并保存全部数据的平均值和方差。但这将非常昂贵,因为我们必须在训练期间将整个数据集的值保存在内存中。相反,移动平均线很好地代表了数据的均值和方差。这样效率更高,因为计算是增量式的——我们只需记住最近的移动平均值。
批量定额层的放置顺序
对于批处理规范层应该放在架构中的什么位置,有两种观点——激活之前和激活之后。最初的论文把它放在前面,虽然我想你会发现文献中经常提到这两个选项。有人说“之后”会有更好的结果。

批量定额可在激活前或激活后使用(图片由作者提供)
结论
Batch Norm 是一个非常有用的层,您最终会在您的网络架构中经常使用它。希望这能让你很好地理解如何使用批处理规范。
理解为什么批处理规范有助于网络训练也是有用的,我将在另一篇文章中详细介绍。
最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、音频深度学习和地理定位机器学习的其他系列。
让我们继续学习吧!
直观地解释了批量定额——它为什么有效?
原文:https://towardsdatascience.com/batch-norm-explained-visually-why-does-it-work-90b98bcc58a0?source=collection_archive---------11-----------------------
实践教程,直观的深度学习系列
一个温和的指南的原因,批量规范层的成功,使训练收敛更快,在平原英语

由 Unsplash 上的absolute vision拍摄
批量范数层经常用于深度学习模型中,与卷积或线性层相关联。许多最先进的计算机视觉架构,如 Inception 和 Resnet,都依赖于它来创建可以更快训练的更深层次的网络。
在本文中,我们将探讨为什么批处理规范有效,以及为什么在训练模型时它需要较少的训练时期。
你可能也喜欢阅读我的另一篇关于 Batch Norm 的文章,这篇文章用简单的语言解释了什么是 Batch Norm,并一步一步地介绍了它是如何在幕后运作的。
如果你对一般的神经网络架构感兴趣,我有一些你可能会喜欢的文章。
- 优化器算法 (梯度下降优化器使用的基本技术,如 SGD、Momentum、RMSProp、Adam 等)
- 图像字幕架构 (具有图像特征编码器、序列解码器和注意力的多模态 CNN 和 RNN 架构)
批量定额为什么管用?
毫无疑问,Batch Norm 工作得非常好,并为深度学习架构设计和培训提供了大量可测量的好处。然而,奇怪的是,究竟是什么赋予了它如此神奇的力量,目前还没有一个普遍认同的答案。
诚然,已经提出了许多理论。但是多年来,关于这些理论中哪一个是正确的一直存在争议。
最初的发明者对为什么批处理规范有效的第一个解释是基于一种叫做内部协变量转移的东西。后来在麻省理工学院研究人员的另一篇论文中,该理论被驳斥,并基于损耗和梯度曲线的平滑提出了另一种观点。这是两个最著名的假设,所以让我们在下面回顾一下。
理论 1——内部协变量转移
如果你和我一样,我相信你会觉得这个术语很吓人!😄用简单的语言来说,这是什么意思?
假设我们要训练一个模型,模型需要学习的理想目标输出函数(虽然我们事先不知道)如下。

目标函数(图片由作者提供)
不知何故,假设我们输入到模型中的训练数据值只覆盖了输出值范围的一部分。因此,该模型只能学习目标函数的子集。

训练数据分布(图片由作者提供)
该模型不知道目标曲线的其余部分。什么都有可能。

目标曲线的其余部分(图片由作者提供)
假设我们现在向模型提供一些不同的测试数据,如下所示。这与模型最初训练时使用的数据有着非常不同的分布。该模型无法对这些新数据的预测进行归纳。
例如,如果我们用客机的图片训练一个图像分类模型,然后用军用飞机的图片测试它,这种情况就会发生。

测试数据有不同的分布(图片由作者提供)
这就是协变量转移的问题——尽管新数据仍然符合相同的目标函数,但模型输入的数据分布与之前训练的数据分布非常不同。
为了让模型知道如何适应这些新数据,它必须重新学习一些目标输出函数。这会减慢训练过程。如果我们从一开始就为模型提供了覆盖所有值的代表性分布,它就能够更快地了解目标输出。
既然我们了解了什么是“协变量转移”,那么让我们看看它是如何影响网络训练的。
在训练过程中,网络的每一层都学习一个输出函数来适应它的输入。假设在一次迭代中,层“k”接收来自前一层的小批量激活。然后,它通过基于该输入更新其权重来调整其输出激活。
然而,在每次迭代中,前一层‘k-1’也在做同样的事情。它调整其输出激活,有效地改变其分布。

协变量移位如何影响训练(图片由作者提供)
这也是层“k”的输入。换句话说,该层接收的输入数据的分布与以前不同。它现在被迫学习适应这种新的输入。正如我们所看到的,每一层最终都试图从不断变化的输入中学习,因此需要更长的时间来收敛并减缓训练。
因此,提出的假设是批处理范数有助于稳定这些从一次迭代到下一次迭代的移位分布,从而加快训练。
理论 2 —损耗和梯度平滑
麻省理工学院的论文发表的结果挑战了解决协变量移位是 Batch Norm 性能的原因的说法,并提出了不同的解释。
在典型的神经网络中,“损失景观”不是平滑的凸面。它非常颠簸,有陡峭的悬崖和平坦的表面。这给梯度下降带来了挑战——因为它可能会在它认为有希望遵循的方向上突然遇到障碍。为了弥补这一点,学习率保持在较低水平,这样我们在任何方向都只能迈出小步。

一个神经网络损失景观 (来源 ,经郝莉许可)
如果你想了解更多这方面的内容,请参阅我的关于神经网络优化器的文章,这篇文章更详细地解释了这一点,以及不同的优化器算法是如何发展来应对这些挑战的。
本文提出批处理范数的作用是通过改变网络权值的分布来平滑损失景观。这意味着梯度下降可以自信地朝着一个方向迈出一步,因为它知道在这个过程中不会发现突然的中断。因此,它可以通过使用更大的学习速率来迈出更大的步伐。
为了研究这一理论,本文进行了一项实验,以分析一个模型在训练过程中的损失景观。我们将尝试用一个简单的例子来形象化这一点。
假设我们有一个简单的网络,有两个权重参数(w1 和 w2)。这些权重的值可以显示在 2D 表面上,每个权重有一个轴。权重值的每个组合对应于这个 2D 平面上的一个点。
随着训练过程中重量的变化,我们移动到这个表面上的另一个点。因此,可以在训练迭代中绘制权重的轨迹。
请注意,下图仅显示了每个点的重量值。为了形象化这种损失,想象一个 3D 表面,第三个轴代表从页面出来的损失。如果我们对所有不同重量组合的损失进行测量和绘图,损失曲线的形状称为损失图。

(图片作者)
实验的目标是通过测量如果我们继续向同一方向移动,在不同点的损失和梯度看起来像什么,来检查损失情况。他们在有和没有批量标准的情况下进行测量,看看批量标准有什么影响。
假设在训练期间的某次迭代‘t’时,它在点 P(t)。它评估 Pt 处的损耗和梯度。然后,从该点开始,以一定的学习速率向前迈出一步,到达下一个点 P(t+1)。然后它倒回 P(t ),并以更高的学习速率重复该步骤。
换句话说,它通过沿着梯度方向采取三种不同大小的步骤(蓝色、绿色和粉色箭头),使用三种不同的学习速率,尝试了三种不同的替代方案。这给我们带来了 P(t+1)的三个不同的下一点。然后,在每一个 P(t+1)点,它测量新的损失和梯度。
在此之后,对同一网络重复所有三个步骤,但包括批量标准。

(图片作者)
现在,我们可以绘制出 P(t+1)点(蓝色、绿色和粉色)在单个方向上的损耗。起伏的红色曲线表示没有批次标准的损失,平滑下降的黄色曲线表示有批次标准的损失。

批量亏损平稳下降(图片由作者提供)
类似地,我们可以画出这些点上梯度的大小和方向。红色箭头显示梯度在大小和方向上剧烈波动,没有批次标准。黄色箭头显示梯度的大小和方向保持稳定,具有批次标准。

批量规范的渐变更平滑(图片由作者提供)
这个实验告诉我们,批量范数显著地平滑了损失情况。这对我们的训练有什么帮助?
理想的情况是,在下一个点 P(t+1),梯度也位于相同的方向。这意味着我们可以继续朝着同一个方向前进。这样可以让训练顺利进行,快速找到最小值。
另一方面,如果 P(t+1)处的最佳梯度方向将我们带向不同的方向,我们将会徒劳地沿着之字形路线前进。这将需要更多的训练迭代来收敛。
虽然这篇论文的发现到目前为止还没有受到质疑,但不清楚它们是否已经被完全接受为结束这场辩论的决定性证据。
不管哪个理论是正确的,我们可以肯定的是批处理规范提供了几个优点。
批量定额的优点
Batch Norm 提供的巨大好处是让模型更快收敛,加快训练速度。这使得训练对如何初始化权重和超参数的精确调整不太敏感。
批量定额让你使用更高的学习率。如果没有批处理规范,学习率必须保持较小,以防止大的异常梯度影响梯度下降。批处理规范有助于减少这些异常值的影响。
批次范数还降低了梯度对初始权重值的依赖性。由于权重是随机初始化的,因此在训练的早期阶段,异常权重值会扭曲梯度。因此,网络收敛需要更长的时间。批处理规范有助于抑制这些异常值的影响。
批量定额什么时候不适用?
批量定额不适用于较小的批量。这导致每个小批量的平均值和方差中有太多的噪声。
批量定额不适用于循环网络。每个时间步长之后的激活具有不同的分布,使得对其应用批量定额不切实际。
结论
即使我们不确定正确的解释,探索这些不同的理论也是令人着迷的,因为它让我们对神经网络的内部工作有了一些了解。
无论如何,批处理规范是我们在设计架构时绝对应该考虑的一层。
最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、音频深度学习和地理定位机器学习的其他系列。
让我们继续学习吧!
使用 PyTorch 深度学习框架的序列数据批量采样器
原文:https://towardsdatascience.com/batch-sampler-for-sequential-data-using-pytorch-deep-learning-framework-part-3-df19f449f24e?source=collection_archive---------13-----------------------
在 PyTorch 框架的 dataloader 中使用零填充顺序数据集时,优化 GPU 利用率

杰西卡·约翰斯顿在 Unsplash 上的照片
注意——要了解如何为自定义数据集编写数据加载器,无论是顺序的还是图像的,请参考这里的。
对于数据点大小可能不同的顺序数据集,我们使用零填充使所有数据点大小相同。因此,批处理可以转换为张量,并传递到图形卡(GPU)进行并行处理。
但是这种方法不是最佳的。考虑两批 8 个数据点,每个数据点的大小如下:
- 批次 1— [2,5,5,4,6,7,8,2],批次的最终大小= 8*8
- 批次 2— [2,32,5,36,6,34,8,2],批次的最终大小= 36*8
在批次 1 中,所有数据点需要使用零填充转换为大小 8,而在批次 2 中,所有数据点需要转换为大小 36。在这两种情况下,最小大小都是 2,但是在批次 1 中,我们只给大小为 2 的元素添加了 6 个零,而在批次 2 中,我们需要添加 34 个零。因此,我们可以看到,批处理 2 在处理无用的零时浪费了大量 GPU 内存,而批处理 1 是一种高效的打包方式,浪费的 GPU 很少。这个例子显示了问题所在,也给出了我们的解决方案。如果我们能以某种方式手工制作批次,那么我们就能确保每个包装都是有效的。
但是我们怎么做呢??
还记得内部提供的 getitem 函数中的 index 变量吗,如果我们可以手动为每个批次提供索引,那么我们的工作就完成了。为此,我们可以使用数据加载器中的 batch_sampler 参数,如下所示。
train_dataset = Dataset_seq(word2id, train_path)
sampler = Sampler(tokens, data, bin_size) #data is list of sentences
present in whole corpus
train_batch_sampler_loader = DataLoader(
train_dataset,
batch_sampler = sampler,
collate_fn = collate_fn)
现在,将使用我们将在下面定义的 sampler 函数来提供一个批次的索引。
注意——对于不同的时期,最好在一批中有不同的数据点集,即如果在第一个时期一批通过(数据 1、数据 2、数据 3、数据 4 ),在其他时期,我们应确保不一起提供相同的数据集(数据 1、数据 2、数据 3、数据 4 )。这是为了确保我们的模型不会学习提供数据点的模式/顺序。
现在让我们来理解如何为我们的采样器函数编写算法:
- 我们将创建一个包含每个数据点长度的列表 text_len 。
- 然后,我们将创建箱(或桶数据),使得每个箱存储大小小于或等于对应于该箱的大小的数据点的索引。这里,对应于每个库的大小取决于 bin_size。例如,如果 bin_size = 2,那么 bin 的大小将是 3,5,7…直到最大尺寸出现在 text_len 中。
- 如果说 text_len = [2,3,4,5,6,7,8],那么我们将得到{3: [0,1],5: [2,3],7: [4,5],8: [6]}即索引 0,1 处的值大小≤ 3,索引 2,3 处的值大小≤ 5,依此类推。最后一个 bin 的大小为 8,因为这是 text_len 中的最大大小。
- 现在,我们已经根据大小分离了所有数据,我们将创建我们的批次。为此,我们将使用一个参数 n_tokens ,该参数指示 GPU 中可以加载的最大总大小(包括零填充)。因此,如果 n_tokens=500 ,那么我们可以使每一批在补零之后,一批中每个数据点的大小之和小于或等于 500。
- 现在,为了形成批,我们从最大的桶开始,继续按顺序挑选索引,直到该批的总大小刚好小于或等于 n_tokens。一旦形成一个批次,我们将其附加到 final_indicies 中,这是一个列表列表。这个过程一直持续到所有的数据点(存在于所有的箱中)被拾取并被分配给一批。
- 为了确保不在不同时期发送相同的一组批,在每个时期之后,我们随机打乱为每个箱存储的列表。因此,当我们按顺序开始从箱子中挑选时,我们每次都会得到不同的数据。
请参考下面的算法代码
我希望这个博客能帮助你理解和探索新的应用。请分享你的反馈和其他方法,让这个博客变得更好。
成为 介质会员 解锁并阅读介质上的许多其他故事。关注我们的 中的 ,阅读更多此类博文。
使用 GPyTorch 的批量多维高斯过程回归
原文:https://towardsdatascience.com/batched-multi-dimensional-gaussian-process-regression-with-gpytorch-3a6425185109?source=collection_archive---------16-----------------------
实践教程
克里金法[1] ,更普遍的说法是高斯过程回归(GPR),是一种强大的非参数贝叶斯回归技术,可用于从时间序列预测到插值的应用。



本演示中的 fit GPR 模型示例。高维高斯过程回归/克里金模型在许多不同领域都很有用,例如插值。图片来源:作者。
GPyTorch [2] ,一个为高斯流程设计的包,通过 PyTorch 后端、批量训练和推理、和CUDA 硬件加速,充分利用了硬件加速方面的重大进步。
在本文中,我们研究 GPyTorch 的一个具体应用:为分批、多维插值拟合高斯过程回归模型。
进口和要求
在我们开始之前,让我们确保所有的包都已安装并导入。
安装块
要使用 GPyTorch 进行推理,您需要安装gpytorch和pytorch:
# Alternatively, you can install pytorch with conda
pip install gyptorch pytorch numpy matplotlib scikit-learn
导入块
一旦我们的软件包安装完毕,我们就可以导入所有需要的软件包:
# GPyTorch Imports
import gpytorch
from gpytorch.models import ExactGP, IndependentModelList
from gpytorch.means import ConstantMean, MultitaskMean
from gpytorch.kernels import ScaleKernel, MultitaskKernelfrom gpytorch.kernels import RBFKernel, RBFKernel, ProductKernel
from gpytorch.likelihoods import GaussianLikelihood, LikelihoodList, MultitaskGaussianLikelihood
from gpytorch.mlls import SumMarginalLogLikelihood, ExactMarginalLogLikelihood
from gpytorch.distributions import MultivariateNormal, MultitaskMultivariateNormal
# PyTorch
import torch
# Math, avoiding memory leak, and timing
import math
import gc
import math
创建一个批量 GPyTorch 模型
为了创建一个批处理模型,更一般地说,是 GPyTorch 中的任何模型,我们子类化的gpytorch.models.ExactGP类。像标准 PyTorch 模型一样,我们只需要为这个类定义构造函数和forward方法。对于这个演示,我们考虑两个类,一个在我们的整个输入空间上有一个内核,另一个在我们的不同输入上有一个分解的内核【5】。
全输入,批量模式:
该模型使用包装有输出比例超参数的 RBF/平方指数核来计算输入的所有维度之间的核。此外,您可以选择使用自动相关性确定(ARD) [2]为每个特征维度创建一个长度比例参数。
分解后的内核模型:
该模型使用 RBF/平方指数核的乘积计算输入的所有维度之间的分解核,每个核考虑特征空间的单独维度。然后,用 outputscale 超参数包装这个分解后的产品内核。此外,您可以选择使用自动相关性确定(ARD) [2]为两个 RBF 核中的每个特征维度创建一个长度尺度参数。
预处理数据
为了准备拟合高斯过程回归的数据,考虑如何拟合我们的模型是有帮助的。为了利用 PyTorch [3]和 CUDA [4]的硬件加速和批处理,我们将我们预测的变量集的每个结果建模为独立的。
因此,如果我们有需要拟合插值的 B 批数据,每一批都有 N 个样本,X 维度为CY 维度为 D ,那么我们将数据集映射到以下维度:
- X 数据:(B,N,C) → (B * D,N,C)……这是通过平铺完成的。
- Y 数据:(B,N,D) →(B * D,N)……这是通过堆叠完成的。
在某种意义上,我们平铺我们的 X 维数据,使得对于我们的向量值 Y 取的每个值,特征重复 D 次。这意味着我们的批量模型集中的每个模型将负责学习一批 X 的特征和同一批 Y 、、中的单个输出特征之间的映射,从而导致我们的批量模型中总共有 B * D 个模型。这种预处理(平铺和堆叠)是通过以下代码块完成的:
# Preprocess batch data
B, N, XD = Zs.shape
YD = Ys.shape[-1]
batch_shape = B * YD
if use_cuda: # If GPU available
output_device = torch.device('cuda:0') # GPU
# Format the training features - tile and reshape
train_x = torch.tensor(Zs, device=output_device)
train_x = train_x.repeat((YD, 1, 1))
# Format the training labels - reshape
train_y = torch.vstack(
[torch.tensor(Ys, device=output_device)[..., i] for i in range(YD)])# train_x.shape
# --> (B*D, N, C)
# train_y.shape
# --> (B*D, N)
我们执行这些转换是因为尽管 GPyTorch 拥有为批量模型和多维模型(在包文档中表示为多任务)设计的框架,不幸的是(据我所知)GPyTorch 还不支持批量多维模型。由于批处理和硬件加速,上述代码无法对 Y 的不同维度之间的相关性进行建模,从而大幅提高运行时间。
训练批量、多维 GPR 模型!
现在,随着模型的创建和数据的预处理,我们已经准备好训练了!下面的脚本使用 PyTorch 的自动微分框架执行优化超参数的训练。在这种情况下,优化了以下批量超参数:
- 长度刻度
- 输出规模
- 协方差噪声(原始和受限)
请查看本页 [5],了解关于每个超参数的作用的更多信息。
该培训功能如下所示:
运行推断
现在,我们已经在训练数据上训练了一组批量多维高斯过程回归模型,我们现在准备运行推断,在这种情况下,用于插值。
为了证明这种拟合的有效性,我们将训练一个批量多维模型,并将其预测与根据随机生成的数据评估的解析正弦函数进行比较,即
X = {xi},xi ~ N(0_d,I_d),i.i.d.
Y = sin(X),逐元素,即 yi = sin(xi)对于所有 i
(其中 0_d 和 I_d 指 d 维零向量(零均值)和 d 维单位矩阵(单位协方差)。上面的 X 和 Y 将作为我们的测试数据。
为了评估这些预测的质量,我们将计算结果预测的均方根误差(RMSE) 与 Y 的真实分析值进行比较。为此,我们将每批抽取一个测试点( X 中的 C 尺寸,以及 Y 中的 D 尺寸),即我们在批量 GPR 模型中拟合的每个 GPR 模型将预测单一结果。将对所有批次的预测样本计算 RMSE。
结果
上述实验导致各批次的平均 RMSE 约为 0.01。自己试试!
下面是从上面的脚本生成的结果,显示了 X 和 Y: 中每个维度的预测值和真实值









将我们的预测值与真实分析值进行比较的结果。第一列显示 X 的前两个维度与 Y. 的给定预测维度的关系第二列显示 X 的前两个维度与 Y. 的给定真解析维度的关系最后一列显示 X 的给定维度与 Y. 的相同预测维度的关系图片来源:作者。
下表列出了基础数据分布不同方差程度的 10 次迭代的平均 RMSE 值:

在我们的批量多维高斯过程回归模型的测试集上,基础正态分布与平均 RMSE 的方差。图片来源:作者。
总结
在本文中,我们看到我们可以使用 GPyTorch、创建批处理、多维度高斯过程回归模型,这是一个最先进的库,在其后端利用 PyTorch 进行加速推理和优化。
我们使用解析正弦波实验评估了这种批量多维高斯过程回归模型,并发现在对多元(即独立数据)标准正常生成的数据进行回归时,我们能够实现约为 0.01 的 RMSE ,这表明这些模型的非参数功效非常适合各种函数近似和回归任务。
敬请关注完整的 GitHub 资源库!
这里有更多的可视化!请注意,下面的模型利用的批量大小为 1,但与上面的模型来自同一个类,并为每个输出维学习一维高斯过程回归量。


将 GPR 拟合到 Ackley 测试函数。图片来源:作者。


将 GPR 拟合到 Branin 测试函数。图片来源:作者。


将 GPR 拟合到 Rastrigin 测试函数。图片来源:作者。


用余弦 8 测试函数拟合探地雷达。图片来源:作者。
参考
[1]奥利弗,玛格丽特和理查德·韦伯斯特。"克里金法:地理信息系统的一种插值方法."《国际地理信息系统杂志》4.3(1990):313–332。
[2] Gardner,Jacob R .等,“Gpytorch:带 gpu 加速的黑盒矩阵-矩阵高斯过程推断。” arXiv 预印本 arXiv:1809.11165 (2018)。
[3]亚当·帕兹克、萨姆·格罗斯、弗朗西斯科·马萨、亚当·莱勒尔、詹姆斯·布拉德伯里、格雷戈里·查南、特雷弗·基林、林泽铭、娜塔莉亚·吉梅尔斯海因、卢卡·安提加、阿尔班·德斯迈松、安德烈亚斯·科普夫、、扎卡里·德维托、马丁·赖森、阿利汗·特贾尼、萨桑克·奇拉姆库尔蒂、伯努瓦·施泰纳、、、、接君·巴伊和苏史密斯·钦塔拉。Pytorch:命令式风格,高性能深度学习库。在 H. Wallach、H. Larochelle、A. Beygelzimer、f .达尔凯-Buc、E. Fox 和 R. Garnett 编辑的《神经信息处理系统的进展》第 32 卷第 8024-8035 页中。柯伦联合公司,2019。
[4] NVIDIA,Vingelmann,p .和 Fitzek,F. H. P. (2020 年)。 CUDA,发布时间:10.2.89 。从 https://developer.nvidia.com/cuda-toolkit取回。
[5]仁食谱,【https://www.cs.toronto.edu/~duvenaud/cookbook/】。
使用云调度程序和函数在 GCP 批处理作业
原文:https://towardsdatascience.com/batching-jobs-in-gcp-using-the-cloud-scheduler-and-functions-2d542410c11d?source=collection_archive---------22-----------------------
演示如何使用云调度程序、发布/订阅和云功能在 GCP 平台中设置无服务器批处理作业。

卢卡斯·布拉塞克在 Unsplash 上的照片
在设计和实现解决方案时,我经常面临围绕数据存储和处理设置循环批处理作业的需求。最近,我一直在努力让我的基础设施尽可能保持无服务器,所以在这篇文章中,我将向你展示如何利用谷歌云平台来免费运行你的项目可能需要的几乎任何批处理作业。
用例
对我来说,当涉及到数据处理、协调和清理时,这个批处理模式是最有用的。这是一个涉及数据聚合的示例…
存储桶可以是一个有效的流数据存储库,但是如果您的有效负载很小并且很频繁,那么如果您必须频繁读取,为每个有效负载创建一个文件会非常昂贵。我通过运行一个批处理作业来解决这个问题,将单独的有效负载合并到每小时或每天的文件中,这是一个更具成本效益的解决方案。
或者数据库清理怎么样…
如果您有一个包含大型时间序列数据集的 SQL 数据库,定期清除对性能至关重要。您可以将一个重复的作业压缩到一个 web 应用程序或 ETL 系统中,该系统将数据加载到您的表中,但是我使用这种无服务器批处理方法来解耦解决方案并简化维护。
体系结构
我们将使用 3 个 GCP 服务来实现我们的无服务器批处理解决方案。云调度器将触发我们的批处理事件,发布/订阅将用于将事件传输到云函数,云函数将执行所需的批处理操作。

作者图表
定价
GCP 提供了一个非常慷慨的免费层,我在下面为我们需要调度和运行批处理作业的三个服务做了一个简化的成本表。每 5 分钟运行一次的批处理作业将使用 1 个云调度程序作业、大约 9,000 次云功能执行和大约 9MB 的发布/订阅吞吐量。

作者图表
如果你的项目需要 3 个以上的工作,你将被收取每月 10 美分的额外工作。
配置
发布/订阅
首先,让我们配置一个发布/订阅主题,因为在我们设置调度程序和无服务器功能时都需要它。主题可以在 GCP 控制台的这里进行配置。

作者图表
- 正如你所看到的,我们需要配置的只是主题名称——我使用的是
example-topic
云调度程序
接下来,我们将云调度器配置为我们的批处理触发器。点击这里并创建您的调度作业。

作者图表
- 在我的示例中,我将调度程序配置为每 30 分钟运行一次,但是您可以根据需要设置任何时间段
- 指定我们在上一步中创建的主题—我使用的是
example-topic - 我们的云函数不需要任何东西,除了来自调度器的触发器,所以有效载荷值并不重要,你可以输入任何值——我用的是
run
云函数
我们差不多完成了,最后一步是创建一个云函数,当调度程序触发一个事件时,这个云函数就会被触发。这里可以找到云功能配置。

作者图表
- 选择云发布/订阅作为触发类型
- 选择在第一步中创建的主题
- 继续进行代码配置—我将使用现成的 Node.js 函数。该函数只是记录发布/订阅有效负载的内容。
该功能可能需要一分钟才能完全部署。
请记住,在这一步中,您可以使用任何可用的编程语言。
测试
为了测试我们的配置,我们需要查看云调度器列表,并使用RUN NOW选项手动触发我们的调度器。

作者图表
为了确保我们的功能成功触发,我们可以前往我们的云功能列表,选择您之前配置的功能并查看Logs选项卡。

作者图表
您应该看到日志输出,表明您的函数已经运行,并且还应该显示您为云调度程序配置的有效负载消息。
成功了!
结论
现在,在 5 分钟内,我们配置了一个 100%免费的解决方案,您可以使用它来运行各种类型的批处理作业。如果您发现自己需要快速设置一个高度解耦的解决方案来启动或运行批处理作业,那么现在您可以使用 GCP 快速简便地完成它。
祝好运,编码快乐!
原载于 2021 年 2 月 7 日【http://www.theappliedarchitect.com】。**
面向人员分析应用的自动 ML 巨头之战
原文:https://towardsdatascience.com/battle-of-the-auto-ml-titans-for-people-analytics-application-1dc6eed9b5eb?source=collection_archive---------35-----------------------
评估用于员工流失预测的 Tpot & Pycaret 自动机器学习库

GR Stocks 在 Unsplash 上拍照
展望未来并预测将要发生的事情有多强大?在数据科学中,机器学习实现了这一点!巧妙的,通过从过去发生的事情中学习来预测未来可能发生的事情。我们可以想象,这种技术的应用在人员分析中可能是革命性的,一个经典的用例是预测员工辞职。
自出现以来,ML 已经成熟了很多,并且今天处于这样一个阶段:初涉概念并且通常被预测分析的想法吓倒的数据科学家也可以投入到探索 ML 中,并缩短解决问题的时间。Auto ML 正是实现这一点的途径—为您的数据集评估和应用最佳 ML 管道来执行预测分析。因此,我强烈鼓励人员分析师(具有编程知识)采取这些令人放心的步骤进入预测分析的世界。在本文中,我们将在开源数据集上评估两个强大的 auto ML 库— Tpot 和 Pycaret,以根据一些已知的特征信息预测流失—某人是留下还是离开。
为什么是自动 ML?
对我来说,选择 auto ML 而不是传统 ML 是一个很容易的决定,因为前者可以缩短从数据准备到预测的求解时间。因为当你试图按照下图中概述的步骤顺序,一次对一个 ML 模型进行优化,使其对你的数据集具有最佳预测能力时,会浪费很多时间。而在 auto ML 中,一般来说,所有这些步骤,包括超参数调整、对单个模型进行分组以产生整体最佳组合预测模型,都被配置为在其母公司的保护下发生,用户的干预最少甚至没有。

作者图片
了解基础知识
下一部分将说明正在评估的两个 auto ML 库如何在开源 HR 流失 Kaggle 数据集上预测流失。在此之前,我们需要熟悉下图中捕获的一些关键指标— 混淆矩阵、精确度、召回率、F1 ,以选择获胜的 ML 模型。请注意,这并不是评估任何机器学习模型的所有指标的详尽列表,而是与手头的任务最相关的,并且已经结合这个特定的 ML 任务进行了解释。

作者图片
在看了上面的关键因素之后,我还建议看一下 AUC (曲线下面积)分数,简单地说,它衡量真正积极预测与随机猜测的准确性。准确性度量是所有观测值的所有真实预测(包括正面的&负面的)的度量,与精确度和召回率相比,它在这种情况下并不是一个非常具有指示性的度量,因为一个模型可以基于它对留下的群体(真实的负面)的正确预测而高度准确,但是它对离开的群体(真实的正面)的预测可能完全错误,这是我们情况下的目标。
值得注意的是,本文中考虑的示例是监督(二元)分类机器学习模型——分类,因为响应变量是分类的,保存表示员工离开或留下的值。因此,这些指标实际上是以一种简化的方式根据案例研究进行解释的。
评估自动 ML 库
有许多介绍评估模型的在线资源;本文下面的参考资料部分包含了一些有用的链接,供进一步阅读。本文将着重于通过理解给定的数据集,将 Pycaret 和 Tpot auto ML 库应用于预测辞职员工的业务任务。
第一步是在命令提示符窗口中使用pip install tpot和pip install pycaret安装我们正在评估的 auto ML 库。安装完成后,下一步是打开 Jupyter 环境进行编码(本文使用 JupyterLab 作为编码平台)。
让我们从库和数据集的导入开始。
作者图片
打印数据集的形状(或者更具体地说,pandas 数据框)显示有 14,999 行和 9 列。head()函数输出数据集中的前 5 行,让我们对正在处理的信息有所了解。

作者图片
很明显,标有“左”的列表示流失,“1”表示离开的人,“0”表示继续留下的人。这是我们的回应栏目。剩余的列是特征,我们将把它们提供给 ML 模型,以解释与响应的关系,然后基于这些解释进行预测。
我们可以进一步推断,所有的特征列都是数值型的,仅仅是因为它们保存的值不是离散的(就像性别—男性,女性是离散值)。这也适用于“薪金”列,该列包含“低”、“中”和“高”的值,因此清楚地展示了这些值之间的内在关系,即高薪金>中薪金>低薪金。在我们评估 auto ML 模型之前,使用下面的代码进行一个简单的检查,确认是否有任何列包含丢失的值,但是幸运的是,对于这个数据集,没有丢失的值,代码只是返回 0。在您可能正在处理的真实业务案例数据集中,决定您希望如何处理任何缺失值(删除它们或估算平均值等)至关重要。通常,auto ML 库在建模中配置了某种程度的缺失值插补,以满足大多数情况。
作者图片
1。Pycaret
让我们从设置 Pycaret 分类模块开始。这一步必须通过的元素是“数据”中的数据框和“目标”参数中的响应列。还有更多的参数可以使用,并进一步增强 setup()函数的用法;然而,对于这个示例,我们将退回到依赖配置默认值。在缺省值中需要指出的是,训练测试分割是 70–30 %,除非在调用 setup()函数时进行了调整。
作者图片
从下面执行 setup()函数的输出中可以看出,Pycaret 将大多数特性列解释为 categorical。

作者图片
我们可以使用“numeric_features”参数传递我们想要将数据类型更改为数字的列,因此更新后的代码如下所示。
作者图片
执行这个更新的设置代码现在显示了作为列表传递给“numeric_features”参数的特性列,所有这些特性列都反映为数字数据类型。

作者图片
我们仍然需要处理“salary”列,将其从当前的分类数据类型转换为“Numeric”因为列中的值是字符串类型,所以一种转换方法是为这些字符串值分配数字,以保持高>中>低:2>1>0 的关系。这种改变可以在评估 ML 模型之前作为数据准备的一部分来完成,因为它也是评估 Tpot 的通用改变。
作者图片
现在我们可以看到,“salary”列中的值已经被转换为代表以前的低、中和高字符串值的数字。随后,执行 Pycaret 分类 setup()并在列表中为“numeric_features”参数传递“salary ”,可以将所有功能列反映为数字数据类型。

作者图片

作者图片
然后,根据 setup()函数的提示,我们可以按“enter”键来初始化模型,并开始可视化 auto ML 可以带来的神奇效果这一激动人心的部分。通过调用下面的 compare_models()函数,我们将在代码环境中看到 Pycaret 对训练分割运行 10 重交叉验证,以对特征与响应的关系做出最佳解释,从而实现对测试分割或未来未知数据的最佳预测。默认结果排序是通过准确度度量,因此被称为通过 F1 度量排序的参数,以查看此处用例的最佳精度-召回平衡模型。
作者图片

作者图片
具有最佳度量分数的 ML 模型方便地用黄色突出显示,以便缩小和简化我们的选择过程。在执行 compare_models()函数之后,变量“best_model”保存这种情况下的随机森林分类器。对于给定的数据集,我们可以简单地使用随机森林分类器模型,因为这个 ML 模型显示了最有希望的整体度量分数。没有比这更简单的了!
需要注意的是,作为 compare_models()函数输出的指标是 10 次交叉验证的平均值。现在让我们看看测试分割的混淆矩阵,以揭示预测与实际相比有多准确。
作者图片

作者图片
我们可以看到,与真实阴性和真实阳性中反映的绝大多数准确预测相比,假阴性和假阳性中反映的失误相当小,因此解释了> 95%的平均指标。
绘图模型还有其他基本绘图套件,您可以通过更改“plot”参数来指定其他值,如“pr”来绘制精度-召回曲线,“auc”来绘制 ROC 曲线并确认 AUC,等等。
预测的最后一步非常简单,只需调用 predict_model()函数并传递所选的 ML 模型和数据集来进行预测。对于此图,初始数据集已被重新使用,但可以很容易地调整为一个新的数据集,其中包含模型的未知数据,以便进行新的预测。
作者图片
正如我们在下面看到的,predict_model()函数输出提供了额外的列—“Label”反映了 ML 模型对数据集中每个行项目的预测,而“Score”反映了“Label”中预测的概率百分比这就是我们所需要的,让我们的商业利益相关者对那些可能离开的人有所预见,以便采取适当的行动来留住他们。

作者图片
2. TPOT
与 Pycaret 相比,Tpot 在执行方面有所不同。首先,我们需要分割整个数据集,以清楚地定义“X”和“y”中的特征和响应,并进一步定义与 Pycaret 保持一致的 70–30%的训练测试分割。形状函数输出确认分割。
作者图片

作者图片
类似地,在准备训练 Tpot 分类器模型时,将“n_splits”参数设置为 10,以匹配与 Pycaret 一致的 10 重交叉验证。针对此用例调整的其他参数与您将在下面的参考资料链接中找到的参数相比,是“计分”从准确性更改为 f1,类似于在 Pycaret 中基于相同的精度-召回平衡指标选择排名最佳的模型,以及“n_jobs”从-1 更改为 6,这影响了 Tpot 构建 ML 管道所用的系统内核数量(数字越大,使用越少,因为-1 会用完所有内核)。
作者图片
Pycaret 与 Tpot 的一个重要区别是,后者需要将近 2 个小时来拟合最佳 ML 模型,而前者只需不到 2 分钟。2 小时后,这是 Tpot 在拟合了列车特征-响应后的输出。对于给定的数据集,性能最好的 ML 管道获得了大约 97.2%的平均 F1 分数,这与我们从 Pycaret 的 compare_models()函数输出中获得的结果没有太大的不同。我们还看到,顶级模型本身是 KNeighbours 和决策树分类器的组合,因此这也不同于 Pycaret 的最佳模型输出。

作者图片
太好了!既然我们已经走了这么远,让我们最终使用训练过的 Tpot 模型来访问测试集上的预测,并看看我们是否真的取得了优于 Pycaret 的结果。要执行预测,我们只需调用函数plot_metrics(X_test, y_test, model),其中 plot_metrics()是一个自定义函数,它被定义为使用传统的 matplotlib 和 seaborn 库来获得下面的图(代码细节请参考参考资料中提供的 GitHub gist 链接)。

作者图片
结论
我们上面看到的结果表明,对于这个给定的数据集,通过最少的干预和时间,我们可以缩小范围并可能“生产化”的最佳自动 ML 将是 Pycaret。很重要的一点是,用实际业务数据最终确定 ML 模型可能需要比依赖默认值更多的实验(如超参数调整、堆叠、混合模型、特征缩放等)。)即使使用 auto ML,也要在初始缩小部分做大量繁重的工作。愉快地探索您的业务数据!
- 延伸阅读资源 —
- Pycaret 分类教程
- Tpot 分类教程
- GitHub 要点链接到代码
整体之战——随机森林 vs 梯度推进
原文:https://towardsdatascience.com/battle-of-the-ensemble-random-forest-vs-gradient-boosting-6fbfed14cb7?source=collection_archive---------10-----------------------
机器学习领域最流行的两种算法,谁会赢?

Geran de Klerk 在 Unsplash 上拍摄的照片
如果你在机器学习领域呆过一段时间,你肯定听说过一个叫做偏差-方差权衡的概念。这是任何机器学习实践者都应该学习和意识到的最重要的概念之一。
本质上,偏差-方差权衡是机器学习中的一个难题,即具有低偏差的模型通常具有高方差,反之亦然。
偏差是模型预测的实际值和期望值之间的差异。结果,一个高偏差的模型被认为是过于简单,数据拟合不足。
另一方面,方差表示模型对训练数据中微小波动的敏感性。具有高方差的模型对噪声敏感,因此会过度拟合数据。换句话说,该模型非常适合训练数据,但不能概括看不见的(测试)数据。
考虑到这一点,在本文中,我想分享几种平衡偏倚和方差的技术之一:集成方法。
首先,什么是合奏法?
集成方法涉及聚合多个机器学习模型,目的是减少偏差和方差。理想情况下,集成方法的结果将优于任何单独的机器学习模型。
有 3 种主要的集合方法:
- 制袋材料
- 助推
- 堆垛
出于本文的目的,我们将只关注前两个:打包和提升。具体来说,我们将检查和对比两种机器学习模型:随机森林和梯度增强,它们分别利用了打包和增强技术。
此外,我们将在本文的后半部分应用这两个算法来解决泰坦尼克号生存预测竞赛,以了解它们在实践中是如何工作的。
https://www.kaggle.com/c/titanic
决策图表
在我们开始之前,重要的是我们首先理解什么是决策树,因为它是随机森林和梯度推进的基础算法。
决策树是一种监督学习算法,它为任何基于树的模型(如随机森林和梯度推进)奠定了基础。决策树可用于分类和回归问题。
树的每个节点代表一个变量和该变量上的一个分割点(假设该变量是数值型的)。树的叶节点包含树用来进行预测的输出变量。
让我们以 Kaggle 房价预测比赛为例。
假设我们正在构建一个决策树模型,该模型将考虑一所房子的各种特征,例如卧室数量、地段大小、邻居位置等,以便对其最终销售价格进行预测。
为简单起见,假设我们模型的最终结果看起来像这样:

图片来源丹·贝克尔,卡格尔
给定一个随机房屋,我们的模型现在能够从决策树的最顶端(根节点)向下遍历到树的底部(叶节点),并给出该特定房屋的预测价格。
更具体地说,基于这个模型,一栋拥有两个以上卧室、面积大于 11,500 平方英尺的房子的预测价格为 233,000 美元,以此类推。
当然,决策树可以变得比上面显示的更加复杂和精密,具有更大的深度和更多的节点,这反过来将使树能够捕捉预测器和目标变量之间更详细的关系。
随机森林(装袋)
既然我们已经了解了什么是决策树以及它是如何工作的,让我们来检查一下我们的第一个集成方法,bagging。
Bagging 也称为 bootstrap aggregating,是指使用不同的训练数据子集(引导数据集)创建和合并独立、并行决策树集合的过程。
密切注意的话,独立和平行。使用随机森林构建的决策树对模型中的其他树没有任何知识和影响。这是装袋的一个关键特征。
一旦构建了所有的树,模型将选择由单个决策树做出的所有预测的模式(多数投票),并将结果作为最终预测返回。
我希望现在已经很清楚,装袋通过在多棵树上分散错误的风险来减少对单棵树的依赖,这也间接减少了过度拟合的风险。
显然,随机森林并不是没有缺陷和不足。以下是一些应该和不应该使用随机森林的情况:
何时使用随机森林
- 它可用于分类( RandomForestClassifier )和回归( RandomForestRegressor )问题
- 您对预测值的重要性(特征重要性)感兴趣
- 您需要一个快速的基准模型,因为随机森林可以快速训练,并且需要最少的预处理,例如特征缩放
- 如果您有杂乱的数据,例如缺失数据、异常值等
何时不使用随机森林
- 如果你正在解决一个复杂、新奇的问题
- 透明度很重要
- 预测时间很重要,因为模型需要时间来聚合来自多个决策树的结果,然后才能得出最终预测
总结一下随机森林,这里有一些要考虑的关键超参数:
- n_estimators: 控制将建立多少个单独的决策树
- max_depth: 控制每个单独的决策树可以有多深
梯度推进(推进)
另一方面,Boosting 采用迭代方法,通过关注先前迭代中的错误,将多个弱的顺序模型组合起来,创建一个强模型。
弱模型是仅比随机猜测稍好的模型,而强模型是与真实分类强相关的模型。
boosting 不同于 bagging 的一个重要区别是,boosting 下的决策树不是独立构建的,而是以连续的方式构建的,其中每棵树都有效地从之前的错误中学习错误。
还值得注意的是,还有其他的增强变体,例如 AdaBoost (自适应增强) XGBoost (极端梯度增强)和 LightGBM (轻度梯度增强),但是对于本文的目的,我们将只关注梯度增强。
与上一节类似,以下是一些应该和不应该使用梯度增强的情况:
何时使用梯度增强
- 它可用于分类(GradientBoostingClassifier)和回归(GradientBoostingRegressor)问题
- 您对预测值的重要性(特征重要性)感兴趣
- 预测时间很重要,因为与随机森林不同,梯度推进下的决策树不能并行构建,因此构建连续树的过程需要一些时间
何时不使用梯度增强
- 透明度很重要
- 培训时间很重要,或者当您的计算能力有限时
- 您的数据非常嘈杂,因为梯度增强往往会强调甚至最小的误差,因此,它可能会过度适应数据中的噪声
此外,以下是梯度增强需要考虑的一些关键超参数:
- learning_rate: 促进了算法找到最优解的速度和速度
- max_depth: 控制将建立多少个单独的决策树(梯度推进下的树通常比随机森林下的树浅)
- n_estimators: 控制要建立多少棵连续的树(梯度推进下的树的数量通常比随机森林多)
泰坦尼克号案例研究
正如所承诺的,现在让我们在一个实际的项目中应用随机森林和梯度推进,泰坦尼克号生存预测竞赛,以加强我们在本文中已经覆盖的内容。
如果你想继续,请点击这里查看我的 GitHub 上的完整笔记本。
让我们先来看看数据集的前 5 行。

现在,我们将执行一些特征工程和数据预处理,以便为建模准备好数据。具体来说,我们将执行以下操作:
- 在年龄栏中填入乘客的平均年龄
- 将 SibSp 和 Parch 特性组合成一个特性:family_size
- 创建一个新特征 cabin_missing,它作为 cabin 列中缺失数据的指示器
- 对性别列进行编码,将 0 分配给男性乘客,1 分配给女性乘客
- 训练测试分割(80%训练集和 20%测试集)
我将在本文中省略细节,但是如果您对这些步骤背后的基本原理和实际代码感兴趣,请参考我的笔记本。

我们的数据现在可以用于建模了!
随机森林分类器
要查看该模型的默认超参数:
# Default hyperparameters for RandomForestClassifier
print(RandomForestClassifier())

在我们将模型拟合到训练数据之前,我们可以使用 GridSearchCV 来找到超参数的最优集合。
# Set up GridSearchCV
rf = RandomForestClassifier(n_jobs = -1, random_state = 10)
params = {
'n_estimators': [5, 50, 250],
'max_depth': [2, 4, 8, 16, 32, None]
}
cv = GridSearchCV(rf, params, cv = 5, n_jobs = -1)# Fit GridSearchCV to training set
cv.fit(X_train, Y_train)# Best parameters
cv.best_params_
- 最大深度: 4
- n _ 估计量: 50
换句话说,这个训练集的最理想的随机森林模型包含 50 个最大深度为 4 的决策树。
最后,我们可以继续使用这组超参数来拟合我们的模型,并随后评估它在测试集上的性能。
# Instantiate RandomForestClassifier with best hyperparameters
rf = RandomForestClassifier(n_estimators = 50, max_depth = 4, n_jobs = -1, random_state = 42)# Fit model
start = time.time()
rf_model = rf.fit(X_train, Y_train)
end = time.time()
fit_time = end - start# Predict
start = time.time()
Y_pred = rf_model.predict(X_test)
end = time.time()
pred_time = end - start# Time and prediction results
precision, recall, fscore, support = score(Y_test, Y_pred, average = 'binary')
print(f"Fit time: {round(fit_time, 3)} / Predict time: {round(pred_time, 3)}")
print(f"Precision: {round(precision, 3)} / Recall: {round(recall, 3)} / Accuracy: {round((Y_pred==Y_test).sum() / len(Y_pred), 3)}")
- 拟合时间: 0.469
- 预测时间: 0.141
- 精度: 0.797
- 召回: 0.689
- 精度: 0.799
# Confusion matrix for RandomForestClassifier
matrix = confusion_matrix(Y_test, Y_pred)
sns.heatmap(matrix, annot = True, fmt = 'd')

作者图片:随机森林的混淆矩阵
梯度推进分级机
现在,让我们来看看梯度增强如何对抗随机森林。
类似地,要查看该模型的默认超参数:
# Default hyperparameters for GradientBoostingClassifier
print(GradientBoostingClassifier())

使用 GridSearchCV 查找最佳超参数。
# Set up GridSearchCV
gb = GradientBoostingClassifier(random_state = 10)
params = {
'n_estimators': [5, 50, 250, 500],
'max_depth': [1, 3, 5, 7, 9],
'learning_rate': [0.01, 0.1, 1, 10, 100]
}cv = GridSearchCV(gb, params, cv = 5, n_jobs = -1)# Fit GridSearchCV to training set
cv.fit(X_train, Y_train)# Best parameters
cv.best_params_
- 学习率: 0.01
- 最大深度: 3
- n _ 估计数: 250
正如我们所看到的,使用梯度推进构建的树比使用随机森林构建的树更浅,但更重要的是两种模型之间估计量的差异。梯度增强比随机森林有更多的树。
这证实了我们之前讨论的随机森林和梯度增强的结构以及它们的工作方式。
接下来,让我们将我们的梯度推进模型拟合到训练数据。
# Instantiate GradientBoostingClassifier with best hyperparameters
rf = GradientBoostingClassifier(n_estimators = 250, max_depth = 3, learning_rate = 0.01, random_state = 42)# Fit model
start = time.time()
rf_model = rf.fit(X_train, Y_train)
end = time.time()
fit_time = end - start# Predict
start = time.time()
Y_pred = rf_model.predict(X_test)
end = time.time()
pred_time = end - start# Time and prediction results
precision, recall, fscore, support = score(Y_test, Y_pred, average = 'binary')
print(f"Fit time: {round(fit_time, 3)} / Predict time: {round(pred_time, 3)}")
print(f"Precision: {round(precision, 3)} / Recall: {round(recall, 3)} / Accuracy: {round((Y_pred==Y_test).sum() / len(Y_pred), 3)}")
- 适合时间: 1.112
- 预测时间: 0.006
- 精度: 0.812
- 召回: 0.703
- 精度: 0.81
# Confusion matrix for GradientBoostingClassifier
matrix = confusion_matrix(Y_test, Y_pred)
sns.heatmap(matrix, annot = True, fmt = 'd')

图片由作者提供:渐变增强的混淆矩阵
这里,我们观察到,与随机森林相比,梯度增强具有更长的拟合时间,但是预测时间要短得多。
同样,这与我们最初的预期一致,因为训练是在梯度增强下迭代完成的,这解释了更长的拟合时间。但是,一旦模型准备就绪,与随机森林相比,梯度增强进行预测所需的时间要短得多。
概括一下,随机森林:
- 创建独立、并行的决策树
- 使用一些深度决策树可以更好地工作
- 拟合时间短,但预测时间长
相比之下,梯度增强:
- 以连续的方式构建树,其中每一棵树都在前一棵树所犯错误的基础上进行改进
- 与多个浅层决策树一起使用效果更好
- 拟合时间长,但预测时间短
感谢您的阅读。请随意查看我下面的其他文章!
https://medium.com/geekculture/70-data-science-interview-questions-you-need-to-know-before-your-next-technical-interview-ccfbd37a37b3 https://chongjason.medium.com/i-finally-got-a-data-science-job-39f58774785
拜耳大规模建模和加载数据的方法
原文:https://towardsdatascience.com/bayers-approach-to-modelling-and-loading-data-at-scale-abe83e2f460e?source=collection_archive---------40-----------------------
早在 4 月份,我们就为我们的社区举办了一次在线会议,名为 Orbit 2021 ,通过聆听来自拜耳医药公司的 Henning Kuich、Dan Plischke 和 Joren Retel,我们的社区得以一窥拜耳医药公司的一个团队如何使用 TypeDB 来加速他们的药物研发渠道。
目标
拜耳的团队从根本上想要更好地了解疾病,以便他们能够创造更好的治疗干预措施。对疾病的更深入了解使得能够识别和开发具有很少或没有副作用的新治疗干预。
为了实现这一点,他们需要建立一个模型,准确地表示疾病的生物系统,并将其映射到他们可用的大型生物医学数据集。
挑战
描述疾病—数据模型
为了在 TypeDB 中模拟疾病,他们从可以调整的概念开始。将它们建模为 TypeDB 模式中的实体,如下所示:
define
gene sub entity;
variant sub entity;
protein sub entity;
complex sub entity;
indication sub entity;
这里,gene、variant、protein和complex被选为实体,因为它们可以以某种形式与疾病相关联。通过实体indication对感兴趣的疾病进行建模。在实践中,他们需要捕捉生物系统内部的内在相互关系,而生物是复杂的!当然,这意味着我们需要担心生物系统中大量的其他事情。

比如genes在cells中表示,cells是tissues的一部分,而tissues在一个organisam中。这些数据可以来自临床研究中的分析和实验。将所有这些放在一起,并建立正确的关系模型,可能会得出如下结果:

请注意,由于拜耳所做工作的性质,他们无法展示模型的全部细节
为什么是强类型数据库?
为什么 Bayer 团队选择使用 TypeDB 作为这类建模的数据库?
生物学中的一切都是极其相关和依赖于上下文的,这使得在传统的关系数据库中表示数据非常困难。正因为如此,Henning 和他的团队认为 TypeDB 的类型系统是一种更自然的生物学建模方式。
生物医学实验是高度特定于环境的,因此在构建生物医学知识图时,您希望能够快速询问使用了哪些参数,实际的化验是什么,是在体外还是在细胞中?这需要一个能够捕捉这种复杂程度的数据库,以及一种允许我们轻松地对这些数据提出复杂问题的查询语言。有了 TypeDB,Henning 的团队就能做到这一点。
Bayer 还利用了 TypeDB 中本机推理引擎的优势。推理可以为拥有类似复杂生物医学数据的团队做很多事情。例如,Henning 和他的团队使用 TypeDB 的推理引擎,根据它们在染色体上的位置来推断variant到gene的连接。
基因本质上只是基因组中的序列,实际上是沿着一长串其他位置的位置。变体是这些序列的变体,也沿着相同的数字和位置延伸。使用 type QL(TypeDB 的查询语言),该团队能够根据重叠位置将变异映射到基因,而不是依赖于其他需要他们导入变异和基因之间关系的数据库。重要的是,这避免了维护其他数据库的需要,因为定期更新和迁移这些数据库需要很长时间。所有这些都可以通过使用 TypeDB 的推理引擎来避免。
TypeDB 还允许您在数据库生命周期中的任何时间点重新定义模式。例如,我们可以添加一个新的定义,根据基因的位置来定义与基因相关的变异。这很重要,尤其是当我们添加新的数据集时。所有这些都使 Henning 的团队能够更有效地运作,并加速他们的药物发现过程。
通过 github 上的 BioGrakn-Covid repo,你可以看到一个在生物学领域完全充实的模式的例子。
加载数据和开源的 TypeDB 加载器
既然有了一个模式来表示我们正在使用的系统,那么大规模加载数据就成了下一个挑战。为了以拜耳想要的方式做到这一点,亨宁和他的团队构建并开源了 TypeDB Loader (以前的 GraMi),这是一个用于 TypeDB 的数据迁移工具。在这里,我们描述它是如何工作的,以及拜耳团队是如何使用它的。
Henning 的团队决定构建他们自己的定制加载器的原因是,他们想要一种更好、更具可伸缩性的方式来将大量数据加载到 TypeDB 中。为了加载数据,最初的 TypeDB 文档建议构建一个读入文件(例如以表格格式)的函数,并构建一个生成插入查询的模板函数。然后,我们可以使用其中一个客户端驱动程序将其插入到 TypeDB 数据库中。但是,在大规模这样做时,会引入 TypeDB Loader 试图解决的许多挑战:
- 处理所需模板函数的重复逻辑
- 注意潜在的脏数据,防止插入过程中的错误
- 每个事务的插入查询的并行化和批处理
- 大数据容错

TypeDB Loader 是如何工作的?

使用已定义的 TypeDB 模式,我们的第一步是将数据映射到模式。这在两个配置文件中处理。第一个是处理器配置,它包含数据和模式之间的逻辑;例如,必须为每种类型生成哪些属性。这决定了某些属性是否是必需的,并确保获取的数据产生正确类型的正确属性。
第二个配置文件是数据配置文件。在这里,我们可以指定正在读取哪个数据文件,它是什么类型的文件,在处理器配置中使用什么类型的处理器,然后将数据中的列映射到处理器配置中的实际处理器。这确保了所有内容都被正确插入。

拜耳团队还希望能够在数据迁移发生时对其进行监控。插入了什么,哪里可能发生了错误,以及由于什么原因在哪里停止了。这允许您从停止的确切位置重新开始迁移,消除了复制或丢失数据的风险。
现在如何使用 TypeDB Loader?
TypeDB Loader 是一个 Java 应用程序和库,使您能够将其用作 CLI 工具或在自己的 Java 项目中使用。一旦决定了使用这两种方法中的哪一种,就可以指定正在与哪个 TypeDB 实例进行对话以及正在写入哪个数据库。然后提供您的数据配置、处理器配置、TypeDB 模式,然后确定您希望在哪里跟踪迁移状态。这可以像一个 JSON 文件一样简单。

就是这里,TypeDB Loader 从这里开始。Henning 和他的团队正在继续发布更新,并鼓励任何感兴趣的人关注#typedb-loader 频道中关于 Discord 的进展。
TypeDB Loader 的最新版本(GraMi 0.1.1)增加了哪些特性?
- 将带有属性的嵌套关系作为角色扮演者导入
- 将属性追加到现有类型
- 向现有数据追加或插入数据
- 更新模式,包括更新规则
- 对数据插入进行大量测试,以防止数据丢失或错误
- 在迁移开始前捕捉错误的处理器和数据配置验证
- 为快速入门自动生成处理器配置框架
TypeDB 装载机路线图的下一步是什么?
- 改进数据警告日志记录,这是一个更易于理解和解析的整合输出
- 规则管理,使应用和定义或未定义的规则变得更容易
- 直接从 SQL 表中读取,而不仅仅是文件
- 构建 Kafka 连接器,使其成为更大的数据处理基础设施的一部分
理解贝叶斯定理的 3 种方式将提高您的数据科学
原文:https://towardsdatascience.com/bayes-theorem-abc1795af097?source=collection_archive---------25-----------------------
入门
掌握这个直观的统计概念将提高你作为决策者的可信度。

照片由艾拉·奥尔森从派克斯拍摄
贝叶斯定理为我们提供了一种根据新证据更新信念的方法,它考虑了我们先前信念的强度。运用贝叶斯定理,你试图回答这个问题:根据新的证据,我的假设的可能性有多大?
在本文中,我们将讨论贝叶斯定理可以改进您的数据科学实践的三种方式:
- 更新
- 通信
- 分类
最后,你会对基本概念有深刻的理解。
#1 —更新
贝叶斯定理提供了一个检验假设的结构,考虑了先前假设的强度和新的证据。这个过程被称为贝叶斯更新。

贝叶斯定理,其中 A 代表假设,B 代表与假设相关的新证据。
换句话说,这个公式就是“给定 B 的可能性 等于 ( 开括号)给定 B 的可能性 乘以A 的可能性(闭括号 ) 除以B 的可能性”
让我们再看一遍公式,这次是变量的定义:
“根据新证据提出假设的可能性 等于 新证据为真的可能性假设假设假设也为真 乘以 观察到新证据之前假设的可能性,除以( 除以【T41)新证据的可能性。”****
这可以进一步缩短:
“后验概率 等于 可能性 乘以 先验概率 除以 b y 边际可能性。”
不管贝叶斯定理现在听起来是否直观,我保证你一直都在使用它。
真实世界的例子
假设你的朋友打电话告诉你,她很抱歉,但她今晚不能来吃饭了。她最近收养了一只患了流鼻涕的宠物考拉。她真的需要呆在家里监控情况。
你的假设是你的朋友不会无缘无故地抛弃你。(毕竟,你做了一个卑鄙的 phở,你的朋友会疯狂地跳过它。)根据她新宠物的最新证据,你的假设为真的可能性有多大?

照片由瓦莱丽娅·米勒从派克斯拍摄
为了评估我们的朋友因为照顾考拉而不去吃饭的后验概率,我们需要考虑你的朋友需要和考拉呆在家里的可能性,假设你的朋友是一个正直的人,没有好的理由不会放弃晚餐计划。你可能会得出这样的结论:通常负责任的好朋友很有可能会呆在家里照看宠物。
接下来,我们将可能性乘以先前的****概率。在你的朋友打电话之前,你对她的晚餐计划的信心有多强?如果你认为你的朋友坚如磐石,通常不愿意在最后一刻改变计划,那么你的先验概率很大,不管有没有新的证据,你都不太可能改变这一观点。另一方面,如果你的朋友很古怪,你已经在想她是否会打电话取消约会,你的先验概率很低,这也可能会质疑她关于和考拉呆在家里的说法。****
最后,我们用考拉所有权的边际可能性除以上面的计算🐨
贝叶斯推理是建立在这种灵活的、常识性的方式上的,这种方式基于我们先验的力量和新证据的可能性来更新我们关于世界的模型。事实上,贝叶斯定理最初的应用是评估上帝的存在。
当涉及到生活和数据科学的关键问题时,作为评估信念如何随时间变化的直观方法,贝叶斯定理是最棒的。
#2 —沟通
正如贝叶斯定理可以帮助你理解和阐明面对新的证据你如何更新你的理论,贝叶斯也可以让你成为一个更强的数据科学传播者。
数据科学从根本上讲就是应用数据来改进决策。
决定你生活结果的只有两件事:运气和你决定的质量。你只能控制这两样东西中的一个。—安妮·杜克,扑克冠军和作家
提高决策质量通常意味着说服决策者。正如每个人的情况一样,您组织中的决策者正在参与对话
真实世界的例子
我曾经是一家热气球制造商的顾问。我的任务是帮助建立一个数据库,提高客户对其供应链、制造流程和销售的端到端理解。
第一天,工厂经理带我们参观了车间,他自豪地描述了一份新的更轻、更便宜的原材料供应商合同。
但是有一个问题。当我的团队将企业内不同数据源的数据表连接起来时,我们发现了新供应商的材料和 2.5%的废品增长之间的联系。

由达伦·李在 Unsplash 上拍摄的照片
工厂经理有很强的预感,新的供应商对他的业务是一个净积极因素。我们有一些相反的证据。我们也有贝叶斯定理。我们明白这个事实:
先验越强,改变它需要的证据就越多。
在带着我们的发现去找工厂经理之前,我们需要收集额外的证据,证明不存在其他因素,(例如,磨损的机器、新员工、环境条件等)。)导致不同的废料水平。
最终,我们带着更多的证据找到了经理,并帮助他重新谈判供应商合同。
#3 —分类
贝叶斯定理可以应用于文本分析用例,这种技术被称为朴素贝叶斯,因为它天真地假设数据集中每个输入变量(在这种情况下,每个单词)的独立性。
真实世界的例子
假设你发现了一堆你祖父母写的信。他们有一段混乱的关系,有足够的戏剧来证明洛基的浪漫并不局限于真人秀中的年轻人。

来自 Pexels 的 RODNAE Productions 摄影
您希望构建一个情感分类器来确定大多数内容是正面的还是负面的。一种方法是利用朴素贝叶斯。
像朴素贝叶斯这样的生成分类器将建立一个模型,说明一个类(在本例中,正或负)如何生成一些输入数据。给定一个观察(来自我们的 letters 测试语料库的一个新句子),它返回最有可能生成该观察的类。这与学习输入特征的预测能力的判别分类器如逻辑回归形成对比。
朴素贝叶斯建立在单词袋技术的基础上——基本上是将文档转换成直方图,记录每个单词被使用的次数。
您可以使用我们在第 1 部分中学习的贝叶斯推理公式的稍加修改的版本来计算每个观察的最可能类。稍微修改的是朴素贝叶斯的朴素部分:假设每个单词的概率在给定的类中是独立的,因此你可以将它们相乘来产生句子与类一起的概率。**

via 语音和语言处理 作者丹尼尔·茹拉夫斯基&詹姆斯·马丁
在上面的公式中, wᵢ 表示文档中一个单词的计数 c. 公式的分母是单词落入给定类别的条件概率之和。
公式中的+1 防止了在一个类中没有观察到单词的情况下乘以零的任何机会。这种加一的技术叫做拉普拉斯平滑。
最后,|V|由所有类中所有单词的并集组成。
贝叶斯定理词汇
- 后验概率:根据新证据假设的可能性
- 可能性:假设假设假设为真,证据为真的可能性
- 先验概率:在新的证据出现之前,你相信假设是正确的力量
- 边际可能性:证据
- 朴素贝叶斯(Naive Bayes):一种分类算法,假设数据集特征之间的朴素独立性
- 生成分类器:模拟一个特定的类如何生成输入数据
- 单词袋:将文档转换成直方图的文本的简化表示
- 拉普拉斯平滑:避免乘以零的简单加法平滑技术
摘要
我坚信贝叶斯定理对数据科学家是有用的,但我会根据你在评论中给我的反馈更新后验概率。期待听听大家如何在生活和工作中运用贝叶斯定理。
更多文章促进您的数据科学
**** </10-python-skills-419e5e4c4d66> ****
贝叶斯定理,用可视化清晰地解释
原文:https://towardsdatascience.com/bayes-theorem-clearly-explained-with-visualization-5083ea5e9b14?source=collection_archive---------1-----------------------
如果您的 COVID 检测呈阳性,那么您实际上患有 COVID 的几率有多大?
动机
想象一下你来医院检测有没有 COVID。您收到了坏消息:您的 COVID 检测呈阳性!然而,你认为结果有可能是错误的。

作者图片
通过在互联网上做一些研究,你知道三条信息:
- 假定一个人是健康的,那么这个人具有阳性测试结果的概率是 0.01
- 假设患者患有 COVID,则患者检测结果为阳性的概率为 0.98
- 患者患有 COVID 的概率为 0.01。
注意:这些数字不是真实的,是为了教学目的而编造的。
如果患者的 COVID 检测呈阳性,那么他患 COVID 的概率是多少?
这个测试似乎有很高的准确性。检测阳性后,你得 COVID 的概率应该很高吧?
在解决这个猜测之前,让我们用贝叶斯定理来回答这个问题。
贝叶斯定理是什么?
贝叶斯定理是一个简单的数学公式,用于计算条件概率。这个定理表明:

作者图片
一般来说,贝叶斯定理使用与事件相关的新信息来更新事件的概率。
让我们试着用一个例子来理解这个定理。想象有 8 人用 COVID 检测出阴性人和 6 人用 COVID 检测出阳性。在测试呈阳性的 6 人中,只有 4 人确实患有 COVID。
我们表示:

作者图片

作者图片
要获得随机选择的 COVID 和检测阳性的人的概率,我们只需将 COVID 和检测阳性的人数除以接受检测的总人数。

作者图片
为了得到一个随机选择的人患有 COVID 的概率,假设该人测试结果为阳性,我们将患有 COVID 且测试结果为阳性的人数除以测试结果为阳性的人数。

作者图片
请注意,P(+和 D)与 P(D|+)之间的唯一区别在于
- P(+和 D)的样本空间由所有测试的人组成
- P(D|+)的样本空间仅由测试为阳性的人组成。
请注意,这个等式:

作者图片
类似于等式:

作者图片
因此,我们可以说

作者图片
酷!现在我们了解了贝叶斯定理,让我们用它来解决文章开头提到的问题。
问题
一个人有 COVID 的概率是:

作者图片
这意味着,如果从一组人中随机选择一个人,这个人有 1%的几率患有 COVID。

作者图片
假设一个人是健康的,那么这个人检测结果为阳性的概率是

作者图片
这意味着,如果从一群健康人中随机选择一个人,这个人被检测为阳性的概率是 1%。

作者图片
假设一个人有 COVID,则他的检测结果为阳性的概率为

这意味着,如果从一群患有 COVID 的人中随机选择一个人,这个人被检测为阳性的概率是 98%。

作者图片
问题
如果一个随机选择的人 COVID 检测呈阳性,那么这个人有 COVID 的概率是多少?

作者图片
基于贝叶斯定理,该概率可以通过以下等式来计算:

作者图片
因为

作者图片
我们有:

作者图片
因为我们已经知道 P(+|D)和 P(D),我们只需要找到 P(+)。
查找 P(+)
P(+)是随机选择的人检测为阳性的概率。我们可以用下面的等式求出 P(+):

作者图片

作者图片
我们已经知道 P(+|D),P(D)和 P(+|H),所以我们只需要找到 P(H)。
P(H)可以通过用 P(D)减去 1 得到:

作者图片

作者图片
因此,P(+)是

作者图片
求 P(D|+)
现在我们可以用之前找到的 P(+)的值来找到 P(D|+)。

作者图片
如果一个人的 COVID 检测呈阳性,那么他患 COVID 的概率只有 49.7%!这意味着有超过 50%的几率你没有感染 COVID** ,即使你的 COVID 检测呈阳性。**

作者图片
等等!这听起来不对劲
这里一定有问题!毕竟,我们得到的初始统计数据表明测试具有非常高的精确度。
请记住,假设一个人是健康的,这项测试在 99%的情况下都能正确预测这个人的状况。

作者图片
假设一个人患有 COVID,该测试在 98%的情况下都能正确预测该人的状况。

作者图片
为什么如果一个人测试呈阳性,那么这个人确实患有 COVID 的概率小于 50%?因为患 COVID 的人只占 1%。

作者图片
因此,即使测试非常准确,如果您用 COVID 测试为阳性,您也很有可能没有 COVID,因为出现 COVID 的情况非常罕见。****
有了贝叶斯定理,我们可以根据新的信息更新我们的信念。很酷,不是吗?
怎么做才能增加 P(D|+)?
提高 P(D|+)的一个方法是提高测试的准确性。然而,由于测试已经非常准确,很难让它更加准确。
另一个增加 P(D|+)的方法是测试两次。如果随机选择的一个人在的两次检测申请中的每一次检测结果为阳性,那么这个人实际患病的概率是 99% !

作者图片
你可以在这里找到这个概率是如何计算出来的。
模拟贝叶斯定理
为了更好地理解贝叶斯定理,我们可以使用 Seeing Theory ,这是由 Daniel Kunin 创建的一个网站,用于可视化概率和统计。
下面的 GIF 展示了我用视觉理论模拟上面提到的问题。

作者 GIF
你可以试试上面的模拟这里。
右栏的 9 个球是测试呈阳性的人。在这些人中,6 人患有 COVID,3 人健康。

作者图片
我们可以看到这个模拟中的 P(D|+)是 6/9=0.67,和我们之前发现的 0.497 的结果不一样。这是因为我们只模拟了 500 人的实验。
如果我们用非常多的人,P(D|+)会非常接近 0.497。
结论
恭喜你!您刚刚学习了什么是贝叶斯定理,以及如何使用它来解决现实世界中的问题。如果你仔细观察你周围的问题,你会发现贝叶斯定理可以用来解决许多现实世界的问题。
当你想根据一条新信息更新概率时,贝叶斯定理可能会派上用场。
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 Twitter 上与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
** **
解释贝叶斯定理
原文:https://towardsdatascience.com/bayes-theorem-explained-1b501d52ae37?source=collection_archive---------5-----------------------
数据科学基础
贝叶斯统计简介
贝叶斯定理提供了一种在有新信息时计算事件更新概率的方法。简单来说就是条件概率的一种计算方式。在这篇文章中,我们将看看贝叶斯定理的概述,然后我们将把这个定理应用到一个简单的问题上。

davisuko 在 Unsplash 上拍摄的照片
1.贝叶斯定理概述
我们可以使用贝叶斯定理通过以下公式找到条件概率:

贝叶斯定理公式
这些组件有特殊的名称:

‘一’是利益的事件。作为起点,P(A)代表我们的先验信念:事件 A 发生的概率。利用新证据 B,将后验置信或更新的概率表示为 P(A|B):给定证据 B 的事件 A 已经发生的概率。
我们可以从更常见的条件概率公式中自己推导出这个公式。事件 A 的概率给定事件 B 由下式得出:

等式 1
使用相同的公式,让我们看看给定 A 的 B 的逆概率:

等式 2
如果我们重新排列这个等式,我们会看到:

重新排列的等式 2
现在,如果我们用重新排列的等式 2 替换第一个等式的分子,我们就得到贝叶斯定理的公式。

有些问题我们不会知道 P(B)。这意味着我们需要在求解 P(A|B)之前找到 P(B)。在这种情况下,公式可以扩展为:

现在,让我们看一个应用定理的例子。
2.例子
让我们假设有一种疾病,在一个村庄的 33%的人口中发现。诊断测试具有 86%的敏感性和 79%的特异性。我们想知道如果一个病人检测结果呈阳性,他患病的概率。
2.1.直观地解决它
首先,让我们用直觉来解决这个问题。在这样做的同时,我们希望将概率转化为计数。首先,让我们假设这个村庄有 21 个居民。为什么是 21?因为一幅图像中的 21 只熊猫看起来很合适。任何数字都可以。一般来说,10 的倍数如 100 或 1000 是好的。
📍我们知道的第一条信息是: “有一种疾病,在一个村庄 33%的人口中发现”

有 7 个居民得了这种病。所以剩下的 14 个居民没有患病。让我们想象一下居民们:

全村居民|作者图片
在这里,这两种熊猫代表了某人是否得了这种病:

📍我们知道的第二条信息是: “一个诊断测试有 86%的灵敏度”
这意味着 86%的患病者得到了阳性结果。

患病的 7 名居民中,有 6 人检测呈阳性。所以剩下的一个居民被错误地检测为阴性。

疾病患者|作者图片
在这里,绿光代表阴性测试结果,而红光代表阳性测试结果。
📍我们知道的最后一条信息是: “一个诊断测试有 79%的特异性。
这意味着 79%没有患病的人得到了阴性结果。

在 14 名未患病的居民中,有 11 人检测结果呈阴性。所以剩下的三个居民被错误地检测为阳性。

无病者|作者图片
我们试图回答的问题是:

如果我们观察人群中被检测为阳性的子集,答案就显而易见了:

那些测试过的正面|作者图片

因此,如果测试结果呈阳性,一个人有 67%的概率患有这种疾病。换句话说,虽然一个人一般有 33% (先验)的患病几率,但一旦检测出阳性(证据),患病的概率就会增加到 67% (后验)。说一个人即使被检测为阳性,仍有 33%的机会患病是愚蠢的。
2.1.用贝叶斯定理解决它
现在,让我们用贝叶斯定理公式来解决它:

由于我们想知道在检测结果为阳性的情况下,患某种疾病的概率,我们可以将事件定义如下:
◼️ 事件 A: 患病
◼️ 事件 B: 检测结果为阳性

虽然我们知道分子中的值,P(正):得到阳性检验的概率并不容易提供给我们。所以我们可以使用扩展公式:

这意味着:

我们知道以下情况:

现在,我们可以将这些值代入公式:

我们得到了同样的答案,但是以一种更简洁的方式。

卢卡斯·乔治·温迪特在 Unsplash 上拍摄的照片
您想要访问更多这样的内容吗?媒体会员可以无限制地访问媒体上的任何文章。如果你使用 我的推荐链接 ,成为会员,你的一部分会费会直接去支持我。
希望你已经对贝叶斯定理有了一些直觉。感谢您阅读我的文章。如果你感兴趣,这里有我其他一些帖子的链接:
◼️️ 比较随机森林和梯度推进
◼️️ 决策树是如何建立的?
◼️️ 管道,ColumnTransformer 和 FeatureUnion 说明
◼️️ FeatureUnion,ColumnTransformer &管道用于预处理文本数据
再见🏃 💨
医学检验的贝叶斯定理
原文:https://towardsdatascience.com/bayes-theorem-for-medical-test-f1fb12b579c6?source=collection_archive---------9-----------------------
理解医学检验的贝叶斯定理。解释结果和更多测试的组合

照片由 Testalize.me 在 Unsplash 上拍摄
B 阿耶斯定理是统计学中的主要定理之一,也是科学中应用最广泛的公式之一。
直到上世纪中叶,它的重要性一直在稳步增长。现在,它被认为是所有统计学课程的基础,应用于几乎所有的研究领域,而不是工业领域。
乍一看,贝叶斯定理似乎令人困惑,并且常常难以理解,而这在本质上并不容易的统计学领域已经存在。
然而,如果我们分析引导贝叶斯得出他的定理的思维过程,我们会看到这些是自然的和逻辑的思维方式。
定理
贝叶斯定理是以托马斯·贝叶斯牧师的名字命名的。大约在 1740 年,贝氏进行了一项思维实验:他想象自己背靠一张平的方形桌子,把一个球发射到桌子上,但不知道球会落在哪里。
然后,他想到发射第二个球,这次问他的助手球是落在第一个球的左边、右边、前面还是后面。使用这个系统,他能够缩小每次新发射的第一个球的位置。
使用这种系统不可能准确地知道第一个球落在哪里;但是它创造了一种方法,或者说一种思维方式,通过这种方法,每一个新的证据都可以提高估计值。这是他的定理创造的最有趣的范式转变之一
贝叶斯从未发表过他的想法。在他 1761 年去世后,他的朋友理查德·普莱斯发现了他的笔记并扩展了它们。通过应用现代标准,我们应该把这个定理称为贝叶斯价格定理。然而,尽管普莱斯做了工作,这个定理仍然不为人知,直到被皮埃尔·西蒙·拉普拉斯重新发现。他重新陈述了定理给出了“(给定一个事件)原因的概率与事件(给定其原因)的概率成正比”。
用更现代的话来说:贝叶斯定理描述了一个事件发生的可能性,基于可能与该事件相关的条件的先验知识。
经典表示
该公式最经典的表示如下:

贝叶斯定理(作者图片)
其中 A 和 B 是我们想要分析的两个事件,并且:
- P(A)和 P(B)是事件 A 和事件 B 的不同且独立的概率。A 是假设为真的概率。 P(A)是前面的。
- P(B) 是看到证据的概率。这个元素叫做。**
- P(A|B) (读作:A 的 P 使得给定 B 的 P 的 B)是条件概率,因此,事件 A 的概率,给定事件 B 已经发生(为真)。这被称为概率** 或条件概率。**
- 反之亦然, P(B∣A) 是 b 给定 a 的概率.假设为真时看到证据的概率。这种可能性被命名为。
因此,该公式将先验概率与后验概率联系起来,并有可能将新的观察结果整合到基于先前观察结果的已建立模型中。
典型的例子
让我们从一个简单的例子开始,看看当我们拥有所有需要的信息时,贝叶斯定理是如何工作的。
让我们考虑一所由 60%的男生(B)和 40%的女生(G)组成的学校,其中所有的男生都留着短发,而留长发的女生(L)和留短发的女生的比例相等(50/50)。
我们遇到了一个剪短发的学生。 学生是女生的概率有多大?
发型事件与学生的性别有关,因此这些是我们的因变量。学生的性别是自变量。
- 考虑到整个学校,学生剪短发(事件 S)的概率是所有男生加上一半女生:P(S)=60%+(40/2)%=80%
- 假设学生是女生,留短发的学生的相关概率为:P(S∣G) = 50%
这是因为女生在长发和短发之间平分秋色。 - 假设学生是男生,留短发的学生的相关概率是:P(S∣B)=100%
因为所有男生都留短发。
我们现在可以应用公式来计算条件概率:**
p(g∣s)= p(g)p(s∣g)/p(s)= 0.4×0.5/0.8 = 0.25→25%
综上,留短发的学生是女生的概率是 16%。
理解医学测试的贝叶斯定理
为了评估诊断测试的性能,我们需要使用通常所说的混淆矩阵。这是一个简单的 2 乘 2 表格网格,其中计算了测试的预测与患者的真实情况。

混乱矩阵(图片由作者提供)
如果患者被预测为阳性,并且确实受到疾病的影响,则称之为真阳性。**
与之相反的是真阴性,患者是健康的,并且预测如此。**
剩下的元素是夫妇假阳性,被认为受影响但健康的人和假阴性,被认为健康但患病。**
很容易看出最后两种在医学上是最危险的。一个假阳性的个体最好的情况是受到惊吓,最坏的情况是不需要治疗。假阴性反而会推迟必要的治疗。
医学悖论
让我们看一个医学测试和逻辑错误的例子,这种逻辑错误经常被称为医学悖论,尽管这种说法并不恰当。
让我们假设我们有一个医学测试,它被宣传有 99%的准确率,对于一种影响 0.1%人口的疾病。如果在 10 万人身上进行。该测试有以下结果:

对 10 万人的测试结果(图片由作者提供)
我们想了解:
测试 P(+)结果为阳性,以及受疾病 P(D|+)影响的概率是多少?
给定 99%的测试准确度,我们可能认为有 99%的测试是准确的。但是贝叶斯定理告诉我们一些其他的东西。让我们看看如何:
让我们找到贝叶斯定理的所有元素:
- 被疾病感染的概率(D),未经检验等于它在人群中的传播,这是先验假设: P(D) = 0.1%。**
- 与之相反,不患此病的是: P( D) = 1-P(D) = 99.9%
- 测试结果为阳性的概率是所有阳性结果的总和除以品尝的总人数:(97+999)/100,000 = P(+) = 1.096%
- 与之相反的是 P(-) = 1-P(+) = 98.904%
使用混淆矩阵,我们可以构建另一个矩阵来帮助我们解决问题:

(图片由作者提供)
如果我们计算一下,这相当于:
- TPR 通常被称为灵敏度,代表 P(+|D),等于 97%。
- TNR 或更一般的特异性,因此 P(-| D)等于 99%。
- FNR 也称为遗漏率,P(-|D)等于 3%。
- FPR 已知虚警 P(+| D)的概率为 1%
在这些指标中,灵敏度和特异性是与医学测试最相关的指标,通常最好有一项测试能预测更多的 FP 而不是 FN,因为通常会进行第二次测试来确认疾病,而几乎没有人想再次检查他们是否没事。**
回到我们的问题,看看在测试呈阳性时感染该疾病的概率是多少,我们可以在以下公式中看到所有结果:
- P(D|+)= P(+|D) P(D)/P(+) → 8.9%
- P( D|+) = P(+| D) P( D) /P(+) → 91.1%
- P(D|-) = P(-|D) P(D)/P(-) → 0%
- P( D|-) = P(-| D) P( D)/P(-) → 91.1%
我们可以看到,如果我们以 99%的准确度测试阳性,我们仍然有 91%的概率 P( D|+)健康,只有 9%的概率 P(D|+)患病。这比 99%更不可怕。
鉴于我们的测试和疾病的传播,有 1.1%的人测试呈阳性,只有 9%的人在测试中实际患病。
给定两个阳性测试的患病概率
然而,让我们想象我们想要使用相同的程序做第二个测试。
鉴于两次阳性检测,受影响的概率有多大?
首先,我们需要计算两次结果为正的概率。应该是:
P(++) = P(+│D) P(D)+P(+│ D) P( D)
如果我们计算一下,结果会是:0.0010408
现在,为了计算 P(D|++ ),我们将使用以下公式:

给定两个阳性和相等测试的患病概率(图片由作者提供)
现在的结果是:90.4%
这意味着我们几乎可以肯定,如果进行第二次阳性测试,结果是正确的。我们可以通过增加第三个测试等等来尝试。
贝叶斯测试的美妙之处在于,我们可以根据新的测试来更新我们的信念。
简单解释的贝叶斯定理
原文:https://towardsdatascience.com/bayes-theorem-simply-explained-17217ebc39ff?source=collection_archive---------27-----------------------
如果无知是福,知道如何处理不完整的知识是关键。贝叶斯定理将所有这些形式化。
贝叶斯定理形式化地描述了在我们对影响事件实现的其他因素的不完全了解以及我们预先存在的信念的情况下,如何计算事件发生的概率。比如今天天阴的话会下雨吗?
让我们从一些基本定义开始。事件 A 发生的概率是一个介于 0 和 1(或 0%和 100%)之间的数字,在数学上由某个函数 P(A)表示,称为边际概率,即,与其他事件无关。如果我们同时考虑两个事件 A 和 B ,那么这个概率就是一个二维函数 P(A,B)称为联合概率。值得注意的是,它是对称的,意味着 P(A,B) = P(B,A)。如果这两个事件完全不相关,那么它分解为 P(A,B) = P(A)*P(B)。
接下来我们可能想知道的是,在已知 B 已经发生的情况下,事件 A 发生的概率是多少。这叫做条件概率,用一个函数 P(A|B)来描述。统计学中有一个著名的原理叫做乘积法则告诉你如何从条件事件的联合概率 P(A,B)和边际概率即 P(B)推导出条件概率 P(A|B)。这其实很简单:
P(A|B) = P(A,B) / P(B)
除以 P(B)确保概率在 0 和 1 之间。值得注意的是,条件概率是而不是对称的,这意味着通常 P(A|B) ≠ P(B|A)。例如,阴天下雨的可能性(例如 30%)比下雨时阴天下雨的可能性(例如 99%)要小。
这些关系很容易颠倒过来:
P(A,B) = P(A|B) * P(B)
P(B,A) = P(B|A) * P(A)
这基本上说明了联合概率是掌握系统完整信息的关键。
问题是,在大多数情况下,我们对某个过程的知识是不完整的,这意味着我们无法获得联合概率 P(A,B)!另一方面,在假设事件 B 为真的情况下,我们通常对事件 A 的发生有一些了解,并且我们可能对事件 A 总体发生的可能性有一些预先存在的想法。然后,由德高望重的托马斯·贝叶斯设计的一个定理来拯救我们,告诉我们如何在两个条件概率之间“切换”,即:
P(B|A) = P(A|B) * P(B) / P(A)
这很容易通过认识到以下几点得出:
P(A|B) * P(B) = P(A,B)
P(B|A) * P(A) = P(B,A) = P(A,B)
=>
P(A|B) * P(B) = P(B|A) * P(A)
=>
P(B|A) = P(A|B) * P(B) / P(A)
在贝叶斯统计行话中,P(B|A)是后验概率(我们要计算的),P(A|B)称为似然,P(B)称为先验概率,归一化因子 P(A)是边际似然或模型证据。简单地说,可能性编码了事件 A 在一些假设 B 下可能发生的概率,先验是我们相信 B 实际上是可能的。稍微延伸一下:假设我们已经观察到了看起来像是奇迹的东西,并且我们相信不管上帝是否存在,奇迹都会发生,那么上帝存在的概率是多少?也许这就是托马斯·贝叶斯在考虑的事情。
总结一下:
- 联合概率:P(A 和 B) = P(A,B) = P(B,A)
- 条件概率:P(给定 B)= P(A|B)
- 乘积法则:P(A|B) = P(A,B) / P(B)
- P(A|B) * P(B) = P(A,B) = P(B,A) = P(B|A) * P(A)
- P(B|A)= P(A|B)*P(B) / P(A)(贝叶斯定理)

两个变量之间的联合概率分布示例及其沿 x -和 y 轴绘制的相应裕量概率分布(左),以及 X2 固定为给定值时 X1 的条件概率分布示例(右)。图片作者。
如果你正在阅读这篇文章,可能是因为你听说过朴素贝叶斯分类器及其在拒绝不需要的电子邮件方面的成功。它是如何工作的,为什么它是“天真”的?
首先,我们在谈论一个分类器,它是一个统计模型,根据一些特征向量 X 的值将实例分成不同的(通常是互斥的)类别。在上面提到的例子中,特征可以是是否下雨,类别可以是是否应该带伞。贝叶斯定理的完全应用将需要相当多的计算,例如归一化因子 P(X)的计算,这通常意味着在多维特征空间上运行马尔可夫链 蒙特卡罗积分。然而,在大多数应用中,我们只想知道类别,而不是(归一化的)概率。这样,定理可以简化为:
P(umbrella | X ) ∝ P(X | umbrella) * P(umbrella)
另一个大问题是特性 X 之间的相关性。在现实生活中,湿度、温度和一天中的时间之间存在相关性,分类器应该在优化步骤中考虑这一事实。例如,湿度的增加可能与温度的增加相关。然而,在实践中,经常会出现这样的情况,即输入要素被处理或设计成其相关性实际上非常小或可以忽略不计。如果是这样,那么可能性(记住这是一个条件概率!)分解为:
P(X|umbrella) = P(rainy|umbrella) * P(cloudy|umbrella) * P(humid|umbrella) * P(hour|umbrella)
因此,对于特征向量的给定实例 X = ( X _1, X _2, X _3, X 4),算法只需找到 P(雨天=X 1 |雨伞)、P(多云= X _ 2 |雨伞)等的最大值..然后将这些因素相乘:
umbrella = argmax_j P(umbrella_j) * Prod_i[ P(X_i|umbrella_j) ] = max{
P(Y) * P(X_1|Y) * P(X_2|Y) * P(X_3|Y) * P(X_4|Y),
P(N) * P(X_1|N) * P(X_2|N) * P(X_3|N) * P(X_4|N)
}
在许多情况下,处理一个可能有上百个特性的产品会导致数值不稳定或内存溢出。然后,通常采用产品的负对数,而不是最小化函数:
-logP(X|umbrella) = -logP(umbrella) - log(P(X_1|umbrella) - log(P(X_2|umbrella) - log(P(X_3|umbrella) - log(P(X_4|umbrella)
总之,贝叶斯定理是一种计算给定事件 A 的概率的正式方法,这种方法基于对其与其他事件 B _1、 B _2、……以及我们先前的信念的不完全了解。它在统计学中的重要性不能被夸大,它的应用无处不在。我们在这里讨论了朴素贝叶斯分类器,这是一种流行的方法,例如在 scikit-learn 库中实现的方法。我在之前的文章中也讨论过如何用贝叶斯优化来训练神经网络。
贝叶斯定理——机器学习的核心
原文:https://towardsdatascience.com/bayes-theorem-the-core-of-machine-learning-69f5703e511f?source=collection_archive---------21-----------------------
机器学习基础
贝叶斯定理的一个例子及其重要性

作者形象
许多机器学习模型试图以某种方式估计后验概率。监督机器学习模型的训练可以被认为是利用所接收的每个数据点来更新估计的后验。这句话是理解机器学习的关键,要想完全理解它的意义,首先必须理解贝叶斯定理。
贝叶斯定理在数据科学中应用广泛。它构成了机器学习文献的基础。这篇文章形象化了一个小例子,以帮助形成对定理的直观理解。
贝叶斯推断
贝叶斯推断是基于新信息更新结果概率的过程。在收到此信息之前,我们可能预先相信某个事件正在发生。然而,一旦我们收到新的信息,结果的概率可能会改变。正确更新结果概率的方法是通过贝叶斯推断。
贝叶斯定理指出,后验概率(给定所接收的新信息的事件概率)与看到新信息的可能性乘以先前的信念成比例。在机器学习领域,后验概率和先验概率之间的这种比例关系是反复出现的。
贝叶斯推理示例
假设你在面试时被问到以下问题:
乔是一名大学工科学生。试着从下面的陈述中猜测他是否会在他的学士课程中获得一等奖:
“乔最近的一次任务刚得了第一名。乔是个好学生,工作努力”
大多数人可能会认为,乔更有可能获得第一名。让我们编一些数字,应用贝叶斯定理。
- 乔的班上有 100 名学生
- 10 末会得到第一个学士
- 在总共 10 名将获得第一名的学生中,90%符合上述说法
- 在这 90 位没有获得第一的人中,只有 20%符合上面的说法

作者形象
在上图中,底部是随机学生获得第一名的概率。如前所述,这是 10%,并显示为 P(C1)。在这些学生中,90%的人符合这一说法,他们是 P(s|C1)。在没有获得第一名的人中,只有 20%的人符合这个标准,P(s|C2)。
橙色区域是将获得第一个并符合陈述的人员。在“绿色区域”中的是不会获得第一个总体评分但也符合该陈述的学生。
我们知道乔符合这种说法,所以他要么处于有利地位,要么处于不利地位。Joe 出现在橙色区域的概率就是用橙色区域除以橙色和绿色区域之和:

后验概率与似然性乘以先验概率成正比。给定陈述,乔获得第一名的概率是符合陈述的学生获得第一名的概率,除以符合陈述的学生人数。
在实践中,分母通常称为 P(s),即该陈述为真的学生数。然而,人们几乎总是最终将分母扩展成上面看到的形式。
我们可以把数字代入,看看乔是否会得第一名:

因此,在给出的陈述中,乔获得学士学位的概率只有 33%。即使这句话对得第一名的人来说是正确的 4 倍多,因为只有少数学生得第一名,乔得不到第一名的可能性仍然更大。显然,这是一个愚蠢的例子,我编造了这些数字,但你会明白为什么这种问题可能是反直觉的,为什么贝叶斯推理是如此有用。
结论
现在你可以去看看这篇文章的最初陈述,希望它能给你一个关于机器学习的新视角。
贝叶斯推理、贝叶斯分类器和估计后验概率很容易成为我在机器学习中最喜欢的话题。要理解更复杂的算法,理解这个简单的规则是极其重要的。如果你想了解这个话题的更多内容,可以去 youtube 上的 3Blues1Brown 看看,他对贝叶斯定理有很好的解释,并给出了自己的例子。
支持我
希望这对你有帮助,如果你喜欢它,你可以 跟我来!
您也可以成为 中级会员 使用我的推荐链接,访问我的所有文章和更多:https://diegounzuetaruedas.medium.com/membership
你可能喜欢的其他文章
可微发电机网络:简介
傅立叶变换:直观的可视化
贝叶斯 A/B 测试在 5 分钟内完成
原文:https://towardsdatascience.com/bayesian-a-b-testing-and-its-benefits-a7bbe5cb5103?source=collection_archive---------2-----------------------
什么是贝叶斯 A/B 测试,什么时候应该使用它?

A/B 测试的困境。图片作者。
最近,贝叶斯 A/B 测试得到了大量的宣传,因为它的方法易于理解,并允许有用的计算,如治疗优于控制的概率。贝叶斯推理在小样本上也表现得更好;根据 2019 中期帖子,贝叶斯 A/B 测试可以减少 75%的所需样本量。
虽然这些方法在计算上比传统的 frequentist 方法更昂贵,但是它们是离线计算的,这降低了性能要求。主要的挑战是选择有效的分布来支持推理。
任何拥有实验管道和计算机的人都可以利用贝叶斯 A/B 测试技术。以下是如何…
贝叶斯 A/B 测试的步骤
- 根据您的兴趣选择您的发行版。这里,我们讨论二项式、多项式和指数分布。它们涵盖了大多数业务用例。
- 计算你的先验。基于上面选择的分布,我们接下来选择一个共轭先验,并选择最能反映我们预实验数据的分布参数。分布参数可手动选择或使用库选择。
- 运行实验。
- 使用蒙特卡罗模拟计算三个关键指标。这些指标是提升百分比、最佳概率和预期损失。
但是,到底是怎么回事呢?
好了,让我们慢下来,了解一下到底发生了什么。
贝叶斯统计
从第一格开始,我们来说说贝叶斯推断是什么。一句话,贝叶斯推理利用条件概率来帮助我们理解数据如何影响我们的信念。

贝叶斯方法。图片作者。
假设我们从天空是红色的先验信念开始。看了一些数据后,我们很快就会意识到这种先前的想法是错误的。因此,我们执行贝叶斯更新来改进我们关于天空颜色的不正确模型,最终得到一个更准确的后验信念。
似然分布和共轭先验
我们信念的一个关键组成部分是我们数据的结构。我们经常通过分布来描述这种结构。例如,在我们的天空例子中,假设有各种颜色(红色、白色、蓝色等。),我们的分布将是多项式。如果我们看一组数字,我们的分布可能是正态。如果数据是真/假值,它将是二项式,等等。
这些分布被称为似然分布,因为它们显示了我们的数据呈现某个值的可能性。
对于我们的天空例子,我们正在处理一个多项式分布,但是还有一个分布我们需要考虑。当执行贝叶斯更新时,我们必须考虑概率分布的共轭先验分布。共轭是来自同一个家族的分布。对于我们的情况,多项式分布的共轭先验是狄利克雷分布。
共轭先验是我们数据的可能性分布的来源。例如,如果我们正在抛硬币,那么二项式分布显示了抛硬币的次数 n 看起来像是正面的概率 p 。但是,往往 p 本身就有分布。 p 的分布是共轭先验分布。
好吧,那是很多,但是如果你想继续学习共轭先验,这里有一个来自麻省理工学院的很好的资源。
让我们继续将这些发行版用于不同的业务应用程序。
商业中常见的分配
通常,我们可以在业务环境中观察到三种主要类型的数据(尽管其他分布也是有用的):
- 二进制:用户有一个选项可以选择的数据。
- 分类:用户有一组选项可供选择的数据。
- 连续:用户有一组选项可以选择的数据,但是我们只观察这些选项的集合。
对于二进制数据,让我们举一个在线 ML 教科书商店转换的具体例子。 Conversion=1 表示用户购买了一本书,而 conversion=0 表示他们没有购买。
在这个场景中,二项式分布描述了我们的数据。二项式的共轭先验是 beta 分布,下面可以看到这两个分布。

具有不同超参数值的贝塔(上)和二项式(下)。图片作者。
转到我们的第二类数据,分类数据的似然分布是多项式,它的共轭先验是狄利克雷。因为这些图通常是高维的,所以我们不打算展示可视化。
最后,对于连续数据,我们使用带有伽玛共轭先验的指数分布。如果你想知道它们长什么样,可以看看这些链接。
很简单,对吧?根据数据类型,只需应用这些分布就可以了。
贝叶斯统计计算
现在我们已经了解了如何为我们的实验选择一个分布,让我们学习如何确定实验影响。我们通过计算三个统计数据来做到这一点:
- 治疗电梯
- 成为最佳的可能性
- 预期损失
对于我们的第一个计算,治疗提升仅仅是我们的治疗和控制之间的百分比变化。这是我们的治疗效果,可以用下面的公式计算。为了简单起见,让我们假设只有一种治疗和一种对照。
treatment_lift = (treatment - control) / control
对于我们的第二次和第三次计算,我们需要开发一个蒙特卡罗模拟。为什么你会问?因为我们只有一个数据样本,所以我们无法计算任何概率——我们不知道数据在其他样本中会是什么样子。因此,为了生成更多的数据,我们利用了关于我们的数据生成机制(后验分布)的知识和来自该机制的样本。10,000 个样本是一个很好的经验法则。
对于我们的第二个统计数据,即最佳概率,我们只需查看所有模拟样本,并计算我们的处理优于我们的控制的时间百分比。这个比例成为我们的最佳治疗的概率。查看下面的 pythonic 伪代码。
# probability best of treatment
samp_treatment = sample_from_distribution(treatment_dist, n=10000)
samp_control = sample_from_distribution(control_dist, n=10000)probability_best = mean(int(samp_treatment > samp_control))
最后,对于我们的第三个统计,我们希望计算预期损失,即我们为实施不正确的治疗所付出的代价。为了计算预期损失,我们迭代样本并计算 max(treat - control,0) 。然后,我们取这些零界值的平均值来确定我们的预期损失。
# pythonic pseudo code - expected lossloss = mean(max(samp_control - samp_treatment, 0))
预期损失和最佳概率是贝叶斯实验的两个主要卖点。Frequentist 方法不提供任何值。
有关这些计算的详细信息,请查看这篇帖子。
现在你知道了!
实施说明
- 如果你选择一个有效的先验,贝叶斯 A/B 测试需要一个较小的样本量,这样你可以更快地得到结果。
- 贝叶斯方法比频率主义方法计算量更大。
- 当选择先验时,偏向弱先验,即较小的超参数值。
感谢阅读!我将再写 46 篇文章,将“学术”研究引入 DS 行业。查看我对贝叶斯 A/B 测试的链接/想法的评论。
贝叶斯 A/B 测试解释
原文:https://towardsdatascience.com/bayesian-a-b-testing-explained-344a6df88c1a?source=collection_archive---------10-----------------------
用 Python 实现解释贝叶斯 A/B 测试

来自水花的图片由亚历山德罗·克罗斯托
A/B 测试在各个行业都有很多应用。从试图确定最佳市场群体到医疗药物测试,它有各种应用,并允许企业根据结果做出决策。有两种常用的方法来进行 A/B 测试,频率主义方法和贝叶斯方法,这两种方法都是从假设测试的基础开始的。在本文中,我将介绍贝叶斯方法在 A/B 测试中的解释和实现。这篇文章假设你对实践中的 A/B 测试有一个很好的理解,如果没有,你可以在这里了解更多关于它和频率主义方法。
目录
- 贝叶斯方法
-贝叶斯机器学习 - 贝叶斯 A/B 测试
-探索漏洞利用困境 - 问题陈述
- 贝叶斯班迪特/汤普森采样
-贝叶斯定理
-贝塔分布 - 履行
- 结束语
- 资源
贝叶斯方法
贝叶斯方法源于一个主要规则,即一切都是随机变量。例如,如果给定某个数据集,并要求您查找数据的平均值和方差,您的输出将只是一个映射到平均值的数值和一个映射到方差的数值。然而,在贝叶斯方法中,你不再寻找一个数字,而是一个分布。
When trying to identify the mean, you can see the difference of approaches below :
Frequentist : ῦ
Bayesian : p(ῦ | data)
贝叶斯机器学习
如果你从机器学习的角度来考虑这个问题,那么你可以看到 A/B 测试在直觉上与强化学习非常相似。强化学习指的是允许代理在一个环境中采取行动,以最大化奖励的概念。A/B 测试可以被视为一组随机实验,随机划分用户,以最大化某些回报。
例如,如果我们要用 A/B 测试对网站上两个按钮的点击率进行建模,不同按钮的不同布局可以被定义为一个动作,点击率的增加可以作为一种奖励。我们想选择一个布局,将最大限度地提高点击率。
贝叶斯 A/B 测试
给定一些数据,贝叶斯程序可以概述为以下步骤[1]:
- 确定先验分布(高斯、泊松、贝塔等。),这表达了我们在看到任何数据之前对参数(例如ῦ)的初步理解
- 选择一个统计模型(马尔可夫链,贝叶斯土匪等。)这反映了我们对给定ῦ的 x 的信念
- 在观察一些数据后,更新我们的信念并计算后验分布 p(ῦ | x)。后验分布是一种概率分布,它描绘了在观察数据后您对参数的更新信念。
可以想象,观察次数(N)越大,你的后验分布的近似值就越好。然而,如果你的观察次数太多,你会失去很多可以为你的网站带来收入的印象。例如,如果你正在为你的网站运行 A/B 测试,以确定哪个(两个)登陆页面产生非常高的点击率,那么你做的样本越多,你接触到的登陆页面的人就越多,这将减少你可能获得的点击次数。因此,样本大小既不太大也不太小是理想的。
探索漏洞利用困境
在强化学习中,当代理通过评估可能导致积极结果的场景来收集信息时,被称为探索。在探索之后,人们学习在给定当前已知信息的情况下具有最高可能结果的最优决策,这被称为开发。最好是平衡剥削,和剥削。
问题陈述
假设您想要测试在您的平台上创建用户的两个不同的位置。你的位置 1 位于网站的左上角,而位置 2 位于右上角。两个登录页面之间唯一的区别是注册按钮在两个不同的位置,其他都是一样的,我们的实验是 iid 。
贝叶斯土匪/汤普森抽样
在我们探索贝叶斯强盗算法之前,我们需要对贝叶斯定理和贝塔分布做一点回顾。
贝叶斯定理

图片由 Tirthajyoti Sarkar 提供从这里
本质上,后验~似然*先验
贝塔分布
这是一个以区间[0,1]为界的连续概率分布,取决于两个参数 α 和 β。两个 α 和 β 都必须为正。在不涉及算法的情况下,贝塔分布的概率密度函数可以用下面的公式来模拟:

图片由作者提供
要获得更详细的解释和推导,请访问维基百科的测试版页面这里。

该动画展示了β分布如何随着其参数α和β的不同值而变化。来源: Pabloparsil 来自维基百科
现在我们可以探索贝叶斯土匪/汤普森采样算法。为了这个实验的目的,让我们假设我们知道位置 1 和位置 2 的点击率概率。当然,在现实世界的例子中,这不会发生,但为了评估我们的算法在这种情况下的表现,让我们说p(pos1) = 0.1和p(pos2) = 0.55
既然我们没有任何现存的观察,我们就不可能有任何先验的信念。为了模拟我们的先验概率,我们可以使用α = 1 和β=1 的β分布。这将是[0,1]域上的均匀分布。我们选择均匀分布,因为我们不知道结果可能是什么,因此我们给每一个可能的值相等的概率。注意,对于行业场景,如果您有可用的先验知识,那么您应该在您的实现中使用这些先验知识。
对于这种方法,一步中的后验成为下一步中的先验,我们的后验和先验都可以通过 beta 建模。
** Beta * Data = Beta**
|____| |____|
prior posterior
实施
请注意,由于分布的随机抽样,您的实现可能会有稍微不同的结果。


如你所见,该算法很快收敛到最佳分布。根据这个实验的结果,很明显位置 2 比位置 1 更好,应该是你网站上注册按钮的位置。
结束语
频率主义者和贝叶斯方法的主要区别在于贝叶斯认为参数是随机变量。进行 A/B 测试的步骤贝叶斯方法是确定你的先验分布,选择一个统计模型,并计算和更新你的后验分布。一般来说,贝叶斯方法比其他传统的 A/B 测试收敛得更快。这意味着需要更小的样本才能得出结论。
资源
- [1]http://www.stat.cmu.edu/~larry/=sml/Bayes.pdf
- [2]https://jamesmccaffrey . WordPress . com/2017/11/30/the-epsilon-greedy-algorithm/#:~:text = In % 20 short % 2C % 20 epsilon % 2d greedy % 20 means,the % 20 multi % 2d armed % 20 bandit % 20 problem。
- [3]https://www . dynamic field . com/lesson/Bayesian-approach-to-ab-testing/
- [4]https://towards data science . com/intro-to-reinforcement-learning-the-explore-exploit-dilemma-463 CEB 004989
- https://web.stanford.edu/~bvr/pubs/TS_Tutorial.pdf
- [6]https://github . com/lazy programmer/machine _ learning _ examples/tree/master/ab _ testing
如果您喜欢这篇文章,您可能也会感兴趣:
PyMC3 中的贝叶斯 A/B 测试
原文:https://towardsdatascience.com/bayesian-a-b-testing-in-pymc3-54dceb87af74?source=collection_archive---------5-----------------------
贝叶斯统计
抛弃 p 值,拥抱更直观的概率

由 OpticalNomad 在 Unsplash 上拍摄的照片
有时,你不得不在两个选项中做出选择。这可能是在完全不知情的情况下,你只有 50%的可能性做出更好的选择。在一些不知情的情况下,你甚至可以用一个简单的技巧来提高这个概率,正如我在另一篇文章中所展示的。
然而,通常情况下,你能够收集一些信息帮助你选择更好的选项。一个简单而聪明的方法是 A/B 测试,你可能已经听说过或者已经使用过了。

两个实验的结果。是 A 还是 B 产生的价值更高?你对此有多确定?图片由作者提供。
在本文中,我将简要解释 A/B 测试背后的动机,并概述其背后的逻辑。这种方法的问题在于它使用了容易被误解的 p 值。
因此,我们将花时间用少许贝叶斯魔法来改进这种方法,产生贝叶斯 A/B 测试。最重要的是,我们将使用 Python 中出色的 PyMC3 库实现一个简单的贝叶斯 A/B 测试。
如果您不完全确定什么是贝叶斯统计,或者您以前从未使用过 PyMC3,请查看我关于这个主题的入门级文章:
A/B 测试动机
假设您经营着一家相当成功的在线商店,每天有大约 10,000 名访问者。这 10000 人中大约有 100 人实际上在你的店里买了东西——你所谓的转化率大约是 100/10000 = 1%,相当小。
大多数网上商店的转化率在 1-3%左右,亚马逊甚至超过 10%。
因为无论如何都会有很多人光顾你的店铺,但只有很少一部分人成为顾客,所以你决定提高你的店铺的转化率,因为这是提高收入的最大杠杆。你认为:
是什么让人们不买我的好产品?
你想不出一个好的解释,所以你向一些朋友寻求灵感。他们告诉你,他们不喜欢你购买按钮的蓝色。也许红色会更吸引人?这是你可以测试的东西!

让战斗开始吧!图片由作者提供。
方法如下:
以 50%的概率随机将新访客分配到蓝队或红队。蓝队的人会看到蓝色按钮,红队会看到红色按钮。在运行这个过程一段时间后,您检查哪个团队实现了更高的转化率。
术语:你称蓝队对照组,红队治疗组或试验组。对照组给你一个指示,如果你让一切保持原样会发生什么,治疗组告诉你如果你做某种干预会发生什么,比如改变按钮的颜色。
请注意,如果您想轻松评估实验,这种随机化很重要。你应该而不是做的事情包括:
- 将所有男性分配到红色团队,将所有女性分配到蓝色团队,因为即使一个团队的转化率高得多,你也无法知道这是因为按钮的颜色还是仅仅因为性别。
- 本周将每个人分配到红色团队,下周分配到蓝色团队,因为即使一个团队的转换率很高,你也无法知道这是因为按钮的颜色,还是因为人们在一周内购买了更多的东西,而不考虑颜色。也许其中一周包括像黑色星期五或圣诞节这样的节日,或者其他更微妙的季节模式。
- …
你明白了。为了提取按钮颜色效果 ,应该没有其他混淆效果可以解释两个团队的不同转换率。
准备 A/B 测试
让我们假设您为您的 A/B 测试进行了一天的适当的数据收集,并最终获得了一些数据。你有 10,000 名访客,你将他们随机分为蓝队(对照组)和红队(治疗组)。你记下这位游客是否买了东西(编码为 1 )或没有买(编码为 0 )。
我们使用以下代码模拟结果:
import numpy as np
np.random.seed(0)
blue_conversions = np.random.binomial(1, 0.01, size=4800)
red_conversions = np.random.binomial(1, 0.012, size=5200)
你可以看到我把 1%作为对照组转化率,1.2%作为治疗组转化率。所以你已经知道,如果采样没有做什么奇怪的事情,红色按钮应该表现得更好!但让我们从现在开始假装我们不知道这些数据是如何产生的,因为这是我们在现实中经常面临的问题。
另外,请注意,这些组有不同的大小,这通常是随机分配的结果。他们在 10000/2 = 5000 左右,但不太可能得到如此完美的 50:50 分成。然而,这很好。
两个 NumPy 数组都由 1 和 0 组成,大多数条目都是 0。
print(blue_conversions)
# output: [0 0 0 ... 0 0 0]
print(red_conversions)
# output: [0 0 0 ... 0 0 0]
接下来,我们可以检查的是 one(即购买了某些东西的访问者)的份额。
print(f'Blue: {blue_conversions.mean():.3%}')
print(f'Red: {red_conversions.mean():.3%}')
# output: Blue: 0.854%, Red: 1.135%
这表明红色按钮的性能可能会更好,但我们现在还不能确定。即使不同组之间的转化率完全相同,一组最终的转化率也很可能比另一组高。
我们仍然必须排除这仅仅是由于偶然而发生的,这正是 A/B 测试的目的。
进行 A/B 测试
现在让我们看看我们如何能对正在发生的事情提出一个更好的解释。蓝色按钮好还是红色按钮好?首先,我们将再现传统的方式,然后,我们将做贝叶斯风格。
传统的方式
我不会在这里深入探讨,因为有大量的资源可以完美地解释如何进行一个普通的 A/B 测试。你想知道以下两个假设哪个是正确的:

图片由作者提供。
基本上,你计算某种测试统计,例如在费希尔精确测试或 T2 韦尔奇的 t-测试中。然后计算一个 p 值,并检查它是否在某个任意范围内,比如 5%。让我们来看看韦尔奇的 t 测试。
from scipy.stats import ttest_ind
print(f'p-value: {ttest_ind(blue_conversions, red_conversions, equal_var=False, alternative="less").pvalue:.1%}')
# output: p-value: 7.8%
因为有些人纠结于 p 值,你可以这样解读:
假设₀是真实的,我们得到我们观察到的或者更极端的结果的几率最多是 7.8%。
由于 7.8% > 5%,我们保持原假设。没有证据表明红色按钮明显比蓝色按钮好,所以我们只保留蓝色按钮。
我认为 p 值的定义相当不直观——每个曲解过 p 值的人都证明了这一点。最常见的误解如下:
蓝色更好的概率是 7.8%。(错!!!)
虽然这是 p 值告诉你的而不是,但是能够表达出这样一个清晰而简短的陈述是可取的,不是吗?好吧,那么,贝氏拯救。
贝叶斯方法
贝叶斯 A/B 测试有以下优点:
- 它使您能够以一定的概率做出一个版本比另一个版本更好的陈述。正是我们想要的。
- 你不需要知道所有的统计测试。您只需构建一个合适的生成模型,然后按下贝叶斯推理按钮。
我假设你现在已经有一些关于使用 PyMC3 的先验知识,否则,检查我上面的链接文章。
为了更清楚地说明这些优点,让我们借助 PyMC3 用贝叶斯方法来分析我们的问题。首先,我们需要考虑要推断哪些参数。这很容易,有两个未知参数:
- 蓝色按钮的转换率
- 红色按钮的转换率。
我们现在需要决定两个参数的先验分布。由于转换率可以在 0 到 1 之间,所以贝塔分布是有意义的。Beta 分布有两个参数 a 和 b,,你可以通过改变它们来创建不同的分布。

图片由作者提供。
因为我们知道转换率相当小,例如,两者的良好先验都是β(1,99)。

图片由作者提供。
现在,我们必须模拟我们观察到的结果(包含 0 和 1 的数组)是如何与这些参数联系起来的。最直接的方法是使用伯努利变量,因为它们只能取值 0 和 1,并使用单个概率参数。
长话短说,我们可以写下面的小程序:
import pymc3 as pm
with pm.Model():
blue_rate = pm.Beta('blue_rate', 1, 99)
red_rate = pm.Beta('red_rate', 1, 99)
blue_obs = pm.Bernoulli('blue_obs', blue_rate, observed=blue_conversions)
red_obs = pm.Bernoulli('red_obs', red_rate, observed=red_conversions)
trace = pm.sample(return_inferencedata=True)
加上解释,这个程序应该对你有意义。在模型的前两行,我们定义了先验知识。之后,我们设计模型的输出(伯努利变量),并使用observed参数额外给出来自 A/B 测试准备的观察结果。最后一行是著名的贝叶斯推理按钮的 PyMC3 版本。
在trace对象的帮助下,你可以重建转换率的后验分布。
import arviz as az
az.plot_posterior(trace)

图片由作者提供。
我们发现,蓝色的转化率约为 0.854%,红色的转化率约为 1.135%,这与我们的最大似然估计值非常接近,甚至还有一个可信的估计区间。比如蓝率在 0.62%到 1.1%之间,有 94%的概率。
整洁,对不对?但这并没有回答我们的问题。红色按钮的转化率比蓝色按钮的转化率高的概率有多大?为了回答这个问题,我们可以对两个后验分布进行采样,看看红色比率高于蓝色比率的频率。幸运的是,样本已经存储在trace对象中。我们只需了解红色速率样本比蓝色速率样本大的频率。
blue_rate_samples = trace.posterior['blue_rate'].values
red_rate_samples = trace.posterior['red_rate'].values
print(f'Probability that red is better: {(red_rate_samples > blue_rate_samples).mean():.1%}.')
# Output (for me):
# Probability that red is better: 91.7%.
这是我们可以合作的事情!这对我们来说很容易理解,但对其他所有人来说也很容易理解,我特别关注业务部门。红色按钮更好,概率在 92%左右。
完美!”,你想着和你店里的红版,希望它能提高你的转化率。

Uaaa,uaaa,uaaa。图片由作者提供。
现在想象一下:这只是一个微小的变化,却有可能增加你的销售额。可能有各种各样的或大或小的东西你可以修补,让你的商店更好。比赛刚刚开始。
结论
在许多情况下,我们不得不在两个选项中做出选择。这可以只是一个按钮的颜色,也可以是一个对象在网站上的位置,按钮或图像上的文本,或者任何可能被改变的东西。
在两个版本之间进行选择的一种方法是运行 A/B 测试。这个想法很简单:你把你的顾客分成两组,唯一不同的是你想改变的东西,也就是一个按钮的颜色。这样你就可以确定只有你改变的事情导致了结果的改变,其他的都没有。不是人们的年龄或性别,也不是你收集数据的工作日。
通常,人们使用 p 值进行经典的 A/B 测试。虽然这对于统计学家来说是一个熟悉的概念,但普通人经常会对涉及 p 值的陈述感到困惑。这就是为什么我们转向贝叶斯 A/B 测试,它允许每个人都可以很容易地掌握结果。最后,我们甚至可以用 PyMC3 不用太多代码就能得出这样的结果。
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何都要计划获得中等订阅量,
为什么不通过此链接https://dr-robert-kuebler.medium.com/membership?这将对我帮助很大!😊
说白了,给你的价格不变,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我的话!
有问题就在LinkedIn上写我!**
贝叶斯 AB 检验—第一部分—转换
原文:https://towardsdatascience.com/bayesian-ab-testing-part-i-conversions-ac2635f878ec?source=collection_archive---------13-----------------------

在 Unsplash 上庞浩文的照片
系列结构
在之前的一篇博文中,我讨论了使用贝叶斯 AB 测试方法而不是频繁测试方法的优势。在这一系列的博客文章中,我将更深入地研究相关的计算,以及如何在现实世界中实现它们。该系列的结构如下:
- 基于转换的测试度量(速率度量)的建模和分析
- 基于收入的测试指标的建模和分析
- 计算测试持续时间
- 选择一个合适的先验
- 用多个变量运行测试
因此,废话不多说,让我们进入如何在贝叶斯产品实验中建模、使用和分析基于转换的测试指标。
实验背景
根据在上一篇文章中使用的例子,让我们假设我们最近改变了追加销售屏幕上的信息,并希望在向更广泛的用户群发布之前进行 AB 测试。我们假设我们所做的改变将会带来更好的转化率。
与 frequentist 方法类似,我们可以将𝑋促销屏幕上的每次转换建模为伯努利随机变量,转换概率为𝜆:

在频率主义方法下,我们假设𝜆是一个常数,而在贝叶斯方法下,我们将其建模为一个随机变量,有自己的概率分布。我们的第一步是使用过去的数据为这个分布选择一个合适的近似值。我们称之为我们之前的𝜆.分布
然后,我们设定损失阈值,这是我们在犯错时愿意接受的最大预期损失。与任何统计建模一样,贝叶斯实验方法是建立在真实世界数据的近似值之上的。因此,我们总是有可能从测试中得出错误的结论。这个损失阈值让我们可以说,即使我们得出了错误的结论,我们也可以确信转化率不会下降超过我们可以接受的水平。
最后,我们以随机实验的形式抽取样本,并使用这些样本来更新分布,从而更新我们关于𝜆在追加销售屏幕的控制和治疗版本下的信念。我们可以使用这些后验分布来计算治疗优于对照组的概率以及错误选择治疗的预期损失。
所以我们的第一步是选择𝜆.的先验分布要做到这一点,我们可以看看我们最近(过去几周)收集的关于这一转换的数据。我生成了一个样本先验数据集,我们可以用它来做这个练习。
import pandas as pdprior_data = pd.read_csv('prior_data.csv')
print(prior_data.head())
print(prior_data.shape)

因为这个数据集是人工生成的,所以它已经是这个练习的理想格式。在现实世界中,我们可能需要执行一些 ETL 操作来获得这种格式的数据。然而,这超出了本文的范围。
我们看到我们有 5268 个用户的样本大小,对于每个用户,我们可以看到他们是否在这个屏幕上转换。我们可以继续计算之前的转换率。
conversion_rate = prior_data['converted'].sum()/prior_data.shape[0]print(f'Prior Conversion Rate is {round(conversion_rate, 3)}')

选择先验分布
我们看到先前的数据给出了大约 30%的转化率。我们现在用它来为𝜆.选择一个先验分布选择先验是贝叶斯实验方法的一个重要方面,值得单独发表。我将在本系列的第 4 部分中对此进行更深入的探讨。然而,为了这篇文章的目的,我将使用一个粗略的方法来选择一个先验。
我们将使用 beta 分布来模拟我们的转换率,因为它是[0,1]上的灵活分布,也是良好的共轭先验。当我们用实验数据计算后验概率时,这将使我们的计算更容易。
为我们的转换选择先验分布时,最好选择比先验数据建议的更弱的先验。我将在本系列的第 4 部分再次深入探讨这个问题,但是本质上,选择太强的先验可能导致我们的后验分布是错误的,因此可能导致错误的计算和结论。
记住这一点,让我们看看不同强度的潜在前科。
import numpy as np
from scipy.stats import beta
import matplotlib.pyplot as pltfig, ax = plt.subplots(1, 1)x = np.linspace(0,1,1000)beta_weak = beta(round(conversion_rate, 1)*10 + 1, 10 + 1 - round(conversion_rate, 1)*10)beta_mid = beta(round(conversion_rate, 1)*50 + 1, 50 + 1 - round(conversion_rate, 1)*50)beta_strong = beta(round(conversion_rate, 2)*100 + 1, 100 + 1 - round(conversion_rate, 2)*100)ax.plot(x, beta_weak.pdf(x), label=f'weak Beta({int(round(conversion_rate, 1)*10) + 1}, {10 + 1 - int(round(conversion_rate, 1)*10)})')ax.plot(x, beta_mid.pdf(x), label=f'mid Beta({int(round(conversion_rate, 1)*50) + 1}, {50 + 1 - int(round(conversion_rate, 1)*50)})')ax.plot(x, beta_strong.pdf(x), label=f'strong Beta({int(round(conversion_rate, 2)*100) + 1}, {100 + 1 - int(round(conversion_rate, 2)*100)})')ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Choice of Priors')
ax.legend()

先验选择(图片由作者提供)
这里我们可以看到三个先验分布,它们的平均转换率约为 30%,与我们的先验数据相似,但都比先验数据的真实分布弱得多。
让我们选择一个在图中最弱和中等先验之间的先验(𝐵𝑒𝑡𝑎(7,15)

其中𝐵(𝑎,𝑏)是被定义为的β函数

并且具有该属性

prior_alpha = round(conversion_rate, 1)*20 + 1
prior_beta = 20 + 1 - round(conversion_rate, 1)*20prior = beta(prior_alpha, prior_beta)fig, ax = plt.subplots(1, 1)x = np.linspace(0,1,1000)ax.plot(x, prior.pdf(x), label=f'prior Beta({int(round(conversion_rate, 1)*20) + 1}, {20 + 1 - int(round(conversion_rate, 1)*20)})')
ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Chosen Prior')
ax.legend()

选择的先验(图片由作者提供)
设置损失阈值
既然我们已经选择了先验,我们需要选择我们的𝜖,这是我们在错误选择错误变量的情况下愿意接受的最高预期损失。让我们假设这对我们来说是一个重要的转变,所以我们希望对这个𝜖.相当保守我们不愿意接受超过 0.5%的相对预期损失。所以我们设定𝜖=0.005∗0.3=0.0015.
我们有一个预期损失的先验和阈值,所以我们可以开始运行我们的实验并从中收集数据。
实验结果
让我们假设我们已经让我们的实验运行了几个星期,并想检查我们是否能从中得出任何结论。为了做到这一点,我们需要使用我们的实验数据来计算我们的后验分布,然后我们可以使用它来计算每个变量变得更好的概率,以及错误选择每个变量的预期损失。
出于本练习的目的,我生成了一个样本实验数据集。让我们从探索它和聚合它开始,找出每个变体的转换率。
experiment_data = pd.read_csv('experiment_data.csv')print(experiment_data.head())
print(experiment_data.shape)

我们看到该数据集与之前的数据集相似,只是多了一列,用于指定用户被分配到哪个组,以及他们看到哪个变量。再次值得注意的是,由于这个数据集是人工生成的,它已经是这个练习的理想格式,不需要额外的 ETL 操作。
我们现在可以开始汇总数据了。
results = experiment_data.groupby('group').agg({'userId': pd.Series.nunique, 'converted': sum})results.rename({'userId': 'sampleSize'}, axis=1, inplace=True)results['conversionRate'] = results['converted']/results['sampleSize']print(results)

我们可以通过观察得知治疗有更好的转化率,但我们需要进行进一步的计算,以更新我们对对照组和治疗组变异体各自的转化概率𝜆_𝑐和𝜆_𝑡的看法。
有了我们的实验数据,我们现在可以计算每个变量下的后验分布。但在此之前,让我们探索一下,仅仅从我们现有的信息中,这是如何可能的背后的数学原理。我们将使用一个定理[1]陈述如下:
假设我们有先验知识

假设一个变体被展示给𝑛的访问者,而𝑐改变了信仰,那么该变体的后验分布由下式给出

让我们继续证明这一点。根据贝叶斯定理,我们得到了

由于我们将每次转换建模为具有概率𝜆的伯努利 RV,给定𝜆,我们可以将向𝑛游客展示变量的结果建模为二项式 RV。所以我们有

因此,使用我们先前的定义

现在让我们只考虑系数

利用贝塔函数的定义,我们可以说

将(3)和(4)替换回(2)

将(5)替换回(1)

自𝑓(𝜆以来;𝑎+𝑐,𝑏+𝑛−𝑐)是在[0,1]上的分布,分母是 1,我们得到了我们想要的结果。
现在我们已经充分相信了数学,我们可以计算我们的后验分布。
control = beta(prior_alpha + results.loc['control', 'converted'], prior_beta + results.loc['control', 'sampleSize'] - results.loc['control', 'converted'])treatment = beta(prior_alpha + results.loc['treatment', 'converted'], prior_beta + results.loc['treatment', 'sampleSize'] - results.loc['treatment', 'converted'])fig, ax = plt.subplots()x = np.linspace(0.26,0.42,1000)ax.plot(x, control.pdf(x), label='control')
ax.plot(x, treatment.pdf(x), label='treatment')
ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Experiment Posteriors')
ax.legend()

实验后验(图片由作者提供)
现在我们已经得到了后验分布,我们可以继续计算联合后验分布。由于随机实验是基于将用户随机分配到一个变量的想法,我们可以假设这两个分布是独立的。请注意,情况并非总是如此。例如,在某些情况下,网络效应可能会发挥作用,我们需要考虑到这一点。这种假设也依赖于随机分配过程的正常工作。
让我们假设我们的随机分配方法工作正常,没有网络效应。在这种假设下,我们可以说:

让我们用这个来计算我们的联合后验分布。
import seaborn as snsjoint_dist_for_plot = []
for i in np.linspace(0.26,0.42,161):
for j in np.linspace(0.26,0.42,161):
joint_dist_for_plot.append([i, j, control.pdf(i)*treatment.pdf(j)])joint_dist_for_plot = pd.DataFrame(joint_dist_for_plot)joint_dist_for_plot.rename({0: 'control_cr', 1: 'treatment_cr', 2: 'joint_density'}, axis=1, inplace=True)tick_locations = range(0, 160, 10)
tick_labels = [round(0.26 + i*0.01, 2) for i in range(16)]heatmap_df = pd.pivot_table(joint_dist_for_plot, values='joint_density', index='treatment_cr', columns='control_cr')ax = sns.heatmap(heatmap_df)
ax.set_xticks(tick_locations)
ax.set_xticklabels(tick_labels)
ax.set_yticks(tick_locations)
ax.set_yticklabels(tick_labels)
ax.invert_yaxis()

关节后部(图片由作者提供)
图表中的蓝线代表𝜆_𝑐=𝜆_𝑡.由于后关节在这条线以上,我们可以用它作为治疗效果更好的直观指示。如果后关节在这条线以下,那么我们可以很确定控制会更好。如果关节后部的任何部分在线上,那么哪种变型更好就有更多的不确定性。
为了量化这一点,我们需要计算𝑝(𝜆_𝑡≥𝜆_𝑐)和𝐸𝐿,错误选择治疗的预期损失。
import decimal
decimal.getcontext().prec = 4control_simulation = np.random.beta(prior_alpha + results.loc['control', 'converted'], prior_beta + results.loc['control', 'sampleSize'] - results.loc['control', 'converted'], size=10000)treatment_simulation = np.random.beta(prior_alpha + results.loc['treatment', 'converted'], prior_beta + results.loc['treatment', 'sampleSize'] - results.loc['treatment', 'converted'], size=10000)treatment_won = [i <= j for i,j in zip(control_simulation, treatment_simulation)]chance_of_beating_control = np.mean(treatment_won)print(f'Chance of treatment beating control is {decimal.getcontext().create_decimal(chance_of_beating_control)}')

从模拟中我们看到𝑝(𝜆_𝑡≥𝜆_𝑐)=0.9718 so 治疗有 97%的机会比对照组好。
既然我们已经计算了治疗效果更好的可能性,我们需要计算𝐸𝐿.每个变量的损失函数由下式给出

因此,每个变量的预期损失由下式给出

我们用这个来计算预期损失[2]
decimal.getcontext().prec = 4loss_control = [max(j - i, 0) for i,j in zip(control_simulation, treatment_simulation)]loss_treatment = [max(i - j, 0) for i,j in zip(control_simulation, treatment_simulation)]all_loss_control = [int(i)*j for i,j in zip(treatment_won, loss_control)]all_loss_treatment = [(1 - int(i))*j for i,j in zip(treatment_won, loss_treatment)]expected_loss_control = np.mean(all_loss_control)
expected_loss_treatment = np.mean(all_loss_treatment)print(f'Expected loss of choosing control: {decimal.getcontext().create_decimal(expected_loss_control)}. Expected loss of choosing treatment: {decimal.getcontext().create_decimal(expected_loss_treatment)}')

通过运行模拟,我们看到:
𝐸𝐿 = 0.0001369 < 0.0015 = 𝜖
因为其中一个变异的预期损失低于我们在测试开始时设定的阈值,所以测试达到了显著性。我们可以很有把握地得出结论,治疗效果更好,错误选择治疗的预期成本不会超过我们能接受的水平。因此,我们强烈建议将追加销售屏幕的处理方式推广到我们的其他用户群。
我希望这个案例研究有助于您理解实现贝叶斯 AB 测试方法所需的计算。观看这个空间的系列的下一部分!
参考
[1] VWO 白皮书作者:C. Stucchio
[2] 贝叶斯 A/B 测试——一个模拟的实践探索作者 Blake Arnold——我使用了 Blake 代码中的逻辑来计算预期损失
我还发现迈克尔·弗拉斯科的《贝叶斯 A/B 测试的力量》非常有助于理解贝叶斯 A/B 测试方法的技术层面
我这篇文章的代码可以在这里找到
感谢阅读这篇文章!我希望它能帮助您更好地理解如何实现转换度量的贝叶斯 AB 测试方法。
如果你喜欢阅读我的文章,愿意支持我的写作,并且正在考虑订阅一个媒体,请随时使用我下面的推荐链接。我会从你的订阅费中提成。
https://medium.com/@kaushsk12/membership
贝叶斯 AB 检验—第二部分—收入
原文:https://towardsdatascience.com/bayesian-ab-testing-part-ii-revenue-1fbcf04f96cd?source=collection_archive---------10-----------------------

米歇尔·汉德森在 Unsplash 上的照片
系列结构
这篇文章是关于将贝叶斯 AB 测试方法应用于现实生活产品场景的系列博客文章的第二部分。它使用了在系列的第一部分中讨论的一些概念。
- 基于转换的测试指标(速率指标)的建模和分析
- 基于收入的测试指标的建模和分析(连续指标)
- 计算测试持续时间
- 选择一个合适的先验
- 用多个变量运行测试
让我们开始讨论如何在贝叶斯产品实验中建模、使用和分析收入测试指标。
实验背景
假设我们最近对应用程序中的商店功能进行了 UX 更改。我们相信这些变化让我们的用户更容易进行更大的应用内购买,我们希望在向更广泛的用户群发布之前进行 AB 测试。我们假设我们所做的改变将导致每用户平均收入的显著提高。
我们将每个用户产生的收入建模为随机变量𝑅=𝑋∗𝑌,其中:
𝑋是一个伯努利随机变量,它指的是用户是否进行了购买,转换概率为𝜆:𝑋𝐵𝑒𝑟(𝜆)
𝑌是一个指数随机变量,指的是购买的规模,如果它是与利率参数𝜃:𝑌𝐸𝑥𝑝(𝜃)
在这个模型中,我们知道每笔销售的平均收入是由 1/𝜃给出的,每用户的平均收入是由𝜆/𝜃.给出的
我们分析的第一步是查看过去的数据,为该模型的关键参数𝜆和𝜃选择合适的先验分布。
接下来,我们设置一个损失阈值——在我们错误地推出错误变体的情况下,我们愿意接受的最大预期损失。与任何统计建模一样,贝叶斯实验方法是建立在真实世界数据的近似值之上的。因此,我们总是有可能从测试中得出错误的结论。这个损失阈值允许我们说,即使我们得出了错误的结论,我们也可以确信每个用户的平均收入不会下降超过这个阈值。
最后,我们以随机实验的形式抽取样本,并使用这些样本来更新分布,以及我们对商店控制和治疗版本下的𝜆和𝜃的信念。然后我们可以用这些后验分布来计算我们感兴趣的概率和预期损失。
为了给我们的参数选择先验分布,让我们先看看我们最近收集的一些过去的购买数据。我生成了一个样本先验数据集,我们可以用它来做这个练习。
import pandas as pd
import numpy as npprior_data = pd.read_csv('prior_data.csv')print(prior_data.head())
print(prior_data.shape)

因为这个数据集是人工生成的,所以它已经是这个练习的理想格式。在现实世界中,我们可能需要执行一些 ETL 操作来获得这种格式的数据。然而,这超出了本文的范围。
我们看到,我们有一个 5268 个用户的样本大小,对于每个用户,我们可以看到他们是否进行了购买。对于那些确实进行了购买的用户,我们还可以看到购买的规模。我们可以继续计算之前的转换率、每笔销售的平均收入、每笔销售收入的比率参数以及每用户的平均收入。
conversion_rate = prior_data['converted'].sum()/prior_data.shape[0]converted = prior_data[prior_data['converted'] == 1]
avg_purchase = converted['revenue'].mean()print(f'Prior Conversion Rate is {round(conversion_rate, 3)}. Average Revenue per Sale is {round(avg_purchase, 3)}.')print(f'Rate Parameter for Revenue per Sale is {round(1/avg_purchase, 3)}. Average Revenue per User is {round(conversion_rate*avg_purchase, 3)}.')

选择先验分布
利用上面的信息,我们可以选择𝜆和𝜃.的先验分布使用与前一篇文章相同的逻辑,我们可以为我们的转换概率𝜆.选择𝐵𝑒𝑡𝑎(7,15 的先验总之,我们选择使用贝塔分布,因为它是[0,1]上的灵活分布,并且在之前是一个好的共轭。
对于𝜃,每笔销售收入的比率参数,我们将使用伽马分布,因为它是一个在[0,∞)上的灵活分布,也是一个很好的共轭先验。当我们用实验数据计算后验概率时,这将使我们的计算更容易。
我们可以选择非常弱的先验分布𝐺𝑎𝑚𝑚𝑎(0.1,0.1)。[1]
设置损失阈值
既然我们已经选择了先验,我们需要选择我们的𝜖,这是我们在错误选择错误变量的情况下愿意接受的最高预期损失。让我们假设商店不是我们的主要收入来源,但它对我们非常重要,所以我们希望在这个𝜖.上保守一些我们可以设定𝜖 = 0.005。
我们有先验分布和预期损失的阈值,所以我们可以开始运行我们的实验并从中收集数据。
实验结果
让我们假设我们已经让我们的实验运行了几个星期,并想检查我们是否能从中得出任何结论。为了做到这一点,我们需要使用我们的实验数据来计算我们的后验分布,然后我们可以使用它来计算每个变量变得更好的概率,以及错误选择每个变量的预期损失。
出于本练习的目的,我生成了一个样本实验数据集。让我们从探索它开始。
experiment_data = pd.read_csv('experiment_data.csv')print(experiment_data.head())
print(experiment_data.shape)

我们看到该数据集与之前的数据集相似,只是多了一列,用于指定用户被分配到哪个组,以及他们看到哪个变量。再次值得注意的是,由于这个数据集是人工生成的,它已经是这个练习的理想格式,不需要额外的 ETL 操作。
我们现在可以开始汇总数据了。
results = experiment_data.groupby('group').agg({'userId': pd.Series.nunique, 'converted': sum, 'revenue': sum})results.rename({'userId': 'sampleSize'}, axis=1, inplace=True)results['conversionRate'] = results['converted']/results['sampleSize']results['revenuePerSale'] = results['revenue']/results['converted']
print(results)

经检查,似乎两组有相似的转换率,但治疗有更好的每销售收入。然而,为了更新我们关于𝜆和𝜃的两种变体的信念,我们需要进行进一步的计算。
使用前一篇文章的中概述的计算,我们可以计算两个变量的𝜆后验分布。
from scipy.stats import beta, gamma
import seaborn as sns
import matplotlib.pyplot as pltcontrol_cr = beta(7 + results.loc['control', 'converted'], 15 + results.loc['control', 'sampleSize'] - results.loc['control', 'converted'])treatment_cr = beta(7 + results.loc['treatment', 'converted'], 15 + results.loc['treatment', 'sampleSize'] - results.loc['treatment', 'converted'])fig, ax = plt.subplots()x = np.linspace(0,1,1000)ax.plot(x, control_cr.pdf(x), label='control')
ax.plot(x, treatment_cr.pdf(x), label='treatment')
ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Experiment Posteriors')
ax.legend()

转换后验概率(图片由作者提供)
𝜆_𝑐和𝜆_𝑡的后验分布几乎相同。通过观察我们可以看出,处理对转换概率没有大的影响。
让我们来看看它是如何影响收入的比率参数的。我们将使用下面的结果[2]来计算𝜃_𝑐和𝜃_𝑡:
假设先验
𝜃 ∼ 𝐺𝑎𝑚𝑚𝑎(𝑘, Θ)
假设向𝑛游客展示了一个变种。𝑐换算成每销售𝑠.的平均收入然后,后验分布由下式给出
𝜃|𝑐,𝑠 ∼ 𝐺𝑎𝑚𝑚𝑎(𝑘 + 𝑐, Θ/(1 + Θ𝑐𝑠))
(如果你对这个结果背后的数学原理感到好奇,这里有的证明。)
让我们继续计算我们的后验概率𝜃_𝑐和𝜃_𝑡.
control_rr = gamma(a=(0.1 + results.loc['control', 'converted']), scale=(0.1/(1 + (0.1)*results.loc['control', 'converted']*results.loc['control', 'revenuePerSale'])))treatment_rr = gamma(a=(0.1 + results.loc['treatment', 'converted']), scale=(0.1/(1 + (0.1)*results.loc['treatment', 'converted']*results.loc['treatment', 'revenuePerSale'])))fig, ax = plt.subplots()x = np.linspace(0,3,1000)ax.plot(x, control_rr.pdf(x), label='control')
ax.plot(x, treatment_rr.pdf(x), label='treatment')
ax.set_xlabel('Rate Parameter')
ax.set_ylabel('Density')
ax.set_title('Experiment Posteriors')
ax.legend()

费率参数(每笔销售收入)后验概率(图片由作者提供)
后验分布根本没有重叠,所以我们可以相当确定其中一个变量比另一个更好。处理率参数低于控制率参数,因此更好,因为它将导致更高的平均销售收入。为了更清楚地看到这一点,让我们画出在这些后验概率下每笔销售的平均收入的分布。
fig, ax = plt.subplots()x = np.linspace(0,3,1000)
z = [1/i for i in x]ax.plot(x, control_rr.pdf(z), label='control')
ax.plot(x, treatment_rr.pdf(z), label='treatment')
ax.set_xlabel('Avg Revenue per Sale')
ax.set_ylabel('Density')
ax.set_title('Experiment Posteriors')
ax.legend()

每笔销售的平均收入(图片由作者提供)
我们可以清楚地看到,治疗组的平均销售收入高于对照组。
所以两种变体有相似的转换率,但是 treatment 有更好的每笔销售的平均收入,所以它也必须有更好的每用户平均收入。让我们画出每个用户平均收入的后验概率来证实这一点。我们可以进行一些模拟来帮助我们。
control_conversion_simulation = np.random.beta(7 + results.loc['control', 'converted'], 15 + results.loc['control', 'sampleSize'] - results.loc['control', 'converted'], size=100000)treatment_conversion_simulation = np.random.beta(7 + results.loc['treatment', 'converted'], 15 + results.loc['treatment', 'sampleSize'] - results.loc['treatment', 'converted'], size=100000)control_revenue_simulation = np.random.gamma(shape=(0.1 + results.loc['control', 'converted']), scale=(0.1/(1 + (0.1)*results.loc['control', 'converted']*results.loc['control', 'revenuePerSale'])), size=100000)treatment_revenue_simulation = np.random.gamma(shape=(0.1 + results.loc['treatment', 'converted']), scale=(0.1/(1 + (0.1)*results.loc['treatment', 'converted']*results.loc['treatment', 'revenuePerSale'])), size=100000)control_avg_purchase = [i/j for i,j in zip(control_conversion_simulation, control_revenue_simulation)]treatment_avg_purchase = [i/j for i,j in zip(treatment_conversion_simulation, treatment_revenue_simulation)]fig, ax = plt.subplots()x = np.linspace(0,1,1000)ax.hist(control_avg_purchase, density=True, label='control', histtype='stepfilled', bins=100)
ax.hist(treatment_avg_purchase, density=True, label='treatment', histtype='stepfilled', bins=100)
ax.set_xlabel('Avg Revenue per User')
ax.set_ylabel('Density')
ax.set_title('Experiment Posteriors')
ax.legend()

每用户平均收入(图片由作者提供)
治疗组的平均收入明显高于对照组。通过检查这些后验,我们可以很有把握地认为治疗是更好的。然而,为了量化这一点,我们需要计算𝑝(𝜆_𝑡/𝜃_𝑡 ≥ 𝜆_𝑐/𝜃_𝑐)和𝐸𝐿,错误选择治疗的预期损失。
treatment_won = [i <= j for i,j in zip(control_avg_purchase, treatment_avg_purchase)]chance_to_beat_ctrl = np.mean(treatment_won)
print(f'Chance of beating control: {round(chance_to_beat_ctrl, 3)}.')

从模拟中我们看到𝑝(𝜆_𝑡/𝜃_𝑡 ≥ 𝜆_𝑐/𝜃_𝑐) = 1,所以治疗有 100%的机会比对照组好。
既然我们已经计算了治疗效果更好的可能性,我们需要计算𝐸𝐿.每个变量的损失函数由下式给出

我们用这个来计算预期损失。
loss_control = [max(j - i, 0) for i,j in zip(control_avg_purchase, treatment_avg_purchase)]loss_treatment = [max(i - j, 0) for i,j in zip(control_avg_purchase, treatment_avg_purchase)]all_loss_control = [int(i)*j for i,j in zip(treatment_won, loss_control)]all_loss_treatment = [(1 - int(i))*j for i,j in zip(treatment_won, loss_treatment)]expected_loss_control = np.mean(all_loss_control)
expected_loss_treatment = np.mean(all_loss_treatment)print(f'Expected loss of choosing control: {round(expected_loss_control, 3)}. Expected loss of choosing treatment: {round(expected_loss_treatment, 3)}')

从运行模拟中我们看到
𝐸𝐿=0 < 0.005=𝜖.
因为其中一个变异的预期损失低于我们在测试开始时设定的阈值,所以测试达到了显著性。我们可以很有把握地得出结论,治疗效果更好,错误选择治疗的预期成本不会超过我们能接受的水平。因此,我们强烈建议将追加销售屏幕的处理方式推广到我们的其他用户群。
我希望这个案例研究有助于您理解实现贝叶斯 AB 测试方法所需的计算。观看这个空间的系列的下一部分!
参考
[1] 通过 Omri Fima 的贝叶斯 A/B 测试优化收入
[2] VWO 白皮书作者:C.Stucchio
我这篇文章的代码可以在这里找到
感谢阅读这篇文章!我希望它能帮助您更好地理解如何为收入和其他计数指标实现贝叶斯 AB 测试方法。
如果你喜欢阅读我的文章,愿意支持我的写作,并且正在考虑订阅一个媒体,请随时使用我下面的推荐链接。我会从你的订阅费中提成。
https://medium.com/@kaushsk12/membership
贝叶斯 AB 测试第三部分测试持续时间
原文:https://towardsdatascience.com/bayesian-ab-testing-part-iii-test-duration-f2305215009c?source=collection_archive---------22-----------------------

在 Unsplash 上由 Aron 视觉拍摄的照片
系列结构
这篇文章是将贝叶斯 AB 测试方法应用于现实生活产品场景的系列博客文章的第三部分。它使用了在系列的第一部分中讨论的一些概念。
- 基于转换的测试指标(速率指标)的建模和分析
- 基于收入的测试指标(持续指标)的建模和分析
- 计算测试持续时间
- 选择一个合适的先验
- 用多个变量运行测试
实验背景
根据上一篇文章中使用的示例,我们假设我们最近更改了追加销售屏幕上的信息,并希望在向更广泛的用户群发布之前进行 AB 测试。我们假设我们所做的改变将会带来更好的转化率。
我们继续将转换率建模为具有转换概率𝜆的伯努利随机变量,进而我们使用𝐵𝑒𝑡𝑎(7,15).的先验分布进行建模然后我们选择我们的预期损失阈值𝜖 = 0.0015。我们现在准备运行我们的测试,但是我们要运行多长时间呢?
在我们深入分析来回答这个问题之前,让我们首先考虑一下测试持续时间实际上意味着什么。以下公式给出了计算测试持续时间的常用方法:

测试中包含的变量数量和用户比例是在测试设计过程中就已经决定的因素。我们预计一周内的用户数量是基于前几周的数据进行的简单计算。所以本质上,问题归结为在实验中为每个变体选择一个合理的所需样本量。
人们经常建议,贝叶斯产品实验应该运行,直到其中一个变量的预期损失低于我们的阈值𝜖,在这一点上,我们宣布该变量为赢家。这样我们就不需要担心计算所需的样本量。然而,遵循这种方法可能会导致我们错误地选择一个变体来推出,因为这是一个被称为窥视 [1]的概念。为了进一步探讨这一点,让我们考虑下面的例子。
偷看
让我们考虑一下𝜆_𝑐和𝜆_𝑡非常相似的情况。我们模拟运行 AB 测试,并期望结果是非决定性的。然而,我们看到以下结果。

偷看例子(图片由作者提供)
我们从右侧的转换率中可以看出,𝜆_𝑐和𝜆_𝑡在前 1000 个样本中趋于一致。然而,更有趣的观察是关于左边的图表。我们看到,在前几个样本中,控制预期损失低于阈值。如果我们在这里停止测试,我们会得出控制明显优于治疗的结论,这将是错误的结论。我们还看到,如果我们在这里不停止测试,根据我们停止测试的时间,所有三种结果(对照组获胜、治疗组获胜和非决定性测试)都是可能的。那么我们如何决定何时停止测试呢?
运行我们实验的模拟将帮助我们避免落入窥视的陷阱,并最终帮助我们为每个变量选择一个合理的所需样本量。在我们研究这是如何工作的之前,让我们考虑下面的警告。
警告
下面提出的方法的主要警告是,它没有考虑任何选择测试持续时间的实验设计参数。特别是,它没有考虑任何季节或基于时间的转换变化。在现实世界中,您用作测试指标的转换很可能会根据一周中的某一天甚至一天中的某个时间而变化。因此,为了避免由于季节变化而得出错误的结论,至少运行几周的测试是值得的。我建议使用这篇文章中概述的方法来计算运行测试需要多长时间。
样本量计算
影响所需样本量的主要因素有三个:
- 可察觉的最小影响𝛿—𝜆的最小变化我们需要推广治疗
- 预期损失阈值𝜖——在我们错误宣布赢家的情况下,我们愿意接受的转化率的最大损失
- 转换概率𝜆标度
我们将在后面的文章中深入探讨这些因素是如何影响样本量的,但是让我们先建立一个计算合理样本量的过程。
让我们先给上述因素赋值。我们对实验进行了 100 次模拟,平均先验转换率为 32%,预期损失阈值𝜖为 0.0015,相对最小可检测效应为 15%(因此我们寻找𝜆_𝑡≥0.15∫𝜆_𝑐).
现在让我们来研究一下模拟数据。

实验模拟(图片由作者提供)
通过检查,我们可以看到,在通过处理达到最小可检测效果的情况下,大多数实验在我们达到每个变体 2000 个样本时结束。然而,我们仍然需要对 4000 个用户进行测试,这是一个很大的数字,可能需要一段时间。因此,让我们看看我们是否可以减少这一点,同时仍然非常肯定,测试将是决定性的。
为了停止测试,我们需要设置一个最小样本数,这样我们就不会掉进偷看的陷阱。让我们放大上面的预期损失图来选择这个最小样本数。

实验模拟—放大低样本量(图片由作者提供)
再次,通过仔细观察,我们可以看到,如果我们将最小样本量设置为 200,大多数假阳性(选择控制的预期损失低于阈值的情况)都可以被消除。我们现在继续,并绘制在每个模拟中需要多少样本来宣布获胜者[2],假设每个变体至少观察到 200 个样本。

结论性模拟(图片由作者提供)

我们看到,我们只需要每个变体 450 个样本,80%的测试就能得出结论。因此,如果我们决定运行测试,直到我们有 900 个样本,然后,鉴于最低可检测的影响,我们有 80%的机会,测试将是决定性的。因此,我们看到,我们很可能找到一个比我们原来认为的少 3100 个样本的结论性结果。
应用同样的逻辑,现在让我们看看我们前面讨论的差异因素是如何影响所需样本量的。
最小可检测效应
最小可检测效应𝛿是我们想要检测的𝜆的最小相对百分比变化。这是最小的变化,将使治疗值得推出给我们的用户群。让我们看看这个𝛿如何影响我们的样本量计算。当从{0.05,0.15,0.3}中选择𝛿时,我们将使用 32%的先前平均转换率和 0.0015 的预期损失阈值。

𝛿变化的决定性模拟(图片由作者提供)

我们发现,最低可检测效应越高,80%的决定性试验所需的每个变异体的样本量越低,反之亦然。选择 5%的𝛿将要求我们总共获得大约 2100 个样本,而选择 30%的𝛿将要求我们总共只获得大约 600 个样本。直觉上,这是有意义的,因为转换概率的变化越大,我们需要确定它的样本就越少。
预期损失阈值
预期损失阈值𝜖是在我们错误地选择了一个变量的情况下,我们愿意接受的最大预期损失。这是我们在这种情况下最大的预期转化率下降。让我们看看这个𝜖如何影响我们的样本量计算。当从{0.0005,0.0015,0.003}中选择𝜖时,我们将使用 32%的先验平均转化率和 15%的最小可检测效应。

𝜖变化的决定性模拟(图片由作者提供)

我们看到,预期损失阈值越高,80%的检验所需的每个变量的样本量越低,反之亦然。选择 0.0005 的𝜖将需要我们总共获得大约 1350 个样本,而选择 0.003 的𝜖将需要我们总共仅获得大约 650 个样本。所需样本量的变化小于最小可检测效应的情况,因为𝜖的变化规模不同于𝛿.的变化规模然而,概念是相似的,预期损失阈值越低,我们就越想确定实验的结果,因此所需的样本量就越大。
转换概率的标度
现在让我们看看测试中使用的转换概率的比例如何影响我们的样本大小计算。我们将使用 15%的𝛿,并选择 0.005 的相对𝜖。我们在这种情况下使用了相对𝜖,因此分析更加公平,这与在之前的情况下使用𝜖 = 0.0015 相同,之前的平均转换率保持不变,为 32%。在这种情况下,我们将考虑{0.05,0.32,0.6}之前的平均转换率。

𝜆变化的决定性模拟(图片由作者提供)

我们看到一个有趣的结果。尽管对于较高的转换率,所需的样本量没有(相对)大的差异,但是随着转换率变低,所需的样本量变得不成比例地大。在计算所需的样本量时,这是一个需要牢记的重要概念。这是因为转换概率𝜆越低,𝜆的后验分布就越分散,因此我们需要更多的样本来减少这种分散。
我希望这篇文章对你估计贝叶斯产品实验的合理测试持续时间有所帮助,并理解影响它的因素。观看这个空间的系列的下一部分!
参考
【1】贝叶斯 AB 测试对偷看免疫吗?作者大卫·罗宾逊
[2] 贝叶斯 A/B 测试——布莱克·阿诺德的模拟实践探索——我从布莱克的帖子中获得了查看结论性模拟百分位数的想法
我这篇文章的代码可以在这里找到
贝叶斯 AB 检验——第四部分——选择先验
原文:https://towardsdatascience.com/bayesian-ab-testing-part-iv-choosing-a-prior-5a4fe3223bfd?source=collection_archive---------16-----------------------
如何为您的测试度量选择一个合理的先验分布

杰森·登特在 Unsplash 上拍摄的照片
系列结构
这篇文章是关于将贝叶斯 AB 测试方法应用于现实生活产品场景的系列博客文章的第 4 部分。它使用了本系列第一部和第二部中讨论的一些概念。
- 基于转换的测试指标(速率指标)的建模和分析
- 基于收入的测试指标(持续指标)的建模和分析
- 计算测试持续时间
- 选择合适的先验
- 用多个变量运行测试
什么是先验分布?
在贝叶斯推理中,先验分布是一种概率分布,用于在从基础总体中抽取样本之前表明我们对未知变量的信念。然后,我们使用这些数据,通过贝叶斯法则更新我们对变量的信念,从而得到变量的后验分布。
在 AB 测试的上下文中,先验分布是一组我们认为测试度量要采用的值,并为每个值分配一个概率。然后,我们以随机实验的形式抽取样本,用于计算后验分布。这些后验分布反过来用于计算 AB 检验的结果。
先验分布的选择如何影响实验?
嗯,贝叶斯法则告诉我们

用文字来说,可以写成

其中分母是归一化常数。因此,该规则可以简化为

因为测试的结果是根据后验概率计算的,而先验是后验概率的一个因素,所以先验的选择对测试有影响,但我们需要小心它的影响有多大。如果我们选择太强的先验,先验将成为主导因素,提取样本的可能性不会产生太大的影响,使实验变得无用。这可能会导致后验概率、控制概率和变异概率快速收敛,从而导致测试不确定。然而,如果我们选择一个非常弱的先验,后验概率将主要依赖于可能性,所以我们需要更多的样本来得出结论性的结果,导致测试时间更长,产品迭代速度更慢。
为了使我们的后验分布更容易计算,我们也可以使用共轭先验。共轭先验是我们可以与似然函数一起使用的先验分布,使得我们计算的后验分布具有与先验分布相似的形式。使用共轭先验简化了我们的计算,同时仍然为测试度量提供了良好的统计模型。在本系列的第一篇和第二篇文章中,我们已经看到了简化的计算和共轭先验的选择是如何对我们有利的。
前科类型
在我们深入探讨如何选择一个先验之前,让我们快速看一下三种主要类型的先验。[1]
主观的
- 基于实验者对该领域的了解
- 在我们的例子中,这将基于产品和数据团队先前对这个测试指标的经验
客观且信息丰富
- 基于该值的历史数据
- 在我们的例子中,这将基于我们所拥有的关于测试指标的任何历史数据
- 它也可能是以前实验的后验分布
无信息的
- 不传达任何价值信息的先验
- 在我们的例子中,这将是测试度量空间上的均匀分布
让我们假设我们是公司和产品的新手,所以我们没有足够的信息来使用主观先验。我们也不希望使用无信息的先验,因为我们认为这将导致更长的测试,从而阻碍我们产品的进展。让我们来看几个技巧,我们可以用来选择一个客观的和信息丰富的先验。
检查
选择先验分布的最简单方法是绘制和检查相关测试指标的历史数据。为了进一步理解这一点,让我们考虑这个系列的第篇文章中的实验。假设我们最近更改了追加销售屏幕上的信息,并希望在向更广泛的用户群发布之前进行 AB 测试。我们假设我们所做的改变将会带来更好的转化率。
在我们设置测试之前,我们希望使用历史数据来选择一个先验。让我们看看如何绘制数据来帮助我们选择。我们将数据分成 100 个分区,计算出每个分区的转换率,并将转换率绘制成直方图。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
prior_data = pd.read_csv('prior_data_conversions.csv')x = np.linspace(0,1,1000)partitions = np.array_split(prior_data, 100)rates = []for partition in partitions:
rates.append(partition['converted'].mean())_, ax = plt.subplots()sns.histplot(rates, kde=True, label='CR')ax.legend()
ax.set_xlabel('Conversion Rate')
ax.set_ylabel('Density')
ax.set_title('Histogram of Prior Conversion Rates')

先前转换率的直方图(图片由作者提供)
我们现在可以选择一个类似于上面分布的先验分布,但是稍微弱一点。我们不想选择太强的先验,因为我们希望可能性成为计算先验的主导因素。然而,我们确实希望选择一个足够强的先验,这样测试持续时间将会更短。
我们将使用β分布来模拟我们的转换率,因为它是[0,1]上的灵活分布,也是一个很好的共轭先验。所以让我们继续,为我们的练习绘制一些不同强度的潜在先验。
import numpy as np
from scipy.stats import beta
import matplotlib.pyplot as plt_, ax = plt.subplots(1, 1)x = np.linspace(0,1,1000)beta_weak = beta(4, 8)
beta_mid = beta(16, 36)
beta_strong = beta(33, 69)ax.plot(x, beta_weak.pdf(x), label=f'weak Beta({4}, {8})')
ax.plot(x, beta_mid.pdf(x), label=f'mid Beta({16}, {36})')
ax.plot(x, beta_strong.pdf(x), label=f'strong Beta({33}, {69})')ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Choice of Priors')
ax.legend()

先验选择(图片由作者提供)
我们看到,即使我们绘制的最强先验也比转化率的历史分布弱。所以我们可以提前选择𝐵𝑒𝑡𝑎(33,69)作为我们的前期分销。
我们现在可以运行我们的实验,计算后验概率和测试结果。要了解更多关于如何做到这一点,特别是对于概述的实验,请查看这篇帖子。
蒙特卡罗马尔可夫链(MCMC)
一个更复杂但非常有趣的选择先验分布的方法是使用蒙特卡罗马尔可夫链。这种方法对于未知变量由其他随机变量决定的模型特别有用,每个随机变量都有自己的分布。因此,这是一个很好的 AB 测试技术,测试指标是基于收入的(比如每个用户的平均收入)。
在我们开始讨论如何使用这种方法之前,让我先介绍一下它是如何工作的——MCMC 应该有自己的一篇文章,所以这篇介绍会非常简短。[2] MCMC 方法允许我们通过运行模拟从一个未知分布中取样(因此名称的 蒙特卡罗 部分),其中我们创建一个马尔可夫链,它将我们的未知分布作为其平稳分布。
但是这些术语实际上是什么意思呢?嗯,马尔可夫链是一个在一组状态之间跳跃的过程,每次跳跃都遵循马尔可夫性质。简而言之,这意味着跳转到某个特定状态的概率只取决于流程的当前状态,而不是流程跳转的前一个状态。由于这种无记忆的特性,以及在不同状态之间跳跃的概念,这个过程通常被称为随机行走。让我们假设我们执行无限步的随机行走,那么平稳分布是我们访问每个状态的步数的比例。
现在我们对 MCMC 方法有了一点了解,让我们开始使用它们来为 AB 测试选择先验。让我们考虑一下这个系列的第二篇文章中的实验。我们最近对应用程序中的商店功能进行了 UX 更改。我们相信这些变化让我们的用户更容易进行更大的应用内购买,我们希望在向更广泛的用户群发布之前进行 AB 测试。我们假设我们所做的改变将导致每用户平均收入的显著提高。
我们将每个用户产生的收入建模为随机变量𝑅=𝑋∗𝑌,其中:
𝑋是一个伯努利随机变量,指的是用户是否进行了购买,转换概率为𝜆-𝑋∼𝐵𝑒𝑟(𝜆)
𝑌是一个指数随机变量,指的是购买的规模,如果它与利率参数𝜃-𝑌∼𝐸𝑥𝑝(𝜃)
我们可以用𝜆和𝜃的共轭先验来简化我们的计算。

我们现在需要为我们的参数选择先验,这可能是无信息的。

import arviz as az
import pymc3 as pmprior_revenue = pd.read_csv('prior_data_revenue.csv')rev_observed = prior_revenue[prior_revenue['converted'] == 1]['revenue'].valuesconv_observed = prior_revenue['converted'].valuesmodel = pm.Model()with model:
alpha = pm.Uniform("alpha", lower=0, upper=100)
beta = pm.Uniform("beta", lower=0, upper=100)
k = pm.Uniform("k", lower=0, upper=5)
theta = pm.Uniform("theta", lower=0, upper=5) cr = pm.Beta('cr', alpha=alpha, beta=beta)
rr = pm.Gamma('rr', alpha=k, beta=(1/theta)) conversion = pm.Bernoulli('conversion', p=cr, observed=conv_observed) revenue_per_sale = pm.Exponential('revenue_per_sale', lam=rr, observed=rev_observed) trace = pm.sample(10000, return_inferencedata=False)
一旦我们拟合了模型,我们现在可以绘制每个参数的分布,并打印出一些汇总统计数据。
with model:
az.plot_trace(trace, compact=False)

MCMC 跟踪(图片由作者提供)
with model:
display(az.summary(trace, kind='stats', round_to=2))

map_estimate = pm.find_MAP(model=model)print(map_estimate)

我们将要使用的两个主要统计数据是每个参数的平均值和每个参数的 MAP 估计值。简而言之,后者是对每个参数分布的点的估计,这些点导致转换率和收益率分布的模式。由于我们的参数先验是一致的,这些估计也是𝜆和𝜃.先验分布的极大似然估计[3]
让我们继续使用这些统计数据来绘制前科。
from scipy.stats import betacr_prior_mean = beta(33, 67)
cr_prior_map = beta(47, 100)x = np.linspace(0,1,1000)_, ax = plt.subplots()sns.lineplot(x=x, y=cr_prior_mean.pdf(x), label='mean Beta(33,67)')
sns.lineplot(x=x, y=cr_prior_map.pdf(x), label='map Beta(47,100)')ax.set_xlabel('Conversion Probability')
ax.set_ylabel('Density')
ax.set_title('Conversion Probability Prior')
ax.legend()

在转换概率𝜆的情况下,两种分布非常相似。我们将继续选择较弱的一个作为度量,因此我们的先验由下式给出
𝜆∼𝐵𝑒𝑡𝑎(33,67)
from scipy.stats import gammarr_prior_mean = gamma(a=2.3, scale=2.0)
rr_prior_map = gamma(a=5, scale=0.4)x = list(range(20))rr_mean = [rr_prior_mean.pdf(i) for i in x]
rr_map = [rr_prior_map.pdf(i) for i in x]_, ax = plt.subplots()sns.lineplot(x=x, y=rr_mean, label='mean Gamma(2.3,2.0)')
sns.lineplot(x=x, y=rr_map, label='map Gamma(5,0.4)')ax.set_xlabel('Revenue Rate')
ax.set_ylabel('Density')
ax.set_title('Revenue Rate Prior')
ax.legend()

类似地,在𝜃收益率的情况下,让我们继续选择较弱的先验,它使用来自我们的 MCMC 算法的𝑘和θ分布的平均值。所以我们有
𝜃∼𝐺𝑎𝑚𝑚𝑎(2.3,2.0)
现在我们有了先验知识,我们可以进行实验,计算后验概率和测试结果。为了找到更多关于如何做到这一点的信息,特别是对于这个概述的实验,请查看这篇帖子。
我希望您发现这种用于选择先验知识的技术探索是有帮助的。请关注本系列的下一部分!
参考
[1]http://www.stats.org.uk/priors/Bayes6.pdf
[2]Rahul Agarwal 的《每个人的 MCMC 直觉》——我发现这对理解 MCMC 算法很有帮助
[3] 最大似然估计 VS 最大后验 A杨
我在这篇文章中的代码可以在这里找到。
通过 JAX 的贝叶斯近似神经网络示例
原文:https://towardsdatascience.com/bayesian-approximated-neural-network-example-via-jax-flexible-parameter-distributions-for-odes-9b4a7f79b493?source=collection_archive---------21-----------------------
常微分方程的灵活参数分布
虽然存在几种已知的方法来近似 ode 的参数分布(特别是 PyMC3 ),但这种概念验证方法在不提供先验分布的情况下估计未知分布。使用神经网络中的漏失概念作为模型不确定性的贝叶斯近似形式,可以通过训练的神经网络的采样来近似灵活的参数分布。
由于具有由给定神经网络学习的灵活输出分布的优势,理论上预测可以更好地拟合伴随有模型不确定性而不是硬离散数字的真实生活数据。对于许多业务场景,尤其是与医疗保健行业的患者护理相关的业务场景,拥有这些预测信息是必不可少的。毕竟,当模型的可解释性或置信度未知时,医生为什么要根据给定患者的图表考虑稳健模型的输出以获得更好的药物治疗呢?在做出关键决策时,我们当然希望对模型的预测有所了解。当将这种方法与常微分方程(ODE)甚至常微分方程系统相结合时,可以更容易更有效地对复杂的真实世界动力学进行建模,而同时仍然应用一些刚性结构(以增加可解释性)。可以导出模型不确定性和灵活的 ODE 参数分布,而不必对潜在参数“可能”是什么做出有影响的先验假设。
启发我的是这篇论文:
【arxiv.org 【1506.02142】作为贝叶斯近似的辍学:表示深度学习中的模型不确定性】
本文中的示例用于估算一个简单 ODE 所需的两个参数,dy/dt = -r * y。一个参数用于增长率 r,另一个参数用于对某个 t 进行积分的初始 y 值。概念验证的一个期望是可视化 t 轴上的输出分布,并有可能在 t 轴上具有可变分布。通过对经过训练的贝叶斯神经网络进行采样(通过丢弃),我们可以预期近似的 ODE 参数分布是灵活的,因此不能保证是一致的。我发现这对于更复杂的情况是非常强大和有用的,而不必提供一些假设的先验分布,因为神经网络将近似参数分布,并且还可以扩展以及支持连续/在线训练。
我更喜欢将变量依赖关系保存在外部,而不是内嵌,但是我想提供一个工作的单个文件脚本,以便更容易地查看所有引用的函数和变量。下面是单个文件中的完整代码(文件:Bayesian _ appx _ nn _ ex _ jax . py):
https://github.com/bmurders2/Bayesian-Approximated-Neural-Networks-for-Flexible-ODE-Parameter-Distributions
Python 文件依赖于以下包:
- numpy
- 熊猫
- matplotlib
- 海生的
- jax[cpu] ( JAX )
我在执行 Python 脚本时的方法依赖于 Tensorflow GPU Docker 镜像(版本 2.6.0,Python 3.6.9)进行加速的 GPU CUDA 训练。然而,运行这个脚本既不需要 Tensorflow 也不需要 GPU,因为标准的基于 CPU 的 JAX 包也可以工作(用列出的包和 Python 3.9 成功测试)。JAX 对 XLA 和 JIT 的利用甚至对于 CPU 来说都是惊人的!如果您在执行这个 Python 文件时碰巧使用了 VS 代码,那么有一些字符串,#%%,它们是 VS 代码的 Python 交互特性的一部分,用于在处理 Python 文件时获得类似 Jupyter 的体验。如果这个 Python 文件作为 Jupyter 文件导出,这些字符串将自动创建它们相应的单元格(如果直接在 Jupyter 笔记本中运行这个带有交互单元格的文件比 VS Code 的交互窗口特性更好)。
JAX 的实验包包括 Stax 直接在 JAX 境内进行神经网络开发和训练。其他强大的软件包使用 JAX 创建非常健壮的神经网络,如 Trax ,但我认为 Stax 更容易为这个演示建立原型,不需要 JAX 以外的其他软件包。Python 文件使用以下神经网络超参数:
- 辍学率值:0.1
- 每层单位:2048
- 隐藏层数:1
- 主要激活功能:MISH
虽然“深”神经网络将允许更鲁棒的拟合,但是这个示例 ODE 对于单个隐藏层来说足够简单,但是具有“非常宽”的隐藏层(当试图通过神经网络放弃这种贝叶斯近似方法来关联或“近似”高斯过程时,这是一个重要的概念)。对于训练,在对训练数据进行全面训练之前,有一个“好的”猜测是非常重要的。这类似于大多数优化器或最小化算法,其中初始参数值的“坏”猜测可能阻止适当拟合的有效收敛。因此,训练被分成两部分,第一部分用于在对添加了噪声的训练数据进行最终训练之前“启动”神经网络以输出“好的”猜测参数值。采用这种方法将大大有助于在训练期间避免 NaN 值,因为给定函数的参数可能具有非常陡的梯度,这取决于参数所在的位置。为两个训练实例选择的优化器是 JAX 的 ADAMAX,其步长为 2e-3 用于启动训练会话,2e-5 用于针对添加噪声的训练数据的训练。对于损失训练函数,使用 Huber。
在对添加了噪声的训练数据进行训练之后,使用 200 个样本来确定使用任意预测区间的分位数的输出分布。在这种方法中,使用直接标准差+平均值上的分位数绘制预测区间更有用,因为您不必担心区间会忽略 ODE 的重要方面,例如跨越目标 ODE 函数的水平渐近线。 Seaborn 和 Matplotlib 用于以下地块:
- 导出跨 t 轴的输出样本的密度视觉。
- 样品的外观。
- 单个样本的图。
- 近似 ODE 参数的分布。

按作者分类的图像—t 轴上输出分布的密度图

按作者分类的图像-输出的等值线视图

按作者分类的图像-带有预测间隔的单个样本视图

按作者分类的图像-参数 y(0)的样本分布

按作者分类的图像-参数 r 的样本分布
我们可以从近似 ODE 参数的密度图中看到,它们并不完全一致,这正是我在训练后想要看到的。目标 ODE 并不太复杂,但是演示这种方法如何灵活地获得非均匀分布才是目标。重要的是,绘制更多的样本可以影响 ODE 参数估计的可视化近似密度图,但是对于 200 个样本,对于近似 ODE 参数密度“是什么”应该是足够的。
我们可以使用某种形式的增广神经常微分方程,通过这里提出的贝叶斯扭曲,直接逼近该函数。但是,如果我们碰巧对潜在的动态有一些合理的知识或假设,那么利用这种方法会更好。试图用黑盒模型直接模拟潜在动态的一个可能的结果是,我们将无法适当地欣赏参考常微分方程确实存在的水平渐近线。然而,这种方法允许利用神经网络来“学习”目标 ODE 参数的分布,并给出有用的预测区间和中值输出。我对这种方法很感兴趣,并希望其他人会受到启发,利用概率输出进行数据建模(特别是像神经网络这样的黑盒模型)。
PyMC3 中的贝叶斯分层建模
原文:https://towardsdatascience.com/bayesian-hierarchical-modeling-in-pymc3-d113c97f5149?source=collection_archive---------2-----------------------
贝叶斯统计
治愈你模特的健忘症

在 Unsplash 上由 Rob Pumphrey 拍摄的照片
两种方法的故事
有时,当你试图在一个完全异构的数据集上进行机器学习时,你会面临选择的痛苦。作为我所说的异构数据集的一个例子,考虑一个简单的身高数据集。

图片由作者提供。
这个数据真正重要的特征是身高。然而,我们也可以在这里找到两个不同的群体:男性和女性。仅由男性组成的子数据集本身是同质的,仅由女性组成的子数据集也是如此,但是将两者放在一起会产生异质数据集。
给定一些异构数据,您可以:
- 在完整的数据集上构建一个大模型,或者
- 在数据集更小、更同质的部分上构建多个模型。

图片由作者提供。
利弊
构建一个大模型,也被称为(完全)池化,通常是最简单的方法:你把所有的样本放在一起,忘记不同的组。然而,如果大模型过于简单,它可能会忽略数据中的不同细微差别,从而导致不符合。当使用高度可解释的模型(如线性模型)时,这个问题会很快发生。如果您可以并且想要使用黑盒方法,如梯度增强,该模型可以自己发现并学习不同的子数据集,但代价是降低了可解释性。
建立几个更小的模型似乎是一个更好的主意:你将数据集分割成不同的更同质的部分,并为每个部分建立一个更小的模型。由此产生的模型被称为非池化模型。这样,每个模型都可以很好地处理一小部分数据,并且它们应该一起形成一个不错的模型。这种方法的明显缺点是你必须适应许多模型,但是当小数据集变得太小时,一个更严重的问题出现了:过度适应。
为了说明这一点,假设我们的身高数据集由 100 个样本组成:97 名女性和 3 名男性。我们现在想通过取身高的样本平均值来估计每组的平均身高。虽然女性的猜测应该是相当不错的,但男性的结果将非常不可靠,因为观察的数量很少。主要问题如下:
子模型是完全独立的。被训练的每个子模型不向其他子模型传递任何信息。在某种意义上,总模型忘记了它在每个子数据集上做什么。
未冷却的模型。
模特的健忘症
虽然训练孤立的模型在某些情况下可能有意义,但在我看来,子模型共享知识往往更好。
举个现实生活中的例子,在 小酒馆到德国金色 M 买个芝士汉堡的等待时间平均需要两分钟(这个数字是我编的)。如果我现在去法国,平均等待时间很可能与这两分钟相差不远。日本可能也是如此。当然,一些国家更快,一些国家平均更慢,但是不管是哪个国家,等待一个汉堡一个小时应该是一个相当罕见的例外。所以,如果我饿了,想在法国吃一个芝士汉堡,我会想到要等多久,也许我是对的。我可以将从一个小组(德国)学到的知识转移到另一个小组(法国)进行预测。这同样适用于 heights 数据集。
一个有用的默认
当然,你也可以创造一些情景,让人们误以为记住了你学过的东西。在医生办公室的等待时间可能不会给你任何关于交通灯绿色阶段持续时间的指示,所以你不应该试图在这两个不相关的变量之间分享知识。
然而,如果我们诚实,通常我们不会看到来自完全不相关和随机来源的数据。通常情况下,这是相当一致的,只是在国家、性别、商店等群体中有一些变化,因此
我觉得分享知识往往是一个很好的默认。
那么,如何让我们的模型有更好的记忆呢?或者说,换一种方式,如何教会子模型之间的沟通和协同工作?这有几种方法,例如,在神经网络的情况下,参数或权重分配,这里我不打算详细说明。
然而,正如你从这篇文章的标题中所知道的,我们将转向贝叶斯,并学习如何做贝叶斯分层建模作为我们问题的可能解决方案。我们将再次使用 PyMC3 ,因为它是一个不错的包。
如果您从未听说过贝叶斯统计或 PyMC3,并想学习它,请查看我关于这个有趣主题的其他介绍性文章。
走吧!
PyMC3 中的分层建模
首先,我们将重新审视两者,在贝叶斯设置中的池化和非池化方法,因为它是
- 一个很好的练习,而且
- 非池化和层次化(也称为部分池化或多级)的代码库非常相似。
在我们开始之前,让我们创建一个数据集进行实验。我们将创建一个简单的一维回归问题,即只有一个特征和一个目标。有八个不同的组,每个组都有自己的斜率,固定截距为零。
import numpy as np
np.random.seed(0) # to keep it reproducible
mean_slope = 2 # the 8 different slopes have a mean of 2
slopes = np.random.normal(mean_slope, size=8)
groups = np.array(50*[0, 1, 2, 3, 4, 5, 6] + 5*[7])
x = np.random.randn(355)
y = slopes[groups] * x + 0.1*np.random.randn(355)
groups变量包含每个观察值所属的组。0 到 6 组各有 50 个观察值。然后,最后是少数群体 7,只有五个观察值。
作为一个小指南,要获得属于组 2 的元素,可以使用x[groups==2], y[groups==2]。这个子数据集的斜率是slopes[2]。
为了增加趣味,让我们在这个少数群体中加入局外人。
y[-1] = 30 # the last 5 observations are from minority group 7
y[-2] = 30
导入我们最喜欢的贝叶斯库后
import pymc3 as pm
import arviz as az
我们可以开始建模了!
混合模型
我们将从忽略组开始,将这个数据集视为一个大块。PyMC3 中不带截距的简单贝叶斯线性回归如下所示:
with pm.Model() as pooled_model:
slope = pm.Normal('slope', 0, 20)
noise = pm.Exponential('noise', 0.1)
obs = pm.Normal('obs', slope*x, noise, observed=y)
pooled_trace = pm.sample(return_inferencedata=True)
az.plot_posterior(pooled_trace, var_names=['slope'])
输出将是

图片由作者提供。
这基本上没用,因为我们只得到一个单一的斜率,但这并不奇怪。下一个最好的方法是为每组引入一个斜率。
无池模型
with pm.Model() as unpooled_model:
slope = pm.Normal('slope', 0, 20, shape=8)
noise = pm.Exponential('noise', 10)
obs = pm.Normal('obs', slope[groups]*x, noise, observed=y)
unpooled_trace = pm.sample(return_inferencedata=True)
az.plot_posterior(unpooled_trace, var_names=['slope'])
我们现在有八个不同的斜坡,都是独立训练的:

图片由作者提供。
我们也可以仅标绘 94%的高密度区间(HDI ),即包含 94%后位质量的短可信区间
az.plot_forest(unpooled_trace, var_names=['slope'], combined=True)
我们得到了

图片由作者提供。
你可以看到第 0 组到第 6 组的斜率很小,而第 7 组的斜率很大。但这是完全错误的,因为我们所有的斜率都应该在值2左右。发生了什么事?简单:我们通过在最小的群体中引入异常值来欺骗模型。
这正是我之前谈到的问题:组 7 的子模型没有机会,因为它不知道组 0 到组 6 中发生了什么。它不知道斜率通常在 2 左右。
所以,让我们来解决这个问题。
部分池化 aka 层次模型
with pm.Model() as hierarchical_model:
mu_slope = pm.Normal('mu_slope', 0, 1) # hyperprior 1
sigma_slope = pm.Exponential('sigma_slope', 13) # hyperprior 2
slope = pm.Normal('slope', mu_slope, sigma_slope, shape=8)
noise = pm.Exponential('noise', 10)
obs = pm.Normal('obs', slope[groups]*x, noise, observed=y)
hierarchical_trace = pm.sample(
return_inferencedata=True,
target_accept=0.995
)
az.plot_posterior(hierarchical_trace)
那么,现在这是什么?在无池模型中,我们通过
slope = pm.Normal('slope', 0, 20, shape=8)
我们告诉模型,斜率应该在零左右,但是具有相当大的 20 的标准偏差。
在分层模型中,我们定义了所谓的超先验来为斜率先验找到更好的均值和标准差。重要的是:
mu_slope = pm.Normal('mu_slope', 0, 1)
sigma_slope = pm.Exponential('sigma_slope', 13)
slope = pm.Normal('slope', mu_slope, sigma_slope, shape=8)
我们用mu_slope代替零,用sigma_slope代替二十,就这么简单。这两个都是随机变量,我们可以用贝叶斯推理来学习。mu_slope和sigma_slope被称为超优先级,例如,决策树的最大深度被称为超参数。它们都比slope高一个层级,因为在slope可以计算之前,它们必须首先被评估。
注意:我在
sample方法中添加了target_accept=0.995来改进采样,因为从这个嵌套的后验模型中采样不再像对非 pool 模型那样容易。我可以在另一篇文章中进一步解释这一点。
后验看起来像这样:

图片由作者提供。

图片由作者提供。
这仍然不是完美的,但比无池模型更接近事实。这是因为该模型还试图使用mu_slope超级函数来计算斜率平均值。真实的先验应该是 2,然而,由于异常值,模型认为它大约是 3。

图片由作者提供。
尽管如此,我们在非 pool 模型中看到的大斜率15将拉向这个大约 3 的mu_slope。其他参数也是如此:
在分层建模中,所有参数都被拉向全局平均值。这种效应被称为收缩。
总而言之,层次模型是明显的赢家。作为最后一步,让我们使用标牌符号直观地比较三种型号。这是一个不言自明的模型可视化表示,可能对你们当中的视觉学习者有所帮助。
使用平板符号比较模型
PyMC3 有一个奇妙的功能pm.model_to_graphviz(model)以一种很好的方式显示你的模型。

图片由作者提供。
我喜欢这种表示,因为你可以清楚地看到模型的某种演变。在混合模型中,我们从单一斜率开始。然后我们增加斜率的数量,用数字为 8 的方框表示。
这个符号是为斜坡画 8 个圆的捷径。我猜这个小盒子应该是一张桌子,上面叠放着 8 个盘子,我们从上面看,因此得名。
这个过程的最后一步是在顶层引入一个新的变量层,即超优先级。
结论
在本文中,我们讨论了处理异构数据集时不同的建模方法。起初,我声称有两种方式:池化和非池化模型。很明显,我在撒谎,正如我们已经看到的分层建模一样。
一个有趣的观察是,您可以将分层建模看作是对非池化建模的推广。如果您将超优先级设置为某个常量随机变量,您将再次以无池方法结束。否则,层次模型通过跟踪全局参数来做一些不同的事情,例如mu_slope,它充当我们想要估计的实际参数的种子。作为一个很好的副作用,我们也得到这些全局参数的估计。如果在不同的组中没有值得分享的东西,层次模型也会学习这个,这很好。这就是为什么我认为你应该尽可能使用层次化的方法,而不是非池化的方法:通常这没有坏处。
当使用分层建模而不是无池建模时,唯一可能出错的是有更多的参数要估计,并且由于嵌套的参数,估计也变得更加困难。你必须使用一些技巧,比如改变 MCMC 采样参数或者引入所谓的非中心变量。
一个以为中心的 ( 我称之为嵌套的)变量类似于另外两个随机变量a和b的pm.Normal('X', a, b),这就是我们上面用过的。然而,在正态分布的特殊情况下,你也可以写a + b*pm.Normal('X', 0, 1),这从统计学的角度来看是等价的,但对于计算后验分布的 MCMC 算法来说是一个巨大的差异。
尽管如此,如果你能克服计算问题,我认为分层建模通常是一条值得尝试的道路。
作为一个额外的资源,看看托马斯·威奇和达内·埃尔伯斯写的这篇不错的博文。
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何,计划获得一个中等订阅量,
为什么不做 通过这个环节 ?这将对我帮助很大!😊
透明地说,给你的价格不变,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我!
如果你有任何问题,请在 LinkedIn 上给我写信!
Python 中的贝叶斯推理和马尔可夫链蒙特卡罗抽样
原文:https://towardsdatascience.com/bayesian-inference-and-markov-chain-monte-carlo-sampling-in-python-bada1beabca7?source=collection_archive---------3-----------------------
通过一个用 Python 实现的掷硬币的深入示例,介绍如何使用贝叶斯推理和 MCMC 采样方法来预测未知参数的分布。

图片来自 Adobe Stock
介绍
本文将一个基本的抛硬币例子推广到一个更大的环境中,在这个环境中,我们可以检查贝叶斯推理和马尔可夫链蒙特卡罗抽样在预测未知值方面的用途和能力。有许多有用的软件包可以使用 MCMC 方法,但是这里我们将从头开始用 Python 构建我们自己的 MCMC,目标是理解其核心过程。
什么是贝叶斯推理?
贝叶斯推断是一种方法,当我们收集更多的数据和证据时,我们使用贝叶斯定理来更新我们对概率或参数的理解。
什么是马尔可夫链蒙特卡罗抽样?
MCMC 方法(通常被称为)是一种用于从概率分布中取样的算法。这类算法采用随机抽样来获得数值结果,随着样本数量的增加,这些结果会收敛于事实。有许多不同的算法可以用来创建这种类型的采样链——我们在这个具体例子中使用的算法称为 Metropolis-Hastings 算法。MH 实现允许我们从一个未知的分布中抽取样本,只要我们知道一个与我们想要从中抽取样本的分布的概率密度成比例的函数。不需要知道精确的概率密度,仅仅是它的比例性就使得 MCMC-MH 特别有用。我们将在这个例子的后面描述算法的详细步骤。
硬币工厂问题
这个例子将模拟掷硬币的结果的概率,但是在一个扩展的上下文中。想象一下,一个全新的硬币工厂刚刚建成,生产一种新的硬币,他们让你确定工厂生产的硬币的一个参数,即硬币翻转时正面/反面落地的概率。我们称之为硬币的“偏向”。每枚硬币都有自己的偏差,但鉴于它们是在相同的过程中生产的,只有轻微的差异,我们预计工厂不会随机生产硬币,而是围绕“工厂偏差”生产。我们将使用来自特定硬币和工厂偏差的信息来创建概率分布,以确定硬币最有可能产生的偏差。用贝叶斯的话来说,我们将使用可能性(硬币数据)和先验(工厂偏差)来产生硬币偏差的后验分布。

图片来自 Adobe Stock
于是,工厂开张并生产了第一枚硬币。鉴于它是一种新的硬币和铸币厂,我们不知道它在翻转时会有什么表现(假装我们不知道硬币通常是如何工作的,我们试图预测一个“未知”的参数)。因此,我们用第一枚硬币做了一个实验,将它翻转 100 次,记录下它正面着地的次数——57 次。为了更新我们对工厂偏差的理解,我们将在生产更多硬币时这样做,但首先,让我们只分析第一枚硬币。
贝叶斯背景下的问题
在我们走得太远之前,我们需要在贝叶斯定理的背景下定义这个问题。等式的左边称为后验;一般来说,就是一个假设( H )给定一些证据( E )的概率。在右边的分子中,我们有我们的可能性(假设我们的假设为真,看到证据的概率),乘以先验(假设的概率)。左边的分母是边际可能性或证据;这是观察证据的概率。幸运的是,我们将不需要使用边际可能性来抽样后验概率。

贝叶斯定理-作者图片。
在大多数实际应用中,直接计算后验分布是不可能的,这就是为什么我们采用数字采样技术,如 MCMC。
在后面的
那么我们对硬币厂感兴趣的后验概率是多少呢?这是概率, P ,工厂生产一个有偏差的硬币, p ,给定我们的数据, x 人头数— P(p|x) 。定理的其余部分可以写成如下:

我们硬币工厂背景下的贝叶斯法则。
这里需要记住的是,我们预测的是后验概率分布( P(p|x) )一枚硬币有一定概率正面朝上,或者偏向( p ),这是两回事。工厂偏差是以一定偏差生产的硬币的概率分布;这是 P(p) ,先验。
可能性—二项式分布
这里的似然函数是观察到正面的概率, x,给定一个有偏差的硬币 p. 对于抛硬币,这个函数可以用二项分布来精确描述。对于有偏差 p 的硬币,观察到 x 正面出 n 翻转的概率可以写成:

二项式分布-作者图片
值得注意的是,我们目前不知道给定硬币的值 p 。这个值是我们的 MCMC 将随机抽样的值。用一个随机值初始化 p 后,经过多次采样,模型会收敛到 p 的真实值。
让我们开始用 Python 编写这个例子。我们需要定义第一次硬币实验中观察到的数据,以及根据给定的数据从二项分布中得出概率的似然函数。Scipy.stats 是一个很棒的 Python 库,可以很容易地定义像二项式这样的分布,这也是我在这个例子中使用的。
在先的;在前的
接下来,我们需要定义我们的先验函数, P(p) 。p 的值只能在 0 和 1 之间,0 代表硬币永远不会正面朝上,1 代表硬币永远正面朝上。请记住,工厂只生产了一枚硬币,所以我们没有任何信息可以预期 p 的先验概率是多少(假装我们不知道硬币是如何工作的)。在这个问题的背景下,由于只生产了一枚硬币,我们还不知道工厂偏见可能是什么。因此,我们将使用所谓的均匀先验。在贝叶斯推理的上下文中,这意味着我们赋予概率 p 在 0 和 1 之间的任意值相等的权重。
我们可以用 Scipy 和均匀分布 PDF 轻松做到这一点。这种默认分布只存在于 0 到 1 之间,正如我们所需要的。
既然我们已经定义了似然和先验,我们可以继续理解和编码马尔可夫链。
大都会-黑斯廷斯 MCMC
如上所述,这些方法从连续的随机变量中抽取样本——在我们的例子中是针对 p 。我们将使用的 MCMC 是随机游走类型,它随机生成样本,并根据它们与模型的拟合程度来决定是否保留它们。
接受比率
Metropolis-Hastings 算法相当简单,但首先,我们需要定义如何接受或拒绝新的样本抽取。每次迭代,将为 0 和 1 之间的 p 建议一个新值,我们将这个建议值称为p′。如果这个值比前一个值更好,我们只想接受并更新它。这是通过计算接受率来完成的。这个接受率是我们的贝叶斯定理对建议值与先前值的比率,如下所示。

接受率, R —作者图片
这里有几点需要注意。首先,你可能已经注意到,这个接受率不包括贝叶斯定理的边际似然(证据)部分,我们也没有在上面为它定义一个函数。这是因为证据不会因为新的 p 值而改变,因此在这个比率中抵消了它自己。这太棒了,因为计算贝叶斯定理的边际似然部分在实践中通常是极其困难或不可能的。MCMC 和贝叶斯推理允许我们在不知道边际可能性的情况下对后验样本进行采样!
第二,这里任何大于 1 的值都意味着建议值更好,应该接受。接受新值的第二部分是将 R 与 0 和 1 之间的另一个随机抽取值进行比较,因此习惯上只在 R 更高时将 R 设为 1。
为了简单起见,我们将编写一个函数来计算这个接受率,以便在我们的采样链循环中轻松实现。
让我们明确定义 MH 算法的步骤,这样就更清楚了。
采样算法
我们已经定义了可能性、先验和接受概率的函数。在循环之前,我们必须做的最后一件事是用 0 到 1 范围内的随机值初始化 p 。
以下是我们的 Metropolis-Hastings 算法的步骤:
- 在 0 和 1 之间随机提出一个 p 的新值,称之为p′(或 p_new)。
- 计算接受率 r。
- 生成另一个介于 0 和 1 之间的均匀随机数,称之为 u 。
- 如果 u < R ,接受新值并设置p = p′。否则,保持 p 的当前值。
- 记录该样品的 p 的最终值。
- 多次重复步骤 1 到 5。
非常简单。在我们编写代码之前,让我们先来研究一下 MCMC 中使用的其他一些常见概念。
老化
MCMCs 是随机初始化的,必须收敛到正确的值,这通常需要相当多的样本。当绘制我们的结果和后验分布时,在模型收敛之前包含这些早期样本是无效的。因此,我们实施了所谓的“老化”,即排除第一批不太准确的样本。当整个链约为 10k–20k 时,MCMCs 的老化通常约为 2000–5000 个样本。
落后
MCMCs 需要考虑的另一个非常重要的问题是样本独立性。这里的新样本通常依赖于前一个样本,因为有时我们不接受新的随机值而保留旧值。为了解决这个问题,我们实现了所谓的“滞后”。滞后是指我们不是记录每一个样本,而是每隔一个,或者每五个或十个样本记录一次。
模拟
太好了,我们现在拥有了编写和运行 MCMC 所需的一切。
可视化结果
MCMC 结果通常以两种方式绘制——后验分布和迹线图。后验概率可以显示在直方图中,在直方图中我们可以直观地检查最可能的值和方差。轨迹图显示了每个样本迭代的 p 的值,并显示了 MCMC 的行为和收敛。后验分布不应包含老化样本,但包含迹线老化可以帮助我们检查模型从哪里开始,以及它收敛得如何。老化样本不包括在下面的跟踪图中。

后验分布和迹线——作者图片。
检查结果,我们可以看到我们的后验正态分布。我们还可以从跟踪图中看到,我们在收敛值附近进行了很好的随机采样,这很好。当提取后验值时,对于分布的其余部分,使用 p 的最后值并不总是准确的。由于这个原因,后验值通常被认为是分布的平均值。在这种情况下,我们的平均后验值是 0.569。
这个值几乎是我们预测的,如果我们把这个硬币的数据的频率概率,57/100 头。我们的 MCMC 预测这一点的原因是因为这是第一枚硬币,我们不太了解它们应该如何表现。在均匀先验的情况下,后验受似然函数(即数据)的影响更大。贝叶斯推断的下一步是用更多的数据更新我们的理解,所以让我们保持工厂运转,制造更多的硬币来测试。

照片由 GSJJ 在 Unsplash 上拍摄
更新我们的理解
我们等一会儿,工厂生产了 500 枚硬币。我们运行同样的 100 次翻转实验,并记录每枚硬币的最可能偏差。让我们绘制一个直方图,并检查产生的偏差的分布,以了解工厂偏差。

500 硬币工厂偏见-作者图片。
检查这些数据,我们了解到平均偏差是 0.511,标准偏差是 0.049。数据看起来是正态的,所以让我们用这些参数的正态分布对其建模,这显示为红色。
这个分布包含了我们预计在这个工厂生产的硬币更有可能出现哪些偏差的信息。像这样更新我们的理解,将会给我们一个比我们以前的,不知情的,一致的先验更准确的结果。这正是贝叶斯推理的目的——我们可以简单地更新我们的先验函数来表示工厂偏差的数据。
工厂偏见先验-作者图片。
现在我们已经用更多的先验信息改进了我们的模型,让我们生产第 501 枚硬币并进行同样的实验。在这个实验中,我们在 100 次投掷中得到 63 次投掷。我们必须像以前一样根据这些数据建立我们的似然函数:
很好,现在让我们看看包含工厂偏差的信息如何影响 MCMC 的结果,以及我们认为这枚硬币的真实偏差是多少。我已经运行了一个 MCMC,使用了与上面相同数量的样本和参数,但是使用了更新的先前和新的硬币数据。下图显示了第 501 枚硬币的后验分布和迹线。

后验和迹线来自 MCMC,更新了前验——由作者更新。
尽管这枚硬币的数据表明偏差约为 0.63,但我们的贝叶斯推理模型表明实际值更接近 0.53。这是因为我们的知情先验函数在模型中占有权重,告诉我们即使我们观察到这种硬币有 63 个头像,鉴于硬币的平均偏差约为 0.51,我们预计第 501 个头像的偏差更接近工厂偏差。即使这枚硬币有 0.5 的偏差,观察 100 次投掷中的 63 次投掷也不是完全不可能的,我们不应该假设这个数据代表确切的值。先验函数具有权重,就像似然性具有通知后验分布的权重一样。如果我们要生产成千上万的硬币,并告知先前的分布更多,这将在模型中给予它更高的权重。这种用更多信息来更新我们的理解以预测未知参数的想法正是贝叶斯推理有用的原因。正是利用更多更好的数据来调整和操作这些可能性和先验函数,使我们能够改进和充实我们的推理模型。
结论
当实现贝叶斯推理和 MCMC 时,人们通常不希望知道后验分布是什么样子,因为我们在这里是编造数据的。这是推断未知参数的强大工具——只需知道后验分布与什么成比例(例如,线性模型和预测参数斜率和截距,或逻辑模型和参数α和β)。这允许我们做一些事情,比如预测我们无法解决的高维积分的结果——信不信由你,你可以只用随机性和统计学来做!
参考
除了上面给出的维基百科链接之外,这篇文章对于结合贝叶斯推理和 MCMC 的上下文非常有帮助。
接下来,我建议利用 PyMC3 这样的包来进行贝叶斯推理,而不是从头开始编码。Will Koehrsen 的这篇文章提供了一个很棒的真实例子,值得一看:
如果你希望深入研究使贝叶斯推理和 MCMC 成为可能的数学和推理,我强烈推荐这篇文章— 贝叶斯推理问题,MCMC 和变分推理。
如果你想了解更多关于我的实施的信息,或者想给我反馈(非常感谢),请给我发信息或电子邮件到 jonny.hofmeister@gmail.com。
谢谢大家!
贝叶斯线性回归:基于 arm 的汽车销售分析
原文:https://towardsdatascience.com/bayesian-linear-regression-analysis-of-car-sales-with-arm-in-r-b1147e79a9a4?source=collection_archive---------22-----------------------
使用贝叶斯线性回归解释不确定性

来源:图片来自 Pixabay
线性回归是最常用也是最有用的建模工具之一。
虽然没有任何形式的回归分析可以接近现实,但它可以很好地预测因变量,并确定每个自变量影响因变量的程度,即每个系数的大小和重要性。
然而,传统的线性回归可能有缺点,因为这种方法不能真正解释估算中的不确定性。
然而,贝叶斯线性回归可以作为这个问题的解决方案-通过重复模拟提供许多不同的系数值估计。例如,如果我们希望进行 20,000 次模拟,这种方法可以返回 20,000 条不同的回归线,这些回归线将说明在各种情况下因变量的潜在波动。
为了说明这一点,让我们来看看 R 中的 arm 库如何使用贝叶斯线性回归来预测汽车销量。
标准线性回归
该分析是在 Kaggle 可用的汽车销售数据集上进行的,该数据集根据 CC0 1.0 通用(CC0 1.0)公共领域专用许可提供。
在第一种情况下,设计线性回归来确定销售额(以千计)如何根据以下因素波动:
- 发动机尺寸
- 车型
- 马力
- 轴距
- 宽度
- 长度
- 整备重量
- 燃料容量
- 燃料效率
- 功率性能因数
这里是线性回归和输出结果。
Call:
lm(formula = Sales_in_thousands ~ Engine_size + Vehicle_type +
Horsepower + Wheelbase + Width + Length + Curb_weight + Fuel_capacity +
Fuel_efficiency + Power_perf_factor)Residuals:
Min 1Q Median 3Q Max
-104.47 -29.09 -6.86 14.00 337.19Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -302.7471 154.7623 -1.956 0.05242 .
Engine_size 31.7419 11.0641 2.869 0.00475 **
Vehicle_typePassenger -45.1881 19.3850 -2.331 0.02117 *
Horsepower -0.5830 0.8825 -0.661 0.50990
Wheelbase 3.7231 1.3670 2.724 0.00727 **
Width 0.8454 2.4341 0.347 0.72889
Length 0.7609 0.8295 0.917 0.36054
Curb_weight -63.7597 20.4988 -3.110 0.00226 **
Fuel_capacity -1.1049 2.7603 -0.400 0.68955
Fuel_efficiency 0.5560 2.3522 0.236 0.81350
Power_perf_factor 0.2592 1.9605 0.132 0.89502
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 58 on 141 degrees of freedom
(5 observations deleted due to missingness)
Multiple R-squared: 0.3391, Adjusted R-squared: 0.2922
F-statistic: 7.235 on 10 and 141 DF, p-value: 3.643e-09
我们可以看到,发动机尺寸、车型、轴距和整备质量在 5%的水平上具有统计显著性(一些变量在 1%的水平上具有显著性)。
在删除无关紧要的变量并在迭代中再次生成回归后,最终的回归结果如下:
Call:
lm(formula = Sales_in_thousands ~ Vehicle_type + Wheelbase +
Curb_weight)Residuals:
Min 1Q Median 3Q Max
-107.15 -32.26 -9.68 18.33 339.38Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -288.840 76.741 -3.764 0.000239 ***
Vehicle_typePassenger -44.626 12.673 -3.521 0.000568 ***
Wheelbase 5.287 0.816 6.479 1.23e-09 ***
Curb_weight -57.100 10.697 -5.338 3.39e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 58.67 on 151 degrees of freedom
(2 observations deleted due to missingness)
Multiple R-squared: 0.2787, Adjusted R-squared: 0.2644
F-statistic: 19.45 on 3 and 151 DF, p-value: 1.027e-10
重要变量是车辆类型、轴距和整备质量。虽然 27.87% 的 R 平方在统计学上较低,但这并不一定意味着模型不好。事实上,有许多不同的因素可以影响汽车销售,这里没有考虑。
模型中的其余变量被表示为非常重要,这表明它们与确定汽车销售相关。让我们更详细地分析模型系数。
- 在这种情况下, -288.84 的截距是虚假的,但理论上代表了所有其他系数为零时的最小销售额。但是,销售额不能为负,因此系数本身没有任何意义。
- 由于 Vehicle_typePassenger 变量的系数为-44.626,这意味着如果一种车型被归类为“客车”而不是“轿车”,销售额将下降 $44.626 。
- 轴距每增加一个单位,汽车销量就会增加5.287 美元。
- 整备质量每增加一个单位,汽车销量就会减少-57.10 美元。
使用方差膨胀因子检验时,没有一个变量的多重共线性检验为阳性(即 VIF 统计值大于 5)。这表明没有一个变量彼此显著相关,因此扭曲了回归结果。
> library(car)
> vif(M1)
Vehicle_type Wheelbase Curb_weight
1.384649 1.746395 2.035252
直方图表明汽车销售的分布是非正态的。因此,在这种情况下,异方差性没有被测试(或者实际上被校正)。事实上,正态性并不是生成线性回归模型的必要条件。

来源:RStudio 输出
贝叶斯线性回归
“所有的模型都是错的,但有些是有用的。”
乔治·e·p·Box
虽然上述线性回归提供了信息,但它的一个缺点是没有考虑到估计中的不确定性。
例如,我们真的可以期望轴距每增加一个单位,汽车销量总会增加 5.287 美元吗?
事实上,我们知道情况并非如此。相反,我们想想出一种方法来解释估计中的不确定性,并生成一系列广泛的销售预测。
毕竟,贝叶斯分析的目的是以概率的方式分析数据——考虑尽可能多的潜在情况。
考虑到这一点,R 中的 arm 包用于生成 20,000 条不同的回归线,以说明估计中的不确定性。
我们可以看到,生成模拟时,会生成具有不同系数估计的回归。
> library(arm)
> M1.sim <- sim(M1, n.sims=20000)
> M1.sim
> coef.M1.sim <- coef(M1.sim)
> coef.M1.simAn object of class "sim"
Slot "coef":
(Intercept) Vehicle_typePassenger Wheelbase Curb_weight
[1,] -142.29350 -40.1585711 4.046482 -62.73836
[2,] -311.43351 -46.1396357 6.056344 -74.03777
...
[249,] -249.44178 -52.5240319 5.590081 -76.08825
[250,] -184.34866 -60.6832116 4.493316 -59.79492
[ reached getOption("max.print") -- omitted 19750 rows ]
此外,还会产生残差(由σhat提取):
> sigma.M1.sim <- sigma.hat(M1.sim)
> sigma.M1.sim
[1] 53.53439 56.59501 62.36744 48.25297 62.11458 65.81519 51.64420
[8] 62.34890 55.86902 52.15755 60.12543 59.68573 55.92115 62.00584
[15] 60.30506 63.08531 56.79228 57.74138 53.94584 57.22139 60.00236
...
[981] 54.00598 63.18356 59.70908 60.27791 64.86504 53.71799 59.88211
[988] 58.08702 56.12842 62.05933 61.02171 54.30973 60.43517 61.74605
[995] 54.91794 60.25361 56.72824 57.06674 61.47696 62.64697
[ reached getOption("max.print") -- omitted 19000 entries ]
现在,可以在分位数的基础上计算系数的不确定性:
> apply(coef(M1.sim), 2, quantile)
(Intercept) Vehicle_typePassenger Wheelbase Curb_weight
0% -589.44627 -98.60129 1.929788 -97.18706
25% -341.31489 -53.40231 4.737972 -64.23857
50% -289.01086 -44.73874 5.287846 -57.07201
75% -237.68266 -36.07124 5.836498 -49.90656
100% 20.27591 11.40947 8.547013 -19.46040
通过观察这些系数,我们可以看到系数本身可能存在显著的变化。
例如,虽然乘用车类型降低了 0%、25%、50%和 75%分位数的销售额,但在 100%分位数的模拟中,销售额实际上是增加的。有没有逆势而上的特殊车型?这个模型可以为进一步研究这个问题提供一个有用的起点。
对于汽车的轴距(前轮和后轮之间的距离),我们可以看到,在 0%分位数时,每增加一个单位对销售额的影响是 1.92 美元,但在 100%分位数时会增加到 8.54 美元。
除了系数估计值之外,我们还可以绘制残差图(由 sigma.hat 提取):

来源:RStudio 输出
以下是基于分位数报告的残差:
> q
0% 25% 50% 75% 100%
47.52279 56.60056 58.82638 61.15704 78.96791
鉴于我们已经看到汽车销售的分布具有强烈的正偏态分布(即,选定的几款汽车显示的销售数字比其余的高得多),这可能是我们看到高不确定性估计值的原因之一,即,50%分位数的不确定性估计值为 58,826 美元。
然而,贝叶斯线性回归在通过生成大范围的模拟和潜在情景来模拟这种不确定性时非常有用。
结论
在本文中,您已经看到:
- 传统线性回归的缺点
- 如何生成贝叶斯线性回归
- 使用 arm 包生成许多回归模拟
- 模型估计的不确定性分析
非常感谢您的宝贵时间,非常感谢您的任何问题或反馈。你可以在michael-grogan.com找到更多我的数据科学内容。
免责声明:本文是在“原样”的基础上编写的,没有担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。作者与本文提及的任何第三方无任何关系。
Bambi 贝叶斯线性回归
原文:https://towardsdatascience.com/bayesian-linear-regression-with-bambi-a5e6570f167b?source=collection_archive---------4-----------------------
利用贝叶斯推理得到你的预测分布
动机
用回归线拟合样本数据时,可能会得到如下的回归线:

作者图片
如果你能得到一个预测的分布,而不是一条回归线,不是很好吗?

作者图片
这就是贝叶斯线性回归派上用场的时候。在本文中,您将学习如何用 Python 构建贝叶斯线性回归。
线性回归到底是什么?
要了解贝叶斯线性回归和普通最小二乘线性回归(OLS)(我们都很熟悉的线性回归)的区别,我们先来了解一下什么是 OLS。
从一个例子开始
理解算法最简单的方法是从一个例子开始。
我们将在 Kaggle 上使用显示学生数学和葡萄牙语成绩的数据集。

作者图片
绘制数据:

作者图片
我们的目标是找到最能描述数学成绩和葡萄牙语成绩之间关系的线性回归线。
如果您有𝑛变量,您的线性回归方程将如下所示:

作者图片
其中𝑦是响应变量,𝑥's 是解释变量,𝛽ᵢ是变量𝑥ᵢ的权重, ε 是误差项。
由于我们的数据中只有一个解释变量,我们的线性回归方程将如下所示:

作者图片
其中,𝑦是预测的葡萄牙语分数,𝑥是观察到的数学分数。
在矩阵形式中,等式变为:

作者图片
𝛽有几个可能的值,但我们将只选择最小化残差平方和(RSS)的𝛽值。RSS 是𝑦ᵢ和𝑦̂ᵢ之间的平方差之和,其中𝑦ᵢ是数据的第一个实际值,𝑦̂ᵢ是使用回归的第一个预测值。

作者图片
最小化 RSS 将给出𝛽.的估计让我们尝试使用 scikit-learn 的线性回归模型来应用这个方法。
绘制回归线:

作者图片
求系数:
array([0.4335796])
找到截距:
7.403346211071996
通过看系数和曲线图,我们可以说,如果数学成绩增加 1,葡萄牙语平均成绩增加 0.43。如果数学成绩为 0,葡萄牙语成绩的预测值为 7.403。
普通最小二乘法返回单点估计。但是如果我们想看到可能的估计值的分布呢?让我们试着用斑比来做这件事。
使用 Bambi 构建贝叶斯线性回归模型
斑比是什么?
Bambi 是用 Python 编写的高级贝叶斯建模接口。它构建在编程框架 PyMC3 之上。因此,Bambi 类似于 PyMC3,但是更容易使用。
要安装 Bambi,请键入:
pip install bambi
建立线性回归模型
使用 Bambi 构建线性回归模型非常简单。既然我们要用mat(数学成绩)来预测por(葡萄牙成绩),我们可以写:
使用 PyMC3 从 4 条链中各抽取 1000 个样本(单次运行 MCMC ):
默认情况下,Bambi 使用family="gaussian",这意味着具有正常误差的线性回归。
分析系数的分布
使用 ArviZ 绘制结果:

作者图片
在上图中,Intercept和mat分别是来自方程𝑦 = 𝛽₀ + 𝛽₁𝑥 + ε的𝛽₀和𝛽₁。左边的图显示了变量的分布。右边的图显示了每次迭代中每个变量的值。
看左边的图,我们可以说:
- 𝛽₀和𝛽₁的分布接近正态分布。
- 𝛽₀的平均值从 7.2 到 7.5。
- 𝛽₁的平均值从 0.42 到 0.44。
这太酷了!我们得到的不是𝛽₀和𝛽₁的单点估计,而是𝛽₀和𝛽₁的分布。
分布的形状也有助于我们理解我们对𝛽₀或𝛽₁.的价值有多确定具体来说:
- 分布的扩散越大(越大【σ】),我们对𝛽₀和𝛽₁.的价值就越不确定
- 分布的扩散越小(越小【σ】),我们对𝛽₀和𝛽₁.的价值就越有把握

作者图片
比较贝叶斯线性回归和 OLS 的结果
与 scikit-learn 的普通最小二乘线性回归生成的𝛽₀和𝛽₁的值相比,Bambi 的贝叶斯线性回归生成的𝛽₀和𝛽₁的平均值如何?从寻找斑比创造的𝛽₀和𝛽₁的意义开始。
𝛽₀:的意义
0.43346411871369533
𝛽₁:的意义
7.403637994335104
它们非常接近 scikit-learn 生成的𝛽₀和𝛽₁的值!
绘制回归线
𝛽₀和𝛽₁.共有 4×1000 = 4000 个样本对于每一对𝛽₀和𝛽₁,我们可以得到𝑦.的一个估计
让我们用 10 对不同的𝛽₀和𝛽₁:来看 10 个预测

作者图片
酷!现在让我们使用𝛽₀ 的平均值和𝛽₁ 的平均值来得到𝑦(用黑线表示)的单一估计值。

作者图片
从上面的图中,我们可以看到黑线很好的呈现了所有的绿线。
所有预测的分布图
将单个预测分布与平均预测分布进行比较的另一种方法是将它们的分布相互重叠。

作者图片
从上面的图中我们可以看到,橙色线(平均预测分布)很好地代表了黑线(观察值)。
绘制预测的最高密度区间
对于𝑥 的特定值,最常见的预测是什么?让我们使用az.plot_hdi (HDI 代表最高密度区间)来解决这个问题。

作者图片
在上面的图中,
- 暗红色区间是给定𝑥值时 38%的预测值所在的区间
- 给定𝑥值,浅红色区间表示 68%的预测值
例如,如果数学成绩是 10,我们可以说葡萄牙语成绩的 38%的预测位于 10.5 到 12.8 之间。
通过创建贝叶斯线性回归模型,我们能够在给定𝑥.值的情况下创建大多数预测所在的区间很酷,不是吗?
结论
恭喜你!您刚刚学习了如何使用 Bambi 获得线性回归模型的系数分布,这使您能够获得可能预测的分布。
有一个分布将会给预测带来更多的洞察力。既然使用 Bambi 创建贝叶斯线性回归模型很容易,为什么不试一试呢?
本文的源代码可以在这里找到:
https://github.com/khuyentran1401/Data-science/blob/master/statistics/bayes_linear_regression/linear_regression.ipynb
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以通过 LinkedIn 和 Twitter 与我联系。
如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:
参考
科尔森,W. (2018 年 4 月 20 日)。贝叶斯线性回归简介。中等。检索于 2021 年 12 月 29 日,来自https://towards data science . com/introduction-to-Bayesian-linear-regression-e66e 60791 ea 7
贝叶斯逻辑回归
原文:https://towardsdatascience.com/bayesian-logistic-regression-53df017ba90f?source=collection_archive---------9-----------------------
从零开始用朱莉娅语言

变化参数分布的模拟。图片作者。
如果您曾经搜索过评估模型准确性的评估指标,那么您很可能会发现许多不同的选项可供选择。从某种意义上说,准确性是预测的圣杯,所以机器学习社区花大量时间思考它一点也不奇怪。在一个越来越多的高风险决策被自动化的世界中,模型准确性实际上是一个非常有效的关注点。
但是,这种模型评估的方法看起来像是自动化决策制定的一种可靠而完整的方法吗?我们没有忘记什么吗?有些人会说,我们需要更多地关注模型的不确定性。无论你对你的模型进行了多少次交叉验证,优化的损失指标以及它的参数和预测仍然是固有的随机变量。仅仅关注预测的准确性而完全忽略不确定性会给自动决策系统带来错误的信心。因此,任何从数据中学习的可信的方法至少应该对其自身的不确定性保持透明。
我们如何估计模型参数和预测的不确定性? Frequentist 不确定性量化方法通常涉及基于渐近假设或自举的封闭型解决方案(例如,参见此处的逻辑回归的)。在贝叶斯统计和机器学习中,我们关心的是对模型参数的后验分布建模。这种不确定性量化方法被称为贝叶斯推理,因为我们以贝叶斯方式处理模型参数:我们基于先验知识或信念对其分布做出假设,并根据新证据更新这些信念。频率主义者的方法避免了明确先前信念的需要,这在过去有时被认为是不科学的。然而,频率主义者的方法有自己的假设和缺陷(例如,参见 Murphy (2012))的讨论)。不深入讨论这个问题,现在让我们看看贝叶斯逻辑回归是如何自下而上实现的。
基本事实
在本帖中,我们将使用由二进制标签和相应的特征向量组成的合成玩具数据集。使用合成数据的好处是,我们可以控制生成数据的基本事实。特别地,我们将假设二元标签确实是由逻辑回归模型生成的。从混合高斯模型中生成特征。
为了给我们的例子增加一点生气,我们假设二进制标签根据猫和狗的身高和尾巴长度将样本分为猫和狗。下图显示了二维特征域中的合成数据。在下一节介绍贝叶斯逻辑回归之后,我们将使用这些数据来估计我们的模型。

地面真相标签。图片作者。
数学
在 Medium 上的文章中加入数学仍然有点麻烦,所以这里我们将完全依靠直觉,完全避免公式。使用 Julia 语言的好处之一是它允许使用 Unicode 字符,所以我们将在下面看到的代码看起来几乎和数学一样。如果你想看到完整的数学处理,以全面理解所有的细节,请随时查看我的网站上这篇文章的扩展版本。
问题设置
贝叶斯逻辑回归的起点是贝叶斯定理,它正式声明参数的后验分布与两个量的乘积成比例:给定参数的观察数据的可能性和参数的先验密度。应用到我们的上下文中,可以直观地理解如下:我们关于逻辑回归系数的后验信念由我们的先验信念和我们观察到的证据(即数据)形成。
在假设单个标签-特征对独立地分布和相同地分布的情况下,它们的联合似然性就是它们单个密度的乘积(伯努利)。关于参数的先验信念由我们决定。在实践中,它们可能来自以前的实验。这里我们将使用零均值球面高斯先验,原因将在下面进一步解释。
与线性回归不同,估计或最大化后验概率没有封闭形式的解析解,但幸运的是,精确的近似值确实存在(Murphy 2022)。一种最简单的方法叫做拉普拉斯近似法,实现起来非常简单,计算起来也非常高效。它依赖于以下观察结果:在高斯先验假设下,逻辑回归的后验概率也近似为高斯分布:特别是,该高斯分布以最大 T2 后验概率(MAP)估计为中心,其协方差矩阵等于在该模式下评估的逆 Hessian 矩阵。下面我们将看到如何估计地图和相应的黑森。
解决问题
实际上,我们不会直接最大化后验概率。相反,我们最小化负对数似然,这是等价的,并且更容易实现。下面的 Julia 代码显示了这个损失函数及其导数的实现。
免责声明 ❗️ 我应该提到这是我第一次用 Julia 编程,所以对于任何一个 Julia 的专业人士:请容忍我!非常乐意在评论中听到你的建议。
如您所见,负对数似然性等于两项之和:首先是(对数)伯努利分布之和(对应于数据的似然性),其次是(对数)高斯分布(对应于我们先前的信念)。
拉普拉斯近似下贝叶斯逻辑回归的损失函数及其导数。
由于最小化这个损失函数是一个凸优化问题,我们有许多有效的算法可供选择来解决这个问题。有了 Hessian,使用二阶方法似乎是很自然的,因为包含关于损失函数曲率的信息通常会导致更快的收敛。这里我们将这样实现牛顿法:
Julia 语言中带 Arminjo 回溯的牛顿法。
后验预测
假设现在我们已经使用训练数据训练了贝叶斯逻辑回归模型作为我们的二元分类器,并且新的未标记样本到达。与任何二元分类器一样,我们可以通过简单地将新样本插入到我们的拟合模型中来预测丢失的标签。如果在训练阶段,我们发现模型达到了很好的精度,我们可以期待良好的样本外性能。但是因为我们仍然在处理一个随机变量的期望值,我们通常想知道这个预测有多嘈杂。
形式上,我们对后验预测分布感兴趣,它没有任何进一步的假设,是一个数学上难以处理的积分。它可以通过蒙特卡洛进行数值估计——通过简单地从后验分布中重复采样参数——或者通过使用所谓的概率单位近似值。后者利用了 sigmoid 函数可以由重新调整的标准高斯 cdf 很好地近似的发现(见下图)。以这种方式近似 sigmoid 函数允许我们导出后验预测的解析解。这种方法用于生成下一节中的结果。

概率单位近似的演示。图片作者。
估计值
下面的第一张图显示了在不同程度的先验不确定性下,高度和尾长系数的后验分布。红点表示无约束最大似然估计(MLE)。注意,随着先验不确定性趋于零,后验不确定性接近先验不确定性。这是很直观的,因为我们已经强加给自己,我们对先前的信念没有不确定性,因此再多的新证据也不能把我们推向任何方向。相反,对于非常大的先验不确定性,后验分布以无约束极大似然估计为中心:先验知识非常不确定,因此后验分布由数据的似然性决定。

不同先验不确定度σ下的后验分布。图片作者。
后验预测呢?情况类似:因为对于非常低水平的先验不确定性,后验完全由零均值先验支配,所以所有样本都被分类为 0.5(下图左上图)。随着我们逐渐增加先验的不确定性,预测后验越来越依赖于数据:预测标签的不确定性仅在没有样本填充的区域高。毫不奇怪,这种影响对于 MLE 来说是最强的,我们看到了一些过度拟合的证据。

不同先验不确定度σ下的预测后验分布。图片作者。
包扎
在这篇文章中,我们看到了贝叶斯逻辑回归是如何在 Julia 语言中实现的。模型参数的估计后验分布可用于量化系数和模型预测的不确定性。我认为对模型的不确定性保持透明是很重要的,以避免对估计值过于自信。
贝叶斯(概率)机器学习有更多的好处。了解我们的模型在输入域的什么地方表现出高度不确定性,例如,可以有助于标记数据:例如,参见 Gal、Islam 和 Ghahramani (2017)以及对图像数据的主动学习的有趣应用的后续工作。类似地,最近有一项工作在算法追索权的背景下使用了后验预测的估计值(舒特等人,2021)。关于算法追索权的简要介绍,请参见我的上一篇文章。
作为进一步阅读概率机器学习的重要参考,我强烈推荐 Murphy (2022)。这本书的电子版目前可以作为草稿免费获得。最后,如果你很好奇想详细看看完整的源代码,想亲自尝试一下代码,可以看看这个互动笔记本。
参考
克里斯托弗·毕晓普,2006 年。模式识别与机器学习。斯普林格。
加尔,亚林,里亚沙特伊斯兰和邹斌 Ghahramani。2017."图像数据的深度贝叶斯主动学习."在机器学习国际会议,1183–92。PMLR。
凯文·墨菲,2012 年。机器学习:概率视角。麻省理工出版社。
— -.2022.概率机器学习:简介。麻省理工出版社。
舒特,丽莎,奥斯卡·基,罗里·麦克·格拉斯,卢卡·科斯塔贝洛,波格丹一世·萨卡利安努,亚林·加尔,等。"通过隐含最小化认知和随机不确定性产生可解释的反事实解释."在国际人工智能和统计会议上,1756–64。PMLR。
全文发表于 2021 年 11 月 15 日 https://www.paltmeyer.comhttps://www.paltmeyer.com/post/bayesian-logistic-regression/。
通过 PyMC3 在 Python 中进行贝叶斯营销组合建模
原文:https://towardsdatascience.com/bayesian-marketing-mix-modeling-in-python-via-pymc3-7b2071f6001a?source=collection_archive---------0-----------------------
营销分析
一次性估计饱和度、残留和其他参数,包括它们的不确定性

由格雷格·拉科齐在 Unsplash 上拍摄的照片
在这篇文章中,我想结合我在早期文章中讨论的两个概念:贝叶斯建模和营销组合建模。因为你很有可能对这两个主题都不熟悉,所以让我给你一个快速的介绍和进一步的阅读。我会
- 激发什么是营销组合建模,
- 贝叶斯建模是什么,以及
- 为什么将两者结合起来是有意义的。
然后,我将向您展示如何使用 PyMC3 进行实践。
准备工作
如果你是我文章的热心读者(谢谢!),你可以跳过几节直接看代码。否则,请继续阅读。
营销组合建模
每个企业的一个基本问题是决定在哪些渠道上花费营销预算。你可以每天花 1000€在电视广告上,2000€在广播广告上,3000€在网页横幅广告上,跟着感觉走。但这有什么好处吗?
也许网页横幅频道已经在 T21 饱和了,在那里只花 1500€和 3000€一样好。这样你就可以节省 1500€,或者把它们投入到其他更好的销售渠道。
或者也许一些频道甚至有负的投资回报率——你在广告上花的每一欧元,你得到的回报不到一欧元。我们绝对不应该在这样一个频道上浪费太多的钱,至少从商业角度来看它没有战略重要性。
要回答这样的问题,你必须了解不同的媒体支出(电视、广播……)如何影响你的销售或其他感兴趣的 KPI。
在营销组合建模中,你从媒体支出数据集开始。它通常通过一些控制变量进行扩展,即关于任何可能影响目标 KPI 的信息,如假期、天气、足球锦标赛、停工、产品价格等等。不过,为了简洁起见,我们将省略控制变量。然后,当然,你需要一个你想要预测的 KPI。这通常是销售额、新客户数量等等。因此,典型的数据集可能如下所示:

图片由作者提供。
在我以前的文章中,我更详细地描述了动机以及如何进行营销组合建模。为了理解本文的其余部分,请在这里查看它们:
贝叶斯建模
许多估计器和模型源于一种最大似然方法。举个例子,假设你想估计一枚硬币正面朝上的概率 p 。你翻转 10 次,看到 8 个头,你得出什么结论?概率的自然估计是 p = 8 / 10 = 80%,这也是最大似然估计。你也可以计算一个置信区间,看看这个估计是否可靠,但是我们想走另一条路。
想象一下,我们想要加入一些关于概率 p 的先验知识。如果你从钱包里随机抽取了硬币,比如没有理由认为硬币有偏差,那么 p 应该不会离 50%太远,假设你不是魔术师。
使用贝叶斯建模,您可以将这种先验知识结合起来,最终得到对 p 的密度估计,即不是单个值,而是整个分布。这个分布可能在最大似然估计和先验之间的某处有一个峰值,可能是 65%。

红色曲线的模式是最大似然估计。图片由作者提供。
总而言之,贝叶斯建模是关于在先验知识和观察到的数据之间找到一个平衡点。在上图中,这意味着:没有任何数据,我们从蓝色曲线开始。这只是一种信念,一种直觉。然后,我们观察数据,告诉我们将蓝色曲线向红色曲线移动。我们以黄色混合曲线结束,它描绘了所谓的后验分布。
你可以在这里阅读更多关于动机的信息:
现在,理解理论是好的,但我们也必须能够应用它来完成事情。通常,我使用令人敬畏的 python 库 PyMC3 进行贝叶斯建模。你可以在这里看到它的作用:
为什么营销混合建模与贝叶斯?
您可以用许多超参数来定义营销组合模型:
- 饱和度
- 结转强度
- 结转长度
- …
然后,可以使用超参数优化方法来找到最优组合。这就是我在另一篇关于营销组合建模的文章中所做的, 用 Python 升级的营销组合建模。
这种方法很好,但是有一点我不喜欢:
超参数估计通常是不稳定的。
这意味着完全不同的超参数集可能产生同样好的模型。可能会有
- 型号 A 的电视残留强度为 0.4,电视饱和度为 0.8,以及
- 型号 B 电视结转强度 0.9,电视饱和度 0.5,
两者在测试装置上具有相同的 r 或 MAPE。从预测的角度来看,这两种模型是可以互换的,如果你保持在你目前所看到的营销支出范围内。
然而,使用模型 A 进行外推完全不同于使用模型 b 进行外推。这是一种相当不令人满意和麻烦的行为,因为外推是优化媒体预算时要做的事情。如果你过去一直每天花 0€到 1000€在电视广告上,为了优化,你必须知道当你花 5000€甚至 10000€时会发生什么。
你需要一个具有出色推断能力的模型。
通常,你不得不在两个以上的型号中选择。在这种情况下,您至少可以通过两种方式进行操作
- 你可以选择你创建的第一个模型,因为你甚至没有意识到这个问题。这种方法简单但危险。
- 您可以选择一个对您、一些领域专家或利益相关者来说正确的模型。对于一些人来说,这是可以的,但我不喜欢将产出预期放入模型中,因为下面的问题:
如果有人已经知道了答案,我为什么还要建立一个复制这个答案的模型呢?
从这里也可能有一些合理的方法,但是我现在想向你展示如何使用贝叶斯建模来规避这个问题。
建模开始!
首先,让我们获取数据集。
import pandas as pd
data = pd.read_csv(
'https://raw.githubusercontent.com/Garve/datasets/4576d323bf2b66c906d5130d686245ad205505cf/mmm.csv',
parse_dates=['Date'],
index_col='Date'
)
X = data.drop(columns=['Sales'])
y = data['Sales']
然后,我们必须定义饱和度和结转功能,类似于上一篇文章。在 PyMC3 语言中,它可能是这样的:
import theano.tensor as tt
def saturate(x, a):
return 1 - tt.exp(-a*x)
def carryover(x, strength, length=21):
w = tt.as_tensor_variable(
[tt.power(strength, i) for i in range(length)]
)
x_lags = tt.stack(
[tt.concatenate([
tt.zeros(i),
x[:x.shape[0]-i]
]) for i in range(length)]
)
return tt.dot(w, x_lags)
饱和度函数应该很容易掌握。然而,结转有点麻烦。基本上,您可以将遗留转换表示为矩阵向量乘法。你只需要先组装矩阵x_lags和向量w就可以了。作为一个例子,我们可以转换输入向量 x = ( x ₁, x ₂, x ₃, x ₄),结转长度为 3 via

图片由作者提供。
上面代码中的carryover函数就是这样做的。有了这些功能,我们终于可以开始建模了。
import pymc3 as pm
with pm.Model() as mmm:
channel_contributions = []
for channel in X.columns:
coef = pm.Exponential(f'coef_{channel}', lam=0.0001)
sat = pm.Exponential(f'sat_{channel}', lam=1)
car = pm.Beta(f'car_{channel}', alpha=2, beta=2)
channel_data = X[channel].values
channel_contribution = pm.Deterministic(
f'contribution_{channel}',
coef * saturate(
carryover(
channel_data,
car
),
sat
)
)
channel_contributions.append(channel_contribution)
base = pm.Exponential('base', lam=0.0001)
noise = pm.Exponential('noise', lam=0.0001)
sales = pm.Normal(
'sales',
mu=sum(channel_contributions) + base,
sigma=noise,
observed=y
)
trace = pm.sample(return_inferencedata=True, tune=3000)
我们可以看到所有参数(不再有超参数!)用粗体标出。它是回归系数、饱和强度、残留强度、基线和噪音。
请注意,我没有考虑结转长度,而是将其设置为 21。这是因为我还不知道如何在 PyMC3 中用可变维度在
carrover函数中创建矩阵和向量。但通常,我会用泊松随机变量来表示遗留长度。如果你知道如何正确地做这件事,请给我留言!😉也许现在也是给 pyro 一个机会的好时机,PyMC3 这样的另一种概率编程语言。
模型输出的分析
之后,我们可以看看通常的图片。让我们从后验分布开始。执行
import arviz as az
az.plot_posterior(
trace,
var_names=['~contribution'],
filter_vars='like'
)
生产

图片由作者提供。
在这里,你可以看到所有参数的后验概率。它们都有很好的单峰形状。您还可以通过以下方式探索变量对的行为
az.plot_joint(
trace,
var_names=['coef_TV', 'sat_TV'],
)

图片由作者提供。
这里你可以看到饱和强度和回归系数不是独立的,而是负相关的:系数越高,饱和参数越低。这是有意义的,因为较高的系数可以补偿较慢增加的饱和曲线(=较低的sat_TV),反之亦然。
让我们看另一个例子:
az.plot_joint(
trace,
var_names=['car_TV', 'sat_TV'],
)

图片由作者提供。
在这里,我们可以看到为什么超参数优化可能会有问题。这张图片中的每个点都是一个潜在的模型,你可以通过超参数优化找到它。
对于一个真正唯一的最佳模型,我们更愿意看到一个点云紧紧的集中在一个点上(car_TV_true,sat_TV_true)。然而,在这里,我们看到 TV 残留强度可以具有在 0.4 和 0.5 之间的合理值,这取决于饱和度参数。
在我们下结论之前,我们还可以检查一下这个模型是否好。执行
import matplotlib.pyplot as plt
with mmm:
posterior = pm.sample_posterior_predictive(trace)
means = posterior['sales'].mean(0)
stds = posterior['sales'].std(0)
plt.figure(figsize=(20, 8))
plt.plot(y.values, linewidth=2, c='r', label='Observations')
plt.plot(means, linewidth=1, c='b', label='Mean prediction')
plt.fill_between(np.arange(len(y)), means - 2*stds, means + 2*stds, alpha=0.33)
plt.legend()
给了我们

图片由作者提供。
所以看起来这个模型找到了一些有用的东西。在这里,我不会进一步详细讨论如何评估模型的性能,我们可以在将来这样做。
渠道贡献
到目前为止,我们已经处理了分布,但是对于我们最喜欢的渠道贡献图,让我们再次以单个值结束。由于我们在 PyMC3 代码中引入了一些通道贡献变量,现在我们可以使用一个简短的compute_mean函数轻松提取它们。
def compute_mean(trace, channel):
return (trace
.posterior[f'contribution_{channel}']
.values
.reshape(4000, 200)
.mean(0)
)
channels = ['Banners', 'Radio', 'TV']
unadj_contributions = pd.DataFrame(
{'Base': trace.posterior['base'].values.mean()},
index=X.index
)
for channel in channels:
unadj_contributions[channel] = compute_mean(trace, channel)
adj_contributions = (unadj_contributions
.div(unadj_contributions.sum(axis=1), axis=0)
.mul(y, axis=0)
)
ax = (adj_contributions
.plot.area(
figsize=(16, 10),
linewidth=1,
title='Predicted Sales and Breakdown',
ylabel='Sales',
xlabel='Date'
)
)
handles, labels = ax.get_legend_handles_labels()
ax.legend(
handles[::-1], labels[::-1],
title='Channels', loc="center left",
bbox_to_anchor=(1.01, 0.5)
)

图片由作者提供。
看起来不错!
总结与展望
在本文中,我们讨论了使用最大似然法的营销组合建模可能会因为超参数估计而变得困难。可能有许多模型在测试集上表现良好,但具有完全不同的外推行为——这些(超)参数非常不稳定。
然而,适当的外推是优化的关键。因此,我们设计了一个基本的营销组合模型,在贝叶斯设置中具有饱和和结转效应。这被证明是有用的,因为它一次估计所有的参数,给我们更稳定的参数估计。
然后,我们使用 PyMC3 实现了它,并再次创建了一个漂亮的贡献图表,以查看渠道支出对销售额的贡献。
模型扩展
我们现在可以采用我们已经创建的贝叶斯模型,并进一步扩展它。例如,我们可以引入随时间变化的参数。如果两年前电视遗留强度开始为 0.8,但随着时间的推移慢慢下降到 0.5,这可能是有用的,这是概念漂移的一个例子。我们可以使用高斯随机游走,轻松地对此建模,如我关于滚动回归的另一篇文章所示:
同样,我们可以对变化的基线进行建模。到目前为止,我们已经把基线当作一个单一的数字,它在整个训练期间是固定的。但也许随着时间的推移,由于我们的战略广告努力,它也增加了。这是使用我们旧的超参数优化最大似然模型很难解决的问题。
我希望你今天学到了新的、有趣的、有用的东西。感谢阅读!
作为最后一点,如果你
- 想支持我多写点机器学习和
- 无论如何都要计划获得中等订阅量,
为什么不做 通过这个链接 ?这将对我帮助很大!😊
说实话,给你的价格没有变化,但大约一半的订阅费直接归我。
非常感谢,如果你考虑支持我的话!
有问题就在 LinkedIn 上写我!
网球运动员排名的贝叶斯模型
原文:https://towardsdatascience.com/bayesian-modelling-for-tennis-player-ranking-d151aef789a7?source=collection_archive---------27-----------------------
贝叶斯模型如何帮助我们对网球比赛结果建模并创建运动员排名?

图片来自 Pixabay 上的 Bessi
我的前两篇文章是关于马尔可夫链蒙特卡罗和变分推理背后的理论,它为贝叶斯建模奠定了基础。在本文中,我们将使用贝叶斯模型和 MCMC 来预测网球比赛的结果,并在这样做的过程中,创建一个网球运动员的排名。
数据如何?
本项目使用的所有数据均来自此处的。我选择使用 2019 年的数据,因为 2020 年对体育来说是一个怪异的年份(&其他一切!)
2019 年的数据包含 2611 场男子单打比赛,来自所有 ATP(网球职业选手协会)锦标赛。对于这个项目,我们将只使用数据的Winner、Loser和Surface列。
本项目所需的数据处理如下:
- 将玩家姓名映射到玩家 ID
- 将曲面映射到曲面 ID
- 将
Winner和Loser列改为player1和player2 - 随机洗牌,使
player1不总是赢家(我们不希望任何模型知道player1有优势)。 - 创建一个名为
result_category的新列,指示player1是否赢得了游戏。
这给我们留下了一个看起来像这样的数据帧:

经过处理的 ATP 网球数据,图片由作者提供
建模理论
这个问题的建模方法围绕着一个想法,即一个网球运动员有一个潜在的技能分数,决定了他们赢得比赛的能力。如果一个玩家的分数比另一个玩家高,他们应该更有可能赢。此外,一个玩家应该有 3 个不同的奖励,取决于他们玩的表面(草地,粘土或硬)。这应该模拟玩家在不同表面上的真实可变性。
值得注意的是,由于我们将此视为贝叶斯建模问题,一切都变成了概率,所有技能和表面奖励都带有不确定性,这应该模拟不同玩家的真实方差。
实践建模
有很多不同的包可以用来解决这样的问题,包括PyMC3和pyro.,我选择使用PyStan,它是一个包装Stan编程语言的包装器。
我不会深入讨论如何使用 Stan 的细节,因为 Stan 手册比我能做的要好得多,但是我会试着解释一些基本的东西。有 3 个主要模块定义一个模型,data、parameters和model(可选地,你也可以包括generated quantities)。
data定义所有的模型特征和目标(如果有的话)parameters定义所有你想要取样的变量model定义参数先验和模型似然generated quantities在采样后运行,用于执行模型推断
主要关注的是model块,我们在这里定义先验和似然性。
似然性表明给定的网球比赛分布为二元伯努利随机变量,其中参数 p 由运动员能力差异的 sigmoid 确定。

来自标准文档的伯努利逻辑函数。注意 logit^-1 和乙状结肠一样
玩家能力是两件事的函数,基础技能分数player_ability和表面奖励surface_bonus。注意选择不使用超先验参数化player_ability和surface_bonus的平均值。这是因为可能性仅取决于player_ability和surface_bonus中的差异,因此任何关于平均值的先验只会导致约束较差的问题。
请注意,我们确实允许每个表面有单独的标准偏差,即一些表面会导致或多或少的性能差异。最后值得注意的建模细节是两个标准差的先验选择。两者都被选作uniform(0,10),这是一个完全未知的先验,目的是不在模型上强加太多的先验信息。我们同样可以选择像逆伽马先验这样的东西,但是我在采样时似乎收敛得稍微差一些。
结果
因此,如果我们对大约 90%的游戏(随机选择)进行训练,并对最后 10%进行验证,我们在测试集上获得的二进制准确率大约为 70%,在维持集上获得的二进制准确率为 65%。这并不坏,因为我们给模型的唯一信息是谁玩了,结果是什么,他们在什么表面上玩。
但是请记住,贝叶斯模型允许对我们预测的不确定性进行测量。如果我们根据预测样本的标准偏差来设定预测的阈值,我们可以建立这样的曲线…

σ与精度图,图片由作者提供
因此,通过设定大约 0.49 的标准偏差阈值,我们可以将准确率提高到近 90%!
玩家排名
我们的模型要求我们学习每个玩家的分数,以便预测谁将赢得给定的网球比赛。所以我们的模式还免费给了我们一个玩家排名!

模特选手排名,作者图片
如果把排名和 2019 年底开始的 ATP 排名对比一下…

2019 年底 ATP 排名
我们以正确的顺序获得了前 6 名,并且我们正确地找到了 ATP 前 10 名中的 8/10!对于几个小时的造型来说还不错!
我们学到了什么?
在本文中,我们在 Stan 中构建了一个贝叶斯模型来预测网球比赛的结果。我们还研究了如何使用该模型为球员创建一个与 ATP 排名相当一致的球员排名!使用 Stan 既直观又有趣。我很期待看到我们还能用它做些什么!
贝叶斯网络:分析酒店客户数据
原文:https://towardsdatascience.com/bayesian-networks-analysing-hotel-customer-data-cd67dfd6fd43?source=collection_archive---------16-----------------------
用 bnlearn 实现概率建模

来源:图片由 geralt 从 Pixabay 拍摄
在检查不同变量之间的依赖关系时,贝叶斯网络是一个非常直观的工具。
具体来说, DAG (或有向无环图)是允许我们表示给定变量集之间的条件概率。
使用 Python 中的 bnlearn 库,让我们看看这样的分析如何让我们收集关于酒店客户不同属性之间的依赖性的见解。
背景
本分析中使用的酒店预订数据来自 Antonio、Almeida 和 Nunes (2019)。
采用不同酒店客户属性的数据集,如客户是否取消、他们的原籍国、市场细分等,从数据集中随机抽取 1000 个观察值。

来源:Jupyter 笔记本输出,Antonio、Almeida 和 Nunes 的数据集(2019 年)
数据处理和 DAG 生成
我们将首先把数据转换成一个热数据矩阵。该函数通过自动检测相关数据类型并在必要时实现一键编码来工作:
dfhot, dfnum = bn.df2onehot(df)
现在,我们将生成 DAG。
首先,将根节点设置为is cancelled,即客户是否取消了酒店预订。在这种情况下,我们将它设置为根节点——因为我们对研究不同的客户属性如何影响取消行为特别感兴趣。
此外,我们还选择放弃某些变量,如提前期,因为我们主要对分析整个数据集的分类特征感兴趣,并根据每个特征中包含的不同类别分配取消概率。
与数据集中其他要素紧密关联的要素将被丢弃。例如, ReservedRoomType 与 AssignedRoomType 紧密相关,因此决定放弃前者。
DAG = bn.structure_learning.fit(dfnum, methodtype='cl', black_list=['LeadTime', 'Country', 'DistributionChannel','ReservedRoomType'], root_node='IsCanceled', bw_list_method='nodes')G = bn.plot(DAG)
以下是生成的 DAG:

来源:Jupyter 笔记本输出
如上所述,我们现在可以看到变量之间依赖关系的网状图。
例如,取消似乎证明了一个很强的条件概率,其中市场细分和需要停车位。换句话说,某个细分市场的客户比其他人更有可能取消预订,停车位的可用性似乎也对客户是否选择取消预订有很大影响。
反过来, MarketSegment 变量似乎显示出与 AssignedRoomType 和 DepositType 等的显著相关性。例如,某些细分市场可能比其他市场更愿意提前支付押金,或者某些细分市场可能为某个房间类别支付更多费用。
当然,这是表面层次的分析,因为虽然 DAG 的可视化可以向我们显示不同变量之间存在依赖关系,但它们无法解释这些依赖关系的性质或它们存在的原因。
从这个角度来看,在进行进一步分析之前,对不同变量之间的关系有一个总体的了解是非常有用的。
进一步分析
在更详细地生成 DAG 的图之后,我们现在可以更详细地分析参数。
简单看一下另一个例子
让我们考虑一个不同的例子 bnlearn 库提供的洒水喷头例子。

来源:Jupyter 笔记本输出
当分析这里的相关性时,我们可以看到雨和云之间存在关系,无论洒水器是开着还是关着,以及湿草的发生率。
可以在变量之间计算 CPD(或条件概率分布)。
例如,这里是生成的 Rain 变量的 CPD。
[bnlearn] >CPD of Rain:
+---------+--------------------+---------------------+
| Cloudy | Cloudy(0) | Cloudy(1) |
+---------+--------------------+---------------------+
| Rain(0) | 0.6518218623481782 | 0.33695652173913043 |
+---------+--------------------+---------------------+
| Rain(1) | 0.3481781376518219 | 0.6630434782608695 |
+---------+--------------------+---------------------+
如果是阴天,看不到下雨的概率超过 65%。在这种情况下,观测到降雨的概率不到 35%。
另一方面,如果有云,那么观察到下雨的概率超过 66%,观察到不下雨的概率略高于 33%。
回到我们酒店的例子
既然我们已经考虑了一个更简单的例子,那么让我们来看看在酒店数据中生成的一些 CPD。
>>> model = bn.parameter_learning.fit(DAG, dfnum)
看到取消本身的概率刚刚超过 38%。
[bnlearn] >CPD of IsCanceled:
+---------------+-------+
| IsCanceled(0) | 0.611 |
+---------------+-------+
| IsCanceled(1) | 0.389 |
+---------------+-------+
现在,让我们考虑不同变量对取消概率的影响。
所需停车位

来源:Jupyter 笔记本输出
我们可以看到,如果没有所需的停车位可用,那么客户取消的可能性会大大增加。
细分市场

来源:Jupyter 笔记本输出
从该 CPD 中,我们还可以看到某些细分市场显示出比其他市场更高的取消概率。
现在,让我们假设我们希望考虑选择变量组合对取消概率的影响。
我们以餐食变量为例。如果酒店不满足顾客的饮食要求,任何一位顾客取消预订的可能性有多大?
>>> query = bn.inference.fit(model, variables=['IsCanceled'], evidence={'Meal':True})
>>> print(query)
>>> print(query.df)+----+--------------+---------+
| | IsCanceled | p |
+====+==============+=========+
| 0 | 0 | 0.62191 |
+----+--------------+---------+
| 1 | 1 | 0.37809 |
+----+--------------+---------+
那么,如果我们也考虑所需的停车位呢?
>>> query = bn.inference.fit(model, variables=['IsCanceled'], evidence={'RequiredCarParkingSpaces':True, 'Meal':True})
>>> print(query)
>>> print(query.df)+----+--------------+---------+
| | IsCanceled | p |
+====+==============+=========+
| 0 | 0 | 0.66197 |
+----+--------------+---------+
| 1 | 1 | 0.33803 |
+----+--------------+---------+
我们可以看到取消的概率下降到 33%多一点。当去除用餐变量时,概率刚刚超过 34%。从这个角度来看,分析表明,一家酒店如果有足够的停车位供有需求的顾客使用,那么取消预订的可能性就会大大降低。
通过这种方式, bnlearn 库在提供变量之间存在的条件概率的高层次概述以及对那些依赖关系的本质的更详细分析方面非常有用。
结论
在本文中,您已经看到:
- 贝叶斯网络如何运作
- 如何绘制和解释定向丙烯图(DAG)
- 用 bnlearn 计算条件概率
非常感谢您的宝贵时间,非常感谢您的任何问题或反馈。你可以在这里找到原始文章以及该项目的 GitHub 文件夹的链接。
参考
- 安东尼奥、阿尔梅达、努内斯(2019)。酒店预订需求数据集。
- erdogant.github.io: bnlearn 文档。
免责声明:本文是在“原样”的基础上编写的,没有任何担保。它旨在提供数据科学概念的概述,不应被解释为专业建议。本文中的发现和解释是作者的发现和解释,不被本文中提到的任何第三方认可或隶属于任何第三方。作者与本文提及的任何第三方无任何关系。
贝叶斯神经网络
原文:https://towardsdatascience.com/bayesian-neural-network-7041dd09f2cc?source=collection_archive---------13-----------------------

图 1:示意图显示了这项工作中使用的贝叶斯神经网络的架构。该网络有一个包含八个参数的输入层、一个包含十二个节点的隐藏层和一个包含一个节点的输出层。输入层和隐藏层之间的权重由正态分布的 w0_ij 定义。I,j 是节点输入和隐藏层节点索引。类似地,w1_jk 是隐藏层和输出层之间权重的正态分布。在输出节点,网络产生介于 0 和 1 之间的预测分数分布。图摘自我在 arxiv 上发表的一篇文章:https://arxiv.org/abs/1911.09660
在传统的神经网络中,权重被指定为单个值或点估计值,而在 BNN 中,权重被视为概率分布。网络权重的这些概率分布用于估计权重和预测的不确定性。图 1 显示了重量呈正态分布的 BNN 的示意图。使用贝叶斯定理计算权重的后验值,如下所示:

其中 X 是数据,P(X|W)是观察到 X 的可能性,给定权重(W),P(W)是权重的先验信念,分母 P(X)是数据的概率,也称为证据。它需要对所有可能的权重值进行积分,如下所示:

综合证据中所有的不确定权重,很难找到一个封闭形式的解析解。因此,基于模拟或数值的替代方法,如蒙特卡罗马尔可夫链(MCMC),变分推理(VI)被考虑。MCMC 抽样已经成为现代贝叶斯统计中重要的推理方法。科学家们在许多应用中广泛研究和应用。然而,该技术对于大型数据集或复杂模型来说很慢。另一方面,变分推断(VI)比其他方法更快。它还被应用于解决许多大规模计算昂贵的神经科学和计算机视觉问题。
在 VI 中,考虑一个新的分布 Q(W|θ),它近似于真实的后验 P(W|X)。Q(W|θ)通过 W 进行参数化,VI 通过优化找到使两个分布的差异最小化的正确集合:

在上面的等式-3 中,KL 或 kull back–lei bler 散度是真实分布和近似分布之间相似性(相对熵)的非对称和信息论度量。Q(W|θ)和 P(W|X)之间的 KL 散度定义为:

用等式-1 代替 P(W|X ),我们得到:

取 Q(W|θ)的期望值,我们得到:

上面的等式仍然显示了 logP(X)的依赖性,使得很难被 KL 计算。因此,通过添加具有负 KL 散度的 logP(X) 来导出备选目标函数。 logP(X) 是关于 Q(W|θ)的常数。新函数称为下界证据(ELBO ),表示为:

第一项称为似然性,第二项是变分分布和先验权重分布之间的负 KL 散度。因此,ELBO 在可能性和先验之间进行平衡。可以使用不同的优化算法(如梯度下降)来优化 ELBO 目标函数以最小化 KL 散度。
想要在你的领域找到对机器学习和图论感兴趣的人吗?
我将通过分享关于 xoolooloo 的有趣信息来结束这篇文章。它是一个基于位置的搜索引擎,使用相似和多重兴趣来查找当地人。例如,如果你读了这篇文章,你肯定对图论、机器学习感兴趣。因此,你可以在你的地区找到有这些兴趣的人;去看看 www.xoolooloo.com 的
非常感谢您的阅读。我希望你喜欢这篇文章。完整代码和相关数据可在 Github 上找到。文章链接:https://arxiv.org/abs/1911.09660。我很想收到你的来信。你可以联系我:
Email: sabbers@gmail.com
LinkedIn: [https://www.linkedin.com/in/sabber-ahamed/](https://www.linkedin.com/in/sabber-ahamed/)
Github: [https://github.com/msahamed](https://github.com/msahamed)
Medium: [https://medium.com/@sabber/](https://medium.com/@sabber/)
贝叶斯优化:一步一步的方法
原文:https://towardsdatascience.com/bayesian-optimization-a-step-by-step-approach-a1cb678dd2ec?source=collection_archive---------3-----------------------
统计、概率、优化
用统计细节解释贝叶斯优化

M. B. M. 在 Unsplash 上拍摄的照片
在许多现实生活的分析用例中,优化函数是非常重要的。所谓优化,我们的意思是,用某一组参数组合找到目标函数的最大值或最小值。找出最小值或最大值以及参数应该是目标。在本文中,我们将讨论用贝叶斯方法优化一个未知的代价函数的基础。
昂贵的黑盒函数优化——微积分
从基础微积分我们知道,要找到一个函数的最大值或最小值,我们需要求解 x 的导数方程,如下所示:

方程的根将是参数 x 的最优值,这又给出了函数 f(x)的最优值。只要知道函数 f(x)的完整代数形式,就很简单。但是,在许多现实生活场景中,事情并非如此简单。如果它是一个黑盒,那么你将只知道任何 f(x)的输出&输入值,但是你将不知道完整的形式。所以,分析上你找不到导数。除此之外,调用该函数的成本可能非常高。考虑如下两个用例:
1.找出神经网络的最佳超参数组合
考虑一个解决分类问题的大型复杂神经网络。超参数可以是网络中隐藏单元的数量、隐藏层的数量等。这些之间的关系可以被认为是一个假设的函数,该函数将超参数作为输入,并将分类精度作为输出。当然,你不知道这个函数的实际代数形式。找到最佳组合的一种方法是通过反复训练网络来尝试各种随机组合。问题的根源就在于此。我们负担不起重复培训,因为这是一个非常庞大和复杂的网络,培训需要大量的时间和资源。贝叶斯优化可以在这里有所帮助。
2.考古遗址的挖掘——寻找最佳“挖掘点”
不仅对于软件(如神经网络案例),贝叶斯优化也有助于克服物理世界的挑战。在一个考古现场,专家们想到的主要问题是:“在哪里挖掘?”。不用说,从人力、金钱和时间的角度来看,挖掘是一个昂贵的“黑箱”操作。这个函数可以被认为是返回了一个站点中可用资源的列表,参数可以是位置细节,以及其他一些特定领域的东西。找到那个位置是一个挑战,贝叶斯方法可以解决这个问题。
在所有情况下,都需要进行一些函数的初始运行来进行估计。考虑以下功能:
它是“白盒”(因为导数可以通过分析找到),乍看起来成本并不高,但是为了方便起见,假设它是成本很高的&本质上是“黑盒”,需要大量时间来返回输出。让我们进行一些模拟,
x = np.random.randn(5,2)
y = costly_function(x)
pd.DataFrame(data={'y':y, 'x0':x[:,0], 'x1':x[:,1]})
结果呢,

该函数有两个参数 x0 和 x1。对于上面这种代价很高的函数,我们只能调用几次。可能发生的情况是,初始的函数结果&输入可能在一个文件或数据库中给我们。然后,我们必须找出最佳(最小或最大)值和与之相关的参数组合(本例中为 x0 & x1)。我们永远不会知道实际的代数形式,导数的解析形式,因此必须进行数值优化。
在贝叶斯优化中,输入/输出组合的初始集合通常如上所述给出,或者可以从函数中生成。对于上面讨论的两个用例,可以如下实现:
- 神经网络在不同的超参数组合上被训练多次,并且精确度被捕获和存储。该集合可以用作初始数据点。
- 在考古挖掘作业中,可以进行几次初步挖掘来收集有关遗址的信息。它作为初始数据点。
简而言之,这是一个约束优化,它解决了下面给出两个问题:
I)找出以数值方式给出黑盒函数最优值的最优参数,因为无法找到解析导数。
ii)保持整个过程中函数调用的数量尽可能的少,因为这是非常昂贵的。(除了最初的几次运行)
贝叶斯优化术语
贝叶斯方法基于“黑盒”函数的统计建模和参数空间的智能探索。了解几个术语是很重要的。
1.代理模型
它是“黑箱”功能的统计/概率模型。它是后者的代理。为了试验不同的参数,该模型用于模拟函数输出,而不是调用实际的高成本函数。高斯过程回归(它是多变量高斯随机过程)被用作贝叶斯优化中的“代理”。
2.采集功能
它是一个度量函数,决定哪个参数值可以从函数中返回最佳值。它有许多变体。我们将与“预期改进”一起工作。
3.勘探 vs 开采
典型的策略是在参数空间中的局部和全局最优值之间进行补偿。考虑下面给出的图表:
https://www.shutterstock.com/image-vector/local-global-maxima-minima-1961848822
在进行参数空间探索时,可以在函数具有高值或低值的地方找到许多这样的局部最优数据点。但是,这一过程不应就此停止,因为在其他一些领域可能有更多的最佳值。它被称为“探险”。另一方面,也应该重视从函数中持续返回最优(高或低)值的点。就是“剥削”。所以,两者都有一定的意义。这是一个微不足道的决定,“什么时候探索不同位置的更优数据点,或者什么时候利用同一个方向的&”。这是贝叶斯优化在参数空间中击败传统随机搜索或网格搜索方法的领域,因为它采取了中间立场。它有助于通过少量的实际函数调用更快地实现目标。另外两种方法是完全忽略这一事实的盲目搜索。搜索必须非常精确&“切中要害”以降低成本。贝叶斯方法很好地解决了这个问题。
简而言之,采集函数使用“探索对开发”策略,以迭代方式决定最佳参数搜索。在这些迭代中,代理模型有助于获得函数的模拟输出。任何贝叶斯方法都是基于“先验/后验”的概念。前面提到的函数的初始运行被用作起始点或“先验”,并且在每次迭代中,这些“先验”被“后验”数据点丰富。几次迭代后,达到最佳数据点,整个过程在此停止。接下来,我们将看到所有这些技术的实际应用。
逐步实施
我们将使用前面部分声明的带有两个参数的同一个“成本函数”作为要优化的目标函数,即,我们需要在当前情况下最大化它。假设该函数是“黑盒”,很少运行的输出会给我们。我们将定义一个类“BayesianOptimizer ”,并逐步声明它的功能和属性。
让我们首先创建类的结构并声明它的属性。
“gauss_pr”是前面提到的代理模型。“x_init”和“y_init”通常是初始运行集合中函数的参数和输出。您将及时看到其他属性的用法。
现在,我们将在同一个类中创建一个名为“_get_expected_improvement”的函数,这是贝叶斯方法的核心。就是前面说的想要的采集函数。在开始之前,让我们先讨论一些理论。
每当尝试一个新的数据点时,我们都需要计算一个称为“预期改进”或“EI”的指标来给出该数据点的权重。公式由下式给出:

在哪里


这乍一看有点复杂。“mu(f(x))”是根据高斯过程对新数据点 x 的预测(即“y”值)。“max{f(x)}”是根据当前阶段的整个先验列表的预测的最大值(也是从高斯过程获得的)。“sigma(f(x))”通常是新数据点 x 的预测标准偏差。“mu(f(x))”和“max{f(x)}”之间的差异只是为了检查搜索过程的改进。较高的值表示新数据点正在从函数返回一个高值,该值比迄今为止获得的最大值“显著”高。这个“显著性是通过将差值乘以累积概率密度得到的。因此,它给出了一个预期的或整体的"表示改进,当然这是"开发部分。这个值还被一个神奇的因子“sigma(f(x))”放大了。它给出了“EI”度量的不确定性,并且是处理“探索部分的秘密。“mu(f(x))”和“sigma(f(x))”很好地平衡了彼此的影响,因此 EI(x)采取了中间立场。
现在,我们将看到这个函数的实现,
它避免了实际的函数调用,并使用高斯过程作为代理。因此,具有不同点的试验通过代理高斯过程发生,而不是实际函数。这就是“降低成本”的秘诀之一。
这个高斯过程是如何迭代建立的,我们后面会看到。
接下来,这个获取函数用于计算随机选择的数据点的邻域中的“EI”度量,在数值上,它通过数值导数计算而被最大化。不要在这里混淆!!我们刚才又说了函数的“数值导数”。但是,它不是目标成本函数。它是关于最大化采集函数。只要想一想!!我们将只对给出“EI”最大值的数据点感兴趣,即从当前最大值给出目标函数的最大改进(“y”值)。
当然,这将为我们继续搜索参数空间提供正确的方向,避免不必要的盲目探索。这是“降低成本”的第二个秘诀。
接下来我们将看到实现,
尝试了一批(由“batch_size”提到的)随机生成的数据点,并且对于每一个数据点,采集函数被最大化(实际上,负函数被最小化以匹配“scipy”库支持)。将函数的负值最小化等价于将其最大化)。同样,从迭代中取“EI”的最大值,并返回相应的参数 x 值。从一个起点开始数值最大化,再从结果中取最大值,实际上给了参数 x 一个正确的方向,有适量的平均值和不确定性。它是广度搜索(不确定性)和深度搜索(均值)之间的折衷,从两者中获得最佳效果。
现在,下一部分是实际工作。您看到有一个高斯过程回归器作为代理模型。它用于在“先前”数据点的基础上迭代构建模型。“优化”功能可以完成所有这些工作。如下图所示。
上述步骤可以总结如下:
I)从初始“先前”数据点中找出最大值和相应的参数 x
ii)用初始“先前”数据点构建高斯过程。高斯过程使用最大似然估计来寻找参数之间的正确联合分布。
iii)使用采集函数获得下一个最佳参数 x。如前所述,在这个步骤中,在高斯模型的帮助下对不同的数据点进行试错,而不需要调用实际的“昂贵的”目标函数。
iv)使用真实目标函数获得参数值 x 的“y”值。它是“后验”数据点。
v)用“后验”数据更新“先验”,根据“先验”更新当前最大值,然后再次转到步骤 ii)
vi)最后,返回当前最大“y”值和相应的参数 x。
您会注意到,我们还进行了一些距离计算,并捕获了当前的最佳样本(除了当前的最大值 y 和相应的 x 之外,什么也没有)。从函数“_get_next_probable_point”计算两个连续的可能的下一个 x 值之间的距离。它显示了算法的进度。你会在结果中看到这一点。
结果
我们将使用两个二维样本参数作为初始数据点。我们可以使用 n 维,因为“costing _ function”足够通用,可以处理这种情况。
sample_x = np.array([[8,1],[6.2,5.3]])
sample_y = costly_function(sample_x)
现在,是时候使用“BayesianOptimizer”类了,
bopt = BayesianOptimizer(target_func=costly_function, x_init=sample_x, y_init=sample_y, n_iter=200, scale=10, batch_size=30)
bopt.optimize()
它触发邻域大小为 30 的搜索,并进行 200 次迭代。结果如下所示:

因此,对于参数 x0=1.92 和 x1=3.62,代价函数的最大值是 3.7。你可能已经注意到,在代价函数的定义中,我们引入了一个随机噪声,只是为了让它的导数难以计算。
记住,正如前面多次说过的,你永远也不会得到“高成本函数”的主体或定义。这里,为了便于理解,我们只创建了一个虚拟函数。但是,实际上,情况并非如此。样本 x & y 可能作为数据集提供给你,或者会有一些公共/私有托管的“黑盒”API,可以调用它来获得任何 x 的 y 值。
现在,我们将从计算中得到一些其他的结果,
可以画出距离,
pd.DataFrame(bopt.distances_).plot()

注意,两个连续的可能的下一个 x 点之间的距离随着迭代而减小。这是意料之中的。高斯模型在每次迭代后变得更加成熟,其预测变得更加完美,从而产生精确的“EI”值。最终,在每次迭代之后,它更接近最优 x,因此距离开始减小。
现在,我们将看到“y”值在迭代中是如何变化的,
bopt.best_samples_['y'].plot()

注意,y 是逐步达到最大值的。每次迭代都产生对最大值“y”的更好估计。
现在,同样的图计算“EI”
bopt.best_samples_['ei'].plot()

“EI”正在如预期的那样下降。想想吧!!。每一次迭代之后,都会产生一个更好的 y,所以这意味着当我们向最优的方向前进时,获得更大改进的机会就更少了。
有趣的事实
一个大问题“你如何决定 n_iter?”改变它的值肯定会影响我们对最大值的估计。这里需要注意的一点是,
n_iter 等于在除初始化部分之外的整个优化过程中调用实际代价函数的次数
所以,当然它的价值取决于我们准备承担多少成本。
考虑神经网络模型的用例 1。如果有一个云环境,它对深度神经网络的每次“训练”运行向其客户收费,并且存在预算约束,则必须相应地设置“n_iter ”(因为在这种情况下,目标函数是网络的训练&获得准确性)。
贝叶斯方法试图通过减少实际调用来给出函数的估计,因此在某些情况下其准确性可能不如 RandomSearch 或 GridSearch。
当成本比非常小的精确度更重要时,贝叶斯优化是有用的。
源代码可以在这里找到,
https://github.com/avisheknag17/public_ml_models/blob/master/bayesian_optimization/bayesian_optimization.ipynb
贝叶斯优化和超参数调整
原文:https://towardsdatascience.com/bayesian-optimization-and-hyperparameter-tuning-6a22f14cb9fa?source=collection_archive---------10-----------------------

Patrick Federi 在 Unsplash 上的照片
一般的优化问题可以表述为通过遵守某些约束来寻找某个目标函数的极小点的任务。更正式的说法是,我们可以把它写成

我们通常假设我们的函数是可微的,并且根据我们如何计算我们函数的一阶和二阶梯度(Jacobians 和 Hessians ),我们指定不同种类的方法来解决这个问题。因此,在一阶优化问题中,我们可以评估我们的目标函数以及雅可比,而在二阶问题中,我们甚至可以评估 Hessian。在其他情况下,我们对目标函数的形式施加一些其他约束,或者做一些技巧来逼近梯度,比如在拟牛顿优化中逼近 Hessians。然而,这些不包括 f(x)是黑盒的情况。因为我们不能假设我们完全知道这个函数,我们的任务可以重新表述为在发现函数的同时找到这个最佳点。这可以写成同样的形式,只是没有约束

KWIK
为了找到未知的 f 的最优 x ,我们需要明确地推理关于 f 的已知信息。这是受知道它所知道的框架的启发。我将展示一个来自原始论文的例子,它有助于激发对我们功能的这种明确推理的需求。考虑导航下图的任务:

图 1:知道它所知道的(KWIK)示例(摘自原始论文)
图中的每条边都与一个二元成本相关联,我们假设代理事先不知道这些成本,但知道图的拓扑结构。每次代理从一个节点移动到另一个节点时,它都会观察并累积成本。一集是从左边的信源到右边的信宿。因此,学习任务是在几集内找出最佳路径。对于代理来说,最简单的解决方案是假设边的成本是一致的,因此,选择通过中间的最短路径,这样总成本为 13。然后,我们可以使用标准的回归算法来拟合这个数据集的权重向量,并简单地根据到目前为止观察到的节点来估计其他路径的成本,这为我们提供了 12 个顶部路径、13 个中间路径和 14 个底部路径。因此,代理会选择中间路径,即使它与上面的路径相比是次优的。
现在,让我们考虑一个代理,它不仅适合一个权重向量,还可以推理它是否可以利用可用数据获得边的成本。假设代理通过中间路径完成了第一集,累计奖励 13,那么它需要回答的问题就是接下来该走哪条路径。在底部路径中,倒数第二个节点的成本是 2,这可以从已经访问过的节点的成本中计算出来

这比我们开始时一致的假设给了我们更多的确定性。然而,这种依赖性对于上层节点并不真正存在,因为线性组合对已经访问过的节点不起作用。如果我们引入一种方法,让我们的代理说它不确定上层节点的成本的答案,我们可以从本质上激励它在下一轮中探索上层节点,允许我们的代理访问这个节点并发现最优解。这类似于我们如何讨论强化学习中的探索-利用困境。
MDP 和信念
受前一节和土匪的启发,我们可以将我们的求解器建模为代理,将函数建模为环境。我们的代理可以在一系列可能的值和有限的样本预算中采样函数值,它需要找到最优的 x 。从环境中采样后得到的观测值是一个有噪声的估计,可以称之为 y 。因此,我们可以把函数写成这些估计的期望值

我们可以把这看作一个马尔可夫决策过程,其中状态是由代理到目前为止收集的数据定义的。姑且称这个数据为 S 。因此,在每次迭代 t 时,我们的代理处于一种状态,需要决定在哪里采样下一个点。一旦它收集了这个样本,它就把它添加到现有的知识中:

我们可以创建一个策略,代理可以遵循该策略从某个特定的状态执行任何操作:

该代理使用一个对 f 的先验进行操作,并基于该先验通过将其乘以对输出的期望来计算确定性后验:

由于代理事先不知道 f ,所以它需要根据累积的数据计算该函数的后验置信

通过引入这种信念,我们可以在这些后验信念上定义一个 MDP,这意味着该 MDP 中的状态是后验信念【P(f | S)】,并且从一个信念状态到另一个信念状态的转换是随机的。因此,代理需要本质上模拟这个 MDP 中的转换,并且它可以在理论上解决最优问题。然而,困难在于后验信念的计算。
贝叶斯方法
这就是贝叶斯方法发挥作用的地方。他们将这种信念公式化为贝叶斯表示,并在每一步使用高斯过程进行计算。在此之后,他们使用启发式方法来选择下一个决策。用于计算这种信念的高斯过程被称为替代函数,而启发式被称为获取函数。我们可以把这个过程写成如下:
- 使用替代高斯过程计算后验置信值【x】以形成围绕该估计值的平均值和标准偏差的估计值【σ(x)以描述不确定性
- 计算采集函数 α(x) ,该函数与从数值范围中采样下一个点的益处成比例
- 找到这个采集函数的最大点,并在下一个位置采样

这个过程重复固定次数的迭代,也称为优化预算,收敛到一个相当好的点。三种流行的采集功能是:
- 改善概率(MPI) →采集函数值与每个点的改善概率成正比。我们可以把它描述为代理后验概率的上尾 CDF:

- 预期改善(EI) →该值不仅与概率成比例,还与从该点开始的可能改善幅度成比例:

- 置信上限(UCB) →我们通过偏差和可调控制参数来控制探索,并利用后验平均值来获得下一个采样点:

对获取函数的这种最大化的评估是另一个非线性优化问题。然而,优点是这些函数是解析的,因此,我们可以区分它们,并确保至少在局部水平上收敛。为了使这个过程全局收敛,我们需要从该域的多个起点进行优化,并希望在所有这些随机起点之后,该算法找到的最大值确实足够接近全局值。
超参数调谐
全局贝叶斯优化可以显示良好结果的地方之一是神经网络的超参数优化。因此,让我们实现这种方法来调整图像分类器的学习率!我将使用 KMNIST 数据集和一个带有随机梯度下降优化器的小型 ResNet 模型。我们的攻击计划如下:
- 使用数据集和可定制的学习率为我们的神经网络创建一个训练管道。
- 将网络的训练和推理投射到一个目标函数中,这个目标函数可以作为我们的黑箱。
- 将推断映射到可以在优化过程中使用的评估度量。我们本质上需要一个足够好的信号,让我们的求解器可以用来评估采样点。
- 在全局贝叶斯优化过程中使用此函数。
创建培训管道和目标函数
我已经使用 PyTorch 和 lightning 模块创建了一个样板文件,可以用来训练我们的网络。由于 KMNIST 和 ResNet 架构已经在 PyTorch 中可用,所以我们需要做的就是为 MNIST 定制 ResNet 架构,我已经做了如下工作:
一旦完成,我们的下一步是使用训练管道,并将其转换为目标函数。为此,我们需要以某种方式评估我们的模型。我使用了平衡准确性作为评估指标,但也可以使用任何其他指标(如 AUC-ROC 评分)
实施贝叶斯优化
正如前面提到的,我们首先需要一个高斯过程作为代理模型。我们可以从头开始写,或者使用一些开源库来完成。在这里,我使用 sci-kit learn 创建了一个回归变量
一旦高斯过程建立,我们现在需要写采集函数。我使用了预期改进获取功能。核心思想可以按照莫卡斯和莫卡斯的提议重写:

在哪里

乘数φ和ɸ分别是 PDF 和 CDF 函数。这个公式是一个解析表达式,它与我们先前的公式获得了相同的结果,并且我们增加了ε作为探测参数。这可以通过以下方式实现:
代理函数只是使用之前编写的高斯过程进行预测。一旦我们有了预期的改进,我们需要通过最大化这些预期的改进来优化我们的收购
把所有的放在一起
现在我们有了优化例程,我们只需要将它们与我们的目标函数结合成一个循环,我们就完成了。我已经将优化实现为一个类,并将参数传递给这个类。因此,主循环如下所示:
这里,我在主循环中使用了 10 次函数求值的预算,在第一次后验估计之前使用了 2 次函数求值的预算。下面显示了最终结果的示例图

纵轴是平衡精度,横轴是学习率。可以看出,这是主循环的第三次迭代,采样 2 个点作为初始估计,并且获取函数在不确定性和平均值平衡的区域是最高的。
这是我在 TDS 发表的第一篇文章,所以我希望你会喜欢。我应该声明的一点是,上述采集函数的优化并没有真正使用我之前提到的多起点方法。但是,我计划在将来将这一点添加到代码中。代码在我的 Github 库里。我在我的网站上不断总结我学到的东西,欢迎随时查看。
超参数调整方法-网格,随机或贝叶斯搜索?
原文:https://towardsdatascience.com/bayesian-optimization-for-hyperparameter-tuning-how-and-why-655b0ee0b399?source=collection_archive---------10-----------------------

局部最小值和最大值的示例(图片由作者提供— Mayrhofen 2019)
使用三种方法的超参数优化实用指南:网格、随机和贝叶斯搜索
当我在做我的上一个项目时,在我训练了模型的第一个版本之后,我得到了一个新的数据块。那天,我觉得有点懒,并尝试使用相同的模型类型和超参数,用新数据重新训练我的模型。可惜没有按照我的预期进行。由于数据量的增加,它的性能没有得到改善,反而略有下降。添加的数据与我之前的数据分布不同,与原始数据相比,它的数量不可忽略,这与我的预期相反。
因此,我发现自己处于一个未知的领域,不知道应该使用哪个超参数。我手动尝试了一些选项,但有太多可能的组合,我在管理我的实验时遇到了麻烦。那时,我决定更深入地研究超参数调优领域。
你对这篇文章有什么期待?
- 超参数调谐简介。
- 解释超参数搜索方法。
- 每种方法的代码示例。
- 比较和结论。
对于帖子中的所有例子,我使用了 Kaggles 的心脏病发作分析预测数据集。
我准备了一个简单的管道,用于所有的例子。
什么是超参数调整,为什么它很重要?
超参数是控制算法整体行为的算法变量。它影响其速度、分辨率、结构,并最终影响性能。有时它只有很小的影响,但在其他情况下,它是至关重要的。一个很好的例子是学习率。当它太大时,学习不够敏感,模型结果不稳定。但是当它太小时,模型学习起来就有困难,可能会卡住。
当算法有许多参数时,很难尝试所有可能的组合来找到最佳集合。因此,我们希望以一种可管理的方式高效地进行超参数调整。
超参数搜索的类型
执行超参数搜索有三种主要方法:
- 网格搜索
- 随机搜索
- 贝叶斯搜索
网格搜索
执行超参数调整的基本方法是尝试所有可能的参数组合。例如,如果您想要调整 learning_rate 和 max_depth ,您需要指定您认为与搜索相关的所有值。然后,当我们运行超参数优化时,我们尝试两个列表中的所有组合。
在下面的例子中,我试图找到 learning_rate (5 个值)、 max_depth (5 个值)和 n_estimators (5 个值)的最佳值——总共 125 次迭代。
随机搜索
与网格搜索不同,在随机搜索中,只尝试了部分参数值。参数值从给定的列表或列表指定的分布中采样。被采样的参数设置的数量由 n_iter 给出。当参数以列表形式呈现时,执行无替换采样(如网格搜索)。但是如果参数以分布形式给出,则使用带有替换的采样(推荐)。
根据我的经验,随机搜索的优点是你可以在不增加迭代次数(耗时)的情况下扩展你的搜索范围。此外,您可以使用它来找到狭窄的限制,以便在更小的区域内继续进行彻底的搜索。
在下面的例子中,我使用参数分布进行替换采样。
贝叶斯搜索
贝叶斯搜索与其他方法的主要区别在于,调整算法根据前一轮得分在每一轮中优化其参数选择。因此,该算法不是随机选择下一组参数,而是优化选择,并且可能比前两种方法更快地达到最佳参数组。也就是说,这种方法只选择相关的搜索空间,并放弃最有可能不提供最佳解决方案的范围。因此,当您拥有大量数据,学习速度较慢,并且您希望最大限度地减少调整时间时,这是非常有益的。
与随机搜索示例相同,我在这个示例中使用了用于采样的参数分布:
参数搜索的可视化——学习率

这个比较中的最佳学习率参数是 0.008(通过贝叶斯搜索找到)。
每次迭代平均分数的可视化

我们可以看到贝叶斯搜索比其他方法略胜一筹。这种影响在更大的数据集和更复杂的模型中更加明显。
讨论和结论
我在相同的参数范围内运行了三种搜索方法。网格搜索运行 125 次迭代,随机和贝叶斯运行 70 次迭代。这个数据集相对简单,所以分数的变化并不明显。尽管如此,随机搜索和贝叶斯搜索比网格搜索表现更好,迭代次数更少。贝叶斯搜索找到了实现最佳得分的超参数。
关于该主题的进一步阅读,我推荐阅读以下精彩帖子:https://towardsdatascience . com/a-conceptual-explain-of-Bayesian-model-based-hyperparameter-optimization-for-machine-learning-b 8172278050 f。
祝你好运!
贝叶斯优化的超参数调整或者我如何用木头雕刻船
原文:https://towardsdatascience.com/bayesian-optimization-or-how-i-carved-boats-from-wood-examples-and-code-78b9c79b31e5?source=collection_archive---------36-----------------------
示例和代码

作者图片
小时候,我和祖母在一个小村庄里度过夏天,周围没有同龄人,也没有什么娱乐活动。虽然阅读占据了我大部分的时间,我也曾经用木头雕刻小船。我的船有三个我特别注意的特点——船的宽度、龙骨的长度和桅杆的长度。
一般来说,更宽的船更稳定,但速度较慢,也不好看。桅杆较长的船需要平衡,因此龙骨较长,速度较慢。我测试了随机配置的船只,没有遵循系统的方法。
设计船很有趣,那时我有足够的时间。另一方面,为大多数机器学习模型寻找最佳超参数通常是不可避免的。在时间紧迫的情况下,这可能是一项压力很大且非常昂贵的任务。虽然超参数网格搜索对于单个参数来说可能足够了,但是对于更多的参数来说,可能的测试选项的数量呈指数增长!
好在有帮助——贝叶斯优化!
这篇文章是对必要组件的一个非常简短的概述,旨在以一个 jupyter 笔记本的形式提供可伸缩的代码。看看吧!
理论
在解释这个问题时,我发现牢记最终目标是有用的。本文的目标是找到深度神经网络的超参数,以最大限度地提高验证精度。为此,我们将使用贝叶斯优化。我们可以将这个过程分成几个步骤:
- 用超参数值初始化网络;
- 训练模型并在验证集上保存最佳精度;
- 对目前收集的性能数据拟合一个高斯过程 (GP)。这里,到目前为止测试的超参数值是独立变量,并且具有这些超参数值的模型的精度是预测变量;
- 使用 GP fit 上的采集功能获得下一组超参数值,通过这些值,模型有望获得更好的性能;
- 转到步骤 1。
因此,该过程需要两个重要步骤
- 损失函数估计——将通过高斯过程实现;
- 获取函数——损失的最高预期改善。
高斯过程
与线性模型不同,我们选择一个具有有限参数的函数,高斯过程(GPs)是非线性模型,不会将我们局限于一个函数。GPs 允许用一系列函数对数据建模。
使用 GPs 时,我们假设每个数据点都是正态分布的随机变量,并且每个数据点都相互关联。也就是说,整个数据集可以用具有非平凡协方差的多变量正态分布来描述。
GPs 完全由均值 m 和克内尔 K 函数描述。mean 函数非常简单,它接受数据点特征并返回该数据点的预测变量的平均值。核函数将两个数据点作为输入,并返回它们之间的协方差。内核描述了数据点之间的关系,因此是对结果拟合方式的隐含约束。
让我们从一个由五个数据点组成的简单例子开始。在我们的例子中,假设 y 轴是我们想要最大化的机器学习算法的损失函数,x 轴是影响预测精度的超参数,例如预烧时间。

作者图片
对于我们的高斯过程,我们假设损耗相对于预烧期是平滑的,我们不希望损耗在预烧期发生微小变化后突然改变。因此,我们选择一个非常标准的平方指数核来加强这种平滑先验。

平方指数核
直观上,如果点 x 和 x’靠得很近,协方差将会很大,即,与相距较远的点相比,它们对彼此的位置具有更大的影响(这里 l 和σ是核的超参数)。核函数通常以矩阵形式书写,即通过 GPs 建模的多元高斯分布的协方差矩阵。因此,我们可以享受这个矩阵的一些性质——正定性和对称性。
核的选择是一门艺术,有很多关于如何自动完成这项工作、如何将核组合在一起以及如何为多维数据选择核的研究,因为为一个维度做出的假设可能不适用于另一个维度。更多内核可视化可以在这里找到。一个完整的研究分支正在研究模型训练时的学习内核。
让我们回到这个问题上来。我们用 GP 建模我们的数据:

作者图片
注意,即使在我们有数据测量(损失)的位置,标准偏差也是非零的。这是因为除了平方指数内核之外,我们还使用了白化内核——添加到每个点的小常数方差,允许预测值中的一些不确定性。当我们寻找函数的最大值时,这将是有用的。
关于高斯过程的更多细节,请查看尼尔·劳伦斯的博客和这篇精彩的博文。
贝叶斯优化— 采集 函数
该步骤中的任务是找到超参数的值,该值将改善我们找到的拟合损失函数的当前最大值(最小值)。为了确定每个点的潜力(例如,相对于预期的改进或改进的概率)是最大值(最小值),我们使用一个获取函数。采集函数接收获得的 GP 拟合(每个点的平均值和方差),并为机器学习算法的下一次运行返回超参数值。下面我们考虑两个简单的获取函数:改进概率和预期改进。
改进概率:通过均值和方差估计,我们寻找最有可能成为下一个峰值的点。

改进概率标准
这里ф是标准累积正态分布,μt(x)是点 x 处的预测平均值,f(x+)是数据点中的当前最大值,ε是避免分子中为零的小误差项,sigma 是点 x 处的标准偏差,用于标准化分布。均值越大,概率越高。另一方面,较小的标准差会导致较高的概率值,因为我们在预测中更有把握。因此,改进的可能性阻碍了对空间的探索。
预期改进:另一种常见的方法是使用预期改进。该方法允许具有较高估计方差的点有更大的机会被选择。在这种情况下,要选择的下一个点将最大化预期的改善,x_(t+1)=argmax_x(EI),其中:

预期的改进
有关推导的更多细节,请参考本文的部分。在下面的例子中,我将使用预期改进,因为它已被证明可以产生更好的样本。下面给出了上述功能的预期改进。

作者图片
EI 标准在大约 11800 和 12900 处有两个明显的峰值,在[8000,10500]和[14200,16000]处有平坦的尾部。我们可以重新查看上图中的 GP 拟合,并注意到峰值对应于均值和标准差之和最大的拟合值。
基于汤姆森采样的其他策略可以在教程 1 和教程 2 中找到。更多的例子可以参考这篇的文章。
让我们运行一些代码!
本文基于一个 jupyter 笔记本。我把这个例子设计成可扩展的——添加更多的变量来优化只需要设置这些变量的名称、它们的范围和采样位置的数量。因此,下面的两个例子需要最少的代码更改。
在这两个例子中,我都使用预期改善作为获取函数。试着自己运行代码,用改进的概率来代替。
1D 的例子
假设我们正在训练一个变压器网络,为此我们需要找到老化超参数的最佳值。

作者图片
所选点随着时间的推移逐渐攀升至函数的最大值。随着在最大值周围采样的点越来越多,该点周围的方差越来越小。同时,即使未探索区域的预测平均值小于最大值,高方差也允许探索未探索的空间。
2D 的例子
1D 的情况不太实际,因为通常有更多的超参数需要优化。在这个例子中,我们考虑具有两个超参数的 2D 情况:预烧期和学习率。在 3D 中可视化采样点可能很困难。下面我也展示了数据的等高线图——从顶部看。

作者图片
这两个例子最终都融合了。运行更多的迭代会产生更精确的估计。典型的停止标准是每个新步骤的增加。
实用性
直接在原始参数值以及我们正在建模的损失函数的原始范围上运行贝叶斯优化可能具有不利影响,因为核函数没有考虑变化的范围。为了将这一方面纳入优化,我将数据重新调整到 0–1 的范围。
由于最终准确度的值受到许多条件的影响,例如机器学习算法的初始化,因此在对其建模时,我们允许在具有白噪声核的预测中存在一些噪声。
进一步阅读
贝叶斯优化非常昂贵,应考虑实际因素。关于如何在实践中运行它的更多细节,请查看这篇论文。
对于那些对集成解决方案更感兴趣的人,请查看权重和偏差,它为跟踪模型的超参数和度量提供了现成的套件,以及他们对贝叶斯优化的实现
Distill 有一篇很棒的关于贝叶斯优化的文章,一定要看看牛津大学的这篇评论文章!
别忘了这篇文章是基于一本 jupyter 笔记本。看看吧!
非常感谢 Param 韩吉对内容提出的宝贵建议!
喜欢作者?保持联系!
我错过了什么吗?不要犹豫,直接在 LinkedIn 或 Twitter 上给我留言、评论或发消息吧!
用 Python 实现贝叶斯优化
原文:https://towardsdatascience.com/bayesian-optimization-with-python-85c66df711ec?source=collection_archive---------1-----------------------
优化评估成本高昂的黑盒函数
如果你在数据科学或机器学习领域,很可能你已经在做优化!例如,训练一个神经网络是一个优化问题,因为我们希望找到一组模型权重,使损失函数最小化。找到产生最佳性能模型的超参数组是另一个优化问题。
优化算法有多种形式,每一种都是为了解决特定类型的问题而创建的。特别是,学术界和工业界的科学家共同面临的一类问题是评估昂贵的黑盒函数的优化。在今天的帖子中,我们将探讨如何用 Python 优化评估代价高昂的黑盒函数!

最优化问题是科学和工程中经常遇到的问题。Shane Rounce 在 Unsplash 上拍摄的照片。
评估黑盒功能的成本很高
“评估昂贵的黑盒”意味着所涉及的功能或操作需要花费大量的金钱或资源来执行,并且其内部工作方式无法理解。一个评估代价昂贵的黑盒函数的好例子是优化深度神经网络的超参数。每个训练迭代可能需要几天的时间来完成,我们不能预先分析超参数值,这将导致最佳性能的模型。
当然,我们对每一个可能的超参数值进行交叉验证网格搜索,但是重复这么多训练迭代会导致计算成本激增!需要一种更有效的方法来使用最少的迭代次数找到最佳的超参数集。好在那种方法已经存在:贝叶斯优化!
贝叶斯优化算法
贝叶斯优化是一种基于机器学习的优化算法,用于寻找参数,以全局优化给定的黑盒函数。该算法包含两个重要部分:
- 要优化的黑盒函数: f ( x )。我们要找到全局优化 f ( x )的 x 的值。根据问题的不同, f ( x )有时也被称为目标函数、目标函数或损失函数。一般来说,我们只知道 f ( x )的输入和输出。
- 采集函数: a ( x ,用于生成 x 的新值,以供 f ( x )评估。 a ( x )内部依靠一个高斯过程模型 m ( X , y )生成新的 x 值。
优化过程本身如下:
- 定义黑盒函数 f ( x )、采集函数 a ( x )以及参数 x 的搜索空间。
- 随机产生 x 的一些初始值,从 f ( x )测量相应的输出。
- 将一个高斯过程模型 m ( X , y )装配到 X = x 和y=f(X)上。换句话说, m ( X , y )作为 f ( x )的代理模型!
- 采集函数 a ( x )然后使用 m ( X , y )生成新的 x 值,如下所示。用 m ( X , y )预测f(X)如何随 x 变化。导致 m ( X , y )中预测值最大的 x 的值,则建议作为 x 的下一个样本,用 f ( x )进行评估。
- 重复步骤 3 和 4 中的优化过程,直到我们最终得到一个导致全局最优值 f ( x )的值 x 。请注意, x 和 f ( x )的所有历史值都应该用于在下一次迭代中训练高斯过程模型 m ( X ,y)——随着数据点数量的增加, m ( X , y )在预测最优值方面变得更好
用bayes_opt库进行贝叶斯优化
作为演示的一部分,我们使用[bayes_opt](https://github.com/fmfn/BayesianOptimization)库来执行对基于sklearn乳腺癌数据训练的SVC模型的超参数C的搜索。
优化器的组件包括:
- 黑盒函数 f ( x )是我们希望最大化的 ROC AUC 分数,以便获得最佳表现模型。
- 所使用的采集函数 a ( x )是置信上限(
"ucb")函数,其形式为:a = mean + kappa * std。mean和std都是高斯过程模型 m ( X , y )的输出。kappa是优化器的一个超级参数,用于平衡对 x 搜索的探索和利用。对于kappa的小值,std没有mean和那么强调,a* ( x )侧重于在发现的局部极小值周围搜索。对于kappa的大值,std更为重要, a ( x )侧重于在 x 的未搜索区域进行搜索。*
执行上述优化步骤的“现成”Python 代码如下。
*import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from bayes_opt import BayesianOptimization, UtilityFunction
import warnings
warnings.filterwarnings("ignore") # Prepare the data.
cancer = load_breast_cancer()
X = cancer["data"]
y = cancer["target"]X_train, X_test, y_train, y_test = train_test_split(X, y,
stratify = y,
random_state = 42)scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)# Define the black box function to optimize.
def black_box_function(C):
# C: SVC hyper parameter to optimize for.
model = SVC(C = C)
model.fit(X_train_scaled, y_train)
y_score = model.decision_function(X_test_scaled)
f = roc_auc_score(y_test, y_score)
return f# Set range of C to optimize for.
# bayes_opt requires this to be a dictionary.
pbounds = {"C": [0.1, 10]}# Create a BayesianOptimization optimizer,
# and optimize the given black_box_function.
optimizer = BayesianOptimization(f = black_box_function,
pbounds = pbounds, verbose = 2,
random_state = 4)optimizer.maximize(init_points = 5, n_iter = 10)print("Best result: {}; f(x) = {}.".format(optimizer.max["params"], optimizer.max["target"]))*
运行上面的 Python 代码会打印出以下输出:
*| iter | target | C | -------------------------------------
| 1 | 0.9979 | 9.674 |
| 2 | 0.9975 | 5.518 |
| 3 | 0.9979 | 9.73 |
| 4 | 0.9979 | 7.177 |
| 5 | 0.9979 | 7.008 |
| 6 | 0.9914 | 0.1023 |
| 7 | 0.9981 | 8.505 |
| 8 | 0.9981 | 8.15 |
| 9 | 0.9981 | 8.327 |
| 10 | 0.9981 | 8.8 |
| 11 | 0.9981 | 8.67 |
| 12 | 0.9981 | 7.974 |
| 13 | 0.9979 | 6.273 |
| 14 | 0.9981 | 8.064 |
| 15 | 0.9981 | 8.911 | ===================================== Best result: {'C': 8.505474666113539}; f(x) = 0.9981132075471698.*
从上面的结果来看,优化器设法确定使用超级参数值C = 8.505会产生性能最佳的模型!
对优化过程的更多控制
您可能已经意识到优化器将搜索参数作为连续变量输出。如果参数必须是离散的,这将导致一个问题。作为一个例子,让我们假设我们也想搜索模型SVC的最佳degree值,然而degree必须是一个整数。在这种情况下,我们需要对优化过程进行更多的控制。
此外,我们没有指定上面采集函数 a ( x )的超参数kappa,也没有指定使用哪种类型的采集函数。一般来说,缺省设置在大多数情况下应该是有效的,但是在某些情况下,对优化器有更多的控制会更好。
幸运的是,bayes_opt并没有使用上面显示的简单工作流程,而是提供了一个更加可控的优化过程。在这种情况下,我们必须在一个for循环中手动执行每个优化步骤。在这个for循环中,如果需要,我们可以添加额外的代码来执行其他计算,比如强制搜索参数是离散的。
*# Create the optimizer. The black box function to optimize is not
# specified here, as we will call that function directly later on.
optimizer = BayesianOptimization(f = None,
pbounds = {"C": [0.01, 10],
"degree": [1, 5]},
verbose = 2, random_state = 1234)# Specify the acquisition function (bayes_opt uses the term
# utility function) to be the upper confidence bounds "ucb".
# We set kappa = 1.96 to balance exploration vs exploitation.
# xi = 0.01 is another hyper parameter which is required in the
# arguments, but is not used by "ucb". Other acquisition functions
# such as the expected improvement "ei" will be affected by xi.
utility = UtilityFunction(kind = "ucb", kappa = 1.96, xi = 0.01)# We want to optimize both C and degree simultaneously.
def black_box_function(C, degree):
model = SVC(C = C, degree = degree)
model.fit(X_train_scaled, y_train)
y_score = model.decision_function(X_test_scaled)
f = roc_auc_score(y_test, y_score)
return f# Optimization for loop.
for i in range(25):
# Get optimizer to suggest new parameter values to try using the
# specified acquisition function.
next_point = optimizer.suggest(utility) # Force degree from float to int.
next_point["degree"] = int(next_point["degree"]) # Evaluate the output of the black_box_function using
# the new parameter values.
target = black_box_function(**next_point) try:
# Update the optimizer with the evaluation results.
# This should be in try-except to catch any errors!
optimizer.register(params = next_point, target = target)
except:
passprint("Best result: {}; f(x) = {:.3f}.".format(optimizer.max["params"], optimizer.max["target"]))plt.figure(figsize = (15, 5))
plt.plot(range(1, 1 + len(optimizer.space.target)), optimizer.space.target, "-o")
plt.grid(True)
plt.xlabel("Iteration", fontsize = 14)
plt.ylabel("Black box function f(x)", fontsize = 14)
plt.xticks(fontsize = 14)
plt.yticks(fontsize = 14)
plt.show()*
此代码导致输出:
Best result: {‘C’: 9.984215837074222, ‘degree’: 4.0}; f(x) = 0.998.

超过 25 次迭代的 SVC 模型的 C 和度的贝叶斯优化。
根据上面的结果,优化器设法确定使用超级参数值C = 9.984和degree = 4会产生性能最佳的SVC模型!
摘要
今天,我们探讨了贝叶斯优化的工作原理,并使用贝叶斯优化器来优化机器学习模型的超参数。对于小数据集或简单模型,与执行网格搜索相比,超参数搜索的速度可能并不显著。然而,对于非常大的数据集或深度神经网络,测试网格中的每个样本在经济上可能变得不可行,使用贝叶斯优化将提高超参数搜索过程的效率!
在以后的帖子中,我将演示如何使用贝叶斯优化来优化激光器的功率输出!在此之前,感谢您的阅读!
参考
[1] C. M. Bishop (2006),https://www.microsoft.com/en-us/research/uploads/prod/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf【斯普林格】。【https://github.com/fmfn/BayesianOptimization】 https://github.com/fmfn/BayesianOptimization 。
【3】https://scikit-optimize.github.io/stable/。**
偏差修正似然的贝叶斯参数估计
原文:https://towardsdatascience.com/bayesian-parameter-estimation-with-bias-corrected-likelihood-c0a86f91f90e?source=collection_archive---------24-----------------------

照片由西格蒙德在 Unsplash 上拍摄
O 统计估计量的一个特征是它们可能是有偏的:即使估计量是(弱)一致的,也就是说,随着样本量的增加,估计量的值(在概率上)收敛于潜在参数的真实值,估计量的期望值可能不同于真实值。
下面的例子给出了一个有偏估计量。假设我们参加一次抽奖,从一个瓮中抽取不同颜色的球,一次抽取一个球。我们假设球的总数要么非常大,要么每次试验后球都被放回瓮中。我们不知道不同颜色的数量,但我们碰巧知道抽奖是公平的,因为每次尝试抽取特定颜色的概率是固定的,并且与颜色无关。换句话说,颜色均匀地分布在球中。通过观察有限的试验序列(即,不是所有的,而只是骨灰盒中包含的球的样本),我们可以尝试并估计不同颜色的总数,从而通过正确猜测下一次试验中抽取的颜色来估计我们赢得彩票的机会。首先,我们可以记下观察到的颜色并连续编号,例如:

如果我们观察上面的顺序,我们可以很容易地推断出:至少有种K =4种颜色可供选择。一般来说,在给定未知参数 K colors 的情况下,观察长度为n 的独立试验序列、k₂……的可能性计算为:**

K 的最大似然估计器(MLE)** 最大化该似然:**

所以在这个意义上,颜色总数的平凡下界 K = 4 也是颜色总数的最佳可能估计量。
经过多次试验后,几乎肯定会观察到所有可能的颜色,因此 MLE 在概率上收敛于真实的参数值:它是一致的估计量。但是我们也知道,估计量会系统地低估小样本的真实值,因为很明显,它的值永远不会大于试验次数。我们希望明确地计算这种偏差。设 K₀ 为未知参数的真值。在 N 独立试验中找到颜色号 k 的概率由下式给出:

因此,MLE 的偏差计算为:

我们不能把这种偏差加到我们的估计中,因为它取决于我们希望估计的未知参数值。
F 或大样本量 N ,上述偏差趋近于零。然而,我们也看到,对于大参数值 K₀ ,不仅小样本量的偏差大,而且即使对于大样本,偏差也非常缓慢地接近零。也许我们运气好,对 K₀ 的大小有一些先验知识;也许我们对彩票中奖的可能性有一些先入为主的想法。纳入此类先入之见的标准方法是采用贝叶斯范式,并通过先验概率“修正”可能性:

超参数 λ 被选择为最符合我们对【K】的先入之见,并且后验分布在观察证据后对我们关于参数的知识进行建模。隐含着从频率主义者到贝叶斯观点的范式转变:我们已经从把K 想象成一个具有未知但确定值的参数,转移到把 K 想象成一个随机变量。随机是因为我们缺乏关于它的“真实价值”的知识——贝叶斯应该用引号括起来,因为这是一个他们已经放弃了本体论承诺的实体。然而,在这篇文章中,我们不会采取一个明显的频率主义者或贝叶斯立场,而是提出一个实际的组合。**
尽管如此,点估计仍然是有意义的,因为我们有最高的可信度,最大后验估计量(MAP)😗***

形式上,MAP 估计量与无信息(即,均匀/恒定先验)的 MLE 一致。没有商定的“正确”方法来选择信息先验的形状,因此我们将继续假设它是泊松分布:

现在,我们可以希望通过先验知识的贡献来纠正偏差。下图显示了从带有= 25***种不同颜色的骨灰盒中进行抽奖的模拟:*****

圆点代表作为样本大小函数的最大似然估计,它总是低估真实值,并且这种偏差对于小样本特别大。虚线表示具有泊松先验和 λ = 35 的 MAP 估计。即使先验表现出相当大的初始高估,在仅仅几次试验之后,最大似然和后验分布实际上是一致的。另一方面,实线显示出对这种效应更强的鲁棒性。它表示具有偏差校正似然的 MAP 估计量,如下所述。
因此,如果对似然性的估计存在较大偏差,我们不能指望先验信息在没有一些额外修正的情况下得到有效补偿。如前所述,校正偏差并不简单,因为它取决于未知参数。然而,我们可以从先验分布中计算参数值估计,然后该先验分布可以代替真实的参数值并通知偏差的估计:

这允许我们用先验偏差校正似然性写下后验分布如下:

只要我们知道似然估计的偏差是真实参数值(和样本大小)的函数,就可以使用这个公式。如果在分析上不知道,可以想象这种函数可以通过蒙特卡罗模拟产生。
如下图所示,当先前估计本身存在负偏差( λ = 18 )时,偏差校正图也显示出改进的鲁棒性:

结论
对于这个玩具示例,我们已经表明,通过使用先验信息来校正贝叶斯参数估计中的似然偏差可能意味着对小样本量的估计的准确性和稳健性的改进。这种技术可以很容易地推广到这个玩具示例之外,并可能在现实世界的应用程序中有用。
参考
维基百科上的最大似然估计
维基百科上的最大后验估计
维基百科上一致的估计量
基于 PyMC3 的贝叶斯价格优化
原文:https://towardsdatascience.com/bayesian-price-optimization-with-pymc3-d1264beb38ee?source=collection_archive---------13-----------------------
PyMC3,黑仔可视化和概率决策

信用:Pexels.com
在本文中,我们将从贝叶斯的角度探讨价格优化。那么什么是价格优化?
它是在给定成本和收入的情况下优化商品或服务的价格。收入通常受制于“需求曲线”,这是价格和消费者需求单位之间的简单关系。过低的价格会吸引市场上的任何人,但不会带来足够的收入来抵消成本。但反过来也是如此。如果价格太高,那么很少顾客(如果有的话)会被吸引;因此,成本仍然可能超过收入。因此,优化的任务。
正如我们将看到的,成本可能是需求单位的任何函数。这可能是购买、储存、运输或任何基本上与所需单位相关的任何成本。在这种情况下,为了便于说明,我们将做一个简单的假设,但是可以更改函数以满足任何需要考虑的任意成本。
那么为什么是贝氏?
Frequentist 方法使用置信区间。这意味着我们有 X%的把握,某个参数的真实值落在给定的区间内。但是在这段时间内,我们的信心如何呢?频繁主义者的方法在这里帮不了我们太多。更糟糕的是,参数通常是相互关联的。
另一方面,贝叶斯方法模拟所有参数的联合分布。当然,我们可以做出 X%的可信区间——但是我们的分析给出了参数联合分布的形状。当我们想模拟收入、成本和利润对价格变化的反应时,置信区间对我们的目的来说不够透明。
数据模拟
假设我们在一个炎热的夏天在一个柠檬水摊位上工作,卖几夸脱的柠檬水。我们有一个冷藏箱,我们以 50 美元的固定费用租用,每夸脱柠檬水需要 1.5 美元的冰——我知道这很荒谬。但这是一个成本约束,我们将在后面出于说明目的实现它,以便您可以将其替换为您自己的成本函数。
首先,我们需要一条需求曲线;为了简单起见,我们将模拟我们自己的。需求曲线建模有多种方法。一个很有效的方法包含了指数衰减。当价格接近零时,预测的需求将无限高,而如果价格任意(无限)高,需求将渐近接近零。
我们是怎么得到这条曲线的?嗯,我刚刚说漏嘴了,是模拟的!但是让我们假设你提供了不同价格的几夸脱柠檬水,你观察到了下面的模式。实际上,使用折扣本身就是一门科学。你可以清楚地了解需求曲线,并评估营销渠道的功效。我们不会在这里进入折扣和定价实验,因此模拟。

鸣谢:作者图片
贝叶斯线性模型
我们本质上只是揭示了我们设定的参数。价格和需求的对数单位之间存在线性关系(因为需求呈现指数衰减。)
为什么是贝叶斯模型?我们可以推断它们的联合分布,而不是推断单个参数、截距和斜率的置信区间。这太棒了!它允许我们推断收入、成本和利润的分布。
频率主义者的方法是使用单一的斜率和截距,得出收入、成本或利润的点估计值。这将使我们无法清楚地表达我们对最优决策的确定性。
正如您所看到的,PyMC3 语法非常用户友好,易于理解。如果你已经熟悉贝叶斯分析,你会注意到我对 m、b 和 s 的先验知识,我们的斜率、截距和噪声项。这些有效地规范了搜索空间。斜率和截距可能是正的也可能是负的,所以我用了正常的先验。然而,噪声(误差)不可能是负的,因此我选择了指数分布。
后验预测图
让我们看看贝叶斯方法在后验预测分布中的作用。贝叶斯分析的一个真正有用的特性是生成后验预测分布的能力。这意味着我们可以可视化我们的模型认为是什么(和不是什么!)有可能。我们从斜率和截距的联合分布中取样,在给定一系列价格的情况下推断需求单位的预测,并绘制图表。绘制的线条简洁地捕捉了我们的价格-需求关系的变化!

鸣谢:作者图片
收入和利润
最后一步归结为定义一个成本函数,并推断出对需求、收入、成本和利润的预测,我们将这些视为具有自身分布的随机变量。
收入很简单,它是价格乘以需求量。我武断地决定,成本是 50 美元的管理费用加上 1.5 美元/单位。然而,这个成本函数可以替换为所需单元的任何函数。

鸣谢:作者图片
上面,我们可以看到 5.5 美元/单位的价格对应的是最大化的利润。下面的另一种视觉化方式捕捉到了 2D 的这种关系。热点中心显示,在给定需求、收入和成本的情况下,5.5 美元的价格可以带来 95-105 美元的总利润。

鸣谢:作者图片
最后这张图显示了价格和利润之间的关系,这是价格优化中倒数第二个利益关系。我们现在知道,我们可以以大约 5.5 美元的价格出售一些商品或服务,产生 95-105 美元的利润。
你有它!我希望我已经说服你至少尝试贝叶斯方法。一点额外的前期工作会给你一个更健壮的框架来理解你的决策空间。
离别笔记
亲爱的读者,我注意到一种模式,即用户将我的故事添加到他们的列表中,但不鼓掌或订阅。请——如果你喜欢我的内容,通过鼓掌、评论和订阅来确认它是有用的。这(1)有助于我确定下一步为您创建什么内容的优先级,以及(2)有助于其他媒体用户找到我的内容。谢谢你!
贝叶斯强化学习:用安全网模仿
原文:https://towardsdatascience.com/bayesian-reinforcement-learning-imitation-with-a-safety-net-6dd4d66da8bb?source=collection_archive---------25-----------------------
人工智能校准和安全
用恐惧强化学习

由 Alfonso Navarro 在 Unsplash 上拍摄
想象一下
比方说,你在高速公路上开车,无意中发现了这个:

斯卡泰利·奥尔谢夫斯基在斯卡泰利上的照片
显然,被圈起来的物体是一个汽车保险杠,但是让我们假设我们不确定这个物体是什么。作为人类,我们通过一系列问题来决定下一步行动:
- “那是什么?”
- “危险吗?”
- "我要不要急转弯来避开这个物体?"
尤其是在路上,我们倾向于安全行事。如果我们不知道这个物体是什么,我们几乎总是会选择避开这个物体。
然而,假设我们有一些人工智能机器人驾驶汽车。我们还假设人工智能确定这个物体是很可能是一个无害的纸箱。因此,驾驶汽车的代理人可能不会考虑到物体可能存在的风险与代理人所想的不一样。

克里斯托夫·杰施克在 Unsplash 上拍摄的照片
比较奖励信号
面对不确定性,我们如何训练代理人考虑这些风险?好吧,我们将从展示我们如何在学习环境中表现这种假定的“不确定性”开始。
要快速回顾强化学习的基础,请查看由 SmartLab AI 和 Robert Moni 撰写的这篇文章:
https://medium.com/@SmartLabAI/reinforcement-learning-algorithms-an-intuitive-overview-904e2dff5bbc
典型的强化学习环境给了我们一个显式的奖励函数,将状态-动作对映射到实数。在给定的状态下,更高的奖励意味着更有利的行动,反之亦然。RL 目标是最大化给定剧集的累积奖励:

然而,如果我们不确定这个奖励函数呢?假设我们有一套不同的奖励函数。有些可能是错的,有些可能是对的,或者可能一些子集的组合更接近于地面真相。然后,假设这些奖励函数中的每一个都有可能是“真正的奖励函数”报酬函数的这种分布称为后验报酬分布。
换句话说,给定一个国家行动对,与其回报相关的不是一个单一的实数,而是一个分布(多个数字,每个数字都有自己的概率)。这就是我们如何对环境中的不确定性建模;我们不确定我们行为的后果。
那又怎样?为什么不能只取这个报酬分布的期望值,把它崩成一个呢?这样,我们就有了和以前一样的场景:每个国家行动对都有一个单一的奖励。让我们看看会出什么问题。

斯特凡诺·佐卡在 Unsplash 上的照片
让我们把这个和汽车驾驶的例子联系起来。假设我们有以下奖励分配,假设驾驶员决定碾过物体:
- 如果物体是一个纸板箱,奖励 1(概率. 9)
- 如果物体是汽车保险杠(概率 0.1),奖励-5
在期望值中,我们的代理会被鼓励碾过物体,并会选择忽略与作为保险杠的物体相关的可能的风险。
那么,我们如何避免这个问题呢?我们需要一种可以训练风险意识策略的算法。接下来,我们将再看几个公式来帮助我们深入了解。

照片由 Unsplash 上的 Loic Leray 拍摄
动机
假设我们有一些连续的奖励概率分布。然后,假设我们绘制了不同轨迹的累积回报的概率分布图。
换句话说,x 轴代表一个代理可以采取的所有可能轨迹的累积回报。y 轴是每个轨迹的相关概率密度(注意这不是概率本身,因为我们现在处理的是连续分布)。

此分布的哪一部分代表与此环境相关的风险?我们可以把风险解释为导致不利结果的可能性。所以,我们的“风险”与这个图的左边,或者分布的某个较低的分位数相关。这就引出了我们对 Var 的定义。

Var 代表分布的 1-alpha 最低分位数。换句话说,它告诉我们,有 1-alpha 的概率生成一条轨迹,其累积回报低于 Var。直觉上,我们希望增加这个 Var 值。通过这种方式,我们可以增加在 1-alpha 概率的最坏情况下获得的回报,最大化甚至在“风险”情况下的表现。
然而,由于各种属性,Var 很难优化。相反,我们定义了 CVaR 值,这个值更容易优化:

CVaR 代表 1-alpha 下分位数内的预期表现。我们可以这样想 CVaR。假设,如果我们要训练奖励分布的期望值,给定一个状态,我们将通过考虑整个奖励分布来计算奖励。
然而,我们可以认为 CVaR 是在看这个分布的一个更小的窗口,即它的一些 1-alpha 更低的分数。然后,我们放大该窗口,并计算该窗口中的预期值(忽略其他一切)。
那么,CVaR 这个东西是什么意思呢?直觉上,如果我们能最大化 CVaR,我们就能最大化与那些悲观奖励函数相关的奖励金额(或者我们可以认为它是最小化惩罚),所有这些加起来有 1-alpha 的正确概率。

由史蒂文·韦尔奇在 Unsplash 上拍摄的照片
训练一项可怕的政策
因此,我们希望最大化 CVaR 来训练一个在 1-alpha 最坏情况下优化回报的策略:

其中 pi 代表一项政策,R 是后验奖励分布,psi 代表给定一项政策和奖励分布的累积奖励分布。
在某种意义上,我们可以认为增加 alpha 是告诉我们的政策有多害怕最坏的情况(就回报而言)。alpha 越高,左边的窗口越小,我们的 CVaR 向左移动越远,我们越优先考虑最坏的情况。
出于优化的目的,有一种表示 CVaR 的有用方法。下面是我们可以申请的身份(此处不涉及证明):

期望值中的“+”下标表示 ReLU 函数。因此,我们可以在我们的上下文中重新定义 CVaR,如下所示:

等一下。事情变得一团糟。让我们剖析一下这个等式中的每一个变量。这里,我们根据训练环境中的变量重新定义 CVaR。适马是我们正在最大化的一个参数,在我们之前对 CVaR 的重新定义中已经给出。阿尔法是一个超参数。
向量 p_r 代表与我们每个可能的回报函数相关的后验概率。然后,我们加粗的 psi 表示在每个奖励函数下轨迹的预期累积奖励。这个概率向量“点乘”成括号中的结果向量,产生先前定义的期望值。
总的优化问题变成如下:

注意我们在右边给出了一些约束。我们在这篇文章中没有推导出约束,但是它总结了 MDP 施加的约束(即平稳性)。变量 u 表示给定策略下的预期状态动作占用率计数。使用线性规划,我们可以在多项式时间内求解一个策略,定义如下:

那么,我们如何在强化学习的背景下计算这些变量呢?让我们看一下这项政策的每一部分:
- 后验回报函数概率:这些是给我们的
- 给定回报函数的预期回报:这些值可以通过不同的政策展开和蒙特卡罗来估计
- 适马:通常利用 CVaR 是凹的这一事实进行估计。欲了解更多详情,请查阅论文[1]。
因此,在实际训练中,我们收集政策轨迹样本,并随后估计预期回报和 sigma。然后,我们可以通过相应地求解线性规划来生成最优策略。
为了将这个公式转化为连续的状态和动作空间,我们可以使用一个策略梯度,其优势等于或正比于烧烤目标。这个烘烤目标/优点值是通过如上所述的类似采样来估计的。

由 Clark Young 在 Unsplash 上拍摄
玩小鸡游戏
最大化 CVaR 是通过直接优化较低分位数性能来训练风险容忍策略的强有力方法。但是,也有不好的一面。
仅仅最大化 CVaR,特别是在高 alpha 值的情况下,很大程度上忽略了更高的分位数回报函数。换句话说,习得的政策可能过于悲观和厌恶风险。对给定的奖励分配的这种不信任会产生次优的政策,特别是当奖励分配实际上是准确的时候。
因此,BROIL 选择在优化 CVaR 和报酬分布的期望值之间进行平衡:

其中 lambda 是一个超参数,表示我们对优化期望值的支持程度。我们可以将 lambda 解释为对奖励分配的信任度的度量。

马科斯·迈尔在 Unsplash 上的照片
结果
关于初步结果,请查看丹尼尔·布朗的论文[1]。当我们增加和减少 BROIL 的超参数(alpha 和 lambda)时,我们可以看到非常有趣的政策变化。
《炙烤的持续适应》是我和我的两个搭档和朱探索的一个班级研究项目的一部分。我们发现,通过修改最先进的策略梯度方法,BROIL 可以平滑地适应具有连续状态和动作空间的更复杂的环境。我们探索的其他部分将不会公开,因为我们的工作可能会进一步探索。
参考
[1]D.Brown,S. Niekum,M.Petrik,Bayesian 模仿学习的鲁棒优化 (2020)。
从经典到最新,这里是讨论多代理和单代理强化学习的相关文章:
贝叶斯统计程序设计:导论
原文:https://towardsdatascience.com/bayesian-statistical-programming-an-introduction-4ca3e2ddae76?source=collection_archive---------11-----------------------
第 1 部分,共 5 部分:贝叶斯统计的基本理论以及如何用 Python 实现一个简单的理论。
即使对于非数据科学家来说,贝叶斯统计这个术语也很流行。你可能在大学期间学过必修课,但没有意识到贝叶斯统计有多重要。事实上,贝叶斯统计不仅仅是一种特定的方法甚至是一类方法;这是一种完全不同的统计分析范式。

阿曼德·库利在 Unsplash 上拍摄的照片
为什么是贝叶斯统计?
贝叶斯统计为您提供了更新您对新数据证据的信念的工具,这是一个在许多现实世界场景中常见的概念,例如用于跟踪流行病、预测经济趋势或预测气候变化。贝叶斯统计是许多更著名的统计模型的基础,例如高斯过程。
[## 用简单的英语介绍高斯过程编程
towardsdatascience.com](/introduction-to-gaussian-process-programming-in-plain-english-8dd7a94cb18d)
最重要的是,学习贝叶斯统计的原则对于作为数据科学家的您来说是一笔宝贵的财富,因为它为您提供了一个全新的视角来解决现实世界数据的动态来源的新问题。
注意:这是包含贝叶斯统计编程主题的 5 部分系列文章的第一篇。
- 这篇文章涵盖了贝叶斯统计的基本理论以及如何用 Python 实现一个简单的贝叶斯统计。
2.第二篇将向您介绍贝叶斯推理以及如何执行基本的模型评估。
[## 构建和评估您的贝叶斯统计模型
towardsdatascience.com](/building-and-evaluating-your-bayesian-statistical-model-3ab703fc4ea8)
3.第三部分将涵盖一种特殊类型的贝叶斯算法,称为蒙特卡罗马尔可夫链(MCMC)。
4.第四部分将基于之前的文章构建一个更复杂的贝叶斯模型。
5.第五部分将向您介绍贝叶斯模型检查和评估的高级概念。
目录:
- 什么是贝叶斯统计?
- 贝叶斯编程介绍
- 贝叶斯工作流
- 构建简单的贝叶斯模型
事不宜迟,让我们开始介绍贝叶斯统计编程帖子。
什么是贝叶斯统计?
你可能在网上或课堂上看到过这个等式。

贝叶斯统计公式(来源: PyData 2019 )
如果你还没有,不要担心,因为我将简要地向你介绍贝叶斯的基本原理和公式是如何工作的。
关键术语
上述贝叶斯公式的组成部分通常被称为概率陈述。例如,在下面的后验概率陈述中,该术语的意思是“给定观察值 y ,θθ(θ)的概率是多少”。
Theta (θ)是这里的未知数,称为我们感兴趣的参数。参数的不确定性遵循特定的概率分布,该概率分布可以使用将数据与所讨论的参数相关联的模型的组合来估计。

贝叶斯概率陈述(图片由作者提供)
上面的贝叶斯统计公式也被称为 逆概率 ,因为它是从观测值到参数开始的。换句话说,贝叶斯统计试图从数据(结果)中推断假设(原因),而不是用数据来接受/拒绝工作假设。
贝叶斯公式
那么,贝叶斯公式告诉了我们什么?
- 后验概率是我们感兴趣的主要部分,因为θ是我们感兴趣的参数。
- 观察可能性简单地表示给定一个具体的θ值,数据 y 在现实世界中被看到的可能性有多大。
- 先验概率是我们对θ应该是什么样子的最佳猜测(例如,它可能遵循正态或高斯分布)
- 归一化常数只是一个使整个方程积分为一的因子常数(因为概率不能低于 0 而高于 1)。
既然我们已经介绍了贝叶斯统计的基本理论,让我们开始为即将到来的贝叶斯编程教程做准备。
贝叶斯编程介绍
装置
首先,安装 PyMC3 作为我们执行贝叶斯统计编程的选择库。
- 使用康达(推荐)
conda install -c conda-forge pymc3
2.使用画中画
pip install pymc3
获取数据
我们将使用描述美国家庭中氡气浓度的氡数据集。氡已被证明是非吸烟者中肺癌的最高预测因素之一,其浓度通常与房屋的整体条件有关(例如,地下室的存在,等)。
首先,在您的笔记本或终端中运行以下命令:
!wget "[https://raw.githubusercontent.com/fonnesbeck/mcmc_pydata_london_2019/master/data/radon.csv](https://raw.githubusercontent.com/fonnesbeck/mcmc_pydata_london_2019/master/data/radon.csv)"
确保您的数据位于笔记本的同一目录中。
数据探索
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as npradon = pd.read_csv('./radon.csv', index_col=0)radon.head()
我们注意到有 29 栏描述了一个家庭中氡的浓度。

数据集摘要(图片由作者提供)
让我们画一张图,显示“ANOKA”县氡的对数浓度分布,用一条垂直线说明对数浓度为 1.1。
anoka_radon = radon.query('county=="ANOKA"').log_radon
sns.distplot(anoka_radon, bins=16)plt.axvline(1.1)

密度分布(图片由作者提供)
在阿诺卡,氡对数浓度超过 1.1 的家庭比例似乎相当大,这是一个相当令人担忧的趋势…
贝叶斯工作流
现在我们有了数据,让我们进行贝叶斯推断。一般来说,这个过程可以分为三个步骤:
步骤 1:指定概率模型
这是你作为建模者将要做出许多选择的地方。你需要将最可能的概率分布函数(例如,正态或高斯、柯西、二项式、t 分布、f 分布、等)分配给所有的。

概率分布函数的样本(来源:NIST.gov)
所谓一切,我指的是包括未知参数、数据、协变量、缺失数据、预测在内的一切。因此,尝试不同的分布函数,看看它在现实世界中有什么意义。
步骤 2:计算后验分布
记得这个人吗?

后验分布(图片由作者提供)
好,现在你将计算这个概率项,给定贝叶斯方程右边的所有项。
第三步:检查你的模型
与其他 ML 模型一样,评估您的模型是关键。回到第一步,检查你的假设是否有意义。如果没有,改变概率分布函数,并一遍又一遍地重复。
构建简单的贝叶斯模型
现在,我将向您介绍一个简单的编程练习来构建您的第一个贝叶斯模型。我将在后续的帖子中更详细地介绍这些内容,请关注我!
步骤 1:定义贝叶斯模型
首先,我们用两个参数定义 Randon 的贝叶斯模型,均值(μ-“miu”)和它的偏差(σ-“sigma”)。这些参数(μ和σ)也需要通过选择我们选择的分布函数来建模(记住:我们必须定义所有参数的概率分布)。
对于这些,我们选择的函数是μ=0 和σ=10 的正态/高斯分布和均匀分布。您可以在模型验证检查期间重新校准这些值,如上面步骤 3 中所述。
from pymc3 import Model, Normal, Uniformwith Model() as radon_model:
μ = Normal(’μ’, mu=0, sd=10)
σ = Uniform(’σ’, 0, 10)
下一步是用另一个概率分布编译 radon_model 本身。
with radon_model:
dist = Normal('dist', mu=μ, sd=σ, observed=anoka_radon)
步骤 2:用数据拟合模型
现在,我们需要用数据来拟合模型(即培训)。
from pymc3 import sample
with radon_model:
samples = sample(1000, tune=1000, cores=2, random_seed=12)
让我们画出我们的参数μ在训练后的分布图,同时画出 95%的置信线
from arviz import plot_posterior
plot_posterior(samples, var_names=['μ'], ref_val=1.1)

Miu 的分布(图片按作者)
看起来 1.1 的对数浓度可能没有那么糟糕,因为它接近分布的尾端(只有 2.2%的样本具有大于 1.1 的对数浓度)。
离别的思念
我们已经讨论了贝叶斯统计的基本理论,以及为什么它对任何数据科学家来说都是如此重要的工具。在下一篇文章中,我将更详细地介绍构建更健壮的贝叶斯模型所需的一些建模方面。敬请期待!
做订阅我的邮件简讯:【https://tinyurl.com/2npw2fnz】在这里我定期用通俗易懂的语言和漂亮的可视化总结 AI 研究论文。
贝叶斯统计 101
原文:https://towardsdatascience.com/bayesian-statistics-101-4c4bc5fde1e1?source=collection_archive---------1-----------------------

照片由 Unsplash 上的延斯·勒列拍摄
不管你喜不喜欢,你都不会再以同样的方式看待统计数据了
介绍
贝叶斯统计与经典统计(也称为频率统计)的基本区别在于它对概率的解释。前者将其视为“信任度”,而后者将其视为“在多次试验中观察到的相对频率”。
这种差异可能看起来过于抽象,但它对后来开发的方法有很大的实际影响。
频率主义者的观点是最常见的,因此影响了大量的统计技术。然而,许多现代方法依赖于贝叶斯方法,可以产生很好的结果,当没有太多数据可用时,为您提供替代方案。
我们现在将看到的方法将为您提供一个正式的框架,通过该框架,您可以将主观判断添加到您的数据科学问题中,这在您没有太多可用数据时,或者在您知道数据存在某种缺陷时会特别有用。它还将帮助您理解一些著名的机器学习算法的起源,如朴素贝叶斯分类器和贝叶斯神经网络。
我们将从快速浏览贝叶斯定理(贝叶斯统计的核心)开始,然后继续学习由此衍生的一些技术,以及如何使用它们来解决各种统计问题。顺便说一下,我们将使用 Python。
贝叶斯定理

贝叶斯定理
上面的等式很简单,但是理解它需要知道一些概率论的符号:
- P(A) :事件发生的概率 A
- P(A|B) :假设事件 B 发生,事件 A 发生的概率
一个事件可以是任何事情。例如, P(A|B) 可以表示“假设( | )你的聚合酶链式反应测试检测结果为阳性( B ),你得到 COVID ( A )的概率( P )。要使用上述等式计算该概率,我们需要:
- P(A) :具有 COVID 的概率(不考虑测试结果)
- P(B) :聚合酶链式反应测试出现阳性结果的概率(无论您是否有 COVID)
- P(B|A) :给定 COVID,聚合酶链式反应测试出现阳性结果的概率
这个定理可以很容易地从条件概率的定义中推导出来,它并不专门用于贝叶斯统计,也不是经常性的争论。到目前为止,这只是基本的概率论。
贝叶斯统计
贝叶斯统计从现在开始所做的就是把这个定理变成下面的咒语:
你对世界如何运转有一个先验的信念。一旦你得到数据,你就相应地更新这种信念。
这意味着您通过定义一个先验分布来开始解决任何问题(这一步非常主观),然后您使用观察数据的可能性来更新该先验,创建一个后验分布。
不清楚?让我们看一个问题解决方案的例子,你会看到这在实践中是如何发生的。
蒙蒂·霍尔问题
让我们做个交易是一个流行的电视游戏节目,始于 60 年代的美国,其最初的主持人叫蒙蒂·霍尔。基于它的一个著名的概率谜题后来出名了,格式如下:
你在游戏节目的舞台上,这里有三扇门。其中一个后面有一辆汽车,另外两个后面有一只山羊。你必须选择其中一扇门,你的奖品将是门后的任何东西(显然你想要这辆车)。
你选 1 号门。然后主人打开 3 号门,发现门后有一只山羊。然后,他给你选择坚持 1 号门还是转 2 号门。你是做什么的?
这就是这个问题引起了很多愤怒的地方:我们的直觉告诉我们,换车门或坚持我们的选择之间没有区别,两者都有 50%的可能性把车藏起来。然而,仔细观察就会发现,换门确实是有益的——它实际上会让你的胜算翻倍。
让我们用贝叶斯观点来看这个问题。
我们从每个门的 1/3 的先验概率分布开始。这意味着每扇门都有 1/3 的机会成为“正确的”门(有 3 扇门,我们没有理由认为其中一扇门比另一扇门更有可能)。先验是贝叶斯定理中的 P(A)。

我们的前科
然后,考虑到我们拥有的新数据,我们继续计算可能性。如果汽车在后面,主人打开 3 号门(如他所做的)的可能性有多大:
- 1 号门:主持人会在 2 号门和 3 号门之间随机选择,所以这种情况下他打开 3 号门的概率是 1/2
- 门 2 :主持人必须打开门 3(因为汽车在门 2 后面,而你已经选择了门 1),所以在这种情况下他打开门 3 的概率是 1
- 3 号门:如果后面有车,主人不可能打开 3 号门,所以这种情况下主人打开 3 号门的概率是 0
这给我们留下了:

每个门的先验和可能性
似然性相当于贝叶斯定理中的 P(B|A)。现在,让我们计算“先验”和“可能性”的乘积:

先验*可能性是前两列的乘积
您会注意到 3 个值(1/6、1/3 和 0)加起来不等于 1。这是因为我们遗漏了贝叶斯定理的最后一个元素:P(B)。这恰好是这三个值的总和。通过将每一个除以总和,我们将以它们加到 1 的方式缩放它们。在我们的问题中,3 个值相加等于 1/2 (1/6 + 1/3 = 1/2)。为了找到我们的后验概率,我们只需将最后一列除以 1/2:

最后,我们的后路!
正如所料,汽车在 3 号门后面的概率是 0,因为主机已经打开了它。我们还看到,门 2 隐藏汽车的可能性是门 1 的两倍。
如果你对这个问题特别感兴趣,或者你觉得结果太反直觉,这里有一整篇文章关于它。
好吧,我知道这是一个玩具问题,我们使用了一个非常简单的分布作为我们的先验。当我们面对现实生活中的复杂问题时,会发生什么呢?这些问题有许多变量,先验不容易定义,可能性很难计算。幸运的是,有一个 Python 库可以帮助我们:PyMC3。
使用 PyMC3,您可以对许多事情使用贝叶斯推理,包括估计回归和分类的参数。您可以使用该库附带的内置函数来完成这项工作,或者使用它从头开始构建定制模型。第一个选项更简单,但灵活性较差,而第二个选项在选择参数时会给你更多的自由。
让我们来看看如何将这两个选项用于回归和分类等经典问题。
回归
线性回归“从零开始”

贝叶斯线性回归定义
如果你熟悉线性回归,你会发现它与传统模型有一些不同。主要的一点是,在贝叶斯回归中,我们不把参数α、β1、β2 和σ看作固定值,而是看作服从分布的变量。
我们将尝试估计这些分布,使用和以前一样的方法:定义一个先验分布并用数据更新它,得到一个后验分布。
在写这一部分时,我在使用真实世界的数据还是生成虚假数据来运行回归之间犹豫不决。我决定使用假数据,因为这将使我们能够将我们的结果与真实的地面真相进行比较:我们用来生成数据的参数。
**[IN]:** import arviz as az
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pymc3 as pm**# Setting a random seed for reproducibility**
np.random.seed(23)**# True parameter values**
alpha = -0.8
beta = [-1, 1.5]
sigma = 1**# Number of observations**
size = 500**# Predictor variables**
X1 = np.random.randn(size)
X2 = np.random.randn(size) * 0.8**# Outcome variable**
Y = alpha + beta[0] * X1 + beta[1] * X2 + np.random.randn(size) * sigma**# Putting our original data into a dataframe (we'll use it later on)**
df = pd.DataFrame(
data = np.array([X1, X2, Y]),
index=['X1', 'X2', 'Y']
).T
目前,除了导入所需的库和生成数据之外,我们还没有做太多工作。现在让我们使用 PyMC3 创建第一个模型:
**[IN]:**
with pm.Model() as model_1:
**# Data**
X_1 = pm.Data('X1', X1)
X_2 = pm.Data('X2', X2) **# Priors**
alpha = pm.Normal("alpha", mu=0, sigma=10)
beta = pm.Normal("beta", mu=0, sigma=10, shape=2)
sigma = pm.HalfNormal("sigma", sigma=10) **# Likelihood**
mu = alpha + beta[0] * X_1 + beta[1] * X_2
Y_obs = pm.Normal("Y_obs", mu=mu, sigma=sigma, observed=Y)
**# Posterior**
trace = pm.sample(100, return_inferencedata=False, chains=4)
az.plot_trace(trace)
首先,请注意模型构造的格式,这是 PyMC3 的标准格式:您将所有内容(数据、先验、似然和后验)放在一个“with”语句中,在这里命名您的模型(在我们的例子中是“model_1”)。稍后可以访问这个模型。
你可能会问为什么这些前科?在这种特定情况下,对于α和β,我们使用以 0 为中心的正态分布,因为我们没有任何先验知识可以表明 X 和 y 之间的强关系。关于每个先验中的σ= 10,它设置了正态分布的标准偏差,因此该数字越高,我们的先验中的方差越大,因此它们的信息量越少(如果您不太确定这些先验,这可能是一件好事)。西格玛参数的半正态分布将保持其正值。
尝试测试不同的先验,看看最终结果变化有多大,这实际上是一件好事,看看你的模型对不良先验有多稳健(变化越大,你越依赖你的先验)。
让我们来看看我们模型的输出:

第一个模型输出
该图中的每一“行”代表我们的一个参数(α、β、σ),左边部分代表后验分布,右边部分代表它们随时间的收敛。
以左上角的图为例:它显示了 alpha 的估计后验分布。但是等等,实际上有 4 个发行版,而不是一个!这是因为 pm.sample()有一个名为链的参数,设置为 2 或系统中 CPU 的数量,取其中较大的一个。在我的例子中,它等于 4,但是为了便于说明,我决定显式地设置它。链将设置并行运行的独立链的数量,这允许我们有一些收敛统计。
您还可以在右侧的图中看到链的概念,每个链有一条线。然而,这些线条显示的是什么?你看到 pm.sample()中的 100 了吗?也就是设置要抽取的样本数量。这些线条基本上显示了 100 个样本中,4 个链中每个链的参数的最可能估计值。对于 alpha,您可以看到它在-0.8 附近变化(尽管稍微偏向较低的值)。
在中间的左、右图中,beta 1 和 beta 2 的信息相同(可以通过不同的颜色区分它们)。
如你所见,估计的分布或多或少与基本事实一致(一些偏差可能来自我们设定的先验)。
我们有后验分布和它们的图,但是你可能想知道我们如何用它做预测。PyMC3 有一个名为fast _ sample _ posterior _ predictive的函数,它允许我们这样做:
**[IN]:**
with model_1:pm.set_data({
'X1': [0.6, 0.02],
'X2': [-1.3, 0.3]
})
y_test = pm.fast_sample_posterior_predictive(trace, samples=100)print(y_test['Y_obs'].mean(axis=0))**[OUT]:**
[-3.27941019 -0.31231568]
输出是我们放入示例中的 2 个观察值的预测,通过使用我们的后验分布获取 100 个样本来生成。
此外,如果您需要点估计而不仅仅是分布,您可以通过运行 find_MAP 并使用这些参数构建一个经典的线性方程来获得:
**[IN}:**
pm.find_MAP(model=model_1)**[OUT]:**
{'alpha': array(-0.85492716),
'beta': array([-1.05603871, 1.48859634]),
'sigma_log__': array(0.04380838),
'sigma': array(1.04478214)}
尽管 PyMC3 可能需要一段时间才能运行,但它确实让我们的生活变得轻松了许多。但是它到底是做什么的呢?
PyMC3 的工作方式与我们构建 Monty Hall 示例的方式并不完全相同,因为它并不计算精确的后验分布。相反,它做出了一个聪明的举动,实际上是从后验概率中采样数据,以便对其进行估计(这就是为什么你会在我们代码的“后验”部分看到“样本”函数)。
虽然这不会产生我们正在寻找的精确分布,但它在合理的时间内给了我们一个很好的近似值。它使用主要基于 MCMC(马尔可夫链蒙特卡罗)和 VI(变分推理)算法的方法来拟合模型。如果你想要更多关于这两种方法的数学细节,我建议你阅读这篇文章。
使用 GLM 的线性回归
现在,让我们看看如何使用 PyMC3 中的 GLM 类来获得我们的后验概率:
**[IN]:**
from pymc3.glm import GLM# Creating our model
with pm.Model() as model_glm:
GLM.from_formula('Y ~ X1 + X2', df)
trace = pm.sample(100)
pm.traceplot(trace)
plt.show()**[OUT]:**

GLM 产量
这个模型的构建几乎是不言自明的,也就是说,你所要做的就是写出 GLM 的公式,剩下的工作和以前差不多。显然,区别在于运行代码时幕后发生了什么。例如,你会注意到,这一次,你没有为你的参数设置先验。相反,PyMC3 使用默认的、无信息的先验,例如宽均匀和扩散正态分布,试图添加尽可能少的先验信息。
对结果的解释与前面的例子相同。
分类
逻辑回归“从零开始”
对于这个例子,让我们像以前一样重复使用相同的数据,但是为 Y 创建两个类:高于平均值的类和不高于平均值的类。
**[IN]:**
**# Creating a binary variable**
df['Y_bin']=df['Y']>df['Y'].mean()
我们现在将应用与线性回归相似的方法,但使用不同的可能性函数:
**[IN]:**
with pm.Model() as model_log: **# Priors**
alpha = pm.Normal("alpha", mu=0, sigma=10)
beta = pm.Normal("beta", mu=0, sigma=10, shape=2) **# Likelihood **
p = pm.Deterministic('p', pm.math.sigmoid(alpha + beta[0] * X1 + beta[1] * X2))
Y_obs = pm.Bernoulli("Y_obs", p, observed=df['Y_bin'])
**# Posterior**
trace = pm.sample(100, return_inferencedata=False, chains=4)
az.plot_trace(trace)**[OUT]:**

我们第一次逻辑回归的输出
首先,请记住,我们在这里估计的参数与我们为线性回归创建的参数不同,尽管它们有相同的名称。在第一种情况下,我们直接使用它们来创建 Y,而这里我们是在估计逻辑回归中的参数,所以我们不应该使用我们为 alpha 和 beta 设置的初始值作为这些参数的基础。
使用 GLM 的逻辑回归
让我们再次尝试解决上述分类问题,但使用 GLM:
**[IN]:**
from pymc3.glm.families import Binomialwith pm.Model() as model_glm_logistic:
GLM.from_formula('Y_bin ~ X1 + X2', df, family=Binomial())
trace = pm.sample(100)
pm.traceplot(trace)
plt.show()

逻辑回归的输出-GLM 版本
这个版本(逻辑回归)与第一个 GLM(线性回归)之间的差异主要在于 family=Binomial() 参数,显然至少在构建代码方面是如此。
结论
正如你所看到的,贝叶斯推理背后的直觉很简单:你的后验概率将介于你的先验(主观)信念和你观察到的数据之间,这意味着不同的人将得到不同的分布。然而,由此产生的方法并不那么简单,因为它们要求我们以不同的方式思考:总是根据分布而不是固定参数进行推理。
这只是对基本贝叶斯统计和推理的介绍,但这个主题要深入得多,并且有更多有趣的方法源于它:朴素贝叶斯分类器、贝叶斯神经网络、贝叶斯假设测试、贝叶斯分层建模和贝叶斯强化学习。希望我很快会在另一篇文章中写这些话题。
更进一步
如果你想更深入地研究贝叶斯统计,这里列出了一些额外的信息来源:
https://docs.pymc.io/en/stable/pymc-examples/examples/getting_started.html [## 斯坦 vs PyMc3 (vs 爱德华)
towardsdatascience.com](/stan-vs-pymc3-vs-edward-1d45c5d6da77)
最后,本文使用的代码可从以下网址获得:
https://github.com/arthurmello/statistics/blob/master/6. Bayesian statistics/Bayesian statistics.ipynb
如果你喜欢这篇文章,你可能也会喜欢这些:
https://medium.com/@arthurmello_/the-science-of-why-a-brief-introduction-ed92060e6f0d
如果你想进一步讨论,请随时在 LinkedIn 上联系我,这将是我的荣幸(老实说)。
贝叶斯统计
原文:https://towardsdatascience.com/bayesian-statistics-11f225174d5a?source=collection_archive---------16-----------------------
入门
很难相信概率统计曾经有过争议

常客 vs Bayesians |照片由 Lucas Benjamin 拍摄
这篇文章建立在我上一篇关于 Bootstrap 重采样的文章之上。
贝叶斯模型简介
贝叶斯模型是一类丰富的模型,可以为频繁模型提供有吸引力的替代方案。可以说,贝叶斯统计最广为人知的特征是贝叶斯定理,稍后将详细介绍。随着最近更强大的计算能力的出现和普遍接受,贝叶斯方法现在被广泛用于从医学研究到自然语言处理(NLP)到理解到网络搜索的领域。
在 20 世纪早期,有一场关于现在被称为贝叶斯的合法性的大辩论,贝叶斯本质上是一种做一些统计的概率方法——与我们都非常熟悉的“频繁主义者”阵营形成对比。用我们时代的说法,这是统计学家之间的#雅各布团队与#爱德华团队之争。这个争论现在已经没有实际意义了,因为几乎每个人都是贝叶斯主义者和频率主义者。一个很好的启发是,有些问题用频率主义方法处理更好,有些用贝叶斯方法处理更好。
在这篇文章结束时,我希望你能欣赏这个笑话:贝叶斯是这样一个人,她模糊地期待一匹马,瞥见一头驴,强烈地相信她看到了一头骡子!
历史
托马斯·贝叶斯牧师(1702-1761)提出了贝叶斯定理的一个有限版本。贝叶斯的兴趣在于赌博游戏的概率。他也是艾萨克·牛顿爵士新奇的微积分理论的狂热支持者,出版了他令人惊讶的标题为“流动学说导论,并为数学家们对《分析家》作者的反对意见进行辩护。”
1814 年,皮埃尔·西蒙·拉普拉斯在“Essai philosophique sur les probabilityés”中发表了一个版本的贝叶斯定理,类似于它的现代形式拉普拉斯将贝叶斯方法应用于天体力学问题。解决这些问题对 18 世纪晚期/19 世纪早期的船只有很大的实际意义。地球物理学家和数学家哈罗德·杰弗里斯广泛使用了贝叶斯方法。
二战见证了贝叶斯方法的许多成功应用:
- Andrey Kolmagorov,一位俄罗斯(苏联)的统计学家,使用贝叶斯方法极大地提高了火炮的精确度
- 艾伦·图灵用贝叶斯模型破解了德国潜艇的密码
- 伯纳德·库普曼,法国出生的美国数学家,通过截获定向无线电信号帮助盟军定位德国潜艇
20 世纪后半叶,计算贝叶斯方法取得了以下显著进展:
- 使用蒙特卡罗方法的统计抽样:斯坦尼斯拉夫·乌兰,约翰·冯·诺依曼;1946, 1947
- MCMC,或马尔可夫链蒙特卡罗;Metropolis 等人(1953)《化学物理杂志》
- Hastings (1970),使用马尔可夫链的蒙特卡罗抽样方法及其应用
- Geman 和 Geman (1984)图像的随机松弛、吉布斯分布和贝叶斯恢复
- 杜安,肯尼迪,彭德尔顿和罗威思(1987),哈密顿 MCMC
- 盖尔范德和史密斯(1990),基于抽样的方法来计算边际密度。
贝叶斯与频率主义观点
随着更强大的计算能力和普遍接受,贝叶斯方法现在被广泛应用于从医学研究到自然语言理解到网络搜索的各个领域。在实用主义者中,今天的普遍看法是,有些问题用频率主义方法处理更好,有些用贝叶斯方法处理更好。
从我关于中心极限定理 (CLT)的第一篇文章开始,我就确定了你需要“足够的数据”来应用 CLT。Bootstrap 抽样是获得更多接近基础分布的分布的便捷方法。这些是常客的工具;但是,如果数据太少,无法可靠地应用 CLT,会发生什么呢?作为一名概率贝叶斯统计学家,我已经有了一些估计,不可否认,有一点猜测,但有一种方法可以以智能的方式将猜测与我的数据结合起来。这就是贝叶斯统计的基本内容——你把它结合起来,基本上,这种结合是两个概率分布的简单乘法,一个是你猜测的,另一个是你有证据的。
数据越多,先验分布就越不重要,可以使用 Frequentist 方法。但是,在数据较少的情况下,贝叶斯的会给你一个更好的答案。
那么贝叶斯和频率主义方法论有什么不同呢?简单来说:
- 贝叶斯方法使用先验分布来量化已知的参数
- 常客没有量化任何参数;取而代之的是使用 p 值和置信区间 (CI)来表达关于参数的未知数
这两种方法都很有用,可以融合越来越多的数据,但形成对比:
严格的频率主义方法
- 目标是点估计和 CI
- 从观察开始
- 给定新的观察值,重新计算模型
- 示例:均值估计、t 检验、方差分析
贝叶斯方法
- 目标是后验分布
- 从之前的分布开始(猜测)
- 给定新的观察值,更新后验(信念/假设)
- 示例:平均最高密度区间(HDI)重叠的后验分布
今天,没有人是严格的常客。贝叶斯方法简单有效,这是事实。
贝叶斯定理
贝叶斯定理描述了一个事件的概率,基于先验知识(我们的猜测)可能与事件相关的条件,我们的数据。贝叶斯定理告诉我们如何将这两种概率结合起来。例如,如果患阿尔茨海默氏症等疾病与年龄有关,那么使用贝叶斯定理,一个人的年龄可以用来更可靠地评估他们患阿尔茨海默氏症、癌症或任何其他年龄相关疾病的概率。
贝叶斯定理用于更新假设的概率;假设是这种猜测,这种先验分布。先验的意思是你之前的信念,在你有证据之前就有的信念,是更新它的一种方式。因为你得到了更多的信息,你更新了你的假设,等等。
对于那些不知道或者已经忘记的人,让我们从条件概率的规则中推导出贝叶斯定理:

条件概率
翻译成“给定 B 的情况下,A 发生的概率。”

"给定 A 发生的概率,B 发生的概率."
消除𝑃(𝐴∩𝐵)和做非常小的代数:

或者,重新排列术语

也就是贝叶斯定理!这描述了如何找到给定事件 b 的事件 A 的条件概率。
应用程序
你有一个疾病测试,鉴于你有这种疾病,你得到阳性测试结果的概率非常非常高;换句话说,这个测试有很高的准确率。问题是,即使你没有患病,也有可能得到阳性检测结果。你可以根据贝叶斯定律简单计算。重要的一点是,这些概率并不等同于给定疾病后得到阳性结果的概率也不等同于给定疾病阳性结果后得到阳性结果的概率。

测试灵敏度与疾病的发病率不匹配
这是两种不同的概率分布。使它们如此不同的是患病的概率和阳性检测结果的概率。所以如果这种病很少见,那么发病的概率会非常非常小。
疾病检测:A =有疾病,B =检测呈阳性。

例子

尽管测试的准确度很高,但该测试的灵敏度相当差
使用 Bayes 定理,我们已经推导出,这种疾病的阳性测试结果表明,只有 10%的时间该人将实际患有该疾病,因为该疾病的发病率比假阳性率低一个数量级。
Python 示例:头发和眼睛颜色的概率
样本人群具有以下头发和眼睛颜色组合的概率。我将在 Jupyter 笔记本中运行下面的代码来查找条件概率:
# begin with the imports
import pandas as pd
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
import scipy
import seaborn as sns
import itertools%matplotlib inline# create the dataframe
hair_eye = pd.DataFrame({
'black': [0.11, 0.03, 0.03, 0.01],
'blond': [0.01, 0.16, 0.02, 0.03],
'brunette': [0.2, 0.14, 0.09, 0.05],
'red': [0.04, 0.03, 0.02, 0.02],
}, index=['brown', 'blue', 'hazel', 'green'])hair_eye

名词(noun 的缩写)b:这是眼睛颜色的字符串索引,而不是从零开始的数字索引。
hair_eye.loc[‘hazel’, ‘red’]

2%的人有淡褐色的眼睛和红色的头发
上表中的数字是条件概率。请注意,在这种情况下:
𝑃(hair|eye)=𝑃(eye|hair)p(hair|eye)=p(eye|hair)
给定这些条件概率,很容易通过对行和列中的概率求和来计算边际概率。边际概率是沿着分布的一个变量(一个边际)的概率。边际分布的总和必须是 1。
## Compute the marginal distribution of each eye color
hair_eye[‘marginal_eye’] = hair_eye.sum(axis=1)hair_eye

添加了 marginal_eye 列
hair_eye.sum(axis=0)

头发颜色的概率总和为 1
hair_eye.loc[‘marginal_hair’] = hair_eye.sum(axis=0)
hair_eye.describe

眼睛颜色概率的总和也是 1.0
我有蓝色的眼睛。我想知道他们有蓝眼睛的头发颜色的边际概率是多少?
# probability of blue eyes given any hair color divided by total probability of blue eyes# marginal probabilities of hair color given blue eyes
#blue_black(.03/.36) + blue_brunette(.14/.36) + blue_red(.03/.36) + blue_blond(.16/.36)
blue = hair_eye.loc[‘blue’,:]/hair_eye.loc[‘blue’,’marginal_eye’]
blue

对于一个蓝眼睛的人来说,有 44%的可能是金发,像我一样
应用贝叶斯定理
有一个方便用于计算问题的贝叶斯定理公式,因为我们不想像上面的例子那样,将所有计算 P(B) 的可能性相加。
这里有更多关于条件概率的事实和关系,主要来自于 P(B)很难计算的事实:

重写贝叶斯定理;

这是一个混乱,但我们并不总是需要复杂的分母,这是 B 的概率。 P(B) 是我们的实际证据,很难得到。请记住,这是概率性的,我们使用的数据样本比我们通常使用的要小。
重写我们得到的:

忽略常数 𝑘,因为它给出的证据——p(b)——被假定为常数,我们得到:

我们不需要知道实际证据和数据的概率分布
应用简化关系贝叶斯定理
我们将上述简化关系解释如下:

比例贝叶斯
比例关系适用于观察到的数据分布,或模型中的参数(部分斜率、截距、误差分布、套索常数等)。上面的等式告诉你如何把你的先验信念和你的证据结合起来,如果你想称之为先验分布的话。
一个重要的细微差别是,虽然我们不能谈论精确的值,但我们可以谈论分布;我们可以讨论概率分布曲线的形状。我们要的是所谓的后验分布。这就是我们想要的。我们所做的是猜测先验分布:A 的概率是多少?给定我所拥有的数据,某事为真的概率是多少?给定 B 的概率是多少?给定我所拥有的数据,某事为真的概率是多少?有些人会将此重新表述为,给定数据 B,我的假设 A 为真的概率是多少?
我可能只有很少的数据。太少做任何常客的方法;但是我可以估计,利用我拥有的少量数据,称为可能性,我可以估计这个数据是正确的概率,假设我可以直接计算。因为我有数据,不是很多数据,对我来说太少了以至于不能相信,但是我有一些数据。我有我的假设。所以我可以计算我的分布。
先验分布是我的假设的概率,我不知道,但我可以猜出来。如果我真的不擅长猜测,我会说这个先验分布是一个均匀分布,它可能是高斯或任何其他形状。现在,如果我猜测均匀分布,我仍然在做概率统计,贝叶斯统计,但我真的,真的很接近常客会做的。
在贝叶斯理论中,当我得到更多的数据时,我会更新这个先验分布,因为我会说,“嘿!”一开始我以为是制服。现在我看到,这个东西,这个概率分布,实际上有一个中间值。所以我现在要选择一个不同的分布。或者我要修改我的分布,以适应我在屁股上看到的东西。我试图让这个先验分布看起来和我的后验分布形状相似。当我说形状相似时,那实际上是非常误导的。我想做的是找到一个数学公式,将 A 的概率和给定 B 的概率混合起来。数学的类型相似,等式看起来相似,就像问题的公式化,而不是实际的概率;我们称之为得到共轭先验。这是当你寻找一个在数学上与你认为的最终分布相似的分布时。这在形式上被称为搜索共轭先验。由于其灵活性,β分布经常(但不总是)被用作先验分布。
重申一下,假设被形式化为模型中的参数,P(A),而 P(B|A) ,是给定这些参数的数据的概率——这很容易做到,t 检验可以做到这一点!
创建贝叶斯模型
给定关于参数行为的先验假设(先验),生成一个模型,告诉我们观察我们的数据的概率,以计算我们的参数的新概率。因此,使用贝叶斯模型的步骤如下:
- 确定与研究问题相关的数据:例如,数据的测量范围
- 定义数据的描述性模型。例如,选择线性模型公式或(2,1)的 beta 分布
- 指定参数的先验分布——这是假设的形式化。例如,认为线性模型中的误差正态分布为𝑁(𝜃,𝜎)
- 选择贝叶斯推理公式来计算后验参数概率
- 如果观察到更多数据,则更新贝叶斯模型。这是关键!随着更多数据的加入,后验分布自然更新
- 从参数的后验分布的实现中模拟数据值
选择一个先验
先验分布的选择对贝叶斯分析非常重要。先验知识应该让持怀疑态度的观众信服。要考虑的一些启发是:
- 领域知识(SME)
- 先前的观察
- 如果知识贫乏,则使用信息量较少先验知识
- 注意:均匀先验是信息性的,你需要对值的范围设置限制
一种分析和计算简单的选择是前面提到的共轭先验。当似然性乘以共轭先验时,后验分布与似然性相同。大多数命名的分布都有共轭:

共轭先验并不总是被使用
Python 示例:新冠肺炎随机采样
作为您所在城市的卫生官员,您对分析新冠肺炎感染率很感兴趣。您决定在红灯时在十字路口抽取 10 个人的样本,并确定他们的 Covid 测试结果是否为阳性——测试速度很快,为了避免抽样偏差,我们对他们进行了测试。数据是二项式分布的;一个人测试阳性或测试阴性——为了简单起见,假设测试是 100%准确的。
在本笔记本示例中:
- 为参数𝑝选择一个先验,即拥有新冠肺炎的概率。
- 使用数据,计算可能性。
- 计算后验和后验分布。
- 尝试另一个以前的发行版。
- 向我们的数据集添加更多的数据,以更新后验分布。
数据的似然性和后验分布是二项式分布。二项分布有一个参数我们需要估计,𝑝,概率。对于𝑘在𝑁试验中的成功,我们可以正式这样写:

以下代码计算一些基本的汇总统计信息:
sampled = [‘yes’,’no’,’yes’,’no’,’no’,’yes’,’no’,’no’,’no’,’yes’]
positive = [1 if x is ‘yes’ else 0 for x in sampled]
positive

N = len(positive) # sample size
n_positive = sum(positive) # number of positive drivers
n_not = N — n_positive # number negative
print(‘Tested positive= %d Tested negative= %d’
‘\nProbability of having COVID-19= %.1f’
% (n_positive, n_not, n_positive / (n_positive+ n_not)))

对于先验,我将从均匀分布开始,因为我不知道预期 Covid 率是多少:
N = 100
p = np.linspace(.01, .99, num=N)
pp = [1./N] * N
plt.plot(p, pp, linewidth=2, color=’blue’)
plt.show()
下一步:计算可能性。可能性是给定参数的数据的概率,【𝑃(𝑋|𝑝】。每个测试的每个观察值为“肯定”或“否定”都是伯努利试验,所以我选择二项分布。
def likelihood(p, data):
k = sum(data)
N = len(data)
# Compute Binomial likelihood
l = scipy.special.comb(N, k) * p**k * (1-p)**(N-k)
# Normalize the likelihood to sum to unity
return l/sum(l)l = likelihood(p, positive)
plt.plot(p, l)
plt.title(‘Likelihood function’)
plt.xlabel(‘Parameter’)
plt.ylabel(‘Likelihood’)
plt.show()

给定我们的假设,我们的数据为真的概率
现在我们有了先验和似然,我们可以计算参数𝑝:𝑃(𝑝|𝑋】的后验分布。
注意:这里使用的计算方法是为了便于说明而简化的。必须使用计算效率高的代码!
def posterior(prior, like):
post = prior * like # compute the product of the probabilities
return post / sum(post) # normalize the distributiondef plot_post(prior, like, post, x):
maxy = max(max(prior), max(like), max(post))
plt.figure(figsize=(12, 4))
plt.plot(x, like, label=’likelihood’, linewidth=12, color=’black’, alpha=.2)
plt.plot(x, prior, label=’prior’)
plt.plot(x, post, label=’posterior’, color=’green’)
plt.ylim(0, maxy)
plt.xlim(0, 1)
plt.title(‘Density of prior, likelihood and posterior’)
plt.xlabel(‘Parameter value’)
plt.ylabel(‘Density’)
plt.legend()
post = posterior(pp, l)
plot_post(pp, l, post, p)

print(‘Maximum of the prior density = %.3f’ % max(pp))
print(‘Maximum likelihood = %.3f’ % max(l))
print(‘MAP = %.3f’ % max(post))

有了均匀的先验分布,后验就是概率。关键点在于,在给定均匀先验的情况下,频繁者概率与贝叶斯后验分布相同。
尝试不同的先验
从上面的图表中,我选择了二项式分布的共轭先验,也就是贝塔分布。贝塔分布定义在区间 0 ≤贝塔(P|A,B)≤10 ≤贝塔(P|A,B)≤1 上。贝塔分布有两个参数,𝑎和𝑏,它们决定了形状。
plt.figure(figsize=(12, 8))alpha = [.5, 1, 2, 3, 4]
beta = alpha[:]
x = np.linspace(.001, .999, num=100) #100 samplesfor i, (a, b) in enumerate(itertools.product(alpha, beta)):
plt.subplot(len(alpha), len(beta), i+1)
plt.plot(x, scipy.stats.beta.pdf(x, a, b))
plt.title(‘(a, b) = ({}, {})’.format(a,b))
plt.tight_layout()

请注意,这些贝塔分布在参数稍有不同的情况下会变得多么不同
我仍然不太了解这个十字路口的司机的行为,他们可能有也可能没有新冠肺炎,所以我选择了一个相当不具信息性或宽泛的贝塔分布作为假设的先验。我选择 a=2 和 b=2 的对称先验:
def beta_prior(x, a, b):
l = scipy.stats.beta.pdf(p, a, b) # compute likelihood
return l / l.sum() # normalize and returnpp = beta_prior(p, 2, 2)
post = posterior(pp, l)
plot_post(pp, l, post, p)

注意,后验的模式接近于似然的模式,但是已经向先验的模式移动。贝叶斯后验概率向先验转移的这种行为被称为收缩性质:后验概率的最大似然点的趋势被称为向先验概率的最大似然点收缩。
更新贝叶斯模型
让我们用数据集的 10 个新观察值来更新模型。请注意,添加到模型中的观察值越多,后验分布就越接近可能性。
注意:对于大型数据集,可能需要大量的数据来观察后验概率和可能性的收敛行为。
new_samples = [’yes’,’no’,’no’,’no’,’no’,
‘yes’,’no’,’yes’,’no’,’no’] # new data to update model, n = 20
new_positive = [1 if x is ‘yes’ else 0 for x in new_samples]l = likelihood(p, positive+ new_positive)
post = posterior(pp, l)
plot_post(pp, l, post, p)

与第一个相比,注意当我们用更多的数据更新时,两个分布的收敛
可信区间
可信区间是贝叶斯后验分布上的区间。可信区间有时被称为最高密度区间(HDI)。例如,90%可信区间包含具有最高概率密度的后验分布的 90%。由于贝叶斯的可信区间和频率主义者的置信区间缩写相同(CI ),这可能会引起混淆。
幸运的是,可信区间是频率主义者置信区间的贝叶斯模拟。然而,它们在概念上是不同的。置信区间是根据测试统计的分布选择的,而可信区间是根据参数的后验分布计算的。对于对称分布,可信区间在数值上可以与置信区间相同。然而,在一般情况下,这两个量可以有很大的不同。
现在,我们绘制二项分布参数 p 的后验分布。95%可信区间(HDI)也将计算并显示出来:
num_samples = 100000
lower_q, upper_q = [.025, .975]# Caution, this code assumes a symmetric prior distribution and will not work in the general casedef plot_ci(p, post, num_samples, lower_q, upper_q):
# Compute a large sample by resampling with replacement
samples = np.random.choice(p, size=num_samples, replace=True, p=post)
ci = scipy.percentile(samples, [lower_q*100, upper_q*100]) # compute the quantiles
interval = upper_q — lower_q
plt.title(‘Posterior density with %.3f credible interval’ % interval)
plt.plot(p, post, color=’blue’)
plt.xlabel(‘Parameter value’)
plt.ylabel(‘Density’)
plt.axvline(x=ci[0], color=’red’)
plt.axvline(x=ci[1], color=’red’)
print(‘The %.3f credible interval is %.3f to %.3f’
% (interval, lower_q, upper_q))
plot_ci(p, post, num_samples, lower_q, upper_q)

因为上面的后验分布是对称的,和我们选择的贝塔先验一样,的分析和频率主义方法中 CI 的分析是一样的。我们可以有 95%的信心,在这个十字路口红灯时,大约 40%的司机会有新冠肺炎!这些信息对于卫生机构合理分配资源非常有用。
如果你还记得第三段中的笑话,关于贝叶斯人模糊地怀疑一匹马,瞥见一只驴,并强烈怀疑看到了一头骡子——我希望你现在能给笑话的每个条款分配适当的部分贝叶斯定理。
查看我的下一篇关于线性回归和使用 bootstrap 和回归模型的文章。
在 Linkedin 上找到我
物理学家兼数据科学家——适用于新机遇| SaaS |体育|初创企业|扩大规模
辉瑞-生物泰克新冠肺炎疫苗功效的贝叶斯统计—第一部分
原文:https://towardsdatascience.com/bayesian-statistics-of-efficacy-of-pfizer-biontech-covid-19-vaccine-part-i-efac8d4e0539?source=collection_archive---------6-----------------------
BCN 因果 ALGO
疫苗效力和β-二项式模型

疾控中心在 Unsplash 上拍摄的照片
目录
第一部分(本帖) 简介
什么是疫苗效力
结果可信度 贝叶斯推断
β-二项式模型
利用模拟进行疫苗效力统计 疫苗和安慰剂发生率
蒙特卡罗方法
后验概率和 95%可信区间
第二部分( 下一篇 )
转载自文章的统计数据 附加参数θ
θ的先验分布和发生率的调整
后验疫苗效力的可信区间
先前有感染迹象的参与者和先前无感染迹象的参与者中的新冠肺炎发生率
最终注释
参考文献
介绍
2020 年 12 月 10 日《新英格兰医学杂志发表了一篇题为bnt 162 b 2 mRNA 新冠肺炎疫苗 的安全性和有效性的论文。本文介绍了一项随机对照研究的结果,其中 43,548 名参与者被随机分配接受两剂 BNT162b2 疫苗(现称为辉瑞-生物泰克新冠肺炎疫苗)或两剂安慰剂。这些剂量每隔三周使用一次。然后对参与者进行为期约 2 个月的新冠肺炎发展跟踪。结果令人吃惊。疫苗效力为 95% ,其中可信区间等于(90.3–97.6%)。发表一天后,美国美国食品药品监督管理局发布了第一份疫苗的紧急使用授权。这是一个新的希望,因为这个世界正在经历一个非常复杂的时期,死亡人数增加,封锁,边境关闭,失业率上升,就业机会消失,经济衰退…
除了是一个重要的结果之外,引起我注意的是这篇论文的作者使用可信区间报告了统计数据。这意味着研究者决定使用贝叶斯而不是频率主义者的推论。由于我参与了随机对照试验的设计,我想了解它是如何完成的。不幸的是,文章或研究方案中并未包含所有细节。所以我需要做一些侦查工作。
首先,我收集了关于疫苗组和安慰剂组的人数,以及每组中受感染人数的信息,然后我做了一些计算。得到的可信区间的大小与文章中的接近,但不相同。所以我更仔细地看了协议。我试着从那里重现这些步骤。这一次,计算出的可信区间更接近原始区间,但仍不完全相同。
最后,我意识到我们需要对疫苗组和安慰剂组的规模进行额外的调整。和“瞧!”。数字是一样的。但是我怎么能确定这不是巧合呢?幸运的是,文章中还计算了另一个可信区间。有了这些,我就可以确认这些步骤很可能是正确的。
我不得不承认,在试图找出如何从文章中重现结果时,我获得了一些乐趣。如果你有兴趣了解 2020 年最重要的一项研究中的统计数据是如何计算的,在这篇文章中你可以找到跟随我的步骤所需要的一切。我希望你熟悉统计学,但你不需要成为专家。在这里,我试图解释贝叶斯推理的一些概念,可以帮助你理解计算。我还包含了您自己执行的 Python 代码。
我把笔记分成了两部分。在第一部分的中,我会给你一个理解下面章节所需的贝叶斯推理的最小概要。然后,我将介绍一种简单的方法来计算文章的统计数据。用这种方法,你可以得到接近原来的结果。如果这对你来说还不够,你还应该读一下 第二部分 的注释。这部分稍微难一点。我们将向您展示一种方法,允许您以一位数的精度再现结果。然后,我们将使用文章中可以找到的另一个可信区间来验证该方法。
什么是疫苗效力
在转向贝叶斯统计之前,让我解释一下如何估计疫苗效力。首先,我们需要将研究参与者随机分为两组:疫苗组和安慰剂组。被称为疫苗组的第一组人接受疫苗,安慰剂组的人接受安慰剂。无论是参与者还是申请人员都不知道参与者接种的是疫苗还是安慰剂。然后,当研究结束时,疫苗效力通过以下公式进行评估

其中 IRR 为发生率比,由下式给出

疫苗发病率 是疫苗组中确诊的新冠肺炎病病例与人数之比 安慰剂发病率 与安慰剂组相同(参见论文中的统计分析部分)。
现在,让我们看看纸上的数字,重新计算。这些数字可以在下表中找到,这是我从原始文章中复制的。

表 1:针对 covid 的疫苗效力(转载自https://www.nejm.org/doi/full/10.1056/NEJMoa2034577
您可以在表格的第一行看到,在疫苗接种前没有感染迹象的参与者的情况下在疫苗组中,我们有 8 个新冠肺炎病例,根据监测时间调整后的参与者人数为 17,411 (见表 1)。注意,我们没有使用参与者总数,即18198。这是因为需要对监测时间进行调整,因为不是每个人都在同一时间参与了研究。例如,如果一个人被监测 1 个月,而另一个人被监测 2 个月,这是不一样的,因为后者有更多的机会出现有症状的新冠肺炎。所以我们必须修改这个总数,我们得到 17,411 。我们无法重现这一计算结果,因为我们无法获得单个患者的数据。然而,我们建议对如何做到这一点感兴趣的读者参考这个笔记本。
因此,我们可以计算疫苗发病率如下

安慰剂组的发病率也是如此:

把这些放在一起

我们可以用下面的方式解释这个结果。在接种疫苗的人群中,95%通常会出现新冠肺炎症状的人没有表现出任何迹象。
结果的可信度
这个 95%的功效看起来确实很不错。但是……我们有多少信心?在随机对照试验中,我们通过估计无效或效力不足的疫苗上市的概率来回答这个问题。我们称之为“控制I 型误差”。
在本研究中,疫苗效力的评估是基于疫苗效力大于 30% 的概率(参见方案第9.1.2.1 部分,第 107 页)。他们决定,为了批准疫苗,这个概率必须大于 97.5%。即

换句话说,犯 I 型错误的概率应该低于 2.5%,在这种情况下,I 型错误意味着批准效力低于 30%的疫苗。结果如何?表 1 的最后一列显示疫苗效力大于 30%的概率高于 99.99% 。等价的,犯 I 型错误的概率低于 0.01% 。
事实上,结果要比这好得多。 95%可信区间等于(90.3–97.6%)。稍后我会详细解释什么是 95%可信区间。现在让我告诉你,它暗示疫苗效力大于 90.3% 的概率是 97.5%。所以最初的 30%门槛相当悲观。

30%的阈值相当悲观,因为结果表明疫苗效力的分布在右侧很远。这对我们来说是个好消息。
现在轮到我们深入贝叶斯推理来计算这些结果了。
贝叶斯推理
在这封短信中无法解释贝叶斯统计。有很多书很好地做到了这一点(例如, 贝叶斯统计,李家杰的导论)。我要做的是展示足够的信息来解释和再现文章的结果。我还会向读者推荐在哪里可以找到更多的解释。
贝叶斯统计中的核心角色当然是由贝叶斯定理扮演的。为了我们的需要,我们可以把它重新表述为

这是什么意思?先验信念代表我们在收集数据之前的信念,由可能参数的概率分布表示。似然是针对每个可能的参数,得到观测数据的概率。(先验信念)*(观测数据的似然)是修正我们信念的公式。如果更有可能为某些参数收集观察数据,则这些参数在后验置信的分布中获得更多权重。奇怪的等号表示我们可以忽略常数,也就是说我们不在乎这个公式是乘以 0.01 还是 100。这里我们处理概率分布,所以我们只需要知道不同可能性之间的关系。
我知道第一次看到这种形式主义有点尴尬。但它代表了一种相当直观的东西。例如,如果我们有一种新的疫苗,而我们对此一无所知,那么我们之前的信念就非常薄弱。在这种情况下,我们可以说,根据我们先前的信念,疫苗效力低于 30%或高于 30%的概率是相同的。但是,在看到一项研究的结果后,我们的后验信念会发生变化。有了像我们这里这样的结果,我们可以说疫苗效力更有可能大于 30%。
贝塔二项式模型
我们还需要解释一下贝塔-二项式模型是如何工作的。在这个模型中,我们假设一个人有一定的概率获得新冠肺炎。假设这个概率是θ。那么,如果我们观察到在 n 个人中, k 个生病,那么这个事件的可能性遵循 二项分布 。即

我们假设θ遵循 贝塔分布 作为我们的先验信念:

其中α和β是大于零的参数。这种假设的最重要的原因是下面我们解释的贝塔分布和二项式分布之间的数学联系。即贝塔分布是伯努利分布的共轭先验。
事实上,因为在公式中

我们可以忽略常数(这意味着我们可以忽略不包含θ的所有因子),我们得到

这意味着后验置信也遵循参数为α+k 和β+n-k 的贝塔分布。如果后验置信和先验置信遵循相同类型的分布,我们说对于似然函数我们有共轭先验(参见李的贝叶斯统计书的第 3.1.1 节)。
综上所述,如果我们的模型具有遵循二项式分布的似然函数,并且先验函数遵循贝塔分布,我们称这个模型为贝塔-二项式模型,并将其写为

使用模拟的疫苗效力统计
首先,我将计算疫苗效力的统计数据,与本文中的方法略有不同。我觉得初读起来更简单易懂一点。在本笔记的第二部分,我们将再现原始计算。
疫苗和安慰剂发病率
现在我们回到疫苗和安慰剂的发病率。首先,我们假设我们先前的信念是,接种疫苗和服用安慰剂的人感染新冠肺炎病毒的概率是相同的。这意味着它们都遵循相同的β分布,具有相同的参数α和β。现在,这些参数的值应该是什么?嗯,我们可以假设平均大约 1%的人会生病。此外,我们希望选择相对较弱的先验信念,这意味着当我们收集到足够的数据时,它们可以很容易地被改变。那么自然的选择是假设β=1,α≤1,这样

重写为

我们明白了

那么α应该在 0.010101 左右。因此,我们假设疫苗和安慰剂发病率的先验分布遵循相同的β(0.010101,1)分布。

疫苗和安慰剂发病率的先验分布
现在,在进行试验后,在疫苗组中,我们在 17,411 名参与者中观察到了 8 例新冠肺炎病例(让我提醒你,这个数字是经过调整的,因为参与者的监测时间不同)。因此,使用上一节中的公式可以得出疫苗发生率的后验 Beta-二项式模型为 Beta(0.010101+8,1+17411–8)。另一方面,安慰剂发生率为β(0.010101+162,1+17511–162)。我们总结如下。

那么这些分布的曲线如下:

疫苗和安慰剂发生率的后验分布
这些图清楚地显示了疫苗发病率的分布远低于安慰剂发病率的分布。这已经表明,我们偶然得到这些结果的可能性极小。反正我们来统计一下。
蒙特卡洛法
所以现在我们要计算疫苗发病率低于安慰剂发病率的概率。即

我们将使用蒙特卡罗方法。
蒙特卡洛方法是一种对复杂或不可能以显式形式给出的公式进行数值估计的方法。为了估计我们的概率,我们将从疫苗发生率和安慰剂发生率的分布中抽取 1,000,000 对数字,然后看看其中有多少数字的疫苗发生率较低。这里我们提供了 python 代码。
结果是 1.0。意味着概率几乎是 1。

后验概率和 95%可信区间
让我们回忆一下,疫苗效力是由公式给出的。

首先,我们计算疫苗效力大于 30%的概率。尽管有可能获得一个显式的公式(例如参见 T2 的论文,这里我们还是使用模拟。
因此,我们可以如表 1 所示:

同样的方法我们可以计算出 95%的可信区间。有几种方法可以定义可信区间(例如参见这篇维基百科文章)。在文章中,95%可信区间定义为包含 95%后验分布的区间,受百分位数 2.5 和百分位数 97.5 的限制。下面是计算它的 python 代码。

具有 95%可信区间的后验分布:(90.8–97.9%)
最终我们的结果是,疫苗效力为 95%,95%可信区间等于(90.8–97.9%)。您可以得到稍微不同的结果,但它们应该非常接近。这些结果与文章中的结果非常相似,95%可信区间等于(90.3–97.6%)。但它们略有不同。在本笔记的第二部分,我们将介绍如何重做文章中的计算。
第一部分结束
在这一部分中,我们学习了如何计算疫苗效力,以及如何使用贝叶斯统计估计其可信度。第二部分稍微复杂一点。我们将进一步了解研究方案,以便向您展示如何像本文中那样计算统计数据。
所有可视化,除非另有说明,均由作者提供。
辉瑞-生物泰克新冠肺炎疫苗有效性的贝叶斯统计—第二部分
原文:https://towardsdatascience.com/bayesian-statistics-of-efficacy-of-pfizer-biontech-covid-19-vaccine-part-ii-7c5388489163?source=collection_archive---------17-----------------------
BCN 休闲 ALGO
复制原始结果

(经玛丽亚·何塞·佩莱斯·蒙塔尔沃许可)
本文是后辉瑞-生物科技新冠肺炎疫苗功效贝叶斯统计的第二部分——第一部分。在第一部分中,我给了你一个贝叶斯推断的简单总结,这是理解如何计算疫苗效力的统计数据所需要的。然后,我向您展示了一个简单的方法,它可以让您获得接近于来自原始文章的结果。如果这些对你来说还不够,你还应该看看这一部分。这稍微有点困难,但是我将向您展示如何以一位数的精度重现可信区间的计算。然后,我们将使用文章中可以找到的另一个可信区间来验证该方法。
目录
第一部分( 上一篇 ) 简介
什么是疫苗效力
结果可信度 贝叶斯推断
β-二项式模型
使用模拟法统计疫苗效力 疫苗和安慰剂发生率
蒙特卡罗方法
后验概率和 95%可信区间
第二部分(本帖)
从文章中复制统计数据 附加参数θ
θ的先验分布和发生率的调整
后验疫苗效力的可信区间
新冠肺炎在有和无先前感染证据的参与者中的发生率
最终注释
参考文献
从文章中复制统计数据
如果我们想了解文章中的统计数据是如何计算的,我们需要查看研究方案。该协议的重要之处在于,它应该在实验开始前注册,以避免事后挑选最方便的计算。
然而,正如 Sebastian Kranz 在这篇博客文章中所写的那样,我们需要“做一个有根据的猜测”,因为我们并不知道所有的细节。除了他有根据的猜测之外,我还需要增加一个,即对新冠肺炎出现次数的调整。加上这个额外的“猜测”,数字与下表完全相同。

表 1:针对 Covid 的疫苗效力(转载自 https://www.nejm.org/doi/full/10.1056/NEJMoa2034577)
在本节的最后,我们通过再现有感染迹象的参与者和没有感染迹象的参与者中的新冠肺炎发生率来验证我们的计算,这是表 1 的第二行。
附加参数θ
让我们来看看第 102-103 页的协议。他们决定借助一个额外的参数来估计疫苗效力的不确定性。该参数θ由以下公式给出:

该公式将θ与疫苗效力联系起来。乍一看,这个额外的参数似乎是一个额外的复杂因素,有什么好处呢?原因是,正如我们将在下面展示的,我们可以用一个贝塔-伯努利模型来模拟θ,这样就不需要使用蒙特卡罗方法。让我展示一下。
首先,请注意,我们可以将公式改写为

然后,如果我们假设每组(疫苗组和安慰剂组)有相同数量的参与者,那么公式就变成了

我们在这里。我们可以用贝塔-伯努利模型来模拟θ。一旦我们知道了θ,我们就可以用公式计算出疫苗效力

θ的先验分布
在协议第 102-103 页,假设θ的先验分布遵循贝塔分布贝塔( 0.700102,1)。现在让我试着按照协议,找出这些α=0.700102,β=1 是从哪里来的。
首先,他们假设疫苗效力的先验值为 30%。那么,θ的先验值应等于:

由于θ遵循β分布,那么,正如我们之前所做的,其参数的自然选择,β=1 且α≤1 应该是这样的

然后设β=1,我们得到

就像协议里说的那样。

θ的先验分布:β(0.700102,1)
θ的后验分布和事件的调整
现在让我们得到θ的后验分布。由于疫苗组有 8 例新冠肺炎,安慰剂组有 162 例,因此后验分布为β(0.700102+8,1 + 162) 。然而,由于疫苗组的规模不等于安慰剂组的规模,我们需要调整这些数字。让我解释一下我们需要怎样做。
调整监测时间后,疫苗组有 17411 人,安慰剂组有 17511 人。总计 34922。因此,如果各组相等,那么每组应该有 17461 个。因为在疫苗组中,我们在相应的组中分别出现了 8 次和 162 次新冠肺炎,使用比例我们得到

那么θ的后验分布就是β(0.700102+8.02297,1+161.53743)。

θ的后验分布:β(0.700102+8.02297,1+161.53743)
疫苗后验效力的可信区间
知道了θ的分布,我们就可以最终计算出疫苗效力的可信区间。使用 python 可以做到如下。
四舍五入我们得到 95%可信区间是(90.3,97.6),和文章中的完全一样。

95%可信区间下疫苗效力的后验分布
先前有感染迹象和没有感染迹象的受试者中的新冠肺炎发生率
最后,让我将上述所有内容应用于重现疫苗效力,以及在有感染迹象和无感染迹象的受试者中,在第二剂疫苗后至少 7 天出现新冠肺炎的
95%可信区间(见表 1 第二行)。这将证实我们有根据的猜测。
首先,我们再次需要调整两组中新冠肺炎的出现次数:

因此,在这种情况下,θ的后验分布为β(0.700102+9.03613,1 + 168.327),我们可以使用 python 计算 95%可信区间,如下所示。
舍入后,我们得到它等于(89.9–97.3),与文章中的完全一样。
最后一个音符
如果你已经到了这一步,并且没有迷失太多,那么恭喜你。我们设法以一位数的精度复制了表 1。我花了相当长的时间才弄清楚所有的细节。尽管如此,我不能 100%肯定地说这些就是研究人员采取的确切步骤。
我不得不承认,我不仅在试图弄清楚统计是如何进行的过程中获得了乐趣,而且学到了很多东西。我希望你也是。我还希望,如果你对贝叶斯统计相对陌生,我能够展示这种推理方式是非常强大的。它给我一种感觉,我很清楚自己在做什么。
我只是触及了贝叶斯推理的表面。让我在这里给你一个参考文献列表,你可以在那里找到关于这个主题的更多信息。
参考文献
对于不熟悉贝叶斯统计的读者,我推荐以下两本书中的一本。两个都很棒,虽然第一个在数学上肯定要轻一些。
然后,我会建议看一看原始文章和预注册协议和 Sebastian Kanz 注意。
【1】Richard McElreath:统计学再思考第二版。
【2】【贝叶斯统计概论】第四版**
****【3】Polack FP,Thomas SJ,Kitchin N,等bnt 162 b 2 mRNA 新冠肺炎疫苗的安全性和有效性。N Engl J Med 2020;383:2603–2615.
****【4】BioNTech-Pfizer:方案:一项 1/2/3 期研究,旨在评估针对健康个体的新冠肺炎候选 RNA 疫苗的安全性、耐受性、免疫原性和有效性(从 326 页开始)
Sebastian Kranz: 看看 BioNTech/Pfizer 对他们的新冠肺炎疫苗试验的贝叶斯分析。
所有可视化,除非另有说明,都是作者的。
贝叶斯统计概述和你的第一个贝叶斯线性回归模型
原文:https://towardsdatascience.com/bayesian-statistics-overview-and-your-first-bayesian-linear-regression-model-ba566676c5a7?source=collection_archive---------0-----------------------
简要回顾贝叶斯学习,然后在 NYC Airbnb 开放数据集上实现贝叶斯线性回归模型
你好。欢迎阅读我的第一篇文章,在这篇文章中,我将简要介绍贝叶斯统计,然后带您浏览一个简单的贝叶斯线性回归模型。
目前,我们研究的大多数机器学习问题都是通过频繁模式解决的,而贝叶斯学习的应用相对较少。因此,在这篇文章中,我想讨论 ML 中一个非常普遍的话题——线性回归——并展示如何使用贝叶斯方法实现它。
当我第一次开始研究这个问题时,我有很多问题,比如,什么时候使用贝叶斯是有益的,输出与它的非贝叶斯对应物(Frequentist)有什么不同,如何定义先验分布,python 中是否有用于估计后验分布的现有库,等等。我试图在这篇文章中回答所有这些问题,同时保持简短。
1。贝叶斯总结
1.1 什么是贝叶斯学习,与频率主义者统计有什么不同
Frequentist 和 Bayesian 是统计学的两个不同版本。Frequentist 是一个更经典的版本,顾名思义,它依靠事件的长期运行频率(数据点)来计算感兴趣的变量。另一方面,贝叶斯也可以在没有大量事件的情况下工作(事实上,它甚至可以在一个数据点上工作!).两者的主要区别在于:frequentist 会给你一个点估计,而 Bayesian 会给你一个分布。
有一个点估计值意味着—“我们确定这是这个感兴趣变量的输出”。然而,有一个分布可以解释为——“我们相信分布的平均值是这个感兴趣的变量的很好的估计,但是也有不确定性,以标准偏差的形式”。
那么,什么时候使用贝叶斯有用呢?如果您对既关心估计又关心确定性方面的 ML 任务感兴趣,贝叶斯方法将非常有用。举个例子:如果你想知道今天是否会下雨,有一个类似“有 60%的概率可能会下雨”的输出,会比只说“会下雨”更直观的反应。后者的回答不包括该模型对其预测有多有信心。
1.2 贝叶斯哲学:
贝叶斯方法背后的主要潜在公式是 贝叶斯定理 。这是一个简单的公式,帮助我们计算一个事件 A 给定事件 B 的条件概率:

作者图片
1.2.1 术语:
P(A|B) 称为后验概率:我们希望计算的分布
P(B|A) 称为可能性:假设事件 A 已经发生,事件 B 发生的可能性有多大?
P(A) 被称为先验:我们最初对感兴趣的变量的猜测
P(B) 称为证据:事件 B 发生的可能性。注意:这通常很难计算,并且在估计后验概率时通常不计算
应用程序
贝叶斯定理的一些常见应用是:
- 假设今天是阴天(事件 B),那么今天下雨(事件 A)的概率是多少
- 在 c 罗不上场的情况下(事件 B),曼联今天获胜的概率有多大(事件 A)
- 假设我们在 4 次投掷中看到 3 个正面和 1 个反面(事件 B),硬币有偏差的概率是多少(事件 A)。
1.3 频率主义者 vs 贝叶斯:一个简单的例子:
考虑以下,频率主义者与贝叶斯的最常见的例子:在掷硬币中评估偏差:
在贝叶斯公式中,这将转化为:
事件 A =硬币是否倾斜(比如朝向正面)
事件 B =样本硬币投掷(经验数据)
P(A|B) =待计算!
P(A) =先验概率(这里假设先验假设硬币没有偏差,在 0 和 1 之间是均匀的)
使用上述术语和先验假设,让我们计算多达 500 次掷硬币的后验概率。后验概率是在每次抛硬币后计算的,输出可以在下图中看到。每次迭代计算的后验概率成为下一次迭代的先验概率。红色虚线是每次试验后 frequentist 的输出。

作者图片
从上面的图中,您可以看到分布迅速从均匀转变为高斯分布,平均值约为 0.5。另一点需要注意的是,在每次迭代后,钟形曲线只会变细,表明方差减少。这意味着,它仍然编码了少量的不确定性,而频率主义者只给出一个值。
2.贝叶斯线性回归:
当我在探索用贝叶斯学习代替常见的 ML 解决方案来完成回归任务时,给我印象最深的一个应用是贝叶斯线性回归。我已经在一些 ML 问题中应用了它,并想在这里分享它的一瞥。在深入研究之前,下面是普通线性回归的简短回顾。
2.1 线性回归概述:
线性回归试图在响应变量和输入变量之间建立线性关系。使用以下公式对此进行了最佳描述:

在上式中,所有 x_i 都是输入特征,β_i 是相关系数。ε对应于等式中的统计噪声(x 和β的线性关系没有考虑到这一点)。上面表示的方程是回归的最一般形式。通过最小化损失函数(通常是 L2 损失函数)来计算系数。因此也被称为普通最小二乘(OLS)算法。由于我们只有一个系数的估计值,所以我们最终只有一个响应变量(y)的值
2.2 贝叶斯线性回归:
从贝叶斯的角度来看,线性回归方程会以稍微不同的方式书写,这样就没有对系数的单一估计。这主要包括两个步骤:
- 计算β(即 P(β|X,y))的后验分布
- 使用后验分布计算响应变量
2.2.1 计算β的后验分布
受贝叶斯定理的启发,我们有

由于证据项难以计算,因此可以写成:

看上面的等式,我们可以看到我们需要在等式中输入两个东西——可能性和先验。这不是很直接。
2.2.1.1 预选:
通常,先验分布的选择基于领域知识。从字面上看,先验意味着我们对未知事物的信念。在大多数情况下,我们会有一些关于先验的知识,这可以更容易地为它分配一个特定的分布。在最坏的情况下,我们可以从文献调查中提取一些知识,或者使用均匀分布。以掷硬币为例,我们使用了统一的先验假设,假设我们对硬币的偏差一无所知。该先验将被给定为:

类似地,我们也会为其他未知量(ε,σ)分配先验。
【2.2.1.2 可能性:
似然项由 P(X,y|β)给出。由于 X 是常数,不依赖于β ,似然项可以改写为 P(y|β) 。最常见的方法是假设“y”遵循正态分布,以 OLS 预测作为平均值。因此,可能性项将由下式给出:

现在,如果我们在贝叶斯方程中加入先验和似然项,事情会变得非常复杂。在多个概率密度函数的帮助下计算后验概率可能看起来非常令人生畏。虽然,研究人员已经提出了各种技术来解决这个问题。一个非常流行和成功的方法是马尔可夫链蒙特卡罗算法(MCMC) 。它计算实际后验分布的近似值。因此,当您从这个近似分布中抽取样本时,您基本上是从未知量的真实(或接近真实)分布中抽取样本(在我们的例子中,是β、ε、σ)。我们可以使用这些抽取的样本来计算其他感兴趣的指标,如平均值、标准差等。我不会深入研究这个算法,但是如果您有兴趣了解更多,我在参考资料中提供了一些链接。
2.2.2 使用后验分布计算响应变量
如前所述,贝叶斯线性回归模型的输出将是一个分布,而不是一个单一的估计。因此,如前所述,考虑它的一种方法是使用均值为(β)的高斯分布。T * X) + ε,带有一些方差σ。同样,这将表示为:

[注意,我们将使用上一步中所有未知数的计算后验分布的平均值]
现在,为了对给定的数据点(x_i)进行预测,我们可以用 x_i 代替 X,从上述正态分布中抽取样本。
3。在 NYC Airbnb 数据集上实现贝叶斯线性回归:
[注意:这一整节的代码可以在这里找到github/colab
让我们尝试在一个公共数据集上实现我们所学的所有内容— NYC Airbnb 数据。该数据集包含在纽约不同行政区出租整个公寓的价格信息。数据集的一个小预览是:

不同行政区的价格分布如下:

作者图片
你可以看到每个区的价格都有很大的不同。不出所料,曼哈顿似乎有更高的方差。这是因为一些社区,如上西区、西村等。,可以看到一个非常不同(更贵)的公寓价格(如下所示):

作者图片
现在,比方说,你在曼哈顿唐人街拥有一套公寓,你想把它放在 Airbnb 上。你会给它报价多少?(假设 Airbnb 没有报价)。
对此可能有许多解决方案,但其中之一将是贝叶斯线性回归,因为它将为我们提供一系列值。而且,拥有这个范围将帮助你很好地理解价格的分布,做出明智的选择。
3.1 OLS 预测:
使用 scikit learn 实现 OLS 给出曼哈顿唐人街这套公寓的估价为 227 美元。让我们也包括它与其他社区的比较:
[为了简单起见,我们只关注几个街区:中城、东哈莱姆区、唐人街、上西区、NoHo]

作者图片
看上面的图表,我们可以看到唐人街的价格差异很大(在 65 美元到 1500 美元之间)。上西区和中城等其他街区的差异要比唐人街大得多。因此,仅仅依靠一个单一的估计似乎并不完全正确。
2.4 编码贝叶斯线性回归:
为了编写贝叶斯线性回归,我会使用 pymc3 包。
再次回忆一下,响应变量定义为:

现在,开始吧,我们首先要指定三个未知数的先验分布:β,ε,σ
由于我已经对数据进行了标准化,我将对这些参数使用均值为 0 且标准差稍高的标准正态分布。

使用 pymc3 的代码将是:

现在,要利用 pymc3 中的内置算法来估计后验分布,请运行以下代码:

“ 样本 ”功能负责自动分配合适的算法。例如:连续输出的 NUTS(一种哈密顿蒙特卡罗方法),离散输出的 Metropolis,二进制输出的 Binary Metropolis 等。你可以在这里找到更多关于推理步骤的细节。
现在,您可以使用以下代码绘制参数的后验分布:



作者图片
β参数有多个图,对应每个维度的边际分布。(要详细查看所有特性,请参考代码[github][colab])
接下来,可以使用计算出的β、ε和σ的分布来绘制特定数据点 x_i 的正态分布。

使用上面的公式,列出曼哈顿唐人街附近公寓的价格分布如下:

作者图片
对于不同的社区,这种分布会有所不同。此外,方差将根据我们拥有的数据量减少/增加。上面的分布是仅用 3K 数据点计算的。
拥有如上的分布将帮助我们更好地理解价格市场,并帮助我们做出明智的决定。
2.5 当‘N’很大时会发生什么:
让𝑁表示我们拥有的证据的实例数量。随着我们收集越来越多的证据,即当𝑁→∞,我们的贝叶斯结果(经常)与频率主义者的结果一致。因此,对于一个无限大的 N,贝叶斯或频率主义者的统计推断是相似的。然而,对于小𝑁,推断是不稳定的:频率主义者的结果有较高的方差。这就是贝叶斯结果有优势的地方。
对于 3000 个数据点,频率主义者和贝叶斯的均值之间的比较没有很大不同:

结论:
这篇文章只是对贝叶斯线性回归的介绍,以及一些贝叶斯概念的回顾。作为一名数据科学家,了解解决同一个问题的不同方法以及它们之间的比较是非常有益的。当我开始探索贝叶斯方法来解决我们工作中的一些常见的 ML 任务时,我个人感到非常激动,并被迫在这里分享一些。
其次,这篇文章不应该被认为是贝叶斯主义者。两者都是不同的方法,声称一种比另一种好是不正确的。主要看你的用例是什么。Cassie Kozyrkov 深入研究了这一比较,如果你感兴趣,我强烈推荐这篇文章。
感谢阅读!
我非常感谢你通读整篇文章。如果您有任何问题/想法或想要分享任何建设性的批评,非常欢迎您通过 @Akashkadel 联系我。这是我的第一篇文章,我真的希望提高。
参考资料了解详情:
- 贝叶斯先验:https://fukamilab . github . io/bio 202/05-B-Bayesian-priors . html
- 基于不同先验选择的后验输出比较:https://OCW . MIT . edu/courses/mathematics/18-05-introduction-to-probability-and-statistics-spring-2014/readings/MIT 18 _ 05s 14 _ reading 15b . pdf
- 马尔可夫链蒙特卡罗方法介绍:https://towards data science . com/a-zero-math-introduction-to-Markov-Chain-Monte-Carlo-methods-dcba 889 e0c 50
- 马尔可夫链蒙特卡罗视频讲解:https://www.youtube.com/watch?v=yApmR-c_hKU&t = 612s
- 另一篇关于贝叶斯线性回归的好文章:https://towards data science . com/introduction-to-Bayesian-Linear-Regression-e66e 60791 ea 7
- Pymc3 指南:https://docs . pymc . io/en/v3/pymc-examples/examples/getting _ started . html
贝叶斯结构时间序列中断方法
原文:https://towardsdatascience.com/bayesian-structural-time-series-interruption-method-5018761db92b?source=collection_archive---------28-----------------------
差异中的差异的贝叶斯方法

克里斯·利维拉尼在 Unsplash 上的照片
W 在处理真实世界的数据时,很难找到干净、孤立、可控的实验室数据集。我们经常发现,我们都学习的更经典的统计方法根本不起作用——它们的假设太不现实或太死板,数据集在各方面都让它们失望。例如,一个常见的假设是独立同分布随机变量。这通常是不现实的:你怎么能保证同一个板块中两家公司的股价是独立同分布的呢?他们是竞争者,因此他们的价格不是独立的。它们没有理由分布相同(一个可能是成长型公司,另一个可能是蓝筹股价值公司,因此具有不同的股价函数)。有时,假设 i.i.d .可能不是获得相关结果所必需的,但可能会妨碍推断(参见此处的讨论)。
线性回归增加了更多的假设,例如线性(两个变量共享一个线性关系)、同方差(残差的方差是常数)、独立性(这意味着没有自相关)和正态分布。差异中的差异法假定治疗组与对照组的分配是随机的,两组在结果方面具有平行趋势(组间差异随时间保持不变),并且没有溢出效应。对于真实世界的数据,这可能是一个问题。首先,分配可能不是随机的。对于经济学数据,当一个政府宣布一个 X 规则时,它通常对所有人都有效(不仅仅是一个治疗组)。其次,对照组和治疗组之间的关系通常会随着时间而变化(我稍后将称之为时变)。第三,很难说没有溢出效应。一个买家可能会因为一个有趣的广告而对产品 X 感兴趣,但是在公司的网站上也会对产品 Y、甚至两种产品感兴趣。也可能是这样的情况,你没有一个控制组(你只有一个产品或一个法律变化),但仍然想确定一个事件 E 是否改变了一个时间序列变量的过程。一种方法是使用贝叶斯结构时间序列。
例如:政府公告和盈亏平衡汇率
我的理学学士论文使用 BSTS 方法来评估政府公告是否会影响盈亏平衡率(的时间序列路径)。盈亏平衡利率就是政府债券的名义收益率和实际收益率之差。因此,这里感兴趣的变量( y )是具有非常高的自相关性的时间序列变量。不仅如此,它还受到遗漏变量偏差的影响——这意味着有一个未知(或换句话说,未观察到的)变量 Z 影响y。这就是流动性溢价,它很难测量,并且可能是时变的。因为我们处理的是政府公告,所以没有控制组。政府公告是面向所有人的,我们无法观察如果它没有发生会是什么结果(我们无法回到过去改变过去来看)。还有趋势和季节性效应也需要分解。
python 包 causalimpact 可以帮助我们实现这个模型。我们没有反事实(来自对照组的观察结果),但是我们有关于盈亏平衡率的多年数据,以及一些与盈亏平衡率相关的其他变量。这些被称为协变量。它们与响应变量 y 的关系可以假设为静态的(随时间恒定)或时变的(随时间变化)。通常选择与响应变量关系大致相同的变量更简单。
对于盈亏平衡率,我将使用富时 100 指数的收盘价、英镑的交易指数(因为我们正在测试英国政府债券)和 25 年的盈亏平衡率。将使用 25 年的盈亏平衡率,因为它与响应变量 y 非常相关,但不受独立变量 X. 的影响。这可以在下图中看到,其中蓝线是 5 年的盈亏平衡率,绿线是 25 年的盈亏平衡率。这些年来,他们的关系似乎非常稳定。

资料来源:Brunna Torino
此外,您需要选择与干预日期相关的前期和后期。 前期需要足够长,以便模型能够充分学习时间序列的路径及其与协变量的关系;后期需要反映效果需要多长时间才能完全“显示”在数据中(例如,一个活动需要多长时间才能开始工作?新信息需要多长时间才能在股票市场上定价?).然而,后期应该是前期的一小部分,因为随着该比率的上升,模型对其预测越来越不自信。
实施
一旦我决定了感兴趣的变量、协变量和干预前/后参数,下面是我如何在我的模型中实现它们:
首先,我分别使用 20 天和 5 天创建前期和后期日期。接下来,我确保所有的日期都是工作日。所有日期都被传递到不同的列表(干预日期、前期日期、后期日期和干预日期+ 1 算法格式)。
接下来,我们需要将 y 时间序列的索引设置为 DateTimeIndex 类型。我正在处理多种到期日(3 年和 15 年之间的多种盈亏平衡利率),所以我需要做两个循环:一个针对每个到期日,一个针对每个干预日。我提取模型的 p 值、平均效应和累积效应。下面是实现的主要部分:
最后,我将输出附加到原始数据集。现在,我有了干预日期、协变量值、债券公告的意外规模(这是我的独立变量),以及该公告对相关时间序列 y 的影响,以及表明影响是否显著的 p 值。你可以在这里停下来,逐个分析影响,或者使用 logit 回归来建立因果关系。这将为您提供以下模型:
*显著性[0,1] = alpha 意外 债券公告规模
其中 alpha 是要测量的系数, y 变量是一个二进制[0,1],表示 BSTS 方法发现的干预是否显著,以及绑定公告的意外大小,简单如下:
还可以查询模型的单个地块以了解其准确性。以下是 2018 年 9 月 25 日政府公告的情节:

资料来源:Brunna Torino
黑线显示盈亏平衡率,蓝线显示模型的预测。该模型能够在干预前保持在实际 y 的 0.05 点之内,但在干预后却不能,这表明时间序列可能在干预日期后发生了突然变化。
结论
据估计,债券公告对盈亏平衡利率的影响即使有,也是很小的。然而,如果没有一些严肃的数据平滑,这种影响不可能被线性回归准确地捕捉到:这个特定练习的 r 低至 2–7%。差异中的差异做出了一系列假设,即数据没有通过,并且合成控制的构建将更加困难,即使可能或准确。
这种方法对于这样的情况是一个非常有用的选择:数据并不像实验室那样完美,真实的影响可能很小并且在发展,没有什么可以被假设为线性和简单的。世界是一个复杂的地方,能够捕捉这种复杂性的灵活模型应该更受那些寻求真正理解它的人的欢迎。
Bayesian mmm——最先进的媒体混合模型
原文:https://towardsdatascience.com/bayesianmmm-state-of-the-art-media-mix-modelling-9207c4445757?source=collection_archive---------5-----------------------

罗伯特·卡茨基在 Unsplash 上的照片
轻松测试你的媒体组合的贝叶斯模型
测试一个新的营销组合模式是非常耗时的。这就是开发 BayesianMMM(一个无需编写代码就能适应 MMM 的脚本)的原因。
几个小时之内,你就可以看到艺术模型的结果。
https://github.com/leopoldavezac/BayesianMMM
观众
- 营销数据科学家
- 营销机器学习工程
- 营销数据分析师
- 活动经理/所有者
介绍
媒体组合模型是营销科学的圣杯。一个准确的媒体组合模型可以给我们提供最佳的媒体组合,即在增加收入的同时减少媒体支出的组合。
一个媒体组合模型揭示了媒体支出和收入之间的因果关系。
用于训练这种模型的数据集通常是每周一次的,看起来像这样,

作者图片
模型
BayesianMMM 中使用的模型是由谷歌的一组研究人员在Bayesian Methods for Media Mix Modeling with carry out and Shape Effects中提出的。
就像经典的 MMM 一样,它旨在根据媒体支出和其他控制变量(季节、天气等)来预测销售。然而,经典回归模型有三个关键的更新。
遗留效应
媒体支出对销售有持久的影响,在某一周花费的一美元将有助于几周的销售。我们称这种效应为遗留效应,它被明确纳入模型中。
两个数学函数可用于模拟遗留效应。
地理预测
地理数据转换 仅模拟媒体支出的持久影响。
该函数将 L 周期间给定媒体的媒体花费 L 和保留率作为输入。l 是花费的最大持续时间效果。L 可以被视为超参数,使用商业知识定义或设置为 13(在模拟设置中,已经发现 L 是无穷大的良好近似值),如研究论文中所建议的。留存率是一个系数,它使用当前期间(t)的支出得出下一期间(t+1)的留存支出。

作者图片
这里,我们在 lag = 0 时将开销设置为 1,否则设置为 0。在保留率为 0.7 的情况下,我们获得了以下结转支出。

作者图片
Adstock 改造
有时,我们预计媒体支出效应会在一段时间后达到顶峰。广告转型模拟了媒体支出的持久和延迟影响。
该函数将 L 周期间给定媒体的媒体花费 L、峰值的保留率和延迟作为输入。延迟是峰值效应之前的周期数。

作者图片
这里,我们再次在 lag = 0 时将开销设置为 1,否则设置为 0。在保留率为 0.7,延迟为 5 的情况下,我们获得了以下 adstock 开销。

作者图片
形状效应
媒体支出越大,回报越少。我们称之为形状效应,它明确地包含在模型中。
希尔
该函数将周期 t 的花费、形状和半饱和度作为输入。这些参数不像遗留转换的参数那样容易解释。如果你不理解他们,你就必须和他们一起玩。

作者图片
这里我们设置花费为 1,形状为 0.5,半饱和度为 0.5。

作者图片
综上所述,我们的模型可以表述如下:

作者图片
拟合方法
通过 pystan API 使用 MCMC 估计模型参数。
我们在参数分布上设置了与研究论文中相同的先验。
在用户定义的迭代次数之后,我们获得了参数后验分布的样本。我们使用这些样本来估计参数的真实值。
挑战
要适应一个媒体组合模型有很大的挑战,这里有一个不完整的列表。
- 有限的可用数据
与参数的数量相比,可用的数据量很小。这可能导致准确性问题,并在测试和评估准确性中引入一些偏差。
- 输入变量之间的相关性
媒体支出之间通常有很高的相关性。这可能导致不良的销售归因于销售渠道。
- 有限的数据范围
有限的数据范围也可能是一个问题,因为营销利益相关者总是想推断结果。
您可以在媒体混合建模的挑战和机遇中了解更多关于这些挑战以及如何应对的信息。
结果
运行脚本后,我们得到以下结果,

作者图片
在这里,您可以看到使用演示数据集生成的贡献分析图。

作者图片
使用
要了解如何使用 BayesianMMM,请参考 Github repo。
*https://github.com/leopoldavezac/BayesianMMM
结论
虽然 BayesianMMM 脚本将大大减少测试最先进的媒体混合模型所需的时间,但它并没有处理所有的挑战。你还是要自己处理这些事情!
感谢阅读,您可以在 LinkedIn 上与我联系。*
BBN:贝叶斯信念网络——如何用 Python 有效地构建它们
原文:https://towardsdatascience.com/bbn-bayesian-belief-networks-how-to-build-them-effectively-in-python-6b7f93435bba?source=collection_archive---------0-----------------------
机器学习
使用真实生活数据在 Python 中构建模型的贝叶斯信念网络的详细解释

图片由皮克斯拜的 Gerd Altmann 提供
简介
大多数人可能已经熟悉朴素贝叶斯算法,这是一种用于分类问题的快速而简单的建模技术。虽然朴素贝叶斯由于其速度和相对较好的性能而被广泛使用,但它是建立在所有变量(模型特征)都是独立的假设之上的,而这在现实中往往是不正确的。
在某些情况下,您可能想要构建一个模型,在其中您可以指定哪些变量是从属的、独立的或者条件独立的(这将在下一节中解释)。您可能还希望实时跟踪事件概率随着新证据引入模型而发生的变化。
这就是贝叶斯信念网络派上用场的地方,因为它们允许你通过清晰地勾勒变量之间的关系来构建一个带有节点和有向边的模型。
内容
- 贝叶斯信念网络(BBN)属于哪一类算法
- 贝叶斯信念网络(BBN)和有向无环图(DAG)简介
- 使用真实生活数据的贝叶斯信念网络 Python 示例
-用于天气预测的有向无环图
-数据和 Python 库设置- BBN 设置
-使用 BBN 进行预测
- BBN 设置
- 结论
贝叶斯信念网络(BBN)属于哪一类算法?
从技术上讲,BBN 国内没有培训。我们简单地定义了网络中不同的节点是如何连接在一起的。然后,我们观察在将一些证据传递到特定节点后,概率如何变化。因此,我将概率图形模型归入它们自己的类别(见下文)。
旁注,由于神经网络独特的机器学习方法,我已经将它们归为一类。然而,它们可以用于解决广泛的问题,包括但不限于分类和回归。下图是交互式,请务必点击👇在不同的类别上对进行放大并展示更多的。
机器学习算法分类。互动图表由作者创作。
如果你也热爱数据科学和机器学习 ,请 订阅 每当我发布新故事时,你都会收到一封电子邮件。
贝叶斯信念网络(BBN)和有向无环图(DAG)
贝叶斯信念网络(BBN)是一种概率图形模型(PGM),它通过有向无环图(DAG)表示一组变量及其条件依赖关系。
为了理解这意味着什么,让我们画一个 DAG 并分析不同节点之间的关系。

有向无环图。图片由作者提供。
利用上述内容,我们可以陈述变量(节点)之间的关系:
- 独立性: A 和 C 相互独立。B 和 C 也是如此。这是因为知道 C 是否发生并不会改变我们对 A 或 B 的认识,反之亦然。
- 依赖: B 依赖 A,因为 A 是 B 的父,这个关系可以写成条件概率:
P(B|A)。d 还依赖于其他变量,在这种情况下,它依赖于其中的两个——B 和 c,同样,这可以写成一个条件概率:P(D|B,C)。 - 条件独立: D 被认为是条件独立于 A 的,这是因为一旦我们知道事件 B 是否发生了,A 从 D 的角度来看就变得无关紧要了,换句话说,下面是真的:
P(D|B,A) = P(D|B)。


使用真实数据的贝叶斯信任网络 Python 示例
用于天气预报的有向无环图
让我们用澳大利亚的天气数据来建造一个 BBN。这将使我们能够根据今天的一些天气观测来预测明天是否会下雨。
首先,在详细介绍如何构建 DAG 之前,让我们先来看看它。注意,我已经显示了所有不同事件组合的概率。在接下来的几节中,你会看到我们是如何使用天气数据来计算这些数据的。

贝叶斯信念网络(BBN)预测明天是否下雨的有向无环图(DAG)。图片由作者提供。
数据和 Python 库设置
我们将使用以下数据和库:
- 来自 Kaggle 的澳大利亚天气数据
- PyBBN 用于创建贝叶斯信念网络
- 熊猫进行数据操作
- 用于绘制图形的 NetworkX 和 Matplotlib
让我们导入所有的库:
然后我们从 Kaggle 获取澳大利亚的天气数据,你可以按照这个链接下载:https://www . ka ggle . com/jsphyg/weather-dataset-rattle-package。
我们接收数据并推导出一些新的变量用于模型中。
以下是数据的快照:

经过一些修改的 Kaggle 的澳大利亚天气数据片段。图片由作者提供。
建立贝叶斯信念网络
现在我们已经准备好了所有的库和数据,是时候建立一个 BBN 了。第一阶段要求我们定义节点。
需要注意一些事情:
- 这里的概率是数据中变量类别的归一化频率。例如,“H9am”变量在值≤60 时有 43,594 个观察值,在值> 60 时有 98,599 个观察值。

变量值计数。图片由作者提供。
- 虽然我使用了归一化频率(概率),但如果你使用实际频率,它也是有效的。在这种情况下,您的代码应该是这样的:
H9am = BbnNode(Variable(0, 'H9am',['<=60', '>60']), [43594, 98599])。 - 对于子节点,如“Humidity3pmCat”,它有一个父节点“Humidity9amCat”,我们需要为每个组合提供概率(或频率),如 DAG 中所示(注意每行加起来为 1):

“湿度 3pmCat”标准化频率(概率)。图片由作者提供。
- 您可以通过两次计算“H3pm”的概率/频率来实现这一点,第一次通过获取“H9am”≤60 的数据子集,第二次通过获取“H9am”> 60 的数据子集。
- 因为一次计算一个频率很费时间,所以我写了一个简短的函数来给出我们所需要的。
因此,让我们使用上面的函数,而不是手动输入所有的概率。同时,我们将创建一个实际的网络:
请注意,如果您正在处理一个小的数据样本,则存在某些事件组合不存在的风险。在这种情况下,您会得到一个“列表索引超出范围”的错误。一个解决方案是扩展您的数据以包含所有可能的事件组合,或者识别缺失的组合并添加它们。
现在,我们要绘制图表来检查我们是否按照预期进行了设置:
下面是结果图,它符合我们的预期设计:

BBN 天气预报的有向无环图。图片由作者提供。
利用 BBN 进行预测
我们的模型准备好了,我们可以用它来预测明天是否会下雨。
首先,让我们画出每个节点的概率,而不向图中传递任何附加信息。注意,我已经设置了一个简单的函数,这样我们就不必在以后重新输入相同的代码,因为我们需要多次重新生成结果。
上面的代码打印了以下内容:

原始 BBN 概率。图片由作者提供。
如你所见,这给了我们每个事件发生的可能性,即“明天下雨(RT)”的概率为 22%。虽然这很酷,但我们可以通过查看原始数据集中“RainTomorrow”变量的频率来获得同样的 22%的概率。
说接下来的步骤是我们从 BBN 中获得大量价值的地方。我们可以将证据传入 BBN,看看这如何影响网络中每个节点的概率。
假设现在是上午 9 点,我们已经测量了室外的湿度。上面写着 72,显然属于“> 60”的波段。因此,让我们把这个证据传递到 BBN,看看会发生什么。注意,我创建了另一个小函数来帮助我们。
这给了我们以下结果:

BBN 概率与“H9am”证据。图片由作者提供。
大家可以看到,“湿度 9am>60”现在等于 100%,“湿度 3pm>60”的可能性从 32.8%上升到了 44.2%。与此同时,“明天下雨”的几率上升到了 26.1%。
此外,请注意“风速”的概率没有变化,因为“W”和“H9am”相互独立。
您可以再次运行相同的证据代码,以从网络中移除证据。之后再来传“H3pm”和“w”的两个证据。
结果如下:

具有“H3pm”和“W”证据的 BBN 概率。图片由作者提供。
不出所料,这告诉我们明天下雨的可能性上升到了 67.8%。请注意“H9am”的概率也发生了变化,这告诉我们,尽管我们只测量了下午 3 点的湿度,但我们 93%确定今天上午 9 点的湿度也在 60 以上。
结论
贝叶斯信念网络有许多用例,从帮助诊断疾病到实时预测比赛结果。
你也可以建立 bbn 来帮助你做营销决策。说,我可能想知道这篇文章有多大可能达到 10K 的观点。因此,我可以构建一个 BBN 来告诉我某些事件发生的概率,例如在 Twitter 上发布这篇文章的链接,然后评估当我获得十次转发时这一概率如何变化。
最终,可能性几乎是无限的,有能力生成实时预测,一旦引入新的证据,就会自动更新整个网络。
我希望你和我一样发现了贝叶斯信念网络。如果您有任何问题或建议,请随时联系我们。感谢阅读!
干杯!👏
索尔·多比拉斯
如果你已经花光了这个月的学习预算,下次请记得我。 我的个性化链接加入媒介是:
https://solclover.com/membership
如果你想继续学习贝叶斯主题,你可以看看下面这篇关于朴素贝叶斯分类器的文章。
用 Python 做蛋白质组学侦探
原文:https://towardsdatascience.com/be-a-proteomic-detective-with-python-6ea18ef3f8f3?source=collection_archive---------28-----------------------
在 Jupyter 笔记本中检查同量异位标记蛋白质组学结果的质量

我们应该用我们的质谱数据跟随福尔摩斯和华生的脚步。西德尼·佩吉特的《海滨杂志》(1892)插图,目前在公共领域
同量异位标记定量蛋白质组学很复杂,需要大量的样品制备、质谱(MS)采集和数据分析。样品被溶解和增溶,半胱氨酸残基通常被还原和烷基化,蛋白质被消化成肽,肽被同位素标记的试剂标记,通常被分馏和脱盐[1]。而这只是从样品瓶到质谱仪的路径!很多事情都可能出错,因此仔细检查数据的质量非常重要,这些数据将成为生物学和医学结论的基础。
今天,我想分享一个 Jupyter 笔记本,其中包含一系列处理和可视化步骤的 Python 代码,我发现在检查蛋白质组发现者 (PD)套件的输出时,这些代码非常方便。它是 PD,因为我们在实验室中使用它,当然,如果输出足够全面,也可以使用其他数据处理管道。完整的笔记本已经上传到 Github 库,这里我将展示一些我认为对了解数据集质量特别有用的图。
本示例数据由 10 份标有串联质谱标签(TMT) 试剂的大肠杆菌样本组成,是图林和安德森【2】最近一项研究的一部分。MS 文件在项目 PXD007647 中公开,可从 PRIDE 档案中获得;我已经下载了原始文件,并使用 PD 2.4 和工作流中的频谱导出器节点对其进行了重新处理。激活所述节点后,输出由一堆制表符分隔的文本文件组成:
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_QuanSpectra.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_SpecializedTraces.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_Proteins.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_PeptideGroups.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_MSMSSpectrumInfo.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_PSMs.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_ResultStatistics.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_ProteinGroups.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_InputFiles.txt
/PD_Out/PXD007647_Reproc_TMT-set-2_8fracs_PrSMs.txt
让我们看看所选的收藏夹,按照在笔记本中出现的顺序(即任意顺序)。
文件 MSMSSpectrumInfo
研究中的标记批次已被分成几个部分,在 MS 上对每个部分进行分析,形成一个单独的文件。有趣的是检查分数是否正常,例如,查看每分钟采集多少碎片光谱:

作者形象
但可能更重要的是每分钟的识别数量。不规则的分布和缺乏标识可能表明,除其他选择外,需要修改分馏方案。在这个项目中,情况相当不错,没有一个文件在很大程度上没有标识,尽管对于某些人来说,配置文件看起来有点扭曲:

作者形象
文件全光谱
由于这是一项定量研究,我肯定想检查正常化前后 quan 通道中的值分布(在 PD 中进行)。我们希望看到标准化的通道排列在一个好看且统一的范围内:

作者形象
使用 SN 值的平方根而不是 log 值有助于保持零值,从而更全面地了解强度分布。该数据集没有太多零强度光谱,中位强度似乎在 100 左右,这是很高的。同时,在 y- 轴上的刻度显示许多高强度光谱没有指定的肽 id(可以选择“sharey=True”来同等地缩放子图并强调这一点)。

作者形象
文件 PSm
由于通常有成千上万的肽谱匹配(PSM ),当试图表示点的密度时,使用六邻体蛋白图可能是一个好主意,参见下面的质量误差图示例。我们可以用非常小且高度透明的单个点来绘制散点图,但是六边形的面元非常清楚地代表了分布。在这个项目中,质量准确度符合要求,集中在百万分之五(ppm)以内:

作者图片
文件肽组
在研究同量异位数据集时,我经常检查每种蛋白质中肽定量值的相对标准偏差(RSD ):
在最简单的情况下,我们期望来自蛋白质的肽重复该蛋白质的定量特征。数据集中大多数蛋白质内肽的高变异系数可能是低信号强度(因此,高相对噪声水平)的证据。在我们的例子中,不同样品的平均值和中值 RSD 在 8%和 19%之间,这是相当合理的:

作者图片
半胱氨酸衍生可以影响蛋白质的结构,并影响最终数据集中一些肽的量。如果出现问题,修饰的半胱氨酸肽的相对水平可能较低(对数比<< 0) on a global scale for the affected samples. One of the ways to express that is a clustered heatmap, which is conveniently available via seaborn 库。在我们的案例中,不同的肽具有不同的丰度分布,但是没有样品在整个样品的规模上具有低丰度的含半胱氨酸的肽:

作者图片
文件蛋白质
古老的主成分分析(PCA)也值得一看。它可以帮助发现异常样本,并检查样本组是否如预期的那样(我还没有为这个项目提取这些信息)。让我们绘制两个主要的主成分,稍微修改默认的 matplotlib 散点图,并将解释方差的百分比添加到轴标签:

作者图片
摘要
这篇文章介绍了我用来检查蛋白质组发现者的同量异位素标记质谱蛋白质组数据质量的 Jupyter 笔记本。代码和示例数据可以在的 Github 库中找到。
参考
[1] N .劳尼亚尔和 J. R .耶茨,三。鸟枪法蛋白质组学中基于同量异位标记的相对定量 (2014),蛋白质组学研究杂志,13,12,5293–5309。开放访问。
[2] E .图林和 D.I .安德森。PBP1B 和 LpoB 在 cysB 突变株中的上调赋予了大肠杆菌 (2019),抗微生物药。化学药剂。,63,10,e 00612–19。开放访问。
在解释预测模型以寻求因果洞察力时要小心
原文:https://towardsdatascience.com/be-careful-when-interpreting-predictive-models-in-search-of-causal-insights-e68626e664b6?source=collection_archive---------1-----------------------
思想和理论
对试图从现代预测机器学习模型中提取因果洞察力的陷阱进行了仔细的探索。

斯科特·伦德伯格/伊尔克切利克-伊斯托克
与来自微软的 Eleanor Dillon、Jacob LaRiviere、Jonathan Roth 和 Vasilis Syrgkanis 关于因果关系和可解释机器学习的联合文章。
像 XGBoost 这样的预测性机器学习模型在与 SHAP 这样的可解释性工具搭配时变得更加强大。这些工具可识别输入要素和预测结果之间最具信息性的关系,这对于解释模型的作用、获得利益相关方的认可以及诊断潜在问题非常有用。很容易将这种分析向前推进一步,并假设解释工具也可以识别决策者如果想要在未来改变结果应该操纵什么特征。然而,在这篇文章中,我们讨论了使用预测模型来指导这种政策选择经常会产生误导。
原因与相关和因果的根本区别有关。SHAP 将预测性 ML 模型获得的相关性透明化。但是,让相关性变得透明并不能让它们成为因果关系!所有的预测模型都隐含地假设每个人在未来都将保持同样的行为方式,因此相关模式将保持不变。为了理解如果有人开始表现不同会发生什么,我们需要建立因果模型,这需要做出假设并使用因果分析工具。
订户保留示例
假设我们的任务是构建一个模型来预测客户是否会续订产品。让我们假设,经过一番挖掘,我们设法获得了对预测客户流失很重要的八个特征:客户折扣、广告支出、客户每月使用量、上次升级、客户报告的错误、与客户的互动、与客户的销售电话以及宏观经济活动。然后,我们使用这些功能来训练一个基本的 XGBoost 模型,以预测客户是否会在订阅到期时续订:
X, y = user_retention_dataset()
model = fit_xgboost(X, y)
一旦我们有了 XGBoost 客户保持模型,我们就可以开始探索它从像 SHAP 这样的可解释性工具中学到了什么。我们从绘制模型中每个特征的全局重要性开始:
explainer = shap.Explainer(model)
shap_values = explainer(X)clust = shap.utils.hclust(X, y, linkage="single")
shap.plots.bar(shap_values, clustering=clust, clustering_cutoff=1)

该条形图显示,提供的折扣、广告支出和报告的错误数量是驱动模型预测客户保留率的三大因素(它还包括我们稍后将使用的功能冗余聚类)。这很有趣,乍看起来很合理。
然而,当我们更深入地研究改变每个特征的值如何影响模型的预测时,我们发现了一些不直观的模式。SHAP 散点图显示了更改特性值如何影响模型对更新概率的预测。如果蓝点遵循递增模式,这意味着特征越大,模型的预测更新概率越高。
shap.plots.scatter(shap_values)

预测任务与因果任务
散点图显示了一些令人惊讶的发现:
- 报错多的用户更有可能续费!
- 折扣较大的用户不太可能续约!
我们反复检查我们的代码和数据管道以排除错误,然后与一些业务合作伙伴交流,他们给出了直观的解释:
- 重视产品的高使用率用户更有可能报告错误并更新他们的订阅。
- 销售人员倾向于给他们认为对产品不太感兴趣的客户高折扣,这些客户的流失率更高。
模型中这些起初与直觉相反的关系是个问题吗?那取决于我们的目标是什么!
我们这个模型的最初目标是预测客户保持率,这对于像为财务规划估计未来收入这样的项目很有用。由于用户报告的错误越多,更新的可能性就越大,在模型中捕捉这种关系有助于预测。只要我们的模型具有良好的样本外拟合,我们就应该能够为金融提供良好的预测,因此不应该担心模型中这种关系的方向。
这是一类称为预测任务的任务的例子。在预测任务中,目标是在给定一组特征X的情况下预测结果Y(例如更新)。预测练习的一个关键组成部分是,我们只关心预测model(X)在类似于我们的训练集的数据分布中接近Y。X和Y之间的简单关联有助于这类预测。
然而,假设第二个团队选择了我们的预测模型,新的目标是确定我们公司可以采取什么行动来留住更多的客户。这个团队非常关心每个X特性如何与Y相关联,不仅仅是在我们的培训分布中,还包括世界变化时产生的反事实场景。在这种用例中,识别变量之间的稳定相关性已经不够了;这个团队想知道操作特征X是否会导致Y的变化。想象一下当你告诉工程主管你想让他引入新的 bug 来增加客户更新时他的表情!
这是一类叫做因果任务的任务的例子。在因果任务中,我们想知道改变世界的一个方面X(例如报告的错误)如何影响结果Y(更新)。在这种情况下,关键是要知道改变X是否会导致Y增加,或者数据中的关系是否仅仅是相关的。
估计因果效应的挑战
理解因果关系的一个有用工具是写下我们感兴趣的数据生成过程的因果图。我们的示例中的因果图说明了为什么我们的 XGBoost 客户保留模型获得的稳健预测关系不同于团队感兴趣的因果关系,该团队希望计划干预以增加保留。这个图只是真实数据生成机制的总结(可以在本文的笔记本版本中找到)。实心椭圆表示我们观察到的特征,而虚线椭圆表示我们不测量的隐藏特征。每一个特征都是一个带有箭头的所有特征的函数,外加一些随机效果。
在我们的例子中,我们知道因果图,因为我们模拟数据。在实践中,真正的因果图是未知的,但是我们可以使用关于世界如何工作的上下文特定的领域知识来推断哪些关系可以或不可以存在。

在这个图表中有许多关系,但是第一个重要的关注点是我们可以测量的一些特征受到不可测量的混杂特征的影响,比如产品需求和面临的缺陷。例如,报告更多错误的用户会遇到更多的错误,因为他们使用产品的次数越多,他们也更有可能报告这些错误,因为他们更需要产品。产品需求对更新有直接的因果影响。因为我们不能直接测量产品需求,我们最终在预测模型中捕捉到的缺陷报告和更新之间的相关性结合了所面临的缺陷的小的负面直接影响和来自产品需求的大的正面混杂影响。下图描绘了我们示例中的 SHAP 值与每个特征的真实因果关系(由于我们生成了数据,所以在此示例中是已知的)。

预测模型捕捉了报告的错误对保留的总体积极影响(如 SHAP 所示),即使报告错误的因果影响为零,而发现错误的影响是负面的。
我们在折扣方面也看到了类似的问题,这也是由未被观察到的客户对产品的需求所驱动的。我们的预测模型发现折扣和保留率之间存在负相关关系,这是由这种与未观察到的特征(产品需求)的相关性驱动的,尽管实际上折扣对续订有很小的正面因果影响!换句话说,如果两个客户有相同的产品需求,并且在其他方面相似,那么折扣较大的客户更有可能续订。
当我们开始将预测模型解释为因果关系时,这个图还揭示了第二个更隐蔽的问题。请注意,广告支出也有类似的问题——它对保留没有因果关系(黑线是平的),但预测模型显示出积极的影响!
在这种情况下,广告支出只受上次升级和每月使用量的驱动,因此我们不存在未观察到的混淆问题,而是存在观察到的混淆问题。在广告花费和影响广告花费的特征之间存在统计冗余。当我们通过几个特征获得相同的信息时,预测模型可以使用这些特征中的任何一个进行预测,即使它们并不都是因果关系。虽然广告支出对更新本身没有因果关系,但它与推动更新的几个特征密切相关。我们的正则化模型将广告支出确定为一个有用的预测因素,因为它总结了多个因果驱动因素(因此导致了一个更稀疏的模型),但如果我们开始将它解释为因果效应,那就变得严重误导了。
我们现在将依次处理我们例子中的每一个部分,以说明预测模型何时能够准确地测量因果关系,何时不能。我们还将介绍一些因果工具,这些工具有时可以在预测模型失败的情况下估计因果影响。
当预测模型可以回答因果问题时
让我们从例子中的成功开始。请注意,我们的预测模型很好地捕捉了经济特征的真实因果效应(更好的经济对保留有积极影响)。那么,我们什么时候才能期待预测模型捕捉到真正的因果效应呢?
允许 XGBoost 获得良好的经济因果效应估计的重要因素是特性的强独立分量(在此模拟中);它对记忆的预测能力与任何其他可测量的特征或任何不可测量的混杂因素相比并没有很大的冗余。因此,它不受未测量的混杂因素或特征冗余的影响。

经济性与其他测量特征无关。
由于我们已经在 SHAP 条形图的右侧添加了聚类,我们可以将数据的冗余结构视为一个树状图。当特征在树状图的底部(左侧)合并在一起时,这意味着这些特征包含的关于结果(更新)的信息是非常多余的,并且模型可能已经使用了任一特征。当特征在树状图的顶部(右侧)合并在一起时,意味着它们包含的关于结果的信息是相互独立的。
通过注意到经济直到聚类树状图的最顶端才与任何其他特征合并,我们可以看到经济独立于所有其他测量的特征。这告诉我们,经济不会遭受观察混淆。但是,要相信经济效应是因果关系,我们还需要检查未观察到的混淆。检查不可测量的混杂因素更加困难,并且需要使用领域知识(在上面的例子中由业务伙伴提供)。
对于提供因果结果的经典预测 ML 模型,特征不仅需要独立于模型中的其他特征,还需要独立于未观察到的混杂因素。很难找到感兴趣的驱动因素自然表现出这种独立性的例子,但当我们的数据包含一些实验时,我们经常可以找到独立特征的例子。
当预测模型不能回答因果问题,但因果推断方法可以帮助
在大多数真实世界的数据集中,特征不是独立的和无根据的,因此标准预测模型将不会了解真正的因果关系。因此,用 SHAP 解释它们不会揭示因果关系。但是并不是一切都完了,有时我们可以使用观察因果推理的工具来解决或者至少最小化这个问题。
观察混杂
因果推理有帮助的第一种情况是观察混淆。当有另一个特征对原始特征和我们预测的结果都有因果影响时,这个特征就是“混杂的”。如果我们可以测量另一个特征,它被称为观察混杂。

每月使用和最后升级的广告花费是非常多余的。
我们场景中的一个例子是广告支出特性。尽管广告支出对保留没有直接的因果影响,但它与上次升级和每月使用功能相关,而这些确实会推动保留。我们的预测模型将广告支出确定为保留率的最佳单一预测指标之一,因为它通过相关性捕捉了如此多的真正因果驱动因素。XGBoost 强加了正则化,这是一种奇特的说法,它试图选择仍然预测良好的最简单的可能模型。如果使用一个特征而不是三个特征也能预测得一样好,它会倾向于这样做以避免过度拟合。但这意味着,如果广告支出与上次升级和每月使用量高度相关,XGBoost 可能会使用广告支出而不是因果特征!XGBoost(或任何其他具有正则化的机器学习模型)的这一属性对于生成未来保持力的鲁棒预测非常有用,但对于理解如果我们想要增加保持力,我们应该操纵哪些特征却不是很好。
这突出了为每个问题匹配正确的建模工具的重要性。与错误报告的例子不同,增加广告支出会增加用户保留率的结论在直觉上没有错。如果没有适当关注我们的预测模型是什么,而不是什么,我们可能会很容易地继续这一发现,并在增加广告支出后才知道我们的错误,没有得到我们预期的更新结果。
观察因果推理
对广告支出来说,好消息是我们可以衡量所有可能混淆它的特征(在上面的因果图中,这些特征带有指向广告支出的箭头)。因此,这是一个观察到混淆的例子,我们应该能够仅使用我们已经收集的数据来解开相关模式;我们只需要从观察因果推断中使用正确的工具。这些工具允许我们指定哪些特征会混淆广告支出,然后针对这些特征进行调整,以获得广告支出对产品更新的因果影响的无根据估计。
一个特别灵活的观察因果推理工具是双/去偏机器学习。它使用您想要的任何机器学习模型,首先去发现感兴趣的特征(即广告支出),然后估计改变该特征的平均因果效应(即因果效应的平均斜率)。
双 ML 的工作方式如下:
- 使用一组可能的混杂因素(即,不是由广告花费引起的任何特征)训练模型来预测感兴趣的特征(即,广告花费)。
- 使用同一组可能的混杂因素训练一个模型来预测结果(即确实更新)。
- 使用感兴趣的因果特征的残差变异来训练模型以预测结果的残差变异(减去我们的预测后剩余的变异)。
直觉是,如果广告支出导致更新,那么不能被其他混杂特征预测的广告支出部分应该与不能被其他混杂特征预测的更新部分相关。换句话说,double ML 假设存在影响广告花费的独立(未观察到的)噪声特征(因为广告花费并不完全由其他特征决定),因此我们可以估算该独立噪声特征的值,然后在该独立特征上训练模型以预测输出。
虽然我们可以手动完成所有双 ML 步骤,但使用像 econML 或 causaml 这样的因果推理包更容易。这里我们用的是 econML 的 LinearDML 模型(详见笔记本)。这将返回一个 P 值,表明该治疗是否具有非零因果效应,并且在我们的场景中运行良好,正确地识别出没有证据表明广告支出对更新有因果效应(P 值= 0.85):

请记住,双最大似然(或任何其他观察因果推断方法)只有在您可以测量和识别您想要估计因果效应的特征的所有可能混杂因素时才有效。这里我们知道因果图,可以看到每月使用量和上次升级是我们需要控制的两个直接混杂因素。但是,如果我们不知道因果图,我们仍然可以查看 SHAP 条形图中的冗余,并看到每月使用量和上次升级是最冗余的功能,因此是控制的良好候选项(折扣和报告的错误也是如此)。
非混淆冗余
因果推理有帮助的第二种情况是非混淆冗余。当我们想要因果效应的特征驱动模型中包含的另一个特征,或者被另一个特征驱动,但是该另一个特征不是我们感兴趣的特征的混杂因素时,就会发生这种情况。

销售拜访功能就是一个例子。销售电话会直接影响客户保持,但也会通过互动间接影响客户保持。当我们在模型中同时包含交互和销售拜访功能时,这两种功能共享的因果关系被迫在它们之间展开。我们可以在上面的 SHAP 散点图中看到这一点,它显示了 XGBoost 如何低估了销售电话的真正因果影响,因为大部分影响都放在了交互功能上。
非混杂冗余原则上可以通过去除模型中的冗余变量来固定(见笔记本)。例如,如果我们将互动从模型中移除,那么我们将获得销售电话对续订概率的全部影响。这种移除对于双 ML 也很重要,因为如果控制由感兴趣的特征引起的下游特征,双 ML 将不能捕捉间接因果效应。在这种情况下,double ML 将只测量不通过其他特征的“直接”效果。然而,双 ML 对于控制上游非混杂冗余(冗余特征引起感兴趣特征)是稳健的,尽管这将降低您检测真实效应的统计能力。
不幸的是,我们通常不知道真正的因果图,因此很难知道另一个特征何时对我们感兴趣的特征是冗余的,因为观察到了混杂与非混杂冗余。如果是因为混淆,那么我们应该使用像 double ML 这样的方法来控制该特征,而如果是下游结果,那么如果我们想要完全的因果影响而不仅仅是直接影响,我们应该从我们的模型中删除该特征。控制一个我们不应该控制的特征往往会隐藏或分割因果关系,而未能控制一个我们应该控制的特征往往会推断出不存在的因果关系。当你不确定的时候,这通常使控制一个特性成为更安全的选择。
当预测模型和非发现方法都不能回答因果问题时
双最大似然法(或任何其他假设未发现的因果推断方法)仅在您可以测量和识别您想要估计因果效应的特征的所有可能混杂因素时才有效。如果你不能测量所有的混杂因素,那么你就处于最困难的情况:未被观察到的混杂因素。

折扣和 bug 报告功能都受到未观察到的混淆的影响,因为并非所有重要的变量(例如,产品需求和面临的 bug)都在数据中进行了测量。尽管这两个功能相对独立于模型中的所有其他功能,但仍有一些重要的驱动因素无法衡量。在这种情况下,需要观察混杂因素的预测模型和因果模型(如 double ML)都将失败。这就是为什么 double ML 估计了折扣特征的一个很大的负因果效应,即使在控制所有其他观察到的特征时也是如此:

除非能够测量先前未测量的特征(或与其相关的特征),否则很难在未观察到的混杂因素中找到因果关系。在这些情况下,识别能够为政策提供信息的因果效应的唯一方法是创建或利用一些随机化,打破感兴趣的特征和不可测量的混杂因素之间的相关性。在这种情况下,随机实验仍然是寻找因果关系的黄金标准。
基于工具变量、差异中的差异或回归不连续性原理的专门因果工具有时可以利用部分随机化,即使在不可能进行完整实验的情况下。例如,在我们无法随机指定治疗方法的情况下,可以使用工具变量技术来确定因果关系,但我们可以随机推动一些客户接受治疗,如发送电子邮件鼓励他们探索新产品功能。当新的治疗方法在不同组间交错引入时,差异中的差异方法可能是有帮助的。最后,当治疗模式表现出明显的截止点时,回归不连续性方法是一个很好的选择(例如,基于特定的、可测量的特征(如每月收入超过 5000 美元)的治疗资格)。
摘要
像 XGBoost 或 LightGBM 这样灵活的预测模型是解决预测问题的强大工具。然而,它们不是固有的因果模型,因此用 SHAP 解释它们将无法准确回答许多常见情况下的因果问题。除非模型中的特征是实验变化的结果,否则在不考虑混杂因素的情况下将 SHAP 应用于预测模型通常不是一个合适的工具来测量用于为政策提供信息的因果影响。SHAP 和其他可解释性工具可以用于因果推理,SHAP 被集成到许多因果推理包中,但那些用例本质上是明确的因果关系。为此,使用我们将为预测问题收集的相同数据,并使用像 double ML 这样专门设计来返回因果影响的因果推断方法,通常是为政策提供信息的好方法。在其他情况下,只有实验或其他随机来源才能真正回答如果的问题。因果推断总是需要我们做出重要的假设。本文的主要观点是,我们通过将正常的预测模型解释为因果关系而做出的假设通常是不现实的。
由决策驱动,而不是数据驱动
原文:https://towardsdatascience.com/be-decision-driven-not-data-driven-d12b9b7edd8b?source=collection_archive---------24-----------------------
在你的合作决策过程中需要考虑的七点

杰瑞米·帕金斯上的 Unsplash
科技媒体痴迷于数据。但是在对企业数据素养进行了八年的测量后,只有 24%的公司报告已经达到了数据驱动的涅槃。这比去年少了家公司。
也许数据驱动是错误的目标。
研究者 Bart de Langhe 和 Stefano Puntoni 是这样认为的。他们主张变成决策驱动,而不是数据驱动。
这种区别似乎很小,但事实并非如此。这就像共产主义者对资本家,民主党人对共和党人,或者红袜队对扬基队球迷。
决策文化并不像说波士顿是一个比纽约更好的体育城市那样一成不变。数据科学既是创造性的,也是技术性的,就像盖房子一样——建筑师、设计师、建筑商和管道工必须一起工作。起初,架构师领导;在施工阶段,建筑商主导,在完工阶段,设计主导;房主是最终的决策者。
决策驱动的思维在七个方面不同于数据驱动的方法:
- 从问题开始,不是数据。决策驱动思维花更多时间设计问题。测题两遍,切数据一遍!
- 决策者领导项目,而不是数据科学家。房主设定基调,而不是建筑商。
- 思考未知多于已知。在零售业,一个常见的数据驱动项目找出如何优化忠诚度计划;决策驱动型思维首先探究是什么让客户犹豫不决。
- 先看宽,再潜深。数据驱动的团队经常一头扎进他们已经拥有的数据池。Puntoni 和 de Lange 建议决策优先团队“先宽后窄”
- 构建新的数据盒子。当你开始提问时,你会很快发现你丢失了数据。以决策为中心的团队可以更快地确定对新调查、模拟或第三方数据的需求。
- 定位并减少偏差。通过预先接纳更广泛的团队,决策导向的团队往往更加多样化。多样性有助于通过质疑假设来根除偏见。
- 不是后视镜。数据驱动思维从历史数据开始,说明已经发生的事情。虽然过去可能只是序幕,但疫情之前的模式可能不再适用。
巴勃罗·毕加索说:“计算机的问题在于它们所能做的只是提供答案。”他的信息很深刻:不要让技术领先;领导你的技术。由决策驱动,而不是数据驱动。

马克·帕尔默(www.techno-sapien.com)
在谷歌数据流上传送(批量+流)你的数据管道
原文:https://towardsdatascience.com/beam-batch-stream-your-data-pipelines-on-google-dataflow-2e3230bcdc21?source=collection_archive---------23-----------------------
Apache Beam 是批处理和流处理的统一编程模型
为什么需要数据管道?
在 21 世纪,大多数企业依靠可扩展的平台&服务或产品的数据化来保持市场竞争力。随着来自不同来源、具有不同数量、速度和种类的数据激增,企业需要新的数据战略。因此,需要数据管道将所有不同来源的数据整合到一个共同的目的地,以进行快速分析,或者在连接的应用程序和系统之间处理和传输数据。
因此,组织开始根据其业务需求部署批处理或流式管道。
P
批量处理:
- 与有界数据集一起使用。
- 在一段时间内收集一组数据,然后一次性处理。
- 更关心吞吐量而不是延迟。
- 用例:寻找一家银行的忠实客户;折扣后的销售差额等。
流处理:
- 用于未绑定的数据集。
- 数据一生成就被馈送到处理引擎。
- 更关心延迟而不是吞吐量。
- 用例:股市情绪分析;实时检测欺诈交易、物联网设备等。
R 例如,在 Spark 中,rdd/data frame 用于批处理,而您需要为流处理编写数据流。因此,他们需要维护两个不同的流水线以及各自的执行引擎,这不仅增加了总的维护开销,而且将它们与相关的执行引擎锁定在一起。
为了缓解这些挑战,谷歌孵化了一个数据流模型,可以应用于有界和无界数据集,然后将其 SDK 捐赠给 Apache 基金会。
从那时起,贡献者社区培育了它,因此,我们有了" Apache Beam "一个统一的编程模型,它易于使用,对流和批处理工作流进行数据并行处理,最重要的是平台独立性(可移植,支持多个运行程序),以消除任何 API 锁定。
Apache Beam 是批处理&流处理的统一编程模型,抽象层允许用任何语言(Java、Python、Go 等)创建。)并且可以在 Google Cloud Dataflow、Spark、Flink 等任何执行框架上执行。
阿帕奇波束的体系结构;

作者的 Apache Beam 架构
- 使用您选择的编程语言 SDK——Java、Python 或 Go——编写管道。
- Beam / Runner API 将其转换为可由执行引擎使用的语言通用标准。
- Fn API 提供了特定于语言的 SDK 工作器,这些工作器充当嵌入到管道中作为函数规范的 UDF 的 RPC 接口。
- 选定的运行器在底层资源上执行流水线,正确选择运行器是高效执行的关键。
Apache 射束工作流程:

作者的 Apache 工作流
:Pipeline:封装了从开始到结束的数据处理任务,包括读取 I/P 数据、转换和写入 O/P 数据。
PCollection: 波束流水线操作的分布式数据集。它可以是有界的,也可以是无界的。它本质上是不可变的,因此,对 PCollection 的任何转换都会创建一个新的 PCollection。
PTransform: 表示应用于 PCollection 的数据处理操作或转换步骤。
I/O Sink&Sources:Source 和 Sink APIs 提供了将数据读入集合或从集合中写出的函数。
阿帕奇波束能力矩阵;
Apache Beam 的主要优势是它的可移植 API 层,可以跨多种执行引擎或运行程序执行。因为它为不同的赛跑者提供了在技术创新上竞争的公平场所,这些技术创新提供了更好的性能、可靠性、操作管理的简易性等。因此,Apache 发布了一个能力矩阵,将不同跑步者的能力按照其相应的“什么/哪里/何时&如何”问题进行分组:

参考: 阿帕奇波束能力矩阵 来自 Apache.org
在图表中,你可以看到谷歌云数据流运行检查所有主要功能,但这不是我认为谷歌云数据流是推荐选择的唯一原因。
那么,为什么谷歌云数据流?
首先,谷歌对开源及其社区的承诺无与伦比。自 2016 年以来,谷歌已经为 15,000 多个开源项目做出了贡献,通过云数据流,谷歌甚至减轻了其设置、维护和扩展所需的开销,以高效执行复杂的大规模连续作业,方法是提供:
- 完全托管的无服务器服务。
- 自动优化管道,如使用的工人数量,将数据流拆分到关键空间,并并行处理它们。
- Liquid Sharding(动态工作再平衡)可根据作业管道的需求动态调整工作人员的数量。
- 用于批处理的低价灵活资源调度(FlexRS ),保证在 6 小时的窗口内执行。
- 内置的实时人工智能功能允许构建智能解决方案,如预测分析、异常检测等。
- 开箱即用集成到谷歌云资源的其余部分,实现无缝连接。

作者的 Google Cloud 原生数据源和数据流接收器
结论
在这里,我向您概述了 Apache Beam 编程模型,以及为什么 Google Cloud Dataflow 实际上应该是它的运行者,如果您还在阅读这篇文章,我相信您对探索 Apache Beam 的下一个数据管道非常感兴趣,或者希望在一个统一的、独立于平台的模型中转变现有的管道。所以为什么停止,不久我将发布一个实际的场景及其实现,以便更好地理解。
同时,这里有一些我提到的资源,你也应该浏览一下,以便更深入地理解:
- 阿帕奇光束文档
- 数据流模型
- 阿帕奇波束能力矩阵
- 数据流模板:谷歌提供数据流模板,让你从加速学习开始。
用 Python、熊猫和财务规划打败我的银行
原文:https://towardsdatascience.com/beating-monzo-plus-with-python-and-pandas-83cb066c1b95?source=collection_archive---------43-----------------------
我如何用编程超越英国银行的新星

图片来自 StockSnap
大约两年前,我开始在 Monzo 银行工作,当时我发现这家完全在线的银行非常有趣——看不到任何高街位置。即使是现在,我也对这些纯数字银行取得的成就印象深刻,它们拥有储蓄罐和交易分类等有用的功能。
老实说,直到最近,我还不太在意 Monzo 根据供应商对交易进行自动分类的能力,但自从开始大学生活以来,管理财务对我来说变得重要多了。我决定仔细看看这个特性,虽然它很酷,但我对选项的缺乏感到非常失望。

作者图片
不要误会我的意思,Monzo 的类别选择是好的,但明显缺乏一些重要的选项,如“租赁”或“定期订阅”或类似的。当然,这两项实际上都可以归入“账单”项下,但其他像洗衣服这样乞讨的学生必须支付的费用呢?当然没有这个类别,而“费用”可以是任何东西。
我感到有点挫败,于是就建立了一个电子表格,每周花一个小时左右查看我的交易,填写表格,合计我每个月在不同东西上花了多少钱。我最终为我的三个主要账户——我的 Monzo 账户、我的学生银行账户和我的帮助购买 ISA——配置了电子表格,并设置了一些 Excel 公式,如果我向另一个账户转账,就会自动从一个账户中扣除,等等。

作者图片
这在一段时间内运行良好,虽然我仍然对 Monzo 没有默认提供类似的功能感到不高兴,但我还是继续使用该银行。
然而,2020 年 7 月,当 Monzo 为他们的银行账户引入一个新功能时,一切都改变了,这个功能可以同时解决我的问题并产生一个新问题,而且是一个相当大的问题。
你看,2020 年 7 月 15 日,Monzo 发布了 Monzo Plus,这是一种新型账户,提供了许多好处,包括虚拟卡、更多利息,你猜对了,还有自定义类别。
当然,Monzo Plus 的问题在于它是一项付费服务。这不是很多——一个月只有 5 英镑——但是作为一个破产的大学本科生,支付这个不是一个选择。我拒绝再保持沉默了。
在一阵绝对的愤怒中,我冲向我的电脑,设置了一个 virtualenv,打开 PyCharm,开始愤怒地敲键盘。不久后,我有了一个基本的程序,它可以处理我从 Monzo 应用程序下载的 CSV 交易,让我对它们进行分类,然后,如果我愿意,可以存储一个供应商名称分类图,这样我就不必每次都处理每笔交易。然后,我使用 openpyxl 模块将每个类别的总数插入到我已经在使用的电子表格中。
这很棒,随着时间的推移,我对它进行了更新,以存储任何成功解析的事务的事务 ID,这样,在多次使用该软件时,它就不会对同一事务进行两次计数。
实际上,该程序所做的只是将交易数据的 CSV 读入 pandas 数据帧,询问用户交易属于哪一类,将其插入数据帧,并对所有数据进行合计。自然,有很多用户输入检查和后退的废话,但这是它的一般要点。
然而,故事并没有就此结束。有一天,我和我的一个朋友谈到了这个问题,他也在 Monzo 银行工作,他提到他也会发现这样一个程序很有用,但需要它处理不同的类别,并将数据插入到电子表格的不同行中。
因此,我重写了部分内容,从 TXT 文件中提取自定义类别名称和电子表格行,并想“如果他会觉得有用,也许其他人也会觉得有用。”
我最终把这个项目上传到了 GitHub,并扩展了对所有银行的支持,增加了一些功能来改善用户体验。如果您有兴趣检查这个项目或者自己使用它,您可以在 GitHub 上找到它:
https://github.com/isaacharrisholt/vorn-finance-tracker
感谢阅读到底!如果你喜欢这篇文章或者觉得它有用,请告诉我。非常感谢任何反馈!
用 dtreeviz 实现漂亮的决策树可视化
原文:https://towardsdatascience.com/beautiful-decision-tree-visualizations-with-dtreeviz-af1a66c1c180?source=collection_archive---------9-----------------------
入门
改进绘制决策树的旧方法,永不回头!

卢克·理查森在 Unsplash 上拍摄的照片
决策树是一类非常重要的机器学习模型,也是许多更高级算法的构建模块,如随机森林或著名的 XGBoost。这些树也是基线模型的良好起点,我们随后会尝试用更复杂的算法对其进行改进。
决策树的最大优势之一是其可解释性——在拟合模型后,它实际上是一组可用于预测目标变量的规则。这也是为什么绘制规则并展示给利益相关者很容易,因此他们可以很容易地理解模型的底层逻辑。当然,前提是树不要太深。
结合使用scikit-learn和matplotlib,可视化决策树会非常简单。然而,有一个叫做dtreeviz的不错的库,它带来了更多的东西,并且创建了不仅更漂亮而且传达了更多关于决策过程的信息的可视化。
在本文中,我将首先展示绘制决策树的“老方法”,然后介绍使用dtreeviz的改进方法。
设置
和往常一样,我们需要从导入所需的库开始。
然后,我们从scikit-learn加载虹膜数据集。我们还将回顾一个回归示例,但我们稍后将加载波士顿住房数据集。
“老方法”
下一步包括创建训练/测试集,并使决策树分类器适合 Iris 数据集。在本文中,我们只关注可视化决策树。因此,我们没有注意拟合模型或找到一组好的超参数(有很多关于这些主题的文章)。我们唯一要“调整”的是树的最大深度——我们将其限制为 3,这样树仍然可以适应图像并保持可读性。
现在我们有了一个合适的决策树模型,我们可以开始可视化该树。我们从最简单的方法开始——使用scikit-learn中的plot_tree函数。
tree.plot_tree(clf);

作者图片
好吧,对于一句俏皮话来说还不错。但是可读性不是很好,比如没有特性名(只有它们的列索引)或者类标签。通过运行下面的代码片段,我们可以很容易地改进这一点。

作者图片
好多了!现在,我们可以很容易地解释决策树。也可以使用graphviz库来可视化决策树,但是,结果非常相似,具有与上图相同的一组元素。这就是为什么我们会在这里跳过它,但你可以在 GitHub 上的笔记本中找到实现。
dtreeviz 正在运行
看过绘制决策树的老方法后,让我们直接进入dtreeviz方法。
代码片段基本上是不言自明的,所以我们可以继续看结果。首先,让我们花点时间来承认这是一个多么大的改进,特别是考虑到函数调用非常相似。

作者图片
让我们一步一步地检查情节。在每个结点上,我们可以看到用于分割观测值的要素的堆积直方图,并按类进行着色。通过这种方式,我们可以看到各个类是如何被每次拆分所分隔的。值在 x 轴的小三角形是分割点。在第一个直方图中,我们可以清楚地看到 setosa 类的所有观测值的花瓣长度都小于 2.45 cm。
树的右边分支表示选择大于或等于分裂值的值,而左边分支表示选择小于分裂值的值。叶节点表示为饼图,它显示叶中的观察值属于哪个类。通过这种方式,我们很容易看出哪个类占多数,因此模型的预测也是如此。
在这张图上我们没有看到的一点是每个节点的基尼系数。在我看来,直方图提供了更多关于分割的直觉,系数的值可能与利益相关者的演示无关。
注意:我们也可以为测试集创建一个类似的可视化,我们只需要在调用函数时替换x_data和y_data参数。
如果您不喜欢直方图,并且想要简化图形,您可以指定fancy=False来接收下面的简化图形。

作者图片
dtreeviz的另一个方便的特性是提高了模型的可解释性,它突出显示了图形上特定观察的路径。这样,我们可以清楚地看到哪些特征有助于分类预测。
使用下面的片段,我们突出了测试集的第一次观察的路径。
该图与前一个非常相似,但是,橙色突出显示清楚地显示了观察遵循的路径。此外,我们可以在每个直方图上看到橙色三角形。它表示给定特征的指示观察值。在最后,我们看到该观察的所有特性的值,用于决策的特性以橙色突出显示。在这种情况下,仅使用两个特征来预测观察值属于云芝类。

作者图片
提示:我们还可以通过设置orientation=”LR”将绘图的方向从自上而下改为从左向右。我们没有在本文中展示它,因为对于屏幕较窄的设备来说,图表不会被很好地缩放。
最后,我们可以用简单的英语打印出用于该观察预测的决策。为此,我们运行以下命令。
这样,我们可以清楚地看到这个观察满足的条件。
回归示例
我们已经介绍了一个分类示例,它展示了这个库的大多数有趣的功能。但是为了完整起见,我们还看了一个回归问题的例子,以显示这些图是如何不同的。我们使用另一个流行的数据集——波士顿住房数据集。这是一个问题,我们使用一组不同的区域来预测波士顿特定区域内的中值房价。
代码感觉已经差不多了。唯一的变化是我们增加了show_node_labels = True。对于较大的决策树来说,这尤其方便。因此,在与一组人讨论情节时,很容易通过节点的编号来指出我们正在讨论的是哪一部分。

作者图片
让我们深入分类树和回归树之间的差异。这一次,我们不是查看直方图,而是检查用于分割的特征与目标的散点图。在这些散点图上,我们看到一些虚线。他们的解释如下:
- 水平线是决策节点中左右桶的目标平均值。
- 垂直线是分割点。这与黑色三角形所代表的信息完全相同,但是,它使得比较水平线更容易->更容易将两边分开。
在叶节点中,虚线显示叶内目标的平均值,这也是模型的预测。
我们已经展示了我们可以突出某个观察的决策路径。我们可以更进一步,只绘制用于预测的节点。我们通过指定show_just_path=True来做到这一点。下图仅显示了从上面的树中选择的节点。

作者图片
结论
在本文中,我展示了如何使用dtreeviz库来创建优雅且有洞察力的决策树可视化。在使用它一段时间后,我肯定会继续使用它作为可视化决策树的首选工具。我确实相信,使用这个库创建的图对于不每天使用 ML 的人来说更容易理解,并且可以帮助向涉众传达模型的逻辑。
另外值得一提的是,dtreeviz支持 XGBoost 和 Spark MLlib 树的一些可视化。
您可以在我的 GitHub 上找到本文使用的代码。一如既往,我们欢迎任何建设性的反馈。你可以在推特上或者评论里联系我。
觉得这篇文章有趣?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用这个链接成为会员,你将支持我,而不需要额外的费用。提前感谢,再见!
如果您喜欢这篇文章,您可能还会对以下内容感兴趣:
参考
- https://github.com/parrt/dtreeviz
- https://explained.ai/decision-tree-viz/index.html
用 Python 制作的美丽山脊图
原文:https://towardsdatascience.com/beautiful-ridge-maps-with-python-640906a30e10?source=collection_archive---------32-----------------------
如何用 Python 快速绘制酷炫的立面图

这种视觉效果是海拔图和山脊图巧妙结合的结果。
它使用多条水平线来表示地形的高程,就像跟踪各个纬度的峰值,一条在另一条之上。

结果是一个看起来非常酷的地图,它塑造了特定区域的山脉和不同的海拔高度。
我不确定这种可视化的实际应用,除了为一份报告制作一个好看的首页或让区域分析 PowerPoint 发光。但它们是一些非常吸引人的地图,值得一些关注。
山脊图
为了快速创建我们的可视化,我们可以使用 ridge_map 。
该软件包使用来自【SRTM】、Matplotlib 的高程数据来绘制图表,甚至用 Scykit 和 Numpy 检测湖泊。
安装后,我们可以通过导入 ridge_map,运行 plot_map,不需要任何参数来测试。我们应该弄一张白山的地图。
from ridge_map import RidgeMapRidgeMap().plot_map()

酷毙了。现在让我们尝试一个不同的位置。
自定义地图
首先,我们需要一些坐标。我用谷歌地图找到了它们。你也可以将地图显示为“地形”,这样你就可以知道最终的可视化效果会是什么样子。
一旦你找到你想要的,你可以在地图上点击鼠标右键来获得坐标。


山脊图将需要两组坐标,一组用于左下角,另一组用于右上角。
(-123.2510,49.6902,-122.1194,50.3446)
(左下 Long,左下 Lat,右上 Long,右上 Lat)
Google 的坐标顺序相反,Lat/ Long,所以我们需要反过来。
# coordinates
bl = [49.6902343443372, -123.25105812920076][::-1]
tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)
values = rm.get_elevation_data()
rm.plot_map(values=rm.preprocess(values=values), label=None)

我们首先定义 RidgeMap 并将坐标传递给构造函数。
获取高程数据
然后,我们使用 get_elevation_data 检索一个带有我们的规范的 NumPy 数组。这里我们有三个方便的论据。让我们试试它们。
# coordinates
bl = [49.6902343443372, -123.25105812920076][::-1]
tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)
values = rm.get_elevation_data(**num_lines=160,
elevation_pts=800,
viewpoint="south"**)
rm.plot_map(values=rm.preprocess(values=values), label=None)

那更好!
get_elevation_data 方法允许我们选择视点以及可视化的详细程度。
预处理
预处理方法将使我们能够配置高程比以夸大丘陵和山脉,并配置水检测。其中water_ntile删除基于海拔百分比的数据,而lake_flatness删除三个方块内的变化。
# coordinates
bl = [49.6902343443372, -123.25105812920076][::-1]
tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data(num_lines=160,
elevation_pts=800,
viewpoint="south")rm.plot_map(values=rm.preprocess(values=values,
**water_ntile=0,
lake_flatness=8,
vertical_ratio=80**),
label=None)

来自 get_elevation_data 和预处理的所有这些参数都是有益的,但有时使用起来很棘手。
绘图地图
对于更加美观的定制,我们有 plot_map 方法。在那里我们可以配置颜色、线宽和标签。
**import seaborn as sb
cmap = sb.light_palette("#69d", as_cmap=True)**# coordinates
bl = [49.6902343443372, -123.25105812920076][::-1]
tr = [50.34462404053542, -122.11945787458642][::-1]rm = RidgeMap(bl + tr)values = rm.get_elevation_data(num_lines=160,
elevation_pts=800,
viewpoint="south")rm.plot_map(values=rm.preprocess(values=values,
water_ntile=0,
lake_flatness=8,
vertical_ratio=80),
** label=None,
line_color=cmap,
kind="gradient",
linewidth=1,
background_color='black',
size_scale=15**)

山脊图允许我们进行大量的定制。对于所有其他的,我们也有 Matplotlib。
Matplotlib
plot_map 方法返回轴,所以我们可以根据自己的需要进行修改。
import seaborn as sb
**import matplotlib.pyplot as plt**cmap = sb.light_palette("#69d", as_cmap=True)# coordinates
bl = [49.6902343443372, -123.25105812920076][::-1]
tr = [50.34462404053542, -122.11945787458642][::-1]
**whistler = [50.11262255339053, -122.96522325554356][::-1]**rm = RidgeMap(bl + tr)# convert annotation coordinates
**whistler_coords = ((whistler[0] - rm.longs[0])/(rm.longs[1] - rm.longs[0]),(whistler[1] - rm.lats[0])/(rm.lats[1] - rm.lats[0]))**values = rm.get_elevation_data(num_lines=160,
elevation_pts=800,
viewpoint="south")**ax =** rm.plot_map(values=rm.preprocess(values=values,
water_ntile=0,
lake_flatness=8,
vertical_ratio=80),
label=None,
line_color=cmap,
kind="gradient",
linewidth=1,
background_color='black',
size_scale=15)**ax.plot(*whistler_coords, '.',
color='white',
transform=ax.transAxes,
zorder=len(values)+10)****ax.text(whistler_coords[0]+0.01,
whistler_coords[1]+0.02,
'Whistler',
fontproperties=rm.font,
size=20,
color="white",
backgroundcolor='black',
transform=ax.transAxes,
verticalalignment="bottom",
zorder=len(values)+10)**

总的来说,根据我的经验,这种可视化需要大量的实验。因为它更具艺术性而非分析性,你需要测试不同的变量,看看会发生什么,直到你找到你喜欢的东西。
尽管我不需要这样的地图,但我从这些可视化中获得了很多乐趣,并将再次使用它们来美化我的演示。
我用山脊图创建了这篇文章中的所有图像。你可以随意使用它们。
感谢阅读。希望你喜欢:)
更多 Python DataViz 教程。
【参考文献:】
https://github.com/ColCarroll/ridge_map;
https://github.com/tkrajina/srtm.py;
带有 Tableau 和 Google Maps API 的简单精美的地图
原文:https://towardsdatascience.com/beautifully-simple-maps-with-tableau-and-the-google-maps-api-6eeb89263c52?source=collection_archive---------21-----------------------
轻松地将任何城市名称转换成可映射的地理位置。

由梅丽莎·施密茨 | 制作的图形在 Tableau Public 上直播
Tableau 有一个内置函数,可以识别主要城市的名称。但是,如果 Tableau 不能自动识别可视化所需的城市,该怎么办呢?
如果只有少数几个城市,手动搜索纬度和经度值并将其添加到数据表中可能会更快。但是除此之外,你肯定想用脚本来节省时间。
这个 Python 脚本是通用的,所以你可以在任何需要地理定位的项目中反复使用它,而不仅仅是上面的 Tableau visual 。
另外,内置的安全性可以防止意外的 API 密钥泄漏。
你需要什么
- 安装了请求、json 和 pandas 库的 python 3
- 您自己的谷歌地图 API 密钥
- 答。带有“城市”列的 csv 文件(参见下面的示例)
- Tableau 桌面(免费试用可用)
在本文中,我将重点关注 Python 脚本和 Tableau 中的地图。关于安装 Python 库和获取 Google Maps API 密钥,网上有很多其他教程,所以如果你需要帮助,我在上面提供了链接。

照片由安德鲁·尼尔在 Unsplash 上拍摄
准备您的数据
对于这个项目,您的输入数据非常简单:一个. csv 文件,其中有一个名为“city”的列,包含您希望绘制地图的所有城市。这里有一个例子,用一个随机城市生成器制作:
Google Maps 地理定位 API 足够灵活,可以识别州和国家的各种文本表示。我特意包括了上面的例子,以表明即使你不使用缩写,这也是可行的。
提示:确保你的。csv 文件没有用
,分隔,否则您可能会遇到由于城市、州对中的,而导致的解析错误。
代码:将城市名称转换成地理位置
首先,我们从导入语句开始:
然后,我们为。csv 文件和您的谷歌地图 API 密钥:
注意:这不是传入此信息的唯一方式,但这是的一种方式,有助于确保您不会意外地通过硬编码或在存储库中留下包含您的 API 密钥的文件而暴露 API 密钥。
接下来,我们将定义一个调用 Google Maps 地理位置 API 的函数,将每个城市转换为地理位置(即纬度和经度元组):
这里面有很多东西,所以让我们稍微分解一下。
- 函数变量:
geo变量是您稍后将在脚本中调用的城市列的占位符。api_key不言自明。 - API 请求:
payload遵循 Google Maps 地理定位 API 接受请求参数的格式,在下一行填入params。在这种情况下,geo将指城市。 - JSON 数据角力:
rLocation将原始的 JSON 位置数据收集到一个变量中,然后用这个变量通过解析 JSON 结果找到latitude和longitude。 - 错误处理: 如果你不熟悉
try和except关键字,这是 Python 中的基本错误处理。这里我们通过传递None值来处理任何IndexError。 - 返回: 最后,我们以
latitude, longitude元组的形式返回数据。
提示:如果这是您第一次使用 Google Maps 地理定位 API ,我建议在您的 web 浏览器中单独调用该 API,这样您就可以自己查看原始的 JSON 结果,并理解上面完成的复杂解析(特别是如果该 API 在将来更新的话)。
现在我们已经定义了这个函数,我们可以开始使用我们的数据了。
从这里开始,我们来读你的原著。csv 文件转换成 DataFrame,并创建一个空列表,我们将在下一步填充它。
然后我们将遍历city列的每一行,用每个城市填充我们的列表。
还记得在我们的geoGoogle()函数中,我们如何将latitude, longitude作为一个元组返回吗?我们也为此做了准备,创建了latList和lonList来存储这些值作为 DataFrame 新列。
现在我们开始这个脚本的核心部分:使用在geoGoogle()中返回的元组将城市名转换成它们的latitude, longitude对。这些然后被存储在我们上面创建的列表中,然后使用pd.Series转换成我们的数据框架df中的新列。
如果您想自己确认生成的纬度和经度是正确的,您会注意到我包含了一个可选的打印语句。
然后我们将这个最终数据集导出到一个新的。csv 文件,确保使用;分隔符,以避免由于城市的city, state文本格式导致的解析错误:
最后,作为最后一笔,我们可以添加一条打印消息来通知用户脚本已经运行完毕,以及生成的新数据文件的名称(将在原始文件名的基础上添加一个前缀geo):

丹尼斯·库默在 Unsplash 上拍摄的照片
在 Tableau 中创建最终的地图可视化
现在我们已经准备好了数据,我们可以导入新的。csv 文件作为 Tableau 中的数据源。

这一步的关键是确保 Tableau 正确解释数据类型。具体来说,我们希望检查Latitude和Longitude列是否被解释为地理数据类型并被赋予适当的地理角色。
为您的地图创建新图纸。在Data侧边栏的Measures部分,右击Latitude并导航至Geographic Role > Latitude。
这将把数据类型符号从#变为一个地球,代表一个地理数据类型。对Longitude做同样的操作。
从这里开始,您就可以绘制地图了。您可以通过将Longitude拖动到列,将Latitude拖动到行来实现这一点,如下所示。

但是这件事有点奇怪。我们的原始数据集中有许多数据点。那么为什么我们在这里只看到一个呢?

如果你仔细观察,你会发现,在默认情况下,Tableau 创建了一个集合度量,这次是以平均值的形式。你看到的这个点是你所有地理位置的平均值。
幸运的是,修复非常简单。导航至Analysis > Aggregate Measures并取消勾选Aggregate Measures。这将为我们提供每个地理位置数据点的预期结果。
这样,我们就得到我们想要的输出,一个简单明了的地图,将每个位置显示为下面地图上的一个单独的点。

由梅丽莎·施密茨 | 制作的图形在 Tableau Public 上直播
从那里,您可以做自己的 Tableau 魔术自定义颜色,大小,标签,工具提示,等等。在上面的图形中,我改变了颜色以匹配我的客户的红色营销,并放大了圆圈的大小,以便作为一个小图形更容易查看。
想要展示的不仅仅是地点吗?只需添加更多数据。
但是,如果你的目标只是显示一个最小的,干净的地图,每个位置都有统一的点,那就完成了!
感谢阅读!
我希望这篇教程能帮助你发现一种新的方法来使用你的其他技能解决 Tableau 中的问题!
我怀疑在 Tableau 中可能有一个更优雅的方法来解决这个问题(或者甚至是一个更简化的 Python 脚本),我鼓励你在评论中提出建设性的质疑。通过这篇文章,我想展示的是,你不必成为每一种工具的大师,或者作为纯粹主义者,只用一种工具解决每一个问题。利用你所掌握的工具有助于全面提高你解决问题的能力。不要害怕尝试。
与任何类型的编程一样,通常有多种方法来解决同一个问题。这就是我选择如何解决我的问题。
如果你想看本教程中使用的完整的原始脚本,你可以在 GitHub 这里查看它:
https://github.com/schmitzmelissa/geocoding-script
或者,如果您想在 Tableau Public 上开始示例可视化,您可以在此处进行操作:
谢谢你的来访!
知道更好的直接在 Tableau 解决这个问题的方法吗?在评论中分享你的专业知识吧!
美化 Python 中杂乱的情节&解决 Seaborn 中常见的问题
原文:https://towardsdatascience.com/beautifying-the-messy-plots-in-python-solving-common-issues-in-seaborn-7372e6479fb?source=collection_archive---------9-----------------------
让我让你的生活更轻松…

用 Python 创建可展示的情节可能有点令人生畏。如果你习惯于使用其他 BI 软件甚至 R 来制作你的可视化效果,尤其是这样,因为大多数的图形已经为你美化过了。另一个问题是,事情可能会以多种方式出错,解决问题的方法将取决于你对剧情的选择。在这里,我将演示几种在 Python 中为各种场景轻松创建绘图的方法,并向您展示如何解决每种情况下可能出现的一些问题。
在这篇文章中,我将重点关注效率,并分享一些将使创建视觉上吸引人的情节快速的花絮。
基本设置
Matplotlib中的 Pyplot 是 Python 中绘图的必备。其他库很可能都使用 Matplotlib 作为后端。Seaborn 就是一个例子。Seaborn 增加了一些不错的功能,但是这些功能有时会造成混乱。让我们先导入所有的包。
**import** pandas **as** pd **
import** matplotlib.pyplot **as** plt
**import** seaborn **as** sns
%matplotlib inline
如果您使用允许您在前端显示图的 iPython 平台,如 Jupyter Notebook,使用%matplotlib inline显示图。
添加样式
如果你只是想要一些像样的东西快速运行,我强烈推荐分配一个的剧情风格。剧情风格瞬间将多种风格元素应用到你的剧情中,省去一些麻烦。提前指定样式的另一个原因是保持整体外观的一致性。如果在文档中使用不同的绘图方法(sns, plt, pd),可能会导致不一致的绘图。
**plt.style.use**('plot-style-name-goes-here')
哪种风格是最好的?
我特别喜欢fivethirtyeight的知名度和简单性。学术界的观众可能更熟悉ggplot style,因为它是 r 中的一个流行库。参见下图来比较一些风格。
seaborn很棒,但是它有太多的选择,可能超过了我们现在想要的。如果您想查看可用样式完整列表,请运行plt.style.available。展望未来,我将使用fivethirtyeight来风格化我所有的情节。

作者图片
问:我必须使用 Matplotlib 绘图吗?
如果你用的是 Pandas,它还附带了一些绘图功能(但它的后端是 Matplotlib)。如果您只想快速查看分布(直方图或密度图)或两列之间的一对一直接关系(折线图或散点图),这将非常方便。
请注意,熊猫绘图不会自动找到最佳绘图类型。默认始终是线形图。
# Pandas plot example - df is a Pandas dataframedf.*column_name*.**plot**(**title** = '*Title*', **kind** = '*hist*')# Above is identical to below using Matplotlib.pyplot ...plt.**hist**(df.*column_name*)
plt.**title**('*Title*')
plt.**ylabel**('*Frequency*')
plt.**show**()# You can also plot relationship between variablesdf.**plot**(**x** = '*column1_name*', **y** = '*column2_name*', **kind** = '*scatter*')
现在我们有了基本的设置,让我们看看不同的场景。
绘制频率/计数数据

Seaborn 的 Countplot 提供了一种快速显示每个值出现频率的方法。
sns**.countplot**(df.*column_name*)# to group
sns.**countplot**(**x** = '*column1*', **hue** = '*column2*, **data** = *df2*)
但是有时事情会变得很糟糕…

我们在这里看到了一些问题,我们在 x 轴上的刻度标签重叠,图例框在一个不太理想的位置。让我们看看如何解决这些问题。
问:如何旋转标签?
我们可以使用 Matplotlib 覆盖 x 刻度的设置。rotation表示旋转文本的角度,ha(水平对齐)移动标签,使其在右侧对齐。
sns.countplot(x = '*method*', hue = '*number*, data = *df2*)
**plt.xticks(rotation = 45, ha = 'right')**

问:如何将图例移出?
要移动图例的位置,我们需要指定图例的位置。我们可以使用 Matplotlib 覆盖图例设置。bbox_to_anchor允许您手动设置图例的位置。如果你只是想把这个放在图的右上角,我们也可以添加位置信息loc = ‘upper right'。
sns.countplot(x = '*method*', hue = '*number*, data = *df2*) plt.xticks(rotation = 45, ha = 'right')
**plt.legend(title = '*Number*', bbox_to_anchor = (1, 1))**

问:我如何堆叠酒吧?
剧情看起来比较好,但是读起来有点吃力。如果每个方法都堆叠了这些条,就更清楚了。countplot有一个名为dodge的参数,默认设置为 True。如果我们将其设置为 False,它将堆叠条形图。
sns.countplot(x = '*method*', hue = '*number*, data = *df2,* **dodge = *False***)
plt.xticks(rotation = 45, ha = 'right')
plt.legend(title = '*Number*', bbox_to_anchor = (1, 1))

问:顺序似乎是随机的?我如何能改变顺序?
我们的情节看起来更好,但整体顺序似乎非常随机。我们也可以使用countplot手动设置绘图顺序。这个功能也可以作为一个过滤器。(当我们这样做的时候,让我们去掉 x 标签并把它也设置为一个标题。)
sns.countplot(x = '*method*', hue = '*number*, data = *df2,* dodge = *False,* **order = ['Radial Velocity', 'Transit', 'Imaging',
'Microlensing', 'Eclipse Timing Variations'**])
plt.xticks(rotation = 45, ha = 'right')
plt.legend(title = '*Number*', bbox_to_anchor = (1, 1))
plt.xlabel('')
plt.title('Method')

太好了!现在我们的频率图看起来好多了。
绘制分类 x 定量
使用 Seaborn 的catplot,您可以很容易地尝试许多不同的选项来绘制类别的值。默认情况下, Catplot 是一个带状图,但是您可以通过将kind参数分配给不同的图类型来更改选项,例如box或violin。只是为了让大家更加迷惑,您也可以通过直接调用它们(例如sns.boxplot或sns.violinplot)来绘制这些分类图,并且可用的参数会有所不同。让我们试着修复一个混乱的 catplot。
# first using catplot
sns.**catplot**(**x** = '*year*', **y** = '*distance*', **hue** = '*method*',
**data** = df, **kind** = '*box*')

哦,不!这一次,它确实将图例放在了外面,但是 x 刻度再次重叠。对于箱线图来说,线条似乎也太粗了,异常值标记非常大。最后,剧情有点太窄了。我们知道如何修复 x 记号,现在让我们修复其他问题。
问:箱线图周围的线条看起来很奇怪,它们太粗了。
为了优化线宽,我们可以手动设置绘图的线宽。
sns.catplot(x = '*year*', y = '*distance*', hue = '*method*',
data = df, kind = '*box*', **linewidth = 0.5)**
plt.xticks(rotation = 45, ha = 'right')

问:箱线图上的异常值标记太大。
现在,与我们漂亮的新系列相比,离群值似乎不成比例。让我们也把它们变小。如果你想完全删除它们,你可以使用showfliers = False。
sns.catplot(x = '*year*', y = '*distance*', hue = '*method*',
data = df, kind = '*box',* linewidth = 0.5, **fliersize = 1**)
plt.xticks(rotation = 45, ha = 'right')

问:我的情节太狭窄了。怎么才能改变剧情的比例?
最后,整个情节看起来太狭窄了。所以我们试着通过改变长宽比来扩大绘图区域。坡向值改变宽度,保持高度不变。
sns.catplot(x = '*year*', y = '*distance*', hue = '*method*',
data = df, kind = '*box',* linewidth = 0.5, fliersize = 1, **aspect = 1.5**)
plt.xticks(rotation = 45, ha = 'right')

如果你直接使用sns.boxplot,它将没有aspect参数,我们将需要通过使用 Matplotlib 设置图形大小来改变纵横比。fig = plt.figure(figsize = (w, h))
问:我的绘图在保存到本地时会被切断。
最后,在本地保存时,有时图的标题或图例可能会被裁剪。为了防止这个问题,在保存情节之前调用plt.tight_layout()。
今天,我们简要地看了一些使用 Matplotlib 和 Seaborn 在 Python 中设置情节的技巧,以及如何解决使用 Seaborn 时的一些常见问题。如果你经常遇到任何其他问题,请留下评论,我可以添加到帖子中!
新年快乐

真诚媒体在 Unsplash 上拍摄的照片
2022 年成为数据科学家:为期 52 周的实用课程
原文:https://towardsdatascience.com/become-a-data-scientist-in-2022-a-practical-52-week-course-8244cc18284e?source=collection_archive---------1-----------------------
涵盖统计、SQL、Python、数学等内容的完整数据科学课程

扎克·杜兰特在 Unsplash 上的照片
如果你一直在考虑转行到数据科学,或者一直在观看自学数据科学的教程,但不确定接下来该学什么,这里有一个完整的 52 周课程,将教你在 2022 年成为数据科学家所需的大部分知识。
该课程涵盖了每个数据科学家都必须知道的东西,如统计学、数学、SQL 和 Python。所有这些都是宽泛的主题,但本课程涵盖了数据科学中大量使用的主题。
请注意,您应该按照本文中列出的顺序学习课程,但是您也可以先学习您最喜欢的科目。例如,我喜欢编程,所以我会先开始学习 Python 和 SQL,但是如果你喜欢概率,那么你应该从统计学开始。
在下面我的 YouTube 视频中,你可以找到成为一名数据科学家需要学习的所有东西的概述。
请务必点击 订阅此处 获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)
第 1–10 周:用于数据科学的 SQL
SQL 不仅对于数据科学,而且对于任何与数据相关的领域都是必不可少的。SQL 允许我们使用数据库。作为一名数据科学家,您经常需要从数据库中提取数据来执行您的分析,因此这是一项非常有用的技能,您需要掌握。
这个 4 小时的视频是一个针对初学者的 SQL 课程,它将教你所有你需要知道的关于数据库管理和如何创建 SQL 查询的东西。你将学习使用 MySQL 数据库的 SQL,SQL 理论,一些基本的数据库术语,数据定义语言(DDL),SQL 关键字,数据操作语言(DML),数据控制语言(DCL),事务控制语言(TCL)等等。
让我们更详细地了解一下本课程的课程表(以及我认为数据科学课程中最重要的部分)
- 关系数据库的核心概念(表和键)
- SQL 基础知识(DDL、DML、DCL 和查询)
- 如何创建表和插入数据(创建、删除、插入)
- 逻辑和比较运算符
- SQL 约束(非空、唯一、主键等)
- 聚合(计数、总和、最小值、最大值)
- 更新和删除(更新,哪里,删除)
- 基本查询(SELECT …FROM、ORDER BY、LIMIT 等)
- 通配符(%,_)
- 联合和联接(内部联接、左联接、右联接等)
- 嵌套查询
第 11–18 周:学习数据科学的统计学和概率
我们使用数据科学中的统计学来分析和解释数据。统计有助于我们发现异常,以便在项目中区分最佳数据并删除不必要的数据。所有这些都是至关重要的,以确保我们用来训练我们的模型的数据没有偏见。
学习数据科学的统计学
这段 1 小时的 YouTube 视频涵盖了的描述性统计。您将学习不同类型的数据,如何构建直方图和散点图,如何找到平均值、中值和众数,学习偏度、方差和标准差,并查看一些实际示例。
本教程涵盖了正态分布。这是统计学中最重要的概念之一。这是推断统计学的基础(我们对数据点的推断大多基于正态分布)。
本单元的所有视频教程都涵盖了置信区间。您将学习置信区间、如何估计人口比例以及如何估计人口平均值(您将在此学习 t 统计)。
最后,本单元所有视频教程涵盖假设检验。您将学习一些重要的概念,如 p 值、错误类型(I 型和 II 型错误)和显著性检验。除此之外,你将学习如何构造一个关于比例的测试。
学习数据科学的概率
本单元的前 8 节涵盖了概率的基础知识。在那里,您将学习数据科学所需的所有概率概念,如基本理论概率、使用样本空间的概率、基本集合运算、实验概率、随机性、加法规则、独立和相关事件的乘法规则以及条件概率。
该单元包括计数、排列和组合。您将首先学习如何使用树形图和花图计算结果。然后你将学习排列和组合背后的概念,并看到一些应用。
最后,在这个播放列表中,你会发现很多离散分布的教程,作为一个数据科学家你应该知道。至少学习伯努利分布、二项式分布、泊松分布和均匀分布(这里有一些离散分布的概述),而在第二个播放列表中,您会发现一些您也应该知道的连续概率分布(正态分布、学生 T 分布、卡方分布、指数分布和逻辑分布)
第 19–25 周:学习数据科学的数学
数据科学中广泛使用的数学分支有两个:微积分和线性代数。这是理解稍后将使用 Python 实现的机器学习和深度学习模型的基础。
这个第一线性代数单元涵盖了向量和空间。您将学习线性代数的向量、线性组合和跨度、线性相关性和独立性、子空间和子空间的基础、向量点积和叉积以及矩阵。
第二线性代数单元都是关于矩阵变换。它涵盖了函数和线性变换,变换和矩阵乘法,反函数和变换,如何找到逆和行列式以及如何转置一个矩阵。大部分这些东西都可以用 Python 通过几行代码来完成,但是了解它背后的数学原理对你是有好处的。
微积分 1 和微积分 2 单元涵盖了基本的数学知识,如导数、微分方程、积分、级数以及它们的应用。
第 26–52 周:为数据科学和机器学习学习 Python
学习面向数据科学的 Python 不仅包括听课,还包括解决练习和项目,因此这可能比其他科目需要更多的时间。在之前的一篇文章中,我分享了在 2022 年学习数据科学 Python 的完整的 26 周课程。
课程分为 4 个主要部分:
- 数据科学的 Python 核心概念
- 用于数据分析的 Python
- 用于数据可视化的 Python
- 用于机器学习的 Python
每个部分都有免费的视频教程、指南、练习和项目,可以帮助您掌握 Python 数据科学。所有的免费资源都可以在下面的文章中找到。
与 6k 以上的人一起加入我的电子邮件列表,获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)
如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。
https://frank-andrade.medium.com/membership
如何在不编码的情况下成为一名出色的数据科学家(+工程师)
原文:https://towardsdatascience.com/become-a-data-scientist-or-data-engineer-without-coding-skills-fbf11ac8e278?source=collection_archive---------2-----------------------
从数据中获得意义是常识。编码技能不是数据科学家或数据工程师的超能力。

数据科学家和数据工程师不需要编码技能。——照片由 Pexels 的 Lukas 拍摄
如果你梦想成为一名 数据科学家或数据工程师 ,你可能会在那个梦里看到一个充满代码的黑屏。打磨你的编码技能可能是你在这个旅程中得到的流行建议。然而,令人惊讶的是,它 与编程无关。
数据科学是从原始记录集合中获取意义的过程。编程语言只是一种工具。它就像一个用来做饭的容器。但是容器本身并不是食物。
人们对数据科学失去兴趣是因为有些人不擅长编程。他们甚至无法理解像 Python 这样直观的语言。然而,对其他人来说,这很自然。但这些不是能力,而是不同的能力。
这个故事会改变你的视角。即使你不会或不想编程,你也可以成为一名杰出的数据科学家。 批判性思维和一些数据素养 会让你甚至有能力管理一个数据项目。
今天我们有 不需要编码技能的技术 开始数据科学。他们还有 几个程序员没有 的好处。由于它们的直观性和较少的依赖性,我向所有渴望成为数据科学家的人推荐它们。
我们将在本帖中讨论 KNIME 分析平台。只需要常识就能理解数据。另一个流行的替代是rapid miner。两者都已经存在了一段时间,许多公司也在生产中使用它们。然而,在我看来,他们仍然被低估了。
在继续之前,我们先让你成为一名数据科学家和数据工程师。
用 KNIME 启动数据科学,无需编写任何代码。
你可以下载并像其他应用程序一样在你的电脑上安装 KNIME 。该软件是免费和开源的。 你可以用它来搭建 数据管道,数据角力,训练机器学习模型,实时预测。这几乎是大多数数据科学家和数据工程师的工作。
假设您正在为一家零售连锁店创建一个 客户细分引擎 。您从两个不同的系统接收数据。一个是包含客户人口统计信息的表,另一个是关于他们购买模式的表。您的任务是每天在收到新数据时更新分类表示。

数据科学和数据工程项目的工作流程—由作者创建的图像。
这个 的第一部分是一个 ETL。 就是我们例子中的数据工程部分。我们从不同的数据源中读取数据(提取、连接它们、过滤(转换)并保存(加载)数据以备将来参考。
在 的第二部分,我们创建了一个 K 均值聚类引擎。 这是我们例子中的数据科学部分。它从保存的路径中读取数据,执行聚类,并输出一个表。输出表包含每个客户的分类标签。
关于 KNIME 的界面需要了解什么?
该界面有许多令人难以置信的功能。然而,对于这个介绍性的练习,我们只对两个组件感兴趣。节点存储库在左下角,工作流编辑器在中间。编辑器右侧的描述小部件也很有帮助。

截图来自作者。
KNIME 背后的工程团队完成了一项了不起的工作。他们已经为数据科学家将执行的几乎每一项活动创建了节点。我们可以从节点库中搜索任何节点。
您可以将这些节点中的任何一个拖到编辑器中。双击任意节点;您会看到一个配置窗口。您可以在此窗口中进行活动运行所需的所有设置。
您可以通过单击任何节点来调出它的即时文档。它将解释所有的输入要求和节点将返回什么。
从数据源读取数据-提取。
在 KNIME 中,有几种方法可以从数据源中提取数据。您可以读取文件、查询数据库、调用 REST 端点等。
在本例中,我们从本地文件系统中读取了几个 CSV 文件。您可以在节点存储库中搜索 CSV reader 节点,并将其拖到编辑器中。
当你把它拖到主窗口时,你会看到红色的交通灯在节点的下面。说明我们还没有配置。您可以双击它并将其配置为从文件路径中读取。

作者截图。
你可以看到指示器现在是黄色的。这意味着该节点已准备好执行。右键单击节点并选择执行。现在指针变成绿色。节点执行成功。
您可以通过右键单击并选择列表中的最后一个元素来查看结果。在 KNIME 中,最后的几个选项总是该节点的输出。CSV reader 节点只输出一项——文件表本身。
在本例中,我正在读取两个 CSV。你可以从这个 Git 库下载它们。
执行连接、过滤等。—转换。
KNIME 有直观的节点来执行各种数据争论任务。在这个例子中,我们使用了其中的两个——连接和行过滤器。您可能需要执行宁滨、规范化、删除重复和空值等操作。
转换一个变量并聚合它是一种常见的任务。这种技术通常被称为 map-reduce 操作。
它们都是 KNIME 中的另一个节点。
我从存储库中取出了 joiner 节点。使用鼠标,我将 CSV 节点的输出(右)与 joiner 节点的输入(左)连接起来。您可以通过选择每个表的列来执行连接操作,从而配置该节点。

作者截图。
与 CSV 阅读器节点不同,连接器节点有三个输出。如果您将鼠标悬停在它们上面,工具提示会解释它们是什么。第一个是连接结果。在我们的例子中,我们不使用第二个(左不匹配)和第三个(右不匹配)。
接下来,让我们提取行过滤器节点,并将其与 joiner 节点的输出连接起来。我们可以将其配置为删除一次性购买的客户。将 visit_count 变量的下限设置为 2。

作者截图。
保存输出—加载。
ETL 管道的最后一部分是将数据加载到持久存储中。我们不想让这个例子变得复杂。因此我们将其写入 CSV。但是,在实际项目中,您可能必须将其加载到数据库或数据仓库中。不用担心;KNIME 在任何情况下都有帮助。
我抓取了 CSV writer 节点,并以与 CSV reader 非常相似的方式对其进行了配置。

作者截图。
这最后一部分总结了 ETL 管道。这是数据工程师的一项重要任务。在 LinkedIn 上找一些职位描述,自己看看。
无需编码即可执行机器学习任务。
我们有干净的数据,并准备好建立令人兴奋的东西。在这个例子中,我们提出了一个市场细分问题。为此,我们将使用 K-Means 聚类算法。同样,您可以在 KNIME 中执行几乎任何机器学习算法,而无需编写一行代码。
K-Means 根据客户属性的相似性创建客户群。除了使用哪些属性,我们还可以指定需要多少个组。
让我们从存储库中取出 k-Means 节点,并将其与行过滤器节点的输出连接起来。我们可以配置它,根据客户的年龄和访问次数将客户分成四个集群。

作者截图。
执行节点后,您可以检查输出。您将获得每个客户的分类标签和每个分类的摘要。
我在这个例子中选择 K-Means 是因为它简单。对于大多数机器学习应用程序,您有几个其他任务要执行。重新训练一个模型也很重要。
KNIME 的 youtube 频道有许多有见地的视频来帮助你的数据科学之旅。
在 KNIME 中可视化您的分析。
大多数数据科学项目的最后部分是可视化见解。Tableau 等商业智能(BI)平台专门研究这一领域。你可以连接 KNIME 与他们进行高级分析。然而,场馆本身支持基本的可视化。商业智能平台对更广泛的受众来说是极好的。但是对于数据科学家来说,KNIME 的可视化节点已经足够了。
我们将使用散点图节点在用于聚类的两个变量之间创建一个图表。但在此之前,让我们在工作流中放置一个颜色管理器节点。
与其他可视化工具不同,我们需要在绘制记录之前对其进行着色。
您可以选择颜色和用于颜色选择的变量。然而,在这个例子中,我们对缺省值很满意。颜色管理器为它选择聚类标签,默认颜色也很好。

作者截图。
我们现在可以将散点图节点添加到工作流中。让我们将其配置为使用 x 轴中的年龄和 y 轴中的访问计数。此外,请确保您勾选了“在输出时创建图像”复选框。
现在,您可以执行散点图节点并调出图像输出。您也可以使用图像写入器节点将结果导出到文件中。
如果你需要参考,下面是最终的工作流程。

作者截图。
最后的想法
非常好。我们建立了一个完整的数据管道,没有一行代码。它涵盖了 ETL,这是数据工程师的一项重要工作。此外,我们还建立了机器学习模型,并将它们的输出可视化。
非常好。我们建立了一个完整的数据管道,没有一行代码。它涵盖了 ETL,这是数据工程师的一项重要工作。此外,我们还建立了机器学习模型,并将它们的输出可视化。
编程对于数据科学是必不可少的是一个神话。这两者是相关的。但它们并不相互依赖。
我不主张完全避免编程。在某些时候,你需要它。例如,数据科学中的一项最新发现可能还没有出现在 KNIME 中。这个平台可以很好地执行已经存在并受欢迎的内容。
还有,如果你是数据科学研究者,KNIME 只有一点用处。你需要用你自己的代码来构建你自己的算法。
由于这个原因,KNIME 本身为程序提供了灵活性。标准安装已经有了 Java 和 JavaScript 节点来完成这项工作。还可以扩展使用 Python 等语言。
重点是,你不需要每次都编码。
谢谢你的阅读,朋友。看来你和我有许多共同的兴趣。也一定要看看我的个人博客。
在LinkedInTwitterMedium上跟我打招呼。我会为你打破僵局。
还不是中等会员?请使用此链接 成为会员 因为我为你免费推荐赚取佣金。
成为更高效的 Python 程序员
原文:https://towardsdatascience.com/become-a-more-efficient-python-programmer-3850c94b95a4?source=collection_archive---------11-----------------------
了解用 Python 创建列表和完成其他任务的最佳方式

照片由 Gema Saputera 在 Unsplash 上拍摄
任何 python 程序员的目标都是编写可读性最强、计算效率最高的代码。在之前的教程中,我们介绍了用 python 创建列表的几种方法,包括使用 for 循环、map 和 filter 函数以及列表理解。但是哪一个可读性最强并且需要的执行时间最少呢?
在本教程中,我们将使用 Python timeit 模块,首先通过测量它们的执行时间来比较在 Python 中创建列表的所有三种方法的性能,包括 for 循环、map 函数和列表理解。
之后,我们将比较 reduce 函数和一些完成相同任务的内置或专用 Python 函数,并比较它们的执行时间。
要查看 lambda 函数、map 和/或 reduce 函数和/或 list comprehensions,请查看:
创建列表
我们将创建一个包含从 0 到 9 的平方值的数字列表。为此,我们将创建三个函数,一个使用 for 循环,一个使用 map 函数,一个使用 list comprehensions。我们将在这些函数中用来循环的 iterable(我们可以循环的东西)将是一个 range 对象,它是由 python 中内置的 range 函数创建的。
在我们创建这三个函数之后,我们将使用 timeit 模块来测量所有三个函数的执行时间,以便衡量所使用的每种方法的计算效率。
我们开始吧!
For 循环
创建这个列表的一种方法是使用 for 循环遍历 range 对象,并将平方值追加到新列表中。
这是我们如何用代码实现的:
def for_loop():
squared_list = []
for num in range(10):
squared_list.append(num**2) return squared_list
注意我们是如何在 range 对象上循环的,这个对象是由 range 函数创建的,名为 range(10) 。这是一个可迭代的对象,我们可以使用 for 循环来遍历它,这将为我们提供从 0 到 9 的整数。我们也将在其他函数中使用这个相同的对象。
地图功能
制作这个列表的另一种方法是使用名为 map 的内置 python 函数。 map 函数接受两个参数:我们想要应用的函数和我们想要应用它的可迭代对象或序列(比如本例中的 range 对象)。换句话说,map 函数将这个函数映射或应用到我们传入的 iterable 对象的每个元素。
地图(函数,可迭代)
我们可以使用下面的代码利用 map 函数创建上面的列表:
def map_func():
return list(map(lambda num: num**2, range(10)))
我们使用一个 lambda 函数(匿名函数)作为我们传递给 map 函数的函数,当它遍历 range 对象时,它接受 num 并返回 num 的平方。
记住,map 函数将返回一个 map 对象,它是一个迭代器。如果我们想从这个 map 对象创建一个列表,我们需要将 map 对象传递给内置的 list 函数。
列出理解
我们将编写的最后一个函数将使用 list comprehensions 来创建我们想要的列表。列表理解允许我们从其他序列(或可迭代对象)中以一种非常简洁但可读性很高的方式创建列表。
列表理解由括号组成,括号包含一个表达式,后跟一个 for 循环,以及零个或多个 for 或 if 子句。
中 的
我们将使用 list comprehensions 遍历另一个 iterable 对象,特别是 range 对象,并添加从 0 到 9 的数字的平方,如下所示:
def list_comprehension():
return [num**2 for num in range(10)]
性能比较
为了测量每个函数花费的时间,我们将使用 python 内置的time it模块。这个模块将为我们提供一种简单的方法来测量运行这些函数所花费的时间。
首先,我们将导入 timeit 模块。然后从那个模块我们将使用 timeit 函数。 timeit 函数接受多个参数;但是,我们将只传入一个,其他的使用默认值。
timeit . timeit(stmt = ' pass ', setup='pass' , timer= <默认定时器> , number=1000000 , globals=None )
我们将传入的参数是我们想要运行的函数( stmt 参数)。我们可以用 number 参数指定我们希望该函数运行的次数,而 timeit 函数将返回总的执行时间。
我们将每个函数运行 100 万次(这是默认值)。下面是我们的代码和结果:
*import timeitprint(f'Time for the for loop: {timeit.timeit(for_loop)}')
print(f'Time for map: {timeit.timeit(map_func)}')
print(f'Time for the list comprehension: {timeit.timeit(list_comprehension)}')**Results:****Time for the for loop: 3.5020802999999887
Time for map: 4.0746793999999795
Time for the list comprehension: 3.3324222999999904***
正如我们在上面看到的,理解一个列表花费了最少的时间,只有 3.33 秒。for 循环略微落后,为 3.50 秒,map 函数的执行时间最长,为 4.07 秒。
基于这些结果,以及列表理解通常比映射和过滤函数以及 for 循环更容易阅读和理解的事实,使列表理解成为我创建列表的首选方法。
* *
减少功能
我们现在将比较 reduce 和使用 for 循环的执行时间。然后,我们将 reduce 与一些相应的内置或专用 Python 函数进行比较。
Reduce 与 For 循环
我们将编写两个取数字 1 到 9 的乘积的函数。一个函数将使用 for 循环,另一个将使用 reduce 函数。
带 For 循环的函数
*def for_loop_prod():
product = 1
for num in range(1,10):
product*=num
return product*
我们要将 1 和 9 之间的数相乘,得到它们的乘积,这将由 range(1,10) 提供。我们创建变量 产品 并将其设置为 1。然后,我们使用 for 循环遍历 range 对象,并将每个数字乘以上一次迭代的结果。在循环数字 1-9 之后, 乘积 或累加器将等于 362880,我们将返回该值。
在我们编写将使用 reduce 的函数之前,让我们简单回顾一下 reduce 函数。
什么是 reduce?
简单地说,reduce 函数接受一个 iterable,比如一个 list,或者在本例中是 range 对象,并将其缩减为一个累积值。reduce 函数可以接受三个参数,其中两个是必需的。两个必需的参数是:一个函数(它本身接受两个参数)和一个 iterable。第三个参数是一个初始化器,是可选的。
reduce(函数,可迭代[,初始值设定项])
要使用 reduce 函数,我们需要按如下方式导入它:
*import functoolsorfrom functools import reduce*
reduce 接受的第一个参数,函数本身必须接受两个参数。Reduce 然后将这个函数累积地应用到 iterable 的元素上(从左到右),并将其减少到一个值。
因此,我们可以使用 reduce 函数来计算数字 1–9 的乘积,如下所示:
*def reduce_prod():
return reduce(lambda x,y:x*y, range(1,10))*
我们的 iterable 对象是 range 对象。我们的λ函数接受两个参数, x 和 y 。Reduce 将首先获取 range 对象的前两个元素 1 和 2,并将它们作为参数 x 和 y 传递给 lambda 函数。**λ函数返回它们的乘积,即 1 * 2,等于 2。Reduce 随后将使用这个累加值 2 作为新的或更新的 x 值,并使用 range 对象中的下一个元素 3 作为新的或更新的 y 值。然后,它将这两个值(2 和 3)作为 x 和 y 发送给我们的 lambda 函数,然后返回它们的乘积 2 * 3 或 6。然后,这个 6 将被用作我们新的或更新的 x 值,range 对象中的下一个元素将被用作我们新的或更新的 y 值,即 4。依此类推,直到到达 range 对象的末尾。换句话说,x 参数用累积值更新,y 参数从 iterable 更新。
性能比较
我们将再次使用 timeit 函数来测量上述 for 循环和 reduce 函数的执行时间。
*import timeitprint(f'Time for a for loop: {timeit.timeit(for_loop)}')
print(f'Time for reduce: {timeit.timeit(reduce_function)}')**Results:****Time for a for loop: 1.0081427000004624
Time for reduce: 1.684817700000167***
正如我们所看到的,与 reduce 函数相比,for 循环的执行时间更少。然而,在我们决定使用 for 循环来完成类似于获取 iterable 的乘积的任务之前,让我们看看专用函数在计算效率方面能提供什么。
* *
减少与专用功能
我们将 reduce 函数与四个专用的 Python 函数进行比较: prod 、 sum 、 max 和 min 。 prod 函数实际上在 math 模块中,所以这是我们需要首先导入的唯一函数。
以下是接受 range 对象的乘积、总和、最大值和最小值的函数:
***Product:**def reduce_prod():
return reduce(lambda x,y:x*y, range(1,10))def math_prod():
return math.prod(range(1,10))**Sum:**def reduce_sum():
return reduce(lambda x,y:x+y, range(1,10))def builtin_sum():
return sum(range(1,10))**Max:**def reduce_max():
return reduce(lambda x,y: x if x > y else y, range(1,10))def builtin_max():
return max(range(1,10))**Min:**def reduce_min():
return reduce(lambda x,y: x if x < y else y, range(1,10))def builtin_min():
return min(range(1,10))*
以下是他们的执行时间:
*print(f'Time for reduce product: {timeit.timeit(reduce_prod)}')
print(f'Time for math prod: {timeit.timeit(math_prod)}')print(f'Time for reduce sum: {timeit.timeit(reduce_sum)}')
print(f'Time for builtin sum: {timeit.timeit(builtin_sum)}')print(f'Time for reduce max: {timeit.timeit(reduce_max)}')
print(f'Time for builtin max: {timeit.timeit(builtin_max)}')print(f'Time for reduce min: {timeit.timeit(reduce_min)}')
print(f'Time for builtin min: {timeit.timeit(builtin_min)}')**Results:****Time for reduce product: 1.7645603999999366
Time for math prod: 0.5869173999999475****Time for reduce sum: 1.4824804999998378
Time for builtin sum: 0.4908693999998377****Time for reduce max: 1.6678851000001487
Time for builtin max: 0.591082900000174****Time for reduce min: 1.5096722000000682
Time for builtin min: 0.6109481999999389***
在所有情况下,专用 Python 函数的性能明显优于 reduce 函数。如果我们将数学 prod 函数与上面的 for 循环进行比较,prod 函数的性能要比 for 循环好得多。
结论
看起来,如果 Python 中有一个专门的函数来做我们需要的事情,我们应该使用它,因为它很可能会比用 for 循环或 reduce 函数编写自己的代码给我们带来更好的性能。
注意:我们可以通过传入操作符函数而不是 lambda 函数作为参数来获得更好的性能。例如,在上面的 sum 函数中,我们可以传入操作符。add* 作为 reduce 的函数参数,这将比使用 For 循环提供更好的性能。*
因此,如果内置或专用的 Python 函数尚不存在,那么 reduce 函数可以与关联运算符函数一起使用,如果这是一个选项的话。否则,一个编写良好的 for 循环对于可读性和性能来说是最好的。
如果你喜欢阅读这样的故事,并想支持我成为一名作家,考虑注册成为一名媒体成员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你用我的 链接 报名,我会赚一小笔佣金。
*https://lmatalka90.medium.com/membership *
摘要
在本文中,我们看到了用 Python 制作列表的不同方法的性能:使用 for 循环、map 函数和列表理解。我们看到,列表理解通过具有最低的执行时间,在这些方法中提供了最大的可读性和最好的性能。接下来,我们看到了使用 for 循环、reduce 函数和一些内置函数的性能。我们发现内置函数大大优于 reduce 函数,并且在较小的程度上,使用 for 循环。总之,为了创建列表,我建议尽可能使用列表理解,而不是使用 reduce 函数,使用专用函数来获得更好的可读性和性能。
成为一名没有编码和技术知识的数据科学家
原文:https://towardsdatascience.com/becoming-a-data-scientist-without-prior-coding-and-technical-knowledge-3d2deea1daa8?source=collection_archive---------47-----------------------
通往数据科学的非编码、非技术之旅

照片由 Unsplash 上的 Dmitry Ratushny 拍摄
如果你在这里,你可能会好奇一个没有编码、没有软件工程经验(来自一个完全不相关的领域)的人是如何进入数据科学的。
只是为了让你知道你是否想留下来,我希望为你回答这些问题:
- 我如何准备好过渡到数据科学?
- 我现在必须开始培养的必备技能是什么?
- 我如何开始学习?
- 数据科学的研究生学习适合我吗?
- 作为一名非技术出身的数据科学家在科技公司工作是什么感觉?
在本文中,我不会与您分享学习数据科学的确切课程或途径。
已经有很多关于这方面的文章了。我不认为这些年来学习的基本领域发生了变化。
可能会有新的技术栈,或尖端的图书馆,或新的训练营或课程发布,但实用数据科学所立足的基础保持不变。
我能提供的更详细的信息是我阅读和参加的向数据世界过渡的书籍、课程和程序,以及我为进入数据科学领域所做的准备。
如果它对我有效,谁知道它可能对你也有效。
我如何准备好过渡到数据科学?

弗朗西斯·达·席尔瓦在 Unsplash 上的照片
一个小小的背景故事。
我曾经梦想发明新的神奇材料。我一生中花了相当多的时间在实验室里接受培训,以成为一名化学家(和一名材料工程师)。
我喜欢把东西放在一起创造更好的,潜在的更有用的东西的想法。六年来,我正式接受训练,成为我所在领域的专家(包括在美国的研究生学习),在实验室内外度过时光。
然而,在我作为本领域学生的某个时候,我意识到我创造新的、有用的东西的愿望并没有被限制在实验室里。大约在 2016 年末的这个时候,我了解了数据科学。
巧合的是,也是在那个时候,我决定要温习一些几乎没什么用的高中编码知识,作为一种爱好,我必须学习一些新的东西。
转折点。
随着我对数据科学的了解越来越多,我了解到它并不像我想象的那么陌生。这是解决问题的同一种科学方法——但不是使用不同种类的化学品和处理技术来获得想要的输出,而是使用数据和统计数据。
当我知道如何编写代码,如何使用我在大学学到的现有统计和数学知识,以及我过去学到的研究和实验方法,并在特定的商业环境中使用它来解决问题时,我的内心感到不安——几乎与我最初追求成为一名研究科学家时的感觉一样。
就在那时,我决定温习编码技能,不是为了爱好,而是为了学习如何用它来解决数据问题。
要过渡到像数据科学这样的新领域,请记住以下几点:
- 有很多东西要学——就像很多很多。没有捷径可走。即使是现在,我几乎每天都在学习。
- 你需要学会如何学习。知道哪种学习媒介适合你。虽然,我现在告诉你,没有逃避的书,阅读大量的文本。(我提到阅读和编写文档了吗?)学习如何学得最好是一种可以帮助你更快积累知识的技能。
- 要成为数据科学家,你需要了解你将做出的取舍。这可能意味着你需要连续几个小时学习,一些周末计划被取消,一些深夜会议处理你的文件夹,等等。— 你知道程序。
- 请记住,没有人天生就是数据科学家。当你不明白某件事时,不要轻易不知所措。伟大的人曾经也很糟糕。
此外,要准备过渡,尽可能熟悉话题是很重要的。
我推荐阅读关于数据科学的文章、书籍、研讨会和会议。
我建议你先阅读商业应用,以便在这个领域获得更多的立足点,并对它有更多的了解。
这里有一些很好的书籍可供阅读:
</21-data-science-books-you-should-read-in-2021-db625e97feb6>
我可能会将我对数据科学的热情归因于从我阅读的早期书籍中了解到的公司如何利用数据来做令人惊讶的事情(不要忽视对数据的一些边缘道德使用,这是另一个话题)
谢天谢地,现在的在线资源比五年前丰富多了,更不用说很多都是免费的。
所以,坐下来,上谷歌,做一块海绵,尽可能多地吸收。
我现在必须开始培养的必备技能是什么?

韦斯·希克斯在 Unsplash 上的照片
数据科学有三大支柱,即:编程、统计和业务(领域专长)。通常,我们参考这三个领域的维恩图来定义什么是数据科学家。你可能已经看到了。
简而言之,要开始学习数据科学,您需要掌握三大主题的工作和实践知识。
要知道从哪里开始,我建议直接从你的最薄弱的环节开始。
如果你在大学里已经知道一点数学和统计学,但是从来没有写过一行代码,那就去学编程吧。
如果你是一个业余编程爱好者,但几乎不知道什么是正态分布,那就去查阅和学习统计学吧。
要快速学习,重要的是学习要尽可能直接,尽可能投入。
至于商业,除非你有自己的企业,否则你最好读一些商业书籍和一些不错的老哈佛商业评论。
对我来说,我已经开始描绘我知道的和不知道的。
我确定了编程、统计和商业中对实用数据科学至关重要的哪些子主题是我已经熟悉的,而不是一无所知的。作为我第一次尝试转行的一部分,我决定我需要学习 Python 编程。
然而,就像任何其他具有潜在陡峭学习曲线的学科一样,对我来说,学习我的舒适区之外的东西是一场斗争。
我知道我需要以一种有趣和可以忍受的方式学习。就在那时,我偶然发现了这本书:如何用 Python 自动化枯燥的东西,作者是 Al Sweigart 。
https://automatetheboringstuff.com/
顾名思义,这本书不是正式文本。它试图取笑我们每天做的许多平凡的任务,并取笑我们以前没有做任何事情来自动化这些任务。
所以我从那本书开始。
此外,我开始在数据科学的背景下审视我的研究生课程。我选修了一门关于高级回归方法的额外课程,以更多地了解高级统计学如何在研究中用于预测事物。
此外,我开始研究人工智能是如何在我的领域中创新的(并了解到我的导师在他的论文中已经做了很多这样的事情!)
就主题而言,重点关注三大领域:
- 编程;编排
- 统计数字
- 商业
如果可能的话,试着由内而外地工作,看看你现在在做什么,看看你可以通过写代码、用统计数据更好地分析数据,以及在你目前的工作中应用一些好的商业或领导实践来改进什么。
你会惊讶地发现,通过首先在内部学习和思考这些主题,你在任何其他背景下学习数据科学都会变得更加容易。
我如何开始学习?

照片由 Siora 摄影在 Unsplash 上拍摄
现在学习的方法太多了,可能会让人不知所措。
除了书籍和正规教育,你现在有了 Youtube 视频,像 Udemy 、 EdX 和 Coursera ,像 Datacamp 和 Dataquest 这样的互动教育平台,甚至还有关于数据科学的播客。
现在,对数据科学一无所知是一种罪过。
我敢肯定,如果你之前问过谷歌关于数据科学的问题,你很可能会被你必须利用的课程和订阅广告轰炸。
不过,棘手的是:
每个人的学习方式不同。
这就是为什么学习如何学得最好很重要。
至于我,我从一个全面结构化的自定进度在线计划开始。
我从微软教授的 EdX 学习课程开始了我的旅程。那时,Udemy 上没有很多高质量的课程,我发现 Youtube 太过杂乱,无法成为一个有效的学习工具。
此外,我还不想从约翰霍普金斯大学的热门课程中学习 R。我想建立在我现有的 Python 知识的基础上,所以参加微软的课程对我来说是有意义的。
我花了一些时间完成所有 10 门课程。它不同于正规学校教育,非常实用。没有人强迫我完成这个项目,所以对我个人来说回报更大。
数据科学的研究生学习适合我吗?

由琪琪·奥尼肯在 Unsplash 上拍摄的照片
开门见山地说,是的,我的确上过数据科学的研究生课程。
我这样决定并不是因为我参加的 MOOCs 没有帮助,而是因为我只是渴望结构。更重要的是,我把研究生学习看作是我进入一个充满活力的社区的跳板,这个社区对我想要成长的领域充满热情。
正如我提到的,很多在线学习是分散的,高质量的材料很难找到。有时候,我们不承认我们没有从刚买的课程中得到实惠,因为我们已经为它支付了 xxx 美元。
虽然正式的校内项目也是如此,但是很难犯错误,特别是如果你看看外面的优秀项目。
如果符合以下条件,您可能希望进行数据科学方面的研究生学习:
- 你想要结构化的学习。
- 你需要一些外部的学习动力,而不是完全自发的。
- 你会发现额外的凭证很有价值。
- 你想建立关系网。
- 如果你以前尝试过自定进度的学习,想要更多的挑战。
- 如果你有一些经验,只是想在大学环境中提高技能。
对我来说,我发现数据科学的研究生课程非常有价值。
这让我对数据的肤浅理解更加严谨。它帮助我接触到所有其他相关主题,包括软技能培训,如果没有这个项目,我不会有这些培训。
我可以说我在研究生院度过了比以前任何时候都要艰难的几个月。因为同样的研究生项目,我得以在我现在工作的公司获得面试机会。
这并不是说你需要一个数据科学硕士学位才能成为一名数据科学家。这当然不是一个要求。
我认识的很多从事数据工作的了不起的人都没有高学历,但他们是有能力的数据专业人士,能产生影响。
作为一名数据科学家是什么感觉?

蒂尔萨·范·迪克在 Unsplash 上拍摄的照片
三年过去了,我终于完成了从非技术职业到数据科学领域的转变。
如果我在脑子里讨论作为一名数据科学家是什么样的,这篇文章会太长,但我可以说:
- 数据科学是一个令人兴奋的领域,涉及大量的学习、解决问题和打破常规的思考。如果你想要挑战,每次都想做不同的事情,那么数据科学就是你的职业。我几乎从不长时间做同样的事情。
- 真如他们所说: 数据科学家花很多时间清理数据,只有很少一部分时间创建模型 。在理想世界中,我们希望我们的科学家 100%地实施尖端算法。然而在现实中,这种情况很少发生。
- 不要低估更简单的模型而忽视更复杂的模型。通常情况下,非线性模型能够以比复杂模型更低的开销提供相同的价值。有时候,这正是业务所需要的,这很好。
- 如果和数据打交道,需要学习 SQL。以前不关心 SQL,从来没有这么错过。我曾经相信我可以用 Pandas 和 Numpy 来处理我的数据。不幸的是,我得到了惨痛的教训。如果你打算加入一家大公司,他们的数据很有可能是巨大的,而且他们正在使用 SQL 的某种变体。知道如何查询数据是一项非常强大的技能,你应该花时间去掌握。这将为您的数据职业生涯带来巨大回报。
- 数据科学家是一个不断发展的角色。你具体做什么,你如何定义成功,取决于你的组织和你所处的商业环境。众所周知,公司和他们对数据科学的期望之间存在脱节。公司仍在尝试组织结构和有效的方式来部署他们的 DS 人才。
- 对于公司来说,在整个组织内实现数据民主化和分析数据的技能有很大的价值。如果少数数据科学家能够对公司产生巨大影响,想象一下如果每个人都足够精通数据。
- 数据科学有时会令人沮丧。有时数据中断,有时您的代码中断。有时候你不知道到底发生了什么。有时候你不得不从头再做一遍。
结束语
数据科学是一个令人兴奋的领域。这不仅仅是一些炒作。这是一个为选择投资 It 的企业带来真正价值的领域。虽然,这需要掌握一些硬技能,并倾向于自主学习(无论你是否选择为此接受正规学校教育)。
有了对组件技能的关注和足够的实践,即使没有以前的编码或技术经验,也一定可以过渡到这个领域。
你打算进军数据科学吗?请在评论中告诉我!🙌
如果你喜欢这个,比如说👋在推特上关注我!
成为人工智能伦理学的后起之秀
原文:https://towardsdatascience.com/becoming-an-upstander-in-ai-ethics-577a38b23e45?source=collection_archive---------41-----------------------

照片由阿曼达·林斯在 Unsplash 拍摄
我们不记得敌人的话语,只记得朋友的沉默。
MLK
在过去的 3 个月里,我们已经看到了人工智能伦理领域的巨大变化,我认为我们应该深入思考我们所有人在对世界产生有意义的积极影响方面所能发挥的作用。这种成为人工智能伦理新贵的想法特别强大,我相信在 2021 年,这是帮助我们所有人创建更健康的生态系统的正确方式。
A.为什么这很重要
正如我在关于为什么 2021 年人工智能伦理需要公民能力的文章中所说的,我认为这是一个额外的附加条款,我们需要对这种能力采取行动。我们经常会遇到这样的情况,当我们看到不公正的事情发生在我们身边或发生在我们身上时,我们可以提高嗓门(尊敬地)指出它们。有时,由于担心我们和我们所珍惜的人的安全,我们会回避采取行动。但是,正如我们在开篇所看到的,有时这个决定的代价可能是巨大的。
以下是我认为我们需要成为暴发户的一些关键驱动因素:
- 警惕有好处
- 避开无知的面纱
- 被动也是一种姿态
1.警惕有好处
在我们有健全的法规和其他安全机制之前,我们需要提高警惕,并在谁有权以及何时指出不公正的问题上更进一步。
大赦国际发布的一个有趣的作品谈到拥有一个众包地图,显示城市中监控技术被发现的地方,这是体现这种方法的重要一步。这提高了我们的警惕性,并有助于我们成为有经验证据支持的后起之秀。当我们站起来要求改变时,这些证据为我们的论点增加了更多的实质内容。
2.避开无知的面纱
即使你认为这些事情中的一些目前并没有影响到你,不要忘记罗尔斯关于“无知之幕”的观点,在这个观点中,如果你不知道你会站在那些互动的哪一边,你会想象在一个世界中互动的规则和机制应该是什么。
从本质上说,这意味着即使你目前没有受到歧视,你也不知道将来事情会怎样发展。最好是做一个反对不公正的暴发户,即使这些不公正现在与你无关,这样当你不可避免地成为科技系统造成的其他形式的不公正的目标时,有人会支持你。
3.被动也是一种姿态
有些人可能会说,保持被动,听其自然,希望市场会自我修正,可能是解决这一问题的一种方法。一些人还认为,不采取积极的立场可以帮助他们避免争议,置身于所有这些混乱的问题之外。
但是,请记住,被动的姿态仍然是一种姿态,正如 MLK 的开场白所示,这将会引起他人的注意,并塑造他们对你是什么样的公民的看法。
B.如何着手此事
空谈是廉价的,行动才是一切!
所以,这就带来了一个问题,一旦我们同意扮演一个更积极的角色,成为一个新崛起的人是一个重要的想法,那么首先应该如何去做这件事。
以下是实现这一目标的一个很好的起点:
- 即使没有什么进展也要表现出来
- 找到你周围对这个主题感兴趣的人
- 与社区直接合作,而不是依赖代理人
1.即使没有什么进展也要表现出来
在积极支持正确的事情方面,缺乏进展往往是一个很大的阻碍和令人沮丧的因素。发展迟缓带来的疲劳和对真正利益的忽视甚至会让最坚定的支持者灰心丧气。然而,正如我在我的文章中概述的,为什么 2021 年的人工智能伦理需要公民能力,这些时刻对我们来说尤其关键,我们需要出现并试图产生影响。
在物理学中,有一个叫做限制摩擦的概念,它谈到了一个临界阈值,在这个阈值之上,需要施加一个恒定的力来使物体运动,在越过这个阈值之后,当一个人从静态摩擦域移动到动态摩擦域时,移动物体会变得稍微容易一些。
这些微小进展的时刻与限制摩擦的想法有很多相似之处,我对那些在这个领域工作的人的建议是,在似乎没有进展的时候,增加一点点额外的推力,让事情向前发展,在这个领域创造进展。
2.找到你周围对这个主题感兴趣的人
现在有很多地方性的和有背景的社区在谈论人工智能伦理的话题。虽然我们还没有针对所有人的有效发现机制,但如果你有一些同伴,成为人工智能伦理领域有效的后起之秀的旅程肯定会更容易。
蒙特利尔人工智能伦理研究所(Montreal AI Ethics Institute)及其学习社区(learning communities)和 T2 公共研讨会(public workshops)是结识世界各地志同道合者的绝佳方式。与社区分享你正在做的工作,作为一种提高兴趣的方式,邀请他们参与你的努力,分享你的时间和专业知识,以进一步推动他们的努力,这总是一个伟大的第一步。
3.与社区直接合作,而不是依赖代理人
这一点我怎么强调都不为过!
正如我在我的文章中提到的,为了实现负责任的人工智能,弥合“可信度差距”,有许多人正在做真正有意义的工作,但不幸的是,他们在当前的生态系统中是隐形的,因为我们将证书和荣誉视为我们应该邀请谁参加不同对话的代理。
当谈到与社区合作时,根据我们在蒙特利尔人工智能伦理研究所的丰富经验,我们发现获得洞察力的最有效方法是直接与面临算法系统不公正问题的社区合作,而不是依赖那些可能准确代表他们利益的代理人。
虽然实际去与各种社区交流需要大量的努力和时间,但这绝对是值得的,因为我们可以更全面地了解人们的利益,同时能够以有意义的方式解决这些问题,希望也能得到他们的参与和支持。
C.怎么办?
到目前为止,我们讨论的所有内容都为我们采取行动提供了强有力的理由和动力,但正如我们之前所说的,空谈是廉价的,没有行动什么都不是。那么我们到底应该怎么做呢?
以下行动为任何想要做出真正改变的人提供了一个很好的起点:
- 教育自己去理解其中的细微差别
- 寻找可以建设性地分享反馈的渠道
- 如果你周围还没有社区,帮助建立一个社区
1.教育自己去理解其中的细微差别
对于一个有效率的州来说,一个人必须首先教育自己对问题有一个细致入微和平衡的理解,这样为一个问题辩护时提出的论点才是实质性的。
这也有助于将补救工作引向一个方向,这将产生真正有所作为的变化,而不是可能会推迟一点对话而没有真正解决核心问题的表面变化。
自我教育的优势也将有助于你反击那些肤浅的措施,指出它们在你更深的理解下可能会失败。最终,这是一个很好的方式来推动人们在行动中承担更高层次的责任。
2.寻找可以建设性地分享反馈的渠道
成为新州并不意味着我们必须参与反对建设性方法的行动主义。我们正在寻求变革,这需要我们认识到,我们需要与现有的利益相关者和行为者合作,这样我们才能实施变革,而不是仅仅提出问题,然后不采取任何行动来帮助那些试图将这些建议付诸行动的人。
提供反馈的渠道,无论是从提出问题的人到负责将建议付诸实践的人,反之亦然,都需要是可访问的和透明的,以便在分享反馈和看到反馈被考虑和采纳的过程中,信任不会成为无意中的牺牲。
3.如果你周围还没有社区,帮助建立一个社区
正如我有机会在许多地方阐述的那样,特别是随着蒙特利尔人工智能伦理研究所的成立,当你踏上改变世界的旅程时,一个社区将非常重要。
这一切都始于一个想法的核心,但它要求我们也有能力战胜失败和挑战,因为它们将不可避免地出现。那时,有一个可以依靠的社区将是必不可少的。有大量的区域性和特定领域的社区正在致力于解决这些问题,但是如果你发现它们并不能完全解决你所看到的问题,那就去创建一个吧!作为奖励,请随时联系蒙特利尔人工智能伦理研究所团队,我们甚至可能在那里帮助你。
要阅读更多见解并了解伦理人工智能,你可以报名参加由蒙特利尔人工智能伦理研究所举办的人工智能伦理简报。
你也可以在这里找到更多关于我工作的信息——https://ATG-abhishek . github . io
在投资机器学习算法之前,先关注端到端的流程策略
原文:https://towardsdatascience.com/before-investing-in-machine-learning-algorithms-focus-on-end-to-end-process-strategy-c9b693865928?source=collection_archive---------36-----------------------
为什么数据科学产品经理应该在制定数据科学要求之前,围绕重新思考和重新设计流程/系统展开对话

Clark Van Der Beken 在 Unsplash 上拍摄的照片
企业明白投资人工智能以跟上加速发展趋势的好处。即使是多年来一直为自己能够仅凭“直觉”创造成功企业而自豪的商业领袖,也承认了数据驱动决策的力量。无论组织是想建立自己的全栈数据科学团队,还是决定与人工智能顾问合作,企业领导人都很清楚实施机器学习算法所涉及的高成本和时间。因此,大多数公司都与管理顾问合作,以确定可以通过人工智能转变的关键业务领域,并努力在这些有影响的流程中引入数据科学建议。这种方法比在整个组织中引入机器学习模型更安全、更具成本效益。
业务部门的发现会议和创新日有助于关注业务中的关键挑战,然后数据科学产品经理将负责制定要求并与数据科学团队合作,以自动化和优化流程,同时努力实现精确的产出。大多数数据科学产品经理来自分析或工程背景,他们确实拥有如何与数据科学团队合作交付正确解决方案的智慧。但是这最终也是一个漏洞,因为产品经理热衷于解决方案,并且更经常地假设业务团队已经完成了评估整个过程的基础工作。对于大多数来自工程背景的产品经理来说,总有一个声音在他们的大脑中窃窃私语,讲述推断正确逻辑的所有方法,即使在需求阶段的早期,数据也需要解决问题。抛开技术智慧的提示,数据科学产品经理应该敞开心扉,深入了解业务流程。数据科学产品经理应该从构建端到端的流程流开始,同时在研究解决方案之前考虑互连的系统和流程。仅仅专注于设置并坚持着陆,而不了解中间的所有线程,将扼杀组织从完全采用数据科学成果中获得的好处。
例如,每个零售商都同意,为了在竞争中保持领先,必须使用先进的分析模型,将历史数据与影响消费者行为的所有外部变量相融合,以构建创新和个性化的解决方案。数据科学团队进行了广泛的研究,以分析市场洞察和交易数据,从而为正确的时间和地点推荐正确的产品。但是,为了充分发挥数据科学模型的潜力,产品经理不应该仅仅从商业化的角度来看待这一需求,还应该花时间了解下游供应链的约束。有时,满足高度本地化需求的物流成本超过了个性化产品带来的收入增长。如果产品经理从构建流程图开始,这将有助于从流程中所有相互关联的步骤中产生影响。在这个阶段,如果产品经理希望做出数据驱动的决策,他们应该与业务部门就重新思考和重新设计他们的一些流程进行坦诚的对话。在进行这些对话之前,产品经理应该与数据分析师合作,从分析中创建估计的 ROI,以推动他们的观点。有时,这可能涉及到后退一步,为每个地区提供超定制的产品组合,而不是选择建立最佳的客户群,这有助于在本地化和满足供应链约束之间建立平衡。但是,通过进行端到端的流程分析,并在需求阶段就执行约束进行早期讨论,数据科学产品经理可以确保最终产品被无缝采用和利用。
作为产品经理,最初的问题从来不是“我该如何解决这个问题?”,而是“我们试图解决什么”,更重要的是“你为什么需要这个?”。有时,业务团队如此习惯于执行像第二天性这样的日常任务,以至于他们不希望增强例行程序,这些请求主要是围绕新的挑战。把事情放在上下文中,可能有一个全渠道包优化的请求;一种有效构建最佳装箱组合的算法,用于运送到配送中心或商店。借助 COVID,大多数零售商可能正在寻找一种有效的解决方案来满足地理层面的全方位需求,同时还要考虑物流成本。但是在这个流程的下游可能有其他核心活动,它们使用过时的工具,无法处理复杂算法的输出。在涉及多个领域的情况下,很难保持项目目标的同步。在实现分析输出之前,需要首先更新下游系统和流程。在任何流程重新设计之前构建高级分析解决方案都不会显著节约成本或增加收入,数据科学投资也将变得毫无用处。在投资解决方案之前,澄清当前流程和现有系统的效率。
在流程映射阶段之后,数据科学产品经理在工程或分析方面的优势以及对细节的执着会大放异彩。业务团队往往会忽略任务之间的数据或系统依赖关系,产品经理可以在流程图上叠加一个数据流图,以揭示可能在项目后期突然出现的技术挑战。
总之,数据科学产品经理应该专注于彻底理解业务流程。流程图不应止于分析结果的获取,还应包括通向最终客户的所有系统/流程。在这个阶段之后,数据科学产品经理可以利用他们的工程背景,通过缩小技术细节和解决执行中可能出现的复杂性,为需求添加最后的润色。数据科学产品经理应该在需求阶段扮演业务客户的角色,同时在之后带来分析视图,以揭示如果一个领域要成功实现数据科学解决方案,需要进行的流程/系统重新设计。
在你开始一个数据科学项目之前,问你的用户一个问题
原文:https://towardsdatascience.com/before-you-start-a-data-science-project-ask-your-users-this-one-question-c0b1159f79df?source=collection_archive---------38-----------------------
行业笔记

低保真度原型草图
一个好的数据科学家会问用户很多关于他们可能构建的产品的(商业)目的的问题。通过在执行任何技术工作之前与最终用户交谈,我已经能够在一些项目上节省数周的时间。
在数据准备、数据工程或模型建立之前,问你的用户“你将如何处理最终的输出?”更进一步,向他们展示带有虚假数据或可视化效果的低保真度输出原型。

愤怒客户拓展项目的低保真度原型
我将给出我参与的一个示例项目的概要。该企业有一个模糊的想法,即拓展到客户有一个未解决的愤怒的电话。企业希望用户满意,客户满意度是一个关键的绩效指标,可能会对下游收入和奖金产生影响。此外,如果客户提出正式投诉,则需要提交法规文档,这将自动让公司付出 100 美元的成本以及更多员工时间的成本。
一些同事立即开始了一些复杂的数据工程,以获取大量的呼叫中心记录,并将呼叫与我们数据仓库中的客户信息联系起来。我们开始讨论自然语言处理(NLP)步骤的效果如何,并手动检查通话记录,看看 NLP 摘要是否恰当地将通话标记为愤怒;一些电话开始时很生气,但后来客户看起来很好。但在我们进一步深入之前,我们会见了我们的同事,他们将主动接触这些愤怒的客户,这是他们以前没有做过的任务。当展示低保真度原型时,他们有许多问题和需求。
- 我如何知道客户为什么生气?
- 我能看看他们最近的通话记录吗?
- 我可以查看客户的订单历史吗?
- 我需要客户的电话号码、电子邮件地址、联系地址和账单地址
- 我怎么知道别人是否没有给他们打电话?这些数据会与呼叫中心运营团队协调吗?
- 你能优先考虑金钱数额和愤怒分数较高的人吗?
- 这个报告每天都会来吗?我们将如何接收它?在内部应用程序中?在 Excel 中?
- 每天有多少人会出现在这个名单上?我们认为,在我们习惯这种方式之前,我们不会有时间每天联系 10 个以上的人。
最终,我们为我们的同事在输出中添加了一些东西,而不太关注自然语言处理的性能。

金融风险模型低保真度原型
对于另一个项目,公司希望我们根据自己的历史数据样本评估一些供应商财务风险模型。我们已经有了其中一个模型的基础设施和合同;企业希望判断是否值得努力潜在地转换模型。我们向他们展示了一个带有假数据的表格,显示了输出的样子(即低保真度原型)。这引发了一些问题和评论:
- 这个分析的时间段是什么?
- 什么是人口纳入和排除?
- 我们更换供应商的标准是什么?我们能否将平均绝对误差的差值乘以我们的总体,以获得潜在的节约金额?
- 平均绝对误差最合适吗?难道我们对异常值不敏感吗,均方差会更合适吗?或者,我们是否应该在评估中包括多个指标,例如还包括 r 的平方和实际正负 5%以内的人员百分比?
- 我们是否应该提前与 IT 部门沟通,询问他们实施新的财务风险模型可能需要多少工作和时间?
- 我们今天如何使用金融风险模型?它的性能有多重要?我们是否只需要一个“在大概范围内”的模型?
- 这些供应商的未来改进路线图是什么样的?所有的供应商似乎都准备在未来几年取得成功吗?
原型帮助我们数据科学家巩固了我们的方法,并帮助经理们更多地考虑他们所要求的。
尝试为你的下一个项目创建一个低保真度的原型。保真度低意味着你应该能很快做到;它可能看起来不太好,但用户应该有一个好主意。我喜欢在纸上做可视化草图,或者用一些假数据在 Excel 或 r 中创建表格和图表。
数据转换的初级解释
原文:https://towardsdatascience.com/beginner-explanation-for-data-transformation-9add3102f3bf?source=collection_archive---------11-----------------------
数据转换的基本概念

克里斯·劳顿在 Unsplash 上的照片
如果你喜欢我的内容,并想获得更多关于数据或作为数据科学家的日常生活的深入知识,请考虑在这里订阅我的时事通讯。
介绍
什么是数据转换?—我很确定任何学习数据和统计学的人都会在某个时候碰到这些术语。数据转换是一个概念,指的是应用于数据集中每个值的数学函数,将该值替换为新值。在数学方程式中,我们可以用下图来表示。

作者图片
如果我用更简单的解释来说,数据转换是通过数学方程式将你的数据转换成另一种数据的过程。
为什么我们需要做数据转换?转换数据有什么好处吗?从统计学的角度来看,原因是:
- 转换数据允许您满足某些统计假设,例如,正态性、同质性、线性等。
- 数据转换将不同列中的值进行缩放以进行比较,例如,以美元为单位的薪金(范围从 100 到 10000)和以千克为单位的体重(范围从 20 到 100)。
数据转换有助于获得新的见解并清除数据中的干扰。但是,使用数据转换方法需要您根据转换后的数据理解转换效果、含义和结论。在我看来,只有在必要的情况下,并且你明白你的转换目标时,你才进行数据转换。
数据转换的方法有哪些?根据 McCune 和 Grace (2002)在他们的生态群落分析书中所述,这些方法是:
- 单调变换
- 关系化(标准化)
- 概率变换(平滑)
如果上面的术语对你来说很陌生,没关系。让我们更深入地探索所有这些方法!
我要说的一个免责声明是,在进行数据转换时,您需要非常小心,因为您最终会得到一个转换后的数据,它不再是您的原始数据。了解数据转换的目的是什么,并报告您已经完成的任何数据转换。
单调变换
什么是单调变换?这是一种数据转换方法,它将数学函数应用于每个独立于其他数据的数据值。单词 monotonic 来自方法 procedure,它转换数据值而不改变它们的等级。用一个更简单的术语来说,单调变换改变了你的数据而不依赖于其他数据,并且不改变它们在列中的排名。
著名的单调变换函数的一个例子是对数变换或对数变换。顾名思义,对数转换通过对每个数据值应用对数函数,将数据值转换为对数值。许多变量遵循对数正态分布,这意味着值在对数变换后将遵循正态分布。这是对数变换的好处之一——遵循正态假设,或者至少接近正态假设。
在数学术语中,对数变换用下面的等式表示。

作者图片
让我们用样本数据试试对数变换法。我会使用来自 Kaggle 的关于工科毕业生薪水的数据。首先,将数据读入数据框。
import numpy as np
import pandas as pd
import seaborn as snsdata = pd.read_csv('Engineering_graduate_salary.csv')
该数据集中有 33 个要素,但我不会使用所有可用的数据。这个数据是为了知道是什么影响了工资,那么我们就试着把工资数据分布可视化吧。
sns.distplot(data['Salary'])

作者图片
正如我们在上面的图像中所看到的,工资特征不是正态分布的。让我们应用对数变换将数据转换为正态分布。
#Salary Log Transformation with base 10
data['log10_Salary'] = data['Salary'].apply(np.log10)
通过一行代码,我们将数据转换为以 10 为底的对数值。让我们再一次想象它。
sns.distplot(data['log10_Salary'])

作者图片
工资数据现在更接近正态分布。我们可以尝试使用正态性检验来检验正态性,比如夏皮罗检验,但我不会在本文中解释这个概念。
数据转换的另一个目的是从数据关系中获得更好的洞察力。比如我只对大学的 GPA 和工科毕业生的工资之间的关系感兴趣。让我们试着用散点图把它形象化。
sns.scatterplot(x = 'Salary', y = 'collegeGPA', data = data)

作者图片
我正试图将薪水和大学 GPA 之间的关系可视化,结果我得到了一个没有太多洞察力的数据集群。这是我们可以应用对数变换来重新调整数据以获得更好清晰度的时刻之一。
sns.scatterplot(x = 'log10_Salary',y = 'collegeGPA', data = data)

作者图片
薪水和大学绩点的关系现在清晰多了,绩点和薪水之间没有太大的关系。尽管如此,我们现在做的是可视化日志值与未缩放特征之间的关系。让我们试着把大学的 GPA 特征也转换一下,并把这种关系形象化。
data['log10_collegeGPA'] = data['collegeGPA'].apply(np.log10)
sns.scatterplot(x = 'log10_Salary',y = 'log10_collegeGPA', data = data)

作者图片
与我们在没有任何数据转换的情况下将其可视化时相比,现在这种关系非常明显。这是进行数据转换的另一个好处。
这是有益的,特别是当您需要向业务用户展示数据关系时,但是您的数据是聚集的,因此很难获得任何洞察力。
单调变换有许多方法。不过,我不会在本文中解释它们,因为我计划撰写另一篇文章来概述其他单调转换方法。重要的是你明白什么是单调变换。
关系化(标准化)
相对化或标准化是一种数据转换方法,其中列或行标准转换数据值(例如,最大值、总和、平均值)。它不同于单调变换,在单调变换中,标准化不是独立的,而是依赖于另一个统计量。
当出现不同单位的属性时,您通常需要标准化,并且您的分析需要具有相似单位的数据。分析示例是聚类分析或降维,它们依赖于数据距离。
著名的标准化方法是 Z 分数标准化,通过特征的平均值和标准偏差将数据转换成比例。转换后的特征均值约为 0,标准差约为 1。Z 得分标准化转换后,转换后的数据本身将被称为 Z 得分。在数学符号中,它用下面的等式表示。

作者图片
其中 x =特征值,μ =特征均值,σ =特征标准差。
需要记住的一点是,尽管 Z 分数标准化将您的数据转换为遵循正态分布标准,但要素分布本身并不一定遵循正态分布。毕竟,Z 值标准化的目的是重新调整要素的比例。
让我们用一个数据集示例来尝试 Z 分数标准化。首先,我们需要导入我们想要使用的包。
#Import Z-Score Standard Scaler from the Sklearn package
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
比方说,我想重新调整上一个例子中的工资数据。这是我们的原始数据和统计。
data['Salary'].head()

作者图片
data['Salary'].agg(['mean', 'std'])

作者图片
我们的数据单位是万,工资平均值如上图所示。然后,我们使用之前导入的缩放器将数据转换为 Z 分数,但首先,我们需要拟合缩放器(这是获取特征的平均值和标准差的过程)。
scaler.fit(np.array(data['Salary']).reshape(-1, 1))
如果您想再次检查我们的定标器是否获得了正确的平均值和标准偏差,我们可以使用下面的代码访问该值。
print('Salary Mean', scaler.mean_)
print('Salary STD', np.sqrt(scaler.var_))

作者图片
结果略有不同,但几乎可以忽略不计。让我们将工资数据转换成 Z 分值。
data['Z_Salary'] = scaler.transform(np.array(data['Salary']).reshape(-1, 1))data[['Salary', 'Z_Salary']].head()

作者图片
我们现在可以看到原始数据和转换后的数据之间的差异。当您的数据小于平均值时,Z 得分为负值,反之亦然。让我们检查一下转换后的数据统计。
data['Z_Salary'].agg(['mean', 'std'])

作者图片
可以看到,转换后的数据均值接近 0,标准差接近 1。使用 Z 分数标准化进行缩放的每个要素都将遵循相同的标准。
Z 分数标准化还有另一个好处,那就是异常值检测。我不会详细解释,但基本上,离群点检测概念与经验法则有关。任何大于 3 或小于 3 的 Z 值都被视为异常值。
像单调转换一样,关系化或标准化也有许多方法,但这将是另一篇文章来详细讨论它。
概率变换(平滑)
概率变换或平滑是一种数据变换过程,用于消除数据中的任何噪声,以增强数据中最强的模式。
这种转换对异类或有噪声的数据特别有效。平滑过程允许您看到以前看不到的数据模式。尽管在解释平滑过程的结果时需要小心,但它可以向您显示一个趋势,即使是从随机数据看也是可靠的。
常用的平滑技术是核密度估计(KDE) 平滑。这种技术基本上是通过估计基于有限数据样本的总体随机变量的数据概率函数来平滑数据。
让我们尝试平滑数据样本以获得数据模式。例如,我想看看计算机编程数据的分布。
sns.distplot(data['ComputerProgramming'], kde = False)

作者图片
这里可以看到宁滨数据模式,但是我们可能希望消除任何可能会分散我们对真实模式的注意力的干扰。让我们使用 KDE 平滑来获得该模式。
sns.distplot(data['ComputerProgramming'], hist = False)

作者图片
通过平滑技术,我们使用数据的概率函数估计将数据转换成密度值。正如我们所看到的,我们的数据中有两个峰值,一个在 0,另一个在 500 附近,后者的峰值最高。
这种模式只有在我们平滑数据时才能看到。你可能会问,平滑模式似乎显示了不同于宁滨模式的模式。还记得平滑的目的吗?就是消除数据中的噪声,增强最强的模式。此外,KDE 根据样本数据估计人口中的概率函数,这意味着平滑模式是对人口中可能发生的情况的估计。
仍然有许多概率变换或平滑方法可以学习,但我会把它留到下一次。平滑的重点是转换数据以消除任何噪声并增强模式。
结论
数据转换是数据科学家应该知道的一项技术,因为它有好处。根据 McCune 和 Grace (2002)在他们的生态群落分析书中所述,有 3 种数据转换方法。它们是:
- 单调变换
- 关系化(标准化)
- 概率变换(平滑)
希望有帮助!
访问我的LinkedIn或 Twitter 。
如果您没有订阅为中等会员,请考虑通过我的介绍订阅。
初学者友好的数据科学项目接受贡献
原文:https://towardsdatascience.com/beginner-friendly-data-science-projects-accepting-contributions-3b8e26f7e88e?source=collection_archive---------33-----------------------

弗雷迪:维克多·福加斯在 Unsplash 上拍摄的照片。
想为开源软件做贡献吗?这里有几个地方可以开始。
TLDR:看看支持数据科学家的四个开源软件项目,包括广受欢迎的熊猫,新兴的数据分析师,被称为人物分析数据(技术上是开放数据)的 R 包,以及熊猫概况。还讨论了支持开源软件项目的原因,包括让世界变得更美好的机会以及增强或构建知识和技能的机会。
更新:本文的更新版本(2022 年 5 月)现已发布:
简介和动机
成为数据科学家的最佳方式是成为一名数据科学家。提高数据科学水平的最好方法是练习、练习、再练习。
为开源软件项目做贡献至少有三个明智的理由:
- 你可以为他人创造一个更美好的世界。
- 为开源项目做贡献将有助于你学习。
- 为开源项目做贡献也是扩展你的专业组合的好方法。
开源软件项目是那些向公众开放代码的项目。每个项目的具体工作方式是不同的。
例如,Python 是在开放软件倡议(OSI)下许可的开源编程语言。Python 软件基金会管理 Python 的开发。为 Python 做贡献不是初学者的命题。
数据科学家熟悉的另一个开源项目是 Pandas。熊猫的作者在 GitHub 上解释说,“欢迎所有的贡献、错误报告、错误修复、文档改进、增强和想法。”
如果你是一名数据科学家,并且希望让世界变得更美好,我建议你考虑为开源项目做一点或多点贡献。
本文确定了四个开源软件项目,它们为初级和中级数据科学家提供了机会。这些项目包括广受欢迎的熊猫,一个新兴的数据列表,一个被称为人物分析数据(技术上公开的数据)的 R 包,以及熊猫档案。
熊猫
一想到要为一个像熊猫这样突出和广泛使用的项目做贡献,可能会令人生畏。不要烦恼。熊猫的贡献者和维护者是受欢迎的人群。
因为有很多用户贡献和报告熊猫的问题,所以有一些不需要写代码的“贡献”方式。
例如,你可以在 GitHub 上浏览问题跟踪器。找到一个你感兴趣的问题。看看您能否重现该问题。无论您能否重现该问题,请务必在问题跟踪器上发布您的努力和结果。
重现问题时,您可能会发现原因。您可能不知道如何消除原因,但如果您发布您所了解的内容,将有助于其他人纠正问题。要了解更多关于为 Pandas 做贡献的信息,请参阅 Pandas project GitHub repository 的 ReadMe.md.
成为数据科学家的最佳方式是成为一名数据科学家。
数据列表
根据其 twitter 简介,Datasist 是一个“用于简单数据分析、可视化和建模的开源 Python 库。”这个项目有投稿指南。瑞星奥德瓜(Twitter 上的)是这个项目最初和主要的编码者。
在投稿指南中,Datasist 强调了文档的重要性。如果你相信高质量文档的重要性,并且你也对编写文档感兴趣,这个项目将欢迎你的贡献。通过增强或改进文档来为项目做贡献也算贡献。文档贡献和贡献新的代码或特性一样重要——这两种贡献类型以不同的方式计算,但是它们确实很重要。
如果您不熟悉 Datasist,它是一个可以让您更快地进行数据探索和建模的库。例如,下面的代码显示了如何将第 4–7 行(四行)重构为第 13–14 行(两行):
人员分析数据
这个项目是一个特例。它不是一个软件项目。相反,它是公开可用的数据。数据科学家可以将这些数据用于测试、培训和其他项目,这些项目可以从备用数据集的使用中受益。
数据来源于 人物分析 中的回归建模手册。作者通过可从综合 R 档案网 (CRAN)获得的 R 包提供该书的数据。R 包使得在 R 中加载这些数据变得很容易。
这个 R 包已经成熟,可以移植到 Python、Stata、Julia、SAS、Matlab 等。也许用一个宏来抓取数据并把它放入 MS Excel 将是聪明而有用的。这是一个良好的开端。把下面变成一个包。
如果你捡到这个,请告诉我。我愿意合作。我还建议在继续之前和作者基思·麦纽提(在 LinkedIn 上)聊一聊。得到他的祝福是有意义的。他已经公开讨论了移植该作品的前景。
熊猫-侧写
这个项目很好地利用了 GitHub 的赞助计划。至少有七个赞助商,这个项目得到了很好的维护。为了支持贡献者,这个项目有一个组织良好的贡献指南。该项目还有一个经常光顾的松弛频道。
初学者或中级数据科学家可以做的贡献的一个例子就是这个,它需要更新包的教程。starter 的另一个贡献是解决这个问题,其中包括添加参数来调整饼图的颜色。
如果您还不熟悉这个包,它可以减少您花费在探索性数据分析上的时间。实现只需要五行代码(如下所示)。这五行代码的输出摘录见下文。

图片鸣谢:作者实现熊猫——剖析报告(节选)。
对熊猫概况的深思熟虑的贡献将有可能改善你和他人的工作。保证。
https://adamrossnelson.medium.com/membership
感谢阅读
如果你喜欢我要说的话,可以在:adamrossnelson.medium.com找到更多。
感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelson| LinkedIn:亚当·罗斯·纳尔逊 |脸书:亚当·罗斯·纳尔逊。
初学者友好的虚拟环境管理— Anaconda + PyCharm
原文:https://towardsdatascience.com/beginner-friendly-virtual-environment-management-anaconda-pycharm-36178e20129f?source=collection_archive---------22-----------------------
轻松设置您的第一个虚拟环境

杰西卡·路易斯在 Unsplash 上的照片
Python 是趋势语言,因为它是几个专业领域中最流行的选择,如数据科学和机器学习。因此,许多人选择 Python 作为他们学习的第一门编程语言。对于初学者来说,虚拟环境是一个让他们相当困惑的概念。在这篇文章中,我想以初学者友好的方式回顾一下它是什么以及如何设置它。
虚拟环境
Python 是开源的,允许整个社区开发和发布他们的 Python 程序,通常是以框架、库或包的形式。Python 发展很快,从 2 到 3,已经看到了几周前正式发布的 3.10。Python 的第三方包也发展得非常快。原因很简单——越来越多的人在使用 Python,他们正在努力开发有益于其他 Python 程序员的工具。
然而,这是有代价的——用最新的 Python 和第三方包来保持项目的进度是很昂贵的。它们并不总是向后兼容的。例如,您的项目 A 使用 Python 3.6 和包 v1.2 版)。但是,你有另一个项目 B,它使用 Python 3.8 和包 a (v2.2)。很显然,如果两个项目都想留在同一台电脑上,你就不能在你的电脑系统上使用默认的 Python,还有其他的包,都是设置成某个版本的。
因此,您必须适应这些具有冲突的 Python 和包需求的项目。这是为您的项目创建虚拟环境的简单原理。

项目之间的冲突需求(图片由作者提供)
本质上,每个虚拟环境都可以被概念化为你的计算机系统中的一个独立的盒子,如上图所示。在这个框中,您有了所需的 Python 版本和项目所需的包。这些框是独立的,这样您在一个项目中所做的不会影响其他项目。
我们总是建议您为您的项目创建不同的虚拟环境,即使目前不同的项目可能共享一个 Python 版本和包。然而,当您想更新 Python 版本和一个项目的一些包,而不是其他项目时,机会就来了。不兼容将会发生,您将不得不再次重新配置项目。因此,我们应该从正确设置的虚拟环境开始我们的任何项目。
Anaconda 用于虚拟环境管理
我希望你现在明白什么是虚拟环境,以及为什么你想为你的项目创建一个虚拟环境。现在,问题来了,我们如何管理虚拟环境。对于初学者,我认为使用命令或终端不是您最喜欢的选择。因此,我将为您提供一个点击式解决方案。我使用最多的工具是 Anaconda ,这是数据科学和机器学习社区中虚拟环境管理最常见的选择。

蟒蛇安装者(链接:https://www.anaconda.com/products/individual#Downloads
如图所示,Anaconda 支持主要的操作系统,您应该能够找到您需要的操作系统。完成下载后,只需按照提示进行安装,这应该很简单。
py charm——最大化生产力的 Python 编辑器
Python 编程有多个编辑器,比如 Visual Studio Code,Vim,Jupyter Notebook,当然还有 PyCharm。在这些选择中,PyCharm 是我的最爱,因为它几乎不需要设置。

下载 PyCharm(链接:https://www.jetbrains.com/pycharm/download/#section=mac)
您选择与您的操作系统相匹配的安装程序。社区版免费使用。值得注意的是,如果你在教育或学术机构工作,你也可以自由使用专业版。对我来说,因为我在一所非营利性的州立大学工作,所以我可以自由使用专业版。
我认为在您的计算机上安装 PyCharm 应该没有问题。所以,我们继续吧。
使用 Conda 虚拟环境的新项目
在您能够运行 PyCharm 之后,您可以创建一个项目,您将看到如下所示的内容:

皮查姆的新项目
你要注意的一件事是,你要用 Conda 创建一个新的环境,尽管还有其他一些选项。如您所见,您可以自由选择想要的 Python 版本。有一个复选框“对所有项目都可用”,通过检查您可以使用哪个解释器(您可以认为它是您的项目运行的 Python 版本)。
在项目中,右键单击项目目录,选择 New,从这里可以创建一个新的 Python 文件,假设它的名字是test_file.py。需要注意的一点是,在右下方,你会看到我们项目的解释器被设置为 Python 3.9 (pythonProject)。

显示解释器设置
安装/删除软件包—点击
对于初学者来说,一个方便的特性是 PyCharm 会通过提供适当的提示来尝试安装缺失的包。假设我们想在 Python 文件中使用熊猫。因为我们还没有安装它,您应该会看到一个错误,如下所示。

导入丢失的包时出错
你移动你的鼠标到软件包上,弹出菜单可以建议你安装软件包。你只需点击“安装包熊猫”并等待一会儿,你会看到熊猫安装,没有更多的错误指示。
要查看安装了哪些包,可以点击底部的“Python 包”标签。你会发现熊猫现在确实在名单上。

Python 包
在搜索框中,可以输入想要安装的 Python 包,比如 matplotlib。您将看到显示了可用的选项。你可以选择正确的安装。此外,您可以选择不同于最新版本的版本。

手动安装软件包
另一方面,你也可以删除一个包,通过输入包来显示它的信息,正如你在下面的截图中看到的。

手动删除包
使用终端
当您熟悉终端时,您可能会发现使用终端安装软件包更容易。用 PyCharm 也很方便。您只需点击底部的终端选项卡。应该引起您注意的一件事是,您会注意到在提示符前面的括号中有一个名称。
(pythonProject) computer_name:pythonProject ycui1$
如果你记得的话,那是现任翻译的名字。在 conda 的术语中,它是虚拟环境的名称。因此,您所做的一切(例如,软件包的安装)都将发生在虚拟环境中。
一些常用命令如下所示。
**Installation**
*# use conda*
conda install package_name
*# use pip*
pip install package_name**Deletion**
# use conda
conda remove package_name
# use pip
pip uninstall package_name
当然,使用终端还可以做许多其他事情。关于使用终端进行虚拟环境管理的详细说明,请参考我以前的文章:
</8-essential-commands-to-get-started-with-conda-environments-788878afd38e>
结论
在本文中,我们学习了如何使用 Anaconda 和 PyCharm 为我们的项目建立一个虚拟环境,并学习了最基本的操作,比如在环境中安装和删除包。
最后提醒一下,为每个项目建立一个单独的虚拟环境总是一个好的做法。
感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?通过使用我的会员链接支持我的写作(对你没有额外的费用,但是你的一部分会费作为奖励由 Medium 重新分配给我)。
使用 PyTorch Lightning 的可变自动编码器(VAE)初学者指南
原文:https://towardsdatascience.com/beginner-guide-to-variational-autoencoders-vae-with-pytorch-lightning-13dbc559ba4b?source=collection_archive---------5-----------------------

凯利·西克玛在 Unsplash 上的照片
这篇博客文章是一个迷你系列的一部分,该系列讨论了使用可变自动编码器构建 PyTorch 深度学习项目的不同方面。
第 1 部分:数学基础与实现
第 2 部分:用 PyTorch Lightning
增压第 3 部分:卷积 VAE、继承与单元测试
第 4 部分 : Streamlit Web App 与部署
autoencoder 是一种无监督的神经网络架构,旨在寻找数据的低维表示。在这篇博客文章中,我将介绍 variable Autoencoder 的一个简单实现,它是 auto encoder 的一个有趣的变体,允许生成数据。
我不能创造的东西,我不理解——理查德·费曼
当我开始这个项目时,我有两个主要目标:
1。 练习将数学概念翻译成代码
使用预先构建的模型和常用的神经网络层只能做到这一步。将数学方程翻译成可执行代码是一项重要的技能,在学习如何使用深度学习库时,这是一个非常好的实践。实现像 VAE 这样的简单架构对于理解实验室新出的最新模型大有帮助!
2。 学习 PyTorch 闪电
PyTorch 闪电一直是我想学很久的东西。它是 PyTorch 的一个非常有用的扩展,极大地简化了训练模型所需的大量过程和样板代码。利用这个项目作为学习 PyTorch Lightning 的平台,帮助我在实习中有信心将其应用到其他项目中。
变分自动编码器和表示学习
在浏览代码之前,我们首先需要了解自动编码器是做什么的,以及为什么它非常有用。自动编码器通过学习数据的低维表示来工作,并尝试使用该低维数据来重新创建原始数据。
对于这个项目,我们将使用 MNIST 数据集。每个图像为 28×28 像素宽,可以表示为 784 维向量。正如大多数图像所预期的那样,许多像素共享相同的信息,并且彼此相关。这也意味着这些像素中的信息在很大程度上是冗余的,可以压缩相同数量的信息。数据的这种压缩形式是相同数据在更小的向量空间中的表示,该向量空间也称为潜在空间。给定一个特定的数据集,自动编码器试图找到最能反映底层数据的数据的潜在空间。

自动编码器架构—作者图片
- 编码器
- 解码器
- 潜在空间/瓶颈
- 重建损失
让我们看看自动编码器是如何为单个数据点工作的。首先,编码器部分试图将图像中的信息强行送入瓶颈。从数学上讲,这可以看作是从 R⁷⁸⁴到 r·⁴(瓶颈维度)的一个非常复杂的函数。维度低得多的瓶颈确保了信息将被压缩。接下来,解码器尝试使用该压缩信息来重建原始数据。根据压缩的潜在表示,解码器试图重建原始数据点。正如预期的那样,重建将不会是相同的,并且模型将基于原始数据和重建数据之间的差异而受到惩罚。对于普通的自动编码器,损失函数将是 L2-诺姆损失。最终,经过训练后,编码器应该能够将信息压缩成仍然有用的表示形式,并保留原始数据点的大部分结构。
可变自动编码器
既然我们已经了解了自动编码器是做什么的,让我们看看它们不太确定的表亲变分自动编码器(VAE)。vae 通常用于数据生成,而不是数据压缩。由于这一关键差异,架构和功能与普通的自动编码器略有不同。普通自动编码器的问题是数据可能被映射到一个不规则的向量空间。不规则的潜在空间降低了模型很好地推广到看不见的例子的能力。做到这一点的一种方法是执行正则化,这可以防止过度拟合,并在模型具有异常结构时惩罚模型。这平衡了模型压缩信息的能力和生成新数据的能力。

不规则的概率分布可能包含解码器性能较差的“口袋”,因为很少有例子被映射到该区域——按作者的图像
VAEs 不是将信息编码成向量,而是将信息编码成概率空间。这意味着,我们假设数据是从一个先验概率分布中产生的,然后尝试学习如何从这个概率分布中推导出数据。这个概率分布将是一个没有协方差的多元正态分布(N~(μ,σ))。这允许潜在的概率分布由 2 个 n 大小的向量来表示,一个用于平均值,另一个用于方差。

VAE 建筑——作者图片
我们先来看一下前传。数据点通过编码器,但现在将被编码成两个矢量,而不是一个。这两个向量定义了一个概率分布,我们可以从这个概率分布中取样。从这个分布中取样给我们一个数据点的潜在表示。然后,该表示通过解码器获得重新创建的数据点。
VAE 正规化
如前所述,VAE 的另一个重要方面是确保潜在空间的规律性。在此之前,让我们先定义一些术语:
- 先验— P(Z) 先验表示所有数据的底层分布。先验通常是标准正态分布 N(0,I ),因为它简单且高度规则。
- 后验— P(X|Z) 后验表示给定特定数据点的条件分布,本质上,这是数据点被编码成的分布。后验是 N(μ,σ)的正态分布,其中σ是对角协方差矩阵。
为了正则化后验分布,我们分配一个代价函数,惩罚模型偏离先验分布。这个成本函数是 Kullback-Leibler 散度(KL-Divergence ),它度量两个概率分布之间的差异。

连续概率分布的 KL 散度—维基百科
对于许多分布,积分可能难以求解,但对于一个分布(先验)是标准正态而另一个分布(后验)有一个对角协方差矩阵的特殊情况,KL-散度损失有一个闭合解。

高斯和标准高斯之间的 KL 散度—维基百科
当训练 VAE 时,损失函数由重建损失和 KL 发散损失组成。KL-Divergence 的正则化确保后验分布始终是正则的,并且从后验分布进行采样允许生成有意义和有用的数据点。
代码段
现在让我们进入代码,看看 PyTorch 中的一切是如何组合在一起的!
初始化
初始化相当简单,编码器和解码器本质上与普通自动编码器的架构相同。主要区别在于,有两个额外的层将瓶颈转化为μ和σ向量。在这种情况下,这一层没有压缩,但这是一个可以调整的设计选择。
重新参数化技巧
实施 VAE 模型的另一个基本步骤是重新参数化技巧。如果仔细观察架构,从μ和σ向量生成潜在表示涉及采样操作。采样操作的问题在于,它是一个随机过程,梯度不能反向传播回μ和σ矢量。

将 x 解构为确定性部分μ和σ以及随机部分 z
⊙ —逐元素乘法运算符
为此,我们利用了重新参数化技巧,它允许我们分离操作的随机和确定部分。其工作原理是,我们从标准正态分布 N(0,I)中进行采样,并使用μ和σ矢量对其进行变换。
总的来说,这允许对μ和σ向量进行梯度更新,这将允许 VAE 的编码器层从训练过程中学习。
把所有的东西放在一起!
正向传递现在只是编码和解码步骤,其间有重新参数化/采样操作。
需要注意的一件重要事情是,数据被编码为log_var而不是variance。log_var矢量是由许多线性图层生成的,因此,矢量的值将从[-∞,∞]开始。由于方差不能为负,我们取指数,这样方差将有一个合适的范围[0,∞]。
在下一部分,我们将看看 PyTorch Lightning 如何简化整个过程,并更详细地探索模型及其输出(插值)!
请随意查看 GitHub 上的完整代码,非常感谢您的任何反馈!
VAEs 入门指南 第二部分
github:https://github.com/reoneo97/vae-playground
领英:https://www.linkedin.com/in/reo-neo/
有用链接:
(1)了解变分自动编码器(VAEs)
非常有用的资源,尤其是如果你想深入研究 VAEs 的数学方面。
(2)变型自动编码器——Arxiv 洞察
精心制作的视频介绍了 VAE 的基本知识和机制,同时在结尾部分介绍了许多关于 VAEs 的最新研究。
https://www.youtube.com/watch?v=9zKuYvjFFS8
使用 PyTorch Lightning 的可变自动编码器(VAE)初学者指南(第 2 部分)
原文:https://towardsdatascience.com/beginner-guide-to-variational-autoencoders-vae-with-pytorch-lightning-part-2-6b79ad697c79?source=collection_archive---------14-----------------------

由马克-奥利维尔·乔多因在 Unsplash 上拍摄的照片
这篇博客文章是一个迷你系列的一部分,该系列讨论了使用可变自动编码器构建 PyTorch 深度学习项目的不同方面。
第 1 部分:数学基础与实现
第 2 部分:用 PyTorch Lightning
增压第 3 部分:卷积 VAE、继承与单元测试
第 4 部分 : Streamlit Web App 与部署
在第 1 部分的中,我们看了变分自动编码器,这是一个基于自动编码器的模型,但允许数据生成。我们了解了整体架构和实现细节,使它能够成功地学习。在这一节中,我们将讨论 PyTorch Lightning (PL),它为什么有用,以及我们如何使用它来构建我们的 VAE。
PyTorch 闪电是什么,为什么要用?
简而言之,PyTorch lightning 是 PyTorch 的一个附件,它使得训练模型更加简单。PyTorch Lightning 模块具有默认的类方法,可以减少训练模型时所需的不必要的样板代码。在进行实验时,我们通常想做一些小的改变,这对于大的模型来说是非常困难的。除了简化代码,Pytorch Lightning 还包含许多有用的功能,例如自动学习率查找。让我们看看如何将 Pytorch 代码翻译成 Pytorch Lightning。
培训和验证步骤
在一个标准的 PyTorch 类中,只有 2 个方法必须被定义:定义模型架构的__init__方法和定义向前传递的forward方法。所有其他操作(如数据集加载、训练和验证)都是在类外部运行的函数。
在 PyTorch Lightning 中,我们使用training_step来定义训练步骤中发生的操作。这可能包括日志记录、损失计算和反向传播等操作。然而,当使用 PyTorch Lightning 时,所需的代码大大减少了,重用已经定义的类方法相当简单。
PL 将调用training_step方法。基于在training_step中计算的损失,PL 将反向传播损失,并计算梯度和优化模型权重。在上面的代码中,我们看到有一个configure_optimizers方法,这是一个简单的类方法,它返回将用于模型训练的优化器。与需要optimizer.step()和loss.backward()的普通 PyTorch 不同,这些步骤被抽象出来,作为training_step方法的一部分自动运行。
执行验证步骤几乎是相同的代码。函数反向传播将计算并返回验证损失,并且不会进行参数更新。
PL 培训师
了解如何使用 PyTorch Lightning 的另一个重要补充是训练师课程。这个类对于将任何数据拟合到模型中是必不可少的。使用trainer.fit(model,dataloader)我们指定训练模型的数据。在实例化 trainer 对象时,我们还可以传递一些不同的参数来定义培训过程。
- 训练参数
- 时代数
- 用于训练的 GPU 数量
- auto _ lr _ find 自动确定要使用的学习率。在不需要任何额外实验的情况下,快速建立基线和训练模型非常有用。
使用 PyTorch 闪电训练器拟合模型
数据集加载
例如,用于训练、验证和测试的数据源是固定的,我们可以通过在类中定义 DataLoaders 来进一步扩充 LightningModule。 PyTorch Lightning 将自动从相应的数据加载器获取数据,并将其用于模型训练。
注意,我们可以简单地使用trainer.fit(model),而不必为训练或验证指定数据加载器。在这种情况下,由于 MNIST 是一个公共数据集,train_dataloader的代码相对较短,但对于更复杂的例子,在将数据加载器转换成适合训练的格式之前,该步骤可能包括几个预处理操作。
其他方法和回调
现在你可能会想。
“我试图解决的问题并不简单,如果我需要解决该怎么办?”
- 每个历元改变数据集
- 降低学习率
- 保存一些输出
幸运的是,pl.LightningModule基类有许多额外的方法来帮助执行任何可能有助于训练神经网络的操作。这里我们将实现validation_epoch_end。这将在每个时期后保存图像样本,以便我们验证我们的 VAE 模型是否训练正确。
validation_epoch_end接收validation_step的所有输出。在validation_step中,前向调用的输出与损失一起返回。我们可以简单地从x_out中提取一个样本,将其重新整形为合适的大小,并将数组保存为图像。
除了使用额外的类方法,另一种定制训练过程的方法是使用回调。与类函数相比,回调包含非常相似的方法,但是更具可配置性。如果在整个训练周期的多个不同点调用回调,应该使用回调来防止重复相同的代码块。还有一些预构建的回调函数,可以执行常见的操作,比如保存模型检查点或执行提前停止。
张量板跟踪
如果您之前注意到了,对于训练和验证步骤,我们使用self.log()。PyTorch Lightning 使记录训练期间的不同指标变得极其容易,并且可以使用 TensorBoard 轻松访问这些数据。训练循环期间记录的所有值将存储在lightning_logs中。

使用张量板跟踪损失函数
通过在终端中运行tensorboard --logdir lightning_logs/,可以可视化和监控记录的所有指标/损失。这有助于您跟踪不同的实验,并调整正在使用的一些超参数。
最终输出


比较第一个时期(左)和最后一个时期(右)期间的图像样本
比较第一个和最后一个时期的图像,我们可以看到模型已经成功地从图像中学习。在左图中,大多数项目是模糊的,而右图中的数字明显更清晰。值得注意的一点是,图像仍然很模糊。关于 VAEs 的一个有趣的事情是,它们可以与更适合该任务的特性选择架构一起使用。在这个例子中,我们使用 MNIST 数字的扁平矢量表示,但这肯定不是最好的方法。对于计算机视觉任务,使用几个卷积层将允许更好的特征提取,并帮助模型获得明显更好的结果。在这种情况下,我们仍然能够获得不错的性能,因为 MNIST 是一个“简单”的数据集。使用卷积 VAE 将获得明显更好的娱乐损失性能,因为从瓶颈中提取的特征将更有用。
构建图像的 VAE,可以从几层卷积步骤开始,取特征 max 展平矢量,用这个矢量获得瓶颈中的μ和σ矢量(参考 Part 1 )。为 VAE 执行正则化的神经网络架构仅出现在瓶颈处,并且该组件可以用于其他神经网络架构中。
除了图像之外,VAEs 还被成功地应用于许多不同的数据集,并且在自然语言处理(NLP)任务中取得了非常显著的效果。最近对 VAEs 的研究也产生了新的架构,如 MMD-VAE 和 VQ-VAE,它们实现了更好的性能。有关不同 VAE 架构的更多信息,请查看下面的链接。
请随意查看 GitHub 上的完整代码,非常感谢您的任何反馈!
github:【https://github.com/reoneo97/pytorch-lightning-vaeT2
LinkedIn:https://www.linkedin.com/in/reo-neo/
有用的资源
(1)不同 VAE 架构的 PyTorch 实现
https://github.com/AntixK/PyTorch-VAE
不同 VAE 架构的有用汇编,显示了各自的 PyTorch 实现和结果。
(2)神经离散表示学习
关于矢量量化 VAE (VQ-VAE)的论文。关于如何进一步改进离散数据的 VAEs 的有趣论文。强调 VAEs 存在的一些问题以及 VQ-VAEs 如何解决这些问题
(3) MMD-VAE
https://ermongroup.github.io/blog/a-tutorial-on-mmd-variational-autoencoders/
一篇有趣的博文,讲述了一种不依赖 KL 散度损失函数来正则化潜在概率分布的不同方法。
使用 PyTorch Lightning 的可变自动编码器(VAE)初学者指南(第 3 部分)
原文:https://towardsdatascience.com/beginner-guide-to-variational-autoencoders-vae-with-pytorch-lightning-part-3-9d686d0d85d9?source=collection_archive---------22-----------------------
用最少的额外代码构建新模型

亚历山大·奈特在 Unsplash 上拍照
这篇博客文章是一个迷你系列的一部分,该系列讨论了使用可变自动编码器构建 PyTorch 深度学习项目的不同方面。
第 1 部分:数学基础与实现
第 2 部分:用 PyTorch Lightning
增压第 3 部分:卷积 VAE、继承与单元测试
第 4 部分 : Streamlit Web App 与部署
在这一节中,我们将看看如何使用上一节中编写的代码来构建卷积 VAE。这种 VAE 能更好地识别图像中的重要特征,从而生成更好的图像。
最好的部分是,由于 PyTorch 模块和类继承,这个新模型可以用最少的额外代码来构建。
什么是卷积 VAE?
卷积是图像处理中常用的一种操作,用于提取特定图像的特征。图像通常充满了不必要的信息,放大任何像素,周围的像素很可能有非常相似的颜色。在卷积神经网络(CNN)中,许多卷积滤波器被自动学习以获得在分类和识别图像时有用的特征。我们简单地借用这些原理来使用卷积层来构建 VAE。
通过构建卷积 VAE,我们旨在获得更好的特征提取过程。即使我们不执行任何分类/回归任务,我们也希望潜在的表示尽可能地丰富信息。通过更强大的特征提取,解码器可以生成更有说服力的数据点。
即使这个新模型使用了新的架构,我们也希望高效地编写代码。好的高效的代码使用干(不要重复自己)原则。为了避免不必要的重复代码,我们将使用继承这一强大的概念来构建我们的模型。
什么是继承?
继承是面向对象编程(OOP)语言中一个非常强大的概念。它允许用户定义对象,然后构建新对象,同时保留原始对象的一些功能。继承是一个非常广泛的话题,有些事情,比如多重继承,我就不详细介绍了。有关 Python 和继承中 OOP 编程的更多信息,请查看本文。
https://realpython.com/inheritance-composition-python/
实际上,继承是如此普遍,以至于我们已经在第 1 部分中使用了继承。甚至在不知道的情况下,继承在 PyTorch 中被广泛使用,其中每个神经网络都从基类nn.Module继承。
因此,我们只需要定义__init__ 和forward方法,剩下的工作由基类来完成。我们将要构建的模型将进一步推进这一步,并建立在上一节构建的 VAE 的基础上。
继承允许我们在不同的阶段建立复杂的模型。我们之前建立的 VAE 模型充当了骨架。它执行重新参数化并实现 KL-散度损失。
然后我们可以继承这个类,创建一个更好的模型,使用一个更适合这个任务的架构。

conv·VAE 继承了 VAE 的所有方法,然后改写了编码器和解码器。作者图片
然后可以通过改变编码器和解码器来修改该模型。编码器简单地进行表示学习,解码器进行生成。这些子网可以是简单的线性层,也可以是复杂的网络。
在我们的卷积 VAE 中,我们希望改变这些组件,同时保持所有其他组件不变。使用继承可以很容易做到这一点
这允许我们避免重复大量的代码。像forward、training_step、train_loader 这样的类方法将保持完全相同,继承允许我们自动复制它们。
代码重构

照片由 Garett Mizunaka 在 Unsplash 上拍摄
如果你仔细观察,在之前的模型中。向前的步骤包括在将向量送入编码器之前将其展平。对于卷积 VAE,我们不想做这种展平,因为它会阻止我们 2D 卷积。
似乎要使继承工作,我们需要做一些代码重构!
从本质上讲,代码重构是在保持外部功能不变的情况下对代码进行一些修改。这意味着代码在输入和输出方面仍然具有相同的行为。重构可以使代码运行得更快,或者在我们的例子中,简化代码,以便我们可以在其他地方重用它。
我们可以重构我们的代码,而不是重写整个前进步骤,这样输入张量的展平和将其整形回 28 x 28 发生在self.encoder和self.decoder内,而不是在前进函数内。
这使得该模型更加通用,因为它可以适应不同的编码器,例如卷积,其中我们不想平坦化输入向量。
单元测试
但是坚持住!我们先不要做重构。您希望发生的最糟糕的事情是,当您更改代码时,您的模型会崩溃。我们希望确保 VAE 模型在重构后仍然做完全相同的事情。
确保您的项目在更改后仍然可用的一个好方法是编写单元测试。
单元测试是简单的脚本,您可以运行它来确保您的代码正常工作。在我们的模型中,这是为了确保我们建立的模型仍然能够训练,梯度仍然能够很好地反向传播。
为此,我们将使用 pytest,这是一个用于编写单元测试的强大库,它还包含有用的调试工具来找出测试失败的原因。
首先,我们在目录中创建一个名为tests的文件夹。在这个文件夹中,我们创建了一个名为test_model.py的文件。这将存储所有需要的单元测试。
让我们定义一个简单的测试:
pytest 的另一个很酷的特性是它会自动搜索包中的测试函数。只要函数名以test开头,pytest 就会相应地运行测试。
通过在命令行中运行pytest,我们可以确认测试通过。
Pytorch 模块化
现在有了合适的测试系统,我们可以开始修改代码了。
关于 PyTorch 模块,需要理解的一件重要事情是,它们基本上是函数。当一个输入被传递给任何 PyTorch 模块时,它只是运行一些操作,然后将渐变反向传播。
这意味着即使简单的整形操作也可以初始化为 PyTorch 对象。
展平模块
我们简单地将旧的 forward 函数的第一行作为一个模块添加进去。通过这种方式,将Flatten()作为一个模块放在编码器中可以实现同样的目的。
现在让我们为堆栈模块编写代码。对于 MNIST 数据集,该模块将张量整形回其原始形状(1,28,28)
在我们的例子中,因为图像是黑白的,所以只有一个通道,但是让我们构建一个堆栈模块,它也可以处理彩色图像。
为此,我们必须将关于数据集的信息存储到模型本身中。这是通过将数据的原始形状作为参数传递给模块来实现的。这些参数是通道、高度和宽度。前进操作将是一个类似于展平模块的view操作。
为了存储这些参数,我们需要使用 init 函数。这允许我们将这些参数存储为类变量。为此,我们首先将其初始化为 PyTorch 模块,这是通过调用__init__函数中的super(self,Stack).__init__() 来完成的。
堆栈模块
既然我们已经将这些整形函数抽象成它们自己的对象,我们可以使用nn.Sequential将这些操作定义为编码器和解码器模块的一部分。
新 VAE 法典
就像整形操作是self.encoder和self.decoder的一部分一样
让我们运行单元测试来检查代码是否有效。

作者图片
不错!测试通过,代码按预期运行。
https://docs.pytest.org/en/6.2.x/
构建卷积编码器
有了这些改动,我们就可以开始建造 VAE conv 了。让我们从编码器开始。
conv·VAE 的编码器和 init 函数
编码器的第一部分是Conv2d层的连续步骤以及ReLU激活和BatchNorm2d以帮助加速训练。该步骤在降低维度的同时执行特征提取。
下一步是展平步骤,将矢量转换回一维。VAE 中的潜在代表是一个单一的向量,我们需要得到相同形状的输入。这可以使用我们之前定义的Flatten()模块来完成。只要从 VAE 文件中导入它,我们就可以在编码器中使用它。
继续看解码器
conv·VAE 的解码器网络
解码器的架构非常相似。基本上是一样的,只是方向相反。
1.前馈层(nn.Linear)
2.Stack将线性层转换为带通道的 2d 形状的模块
3.ConvTranspose2d对图像进行增采样并生成具有更大高度和宽度的图像的图层。(与 Conv2d 相反)
4.Conv2d层清理最终输出
最终层应该输出与原始形状具有相同尺寸的东西,并且 MSE 损失可以很容易地应用。
信不信由你,我们结束了!默认情况下,Python 类将继承所有的方法,因此除了__init__ 之外的所有其他函数都不必重新定义。这意味着从培训、验证甚至save_images的一切都将自动呈现在新的 Conv VAE 中使用。
结果!


图片来自香草 VAE(左)和卷积 VAE(右)。作者图片
卷积 VAE 产生的图像似乎更清晰,图像中有更多的可变性。尽管使用相同的潜在空间维度,新模型能够捕捉和重建显示更多变化的图像。这显示了改进的编码器-解码器网络的能力,并且当应用于彩色图像时,这种差异将更加显著。
在下一节(也是最后一节),我将着眼于将模型完全部署到 Heroku 上所需的步骤,并创建一个与它们交互的平台!
初级到高级列表理解练习题
原文:https://towardsdatascience.com/beginner-to-advanced-list-comprehension-practice-problems-a89604851313?source=collection_archive---------3-----------------------
列表理解、字典理解和嵌套列表理解的练习题

rawpixel.com 创建的背景向量—www.freepik.com
介绍
假设我想创建一个从 1 到 1000 的数字列表,并编写了以下代码…
你能找出它有什么问题吗?
numbers = []
for i in range(1,1001):
numbers.append(i)
恶作剧问题。上面的代码没有问题,但是有一个更好的方法可以用列表理解达到同样的结果:
numbers = [i for i in range(1, 1001)]
列表理解非常好,因为它们需要更少的代码行,更容易理解,并且通常比 for 循环更快。
虽然列表理解并不是最难理解的概念,但它一开始肯定看起来不直观(对我来说的确如此!).
这就是为什么我给你八个练习题,让你把这个概念钻到脑子里!我将首先在顶部为您提供问题列表,然后提供答案。问题 1-5 相对简单,而问题 6-8 则稍微复杂一些。
说到这里,我们开始吧!
问题
**# Use for the questions below:**nums = [i for i in range(1,1001)]string = "Practice Problems to Drill List Comprehension in Your Head."
- 找出 1-1000 中所有能被 8 整除的数字
- 找出 1-1000 中所有包含 6 的数字
- 计算字符串中的空格数(使用上面的字符串)
- 删除一个字符串中的所有元音(使用上面的字符串)
- 查找字符串中少于 5 个字母的所有单词(使用上面的字符串)
- 使用字典理解来计算句子中每个单词的长度(使用上面的字符串)
- 使用嵌套列表理解来查找 1-1000 中除 1(2-9)之外的所有可被任何单个数字整除的数字
- 对于所有的数字 1-1000,使用嵌套列表/字典理解来找出任何数字可被整除的最高一位数
1.找出 1-1000 中所有能被 8 整除的数字
q1_answer = [num for num in nums if num % 8 == 0]
2.找出 1-1000 中所有包含 6 的数字
q2_answer = [num for num in nums if "6" in str(num)]
3.计算字符串中的空格数
q3_answer = len([char for char in string if char == " "])
4.删除字符串中的所有元音
q4_answer = "".join([char for char in string if char not in ["a","e","i","o","u"]])
5.查找字符串中少于 5 个字母的所有单词
words = string.split(" ")
q5_answer = [word for word in words if len(word) < 5]
6.使用字典理解来计算句子中每个单词的长度
q6_answer = {word:len(word) for word in words}
7.使用嵌套列表理解来查找 1-1000 中除 1(2-9)之外的所有可被任何单个数字整除的数字
q7_answer = [num for num in nums if True in [True for divisor in range(2,10) if num % divisor == 0]]
8.对于所有的数字 1-1000,使用嵌套列表/字典理解来找出任何数字可被整除的最高一位数
q8_answer = {num:max([divisor for divisor in range(1,10) if num % divisor == 0]) for num in nums}
感谢阅读!
我希望这对你有用。如果你能够用列表或字典的理解来解决这些问题,我想可以说你对这个概念有很强的理解。
如果你觉得这很有用,并且想要更多这样的文章,请在评论中告诉我:)
一如既往,我祝你学习一切顺利。
不确定接下来要读什么?我为你挑选了另一篇文章:
又一个!
</50-statistics-interview-questions-and-answers-for-data-scientists-for-2021-24f886221271>
特伦斯·申
- 如果你喜欢这个, 跟我上媒 了解更多
- 有兴趣合作吗?让我们连线上LinkedIn
- 报名我的邮箱列表 这里 !
初学者指南:提取、转换、加载(ETL)
原文:https://towardsdatascience.com/beginners-guide-extract-transform-load-etl-49104a8f9294?source=collection_archive---------27-----------------------
了解数据分析中的大数据原理

照片由法比奥在 Unsplash 上拍摄
提取、转换、加载过程(简称:ETL)描述了从各种来源收集数据到最终存储在数据仓库解决方案中的步骤。当需要可视化大量数据时,各个阶段就开始发挥作用了。
什么是 ETL?
公司和组织面临着必须处理越来越大的数据量的挑战。这些信息也来自许多不同的系统,它们有自己的数据结构和逻辑。这些数据应该尽可能统一地存储在中央数据仓库中,以便用于数据挖掘或数据分析。
为了保证这些信息的可靠性和弹性,必须从不同的源系统中提取、准备这些信息,然后加载到目标系统中。所有这些都发生在 ETL 过程中。

ETL 过程步骤
为了更好地理解提取、转换和加载过程,有必要详细了解一下各个阶段:
ETL 提取
提取是从各种来源检索数据并集中存储的过程步骤。在这个步骤中,除了其他事情之外,还执行数据质量检查以确保数据仓库中的干净状态。这些检查可以包括,例如,匹配数据类型或寻找缺失值。例如,可以检查是否所有表示价格的项目都用美元标记。如果数据有严重的质量缺陷,也可以在这个阶段被拒绝。如果没有或只有少量缺陷,数据将被传递到下一阶段,在那里进行必要的更改。
提取步骤包括从各种来源加载信息。其中包括:
ETL 转换
在这个阶段,所有数据都被转换成与数据仓库或应用程序的数据模型相匹配的结构。如果仍然有数据质量问题,现在已经处理了。例如,这包括填充缺失值或纠正错误。此外,这里已经进行了基本计算,可以用这些计算来汇总或准备数据。这可能包括,例如,营业额已经按日累计,如果需要,不是每个订单都单独保存。
ETL 加载
我们在前面步骤中准备的数据现在可以加载到数据仓库或目标数据库中。如果那里已经有较旧的同类型信息,这必须相应地补充,甚至交换。这通常是通过使用唯一的 ID 或输入信息保存的时间来完成的。通过这种方式,可以对数据进行比较,并有针对性地删除过时的信息。
ETL 应用程序
ETL 过程主要用于当您希望将数据集中存储在公司或组织的数据仓库中时。为此,必须从各种数据存储中收集数据并进行合并。信息具有完全不同的数据结构并不少见,这需要在转换步骤中做一些工作。
当信息要在商业智能解决方案中显示时,ETL 过程用于确保数据以这样一种方式存储,即它可以尽可能容易地在图中显示并且没有错误。
提取、转换和加载过程步骤可用于多种应用。其中包括:
- 数据仓库中信息的集中存储。
- 借助商业智能实现数据可视化
- 合并来自不同系统的数据
ETL 挑战
当要迁移许多非常不同的系统及其数据时,ETL 阶段可能会带来最大的挑战。然后,数据模型完全不同的情况并不少见,必须对它们进行大量的转换工作。
否则,如果数据质量存在必须首先纠正的缺陷,转换步骤的成本也会很高。在某些应用程序中,丢失值根本无法避免,仍然必须进行相应的处理。例如,如果我们在测量装配线上的组件的生产线上有测量数据,但维护是在 2021 年 5 月 30 日和 2021 年 6 月 1 日之间执行的,因此在此期间没有收集数据。因此,我们在此期间丢失了所有记录的零件长度测量值。我们现在可以忽略该期间的记录,或者,例如,用前后几天的测量平均值替换缺失的字段。
ETL 与 ELT
ETL 过程已经建立了几年甚至几十年。然而,在同一时期,许多应用程序中积累的数据量也显著增加。因此,直接构造所有结果数据并将其存储在数据仓库中是一件非常昂贵的事情。相反,在大多数情况下,非结构化数据首先存储在所谓的数据湖中。在那里,数据以原始格式存储,直到特定应用程序需要它。
为此,ETL 过程被修改为所谓的 ELT 过程。正如字母的排列已经表明的,填充数据湖的第一步是“装载”步骤。在数据湖中,数据仍然是非结构化的、未排序的和未更正的。

ETL vs. ELT |来源: LinkedIn
一旦特定用例需要这些信息,并且已经定义了目标数据格式,就开始准备数据的“转换”过程。例如,Hadoop 可以作为数据湖的技术。
这是你应该带走的东西
- ETL 包含从不同系统收集数据、准备数据并将其存储在目标系统中的重要过程步骤。
- 各个阶段确保信息与数据模型保持一致,并符合特定的质量标准。
- ETL 主要用于将数据存储在数据仓库中或显示在 BI 应用程序中的时候。
如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !此外,媒体允许你每月免费阅读 3 篇 。如果你想让无限制地访问我的文章和数以千计的精彩文章,不要犹豫,通过点击我的推荐链接:*https://medium.com/@niklas_lang/membership获得会员资格,每个月只需支付 5**
*** ***
功能选择初学者指南
原文:https://towardsdatascience.com/beginners-guide-for-feature-selection-by-a-beginner-cd2158c5c36a?source=collection_archive---------15-----------------------
特征选择的不同方法以及为什么每个人都要为特征选择而烦恼;通过比较不同的方法来选择最优的特征选择方法。
处理大型数据集时,由于存在大量要素,建模运行起来可能会非常耗时。一个模型有数百个特征并不罕见。那么剔除不相关的和不合格的特征就很关键了。这就是特征选择的概念发挥作用的时候了。在本文中,我将尝试介绍一些广泛使用的特性选择技术,并演示其中的一些。
特征选择对于建立计算高效的模型是极其重要的步骤。这方面有很多技巧。让我们从定义特征选择的过程开始。
特征选择是选择最相关的预测特征的子集用于机器学习模型建立的过程。
特征消除通过剔除冗余特征和不能提供太多洞察力的特征来帮助模型更好地执行。它在计算能力上是经济的,因为需要训练的功能更少。结果更易于解释,并且通过检测共线要素减少了过度拟合的机会,如果方法使用得当,还可以提高模型的准确性。
特征选择方法:

特征选择方法的亮点,按作者分类的图片
1。过滤方式:
探测能力:★☆☆|速度:★★★★

从可用的布景中挑选最好的,照片由 UX 印度尼西亚在 Unsplash 上拍摄
这不是机器学习方法。它根据要素的属性过滤要素。这种方法是“模型不可知”的,即性能不依赖于所用的模型。
这种方法应该用于初步筛选。它可以检测恒定的、重复的和相关的特征。通常在减少功能方面不是最好的表现。也就是说,这应该是减少要素的第一步,因为它根据所使用的方法来处理要素的多重共线性。

使用过滤方法的特征选择过程,按作者分类的图像
这方面的几个例子:
- 单变量选择(ANOVA: 方差分析 )
- 卡方
- 基于皮尔森相关性
- 线性判别分析(LDA): 线性判别分析用于寻找特征的线性组合,其表征或分离两个或更多类别的分类变量
2。包装方法:
探测能力:★★★☆ |速度:★☆☆☆

机器学习的胜利,照片由附身摄影在 Unsplash
这种方法使用机器学习算法。这种方法的性能取决于所选的模型和底层数据。通常可以建议最佳的特征子集。尝试不同的功能子集以找出最佳功能。通常计算量非常大。可以检测特征之间的相互作用。
在特征消除方面可能是最好的性能。对于大型数据集,包装器非常慢。

使用包装方法的特征选择过程,由作者创建的图像
这方面的几个例子:
- 正向选择
- 向后选择
- 穷举搜索
3。嵌入方法:
探测能力:★★★☆☆ |速度:★★★☆☆

人机协同工作,图片来自 pixabay
构建模型时执行特征选择。通常比包装方法的计算成本低。通常提供两全其美的结果,通常是更现实的方法。

使用嵌入式方法的特征选择过程,按作者排序的图像
这方面的几个例子:
- 拉索
- 带脊套索(使用 ElasticNet 规则化特征)
- 基于树的选择。
- 回归系数(特征必须标准化)。
超参数调整对于该方法非常重要,这是该方法的人工干预部分。
4。混合方法:
探测能力:★★★☆☆ |速度:★★★☆
上述所有技术的融合。这种方法比包装器方法计算量少,并且具有良好的性能。

使用混合方法的特征选择过程,按作者排序
这方面的几个例子:
- 功能洗牌
- 递归特征消除
- 递归特性添加
带走消息:
- 过滤方法通过特征相对于目标变量的相关性基于特征的相关性对特征进行排序,而包装方法通过实际训练特征子集上的模型来测量特征子集的有用性。
- 与包装器方法相比,过滤器方法要快得多,因为它们实际上并不训练模型。而包装器方法则不然,这使得它们计算量很大,有时甚至无法执行。
- 过滤方法使用选定的统计方法进行特征选择,而包装方法执行交叉验证以确定特征的最佳子集。
- 由于要素的属性,过滤方法可能无法找到要素的最佳子集,但是包装方法通常可以更经常地提供要素的最佳子集。
- 包装器方法倾向于使模型更容易过度拟合,对于那些方法,测试训练分离是必须的。
为了演示这些技术,我对“金县住房数据集”执行了基于特征间相关性的特征选择、方差分析、正向选择、RFE 和套索技术。
为了使这篇文章简短,不偏离主题,我将简要介绍一下我为准备数据所采取的步骤。
- 分类特征是 OneHotEncoded。
- 我从“id”栏中删除了重复项。
2.在 NaN 中填入 0,并在“waterfront”、“view”、“yr _ renovated”和“sqft_basement”功能中将其他错误输入填入 0。
3.转换适当的数据类型。
4.从数据中剔除异常值。
5.将数据缩放至最小最大缩放器(此缩放器单独缩放和转换每个要素,使其位于数据集的给定范围内,例如,介于 0 和 1 之间)以用于 lasso。
包含这部作品的笔记本可以在 GitHub 上的Feature_Selection.ipynb找到这里的。
- 过滤方法:
- 基于皮尔森相关性
我使用这个函数来获得相关的特征
在清理的数据集上运行时,结果如下:
correlated features: 1
correlated features: {'sqft_above'}
这意味着“sqft_above”功能与其他功能相关,应该删除。
- 单变量选择(ANOVA)
我使用这一行代码来执行 ANOVA。
我根据 r 的平方对结果进行了排序。结果如下。

作者图片
由此,我对模型中包含的最重要的特性有了一个想法。如grade、sqft_living、zipcode等。

作者图片
绘制时,我也能根据它们的 p 值感觉到它们的重要性。grade和condition具有很高的 p 值。
2.包装方法:
- 预选
我在 OneHotEncoded 数据帧上使用这个函数进行前向选择。
然后我运行了下面的代码。
model = forward_selected(df_model_processed_ohe, 'price')
print(model.model.formula)
print(model.rsquared_adj)
model.summary()
结果给出了从最重要到最不重要的特性。
price ~ sqft_living + yr_built + sqft_lot + sqft_living15 + zipcode_98004 + grade_9 + grade_8 + grade_10 + grade_7 + zipcode_98023 + zipcode_98033 + zipcode_98040 + zipcode_98092 + zipcode_98042 + zipcode_98003 + zipcode_98058 + zipcode_98038 + zipcode_98030 + zipcode_98031 + zipcode_98055 + zipcode_98002 + zipcode_98198 + zipcode_98032 + zipcode_98178 + zipcode_98168 + zipcode_98022 + zipcode_98112 + view_4 + zipcode_98199 + zipcode_98115 + zipcode_98103 + zipcode_98117 + zipcode_98119 + zipcode_98105 + zipcode_98107 + zipcode_98109 + zipcode_98116 + zipcode_98102 + zipcode_98122 + zipcode_98052 + zipcode_98006 + zipcode_98005 + zipcode_98053 + zipcode_98136 + zipcode_98144 + zipcode_98008 + zipcode_98029 + condition_5 + view_2 + zipcode_98188 + view_3 + zipcode_98027 + zipcode_98007 + zipcode_98074 + zipcode_98075 + zipcode_98034 + zipcode_98125 + zipcode_98039 + zipcode_98126 + zipcode_98177 + grade_11 + zipcode_98133 + zipcode_98118 + sqft_basement + condition_4 + yr_renovated + view_1 + zipcode_98155 + waterfront_1 + zipcode_98072 + zipcode_98011 + zipcode_98065 + zipcode_98028 + bathrooms + zipcode_98106 + floors + zipcode_98108 + zipcode_98077 + zipcode_98146 + zipcode_98056 + zipcode_98059 + zipcode_98045 + zipcode_98019 + zipcode_98166 + zipcode_98014 + zipcode_98024 + zipcode_98010 + condition_3 + zipcode_98148 + zipcode_98070 + grade_5 + bedrooms + sqft_lot15 + 1r_sq: 0.8315104663680916
这还会返回用于检查同质性的图。

作者图片
我可以看到,残差图远非完美,模型中有明显的偏差。
3.嵌入式方法:
我为这个演示表演了套索。使用 sklearn.linear_model 中的 LassoCV
一开始有 95 个特征。上面代码的结果是:
Model r squared 0.8307881074614486
Number of Selected Features: 91
Lasso 将特征集减少到 91。这些功能已被删除- sqft_lot15 ' 、 zipcode_98070 ' 、 zipcode_98148 '、 grade_8 '。
4.混合方法:
为了演示这一点,我使用了来自 scikit-learn、sklearn.svm 和 sklearn.feature_selection 模块的 SVR 和 RFE。如果在 RFE“n _ features _ to _ select”中没有传递任何内容,则选择一半的特征。我为这个特性选择使用了下面的代码。
这样的结果是:
Model r squred: 0.776523847362918
number of selected feature 47
为模型选择特征更像是一门艺术,其中使用的判断力很重要。建模中经常用到的一句话是垃圾输入垃圾输出。对于特征选择也是如此。我们在根据选定的特性建模时必须小心,因为有时候越少越好。
在上面的演示中,他们中的一些人表现良好,而一些人表现不佳。这取决于数据科学家根据分析的目标为他们的模型选择最佳数字。也就是说,这些技术对于任何一个高效的数据科学家来说都很方便。
另一种方法是用于降维的主成分分析。它在保留属性的同时减少了特征,但是牺牲了模型的推理。
今天到此为止。下次见!
Google Data Studio 数据可视化初学者指南
原文:https://towardsdatascience.com/beginners-guide-on-data-visualization-with-google-data-studio-3c0c26c3bff4?source=collection_archive---------8-----------------------
使用 Data Studio 更好地可视化和理解数据的初学者教程

艾萨克·史密斯在 Unsplash 上拍摄的照片
介绍
数据科学就是处理数据,其中一个重要的分支是数据可视化,您可以通过交互和可视化的方式交流和呈现最终结果的信息。除了使用数据可视化将结果呈现给最终用户,我还经常在数据科学流程的不同步骤中使用数据可视化,例如在数据预处理之前让我更好地理解数据,以及在建模步骤中,我在不同的图表中可视化我的预测结果,以查看模型如何再次执行历史结果(,尤其是对于时间序列预测)。
关于谷歌数据工作室
Google Data Studio 于 2016 年首次推出测试版,并成为数据可视化的常用工具——为什么?
- 方便用户的
- 兼容多种数据源(如:MySQL、Google Analytics、Google BigQuery、PostgreSQL、Youtube、excel 文件等。)
- 实时数据连接器—与多个数据源无缝集成,并刷新您的报告
- 价格——每个用户都可以免费使用!
- 个性化—根据您选择的图表、颜色和指标定制您的控制面板
- 共享和协作—您可以与其他人或所有人共享您的报告!
让我们开始学习如何用 Google Data Studio 构建交互式可视化。
入门指南
首先,使用谷歌账户https://datastudio.google.com/登录 Data Studio,你将会直接进入 Data Studio 主页:

Data Studio 主页(图片由作者提供)
在主页上,请注意 Google Data Studio 提供了各种各样的模板来启动您的过程。从模板中,您可以根据个人喜好定制图表、字体和颜色。(如果你要选择一个模板开始——根据你的主题选择一个相关的模板!)

谷歌数据工作室——模板库(图片由作者提供)
对于本教程,我们将从一个空白报表开始,以便更好地理解如何从头开始构建您自己的仪表板。首先选择:(+)空白报告。

从空白报告开始(图片由作者提供)
添加数据源
打开一个空白报告后,要做的第一件事是连接到一个数据源,它也是仪表板的构建块。Google Data Studio 会提示您一个选项:向报告添加数据。Google Data Studio 提供了各种各样的连接器,让我们连接一个来自 Google Big Query 的公共数据集。

将数据添加到报告中(图片由作者提供)
我们将在本教程中使用的公共数据集是——伦敦自行车租赁,可在谷歌大查询公共数据集 ( 来源:data.london.gov.uk)中找到。该数据集包含伦敦桑坦德循环雇佣计划的雇佣人数信息。

添加来自 Google Big Query 的数据(图片由作者提供)
在将数据添加到报告中后,Google Data Studio 会根据对所提供数据集的理解自动制表。

谷歌数据工作室-编辑视图(作者图片)
让我们删除创建的表,因为我们想从头开始构建—右键单击“删除”。
指标和维度
在开始构建可视化之前,需要理解两个重要的术语,即术语“度量”和“维度”。
指标—是数据中的数字测量值,以数字形式表示。(比如销售价值、时间、持续时间等。)
维度-是数据中的分类值。(例如性别、国家、城市等。)
因此,在构建图表时,维度用于分解指标值。例如:
- 销售值 (公制) 按城市分解 (维度)
- 按性别细分的子女数量 (公制)【维度】
添加“条形图”
现在让我们添加第一个视觉效果——一个条形图。从工具栏中,单击“添加图表”和一个下拉列表,该列表包含不同的图表,您可以从中选择您想要的图表。在这里,我将选择一个水平条形图。

添加图表选项(图片由作者提供)
从下拉菜单中选择后,“条形图”将添加到报告中。选择条形图,您会发现可以从右侧窗格配置条形图上显示的数据。在这里,我选择可视化出租次数最多的前 10 个站点。

添加“条形图”(图片由作者提供)
在右侧窗格中,配置以下选项:
- 尺寸:起点站名称
- 指标:计数(租赁标识)
- 排序:计数(租赁标识),降序

选择“条形图”的维度和度量(图片由作者提供)
接下来,由于我们的数据集中总共有 880 个不同的“起点站名称”,让我们选择可视化骑手经常乘坐的前 10 个最受欢迎的车站。我们可以在右侧窗格—“Style”选项卡下进行配置,并将条形数量限制为“10”。

设置“条”的数量(图片由作者提供)
定制您的“条形图”
当构建仪表板时,这是我最喜欢的部分,即根据我个人的喜好改变条形图的颜色。在 Google Data Studio 中,这可以在右边的“风格”选项卡上完成。

自定义“条形图”颜色(图片由作者提供)
在右侧窗格—“样式”选项卡上,根据您自己的偏好配置以下选项:
- 颜色依据:选择您喜欢的颜色
- 参考行:metric:rental _ id;计算:平均值
- 您选择的字体
- 您选择的图表背景和边框颜色
添加“折线图”
除了条形图之外,现在让我们添加一个“折线图”来显示一段时间内的租赁总数。折线图有助于了解成交量在一段时间内的波动情况。同样,从工具栏中,单击“添加图表”,并从下拉菜单中选择“折线图”。

添加“折线图”(图片由作者提供)
在右侧窗格中,配置以下选项:
- 维度:开始日期
- 指标:计数(租赁标识)
- 排序:开始日期,升序

选择“折线图”的维度和度量(图片由作者提供)
创建“双轴折线图”
从我们当前的折线图继续,让我们通过添加另一个指标来创建一个双轴图。双轴图表通常用于可视化两个不同度量标准之间的关系。

向当前“折线图”添加第二个指标(图片由作者提供)
选择折线图,并在右侧窗格中添加以下指标:
- 度量:sim(持续时间)
请注意,添加第二个指标后,每个日期的 total rental_id 的值不再那么明显。这是因为两条线绘制在同一轴上,并且具有不同的比例测量值。要解决此问题,请通过在右轴绘制第二个 metic 来创建双轴折线图。这可以在右侧窗格的“样式”选项卡下进行配置。

创建“双轴折线图”(图片由作者提供)
在右侧窗格—“样式”选项卡上,配置以下选项:
- 滚动到系列# 2——它代表我们的第二个指标:持续时间
- 轴:右侧
现在,在折线图上清楚地查看两条线,只是在一张图表上绘制这么多日期可能会太拥挤?让我们通过按月分组数据并添加日期范围选项来解决这个问题。
按月份和日期范围选项分组数据
要按月对值进行分组,请通过选择右侧窗格中“start_date”维度下的日历图标进行配置。

按“年/月”对日期值进行分组(图片由作者提供)
在右侧窗格—“数据”选项卡上,配置以下选项:
- 在维下—选择日历图标
- 选择日期和时间→“年月”

按“年/月”图表分组日期值(按作者分组的图像)
现在,我们可以更好地了解从 2015 年到 2017 年 6 月每个月的总租金和持续时间。此外,我们可以添加一个过滤器选项来选择要查看的时间段的日期范围。
在引入日期范围控制选项之前,在右侧窗格中添加“start_date”作为两个图表的日期范围维度。添加此维度后,两个图表都将根据数据范围控件选择的值进行筛选。

添加日期范围维度(作者图片)
接下来,从工具栏中,单击“添加控件”并选择“日期范围控件”

添加“日期范围控件”(图片由作者提供)
将日期范围控件属性设置为“自动日期范围”。使用此选项,用户可以从日历视图中选择他们的日期范围。

设置“自动日期范围”(图片由作者提供)
要测试“日期范围控制”过滤器,请将报告切换到“查看”模式。

切换“查看”模式(图片由作者提供)
“查看”模式以不可编辑的形式显示仪表板,您可以在其中预览仪表板并与之交互。在“查看”模式下,通过选择一个日期范围来测试“日期范围控件”并将其应用于报告。(这里我选择的是 2016 年 2 月—2017 年 2 月)

选择日期范围(按作者分类的图像)
根据所选的日期范围,观察图表中的变化。请注意,条形图值已减少,折线图日期范围基于选定的日期范围。

“日期范围控制”的结果(图片由作者提供)
添加“记分卡”
除了绘制图表,我们还可以将记分卡添加到仪表板中。记分卡显示单个指标的汇总值。记分卡的常见用途是用于查看-总销售额、总订单、平均销售额、最大值等。
要添加“记分卡”,请从工具栏中选择,单击“添加图表”并选择您选择的“记分卡”。

添加“记分卡”(图片由作者提供)
让我们使用记分卡来查看租赁总数。类似地,用于记分卡的数据可以在右侧窗格中配置。

选择“记分卡”的日期范围维和度量(按作者排序的图片)
在右侧窗格中,配置以下选项:
- 日期范围维:开始日期(日期)
- 指标:计数(租赁标识)
此外,我们希望记分卡的标题是“Total Rental ”,而不是默认的列名。让我们将“租赁标识”的指标重命名为“总租赁”。
- 将鼠标悬停在 rental_id 指标选项下的“CT”指标上,可以看到一个铅笔图标。
- 点击铅笔图标,在名称部分添加“总租金”。

将指标重命名为“总租金”(图片由作者提供)
重命名指标后,我们的记分卡标题将基于指标提供的名称。除此之外,根据您自己的偏好调整右侧窗格“样式”选项卡上的记分卡填充。

“总租金”记分卡(图片由作者提供)
重复相同的过程,使用指标:sum(duration)创建另一个记分卡,并将指标重命名为“Total Rental Duration”。

两个记分卡结果(图片由作者提供)
添加“文本/图表标题”
使用工具栏下的“文本框”选项,可以很容易地将文本添加到报告中。让我们快速使用“文本框”选项为条形图和折线图添加一个图表标题。

使用“文本框”添加图表标题(图片由作者提供)
添加 textbox 后,您可以根据自己选择的字体样式、字体颜色、文本对齐方式和背景颜色,从右侧窗格中配置样式。
在我们结束并完成仪表板的设计之前,让我们添加另一个过滤器选项——“滑块”。
添加“滑块”控件
滑块控件允许用户根据数值维的值范围进行筛选。让我们添加一个滑块,让用户根据租赁期限进行选择。
要添加“滑块”,从工具栏中选择,单击“添加控件”并选择“滑块”选项。指定用于右侧窗格“数据”选项卡上的滑块的控制字段。

选择“滑块”的日期范围维度和控制字段(图片由作者提供)
在右侧窗格中,配置以下选项:
- 日期范围维:开始日期(日期)
- 控制字段:持续时间
此外,我们希望滑块的标题是“租赁期限”,而不是默认的列名。让我们将该指标重命名为“租赁期限”。

将指标重命名为“租赁期限”(图片由作者提供)
添加“主题和布局”
最后,我们可以将“主题和布局”应用到报告中。主题有助于根据所选主题预定义一组颜色和样式组合。
工具栏菜单中有一个“主题和布局”选项。选择了该选项,您可以在右侧窗格中选择您想要的“主题和布局”。

主题示例—“星座”
在选择了你喜欢的“主题和布局”之后,你的仪表板就差不多完成了。在“查看”模式下查看您的最终仪表板结果,您可以使用“共享”选项开始与他人共享您的报告,或者下载 PDF 格式的报告。

最终仪表板视图(图片由作者提供)
结论:
数据可视化是数据科学家的一项重要技能,因为它有助于更好地理解数据,并有效地交流结果。根据我个人使用 Google Data Studio 的经验,对于任何人来说,它都是一个非常好的数据可视化入门工具。由于界面易于导航,您可以轻松掌握这些新技能。本文中的教程是帮助您入门的基础,我建议您在 Google Data Studio 上试用并进一步探索所提供的更高级的选项。
最后,感谢您阅读这篇文章!
参考和链接:
[1]https://search business analytics . tech target . com/definition/data-visualization
[2]https://support.google.com/datastudio/answer/6283323?hl=en
[3]https://infogram.com/create/dual-axis-chart
NLP 项目初学者指南:美国毕业典礼演讲分析
原文:https://towardsdatascience.com/beginners-guide-to-an-nlp-project-analysis-of-commencement-addresses-in-the-u-s-5bf228c3c5e7?source=collection_archive---------33-----------------------

汤姆·菲茨西蒙斯拍摄的照片
每年,学院或大学都会邀请著名的演讲者,如技术领袖、政治家、著名作家、学术界或娱乐界有影响力的人士等。向毕业班致辞。通过自然语言处理,该项目分析了这些振奋人心和令人心酸的演讲,确定了它们的共同特点以及是什么使它们脱颖而出。这是我在为期 12 周的 Metis 数据科学训练营中从事的第四个项目(持续时间为两周半)。
为了更好地塑造这个项目,我把它缩小到我希望从这个项目中回答的 3 个问题:什么?谁啊。又是怎么做到的?也就是说,说话者谈论什么?谁是观众?说话的人是如何说话的?
在这篇博客中,我将向您介绍我作为自然语言处理(NLP)初学者为这个项目所采取的步骤:
- 数据收集
- 数据清理和简单 EDA
- 主题建模
- 主题建模分析
- 情感分析
数据收集
成绩单。需要的主要数据是毕业典礼演讲的文字记录。谷歌了一番后,我决定从两个来源入手。第一个来自于 Charlie Harrington 在 FloyHub 上收集整理的一个数据集,可以直接下载。二是来自网站毕业智慧,可以用 BeautifulSoup 刮。在合并数据和删除重复数据后,我得到了 400 多份副本。
演讲者和学校信息。每次演讲的演讲者和演讲发生的地点都可以和抄本一起收集。然而,为了使它们成为有用的特征,我用 Selenium 搜集了诸如年龄、每个发言者的职业和每个学校的坐标等信息。
数据清理和简单 EDA
数据清理。为了回答第一个问题——他们谈论什么——我们需要进行主题建模。在我们开始主题建模之前,我们首先需要清理文本数据。这一步包括使所有字母小写,删除标点符号,删除数值或任何无意义的文字等。
包话。在清理文本之后,我们可以为抄本和文档术语矩阵创建单词包。在这里,文档是一个演讲记录。一般来说,根据你对主题建模的需求,有两种主要的方法:来自sklearn.feature_extraction.text的CountVectorizer或TfidfVectorizer。
计数矢量器 : 统计每个术语在每个文档中出现的频率,每个术语的权重相等。
TfidfVectorizer : 简称 term-frequency 逆文档频率。使用这种方法,出现在较少文档中的术语将具有较大的权重。例如,如果大多数演讲都提到了“毕业”,那么“毕业”一词在文档-术语矩阵中的价值就会降低,在主题建模中的重要性也会降低。
注意,在这一步,您可以在矢量器中指定要删除的停用词(例如,
CountVectorizer(stop_words='english'))。停用词是像“and”、“the”、“like”等对句子没有多大意义的词。
探索性数据分析 。为了更好地理解我们正在处理的文字记录,我们可以从单词包中找出最常用的单词开始:

所有演讲中最常用的词。排在前面的是生活、时间、思考、世界。作者图。
从这个图表中,我们可以看到所有演讲的共同主题。但是我们仍然需要把它分解开来,看看每个演讲者在他们的演讲中到底提到了什么。这是我们分析的主要部分:主题建模。
主题建模
主题建模有几种方法,如 LDA (潜在狄利克雷分配)和 NMF (非负矩阵分解)。
LDA是一个生成概率模型。文档由主题分布组成,主题由单词分布组成。假设每个文档都是由一个过程生成的,在这个过程中,我们从主题分布中随机选择一个主题,然后从相应的主题中随机选择一个单词。
NMF是一种线性代数优化算法。从上一个矢量器步骤开始,我们通过 m 构建维度为 n 的文档-术语矩阵,其中n是文档(抄本)的数量,m是术语的数量(词汇的大小)。我们可以将 t 指定为主题的数量,并找到两个矩阵:文档-主题( n 乘 t )和主题-术语( t 乘 m ),这样它们的乘积就是(近似)文档-术语矩阵。
我测试了 LDA 的CountVectorizer和 NMF 的TfidfVectorizer。在这两种方法中,您必须为模型选择主题的数量(就像一个超参数)。经过几轮的试验和比较,我选择了有 8 个主题的 NMF,因为在这种情况下,主题更容易理解,演讲的分类也更有意义。以下是我的 8 个主题和每个主题的关键词:

寻找演讲的主题。图片作者。
主题建模分析
确定主题后,我们现在需要分析和解释结果。就时间而言,看看演讲主题的趋势如何随时间发展会很有趣。其他方面可以是说话者的职业之间比较的主题分布。或者在不同的观众群中——这是我们最初的问题谁。
A.历年话题趋势
下面的百分比堆积面积图显示了这些年来主题的趋势,每种颜色代表一个主题。这种类型的情节乍一看可能有点乱,但它有它的优点。很容易看出哪一年哪些话题在所有演讲中占了较大的比重,以及这些比重如何改变了久而久之。

百分比堆积面积图显示历年来演讲主题的趋势。作者图。
例如,它表明家庭&朋友一直是一个受欢迎的话题。另一方面,女性的声音只是在 2000 年代后期才开始出现。值得注意的是,新生代&国家话题是 2004 年最热门的话题。这可能与当年晚些时候的总统选举有关。另一个发现是,科技/商业话题在 2005 年略有增加,但随后被艰难所取代。有人可能会说,由于始于 2007 年并延续至 2008 年的全球金融危机,可能会有更多的演讲者在演讲中谈到恐惧、失败或挑战。
B.不同演讲者职业之间的话题分布比较
基于网络搜集的数据,演讲者的职业可以大致分为 8 类:
- 艺术:艺术家、音乐家…
- 学术界:教育工作者、研究人员、科学家…
- 娱乐:电影行业的人,电视主持人…
- 医学/法律:外科医生、医生、律师、法官…
- 政治:国家领导人、参议员、市长…
- 出版:作家,诗人,记者…
- 运动:运动员
- 技术/商业:技术行业的人,首席执行官…
这些职业的主题分布显示在下面的饼图中:

话题分布因演讲者职业而异。作者图。
我们可以看到,对于艺人和运动员来说,演讲主题就没那么多样化了。艺术家谈论很多艺术和艰辛,运动员谈论最多的是体育(这并不奇怪)。虽然学术界和政界的演讲者都有很大一部分是关于新一代和国家的话题,但背景略有不同。前者从知识上讲新一代,后者讲国家和历史。娱乐业的演讲者倾向于分享故事和建议(包括在家庭和朋友的话题中)。在所有职业中,出版业(包括作家、记者等)更多的发言人(百分比)关注妇女的声音。近一半的科技或商业演讲者(47%)将梦想作为演讲主题。
C.不同受众位置之间的主题分布比较
我们还将看看不同学校的主题分布,以回答关于谁是观众的最初问题。使用从谷歌地图上抓取的坐标,我们可以将学校划分为美国的三个地区,以确定观众的位置:东部、中部和西部。

不同受众的主题分布(基于位置)。图片作者。
乍一看,西部和东部地区的主题分布相似,西部地区的“艰难”和“新一代和国家”的比例略高。在东方,人们更多地谈论体育(体育精神)和艺术与科学。有趣的是,虽然西部和东部的女性声音比例相当,但在中部地区却不存在。
情感分析

将每份抄本分成 10 段,追溯情绪的演变。作者图。
我想找到答案的最后一个问题是说话者如何说话。情感分析在自然语言处理中起着重要的作用,可以用现成的软件包来完成,如nltk的 VADER(用于情感推理的效价感知词典)textblob的 TextBlob 等。在使用 VADER 的情况下, compound score 是一个介于 1 和-1 之间的归一化值,告诉你一段文本是正面的、中性的还是负面的。对于文本,您可以根据您希望如何执行分析,按句子、段落或任何其他方式来分隔它。我选择将每份文稿分成 10 个部分,这样我可以检查整个演讲过程中情绪的演变。
对于每个职业类别,在每个部分评估平均 VADER 分数。为不同的职业找到不同的情感特征是非常有趣的。下面是几个例子。

不同说话人职业的情感分析。作者图。
从对 4 种不同职业的情绪比较中,我们看到娱乐和科技行业的演讲者在整个演讲中倾向于保持积极的态度。然而,律师、医生或学术研究者演讲中情绪的演变显示了一种不同的模式。他们可能以积极的开头和结尾开始,但在演讲中途变得不那么积极甚至消极。
结论
综上所述,我从三个方面分析了 400+开始演讲的文字记录。首先,使用主题建模来确定演讲的主题,并考察主题在过去二十年中的趋势。虽然有一些冷静的观察和潜在的解释,但我们应该记住,样本量可能太小,无法得出任何可靠的结论。第二,研究不同职业的演讲者和来自美国不同地区的观众的主题分布。从观众的角度来看,未来我们可以根据演讲者的职业来猜测演讲主题,这可能会影响一个机构如何选择邀请哪个演讲者参加毕业典礼。对于演讲者来说,知道观众来自哪里,这种分析可以揭示什么主题可能更好地谈论。最后但同样重要的是,对演讲持续时间内的情绪进行分析。大部分演讲的常见套路是积极的开场和积极的结尾,中间有些起伏。然而,振动的幅度因说话者的职业而异。
请在下面留下你的问题或评论!
完整演示文稿
自动化回归测试初学者指南
原文:https://towardsdatascience.com/beginners-guide-to-automating-regression-testing-5e133d1824e?source=collection_archive---------24-----------------------
利用 Jest 和木偶来测试你的网页

亚历山大·奈特在 Unsplash 上拍照
回归测试检查对系统所做的更改是否负面影响或破坏了任何现有的特性。它通常在每次更新或提交代码库之后立即执行,以识别新的 bug 并确保您的系统正常工作。
它是软件测试生命周期的一个重要部分,并提供以下好处:
- 在更新后识别和检测错误。这允许团队立即修复 bug,并确保对现有客户的影响最小。
- 在项目因未检测到的错误而失控之前,减轻并降低项目的风险
- 添加新功能时过渡更顺畅,不会破坏现有功能
自动化回归测试
当谈到测试时,测试自动化总是大多数组织的首选。然而,发现什么应该自动化以及如何自动化可能是一个挑战。
创建稳定和健壮的测试脚本可能相当复杂,需要经验才能做好。此外,扩展整个自动化流程也是大多数缺乏开发运维经验的组织面临的另一个障碍。
有相当多的工具可以帮助您简化整个测试过程。例如,Jest 和 Selenium 等开源模块是项目中 kickstart 自动化过程的良好选择。
事实上,您可以将它与云服务和智能报告附带的更复杂的工具相结合。其中一个工具是 Perfecto ,它带有免费试用版,允许您:
- 进行长达 240 分钟的实时自动测试,以及
- 通过公共云访问各种流行的真实移动设备。
此外,大多数专业工具都有自己的测试数据和环境,很容易配置。这有助于简化整个测试过程。看看下面的 Github 库,它对两者都进行了 web 测试:
- 桌面
- 移动。
您可以轻松地在 Perfecto 中自动测试,生成智能报告,如下图所示。

图片取自 Perfecto 的官方文档
设置
在本教程中,您将学习使用以下开源工具对网页进行自动化回归测试:
Jest—一个 JavaScript 测试框架,开箱即用,几乎不需要任何配置Puppeteer—通过 DevTools 协议控制 Chromium 的 headless Node.js API。
确保你已经在本地机器上安装了Node.js。建议版本节点 10.18.1 或以上使用puppeteer 3.0.0。
初始化
如果你从一个空的工作目录开始。运行以下命令初始化package.json:
npm init
通过 NPM 安装软件包
接下来,运行以下命令安装所有必需的软件包:
npm install --save-dev jest-puppeteer puppeteer jest
除了 Jest 和 Puppeteer 之外,还有另一个名为jest-puppeteer的包,它带有用于测试这两个包的高级 API。
配置
打开package.json并添加以下配置。这允许您稍后使用yarn test或npm run test运行测试。
"scripts": {
"test": "jest"
}
继续添加下面的代码,它代表 Jest 的配置。
"jest": {
"preset": "jest-puppeteer"
}
你的package.json应该是这样的。请注意,订单和版本号可能不同。
{
"name": "jest-puppet-app",
"version": "1.0.0",
"description": "",
"main": "index.test.js",
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"jest": {
"preset": "jest-puppeteer"
},
"devDependencies": {
"jest": "^26.6.3",
"jest-puppeteer": "^4.4.0",
"puppeteer": "^5.5.0"
}
}
实现测试脚本
完成后,创建一个名为index.test.js的新 JavaScript 文件。随便起什么名字,只要以test.js结尾就行。Jest 将自动捕获所有文件作为测试套件的一部分。
加载网页
我们将使用 Google 的主页运行一个简单的网页测试。在文件中添加以下内容。
describe('Google', () => {
beforeAll(async () => {
await page.goto('https://google.com');
});
});
describe有助于将我们所有的测试用例归为一组。另一方面,beforeAll负责初始化,因为它在整个测试中只被调用一次。您可以将其视为一次性的安装程序块。如果你打算在每个测试用例开始之前执行一些东西,你应该使用beforeEach来代替。
默认情况下,它将以无头模式运行,不涉及任何接口。对于健全性检查,我们的测试是基于谷歌的主页。
检查标题
让我们从一些简单的东西开始,比如网页标题上的断言。继续在beforeAll语句的正下方追加一个新的测试函数。我们将检查页面的标题是否与字符串Google匹配。it是内置test函数的别名。你可以互换使用它们。
describe('Google', () => {
beforeAll(async () => {
await page.goto('https://google.com');
}); it('should be titled "Google"', async () => {
await expect(page.title()).resolves.toMatch('Google');
});
});
运行测试脚本
保存文件并在您的终端中键入以下内容来运行我们的测试脚本:
npm run test
您应该会看到以下输出:

作者图片
检查文本内容
事实上,您可以在断言之前为返回的响应分配一个变量。这为您想要测试的东西提供了更好的控制。例如,您可以用下面的代码检查网页的正文是否包含字符串google:
it('should load without error', async () => {
let text = await page.evaluate(() => document.body.textContent);
expect(text).toContain('google');
});
检查元素
jest-puppeteer附带以下高级 API 方便您使用。
[toClick](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toClick)—期望一个元素在页面或元素中,然后点击它。[toDisplayDialog](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toDisplayDialog)—期望块函数触发一个对话框并返回。[toFill](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toFill)—期望页面或元素中有控件,然后用文本填充它。[toFillForm](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toFillForm)—期望页面或元素中有一个表单,然后填充其控件。[toMatch](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toMatch)—期望页面或元素中出现文本或字符串 RegExp。[toMatchElement](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toMatchElement)—期望页面或元素中存在元素。[toSelect](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toSelect)—期望页面或元素中出现选择控件,然后选择指定的选项。[toUploadFile](https://github.com/smooth-code/jest-puppeteer/blob/master/packages/expect-puppeteer/README.md#toUploadFile)—期望输入文件控件出现在页面或元素中,然后用本地文件填充它。
有时,您可能想要检查特定的 UI 元素,比如输入或按钮。在这种情况下,您可以利用toMatchElement功能来帮您实现。它接受一个表示匹配元素的 CSS 选择器的字符串。下面列出了一些最常见的 CSS 选择器
type selector—代表节点名称。例如,input将匹配第一个<input>元素。class selector—基于类别的匹配。语法以classname前面的点开始。例如,.box将匹配包含类box的第一个元素。id selector—根据id选择元素。语法以#符号为前缀。例如,#firstHeading将匹配保存 idfirstHeading的第一个元素。attribute selector—选择具有给定属性的元素。例如,input[value=”Click Me”]将匹配第一个<input>元素,并将Click Me作为其值。
toMatchElement将返回第一个匹配的元素。如果没有匹配元素,它将报告一个错误。
让我们添加以下测试函数,该函数检查以下元素是否存在:
- 名为
btnK且值为Google Search的输入 - 名为
btnI且值为I’m Feeling Lucky的输入
it('should contain a Google Search and Lucky button', async () => {
await expect(page).toMatchElement('input[name="btnK"][value="Google Search"]');
await expect(page).toMatchElement(`input[name="btnI"][value="I'm Feeling Lucky"]`);});
此外,在执行匹配后,您可以利用 evaluate 函数从元素中提取信息。这允许您对提取的信息单独执行断言。
下面的例子说明了如何根据预定义的值来验证特定元素的href和innerHTML是否正确。
你可以在下面的要点中找到完整的 JavaScript 代码。
保存文件并运行以下命令再次测试它。
npm run test
最终输出应该如下所示:

作者图片
结论
让我们回顾一下今天所学的内容。
我们从回归测试的详细解释和自动化面临的挑战开始。
然后,我们通过npm安装了必要的包,并对package.json文件做了一些修改。
我们继续用 JavaScript 实现了一个简单的测试脚本,用于检查网页的标题。此外,我们还尝试了由jest-puppeteer提供的其他高级 API。
感谢你阅读这篇文章。希望在下一篇文章中再见到你!
参考
- 木偶师 Github
- Jest Github
- 小丑 Github
- Jest——与木偶师一起使用
- Mozilla — CSS 选择器
梯度下降初学者指南
原文:https://towardsdatascience.com/beginners-guide-to-gradient-descent-47f8d0f4ce3b?source=collection_archive---------14-----------------------
关于梯度下降法你需要知道的一切

由 Ales Krivec 在 Unsplash 上拍摄的照片
梯度下降法是最优化问题的解决指南,在它的帮助下,人们可以找到函数的最小值或最大值。这种方法用于训练模型的机器学习领域,在那里被称为梯度下降法。
梯度下降法有什么用?
人工智能的目标通常是创建一种算法,该算法可以在输入值的帮助下尽可能准确地进行预测,即非常接近实际结果。预测和现实之间的差异通过所谓的损失函数转换成一个数学值。梯度下降法用于寻找损失函数的最小值,因为这样就找到了模型的最佳训练条件。
AI 算法的训练然后用于尽可能最小化损失函数,以便具有良好的预测质量。例如,人工神经网络在每个训练步骤中改变单个神经元的权重,以逼近实际值。为了能够专门解决损失函数的最小化问题并且不随机改变各个权重的值,使用了特殊的优化方法。在人工智能领域,最常使用的是所谓的梯度下降法。
为什么我们接近最小值而不仅仅是计算它?
从微积分中我们知道,我们可以通过设置一阶导数等于 0,然后检查二阶导数在这一点上是否不等于 0 来确定一个最小值或最大值。理论上,我们也可以将这个过程应用于人工神经网络损失函数,并使用它来精确地计算最小值。然而,在具有许多变量的更高的数学维度中,精确的计算是非常昂贵的,并且将花费大量的计算时间,最重要的是,资源。在神经网络中,我们可以很快拥有几百万个神经元,从而在函数中相应地拥有几百万个变量。
因此,我们使用近似方法来快速接近最小值,并确保在一些重复之后找到接近最小值的点。
梯度下降的基本思想
梯度下降法的背后是一个数学原理,即函数的梯度(函数的导数有一个以上的自变量)指向函数上升最多的方向。相应地,相反的情况也成立,即函数在梯度的相反方向上下降得最厉害。
在梯度下降法中,我们试图尽可能快地找到函数的最小值。在人工智能的情况下,我们正在寻找损失函数的最小值,我们希望非常快地接近它。所以如果我们沿着梯度的负方向走,我们知道函数下降得最多,因此我们也最快地接近最小值。
对于函数 f(x) = x,我们已经画出了在某些点上具有梯度 f′(x)的切线。在这个例子中,最小值在点 x = 0 处。在点 x = -3 处,切线的斜率为-6。根据梯度法,我们应该向梯度的负方向移动,以更接近最小值,所以— (- 6) = 6。这意味着最小值的 x 值大于-3。然而,在点 x = 1 处,导数 f′(1)的值为 2。因此,梯度的相反方向将是-2,这意味着最小值的 x 值小于 x = 1。这使我们逐渐接近最小值。
简而言之,梯度下降状态:
- 如果函数的导数在 x 点是负的,我们在 x 方向上向前寻找最小值。
- 如果函数的导数在点 x 处为正,我们在 x 方向上向后寻找最小值。
在函数有多个变量的情况下,我们不仅要考虑导数,还要考虑梯度。在多维空间中,梯度相当于二维空间中的导数。
我们需要学习率做什么?
梯度下降法给了我们每个起点对应的方向。然而,它并没有告诉我们应该在相应的方向上走多远。在我们的例子中,借助梯度法,我们无法知道在 x = -3 的位置,我们是否应该在正 x 方向上走一步、两步,甚至三步。
在学习率的帮助下,我们可以设置每一步应该有多大。存在学习率的值可以在每一步中改变的方法,但是在大多数情况下,学习率的值是恒定的,并且例如是 0.001 的值。
我们如何找到最佳的学习速度?
学习率大小的决定实际上似乎很简单。在小的学习率下,我们接近最小值的速度非常慢,尤其是当我们的起点远离极值点的时候。另一方面,如果我们使用较大的学习率,我们可能会更快地向最小值移动,所以我们应该选择较大的学习率。不幸的是,事情没那么简单。
例如,在我们不知道的情况下,起点已经非常接近最小值。那么大的学习率可能太大,以至于我们永远不会达到最小值。如果我们从点 x=1 处的函数 f(x) = x 开始,并使用学习率> 1,我们将不能很快达到最小值 x = 0,因为到最小值的距离只有 1。
因此,选择一个合适的学习速率并不容易回答,也没有一个我们可以使用的最佳值。在机器学习中,这样的参数有一个名字:超参数。这些是模型中的参数,其值对成败至关重要。这意味着,通过改变超参数,表现不佳的模型可能会变得明显更好,反之亦然。学习率是许多超参数中的一个,并且应该在不同的训练运行中简单地变化,直到达到模型的最佳值。
梯度下降的问题
使用梯度法时,我们可能需要处理两个主要问题:
- 我们最终得到的是函数的局部最小值,而不是全局最小值:有许多变量的函数很可能不只有一个最小值。如果一个函数有几个极值,比如最小值,我们称之为具有最低函数值的最小值的全局最小值。其他最小值是所谓的局部最小值。梯度下降不会自动使我们免于寻找局部最小值而不是全局最小值。然而,为了避免这个问题,我们可以测试许多不同的起点,看看它们是否都收敛到同一个最小值。
- 当我们在神经网络及其损失函数的上下文中使用梯度下降法时,会出现另一个问题。在特殊情况下,例如当使用前馈网络时,梯度可能是不稳定的,即它可能变得非常大或者非常小并且趋向于 0。借助于神经元的其他激活函数或权重的某些初始值,可以防止这些影响。但是,这超出了本文的范围。
多维空间中的梯度法
对于我们最初的例子 f(x) = x,极值点很容易计算,也可以不用梯度法确定。由于变量不止一个,这就不再那么容易了。比如,我们取函数 f(x,y) = x + y,试着分几步逼近最小值。
1.起点的确定:如果要用梯度下降法,我们需要一个起点。有许多方法可以找到一个最佳的起点,但这不是本文要详细讨论的。我们简单地从点 P(2,1)开始搜索。
2.计算导数/梯度:接下来我们要计算函数的一阶导数。在多维空间中,这被称为梯度。它是变量所有导数的向量。在我们的例子中,函数由两个变量组成,所以我们需要形成两个导数。一个是以 x 为变量的一阶导数,另一个是以 y 为变量的一阶导数:

梯度就是向量,第一项是对 x 的导数,第二项是对 y 的导数:

3.插入起点:现在我们将起点插入渐变:

4.将步长为负的渐变添加到起点:最后一步,我们现在从起点开始沿着渐变的负方向前进。也就是我们从起点减去梯度乘以学习率。学习率为 0.01,这意味着:

因此,我们现在有了我们的新点 p₂(1.96;0.98),用它我们可以重新开始该过程以接近最小值。
这是你应该带走的东西
- 梯度下降用于尽可能快地逼近函数的最小值。
- 为此目的,人们总是在梯度的负方向上在一个点上迭代。步长由学习速率决定。
- 梯度下降可以有不同的问题,这些问题可以借助于不同的激活函数或初始权重来解决。
如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !此外,媒体允许你每月免费阅读 3 篇 。如果你想让无限制地访问我的文章和数以千计的精彩文章,不要犹豫,通过点击我的推荐链接:*https://medium.com/@niklas_lang/membership获得会员资格,每个月只需支付 5**
*** ***
Kubernetes 和 Docker 初学者指南
原文:https://towardsdatascience.com/beginners-guide-to-kubernetes-and-docker-c07655e43ebb?source=collection_archive---------29-----------------------
你需要知道的关于 Kubernetes 及其应用的一切

照片由 Unsplash 上的 Ihor Dvoretskyi 拍摄
Kubernetes 是一个容器编排系统。这意味着应用程序可以在不同的容器之间拆分,从而运行得更快更有效。它是一个开源项目,于 2014 年首次发布。Kubernetes 非常强大,可以管理分布在数千台计算机上的系统。
为什么 Kubernetes 也叫 k8s?
顺便说一下,希腊语 Kubernetes 的意思是舵手,这正是程序所做的,它控制。在本文中,我们将主要使用 Kubernetes k8s 的缩写。这是因为 Kubernetes 这个词以 k 开头,以 s 结尾,中间有 8 个字母。
什么是容器,我们为什么需要它们?
大数据或机器学习的一个定义特征是,在许多情况下,一台计算机不足以处理大量的计算负载。因此,有必要使用多台可以分担工作的计算机。此外,群集还可以弥补单个计算机的故障,从而确保应用程序可以连续访问。我们将这种计算机排列称为并行计算的计算集群或分布式系统。
现在我们知道什么是集群,但是我们还不知道容器是什么。
容器来自 Docker 软件环境。现在,只是这样:我们实际上可以认为 Docker 容器是相对实用的,就像一个运输容器。让我们假设三个人在这个容器中从事某项任务(我知道这很可能违反了每一个适用的职业健康和安全法,但它非常符合我们的例子)。
在这个容器中,他们找到了完成任务所需的所有资源和机器。他们通过容器中的某个舱口接收所需的原材料,并通过另一个舱口释放成品。因此,我们的集装箱可以相对不受干扰地运行,并在很大程度上自给自足。里面的人不会注意到包括集装箱在内的船现在是在巴西的汉堡港,还是在平静的海面上。只要有源源不断的原料供应,不管他们在哪里,他们都会执行任务。
软件环境中的 Docker 容器也是如此。它们是精确定义的、独立的应用程序,可以在不同的机器上运行。只要它们持续接收规定的输入,它们也可以持续工作。
我们要 Kubernetes 做什么?
到目前为止,我们已经讨论过:我们使用计算集群在多台计算机上可靠、高效地运行计算密集型项目,如机器学习模型。反过来,在容器中,我们编写子任务,这些子任务可以是独立的,并且总是以相同的方式运行,不管它们是在计算机 1 上运行还是在计算机 2 上运行。这听起来足够了,不是吗?
分布式系统提供了优于单个计算机的优势,但也带来了额外的挑战,例如,在集群内的计算机之间共享数据或通信。Kubernetes 接管将容器分发到集群的工作,并确保程序顺利运行。这使我们能够专注于实际问题,即我们的特定用例。
Kubernetes 集群是如何构建的?
Kubernetes 通常安装在一组计算机上。该集群中的每台计算机被称为一个节点。反过来,几个所谓的吊舱在一台计算机或节点上运行。最后,带有较小应用程序的容器在 pod 上运行,并且可以在本地系统中通信。
为了让 pod 和其中的容器运行起来不复杂,Kubernetes 集群中有一些辅助功能和组件来确保所有系统都在运行。
- 控制面板:这是监控整个集群的电脑。它不为应用程序运行任何 pod。取而代之的是,单独的 pod 被分配了在其上运行的容器。
- Sched :调度器在集群中留意新创建的 pod,并将它们分配给现有的节点。
- ETCD :集群中积累的需要保存的所有信息的存储库,例如配置元数据。
- 云控制器管理器(CCM) :当系统的一部分运行在云资源上时,这个组件开始发挥作用,处理与云的通信和协调。
- 控制器管理器(CM):Kubernetes 集群中最重要的组件监控集群,寻找故障节点,然后重新分配容器和 pod。
- API :该接口实现节点与控制平面之间的通信。
节点的设计比控制面板更薄,除了 pod 之外,还包含两个用于监控的基本组件:
- Kubelet :它是一个节点内的控制平面,保证所有吊舱正常运行。
- Kube proxy (k-proxy) :该组件通过在节点内部创建网络,将传入的节点流量分发到 pods。
用 k8s 有什么好处?
计算机集群的原理是计算机科学的一个真正突破,因为它允许管理密集的计算任务,并且由于可伸缩性,还可以以比强大的机器相对更低的成本提供。然而,直到 k8s 的引入,管理这样的集群是非常昂贵的,并且实际上是不可管理的。这也是 Kubernetes 现在成为真正的行业标准的原因之一。
其他优势包括:
- 自动扩展:根据需求,(云)资源可以增加或减少。这样可以节省成本,因为这样可以避免基础架构被设置为处理高峰,而在其他时间保持闲置状态。比如某票务平台,可以在知名艺人卖演唱会门票的时候,响应抢购。但是,由于这些版本是例外,因此他们可以缩减其基础架构。
- 负载平衡:控制器管理器可以将单个计算机的负载转移到其他机器上。这可以防止系统故障并减少组件的负载。
- 开发者友好性:对于应用开发者来说,Kubernetes 提供的优势是它已经可以集成到许多工具中,程序员可以完全专注于实际任务。
- 本地和云的兼容性 : Kubernetes 也用于构建混合基础设施,部分运行在云中,部分运行在本地服务器上。通过 Kubernetes,这些组件之间的通信和协作变得很容易。
清晰:K8s 为整个集群提供了一个清晰的仪表板,提供了一个初步的概览,并使问题区域很快显现出来。
Kubernetes 支持哪些应用程序?
- 网站:网站上的负载并不总是一样的。高峰时段网站上的用户比晚上多。在 Kubernetes 的帮助下,可以有针对性地控制负载。
- 微服务架构:如今许多应用都采用所谓的微服务架构。这意味着复杂的应用程序,如一个网站,被分成小的,可管理的微服务。这样,它们就比“困”在一个单一的大型应用程序中更容易改进或更新。在这样的安排中,微服务可以部署在单独的容器中,这些容器又由 Kubernetes 进行编排。
- 软件即服务——产品:在这个领域,一家公司提供客户使用的特定软件。因为客户代表一系列应用程序场景,所以集群上的负载必须相应地分布和平衡。
今天,Kubernetes 被用在任何有分布式系统的地方。此外,在投入使用之前的不同阶段工作时,它简化了开发工作。Kubernetes 的应用领域包括:
- 由不同计算机组成的网络称为集群。反过来,容器可以自主执行某项任务,而不管它在什么系统上执行。
- Kubernetes 为我们处理计算集群中容器的管理。
- Kubernetes 集群具有各种组件,可确保所有 pod 都在运行,系统继续运行。
这是你应该带走的东西
- 由不同计算机组成的网络称为集群。反过来,容器可以自主执行某项任务,而不管它在什么系统上执行。
- Kubernetes 为我们处理计算集群中容器的管理。
- Kubernetes 集群具有各种组件,可确保所有 pod 都在运行,系统继续运行。
如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !此外,媒体允许你每月免费阅读三篇文章。如果你想让无限制地访问我的文章和数以千计的精彩文章,不要犹豫,通过点击我的推荐链接:【https://medium.com/@niklas_lang/membership】每月花$ 5 获得会员资格*
** **
2021 年学习计算机视觉的初学者指南
原文:https://towardsdatascience.com/beginners-guide-to-learn-computer-vision-in-2021-6083ab6de6af?source=collection_archive---------26-----------------------
阅读可以帮助你提高计算机视觉技能的资源

尼克·莫里森在 Unsplash 上拍摄的照片
从我本科学习的第一年开始,我就是机器人俱乐部的一员,在那段时间,深度学习是我们大学里一个相当新的流行词。在我的俱乐部里,每个人都对计算机视觉着迷,因为在一次关于图像处理的研讨会之后,我们都认为这个世界已经向我们展示了它的真正潜力!现在在从众的驱使下,我也学习和发掘了和身边所有人一样的资源,他们给了我很大的基础。但是我第一次面试一家计算机视觉初创公司就让我找到了自己的位置。我不知道这个领域到底有多广阔,所以为了帮助你们避免尴尬,我汇集了一些资源,让你们的旅程更轻松。
首先,花点时间了解自己是否真的喜欢这个领域。为此,我将链接一些展示特定应用的博客,如果您感兴趣,请继续查看相应的资源。
在线课程
先说计算机视觉的基础知识,以及大家需要的基本概念。我更喜欢的学习方式总是通过在线讲座,因为我可以控制速度,而且对于更简单的概念,我可以浏览笔记而不是观看整个视频。所以接下来的系列讲座对学习 CV 是相当全面的。
- 计算机视觉简介,Udacity,佐治亚理工学院提供。这门课程帮助我克服了学习这个全新领域的恐惧。
- CS231n:用于视觉识别的卷积神经网络,斯坦福大学。这门课的老师是这个领域的世界知名教授,在我看来,这是 CNN 最好的课程之一。
- 计算机视觉讲座,Alberto Romay。通俗易懂的讲座系列为了让初学者对 CV 有一个完整的了解,我的一些朋友学习了这个课程而不是第一个。
为了充分利用这些课程,坚持一个系统的时间表,并适当地练习每一项作业,以清除你的基础知识。这将让你在使用计算机视觉和深度学习的通用框架和平台时充满信心。
编码和实现
学习 CV 的第一步是用你选择的语言学习 OpenCV 框架。对于大多数应用程序,我更喜欢 OpenCV 而不是 MATLAB,但这取决于您。学习图像处理、相机几何和 OpenCV 的一些书籍有:
- 使用 OpenCV 库学习 OpenCV 3:c++中的计算机视觉,Adrian Kaehler 和 Gary Bradski( Book )
- 3D 计算机视觉技术和算法介绍,博古斯瓦夫·西加内克和 j .保罗·西伯特(书)
深度学习框架:
深度学习框架帮助你实现各种深度学习架构。它们使得不同神经网络的实现更加容易。最常用的框架有【py torch】Keras、 和 TensorFlow 。我个人在大多数情况下使用 PyTorch,因为我觉得它易于理解和实现。还有更多构建在 PyTorch 或 TensorFlow 之上的库/框架,使实现更加容易。下面是两个这样的库,我相信会很有帮助。
- Fast.ai 是你应该注意的下一个课程。还有,fast.ai 是 PyTorch 上面的高层框架,但是他们改 API 太频繁了,文档的缺乏使得用起来不太靠谱。然而,理论和有用的技巧只是花时间观看本课程的幻想。(免费)
- PyTorch Lightning 是当今最热门的图书馆之一。它可以帮助你实现多 GPU 训练和许多其他工程设施,只需改变一些参数。如果你想学习 PyTorch 闪电,我写了这篇博客。
研究及其实施
计算机视觉在不断进步,这个领域的研究也在以极快的速度进行。因此,尤其是在深度学习和计算机视觉的交汇点,让自己跟上当前最先进的方法是很重要的。
- ArXiv.org——你可以在这里找到几乎所有的研究论文,最棒的是,它是完全免费的。
- Github —你可以在 Github 上找到所有的开源代码。查看和阅读代码有助于您清晰地实现不同的研究论文,并增强您实现任何新架构的信心。
竞争
如果你在学习新事物的时候需要持续的动力,参与竞争将是最好的选择。我有很多朋友,只通过参加多个比赛,就了解了很多不同的概念。有许多可用的网站,但我通常更喜欢以下方式:
- 他们有许多活跃的竞争和不活跃的竞争。你可以利用这个地方通过参加不活跃的竞赛来学习,看看哪种方法表现最好,然后找出原因。你可以参与到积极的竞争中来,让自己相信你能够理解问题并相应地处理它(显然,只有当你足够自信,能够找出哪件事最适合当前的问题陈述时,你才应该这样做)
- 参加 CVPR、ECCV、ICCV、AAAI 等会议组织的比赛。这些会议是顶级的计算机视觉会议,每个人都梦想在这些会议上发表论文,因此如果你能在排行榜上名列前茅,你也将有机会参加这些会议,我个人认为这将使你完美地接触到当前的艺术状态。
必须阅读研究论文
以上提到的东西足以成为计算机视觉的媒介。但是,我强烈建议也阅读下面列出的一些研究论文。阅读研究论文有助于你了解研究中的新观点,并激发你进行创新思维。我还附上不同主题的介绍性博客或视频。
- 图片分类(博客)——AlexNet、 GoogLeNet 、 VGG16 、 ResNet 、 Inception 、 Xception 、 MobileNet
- 物体检测。(视频)——RCNN、 Fast-RCNN 、Fast-RCNN、 SSD 、 YOLO
- 物体跟踪。(视频)——SMOT,费尔莫特
- 语义分割。(博客)——FCN、塞格内 t、 UNet 、 PSPNet 、 DeepLab 、 ICNet 、 ENet
- 实例分割。(博客 ) — Mask-RCNN , YOLACT
希望这篇文章能为你学习计算机视觉提供必要的资源。如果你认为添加更多的东西可以使这篇文章更好,更值得一读,我随时欢迎你的建议。关注我们的媒体阅读更多此类内容。
成为 介质成员 解锁并阅读介质上的许多其他故事。
Python 正则表达式初学者指南
原文:https://towardsdatascience.com/beginners-guide-to-regular-expressions-in-python-d16d2fa31587?source=collection_archive---------11-----------------------
关于正则表达式的简单教程,涵盖了你需要知道的所有基础知识

真诚媒体在 Unsplash 上拍摄的照片
介绍
在我们当前的时代,有来自各种来源的大量数据,尤其是文本数据。在数据驱动的一代,诸如 机器学习 和 自然语言处理 等技术充分利用了自然语言数据的力量来分析和提取以前不可能的有趣见解。在分析文本数据的过程中,在将数据输入模型之前,对其进行预处理几乎是一个必要的步骤。在预处理步骤中,在输入文本中搜索特定的模式可能是有用的。
这就是正则表达式的用武之地!正则表达式试图发现一个输入字符串中是否存在一个指定的模式,当它存在时执行一些操作。这对于许多涉及文本分析和处理的数据科学项目非常有用。
本文将教你使用 Python 的正则表达式的基础知识。在进入本文之前,我们先来导入正则表达式库:

导入库
基本语法
基本上,正则表达式(regex)是关于在输入字符串上捕获一组文本并对它们执行一些操作。为此,我们需要一种方法来定义某些模式(例如数字、字母、标点符号),以便我们可以在输入字符串中进行捕获或匹配。为了方便起见,regex 为我们提供了这些非常容易理解和使用的模式:

正则表达式基础
在固定字符匹配的基础上进行扩展,regex 还通过定义不同的字符集来支持更灵活的匹配,例如数字、字母数字字符等。

正则表达式字符类
此外,regex 还定义了一些量词,您可以将这些量词放在字符集旁边,以指示您想要捕获多少字符集:

正则表达式量词
在我们熟悉了 regex 提供的模式类型之后,我们现在可以看看最常见的函数。
5 个最常见的正则表达式函数
这里列出了最常用的正则表达式函数,下面还提供了示例:
re.match(<regex>, s):从输入字符串s的开头开始查找并返回正则表达式<regex>的第一个匹配项re.search(<regex>, s):查找并返回输入字符串s中正则表达式<regex>的第一个匹配re.finditer(<regex>, s):查找并返回一个迭代器,该迭代器由输入字符串s中正则表达式<regex>的所有匹配组成re.findall(<regex>, s):查找并返回输入字符串s中正则表达式<regex>的所有匹配列表re.sub(<regex>, new_text, s):查找输入字符串s中正则表达式<regex>的所有匹配,并用new_text替换
重新匹配
re.match(<regex>, s)匹配从句子开头开始的正则表达式模式,并返回匹配的子字符串。如果发现了什么,那么它返回一个re.Match对象;如果没有,则返回 none:

要获得匹配的子串和文本的位置,可以分别使用.span()和.group()。

如果匹配的子字符串不是从输入字符串的开头开始,则re.match将返回None:

重新搜索
re.search(<regex>, s)匹配整个输入句子中的正则表达式模式,并返回匹配的子字符串的第一个匹配项。re.search和re.match的区别在于,re.search 匹配的子串不必从输入字符串的开头开始。与re.match一样,当找到匹配时,它也返回一个re.Match对象:

重新发现
re.finditer(<regex>, s)匹配输入字符串中的所有正则表达式模式,并返回一个迭代器,其中包含匹配子字符串的所有re.Match对象。与re.match和re.search类似,您可以使用.span()和.group()来获取位置和匹配的子字符串。

重新发现
re.findall(<regex>, s)匹配输入字符串中的所有正则表达式模式,并返回包含所有匹配子字符串的列表。re.findall和re.finditer唯一的区别是re.findall返回一个列表而不是一个迭代器,并且包含匹配的子字符串而不是re.Match对象。

回复
re.sub(<regex>, new_text, s)匹配输入字符串中的所有正则表达式模式,并用提供的new_text替换它们。

而这些都是 regex 提供的基本功能!
分组
到目前为止,您可能注意到所有的例子都捕获了完整的正则表达式模式。但是,您可能希望匹配一个正则表达式模式,但只捕获它的一部分(或一组)。幸运的是,regex 通过使用括号()提供了一种简单的方法。您可以通过在 regex 模式中用()将想要捕获的组括起来来定义它,如下例所示:

旁注
在处理正则表达式时,记住以下两点可能会有所帮助。
编译的正则表达式函数
在上面的例子中,你可能会注意到我们主要是直接使用re提供的模块级函数。执行正则表达式模式匹配的另一种方法是首先编译模式,然后调用编译对象上的函数:

这两种方法是做同一件事的替代方法,几乎没有性能差异,所以您可以使用您喜欢的任何方法。通常,如果您打算多次使用该模式,您可以使用编译方法;否则,使用模块级函数更简单。
Python 原始字符串' r '
每当您试图匹配输入字符串中的反斜杠\字符时,您可能会尝试这样做:

但是,如您所见,没有返回任何对象。这是因为在处理正则表达式时,模式首先被传递给 Python 字符串解释器,后者将前两个\\解释为\,然后被传递给 regex 解析器,后者将\视为后面的转义字符。因此,一个解决方法是使用四个反斜杠\\\\:

或者,更简洁方便的方法是使用 Python 原始字符串r跳过 Python 解释器级别,以避免重复反斜杠:

结论
恭喜你到达文章末尾!希望你学到了一些东西,现在更熟悉使用 Python 的正则表达式。如果你喜欢我的帖子,请随时关注我,并欢迎看看我的其他文章!
参考
[1] Python 官方文档关于正则表达式,Python
[2]Python-正则表达式,TutorialsPoint
[3]Python Regex cheat sheet,Debuggex
如何用 UMAP 以惊人的美丽方式分析 100 维数据
原文:https://towardsdatascience.com/beginners-guide-to-umap-for-reducing-dimensionality-and-visualizing-100-dimensional-datasets-ff5590fb17be?source=collection_archive---------3-----------------------
降低维度并“看到”您的数据

照片由 艺术工作室 拍摄自 像素
介绍
无论机器学习模型有多强大,它们都无法击败你在“啊哈!”通过丰富的视觉效果探索数据的瞬间。但是,在你说“这真的过时了”之前,你可以创建这么多直方图、散点图、热图
在那些时刻,你需要一些东西来提醒你数据是多么的惊人和迷人。你需要从像流动数据或相关子编辑这样的杰作视觉效果中获得灵感,但你不必走那么远。最近,我很幸运地遇到了 UMAP——一个以惊人的美丽方式可视化和聚集高维数据的 Python 包。这正是我需要记住的,为什么我两年前开始学习数据科学。
今天,我们将学习如何通过使用统一流形近似和投影(UMAP)包将多维数据集投影到 2D 来分析多维数据集,如下所示:



作者图片和 UMAP 文档。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
什么是 UMAP?
UMAP 是一种降维算法,也是一种强大的数据分析工具。
就速度而言,它类似于 PCA(主成分分析),并类似于 tSNE 来降低维度,同时尽可能多地保留数据集的信息。在 2018 年推出 UMAP 算法之前,PCA 和 tSNE 有两个最显著的缺陷:
- 主成分分析速度非常快,但代价是减少后丢失了更精细的数据细节
- tSNE 非常慢,尽管它保留了数据的底层结构。
我们将在后面详细讨论这些差异。现在,是时候领略一下 UMAP 的风采了,我们将立即从一个具有挑战性的数据集开始:

为 Kaggle TPS 九月竞赛生成的合成数据。
>>> tps.shape(957919, 119)
Kaggle TPS 九月数据集包含约 100 万行和约 120 个要素,目标为二进制。它们都是数值型的,我们对在这个数据集上执行适当的 EDA 很无能为力。我们的选项仅限于打印汇总统计数据和绘制每个特性的直方图。
让我们看看 UMAP 能为我们做些什么。在使用它之前,我们将对数据集进行采样以避免过度绘制,并填充缺失的值:
这里,目标表示客户是否要求他们的保险。
在安装并导入 UMAP 后,我们初始化流形算法,并以熟悉的 Sklearn fit/transform模式将其拟合到X、y:
>>> X_reduced.shape(100000, 2)
默认情况下,UMAP 将数据投影到两个部分(2D)。让我们创建一个由目标类着色的散点图:
>>> plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=y, s=0.5);

尽管看起来很有趣,但情节并没有显示出任何清晰的模式。这是因为我们在拟合 UMAP 之前没有缩放特征。该算法使用距离度量对相似的数据点进行分组,并且具有较高比例的要素会对此类计算产生偏差。
因此,我们将选择分位数转换器来根据分位数和中位数缩放要素。这种缩放方法更适合数据集,因为它包含许多倾斜和双峰特征:
# Plot the results
plt.scatter(X_reduced_2[:, 0], X_reduced_2[:, 1], c=y, s=0.5);

现在,我们正在谈话!UMAP 设法完美地捕捉到了目标阶层之间隐藏的区别。我们还可以看到一些异常值(黄色斑点周围的点)。数据集毕竟没有那么有挑战性。
但是,这个情节和我给你看的一点也不接近。在每一个集群中看到结构模式仍然是多余的。为了更上一层楼,我们将使用默认的 UMAP 可视化软件包和更多的功能。我们需要一个更好的数据集。
与 UMAP 更好的可视化
本节将分析 Kaggle TPS 月份的竞争数据,这些数据根据大约 75 个数字质量对大约 20 万个电子商务列表进行了分类。让我们导入它并快速浏览一下:

为 Kaggle TPS 九月竞赛生成的合成数据。
目标包含九个类。
和以前一样,我们将扩展所有功能,但这次是通过简单的对数转换。然后,我们拟合 UMAP 流形:
拟合完成后,我们将导入umap.plot包(单独安装)并绘制一个点云:

它不像太空中的星云吗?我们可以清楚地看到,8 类主宰了空间,并聚集在中心。第 6 类也与其他类明显不同。我们看到半个圆形的混合数据点围绕着第 8 类。关于单个数据点,它们可以被归类为异常值。
上面关于可视化的一个注意事项——我们只是传递拟合的流形(不是转换的数据!)到
points函数,并指定颜色编码的标签。我也选择了fire作为黑暗主题。
您也可以使用umap.plot.connectivity创建连接图,用于诊断目的,并更好地理解歧管结构。请注意,创建这些图非常耗时,而且计算/内存负担很重。


您可以从文档的本节中了解更多关于 UMAP 可视化的信息。
UMAP 的最基本参数
潜在的减少算法具有许多参数,这些参数可以显著地影响流形,从而影响视觉效果。四个最重要的是:
n_componentsn_neighborsmin_distmetric
正如你可能已经猜到的,n_components控制投影后的维数。为了便于可视化,默认值为 2。但是,对于包含 100 个以上要素的数据集,2D 可能不足以完全保留数据的基础拓扑结构。我建议以 5 为步长尝试 2-20 之间的值,并评估不同的基线模型,以查看准确性的变化。
接下来,我们有n_neighbors。它控制着 UMAP 在构建流形时为每个样本寻找的局部邻域的面积。较小的值将关注点缩小到局部结构,考虑到特性和小模式,可能会丢失大的图片。
n_neighbors的值越大,灵活性越大,允许 UMAP 关注相应维度的数据的更广泛“视图”。当然,这是以失去结构的细节为代价的。该参数的默认值为 15。

将具有不同 n _ 邻域的 UMAP 流形拟合到 TPS 六月数据的样本
另一个关键参数是min_dist,它控制数据点之间的文字距离。您可以调整默认值 0.1 来控制不同点云的紧密度。较低的值将导致更密集的嵌入,使您更容易看到单个簇。这在聚类过程中可能很有用。相比之下,接近 1 的值给点更多的喘息空间,并使您能够看到更广泛的拓扑结构。

用不同的最小距离拟合 UMAP 流形
metric表示计算点与点之间距离的公式。默认是euclidean,但是你可以在很多其他选项中选择,包括manhattan、minkowski和chebyshev。
使用 UMAP 的最佳实践
使用 UMAP 时首先要考虑的是 RAM 消耗。在引擎盖下,UMAP 消耗了大量的内存,尤其是在拟合和创建像连通性图这样的图表时。我建议在至少有 16GB 内存的机器上运行 UMAP。
例如,在创建连通性图时,即使绘图部分中的 200k 行数据集也消耗了约 18GB 的 RAM。文档建议将low_memory设置为 True 作为一种可能的解决方案。此外,我建议通过使用 NumPy 将每一列转换为尽可能小的子类型来减少数据集的内存使用。我在以前的一篇文章中详细讨论了如何处理内存不足的问题:
此外,不要忘记变换/缩放数字要素,因为默认情况下它们往往具有不同的比例。我建议将 QuantileTransformer 用于双峰、三峰等疯狂分布。PowerTransformer 最适合倾斜的特征。无论您选择哪种转换器,目标始终是使特性尽可能呈正态分布。
摘要
今天,我们已经介绍了 UMAP 的基本知识,并且只了解了它的一小部分功能。对于进一步的阅读,我建议查看软件包的文档。在那里,你会看到 UMAP 的不同用例,以及它是如何被谷歌这样的科技巨头用在各种项目中的。
也有专门的部分比较 UMAP 与其他维数约简算法。对于一个数学爱好者来说,你也可以阅读 UMAP 是如何工作的,以及它的公式证明。感谢您的阅读!

您可能也会对…感兴趣
[## 2021 年使用 Optuna 调整 LightGBM 超参数的 Kaggler 指南
towardsdatascience.com](/kagglers-guide-to-lightgbm-hyperparameter-tuning-with-optuna-in-2021-ed048d9838b5) </tired-of-cliché-datasets-here-are-18-awesome-alternatives-from-all-domains-196913161ec9>
XGBoost 分类问题入门指南
原文:https://towardsdatascience.com/beginners-guide-to-xgboost-for-classification-problems-50f75aac5390?source=collection_archive---------1-----------------------
利用最热门的 ML 库实现一流的性能

照片由 唐古尔德 上 像素
XGBoost 是什么,为什么这么受欢迎?
下面给大家介绍一下 ML 社区最火的机器学习库——XGBoost。近年来,它一直是赢得大规模 ML 竞赛的算法背后的主要驱动力。它的速度和性能是无与伦比的,它始终优于任何其他旨在监督学习任务的算法。
该库是可并行化的,这意味着核心算法可以在 GPU 集群上运行,甚至可以在计算机网络上运行。这使得通过对上亿训练样本进行高性能训练来解决 ML 任务成为可能。
最初,它是作为命令行应用程序用 C++编写的。在赢得了物理学领域的巨大竞争后,它开始被 ML 社区广泛采用。结果,现在这个库有了其他几种语言的 API,包括 Python、R 和 Julia。
在这篇文章中,您将学习 XGBoost 解决分类任务的基础知识、XGBoost 的超参数的大量列表的概述以及如何调优它们。
https://ibexorigin.medium.com/membership
获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:
https://alphasignal.ai/?referrer=Bex
术语复习
在我们继续 XGBoost 的代码示例之前,让我们回顾一下我们将在本文中使用的一些术语。
分类任务:一个有监督的机器学习任务,通过研究一个实例的特征来预测该实例是否属于某个类别。例如,通过查看一个人的身体测量值、病史和葡萄糖水平,您可以预测一个人是属于“患有糖尿病”还是“没有糖尿病”。
二进制分类:一种分类类型,目标实例只能属于两个类中的一个。例如,预测电子邮件是否是垃圾邮件,客户是否购买了某种产品等。
多类分类:另一类分类问题,目标可以属于多个类别中的一个。比如预测一只鸟的种类,猜测某人的血型等等。
如果你发现自己被其他术语搞糊涂了,我为初学者写了一个小的 ML 字典:
如何为 XGBoost 预处理数据集
除了基本的数据清理操作之外,XGBoost 还需要满足一些要求才能达到最佳性能。主要是:
- 数字要素应进行缩放
- 分类特征应该被编码
为了展示这些步骤是如何完成的,我们将使用来自 Kaggle 的 Rain in Australia 数据集,我们将根据一些天气测量来预测今天是否会下雨。在本节中,我们将通过利用 Scikit-Learn 管道来关注预处理。

该数据集包含澳大利亚多个气象站 10 年来的天气测量数据。你既可以预测明天下雨,也可以预测今天下雨,所以数据集中有两个目标,名为RainToday、RainTomorrow。
由于我们将只预测RainToday,我们将删除另一个以及其他一些不必要的特性:
cols_to_drop = ["Date", "Location", "RainTomorrow", "Rainfall"]
rain.drop(cols_to_drop, axis=1, inplace=True)
删除
Rainfall列是必须的,因为它记录了以毫米为单位的降雨量。
接下来,让我们处理缺失值,首先查看它们在每列中的比例:
如果比例高于 40%,我们将删除该列:
三列包含超过 40%的缺失值。我们将放弃它们:
现在,在我们继续讨论管道之前,让我们先将数据分成特性和目标数组:
接下来,有分类和数字特征。我们将构建两个独立的管道,稍后将它们合并。
接下来的代码示例将大量使用 Sklearn-Pipelines。如果你不熟悉它们,可以看看我的另一篇文章中关于它们的完整指南。
对于分类特征,我们将使用列的模式估算缺失值,并使用一键编码对其进行编码:
对于数字特征,我将选择平均值作为估算值和StandardScaler,这样特征的平均值为 0,方差为 1:
最后,我们将使用一个列转换器来组合这两个管道。要指定管道是为哪些列设计的,我们应该首先隔离分类和数字特征名称:
接下来,我们将把它们和它们对应的管道一起输入到一个ColumnTransFormer实例中:
完整的管道终于准备好了。唯一缺少的是 XGBoost 分类器,我们将在下一节添加它。
分类问题的 XGBoost 示例
要开始使用xgboost,只需安装pip或conda:
# pip
pip install xgboost
# conda
conda install -c conda-forge xgboost
安装完成后,可以用它的标准别名— xgb导入。对于分类问题,库提供了XGBClassifier类:
幸运的是,分类器遵循熟悉的sklearn拟合预测模式,这意味着我们可以自由地将其用作任何sklearn模型。
在训练分类器之前,我们先对数据进行预处理,并将其分为训练集和测试集:
由于目标包含NaN,所以我是手工估算的。此外,将y_processed传递到stratify也很重要,这样拆分在两个集合中包含相同比例的类别。
现在,我们用默认参数拟合分类器,并评估其性能:
即使使用默认参数,我们也得到了 85%的准确率,这已经相当不错了。在接下来的部分中,我们将通过使用 Scikit-learn 提供的GridSearchCV来进一步改进这个模型。
XGBoost 的幕后动力是什么
与许多其他算法不同,XGBoost 是一种集成学习算法,这意味着它结合了许多模型的结果,称为基本学习器来进行预测。
就像在随机森林中一样,XGBoost 使用决策树作为基础学习器:

图片由作者提供。预测降雨的决策树
上面可以看到一个决策树的例子。在每个决策节点(圆圈)中,有一个问题只有两个可能的答案。在每棵树的底部,都有一个决策(矩形)。在上面的树上,第一个问题是是否是晴天。如果是的话,你马上决定不会下雨。否则,你会继续问更多的二元(是/否)问题,最终在最后一片“叶子”(矩形)上做出一些决定。
个体决策树是低偏差、高方差的模型。他们非常善于在任何类型的训练数据中找到关系,但却很难在看不见的数据上很好地概括。
但是,XGBoost 使用的树与传统的决策树有点不同。它们被称为 CART 树(分类和回归树),而不是在每个“叶”节点中包含一个决策,它们包含一个实例是否属于一个组的实值分数。在树达到最大深度之后,可以通过使用某个阈值将分数转换成类别来做出决定。
谈到 XGBoost 的内部,我绝不是专家。这就是为什么我推荐你去看看这个完全在 XGBoost 上的超棒的 YouTube 播放列表和另一个完全针对梯度增强的播放列表,我根本没有提到它。
XGBoost 分类器超参数概述
到目前为止,我们只使用了 XGBoost 分类器的默认超参数:
术语复习:模型的超参数是模型的设置,应该由用户提供。模型本身不能从给定的训练数据中学习这些。
如你所见,它有很多。尽管我们使用默认值取得了相当好的结果,但是调整上述参数可能会导致性能的显著提高。但是在我们开始调优之前,让我们来看一下最常调优的超参数的概述:
learning_rate:也称为 eta ,它指定了通过使用额外的基本学习器,模型拟合残差的速度。
- 典型值:0.01–0.2
2.gamma, reg_alpha、reg_lambda:这 3 个参数分别指定了 XGBoost 完成的 3 种正则化类型的值——创建新分裂的最小损失减少、L1 reg 的叶权重、L2 reg 的叶权重
gamma的典型值:0 - 0.5,但高度依赖于数据reg_alpha和reg_lambda的典型值:0 - 1 是一个很好的起点,但同样取决于数据
3.max_depth -树的决策节点可以有多深。必须是正整数
- 典型值:1–10
4.subsample -可用于训练每棵树的训练集部分。如果该值过低,可能会导致拟合不足;如果该值过高,可能会导致拟合过度
- 典型值:0.5–0.9
5.colsample_bytree -可用于训练每棵树的特征的分数。较大的值意味着几乎所有的特征都可以用于构建决策树
- 典型值:0.5–0.9
以上是人们经常调的主要超参数。如果你不完全理解它们(像我一样),这是完全可以的,但是你可以参考这篇文章,它给出了上述每个参数如何工作以及如何调整它们的全面概述。
使用 GridSearchCV 对 XGBoost 进行超参数调优
最后,是时候给我们的 XGBoost 分类器充电了。我们将使用来自 Scikit-learn 的GridSearchCV类,它接受所需超参数的可能值,并为每个超参数组合的给定数据拟合单独的模型。我不会详细介绍 GridSearch 是如何工作的,但您可以查看我关于该主题的另一篇综合文章:
我们将在两轮中只调整几个参数,因为调整既费时又费力。让我们为第一轮创建参数网格:
在网格中,我将subsample和colsample_bytree固定为推荐值,以加快速度并防止过度拟合。
我们将从sklearn.model_selection导入GridSearchCV,实例化并使其适合我们预处理的数据:
经过漫长的折磨,我们终于得到了最好的参数和最好的分数:
这一次,我选择了roc_auc指标,它计算 ROC(接收机工作特性)曲线下的面积。对于不平衡分类问题,它是最受欢迎和最健壮的评估度量之一。你可以在这里了解更多。让我们看看最好的参数:
如你所见,只有scale_pos_weight在它提供的范围中间。其他参数处于其范围的末端,这意味着我们必须继续探索:
我们将使用更新的参数网格为数据拟合一个新的 GridSearch 对象,并查看我们是否在最佳得分上有所改进:
看起来第二轮调优导致了性能的轻微下降。我们别无选择,只能坚持第一组参数,即:
让我们用上面的参数创建一个最终的分类器:
最后,对测试集进行预测:
结论
关于分类问题,我们已经在 XGBoost 的介绍性指南的末尾做了介绍。尽管我们已经介绍了很多内容,但是就 XGBoost 本身和分类主题而言,仍然有许多主题需要探索。
我强烈建议您查看我提供的链接,作为学习 XGBoost 的额外资源,并建议您阅读更多关于如何解决分类问题的内容。

幕后:三角洲湖克隆
原文:https://towardsdatascience.com/behind-the-scenes-delta-lake-clones-d3578cff76a9?source=collection_archive---------14-----------------------
如何使用 Spark 轻松克隆您的 delta lake 表?

朱迪思·普林斯在 Unsplash 上的照片
什么是三角洲湖克隆体?
在 Databricks delta lake 中,克隆只是您的 delta 表在给定快照时间的副本,它们与您的源表具有相同的模式、结构和分区。创建克隆后,对其所做的更改不会影响源表,反之亦然。这是 Databricks 7.2 中的一项功能。
Databricks Delta Lake 支持两种类型的克隆
- 浅层克隆:浅层克隆是增量表的简单副本,这意味着它只是源表元数据的副本,而不是实际数据本身。正因为如此,创建一个浅层克隆是超级快速和容易的。
- 深度克隆:顾名思义,它是源表的真实副本。
那么,克隆人的意义何在?
克隆可以打开 Delta Lake 的许多大门,主要是克隆可以在归档数据和在数据集上运行短期测试用例中发挥重要作用,这种实验是您希望对源表保密的。
例如,您可以通过创建浅层克隆来测试生产表上的工作流,并在不破坏源数据的情况下在克隆上运行测试。由于浅层克隆是一个即时副本,您可以快速测试优化实验以提高查询的性能,并且这些更改会保留在克隆上。
浅层克隆的另一个很好的用例是,通常您会想要回填或重新计算表中的大部分历史数据。这可以使用浅层克隆轻松实现,对克隆运行回填或重新计算,然后在满意时用克隆替换原始表。
如何创建和管理三角洲湖克隆?
说够了!让我们开始克隆,了解幕后发生的事情。
Databricks 提供了一个免费的社区版,这是一个非常酷和强大的功能。正如作者自己所承认的,整本书“Spark The Definitive Guide”都是使用社区版编写的。
像大多数功能一样,你可以在社区版上免费试用 Delta 克隆版。如果您还没有机会设置它,请今天就注册。注册并运行一个集群几乎不需要几分钟。
让我们为运行我们的实验设置一些样本数据。
%sql
Create database Person;
Drop table if exists Person.Address;
Create table Person.Address (
addressId int,
address string,
customerId int,
startDate string,
endDate string
)
USING DELTA
LOCATION 'dbfs:/FileStore/DeltaClones/Address/'
在表格中插入一些数据。
%sql
insert into Person.Address
select 1 as addressId, "1 downing" as address, cast(rand()*10 as integer) as customerId, '2020-11-05' as startDate,null as endDate
union
select 2,"2 downing",cast(rand()*10 as integer), '2020-11-05',null
快速查看一下文件结构,我们现在应该有一个用一些 parquet 文件创建的 delta 表来存储数据,还有一个 _delta_log 来跟踪事务日志。
%fs
ls dbfs:/FileStore/DeltaClones/Address/

增量目录的结构(图片由作者提供)
浅层克隆
让我们从创建示例表的浅层克隆开始。
%sql
Create or replace table Person.AddressShallow
SHALLOW CLONE Person.Address
LOCATION 'dbfs:/FileStore/Clones/AddressShallow/'
如果我们从定义中没有记错,浅层克隆只是复制了元数据,而不是实际的数据本身,让我们验证一下这个说法。
%fs
ls dbfs:/FileStore/Clones/AddressShallow/

浅层克隆增量目录(图片由作者提供)
太棒了。没有保存任何数据的文件,只有 _delta_log,让我们检查一下是否可以通过运行 select 来查询它。

在浅层克隆上选择查询(按作者排序的图像)
关上前门!我们有一个可以轻松查询的源表副本,但实际上,它只是元数据的副本。在我们的选择查询中使用 input_file_name() 函数,很明显克隆正在从源表中读取文件。
浅层克隆本质上创建了一个指向原始表文件的 new _delta_log。如果您分析浅层克隆的事务日志,您将看到所执行的操作是一个克隆,并且有指向原始表文件的文字指针。
现在,让我们测试一下关于隔离的说法。让我们更新一下我们的浅层克隆。
%sql
update Person.AddressShallow
set endDate = '2021-01-01'
查看 delta 目录,我们看到一旦您对克隆数据文件进行了更改,就会开始出现这些文件。

更新后的增量目录(图片由作者提供)
您可以通过对其运行 select 查询来验证这一点。现在,从属于克隆的文件中读取数据,而不是从源表中读取数据。

更新后选择(图片由作者提供)
这证明了隔离理论。浅层克隆是复制源表并在其上运行大量实验的最快方法,而不必担心破坏源数据。现在,去弄清楚用例吧!
深层克隆
让我们创建源表的深层克隆
%sql
Create or replace table Person.AddressDeep
DEEP CLONE Person.Address
LOCATION 'dbfs:/FileStore/Clones/AddressDeep/'
从我们这里得到的表的大小来看,这可能不明显,但是如果它是一个大表,则需要一段时间来进行深度克隆。
让我们做同样的例行检查,并检查了三角洲目录。

增量目录深度克隆(图片由作者提供)
您可以立即注意到浅层克隆和深层克隆之间的差异,深层克隆实质上是对源表的真实复制。嗯,技术上不是镜像拷贝,因为深度克隆只克隆你的源增量表的最新版本。您不会在深层克隆中获得事务的历史记录。您可以通过描述深层克隆的历史并将其与源表的历史进行比较来验证这一点。

深层克隆历史(图片由作者提供)
对于其余部分,深层克隆的行为与浅层克隆完全一样。对深层克隆所做的任何或所有更改都会被隔离。
结论
三角洲湖的克隆不像遗传学中的克隆那样困难或有争议。
浅层克隆有如此大的潜力,它使得处理大型数据集变得流畅、干净和经济高效。是的,深度克隆增加了一个很好的接触,但我不认为有很大的需求,特别是当你可以使用“创建选择表”操作的时候。
你对克隆人有什么看法?我很想知道您的想法和见解,尤其是关于证明使用深度克隆是合理的用例类型。
所有的源代码都可以在这个笔记本里找到。一定要去看看!
参考
- https://docs . databricks . com/spark/latest/spark-SQL/language-manual/delta-clone . html
- https://databricks . com/blog/2020/09/15/easy-clone-your-delta-lake-for-testing-sharing-and-ml-reproducibility . html
- https://www.youtube.com/watch?v=b8l107IYONM
数据分析师招聘流程的幕后
原文:https://towardsdatascience.com/behind-the-scenes-of-a-data-analyst-recruiting-process-b2cf835c3344?source=collection_archive---------32-----------------------
增加你作为招聘经理或求职者的成功机会

图片由 www_slon_pics 来自 Pixabay
今年早些时候,我参与了团队中一个新数据分析师职位的招聘过程。我面试过数据分析师的工作,也做过现场面试的面试官,但这是我第一次从头到尾参与招聘过程。今天,我想让你看看招聘过程的幕后,以及作为招聘经理或求职者,你如何利用这两方面的信息。
工作说明
职位描述是我们对候选人的期望清单。我们委托人力资源部帮助我们筛选符合工作要求的申请人。我们的错误是没有向人力资源部传达我们认为最重要的技能。这导致不合格的候选人通过了最初的人力资源面试,并继续与我的经理进行面试。
让我们来看看这个混合数据分析师/数据科学家角色所需的技能。
-为推动业务影响而发起和提供可行的分析/建议的良好记录
-一些构建数据科学模型以提供更深入见解的经验
-出色的沟通技巧(技术和非技术)以及与高层利益相关者的舒适合作
招聘提示:
人力资源部门和招聘经理应该就成功胜任该职位所需的最重要的技能达成一致。为人力资源部门提供资格预审问题,以评估候选人是否具备与这些技能相匹配的经验。使用上面的例子,人力资源可以要求候选人描述他们提供推动业务影响的建议的时间,从机器学习模型中获得见解的例子,以及他们向不同受众解释数据结果以评估他们的沟通技能的方法。
添加资格预审问题有助于我们在最初的人力资源面试中筛选出候选人,并节省了我的经理与不具备必要技能的候选人交谈的时间。
申请人提示:
关注职位描述中的前 2 到 3 项必备技能。如果有一个部分说“拥有很好”,检查一下你是否有上面列出的任何一个。
在你的简历中,强调与职位描述中的顶级技能相匹配的经验,以增加你获得面试的机会。
在你的人力资源或招聘经理面试中,当被要求描述你的工作经历时,讨论你展示这些顶级技能的例子。这将有助于展示你的经验如何符合该角色的需求。
申请人
人力资源部门将这份工作放在常用的求职网站上,如 Glassdoor 和 LinkedIn,但我们没有收到很多申请。我的理论是,因为我们招聘的是高级职位,而我们需要的 6 年以上经验的人并不多。
该职位要求指导初级分析师,并有可能成为经理职位。我建议将职位名称从“高级分析师”改为“高级经理”,以吸引希望成为经理的高级分析师。
这增加了申请人的数量,但不利的一面是,当我们需要一名有潜力成为经理的实践型高级分析师时,我们有经理申请这个职位。我们确实找到了几个不错的候选人,其中一个我们最终录用了。
招聘提示:
如果你找不到足够多的合格申请人,考虑用不同的头衔列出该职位,或者修改该职位的要求,以吸引更多的人来申请。我们最初要求 10 年以上的经验,并将其降低到 6 年以上,以增加我们的申请人。
申请人提示:
LinkedIn 显示求职者的数量。找那些申请人数少的公司,申请那些工作来增加你被注意的机会。
如果你看到同一家公司发布了一份工作,很可能他们没有得到合格的申请人。利用这一点来突出你的经验,符合所需的技能。
带回家测试
我们对每个通过人力资源和招聘经理面试的候选人进行了一次带回家的测试。这有助于我们评估候选人将如何处理现实生活中的商业问题。
有些公司更喜欢技术面试,要求应聘者当场回答问题。我们认为这并不代表未来的表现,因为你可以在网上练习这些类型的测试并通过,但在现实生活中他们可能会失败。
我们能够通过“带回家”测试筛选出许多候选人,否则我们在电话面试中无法做到这一点。
招聘提示:
通过带回家测试或技术面试来评估技术和业务敏锐度。确保测试有助于筛选出无法胜任该职位的候选人。
申请人提示:
通常人力资源部会通知你要考什么。过去,如果是 SQL、Python 或组合测试,我会被提前告知。如果需要,使用在线资源来练习你的技能。
最终想法
从开始到结束,我们的招聘过程花了大约 4 个月。我们最终为我们的团队聘请了一位出色的分析师,当 HR 告诉我们这份工作被接受时,我高兴极了。
在此过程中吸取的经验教训对于我们计划雇佣的未来数据分析师来说,无疑有助于完善流程。作为招聘过程的一部分,我还获得了新的见解,这是我作为求职者从未想到的。
我希望这种幕后的样子有助于你在下次招聘或申请数据分析师工作时,在招聘过程中获得一个新的视角。
你在招聘过程中的经历是怎样的?
你可能也会喜欢…
</7-little-known-factors-to-consider-before-you-accept-that-data-analyst-offer-a27cb36aa285> https://medium.com/the-post-grad-survival-guide/how-to-handle-a-bad-manager-e68032e47
生成图嵌入的快速随机投影算法
原文:https://towardsdatascience.com/behind-the-scenes-on-the-fast-random-projection-algorithm-for-generating-graph-embeddings-efb1db0895?source=collection_archive---------3-----------------------
思想和理论
FastRP 及其超参数的详细研究

由克里斯·贾维斯在 Unsplash 上拍摄的照片
绝大多数数据科学和机器学习模型依赖于创建一个向量,或者嵌入你的数据。这些嵌入中的一些自然地创造了它们自己。例如,对于按列组织的数字数据,我们可以把与每一行相关的值看作一个向量。在更复杂的情况下,如自然语言处理,我们必须通过各种不同的方法从单词中生成这些嵌入,如一键编码、跳格法,如 word2vec 等。这些向量然后被用作要被建模的数据的表示。
很容易将嵌入理解为独立的实体,其中一行的数据不会影响下一行。然而,对于网络图就不一样了。这个域中的数据点是相互关联的,它们之间的关系与单个数据点一样重要。因此,有必要找到一种方法,将图中的节点转换为嵌入,同时还保留这些节点与其邻居的关系(即上下文)。
我最初发布了一篇关于如何开始使用图嵌入的博文。这个帖子可以在这里找到。
还有一个由 Tomaz Bratanic 写的很棒的帖子,展示了 FastRP 在节点分类任务中的使用,可以在这里找到。
这篇特别的文章建立在上面的以及我的前一篇文章的基础上,在那篇文章中,我展示了使用 Streamlit 创建一个仪表板,以及如何修改 Neo4j 生成的图形嵌入超参数。这是为 FastRP 和 node2vec 图嵌入算法创建的。我通过 t-SNE 提供了一种二维可视化嵌入的方法。
在这篇文章中,我们将探讨其中一种嵌入算法 FastRP 的原因和方法,另一篇文章的目标是如何优化这些超参数。
此外,这篇文章与托马兹·布拉塔尼克的文章“理解 Node2Vec 算法的完全指南”是平行的
警告!
数学就要来了!如果你从未尝试过在介质上正确渲染数学,那就不好看了!我会尽我所能…

照片由this engineering RAEng在 Unsplash
FastRP 的起源:Johnson-Lindenstrauss 引理
FastRP 算法是由 H. Chen 等人创建的。al,这个你可以在原论文里详细读到。我真的推荐那篇文章,因为我会大量引用它。因为它背后的数学是 Neo4j FastRP 算法的基础(甚至包括变量名),我们需要花一点时间来讨论这个数学。不要担心…我希望不要让它变得太糟糕,我对你充满信心,亲爱的读者,你会度过难关的!
约翰逊-林登斯特拉斯引理,也称为 JL 引理,是 FastRP 算法的数学核心。简而言之,它说如果向量空间中的点具有足够高的维数,那么它们可以以近似保持点之间距离的方式被投影到合适的低维空间中。如果你仔细想想,这真的是大多数降维方法的根源。

降维基础(图片由作者提供)
所以是的,我们正试图从p-维空间到d-维空间,其中 d < p 。给定这两个点 xᵢ 和xⱼ,我们想要创建一些映射,ψ,它从高维空间转换到低维空间,同时理想地近似保持这两个点之间的距离。这实质上意味着我们要求解下面的等式:

降维解决方案(图片由作者提供)
我们的目标是让ϵ尽可能小。这个等式成立的事实就是 JL 引理。
这里真正的诀窍是理解ψ应该是什么。D. Achlioptas 发现(并在本文中描述)你可以通过使用一个简单的二进制抛硬币,一个随机数,获得数据库友好的随机投影(实际上,这是论文的标题)。陈等。al 用这个想法实现了一个随机投影矩阵, R ,这将是我们最终给出的映射的要点

随机投影矩阵(图片作者提供)
事实上,李等人曾报道过只要 R 的均值为零,那么点与点之间的两两距离就保持不变——这就是降维的目的。此外,李表明 s 可被选择为与图中边数的平方根一样高, s = sqrt(m),假设下游矩阵(见下文)可被认为非常稀疏。有趣的是,使用这个随机投影矩阵实际上可以比高斯随机投影快上 sqrt(m)。然而,根据矩阵的稀疏性,在最初的 Achlioptas 论文中发现选择 s = 3 是足够的。
那么这和图表有什么关系呢???
我很高兴你问了!是的,所以我们有这个矩阵可以随机化东西。很明显,我们想把它应用到其他矩阵中。但是我们有什么矩阵和图有关系呢?
邻接矩阵是一个很好的开始!实际上,我们将通过创建转移矩阵 A 来对其进行一点改进,如 A = D⁻ S 其中 S 是邻接矩阵, D 是图的度矩阵(给出每个节点度的对角矩阵)。让我们快速地将它们可视化,因为这将使后续矩阵的维度更加清晰。假设我们有一个加权的有向图,如下所示

样本加权有向图(图片由 Tomaz Bratanic 提供,经许可使用)
(注意,我们也可以用未加权和/或无向图来做这件事,但我想我会展示最复杂的例子。)因此,根据上面的图,我们将得到邻接矩阵,如下所示

加权有向图的邻接矩阵(图片由作者提供)
我们还可以建立度矩阵:

上述加权有向图的度矩阵(图片由作者提供)
因此,我们可以通过以下方式构建转移矩阵

上述加权有向图的转移矩阵(图片由作者提供)
注意,上面的每个矩阵都是一个正方形,n×n矩阵,其中 n 是图中节点的数量。
现在我们开始进入 FastRP 算法的 Neo4j 实现实际使用的符号!这里是我们开始进入这些超参数的地方。
像任何嵌入的创建一样,在我们做有趣的事情之前,我们想考虑标准化我们的数据。记住,我们的一些节点可能有很高的相对度。因此,我们将创建一个归一化矩阵(对角线在 n 中),由下式给出

归一化矩阵(图片由作者提供)
其中 β 是归一化强度, m 是边的数量, dⱼ 是第 j 个节点的度数。所以当 β 趋于无穷大时,我们可以得到

让我们思考一下这实际上意味着什么,特别是当我们将这个归一化矩阵应用于转移矩阵时。假设我们有 A 的 k- 次方(,即我们用本身 k 乘以 ) 乘以 A 。aᵏ的第 ij 个条目,是随机游走正好 k 步从 I 到达 j 的概率!
是的,这是粗体和斜体,因为它真的很重要。FastRP 只是由这个抛硬币随机发生器控制的随机行走!

照片由克里斯·布里格斯在 Unsplash 上拍摄
所以现在我们知道了…
我们现在把 A 换一种形式,这样计算效率更高,然后我们就准备写出实际的 FastRP 算法是什么了。

再生 Aᵏ(图片由作者提供)
现在是开始 FastRP 的时候了!
给定我们的图转移矩阵 A ,嵌入维数 d ,归一化强度 β ,以及一些迭代权重 α₁ … αₖ (稍后将详细介绍这些),步骤如下:
- 产生 Rᵢⱼ 随机投影矩阵
- 计算矩阵嵌入的第一次迭代为 N₁ = A ⋅ L ⋅ R
- 计算 i = 2 时 N 的后续值..节点数为 Nᵢ ←一个⋅ Nᵢ₋₁
- 计算 N 的所有值的加权和
这里的最终结果是我们得到了(n×n)⋅(n×n)的矩阵乘法,这导致 N 具有维度 (n × d) ,这正是我们想要的(每个 n 节点有一个 d 维度嵌入)。
如果我们在 LR 引理的背景下考虑这个问题,回想一下ψ是把我们从ℝᵖ带到ℝᵈ.的东西因此,如果我们认为 N = A ⋅ L ⋅ R ,这就意味着ψ= l⋅r。
重量,重量,更多重量
是的,我们在上面的 α 值中有另一组权重。这些是为每个 Nᵢ 计算的迭代权重,它们需要自己的解释。
很明显,这些权重将控制上述每一步对最终节点嵌入的相对影响。对于 1 次迭代,我们将只获得基于每个节点的第一个邻居的嵌入,这不是很有用。因此,例如,假设我们有 4 次迭代(即 k = 4 )。这到底意味着什么?我们之前说过(上面粗体斜体部分)Aᵏ 的第 ij 项表示从 j 到达 i 的概率正好是 4 步。如果在 5 步之前概率为零,那么 Aᵢⱼ 为零。换句话说,在 k = 4 的情况下,我们不能随机跳到图中的一个节点,也就是说,5 跳或更多跳。因此 k 告诉我们,我们在嵌入中包含了节点周围的多少局部邻域。然后,我们可以将上面的每个随机投影步骤加权为

FastRP 嵌入的最终计算(图片由作者提供)
实际上,如果我们只关注任何给定节点的近邻,那么嵌入效果不会很好。因此,忽略那些小的 k 值甚至是值得的。事实上,这正是作者们最初所做的。他们观察到嵌入在 k = 4 并且仅使用 A 和 A⁴ 的情况下是很好的。所以基于此,他们设定了权重 (α₁,α₂,α₃) = (0,0,1) 。在原始论文中,他们然后通过参数化调整 α₄ 和 β 来优化他们的嵌入,给定一个期望值 d 。

照片由 Tony Tran 在 Unsplash 上拍摄
哇!太多了!真的值得吗???
TL;是的博士!
该算法既快速又简单。例如,作者报告说,使用 WWW-200k 数据集,FastRP 进行嵌入的 CPU 时间是 136.0 秒,而 node2vec 用了 63.8 天!当与 node2vec 和另一种流行的嵌入算法 DeepWalk 进行比较时,他们观察到嵌入产生的节点分类结果至少一样准确,如果不是更准确的话!还有很多其他的图形嵌入算法,但是 FastRP 的一个优点是它非常简单。它也很容易扩展,允许您合并图的附加信息,如单个节点的属性,以进一步增强您的嵌入。
和任何图嵌入算法一样,所谓“魔鬼”就在细节中。如何设置每个超参数将取决于您的图表本身,并且需要相当多的实验。这将是未来博客文章的主题。敬请期待!
特别感谢Tomaz Bratanic和Michael Hunger对本帖的建议和点评。
参考
- CJ Sullivan,“图形嵌入入门” (2021)
- Tomaz Bratanic," Twitchverse:为节点分类任务使用 FastRP 嵌入"(2021)
- CJ Sullivan " 用 t-SNE 和 Python 可视化图形嵌入(2021)
- 托马兹·布拉塔尼克,《理解 Node2Vec 算法完全指南》 (2021)
- H.Chen,S.F. Sultan,Y. Tian,M. Chen,S. Skiena,“通过非常稀疏的随机投影实现快速准确的网络嵌入”, CIKM '19:第 28 届 ACM 信息与知识管理国际会议论文集(2019)
- D.Achlioptas,“数据库友好的随机预测:约翰逊-林登施特劳斯与二进制硬币,”计算机系统与科学杂志(2003)
- 页(page 的缩写)李,T.J. Hastie,K.W. Church,“非常稀疏随机投影”,06:第 12 届 ACM SIGKDD 知识发现与数据挖掘国际会议论文集(2006)
作为一名 COBOL 开发人员可能非常有趣
原文:https://towardsdatascience.com/being-a-cobol-developer-can-be-very-fun-c0072454d75c?source=collection_archive---------3-----------------------
意见
软件公司的技术背后有更多的东西

黄英一在 Unsplash 上拍照
开发人员在评估合作时会将公司采用的技术作为一个主要衡量标准。基于此的决定太肤浅了。我们真的害怕科技吗?或者也许我们把公司文化和它联系起来?
我想告诉你我的故事,如果我在 2010 年 25 岁的时候拒绝在 COBOL 中工作,我会失去什么。
大城市生活
大学毕业后,我开始在米兰的一家大公司工作。我在一个私人社交网络上工作,使用最新的 Java 技术栈。那是 2010 年:趋势市场和良好工作环境中的趋势技术。

米兰的公司总部(图片来自街景 2021 谷歌)
不幸的是,在我的内心,我感觉很糟糕。我出生在意大利的群山之中,大城市的生活不适合我。
我认识一位大学老同学,他在那里的一家优秀软件公司工作。我得到了一个面试机会,并接受了这份工作。他们是所在市场的领导者。只有一个缺点:他们的核心业务是基于用 COBOL 编写的软件。

我接受采访时 COBOL 公司的办公室(图片来自 Streetview 2021 Google)
我在米兰的一些同事说我疯了,这些年来我的市场吸引力会下降。幸运的是,我没有听他们的。
你想要 COBOL 上的数字吗?
我们所有人都已经意识到目前有多少 COBOL 在使用。由于疫情,我们在美国有了一个例子,这种古老的语言仍然对我们的社会有着巨大的影响。
反正这个和我想跟你说的无关。我不想说服任何人 COBOL 是一种很酷的语言,因为它不是。这可能是我用过的最糟糕的语言(从技术上来说)。
是哪些特质让它变得如此丑陋?为什么软件开发人员不喜欢和它一起工作?
问题
让我们试着猜测哪些是一个人可能害怕面对的问题。我将列举一些我在经历中遇到的情况:
- 源代码文件长约 70000 行。很多这样的。
- 神秘的(有时很有趣😂)变量和过程的名称。
- 混乱和过时的用户界面。
- 没有数据结构库(例如,没有动态数组)。
- 过时的 IDE
- 没有测试框架。
- 程序设计。
- 非典型数据类型(例如,无 int、float、double、string、char 等)。
- 不支持定义新的数据类型(即 C 中的 struct)。
- 没有具有本地分配范围的函数。
- 专有和过时的持久性。
- 我应该继续吗?我想你明白了😅
典型的开发者反应(图片来自 Giphy
改变你的视角
在问自己“我最后去了哪里?”停下来,深呼吸,从另一个角度看这个列表。
只有当它们和下面的句子一起出现时,这些才是问题:
在这里,我们一直是这样做的
这句话是你在工作生活中唯一不能说的话。这是害怕变化的症状。
但是如果你和那些拥抱变化的人一起工作,那列表上的点就不是问题了。那些都是机会!而且是这么多!
绿色的田野

由西蒙·瓦尔蒂在 Unsplash 上拍摄的照片
上面的图片代表了我如何看待一个由心态良好的人所拥有的遗留项目。一栋老房子,环境很好,你的付出会得到赏识。你有很多方法可以贡献。
没有动态数组库?你可以造一个!你们中有多少人有机会将动态数组库投入生产?我做了,它在 1918 个源文件中被引用了 23954 次(而且是开源)。
过时的 IDE?我的一个同事创建了一个 VS 代码扩展。从那以后,整个团队都采用了 VS 代码,它比官方的旧 IDE 要好得多。
我们有机会挑战的一些相关主题的列表:
- 用于动态内存作用域分配(垃圾收集)的库
- 新的高性能存储
- 错误处理设计
- 本地 API 提供者
- 网格的通用功能设计
- 采用版本控制工具,然后过渡到 git
- 向敏捷方法的过渡
我们必须时刻牢记,工具是有局限性的。不是我们的。
COBOL 的社区支持度很低。然后,不要问“我要使用哪个框架/库/工具?”,问题是“我要构建哪个框架/库/工具,如何构建?”。从某种角度来说,这比在现代的框架丛林中潜水更放松。
我做了一个梦
大学期间,我专攻计算机视觉。我梦想为这个领域创造产品。但我也想留在瓦尔卡莫尼卡,这里并不完全是硅谷。

图片由作者用http://memegenerator.net/创作
好吧,最后,我就是这么做的。

图片由作者用http://memegenerator.net/创作
我们有围绕主要 COBOL 软件的附属产品。那些大多是用 C#写的。其中一个从特定类型的扫描文档中执行自动数据输入。它一直是该公司的战略产品,但它的生产是外部的。它的成本非常高,而且供应商,比方说,“有问题”。
我的老板们决定在内部从头开始重写。这项活动是分配给我的。
那是一个难以置信的疯狂…哦,对不起…勇敢的决定。如果我们失败了,我们就会失去在市场上的战略地位。
幸运的是,我们成功了。那次行动的成功并不是因为我构建的软件足够好。如果我是一个人,我会失败的。这是团队的成果。
我们用一种识别可靠性非常高的产品来替代,即使是在文件不良的情况下。试播期间,出现了那么多问题,但是从来没有人责怪过我。我的队友吸收了外部的打击,让我一个接一个地进入解决问题的状态。对于“队友”,我指的也是经理、POs、服务台,显然还有其他开发人员。
如果我因为 COBOL 而拒绝和这些人一起工作,我就会失去做我喜欢做的事情,我喜欢生活的地方的机会。
结论
公司继续呈指数增长,我们有了新的闪亮的办公室,如此多的新同事,和国际合作伙伴。我在欧洲旅行,开始每天说英语,参加会议,体验许多技术领域,和同事们一起玩得很开心。
让我直截了当地告诉你,这样我就能准确无误地向你传达我心中的信息:
不要关注技术,关注人。你可能会惊讶!
感谢您的阅读。
附言
最后一件事…相信我…它总是比 Javascript 好🤣!(请不要有火焰🔥,这只是一个笑话。我也喜欢用 Javascript 工作😜)
2021 年 4 月 1 日更新
米歇尔·丽娃邀请我参加他在 youtube 上的推理直播。我们谈到了 Cobol、数组库和测试驱动开发方法。好奇就去看看吧😄
成为新闻和媒体行业的数据科学家
原文:https://towardsdatascience.com/being-a-data-scientist-in-the-news-and-media-industry-166b81961cde?source=collection_archive---------39-----------------------
一种观点
随着技术改变预期,新的角色出现

朱利叶斯·德罗斯特在 Unsplash 上的照片
在过去十年中,数据科学家的角色大幅增加。如今,几乎每个公司都在为他们的业务寻找数据科学家。这个角色的重要性来自于它的社交和技术技能。数据科学家的工具箱中应该有这两种类型的属性。尤其是,我认为在新闻和媒体行业,社交能力和技术能力同等重要。甚至有时候,社交技能可能比技术技能更重要。我觉得 51%是社交,49%是技术。
首先,新闻和媒体行业的两个最重要的社会方面是在更高的水平上呈现一种思想和人类互动。当然,这些方面可以在许多部门找到,但人们更意识到拥有它们,尤其是在这一领域。例如,如果你在这个领域工作,作为一名数据科学家,你需要有良好的表达能力。此外,作为一个数据说书人,你可以期待。拥有这样的社交技能会让你更加相信你正在做的事情。不用说,你不能提出你不相信的东西。此外,成为该领域的数据科学家可能需要对人类交互概念有更多的了解。例如,作为一名数据科学家,理解你准备的报告中的期望是最基本的。除了你的日常工作活动之外,研究人类行为、情感,甚至心理学,都可以给你的工作增加巨大的价值。同样明显的是,在新冠肺炎疫情时报,通过视频会议工具进行远程工作和演示变得越来越重要。作为一名数据科学家,在提高社交技能的意义上,使用这些工具是不可避免的。
其次,新闻和媒体空间有两个重要的技术方面:可视化和数据检查工具。说到数据可视化,有一些流行的工具,比如 Tableau、Power BI 等。但是,MS Excel 也可以添加到该工具列表中。举个例子,数据科学家在工作中处理海量的数据并不奇怪,而成为新闻和媒体行业的数据科学家就意味着他们仍然拥有那么多的数据,也许更多。尽管每个数据科学家的工作描述都可以包括在报告中准备可视化数据,但新闻和媒体行业的管理需求可能会变得更具挑战性。这是因为自然地,这个地区的所有人实际上都倾向于更形象地思考。原因可能是一直在处理电视广播、社交媒体数据。此外,熟悉用户界面概念可以为这个行业的数据科学家带来巨大的成就。除了可视化工具,该领域的数据科学家还需要具备编程技能,尤其是 Python、R 和 SQL 语言。当谈到处理和熟悉大数据时,这些语言是顶级的。数据科学家对这些语言掌握得越多,他/她从数据中掌握工业概念和术语就越容易、越快。
总之,数据科学家是终身学习者,他们需要在社交和技术上提高自己。显然,这些社交和技术技能在所有数据科学家的生活中扮演着重要角色。做新闻媒体行业的数据科学家,到最后只能要求更多的社交能力。在数据领域,我认为社交技能和技术技能同等重要。最终,如果数据科学家不能在工作中明智而高效地使用这两者,那么作为数据科学家的魔力就失去了,这很不幸。
理性地相信
原文:https://towardsdatascience.com/believe-rationally-9a5d97c377db?source=collection_archive---------7-----------------------
如何基于证据更新你的信念
你有新冠肺炎吗?
想象你做了一个快速的家庭新冠肺炎测试。如果你测试呈阳性,你应该有多担心?或者,如果您测试结果为阴性,您应该感到有多安全?

由 Medakit 有限公司在 Unsplash 上拍摄的照片
这篇文章将用知识和工具武装你,让你正确而容易地评估这些证据,并相应地更新你对自己的信念/知识/假设的信心。毕竟,你的生活可能取决于它。
你应该如何评估证据?
假设
要评估证据,你首先要后退一步,明确证据的确切用途。有一个假设(或者可以称之为信念)有可能是真的。在这种情况下,假设是:“你有新冠肺炎”。这个假设的新证据是:“你测试呈阳性”(使用一种特殊的快速家庭测试)。
先验可能性
在考虑假设的任何新证据之前,您估计假设为真的先验可能性(如证据之前的“先验”)。很容易就能找到你所在地区当前的新发病例率。例如,在 2021 年 12 月 2 日之前的 7 天里,我所在的县(华盛顿州金县)每 10 万居民中就有 64 例新增新冠肺炎病例。如果你住在我的地区,没有症状,没有理由怀疑最近的接触,并且没有使你更易受影响的先存疾病,你合理地选择 64 / 100,000 * 100 或 0.064% 的基本率作为你现在患新冠肺炎的在先可能性。
这种先验可能性表明,在 10,000 人的样本中,大约 6 人患有新冠肺炎病,9,994 人没有。

按感染 covid 和未感染 covid 的样本分类(图片由作者提供)
后验概率
然后你考虑假设(你有新冠肺炎)的新证据(你测试为阳性)。基于新的证据,您更新了先验概率(0.064%),从而得到假设为真的后验概率(后验概率是在知道证据之后)。
这需要两条信息。

BinaxNOW 新冠肺炎 Ag 卡—使用说明 https://www . FDA . gov media 下载
- 如果假设是真的,证据的可能性有多大?在这种情况下,如果您确实患有新冠肺炎,您检测呈阳性的可能性有多大?这就是真正的正率。从一个常用快速检测(BinaxNow)的数据来看,真阳性率为 84.6% 。这意味着,每 1000 名新冠肺炎病毒携带者中,约有 846 人检测呈阳性,154 人检测呈阴性。你知道一万个样本中有六个人有新冠肺炎。因此,样本中的 6 个人或大约 5 个人中的 84.6%将患有新冠肺炎,并且正确地测试为阳性。

Covid 感染的测试结果分类(图片由作者提供)
2.如果假设是错误的,证据的可能性是什么?在这种情况下,尽管您实际上并未感染新冠肺炎,但检测结果呈阳性的可能性有多大?这是假阳性率。根据数据有一个 1.5% 假阳性率。你知道 10000 个样本中有 9994 个人没有新冠肺炎。因此,9994 人中的 1.5%或大约 150 人将没有 covid,但测试呈阳性。

根据测试结果进行的无 Covid 细分(图片由作者提供)
现在你有了真阳性率和假阳性率,你有新冠肺炎的假设的后验概率是多少?它是样本中患有新冠肺炎病毒且测试呈阳性的人数除以样本中测试呈阳性的人数,而不管他们实际上是否患有新冠肺炎病毒。用百分比表示,结果是 5 / (5 + 150) * 100 或约 4%。该证据将您患新冠肺炎的可能性从之前的 0.064% 更新为之后的 4 % 。

后验概率公式(图片作者提供)
尽管在家中的快速检测中呈阳性,但只有 4%的几率真的患有新冠肺炎病?没错。在我居住的地方,这种疾病的低发病率(降低了先前的可能性),加上非零的,尽管很小的假阳性率,导致了非常低置信度的阳性检测。所以不要对这样的正面结果过分担心。但是也不要忽视!使用它作为一个指标,你应该用一个高特异性测试(如分子聚合酶链式反应测试)来确认结果。
你测试结果呈阴性的另一种情况呢?如果你有新冠肺炎,测试有 15.4%的机会显示阴性。这是假设为真时证据为真的可能性(证据的真实阳性率)。或者,如果你没有新冠肺炎,测试有 98.5%的机会显示阴性(证据的假阳性率)。与之前相同的 0.064%的先验概率,新冠肺炎病的后验概率为 0.010%或万分之一。你应该感到很安全。不需要任何进一步的测试,除非你有症状或怀疑最近接触。
如果先前患新冠肺炎的可能性更高呢?并不是所有的感染者都接受检测,所以报道的病例率肯定是被低估了。此外,你可能生活在高发病率地区,或有症状,或最近接触过新冠肺炎患者。那么阳性检测结果确实令人担忧,需要采取行动。即使先前的可能性适度增加到 1%,阳性检测后患新冠肺炎的后验可能性增加到更显著的 36%。

新冠肺炎的后验概率与先验概率(图片由作者提供)
关键是筛查结果并不意味着结果一定是真实的。最近电视上的一个关于家庭癌症筛查测试的广告自信地宣称“发现了 92%的结肠癌”。但是,当你正确地考虑阳性测试的证据时,不到四分之一的测试阳性的人实际上患有癌症。在你根据测试结果采取任何激烈的行动之前,正确评估结果,并根据证据权衡你的信念。
你如何更容易地评估证据?
不要担心,你不必每次都为一个假设评估一些证据而进行繁琐的计算。只要你清楚假设是什么,证据是什么,证据的真阳性和假阳性率是多少,你就可以简单地在工具中输入值,并获得更新的后验概率。如果你很难找到这样的工具,请随意使用我在 https://vishesh-khemani.github.io/bayesian/bayesian.html 的粗略原型。

评估阳性新冠肺炎检测结果的工具截图(图片由作者提供)
这可以用于什么样的场景?
你的朋友是靠作弊赢的吗?
想象一下,你和你的朋友玩一个基于运气的游戏,你们中的任何一方都有可能赢得一轮。例如,游戏在掷骰子时比你的对手掷得高。或者赢得掷硬币。然后你发现你的朋友一直赢。在经历了多少次损失后,你会愿意破坏你们的友谊,指责她出轨吗?

孙富在 Unsplash 上的照片
如果你已经认识你的朋友很长时间了,但从来没有找到怀疑她的诚实的理由,你对她之前出轨可能性的估计会很低,比如说 1%。如果她作弊,她赢的几率是 100%。如果她没有作弊,她赢的几率是 50%。在工具中输入这些数字,你会发现,在她第 7 次获胜后,她很有可能作弊,而在第 10 次获胜后,她最有可能作弊。我愿意用这些几率来指控她。

评估纯运气游戏胜率的工具截图(图片由作者提供)
你的朋友是千里眼吗?
一个朋友声称能读懂你的心思,猜出你想到的一个个位数。你不相信这种无稽之谈,并认为你朋友的说法只有 0.0001%(或百万分之一)的概率是真的。然后,让你吃惊的是,他猜出了你的号码。再一次。猜对几次后你会改变主意,相信朋友的千里眼?

由胡尔基·奥莰·塔巴克在 Unsplash 拍摄的照片
猜对 6 次后,胜算有利于千里眼!我个人认为这是不可能发生的,但是,请记住保持开放的心态,让你的信念与证据相称。

检查超视力证据的工具截图(图片由作者提供)
被告有罪吗?
你是一名被告被控抢劫案的陪审团成员。抢劫发生在一个小镇上。犯罪现场的 DNA 与被告的 DNA 相匹配。然而,被告有不在场证明。此外,抢劫案的一名目击者在警察列队指认时没有指认被告是抢劫犯。你认为被告有罪还是无罪?

廷杰伤害律师事务所在 Unsplash 上的照片
你从估计之前有罪的可能性开始。这起抢劫似乎是随机行为,镇上的任何人都有可能实施。该镇成年人口为 10000 人。所以你估计被告有万分之一的机会(0.01%)有罪(在考虑任何证据之前)。
然后你考虑第一个证据:DNA 匹配。如果被告有罪,DNA 肯定匹配。一名专家证人在审判中作证说,任何随机的人(包括被告)与犯罪现场的 DNA 匹配的可能性是百万分之一。所以,如果被告无罪,DNA 匹配的可能性是 0.0001%。这一证据将有罪的可能性从 0.01%更新为 99.01%。DNA 匹配非常不利于定罪。

评估 DNA 匹配证据后有罪的事前和事后可能性(图片由作者提供)
你接下来检查不在场证据。被告的妻子声称抢劫发生时他正在杂货店购物。商店的一名收银员证实在商店看到了被告。如果被告有罪,他的妻子很可能在撒谎,收银员要么弄错了,要么在撒谎。您估计妻子和商店员工提供不正确信息的可能性为 10%。另一方面,如果被告无罪,那么不在场证明很可能是真实的,比如说有 99%的把握。有了这个证据,有罪的可能性从 99.01%上升到 90.99%。

评估不在场证据后有罪的事前和事后可能性(图片由作者提供)
最后一项证据是目击者没有在警察列队指认中认出被告。如果有罪,这不太可能,但有 10%的可能性。如果无罪,这似乎是预期的结果,所以不被识别的可能性很高,比如说 99%。现在内疚的几率从 90.99%到 50.50%。

评估目击者证据后有罪的先验和后验可能性(图片由作者提供)
51%的有罪几率远低于排除合理怀疑的有罪标准。你认为被告无罪。
如果没有上述评估证据的原则性方法,你怎么会得出结论呢?你会做几乎所有陪审员都会做的事情:运用你的直觉。你知道吗?大多数人的直觉告诉他们,DNA 匹配(随机匹配的概率只有百万分之一)超出了有罪的合理怀疑。其他开脱罪责的证据会被淹没,也许不公平地归咎于人为错误或欺骗。
现在,你已经掌握了通过评估相关证据来更新信念信心的知识和工具。有先入为主的观念是可以的,只要你保持开放的心态,诚实地评估任何新数据(尤其是如果它与你的信念相反)。勇往直前,理性地相信。
参考
- 关于人类理解的探究——大卫·休谟
- https://en.wikipedia.org/wiki/Bayesian_inference
- https://www . CDC . gov/corona virus/2019-ncov/lab/resources/antigen-tests-guidelines . html
- https://en.wikipedia.org/wiki/R_v_Adams
基准测试:用 jax 加速批量线性代数运算
原文:https://towardsdatascience.com/benchmark-accelerating-batch-linear-algebra-operations-with-jax-6962cdea5011?source=collection_archive---------42-----------------------
理解大数据
代码更改最少,速度明显加快
像numpy这样的包是当今数据科学工作的面包和黄油。然而,我们可能会遇到numpy无法轻松处理或只能以次优方式处理的情况。

当你穿越到未知的领域…照片由 Alex 在 Unsplash 上拍摄
我最近遇到过这样的情况:当实现一个概率矩阵分解(PMF)推荐系统时,我必须将许多对矩阵U和V.T相乘,当我调用numpy.tensordot来实现我的目标时,我的 Jupyter 内核崩溃了。
不满足于不得不在多核机器上一个接一个地乘以矩阵,我转向了jax,粗略地说就是类固醇上的numpy。DeepMind (cue AlphaGo music)和谷歌的研究人员在日常工作中使用这个[jax](https://jax.readthedocs.io/en/latest/)库— —主要是在深度学习方面— —一个丰富的生态系统已经围绕它涌现出来。
https://deepmind.com/blog/article/using-jax-to-accelerate-our-research
在jax的优点中,我在这里关心的一个是它可以很容易地向量化(纯)函数,通过底层的并行化实现加速。如此加速的代码可以在 CPU、GPU 和/或 TPU 上执行,无需修改!
问题陈述
具体来说,这里是U和Vt的形状。它们是成批的矩阵,而不是成批的行,由于表格数据的流行,成批的行更常见。所以U和Vt分别包含 100 个矩阵,

U 和 Vt 的形状,我会把它们相乘。对于那些好奇的人来说,U 和 V 是 MCMC 的后验样本。文章作者截图。
我想将每一对对应的矩阵相乘得到R,其形状为(100,610,9724)。换句话说,用Vt[0]乘以U[0],用Vt[1]乘以U[1]…,用Vt[100]乘以U[100]。
然后,我想对 0 轴(所有 100 个矩阵在R中)进行平均,最终得到一个 610 乘 9724 的矩阵。
基准
作为基线,让 Python 一个接一个地乘以矩阵,然后在轴 0 上平均结果。我的 2015 Macbook Pro 用了大约 10 秒,它有 16 GBs 的内存和英特尔 i7 CPUs。

顺序执行的基准。文章作者截图。
相比之下,如下图截图所示,执行同样的操作仅用了jax 2.2 秒!注意,我必须在jnp.mean()后添加.block_until_ready()才能获得有意义的基准,因为jax遵循惰性/异步评估。

使用 jax 的基准。文章作者截图。
最后但同样重要的是,当我将批中的矩阵数量从 100 增加到 150 时,上面的运行时会有不同的伸缩。朴素的顺序评价用了 50 秒,而jax只用了 3 秒。换句话说,当问题需要更多内存时,使用 **jax** 的好处真的显现出来了。
外卖食品
也许有一种简单的方法来完成我想在numpy中做的事情,但是使用jax也同样简单— —并且在设备类型和内存使用方面具有巨大的可伸缩性。
虽然jax自带数组数据类型,但是 [numpy.ndarray](https://github.com/google/jax/issues/712)的子类,因此jax可以与现有的numpy工作流集成。
TL;博士--可以的话就用jax!
跨语言信息检索基准数据集(CLIR)
原文:https://towardsdatascience.com/benchmark-dataset-for-cross-lingual-information-retrieval-clir-e77d75472e89?source=collection_archive---------21-----------------------
思想和理论
我们展示的数据集使研究人员能够在医学领域建立和评估英语和七种欧洲语言的 CLIR 系统。

由安东尼·马蒂诺在 Unsplash 上拍摄
介绍
在这个故事中,我将介绍我们对扩展现有跨语言信息检索(CLIR)数据集的贡献,这些数据集是在 CLEF 电子健康评估实验室的信息检索(IR)任务期间发布的。所得到的数据集旨在建立和评估医学领域中的 CLIR。支持的语言有英语、捷克语、法语、德语、匈牙利语、波兰语、西班牙语和瑞典语。
什么是跨语言信息检索(CLIR)?
CLIR 使用户能够通过以不同于收集语言的语言提出查询来搜索信息。这有助于打破系统用户和用不同语言表示的大量数据之间的语言障碍。自 20 世纪 90 年代末以来,这项任务已经引起了国际关系研究界的关注,互联网的发展是 CLIR 系统需求的有力证据,因为全球的数字内容已经开始显著增加。
CLIR 和 COVID19
在 COVID19 疫情期间,CLIR 变得比以往任何时候都重要,因为个人、政策制定者和医生都希望更多地了解 COVID19,并阅读来自世界各地的故事、治疗方案和抗击 COVID19 的展示。这些信息当然可以用他们可能不会说的多种语言获得。
围绕 COVID19-topic 改进搜索和信息访问的最新努力之一是 COVID19 MLIA 评估:“新冠肺炎·MLIA 评估组织了一项社区评估工作,旨在参考一般公共用例,加快创建资源和工具,以改进当前紧急情况下的多语言信息访问(MLIA)”,来源: MLIA 网站。
接近 CLIR
CLIR 系统通常包括两个步骤,第一步是翻译步骤,包括将查询翻译成文档集合的语言,或者将文档集合翻译成查询语言。翻译完成后,任务就简化为单语的信息检索任务。
不同的方法和研究调查了 CLIR 任务中的两个主要问题:
- 查询和文档集合哪个更好翻译?或者将两者转换成一个共同的表示?
- 翻译怎么做?CLIR 的翻译任务是否类似于旨在生成人类可读翻译的正常机器翻译任务?
有关这两种方法的更多信息,我可以参考我去年在语言学协会(ACL)会议上发表的一篇论文,在这篇论文中,我对上述两种方法进行了全面的比较。
https://www.aclweb.org/anthology/2020.acl-main.613/
CLIR 和 COVID19
在 COVID19 疫情期间,医疗领域的搜索变得非常重要,因为个人、政策制定者和医生希望通过在线访问多种语言的信息来获得最新信息。实际上,新冠肺炎多语言信息获取(MLIA) 计划是邀请世界各地的研究人员设计搜索引擎系统的最新活动,该系统可以帮助搜索者以多种语言在线查找 COVID19 相关信息。
我们的 CLIR 测试数据集
该测试数据集基于 2013-2015 年 CLEF 电子健康以患者为中心的 IR 任务期间发布的三个测试集[Goeuriot 等人,2015 年,2014 年,Suominen 等人,2013 年]。我们主要通过将查询翻译成更多的语言来扩展测试集,并将相关性评估扩展到原始评估的两倍以上。扩展的测试集可通过LINDAT/CLARIN 知识库在线获取
测试数据集主要包含三个部分:
1-文档集合
我们扩展数据中的文档集合摘自 CLEF 电子健康 IR task 2015。这些文件以 HTML 格式提供。每个文档都包含 HTML 标记、CSS 和 javascript 代码。
该集合包括大约 110 万份从医学网站上抓取的文档。关于文档集合的更多信息可以在[1]中找到。
2-查询
本研究中的查询来自 CLEF 电子健康 CLIR 任务 2013–2015 期间发布的测试集,如下所示:
2013 年和 2014 年的查询在 CLEF e health IR task 2013【Goeuriot 等人,2013】和 CLEF e health IR task 2014【Goeuriot 等人,2014】中,医疗专家根据患者的出院总结生成查询。
选择医学专家(护士和临床医师)进行查询生成的动机是这些专家每天都与患者接触;因此,他们可以了解自己的信息需求。
产生的问题如下:医学专家得到出院总结,他们被要求随机选择一种疾病,然后写一个简短的问题描述它。他们假设,当患者想要找到更多关于同一种疾病的信息时,他们会使用相同的查询。让医学专家参与从出院总结中生成查询会在某种程度上影响查询的性质,因为它们包含医学术语,并且它们往往很短。
2015 年的查询在 CLEF eHealth Evaluation Lab 2015 中,被称为的 IR 任务检索有关医疗症状的信息【Palotti 等人,2015】。该任务的目标是设计红外系统,可以帮助外行人(没有医疗经验的用户)找到与他们的健康状况相关的信息,并了解是什么导致了他们的症状(自我诊断)。因此,本任务中查询的创建试图尽可能模拟真实情况。
查询创建步骤中的参与者是没有医疗经验的大学生,试图模拟普通搜索引擎用户的情况。
他们观看了包含医疗问题症状的图像和视频。然后,他们被要求为每个案例生成查询,因为他们认为这些查询将代表他们的信息需求,并最终将引导他们找到相关的文档。
新数据拆分如前两段所示,CLEF eHealth IR 的 2013、2014 和 2015 年实验室中的查询之间的主要差异是这些查询的来源,以及 2013–2014 年使用医学术语的趋势与 2015 年的情况相反。
我们希望设计一个对如此多样的用户查询稳定的 CLIR 系统,而不是设计一个偏向于一种类型的查询(短的有医学术语,长的没有医学术语)的系统。
为此,我们从 2013 年(50 个查询)、2014 年(50 个查询)和 2015 年(66 个查询)的每个 IR 任务中获取了测试查询。我们将它们混合在一起,以获得更具代表性和平衡的查询集,然后将这些查询分成两组:100 个用于训练的查询(33 个来自 2013 年测试集,32 个来自 2014 年,35 个来自 2015 年)和 66 个用于测试的查询(17 个来自 2013 年测试集,18 个来自 2014 年,31 个来自 2015 年)。
这两个集合根据其来源年份的分布、相关性评估信息中存在的相关/不相关文档的数量以及查询长度(标记的数量)来分层。
所有年份的查询都以 aTREC ( TREC 是 NIST 文本检索会议的缩写)格式表示,如下所示:
标题 :该字段包含查询的标题,通常称为查询。用户的信息需求应该在这个域中表示,这个域最终将被馈送给一个 IR 系统进行检索。
*D*描述:该字段帮助描述较长句子中的标题。
Narrative:该字段向注释者描述相关文档应该包含的内容。该字段对于相关性评估过程而非检索阶段非常有用。
Pprofile:关于将要进行自我诊断的患者的信息,如他们的性别、年龄和其他医疗相关信息。
Discharge _ summary:该字段包含一个文本文件的处理程序(ID),该文件包含相应患者的出院总结。

测试查询的示例
3-相关性评估
相关性评估是法官(在该领域有经验的人)确定每个文档是否与特定查询相关的过程。
我们建立了一个使用多个系统检索的排名靠前的文档池,然后评估人员查看每个文档-查询对并确定其相关程度。相关度可以是:
- ****不相关:文档与信息需求完全不相关。
- ****有些相关:该文档部分回答了信息需求。这意味着一些信息被遗漏了,搜索者不得不阅读更多的文档来完整地得到他们的问题的答案。
- ****高度相关:该文档完全满足信息需求,无需阅读任何其他文档。
我们使用 Relevation toolkit ,这是一个开源工具,用于为 IR 评估进行相关性评估【Koopman 和 Zuccon,2014】。

相关性评估员使用的相关 web 界面。
下表显示了官方评估(在 2013 年、2014 年和 2015 年完成)与我们在评估文件数量方面的扩展的统计数据。扩展后的数据集总共包含 38 个、 109 个文档-查询对,14 个、 368 个文档-查询对。

相关性评估统计
结论
我在这个故事中介绍了我们扩展现有数据集以支持七种欧洲语言的 CLIR 的努力。数据集在这里公开。
这个数据集的完整描述发表在 2019 年欧洲信息检索会议(ECIR)的一篇短文中[2]。
如果你对这项工作有任何问题,请不要犹豫,在评论中写下你的问题。
参考
- [1]帕罗蒂等人:CLEF 电子健康评估实验室 2015,任务 2:检索有关医学症状的信息,CEUR-WS.org
- [2] Shadi Saleh 和 Pavel Pecina,医学领域跨语言信息检索的扩展 CLEF eHealth 测试集,(2019),2019 年欧洲信息检索会议, Springer 。
M1 在 TensorFlow 培训上与 20 核至强竞争
原文:https://towardsdatascience.com/benchmark-m1-part-2-vs-20-cores-xeon-vs-amd-epyc-16-and-32-cores-8e394d56003d?source=collection_archive---------16-----------------------
M1 性能与 20/40 核至强银裸机和 AMD EPYC 服务器的比较

在 M1 基准测试文章 的 第一部分中,我在三个 TensorFlow 模型上将 MacBook Air M1 与 iMac 27 英寸酷睿 i5、8 核至强白金、K80 GPU 实例和 T4 GPU 实例进行了比较。
虽然 GPU 没有预期的那么高效,可能是因为 TensorFlow 的早期版本还没有完全针对 M1 进行优化,但它显然显示出令人印象深刻的 CPU 性能,远远超过了 iMac 和 8 核 Xeon(R) Platinum 实例。
虽然将入门级笔记本电脑与如此高端的配置进行比较通常是不公平的,但 M1 有优势;它有 8 个物理核心。
iMac 27 英寸 Core i5 有 4 个内核,8 核 Xeon(R) Platinum 就像计算 vCPU 的每个实例一样,因此只有 4 个物理内核。我按照这张纸的反复检查了core id、siblings 和physical id以确保无误。
设置
在本文中,我将 M1 与具有 8 到 20 个物理内核(16 到 40 个超线程内核)的更强大的配置进行了比较。

基准配置
AMD EPYC 配置是实例,而至强银是裸机,这意味着真正的物理专用服务器。
至强服务器有两个 CPU,每个 CPU 有 10 个内核(20 个线程),因此总共有 20 个物理内核(40 个线程)。
它使用 TensorFlow 2.3.1 从一些编译选项中获益。启动时,它会显示以下内容:
This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA
我还比较了与 Anaconda 一起交付的英特尔(R) MKL。两者表现相似。
MacBook Air 正在使用能够从 M1 的全部潜力中受益的苹果硅原生版 TensorFlow (即使第一部分文章显示 GPU 看起来尚未优化)。
提醒一下(如前一篇文章所示),这里是 M1 的规格。
- 8 核 CPU (4 个 3.2 GHz 高性能,4 个 2.06 GHz 高效率)
- 8 核 GPU (128 个执行单元,24 576 个线程,2.6 TFlops)
- 专用于线性代数的 16 核神经引擎
- 统一内存架构 4 266 MT/s (34 128 MB/s 数据传输)
模型
你可以找到 前一篇 中使用的模型和数据集。
结果
下图显示了在 CPU 上的训练结果。

在 CPU 培训方面,MacBook Air M1 的性能远远超过了两个 AMD EPYC 和 20/40 核英特尔至强银处理器在 MLP 和 LSTM 的性能。只有 convnet 在 128 和 512 样本批量方面比至强稍有优势,AMD EPYC 16/32 在 512 样本批量方面仅略胜一筹。
下图显示了其他设备比 M1 CPU 慢多少倍。

对于 MLP 和 LSTM 来说,M1 比 8/16 核 AMD 快 5 到 13 倍,比 16/32 核 AMD 快 3 到 12 倍,比 20/40 核 Xeon 银裸机快 2 到 10 倍。对于 CNN 来说,M1 在 32 个样本批量上大约比其他公司快 2.5 倍,在其他批量上比 AMD EPYC 快 2 倍,在 128 和 512 个样本批量上比 20/40 核 Xeon(R) Silver 仅慢10%到 20%。
CPU 消耗
让我们在培训期间检查一下至强处理器的 CPU 消耗。

培训期间的至强银级 CPU 消耗
一半的内核负载约为 70%,这意味着超线程在这种情况下没有用,只使用物理内核。
现在让我们检查整个基准测试期间 M1 CPU 的历史记录。

M1 CPU 负载——MLP,CNN,LSTM
令人惊讶的是,在 MLP 和美国有线电视新闻网的培训中,只有 4 个内核被真正使用,但仅在 50% 时使用。最大负荷发生在 LSTM 训练期间;这也是其他 4 个内核负载达到 50%的唯一情况。我们可以假设负载最大的是 3.2 GHz 的“高性能”内核。
那么,M1 如何通过仅部分使用其一半的内核来实现如此卓越的性能,从而击败使用 AVX-512 指令编译的 TensorFlow 版本的 20/40 核至强银处理器呢?M1“性能”内核的频率比至强(R)内核高 50%,但这一内核有 20 个物理内核,这一频率差异不足以解释这一性能差距。
为什么 M1 这么快?
由于苹果从未透露其处理器设计的细节,所以很难知道 M1 不同地区的实际使用情况。无论如何,我们可以尝试制定一些假设。
- M1 CPU 包括【ML 加速器】如这里提到的,它们被 ML Compute BNNS 原语在 CPU 上训练神经网络模型时使用。如果我们参考 这篇文章 我们可以假设“ML 加速器”是 AMX2 (苹果矩阵协处理器)的通称,所以它可能更像是一个迷你 NPU 能够加速线性代数计算,尤其是矩阵乘法。但与神经引擎不同的是,它与 CPU 一起工作,而不是作为一个独立的组件,因此减少了延迟,提高了密集矩阵计算的吞吐量。这可以解释为什么在 LSTM 上观察到最大的间隙,因为这种类型的单元不仅基于矢量,而且需要更多的迭代处理。CPU 和高吞吐量矩阵计算单元的组合对于这种模型似乎非常有效
- 通用内存设计支持对 SoC 的每个内核和每个组件进行更快的数据访问,同时更好的 CPU 设计支持更高效的并行处理
再说一遍,这些都是假设,只有苹果能解释它到底是如何工作的。
结论
从这些测试来看,似乎
- 为了训练 MLP 和 LSTM , M1 的 CPU 比所有测试过的高端服务器都要快得多
- 为了训练 CNN , M1 只比测试的高端服务器稍慢
当然,这些指标只能考虑用于本测试中使用的类似神经网络类型和深度。
对于持续超过 20 分钟的大型培训和密集计算,我仍然会选择基于云的解决方案,因为它们提供了针对如此长时间的重负载而构建的卡,并且能够同时发送几个任务。但这种情况只适用于一些特定的研究,仅占我工作的 10%,主要用于一些特定业务领域的专业用途。
作为一名机器学习工程师,对于我的日常个人研究来说,M1 Mac 显然是当今最好、最具成本效益的选择。
感谢您的阅读。
使用基于云的 AutoML 测试您的机器学习模型
原文:https://towardsdatascience.com/benchmark-your-models-6ef942e2683f?source=collection_archive---------14-----------------------
开发准确的模型和工具来预测或分类数据是数据科学家工作不可或缺的一部分。构建模型需要相当多的努力,而且可能很耗时——如果你正在寻找这个过程的潜在捷径,请继续阅读。
首先,让我们假设我们获得了一个由几个预测值和一个响应变量组成的数据集,期望的结果是一个正确预测价格列的回归模型,这是一个经典的监督学习任务。在接下来的几个段落中,我将简要介绍这个问题的建模(使用与 R 相关的(伪)代码)。
在正常的工作流程中,会构建各种不同的模型,最终选择并部署最有说服力的模型。这可能不仅在模型选择方面非常耗时——关键词:数据采样、交叉验证(CV)——而且没有为您提供可以参考的基准。在一天结束的时候,你符合你的“最佳模型”,这可能实际上真的很好,或者在不同的场景中,根本不是。
有什么方法可以快速找到我们可以参考的“默认模型”呢?绝对的!

面向 ML 的云计算—图片由 Pero Kalimero 提供
此外,模型的性能通常不仅取决于模型训练的数据集(关键词:训练误差、随机效应),而且在应用不同的超参数时,性能也会有很大差异——这就是组合学发挥作用并使您的生活变得更加艰难的地方。最终,数据科学家找到了“最准确”的模型,但是还有一个问题:
是否有任何更好的建模选项尚未解决?
“总有更大的鱼”[Qui-Gon Jinn],或者在我们的情况下,一个模型可能比我们的实现做得更好。话虽如此,即使我们找不到更好的模型,这也是一件值得了解的好事,不是吗?这是我想介绍 AutoML 的地方。尽管在数据科学领域中有许多不同的“AutoML”实现,但我将介绍一种简单的“按需付费”方法,它不会让我们陷入无尽的设置周期。
我将检查以下工作流程,以(1)在本地构建一个模型,以及(2)查看通过 Google 的 AutoML 实现实现的模型基准:
**Local Setup:**
1\. Defining a dummy dataset
2\. Train a model and tune hyperparameters (cross validation)**Cloud Setup:**
3\. Upload a dataset Google's Vertex AI (bucket)
4\. Set up Vertex AI and build a model through AutoML
5\. Compare performance
本文中的示例数据集引用了一个回归任务,如果你的底层分析问题是一个分类任务,你可以在这里找到一些启发:
创建简单的虚拟数据集
在这个实验中,我使用了 X1 和 X2 的递增值(都在区间[0,1])组合成一个响应变量 Y,其中 Y 定义为:
Y = 100 * [ max(e^y1, e^y2, ..) / sum((e^y1, e^y2, ..)) ]
其中(小写) yi 取自多元高斯分布。这个实现的功劳归于 梅亚军 教授,他向我介绍了这种生成随机数据的有趣方式。
这里我们需要知道的重要一点是,响应数据显示了一个曲率,这表明线性回归可能不是最好的选择,而是局部核平滑方法或非线性模型。
在本地机器上构建模型
我决定使用两种不同的模型,多元线性回归以及 gbm (梯度推进机)。
(调整后的)gbm 模型的一个示例:
如上所述,拟合模型很简单,但也需要执行类似“gridsearch”的超参数调整,以获得最合理的结果。这与线性回归模型无关,但是 gbm 有多种可以修改的超参数(例如 n.trees,shrinkage parameter,minobsinnode )。
请记住,对于基于树的模型,我们应该始终关注过度拟合,因此应该谨慎设置和评估树的大小、节点中的最小观察值和 CV。
鉴于上述模型设置,gbm 能够在 1.11568 的 RMSE 下进行预测,鉴于所有响应 Yi 的平均值约为 50,该值似乎较低。线性回归得出的 RMSE 为 3.1846 ,该值相当大,但正如预期的那样,给出了响应数据的非线性形状。
现在有趣的问题是:“gbm 模型与 AutoML 拟合的类似基准的模型相比如何?”
基准模型
为了找到上述示例模型的基准,我使用了 Google 的 Vertex AI,它提供了 AutoML 功能。事实证明,该过程允许我们将模型拟合到训练数据,而不必考虑要应用的不同模型类型及其相关的超参数。此外,还会考虑交叉验证。
首先,我们需要在云控制台中直接上传或“创建”数据集,将数据存储在一个桶中。数据类型是“表格”格式(这是一个 csv 文件),我们要执行的任务是一个回归任务。

假设我们想要预测连续值,基本任务就是回归。截图取自谷歌云平台
一旦数据被上传和设置,例如提供了正确的列名等。,导航栏中的培训部分允许我们培训模型。不需要任何编码经验,因此我们可以简单地点击添加/删除模型构建过程中的变量。

选择功能和响应—来自 Google 云平台的截图
在最后一步中,我们只需要确定我们允许模型训练的时间。我选择了两个小时,(而一个小时是选择的最小单位)——只要确保您允许该过程提前停止,如果已经实现了收敛,这可能会为您节省一些美元。
在训练模型时,您可以观察准确性度量的进度。这为您提供了一个第一印象,即您的训练模型最终可能与 AutoML 模型相比有多好。

悬停在线上显示当前获得的 RMSE——来自谷歌云平台的截图
在模型停止后(由于预算限制或因为模型收敛),可以观察到最终结果指标如下:

模型收敛/停止后的结果指标—来自 Google 云平台的截图
在现实世界的场景中,我们可能希望对新的数据点进行预测。这要求用户设置接受请求的端点,并返回请求中给定数据点的预测。
尽管建立 AutoML 模型很容易,但通过局部拟合模型进行预测要容易得多,而且更重要的是,不会像请求那样产生成本。AutoML 模型既可以作为一个整体下载来进行预测,也可以通过 API 调用(演示代码由提供商提供)——这两种方法都很简单,但仍然比使用机器模型复杂。
比较和结论
在本例中,我们可以看到本地模型(gbm)和 AutoML 模型的结果非常接近,尽管 AutoML 的表现稍好一些。这是否意味着我们应该放弃我们的拟合模型?很可能不是。
- AutoML 花了 1.5 个多小时才得出合理的结果,而本地拟合的 gmb 模型只花了大约 20 分钟(包括调整超参数的 gridsearch 过程)。
- RMSE 中的差异约为 0.02,这对于我们的模型来说是一个很好的结果,也表明我们正处于良好的轨道上,甚至可能通过引入更多种类的可能超参数(例如,增加助推模型的相互作用深度)来改善
- 成本与收益:赢家再清楚不过了。如果你对模型成本感兴趣,可以随便谷歌一下,但有一点可以肯定,云一点也不便宜。
- 进行预测需要对基于云的模型进行部署和集成,而本地模型一旦适合就可以进行预测。然而,如果您正在使用一个大规模生产环境的模型,您可能仍然喜欢基于云的 AutoML 解决方案。
我对数据科学家在这一切中的角色的看法:
AutoML 是否根除了数据科学职业?—很可能不是。
显然,AutoML 模型做了出色的工作,让我们有了一个好的模型基准。如果盲目地执行算法来衡量 AutoML 解决方案的结果,结果可能不会有很大的不同。
简单的调整会对模型结果产生难以置信的巨大影响。数据专家的主要好处之一是,这些调整来自经验和知识。例如:在另一个不同的例子中,我可以了解到简单的数据转换可以为更简单的模型带来更好的结果— AutoML 希望只处理结果来找到更好的拟合,这可能会带来复杂性。
一个更简单的模型不仅可以节省大量资金,还可以让我们更容易地获得可以解释和说明的结果,例如,考虑一个泊松回归模型,它允许我们解释系数,而不是“只”提供重要性度量的集合学习器。毫无疑问,后一种模式可能更难解释和证明。
{照顾好自己,如果可以的话,也照顾好别人}
—借用史蒂芬·都伯纳
用风格对时间序列数据集进行基准测试
原文:https://towardsdatascience.com/benchmarking-time-series-datasets-with-style-2a4e8789a965?source=collection_archive---------18-----------------------
行业笔记
如何交叉检查/核实大型时序数据集?
我从事能源系统建模、油气井建模和油井完整性管理系统的工作。在许多情况下,基准数据集或发现来自不同来源或来自多个建模结果的时间序列数据之间的差异至关重要。
时间序列是一系列随时间变化的数据点。
对大型数据集进行基准测试,并快速发现差异和风格,可以为您节省推动见解的时间。
例如,在超过 100 个国家和 60 个行业的全球能源数据集中,绘制整个数据集以对两个不同的数据源进行基准测试,或者甚至在运行模型以预测不同的情景之后,这将是非常乏味的。
在英国石油公司的《世界能源统计评论》中,对不同的能源情景进行了量化,显示了英国石油公司对不同能源环境下能源未来的看法(照常营业情景和净零情景)。
这些数据是 2025 年、2030 年、2035 年、2040 年、2045 年和 2050 年主要消费国和地区的数据。
我们如何在不绘图的情况下发现时间序列预测(两种能源情景)之间的差异?我们如何跳过绘制两种能源情景之间的 60 个时间序列数据(120 条线图)来找出主要变化在哪里?
我们从哪里得到的数据?
我们在构建案例时所依赖的数据是《英国石油公司 2020 年世界能源统计评论》,我们在之前的工作中向展示了如何使用 python 以干净的形式提取数据。
发现时间序列数据之间差异的传统方法
我们的目标是区分不同燃料(石油、天然气、可再生能源、核能、煤炭)的预测需求,以及几个国家/地区(美国、欧盟、中国、印度等)的“一切照旧”情景和“净零”情景。).
传统的方法是在两个场景之间绘制一个线图

线形图指出两个时间序列数据之间的差异。图片作者作者
传统方法的问题?
这将需要绘制两种能源情景之间的 60 个时间序列数据(120 个线图),以确定主要变化在哪里。如果您有一个更大的模型或几个特征,使用绘图作为解决方案会变得更加困难。
如何更快发现一种风格的差异?
能够看到不同建模场景之间的时间序列数据差异的全貌,或者检查不同数据更新之间的差异,或者在大规模的基准测试过程中,可以节省更多时间来进行高质量的分析和提供见解。
对两种能源情景结果(时间序列数据)进行基准测试的步骤如下:
- 提取数据。
- 以长格式重新组织数据,并有两列,每一列对应一个要进行基准测试的时间序列(能源场景)。
- 计算两个时间序列数据集之间的无量纲差。
例如,2035 年非洲煤炭消费的无量纲差异为{(5–2)/5 } = 0.6

长格式的结构化干净数据集。图片由作者
4.求和每个县每个部门的两个时间序列之间的无量纲差异。

两个能源情景数据集之间的差异总和(时间序列)。作者图片
5.重新构造数据帧,使两个最重要的变量是索引和列名。例如,国家是指标而部门是栏目。

图片作者作者
6.使用热图可视化结果。

发现(基准)两种能源情景(时间序列数据)之间差异的热图。图片由作者
热图将浅色显示为两个数据集匹配的区域。也就是说,两种能源方案显示了相似的结果。美国的水电消费就是一个例子。然而,中东的可再生能源消费在一切照旧情景和净零情景之间有很大差异。
下面的示例显示了生成的热图如何帮助发现不同时间序列数据之间的差异。

基准时间序列数据摘要。图片作者作者
整部作品可在 Github 上获得。
SSH 远程登录的优势
原文:https://towardsdatascience.com/benefits-of-remote-entry-with-ssh-76acb72f918a?source=collection_archive---------33-----------------------
快速教程
使用 ssh-keygen 保持您的动力

照片由 Goh Rhy Yan 在 Unsplash 上拍摄
我所有的工作都是在远程计算机上完成的,这通常需要我在一天中多次输入密码。这个小任务是可以避免的。
在这篇文章中,我将描述如何设置进入服务器的无钥匙进入,这样你就不必每次登录或scp文件时都输入密码。我还将描述如何在不输入密码的情况下通过 bastion 服务器远程复制文件,以及如何安排远程备份。
0.设置无钥匙进入
在本地计算机上,使用以下命令创建 RSA 密钥:
ssh-keygen
这将使用您的 RSA 密钥创建一个文件。默认位置是
~/.ssh/id_rsa
将密钥复制到远程服务器上的~/.ssh/authorized_keys中:
ssh-copy-id user@remote.server
现在你可以不用密码进入ssh服务器了:
ssh user@remote.server
如果我的远程服务器有一个堡垒主机怎么办?
在这种情况下,您可以遵循与上面相同的步骤,将您的 bastion 服务器视为您的本地机器。
首先,登录到您的堡垒服务器并创建一个 RSA 密钥。然后使用ssh-copy-id将其复制到您的远程服务器。最后,确认你可以用密码ssh进入远程服务器。
1.复制文件
一旦设置了ssh键,你就可以在没有密码的情况下跨服务器传输文件。
1.1 从本地机器复制→远程服务器
1.2 从远程服务器复制→本地机器
2.跨堡垒服务器移动文件
您可以使用移动文件到远程服务器,即使您中间有一个堡垒节点。
首先,确保使用ssh-keygen在堡垒服务器和远程服务器上设置了 RSA 密钥
2.1.从本地机器复制→远程服务器
您可以使用rsync将文件从本地机器复制到远程服务器。
-e标志执行其后的命令。它将首先ssh进入堡垒服务器,然后ssh进入远程服务器。
2.2 从远程服务器复制→本地机器
这将把文件从远程服务器复制到您的本地机器。再次绕过堡垒服务器。
2.远程备份
启用 RSA 密钥后,您可以使用 cron 作业每月无缝备份一个远程目录。这里有一个简单的例子。
首先,打开您的 crontab:
crontab -e
并粘贴以下内容来安排远程备份
这将在每月 1 日凌晨 1:00 将远程目录备份到您的本地计算机。
rsync标志是:
-r→递归备份源目录-t→保存文件上的时间戳
如果你不熟悉 cron jobs,我推荐以下视频
结论
远程登录服务器的能力比无钥匙进入有更多的优势。您可以无缝地将文件移动到远程服务器,跨堡垒服务器传输数据,并安排在指定时间备份远程目录。
感谢您阅读和支持媒体作者
https://lukegloege.medium.com/membership
CatBoost 机器学习算法的优势
原文:https://towardsdatascience.com/benefits-of-the-catboost-machine-learning-algorithm-fcd8c1ff2a8?source=collection_archive---------7-----------------------
意见
面向数据科学家和 ML 工程师

由 Ludemeula Fernandes 在 Unsplash 拍摄的照片。
目录
- 介绍
- 分类特征更强大
- 集成绘图功能
- 高效处理
- 摘要
- 参考
介绍
辞旧迎新。更具体地说,对于未来的许多数据科学家和 ML 工程师来说, CatBoost [2]可能会取代 XGBoost。这不仅是数据科学竞赛的一个伟大算法,而且由于各种原因,它对专业数据科学家和 ML 工程师也非常有益。通常,复杂的机器学习算法可能需要似乎永远的训练,然后缺乏关键的绘图工具,这些工具可以帮助解释特征以及模型训练本身。也许 CatBoost 最大的好处在于它的名字,我们将在下面详细阐述。话虽如此,让我们更深入地了解一下 CatBoost 的三个主要优势。
分类特征更强大

米哈伊尔·瓦西里耶夫在Unsplash【3】上的照片。
数据科学最令人沮丧的部分之一就是数据。这些数据可能包含多种形式,但可能导致所有问题的主要形式是分类特征类型。这种类型也可以更具体地描述为字符串、对象或分类dtype。
当前空间/问题
大多数(如果不是所有)其他机器学习算法的当前位置是,它们通过一次热编码摄取分类特征。这种转换意味着您将有更多的列,多达数百个甚至数千个,这些列将被赋值为 0 或 1。当然,这种方法有时很有用,比如只有两个类别时,但是当您有像 ID 这样的可以采用成千上万甚至更多独特形式的特性时,拥有稀疏数据帧只会使您的模型花费太长的时间来训练,尤其是如果它在生产环境中频繁运行的话。
下面是突出显示的当前空间:
- 过多的单热编码特征/稀疏
- 列太多
- 训练速度变慢
- 功能通常不太强大
- 在生产中匹配训练/测试/推断数据可能很困难
CatBoost 空间/好处
CatBoost 使用有序的目标编码,这实质上允许您将特征/列保持在其原始状态,从而允许您更容易地与 ml 工程师和软件工程师协作。您将不必担心匹配几个特性的“一键编码”,并按照它们的意图来解释这些特性。不仅如此,这种编码允许更重要的特性重要性。
下面是突出显示的 CatBoost 空间:
- 没有热编码/稀疏数据帧
- 保持数据帧的原始格式,使协作更容易
- 训练更快
- 分类特征更重要
- 模型更准确
- 现在,您可以使用以前无法使用的要素,如 ID 或具有高唯一计数的分类要素
总的来说,通过以 CatBoost 处理的方式对您的分类特征进行编码,该模型将更加准确,因为它经过了多次测试和比较,并在文档中进行了更详细的概述。因此,重要的是不仅要关注数字特征,还要关注过去的机器学习算法中经常忽略的分类特征。
集成绘图功能

SHAP 的 CatBoost 实现的概要图[4]。
随着新库的出现,更简单的绘图技术变得越来越普遍,CatBoost 也不例外。这个库中有几个图值得强调,包括训练图和特征重要性图。
训练地块
该图允许您只需在拟合方法中设置plot=True即可看到模型的每次迭代。您还可以看到训练与测试图,它将显示评估准确性时预期的曲线。例如,如果您使用MAE ( 平均绝对值)优化您的模型,该图将显示训练和测试最终变平,但在过度拟合之前停止,因此您将知道您的模型需要的最佳迭代次数。
- 查看训练与测试迭代
- 查看每个 X 迭代的输出,以获得更具体的精度结果
- 培训的透明度和粒度
SHAP 特征重要性
如果你已经是一名数据科学家,你会知道 SHAP [5]是评估和查看你的特性重要性的最好工具之一。比方说你想看你的模型的前 10 个特性,排名,你可以很容易地用这个库特性。我使用的主要工具是summary plot,它显示了你所有的特征,分类的和数字的。您可以通过增加或减少目标值来查看每个单独的数据点及其贡献。当与利益相关者分享结果和特征分析时,这个图非常强大,因为它非常用户友好且易于理解。
- 显示模型顶级特征的摘要图
- 每个模型在目标值上的排名
- 针对特定预测的个人
force_plot(当更深入地研究由红色和蓝色着色的特定拉动特征以获得高和低效果时非常好的粒度) - 简单地为涉众协作和演示解释模型特性
总的来说,当然,官方文档中包含了更多的图,但这两个图可能是最常用的,因为它们非常强大,对于您自己理解模型非常有用,对于没有数据科学背景的其他人也是如此。
高效处理

由 Kurt Cotoaga 在Unsplash【6】上拍照。
CatBoost 的最后一个好处是第一个好处的产物。因为没有稀疏数据框架,所以使用大量分类特征的模型处理速度比使用其他算法(如 XGBoost 或 Random Forest)要快得多。
以下是关于 CatBoost 训练和预测的其他一些更详细的效率优势:
- 分类特征处理允许更快的训练
- 过拟合检测器将在必要时自动停止模型训练
- 参数可以自我调整,因此您不必浪费时间进行调整,这可能需要几个小时甚至几周的时间——根据我的经验,CatBoost detail 总是优于手动调整或网格和随机网格搜索
- GPU 培训
每一种新的、更受欢迎的算法都关注速度和效率,而这正是 CatBoost 做得非常好的地方。
摘要
在选择机器学习算法时,数据科学家需要考虑很多因素。例如,每种算法都有许多优点和缺点,每次迭代通常会使算法或库更加面向专业人员,坦率地说,CatBoost 主要是优点。
以下是 CatBoost 库的三大优势:
* Categorical Features are More Powerful* Integrated Plotting Features* Efficient Processing
我希望你觉得我的文章既有趣又有用。如果您同意或不同意 CatBoost 库的这些优点,请随时在下面发表评论。为什么或为什么不?你用过或听说过这个图书馆吗?关于这个库,你认为还有什么好处是必须指出的?这些当然可以进一步澄清,但我希望我能够阐明 CatBoost 的一些好处。
感谢您的阅读!
我不属于这些公司中的任何一家。
请随时查看我的个人资料、 Matt Przybyla 、和其他文章,并通过以下链接订阅接收我的博客的电子邮件通知,或通过点击屏幕顶部的订阅图标 点击关注图标 的订阅图标,如果您有任何问题或意见,请在 LinkedIn 上联系我。
订阅链接:https://datascience2.medium.com/subscribe
参考
[1]lude meula Fernandes 在 Unsplash 上拍摄的照片,(2017)
[2] Yandex, CatBoost 主页,(2021)
[3]米哈伊尔·瓦西里耶夫在 Unsplash 上拍摄的照片,(2017)
[4] M.Przybyla,SHAP 实施 CatBoost 的概要图截图,(2021)
[5]斯科特·伦德伯格, SHAP 文件,(2018)
[6]Kurt coto aga 在 Unsplash 上拍摄的照片,(2018)
用 Python 实现伯努利和二项随机变量
原文:https://towardsdatascience.com/bernoulli-and-binomial-random-variables-d0698288dd36?source=collection_archive---------11-----------------------
用 Python 实现大学统计
介绍
在一系列的每周文章中,我将涉及一些重要的统计学主题。
目标是使用 Python 来帮助我们获得对复杂概念的直觉,从经验上测试理论证明,或者从零开始构建算法。在本系列中,您将会看到涵盖随机变量、抽样分布、置信区间、显著性检验等主题的文章。
在每篇文章的最后,你可以找到练习来测试你的知识。解决方案将在下周的文章中分享。
迄今发表的文章:
- 伯努利和二项随机变量与 Python
- 用 Python 从二项式到几何和泊松随机变量
- 用 Python 实现样本比例的抽样分布
- Python 的置信区间
- 使用 Python 进行显著性测试
- 用 Python 进行组间差异的双样本推断
- 分类数据的推断
- 高级回归
- 方差分析— ANOVA
像往常一样,代码可以在我的 GitHub 上找到。
随机变量
我们将从定义什么是随机变量(RV)开始。要考虑的第一个重要方面是,它不是一个传统变量。一个随机变量可以有不同的概率取不同的值,所以我们无法求解它们,例如,像我们在方程 y = x + 1 中所做的那样。相反,谈论 RV 小于或大于某个值的概率更有意义。简而言之,RV 将随机过程的结果映射到数字上。
对于我们来说,最简单的例子就是抛硬币。

图 1:抛硬币帮助我们理解房车的概念;来源
可能的结果是“正面”和“反面”,我们分别量化为 1 和 0。

伯努利随机变量
随机变量可以是离散的,也可以是连续的。我们将从关注离散 RVs 开始。根据定义,离散变量只能取不同的值,比如上面掷硬币的例子。对于这些变量,你可以计算它可以取多少个不同的值。
我们上面定义的 RV X 实际上是一个伯努利 RV。它可以以概率 p 取值 1(在公平硬币的情况下, p 等于 0.5 或 50%),以概率 q = 1-p 取值 0。其概率质量函数可以定义为:

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import bernoulli, binom
import seaborn as sns
让我们从定义一个成功概率为 p=0.3 的伯努利 RV X 开始。
p = 0.3
X = bernoulli(p)
我们可以打印 0 和 1 的概率质量函数值。
print(np.round(X.pmf(1),2))
print(np.round(X.pmf(0), 2))0.3
0.7
为了帮助形象化,让我们从变量中抽取 10,000 个样本,根据经验得出相同的值。
X_samples = X.rvs(100000)sns.histplot(X_samples, stat="density", discrete=True, shrink=0.2);

图 2:RV X 的样本分布
看起来不出所料;我们有 0.3 的成功概率和 0.7 的失败概率。
让我们定义一下 RV 的均值和方差。平均值的计算方法是将每个结果的值与相应概率的乘积相加。方差是每个结果的值与平均值的平方偏差,由各自的概率加权。更正式地说:

我们可以将经验计算的平均值与我们刚刚得出的理论平均值进行比较。它们确实非常接近,而且随着样本量的增加,它们会变得更接近。
print('Empirically calculated mean: {}'.format(X_samples.mean()))
print('Theoretical mean: {}'.format(p))print('Empirically calculated standard deviation: {}'.format(X_samples.std()))
print('Theoretical standard deviation: {}'.format((p*(1-p))**(1/2)))Empirically calculated mean: 0.30059
Theoretical mean: 0.3
Empirically calculated standard deviation: 0.45851461470709964
Theoretical standard deviation: 0.458257569495584
二项式随机变量
我们可以将二项式 RV 视为一组伯努利实验或试验。这样,我们对分布的性质是如何得到的理解就变得简单多了。
在深入定义之前,让我们先来看看将 RV 定义为二项式需要满足的主要条件:
- 审判是独立的;
- 每次试验都可以分为成功或失败;
- 有固定的试验次数;
- 每次试验成功的概率是恒定的。
让我们将 RV Z 定义为 n 次试验后的成功次数,其中每次试验的 P(成功)为 p 。
我们再定义 Y ,一个伯努利 RV,其 P(Y=1)=p , P(Y=0)=1-p 。
Y 代表组成 Z 的每个独立试验。我们已经得到了 Y 的方差和期望值。

使用下面的性质 E(X+Y)=E(X)+E(Y),我们可以导出我们的二项式 RV Z 的期望值:

回想一下,我们有 n 个独立试验或 n RV Y 被求和。
在推导 VAR(Y)时,过程是相同的,因为 VAR(X+Y)=VAR(X)+VAR(Y)也成立。然后我们有:

现在让我们用一个实验来测试我们的理论理解。
n=6
p = 0.3
Y = bernoulli(p)
我们定义了我们的 Y 变量。我们可以根据上面定义的这个 Y 变量来构造我们的 X 变量;这些是伯努利独立试验。让我们假设我们有 6 个独立的试验。
Y_samples = [Y.rvs(1000000) for i in range(6)]
Y_samples[array([0, 0, 0, ..., 0, 1, 1]),
array([1, 0, 1, ..., 0, 0, 0]),
array([0, 0, 1, ..., 1, 1, 0]),
array([1, 0, 0, ..., 0, 0, 0]),
array([0, 0, 0, ..., 0, 1, 0]),
array([0, 0, 0, ..., 0, 0, 0])]Z_samples = sum(Y_samples)print('Empirically calculated expected value: {}'.format(Z_samples.mean()))
print('Theoretical expected value: {}'.format(n*p))Empirically calculated expected value: 1.800219
Theoretical expected value: 1.7999999999999998print('Empirically calculated variance: {}'.format(Z_samples.var()))
print('Theoretical variance: {}'.format(n*p*(1-p)))Empirically calculated variance: 1.2612705520390002
Theoretical variance: 1.2599999999999998
我们对我们的理论推导感觉更好,因为我们的实验表明我们确实在正确的道路上。
我们也可以画出二项式分布。记住这是一个离散分布。
sns.histplot(Z_samples, stat="density", discrete=True, shrink=0.3);

图 3:我们的 RV Z 的抽样分布,它是一个二项式 RV。
二项式 PMF 和 CDF
二项式概率质量函数(PMF)可以写成如下形式:

乍一看似乎有点令人生畏;让我们试着把它分解成更小的可解释的部分。
第一项仅仅是二项式系数,或者当顺序无关紧要时,我们可以从 n 个可能的项目中选择 k 个项目的不同方式的数量,即集合 ABC 与 CBA 相同。

回想一下 n!/(n-k)!是排列的数量或不同方式的数量,当顺序重要时,我们可以从 n 个可能的项目中选择 k 个项目,即 ABC 和 CBA 算作两个不同的结果。 k!只是排列 k 项的数量方式。例如,在 3 个项目和 3 个位置的情况下,我们有以下可能性:

回想一下 3!=3 * 2 *1= 6.
让我们开始构建小函数来处理不同的组件,从计算输入参数的阶乘的函数开始。
def fact(n):
x = 1
for i in range(1, n+1):
x *= i
return x
fact(3)6
现在,我们可以在另一个计算二项式系数的函数中使用函数fact()。
def comb(n, k):
x = 1
return fact(n)/(fact(k)*fact(n-k))
comb(6, 3)20.0
最后,将所有东西放在一起:
def binompmf(prob, n, k):
return comb(n,k)*prob**k*(1-prob)**(n-k)
累积分布函数(CDF)是一个有用的函数,它通常与分布的 PMF 一起出现在统计包中。这只不过是我们的 RV 取值达到 a z 的概率:

def binomcdf(prob, n, x):
result = 0
for x_ in range(0, x+1):
result += binompmf(prob, n, x_)
return result
让我们试一试。

图 4:克里斯蒂亚诺·罗纳尔多的任意球表现可以用二项分布来建模,来源
我们想要评估模拟克里斯蒂亚诺罗纳尔多任意球得分能力的概率分布。我们将使用下表,其中显示了罗纳尔多在西甲联赛和冠军联赛中的任意球记录:

表 1:罗纳尔多的任意球记录,来源
c 罗有 0.094 的概率成功转换欧冠任意球。基于此,c 罗欧冠 7 罚 1 中的概率有多大?
binompmf(0.094, 7, 1)0.3639109131870316
得分小于 2 的概率是多少?
binomcdf(0.094, 7, 1)0.8649797389430357
练习:
你将在下周的文章中找到答案。
1.一家公司生产瓶装水。在其主要工厂,有缺陷的瓶子数量是 5%。质量检查包括随机选择和测试 1000 瓶。这些样品中有缺陷的瓶子数量的平均值和标准偏差是多少?
2.一家葡萄酒公司正在进行促销活动,声称每 4 箱葡萄酒中有 1 箱含有惊喜。假设你会买 5 箱这款酒,让 X 代表你在这些箱子里可以赢得的惊喜数量。假设这些盒子代表随机样本,并假设盒子之间的惊喜是独立的。你在 5 个盒子中最多赢得 1 个惊喜的概率是多少?
你能用三种不同的方法解决这个问题吗?提示:通过抽样,对个体概率求和,并使用 CDF)
3.一位数学老师正在和她的学生一起做一个活动,她给他们一个 20 题的选择题,他们一个答案也不知道。学生需要猜测每个问题,每个问题有 5 个可能的选择,其中一个是正确的。每个学生答对的问题数量的平均值和标准差是多少?
(你能用两种不同的方法解决这个问题吗?提示:通过采样和使用我们上面做的理论推导)
保持联系: LinkedIn
从零开始使用 Python 的伯努利分布
原文:https://towardsdatascience.com/bernoulli-distribution-with-python-from-scratch-89fda3c822b?source=collection_archive---------9-----------------------
如何为好奇从头编码伯努利分布

克里斯里德在 Unsplash 上的照片
为了解决一个问题,我们使用了通用的现成库,但是我们并没有去寻找这些函数如何工作以及如何为我们的目的服务。更重要的是,如果我们需要修改一个函数,我们不知道如何去做。
因此,本文的目的是如何以简单的方式编写伯努利概率分布及其一些性质,而不使用像“SciPy”这样的现成库,并从头获得一些基本技能。
伯努利分布是一种离散分布,在执行随机实验时使用,并且只获得两个结果,如好-坏、正-负、成功-失败。那些陈述被用来描述一个事件的概率。伯努利试验是表示一个实验的简单方法,如硬币正面或反面的结果,考试通过或失败的结果等。
概率函数
如果 X 是随机变量,p 是具有该分布的事件的概率,则:

伯努利概率质量函数
Python 代码:
#bernoulli probability mass function:def pmf(x,p):
f = p**x*(1-p)**(1-x)
return f
平均
伯努利随机变量 X 的平均值或期望值 E(x)为:

Python 代码:
# expected value of x
def mean(p):
return p
方差和标准偏差
随机变量 X 的方差为:

Python 代码:
#variance of x
def var(p):
return p*(1-p)#standard deviation is root of variance
def std(p):
return var(p)**(1/2)
产生随机变量
为了生成对应于伯努利分布的随机变量
Python 代码
import numpy as np#size is a parameter that how many number generates
def rvs(p,size=1):
rvs = np.array([])
for i in range(0,size):
if np.random.rand() <= p:
a=1
rvs = np.append(rvs,a)
else:
a=0
rvs = np.append(rvs,a)
return rvs
让我们把它们放在一起
import numpy as np#created a bernoulli class
class bernoulli(): def pmf(x,p):
"""
probability mass function
"""
f = p**x*(1-p)**(1-x)
return f
def mean(p):
"""
expected value of bernoulli random variable
"""
return p
def var(p):
"""
variance of bernoulli random variable
"""
return p*(1-p)
def std(p):
"""
standart deviation of bernoulli random variable
"""
return bernoulli.var(p)**(1/2)
def rvs(p,size=1):
"""
random variates
"""
rvs = np.array([])
for i in range(0,size):
if np.random.rand() <= p:
a=1
rvs = np.append(rvs,a)
else:
a=0
rvs = np.append(rvs,a)
return rvs
例子
假设一个一级方程式赛车有 0.2 的概率发生事故。因此,如果发生事故,X = 1,否则 X = 0。求 X 的期望值、方差和标准差,并产生 10 次随机变量。
p=0.2 # probability of having an accidentbernoulli.mean(p) # return -> 0.2
bernoulli.var(p) # return -> 0.16
bernoulli.std(p) # return -> 0.4#each execution generates random numbers, so array may be change
bernoulli.rvs(p,size=10)
#return-> array([0., 0., 0., 0., 1., 0., 1., 0., 0., 1.])
希望这篇文章有用,给你一个不一样的视角。
参考资料:
伯努利分布https://www.wikiwand.com/en/Bernoulli_distribution
概率分布https://www.wikiwand.com/en/Probability_distribution
用于测量文本相似性的伯特
原文:https://towardsdatascience.com/bert-for-measuring-text-similarity-eec91c6bf9e1?source=collection_archive---------1-----------------------
高性能的 BERT 语义相似度

作者形象
A 我们今天似乎要谈论的是 BERT 这个,BERT 那个。我想写点别的东西,但是伯特太太好了——所以这篇文章将是关于伯特和序列相似性的!
自然语言处理的很大一部分依赖于高维空间中的相似性。通常,NLP 解决方案会获取一些文本,对其进行处理以创建一个表示所述文本的大向量/数组,然后执行几个转换。
这是高度立体的魔法。
句子相似性是高度维度魔法有多强大的最明显的例子之一。
逻辑是这样的:
- 取一个句子,把它转换成一个向量。
- 取许多其他句子,并把它们转换成向量。
- 找到它们之间具有最小距离(欧几里德)或最小角度(余弦相似度)的句子——更多信息请参见这里的。
- 我们现在有了一个衡量句子之间语义相似度的方法——简单!
从更高的层面来说,它没有太多其他的东西。当然,我们想更详细地了解正在发生的事情,并在 Python 中实现它!让我们开始吧。
BERT 为什么会帮忙
正如我们已经提到的,伯特是自然语言处理的最有价值球员。这在很大程度上归功于贝尔特将单词的意思嵌入到密集的向量中的能力。
我们称它们为密集向量,因为向量中的每个值都有一个值,并且有成为该值的原因——这与稀疏向量形成对比,例如单热编码向量,其中大多数值为 0 。
BERT 在创建这些密集向量方面非常出色,每个编码器层(有几个)都会输出一组密集向量。

BERT 基础网络-隐藏层表示以绿色突出显示。
对于 BERT 基,这将是一个包含 768 的向量。这 768 个值包含我们对单个标记的数字表示,我们可以将其用作上下文单词嵌入。
因为这些向量中有一个用于表示每个令牌(由每个编码器输出),所以我们实际上看到的是大小为 768 的张量乘以令牌的数量。
我们可以得到这些张量,并对它们进行变换,以创建输入序列的语义表示。然后,我们可以采用我们的相似性度量,计算不同序列之间的相似性。
最简单和最常用的提取张量是 last_hidden_state 张量,它由 BERT 模型方便地输出。
当然,这是一个相当大的张量——在 512x768 处——我们想要一个向量来应用我们的相似性度量。
为此,我们需要将 last_hidden_states 张量转换为 768 维的向量。
创建矢量
为了将我们的 last_hidden_states 张量转换成我们的向量,我们使用了一个均值池运算。
这 512 个标记中的每一个都有各自的 768 个值。这种汇集操作将取所有标记嵌入的平均值,并将它们压缩到单个 768 向量空间中,从而创建一个“句子向量”。
同时,我们也不能只把平均激活当做一回事。我们需要考虑空填充标记(我们不应该包括它)。
用代码
这在过程背后的理论和逻辑上是很棒的——但是我们如何在现实中应用它呢?
我们将概述两种方法——简单的方法和稍微复杂一点的方法。
简单句子变形金刚
对我们来说,实现我们刚刚讨论的所有内容的最简单的方法是通过sentence-transformers库——它将这个过程的大部分封装到几行代码中。
首先,我们使用pip install sentence-transformers安装句子转换器。这个库在幕后使用了 HuggingFace 的变形金刚——所以我们实际上可以在这里找到句子——变形金刚模型。
我们将利用[bert-base-nli-mean-tokens](https://huggingface.co/sentence-transformers/bert-base-nli-mean-tokens)模型——它实现了我们到目前为止讨论过的相同逻辑。
(它也使用 128 个输入令牌,而不是 512 个)。
让我们创建一些句子,初始化我们的模型,并对句子进行编码:
很好,我们现在有四个句子嵌入—每个包含 768 个值。
现在我们要做的是找出这些嵌入,并找出它们之间的余弦相似性。所以对于第 0 句:
三年后,棺材里仍然装满了果冻。
我们可以用下面的句子找到最相似的句子:
现在,这是一个更简单——更抽象的方法。七行代码来比较我们的句子。
参与—变形金刚和 PyTorch
在进入第二种方法之前,值得注意的是它和第一种方法做同样的事情——但是低了一个层次。
使用这种方法,我们需要执行到 last_hidden_state 的转换来创建句子嵌入。为此,我们执行平均池操作。
此外,在平均池操作之前,我们需要创建 last_hidden_state ,我们这样做:
在我们生成密集向量embeddings之后,我们需要执行一个平均池操作来创建一个单一的向量编码(嵌入的句子)。
为了进行这种平均池操作,我们需要将我们的embeddings张量中的每个值乘以其各自的attention_mask值——这样我们就可以忽略非实数标记。
一旦我们有了密集向量,我们就可以计算每个向量之间的余弦相似性,这与我们之前使用的逻辑相同:
我们返回几乎相同的结果——唯一的区别是索引三的余弦相似性已经从0.5547变为0.5548 —由于四舍五入的原因,这是一个微小的差异。
以上是关于使用 BERT 测量句子语义相似性的介绍——同时使用了句子转换器和一个带有 PyTorch 和转换器的底层实现。
您可以在此处和处找到两种方法的完整笔记本。
我希望你喜欢这篇文章。如果您有任何问题或建议,请通过推特或在下面的评论中告诉我。如果你对更多类似的内容感兴趣,我也会在 YouTube 上发布。
感谢阅读!
参考
名词(noun 的缩写)Reimers,I. Gurevych,句子-伯特:使用连体伯特网络的句子嵌入 (2019),2019 年自然语言处理实证方法会议录
🤖带变压器的 NLP 课程
如果您有兴趣了解关于 NLP 相似性度量的更多信息(包括我们在这里使用的余弦相似性),请查看我写的这篇解释最流行的度量的文章:
*所有图片均由作者提供,除非另有说明
用于下一句预测的 BERT
原文:https://towardsdatascience.com/bert-for-next-sentence-prediction-466b67f8226f?source=collection_archive---------9-----------------------
另一半用来训练伯特

胸部+三与伯特-图片由作者(抱歉)
NNext 句子预测(NSP)是 BERT 模型(另一个是掩蔽语言建模——MLM)背后的训练过程的一半。
MLM 教伯特理解单词之间的关系,NSP 教伯特理解句子之间的长期依存关系。
没有 NSP,伯特在每一个指标上都表现得更差——所以这很重要。
现在,当我们使用预训练的伯特模型时,与 NSP 和 MLM 的训练已经完成,那么我们为什么需要了解它呢?
嗯,我们实际上可以微调这些预训练的 BERT 模型,以便它们更好地理解我们特定用例中使用的语言。为此,我们可以利用 MLM 和 NSP。
因此,在本文中,我们将深入探讨什么是 NSP,它是如何工作的,以及我们如何用代码实现它。
下一句预测
NSP 给伯特两个句子,句子 A 和句子 B。然后我们说,“嗨,伯特,句子 B 是在句子 A 后面吗?”——伯特说要么是IsNextSentence要么是NotNextSentence。
假设我们有三个句子:
- 找到神奇的绿色球体后,戴夫回家了。
- 3.6 百万年前,坦桑尼亚北部拉托里的火山灰上留下了类似人类的脚印。
- 回到家,戴夫吃完剩下的披萨,在沙发上睡着了。
如果我问你是否相信(逻辑上)那句 2 跟在句 1 后面——你会说是吗?大概不会。
句子 3 下面的句子 1 怎么样?似乎更有可能。
伯特从 NSP 那里学到的正是这种逻辑风格——句子之间的长期依存关系。
代码中的 NSP
让我们看看如何用代码演示 NSP。
我们将使用拥抱脸的变形金刚和 PyTorch,以及bert-base-uncased模型。因此,让我们首先导入并初始化所有内容:
注意,我们有两个单独的字符串——句子 A 的text和句子 b 的text2。将它们分开可以让我们的分词器正确地处理它们,我们稍后会解释这一点。
我们现在需要采取三个步骤:
- 标记化
- 创建分类标签
- 计算损失
先说标记化。
1。 标记化 —我们使用初始化的tokenizer来执行标记化,同时传递text和text2。
对于 NSP,有几件事我们应该知道。首先,我们的两个句子被合并到同一个张量集中——但是伯特有办法识别出它们实际上是两个独立的句子。
- 两句之间加一个【SEP】记号。这个分隔符由上面的 input_ids 张量中的 102 表示。
- token_type_ids 张量包含段 id,用于识别各个令牌属于哪个段。A 句用 0 表示,B 句用 1 表示。
2。 创建类标签——下一步很简单,我们在这里需要做的就是创建一个新的标签张量来标识句子 B 是否跟在句子 a 后面
我们用一个值 0 来表示IsNextSentence,用 1 来表示NotNextSentence。另外,我们必须使用torch.LongTensor格式。
3。最后,我们开始计算我们的损失。我们从通过我们的模型处理我们的inputs和labels开始。
我们的模型将返回损失张量,这是我们将在训练期间优化的内容——我们很快将继续进行。
预言;预测;预告
我们可能也不需要训练我们的模型,而只是想使用模型进行推理。在这种情况下,我们将没有标签张量,我们将修改代码的最后一部分来提取 logits 张量,如下所示:
我们的模型将返回一个 logits 张量,它包含两个值——索引 0 中的IsNextSentence类的激活,以及索引 1 中的NotNextSentence类的激活。
从这里开始,我们所做的就是使用输出逻辑的 argmax 来返回我们模型的预测。在这种情况下,它返回 0 —这意味着 BERT 相信句子 B 跟随句子 A(正确)。
这就是伯特的这篇关于 NSP 基本面的文章。我们已经介绍了 NSP 是什么,它是如何工作的,以及我们如何使用 NSP 提取损失和/或预测。
我希望你喜欢这篇文章!如果你有任何问题,请通过 Twitter 或在下面的评论中告诉我。如果你想要更多这样的内容,我也会在 YouTube 上发布。
感谢阅读!
参考
[1] J .德夫林等人。艾尔。, BERT:语言理解深度双向转换器预训练 (2019),NAACL
🤖带变压器的 NLP 课程
如果你有兴趣了解更多关于使用 NSP 的另一半——MLM 来微调伯特的知识,请阅读这篇文章:
[## 用 BERT 进行掩蔽语言建模
towardsdatascience.com](/masked-language-modelling-with-bert-7d49793e5d2c)
*除另有说明外,所有图片均出自作者之手
贝塔斯曼 Arvato 金融解决方案客户细分
原文:https://towardsdatascience.com/bertelsman-arvato-financial-solution-customer-segmentation-c8528d5ac77a?source=collection_archive---------32-----------------------

由 vectorjuice / Freepik 设计的照片
如今,随着大数据成为现实,人们开始关注如何利用数据实现商业价值。更成熟的一个领域是如何描绘潜在客户或预测客户的行为,以更精确地瞄准市场或客户。
问题陈述
贝塔斯曼 Arvato 金融解决方案在 Udacity 提供了一个现实世界的挑战。Arvato 提供了四个人口统计数据集。它们是:
- 德国一般人口的人口统计数据;891 211 人(行)x 366 特征(列),命名为 azdias。
- 邮购公司客户的人口统计数据;191,652 人(行)x 369 个特征(列),命名为客户。
- 作为营销活动目标的个人的人口统计数据;42 982 人(行)x 367(列)的响应,将其命名为 mailout_train。
- 作为营销活动目标的个人的人口统计数据;42 833 人(行)x 366(列),没有响应,命名为 mailout_test。
有了这些数据,
- 你能进行客户细分,找出最能描述公司核心客户群的人群吗?有了这个,营销才能精准定位客户,提高客户转化率,降低成本。
- 你能开发一个模型来预测哪些人会对某个活动做出反应吗?可以提高广告转化率,降低活动成本。
韵律学
考虑到问题的特征,提供了两种类型的解决方案:
对于问题 1,因为它没有标签,所以使用无监督的机器学习。这是一个高维数据集。首先使用 PCA(主成分分析 ) 进行降维,然后使用肘形法为 KMeans 选择最佳的 K 个聚类对客户进行聚类,最后结合原始数据进行分析。
对于问题 2,因为在训练集中有一个标签,所以目标是预测测试数据集。这里采用有监督的机器学习。由于训练数据集中存在明显的类别不平衡,42962 个客户中有 532 个响应,只有%1 个正值。
应该选择哪个矩阵来评估模型?让我们来看看混淆矩阵。

图 1:混淆矩阵
因为有一个很大的输出类不平衡,其中大多数个人没有回应邮寄。因此,预测单个类并使用准确性似乎不是一种合适的性能评估方法。相反,该项目将使用 AUC 来评估性能。AUC 是 ROC(受试者操作特征)曲线下的面积。该曲线绘制了不同阈值设置下的真阳性率(TPR)与假阳性率(FPR)的关系。
一些定义供您参考:
敏感性= TP/(TP+FN)
特异性=TN/(FP+TN)
TPR=敏感性= TP/(TP+FN)
FPR = 1-特异性= FP/(FP+TN)
(TP、TN、FP、FN:请参考图 1 混淆矩阵)
1。 EDA 和数据清理
对于这样一个超过 300 个特征的大文件,检查一列或一行中的数据是非常困难的。数据探索将有助于我们理解它和清理它。
图 3 以列的方式显示了一般人群的空值百分比。50%空值百分比为 0.12。

图 2:按列显示的总体空值百分比说明

图 3:按列排列的总体空值百分比
图 5 以列的方式显示了一般人群的空值百分比。50%空值百分比为 0.27。

图 4:客户在列中的空值百分比

图 5:按列排列的客户空值百分比
经过调查,除了附加列之外,这四个数据集具有几乎相同的特征。以下数据清理过程是针对四个数据集开发的。
数据清理过程总结如下:
- 把未知数据改成 Nan。未知有不同的来源,如数字数据-1,0 或字符串 X 或 XX。
- 删除有大量缺失值的列。阈值设置为 90%,这意味着如果空值的百分比超过 90%,该列将被删除。
- 删除不必要的列,例如,CMEO-DEU-2015 是 CMEO-德乌格-2015 的详细信息,可以用 CMEO-德乌格-201 表示,这些列将被删除。D19 _ LETZTER _ KAUF _ BRANCHE 是其他列信息的汇总,将被删除。
- 分类数据的编码。这只是去 KZ 西部的。
- 从数据时间数据中提取信息。仅从 EINGEFUEGT_AM 提取年份信息。
- 用大多数频率数据替换空值。
2.客户聚类
从第一步开始,已经选择了 358 个特征。现在 PCA(主成分分析)来分解特征。提取主要特征后,将使用 KMeans 对数据进行聚类。
对于 PCA 加 KMeans,有两个重要的参数需要确定:PCA 成分的数量和 KMeans 的核。
选择 PCA 和 KMeans 的参数
PCA
屏幕下方的图显示了组件 358 和 15。

图 6:n _ components = 358 的 PCA 屏幕图

图 7:n _ component = 15 的 PCA 屏幕图
从图 6,我们可以看到,200 个组件将涵盖 90%的方差,这应该是一个很好的选择,理论上。但是,实际上,运行单个笔记本电脑,PCA 200 组件需要 6 分 56 秒,然后用 combine with KMeans 运行一个多小时仍然得不到结果。考虑到输入/输出平衡,从图 7 也可以看出,在元件 15 之后,其余元件的方差小于 1%,所以我决定选择 n_componenets 作为 15。
k 表示
下面是根据肘法绘制的图。从下面的图片 8,我不能很清楚地看到肘点,妥协的现实,这可以帮助分析和数据列,我选择的质心和集群的数量为 10。

图 8:k 均值与 SSE(误差平方和)
现在选择的参数是:n_component=15,n_cluster=10。
使用拟合的模型来预测客户数据。现在我们得到了集群和客户的总体数据的概述。
聚类分割分析
现在回到主成分 0,其累积方差解释为 8.37%,如下图 7 所示。

图 9:前 5 名和后 5 名组件
如图 9 所示,这 10 大特征来自不同的预测。有了这些,我们就可以分析出特征清晰的集群。
- 普通人群与客户的聚类比较:

图 10:聚类与人口类型
从图 10 中,我们可以看到,与一般人群相比,集群 1、9、3 和 6 在百分比方面有显著变化(增加),这表明这些集群的人群有更高的潜力成为客户。
2。具有顶级特性的集群
现在,我们检查一般人群和客户之间差异最大的分类 1。
比较 Cluster1 中组件 0 的前 5 个和后 5 个变量的 Customer 和一般人群的平均值。由于 CAMEO_INTL_2015 的平均值具有非常不同的范围,因此会单独显示。
其他顶部 5 和底部 4 特征的差异如下图 11 所示:

图 11:组件 0 的顶部 5 和底部 4 特征
CAMEL_INTL_2015 的平均值为 Pics12:

图片 12: CAMEO_INTL_2015
组件 0 的前 5 名和后 5 名功能已在之前发布。现在我想按绝对权重对它们进行排序。
- MOBI 栅格法:客户的平均值为 1.02,而普通人群的平均值为 1.35。此项在提供的属性文件中找不到解释。但 MOBI 是一种移动类别,1 左右的 MOBI 栅格具有更高的潜力。
- KBA13_ANTG3: 1.00 vs 2.2,对应客户 vs 一般人群。没有对应的属性,但是我们可以发现 KBA13 显示了汽车共享的水平。
- PLZ8_ANTG3: 1.00vs 2.09,对应客户 vs 一般人群。它显示了 PLZ8 中 6-10 户家庭住宅的数量。
- PLZ8_ANTG1:来自客户的平均值为 2.00,来自一般人群的平均值为 1.82。它显示了 PLZ8 中 1-2 户家庭住宅的数量。
- CAMEO_DEUG_2015: 2.02 vs 7.14。2 代表中上阶层,7 代表中下阶层。
- KBA13_ANTG1: 2.00 vs 1.74,对应客户 vs 一般人群。没有对应的属性,但是我们可以发现 KBA13 显示了汽车共享的水平。
- MOBI_REGIO: 4.99 对 1.91,对应客户对一般人群。这是一种移动模式,表明 4.99 附近的价值比 1.91 更有潜力。
- CAMEO_INTL_2015: 14.13 vs 45.49。14 表示 2 个富裕家庭——老年家庭和成熟夫妇,45 表示不太富裕的家庭——退休老人。
- LP_STATUS_GROB: 2.21 vs 1.62,对应客户 vs 一般人群。是社会地位,表明 2.2 左右的地位,比 1.62 有更高的潜力。
- VK_DHT4A: 1.11 vs 7.81。属性表中不存在 t。
所以,目标人群的图片是 MOBI_RASTER 在 1 左右,KBA13_ANTG3 在 1.0 左右,PLZ8_ANTG3 在 1.0 左右,PLZ8_ANTG1 在 2 左右(中上阶层),KBA13_ANTG1 在 2 左右,MOBI_REGIO 在 5 左右,CAMEO_INTL_2015 在 14 左右(富裕家庭-年长家庭&成熟夫妻),LP_STATUS_GROB 社会地位在 2.21 左右,VK_DHT4A 在 1 左右。
3.客户标签
这一部分是开发一个模型来预测哪些人会对一个活动作出反应。使用监督学习。
集合模型
三个估计器:RandomForestClassifier((n_estimators=1000)、xgb classifier((n _ estimators = 1000)和 LGBMClassifier(learning _ rate = 0.001,n _ estimators = 1000,lambda_l2 = 0.1)是整体。
ROC 曲线如下图 13,14,15:

图 13: RandomForestClassifier

图 14: XGBClassifier

图 15: LGBMClassifier
三个评估者的分数和墙时间如下:
the roc_auc_score of RandomForestClassifier is 0.66, Wall time: 2min 46s
the roc_auc_score of XGBClassifier is 0.74, Wall time: 3min 58s
the roc_auc_score of LGBMClassifier is 0.75, Wall time: 49.9 s
根据分数,我选择 LGBMClassifier 作为进一步模型调整的估计器。
模式调谐
以 LGBMClassifier 为估计量,用 Gridsearch 进行 5 分裂 StratifiedKFold 交叉验证,学习率为 0.01 和 0.001,n_estimator 为 500,1000 和 2000,这里用来寻找最佳估计量。
最好的分数如下:

图 16:最佳成绩
最佳估计值是:

图 17:最佳估计值
gridsearch 结果如下:

图 18:分割分数
用最佳估计量预测测试数据集的正概率,得到 Kaggle 评分为 0.79976。

图 19: Kaggle 分数
总结:
我在这个项目中完成的工作总结如下:
- 探索人口统计数据:德国的一般人口,邮购公司的客户,以及市场活动训练和测试数据集。
- 清理数据集并选择要素。
- 使用 PCA 和 KMeans 对人群进行聚类。
- 分析高潜力聚类的前 10 个特征,以获得目标人群的相对清晰的图像
- 集成模型以选择最佳性能估计器,然后通过 Gridsearch 交叉验证调整模型。
可能的进一步测试和改进:
这是一种迭代过程。在这个过程中,我了解并发现了新的问题,并不时地重复这些过程。仍有可以进一步改进的地方:
- 优化特征选择过程,例如,部署统计技术来选择特征,检查异常值,测试删除值的不同阈值(目前使用 0.9 的列方式)
- 部署 PCA 流程可用于监督模式
- 如果重新采样,性能会如何变化
部分代码可以在这里找到。
感谢 Arvato 和 Udacity 提供如此有趣的项目,也感谢您抽出时间阅读。
数据科学家的最佳工作城市
原文:https://towardsdatascience.com/best-cities-to-work-as-a-data-scientist-a295ff60c6ef?source=collection_archive---------19-----------------------
硅谷不是你唯一的选择。世界各地都需要数据科学家,说英语和法语可能会成为一项有价值的技能。

由斯蒂芬·莱昂纳迪在 Unsplash 上拍摄的照片
数据科学家的工作前景很有希望。根据美国劳工统计局的数据,到 2026 年,大约会有 1150 万个职位空缺。这些数字表明,硅谷以外的公司认识到了数据专业人员对其业务的重要性。因此,无论是有经验的专业人士还是那些转行到数据科学的人都可以拓展他们的视野。虽然,硅谷仍然是数据专业人员的首选地区,平均工资最高,但它不是唯一的选择。
基于不同行业不断增长的需求,下面的城市列表对数据科学家来说呈积极趋势。影响以下榜单的一些因素包括招聘公司的数量、政府投资、学术界和产业界的合作以及薪资。有趣的是,主要城市不再只讲英语。对数据专业人员和人工智能的投资也投向了法语区。既然英国已经退出欧盟,说法语的趋势可能会得到推动。
所以,这里是除了硅谷,最好的数据科学家工作的城市,英语和法语分开。
说英语的城市
美国波士顿
波士顿以其高度集中的大学而闻名,如麻省理工学院和哈佛大学,以及保险和网络安全公司。根据管理咨询公司毕马威(KPMG)的数据,波士顿是全球十大城市之一,将成为“未来四年硅谷以外领先的技术创新中心”。更不用说 AngelList 上几家正在招聘的初创公司了。平均年薪为 141,000 美元,考虑到生活成本,这提供了高于平均水平的购买力。
印度德里
印度是全球发展最快的科技中心之一,德里在年轻企业家方面走在前列。越来越多的美国公司正在寻求收购当地初创公司,以进入这个复杂而又必要的市场。虽然与西方国家相比,货币汇率拉低了工资,但生活成本也很低。因此,德里成为初创公司和创新想法的绝佳测试市场。此外,瞄准印度消费者也是一个巨大的机会,因为大约有 3.4 亿人可以上网。毫不奇怪,像阿里巴巴和谷歌这样的跨国公司已经利用了中国的数字世界。
英国伦敦
伦敦是人工智能(AI)和金融科技产业(FinTech)之间联系的世界中心。英国政府与世界各地 50 多家专门从事人工智能的科技公司达成了一笔 10 亿英镑(约合 135 万美元)的交易。这座城市也是 T4 艾伦图灵研究所的所在地。伦敦经常举办国际峰会,如深度学习峰会、人工智能峰会、ODSC 的欧洲会议和 Strata Data 会议。建立关系网的机会并不缺乏。
**https://london.intelligenthealth.ai/
生活成本很高,主要是因为房租,房租可以占到一个人月收入的 60%。然而,一名数据科学家的平均工资为 61543 英镑,比全国数据科学家的平均工资高出 10%。此外,伦敦距离剑桥大学所在地剑桥只有 50 分钟的路程,被认为是欧洲领先的生物医学研究中心之一。
美国罗利-达勒姆
“三角”(罗利、达勒姆和教堂山)因两个研究和技术中心而闻名。这个三角区是联想、思杰和思科等顶级公司的所在地。罗利-达勒姆的人口更年轻、更兴旺,平均年龄为 36 岁。这个中等规模的城市群已经成为数据专业人员的首选地点之一。此外,与旧金山相比,其市民的生活成本要低得多。对数据科学家的需求主要来自医疗 IT 和技术研究实验室。
加拿大多伦多
多伦多的大部分数据专业工作都是由金融机构推动的,如道明银行、汇丰银行、加拿大皇家银行、丰业银行等。一个入门级数据科学家职位的平均年薪在 8 万到 8.5 万加元之间。多伦多大学是世界上计算机科学领域的顶尖大学之一,并培养跨学科的研究环境【9】。因此,该市在涉及大数据的广泛学术学科和商业创新方面的贡献吸引了人们的关注。多伦多也是向量研究所的所在地,该研究所推动人工智能的研究和领导,促进经济增长,改善加拿大人的生活。
说法语的城市
瑞士日内瓦
尽管瑞士是欧洲生活成本最高的城市之一,但如果你在日内瓦从事数据科学家的工作,这可能不是问题。这座城市以不断增加的财务回报吸引着有才华的数据科学家,因为日内瓦的平均净工资可能比伦敦高 75%。顶级科技公司在日内瓦设有办事处,包括戴尔、惠普、IBM、微软、谷歌和甲骨文。但如果你想在创业环境中工作,这里的是 2021 年你要关注的一个列表。
加拿大蒙特利尔
蒙特利尔市可能会让加拿大以外的许多数据科学家和人工智能专业人士感到惊讶。然而,蒙特利尔已经成为一个人工智能的发电站。据《福布斯》杂志和《深度学习》一书的作者约舒阿·本吉奥教授(T21)说:
“蒙特利尔结合了优秀的大学、创新的公司(包括在该市设立办事处的多家硅谷公司)以及加拿大的合作精神……与北美大部分地区的竞争、个人主义文化不同。【11】”
另外,在这里工作的另一个原因是蒙特利尔学习算法研究所( MILA )。该研究所类似于一家大型初创公司,已经成为蒙特利尔人工智能开发的中心。MILA 结合了麦吉尔大学和蒙特利尔大学的机器学习研究人员。它有超过 500 名专业人员致力于机器学习创新,并提供许多培训课程。
法国巴黎
最后但并非最不重要的一点是,巴黎的生活成本低于其他一些欧洲中心,比如日内瓦。自 2014 年以来,它已被 IBM 和亚马逊等知名科技公司选中来开发创新实验室,而 Deepmind 则有进一步发展其人工智能实验室的长期计划(视频如下)。巴黎绝对是一座历史悠久、充满活力的城市,这使它更具吸引力。它的特点是平均年薪约为 55,000 美元,随着法国政府承诺投资于技术和研究,这一数字可能会增加。此外,巴黎距离伦敦市中心仅 2 小时火车路程,去日内瓦也很方便。
DeepMind 研究科学家雷米·穆诺斯(Remi Munos)讲述了他回到法国建立并领导巴黎 DeepMind 的经历
结论
数据专业人员很吃香,至少在未来几年内还会如此。在硅谷做一名数据科学家可能是一个梦想,而且会一直如此。尽管如此,全球许多城市都在雇佣数据专业人士,投资机器学习,并创建人工智能研究中心。因此,讲法语的城市似乎已成为潜在的中心,从而使法语成为数据专业人员的第二语言。这是一个令人兴奋的机会,因为法语可以为有经验的专业人士和那些在转行的人开辟一条新的道路,否则,他们将无法在硅谷这样的高科技和人工智能公司工作。
感谢阅读。下面是一些你会喜欢的文章:
** https://medium.com/codex/top-10-artificial-intelligence-influencers-you-should-follow-ca91e94c797b
参考文献:
【1】https://economic times . India times . com/magazines/panache/11-5-Mn-job-openings-by-2026-sky-high-sales-why-data-science-is-booming/articleshow/74667347 . CMS?from=mdr
【2】https://www . biz journals . com/Boston/blog/bbj _ research _ alert/2016/04/meet-Massachusetts-fast-growing-cyber security . html
【3】https://www . builtin Boston . com/2016/10/11/Boston-cyber security-companies
【4】https://info . KPMG . us/content/dam/info/en/innovation-enterprise-solutions/pdf/2019/technology-innovation-hubs-2019 . pdf
https://angel.co/role/l/data-scientist/boston
****【6】https://www . insights success . in/India-the-fast-growing-tech-hub-in-the-world/
****【7】https://www . adzuna . co . uk/jobs/sales/London/data-scientist
****【8】https://www . adzuna . co . uk/jobs/sales/London/data-scientist
****【9】tae sun Yoohttps://medium.com/@yoots1988的文章,检索自https://towards data science . com/data-career-market-insights-in-Toronto-indees-indeed-ca-1e 50 CDB 88458
https://www.numbeo.com/cost-of-living/compare_cities.jsp?国家 1 =英国+英国&城市 1 =伦敦&国家 2 =瑞士&城市 2 =日内瓦
【11】https://www . Forbes . com/sites/Peter high/2017/11/06/why-Montreal-has-emerged-as-an-artificial-intelligence-power house/?sh=66ef582b23bd
https://www.aiforhumanity.fr/en/****
作为数据科学家最适合工作的公司
原文:https://towardsdatascience.com/best-companies-to-work-for-as-a-data-scientist-aa991ff29e2a?source=collection_archive---------8-----------------------
寻找数据科学职位时,拓展你的视野

乔丹·怀特菲尔德在 Unsplash 上的照片
你是一名正在积极寻找工作的数据科学家,还是转行到数据科学并想知道那里有什么?如果是这样,这篇文章将为你提供一些超越传统科技公司的数据科学家工作方向的见解。
显然,大多数数据专业人士会很乐意在一家形成广为人知的缩写 FAANG (脸书、苹果、亚马逊、网飞、谷歌)的公司工作。FAANG 公司处于技术发展的前沿。因此,数据科学家可以在这些公司中的一家工作几年,学到很多东西。
然而,根据美国劳工统计局的数据,操纵数据的需求将会上升,到 2026 年将会有大约 1150 万个职位空缺。数据专业人士(包括机器学习和软件工程师)将有如此多的机会,他们不必专注于 FAANG 公司。出于这个原因,这里列出了一些有潜力提供独特数据科学职业的科技公司。该榜单基于 Glassdoor 和科技公司最佳工作场所排名的结合。尽情享受吧!
大公司
英伟达
NVIDIA 不像你曾经工作过的地方。您将解决一些世界上最具挑战性的问题,并发现前所未有的方法来提高各地人民的生活质量。从医疗保健到机器人,从自动驾驶汽车到大片。Nvidia 正在挖掘人工智能的无限潜力,以吸引我们这个时代的爱因斯坦,并定义下一个计算时代。这是一个我们的 GPU 充当能够感知和理解世界的计算机、机器人和自动驾驶汽车的大脑的时代。做以前从未做过的事需要远见、创新和世界上最优秀的人才(也许是你)对他们一生的工作充满热情。该公司的使命是“汇集超人的能力来解决一些世界上最棘手的问题。”
快速参观:英伟达办公室
https://www.nvidia.com/en-gb/about-nvidia/careers/
销售队伍
Salesforce 是客户关系管理领域的全球领导者。它已经被评为 2020 年在英国工作的# 1****【2】。他们将公司聚集在一起,在数字时代缩小它们与客户之间的差距。Salesforce 使各个行业和规模的公司能够利用多种技术(社交、云、互联网、移动和人工智能)以一种完全创新的方式连接他们的客户。
Salesforce 的核心价值观是信任、客户成功、创新和平等。然而,该公司希望他们的员工多做一点,为每个人创造更好的体验。所以,你应该期待长时间的工作。由于大型数据集与职业行为和数字规划相关联,在 Salesforce 工作可能是一个独特的机会,可以持续产生见解并支持业务决策。如果你想在以后的职业生涯中加入 FAANG 公司,这种经历会让你成为一名出色的候选人。
https://www.salesforce.com/company/careers/?d=cta-rdr-uk-global
土坯
近四十年来,Adobe 一直致力于通过数字体验改变世界。只有 Adobe 提供了设计和交付卓越数字体验的所有工具。他们的座右铭是“为所有人创造创造力”然而,正如我们所知,新冠肺炎改变了生活和工作;企业和组织需要创造“新常态”。他们应该采用数字格式,包括 Adobe 解决方案和远程学习资源。
Adobe 提供软件和咨询服务以及增强程序,如 Adobe Sign 。他们的计划支持企业和政府机构通过浏览器或移动设备使用基于云的电子签名服务来保持运营。在 Adobe 工作的数据科学家可以扩展他们在媒体领域的专业知识,或者进入营销、销售或客户分析领域。
中型&小型公司
塔尼乌姆
Tanium 是一家总部位于美国加利福尼亚州的私营终端安全和系统管理公司。Tanium 为面临安全和 IT 管理挑战的组织提供解决方案。它们提供了跨计算机网络以无与伦比的规模快速查看一切和做任何事情的能力。对于所有热衷于 网络安全 的数据科学家来说,Tanium 应该在你的清单上。Tanium 的使命是“为世界上最大的公司和政府机构降低复杂性、提高效率并协调 IT 团队。”
了解一下 Tanium
https://www.tanium.com/careers/
OpenAI
OpenAI 是一家人工智能研究和部署公司。OpenAI 的专业人员致力于保证高度自主的系统在最具经济价值的工作中超越人类,这将使整个人口受益。他们试图建立安全和有益的人工通用智能,并间接为其他具有相同目标的公司做出贡献。作为一名数据科学家在 OpenAI 工作的独特优势之一是,他们将' audacity '作为核心价值观【3】。该公司大量投资于来自数据的见解,并不怕违反既定规范。这是一个独一无二的机会,让你超越自我,将你的见解和想法带入生活。
https://openai.com/jobs/
基础 SP
Foundation SP,简称 FSP,是一家数字解决方案和服务提供商,为组织创造积极吸引员工的机会。他们专注于释放数据的价值。该公司有一个以人为本的商业政策,并为他们从一开始就发展的以价值观为导向的包容性文化感到无比自豪。通过帮助各种公共和私营部门组织转变工作方式和利用数据解决方案,FSP 在这些组织中蓬勃发展。最终,数据是改善他们与客户和员工关系的核心。Foundation SP 的专长是商业生产力应用、数据和人工智能,以实现战略目标。
https://www.linkedin.com/company/foundation-sp/jobs/
齿轮组
手动数据部署既困难又耗时。任何公司都不应该依赖过时或不完整的数据。因此,在过去的几年里,Gearset 痴迷地使用客户反馈(以数据的形式)来驱动公司的日常发布,建立一个平台来处理最复杂的工作流。Gearset 与 Azure DevOps 和 GitHub 等领先提供商的集成意味着客户可以在其工作流程和管道的各个方面获得最佳产品。该公司现在是 Salesforce 的领先 DevOps 工具(上面已经提到)。它从刚开始使用 DevOps 的团队一直扩展到拥有数百名专业人员的团队,充分利用并行开发和持续交付。
https://gearset.com/careers/
结论
随着对数据科学家的需求持续增长,越来越多的公司依靠数据来改善其业务、产品和服务。寻找工作的数据科学家不需要(也不应该)仅仅依靠 FAANG 公司来开始他们的职业生涯。有很多不同规模的科技公司可以提供独特的专业(和学习)体验。数据科学家的公司范围很广,从网络安全和客户关系到开源人工智能。所以,花点时间想想你想专注于哪个领域的专业知识。当然,有你的公司。希望这篇文章让你对求职者应该关注的科技公司有了新的认识。如果你想了解更多,可以查看 Glassdoor 的列表和《最佳工作场所》网站【4】。
感谢阅读。这里有一些你可能会喜欢的文章:
参考文献:
【1】****福布斯https://www . Forbes . com/sites/louiscolumbus/2019/01/23/data-scientist-leads-50-best-jobs-in-America-for-2019-据 glassdoor/?sh=6d4e71e77474
【2】glass door 排名https://www . glass door . co . UK/Award/Best-Places-to-Work-UK-LST _ kq 0,22.htm
【3】OpenAI 值https://openai.com/jobs/
【4】最佳工作场所https://www . greatplacetowork . co . uk/awards/uks-best-workplaces/uks-best-workplaces-2020/
2021 年学术界最佳数据科学工具
原文:https://towardsdatascience.com/best-data-science-tools-for-academia-in-2021-587d94b3541c?source=collection_archive---------31-----------------------
学术界数据科学家的三大工具

活动发起人在 Unsplash 上的照片
数据科学领域的发展速度与其他领域不同。机器学习在不断发展,像 PyTorch 和 TensorFlow 这样的库也在不断改进。像 Open AI 和 Deep Mind 这样的研究公司不断推进机器学习可以做的事情的边界(即: DALL。E 和夹住。基本上,成为数据科学家所需的技能保持不变,即统计学、Python/R 编程、数据库、PyTorch/TensorFlow 和数据可视化。然而,数据科学家使用的工具总是在变化或更新。
我是学术界的一名研究员,我注意到学术界在实施行业中可用的最新工具方面落后。因此,本文将介绍 2021 年学术数据科学家的最佳工具。此外,这可能对数据科学领域的初学者或希望在工作场所实现一些数据科学技术的非程序员最有用。
1.来自谷歌云平台的 AutoML
机器学习即服务(MLaaS)在云上训练模型的选项有很多,比如亚马逊 SageMaker、微软 Azure ML Studio、IBM Watson ML Model Builder 和谷歌 Cloud AutoML。
就这些 MLaaS 供应商中的每一个所提供的服务而言,事情在不断变化。几年前,微软 Azure 可能是最好的,因为它提供异常检测、推荐和排名等服务,而当时亚马逊、谷歌和 IBM 都不提供这些服务。但是现在情况变了。找出哪个是最好的 MLaaS 提供商可能需要一篇完全不同的文章,但是,在 2021 年,很容易根据用户界面和用户体验选择一个最喜欢的。
目前,我正在开发一个用于算法交易的机器人,虽然一开始,我是在亚马逊网络服务(AWS)上工作的,但我发现了一些障碍,这让我尝试了一下谷歌云平台(GCP)。我过去用过 GCP 和 AWS,我倾向于使用任何在价格和易用性方面最方便的系统。
在使用 GCP 之后,推荐它的主要原因是他们在用户界面上做的工作,使它尽可能的直观。你可以在没有教程的情况下直接跳到上面,这样事情就变得有意义了,而且实现起来花费的时间也更少。因此,来自 GCP 的 AutoML 是 2021 年值得关注的事情。
贝娄,找一个 GCP 的视频解释 AutoML 是如何工作的:
2.IDEs: Jupyter 笔记本/ PyCharm / Visual Studio 代码
使用正确的 IDE 来开发您的项目绝对是需要考虑的事情。尽管这些工具在程序员和业余爱好者中是众所周知的,但是仍然有许多非专业程序员可以从这个建议中受益。举个例子,我发现学术界很大一部分在 Jupyter 笔记本的实现上落后了。事实上,学术界的研究项目是实施笔记本电脑以优化知识转移管理的最佳方案。

图片作者:Jupyter Notebook
如果需要更多关于 Jupyter 笔记本的信息,我会在这里留下几个链接和这里,链接到更深入讨论 Jupyter 的其他文章。
像 PyCharm 和 Visual Studio 代码这样的工具几乎是 Python 开发的标准。PyCharm 是我的首选,也是最流行的 Python IDEs 之一。它兼容 Linux、macOS 和 Windows。它附带了大量的模块、包和工具来增强 python 开发体验。而且它有很棒的智能编码特性。
3.蟒蛇
Anaconda 是实现虚拟环境的一个很好的解决方案,它非常适合复制别人的代码。作为一名数据科学家,我总是试图创建一个 requirement.txt 文件,其中包含我的代码中使用的所有包。同时,当我要实现别人的代码时,我喜欢从头开始。用 Anaconda 启动一个虚拟环境并从 requirement 文件夹安装所有必需的包只需要两行代码。如果这样做之后,我不能实现我试图实现的代码,那么这是别人的错误。
在我开始使用 Anaconda 之前,我曾多次在尝试使用由特定版本的包(如 NumPy 和 pandas)开发的脚本时遇到各种各样的问题。例如,最近我发现了 NumPy 的一个 bug,而 NumPy 支持团队的解决方案正在退化到以前的 NumPy 版本(临时解决方案)。现在假设您想使用我的代码,而不安装我使用的 NumPy 的确切版本。我就是不工作。这就是为什么在测试别人的代码时,我总是使用 Anaconda。
在链接到这里、的文章中,sou Maya mauthor博士比较了 Anaconda 和 pipenv 创建 Python 虚拟环境的能力。正如在那篇文章中可以看到的,实现 Anaconda 有一个明显的优势(只是以防万一,您不确定这是不是最好的选择)。
结束语
总的来说,本文推荐实现像 Anaconda 和 Jupyter 这样的工具。虽然这和业内很多专业人士做的没什么区别,但这不是我在学术界发现的(有例外)。因此,我希望这篇文章能帮助学术数据科学家优化他们的工作流程。
来自 Google 云平台的 AutoML 提供了 MLaaS,绝对是值得考虑的,特别是对于小型研究团队,他们有足够的预算来覆盖 AutoML,但可能不足以购买大数据服务器。
感谢您的阅读,感谢您对本文的任何反馈。你可以在我的 GitHub 页面上看到我在机器学习方面的公开工作,并随时关注我或通过 LinkedIn 联系我。
每个数据科学家都应该知道的最佳特性工程方法
原文:https://towardsdatascience.com/best-features-engineering-methods-every-data-scientist-should-know-34011df40ee0?source=collection_archive---------27-----------------------
高级数据科学家用于快速特征工程的技巧和诀窍

由 Sabrina Nedjah 在 Unsplash 上拍摄的照片
文章合著者 s 作者: @bonnefoypy 和@ emeric . chaize Olexya 的 CEO 们。
在大多数数据科学项目中,特性工程是探索性数据分析之后的自然步骤。该过程包括设计正确的特征以获得最佳预测。易于使用的特性工程方法包括 Pycaret 和 Azure studio。
要成为独角兽数据科学家,掌握最新的特征工程方法是一项必备技能。在本文中,我们将回顾 Kaggle winners 的特性工程方法,这些方法可以简单快速地实现。
- Pycaret
PyCaret 是一个简单易用的顺序管道,包括一个很好的集成预处理功能,包括一步特征工程:
**#import libraries**!pip install pycaretfrom pycaret.regression import * **#open the dataset**df = pd.read_csv('dog_data.csv')df

狗数据集(作者提供图片)
**#define feature engineering pipeline:**from pycaret.regression import *exp = setup(data = df, target = ‘breed’, feature_interaction = True)

Pycaret 特征工程操作 ( 图片由作者提供)
所有预处理步骤都在 setup()中应用。用 20 多种特征工程方法为你的机器学习准备数据集,包括多项式、三角函数、算术运算。与目标相关的最佳特征被自动选择。

Pycaret 算术工程管道的新特性 ( 图片由作者提供)
Pycaret 算术工程管道的新特性 ( 图片由作者提供)
模型=设置(df,target = '品种',多项式 _ 特征=真)
型号[0]

Pycaret 多项式工程管道的新特性 ( 图片由作者提供)
更多关于 PyCaret 预处理能力的细节请点击这里。

由 Slashio 摄影在 Unsplash 上拍摄
2。蔚蓝工作室
微软的这款免费工具(无需注册信用卡)可以通过模块化方法,使用带有完整数据导入选项的个性化数据工程管道,以简单快捷的方式自动创建功能。

Azure Studio 导入数据向导 ( 图片由作者提供)
以下示例使用此方法从 139067 行 56 列的财务数据集中设计新功能。

Azure studio 功能工程管道(图片由作者提供)
例如,从数字“paymentInstrumentAgeInAccount”数字特征,框架可以在不到一分钟的时间内一步创建 300 多个新特征:

Azure studio 数学运算(图片由作者提供)
拥有 300 多种操作和功能的完整列表:

蔚蓝工作室特别行动 ( 图片由作者提供)
通过将 R、SQL 和 python 脚本相结合,可以从一系列预配置选项中创建一个更复杂的框架,如下所示:

Azure studio 以使用 R 脚本的工程管道为特色
关于 Azure 预处理能力的更多细节点击这里。
总结一下
这个简短的概述提醒我们在数据科学中使用工程方法的几个特征的重要性。这篇文章涵盖了快速简单的工程方法,并分享了有用的文档。
结论
如果你有空闲时间,我建议你看看这个:
</4-tips-for-advanced-feature-engineering-and-preprocessing-ec11575c09ea>
希望你喜欢,继续探索!

照片由 Ozgu Ozden 在 Unsplash 上拍摄
为机器学习简化数学的最佳库
原文:https://towardsdatascience.com/best-library-to-simplify-math-for-machine-learning-ed64cbe536ac?source=collection_archive---------14-----------------------
使用 sympy Python 库简化用于机器学习的微积分

图片由皮克斯拜的 Gerd Altmann 提供
没有数学,你什么也做不了。你周围的一切都是数学。你周围的一切都是数字。 —夏琨塔拉·戴维
数学是机器学习的一个重要方面。虽然有些人可能绝对崇拜数学,但有些人可能不喜欢它。然而,要成功解决机器学习任务,至少要有一些数学知识,并理解概率、统计和微积分的概念。
在这篇文章中,我们将重点放在微分和积分。这两个概念是学习机器学习概念的重要方面。虽然积分学在你的机器学习之旅开始时可能没有太大用处,但当你对这门学科有了更深入的了解时,它会变得更有意义。
另一方面,微分学和微分在实现机器学习的许多目标中起着至关重要的作用。在通过神经网络或其他类似结构的反向传播中,可以注意到分化的一个最重要的用例。为了验证输出的结果或在训练期间产生有效的结果,微分和反向传播起着至关重要的作用。
在这篇文章中,我们将保持一切简单和容易。我们将学习更多关于 sympy 库的知识,我们将利用它来简化区分和整合。在理解了这个库的基本概念之后,我们将最终构建一个简单的差分计算器。事不宜迟,让我们从探索这些主题开始吧。
什么是 sympy?

图片由 Gerd Altmann 来自 Pixabay
我们已经讨论过,积分和微分被认为是理解多种机器学习概念(如反向传播)的先决条件。幸运的是,python 还提供了一个免费的、轻量级的、基于 python 的库,名为 sympy 。这是一个符号数学的 python 库。
在您的系统上安装 sympy 库之前,有一些先决条件。其中一个主要要求是,您需要在您的环境中安装 mpmath Python 库。推荐的安装方法是在 Anaconda 环境的帮助下进行,因为大多数先决条件都是在这里安装的。
Anaconda 是来自 Continuum Analytics 的免费 Python 发行版,包括 SymPy、Matplotlib、IPython、NumPy 和许多更有用的科学计算软件包。应该使用以下命令来更新 Sympy 库。
conda update sympy
对于普通安装,一旦您满足了要求,包括 Python 版本高于 3.5,您就可以用下面的命令安装这个库。
pip install sympy
在安装了这个库之后,您可以继续用几行代码执行数学演算操作,比如积分和微分。让我们首先用一些具有差异性和集成性的代码块进行实验。在学习了一些基本功能之后,我们将继续构建一个简单的差分计算器。
通过 Sympy 轻松实现差异化:
在本文的这一部分,我们将了解一些与 sympy 差异相关的基本功能和操作。首先,我们将导入这个库,然后按照步骤轻松区分一个特定的函数。建议您在 Jupyter 笔记本上并排跟随,以获得每个代码示例的最佳结果。
import sympy
我们将继续分析 sympy 库的一些基本功能和操作。首先,我们需要为它将携带的符号类型定义一个变量。这里的“x”是我们选择的象征。一旦你设计好了符号,你就可以开始执行微分操作了。在这个例子中,我对下面的函数做了一个简单的计算——5x。您可以随意尝试该库并探索更多内容。
x = sympy.Symbol('x')
deriv = sympy.diff(5*(x**2))
deriv
结果:
10𝑥
要了解构建更多独特项目所需的所有差异化规则,我建议查看以下链接这里。
与 Sympy 轻松集成:
在本文的这一部分,我们将了解与 sympy 集成相关的一些基本功能和操作。首先,我们将导入库,然后按照步骤对几个函数进行集成。要了解构建更多独特项目所需的所有整合规则,我建议查看以下来自的链接。
from sympy import *
在接下来的几个代码块中,我们将继续执行一些基本的集成操作。这些函数非常简单,不言自明,对集成有基本的了解。
x = Symbol('x')
limit(sin(x)/x, x, 0)
结果:
1
integrate(1/x, x)
log(x)
结果:
log(𝑥)
有了这些关于 sympy 的基本知识,让我们在本文的下一节中继续构建一个简单的差分计算器项目。
简单项目:
现在,我们将为一个基本的微分计算器构建一个简单的项目。为了理解构建这个计算器所需的所有微分规则,我建议从这里查看以下链接。我将只提供一个小的代码片段类型的差分计算器,我试图建立。你可以使用你自己的创新思想,执行更有效的差分计算器。下面是一个简单的代码块,展示了导数计算器的一些可能的函数。
class Derivative_Calculator:
def power_rule(*args):
deriv = sympy.diff(*args)
return deriv
def sum_rule(*args):
derive = sympy.diff(*args)
return deriv
我已经利用导数计算器类编写了一系列带有*args 注释的函数,因为我们不知道将通过该函数传递的元素数量。这个概念对于构建差分计算器很有用。我只利用了这些微分法则中的一些。我鼓励用户多尝试这些。下面的文章是理解 Python 中的高级函数的指南,并附有代码和示例。
在下一个代码块中,我们将允许用户选择一个他们想要执行特定操作的选项。这些选项的选择范围包括不同类型的区分规则。你可以自由地试验并构建一个你喜欢的差分计算器。
print("""
Enter The Type of Operation to be Performed: (Choose the number of your choice -)
1\. Power Rule
2\. Sum or Difference Rule
3\. Product Rule
4\. Chain Rule
""")
Operation = int(input())
Derivative = input("Enter your derivative: ")
上面的代码块将产生下面的结果。在这里,我通过选项选择“1”来激活幂规则,并对函数 3x 执行计算。
结果:
Enter The Type of Operation to be Performed: (Choose the number of your choice -)
1\. Power Rule
2\. Sum or Difference Rule
3\. Product Rule
4\. Chain Rule
1
Enter your derivative: 3*x**2
最后,我将激活下面的代码块,这将使我的类和幂规则函数能够输入正确的答案。
differentiatie = Derivative_Calculator
differentiatie.power_rule(Derivative)
结果:
6𝑥
我们可以注意到,提供了微分后的准确答案。虽然这是一个简单的项目,但我鼓励你们所有人把它变得更加复杂和创新!
结论:

由 Alexandru Acea 在 Unsplash 上拍摄的照片
纯数学,就其本身而言,是逻辑思想的诗歌。
—阿尔伯特·爱因斯坦
数学知识对于理解机器学习的复杂细节和成为该领域的专家至关重要。只有对数学有了详细的了解,你才能解释一些关键概念,这是深入特定主题所必需的。大多数机器学习算法需要数学,微积分的学习是机器学习进一步发展的重要因素之一。
在本文中,我们了解了为什么数学对于任何追求机器学习的爱好者来说都是必不可少的。然后,我们继续了解与 sympy 库相关的基本元素,以及如何将它用于微积分。最后,我们构建了一个简单的导数计算器项目,可以对其进行改进以适合您的目的,并用于简化您的实际计算。
你可以从这里查看官方文档,了解如何使用这个模块的更多细节。但是,如果您对本文讨论的主题还有任何困惑,请随时告诉我。我会尽可能快地回复你。
看看我的其他一些文章,你可能会喜欢读!
</6-best-programming-practices-f2605c5b469c> </5-essential-skills-to-develop-as-a-data-scientist-16442f094c09> </5-nlp-topics-and-projects-you-should-know-about-65bc675337a0> </7-tips-to-crack-data-science-and-machine-learning-interviews-38b0b0d4a2d3>
谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!
arXiv 精选—2021 年 2 月阅读
原文:https://towardsdatascience.com/best-of-arxiv-january-2021-59863785b729?source=collection_archive---------17-----------------------
ML 论文每月精选。

在你的阅读清单上保持领先是很难的,而找到哪些论文应该在阅读清单上更难。在 Zeta Alpha 我们总是密切关注最新的 ML 研究,所以我们认为每月分享一次最近的论文精选会很有用,以展示我们认为会有影响力的出版物,主要基于每部作品的贡献和作者的声誉。不要把这个列表看得太全面:像其他人一样,我们也有自己的偏见,但是你能从 2000 多篇论文中选择的就这么多了。尽情享受吧!
1.从自然语言监督中学习可转移的视觉模型(OpenAI CLIP) | ✍️ 博文 |👾代码
亚历克·拉德福德、琼·金旭等人
🎖 为什么→ OpenAI 论文总是在社区中制造很多噪音,大多数时候是有充分理由的。结果部分的广泛性和令人印象深刻的零射击性能使这部作品成为对 CV 和 NLP 感兴趣的人的必读之作。
💡关键见解→ 这部作品的主旨遵循了 OpenAI 的剧本,并再次证明了萨顿的惨痛教训:
- 为任务策划有史以来最大的同类最佳数据集;在这种情况下,(图像、文本)对从网络上爬取(4 亿个样本🤯).
- 精心设计大规模和大型计算机培训。
- 展示如何一个简单的任务就是你所需要的全部如果你扩展数据和计算足够的话。
在这种情况下,他们从网络上创建了一个 4 亿(文本,图像)对的数据集,没有任何人工标记,并在对比设置中共同学习文本和图像的表示;其中该模型最大化正面(文本、图像)对的相似性,并且推开负面对。实验的广度确实令人惊叹,在这些结果中,也许最有趣的是那些零镜头分类、在顶级 ResNet-50 特征上的性能可与完全监督的线性分类器相媲美(见下图)。

剪辑(左)和零镜头分类方法的对比预训练框架。来源:https://cdn . open ai . com/papers/Learning _ Transferable _ Visual _ Models _ From _ Natural _ language . pdf

CLIP vs ResNet50 的零射击性能+微调线性分类器。来源:https://cdn . open ai . com/papers/Learning _ Transferable _ Visual _ Models _ From _ Natural _ language . pdf
2. RepVGG:让 VGG 式的网络再次伟大起来👾代码
丁小寒等著
🎖 为什么→ SOTA 不是一切,这项工作证明了它回到了图像分类的鲁棒快速 CNN 的基础,同时保留了分支 resnets 的最新技巧的性能,实现了速度-性能的平衡。
💡关键见解→ 随着计算机视觉领域的成熟,效率、速度和可定制性变得越来越重要,因为研究希望与现实世界的应用相关。这项工作背后的主题是“让我们回到基础并擅长于此”:他们吹嘘没有分支,只使用 3x3 卷积+ ReLUs,不使用架构搜索、复合缩放或任何其他“繁重的设计”。
本文的主要贡献是作者所谓的结构重新参数化。该方法允许训练具有剩余连接的模型,然后将它们转换成单路径模型拓扑,这使得推理非常快。ImageNet Top-1 的性能仍然在 80%左右(远远低于 SOTA 的 90%),但单个 GPU 上每秒示例的真实速度远远领先于竞争对手。

与其他现有模型相比,ImageNet top-1 精度和推理速度的权衡。来源:https://arxiv.org/abs/2101.03697
3.让预先训练的语言模型成为更好的一次性学习者 |👾代码
高天宇、亚当·费舍尔和陈。
🎖 为什么:我们不会很快部署 GPT-3 大小的型号,因为它需要资源,但我们都在为更小的型号带来令人惊讶的少量拍摄能力!
💡关键见解:可以说,GPT-3 的主要贡献是令人惊讶的少数和零射击性能以及“提示范式”,其中不是在任务上微调模型,而是找到提示,使模型成功执行任务,而无需任务特定的标签。在这项工作中,作者研究了我们如何训练更小的语言模型来显示类似的少数镜头能力。论文的相关工作部分是类似研究方向的相关参考文献的金矿,如 Schick 和 Schütze 的《小语种模型也是少镜头 Learners"⁴》。
本文考虑了几个镜头学习设置,其中我们假设有一个预训练的模型 L,我们希望用每类 K 个训练示例的有限集合对新任务 D 进行微调。为此,他们研究了基于提示的微调,这种微调不是用来自任务 D 的监督信号来更新模型参数,而是将训练样本与提示连接起来,这将使模型通过分类来完成句子。例如,给出一个电影评论"没有理由看它。”,模型提示“无理由观看。果然是【面具】”该模型预测掩码标记,我们将掩码标记与情感标签相关联。
他们通过手动和自动提示以及“演示”来探索微调,这将标记的示例连接到模型提示的输入。结果表明,使用这些技术,小语言模型可以在少数镜头设置上表现得非常好。

不同提示和微调策略的结果。来源:https://arxiv.org/abs/2012.15723
4.开关变压器:通过简单有效的稀疏性扩展到万亿参数模型 |👾代码
威廉·费杜斯、巴雷特·佐夫和诺姆·沙泽尔。
🎖 为什么→ 我们经常把更多的参数与需要更多的计算联系在一起,但事实并非如此。放大模型是一种趋势,将在未来几年保持相关性,这项工作是一个很好的例子,推动模型大小的边界。
💡关键见解 →题目中的万亿这个词需要一些说明,这些万亿参数是稀疏,这意味着它们中的大部分在计算一次向前传球时都没有用到。每个转换器层都是专家的混合体,在推理时进行硬路由,这样,当您添加专家时,每次向前传递的操作数保持不变,尽管内存占用和计算节点之间的通信开销会增加。
这篇论文有太多的内容要在几个段落中浓缩,但我要强调的是,最有趣的发现之一是如何通过向每一层添加专家来扩大变压器的规模,从而大大加快学习速度,同时保持其他变量不变。
从结果来看,在最大参数数量时,性能仍然没有接近收敛,因此我们可以期待在变得更大时发现更多有趣的现象。这在现实世界的设置中很重要,因为较小的模型可以从较大的模型中提炼或删减,而较大的模型优于从零开始训练的等效模型;这是一种可能在未来几年成为主导的学习模式。

作为稀疏模型参数(左)和训练步骤(右)的函数的性能增益。对于所有显示的情况,推断中的失败次数都是相同的。来源:https://arxiv.org/pdf/2101.03961.pdf
5.论随机鹦鹉的危险:语言模型会不会太大?
作者:艾米莉·本德、t·格布鲁、a·麦克米兰·梅杰和 Ss·什米切尔。
🎖Why → 作为我们刚刚分享的关于大变形金刚的工作的对比,这里有一篇论文指出了语言模型现状的危险。2020 年 12 月初,关于这项工作初步版本的争议引发了谷歌人工智能伦理研究员蒂姆尼特·格布鲁(Timnit Gebru)的解雇,这成为了人工智能内部伦理和谷歌在 2010 年可疑地位的公开辩论的中心。
💡关键见解→ 在这份立场文件中,作者回顾了语言模型的现状及其带来的更广泛的危险,如环境和财务成本,这是一个长期存在负面社会偏见的训练数据集,与从业者缺乏问责制有关。作者提出的建议是在建立语言模型时权衡这些因素,并超越语言研究中越来越大的模型,而是专注于诸如管理和记录更高质量数据集的领域。虽然这篇论文背后的整个故事使其内容比实际更重要,但这是一篇有趣的阅读,有许多相关参考资料,捕捉了截至 2021 年 1 月的语言模型快照。

突出的语言模型及其参数计数和预训练数据集大小。来源:http://faculty . Washington . edu/e bender/papers/random _ parrots . pdf
6.反思多级检索管道中 BERT 重排序器的训练👾代码
高鲁豫、戴、杰米卡兰。
🎖 为什么 →我们发现这项工作在 MS-Marco 排行榜上名列前茅,这是最受欢迎的信息检索基准之一,尽管边缘非常粗糙,但这篇论文基于神经检索损失函数的一个非常简单的变化,结果很有希望。
💡关键见解→ 现代神经重排序器分两步工作,以减轻运行完整神经网络来计算每个文档查询对的相关性的高计算成本。
- 初始检索器(M)从整个文档集 d 中选择候选库 C
- 一个神经模型——re-ranker(R)——获得每个文档-查询对作为输入,并对它们的相关性进行评分。该过程通常依赖于查询文档相关性的人工注释,其中重分类器最小化所有候选 C 中的二进制交叉熵损失,将它们分类为正样本或负样本。

人们通常会期望,当第一模型 M 变得更好时,系统的整体性能将会提高,因为重新排序器得到了更好的样本可供选择,并且工作人员已经试图改进这个第一检索阶段。然而,实验表明,当检索器 M a 选择更好的文档池时,重新排序器 R 通常更难区分相关文档和不相关文档。本文针对这种现象提出了一种非常简单的解决方案,该解决方案包括用对比损失来代替 BCE 损失(其中所有文档被分类为相关或不相关),其中一次仅考虑一个正面文档,并且负面文档通过 M 在排名靠前的文档中进行采样,这比 BCE 对假阳性的征税更强:

这个巧妙简单的改变足以让这部作品达到 MS-MARCO benchmark 的巅峰。然而,如果你查看这篇论文,你会发现这仍然是非常粗略的初步工作,结果非常有限:顶级性能依赖于技巧和启发(正如所有领先的 IR 方法一样),并且需要更多的消融实验来真正理解在重新排序中使用这种对比损失的好处。我们期待着那一天!

与之前最先进的 PROP 相比,建议模型的性能。来源:https://arxiv.org/abs/2101.08751
7.用于开放领域问题回答的神经检索器的端到端训练👾代码
Devendra Singh Sachan 等人
🎖为什么→ 与之前的论文不同,这项工作对开放式问题回答(QA)的预训练任务进行了详细的系统研究,它与我们刚刚讨论的文档排序和重新排序任务有很多共同之处。它很好地介绍了在 QA 排行榜上占主导地位的最新实践,由来自 MILA、麦吉尔和英伟达的知名研究人员撰写。
💡关键见解→ 在这种情况下,开放式问题回答的神经管道也包括第一阶段检索器,它选择一组上下文、和读者提出的问题“ q 和上下文“K”的集合,对它们进行编码,然后基于这两部分输入对答案“a”进行解码。作为读者模型,他们使用预先训练的 T5 模型。
与开关变压器论文类似,在一个段落中要总结很多内容。为检索者研究的两个主要的训练前任务是逆向完形填空任务(ICT)和掩蔽显著跨度:
- 逆向完形填空任务(ICT):提取文档的片段,并在对比设置中学习片段和文档的表示,该表示将片段与它们原来所属的文档相匹配。
- 掩蔽显著跨度:预测标记(如命名实体)的掩蔽显著跨度。
此外,这项工作比较了将上下文纳入答案生成的两种方法:
- 单个 top-k:答案的可能性被分解为上下文集合的边际总和 K 。
- 联合 top-k:答案的可能性是直接在上下文集合上计算的 K. 在实践中,这意味着上下文被连接起来作为读者模型的输入,问题可以同时关注所有文档以生成答案。
这项工作为第一个检索阶段以及自然问题和 TriviaQA 数据集的“端到端”QA 提供了最先进的技术。

只检索自然问题和繁琐问题的结果。来源:https://arxiv.org/pdf/2101.00408.pdf

与之前的 SOTA 相比,端到端 QA 性能。来源:https://arxiv.org/pdf/2101.00408.pdf
8。对手实例化:差分私有机器学习的下限
米拉德·纳斯尔等人
🎖 为什么→ 差分隐私(DP)的机器学习实践仍然不是主流,部分原因是进入门槛高,研究阶段相对较早。不要让标题中的花哨词汇吓到你,这项工作提供了对 DP 的广泛介绍,并研究了在现实约束下实例化对手时可以保留多少隐私。
💡关键见解→ 假设您想要在医院托管的机密医疗数据上训练一个模型。您使用这些数据定义一个用于训练模型的计算,对于训练的每一次迭代,您将模型的权重发送给医院,医院计算一些权重更新并将其发送给您。现在,如果你是一个非常聪明的坏演员——一个对手— ,在给定权重更新的情况下,你能从训练数据集中推断出任何个人数据吗?差分隐私负责给你收到的数据添加足够的噪音,这样你就无法从中恢复任何有意义的数据(这是一种极端的过度简化,但你已经明白了要点)。
现在,差分隐私通常研究隐私的正式上限(即最坏的情况),例如,假设的对手可以完全访问每个中间权重更新。但是在真实的环境中,我们可以将这些约束进一步细化为更现实的约束。例如,的对手只能访问最终模型,或者只能通过 API 访问其预测,等等。本文考察了隐私保护如何在这些更现实的案例中发挥作用。结果表明,当这些现实的约束被强加时,隐私界限是如何大大增加的,这是这些技术的现实世界适用性的一个有希望的结果。

现实对手约束下的差分隐私保护综述。来源:https://arxiv.org/pdf/2101.04535.pdf
9. GENIE:文本的人在回路评估排行榜 |👾代码 |🌐网站
丹尼尔·哈沙比等人
🎖 为什么:如果当今的 ML 进展都是关于排行榜的,那么这些就不应该局限于完全自动评估的领域。文本生成就是这样一个任务,完全自动的评估是非常困难的:BLEU,ROUGE 分数在一定程度上与人类的判断相关,一旦它们成为优化目标,这种相关性就会消失。
提出了一种结合经典自动评测和众包便捷人工评测的评测基准。这里做了大部分繁重的工作:人工评估基准已经使用了几十年,但是从来没有像 GLUEbenchmark 这样的自动基准那样大规模和方便。现有的人在回路评估框架,如 HYPE⁵、ChatEval⁶或 HUME⁷,每个都只专注于一项任务,所以看看 GENIE 作为一个更通用的基准在社区中获得多少牵引力将是有趣的。
🔗哪里可以找到:你可以在 https://leaderboard.allenai.org/genie-mt/submissions/public找到更多关于它以及如何提交你的模型的信息

GENIE 目前支持的任务。来源: GENIE
文本生成的人在回路评估排行榜
10.机器人操作中自动发现目标的不对称自我游戏 |📺演示
作者 OpenAI 等人(要求论文引用格式)
🎖 为什么→ 自我游戏适用于机器人操作。尽管由于缺乏实验深度(即所有实验都只是模拟)而被 ICLR 2021 拒绝,但其背后的想法是非常有前途的,毫无疑问将产生坚实的影响。
💡关键见解→ 本文介绍了机器人操纵的任务,这实质上意味着让机器人学习操纵给定指令或特定目标的对象。在这种情况下,他们探索机器人如何学习操纵物体来实现目标,只给定最终目标,没有指令。
解决这个问题的想法很简单:我们考虑两个机器人,爱丽丝和鲍勃。Alice 创建对象的配置,Bob 需要复制它们。Alice 因提出 Bob 无法创建的配置而获得奖励,Bob 因能够复制 Alice 的状态而获得奖励。假设 Alice 需要为 Bob 生成配置,我们确信 Bob 呈现的状态是可行的。在这种情况下,爱丽丝和鲍勃都不需要被贴上标签的监督,并且鉴于爱丽丝和鲍勃都是在这种对立的情况下从头开始,爱丽丝提出的配置自然会变得越来越困难,模仿课程学习的概念,其中任务变得越来越困难,但没有明确地管理一组按复杂程度分级的任务。
要使这一过程稳定并在实践中发挥作用,还需要许多额外的细节,但正如模拟实验所指出的那样,自我游戏似乎比教会鲍勃成为操纵表面上的物体的专家的课程学习更有效和更强大。

机器人操作的自我游戏框架。来源:https://arxiv.org/pdf/2101.04882.pdf

不同简单任务上自我游戏与课程学习的比较。来源:https://arxiv.org/pdf/2101.04882.pdf
我们的每月精选到此结束,但我们才刚刚开始。如果你想了解最新的研究,请在推特上关注我们 @zetavector 。我已经在期待分享二月份的下一个选择;回头见!
参考文献:
[1]“弱监督开放领域问答的潜在检索”Kenton Lee 等 2019。
[2]领域:检索-增强语言模型预训练Guu 等 2020。
[3] " 用统一的文本到文本转换器探索迁移学习的极限" Colin raff El 等人,2020。
[4] " 小语种模特也是很少出手的学习者" Schick 和 Schütze 2020。
[5]HYPE:生成模型的人眼感知评价基准Sharon Zhou 等 2019。
[6] " ChatEval:一个聊天机器人评测的工具" joo Sedoc 等人 2019。
[7]“统一人工和统计评价的自然语言生成”Tatsunori Hashimoto 等人 2019。
arXiv 精选—2021 年 6 月阅读
原文:https://towardsdatascience.com/best-of-arxiv-june-2021-dcd3aa48a66d?source=collection_archive---------33-----------------------
最近的 ML 论文每月精选:MLPs 回归,无令牌语言模型,视觉变形金刚上的 SSL 等等。

图片作者。
在过去的一个月里,ML 研究文献带来了令人惊讶的结果,例如 MLPs 作为计算机视觉的竞争性架构的复兴,或者对批处理规范化作为一种完全无害的层的质疑。变形金刚也(当然)在盘子上:用于视觉上的自我监督学习,以及句子表示技术和字符级语言建模。
这是每月一次的最新 ML 研究文献精选,由 Zeta Alpha 支持,我们总是密切关注最新的论文。尽情享受吧!
MLP 混合器:一个全 MLP 架构的愿景👾代号
作者:伊利亚·托尔斯泰欣、尼尔·霍尔斯比、亚历山大·科列斯尼科夫、卢卡斯·拜尔等人
❓Why → 非常简单的基于 MLP 的架构突然比它们应该的工作得更好,这具有有趣的含义,并推进了我们关于深度学习工作原理的知识。
💡关键见解→ 你或许可以通过扩大规模来解决 ML 问题。好吧,好吧,这是一个过于简化和夸张的说法,但是里奇·萨顿的惨痛教训似乎比好酒更容易陈酿。
本文构建了一个既不使用注意力也不使用 CNN 的架构,其工作方式如下:
- 将图像分割成小块,展平成矢量并叠加。
- 转置堆栈,并对所有面片的每个要素应用 2 层 MLP。
- 转置回原始形状,并在每个面片的所有要素上应用 2 层 MLP。
- 重复前面的块 N 次。
结果并不十分 SOTA,但足以引起一些眉毛和引发讨论。虽然 CNN 目前还没有走向任何地方,但这加强了一个想法,即架构选择不是引入所需归纳偏差(如平移不变性/等方差)的必要条件,这些可以通过增强等技术仅从数据中学习,尽管效率较低。
非常有趣的是,就在这篇论文被上传到 arXiv 之后,其他几篇显示非常相似结果的文章也被上传,如注意 MLPs, RepMLP:将卷积重新参数化为完全连接的图像识别层, ResMLP:具有数据高效训练的图像分类前馈网络和你甚至需要注意吗?一堆前馈层在 ImageNet ⁴.上表现惊人的好

来源:https://arxiv.org/pdf/2105.01601.pdf
字节 5:通过预先训练的字节到字节模型走向无令牌的未来👾代码
作者薛阿迪蒂亚·巴鲁阿、诺亚·恒、拉米·阿尔-Rfou 等人
❓Why → 大多数 NLP 语言模型(LM)都是在几万个标记的固定词汇或子词单元上操作的。虽然这种方法在大多数时候都很有效,但它仍然会遇到诸如打字错误、大写变化或形态变化等问题。无令牌 LMs 是解决这些问题的一个很有前途的方向。
💡关键见解→ 本文的主要目标是展示如何在不牺牲性能的情况下,通过最少的修改,使现有的基于令牌的语言模型(mT5⁹)适用于字符或字节级操作。事实上,作者几乎没有改变主干 T5 架构:他们只是简单地去掉了原来的句子片段标记器,并把文本作为 UTF 8 字符的原始序列,这相当于 256 的“词汇表”大小。训练前的目标-最初屏蔽大约 3 个标记的范围并预测它们-被调整为大约 20 个字符的平均屏蔽范围长度。最后,作者还发现,byT5 受益于编码器和解码器之间的不均匀参数分布:与常规 T5 不同,以较轻的解码器为代价获得“沉重”的编码器是有益的。

来源:https://arxiv.org/pdf/2105.13626.pdf
这篇文章最令人惊讶的方面是,byT5 几乎不需要任何调整就可以达到与其原始版本相当的性能。此外,byT5 具有几个优点,例如对噪声的鲁棒性更强,并且在拼写和发音很重要的任务中表现更好。这为现有的转换器适应字节级序列输入描绘了一个充满希望的未来,尽管有许多警告适用:训练和推理效率仍然明显较差。
自监督视觉变压器的新兴特性 (DINO)👾代号
作者玛蒂尔德·卡隆等人
❓Why → 成熟的自我监督视觉变形金刚是迟早的事,现在它们来了。虽然这只是 vision transformers 和 SSL 的第一步,但这项技术将在接下来的几个月里变得更加实用。
💡关键洞察力→ 视觉变形器可以使用 Bootstrap Your Own Latent 方法训练,其中图像的不同视图由教师和学生编码,输出的相似性最大化。该方法通过使一个网络是另一个网络的指数平均值来避免崩溃(即,对所有图像输出相同的嵌入)。
然而,与 BYOL 不同的是,他们在模拟分类器上使用交叉熵作为输出之间的相似性度量,而不是内积相似性,这允许他们在 softmax 中设置“温度”正则化,这有助于训练稳定性。
这种方法最引人注目的结果是,在没有任何监督的情况下,transformer 中深层的注意力图形成了令人惊讶的高性能对象分割,并且对学习表示的 k-NN 检索也显示了将该技术应用于图像检索的有希望的结果。

资料来源:https://arxiv.org/pdf/2104.14294.pdf
你可能也会喜欢 : 用 Swin 变形金刚进行自我监督学习
简单的句子嵌入对比学习👾代码
由王彤宙和菲利普·伊索拉创作
❓Why → 在无监督的句子表征学习上取得了令人印象深刻的进步,这是一种非常简单的方法,有可能用于其他领域。
💡关键见解→ 在计算机视觉中,生成输入的两个视图就像获取图像的两种不同作物一样简单,但由于语言的离散性,这种简单的增强不能直接应用于语言,这使得对比学习有点棘手。
在这项工作中,作者建议简单地将同一个句子输入到 transformer encode 两次,但在前馈层和注意力层中绘制不同的随机丢失。令人惊讶的是——至少对我来说——添加任何其他以前使用过的增强功能,如“删除一个单词”或“裁剪句子的一部分”,都会降低性能。类似地,添加以前研究过的目标,如“下一句预测”,也会降低性能。
虽然最令人印象深刻的结果是针对仅无监督的训练,但作者也扩展了他们的方法,通过使用正面和负面句子对分别作为正面和硬负面样本来利用标记的数据。
结果不仅包括标准的句子级基准,如 STS⁵,还包括对表征的对齐和一致性的分析,最近被提议作为表征 quality⁵.的预测代理

来源:https://arxiv.org/pdf/2104.08821.pdf
蛋白质序列到结构的学习:这是终点(-端到端的革命)?
作者:埃洛蒂·莱恩、斯蒂芬·艾斯曼、阿恩·埃洛夫松和谢尔盖·格鲁丁宁
❓Why → 几个月前,DeepMind 的 AlphaFold 进行了一轮展示,展示了变形金刚和 SSL 如何跳过被称为蛋白质折叠的任务,蛋白质的 3D 结构仅由它们的线性氨基酸结构构建而成。我没有必要的背景来理解这到底有多有影响力,但这篇论文帮助奠定了事态的发展,并提供了关于蛋白质结构领域深度学习未来的知情意见。
💡关键见解→ AlphaFold 2 确实走在了时代的前面,这是 it 计算资源的一个重要原因,它越来越成为研究的一个区分因素。这再一次将学术研究团体置于一个困难的位置,与资金雄厚的公司支持的实验室竞争。
结构生物学精确预测的影响在很大程度上仍然是未知的。虽然蛋白质结构的确在很大程度上决定了它的性质,但还有更多变量在起作用。从乐观的方面来看,计算机模拟结构蛋白预测将会以比以前更快的数量级实现一致、深刻和新颖的生物学见解;但在悲观的一端,这些不足以成功地模拟更现实的蛋白质行为,如复杂的动力学,灵活性和相互作用,这种方法只会在少数情况下有用。

来源:https://arxiv.org/pdf/2105.07407.pdf
扩散模型在图像合成上击败甘斯👾代码
Prafulla Dhariwal 和 Alex Nichol
❓Why → GANs⁶自从引入以来,多年来一直是无可争议的图像生成方法。然而,在过去的几年里,越来越多的基于可能性的替代方法正在出现,以取代它们。他们会变得一样受欢迎吗?
💡关键见解→ 一个月前,我们在 ICLR 强调了一篇扩散模型论文,这篇论文的主旨大部分是相似的,尽管需要额外 8 个月的工作来完善。扩散模型的要点如下:你可以将图像转换成“噪声”作为“扩散过程”。想想单个水分子是如何在流动的水中运动的:有一些确定性的水流遵循一个梯度,并伴随着一些额外的随机抖动。你可以对像素图像做同样的事情,扩散它们,这样它们最终就像一个易于处理的概率分布中的噪声。现在,这个过程实际上是可逆的,所以同样的“反向”扩散过程可以用来从噪声中生成图像。
作者展示了一个良好调整的模型如何在许多图像生成基准上达到 SOTA,超越甘斯。然而,仍然有警告。

来源:https://arxiv.org/pdf/2105.05233.pdf
有一些权衡仍然是不可避免的:GANs 仍然是图像生成任务中最受欢迎的技术,并且速度很快,但它们通常缺乏多样性,并且没有覆盖图像的整个领域,这使得它们更难扩展和应用到新的领域。另一方面,基于可能性的模型——如 VQ-VAE、扩散模型或自回归生成——以速度和图像保真度为代价提供了更好的覆盖范围,由人类(或其他代理指标)来判断。
重新思考 BatchNorm 中的“批处理”
吴雨欣和贾斯廷·约翰逊
❓Why → 自从 batchnorm⁷被提出以来,它已经成为 DL 工具箱中无处不在的工具。然而,它具有不可忽视的含义,而这些含义往往被经验驱动的研究所忽视。
💡关键见解→ 这里有很多东西需要解开,但我要强调的是,BatchNorm 并不像乍看上去那样无害。
首先,BatchNorm 是唯一一个对组而不是对单个输入进行操作的层,这意味着它在训练和推理过程中必然会有不同的行为。而且,BatchNorm 会导致批内信息泄露。该论文给出了以下有见地的例子:设想通过具有 16 个不同类别的 32 个图像,每个类别 2 个图像,一致地构造训练批;该模型将通过至少“成对地”而不是单独地为每个样本生成标签来学习利用这种批量模式。在对比 learning⁸.中可以观察到类似的“欺骗”现象
训练-测试的不一致性也无意中损害了用 BatchNorm 训练的模型的性能:指数移动平均(EMA)技术——最常用于估计用于推断的总体统计数据——导致有偏差的估计,损害了测试集中的性能。
那么我们能从这一切中得到什么呢?您可能应该继续使用 BatchNorm,并受益于它在最常见的设置下的良好工作(从训练集中提取固定大小的批处理 i.i.d ),并使用从同一数据分布中提取的测试集);但在其他情况下使用时要格外小心。

来源:https://arxiv.org/pdf/2105.07576.pdf
我们的月度评选到此结束;如果你想了解最新的研究,请在 Twitter 上关注我们。如果你想了解更多关于 ML 代码、实现和库的最新进展,请查看我们的其他博客系列 最佳 ML 工具和软件 。下集再见!
参考文献:
[1] 关注 MLPs——作者,戴子航,David R. So,Quoc V. Le,2021。
[2] RepMLP:将卷积重新参数化为全连通层,用于图像识别——丁小寒,,韩,丁桂光,2021 .
[3] ResMLP:数据高效训练的图像分类前馈网络 — Hugo Touvron 等 2021。
【4】你甚至需要关注吗?一堆前馈层在 ImageNet——Luke Melas-Kyriazi,2021。
[5] 通过超球面上的对齐和一致理解对比表征学习——王彤宙和菲利普·伊索拉,2020。
[6] 生成对抗网络——作者 Ian J. Goodfellow 等人 2014。
[7] 批量归一化:通过减少内部协变量移位加速深度网络训练——作者谢尔盖·约夫,克里斯蒂安·塞格迪
[8] 采用对比预测编码的数据高效图像识别 — 作者 Oliver Henaff,2020。
[9]【mT5:一个大规模的多语种预训练文本到文本转换器——由薛、诺亚康斯坦、等人 2020。
arXiv 精选——2021 年 4 月阅读:GPT 反击战,视频变形金刚等等
原文:https://towardsdatascience.com/best-of-arxiv-readings-for-april-2021-gpt-strikes-back-video-transformers-and-more-d620e1cec82?source=collection_archive---------15-----------------------
ML 论文每月精选

图片作者。
在你的阅读清单上保持领先是很难的,而找到哪些论文应该在清单上就更难了。在 Zeta Alpha 我们总是密切关注最新的人工智能研究,所以我们每月都会分享一些最近的论文,以展示我们认为会有影响力的出版物,主要基于每部作品的贡献和作者的影响力。不要把这个列表看得太全面:像其他人一样,我们也有自己的偏见,但是你能从 4000 多篇论文中选择的就这么多了。尽情享受吧!
1。所有 NLP 任务都是生成任务:一个通用的预训练框架 |👾代号
作者:杜,钱玉洁,小刘,,,邱,,杨,。
🎖Why → 本文是现有的三种主要语言预训练方法的地图:自回归(例如,擅长文本生成的 GPTs),掩蔽语言建模(又称填空,如 BERT,擅长 NLU 分类任务)和 seq2seq(针对 T5 等编码器-解码器模型,擅长翻译或摘要等条件文本生成)。这三种技术各有优缺点,所以如果我们能得到最好的结果,那不是很好吗?这里有一个尝试。
💡关键见解→ 下表总结了三种主要语言预处理方法的主要用途。提醒一下,NLU 是基准测试中的分类任务,比如 SuperGLUE (情感分析,自然语言推理等。),条件生成是文本生成任务,其中输入和输出序列之间存在特定的关系(如翻译或总结文本),而无条件生成是自由生成文本的任务。

其中\003; =擅长;—=可以适应;✕=cannot 被直接应用到。资料来源:https://arxiv.org/pdf/2103.10360.pdf
作者提出了一种统一的预训练技术,他们称之为通用语言模型(GLM),并在图描述中进行了精确总结。

来源:https://arxiv.org/pdf/2103.10360.pdf
部分 A 和 B 的这种分离背后的动机是迫使同一模型学习双向编码器(A)和单向解码器(B)。以前基于跨度的模型(如 spanBERT)之间的一个区别是,跨度的长度现在对模型来说是未知的。这项技术需要一些技巧和细节来解决,比如位置编码,这在本文中有详细说明。
说到结果,与 RoBERTA 的比较可能是最有趣的比较之一,其中采用这种新的预训练方法的相同模型优于原始实现。在某些情况下,把最初的 MLM 训练目标和 GLM 混合起来更好,这表明 GLM 并不是普遍优越的。对于 seq2seq 评估,他们执行抽象概括,与类似大小的模型相比,它表现良好。
2。GPT 也明白了👾代号
【作者:】刘潇、延安郑、杜、、钱玉洁、杨、。
🎖Why → 我可以自信地把这篇文章放在我过去一个月的首要任务中。这个想法既聪明又简单,结果看起来非常惊人,论文非常清晰,充满了真知灼见。它挑战了来自同一个研究小组的前一篇论文提出的一个既定事实:自回归预训练对 NLU 没有好处。好吧,拿着你的纸!继续阅读……他们提出的技术 p-tuning ,有可能成为少量学习和微调大型 LMs 的标准技术,对于这些技术,传统的微调效果不是很好,或者成本太高。
💡关键见解→2020 年 5 月,GPT-3 让最持怀疑态度的人感到惊讶,它展示了一个简单的生成性预训练如何扩展到数千亿个参数,只需通过用描述任务的自然语言和/或给它一些例子来“提示”模型,就可以显示出令人印象深刻的零击球和少击球性能。这激发了一些深入探究“提示”艺术的作品,如 PET⁴.甚至有人提出了自动为模型寻找好的提示来解决任务的技术,而不需要像 AutoPrompt 那样更新任何模型参数。
在这项工作中,作者有一个绝妙的想法,不再将提示限制为固定词汇表中的实际单词。相反,他们学习固定数量的连续嵌入,可以通过梯度下降进行优化,他们称之为 p-tuning 。这意味着所有的原始模型参数可以保持冻结,只有提示嵌入被更新。把这想象成某种差异化编程 2.0 很有趣,在这里你学会解释一个冻结的预训练模型做什么。

来源:https://arxiv.org/pdf/2103.10385.pdf
在微调、p-tuning 和手动提示之间的比较中,结果是最有趣的。特别是对于知识探测(从一个冻结的预训练模型中提取仿真陈述),p-tuning 比其他方法表现得好得多。在 SuperGLUE 基准测试中,虽然 p-tuning 不能与其他 SOTA 相提并论(但考虑到那里巨大的模型大小差异,这不是一个公平的比较),但与标准微调或手动提示相比,p-tuning 显示出非常强的性能。


来源:https://arxiv.org/pdf/2103.10385.pdf
3。作为通用计算引擎的预训练变压器 |👾代号 | ✍️ 博客
凯文·卢、阿迪蒂亚·格罗弗、彼得·阿贝耳和伊戈尔·莫达奇。
🎖Why → 尽管在我看来,这篇论文的核心主张仍未确定(细节决定成败),但将预先训练好的变形金刚理解为“计算引擎”的想法很有意思——给出适当的指令,它可以计算出任何东西。在我看来,这与“GPT 也理解”的论文有很好的联系,在这篇论文中,学习了任务的模型输入,而不是模型参数。
💡关键见解→ 作者探索了变形金刚如何执行各种不同寻常的任务,特别是计算任务:位存储(重复损坏的位串)、位异或(计算两个位串的元素异或,这是 NNs 历史上很难执行的事情)、ListOps(给定一系列预测结果位的操作)、MNIST(手写数字数据集)和 CIFAR-10(图像分类基准)。
更有趣的是,他们声称有一些关于语言的预训练,使它学习所有这些其他任务的普遍性(这些任务事先与语言无关)。为了研究这一假设,他们获得了一个预训练的语言转换器,冻结了除层归一化和输入和位置嵌入之外的所有权重,称之为冻结预训练转换器(FPT)。

来源:https://arxiv.org/pdf/2103.05247.pdf
问题出在细节上,因为允许规范化层中的微调仍然会影响自我注意力在未来层中的行为,尽管自我注意力被冻结,但这种微调还是会隐式地优化它们(参见表 11 中它对性能的影响)。此外,通过微调嵌入、输出和层范数参数,随机初始化的转换器已经在许多任务上表现得非常好。
无论如何,尽管论文关于变压器是通用计算引擎的核心主张仍有争议,但论文充满了消融研究——如下表所示——这些研究很新颖,并提供了深刻的结果,以了解它们擅长什么,不擅长什么。

来源:https://arxiv.org/pdf/2103.05247.pdf
4。生成具有稀疏表示的图像
作者:查理·纳什、雅各布·梅尼克、桑德·迪勒曼和彼得·w·巴塔格利亚
🎖Why → 提醒您,用于压缩的离散余弦变换(DCT)图像处理等经典众所周知的技术可以增强图像生成等 ML 任务。
💡关键见解→ 部分受最近基于可能性的图像生成模型(如 OpenAI 或 VQ-VAE⁶的达尔·e⁵)的成功启发,本文探索了稀疏表示在任务中的应用。与 GANs 相比,基于似然性的生成模型的优点之一是,它们训练起来更稳定,并且也没有陷入没有覆盖图像分布的整个空间的模式的风险。使用稀疏表示的动机是它们易于压缩(有很多 0!),研究神经网络在这种表示空间中的表现非常有趣,与常见的图像网格结构形成对比。
我个人不知道 JPEG 压缩中使用的 DCT 变换,它真的很酷。以手动方式,您可以将图像分割成几个像素(即 8×8)的块,然后将所有像素值拟合到 2D 中基于余弦的函数中,8×8 = 64 个自由度。这将图像块表示为由 64 个系数加权的 64 个“频率”函数的叠加。这些系数中的大部分可以在不影响感知图像质量的情况下被移除(我们人类不会看到很多小的高频信息),这导致了易于压缩的稀疏表示(这就是为什么它被用于 JPEG 文件压缩)。看完这段精彩的 DCT 介绍视频后,这篇论文会更有意义。
本文构建的图像表示由一个来自这个 DCT 变换的所有非零稀疏系数的列表(经过一些特殊的量化技巧,但您可以得到它的要点)以及它们的通道和位置信息组成。该模型被训练为自回归预测这些元组,考虑它们的值分类,以自我监督的方式最大化可能性。

来源:https://arxiv.org/pdf/2103.03841.pdf
就结果而言,它们总体来说非常好;即使没有超过 SOTA,也可以与之相提并论(除了在比根仍然统治的阶级条件下)。然而,让我们不要忘记,这些指标只是人类判断质量的代理,所以用你自己的眼睛检查结果!

来源:https://arxiv.org/pdf/2103.03841.pdf
5。ViViT:视频视觉转换器
作者:阿努拉格·阿纳、穆斯塔法·德赫加尼、格奥尔格·海戈尔德、孙辰、马里奥·卢奇奇和科迪莉亚·施密德。
🎖Why → 变形金刚征服的又一个任务(这可能是一个独立的部分)。给定足够的参数和数据(以及适当的扩充),似乎没有变压器不能破解的任务。
💡关键见解→ 本文基于现有的视觉转换器(ViT ),例如“一幅图像相当于 16x16 words"⁷”,并尝试使用不同的策略来同时表示空间和时间维度。这项工作最有趣的一个方面是概述不同的策略来标记视频并对它们应用变形层。首先,在对视频进行标记时,他们解释了统一帧采样与小管嵌入,见下图。

来源:https://arxiv.org/pdf/2103.15691.pdf
其次,在计算跨空间和时间的注意力时,他们提出了 4 种替代方案:时空注意力(一切关注一切)、因式分解的编码器(首先仅空间变换器,然后时间)、因式分解的自我注意力(每个变换器块具有空间然后时间的自我注意力块)、因式分解的点积注意力(一个具有空间头部和时间头部的自我注意力随后被连接)。
他们的消融显示,如果训练良好,4 种不同的模型并没有那么不同,并且在图像数据集上利用预先训练的变压器很有帮助。事实上,他们并没有真正详细地披露他们是如何预先训练他们的模型的,只是说他们是在 ImageNet 或 JFT 数据集上进行的。他们在多个视频分类基准测试中取得了一流的性能,包括 Kinetics 400 和 600、Epic Kitchens、Something-Something v2 和 Moments in Time。标签平滑、混合和随机深度等增强和技巧仍然是实现这一性能的关键,正如它们的消融所示。
6。感知者:具有重复注意的一般感知
安德鲁·耶格尔、菲利克斯·吉梅诺、安德鲁·布洛克、安德鲁·塞斯曼、奥里奥尔·维尼亚尔斯和若昂·卡雷拉。
🎖Why → 对数据进行尽可能少的假设是有趣的,因为它有潜力很好地转移到许多领域。在这种情况下,感知者是一个关注可伸缩性(消除自我关注的讨厌的 N 次方),并对数据结构做最小假设的架构。
💡关键见解→ 感知者架构包括重复以下架构模块,包括:
- 潜在表示(大小为 NxD,长度为嵌入大小)和数据的原始表示(大小为 MxC,长度为通道)之间的交叉关注步骤。这使得交叉注意力具有 NxM 而不是 MxM 的复杂度,这在 N<
- A transformer layer that maps a latent representation to another latent representation of the same shape (see figure below).

Source: https://arxiv.org/pdf/2103.03206.pdf时是相当大的
这可以被认为是将原始表示重复缩小为潜在表示。假设在该实现中,块共享它们的权重,则可以认为是展开的 RNN。实际上,在附录中我们可以看到重量共享和非重量共享之间的比较,其中前者达到更好的性能,因为它不像非重量共享那样过度拟合;这种重量分担导致 44M 参数模型。
作者对各种形式进行了实验:图像、原始音频、视频、原始音频+视频和点云。虽然结果部分不是很全面,但性能与现有模型相当或更好,特别是与现有的多模态模型相比(例如,ImageNet top-1 上的 85.7%)。结果令人印象深刻,但我们不能忘记细节:虽然架构对所有模态保持相同,但需要一些模态特定的扩展和位置嵌入来实现它(裁剪、特殊位置编码等)。)

顶级 ImageNet 性能。红色的方法利用了特定领域的“图像网格结构”,而蓝色的结果则没有。来源:【https://arxiv.org/pdf/2103.03206.pdf】T4
7。注意力并不是你所需要的全部:纯粹的注意力会随着深度成倍地下降👾代码
作者董一禾、让·巴普蒂斯特·科多尼尔和安德烈亚斯·卢卡斯。
🎖Why → 偶尔一篇理论论文不会要了我们的命,有时它们会提供有价值的见解,而不仅仅是到处都是可怕的核心数学。这就是一个这样的例子:为什么这些跳跃连接如此重要?
💡关键见解→ 感谢上帝,我们有这些跳过连接。注意和跳过连接是你需要的全部*。
好吧,让我们扩展一下,你可能听说过跳过连接(或残差)有助于通过更深的网络传播梯度稳定训练。这篇论文提供了一个理论基础,解释了为什么这在变形金刚中如此重要:没有变形金刚,自我注意力输出可以证明会非常快速地退化——通过 SGD成双指数级——,这意味着它会变成一个秩 1 矩阵,其中会杀死流经它的信息(即,想象一个嵌入序列,其中所有嵌入都是彼此的倍数)。
这篇论文的主要观点与其说是惊人的见解,不如说是对现有怀疑的确认。一些工作已经根据经验展示了如何将注意力矩阵分解成对性能影响最小的低秩矩阵,例如“Linformer"⁸.”
8。可变速率离散表示学习 |⏯演示
作者:桑德·迪勒曼、查理·纳什、杰西·恩格尔和卡伦·西蒙扬。
🎖Why → 可变利率表示法的想法令我着迷。直觉上,听和理解口语,信息并不是均匀分布的,我们的表征又何必如此呢?这提出了许多挑战,但很高兴看到研究解决了这个问题。
💡关键见解→ 这项工作构建了基于事件的表示,涉及随时间量化的编码器解码器架构,经过训练后,解码器输出的对数似然性最大化,以适应量化的潜在表示。“慢度惩罚”激励潜在表示保持与前一时间步相同的值;这种惩罚是由明确强加容量瓶颈的想法所激发的。他们使用的另一个技巧是施密特触发量化:由于噪声,量化值可能会跳跃太多,因此 STQ 会施加一个记忆量化,只有当变量变化超过一定量时才会跳跃。
给定这种设置,直觉是量子化的潜在表示应该只在有事件时改变。例如,如果有 2 秒钟的沉默,表征可能会保持不变,但如果有人在说话,平均事件发生率(AER,潜在表征的变化)应该会更高。将编码器和解码器参数化的神经网络是一个“鼓形变压器”,要完成这项工作,还需要本文中详述的更多技巧。
关于结果,最有趣的部分是关于所有超参数的烧蚀,如慢度、AER、量子化水平等。与现有工作的比较不像人们所希望的那样广泛,但这主要是因为口语建模的自动评估不是非常可靠。

来源:https://arxiv.org/pdf/2103.06089.pdf
9。巴洛双胞胎:通过减少冗余进行自我监督学习 |👾代号
作者:Jure Zbontar、李静、Ishan Misra、Yann LeCun 和 Stéphane Deny。
🎖Why → 这是一个新的自我监督的损失!它非常简单,可与其他 SOTA 表示学习技术(SimCLR,BYOL)相媲美,并呈现了一些有趣的特性,值得进一步研究…
💡关键见解→ 我喜欢将它概念化的方式是在“每个特征”的基础上进行某种对比学习(但是不要做太多的类比,因为这是不正确的)。您有一个图像的两个视图(假设两个作物),您最大化每个特征的相关性,同时最小化其余特征之间的相关性。您也可以将此视为计算两个表示的外积(估计两个表示的互相关),对整个批次求和并归一化,并使其尽可能接近一个单位矩阵。


巴洛双胞胎损失函数。
这一目标的理论依据可以追溯到 1961⁹的神经科学家 H. Barlow,他假设处理感官信息的目标是将其重新编码为阶乘代码,这意味着具有令人满意的独立成分的表示。巴洛孪晶损失函数受这一想法的启发,因为它鼓励表示只与每个分量相关,而不是全局相关。
其结果可与现有的表示学习技术相媲美,如 BYOL 和 SimCLR,但它有几个有趣的特性。首先,与 BYOL 不同,它对较小的批量(小= 256,512)似乎很稳健;对于大批量(2048,4096),它实际上会降级!我们就此询问了作者,他们告诉我们他们也很困惑。第二,表示维度似乎没有饱和,与比较的方法不同,它不断改进下游性能。

来源:https://arxiv.org/pdf/2103.03230.pdf
10。如何在神经网络中表示部分-整体层次
杰弗里·辛顿。
🎖Why → 深度学习的创始人之一押注于计算机视觉的关键挑战是什么以及如何解决这些挑战。但是没有提供一个工作系统。(还没?).
💡关键见解→ 论文提出的第一点是,人类将视觉场景解析为部分-整体层次,并在元素之间建立视点不变的空间关系。换句话说,我们将图像的一部分表示为一个层次结构,即什么东西属于什么东西(或者对象的子部分等等),并且这些是视点不变的(我们将铅笔和纸建模为当我们四处移动时仍然是相同的)。这项工作似乎是他的胶囊网络⁰想法的自然延伸,也试图捕捉不同层次的表现。
根据 Hinton 的说法,这里的主要问题是,当前的端到端神经网络不允许我们动态构建这些解析树,并动态分配神经元组来表示其中的节点。他设想的解决方案——GLOM——最好理解为处理一系列图像(或视频)。它由代表不同层次视觉结构的向量列迭代表示图像的块组成(即每个块约 5 个向量)。在每个时间步,这些列以不同的贡献进行更新:自下而上的预测(L-1 到 L),自上而下的预测(L+1 到 L),相同级别的预测,以及补丁邻域中嵌入的注意力加权平均。理想情况下,对其进行训练将在不同级别产生相同向量的岛,对应于表示其部分-整体层次的图像的解析树。**

来源:https://arxiv.org/pdf/2102.12627.pdf
论文继续用生物学、数学和神经网络的观点来推动这一点;以及描述关于该系统如何以及为什么工作的许多考虑,这些考虑太长了,无法在此进行总结。
最后,尽管这篇文章没有描述一个工作系统,但是有些人已经实现了它,所以来看看吧!
我们的每月精选到此结束;如果你想了解最新的研究,请在 Twitter 上关注我们。我已经在期待着分享五月的下一个选择;回头见!
参考文献
[1] " SuperGLUE:通用语言理解系统的更具粘性的基准"作者 A. Wang,Y. Pruksachatkun,N. Nangia,A. Singh 等人 2019。
[2] " SpanBERT:通过表示和预测跨度来改善预训练" Mandar Joshi,Chen 等人 2019。
[3]“RoBERTa:稳健优化的 BERT 预训练方法”,作者刘,Myle Ott,Naman Goyal,杜等,2019。
[4]“重要的不仅仅是规模:小型语言模型也是很少尝试的学习者”Timo Schick 著,Hinrich Schütze,2020 年。
[5]“零镜头文本到图像生成”作者 Aditya Ramesh、Mikhail Pavlov、Gabriel Goh、Scott Gray、Chelsea Voss、Alec 拉德福德、陈唐山和 Ilya Sutskever 等人,2021。
[6] " 神经离散表征学习" Aaron van den Oord,Oriol Vinyals,Koray Kavukcuoglu 等人 2017。
[7]《一幅图像抵得上 16x16 个字:大规模图像识别的变形金刚》阿列克谢·多索维茨基、卢卡斯·拜尔、亚历山大·科列斯尼科夫、德克·韦森博恩、翟晓华等人 2020。
[8]“林前者:线性复杂性的自我注意”,作者:王思农、李贝琳达、马迪安·卡巴萨、和,2020。
[9] " 感官信息转换的潜在原则" Horace Barlow,1961。
[10] " 胶囊间的动态路由" Sara Sabour,Nicholas Frosst,和 Geoffrey E. Hinton,2017。
[11]“自动提示:通过自动生成的提示从语言模型中获取知识”T19,作者:Taylor Shin,Yasaman Razeghi,Robert L. Logan IV,Eric Wallace 和 Sameer Singh,2020 年。
arXiv 精选—2021 年 7 月阅读
原文:https://towardsdatascience.com/best-of-arxiv-readings-for-july-2021-d09a192d7fd8?source=collection_archive---------15-----------------------
最近的 ML 论文每月精选:专家的回归,注意力可能没有那么特别,像变形金刚一样思考是什么感觉?

图片作者。
在你的阅读清单上保持领先是很难的,而找到哪些论文应该在清单上就更难了。在 Zeta Alpha 我们总是密切关注最新的人工智能研究,所以我们每月都会分享一些最近的论文,以展示我们认为会有影响力的出版物,主要基于每部作品的贡献和作者的影响力。不要把这个列表看得太全面:像其他人一样,我们也有自己的偏见,但是你能从 4000 多篇论文中选择的就这么多了。
这个月,我们将志愿者计算带到了最前沿,更多的变形金刚,专家的组合等等。尽情享受吧!
开放协作中的分布式深度学习 |👾代号
迈克尔·迪斯金、阿列克谢·布克蒂亚罗夫、马克斯·里亚宾等人
❓Why → 汽车几乎一生都在停放,同样,世界上很大一部分计算在大部分时间处于闲置状态。这篇论文展示了志愿者计算——不同团体自愿提供计算资源——如何成功地训练大型语言模型。
💡关键见解→ 志愿者计算(VC)是一种范式,其中各方通过为一种通用算法提供计算资源来进行合作(例如,人们在睡觉时让他们的个人计算机为其他人运行东西)。尽管前景看好,但风险投资并不是免费的午餐:要让它在实践中发挥作用,需要许多考虑因素和谨慎的设计决策,因为你可以从参与者那里假设很少:他们的互联网可能有不同的速度和延迟,硬件可能从移动芯片到高端多 GPU 节点。您希望能够使用一个异质的志愿者团队,为需求设置一个低标准,但是您也希望避免使用最小公分母来平衡所有资源。
本文出色地展示了现有的分布式计算范例,同时讨论了它们的主要权衡,例如节点通信与计算。基于这一分析,作者提出了 DeLOC,其中对等体独立且异步地对微批次执行训练步骤,存储网络一小部分的权重梯度,并以一定的频率聚合它们,以更新整个模型的状态。实际上,这相当于在非常大的批量上训练整个模型。节点进行通信以同步模型的全局状态的方式介于“参数服务器”和“全简化”模型之间(即,一个中心节点进行聚合,或者所有节点自己进行聚合)。所有这些超参数,比如多长时间一次以及哪些节点互相通信,都被巧妙优化,以最大化训练吞吐量。


来源:https://arxiv.org/pdf/2106.10207.pdf
实现是通过 Hivemind 完成的,这是一个专门从事志愿者计算的 PyTorch 库(下面将更深入地描述)。
利用专家的稀疏混合来缩放视觉
作者:卡洛斯·里克尔梅、琼·普伊格韦尔、巴兹尔·穆斯塔法等人
❓Why → 混合专家正在成为将模型扩展到惊人规模的首选技术:关键优势是增加模型参数的可能性,同时保持推理计算成本不变。
💡关键见解→ 简而言之,专家的混合是一个模型,其中输入在推理时被路由到不同的子模型:推理的计算成本将由使用的计算路径决定,而模型表达能力将由参数的总数决定;有点儿两全其美。
专家的混合先前已经表明对于语言模型转换器(例如开关转换器)和系统(例如 FastMoE)是有效的,但是还没有在这种规模上应用于图像。该模型几乎与原始 ViT 相同:将图像分成小块,线性投影到小块嵌入中,并作为序列通过转换器。然而,在这种情况下,常规 ViT 层与 MoE ViT 层交错,其中 MLP 前馈层由一组 k MLP 专家取代,在此之前有一个路由器,该路由器根据输入的值通过不同的专家发送每个图像补丁。专家和路由器都通过梯度下降进行训练,并精心设计损失函数,以激励训练中的各种专家,避免崩溃模式,例如只有一个活跃的专家。

来源:https://arxiv.org/pdf/2106.05974.pdf
也许 MoE 应用于大型神经网络的最令人惊讶的结果是,相对于原始 ViT,学习效率(即,将模型训练到特定性能所需的计算量)得到了显著提高。

来源:https://arxiv.org/pdf/2106.05974.pdf
最近的其他工作比较了计算机视觉的 CNN 和 Transformers:VOLO:视觉识别的 Vision outlook er及其在 GitHub 上的流行实现。
无注意力变压器
翟双飞等人
❓Why → 加入上个月基于 MLP 的 CV 架构的热潮,越来越多的证据表明注意力本身并没有多少特别之处。只要网络以某种方式模拟其输入的相互作用,在给定足够的参数和数据的情况下,梯度下降将恰好找到它的方式。
💡Key insights → 作者提出了一种简单的学习成对偏差 w 添加到关键字矩阵,而不是将注意力计算为查询和关键字矩阵之间的传统矩阵乘积,该偏差通过以下表达式形式的指数进行转换,其中 t 是序列元素,所有乘积都是元素式的,而不是点积。


当计算完整的注意力-自由-注意力时,计算成本并没有减少(只在内存空间中),在我看来,最有趣的一点是这样的事实:结果不是 SOTA,但它们足够高,足以引起一些人的注意。实验在图像(使用图像自回归建模)和文本(自回归语言建模)上进行,显示了该机制的通用性。

来源:https://arxiv.org/pdf/2105.14103.pdf
你可能还会喜欢… Charformer:通过基于梯度的子词标记化的快速字符变形器,它与上个月发布的字符级 T5 语言模型 byt⁵⁶有相似的精神。
重新审视表格数据的深度学习模型
尤里·戈里什尼、伊万·鲁巴切夫、瓦伦丁·赫鲁尔科夫和阿尔特姆·巴奔科。
❓Why → 表格数据可能是学术研究和行业应用之间利益差距最大的形式之一,学术研究如今很少受到关注,而行业应用则无处不在。也许是因为深度学习的最新和最棒的在这里做得不太好…?无论如何,这篇文章是我很久以来看到的最好的表格数据直接比较方法!
💡关键见解→ 梯度推进决策树(GBDTs)自 200 年⁴以来就已经存在,诸如 XGBoost ⁷等流行的实现被广泛使用是有充分理由的:深度学习方法仍然没有在稳健和全面方面胜过它。
这项工作提出了许多表格数据集和几种算法的详细数值结果,重要的是,没有对神经网络进行额外的优化和技巧;然而,它们开箱即用。在我看来,最有见地的一点是他们使用合成数据进行的实验。作者使用适应 GBDTs 风格决策规则或神经网络回归的试探法生成合成表格数据集。当混合到不同程度时,结果是一系列数据集,其中两种技术有望优于另一种。在下图中,最左侧是神经网络友好数据集的误差,最右侧是 GBDT 友好数据集的误差。正如预期的那样,ResNet 和 CatBoost 在两者之间表现出明显的权衡,但基于 Transformer 的分类器似乎是一个万事通,不精通。

来源:https://arxiv.org/pdf/2106.11959.pdf
另见:表格数据:深度学习不是你需要的全部。
像变形金刚一样思考
盖尔·维斯、约夫·戈德堡和埃兰·亚哈夫。
❓Why → 这篇论文与众不同,很有趣。用新的方式思考和谈论已知的东西对于发展新的想法是必不可少的,这是一个很好的例子。作为一个奖励,魔鬼在细节中,看起来注意力是图灵完全的 ⁸(有点像?).
💡关键见解→ 受限访问序列处理语言(RASP)是一种编程语言,能够自然地表达转换器执行的计算。要点如下,RASP 将转换器建模为处理长度为 n 的序列和大小为 n×n 的矩阵的任意算法。输入序列可以通过逐元素操作和/或通过选择和聚合元素来转换,这些元素的关系通过类注意力矩阵(聚合器)来建模。差不多就是这样,您可以通过只使用本文中显示的这些原语来解决许多任务,这些原语可以很好地映射到 Transformer 计算中,并且可以相互编译。

来源:https://arxiv.org/pdf/2106.06981.pdf
最有趣的见解之一是如何在 RASP 形式中表达受限注意力转换器(例如,高效转换器)(例如,通过在某些区域将聚合器矩阵设置为假)必然削弱其计算表达能力。作者在综合任务中展示了这一点,如排序,只有完全转换才能成功。
用于展示 RASP 及其预测和理解转换器如何执行计算的其他综合任务包括反转字符串、制作直方图、双直方图、按字母顺序排序、返回最频繁的令牌以及识别 Dick-k 语言。
高效深度学习:关于让深度学习模型更小、更快、更好的调查
作者高拉夫·蒙哈尼。
❓Why → 虽然没有任何新颖的贡献,但这是一篇从工程师角度出发的精彩介绍,涵盖了每个从业者都应该知道的高效数据挖掘的相关技术。
💡关键见解→DL 的效率有很多方面。也许最重要的区别在于学术研究花费最多资源的训练和大规模应用花费最多资源的推理;这项调查涵盖了这两种情况。
例如,这项工作向读者介绍了数据扩充、提炼或迁移学习等技术,这些技术对培训效率有着积极的影响。同时,其他解释的技术,如量化或剪枝,通常用于提高推理效率。
涵盖的其他主题包括超参数优化、高效架构和关于框架的基础设施考虑事项,如 PyTorch Mobile 或 TensorFlow Lite ,它们是生态系统的关键要素。调查中最有用的部分之一是在每一部分末尾推荐的经验法则和方法,它们有助于将每种技术与其用例联系起来。

来源:https://arxiv.org/pdf/2106.08962.pdf
调查可能是了解你不是专家的研究领域发生了什么的最好方法。以下是其他最近的调查,作为进入这些领域的一个极好的切入点:自然语言处理的图形神经网络:一项调查、一项关于变形金刚的调查、一项关于在低资源情况下自然语言处理的最近方法的调查
我们的月度评选到此结束;如果你想了解最新的研究,请关注我们的 Twitter @zetavector 。下集再见!
参考文献
[1] 开关变压器:以简单有效的稀疏性缩放至万亿参数模型——William Fedus、Barret Zoph 和 Noam Shazeer,2021。
[2] FastMoE:一种快速的专家混合训练系统 —何家傲等,2021。
[3] 一幅图像抵得上 16x16 个字:大规模图像识别的变形金刚——作者阿列克谢·多索维茨基、卢卡斯·拜尔、亚历山大·科列斯尼科夫、德克·韦森博恩、翟晓华等 2021。
[4] 贪婪函数逼近:一个梯度推进机—j . h . Friedman 著,2001。
[5] 从大型语言模型中提取训练数据—Nicholas Carlini 等人 2020。
[6] ByT5:用预先训练好的字节到字节模型走向无令牌的未来——作者:薛、阿迪蒂亚·巴鲁阿、诺亚·康斯坦特、拉米·阿尔-Rfou 等人 2021。
[7] XGBoost:一个可扩展的树提升系统 —陈天琦,Carlos Guestrin,2016。
[8] XCiT:互协方差图像变形器——Alaaeldin El-Nouby 等人 2021。
[9] 注意力是图灵——完成——豪尔赫·佩雷斯、巴勃罗·巴塞洛和哈维尔·马林科维奇,2021。
[10] 通过内容自适应多分辨率合并将单目深度估计模型提升到高分辨率 — 作者:S. Mahdi H. Miangoleh,Sebastian Dille,龙脉,Sylvain Paris 和 Ya yaz Aksoy,2021。
arXiv 精选—2021 年 3 月阅读
原文:https://towardsdatascience.com/best-of-arxiv-readings-for-march-2021-c707263b2778?source=collection_archive---------20-----------------------
ML 论文每月精选。

在你的阅读清单上保持领先是很难的,而找到哪些论文应该在清单上就更难了。在 Zeta Alpha 我们总是密切关注最新的人工智能研究,所以我们每月都会分享一些最近的论文,以展示我们认为会有影响力的出版物,主要基于每部作品的贡献和作者的影响力。不要把这个列表看得太全面:像其他人一样,我们也有自己的偏见,但是你能从 4000 多篇论文中选择的就这么多了。尽情享受吧!
TransGAN:两个变形金刚可以组成一个强大的 GAN 👾代号
由、畅&由王。
🎖Why → 变形金刚征服的又一个任务。事实上,我很惊讶地听说,以前没有人成功地建立了完全基于变压器的 GANs 但是它们很难做好,需要一些技巧,本文将对此进行探讨。主要作者江一帆告诉我们,⁴之前曾与甘斯广泛合作,这对我们帮助很大,因为魔鬼在细节中,很可能许多人在这次尝试之前已经尝试过,但没有成功。
💡关键见解→ GANs 向来以训练不稳定著称,TransGAN 更是如此。一个完全基于 Transformer 的 GAN 不能开箱即用,它需要一些技巧来使它的性能与它的成熟的 CNN 兄弟相当。
实现这一点的 3 个主要技巧是:
- 数据扩充是强大性能的关键(对于基于 CNN 的 GANs 来说,这一点并不突出)。
- 作为均方误差的辅助自监督重建损失。
- 在训练中动态增加注意感受野,从仅局部注意开始,逐渐增加到全局注意。这可能是最有争议的技巧,因为局部注意力是对像素邻域的线性操作,这与卷积核的操作非常接近。
这最后一点并没有使研究无效,但是证实了归纳偏差在 ML 中的重要性。此外,最新的结果令人印象深刻,需要在这个方向上进一步研究。

资料来源:https://arxiv.org/pdf/2102.07074.pdf

来源:https://arxiv.org/pdf/2102.07074.pdf
转移的标度律
来自 OpenAI 的 Danny Hernandez 等人
🎖Why → 迁移学习正变得越来越重要,因为自我监督的预训练和特定任务的微调是许多任务实现 SOTA 的主导范式。本文从 OpenAI 的大规模实验中得出经验法则,量化迁移对语言建模的帮助。
💡关键见解→ 传输的有效数据被定义为从头开始的模型需要匹配传输的模型性能的数据量。这种有效的数据传输遵循以下形式的幂定律:

其中 D_F 为微调数据大小,N 为模型参数个数。令人印象深刻的是,这个经验法则适用于从文本到 python 数据的转换实验,而不是从头开始训练;对于模型大小在 4 个数量级以内、目标数据集大小在 3 个数量级以内的语言建模任务。

有效数据、有效数据传输和微调数据集等关键概念的可视化解释。来源:https://arxiv.org/pdf/2102.01293.pdf
这篇论文仍然有许多局限性,例如,实验只关注英文文本和 python 代码之间的转换,但在模型和数据集不断增加的时代,比例定律将是相关的。最有趣的结果之一是,即使在微调数据集“很小”的情况下,根据文本预训练的模型也不会受到“数据约束”,这与从头开始训练不同(见下图)。

来源:https://arxiv.org/pdf/2102.01293.pdf
我们能自动化科学审查吗?(没有,但是……)|👾代码 | 🕹 演示
作者袁,&格雷厄姆纽比格。
🎖 为什么→ 这个挑衅性的标题背后隐藏着一项关于科学审查自动化的细致而严肃的研究。有趣的是,问这个问题的行为暗示了对当前复习状态的某种程度的怀疑…
💡关键见解→ 本文提出使用 NLP 模型为科学论文生成第一轮同行评审。作者收集了机器学习领域的论文数据集,用每篇评论中涵盖的内容的不同方面对它们进行注释,并训练有针对性的摘要模型,该模型接收论文以生成评论。他们进行了大量的实验,以表明系统生成的评论往往比人工撰写的评论触及更多的论文方面,但生成的文本在所有方面的建设性都较低,除了对核心观点的解释,这些观点在很大程度上是事实上正确的。(第一段完全是由本文介绍的系统生成的。)
该论文的结论是,评论生成在当前状态下不能取代人工评论者,但是作为一个辅助过程可能是有帮助的。为了证明这一立场,作者定义了一组可以在一定程度上客观衡量的定量研究人类评论的方面:
- 果断性—以推荐准确度(RAcc)衡量
- 全面性——用方面覆盖率(ACov)和方面召回率(ARec)来衡量
- 调整—以信息含量(Info)衡量,如
- 准确性——以汇总准确性(SAcc)衡量
生成的评论非常令人印象深刻,但它在关键的事实陈述中出现,因为这是文本生成模型经常出现的情况,这在科学评论环境中是不可接受的。数据集的收集和评估非常广泛和复杂,因此值得一试。这项工作提出了一个有趣的问题:如果自动审查模型比人好得多(如果可以正确定义的话),它应该被使用吗?古德哈特定律“当一个指标成为一个目标,不再是一个好的指标”会对它造成更严重的影响吗?

来源:https://arxiv.org/pdf/2102.00176.pdf
挖掘自己的观点:通过跨样本预测进行自我监督学习 |👾代码
迈赫迪·阿扎布等人
🎖Why → 这项工作令人惊讶,因为在硬负挖掘的背景下,人们经常使用最近邻嵌入,假设它们是需要在对比损失中“推开”的负样本。然而,这篇论文恰恰相反。这很有效。
💡重要见解→ 有趣的是,这篇论文来自神经科学背景,人们可以通过实验部分直观地感受到这一点。Mehdi aza bou——主要作者——告诉我们这个项目是如何通过尝试使用自我监督来解码神经脉冲数据开始的,结果非常好,他们决定将这项技术应用到图像上!这是相近田地间异花授粉的极好例子。
这项工作是 BYOL 的自然延伸,其中通过仅使用正样本进行对比学习来学习表示,并且将同一图像的增强表示一起推送到,并且通过使用两个编码器,一个在线编码器和一个平均编码器(其参数是在线编码器的移动指数平均值),该模型避免了崩溃。然而,在这种情况下,作者更进了一步;他们不是只使用图像的增强作为正样本,而是通过从嵌入空间中最近的邻居采样来挖掘不同的视图,并将这些视图视为图像的挖掘正视图。
这种方法如此有效的事实非常令人震惊,并且挑战了一些关于成功的表征学习的假设。它轻松实现了 MNIST、CIFAR-10 和 100 的最先进表现;它能够比以往任何时候都更好地代表神经记录,而且它肯定会激发类似方向的进一步工作。

来源:https://arxiv.org/pdf/2102.10106.pdf
零截图文本到图像生成 | ✍️ 博客 |👾代码
由 OpenAI 等人撰写
🎖Why → 大规模再印象,可以创建以字幕为条件的引人注目的图像生成 ala 语言建模,以自监督自回归模式训练。这项工作在文本到图像的生成方法上取得了进展,并且一定会产生影响。
💡关键见解→ 将图像的标题编码成标记,并将它们与表示图像的标记连接起来。表示图像的记号是对图像训练离散 VAE 的结果,该离散将图像表示为 32×32 记号的网格,其中该记号的词汇大小是 8192。您可以将这种表示方式想象成每幅图像是 8192 个词汇中的 32×32 = 1024 个单词。这个技巧大大减小了图像空间的大小,使其类似于语言符号,即字典中的离散符号。
该记号序列可以被大规模地自回归训练,这在推理时可以用图像的标题来提示,这将由具有图像记号的模型自回归完成,该图像记号又可以由 dVAE 解码到像素空间中。
像往常一样,制作这个大规模模型所需的工程是令人震惊的,结果是真正的赏心悦目。

来源:https://arxiv.org/pdf/2102.12092.pdf
走向因果表征学习
作者:b . schlkopf,F. Locatello,S. Bauer,N. Rosemary Ke,N. Kalchbrenner,A. Goyal & Y. Bengio。
🎖why→2021 年机器学习和因果关系的状态。虽然还不是最突出的,这一领域的研究有一个充满希望的潜力,以克服经典的 ML 限制分布外推广;最终放弃著名的 i.i.d .假设。
💡关键见解→ 本文可作为对 ML 因果关系感兴趣的从业者和研究人员的切入点。世界模型的一个有用和简单的分类被提出,其中每个类的能力被仔细考虑(见下表)。

资料来源:https://arxiv.org/pdf/2102.11107.pdf
不可能在一个段落中涵盖论文的全部内容,但它涉及的一些相关主题是 i.i.d .假设的脆弱性、观察数据和干预数据之间的差异、因果图模型和结构因果模型之间的差异(只有后者可以进行反事实推理)以及独立因果机制等基础原则。
最后,作者回顾了因果表征学习对半监督学习、对抗性脆弱性、鲁棒性和泛化、自我监督、数据扩充、强化学习、多任务学习和一般科学应用等方法的影响。

来源:https://arxiv.org/pdf/2102.11107.pdf
无需归一化的高性能大规模图像识别
作者:安德鲁·布洛克,索哈姆·德,塞缪尔·l·史密斯&卡伦·西蒙扬。
🎖Why → 分层和批量归一化已经成为深度学习工具集中的标准方法有一段时间了。本文通过展示大规模图像识别如何在没有任何标准化的情况下工作,对这种技术的重要性提出了挑战;仅使用渐变剪辑。
💡关键见解→ 通常,普通梯度裁剪将梯度向量的范数限制为固定的超参数λ。虽然这种技术可防止梯度爆炸,并允许在训练中进行更大批量,但该程序对超参数 lambda 的调整非常敏感。为了规避这个问题,作者提出了“自适应梯度裁剪”(AGC),它基于权重梯度和权重值之间的比率来裁剪梯度:

自适应渐变剪辑。资料来源:https://arxiv.org/pdf/2102.06171.pdf
抛弃规范化的最大吸引力之一是它的计算效率低下;将批量标准化转换为自动增益控制可以为同等大小的模型提供更快的训练。此外,如下所示,限幅超参数是稳健的,并且该技术允许训练中更大的批量。

(左)AGC 缩放至更大批量;(右)跨越限幅阈值的性能。
主要结果部分似乎只提供了与其他工作相比有利的精选案例,因此有必要进行进一步审查。尽管如此,在没有任何规范化的情况下训练端到端模型是使 DL 模型更有效的一个有希望的方向。
变压器中的位置信息:概述
菲利普·杜弗特、马丁·施密特、辛里奇·舒茨。
🎖 为什么→ 变形金刚中的编码顺序——它不会因自我关注的设计而改变——似乎总是一种事后想法,让我们面对现实吧,它们无处不在!这篇论文阐明了这个话题,并解释了所有的变化。然而,问题仍然是这在多大程度上是相关的…!
💡关键见解→ 变形金刚中位置信息的编码方式尚未统一,存在大量不同的研究想法。本文的作者提供了一个分类,可用于绘制这项研究的状态图(见下表)。

来源:https://arxiv.org/pdf/2102.11090.pdf
作者还提供了一个全面的理论框架来比较不同的方法:添加位置嵌入与修改注意屏蔽,顺序与基于图的排序,或对跨语言学习的影响。
虽然这篇论文没有向读者提供任何新颖的结果,但它是一个关于变形金刚动物园研究的的极好例子,因为变形金刚无处不在。这类研究的另一个最近的例子是"变压器的修改会在实现和应用之间转移吗?”,作者在其中探索了对核心变压器架构的大量小修改是否真的产生了有意义的差异(剧透:不尽然)。
PAQ:6500 万个可能被问到的问题以及你可以用它们做什么👾代码
帕特里克·刘易斯等人
🎖Why → 从语料库中自动生成问答方法的令人印象深刻的结果:如果你能想出所有可能的问题及其答案,你只需要记住它们!
💡关键见解→ 现有技术开放领域问题回答模型通常遵循两步检索器和读者方法,其中对于给定的问题,检索器检索问题答案可能所在的证据段落,读者通过联合处理问题和段落来提取答案。实际上,这意味着每个单个答案所需的计算量很高。
在这项工作中,作者提出了一种仅检索器的方法,该方法与检索器-读取器模型的性能相匹配,速度快几个数量级。这种方法在概念上很简单:从维基百科语料库中,找到看起来像答案的片段,并生成人类可能会问的与之匹配的问题。这导致了大规模的、自动生成的 6500 万个问答对,其在 TriviaQA 和自然问题上表现得很有竞争力,因为它已经有了许多答案。此外,问答检索器非常擅长确定答案的可信度,因此当问题看起来不像任何现有的 PAQ 时,适合添加一个后备的完整检索器-阅读器模型。

来源:https://arxiv.org/pdf/2102.07033.pdf
我们的每月精选到此结束;如果你想了解最新的研究,请在推特上关注我们 @zetavector 。我已经很期待分享四月份的下一个选择了;回头见!
参考文献
[1] 引导你自己的潜能:自我监督学习的新方法,作者 Jean-Bastien Grill 等人,2020 年。
[2]Transformer 的修改会在实现和应用之间转移吗?,由莎兰纳朗等人 2021。
[3] EnlightenGAN:无需配对监督的深度光线增强,江一帆等人 2019。
[4] AutoGAN:生成对抗网络的神经架构搜索,新宇龚等 2019。
