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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

潜在狄利克雷分配(LDA):主题发现的概率建模方法指南

原文:https://towardsdatascience.com/latent-dirichlet-allocation-lda-a-guide-to-probabilistic-modeling-approach-for-topic-discovery-8cb97c08da3c?source=collection_archive---------29-----------------------

潜在狄利克雷分配在 python 中的实现

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

来源

潜在狄利克雷分配(LDA)是主题建模中最常用的算法之一。LDA 由 J. K. Pritchard、M. Stephens 和 P. Donnelly 于 2000 年提出,并由 David M. Blei、Andrew Y. Ng 和 Michael I. Jordan 于 2003 年重新发现。在这篇文章中,我将试着给你一个什么是主题建模的概念。我们将学习 LDA 如何工作,最后,我们将尝试实现我们的 LDA 模型。

什么是主题建模?

主题建模是机器学习和自然语言处理中最有趣的领域之一。主题建模意味着从文档集合中提取抽象的“主题”。自然语言处理的主要应用之一是在大量的文本文档中了解人们在谈论什么。通读所有这些文档并提取或编辑主题真的很难。在这些情况下,主题建模用于提取文档信息。为了理解主题建模的概念,让我们看一个例子。

假设你正在读报纸上的一些文章,在这些文章中,“气候”这个词出现得最多。所以,从正常意义上来说,你可以说这些文章更有可能是关于气候的。主题建模以统计的方式做同样的事情。它通过聚集相似的单词来产生话题。这里有两个术语:一个是“主题建模”,另一个是“主题分类”。虽然它们看起来相似,但它们是完全不同的过程。第一种是非监督机器学习技术,第二种是监督技术。
让我们详细阐述一下这个概念。

主题分类通常涉及互斥的类别。这意味着每个文档都标有特定的类别。另一方面,主题建模并不相互排斥。同一份文件可能涉及许多主题。由于主题建模是基于概率分布工作的,所以同一文档可能具有跨越许多主题的概率分布。

对于主题建模,您可以使用几种现有的算法。非负矩阵分解(NMF)潜在语义分析或潜在语义索引(LSA 或 LSI)潜在狄利克雷分配(LDA) 是这些算法中的一些。在本文中,我们将讨论潜在的狄利克雷分配,这是主题建模中最常见的算法之一。

潜在狄利克雷分配(LDA)

"潜在狄利克雷分配(LDA)是一个生成统计模型,它允许观察集由未观察到的组来解释,这解释了为什么数据的某些部分是相似的。例如,如果观察是收集到文档中的单词,它假设每个文档都是少量主题的混合物,并且每个单词的出现都归因于文档的一个主题*。—维基百科*

好吧,让我们试着理解这个定义。

L atent Dirichlet 分配(LDA)的基本思想是,文档被认为是各种主题的随机混合,主题被认为是不同单词的混合。现在,假设你需要一些与动物有关的文章,你面前有成千上万的文章,但你真的不知道这些文章是关于什么的。看完所有这些文章,要找出与动物相关的文章,真的很繁琐。让我们看一个例子。

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

作为一个例子,让我们考虑我们有四篇文章。第 1 条涉及动物,第 2 条涉及遗传类型,第 3 条涉及计算机类型,第 4 条是动物和遗传类型的组合。作为一个人类,你可以很容易地根据它包含的单词来区分这些主题。但是如果有几千条,每条有几千行,你会怎么做?答案会是这样的——“如果我们能在计算机的帮助下做到这一点,那么我们应该这样做”。是的,借助于潜在的狄利克雷分配,计算机可以这样做。现在我们将试着理解 LDA 是如何工作的。首先,我们将看到 LDA 的图形表示,然后我们将看到概率计算公式。**

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

上图是 LDA 的图示。在上图中,我们可以看到有六个参数-

α(α)和η*(η)——代表狄利克雷分布。高 alpha 值表示每个文档包含大多数主题,相反,较低的 alpha 值表示文档可能包含较少数量的主题。与 alpha 相同,较高的η值表示主题可能覆盖大多数单词,相反,较低的 eta 值表示主题可能包含较少数量的单词。*

β(β)和θ*(θ)——代表多项式分布。*

z —代表一堆话题

w —代表一串单词

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

公式的左边表示文档的概率。在公式的右边,有四个术语。公式的第一项和第三项将帮助我们找到主题。第二个和第四个将帮助我们找到文章中的单词。公式右侧的前两项表示狄利克雷分布,右侧的其余部分是多项式分布。

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

我们假设,在上图中,左边的三角形中,蓝色的圆圈表示不同的文章。现在,如果我们将文章分布在不同的主题上,它将如直角三角形所示分布。蓝色圆圈将移动到三角形的角上,这取决于它在该主题中所占的百分比。这个过程是由公式右边的第一项完成的。现在,我们使用多项式分布根据第一个词的百分比生成主题。

现在,在得到主题后,我们会发现哪些单词与这些主题更相关。这是通过另一个狄利克雷分布来实现的。主题根据单词分布,如下所示。

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

现在,我们将使用另一个多项式分布来查找与这些主题更相关的单词,并使用该狄利克雷分布生成具有概率的单词。这个过程进行多次。

因此,我们将找到与主题更相关的词,并基于这些主题分发文章。

实施 LDA

你可以在 GitHub 中找到代码。要实现 LDA,您可以使用 gensim 或 sklearn。这里,我们将使用 gensim。

加载数据

为了实现的目的,我使用了 Kaggle 数据集。该数据集由 15 列 2150 个数据集信息组成:

*dataset = pd.read_csv('/content/drive/My Drive/topic modelling/voted-kaggle-dataset.csv')*

数据预处理

为了处理数据,首先,我们选择对这个过程有意义的列。然后删除包含任何缺失值的行。

*modified_dataset = modified_dataset.dropna()*

然后,我们将计算标签列中唯一标签的数量,因为我们会将此视为模型的主题数量。

*unique_tag = []
**for** i **in** range(len(tag_dataset)):
  tag_string = str(tag_dataset[i])
  **if** tag_string != "nan" :
    tag_word=convert(tag_string)
    **for** j **in** range(len(tag_word)):
      **if** tag_word[j] **not** **in** unique_tag:
        unique_tag.append(tag_word[j])
print(len(unique_tag))*

删除标点符号并转换小写的整个文本使训练任务更容易,并提高了模型的效率。

*remove_digits = str.maketrans('', '', string.digits)
exclude = '[!"#$%&**\'**()*+,-./:;<=>?@[**\\**]^_`{|}~]'
**for** column **in** ['Title','Subtitle','Description']:
  modified_dataset[column] = modified_dataset[column].map(**lambda** x : x.translate(remove_digits))
  modified_dataset[column] = modified_dataset[column].map(**lambda** x : re.sub(str(exclude), '', x))*

我们需要标记数据集并执行词干操作。

***import** **nltk**
nltk.download('punkt')
tokenized_dataframe =  modified_dataset.apply(**lambda** row: nltk.word_tokenize(row['Description']), axis=1)
print(type(tokenized_dataframe))**def** lemmatize_text(text):
    **return** [ps.stem(w)  **for** w **in** text **if** len(w)>5]ps = PorterStemmer() 
stemmed_dataset = tokenized_dataframe.apply(lemmatize_text)*

探索性数据分析

通过使用 WordCloud ,我们可以验证我们的预处理是否正确完成。单词云是由单词组合而成的图像,看起来像一个云状。它向我们展示了一个词在文本中出现的频率——它的频率。

***from** **wordcloud** **import** WordCloud
**import** **matplotlib.pyplot** **as** **plt**
*#dataset_words=''*
*#for column in ['Title','Subtitle','Description']:*
dataset_words=''.join(list(str(stemmed_dataset.values)))
print(type(dataset_words))
wordcloud = WordCloud(width = 800, height = 500, 
                background_color ='white',  
                min_font_size = 10).generate(dataset_words) 

plt.figure(figsize = (5, 5), facecolor = **None**) 
plt.imshow(wordcloud) 
plt.axis("off") 
plt.tight_layout(pad = 0) 

plt.show()*

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

建立模型

对于 LDA 模型,我们首先需要构建一个单词字典,其中每个单词都有一个唯一的 id。然后需要创建一个包含 word_frequency — ->(word_id,word_frequency)的单词 id 映射的语料库。

*dictionary_of_words = gensim.corpora.Dictionary(stemmed_dataset)word_corpus = [dictionary_of_words.doc2bow(word) **for** word **in** stemmed_dataset]*

最后,训练模型。

*lda_model = gensim.models.ldamodel.LdaModel(corpus=word_corpus,
                                                   id2word=dictionary_of_words,
num_topics=329, 
random_state=101,
update_every=1,
chunksize=300,
passes=50,
alpha='auto',
per_word_topics=**True**)*

连贯性衡量一个主题中单词之间的相对距离。

*coherence_val = CoherenceModel(model=lda_model, texts=stemmed_dataset, dictionary=dictionary_of_words, coherence='c_v').get_coherence()

print('Coherence Score: ', coherence_val)*

一致性值:0.4

估价

***for**  index,score **in** sorted(lda_model[word_corpus[2]][0], key=**lambda** tup: -1*tup[1]):
    print("**\n**Score: **{}\t** **\n**Topic: **{}**".format(score, lda_model.print_topic(index, 10)))*

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

顶部的主题获得了最高的概率,并且它与类似经济的东西相关。

你可以在 GITHUB 上找到所有代码。

参考文献:

  1. 潜伏的狄利克雷分配 作者大卫·m·布雷,安德鲁·y·Ng&迈克尔·乔丹。
  2. 潜伏的狄利克雷分配路易斯·塞拉诺。
  3. 潜在狄利克雷分配(算法)由 ML 论文讲解— A.I .苏格拉底圈— AISC。

最后,感谢您的阅读。感谢任何反馈。

潜在语义分析—从文档中推断出隐藏的主题

原文:https://towardsdatascience.com/latent-semantic-analysis-deduce-the-hidden-topic-from-the-document-f360e8c0614b?source=collection_archive---------4-----------------------

让计算机学习和理解人类语言仍然是最困难的任务。语言包含巨大的词汇,每部作品根据上下文有不同的含义,让计算机学习上下文是一个悬而未决的问题。在此,我们将尝试推导出文本所代表的隐藏主题,并将这些知识用于文档聚类。

主题模型

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

分析 vidhya —主题建模

主题模型是一种无监督的方式来推断隐藏的主题所代表的文本或文件。这个主题不是诸如体育、新闻或商业之类的实际主题,而是可以用来以最佳方式表示文本的词语。

这种技术非常强大,可以在无人监督的情况下用于文档聚类。如果你使用过谷歌新闻,那么你会看到不同来源的新闻聚集在一起,如果这些新闻代表相似的主题。这是主题建模的应用之一。

潜在语义分析

潜在语义分析是一种通过理解文本的上下文来分析文本和发现隐藏主题的有效方法。

潜在语义分析(LSA)用于发现由文档或文本表示的隐藏主题。这个隐藏的主题然后被用于将相似的文档聚集在一起。LSA 是一种无监督的算法,因此我们不知道文档的实际主题。

为什么是 LSA?

查找相似文档的最简单方法是使用文本的向量表示和余弦相似度。向量表示以向量的形式表示每个文档。这个向量被称为文档术语矩阵。

例如:

a1 = "the petrol in this car is low"
a2 = "the vehicle is short on fuel"

考虑以上两个字符串并形成上下文,我们可以理解这两个字符串是相似的。我们将尝试使用向量表示来找出这些字符串有多相似。

上述示例的文档术语矩阵为:

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

文档术语矩阵

文档-术语矩阵的大小是(文档数量)*(词汇大小)。词汇量是所有文档中出现的唯一单词的总数。这里的词汇量是 11,文档数是 2。

文档之间的相似性是使用文档之间的余弦相似性矩阵来找出的。文档a1a2之间的相似度是 0.3086067,这太低了,因为文档在上下文中大多相似。这是文档术语矩阵的缺点,因此也是向量表示技术的缺点。另一个缺点是词汇量大,因为该语言具有巨大的词汇量,导致矩阵更大且计算成本高。

向量表示法的这一缺点导致了寻找文档间相似性和隐藏主题的新技术的需求。该技术可以解决同义词的问题,并且计算上也不昂贵。建议的技术是潜在语义分析。

LSA 的工作

术语共现矩阵

这个矩阵的维数是(词汇大小)*(词汇大小)。它表示单词在数据集中出现的频率。矩阵帮助我们理解属于一起的单词。

对于上面的例子,术语共生矩阵是:

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

术语共现矩阵

正如我们所看到的,单词theis是最常见的,但在句子的意思中不是很有用。我们将在本博客的后面看到如何使用这个矩阵及其好处。

概念

LSA 返回代表给定文档的概念而不是主题。概念是以最佳方式表示文档的单词列表。

例如,在体育文档的数据集中,概念可以是

概念 1:球、鞋、目标、胜利

概念 2:球,球棒,得分,裁判

我们可以看到两个概念——概念 1 代表足球,概念 2 代表板球。但是我们可以看到,这些概念可以有重叠的词,因此,整个词集共同代表一个概念,而不是单个的词。LSA 试图使用术语共现矩阵来找到被称为概念的最佳单词集来表示文档。

概念也是通过降维来表示文档的一种方式。

奇异值分解

我们可以看到文档-术语矩阵非常稀疏并且大小很大。在如此大的矩阵上的计算是昂贵的,并且没有非常显著的结果,并且矩阵中的许多值是零。为了降低计算复杂度并获得更相关和有用的结果,使用了 SVD。

SVD 将矩阵分解成三个不同的矩阵:正交列矩阵、正交行矩阵和一个奇异矩阵。

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

研究之门

奇异值分解的主要优点是我们可以将矩阵的规模从数百万减少到 100 或 1000。上图中的K是矩阵的秩。类似地,如果我们仅使用 k 列和 k 行,那么我们也可以近似地计算矩阵 A,而没有任何大的损失。

在 SVD 计算期间,我们计算代表项共生矩阵的A*(A'T)。这意味着上面矩阵中带有索引(i,j)的值表示术语(I)和术语(j)在文档数据集中同时存在的次数。点击了解 SVD 更多信息

履行

实现是理解概念的最佳方式。我们将使用一个小例子来实现 LSA,这将有助于我们理解 LSA 的工作和输出。

我们将使用的文档是

a1 = "He is a good dog."
a2 = "The dog is too lazy."
a3 = "That is a brown cat."
a4 = "The cat is very active."
a5 = "I have brown cat and dog."

这里我们可以看到,必须生成两个概念,一个代表猫,另一个代表狗。

将此文档列表转换为数据帧:

import pandas as pd
df = pd.DataFrame()
df["documents"] = [a1,a2,a3,a4,a5]
df

df应该是这样的:

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

文档数据框架

预处理

任何机器学习算法最重要的部分就是数据预处理。数据中存在的噪声越多,模型的准确性越低。

我们将对数据执行四种类型的处理:

  1. 删除文本中的所有特殊字符。
  2. 删除所有少于 3 个字母的单词。
  3. 小写所有字符。
  4. 删除停用词。
#remove special characters
df['clean_documents'] = df['documents'].str.replace("[^a-zA-Z#]", " ")#remove words have letters less than 3
df['clean_documents'] = df['clean_documents'].fillna('').apply(lambda x: ' '.join([w for w in x.split() if len(w)>2]))#lowercase all characters
df['clean_documents'] = df['clean_documents'].fillna('').apply(lambda x: x.lower())

为了移除停用词,我们将对字符串进行标记,然后再次追加所有不是停用词的词。

import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = stopwords.words('english')# tokenization
tokenized_doc = df['clean_documents'].fillna('').apply(lambda x: x.split())# remove stop-words
tokenized_doc = tokenized_doc.apply(lambda x: [item for item in x if item not in stop_words])# de-tokenization
detokenized_doc = []
for i in range(len(df)):
    t = ' '.join(tokenized_doc[i])
    detokenized_doc.append(t)df['clean_documents'] = detokenized_doc

经过预处理后,我们的数据将如下所示:

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

清洗完文件后

文档术语矩阵

我们将使用sklearn来生成文档术语矩阵。

from sklearn.feature_extraction.text import TfidfVectorizervectorizer = TfidfVectorizer(stop_words='english', smooth_idf=True)X = vectorizer.fit_transform(df['clean_documents'])

我们用TfidfVectorizer代替CountVectorizer,因为 tf-idf 是更有效的矢量器。你可以在这里了解传递给TfidfVectorizer 的各种参数,要了解 tf-idf 你可以查看这个链接

X的形状将是(5,6),其中行代表文档数 5,列代表术语数 6。

要查看条款

dictionary = vectorizer.get_feature_names()
dictionary

这将给出一组单词

['active', 'brown', 'cat', 'dog', 'good', 'lazy']

奇异值分解

from sklearn.decomposition import TruncatedSVD# SVD represent documents and terms in vectors 
svd_model = TruncatedSVD(n_components=2, algorithm='randomized', n_iter=100, random_state=122)lsa = svd_model.fit_transform(X)

TruncatedSVD对文档-术语矩阵执行 SVD 函数,并给出降维后的向量。如果你想要矩阵不降维,你应该使用fit而不是fit_transform

n_components是输出数据的维度。n_components的值代表不同主题的数量。可以在这里了解更多 sklearn SVD。

现在,我们将检查分配给文档的主题

pd.options.display.float_format = '{:,.16f}'.format
topic_encoded_df = pd.DataFrame(lsa, columns = ["topic_1", "topic_2"])
topic_encoded_df["documents"] = df['clean_documents']
display(topic_encoded_df[["documents", "topic_1", "topic_2"]])

输出如下所示

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

电平移动放大器(Level Shift Amplifier)

我们可以看到分配给每个文档的主题。关于狗的文档由 topic_2 表示,关于猫的文档由 topic_1 表示。最后一个既有猫又有狗的文档更多地由 topic_1 表示,但也属于 topic_2。这与 topic_1 更相似,因为文档包含单词browncat,这两个单词在 topic_1 中的权重更高。

我们还可以看到每个主题中术语的权重。

encoding_matrix = pd.DataFrame(svd_model.components_, index = ["topic_1","topic_2"], columns = (dictionary)).T
encoding_matrix

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

术语-主题矩阵

从上面我们可以看到,术语browncat在 topic_1 中的权重都高于 topic_2。

我们已经看到了 LSA 的实施和运作。

应用程序

LSA 是 LSI 和降维算法的先驱。

  1. LSA 用于降维。我们可以在不丢失任何上下文的情况下,将向量的大小从数百万急剧减少到数千。这将有助于我们减少计算能力和执行计算所需的时间。
  2. LSA 用于搜索引擎。潜在语义索引(LSI)是在 LSA 上开发的算法。使用从 LSA 开发的向量来找到匹配搜索查询的文档。
  3. LSA 也可以用于文档聚类。正如我们看到的,LSA 为每个文档分配主题,基于分配的主题,我们可以对文档进行聚类。

潜在语义分析:直觉、数学、实现

原文:https://towardsdatascience.com/latent-semantic-analysis-intuition-math-implementation-a194aff870f8?source=collection_archive---------4-----------------------

我们如何使用无监督学习从文本中提取主题和话题

TL;DR —文本数据深受高维度之苦。潜在语义分析(LSA)是一种流行的降维技术,遵循与奇异值分解相同的方法。LSA 最终根据 r 潜在T5(即隐藏*)特征来重构文本数据,其中 r 小于数据中的项数 m 。我将解释概念上的数学上的直觉上的,并使用 20 个新闻组数据集在 Scikit-Learn 中运行一个基本的实现。*

语言不仅仅是你面前单词的集合。当你阅读一篇文章时,你的脑海中会浮现出一些图像和概念。当你阅读许多文本时,主题开始浮现,即使它们从未被明确地表达出来。我们理解和处理语言的天生能力挑战了算法表达式(目前)。LSA 是最流行的自然语言处理(NLP)技术之一,它试图用数学方法确定文本中的主题。LSA 是一种无监督的学习技术,它基于两个支柱:

  • 分布假说,即意思相近的词频繁出现在一起。JR Firth 的名言“你应该从一个人交往的朋友那里知道一个词”很好地概括了这一点
  • 奇异值分解(SVD——图 1)是一种数学技术,我们将更深入地研究它。

请注意,LSA 是一种无人监督的学习技术——没有基础真理。潜在的概念可能存在,也可能不存在!在我们稍后将使用的数据集中,我们知道有 20 个新闻类别,我们可以对它们进行分类,但这只是出于说明的目的。通常情况下,我们会在非结构化、无标签的数据上使用 LSA。

像所有的机器学习概念一样,LSA 可以分为 3 个部分:直觉、数学和代码。请随意使用目录中的链接,跳到与您最相关的部分。完整的代码可以在这个 Github repo 中找到。

术语注释:通常,当对文本数据进行这种分解时,术语 SVD 和 LSA(或 LSI)可以互换使用。为了简单起见,从现在开始我将使用 LSA。

本文假设对基本的自然语言处理预处理和单词矢量化有一些了解(特别是 tf-idf 矢量化 )。

内容:

  1. 直觉:用政治新闻话题解释
  2. 数学 : SVD 作为矩阵的加权有序和作为一组 3 个线性变换
  3. 代码实现:python 3 中的 Scikit-Learn 和 20 个新闻组数据
  4. 参考文献

1.直觉

(返回目录)

简单来说:LSA 把有意义的文本文件放在不同的地方重新创作,每一部分都表达了看待文本意义的不同方式。如果你把文本数据想象成一个想法,那么对于这个想法会有 n 种不同的方式看待,或者有 n 种不同的方式概念化整个文本。LSA 将我们的数据表简化为一个潜在的概念表。

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

图 1:奇异值分解的公式和矩阵维数

假设我们有一些数据表,在本例中是文本数据,其中每行是一个文档,每列代表一个术语(可以是一个单词或一组单词,如“baker’s 十二”或“Downing Street”)。这是表示文本数据的标准方式(在文档术语矩阵中,如图 2 所示)。表格中的数字反映了该单词在文档中的重要性。如果数字是零,那么这个单词就不会出现在文档中。

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

图 2:文档术语矩阵,在应用了某种矢量化之后,在我们的例子中是 TF-IDF(但是单词包也可以)

不同的文档将涉及不同的主题。假设所有文件都是政治文章,有 3 个主题:外交政策(F.P .)、选举和改革

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

图 3:文档-主题矩阵(或者文档- 潜在的-概念,如果你喜欢的话)

假设有些文章属于每一个类别,有些属于两个类别,有些属于所有三个类别。我们可以绘制一个表格,其中每行是一个不同的文档(一篇新闻文章),每列是一个不同的主题。在单元格中,我们将使用不同的数字来表示该文档属于特定主题的程度(参见图 3)。

现在,如果我们从概念上将注意力转移到主题本身,我们应该问自己以下问题:我们是否期望某些 单词 在这些主题中更频繁地出现?

如果我们看外交政策,我们可能会看到像“中东”、“欧盟”、“大使馆”这样的术语。对于选举,可能是“选票”、“候选人”、“政党”;对于改革,我们可能会看到“法案”、“修正案”或“腐败”。因此,如果我们在不同的表中绘制这些主题和这些术语,其中的行是术语,我们会看到根据哪个主题最强烈地属于每个术语绘制的分数。自然会有在所有三个文档中出现的术语(“总理”、“议会”、“决定”),这些术语会在所有三列中有分数,反映它们属于任一类别的程度-数字越高,其与该主题的关联越大。因此,我们的第二个表(图 4)由术语和主题组成。

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

图 4:术语-主题矩阵

现在,最后一个组件作为一个表来解释有点棘手。它实际上是一组数字,一个数字代表一个话题。这些数字代表什么?它们代表了每个主题解释了我们的数据的程度。

他们如何“解释”这些数据?好吧,假设实际上,“改革”并不是贯穿我们文章的突出主题,大多数文章更适合“外交政策”和“选举”。因此,“改革”在这一组中会得到一个很低的数字,低于其他两个。另一种选择是,也许所有三个数字实际上都很低,我们实际上应该有四个或更多的主题——我们后来发现我们的许多文章实际上都与经济学有关!由于只坚持三个主题,我们已经剥夺了自己获得更详细和精确的数据的机会。这个数组的技术名称是“奇异值”。

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

图 5:奇异值——我们的主题在文本中的相对重要性是什么?

这就是目前为止的直觉。您会注意到我们的两个表有一个共同点(文档/文章),这三个表都有一个共同点——主题,或者它们的某种表示。

现在让我们解释一下这是一种怎样的降维技术。如果我们指定一些文档和主题,就更容易看到优点。假设我们有 100 篇文章和 10,000 个不同的术语(想想所有这些文章会有多少独特的词,从“修正”到“热心的”!).在我们最初的文档术语矩阵中,有 100 行和 10,000 列。当我们开始将数据分解为 3 个部分时,我们实际上可以选择主题的数量——我们可以选择 10,000 个不同的主题,如果我们真的认为这是合理的。然而,我们也许可以用更少的主题来表示数据,比如我们最初谈到的 3 个主题。这意味着在我们的文档主题表中,我们将削减大约 99,997 列,在我们的术语主题表中,我们将做同样的事情。我们从表中丢弃的列和行在图 6 中显示为散列矩形。M 是原始文档-术语表; U 是文档主题表,𝚺 (sigma)是奇异值的数组,而 V-transpose (上标 t 表示原始矩阵 t 已沿其对角线翻转)是文档主题表,但沿其对角线翻转(我将在数学部分解释原因)。

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

图 6 —我们丢弃了哪些散列

至于表示主题重要性的一组数字,从一组 10,000 个数字中,每个数字越来越小,因为它对应于一个不太重要的主题,我们削减到只有 3 个数字,用于我们剩余的 3 个主题。这就是为什么 LSA 的 Python 实现被称为截断的 SVD:顺便说一下,我们截掉了表的一部分,但是我们稍后会看到代码。同样值得注意的是,我们事先不知道 3 个主题是什么,我们只是假设会有 3 个,一旦我们得到了组件,我们就可以探索它们,看看术语是什么。

当然,我们不只是想回到原始数据集:我们现在有 3 个可以使用的低维组件。在代码和数学部分,我们将讨论我们实际上前进了哪一步。简而言之,一旦我们截断了表(矩阵),我们将得到的产品是文档主题表( U ) 乘以奇异值(𝚺).这可以解释为文档(我们所有的新闻文章)以及它们属于每个主题的程度,然后根据每个主题的相对重要性进行加权。你会注意到,在这种情况下,这个最终表格中遗漏了一些东西,即单词。是的,我们已经超越了文字,我们丢弃了它们,但保留了主题,这是一种表达我们文本的更简洁的方式。

2.数学

(返回目录)

对于数学,我将对 SVD 进行两种不同的解释:首先是可以用于实方阵 M 的一般几何分解,其次是与我们的例子更相关的可分离模型分解。SVD 也用于基于模型的推荐系统。它非常类似于主成分分析(PCA),但是它在稀疏数据上比 PCA 操作得更好(并且文本数据几乎总是稀疏的)。PCA 对数据集的相关性矩阵进行分解,而 SVD/LSA 直接对数据集进行分解。

我们将把这个矩阵分解成组成矩阵。我所说的因式分解本质上与我们用一个数来表示它的因子是一样的,当这些因子相乘时,我们就得到了原始数,例如 A = B * C * D。

这也是为什么它被称为奇异值分解——我们将分解成它的组成部分。

一般几何分解

我们在原始矩阵中无法获得的额外维度,即 r 维度,是潜在概念的数量。一般来说,我们试图把我们的矩阵表示成其他矩阵,它们的一个轴是这组分量。您还会注意到,基于维度,3 个矩阵的乘法(当 V 被转置时)将使我们回到原始矩阵的形状,维度 r 实际上消失了。

在理解数学的过程中,重要的不是确定 u、v 和𝚺中每个数字的代数算法,而是这些乘积的数学性质以及它们之间的关系。

首先,重要的是首先考虑矩阵实际上是什么,它可以被认为是向量空间的变换。在图 7 的左上角,我们有两个垂直的向量。如果我们只有两个变量开始,那么特征空间(我们正在查看的数据)可以在这个空间的任何地方绘制,这个空间由这两个向量描述。现在移到我们图的右边,矩阵 M 被应用到这个向量空间,这就把它转换成新的,在右上角的转换空间。在下图中,M 的几何效应被称为“剪切”向量空间;两个向量 𝝈1𝝈2 实际上是我们在这个空间中绘制的奇异值。

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

图 7:来源:维基百科;奇异值分解链接;作者:格奥尔格-约翰

现在,就像你们在学校可能记得的点的几何变换一样,我们可以把这个变换 M 看作三个独立的变换:

  1. V引起的旋转(或反射)。注意V * = V-转置*由于 V 是实酉矩阵,所以 V 的复共轭与其转置相同。在矢量项中,V 或 V* 的变换保持基矢量的长度不变;
  2. 𝚺具有沿其奇异值拉伸或压缩所有坐标点的效果。想象一下我们在左下角的圆盘,我们朝着 𝝈2 的方向垂直向下挤压它,然后沿着 𝝈1 的方向水平拉伸它。这两个奇异值现在可以被描绘成椭圆的长半轴和短半轴。你当然可以将此推广到 n 维度。
  3. 最后,应用 U 旋转(或反射)我们的特征空间。我们已经得到了与直接从 M 转换相同的输出。

我还推荐关于 SVD 的优秀的 Wikipedia 条目,因为它对这个过程有特别好的解释和 GIF。

所以,换句话说,其中 x 是任意列向量:

M 对 x 的变换与右边矩阵对 x 的三次变换相同

矩阵 UV* 的性质之一是它们是酉矩阵,因此我们可以说这两个矩阵的列形成了两组正交基向量。换句话说,你可以从 U 得到的列向量会形成它们自己的坐标空间,这样如果有两列 U1U2,你就可以写出空间的所有坐标,作为 U1U2 的组合。这同样适用于 VV1V2的列,并且这将推广到n-尺寸(你将有n-列)。

可分离模型分解

如果我们想象我们的矩阵 M 可以被分解成可分离矩阵的加权和,我们可以得到对 PCA 的相同理解,如下所示。

将我们的数据 M 分解成可分离矩阵的加权和, Ai

矩阵𝐴𝑖据说是可分的,因为它们可以分解成两个向量的外积,用奇异值𝝈I加权。计算形状为( m,)和( n,)的两个向量的外积将给出形状为(m,n)的矩阵。换句话说,计算两个向量中任意两个数的每个可能乘积,并放入新矩阵中。奇异值不仅对和进行加权,而且对和进行排序,因为值是按降序排列的,所以第一个奇异值总是最高的一个。

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

图 8:我们的可分离矩阵。请注意,≅符号代表这样一个事实,即只有 3 个乘积的分解集近似于我们的原始矩阵,它并不完全等于它。

在图 8 中,你可以看到如何将它可视化。以前我们有高的 U ,正方形σ和长的𝑉- 转置矩阵。现在你可以想象从 U 中取出第一个垂直切片,用第一个奇异值对其所有值进行加权(相乘),然后通过与𝑉 的第一个水平切片进行外积-转置,用这些切片的维度创建一个新矩阵。然后我们把这些乘积加在一起,得到 M。或者,如果我们不做完全求和,而只是部分完成,我们得到的是截断的版本。

因此,对于我们的数据:

  • 其中 M 是我们原来的( m,n )数据矩阵——M 行,n 列; m 个文档,n 个术语
  • u 是一个( m,r )矩阵— m 个文档和 r 个概念
  • σ是一个对角线 ( r,r )矩阵——除了对角线上的值以外,所有值都为零。(但是非零值代表什么呢?
  • v 是一个( n,r )矩阵— n 项,r 个概念

𝚺的值代表了每个潜在概念在多大程度上解释了我们数据中的差异。当这些乘以该潜在概念的 u 列向量时,它将有效地加权该向量。

如果我们将它分解成 5 个组件,它看起来会像这样:

加权文档概念向量和术语概念向量的外积之和

这里原本会有 ru 个向量;5 个奇异值和 n 个𝑣*-转置*向量。

3.代码实现

(返回内容)

在最后一节中,我们将看到如何使用 Scikit-Learn 实现基本的 LSA。

提取、转换和加载我们的文本数据

from sklearn.datasets import fetch_20newsgroups
X_train, y_train = fetch_20newsgroups(subset='train', return_X_y=True)
X_test, y_test = fetch_20newsgroups(subset='test', return_X_y=True)

清洗和预处理

文本数据的清理通常与数字数据的清理截然不同。您经常会发现自己已经准备好了矢量器、模型,并准备好进行网格搜索,然后提取特征,却发现 cluster x 中最重要的特征是字符串“_ _”…因此您需要返回并做更多的清理工作。下面的代码块是我意识到需要从数据集中删除网站 URL、号码和电子邮件的结果。

from nltk.corpus import stopwords
from nltk.tokenize import RegexpTokenizer
import re
tokenizer = RegexpTokenizer(r'\b\w{3,}\b')
stop_words = list(set(stopwords.words("english")))
stop_words += list(string.punctuation)
stop_words += ['__', '___']# Uncomment and run the 3 lines below if you haven't got these packages already
# nltk.download('stopwords')
# nltk.download('punkt')
# nltk.download('wordnet')def rmv_emails_websites(string):
    """Function removes emails, websites and numbers""" new_str = re.sub(r"\S+@\S+", '', string)
    new_str = re.sub(r"\S+.co\S+", '', new_str)
    new_str = re.sub(r"\S+.ed\S+", '', new_str)
    new_str = re.sub(r"[0-9]+", '', new_str)
    return new_strX_train = list(map(rmv_emails_websites, X_train))
X_test  = list(map(rmv_emails_websites, X_test))

文本数据的符号化和矢量化

我们的模型处理数字,而不是字符串!因此,我们将文本标记化(将所有文档转化为更小的观察实体——在本例中为单词),然后使用 Sklearn 的 TF-IDF 矢量器将它们转化为数字。我建议任何转换过程(尤其是那些需要时间运行的过程)都在数据的前 10 行进行,并检查结果:它们是您期望看到的吗?数据框的形状是你所希望的吗?一旦你对你的代码有信心了,就输入整个语料库。

tfidf = TfidfVectorizer(lowercase=True, 
                        stop_words=stop_words, 
                        tokenizer=tokenizer.tokenize, 
                        max_df=0.2,
                        min_df=0.02
                       )
tfidf_train_sparse = tfidf.fit_transform(X_train)
tfidf_train_df = pd.DataFrame(tfidf_train_sparse.toarray(), 
                        columns=tfidf.get_feature_names())
tfidf_train_df.head()

这将为您提供矢量化的文本数据——文档术语矩阵。对测试集也重复上面的步骤,但是使用 transform, fit_transform。

探索性数据分析 LSA

仅仅为了我们的分解数据的可视化和 EDA 的目的,让我们将我们的 LSA 对象(在 Sklearn 中是 TruncatedSVD 类)适合我们的训练数据,并且只指定 20 个组件。

from sklearn.decomposition import TruncatedSVDlsa_obj = TruncatedSVD(n_components=20, n_iter=100, random_state=42)tfidf_lsa_data = lsa_obj.fit_transform(tfidf_train_df)
Sigma = lsa_obj.singular_values_
V_T = lsa_obj.components_.T

现在让我们想象奇异值——下面的柱状图是否显示了我们对它们的预期?

sns.barplot(x=list(range(len(Sigma))), y = Sigma)

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

图 9 —我们的奇异值,代表每个潜在概念在多大程度上解释了数据中的差异

让我们通过术语-主题矩阵,V-trans pose 来探索我们减少的数据。 TruncatedSVD 将把它作为形状的 numpy 数组(num_documents,num_components)返回,所以我们将把它变成一个 Pandas dataframe 以便于操作。

term_topic_matrix = pd.DataFrame(data=lsa_term_topic, 
                                 index = eda_train.columns, 
                                 columns = [f'Latent_concept_{r}' for r in range(0,V_T.shape[1])])

让我们将术语-主题矩阵分割成 Pandas 系列(单列数据框),按值排序并绘制它们。下面的代码为我们的第二个潜在组件绘制了这个图(回想一下,在 python 中我们从 0 开始计数),并返回图 10 中的图:

data = term_topic_matrix[f'Latent_concept_1']
data = data.sort_values(ascending=False)
top_10 = data[:10]
plt.title('Top terms along the axis of Latent concept 1')
fig = sns.barplot(x= top_10.values, y=top_10.index)

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

图 10:尽管看起来很嘈杂,但这里至少有三个术语有一个很强的主题

这些词在我们的第二个潜在成分中排名很高。这个轴的另一端的单词呢(见图 11)?

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

图 11:在这个时候,作者意识到了旅鼠/词干是多么有用

你可以自己决定这种语义分歧意味着什么。添加更多的预处理步骤将有助于我们摆脱像“说”和“说”这样的词产生的噪音,但我们现在将继续努力。让我们为第六个潜在概念再做一对想象(图 12 和 13)。

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

图 12

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

图 13:我们再一次看到技术术语在这些数据中非常突出

在这一点上,由我们来从这些情节中推断出一些意义。概念 5 的轴的负端似乎与技术和科学主题有很强的关联(“空间”、“科学”、“计算机”),但正端也是如此,尽管更侧重于计算机相关的术语(“硬盘”、“驱动器”、“系统”)。

现在澄清一下,确定正确的组件数量需要调优,所以我没有将参数设置为 20,而是将其改为 100。您可能认为这仍然是一个很大的维数,但是我们最初的维数是 220(这是对我们最小文档频率的限制!),所以我们减少了相当大的一部分数据。我将在另一篇文章中探讨如何选择奇异值的最佳数量。现在,我们将继续我们所拥有的。

在我们的建模任务中使用我们的潜在组件

虽然 LSA 是一种无监督的技术,通常用于在未标记的数据中发现模式,但我们在这里使用它来降低标记数据的维度,然后再将其输入模型。我们将比较 LSA 数据和标准 TF-IDF 数据的准确性,以衡量 LSA 从原始数据集中获取了多少有用信息。我们现在有一个形状的训练数据集(11314,100)。文档的数量保持不变,我们已经创建了 100 个潜在的概念。现在,让我们在这一点上和我们的标准 TF-IDF 数据上运行一个模型。下面的实现的目的不是得到一个好的模型,而是比较两个非常不同的数据集。我通过 GridSearchCV 加入了基本的交叉验证,并对 tolerance 超参数进行了少量的调整。如果你这样做是为了建立一个实际的模型,你会比下面写的走得更远。这只是为了帮助您进行基本的实现:

logreg_lsa = LogisticRegression()
logreg     = LogisticRegression()
logreg_param_grid = [{'penalty':['l1', 'l2']},
                 {'tol':[0.0001, 0.0005, 0.001]}]grid_lsa_log = GridSearchCV(estimator=logreg_lsa,
                        param_grid=logreg_param_grid, 
                        scoring='accuracy', cv=5,
                        n_jobs=-1)grid_log = GridSearchCV(estimator=logreg,
                        param_grid=logreg_param_grid, 
                        scoring='accuracy', cv=5,
                        n_jobs=-1)best_lsa_logreg = grid_lsa_log.fit(tfidf_lsa_data, y_train).best_estimator_
best_reg_logreg = grid_log.fit(tfidf_train_df, y_train).best_estimator_print("Accuracy of Logistic Regression on LSA train data is :", best_lsa_logreg.score(tfidf_lsa_data, y_train))
print("Accuracy of Logistic Regression with standard train data is :", best_reg_logreg.score(tfidf_train_df, y_train))

它返回:

Accuracy of Logistic Regression on LSA train data is : 0.45
Accuracy of Logistic Regression with standard train data is : 0.52

性能的下降是显著的,但是您可以将这一点纳入优化流程,并调整潜在组件的数量。这在我们的测试数据(7532 个文档)上表现如何呢?

Accuracy of Logistic Regression on LSA test data is : 0.35
Accuracy of Logistic Regression on standard test data is : 0.37

两者的精确度都大大下降了,但是请注意模型之间的差距有多小!我们的 LSA 模型能够从我们的测试数据中获取与我们的标准模型一样多的信息,而尺寸却不到一半!由于这是一个多标签分类,最好用混淆矩阵来显示(图 14)。当你考虑给定 20 个新闻类别的随机分类概率时,我们的结果看起来明显更好。如果你不熟悉混淆矩阵,作为一个经验法则,我们想最大化对角线上的数字,最小化其他地方的数字。

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

图 14— 我们测试数据的混淆矩阵(7532 个文档)。y 轴代表实际新闻类别,x 轴代表预测新闻类别。对角线值是所有正确分类的文档。

这就结束了我们在 Scikit-Learn 中对 LSA 的实现。我们已经讨论了这项技术的直觉、数学和编码。

我希望你喜欢这篇文章,并会感谢任何数量的掌声。请在评论中留下任何反馈(积极的或建设性的),尤其是关于数学部分,因为我发现这是最难表达的。

4.参考

(返回目录)

参考资料:

[1] L. Hobson,H. Cole,H. Hapke,自然语言处理在行动 (2019),https://www . manning . com/books/Natural-Language-Processing-in-Action

[2] Pedregosa 等著,sci kit-learn:Python 中的机器学习 (2011),JMLR 12,第 2825–2830 页。

[3] 哈姆达维 Y, TF(词频)-IDF(逆文档频)从 python 中的无到有 (2019),走向数据科学

[4]维基贡献者,奇异值分解https://en.wikipedia.org/wiki/Singular_value_decomposition

潜在随机微分方程

原文:https://towardsdatascience.com/latent-stochastic-differential-equations-a0bac74ada00?source=collection_archive---------30-----------------------

活动讲座

大卫·杜文瑙德| TMLS2019

来自多伦多机器学习峰会的演讲:【https://torontomachinelearning.com/

关于演讲者:

David Duvenaud 是多伦多大学计算机科学和统计学的助理教授。他是加拿大研究生成模型的主席。他的博士后研究是在哈佛大学完成的,在那里他从事超参数优化、变分推理和化学设计。他在剑桥大学获得博士学位,与邹斌·格拉马尼和卡尔·拉斯姆森一起研究贝叶斯非参数。大卫在谷歌研究院的机器视觉团队呆了两个夏天,还联合创立了能源预测和交易公司 Invenia。David 是 Vector Institute 的创始成员,也是 ElementAI 的研究员。

关于演讲:

许多真实世界的数据是不定期采样的,但是大多数时间序列模型需要定期采样的数据。连续时间潜变量模型可以解决这个问题,但直到现在,只有确定性模型,如潜在常微分方程,是有效的反向传播训练。我们将伴随灵敏度方法推广到随机微分方程,构造了一个 SDE,它在时间上向后运行并计算所有必要的梯度,以及一个通用算法,该算法允许随机微分方程通过具有恒定存储成本的反向传播来训练。我们还给出了函数空间中基于梯度的随机变分推理的有效算法,所有算法都使用了自适应黑盒 SDE 解算器。最后,我们将展示对时间序列数据应用潜在随机微分方程的初步结果,并讨论无限深度贝叶斯神经网络的原型。

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

潜在随机微分方程

潜在变量&期望最大化算法

原文:https://towardsdatascience.com/latent-variables-expectation-maximization-algorithm-fb15c4e0f32c?source=collection_archive---------7-----------------------

机器学习的贝叶斯方法

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

潜伏的‘烟雾’:(图片来源:作者)

“潜伏”一词源于拉丁语,意思是隐藏起来。大概你们都知道潜热,是相变保持温度不变所需的热能。因此,我们观察到一种变化,但其背后的原因显然是隐藏的。潜在变量模型(LVM)的动机是用一些潜在的隐藏变量来解释数据的表层结构。在这篇文章中,我们将通过一个例子来理解 LVMs 和非常著名的处理这类模型的算法,即期望最大化(EM)算法。我个人认为这个主题是贝叶斯机器学习的核心之一,它将涉及大量的数学知识。但是,相信我,会很容易的。此外,了解 EM 算法的核心概念将有助于您真正理解变分自动编码器和最终 GAN 的基础。你可以从这篇文章中学到什么:

  1. 为什么是潜变量模型(LVM)?
  2. 高斯混合模型(GMM)。
  3. 期望值最大化算法。
  4. 变分推理和 EM 算法。
  5. 用 EM 算法训练 GMM 的例子。

潜在变量和 LVM:

为什么是隐藏变量?潜在变量可能是一些理论概念,或者是无法观察到的真实物理变量。我们用几个现实的例子来阐述吧。在文本文档中,提取的“单词”可以被视为特征。通过分解这些特征,我们可以找到文档的“主题”。因此,观察到的特征(“单词”——树枝、根、叶子、花、果实)会分解为潜在特征(“主题”——树、花园)。每当我们有大规模、高维度的噪声特征时,在潜在特征上建立分类器是有意义的。在对象识别任务的情况下,每个数据点(像素强度矩阵)对应于一个对象的图像。在这种情况下,潜在变量可以解释为对象的位置方向。正如克里斯·毕晓普在他的模式识别书中提到的—

潜在变量的主要作用是允许观察到的变量上的复杂分布根据从较简单的(通常是指数族)条件分布构建的模型来表示。

通常一个 LVM p ,是 2 组变量 x,z 的概率分布; p(x,z)。x 是数据集 D 中学习时的观察变量,而 z 从未观察到。模型的联合概率分布可以写成 p(x,z) = p(x|z) p(z)

您将会看到,开发 LVMs 的拟合算法相当困难,但是研究这一点并没有什么好处

  1. LVM 通常比原始模型具有更少的参数,这些参数直接表示可见空间中的相关性。
  2. LVMs 中的 LV 主要充当数据的压缩表示,这也称为“瓶颈”。这是无监督学习的基础。如果你想到一个形象(例如。人脸)作为观察变量 x 那么,潜在变量 z 可以编码人脸的特征(在训练期间看不到),就像它可以编码人脸是快乐还是悲伤,男性还是女性等等。
  3. LVMs 还可以帮助我们处理缺失数据。前一点和这一点是相关的。如果我们可以对潜在变量进行后验推断,即给定一幅图像 x 潜在因子 z 是什么,那么一旦我们发现某些图像有缺失部分,潜在因子就可以用于重建。

为了讨论和发展一个现实的 LVM,我们将根据离散的潜变量来公式化高斯混合模型(GMM)。由于获取 LVMs 中最大似然估计量的最通用技术是 EM 算法,我们将在接下来的章节中详细讨论。

概率聚类和 GMM;

在我之前的 DBSCAN 算法文章中,我已经讨论了 K-Means 算法的缺点,特别是在处理不同密度、大小和数据点的空间聚类时,包括噪声和异常值。K-Means 的另一个问题是它执行硬聚类。让我们看一个使用简单的[make_blobs](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_blobs.html)数据集的例子。在下面的图 1 中,我们看到了包含 3 个带标签和不带标签的聚类的数据集。一旦我们应用 K-Means 算法,它将识别 3 个聚类,但是不可能将任何概率分配给聚类边界处的数据点。如果我们想知道每个数据点属于这三个聚类的概率或可能性(对于聚类边界上的点尤其重要),该怎么办?

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

图 1:创建 Blobs 数据集(左)和包含标签的相同数据集(右)。来源:作者

在图 2 中,我们展示了一个将高斯混合模型(GMM)聚类应用于数据集的示例,每个数据点的大小与 GMM 预测的确定性成比例。这与 K-Means 结果进行比较,您可以清楚地看到差异,尤其是对于边界处的点。

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

图 2:使用 GMM 的软聚类(右)的比较通过给每个数据点分配预测的确定性来描述。这与硬聚类-K-Means(左)相比较。来源:作者

将这种软聚类作为一种动机,让我们使用潜在变量建立 GMM,但在此之前,让我们回忆一下多元正态分布。这里使用的符号很常见。

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

实验一:多元正态分布。

我们将使用混合正态分布来开发一个概率聚类(软聚类)模型。认为 GMM 是高斯分量的线性叠加的天真想法。每个分量将具有与其相关联的某种概率来表示特定的数据点。

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

实验 2:高斯分布的混合。

π在 Exp 中称为混合系数。2.对于单个数据点,总和超过聚类数 K 。变量 xz (潜伏)的联合概率分布为: p(x,z) = p(x|z) p(z) 。因此数据点 x 上的边际分布将由下式给出: p(x) = ∑ p(x|z) p(z) dz (通过对变量 z 求和/积分获得)。考虑这个 p(x) 的一种方式是混合分布 p(x|z) ,用 p(z) 加权。对于 GMM 上下文,我们可以把 z 看作是一个二进制随机变量,具有 1 的 K 表示(你可以把这看作是分类表示),其中一个特定元素等于 1,其他所有元素都是 0。

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

实验 3:潜在变量的边际分布。

现在,混合系数和潜在变量 z ,当我们考虑 z 上的边际分布是按照上面表达式中定义的混合系数来指定时,都落入一个位置。混合系数所满足的条件是必要的,以便它们可以有效地解释为概率。我们认为第 k 个混合系数(π_k)是 z_k 等于 1 的先验概率。由于潜在变量使用 1/K 的表示法(把这看作是分类表示法),我们可以用另一种方式写出 p(z)和相应的条件分布如下—

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

实验 4:边际和条件分布

因此,结合多元正态分布和潜在变量分布,我们可以重写 GMM 模型如下。

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

实验 5:混合系数和多元正态分布的 GMM。

上述表达式对单个数据点有效。对于几个数据点,我们将有一个对应的潜在变量与每个观察到的数据点相关联。我们现在可以处理联合分布 p(x,z),而不是只处理边际分布。我们让事情变得更复杂了吗?为了回答这个问题,我们必须在可能性估计的数学中稍微深入一点。下一节将揭示潜在变量将如何帮助我们解决最大似然估计(MLE)容易。

期望值最大化算法(动机):

我们对 GMM 的主要刺激是进行数据点的软聚类。获得每个聚类的最佳参数(混合系数、聚类均值、协变矩阵)的一般直觉是执行通常的 MLE 任务。在上面的表达式 4 中,我们已经为单个数据点写了 GMM 模型。让我们考虑一个具有 N 个点的数据集,这样该观察集将是{x1,x2,x3,…,xN}。对于 N 个数据点,似然函数如下—

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

实验 6:对数似然函数包括所有 N 个数据点。

这个表达式的最大问题是对数并不直接作用于高斯,而是作用于高斯混合的和。因此,相对于对数对指数的作用,我们没有优势。所以确实这个表情很难还原。意识到这不是单个高斯函数的问题。除了前面的问题,另一个可能出现的问题是当 GMM 的一个组成部分只解释了一个点。这意味着其中一个μ等于数据点 x_n,在方差趋于 0 的极限内,似然项的行为类似于δ函数。所以最大化可能性在这个问题中不是一个好主意。与单个高斯分布问题相比,考虑高斯混合问题的另一种方式是,虽然单个高斯模型属于具有凹对数似然(对于足够简单的族来说是易处理的)的指数族,但是分量的混合不会具有这种性质。因此,所有这些原因都需要一种新的方法来确定参数,并且是时候深入研究期望值最大化(EM)算法了,该算法确实是基于贝叶斯更新规则的。

EM 算法:

在学习 EM 算法之前,我们需要先推导一些重要的表达式。首先,我们将利用贝叶斯定理从条件分布 p(x|z) 中得到给定 xz 的后验分布表达式,如下所示

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

实验 7:潜在变量的后验分布

γ 项被称为责任,它代表潜在变量 z 的第 k 个分量为解释观察值 x 所承担的责任。顾名思义,EM 算法依赖于两个简单的步骤:期望(E 步)和最大化(M 步)

a)。E-step:期望步骤是我们计算后验分布的地方,即基于当前参数的责任(exp: 5)。这更多的是解决推断问题,即哪个高斯负责哪个数据点?

b)。M-Step:从 E-step 获得的概率然后用于计算更新的参数(μ、σ和π)。

在几次迭代之后,该过程将收敛,并且我们获得参数的最佳拟合值。让我们更一般地回顾一下 EM 算法的步骤——

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

实验 8:EM 算法的一般步骤

在这里,重要的是要提到,一旦我们知道了集群分配,就可以获得最佳参数(这是我们在 E-step 上尝试的一部分)。还要意识到,由于从 E-step 中获得了后验概率,我们可以使用期望的定义,然后我们需要最大化完整数据可能性的期望而不是数据可能性。我们如何进入这种期望的表达,在接下来的部分将会更加清楚,但是现在记住在责任(在实验中定义)方面。7) 我们可以计算出 [1]参数(μ,σ,π),表达式如下—

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

实验 8:从 MLE 获得的参数。

变分下界和 EM 算法;

这是刚才提到的,直到收敛重复 EM 算法的步骤。你可能会想怎么保证算法收敛?我们来深入挖掘一下!我们从 GMM 开始说,对于每个数据点 x_n 都有一个潜在变量 z_n 。完整数据集的对数似然采用如下形式—

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

实验 9:包含潜在变量的完全可能性

如前所述,这个表达式的问题是对数是作用于高斯混合的和。我们将耍些小花招来解决这个问题。让我们在潜在变量上引入任意概率分布(没有任何特殊性质)— q(z) 现在我们可以修改上面的表达式——

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

实验 10:数据似然性的微小变化

使用期望值的定义,这个表达式可以进一步简化为—

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

实验 11:使用期望的定义

期望项可以理解为从分布 q_i 中提取的 z_i 的期望值。我们可以将这个表达式与 Exp 进行比较。为了理解对潜在变量求和是如何给出期望值的。在 Exp 中。11、日志正在对期望值进行操作。鉴于 **Log 是一个凹函数,**让我们应用 詹森不等式 来进一步简化表达式——

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

实验 12:用詹森不等式修改实验 11。

上面的表达式表示完整数据集的对数似然大于或等于上面的期望值。期望项被称为证据下限(ELBO) ,通过对数展开和应用贝叶斯定理,我们可以得出更有意义的结论

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

实验 13:证据下限

使用 KL 散度的定义,上述表达式变成—

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

实验 14: ELBO 和 KL 背离

当 KL 散度≥ 0 时,这意味着 ELBO ≤ log p(x) 。现在我们知道它为什么被称为下界了。我们的目标是最大化我们的数据可能性 log p(X) ,相反,我们最大化 ELBO。基于这个表达式(Exp。14)让我们再回顾一遍 EM 算法的步骤—

  1. 通过随机初始化参数来启动算法。
  2. e 步骤:最大化 ELBO w.r.t q(z) 并保持参数 (π,μ,σ)不变。由于 log p(X) 独立于q(z)这个步骤本质上只是计算 KL 散度,并且在 GMM 的情况下 q(z) 被设置为等于后验概率。这是可能的,因为在 GMM 中可以计算每个数据点的后验概率。
  3. m 步:ELBO 相对于参数最大化,而 q(z) 保持固定,这与 MLE 估计非常相似。在这个步骤中,参数被更新。

为什么趋同:

我们以一个问题开始这一节——为什么 EM 算法能保证收敛?EM 算法是一个迭代过程,因此 E 和 M 步骤循环进行。重要的是要记住,在 EM 算法的每一步中,首先将分布 q(z) 设置为等于后验 p(z|x) (E 步),并且从最大化开始在 M 步中更新参数。随着更新的参数,下限增加(除非算法已经达到局部最大值)。这又增加了对数似然性,但是 log p(x) 比下限增加得更多,因为虽然 q(z) 是针对旧参数获得的,但是现在在 E 步骤中,当我们再次计算后验 p(z|x) 时,并且这次使用来自 M 步骤的新参数,产生非零 KL 发散项。因此,下限以及数据似然性单调增加。为了确保算法不会陷入局部最大值,我们对不同的参数初始值运行算法。数据似然性的这种单调递增的性质正是我们想要展示的收敛的代理。如果我们看到可能性在每一步都没有增加,这有时对调试代码非常有帮助。为了运行该算法,我们将给出迭代次数作为参数,并且还为损失函数的分数增加设置容差。现在,是时候将所有的理论付诸实践了,让我们来编码吧!!请查看笔记本,了解详细的代码以及参考资料部分的其他参考资料。

用 Python 实现 EM 算法;

让我们从定义 E-step 开始。这里,我们的主要目标是定义后验分布,在我们把它定义为 Exp 中的责任之前。7.下面是代码块—

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

EM 算法的 e 步(适用于 GMM)

接下来,我们实施 M 步,这是关于最大化的期望,对于 GMM,我们已经知道最好的参数,一旦我们从 E 步得到后验。最大似然估计的参数在实验中给出。8,我们将使用它们来定义 M-step,如下所示—

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

GMM 的 M-step

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

Exp。15: ELBO 的可能性和后验概率

一旦我们定义了 E 和 M 步骤,现在我们将实现证据下限作为损失函数。我们从 Exp 修改下界表达式。12 至如实验所示。15.对于潜在变量的分布 *q(z),*我们将使用从 E-step 计算出来的后验。考虑到这些,让我们将 ELBO 定义如下—

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

现在,我们已经准备好定义训练循环,我们设置迭代次数和容差,并确保算法以随机初始化的参数启动几次,以免陷入局部最大值。在训练期间,我们需要指定集群的数量,对于复杂的问题,这可能是一个问题。由于 EM 算法很耗时,通常建议运行 K-Means 算法来确定聚类数,然后对 GMM 运行 EM。另外,确定这一点的另一种方式是使用 Akaike 信息标准。在我的博士研究中,我确实用 AIC 来分离天体物理模型,但这与我们目前的目的不同。训练循环的代码如下—

最后,在训练之后,我们可以画出轮廓—

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

图:左:2D 数据集,聚类成 3 个高斯混合(右)。来源:作者

使用 Scikit-Learn:

使用 sklearn 的 GaussianMixture 类,用 3 行代码就可以实现 GMM EM 算法的所有这些理解和相应的长代码。但是当你知道基本知识的时候,生活总是更好!下面是代码块—

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

使用 scikit-learn 实现 GMM 很容易!

结论:

我们已经完成了这项工作,在这个过程中,我们学习了贝叶斯方法在无监督学习中的几个重要概念。在许多重要的概念中,我希望你们至少能回忆起最重要的一些——

  1. 通过 EM 算法的迭代步骤更新基于先验知识的概率分布。这是贝叶斯推断的基础——一旦我们更新了数据(证据),我们的信念会如何改变。
  2. 为什么引入潜在变量有助于我们更好地理解数据,并最终帮助计算最大似然?
  3. KL 散度和 ELBO 通过数据的可能性的关系。这一点你会在生成模型的概念中反复遇到(GMM 是生成模型的一个简单例子)。
  4. 对于 GMM,单个数据点的后验概率可以通过分析计算得出,但在复杂模型中可能不是这种情况(大多数情况下后验概率是难以处理的),因此,它不能作为潜在变量分布的代理( q(z) = p(z|x) )。在这种情况下,我们试图从尽可能接近后验分布的分布族 Q 中选择 q 。这是变分贝叶斯和最终变分自动编码器(VAE)和生成对抗网络(GAN)的基础。

感谢阅读,希望这能对你有所帮助。干杯!!!

页(page 的缩写)s:我在另一篇文章中讨论了贝叶斯机器学习中的另一个重要概念,称为共轭先验

参考文献:

[1] EM 算法: Andrew NG 笔记来自斯坦福知识库。

[2] 变分推论:大卫·布雷的评论。

[3]克里斯·毕晓普的模式识别书:第 9 章。

[4]笔记本链接: GitHub

Matplotlib 的最新酷功能

原文:https://towardsdatascience.com/latest-cool-features-of-matplotlib-c7a1e2c060c1?source=collection_archive---------24-----------------------

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

照片由 Paola GalimbertiUnsplash 上拍摄

立即将您的 Matplotlib 升级至最新版本 3.3

日前,Matplotlib 发布了 3.3 版本— 其家族第三代中最新的。它引入了一些非常令人兴奋的特性,我强烈建议您今天就升级 Matplotlib。这篇文章将通过一些例子来引导你。

我使用以下命令在我的虚拟环境中更新到最新版本。对于新的安装,请参考官方安装指南。

pip install matplotlib --upgrade

下面我们来看看 Matplotlib 3.3 的最新 亮点功能。

1)生成复杂子情节网格的语义方式

通过subplot_mosaic()介绍了一种不太冗长的方式来生成支线剧情,这种方式允许你以一种 语义方式 可视化地布局你的坐标轴。早先,你不得不使用相对更冗长的方法subplots()GridSpec。此外,您可以随意命名您的轴。

例如,要生成如下所示的网格,现在可以以列表的形式传递布局。缺失的支线剧情被标示为'.'。要将一个支线剧情跨越两列,重复名字,就像我对'bar'做的那样。若要跨行(垂直),请在第二个列表中垂直下方使用相同的名称。名字'bar''hist''scatter'也可以用来控制/修改相应支线剧情的属性。

这个功能挺酷很宽泛的,关于这个 复杂语义图构图 这里你要详细阅读。这个超链接还向您展示了其他简写的 ASCII 符号,以重新创建下图。

axes = plt.figure(constrained_layout=True).subplot_mosaic(
                [['.', 'bar', 'bar'], # Note repitition of 'bar'
                 ['hist', '.', 'scatter']])for k, ax in axes.items():
    ax.text(0.5, 0.5, k, ha='center', va='center', 
            fontsize=36, color='magenta')

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

使用 subplot_mosaic()生成的支线剧情。请注意跨越两列的扩展“条”。

创建后共享 x 轴和 y 轴

你现在也可以在不同的支线剧情中共享轴线,就像这里举例的。

2)设置轴框的纵横比

轴框 的 纵横比是轴的高度除以其物理单位的宽度。所以如果你需要一个正方形的盒子,盒子的长宽比为 1。现在,您可以通过如下所示的set_box_aspect()方法直接设置该比率。此处提供了该功能的几个使用案例。在下面的代码中,注释掉最后两行,以查看轴框纵横比的变化。

fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)ax1.plot(np.random.randint(0, 100, 1000), 'go')
ax2.plot([300, 900], [20, 55], 'g')ax1.set_box_aspect(1)
ax2.set_box_aspect(1)

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

盒子长宽比为 1 的支线剧情。

3)图例中的彩色标签

使用关键字参数labelcolor调用图例时,可以指定图例文本标签的颜色。默认情况下,它总是黑色的。

参见下面的示例,我将标签的颜色设置为标记面的颜色:

fig = plt.figure()x = np.linspace(0, 2*np.pi, 500)plt.plot(x, np.sin(x**2), '-o', c='orangered', mfc='b',
         lw=3, markevery=4, label=r'sin($x^2$)')plt.legend(fontsize=20, labelcolor='markerfacecolor',
           handlelength=1)

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

使用参数“labelcolor”将图例设置为标记颜色的图形。

Matplotlib 3.3 现在还提供了 Google AI 团队的 turbo colormap。

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

Matplotlib 3.3 中的 Turbo 颜色映射。

4)记号和标签

轴和颜色条标签的新对齐方式

现在,您可以在三个位置对齐 xy 轴标签。x-标签可以对准 x 轴的左侧、中间或右侧。类似地, y 标签可以在 y 轴的顶部、中心或底部对齐。这可以使用参数loc来完成。下面的例子说明了这一点:

plt.xlabel(r"$x$ (radians)", loc='right', fontsize=18)
plt.ylabel(r"sin($x^2$)", loc='bottom', fontsize=18)

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

一种图形,其各自的轴的右边标有 x,底部标有 y。

使用字符串和 lambda 函数设置刻度格式化程序

现在,在轴上设置刻度格式要简单得多。例如,您现在可以直接使用字符串函数作为字符串格式化程序的输入。下面的代码片段比较了使用字符串格式化的最新方式和旧方式。你可以清楚地看到最新的方法是多么简单。参见这个例子,了解 lambda 函数的类似用法。

import matplotlib.ticker as mticker# Plot the sinusoidal function# In latest version 3.3 
ax.xaxis.set_major_formatter('{x:.0f} rad')# Before version 3.3
ax.xaxis.set_major_formatter(mticker.StrMethodFormatter('{x:.0f} 
                             rad'))

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

x 轴上新字符串格式的演示。

5) rcParams 可以作为 Decorators 传递

这是一个真** 特色。现在你可以用定制的装饰器包装你的函数来控制你的绘图的参数。在下面的例子中,我用自定义的rcParams设置来装饰函数以绘制正弦曲线。**

from matplotlib import rc_context@rc_context({"lines.linewidth": 6, 
             'figure.facecolor': 'lightgreen',
             'legend.fontsize': 18})
def plot_sin(x):
    fig, ax = plt.subplots(figsize=(6, 4))
    ax.plot(x, np.sin(x**2), label=r'sin($x^2$)')
    ax.legend()
    returnplot_sin(x)

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

使用 rcParams 设置作为装饰器生成的图。

6) 3D 绘图现在支持次要刻度

到目前为止,还没有直接的方法在 3D 轴上启用次要刻度。现在你可以简单地使用关键字minor=True打开它们。改编官方示例,我在下面展示应用于 z 轴的该功能。

from mpl_toolkits.mplot3d import Axes3Dfig = plt.figure()
ax = fig.add_subplot(projection='3d')ax.scatter([0, 1, 2], [1, 3, 5], [30, 50, 70])ax.set_zticks([35, 45, 55, 65], minor=True)
ax.set_zticklabels([r'$\alpha$', r'$\beta$', r'$\delta$',
                    r'$\gamma$'], minor=True)ax.tick_params(which='major', color='r', labelcolor='r', width=5)
ax.tick_params(which='minor', color='b', labelcolor='b', width=3)

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

z 轴上带有次要刻度的 3D 绘图。

7)保存图形时指定后端

现在,您不需要在 Jupyter 笔记本的开头明确指定后端。您可以简单地将所需的后端作为参数 传递,同时使用后端关键字保存图形 。例如,如果您想用 pgf 后端保存 pdf 图形,您可以执行以下操作**

plt.savefig('/Users/Henry/Downloads/sinusoidal.pdf', backend="pgf")

你可以在 matplotlib 这里阅读更多关于后端的内容。

8)通过两点的无限长直线

现在你可以使用新引入的axline方法直接画出通过两点的无限长的线。有两种选择:要么明确指定两点并让系统计算斜率,要么指定一点和直线的斜率。以下示例显示了这两个选项的用法。

记住:关键字slope应该只能用于线性秤。对于所有的非线性刻度,你必须明确的通过两点。****

**fig, ax = plt.subplots(figsize=(6, 4))ax.axline((.4, .4), slope=5, color='r', label='using slope')
ax.axline((.3, .4), (.5, .6), color='b', label='using points')ax.legend(fontsize=18, frameon=False)**

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

在 Matplotlib 3.3 中使用 axline()方法绘制无限长的线

尽管最新版本 3.3 中引入了其他几个有趣的特性,但我会保持这篇文章的简短,并建议您参考阅读官方页面此处了解引入的变化的完整列表。

如果你有兴趣了解之前的 Matplotlib 版本 3.0、3.1 和 3.3 中的新功能,请阅读我之前的帖子Matplotlib 3 的新功能

人工智能视频流的最新技术进步

原文:https://towardsdatascience.com/latest-technological-advancements-in-video-streaming-with-ai-293d3b8b2a7e?source=collection_archive---------29-----------------------

回顾网飞等视频流媒体公司使用的最新技术。

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

照片由耶稣爱奥斯汀Unsplash

互联网上 85%的数据是通过视频消费的。大约 2.8 艾字节的数据通过流媒体视频在互联网上传输。这种增长是由网飞等视频点播平台、Zoom 等视频通信平台、Tiktok、电子竞技、直播等社交平台的出现推动的。

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

图片作者来自 Vadoo

Covid19 疫情加速了视频消费,并一直是公司从离线模式转向在线直播模式的驱动力。随着日常视频消费的爆炸式增长,我们需要为即将到来的需求做好准备。

在本文中,我们将讨论视频流技术的最新进展,以及它们如何帮助改善流体验。

超分辨率

人工智能已经颠覆了各种行业,视频流也不例外。AI 模型可以通过从大量图像中学习,学习如何从低分辨率图像生成高分辨率图像。这种从低分辨率图像生成高分辨率图像的方法称为超分辨率

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

来自 Kaggle创作者的图片

超分辨率属于生成算法领域,该算法能够生成以前没有的信息。从上图中可以看出,网络可以从左侧获取图像,并想象更精细的细节来重新创建右侧的图像。这是可能的,因为人工智能模型已经在大量图像数据上接受了训练,现在它知道如何在提供新图像时放大图像。

同样的概念可以扩展到稍加修改的视频。在视频的情况下,过去的多个生成的高分辨率帧和当前的低分辨率帧一起用于生成当前的高分辨率帧,但是概念是相同的。这项技术提供了以 480p 发送视频,但在客户端设备上以 1080p 观看的能力。

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

图片来自论文作者作者

由于深度学习的最新进展和客户端设备巨大计算能力的可用性,这项技术是可能的。最近的一篇论文 TecoGAN 产生了高分辨率的结果,与现实世界的图像惊人地相似,如上图所示。使用这项技术可以节省高达 30%的带宽消耗,从而改善整体用户体验。

P2P 流媒体

视频流遵循客户端-服务器模型。内容从称为 CDN 的边缘位置传送,CDN 缓存来自服务器的内容。客户端设备,即手机/笔记本电脑/电视,从这些 CDN 获取内容,开始播放您的视频。通过 CDN 的视频流有一些限制,如下所述

  1. 使用 CDN 的视频流是昂贵的
  2. 收视率高峰导致高缓冲
  3. 由于 CDN 覆盖不佳,向远程位置交付内容

由于这些原因,视频流公司很难有效地扩展其服务并提供良好的用户体验。所有这些问题都可以通过使用 P2P 流媒体扩展 CDN(即混合 CDN)来解决

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

图片作者来自论文

在传统 CDN 上添加对等层,通过分发来自相邻对等体的内容来减少主 CDN 的负载,这些对等体本身就像一个 CDN,从而使边缘更接近用户。由于 CDN 上的负载减少,费用现在将减少 40%,同时用户体验也由于较低的重新缓冲而得到改善,因为内容是从附近的对等点而不是远处的 CDN 获取的。关于这项技术如何工作的更多信息可以在这里找到。

使用 Vadoo 缩放您的视频流

多 CDN

我们已经看到,内容通过 CDN 传送到客户端设备,CDN 缓存来自服务器的内容。CDN 由位于多个位置的数据中心组成,提供内容服务。这些位置被称为接入点(POP)。理想情况下,我们希望有尽可能多的 POP。但并不是所有的 CDN 在全球范围内都有同等的影响力。例如,一些最受欢迎的 CDN 在中国甚至没有一个 POP。

另外,每个 CDN 的性能都是随时间变化的,不一致。根据墨菲定律,CDN 可能会在任何时间点发生故障。为了应对所有这些风险,理想的选择是同时接入多个 CDN。这可以通过联系多个 CDN 并单独与它们中的每一个达成交易来实现,也可以通过联系为您管理所有这一切的多 CDN 提供商来实现。

使用多 CDN 为您的视频流服务提供支持,为您提供有助于改善整体用户体验的优势。

  1. 通过切换到工作的 CDN 来防止服务突然停止
  2. 使用实时用户监控(RUM)指标从当时性能最高的 CDN 获取内容,以提高服务质量(QOS)
  3. 中游交换有助于降低 CDN 成本

CMAF

直播体育比赛会比电视广播延迟 25-30 秒,从而影响用户体验。这是由于视频流技术的设计方式。流式传输视频的最主要方式是基于 HTTP 的流式传输,其中视频内容通过以下步骤传送

  1. 视频使用编解码器(如 h264)进行编码,以减小视频文件的大小
  2. 然后,视频被转换成可流式传输的格式,如 HLS 或 MPEG-DASH
  3. 来自服务器的内容现在通过 CDN 分发
  4. 视频播放器在开始播放之前会缓冲一些视频片段

HLS 或 MPEG-DASH 允许分段发送视频,由视频播放器顺序下载。一个片段通常包含大约 10 秒钟的视频。编码器必须等待对视频的整个片段进行编码,然后才能将其用于 CDN。CDN 必须等待接收完整的视频片段,然后才能将其传递给视频播放器。视频播放器必须在开始播放之前缓冲至少几段视频,以保持用户体验。

整个过程会导致 25-30 秒的延迟。此外,由于存在多种格式,即 MPEG-DASH 的 ts fr HLS 和. mp4,因此需要双倍的存储、双倍的编码和双倍的 CDN。CMAF 试图解决上述两个问题。

CMAF 提供了 HLS 和 MPEG-DASH 都支持的一致格式的片段 mp4(fmp4)。它还具有进行分块传输编码的能力。这意味着,编码器在传输之前不会等待整个视频片段。该段被进一步分成更小的块,并且这些块在被编码时被发送,该编码由 CDN 以不特定的顺序传递给编码器。视频播放器负责组织数据块并播放视频片段。

因此,CMAF 有助于减少编码和存储成本,以及减少使用分块传输编码的延迟。

按标题编码

视频编码是使用 H.264 等编解码器压缩视频的过程,这些编解码器利用连续帧中存在的公共信息,因此只在帧中存储新添加的信息。为了应对各种网络条件和多变的互联网连接,视频内容以多种分辨率进行编码,并进行智能切换。这种技术被称为自适应比特率(ABR)。

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

图片来自网站

下图描述了多种分辨率和相应的比特率分配。这里要注意的关键因素是,相同分辨率的内容可以以多种比特率编码,即 1920 x 1080 的视频可以以 5800 mbps 或 6800 mbps 甚至 4800 mbps 的速率编码。这是因为视频压缩是有损压缩,因此选择的比特率越小,压缩视频中可用的信息就越少。这可以在编码伪像中观察到,类似于您在流媒体平台上观看视频时观察到的上图。

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

图片来自网飞博客的作者

既然我们知道可以使用不同的比特率对特定分辨率的视频进行编码,那么在现实世界中,可以选择理想的通用比特率,以便在不消耗大量带宽的情况下减少伪像。上图显示了为所有视频选择的通用带宽模式。但是这种一刀切的方法有一个问题。诸如高辛烷值动作电影的一些视频可能具有丰富的信息,因此可能需要更高的比特率来编码,而简单的卡通视频甚至可以用更低的比特率来执行。

因此,网飞建议以多种比特率对特定的视频分辨率进行编码,然后选择最佳比特率来呈现没有伪像的视频。这是使用称为 VMAF 的度量来完成的,VMAF 是识别渲染视频质量的视觉分数。在此帮助下,可以为每个视频设计定制的比特率阶梯。因此,如果我们正在流式传输卡通视频,它可以以较低的比特率发布,同时仍然具有类似的质量,而动作电影可以以较高的比特率发布,没有任何伪像,从而改善用户体验。

摘要

总而言之,我们已经看到了多种有助于扩展、改善用户体验和减少视频流延迟的技术。5G 和虚拟现实(VR)和增强现实(AR)世界的到来以及电子竞技的兴起将使视频带宽消耗飙升。因此,是时候采用最新技术来跟上并服务于这种增长了。

面向数据科学家的乳胶,不到 6 分钟

原文:https://towardsdatascience.com/latex-for-data-scientists-in-under-6-minutes-3815d973c05c?source=collection_archive---------25-----------------------

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

背景图片:不飞溅

任何数据科学简历的必备技能

作为一名数据科学家,你与数据打交道。数据本质上是数学的——你必须能够清楚地表达这些想法。即使您没有开发算法,表达常见数据科学技术的能力——可能是多项式回归或 box-cox 变换的结果——也是必不可少的。

也就是说,LaTeX,这种最流行的数学排版语言,有很多很多多余的东西。本教程将只展示 LaTeX 中与数据科学相关的最重要的部分,到最后,您将对 LaTeX 有足够的了解,可以将它结合到您的项目中。

这是乳胶,在 6 分钟或更短的时间内。最后是 5 道练习题。

显示数学

要在文本中显示数学,表达式必须在美元符号之间。

In physics, the mass-energy equivalence is stated  by the equation $E=mc^2$, discovered in 1905 by Albert Einstein.

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

或者,可以使用打开和关闭\[\]

The mass-energy equivalence is described by the famous equation\[E=mc²\]

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

这将自动使数学居中并显示在新的一行上。

下标和上标

下标用 _,上标用^.$a^2$将输出。上标也可以通过连续调用与下标组合:

\[ a_1^2 + a_2^2 = a_3^2 \]

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

对于更长的上标和下标,将上标和下标放在括号中可以清理代码:

\[ x^{2 \alpha} - 1 = y_{ij} + y_{ij}  \]

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

注意——LaTeX 有许多符号可以用\name来调用。在上面的例子中,使用了\alpha。其他的还有\infty,是无穷大的符号。

上标和下标也可以以多种方式嵌套和组合,只要用括号明确指定范围:

\[ (a^n)^{r+s} = a^{nr+ns}  \]

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

许多数学运算符需要下标或/和上标。在这些情况下,运算符被视为具有正常上标和下标属性的对象。以 sigma/summation 操作符为例,这个操作符由\sum调用。

\[ \sum_{i=1}^{\infty} \frac{1}{n^s}  
= \prod_p \frac{1}{1 - p^{-s}} \]

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

即使使用 sigma 操作符对常规对象调用上标和下标,它也会自动对齐。

另外需要注意的是——当使用[ and ]开始和结束指示符时,所有内容都放在一行中,所以放在几行中的代码不会影响最终结果。

对上标和下标进行操作的其他运算符包括:

  • \int对于积分
  • \cup用于联合(朝上 u)
  • \cap对于交叉点(朝下 u 形)
  • \oint对于曲线积分
  • \coprod为联产品

经营者

三角函数、对数和其他数学函数可以取消斜体,并通过在前面加一个\来格式化。

\[ 
\sin(a + b ) = \sin(a)\cos(b) + \cos(a)\sin(b) 
\]

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

有些运算符可以通过下标接受参数,比如 limit 运算符。

\[ 
\lim_{h \rightarrow 0 } \frac{f(x+h)-f(x)}{h} 
\]

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

注意一个极限声明是如何包含一个下标和一个符号\rightarrow的调用的。\frac{a}{b}是一种创建分数的方法a/b

分数和二项式

为了让本节中的一些命令生效,您必须首先在文件的开头包含amsmath包。

\usepackage{amsmath}

分数和二项式系数非常简单。它们被称为\name{parameter1}{parameter2}

\[     
\binom{n}{k} = \frac{n!}{k!(n-k)!} 
\]

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

当分数被内联使用时,它们的显示方式会有所不同。

Fractions can be used alongside the text, for  example $frac{1}{2}$, and in a mathematical  display style like the one below:\[\frac{1}{2}\]

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

通过使用分数作为参数,可以很容易地嵌套分数。

\[   
a_0+\cfrac{1}{a_1+\cfrac{1}{a_2+\cfrac{1}{a_3+\cdots}}} 
\]

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

上面的命令使用了来自amsmath包的\cfrac{}{},它保持片段的大小不变,即使它们是嵌套的。这可以用\frac{}{}来代替,这会让嵌套的分数变小。

括号和圆括号

LaTeX 支持多种类型的支架:

  • (x+y)渲染( x + y )
  • [x+y]渲染[ x + y ]
  • \{ x+y \}渲染{ x + y }
  • \langle x+y \rangle渲染⟨ x + y
  • |x+y|渲染| x + y |
  • \| x+y \|渲染∩x+y

有时,括号和圆括号对于表达式来说太小,例如,如果它有分数。

动态圆括号和括号由\left[object]\right[object]命令操作,表示开始和结束。

\[  
F = G \left( \frac{m_1 m_2}{r^2} \right) 
\]

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

在这种情况下,[object]是一个括号,所以表达式被包含在\left(\right)中。[object]也可以用括号代替(\left[\right])。

矩阵

这个amsmath包包含了许多排版矩阵的命令。

一个矩阵由几个值定义,每行由&分隔,每行由一个\\分隔。它包含在标准的\begin{object}\end{object}中。

对于没有侧括号的简单矩阵:

\begin{matrix}
1 & 2 & 3\\
a & b & c
\end{matrix}

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

{pmatrix}替换\begin{matrix}\end{matrix}中的{matrix},将括号括在矩阵周围:

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

{bmatrix}用括号括起来:

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

…然后{Bmatrix}用花括号把它括起来。

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

实践

现在,你有了乳胶的基本技能。找到将创建给定输出的代码。

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

解决方法

#1(损失):

\[
Loss = Bias^2 + Variance^2 + Noise
\]

#2(卡方检验):

\[
Chi 
= \frac{(\hat(y)-y)^2}{\sqrt{y}}
= \frac{\delta^2}{\sqrt{y}}
\]

第三名(KNN):

\[
\hat(f)(x)
\leftarrow \frac{\sum f(x)}{k}
\]
\[
DE(x_i,x_j) = \sqrt{(x_i-x_j)^2 + (y_{xi}-y_{xj})^2}
\]

#4(乙状结肠):

\[
\frac{1}{1+e^{-(wx+b)}}
\]

#5 ®:

\[
R^2 = \frac{n \sum xy - \sum x. \sum y}{\sqrt{(n \sum x^2 - (\sum x)^2). (n \sum y^2 - (\sum y)^2)}}
\]

结论

在本教程中,您学习了…

  • 如何内联和单独格式化数学
  • 如何使用上标和下标,以及运算符
  • 如何呼叫特定的接线员
  • 如何使用圆括号和方括号,包括动态的
  • 如何创建带有各种侧括号样式的矩阵

现在你可以漂亮地格式化数学了!从现在开始学习 LaTeX 的大部分内容是记忆某些对象的代码(\object),因为你现在已经知道 LaTeX 的基本结构。

如果您喜欢这篇文章,您可能也会对本系列的其他文章感兴趣:

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

继续并点击“添加”。

使用 GitHub 页面,通过 5 个简单的步骤免费创建一个网站

原文:https://towardsdatascience.com/launch-a-website-for-free-in-5-simple-steps-with-github-pages-e9680bcd94aa?source=collection_archive---------23-----------------------

不到 10 分钟就能在网上建立你的个人投资组合网站。

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

尼古拉斯·皮卡德在 Unsplash 上拍摄的照片

拥有自己的网站可以让你向世界展示你是谁,以及你热爱什么。

许多人认为,对于普通人来说,建立一个网站成本太高,或者技术难度太大。实际上,它根本不需要花费任何成本,任何人都可以完成——不管经验水平如何——并且可以在 10 分钟内启动并运行!(可以查看我的这里)

GitHub Pages 是 GitHub 的一个特性,它允许用户直接从存储库中托管静态网页。这是托管个人投资组合网站、展示项目或为小型组织托管其页面的理想选择。在这篇文章中,我将展示对于任何人来说,通过 GitHub 页面建立一个网站是多么简单。

步骤 1 —创建 GitHub 帐户

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

如果您已经有一个 GitHub 帐户,可以跳过这一步。如果没有,可以 报名这里

在整篇文章中,我尽量不假设您已经掌握了相关知识,但是如果您以前从未使用过 Git,我建议您熟悉 Git 概念。本文从完整的基础知识开始,对 Git 和 GitHub 进行了很好的介绍:

[## Git 和 GitHub 入门:完全初学者指南

Git 和 GitHub 基础知识,供好奇和完全困惑的人使用(加上最简单的方法来为您的第一次公开…

towardsdatascience.com](/getting-started-with-git-and-github-6fcd0f2d4ac6)

步骤 2-为你的网站创建一个存储库

资源库是存储项目所有代码的地方,或者如 GitHub 的帮助页面所解释的:

“存储库就像是项目的文件夹。项目的存储库包含项目的所有文件,并存储每个文件的修订历史。您还可以在存储库中讨论和管理您的项目工作。” GitHub 帮助

因此,要开始我们的项目,我们需要做的第一件事是为我们网站的代码创建一个存储库。现在我们有了一个 GitHub 帐户,这很容易做到。只需导航到 GitHub 主页的右上方,在“+”菜单下,选择“ New Repository ”。

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

添加新的存储库

这将打开“创建新存储库”页面,我们可以在其中选择存储库名称,并选择我们的存储库是“*公共”*还是“私有”。重要的是,我们给这个存储库一个特定的名称,这样 GitHub 就知道这个存储库应该通过 GitHub 页面托管。这个应该是[your_username].github.io。例如,因为我的 GitHub 用户名是 emilegill743,所以我的存储库名称——我们稍后将看到我的网站 URL——将是 emilegill743.github.io 。我们还希望将我们的存储库设置为“Public”,因为如果我们升级到 GitHub Pro,GitHub Pages 只允许托管“ Private ”存储库。

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

为我们的 GitHub 页面网站创建一个存储库

一旦我们完成了这些,GitHub 将带我们到我们新创建的存储库,并解释我们可以开始使用存储库的本地副本的几种方法。如果您不熟悉在命令行上使用 Git,将这个空存储库"克隆到您的本地系统的最简单的方法是使用在桌面中设置的""选项。这将打开 GitHub Desktop——可以在这里安装——在您选择的位置创建一个存储库的本地副本。现在,在您的本地文件系统上将会有一个以您的存储库命名的空文件夹,它将会跟踪我们所做的任何更改。然后,这些更改可以被“提交”和“推送”到我们在 GitHub 上的远程存储库。**

第三步——选择你的网站设计

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

https://html5up.net/上提供的模板

现在,如果你是铁杆,你可能想从头开始设计你的网站。理论上,你可以这样做;我们所需要的只是我们的远程存储库中的一个index.html文件,GitHub 将继续渲染我们的网站。然而,由于这篇文章的目的是让我们的网站尽快建立并运行,我们将使用一个模板来开始。这将使我们能够以最少的工作量创建一个时尚、响应迅速、专业的网站。

有许多网站提供网站设计的模板,有些可以花很少的钱购买,但许多是免费的。我特别喜欢的是 HTML5 UP ,它提供了一系列漂亮的设计,非常适合个人作品集网站。在知识共享署名 3.0 许可下,所有的设计都是免费的,这意味着我们可以随心所欲地使用它,只要我们为设计归功于 HTML5。

随意自己做研究,找到最适合自己的设计;为了演示,这里我用 HTML5 UP 的地层主题

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

Strata by HTML5 UP!

第 4 步—推送至 GitHub

既然我们已经选择了我们的设计,我们可以下载它的相关文件,并将它们转移到我们的本地存储库中。然后,我们可以提交我们的更改,并将其推送到我们的远程存储库。同样,如果你习惯使用 Git,可以通过命令行来操作,但是如果你是新手,你可以使用 GitHub Desktop。

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

推送至 GitHub

这就是奇迹发生的地方。打开网络浏览器并导航至 URL [your_username].github.io

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

我们的网站上线了!现在让我们看看如何添加最后的润色和个性化,现在它只是一个模板。

第五步——定制你的网站

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

对于这最后一步,我们需要一个文本编辑器。如果你是一个编程专家,你可能已经有了一个文本编辑器。任何都可以,但我个人推荐 Visual Studio 代码,你可以在这里安装。

在我们的文本编辑器中打开包含我们的存储库的文件夹,我们将看到所有有助于我们网站设计的文件。其中最重要的是我们的index.html文件,它表示我们网站主页的结构。可能还会有一些.css文件,也可能有一些.js。如果你不熟悉这些,不要太担心,当我创建我的第一个网站时,我并不熟悉!一个基本的总结是,HTML(超文本标记语言)构成了网页结构的构建模块,CSS(层叠样式表)描述了网页的样式,Javascript 定义了网页的交互行为。

我建议的第一件事是你下载 Visual Studio 代码的‘Live Server*’*扩展,这将使我们能够在编辑网站时预览它,当我们保存更改时会自动刷新。或者,您可以在 web 浏览器中打开index.html页面,手动刷新以检查更改。

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

VS 代码的实时服务器

关于如何编写 HTML,我不会讲太多细节,否则,这很快就会变成一个教程。基本语法由构成 HTML 元素的’标签组成,HTML 元素是 HTML 网页的构建块。这些标签通常由开始标签、标签的任何属性、一些内容和结束标签组成。

*<tag attribute="value">Some content</tag>*

你想在多大程度上定制你的网站取决于你自己。在最基本的层面上,你需要改变网页中 HTML 元素的内容来反映你的个人信息。您可能还想更改网页中的图像。要做到这一点,你需要做的就是把你想要使用的图像复制到你的存储库中(如果你使用的是 HTML5 UP 模板,它可能已经有一个为图像指定的文件夹),然后修改图像元素的src属性来反映你的新图像<img src="path_to_image.jpg"/>的路径。这里值得注意的是,图像元素由包含其属性的单个标签组成,而不是像许多其他 HTML 元素那样由开始和结束标签组成。

如果你有兴趣学习更多关于 HTML、CSS 和 JavaScript 的知识,这样你就可以让你的网站个性化更上一层楼,我强烈推荐哈佛的 CS50W : 用 Python 和 Javascript 进行 Web 编程 。这是一门关于 edX 的完全免费的课程,它的前几章主要关注 Git、HTML 和 CSS,之后会继续关注 Javascript。它很好地介绍了让网站真正成为我们自己的网站所需的技巧。

要获得更多灵感,请随时查看我的网站 emilegill743.github.io 和下面链接的相应 github 库。

* [## Emile gill 743/Emile gill 743 . github . io

我的个人作品集网站,通过 GitHub 页面托管,基于 HTML5 UP 的 Strata 主题。…

github.com](https://github.com/emilegill743/emilegill743.github.io)

感谢阅读!*

如果你喜欢这篇文章,可以看看我的其他文章:

* [## 聪明的方法是找到一个杂货递送点

使用 Python、Heroku 和 Twilio 从一个杂货网站的 API 中抓取数据,并在出现插槽时获得文本通知…

towardsdatascience.com](/finding-a-grocery-delivery-slot-the-smart-way-f4f0800c4afe) [## PostgreSQL 入门实用指南🐘

Python 的 PostgreSQL、pgAdmin 和 SQLAlchemy 入门。将 SQL 融入 Python 的核心…

towardsdatascience.com](/a-practical-guide-to-getting-set-up-with-postgresql-a1bf37a0cfd7)*

在几分钟内,在浏览器中启动您自己的人脸识别应用程序(实时)

原文:https://towardsdatascience.com/launch-your-own-real-time-face-recognition-algorithm-in-your-browser-in-minutes-beginner-guide-a8f2e6fd505c?source=collection_archive---------24-----------------------

用 Face API 和 Docker 实现基于 JavaScript 的人脸识别

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

三二一…发射!

如果您想自己实现它,请跳到下面的实现部分。

如果你只是想玩一个没有任何编码的实时人脸识别算法,可以运行下面这个 Dockerized web app:

docker run -p 8080:8080 billyfong2007/node-face-recognition:latest

这个 Docker 命令将从 Docker Hub 运行 Docker 映像,并将容器的网络端口 8080 绑定到您的计算机。您可以在浏览器中访问面部识别算法,方法是:

localhost:8080

该网页将访问你的笔记本电脑的摄像头,并开始实时分析你的表情!

不要担心,这完全脱机工作,你将是唯一一个可以查看视频流的人…假设你的计算机没有受到损害。

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

无论如何,你可能会开始像一个傻瓜一样在电脑前做各种有趣的表情(或者悲伤/愤怒等)!

履行

这个算法消耗了建立在 tensorflow.js 核心 API 之上的 Face API 。你也可以训练这个算法来识别不同的人脸。

对于那些还在阅读的人来说,也许您想知道如何构建自己的节点应用程序来使用 Face API?好了,我们开始吧:

你可以在我的 GitHub Repo 里找到所有的源文件。

首先,你需要安装 NPM 的实时服务器来服务你的 HTML:

npm install -g live-server

构建一个名为 index.html: 的准系统 HTML 页面

这个 HTML 包含一个视频元素,我们将使用它来传输您笔记本电脑的网络摄像头。

然后用以下内容创建 script.js :

该脚本做了几件事:

  1. 从目录异步加载所有模型
  2. 请求访问您的网络摄像机的权限
  3. 一旦视频开始流,创建一个画布,并调用 Face API 每 100ms 在画布上绘制一次。

需要的机器学习模型可以从我的 GitHub Repo 下载:

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

一旦你准备好了 index.html、script.js 和模型,你就可以开始了。您仍然需要包含 face-api.min.js,您的应用程序才能开始工作:

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

现在你准备好了!开始使用 live-server 服务您的 HTML 页面:

cd /directory-to-your-project
live-server

这个简单的 JavaScript 项目让我体验了 ML,我希望我能做更多,但我不确定这个算法在现实生活中会有什么实际用途。你怎么想呢?

页(page 的缩写)s:这是我的第一篇媒体文章,如果你认为这篇文章需要进一步澄清,请告诉我!😃

使用 Flask & Python 在 7 分钟内启动您自己的 REST API

原文:https://towardsdatascience.com/launch-your-own-rest-api-using-flask-python-in-7-minutes-c4373eb34239?source=collection_archive---------19-----------------------

下面的文章介绍了使用 Python、Flask 和 Sqlite3 开发 REST API

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

1.简介:

应用程序编程接口(API)被定义为处理两个或更多中介(通常是用户和数据库之间)之间的交互的接口。更常见的是,大多数被访问的网站、被玩的视频游戏、甚至是被流式传输的视频都涉及到被利用的某种级别的 API。作为数据科学家,我们经常使用 API 来检索信息,如股票价格、文章或其他类型的信息。数据科学家通常会发出 HTTP 请求,这通常会导致数据以 JSON 文件的格式返回。

表述性状态转移(REST)类型的 API 是一种架构风格,它使用 HTTP 请求来获取、上传、发布和删除数据(图 1)。作为用户,当使用诸如 Postman 之类的软件或者诸如 Requests 之类的普通 Python 库来发出 HTTP 请求时,我们经常会体验到 API 的客户端。然而,对于大多数 Python 开发者来说,API 函数的底层框架仍然是一个“黑箱”。本文的目的是通过使用 Flask 框架从头开发一个 API 来探索这一领域。

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

图 1:REST API 的主框架,其中 API 的客户端允许使用 GET、POST、DELETE 和 PUT 方法添加和删除数据。

2.REST API 的基础:

REST API 背后的主要结构由三个关键项目组成:(url 和端点,(2)方法,以及(3)数据。当客户机针对 API 发出 HTTP 请求以检索数据时,必须设计的第一项是 URL。URL 通常包含站点域、一系列目录层次结构,最后是端点,通常遵循图 2 所示的结构。

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

图 HTTP 请求 URL 的一般结构。

使用 REST API 发出请求时,通常使用四种主要方法:GET、POST、PUT 和 DELETE。虽然这些方法大多是不言自明的,但主要的好处是可以使用这些方法从任何给定的数据库中检索、添加或删除数据。GET 请求是最常见的请求类型,主要用于从服务器或数据库中检索数据。POST 请求用于向 API 发送数据,以便创建或更新条目。与 POST 类似,PUT 请求用于向 API 发送数据,以便创建或更新条目,但是,PUT 请求是等幂的,这意味着可以多次应用该方法,而不会改变最终结果。最后,删除请求用于删除数据库中的某些条目。下面的图 3 总结了 REST API 背后的主要方法,使用了一个关于每个请求的示例解释命令。

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

图 3:REST API 背后的四个主要方法,以及一个以职位发布为例总结功能的示例语句。*请注意,PUT 方法类似于 POST 方法,但是它们是等幂的,多次调用相同的请求将产生相同的结果。另一方面,POST 请求是非等幂的,发出相同的请求可能会导致意外的结果。

最后,构成 API 的最后一项是要查询的实际数据,可以是从小的 CSV 文件到大的关系数据库。出于本文的目的,我通过转换一个示例 CSV 文件,使用 Python 的 sqlite3 库创建了一个数据库。

3.准备数据库:

出于本文的目的,我们将使用一个关于 CS 和数据科学职位的职位发布数据集来创建一个 API。现在让我们继续使用 sqlite3 库创建一个数据库。出于本文的目的,为了简单起见,我们将坚持使用 s qlite3 库,然而,生产级数据库应该利用 MySQLPostgreSQL 来获得最大效率,这两者在 AWS 等云服务器上都很容易获得。我们从 sqlite3 开始,创建一个允许我们创建新的 sqlite3 连接的函数。这里的主要目标是准备一个函数,通过创建一个连接来创建一个新的数据库文件。

def createSqliteConnection(database):
    """ 
    Function that creates a connection to a sqlite3 database file.[@param](http://twitter.com/param) database -- The path and name of the database file to connect to.
    """
    conn = None
    try:
        print("----------Attempting to connect to database using Sqlite3 version {version} ...".format(version = sqlite3.version))
        conn = sqlite3.connect(database)
        print("----------Successfully to connected to {database}".format(database = database))except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()

创建数据库后,现在可以直接从 CSV 导入数据。

def pandasToDatabase(csvDocument, database, tableName):
    conn = sqlite3.connect(database) 
    df = pd.read_csv(csvDocument)
    df.to_sql(tableName, conn, if_exists = "append", index = False)

两个函数都完成后,我们现在可以继续执行这些函数:

if __name__ == '__main__':
    createSqliteConnection("data/datasciencejobs_database.db")
    pandasToDatabase("data/datasciencejobs_database.csv", "data/datasciencejobs_database.db", "tblJobs", )

这将导致创建一个名为:

data/datasciencejobs_database.db

现在创建了主数据库文件,我们现在能够使用 API 直接从数据库中查询数据,从而避免了 CSV 的使用。这允许更快和更干净的连接。

4.创建 Flask 应用程序:

针对 API 的 Flask 应用程序的后端开发不同于大多数用户熟悉的标准的基于 GUI 的 web 应用程序。从高层次的角度来看,主要的区别可以总结在图 4 中。两者之间的主要区别在于,由于必须考虑图形用户界面,标准 web 应用程序的重点转向了 HTML 和布局功能。另一方面,API 的主要关注点是信息的路由和流动。

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

图 flask 应用程序用于 API 时相对于标准 web 应用程序的一般高层次比较。

我们通过在 app.py 文件中定义我们的“app”并创建一个 Flask 应用程序来开始这个过程。

app = flask.Flask(__name__)
app.config["DEBUG"] = True

然后,我们必须创建几个函数,当在 URL 中采用某些路线时,这些函数会显示数据。让我们从一个简单的’ view all’ 函数开始,它显示数据库中的所有条目。请注意,我们使用的是上面指定的 GET 方法。

@app.route('/api/v1/jobs/datascience/all', methods=['GET'])def apiViewAll():
    conn = sqlite3.connect('data/datasciencejobs_database.db')
    conn.row_factory = dictFactory
    cur = conn.cursor()
    all_books = cur.execute('SELECT * FROM tblJobs;').fetchall()
    return jsonify(all_books)

启用此功能后,最终用户现在能够查询我们数据库中的所有数据。目前,这还不是问题,因为数据库包含的条目不超过 1000 个,但是,随着数据库的增长,最终用户需要等待很长时间才能访问整个数据库,这将成为更大的问题。也就是说,任何 REST API 的高效设计的一部分是基于预定的文件服务器查询数据的能力,以便查询数据库的某些部分。假设数据库由列’ id '、 datetime '、 country ‘和’ content ‘组成,一个“最佳设计”的 API 将允许用户使用前三个参数来查询数据。必须开发一个函数,允许通过指定’ id '、日期时间’或’国家’来使用多个端点过滤数据。请注意,如果没有指定任何条目,将发出错误 404 页面未找到。

@app.route('/api/v1/jobs/datascience', methods=['GET'])def apiViewByFilter():
    '''
    Function that allows users to filter the results in the API     based on specified input.
    '''
    query_parameters = request.args
    id = query_parameters.get('id')
    dateTime = query_parameters.get('dateTime')
    cleanContent = query_parameters.get('cleanContent')
    country = query_parameters.get('country')
    query = "SELECT * FROM tblJobs WHERE" to_filter = []
    if id:
        query += ' id=? AND'
        to_filter.append(id) if dateTime:
        query += ' dateTime=? AND'
        to_filter.append(dateTime) if cleanContent:
        query += ' cleanContent=? AND'
        to_filter.append(cleanContent) if country:
        query += ' country=? AND'
        to_filter.append(country) if not (id or dateTime or cleanContent or country):
       return pageNotFound(404) query = query[:-4] + ';'
    conn = sqlite3.connect('data/datasciencejobs_database.db')
    conn.row_factory = dictFactory
    cur = conn.cursor() results = cur.execute(query, to_filter).fetchall() return jsonify(results)

最后,现在完成了 API 的所有部分,可以使用 Flask 的运行功能运行应用程序。

app.run()

API 中指定的三个主要端点允许用户查询所有数据,或者基于“id”、“国家”和“日期时间”。

例如,用户可以使用以下方式查询所有数据:

‘127.0.0.1:5000/api/v1/jobs/datascience/all’

用户还可以使用其中一个端点来查询数据:

‘127.0.0.1:5000/api/v1/jobs/datascience?country=United%20States’
‘127.0.0.1:5000/api/v1/jobs/datascience?id=81953194’

5.部署 Flask 应用程序:

API 完成并按预期运行后,下一个逻辑步骤是将应用程序部署到服务器。出于本教程的目的,API 是使用本地端口在本地“部署”的。部署基于 Flask 的应用程序的一些最佳选项包括: AWSHerokuPythonAnywhere 。在探索了这三个版本之后,我个人发现www.pythonanywhere.com是这三个版本中最用户友好和最便宜的,拥有关于部署过程的全面的文档

结论:

总之,为了理解管理这个功能的主要框架,我们对 REST APIs 进行了概述。为了存储我们感兴趣的数据,创建了一个 SQL 数据库。最后,使用 Flask 使用 REST APIs 的最佳实践开发了一个 API,允许用户通过多个端点查询数据。

欲了解更多信息和访问代码,请访问 my GitHub

我们如何利用 AWS 在 60 天内推出数据产品

原文:https://towardsdatascience.com/launching-beta-data-product-within-two-month-with-aws-6ac6b55a9b5d?source=collection_archive---------11-----------------------

新闻捕手

两个人的团队在不到两个月的时间里为 200 名用户计划并发布了一个测试版,并且没有放弃他们的全职工作。

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

测试版 newscatcherapi.com 解决方案架构

60 天内,我们:

  • 迭代我们的架构设计 3 次
  • 发布的 Python 包在 GitHub 上获得了 800 多颗星
  • 收到了 200 多个测试版的注册
  • 交付了我们的最小可行产品

这篇文章中我将要谈到的产品的官方网站

在本文中:

  • 第一部分产品
  • 第二部分。计划&要求
  • 第三部分。解决方案架构
  • 第四部分。发布测试版

我们是由两名数据工程师组成的团队。在 2020 年 2 月和 3 月,我们将大部分空闲时间用于构建一个 API,让你可以搜索新闻文章的数据。

这就像用一行代码查询谷歌新闻档案。

我们之前几乎没有使用 AWS 或交付成功的端到端解决方案的经验。尽管如此,正确的规划、寻求帮助和投入一些时间来寻找正确的工具使之成为可能。

尽管这是一个测试版。

我们遵循的原则

在业务方面:

  1. 尽可能多地使用外部工具
  2. 尽可能快地交付,以便尽快获得用户的反馈
  3. 用户至上。他们应该决定什么重要,什么不重要

在技术方面:

  1. 尽量减少使用您必须自己运行的服务器
  2. 如果已经编写了代码,就不要再编写了
  3. 只有当客户无法使用您的解决方案时,性能才是重要的
  4. 请求帮助

第一部分.产品

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

何塞·马丁·拉米雷斯 C 在 Unsplash 上拍摄的照片

问题

我们大多数人阅读新闻。当我们为了个人兴趣消费新闻时,很容易跟随我们感兴趣的事情。

许多企业还必须不断了解全球的最新动态。典型的例子是金融机构。他们使用替代数据来识别非金融活动产生的风险。

政治、文化和社会事件可能引发另一系列事件,重塑某些金融市场。

当然,你可以谷歌任何关键词或话题,找到最相关的新闻结果。但是,假设你是一个交易者,想要了解投资组合中每家公司的最新消息。每小时一次。

https://www.gifbay.com/gif/newspaper_press-130154/

或者,你必须分析一个人/公司/事件在过去的一个月中被提及了多少次。

或者,您希望向服务的用户显示特定主题的最新新闻。

从某种意义上来说,**手工劳动要么变得不可能,要么变得过于昂贵。**成千上万的新闻文章需要分析。如果你想扩大规模,你必须自动化这个过程。

解决办法

Newscatcher AP I 是一个 JSON API,可以让你搜索新闻数据。例如,您想获得在过去一天发表的关于苹果公司的所有文章的列表。

对于每个数据记录,您将获得:

  • 相关性分数(文章与搜索标准的匹配程度)
  • 统一资源定位器
  • 发布日期和时间
  • 标题
  • 摘要
  • 文章语言
  • 网站的全球排名

我们从数以千计的新闻网站收集新闻文章数据,更重要的是,将这些数据标准化。

是数据即服务吗?

Auren Hoffman 的《数据即服务圣经》是任何想要了解什么是数据业务的人的必读之作。

根据 Auren 的愿景,数据业务有 3 大支柱:

  1. 数据采集 —我们必须从数千家不同的在线新闻发布商那里收集新闻
  2. 数据转换 —我们必须规范化我们的数据并存储它,以便它可以被数据交付流程使用
  3. 数据交付 —我们必须让客户能够消费我们的数据(例如,API)

DaaS 卖给你的是材料,而不是解决方案本身。**你必须根据自己的需求调整数据以提取价值。**因此,潜在客户池减少到那些拥有数据团队作为资源的人。但是,那些拥有开发人员的客户可以根据需要精确地调整数据产品。

DaaS 对 SaaS

当你饿的时候,你有两个主要的选择。

第一个是从餐馆点一些食物/去餐馆。例如,你订了 20 美元的比萨饼。

另一个选择是去杂货店,花 8 美元买下所有的食材,然后自己做饭。

自己做披萨的缺点就是要花时间。另外,你需要掌握一些技能。但是,它更便宜(如果你不为你的时间收费的话),而且你可以随心所欲地定制

餐馆的比萨饼通常不能定制。

比萨饼店是 SaaS 的一个例子,因为它给你的是最终产品。杂货店是 DaaS 的一个例子,因为它给你资源来烘烤你自己的比萨饼。

什么是贝塔?

贝塔是你如何能:

  • 验证你的想法,
  • 揭示主要技术问题
  • 收集关于用户需要的最重要功能的反馈

你不收费,所以它不需要完美。

为什么发布测试版而不是最终版?

嗯,你必须非常擅长你正在做的事情,并且完全了解你的受众,这样才能在第一次尝试时就发布“有价值的东西”。所以多花一点时间最终会有回报。

对我们来说,这也是为了验证我们的架构。我们必须看到不同的部件是如何粘在一起的。

β=最小可行产品

我不确定这是否总是正确的,但在大多数情况下应该是这样。你只留下产品无法生存的功能。

所有不必要的都放在 MVP 后的第一栏。

第二部分。计划和要求

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

伦纳特·约翰逊Unsplash 上拍摄的照片

测试版要求

用户传递单词/短语,API 返回一堆关于搜索主题的文章。就这么简单。

从 API 收到响应应该不会超过 3-5 秒。

我们还添加了一些过滤器,因为这很容易做到。

任何需要一个多小时开发的功能都被抛弃了。

我们的文档页面很好地展示了我们所取得的成就。

如何构建新闻 API?

简单来说,我们必须从新闻网站获取文章,比如 nytimes.com 的和 theverge.com 的等。最终目标是从任何现有的新闻网站上获取。

然后,数据规范化&重复数据删除——最重要的部分。每篇文章都是一个数据点——它有一组变量,如标题、出版日期、作者等。

例如,一篇文章发表的日期和时间应该是我们最终数据源中的一个时区。否则按时间查询数据就没有任何意义了。

最后,在我们收集和标准化之后,我们应该将数据存储在某个地方。更重要的是,检索数据应该很容易。在我们的例子中,我们很大程度上依赖于搜索功能。

去拿文章。数据收集

在我开始解释架构设计之前,我应该解释一下我们将如何收集新闻文章的数据。

第一个想法可能是为每个网站设置网页抓取器。Web 抓取已经很发达了——有很多开源库使得 web 抓取变得很容易。

但是,每个网站都有自己的结构。即使有一些令人惊奇的库可以帮助你从新闻文章中构建数据(比如报纸),它也不能 100%适用于这些来源。

制作成千上万个可以避免被禁的网络爬虫既昂贵又耗时

在理想的情况下,我应该有一个 API 来从每个新闻数据提供者那里检索最新的新闻。另外,每个 API 都是相同的设计。

但是没有这样的 API。然而,另一种获取新闻数据的方法是存在的。并且,它已经被规范化了。它被称为 RSS。

根据维基百科RSS 是一种网络提要,允许用户和应用程序以标准化的、计算机可读的格式访问网站的更新。

对于新闻网站来说,网站更新是新的新闻文章。几乎每个新闻网站都有。

RSS 已经标准化了。算是吧。您需要做一些额外的工作来从中提取主要字段。

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

nytimes.com 的主要 RSS

第三部分。解决方案架构

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

newscatcherapi.com AWS 架构图测试版

将收集到的标准化数据传送到我们的最终数据存储需要 7 个步骤——弹性搜索:

  1. CloudWatch 事件触发λ
  2. Lambda 从 DynamoDB 获取 RSS 提要 URL
  3. 同一个 Lambda 将所有这些 RSS URLs 发送到 SQS
  4. Lambda 获取来自 SQS 的每个 RSS 端点,并读取和规范化提要
  5. 新闻文章数据被插入 DynamoDB
  6. DDB 流收集多达 X 条新插入的记录,并将其发送给 Lambda
  7. Lambda 在 Elasticseearch 中插入新记录

第一步。 CloudWatch 事件触发了“编排”lambda

AWS Lambda 是一个无服务器的功能即服务工具,它运行您的代码来响应事件。您不必维护服务器。您只需为执行该功能的时间付费。

CloudWatch 事件是一个 cron 作业的 AWS 实现。

你可以设置 CloudWatch 事件,每隔 X 分钟、小时、天等触发你的 Lambda。

第二步。“编排”lambda 从 DynamoDB 获取 RSS 提要 URL

DynamoDB 表包含了我们用来更新新闻数据库的所有 RSS 提要

DynamoDB 是 AWS 的一个完全托管的非 SQL 数据库。与 AWS Lambda 一样,您不必管理其背后的硬件或软件。您可以将它作为存储数据的现成解决方案。

第三步。“编排”lambda 将所有这些 RSS URLs 发送到 SQS

现在您有了一个必须处理的所有 RSS 提要的列表。

它们有数千个,所以循环处理每一个不是一个选项。

让我们假设我们有另一个 Lambda 函数可以读取和规范化 RSS。AWS Lambda 允许您进行数百个并行调用。因此,你可以考虑从你当前的 Lambda 调用许多其他的 Lambda。

这种方法应该是可行的,但是,它会使您的过程变得复杂并且容易失败。

所以你需要中间的东西。

简单队列服务是由 AWS 完全管理的队列服务。

我们将把所有的 RSS 端点作为消息发送给 SQS,而不是从我们的“编排”Lambda 中触发 RSS 处理。然后,来自 SQS 的新消息可以触发 RSS 处理 Lambda。

通过添加 SQS 层,我们使得检查每个 RSS 端点处理的成功变得更加容易。如果其中一个 lambda 失败,它不会中断处理其他 RSS 提要的任何其他 lambda。

**第四步。**Lambda 从 SQS 获取每个 RSS 端点,并读取和规范化提要

我最喜欢的 AWS Lambda 特性是,你不用为同时执行多个 Lambda 而多花钱。当您不知道未来的工作负载,或者想要确保系统在接收更多负载时不会崩溃时,它使 Lambda 成为一个有用的工具。

这个 Lambda 是一个 Python 函数,它将 RSS URL 作为输入,并返回结构化数据(标题、发布日期、作者、文章 URL 等。)

现在,当我们从每个 RSS 提要中提取并规范化新闻文章的数据时,必须存储这些数据。

**第五步。**新闻文章数据被插入 DynamoDB

在将数据发送到 Elasticsearch 集群之前,我们将其放入 DynamoDB。主要原因是 Elasticsearch 确实失败了。Elasticsearch 在很多方面都很棒(我们将在后面讨论),但是 Elasticsearch 不能成为你的主要数据存储

重复数据删除。每个 RSS 提要偶尔会更新一次。它向提要添加了更多的文章。例如,新闻网站 X 的 RSS 提要总是包含 100 篇文章。提要每小时更新一次。如果在这一小时内有 10 篇新文章,那么它们将出现在顶部。而最早的 10 篇文章将被删除。其他 90 篇文章会和一个小时前一样。因此,所有这 90 篇文章在我们的数据库中都是重复的。

我们有成千上万的这样的反馈。

因此,如果我们能够验证每个 ID(不管它是什么)是否已经存在于我们的数据库中,那就太好了。

我从 Reddit 上得到了很好的建议:

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

感谢来自 AWS 的 Vladimir Budilov 的帮助

诀窍是确保我们对每篇新闻文章都有一个一致的 ID 键。我们是每篇文章的标题+网址。然后,当我们将这些数据插入 DynamoDB 时,只允许新的 id(检查 DynamoDB 的 attribute_not_exists 设置)。

因此,我们不必自己消除重复数据。

第六步。 DDB 流收集多达 X 条新插入的记录,并将其发送给 Lambda

现在,我们必须从 DynamoDB 向 Elascticsearch 集群发送新数据。

我们在 DynamoDB 插件上做了一个触发器。每次任何数据被插入 DynamoDB 时,它都会被 Lambda 拾取,然后将这些新数据发送到 Elasticsearch 集群。

将数据加载到 DynamoDB 中我们显著降低了 ES 的负载,因为它将接收更少的新数据。另外,DynamoDB 是我们的主要数据来源。

第七步。 Lambda 在 Elasticsearch 中插入新记录

DynamoDB 承担了确保数据库中没有重复项的所有繁重工作。只有新插入的记录才会进入 Elasticsearch 集群。

您可以将 Lambda 设置为等待新的 X 记录或 Y 分钟,然后一次获取多个记录。这样你的交易会更少,而且你可以利用 Elasticsearch 批量插入。

为什么选择 Elasticsearch?

因为这是使用全文搜索的最佳方式。

Elasticsearch 很复杂,你几乎可以调整任何东西。充分了解数据的用途和用途可以让您优化集群以获得最佳性能。

然而,出于测试目的,我们几乎在所有地方都使用默认设置。

数据交付/API

到目前为止,我们确保我们的 Elasticsearch 集群得到了新数据的更新。现在,我们必须为用户提供一个工具来与我们的数据进行交互。我们选择让它成为一个 RESTful API。

我最喜欢的组合是用 API Gateway + Lambda 来做。

来自 AWS 页面:

API Gateway 处理接受和处理多达数十万个并发 API 调用所涉及的所有任务,包括流量管理、CORS 支持、授权和访问控制、节流、监控和 API 版本管理。

因此 API 网关负责管理 API 请求。我们还是要实现逻辑层。Lambda 函数将处理每个 API 调用。

Lambda 本身是用一个叫 Flask 的微型 web 框架编写的。

这个 Lambda 的任务是解析用户传递的参数(比如他们想要查找文章的短语)。然后,它查询我们的 Elasticsearch 集群。最后,它组成一个干净的 JSON 响应对象,发送给用户。

除了 Flask,我们还使用了elasticsearch-DSL-py包来帮助编写和运行针对 elastic search 的查询。

我建议使用 Zappa 部署 API Lambdas:

Zappa 使得在 AWS Lambda + API Gateway 上构建和部署无服务器、事件驱动的 Python 应用程序(包括但不限于 WSGI web 应用程序)变得非常容易。可以把它想象成 Python 应用程序的“无服务器”网络托管。这意味着无限扩展、零停机、零维护,而成本只是您当前部署的一小部分!

当你不确定你要服务多少个调用时,用 Lambda 部署你的 API 是最方便的。

更重要的是,如果你有 0 个电话,你支付 0。

第四部分。后期测试

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

照片由蓝屋滑雪板Unsplash 上拍摄

初始(beta 后)发布计划

除了我们在测试版中取得的所有成就之外:

  • 按语言过滤
  • 适用于 6-10 种最常见语言的正确文本分析器
  • 精确匹配搜索
  • 必须包含/排除一个短语
  • 按国家过滤
  • 每个国家/地区端点的头条新闻
  • 按主题过滤(体育、商业、娱乐等。)
  • 页码

我们将有大量的工作来优化我们的弹性搜索集群。最大的变化是正确的根据语言分析文本字段。

重点是让搜索知道用户想要的语言。例如,默认的 Elasticsearch 文本分析器不知道“got”是“go”的基本形式。而英语分析器使用词干来跟踪这些东西。

因此,知道你希望你的文章被搜索到哪种语言将极大地提高找到的文章的相关性分数。

日志记录是我们想要实现的另一件重要的事情。最有可能的是,我们将使用 Elasticsearch 进行日志记录。

还应实施弹性搜索恢复计划。至少,我们应该知道集群何时关闭(目前情况并非如此)。

结论

它只是工作。你还需要从测试版中得到什么?

帮助我们进行测试的两个主要因素是:

  1. 请 Reddit 帮助我们设计建筑
  2. 投资一些时间来发布我们的 Python 包 →获得 beta 注册

https://www.youtube.com/watch?v=r13riaRKGo0

感谢你一路阅读到这里。

支持我们的最好方式是参加我们的封闭测试

About meMy name is Artem, I build [newscatcherapi.com](https://newscatcherapi.com/) - ultra-fast API to find news articles by any topic, country, language, website, or keyword.I write about Python, cloud architecture, elasticsearch, data engineering, and entrepreneurship.

走向不确定性——让您的 ML 模型经得起未来考验的 6 个明智步骤

原文:https://towardsdatascience.com/launching-into-uncertainty-6-smart-steps-to-future-proof-your-ml-models-bdebbccc6c43?source=collection_archive---------71-----------------------

新冠肺炎版:

你的机器学习模型在疫情会失败。以下是减轻损害的方法。

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

来自 Unsplash 的照片 Anastasia Patrova

有许多文章关注机器学习如何能够并且正在疫情期间提供帮助。韩国和台湾政府成功展示了他们如何利用人工智能来减缓新冠肺炎病毒的传播。法国科技公司发现没有戴口罩的热点地区,建议政府将重点放在教育上。数据和医学专家合作索引新冠肺炎医学期刊论文

来自数据科学界的参与令人振奋,结果也很突出。

但是这个帖子讲的恰恰相反。我在这里不是要吹捧机器学习的成功。我在这里对它所有的荣耀和奇迹产生一点怀疑。我是来问这个问题的:

在这段不确定的时间里,你在观察你的机器学习模型吗?

为什么不呢?

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

照片由斯蒂芬·道森Unsplash 拍摄

现实生活中的数据经常与训练数据相背离。从您将准确、稳定的模型发布到产品中的那一天起,随着客户的发展,它的性能每天都在下降。对于新冠肺炎来说,这就好像是将模型从安全的培养皿中释放出来,放入狂野的西部。

随着政策变化、利率下降和支付假期,突然的数据转移会对您的模型产生深远的影响。模型精度下降没问题,但是对变化一无所知就不行了。

模型精度下降是可以的,但是对变化一无所知是不行的

在过去的几周里,我一直在参与这些机器学习模型的影响评估。最初这是压倒性的,所以我收集了一些实际的步骤,希望其他团队可以带着更多的信心和更少的恐慌来处理这个过程:

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

作者制作的信息图。由 Eucarlp 从www.flaticon.com创作的图标

为了避免就这个主题写一整本书,本文使用了相当多的术语。如果您不确定术语的含义,请单击超链接。

步骤 1:识别受影响的用例以及涉众

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

图标来自桉树,作者改编。

不是所有的用例都会受到疫情的影响,就像不是所有的模型都会遭受数据数据或概念漂移

任何软件评估的第一步都和任何软件开发的第一步一样:提出问题。

问一堆问题。

如果您有许多正在进行的用例,并且不确定先处理哪一个,请从以下问题开始:

❓:我在模拟人类行为吗?(即复活节期间购买的物品、房屋贷款首付款)

❓Did:我对政府或企业在危机期间改变的政策(如旅行禁令、银行支付假期)有任何固有的假设

一旦你确定了用例,然后指出受这些用例影响的涉众。涉众通常是该领域的主题专家,因此他们可以在下面的步骤 2 中帮助您。

给自己画一个决策树。

如果您的系统涉及到人员或策略,请继续执行步骤 2。

否则,继续前进。

第二步:评估事情出错时的风险和暴露程度

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

图标来自桉树,作者改编。

这个疫情是黑天鹅事件的经典案例。这是一次罕见的意外病毒爆发,后果严重。

所以很有可能事情会出错,但是会错到什么程度呢?

事情将会出错,但到底会错到什么程度呢?

情景分析 可以帮助我们驾驭这些极端情况。

在这一步中,与业务部门的 SME(主题专家)交谈非常有价值。他们通常有许多问题想要答案,数据科学家将分析数据以生成这些问题的洞察包。这时候这些问题可以帮助你审问你的模型。

举个例子,

“如果房地产销售大幅下降,我们的底线会怎么样?”

好了,现在是检验它的时候了。如果您正在对房屋贷款产生的收入进行建模,那么在房屋贷款销售额较低时(夏季度假城镇的冬季月份)检查数据。然后,根据 SME 的建议进行调整,生成一个假的输入数据集,并在您的模型中运行。这可以帮助您评估模型面临风险的区域。

给出一个量化的数字可以帮助企业做出艰难的决定。即使我们觉得我们没有足够的信息来提供预测,但仍然要做出决定。贷款仍然需要发放,卫生纸仍然需要运输。我们不应该把责任推得更远,而应该专注于尽力而为。

给出一个附有所有星号的预测。

如果影响很大,请继续第 3 步进行彻底检查。

否则,继续前进。

步骤 3:检查整个解决方案的漏洞

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

图标来自桉树,作者改编。

机器学习解决方案不仅仅是模型本身。有数据工程管道、推理和模型再训练。端到端地扫描整个解决方案以发现漏洞非常重要。

机器学习解决方案不仅仅是模型

以下是您可以关注的一些领域:

⏩大量购买会破坏你的销售渠道吗?一些供应商的预测算法被订单数量的突然变化破坏。另一方面,一些欺诈检测系统被误报淹没了。

⏩您的基础架构上的基本负载是否发生了变化?有些模型不太相关,有些甚至更重要,转移您的计算资源可以平衡成本。

⏩调查模型的全局和局部特征重要性。你的主要特征对疫情敏感吗?他们应该吗?有很多关于可解释 AI 的文章,在未知的时间里,推理可解释性可以给人们需要的透明度。

在整个管道中定义检查。

到第 3 步时,您已经确定您的解决方案受到了危机的影响。所以继续第 4 步。

从这一点开始,没有前进,只有前进。

步骤 4:设置自动警报和修复

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

图标来自桉树,作者改编。

如果你正在阅读这篇文章,你可能还没有监控系统。否则,你将设置 500 吉拉门票,并在您的下一步顶部。

部署机器学习模型就像驾驶飞机一样

想象你是一名飞行员:

☑️:没有伐木就像没有黑匣子的飞行。任何恐怖分子都可以劫持飞机而不承担任何后果。

🖥️:没有监控就像在新的空域盲目飞行。飞行员不知道他要去哪里,你也不知道。

🌪没有弹性基础设施的️️:就像一架无人维护的飞机。机票很便宜,但飞机随时可能坠毁。

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

来自 UnsplashKaotaru 摄影, melio.ai 编辑

你不会带着一个失明的飞行员和一个坏掉的引擎登机,为什么你要部署一个没有日志记录、监控和弹性基础设施的模型呢?

先不说监控,治愈呢?

许多成熟的机器学习解决方案都在系统中内置了自动化的再培训。但在这些极端事件中,或许值得看一看刷新的车型。他们使用最新的数据进行预测吗?他们应该吗?

面对未知情况时,自动重新部署刷新的模型可能会有风险。人在回路的方法可以是临时的,也可以是战略性的解决方案。

1️⃣设置了自动再培训和报告(使用业务 KPI 以及步骤 3 中定义的抽查)。

在疫情时期,2️⃣用更严格的警告标准警告人们要得到认可。

3️⃣:如果步骤 1-3 被严格执行,并且风险和暴露被承认,那么我们可能准备好重新部署模型。

监控数据和模型漂移,并在必要时重新部署。

如果您仍然不确定,设置 金丝雀部署 并将您的一小部分流量重定向到新模式。然后等新车型稳定了再慢慢淘汰旧的。

第五步:打开包装,交流未来的挑战

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

图标来自桉树,作者改编。

新冠肺炎的影响从卫生纸短缺到全球经济崩溃不等。即使不是所有行业,也是大多数行业受到了正面或负面的影响。

这种反常可能会成为新的常态

远程工作、破产激增、结构性失业以及旅行限制等长期影响尚不明朗。当历史数据在这种前所未有的情况下不适用时,“异常”就可能成为新的常态。这迫使我们回过头来解开基本的商业问题,并重新思考许多假设。

⏩我们在未来的模型训练中包括疫情的数据吗?

⏩我们是否包含了更好地反映当前现实的新特性?

⏩当发生重大中断时,我们应该调整模型的敏感性吗?

⏩我们需要重新评估疫情之前选择的模型指标吗?

⏩当事情“恢复正常”时,我们会恢复上述所有情况吗?

在这个阶段,问题比答案多。盲目推荐“最佳实践”为时尚早。

唯一的办法是保持好奇,保持沟通畅通,承认风险,一步一步来。

步骤 6:建立后备系统以减轻影响

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

图标来自桉树,作者改编。

你想过为什么蜣螂不会迷路吗?

这些微小的昆虫使用一系列的导向系统来帮助它们达到尽可能高的精确度。当一个系统不可靠时,他们切换到使用另一个

当你没有任何数据的时候,你就得用理智~理查德·费曼

著名物理学家、诺贝尔奖获得者劳蕾特·理查德·费曼在调查美国宇航局挑战者计划灾难时说:“当你没有任何数据时,你必须使用理性。”(摘自戴维·爱泼斯坦的系列,第 9 章)。

当机器学习依赖于历史模式时,这一点尤其正确。当历史模式不可靠时,需要调用替代策略:

无监督 或半监督方法可以帮助重新定义问题空间。基于现有用户的新行为为其创建新的细分。一个过去的户外迷可能是现在正念的瑜伽士。

压力测试:第二步建立的场景分析框架可用于加载输入数据的各种极端情况。

⏩集成或选择:集成很受欢迎,因为它能够通过组合多个弱学习者来创建强学习者。有时,这可能是不必要的。一个用例可能有多个模型。工程管道可以检测变更或属性,并使用最合适的模型进行推断。

或者以上都有,以人为中心。

这就是为什么女士们先生们——AutoML 不会取代数据科学家。成为理性的声音。与中小企业交流。保持冷静,坚持下去。

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

来自 UnsplashTonik 拍摄的照片

在这个不确定的时期避免变化是一项挑战。没有人能确定任何事情,做一个预测是令人畏惧的。遵循以下步骤可以指导您解决无法预见的问题:

  1. 回到基本面,这个用例是关于什么的?
  2. 问题&解释你的模型
  3. 抽查您的整个解决方案
  4. 建立测井&监控框架
  5. 再培训和重新部署
  6. 保持好奇心,为未来做准备
  7. 做一只屎壳郎

如果你喜欢这篇文章,我以前也发表过类似的主题:

感谢阅读 ⭐在媒体LinkedIn 上关注我,或者访问我的网站。此外,如果你想评估你的机器学习部署框架,在 Melio Consulting 给我们发电子邮件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值