TowardsDataScience-博客中文翻译-2021-四十六-

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

TowardsDataScience 博客中文翻译 2021(四十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何为单一语言调整多语言 T5 模型

原文:https://towardsdatascience.com/how-to-adapt-a-multilingual-t5-model-for-a-single-language-b9f94f3d9c90?source=collection_archive---------12-----------------------

实践教程

仅为您的语言的标记加载嵌入,以减少模型大小

T5 是谷歌的一个编码器-解码器转换器,曾经是几个 NLU 和 NLG 问题的 SOTA,现在仍然是 seq2seq 任务(如文本摘要)的基础。第一个 T5 型号是仅用于英语的,然后是大规模的多语言版本。这个模型涵盖了 101 种语言,规模确实很大。

这篇文章展示了如何通过修剪冗余的嵌入从多语言模型中提取出单一语言模型。这将参数数量减少了两倍以上,而质量没有显著损失。对于俄语,我们的结果是,但是你可以用 mT5 的 101 种语言中的任何一种来尝试。

三分之二的 MT5 参数是嵌入的,我们可以去掉不用的。图片由作者提供。

选择词汇

这个想法类似于论文Load What your Need:多语言 BERT 的一个小版本。我们使用原始记号赋予器来处理俄语语料库,统计不同记号的频率,并且仅保留足够频繁使用的记号,修剪所有其他记号。

我们还在模型中保留了少量的英语标记,使其成为双语的。我们需要这一点来使模型能够将知识从英语转移到俄语下游任务,还因为英语单词和短语经常出现在现代俄语文本中。

我们首先加载现有的多语言模型。

import torch
from transformers import T5ForConditionalGeneration, T5Tokenizer
tokenizer = T5Tokenizer.from_pretrained("google/mt5-base")
model = T5ForConditionalGeneration.from_pretrained('google/mt5-base')

该模型主要由嵌入组成:其 33%的参数是输入嵌入(在其编码器和解码器之间共享),33%是输出嵌入。

def msize(m):
    return sum(p.numel() for p in m.parameters())print(msize(model.shared) / msize(model))   # 0.3298
print(msize(model.lm_head) / msize(model))  # 0.3298

为了估计不同标记的频率,我们从莱比锡语料库中提取了一个俄语和一个英语句子语料库。我们使用这两种语言是因为我们希望我们的模型最终是双语的。

import pandas as pd
import csv
from collections import Counter
from tqdm.auto import tqdm, trangedf_ru = pd.read_csv('rus-ru_web-public_2019_1M-sentences.txt', sep='\t', header=None, quoting=csv.QUOTE_NONE)
df_ru.columns = ['idx', 'text']
cnt_ru = Counter()
for text in tqdm(df_ru.text):
    cnt_ru.update(tokenizer.encode(text))
print(len(cnt_ru), len(cnt_ru)/tokenizer.vocab_size)  
# 58438 0.2336

在统计了俄语语料库中的标记后,我们发现只有 23%的模型词汇被使用。此外,前 20K 个标记构成了俄语语料库的 99%以上。对于英语来说,统计数据是相似的。

for top in 10_000, 20_000, 30_000:
    print(top, sum(v for k, v in cnt_ru.most_common(top)) / sum(cnt_ru.values()))
# 10000 0.9645
# 20000 0.9940
# 30000 0.9982

我们决定使用下列词汇:

  • 原始令牌化器的 1K 个顶级令牌(以防万一)
  • 英语词汇中的顶级 10K
  • 俄语词汇前 20K 名
  • T5 使用的 100 个特殊令牌

这给了我们 30K 令牌的词汇表,是多语言版本中 250K 令牌的 12%。

new_tokens = set(range(1000))
for i, (k, v) in enumerate(cnt_en.most_common(10_000)):
    if k not in new_tokens:
        new_tokens.add(k)
for i, (k, v) in enumerate(cnt_ru.most_common(25_000)):
    if len(new_tokens) == 29_900:
        print(i, 'Russan tokens are included')
        break
    if k not in new_tokens:
        new_tokens.add(k)for t in range(tokenizer.vocab_size - 100, tokenizer.vocab_size):
    new_tokens.add(t)print(len(new_tokens))
kept_ids = sorted(new_tokens)

更新模型

更新神经网络很容易:只需替换其输入和输出嵌入的参数。这将模型大小减少了 58%(从 2.2GB 减少到 0.9GB)。

new_size = len(kept_ids)
new_emb = torch.nn.Embedding(new_size, model.shared.embedding_dim)
new_head = torch.nn.Linear(in_features=model.lm_head.in_features, out_features=new_size, bias=False)
for new_id, old_id in enumerate(kept_ids):
    new_emb.weight.data[new_id] = model.shared.weight.data[old_id]
    new_head.weight.data[new_id] = model.lm_head.weight.data[old_id]
model.shared.weight = new_emb.weight
model.lm_head.weight = new_head.weightmodel.config.__dict__['vocab_size'] = new_size
model.config.__dict__['_name_or_path'] = 'cointegrated/rut5-base'

更新记号赋予器出人意料地更加棘手。T5 使用 Sentencepiece tokenizer,用 C 实现,对 Python 是不透明的。幸运的是,我们可以下载它的模型,并使用它的 Protobuf 表示将其部署到 Python 中。

! wget [https://raw.githubusercontent.com/google/sentencepiece/master/src/sentencepiece_model.proto](https://raw.githubusercontent.com/google/sentencepiece/master/src/sentencepiece_model.proto)
! protoc --python_out=. sentencepiece_model.protoimport sentencepiece_model_pb2 as spmp
smp = tokenizer.sp_model.serialized_model_proto()
m = spmp.ModelProto()
m.ParseFromString(smp)print('the loaded model has pieces:', len(m.pieces))
new_pieces = [m.pieces[idx] for idx in kept_ids]
print('the new pieces:', len(new_pieces))# replace the content of the first 30K pieces
for i, p in enumerate(new_pieces):
    m.pieces[i].piece = p.piece
    m.pieces[i].score = p.score
    m.pieces[i].type = p.type# drop the remaining pieces
n = len(new_pieces)
for i in trange(len(m.pieces) - n):
    m.pieces.pop(len(m.pieces) - 1)print(len(m.pieces))
with open('new_sp.model', 'wb') as f:
    f.write(m.SerializeToString())new_tokenizer = T5Tokenizer('new_sp.model', extra_ids=0)

现在我们可以保存新的模型和新的记号赋予器。

new_tokenizer.save_pretrained('rut5-base')
model.save_pretrained('rut5-base')

到目前为止,创建模型的所有代码都可以在 Github 的上获得。俄罗斯 T5 型号在的 Huggingface 仓库有售。

坦率地说,这个模型本身是非常无用的,因为 mT5 只在预测缺失单词的无人监督的任务上受过训练。然而,这个模型可以针对许多其他任务进行微调:文本摘要、翻译、对话响应生成、释义等。在下一篇文章中,我们将展示如何进行这样的微调。订阅敬请关注!

这篇文章是由大卫·戴尔(https://daviddale.ru/en)写的,他是 NLP 的研究科学家和聊天机器人的开发者。

如何向现有的 Pandas 数据框架添加新列

原文:https://towardsdatascience.com/how-to-add-a-new-column-to-an-existing-pandas-dataframe-310a8e7baf8f?source=collection_archive---------1-----------------------

讨论在熊猫数据框中插入新列的 4 种方法

猪八戒在 Unsplash 上拍照

介绍

在今天的简短指南中,我们将讨论向数据帧中添加新列的四种不同方法。具体来说,我们将探索如何

  • 一次插入一列或多列
  • 覆盖现有列
  • 通过考虑索引来添加列
  • 通过忽略索引来插入列
  • 添加具有重复名称的列
  • 在指定位置插入列

采用简单赋值、insert()assign()concat()的方法。

首先,让我们创建一个示例 DataFrame,我们将在本指南中引用它来演示一些与向 pandas 框架添加列相关的概念。

import pandas as pd df = pd.DataFrame({
    'colA':[True, False, False], 
    'colB': [1, 2, 3],
})print(df) *colA  colB
0   True     1
1  False     2
2  False     3*

最后,假设我们需要插入一个名为colC的新列,该列应该包含值'a''b''c',分别表示索引013

s = pd.Series(['a', 'b', 'c'], index=[0, 1, 2])
print(s)*0    a
1    b
2    c
dtype: object*

使用简单赋值

插入新列的最简单方法是简单地将Series的值分配到现有帧中:

**df['colC'] = s.values**print(df) *colA  colB colC
0   True     1    a
1  False     2    b
2  False     3    c*

请注意,假设新列的索引与数据帧的索引相匹配,上述方法适用于大多数情况,否则NaN值将被分配给缺失的索引。举个例子,

df['colC'] = pd.Series(['a', 'b', 'c'], index=[1, 2, 3])
print(df) *colA  colB colC
0   True     1  NaN
1  False     2    a
2  False     3    b*

使用 assign()

当您需要在一个数据帧中插入多个新列时,可以使用[pandas.DataFrame.assign()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.assign.html)方法;当您需要忽略要添加的列的索引时,可以使用方法;当您需要覆盖现有列的值时,可以使用方法。

该方法将返回一个新的 DataFrame 对象(副本),其中包含所有原始列和新列:

e = pd.Series([1.0, 3.0, 2.0], index=[0, 2, 1])
s = pd.Series(['a', 'b', 'c'], index=[0, 1, 2])**df.assign(colC=s.values, colB=e.values)** colA  colB colC
0   True   1.0    a
1  False   3.0    b
2  False   2.0    c

永远记住用分配:

  • 忽略要添加的列的索引
  • 所有重新分配的现有列都将被覆盖

使用 insert()

或者,也可以使用[pandas.DataFrame.insert()](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.insert.html)。这种方法通常在需要在特定位置或索引插入新列时有用。

例如,要将colC添加到数据帧的末尾:

**df.insert(len(df.columns), 'colC', s.values)**print(df)
 *colA  colB colC
0   True     1    a
1  False     2    b
2  False     3    c*

colAcolB之间插入colC:

df.insert(1, 'colC', s.values)print(df) *colA colC  colB
0   True    a     1
1  False    b     2
2  False    c     3*

另外,insert()甚至可以用来添加一个重复的列名。默认情况下,当 DataFrame 中已经存在一列时,会引发一个ValueError:

df.insert(1, 'colC', s.values)
df.insert(1, 'colC', s.values)**ValueError: cannot insert colC, already exists**

但是,如果将allow_duplicates=True传递给insert()方法,DataFrame 将有两列同名:

df.insert(1, 'colC', s.values)
df.insert(1, 'colC', s.values, allow_duplicates=True)print(df)
 *colA colC colC  colB
0   True    a    a     1
1  False    b    b     2
2  False    c    c     3*

使用 concat()

最后,[pandas.concat()](https://pandas.pydata.org/docs/reference/api/pandas.concat.html)方法还可以用于通过传递axis=1将新列连接到 DataFrame。这个方法返回一个新的数据帧,它是连接的结果。

**df = pd.concat([df, s.rename('colC')], axis=1)**print(df)
 *colA  colB colC
0   True     1    a
1  False     2    b
2  False     3    c*

上述操作将使用索引将序列与原始数据帧连接起来。在大多数情况下,如果要连接的对象的索引彼此匹配,您应该使用concat()。如果索引不匹配,则每个对象的所有索引都将出现在结果中:

s = pd.Series(['a', 'b', 'c'], index=[10, 20, 30])
df = pd.concat([df, s.rename('colC')], axis=1)print(df)
 *colA  colB colC
0    True   1.0  NaN
1   False   2.0  NaN
2   False   3.0  NaN
10    NaN   NaN    a
20    NaN   NaN    b
30    NaN   NaN    c*

更改要添加的列的索引

向数据帧添加新列时,最棘手的部分之一是索引。您应该小心,因为我们在本指南中讨论的每种方法都可能以不同的方式处理索引。

如果由于任何原因,要添加的新列的索引没有任何特殊意义,并且您不希望在插入时考虑它,您甚至可以指定Series的索引与数据帧的索引相同。

s = pd.Series(['a', 'b', 'c'], **index=df.index)**

最后的想法

在今天的简短指南中,我们讨论了在 pandas 数据框架中插入新列或覆盖现有列的 4 种方法。我们已经看到了如何使用简单赋值、assign()insert()concat()方法来插入或覆盖新列。

此外,我们讨论了基于您想要实现的最终目标,您应该何时使用每种方法(例如,如果您想要忽略或考虑要添加的新列的索引)。

插入新列时,您必须选择最合适的方法,因为当新列和现有框架的索引不匹配时,每个列可能会有不同的行为。

成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。

你可能也会喜欢

</6-tips-to-help-you-stand-out-as-a-python-developer-2294d15672e9>

如何在 Streamlit 中添加用户认证服务

原文:https://towardsdatascience.com/how-to-add-a-user-authentication-service-in-streamlit-a8b93bf02031?source=collection_archive---------1-----------------------

使用 Streamlit-Authenticator 开发安全登录表单

照片由弗兰克在 Unsplash 上拍摄

细流

Streamlit 自 2019 年 10 月成立以来,已经走过了极其漫长的道路。它增强了软件开发社区的能力,并有效地使我们开发和部署应用程序到云的方式民主化。然而,与所有新工具一样,还有一段路要走,尽管 Streamlit 团队不懈地努力部署新功能并解决来自社区的请求,但我们开发人员可以自行交付特定功能。

Streamlit 目前缺乏的一项功能是为其应用程序实施安全登录和身份验证服务的能力,但 Streamlit Cloud 除外,它提供身份验证作为一项高级功能。在当前的形式下,没有无缝的方法来为我们的自部署应用程序实现登录表单。虽然对许多开发人员来说,这不是问题,但对其他人来说,这可能是一个问题。想象一下,如果你试图开发一个应用程序,其中包含受限或敏感的内容,这些内容可能只提供给你的一部分受众。在这种情况下,缺少安全的身份验证模块会使 Streamlit 成为一个不合适的框架。幸运的是,有了Streamlit-Authenticator,您就可以随心所欲了。

履行

对于本教程,我们将生成一个简单的登录表单,该表单将对一组预定义的用户进行身份验证,以访问我们的 web 应用程序上的内容,还将演示用于重置密码、更新用户详细信息、注册新用户的小部件,并为用户提供找回忘记的用户名和/或密码的方法。如果您还没有这样做,请启动 Anaconda 或您选择的任何其他 Python IDE,并安装 Streamlit-Authenticator :

pip install streamlit-authenticator

然后继续将以下包导入到脚本中:

import streamlit as st
import streamlit_authenticator as stauth

1.哈希密码

最初创建一个 YAML 配置文件,并定义您的用户凭证(名称、用户名和明文密码)。此外,输入将存储在客户端浏览器上的 JWT cookie 的名称、随机密钥和过期天数,以启用无密码重新身份验证。如果不需要重新认证,可以将过期天数设置为 0。最后,定义预授权用户的电子邮件列表,这些用户可以使用 register_user 小部件注册并将其凭证添加到配置文件中。

credentials:
  usernames:
    jsmith:
      email: jsmith@gmail.com
      name: John Smith
      password: abc # To be replaced with hashed password
    rbriggs:
      email: rbriggs@gmail.com
      name: Rebecca Briggs
      password: def # To be replaced with hashed password
cookie:
  expiry_days: 30
  key: some_signature_key # Must be string
  name: some_cookie_name
preauthorized:
  emails:
  - melsby@gmail.com

然后使用哈希模块将明文密码转换为哈希密码。

hashed_passwords = stauth.Hasher(['abc', 'def']).generate()

最后,用哈希密码替换配置文件中的纯文本密码。

2.创建登录小部件

随后,将配置文件导入到您的脚本中,并创建一个身份验证对象。

from yaml.loader import SafeLoaderwith open('../config.yaml') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['preauthorized']
)

最后,如下所示呈现登录小部件。在这里,您需要为登录表单提供一个名称,并指定表单的位置,即主体或侧栏(默认为主体)。

name, authentication_status, username = authenticator.login('Login', 'main')

Streamlit-Authenticator 登录表单。图片作者。

3.认证用户

然后,您可以使用返回的名称和身份验证状态来允许经过验证的用户访问任何受限制的内容。此外,您可以在您的主体或侧边栏的任何位置添加一个可选的注销按钮(默认为主体)。

if authentication_status:
    authenticator.logout('Logout', 'main')
    st.write(f'Welcome *{name}*')
    st.title('Some content')
elif authentication_status is False:
    st.error('Username/password is incorrect')
elif authentication_status is None:
    st.warning('Please enter your username and password')

如果您需要访问持久名称、验证状态和用户名变量,您可以使用 st.session_state["name"]ST . session _ state[" authentic ation _ status "]ST . session _ state[" username "]通过 Streamlit 的会话状态检索它们。这样,您可以使用 Streamlit-Authenticator 跨多个页面对用户进行身份验证。

if st.session_state["authentication_status"]:
    authenticator.logout('Logout', 'main')
    st.write(f'Welcome *{st.session_state["name"]}*')
    st.title('Some content')
elif st.session_state["authentication_status"] is False:
    st.error('Username/password is incorrect')
elif st.session_state["authentication_status"] is None:
    st.warning('Please enter your username and password')

Streamlit-Authenticator认证内容。图片作者。

或者提示未经验证的用户输入正确的用户名和密码。

Streamlit-Authenticator未经验证的登录尝试。图片作者。

请注意,注销会将认证状态恢复为,并且还会删除相关的重新认证 cookie。

4.创建密码重置小部件

您可以使用 reset_password 小部件来允许登录用户修改他们的密码,如下所示。

if authentication_status:
    try:
        if authenticator.reset_password(username, 'Reset password'):
            st.success('Password modified successfully')
    except Exception as e:
        st.error(e)

Streamlit-Authenticatorreset _ password 小工具。图片作者。

5.创建新的用户注册小部件

您可以使用 register_user 小部件来允许用户注册您的应用程序,如下所示。如果您需要对用户进行预授权,请将预授权参数设置为 True,并将他们的电子邮件添加到配置文件中的预授权列表中。一旦他们注册,他们的电子邮件将自动从配置文件的预授权列表中删除。或者,为了允许任何人注册,将预授权参数设置为 False。

try:
    if authenticator.register_user('Register user', preauthorization=False):
        st.success('User registered successfully')
except Exception as e:
    st.error(e)

Streamlit-Authenticatorregister _ user _ widget。图片作者。

6.创建忘记密码小部件

您可以使用 forgot_password 小部件让用户生成一个新的随机密码。该密码将被自动散列并保存在配置文件中。该小工具将返回用户名,电子邮件和新的随机密码的用户,然后应该转移到他们的安全。

try:
    username_forgot_pw, email_forgot_password, random_password = authenticator.forgot_password('Forgot password')
    if username_forgot_pw:
        st.success('New password sent securely')
        # Random password to be transferred to user securely
    else:
        st.error('Username not found')
except Exception as e:
    st.error(e)

Streamlit-Authenticatorforgot _ password 小工具。图片作者。

7.创建忘记用户名小部件

您可以使用 forgot_username 小部件让用户找回他们忘记的用户名。该部件将返回用户名和电子邮件的用户,然后应该转移到他们的安全。

try:
    username_forgot_username, email_forgot_username = authenticator.forgot_username('Forgot username')
    if username_forgot_username:
        st.success('Username sent securely')
        # Username to be transferred to user securely
    else:
        st.error('Email not found')
except Exception as e:
    st.error(e)

Streamlit-Authenticatorforget _ username 小部件。图片作者。

8.创建更新用户详细信息微件

您可以使用 update_user_details 小部件来允许登录用户更新他们的姓名和/或电子邮件。小部件将自动在配置文件和重新认证 cookie 中保存更新的详细信息。

if authentication_status:
    try:
        if authenticator.update_user_details(username, 'Update user details'):
            st.success('Entries updated successfully')
    except Exception as e:
        st.error(e)

Streamlit-Authenticatorupdate _ user _ details 小工具。图片作者。

9.更新配置文件

请确保在更新凭证或使用重置 _ 密码注册 _ 用户忘记 _ 密码更新 _ 用户 _ 详细信息小工具时,重新保存配置文件。

with open('../config.yaml', 'w') as file:
    yaml.dump(config, file, default_flow_style=False)

结论

既然您已经看到了在 Streamlit 中使用哈希和 JWT cookie 创建和使用安全的用户认证服务是多么简单,那么就放心地在您自己的应用程序中尝试吧。

使用 Streamlit 开发 Web 应用程序:

https://www.amazon.com/Web-Application-Development-Streamlit-Applications/dp/1484281101?&linkCode=ll1&tag=mkhorasani09-20&linkId=a0cb2bc17df598006fd9029c58792a6b&language=en_US&ref_=as_li_ss_tl

GitHub 资源库:

https://github.com/mkhorasani/Streamlit-Authenticator

如果您想了解更多关于数据可视化和 Python 的知识,请随时查看以下(附属链接)课程:

使用 Streamlit 和 Python 构建数据科学 Web 应用程序:

https://www.coursera.org/projects/data-science-streamlit-python?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgTzrEwvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

面向所有人的 Python 专业化:

https://www.coursera.org/specializations/python?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW16Ewvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

使用 Python 实现数据可视化:

https://www.coursera.org/learn/python-for-data-visualization?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW2aEwvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

新到中?您可以在此订阅和解锁无限文章。

如何将决策阈值调整添加到您的端到端 ML 管道中

原文:https://towardsdatascience.com/how-to-add-decision-threshold-tuning-to-your-end-to-end-ml-pipelines-7077b82b71a?source=collection_archive---------11-----------------------

在本文中,我将向您介绍我在处理不平衡数据时使用的两个包( imblearn ,虽然我也经常使用,但不在其中)。一个将帮助您调整模型的决策阈值,第二个将使您的模型在部署时使用选定的阈值。

你为什么要在乎?

首先,作为一名每天与客户打交道的数据科学家,我解决的绝大多数问题都是不平衡二进制分类问题。如果你想一想,如果你对你的顾客、病人、机器等有疑问。这很可能是一个“是/否”的问题。如果你对这个问题感兴趣,也很可能是因为两个答案中的一个不太常见,但对你来说更重要:“我的顾客会购买什么吗?”“我的机器在接下来的 X 小时内需要维护吗?”。

对于不平衡的问题,有许多奇特的技术:多数类的随机欠采样、少数类的随机过采样、 SMOTE 、 ADASYN …以及许多优秀的中等文章,以学习掌握它们。这篇文章是关于一个简单得多,但在我看来,不平衡环境中更普遍的问题: 调整决策阈值,并将其“嵌入”到您的模型中。

在接下来的几节中,我将使用 scikit-lego ,这是一套非常棒的 sklearn 扩展(只要你认为“我希望 sklearn 可以这样做……”就可以检查这个包)和https://www.scikit-yb.org/en/latest/,这是一个用于机器学习可视化的包。它们都可以很好地与 sklearn 一起工作,所以你可以混合和匹配函数和类。

在我们开始之前的一些免责声明:首先,我假设你对 sklearn 有一些熟悉,所以不会深入每一行代码的细节。此外,我在这里的目标只是获得一些工作管道作为示例,因此我有意跳过数据科学过程的基本步骤,包括检查共线性、特征选择等。

构建初始 sklearn 管道

TL;DR:在这一节中,我将提醒您为什么管道会摇摆,并在样本数据集上创建一个管道。如果您是管道专家,请跳到下一部分!

当您构建和部署机器学习模型时,通常最佳做法是尝试使它们“尽可能端到端”。换句话说,试着将大多数与模型相关的数据转换组合成一个单独的对象,我们称之为模型。而在 sklearn 的世界里,你是通过管道来做到这一点的。

我开始使用 sklearn 管道作为数据科学的最佳实践。如果你不使用它们,你绝对应该阅读来自的这篇文章:其中一节解释了如果你不使用它们会出现什么问题,特别是数据泄露。随着我越来越多地使用它们,我意识到通过使用管道,您还可以将更多的东西抽象成您所谓的“您的模型”,,这对于部署来说非常棒。

通过使用管道,你还可以将更多的东西抽象成你所谓的“你的模型”

为了更具体地说明这一点,让我们在一个样本数据集上构建一个管道。我将使用 sklego 附带的关于心脏病的样本数据集。

这个数据集非常简单:9 个数值型(为了简单起见,我将有序的类别如 cp 保留为数值),3 个二元型( sex,fbs,exang ),1 个分类型( thal )。目标是二元的,不平衡的:只有 27%的样本有阳性标记。

我们不平衡的目标(图片来自 sklego 文档

我构建了一个由两个管道组成的快速管道,一个管道用于数值(为了简单起见,我将二进制和有序分类特征视为数值),另一个管道用于分类值。在训练数据中没有缺失值,但是为了防止它们在生产中出现,我加入了一些简单的插补。我注意到 thal 特性的一些类别似乎是错误的,所以我手动将我想要的类别提供给一个热编码,这样 sklearn 就不会对它们进行编码。

在下面的代码中,我实际上已经在使用 sklego 了。通常,我会为数字和分类特性编写不同的管道,然后定义要应用它们的特性列表,并使用 ColumnTransformer 将所有东西放在一起。有了 sklego,就简单多了:有一个PandasTypeSelector类,可以根据它们的熊猫类型选择列。我简单地把一个放在我的两个管道的开始,然后用一个 FeatureUnion 合并两个管道。****

现在我们已经完成了预处理部分,我们需要做的就是添加模型。这是一个小数据集和一个简单的问题,因此我将建立一个简单的逻辑回归。我将使用网格搜索来调整正则化参数 C,并将其他参数保留为默认值(再次,跳过模型构建的重要部分,不要在家复制!).

好了,我们现在有一个训练有素的管道与几个步骤,包括一个简单的模型。请注意,现在,我们还没有对不平衡做任何事情,但我们已经准备好了有趣的部分!

调整决策阈值

让我们透过混淆矩阵的镜头来看看模型预测。请注意,因为我们要做一些额外的调优,所以我们在训练集上这样做(在一个真实的项目中,我可能会分成训练、测试和验证来正确地做事情)。这里我们开始使用 yellowbrick,因为尽管使用 matplotlib 制作这种图表很容易,但是正如你所看到的,使用 ConfusionMatrix 类代码要简单得多。

我们的混淆矩阵显示,我们有更多的假阴性比假阳性

首先,我们可以看到这个样本模型做得很好(交叉验证的平均精度是 0.78):精度(当我们预测 1 时,我们有多少次是正确的?)是 0.8,而回忆(我们预测了多少真 1?)是 0.67。现在,我们问自己:这是精确和召回之间的正确平衡吗?我们喜欢低估还是高估我们的目标?在现实生活中,这是您将数据科学问题与真正的底层业务问题联系起来的时候。

现在,我们问自己:这是精确和召回之间的正确平衡吗?我们喜欢低估还是高估我们的目标?在现实生活中,这是您将数据科学问题与真正的底层业务问题联系起来的时候。

为了做出这个决定,我们看一个不同的图表,这就是 yellowbrick 真正强大的地方,它为我们提供了 DiscriminationThreshold 类。任何二元模型通常会输出一个概率或一个可用作概率代理的分数,您得到的最终输出(0 或 1)是通过对该分数应用阈值而获得的。我们能做的是定义依赖于该阈值的不同量,然后不断移动阈值,以观察这些量如何增加或减少。通常,随着阈值的增加,精度会增加,而回忆会减少:例如,如果将阈值设置为 0.9,则只有当 1 的可能性比 0 大得多时,模型才会预测 1,因此,预测的 1 会更少,但正确的机会会更多。

由 DiscriminationThreshold 类生成的图表

这张图表上有很多信息。首先,蓝、绿、红线对应的是非常常见的指标。我们已经讨论过精度和召回率,f1 是两者的调和平均值。我们可以看到,当第二个函数减小时,第一个函数增大,并且存在一个最佳点,在该点 f1 最大,即在精确度和召回率之间的平衡是理想的。Yellowbrick 通过在理想阈值处绘制一条虚线来帮助我们。

紫色数量指的是一个不同的数量,在学习数据科学时,您不一定要了解这个数量,但在现实世界的数据科学用例中,这个数量非常重要。yellowbrick 文档很好地描述了这一指标:

****排队率:“队列”是垃圾邮件文件夹或欺诈调查台的收件箱。此度量描述必须审查的实例的百分比。如果审查成本很高(如防止欺诈),则必须根据业务要求尽量降低成本。如果没有(如垃圾邮件过滤器),这可以优化,以确保收件箱保持干净。

最后,误差带向我们展示了这些量的不确定性:正如您在上面的代码片段中看到的,yellowbrick 为我们重新拟合了模型一定次数(默认为 50 次),我们在这里看到的是中位数和对应于四分位数范围(我手动设置)的带。

在我们的例子中,我们可以遵循 yellowbrick 的默认行为,即选择最佳 f1 分数(可以使用DiscriminationThresholdargmax参数进行更改),这意味着对于这个特定的问题,我们希望在精确度和召回率之间取得良好的平衡。

最后要注意的是,当我们执行网格搜索时,我们使用average_precision选择了最佳模型,这很重要。例如,如果我们使用 f1 分数,那么我们将只依赖默认阈值,因此可能会错过在不同阈值下产生更好 f1 分数的超参数组合。因此,我确保使用与阈值无关的度量来选择模型,然后才调整阈值。****

改变我们模型的决策阈值

在最后一部分,我们回到“端到端”的讨论。在您当前的不平衡模型中,您可能已经执行了决策阈值调优。但是接下来会发生什么呢?现在,您有了一个预测概率或分数的模型和一个二元预测,并且您知道不要相信该二元预测,因为您想要覆盖默认阈值。

但是,你究竟如何越过这个门槛呢?嗯,这个问题困扰我很久了。在我投入生产的一系列模型中,我们会将理想的阈值存储在某个地方,例如在部署环境中的环境变量中,然后调用模型的predict_proba()方法,并应用该阈值。维护起来比看起来要困难得多,因为你必须担心两件事:模型和它的门槛。每当你重新部署一个新版本的模型时,你都需要确保与它保持一致……疯狂的是,在 sklearn 存储库上已经有一个问题公开了 5 年多了!

嗯,正如我在本文开头提到的,每当你想到“我希望 sklearn 那样做……”的时候,就去 sklego 看看吧!

上面的代码片段有点难读,但是真的很有用!首先,我们从 yellowbrick visualizer 中提取最佳阈值,方法是访问我们选择的度量标准的底层 cv 分数数组(这里,visualizer.argmax等于f1)并获取它的argmax()。这为我们提供了最佳阈值在visualizer.thresholds_数组中的位置。据我所知(如果有更好的办法请掉个评论!)这是获得 yellowbrick 之前打印的最佳阈值(虚线)的唯一方法。

一旦我们有了这个,我们就创建了我们的最终管道,通过简单地将best_model包装在一个 Thresholder 对象中,当我们调用.predict()而不是默认的 0.5 值时,这个包装器负责应用指定的阈值。因为我们在创建 Thresholder 时传递了refit=False,所以.fit()调用不会重新调整包装的模型(请随意检查源代码以查看该调用中发生了什么)。

而且,就是这样!我们现在有一个完整的管道,不仅可以进行所有的预处理(因为访问您的模型的人不应该知道您正在进行缩放或一个热编码),使用您的业务问题的最佳阈值(因为我们不想低估或过度预测我们的目标),并将该阈值直接嵌入到模型中,实现更端到端模型的承诺!

编辑-2023 对此博客帖子的编辑

在本教程的原始版本中,最后一个代码片段稍微复杂一些(我重新定义了一个新的管道,并且只包装了估计器,即带有阈值的管道的最后一步)。从那时起,Sklego 团队实际上使事情变得简单了一点,如上所示,这要感谢这个 PR 。此外,正如他们在相关的问题中提到的,通过利用refit参数,可以更进一步,在调整其他超参数时(在 GridSearchCV 期间)直接执行阈值调整。为了保持文章的主要结构,我将阈值调整作为一个单独的步骤使用 yellowbrick(这也有其他好处),但两个选项都工作得很好!

如何在分析中添加发现阶段并创建双轨敏捷

原文:https://towardsdatascience.com/how-to-add-discovery-phase-and-create-dual-track-agile-in-analytics-527b090d4fab?source=collection_archive---------68-----------------------

在用看板构建 BI 解决方案中实施设计思维方法

在管理数据质量控制面板的五年时间里,我们从集中式的老式 BI 工具转变为以用户为中心的现代平台,支持自助分析。使命保持不变—通过显示相关指标和仪表板来帮助提高数据质量。

@钳工在 Unsplash 上的照片

除了工具本身的形状,开发过程也经历了漫长的旅程。结合设计思维,精益和敏捷是目前交付过程的基础。

为什么这很重要:

1.更好的产品—最终用户更好的验证

只有经过验证的功能才会交付给客户。它最小化了发布一个很少使用的特性的机会

2 效率—减少浪费,降低成本

  • 将流程分成两部分意味着更有可能在第一次就做对,而不是通过几次迭代来校准产品,这导致了更快的开发和发布周期
  • 因为产品 backlog 中只允许有效的特性,所以浪费的资源会更少。

我们从敏捷和开发开始,让用户清楚地定义他们需要的功能需求。该产品以正确的方式响应并动态调整客户需求。随着成熟和技能的增长,我们有一种感觉,通过在数据质量方面更加主动,我们可以做得更多。

我们的目标是交付超出现成需求的特性,并开始创建一个分析解决方案,从而带来更多的价值,并使用数据分析。我们的专业知识和技能在增长,但我们仍然不能完全满足客户的需求。

这是设计 101 工作坊开始的时候。

关键的学习是与我们的用户感同身受,让他们谈论问题,而不只是等待他们提供需求。我们开始利用我们的经验来发现和解决问题,而不仅仅是开发软件。

我们的方法发生了变化,我们正在创建向我们的利益相关者展示的微型产品(小型 MVP 或我们如何称之为最小可行仪表板),然后我们跟进最初的反馈,要么继续开发,要么只是减少损失。

概念是设计思维、精益创业和敏捷开发的结合,它包含两个共存的轨道——发现和开发。看板系统中的两条轨道并行工作,但是有不同的范围和目标。

作者图片

交付是以正确的方式生产产品。使用敏捷,我们可以动态响应,并允许我们的团队快速适应客户的需求。

发现是关于使用以下方式制造合适的产品:

  • 同理心:抓住真实的用户问题,建立对目标用户/顾客的同理心。这是关于研究和寻找机会。主要工具是访谈、调查和分析
  • 构思、创新和解决问题:产生尽可能多的想法和潜在的解决方案。
  • 原型和测试:为产生的想法建立低保真度的原型,准备在真实的或有代表性的用户身上进行测试。它允许在提交构建想法之前创建有效的想法。

探索路线应回答 3 个问题,外加一个额外问题:

  • 用户会用吗?(值)
  • 用户能用吗?(可用性)
  • 我们能建造它吗?(努力)

这 3 个是标准的,但是我们为功能特性增加了一个

  • 我们能重用它吗(可重用性)

因此,如果我们设法为重复数据删除或错误数据警报等功能创建一个有用的统计算法,那么另一个内容控制面板应该考虑的潜在价值。在许多情况下,这可能会扭转局势。

为了分散和更加敏捷,我们将产品(现在更多的是一个解决方案或平台)拆分为不同所有者和客户的较小产品,这样我们就可以轻松地执行设计阶段,因为应用程序应该服务于非常不同的用户组

技术变革至关重要。

开始时,整个应用程序是自定义开发的后端数据库级别加上记分卡的 C#网页。在某个时候,我们开始使用 PowerBI,这是一个游戏改变者,因为我们可以用快速切片和骰子来调整报告,而不是用 sprint planning 来处理每个小变化。

我们也有了第一批超级用户,我们能够使用我们准备的干净数据集创建他们的报告。

由于团队由开发人员和分析师组成,我们试图避免在两个轨道之间设置界限,并试图让每个人都参与进来,但开发人员将更多地参与数据库级别的后端开发和一些应用程序,而分析师则更多地专注于设计轨道,拥有一些额外的权力 bi 报告创建,但这只是纸上谈兵,实际上有很多合作。

双轨允许团队将精力投入到正确的功能上,并推出能够带来价值的产品。订阅并关注我,不要错过我们团队如何实现这一目标的下一部分。

如何使用预提交框架为您的 python 项目添加 git 挂钩

原文:https://towardsdatascience.com/how-to-add-git-hooks-for-your-python-projects-using-the-pre-commit-framework-773acc3b28a7?source=collection_archive---------8-----------------------

PC:维基媒体(【https://commons.wikimedia.org/wiki/File:Fish-hook.JPG】T2

为什么我们需要饭桶挂钩?

作为开发人员,我们需要确保我们正在编写的程序的可读性、可写性和可靠性。如果我们采取 git repo,多个贡献者每天编写或修改数百行代码,新的贡献者进来,很少人出去。所以为了使代码库一致,我们必须遵循一定的标准。例如,某些代码格式样式(黑色)或林挺样式(flake8)等。通常,这些健全性检查发生在提交(提交)代码以供审查之前,也可能有提交之后需要完成的操作,比如维护内部日志。

在深潜之前,让我告诉你我们今天要看什么,

  1. 什么是 Git 钩子?
  2. 什么是预提交框架?
  3. 如何在 python 项目中使用预提交框架?

什么是 Git 钩子?

正如我在上面提到的,当开发工作流中发生事件时,我们需要执行某些动作(任务),这就是所谓的钩子。

Git 挂钩是每当 Git 存储库中发生特定事件时自动运行的脚本。

例如,在每次提交之前运行黑色格式化和薄片 8 林挺。实际上,我们可以在 git 事件的不同阶段添加钩子。

  • 预提交:-在提交前运行特定的钩子,如果失败,则中止提交
  • 预合并-提交:-在合并前运行某个钩子,如果失败,中止合并
  • 预推送:-在推送至远程存储库之前运行某个挂钩,如果失败,则中止推送
  • 提交后:-在成功提交后立即运行钩子
  • 结帐后:-从一个分支结帐后立即运行挂钩
  • 合并后:-在成功合并后立即运行挂钩
  • 等等

当我们做git init时,它将最常用的 git 钩子添加到.git/hooks/,中,我们可以使用最常用的脚本语言编写自己的钩子。但今天我们将看到一个旨在简化这一过程的框架。

什么是预提交框架?

这是一个管理和维护多语言 git 挂钩的框架。你可能会有一个问题,为什么我们需要一个钩子的框架。

随着我们创建更多的库和项目,我们可能会发现跨项目共享我们的预提交钩子是痛苦的。我们不得不从一个项目到另一个项目复制和粘贴笨拙的 bash 脚本,并且不得不手动改变钩子以适应不同的项目结构。有时我们需要的一些好的 linters 或其他测试工具,可能不是用我们项目中使用的语言编写的。

预提交是一个用于预提交挂钩的多语言包管理器。我们可以简单地指定我们想要的钩子列表,预提交管理任何用任何语言编写的钩子的安装和执行,而不需要任何 root 权限。

如何在 python 项目中使用预提交框架?

  1. 安装提交前框架
pip install pre-commitorconda install -c conda-forge pre-commit

.pre-commit-config.yaml添加到项目的根文件夹中。在这个例子中,我将展示如何为每次提交和推送添加黑色格式和林挺。

让我们在这里分解每个组件,

  • default_stages:-钩子的 stages 属性的配置级默认值。这只会覆盖不设置阶段的单个挂钩。
  • default_language_version:-如果没有为各个挂钩设置 language_version,则应该使用的默认语言版本。
  • 仓库:-仓库映射列表
  • repo:-git clone 的存储库 URL,钩子的代码将从这里获取。
  • 版本:-需要使用哪个版本的回购(标签)
  • 钩子:-钩子映射的列表,钩子映射允许用户从 repo 中选择需要使用哪个钩子,并允许定制。
  • id:回购中的挂钩名称。
  • args:需要为该钩子传递命令行参数。
  • exclude:- regex 表示要为该挂钩排除的文件/文件夹名称。
  • 类型:-该钩子要考虑的文件类型。

还有很多组件,可以自定义钩子。

2.添加配置文件后,运行下面的命令来安装钩子

pre-commit install --hook-type pre-commit hook-type pre-post

这将安装应该在提交和推送之前运行的挂钩。

3.修改项目中的任何文件,并尝试提交它们

失败的预提交(PC:作者)

这里,由于一些代码重新格式化和 lint 错误,我的钩子失败了。注意,如果任何挂钩失败,那么提交将被中止。解决问题并重新提交。

成功的预提交(PC:作者)

如果您已经配置了任何预推挂钩,这将是相同的。

成功的预推送(PC:作者)

你可以在这里找到完整的源代码,https://github.com/Mathanraj-Sharma/python_boilerplate

总之,git 钩子就是我们希望在 git 事件发生时触发的任何脚本。它有助于自动化重复性工作,以保持所编写代码的一致性。在早期阶段,它可能看起来不太有效,但是随着项目的增长和更多贡献者的加入,我们可以感受到 git 挂钩的好处。

编码快乐!!!

如何向 Python 绘图添加渐变背景

原文:https://towardsdatascience.com/how-to-add-gradient-background-to-python-plots-9beda811ea19?source=collection_archive---------14-----------------------

本文讨论了一种在 Python 中向绘图添加渐变背景的简单方法

作者图片

我们有时可能需要给绘图添加多色背景,以突出绘图的几个部分。例如,我们可以分别用红色和绿色突出显示衰退和复苏的时期。在本文中,我们将讨论在 Python 中实现这一点的简单而有效的方法。对于 Tableau 用户,这类似于添加参考波段。

我们将讲述 Nifty(印度股票市场的基准指数)在新冠肺炎期间的表现。我们将分别用红色和绿色突出显示低迷期和恢复期,并使用渐变背景来描述波动性。

在上面的代码片段中,变量 nifty 存储 nifty 从 2020 年 1 月 1 日到 2020 年 9 月 18 日的收盘值。变量 slump 存储了 Nifty 从 2020 年 2 月 19 日到 2020 年 5 月 18 日的收盘值,这是 Nifty 因新冠肺炎而崩盘的时期。变量 recovery 存储 Nifty 从 2020 年 5 月 18 日到 2020 年 9 月 18 日的收盘值,这是 Nifty 开始从新冠肺炎复苏的时期。下面是 俏皮的 数据框的快照。

漂亮的数据框(图片由作者提供)

为了理解情节中的内容,我们将绘制没有任何背景颜色的时间序列,并讲述 Nifty 在新冠肺炎的旅程。

作者图片

在上面的图中,衰退和复苏的时期分别用红色和绿色突出显示。有一些注释突出了主要事件。还有一个更大字体的注释,强调了屠杀的天数。如果我们需要描述萧条和复苏时期的波动性,那该怎么办?我们可以通过使用渐变背景来做到这一点。虽然这种方法可能计算量很大,但使用它可以给故事增加一个新的维度。我们将看看代码添加渐变背景到上面的情节。

作者图片

渐变背景是怎么添加的?

  1. 我们计算了低迷期和恢复期数值的 3 天移动平均值。
  2. 移动平均值在 0.15 到 1 的范围内进行归一化,作为红色和绿色垂直线(axvline)的 alpha 值,绘制为图的背景。对于红线,标准化移动平均值越高,线就越亮。对于绿色线条,标准化移动平均值越高,线条越暗。
  3. 每个标准化值重复 10 次,因为垂直线将被绘制成 x 刻度递增 0.1,即每个单个 x 刻度有 10 条垂直线。
  4. 归一化移动平均值的最后一个值重复 20 次,以确保值的数量与原始时间序列的数量相同,因为移动平均值计算将导致时间序列中值的数量减少。
  5. 垂直线作为绘图的背景,x 刻度以 0.1 为增量。

在上面的图中,我们可以看到在复苏的初始阶段交替出现的亮绿色和暗绿色条带,表明复苏的初始阶段比后期阶段更加不稳定。我们还可以看到一条较暗的红色带,Nifty 在 7610.25 点触底。

本文到此结束。我们已经讨论了如何使用多种颜色向 Python 绘图添加渐变背景。这种技术可以用来突出商业周期。保持垂直线的 alpha 值不变将产生多色背景,而不是渐变背景。

如何将图像作为尺寸添加到 Tableau 表格中

原文:https://towardsdatascience.com/how-to-add-images-as-dimensions-in-a-tableau-table-draft-219e65b7eced?source=collection_archive---------7-----------------------

在本教程中,我们将了解如何在一个简单的 Tableau 表格的一列或多列中使用图像。

作者图片

你可以从 这个链接 下载一个包含本教程所有内容的 zip 文件。在 zip 存档中,您可以找到我们将在本教程中制作的 Tableau 工作簿,或者您也可以按照说明自己制作。

在这个故事中,我将使用 macOS 系统的 Tableau Desktop 2018.3(试用版)。

准备工作环境

首先,我们必须准备一个自定义调色板形状 ,这听起来可能很难,但却非常简单,我们唯一要做的就是将“西欧旗帜”文件夹复制到以下文件夹之一,这取决于你使用的是 Mac 还是 Windows 系统。

Mac

/用户/ <用户>/文档/我的 Tableau 资源库

视窗

C:\Users\ <用户> \Documents\My Tableau 资源库

Flags PNG 文件由 Flagpedia 网站提供。

资料组

我们将使用世界卫生组织(世卫组织)制作的文件“世界卫生 2020”数据集,特别是“alcoholsubstanceabuse . CSV”文件。CSV 文件包含在上面描述的 zip 存档中,但是您可以通过点击链接到相关的 Kaggle 页面来找到整个数据集。

我们走吧

因为我们是数据分析师,而不是魔术师,所以没有理由对我们在 Tableau 表的列中包含图像的工作区保密。解决方法基本上包括制作两个具有相同上下文https://anthonysmoak.com/2020/10/06/understanding-tableau-context-filters/****的表格,并使用透明背景将它们重叠。将自定义图像包含到 Tableau 表格中的最佳(也可能是唯一)方法是创建一个自定义形状调色板,并在标记区域中使用它,这允许用户通过直接在表格中添加尺寸相关的图像来自定义表格,但不允许完全控制图像的位置,因为您只能决定将它们包含到标记区域中。

以下说明将伴随您完成制作此解决方法的工作示例的所有步骤。

作者图片

像往常一样,我们必须将 Tableau 桌面工作簿连接到我们的数据源。在“数据源”选项卡中,我们在“位置”字段中插入了一个数据源过滤器,因此我们将只处理西欧国家,特别是:

  • 奥地利
  • 法国
  • 德国
  • 爱尔兰
  • 意大利
  • 葡萄牙
  • 西班牙
  • 瑞士
  • 大不列颠及北爱尔兰联合王国

作者图片

现在是时候转到“工作表 1”并遵循以下步骤:

  1. 表 1 重命名为图例
  2. 在标记菜单中,从下拉列表中选择形状
  3. 将尺寸列表中的位置药丸拖放到标记菜单中的形状图标上;

4.点击形状的图标;

5.点击“重新加载形状”按钮,这将加载我们全新的自定义形状调色板和国家的国旗;

6.从下拉调色板中选择“标志西欧”;

7.映射每个项目(国家)及其标志,然后单击“确定”;

作者图片

8.新建一个工作表,重命名为“表格数据”;

9.在分析菜单中取消选中“聚合措施”;

10.拖拽位置Dim1 药丸到成排区域;

11.将第一个工具提示药丸拖放到标记区域;

12.将“周期”拖放到过滤器区域;

13.在常规选项卡中,勾选“全部使用”;

14.在行区域,右键点击位置,选择“显示过滤器”;

15.点击右边栏的位置滤波控制器上的向下箭头,将其设置为单值(列表)

16.再次点击,进入自定义,取消勾选显示所有值

17.在过滤器区,右键点击“周期”药丸,点击“显示过滤器”;

18.点击右边栏中“周期滤波控制器”上的向下箭头,将其设置为“单值(列表)”;

19.再次点击,进入自定义,取消勾选显示所有值

20.右键点击行区域中的位置药丸,选择滤镜

21.转到“ Top ”选项卡,按字段“ First Tooltip ”选择前 5 名;

22.右键点击行区域中的位置药丸,选择排序

23.按“第一个提示信息升序排列;

24.创建一个名为“标志图标的计算字段,并将其设置为空;

作者图片

25.拖动标志图标药丸,放在位置Dim1 之间的行区域;

26.将行高设置为实际高度的两倍;

作者图片

27.进入格式底纹菜单,设置为默认,工作表;

作者图片

28.复制工作表“表数据”,重命名为“表标志”;

29.转到“表格标志”工作表;

30.在标记区从下拉列表中选择形状

31.拖动位置药丸,放在形状图标上;

32.从标记区删除第一个提示药丸;

33.右击“位置标签,选择“格式…”;

34.在默认字体窗口中设置白色。

35.右键点击“葡萄牙”(任何其他国家),选择“格式…”;

36.对“ Dim1 ”值做同样的操作;

37.转到格式菜单中的"边框"选项卡,将""放入列分隔线和行分隔线;

作者图片

38.创建一个新仪表板,并将其重命名为“酒精物质滥用”;

39.将“表格数据”和“表格标志”拖放到仪表板中;

40.将表格设置为浮动,并删除任何图例或过滤器控制器;

41.点击“表格数据区域的向下箭头,选择过滤器,“期间”;

42.点击“周期滤波控制器”中的向下箭头,选择“单值(列表)”;

43.点击“周期过滤控制器”中的向下箭头,取消勾选自定义,“显示所有值”;

44.点击“期间过滤控制器”中的向下箭头,勾选应用到工作表,“全部使用此数据源”;

45.对“ Dim1 ”过滤器进行同样的操作;

46.点击“表标志区的向下箭头,选择浮动订单,“送至后台”;

47.点击“表格标志区域的向下箭头,取消选择“标题”;

48.点击“表数据区的向下箭头,选择浮动订单,“前置”;

49.点击“表格数据区域的向下箭头,取消选择“标题”;

50.在布局页签中,对“表格数据”和“表格标志”的 xyw、 z 设置相同的值;

51.选择“表格数据,在布局面板中设置“”为背景;

51.手动调整列宽,使图标出现在标志图标标签下;

作者图片

作者图片

结论

在这一长串步骤的最后,您可能已经开发了自己的 Tableau 工作簿,其中第二列中有各国国旗。如果您遇到任何问题,您可以下载完成 Tableau 工作簿的 zip 文件。如果你发现了任何快速的解决方案,请在下面的评论区分享,当然,也可以通过下面我的推荐联系我。

如何在不到 5 分钟的时间内增加交互式模型的可解释性

原文:https://towardsdatascience.com/how-to-add-interactive-model-explainability-in-less-than-5-minutes-af4f3379f30f?source=collection_archive---------29-----------------------

让 shapash python 包为您完成这项工作

作者 gif

不要在没有准备好的情况下参加下一次演示

理解你的模型在做什么是非常重要的。评估模型的信息越多,对模型的调整就越好。即使你对算法的内部运作有深刻的理解,你的商业伙伴也不了解。你需要能够生动有趣地展示你的发现。

有时,业务合作伙伴有更多的主题专业知识,可能有助于提供特性上下文。如果他们真的理解你传达的内容,他们可以帮助你进一步调整模型。

我听到的最常见的问题之一是,“什么数据进入模型?”哪个翻译成"哪个特性最重要?”。你需要准备好以他们能理解的方式回答这个问题。Shapash 提供了一些有趣的输出,可能有助于您通知您的受众。

为什么要尝试 shapash?

我总是在寻找有趣的包来用于我的日常工作,我遇到了 shapash。如果你了解我,你知道我不喜欢争论。该软件包必须易于使用,否则它没有机会快速验证概念。仅仅几行代码就为您的模型脚本增加了交互式和类似报告的可解释性。

我认为这是完全值得你花时间去看看这个包和它的产品。设置很简单(记住,我不太喜欢麻烦)。我在下面详述了这些步骤。

装置

一如既往,建议您创建一个新的虚拟环境。我在下面的参考资料部分包含了安装过程的链接。对于这个例子,我使用的是 Jupyter,所以我只需要安装 ipywidgets(并启用)和 shapash。

添加这个简单的代码块。

在训练完模型(在本例中为“回归器”)之后,添加一个简单的代码块来编译和执行 SmartExplainer。本文后面附有完整的示例代码。

from shapash.explainer.smart_explainer import SmartExplainer
# shapash Step 1: Declare SmartExplainer Object
xpl = SmartExplainer()# shapash Step 2: Compile Model, Dataset, Encoders
xpl.compile(    x=Xtest,    
                model=regressor,    
                preprocessing=encoder, #optional
                y_pred=y_pred) # shapash Step 3: Display interactive output
app = xpl.run_app()

运行代码

您应该从数据获取、特征工程和模型训练到模型评分来运行您的代码。接下来,当您执行 run_app()时,将显示一个应用程序链接。

作者截图

只需单击该链接,打开一个带有您的输出的浏览器窗口。您将能够浏览各种可视化效果。

shapash app —作者 gif

奖励—生成 HTML 报告的代码片段

当您想要与同事共享发现时,您可以生成 HTML 报告来共享。

# Step 4: Generate the Shapash Report
xpl.generate_report(
        output_file='medium_spending_scores_report2.html',
        project_info_file='shapash_project_info.yml',
        x_train=Xtrain,
        y_train=ytrain,
        y_test=ytest,
        title_story="Spending Scores Report",
        title_description="""This is just an easy sample.
            It was generated using the Shapash library.""",
        metrics=[
            {
                'path': 'sklearn.metrics.mean_absolute_error',
                'name': 'Mean absolute error',
            }])

HTML 报告——非常好。作者 gif

完整示例代码

Jupyter 笔记本和文件:

https://github.com/dmoyer22/simple_shapash_example

。py 版本:

参考文献

https://github.com/MAIF/shapash https://shapash.readthedocs.io/en/latest/installation-instructions/index.html

结论

我认为 shapash 在模型可解释性工具箱中有一席之地。如果你不能向非技术同事解释你的工作,你的结果可能会被忽视。没有人希望这种情况发生。

我看到的在工作场所推进其数据科学职业生涯的人,是那些演讲精彩并直接面向特定受众的人。所以,照吧!

如何在 Python f-strings 中添加新行

原文:https://towardsdatascience.com/how-to-add-new-line-in-python-f-strings-7b4ccc605f4a?source=collection_archive---------4-----------------------

如何修复语法错误:f 字符串表达式部分不能包含反斜杠

由 Kevin Mak 在 Unsplash 上拍摄

介绍

在 Python 中,不可能在 f 字符串的花括号{}中包含反斜杠。这样做会导致一个SyntaxError:

>>> f'{\}'
SyntaxError: f-string expression part cannot include a backslash

这种行为完全符合 PEP-0498 关于文字字符串插值的要求:

反斜杠不能出现在 f 字符串的表达式部分中,所以你不能使用它们,例如,在 f 字符串中转义引号

在接下来的几节中,我们将探索几个选项,你可以使用这些选项在 f 弦中添加反斜杠(包括新行)。

在 f 弦中使用反斜杠

正如我们已经讨论过的,反斜杠不能直接在 Python f 字符串中使用。但是,有一个简单的解决方法,允许我们使用反斜杠来表示新行、制表符等。

假设我们有一个想要输出到标准输出的整数列表。

nums = [10, 20, 30] 
print(f"Numbers:\n {'\n'.join(map(str, nums))}")

不出所料,上述操作将会失败

SyntaxError: f-string expression part cannot include a backslash

一种解决方法是将新的行字符(即'\n')添加到一个字符串变量中,然后在打印出数字时引用该变量。举个例子,

new_line = '\n'
nums = [10, 20, 30] 
print(f"Numbers:{new_line}{new_line.join(map(str, nums))}")

输出应该是

Numbers:
10
20
30

请注意,您可以对几乎所有需要反斜杠的字符都这样做。例如,让我们假设您想要在 f 字符串中使用制表符。以下应该是窍门:

tab = '\t'
print(f'Hello {tab} World!')# Output
Hello   World!

如何在 f 弦中添加新的一行

特别是对于新行,我们还可以遵循另一种方法在 Python f-strings 中添加新的行字符。

os包附带了一些关于其他系统信息的功能。这包括返回新行字符的[os.linesep](https://docs.python.org/3/library/os.html#os.linesep)

用于在当前平台上分隔(或者说,终止)行的字符串。这可以是单个字符,比如 POSIX 的'\n',也可以是多个字符,比如 Windows 的'\r\n'

举个例子,

import osnums = [10, 20, 30] 
print(f"Numbers:{os.linesep}{os.linesep.join(map(str, nums))}")

输出将再次是

Numbers:
10
20
30

请注意,在编写以文本模式打开的文件时,必须避免使用os.linesep作为行终止符。相反,你必须使用单个的'\n'

另一种可能,是用chr()功能生成一个新的行字符。Python 中的chr()函数返回对应于 Unicode 字符的输入整数的字符串表示。Unicode 中10的十进制值相当于换行符(即新行)。

>>> chr(10)
'\n'

因此,为了使用chr()在 f 弦中添加新的线条,您需要做的就是

nums = [10, 20, 30] 
print(f"Numbers:{chr(10)}{chr(10).join(map(str, nums))}")# Numbers:
# 10
# 20
# 30

最后的想法

在今天的文章中,我们讨论了 Python 的一个限制,它阻止我们在 f 字符串中使用反斜杠。我们介绍了一些可能的解决方法,并且我们还特别探索了如何在 Python f-strings 中隐式地添加新行。

本质上,你有三个选择;第一个是定义一个新行作为字符串变量,并在 f-string 花括号中引用该变量。第二种解决方法是使用返回新行字符的os.linesep,最后一种方法是使用对应于 Unicode 新行字符的chr(10)

如何在 Python 中向散点图添加文本标签(Matplotlib/Seaborn)

原文:https://towardsdatascience.com/how-to-add-text-labels-to-scatterplot-in-matplotlib-seaborn-ec5df6afed7a?source=collection_archive---------0-----------------------

使用 seaborn 或 matplotlib 库时,如何在 python 中向散点图添加文本标签的分步指南

Python 非常适合数据可视化!Matplotlib 非常快速和健壮,但是缺乏美感。基于 matplotlib 构建的 Seaborn 库极大地提高了美观性,并提供了非常复杂的情节。然而,当涉及散点图时,这些 python 库没有任何直接的选项来显示数据点的标签。在 Tableau 和 Power BI 等其他数据可视化工具中也有这个特性,只需点击几下或者将指针悬停在数据点上。

在本文中,我将解释如何向 seaborn 或任何其他基于 matplotlib 框架构建的库制作的散点图添加文本标签。

数据

数据集是英超积分榜。我们感兴趣的有三列:
一、队:队名
二。 G:进球得分
iii。 GA:失球

散点图:进球数与失球数

可以绘制一个简单的散点图,其中进球得分在 x 轴上,失球在 y 轴上,如下所示。

plt.figure(figsize=(8,5))
sns.scatterplot(data=df,x=’G’,y=’GA’)plt.title(“Goals Scored vs Conceded- Top 6 Teams”) #title
plt.xlabel(“Goals Scored”) #x label
plt.ylabel(“Goals Conceded”) #y label
plt.show()

基本散点图

标记特定项目

最常见的散点图可能包含大量的数据点,我们可能会对某些特定项目相对于其他项目的表现感兴趣。标注所有的数据点可能会使你的绘图过于笨拙,难以理解。例如,如果我们正在检查美国的社会经济统计数据,在散点图中显示所有国家的标签是没有意义的。如果美国和其他选定的竞争对手的数据被标记出来,这将是有用的,这样我们就可以了解这些国家相对于彼此和世界其他地区的表现如何。
来到我们的数据集,我是托特纳姆热刺队的球迷,我只对托特纳姆热刺队对阵其他球队的表现感兴趣。
我可以使用 plt.text() 添加标签

*Syntax: 
plt.text(x=x coordinate, y=y coordinate, s=string to be displayed)*

He x 和 y 分别是 TOT 的进球数和失球数。要显示的字符串是“TOT”
x、y 和 s 是位置自变量,如果遵循它们的顺序,则不需要明确提及。

plt.text(df.G[df.Team=='TOT'],df.GA[df.Team=='TOT'],"TOT", color='red')

颜色大小阿尔法(透明性)等附加参数。可用于更改文本格式。它也可以在 fontdict 中分组,使你的代码易于阅读和理解。

plt.text(df.G[df.Team==’LIV’],df.GA[df.Team==’LIV’],”LIV”, 
 fontdict=dict(color=’black’, alpha=0.5, size=16))

带有特定标签的散点图(图片由作者提供)

添加背景框

bbox 参数可用于突出显示文本。

sns.scatterplot(data=df,x=’G’,y=’GA’)
plt.text(x=df.G[df.Team==’TOT’]+0.3,
         y=df.GA[df.Team==’TOT’]+0.3,
         s=”TOT”,
         fontdict=dict(color=’red’,size=10),
         bbox=dict(facecolor=’yellow’,alpha=0.5))

请注意,x 和 y 坐标上添加了 0.3 的缩进,以便文本和背景框不会与数据点重叠。
这是可选的,但可以提高图表的美观性。

带文本框的散点图(图片由作者提供)

标记所有点

有些情况需要标记散点图中的所有数据点,尤其是当数据点很少时。
这可以通过使用一个简单的 for 循环遍历数据集并添加 x 坐标、y 坐标和每行的字符串来完成。

sns.scatterplot(data=df,x=’G’,y=’GA’)for i in range(df.shape[0]):
 plt.text(x=df.G[i]+0.3,y=df.GA[i]+0.3,s=df.Team[i], 
          fontdict=dict(color=’red’,size=10),
          bbox=dict(facecolor=’yellow’,alpha=0.5))

带所有标签的散点图(图片由作者提供)

最后一击

我们已经完成了标签散点图的构建。但是,我们可以观察到一些文本框突出在图形区域之外。如果文本能够被包裹在情节的画布中,将会更具美感。这可以通过改变位置、大小等来实现。的文本。
我通常通过使用 matplotlib 中的 xlim()ylim() 函数来增加绘图区域来实现这一点。
在下面的代码中,你可以看到我是如何在设置 x 和 y 限制时,在绘图周围应用 1 个单位的填充的。

plt.figure(figsize=(8,5))
sns.scatterplot(data=df,x=’G’,y=’GA’)for i in range(df.shape[0]):
 plt.text(x=df.G[i]+0.3,y=df.GA[i]+0.3,s=df.Team[i], 
          fontdict=dict(color=’red’,size=10),
          bbox=dict(facecolor=’yellow’,alpha=0.5))plt.xlim(df.G.min()-1,df.G.max()+1)                #set x limit
plt.ylim(df.GA.min()-1,df.GA.max()+1)              #set y limit plt.title(“Goals Scored vs Conceded- Top 6 Teams”) #title
plt.xlabel(“Goals Scored”) #x label
plt.ylabel(“Goals Conceded”) #y label

plt.show()

带标签的填充散点图(图片由作者提供)

如果你知道任何更好的方法来包装画布区域内的元素,请在评论中告诉我。

资源:

你可以在 GitHub 查看这篇文章的笔记本。

成为会员

我希望你喜欢这篇文章,我强烈推荐 注册中级会员 来阅读更多我写的文章或成千上万其他作者写的各种主题的故事。
你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。

这里有一些你可能感兴趣的其他故事。

迈克尔·泽兹奇在 Unsplash 上拍摄的照片

如何使用共形预测将不确定性估计添加到模型中

原文:https://towardsdatascience.com/how-to-add-uncertainty-estimation-to-your-models-with-conformal-prediction-a5acdb86ea05?source=collection_archive---------5-----------------------

为什么不确定性估计的共形预测可以改善您的预测

扎克·萨维纳尔在号航天飞机上的照片

预测建模在社会中的流行正在增加,并且这些算法在我们的社会中的角色正在改变。许多人关心对这些算法的信任程度。欧洲引入 GDPR 等政策变化表明,人们想知道这些对我们生活有如此大影响的算法是如何工作的。

点预测对回归问题意味着什么?在训练过程中对数据的微小改变会对输出产生很大的影响吗?您有多确定点估计是您试图预测的实际值?

同样,对于分类,在二元问题中,预测是 0 还是 1 是什么意思?你的模型能预测相反的等级吗?还是它如此确信实际值是您可以确定的 1 类?

对于任何一个有监督的问题,输出只是整体解决方案的一部分。了解不确定性在预测建模中是如何工作的,这就引出了本文的主题,共形预测。

我在这篇文章中加入了共形预测的背景信息。所以对于那些寻找复制粘贴代码的人来说,向下滚动并复制。

保形预测

共形预测是一种模型不可知的方法,用于计算监督问题的不确定性估计。本文将在归纳共形预测(ICP)的背景下讨论共形预测,但我们知道还有另一种形式,即转导共形预测(TCP)。

由于模型不可知,任何模型都可以包含共形预测。因此,无论您有复杂的深度学习分类器还是具有 1000 个估计量的随机森林,共形预测都可以包含在模型中。这一方面使得共形预测模型不可知。

无论问题是回归问题还是分类问题,不确定性估计都有不同的形式。

对于回归问题,共形预测会将点预测更改为预测间隔。这些间隔围绕着您的模型所做的点估计,间隔的大小直接与您想要的模型确定程度相关联。

对于分类问题,保形预测将单类预测变为集合预测。这些集合可以包括您试图预测的每个可能的类。当存在多个类别时,这表明您的模型对预测不太确定。而且,集合也可以是空的。如果是这种情况,那么您的模型确实不确定要预测什么类。当您希望您的预测更有把握时,更多的类将出现在您的预测集中。

在问题的回归和分类版本中,输出的大小由用户控制。这个影响输出的参数被称为重要性。

保形预测在统计上是有效的。例如,如果将显著性设置为 0.1,则集合和区间将在 90%的时间内包含实际类或真值。这个属性意味着一个测试实例的真实值在 90%的时间内将会落在您的区间内,或者测试实例的真实值将会在预测中。

计算这些区间和集合的方法遵循三个步骤。对于 ICP,数据分为三组:训练、校准和测试。具体做什么的细节将在下面讨论。

缺点和顾虑

听起来不错。好吧,这些统计保证有两大警告。第一个是保形预测是在可交换性假设下定义的。这种假设意味着保形预测假设您用来训练数据、验证和测试数据的数据是可交换的。这有一个详细的数学公式,但本质上,这就是它的意思。

为训练模型而选择的数据可以放入测试集中。或者考虑您用于校准的数据。同样,这些数据可以用于训练或测试。

每个记录都可以与另一个记录交换。

但是可交换性有更强的含义。对于可交换的数据,整个数据集必须来自同一分布。虽然对于许多数据集和将来的实例来说,这一方面是已知的,但是对于其他数据集来说,数据分布会随着时间而变化。在这些情况下,保形预测仍然可以提供一些不确定性估计,但理论上的保证不再可靠。

第二个警告是不确定性估计有一个权衡。例如,假设您希望 90%地保证您的预测区间包含真实值。在这种情况下,你会有更大的间隔。但是如果你只想有 50%的把握,那么你的间隔时间会长很多。

分类类似。更多的信心,更大的集合。信心更少,套数更少。

然而,这些集合和间隔大小并不简单地线性缩放。相反,它们与您的模型的性能直接相关。所以显著性为 0.5 的区间可能比显著性为 0.1 的区间小很多。

戴维·罗蒂米在 Unsplash 上的照片

符合与不符合

保形预测的中心思想是围绕着一致性的概念。或者反过来说,不合规。这个概念是预测区间和预测集的核心。但它到底是什么?

不一致分数衡量每条记录与其余数据不一致的程度。

对于回归,非一致性分数通常被测量为模型预测和校准实例的真实值之间的差异。

不一致分数是二元分类的校准数据上与您的分类器相反类别的预测概率。

注意这里校准数据集的使用。首先,根据一组数据训练模型,然后根据校准集计算不合格分数。接下来,根据这些校准分数和用户指定的显著性水平,保形预测构建区间或调整如何将类添加到分类集中。

使用显著性水平以及一组不一致性分数来确定预测区间。基于用户重要性,通过取分数的第 n 个百分点来粗略计算区间。因为回归的不一致性分数是预测校准和真实校准之间的差异,所以一致性分数是误差。

对于分类,事情的安排略有不同。不一致性分数代表每个类别的预测概率。如果对于用户指定的显著性水平,预测的概率与该显著性一致,则每个类别被包括在该集合中。此处的细节根据所使用的确切不合格分数而有所不同。然而,选择在集合中保留哪些类的过程仍然是相同的。

测试和校准

执行校准后,模型可以预测不确定性。

但是剩下的工作是测试保形预测器是否正常工作。比如预测类集中是否存在真实类?真值存在于预测区间吗?

为了回答这两个问题,共形预测器具有它们的校准曲线形式,因为估计的不确定性取决于显著性水平,模型的性能随着该显著性而变化。

在不同的显著性水平上评估性能,以确保具有不确定性的预测在多个显著性水平上是一致的。

校准曲线(作者照片)

根据设计,显著性水平为 0.1 的共形预测值应该在 90%的时间里包含实际值。因此,通过用 0 和 1 之间的值改变显著性来评估性能应该与从 0 到 1 的线性线对齐。

通常情况下,情况并非如此。然而,对于越来越大的数据集(完全代表其分布的数据集)和性能良好的模型,校准曲线接近完美的线性。

当校准曲线不完全一致时,这意味着一些事情。数据可能不是来自同一个分布。如果数据是真正可交换的,那么根据保形预测的定义,你应该看到校准。

除了具有校准良好的共形预测器之外,另一个方面值得评估— 区间的大小和集合的大小。

当一个模型在统计上保证了分类和回归的不确定性估计时,这是很好的,但是大小很重要。例如,如果每个预测集包含所有类,则该模型没有帮助。类似地,对于回归,如果每个区间都是巨大的,那么,当然,真实值会落在其中的某个地方。

由于这些原因,通常显示保形预测器的区间大小和预测集的平均大小。

此处未显示但值得查看的一些其他度量是共形分类器的单线数和共形预测器的 p 值分布。

当你的分类器非常确定时,单态的数量给你一个概念。

并且 p 值的分布类似于校准曲线。因此,当一个图被完美校准时,p 值的分布应该是均匀的。

应用保形预测

对于这篇文章,我将使用库‘nonconformist ’,它实现了保形预测的几种算法。此外,我添加了一些扩展来展示保形预测的一些属性。

注意,在撰写本文时,nonconformist 的基本安装是建立在旧版本的 sklearn 上的。有些模块导入 sklearn.cross_validation,需要修改为导入 sklearn.model_selection。您可以在您的环境中的“site-packages”下找到该包。

这第一部分代码有一些通用的导入和用于校准图的函数。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris, load_boston
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from nonconformist.icp import IcpClassifier, IcpRegressor
from nonconformist.nc import ClassifierNc, MarginErrFunc, ClassifierAdapter, RegressorNc, AbsErrorErrFunc
from sklearn.model_selection import train_test_splitdef regression_calibration_curve(estimator, X, y, alphas=np.linspace(0.1,1,10, endpoint=True)):
    errors = []
    interval_sizes = []
    for a in alphas:
        pred = estimator.predict(X, significance=a)
        interval_sizes.append(np.mean([y-x for x, y in pred]))
        errors.append( 1 — np.mean([x <= z and z <= y for (x,y), z in zip(pred, y)]))
    return errors, interval_sizesdef regression_calibration_plot(estimator, X, y, alphas=np.linspace(0.1,1,10, endpoint=True)):
    errors, interval_sizes = regression_calibration_curve(estimator,X,y,alphas)
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ax1.plot([0,1], [0,1])
    ax1.plot(alphas, errors, ‘o’)
    ax2.plot(alphas, interval_sizes, ‘ — ‘)
    ax1.set_xlabel(‘Significance’)
    ax1.set_ylabel(‘Error Rate’)
    ax2.set_ylabel(‘Avg. Interval Size’)
    plt.title(‘Regression Conformal Calibration Curve’)
    plt.show()def classifier_calibration_curve(estimator, X, y, alphas =np.linspace(0,1,10, endpoint=True)):
    errors = []
    set_sizes = []
    for a in alphas:
        pred = estimator.predict(X, significance=a)
        set_sizes.append(np.mean([np.sum(set) for set in pred]))
        errors.append(1 — np.mean([set[t] for set, t in zip(pred, y)]))
    return errors, set_sizesdef classification_calibration_plot(estimator, X, y, alphas=np.linspace(0,1,10, endpoint=True)):
    errors, sizes = classifier_calibration_curve(estimator,X,y,alphas)
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ax1.plot([0,1], [0,1])
    ax1.plot(alphas, errors, ‘o’)
    ax2.plot(alphas, sizes, ‘ — ‘)
    ax1.set_xlabel(‘Significance’)
    ax1.set_ylabel(‘Error Rate’)
    ax2.set_ylabel(‘Avg. Set Size’)
    plt.title(‘Classification Conformal Calibration Curve’)
    plt.show()

这里我使用不同的领域进行回归和分类。当库的重要性设置为 0 时,预测间隔似乎有问题。

以下示例使用 iris 数据集进行分类,使用 Boston housing 数据集进行回归。使用的基本模型是决策树,但是 nonconformist 允许任何 sklearn 模型。目前,该包不支持 TensorFlow。

回归

对于回归,校准图显示在间隔大小的旁边。对于波士顿住房数据集,目标变量的标准偏差约为 9。因此,在这种情况下,这些间隔并不太大。您还可以在这里看到,这个模型经过了很好的校准。

此处使用的不合格度量是绝对误差。

data = load_boston()
y = data.target
X = data.data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=42)
X_calibration, X_test, y_calibration, y_test = train_test_split(X_test, y_test, test_size=0.4, random_state=42)estimator = DecisionTreeRegressor(random_state=10)
icp = IcpRegressor( RegressorNc(estimator, AbsErrorErrFunc()))
icp.fit(X_train, y_train)
icp.calibrate(X_calibration, y_calibration)
regression_calibration_plot(icp, X_test, y_test)

回归模型的校准曲线(作者照片)

分类

这里,校准图包括平均器械包大小。对于虹膜数据集,有三个类别。如你所见,随着重要性的增加,集合的大小会减小。在这种情况下,该模型相当好,集合大小迅速下降到 1 左右。但是,您可以看到这些集合大小开始下降。这种下降是因为,在不同的显著性水平上,模型对预测任何类别都没有信心。这种模式随着所选显著性的增加而增加。无论如何,你可以看到这个模型是相对校准良好的。

此处使用的不合格指标是误差。

data = load_iris()
y = data.target
X = data.data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=2)
X_calibration, X_test, y_calibration, y_test = train_test_split(X_test, y_test, test_size=0.4, random_state=2)estimator = DecisionTreeClassifier(random_state=10)
icp = IcpClassifier(ClassifierNc(ClassifierAdapter(estimator), MarginErrFunc()))
icp.fit(X_train, y_train)
icp.calibrate(X_calibration, y_calibration)
prediction = icp.predict(X_test, 0.1)
classification_calibration_plot(icp, X_test, y_test)

分类模型的校准曲线(作者提供照片)

结论

保形预测的好处是所做的预测有统计置信度支持。您可以为分类器和回归器提供不确定性估计值。

这个框架是一般化的,因此不管你的监督模型如何,你都可以将你的模型转换成一个共形预测器。

这篇文章简要介绍了共形预测。训练和校准的方法有许多变体。例如,一些变体减小了预测区间和集合的大小。所使用的符合性和不符合性分数也有许多变体。有些分数甚至包含了预测的难度。

总体保形预测是一个相当简单的过程。但这正是它如此有效的原因。它产生的预测具有可控的不确定性。最重要的是,预测集和区间在统计上是有效的。

如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 Medium 上关注我。

如果你对我的写作感兴趣,想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。

https://zjwarnes.medium.com/membership

如何应对需求预测引擎的功能挑战

原文:https://towardsdatascience.com/how-to-address-functional-challenges-of-a-demand-forecasting-engine-6a3ea123d9ea?source=collection_archive---------25-----------------------

行业笔记、理解大数据

设计可大规模部署到生产管道中的综合预测解决方案。

零售业的需求预测是一个古老的问题,已经设计了不同的解决方案来克服许多挑战。但是这个问题似乎一直存在,并且不是所有的商业利益相关者都对他们当前的需求预测引擎的运行方式感到满意。从不完整的时间序列、数据基数、缺货、产品停产、新产品上市、新店上市、从店内到交付渠道的结构性转变、covid 等灾难性事件的发生(这些事件改变了客户认知及其购买行为的整个动态)、同类相食和光环的影响、向上扩展高效引擎以生成数百万 SKU 的预测、模型管理复杂性、最终决策引擎中业务规则的集成等,可能会出现大量挑战。有一些方法可以很好地处理这些问题,但是在选择建模框架时需要大量的定制。在本文中,我们将讨论这些定制,以及如何设计一个可以大规模部署到生产流水线中的综合预测解决方案。

首先,我们将从混合效应模型(通常称为线性混合效应模型——LME)的一个重要概念开始。在进入这个领域之前,理解“合用”和“不合用”的概念是很重要的。

假设您要预测未来 4 周 10 种产品的需求,给定 208 周的历史记录(即 4 年的数据)。这转化为 208*10,即 2080 行项目,我们将它们作为训练数据的一部分。实际上,一种产品的需求也会对其他产品产生影响。它违反了独立性和同分布(i.i.d .)的主要假设之一。当我们组装整个 2080 系列行项目并构建一个单一模型来捕捉需求时(这被称为“汇集”),它通常会生成高估的参数,并且由于数据的结构不正确而经常产生不正确的估计。对于非均匀/不完整的时间序列,它通常生成偏向于具有更多数据点的时间序列的估计。在非联营的情况下,我们通常单独处理每个系列并预测它们的需求(这被称为非联营)。对于无池模型,产品间的可变性经常被忽略,因为每个产品被不同地对待。这导致对斜率的不正确估计。为了克服这两种方法的局限性,我们经常使用“部分统筹法”,也称为混合效应模型。基于汇集变量或随机效应,系数的估计会有所不同。举个例子,考虑下面的形式。

这意味着截距和价格系数将因产品组而异,

意味着交叉产品的价格弹性不会因产品组而异。因此,这些在模型中被称为固定效应。固定和随机效应的选择不作为当前博客的一部分进行讨论,但建议将最感兴趣的变量作为随机斜率包含在分组变量中。但是这里需要注意的一点是,部分池可以在一定程度上处理不完整的时间序列和数据基数。

如何控制一些关键变量的决策?

需求预测通常与其他商业决策过程相关联,如价格建议、折扣策略、库存计划等。因此,这些外生变量将成为需求模型的特征。因此,知道如何在存在其他特征的情况下控制这些变量是很重要的。业务经常对这些关键特性如何变化设置许多限制,其影响应该有一个治理机制,且不应该是不可控。

我们可以把它们拿出来分别建模吗?

标准的附加需求模型如下所示:

现在让我们将需求序列分解为趋势和季节性。因此,残差可以考虑如下:

这里剩余 1 也称为分解需求。现在,让我们尝试开发一个仅将价格作为关键特征的混合效果模型。因此,模型方程如下所示:

请注意,上述残差模型仅在估计弹性时是重要的。既然我们已经有了自我产品和交叉产品的价格弹性,让我们看看其余的特征。

所以剩余 2 将主要决定需求预测的准确性,把价格可控性放在一边。现在,为了计算弹性,我们将把所有东西加回到一个等式中,如下所示:

这种方法的一个主要优点是确保价格影响是可控的,并提高需求预测的准确性,过多的复杂性可以在保持价格解释能力完整的残差 2 模型上进行试验。

如何处理缺货?

对于零售和 CPG 行业来说,缺货是极其常见的现象。由于缺货,我们往往会看到时间序列的不连续性,除非给予应有的重视,否则可能会描绘出一个完全相反的故事。有几种方法可以处理这种情况,但最简单的方法如下:

1.为缺货日创建标志——如果我们知道关于缺货的信息,我们应该能够确定某些产品缺货的周/日。针对这些特定的日期/周创建一个标志应该能够捕捉到销售额的下降。但是如果我们没有任何相关的具体信息,我们仍然可以把它作为探索的一部分。如果在某些情况下,需求突然下降到 0,然后在几天/几周后再次回升到最大容量,这可能表明缺货现象。

2.缺货插补—有些情况下,我们不希望通过标志创建额外的变量,而是希望调整需求本身。我们可以通过插补机制来实现这一点。在我们发现缺货的情况下,我们可以用绝对数字(如最大值/平均值/中值)或移动平均值(2 周/3 周平均值)来代替它们。

交叉产品的效果以及如何建模?

在零售场景中的任何需求预测问题中,一个主要的挑战是估计来自相同类别/不同类别的其他产品对自身产品的交叉影响。有时,由于大型零售商的产品种类繁多,这些交叉影响会带来很多麻烦。但是通过明智的方法,这些问题可以得到很好的解决。因此,让我们确定我们可以遵循的步骤,以便在方法上取得一致。

第一步:选择交叉产品

衡量叉积影响的第一步是识别它们。这些通常是由业务团队根据产品知识和客户行为确定的。但是我们也可以从数据中发现这一点。简单的关联规则挖掘或购物篮分析可以显示客户一起购买的商品列表。现在,这个列表有时可能很稀疏,如果不谨慎考虑,可能会导致模型过度拟合。因此,根据销售贡献筛选出列表非常重要。通常,长尾产品是大多数零售商的常见现象,谨慎的过滤可以减少长尾,只保留相关产品作为范围的一部分。

第二步:衡量影响

如果模型本质上是乘法的,即如果需求函数采用以下函数形式

在这种情况下,对应于交叉项目价格的系数可以直接转化为弹性。这意味着交叉产品的价格有 1 个单位的变化,需求就会有 b2 个单位的变化。

在模型采用如下半对数函数形式的其他情况下

对应于交叉产品价格的系数可以解释为价格的单位变化将导致 b2%的需求变化。

第三步:控制影响

现在,通过控制影响,我们必须确保所有此类交叉产品的累积影响应小于自身对总体需求的影响。但是为什么要这么做呢?想象一下,即使你降低价格,需求也会下降,因为你的交叉产品抵消了对自我需求的影响。在这种情况下,你如何建议价格变动?如果我们不控制交叉产品的影响,几乎不可能提出任何解决方案。但是从数学上来说这意味着什么呢?

但是我们如何在评估过程中实现这一点呢?我们可以使用约束套索来确保上述条件。约束套索将确保单个交叉产品价格的系数在一定范围内,这样整体影响不会超过对自身的影响。另一种方法是重新设计正则化回归本身的优化问题。这为你自己控制每个方面提供了更多的灵活性。

如何打理新推出的产品?

在实际的需求预测问题中,我们经常努力设计一个可以预测新推出产品销售的生态系统。由于数据点不足,我们经常最终预测错误的销售额/宽置信区间。但是,如果我们试图找到一个类似的产品,并使用这些产品的功能作为代理呢?让我们试着去理解这类类比产品的选择。

我们将介绍动态时间弯曲(DTW)的概念。DTW 通常用于识别两个时间序列之间的相似性或时间距离。DTW 的一个有趣的特性是它可以根据手头的问题伸缩自如。

两个时间序列对象 X 和 Y(从相同的数据分布中生成)之间的广义距离可以写成

这也被称为闵可夫斯基距离。对于 P=2,d(X,Y)可以认为是欧氏距离。

现在,X 和 Y 可以具有不同的长度,即,它们中的每一个可以具有不同的开始和结束时间戳,但是频率将是相同的。根据李英敏等人的描述,X 和 Y 之间的点对点对齐和匹配关系可以用一条时间扭曲路径来表示

X 和 Y 的级数长度分别为 m 和 n。

现在,如果我们要考虑最低成本路径,相应的 DTW 距离需要满足以下标准。

那么这在物理上意味着什么呢?对于两个不同的时间序列,我们将通过滑动方式遍历时间路径,并计算它们之间的距离。我们将根据获得最小距离的位置选择类似的产品序列。现在我们可以一对一匹配,也可以一对多匹配。这意味着参考序列的单个时间成分可能与类似序列一对一匹配或一对多匹配。基于此,累积距离矩阵的构造将会变化。

这里总结一下研究结果,DTW 是一种强大的算法,可以使用时序匹配来识别新引入的参考产品的类似产品。

结论

在这篇博客中,我们讨论了需求预测问题的不同挑战,以及我们如何解决其中一些挑战。需求预测在很大程度上属于时间序列模型范式的范围,直到 2017 年,深度学习模型的应用范围在很大程度上仅限于 LSTMs。但是随着 NLP 中转换器机制的出现,时间序列研究人员也试图在结构化数据空间中引入许多类似的组件。因此,Rangapuram 等人在 2018 年推出了一种称为深度状态空间模型(DSSM)的新技术,在数据科学界获得了很大的人气。它的一个流行应用是在沃尔玛主办的 Kaggle 的 M5 预测竞赛中发现的。作为评估过程本身的一部分,它毫不费力地解决了我们在博客中讨论的许多挑战。此外,管理模型复杂性也非常简单,因为您不必在 DeepState 范式中管理成千上万的预测模型。这反过来又解决了许多行业目前正在努力解决的扩展问题。在我们的下一篇博客中,我们将更多地讨论这种需求预测模型的部署方面,以及我们如何引入不同的架构来扩展预测引擎。

参考资料:

1.https://www.ijcai.org/proceedings/2019/0402.pdf

2.【https://www.hindawi.com/journals/mpe/2010/749517/

3.https://stats . idre . UCLA . edu/other/mult-pkg/introduction-to-linear-mixed-models/

4.https://mobi dev . biz/blog/machine-learning-methods-demand-prediction-retail

如何用贝叶斯“期望损失”分析 A/B 实验

原文:https://towardsdatascience.com/how-to-analyse-a-b-experiments-using-bayesian-expected-loss-b959e21a77ce?source=collection_archive---------10-----------------------

如何为你的实验计算贝叶斯预期损失指南

图片由皮克斯拜的大卫·施瓦森伯格拍摄

让我们想象一下,我们已经进行了 A/B 实验四周了。我们现在要做一个决定:变异是赢家还是输家?我们对这个决定有多大把握?

为了帮助回答这个问题,下面是我们假想实验的结果。它比较了一段时间内累积跟踪的两个变异组的转换率:

图片作者。奖励的故事。随时间绘制的累积“转换率”。越高越好。

上面的线形图显示了我们两个变量的累积转换率。对照组的转化率稍高。这是过去三周的情况。

这个结果的总体 贝叶斯概率89.9%。这刚好低于我们公司通常接受的阈值(~90%)。如果你用频率主义者的术语来说,你可以认为这是统计学意义的水平。

实验本身的一些背景:我们使用这个测试来降低一个重要特性发布的风险。这里的“赢”是可取的,但不是必要的。同时,一个“平坦”的结果是可以接受的。“损失”是我们最想避免的。

总的来说,基于以上观点,我们可以看出这个实验有可能会“失败”,但我们不能完全确定。

这是许多实验中常见的情况。需要做一个决定,但是结果还不清楚,所以要满怀信心地去做。在这种情况下通常会发生的是,实验继续运行,希望通过更多的流量获得更大的确定性。

所有这一切的发生是因为上面的视图是我们实验的一个不完整的图片。上面的视图代表运行这个测试的奖励(或者在这个例子中没有奖励)。这里缺少的是帮助我们做决定的风险的观点。

我在之前的一篇文章中写过预期损失。由 克里斯·斯图基奥 为 VWO 开发的预期损失代表了选择一个实验变量而非另一个的风险。你可以在他的白皮书中找到更多相关信息。

但本质上,风险越低越好。如果我们绘制选择一个变量而不是另一个变量的累积预期损失,我们的实验看起来像这样:

图片作者。风险的故事。随着时间的推移绘制的累积“预期损失”。越低越好。

我们可以看到,选择变体的相对“成本”是 0.75%。这在财务上意味着什么取决于被测试的流量和段。这也将因公司而异。

例如,0.75%对于一些高流量的大公司来说可能是一个决定性因素。

现在回顾这个线图,我们可以看到这些线看起来足够稳定,可以接受这个“风险”的观点。所以现在,出现了一个商业决策:推出这个特性的需要是否超过了风险?

我们已经给了决策者足够的信息来做决定。我们也可以根据紧急程度在第三周做出这个决定。在显示风险的同时显示回报是讲述我们实验的数据故事的一种非常强大的方式。

计算预期损失

那么,我们如何计算预期损失呢?让我们更深入地看看,使用一个可信赖的 Jupyter 笔记本并测试我们的 Python 3 技能!

我们将使用什么

如果您想继续学习,我假设您已经安装了 Jupyter Notebook 和 Python 3。

另外,我们将使用 numpy 和 scipy ,所以你也需要安装它们。我们应该已经有了 functools ,因为我们使用的是 Python 3。

我们笔记本中的第一个单元格看起来像这样:

**import** **numpy** **as** **np**
**from** **scipy.stats** **import** beta
**from** **functools** **import** reduce

这将加载我们需要的所有库。

加载一些示例数据

接下来,我们添加数据。这意味着增加每个变体的访问量(或用户数,如果你喜欢的话)以及转化率。

**visits_control** =  5625348
**orders_control** =  219197**visits_variation** = 5613277
**orders_variation** = 221100

我只是编造了这些数字,但如果真的这么做,我们将从我们选择的分析工具中获得这些数据。

计算转化率

我们需要知道每个变体的转换率是多少。

conversion_control = orders_control / visits_control
conversion_variation = orders_variation / visits_variationprint("Control:", conversion_control)
print("Variation:", conversion_variation)

这个的输出:

Control: 0.0389659448624334
Variation: 0.03938875633609387

小数点后两位分别为 3.90%和 3.94%。

正态分布的随机样本

让我们进入一些基本的统计概念。我们可以假设转换率为正态分布,因此根据中心极限定理为每个转换率创建一条正态分布曲线。

下面是正态分布曲线的样子:

图片作者。正态分布曲线。

横轴定义转化率,粉线是我们“观察到的”转化率。所以,对于对照组,这是 0.038965 或 3.90%。对于变化,这是 0.039389 或 3.94%。

这些值就是我们的或我们每条分布曲线的“平均值”。

垂直定义了“观察”的体积。曲线下的形状是这些观测值的概率分布。离我们的左边或者右边越远,我们的“观察”就越少。

我们可以为标准差 σ 画一些线:

图片作者。有标准偏差的正态分布曲线

想象一下,我们从对照组样本中随机抽取一些样本。这些随机样本的转换率是多少?嗯,有一个 68.26% 我们的随机样本会来自上面的粉色阴影区域(34.13% + 34.13%):

图片作者。正态分布曲线突出显示-平均值的 1/+1 标准偏差

离平均值越远,意味着这些值出现的几率越小。

如果这还不清楚,不要担心。随着我们继续下去,事情有希望变得更加清楚。让我们继续使用 python 的魔力从我们的正态分布曲线中抽取一些随机样本。

编辑:更正一下,我们实际上是要从 beta 发行版中抽取样本。

首先,我们定义需要多少个随机样本:

**N_MC** = 10

尽管我们通常会使用类似于 10,000100,000 这样的数字,但使用一个更小的数字来演示要容易得多。

为了获得随机样本,我们需要将“成功”和“失败”传递到 python 函数中。这个函数调用如下所示:

beta.rvs(successes, failures, size=N_MC)

我们使用这些值来生成随机样本:

control_successes = orders_control
control_failures = visits_control-orders_controlcontrol_sample = beta.rvs(control_successes, control_failures, size=N_MC)

如果我们打印出control_sample的值,我们会得到:

[0.03903641 0.0389794  0.03905511 0.0390165  0.03891369 0.03899223
 0.03884811 0.03901279 0.03884893 0.03901625]

基于我们观察到的“平均值”的十个样本转换率列表。它们看起来非常接近我们的控制转换率 0.038965。这正是我们所期待的。

我们需要为变体组做同样的事情:

var_successes = orders_variation
var_failures = visits_variation-orders_variationvariation_sample = beta.rvs(var_successes, var_failures, size=N_MC)

variation_sample的打印输出:

[0.0393568  0.03934686 0.03950938 0.03935167 0.03929198 0.0393716
 0.03940077 0.03934958 0.03939534 0.03936369]

它们看起来非常接近我们的变异转换率 0.039389。这也是我们所期待的。

计算预期损失

所以,现在我们有了:

  1. control_sample: 根据我们观察到的对照组的转化率,列出 10 个随机转化率
  2. 变异 _ 样本:基于我们对变异组观察到的转化率的 10 个随机转化率列表

现在我们要比较两组样本。如果我们将它们压缩成一个由元组组成的列表,就很容易做到——元组是由两个值组成的列表。所以,如果我们这样做…

samples = list(zip(variation_sample, control_sample))

…并打印samples的输出,我们将得到:

[(0.03935680021728885, 0.03903640775019114), (0.039346863185651795, 0.03897940249438995), , (0.039351671006072196, 0.0390165049777375), (0.03929198308373445, 0.03891368745047992), (0.03937159635366056, 0.038992234526441655), (0.03940077430481381, 0.0388481084116417), (0.03934958290885752, 0.039012789327513016), (0.039395339750152525, 0.03884893384273168), (0.039363691751648874, 0.03901625035958206)]

这是对此的另一种观点:

图片作者。可视化元组列表

拥有一个元组列表可以更容易地比较我们的两个值。为了计算出对照组的预期损失,我们需要对列表中的每个样本执行以下操作:

  1. variation_sample - control_sample
  2. 将任何负的结果基线到0 (因为预期损失要么是 0 要么是正数,永远不会是负值)
  3. 返回列表的平均值

为了在 python 中做到这一点,我们创建了一个差异列表,如diff_list:

diff_list = map(**lambda** sample: np.max([sample[0]-sample[1], 0]), samples)

diff_list中的每一项相加…

sum_diff = reduce(**lambda** x,y:x+y, diff_list)

..然后返回百分比形式的平均值。

EL_CONTROL = sum_diff/N_MC * 100.

对照组的最终预期损失为:

0.04018252880723959

换句话说,如果我们选择对照组,我们预计损失为 0.04018%。

现在,我们需要为变体组做同样的事情:

diff_list = map(**lambda** sample: np.max([sample[1]-sample[0], 0]), samples)
sum_diff = reduce(**lambda** x,y:x+y, diff_list)EL_VAR = sum_diff/N_MC * 100.

印刷EL_VAR给了我们:

0.0

换句话说,我们期望通过选择变化不会损失什么( 0% )。所以,总的来说,变异组的风险最小。

需要注意的是,我们在这里使用了 10 个样本。如果我们真的这样做,我们会使用更多的样本。但本质上是相同的过程。简单吧?

现在,这些对预期损失的计算可能有用,也可能没用。我们还需要知道这个结果是否“显著”。

为此,我们需要绘制一段时间内的累积结果。你可以将预期的损失数字输入 Excel,并在那里绘制图表,或者你可以创建一个 Jupyter 笔记本。

最终的视图类似于这样:

图片作者。预期损失示例。

我们可以应用一些规则来验证一个测试是否足够稳定。我在与我合作过的团队中使用的规则是:

  1. 七天没有预期损失线交叉
  2. 预期损失线的一致性
  3. 最好的概率应该是 90%或更高

注意:概率最好使用转换率,而不是预期损失,因为我们删除了低于 0 的值。

尽管示例折线图有几周的数据,但您可以更早地读取数据(可能在第 3 周)。这个想法是企业在决定测试结果之前就意识到了风险。

以这种方式利用预期损失视图有助于减少我运行的许多实验的运行时间,尤其是那些主要目标是对某个功能或首次展示进行风险评估的实验。

我真的相信从风险回报的双重视角来看待实验是非常强大的。不仅仅是在分析实验时,在与利益相关者交流结果时也是如此,因为这会使决策变得更加容易。

很想听听你的想法。有没有其他视图可以让最终用户更清楚地了解实验结果?

关于我

我是伊克巴尔·阿里,漫画作家 ,前 Trainline 优化主管。

我通过培训、建立流程和讲述实验的数据故事来帮助公司开展实验项目!

这是我的 LinkedIn 如果你想联系。或者跟随我来到这里。

如何用 R 分析视频相关数据?

原文:https://towardsdatascience.com/how-to-analyse-video-related-data-with-r-375700278c6a?source=collection_archive---------22-----------------------

趋势 YouTube 视频统计

来自 Kaggle 的热门 YouTube 视频的每日统计

克里斯蒂安·威迪格在 Unsplash 上拍摄的照片

r 编程语言在分析和快速可视化数据方面非常强大。使用 RStudio 可以轻松做到这一点。我探索了 YouTube 视频的每日趋势统计,你可以从这个链接找到这个数据集。而且,你也可以从这个链接找到我关于这个作品的 Kaggle 笔记本。

我要回答的问题如下:

  • 这些属性之间有什么关联:类别 id视图喜欢不喜欢评论数
  • 按国家划分,视频剪辑出现的情况有哪些?
  • 基于一天中的时间,喜欢的百分比是多少?
  • 在不同的时间间隔内,视频剪辑在各国出现了多少次?
  • 英国数据集中最常见的标签是什么?

这些属性之间有什么关联:类别 id观点喜欢不喜欢评论数

从上图我们可以看到,最相关的数据点是喜欢评论数,那个相关性是 0.86 。一个视频的点赞越多,它的评论就越多。之后我们看到第二高的相关性是 0.81 ,这个相关性来自于视图喜欢的属性。

按国家划分,视频剪辑出现的情况有哪些?

当我们按国家检查出场次数时,很明显俄罗斯的视频出场次数最多,其次是墨西哥和印度。

基于一天中的时间,喜欢的百分比是多少?

一天中的时间在广播中非常重要,在当今的视频流中也是如此。这就是为什么检查视频何时出现是至关重要的。上图显示了基于一天中不同时间的喜欢的百分比。据此,白天(10:00-16:00)的比例最高 32.3%

在不同的时间间隔内,视频剪辑在各国出现了多少次?

墨西哥、韩国和日本在不同时间段的出现次数略低。

英国数据集中最常见的标签是什么?

使用最多的标签分别是视频音乐3219 次。在这个图表中,我只检查了英国的数据集,所以英语标签已经被处理和可视化。重要的是要知道,如果你正在处理其他语言,那么你需要小心编码。否则,您无法处理数据。

如果你想检查我的 R 代码,那么你可以看到我的 Kaggle 笔记本上的这项工作。这里是的链接。

如何用布局解析器包分析 PDF?

原文:https://towardsdatascience.com/how-to-analyze-a-pdf-with-the-layout-parser-package-177b1c1600f2?source=collection_archive---------12-----------------------

我最近参与了一个项目,该项目需要解析 PDF,以便识别页面的区域并从这些区域返回文本。然后,文本区域将被馈送到 Q/A 模型( farm-haystack ),并从 PDF 返回提取的数据。本质上,我们希望计算机为我们读取 PDF 文件,并告诉我们它找到了什么。目前,有一些流行的模块以不同的效率执行这项任务,即 pdfminer 和 py2pdf 。问题是表数据很难解析/检测。解决办法?取出表格和图表,只返回文本块。

下载布局解析器。

pip install layoutparser

将. pdf 转换为图像。

我们需要将 PDF 的每一页转换成图像,以便对其执行 OCR 并提取文本块。有许多不同的方法可以做到这一点。您可以转换 PDF 并在本地机器上保存图像。但是出于我们的目的,我们希望将 pdf 页面的图像临时保存在内存中- >提取文本- >丢弃图像,因为在我们执行 OCR 之后,我们不再需要该图像(我们仍然拥有原始的 PDF 文件)。为了解决这个问题,我们将使用 pdf2image 包:

pip install pdf2image 

这个软件包将允许我们输入一个 PDF 文件,并输出一个图像的每一页。我们可以选择将图像保存在存储介质上,或者暂时将 PDF 作为 PIL 图像列表进行处理,然后在完成后将其丢弃。

images = convert_from_bytes(open('FILE PATH', 'rb').read())

现在,您将拥有一个可以循环浏览的图像列表。

为了让布局解析器包能够读取这些图像,您需要将它们转换成像素值的数组,这可以通过 numpy 轻松实现。

image = np.array(image)

实例化您的 OCR 工具并提取文本。

目前,有两个 OCR 工具,你可以用这个包:谷歌云视觉(GCV)和宇宙魔方。我们将使用宇宙魔方。为了检测页面的区域,存在可用于各种用例(表格、杂志出版物、学术期刊)的预先训练的深度学习模型。我们将使用专门用于学术期刊的名为 PubLayNet 的模型。请记住,有多种方法可以为您的特定用例训练定制模型。

model = lp.Detectron2LayoutModel(
            config_path ='lp://PubLayNet/mask_rcnn_X_101_32x8d_FPN_3x/config', # In model catalog
            label_map   = {0: "Text", 1: "Title", 2: "List", 3:"Table", 4:"Figure"}, # In model`label_map`
            extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.8] # Optional
        )#loop through each page
for image in images:
    ocr_agent = lp.ocr.TesseractAgent()

    image = np.array(image)

    layout = model.detect(image)text_blocks = lp.Layout([b for b in layout if b.type == 'Text']) #loop through each text box on page.

    for block in text_blocks:
        segment_image = (block
                        .pad(left=5, right=5, top=5, bottom=5)
                        .crop_image(image))
        text = ocr_agent.detect(segment_image)
        block.set(text=text, inplace=True)

    for i, txt in enumerate(text_blocks.get_texts()):
            my_file = open("OUTPUT FILE PATH/FILENAME.TXT","a+")
            my_file.write(txt)

运行上述代码后,您可以使用以下语法挑选出每个页面中您感兴趣的区域:

text_blocks = lp.Layout([b for b in layout if b.type == 'Text'])title_blocks = lp.Layout([b for b in layout if b.type == 'Title'])list_blocks = lp.Layout([b for b in layout if b.type == 'List'])table_blocks = lp.Layout([b for b in layout if b.type == 'Table'])figure_blocks = lp.Layout([b for b in layout if b.type == 'Figure'])

现在,你可以从你感兴趣的部分提取文本,忽略你不需要的部分。

结论

到目前为止,布局解析器包已经被证明是分析页面结构的最可靠和最简单的工具。在这个简短的教程中,我们重点介绍了如何获取一个完整的(多页)PDF,并提取页面中机器可读的部分,然后输入到 NLP 模型中进行分析。有关更多信息,请参考文档!

如何使用 Python 数据科学包分析血糖数据

原文:https://towardsdatascience.com/how-to-analyze-blood-glucose-data-with-python-data-science-packages-4f160f9564be?source=collection_archive---------8-----------------------

使用 Pandas、NumPy、Matplotlib、Seaborn、Plotly 等工具从血糖监测仪数据中提取信息。

塞内卡之死,曼努埃尔·多明格斯·桑切斯,1871 年。

1 型糖尿病糟透了。将血糖水平始终保持在目标范围内对于预防和/或延迟严重健康问题的发生非常重要,如心脏病、视力丧失、肾病、神经损伤以及其他一系列不好的事情。不过,我不是来这里哀叹这有多糟糕的。我在这里演示如何分析血糖数据,以改善您和/或您所爱的人的整体血糖控制。

这篇文章的目标是:

  • 为了深入分析我的血糖(BG)随时间的变化情况,
  • 根据这些数据确定可行的措施来改善我的血糖控制,以及
  • 为希望这样做的人提供一个教育模板和工具包。

下面的可视化和分析对那些与 T1 糖尿病作斗争的人来说非常有价值。我希望这篇文章能给那些人必要的知识和技能来进行他们自己的分析,并最终改善他们的生活。这里讨论的所有代码都是我写的,是免费的,可以在本文末尾下载。

“最重要的不是你承受了什么,而是你如何承受。”——塞内加,罗马斯多葛派哲学家,论普罗维登斯

我使用了发表在糖尿病技术&治疗学杂志上的论文来确定哪些统计方法和图形表示是相关的,并为希望分析血糖监测器数据的人提供最大价值。以下是这类分析最重要的统计工具:

  • 平均血糖值 (mg/dL),总体血糖控制的通用描述符。
  • 血糖值的四分位数范围,适用于非对称分布。
  • BG 变化率的标准偏差,代表葡萄糖转换的扩散和范围,或葡萄糖波动稳定性的度量。
  • 花费在预定值之内、之下和之上的时间百分比。由糖尿病控制和并发症试验建议的三个临床上明显不同的血糖区域是:低血糖 (BG < 70 mg/dL)、目标范围 ( 70 < BG < 180)、以及高血糖 (BG > 180)。
  • 叠加总葡萄糖轨迹的葡萄糖轨迹,直观展示血糖值高于或低于相关阈值的时间。
  • 庞加莱图(滞后图),方便直观显示总体血糖控制和快速血糖波动。
  • 控制可变性网格分析,一种用于确定血糖控制趋势的可视化工具。

以下部分将演示如何计算或创建相关的价值或可视化,解释它为什么重要,并举例分析我自己的数据。

数据预处理

第一步是拉数据。在我的情况下,我使用 Dexcom 连续血糖监测仪(CGM)。通过 Dexcom Clarity 可以轻松访问您的数据,这些数据可以作为 CSV 文件下载。我将提取 30 天的数据。输出如下所示:

图一。将 Dexcom Clarity 数据截图为 CSV 文件。(图片由作者提供)

我们要查看的重要数据是时间戳葡萄糖值(mg/dL) 列。每 5 分钟,CGM 获取一个数据点,存储它,并显示给用户。

接下来,我们需要导入所有相关的库。今天我们将使用 Pandas、NumPy、Matplotlib、Seaborn 和 Plotly。

我们需要的唯一相关列是时间戳葡萄糖值(mg/dL)。我们还可以删除数据帧的前几行,重置索引,并清除列名:

现在,有了一个清晰的数据框架,我们就可以开始分析了。

平均葡萄糖值

给定期间的平均葡萄糖值是总体血糖控制的简单描述。糖尿病患者的目标范围在 70 和 180 mg/dL 之间,正常(非糖尿病)平均葡萄糖在 90 和 110 mg/dL 之间。

熊猫们。describe()(描述)函数为我们提供了值的总数和一些描述性统计数据,包括平均值:

****

****我在这 30 天内的平均葡萄糖值为 117 毫克/分升,相当不错。我应该指出,我没有胰岛素泵,而是每天至少注射 4 次胰岛素来维持目标水平,每次注射的量主要取决于碳水化合物的消耗量(以及许多其他因素)。

注意 : 上面显示的标准差(STD)值可能会产生误导,因为血糖测量范围高度不对称——低血糖范围(40–70mg/dL)在数值上比高血糖范围(180–400+mg/dL)窄。因此,葡萄糖值的分布高度倾斜,STD 主要受高血糖波动的影响,而对低血糖不敏感[1]。出于这个原因,四分位距(IQR)是一个更适合非对称分布的衡量标准。

血糖值的四分位数范围

可以使用 Seaborn 创建一个盒须图来演示我们在上一节中计算的 IQR:

****

****图二。血糖四分位距。(图片由作者提供)

上面的图是我的 IQR 的视觉表现。值的范围从~ 40(CGM 可检测的最小值)到 200,超过 200 的点被归类为异常值,由 IQR 确定。

我们可以根据一周中的某一天来划分图表,以尝试识别任何趋势:

****

****图三。用 Plotly 生成的盒须图在一周中的某一天拆分。(图片由作者提供)

上面的图 3 揭示了一些有趣的见解。让我们特别来看看星期六。注意位于顶部“须状物”之外的点——这些是异常值,或者在数值上远离其余数据的观察值。虽然周六的 IQR(盒子)相当小,但看起来我有一次不寻常的高血糖水平之旅。由于周末通常对我来说在饮食和锻炼习惯方面不太结构化,这是有意义的。饮酒、非正常饮食(例如在餐馆就餐)以及潜在的缺乏锻炼都是我在周六更频繁发生的事情,都可能导致血糖控制较差。

从这个分析中可以得出一个可行的见解,那就是我需要更加注意我的周末习惯,并且在这些时间里更加重视血糖控制。

下面是同样的 GIF 格式的图表,展示了 Plotly 的一个有趣的好处:它是交互式的!将鼠标悬停在图形的不同区域上可以很容易地比较数值。

****图 4。盒须图 GIF,展示 Plotly 的交互性。(图片由作者提供)

血糖变化率的标准偏差

如平均葡萄糖值一节所述,不建议而非计算简单葡萄糖值随时间变化的标准差(SD)。重申原因:

  1. “血糖测量范围高度不对称,
  2. 低血糖范围在数值上比高血糖范围窄,并且
  3. 个体的葡萄糖值的分布通常是相当偏斜的。"[1]

相反,我们可以计算血糖值随时间的变化率,这通常是对称的,并计算其标准偏差。所得值在统计上是准确的,并可作为血糖稳定性的指标。较高的血糖变化率标准差表明血糖变异性增加,因此控制较差。****

为了计算变化率,我们使用以下公式:

其中变化率以(毫克/分升)/分钟为单位。因为我们的读数是每 5 分钟读取一次,所以分母就是 5。在 Python 中,它看起来像这样:

****

为了对此进行可视化,我们将使用 Seaborn 直方图和一些有趣的 f 字符串格式,用变化率的平均值和标准偏差值自动填充标题:

****

****图五。血糖变化率图。(图片由作者提供)

价值本身并不十分直观。我的血糖值的标准差是 0.99,这意味着我的大部分时间(~68%)是在血糖变化率在-1 和+1 之间的情况下度过的。如果标准差是 5,这意味着我的血糖水平波动更大更快,这不是一个理想的状况。

为了使该分析最具影响力,它将被用作治疗变化之间的比较工具。你可以计算一个 30 天的标准偏差,然后实施一些改变(胰岛素与碳水化合物的比率,日常锻炼,不同类型的锻炼,饮食的改变,等等。)并在接下来的 30 天内再次计算。希望第二个数据集的标准差更小,您可以量化这种变化对您整体血糖控制的影响。

在范围内的时间百分比(TIR)

了解各种范围内的时间百分比作为 CGM 变化的一般行为的指示是有用的。如本研究前面所述,相关范围如下:

  • ****低血糖(血糖< 70 毫克/分升)
  • 目标范围 ( 70 毫克/分升<血糖< 180 毫克/分升)
  • ****高血糖(血糖> 180 毫克/分升)

这个值的计算对我来说有点棘手,涉及到 Pandas 方法,如 。grouper(),。解散堆叠()和。菲尔娜()。 参见下面的代码和相应的输出:

我们可以通过计算每个离散时间段的简单百分比来总结这些结果。在本例中,我使用 f-string 格式创建了一个间距很小的表格输出:

在这 30 天的时间里,我的 BG 值在大约 90%的时间范围内。我希望这个数字更高,但它永远不会是完美的。最终,较高的 TIR 与较低的微血管并发症风险相关****【2】。TIR 应与实验室得出的 A1C 值结合起来考虑,以准确评估您自己的日常血糖变化。

我只能找到一些 TIR 目标的例子。Diabetes.org 规定的目标是至少 70%的 TIR,但我个人认为这太低了。可以说,TIR 越高越好。

葡萄糖痕迹

葡萄糖轨迹图仅仅是 BG 值的时间序列。可视化血糖水平随时间的波动很有用,可以确定一天中是否有任何趋势。

我编写了下面的代码来创建一个有按钮来改变显示区域的交互式图形。例如,单击“1d”会将窗口更改为仅显示一天的数据。类似地,“1m”会将视图更改为包含一个月的数据。从那里,您可以来回拖动以查看血糖值如何随时间波动:

****

****图六。葡萄糖值对时间,叠加总葡萄糖值。(图片由作者提供)

上图 6 是我 2021 年 7 月 25 日的 BG。10 点 30 分左右,我的血糖超过高血糖阈值,直到 12 点。红线清楚显示了偏移的持续时间,这被称为聚集葡萄糖轨迹。没有这条线,很难快速知道血糖值是否在可接受的范围内。例如,从 1500 年到 1900 年,血糖水平明显上升,随后下降。虽然直观上这可能表明在此期间缺乏控制,但叠加的聚集葡萄糖迹线(红线)显示 BG 值从未越过高血糖或低血糖阈值,表明血糖控制令人满意。**

为了计算总的葡萄糖轨迹,我使用简单的 if/else 逻辑在 DataFrame 中创建了一个新列:

****

庞加莱图

庞加莱图传统上在物理学中用于可视化系统的动态行为。在这个用例中,“一个更小、更集中的图表示系统(患者)的稳定性,而一个更分散的庞加莱图表示系统(患者)的不规则性,在我们的情况下反映出较差的葡萄糖控制和快速的葡萄糖偏移。”[1]

图中每个点的坐标 BG(t-1)在 x 轴上,BG(t)在 y 轴上。每个点的坐标(y-x)之差代表血糖变化率。为了计算这个,我简单地在 DataFrame 中创建了一个名为“Lag”的新列,并使用了熊猫。shift() 函数获取(t-1):

该图是可视化治疗变化的效果的理想对比工具。例如,可以收集 30 天期间的血糖“控制”数据,对治疗进行一些改变(例如,调整碳水化合物比率、调整基础剂量、定期锻炼、改变饮食等。)30 天,并收集血糖数据,然后将这两个时间段相邻绘制,并比较其分布。更集中的第二个 30 天时期将指示有益的治疗。

由于我没有任何可以比较的治疗变化,我决定用 3 个独立的时间框架展示庞加莱图——一个“好的一天”,一个“坏的一天”,以及总共 30 天的时间段:

****

****图七。比较三个不同时期血糖控制的庞加莱图。(图片由作者提供)

从上面的图 7** 可以清楚地看到,最左边的图确实是“糟糕”的一天,点数分布越大,表明血糖变化越大。**

“30 天总计”图表上有一个异常点,这是我的 CGM 在两个小时内无法获取数据的结果。在此期间,我的血糖变化了 108 mg/dL,导致两个相邻时间戳之间存在显著差异。

控制可变性网格分析(CVGA)

把最好的留到最后,对我来说,CVGA 是整个项目中最具洞察力的一幅图。CVGA 是另一个可视化整体血糖控制的工具。在我们看了图表之后,我会解释它是什么:

****

****图 8。控制可变性网格分析。(图片由作者提供)

图 8上的每个点代表这 30 天期间的一天。每个点的 x 坐标是该 24 小时内的最小血糖值,y 坐标是该 24 小时内的最大血糖值。(注意 x 轴的反方向。)我通过创建一个按天聚合的新数据框架并使用 NumPy 的 min 和 max 聚合函数来计算这些值:****

****

为了解释该图,让我们来看一个例子点,图 8 中的红色“X”,其坐标为(56,181)。从我们之前显示每日最小值和最大值的 DataFrame 输出中,我们可以看到该坐标对应于 2021 年 7 月 19 日。这一天,我的最低血糖值为 56,最高血糖值为 181,这一数据点位于图表的“较低 C”部分。理想的一天会落在图表的绿色区域,完美的一天在“A”部分。“A”天的最低温度在 90 度到 110 度之间,最高温度低于 180 度。各区域[1]的定义见下面的表 1** 😗*

表 1 CVGA 区定义。来源

CVGA 表明我的血糖趋势低于正常水平。具体来说,它表明我倾向于对高点进行过度修正。我显然需要重新评估我的高血糖校正率,并更加重视减少我经历的低血糖次数。

我在 CVGA 的结果看起来相当差,但我们必须记住,他们没有考虑低或高的持续时间,只是绝对的最小值和最大值。我很快纠正了低血糖(基于“在范围内的时间百分比”一节中讨论的结果),但这些低血糖症仍然对整体健康有害,必须加以解决。将这些分析结合起来考虑,对你自己的血糖控制有一个整体的了解是很重要的。

结论——自己试试!

非常感谢你的阅读。如果你或你认识的人是 T1 糖尿病患者,希望你在这篇文章中发现了价值。你可以用你自己的数据创建我在这里展示的所有相同的图表——只需从我的 GitHub repo 下载 Jupyter 笔记本。如果你有任何问题,我很乐意帮忙。欢迎在下面或 GitHub 上发表评论。

医疗建议免责声明:本文中包含的信息,包括但不限于文本、图形、图像和其他材料,仅供参考。本文中的任何材料都不能替代专业的医疗建议、诊断或治疗。在开始新的医疗保健方案之前,如果您对医疗状况或治疗有任何疑问,请务必向您的医生或合格的医疗保健提供者寻求建议,切勿因为您在此阅读或了解的内容而忽视专业医疗建议或延迟寻求建议。

参考资料:

[1]https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2903980/

[2]https://clinical.diabetesjournals.org/content/38/5/439

如何分析两组连续数据

原文:https://towardsdatascience.com/how-to-analyze-continuous-data-from-two-groups-8d101510790f?source=collection_archive---------22-----------------------

数据可视化

统计假设检验 SciPy 和 Seaborn 的视觉效果

大多数数据科学从业者不理解传统统计学。传统的统计学家不使用许多现代数字。让我们弥合这一差距。

想象一个任务。你有几十或几百个特征可以用来预测结果。假设这个结果是电子商务网页的点击量。假设你在电子商务网页上有很多数据:所有者、URL、托管服务、更新频率、东道国等等。你的模型可以预测点击次数,而且预测的准确度令人印象深刻。但是你的老板问你,“来自美国的网页和来自欧盟的网页在点击量上有区别吗?”你能通过假设检验和视觉支持来回答这个问题吗?如果你的答案从“一点也没有”到“可能”,继续读下去。

前面的例子代表了一个典型的数据科学问题。为了大大简化分析,让我们放在一起一个玩具数据集。玩具组代表了从更类似于上面的大数据中提取的内容。

我们想评估一个体育活动项目的有效性。这个项目旨在鼓励参与者更频繁地锻炼。这项研究有两个独立的组:控制组和干预组。这个项目进行了两周,研究者记录了每个参与者报告的每日锻炼时间。这些数据构成了下面的熊猫数据框架。完整源代码此处。让我们探讨以下问题:

对照组和干预组之间的每日锻炼率(每天分钟数)有差异吗?

**from** **scipy** **import** stats
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**
%matplotlib inlineexercise_group = ['control']*38+['intervention']*42
exercise_rates = [25, 20, 75, 0, 50, 0, 40, 0, 0, 0, 0, 0, 25,
                 75, 0, 0, 20, 0, 0, 0, 0, 20, 20, 0, 25, 0,
                 40, 20, 40, 50, 25, 30, 25, 20, 25, 50, 30,
                 40, 20, 30, 25, 50, 0, 40, 75, 10, 15, 3, 15,
                 95, 25, 50, 40, 8, 20, 25, 50, 5, 5, 12, 30,
                 40, 10, 0, 10, 20, 20, 25, 10, 0, 50, 20, 20,
                 5, 15, 30, 10, 25, 20, 15]
exercise = pd.DataFrame({'group': exercise_group,
                         'rates': exercise_rates})
exercise

实践数据

我们可以用表格来显示这些数据。首先从 group 列中获取组。

consolidated_unique_strings = []
**for** unique_string, sub_df **in** exercise.groupby('group'):  
  consolidated_unique_strings.append(unique_string)
print(consolidated_unique_strings)>>>['control', 'intervention']

然后应用于聚集的子数据框架结果。我们看到了干预组和对照组在每组中的观察次数、平均值、相似的标准差和相同的中位数。

consolidated = pd.DataFrame(unique_string.describe().rename(
    columns={'score':sub_df}).squeeze()
    **for** sub_df, unique_string 
    **in** exercise.groupby('group'))consolidated.index = consolidated_unique_strings *#replace row names*
print(consolidated.round(1)) *#round results to one decimal*

按组汇总的数据摘要

查看这些数据的传统方式是通过 Tukey 箱线图。箱线图的盒子有三个主要部分,25%四分位数的底线,中间线或 50%四分位数,以及 75%四分位数的上边界。对于蓝色控制盒,这些值将是 0、20、30,如下所示。盒子上的“胡须”代表异常阈值。晶须的端点出现在 1.5 倍的四分位间距(IQR)。对于下面的橙色干预框,IQR 将是第 75 个百分点减去第 25 个百分点,即第 3 个四分位数减去第 1 个四分位数,或 30–10 = 20。对于橙色干预组,中位数,即第 50 个百分位数,与第 2 个四分位数相同,出现在 20。50 岁时的晶须为(中位数+ 1.5*IQR) = 20+30。0 处的晶须为(中值-1.5 * IQR)= 20–30 =-10。然而,晶须不会超出数据的范围,在本例中为 0。因此,我们发现较低的晶须底部为 0。

我们在橙色一侧的顶须上方看到的两个点是干预组中的异常值。除非这些异常点有已知的数据质量问题,否则它们必须始终包含在分析中。请注意数据科学行话不一致性#10,000,321:离群值在 matplotlib 文档中被称为“飞行者”,seaborn 就是建立在这个基础之上的。

sns.boxplot(x='group', y='rates', data=exercise)

默认箱线图

就我个人而言,可能和你们中的许多人一样,不喜欢 seaborn 的默认调色板。因此,使用来自十六进制图表的两种漂亮的颜色,我将手动改变下一个数字的调色板,就像这样。

sns.set_theme(style='darkgrid')
sns.set_palette(['#299EF0','#40E0D0'])

下面是没有原始观测值和有原始观测值的箱线图的两个并排演示。对于大多数应用程序,如果可能的话,我建议将原始观测值添加到箱线图中。通过添加下面的点,我们可以在 y 轴上看到观察的频率。该信息在历史上被归入直方图;然而,我们现在可以选择将这两种类型的信息放在一个图上。在对照组中,我们看到很大一部分参与者的假装日常锻炼率保持为零。然而,我们可以看到,干预,锻炼计划,似乎减少了 0 的观察次数,并可能与更高的比率有关。

f, axes = plt.subplots(1, 2, figsize=(7, 7)) 
sns.boxplot(x=’group’, y=’rates’,data=exercise,ax=axes[0]
            ).set_title(‘Traditional Boxplot’) 
sns.boxplot(x=’group’, y=’rates’, data=exercise,ax=axes[1]
            ).set_title(‘Boxplot Overlaid with Observations’) 
sns.swarmplot(x=’group’, y=’rates’, data=exercise, color=’0.25',
              ax=axes[1]) 
plt.show()

或者,我们可以使用小提琴图来添加水平趋势线,以更具装饰性的方式表示混合箱线图-直方图。

h = sns.catplot(x='group', y='rates', kind='violin', inner=**None**, 
                data=exercise)
sns.swarmplot(x='group', y='rates', color='k', size=3, 
                data=exercise, ax=h.ax)
h.ax.set_title('Violin Plot')

有时,我们只是想展示要点,而没有干扰、干扰或推断。在这种情况下,catplot 是一个很好的选择。如果你没有兴趣告诉某人任何事情,这就是给他们的阴谋类型。

g = sns.catplot(x=’group’, y=’rates’, kind=’swarm’, data=exercise) g.ax.set_title(‘Raw Observations’)

boxenplot 函数是一个字母值图的 seaborn 实现。这种类型的绘图对于大型数据集特别有用。更多细节可以在这篇伟大的文章中找到。

i = sns.boxenplot(x=’group’, y=’rates’, 
                  data=exercise,showfliers=**False**) 
i = sns.stripplot(x=’group’, y=’rates’, 
                  data=exercise,size=4,color=’0.25') 
i.set_title(‘Boxenplot with Points’)

最后,通过显示平滑的表示,如 KDE 图,可以优化对屡试不爽的直方图的解释。由于视觉上的简单性,内核密度视图非常强大。通过选择平滑参数,数据被用于拟合平滑的高斯核,产生连续的概率密度函数估计。如果基础数据是有界的或不平滑的,这种估计会引入失真。例如,查看新的 x 轴,它现在从-20 扩展到 120,而原始数据范围是 0 到 95。然而,即使有这样的限制,KDE 的观点阐明了对照组的双峰行为。由于有两个明显的峰值,这种行为在其他图中也有显示,但没有突出显示。

g = sns.displot(exercise, x='rates', hue='group',bins=9)
g.ax.set_title('Overlaid Histograms')

h = sns.displot(exercise, x='rates', hue='group',kind='kde',bw_adjust=.75)
h.ax.set_title('Kernel Density View')
plt.show()

现在这类数据的可视化分析已经彻底穷尽,我们可以回到最初的问题。对照组和干预组之间的每日锻炼率(每天分钟数)有差异吗?我们的视觉分析表明也许。使用 SciPy 包,我们还可以进行统计假设检验。这里合适的检验是两个独立组的双边 t 检验。

这里重要的关键是独立。小组参与之间没有交叉,我们假设这些小组是随机选择的。如果每组的基线运动率存在差异,那么独立性要求就没有得到满足,我们就不能使用 t 检验。

假设检验将得出以下结论:

零假设(Ho):各组之间的运动率没有差异。

替代假设(Ha):锻炼率和群体成员之间存在关联。

由于每组的标准差相似(对照组和干预组分别为 21.2 和 19.8),我们可以使用假设方差相等的 t 统计公式。最终的 t 检验统计值为-0.62。使用 0.05 的显著性水平α,这对应于 0.54 的 p 值,其不显著。因此,我们无法拒绝零假设,因为缺乏证据表明这些组之间的比率存在差异。相应地,我们认为锻炼计划是无效的。

这是大多数分析得出结果的方式。然而,还有更多。现在我们必须记住,这些结果可能包含设计误差。在统计学中,有第一类和第二类错误。

  • 第一类错误是当实际上没有差异时,得出结论说两组之间有差异。
  • 第二类错误是得出结论,认为两组之间没有差别,而实际上是有差别的。

t 检验旨在查看来自两个来源的 1D 数据,并计算聚合值或统计数据,以确定数据是否与下图相似,是否有明显的峰分离。将统计数据映射到其假设的分布,并计算 p 值,即尾部下的面积。如果 p 值小于 0.05,则表明数据可能看起来与这个借用数字相似。

一般 t 检验的可视化

然而,我的数据与图表不符。让我们将其与我们的实际数据进行比较。在下图中,左边的绿色区域类似于右边的蓝色区域。p 值 0.54 是获得至少与观察结果一样极端的结果的概率。换句话说,对照组均值和干预组均值接近的几率很高。在这种情况下,这种可能性超过 50%。因此,我们得出结论,峰没有很好地分开,没有区别。

(左)此 t 检验的可视化。(右)常规 t 检验的可视化

然而,考虑到该数据中的高水平变化,尤其是在对照组中,检测 3 分钟/天的样本均值差异的能力较低。为了用 80%的功效或 20%的机会来检测这种差异,我们将需要数据集中至少 1804 个观察值。参见下面由这个自由功效计算器生成的计算结果,使用平均值的差异(20.8 +/- 21.2 对照和 23.6 干预),干预与对照的比率为 1.1,显著性水平为 0.05,功效为 0.8,该试验应该包括 859+946 = 1804 名参与者,而不是 80 名。就目前情况而言,传导测试的功效约为 10%,因此我们有 90%的机会在 t 测试中犯下 II 型错误。换句话说,由于 80 名参与者的小样本量,有 90%的可能性我们得出结论没有差异。

t 检验的功效计算

尽管独立组间双边 t 检验的假设检验结果不显著,但该检验不足以进行检测。因此,对于希望限制错误率的从业者来说,假设检验结果仍然是不确定的。虽然假设检验不提供信息,但对分布的视觉分析产生了边缘证据,表明各组之间的参与者行为可能存在差异。

将这些工具整合到您自己的分析中。在这里找到源笔记本。

如何在 Python 中使用米托分析数据

原文:https://towardsdatascience.com/how-to-analyze-data-using-mito-in-python-4bf817092367?source=collection_archive---------17-----------------------

Jupyter 笔记本上的电子表格和编程,为什么不呢?

蒂姆·约翰逊在 Unsplash 上拍照

介绍

数据包含如此多有意义的见解。数据分析是获得这些见解的途径。有时,我们对选择我们想要使用的工具感到困惑,不管是使用像 Excel 这样的电子表格软件。或者我们可以使用 Python 这样的编程语言。

对于一些人来说,他们更喜欢使用电子表格工具。其中一个原因是因为他们还不会编程。

对于大数据,不建议使用电子表格工具。所以,我们需要分析大数据的编程。但是谢天谢地,有一个工具可以把两者联系起来。它叫米托。

米托是一个具有分析数据能力的库。与熊猫图书馆不同,米托有一个类似电子表格软件的界面。因此,我们可以在不干扰代码的情况下探索和处理数据。

在本文中,我将向您展示如何使用米托分析数据。此外,我将向您展示该工具中包含的功能。没有进一步,让我们开始吧!

履行

安装并加载库

在我们可以使用这个库之前,我们需要先安装它。我们需要安装 mitoinstaller 库,以便用“pip”命令安装米托。下面是执行该操作的命令:

**python -m pip install mitoinstaller**

之后,您可以使用以下命令行安装米托:

**python -m mitoinstaller install**

如果安装完成,它将显示如下文本:

截图为作者截图。

现在我们可以在笔记本上加载库了。

请记住,您只能在 JupyterLab 中使用米托。直到现在,你还不能用普通的 Jupyter 笔记本来访问它。

现在让我们初始化米托表。为此,请复制以下代码行:

**import mitosheet
mitosheet.sheet()**

下面是运行代码的结果:

截图为作者截图。

如果能看到笔记本上的界面,说明现在可以用了。

数据源

对于数据源,我们将使用来自 Kaggle 的数据集,名为 Twitch 上的 Top Streamers。基本上,该数据集包含 2020 年前 1000 条飘带的信息。

数据集中包含的信息是观众数量、关注者、语言名称、频道名称等。您可以在这里 访问数据集

免责声明:
数据集在公共领域。它还包含“CC0:公共领域”许可证。更多详情,可以看一下 这里

打开数据集

要打开数据集,我们需要从中创建一个 dataframe 对象。我们可以利用熊猫图书馆来做这件事。让我们为此编写以下代码行:

**import pandas as pd
df = pd.read_csv('twitchdata-update.csv')**

在我们得到数据帧之后,下一步是将它加载到我们的米托表中。为此,添加以下代码行:

**mitosheet.sheet(df)**

下面是运行代码的结果:

截图为作者截图。

从上面可以看到,数据已经加载完毕。现在让我们探索米托能做什么。

创建新列

有了米托,我们可以像在电子表格上一样探索和定制数据集。我想向您展示的第一个功能是向数据集中添加一列。

假设我们想要添加一个列,其中有一个布尔值来确定频道是否为英语。我们称这个栏目为“是英语”栏目。

要添加列,请看这个 GIF:

GIF 是作者捕获的。

写公式

因为米托就像一个电子表格工具,我们可以在笔记本上使用,所以我们可以像电子表格软件一样使用公式来定制列。

让我们回忆一下 is_english 专栏。如果语言是英语,我们希望将布尔值设置为 1。在电子表格软件中,我们可以使用这样的公式:

**IF(language == 'English', 1, 0)**

让我们把这个公式应用到米托身上。以下是该过程的 GIF:

GIF 是作者捕获的。

过滤数据

设置完列的值后,让我们根据“is_english”列过滤数据。我们将获取包含值 1 的行。

在米托,我们可以很容易地做到这一点。我们只需要给出进行过滤过程的参数。看看这张 GIF:

GIF 是作者捕获的。

可视化图表

我们可以做的下一个功能是可视化数据。有了米托,我们可以更容易地显示图表,而不是花时间编写代码和查看助手的网站来获取特定问题的语法。我们可以可视化图表,如箱线图、直方图、散点图和条形图。

GIF 是作者捕获的。

创建数据透视表

我想向您展示的下一个功能是创建数据透视表。就像以前的特性一样,我们只需要给出完成某项任务的参数。

为了创建数据透视表,我们可以设置哪一列作为行、列和值。从该表中,我们可以看到基于特定列的值。在这种情况下,我们希望根据成熟度和语言来合计关注者的数量。

请看这张 GIF 图片,了解如何创建数据透视表:

GIF 是作者捕获的。

对数据进行排序

让我们看看我们的数据透视表。如您所见,该表包含了基于成熟度和语言的追随者数量。但是我们仍然没有得到洞见。我们先把数据整理一下。

有了米托,整理数据变得简单了。为此,我们只需点击几个按钮。请看这张 GIF:

GIF 是作者捕获的。

如果对没有成熟内容的栏目进行排序,可以看到英语是最多的语言。然后是韩语、俄语、西班牙语等等。

但是如果你看到更多的细节,非成熟内容的关注人数和成熟内容的关注人数是不一样的。让我们对成熟栏中的数据进行排序。这是这样做的结果:

截图为作者截图。

如你所见,韩国人不在第二位。大部分是欧洲语言。韩国语在汉语和泰语之下。

代码生成

这是米托能做的最后一件事。它会生成代码。当我们对数据进行一些处理时,它会根据这些数据自动生成代码。在我的例子中,这是米托生成的代码:

正如你所看到的,它看起来像我们使用的熊猫指令。有了米托,我们可以像电子表格软件一样进行处理,并基于它生成代码。

结束语

干得好!现在,您已经学习了如何在 Python 中使用米托分析数据。对于那些刚接触编程和数据分析的人,我希望它能帮助你入门。

如果你对这篇文章感兴趣,请关注我的媒体以获得更多类似的文章。我将谈论大量的数据科学,从教程到许多领域的应用。

如果您有任何问题或想讨论,可以通过 LinkedIn 或电子邮件(【khaliddotdev@gmail.com】T4)联系我。

谢谢你看我的文章!

如何用 R 分析数据:dplyr 初学者完全指南

原文:https://towardsdatascience.com/how-to-analyze-data-with-r-a-complete-beginner-guide-to-dplyr-4a3c26fe4371?source=collection_archive---------32-----------------------

在 10 分钟或更短时间内学会基本的数据分析

由absolute vision在 Unsplash 上拍摄

数据集通常需要很多工作时间才能完全理解。r 通过dplyr包使这个过程尽可能简单——这是基于代码的数据分析的最简单的解决方案。今天你将学会如何使用它。

您将在整篇文章中使用 Gapminder 数据集。它可以通过 CRAN 获得,所以一定要安装它。下面是如何加载所有必需的包:

下面是 Gapminder 数据集的前几行:

图片 1 — Gapminder 数据集标题(图片由作者提供)

这就是你开始分析所需要的。

今天,您将了解:

  • 列选择
  • 数据过滤
  • 数据排序
  • 创建派生列
  • 计算汇总统计数据
  • 分组

列选择

通常情况下,您不需要所有的数据集列来进行分析。r 的dplyr提供了几种选择感兴趣的列的方法。第一个更明显——在select()函数中传递列名。

下面是如何使用该语法来选择几列:

结果如下:

图 2 —列选择方法 1(作者图片)

但是,如果您有几十个列,并且想选择除了少数几个以外的所有列,该怎么办呢?有一种更好的方法—用减号(-)作为前缀来指定不需要的列:

结果如下:

图 3 —列选择方法 2(作者图片)

如您所见,列是唯一没有显示的列。这就是你应该知道的关于列选择的全部内容。让我们继续进行数据过滤。

数据过滤

过滤数据集是工作中最常见的操作之一。并非所有数据在给定时间都是相关的。有时,您需要特定产品的值或其在 Q1 的销售额。或者两者都有。这就是filter()功能派上用场的地方。

以下是如何显示 2007 年的结果:

结果如下所示:

图 4 —数据过滤示例—年份= 2007(作者提供的图片)

您可以在一个filter()函数中嵌套多个过滤条件。请确保用逗号分隔条件。以下是如何选择 2007 年波兰的一项记录:

结果如下:

图 5 —数据过滤示例—年份= 2007,国家=波兰(图片由作者提供)

但是如果您想要多个国家的结果呢?您可以为任务使用%in%关键字。以下片段显示了波兰和克罗地亚 2007 年的记录:

结果如下:

图片 6 —数据过滤示例—年份= 2007,国家=(波兰,克罗地亚)(图片由作者提供)

如果你理解了这些例子,你就理解了数据过滤。让我们继续数据排序。

数据排序

有时您希望数据按特定的列值排序。例如,您可能希望按年龄对用户进行排序,或按分数对学生进行排序,可以是升序也可以是降序。您可以使用dplyr及其内置的arrange()函数轻松实现这一行为。

以下是如何按预期寿命排列结果:

结果如下所示:

图 7 —数据排序示例 1(作者图片)

如您所见,数据是按照 lifeExp 列升序排列的。大多数情况下需要降序排列。以下是实现它的方法:

结果如下:

图 8 —数据排序示例 2(作者提供的图片)

有时您只想返回几行。top_n()功能让您指定应该显示多少行。这里有一个例子:

结果如下图所示:

图 9 —数据排序示例 9(作者图片)

这就是关于排序的问题。接下来—派生列。

创建派生列

通过dplyr,您可以使用mutate()功能创建新属性。新的属性名放在等号的左边,内容放在右边——就像你要声明一个变量一样。

下面的示例将 GDP 计算为人口和人均 GDP 的乘积,并将其存储在专用列中。在此过程中还会发生其他一些变化:

结果如下:

图 10-将 GDP 计算为(人口*人均 GDP)(图片由作者提供)

也可以用transmute()代替mutate()。有一个严重的区别—transmute()只保留派生列。让我们在上面的例子中使用它:

结果如下所示:

图 11-使用 transmute()计算 GDP 所有其他列被删除(图片由作者提供)

你会更经常地使用mutate(),但是知道额外的功能不会有坏处。

计算汇总统计数据

汇总统计不需要任何介绍。在许多情况下,您需要计算一列的简单平均值。以下是如何计算整个数据集的平均预期寿命:

结果如下:

图 12-计算整个数据集的平均预期寿命(图片由作者提供)

正如您所想象的,您可以链接其他函数来只计算子集的汇总统计信息。以下是如何计算 2007 年欧洲人的平均寿命:

结果如下图所示:

图 13 —计算 2007 年欧洲的平均预期寿命(图片由作者提供)

您可以使用汇总统计做更多的事情,但是这需要一些分组知识。让我们接下来讨论这个问题。

分组

汇总统计在与分组结合使用时变得更加强大。例如,您可以使用group_by()函数来计算各大洲的平均预期寿命。方法如下:

结果如下:

图 14 —计算各大洲的平均预期寿命(图片由作者提供)

您还可以使用前面讨论过的排序函数来按平均预期寿命排列数据集。下面是如何以递减的方式实现这一点:

结果如下所示:

图 15-按各大洲平均预期寿命排序的数据集(图片由作者提供)

另一个强大的功能是if_else()。您可以在创建其值取决于某些条件的新列时使用它。

例如,下面是如何创建一个名为 over75 的列,如果一个大陆的平均预期寿命超过 75 岁,该列的值为 Y ,否则为 N :

结果如下图所示:

图 16 —在属性创建时使用 if_else()(图片由作者提供)

这就是你应该知道的所有关于分组的知识!接下来让我们总结一下。

结论

今天你已经学会了如何用 R 的dplyr分析数据。这是对开发者最友好的包之一,比 Python 的竞争对手熊猫简单多了。

阅读完本文后,您应该能够分析和准备任何类型的数据集。当然,你可以做更高级的事情,但通常这些只是你今天学到的东西的组合。

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

https://medium.com/@radecicdario/membership

加入我的私人邮件列表,获取更多有用的见解。

原载于 2021 年 1 月 5 日 https://appsilon.com**的

如何使用 Python 分析足球赛事数据

原文:https://towardsdatascience.com/how-to-analyze-football-event-data-using-python-2f4070d551ff?source=collection_archive---------4-----------------------

我们来分析一下 2018 年 FIFA 世界杯韩国和德国的比赛

由福赞·萨里在 Unsplash 上拍摄的照片

介绍

数据科学是从数据中获取洞察力的一种方式。数据科学正在影响许多领域,包括足球。

足球包含了太多的数据,从个人到团队。有了数据,我们可以用更有意义的方式去理解游戏。

此外,对于团队来说,这些数据可以产生有助于决策的洞察力。因此,团队可以找到赢得比赛的策略。

在本文中,我将带您了解如何使用 Python 分析足球赛事数据。既然如此,我们就来分析一下 2018 年 FIFA 世界杯德国和韩国的比赛。没有进一步,让我们开始吧!

履行

获取数据

对于数据,我们将使用来自 StatsBomb 的数据。StatsBomb 是一家专门研究足球领域的分析公司。他们提供了大量的足球数据,尤其是赛事数据。

对于那些想学习足球分析的人来说,谢天谢地,StatsBomb 已经公布了公开数据。数据由已经结束的足球联赛组成。您可以在这里 访问数据

注意:在获取数据时,请保持耐心,因为数据量非常大。

探索数据

下载完数据后,下一步是探索它。数据的文件夹结构如下所示:

还有像事件、阵容和比赛这样的文件夹。

  • events 文件夹包含以 JSON 格式概括比赛的文件。
  • “阵容”文件夹包含每场比赛中每支球队的阵容。
  • matches 文件夹包含每个比赛的匹配项。它也被分成几个比赛的不同季节。

那么,当数据中有很多文件时,我们如何检索特定的匹配呢?正如我之前提到的,我们将分析德国和韩国之间的世界杯比赛。在下一节中,我将向您展示如何检索数据。

检索事件数据

可以通过这些步骤检索事件数据。首先,我们打开 competitions.json 文件。该文件是访问 StatsBomb 数据的第一道关口。这样做的原因是因为我们需要比赛和赛季 ID 来访问比赛列表。

为了处理 JSON 文件,pandas 库提供了使用 read_json 函数将 JSON 文件作为数据帧读取的功能。下面是实现这一点的代码:

现在您可以看到包含 StatsBomb 提供的所有比赛信息的行。

综上所述,纳入该数据的比赛有西甲(西班牙联赛)、欧锦赛、世界杯(男女)和欧冠。

现在,我们希望将包含 FIFA 世界杯信息的行放入其中。让我们使用这行代码过滤数据集:

从上面可以看到,FIFA 世界杯的比赛和赛季 ID 分别是 43 和 3。现在让我们访问包含 ID 的文件夹。

对于每个竞赛,文件夹都以竞赛 ID 命名。每个文件夹都包含 JSON 文件。每个文件都附有季节 ID 作为名称。

现在,让我们使用以下几行代码来访问该文件:

哇,数据太多了,读起来很混乱。先用循环整理一下吧。在每次迭代中,我们获取比赛 ID、球队名称和分数。让我们写这几行代码:

现在比以前整洁多了。让我们来看看德国对韩国的比赛。最终比分是 2 比 0,韩国队获胜。你可能不知道,德国和韩国的比赛非常精彩。

这一结果也使得德国队在小组赛中被淘汰出局。这是德国自 1938 年以来首次在首轮被淘汰。

回到正题,德国对韩国的比赛 ID 是 7567。让我们使用下面几行代码来访问该文件:

这比上一个多得多。为了简化我们的分析,pandas 库提供了 json_normalize 函数。这个函数如此强大是因为它可以处理嵌套的 JSON。现在让我们写这几行代码:

给你。比以前更易读。现在让我们从数据中创建一些可视化。

创建拍摄地图

我们可以创建的可视化之一是拍摄地图。在这张地图上,我们想看看每个队投了多少球。同时,我们想知道进球的机会有多大。我们称这个机会为预期目标。

为了创建可视化,我们需要首先获取事件数据。然后,根据事件名称过滤数据。在这种情况下,我们需要记录镜头的数据。让我们写下这行代码:

获得数据后,现在让我们编写这些代码行来生成镜头图:

我先解释一下代码。基本上,我们想首先创建一个足球场。然后,我们还创建了一个与已拍摄的镜头相对应的点的集合。为了创建这个音高,我们可以使用 FCPython 文件中的 createPitch 函数。

对于 FCPython 文件,可以查看我的 GitHub 库 这里 。感谢创造代码的追踪团队之友。

为了生成点,我们设置了循环来迭代数据帧中的行。对于每次迭代:

  • 我们带着坐标和预期目标(xG)值。
  • 然后,我们根据前面的参数生成一个圆。xG 值将用作圆大小的值。我们也为不是目标的镜头设置透明度。

如果您正确编写代码,它应该会生成如下所示的可视化效果:

该图由作者生成。

现在我们可以从数据中获得洞察力。正如我们从上面看到的,我们知道德国抓住了很多机会。但是他们不能从中得分。

此外,他们有几个镜头有很大的 xG 值。xG 值越大,进球几率越大。但遗憾的是,德国人无法将其转换为目标。

在韩国方面,我们可以看到他们没有太多的机会。他们不像德国人那样对每次投篮都有很高的预期目标。

但是,在比赛结束时,德国队犯了一些错误,导致了尴尬的结果。孙兴民和金英权是韩国的英雄。

但遗憾的是,韩国和德国不得不退出竞争。

结论

这是你可以创造的形象之一。我们可以做很多数据可视化。

我的建议是为每个球员创建一个传球热图,一个通往进球的控球链,或者一个传球图。

正如我之前说过的,足球赛事数据中有很多真知灼见。因此,这有助于球队和足球爱好者更好地理解这项运动。

干得好!现在,您已经学习了如何使用 Python 分析来自 StatsBomb 的足球赛事数据。我希望它能启发你开始使用 Python 分析体育数据,尤其是足球。

如果你喜欢我的文章,想看更多,可以关注我,订阅我的媒介账号。如果你想在 LinkedIn 上和我联系,你也可以这样做。您可以在这里 访问我的 LinkedIn 个人资料

谢谢你看我的文章!

如果你需要 jupyter 笔记本和 FCPython 文件,可以在这里 访问我的 GitHub 库

免责声明:
StatsBomb 已给予使用和分析数据的权利。你可以在这里 阅读关于数据 使用权的许可。

参考文献

[1]德国在输给韩国后退出了比赛。BBC。https://www.bbc.com/sport/football/44439270
【2】stats bomb:公开数据。https://github.com/statsbomb/open-data

如何用 Python 分析调查数据

原文:https://towardsdatascience.com/how-to-analyze-survey-data-in-python-c131764ea02e?source=collection_archive---------14-----------------------

Jac Alexandru 在 Unsplash 上的照片

以下是一些使用 Python 清理、分析和可视化调查数据的技巧和代码。

在我们开始之前,如果你还没有开始你的调查,这里是我的一些建议,告诉你如何利用数据和心理洞察力获得最多的受访者。没有好的(或足够的)数据,你建立的任何模型,或者你提取的推论,都将是无用的。

众所周知,调查数据是一种痛苦,主要是因为人们在回答调查时很懒,会做一些奇怪的事情。调查软件也很烦人。本指南将着眼于这两个问题,并提供信息和代码,以帮助您快速修复这些问题,并进入更有趣的东西,如分析或构建模型。

我将首先展示一个快速的 excel 技巧,它将为你节省大量的清理时间。然后,我将向您展示大量 Python 代码,以帮助您健壮、高效地清理和探索您的数据。我会将所有代码公开存储在我的 GitHub 中,所以你可以随意使用它并将其应用到你的工作中。

正确导出和导入数据

首先,确保你使用正确的文件类型/编码器。我怎么强调都不为过。如果你一开始就做这一步,你会节省很多时间。我不能说这是所有调查软件的情况,但它适用于绝大多数。

大多数调查公司将输出 UTF-8 编码的 CSV。Excel 不太喜欢这样,当您使用特殊字符时,偶尔会在文本前吐出奇怪的符号,例如:

幸运的是,有一种快速的方法可以解决这个问题。首先,将您的调查结果保存为一个新文件,但要做成文本文件。

然后打开一个新的工作簿,点击数据>获取数据>从文件>从文本/CSV。选择您的文本文件,然后更改它,

敬这个。

因此,我们很容易从看起来像这样的数据。

我生成的一些丑陋的假调查数据

敬这个。

我生成的一些非常干净的假调查数据

我们已经从被乱码包围、实际上无法使用的数据发展到(相对)干净、易于阅读和组织的数据。

清洁

拥有这些数据对我们来说没有多大用处,除非我们知道如何利用它们。在下一节中,我将带您了解一些快速处理和清理调查数据的方法。根据你的知识,其中一些可能是显而易见的,所以如果是这样,我很抱歉,但希望你能从中找到一些东西。

删除冗余列

首先,调查往往会有很多你不关心的栏目——直接把它们去掉就行了。幸运的是,他们中的大多数都在调查的开始阶段,所以你可以快速地将他们根除。我们可以使用下面的 iloc(整数位置)根据需要删除前 n 列。

iloc 一行程序删除数据帧的前 n 列。将“n”更改为您希望在新数据框架中出现的第一列的列号。

生成二进制

根据您要对调查数据做什么,通常需要将字符串变量转换成二进制。大多数机器学习模型都不喜欢字符串。你可以用多种方式重新编码/替换数据,但这只是我不久前写的,还没有任何问题。它只接受一个数据帧,并返回一个相同的数据帧,其中的字符串变量被重新编码为 1 和 0。如果观察值存在,它输出 1,如果是 0 或 NaN,它输出 0。您可以相应地调整它,或者在数据帧的特定列上将它的大块与“映射”或“应用”结合使用。for 循环中的代码行是您真正需要构建的。

将字符串列转换为二进制列的函数

将连续变量分组为分类变量

分类变量各有利弊,有时有用,有时没用。不幸的是,我们不能把分类变量变成连续变量——但是我们可以反过来做。现在,我将向您展示几个快速实现这一点的方法。首先,如果你想要同等规模的群体,使用熊猫的“切割”方法是相当容易的。它将一个分类变量分成你指定的任意多个组,甚至可以提供标签。这完全取决于您的项目是否应该使用标签,但选项是存在的。

创建一个熊猫系列/组数据框架,将连续变量转化为类别

我们还可以手写函数,以便针对更具体、更恰当的分析来定制这些条块。年龄段是常用的,所以这里有一个使用年龄段作为分类框的例子。

将连续变量分组到特定组的函数示例。

一键编码

一种热编码经常用于机器学习和日常数据分析。简而言之,它为分类变量中的每个类别创建一个“二元”虚拟变量。下面是一个例子,关于这个主题的更多信息可以在这里找到。

https://medium . com/@ michaeldelsole/what-one-hot-encoding-and-how-do-it-f0ae 272 f 1179

有些调查会自动完成,有些不会。有些调查软件会在你不想让他们做的时候做,有些则不会。所以基本上我们需要学会如何在两者之间随意切换。熊猫和 Scikit learn 都有自己不同的版本,分别在这里和这里看到。两者都非常简单。

探测

有成千上万不同的教程告诉你如何探索你的数据。然而,他们中的大多数人关注的是连续数据。因此,我不会浪费你(或我)的任何时间,我将坚持强调在调查数据中特别有用的方法和工具。

描述(数字版本)

有几个内置的功能可以帮助您更快地了解您的。Describe 是数据科学家经常使用的一个非常常用的工具,但这只适用于数字和连续变量。如果导入 NumPy 并在 describe 中包含一个参数,还可以查看分类变量。这点可以从下面看出来。根据您是否有一个热编码变量,计数的输出将有不同的含义,但通过快速查看您的数据,这将很容易弄清楚。

描述的 Numpy 适应值-用于分类变量。

一些调查软件会以一种热门的格式输出问题。所以,你不想为了能看一眼就把它改回来。您仍然可以使用如上所述的 describe 来获得计数,但是它不输出百分比,这可能非常有用。

分组依据交叉表和热图

查看数据的子组可能非常重要,尤其是在调查数据中。比较不同人群的答案非常重要,不能不做。如果男人和女人的答案完全不同怎么办?老年人和年轻人完全不同意怎么办。这是可能的,也是常见的。这里,我们可以看三种方法:分组法、交叉列表法和热图法。所有这些都有着内在的联系,实际上是同一事物的变体。

分组依据

我不会深究 groupby 是如何工作的,但如果你想知道更多,这里有详细的解释。顾名思义,该方法根据分类变量对数据进行分组,然后您可以对这些单独的组应用方法和聚合函数。如下图所示。

https://towards data science . com/how-to-use-the-split-apply-combine-strategy-in-pandas-group by-29 E0 EB 44 b 62 e

所以用我们的数据,我们可以做出这样的东西。输出也是 panda 的数据帧,所以如果你愿意,可以给它指定一个名称并进一步操作。

熊猫分组的一个例子

交叉表

我们在这里生成的是一个交叉表,虽然很简单,但 pandas 有一个函数可以使它变得更快——它被恰当地命名为交叉表。这对于选择题和必答题非常有用。比如一道有年龄段的必修年龄题。

我们可以通过原始计数或百分比来实现这一点,如代码所示。

然而,通常在调查数据中,人们被允许对一个问题选择不止一个答案。比如说;“你喜欢读什么类型的书:请勾选所有适用的选项”。有些人可能不选择类别,有些人可能选择七个类别。因此,数据开始变得令人烦恼的复杂。调查输出通常通过为每个选项设置一列来处理这一问题,即一个热编码列。因此,交叉表和 groupby 方法需要为此进行调整。下面是我常用的一个函数。

该函数将完整的数据帧、要分组的列以及感兴趣的数据中的特定列作为输入。这与 pandas crosstab 函数非常相似,但它被设计为处理一个热编码列(不一定是 1 或 0,可以是“苹果”或 0)。

这将给出与前面的交叉表完全相同的百分比输出,但可以用于一次性编码的列,以便同时查看它们。

热图

这些交叉表很棒,但有时可能有点复杂,难以阅读。这就是热图的用武之地。他们获取交叉表并添加一些颜色,其中颜色的深浅与计数或百分比的大小成比例。因此,我们可以在交叉表中使用下面的代码,让它们变得生动起来。获取前面讨论过的交叉表输出,并将它们传递给下面的热图函数。

以百分比显示虚假调查数据的热图

摘要

当然,这并不是一个关于如何分析调查数据的完全详尽的过程。然而,这是我在进入模型或其他统计测试之前所做的 90%的清理和探索。如前所述,我已经将所有代码保存在我的 Github 帐户这里,我真的希望这将使你在未来处理繁琐的调查数据时更加轻松。

感谢阅读。如果你喜欢这篇文章,下面是我更多的文章。

干杯,

詹姆斯

If I’ve inspired you to join medium I would be really grateful if you did it through this [link](https://jamesasher4994.medium.com/membership) — it will help to support me to write better content in the future.If you want to learn more about data science, become a certified data scientist, or land a job in data science, then checkout [365 data science](https://365datascience.pxf.io/c/3458822/791349/11148) through my [affiliate link.](https://365datascience.pxf.io/c/3458822/791349/11148)

如何利用数据(和心理学)获得更多的数据。

如何在你的网站上动态显示 Matplotlib 图和熊猫数据框

我如何利用数据科学进入梦幻足球的前 1%

如何分析你的分类器的性能

原文:https://towardsdatascience.com/how-to-analyze-the-performance-of-your-classifier-4567f66318a7?source=collection_archive---------27-----------------------

知道使用哪些指标并不总是简单明了的

Firmbee.com 在 Unsplash 上拍照

随着深度学习的蓬勃发展,越来越多的人正在学习如何训练他们的第一个分类器。但是一旦你完成了训练,接下来的分析是至关重要的。知道使用哪些指标并不总是简单明了的。在本文中,我将讨论准确度、精确度、召回率、f1 分数和混淆矩阵来衡量分类器的性能。

真与假,正与负

在开始度量之前,让我们看一些术语,我们将用来定义这些度量[1]。

我们将做出如下定义:

  1. 肿瘤阳性类别
  2. 无肿瘤——阴性类别

所以积极和消极是我们定义的阶级。True 意味着预测和实际的类匹配。False 表示预测和实际类不匹配。

现在我们可以看看以下四个术语:

  1. 真阳性(TP) :这意味着预测为阳性类别实际类别也为阳性
  2. 假阳性(FP) :这意味着预测为阳性类别,而实际类别为阴性类别
  3. 真阴性(TN) :这意味着预测是阴性类别,而实际类别也是阴性。
  4. 假阴性(FN) :这意味着预测为阴性类别,而实际类别为阳性类别

准确(性)

这是一个非常流行的指标,它告诉你在所有的预测中有多少是正确的。

Accuracy = Total correct predictions / Total predictions [2]

或者

Accuracy = (TP + TN) / (TP + FP + TN + FN)

注:Total predictions = TP + FP + TN + FNTotal correct predictions = TP + TN.

这是一个非常简单的性能衡量标准。然而,对于类别高度不平衡的数据集,这可能会产生误导。假设我们有 100 个样本,其中 10 个是肿瘤,90 个不是肿瘤。分类器正确地分类了 89 个非肿瘤,但只有一个是真正的肿瘤。

对于这个例子:TP: 1,FP: 1,TN: 89,FN: 9

我们将获得 90%的准确率。看起来这个模型表现得很好。然而,在现实中,它在肿瘤类中表现很差。医疗应用中的假阴性可能会导致死亡。然而,准确性给人一种表现出色的错觉。我们接下来要看的指标在这些情况下会有所帮助,并让我们更好地理解分类器的性能。

精确

精度被定义为相关实例在检索到的实例中所占的比例 [3]。它也被称为阳性预测值。它是集合中真阳性与预测阳性的比率,即真阳性和假阳性的总和。

Precision = TP/ (TP + FP)

Precision 试图回答这样一个问题:多大比例的肯定识别是正确的?[4]

如果我们继续前面的例子,

精度= 1 / (1 + 1) = 0.5

精度为 0.5,这意味着分类器与随机猜测一样好。

注意:精度值为 1 的模型不会有误报。

回忆

召回被定义为检索到的相关实例的分数【3】。也就是所谓的敏感。它是真阳性与集合中总阳性的比率,即真阳性和假阴性的总和。

Recall = TP/ (TP + FN)

Precision 试图回答以下问题:正确识别的实际阳性率是多少?[4]

如果我们继续前面的例子,

回忆= 1 / (1 + 9) = 0.1

召回率是 0.1,这意味着分类器只能检索 10%的肿瘤实例,而 90%将被错误地分类为非肿瘤。基于肿瘤检测应用的要求,这是非常差的性能。

注意:召回值为 1 的模型不会有假阴性。

f1-分数

这是一个结合了精度和召回值来给出性能评估的指标。F1 分数被定义为精确度和召回率的调和平均值[5]。

F1-score = 2 * (precision * recall ) / (precision + recall )

它对精确度和召回率给予了同等的重视。与仅取精确度和召回值的算术平均值或几何平均值相比,F1 分数将给出较低的值。它将倾向于两个值中的较低值,以减轻较大异常值的影响。

对于上面的例子,

f1-得分= 2 * 0.5 * 0.1 / (0.5+0.1) = 0.16667

我们得到的 F1 值更接近于两个指标中较低的召回值。因此,高 F1 分数将指示分类器具有高精度以及高召回率。

混淆矩阵

在分类的机器学习中,混淆矩阵(也称为误差矩阵)是一个允许可视化分类性能的表格[6]。每行代表实际类中的实例,列代表预测类中的实例或其他方式。

注意:请确保您正确阅读了您正在使用的库的文档,以确保您知道行和列代表哪些条目。对于 scikit-learn,行代表真实标签,列代表预测标签[7]。

对于二进制分类,混淆矩阵可以使用 TP、FP、TN 和 FN 值灵活地表示。

二元分类的混淆矩阵(来源:作者)

对于我们的例子,混淆矩阵是:

来源:作者

看着这个混淆矩阵,我们可以清楚地看到分类器的性能如何。理想的混淆矩阵将只有对角线元素,没有非对角线元素,即 FP 和 FN 为零。在这种情况下,精度和召回值将为 1。形象化该矩阵的一个好方法是热图。这将加热有较大条目的地方,也就是说,使那些条目明亮,而其他条目柔和。如果我们观察到一条明亮的对角线,我们很快就知道混淆矩阵是正确的。这对多类分类混淆矩阵更有意义。

查看矩阵可以快速找出每个类别有多少样本被正确分类,以及错误分类样本的分布。然后,您可以检查并查看是否有突出的内容。就像一个特定的类被严重错误地归类为另一个类,那么您可以手动检查样本,看看是否一切正常。也许样品有问题。或者你明白分类器失效的条件。

结论

在本文中,我们研究了一些对分析分类器性能有用的分类指标。我们从真与假、正与负的概念开始。然后将准确性视为一种度量,并观察到它对不平衡的数据集具有误导性。接下来,我们将精确度、召回率和 F1 分数作为处理不平衡数据集的指标。最后,我们看了混淆矩阵,这是一个非常有用的表格表示,可以直观地显示分类器的性能。希望这篇文章对你有帮助。如果您使用任何其他工具或指标,请与我分享!感谢您阅读这篇文章。关注更多有趣和有见地的文章。另外,如果你想了解更多的指标,你可以阅读拉胡尔·阿加瓦尔的文章。

参考

[1]https://developers . Google . com/machine-learning/速成/分类/真-假-正-负

[2]https://developers . Google . com/machine-learning/crash-course/classification/accuracy

https://en.wikipedia.org/wiki/Precision_and_recall

[4]https://developers . Google . com/machine-learning/crash-course/class ification/precision-and-recall

https://en.wikipedia.org/wiki/F-score

https://en.wikipedia.org/wiki/Confusion_matrix

[7]https://sci kit-learn . org/stable/modules/generated/sk learn . metrics . confusion _ matrix . html

如何用 UBIAI 注释 pdf 和扫描图像

原文:https://towardsdatascience.com/how-to-annotate-pdfs-and-scanned-images-for-nlp-applications-f7b7b1db5c4a?source=collection_archive---------20-----------------------

利用 OCR 技术

来自 Pexels 的 cottonbro 摄影

介绍

无论是收据、合同、财务文件还是发票等。自动化信息检索将帮助您以极小的成本提高业务效率和生产率。然而,如果没有的文字注释,这一惊人的壮举是不可能实现的。虽然诸如 NER 或关系提取等 NLP 任务已广泛用于非结构化文本中的信息检索,但分析诸如发票、收据和合同等结构化文档是一项更复杂的工作。

首先,我们想要提取的实体(如价格、卖家、税收等)没有太多的语义上下文。)可用于训练 NLP 模型。第二,从一张发票到另一张发票,文档布局经常改变;这将导致传统的自然语言处理任务,如 NER,在结构化文档中表现不佳。也就是说,结构化文本(如发票)包含丰富的实体空间信息。该空间信息可用于创建 2d 位置嵌入,其表示标记在文档内的相对位置。最近,微软发布了一个新的模型 LayoutLM 来联合建模扫描文档图像中文本和布局信息之间的交互。他们在几个下游任务中取得了新的最先进的结果,包括表单理解(从 70.72 到 79.27)、收据理解(从 94.02 到 95.24)和文档图像分类(从 93.07 到 94.42)。

LayoutLM 位置嵌入架构

扫描图像和 PDF 注释

为了对定制发票的 layoutLM 模型进行微调,我们需要为模型提供带注释的数据,这些数据包含每个标记的边界框坐标以及标记之间的链接(请参见教程这里的以对 FUNSD 数据进行微调):

{
"box": [76,129,118,139],"text": "Brand:","label": "question","words": [{"box": [76,129,118,139],"text": "Brand:"}],"linking": [[0,2]],"id": 0}]}

因为大多数收据和发票都是扫描或 PDF 格式的,所以我们需要找到一种能够直接在原生 PDF 和图像上进行 OCR 解析和注释的注释工具。不幸的是,大多数支持 OCR 注释的注释工具要么过于昂贵,要么不完整,因为您必须在注释之前在外部执行 OCR 步骤。

这就是为什么在 UBIAI 上,我们开发了一个端到端的解决方案,可以直接在原生 pdf、扫描图像或来自您手机的图像上进行注释,而不会丢失任何文档布局信息。这对于文本序列和空间信息同等重要的发票提取非常有用。你所要做的就是直接上传你的 PDF、JPG 或 PNG 文件,然后开始注释。使用 AWS Textract 最先进的 OCR 技术,UBIAI 将解析您的文档,并提取所有标记及其边界框。只需突出显示原始文档(右侧面板)或已解析文本(左侧面板)上的标记,并分配一个标签。除了实体标注,还可以进行关系标注和文档分类标注。

UBIAI OCR 注释接口

注释多个单词也很容易。只需在你想要选择的单词周围创建一个框架,它们就会自动得到注释(见下文)。

带框架选择的 OCR 注释

发票预注释

此外,您可以使用字典、正则表达式(例如查找日期、电子邮件、姓名等)预先注释您的发票。)或者是预先训练好的 ML 模型。

正则表达式输入

使用正则表达式预先标注日期

注释导出

完成注释后,只需以 JSON 格式导出带注释的文档:

JSON 格式的注释导出

结论

UBIAI 的 OCR 标注,通过提供一个简单易用、准确的标注接口,让你训练 NLP 模型的摩擦更小。您不必担心使用外部 API 预处理图像或添加规则来预先注释文档。只需上传您的文档,添加注释,然后导出即可。在下一部分中,我们将展示如何在您自己的发票识别数据集上微调 layoutLM 模型,敬请关注!

如果你想为你的结构化文本训练一个自然语言处理模型,请访问https://ubai . tools或者发邮件给我们安排一个演示!

在推特上关注我们

如何在 Python 中匿名化地点

原文:https://towardsdatascience.com/how-to-anonymise-places-in-python-55597d0ded24?source=collection_archive---------39-----------------------

编码教程,文本分析

一个现成的代码,根据地名数据库识别和隐藏地点

Max 陈在 Unsplash 上的照片

在本文中,我将展示如何在不使用 NLP 技术(如命名实体识别)的情况下,在 Python,中识别和匿名化地点。

地名识别基于地名录,地名录由地名数据库构建。

Geonames 是一个网络服务,包含了(几乎)世界上所有的地方。Geonames 数据库可通过链接免费下载。您可以下载完整的数据库,包括世界上所有国家,或只有一个特定的国家。

这篇文章背后的想法是从 Geonames 数据库中建立一个地名录,并利用它来识别句子中的地点。在实践中,所实现的算法搜索句子中的每个单词是否包含在词典中。为了搜索比一个单词更长的地方,考虑n grams

文章组织如下:

  • 导入 Geonames 数据库
  • 识别句子中的位置
  • 句子中的匿名位置
  • 扩展匿名功能

导入 Geonames 数据库

第一步是导入 Geonames 数据库,可以从此链接下载。您可以选择是导入完整的数据库(AllCountries.zip)还是特定的国家(如意大利的 IT.zip)。每个国家都通过其识别码来识别。

完整的数据库更加完整,但比单一国家数据库需要更多的处理时间。

因此,您应该根据要处理的文本选择正确的数据库。在本教程中,我主要关注意大利数据库,但是同样的代码也可以被其他数据库所利用。

从 Geonames 链接,我下载 IT.zip 文件,解压后放入我的工作目录:

作者图片

然后我把它导入一个熊猫的数据框架:

import pandas as pddf = pd.read_csv('source/IT.txt', sep=' ', header=None)

作者图片

数据框架的第 1 列包含用于建立地名索引的地点列表:

gaz = df[1]
gaz = gaz.tolist()

实施的地名索引包含 119.539 个地方。

识别句子中的位置

现在我定义一个函数,它接收一个文本作为输入,然后返回文本中包含的所有位置。该函数执行以下操作:

  • 删除文本中的所有标点符号
  • 将句子分割成记号,用空格符隔开。这可以通过split()功能来完成
  • 从识别出的记号开始,构建所有可能的 ngrams,n ≤ 5。我利用nltk库的ngrams函数将文本分割成 ngrams。例如在句子 Oggi sono andata a Parigi 中,n ≤ 5 的 ngrams 包括:
(‘Oggi’, ‘sono’, ‘andata’, ‘a’, ‘Parigi’)
(‘Oggi’, ‘sono’, ‘andata’, ‘a’)
(‘sono’, ‘andata’, ‘a’, ‘Parigi’)
(‘Oggi’, ‘sono’, ‘andata’)
(‘sono’, ‘andata’, ‘a’)
(‘andata’, ‘a’, ‘Parigi’)
(‘Oggi’, ‘sono’)
(‘sono’, ‘andata’)
(‘andata’, ‘a’)
(‘a’, ‘Parigi’)
(‘Oggi’,)
(‘sono’,)
(‘andata’,)
(‘a’,)
(‘Parigi’,)
  • 从最大的 n 元语法开始(n = 5),搜索每个 n 元语法是否包含在地名录中。如果是,则找到一个位置,并且可以将其添加到找到的位置的列表中,并且从原始文本中移除该位置,否则,继续。注意

该函数的完整代码如下:

from nltk import ngrams
import redef get_places(txt):
    # remove punctuation
    txt = re.sub(r"[^\w\d'\s]+",'',txt)
    n = 5
    places = []

    for i in range(n,0,-1):
        tokens = ngrams(txt.split(), i)
        for t in tokens:
            token = " ".join(t)
            try:
                res = gaz.index(token)
            except ValueError:
                continue
            if res:
                places.append(token)
                txt = txt.replace(token,"")
    return places

现在我可以用一个例子来测试这个函数:

txt = 'Oggi sono andata a Roma e a Milano.'
get_places(txt)

它给出了以下输出:

['Roma', 'Milano']

句子中的匿名位置

现在,我准备利用前面定义的函数来匿名化函数。简单地说,我可以用符号字符替换找到的位置,例如 x。所有的搜索操作都必须在原始文本的副本上进行,以便保留原始文本(即删除标点以便操作)。

这是匿名的完整功能:

def anonymise_places(txt):
    temp_txt = re.sub(r"[^\w\d'\s]+",'',txt)
    n = 5
    # remove punctuation
    for i in range(n,0,-1):
        tokens = ngrams(temp_txt.split(), i)
        for t in tokens:
            token = " ".join(t)
            try:
                res = gaz.index(token)
            except ValueError:
                continue
            if res:
                txt = txt.replace(token,"X")
                temp_txt = temp_txt.replace(token,"")
    return txt

扩展匿名功能

所实现的功能可以通过覆盖全世界的地名录来扩展。然而,全世界的地名数据库约为 1.5 GB,因此难以管理。因此,您可以下载它,加载到 Pandas 中,然后只选择感兴趣的列(对应于列 1 ),并将结果导出为一个新的 csv 文件,大约 274 MB:

df_all = pd.read_csv('source/allCountries.txt', sep=' ', header=None)
df_all[1].to_csv('source/places.csv')

前面的操作可能需要一段时间,因为文件非常大。然后,您可以将这个新文件用作地名词典,而不是 IT.txt。

摘要

在本文中,我描述了如何在不使用 NLP 技术的情况下匿名化 Python 中的位置。拟议的方法是基于使用地名录,地名录是根据地名数据库建立的。

本教程的完整代码可以从我的 Github 库下载。本教程还包含了一个在gradio中的函数测试,这是一个非常强大的用于 Web 应用的 Python 库。请继续关注关于gradio的教程

相关文章

https://medium.datadriveninvestor.com/how-to-restore-the-original-layout-of-a-text-document-after-a-manipulation-in-python-8f3de41e8e95 https://medium.com/geekculture/the-top-25-python-libraries-for-data-science-71c0eb58723d

如何回答一个编码面试问题?

原文:https://towardsdatascience.com/how-to-answer-a-coding-interview-question-1613776358e?source=collection_archive---------21-----------------------

Jexo 在 Unsplash 上的照片

帮助您回答编码问题的分步指南。

C oding 面试是各种软件相关职位必不可少的一部分,比如软件工程师、机器学习工程师、数据科学家等。大多数公司使用编码进行技术筛选。这意味着如果你不能很好地编码,他们将不会继续你的面试过程。今年早些时候,当我申请各种 ML 工程师职位时,我最初的技术筛选面试中有近 85%是由编码轮组成的。

将编码作为日常工作的一部分并不能保证你会在这些编码面试中表现出色。在几次编程面试失败后,我艰难地学会了这一点。在面试中,用某种语言编写代码的能力只是冰山一角(下一节中的[F5])。时间管理,与类似的问题相关,打磨你的基础,练习是一些需要做的关键事情。在这篇文章中,我将分享我准备编码面试的有组织的方法。我将这篇文章分成两部分。

你在什么方面被评估?

首先要了解面试官感兴趣的是什么,这样我们才能相应地回答他们。面试官通常根据以下评估标准来评估你

【EC1】—理解问题的能力

【EC2】—需要时收集信息的能力

【EC3】—遇到问题时你的思考过程

【EC4】—以有组织/模块化的方式编码的能力

【EC5】—您的编码技能和评估运行时约束的能力

【EC6】—在工作中实现改进的能力

编码模板

我发现定义一个模板并在我的编码面试中使用它非常有用。该模板有助于以一种有组织的方式划分你的思维过程,以避免对一件事说得太多,而没有时间留给其他人。这也有助于瞄准面试官正在寻找的必要因素[EC1-EC6]。

如何回答一个编码问题?—模板(作者图片)

1。听问题:

面试官会解释问题,并通过一个玩具例子来帮助你理解问题。当面试官解释的时候,在另一张纸上记下你认为关键的要点。

目标:【EC1】

2。谈谈你对问题的理解:

听完问题,不要跳进去开始编码(即使你确切知道问题是什么,如何解决) 。而是重复问题,确认自己的理解。询问澄清性问题,例如

  1. 输入/输出数据类型限制是什么?
  2. 输入大小/长度有限制吗?
  3. 如果输入无效会发生什么?
  4. 角落/特殊情况:特定问题的问题,例如当你在一个字符串中看到一个非数字字符,而两个数字字符串需要相乘时会发生什么?(你认为它是无效输入,还是忽略非数字字符?)

大多数时候面试官不会给你所有需要的信息。面试官在求职者身上寻找的东西之一是 能够问正确的问题来收集所有必要的信息

目标:【EC1】,【EC2】

3。讨论你的方法:

讨论你解决问题的方法,问面试官他/她是否同意。谈谈你更喜欢使用的数据结构及其背后的原因。和面试官讨论伪代码。

目标:【EC3】

4.开始编码:

在你真正开始编码之前,一定要问面试官。定义有用的函数,并在编写代码时进行解释。编码时最重要的事情是大声思考,这样面试官可以评估你的思考过程。在每一行代码中,大声说出你为什么使用它,以及这个选择将如何影响代码输出。例如,在编写 For 循环时,比方说

“现在我们将定义一个 for 循环,一次迭代 xyz 列表中的一个元素,以便我们可以根据期望的输出[或特定于问题的原因]处理每个元素”

万一你被困在某个地方,面试官会给你一些微妙的暗示。一定要注意那些暗示。

目标:【EC4】,【EC5】

5.讨论时间和空间的复杂性

根据你的方法的大 O 来讨论你的代码的时间和空间复杂度。这个有用的资源对初学者来说是一个很好的起点。试着把你的代码分解成块,讨论时间复杂度,然后再谈代码的整体时间复杂度。

目标:【EC5】

6.优化方法(如果可能或者面试官建议)

在讨论了你的代码的复杂性之后,如果你的方法还没有优化,面试官可以要求你改进它。面试官会通过提示来强调可以改进的代码块。一定要注意这一点。

目标:【EC5】,【EC6】

这个 6 步模板将帮助你分而治之解决面试问题。

总结:

编码面试不仅仅是关于你的编码技能。这也是关于你在压力下的工作能力。如果你有一个很好理解的模板可以遵循,它一定会帮助你管理你的时间。知道面试官在寻找什么将有助于你有条理地处理这些因素。本文研究了成功的编码面试的一些重要评估标准,并讨论了回答编码问题的模板。

您可能还会发现下面的文章很有用

https://medium.com/swlh/cheat-sheets-for-machine-learning-interview-topics-51c2bc2bab4f

如果这篇文章对你有帮助,或者你想了解更多关于机器学习和数据科学的知识,请关注我Aqeel an war,或者联系我LinkedIn或者Twitter

如何回答任何机器学习系统设计面试问题

原文:https://towardsdatascience.com/how-to-answer-any-machine-learning-system-design-interview-question-a98656bb7ff0?source=collection_archive---------0-----------------------

下次面试时回答任何机器学习系统设计问题的模板。

这个模板将指导你解决几乎所有你在面试中遇到的 ML 系统设计问题。值得注意的是,该模板是有意通用的,以便当您发现新的系统设计问题时,可以很容易地填写每个部分。​

以下是您在进行 ML 系统设计面试时应该采取的步骤的概述:

当你在回答一个 ML 设计面试问题时,要关注的两个领域是数据和建模。这是因为 ML 设计面试的主旨是了解你面对(几乎)现实世界问题时的思维过程,数据收集/预处理以及你将选择的模型将是你将构建的核心组件。因此,你应该在面试中重点关注这些方面。​

澄清要求

米米·蒂安在 Unsplash 上的照片

当给你一个问题时,你应该做的第一件事是澄清要求。例如,您的提示可以是“设计一个向拥有个人资料的用户推荐我们产品的系统。”大多数 ML 系统设计问题都是有意模糊的,这样你会问更多的问题来理解范围和你应该关注的组件。​

在面试官给你提示后,用你自己的话重述一遍。这可以确保你和面试官在同一页上,你会回答正确的问题。​

为了理解范围,您应该问一些问题:

  1. 我们能接触到多少数据?[对于较小的数据集,不太复杂的模型可能更合适,但对于较大的数据集,像深度神经网络这样的较大模型可能会起作用]
  2. 硬件限制:我们有多少时间来完成任务?有多少计算能力可用?[如果我们受到硬件尺寸的限制,那么我们应该使用更简单的型号]
  3. 我们是需要一个能快速响应请求的模型,还是需要一个极其精确的模型?[深度模型通常比传统的 ML 模型更慢但更准确,这个问题向面试官表明你正在考虑权衡取舍]
  4. 我们需要考虑重新训练模型吗?

你应该把这些答案写在白板上(或者如果你是在网上面试的话,写在网上)。请注意,根据使用情形,有些问题可能不相关,因此您不需要询问所有问题。

韵律学

既然您已经对用例有了一个清晰的概念,并且问了一些澄清性的问题,那么您可以使用这些信息来确定建模时使用的最佳度量。您应该始终给出至少两个指标:一个用于离线,一个用于在线。

离线指标是我们在构建模型时用来给模型打分的指标。这是在投入生产并展示给用户之前。这是研究或教程中的典型场景,其中您将数据集分为三个集:训练集、评估集和测试集。这些离线指标的一些例子是 AUC、F1、R、MSE、联合交集等。

在线指标是一旦模型投入生产服务请求,我们从模型中得到的分数。在线指标可以是点击率或用户观看推荐视频的时长。这些指标是特定于用例的。你需要考虑一旦模型投入生产,公司将如何评估它对用户是否有用。

另一组有用的指标是非功能性指标。你可以向面试官提到这些,以表明你正在考虑所有可能的方法来衡量一个模型的好处。

非职能指标:

  • 超大型数据集的训练速度和可扩展性
  • 新技术的可扩展性
  • 易于培训、调试、评估和部署的工具

体系结构

下一步是创建一个通用架构,有些公司要求你画出架构。您至少应该包括以下步骤:

数据

这一部分和下一部分将是你在面试中花费最多时间的地方,也是面试官关注你表现的地方。

  1. 首先,确定目标变量以及如何收集和标记它(如果需要)
  • 在推荐的例子中,目标变量是历史上用户是否喜欢公司的产品。通常有两种方法可以收集这个目标值:隐式或显式。显式目标收集的一个例子是,如果我们查看我们的日志并检查是否有人购买了某个产品,这意味着他们非常喜欢该产品并购买了它。另一方面,如果用户“保存以备后用”某个产品或者用户查看某个产品一定次数,则隐式目标集合将是。请注意,在大多数情况下,显式数据收集通常是收集目标变量的最佳方式。如果你认为你可以找到一种方法来隐含地收集目标变量,那么和你的面试官进行这样的讨论,然后谈论你的每个隐含建议的利弊。

2。讨论功能和可能的功能交叉:

  • 推荐示例的一些可能的特征可以是用户位置、用户年龄、先前观看的视频、视频标题、视频新鲜度等。

3。特色工程:

  • 列车测试分离。
  • 处理缺失值或异常值:通常,我们可以丢弃异常值,如果有大量数据,那么我们可以丢弃缺失值,如果数据有限,那么我们可以通过平均值(或任何其他处理缺失值的方法)估算数据。和你的面试官谈论这个问题,记住这是一次讨论。
  • 平衡正面和负面训练示例:如果您注意到可能会有非常大的不平衡,那么您应该讨论解决这个问题的方法:上采样、下采样以及其他技术,如 SMOTE。
  • 规范化某些列。

4。功能选择:

  • 如果我们使用深度神经网络,那么我们不需要特征选择。如果需要,基于树的估计器可以用来计算特征重要性。此外,我们可以使用 L1 范数进行正则化,使得一些特征系数为零。

5。其他注意事项:

  • 偏见:我们是否从足够大的人口统计子集抽样,如果不是,也许我们可以将最大的分组,并将其他分组为 OOV 人口统计。
  • 对隐私/法律有什么顾虑吗?出于隐私考虑,我们可能需要匿名或删除数据。

一旦我们完成了关于数据的讨论,你应该问面试官他们是否希望你解释如何生产这些数据步骤。根据经验,大多数面试官并不太关心机器学习(ML OPs)的可操作性,因为这是一个新领域,产品和最佳实践一直在变化,然而,表明你知道你需要将你的工作流程生产化将向面试官表明你不仅在 ML 的理论方面很强,而且在工程方面也很强。

数据的 ML 操作:

  1. 存储数据:
  • 如果有任何对象存储(图像、视频等。)需求:亚马逊 S3,GCP 云存储
  • 元数据和结构化(表格)数据的数据库:MySQL、Postgres、Oracle
  • 功能商店(存储和访问 ML 功能)(离线):FEAST、亚马逊 SageMaker 功能商店、Hopsworks 功能商店
  • 数据版本化:DVC,厚皮动物

2。数据摄取和转换:

  • 摄取:离线数据→可以查询您的数据库,在线数据→我们需要高吞吐量和低延迟,所以我们应该使用在线流媒体平台,如 Apache Kafka 和 Apache Flume
  • 转换功能:Apache Spark、Tensorflow 转换

3。编排平台:

  • 气流
  • 库伯内特斯

模型

一旦您到达建模组件,您应该首先给出一个基线模型(如果可能的话)。通常你会有一个不需要机器学习的基线模型。例如,我们之前提示的一个好的基线是向用户推荐最受欢迎的产品。这个“模型”总是容易实现的,并且你现在有了一个基线,你所有的其他模型都应该超越它。​

然后,谈论传统的 ML 模型,这些模型可以快速训练,例如逻辑回归或决策树。一旦你讨论了这些,你就可以谈论更复杂的方法,比如深度学习。

注意:不要忘记给出你所说的每种方法的利弊。示例:

型号 A:

  • 模型、超参数和损失函数的简要说明
  • 模型 A 的优点
  • 模型 A 的缺点

同样,你应该问面试官他们是否希望你解释一下如何生产这种组件。

建模用 ML OPs:

  1. 实验的可重复性:
  • 毫升流量
  • 库贝弗洛

2.并行化超参数调优:Google Cloud、Azure、AWS

3.模型版本控制:

  • DVC
  • 亚马逊 SageMaker
  • 谷歌云人工智能平台

服务

照片由弗洛里安·克拉姆在 Unsplash 上拍摄

现在你要把模型服务给用户,这是面试的最后一部分。

需要提及以下几点:

  1. 在线 A/B 测试:讨论使用您之前提到的在线指标来执行 A/B 测试。
  2. 在哪里运行推断:如果我们在用户的手机/电脑上运行模型,那么它将使用他们的内存/电池,但延迟会很快,另一方面,如果我们在自己的服务上存储模型,我们会增加延迟和隐私问题,但会消除占用用户设备内存和电池的负担。
  3. 监控性能:我们应该记录的一些度量是错误率、返回查询的时间和度量分数。
  4. 你的模型的偏见和误用:它从数据中传播了任何性别和种族偏见吗?
  5. 我们应该提到我们多长时间重新训练一次模型。有些模型需要每天重新培训,有些需要每周重新培训,有些需要每月/每年重新培训。经常讨论你选择的再培训制度的利弊。

同样,你应该问面试官他们是否希望你解释一下如何生产这种服务成分。

上菜 ML OPs:

  1. 将日志存储在数据库中,如 ElasticSearch、Logstash、GCP、AWS、Azure
  2. 日志记录分析工具:Kibana、Splunk
  3. CI/CD: CircleCI,Travis CI
  4. 在嵌入式和移动设备上部署
  • 量化
  • 缩小模型尺寸(移动网络)
  • 知识蒸馏(酿酒厂等。)

如何用数据回答复杂问题

原文:https://towardsdatascience.com/how-to-answer-complex-questions-with-data-66ee8e77de20?source=collection_archive---------24-----------------------

早期职业数据科学家经常担心他们的编码和数学技能,或者担心他们是否掌握了足够多的算法。然而,正如我们一次又一次看到的,最复杂问题的答案往往在于将正确的工具与清晰的方法结合起来。当然,学会做那件事说起来容易做起来难。以下是最近的六篇文章,它们探讨了棘手的问题,并带着好奇心和耐心去解决它们——我们希望它们能激励你去尝试一些新的东西。

  • 学习如何利用机器学习和统计学来衡量社会影响 。朱莉娅·尼库尔斯基很想知道公司董事会的构成会如何影响其在可持续发展和人权等领域的表现。Julia 使用多种数据源和利用 NLP 和回归分析的技术,展示了将正确的人放在正确的位置以推动更好的公司政策的明显效果。
  • 发现计算关键指标的新方法 。人口密度可能不是我们大多数人每天都在考虑的事情——或者永远都不会——但它对于政府、医疗系统和城市规划者(以及其他许多人)来说是一个关键的统计数据。尼克·琼斯向我们展示了高分辨率定居层 (HRSL)的强大功能,这是一个“制作巧妙的大型数据集,描绘了地球大部分地区每个 30 米网格单元中的人口数量。”他还解释了如何用几行代码来查询它。

斯蒂芬妮·勒布朗在 Unsplash 上拍摄的照片

  • 在激动人心的增强世界 中了解最新情况。如果你本周只打算阅读一篇专注于深度学习的博客文章,你不妨去看看乔纳森 Laserson 关于测试时间增加、对比损失以及我们如何最终到达自我监督学习成为现实的时刻的精彩解释。
  • 搞清楚倾向评分分层的意义。最近几周,叶雷华发表了一系列信息丰富的帖子,重点关注从大量数据中推断因果关系的挑战。在最新的一期中, Leihua 转向倾向分数,并分享了利用分层方法所需的理论背景和实践细节。
  • 找出你正在做的异常检测是否正确 。Julia Bohutska 说商业智能并不缺少产品和解决方案,但是通常很难评估性能和量化工具对业务的潜在影响。她继续解释她的团队如何基于业务数据建立评估管道,以衡量他们在异常检测方面的成功。
  • 【探索重要性加权回归的力量】(IWR) 。罗摩 183;罗摩克里希南关于从数据中得出最佳政策的系列文章现在已经完成;在这最后一篇文章中,Rama 转向一个三步流程,该流程将允许您使用一个模型做出明智的商业决策,该模型直接预测不同行动之间的结果差异。

感谢您参加我们本周的活动——为学习、分享知识和寻找降低工作(及其他)复杂性的新方法干杯。我们永远感谢你花时间阅读我们作者的文章,感谢你对他们写作的支持。

直到下一个变量,
TDS 编辑

我们策划主题的最新内容:

入门

  • 如何建立您的数据分析团队作者 Louise de Leyritz
  • 作为数据科学家如何更有效地沟通👩🏻‍💻张凯茜
  • x ticks 和 xticklabels 如何真正工作:亨利·阿尔珀特的演练

实践教程

  • 当一个统一的阈值不够用时作者塞巴斯蒂安·吉尔伯特
  • 搜索算法——概念和实现作者四维·考瑟维克
  • 为什么开始使用 sktime 进行预测?作者乔安娜·兰丘克

深潜

  • 训练你自己的国际象棋人工智能由洛根·斯皮尔斯
  • 变形金刚,你能评价阅读段落的复杂程度吗?作者张佩琦
  • 正念机器:神经科学&伦理人工智能的批判理论作者 Haaya Naushan

思想和理论

  • 逻辑解释网络作者皮埃特罗·巴比洛
  • 由 Masaki Adachi 利用 1D RegNet 和 AdaCos 的深度度量学习进行自动光谱识别
  • 由 Monique Cruz 对用户上传的文档进行分类

如何成功应用迁移学习

原文:https://towardsdatascience.com/how-to-apply-transfer-learning-successfully-6b6f489d287d?source=collection_archive---------34-----------------------

斯科特·格雷厄姆在 Unsplash 上拍照

在数千个计算小时上训练的高度准确的深度学习模型的可用性导致了迁移学习在生产中的采用。

注:你也可以在这里 找到这篇帖子https://kanishkmair.com/ml/transfer-learning/

过去十年在深度学习研究领域取得了飞跃,自动化了几项艰巨的任务。然而,这些高度精确的模型需要在消耗大量计算资源的大型云集群/GPU 机器上进行数周的训练。但是,还有一线希望;AI 社区从一开始就是开源的,大部分模型架构和训练参数都很容易使用。

在 NLP 领域,人们可以使用拥抱脸库来训练和微调他们的语言模型。在本文中,我们将迁移学习应用于图像分类任务,使用预训练的模型权重并根据我们的情况进行微调。

步骤 1:训练模型选择

这是研究中最重要的部分:确定最适合我们应用的场景。例如,为敌对网络训练的 CNN 模型可能无法以同样高的精度解决图像分类任务。因此,对训练所选模型的数据集类型以及与我们的问题的相似性进行彻底的研究是选择最佳候选对象所必需的。

第二步:培训方法

在深度学习模型已经使用 CNN 架构的计算机视觉任务的情况下,如果数据相似,我们只修改某些层,因为模型已经学习了有用的图像特征。另一方面,如果我们想找到新的模式,我们训练所有的层。最后,该方法还可能会受到计算资源和可用时间的限制;因此,必须相应地做出谨慎的决定。
我通常会借助以下指南来帮助最终确定方法。

表 1。将基于数据集大小和相似性的学习指南转移到预训练模型的数据集

类似地,在 NLP 任务的情况下,我们可以利用预先训练的单词嵌入,并基于我们的模型架构训练其余的单词嵌入。在这里,我将使用 PyTorch,我们首先导入相关的库。

迁移学习的用例

作为一个例子,让我们假设我们的任务是图像分类。为了模拟这个场景,让我们假设我们获得了 CIFAR-10 数据集来预测 10 个类别。

步骤 1:训练模型选择

首先,我们了解任务并查阅相关研究。常见深度学习任务的预训练模型的一个非常受欢迎的资源是 ONNX 模型动物园,它链接了各种论文和训练好的模型权重。接受图像分类训练的一些模型有 MobileNet、VGG、AlexNet 等。

在选择最高精度的模型之前,我们首先检查它与我们的数据集的训练数据的相似程度。对所有模型的描述表明,它们是在包含多个类的 ImageNet 数据上训练的。在分析我们的 CIFAR-10 数据集时,我们发现它包含正常的图像(没有敌对的例子)。

第二步:培训方法

最后,我们可以得出结论,数据集与我们的相似。现在,我们必须确定数据集是否足够大或足够小。与来自 ImageNet 数据集的高质量图像相比,我们数据集的图像大小更小,但另一方面,任务更简单,因为我们只需预测 10 个类。作为实验,让我们考虑这两种情况。从表中,我们的方法可以是选择分别训练所有层或只训练最后几层。

:查看此 GitHub 链接 获取源代码

准备数据

更多的时候,我们试图在已经标记的数据上进行训练。虽然,如果需要的话,一个定制数据集也可以用于训练。因为我们使用 CIFAR-10 数据集作为输入,它也是由 PyTorch 提供的,所以我们可以加载所需的转换,如下所示。

原始的 CIFAR10 数据集列出了使用 categ_map 变量的 10 个类别,我们可以验证正确的映射。注意,该数据集具有低分辨率(32×32 像素)的图像,使得预训练模型(在 224×244 像素上训练)难以直接预测,需要进一步训练。

图一。来自 CIFAR-10 数据集的样本图像|作者提供的图像

模型选择和培训

根据初步分析,该数据集与 ImageNet 数据集非常相似,PyTorch 上的所有预训练模型都在 ImageNet 数据集上。如前所述,数据集的大小对于 10 个类来说足够大,但由于我们必须将图像调整到更高维度,我们不能确定数据集是否足够大以进行归纳。如前所述,为了进行试验,我将使用这两种方法,这些任务的相应模型是:

  1. AlexNet —微调模型检查点(即假设大数据集并训练整个模型)。
  2. VGG-仅训练最后几个图层(即假设数据集很小,仅训练分类图层)。
*# Load the pretrained model from pytorch
Alexnet = models.alexnet(pretrained=True)
VGG = models.vgg13(pretrained=True)*

以上预训练模型直接从 PyTorch 加载。然而,如果我们想要 PyTorch 上没有的特定 ONNX 模型,可以参考这里的将这些模型加载到 PyTorch 中。

接下来,检查模型层,因此我提供了 alter_model 函数,它可以使模型的最终层或所有层可训练。

图二。AlexNet 架构将被修改|图片由作者提供

使用上面的函数,所需的层权重已经被激活用于训练。现在可以训练模型并使用度量标准,我们可以选择最佳模型。

训练指标有助于确定更大的 VGG 模型具有更高的模型准确性,即使 AlexNet 模型经过了微调。

图 3。损失和准确度图显示 VGG 模型优于 AlexNet 模型|图片由作者提供

估价

报告 2 个模型的测试数据的关键指标。基于测试数据结果,可以进行进一步的模型训练和超参数优化。

最后,一旦模型被训练,我们可以使用下面的函数来查看它的运行。

图 4。使用训练模型预测|作者的图像

结论

总之,如果我们的用例不是非常独特,我们必须尝试研究和利用预先训练的模型参数,并相应地进行微调。在这里,在没有任何超参数调整的情况下,我只训练了 20 分钟,就能够在测试数据(10,000 个样本)上实现 80%的最佳准确度。

最重要的是,对于迁移学习,我们必须知道模型的来龙去脉,以及如何修改它以适应我们的场景和数据集的差异。否则,我们可能从一个有前途的模型中得到非常差的结果。

如何将变形器应用于任意长度的文本

原文:https://towardsdatascience.com/how-to-apply-transformers-to-any-length-of-text-a5601410af7f?source=collection_archive---------0-----------------------

实践教程

为长序列恢复 NLP 的能力

由塞巴斯蒂安·斯坦尼斯在 Unsplash 上拍摄的照片

如今,许多自然语言处理(NLP)任务中事实上的标准是使用转换器。文本生成?变压器。问答?变压器。语言分类?变压器

然而,这些模型的一个问题(这个问题不仅仅局限于 transformer 模型)是我们不能处理长文本。

我在 Medium 上写的几乎每篇文章都包含 1000 多个单词,当对像 BERT 这样的 transformer 模型进行标记化时,将产生 1000 多个标记。BERT(和许多其他变形金刚模型)将消耗最多 512 个令牌——截断任何超过这个长度的东西。

虽然我认为您可能很难在处理我的媒体文章中找到价值,但这同样适用于许多有用的数据源——如新闻文章或 Reddit 帖子。

我们将看看如何解决这个限制。在本文中,我们将从 /r/investing 子编辑中找到对长文的看法。本文将涵盖:

**High-Level Approach****Getting Started**
- Data
- Initialization**Tokenization****Preparing The Chunks**
- Split
- CLS and SEP
- Padding
- Reshaping For BERT**Making Predictions**

如果你更喜欢视频,我在这里也涵盖一切:

高级方法

实际上,计算较长文本的情感背后的逻辑非常简单。

我们将获取我们的文本(比如 1361 个标记)并将其分成包含不超过 512 个标记的块。

包含 1361 个记号的张量可以分成三个更小的张量。前两个张量各包含 512 个记号,最后一个张量包含剩余的 337 个记号。

一旦我们有了我们的组块,并对它们进行了转换,以便它们可以被 BERT 使用(稍后会有更多内容),我们就可以将它们传递给我们的模型,并检索每个组块的情感得分。

最后,对每个情感类别取平均值,为我们提供了对整篇文本(所有 1361 个标记)的总体情感预测。

现在,解释高层方法是一回事。写出来是另一回事。让我们从一个例子开始。

入门指南

数据

首先,我们需要一些数据来处理。我在/r/investing 上发现了这个相当长的帖子:

I would like to get your all  thoughts on the bond yield increase this week.  I am not worried about the market downturn but the sudden increase in yields. On 2/16 the 10 year bonds yields increased by almost  9 percent and on 2/19 the yield increased by almost 5 percent.

Key Points from the CNBC Article:

* **The “taper tantrum” in 2013 was a sudden spike in Treasury yields due to market panic after the Federal Reserve announced that it would begin tapering its quantitative easing program.**
* **Major central banks around the world have cut interest rates to historic lows and launched unprecedented quantities of asset purchases in a bid to shore up the economy throughout the pandemic.**
* **However, the recent rise in yields suggests that some investors are starting to anticipate a tightening of policy sooner than anticipated to accommodate a potential rise in inflation.**

The recent rise in bond yields and U.S. inflation expectations has some investors wary that a repeat of the 2013 “taper tantrum” could be on the horizon.

The benchmark U.S. 10-year Treasury note climbed above 1.3**% f**or the first time since February 2020 earlier this week, while the 30-year bond also hit its highest level for a year. Yields move inversely to bond prices.

Yields tend to rise in lockstep with inflation expectations, which have reached their highest levels in a decade in the U.S., powered by increased prospects of a large fiscal stimulus package, progress on vaccine rollouts and pent-up consumer demand.

The “taper tantrum” in 2013 was a sudden spike in Treasury yields due to market panic after the Federal Reserve announced that it would begin tapering its quantitative easing program.

Major central banks around the world have cut interest rates to historic lows and launched unprecedented quantities of asset purchases in a bid to shore up the economy throughout the pandemic. The Fed and others have maintained supportive tones in recent policy meetings, vowing to keep financial conditions loose as the global economy looks to emerge from the Covid-19 pandemic.

However, the recent rise in yields suggests that some investors are starting to anticipate a tightening of policy sooner than anticipated to accommodate a potential rise in inflation.

With central bank support removed, bonds usually fall in price which sends yields higher. This can also spill over into stock markets as higher interest rates means more debt servicing for firms, causing traders to reassess the investing environment.

“The supportive stance from policymakers will likely remain in place until the vaccines have paved a way to some return to normality,” said Shane Balkham, chief investment officer at Beaufort Investment, in a research note this week.

“However, there will be a risk of another ‘taper tantrum’ similar to the one we witnessed in 2013, and this is our main focus for 2021,” Balkham projected, should policymakers begin to unwind this stimulus.

Long-term bond yields in Japan and Europe followed U.S. Treasurys higher toward the end of the week as bondholders shifted their portfolios.

“The fear is that these assets are priced to perfection when the ECB and Fed might eventually taper,” said Sebastien Galy, senior macro strategist at Nordea Asset Management, in a research note entitled “Little taper tantrum.”

“The odds of tapering are helped in the United States by better retail sales after four months of disappointment and the expectation of large issuance from the $1.9 trillion fiscal package.”

Galy suggested the Fed would likely extend the duration on its asset purchases, moderating the upward momentum in inflation.

“Equity markets have reacted negatively to higher yield as it offers an alternative to the dividend yield and a higher discount to long-term cash flows, making them focus more on medium-term growth such as cyclicals” he said. Cyclicals are stocks whose performance tends to align with economic cycles.

Galy expects this process to be more marked in the second half of the year when economic growth picks up, increasing the potential for tapering.

## Tapering in the U.S., but not Europe

Allianz CEO Oliver Bäte told CNBC on Friday that there was a geographical divergence in how the German insurer is thinking about the prospect of interest rate hikes.

“One is Europe, where we continue to have financial repression, where the ECB continues to buy up to the max in order to minimize spreads between the north and the south — the strong balance sheets and the weak ones — and at some point somebody will have to pay the price for that, but in the short term I don’t see any spike in interest rates,” Bäte said, adding that the situation is different stateside.

“Because of the massive programs that have happened, the stimulus that is happening, the dollar being the world’s reserve currency, there is clearly a trend to stoke inflation and it is going to come. Again, I don’t know when and how, but the interest rates have been steepening and they should be steepening further.”

## Rising yields a ‘normal feature’

However, not all analysts are convinced that the rise in bond yields is material for markets. In a note Friday, Barclays Head of European Equity Strategy Emmanuel Cau suggested that rising bond yields were overdue, as they had been lagging the improving macroeconomic outlook for the second half of 2021, and said they were a “normal feature” of economic recovery.

“With the key drivers of inflation pointing up, the prospect of even more fiscal stimulus in the U.S. and pent up demand propelled by high excess savings, it seems right for bond yields to catch-up with other more advanced reflation trades,” Cau said, adding that central banks remain “firmly on hold” given the balance of risks.

He argued that the steepening yield curve is “typical at the early stages of the cycle,” and that so long as vaccine rollouts are successful, growth continues to tick upward and central banks remain cautious, reflationary moves across asset classes look “justified” and equities should be able to withstand higher rates.

“Of course, after the strong move of the last few weeks, equities could mark a pause as many sectors that have rallied with yields look overbought, like commodities and banks,” Cau said.

“But at this stage, we think rising yields are more a confirmation of the equity bull market than a threat, so dips should continue to be bought.”

我们将以此为例。

初始化

我们需要做的下一件事是初始化我们的模型和标记器。我们将使用 PyTorch 和变形金刚库做任何事情。

幸运的是,transformers 库的初始化非常简单。我们将使用一个用于序列分类的 BERT 模型和相应的 BERT 记号化器,所以我们写:

因为我们使用的是偏重金融的语言,所以我们加载了ProsusAI/finbert模型——一个更懂金融的 BERT [1]。你可以在这里找到车型详情。

标记化

标记化是将文本字符串转换为标记(单个单词/标点)和/或标记 id(将单词映射到嵌入数组中该单词的矢量表示的整数)列表的过程。

对于 transformers 库和 BERT,通常如下所示:

txt = "<this is the large post included above>"tokens = tokenizer.encode_plus(
    txt, add_special_tokens=True,
    max_length=512, truncation=True,
    padding="max_length"
)

这里我们使用 tokenizers encode_plus方法从txt字符串创建我们的令牌。

  • add_special_tokens=True为我们新的“标记化”编码增加了特殊的 BERT 标记,如【CLS】**【SEP】【PAD】
  • max_length=512告诉编码器我们编码的目标长度。
  • truncation=True确保我们剪切比指定的max_length更长的任何序列。
  • padding="max_length"告诉编码器用填充标记填充任何比max_length短的序列。

这些参数构成了标记化的典型方法。但是,正如你所看到的,当我们打算将一个较长的序列分割成多个较短的块时,它们是不兼容的。

为此,我们修改了encode_plus方法,不执行任何截断或填充。

此外,特殊记号【CLS】【SEP】将分别出现在序列的开始和结尾。因为我们将分别创建这些序列,所以我们也必须分别添加这些令牌。

新的encode_plus方法如下所示:

这将返回一个包含三个键值对的字典,input_idstoken_type_idsattention_mask

我们还添加了来从记号赋予器返回 PyTorch 张量(而不是 Python 列表)。

准备区块

现在我们有了记号化张量;我们需要把它分成不超过 510 个令牌的块。我们选择 510 而不是 512,以留出两个位置来添加我们的【CLS】【9】代币。

裂开

我们将split方法应用于我们的输入 id 和注意力屏蔽张量(我们不需要标记类型 id,可以丢弃它们)。

现在每个张量集有三个块。注意,我们将需要在最后的块中添加填充,因为它不满足 BERT 要求的张量大小 512。

CLS 和 SEP

接下来,我们添加序列的开始标记【CLS】和分隔符【SEP】。为此,我们可以使用torch.cat函数,该函数包含一个张量列表。

我们的令牌已经是令牌 ID 格式,因此我们可以参考上面的特殊令牌表来创建我们的【CLS】【SEP】令牌的令牌 ID 版本。

因为我们是针对多个张量来做的,所以我们将torch.cat函数放入一个 for 循环中,并对我们的每个块分别执行连接。

此外,我们的注意力屏蔽块与 1 s 连接,而不是与 101102 连接。我们这样做是因为注意掩码不包含令牌 id,而是包含一组 10

注意掩码中的零表示填充标记的位置(我们接下来会添加),由于【CLS】【SEP】不是填充标记,所以用 1 s 表示

填料

我们需要向张量块添加填充,以确保它们满足 BERT 要求的 512 张量长度。

我们的前两个块不需要任何填充,因为它们已经满足了这个长度要求,但是最后的块需要。

为了检查一个块是否需要填充,我们添加了一个 if 语句来检查张量长度。如果张量短于 512 个记号,我们使用torch.cat函数添加填充。

我们应该将这个语句添加到同一个 for 循环中,在这个循环中我们添加了【CLS】【SEP】标记——如果您需要这方面的帮助,我已经在文章的末尾提供了完整的脚本。

为伯特重塑形象

我们有自己的块,但是现在我们需要将它们重新整形为单个张量,并将它们添加到 BERT 的输入字典中。

使用torch.stack函数将所有张量叠加在一起。

然后,我们将它们格式化成一个输入字典,并将输入 IDs 张量数据类型更改为long,将注意力屏蔽张量数据类型更改为int——这是 BERT 所要求的。

这就是我们准备传递给 BERT 的数据!

做预测

做出我们的预测是容易的部分。我们将我们的input_dict作为一个**kwargs参数传递给我们的model — **kwargs 允许模型将input_idsattention_mask关键字匹配到模型中的变量。

从这里,我们可以看到,我们为每个块获取了一组三个激活值。这些激活值还不是我们的输出概率。为了将这些转换成输出概率,我们必须对输出张量应用 softmax 函数。

最后,我们取每个类(或列)中的值的mean来得到我们最终的正面、负面或中性情感概率。

如果你想提取获胜的类,我们可以添加一个argmax函数:

这就是我们对较长文本的情感预测!

我们选取了一段包含 1000 个标记的长文本,将其分解成块,手动添加特殊标记,并计算所有块的平均情绪。

通常情况下,阅读全文绝对有助于理解所讨论主题的观点。我们已经建立了一种方法来实现这一点,并允许我们解决典型的文本大小限制。

如果你想看完整的代码,你可以在下面的参考资料中找到(有两个笔记本,但是编号为的两个包含了这里使用的确切代码)。

我希望你喜欢这篇文章。如果您有任何问题或建议,请通过 Twitter 或在下面的评论中告诉我!如果你对更多类似的内容感兴趣,我也会在 YouTube 上发布。

感谢阅读!

参考

[1] D. Araci, FinBERT:使用预先训练的语言模型进行金融情绪分析 (2019)

Jupyter 笔记本 1

朱庇特笔记本 2

🤖带变压器的 NLP 课程

如果你想了解更多关于使用变形金刚进行情感分析的知识(这次是使用 TensorFlow),请点击这里查看我关于语言分类的文章:

https://betterprogramming.pub/build-a-natural-language-classifier-with-bert-and-tensorflow-4770d4442d41

如何应用您辛苦获得的数据科学技能

原文:https://towardsdatascience.com/how-to-apply-your-hard-earned-data-science-skillset-812585e3cc06?source=collection_archive---------24-----------------------

从学习到应用的跨越可能是艰难的。为了平稳过渡,需要注意以下几点。

不要把所有的时间都花在教室里

当心书呆子

你不应该惊讶于我——像许多数据科学家一样——有点像书呆子。我喜欢阅读,尝试学习新技能。当你听到一个声音时,会有一种特殊的感觉,它会让你以一种完全不同的方式思考一些事情。

然而,这些年来有一件事一直困扰着我,那就是阅读如何做某事和实际去做之间的差距。无论是烹饪、运动、绘画,还是其他什么——你只是不能像通过实践那样快速地通过阅读来学习。

更糟糕的是,在某些情况下,如果你不应用你学到的知识,书本知识实际上对你的进步是有害的,会减慢你的速度。

我认为这尤其适用于数据科学——无论是书籍还是当今的许多课程。

现在,不要误解我——我坚信阅读会对你的能力和整体技能产生积极的影响。当你应用它们的时候,有些东西会感觉非常不同。

我也非常喜欢跑步课程。我理解机器学习和数据科学的第一步是在 Coursera 上学习吴恩达的原版机器学习。

书籍和课程都服务于一个目的,可以提供数据科学的坚实基础。但是,如果你过于依赖它们,而没有应用这些知识,你很快就会意识到许多现实世界的问题并不那么清晰。

有时候,甚至决定是否使用机器学习都很困难。

从学习到利用

那么,你如何利用这些技能并获得学术和实践经验的最佳组合呢?

数据科学仍然是一个年轻的领域,并且仍在快速变化。构成数据科学技能组合的许多基础组件本身就是广阔的研究领域。要在这些领域取得进步,需要专业知识的传授和丰富的经验。

许多推进机器学习或统计领域的纯理论学者可能永远不会触及真正的商业问题。

所以不要陷入永远学习最新的算法和方法。或者花太多时间试图掌握学术问题。尽你所能从这些不可思议的人和他们提供的学习资源中获取一切——然后卷起袖子,着手解决一些真正的问题。

以下是一些简单实用的走出教室走进办公室的第一步指南:

  1. 尽可能使用最简单的解决方案。这可能很难量化,但至少要在心理上给你的价值函数增加一个惩罚项,惩罚你更复杂的解决方案。如果您可以使用标准的、开源的、易于理解的库来解决您的特定问题,那么就这样做吧。您很快就会发现,定制解决方案带来的维护、调试、支持和集成方面的额外麻烦实际上会让您付出更高的长期成本。
  2. 发现其他人如何将你所学的技术应用到现实世界的问题中。了解 XGBoost 并为金融服务机构工作?在网上搜索,查看像 Medium 或 Kaggle 这样的社区,看看它是如何应用的,以及任何隐藏的困难,这些困难在你开始使用的简单笔记本例子中并不明显。
  3. 更担心数据而不是模型。我明白,测试模型和调整超参数很有趣。更糟糕的是,这里或那里勉强增长 0.5%实际上会给人一种进步的错觉。最大的飞跃总是来自于提高数据质量、设计新的特性或对数据采取不同的观点。
  4. 掌握您选择的数据操作工具。这与上面的观点密切相关。许多项目需要大量的数据操作和一点点模型调整。如果你用熊猫之类的东西,你对应用方法感到舒服吗?多级指数呢?了解这些特性会让你的生活轻松很多。你永远不会知道太多的 SQL。
  5. 学习如何解释、比较和交流模型输出。什么时候考虑准确性?精度?回忆?ROC AUC 告诉你什么?学习如何解释你的模型。模型的可解释性可以毁掉或挽救一个项目。
  6. 在你喜欢的领域中寻找怪异和奇妙的数据集。这一点非常重要——你需要有兴趣和动力去完成事情。用示例和演示数据集来构建东西很好,但它们不会让你脱颖而出,而且潜在的招聘经理更有可能在过去见过类似的数据集解决方案。一些你感兴趣的稀有的小众的东西?它对你来说更有意思,也更容易被看到它的人所注意。这还将教会你如何将问题框定在你理解的背景下,并传达你的发现——这是每个数据科学家的基本技能。

结论

理论很棒。事实上这是必不可少的。

但是不要让它完全支配你的学习。花些时间寻找应用这些知识的机会,测试边界,看看它属于示例问题之外的哪一部分,并整理演示数据集。如果你找到了平衡,你会发现学习变得更容易。当你学习新的东西时,你会有越来越多的背景可以利用——你会问更深层次的问题,并在这个过程中形成更强的理解。

如何问一个关于堆栈溢出的好问题

原文:https://towardsdatascience.com/how-to-ask-a-great-question-on-stack-overflow-965d9cd8846d?source=collection_archive---------28-----------------------

发布精彩问题并获得更好答案的 5 个策略

张家瑜在 Unsplash 上拍照

如果你是搞技术的,你知道什么是栈溢出。更有可能的是,你可能对这项服务又爱又恨——虽然非常有用,但用户可能会对他们认为不“有价值”的帖子相当抵触,询问之前回答过的问题,或者只是使用感谢这个词。尽管如此,找到正确的 SO post 比仅仅为了记住是否应该使用concat()merge()而翻阅文档要快得多。

那么该怎么办呢?勇敢面对堆栈溢出,毒性和所有的世界,还是表明立场,尝试没有它的生活?对于许多程序员和数据科学家来说,这并不是一个真正的选择。我们需要堆栈溢出。尽管要让一个人的帖子被阅读/不被否决是有障碍的,但还是有一些指导方针可以让你遵循,以增加被好评的几率。

如果你真的从一个普通读者变成了专栏作家,那么这篇文章就是一个规则,可以减少否决的可能性,增加你的文章被回复的机会。所以,事不宜迟…

GIF 来自 GIPHY

1.做你的研究(即不要重复)

Stack Overflow 的创始人杰夫·阿特伍德(Jeff Atwood)说,有三种类型的重复问题:1)剪切粘贴重复,2)偶然重复,3)边界重复。虽然最后一个是最不可能让你的帖子被标记和删除的(即,基于微小的变化,它处于重复的边缘),但最好做彻底的研究,看看你的问题是否已经得到了回答。

Stack Overflow 对于任何特定的问题、bug 或安装问题都有一个漂亮的、回答良好的帖子是非常特别的。如果你的问题可以在另一篇文章中找到答案,那么它可能不会持续太久。也就是说,如果你有一个独特的问题,就问吧!

要点:尽你所能找出答案是否已经存在,如果答案不存在,你可以通过发布这个帖子不仅为你自己,也为更大的社区做出非常有价值的贡献。

2.概括一切

您遇到堆栈溢出的原因很可能是因为您有一个特定的问题需要解决。此外,你寻找的许多帖子之所以如此有价值,恰恰是因为它们被浓缩,并以最简单明了的方式呈现。虽然您可能没有在代码中使用变量applebananaorange,但是您可以很容易地推断出它们是什么,并重新编写这样一个示例来满足您的需求。

写一篇好的 SO 帖子也是如此。从你自己的代码开始,以一种没有完全掌握你的特定项目主题的程序员仍然能够理解的方式简化并重写它(常见的变量名有foobarxyzabcapplesbananas等)。此外,通过去除与您遇到的特定 bug 无关的任何无关组件来隔离问题。通过这样做,你增加了你的问题给 SO 用户带来的净收益,并让那些可能真正回答这个问题的用户产生更多的好感。

要点 : 简化,简化,简化 —爱因斯坦

3.详述你的努力(用代码)

有一件事会让人们很快厌烦,那就是认为你是在让他们为你写代码(更糟糕的是,这是一项家庭作业!😮 ).为了鼓励人们想要帮助解决你的问题,在你的帖子中提供一个工作代码示例是至关重要的。此外,根据问题的不同,您还应该提供当前与预期的输出、错误消息、总结您已经尝试过的内容等。

问一个问题完全没问题,甚至对于一个家庭作业(😅),但是堆栈溢出只是在到达需要帮助的地步之后,帮助你解除的阻塞。就像工作面试或第一次约会一样,一开始就表现出诚意会大大增加对方喜欢你的几率。

要点:栈溢出不属于代码的事情,而是调试一旦你已经把事情弄糟了。当你试图让某人把你的帖子公之于众时,一开始就详述你的努力将会获得巨大的回报。

4.不要开玩笑

你可以说我很守旧,但我喜欢说“谢谢”,这可能超出了我的要求。你刚刚救了我的命?谢谢你。从商店买了些我喜欢的麦片。谢了。分享你的一半 PB&J?我可能会以你的名字命名我的第一个孩子。

GIF 来自 GIPHY

是的,不,堆栈溢出,我不同意这一点。帮助部分特别声明“如果您使用签名、标语、问候、感谢或其他聊天内容,它 将被删除 以减少问题和答案中的噪音。”所以,当你写这篇文章时,不要说你好、谢谢和真诚的话,或者干脆写下来,在发表前删掉。

要点:尽管我作为一个中西部人有着所有的本能,但是不要考虑细节,尽量让你的问题简单明了。它读起来会像咸饼干吗?也许吧。但是你会避免被否决吗?没错。

5.正确推销你的问题

就像给 TDS 文章加标签是一门艺术一样,写一个简洁的 so 标题并添加正确的标签也是一门艺术。这可能是一件棘手的事情;完整的标注指南可以在这里找到,这里是关于如何制定好标题的讨论。

每个问题最多可以有五个标签,每个标签应该相对具体。一些好的标签可以是关于你使用的语言(c#csshtmljavascriptpythonr)、技术(support-vector-machinesneural-networkslatent-dirichlet-allocationdecision-trees),或者特定的功能或包(hoverimagesearchdecouplingdplyr)。至于标题,最好是简洁而有描述性的。

要点:一个 clickbaity 标题可能在 Youtube 上工作,但对于堆栈溢出来说,情况正好相反。此外,标记是在每小时数百个新问题中脱颖而出的重要一步。

结论

堆栈溢出可能是一种启发性的、有害的、有益的、对抗性的、慷慨的、势利的媒介,这种媒介肯定会一直存在。有了这些建议,我希望你在面对我们所选择的职业的不可避免的障碍时,加入 SO 社区并提出你自己的问题会感觉更舒服。一路平安,编码愉快!

参考

  • 乔纳森·克罗普科教授在弗吉尼亚大学的课程。我最初是在去年上 SO 的课程时了解他的来龙去脉的,然后今年作为该课程的评分员再次重温了这些想法。他在这里有一本很棒的免费电子书(其中第一章讨论了毒性):https://JK ropko . github . io/surfing-the-data-pipeline/ch1 . html # how-to-avoid-toxicity-in-online-communities。也就是说,如果你想读 DS 的 MS,弗吉尼亚大学有一个很好的选择。
  • https://meta . stack exchange . com/questions/342779/what-about-the-community-is toxic-to-new-users
  • https://meta . stack exchange . com/questions/2950/should-hi-thanks-tagline-and-salutations-be-remove-from-posts
  • https://meta . stack overflow . com/questions/260776/should-I-remove-fluff-when-editing-questions
  • https://sostats.github.io/

评估人工智能对碳排放的影响以及可能的缓解措施

原文:https://towardsdatascience.com/how-to-assess-the-impact-of-ai-on-carbon-emissions-and-possible-mitigations-for-sartups-7e31bcd12a09?source=collection_archive---------37-----------------------

我们有 20 年的时间(到 2026 年)来减少碳排放,否则气候变化将变得不可逆转。-汉斯·约阿希姆·舍恩胡伯

Bermix 工作室在 Unsplash 拍摄的照片

人类面临的最大威胁之一是气候变化,而人工智能在其中扮演着重要的角色。近年来,人工智能已经成为特定伦理问题的焦点,这导致许多人提出疑问。这些问题围绕着人工智能技术如何帮助碳足迹问题,碳足迹通常被其准确性因素所掩盖,这也是开发人工智能的主要原因。

这个关心的问题在模型部署阶段变得更成问题,其中深度神经网络需要部署在各种硬件平台上,每个平台具有不同的属性和计算资源和位置。

机器学习框架通过全天候运行数百万个大规模统计数据集(实验)来建立他们的技能,在这些可能持续数周甚至数月的训练期间不断完善他们的模型,同时也越来越消耗能量。

一旦模型经过训练,其他碳排放因素就会实时出现,如部署、计算资产和位置。这些碳排放占项目[1]总碳排放量的 70%到 80%。

前一年进行的一项研究显示,训练一个现成的人工智能语言处理系统会产生一千四百磅的碳排放。而从零开始训练一个人工智能语言系统甚至可以创造高达 78,000 英镑的收入【2】。这是普通人一生呼出气体的两倍。

欧文·比尔德在 Unsplash 上的照片

鉴于当今的现代人工智能,模型消耗大量的能源,对这些的需求一直在急剧上升。生产顶级人工智能模型的资源消耗每 3、4 个月就会翻一番。

最近,OpenAI 在其博客文章中宣布,已经推出了其最大的人工智能语言模型——GPT-3,该模型在 5000 亿词的数据集上进行粗略训练。相比之下,之前的人工智能模型 GPT-2 是在 400 亿词的数据集上训练的,以获得准确性[3]。在此之前的 2018 年,最好的 NLP 模型 BERT 在 30 亿个单词的数据集上进行训练,BERT 的表现优于 XLNet,XLNet 在 320 亿个单词上进行训练[4]。

随着需要处理数十亿和数十亿单词的数据集以及冗长的训练课程,对人工智能模型中更高准确性的研究将继续呈指数级增长,这导致需要更多的能源消耗和大量的碳排放。

我们在上半年经历的是人工智能变坏的一个方面。它还有另一个方面,这个因素不仅拯救了环境,同时还促进了国家的经济发展,并在治理和逻辑方面提供了更多的透明度。

佩皮·斯托扬诺夫斯基在 Unsplash 拍摄的照片

根据普华永道的研究,很明显,人工智能在环境方面的应用有可能将一个国家的 GDP 提高 3.1-4.4%[5]。此外,在大幅提高 GDP 的同时,如果一切照常,到 2030 年,它可以将全球温室气体排放量减少约 1.5-4.0%[5]。经济增长主要出现在欧洲、东亚和北美,因为它们都实现了 GDP 增长,估计约为 1 万亿美元[6]。

如果对能源部门进行评估,人工智能应用可以节省 2.2%的温室气体排放总量。如果对运输进行同样的评估,它将在 1.7%左右[7,8]。尽管如此,还需要更多地关注水和农业,因为从更广泛的意义上来说,它们在环境中发挥着重要作用。我们必须在更普遍的意义上学习,任何单一的预测都不仅仅依赖于人工智能技术。尽管如此,随着人工智能的使用,周围的技术组件和基础设施的采用也促进了人工智能。

更广泛意义上的“”运动正在兴起,以应对医疗保健、教育等世界挑战。在可持续发展的保护伞下利用人工智能的力量。许多公司主动加入这一新浪潮,并承诺支持解决环境问题,其结果是微软推出的人工智能地球计划。随着新技术浪潮的到来,在人工智能的帮助下识别和解决环境问题成为一项挑战。

正如我们所看到的,人工智能正在极大地增强其他行业减少碳足迹的能力。我们也看到了人工智能本身是如何对相当数量的全球二氧化碳总量负责的。事实上,随着时间的推移,我们必须权衡它给我们带来的好处,以及同一个系统对我们环境造成的损害。

照片由 Unsplash 上的 h heyerlein 拍摄

缓解人工智能模型训练时提出的问题可以尝试的几件事是,将训练课程转移到云,云托管在可再生资源消耗更大的位置附近。作为它的云,应该很容易在一个地方存储数据集,同时,从不同的位置消费它们。

解决这个问题的另一种方法是它制造高效的人工智能算法,斯坦福大学小组进行的研究是评估同一任务的不同算法。有趣的是,结果显示,调整算法和未调整算法的耗电量相差近 880 千瓦时,这是典型美国家庭一个月的典型耗电量[9]。如果我们编写更好的代码或更好的模型,我们就可以对减少应用程序的碳足迹产生巨大的影响。一个更简单的方法是,我们可以根据默认配置评估程序,一旦我们确定了某个模型,我们就可以对它进行微调。

我们知道,不仅机器学习模型的训练需要很高的能量,消耗这样一个 AI 系统消耗的能量远远超过训练。不仅需要算法方面的发展,还需要建立在可持续能源基础上的基础设施,以促进如此巨大的人工智能依赖应用。

随着时间的推移,了解基础设施将如何发展以减轻人工智能在日常生活中的发展和使用将是有益的。

参考资料:

[1]https://analyticsindiamag . com/how-having-bigger-ai-models-can-have-a-disaster-impact-on-environment/
【2】https://hai . Stanford . edu/blog/ais-carbon-footprint-problem #:~:text = The % 20 full % 20 suite % 20 of % 20 experiments,呼气% 20 over % 20 an % 20 all % 20 lifetime。
【3】https://towardsdatascience . com/open ai-GPT-2-理解-语言-生成-通过可视化-8252f683b2f8?gi = bb 0504 f 0969 c
【4】https://dl.acm.org/doi/fullHtml/10.1145/3381831
【5】https://3er viui 9 wo 30 pkxh 1 v2 NH 4 w-WP engine . net DNA-SSL . com/WP-content/uploads/prod/sites/53/2019/04/PwC-Executive-summary . pdf
【6】https://www . world bank . org/https

如何为四种不同的云 Kubernetes 服务分配计算资源:AKS、EKS、GKE 和 Minikube

原文:https://towardsdatascience.com/how-to-assign-computing-resources-for-four-different-cloud-kubernetes-services-aks-eks-gke-and-b3f4deb722bc?source=collection_archive---------27-----------------------

Kubernetes 架构不需要公开来分配云计算硬件。

计算商品云。马西莫·博图里在 Unsplash 上拍摄的照片

介绍

在本文中,我将向您展示如何为四种不同的云类型指定 Kubernetes 节点的计算资源:

  1. Minikube ,一种在本地工作站(沙盒)上训练或测试 Kubernetes 的流行方法;
  2. 用于亚马逊网络服务(AWS)云的弹性 Kubernetes 服务(EKS);
  3. 面向微软 Azure 云的 Azure Kubernetes 服务(AKS);
  4. 用于谷歌云平台(GCP)云的谷歌 Kubernetes 引擎(GKE)。

我们从云、Kubernetes、节点、节点池、集群和虚拟机的工作定义开始。

什么是云?

云是无数的异构硬件,每个都有自己的操作系统,托管您的应用程序,您希望复制这些应用程序(扩展)并在服务失败时重新启动(容错)。

:我用“应用”作为一个微服务、服务、应用、包、网络资源、存储服务的通称,或者 应用即服务(AaaS= = Saas)。

云供应商意识到,计算引擎是作为通用资源指定的通用计算类型提供的商品。

云供应商联合起来…

  • 网络计算引擎商品
  • 应用程序

…让您能够为不同类型的应用租赁不同类型的计算引擎。

:云厂商凭借开源许可、无价格许可、高带宽成为可行。想象一下管理许可费用的成本与云供应商对开源软件的维护成本的对比。

什么是 Kubernetes?

假设有一个应用程序,您希望跨计算引擎复制(扩展)该应用程序,如果某个应用程序的计算引擎出现故障(容错),则将该应用程序移动到另一个计算引擎。

因为需要可扩展、容错的分布式操作服务,谷歌在 2015 年开源了 Kubernetes。

Kubernetes 是独立于云的,因为:

  1. 将物理机引擎转变为虚拟机。然后将虚拟机映射到 Kubernetes 节点抽象
  2. 通过将应用程序放入容器,将应用程序转换为虚拟应用程序。然后将一个或多个容器映射到 Kubernetes pods 抽象

Kubernetes 协调 pod,在节点上启动和初始化pod,如果它们变得不可达(容错),则在不同的节点上重新启动pod,复制(扩展)pod,以及 pod 上的其他分布式操作系统协调操作。

我在这篇博客文章中详细介绍了云计算硬件如何映射到 Kubernetes 节点。云供应商的文档中指定了计算资源的供应。

您无法在 Kubernetes 文档中找到如何配置计算资源的方法,也不应该这样做。

什么是 Kubernetes 节点和节点池?

Kubernetes 的一个重要概念是独立于计算硬件的类型。Kubernetes 将计算引擎(硬件和操作)规范抽象为一个节点

一个节点是主要云供应商的一组有限的虚拟机(VM)产品。每种供应类型指定计算资源和每单位时间租赁计算资源的价格。

虚拟机类型描述了 CPU、GPU 和 xPU 的混合;记忆的数量和类型(快速记忆);磁盘的数量和类型(慢速内存);以及免费的 Linux 变种操作系统(OS)。

每个云供应商还允许你用你想放入或替换的其他计算资源来构建定制的 VM 类型。

:云厂商提供 MS Windows NT 等其他 OS 变种。在许可证供应商的许可下,您还可以将许可证移动到云虚拟机。

您将一个 VM 类型分配给 Kubernetes 外部的一个节点。因此,Kubernetes 配置是独立于云的,因为它只知道哪些节点被分配给了集群,并且独立于该节点的实际虚拟机类型。

:异构计算引擎造成的限制只允许将同构节点(相同 VM 类型)的节点池添加到 Kubernetes 集群。Kubernetes 编排服务(如故障转移和复制)使用不同虚拟机的节点池是一个尚未解决的问题。

从现在开始,我使用更多的术语虚拟机(VM)来指代计算引擎。

:如果你熟悉 DAG(有向无环图),那么一条直线型 DAG 将云虚拟机连接到节点到节点池再到集群。

什么是 Kubernetes 集群?

Kubernetes 是一个用于通过网络连接的节点(VM)的分布式操作系统。一个特定的节点网络(节点池)是一个 Kubernetes 集群

一个或多个节点池被分配给 Kubernetes 集群(节点)。节点池或节点被分配给一个群集,不能分配给两个或多个群集。

Kubernetes 通常在一个集群中编排几个节点(节点池)。

Kubernetes 可以命名和管理许多集群。

:一个集群可以驻留在多个云上,称为多云或混合云。我不会在这篇博客文章中进一步讨论 hybris 云,因为这超出了我们的主要讨论点。

图一。物理硬件被描述为云中的虚拟机(VM)。每个虚拟机都映射到一个节点。相同虚拟机类型的节点被分组到一个节点池中。一个或多个节点池被分配给一个群集。群集不能共享池,节点池也不能共享节点。结果是虚拟机被分配到一个集群。在此图中,我们看到 16 台虚拟机分配给节点池 0,两台不同类型的虚拟机分配给节点池 1,一台虚拟机分配给节点池 2。图片作者。

云计算硬件映射到 Kubernetes 节点组。一个节点组被分配给一个 Kubernetes 集群。

现在,我们研究四种不同的云文档,以确定虚拟机如何映射到节点组。

响亮的类型 1: Minikube

Minikube 就是你如何在本地计算机上运行外观和感觉都很像的 Kubernetes。

我认为 Minikube 是我安装在本地机器上的一个程序,用于培训或测试 Kubernetes。

因为它位于一个本地工作站上,所以 Minkube 实例代表工作站上的一个集群。

在将 Kubernetes 配置推送到云之前,我们在本地沙箱(工作站)上使用 Minikube。

和 Kubernetes 一样,Minikube 使用客户端命令行工具kubectl。但是,Minikube 还需要一个名为。minikube.

Minikube 配置文件

Kubernetes 拥有被命名为集群的上下文。通过使用上下文名,kubectl指向哪个 Kubernetes 集群就对哪个集群进行操作。

Minikube 概要文件是 Minikube 实例的名称,它是本地机器上的一个集群。另一种不同但等效的说法是:“每个新集群都需要一个新的 Minikube 实例。”

如果 Minicube 配置文件kubectl 上下文同名(字符串),则kubectl在 Minikube 实例(当前配置文件)(集群)上运行。

关于 Mimikube 上下文和kubectl简介的更详细讨论:

https://itnext.io/understanding-the-connection-between-minicubes-profile-and-kubectl-s-context-f9a30f89bc62

用于指定本地虚拟机的 Minikube 启动选项。

您可以在本地工作站上使用以下命令启动一个 Minkube 虚拟机(VM)实例:

minikube start -p <profile-name> [options]

您的虚拟机默认使用下面列出的[options]:

minikube start -h

Minikube 实例的一些有用选项:

Options:--cpus=2: Number of local workstation CPUs allocated to Minikube VM instance.--disk-size='20000mb': The local workstation disk size allocated to the minikube VM (format: <number>[<unit>], where unit = b, k, m or g).--memory='': Amount of local workstation RAM to allocate to Kubernetes (format: <number>[<unit>], where unit = b, k, m or g).-n, --nodes=1: The number of nodes to spin up in the Kubernetes cluster. Defaults to 1.

例如:

start -p sanbox -cpus=10 -nodes=5. [log]
. [messages]
. [from starting profile(cluster) sandbox]minikube dashboard &  #startup kubernetes dashboard

图二。Kubernetes 仪表板显示 Minikube 配置文件(集群)sanbox 的 5 个节点。图片:作者工作站的桌面截图。

图 3。节点 sanbox-m05 元数据。图片:作者工作站的桌面截图。

图 3(续)).节点 sanbox-m05 元数据。图片:作者工作站的桌面截图。

图 3(续)).节点 sanbox-m05 元数据。图片:作者工作站的桌面截图。

我们看到,以下三家云供应商与 Minikube 在 Kubernetes 节点的虚拟机预约方面形成鲜明对比。

在 Minikube 中,Kubernetes 集群由一个虚拟机组成。云由一个或多个虚拟机组成。

每个 Minkube 实例都是一个 Kubernetes 集群,驻留在从您的工作站的计算资源创建的 VM 中。Minkube 实例节点是同构的,并对单个虚拟机进行分区。

相比之下,云定义节点池。Kubernetes 集群由节点池组成,其中每个节点池都是一种特定的虚拟机类型。

云类型 2:亚马逊 EKS 节点、节点组和集群

亚马逊为 EC2 提供的 Kubernetes 服务叫做弹性 Kubernetes 服务(EKS )。

EKS 支持 Kubernetes API。eksctl是用于在 EKS 上创建和管理集群的命令行界面(CLI)工具。

如果您熟悉 Kubernetes kuberctl命令行界面(CLI ),则 EKS 的等效界面称为。eksctl

分配虚拟机(VM)

有多种方法和选项可以将虚拟机分配给弹性 Kubernetes 服务(EKS)集群。

首先,创建一个名为*<my-cluster>*的 Kubernetes 集群:

# Example
eksctl create cluster \
 --name *<*zetaC*luster>* \ 
 --without-nodegroup

我们手动分配节点组、节点和虚拟机类型给

  1. 创建一个节点组名*<my-ng>;*
  2. 把它分配给库伯内特集群*<zetaCluster>;*
  3. 在区域
  4. 节点(虚拟机)类型的*<VM-type>;*
  5. 起始节点计数为*<<number-in-node-group>>;*
  6. 最小节点数为*<minimum-number-in-node-group>;*
  7. 最大节点数为*<maximum-number-in-node-group>;*
eksctl create nodegroup \
   --cluster <zetaC*luster>* \
   --region *<region>* \
   --name *<nogroup-name>* \
   --node-type *<VM-type>* \
   --nodes *<number-in-node-group>* \
   --nodes-min *<minimum-number-in-node-group>* \
   --nodes-max *<maximum-number-in-node-group>*

:节点池在 EKS 称为节点组。

:我并没有定义我使用的每一个云概念——比如,区域这个术语。

您不能在 EKS 集群中添加或删除节点;您可以在 EKS 集群中添加或删除节点组。

AWS 提供的 VM 类型(Amazon EC2 实例类型)。

云类型 3: Azure AKS 节点,ResourseGroup。和集群

在 Azure Kubernetes 服务(AKS)中,相同配置的节点被分组到节点池中。这些节点池包含运行应用程序的底层虚拟机。

您可以向节点池中添加节点。遵循独立于云的 Kubernetes 计算资源抽象规则,您可以向 AKS 集群添加一个或多个节点池。

如果您熟悉 Kubernetes kuberctl命令行界面(CLI ),那么 EKS 的对应界面叫做az,用于在 AKS 上创建和管理集群的 CLI。

在 Azure 中,首先,创建一个名为的资源组

az group create — name <nameResourceGroupVM> — location <region>#### Exampleaz group create — name zetaResourceGroupVM — location westeurope

为什么需要创建 AKS 资源组?(可选阅读)

只有 AKS 的 Kubernetes 实现有资源组。AKS ResourceGroups 的目的似乎是指定从哪个 Azure 区域分配虚拟机,以及从哪个区域启动集群。

实质上,AKS 区域是在资源组中指定的,而不是在集群中。您可以通过引用不同的资源组来加速另一个 AKS 区域中的集群。

每个集群创建了两个资源组。一个名为,是显式的,伞对象实例链接该集群的所有内部 AKS 系统资源。

: IMHO,ResorceGroups 可能是为了对 Kubernetes 内部系统虚拟机收费而引入的。可以想象 Kubernetes 群体如此之大,以至于消耗了大量的计算资源。我知道云供应商通过合同谈判管理大型 Kubernetes 群,而不使用名称。微软可能也会这么做。我不知道他们有没有。

第二个 ResourceGroup 实例是未命名的,在创建集群时自动创建。伞状对象实例链接您可能分配给 AKS 集群的所有节点池。

# Create a resource group named sandboxResourceGroup
# in region(az group): East US
create --name sandboxResourceGroup --location eastus

创建一个 AKS 集群。

接下来,您需要创建一个名为sandboxCluster的 AKS 集群:

# Create a basic single-node AKS cluster 
az aks create \
     --resource-group sandboxResourceGroup \
     --name sandboxCluster \
     --node-count 3 \

创建 AKS 集群时,创建了一个默认的节点池 1 ,节点计数为 3。

az aks nodepool list --resource-group sandboxResourceGroup \
     --cluster-name sandboxCluster

输出= >

 [
   { ...
     "count": 3,
     ...
     "name": "nodepool1",
     "orchestratorVersion": "1.15.7",
     ...
     "provisioningState": "Succeeded",
     ...
     "vmSize": "Standard_DS2_v2",
     ...
   }
 ]

向群集添加节点池。

我们可以通过以下方式向sandboxClutser添加第二个节点池:

az aks nodepool add \
     --resource-group sandboxResourceGroup \
     --cluster-name myAKSCluster \
     --name sb1nodepool \
     --node-count 7az aks nodepool list --resource-group sandboxResourceGroup \
     --cluster-name sandboxCluster

输出= >

[
   { ...
     "count": 3,
     ...
     "name": "nodepool1",
     "orchestratorVersion": "1.15.7",
     ...
     "provisioningState": "Succeeded",
     ...
     "vmSize": "Standard_DS2_v2",
     ...
   },
   { ...
     "count": 7,
     ...
     "name": "sb1nodepool",
     "orchestratorVersion": "1.15.7",
     ...
     "provisioningState": "Succeeded",
     ...
     "vmSize": "Standard_DS2_v2",
     ...
   } ]

如果在添加节点池时未指定 VmSize,则默认大小为 Windows 节点池的 Standard_D2s_v3 和 Linux 节点池的 Standard_DS2_v2。— 微软 Azure 文档。

所有虚拟机规格和其他选项都交给[ak aks nodepool add](https://docs.microsoft.com/en-us/cli/azure/aks/nodepool?view=azure-cli-latest#az_aks_nodepool_add).

从群集中删除节点池。

如果不再需要某个池,可以将其删除并移除底层虚拟机节点。要删除节点池,使用 az aks 节点池删除命令并指定节点池名称。

az aks nodepool delete -g sandboxResourceGroup /
        --cluster-name sandboxCluster /
       --name nodepool1 --no-wait

输出= >

[
   { ...
     "count": 7,
     ...
     "name": "sb1nodepool",
     "orchestratorVersion": "1.15.7",
     ...
     "provisioningState": "Succeeded",
     ...
     "vmSize": "Standard_DS2_v2",
     ...
   }
]

你可能会发现有用的杂项 Azure 链接。

虚拟机配置中的批处理池支持几乎所有的虚拟机大小。

Azure 支持的 Linux 发行版和版本。

各种虚拟机包及其性能指标评测。

虚拟机设置—哪个虚拟机最适合您在 Azure 中的工作负载?

云类型 4:护目镜 GKE

要使用以下命令签名创建 GKE 集群:

gcloud container clusters create <CLUSTER_NAME> [options]

所有的gcloud ontainer clusters create选项都在这里详细说明。

创建 GKE 节点池。

与其他云类似,Goggle Kubernetes 引擎(GKE)将虚拟机抽象为一个节点。

节点池而不是节点被添加到 GKE 群集中。

要创建节点池,请运行[gcloud container node-pools create](https://cloud.google.com/sdk/gcloud/reference/container/node-pools/create)命令:

gcloud container node-pools create <POOL_NAME> --cluster <CLUSTER_NAME> [options]

使用以下任一选项指定节点池中的虚拟机类型:

来自 GKE 文件:

--machine-type:节点池中实例使用的计算引擎机器类型。如果未指定,默认机器类型为e2-medium。关于指定机器类型的信息,请参考[gcloud container node-pools create --machine-type](https://cloud.google.com/sdk/gcloud/reference/container/node-pools/create#--machine-type)

--num-nodes:指定要在节点池中创建的节点数。默认值为 3。您的项目必须有足够的配额用于节点数。

--disk-size:节点虚拟机引导磁盘的大小,以 GB 为单位。默认为 100GB。

--image-type:用于节点池的图像类型。映像类型指定要在节点池中的节点上运行的基本操作系统。如果未指定,服务器将选择默认图像类型。

其他gcloud container node-pools create选项的在此详述。

你可能会发现有用的杂项 GKE 链接。

其他节点池管理命令。

可用的有效虚拟机类型列表。

摘要

有人提醒我们,Kubernetes 与机器类型(VM)无关,因此也与云类型无关。

Kubernetes 将计算资源抽象为节点,节点映射到云供应商提供的虚拟机。

由于 Kubernetes 编排服务的异构性(如故障转移和复制)造成的限制,云类型实施只允许将同构节点(相同虚拟机类型)的节点池添加到 Kubernetes 集群。

我向您展示了如何针对四种不同的云类型将 VM 映射到 Kubernetes 节点:

  1. Minikube 在本地工作站上使用 Kubernetes 进行培训或测试的流行方法;
  2. 用于亚马逊网络服务(AWS)的弹性 Kubernetes 服务(EKS);
  3. 面向微软 Azure 的 Azure Kubernetes 服务(AKS);
  4. 用于谷歌云平台(GCP)的谷歌 Kubernetes 引擎(GKE)。

未来的博客文章将讨论 Kubernetes 在生产中为您的机器学习管道提供的机会。

编码快乐!

附录 a .定价

所有云供应商都有相同的基本价格模型,这并不奇怪,因为计算资源现在是商品。根据云供应商及其卓越的产品,在基本定价模型中添加了定制附加服务。

下面我展示了 Goggle价格模型的一部分。

您需要为虚拟机实例使用的资源付费。创建虚拟机实例时,您需要为实例选择一种机器类型,并按照虚拟机实例定价页面中的描述进行计费。具体来说,您需要按照基于资源的计费模型中所述,为每个 vCPU 和 GB 内存单独计费。适用折扣,如持续使用折扣和承诺使用折扣。

所有云供应商都提供合同、批量和/或专用计算资源定价。

如何在 Python 中使用 Keys、BasicAuth、OAuth2 进行认证

原文:https://towardsdatascience.com/how-to-authenticate-using-keys-basicauth-oauth2-in-python-94fddec609cc?source=collection_archive---------30-----------------------

在本文中,我们将使用 5 种不同的 API,它们使用不同类型的认证。我们将使用 Python 来消费 API。

照片由弗兰克在 Unsplash 上拍摄

并不是所有的 API 都像 Twilio 一样有完整的文档。本指南将帮助您使用使用 Keys、BasicAuth 或 OAuth2 保护的 API。

我们将使用以下 API

  • 猫的事实
  • 卡特彼勒即服务(CAAS)
  • Twilio API
  • GitHub API
  • Genius API

你可以在这里找到源代码

目录

  • 不安全的 API
  • 从. env 文件中读取值
  • 带键的 API
  • 具有基本身份验证的 API
  • API 包装
  • 会话对象
  • 通过 OAuth2 保护的 API
  • 使用 GitHub API (OAuth2)
  • 使用 Genius API (OAuth2)

希望对请求库有所了解。如果需要复习,可以参考我之前的文章。

不安全的 API

卡特彼勒事实 API 不需要任何认证,使用起来相当简单。让我们向以下端点发出请求

[https://cat-fact.herokuapp.com/facts](https://cat-fact.herokuapp.com/facts)

上面的 API 返回随机的 Cat 事实

import requests
api_endpoint = "https://cat-fact.herokuapp.com/facts"
response = requests.get(
    api_endpoint
)
for idx, item in enumerate(response.json()):
    print(f"{idx+1}. {item['text']}")

阅读来自。环境文件

在进入下一节之前,让我们看看如何从. env 文件中读取变量。强烈建议将您的凭据存储在. env 文件中,以避免向他人公开。

我们将需要安装 python-dotenv 库。

pip install python-dotenv

假设有一个带有随机 API 标记的. env 文件

API_TOKEN = "SOME API TOKEN"

让我们试着用 Python 读取 API 令牌。

from dotenv import load_dotenv
import os load_dotenv()
API_TOKEN = os.environ.get("API_TOKEN")

get 函数接受存储在。env 文件作为参数。

带键的 API

这是使用 API 时最常见的身份验证形式。在发出请求时,API 密钥/令牌作为标头传入。我们将使用卡特彼勒即服务(CAAS) API。你可以在这里得到一把钥匙

from dotenv import load_dotenv
import os 
import requestsapi_endpoint = "https://api.thecatapi.com/v1/breeds"load_dotenv()
CAT_API_KEY = os.environ.get("CAT_API_KEY")headers = {
    "x-api-key" : CAT_API_KEY
}
response = requests.get(
    api_endpoint,
    headers = headers
)for idx, item in enumerate(response.json()):
    print(f"{idx+1}. {item['name']} : {item['description']}")

我们创建了一个名为的字典来存储 API 密匙。字典中的键是“x-api-key”。但是,这可能会因您使用的 API 而异。有些 API 要求将密钥命名为“授权”、“授权”、“令牌”。最好参考 API 文档的认证部分。

载体认证非常常见,它要求单词“载体”(注意空格)出现在 API 令牌/密钥的开头。

headers = {
    "authorization": f"Bearer {access_token}"
}

我们将在后面的示例中使用载体认证。

具有基本身份验证的 API

使用基本身份验证保护的 API 需要用户名和密码。通常,用户名是客户端 ID,密码是 API 的客户端机密。在某些情况下,用户名可以留空。这应该在 API 文档中提及。

使用基本认证来保护 Twilio API 。你可以在 Twilio 网站上注册并获得 API 证书。

from requests.auth import HTTPBasicAuth
from dotenv import load_dotenv
import os 
import requestsload_dotenv()
TWILIO_ACCOUNT_SID = os.environ.get("TWILIO_ACCOUNT_SID")
TWILIO_ACCOUNT_TOKEN = os.environ.get("TWILIO_ACCOUNT_TOKEN")api_endpoint = f'https://api.twilio.com/2010-04-01/Accounts/{TWILIO_ACCOUNT_SID}/Calls.json?PageSize=5'auth = HTTPBasicAuth(TWILIO_ACCOUNT_SID, TWILIO_ACCOUNT_TOKEN)response = requests.get(api_endpoint , auth = auth)for idx, item in enumerate(response.json()['calls']):
    print(f"{idx+1}. {item['duration']}")

我们创建了一个 HTTPBasicAuth 的实例。它分别接受用户名和密码作为参数。发出请求时,此实例作为参数传递。对于 twilio,用户名是您的帐户 sid,密码是您的帐户令牌。如前所述,对于不同的 API,它可以是不同的。如果您使用的 API 使用基本身份验证来保护其端点,请参考文档以获取用户名和密码。

API 包装

关于 Python,API 包装器本质上是可以使用 pip 安装的库/包。这些库有助于以语法上更简洁的方式与 API 进行通信。在幕后,库仍然利用请求和头来发出请求。然而,包装器让你的代码看起来更干净。

我们之前讨论的 Twilio API 有一个包装器。它可以使用 pip 安装

pip install twilio

让我们试着做和上一节中对 Twilio 做的一样的事情

from twilio.rest import Client
from dotenv import load_dotenv
import os load_dotenv()
TWILIO_ACCOUNT_SID = os.environ.get("TWILIO_ACCOUNT_SID")
TWILIO_ACCOUNT_TOKEN = os.environ.get("TWILIO_ACCOUNT_TOKEN")
client = Client(TWILIO_ACCOUNT_SID , TWILIO_ACCOUNT_TOKEN)calls = client.calls.list(limit=5)for idx, record in enumerate(calls):
    print(f"{idx}. {record.duration}")

正如您所看到的,代码缩短了几行,看起来更加整洁。

API 与包装器的比较

不幸的是,不是所有的 API 都有包装器。然而,他们中的许多人确实如此。在消费者直接使用 API 之前,尝试寻找一个包装器。这将大大简化 API 的使用。

会话对象

您可以创建一个会话对象,而不是每次向安全的 API 端点发出请求时都传递 API 键或 HTTPBasicAuth 实例。您只需认证一次,就可以发出请求,而不需要传递密钥或 auth 实例。

我们将使用 GitHub API,它是使用 BasicAuth 保护的。用户名将是您的 GitHub 用户名,密码是您的个人访问令牌。按照这个教程就可以得到一个。

from requests.auth import HTTPBasicAuth
from dotenv import load_dotenv
import os 
import requestsload_dotenv()
GITHUB_API_TOKEN = os.environ.get("GITHUB_API_TOKEN")base_api_endpoint = "https://api.github.com/user"auth = HTTPBasicAuth("rahulbanerjee26", GITHUB_API_TOKEN)session = requests.Session()
session.auth = authresponse = session.get(base_api_endpoint + '/repos')for idx, item in enumerate(response.json()):
    print(f"{idx+1}. {item['name']}")response = session.get(base_api_endpoint + '/emails')
for idx, item in enumerate(response.json()):
    print(f"{idx+1}. {item['email']}")

在我将会话的 auth 值设置为 HTTPBasicAuth 实例之后,我可以简单地发出请求,而不用每次都通过身份验证。我们的请求仍然在被认证,但是会话对象会处理它。

通过 OAuth2 保护的 API

当你需要一个“使用谷歌注册”、“使用脸书注册”选项时,使用 OAuth2 web flow 进行认证通常在 Flask/Django 应用中使用。然而,一些 API 需要 OAuth2 用于它们的所有端点。GitHub API 也支持 OAuth2 认证。我们还将讨论天才 API 。尽管它支持基于密钥的身份验证,但其端点需要 OAuth2,通过在 headers 对象中传递密钥,可以获得一个令牌并对自己进行身份验证。但是,我们将使用 OAuth2 web 流来验证我们自己。

关于 OAuth2 是如何工作的,我不会说得太详细,因为这超出了本文的范围。下面是一个高层次的概述。如果没有意义,跳到 Github 或 Genius API 部分,它应该更有意义。

  • 我们必须在 API 的网站上创建一个客户端应用程序
  • 客户端应用程序将有一个客户端 ID 和客户端密码
  • 我们必须向 API 的认证端点发出请求。客户端 ID 和客户端密码将作为查询参数传递。
  • 身份验证端点将请求许可,并且必须被授权

谷歌认证截图

  • 一旦授权,它将返回一个代码
  • 该代码必须被提供给另一个端点,该端点将其交换为接入令牌。
  • 这个访问令牌现在可以用作密钥,并在向端点发出请求时作为 header 对象传递。

让我们来看几个例子。

使用 GitHub API (OAuth2)

如上所述,OAuth2 主要用于 Flask/Django 应用程序。使用 OAuth2 时,您将需要一个 web 应用程序 URL 和一个 URL,以便在用户授权/授予权限后将用户重定向到该 URL。由于我们没有网络应用程序,我们没有任何网址。但是,我们可以使用 HTTPBin 。每当我们需要一个 URL 时,我们可以使用下面的 URL

[https://httpbin.org/anything](https://httpbin.org/anything)

首先,你必须创建一个 GitHub 应用。当询问 web 应用程序 URL 或重定向 URL 时,使用上面讨论的 URL。创建应用程序后,将客户端 ID 和客户端密码存储在。环境文件。

import requests
import os
from dotenv import load_dotenv
from urllib.parse import urlencode
import webbrowserload_dotenv()
CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID")
CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET")
REDIRECT_URI = "https://httpbin.org/anything"params = {
    "client_id": CLIENT_ID,
    "redirect_uri": REDIRECT_URI,
    "scope": "user"
}endpoint = "https://github.com/login/oauth/authorize"
endpoint = endpoint + '?' + urlencode(params)
webbrowser.open(endpoint)code = input("Enter the Code: ")

前几行是导入库并从。环境文件。参数字典包含客户机 ID、重定向 URL(我们前面讨论过的 HTTPBin URL)和作用域。范围的值决定了可以访问的端点和可以执行的 HTTP 谓词操作。

我们创建一个 URL 和查询参数,并使用 webbrowser 库在浏览器中打开它。Pythons 脚本等待使用输入我们的代码,

GitHub API 认证截图

单击 authorize 后,您应该被重定向到 HTTPBin URL,并且应该显示一个 JSON 对象。查看键“code”的值。这个值将被交换成一个 API 令牌。输入代码。

print("Got Code")params = {
    "client_id": CLIENT_ID,
    "client_secret": CLIENT_SECRET,
    "redirect_uri": REDIRECT_URI,
    "code": code,
}
endpoint = "https://github.com/login/oauth/access_token"
response = requests.post(endpoint, params=params, headers = {"Accept": "application/json"}).json()
access_token = response['access_token']
print("Got Access Token")

一旦我们获得代码,我们向端点发出另一个请求以获得访问令牌。这一次,我们将代码和客户机秘密作为参数传递。在 GitHub 验证了凭证和代码之后,它将返回一个访问令牌。这个访问令牌可以用作 API 密钥。

session = requests.session()
session.headers = {"Authorization": f"token {access_token}"}base_api_endpoint = "https://api.github.com/user"response = session.get(base_api_endpoint)
print(response)response = session.get(base_api_endpoint + '/repos')
print(response)response = session.get(base_api_endpoint + '/emails')
print(response)

使用 Genius API (OAuth2)

让我们看另一个例子。我将跳过导入库和加载凭证的部分。

parameters = {
    'client_id': GENIUS_CLIENT_ID,
    'redirect_uri': 'https://httpbin.org/anything',
    'response_type': 'code',
    'scope': 'me'
}
endpoint = "https://api.genius.com/oauth/authorize"
endpoint = endpoint + '?' + urlencode(parameters)
webbrowser.open(endpoint)
code = input("Enter the Code: ")

“响应类型”对于某些 API 是强制性的,其值应该始终为“代码”

Genius API 认证的屏幕截图

在我们授权之后,我们将看到一个 JSON 对象,类似于我们在使用 GitHub API 时看到的对象。输入代码。

print(code)
parameters = {
    "code": code,
    "client_id": GENIUS_CLIENT_ID,
    "client_secret": GENIUS_CLIENT_SECRET,
    "redirect_uri": 'https://httpbin.org/anything',
    "response_type": "code",
    "grant_type": "authorization_code"
}response = requests.post("https://api.genius.com/oauth/token", params = parameters).json()
print(response)
access_token = response["access_token"]

“grant_type”也是某些 API 所必需的。该值始终为“授权 _ 代码”。在我们的代码被验证之后,我们得到一个访问令牌。这个令牌可以用作 API 密钥。

session = requests.session()
session.headers = {"authorization": f"Bearer {access_token}"}base_api_endpoint = "https://api.genius.com/account"response = session.get(base_api_endpoint)
print(response)

结论

我希望这篇文章能成为使用 Python 中的 API 的好指南。在直接使用 API 之前,总是要寻找一个包装器。你花 5 分钟寻找一个包装可能会节省你几个小时的头痛。

在 LinkedIn 、 Twitter 上与我联系

资源

Github 回购

https://github.com/rahulbanerjee26/python_apis

原载于 2021 年 5 月 24 日 https://www.realpythonproject.com**的

如何用 Pandas ExcelWriter 自动调整 Excel 列的宽度

原文:https://towardsdatascience.com/how-to-auto-adjust-the-width-of-excel-columns-with-pandas-excelwriter-60cee36e175e?source=collection_archive---------3-----------------------

使用 pandas 时动态调整 Excel 列名的宽度。ExcelWriter 和 Python

照片由米卡·鲍梅斯特在 Unsplash 上拍摄

您可能需要处理的最令人沮丧的事情之一是使用 Python 生成 Excel 文件时,该文件包含许多列,由于列的宽度较短,您无法读取这些列。理想情况下,您应该交付可读的电子表格,其中所有的列都经过适当的格式化,以便它们是可读的。

在这篇文章中,我们将探索快速和简单的方法可以用来

  • 动态 根据列名的长度调整所有列宽
  • 通过使用其名称调整特定列
  • 使用特定列的索引调整该列

最后,我们还将讨论如何修复调用set_column方法(AttributeError: 'Worksheet' object has no attribute 'set_column')时可能出现的一个常见问题。

首先,让我们创建一个 pandas 数据框架,它将在我们的示例中引用,以便演示我们打算在本文中讨论的操作。

现在让我们尝试使用ExcelWriter将我们刚刚创建的熊猫数据帧写入到一个csv文件中,如下所示(注意,如果下面的代码片段因ModuleNotFoundError: No module named openpyxl失败,您需要做的就是通过运行pip install openpyxl来安装库):

将熊猫数据框架写入 Excel 电子表格

输出的电子表格应该类似于下图所示。正如您所看到的,名称较长的列被裁剪掉了,整个表格看起来很糟糕。如果您必须处理许多这样的列,问题会更大。

将熊猫数据帧输出到 Excel 电子表格

在接下来的几节中,我们将探索一些可以用来自动调整列宽的方法,以便电子表格中的输出表格更具可读性。

动态调整所有列的宽度

为了根据列的长度自动调整列的宽度,我们只需要遍历列并相应地设置列宽,如下所示:

注意:如果下面的代码片段与下面的 **AttributeError** 不匹配,请阅读文章末尾,看看如何快速解决这个问题。

AttributeError: 'Worksheet' object has no attribute 'set_column'

现在 Excel 电子表格中输出的熊猫数据框架可读性更好,看起来也更好。所有列都调整到相应的宽度,这将使它们适合空间而不会被裁剪。

将熊猫数据帧输出到 Excel 电子表格中,并自动调整列宽

通过使用列名来调整列的宽度

现在,您可能希望只手动调整特定列(或列的子集)的宽度。您可以通过引用列名来做到这一点,如下面的代码片段所示。为了这个例子,让我们假设我们想要将列this_is_a_long_column_name的宽度调整为30:

通过引用特定列的名称来手动调整其宽度

上面代码片段的输出如下所示。正如我们所看到的,列this_is_a_long_column_name的宽度被调整为20,而其余列的宽度被调整为默认值,这使得宽度较长的列(如最后一列)被裁剪。

输出此 _is_a_long_column_name 的列宽已手动调整的电子表格

使用列的索引来调整列的宽度

或者,您可能希望通过直接引用特定列的索引来手动调整该列的宽度。在下面的示例中,我们通过调整最后一列的宽度来演示这一点。

通过引用特定列的索引来手动调整其宽度

同样,我们可以看到,在这种情况下,最后一列已经被调整为width=40,因此它足够宽以适应列名。

输出最后一列具有手动调整列宽的电子表格

如何修复AttributeError: 'Worksheet' object has no attribute 'set_column'

如果上述任何操作失败,并显示以下错误

AttributeError: 'Worksheet' object has no attribute 'set_column'

你需要做的就是安装xlswriter

pip install xlsxwriter

结论

在这篇文章中,我们探讨了在将 pandas 数据框架写入 Excel 电子表格时自动调整列宽的几种可能方法。我们通常会创建电子表格,这样我们就可以生成看起来漂亮、易读的信息。因此,创建不需要读者手动操作的电子表格以使它们可读是很重要的。你可以用我之前分享的最少的代码来实现这一点,当你试图用熊猫数据框创建 excel 文件时,这些代码肯定会帮助你创建高质量的 excel 文件。

如何使用 Python 实现 3D 点云分割和聚类的自动化

原文:https://towardsdatascience.com/how-to-automate-3d-point-cloud-segmentation-and-clustering-with-python-343c9039e4f5?source=collection_archive---------0-----------------------

实践教程,3D Python

使用多阶 RANSAC 和无监督聚类(DBSCAN)实现点云分割和 3D 形状检测自动化的完整 python 教程。

在本 python 实践指南中学习的 3D 点云分割步骤。首先,我们搜索平面形状(RANSAC),然后我们通过欧几里德聚类(DBSCAN)自动细化。F. Poux

如果你过去曾经处理过点云(或者,就这件事而言,处理过数据),你就会知道在你的观察之间找到模式是多么重要📈。事实上,我们经常需要提取一些更高层次的知识,这些知识严重依赖于确定由共享一个模式的数据点形成的“对象”。

点上的视觉模式从左到右:不分组;接近标准;相似性标准;公共集群区域;线性标准;平行判据:对称判据。资料来源: (Poux 等人,2019 年)

这是一项由我们的视觉认知系统轻松完成的任务。然而,通过计算方法模仿人类的这种能力是一个极具挑战性的问题🤯。基本上,我们希望利用人类视觉系统的倾向性来分组元素集合

“传感器看到的”与模拟人类视觉系统的潜在“对象分组”(黄色的椅子,蓝色的地面,杂乱的实例)。F. Poux

但是为什么有用呢?

问得好!实际上,点云分割的主要动机有三个:

  • 首先,它为最终用户提供了通过更高层次的概括(细分)有效访问和操作个人内容的灵活性。
  • 其次,它创建了数据的紧凑表示,其中所有后续处理可以在区域级别而不是单个点级别完成,从而潜在地显著提高了计算效率。
  • 最后,它提供了提取邻域、图形和拓扑之间的关系的能力,这在基于点的原始数据集中是不存在的。

由于这些原因,分割主要用作预处理步骤,以从点云数据中注释、增强、分析、分类、归类、提取和抽象信息。但现在真正的问题是。我们怎么做呢?

啊…让我们打开盒子👐!

包含两个关键概念的快速 3D 分割理论

在本教程中,我已经为您选择了两个最好的、更健壮的方法,您将在最后掌握它们。我们将依靠两种集中有效的方法: RANSAC 和通过 DBSCAN 的欧几里德聚类。但是在使用它们之前,我想是的😀,重要的是理解主旨,简单来说。

兰萨克

RANSAC 代表随机样本共识,这是一个非常简单但非常有效的算法,如果你的数据受到异常值的影响,你可以使用,这就是我们的情况😊。事实上,无论何时使用真实世界的传感器,您的数据都不会完美。通常,您的传感器数据会受到异常值的影响。RANSAC 是一种试错法,它会将您的数据点分成两个部分:内部数据集和外部数据集。然后,您可以忘记离群值并使用您的内联者。

所以让我用一个小而简单的例子来说明 RANSAC 是如何工作的。假设我们想通过下面的点云拟合一个平面。我们如何做到这一点?

随机点云中的 RANSAC 平面检测模拟。F. Poux

首先,我们从数据中创建一个平面,为此,我们从点云中随机选择 3 个点来建立一个平面。然后,我们简单地检查有多少剩余的点落在该平面上(达到某个阈值),这将为该提议打分。

RANSAC 评分系统图解。您可以看到,每次迭代都会随机抽取 3 个点作为样本,并从中创建一个计划,然后选择将落在该计划上的点。这里,迭代 159 将是最好的候选。F. Poux

然后,我们用 3 个新的随机点重复这个过程,看看我们做得怎么样。好点了吗?更糟吗?同样,我们一遍又一遍地重复这个过程,比如说 10 次、100 次、1000 次,然后我们选择具有最高分数的平面模型(即,其具有剩余数据点的最佳“支持”)。这就是我们的解决方案:支持点加上我们采样的三个点构成了我们的内部点集,剩下的就是我们的外部点集。很简单,匈奴😁?

哈哈,但是对于怀疑论者来说,你没有一个上升的问题吗?我们实际上如何确定我们应该重复这个过程多少次呢?我们应该多久尝试一次?嗯,这实际上是我们可以计算的东西,但现在让我们把它放在一边,专注于手头的事情:点云分割😉。

欧氏聚类(DBSCAN)

对于点云数据集,我们通常需要对空间上连续的点集进行分组,如下图所示。但是我们如何有效地做到这一点呢?

在这个图像中,很明显我们想要将彼此靠近的点分组,找到 5 组点。F. Poux

DBSCAN(带噪声的应用程序的基于密度的空间聚类)算法是在 1996 年为此目的而引入的。这种算法被广泛使用,这也是它在 2014 年被授予经受住时间考验的科学贡献奖的原因。

DBSCAN 对数据集中的点进行迭代。对于它分析的每个点,它都构建了从该点按密度可达的点集:它计算该点的邻域,如果该邻域包含超过一定数量的点,它就被包含在该区域中。每个相邻点经历相同的过程,直到它不能再扩展集群。如果考虑的点不是内部点,即它没有足够的邻居,它将被标记为噪声。这使得 DBSCAN 对于异常值是健壮的,因为这种机制隔离了它们。多酷啊😆?

DBSCAN 算法过程以及两个参数ϵ和最小点数对结果的影响的图示。可以看到,值越大,构成的集群越少。F. Poux

啊,我差点忘了。参数的选择(邻域的ϵ和最小点数的 n_min)也很棘手:在设置参数以创建足够的内部点时必须非常小心(如果 n_min 太大或ϵ太小,这将不会发生)。特别是,这意味着 DBSCAN 将很难找到不同密度的集群。但是,与 Kmeans 不同,DBSCAN 具有计算效率高的巨大优势,不需要预先定义聚类数。最后,它允许找到任意形状的集群。

现在,让我们通过 5 个步骤把所有这些晦涩难懂的东西变成一个超级有用的“软件”💻!

步骤 1 :(点云)数据,总是数据😁

在之前的教程中,我展示了通过使用摄影测量和来自开阔地形的航空激光雷达获得的 3D 数据集上的点云处理和网格划分。这一次,我们将使用我用地面激光扫描仪收集的数据集!

这是本实践指南提供的点云。这是一个简单的厨房,数据来自地面激光扫描仪。F. Poux

我将跳过关于 I/O 操作和文件格式的细节,但是我知道,如果你想弄清楚或者建立一个成熟的专家🧐.,下面的文章中会涉及到它们今天,我们将直接使用众所周知的。ply 文件格式。

</5-step-guide-to-generate-3d-meshes-from-point-clouds-with-python-36bad397d8ba>

🤓 注意 : 对于这个操作指南,你可以使用这个库中的点云,我已经过滤和转换过了,这样你就处于最佳状态了。如果你想在不安装任何东西的情况下预先可视化并使用它,你可以查看一下 webGL 版本。

步骤 2:设置您的 Python 环境。

在下面的前一篇文章中,我们看到了如何使用 Anaconda 轻松地设置环境,以及如何使用 IDE Spyder 管理您的代码。如果你想成为一名成熟的 python 应用程序开发人员,我建议你继续这样做😆。

但是,嘿,如果你喜欢在接下来的 5 分钟内从头开始,我也给你一个 Google Colab 笔记本,你会在文章的结尾找到它。没有要安装的内容;你可以把它保存到你的 google drive,然后开始使用它,也可以使用来自 1☝️.步骤的免费数据集

在 Google Colab 文件中,您可以一个单元格一个单元格地运行脚本,并从 web 上的直接编码体验中受益。开始尝试 Python 的好方法。(是的,猫在橱窗里走😺).F. Poux

🤓

第三步:第一轮细分

嗯,为了尽快得到结果,我要吃“parti-pris”。事实上,我们将通过遵循最小化的编码方法来完成一个很好的分段💻。这意味着对底层库非常挑剔!我们将使用三个非常健壮的,即numpymatplotlibopen3d

好了,要在您的环境中安装上面的库包,我建议您从终端运行以下命令(另外,请注意open3d-admin通道):

conda install numpy
conda install matplotlib
conda install -c open3d-admin open3d

🤓 免责声明注 : 我们选择的是 Python,而不是 C++或者 Julia,所以表演就是表演😄。希望这对您的应用程序来说足够了😉,我们称之为“离线”过程(非实时)。

现在是期待已久的看到第一个结果的时候了!

如何在 3D 点云上实现 RANSAC?

让我们首先用下面一行导入pcd变量中的数据:

pcd = o3d.io.read_point_cloud("your_path/kitchen.ply")

你想快速创造奇迹吗?嗯,我有一个好消息,open3d配备了一个 RANSAC 实现,用于点云中的平面形状检测。唯一要写的一行是:

plane_model, inliers = pcd.segment_plane(distance_threshold=0.01, ransac_n=3, num_iterations=1000)

🤓 注意 : 正如你所看到的,segment_plane()方法持有 3 个参数。这些是距离平面的距离阈值(distance_threshold)以考虑点的内侧或外侧,所绘制的采样点的数量(这里是 3 个,因为我们想要一个平面)以估计每个候选平面(ransac_n)和迭代次数(num_iterations)。这些是标准值,但是要注意,根据手头的数据集,distance_threshold应该被仔细检查。

上一行的结果是plane_model中捕获的最佳平面候选参数 a、b、c 和 d,以及inliers中捕获的被认为是内点的点的索引

现在让我们想象一下结果,好吗?为此,我们实际上必须基于在inliers中捕获的索引来选择点,并且可选地选择所有其他的点作为异常值。我们如何做到这一点?嗯,像这样:

inlier_cloud = pcd.select_by_index(inliers)
outlier_cloud = pcd.select_by_index(inliers, invert=True)

🤓 注意 : 参数invert=True允许选择第一个参数的反义词,这意味着inliers 中没有的所有指标。

好了,现在你的变量保存了这些点,但是在可视化结果之前,我建议我们把内嵌器涂成红色,其余的涂成灰色。为此,您可以像这样传递一个 R,G,B 值列表:

inlier_cloud.paint_uniform_color([1, 0, 0])
outlier_cloud.paint_uniform_color([0.6, 0.6, 0.6])

现在,让我们用下面一行来想象结果:

o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])

🤓 注意 : 如果你想更好地掌握被颜色冲刷过的几何体,你可以事先使用下面的命令计算法线:pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=16), fast_normal_computation=True)。这将确保你得到一个更好的渲染,如下😉。

这显示了上面详述的 RANSAC 脚本的结果。红色的是内点,灰色的是外点。F. Poux

太好了!你知道如何分割你的点云在一个内点集合和一个外点集合🥳!现在,让我们研究如何找到一些彼此靠近的星团。因此,让我们想象一下,一旦我们检测到大的平面部分,我们就有了一些我们想要描绘的“浮动”对象。如何做到这一点?(是的,这是一个伪问题,我有答案给你😀)

如何在点云上使用 DBSCAN?

首先,我们选择一个样本,在这里我们假设我们去掉了所有的平面区域(这个样本可以在这里找到:访问数据样本),如下所示。

我们想要通过欧几里德聚类分割的剩余元素。使用上面的链接可以访问数据集。F. Poux

好了,现在,让我们写一些 DBSCAN 集群。同样,为了简化一切,我们将使用open3d 包的 DBSCAN 方法部分,但是要知道,如果您需要更大的灵活性,在scikit-learn中实现可能是更长远的选择。就时间而言,这几乎是一样的。方法cluster_dbscan直接作用于pcd点云实体,并在点云初始索引后返回标签列表。

labels = np.array(pcd.cluster_dbscan(eps=0.05, min_points=10))

🤓 : 标签在-1n之间变化,其中-1表示它是一个“噪声”点,值0n则是给对应点的聚类标签。请注意,我们希望以 NumPy 数组的形式获得标签,并且我们使用 5 cm 的半径来“生长”集群,并且只有在这一步之后我们至少有 10 个点时才考虑一个。请随意尝试😀。

很好,现在我们有了用每个点一个标签定义的点组,让我们给结果着色。这是可选的,但是对于迭代过程来说,搜索正确的参数值是很方便的。为此,我建议使用 Matplotlib 库来获取特定的颜色范围,例如 tab20:

max_label = labels.max()
colors = plt.get_cmap("tab20")(labels / (max_label 
if max_label > 0 else 1))colors[labels < 0] = 0
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])o3d.visualization.draw_geometries([pcd])

🤓 注意:max_label应该是直观的:它存储标签列表中的最大值。这允许使用它作为配色方案的分母,同时用“if”语句处理特殊情况,其中聚类是偏斜的,并且仅传递噪声+一个聚类。之后,我们确保将这些带有标签-1的噪声点设置为黑色(0)。然后,我们给点云pcd的属性colors3 个“列”的 2D 数组,代表 R,G,b

瞧啊!下面是我们的聚类结果。

参数 eps=0.05 和 min_points=10 的点云 DBSCAN 聚类方案的结果。我们可以清楚地将顶层橱柜与底层橱柜区分开来,还有加热控制器(绿色)和灯(紫色)。F. Poux

太好了,它运行得很好,现在,我们如何实际上以自动化的方式将所有这一切规模化呢?

步骤 4:扩展和自动化

我们的理念将非常简单。我们将首先运行 RANSAC 多次(比如说n次)来提取构成场景的不同平面区域。然后我们将通过欧几里德聚类(DBSCAN)来处理“浮动元素”。这意味着我们必须确保我们有一种方法来存储迭代期间的结果。准备好了吗?

为多个平面形状检测创建 RANSAC 循环

好了,让我们实例化一个空字典,它将保存迭代的结果(segment_models中的平面参数,以及segments中来自点云的平面区域):

segment_models={}
segments={}

然后,我们要确保我们可以影响我们想要迭代检测平面的次数。为此,让我们创建一个保存迭代次数的变量max_plane_idx:

max_plane_idx=20

🤓 : 在这里,我们说要迭代 20 次才能找到 20 个平面,但是有更聪明的方法来定义这样一个参数。它实际上扩展了文章的范围,但如果你想了解更多,可以查看 3D 地理数据学院。

现在让我们进入一个工作循环😁我将首先快速说明。在第一遍(循环i=0)中,我们从离群值中分离出内嵌值。我们将内联体存储在segments中,然后我们希望只处理存储在rest中的剩余点,这成为循环 n+1(循环i=1)的主题。这意味着我们希望将上一步中的异常值视为基点云,直到达到迭代阈值以上(不要与 RANSAC 迭代混淆)。这转化为以下内容:

rest=pcd
for i in range(max_plane_idx):
    colors = plt.get_cmap("tab20")(i) segment_models[i], inliers = rest.segment_plane(
    distance_threshold=0.01,ransac_n=3,num_iterations=1000)
    segments[i]=rest.select_by_index(inliers) segments[i].paint_uniform_color(list(colors[:3])) rest = rest.select_by_index(inliers, invert=True) print("pass",i,"/",max_plane_idx,"done.")

差不多就是这样了!现在,为了形象化整体,当我们用从tab20到循环的第一行(colors = plt.get_cmap(“tab20”)(i))的颜色来描绘每个检测到的片段时,你只需要写下:

o3d.visualization.draw_geometries([segments[i] for i in range(max_plane_idx)]+[rest])

🤓 : 我们传递给函数o3d.visualization.draw_geometries()的列表[segments[i] for i in range(max_plane_idx)]实际上是一个“列表理解”🤔。这相当于编写一个for循环,将第一个元素segments[i]追加到一个列表中。方便的是,我们可以将[rest]添加到这个列表中,然后draw.geometries()方法会理解我们想要绘制一个点云。多酷啊。

RANSAC 点云分割的多次迭代过程的结果。F. Poux

哈!我们认为我们完成了…但是我们做到了吗?你注意到这里有些奇怪吗?如果你仔细观察,会发现一些奇怪的人工制品,比如实际切割一些平面元素的“线条”。为什么?🧐

事实上,因为我们独立于点密度连续性将所有点拟合到 RANSAC 平面候选(其在欧几里得空间中没有限制范围),所以我们具有取决于平面被检测的顺序的这些“线”假象。所以下一步是防止这种行为!为此,我建议在迭代过程中包含一个基于欧几里得聚类的条件,以在连续的聚类中提炼内层点集。准备好了吗?

使用 DBSCAN 对多 RANSAC 循环进行明智的细化

为此,我们将依赖于 DBSCAN 算法。让我详细说明一下逻辑过程,但不要这么简单(激活野兽模式👹).在前面定义的 for 循环中,我们将在内联程序(segments[i]=rest.select_by_index(inliers))赋值后运行 DBSCAN,方法是在其后添加以下代码行:

labels = np.array(segments[i].cluster_dbscan(eps=d_threshold*10, min_points=10))

🤓 : 我其实是在 RANSAC 平面搜索的初始阈值函数中设置了ε,有 10 倍的量级高。这不是深奥的科学,这是一个纯粹的经验选择,但它通常工作得很好,并通过参数使事情变得更容易😀。

然后,在这个循环中,我们将使用一种奇怪的符号来计算我们发现的每个聚类包含多少个点,这种符号利用了列表理解。然后将结果存储在变量candidates中:

candidates=[len(np.where(labels==j)[0]) for j in np.unique(labels)]

现在呢?我们必须找到“最佳候选”,通常是拥有更多点的集群!对于这一点,下面是这条线:

best_candidate=int(np.unique(labels)[np.where(candidates== np.max(candidates))[0]])

好吧,这里有很多技巧,但本质上,我们使用 Numpy 熟练度来搜索并返回属于最大聚类的点的索引。从这里开始,就是下坡滑雪,我们只需要确保在考虑后续 RANSAC 迭代时,每次迭代都添加最终剩余的集群(🔥句子要读 5 遍才能消化):

rest = rest.select_by_index(inliers, invert=True) + segments[i].select_by_index(list(np.where(labels!=best_candidate)[0]))
segments[i]=segments[i].select_by_index(list(np.where(labels== best_candidate)[0]))

🤓 注意:rest变量现在确保保存来自 RANSAC 和 DBSCAN 的两个剩余点。当然,现在内联器被过滤为原始 RANSAC 内联器集中存在的最大集群。

当循环结束时,您会得到一组清晰的线段,这些线段包含遵循平面形状的空间连续点集,如下所示。

注意,我们已经解决了“线”的问题,但是我们仍然有一些灰色的元素,它们还没有被赋值。F. Poux

但这就结束了吗?不,从来没有😄!最后一步!

使用 DBSCAN 聚类剩余的 3D 点

最后,我们走出循环,处理 rest 中存储的尚未归属于任何段的剩余元素。为此,一个简单的欧几里德聚类(DBSCAN)应该可以做到这一点:

labels = np.array(rest.cluster_dbscan(eps=0.05, min_points=5))
max_label = labels.max()
print(f"point cloud has {max_label + 1} clusters")colors = plt.get_cmap("tab10")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0
rest.colors = o3d.utility.Vector3dVector(colors[:, :3])

我使用和以前一样的方法,没有魔法!我只是确保使用连贯的参数有一个完善的聚类,以获得美丽的彩虹厨房你一直梦想在🥳!

这是当前方法的最终聚类结果!祝贺您实现了基于平面的顶级元素检测,您现在可以将其作为更高视觉过程的基础进行操作!F. Poux

如果你想让它直接工作,我还创建了一个 Google Colab 脚本,你可以在这里访问:到 Python Google Colab 脚本。

结论

热烈祝贺🎉!您刚刚学习了如何使用不同的策略,为由数百万个点组成的 3D 点云导入和开发自动分割和可视化程序!真心的,干得好!但是,这条道路当然不会就此结束,因为您刚刚释放了智能过程的巨大潜力,这些智能过程可以在段级别进行推理!

未来的帖子将深入探讨点云空间分析、文件格式、数据结构、对象检测、分割、分类、可视化、动画和网格划分。我们将特别关注如何管理大点云数据,如下文所述:

**

我的贡献旨在浓缩可操作的信息,以便您可以从零开始为您的项目构建 3D 自动化系统。您可以从今天开始,在地理数据学院开始。

https://learngeodata.eu/point-cloud-processor-formation/

更进一步

存在用于点云的其他高级分割方法。这实际上是我深入参与的一个研究领域,你已经可以在文章[1–6]中找到一些设计良好的方法。对于更高级的 3D 深度学习架构,一些综合教程即将推出!

  1. 福克斯、&比伦(2019)。基于体素的三维点云语义分割:无监督的几何和关系特征与深度学习方法。 ISPRS 国际地理信息杂志。8(5), 213;https://doi.org/10.3390/ijgi8050213—杰克·丹格蒙德奖(链接到新闻报道)
  2. Poux,F. ,纽维尔,r .,纽约州,g .-a .&比伦,R. (2018)。三维点云语义建模:室内空间和家具的集成框架。遥感10 (9)、1412。https://doi.org/10.3390/rs10091412
  3. Poux,F. ,Neuville,r .,Van Wersch,l .,Nys,g .-a .&Billen,R. (2017)。考古学中的 3D 点云:应用于准平面物体的获取、处理和知识集成的进展。地学7 (4),96。https://doi.org/10.3390/GEOSCIENCES7040096
  4. Poux,F. ,Mattes,c .,Kobbelt,l .,2020 年。室内三维点云的无监督分割:应用于基于对象的分类,摄影测量、遥感和空间信息科学国际档案。第 111-118 页。https://doi:10.5194/ISPRS-archives-XLIV-4-W1-2020-111-2020
  5. Poux,F. ,Ponciano,J.J .,2020。用于 3d 室内点云实例分割的自学习本体,ISPRS 摄影测量、遥感和空间信息科学国际档案。第 309-316 页。https://doi:10.5194/ISPRS-archives-XLIII-B2-2020-309-2020
  6. 巴西耶,男,维高温,男,普克斯,女,,(2020)。用于建筑物内部分类的点云和网格特征。遥感。12, 2224.https://doi:10.3390/RS 12142224**

如何在 Python 中自动化格式化和林挺

原文:https://towardsdatascience.com/how-to-automate-formatting-and-linting-in-python-ce99d2db9c37?source=collection_archive---------25-----------------------

永远不要再犯错误的代码

照片由 Fotis Fotopoulos 在 Unsplash 上拍摄

我们将查看一些包来格式化、lint、测试我们的代码,然后创建一个预提交钩子来自动化这个过程。这篇由丹·鲁特撰写的文章是对 PEP 8 风格指南的一个很好的概述。

在我们讨论将要使用的包之前,让我们先来看看将要使用的 python 文件

我们有一个函数叫做 helpers.py

帮助者. py

它有简单的算术功能。所有函数都接受两个参数,并对它们执行算术运算。

我们有另一个名为 tester_helpers.py 的文件

tester_helpers.py

这个文件只是测试我们之前定义的函数。它使用 assert 进行简单的相等检查。

现在让我们看看我们将使用的包。

测试🧪

7.7k+ ⭐️

这个包帮助我们运行单元测试。需要记住的一个要求是,包含单元测试的 python 文件应该以“test_”开头。

仅支持 assert 语句。要安装软件包

pip install pytest

若要运行单元测试,请键入以下命令

pytest test_helpers.py

如果您的所有测试都通过了,您应该会看到类似的输出

test_helpers.py ....             [100%]========= 4 passed in 0.01s ===========

如果您得到一个与多个相对导入相关的错误

astroid.exceptions.TooManyLevelsError:

这可能是 pytest 的一个依赖项的问题。你必须卸载 astroid,然后重新安装。这确保安装了最新的 astroid 版本。

pip uninstall astroid
pip install astroid

在这之后,我们必须卸载 pytest 并安装 pytest

pip uninstall pytest
pip install pytest

格式化✍️

YAPF 12k+ ⭐️

这是由 google 开发的,支持就地格式化。要安装软件包

pip install yapf

要格式化文件,请键入以下内容

yapf --in-place *.py

这将格式化您所有的顶级 python 文件,如果您还想包含文件夹,您可以使用以下命令

yapf --in-place **/*.py

但是,这也包括我们的虚拟环境文件夹。要忽略 venv 文件夹,只需创建一个文件。yapfignore 然后加上 venv。

注意:此命令可能需要一些时间来运行。您可以使用文件夹的特定名称来代替' ** '。

isort 4.1k+ ⭐️

这个包对您的 import 语句进行排序,以确保它们遵循 pep8 规则。

进口应按以下顺序分组:

  • 标准库导入。
  • 相关第三方进口。
  • 特定于本地应用程序/库的导入。

isort 对 import 语句进行重新排序,以确保遵循上述规则。
安装软件包

pip install isort

运行 isort

isort .

自动对焦 400+⭐️

它有助于消除未使用的导入、变量和对象键。

要安装软件包

pip install autoflake

运行自动折叠

autoflake --in-place --remove-unused-variables --remove-all-unused-imports *.py

一些其他格式化程序

  • autopep8 3.9k+ ⭐️
  • 黑色 22.1k+ ⭐️

林挺🔎

皮林特 3.5k+ ⭐️

pylint 确保您的代码遵循 pep8 规则和标准。它给每个 python 文件打满分(也可以给你一个负分)

要安装软件包

pip install pylint

运行棉绒机

pylint --fail-under=7 *.py

参数--fail-under是下限,如果任何文件的分数低于下限,将返回一个错误。

提交前挂钩🪝

什么是 Git 挂钩?

Git 挂钩基本上是在重要操作发生之前触发的脚本,例如,在提交之前,在提交之后将代码推送到 repo 之前,等等。你可以在这里了解更多关于 Git 钩子和不同种类钩子的知识。

Enrique lópez-Maas的这篇文章也是了解更多关于 git 钩子的好文章。

我们将重点关注预提交挂钩。预提交挂钩是在提交之前运行的挂钩。

首先,让我们安装软件包

pip install pre-commit

现在,我们将生成一个示例预提交钩子 YAML 文件,稍后我们将编辑它。

pre-commit sample-config

现在让我们添加我们的钩子

pre-commit install

现在,在每次提交之前,我们的 YAML 文件中定义的预提交钩子将被执行。

现在让我们更新我们的 YAML 文件。
删除所有内容,仅保留以下内容

repos:
    - repo: local
      hooks:

我们将在 YAML 文件的hooks:下添加我们的插件(包)。下面是插件的一般语法

- id: (unique id of hook)
     name: (name to be displayed in terminal)
     entry: (command to excute)
     language: system (for our case, always system) 
     always_run: true (if true, it will always run)
     pass_filenames: true (if true, hook will have access to the file name)

让我们为 YAPF 定义一个示例插件

- id: YAPF 
     name: YAPF 🧹
     entry: zsh -c 'yapf --in-place *.py'
     language: system
     always_run: true
     pass_filenames: true

如果您使用的是 bash 或 windows,请用 bash 替换“entry”中的 zsh。

所有其他插件都非常相似,下面是整个 YAML 文件和所有插件

Git 预提交钩子来自动化 Python 中的林挺和格式化

每当您更新您的 YAML 文件时,您必须使用 git add 将该文件添加到临时区域。或者 git add。预提交配置. yaml

下面是一个成功的提交

行动中的预提交

结论

设置预提交挂钩将确保您的代码遵循 pep8 标准并且格式正确。我希望这篇文章对你有用。在 LinkedIn , Twitter 上加我

最初发布于realpythonproject.com

如何自动创建 Python 环境

原文:https://towardsdatascience.com/how-to-automate-python-environment-creation-850743f1c09e?source=collection_archive---------16-----------------------

创建环境,并通过一个命令将它们集成到 Jupyter 笔记本中

照片由 Florian Olivo 在 Unsplash 上拍摄

https://learningfrommachines.substack.com/

介绍

对于那些在数据科学领域的人来说,自动化是他们最喜欢的词之一。将经常占用不必要时间的简单任务自动化是最好的技能之一。你不仅可以用一行代码完成 10/15 分钟的工作,而且你不必担心必须记住过程的每一步,因为你已经为自己开发了这些步骤。

在本文中,我将向您展示如何使用bash脚本在condaipykernel中自动开发 Python 环境。我已经写了如何将您的环境链接到 Jupyter 内核,所以如果您不知道如何做,您可以在下面找到它的链接:

我将在一个 Unix shell 上工作,默认情况下,这个 shell 可用于 Linux 和 macOS。本文不会讨论如何在 Windows 上实现这一点,所以请注意这一点。

事不宜迟,我们开始吧!

项目大纲

在开始任何项目之前,不管是简单的还是复杂的,最好有一个简单的大纲,说明需要做什么,为手边的用户所做的假设,以及程序本身将要采取的行动。

用户的假设:

  • 用户的系统上安装了conda
  • 每次创建新环境时,用户都希望指定 Python 版本

程序的操作:

  • 创建指定名称和 Python 版本的环境。
  • ipykernel安装到 Python 环境中
  • 将环境链接到 Jupyter 内核

一旦所有这些操作完成,您就可以激活环境,安装您需要的任何包,并立即在 Jupyter 中使用它们。

开发脚本

首先,在主目录中,创建一个名为scripts的新文件夹。这将允许您将您选择制作的任何其他脚本也放在该文件中。假设您已经这样做了,首先在文件夹中创建两个文件。对于这个项目,我将称它们为env1.shenv2.sh

然后,您可以用您喜欢的任何文本编辑器打开该脚本。确保你知道你的bash在哪里。这可以通过以下命令完成:

$ which bash

由于我运行的是 Linux,所以我的结果是user/bin/bash。使用一个 shebang,或#!,我们可以把它放在我们的路径前面,以确保我们的文件是可执行的。这将是我们两个脚本中的第一行。

我们将使用两个脚本来完成这项工作。第一个脚本将创建虚拟环境,并使用其名称(第一个参数)和 Python 版本(第二个参数)。)

虽然这只是一行代码,但我们将它放在一个不同的文件中,因为执行在环境完成后结束。这就是第二个文件出现的地方,它允许我们调用第一个脚本来创建环境,然后使用脚本的其余部分来创建 Jupyter 内核。

下面是第一个文件的样子:

如果您不熟悉bash语法,$1代表运行文件所需的第一个参数,而$2代表第二个参数。

对于第二个文件,我们将调用env1.sh并继续内核创建过程。看起来是这样的:

首先,我们用需要的参数调用env1.sh。这意味着两个文件将使用相同的参数。一旦完成,我们必须找到 anaconda,这样我们就可以激活 bash 脚本中的环境。一旦完成,我们就可以激活环境,使用pip安装ipykernel,并将环境链接到与环境同名的内核。

运行脚本

为了简化本文(我假设您以前从未构建过命令行界面),您可以使用以下代码运行脚本:

$ bash scripts/env2.sh automated 3.8

这将使用 Python 版创建一个名为automated的新conda环境。此外,正如我们在env2.sh中看到的,它还将创建一个 Jupyter 内核,也称为automated,我们可以在启动 Jupyter 笔记本后立即开始使用它。

最后的想法

虽然我试图保持简短,但这个项目还可以做一些改进。主要是,我们可以用必要的参数运行chmod,这样文件就是可执行的。然而,如果你有兴趣在空闲时间从事这项工作,我将把它留给你。然而对我来说,运行这一行来自动化这个过程比过程本身要容易得多!

我希望这是一个有用的有趣的项目,你可以从中学习。如果你有任何问题,请在下面留下。

如何用 Python 实现三维点云体素建模的自动化

原文:https://towardsdatascience.com/how-to-automate-voxel-modelling-of-3d-point-cloud-with-python-459f4d43a227?source=collection_archive---------2-----------------------

实践教程,3D Python

使用 Python 和 open3D 将大型点云转化为 3d 体素🧊的实践教程。解锁自动化工作流程,实现高效的 3D 体素化

体素 3D 模型,当前开源 python 教程的成果。它是从文章中可访问的大点云中自动提取的。F. Poux

如果我们有一种快速的方法将从现实中捕捉到的点云转换成 3D 网格会怎么样?如果这些 3D 网格是一个基于体素的集合会怎么样呢?这是有道理的吗?这对你的创作或专业目的有什么帮助?🤔

在探索 python 自动化技巧和窍门之前,让我们先从一个小小的乐高故事开始吧😎。

一个快速的乐高、体素和点云故事

好吧,如果你的童年是在乐高(现在的《我的世界》)的摇篮中度过的,那么腐蚀你应该不会太难😊。你还记得把这些小块组装成 3D 模型有多有趣吗?我们可以用它来创作新的故事或者模拟我们最喜欢的电影。

不,我的目标不是要你买一大堆乐高,而是要吸引这些简单的实体积木的酷感。以及我们能用它们做多少事。

Guillermo Momplet 制作的乐高模型动画示例。

但是与当前的体素谈话有什么实际联系呢?简单地说,体素是 2D 像素的 3D 模拟(有人说是 3D 像素,但这听起来很奇怪)。这是一种构造最初无序的 3D 数据集(如点云)的简单方法。然后你得到这个原始积木的组合,它可以很容易地与乐高组合连接起来。除了物理和数字属性之外,主要区别是😊—体素只能玩一种类型的基础元素(立方体🧊),而 Legos 允许您玩不同维度的各种块。但是如果我们从理论上采用多尺度的观点和推理,正如达索系统公司所说,空间公司在来源:

体素是复制现实的完美建模技术,可以远远超出我们的想象。

示出多尺度视图允许用适应的细化来表示捕捉世界几何图形的基础数据。F. Poux

事实上,我们的 3D 世界是由超微小体素可以大量逼近的物质组成的。因此,如果你有足够高的密度和适当的渲染技术:

您可以使用体素来复制现实世界中无法从外观和行为上与真实事物区分开来的对象。

与原始点云相比,这是一个显著的优势:你可以模拟现实世界的物理现象,而这在其他建模方法中是不可能的,或者是脱发技术😆。

体素可以存储真实的“物质”体积。因此,它们可以方便地开启新的模拟技术,而用其他方法可能会很棘手。F. Poux

💡提示 : I 如果你想更好地理解如何表示 3D 数据以及每种方法之间的技术差异,我鼓励你阅读下面的文章。

Dassault Systèmes,Spatial Corp. 所见的体素作为 3D 表示的主要优势来源

现在你是一个真正的被破坏的体素🥑,是时候动手学习如何以自动化的方式将 3D 点云快速转化为体素集合了。准备好了吗?

https://learngeodata.eu/point-cloud-processor-formation/

步骤 1:编码选择

免责声明:当编码解决一个确定的问题时,没有一个唯一的方向。我给你的解决方案依赖于一些聪明的技巧,使用open3d和可用的函数栈。但是,如果您希望依赖最少数量的库,您也可以遵循下面的文章,将体素采样策略调整为体素创建策略。

在本教程中,我们将只依赖于三个函数库:laspy ( pip install laspy)、open3d ( conda install -c open3d-admin open3d)和numpy ( conda install numpy),python 版本为 3.8。为此,这三行简单的代码:

import laspy as lp
import numpy as np
import open3d as o3d

🤓 : 当前实验运行使用 Python 3.8.12,laspy版本:2.0.3,numpy版本 1.21.2,open3d版本 0.11.2。这样,如果需要调试,您就可以先做一些检查:)。

很好,现在剩下的就是确定一个我们想要体素化的点云。幸运的是,我为您创建了一个非常好的文件,您可以从我的驱动器文件夹中检索到它:下载数据集(。las) ,或使用 Flyvast 在您的网络浏览器中可视化。

提供的点云进行 python 教程。F. Poux

设置完成后,我们就可以开始在我们的环境中加载数据了。

💡提示 : I 如果您是从零开始,并且想要按照一个食谱在 5 分钟内启动并运行 Python,我建议您遵循下面这篇文章,它给出了设置您的环境的所有细节。如果您不想安装任何东西,您也可以使用我在文章结尾提供的 Google Colab 笔记本在云上运行它。

步骤 2:加载数据

首先,我们创建两个变量来处理输入路径(您应该适应您的情况)和数据名称,如下所示:

input_path=”C:/DATA/”
dataname=”heerlen_table.las”

现在,是时候在我们的程序中加载数据了。我们首先将点云作为一个laspy.lasdata.LasData存储在一个point_cloud变量中。

point_cloud=lp.read(input_path+dataname)

然后,为了使用存储在point_cloud变量中的数据,我们将把它转换成open3d点云格式。如果你还记得以前的教程,我们从空间坐标(X,Y 和 Z)中分离出什么是颜色。

pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(np.vstack((point_cloud.x, point_cloud.y, point_cloud.z)).transpose())
pcd.colors = o3d.utility.Vector3dVector(np.vstack((point_cloud.red, point_cloud.green, point_cloud.blue)).transpose()/65535)

🤓 : 仔细看,可以看到一个怪异的 *65535* 。这是因为,在 *laspy* 格式中,颜色是以 16 位无符号方式编码的整数,这意味着数字范围从 *0* *+65535* ,我们希望缩放到一个 *[0,1]* 区间。这些数学猎人有多疯狂😆

步骤 3:创建体素网格

我们有一个点云,我们想要拟合一个体素立方体的集合来近似它。为此,我们实际上只在已建立的 3D 网格上有点的部分生成体素。

为了获得体素单元,我们首先需要计算点云的边界框,它界定了数据集的空间范围。只有到那时,我们才能将边界框离散化成一个由小的 3D 立方体组成的集合:体素。

在我们的例子中,如果切换输入点云,我们将简单地通过给出与初始边界框相关的相对值来计算体素大小,以“概括”该方法。为此,您可以在下面看到,我们提取点云的边界框,我们取最大的边,我们决定将体素大小设置为其值的 0.5%(这是绝对任意的)。最后,我们将获得的值向上舍入到 4 位数,而不会遭受此后不精确的计算。

v_size=round(max(pcd.get_max_bound()-pcd.get_min_bound())*0.005,4)
voxel_grid=o3d.geometry.VoxelGrid.create_from_point_cloud(pcd,voxel_size=v_size)

🤓注意 : 这可能是我写的最不明确的代码行之一,但是它给出了一个很好的例子,说明快速的经验陈述可以实现什么。这方面有很多可以改进的地方,特别是在舍入误差和任意阈值方面。😉

使用建议值和将改变细节层次的其他值在数据集上获得的结果示例。F. Poux

现在我们已经定义了我们的体素单元,我们将实际上切换到一个与空间信息相关的更有效的“表示”,但是更有效:一个二进制表(FalseTrue01)。为此,使用open3d的第一个技巧是使用以下命令行生成体素网格:

voxel_grid=o3d.geometry.VoxelGrid.create_from_point_cloud(pcd,voxel_size=v_size)

太棒了,你现在是你的点云的体素表示的所有者,你可以可视化(如果在 jupyter 环境之外)与:

o3d.visualization.draw_geometries([voxel_grid])

我们的 voxel_grid 变量在open3d中可视化。每个非空的体素保存从基础点平均的颜色信息。F. Poux

这太棒了!但是,如果我们就此止步,我们将陷入最小的利用范围。实际上,在那里你将被限制使用open3d库来处理体素结构,使用有限数量的函数,这取决于你的需要,是否适合你的应用。因此,让我们深入研究从这个数据结构创建 3D 网格的过程😆,我们可以以开放格式导出它。ply 或者。obj)并加载到其他软件中,包括 MeshLab、Blender、CloudCompare、MagickaVoxels、Unity、Unreal Engine 等等。

步骤 4:生成体素立方体(3D 网格)

现在我们有了voxel_grid,我们将提取填充的体素,以便有可能在以后将它们用作独立的实体。

voxels=voxel_grid.get_voxels()

如果我们检查新的voxels变量看起来像什么;我们得到一个包含保存体素信息的open3d.cpu.pybind.geometry.Voxel类型的列表:Voxel with grid_index: (19, 81, 57), color: (0.330083, 0.277348, 0.22266)

好的,我们将把它转换成一个 3D 立方体网格的集合(8 个顶点和 12 个三角形描述了 6 个面)。看到我们试图达到的目的了吗🙃?首先,让我们初始化我们的三角形网格实体,它将包含这个立方体组件:

vox_mesh=o3d.geometry.TriangleMesh()

现在,我们将使用for v in voxels迭代所有体素,对于每个体素,我们将生成一个大小为 1 的立方体,存储在变量cube中。然后我们用手边的体素颜色对它进行着色,最后我们使用方法grid_index提供的索引将体素定位在网格上。最后,我们用vox_mesh+=cube将我们新着色和定位的立方体添加到网格实体中。

for v in voxels:
   cube=o3d.geometry.TriangleMesh.create_box(width=1, height=1,
   depth=1)
   cube.paint_uniform_color(v.color)
   cube.translate(v.grid_index, relative=False)
   vox_mesh+=cube

🤓注意: 翻译方法将是否应该相对于给定的第一个参数(位置)进行翻译作为一个参数。在我们的例子中,因为我们将其设置为 False,所以第一个参数 *v.grid_index* 充当我们系统中的绝对坐标。

以预定义的体素尺寸点云体素化的 Z 级数的图示。F. Poux

步骤 5:导出网格对象。ply 或者。obj)

我们现在有了一个 3D 网格对象,可以进行 I/O 操作了…或者差不多了。事实上,我们仍然处在一个任意整数单位的任意系统中。为了将我们自己定位在由输入点云强加的初始参考框架中,我们必须应用刚性变换(平移、旋转和缩放)来回到原始位置。为了清楚起见,我将这个目标分解成三行代码。🤓

首先,我们将 3D 网格(体素组件)相对平移半个体素单位。这是因为当我们创建初始体素网格时,参考点是体素的最低左点,而不是重心(相对位于单位立方体中的[0.5,0.5,0.5])。

vox_mesh.translate([0.5,0.5,0.5], relative=True)

然后,我们通过体素大小来缩放我们的模型,以将每个立方体单元转换成它的真实大小。这使用了带有两个参数的 scale 方法。第一个是缩放因子,第二个是缩放时使用的中心。

vox_mesh.scale(voxel_size, [0,0,0])

最后,我们需要通过使用体素网格原点相对平移来将体素集合平移到其真实的原始位置。

vox_mesh.translate(voxel_grid.origin, relative=True)

3D 网格来自上面的一组技巧,即基于体素的装配。F. Poux

很好,现在我们有了正确定位的最终立方体组合。一个可选命令是合并闭合顶点。每当我们生成一个立方体时,我们可以处于这样一种配置中,其中一个角顶点与另一个立方角顶点重叠。因此,最好在保留拓扑结构的同时清除这些错误。

vox_mesh.merge_close_vertices(0.0000001)

最后,🥁,我们管道中的最后一个元素是简单地将我们的.ply(或.obj取决于你喜欢的扩展名)文件导出到你的操作系统浏览器中选择的文件夹。

o3d.io.write_triangle_mesh(input_path+”voxel_mesh_h.ply”, vox_mesh)

从那里,您可以自由地在您选择的软件中使用输出文件。如果在导入时,您得到一个旋转的文件,您也可以在 python 代码中添加以下行,并将导出的变量更改为vox_mesh.transform(T):

T=np.array([[1, 0, 0, 0],[0, 0, 1, 0],[0, -1, 0, 0],[0, 0, 0, 1]])
o3d.io.write_triangle_mesh(input_path+”4_vox_mesh_r.ply”, vox_mesh.transform(T))

这只是简单地创建一个变换矩阵T,它定义了绕 Y 轴的逆时针旋转,这通常在一些软件中显示反转的 Z 轴和 Y 轴。这样,如果这种情况发生在你身上,你会有另一个锦囊妙计。

你可以用这款 Google Colab 笔记本直接在你的浏览器中访问代码。

一些遗言

还记得我们在文章开头称赞过体素的多功能性和简单性吗?嗯,我也想给你们一些视觉上的背景。你将在下面看到在他们的表现上演奏能达到什么。体素的有趣之处在于,你可以得到一个有序的结构,你可以更好地处理它。

点云的体素表示。场景表现为立方体、模具、球体、乐高积木、圆柱体或怪人的组合。F. Poux

当然,这只是您很快就能做的事情的预演。😉

结论

您刚刚学习了如何导入点云,将它们转换为体素网格,欺骗系统使它们成为 3D 网格,然后完全自动地导出它们!干得好!有趣的是,能够在 Python 中使用体素也将允许更好地掌握任何点云场景的关系和拓扑,如[2]所示。为了扩展学习之旅的成果,未来的文章将深入探讨体素处理、点云文件格式、3D 数据结构、语义和实例分割[2–4]、动画以及深度学习[1]。我们将研究如何管理大点云数据,如下文所述。

我的贡献旨在浓缩可操作的信息,以便您可以从零开始为您的项目构建 3D 自动化系统。您可以从今天开始,在地理数据学院开始。

https://learngeodata.eu/point-cloud-processor-formation/

参考

  1. Poux,F. ,& J.-J Ponciano。(2020).三维室内点云实例分割的自学习本体。国际摄影测量与遥感学会。拱门。Pho 的。&雷姆。第四十三任——B2,309–316 年;https://doi . org/10.5194/ISPRS-archives-XLIII-B2–2020–309–2020

  2. Poux,F. ,& Billen,R. (2019)。基于体素的三维点云语义分割:无监督的几何和关系特征与深度学习方法。 ISPRS 国际地理信息杂志。8(5), 213;https://doi.org/10.3390/ijgi8050213

  3. Poux,F. ,纽维尔,r .,纽约,g .-a .&比伦,R. (2018)。三维点云语义建模:室内空间和家具的集成框架。遥感10 (9)、1412。https://doi.org/10.3390/rs10091412

  4. Poux,F. ,Neuville,r .,Van Wersch,l .,Nys,g .-a .&Billen,R. (2017)。考古学中的 3D 点云:应用于准平面物体的获取、处理和知识集成的进展。地学7 (4),96。https://doi.org/10.3390/GEOSCIENCES7040096

如何使用 Etsy &灵捷自动化您的在线打印业务

原文:https://towardsdatascience.com/how-to-automate-your-online-prints-business-with-etsy-prodigi-6a093bdff20?source=collection_archive---------22-----------------------

第 1/2 部分:如何使用 Python 和 Etsy +灵积 API 创建订单

图像通过 Unsplash

4 年来,我一直在经营我自己的基于体育数据的印刷业务/爱好&在 Etsy 、 GPBox 和个人销售了 1500 多份印刷品。这是一个学习新编程语言/软件的神奇平台,也是一个发挥创造力和尝试新设计的地方。

它开始是一个极其手工的过程;我会先把照片寄到我家,然后再改地址,送到当地邮局寄出。当我一周接到 1 到 2 个订单时,这只能勉强维持。在英国,我去过的每个地方,邮局排队的情况都很可怕!

随着订单的增加&尤其是在圣诞节前后(约 70%的年度订单来自 11 月/12 月),邮局的冲刺变得过于频繁和紧张。通过谷歌搜索,我了解了直运,即印刷商将订单直接发送给客户的过程。这样,您不需要投资持有任何库存,只需要在自己的商店收到订单时向打印机下订单。

在尝试了几家供应商之后,我找到了一家。他们经营着一个制造中心的国际网络,产品种类繁多,从专业装裱的印刷品到 t 恤衫。在印花方面,我个人一直对质量很满意,我在 Etsy 商店收到的评论也反映了这一点。如果你想自己测试,灵知为新客户提供了不同印刷类型的样品包。

有几种方法可以在 given 上排序。仪表板允许您在在线表格中输入客户的详细信息,上传您的图像文件,然后跟踪您的订单状态。还有一个手动订单表单(我还没有亲自使用过),允许您从导出的 Etsy orders csv 下多个订单。

最强大的选项是 Print API,它允许您使用来自 Etsy API &灵捷 API 的订单详细信息组合,以编程方式下订单并跟踪订单。天才刚刚宣布了他们的 API 的 v4 版本,增加了许多额外的特性,所以现在是时候测试一下了!

下面的代码是用 python 编写的,使用 requests 包和几个支持 csv 文件来自动化整个订购过程。

先决条件

软件:你需要的所有代码都是用 Python 写的,所以你需要把它安装在你的机器上。为了加快速度,我还使用终端(Windows 上的命令提示符)来快速下订单。

账号: Etsy 店铺有一些房源,灵童账号下单。

知识:对 Python 和 API 如何工作的基本理解是很容易的,但是你可以通过使用完整的 GitHub Repo 或拼凑下面的代码片段来获得。

硬件:对于第 2 部分,我使用一个插在电视机后面的 Raspberry Pi 每小时调用一次 API,检查未结订单的状态,尽管我确信有更好的方法可以做到这一点,我们将在后面讨论!

证明

我通常发现这是新项目中最辛苦的部分,但也是最重要的部分之一。当从灵物 API 开始时,您有两个端点可以调用;“沙盒”,即当您创建订单时,没有生产发生,也没有成本。“prodigi”是生产端点,所以只有当您确定要下订单时才使用这个端点。

两个端点都有一个单独的密钥来认证用户,从版本 4 开始,在您进行的调用中只需要 REST API 密钥。我发现在代码的开头使用 if 语句来区分这两者很有用,如下所示:

Etsy 的认证过程有点复杂。你需要创建一个应用程序,将授予你一个关键和秘密。然后,您需要将它们交换为 OAuth 访问令牌和访问令牌密码(总共有 4 个唯一的字符串)。当用您的密钥和秘密交换令牌时,您还需要包含权限范围(您的应用程序需要访问的内容)。出于这个项目的目的,您将需要 transactions_rtransactions_w. 参见下面生成所需令牌的示例脚本。

收集 Etsy 订单详细信息

现在我们已经得到了所有的密钥和秘密,我们可以查询 Etsy API 来返回我们选择的订单的详细信息([order_num]是一个整数,表示未完成的订单,0 表示最近的订单)。您需要将您的 _SHOP_HERE 替换为您的店铺 id,您可以在此处找到。使用 json 包,我们可以解包 API 的响应并收集订单细节。

我指定了一系列必要的(名字,第一行,第二行等等。)和可选的(total,order_date)变量,当我们在 Prodigi API 上下订单时会重用这些变量。我包含了总数和订单日期,因为我将每个订单的信息保存在一个单独的表中,以便以后进行分析。

第 31–35 行有效地映射了灵童和 Etsy 之间的国家代码。Prodigi 要求两个字母的 ISO 代码,而 Etsy 提供整数格式的国家 ID。你可以下载参考我这里用的的表。

第 36–42 行在技术上并不是必需的,但是由于 GB 快递(皇家邮政跟踪递送)在灵吉上只是额外增加了 1 行,所以我选择将所有 GB 订单设置为快递选项,而不考虑他们的 Etsy 递送选项。

现在我们已经获得了所有客户的详细信息,我们需要调用特定的收据来找出他们订购了哪种打印。这是在第 44–47 行完成的。

映射和下单

我们获取收据的调用返回一个对象数组,每个订购的商品一个对象。由此,我们可以收集打印的详细信息,如列表 ID 以及我们在商店中设置的任何自定义变量。在我的情况下,我使用大小(A4,A3 等。)和有框/无框印刷品。

为了在清单 Id 和产品变体之间建立联系,我使用了一个 excel 文件中的映射表(你可以在这里找到一个的例子)。它包括打印的大小&类型,以及到实际图像文件的可共享链接(我将我所有的图像保存到 Google Drive,并允许任何有特定链接的人访问它们,以便图像可以被 gign 获取)。

一旦映射完成,我们就有了下订单所需的所有信息,接下来是时候构建 json 有效负载来发布到灵物 API 并下订单了。下面的大部分键值对使用我们从 Etsy 收据或随后的映射表中收集的信息。完整文档见此处。

有时,客户不会填写地址中的几行,因为在下 Etsy 订单时不需要这些行(第二行地址、州、城市),这就是为什么需要更新这些字段(第 51-59 行)。

所有这些都确认后,第 62 行对灵物 API 进行 POST 调用来下订单。作为响应,您将获得一个状态代码,确认它是否成功或是否有错误。v4 API 的错误消息似乎更详细,这对于检测调用中的任何缺口很有用。然后,您可以继续在灵物仪表盘上查看您的订单。

最后的想法

加速下单的最后一个技巧是将整个代码包装在一个函数中,然后使用终端为您下单。你可以点击查看整个脚本。您可以通过使用 sys.argv[n]来实现这一点,它允许 python 与 terminal 进行交互,并选取您以特定顺序输入的任何变量。中提供路径名的别名。zshrc 文件并下一个新订单就像写etsy 0‘灵童’一样简单!

在第 2 部分中,我们将看看一旦下了订单会发生什么。当订单状态更新,我们需要向客户发送调度通知时,我们如何让 Etsy 和灵捷进行沟通?

如何免费自动化你的 Python 脚本(2021)

原文:https://towardsdatascience.com/how-to-automate-your-python-scripts-for-free-2021-98ac71b0c360?source=collection_archive---------14-----------------------

我将向您展示如何将 Python 脚本设置为在每天的特定时间、每周或每月运行

詹姆斯·哈里森从 Unsplash 拍摄的照片

在这篇文章中,我将向你展示如何为免费自动化你的 Python 脚本。****我之所以强调免费,是因为有很多程序和网站可以在网上为你做这件事,但几乎所有的程序和网站都要求你支付一定的费用来使用它们的应用程序。

因为我知道大多数人不想花这种钱,所以我找到了一种免费的独特方法,这样你就可以自动运行你的 Python 脚本,在每天的某个时间,或者每周,或者每月运行。

这种独特的方式只涉及 2 个简单的步骤。

1.为 Python 脚本创建批处理文件

批处理文件是按顺序处理的命令列表,通常不需要用户输入或干预。要为想要自动化的 Python 脚本创建批处理文件,您需要两条信息。

  1. Python 应用程序的文件路径
  2. Python 脚本的文件路径

我们需要这两条信息,因为批处理文件首先转到我们的 Python 应用程序和启动 Python 的文件路径。然后,它将转到我们的 Python 脚本的文件路径,并在启动的 Python 应用程序中运行该 Python 程序。

要获取 Python 应用程序的文件路径,您需要从最初安装 Python 时开始,转到 Python 在文件中的保存位置。您应该在寻找类似这样的文件。

它还应该有扩展名 python.exe。为了举例说明文件路径应该是什么样子,这是我的 Python 应用程序的文件路径。

  • c:\ Users \ Chris \ Anaconda4 \ python . exe

获得该文件路径后,您需要获得想要自动化的 Python 脚本的文件路径。这应该更容易找到,我将向您展示一个我的文件路径的例子。

  • c:\ Chris \ Documents \ Automate _ Python _ script . py

当你有了这两条信息后,你就需要打开你的记事本,通过你的搜索栏就可以进入。它看起来会像这样..

然后你所要做的就是复制你的两个文件路径,并把它们粘贴到记事本的同一行,中间留有空格。然后,您必须在两个文件路径周围加上引号(“这些是引号”),如果斜线还没有从\改为/的话,请确保将它们更改为。最后,这是你的第一行在记事本中的样子…

在这一行被输入到记事本后,保存记事本,但是你必须改变它给你的扩展名。txt 到。bat** 创建一个批处理文件。假设我想把这个记事本保存为 note1,你可以把它保存为..**

  • 注 1 .蝙蝠

如果你做的一切都是正确的,你的记事本现在应该以 Windows 批处理文件的形式出现,如下…

2.在任务计划程序中设置任务

为 Python 脚本正式创建批处理文件后,现在需要在任务调度器中创建一个任务。

任务计划程序是一个应用程序,你的电脑应该有你的电脑每天运行的所有任务。要访问它,它类似于记事本,因为它应该可以通过您的搜索栏访问。如果你打开了正确的应用程序,它应该是这样的...

要创建新任务,只需在页面右上角的操作选项卡中单击创建基本任务。然后它会要求你为这个任务取一个名字,你可以写任何东西。

要完成创建任务,您需要选择这个新任务的触发器和动作。触发器就是您希望任务开始的时间。

如上图所示,你可以选择每天、每周、每月、电脑启动时触发任务。如果您选择每日、每周或每月,您将转到这些选项设置,在那里您可以设置任务运行的特定时间。

在这里,您可以选择希望任务运行的具体时间

设置好时间后,你可以按下 next,进入 action,它会问你“你希望任务执行什么操作”。选择启动程序,然后单击下一步按钮。你现在应该在一个像这样的窗口上...

这是最后一步,您将选择任务应该运行的程序。同样,我们要运行的程序是我们创建的批处理文件,因此单击 browse 按钮并选择该文件。完成后,您就完成了,可以按“完成”按钮。

恭喜你!如果你做的一切都正确,你的 Python 程序应该会在你设置的日期和时间自动运行。

迷茫?想看这篇文章的视频吗

如果你在阅读这篇文章的时候有一些困惑,你应该看看我在 YouTube 频道上发布的一步一步的教程。

克里斯多夫·唐小蓝

  • 如果你喜欢这个, 跟我上 Medium 了解更多
  • 订阅我的 Youtube 频道: 克里斯多夫·唐小蓝 获取各种数据科学主题的每周内容
  • 让我们连线上LinkedIn

如何用贝叶斯统计避免雨天婚礼

原文:https://towardsdatascience.com/how-to-avoid-a-rainy-wedding-day-with-bayesian-statistics-f17f7a86befe?source=collection_archive---------34-----------------------

你有 162 分钟的空闲时间吗?在一个理想的世界里,我们所有人都会大喊“是!”一起开始消耗本周变量中的每一个项目。毕竟他们都很优秀。唉,我们大多数人都必须做出选择。就像数据科学在最佳状态下帮助人们在正确的时间采取正确的行动一样,我们喜欢指导您的阅读决策。以下是本周必读书目的精选——以及为什么你应该考虑阅读每一本书。

  • 回到基础。如果你是统计学新手,你会想读一读伊内斯·李的关于回归均值的解释,因为它清晰明了,图文并茂。如果你是一个经验丰富的老手,几年前就了解了这个概念,你会想要读 Ines 的帖子,因为它可能会启发你从一个新的角度思考一个常见的话题。

由大卫·霍利菲尔德在 Unsplash 上拍摄

  • (非常)深的潜水。你喜欢婚礼吗?你想了解贝叶斯模型,但不知道从哪里开始?你对柏林春天的天气好奇吗?如果你积极地回答了这些问题中的任何一个(坦白地说,谁不会呢?), Hannah Wnendt 为你准备了一份礼物:她耐心地讲述了她如何比较贝叶斯和频率主义者模型来决定她即将到来的婚礼庆典的最佳日子。
  • 新视觉前沿。医疗领域是深度学习产生最显著现实效果的领域之一。例子: Heather Couture 的概述了最近的进展,允许模型分析大规模、千兆像素大小的组织学图像文件。
  • 新视觉前沿,取两个。变形金刚负责将自然语言处理推向新的激动人心的方向。现在,正如大卫·科科米尼在他对变形金刚“革命”的简单介绍中所展示的那样,我们可以开始在处理图像和视频时使用类似的方法,这也要感谢时代的创造者。
  • 一个警示性的故事——关于传说的故事。现在人们普遍认为,一个出色的数据科学家也必须是一个令人信服的故事讲述者。正如奥斯卡·古德洛在他的(非常精彩的)叙述中所展示的那样,“好故事的诱惑力是一把双刃剑”,它可以诱使数据科学家忽视警告信号,或者迫使数据进入引人入胜但具有误导性的叙述。
  • 选择合适型号的教程。从测试到生产模型是一个令人担忧的时刻;有时候,即使你确定已经检查了所有的方框,事情还是会出错。 Emeli Dral 是来拯救我们的,一步一步地向我们展示如何检查和比较不同的机器学习模型,以确定哪一个将完成这项工作。
  • 有数据支持的性别偏见行动呼吁。即使你已经阅读了几十篇关于女性在数据科学和人工智能领域面临的挑战的文章、文章和推文,你仍然不想错过德尼莎·布莱克伍德对对话的贡献。Denisa 提出了一个又一个有说服力的观点,展示了结构性问题,并以几个可行的想法结束,将该领域引入一个更加公平的视野。
  • 关于人工智能监管未来的对话。几十年来,技术进步的速度远远超过了应该充当其护栏的法律框架。在最近的 TDS 播客节目中,主持人 Jeremie Harris 和法律与技术学者 Josh Fairfield 以谨慎乐观的态度讨论了未来几年的有效监管。
  • 一剂灵感。在我们最新的作者聚焦中,我们采访了博士生 Robert Lange 关于博客的专业(和其他)好处,他在强化学习中获得高级学位的曲折道路,以及挑战、失败的实验和偶尔令人沮丧的挫折如何帮助一名新兴的数据科学家成长。

无论您决定本周与我们一起停留 10 分钟还是 162 分钟,我们都希望您喜欢您的选择——只要您有几分钟时间坐下来休息、呼吸和探索,您就会回来。感谢您的时间、您的好奇心和您的支持。

直到下一个变量,
TDS 编辑器

我们策划主题的最新内容:

入门指南

  • 由阿卜杜拉·法鲁克撰写的引导直观指南
  • 如何在 Python 上一键创建数据可视化作者 Ismael Araujo
  • 非数学家实践教程的内核指南 Luca Prosperi

实践教程

  • 由罗伯特·库伯勒博士讲解的助推机
  • Python 中的音乐:第二部作者凯蒂·何
  • Satenik Safaryan利用迁移学习进行自我监督的语音情感识别

深潜

  • 实用 Python 因果关系:数据科学计量经济学作者 Haaya Naushan
  • Julia 上带跳转的混合整数规划综合研究(第一部分)Ouaguenouni Mohamed著
  • 迁移学习和数据增强由路易斯·罗克应用于辛普森图像数据集

思想和理论

  • 关于神经网络为什么会泛化,平坦度能告诉我们什么?作者克里斯·明加德
  • 21 点:将人工智能应用于网络安全的游戏模型作者史蒂文·麦克埃尔威
  • NLP 的基础直观解释:波束搜索及其工作原理作者 Ketan Doshi

作为一名雄心勃勃的新数据科学家,如何避免精疲力竭

原文:https://towardsdatascience.com/how-to-avoid-burnout-as-an-ambitious-new-data-scientist-ccf44248f4b0?source=collection_archive---------41-----------------------

如果你想成为一名长期成功的数据科学家,避免精疲力尽是最重要的

照片由来自佩克斯的布拉克·科斯塔克拍摄

很难向没有经历过的人描述倦怠。

倦怠可以在不同的人身上以多种方式表现出来,以至于因为害怕评判或缺乏同理心而与他人讨论这样一个抽象的概念会让人感到害怕。

对我来说,倦怠表现为精神疲惫,对工作缺乏热情,无法强迫自己专注于手头的任务而不被更有吸引力的事情分散注意力。在那些日子里,单词在我眼前滚动,没有一丝理解的迹象,我突然有一种冲动,想打电话、打扫房间、做饭、锻炼或做任何与工作无关的事情。

当打扫你的踢脚板听起来比做你的工作更令人兴奋的时候,你知道你已经筋疲力尽了。

当前的忙碌文化几乎使谈论倦怠成为禁忌,然而,如果有什么不同的话,倦怠现在更加普遍,因为我们给自己施加压力,要求自己在工作中做得更多,在生活中做得更多。

不仅如此,作为任何地方的新员工,很自然地会感受到迎接每一个挑战的压力,超额完成项目(尤其是在时间表方面),尽可能多地承担工作。让那个新来的人在你的肩膀上打转会立刻让你陷入一场无法逃脱的精疲力竭的战斗,你很可能会输。

然而,大多数新员工不明白的是,定期耗尽精力会让你很难拥有长久的职业生涯。因此,在您开始作为数据科学家的激动人心的新职业时,养成一些帮助您避免精疲力竭的习惯对您的健康和未来的成功至关重要。

当你完成了工作,你就完成了工作。

我全心全意支持 WFH 运动,尤其是在科技行业。然而,我也注意到在家工作有一些严重的负面影响,这些影响并不容易发现。

最大的罪魁祸首是在你完成一天的工作后不能停下来。这体现在几个方面,包括在你完成一天的所有任务后继续寻找工作,在晚上 8 点回复电子邮件,即使你已经工作了整整 8 小时,也要为第二天的任务开个头。

无需通勤上班就能坐在办公桌前的能力,让人们太容易被工作吸引。

因此,当你完成了一天的所有任务后,你必须结束这一天。

例如,我早上 6:30 开始工作,这通常会导致我在下午 2-3:30 完成当天的所有任务。从那以后,我完全停止工作。为了确保我不会再回到工作中,我会花时间去锻炼,为媒体写一篇文章,打扫卫生,或者准备晚餐。此外,我会确保我的周末 95%不工作,这样我就可以花时间充电,为下周做准备。

通过为自己设定时间或严格列出一天的任务清单,并确保你在下班时严格遵守纪律,你将能够保持健康的工作和生活平衡,避免精疲力竭。

照顾好你的身体,包括身体和精神。

尽管这个建议被反复提及,许多人仍然没有把他们的精神和身体健康放在首位。令人惊讶的是,不健康的身体和精神会导致人们对工作失去信心,对生活总体上不太满意。

虽然已经多次证明,健康的身心是工作和生活中成功的必要条件,但人们往往觉得这些事情太耗费时间,而这些时间本可以“更好地花在”工作上。

这就是为什么如此多的 FAANG 公司提供夜间健身房,健康的午餐,以及员工可以在白天冥想几分钟的空间。虽然是的,这些公司完全使用这些策略,所以他们的员工几乎住在办公室,他们也提供这些设施,所以他们的员工可以在精神和身体上都处于最佳状态。换句话说,健康的员工是高效的员工。

作为一名新的数据科学家,养成一些健康的习惯很重要,这样当工作变得疯狂时,你就有一些常数可以帮助你避免筋疲力尽,并保持健康和高效。从坚持适合你的锻炼计划开始,尝试通过尝试饮食计划或订购预先计划的餐盒来健康饮食,尝试通过冥想、瑜伽或写日记来给自己留出一些精神上的恢复时间。

倾听你的能量水平,让它们指导你的一天。

虽然你的工作周需要在特定的日子完成特定的任务是很自然的,但尽可能倾听你身体的能量水平是很重要的,这样你才能在一周中尽可能地高效。

通过倾听你的身体,你可以在精力充沛的时候计划更紧张的工作任务,当你精力和注意力不集中的时候可以完成更简单的任务。

例如,数据分析或机器学习算法的实现应该在你感觉休息好、注意力集中的日子里进行。当你感到疲倦的时候,试着把注意力集中在简单的任务上,比如回复邮件或者运行不需要太多输入的自动化任务。这种方法也可以用来计划你的一天,在早上你更专注的时候完成更紧张的任务,在下午你更累更不专注的时候完成不太紧张的任务。

围绕你的能量水平来计划你的每周和每天的任务可以帮助确保你的工作不会感觉像是每天的苦差事,并且通过帮助你感觉你的日子是可管理的并且不会过度劳累来帮助你避免精疲力竭。

让空闲时间成为你日程表中的优先事项。

我过去一直认为,任何不致力于做有成效的事情的时间都是浪费时间。如果我不是每时每刻都富有成效,我会感到内疚,我觉得这给了我一种不健康的时间关系。

过了很长时间,我才最终意识到空闲时间实际上是一种富有成效的时间利用方式。

作为一名新员工,让空闲时间成为你日程安排中的优先事项可能会让人感到不可接受,因为害怕看到其他人工作时占用个人时间,或者让你的老板知道你也是人,需要休息。然而,意识到你的幸福和你所做的工作一样重要,是尊重你自己,与工作保持健康关系,避免精疲力竭的重要一步。

对于那些每天日程繁忙的人来说,安排一天中的空闲时间是有好处的。不管是这里的一个小时还是那里的十分钟,给自己时间去做任何你想做的事情,可以减轻你大脑的负担,可以给你短暂的充电,让你度过一天。

利用假期、远程工作和灵活的工作时间。

人们遭受倦怠的一个常见抱怨是,他们觉得自己陷入了每天做同一件事的窠臼。

WFH 运动的美妙之处在于,它让工作世界向远程工作和弹性工作时间开放。此外,在有时间退一步审视工作生活之后,许多人开始认识到利用分配给他们的假期的重要性。

只要利用分配给你的假期时间,尽可能远程工作,利用你最有效率的时候工作,就可以很容易地避免精疲力竭。

求助。

“没有人是一座孤岛。”—许多数据科学家最喜欢引用的一句话

当涉及到在数据科学领域工作时,向他人寻求帮助有时会让人感到害怕,特别是当你需要回答的问题似乎微不足道或不值得他们花时间时。然而,大多数新数据科学家忘记的是,他们的上级都是从初级数据科学家开始的,他们也必须提出问题来解决问题。

作为新员工,你可能会觉得需要直面每一个挑战,尽可能多地自己解决问题。这通常会导致你加班加点地碰壁,因为谷歌拒绝给你解决问题所需的正确答案。当你突然开始觉得你对问题没有任何答案时,这是一种肯定会耗尽精力的方式,骗子综合症就出现了。

相反,通过在你需要的时候寻求帮助,你不仅减轻了自己追求完美的压力,还向你的雇主展示了你在需要的时候能够寻求帮助。信不信由你,寻求帮助不是软弱的表现,通常被视为一种令人钦佩的品质。

追求一个爱好,参加志愿者活动,或者做一些有激情的项目。

在我做副业和志愿者之前,除了工作,我没有什么可以专注的。现在,我发现拥有这些渠道让我更享受我的工作,甚至让我在一周中更有效率。

世界上最成功的人都有爱好是有原因的。在职业生涯的任何阶段取得成功都会付出代价,这就是为什么比尔·盖茨打桥牌,梅丽尔·斯特里普编织,史蒂夫·沃兹尼亚克打赛格威马球,玛丽莎·梅耶尔烘焙。

追求一个爱好,参加志愿者活动,或者从事一个激情项目,这些都可以让你的大脑得到休息,避免精疲力竭。

最后的想法。

数据科学家的工作,就像科技领域的任何工作一样,也不是没有压力。面对竞争激烈的工作环境、利益相关方不切实际的期望,以及为复杂问题提供正确答案的必要性,数据科学家几乎注定会在职业生涯的某个时刻进入精疲力竭阶段。

通过实施上面列出的一些或所有提示,新的数据科学家可以帮助自己避免精疲力竭,并为自己在数据科学领域的漫长而快乐的职业生涯做好准备。

如何避免数据科学服务中的云账单冲击

原文:https://towardsdatascience.com/how-to-avoid-cloud-bill-shock-in-data-science-services-e2ade5fae2a8?source=collection_archive---------28-----------------------

行业笔记

使用 ngrok 在不到 30 秒的时间内构建互联网服务器的方法

由雅各布·本特辛格在 Unsplash 上拍摄的照片

故事开始于大约一年前,当时我构建了一个名为 Owl 的单词相似度服务。我还创建了一系列 REST API 供社区使用这项服务。API 可在这里获得。这是我的一个爱好项目。就我想让它对数据科学社区可用而言,我不想为在云基础架构上托管它支付太多费用。在本文中,我想与您分享如何在您的本地计算机上托管数据科学服务,并在不到 30 秒的时间内将其公开到互联网。我没有夸大其词。如果你想了解更多关于 OWL API 的知识,你可以阅读下面的文章。

—远离大牌。

首先,我在谷歌云平台上部署了这项服务。我在 GCP 的经历比 AWS 更好。对不起 AWS 爱好者,这是我的亲身经历。与 AWS 相比,GCP 的用户界面很友好,他们的文档也足够好。然而,GCP 不是为主持爱好项目而设计的。每月的账单来了,我发现在社区项目中使用 GCP 是没有意义的。

当涉及到一个爱好或者一个社区项目的时候,远离名人。他们每月的账单对你不利!

—在您能够轻松处理成本之前,不要安定下来!

我决定把我的托管服务从 GCP 转到 OVH,一家提供各种网络服务的法国云计算公司。我使用 OVH 成功地将云成本削减了一半。然而,仍然有一些隐性成本让我感到惊讶,每月账单对我来说仍然没有意义。我爱上了我的单词相似度服务,我想继续努力让它变得越来越好。所以,我想让它在网上保持活力。问题是我怎样才能减少每月的账单?

如果你想让一个数据科学服务在互联网上长期存在,不要在你不能轻松管理的每月账单上结算!

—将您的计算机视为一个机会!

我决定把我的电脑变成互联网服务器。然而,我不想花太多时间来配置东西。我做了一点研究,发现了一个名为“ ngrok ”的库。在他们的网站上,他们声称“ Ngrok 通过安全隧道将防火墙后的本地服务器暴露给公共互联网。“起初,我无法猜测我能快速轻松地做到这一点。但是,我决定试一试。

当您将本地计算机转变为互联网服务器时,您将无法获得与云基础架构相同的服务级别。您的本地计算机不时会重新启动,您的服务可能会在短时间内无法访问。然而,你无法相信使用这项技术可以节省多少钱。我最终将每月的账单从 100 多美元减少到了 10 美元!是不是很酷?

你无法相信使用 ngrok 可以节省多少钱。我把每月的托管费用减少了十分之一!

—我如何使用 ngork 构建互联网服务器?

我用了不到 30 秒的时间和 3 个步骤就把我的电脑变成了互联网服务器。我没有夸大其词!让我们假设您有一个服务在localhost上启动并运行。您可以通过运行 docker 并在port 80上公开它来确保 web 服务在localhost可用。这部分我不想描述了。现在的问题是如何通过 3 步把 **localhost** 暴露在公众互联网上。这 3 个步骤简单如下:

  1. 下载ngrok.zipunzip /path/to/ngrok.zip
  2. 运行./ngrok authtoken YOUR_OWN_TOKEN
  3. 运行./ngrok http 80

当你在他们的网站上注册时,他们会给你一个下载软件包的链接。注册他们的服务时,他们还会为您提供YOUR_OWN_TOKEN。运行./ngrok http 80之后,ngrok 服务在ngrok.io域上为您的项目创建一个专用的 URL,看起来像下面的链接。

[http://YOUR_DEDICATED_SUBDOMAIN.ngrok.io/](http://d9500fdc2530.ngrok.io/)

你的服务现在在互联网上对每个人都是可利用的。是不是很神奇?

—最后的话

正如我所说的,这种服务不如专用服务器可靠,并且与特定的云解决方案相比不可扩展。然而,让一个数据科学项目长期存活下来是如此的方便和实惠。你知道机器学习引擎有很高的计算负担。将计算和托管的成本加在一起,你可以想象使用 ngrok 技术将你的电脑作为互联网服务器是多么经济!

**“Ngrok is an amazing technology!”**

感谢阅读!

如果你喜欢这个帖子,想支持我…

  • 跟我上
  • 亚马逊 上查看我的书!
  • 成为 中的一员
  • 连接上Linkedin
  • 关注我 推特

https://pedram-ataee.medium.com/membership

在评估机器学习模型的性能时如何防止数据泄漏

原文:https://towardsdatascience.com/how-to-avoid-data-leakage-while-evaluating-the-performance-of-a-machine-learning-model-ac30f2bb8586?source=collection_archive---------25-----------------------

本文讨论了在评估模型性能时的数据泄漏问题以及避免数据泄漏的方法。

图片由克里斯里德在 Unsplash 上拍摄

当来自训练集的数据传递到验证/测试集时,模型评估期间会发生数据泄漏。这导致模型对验证/测试集的性能估计有偏差。让我们通过一个使用 Scikit-Learn 的“波士顿房价”数据集的例子来理解它。数据集没有缺失值,因此,为了更好地演示数据泄漏,随机引入了 100 个缺失值。

作者图片

在上面的代码中,“X_train”是训练集(用于 k-fold 交叉验证),而“X_test”用于对看不见的数据进行模型评估。上述代码是一个带有数据泄漏的模型评估示例,其中,用于估算缺失值的模式(strategy = ' most _ frequent ')是在“X_train”上计算的。同样,用于缩放数据的平均值和标准偏差也是使用“X_train”计算的。在 k 倍交叉验证之前,对 X_train 的缺失值进行估算,并对“X_train”进行缩放。

在 k 折叠交叉验证中,“X_train”被分成“k”个折叠。在 k 折叠交叉验证的每次迭代中,其中一个折叠用于验证(姑且称之为验证部分),其余折叠用于训练(姑且称之为训练部分)。每次迭代中的训练和验证部分已经使用“X_train”上计算的模式估算了缺失值。同样,它们已经使用“X_train”上计算的平均值和标准偏差进行了缩放。这种插补和缩放操作导致来自“X_train”的信息泄漏到 k 倍交叉验证的训练和验证部分。这种信息泄漏可能导致验证部分的模型的有偏差的性能估计。下面的代码显示了一种通过使用管道来防止它的方法。

作者图片

在上面的代码中,我们在管道中包含了估算器、缩放器和回归器。在这种情况下,“X_train”被分成五份,在每次迭代中,管道使用训练部分来计算用于估算训练和验证部分中缺失值的模式。类似地,用于缩放训练和验证部分的平均值和标准偏差也在训练部分上计算。这一过程消除了数据泄漏,因为在 k 倍交叉验证的每次迭代中,在训练部分计算插补模式和缩放的均值和标准差。这些值用于估算和缩放 k 重交叉验证的每次迭代中的训练和验证部分。

我们可以看到在有和没有数据泄漏的情况下计算的训练和验证 RMSEs 的差异。由于数据集很小,我们只能看到它们之间的细微差别。对于较大的数据集,这种差异可能会很大。验证 RMSE(有数据泄漏)在看不见的数据上更接近 RMSE 只是偶然的。

因此,使用管道进行 k-fold 交叉验证可以防止数据泄漏,并对模型在看不见的数据上的性能提供更好的估计。

如何在数据科学工作中避免挫折并保持快乐

原文:https://towardsdatascience.com/how-to-avoid-frustration-and-stay-happy-in-your-data-science-job-d4c70c6a0ee9?source=collection_archive---------30-----------------------

通过降低复杂性来增加幸福感

瓦尔瓦拉·格拉博瓦在 Unsplash 上的照片

这是一个错误……

开始解决一个新的机器学习问题是如此令人兴奋!这时,我们内心深处的书呆子才真正觉醒,我们可能会对自己说:“终于有了一个新的数据集,在这里我可以尝试我在一篇媒体文章中看到的这种新的神经网络架构,也许我可以用这个大家最近都在谈论的新的 ML 库来实现工作流,还有……”

有时,当我们开始一项新的 ML 任务时,感觉我们又回到了童年,不是吗?我们可以好奇,探索,尝试新事物,可能会失败,学习如何重新走路,最终用这种酷的新方法给我们的同事,客户或老板留下深刻印象!

在我作为数据科学家的最初几年,我有过几次这种激励,但经常很快它导致了很多挫折、压力和自我怀疑,我开始问自己:“ 使用我已经熟悉的框架应用一个更简单的模型不是更容易吗?” 我的模型工作不正常,这个新库没有我解决问题所需的所有功能,而且每次迭代都要花费很长时间来提高准确性,因为我的模型太复杂了,数据量太大了!—听起来很熟悉?如果没有,也许这篇文章不适合你,但是如果你曾经经历过类似的问题,我有一些建议给你!

如何避免压力?

如果事情没有按预期进行并且时间紧迫,沮丧、压力和自我怀疑是一种自然反应。但是我们如何避免这种情况呢?

选择一:永远不要尝试新事物,坚持自己已经知道的,不要冒险!

听起来很简单,对吗?但这听起来也像是你是一个机器人,没有创新,对工作没有激情!你可能会很快感到沮丧,因为进步是我们前进的动力,对吗?所以这个选项似乎不太可行。还有别的吗?

选项 2:从简单开始,建立一个基线,逐渐增加复杂性,分清轻重缓急!

听起来不错,但这意味着什么呢?好吧,让我们一步一步地完成这些指令,如果你决定在开始下一个机器学习任务时选择这个选项,你将有希望以一个伟大的结果结束,最重要的是,在做这件事的时候感到快乐!

善良好奇的在 Unsplash 上拍摄的

开始简单

也许你已经经历过了:自从你开始着手一项新的令人兴奋的 ML 任务后,几天或几周过去了,你被要求展示你的初步发现。然而,到目前为止你所能展示的,只是一些没有不正确的轴标签的探索性数据图(因为谁有时间做这些呢?)和一些不工作的代码,由于一个新的错误消息,今天早上弹出,你可以发誓它不存在昨天晚上!即使它在运行,你也不会对呈现结果感到舒服,因为准确率如此之低,你真的不知道为什么。如何避免这种情况?

建立基线

当你开始处理一个新问题时,你想做的第一件事就是建立某种基线!基线可以是多方面的:

  1. 一个简单的模型

你在做二元分类问题吗?完美!然后简单地从一个逻辑回归开始!这里的关键信息是:不要羞于从最简单的方法开始!实际上,我强烈建议你这么做!为什么?因为这给了你下一步很好的起点和参考。从尽可能不复杂的地方开始,看看它在哪里可行,在哪里不可行。您将更好地理解您的数据,这将有助于您在未来的步骤。此外,你将有一个成功的第一次体验,并有一个基准来比较你未来的模式。

2。基于规则的方法(快速和肮脏的实施)

找到一个合适的简单模型开始,有时会很难。假设您想为电子邮件编写一个垃圾邮件过滤器:您选择哪种方法和模型作为基线?那么,为什么不从一个简单的基于规则的方法开始呢?做一个快速的探索性分析,找到看起来具有高度预测性的特征和模式,然后手动写下一系列对数据进行分类的 if-else 语句。例如,这可以基于平均文本长度(字数)、特定单词的频率(例如“信用卡”)等。获得一个快速简单的基线很重要!你会有一种成就感,并设置下一次迭代中你可以尝试超越的第一个标准——这里的关键哲学是持续改进!

根据我的经验,一个好的基线通常已经执行了可能的最佳模型的大约 90%(当然取决于用例)。在我看来,用一个对我来说可以解释的简单解决方案达到 90%的速度,比花几天或几周时间微调一个难以解释、运行速度较慢且性能仅提高 2%的神经网络更令人印象深刻。

一旦你建立了一个基线,你就有东西可以展示给你的同事和客户了。你将对数据和潜在问题有更好的理解,这将减轻你的压力,因为你已经有了第一个可行的解决方案!太好了!试着从你的同事和客户那里获得一些反馈,看看这与他们的经历和期望相比如何。当您试图改进您的模型时,这些见解将在下一次迭代中证明它们是非常有价值的。当你的同事或客户没有任何有价值的输入时,试着去找文献,将你的第一个结果与现有的解决方案进行比较。在开始改进模型之前,请确保使用了正确数量的数据(见下文)!

数据子集

过去我给自己挖过几次的另一个坑是,在整个数据集上执行我的测试和建模。不,我这里说的不是培训和测试集的重要性,而是精简的重要性!作为一名数据科学家,拥有大量数据(通常)是一个很好的职位,但当你开始解决你的问题时,不要犯一开始就使用所有数据的错误。

这是一个陷阱——摘自 giphy.com

您的数据集中的每一条记录,都会使改进和测试运行的每一次迭代变慢。开始时,通过在尽可能少的数据记录上设置您的机器学习工作流和模型架构,只是为了有一个运行的概念证明,即使模型性能(就准确性而言)很差!

一旦您的管道开始工作,持续增加您的数据集大小,并查看模型性能是否在提高。如果不是这样,那么很可能您的管道有一些不可预见的错误。不使用整个数据集,将让你迭代和调试更快!

将你的训练集分成一个易于管理的小数据集。如果您使用结构化的表格数据,每个类 30 个样本就足够让您入门了。如果您处理结构化数据,如图像,也许一两张图像就足以建立一个概念证明。

逐渐增加复杂性

蒂莫·沃尔茨在 Unsplash 上的照片

一旦你有了基线,就该逐步完善你的模型了!最重要的是,逐渐做到这一点不要一次改变太多参数!这个真的很难懂,我知道!老实说,我自己很少坚持这个原则,但是我们应该这样做:

当我们转向越来越复杂的模型时,理解为什么增加的复杂性会起作用是很重要的!

更复杂意味着更多的活动部件。我们一次做出的改变越多,就越难跟踪到底是什么改变导致了改进!“是我添加的新功能还是我调整的超参数?”

由于改变太多太快,我们可能会以一种黑盒的形式结束,这种黑盒看起来工作得很好,但同时失去了可解释性,这阻碍了未来的改进。许多数据科学家似乎遵循的策略是增加模型的复杂性和参数,直到模型开始过度拟合。然后,他们通过实施某种正规化来阻止这种情况的发生。然而,我们应该始终努力理解我们添加的复杂性是如何改进模型的,以及它是否真的需要。

我在 MLCMU 网站上找到一句话总结了这一点:

“在设计一个新模型时,我们应该时刻意识到,我们不是为了复杂而构建一个复杂的模型,而是为了它的表现力。我们无法在直觉和理论层面解决这个问题,这是我们最终需要偿还的一笔智力债务。”

区分工作的优先顺序

安德鲁·西曼在 Unsplash 上拍摄的照片

在文献中,这通常被称为“找到瓶颈”。机器学习模型通常有很多螺丝钉,我们可以用来调整和提高性能。然而,由于缺乏了解或错误的优先顺序,许多数据科学家专注于错误的参数进行调整,浪费了大量时间来改进错误的东西。

然而,最有趣的事情是,我们经常知道我们正在调整的螺丝不是最重要的,但是我们一直在摆弄(不重要的)细节,只是为了让自己忙起来,这样我们就不必处理更大的问题。

那么我们如何找到这个神奇的螺丝钉呢?一种方法是,避免过于复杂的工作流程(参见上一章)。当我们的模型很简单时,我们通常很好地理解为什么它不起作用,以及如何改进它的性能。然而,当事情变得越来越复杂时,我们就失去了这种全局观念,开始猜测、转来转去、推来拉去,期望最终会发生一些事情来解决我们的问题!尽量避免这种“技术”,因为它经常会导致挫折和更复杂的模型。相反,试着花些时间在错误分析上!

误差分析

当您不知道为什么您的模型表现不佳时,请尝试查看被您的模型错误分类的数据点(用于分类)或显示最大残差(用于回归)。有时这些观察值是异常值,但通常(如果你观察足够多的数据点)你会观察到一种模式,这种模式会让你更好地理解正在发生的事情:也许错误分类的数据点都属于同一类?如果您有多个数据源,也许它们都来自某个返回有缺陷数据点的传感器?也许他们比其他人表现出更多的噪音?

此外,重要的是要知道人类在这些任务上的表现如何,或者更一般地说,该任务的最大预期精度(例如基于文献)是多少。如果你有一个关于理论上什么是可能的准确性的参考,这将有助于你正确地进行优先排序。

照片由科尔顿鲟鱼在 Unsplash 上拍摄

作为一名数据科学家,快乐生活的信息

  • 从一个简单的模型作为基线开始。这有助于更好地理解数据,给你成就感。
  • 不要害怕使用简单的方法让你开始。它们是未来改进的伟大基准。
  • 逐渐向更复杂的方向发展。一次只能更改一个参数。
  • 不要增加不必要的复杂性。只有当你能解释为什么需要它时,才增加复杂性。
  • 将您的数据子集化,这使您能够更快地迭代您的模型并修复错误。
  • 分清工作的轻重缓急!
  • 通过彻底的错误分析来分析模型的性能和评估优先级。

更多材料:

  • 1.基线。https://blog.ml.cmu.edu/2020/08/31/3-baselines/T2
  • 2.Emmanuel Ameisen,构建机器学习驱动的应用https://Christopher GS . com/Machine % 20 Learning/2019/03/30/deploying-Machine-Learning-Applications-in-shadow-mode/
  • 3.吴恩达。Coursera-deep Learning 对生产中机器学习的介绍。AIhttps://www . coursera . org/learn/introduction-to-machine-learning-in-production

如何避免熊猫的记忆错误

原文:https://towardsdatascience.com/how-to-avoid-memory-errors-with-pandas-22366e1371b1?source=collection_archive---------0-----------------------

使用中型和大型数据集时缩放熊猫的一些策略

斯蒂芬妮·克莱帕奇在 Unsplash 上拍摄的照片

TL;如果你经常用熊猫耗尽内存或者有代码执行缓慢的问题,你可以通过测试手动方法来自娱自乐,或者你可以使用 Terality 在 5 分钟之内解决它。我不得不艰难地发现这一点。

上下文:探索未知数据集

最近,我打算从一个流行的视频游戏中探索一个包含 720,000 行和 72 列的数据集:这个想法是为了发现玩家的策略中是否有任何一致的模式。但是由于内存错误,我花了更多的时间试图加载数据,而不是实际探索数据。我很清楚数据分析的 80/20 法则,你的大部分时间都花在探索数据上——我对此没意见。我一直认为,一个新的数据集就像探索一个新的国家,有它自己的背景和习俗,你必须破译,以便解释或发现一些模式;但是在这种情况下,我甚至不能开始工作。

作者图片

当我的数据准备好被处理时,我开始遇到一些问题,因为一些熊猫功能需要比我的机器可用的内存更多的内存来运行。例如,当我想对一列进行排序时,内存不足。鉴于这不是我第一次遇到这种情况,我应用了常用的技术来解决这个问题。首先,我将解释在我发现 Terality 之前我试图做什么来解决这个问题。

策略 1:加载较少的数据(子采样)

解决这类问题的一个策略是通过减少数据集中的行数或列数来减少数据量。然而,在我的例子中,我只加载了 20%的可用数据,所以这不是一个选项,因为我会在我的数据集中排除太多重要的元素。

策略 2:垂直扩展

如果您不能或不应该使用更少的数据,并且您有缺乏资源的问题,您有两个选择:纵向扩展,这意味着向您的环境添加更多的物理资源(在这种情况下是更多的 RAM )(即在一台更大的计算机上工作),或者横向扩展,这意味着将问题分配到几个更小的、协调的实例中。垂直缩放更容易,因为你只需将 插入新硬件并以与之前相同的方式玩 ,只是更快更好。

我以前使用 Google Colab 作为我的默认选项来垂直扩展我的资源。它提供了一个类似 Jupyter 的环境,免费提供 12GB 的 RAM,对时间和 GPU 的使用有一些限制。由于我还不需要执行任何建模任务,只需要一个简单的 Pandas 探索和一些转换,这看起来是完美的解决方案。但是不行,熊猫在第一次操作时就耗尽了内存。

作者图片

策略 3:修改数据类型

鉴于垂直扩展还不够,我决定使用一些辅助技术。第一个是通过修改用于映射一些列的数据类型来减小数据集的大小。给定某种数据类型,例如 int64,python 会分配足够的内存空间来存储-9223372036854775808 到 9223372036854775807 范围内的整数。在阅读了数据的描述之后,我将数据类型更改到最小,从而将数据集的大小减少了 35%以上:

作者图片

作者图片

应用这种技术时要小心选择:有些数据类型不会增加内存大小,事实上,它甚至会使情况变得更糟。一个常见的建议是将对象类型改为分类,但是,在我的例子中,它抵消了我以前的收获:

作者图片

策略 4:横向扩展

水平扩展,基本上意味着添加更多的机器,将需要我将代码分发到多个服务器上。这是一个棘手的问题,通常由 map-reduce 或 Spark 解决;但是我不知道有什么解决方案可以轻松地为熊猫的代码做到这一点。一些开源解决方案可能会有所帮助,但是它们没有一些 Pandas 的方法,不提供相同的语法,并且它们的范围有限。

当我在谷歌上搜索新的技巧时,我发现了真实度。看起来他们是街区的新成员为这类问题提供了一个有趣的替代方案:管理熊猫的水平伸缩。换句话说,似乎 Terality 在幕后产生了一个机器集群,将该集群与环境连接起来,并在新的集群中运行代码。这是完美的,因为从分析师的角度来看它是隐藏的,并且不需要用新的硬件升级本地环境来修改数据或代码。或许你可以在这篇中型文章中更好地了解他们的报价。

在一个简单的入职流程之后,我准备测试这种方法。令我惊讶的是,以前在我的本地和 Google Colab 环境中失败的加载和合并操作运行得更快,并且没有任何 Terality 问题。此外,鉴于他们目前处于私人测试阶段,我不需要支付任何费用。Terality 团队对其产品的其他一些大胆声明包括:

  • 执行 Pandas 代码的速度提高了 100 倍,即使是在大型数据集上
  • 全面支持熊猫 API(方法、集成、错误等)。)
  • 节省基础设施成本

我的用例不够大,不足以测试所有这些功能,我也不打算在同一领域用其他工具建立一个基准。但是,使用私人测试帐户,我通过 Terality 完美地处理了数据集。您可以在下面的屏幕截图中查看记录的加载和合并时间:

作者图片

除了惊人的速度(超过 100GB 的合并输出需要 1 分 22 秒)之外,唯一的区别是 dataframe 是一个 terality.DataFrame。集成和设置花费了不到五(5)分钟,我只需要从 pypypy 安装他们的客户端库,然后用 import terality as pd 替换 import pandas as pd,其余的代码根本不需要任何更改。最后,使用 Terality 给了我几个好处:

  • 超级简单的设置
  • 没有学习曲线—不需要更改任何代码
  • 即时和无限的可扩展性
  • 没有需要管理的基础设施
  • 更快的 pandas 执行速度(但是,我需要对此进行基准测试)

我很想通过处理大于几个 GB 的数据集来测试这个工具的局限性,比如像新冠肺炎开放研究数据集这样的大型公共数据集。我的下一步将是测试对 pandas 代码执行的 100 倍改进是否是合理的。最后,在没有设置和管理负担的水平集群中运行熊猫的想法不仅对独立数据科学家有吸引力,对更复杂的或企业用例也有吸引力。

结论

有许多用例有足够的数据要处理,可以打破熊猫的本地或云环境。像许多其他数据科学家一样,我尝试了几种编码技术和工具,然后尝试了一种外部解决方案,获得了更好的结果。你现在应该试试 Terality,看看它是否也是解决你的熊猫记忆错误的合适工具。你只需要在他们的网站上联系他们的团队,他们会指导你完成整个过程。

如何在 Python 中平衡数据集

原文:https://towardsdatascience.com/how-to-balance-a-dataset-in-python-36dff9d12704?source=collection_archive---------0-----------------------

性能改进

不平衡学习 Python 包的快速教程

作者图片

本教程属于系列如何提高一个机器学习算法的性能。在本教程中,我处理平衡。平衡数据集是指每个输出类(或目标类)由相同数量的输入样本表示的数据集。可以通过利用以下技术之一来执行平衡:

  • 采样过密
  • 欠采样
  • 类别权重
  • 门槛。

在本教程中,我使用了imbalanced-learn库,它是scikit-learn的 contrib 包的一部分。更多详情请点击此链接。

所有代码都可以在我的 Github 库上找到。

数据导入

在本教程中,我使用的是这个数据集,它包含了一些食谱和它们的原产国。

首先,我通过pandas库的read_csv()函数读取数据集。然后,我通过指定菜肴是否是印度菜来构建目标类。

import pandas as pddf = pd.read_csv('[https://nyc3.digitaloceanspaces.com/ml-files-distro/v1/classification/data/recipes.csv'](https://nyc3.digitaloceanspaces.com/ml-files-distro/v1/classification/data/recipes.csv'))
df['is_indian'] = (df.cuisine == "indian").astype(int)
df.head()

作者图片

我通过value_counts()计算每个目标类的记录数。我注意到数据集是不平衡的。

df['is_indian'].value_counts()

它给出了以下输出:

0    36771
1     3003
Name: is_indian, dtype: int64

作为输入特征,我使用由配料列表给出的 TFIDF 值的矩阵。

from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
matrix = vectorizer.fit_transform(df.ingredient_list)X = matrix
y = df['is_indian']

现在,我将数据集分为训练集和测试集。我将测试集的大小设置为整个数据集的 30%。然后,我通过使用Counter()函数打印包含在collections包中的每组样本的数量。

from sklearn.model_selection import train_test_split
from collections import CounterX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)
print(f"Training target statistics: {Counter(y_train)}")
print(f"Testing target statistics: {Counter(y_test)}")

它给出了以下输出:

Training target statistics: Counter({0: 25727, 1: 2114})
Testing target statistics: Counter({0: 11044, 1: 889})

模型结构

现在,我将使用不同的平衡技术来训练和测试决策树算法。我定义了一个名为build_and_test()的函数,每个平衡技术都会调用这个函数。该函数接收训练输入X_tr、测试输入X_te、训练输出y_tr、测试输出y_te、将由类权重技术使用的class_weight参数和将由阈值技术使用的threshold参数作为输入。
此外,build_and_test()功能执行以下操作:

  • 建立并绘制主成分分析( PCA ),显示类别分布
  • 构建并拟合模型
  • 通过计算评估指标来测试模型
  • 计算最佳阈值,在阈值的情况下,技术
  • 使用scikit-plot库绘制指标。
  • 打印分类报告
  • 返回最终组合图的指标。

绘制的指标包括精度/召回率、累积增益和提升曲线。

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_curve, auc, roc_auc_score
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.metrics import classification_reportfrom scikitplot.metrics import plot_roc
from scikitplot.metrics import plot_precision_recall
from scikitplot.metrics import plot_cumulative_gain
from scikitplot.metrics import plot_lift_curvefrom numpy import argmax
import numpy as npdef build_and_test(X_tr, X_te, y_tr, y_te, class_weight=None, threshold=False):

    # Build and Plot PCA
    pca = PCA(n_components=2)
    pca.fit(X_tr.toarray())
    X_pca = pca.transform(X_tr.toarray())plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y_tr, cmap=plt.cm.prism, edgecolor='k', alpha=0.7)
    plt.show()

    # Build and fit the model
    if class_weight:
        model = DecisionTreeClassifier(class_weight=class_weight)
    else:
        model = DecisionTreeClassifier()
    model.fit(X_tr, y_tr)

    # Test the model
    y_pred = model.predict(X_te)
    print('Precision score %s' % precision_score(y_te, y_pred))
    print('Recall score %s' % recall_score(y_te, y_pred))
    print('F1-score score %s' % f1_score(y_te, y_pred))
    print('Accuracy score %s' % accuracy_score(y_te, y_pred))

    y_score = model.predict_proba(X_te)
    fpr0, tpr0, thresholds = roc_curve(y_te, y_score[:, 1])
    roc_auc0 = auc(fpr0, tpr0)

    # Calculate the best threshold
    best_threshold = None
    if threshold:
        J = tpr0 - fpr0
        ix = argmax(J) # take the value which maximizes the J variable
        best_threshold = thresholds[ix]
        # adjust score according to threshold.
        y_score = np.array([[1, y[1]] if y[0] >= best_threshold else [0, y[1]] for y in y_score])

    # Plot metrics 
    plot_roc(y_te, y_score)
    plt.show()

    plot_precision_recall(y_te, y_score)
    plt.show()

    plot_cumulative_gain(y_te, y_score)
    plt.show()

    plot_lift_curve(y_te, y_score)
    plt.show()

    # Print a classification report
    print(classification_report(y_te,y_pred))
    return roc_auc0,fpr0,tpr0, best_threshold

不平衡数据集

首先,我计算不平衡数据集的性能。从主成分分析图中,我注意到红色类是主要代表的。

roc_auc_imb,fpr_imb,tpr_imb, _ = build_and_test(X_train, X_test, y_train, y_test)

作者图片

作者图片

作者图片

作者图片

作者图片

另外,build_and_test()函数返回分类报告:

precision    recall  f1-score   support

           0       0.98      0.98      0.98     11044
           1       0.80      0.80      0.80       889

    accuracy                           0.97     11933
   macro avg       0.89      0.89      0.89     11933
weighted avg       0.97      0.97      0.97     11933

对最小的类进行过采样

过采样是一种将最小类别的样本数量增加到最大类别的技术。这是通过生成合成样本来完成的。可以应用不同的技术来对类进行过采样。在本教程中,我将使用RandomOverSamplerSMOTEimbalanced-learn包还提供了其他技术,比如 ADASYN 和 Rose。所有的过采样器都提供了一个名为fit_resample()的函数,该函数接收X_train输入变量和y_train输出变量,并分别返回过采样的输入和输出变量X_resy_res

from imblearn.over_sampling import RandomOverSampler
over_sampler = RandomOverSampler(random_state=42)
X_res, y_res = over_sampler.fit_resample(X_train, y_train)
print(f"Training target statistics: {Counter(y_res)}")
print(f"Testing target statistics: {Counter(y_test)}")

它给出了以下输出:

Training target statistics: Counter({0: 25727, 1: 25727})
Testing target statistics: Counter({0: 11044, 1: 889})

X_resy_res可以作为build_and_test()功能的参数提供。从主成分分析图中,我注意到绿点的数量惊人地增加了。

roc_auc_ros,fpr_ros,tpr_ros, _ = build_and_test(X_res, X_test, y_res, y_test)

作者图片

所有其他的情节都可以在 Github 的代码中找到。

下表显示了由build_and_test()功能产生的分类报告:

precision    recall  f1-score   support

           0       0.98      0.98      0.98     11044
           1       0.75      0.76      0.76       889

    accuracy                           0.96     11933
   macro avg       0.87      0.87      0.87     11933
weighted avg       0.96      0.96      0.96     11933

同样的分析也可以用在SMOTE技术上。

from imblearn.over_sampling import SMOTE
over_sampler = SMOTE(k_neighbors=2)
X_res, y_res = over_sampler.fit_resample(X_train, y_train)
print(f"Training target statistics: {Counter(y_res)}")
print(f"Testing target statistics: {Counter(y_test)}")

它给出了以下输出:

Training target statistics: Counter({0: 25727, 1: 25727})
Testing target statistics: Counter({0: 11044, 1: 889})

RandomOverSampler类似,从 PCA 图中,我注意到绿色点的大小。关于RandomOverSampler,绿点的分布有很大不同。

roc_auc_smote,fpr_smote,tpr_smote, _  = build_and_test(X_res, X_test, y_res, y_test)

作者图片

使用 SMOTE 技术会产生以下分类报告:

precision    recall  f1-score   support

           0       0.99      0.98      0.98     11044
           1       0.75      0.82      0.78       889

    accuracy                           0.97     11933
   macro avg       0.87      0.90      0.88     11933
weighted avg       0.97      0.97      0.97     11933

欠采样最大的数据集

欠采样是一种将最大类的样本数量减少到最小类的技术。这是通过从最大的类中移除一些采样器来实现的。可以应用不同的技术对类进行欠采样。在本教程中,我将使用RandomUnderSamplerNearMissimbalanced-learn包还提供了其他技术,比如压缩最近邻。与过采样器类似,所有欠采样器都提供一个名为fit_resemple()的函数,该函数接收X_train输入变量和y_train输出变量,并分别返回欠采样输入和输出变量X_resy_res

from imblearn.under_sampling import RandomUnderSamplerunder_sampler = RandomUnderSampler(random_state=42)
X_res, y_res = under_sampler.fit_resample(X_train, y_train)
print(f"Training target statistics: {Counter(y_res)}")
print(f"Testing target statistics: {Counter(y_test)}")

它产生以下输出:

Training target statistics: Counter({0: 2114, 1: 2114})
Testing target statistics: Counter({0: 11044, 1: 889})

一旦对数据集进行了欠采样,我就调用build_and_test()函数。从 PCA 图中,我注意到红点的数量减少了。

roc_auc_rus,fpr_rus,tpr_rus , _ = build_and_test(X_res, X_test, y_res, y_test)

作者图片

生成的分类报告如下:

precision    recall  f1-score   support

           0       0.99      0.92      0.95     11044
           1       0.48      0.92      0.63       889

    accuracy                           0.92     11933
   macro avg       0.73      0.92      0.79     11933
weighted avg       0.95      0.92      0.93     11933

对于NearMiss下采样器也可以进行同样的分析。

from imblearn.under_sampling import NearMissunder_sampler = NearMiss()
X_res, y_res = under_sampler.fit_resample(X_train, y_train)
print(f"Training target statistics: {Counter(y_res)}")
print(f"Testing target statistics: {Counter(y_test)}")

输出如下:

Training target statistics: Counter({0: 2114, 1: 2114})
Testing target statistics: Counter({0: 11044, 1: 889})

现在我可以运行算法了:

roc_auc_nm,fpr_nm,tpr_nm, _  = build_and_test(X_res, X_test, y_res, y_test)

作者图片

带有以下分类报告:

precision    recall  f1-score   support

           0       0.99      0.91      0.95     11044
           1       0.44      0.85      0.58       889

    accuracy                           0.91     11933
   macro avg       0.71      0.88      0.76     11933
weighted avg       0.95      0.91      0.92     11933

类别权重

设置类权重是另一种有效的平衡方法。每个scikit-learn分类模型都可以配置一个名为class_weight的参数,它以 Python 字典的形式接收每个类的权重。为了计算每个类的权重,我可以将最大类的权重设置为 1,将最小类的权重设置为最大类的样本数与最小类的样本数之比。

n= Counter(y_train)
ratio = int(n[0]/n[1])
ratio, n

输出如下:

(12, Counter({0: 25727, 1: 2114}))

我通过设置class_weight参数来调用build_and_test()函数。

roc_auc_cw,fpr_cw,tpr_cw, _  = build_and_test(X_train, X_test, y_train, y_test, class_weight={0:1, 1:ratio})

带有以下分类报告:

precision    recall  f1-score   support

           0       0.98      0.98      0.98     11044
           1       0.73      0.76      0.75       889

    accuracy                           0.96     11933
   macro avg       0.86      0.87      0.86     11933
weighted avg       0.96      0.96      0.96     11933

阈值

调整阈值是平衡数据集的手动技术。从概念上讲,如果预测值大于阈值,则设置为 1,否则设置为 0。关于阈值的更多细节可在此链接中找到。在本教程中,我将阈值设置为最大化尤登 J 统计的值。此外,我将从roc_curve()中提取候选阈值列表。

roc_auc_thr,fpr_thr,tpr_thr, threshold = build_and_test(X_train, X_test, y_train, y_test, threshold=True)
print(f"Best Treshold: {threshold}")

输出如下:

precision    recall  f1-score   support

           0       0.98      0.98      0.98     11044
           1       0.81      0.79      0.80       889

    accuracy                           0.97     11933
   macro avg       0.89      0.89      0.89     11933
weighted avg       0.97      0.97      0.97     11933

Best Treshold: 1.0

在这种情况下,最佳阈值是 1,因此阈值技术表现为不平衡的情况。

一起绘制

最后,我将所有的 ROC 曲线绘制在一起。我注意到在我的情况下,最好的技术是随机下采样,具有最大的 AUC 值。

plt.plot(fpr_imb, tpr_imb, lw=3, label='Imbalanced $AUC_0$ = %.3f' % (roc_auc_imb))
plt.plot(fpr_ros, tpr_ros, lw=3, label='ROS $AUC_0$ = %.3f' % (roc_auc_ros))
plt.plot(fpr_smote, tpr_smote, lw=3, label='SMOTE $AUC_0$ = %.3f' % (roc_auc_smote))
plt.plot(fpr_rus, tpr_rus, lw=3, label='RUS $AUC_0$ = %.3f' % (roc_auc_rus))
plt.plot(fpr_nm, tpr_nm, lw=3, label='NM $AUC_0$ = %.3f' % (roc_auc_nm))
plt.plot(fpr_cw, tpr_cw, lw=3, label='CW $AUC_0$ = %.3f' % (roc_auc_cw))
plt.plot(fpr_thr, tpr_thr, lw=3, label='NM $AUC_0$ = %.3f' % (roc_auc_thr))
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate', fontsize=16)
plt.ylabel('True Positive Rate', fontsize=16)
plt.title('ROC curve', fontsize=16)
plt.legend(loc="lower right", fontsize=14, frameon=False)
plt.tick_params(axis='both', which='major', labelsize=16)
plt.show()

作者图片

摘要

在本教程中,我演示了如何平衡不平衡的数据集。可以使用不同的技术:欠采样、过采样、阈值和类别权重。没有最佳选择,要看数据。在某些情况下,不平衡数据集可能比平衡数据集表现得更好。

如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。

相关文章

新到中?您可以每月订阅几美元,并解锁无限的文章— 点击此处。

如何使用约束优化在 Python 中平衡化学方程式(PuLP)

原文:https://towardsdatascience.com/how-to-balance-chemical-equations-in-python-using-constraint-optimization-pulp-1d7409fbe52b?source=collection_archive---------32-----------------------

我们将使用纸浆和化学分析库来平衡化学方程式

App 截图

原贴于【realpythonproject.com】

你可以在这里 找到源代码https://github.com/rahulbanerjee26/Chemical-Equation-Balancer

先决条件

  • 熟悉约束优化。查看我以前的文章,了解关于约束优化和纸浆的介绍
  • 熟悉化学方程式配平。
  • 对 Streamlit 有所了解是有好处的。Shail Deliwala的这篇文章很好地介绍了 Streamlit。

如何使用约束优化来平衡化学方程式?

平衡一个化学方程式本质上意味着尊重质量守恒,并确保一种元素的左边(反应物)和右边(产物)有相同数量的原子。基本上,如果你将 X 克元素作为反应物,产物中也会有 X 克该元素(理想状态)。

作者图片

在上图中,您可以注意到以下内容

  • 在非平衡方程式中,产物中有两个氢原子和氯原子。然而,反应物中只有一个氢和氯原子。这不尊重质量守恒定律
  • 在平衡方程式中,我们在反应物中使用 2 个氢原子和氯原子。产物中的原子数保持不变。结果,方程平衡了,不再违反质量守恒定律。

上面的方程很容易求解,可以手动完成。然而,随着元素数量的增加和反应物/产物数量的增加,事情变得复杂了。下面的等式虽然可以手动完成,但需要大量的反复试验。

不平衡等式的示例

那么如何才能使用约束优化呢?

让我们考虑一下我们已经看过的第一个方程

不平衡等式的示例

每种反应物/产物的系数可以被认为是一个变量。

变系数方程

X1、X2、X3 和 X4 是可变系数。每个变量必须是大于或等于 1 的整数。

每个元素添加一个约束,即

  • 对于锌:反应物中的锌原子数必须等于产物中的锌原子数

锌造成的限制

  • 对于 Cl:反应物中的氯原子数必须等于产物中的氯原子数

Cl 导致的约束

  • 对于 H:反应物中氢原子的数目必须等于产物中氢原子的数目

H 引起的约束

这个问题可以被认为是一个最小化问题,因为我们需要找到最小的系数来平衡方程。

该问题除了最小化系数之外没有其他目标,这意味着目标基本上是 0(无)。

总结一下,这就是我们的问题是如何设置的

问题设置

该问题可以使用 PuLP 和使用 PuLP 默认解算器的解算器来设置。

现在,我们可以继续推广它来支持其他方程。

解析化学方程式

我们将使用 chemparse 库来解析反应物和产物。

*pip3 install chemparse*

下面是 chemparse 返回内容的几个例子。它们取自图书馆的文献

*“CH4” returns {“C”:1.0, “H”:4.0}
“C1.5O3” returns {“C”:1.5, “O”:3.0}
"(CH3)2(CH2)4" returns {"C":6.0, "H":14.0}*

让我们创建一个函数来解析这些方程。该函数将期待类似于下面的输入

*Zn + HCL -> ZnCl2 + H2*

我们可以用'--> '来分开,得到左手边和右手边]

代码片段

为了得到复合词,我们可以用“+”号分开,去掉后面的空格。

我们需要存储唯一的元素,这样我们就可以为每个元素形成约束,并将每个反应物和产物转换成由 chemparse 生成的字典。

代码片段

首先,我们遍历 lhsCompounds 并存储来自 chemparse 的结果以及唯一元素。

之后,我们迭代 rhsCompounds,我们不需要再次存储唯一的元素。但是,我们将系数存储为负数,因为这样在设置约束时会更容易。

函数来建立和解决约束优化问题

现在,我们可以继续解决问题了。

代码片段

我们将调用之前编写的解析函数并存储返回值。

每个反应物/产物都有一个系数,因此我们可以简单地循环变量 allCompounds(它包含每个反应物/产物的 chemparse 输出),并在每次迭代中创建一个变量。

变量的类别为整数,下限值为 0

代码片段

如前所述,这个问题是一个没有目标的最小化问题。

现在,让我们设置约束

代码片段

如前所述,每个元素都会添加一个与之相关的约束。

  • 我们遍历唯一元素
  • 获得每种反应物/产物中该元素的原子数
  • 对系数求和(记住所有乘积系数都存储为负值)
  • 添加总和应为 0 的约束

现在,我们准备解决这个问题,并创建平衡方程

代码片段

简化 WebApp

安装细流

*pip install streamlit*

这将是一个非常简约的应用程序。

代码片段

我们创建一个 text_input 组件,并将默认值设置为一个不平衡的等式。balance()函数被导入,我们将 text_input 的值作为参数传递。

此外,我们还可以在解决问题之前显示问题。这应该在 balance()函数内部

*st.text(prob)*

如果您对部署您的应用程序感兴趣,请查看由 Aniket Wattamwar 撰写的这篇文章。

联系我上LinkedIn Twitter

如何在一瞬间确定深度学习任务的基线

原文:https://towardsdatascience.com/how-to-baseline-deep-learning-tasks-in-a-flash-b9b7ff4ef482?source=collection_archive---------39-----------------------

本教程介绍了如何开始使用 PyTorch Lightning Flash 构建深度学习的基线

照片由 Dmitry Zvolskiy 从 Pexels 拍摄

PyTorch 闪电是什么?

PyTorch Lightning Flash 是 PyTorch Lightning 的创作者提供的一个新库,可以在几分钟内对新数据集的最新深度学习任务进行快速基线化。

https://github.com/PyTorchLightning/lightning-flash

与 PyTorch Lightning 摆脱样板文件的目标一致,Flash 旨在使其易于训练、推理和微调深度学习模型。

Flash 构建于 PyTorch Lightning 之上,用于为常见的深度学习任务提取不必要的样板文件,非常适合:

  • 数据科学
  • 卡格尔比赛
  • 工业人工智能
  • 应用研究

因此,Flash 为深度学习模型的分布式训练和推理提供了无缝支持。

由于 Flash 是建立在 PyTorch Lightning 之上的,随着您了解得越来越多,您可以用 Lightning 和 PyTorch 无缝地覆盖您的任务代码,为您的场景找到正确的抽象级别。

Nikolai Ulltang 从 Pexels 拍摄的摩托车照片

在这篇文章的剩余部分,我将通过一个内联 Flash 任务代码示例带您完成构建深度学习应用程序的 5 个步骤。

使用 Flash 创建您的第一个深度学习基准

照片来自 Pexels

以下教程的所有代码可以在笔记本下的 Flash Repo 中找到。

我将介绍五个可重复的步骤,您可以将它们应用于自己数据的任何闪存任务。

  1. 选择深度学习任务
  2. 加载数据
  3. 选择一个最先进的模型
  4. 微调任务
  5. 预测

现在让我们开始吧!!!

第一步:选择深度学习任务

照片由像素的皮克斯拜拍摄

应用深度学习过程的第一步是选择我们想要解决的任务。开箱即用,Flash 为常见的深度学习任务提供支持,如图像、文本、表格分类,以及更复杂的场景,如图像嵌入、对象检测、文档摘要和文本翻译。新任务一直在增加。

在本教程中,我们将使用 Flash 构建一个文本分类模型,用于对电影评论进行情感分析。该模型将能够告诉我们,诸如“这是电影史上最差的电影”的评论是负面的,例如“这位导演在这部电影上做得很好!“正。

首先,让我们安装 Flash 并导入文本分类任务所需的 Python 库。

从 PyPy 安装 Flash

用于文本数据加载和分类的导入任务功能

步骤 2:加载数据

现在,我们已经安装了闪存并加载了我们的依赖项,让我们来谈谈数据。为了构建我们的第一个模型,我们将使用以 CSV 文件格式存储的 IMDB 电影评论数据集。查看数据集中的一些示例评论。

review, sentiment"I saw this film for the very first time several years ago - and was hooked up in an instant. It is great and much better than J. F. K. cause you always have to think 'Can it happen to me? Can I become a murderer?' You cannot turn of the TV or your VCR without thinking about the plot and the end, which you should'nt miss under any circumstances.", positive"Winchester 73 gets credit from many critics for bringing back the western after WWII. Director Anthony Mann must get a lot of credit for his excellent direction. Jimmy Stewart does an excellent job, but I think Stephen McNalley and John McIntire steal the movie with their portrayal of two bad guys involved in a high stakes poker game with the treasured Winchester 73 going to the winner. This is a good script with several stories going on at the same time. Look for the first appearance of Rock Hudson as Young Bull. Thank God, with in a few years, we would begin to let Indians play themselves in western films. The film is in black and white and was shot in Tucson Arizona. I would not put Winchester 73 in the category of Stagecoach, High Noon or Shane, but it gets an above average recommendation from me.<br /><br />.", positive

我们需要做的第一件事是使用下面的代码下载数据集。

一旦我们下载了 IMDB 数据集,Flash 就会提供一个方便的 TextClassificationData 模块,该模块可以处理加载以 CSV 格式存储的文本分类数据并将其转换为深度学习模型需要训练的表示形式的复杂性。

我们所需要做的就是向 TextClassificationData 对象提供我们的 IMBDb 数据的文件路径,并告诉它我们的数据中的哪一列是我们想要预测的输入和哪一列是我们想要预测的标签

3.为我们的任务选择一个最先进的模型

在过去几年的自然语言处理中,许多最先进的模型都是以芝麻街角色命名的。根据来自 pixy 的 CC BY-NC-ND 4.0 许可证使用的照片

一旦我们加载了数据集,我们需要选择一个模型来训练。每个 Flash 任务都预加载了对最先进的模型主干的支持,供您立即体验。

默认情况下,TextClassifier 任务使用 tiny-bert 模型,在大多数文本分类任务上实现强大的性能。尽管如此,你仍然可以使用来自拥抱脸变形金刚——文本分类模型库的任何模型,甚至可以自带模型。在 Flash 中,你只需要一行代码来加载主干。

4.微调任务

照片由来自 Pixy 的雪伊·卡尔金斯拍摄

现在,我们已经选择了模型并加载了数据,接下来是使用下面两行代码在分类任务中训练模型的时候了:

由于 Flash Trainer 构建在 PyTorch Lightning 之上,因此可以无缝地将培训分发到多个 GPU、集群节点甚至 TPU。

此外,您还可以获得大量其他难以实现的功能,例如自动化模型检查点和与 Tensorboard、Neptune.ai 和 MLFlow 等平台的日志集成,没有任何麻烦。

作者生成的照片。

任务自带对所有标准任务指标的本地支持。在我们的案例中,Flash Trainer 将自动为您在所有分类标准任务指标上对您的模型进行基准测试,例如精度、召回率、F1 和 more 只需一行代码。

使用 Flash Trainer 可以无缝地检查和共享任务模型,如下所示。

5.预测

照片由来自 Pexels 的sin dre strm拍摄

一旦我们完成了模型的训练,我们就可以用它来预测我们的数据。只用一行代码:

此外,我们可以使用 Flash Trainer 为生产扩展和分发模型推理。

对于在 32 个 GPU 上进行推理的缩放,它就像一行代码一样简单。

您甚至可以将模型导出到 Onnx 或 Torch 脚本,用于边缘设备推断。

把所有的放在一起

那多有趣啊!上面的 5 个步骤被浓缩成下面的简单代码片段,可以应用于任何 Flash 深度学习任务。

后续步骤

现在,您已经拥有了开始构建快速深度学习基线的工具,我迫不及待地想让您向我们展示您可以构建什么。如果你喜欢这个教程,请在下面鼓掌,并在 GitHub 上给我们一颗星。

我们正在不知疲倦地添加更多的 Flash 任务,所以如果你有任何必须的任务,请在下面评论或通过 Twitter @pytorchlightnin 或我们的 Slack 频道联系我们。

关于作者

亚伦(阿里)【博恩施泰因】 是一名人工智能研究员,对历史充满热情,致力于新技术和计算医学。作为 Grid.ai 的开发者宣传负责人,他与机器学习社区合作,用改变游戏规则的技术解决现实世界的问题,然后将这些技术记录在案,开源,并与世界其他地方共享。

如何成为一名数据分析师——谷歌数据工作室的数据 Viz

原文:https://towardsdatascience.com/how-to-be-a-data-analyst-data-viz-with-google-data-studio-5cda4ad475f2?source=collection_archive---------35-----------------------

数据分析师关于客户流失的演示报告

你是一个有抱负的数据分析师或数据科学家,希望建立自己的投资组合和可视化技能吗?

或者你是一名数据分析师,想提高自己的可视化技能和商业智能能力?

或者你对 Tableau 的高成本感到沮丧,正在寻找一个免费的替代品?

今天,我将向您展示我使用(免费!)Google Data Studio,以及如何为您的投资组合创建自己的报告——所有这些都不需要编码。

我们将讨论…

  1. 什么是谷歌数据工作室
  2. 作为一名分析师,你为什么需要了解数据和报告
  3. 如何实施分析过程
  4. 你应该在一份有效的报告中包括什么

我将使用我创建的关于分析客户流失的演示报告来运行这个流程。

作者演示流失探索报告(链接

关于谷歌数据工作室

谷歌数据工作室让你用数据讲述你的故事。特别是,它是一个方便的工具,可以让你—

  • 通过高度可配置的图表和表格可视化您的数据。
  • 轻松连接到各种数据源。
  • 与您的团队或全世界分享您的见解。
  • 与您的团队协作完成报告。
  • 使用内置的示例报告加快您的报告创建过程。

不仅如此,它还有以下令人敬畏的功能。

  • 强大的可视化能力。 Data Studio 提供了丰富的可视化选项,包括折线图、条形图、饼图、地理地图、面积图、气泡图、数据表、数据透视表等。
  • 很强的互动性。报告可以与查看器过滤器和日期范围控件交互。这允许观众探索数据。
  • 可定制性高。你不仅可以包含文本,还可以包含图片,改变你的报告的外观和感觉。
  • 令人印象深刻的连接性。人们可以将来自许多不同数据源的数据连接到 Google Data Studio,包括 Google Sheets(是的!)和 CSV 文件。人们还可以将实时数据连接到谷歌数据工作室,包括谷歌广告、分析、YouTube、BigQuery、MySQL,甚至像脸书、Reddit 和 Twitter 这样的社交媒体平台。

人们可以探索各种各样的数据可视化或商业智能软件。这些软件包括 Tableau、Qlikview、FusionCharts、Highcharts、Datawrapper、Plotly 和 Sisense。

这些都有自己的优点,但一般都很贵。如果你想尝试使用免费软件,那么谷歌数据工作室正适合你。

但是,请注意,您在工作中使用的软件将取决于可用的工具。

注意,谷歌数据工作室提供牛逼(免费!)教程,通过其分析学院。

为什么数据分析师需要了解数据,即

由卢克·切瑟在 Unsplash 上拍摄的照片

作为一家科技公司的分析师,我的职责是执行不同类型的分析并交流见解。四种类型的分析包括—

  • 描述性分析报告过去发生的事情。
  • 诊断分析通过比较描述性数据集来识别模式,从而揭示过去事件的原因
  • 预测分析 旨在通过检测描述性和诊断性分析中的趋势来预测未来的结果。
  • 规定性分析试图根据上述三种类型确定要采取的业务行动。

可以说,所有这些类型的分析都涉及某种形式的数据可视化。特别是,有效的描述性和诊断性分析被数据驱动型公司中的几乎所有利益相关者使用,并涉及数据可视化中的一些繁重工作。

这两种形式的分析可以在商业智能或数据可视化软件上轻松执行,这使得分析师可以创建可视化效果,利益相关者可以访问它们。

因此,如果数据分析师精通此类软件,并且能够高效地创建传达见解的可视化效果,这将非常有帮助。

(诊断)分析的过程

克莱顿·罗宾斯在 Unsplash 上的照片

我今天要分享的报告是一份诊断分析报告。

1。理解问题。

理解业务问题非常重要,因为它允许数据分析师提供符合业务需求的分析。在不了解问题的情况下执行请求充其量是徒劳的。

该报告是为以下模拟场景创建的。

你是 B 电信公司的数据分析师。最近,业务团队发现了客户流失的高峰。但是,它不确定这些客户的特征。你的角色是告知业务团队哪些客户可能流失。

2。计划报告。

计划,计划计划。照片由哈尔·盖特伍德在 Unsplash 拍摄

创建您将要创建的报告的模型可以极大地加快分析过程。有一个计划会减少分心,帮助你专注于手头的任务。

在这一步中,您可能想问自己的一些问题包括:

  • 解决问题的重要指标是什么?
  • 能够解决问题的假设有哪些?

将此应用于我们手头的案例,我们知道我们必须探索的最重要的指标是“客户流失”。

可以解释客户流失的一些假设包括:

  • 任期较短的客户流失率较高
  • 特定人群的客户流失率更高
  • 价格越高的客户流失率越高
  • 订购特定服务的客户流失率更高

3。创建实体模型

回答完这些问题后,我们可以继续创建一个模拟报告。这将有助于分析师可视化步骤 4 中所需的数据。

在这种情况下,我创建了以下模型。正如你可能注意到的,这不是最整洁的,也不是最有美感的——这完全没问题!毕竟只是个草稿。

4。提取和清理数据

既然我们已经有了假设,我们可以提取我们想要探索的相关数据。在典型情况下,可以使用 SQL 提取相关数据。

仪表板中使用的数据集可在 Kaggle 上获得。这是一家拥有 7043 名客户的电信公司的数据集。它包含以下功能:

  1. 客户是否有流失
  2. 客户任期
  3. 客户人口统计信息(性别、年龄范围、是否有伴侣或家属)
  4. 客户支付行为(合同类型、支付方式、无纸化账单、每月费用和总费用)
  5. 客户服务订购(客户是否订购了特定的服务

在这种情况下,数据集是干净的。我们现在可以开始实施我们的计划了——使用 Google Data Studio!

有效报告的剖析

行动纲要

报告应该包括你正在解决的问题陈述和发现。报告第 1 页对此进行了概述。

数据报告的执行摘要(报告和作者图片)

数据文档

为了帮助利益相关者理解报告,应该包括关于数据来源和数据解释的适当文档。这在报告的第二页。

数据报告的数据文档(报告和作者图片)

调查结果

调查结果是报告最重要的部分。发现部分包含标题、可视化、分析和可能的行动。这在样本报告的第 3 页到第 8 页,可以看到如下:

数据报告的结果部分(报告和作者提供的图像)

要打开的东西太多了。让我们将调查结果部分分解成它的结构。

调查结果的分类(报告和作者提供的图片)

摘要

不是所有的利益相关者都有时间去消化所有的可视化。因此,每个调查结果的标题应该是描述性的,并从图表中总结调查结果。

可视化

应该进行适当的可视化以支持该发现。视觉效果也应该是整洁的,以免分散读者对信息的注意力。

分析

有时,描述图表有助于引导读者理解图表。只要有可能和合适,分析员还应该确定发现的统计显著性,以增加对发现的信心。

外卖

分析师也可以尝试对发现和可能的进一步探索做出进一步的假设。这一部分可以引发与相关涉众的有趣讨论,并提出解决当前问题的倡议。

现在轮到你了!

我故意没有触及一些分析,这样你就有机会练习了。请务必在下面留下您将在此报告中包含的分析类型的评论。

如果你想了解更多,

关闭

数据可视化和报告是数据分析师和数据科学家的一项基本技能。

如果你想找一份分析师或数据科学家的工作,你可以建立一份自己的报告,并将它放在简历中,这将是一个加分项。

喜欢这篇文章吗?你可能会喜欢这个—

你也可以在 LinkedIn 上和我联系。我将很高兴收到反馈,回答问题或只是与志同道合的人联系。

https://www.linkedin.com/in/travistang/ [## Travis Tang -数据分析师

www.linkedin.com](https://www.linkedin.com/in/travistang/)

没有 STEM 学位如何成为一名数据科学家

原文:https://towardsdatascience.com/how-to-be-a-data-scientist-without-a-stem-degree-ce00b5a66fd4?source=collection_archive---------6-----------------------

一位处于相同位置的数据科学家的建议

约书亚·厄尔在 Unsplash 上的照片

介绍

作为一名自学成才的数据科学家,我可以自信地说,没有 STEM 学位也很有可能成为一名数据科学家。这不会是一条容易的路,因为它不适合我自己,但它值得每一盎司的努力。

在本文中,我想分享四个关于如何成为没有 STEM 学位的数据科学家的深入技巧。说了这么多,让我们开始吧!

请务必 订阅 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

1.了解数据科学的实用支柱

虽然“数据科学”是一个模糊的术语,但我建议您学习一些核心技能。以下技能对任何数据科学家都至关重要:SQL、Python、统计学、机器学习。我也建议你按照这个顺序学习这些技能。这听起来可能很多,但这和你在大学里每学期必须完成 4-6 门课程没什么不同!

让我们深入了解每项技能:

A) SQL

SQL 是数据的语言,可以说是任何数据科学家最重要的技能。SQL 用于操纵数据、分析数据、构建仪表板、构建管道、编写查询以输入模型,这样的例子不胜枚举。

  • 模式 SQL 教程
  • 学习 SQL (Codecademy)

蟒蛇和熊猫

Python(或任何脚本语言)是做其他事情的基础,比如构建 ML 模型、web 抓取数据、构建自动化脚本等等。

Pandas 是一个用于数据操作和分析的 Python 库。我个人在 Jupyter 笔记本上浏览数据时使用 Pandas 而不是 SQL。

以下是我用来学习 Python 和熊猫的最有用的资源:

  • Python(data camp)简介
  • 学习熊猫教程(Kaggle)
  • 熊猫练习题(GitHub)

C)统计

数据科学/机器学习本质上是统计学的现代版本。通过首先学习统计学,当涉及到学习机器学习概念和算法时,你会有更容易的时间!即使看起来你在最初的几周没有得到任何切实的东西,但在接下来的几周里这是值得的。

以下是我用来学习统计学的最有用的资源:

  • 统计与概率(可汗学院)
  • StatQuest (YouTube)

D)机器学习

机器学习不仅有趣和令人兴奋,而且也是所有数据科学家都拥有的技能。建模只占数据科学家时间的一小部分,这是事实,但这并没有降低它的重要性。

以下是我用来学习机器学习的最有用的资源:

  • 机器学习介绍(Kaggle)
  • 中级机器学习(Kaggle)
  • 机器学习 A-Z (Udemy)
  • 机器学习——斯坦福大学(Coursera)

请务必订阅 订阅 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

2.完成 1-3 个个人数据科学项目

一旦你建立了基础,加速学习的最好方法就是完成一些数据科学项目。最简单的方法是继续 Kaggle ,选择一个数据集,并创建一个预测模型或一些数据可视化。记住,你最初的几个项目不会很棒!但重要的是你如何随着时间的推移而进步。

以下是我过去完成的一些数据科学项目,你可以从中获得一些灵感!

  • 冠状病毒数据可视化使用 Plotly
  • 使用随机森林预测二手车价格
  • 预测预期寿命

在您继续学习和实践数据科学技能的同时,您还可以做其他事情来使自己成为更有价值的数据科学候选人,这就引出了我的下一个技巧:

3.探索非常规的经验机会

作为一名数据科学家,最难的部分是在没有经验的情况下获得第一次机会。然而,以下是几种即使你没有经验也能获得经验的方法:

非营利机会

最近,我偶然看到苏珊·柯里·西维克写的一篇 足智多谋的文章,,文章提供了几个组织,在那里你可以有机会从事现实生活中的数据科学项目。

如果你想在简历中添加更多的经历,我强烈建议你看看这个。

参加比赛

在我看来,没有比通过竞赛展示您的代码更好的方式来表明您已经为数据科学工作做好了准备。Kaggle 举办了各种各样的比赛,包括建立一个模型来优化某个指标。

你现在可以尝试的两个比赛是:

  1. 泰坦尼克号:机器从灾难中学习
  2. 房价:高级回归技术

在媒体上开博客

是的,我有偏见,但是听我说完。你会惊讶有多少数据相关的专业人士在 Medium 上。他们喜欢看信息丰富、见解深刻、有趣的材料。利用 Medium 来记录您的学习成果,用简单的行话解释复杂的主题,或者浏览您的数据科学项目!

具体来说,我建议你为《走向数据科学》杂志撰稿,因为他们目前拥有近 50 万名粉丝。

如果你想要一些灵感,请查看我关于 葡萄酒质量预测 的项目演练。

4.寻找类似数据科学家职位的工作

我知道这将是一场艰苦的战斗,尤其是我之前没有数据科学家的经验。然而,找到类似于数据科学家职位的工作将显著增加你成为数据科学家的机会。这样做的原因是相关的工作会给你机会在商业环境中处理实际数据。

做“数据科学”工作不需要成为数据科学家

以下是一些你可以寻找的数据科学相关的工作:

  • 商业智能分析师
  • 数据分析师
  • 产品分析师
  • 增长营销分析师/营销分析
  • 定量分析师

感谢阅读!

我希望您发现这很有见地,并对您的数据科学事业有所帮助!如果你喜欢这个,一定要关注我的未来内容。一如既往,我祝你学习一切顺利!

不确定接下来要读什么?我为你挑选了另一篇文章:

</10-most-practical-data-science-skills-you-should-know-in-2022-9487d7750e8a>

又一个!

特伦斯·申

  • 如果你喜欢这个, 订阅我的媒介 获取独家内容!
  • 同样,你也可以 跟我上媒
  • 有兴趣合作吗?让我们连线上LinkedIn

如何成为更高效的数据分析师

原文:https://towardsdatascience.com/how-to-be-a-more-productive-data-analyst-82006ab8a487?source=collection_archive---------14-----------------------

在不增加工作量的情况下最大限度提高产量的技巧

照片由来自 Pexels 的 Enric Cruz López 拍摄

作为一名数据分析师,我经常面临一长串的请求,而处理这些请求的时间有限,因为我要么在开会,回答利益相关者的问题,要么在解决 ETL 问题。然而,我仍然设法按时完成了我的项目,没有做更多的工作。今天我想讨论一下我曾经用过的提高效率的方法,以及你如何也能做到。

创建请求所需信息的列表

涉众可能不会在请求中提供所有必要的细节,分析师需要澄清需求。这浪费了双方讨论请求的时间,如果事先就共同请求所需的信息列表达成一致,就可以节省时间。我的大部分请求涉及评估产品实验,在过去,我不得不与利益相关者跟进缺失的信息。自从我与利益相关者一起创建了一个所需信息的列表,我就不再需要追踪缺失的细节,而是可以利用这段时间来处理请求。

保存常见查询和文档链接

我保存 SQL 和 Python 代码片段,以避免为不同的请求重复编写类似的代码。我引用的示例代码越多,我从零开始编写代码的时间就越少,这有助于提高我的生产率。我把我经常参考的文档链接加入书签,这样我就不用再去搜索了。这被证明是节省时间的方法,因为我可以很快找到我需要的东西,然后回到手头的工作上。

学会拒绝会议

如果会议是信息性的,不需要您的输入,请向会议组织者确认是否需要您出席。您可能希望参加会议以了解更多有关主题的信息,但通常情况下,有一套资料或文档可供查看,无需参加会议即可获得相同的信息。或者,让会议组织者录制会议,并在您有时间时观看视频。省下你本来要花在会议上的时间,转而处理一个请求。

关闭即时消息通知

我在一家科技公司工作,Slack 是我们快速获得问题答案的主要沟通来源。这转化为持续的干扰,降低了我的工作效率。如果我正在处理一个要求我全神贯注的请求,我会关闭几个小时的空闲通知,并在到达一个好的停止点时检查我的消息。这极大地提高了我的工作效率。

安排连续会议

我知道连续开会很累人,但如果你要在两个中间有 30 分钟间隔的一小时会议和两个连续会议之间做出选择,我推荐后者。有 30 分钟的休息时间是没有用的,因为这可能太短了,无法完成一项任务或回答问题,你最终会处于无所事事的状态。

试试无会议日

如果你的日历中有几天你没有很多定期会议,考虑把那一天定为无会议日,把会议转移到一周的其他日子。如果没有空闲的一天,试着安排一个下午的空闲时间。我推荐至少连续两个小时的空闲时间,因为我发现少于这个时间是不足以完成我的请求和验证结果的。当我足够幸运,有一天没有会议的时候,我已经能够在请求上取得重大进展,否则在有会议和其他干扰的日子里我就不会取得进展。

列出子任务并记下后续步骤

有时候,我有需要几周才能完成的大项目。对于这些项目,我首先将它们分成子任务,如果我不能完成一个子任务,第二天需要继续,我会记下我已经做了什么,还有什么需要完成。这减少了我记起已经完成的内容的时间,并且我可以直接回到前一天停下来的地方。

我曾经认为我已经很有效率了,因为我按时甚至提前完成了我的要求,但是自从我实施了上面的建议后,我发现我的产出有所提高,尽管我工作的时间是一样的。现在你知道了我的建议,我希望你能比以前更有效率。

你可能也会喜欢…

https://madfordata.medium.com/how-to-reduce-stress-in-a-data-analytics-job-d6567ee85322

如何成为数据科学实习生的鼓励型主管

原文:https://towardsdatascience.com/how-to-be-an-encouraging-supervisor-for-your-data-science-intern-661fcf3baeef?source=collection_archive---------32-----------------------

办公时间

可以让你的团队和实习生受益的 7 个可行步骤

来自 Pexels 的 Cottonbro 摄影

我已经很久没有这种成就感了。

作为顶级作家,你可以获得晋升,赚很多钱在线写作,并建立一个忠实的读者群,然而,这并不能满足于帮助一个数据爱好者释放他的真正潜力。

我帮助管理一个年轻的爱好者,他刚刚完成了在我们公司的实习。他是一名高中生,还没有开始他的大学教育,但有很多渴望学习。这感觉很像我,回到我第一次实习的时候。当他做最后的项目报告时,我无比自豪。

我有很多想法,我想把这些写下来,为我未来指导另一个实习生时的自己和你设立一个很高的标准,如果你有机会改变别人的职业生涯。

我将我的学习归纳为 7 个关键步骤,要成为你的数据科学实习生的鼓励型主管,就要遵循这些步骤。我一个字都不想忘,所以我们开始吧。

1.向你的上司学习

自从我们开始数据科学生涯以来,一直有人在管理我们。因此,当主管的机会出现时——自然地,我向我的主管寻求灵感来设计实习。

问自己这些问题:当你加入团队时,他们给你什么感觉?为了熟悉工作,他们给了什么样的指导?我知道你在想什么。也许你和你的经理相处得不好。在这种情况下,他们可以做些什么不同的事情来让你的工作生活更容易管理呢?你明白了。

原因如下:不管你是否有过正面的经历,他们在这个行业的时间比你长得多。你可以学习数据科学中的所有新工具和技术,但是没有什么可以取代他们与客户、不同领域、与初级员工打交道等方面的经验。

这些年来,我有了巨大的成长,这要感谢我在工作内外的所有导师。在数据科学中,经验比你想象的重要得多。向你前面的人学习,并把它传递给你身边的人。

2.准备好奉献时间

我明白了。你工作很忙。他们不会因为你要管理一个实习生就改变你必须满足的截止日期。如果你必须留下来帮助他们完成项目,他们不会给你额外的报酬,也不会给你加班费。你已经被工作压得喘不过气来了——我明白。

但问题是。如果你答应了这个机会,你必须为它付出必要的时间。否则,你会毁了他们的职业生涯,让他们没有一个积极的开始。这可能看起来是一件无害的事情,但是问问有糟糕实习经历的人(像我),他们会告诉你这件事。

网上有很多学数据科学的信息,经常铺天盖地。你需要时间来指导他们正确的课程、书籍、教程,以及项目的总体流程。早期指导对于数据科学的发展至关重要。

3.想象一次成功的实习之旅

照片由 J avi_indy 在 Freepik 上拍摄

当我理解了实习生的技能后,我为他接下来的 8 周实习制定了一个计划。由于他之前没有任何经验,并且是一名高中生,我想让他体验一下端到端的机器学习工作流,从数据收集到创建最终用户仪表板。

这里的关键是根据实习生的技能和业务需求来定制计划。这需要是一个双赢的双方。你不能指望一个完全的初学者在 8 周内在云中部署生产就绪的应用,你能吗?

这里的最后一步是将计划传达给实习生,分享你的愿景,并询问他们是否对此感到兴奋。推销他们的技能和经验,这样他们会像你一样投入到你的计划中。

4.安排会议节奏

无论你计划花多少时间,事情都会阻碍你。在这 8 个星期里,我生病了;他的实习报告需要修改的地方比我们预期的要多,等等。为了应对不确定性,我们需要建立一个系统。

由于我们远程工作,我为每一个交付物安排了周会和预定义的日期。我还提交了详细的计划,其中包含类似于机器学习工作流程的重点任务,供他每周处理,因此期望是明确的。

因为其他事情都已经安排好了,我们通常讨论的只有他面临的障碍,以及如何克服它们(提示:Google 和 Stackoverflow)。你需要提前设定这种节奏,这样即使在不确定的时候,实习也总是回到既定的结构。

5.欢迎建议(这是他们的旅程)

老实说,这是最关键的一步。为了给实习生一个好的实习经历,如果我们为实习生安排好一切,而不为他的想法和实验提供空间,实习的整个目的就失去了。

我们想尽我们所能给他们最好的,这很好,但这毕竟是他们的实习之旅。他们需要探索,犯自己的错误,并从中吸取教训。我们的角色只是引导他们完成整个过程。

我的实习生继续尝试不同的机器学习模型,我从未使用过的超参数优化库,建立了一个 PowerBI 可视化仪表板(我只使用过 Tableau】)。是的,我想安排实习,但我欢迎他所有的建议,并鼓励他努力去做。

6.在不妥协和灵活之间取得平衡

我从我的经理那里学到了这一点,我很欣赏他的领导风格。他非常灵活,同时又不妥协。如果你太灵活,人们会认为你是理所当然的。如果你太严格,人们会讨厌和你一起工作。诀窍是根据情况平衡两者。

机器学习需要大量的实验,尽管一个人很努力,但结果并不总是有保证的。当他在截止日期前以 51%的准确率返回给我时,我给他更多的时间来尝试其他模型并提高准确率(他最终达到了 70%左右)。

我承认这不是一个容易掌握的技能,我仍然在掌握它的窍门。我是无意识地这样做的,直到我的实习生在我们最后一次坦诚的反馈会议上指出这一点时,我才意识到这一点。

显然,他发现自己很乐意向我寻求帮助,同时也很认真地对待我的指示。我很酷,不是吗?

7.私下批评,公开赞扬

来自 Pexels 的 RODNAE Productions 摄影

这是工作环境中的基本礼仪,但我经常看到实习生没有遵守。许多人认为实习生是理所当然的。批评他们的工作来改进是很好的,但是要在私下一对一的交流中进行。

有很多次,他没有按照指示去做,或者没有在最后期限前完成,我不得不做必须做的事情。但是没有人知道这件事,因为建设性的反馈不需要公开。

最后,让我们面对现实吧——我们都希望被欣赏。在所有的同事中欣赏他所做的所有努力确实感觉很棒,我肯定他也感到高兴。因此,在公共场合称赞和欣赏他们的工作是很重要的。

思考

我没有浪费一分钟去要求指导更多实习生的机会。如果你是数据科学团队的资深成员,那么必须开始指导初级数据爱好者。

虽然你的经验对他们来说很有价值,但你会惊讶地发现你从他们那里学到了很多:

  • 我学会了用更简单的术语来交流和解释复杂的技术——如果不是这样,他就不会理解。
  • 我学会了给出详细的指示,将它们分解成更小的任务——如果不是这样,我们就不得不每周来回联系多次。
  • 我学会了不要低估初学者,所有不断发展的资源只需在谷歌上搜索一下就能找到。

我可以继续这样下去,但老实说,即使我没有学到什么,我也会一遍又一遍地这样做——只是为了满足帮助塑造数据爱好者的职业生涯。

要获得更多关于数据科学、真实体验和学习的有用见解,请考虑 加入我的电子邮件好友私人列表

如何更好地准备虚拟数据科学面试

原文:https://towardsdatascience.com/how-to-be-better-prepared-for-virtual-data-science-interviews-7650c4492d65?source=collection_archive---------34-----------------------

凯恩·莱因霍尔德森在 Unsplash 上的照片

自信地完成数据科学面试,第 5 部分

本文是我的“把握数据科学面试”系列的第五部分。在之前的文章中,我在数据科学面试的时候,主要集中在讨论机器学习、统计、概率论、案例分析中的技术问题。不仅展示你的硬技能很重要,展示软技能也很重要,比如面试中的沟通技巧。由于疫情,传统的面对面面试已经被广泛暂停,如何在屏幕上展示最好的自己是所有面试者面临的一项挑战。在过去几个月的求职过程中,我已经和不同公司的不同人进行了 30 多次虚拟面试。在这篇文章中,我想根据我的经验提供一些更好地准备虚拟面试的技巧。

在采访之前

一旦收到面试邀请,回复招聘人员关于你最合适的时间和日期。如果之后你需要更改时间,请尽快联系招聘人员。设置好日期和时间后,您可以按照以下步骤开始准备面试:

1。安装需要的软件并测试前面的链接:

一些公司使用 zoom,一些公司使用 google hangout 进行虚拟面试。技术面试,可能需要使用 google doc 或者其他白板软件写伪代码。如果没有向您提供白板的共享链接,您可能不需要在面试中回答白板上的问题。不过,你还是要做好准备,以防你需要额外的工具来更好地解释自己。例如,你需要知道如何写下东西,并通过聊天发送,分享你的屏幕,显示写有你想法的白板或文字。至少你身边要有笔和纸,万一你想通过相机直接展示出来。确保提前下载所有必要的软件,并在面试前测试链接,看看它们是否工作正常。

2。准备好设备和备用设备

确保你有好的摄像机和麦克风在虚拟面试中使用。笔记本电脑或平板电脑都应该有很好的摄像头,这样你就不需要再买额外的了。然而,建议在面试时使用自己的耳机。我个人觉得降噪耳机非常有帮助,因为它为我建立了一个安静的环境,并向面试官清晰地传递我的声音。如果可能的话,如果您正在使用的设备发生意外故障,请随身携带额外的设备。记得有一次,我的两台电脑和 iPad 都打不开 zoom,最终还是用手机里的 zoom 去面试了。尽管如此,在面试时把手机放在身边是很重要的。万一你断线了,你仍然可以通过电话联系你的招聘人员或面试官。此外,确保你的电脑、平板电脑和耳机在面试前充满电,以减少断线的机会。

3。了解面试内容并做好相应准备

如果是技术屏,多练习各种领域的基础题。对于虚拟现场会议,准备好行为问题、编码测试和你面试的公司最常用的技术部分。每节课都可以深入技术细节,确保通过公司网站、LinkedIn、博客帖子等对公司和面试官做一些研究。

4。准备闲聊,问一些好问题

在虚拟面试中,闲聊至关重要。这有助于打破僵局,更快地建立你和面试官之间的联系。除了像天气和当前新闻这样的安全话题,我发现询问面试官的虚拟背景非常有帮助。闲聊起到了打开话题的作用,避免了开始时尴尬的沉默。

除了开头,你还可以在面试官介绍完自己后问一些后续问题,以显示你的兴趣。在面试结束时,你应该准备一两个好问题,问面试官关于公司和这个职位的问题。它要求你花一些时间研究面试官和公司,问一些令人印象深刻的问题。你可以准备一份针对公司和角色的常见问题清单。诸如“你如何衡量这里的成功?”,“在这里工作的数据科学家的典型一天是怎样的?”都是很好的例子。或者你可以问更多的技术问题。例如,您可以问,“对于您正在从事的项目,您如何在模型可解释性和模型复杂性之间做出选择?”。应该选择不太复杂、与公司业务高度相关、面试官回答不会花太长时间的问题。此外,在整个面试过程中,你都应该问一些问题,以显示你非常投入到谈话中。

面试的时候

经过充分的准备,今天就是约会的日子!确保在设定时间之前登录,并检查以下几点:

1。职业着装,至少在顶部

尽管不是所有的公司都有具体的着装要求,让求职者在面试时遵守,但我认为穿着职业装更有礼貌。这向面试官表明你在认真对待这次面试,并帮助你过渡到面试心态。然而,我不会说我喜欢穿得太专业,以至于在面试时感觉受到限制。我通常穿职业上衣,下穿运动裤。

除了职业着装,我还会为面试化淡妆。此外,我发现 zoom 的“修饰外观”功能非常有用。这个功能基本上为视频聊天戴上了滤镜,它让我在面试时看起来更好,更有活力。

2。测试互联网连接、摄像头和麦克风

登录后:

  • 通过查看您在相机中的清晰程度来检查互联网连接。如果互联网不是很稳定,请尝试关闭当前正在使用互联网的其他设备,或者尝试将您的计算机与手机中的热点连接。
  • 测试麦克风,看看您是否能正常听到和发出声音。
  • 在正确的位置有良好的照明。灯光不能太亮或太暗,这会让面试官更难看清你的脸。
  • 调整相机位置。虚拟面试的棘手之处在于,当你与面试官进行眼神交流时,你会从面试官的角度往下看。根据个人习惯,你可以不断提醒自己直视镜头,或者你可以把电脑移得更高,或者调整电脑的角度,这样当你看着屏幕上的面试官或你自己时,就不会显得低头了。
  • 有一个干净的背景,最少的干扰,比如一面白墙。如果不可能有一个干净的背景,你应该使用虚拟背景或模糊背景。面试时,确保你在一个安静的房间里,没有宠物或孩子。

3。与面试官保持经常沟通

面试官登录后,询问他或她是否能清楚地听到和看到你。你可以和面试官开始闲聊,或者等他或她来主导谈话。如果你在面试的时候在旁边放一支笔和一张白纸来做笔记,你应该把纸给面试官看,告诉他们你可能会在面试的时候写一些笔记。这将防止面试官认为你在面试时分心或用事先写好的笔记作弊。

在回答问题时,尤其是在编码测试期间,确保在整个过程中传达您的想法,这可以被称为“大声思考”你要确保面试官知道你是如何想出这个解决方案的。通常,面试官更看重你的思考过程,而不是你突然冒出来的完美解决方案。缺乏沟通可能是你认为自己在面试中表现出色,但仍然遭到拒绝的原因。为了更好地沟通,你可以从用自己的句子陈述问题开始,在开始解决问题之前,先问自己是否正确理解了问题。这也会给你争取一些时间去思考答案。总是问一些澄清性的问题,尤其是当你被卡住的时候。不要害怕与面试官交流你的困惑,并寻求暗示。你可以问,“我在考虑用 XX 来回答这个问题。你觉得我走的路对吗?”。好的面试官应该总是给出正确的暗示。在我的第一次数据科学面试中,我被要求写一个 SQL 查询,我安静地完成了它,没有做任何解释。面试官不得不问我,“你解决完了吗?”让我和他谈谈。为了更好的面试表现,你最好总是避免这种情况。

4。不断观察面试官的反应

观察面试官对你的回答的反应是很重要的。确保不要自言自语,不断提醒自己注意听众的反应。你可以直接通过摄像头查看,或者问你有没有把自己解释清楚。当您正在进行演示,并且在共享屏幕时可能看不到观众时,这一点尤其重要。不断检查你的听众是否理解你的回答,并给他们机会问后续问题。

5。问你最后准备的问题

如上所述,你应该提前做一些研究,以便在面试结束时问出有意义的问题。你应该经常问问题,以显示你对这家公司的兴趣。一定要问一些不太复杂也不太专业的问题,让面试官在短时间内无法回答。您可以通过研究其最近推出的项目、有趣的产品功能、在线网络研讨会或博客帖子来找到定制的有趣问题。或者你可以为了自己的利益问一些你真正想知道的问题。例如,如果你将来需要比较工作机会,你可以问一些问题,如公司文化,你申请的职位的共同职业道路,以做出明智的决定。

5。别忘了说谢谢

不管你对面试感觉如何,你都应该表达你的感激之情来结束面试。你应该感谢面试官花时间面试你,回答你关于公司/团队/角色的问题。在疫情期间,我有时会以“谢谢你给我机会和除了我的猫之外的人交谈”来结束谈话。我期待着尽快收到你的回信”。

面试后

虚拟面试结束后,别忘了给你的招聘人员发一封感谢信。此外,让他们知道你已经完成了面试,你期待着尽快得到他们的消息。如果你在面试中遇到任何问题,比如电脑坏了,耳机没了,确保在下次面试前升级或修复你的设备。

这些是我为更好地准备虚拟面试的建议。只要你不断从经验中学习,通过足够的实践,你总是会在面试中变得更好。感谢您的阅读。这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!

https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3 https://zzhu17.medium.com/membership

如何在 5 条线内打败侧手翻游戏

原文:https://towardsdatascience.com/how-to-beat-the-cartpole-game-in-5-lines-5ab4e738c93f?source=collection_archive---------8-----------------------

没有人工智能的简单解决方案

CartPole 是一款在开放式人工智能健身房强化学习环境中的游戏。它在许多教科书和文章中被广泛用于说明机器学习的力量。然而,所有这些机器学习方法都需要大量的编码和大量的计算能力来训练。有没有更简单的解决方法?

答案是肯定的。在本文中,我将展示一个极其简单的解决方案。虽然它只有 5 行长,但它的性能优于任何常见的机器学习方法,并完全击败了 CartPole 游戏。现在我们开始吧!

目录

  1. 车杆问题综述
  2. 对一些简单政策的分析
  3. 得出 5 行解决方案
  4. 结论

横竿问题综述

翻转问题也称为“倒立摆问题。它有一根连着手推车的杆子。由于极点的质量中心高于其支点,这是一个不稳定的系统。官方的完整描述可以在 Open-AI 网站的这里找到。

磁极以一个小扰动开始于一个直立的位置。目标是左右移动手推车,以防止杆子倒下。

以下是该系统的图解(如果你想知道如何设置 OpenAI Gym 环境并渲染这个图解,这篇文章可以提供帮助)。

图片由作者提供,由 OpenAI Gym CartPole-v1 环境渲染

在 OpenAI CartPole 环境中,系统的状态由四个参数(x,v,θ,ω)的“观察值指定,其中

  • x:购物车的水平位置(正表示向右)
  • v:小车的水平速度(正意味着向右移动)
  • θ:极点和垂直位置之间的角度(正表示顺时针方向)
  • ω:极点的角速度(正表示顺时针旋转)

给定一个观察,玩家可以执行以下两个可能的动作中的一个:

  • 0:向左推购物车
  • 1:将推车推到右边

当杆偏离垂直超过 15 度(|θ| ≥ π/12 ≈0.26)时,游戏“完成”。在每个时间步中,如果游戏没有“完成”,那么累计“奖励”增加 1。游戏的目标是获得尽可能高的累积奖励。

让我们详细看看下面的例子:

观察结果:

  • x=0.018:小车在原点 O 的右侧
  • v=0.669:手推车向右移动
  • θ=0.286:极点位于垂直方向顺时针方向(0.286/2π*360≈16.4 度)
  • ω=0.618:磁极正向旋转

Action=1:玩家正在向右推车

累积奖励=47:玩家在这场游戏中成功维持了 47 个时间步

Done=1:这个游戏已经“完成”(因为|θ| > 15 度)

现在我们明白了这个设置。让我们看看如何玩这个游戏来获得高额奖励。

对一些简单政策的分析

在强化学习的上下文中,“策略”本质上意味着一个函数,它接受一个观察(或一系列观察)并输出一个动作。

随机策略

在我们尝试变聪明之前,让我们首先想象一只猴子随机地左右推动手推车,看看它的表现如何。这可以帮助我们建立一个基线。当然,它的实现非常简单:

def rand_policy(obs):
    return random.randint(0, 1)

我们将这种“随机策略”玩了 1000 次,并绘制出每次游戏的累积奖励。我们可以看到平均回报是 22.03,标准差是 8.00。

Theta 策略

当然,我们可以做得比猴子更好。在 Géron,Aurélien 的书中:用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习(第 18 章),有一个非常简单的策略,只取决于极点的角度θ:

def theta_policy(obs):
    theta = obs[2]
    return 0 if theta < 0 else 1

用简单的语言来说,它说如果极点向左倾斜(θ <0), then push the cart to the left, and vice versa. Very intuitive, isn’t it? It’s indeed better than the random policy, with the mean reward almost doubled to 41.67.

And the following is one iteration to show how it performs. It indeed shows some intention to prevent the pole from falling.

One game played by the Theta Policy

Analysis of the Theta Policy

Although better a monkey, the Theta Policy is far from satisfactory. For those with some physics backgrounds, this policy is obviously flawed. Because when the cart is pushed to the left, the pole gets a clockwise 角加速度,而不是顺时针方向的角速度。这个动作的结果是磁极可以顺时针旋转,也可以逆时针旋转。此外,当极点已经向中心移动时,比如θ > 0 和ω < 0,这个动作(向右推)仍然会加速角速度向中心移动,而不是减慢角速度。因此,极点超过了中心。

基于上述力学分析,一个更合理的命题是,当杆远离垂直位置(ω<0)时,向左推动小车(action = 0)。反之亦然。由于它只取决于角速度ω,我们姑且称之为“欧米伽策略”。它的实现就像 Theta 策略一样简单:

def omega_policy(obs):
    w = obs[3]
    return 0 if w < 0 else 1

惊喜!基于一个简单的物理定律,一行字的改变就把可怜的 Theta 政策变成了赢家!这项欧米茄政策平均获得约 200 英镑的奖励!

为了欣赏这 200 个平均奖励,我们来比较一些常见的机器学习策略的平均奖励。请记住,这些机器学习策略要复杂得多,难以解释,并且需要长时间的训练才能达到这些结果:

  • 时序神经网络(在盖伦的书中):大约 46
  • 深度 Q 学习(在第一篇 ): ~130
  • 深度 Q 学习(在第二篇 ): ~200

你可以看到,我们的两行 Omega 策略的性能已经与人工智能驱动的深度 Q 学习策略不相上下,甚至更好。

官方钢管舞网页定义,如果连续 100 次测试的平均奖励>为 195,问题就“解决”了。因此,我们的双线欧米茄政策已经解决了侧翻问题!

得出 5 行解决方案

虽然简单的欧米茄政策已经解决了翻筋斗的问题,但我仍然不满意。快速可视化揭示了原因:

欧米茄政策的一次迭代

我们可以看到游戏结束不是因为杆子倒了而是因为大车偏离原点太远了。这表明该策略成功地“稳定”了极点(保持角速度ω ≈ 0),但处于“平铺”位置(角度θ ≠ 0)。所以手推车一直朝一个方向移动。这并不奇怪,因为欧米伽策略对角度θ没有任何影响。

发现问题后,很容易提出改进的策略:

  • 当角度θ“小”时,我们要稳定 θ。这与欧米茄政策相同。
  • 当角度θ“大”时,我们要修正 θ,即给一个朝向中心的角加速度。这与 Theta 策略相同。

至于“小”和“大”的标准,还没有很好的定义。但合理的起点是 15 度“完成”阈值的 10%,即~0.026。实际上,结果对这个值并不十分敏感。从 0.02 到 0.04 的任何值都可以产生惊人的结果。以下是一个使用 0.03 作为阈值的示例:

def theta_omega_policy(obs):
    theta, w = obs[2:4]
    if abs(theta) < 0.03:
        return 0 if w < 0 else 1
    else:
        return 0 if theta < 0 else 1

这种简单的 5 线政策有多好?

答对了!杆子根本不能倒!一次也没有!累积奖励上限为 500 的原因只是由于 CartPol-v1 环境本身的限制——当游戏进行到 500 个时间步时,它会自动停止。换句话说,我们的θ-ω策略不仅“解决”了问题,还“打破”了游戏!

下面是这个简单的五行策略在实际行动中的表现:

θ-ω策略的一次迭代

系统设置、分析和 GIF 生成的完整记录可从 GitHub 的这里获得。

结论

显然,这不是人工智能练习。但是通过展示如何在 5 行中打破掷球游戏,我希望你能体会到物理定律是多么的简洁。本质上,我们利用了几千年来 人类 学习的结果,来代替 机器 学习代码,得到了一个好得多、简单得多的结果。

因此,下次我们应用任何机器学习算法时,最好先检查现有的知识。

你错过了 LightGBM。它在各个方面都击败了 XGBoost

原文:https://towardsdatascience.com/how-to-beat-the-heck-out-of-xgboost-with-lightgbm-comprehensive-tutorial-5eba52195997?source=collection_archive---------1-----------------------

再也不会了,XGBoost,再也不会了

在这个全面的 LightGBM 教程中学习如何碾压 XGBoost。

照片由 GR 股票 Unsplash。 除特别注明外,所有图片均为作者所有。

我很困惑。

如此多的人被 XGBoost 吸引,就像飞蛾扑火一样。是的,它在著名的比赛中经历了一些辉煌的日子,并且它仍然是最广泛使用的 ML 库。

但是,就性能而言,XGBoost 已经 4 年没有占据头把交椅了。2017 年,微软开源了 LightGBM(光梯度增强机器),它以 2-10 倍的训练速度提供了同样高的精度。

考虑到大规模百万行数据集的普遍存在,这是一个改变游戏规则的优势。还有其他一些区别使天平向 LightGBM 倾斜,使它比 XGBoost 更有优势。

在本文结束时,您将了解到这些优势,包括:

  • 如何为分类和回归任务开发 LightGBM 模型
  • XGBoost 和 LGBM 之间的结构差异
  • 如何使用提前停止和评估集
  • 支持强大的分类功能,速度提升高达 8 倍
  • 使用 LGBM 实现成功的交叉验证
  • 使用 Optuna 进行超参数调谐(第二部分)

https://ibexorigin.medium.com/membership

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

https://alphasignal.ai/?referrer=Bex

XGBoost 与 LightGBM

当 LGBM 发布时,它在生成决策树的方式上有了突破性的改变。

XGBoost 和 LightGBM 都是 ensebmle 算法。他们使用一种特殊类型的决策树,也称为弱学习器,来捕捉复杂的非线性模式。

在 XGBoost(和许多其他库)中,决策树是一次构建一层的:

图片来自 LGBM 文档

这种类型的结构往往会导致不必要的节点和叶子,因为树会继续构建,直到到达max_depth。这导致了更高的模型复杂性和运行时培训成本。

相比之下,LightGBM 采用了一种基于叶子的方法:

图片来自 LGBM 文档

该结构随着最有希望的分支和叶子(具有最大 delta 损失的节点)继续增长,保持决策叶子的数量不变。(如果这对你来说没有意义,不要多心。这不会妨碍你有效使用 LGBM)。

这也是 LGBM 刚出来的时候在速度上碾压 XGBoost 的主要原因之一。

图片来自 LGBM 文档

上面是 XGBoost 与传统决策树和 LGBM 与叶式结构(第一列和最后一列)在大约 500k-13M 样本数据集上的基准比较。说明 LGBM 比 XGB 快几个数量级。

LGBM 还使用连续特征的 h istogram 宁滨,这比传统的梯度提升提供了更高的速度。宁滨数值大大减少了决策树中需要考虑的分裂点的数量,并且它们消除了使用排序算法的需要,排序算法总是计算量很大。

受 LGBM 的启发,XGBoost 还引入了直方图宁滨,这带来了巨大的加速,但仍不足以与 LGBM 相媲美:

来自 LGBM 文档的图像直方图-宁滨比较-第二列和第三列。

我们将在接下来的章节中继续探讨这些差异。

模型初始化和目标

和 XGBoost 一样,LGBM 也有两个 API——核心学习 API 和 Sklearn 兼容 API。你知道我是 Sklearn 的忠实粉丝,所以本教程将重点介绍那个版本。

XGBoost 和 LGBM 的 Sklearn 兼容 API 允许您将它们的模型集成到 Sklearn 生态系统中,以便您可以在管道中结合其他变压器使用它们。

Sklearn API 使用熟悉的fit/predict/predict_proba模式公开LGBMRegressorLGBMClassifier:

objective指定学习任务的类型。除了常见的binarymulticlassregression任务,还有其他的poissontweedie回归。完整的目标列表请参见文档的本节。

>>> reg.fit(X, y)LGBMRegressor()

控制决策树的数量

集成中决策树的数量会显著影响结果。您可以在分类器和回归器中使用n_estimators参数来控制它。下面,我们将在具有 1000 个决策树的 Kaggle TPS March 数据集上拟合 LGBM 二元分类器:

添加更多的树会导致更高的精度,但会增加过度拟合的风险。为了解决这个问题,你可以创建许多树(+2000)并选择一个更小的learning_rate(稍后会详细介绍)。

像在 XGBoost 中一样,将单个决策树与数据相匹配被称为提升回合

提前停止

集合中的每一棵树都建立在最后一棵树的预测上,即每一轮提升都是上一轮的改进。

如果预测在一系列回合后没有改善,那么停止集合的训练是明智的,即使我们没有在n_estimators中硬停下来。

为此,LGBM 在fit函数中提供了early_stopping_rounds参数。例如,将其设置为 100 意味着如果预测在最后 100 轮中没有改善,我们就停止训练。

在查看代码示例之前,我们应该学习一些与早期停止相关的概念。

评估集和指标

只有当您将一组评估集传递给fit方法的eval_set参数时,才能启用提前停止。这些评估集用于跟踪从一轮提升到下一轮提升的预测质量:

在每一轮n_estimators中,单个决策树被拟合到(X_trainy_train),并且在通过的评估集上进行预测(X_evaly_eval)。预测的质量通过eval_metric中的合格指标来衡量。

训练在第 738 次迭代时停止,因为自第 638 次迭代以来验证分数没有提高——提前停止 100 轮。现在,我们可以随心所欲地创建任意多的树,并且可以丢弃不必要的树。

建立基线

让我们用目前已知的信息建立一个基准分数。我们将对 XGBoost 进行同样的操作,以便我们可以比较结果:

LGBM 在大约 4 倍的运行时间内实现了较小的损失。在我们继续交叉验证之前,让我们看看最后一个 LGBM 技巧。

分类和缺失值支持

LGBM 中的直方图宁滨内置了对缺失值和分类特征的处理支持。TPS March 数据集包含 19 个类别,到目前为止,我们一直在使用一次性编码。

这一次,我们将让 LGBM 处理类别,并再次将结果与 XGBoost 进行比较:

要指定分类特性,请将它们的索引列表传递给fit方法中的categorical_feature参数:

如果在使用 LGBM 时使用pandas.Categorical数据类型,可以实现高达 8 倍的速度提升。

该表显示了两个模型的最终得分和运行时间。如您所见,使用默认分类处理的版本在准确性和速度上都胜过了其他版本。干杯!

使用 LightGBM 进行交叉验证

用 LGBM 做 CV 最常见的方法是使用 Sklearn CV 分割器。

我不是在谈论像cross_validatecross_val_score这样的效用函数,而是像KFoldStratifiedKFold这样的分裂器和它们的split方法。这样做 CV,让你对整个过程有更多的掌控。

我已经多次谈到交叉验证的重要性。你可以阅读这篇文章了解更多详情。

此外,它使您能够在交叉验证期间以一种轻松的方式使用早期停止。下面是 TPS 三月份数据的样子:

首先,创建一个 CV 分解器——我们选择StratifiedKFold,因为这是一个分类问题。然后,使用split循环每个训练/测试组。在每一次折叠中,初始化并训练一个新的 LGBM 模型,并可选地报告分数和运行时间。就是这样!大多数人都是这样做 CV 的,包括在 Kaggle 上。

结论

在这篇文章中,我们学习了 LightGBM 的纯建模技术。接下来,我们将探索如何使用 Optuna 充分利用 LGBM 模型的性能。

具体来说,本文的第二部分将包括最重要的 LGBM 超参数的详细概述,并介绍一个经过良好测试的超参数调优工作流程。它已经出来了—在这里阅读它。

您可能也会感兴趣…

</tired-of-cliché-datasets-here-are-18-awesome-alternatives-from-all-domains-196913161ec9> </7-cool-python-packages-kagglers-are-using-without-telling-you-e83298781cf4>

欢迎来到公民数据科学家的时代

原文:https://towardsdatascience.com/how-to-become-a-citizen-data-scientist-294660da0494?source=collection_archive---------1-----------------------

数据科学在很大程度上已经被大众化。AI 现在是主流!

公民数据科学家改变组织的工作方式——来自 Pexels 的凯拉·伯顿摄影。

数据科学不再是财大气粗的大公司的专属领域。

人工智能终于进入了我们的日常生活,你开始看到它在所有行业中得到更广泛的应用只是时间问题,而不仅仅是金融!

随之而来的是新一代的数据科学家,公民数据科学家。

谁是公民数据科学家?

公民数据科学家是指在统计和分析之外的领域工作,但仍然创建或生成包含预测或说明性分析的模型的人。

从医疗保健到零售,几乎每个行业都有公民数据科学家。

https://pub.towardsai.net/data-science-will-be-democratized-9263d6ac009d

在过去,许多人会被称为业务分析师或知识工作者,因为他们依靠自己的洞察力和理解来做出决策。

在当今世界,他们将预测分析作为日常工作的一部分。他们可能不会实现所有的分析技术,但是他们可以判断结果是否有意义。

为什么这很重要?

组织越来越多地使用分析来优化其业务的各个方面,从定价决策到招聘策略。

然而,许多组织发现,IT 无法满足将分析融入日常运营的需求。公民数据科学家填补了这一空白。

公民数据科学家不需要[接受分析或数学方面的培训](http://Five Steps for Building a Successful BI Strategy l Sisense. https://www.sisense.com/blog/five-steps-for-building-a-successful-bi-strategy/),也不需要对所用系统有深入的 IT 知识。他们必须知道什么结果是合理的,并在需要时寻求帮助。

公民数据科学家的角色和职责是什么?

公民数据科学家的工作职责通常不包括处理数据。他们是主流员工,利用预测分析的力量做出更好的决定,这些决定会影响他们的工作绩效,如产品植入或客户定位。

公民数据科学家通常不会构建复杂的模型,因为他们使用的是其他人的数据。相反,他们评估结果,并为经理或其他非技术人员解释结果。

通常,公民数据科学家孤立工作,交换意见或分享最佳实践的机会有限。与同龄人合作是学习新技术和获得更多洞察力的绝佳方式。

成为公民数据科学家的最佳途径是什么?

你不需要成为统计或分析专家。不过,如果你想成为一名公民数据科学家,你应该接触一些技术,如回归分析。

然而,更重要的是您了解预测分析的业务应用。

例如,线性回归可能不是您的应用程序的最佳技术,但是您应该能够判断模型何时过度拟合。

如果你有一些编程能力也会有所帮助,但这不是必需的。你不需要知道如何用 R 或 Python 编程,但熟悉 SQL 和 Excel 会有帮助。

例如,用 SQL 编写一个联合语句对于实现一个成功的模型是至关重要的。

如何成为一名公民数据科学家?这里有一个 5 步方法。

提高您的数据素养

数据素养是理解和交流分析技术及其见解的能力。除了解释数据和得出真知灼见,一个好的数据素养的人会问正确的问题来创造性地解决问题。

提高数据素养的最佳方式是与数据科学家或分析师合作。Kaggle 等平台使之成为可能。另一方面,你也可以尝试一个好的数据素养在线课程。

以下是您可以尝试的程序列表:

  • 数据流畅性:在 LinkedIn learning 上探索和描述数据;
  • 【Tableau eLearning 的全民数据扫盲;
  • Coursera 上的医疗保健数据素养,以及;
  • edX 的数据素养基础。

为工作选择合适的工具。

要成为一名成功的公民数据科学家,您需要学习数据科学家工具的基础知识。

基本编程技能很重要,因为它们可以帮助将非结构化或无组织的数据转换为结构化和连贯的数据集。但是很好地理解无代码平台是必不可少的,比如 Tableau , KNIME ,更不用说 Excel 了。

Tableau 是数据可视化中最常用的工具之一。您可以用 Tableau 连接您的数据集,并使用其拖放界面来创建交互式可视化。也可以从预定义的模板或数据集开始。

KNIME 是另一个开源平台,允许用户使用各种工具创建流程、探索和挖掘信息。它为分布式架构上的大数据集提供了大量的数据查询、转换和分析模块。

Excel 被誉为电子表格之王。它为数据争论提供了强大的功能,大多数人觉得它很容易使用。对于数据科学的初学者来说,这是一个非常好的工具。

很好地理解 SQL 也很重要。虽然各种工具都为初学者提供了向导,但要有效地查询数据集,理解其基础知识是必要的。

找数据科学项目来实践。

在实际数据上练习您的数据科学技能是一个好主意。你可以在各种平台上找到令人兴奋的数据集进行研究和实验。

尝试使用不同的工具分析相同的数据,并比较每种工具提供的见解。

大多数企业数据科学问题已经解决,并且易于复制。你可以找到真实的数据以及它们的解决方案。

还有各种数据科学虚拟竞赛可以参加。例如, Kaggle 为数据科学家提供了一个平台,让他们在现实世界数据集和奖金的挑战中竞争。

请求数据访问并复制您的成功。

一旦你对现实世界的项目进行了充分的实践,就很容易接近公司高管并要求提供数据。

通过参与挑战或在项目中练习来应用你所学到的东西,将有助于你交流你所获得的知识。

在向高层推销之前,做好调查是很重要的。熟悉公司数据,了解公司员工目前拥有多少访问权限。这样,你就可以证明为什么他们需要你的技能!

掌握“数据讲故事”的艺术

要成为一名成功的公民数据科学家,你不需要拥有数学或计算机科学的高等学位。相反,学会分析,学会用数据创造引人注目的故事。

成为一名公民数据科学家需要的不仅仅是技术技能;这意味着理解业务问题,并找到组织中其他人可以使用的见解。最好的方法是与人们交谈,找出他们需要解决的问题,以及他们希望这些结果如何呈现。

要创建一个出色的数据故事,需要关注五个基本要素:

1.你的听众——你将与谁交谈?他们知道什么,或者不知道什么?

2.发生的事情——你交流的目的是什么,现实中发生了什么?

3.轶事——你给观众什么样的背景来帮助他们更好地理解发生了什么?

4.分析——如何用简单的术语解释你的见解?

5.结论——这对观众有什么影响?他们应该从这次谈话中学到什么?

最后的想法

随着 AI 在企业中越来越成为主流,非技术人员正在发挥比以往任何时候都更加突出的作用。

公民数据科学家已经出现,以帮助弥合可能不擅长算法或机器学习技术的 IT 专业人员与知道如何从大型数据集识别见解但缺乏技术技能的业务利益相关者之间的差距。

本文讨论了您可以从哪里开始,您应该学习什么工具和技术,以及在将结果展示给高管时如何推介这些结果。

你对公民数据科学家有什么看法?请在评论中告诉我。

感谢阅读,向我问好LinkedInTwitterMedium

还不是中等会员?请使用此链接 成为会员 因为,在不为你额外付费的情况下,我为你引荐赚取一小笔佣金。

2021 年如何成为计算机视觉工程师

原文:https://towardsdatascience.com/how-to-become-a-computer-vision-engineer-in-2021-c563545d4c9a?source=collection_archive---------3-----------------------

意见和建议

排名第一的大规模开放式在线课程(MOOCs)

图多尔·巴休在 Unsplash 上的照片

我在 2020 年才成为一名专业的计算机视觉工程师,但我用来进入机器学习行业的步骤和策略在短时间内发生了剧烈的变化。

人工智能以创新的速度前进

你可能不会对人工智能行业的不断变化感到惊讶,因为你很清楚人工智能以创新的速度前进。

我的观点是,在 2020 年对大多数 ML 从业者有效的获得角色的方法,在 2021 年可能不一定有效。我们都需要适应。

这篇文章将介绍八种方法,你今天可以探索和使用,以开始你成为计算机视觉工程师的道路。

1.大规模开放在线课程(MOOCs)

MOOC 海报 2013 年 4 月 4 日,作者 Mathieu Plourde,在 Flickr 上获得 CC-BY 许可,探索了“大规模开放在线课程”即 MOOC的含义

MOOCs 是 2008 年推出的一种现代学习工具,目前是数据科学家和机器学习从业者获得领域专业知识的首选方法,通常伴随着公认的认证和证书。

在大多数情况下,MOOCs 比通过学术机构和大学学习的传统方法要便宜得多。通过折扣和支付计划为学生提供资金支持的 MOOCs 并不少见。

与学术机构相比,MOOCs 的另一个优势是在适合你的时间灵活地参加课程、在线课程和考试,而不是严格的时间表和考试时间分配。

“教育不是减少群体数量。教育就是要帮助每个学生成功。”

—吴恩达

互联网上有大量与计算机视觉相关的 MOOCs 你可能面临的主要障碍是选择满足你需求的合适的在线课程。

我建议,首先观察求职者对技能和技术的要求,然后反向选择合适的在线课程。

以下是一些 MOOCs 的链接:

  • 成为计算机视觉专家
  • 深度学习专精
  • 带 TensorFlow 的高级计算机视觉
  • 深度学习 TensorFlow 简介
  • deep learning AI tensor flow 开发者职业证书
  • 计算机视觉简介
  • 计算机视觉基础知识
  • 程序员实用深度学习

有很多 MOOCs,但在搜索时,要考虑以下因素:工作相关性、技术需求、时间长度、课程回顾和成本。

mooc 不仅仅是为初学者设计的,经验丰富的 ML 从业者和深度学习工程师参加特定计算机视觉相关主题的中级和高级 mooc,以提高技能或获得领域专业知识。

在 2021 年,速度、适用性和实用性是 ML 从业者的主要关注点。为了从机器学习的学生过渡到专业人士,选修 MOOCs 以专注于 ML 的实践方面,而不是大学教授的理论内容,可能是一个节省时间和成本的决定。

请注意,在大学获得高级学位是有好处的,你应该在做出职业决定之前进行自己的深入研究。

2.机器学习库和框架

作为一个领域,计算机视觉包含许多方法和技术来解决常见的 CV 问题,如对象检测、人脸识别、姿态估计等。

通常不指望你重新发明轮子或开发新算法来解决琐碎的计算机视觉任务(除非你在研究中工作)。你在学习和职业生涯中会用到的许多工具都可以通过 ML 库和框架获得。

ML 库和框架为 ML 从业者提供了一套工具来实现、培训、测试和部署计算机视觉解决方案。有流行的工具和库,如 TensorFlow 和 PyTorch ,还有其他的如 FastAI , Caffe2 , Keras , Scikit-Learn, MXnet , Darknet 等。

左: TensorFlow Logo 右: PyTorch Logo

ML 行业似乎已经决定将 TensorFlow(Keras)和 PyTorch 作为行业标准。作为一名计算机视觉工程师,我广泛使用 TensorFlow 平台为不同的环境开发 ML 模型。

这里有一个典型的清单,当你学习一个 ML 库的时候,你可以用它作为指导:

  • 为训练构建和加载数据集
  • 预处理各种形式的数据集(文本、图像、数值)
  • 执行数据扩充
  • 从头开始实现一个神经网络
  • 从零开始实现深度神经网络
  • 实现网络定制培训流程
  • 利用各种网络架构进行图像分类
  • 用于迁移学习的负载模型
  • 从头开始实现神经网络中的自定义层、删除层和公共层
  • 训练深度学习模型
  • 用 TensorBoard 监控训练过程
  • 保存并加载一个训练好的模型。

注意:上面的列表并没有包含你需要知道的所有内容,事实上,我怀疑我已经触及了你应该涵盖的 20%,以确保你为一个专业的简历工程师角色做好准备。尽管如此,上面的列表只是一个指南,你可以随意添加和修改。

3.读书

要在 2021 年及以后成为一名计算机视觉工程师,你必须参考实用的机器学习和计算机视觉书籍作为学习资源。

一个计算机视觉工程师从来不会停止学习,主要是因为人工智能领域每天都在进步。

在保持职业生涯的同时,与学生在同一水平学习的 ML 从业者很常见。我知道这一点,因为我是那些仍然必须阅读书籍、博客、研究论文和文章的 ML 从业者之一,以确保我不会落后于 ML 行业。

向 CV 工程师强烈推荐的书籍之一是 Aurélien Géron 的用 Scikit-Learn、Keras、& TensorFlow 进行机器实践学习。这本书适用于所有 ML 实践者,从数据科学家到 NLP 工程师

用 Scikit-Learn、Keras、& TensorFlow 进行动手机器学习

我明确地试图让你明白,阅读实用书籍应该是你正在进行的个人学习策略的一部分。

假设你在你选择的领域中发现了你可能缺乏专业知识的特定领域,无论是数学、统计、编程还是算法。在这种情况下,有大量的实用书籍,易于遵循,对所有不同水平的 ML 从业者都有效。

4.云服务

计算机视觉工程师应该了解云服务吗?

是的,但你不需要成为专家,云计算和数据工程师的唯一职责就是专注于云计算解决方案和服务。

尽管如此,CV 工程师了解如何在云服务上运行机器学习模型是必不可少的,例如 GCP 、微软 Azure 和 AWS 。

以下是 CV 工程师应该了解和利用云服务的一些原因:

  1. 计算资源可用性。训练深度学习模型可能会很昂贵,尤其是如果你必须购买价值数千美元的工作站和机器。云服务提供不同计算规格的 GPU 来运行特定的作业。这些计算机资源按小时收费。
  2. 远程访问共享工作区。大多数团队利用在线开发环境的云服务产品来确保每个团队成员都能访问远程工作区和资源。
  3. 现成的解决方案和训练有素的模型
  4. 通过 API 等为机器学习模型服务的平台。

使用云服务可能会令人望而生畏,有时会出乎意料地昂贵— 尤其是如果您忘记关闭实例。就技能组合而言,拥有云服务知识确实会让你在行业内的简历工程师中名列前茅。

5.证书

我不是指参加在线课程时获得的证书或认证。有给 ML 从业者的认证,可以显示在某些库、云服务和框架方面的专业知识。

TensorFlow、AWS 和 GCP 都是我在本文中提到的工具和资源。另一个信息是,提供这些工具和服务的公司和组织也颁发认可的证书。

几年前,拥有一个拥有高级学位的投资组合就足以获得 ML 职位。随着越来越多的 ML 从业者涌入,招聘人员和雇主使用认证来筛选候选人似乎是合理的。

以下是与洗钱从业者相关的认证清单:

  • TensorFlow 开发者证书
  • 谷歌云 ML 工程师证书
  • AWS 认证机器学习专业
  • 谷歌云专业数据工程师
  • 谷歌云协理云工程师
  • 深度学习。AI TensorFlow 开发者职业证书

从这一点开始,成为一名计算机视觉工程师的章节包含了显而易见的信息。不过,有些内容你会觉得很有价值。

6.深度学习

深度学习是一个与利用深度人工神经网络来检测数据中的模式有关的领域。

计算机视觉工程师通常利用深度学习模型来解决 CV 任务。说 CV 工程师必须理解 DL 领域内的基本概念和思想是轻描淡写的。

2021 年,深度学习将从主要利用卷积神经网络作为模型的构建模块,转向最近推出的 Transformer 架构。

这很可能不是一项工作要求,即 ML 从业者了解如何实现和利用计算机视觉任务的变压器— 主要是因为这仍然是一个研究领域。

一些积极主动的 ML 实践者现在正在探索变压器,并了解它们是如何实现和应用的。

7.移动和边缘设备

Instagram、抖音、YouTube、脸书……这些都是拥有移动应用的公司,你会发现它们以某种形式或方式利用了 ML 模型。

2021 年,计算机视觉工程师必须了解能够在移动环境中开发和集成模型的工具和框架。

CV 工程师应该了解几个平台、工具和框架,下面是几个:

  • tensor flow Lite
  • CoreML
  • 苹果愿景框架
  • 张量流-反应
  • CreateML

了解计算机视觉和深度学习在移动环境中的应用的一个有用的学习资源是《云的实用深度学习、移动&边缘 这本书。

8.编程语言

任何形式的软件工程职业都需要了解至少一种编程语言。

通常,计算机视觉工程师精通 Python。你很可能会发现,在大多数机器学习相关的工作岗位中,Python 是最受欢迎的编程语言。

2021 年,CV 工程师将需要至少掌握一门语言的专业知识,并在另外两到三门语言方面处于中级水平。

这是因为深度学习模型在不同的平台和环境中使用。这些环境中的每一个都利用其他核心编程语言来执行功能和操作。

我目前正在移动环境中集成深度学习模型,这要求我精通 Python、JavaScript 和 Swift。2021 年,我将扩展我的编程语言技能,包括 Kotlin 和 Java。

这里的诀窍是不要把一种语言中所有可用的语法都塞进去,然后继续学习下一种语言。相反,更重要的是理解面向对象编程的基本原则和大多数编程语言中使用的编码模式。

结论

对计算机视觉/深度学习工程师的需求很可能会随着更多面向相机的人工智能应用的采用而增加。

为了成为 CV 工程师,ML 从业者需要学习的内容可能非常多,但是一旦你开始学习,完成一些 MOOCs,并获得核心 ML 库,你会发现学习变得越来越容易。

在这篇文章中,我提出了八种方法,你可以在 2021 年成为一名 CV 工程师。概括地说,下面是一个总结列表:

1。参加在线课程,以获得专业知识或提高知识。

2。使用机器库和框架。

3。阅读实用的 ML/DL 书籍

4。了解云服务,如 GCP、AWS 等

5。考虑获得某些工具和库的认证

6。了解深度学习基础知识

7。选择能够在移动环境中集成深度学习模型的工具、库和框架。

8。理解编程模式和原则,比如面向对象的编程。

愿意更进一步吗?

随着生产中机器学习模型的数量增加,开发可靠、安全和可靠的基础设施的需求也在增加。机器学习操作(MLOps)是将软件开发和部署实践采用到机器学习工作流中的原则,以便于再现性、可追溯性和部署。

Neptune.ai 是一个平台,它将自己作为 MLOps 和开发一个强大的机器学习应用程序所涉及的许多过程中的一个过程的解决方案。更具体地说,Neptune.ai 帮助注册从机器学习管道和工作流中产生的元数据。有关该系统如何应用于计算机视觉的更多信息,请访问以下链接:

https://neptune.ai/blog/mlops-pipeline-for-computer-vision-image-classification

**感谢阅读 **

想要更多吗?

  1. 成为推荐媒介会员,支持我的写作
  2. 订阅 在我发布文章时得到通知
  3. 通过 LinkedIn 联系我
  4. 跟我学学 奥赖利

如何成为数据分析师和数据科学家

原文:https://towardsdatascience.com/how-to-become-a-data-analyst-and-a-data-scientist-fe32986b403e?source=collection_archive---------7-----------------------

当你可以尝试两个角色时,为什么只选择一个呢?

照片由来自佩克斯的詹姆斯·惠勒拍摄

如果你一直在寻找数据分析的职业生涯,你可能会有一个常见的问题是,你应该成为一名数据科学家还是数据分析师。我的经历不同寻常,因为我首先是数据科学家,然后是数据分析师。在身兼两职后,我意识到,如果我先成为一名数据分析师,我会在数据科学家的职位上取得更大的成功。今天我想讨论为什么你应该首先考虑成为一名数据分析师,然后再决定你是否想成为一名数据科学家。

进入壁垒

与数据科学家相比,成为数据分析师的要求较低。如果你只有学士学位,你可以通过在线学习必要的技能或参加分析训练营成为一名数据分析师。成为一名数据科学家可能需要你获得研究生学位,这意味着在你满足数据科学家角色的要求之前,你需要在学校花更多的钱和时间。数据分析师主要需要了解 SQL,但数据科学家也需要了解编程、机器学习、高等数学和统计学。

如果你不确定你是否喜欢一份整天分析数据的工作,那么不要花额外的钱和时间去获得高级学位来学习数据科学技能。先学 SQL,找个数据分析师的工作,搞清楚自己的兴趣所在。如果你发现你想研究机器学习问题,你可以继续学习成为数据科学家所需的技能。

因为我是一名数据科学家,所以一开始我必须学习更多的技能来完成我的工作。要快速上手,压力要大得多。在我成为数据分析师后,工作变得更容易了,因为我已经具备了当数据科学家时的必要技能。如果我一开始是一名数据分析师,我就可以逐渐建立起自己的技能组合,减少同时学习多种技能的压力。

获得数据体验

应届毕业生的一个普遍问题是,在没有任何经验的情况下,如何获得第一份工作。由于对数据分析师的要求较低,成为数据分析师更容易首先获得成为数据科学家所需的分析经验。如果你不能在作为数据分析师的工作中学习编程和机器学习,通过参加在线课程和用 Kaggle 竞赛练习构建模型来补充你的知识。

作为一名数据分析师,确定机器学习模型可以解决的痛点,并将它们作为项目推介给利益相关者。这些项目将为你提供一个实践机器学习和解决实际商业问题的机会。例如,当我是一名数据分析师时,销售团队有两名代表全职手动检查公司数据库中的数百万用户,以确定更有可能升级到团队许可证的单个许可证用户。寻找好的潜在客户非常耗时,因为销售代表一次只能找到一个用户。我开发了一个机器学习模型,选择最有可能升级的用户,让销售代表首先联系,这有助于用更少的时间提高转化率。我能够利用一个业务问题来练习在工作中建立一个机器学习模型,并在我面试下一份工作时将其作为一个话题。

发展软技能

数据分析师支持多个利益相关者,并更经常地提供结果,因为请求的周转时间比数据科学项目更短,而数据科学项目可能需要数周时间来开发机器学习模型。这意味着作为一名数据分析师,你有更多的机会练习发展你的演示和数据讲述技能。了解公司的 KPI 以及它们之间的相互关系,是从您的分析结果中有效呈现可行见解的关键。

由于我首先是一名数据科学家,我不知道如何将我的模型结果与 KPI 联系起来。这导致了许多从未被采用的模型,因为我无法说服我的利益相关者他们的价值。如果我首先是一名数据分析师,当我成为一名数据科学家时,我会学会如何有效地展示我的结果,并能够说服我的利益相关者采用我的模型。

向数据科学过渡

一旦你做过数据分析师,学会了如何处理数据,证明了你可以建立机器学习模型来解决业务问题,并学会了如何有效地展示你的数据结果,那么你就可以尝试申请数据科学家的工作了。

如果已经有一个数据科学小组,那么向数据科学过渡的最简单方法就是在同一家公司内部。你更有可能被接受成为数据科学家,因为你熟悉数据,你是一个已知的量,并且将需要更少的时间来达到实际项目的速度。培训新员工很费时间,能够快速提供价值是招聘经理要考虑的一大问题。

另一个选择是申请初级数据科学家职位。数据科学家职位的要求很高,因为雇主不想雇用没有经验证明的申请人。然而,有了数据分析经验和建立机器学习模型的已证实的业务影响,雇主更有可能忽略典型的要求。

结论

如果你无法在数据科学家和数据分析师之间做出决定,可以考虑先成为数据分析师,然后逐步学习成为数据科学家所需的技能。这将允许您更早地尝试数据分析角色,以避免在意识到自己犯了错误之前花费更多时间来学习数据科学技能,并在研究生院投入更多资金。如果你最终快乐地成为一名数据分析师,那么你就为自己节省了时间和金钱。不管你决定选择哪一个角色,现在你知道你可以选择两者都尝试。

你可能也会喜欢…

如何成为 2021 年的数据科学家

原文:https://towardsdatascience.com/how-to-become-a-data-scientist-in-2021-9e0535924d45?source=collection_archive---------27-----------------------

让你被雇用的完整指南

图片作者,照片(右)来自 unsplash

如果你渴望在 2021 年成为一名数据科学家,那你来对地方了。在这本大规模的深度指南中,我将带您一步一步地了解我成为数据科学家的过程。当然,从零开始成为一个人需要决心、动力和大量的自律。如果你认为你已经准备好迎接挑战,请继续阅读。

内容

  1. 你应该成为一名数据科学家吗?
  2. 你在数据科学领域的理想角色
  3. 资格检查
  4. 提升您的数据科学技能
  5. 从事项目工作
  6. 建立你的在线形象
  7. Linkedin 和网络
  8. 打造你的简历
  9. 被录用!

1.你应该成为一名数据科学家吗?

你应该问的第一个问题是,为什么是数据科学家?

围绕数据科学话题的炒作是非常真实的,但这不应该是你进入这一领域的唯一原因。事实是,成为一名数据科学家绝非易事。数据科学家需要某种查看数据的诀窍,这涉及大量的实验、研究、批判和分析思维。媒体经常将数据科学描绘成邻家的酷孩子,致力于人工智能等令人惊叹的技术,但每个热门词汇的背后都是数小时的辛勤工作和毅力。

如果你认为你已经做了你应该做的研究,并且决定 Data Scientist 适合你,这里有一个好消息。

现在是进入数据科学的最佳时机。

除了这样一个事实:

  1. Linkedin 报道称,人工智能专员是 2020 年排名第一的新兴工作,
  2. 世界经济论坛预测,2022 年,数据科学和相关行业将净增 5800 万个工作岗位
  3. Glassdoor 显示,数据科学家的平均基本工资是 107,801 美元

近年来,数据科学也已基本成熟,其潜力得到了大多数行业的广泛认可。像医疗保健、金融、农业、零售、国防等领域已经看到了它们的运营受到人工智能的影响,并且只会有更多的影响。这意味着,无论是哪个行业,掌握数据科学技能对雇主来说都是有价值的。

此外,学习数据科学从未如此简单!对数据科学的巨大兴趣导致了数据科学资源的爆炸式增长,使该领域的初学者和从业者都受益。视频讲座、博客文章和电子书,各种各样的教学材料可供学习者公开使用。另外,线下面对面的课程现在也很受欢迎,我将在接下来的几节中介绍它们。

那么你应该成为一名数据科学家吗?如果你相信数据科学的潜力,有动力和驱动力,我会说去做吧。

2.你在数据科学领域的理想角色

尽管我把一切都概括为数据科学家,但要明白数据科学中有多种角色。

  • 数据分析师
  • 数据科学家
  • 机器学习专家
  • 数据工程师
  • 商业分析员
  • 人工智能研究科学家,等等

每个角色的细节超出了本指南的范围,但是这篇博客文章很好地总结了这一点。

为什么这很重要?你选择的角色决定了你需要磨练的技能。业务分析师关注产品细节和业务知识,而机器学习专家专注于模型构建。知道你希望专攻哪种角色有助于更好地规划你的学习之旅。一条建议是利用你可能有的任何先前的经验。这样,你可以让自己更受招聘者的欢迎,因为你拥有特定领域的数据分析技能。

在这个阶段做一些自我反省,找到自己真正想要的角色。尽管本指南主要关注数据科学家,但其中许多内容仍然适用于任何其他角色。

3.资格检查

现在检查什么?

现在是时候评估您过去的资历,看看您应该从哪里开始您的数据科学学习之旅。重新开始不重要,重要的是知道在哪里开始。

基本上,您应该尝试检查成为数据科学家所需的这些基本技能;

  1. 概率与统计
  2. 微积分和线性代数
  3. 编程;编排
  4. 数据可视化
  5. 机器学习

你们中的许多人在这个阶段会怀疑自己,怀疑自己的资格是否能够在数据科学领域建立职业生涯。我可以,我向你保证你一定可以。除了像人工智能研究科学家这样的更学术的工作,你当然不需要博士甚至更高的学位来擅长数据科学。

4.提升您的数据科学技能

一旦你知道从哪里开始,就该付诸行动了。学习数据科学通常有三种方式。

  1. 训练营
  2. 研究生学位(硕士或博士)
  3. 大规模开放在线课程(MOOCs)

这些根据个性化学习的能力进行排名,1 为最不可定制,3 为最灵活。没有一条完美的路,只有一条最适合你。

训练营

训练营基本上是密集的校园训练,时间从几周到几个月不等。他们的目标是在短时间内覆盖尽可能多的内容,所以你会看到一个非常陡峭的学习曲线。时间也是一个因素,因为这通常需要在课程中投入大量时间。因此,这个选项只推荐给那些能够安排时间的全日制学习者。

另外,这也是这个榜单上最不个性化的选项。主要是因为大多数新兵训练营假设零知识,并试图从零开始教授一切,所以没有必要定制你的经验,因为每个人都是平等的。

新兵训练营的一个好处是有机会和志同道合的人联系。你的学习伙伴会和你一样有动力,每个人都有一个共同的目标。利用这段时间与他人交流,构建您的数据科学圈。

研究生学位

研究生学位通常从 1-2 年的硕士学位到 3-4 年的博士学位。这些都是专业的研究生课程,具有针对您选择的专业的经过验证的课程。一些例子是麻省理工学院的商业分析硕士和哥伦比亚大学的数据科学硕士。此外,这些课程提供了一定程度的个性化,你可以选择你想学习的课程。你将能够掌控你的学习,决定你想要的专业。然而,在这里陈述显而易见的,这也是最昂贵的选择,你必须考虑到这一点。

参加研究生学位课程通常是一个巨大的承诺,所以要确保你已经做了研究。

大规模开放在线课程(MOOCs)

自 MOOCs 诞生以来,它已经走过了漫长的道路。公认的大学正在发布他们的一些模块作为 MOOCs,甚至像谷歌这样的主要科技公司也推出了他们自己的在线课程。MOOCs 不受欢迎、公司越来越接受自学者的时代已经一去不复返了。使用正确的资源和正确的学习途径,任何人都可以通过在线课程建立自己的数据科学技能库。

此外,已经出现了从校园教学到网上授课的转变。对于那些想要在线课程的灵活性和大学的可信度的人来说,edX 或 Coursera 已经与主要大学合作,在他们的平台上提供硕士课程。这将 MOOCs 带到了一个新的高度,改变了在线课程的定义。

无论您选择哪条道路,提升您的数据科学技能只是成为数据科学家的第一步。

5.从事项目工作

虽然课程告诉雇主你了解数据科学,但项目向他们展示了你作为数据科学家的能力。做项目不仅能增加你的简历,还能帮助你建立作为数据科学家的技能。

卡格尔

图片来自https://www.kaggle.com/

Kaggle,最好的数据科学竞赛平台。即使 Kaggle 因其竞争而闻名,但在 Kaggle 上工作本身就是一个项目。竞争数据集通常是由公司提供的真实数据,目的是利用社区的力量来解决他们的业务问题。比赛过程中,你会经历数据采集->数据处理->建模->评估->和优化的全过程,类似于任何现实生活中的数据科学项目。

如果你是 Kaggle 的新手,可以参加几个类别的比赛。首先,有操场或知识竞赛来测试您的基础知识,而特色竞赛可供数据科学家竞争和获奖。如果可能的话,参加一些有特色的比赛,因为在排行榜上给自己排名是一个很好的经历,也是对你简历的一个很好的补充。

然而,主要的缺点是来自 Kaggle 的数据集是预先清理的。在 Kaggle 举办比赛之前,提交公司已经对数据进行了基本的预处理,这大大减少了你的工作量。如果您没有听说过,数据科学家通常会花费 70%以上的时间处理数据,而只有 30%的时间用于建模。

自发项目

我也建议你走出去,做一些自发的项目。它不一定是改变游戏规则或拯救生命。只要新颖和创新就可以了。如果你知道你希望从事的行业,从事与该行业相关的项目可以是一个很好的开始。找到免费可用的数据集或废弃一个网站,经历实验过程,体验作为数据科学家的感觉。没有比拥有自己的宠物项目更好的建议了,你可以自豪地向全世界(和招聘人员)展示。

6.建立你的在线形象

你说的在线状态是什么意思?要成为数据科学家,我需要成为有影响力的人吗?

不完全是,但是接近了。在包括数据科学在内的技术领域,在线业务变得越来越重要。对于像我们这样的自学者来说,在线展示有助于验证我们在数据科学方面的工作和资格。这种确认来自于你在网上的追随者、评论和同行评论。然而,这不是任何社交媒体追随者或参与,我指的是阅读并发现你的文章有趣的人,在该领域与你分享相同想法或问题的人,甚至是从你的想法中获得灵感并使用你的项目的人。

是的,建立你的在线形象最简单的方法就是写下你的想法并分享你的作品。

中等

图片来自https://medium.com/

Medium 是一个在线出版平台,作家可以在这里免费撰写和分享他们的文章。你不需要域名或者主机服务器来在线发布你的内容。只需注册一个帐户,建立您的个人资料,然后写信。Medium 也成为发布数据科学文章的首选平台,使其成为您开始的最佳选择(您认为您为什么会在这里找到这篇文章)。

那么写什么呢?它可以是任何东西或一切。主要目标是写下你的想法,你的旅程,并吸引像你一样的人。

一些博客创意;

  1. 与他人分享您的数据科学课程
  2. 回顾你参加的课程
  3. 关于您的数据科学项目/竞赛的简短报道
  4. 关于数据科学相关问题的思考

开源代码库

图片来自 https://github.com/

哦,是的,Github。

如果你不知道 GitHub,你就不是真正的技术人员。GitHub 是一个开发平台,用户可以以存储库(repo)的形式上传他们的开源代码,以管理或共享他们的项目。此外,它具有强大的内置版本控制功能,这有利于软件工程师和数据科学家,并允许专业人员之间的协作。因此,开一个 GitHub 账户对于在技术领域获得关注大有帮助。一些潜在的雇主甚至可能要求您的 GitHub 评估您的项目、代码和技术能力!

那么你能用 GitHub 做些什么呢?

  1. 上传项目
  2. Fork 有趣的回复
  3. 提交至其他回购

7.LinkedIn 和网络

永远不要低估网络的力量。当走进未知领域时,伸出援助之手很少是件坏事。

这是 LinkedIn 作为社交平台的优势所在。LinkedIn 允许用户建立自己的职业档案,并把有相似背景的人联系起来。您可以在一个平台上找到相似空间中的人,向他们发送个性化消息,并建立有意义的联系。

这里有 4 个技巧可以帮助你优化你的 LinkedIn 个人资料。

商务化人际关系网

1)添加专业的个人资料图片

首先,登录 LinkedIn 后,点击“查看个人资料”来编辑您的个人资料。

个人资料图片和封面图片用于在 LinkedIn 上代表您自己。这是人们在阅读你的个人资料之前看到的第一件事,良好的第一印象很重要。

图片来自 https://www.linkedin.com/

2)填写您的个人资料部分

您的个人资料被分成几个部分,每个部分都讲述了您的一些情况。最重要的部分是你的经历、教育、证书和项目。首先,单击“添加个人资料部分”,将这些部分分别添加到您的个人资料中。

你可以在背景下找到“经验”、“教育”和证书,而“项目”可以在成就下找到。炫耀你的成就,这是你的个人资料,你应该为你所取得的成就感到骄傲。没有什么太微不足道,给自己应得的功劳。也就是说,你的简介应该保持真实。诚实是最好的策略。

3)个性化你的介绍

接下来,个性化你的介绍,按下封面图片下的铅笔符号。改变你的标题以反映你当前的状态。它可以是你目前在公司的角色,目前的教育,甚至是关于你自己的一般陈述。

举个例子,

  • XYZ 公司的数据分析师
  • 斯坦福大学计算机科学专业
  • 数据科学爱好者与志同道合的人联系

任何能真实描述你的东西。标题会出现在你的个人资料图片旁边,所以这也是你的第一印象所在。让它有价值。

4)让招聘人员找到你

完成你的个人资料后,最后一步是让招聘人员知道你对机会持开放态度。回到你的个人资料页面,点击“添加个人资料部分”,在简介下找到“寻找工作机会”。

作者图片

设置完成后,它将出现在您的个人资料中,但仅对招聘人员可见。

现在你已经完成了,拿出你的联系人或前往建议的网络并开始连接。快乐链接。

建立工作关系网

LinkedIn 并不是建立关系网的唯一途径。事实上,与他人面对面交流会给人留下更有影响力的印象,当然也更有意义。加入您当地的数据科学社区,参加聚会,或参加一些数据科学会议。即使你正在使用 LinkedIn,也不要错过这些社交渠道。所有这些都是认识人、收集想法的好途径,谁知道呢,你可能会在其中找到你的下一任老板。

8.打造你的简历

最后,你准备好去找一份数据科学的工作。或者是?

还有最后一个障碍——让雇主注意到你的简历。招聘人员和雇主每次招聘都会收到数百份简历,那么如何让你的简历脱颖而出,而不被过滤掉呢?

1)简介

除了您的姓名,请确保添加您的社交和在线个人资料。这是为了让招聘人员可以很容易地找到你,如果他们想的话。

2)项目

如果您没有任何数据科学相关的经验,我们建议您优先考虑数据科学项目,然后再考虑经验。这样,无论谁阅读它,它都与工作范围相关。

从最有影响力的项目开始,列出你的前三个项目。尝试在你的项目中有一些变化,以显示广泛的能力。

对于每个项目;

  • 确保标题不言自明(例如,使用 Twitter 的推文情绪预测标准普尔 500 的价格)
  • 描述项目:以一个强有力的行动动词开始->你使用的工具->你取得的成果
  • 保持简短,但要客观地展示你的能力

3)经验

作者图片

接下来是经验部分,列出你 2-3 个最相关和最近的工作经验。

如果你没有任何技术经验,这里是你的博客经验可以派上用场的地方。这可能看起来不多,但它肯定会显示你在数据科学领域的热情和动力。

至于其他经历,让它们与雇主相关。即使你的经历与数据科学无关,也要重新措辞,宣传你的软技能,如沟通、领导能力或时间管理。对于一名数据科学家来说,所有这些都和你的技术技能一样重要。

4)技能

作者图片

在这一部分要有战略性和相关性。虽然你几乎可以在这里写任何东西,但是只写最重要的几个,尤其是在“认证和课程”部分。除非你的证书被广泛认可,否则大多数雇主不会在意你参加了什么 MOOCs。只陈述那些受欢迎的或来自高可信度大学的。

至于技术技能,不要列出所有你认为你知道的技能。要有策略。以公司的职位描述为参考,写出你申请的职位所需要的内容。

尽量把你的简历控制在一页以内,最多两页。简洁是关键,在点击发送按钮之前,根据你申请的职位个性化你的简历。

9.被录用

现在,你已经准备好被聘为数据科学家,继续发送你的简历,并希望一切顺利。作为一名自学成才的数据科学家,我对那些走同样道路的人的建议是坚持不懈。数据科学从来都不容易,成为一名数据科学工作者也是如此。评估你的能力,不要害怕从更低的起点开始。

不要等待,积极行动,开始工作,和我一起加入这个令人兴奋的数据科学家职业。

如何成为 Kaggle 比赛的特级大师

原文:https://towardsdatascience.com/how-to-become-a-kaggle-competitions-grandmaster-9d77431c5b7d?source=collection_archive---------15-----------------------

这并不容易,但你能做到,而且值得

在这篇文章中,我将分享几条来自我个人经历的久经考验的建议,关于如何在 Kaggle 上达到最高级别——竞赛大师。这将包括两者——要做的具体实际的事情,以及更多理论性的长期指导方针。现在,让我们去赢得一些奖牌吧!

照片由 Nghia Le 在 Unsplash 上拍摄

让我们先简单介绍一下,什么是 Kaggle,特别是特级大师头衔。

Kaggle 是一个在线数据科学和机器学习社区,提供许多不同的东西——数据集、课程、讨论,当然还有竞赛。我不会深入描述 Kaggle 的细节——如果你不熟悉它,可以去 kaggle.com 亲自看看,或者在 YouTube 上观看这个 1 分钟长的介绍视频。

主要要知道的是,在数据科学和机器学习的世界里,Kaggle 是一个非常值得尊敬的东西。你应该能找到相当多的招聘广告,声称良好的成绩是获得这份工作的一个优势。在 Kaggle 比赛中表现出色可以极大地促进你在数据科学领域的职业生涯。

你是大师吗?

你可以在 Kaggle 上实现的最重要的事情之一是达到比赛大师级。

为了更好地了解大师级是什么,让我们来看看如何获得它。如果你查看 Kaggle 对这一层的描述,你会发现,它需要 5 枚金牌+其中一枚必须是“单人”金牌。

截图自 kaggle.com

为了全面了解需要做什么,我们需要了解如何获得金牌。让我们也检查一下 Kaggle 提供的描述。

竞赛奖牌颁发给最高的竞赛成绩。每场比赛颁发的奖牌数量因比赛规模而异。

截图自 kaggle.com

*(前 10 名+ 0.2%)表示比赛中每增加 500 支队伍,将额外颁发一枚金牌。例如,有 500 支队伍的比赛将把金牌授予前 11 支队伍,有 5000 支队伍的比赛将把金牌授予前 20 支队伍。

5000 支队伍中的 20 支是很小的一部分。事实上,在任何一项卡格尔比赛中获得金牌都是非常困难的。但是难不代表不可能。你可以做一些事情来增加你的机会。

如何在 Kaggle 上获得金牌?

一开始我必须警告你——那不会很快。我花了大约 2 年的时间收集了所有需要的奖牌,并获得了特级大师的头衔。当然,有些人会更快达到这个目标(谁知道呢,也许你就是其中之一),但我认为平均至少需要 2 年。

所以,让我们从一些实用的建议开始,记住让这条路更短…

明智地选择比赛。

在 Kaggle 中,通常在任何给定的时刻都会有几场正在进行的比赛。我建议你一次只打一个。一枚金牌比两枚银牌更有价值。

根据自己的兴趣选择一个比赛。如果你熟悉信用风险评分,并且有一个类似的竞争正在进行,这应该是一个不错的选择。

请记住,表格竞赛通常更受欢迎。他们正在吸引更多的竞争对手,这反过来使他们更难获得更高的位置。

另一方面,计算机视觉竞赛吸引的竞争者往往少得多,主要是因为数据量大。因此,如果你擅长计算机视觉任务,这可能是一个更容易获得金牌的好选择。拥有巨大的计算资源也是一个巨大的优势。它允许参加超大数据集大小(接近或超过 100 Gb)的比赛。不是每个人都有资源在这样的比赛中认真战斗,所以许多强大的竞争者甚至不会进入。这反过来又使我们更容易达到我们的目标——金牌。

根据参赛者的数量来选择比赛是一种选择,但是,我建议更多地关注第一点——根据你的兴趣来选择。

走自己的路。

史蒂文·勒勒姆在 Unsplash 上拍摄的照片

这是非常诱人的分叉得分最高的公共内核,并开始调整其参数,以跳转到更高的排行榜。但是从长远来看,这没有意义。你几乎肯定不会通过调整一些公共笔记本中的参数来获得金牌。

相反,从探索数据开始。理解你被要求解决的问题。熟悉评估指标。对于某些指标,有一些特殊的技巧可以提高分数。你必须像所有顶级竞争者一样了解和使用它们!

阅读竞争论坛中的讨论——有时一些竞争对手会在那里分享非常有趣和有用的发现。

只有当你做了所有提到的事情,只有当你熟悉了问题和数据,开始建立你的模型。

不要重新发明轮子。

数据探索和交叉验证是在比赛中表现良好的两个最重要的事情。遵循这些良好的实践。从所有可能的角度探索数据,以找到重要的见解,并设计相应的功能来捕捉它们。并使用交叉验证来检查新功能。

根据给定数据集的具体情况,并非所有的交叉验证方案都适用(例如,对于时间序列数据,不应使用未来数据)。熟悉不同的验证方法(KFold、GroupKFold 等),以及它们的优缺点。这将允许您为给定的数据集选择最合适的一个。

特性生成有不同的标准方法(如目标编码、宁滨、一键编码等),您应该知道并在适当的时候使用它们。互联网上有许多关于特征工程技术的有用资源。

跳出框框思考。

Erda Estremera 在 Unsplash 上拍摄的照片

在之前的建议中,我告诉你不要重新发明轮子…但是你应该发明一个新的,如果可能的话!最有可能的是,仅仅遵循一个标准的预定义列表,比如如何制作特性、如何调整模型超参数等等,你不会赢得竞争。当然,你也应该做和检查标准的事情,但是要在比赛中真正成功,你需要做更多的事情。

通常,数据中隐藏着一些重要的见解。一些非常强的特征,一些相关性。一些可以显著提高分数的东西。如果它能被标准技术发现,将会有许多竞争者,他们将会发现它。但是,如果它隐藏在更深的地方,可能需要一些非标准的方法。如果你能成功找到这样一种非标准的洞察力,这将是一个非常强大的竞争优势。

不要害怕测试奇怪的想法。大部分都会失败。但有时,一些奇怪的想法可能会起作用——这可能是一个超级功能,让你赢得一些竞争。因为大多数其他竞争者不会发现它——因为它很奇怪。关于测试奇怪的想法,只有一个建议——确保你检查它们,如果它们不起作用就迅速失败。否则,你可能会发现自己花了所有的时间去检查其中的几个。

组成一个团队。

不需要一个人比赛。嗯……除了你要争夺单人金牌的那种情况。但是对于获得剩下的 4 枚金牌来说,成为一个团队的一部分会有很大的帮助。它不仅给你更多的资源,更多的想法,和更多的手来检查所有的想法。这也让竞争变得更加有趣。

从一方面来说,你的队友越多,你的想法就越多,人手也就越多。但是,根据我的观察——有时候,拥有一个非常大的团队并不像看起来那么有益。作为一个大团队的一员,一个人可能会开始依赖这个团队中的“其他人”来完成一些最困难的工作。这反过来可能会导致没有人 100%工作,大团队实际上不如只有 2-3 人的小团队高效。

我个人喜欢较小的团队(最多 4 人),但那只是我个人的偏好。一般来说,这更多的取决于团队成员的个性。

别忘了这是一场比赛。

有些事情在现实生活任务中没有任何意义,但在比赛时却完全有效。

这些问题包括数据泄露、竞赛数据准备的不同问题。其他竞争对手很可能会试图从这些问题中获得一些好处,所以如果你想保持竞争力,你也应该这样做。

另一个非常具体的竞争是所谓的排行榜调查。这基本上意味着进行各种特制的提交,通过观察这些特定提交上的公共排行榜分数来收集关于测试集的信息。

利用数据泄漏或探测测试集并不是真正的数据科学。然而,这些方法并没有被禁止,并且在一些比赛中被许多选手积极使用,所以你应该意识到这一点。

祝你好运!

…您肯定会需要它!在一些比赛中,运气起着非常重要的作用。由于数据的性质和选择的评估标准,当决定谁将获得金牌时,一些比赛实际上可能非常接近彩票。

我不能给你任何关于如何变得更幸运的建议。所以我只能祝你——好运!专注于成为 Kaggle 比赛大师的目标,你一定会成功的!

如何成为一名机器学习工程师

原文:https://towardsdatascience.com/how-to-become-a-machine-learning-engineer-e420e134c0a3?source=collection_archive---------5-----------------------

包含课程的全面路线图

Jaromír Kavan 在 Unsplash 上的照片

职业生涯中更有成就感的很大一部分来自于进步的感觉。有一段时间,那种感觉对我来说是空虚的。是的,我仍然在获得自由职业机器学习合同,但并不完全是我想要的——恕我对我目前的客户直言。虽然我很感激我得到的机会,但我知道如果我想达到我为自己的职业生涯设定的目标,我必须提高自己。

我做自由职业者不是为了做我不想做的工作。

因此,我对成为一名机器学习工程师最需要的技能进行了一些研究。之后,我查阅了每个领域中最有效的课程(从经验和流行观点中)来提高技能。这个想法是为了深入了解作为一名机器学习工程师,我目前缺乏什么技能,这样我就可以专注于改善这些领域,这反过来会使我成为一名更好的 ML 工程师,作为回报,增加我获得更多我想要的自由职业项目的机会。

注意:在机器学习工程师必备技能中,我涵盖了所有这些概念,因此本文将更多地关注在每个领域提升技能的确切课程。

计算机科学

工作软件是一个成功的端到端机器学习项目的成果。因此,ML 工程师被期望具有良好的计算机科学基础知识,因为他们需要优秀的软件工程技能来创建工作软件。构建计算机科学基础的课程是由来自 YouTube 频道 codebasics 的 Dhav Patel 建议的。

  • 数字信息
  • 互联网
  • 编程
  • 算法

程序设计语言

下一步也是最明显的一步是学习编程语言。如果机器学习工程师的输出是可交付的软件,那么你必须学习如何创建软件。这需要编程语言的知识。

Python 是最流行的机器学习语言。我已经为机器学习和数据科学创建了一个学习 Python 的最佳资源列表,所以一定要去看看。根据你的工作地点,一些公司可能会希望你具备 Java 和 C++等其他语言的知识(主要是因为它们比 Python 快)。我个人喜欢用 Codeacademy 学习编程语言。以下是 C++ & Java 各自的课程:

  • 学习 C++
  • 学 Java

注意:先学一门语言(可能是 Python)再继续。

数据结构和算法

当我们谈论机器学习时,数据结构和算法(DSA)经常被忽略,但这并没有真正反映它的重要性。DSA 详细介绍了标准问题的解决方案,并让我们更好地了解如何高效地使用每一个解决方案。

此外,它还教会我们评估算法效率背后的科学,这允许我们从各种选择中决定问题的最佳解决方案。这对于机器学习工程师来说极其重要,因为有时我们可能需要编写自己的算法,因此良好的 DSA 基础是必不可少的。

练习数据结构和算法的最佳课程和地点(根据普遍需求)包括:

  • Python 中的算法和数据结构 (Udemy)
  • 黑客排名算法(问题解决)
  • HackerRank 数据结构(问题解决)
  • Leetcode 算法(问题求解)

注意:你用来学习算法和数据结构的语言并不重要。更敏锐地理解基本原理。

关系数据库

数据是机器学习的前提;没有数据,没有机器学习。尽管该领域正在向涉及非结构化数据(文本、图像、视频等)的其他领域扩展,但仍然可以肯定地说,用于机器学习的大多数数据都是结构化的。结构化数据通常存在于关系数据库中,所有关系数据库都使用 SQL。事实上,大多数大数据工具都使用 SQL,因此值得学习。

  • 学习数据科学的 SQL 基础知识 (Coursera)
  • 用于数据科学的 SQL(Coursera)
  • SQL 训练营 2021:从零到英雄 (Udemy)
  • 终极 MySQL 训练营:从 SQL 初学者到专家
  • 学习 SQL (Codeacademy)

注意:选择完成 1 然后继续前进!

数学和统计

机器学习涉及大量数学。数学是让我们用来挖掘数据模式的算法能够做出决策的工具。尽管我们偶尔需要重温各种数学概念来理解我们的 ML 职业生涯中的不同技术、系统和架构,但在开始时,有一个坚实的基础来让我们开始是很重要的。基础数学可以分为以下几类:

线性代数课程:

  • 机器学习的数学:线性代数
  • 可汗学院:线性代数

微积分课程:

  • 机器学习数学:多元微积分
  • 可汗学院:微积分

概率统计课程:

  • 可汗学院:统计与概率

注意:我们不需要成为高级的数学专家,因为那可能需要一生的时间。目标是有足够好的基础去理解机器学习中的各种概念。

事实上的数据科学图书馆

随着你在成为机器学习工程师的目标上加大赌注,有一段时间你必须专注于事实上的数据科学框架,因为你几乎每天都要使用它们。目前,我们将忽略机器学习和深度学习框架。

  • NumPy
  • 熊猫
  • SciPy
  • Matplotib/Seaborn/Plotly(选一个)

注意:试着用这些框架来构建一些东西。

机器学习算法

不了解机器学习,做一个机器学习工程师是没有意义的。像机器学习中的大多数主题一样,有许多课程可以学习实际的机器学习算法,但对我来说,最好的一门是斯坦福大学的机器学习。

需要了解的关键算法有:

  • 线性回归
  • 逻辑回归
  • 决策树
  • 随机森林
  • 朴素贝叶斯
  • 支持向量机
  • K-最近邻居
  • k 均值聚类
  • 降维算法(即 PCA
  • 梯度推进机器(即 GBM、XGBoost、LightGBM 等)

注意:你还想学习机器学习的 Python 事实框架 Scikit-Learn 。使用框架来构建一些东西是一个好主意。

深度学习

深度学习是机器学习的一个不断发展的子领域。深度学习的架构受到大脑结构和功能的启发,因此得名“神经网络”。机器学习的良好基础,尤其是线性回归,使深度学习的进展更加简单。我推荐参加 DeepLearning.ai 的深度学习专业,学习 TensorFlow 或 PyTorch 。

注意:挑哪个都没关系;选择一个,变得真正优秀。对于那些决定学习 TensorFlow 的人,我也建议你考虑参加 TensorFlow 开发者证书——我还没有参加过,但肯定会参加。

MLOps

MLOps 是机器学习领域的最新热潮。这是机器学习的 DevOps 等价物,ML 工程师应该知道这一点。这可能会促使你知道,现在我接触的大多数人都与 MLOps 有关,这是一个非常有趣的趋势。如果您想学习 MLOps,可以查看以下资源:

  • 面向生产的机器学习工程(MLOps)专业化 (Coursera)
  • 介绍 MLOps (本书)
  • MLOps(机器学习操作)基础知识(Coursera)——本课程是准备谷歌云认证:机器学习工程师的一部分

额外学习

一旦你学会了上述技能,你就可以作为一名机器学习工程师开始工作了。下面的技能是“很好拥有的”,将帮助你从竞争中脱颖而出,所以学习每一项技能以及何时应用它们都是有价值的。

  • PySpark
  • Hadoop
  • 码头工人
  • 用于机器学习的 CI-CD
  • 使用 Git 进行版本控制
  • FastApi,Tensorflow 服务
  • NoSQL 数据库

最后的想法

成为机器学习工程师是一项艰苦的运动。你必须致力于发展你的技能,这样你才能自信地构建和部署机器学习系统。

没有必要学习本文中的每一门课程。一个更好的解决方案是找到你缺乏能力的领域,并致力于发展这个领域。在整个过程中,也试着利用你正在学习的资源通过博客、视频博客、项目等建立你的文件夹。

感谢阅读!

如果你喜欢这篇文章,请通过订阅我的免费 每周简讯与我联系。不要错过我写的关于人工智能、数据科学和自由职业的帖子。

相关文章

*https://medium.com/analytics-vidhya/courses-to-learn-data-science-in-2021-a52e64344e5c https://medium.datadriveninvestor.com/machine-learning-engineers-must-read-these-5-books-583e81922b84 [## 为 ML 工程师的角色开发软件工程技能

towardsdatascience.com](/developing-software-engineering-skills-for-a-role-as-a-ml-engineer-7cd27ebfc526)*

如何成为熊猫绝地武士

原文:https://towardsdatascience.com/how-to-become-a-pandas-jedi-bad82667b34c?source=collection_archive---------21-----------------------

提高数据分析技能的实用指南

(图片由作者提供)

Pandas 是一个流行的 Python 数据分析和操作库。它提供了各种操作、转换和分析数据的功能。

了解函数的作用是很重要的。但是,更重要的是,我们应该知道对于给定的任务使用哪些函数。在一个典型的例子中,我们没有被告知应用一个特定的函数。相反,我们被赋予一项任务,并期望完成它。

要成为熊猫的主人,我们应该在选择和应用适当的功能来完成任务时感到舒适。它需要对功能的全面理解和大量的实践。

在本文中,我们将在一个超市的数据集上进行一些典型的数据分析和操作任务。重点不是熊猫的某个功能。相反,我们专注于给定的任务,并试图实现一个有效的解决方案。

这是数据集的概述。我已经删除了 Kaggle 上的原始版本中的一些专栏。

import numpy as np
import pandas as pddf = pd.read_csv("/content/supermarket.csv", parse_dates=['date'])
df.head()

(图片由作者提供)

注意 : Parse_dates 参数存储数据类型为 datetime 的给定列。这在处理日期和时间时很重要。

让我们假设,对于一个特定的分支机构,我们需要计算连续两天之间总销售额的最大差值。这可能有助于我们理解增加销售的因素。我们也可以发现是否有非常情况。

最好在编写代码之前设计我们的解决方案。我们可以按如下方式完成这项任务:

  • 过滤属于感兴趣分支的数据点(即行)
  • 选择“日期”和“总销售额”列
  • 按日期将数据点分组并计算总和
  • 按日期对结果排序
  • 计算两个连续日期之间的差异
  • 选择最大值

这似乎是一个非常复杂的操作。然而,熊猫提供了多功能和强大的功能,使我们能够轻松地处理这些任务。

这是我们的解决方案:

df[df.branch == 'A'][['date','total']]\
.groupby('date', as_index=False)\
.sum()['total'].diff().max()2888.53

让我们详细说明代码。第一行筛选属于分支 A 的数据点,并选择日期和总计列。第二行按日期对行进行分组。group by 函数的输出自动按日期排序,因为我们使用日期作为分组列。如果没有,我们可以在 groupby 函数之后使用 sort_values 函数。

第三行计算每组的总量(即每天)。然后,我们选择 total 列并应用 diff 函数。它计算一行与其前一行之间的差异。因为这些行是连续的几天,所以我们最终得到的是连续两天的销售额之差。最后,我们使用 max 函数来查看最大差异。

我们知道最高的差异,但不知道日期是没有用的。因此,我们应该稍微改进我们的解决方案。

df_sub = df[df.branch == 'A'][['date','total']]\
.groupby('date', as_index=False).sum()df_sub['diff'] = df_sub['total'].diff()df_sub.sort_values(by='diff', ascending=False, inplace=True)

第一个操作创建一个 dataframe,其中包含分支 a 的每日总销售额。第二个操作创建一个列,其中包含连续两天的总销售额之差。最后,我们根据降序对行进行排序。

df_sub 的第一行显示了与前一天差异最大的日期。

(图片由作者提供)

我们可以通过检查 2019 年 2 月 16 日和 2019 年 2 月 17 日的总金额来确认结果。

(图片由作者提供)

需要注意的是,这可能不是这项任务的唯一解决方案。Pandas 提供了各种功能和技术,这使它成为一个多用途和强大的数据分析工具。因此,我们可能会为给定的任务提出多种解决方案。

销售分为 6 个产品线。对于一个特定的分支,我们可能希望将数据帧转换成一种格式,在这种格式中,产品线被表示为列。日期将构成行,值是每天的总销售额。

我们可以按如下方式完成这项任务:

  • 过滤属于感兴趣分支的数据点(即行)
  • 选择“产品线”、“日期”和“总计”列
  • 按产品线和日期对数据点进行分组,并计算每组的总销售额
  • 将数据帧从长格式转换为宽格式

这是我们的解决方案:

df_new = df.query('branch == "A"')[['prod_line','date','total']]\
.groupby(['prod_line','date'], as_index=False).sum()\
.pivot_table(index='date', columns='prod_line', fill_value=0)

我们使用查询函数只是为了演示过滤行的另一种方式。然后,我们选择所需的列并应用 groupby 函数。

pivot_table 函数创建一个类似 excel 的数据透视表。index 参数表示在我们的例子中是日期的行。数据透视表中的值成为总销售额,因为这是唯一合适的选项。如果有多个候选值,我们可以使用 values 参数来指定。

如果某个产品系列在某个特定日期没有销售额,该值将变为“NaN ”,但是我们可以使用 fill_value 参数来更改它。

以下是新数据框架的概述:

df_new.head()

(图片由作者提供)

结论

我认为这篇文章展示了熊猫的力量。它简单高效。语法非常直观,这使得代码易于理解。然而,掌握熊猫就像其他工具一样需要练习。

知道一个函数做什么是一回事,但是我们应该能够组合多个函数来完成一个给定的任务。它需要全面理解函数以及它们如何一起使用。

感谢您的阅读。如果您有任何反馈,请告诉我。

如何成为一名出色的数据分析员工

原文:https://towardsdatascience.com/how-to-become-an-amazing-data-analytics-hire-6d7a1f8be766?source=collection_archive---------20-----------------------

推进您的数据分析职业生涯的技能

照片由 mentatdgt 从 Pexels

如果你是少数幸运的人之一,有一位导师指导你如何推进你的数据分析职业生涯,那么恭喜你,你可以停止阅读了。对于像我一样必须自己解决问题的其他人,我想分享我多年来作为数据科学家和数据分析师所增加的技能,这些技能帮助我提升到下一个级别,希望对你也一样。

1.领域经验

招聘经理希望候选人具有领域经验,因为他们可以将业务绩效与数据联系起来,并为公司提供即时价值。如何获得领域经验很重要。如果可能的话,找一份支持公司多个部门的工作,为自己的成功做好准备。这将帮助你更快地获得领域经验,因为你将参与各种各样的项目。

作为一名数据科学家,我支持电子邮件营销团队,并专注于建立模型以提高客户转化率。我很少与其他小组互动,我的领域经验仅限于电子邮件营销,因为我没有要求从事其他项目。不要像我一样消极。和你的经理谈谈涉及其他部门的项目。与其他团队中的人交流,找到一个可以利用数据解决问题的机会,并将此作为一个项目推荐给你的经理。

2.主题体验

即使候选人有领域经验,雇主可能更喜欢从事特定类型分析的人。例如,雇主可能需要一名在营销归因和计算终身价值方面有经验的营销分析师。

尽可能多的进行分析。自愿接受一个项目,即使你没有被分配,如果它与你过去做过的不同。如果你是一名营销分析师,告诉你的经理你有兴趣了解营销的不同方面。试着做一些涉及电子邮件、SEM、SEO、社交媒体等方面的分析,以获得这些领域的知识。了解这些概念会让你成为一个更有吸引力的候选人,因为这会节省你的新雇主教你的时间。

3。以清晰的方式呈现数据结果

数据素养在许多公司都是一个问题对于雇主来说,能够传达利益相关者能够理解并用于决策的结果是一项宝贵的技能。

不用担心让每一个数据呈现都尽善尽美。向你的利益相关者寻求反馈,并为下次改进而努力。我想说,我的第一次数据展示令人惊叹,但在我学会如何有效地用数据讲述故事之前,我尝试了很多次。每次演示对我来说都是一次练习的机会,我最终成为了一名更好的演示者。

从数据会议中找到过去在线发布的演示文稿并观看它们。研究演讲者如何让观众理解他们的观点,看看你是否能在自己的演讲中运用这些观点。

如果你没有机会展示数据结果,建议每月召开一次团队成员会议,分享他们所做的分析。这为练习演示和观察其他分析师如何演示他们的结果提供了机会。你也可以借此机会询问未来演讲中需要改进的地方。

4.A/B 测试

许多数据科学家和数据分析师的工作需要 A/B 测试经验,你应该想办法把这种技能添加到你的简历中。

要获得 A/B 测试经验,找一份你支持的部门进行 A/B 测试的工作。当我被聘为营销数据分析师时,工作描述并不要求 A/B 测试经验,但营销部门进行了实验,我能够获得 A/B 测试的经验。

如果你不能在工作中获得 A/B 测试的经验,考虑参加一个关于 A/B 测试的课程。与一个完全不知道的候选人相比,知道 A/B 测试概念将有助于弥补你现实生活经验的不足。

5.数据科学

即使你是一名没有兴趣成为数据科学家的数据分析师,学习机器学习的概念仍然是有用的。有一些数据科学家头衔的工作需要一些建模,但主要是数据分析师的职责。

如果是在你和另一个一无所知的人之间,知道如何做模特会扩大你的工作选择,让你成为雇主更有吸引力的候选人。在成为数据分析师之前,我是一名数据科学家,我的机器学习经验无疑帮助我获得了数据分析师的工作。

6.数据库和软件系统

公司可能更喜欢有特定数据库或软件经验的候选人,因为这意味着他们不需要花时间教他们。例如,一家使用 Amazon Redshift 作为他们的数据库和 Tableau 作为他们的可视化软件的公司会更喜欢已经使用过这些系统的候选人。

选择那些你可以接触到以前没有接触过的各种不同系统的工作来扩展你的知识。如果最终的决定是在你和另一个没有这些系统经验的候选人之间做出的,这些很好的技能可能会让天平向你倾斜。选择工作时有更重要的考虑,但在做最后决定时要记住这一点。

7.专业发展

对于在工作中学不到的技能,可以考虑参加课程或会议来学习更多。例如,我自学了 Python,但希望得到讲师的正式培训。我的经理批准了一个由公司出资的为期 3 天的 Python 课程,我在工作日参加了该课程,无需请假。

公司有会议和职业发展的预算。如果你能提出一个好的理由让你的公司付钱,你将得到免费培训,你的公司将从你的新知识中受益。

结论

当我刚开始我的数据分析职业生涯时,我不知道什么技能会让我成为更有吸引力的数据分析候选人。幸运的是,我发现了提升到下一个层次所需的相关技能。如果你正在开始你的数据分析职业生涯,我希望这条建议能帮助你尽快推进你的职业生涯。

你可能也会喜欢…

</7-little-known-factors-to-consider-before-you-accept-that-data-analyst-offer-a27cb36aa285>

如何开始你的 NLP 之旅

原文:https://towardsdatascience.com/how-to-begin-your-nlp-journey-5dc6734dfb43?source=collection_archive---------42-----------------------

了解如何使用 Python 处理文本

图片由巴新设计在 Unsplash 上拍摄

自然语言处理(NLP) 是人工智能中最令人兴奋的领域之一。它允许机器以多种方式处理和理解人类语言,并引发了我们与系统和技术互动方式的革命。

在之前的一篇文章中,我谈到了 NLP,它在现实世界中的应用,以及一些核心概念。现在我想向您展示 NLP 是真实的,任何人都可以开始学习它。怎么会?让我们从一个简单的文本开始,并使用一些 NLP 技术围绕它执行一些探索性的数据分析(EDA)。这样,在忙于任何模型或更复杂的任务之前,我们可以用简单而强大的工具来理解数据。

定义您的文本

斯蒂芬·霍金曾经说过:

“人工智能(AI)可能是人类遇到的最好或最糟糕的事情”

我完全同意他的观点,时间会告诉我们到底会发生什么。然而,这是测试一些 NLP 技术的合适句子。为此,让我们首先将短语保存为一个名为“text”的变量:

text = “Artificial Intelligence (AI) is likely to be either the best or the worst thing to happen to humanity.”

使用 langdetect 库,我们可以检查它的语言,并找出用该语言编写的概率:

import langdetect
from langdetect import detect_langs
print(detect_langs(text))

有超过 99.9%的把握,我们可以说这个短语是用英语写的。您还应该考虑使用 拼写检查功能 来纠正任何语法错误。

人物数量呢?

len(text)

我们有 102 个字符,包括空格。不同字符的数量呢?

len(set(text))

让我们来看看它们:

print(sorted(set(text)))

这里有些有趣的东西。我们不仅计算像“(”和“.”这样的非字母数字字符此外,大写字母和小写字母被认为是不同的字符。

标记化

标记化是将连续文本分割成句子和单词的过程。本质上,它的任务是将文本切割成称为记号的片段。我们使用 NLTK 库来执行这项任务:

import nltk
from nltk.tokenize import word_tokenize
tokenized_word = word_tokenize(text)
print(tokenized_word)

我们可以看到,标记化产生了一个单词列表:

type(tokenized_word)

这意味着我们可以调用其中的元素。

tokenized_word[2:9]

我们有多少代币?

len(tokenized_word)

还有独特的代币?

len(set(tokenized_word))

现在我们可以计算与文本的词汇丰富度相关的度量:

len(set(tokenized_word)) / len(tokenized_word)

这表明不同的单词的数量占总单词数的 85.7%。

小写和标点符号

现在,让我们将文本小写以标准化字符,并为将来删除停用词做准备:

tk_low = [w.lower() for w in tokenized_word]
print(tk_low)

接下来,我们删除非字母数字字符:

nltk.download(“punkt”)
tk_low_np = remove_punct(tk_low)
print(tk_low_np)

让我们想象一下单词的累积频率分布:

from nltk.probability import FreqDist
fdist = FreqDist(tk_low_np)
fdist.plot(title = ‘Word frequency distribution’, cumulative = True)

我们可以看到单词“to”和“the”出现的频率最高,但它们并没有真正给文本添加信息。它们就是所谓的停用词

停用词移除

这个过程包括去掉英语中常见的冠词、代词和介词,如“and”、“the”或“to”。在该过程中,一些看起来对 NLP 目标提供很少或没有价值的非常常见的单词被过滤并从要处理的文本中排除,因此移除了对相应文本没有信息性的广泛和频繁的术语。

首先,我们需要创建一个停用词列表,并从我们的标记列表中过滤它们:

from nltk.corpus import stopwords
stop_words = set(stopwords.words(“english”))
print(stop_words)

我们将使用 NLTK 库中的这个列表,但是请记住,您可以创建自己的停用词集。让我们在列表中查找单词“the ”:

print(‘the’ in stop_words)

现在,让我们清除文本中的这些停用词:

filtered_text = []
for w in tk_low_np:
   if w not in stop_words:
      filtered_text.append(w)
print(filtered_text)

我们可以看到,“是”、“是”、“the”和“or”这些词被从我们的文本中删除了。让我们更新单词的累积频率分布:

删除停用词应该以一种非常有意识的方式进行,因为它会在执行其他任务(如情感分析)时带来巨大的问题。如果一个单词的上下文受到影响(例如,通过删除单词“not”,这是对一个成分的否定),该动作可以改变文章的意思。

除了这个例子之外,可能有必要处理其他类型的特征,如 缩写(如单词“不”,应该扩展为),或 重音和音调符号(如单词“陈词滥调”或“天真的”,应该通过删除它们的音调符号来规范化)。

正则表达式

正则表达式(称为 REs,或 RegExes)是一种嵌入在 Python 中的小型、高度专业化的编程语言,可通过 re 模块获得。通过使用它们,您可以为想要匹配的一组可能的字符串指定规则。你可以问这样的问题“这个字符串和模式匹配吗?”,或者“在这个字符串中有匹配的模式吗?”。

例如,让我们搜索以“st”结尾的单词:

import re
[w for w in filtered_text if re.search(‘st$’, w)]

或者数一数第一个词的元音数(“人工”):

len(re.findall(r’[aeiou]’, filtered_text[0]))

您甚至可以根据条件修改文本。例如,将第二个单词(“intelligence”)中的字母“ce”替换为字母“t”:

x = re.sub('ce', 't', filtered_text[1])
print(x)

你可以在这个链接后面找到更多正则表达式的例子。

结论

我们只是触及了所有可能的和更复杂的 NLP 技术的表面。你可能不仅想分析结构化文本,还想分析从对话、声明甚至推文中生成的所有数据,这些都是非结构化数据的例子。非结构化数据并不完全符合关系数据库的传统行列结构,而是代表了现实世界中可用的绝大多数数据。这是混乱和难以操纵的。

由于数据访问的巨大改进和计算能力的增加,NLP 正在蓬勃发展,这使我们能够在医疗保健、媒体、金融和人力资源等领域取得有意义的成果。

我的建议是:了解 NLP。尝试不同的数据源和技术。实验,失败,提升自己。这一学科将影响每一个可能的行业,我们很可能在未来几年达到一个让我们震惊的进步水平。

对这些话题感兴趣?在Linkedin Twitter 上关注我

如何对 Python 中的函数进行基准测试

原文:https://towardsdatascience.com/how-to-benchmark-functions-in-python-ed10522053a2?source=collection_archive---------34-----------------------

在本文中,我们将讨论 Python 中基准函数的 4 种方法

在 Unsplash 上由 Veri Ivanova 拍摄的照片

前三种方法将帮助我们测量函数的执行时间,而最后一种方法将帮助我们测量内存使用情况。

目录

  • 使用时间库
  • 使用 timeit
  • 使用线条轮廓器
  • 使用内存概要分析器
  • 结论

使用时间库

这是计算函数执行时间的最简单的方法之一。我们实际上是在调用函数之前和之后获得了以秒为单位的时间。两者之差可以给我们一个函数时间的估计。我说估计,因为这是测量单次运行的时间。一个更好的基准测试应该是多次运行它并计算平均花费的时间。

import timedef func():
   lst = [i for i in range(100000)]
   start = time.perf_counter()func()
print(f"Completed Execution in {time.perf_counter() - start} seconds")

下面是输出

Completed Execution in 0.007916 seconds

使用 timeit

Timeit 是 Python 中的内置方法。它让我们指定运行函数的次数,这有助于我们计算函数运行的平均时间。这是比单次运行的执行时间更好的度量。但是,对于耗时较长的复杂函数,这种方法可能并不理想。

一般语法如下

timeit.Timer(funcName).timeit(number=number)

number 是我们希望函数执行的次数。它返回所有单个运行时的总和。为了得到平均值,我们可以用总数除以运行次数。

下面是我们如何测量函数 func() 的平均执行时间

import timeitnum_runs = 10
duration = timeit.Timer(func).timeit(number = num_runs)
avg_duration = duration/num_runs
print(f'On average it took {avg_duration} seconds')

输出如下

On average it took 0.004649160000000001 seconds

我们还可以使用 repeat() 方法多次运行实验(运行函数 n 次)。更简单的说,如果我们把一个实验看作是运行我们的函数 func() 10 次,我们就可以把这个实验做 3 次,得到每个实验的执行时间。

一般语法是

timeit.Timer(funcName).repeat(repeat=num_repetions,number=num_runs)

下面是用它来测试我们的函数 func()

num_runs = 10
num_repetions = 3
ex_time = timeit.Timer(func).repeat(
                     repeat=num_repetions,
                     number=num_runs)
print(f'It took {ex_time}')

这将返回以下输出

It took [0.0494772, 0.04936369999999998, 0.048738000000000004]

类似于 timeit() 方法,它返回 10 次运行的总时间。我们可以用 max() 得到最差时间, min() 得到最佳时间, sum(lst)/len(lst) 得到平均执行时间。

使用线条轮廓器

line_profiles 是一个非常酷的库,可以对函数进行逐行分析。在使用这个库之前,我们需要安装它

conda install -c anaconda line_profiler

我们需要在函数之前添加一个装饰器

@profile
def func():
    lst = []
    for i in range(100000):
       lst.append(i)

因为 line-profiler 提供了逐行分析,所以使用它来理解列表没有多大意义。

在 Anaconda 提示符下键入以下命令

kernprof -l main.py
python -m line_profiler main.py.lprof

第一个命令运行我们的 python 脚本,并将日志存储在一个文件中。第二个命令以易于理解的表格形式显示日志。

下面是第二个命令的输出

line_profiler 的屏幕截图

  • Hit- 该行被执行的次数。
  • 时间- 该行花费总时间
  • -每次点击生产线所用的平均时间
  • % Time- 总执行时间的一部分。从上图中我们可以看到,append 函数占用了大约 57%的执行时间。

如果要更改 line_profiler 函数的执行次数,请使用以下代码

prof = profile(func)
for i in range(10):
   prof()

这将运行该函数 10 次。

使用内存概要分析器

它与 line_profiler 非常相似,不同之处在于生成的日志告诉我们内存使用情况,而不是花费的时间。

首先,我们需要安装库

conda install -c anaconda memory_profiler

我们将不得不像以前一样添加相同的装饰

@profile
def func():
    lst = []
    for i in range(100000):
       lst.append(i)

然后在 Anaconda 提示符下键入以下命令

python -m memory_profiler main.py

下面是输出

memory_profiler 屏幕截图

  • 内存使用量 -该行的总内存使用量
  • 递增 -每次执行该行时内存使用量
  • 出现次数 -该行被执行的次数

结论

如果您想要对一段代码或一个函数进行快速的时间性能测试,您应该尝试使用 time 库来测量执行时间。然而,如果你想要一个更好的估计,考虑使用 timeit 库。

如果您想要更详细的逐行分析,可以考虑使用行分析器和内存分析器。

在 LinkedIn 上与我联系

我最近开始了一个修改版的#100daysofcode 挑战。我的目标是每天写与 Python、数据科学或编程相关的内容。在 Twitter 、 Medium 、 Dev.to 、 Hashnode 或 my WordPress 博客上关注我的进展

原载于 2021 年 3 月 23 日【http://www.realpythonproject.com】

如何从标签扩散算法的半监督学习中获益

原文:https://towardsdatascience.com/how-to-benefit-from-the-semi-supervised-learning-with-label-spreading-algorithm-2f373ae5de96?source=collection_archive---------4-----------------------

机器学习

标注扩散算法如何与 Python 示例一起工作的详细说明

标签扩散。图片由作者提供。

介绍

这是关于半监督学习的第二篇文章,其中我探索了使用有标签和无标签数据来构建更好的模型的方法。

这次我将重点放在标签扩散算法上,该算法试图基于已知的已标记和未标记点揭示的内在结构来构造一个平滑的分类函数。

虽然与标签传播相似,但标签传播做了一些不同的事情,这将在本文后面探讨。

内容

  • 标签传播在机器学习算法领域中的位置
  • 标签传播和标签传播的主要区别
  • 标签传播工作原理的简要说明
  • Python 中如何使用标签扩散?

机器学习算法领域内的标签传播

有时,我们发现自己混合了已标记的数据(非常适合分类或回归等监督学习)和未标记的数据(非常适合聚类或降维等非监督学习)。

然而,为了获得最佳结果,将这两组数据结合起来通常是有益的。这种情况是我们希望使用半监督学习方法的一个很好的例子,标签扩散算法是我们的选项之一。

下面的交互式旭日图显示了不同 ML 算法的分类。确保点击👇对各种类别进行放大,揭示更多的

机器学习算法分类。由作者创建的互动图表。

如果你喜欢数据科学和机器学习 ,请 订阅 每当我发布一个新故事时,你都会收到一封电子邮件。

标签扩散和标签传播的区别

如果您已经熟悉标签传播算法,您可能希望了解标签传播与该算法的两个不同之处。如果您不熟悉标签传播,请随意跳到下一节。

对称归一化拉普拉斯算子与随机游走归一化拉普拉斯算子

标签传播算法在其计算中使用对称归一化图拉普拉斯矩阵,而标签传播使用随机游走归一化拉普拉斯矩阵。

但是,请注意,这两个矩阵是相似的,一个可以从另一个导出。因此,从本文的角度来看,理解这两个矩阵的细微差别对我们来说并不重要。

软箝位与硬箝位

标注传播使用硬箝位,这意味着最初标记的点的标注永远不会改变。

同时,标签扩散采用软箝位,由超参数【α(alpha)控制,该超参数规定了该点从其邻居获得的信息与其初始标签信息的相对量。

标签传播工作原理的简要说明

四个步骤描述了标签扩散算法如何操作。

1。定义点之间的成对关系,称为亲和矩阵 W 。该矩阵是在径向基函数核(也称为 RBF 核)的帮助下创建的,用于确定边权重。注意,矩阵 W 在对角线上包含 0,因为没有边将一个点连接到其自身。

连接每对点的边的权重计算。图片由作者提供。

Note, sklrean's implementation of RBF kernel looks slightly different as it replaces **1/2sigma^2** with a hyperparameter **gamma**. The effect is the same as it allows you to control the smoothness of the function. High gamma extends the influence of each individual point wide, hence creating a smooth transition in label probabilities. Meanwhile, low gamma leads to only the closest neighbors having influence over the label probabilities. 

Sklearn 的 RBF 内核实现。图片由作者提供。

这是亲和矩阵的样子:

亲和矩阵。图片由作者提供。

2。创建对称归一化图拉普拉斯矩阵。这一步采用亲和矩阵 W 并将其对称归一化,这有助于步骤 3 中的收敛。

对称归一化图拉普拉斯矩阵 S. Image by 作者。

3。第三步是迭代,利用矩阵乘法将信息从标记点扩散到未标记点。

寻找标签的迭代过程。图片由作者提供。

每个点接收来自其邻居的信息(第一项),并且还保留其初始信息(第二项)。参数α(α)通过控制从邻居接收的信息与初始标签的比例来实现软箝位。Alpha 接近 0 保留所有初始标签信息(相当于硬箝位),alpha 接近 1 允许大部分初始标签信息被替换。

注意 F(0)=Y,所以迭代过程从初始标签信息开始。

4。在步骤 3 中的过程收敛或达到指定的最大迭代次数之后,我们到达分配标签的最后步骤。

矩阵 F 包含标签向量,表示每个点属于特定类别(即,具有特定标签)的概率。然后使用 argmax 操作选择最终标签,这意味着该算法分配具有最高概率的标签。

Python 中如何使用标签扩散?

终于到了在真实数据上使用标签传播的时候了。

注意,对于这个例子,我们选择了有标签可用的营销活动数据,这将帮助我们评估我们的半监督模型的性能。

当然,在我们拟合模型之前,我们将屏蔽大多数标签,以模拟主要包含未标记数据的场景。

设置

我们将使用以下数据和库:

  • Kaggle 的营销活动数据
  • Scikit-learn libraryfor
    1)特征缩放(minmax scaler);
    2)展开标签(展开标签);
    3)模型评估(分类 _ 报告、混淆 _ 矩阵、混淆矩阵显示)
  • 用于数据可视化的 Plotly 和 Matplotlib
  • 熊猫进行数据操作

第一步是导入我们上面列出的库。

接下来,我们下载并摄取营销活动数据(来源: Kaggle )。这一次我们将只使用两个特征来展开标签。因此,我将摄取限制在几个关键列,而不是读取整个表。

此外,您将看到,我们已经派生了一些创建带有屏蔽标签的目标变量所需的附加字段。

下面的代码片段显示了目标变量的数据和分布。

来自 Kaggle 的营销活动数据。图片由作者提供。

请注意,我们保留了 2%的实际标签(1 和 0),并屏蔽了剩余的 98% (-1)。因此,我们的目标包含关于购物者是否有任何依赖项(1),没有任何依赖项(0),或者该信息被屏蔽(-1)的信息。

我们在这里雄心勃勃,因为我们的目标是仅使用 45 个已知标签为 2,195 个数据点分配标签。

我们使用的特征是 MntMeatProducts (购物者每年在肉制品上的花费) MntWines (购物者每年在葡萄酒上的花费)。现在,让我们看看当我们把数据绘制在图表上时,它是什么样子的。

半监督学习中标记和未标记数据的组合。图片由作者提供。

应用标签扩散算法

下一段代码由几个步骤组成,帮助我们准备数据、拟合模型和打印结果。

结果如下:

标签传播结果。图片由作者提供。

正如你所看到的,尽管非常雄心勃勃,我们还是取得了相当好的结果,模型准确率达到了 82% (为了使评估公平,我们只使用了带有屏蔽标签的记录进行模型性能评估)

让我们再次绘制 2D 图,看看新分配的标签是如何分布的。

标签扩散模型结果的 2D 图。图片由作者提供。

我们可以看到蓝点(无家属)和红点(有家属)的明显区别,决策边界位于肉类花费约 400 英镑,葡萄酒花费约 1000 英镑。所以,根据这些数据,看起来没有孩子的人倾向于吃更多的肉,喝更多的酒。

结论

当您只有少量已标记的示例,并且希望对大量未标记的数据应用自动标记时,标签扩散是一种非常好的算法。

然而,和所有半监督学习技术一样,你需要谨慎对待它。通过创建具有已知标签的测试样本或手动检查标签扩散结果的子样本来评估模型总是值得的。

我希望您喜欢阅读这篇文章,我鼓励您在下一个数据科学项目中尝试半监督学习!如果您有任何问题或建议,请随时联系我们。

干杯👏
索尔·多比拉斯

如果你已经花光了这个月的学习预算,下次请记得我。 我的个性化链接加入媒介是:

https://solclover.com/membership

您可能感兴趣的其他文章:

如何最好地利用 Jupyter 和 Julia

原文:https://towardsdatascience.com/how-to-best-use-julia-with-jupyter-82678a482677?source=collection_archive---------6-----------------------

如何将 Jupyter 代码添加到您的 Jupyter 笔记本中,并使您能够在同一个笔记本中同时使用 Python 和 Julia

来自 Pexels 的 Markus Spiske 摄影

Julia 是一种真正令人兴奋的高级、高性能、动态编程语言。它的语法易于理解,预计将成为未来数据科学的主要编程语言之一。

Jupyter 笔记本是一个很棒的多语言 IDE,我总是用它作为我的默认环境,在将我的代码移植到专门的 python 脚本之前,探索数据并编写初步的代码例程等,这些脚本更适合完整的生产目的,例如在 AWS 上运行的 docker 等。

在下面的步骤中,我将解释如何安装 Julia,以及如何将它作为一个内核添加到 Jupyter 中,这样你就可以有效地用 Jupyter 编写 Julia 代码。

我还解释了如何使用 PyJulia 在 python 笔记本中使用 Julia。这个额外的选项非常强大,因为您可以使用这两种语言的优点,特别是在数据探索和数据可视化方面。

我已经列出了应该完成的步骤,首先说明先决条件,然后安装 Julia,然后解释如何集成 Jupyter 和 Julia,最后详细说明如何在同一个笔记本中混合搭配 Python 和 Julia 代码。

安装 Julia 并在 Jupyter 笔记本中使用

先决条件

这里需要注意的是,我假设你使用的是 Linux 发行版,不管是在专用的 Linux 机器上还是通过 WSL 或 virtualBox,只要你使用的是 Linux 环境,这都无关紧要。此外,您应该已经安装了 Jupyter,并在您的本地机器上进行编码等工作。

安装朱莉娅

首先做一个 Julia 语言的基本安装,从 https://julialang.org/downloads/下载 Julia tar,确保使用稳定版本(目前是 1.6.2)

接下来,只需在终端中解压缩文件,就可以使用了。
tar -xvzf julia-x.y.z-linux-x86\_64.tar.gz

将 Julia 添加到路径变量中,方法是在。zshrc 文件。这假设您使用 zsh 作为 shell,但是如果您使用标准 bash,只需在您的。bashrc 文件。
export PATH="$PATH:/path_to_julia_file/julia-1.0.5/bin"

您可能需要为要更新的路径启动一个新的终端窗口,或者您可以在终端中使用下面的命令来强制刷新当前会话,以使用更新的 zshrc/bashrc 文件:

source ~/.zshrc

通过在终端中键入julia来检查这是否有效,它应该会启动朱莉娅 read(读取-评估-打印-循环),如下所示。

作者图片

将 Julia 内核添加到 Jupyter

要给 Jupyter 添加一个 Julia 内核,我们只需添加 IJulia 包。

为了做到这一点,首先从你的终端启动朱莉娅 REPL 像你以前做的那样。

julia

然后在 REPL 内部首先通过键入以下命令开始使用 Pkg:

using Pkg

然后通过键入以下命令添加 IJulia 包:

Pkg.add("IJulia")

第一次添加包时,它也会构建它,但是如果你更新了某些东西,比如下一次添加的路径,你也需要在添加后构建 IJulia。只有当你改变了 Julia 安装文件的位置并更新了指向新文件的路径时,这才有意义。

Pkg.build("IJulia")

要删除软件包,只需打开朱莉娅 REPL 和运行:

Pkg.rm("IJulia")

如果您启动一个 Jupyter 会话,您现在应该能够选择一个 Julia 内核,如下所示:

作者图片

一旦你用这个内核启动了一个笔记本,你就可以直接开始写 Julia 代码了,就像下面这样,我们直接导入基本库,用它来计算 sine(90)。

作者图片

成功了!在 Jupyter 中,您现在应该有了一个完整的 julia-1.0.5 内核,您可以在其中编写本机 julia 代码。只需启动 Jupyter 并为您的内核选择 Julia,您就万事俱备了。

照片由塞巴斯蒂安·沃特曼从 Pexels 拍摄

在同一个笔记本中使用 Julia 和 Python

如果你想在 Python 内核中使用 Julia,在同一个 Jupyter 笔记本中混合使用两种语言的代码,我们需要做一些额外的设置。

这个额外的选项很有用,因为它意味着你可以保留现有的 python 代码,并添加 Julia 单元格等,而不是将所有的 Julia 和 Python 代码保存在单独的笔记本中。

我个人认为使用 python 作为主要基础语言,然后使用诸如 PySparkJulia 这样的语言作为导入语言是很好的,这意味着你可以从 PySpark 中进行 ETL,在 Julia 中进行快速数据分析,以及一些 python 机器学习都在同一个笔记本中。

应该注意的是,就生产代码而言,使用 Julia 的最佳方式是在完整的 Julia 内核中,如前一节所述,但我觉得下面的选项在数据探索阶段很有用,在这一阶段,您可以使用两种语言的优点,以新的令人兴奋的方式探索数据。

为了建立这种双语言设置,我们首先需要 创建一个自定义版本的 Python ,使用静态和动态 Python 库作为 ,这将确保我们不会失去 Julia 的速度和执行时间优势。

构建 Python 的自定义安装

首先安装下面的包,因为 Python 需要它们。
T0

(如果您忘记了可以在之后安装它们,只需在 python 发行文件夹中重新运行makemake install)

接下来从 http://www.python.org/download/下载 python 3.7

(Python 3.7 与 spark2.x 一起工作时很有用,而 spark3.0 与 Polynote 等一起工作时仍有一些问题)

将 python 安装文件移动到您希望在系统上存储这个定制 Python 安装的文件夹中,展开 tar python 安装文件,并在您的终端中运行下面的配置行。
tar -xvf Python-3.7.8.tgz
cd Python-3.7.8
./configure --enable-shared --prefix=/your/custom/path
make``make test
make install

这就完成了我们的定制 Python 安装的设置。

我们现在将继续讨论如何使用这个定制的 Python 设置在同一个笔记本中编写 Python 和 Julia 代码。

安装 PyJulia

为了在 python 笔记本中使用 Julia,我们需要使用 PyJulia 库。首先,我们创建一个新的虚拟环境,它链接到我们刚刚创建的自定义 Python 设置。

mkvirtualenv -p /your/custom/path/bin/python3.7 julia_env

(请注意,我使用 virtualenvwrapper 来创建我的 python 虚拟环境,并强烈推荐它作为保持虚拟环境良好维护的好方法。更多详情请见此链接https://virtualenvwrapper.readthedocs.io/en/latest/

接下来,在这个虚拟环境中,我们使用下面的命令安装 pyJulia:

python -m IPython
pip install julia

最后,在虚拟环境中添加一个新的 Jupyter 内核,链接到这个 Julia 环境。
python -m ipykernel install --user --name=julia_env

现在你应该能够打开 Jupyter,选择你刚刚创建的内核,如下所示

作者图片

一旦你使用 julia_enc 内核启动了一个 notebok,你现在就可以使用 julia 了,你可以在你的笔记本的任意一个单元格中输入下面的命令来获得正弦值(90)。

作者图片

更好的是,您可以在同一个单元中使用 Python 和 Julia 代码。为了测试这一点,请尝试下面的代码行,在使用 Python 打印 f 字符串中“a”的值之前,我们首先使用 Julia Base 获得正弦值(90)并将其赋给变量“a”。

作者图片

您还可以使用 cell magic 将一个单元格更改为 native Julia,这应该由命令%load_ext julia.magic加载。加载后,你可以在任何单元格中使用 Julia,只要以%%julia开头。

例如,在一个单元格中键入下面几行,您应该会得到一个使用本机 Julia 语法的单词“Test”的打印输出。

作者图片

如果你没有使用我们的自定义版本的 Python,它同时使用静态和动态库,你会得到下面的错误,但是因为我们已经建立了我们自己的自定义 Python 安装,我们已经安全地避免了这一点:)

Your Python interpreter is statically linked to libpython

摘要

现在,您应该已经成功地在 Jupyter 中安装了 Julia,并且能够在同一个 Jupyter 笔记本中混合使用 Julia 和 Python 代码。有了所有这些选项,您应该可以成为 Julia 编程语言的专家,并处于数据科学新数据科学工具和库的最前沿。

照片由负空间从像素拍摄

如何在 Google Data Studio 中融合数据,让你的网站数据活起来?

原文:https://towardsdatascience.com/how-to-blend-data-in-google-data-studio-to-visualise-how-users-are-using-your-website-e920fb050c57?source=collection_archive---------23-----------------------

通过一个耐克电子商务的例子。

使用数据为决策提供信息对于产品管理至关重要。或者其他任何东西。谢天谢地,我们并不缺少它。任何在线应用都会产生大量的数据,我们有责任收集这些数据,然后理解它们。

Google Data Studio 帮助我们理解数据背后的含义,使我们能够构建美丽的可视化和仪表盘,将数据转化为故事。如果不是的话,数据素养和学习读写一样是一项基本技能。或者肯定会是。

没有什么比数据民主更强大了,组织中的任何人都可以根据数据定期做出决策。作为实现这一目标的一部分,我们需要能够以一种让数据变得生动、更易访问的方式来可视化数据。我最近一直在学习如何做到这一点,并想分享一些你可以在谷歌数据工作室做到这一点的酷方法。

无论是自动化一些日常的手动分析,你都会发现一些很好的用例,帮助你了解用户如何使用你的数字服务。如果你知道 Google Data Studio,并且可能会问自己是否值得花力气去了解更多,那么这就是为你写的。你可能会想,如果你已经从一些现有的数据源(例如其他谷歌产品)中获得了一些现成的分析,为什么还要投入更多的时间呢?你还能真正获得什么价值?基本上,我是为自己写作,6 个月前。

所以,我假设你知道基本知识(比如连接到数据源),但是如果你不知道,这里有一个很棒的教程。在这篇文章中,我将介绍一些你可以做的更高级的事情,比如混合数据、创建自定义计算字段,使用度量级别过滤器以及创建组合图表,所有这些都使用我基于耐克网站创建的一个假数据集。

产品经理的一个常见用例是比较完成某个体验的一组用户占总用户的百分比。这些被称为比率指标。例如,假设你作为一名设计师为 Nike 工作,想了解有多少用户使用你花了很长时间设计的“设计你自己的”训练器功能,想了解有多少用户完成了所有的定制步骤。

Stephan Schmid 在 Unsplash 上拍摄的照片

一般来说,每当用户与网站的某些部分进行交互时,就会触发 Google Events 。您将有一个用户进入定制流程的事件,中间的所有事件,然后是一个用户完成流程的最终事件。您可以通过以下计算手动创建比率指标:

结束流量事件 /进入流量事件 =完成率(新的比率指标)

在 Data Studio 中,您可以通过以下步骤创建它:

  1. 插入一个以唯一事件为度量的记分卡,然后创建一个指定您感兴趣的事件标签的过滤器(例如进入流)。
  2. 插入第二个记分卡,执行与步骤 1 相同的操作,使用您感兴趣的第二个事件标签创建第二个过滤器(例如 ends flow )。
  3. 通过点击两个记分卡并点击“混合数据”来混合两者。

如果你是一个更加视觉化的学习者,这里有一个视频向你展示这是如何工作的:

在 Google Data Studio 中混合数据和记分卡,以创建计算指标。

这对于全面了解你最近设计的东西非常有用。但是为了优化这一点,你需要观察它在一段时间内的趋势。您每次都可以手动计算,但是让您尝试优化的指标自动计算将非常有用,并在未来为您节省大量时间。

对此最好的视觉化是一个组合图。其中比较了用户与该功能交互的会话,以及您试图优化的完成率(您刚刚通过混合数据创建的自定义指标)。

下面的视频将向您展示我们如何实现这一目标的每一步。总的来说,它包括以下四个方面:

  1. 混合相同数据源中的数据,使用 JOIN (每个数据源中的共享维度),它将是月份(但也可以是任何时间维度,这取决于您希望图表有多详细)。
  2. 创建两个单独的指标,它们只包含您感兴趣的事件标签唯一事件。这将通过使用度量级别过滤器来实现,该过滤器过滤您感兴趣的事件标签(例如,用户进入流/用户结束流)。
  3. 选择您的维度,指标#1(会话)并创建一个新字段,该字段是生成指标#2 的计算
  4. 设计图表的样式,使其看起来像一个组合图表,并在左右轴上显示两个数据系列。

这里有一个视频向你展示这是如何做到的:

展示如何在组合图表上创建计算指标的视频,包括混合数据和高级指标级别过滤器。

一旦我们为它添加了一些样式元素和标题,我们就完成了如下的可视化:

显示 Nike 网站整体会话和教练定制流程完成率的组合图。

有了这样清晰的可视化数据,数据就变得生动起来,你对这个特性有了更清晰的了解。你可以立即看到,随着时间的推移,趋势正在下降。这可以帮助您了解您是否进行了影响完成率的产品更改(例如,流程中的额外步骤或更复杂的步骤)。如果你想要更准确的图片,你可以创建一个谷歌分析部分,只包括用户有机会定制他们的教练的会议(因为不是所有的教练都有这个选项)。这不会改变你的完成率,但可能会减少总会话数。

我使用耐克的例子,因为这有望与大多数人相关。但是还有很多其他的电子商务用例。例如:

  • 有百分之多少的人在 AirBnB 上使用某些滤镜?
  • 用户将您的产品添加到购物篮中的会话比例是多少?
  • 有百分之多少的用户登陆你的结账页面,然后决定不买东西?

在仪表板中可视化重要指标意味着您可以更好地优化它们。并轻松衡量您正在构建的任何东西的成功程度。

我希望你觉得这很有用。我不是谷歌数据工作室的专家,但在过去的 6 个月里,我花了很多时间来学习。一旦我学会了,我很想分享它。

如果你想看到最终的可视化和它是如何配置的,这里是数据工作室报告和这里是谷歌表,其中包含一些基于耐克网站的虚假数据。

如果你觉得这很有趣,可以看看我写的其他一些不用写代码就能构建应用的东西:https://UX design . cc/build-an-app-with-Google-sheets-and-glide-1 efcb 0173055或者用一个启动文档启动项目:https://UX design . cc/start-product-initiatives-with-a-kick-off-document-here-is-my-template-77

如何通过 Tmux 将工作效率提高 10 倍

原文:https://towardsdatascience.com/how-to-boost-10x-productivity-with-tmux-ead3d3d452f9?source=collection_archive---------6-----------------------

给高效数据科学家的个人建议

对于数据科学家和软件工程师来说

Tmux 是一个终端多路复用器。这意味着您可以在一个会话中查看多个终端视图和历史记录(由作者提供)

问题陈述

哦不,我关闭了我的终端,失去了我的进度运行

哦,不,我忘记了部署脚本的命令

我希望有简单的方法来跟踪我在多个数据项目中的运行

欢迎来到 Tmux

Tmux 是什么?

Tmux 代表终端多路复用器。Tmux 类似于 GNU screen,托管多个终端(在一个会话中)并跟踪当前或以前的脚本运行历史。所有这些都在命令行(CLI)环境中的窗格中。

Tmux 将使您的工作效率提高 10 倍,因为:

  • 审计:管理多个运行项目的脚本历史
  • 持久化(Persistence):通用布局,你可以一直使用它来记住你的脚本运行,即使你不小心关闭了终端。
  • 多主机:在一个终端上轻松切换多个程序,然后分离并重新连接它们。您现在可以连接并跳转到同步 SSH 会话,并跟踪您的 ML 服务器运行。

这里有一张 gif 图,让你对 tmux 能为你做什么感到兴奋。

tmux 使用(来源于作者)

注意,我在一个会话中运行了一些操作:

  1. 在 tmux 中将我的会话分成多个窗格
  2. 在一个窗格中运行 vmstat
  3. 在一个窗格中运行 netstat
  4. 编辑 new-file.txt 以保存 netstat 结果
  5. 移动到单独的会话窗格并查看 new-file.txt

请注意,如果没有 tmux,您需要在一个终端视图中运行任务,如果您关闭终端,就会丢失您的进度。

有了 tmux,一切都可以以无故障的方式快速完成。

让我们跳到 tmux!

让我们安装 Tmux

Tmux 作为开源托管在 Github 上(也就是说是免费的!).安装 tmux 非常简单。只需运行以下命令

# For Ubuntu and Debian
sudo apt install tmux# For CentOS and Fedora
sudo yum install tmux# For macOS
brew install tmux

给我看看 tmux

创建会话

tmux 是基于会话的。要在 tmux 中启动一个新的会话,只需在终端中键入tmux new。一旦你进入 tmux,唯一明显不同的是底部一直存在的绿色条(参见 自定义主题 部分的自定义选项)

Tmux 围绕着会话,存储命令和历史的大项目。它是概念单元块,供您“附加”/同步到您的项目中。

  • 创建新会话 : tmux new -s tutorial
  • 附加到现有会话 : tmux attach -t tutorial

一旦您连接到一个会话,您将面对一个不同的终端界面(绿色条在底部)。

要退出会话/窗格,可以运行exit命令。另一个绕过所有出口并退出会话的命令是运行detach

运行 tmux 命令

使用前缀

Tmux 中的所有命令都以前缀快捷键开始(默认为 ctrl+b)。每次我们想运行 tmux 命令时,都会使用这个前缀。要启动提示,输入ctrl+b:

注意:我们可以配置新前缀为Ctrl+a。这有助于你更快地执行命令,因为与Ctrl+b.相比Ctrl+a更容易输入

Tmux 命令

有一些您经常使用的重要命令:

  • 重命名会话Prefix + $
  • 分离会话Prefix + D
  • 创建垂直分割Prefix +%
  • 创建水平分割Prefix + “

为了获得更多的信息,我附上了一张有用的备忘单。感谢 linuxacademy.local

tmux 快捷方式(来源 linuxacademy.com)

配置 tmux 命令设置和键绑定

请注意,有一些键绑定并不直观。例如,要创建一个水平分割,您需要运行Prefix + “。这很容易忘记,所以我们需要将键绑定配置成更直观的方式。

自定义 tmux 可以在.tmux.conf file中找到,你可以通过在你的 bash 终端中运行nano命令来编辑文件,或者用任何文本编辑器打开它。

你可以按照我的配置,根据你的喜好进行更新。

# Set prefix (Ctrl+a)
set-option -g prefix C-a
unbind-key C-a
bind-key C-a send-prefix

# Use Alt-arrow keys to switch panes (Alt+left/right/up/down)
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Shift arrow to switch windows (Shft+left/right/up/down))
bind -n S-Left previous-window
bind -n S-Right next-window

# Mouse mode to alter windows
setw -g mouse on

# Set easier window split keys
bind-key v split-window -h
bind-key h split-window -v

# Easy config reload
bind-key r source-file ~/.tmux.conf \; display-message "~/.tmux.conf reloaded."#Set Tmux plugin to resurrect every time workstation restarted (Ctrl+A Ctrl+S to Save / Ctrl+A Ctrl+R to Resurrect)
set -g [@plugin](http://twitter.com/plugin) 'tmux-plugins/tpm'
set -g [@plugin](http://twitter.com/plugin) 'tmux-plugins/tmux-sensible'
set -g [@plugin](http://twitter.com/plugin) 'tmux-plugins/tmux-resurrect'
set -g [@plugin](http://twitter.com/plugin) 'tmux-plugins/tmux-continuum'# Automatically restore tmux windows when tmux starts.
set -g [@continuum](http://twitter.com/continuum)-restore 'on'# Don't auto-launch tmx at machine boot.  Give me a chance to gcert first.
set -g [@continuum](http://twitter.com/continuum)-boot 'off'# Preserves what was readable in each pane.
set -g [@resurrect](http://twitter.com/resurrect)-capture-pane-contents 'on'
set -g [@resurrect](http://twitter.com/resurrect)-strategy-vim 'session'# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'

仅此而已!恭喜你,你刚刚学到了提高工作效率的重要技巧

复活你的 Tmux!

Tmux 复活拯救

我想这个教程如果不提到 tmux resurrect 就永远不会完整。要问的关键问题是“我们如何在重启后保存 tmux 历史”。

这个想法类似于在最终幻想游戏中保存你的记忆文件。

你在新的地牢里升级了。你沿途收集物品并升级你的角色的装备。在一天结束的时候,你教他们新的技能来对抗老板。

但是在冒险在 boss 战斗中死亡之前,你跑到保存点希望保持角色的当前状态。

当你输了这场战斗,你松了一口气,知道你保存了你的游戏,可以再次尝试,直到你胜利。

类似地,tmux resurrect 保存并加载您的最新状态。

这非常有用,尤其是在您运行构建文件来试验您的新模型并生成一个快速的。运行无监督学习的 sh 脚本代码。最可怕的事情是丢失所有访问 ML 日志的命令历史。

因此,如果您丢失了进度,明智的做法是将最新状态加载到内存中。然后,您可以快速跳转到该项目,并在几秒钟内控制所有最新的终端状态。

要用 tmux resurrect 保存状态,只需运行Prefix + Ctrl+S

保存的 tmux 消息(来源于作者)

要将您的状态加载到一个新的会话中,您只需运行Prefix + Ctrl+R

如果操作正确,您将恢复对当前项目很重要的所有命令历史和会话。

Tmux 恢复加载(来源于作者)

恭喜你,现在你已经准备好用 tmux 做一些很酷的事情了!

参考:

下面是一些参考资料,你应该在迷上 tmux 之后阅读。

  • tmux 之道
  • Tmux 快捷键

总之:Tmux 将您的生产力提高了 10 倍

  • 审计:管理多个运行项目的脚本历史
  • 持久化(Persistence):通用布局,你可以一直使用它来记住你的脚本运行,即使你不小心关闭了终端。
  • 多主机:在一个终端上轻松切换多个程序,然后分离并重新连接它们。您现在可以连接并跳转到同步 SSH 会话,并跟踪您的 ML 服务器运行。

我希望这有助于您理解为什么 tmux 是重要的,并使用它来交付真实的数据影响。

索利·德奥·格洛丽亚

关于作者

文森特用 ML @ Google 对抗网络滥用。文森特使用高级数据分析、机器学习和软件工程来保护 Chrome 和 Gmail 用户。

除了在谷歌的工作,文森特还是乔治亚理工学院计算机科学硕士校友、三项全能运动员和面向数据科学媒体的特约作家,该杂志在全球拥有 100 多万观众,为有志于数据科学的人和数据从业者提供指导。

最后,请通过 LinkedIn Medium Youtube 频道 联系文森特

如何通过多重处理提高预测

原文:https://towardsdatascience.com/how-to-boost-forecasting-with-multiprocessing-e78bc5ba6dbc?source=collection_archive---------9-----------------------

理解大数据

何时以及如何通过集中 CPU 和与 Python 并行计算,使用 ARIMA、脸书·预言家和皮托奇·LSTM 神经网络来促进时间序列预测。

由托马斯·凯利在 Unsplash 上拍摄

预测时间序列数据时,有时既需要速度,又需要精度。当使用 Python 在笔记本电脑上工作时,尝试多处理以获得两个世界的最佳效果。

这篇文章可能适合你,如果:

  • 您正试图在本地机器上优化 Python 中的多处理问题
  • 您正在使用 Statsmodels ARIMA、脸书预言家或 PyTorch LSTM 预测时间序列数据
  • 如果您无法使用 GPU,您正在尝试确定多处理是否是 PyTorch LSTM 的最佳配置

有数据,需要时间

大多数时候你有大量的数据。有些时候,你有足够的时间来分析数据,但大多数时候,你需要在任何时候都产生一些东西。但是,随着数据量的增加,您需要更大更好的模型来产生有用的信息。无论你是需要加快调试代码的速度,还是在黄金时间展示一些东西,大数据和深度模型都将吃掉你不能失去的宝贵时间。

在没有 GPU 的情况下,我能在 MacBook 上更快地进行深度学习吗?

当用脸书预言家预测数据时,考虑到机器有 8 个内核,将进程数设置为 8 似乎是一个最佳选择。

多重处理的动机

为了预测准确的趋势和未来的数据点,你需要大量的数据,一个很好的模型,或者两者兼而有之。但是调试可能具有挑战性。可能需要 5 分钟、10 分钟或 20 分钟才能知道一行代码没有正确运行,因为这是模型运行所需的时间。

为了减少你需要在变化中循环的时间,一个更快的机器,一个 GPU,或者某种云解决方案可以做到这一点——但是如果你以上都没有呢?在花钱进行基于云的工作之前,您希望确保您的模型正常运行吗?或者,如果这是您要在应用程序中部署的内容,该怎么办?无论如何,我们想要更快的速度!

在本文中,我分享了几个实验的结果,这些结果可能有助于您构建自己的多处理解决方案来提高速度。

当使用 statsmodels ARIMA 预测数据时,考虑到机器有 8 个内核,将进程数设置为 6 似乎是最佳选择。

调查的结果

首先,一个警告。我只是一个拿着笔记本电脑做了一些实验的人——你的结果可能会有所不同,我的发现和代码应该被仔细检查。除了警告,我认为这些发现值得分享,可以节省你一些时间,或者至少让你思考一些有趣的问题。

  1. 用 ARIMA、脸书·预言家和 PyTorch 在 python 中实现多重处理是可能的
  2. 对于脸书先知来说,8 核机器上的 8 倍池化进程似乎可以产生最佳结果——对于相同的数据和相同的计算,时钟时间减少了 70%。
  3. 对于 ARIMA 的 statsmodels, 6x 池化进程产生了最佳结果,但是 6 个和 8 个处理器之间的差异可以忽略不计——时钟时间减少了 50%。
  4. 对于用 PyTorch 建造的单层 LSTM,有两个有趣的发现。首先,标准配置(无多重处理)优于所有其他配置使用池化进程,完成任务的时钟时间随着池化进程而逐渐变差。第二,通过平均绝对百分比误差(MAPE)测量的误差似乎随着过程数量的增加而稳步下降。

注意时钟时间等:我对每个配置的三次运行结果进行了平均,并将时钟时间作为开始时间和结束时间与 time.time()之间的差值。

当使用 LSTM 预测数据时,合并过程似乎比不合并过程表现得相对更差,但是 MAPE(误差)似乎减少了。“LSTM-1”是指两个 LSTM 实验中的第一个,其中的输入只是一系列价格。

如何使用多重处理进行预测

更快的结果?听起来不错,但是怎么做呢?在接下来的几节中,我将逐步介绍如何修改 ARIMA、预言家和 LSTM 模型来实现多重处理的关键要点。

使用 Statsmodels ARIMA 的多重处理

使用自回归综合移动平均模块,或简称为“ARIMA”,您可能会对预测具有某种季节性的趋势感兴趣。由于在许多其他文章中已经很好地涵盖了 ARIMA 基础知识这里和这里,我将直接演示一个多处理设置。

ARIMA 的基本设置

**# import dependencies**
from statsmodels.tsa.arima.model import ARIMA# some data...
x_i = [4.1, 3.1, 2.5, 4.0]**# a simple model on the data**
m = ARIMA(x_i, order=(0,1,0))**# fit the model** 
m_fit = m.fit()**# forecast/predict the next n steps**
yhat = m_fit.forecast(steps=1)**# then, compare yhat predictions to y targets...**

准备预测数据

由于 ARIMA 最擅长预测训练集之后的几步,所以我修改了一个数据分块脚本,该脚本适用于具有日期时间列和数据列的数据帧。在我的实验中,数据是从上午 9 点到下午 4 点的交易日中每分钟的股票价格。

# dataframe examplecolumns -> 'ds', 'y''ds' data -> 2019-01-01 09:00:00, ...'y' data -> 1.4, ...

data_chunker.py 中的函数返回数据帧的元组列表,其中每一对都是 15 分钟的数据块。

给定一些分块数据,我们可以遍历数据帧列表,用 ARIMA 的函数包装器计算每个块的预测。

为 ARIMA 做好预测准备

如上所述,给定一些分块数据和 ARIMA 的函数包装器,我们可以通过迭代分块数据来调用 run_arima()函数,分块数据只是一个数据帧列表。

将数据组织成一个可迭代对象并将 arima 作为一个函数应用于该对象的这一步非常重要,因为它决定了如何实现多重处理。如果你把这部分做对了,多重处理就变成了一个简单的任务。

**# from main.py, run arima as list comprehension**model = run_arimaresults = [model(i) for i in chunked_data]# from main, iterate through a list of data and with arima function
# within arima function, iterate through the list of chunked data
# return a forecast of each 15 minute period

进口 PyTorch 多处理器

因为我们使用的是脸书 API(PyTorch 和脸书 Prophet),所以我导入了 py torch 多处理器库,它覆盖了基本的多处理器库。

import torch.multiprocessing as mp
# the torch mp is basically the same as
# import multiprocessing as mp# get number of available processes
process_count = mp.cpu_count()

理解 cpu_count()

方法返回可用进程的总数。据我所知,在 8 核的 MacBook Pro 上,cpu_count()返回值 16——我相信这意味着每个内核有 2 个超线程 cpu 进程。在性能测试期间,如上所述,8 倍进程池的性能优于 2 倍进程,也优于 14 倍进程。我的简短结论是,2x 个进程没有充分利用潜在的计算资源,而 14x 个进程相对更差,因为这些进程在每个内核上争夺资源。

为 ARIMA 实施多处理

现在我们已经有了分块数据、arima 函数包装器和迭代 arima 函数的方法,是时候实现多处理了。

**# this needs to be run from main.py or something similar
# import dependencies as required here
# import helper functions and arima wrapper here****# functions must be guarded in this**
if __name__ == '__main__': model = run_arima **# set a pool of 8**
  p = mp.Pool(8) **# iterate run_arima over chunked data**
  results = list(p.imap(model, chunked_data))

  **# close and join pools per the docs**
  p.close()
  p.join()

上面的代码片段展示了一个简化的例子,但是下一个代码要点展示了如何在多重处理时管理函数参数的发送,以及如何添加 tqdm 进度条。

运行相同函数时,使用和不使用多重处理时每秒迭代次数的比较。左:没有池,每秒约 1.5 次迭代。右图:使用池,每秒最多 11 次迭代。

多重处理框架

基于上面 ARIMA 的例子,我们有了一个多重处理的模板。

  • 将数据组织成块,作为一个像数据帧列表一样的可迭代对象
  • 将预测模型应用于分块对象

将多重处理框架应用于脸书先知

脸书先知的步骤非常相似。主要的例外是 Prophet 的实际代码,它期望使用数据帧,并对时间戳的列名为“ds”和数据的列名为“y”有一定的要求。

与 ARIMA 类似,我们可以将 run_prophet 函数分配给一个模型对象,并在模型和数据上迭代池。

将多重处理框架应用于 LSTM

在这里,LSTM 的框架与 ARIMA 或先知的框架并不完全相同,但没关系,他们是非常不同的模型。LSTM 有什么不同?ARIMA 和脸书先知学习一个模型并预测紧随其后的序列,而我们可以使用 LSTM 来预测远在训练窗口之外的序列。举个简单的例子,ARIMA 和预言家可能擅长根据一周的数据进行训练并预测下一周,但他们可能在未来几个月的预测中表现不佳——这是 LSTM 可以做得很好的地方。

我改编了 PyTorch 的示例代码来创建 LSTM 的多处理版本。给定一个创建 LSTM 模型的函数和一个实现训练迭代的函数,下面的多重处理应用可以工作。

# given a model of LSTM
# given a dict of params
# given a function called train_modelmodel.share_memory()

processes = []# assign processes
for rank in tqdm(range(8)):
    # pool data for train_scaled to function train_model
    p = mp.Process(target=train_model, kwargs=params)
    p.start()
    processes.append(p)# join processes after compute
for p in tqdm(processes):
    p.join()

我从 PyTorch 示例中获得的关键见解是, train_model()函数应该迭代通过模型和数据加载器对象,同时调用一个单独的函数在每个时期执行训练。考虑到没有多重处理,上面对 train_model()的调用可以简单到调用函数并将数据和参数作为字典传递。

# given a dictionary of params
train_model(**params)

我认为这突出了像 LSTM 这样的神经网络和像 ARIMA 这样的更简单的模型之间的一个有趣的区别,但是我需要更多地了解计算在每个过程中是如何工作的——也许这是未来帖子的主题。

在不深入研究如何实际构建 LSTM 的情况下(这是一个完全独立的主题),这里有三个配置架构的技巧,假设您对这个主题有所了解:

  1. 在 train_model()中,调用 PyTorch DataLoader 对象、loss 函数并初始化优化器,然后循环 n 个时期。在每个 epoch 内,调用另一个函数 train_epoch()。
  2. 在 train_epoch()中,枚举 DataLoader 对象并在那里应用 LSTM 模型。
  3. 在 main.py 中,为了传递 LSTM 的所有参数,即层数和批量大小等,创建一个字典并将其作为 kwargs=params 传递给流程函数。然后,在 train_model 的函数签名中,确保有一个 **kwargs 参数来接收字典值。

值得一提的是,至少在我的项目实现中,虽然这种池化的方法“有效”,但与不使用池化相比,它在速度方面表现相对较差。仅在这一方面,它可能不值得花时间来实现。另一方面,我可能错过了让它更有效工作的重要步骤,因为我有一些隐式嵌套的 for 循环。此外,还有一个奇怪的情况,为什么当我们有许多进程并行运行时,错误似乎会有所改善——这是一个有趣的话题,改天再来探讨。

这里的完整实现:https://github.com/justinhchae/stocks以及我的项目合作伙伴(内的知识)对 LSTM 模型配置的生产信用。

结论

在本文中,我展示了如何在同一个数据集上采用多重处理框架来预测 ARIMA 和脸书预言家的模型。在这两种情况下,多重处理通过增加每秒的迭代次数导致了 70%到 50%的时间减少。此外,我还演示了如何应用 PyTorch Hogwild 示例让 LSTM 的多处理工作起来。然而,与 ARIMA 和先知不同,LSTM 在速度方面并没有提高,事实上,随着更多的进程,它的性能下降了。然而奇怪的是,随着并行进程数量的增加,LSTM 误差得到了改善——这是一个值得进一步研究的课题。

我浏览了一些相对琐碎的步骤,以提供如何应用多处理概念的概述,但它们仍然很重要。要了解从数据处理到模型设置的细节,请查看我的 GitHub 库。

我最初开始尝试在没有 GPU 的笔记本电脑上改善深度学习,即通过在 MacBook 上共享 CPU 来更快地学习 LSTM。不幸的是,似乎池化的 CPU 并不能为 LSTM 提供速度优势,在这种情况下,更好的硬件可能最终是必要的。

至于接下来的步骤,应该值得将这些代码迁移到类似于 Google Colab 的地方,看看它在 GPU 上的表现如何。

编辑:如果你正在寻找一个更深入的话题,从头开始学习 Python 中的多处理,可以看看我写的一篇涵盖所有基础知识的文章。

https://python.plainenglish.io/how-to-design-python-functions-with-multiprocessing-6d97b6db0214

资源

  • 项目库
  • Statsmodels ARIMA,文档
  • TDS 应用预测文章
  • Spike 的 Prophet 多处理框架来源
  • 数据分块脚本
  • PyTorch 多处理最佳实践
  • 脸书先知 API
  • 关于 Contentsquare 引擎的多处理
  • 关于 LSTM ,由 TDS 提供

如何用 Python 字典增强熊猫的功能

原文:https://towardsdatascience.com/how-to-boost-pandas-functions-with-python-dictionaries-35da25e250d7?source=collection_archive---------6-----------------------

小窍门

举例说明

由比尔·杰伦在 Unsplash 拍摄的照片

Pandas 是一个非常流行的数据分析和操作库。由于简单直观的 Python 语法,Pandas 通常是有抱负的数据科学家的首选。其强大而高效的功能让大量有经验的数据科学家也对熊猫青睐有加。

Pandas 提供了丰富的功能选择,加快了数据分析过程。默认的参数设置在大多数情况下做得很好,但是我们可以通过定制参数做得更好。

除了常量值或列表之外,一些参数还接受字典参数。在本文中,我们将通过几个例子来演示如何使用字典来增加函数的价值。

我们将使用 Kaggle 上提供的墨尔本住房数据集中的一个小样本作为示例。我们首先使用 read_csv 函数读取 csv 文件。

import numpy as np
import pandas as pdcols =['Price','Landsize','Distance','Type','Regionname']melb = pd.read_csv(
   "/content/melb_data.csv",
   usecols = cols,
   dtype = {'Price':'int'},
   na_values = {'Landsize':9999, 'Regionname':'?'}
)melb.head()

(图片由作者提供)

dtype 参数用于指定数据类型。通过使用字典,我们能够分别为每一列指定数据类型。

现实生活中的数据通常是混乱的,所以我们很可能会遇到缺失值的不同表示。na_values 参数处理这种表示。

考虑这样一种情况,即“土地面积”和“区域名称”列中缺失的值用 9999 和“?”表示,分别为。我们可以向 na_values 参数传递一个字典来处理特定于列的缺失值。

字典也使得 agg 函数更加有用和灵活。agg 函数通常与 groupby 函数一起使用。例如,我们可以计算每种类型房屋的平均值和中值,如下所示。

melb[['Type','Distance']].groupby('Type').agg(['mean','median'])

(图片由作者提供)

如果我们想为多个列计算不同的聚合值,该怎么办?对于每种类型,我们可能需要计算平均距离和总价(以百万为单位)。这项任务可以很容易地用字典来完成。

melb.groupby('Type').agg(
   {
      'Distance':'mean',
      'Price':lambda x: sum(x) / 1_000_000
   }
)

(图片由作者提供)

正如您在上面的截图中看到的,聚合值是带 6 个小数点的浮点数。如果我们把他们围起来,他们会更好看。此外,在大多数情况下,我们不需要这样的精度。

round 函数可用于向上舍入浮点数。我们可以传递一个整数来将所有的值四舍五入到相同的小数点位数。但是,如果我们想对不同的列使用不同的小数点位数,我们可以使用字典。

melb.groupby('Type').agg(
   {'Distance':'mean','Price':'mean'}
).round(
   {'Distance':2, 'Price':1}
)

(图片由作者提供)

距离四舍五入到两位小数,而价格只有一个小数点。

字典还向用于替换数据帧中的值的替换函数添加值。通过使用嵌套字典,我们可以指定列、要替换的值以及用作替换的值。

假设我们需要将 type 列中的值“h”替换为“house ”,将 region name 列中的值“Northern Metropolitan”替换为“Northern”。

melb.replace(
   {
      'Type':{'h':'house'},
      'Regionname':{'Northern Metropolitan':'Northern'}
   }
).head()

(图片由作者提供)

结论

我们已经做了几个例子来演示字典如何增加价值或增强 Pandas 功能的能力。默认设置在大多数情况下做得很好,但最好还是想办法充分利用一个功能。

此外,根据给定的任务定制函数的行为可能会好得多。在某些情况下,使用字典作为参数可以让我们在一个步骤中完成需要多个步骤才能完成的事情。

感谢您的阅读。如果您有任何反馈,请告诉我。

如何在 20 天内打破一个模型——生产模型分析教程

原文:https://towardsdatascience.com/how-to-break-a-model-in-20-days-a-tutorial-on-production-model-analytics-25497e2eab9c?source=collection_archive---------14-----------------------

理解大数据

模型如何在生产中失败,以及如何发现它

图片作者。

假设你训练了一个预测模型。并将其设置为常规使用。欢迎学习生产中的机器学习!

现在,您依靠它来做出业务决策。你必须维护、重新培训和关注你的模型。

它会出什么问题,如何保持跟踪?让我们看一个例子。

这是一个关于我们如何训练一个模型,模拟生产使用,并分析其逐渐衰退的故事。

手头的任务:自行车需求预测

在本教程中,我们将处理一个需求预测问题。

数据集。我们拿了一个关于自行车共享需求的 Kaggle 数据集。我们的目标是预测每小时的自行车租赁量。为此,我们有一些关于季节、天气和星期几的数据。

图片作者。

型号。我们使用从一月份开始的四周数据训练了一个随机森林模型。让我们想象一下,在实践中,我们只是开始收集数据,这是所有可用的数据。经过训练的模型的性能看起来还可以接受,所以我们决定试一试。

反馈。我们假设我们只在每个周末了解基本情况(实际需求)。

这是现实世界机器学习中的一个现实假设。集成和更新不同的数据源并不总是简单的。甚至在实际事件发生之后!也许日常使用数据存储在本地,每周只发送一次并合并到数据库中。

当您为不同的未来期间生成预测时,可能会出现类似的延迟。如果你提前一周预测,这个地平线就成了你的等待时间。

模特体检。由于实际数据每周仅提供一次,我们决定每次都运行常规模型分析。没有实时监控。相反,我们安排了一个生成标准周报告的作业,供数据科学家查看。

如何分析模型性能?

为了在生产中分析我们的模型,我们将明显地使用。它是一个开源工具,可以生成关于模型性能的交互式预建报告。

为了运行它,我们将我们的性能数据准备为熊猫数据帧。
它应该包括:

  • 模型应用日志 —进入模型的特征及相应的预测;和
  • 地面真实数据——作为我们“目标”的每小时实际租赁的自行车数量

图片作者。

您可以使用这个示例 Jupyter 笔记本跟随我们的步骤。

让我们先来看看我们创建的模型的性能。一旦我们训练了一个模型,我们就将训练数据集和预测指定为“参考”数据。敬请关注:这也将有助于我们日后参考这些数据。

reference = raw_data.loc[‘2011–01–01 00:00:00’:’2011–01–28 23:00:00']

我们可以直接从数据帧中选择这个时间段,因为它有 datetime 作为索引。

我们还映射了各个列,以显示该工具是什么,并执行正确的分析:

target = 'count' 
prediction = 'prediction' 
numerical_features = ['temp', 'atemp', 'humidity', 'windspeed', 'hour', 'weekday'] 
categorical_features = ['season', 'holiday', 'workingday']

默认情况下,显然使用索引作为绘图中的 x 轴。在本例中,它是 datetime,所以我们不显式添加任何内容。否则,我们必须在列映射中指定它。

接下来,我们为回归模型调用相应的报告。

regression_performance_dashboard = Dashboard(reference, **None**,  column_mapping=column_mapping, tabs=[RegressionPerformanceTab])

并将结果显示在 Jupyter 笔记本上。

regression_performance_dashboard.show()

我们还将它保存为. html 文件,以便于共享。

regression_performance_dashboard.save('regression_performance_at_training.html')

我们可以看到,鉴于我们只对四周的数据进行了训练,该模型具有良好的质量!

显然报道截图。

更多好消息:误差是对称的,分布在零附近。没有明显的低估或高估。

显然报道截图。

我们将继续把训练中模型表现的数据集作为我们的“参考”这让我们对我们的模型在生产使用中的质量有了很好的感受。因此,我们可以将未来的性能与该基准进行对比。

到野外:生产的第一周

观察生产中的模型有直接的目标。我们想检测是否有问题。理想情况下,提前。

我们还想诊断根本原因,并快速了解如何解决它。也许,模型退化太快,我们需要更频繁地重新训练它?或许,误差太高,需要我们对模型进行适配重建?哪些新模式正在出现?

在我们的例子中,我们简单地从检查模型在训练数据之外的表现开始。我们的第一周变成了一个原本会被搁置的数据集。

我们继续使用示例 Jupyter 笔记本。出于演示目的,我们一次性生成了未来几周的所有预测。实际上,当数据进来时,我们会按顺序运行模型。

为了选择分析期间,我们将在数据框中指明行。

让我们先来比较一下第一周的表现和我们在训练中看到的。前 28 天是我们的参考数据集;接下来的 7 部是制作。

regression_performance_dashboard = Dashboard(reference, production.loc['2011-01-29 00:00:00':'2011-02-07 23:00:00'],  column_mapping=column_mapping, tabs=[RegressionPerformanceTab])

报告出来了!我们可以快速地将生产性能与我们的参考进行比较。

预计会出现一些衰退,但总体来看情况并不那么糟糕。

来自明显报道的截图。

误差略有增加,并倾向于低估。

让我们检查一下我们的目标是否有任何统计上的变化。为此,我们将生成目标漂移报告。

我们称这份报告为明显的标签。在回归模型中,我们的目标是数值,所以我们选择一个匹配的报告:

target_drift_dashboard = Dashboard(reference, production.loc['2011-01-29 00:00:00':'2011-02-07 23:00:00'], 
column_mapping=column_mapping, tabs=[NumTargetDriftTab])

我们可以看到,实际租赁自行车数量的分布仍然十分相似。更确切地说,相似性假设并没有被拒绝。没有检测到漂移。

显然报道截图。

我们预测的分布也没有太大变化。

显然报道截图。

尽管如此,一个合理的决定是通过包含新一周的数据来更新您的模型。这样模型就能继续学习,我们大概也能改善误差。

为了演示的目的,我们将坚持看看事情有多快变糟。

进入下一周!

第二周:跟不上

我们再次根据参考数据集对新的一周进行基准测试。

performance_drift_dashboard = Dashboard(reference, production.loc['2011-02-07 00:00:00':'2011-02-21 23:00:00'], 
column_mapping=column_mapping, tabs=[RegressionPerformanceTab])

乍一看,第二周的车型表现相差不大。

显然报道截图。

梅几乎保持不变。但是,低估倾向继续增长。看来错误不是随机的!平均来说,我们低估了 10 辆自行车。

为了了解更多,我们转向情节。我们可以看到,该模型很好地捕捉了总体每日趋势。所以它学到了有用的东西!但是,在高峰时段,实际需求往往高于预测。

显然报道截图。

在误差分布图中,我们可以看到它如何变得“更宽”,因为我们有更多的高误差预测。向左的转变也很明显。在一些极端的例子中,我们有 80 到 40 辆自行车出现了以前没有发现的错误。

显然报道截图。

让我们也检查一下我们的目标。

target_drift_dashboard = Dashboard(reference, production.loc['2011-02-07 00:00:00':'2011-02-14 23:00:00'], 
column_mapping=column_mapping, tabs=[NumTargetDriftTab])

事情越来越有趣了!

我们可以看到目标分布现在不同了:相似性假设被拒绝。从字面上看,人们租用更多的自行车。这是一个统计上不同于我们训练期间的变化。

显然报道截图。

但是,我们预测的分布并没有跟上!这是模型衰退的一个明显例子。世界上发生了一些新的事情,但它错过了模式。

显然报道截图。

人们很想进一步调查。数据中有什么可以解释这种变化的吗?如果有一些新的信号,再训练可能有助于模型跟上。

在目标漂移报告中,有一个部分可以帮助我们探索特征和目标(或模型预测)之间的关系。

浏览单个功能时,我们可以检查是否注意到任何新的模式。我们知道预测没有改变,所以我们只关注与目标的关系。

例如,随着出租自行车数量的相应增加,似乎有向更高温度(以摄氏度衡量)的转变。

显然报道截图。

这是新款!

也许,它会在再培训中采用这些模式。但是现在,我们只是简单地进入下一周,没有任何更新。

第三周:当事情变糟时

好吧,现在事情看起来很糟糕。在第三周,我们面临一个重大的质量下降。

显然报道截图。

绝对误差和百分比误差都显著增加。

如果我们看看这些图,模型预测明显是分散的。我们还面临着模型未能预测到的高需求新数据段。

但是,即使在目标值的已知范围内,模型现在也会出错。训练之后事情确实发生了变化。

显然报道截图。

我们可以看到,该模型没有很好地外推。预测需求保持在相同的已知范围内,而实际值达到峰值。

显然报道截图。

如果我们放大特定的日子,我们可能会认为在一天中特定的(活跃的)时间里误差更大。我们从晚上 10 点到早上 6 点都很好!

然而,我们在解释这种模式时应该小心。这也可能是由于一些其他相关因素,如在同一时间温度较高。

显然报道截图。

显然会生成更多的图来显示误差。在当前的背景下,这些是描绘同一个故事的不同方式。我们有一个很高的误差,它明显倾向于低估。

显然报道截图。

显然报道截图。

在过去几周,这些相同型号质量问题的早期迹象就已经显现。随着变化的积累,它们被放大了。

回归业绩报告 还会生成一组深入了解表现不佳的细分市场的见解。目标是探究特定特征范围是否可以解释错误。

在我们的例子中,我们特别想了解模型低估目标函数的部分。

显然报道截图。

误差偏差表给出了更多细节。

我们按“范围%”字段对其进行排序。如果特定特性的值在模型低估或高估的组中显著不同,则该特性将排名靠前。

在我们的例子中,我们可以看到极端误差取决于“temp”(温度)和“atemp”(类似感觉的温度)特性。

显然报道截图。

在训练中,情况并非如此。我们在不同的温度下有各种各样的误差,没有一致的模式。

经过快速分析后,我们对模型性能及其缺点有了更具体的了解。这款车型面临新的、异常高的需求。鉴于它是如何被训练的,它倾向于低估它。最重要的是,这些错误根本不是随机的。至少,它们与我们观察到的温度有关。越高,低估越大。

它提出了与天气相关的新模式,这是模型以前无法学习的。天气变暖了,模特变得不听话了。

如果我们运行目标漂移报告,我们还会看到特征和目标之间的线性相关性的相关变化。温度和湿度很突出。

显然报道截图。

****在这一点上,这个模型似乎毫无用处。这是一个生动的例子,说明在有限的数据集上训练的模型无法捕捉季节模式。

我们应该尽快重新训练,并经常这样做,直到我们学会所有的模式。如果我们对频繁的重新训练感到不舒服,我们可能会选择一种更适合时间序列或者在外推方面更好的算法。

打破之前:数据和预测漂移

在实践中,一旦我们收到地面真相,我们确实可以迅速纠正航向。如果我们在第一周之后重新训练这个模型,它可能不会戏剧性地结束。

****但是如果我们没有可用的基本事实呢?我们能提前捕捉到这样的衰变吗?

在这种情况下,我们可以分析数据漂移。我们不需要实际数据来计算误差。相反,我们的目标是查看输入数据是否发生了变化。

图片作者。

再一次,让我们比较生产的第一周和我们在培训中的数据。

当然,我们可以看看我们所有的特征。但我们也可以得出结论,分类特征(如“季节”、“假日”和“工作日”)不太可能改变。我们只看数字特征!

我们指定这些特性,以便工具应用正确的统计测试。在这种情况下是 Kolmogorov-Smirnov。

column_mapping = {}
column_mapping['numerical_features'] = numerical_features

然后,我们将所选期间的漂移报告称为:

data_drift_dashboard = Dashboard(reference, production.loc['2011-01-29 00:00:00':'2011-02-07 23:00:00'], 
column_mapping=column_mapping, tabs=[DriftTab])

一旦我们显示了报告,它就会返回一个答案。我们可以看到,在第一周,特征分布已经有了统计上的变化。

显然报道截图。

让我们放大我们通常的怀疑——温度。

该报告为我们提供了关于特征分布如何随时间演变的两种观点。我们可以注意到观测到的温度是如何一天比一天高的。

这些值明显偏离了我们在培训中看到的绿色通道(平均值的一个标准差)。看着稳定的增长,我们可以怀疑有上升的趋势。

显然报道截图。

在这个情节中,我们也看到:天气变暖了。这不是我们的模型所习惯的!

显然报道截图。

正如我们之前所检查的,在第一周之后,我们没有发现模型预测的漂移。鉴于我们的模型不擅长外推,我们不应该真的期待它。

这种预测漂移可能仍然会发生,并发出诸如输入数据损坏之类的信号。否则,如果我们有一个更敏感的模型,我们会观察它。

尽管如此,数据漂移本身就提供了出色的早期监控,可以检测到变化并对其做出反应。

结束语

频繁的再培训是解决生产模型维护的一种方法。监控和可观察性增加了一层来保证模型质量。

为什么要把它包含在我们的工作流程中?

  • 它加快了调试的速度。无论何时你的模型失败,你都需要找出根本原因。预建的仪表板使它更快。
  • ****它详细地展示了性能。如果在交叉验证中仅依赖于总体模型性能,可能会掩盖重要的模式。您的模型可能会在特定部分无声地失败,需要重新构建。
  • ****它有助于改进模型。您可以探索模型在哪里以及如何出错。它有助于确定最佳的模型体系结构、再培训计划、为特征工程产生想法。或者,向您的主题专家提出正确的问题。
  • 它让你变得积极主动。数据输入的变化可能是模型质量的领先指标。我们希望在问题导致模型失败之前抓住它们。

我能为我的模型做同样的事情吗?

当然啦!转到 Github 或 pip 安装显然能够为您的模型生成这些报告。

最初发表于https://evidentlyai.com并与 埃琳娜·萨穆伊洛娃 合著。**

At 显然 AI,我们构建 开源工具 来分析和监控机器学习模型。

想留在圈子里吗? 报名 获取我们的更新和产品消息,关注上TwitterLinkedin获取更多关于生产机器学习的内容,或者加入我们的 Discord 社区 进行聊天和联系。

作为一名数据科学家,如何打破孤岛并找到社区

原文:https://towardsdatascience.com/how-to-break-down-silos-and-find-community-as-a-data-scientist-c9c8c862f30e?source=collection_archive---------21-----------------------

作者聚焦

"我决定把我的努力集中在我的能力上,而不是我的缺点上。"

在 Author Spotlight 系列中,TDS 编辑与我们社区的成员谈论他们在数据科学领域的职业道路、他们的写作以及他们的灵感来源。今天,我们很兴奋地分享 帕鲁尔·潘迪 本·胡伯尔曼 的对话。

照片由 Parul Pandey 提供

Parul 目前在 H2O.ai 工作,这是一家总部位于加州的基于自动机器学习的初创公司。在学术上,她是一名电气工程师,之前在印度塔塔电力公司从事配电领域的工作。她还是女性编码&数据科学(WiCDS) 的创始人,这是一个非营利组织,旨在支持和促进数据科学、机器学习和人工智能领域的女性和性别少数群体。Parul 也是笔记本类别的 Kaggle 大师,并且是 2019 年 Linkedin 软件开发类别的顶级声音之一。

你是如何决定进入数据科学的,更具体地说,是如何进入你目前专注的数据科学领域的?

我的数据科学之旅非常有趣。我是一名电气工程师;毕业后,我在印度首都的一家电力公司工作。我的日常工作围绕着电力变压器、电网和变电站。然而,幸运的是,我有机会在一个叫做高级计量基础设施(AMI)的电子仪表部门工作,在那里我们将筛选海量的电子仪表数据,以识别仪表中潜在的欺诈或故障。对我来说,这是一个改变人生的时刻,因为我开始看到数据可以给任何企业带来的巨大价值。我开始研究,实际上打开了潘多拉的盒子,尽管是以一种积极的方式。

当时,我并不知道有一个叫做数据科学的领域。我想知道我是否能适应,或者像我这样有经验的人是否能给这个领域带来价值。大约在那个时候,我休了一次产假,我想,那决定了我的命运。这给了我时间思考我的未来。最终,我大胆地辞去了工作。我和一个小家伙在一起,没有工作,没有睡眠,还有很多东西要学。回到基础,从零开始研究一切,既具有挑战性,同时又令人兴奋。我有编程和数学背景,所以这是一个额外的收获。在经历了学习、遗忘、失败、成功和拒绝的阶段后,我改变了职业生涯的轨迹。

我目前在 H2O.ai 工作,是一家自动化机器学习公司。我们的目标是通过让每个人,而不是少数人,都能获得机器学习的力量,来实现机器学习的民主化。

回顾那次转变,你不得不面对什么样的挑战或障碍?

有很多,我相信这对于从非计算机科学背景过渡到数据科学的人来说是很常见的。最大的问题是打入这个领域。公司想要有一些机器学习经验的候选人,不幸的是,我们没有。不管我们的简历有多好,不管我们准备为这份工作付出多少努力,我们就是达不到要求。这既令人沮丧又危险。许多公司以提供经验为借口,剥削应聘者,让他们免费工作。这种不正之风在这个领域很普遍,我也是受害者。

在经历了类似的痛苦经历后,我不再申请任何角色。相反,我决定把努力的重点放在自己的能力上,而不是缺点上。我从孤岛中走出来,开始参与社区活动。我意识到像我一样的其他人也在同一条船上航行。这些约定慢慢变成了聚会和网络研讨会。我开始在像 LinkedIn 和 Twitter 这样的平台上与人们接触。最后,写作是缺失的部分。它给了我发言权、知名度和信心,让我在数据科学领域扬名立万。

你最喜欢现在这个角色的哪一点?这些天你倾向于做什么项目?

作为 H2O.ai 的数据科学布道者,我的角色通常位于数据科学和社区的交叉点。一方面,我致力于人工智能领域的一些最新技术,另一方面,我也可以与社区互动。我喜欢创造关于数据科学的意识,尤其是 H2O.ai 的产品。正如盖伊·川崎所说,“福音不是一个职位;这是一种生活方式。”

我的工作需要很多自我意识和在角色中延伸和成长的意愿。我认为自己很幸运能在这个领域工作,并通过我的工作感动了许多人。

除此之外,我还参与为女性和弱势群体建立社区。我和他们经历了同样的挑战,我想用我的知识来帮助他们。作为wics的一部分,我们几个月前组织了一次博客聚会,唯一的目的是鼓励人们写。

我们还与政府机构一起组织了辅导会议,帮助指导女大学生。我们鼓励他们和他们的导师一起创建项目,这样他们就能理解构思、创新、创造和思考的重要性。

除此之外,我们还定期组织网络研讨会,以便社区了解行业动态。此外,这也为演讲者提供了一个磨练公开演讲技巧的平台。

由于印度的疫情局势,我们不得不后退一步,但事情正在解决,我们将重新启动一些其他举措。

你之前提到过公共写作——是什么激励你开始写作的,它与你的其他职业活动有什么关系?

老实说,我从未想过我会公开写作。已经有杰出的作家了,为什么还有人读我的文章?这些想法使我在相当长的一段时间里不敢写作。忘掉写作;我甚至对在社交媒体上公开发布东西都很谨慎。然后,在 2018 年,我发布了我的第一条标注为吴恩达的推文,令我完全惊讶的是,他不仅转发了这条推文,还在他的时事通讯中做了专题报道。这很有趣,很快我的追随者开始增加。这对我是一个很大的教训。我意识到将你的作品公之于众是多么重要。

然后我用我的文章做实验。我在 Medium 上发表了几篇博文,但反响不太好。反馈是冠军的早餐,对我来说,我一点也没有。然后慢慢地,事情开始好转。媒体上的出版物开始找我投稿。通过出版物发布突然成倍增加你的访问者数量。不久之后,我开始从人们那里得到关于我下一步应该写什么或者应该涵盖哪些主题的建议。这让事情有了转机,我的作家生涯开始了。写作的美妙之处在于它很充实,很有收获。即使在今天,当我写完一篇文章并点击发表按钮时,也会带来一种愉快的成就感。

写作也是我在 H2O.ai 工作中不可或缺的一部分。事实上,我们都非常鼓励写作,因为我们相信“内容为王”的哲学我们经常更新软件,发布新产品和新的解决方案,我们通过博客和文章告知公众。除了我为 H2O 写的技术文章,我还经营着一个 Kaggle Grandmaster 系列,在那里我在 H2O.ai 上展示了老牌数据科学家和 ka ggle grand master的故事,他们分享了他们的旅程、灵感和成就。

当人们因为我写的一篇文章而联系我时,这种感觉尤其强烈。仅仅通过写作这个媒介,我就和许多不同国籍的人建立了联系。

展望未来,你希望在数据科学和人工智能社区中看到什么样的变化?

与几年前不同的是,今天许多来自不同领域和背景的人正在涉足数据科学。这是积极的一步。

数据科学是一个多样化的领域。因此,将不同性别、背景和种族的人聚集在一起更有意义。这样,我们可以带来更多的创造力,让知识、发现和创新蓬勃发展。这需要社会的共同努力,使多样性和包容性成为生态系统的重要组成部分。

除此之外,我希望看到更多来自企业界的“有益的数据科学”倡议。数据有很大的力量,社会的很大一部分可以从中受益。疫情告诉我们,财富不平等正在加剧,并且影响到我们所有人。因此,作为一个社会,我们应该站出来,用我们的技能和技术来帮助那些有需要的人。数据科学应该用于社会公益事业,重要的是要超越利润,把社会作为一个整体来考虑。

想了解更多关于 Parul 与 H2O.ai、WiCSD 和 beyond 的工作和项目吗?在媒体、推特、 LinkedIn 上关注她。

以下是 Parul 在上关于数据科学的深度档案中一些我们最喜欢的帖子。它们包括入门指南和实践教程、采访以及对高级主题的深入探讨。

  • "通过三个简单的步骤自动化您的数据科学项目结构(2021 年 6 月,TDS)
    了解如何快速高效地简化您的数据科学代码存储库和工具。
  • "理解梯度下降背后的数学"(2019 年 3 月,TDS)
    机器学习中常用的优化算法之一背后的简单数学直觉。
  • "我使用 Keras 进入深度学习的旅程(novembr 2018,TDS)
    在 Keras 中从头开始构建和训练神经网络的介绍。
  • "使用 H2O 可视化大型数据集"(2020 年 11 月,TDS)
    了解如何使用 H2O 聚合器函数有效地减少数据的大小。
  • "极客女孩崛起:神话还是现实"(2019 年 12 月,TDS)
    对 2019 年 Kaggle ML 和 DS 关于机器学习和数据科学领域女性代表性调查的分析。
  • "Python 中函数式编程的元素"(2019 年 7 月,TDS)
    学习如何使用 Python 中的 lambda、map、filter 和 reduce 函数来转换数据结构。

请继续关注我们即将推出的下一位专题作者。如果你对你想在这个空间看到的人有建议,请在评论中给我们留言!

如何打入机器学习领域

原文:https://towardsdatascience.com/how-to-break-in-machine-learning-jobs-based-on-6-years-experience-in-ml-f798ac4a0cfa?source=collection_archive---------26-----------------------

基于 6 年的 ML 工作经验

弗兰基·查马基在 Unsplash 上拍摄的照片

免责声明:2 年的学术经验+ 4 年的专业经验。我并不声称自己是一个导师/教练,也不声称自己有非凡的记录。尽管如此,我在这篇博客中写下的任何东西都是我在过去的 2-3 年里采访 100 多个 ML 领域的个人资料的实践经验的结果。

我们今天看到的是一系列机器学习的课程,以及本科生对寻求 ML 职业的巨大兴趣。就我个人而言,许多本科生甚至一些有经验的人都找过我,询问如何开始机器学习方面的工作。在这篇博客中,我整理了一些想法,并提出了一些普通读者在开始旅程时的误解。

我的旅程

  • 不是 ML 领域的大一新生:当我开始职业征程的时候,虽然我是一名应届本科毕业生,但我并不是 ML 领域的大一新生。我大学的最后两年都在从事 NLP 的项目。我注意到人们已经完成了一些在线课程,提到他们对这个领域非常熟悉。我强烈反对这种学习的观念。虽然从在线课程开始是好的,而且可能是必要的(我也做了同样的事情),但是就此打住并不是一个可行的想法(阅读下面的相关章节)。
  • 尽管我有一点 ML 的经验,但得到一份实际的 ML 工作并不容易。我一直在寻找一份全职的实际工作,并不倾向于实习/深造/RA 职位。幸运的是,我得到了一份工作,我决定放弃我在大学实习时收到的一家跨国公司的邀请。TL;大卫:我知道我想在 ML 领域工作,为此我准备放弃一个品牌,在未来的某一天,任何人都会希望以某种身份为其工作。
  • 学术机器学习 vs 生产机器学习:我确信,你们中的很多人已经知道学术机器学习与生产机器学习有很大不同。我只能说这是最大的真理(在博客的下一部分阅读这方面的详细内容)。

闯入机器学习——我所听到的

相信你想冒险进入 ML 的原因背后的基本原理,而不被该领域的大肆宣传所动摇,这里有一些供你思考的要点:

  • 在线课程:这是一个很好的起点,现在有大量的可用资源。不利的一面是,有大量的候选人已经完成了一门或多门在线课程。是什么让你与众不同?
  • ML 中的项目:这是很多人给出的即时反应。拥有温和项目的人谈论情感分类和房价预测,而深度学习爱好者谈论使用 ResNet 或类似架构的文本生成项目或图像分类。同样的问题,许多竞争的候选人也做了完全相同的项目,是什么让你与众不同?
  • 仅深度学习关键词:这是我注意到的另一群候选人,他们只是自发的拥有深度学习生态系统中的所有流行语。你真的认为引用流行语会让你鹤立鸡群吗?

闯入机器学习——我的建议

继续上一节中的指针,这里有一些在机器学习领域开发配置文件的指导原则。

课程

在我看来,课程是理解最大似然算法背后的基本原理和概念所必须的。

  • 虽然课程可以从浅显到高级,但我总是更喜欢从正式课程/教科书中收集信息,而不是速成课程。速成课程可以帮助你快速概述或要点,正式课程可以让你更深入地了解其中的一些要点,教科书可以帮助你理清头绪,同时让在线/正式课程中许多无法解释的概念浮出水面。永远重质量轻数量!ML 是巨大的,没有人期望你知道所有的事情。

项目

同样,在线课程中的温和项目或项目(作业)是开始实际实施的好方法,如果只在课程完成的范围内完成,它们是不够的。除了指定的项目之外,你还做了什么。以下是一些扩展项目的方法:

  • 你在 GitHub 上托管过吗,有合适的 README?这解决了两个目的,它提供了你工作的可见性,使你更有组织性,并帮助你在任何你想要回顾的时候保持你的实现在你的指尖。
  • 你对实验结果做了广泛的分析吗?从 EDA 到成本函数到数据到超参数到误差分析。你能让你的结果可解释吗,例如,如果你要训练一个深度学习系统,最有可能的是你会使用注意机制。能不能外挂代码把注意力地图可视化?
  • 你是否将你所学到的应用到不同的数据上了?如果您学习了情感分类,那么您主要是学习了一种执行文本分类的方法。您是否在另一个数据集上应用了刚刚学习的文本分类:不平衡数据集、具有更多类的多类数据集、大数据等。你注意到你在情感数据的文本分类方面的工作有什么不同?你能从你看到的差异中做些什么/学到些什么吗?

再一次强调质量胜于数量!从 10-15 个普通项目中脱颖而出的 2-3 个优秀项目

深度学习 vs 统计机器学习

如果你是统计机器学习的新手,有很多关于深度学习的信息,那么你很有可能会而不是优先考虑擅长统计概念的候选人。

  • 请注意统计机器学习非常重要,在 ML 面试中肯定会被问到。如果你在通用 ML(表格、数字、分类数据)或 NLP(自然语言处理)领域工作,更是如此。
  • 深度学习不仅仅是了解 CNN、LSTMs 和变形金刚。这也是关于提出能够很好地解决您的数据和业务问题的架构。这是一个需要学习和发展的东西。最好的方法之一是阅读研究论文,学习如何构建 DL 架构。所以,如果你已经用 CNN/lstm/Transformers 训练了几个模型,不要过于自信。

再次强调质量胜于数量!对两个 DL 架构和两个统计 ML 模型有很好的理解比什么都接触一下要好得多。

知道为什么和如何除了什么

我从候选人那里听到了很多被接受的概念,这些概念在大多数情况下是正确的,但是他们没有解释为什么这些概念会起作用。

  • 为什么随着数据集规模的增加,SVM 表现不佳?“差”表示模型的哪个方面?
  • 为什么在神经网络中使用 bias?是不是只用于神经网络?
  • 为什么使用批量归一化?批量规范化是如何实现的?
  • 为什么多代理游戏难?

这些问题的答案只有当你深入概念和阅读时才能观察到/理解。这就是正式阅读和真正的兴趣有所帮助的地方。PS:你不需要知道所有的事情,但是一个小的开始仍然是一个开始。

最后的话

  • 从小处着手 — ML 是广阔的,不要被可用的资源和领域的深度所淹没。挑一个,完成一个。
  • 拓展广度,深入研究 —开始时不要局限于深度学习或表格数据。开始时多探索一点,了解这个空间,然后逐渐深入。算法也是一样,最初选择 4-5 个算法,然后开始深入研究它们。
  • 专攻——在我看来,深入钻研几个领域总是更好。有多种指数可供选择:监督与非监督、NLP 与 CV 与图像、结构化与非结构化。在最初的广度之后,根据你的兴趣开始在几个专业领域建立一个强有力的轮廓是非常重要的。意识到他人并没有坏处,但是对任何事情都只是肤浅的了解却没有足够好的东西给自己带来伤害。
  • 阅读研究论文或博客 —阅读相关的研究论文和博客(媒体博客、公司博客、Kaggle kernels)可以极大地帮助你理解问题空间,帮助你开发不同的视角,让你意识到不同的 ML 问题,并且可以帮助你比在理想主义场景中应用 ML 的传统方法学得更快。
  • 永远不要过于自信——你可能不会相信,但美国职棒大联盟是如此之大,以至于在你成为明星之前,你不能声称自己是明星!永远保持谦逊,向任何人学习更多。总会有一些别人知道而你不知道的事情。

关于我:

  • 领英:https://www.linkedin.com/in/krayush/
  • 个人主页:https://krayush07.github.io/

2021 年如何打入数据科学

原文:https://towardsdatascience.com/how-to-break-into-data-science-in-2021-8-steps-87cb02a4a1f4?source=collection_archive---------6-----------------------

让您踏上数据科学之旅正确轨道的八个步骤。

(src =https://pixabay.com/images/id-4194213/

介绍

It 很容易理解为什么有人会想进入数据科学领域。这个领域是尖端的、令人兴奋的,而且恰好是非常有利可图的。理论上,这个领域听起来像是迈向未来的完美一步,然而,数据科学的世界极其广阔和复杂。数据科学工作可以是很少或没有编程的应用程序,也可以是有大量编程的应用程序,或者是很少或没有统计数据的工作,或者是非常专注于统计数据的工作。

由于数据科学的所有这些令人困惑的部分,甚至更令人困惑的数据科学应用,很容易理解为什么这个领域的入门兴趣非常低。虽然人们可能对数据科学的概念感兴趣,但将这种兴趣转化为承诺可能相当困难。如果你不知道从哪里开始,那就更是如此。幸运的是,你可以采取一些简单可行的步骤,尽可能顺利地融入这个领域。今天,我想透露八件事,如果我今天就开始工作,我个人会在今天做这些事,以便开始从事数据科学工作。

№1:学习(正确的)东西

正如我在介绍中提到的,数据科学的世界是巨大而复杂的,实际上涉及到来自多个学科的多种技能的集合。如果没有正确理解你的角色,在这些方面有所欠缺,肯定会产生一些问题,所以了解你将要从事的工作的具体要求是有好处的。也就是说,这也可能完全不同,取决于数据科学到底想要做什么。

例如,有许多数据科学家很少或根本不做机器学习。这些属性通常属于分析师学科,这是一个数据科学家,可能更适合于统计和用数据呈现业务解决方案。在这个范围的另一端是机器学习工程师,他可能在 C++和 C 等语言中从非常底层的模型上工作。还有更多面向服务器或网络的数据科学家,以及主要专注于为机器学习和产品开发构建数据管道的数据科学家,通常称为数据工程师。关键是,数据科学有许多不同的应用,并且该学科通常不局限于参与数据科学家的所有角色。

牢记这些数据科学家的角色,分析您到底想做什么是很重要的。这也可能需要时间,因为要真正精通数据科学,您必须对它感兴趣。您可能最终更喜欢编程低级数学,而不是可视化数据,在这种情况下,您可能想要追求与数据分析不同的轨迹。

如果您想了解更多关于数据科学领域的不同发展道路,我写了一整篇文章,您可以在这里查阅:

[## 数据科学的学习途径——您应该学习什么?

towardsdatascience.com](/learning-pathways-for-data-science-what-should-you-learn-a0a580a705a2)

№2:获得认证

讨论数据科学或软件工程时,经常会出现一个问题,那就是教育问题。数据科学需要什么样的教育?答案可能相当复杂,因为没有学位也完全有可能找到一份数据科学的工作。就我个人而言,我很享受我的应用科学学位,但现在我有了它,我身处现实世界(而且负债累累),我觉得这是在浪费时间和金钱。当然,我不能给出职业建议,但我会说,在申请大学学位之前,你至少应该了解并意识到你想做什么。

我之前谈到了数据科学的不同应用,我认为这在您获得认证的步骤中起到了很好的作用。例如,对成为分析师感兴趣的人可能想获得统计学学位,而想写模型的人可能对计算机科学学位更感兴趣。这也是个人问题,所以我认为,如果你能够自学这些概念,那么你拥有什么学位并不重要,只要它是定量的。如果您最终在数据科学方面足够优秀而没有学位,您甚至可以通过做自己的开源或自由工作获得认证。这也有助于学习正确的事情,因为你可能也想获得做正确事情的学位。

№3:建立投资组合

获得数据科学工作最重要的资产之一将是投资组合。每当我雇佣数据科学家时,简历只是文件夹的一面镜子。你的简历只是一瞥,真正能证明你技能的是你工作过或参与过的项目。建立投资组合是成为数据科学家的一个重要部分,您的投资组合应该能很好地展示您的技能和能力。

此外,通过检查您的文件夹和 Github 存储库,您可以了解自己和他人的工作方式。考虑到这一点,我会考虑将这些相当大的资产用于获得数据科学方面的职业生涯。

№4:为自己成名

你不仅应该努力在学术上获得认可,而且我认为你应该在互联网上公开成名。越来越多的雇主在雇佣你之前用谷歌搜索你的名字,在数据科学领域这样的技术行业更是如此。谷歌搜索结果能让你从其他申请者中脱颖而出。此外,表明你一直在做某件事,不管是什么事,可以提供关于你如何工作和你可能有什么样的动力的信息。

№5:在开源项目上合作

我个人在招聘时关注的另一个非常重要的事情是开源项目的合作。我们作为数据科学家使用的大多数最棒的包都是开源的,为这些包做贡献可以极大地改变社区对你的看法。更重要的是,它告诉雇主你有能力与其他维护人员和程序员合作,这远没有一些人想象的那么普遍。

此外,在项目中保持一致也是一件至关重要的事情,它可以准确地显示出你是哪种类型的程序员。记住,跟上某些项目,做出贡献,并保持有很长的路要走,因为它可以表明你有能力做所有这些与你的雇主的代码,以及。

№6:对技术产生兴趣

不学习微积分或统计学而更好地掌握数据科学的一个简单方法是更好地掌握技术行业和你周围的世界。技术当然是数据科学学科的中心,我认为当淹没在数据科学提供的令人惊叹的教育世界中时,它很容易被忽视。

了解最新的技术会让你保持在圈子里。由于数据科学仍然是一个新兴领域,这是至关重要的一步,因为未来的技术是为了促进数据科学而创造的。让我们后退一步,考虑一下我们口袋里最受欢迎的科技产品——手机。我们手机中的摄像头已经加入了人工智能,现在大多数手机都使用人工智能来实现“智能”语音识别功能,如 Google now。广告服务使用机器学习,根据收集的数据为你量身定制内容——这可能是不道德的,但关键是技术和数据科学是相互交织的,如果你在这个领域,你可能想留在这个圈子里。

№7:坚持不懈地练习

数据科学家的一个常见陷阱是实践不够一致。回到我之前提出的论点,如果你不不断学习,保持头脑中的知识新鲜,你注定会落后。作为一名数据科学家,你可能遇到的最糟糕的事情就是落后于技术,使用现在已经过时的东西。随着这个领域每天都在快速发展,很容易陷入这个陷阱。

就我个人而言,我基本上每天都在做数据科学工作。这种驱动力将使你与众不同,并表明你真的有能力跟上人工智能的快速发展。

№8:探索!

我给新数据科学家的最后一条建议是探索!这个领域是不可思议的,因为总是有新的东西要学,无论是新概念、新模型、新数学,甚至是新的编程语言。作为一个跨越多个学科的领域,并把它们结合成一项势不可挡的工作,总是有很多值得一看的东西。

关于持续实践和学习的话题,探索你周围的世界和生态系统以不断保持对正在出现的技术的了解是非常有意义的。记住,如果这个领域有新的进展,你可能想要知道它。有很多非常酷的事情,你可以每天都做,来扩展你的知识,这是关键;每天都在进步。

结论

数据科学领域是一个庞大而复杂的网络,包含多种不同的技能,既有硬技能,也有软技能。这些技能适用于学科的多个方面,知道学习哪些技能可能非常困难,尤其是对初学者而言。我能给的最大的建议就是学习你感兴趣的东西,并且坚持学习。专注于某项工作,专攻它,尽你所能地学习相关知识,然后不断扩展这些知识。我希望这篇文章是有帮助的,也许它会帮助你迈出进入数据科学奇妙世界的第一步。非常感谢你的阅读,我很感激!

如何更快地将您的 ML 模型投入生产

原文:https://towardsdatascience.com/how-to-bring-your-ml-models-to-production-faster-c5b6ba408227?source=collection_archive---------11-----------------------

快速部署 ML 模型和创造新竞争优势的简短指南

照片由麦克多比胡在 Unsplash 上拍摄

在不同的人工智能项目之后,我意识到如何快速地建立和部署高效的机器学习(ML)模型可以成为竞争优势的来源。决策者们认识到,在他们现有的技术体系内收集数据以及管理构建、部署和调试模型的整个生命周期并不简单,而且会带来意想不到的挑战。

根据我的经验,数据科学家通常会花时间分析一个数据集,寻找合适的算法,训练一个新的模型,然后交给数据工程师在生产中运行。

这种情况可能会导致问题,数据科学家看不到在生产中运行模型的挑战,而数据工程师不知道模型是如何构造的。我见过很多次数据科学家编写无法在生产中扩展的应用程序。

对于可能没有数据工程师的小公司来说就更难了。结果,我们最终得到的是构造糟糕的 ML 部署管道,并出现了保持 ML 模型更新和在生产中可靠运行的问题。

由于部署复杂、缺乏治理工具和数据问题,只有一小部分机器学习或深度学习项目能够投入生产。

将 ML 模型投入生产

我意识到许多公司在没有明确生产计划的情况下启动 AI 项目。通常,没有人真正想到概念验证之后会发生什么。当一个团队必须将模型集成到生产环境中时,这种策略的缺乏通常会导致严重的问题。

根据公司规模、管理人工智能项目的经验、预算和团队,决策者可以决定只专注于模型培训,以创建概念证明,而不考虑生产和可扩展性。

在这种情况下,数据科学团队可能会简单地决定将模型包装在 API 后面,并直接交付生产。然而,这可能会导致持续的高支持成本,因为在没有可扩展和可复制的计划来更新和调试生产中的模型的情况下,工程师很难可靠地运行系统。

由于机器学习生命周期中缺乏自动化任务,模型通常会以定制的数据管道和每个模型的部署环境而告终

这种缺乏一致的方法减慢了开发,因为碎片化使得改善生态系统的成本很高。此外,团队通常用他们喜欢的语言(通常是 R 或 Python)创建模型,然后将它们重写为另一种语言以在生产框架上运行(例如 Java/Spark)。

ML 模型由几个元素组成,包括数据集、参数和超参数。所有这些组件都需要在整个开发过程中仔细存储和版本化,以确保可再现性。

怎样才能更快地将 ML 模型投入生产

MLOps 是机器学习领域的一个热门话题。简而言之,MLOps 是一种逻辑方法,旨在标准化和自动化大多数数据科学任务,同时为持续开发 ML 模型和快速部署它们创建一个协作环境。

MLOps 使部署用任何开源语言编写的模型变得容易,并公开了一个生产质量的 REST API 来支持实时预测。软件工程也经历了类似的转变,称为 DevOps。

利用 MLops 解决方案的成功公司已经采用了类似的最佳实践。这些实践通常包括标准化的中央管道,用于数据准备/培训,具有可重复的工作流,可以为未来的部署进行更新。

其次,模型管理解决方案使得跨各种度量比较不同的和新的模型变得容易。最后,MLOps 流程应基于数据和 ML 应用程序的持续集成和交付(CI/CD ),同时支持公司使用的所有框架,例如 Torch 或 Tensorflow。

为了更进一步,考虑以下元素:

  • 版本化,以跟踪您使用的所有算法、训练模型、数据集、元数据和超参数。考虑使用容器(Docker、Kubernetes 等。)因为它们提供了一个隔离和版本化模型的好方法。
  • 自动保护措施,不再依赖手动或不一致的流程。
  • 模型注册中心在一个中央存储库中存储、注释和管理生产就绪模型。这个要素也与数据科学团队的快速入职有关。我注意到,人们很难参与进来,看到他们正在做的项目,并确定数据在哪里。
  • 对于计算机视觉项目,你可以考虑使用带有预训练模型的 AI 工具包。具体地说,您可以使用自己的数据来微调特定用例的模型。例如,使用 NVIDIA 多功能、生产质量模型中的一种来完成常见的人工智能任务,或者使用 100 多种神经网络架构中的一种,如 ResNet、VGG、FasterRCNN、RetinaNet 和 YOLOv3/v4。
  • 用于观察资源管理(GPU/CPU)的仪表板
  • 自动监控已部署模型的性能,并在新模型表现不佳时进行回滚。随着时间的推移,许多型号会出现漂移,性能下降。部署的模型需要监控和改装。每个部署的模型都应该记录所有的输入、输出和异常。
  • 为模型构建者提供自我部署通过内部模型治理过程批准的模型的能力。
  • 在生产中部署之前测试和调试 ML 模型的开发环境。
  • 用于测试生产中各种超参数组合的弹性集群..

这些元素将帮助您的公司处理许多重复性的任务,并导致更快的发布周期。ML 开发生命周期的另一个重要方面是什么?数据。

数据问题

对于那些熟悉 ML 项目的人来说,你可能知道手动的数据准备和争论可能会占据 ML 项目 80%的时间。

数据科学家需要数据争论、准备、原型和可视化工具来缩短这一时间。通过利用 MLOps 管道,数据科学团队可以更快、更高效地完成这些任务。先进的 MLOps 解决方案可以支持从数据选择和注释到模型优化的 ML 项目。

在计算机视觉项目中,这种对数据优化的需求至关重要。一些公司在 MLOps 管道和培训数据优化方面部署了独特的专业知识。

其他公司已经创建了端到端的训练数据平台,以便数据科学家可以专注于模型选择和评估,同时外包整个训练数据工作流,从新数据选择和注释到模型警戒。

由于高精度的需要,在生产之前必须处理一些边缘情况。一些平台通过预测任务中可能存在的每种类型的错误,并在注释过程开始之前为其分配数字惩罚值,来主动识别边缘情况。这种主动方法使数据科学团队能够创建全面且可行的说明,从而帮助更快地投入生产。

此外,数据科学团队可以根据他们的初始指导方针不断接收样本结果,以帮助他们优先考虑和确定要注释的数据,从而通过迭代指令加快模型开发。

部署策略

最后但同样重要的是,我强烈建议公司不要只是将他们的模型投入生产。公司必须探索许多不同的方式来部署基于人工智能的解决方案。正如 Christopher Samiullah 所提到的,“影子模式”和“金丝雀”部署对于 ML 应用程序特别有用。在“影子模式”中,您捕获生产中新模型的输入和预测,而不实际服务于这些预测。相反,您可以自由地分析结果,即使检测到错误,也不会产生重大后果。”

ML 项目不再仅仅基于数据科学。首先要清楚地定义你的目标(例如,可接受的精度水平等。)并完全采用敏捷方法(例如,不断迭代,直到找到正确的算法、模型和准确性)。

公司需要认真考虑将模型投入生产所需的时间。其他公司可以通过更快、更高效地将其模型投入生产来获得竞争优势。

一旦投入生产,你还必须确保你的模型保持准确;当涉及到模型性能时,对已部署模型的监控可能会导致坏的意外,并且可能需要模型再培训(例如,概念漂移)。

如果你总体上喜欢这篇文章和我的写作,请考虑通过我在这里的推荐链接注册 Medium 来支持我的写作。谢谢!

如何为所有 Tableau 仪表板构建中央仪表板

原文:https://towardsdatascience.com/how-to-build-a-central-dashboard-for-all-your-tableau-dashboards-f6831acc5701?source=collection_archive---------20-----------------------

为所有 Tableau 服务器仪表板创建一个简单的类似网站的界面

对于那些日复一日发布 Tableau 仪表板并在 Tableau 服务器上发布了数百个仪表板的人来说,要知道使用 Tableau 的开箱即用文件导航系统来浏览它们可能有点麻烦和乏味。如果您想创建一个报告界面,为您的用户提供类似于访问所有 Tableau 仪表板的网站的体验,这里有一种方法可以实现。

来源:https://www . Reddit . com/r/noisygifs/comments/1 krhxe/you _ just _ blow _ my _ mind/

我们先了解一下,把手头的问题分解一下。当 Tableau 开发人员将仪表板发布到 Tableau 服务器时,每个仪表板都会获得一个唯一的 url。当您与同事分享这些链接时,他们会将它们加入书签以供将来参考。随着你不断分享更多的链接,你很快就会意识到这种协作方式很难管理和跟踪。如果所有用户都没有查看所有仪表板的权限,这将变得更加困难。拥有一些具有深入查看功能的仪表板可能是一个潜在的解决方案,但是如果您有超过 50 个仪表板呢?将所有用户集中到一个中心链接来访问所有报告会更加方便用户。它还可以帮助您将报告产品化。

Tableau 的开箱即用解决方案部分解决了这个问题。您的用户可以使用 Tableau 的文件夹结构在仪表板之间导航。然而,这种体验仍然缺乏用户访问一个中央仪表板的技巧,比如网站的主页,然后根据需要转到其他仪表板。当您的用户群渴望通过一次点击操作来查看主控制面板,以便在深入查看具体报告以了解更多详细信息之前快速了解团队的整体健康状况时,这一点尤为重要。

Tableau 服务器文件夹结构。来源:https://community . tableau . com/s/question/0d 54t 00000 c 6 BIH/folder-structure

构建您的报告应用程序

Tableau Server 附带了一个存储库,用于存储用户、组、项目、工作簿名称、描述、视图 URL 和其他相关数据。我们将使用这个存储库来构建我们的主仪表板,它将充当您的应用程序的主页

下面是主页的图像。我们将尝试创建顶部导航菜单和该仪表板的右侧,该仪表板以表格结构包含每个出现在 Tableau 服务器上的报告。

作者图片

用户可以单击任何报告,在单独的选项卡中查看其全部详细信息。下面就是一个这样的例子。通过随时访问顶部导航,他们可以随时导航到主页。

作者图片

主页将只是我们将创建的另一个 Tableau 仪表板,它将包括服务器上所有报告的列表。这些信息包括报告名称、描述(表格格式)以及发布报告的文件夹(顶部导航)。单击报告描述,查看者将被带到相应的报告 URL。每个用户只能看到他们有权访问的视图。

访问 Tableau 存储库

Tableau 存储库是一个 PostgreSQL 数据库,可以从 Tableau Desktop 访问。只有 Tableau 管理员可以访问 Tableau 服务器存储库。默认情况下,Tableau 服务器存储库有两个用户— tableaureadonly 。用户 tableau 可以访问几个数据库视图,这些视图可用于分析服务器活动。 readonly 可以访问额外的数据库表。尽管这两个用户已经可以在 Tableau 上使用,但是他们没有设置密码。要访问 Tableau 服务器存储库,只需启用对数据库的访问并为 readonly 用户设置密码。可以使用 TSM 命令并重新启动 Tableau 服务器来设置密码。

您将需要下表来访问服务器上发布的工作簿,获取它们的说明,并查看有权访问它们的用户。这里是完整的 Tableau 存储库数据字典。

public.workbooks —此表保存代表服务器上存在的工作簿的每条记录。出于这个用例的目的,我们需要名称描述列。

公共的。_workbooks —此表中的每条记录都包含有关服务器上工作簿的更多详细信息。我们需要这个表中的项目名称项目 id 列。

公共的。_views —此表中的每条记录都包含工作簿中的一个视图。我们需要这个表中的 view_url 列。

公共的。_users —此表包含与用户相关的信息。我们需要这个表中的名称列。

public.next _ gen _ permissions 保存他们有权访问的用户和工作簿/视图的信息。使用 authorizable_idgrantee_id 列,我们将知道有权访问各自工作簿视图的用户/组。 authorizable_type 描述被指定权限的事物。对象可以是“项目”、“工作簿”、“数据源”、“视图”或“NamedResource”。 grantee_type 描述谁被授予了权限;用户。对于这个用例,我们将假设访问是在用户级别提供的。

现在我们知道了所有需要的表,让我们看看如何连接这些表。下图描述了它们之间的关系:

作者图片

创建顶部导航

您可以使用 public 的 project_name 列中的文件夹名(或项目名)来构建它。_ 工作簿表。在“行”工具架中拖动“项目名称”列,并在“标记”工具架中选择一个看起来像下拉箭头的自定义形状。阅读本了解定制形状的更多详情。

尝试构建一个像这样的 Tableau 报告界面,以提高您的仪表板的可见性和吸引力。

特别感谢 Sheeraja Rajakrishnan 合作撰写这篇博客。你可以在 https://sheerajarajakrishnan.wordpress.com/阅读更多她的博客。

如何使用 tf.keras 为图像分类从零开始构建卷积神经网络

原文:https://towardsdatascience.com/how-to-build-a-convolutional-neural-network-from-scratch-using-tf-keras-for-image-classification-ee4482de8453?source=collection_archive---------31-----------------------

Keras 中的影像分类实践教程

作者对 CIFAR-10 类的可视化

在本文中,我们将使用 tf.keras 的函数 API 逐层构建一个卷积神经网络,接下来,我们将探索并集成 keras 中 ImageDataGenerator 类提供的数据增强技术。

TF . keras 是什么?

  • tf.keras 是 TensorFlow 对 Keras API 的实现。
  • Keras 需要一个后端来训练定制的神经网络。在从 v1.1.0 开始切换到 TensorFlow 之前,它使用theno作为其默认后端。

本教程还提供了一个 Google Colab 笔记本,供您亲身体验。

我们将使用 CIFAR-10 数据集,这是图像分类任务的常用基线。CIFAR-10 数据集是 60000 幅大小为 32x32 的 RGB 图像的集合。它由 10 个类组成,每个类有 6000 个图像。有 50000 幅图像可用于训练,还有 10000 幅测试图像。

让我们开始吧。

导入必要的库-

import numpy as np
from tensorflow.keras import *
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import seaborn as sns

1.数据准备

正在下载 CIFAR-10 数据集-

(X, y), (test_X, test_y) = datasets.cifar10.load_data()

在可用于训练的 50000 幅图像中,我们将使用 3000 幅图像创建一个验证集,并使用剩余的 47000 幅图像进行训练。

train_X = X[:47000]
train_y = y[:47000]
val_X = X[-3000:]
val_y = y[-3000:]

2.模型架构

我们将使用 TensorFlow 功能 API ,因为与顺序 API 相比,它为我们提供了对每一层的更多控制和访问。

(Conv2D→batch norm→Conv2D→batch norm→Maxpooling2D) 3 →( Dense→batch norm) 3→soft max**

我们将使用的图层-

  • Input()实例化一个符号张量对象

  • Conv2D() 创建一个与层输入卷积的内核。我们将使用它来执行图像的空间卷积。

  • 【batch normalization()在训练时使用当前输入批次的均值和标准差,而在推断时使用训练时看到的批次均值和标准差的移动平均。****

  • MaxPooling2D() 用于 2D 空间数据的池化操作

  • Dense() 图层是一个常规的 NN 图层,可以在方法本身中添加激活和正则化选项。

  • softmax() 应用 softmax 激活功能

选择合适的核大小、步长和填充是设计卷积神经网络的重要参数。斯坦福大学的 CS231n 指南为这些参数选择合适的值提供了一个美丽的直觉,并解释了如何确定每层之后的输出尺寸。

**input = Input(shape=(32, 32, 3))x = layers.Conv2D(32, (3,3), activation='relu',padding='same')(input)x = layers.BatchNormalization()(x)
x = layers.Conv2D(64, (3,3), activation='relu',padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.MaxPooling2D(2)(x)x = layers.Conv2D(128, (5,5), activation='relu',padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Conv2D(256, (5,5), activation='relu',padding='same')(x)
x = layers.BatchNormalization()(x)x = layers.Conv2D(512, (3,3), activation='relu',padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.Conv2D(512, (5,5), activation='relu',padding='same')(x)
x = layers.BatchNormalization()(x)
x = layers.MaxPooling2D(2)(x)x = layers.Flatten()(x)
x = layers.Dense(1024, activation='relu')(x)
x = layers.BatchNormalization()(x)
x = layers.Dense(512, activation='relu')(x)
x = layers.BatchNormalization()(x)
x = layers.Dense(128, activation='relu')(x)
x= layers.Dense(10)(x)output= activations.softmax(x)model = Model(inputs=input, outputs=output,name="TF_Functional_API")model.summary()**

每层涉及的参数数量和层输出的尺寸可以用https://www.tensorflow.org/api_docs/python/tf/keras/Model#summary()方法查看。****

Keras 中用于模型训练和评估的 3 种主要方法是 编译拟合、评估 。TensorFlow 为这些方法中的每一种提供了 综合指南

一些超参数-

  • 损失函数→ 稀疏分类交叉熵
  • 优化器→ 亚当
  • 学习率→ 0.001
  • 批量→ 64
  • 纪元→ 30

3.运行我们的模型(没有数据扩充)

****model.compile**(loss=losses.SparseCategoricalCrossentropy(),optimizer=optimizers.Adam(learning_rate=0.001),metrics=['accuracy'])**model.fit**(train_X, train_y.flatten(), batch_size=64, epochs=30, validation_data=(val_X,val_y.flatten()))**model.evaluate**(test_X, test_y.flatten(), verbose=2)**

该模型在测试集上给出了 81.59 %的准确率。

fit 方法返回一个“History”对象,其中属性“History.history”是各个时期的训练和验证指标(损失和准确性)的字典。因此,它维护一个日志,该日志可用于可视化这些指标,我们将在后面看到。

4.使用 ImageDataGenerator 类的数据扩充

现在,我们将看到如何使用数据增强技术来提高我们的模型的准确性。数据增强有助于防止过度拟合,并帮助神经网络模型更好地概括测试图像的未知变化。归一化、水平翻转、微小旋转、调整大小是最常用的增强技术。**

我们将在 Keras 中使用imagedata generator类。它为输入图像提供了一系列的变换,我们可以很容易地将它们合并到我们的训练中。

**datagen_train=ImageDataGenerator(featurewise_center=True,
                                featurewise_std_normalization=True, 
                                rotation_range=20,
                                width_shift_range=0.2,
                                height_shift_range=0.2,
                                horizontal_flip=True)% For testing and validation set, we just normalize the images
datagen_test=ImageDataGenerator(featurewise_center=True,
                               featurewise_std_normalization=True)datagen_train.fit(train_X)
datagen_test.fit(val_X)
datagen_test.fit(test_X)**

培训和评估-

**model.compile(loss=losses.SparseCategoricalCrossentropy(),optimizer=optimizers.Adam(learning_rate=0.001),metrics=['accuracy'])model.fit(datagen_train.flow(train_X, train_y.flatten(), batch_size=64), steps_per_epoch=len(train_X) / 64, epochs=30, validation_data=datagen_test.flow(val_X, val_y.flatten(), batch_size=64))model.evaluate(datagen_test.flow(test_X, test_y.flatten(), batch_size=1), verbose=2)**

我们达到了 88.30 % 的测试精度,已经实现了大约 7%的提升

5.结果

这是训练进展的视觉化图像

********

6.结论

  • 我们看到了一般的图像分类流程,从数据准备和可视化、模型设计、超参数选择、训练和评估开始。
  • TensorFlow 中的 Keras API,尤其是函数式 API,使得用户设计神经网络非常方便。
  • 在训练中仅仅引入数据扩充就使模型的测试精度提高了约 7 %,从而证明了所讨论的技术的好处。
  • 我们使用 CIFAR-10 数据集进行演示,但是,该模板可以扩展到任何图像数据集。
  • 这里的 是一篇对 Keras 和 tf.keras 之间的主要差异进行广泛讨论的文章

代码可在 这里 进一步开发。

7.进一步探索

提高准确性的一些技巧:

  1. 使用具有跳过连接的架构,如 ResNet ,这些架构已被证明对图像表现良好。
  2. 我们可以用迁移学习。例如,加载在更大的相关数据集(如http://www.image-net.org/)上预先训练的模型,然后在我们的数据集上进行微调。由于大小和类别的相似性,预训练的 CIFAR-100 模型在 CIFAR-10 数据集上可能更有益。
  3. 调整使用的层和超参数。例如,SGD 优化器、更高的批量、改变过滤器尺寸和每层中的过滤器数量。
  4. 使用 学习率调度 随着模型的学习,用历元衰减学习率。
  5. 使用正则化技术,如https://keras.io/api/layers/regularization_layers/dropout/和高级策略,如 CutMix 标签平滑 混合训练 等。********

注意:

我们应该注意到,ResNet 模型最初是为更大尺寸的图像设计的。即来自 ImageNet 的 224x224。因此,它使用最大池操作和更高的卷积步长来降低层间图像的维度。因此,对于 CIFAR-10 图像,我们应该自己实现模型层,并相应地更改过滤器大小和步幅值。

如何为 scikit-learn 构建自定义评估器

原文:https://towardsdatascience.com/how-to-build-a-custom-estimator-for-scikit-learn-fddc0cb9e16e?source=collection_archive---------10-----------------------

实践教程

为不平衡数据实现具有欠采样的定制集成模型

这篇文章将向您展示如何实现您自己的模型,并使其符合 scikit-learn 的 API。最终结果将是一个模型,不仅可以拟合和用于预测,还可以与网格搜索和管道等其他 scikit-learn 工具结合使用。

介绍

这个帖子可以追溯到几个月前。在我的一门机器学习课程中,我们讨论了不平衡数据的话题,以及当数据不平衡时,算法如何很难学习。对于我们的学习算法来说,我们试图预测的事件是如此罕见,以至于在提高评估分数的过程中,我们的模型很少会预测这一类别。我一接触到这个话题就知道它超级重要。我以前见过不平衡的数据,非常清楚现实生活不像玩具数据集那么容易。最能引起我共鸣的案例是预测客户流失。

总之,在我们的课堂上,我们看到了许多可以避免或试图缓解不平衡数据问题的方法,但有一个解决方案让我特别感兴趣:整体重采样。我们在听安德里亚斯·米勒的讲座。在这一节中,他提到了一篇论文“针对类别不平衡学习的探索性欠采样”。在本文中,作者描述了一种有趣的方法来改善不平衡数据集中的分类,他们称之为 EasyEnsemble。基本思想是使用欠采样来训练集成模型,每次重新采样,并组合集成的整体结果。这种模型的好处是减少了欠采样过程中丢弃的数据量。

构建模型

定制模型的具体实现在很大程度上取决于您试图扩展或构建的模型。如果你是从零开始,一个好的开始是 BaseEstimator 。我们可以从为我们的模型构建类开始:

我们需要实现一些方法,但是首先,我们可以继续创建那个__init__方法。

此时,我们基本上只是传递所有的参数并将它们存储为属性。为了实现实际的模型,我们还需要做一些其他的事情。我们需要一种方法来生成合奏。为此,我们将定义一个函数来生成估计量:_generate_estimators

该方法不接受任何参数,因为我们需要的所有数据都已经存储在实例的属性中。我们首先创建一个评估者列表。这将是我们的最终结果;评估者列表。估计器的数量由属性self.n_estimators决定,所以我们只在 for 循环中创建每个估计器。为了构建每个估计器,我们克隆的self.base_estimator,使用所有参数设置它,并用它制作一个管道。我们需要使用不平衡学习的管道( docs )而不是使用 scikit-learn 的管道,这样我们就可以进行欠采样。

现在我们可以回到__init__函数并生成这些估计量:

很好,现在拼图的最后一块是生成一个单独的估计,它对来自集合的结果做出决定。我们将使用投票分类器,它将获得估计器的结果,并使用软投票得出最终结论。

最后,我们需要实现一些其他的方法来实现这个功能,但是不要担心,这是最难的部分,剩下的就很简单了。

我们将实现fitpredictclasses_方法,我们将通过调用VotingClassifier方法来简单地委派责任。

最后但同样重要的是,我们需要实现一个set_params方法。正如在文档中提到的,这个函数是非常基本的,因为它在网格搜索中被用来更新模型的参数。在我们的例子中,这相当简单:

将所有这些放在一起,我们得到了自己的模型,可以与其他 scikit 模型和工具结合使用。我们可以在管道中使用它,进行网格搜索,并像其他模型一样对其进行评分。

剩下唯一要做的就是测试它!

使用模型

如果您将我们刚刚构建的类存储在一个resampled_ensemble.py文件中,导入您的模型就像下面这样简单:

从现在开始,它基本上就像一个 scikit-learn 模型,所以我们可以按通常的方式进行:

我们将实例化该模型,拟合它并检查它的执行情况:

适合我们的模型的分类报告

我们还可以绘制 ROC 曲线和混淆矩阵:

我们的重采样组件模型的 ROC 曲线

我们模型的标准化和绝对混淆矩阵

然而,我认为最好的部分是我们现在可以在管道和网格搜索中使用它:

结论

如您所见,为 scikit-learn 构建您自己的定制模型非常简单,同时还可以利用 scikit-learn 提供的其他工具。您可以构建任何您想要的模型,并且仍然能够将它与度量、管道和网格搜索一起使用。在这篇文章中,我展示了一个为不平衡数据实现模型的例子,但是可能性确实是无穷无尽的。例如,同样的方法可以用于在 scikit-learn 中实现概率编程的贝叶斯模型。我想我们将不得不在以后的帖子中讨论它…

刘小燕,吴俊杰,周志宏(2008)。类别不平衡学习的探索性欠采样。 IEEE 系统、人和控制论汇刊,B 部分(控制论)39 (2),539–550。

穆勒(2018)。高级 Scikit-learn,GitHub 资源库,https://github.com/amueller/ml-training-advanced

米勒和圭多(2016 年)。Python 机器学习简介:数据科学家指南(第 1 版。).奥莱利媒体。

如何在气流上建造 DAG 工厂

原文:https://towardsdatascience.com/how-to-build-a-dag-factory-on-airflow-9a19ab84084c?source=collection_archive---------2-----------------------

用一半代码构建高效 Dag 的指南

照片由克里斯里德在 Unsplash 拍摄

为什么是达格工厂?

让我们看一个非常简单的 DAG,它有两个任务…

在 Airflow 上执行两个简单的 python 脚本所需的样板代码数量是不是很奇怪?不管你写了多少 Dag,你肯定会发现自己在很多不同的 Dag 中写了几乎所有相同的变量,只有微小的变化。

记住,在编码中,通常最好是写一段你以后可以调用的代码,而不是每次你需要那个过程时都写同样的代码。这就叫干干。

如果您的许多 Dag 共享相似的值,例如电子邮件地址开始日期计划间隔、重试次数等等,那么最好有一段代码来实现这些值。这就是我们试图用工厂类实现的目标。

在 Airflow 上使用 DAG 工厂,我们可以将创建 DAG 所需的线路数量减少一半

让我们看看下面的例子

这里,我们想要一个简单的 DAG,它打印今天的日期,然后打印“hi”。

这是它在气流上的样子:

注意我们减少了多少混乱。我们还没有指定使用什么操作符、任务的 id 是什么、计划间隔、谁创建了 DAG 以及它是何时创建的。

我们还可以看到,我们使用字典指定了任务和依赖项,并最终转化为正确的任务依赖项😄

让我们看一个稍微复杂一点的例子:

在这个 DAG 中,我指定了两个参数,我想从缺省值中覆盖它们。这些是 DAG 的所有者及其重试次数。我还在get_airflow_dag()方法中指定了我想要的每日日程表。

此 DAG 有 3 项任务。say_bye()print_date()都依赖于say_hi()。让我们看看这在气流上是什么样子。

现在,让我们看看如何构建 DAG 工厂😃

怎么编码?

老实说,这很简单。我们首先创建一个类,它将包含我们需要运行的所有方法,以便创建一个包含其任务的 DAG。

下面是 DAG 工厂的完整代码。

为了获得完全可用的 DAG,我们将调用的主要方法是get_airflow_dag()

该方法将接收两个强制参数:DAG 的名称和它应该运行的任务。其余的参数是可选的,因为我们可以在函数的实现中设置默认值。在实现时,根据您的用例,可以随意将这些可选参数设置为强制参数,例如,将 cron ( schedule_interval)设置为强制参数或者甚至是 DAG 的所有者可能会很有用。

default_args参数将是一个字典,保存您可能想要覆盖的任何键和值。如果未指定,将使用默认的 default_args。

在我们的例子中,缺省值是:

DEFAULT_ARGS = {
'owner': 'Data Engineer',
'depends_on_past': False,
'start_date': datetime(2021, 1, 1),
'email': ['data_engineers@company.com'],
'email_on_failure': True,
'email_on_retry': False,
'retries': 1,
'retry_delay': timedelta(minutes=5),
}

其他 3 个参数是用于描述 DAG 的主要参数。有更多的选项,所以请随意指定更多。

get_airflow_dag()将运行create_dag()来创建 DAG 对象并返回它。add_tasks_to_dag()稍微复杂一点,因为我们想让用户更容易指定一种方法来创建任务的依赖关系,而不必编写操作符

在我们的例子中,我们总是使用 PythonOperator 来完成我们的任务,所以假设这是一种规范是有意义的。

该实现旨在方便数据工程师的工作,所以我们避免设置额外的东西,如任务的名称,我们只是假设它与函数的名称相同——所以我们使用一点点反射来解决它。

for func in tasks:
    task_id = func.__name__
    task = PythonOperator(
        task_id=task_id,
        python_callable=func,
        dag=dag
    )
    aux_dict[task_id] = taskfor func, dependencies in tasks.items():
    task_id = func.__name__
    for dep in dependencies:
        aux_dict[dep.__name__] >> aux_dict[task_id]

该函数首先创建一个辅助字典来保存 task name: task object 的键值对。这样做是为了只有一组任务对象,并在以后使用它来设置依赖关系。然后,对于最初提供的任务字典中的每个键,利用辅助字典来设置依赖关系。

完成后,DAG 对象就可以被团队返回和使用了🎉。

抓住你了。

文件中有一个小技巧,可以让 Airflow 识别出我们要返回的是一个正确的 DAG。

当 Airflow 启动时,所谓的 DagBag 进程将解析所有文件以查找 Dag。当前实现的工作方式是这样的:

  • dagBag 产生不同的进程,这些进程查看 Dag 文件夹中的文件。
  • 这里称为process_file 的函数为每个文件运行,以确定那里是否有 DAG。
  • 代码运行might_contain_dag,根据文件代码中是否包含“dag”和“airflow”返回 True。这里实现。

这就是为什么像这样调用函数get_airflow_dag的原因,以便在文件中包含两个关键字,这将导致文件被正确解析。

这是一个很难找到的东西,我花了很多时间试图找出为什么我的 DAG 工厂不工作。关于以非传统的方式创建 Dag 需要考虑什么,没有太多的文档,所以这是您在做类似事情时必须考虑的一个大问题。

结论

这篇简单的文章旨在解释如何利用气流上的工厂模式,让数据工程师的生活变得更轻松。

希望你喜欢它!请随意点击我的个人资料,查看其他有用的气流和数据工程文章!😄

如何在 R Shiny 中搭建一个数据分析 App

原文:https://towardsdatascience.com/how-to-build-a-data-analysis-app-in-r-shiny-143bee9338f7?source=collection_archive---------8-----------------------

初学者的循序渐进指南

作者截图

闪亮的是一个 R 包,让你建立交互式网络应用。你需要的只是 R,没有 HTML、CSS 或 JavaScript——尽管你当然可以选择用它们来增强你的应用。你可以在你的电脑上运行应用程序,托管在你自己的服务器上,或者使用 RStudio 的云服务。

在这篇文章中,我将从头开始讲述构建一个简单的数据分析应用程序的过程。你可以在那里找到很多优秀的基础指南,我的目标是更进一步:我们将做一些动态 UI 更新、动态输出、动作按钮面板导航等。

请注意,这不是一个“严肃的”数据分析应用程序,我的目的是展示可能会派上用场的 shiny 的不同功能。然而,一旦我们完成了,向我们的代码添加新的功能应该是相当容易的。

有用的链接

你可以看看我们要在 shinyapps.io 上搭建的app:https://matepocs.shinyapps.io/data_analyser/。

底层代码在我的 GitHub 上。

Shiny 是一个非常有据可查的包,在其 网站 上有的优秀指南。其实有点太有案可稽了,很容易迷失在入门视频、教程、文字指南、文章等迷宫中。

我个人觉得 Hadley Wickham 的Mastering Shiny是一个很好很紧凑的源码,强烈推荐。

准备

规划应用程序

这是我们希望我们的应用程序能够完成的高级设计草图

用户:

  • 导入一个.csv文件;
  • 从列中选择最多 2 个数值型和 1 个因子型变量。

然后是 app :

  • 绘制一个情节;
  • 创建汇总表。

有趣的是我们希望输出根据我们选择的列类型而不同——如果只是选择一个因子变量,我们希望有不同的图,如果我们有一个因子的数值变量,我们希望有一个更复杂的图。

工作环境

我们将在 RStudio 和 r 中工作。要使用shiny,您首先需要安装包:

install.packages(“shiny”)

(我们还将使用的其他软件包:data.tableggplot2,您可能也需要安装它们。我假设你对这些软件包很熟悉。)

接下来,我们需要用 app 的名字创建一个文件夹。我把我的叫做data_analyser。我们将继续在这个文件夹中工作。

一个shiny应用的框架非常简单:一个 R 脚本必须被称为 app.R。所以我们将在我们的data_analyser文件夹中放一个。

(注意:如果你阅读一些旧的指南,你可能会发现这个框架令人困惑。与包含 UI 和服务器功能的 app.R 不同,您过去只需要两个脚本:一个 server.R ,一个 ui.R 。由于传统原因,这种老方法仍然有效,但我认为不推荐使用。此外,您可以在文件夹中有不同的脚本,并在您的应用程序脚本中提供它们。因此,您不必像我们现在要做的那样将所有内容都放在一个脚本中,您可以将您的服务器功能存储在一个单独的 server.R 脚本中,并对其进行编译,只要知道这不是一个要求即可。)

闪亮的框架

最小闪亮应用框架看起来像这样:

library(shiny)ui <- fluidPage()server <- function(input, output){}shinyApp(ui = ui, server = server)

您可以将它复制到您的app.R,并且应该能够通过使用键盘快捷键(如 Cmd + Shift + Return)或点击 RStudio 中的运行应用程序按钮来运行它(它将自动识别这是一个闪亮的应用程序):

(另一种在本地运行应用程序的方式是简单地在控制台上输入runApp(…/data_analyser),当然是添加文件夹的路径。)

如果你运行这个应用程序,你应该会看到一个空窗口弹出。这是意料之中的,但是是时候改变了!

构建步骤

正如这个框架所暗示的,一个闪亮的应用有两个部分:用户界面,和服务器

ui对象负责 app 的布局。它将决定显示什么样的页面或标签,如何格式化显示的文本,需要用户输入什么样的内容,以及将输出放在哪里。(我们还不知道具体的输出是什么,但我们知道它们各自的走向!)

server定义 input output 数据帧之间的连接 的函数。它基本上是一个观察器列表,寻找输入值变化的代码块或其他观察器(只是为了保持有趣)来确定屏幕上显示的输出是否应该更新。

布局

我们将首先关注布局,它是在ui对象中定义的。

首先,让我们进入页面和选项卡。当我们开始输入第一个原型时,我们将ui定义为一个 fluidPage 。我发现很多初学者指南都用 fluidPage,特别是一个sidebarLayout,所以这次让我们做点不同的吧!

我们想为我们的应用程序创建单独的页面,就像一个合适的网站,我们可以使用 navbarPage 来实现这个目的。这将在顶部创建一个链接到不同页面的标题。让我们放入两页:

ui <- navbarPage(
  title = "Data Analyser", 
  main_page, 
  about_page
)

代码还不能运行,我们需要定义这两个页面。两者都需要是一个 tabPanel 对象。它们不可能是流水账。(如果你开始觉得这令人困惑和特别,你并不孤单,但我们几乎没有新的页面构建概念。)

让我们放入两页:

main_page <- tabPanel(title = “Analysis”)
about_page <- tabPanel(title = “About”)

如果您现在运行应用程序,您应该会在顶部的看到导航面板。

你可以把一些一般信息放在“关于”页面上。当格式化文本时,你有许多选择,请看这里的完整列表。这个页面的存在只是为了展示不同的页面如何工作。

about_page <- tabPanel(
 title = “About”,
 titlePanel(“About”),
 “Created with R Shiny”,
 br(),
 “2021 April”
)

(注意:您可以在页面本身和导航面板上使用不同的标题。)

分析页面将会更加精彩。首先,我们希望输入位于左侧的侧边栏中。然后,我们希望在右边有一个单独的绘图和表格区域。用闪亮的术语来说:我们的主页面,tabPanel 将是一个https://shiny.rstudio.com/reference/shiny/0.14/sidebarLayout.html侧栏布局,左边是一个【输入】 侧栏 ,右边是一个 主面板 ,它将采用一个 tabsetPanel 的形式,有两个tab panel。呼。

我觉得我没有理由总结这些是做什么的,如果你好奇可以看看链接,但是名字应该是不言自明的。

这是主页面的框架:****

main_page <- tabPanel(
  title = "Analysis",
  titlePanel("Analysis"),
  sidebarLayout(
    sidebarPanel(
      title = "Inputs"
    ),
    mainPanel(
      tabsetPanel(
        tabPanel(
          title = "Plot"
        ),
        tabPanel(
          title = "Statistics",
        )
      )
    )
  )
)

如果您现在运行该应用程序,您应该会看到以下内容:

(注:这是一个检查 shiny 用这些奇怪的构建模块做什么的好时机。如果您只需在控制台中键入脚本的 main_page 部分,您将看到 shiny 如何将其转换为 HTML。)

输入

接下来,我们将使用不同的用户输入表单来填充输入部分。文本或数字输入、滑块、下拉选择、单选按钮等。在闪亮的宇宙中被统称为小部件。(这里可以找到综合列表。)

每当你添加一个输入小部件时,第一个参数将是它的 ID,这就是我们如何在后面的server部分引用那个特定的输入。第二个参数是标签——放置在界面周围的文本字段,告知用户它的用途。

同样,我们可以列出各个类型的详细信息,但大多数都很简单。我们将需要 文件输入选择输入 ,和一个 动作按钮 ,有更多的细节在官方网站阅读。我们可以在 main_page 的“输入”侧栏面板中插入以下代码:

fileInput("csv_input","Select CSV File to Import",accept=".csv"),
selectInput("num_var_1","Numerical Variable 1",choices=c(not_sel)),
selectInput("num_var_2","Numerical Variable 2",choices=c(not_sel)),
selectInput("fact_var","Factor Variable",choices=c(not_sel)),
actionButton("run_button","Run Analysis",icon=icon("play"))

备注:

  • 由逗号分隔的输入将被很好地排列在一起。
  • 后面我们将这些输入称为input$csv_inputinput$num_var_1等。****
  • 在选择输入字段中,我认为以一个通知用户还没有选择任何东西的选择开始会很好。这就是为什么 not_sel =“未选中”全局变量诞生了。
  • 您可以从 字体牛逼 字形图标 库中添加一个 图标到页面中。你不需要为这个功能安装任何额外的东西。

如果您现在运行应用程序,您应该会看到以下内容:

我们剩下要做的就是决定输出要去哪里,这样我们就完成了 UI。

输出

输出遵循与输入类似的逻辑。此时,我们所能确定的是:

  • 屏幕上的位置;
  • 类型(shiny 必须预先知道它将是文本、表格、情节等);
  • 还有身份证。

就像输入一样,我们可以简单地在main_page的相应区域添加字段,shiny 会智能地填充可用空间。

在绘图选项卡上,我们想要添加的只是一个 绘图输出 :

*plotOutput(“plot_1”)*

统计选项卡将变得更加复杂。我们将利用 fluidRow 功能来将不同的项目并排放置*。(注意到目前为止每个逗号是如何导致下一行呈现在第一行下面的。我们希望避免我们将要创建的小表出现这种情况,将它们放在一起。)***

这是更新后的统计选项卡面板:

*tabPanel(
  title = "Statistics",
  fluidRow(
    column(width = 4, strong(textOutput("num_var_1_title"))),
    column(width = 4, strong(textOutput("num_var_2_title"))),
    column(width = 4, strong(textOutput("fact_var_title")))
  ),
  fluidRow(
    column(width = 4, tableOutput("num_var_1_summary_table")),
    column(width = 4, tableOutput("num_var_2_summary_table")),
    column(width = 4, tableOutput("fact_var_summary_table"))
  ),
  fluidRow(
    column(strong("Combined Statistics"))
  ),
  fluidRow(
    column(tableOutput("combined_summary_table"))
  )*

在第一行,我们将有三个标题,代表三个可选变量。这需要是一个output,因为它会随着我们选择不同的列而动态变化。

接下来,我们放入三个一维汇总表。我们还不用担心它们是什么,我们只知道标题下面会有表格。

最后,我们放入一个合并的汇总表,探索所选变量之间的关系。

备注:

  • 各列的宽度参数显示它们的相对尺寸,遵循 自举网格系统 。(Shiny 用的是同样的框架。)
  • 将文本放在 strong() 中使其加粗。

好了,输出已经放好了。如果你现在运行应用程序,你会看到…自上次以来没有任何变化。是时候连接输入和输出了!

Shiny 中反应式编程的快速总结

在我们开始构建我们的应用程序之前,我认为让快速总结一下* 反应式编程 在 Shiny 中的体现是有益的。如需更详细的指南,请查看本页。***

服务器函数基本上将是一长串连接输入和输出的表达式。有趣的是,这些表达式的顺序通常并不重要,尽管您可能希望保留一些逻辑。

屏幕上显示的大多数输出最终将来自一个render函数。对于文本输出使用 renderText,对于绘图输出使用 renderPlot,等等。所使用的渲染函数的类型将取决于输出的类型。例如,如果您在 ui 中定义了一个 ID 为“book”的 textOutput,并希望在那里显示文本“Dune ”,您可以这样做:

*output$book <- renderText(“Dune”)*

观察你需要如何渲染文本“沙丘”,即使它看起来已经很有纹理了!

当然,您可能希望保持输出的动态性——否则,您可以只在页面上打印标题。

下一步是将它连接到一个input。假设您有一个 ID 为“title”的 textInput 字段。如果您添加以下行:

*output$book <- renderText(input$title)*

每当您更新 title 字段时,图书输出也会更新。

这就是整个系统的美妙之处,如果用户更新了title字段,你不必确定会发生什么——你已经建立了连接,而book输出会像老鹰一样监视任何变化。

下一步,你可以创建所谓的反应表达式:这是输入和输出之间的一种中间步骤。例如,如果要保存两个数字输入的总和,可以将它们保存在一个变量中:****

*sum_of_numbers <- reactive(input$num_1 + input$num_2)*

然后像输入一样使用sum_of_numbers。注意,sum_of_numbers是一个函数,所以当你在代码中引用它的值时,你必须在它后面加上括号(这肯定是一个容易忘记的事情):

*output$sum <- renderText(sum_of_numbers())*

这种来自输出部分的持续警惕起初听起来很棒,但是您很快就会意识到缺点:有些情况下,您肯定不希望每次输入改变时都更新输出字段。这可以通过一个event reactive函数来实现,该函数是一个带有额外输入的反应式表达式:它只在所选输入字段的值发生变化时运行。**

这可能一开始听起来令人困惑,但一旦我们看到实际步骤,就会变得清晰得多。

还有一个格式化注意事项:在server函数中,大多数表达式遵循以下格式:

*variable_to_create <- some_reactive_function({ 
    code_to_execute
})*

(整个服务器功能也是如此。)花括号只是允许您将代码放在多行中。如果你能把代码放在一行中,你可以省略它们。

导入。csv 文件

好了,现在我们知道了这个理论,让我们开始迂回地应用它!

回想一下,我们有一个名为input$csv_input的输入项。一旦被填充,这实际上是一个data.frame,它的元素之一是datapath。(查看此处了解更多信息。)一旦我们知道了文件的路径,我们就可以把它读入* data.table,就像我们通常用fread读入文件一样。***

然而,我们还需要一种配料。如果我们只是试图加载输入字段中的任何内容,应用程序将会试图加载一个空文件并立即崩溃。为了防止这种情况,我们需要添加一个reqcondition:Shiny 确保我们确实有必要的输入的方法。

因此,这将是我们在服务器函数中的第一块:

*data_input <- reactive({
    req(input$csv_input)
    fread(input$csv_input$datapath)
  })*

现在,每当我们上传一个.csv文件,app 就会自动将其结果保存在名为data_inputdata.table中。嗯,不完全是。更准确地说,我们有一个data_input函数,它返回一个data.table。(这个非常容易搞砸!)

(注意:我还没有对数据类型进行任何验证。如果你试图导入任何不是. csv 文件的东西,这个应用程序就会毫不客气地死机。请看这里的https://mastering-shiny.org/action-transfer.html了解更多关于如何确保它是一个. csv 文件的信息。)

基于导入的更新

我们有了数据,我们想用它做什么?

作为第一步,我们希望更新输入部分中的选择—到目前为止,唯一的选项是“未选择”。

我们将使用两个新概念:

  • 整件事将被包裹在一个 观察事件 中。该函数允许您在特定输入字段或反应表达式发生变化时执行一段代码。我们现在要注意的是data_input反应表达式。
  • 为了动态改变选择,我们使用updateSelectInput。顾名思义,这个函数接受一个选择输入字段,并对它进行更新,在我们的例子中就是选择。

我们还创建了一个变量choices,它将是一个

  • “未被选中”,我们总是希望在顶部,
  • data.table中的列。

要在服务器功能中输入的相关代码:

**observeEvent(data_input(),{
  choices <- c(not_sel,names(data_input()))
  updateSelectInput(inputId = “num_var_1”, choices = choices)
  updateSelectInput(inputId = “num_var_2”, choices = choices)
  updateSelectInput(inputId = “fact_var”, choices = choices)
})**

(注意:我最初在这里使用了一个非常奇怪的解决方案来更新选择。在 ui 中有一个选项可以添加输出字段,这些字段将在render ui*函数的帮助下呈现为输入小部件。因此,您确定了 ui 部分中 ui 元素的位置,但是它是作为输出动态创建的。我发现这个解决方案令人困惑,也不太符合逻辑,因为布局和内容之间清晰明了的区别变得模糊了,但这是可能的。)*

我们现在应该看到导入一个.csv文件的影响,一旦导入,您应该能够在下拉列表中选择列名:

如果我们按下按钮呢?

既然我们可以选择要使用的列,那么就该将它们连接到输出了。

让我们试着想象一下,当我们改变其中一个下拉选项时,我们想要看到什么。答案是:我们实际上不想看到任何变化。在我们完成选择之前看到剧情跳跃会很烦人。我们需要在输入和输出之间设置一道屏障,这就是运行分析按钮的用途。

我们将使用一个event reactive表达式。它就像一个常规的反应表达式,但只根据另一个输入的变化进行更新。

**num_var_1 <- eventReactive(input$run_button,input$num_var_1)
num_var_2 <- eventReactive(input$run_button,input$num_var_2)
fact_var <- eventReactive(input$run_button,input$fact_var)**

这样,我们创建了三个表达式,它们的名称与输入源的名称相同(这种命名约定您可能会觉得很讨厌,但我发现这样更简洁)。诀窍在于当run_button输入发生变化时,num_var_1()表达式只会将其值更新为最新的num_var_1输入。

对一个按钮的改变将是 10 次点击中的 10 次。

(注意:这些值将是字符值,但是没有必要使用 renderText,因为我们实际上并没有直接将它们放在屏幕上。)

画出情节

首先,我们需要创建一个绘图对象。就像上面的变量一样,这将取决于按钮的点击。为什么我们不能仅仅依靠价值更新呢?我们将使用 4 个变量:data_input(),num_var_1(),num_var_2(),和 fact_var()。问题是 data_input()不受按钮点击的保护,每当我们选择一个新文件时,值就会更新。

这就是我们将要拥有的:

**plot_1 <- eventReactive(input$run_button,{
    draw_plot_1(data_input(), num_var_1(), num_var_2(), fact_var())
  })**

其中draw_plot_1是一个常规的 R 函数,它可以在server函数之外定义。完整版的draw_plot_1功能,看看我的 GitHub 。我越想聪明地一个块一个块地构建ggplot,代码就越不可读,所以我坚持使用一个冗长的 if-else 语句。该函数是这样开始的:

**draw_plot_1 <- function(data_input, num_var_1, num_var_2, fact_var){
  if(num_var_1 != not_sel & 
     num_var_2 != not_sel & 
     fact_var != not_sel){
     ggplot(data = data_input, 
        aes_string(x = num_var_1,y = num_var_2,color = fact_var)) +
        geom_point()
    }**

所以该函数有三个输入,一个data.table(注意它不再是draw_plot_1函数内部的函数,而是一个真正的常规表,所以不需要使用括号!),以及三个列名,其中任何一个都可以“未选中”,在这种情况下应该忽略。

在上面显示的第一个分支中,使用了所有的变量。在这种情况下,我们需要一个散点图,其中两个轴是两个数值变量,它们被因子变量分成不同的组。

当然,你可以根据自己的目的改变这些情节。

最后,我们必须呈现服务器函数内部的情节:

**output$plot_1 <- renderPlot(plot_1())**

如果您现在运行代码,您应该能够根据您选择的变量看到绘图的更新。如果这三个变量都被选择,你应该有一个彩色散点图:

(并不是说你会想用颜色来描绘这么多的因素!)

如果你只有一个数值变量,它应该画一个小提琴图:

创建表格

我们创建表格的方式将使用类似的逻辑。

回想一下,我们为前三个表添加了一些标题。我们可以这样定义它们的值:

**output$num_var_1_title <- 
  renderText(paste("Num Var 1:",num_var_1()))
output$num_var_2_title <- 
  renderText(paste("Num Var 2:",num_var_2()))
output$fact_var_title <- 
  renderText(paste("Factor Var:",fact_var()))**

不需要将这些放在 eventReactive 中,并使更新以动作按钮为条件,因为底层变量已经只在点击动作按钮时更新。重申一下,例如,我们在上面的公式中使用的num_var_1()表达式是这样的:

**num_var_1 <- eventReactive(input$run_button,input$num_var_1)**

而不是input$num_var_1本身。

如果你现在运行这个应用程序,你应该会看到标题(回想一下我们在创建 UI 时把“组合统计”作为一个固定文本放进去):

我们有四个表要创建,让我们看看一维数值表是如何创建的,其余的遵循类似的结构,查看 GitHub 中的代码。

首先,我们使用另一个 eventReactive 表达式,每当单击 action 按钮时运行一个函数:

**num_var_1_summary_table <- eventReactive(input$run_button,{
    create_num_var_table(data_input(), num_var_1())
  })**

接下来,我们定义create_num_var_table函数:

**create_num_var_table <- function(data_input, num_var){
 if(num_var != not_sel){
  col <- data_input[,get(num_var)]
  if(length(col)>5000) col_norm<-sample(col,5000) else col_norm<-col
  norm_test <- shapiro.test(col_norm)
  statistic <- c("mean", "median", "5th percentile", 
                 "95th percentile", "Shapiro statistic", 
                 "Shapiro p-value")
  value <- c(round(mean(col),2), round(median(col),2),
             round(quantile(col, 0.05),2), 
             round(quantile(col, 0.95),2),
             norm_test$statistic, norm_test$p.value)
  data.table(statistic, value)
  }
}**

结果将是一个包含两列统计和值的data.table。我只是放了一些我能想到的统计数据,还有一个正态性测试,加上你喜欢的任何东西。

(注意:内置的正态性测试有 5000 个样本大小的限制,所以如果导入的 .csv 文件比较长,我会随机抽取一个样本。)

最后,我们将表格呈现在屏幕上:

**output$num_var_1_summary_table <- renderTable(num_var_1_summary_table(),colnames = FALSE)**

我不想显示表格的标题,这可以在colnames参数中设置。

对于其他表,您需要遵循类似的结构。在组合表中,就像我们对图所做的那样,根据我们选择的变量类型,有不同的分支。如果我们选择了所有三个变量,表格将通过因子变量计算不同子组中两个数值变量之间的相关性。

不用说,这只是一种方法,一旦结构完成,您可以在这些表中放入任何您想要的东西。

如果您运行该应用程序,您应该会看到以下内容:

我们结束了,对吗?差不多!

选择一个主题

正如永恒的建议所说,永远不要拖欠任何东西!

所以我们打算改变默认主题。有几种方法可以做到这一点,包括使用自己的 CSS 模板,我们将采取一种非常简单的方法,使用 shinythemes 。你需要先安装软件包。然后,你需要做的就是选择一个主题,然后把它放到 ui 对象中,就像这样:

**theme = shinytheme('united')**

瞧,我们可以看到同一个屏幕,但现在是橙色的(或者你选择的任何东西):

现在我们完成了!

附加注释

本指南比我预期的要长得多,有一些细微差别我觉得我不应该提及,但为了完整起见,它们在这里:

  • 默认情况下,您可以上传的最大文件大小为 5 MB。您可以通过在服务器函数中输入以下代码来增加该值:
    options(shiny.maxRequestSize=10*1024^2) (这将是 10 MB)
  • 如果您想使用数字字段作为因子,R 将生成绘图,但会添加一个连续的色标。在draw_plot函数中,我从这段代码开始将列转换为因子:
    if(fact_var!=not_sel){ data_input[,(fact_var):= as.factor(data_input[,get(fact_var)])] }
  • 您可能已经注意到,对于同一个按钮点击,我们使用了很多 eventReactive。将所有东西收集在一个data.frame中可能比将它们放在单独的事件中更好。并且绘图和表格绘制函数也使用 eventReactive,即使大多数变量已经在内部“eventReactivated”了。我这样做的原因是因为每次导入新的.csv文件时data_input()都会更新。相反,添加另一个data_input_2()变量可能会更清楚,当您单击按钮时,它会根据data_input()进行更新,然后在常规反应表达式中使用该函数以及num_var_1()等。这只是一个例子,说明这种反应式编程可能非常动态,但同时也令人困惑。

App 怎么运行?

当实际运行应用程序时,您有三种选择。

  1. 您可以在本地运行它,例如点击 RStudio 中的运行应用程序按钮。你也可以用 runApp 函数在不打开脚本本身的情况下运行。
  2. 第二个选项是 闪亮服务器 ,用它你可以把它托管在自己的服务器上。我对这个选项没有经验。
  3. 或者可以用 shinyapps.io ,也就是云服务。

我用 shinyapps.io 来托管这个应用程序,你可以在这里查看。

使用 shinyapps.io 非常简单,你注册,创建一个帐户,获得一个令牌,用它你可以发布你的应用程序。一个免费的帐户,你可以获得 5 个应用程序和每月 25 个活跃用户小时。

****https://matepocs.medium.com/membership

其他有用的链接

再一次,我推荐你掌握哈德利·威克姆的《闪亮》,如果你想以一种好的、有条理的方式学习《闪亮》:

你可以在这里找到一些有用的备忘单:

https://www.rstudio.com/resources/cheatsheets/

这是一个 GitHub repo,其中有一个 R 包列表,增强了 Shiny 的默认功能:

https://github.com/nanxstats/awesome-shiny-extensions ****

如何从零开始构建数据湖—第 1 部分:设置

原文:https://towardsdatascience.com/how-to-build-a-data-lake-from-scratch-part-1-the-setup-34ea1665a06e?source=collection_archive---------3-----------------------

如何利用流行技术构建数据工程沙盒的完整教程

在这一系列文章中,我将指导您建立我们自己的数据湖基础设施作为数据工程沙箱。在第一部分中,我将向您展示如何用 docker 托管必要的服务,以及如何配置它们,以便您所做的任何更改都将被完全持久化。在本系列的第二部分中,我将解释如何配置服务以相互通信,以及如何创建模板,通过这些模板,您可以在平台上实现自己的数据项目、概念验证和测试。

您不需要了解 Docker 或任何已使用的服务就能理解本教程,但它可能会帮助您在遇到错误时排除故障。无论如何,我会尽可能具体地让你开始。这些工具被广泛使用,如果你决定深入研究,你可以在网上找到大量的问题、解决方案和指南。

一方面,目标是展示用 docker 托管您自己的数据湖基础设施所需的基础工作,但我也希望您能够理解设计选择和配置背后的原因。为了这个目的,当我认为有必要时,我有时会详细说明:帮助你以后自己找到路。

杰里米·毕晓普在 Unsplash 上拍摄的一张湖上日落的照片。

工具箱

数据工程师在概念验证、用例、项目或开发和生产应用中使用许多工具。下面是这些工具的一个小的,但是广泛流行的子集。正如斯坦尼斯拉夫·莱姆在科幻小说《索拉里斯》中的名言:“没有答案。只有选择。”本着这种精神,让我来介绍一下 techstack!

我们将使用…

Apache NiFi 处理和分发数据。

  • Apache NiFi 支持强大且可伸缩的数据路由、转换和系统中介逻辑的有向图。Apache NiFi 的一些高级功能和目标包括基于 web 的用户界面、高度可配置的服务和数据来源。Apache NiFi 是开源的、可扩展的、安全的服务,背后有一个庞大的社区。点击此处阅读更多内容。
  • 使用 Apache NiFi 的公司:三星,花旗集团,戴尔,迪士尼,Hashmap。

Apache NiFi Registry 用于存储、管理和版本控制 NiFi 资源。

  • Registry 是 Apache NiFi 的一个子项目,它是一个补充应用程序,为跨一个或多个 NiFi 实例的共享资源的存储和管理提供了一个中心位置。我们将使用它来对我们的数据流进行版本控制,并创建可重复使用的模板。点击此处阅读更多内容。

Apache Airflow 以编程方式创作、安排和监控工作流。

  • Airflow 是可伸缩的,因为它的模块化架构,并使用消息队列来编排任意数量的工作器。它的管道是用 Python 编写的,这意味着它允许从代码中动态创建管道,并且可以通过自定义操作符进行扩展。它的 web 用户界面很实用,可以访问管道的所有部分:从源代码到日志。点击此处阅读更多内容。
  • 使用阿帕奇气流的公司:Airbnb、Slack、Robinhood、Square、9GAG。

作为对象关系数据库的 PostgreSQL。

  • PostgreSQL 是一个强大的开源对象关系数据库系统,它在可靠性、功能健壮性和性能方面享有盛誉。点击此处阅读更多内容。
  • 使用 PostgreSQL 的公司:NASA,Instagram,Twitch,Reddit,Twitter。

pgAdmin 作为 PostgreSQL 的管理和开发平台。

  • pgAdmin 是 PostgreSQL 数据库的开源数据库管理和开发平台。我们将在 docker 上发布它的网络版。点击此处阅读更多内容。

MinIO 作为 AWS S3 的本地托管替身,作为对象存储。

  • MinIO 提供高性能、S3 兼容的对象存储。也就是说,我们可以使用任何为 AWS S3 和 MinIO 开发的连接器。这允许我们在本地开发对象存储的概念验证——而不必在 AWS 上托管(并支付)实际的 S3 存储桶——如果我们愿意,以后可以用实际的 S3 存储桶无缝地替换连接。点击此处了解更多。
  • 使用 MinIO 的公司:苹果,GitLab,普华永道,万事达,Paypal,Kayak。

Docker 托管我们的服务。

  • Docker 让我们几乎可以在任何地方轻松托管、运行、使用和配置应用程序。Docker 托管与环境其余部分隔离的容器,因此允许简化和加速工作流。
  • 使用 Docker 的公司有:优步、亚马逊、易贝、纽约时报、Shopify。

这应该让您对构成我们的数据湖基础设施的应用程序有了一个大致的了解。其中一些——如 Apache NiFi Registry——将帮助我们更有效地开发,而其他服务——如 Airflow——将成为我们自己的数据工程沙箱的核心组件。

现在,让我们开始实际设置它们吧!

数据湖组件—由作者创建的图像。维基百科的图标。

准备

首先,您需要安装 docker(例如,从到这里的)。

然后,创建一个空目录,并在其中打开一个终端。

所有必要的代码和文件都将在本文中链接。

码头工人

首先,我们需要一个docker-compose.yml文件,指定我们希望托管哪些服务以及它们在启动时的配置参数。

根据 docker 官方网站:

“组合文件提供了一种记录和配置所有应用服务依赖项(数据库、队列、缓存、web 服务 API 等)的方法。使用编写命令行工具,您可以用一个命令( *docker-compose up* )为每个依赖项创建和启动一个或多个容器。 来源

我们将在本教程中使用的docker-compose.yml文件可以在这里或者在这篇文章的最后找到。将代码复制粘贴到您自己的文件中,或者使用 curl 从终端直接下载到本地文件中:

我们使用以下 docker 映像来托管我们的服务,因为它们在本文撰写时是最新的和/或使设置最容易。通过固定版本(越具体越好),我们可以确保每个人都将运行完全相同的设置。这也是 docker 的主要优势之一——不再是“但它能在我的电脑上工作”。

  1. 气流:puckel/docker-airflow:1.10.9
  2. 动物园管理员:bitnami/zookeeper:3.7.0
  3. 倪飞:apache/nifi:1.14.0
  4. NiFi 注册表:apache/nifi-registry:1.15.0
  5. 米尼奥:bitnami/minio:2021
  6. Postgres: postgres:14-bullseye
  7. pgadmin: dpage/pgadmin4:6.1

你可以自由地使用标签:latest来代替上面指定的版本,只要在你阅读下面的章节时,确保你知道从上面的版本以来的任何变化。然而,latest标签通常是不可预测的,可能会破坏东西,因为随着时间的推移,您将获得不同的图像版本。

启动服务

通过在终端中从我们的docker-compose.yml文件所在的同一个目录中运行docker-compose up命令:

我们告诉 docker 从 web 上提取图像,创建指定的容器并启动文件中定义的服务。运行该命令后,会出现一个日志消息墙,显示服务启动和运行时的日志消息。

日志消息墙—由作者创建的图像。

如果您是 docker 的新手,我建议您使用 Docker 桌面应用程序来跟踪您的服务的健康状况,但是理论上您可以从命令行使用docker ps --all和/或docker stats来做同样的事情。如果要停止 docker 服务,在带有文本墙的终端中按CTRL+C。现在,只要保持服务(和文本墙)运行。

Docker 容器—由作者创建的图像。

如果在使用不同的配置多次停止/启动服务后,服务出现问题,请确保运行docker-compose up --force-recreate。附加标志确保 docker 在启动服务之前获取对合成文件的最新更改。

docker 合成文件的内容

既然您已经复制了docker-compose.yml文件并知道如何启动它,我想解释一下组成 compose 文件的不同代码段。

接下来的章节将详细介绍:

  1. 命名卷和绑定装载
  2. 端口转发
  3. 用户定义的网络和网桥
  4. 主机名和容器名
  5. 环境变量
  6. 重启策略
  7. 健康检查

我将主要使用来自 docker-compose.yml 文件的 airflow 服务的例子:

该文件从指定 docker-compose 软件本身的版本(3)开始。以前的版本可能在语法和功能上有所不同。

yml 文件中的下一个键(services)指定了容器及其配置。一个这样的服务是 Airflow——在上面的例子中,我们想要从 docker 映像puckel/docker-airflow:1.10.9创建一个容器服务。docker 映像基本上是一个特定配置的安装程序,由一组关于如何构建托管特定服务的 docker 容器的指令组成。一个映像的不同版本,甚至不同的映像可能托管相同的应用程序,但是以不同的设置作为起点。

特定于容器的参数将在以下章节中详细讨论。

命名卷和绑定装载

一旦容器停止,在 docker 容器中创建和存储的任何数据都将被删除。这是运行 docker 容器的好处之一,因为我们不需要“清理”它们,不需要卸载服务,也不需要删除文件。然而,这也意味着我们在容器运行时实现的任何更改将在我们停止它后永远丢失。

为了持久化对托管服务的更改(比如 NiFi 数据管道或 Airflow DAGs),我们需要将必要的数据保存在本地机器上的容器之外。我们可以通过使用绑定装载或卷来实现这一点。

绑定坐骑有特定的路径来源,一个例子是./airflow/dags:/usr/local/airflow/dags。compose 文件旁边的本地目录./airflow/dags将被绑定到容器内的文件夹中。我们可以很容易地在我们的项目目录中访问它,并添加/删除数据和文件。绑定挂载是特定于主机系统的,并且不受 Docker 的管理。我们可以将挂载目录绑定到系统中的任何地方,因为我们可以通过它在系统中的完整路径来引用它。

命名卷不包含路径。一个例子是airflow-data:/usr/local/airflow/data。卷airflow-data也需要在顶层volumes声明的合成文件中声明。 Docker 管理卷,意味着非 Docker 进程不应修改卷。您可以使用docker volume ls列出所有命名的卷。

两者之间的一个主要区别是它们在第一次启动时的处理方式。举个例子:当绑定挂载一个像 NiFi 的conf目录这样的目录时,docker 希望某些文件在启动时存在于挂载的目录中。如果没有,Docker 将失败。另一方面,如果您使用conf作为命名卷,docker 将会意识到它还不存在(或者是空的),并在启动时创建默认文件,而不会抛出错误。

在下面的例子中,docker 容器在/usr/local/airflow/dags目录(容器内部)中创建的任何数据都将存储在本地机器上我们项目目录中的./airflow/dags处。在冒号的左边,我们指定我们挂载的本地目录,在右边指定 docker 容器内的映射目录。

如您所见,我们还可以挂载单个文件。在这种情况下,我们挂载一个requirements.txt文件,以便能够在启动时在容器内安装 Python 包。

目录是绑定装载的还是命名卷取决于您需要如何使用它。docker 容器中需要持久化但不需要手动访问的目录应该总是由 docker 管理,因此是命名的卷。另一方面,如果你需要添加/删除/编辑目录中的文件和数据,选择应该落在绑定挂载上。有关更多信息和每个选项的不同使用案例,请查阅官方文档。

端口转发

当您使用 docker 运行一个容器时,它的任何端口都不能从“外部”,从您的本地主机访问。Docker 容器在它们自己的网络中运行,但是您可以发布端口并使它们可以从本地主机访问。下面的代码摘录将容器服务的内部标准 http 端口8080映射到本地主机的端口8085

这意味着,当您访问localhost:8085时,您实际上是在调用 docker 容器的8080端口。这样,我们可以托管多个 docker 容器应用程序,并将它们的 http 端口映射到不同的外部本地主机端口。

用户定义的网络和网桥

用户定义的网桥在容器之间提供自动 DNS 解析,这意味着一个容器将能够与 docker 容器的同一个网络中的其他容器“对话”。

默认情况下,从docker-compose.yml创建的每个容器都加入同一个网络。然而,默认桥接网络上的容器只能通过 IP 地址相互访问,除非您使用-link 选项(这被认为是遗留的)。

在一个用户定义的桥接网络上(就像我们的例子中的dataworld),容器可以通过名称或别名相互解析。这非常实用,因为我们不必手动查找和配置特定的 IP 地址。

当您考虑到每当我们重启 docker 容器时,IP 地址也会发生变化,这就变得特别好了。我们可以让 docker 网络处理 DNS 名称解析,而不是在每次启动后都重新查找我们的 IP 和配置服务连接。

主机名和容器名

为了能够通过名称进行实际解析,我们的 docker 服务需要一个hostname。这些名称将用于解析dataworld网络中的实际 IP 地址——例如,当我们通过 API [http://mynifi:8080/nifi-api/...](http://mynifi:8080/nifi-api/....) 从 Airflow 向 NiFi 发出 API 调用时。

我们可以另外配置container_name——如果我们不这样做,docker-compose 将根据服务名和合成文件的目录分配一个。例如,如果我们没有定义服务的容器名airflow-webserver,docker 会给容器命名为data_world_1_airflow-webserver

一旦我们有多个容器在运行,并且需要区分它们时,具体命名容器是很有帮助的(与在任何其他代码段中命名变量一样)。这些名称也为 docker 提供了一个参考点,允许它引用其他容器( Source )。

一般来说,容器或者通过名称(因此,不允许有重复的名称)或者通过 ID 来识别。以下两个语句适用于同一个容器:

当创建容器后在命令行中运行docker ps --all时,您可以在最后一列中看到名称。

稍后快速浏览一下docker-compose.yml中的相关主机名:

  • 尼菲:mynifi
  • NiFi 注册表:myregistry
  • 气流:myairflow
  • PostgreSQL-DB: mypostgres
  • pgAdmin: mypgadmin
  • 动物园管理员:myzookeeper
  • 米尼奥:myminio

环境变量

Docker compose 将在 shell 中查找环境变量,并替换我们在docker-compose.yml中指定的值。一般来说,docker-compose 中的环境变量帮助我们配置服务的某些部分,以便它们与我们的设置特别匹配。

Airflow 服务不使用任何环境变量,但是 NiFi 使用:例如,我们可以手动将NIFI_ZK_CONNECT_STRING设置为myzookeeper:2181,这样 NiFi 将在启动时自动识别 zookeeper 实例。由于我们创建了一个用户定义的网络,我们可以让 docker 处理名称解析,只使用容器名称而不是 IP 地址。

更多模糊的例子可以在上面看到,如设置一个属性键或在领导者选举周期中的最大等待时间。但是另一个容易理解的例子是 postgres 容器服务,其中我们利用环境变量来指定默认的用户名和密码。

重启策略

每当遇到不是0的退出代码时,策略on-failure将重启容器。当我们手动终止进程时,使用退出代码0,在这种情况下,我们不希望容器重启。在应用程序或 docker 容器的所有其他退出代码上,docker 将尝试为我们自动重启容器。

重启策略的其他选项有noalwaysunless-stopped。如果你对确切的定义感兴趣,可以看看官方文档。

健康检查

健康检查就是检查我们的 docker 容器是否“健康”。在这个上下文中,健康通常意味着它们能够响应 http 请求。Docker 评估返回的 HTTP 代码来决定容器是否健康。

docker 集装箱的健康状态—图片由作者创建。

当我们不指定健康检查时,docker 也无法判断容器是否“健康”。我们的docker-compose.yml中的健康检查非常简单,但是也可以编写更加增强和更加敏感的定制健康检查。

一般来说,我们可以使用任何端点进行基本的健康检查,在正常操作期间返回任何类型的数据——自己检查一下在合成文件中使用的健康检查。

上面的健康检查定义了每 30 秒,命令curl -f http://myairflow:8080/admin/应该被执行。将评估响应的 HTTP 代码,以测试容器是否健康。如果没有响应,将在 20 秒后触发呼叫超时。

在这个上下文中值得注意的是:curl命令是从 docker 网络内部执行的,因此我们需要使用主机名以及容器的原始端口,而不是映射端口!一些服务还为健康检查提供特定的端点,比如mypgadmin:80/misc/pingmyminio:9000/minio/health/live或者甚至是特殊的功能,比如 postgreSQL 数据库的pg_isready命令。

访问服务

在你开始你的容器后

并且您的容器已经启动并运行,您将能够通过以下网站链接访问容器服务:

  • Apache NiFi—http://localhost:8091/NiFi/
  • Apache NiFi 注册表—http://localhost:18080/NiFi-Registry/
  • 阿帕奇气流—http://localhost:8085/admin/
  • pg admin—http://localhost:5050/browser/
  • minIO—http://localhost:9000/

注意:我们不需要直接访问 postgreSQL 和 Zookeeper。如果你感兴趣的话,动物园管理员有一个网络界面。

请注意,一些容器需要一些时间来启动:NiFi 经历一个领导者选举周期(如果您将扩展并将其作为一个节点集群来启动),这将需要一分钟来完成。如果您不耐烦,可以通过将它的环境变量NIFI_ELECTION_MAX_WAIT1 min更改为30 sec来减少这个时间。

如果您想移除所有容器,您可以运行docker-compose down。如果标志docker-compose down -v被设置,该命令也将删除卷。

结束语

在本系列的这一部分中

  1. 我们选择了要使用的技术堆栈,
  2. 我们研究了一个docker-compose.yml文件的组成部分
  3. 我们完成了数据工程沙箱的设置,以使我们的基础设施正常运行。

艰难的工作已经完成——在本系列的下一篇文章中,我们将介绍功能并编写几个Hello world!来展示服务之间的通信和交互。

敬请关注我的 Medium 系列文章!我也写一些关于数据工程工具以及软件和个人开发的文章。

一如既往,我们永远学不完。了解有关…的更多信息

  • docker 撰写入门
  • Docker 的重启策略
  • 为什么要给 docker 容器命名
  • Docker 的存储选项—卷、绑定挂载、tmpfs 挂载和命名管道
  • 阿帕奇气流
  • 阿帕奇尼菲
  • Apache NiFi 注册表
  • PostgreSQL
  • pgAdmin
  • MinIO

我希望你在玩沙盒的时候有很多乐趣!

而且,正如承诺的那样,这里的是docker-compose.yml文件:

如何使用 Python 构建数据科学作品集网站

原文:https://towardsdatascience.com/how-to-build-a-data-science-portfolio-website-using-python-79531426fde5?source=collection_archive---------4-----------------------

提高您的 Python 技能,同时构建您自己的数据科学组合网站。

由设计生态学家在 Unsplash 拍摄的照片

作为一名数据科学家,你需要有一个组合网站,帮助你在一个地方展示你的项目和个人资料。你可能已经有了 Github 和 LinkedIn 页面,但不要指望潜在雇主会浏览你所有的代码和帖子来了解你更多。

建立一个作品集网站可以像使用 WordPress 或 GitHub 模板一样简单;然而,自己创建一个网站将有助于您在学习 Python 中的新事物的同时添加更多的定制功能。

虽然建立一个网站通常需要 Python 之外的知识,但我们不需要成为其他编程语言的专家来创建一个作品集网站。这就是为什么我决定做这个指南,向您介绍构建和部署您的数据科学组合网站所需的基本材料。

**Table of Contents** 1\. [Planning the Website](#1b64)
 - [What to include](#2f09)
 - [Get a Custom Domain Name](#4e22)
2\. [How to Build the Website](#b188)
 - [Backends: Flask vs Django](#0d44)
 - [Front End: Bootstrap (+ HTML, CSS, Javascript)](#c39a)
3\. [Deployment](#2aa5)

规划网站

包括什么

在开始写代码来建立你的作品集网站之前,花些时间来计划网站将会有哪些部分。确保你的作品集网站至少有下面列出的部分。

  • 作品集 : 这将是网站最重要的页面。列出迄今为止你完成的最重要的数据科学项目。添加简短描述和源代码链接。如果你已经写了一篇关于这个项目的文章,那么包括链接。
  • 关于我:这个部分将帮助人们了解你的技能、背景和任何与你相关的事情。
  • 联系方式:您应该在这里添加一个表单,以便人们可以填写他们的姓名、电子邮件,并写消息与您联系。除此之外,您还可以将链接添加到您的 GitHub 和 LinkedIn。

如果您完成了许多数据科学项目,并且有很多关于您作为数据科学家的经历要写,则在每个部分创建一个页面,然后添加一个总结其他部分的登录页面。然而,如果你没什么可写的,那么一页纸应该足够包含前面提到的所有部分。

如果有必要,添加更多的部分,使您的投资组合网站脱颖而出。

获取自定义域名

域名是网站的位置。它是用户在浏览器窗口中输入的文本,用来访问一个网站;例如,Google 的域名是google.com

虽然我们还没有建立网站,但至少你应该检查一下你想要的域名的可用性。有很多域名注册商,比如 GoDaddy 和 NameCheap,你可以在那里看到该域名是否可用。

万一域名可用,不要等到建好网站再去买,否则几周或几个月后可能就不再可用了。域名通常很便宜,所以万一出了问题,你不会损失很多钱。

如何建立网站

后端:烧瓶 vs Django

用 Python 构建网站的两个最流行的框架是 Flask 和 Django。Django 是一个高级 Python web 框架,它使开发者能够在没有第三方库和工具的情况下创建网站。相比之下,Flask 是一个微框架,它提供了 web 应用程序的基本功能。它旨在保持其轻量级的简单性和可扩展的使用。

你应该使用哪一种?这在很大程度上取决于你项目的规模。Flask 更适合较小的、不太复杂的应用程序,而 Django 是为较大的、更复杂的、高负载的应用程序设计的。

如果你想创建一个简单的投资组合网站,Flask 可能是最好的选择。它不仅更适合小项目,而且最容易学习。Flask 比 Django 更 Pythonic 化,因为 flask Web 应用程序的代码大多数时候比 Django 代码更显式。这使得 Flask 对于 Python 编码人员来说很容易上手。

也就是说,如果你计划创建一个更复杂的多功能网站,你应该使用 Django。此外,如果你对 web 开发感兴趣,学习 Django 可能更有价值,因为它比 Flask 更受欢迎。下面是我在 Google Trend 上对这两个框架在 5 年内进行的网络搜索比较。

图片来源:谷歌趋势

上图显示 Django 比 Flask 更受欢迎。也就是说,学习这些框架将帮助您提高 Python 技能。在这篇文章中,你可以阅读到这两个框架的更深入的比较。

YouTube 上有很多免费的 Django 和 Flask 课程。我亲自观看了这个完整的 Django 系列,从中你可以学习如何构建一个博客应用程序。在同一频道还有一个烧瓶系列。在学会基础知识后,我尝试的另一个项目是这个 Django 电子商务网站。完成这些课程后,你可以查看这个视频教程,它展示了一个非常基本的投资组合简历网站的介绍,因此你可以获得一些灵感,并开始建立自己的网站。

前端:引导(+ HTML,CSS,Javascript)

到目前为止,我们已经成功地建立了网站的骨架,但要使网站好看,我们需要使用其他工具。

Web 开发人员需要相当多的 HTML、CSS 和 Javascript 知识来创建一个网站;然而,如果我们的目标是创建一个基本的数据科学组合网站,我们可以使用 Bootstrap 节省几周时间来学习这些编程语言。

Bootstrap 是 HTML、CSS 和 JavaScript 工具的集合,用于创建和构建网页和 web 应用程序。使用 Bootstrap,我们可以专注于开发工作,而不用担心设计,并快速创建一个好看的网站。最重要的是,Bootstrap 是手机友好的,所以网站在手机上看起来仍然不错

这太棒了!多亏了 Bootstrap,我们不需要成为 JavaScript 或 CSS 方面的专家来让你的网站看起来更好(尽管我们仍然需要知道至少一些基础知识)。下面你可以找到一些基本的 Bootstrap 模板,你可以用在你的网站上。

  • 入门模板
  • 导航标题

确保你遵循我之前提到的 Django/Flask 免费课程。在那里,您将发现何时以及如何在您的代码中实现这些引导模板。

注意:正如我之前提到的,你至少应该了解 HTML、CSS 和 JavaScript 代码的基础知识。根据我的经验,HTML 的使用频率更高,所以可以考虑查看这个 免费 HTML 课程

部署

到目前为止,我们建立的网站只能在我们的本地机器上访问。很自然,我们想让所有能上网的人都能访问我们的网站,所以我们将使用 Heroku 来解决这个问题。

Heroku 是一个平台,允许我们轻松地部署和托管应用程序,而不需要我们自己手动设置一切。要使用 Heroku,你必须先创建一个账户。在这之后,你需要做一些事情来设置 Heroku。这个过程可能需要几分钟,所以请查看这个视频教程,一步一步地学习如何用 Heroku 部署您的 web 应用程序。

注意:虽然你可以用 Heroku 免费主持一个项目,但是如果 30 分钟内没有网站流量,他们会让你的网站进入睡眠状态。如果有人访问您的网站,它会在短暂的延迟后变得活跃。要避免这种行为,可以升级到 Heroku 的爱好计划。

就是这样!现在,您已经很好地了解了如何使用 Python 构建一个基本的数据科学组合网站。有了这个,你将能够定制你的网站,并学习我们用于数据科学的普通 Python 材料之外的东西。

与 3k 以上的人一起加入我的电子邮件列表,获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)

如何搭建数据和技术基础实现跨越

原文:https://towardsdatascience.com/how-to-build-a-data-technology-foundation-to-leapfrog-368f354abf3e?source=collection_archive---------15-----------------------

每当商业机会出现时,学会利用数据并迅速将其货币化。

图片来自 [Pixabay](http:// from ) (CC0)

我在数据库技术蓬勃发展的时候开始了我的职业生涯。甲骨文和赛贝斯 RDBM 是主流中的顶尖软件;随着市场上出现全新的在线分析处理(OLAP)和 ETL(例如,提取、转换和加载)工具,数据仓库刚刚开始出现。在那段时间,我们的工作很简单:开发、操作,然后维护。

今天,当您走进一个拥有十年或十年以上 IT 历史的成熟组织时,您会看到复杂的数据系统和迁移的困难。虽然数据和分析已经成为业务数字化的中心,但公司利用数据并实现其价值的速度越快,它获得的竞争优势就越大。实现这一目标需要新技术、新平台和新方法。特别是,一个可扩展的解决方案来跟上不断增长的数据量是一家大型公司的首要计划之一。然而,遗留系统不可能很快被取代。通常一个已建立的遗留系统需要数年时间才能被替换。IT 资源在维护现有系统的常规业务和创新与转型的持续需求之间捉襟见肘,因此出现了迁移浪潮。

一个组织的数据和分析路线图通常有 4 个阶段:首先是构建坚实的基础,然后是自动化和运营化;下一步是跟上业务需求,最后是将 it 转化为新的业务增长机会。问题是没有时间首先建立基金会,然后将其货币化,因为基金会的工作需要很长时间才能完成,而且似乎永无止境。沮丧的业务利益相关者不得不等到重大迁移完成,这可能需要几年时间。更糟糕的是,经过多年的努力,结果往往达不到预期。

许多人将技术债务和遗留系统比作徒步旅行者的背包。“背包”越轻,从长远来看,组织就能越快、越成功地完成技术之旅。这怎么可能,因为在过去十年中,遗留系统曾经是推动业务增长的引擎。这是可能的,但并不容易。下面总结了一个组织可以做的四个关键领域,以确保一个更轻的“背包”来利用数据,并在业务机会出现时快速将其货币化。

  1. 快速设计和实施,但要牢记长期目标

不管是采用敏捷还是开发 3 个月的 MVP,如果你是将来将新系统迁移到新平台的人,你还会做同样的事情还是用不同的方式?每个人都应该问自己这个问题,包括架构师、经理、数据工程师和开发人员。现代技术发展越来越快,各种供应商提供了许多选择。软件或工具可能在短短几年内变得无关紧要或可替代。迁移或改用新工具已经成为常态,而不是例外。

记住这一点,团队应该从一开始就记录每一个需求和业务规则,编写带有注释的好代码,最重要的是,设计一些简单且易于维护的东西,以便将来可以顺利迁移。在管理方面,值得集思广益和深思熟虑来设计整个组织的正确架构,并从一开始就避免部门孤岛。

虽然从产品的角度来看,使用敏捷方法开发 MVP 是可行的,但是我们仍然应该从长远的角度来设计和开发,以便从一开始就进行扩展。它包括小步骤和日常纪律,例如:

  • 建立并遵循标准命名约定、标准文件夹结构
  • 从头开始为事务表构建分区
  • 设计架构和基础设施时考虑未来的增长和容量
  • 建立流程和操作以确保未来的成功。

我们经常听说一个项目是在没有连贯的设计或标准的情况下仓促启动的。它可能会实现短期目标,但从长远来看却不能自我维持。令每个人沮丧的是,我们经常在三个月后发现改变为时已晚,因为这将需要额外的资源和努力——这就是技术债务是如何建立和积累的。为了避免技术债务,整个团队需要遵守纪律,并遵循他们所走的每一步标准。如果没有标准,那就创造一个,从长远来看会买下所有人。

2。因业务需求而创新,但不是为了追逐新技术

我们经常听到人们说他们需要建立一个新的系统来应用最新的技术,这可能是原因之一,但它应该不是主要原因。这项新技术可以提供更多的功能、更快的性能或可扩展的解决方案,但它不是灵丹妙药。许多新技术承诺的比他们目前能提供的更多。因此,评估每一项新工具或技术、进行概念验证、培训和学习、体验并最终构建一个成熟的解决方案都需要时间和精力。我们处在一个技术和工具发展越来越快的时代。当我们跳到一项新技术上时,另一项新技术很快就会出现。当我们最终在一项技术上成熟时,我们已经晚了另一个新浪潮也就不足为奇了。

众所周知,对于数据平台来说,重新设计成本高昂,成功率很低。数据库系统给了开发者和用户极大的灵活性,只要他们有权限,就可以做他们想做的任何事情。可以快速创建新的表或列;存储过程可以在几分钟或几小时内编写完成。所有这些对象都可以独立存在,不依赖于其他对象。随着时间的推移,许多对象变得过时,没有明确的所有者,业务逻辑被埋在许多脚本中。当新的资源加入进来以重新设计系统时,如果不理解数据和业务逻辑,他们就不能移动。这就是为什么重新设计或迁移整个数据仓库需要很长时间的原因。

考虑到这些因素,总是从真实的业务用例和计划开始新技术。在新技术通过审查并且组织的技能集和经验建立并成熟之后,计划使用分阶段的方法迁移遗留组件。赶上新浪潮永远不会太晚。最好的策略是保持现有平台的稳固,但要准备好迎接新的商机。换句话说,不要让业务等待;相反,从小处着手,使用新技术快速实施,以解决业务问题。

3。重塑应该成为常态,一切照旧

在过去的十年中,许多组织成功地构建了一个可扩展的系统。问题是,通过不断的增强,它一直保持着相同的架构。因为资源非常了解这个系统,所以他们会不断地用常规的增强来使业务需求适应当前的架构。对当前架构的不断增强和修补是积累技术债务的另一种方式。人们试图将新的业务需求融入到现有的架构中,而不是构建一个新的架构来更好地满足需求,并且从长远来看可以加速它。

相反,在我们有一个成熟的系统在生产中运行后,我们应该立即开始考虑更适合业务增长的下一代平台。换句话说,不要在十年后进行最后的大规模迁移,而是在 2-3 年内进行增量迁移。虽然在短期内可能需要付出更多努力,但好处是多方面的:

  • 它迫使整体架构以模块化和解耦的方式设计。
  • 通过正确的设计更多地关注业务需求,而不是通过其他方式将业务需求融入当前架构。
  • 通过增量创新不断提高资源的技能和经验
  • 避免需要大量预算的大规模迁移
  • 业务涉众不需要等待新基础的建立。

以上所有的好处都和某个特定的技术无关。它是一种组织战略,是管理 It 预算、资源和规划的方式。然而,对于一个公司来说,保持领先地位以获得并保持其竞争优势是非常重要的。有了这个策略,再创造和基础工作之间不应该有界限,再创造应该变成“照常营业”迁移变得越来越小,越来越增量,并且在微观尺度上执行。因此,企业不需要等待构建基础或进行多年迁移来实现业务增长。

4。为合适的工作培养和利用合适的人才

我们经常观察到,一家公司需要从外部招聘,以启动从当前遗留系统的大迁移,并引入具有创新经验和技能的新人才。那些在过去十年中为最初的创新做出贡献并建立了最新技术的人一直坚持使用当前的系统来不断增强和维护它。他们的日常工作从最初令人兴奋的设计和开发变成了重复但高效的增强和操作工作。

如果我们不断根据业务需求进行再发明,这些人才将会不断学习和积累新的技能和经验。这对公司来说是一笔极好的投资,因为这些有经验的人对业务逻辑了如指掌,并且能够比公司的新人更快地创造出新的解决方案。不断的创新也带来了不断学习和改进的新文化。也就是说,一个组织应该从一开始就确定合适的人才类型。某些人才非常擅长新的想法和承担风险,而其他人则擅长通过建立标准和流程来完善系统。这两者对于组织的 IT 和数据战略的成功同样重要,并且应该因为他们的成就而得到认可。

结论

在 20 世纪 90 年代,微处理器公司英特尔因每两年重新发明和更换一代芯片以赶上摩尔定律而闻名。因此,当时没有人能超越其市场第一的位置。对于 IT 和数据组织,我们也应该采取“英特尔”的方法,不断创新。随着当今技术领域的快速发展,企业不能等待 it 部门花多年时间来构建基础。每当业务需求或机会出现时,就应该设计、增强和构建基础。预先创建基础工作的传统方式已经过时了。创新是基础工作的一部分,所有的基础都可以逐步扩展或替换。这将要求一个组织的战略、预算规划和资源管理发生重大转变。它还需要高度组织化和纪律性的团队,他们建立并遵循标准的每一步。最终,它会带来文化变革,培养基于业务需求的不断学习和创新,从而推动业务增长。

如何使用 Python 构建数据库

原文:https://towardsdatascience.com/how-to-build-a-database-using-python-f4b62a19d190?source=collection_archive---------5-----------------------

使用 Flask-SQLAlchemy 库实现您的数据库,而不处理 SQL

泰勒·维克在 Unsplash 上的照片

介绍

SQLAlchemy 是一个 Python 库,用于实现 SQL 数据库,而不使用 SQL 语言本身。换句话说,您需要做的就是使用 Python 语言实现您的数据库。

SQLAlchemy 是一个用于连接 Flask 项目中的 SQLAlchemy 库的库,它使您的数据库实现比以往任何时候都更容易。本文将向您展示如何使用 Flask-SQLAlchemy 库构建您的数据库。

没有进一步,让我们开始吧!

数据库ˌ资料库

在我们开始实现之前,让我向您解释一下数据库。什么是数据库?数据库是相互集成的数据集合,我们可以使用我们的计算机访问它。

在数据科学中,您可能会以电子表格的形式插入和分析数据。在软件开发领域,就有点不一样了。让我们来看看这个电子表格。

该图像由作者捕获。

在电子表格中,我们可以看到有两列。有书名和作者的名字。如果您查看 author 列,您会看到有些值重复了几次。这种情况我们称之为冗余。

将整个数据集用作一个表并不是最佳做法,尤其是对于那些想要构建网站或应用程序的人。相反,我们必须分离表,我们称之为规范化。

总之,规范化过程会将数据集分成几个表,每个表都包含唯一的标识符。我们将把每个标识符称为主键。如果我们分离上面的数据集,我们将得到如下所示的数据集:

该图像由作者捕获。

从上面可以看到,数据集已经被分成两个表。有图书表和作者表。作者的名字在作者表上。因此,我们不能像在电子表格中那样直接访问名称。

为了检索作者的名字,我们必须通过从 author 表中获取 id 来连接 Book 表和 Author 表。我们将作者的 id 作为 Book 表的外键。

也许这很复杂,但是如果你开始实现一个构建应用程序的数据库,它将提高你的应用程序的性能。

履行

安装库

在我们开始实现之前,我们需要做的第一件事是在我们的计算机中安装这个库。要安装它,我们可以使用 pip 来完成。以下是安装库的语法:

要加载库,我们可以调用下面的语法:

正如您从库的名称中所知道的,我们还需要加载 Flask 库。

启动数据库引擎

加载库之后,下一步是设置 SQLAlchemy 对象和数据库的路径。默认情况下,SQLAlchemy 附带 SQLite 软件。

SQLite 是一个数据库管理系统,我们可以在其中建立和分析我们已经建立的数据库。您可以使用其他 DBMS,如 MySQL、PostgreSQL 或您喜欢的任何 DBMS。要设置我们的数据库,请添加以下代码行:

这段代码将初始化 Flask 和 SQLAlchemy 对象,我们设置一个包含数据库路径的参数。在这种情况下,数据库路径是 SQLite:///C:\ \ SQLite \ \ library . db。

实现数据库

设置好对象和参数后,我们就可以开始实现数据库了。让我们回忆一下上面的数据库表:

该图像由作者捕获。

从上面可以看到,上面有两张桌子。每个表都有自己的类,我们可以在其中初始化列名和表之间的关系。我们将继承一个名为 Model 的类来实现我们的表。根据上图,代码如下所示:

插入值

创建类之后,我们可以构建数据库。要构建数据库,您可以访问终端并运行以下命令:

现在让我们尝试在我们的表上插入值。对于这个例子,让我们输入上面的电子表格中的数据。您可以按照下面的代码插入值:

查询该表

在表中插入值后,现在让我们运行查询来查看数据是否存在。下面是实现这一点的代码:

从上面可以看出,我们的提交是成功的。好吧,这仍然是一个介绍,但我希望你能掌握这个概念,并在一个更大的项目上实施它。

附加:SQL 查询

除了 Flask-SQLAlchemy 库之外,我还将向您演示如何使用本地 SQLite 访问数据库。我们这样做是为了确保已经在上面创建了数据库。要访问 SQLite,您可以打开终端并编写以下脚本:

**sqlite3**

之后,它会这样显示 SQLite 的界面:

该图像由作者捕获。

在下一步中,您可以使用。打开命令,将路径添加到数据库,如下所示:

**.open absolute//path//to//your//database.db**

为了确保我们已经打开了数据库,请写信。终端上的表格是这样的:

**.tables**

它会产生这样的结果:

该图像由作者捕获。

很好,有用。现在让我们尝试使用 SQL 语言来查询我们的数据库:

**SELECT * FROM books**

这是结果:

该图像由作者捕获。

现在让我们试着将两个表合二为一。您可以在终端上编写这行代码:

**SELECT Book.title, Author.name FROM Book
INNER JOIN Author ON Book.author_id = Author.id;**

这是结果:

该图像由作者捕获。

结束语

干得好!现在,您已经使用 Flask-SQLAlchemy 库实现了您的数据库。我希望这篇文章能帮助你在项目中实现数据库,尤其是当你想用 Flask 构建一个 web 应用程序的时候。

如果你对我的文章感兴趣,你可以在媒体上关注我,或者订阅我的时事通讯。还有,如果你有什么问题或者只是想打个招呼,你可以在 LinkedIn 上关注我。

谢谢你看我的文章!

如何使用 Python tweepy 从 Twitter 构建数据集

原文:https://towardsdatascience.com/how-to-build-a-dataset-from-twitter-using-python-tweepy-861bdbc16fa5?source=collection_archive---------6-----------------------

数据收集

一个快速教程和一个现成的脚本来提取推文

图片来自 Pixabay 的照片混合

在本教程中,我解释了一个使用tweepy Python 库从 Twitter 提取数据的非常简单的过程。代码可以从我的 Github 库下载。

具体来说,我将实现一个策略,用#新冠肺炎标签提取前一天的推文,并实现每日提取的自动化。

您可以修改这段代码来提取其他标签。输出数据集如下所示:

作者图片

它包含文本、推文的收藏计数、转发次数和创建日期。

该软件的体系结构由以下元素组成,如下图所示:

  • Twitter 应用程序
  • 获取推文
  • Cron 作业(配置为 crontab)

作者图片

Twitter 应用程序

首先,我需要在 Twitter 开发者网站上注册一名 Twitter 开发者。如果我有一个 Twitter 账户,我可以使用它。我应该单击“Apply ”,然后按照向导进行操作。创建我的 Twitter 开发人员档案后,我可以进入 Twitter 仪表盘并选择项目和应用:

作者图片

我创建了一个新应用程序:

作者图片

我跟随巫师。在向导结束时,我将提供的秘密注册在一个单独的文件中,名为config.py。该文件应该如下所示:

TWITTER_CONSUMER_KEY = 'PUT HERE YOUR API KEY'TWITTER_CONSUMER_SECRET = 'PUT HERE YOUR API SECRET'

向导结束时,新应用程序会出现在左侧的“项目和应用程序”标题下

作者图片

我点击新应用程序,然后点击关键符号:

作者图片

然后我生成访问令牌和密码,并将它们注册到config.py文件中。

TWITTER_ACCESS_TOKEN = 'PUT HERE YOUR ACCESS TOKEN'TWITTER_ACCESS_TOKEN_SECRET = 'PUT HERE YOUR SECRET TOKEN'

获取推文

我可以将 Get Tweet 脚本实现为 jupyter 笔记本,然后我可以将其下载为 Python 脚本。

这个脚本提取了与前天(昨天)相关的带有#新冠肺炎标签的所有推文,并将它们保存到一个. csv 文件中。我用的是tweepy库,可以用pip install tweepy命令安装。

首先,我导入名为config.py的配置文件,它必须位于这个脚本的同一个目录中。

from config import *
import tweepy
import datetime

我通过使用OAuthHandler()类和它的access_token()函数建立了到我们 Twitter 应用程序的连接。然后我通过API()函数调用 Twitter API。

auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
auth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET)
api = tweepy.API(auth,wait_on_rate_limit=True)

现在我安排约会。我需要设置今天和昨天。

today = datetime.date.today()
yesterday= today - datetime.timedelta(days=1)

我使用Cursor()功能在 Twitter 上搜索推文。我将参数api.search和查询字符串传递给游标,查询字符串是通过游标的参数q指定的。查询字符串可以接收许多参数,例如以下(非强制)参数:

  • from: -指定特定的 Twitter 用户资料
  • since: -指定搜索的开始日期
  • until: -为了指定搜索的结束日期,光标还可以接收其他参数,如语言和tweet_mode。如果tweet_mode='extended',则返回 tweet 的所有文本,否则只返回前 140 个字符。
tweets_list = tweepy.Cursor(api.search, q="#Covid-19 since:" + str(yesterday)+ " until:" + str(today),tweet_mode='extended', lang='it').items()

现在我循环遍历tweets_list,对于每条推文,我提取文本、创建日期、转发次数和收藏数。我将每条推文存储在一个名为output的列表中。

output = []
for tweet in tweets_list:
    text = tweet._json["full_text"]
    print(text)
    favourite_count = tweet.favorite_count
    retweet_count = tweet.retweet_count
    created_at = tweet.created_at

    line = {'text' : text, 'favourite_count' : favourite_count, 'retweet_count' : retweet_count, 'created_at' : created_at}
    output.append(line)

最后,我将output列表转换为pandas DataFrame列表,并存储结果。第一次运行这个脚本时,我使用了没有任何其他参数的to_csv()函数。从第二次开始,我应该添加以下参数:df.to_csv(‘output.csv’, mode=’a’, header=False),以便将结果追加到先前存储的输出中,并避免重写头。

import pandas as pddf = pd.DataFrame(output)
df.to_csv('output.csv')

现在,我可以通过在 jupyter 中选择相应的菜单来下载 Python 代码作为.py 脚本。

作者图片

Cron 作业

cron 作业是调度一些重复性操作的一种方式。在这个例子中,cron 作业用于每天下载前一天的 tweets。
它要求运行 cron 作业的机器在将要运行 cron 作业时打开。

如果您有一台 Linux/Mac OS 计算机,您可以按照以下过程来配置 cron 作业:

  • 打开终端并键入crontab -e
    该命令打开一个文本编辑器来插入、修改或删除一个任务
  • 每个任务必须包含执行的时间和日期。顺序是分钟、小时、一月中的某一天、一月、一周中的某一天。您可以使用*来表示所有值

  • 00 01 * * * python /<path_to_file>/get_tweets.py
    插入新的一行。这将在每天凌晨一点运行脚本一次。

如果你有一台 Windows 10 机器,你可以按照这篇文章.&text=This%20will%20open%20a%20window,Server%202016%20or%20Windows%2010.)中描述的步骤来配置 cron 作业。

现在 Twitter 提取器已经准备好了!好好享受吧:)

摘要

在本教程中,我演示了如何通过 Python tweepy提取 tweets。这个过程需要三个步骤:Twitter 应用程序设置、代码编写和 cronjob 设置。

当您想要提取多个 hashtag 时,也可以使用所描述的机制。您可以简单地在查询字符串中添加您想要的所有标签。

如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。

相关文章

https://medium.com/analytics-vidhya/how-to-extract-multiple-tables-from-a-pdf-through-python-and-tabula-py-6f642a9ee673 https://alod83.medium.com/how-to-extract-data-from-a-search-engine-through-python-and-selenium-35dfe6b20db https://betterhumans.pub/6-tips-for-extending-your-knowledge-with-twitter-af2bc8c16bdb

保持联系!

  • 在媒体上跟随我
  • 注册我的简讯
  • 在 LinkedIn 上连接
  • 在推特上关注我
  • 跟着我一起去脸书
  • 在 Github 上关注我

如何建立一个分散的数据平台

原文:https://towardsdatascience.com/how-to-build-a-decentralized-data-platform-58158db6409b?source=collection_archive---------16-----------------------

一个数据工程团队通过端到端数据信任平衡自助服务平台需求的方法。

图片由 Unsplash 上的 Max 提供。

数据平台 让数据变得比以往任何时候都更容易访问和操作——假设你可以信任它。下面是 Auto Trader 的数据工程团队如何构建一个兼顾分散数据所有权和可靠性的数据平台。

总部位于曼彻斯特的 汽车交易商 是英国和爱尔兰最大的数字汽车市场。对于汽车交易商来说,将数百万买家与数千卖家联系起来需要大量数据。

该公司每月有 2.35 亿次广告观看和 5000 万次跨平台访问,每分钟有数千次交互,汽车交易团队可以分析和利用所有数据点来提高效率、客户体验,并最终提高收入。从广告优化到报告,再到 ML 动力汽车估价,数据也为业务成果提供动力。

对于首席开发者 Edward Kent 和他的数据工程团队来说,收集和处理如此大量的数据绝非易事。最近,数据团队一直专注于两项关键任务。

“我们希望让汽车交易商及其客户能够做出基于数据的决策,”Edward 说,“并通过自助服务平台实现数据访问的民主化。”

这些雄心勃勃的目标与向基于云的现代数据架构的迁移不谋而合,这意味着 Edward 和他的团队必须同时让更多团队更容易访问数据,同时建立对数据质量的信任。毫无疑问,这是一个不小的成就。

挑战:建立信任和支持自助数据

“随着我们将可信的内部系统迁移到云,这些旧系统的用户需要相信新的基于云的技术与他们过去使用的旧系统一样可靠,”Edward 说。

如今,Edward 和他的团队拥有强大的数据堆栈。他们通过 Kafka 和 Fivetran 接收数据,在 Apache Airflow 中处理编排和调度,在 BigQuery 和亚马逊 S3 中存储数据,使用 dbt 和 Apache Spark 进行建模,使用 Databricks 进行数据科学记事本,并通过 Looker 向内部消费者提供表面数据。

这些数据吸引了很多眼球。超过 500 名活跃用户(超过所有汽车交易商员工的 50%!)每个月都会登录并使用 Looker 中的数据,包括财务报告等复杂、备受瞩目的数据产品。当然,随着海量数据和多层技术堆栈的出现,数据管道出现故障的机会也越来越多,而这些事件几乎总是由 500 个数据消费者中的一个首先注意到。

Edward 和他的团队需要解决 数据宕机 (他们的数据不完整、错误或不准确的时间段)以提高信任度,但与此同时,这也成为了公司其他部门的瓶颈。他们的数据工程师集中团队处理与数据运营相关的一切事务,从构建新管道和报告的请求,到调查数据质量问题的紧急电话。这种方法无法扩展,并导致请求积压,这促使 Edward 和他的团队制定了一项计划,为企业消费者构建一个抽象的自助式平台,供他们自己使用。

“我们不希望让一个数据团队做所有的事情,而是希望给团队平台级的能力和自主权来构建他们自己的数据产品,”Edward 说。“理想情况下,我们希望让团队管理数据管道生命周期中的一切。所以从摄取到建模到报警,等等。因此,在这种背景下,我们希望将数据可观察性作为一种平台功能来提供。”

解决方案:分散数据所有权

图片由爱德华·肯特提供。

为了实现数据信任和分散数据责任,Auto Trader 希望在 BigQuery 和 Looker 之上添加一个监控、警报和沿袭层,big query 和 Looker 是其数据堆栈中可见性最高的层。

“对我们来说,现在比以往任何时候都更重要的是,我们提供的数据是正确、准确和最新的,”Edward 说。

Auto Trader 使用自动化数据可观察性对 BigQuery 中的所有表执行容量和新鲜度检查,以及模式更改警报。Edward 的团队还在几十个关键表中选择了一套 ML 驱动的统计检查,从而轻松获得列级置信度,而无需定义阈值的繁琐过程。这种方法还帮助他们了解了数据中的所有依赖关系。

“我们发现很难理解 BigQuery 中的哪些表出现在 Looker 的哪些报告中,反之亦然,”Edward 说。“跨这两个系统的自动血统跟踪对我们来说非常强大。”

结果:建立信任的事件跟踪

在迁移到云之前,当内部消费者向他们发送关于看起来不太正确的 Looker 报告的松散消息时,数据工程团队会发现数据质量问题。

图片由爱德华·肯特提供。

然后,数据团队必须 a)调查是否存在真正的问题;b)尝试确定 的根本原因;c)找出哪些表或仪表板在下游,哪些消费者会受到影响;d)最后,跟踪并通知相关的利益相关方,告知他们发现了问题,估计问题何时会得到解决,并在问题解决后再次跟进。

爱德华将这一过程描述为“被动的、缓慢的、不可扩展的”

现在,当检测到可能的事件时,Edward 的团队会收到延迟通知。

图片由爱德华·肯特提供。

由于自动化的端到端沿袭,他们可以更快地调查问题,这有助于数据工程师了解可能的上游和下游影响,直到现场级别,并提供对新鲜度、量和分布变化的可见性,这有助于他们查看更新模式并注意可疑的变化。

图片由爱德华·肯特提供。

沟通也是精简的。Edward 的团队不需要追踪利益相关者——再次使用沿袭——并且可以向相关团队的 Slack 通道发送关于问题和解决方案的通知。

图片由爱德华·肯特提供。

随着自动化监控和警报的实施,以及 lineage 加快了事件解决的速度,数据工程团队通过在下游消费者发现问题之前主动解决数据问题,与利益相关方建立了更大的信任。

结果:可扩展的监控和对“未知的未知”的可见性

Edward 还将机器学习动力监控归功于他们的分散式方法。

“为了开始获得价值,我们不需要知道我们需要监控什么,”Edward 说。“我们的 ML 可以开始寻找模式,并提醒我们任何异常和偏离这些模式的情况。”

图片由巴尔·摩西提供。

例如,他们的数据可观察性平台在一个很少删除的表中发现了 150,000 行的意外删除。一名数据工程师能够深入到 UI 中,并注意到一个通常只看到添加的表被删除了。使用沿袭跟踪,他们可以查看数据的上游是什么,看到它是通过 ETL 从外部来源进入的,然后去与数据所有者核实,看看这是否合法和有意的,或者是否有什么地方出错了。

“在这种情况下,不需要采取任何行动,”爱德华说。“但知道我们的数据正在发生这种事情真的很有价值,因为这给了我们信心,如果真的有问题,我们会以同样的方式发现它。”

数据工程团队使用定制的 SQL 规则和 dbt 进行手动测试,但由于其数据的规模,依赖数据可观察性作为其平台的基石,因此他们可以捕捉“ 未知的未知的 ”。

“无论是自定义 SQL 规则还是 dbt 测试,您都必须进行预先配置,”Edward 说。“你必须事先知道你要监控的是什么,并经历设置它的过程。对我们来说,我们每天都要定义数百个数据模型和构建数百个表。我们想要的是能够有效地启动并运行的东西,而不需要我们付出努力。模式检查、卷检查、新鲜度检查都可以做到这一点。”

成果:增强汽车交易商的自助服务数据平台

图片由爱德华·肯特提供。

这种新方法还支持汽车交易商向分散的自助式数据计划过渡,而不会影响数据质量。

在这种新模式下,分散的警报被发送到适当的团队警报通道。Edward 和他的团队要求将数据所有权和警报与 dbt 中的其他属性一起定义为元数据。yaml 文件,因此拥有特定数据集的产品团队将自动接收到他们自己渠道的警报。

图片由爱德华·肯特提供。

“分散的数据所有权意味着分散的数据质量责任,”Edward 说。“数据可观察性有助于我们提供这种平台能力。”

汽车交易商分散数据所有权的影响

随着汽车交易商寻求在开放访问的同时建立对数据的信任,数据可观察性是确保数据保持准确和可靠的关键。

“我们对数据的了解比以往任何时候都要多得多,”Edward 说。“以前,这些问题中有许多会被数据消费者发现并报告,但现在却被标记出来。从跟踪的角度来看,这种可见性对我们非常重要,因为我们正在向一个分散的数据平台迈进。”

对学习如何构建更可靠的数据平台感兴趣?把手伸向巴尔摩西和其余的 蒙特卡洛团队

特别感谢 Edward Kent 和 Auto Trader 的数据工程团队的其他成员!

如何用 Python 构建数字双胞胎

原文:https://towardsdatascience.com/how-to-build-a-digital-twin-b31058fd5d3e?source=collection_archive---------3-----------------------

思想和理论

锂离子电池数字孪生的 Python 实现

图片由 Pedro Figueras - Pexels 提供。哈维尔·马林插图。

在本教程中,我们将展示如何用 Python 创建一个简单而实用的数字孪生体。锂离子电池将是我们的有形资产。这个数字孪生将使我们能够分析和预测电池行为,它可以集成到任何虚拟资产管理工作流程中。

虚拟系统和数字双胞胎

D 数字双胞胎是工业 4.0 的重要组成部分。其基本原理是在虚拟世界中复制物理资产,以便对其动态进行建模。想象一下,我们在城市水管网的某个地方有一台水泵。水泵消耗能量,并以水流和压力的形式释放出来。术语“复制品”指的是能够模拟这种行为的虚拟对象的创建。

该泵是整个水管网系统的一部分,还有管道、阀门、仪表和其他附件或子系统。这些子系统都是相互联系的。虚拟化系统需要对所有子系统进行同样的操作。之后,我们可以模拟整个系统,包括它的依赖关系。虚拟系统的目标是模拟现实世界,以便引入变更、评估性能或预测该资产或子系统所涉及的场景(例如维护任务)。

如前所述,数字孪生是代表一个子系统的虚拟对象。这个“双胞胎”应该和它的“物理双胞胎”一样对输入变量做出反应。这个虚拟对象必须集成一个模型才能做到这一点。数字双胞胎最重要的特征是一个可以在数字环境中模拟“物理”行为的模型。请记住,当我们说“物理”时,我们指的是任何真实世界的实体(可以是锂离子电池、水泵、人、城市或猫)。任何可以建模的东西都可以被虚拟化(图 1)。

图一。通过模型从物理世界到虚拟世界。图片作者。

ba 电池上锂-i 的数字模型

可充电锂离子电池是一种尖端的电池技术,其电化学依赖于锂离子。除了便携式技术设备之外,这些电池对于电动汽车和配电网络中的能量存储等应用来说也是重要的资产。这些电池最关键的方面是它们的老化成本。经过反复充放电循环后,电池的电池会退化,导致充电容量减少。这种现象一直是开发更持久电池的关键研究领域。它的建模同样也是一个有争议的话题。电池退化对上述技术规划和操作具有重要影响。

电池寿命下降的物理过程相当复杂。近年来,人们提出了一些测量电池寿命损失的半经验锂离子电池退化模型(Chu et al .,2018;Laresgoiti 等人,2015 年)。报废电池通常被描述为只能提供其额定最大容量 80%的电池。使用其中一个经验模型(Chu 等人,2018 年),这种退化可以写成如下:

方程式 1。电池续航时间。

其中𝐿是电池寿命,是初始电池寿命, d 是每单位时间和每循环的线性化退化率(Chu 等人,2018)。该速率可以写成是放电时间- 𝑡、放电循环深度-δ、平均充电循环状态- σ 和电池温度-𝑇𝑐.的函数

方程式 2 。线性化降解速率。

实验数据

我们的模型必须根据我们掌握的信息来预测电池寿命。但是,我们希望将该模型与测量值进行比较,以确定我们的模型的准确性。让我们暂停一会儿。

许多数字双胞胎并不基于精确的物理模型,只使用实验数据集和机器学习算法。这是一种非常酷的做事方法。例如,他们可以使用深度神经网络建立一个模型来捕捉数据的真实动态。然而,为了获得可靠的通用模型,将该模型推广到其他对象需要处理大量样本。另一方面,当处理物理模型时,我们需要较少的数据来获得准确的通用模型。

我们将利用锂离子电池充放电循环的真实数据来构建我们的数字双胞胎。我们将使用美国宇航局艾姆斯预测卓越中心(PCoE)提供的锂离子电池老化数据集。这个数据集对于确定我们的物理模型的准确性和改进它将是有价值的。我们将使用与 5 号电池相关的数据。我们将绘制出“容量”特征与循环次数的关系,并将其与我们的物理模型进行比较。在我们开始之前,我们将用变量𝐿( 电池寿命代替 C ( 电池容量)。等式 1 将被写成如下:

其中,𝐶是电池容量,𝐶_0 是初始电池容量。对于𝑓𝑑,我们使用了以下近似值:

其中,𝑖是充电-放电循环,𝑇𝑐是循环期间在电池中测量的温度,𝑡𝑖是放电时间,𝑘和经验常数的值为 0.13

图二。实验数据与我们的半经验模型的比较。图片作者。

图 2 展示了结果。我们的模型精确地预测了观察值(我们得到平均绝对误差——MAE 为 0.004)。该模型应该收集电池容量行为,其中容量在第一个循环期间缓慢降低,然后在特定点之后加速。这些变化是微妙的,许多工程师利用简单的线性模型来近似这种行为。我们的模型是半经验的,包括各种调整以避免处理 PDEs ( 偏微分方程)。

构建混合数字双胞胎

我们可以用我们的“模型”来直接创建一个数字双胞胎。但是,为了应用机器学习,我们将使用它来改进我们的模型,使用来自 NASA 数据集的实验数据。我们的建议如图 3 所示。

图 3。创造混合数字双胞胎。图片作者。

我们正在使用实验数据改进我们的数学,并使用神经网络改进我们模型的输出。

**#Define inputs and outputs****# input: the simulation capacity**
X_in = (dfb['C. Capacity'])**# output: difference between experimental values and simulation** X_out = (dfb['Capacity']) - (dfb['C. Capacity']) X_in_train, X_in_test, X_out_train, X_out_test = train_test_split(X_in, X_out, test_size=0.33)

我们使用一个非常简单的神经网络:

model = Sequential()
model.add(Dense(64, activation='relu', input_shape=(1,)))
model.add(Dense(32, activation='relu'))
model.add(Dense(1))

编译:

epochs = 100
loss = 'mse'
model.compile(optimizer = SGD(learning_rate=0.001),          
                          loss=loss,
                          metrics=['mae'], **#Mean Absolute Error** )
history = model.fit(X_in_train, 
                    X_out_train, 
                    shuffle=True, 
                    epochs=epochs, 
                    batch_size=20, 
                    validation_data=(X_in_test, X_out_test),
                    verbose=1)

比较的结果:

图 4 。模型结果与实验结果的比较。图片作者。

正如我们在图 4 中看到的,神经网络学习了我们的数学模型和实验结果之间的差异的基本理解。现在我们可以把这种学习加入到我们的数学模型中来改进它:

**# Our digital twin by improving our model with experimental data**
X_twin = X_in + model.predict(X_in).reshape(-1)

仅此而已。我们有我们的数字双胞胎(或混合双胞胎):

  • 我们创造了一个物理模型(或数学模型)
  • 我们将我们的模型与实验数据进行了比较。
  • 通过这种比较,我们能够改进我们的模型。

最后,在我们的虚拟环境中,我们有一个这种电池的“双胞胎”,预计其性能与现实世界中的电池相似。接下来,我们将对比我们的数学模型和数字模型:

图 5 :数学模型与“混合”数字孪生的最终比较。图片作者。

图 5 显示了我们的数字孪生兄弟如何适度地改进了我们的模型。混合数字孪生的好处是,它允许我们采用半经验的数学模型,并使用实验数据来完善它。它具有优于两者的优点,一个是特别的数学模型,因为它可以改进,另一个是 ML 模型,因为它更通用(因此可以应用于例如其他电池,获得比单独的 ML 模型更好的精度)。

预测

通过我们的数字孪生兄弟,我们可以做出预测,以便操作锂离子电池。

图六。使用数字双生子和数学模型进行预测。图片作者。

结论

数字双胞胎是工业 4.0 领域的新兴话题。我们已经展示了如何使用 Python 制作一个最小的数字孪生。当我们有实验数据集时,我们可以展示“混合”数字双胞胎如何成为虚拟化资产的更现实的方式。此外,开发可靠的模型需要较少的数据。我们可以将更多未来的实验数据测量添加到我们的数字双胞胎中,以进一步改进我们的数学模型。

图书馆

我们使用 Keras 库用于 NN,使用 Plotly 用于 plots。

感谢

致汉堡理工大学 Merten Stender 教授, m.stender@tuhh.de 及其作品 Digital twin for structural dynamics applications(此处)。

代码和数据

您可以在 repo 中找到该代码,并在此处找到数据(锂离子电池老化数据集)。

引文

  • B.徐、a .乌达洛夫、a .乌尔比格、g .安德森和 D. S .克尔申。(2018).用于电池寿命评估的锂离子电池退化建模。IEEE 智能电网汇刊第 9 卷第 2 期第 1131-1140 页。doi: 10.1109/TSG.2016.2578950。
  • I .拉雷斯戈伊蒂、s .卡比茨、m .埃克和 D. U .绍尔。(2015).模拟锂离子电池在循环过程中的机械退化:固体电解质相间断裂。能源杂志,第 300 卷,第 112-122 页。

如何用 FastAPI 和 JavaScript 构建一个拖放表单

原文:https://towardsdatascience.com/how-to-build-a-drag-drop-form-with-python-javascript-f5e43433b005?source=collection_archive---------10-----------------------

创建上传文件表单的分步教程

由故事创建的云向量——www.freepik.com

[更新:2022–1–5 引导程序 5]

**Table of Contents**
· [Introduction](#bf70)
· [Set-Up](#8b46)
· [Installing Python Packages Using requirements.txt](#5c70)
· [Structure](#ea1a)
· [Creating the Upload Page](#66a4)
  ∘ [① How to add a router in app/main.py](#e2ac)
  ∘ [② Adding a link to the templates/include/topnav.html](#3174)
  ∘ [③ Creating a controller app/routers/upload.py](#7931)
  ∘ [④ Creating a view page, templates/upload.html](#64d7)
· [Creating Upload Area](#577b)
  ∘ [Updating upload.html](#b8e6)
· [Plan of Procedure](#8a8f)
· [Adding Drag & Drop Functions](#af7f)
· [Python Codes](#1b9a)
· [Adding the upload/new Post Method](#5b10)
· [Demo Using Drag and Drop](#1613)
· [Demo Using File Select](#0db0)
· [Conclusion](#baaf)
· [Updates](#0bcc)
· [References](#fc90)

介绍

本文展示了如何使用 Python 和 Javascript 构建一个拖放表单。上传文件允许用户在你的应用上分析他们的数据或图像。我们在本教程中使用 FastAPI [1],但是您可以将它应用到 Flask 或其他 Python 框架中。FastAPI 是一个现代的高性能 web 框架,用于基于标准 Python 类型提示用 Python 3.6+构建 API。HTML 拖放[2]接口使应用程序能够在浏览器中使用拖放功能。

随文章编码或抓取最终编码。

演示

(选项)这些文章,“创建虚拟环境”和“使用 Gitstart 创建 GitHub 存储库”将帮助您设置 Python 环境。如果你想免费托管你的 FastAPI 应用,请阅读“如何在 Heroku Free 上部署 FastAPI 应用”。

设置

我们在 FastAPI Web Starter 之上构建应用程序。FastAPI Web Starter 是一个用 FastAPI 和 Jinja 构建的静态网站。

$ git clone [git@github.com](mailto:git@github.com):shinokada/fastapi-web-starter.git
$ cd fastapi-web-starter

使用 requirements.txt 安装 Python 包

在根目录下创建requirements.txt文件。

我们将Pillow添加到 FastAPI Web Starter 的requirements.txt中。Pillow【3】是一个 Python 成像库。

使用此 rquirements.txt 安装 Python 包:

$ pip install -r requirements.txt

运行服务器:

$ uvicorn app.main:app --reload --port 8000

请访问 http://127.0.0.1:8000/

结构

FastAPI Web Starter 拥有大部分文件。我们将在本文中创建丢失的文件。

创建上传页面

让我们创建一个新页面。我们需要在app/main.py中添加①一个路由器,②顶部菜单中的一个链接,③一个控制器app/routers/upload.py,④一个查看页面。

①如何在 app/main.py 中添加路由器

我们在app/main.py中为upload增加一条新的路线:

完整代码

...
from app.routers import upload, twoforms, unsplash, accordion
...
app.include_router(upload.router)

我们从app.routers导入upload,包含路由器upload.router。这让我们可以访问http://127 . 0 . 0 . 1:8000/upload。

②向 templates/include/topnav.html 添加链接

完整代码

<li class="nav-item {{'active' if active_page == 'upload' }}">    
    <a class="nav-link" href="/upload">Upload</a>          
</li>

我们使用 Jinja 的 if 语句来检查active_page是否为upload。如果是这样,它将添加active类。

③创建控制器 app/routers/upload.py

第 1 行:我们导入 FastAPI 的 APIRouter。我们可以将这个文件包含在app/main.py中。

第 5 行:我们创建一个APIRouter对象,router

第 9-12 行:我们使用 URL 为/uploadget方法。我们使用HTMLResponse返回一个名为upload.html的 HTML 文件。现在,我们向 HTML 文件返回一个变量result

④创建视图页面,templates/upload.html

第 1 行:我们扩展了 FastAPI Web Starter 中的[base.html](https://gist.github.com/shinokada/47e29b95570ccb3950b8e2d77b8abb4d)

第 2 行:我们将active_page设置为upload。这确保了它将在顶部导航菜单中添加active类。

第 12 行:显示result

让我们启动服务器:

$ uvicorn app.main:app --reload --port 8000

访问http://127 . 0 . 0 . 1:8000/upload

创建上传区域

更新 upload.html

我们将在templates/upload.html中创建一个 div upload-area

第 17 行:因为我们不仅允许用户拖放,还允许用户选择要上传的文件,所以我们也添加了一个提交按钮。

第 37 行:添加dragdrop.js。请注意type="module"。这允许我们在dragdrop.js中导入另一个 javascript 文件。

让我们为static/css/mystyle.css中的上传页面添加一些样式:

现在页面看起来像这样:

上传区。图片作者。

程序计划

以下流程图是按顺序上传文件的总结过程。对于本例,我们将上传一个图像文件并创建一个缩略图。

有序的总结过程。图片作者。

我们用 JavaScript 处理大部分过程,用 Python 创建一个缩略图。我们将在下一节中逐一介绍上述过程。

添加拖放功能

static/js/imagehelpers.js有两个功能。

detect()函数查找图像的宽度和高度。它接受一个图像 URL 和一个回调。它创建一个新的图像对象,并使用 URL 分配图像src。我们找到图像的宽度和高度,并在回调中使用它们。我们将使用图像的宽度和高度来确定缩略图的宽度和高度。

dragdrop()函数中,我们使用draggerdropdragenter事件来改变用户在upload-area上拖动文件时的文本。我们添加preventDefault()stopPropagation()来防止浏览器的默认动作。

在最后一行,我们导出了这两个函数,这样我们就可以将它们导入到另一个 javascript 文件中。

static/js/dragdrop.js中:

第 1 行:因为我们使用了type="module",所以我们可以从./imghelper.js导入detect()dragdrop()函数。

第 4 行:运行导入的dragdrop()函数。

第 6–20 行:preparedata()函数使用file作为源创建一个图像 URL blob。它使用导入的detect()函数和创建的图像 URL blob。回调函数使用的window.width()imgWidthimgHeight -都在detect()函数返回的result中。我们将它们存储在data对象中,并使用stringily()函数将 JavaScript 对象转换成 JSON 字符串。我们追加它和删除的文件。然后我们运行uploadData()函数。

第 23–36 行:这个部分控制用户放下文件时的动作。首先,它会将文本更改为“我们正在上传您的文件”。

event.originalEvent.dataTransfer.files返回文件列表。

从 e . original event . data transfer . files 返回的值

我们用它来定义file变量,获取窗口宽度,winWidth并获取列表中第一个被删除的文件。如果拖放的文件与imageType匹配,则将其发送给preparedata()功能。否则,更改文本“请使用图像文件。再试一次。”。

第 39–41 行:这将触发“选择文件”对话框。

第 44–54 行:该部分与第 28–36 行相同。

第 57–69 行:这个 AJAX 部件将数据发送到 URL /upload/new。一旦成功,它运行updatatags()功能。

第 71–76 行:我们使用一个img标签设置 HTML 内容,并将文本改回"Drag and Drop file here<br />Or<br />Click to Upload"

Python 代码

我们给library/helpers.py增加了四个功能。

setdimensions()计算并返回缩略图的尺寸。

create_workspace()返回一个目录路径,使用uuid.uuid4()创建一个唯一的目录名。

thumb()创建缩略图并保存在目录中。

image_trannspose_exif()防止创建的图像旋转。

添加上传/新发布方法

更新app/routers/upload.py:

第 1 行:从fastapi导入FileUploadFile

第 4 行:从../library/helpers导入所有函数。

第 18 行:添加参数,imgdatafile

第 19 行:imgdata[0]包含winWidthimgWidthimgHeight。我们使用eval()将字符串转换成 Python 字典。

第 22 行:创建目录路径并将其存储在workspace变量中。

第 24 行:将拖放的文件名保存到file_name

第 26 行:存储img_full_path变量的完整路径。

第 27–29 行:将拖放的文件保存在目录中。

第 31–35 行:创建一个缩略图并将路径存储到thumb_path变量。

第 37–40 行:返回img_full_paththumb_path。这些值将在dragdrop.js中用于在页面上插入缩略图。

使用拖放进行演示

使用文件选择进行演示

结论

上传的图像可以在您的应用程序中进行分析。在以后的文章中,我们将介绍如何在图像中找到主色。因为我们在目录中有原始图像和缩略图,所以我们可以根据工作量使用其中一个图像。

通过 成为 的会员,可以完全访问媒体上的每一个故事。

https://blog.codewithshin.com/subscribe

更新

[更新:2022–1–5 Bootstrap 5]
[更新:2021–11–07 FastAPI&依赖项更新]
[更新:2021–08–15 Python 和依赖项更新]

参考

  • [1] FastAPI
  • [2] MDN Web Docs HTML 拖放 API
  • 枕头

如何通过 sqlite3 在 Observablehq 中构建动态条形图

原文:https://towardsdatascience.com/how-to-build-a-dynamic-bar-chart-in-observablehq-through-sqlite3-f8f8b6509ac8?source=collection_archive---------29-----------------------

数据可视化

一个现成的笔记本,利用了 Observablehq 提供的最新 sqlite3 特性

照片由卢克·切瑟在 Unsplash 拍摄

最近,Observablehq 团队发布了一个新功能,允许将 sqlite3 数据库导入笔记本。这个特性非常强大,因为它允许通过经典的 SQL 语法动态查询数据集。Mike Bostock 提供的原始教程可在此链接获得。

在本教程中,我利用新的 sqlite3 特性构建了一个简单的条形图,它可以根据用户的选择动态更新。

作为示例数据集,我使用通用食品数据库,该数据库由 data.world 提供,可通过链接获得。下表显示了通用食品数据库的快照:

作者图片

在本教程中,我们将构建一个动态条形图,显示每个子组的项目数,前提是该组。组选择是通过下拉选择完成的。

将 CSV 文件转换为。

通用食品数据库以 CSV 文件发布,因此,在下载后,必须将其转换为. db 文件。然后,它可以作为文件附件上传到可观察的笔记本中。

为了执行到的转换。db,首先我们必须从其官网下载 sqlite3。我们可以解压缩下载的文件夹,并从命令行进入该文件夹。从 sqlite3 文件夹中,我们可以启动 sqlite3 命令:

./sqlite3

现在 sqlite3 终端打开,我们可以创建一个新的数据库,即food_db:

.open food_db

我们可以按如下方式导入通用食物表:

.mode csv                                                               .import /path/to/your/file/generic-food.csv food_table

在前面的示例中,我们已经将 CSV 文件导入到了 food_table 表中。现在我们可以检查该表是否已被正确导入:

.schema

输出应该如下所示:

CREATE TABLE food_table(
   "FOOD NAME" TEXT,
   "SCIENTIFIC NAME" TEXT,
   "GROUP" TEXT,
   "SUB GROUP" TEXT
);

如果我们查看运行 sqlite3 命令的文件夹,我们可以看到有一个名为food_db的文件。这个文件可以作为 Observablehq 提供的sqlite()函数的输入。

将数据库加载到 Observable

现在我们可以在 Observable 中创建新的笔记本并导入数据库。我们可以单击页面右上角的三个点,然后选择文件附件:

作者图片

我们从文件系统中选择文件,并将其上传到可观察的笔记本中。我们可以通过下面一行代码加载数据库:

db = FileAttachment("food_db").sqlite()

我们可以通过describe()函数列出数据库中包含的所有表格:

db.describe()

它给出了以下输出:

作者图片

describe()函数也可以接收表名作为输入:

db.describe('food_table')

它给出了以下输出:

作者图片

查询数据库

我们准备查询数据库。我们可以使用 SQL 语法来构建任何查询。例如,如果我们想要列出所有组,我们可以运行以下查询:

groups = db.query('SELECT DISTINCT(`GROUP`) from food_table')

下图显示了group变量的快照:

作者图片

我们可以构建一个包含所有组的下拉菜单:

viewof term = Inputs.select(groups.map(d => d.GROUP), {value: "Vegetables", label: "Group"})

注意,我们已经将group变量转换为一个对象列表。下拉选择的输出如下所示:

我们可以通过询问属于通过下拉选择选择的组的所有子组来再次查询数据库:

data = db.query('SELECT count(*) AS value, `SUB GROUP` AS name FROM food_table WHERE `GROUP` LIKE $1 GROUP BY name ORDER BY value DESC', [`%${term}%`])

我们可以将结果显示为表格:

Inputs.table(data)

它给出了以下输出:

作者图片

构建条形图

最后,我们可以按照链接中提供的示例来构建条形图。结果如下所示:

如果您回到本文并在下拉选择中选择另一个组,您应该会在条形图中看到变化。仅此而已!

摘要

在本教程中,我已经说明了如何利用 Observable 提供的新的 sqlite3 特性来构建一个动态条形图。

完整的笔记本可以从这里下载。

如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。

相关文章

[## 如何改进带注释的 D3.js 图形

towardsdatascience.com](/how-to-improve-d3-js-graphs-with-annotations-252fbb9c5bb5)

如何使用 Flask 构建假新闻检测 Web App

原文:https://towardsdatascience.com/how-to-build-a-fake-news-detection-web-app-using-flask-c0cfd1d9c2d4?source=collection_archive---------10-----------------------

机器学习部署

用 Flask 部署文本分类模型

照片由来自 Unsplash 的 Markus Winkler 拍摄

随着不同社交网络的采用,假新闻的传播势不可挡。在推特、脸书、Reddit 上,人们利用假新闻传播谣言,赢得政治利益和点击率。

检测假新闻对于一个健康的社会至关重要,检测假新闻有多种不同的方法。从机器学习的角度来看,假新闻检测是一个二元分类问题;因此,我们可以使用传统的分类方法或最先进的神经网络来处理这个问题。

本教程将从头开始创建一个自然语言处理应用程序,并将其部署在 Flask 上。最终,您将拥有一个运行在本地机器上的假新闻检测 web 应用程序。请看这里的预告。

本教程采用以下结构组织:

  • 第一步:将数据从 Kaggle 加载到 Google Colab。
  • 第二步:文本预处理。
  • 第三步:模型训练和验证。
  • 步骤 4:挑选并加载模型。
  • 第五步:创建一个 Flask 应用程序和一个虚拟环境。
  • 第六步:添加功能。
  • 结论。

注:完整的笔记本在 GitHub 上。

第一步:将数据从 Kaggle 加载到 Google Colab

嗯,机器学习项目最基础的部分就是数据。我们将使用来自 Kaggle 的虚假和真实新闻数据集来构建我们的机器学习模型。

我以前写过一篇关于如何从 Kaggle 下载数据到 Google Colab 的博客。请随意按照里面的步骤操作。

文件夹里有两个独立的 CSV 文件,,分别对应真假新闻。让我们看看数据是什么样的:

true = pd.read_csv('True.csv')
fake = pd.read_csv('Fake.csv')
true.head(3)

真实 CSV 文件的前三行(图片由作者提供)

第二步:文本预处理

数据集有四列,但它们还没有标签,让我们先创建标签。假新闻作为标签 0,真新闻标签 1。

true['label'] = 1
fake['label'] = 0

数据集是相对干净和有组织的。为了提高训练速度,我们使用两个数据集中的前 5000 个数据点来构建模型。您还可以使用完整的数据集来获得更全面的结果。

*# Combine the sub-datasets in one.*
frames = [true.loc[:5000][:], fake.loc[:5000][:]]
df = pd.concat(frames)
df.tail()

用于训练和测试的组合数据集(图片由作者提供)

我们还可以将要素和标签分开,并制作一份数据帧的副本,供以后培训使用。

X = df.drop('label', axis=1) 
y = df['label']
# Delete missing data
df = df.dropna()
df2 = df.copy()
df2.reset_index(inplace=**True**)

酷!时间对于真正的文本预处理,这包括删除标点符号,降低所有大写字符,删除所有停用词, 词干 ,很多时候我们把这个过程叫做 标记化

**from** **nltk.corpus** **import** stopwords
**from** **nltk.stem.porter** **import** PorterStemmer
**import** **re**
**import** **nltk**nltk.download('stopwords')
ps = PorterStemmer()
corpus = []**for** i **in** range(0, len(df2)):
    review = re.sub('[^a-zA-Z]', ' ', df2['text'][i])
    review = review.lower()
    review = review.split()

    review = [ps.stem(word) **for** word **in** review **if** **not** word **in** stopwords.words('english')]
    review = ' '.join(review)
    corpus.append(review)

接下来,让我们使用 TF-IDF 矢量器将每个记号转换为矢量,也就是矢量化记号或 单词嵌入 。您可以使用其他单词嵌入技术来处理这个数据集,如 Word2Vec、Glove,甚至 BERT,但我发现 TF-IDF 足以生成准确的结果。

TF-IDF(词频—逆文档频率)的简明解释:它通过同时考虑一个单词在一个文档中的频率和同一语料库中其他文档的频率来计算该单词的重要性。

例如, detection 这个词在这篇文章中出现的比较多,但在 MEDIUM 语料库的其他文章中却没有出现;因此“检测”是这篇文章中的一个关键词,但是“ term ”这个词几乎在任何文档中都存在,出现频率很高,所以它并不那么重要。

关于 TF-IDF 更详细的介绍可以在这个媒体博客中找到。

**from** **sklearn.feature_extraction.text** **import** TfidfVectorizer
tfidf_v = TfidfVectorizer(max_features=5000, ngram_range=(1,3))
X = tfidf_v.fit_transform(corpus).toarray()
y = df2['label']

大部分完成了!让我们做最后一步,拆分数据集进行训练和测试!

**from** **sklearn.model_selection** **import** train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

步骤 3:模型训练和验证

你可以在这里尝试多种分类算法:逻辑回归、SVM、XGBoost、CatBoost 或神经网络。我使用的是 在线被动攻击算法

**from** **sklearn.linear_model** **import** PassiveAggressiveClassifier
**from** **sklearn** **import** metrics
**import** **numpy** **as** **np**
**import** **itertools**classifier = PassiveAggressiveClassifier(max_iter=1000)
classifier.fit(X_train, y_train)
pred = classifier.predict(X_test)
score = metrics.accuracy_score(y_test, pred)
print("accuracy:   **%0.3f**" % score)

模型精度(图片由作者提供)

相当不错的成绩!让我们打印混淆矩阵来看看误报和漏报。

**import** **matplotlib.pyplot** **as** **plt**

**def** plot_confusion_matrix(cm, classes,
                          normalize=**False**,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    **if** normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    **else**:
        print('Confusion matrix, without normalization')

    thresh = cm.max() / 2.
    **for** i, j **in** itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center",
                 color="white" **if** cm[i, j] > thresh **else** "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')cm = metrics.confusion_matrix(y_test, pred)
plot_confusion_matrix(cm, classes=['FAKE', 'REAL'])

作者图片

因此,在使用 TF-IDF 矢量器的平衡数据集中,使用被动-主动算法,我们得到了 3 个假阳性,没有假阴性。

让我们使用一个看不见的数据集进行验证,比如说来自 CSV 文件的第 13070 个数据点。我们预期分类模型的结果是 0。

# Tokenization
review = re.sub('[^a-zA-Z]', ' ', fake['text'][13070])
review = review.lower()
review = review.split() 
review = [ps.stem(word) **for** word **in** review **if** **not** word **in** stopwords.words('english')]
review = ' '.join(review)# Vectorization
val = tfidf_v.transform([review]).toarray()# Predict 
classifier.predict(val)

模型输出(图片由作者提供)

酷!我们得到了我们想要的。您可以尝试完整数据集中更多看不见的数据点。我相信这个模型会给你一个满意的答案,而且准确度很高。

第 4 步:挑选和加载模型

现在,是时候清理(保存)模型和矢量器了,这样你就可以在其他地方使用它们了。

**import** **pickle** pickle.dump(classifier, open('model2.pkl', 'wb'))
pickle.dump(tfidf_v, open('tfidfvect2.pkl', 'wb'))

再来看看不训练能不能用这个模型。

# Load model and vectorizer
joblib_model = pickle.load(open('model2.pkl', 'rb'))
joblib_vect = pickle.load(open('tfidfvect2.pkl', 'rb'))
val_pkl = joblib_vect.transform([review]).toarray()
joblib_model.predict(val_pkl)

酸洗模型的输出(图片由作者提供)

我们得到了相同的输出!这正是我们所期望的!

现在模型已经准备好了,是时候部署它并检测 web 应用程序上的任何消息了。

第五步:创建一个 Flask 应用程序和一个虚拟环境

Flask 是一个轻量级的 WSGI web 应用框架。与 Django 相比,Flask 更容易学习,但是出于安全考虑,它不适合用于生产。出于这个博客的目的,你将学习 Flask。相反,你可以自由地跟随我的另一个教程学习如何使用 Django 部署一个应用。

  1. 从终端或命令行创建一个新目录:
mkdir myproject
cd myproject

2.在项目目录中,为项目创建一个虚拟环境。

如果您没有安装 virtualen ,运行以下命令在您的终端中安装环境。

pip install virtualenv

在安装了 virtualen 之后,运行下面的代码来创建一个 env。

virtualenv <ENV_NAME>

替换<env_name>中 env 的名称</env_name>

通过以下方式激活环境:

source <ENV_NAME>/bin/activate

您可以在需要时使用以下命令移除 env:

sudo rm -rf <ENV_NAME>

现在你的 env 已经准备好了。让我们先安装烧瓶。

pip install flask

是时候构建 web 应用程序了!

步骤 6:添加功能

首先,让我们在同一个目录中创建一个新文件,包含以下内容,并将其命名为 app.py,我们将在该文件中添加一些功能。将上一步中经过酸洗的模型和矢量器移动到同一个目录中。

我们要构建四个函数: home 用于返回主页;预测用于得到分类结果,判断输入的新闻是假的还是真的; webapp 用于返回网页上的预测; api 是将分类结果转换成 JSON 文件,构建外部 api。

你可能会发现官方文件对你很有帮助。

from flask import Flask, render_template, request, jsonify
import nltk
import pickle
from nltk.corpus import stopwords
import re
from nltk.stem.porter import PorterStemmerapp = Flask(__name__)
ps = PorterStemmer()# Load model and vectorizer
model = pickle.load(open('model2.pkl', 'rb'))
tfidfvect = pickle.load(open('tfidfvect2.pkl', 'rb'))# Build functionalities [@app](http://twitter.com/app).route('/', methods=['GET'])
def home():
    return render_template('index.html')def predict(text):
    review = re.sub('[^a-zA-Z]', ' ', text)
    review = review.lower()
    review = review.split()
    review = [ps.stem(word) for word in review if not word in stopwords.words('english')]
    review = ' '.join(review)
    review_vect = tfidfvect.transform([review]).toarray()
    prediction = 'FAKE' if model.predict(review_vect) == 0 else 'REAL'
    return prediction[@app](http://twitter.com/app).route('/', methods=['POST'])
def webapp():
    text = request.form['text']
    prediction = predict(text)
    return render_template('index.html', text=text, result=prediction)[@app](http://twitter.com/app).route('/predict/', methods=['GET','POST'])
def api():
    text = request.args.get("text")
    prediction = predict(text)
    return jsonify(prediction=prediction)if __name__ == "__main__":
    app.run()

您可以在前面的部分看到一个index.html文件,它是应用程序的主页。在根文件夹中创建一个名为“模板”的文件夹,在里面创建一个文件“index . html”。现在让我们给页面添加一些内容。

<!DOCTYPE HTML>
<html><head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>Fake News Prediction</title>
 <link href="[https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css](https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css)" rel="stylesheet"
  integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
 <script src="[https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js](https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js)"
  integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
  crossorigin="anonymous"></script>
 <script src="[https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js](https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js)"></script></head><body>
 <nav class="navbar navbar-expand-lg navbar-light bg-light">
  <div class="container-fluid">
   <a class="navbar-brand" href="/">FAKE NEWS PREDICTION</a>
   <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup"
    aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
   </button>
   <div class="nav navbar-nav navbar-right" id="navbarNavAltMarkup">
    <div class="navbar-nav">
     <a class="nav-link" target="_blank"
      href="[https://rapidapi.com/fangyiyu/api/fake-news-detection1/](https://rapidapi.com/fangyiyu/api/fake-news-detection1/)">API</a>
     <a class="nav-link" target="_blank"
      href="[https://medium.com/@fangyiyu/how-to-build-a-fake-news-detection-web-app-using-flask-c0cfd1d9c2d4?sk=2a752b0d87c759672664232b33543667/](https://medium.com/@fangyiyu/how-to-build-a-fake-news-detection-web-app-using-flask-c0cfd1d9c2d4?sk=2a752b0d87c759672664232b33543667/)">Blog</a>
     <a class="nav-link" target="_blank"
      href="[https://github.com/fangyiyu/Fake_News_Detection_Flask/blob/main/Fake_news_detection.ipynb](https://github.com/fangyiyu/Fake_News_Detection_Flask/blob/main/Fake_news_detection.ipynb)">NoteBook</a>
     <a class="nav-link" target="_blank" href="[https://github.com/fangyiyu/Fake_News_Detection_Flask](https://github.com/fangyiyu/Fake_News_Detection_Flask)">Code Source</a>
    </div>
   </div>
  </div>
 </nav><br>
 <p style=text-align:center>A fake news prediction web application using Machine Learning algorithms, deployed using Django and Heroku. </p>
 <p style=text-align:center>Enter your text to try it.</p>
 <br>
 <div class='container'>
  <form action="/" method="POST">
   <div class="col-three-forth text-center col-md-offset-2">
    <div class="form-group">
     <textarea class="form-control jTextarea mt-3" id="jTextarea'" rows="5" name="text"
      placeholder="Write your text here..." required>{{text}}</textarea><br><br>
     <button class="btn btn-primary btn-outline btn-md" type="submit" name="predict">Predict</button>
    </div>
   </div>
  </form>
 </div>
 <br>
 {% if result %}
 <p style="text-align:center"><strong>Prediction : {{result}}</strong></p>
 {% endif %}<script>
     function growTextarea (i,elem) {
    var elem = $(elem);
    var resizeTextarea = function( elem ) {
        var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft;
        var scrollTop  = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;  
        elem.css('height', 'auto').css('height', elem.prop('scrollHeight') );
          window.scrollTo(scrollLeft, scrollTop);
      };
      elem.on('input', function() {
        resizeTextarea( $(this) );
      });
      resizeTextarea( $(elem) );
  }

  $('.jTextarea').each(growTextarea);
</script>
</body></html>

上面的脚本创建了这样一个网页:

假新闻检测网络应用用户界面(图片由作者提供)

现在,您可以通过在终端中键入以下命令来运行您的应用程序:

python3 app.py

您将能够在本地运行您的应用程序,并对模型进行测试。

结论

在本教程中,您构建了一个机器学习模型来从真实新闻中检测假新闻,并保存该模型以使用 Flask 构建一个 web 应用程序。web 应用程序正在您的本地机器上运行,您可以尝试使用 Heroku、AWS 或 DigitalOcean 等云服务将其公开。我已经在 Heroku 部署了地雷。请随意试一试。

我希望你喜欢这次旅行。欢迎留言评论,在 Linkedin 与我联系。

如何用数据科学打造梦幻英超球队

原文:https://towardsdatascience.com/how-to-build-a-fantasy-premier-league-team-with-data-science-f01283281236?source=collection_archive---------3-----------------------

利用数据科学和数学优化您的 FPL 团队。

照片由 Nguyen Thu Hoai 在 Unsplash

介绍

梦幻超级联赛是一个体育战略游戏,我们建立了一个足球队的基础上,从英格兰超级联赛的球队。这个游戏的目标是挑选对比赛有贡献的球员。

为了知道球员有没有贡献,我们可以看看它的分数。这些分数是基于几个统计数据检索的,比如助攻数、进球数、上场时间等等。随着分数越来越大,球员们为比赛做出了巨大的贡献。

对于挑选球员,我们也有几个约束。这些制约因素是:

  • 一个队由 15 名队员组成。具体来说,一个球队有两名守门员,五名后卫,五名中场,三名前锋。
  • 给一个团队的预算只有 1 亿英镑。
  • 我们最多只能从一支英超球队中挑选三名球员。

我们如何在这些限制下建立一个团队?我们可以利用数据科学和数学的帮助,而不是依靠我们的常识!

本文将向你展示如何用一个叫做线性规划的数学概念来构建一个梦幻英超球队。

如果对那个概念理解不深也不用担心。我们将使用一个基于 Python 语言的名为 Pulp 的库。

没有进一步,让我们开始吧!

最优化和线性规划

在我们进入实现之前,让我给你解释一下优化和为什么我们应该使用线性编程的原因。

优化过程是优化问题的工作流程。这个问题包括结果和我们受到的限制。一般来说,这个过程分为几个步骤。它们是:

  • 获取问题描述。
  • 制定数学程序
  • 求解数学程序
  • 评估结果
  • 最终确定结果

在我们的例子中,问题描述是我们想要建立一个足球队,它有大量的分数,同时有效地使用预算。

要将问题公式化为数学问题,我们需要知道一些信息。这些是:

  • 我们想要观察的变量。对于我们的问题,我们需要像玩家的价格、点数、团队和位置这样的数据。
  • 目标函数。我们想优化这个函数。在这种情况下,我们希望从我们挑选的球员身上得到很多分数。
  • 因为 FPL 有像预算和球员数量这样的规则,所以我们给出了约束条件。
  • 最后,我们需要跟踪玩家统计数据的数据。

在我们得到所有我们需要的信息后,下一步是解决问题。为此,我们可以使用线性规划。

使用线性编程的原因是因为函数是基于线性表达式格式的。基于该表达式,线性编程将试图找到最佳点。因此,我们可以得到最优的结果。

我不会解释线性规划背后的细节。如果你有更多的兴趣,你可以在网上探索更多。目前,我们主要关注如何使用 Python 解决优化问题。

履行

数据源

对于数据源,FPL 为我们提供了访问历史数据的 API。我们可以检索数据,如球员的统计数据,每个游戏周的结果,球队的表现,等等。数据本身是 JSON 格式的,所以我们必须先重新格式化它。

如果您不能使用 API 或预处理 JSON,不要担心,我们可以使用来自 vaastav 的 GitHub 存储库中的预处理数据。您可以在这里访问数据。要下载数据,我们可以使用 git 克隆来完成。在您的终端上,编写如下命令:

**git clone** [**https://github.com/vaastav/Fantasy-Premier-League.git**](https://github.com/vaastav/Fantasy-Premier-League.git)

加载库

获得数据后,下一步是导入库来处理数据集。我们需要像 pandas 这样的库来分析和处理数据,需要 pulp 来应用线性编程。

如果您仍然没有这些库,您可以使用 pip 命令来安装这些库。在终端上,编写以下命令:

**pip install pandas
pip install pulp**

在你的 jupyter 笔记本上,写下这几行代码:

加载数据

加载库之后,下一步是加载数据。我们将在每个比赛周使用包含当前赛季(2021–22)球员统计数据的数据。让我们写这几行代码:

在这种情况下,我们只取前一个游戏周。就像文章目前写的那样,目前的游戏周是游戏第 6 周。因此,我们从第 5 周的游戏中获取数据。让我们写这几行代码:

从上表可以看出,我们有很多列。因此,我们只选取我们实际需要的列。

这些列是玩家的名字、俱乐部、总点数、价格(价值)和位置。关于这些列的细节将在下一节中解释。

现在让我们写这几行代码:

初始化变量

现在我们有了我们需要的数据。下一步是初始化几个变量。正如我之前提到的,我们从表中提取了几列。原因有两个,目标和限制。

我们采用总点数变量是因为我们想优化点数。同时遵守我们现有的约束。像团队名称、位置和价格这样的变量是需要满足的约束。

现在让我们编写这些代码行来初始化我们需要的变量:

初始化问题

现在我们有了我们需要的变量。下一步是初始化包含我们的目标和约束的 LpProblem 对象。

我们设置参数,如问题的名称和一个对象,以确定问题的目标。因为我们想要最大化点数,所以我们将 LpMaximize 设置为对象的参数。

下面是实现这一点的代码:

定义目标

初始化问题后,下一步是定义目标。我们问题的目标是使点数最大化。

让我们写这几行代码:

定义约束

让我们回忆一下来自 FPL 的约束:

  • 一个队由 15 名队员组成。具体来说,一个球队有两名守门员,五名后卫,五名中场,三名前锋。
  • 给一个团队的预算只有 1 亿英镑。
  • 我们最多只能从一支英超球队中挑选三名球员。

基于上面的约束,我们创建数学上描述约束的表达式。

让我们写这几行代码:

解决问题

我们有了我们需要的变量和数学表达式。现在让我们通过使用这行代码来解决这个问题:

检索玩家列表

程序解决问题后,我们可以检索符合约束条件的玩家姓名。让我们写这几行代码:

检索预期点数和总成本

现在你有了适合 FPL 限制的球队阵容。如果我们想知道期望的点数和使用的预算呢?

从这个问题中,我们可以得到目标和约束方程。我们可以通过计算等式来计算总点数和价格值。

下面是处理结果的代码:

结论

干得好!现在,您已经使用 Python 实现了构建梦幻超级联赛最佳团队的线性规划。

我希望它能帮助你为 FPL 建立你的团队。因此,你可以用有限的预算建立一个能为比赛做出贡献的最佳团队。

如果你对我的文章感兴趣,你可以在 Medium 上关注我。如果有任何问题,可以在 LinkedIn 上联系我。

感谢您阅读我的文章。

参考

[1]https://towards data science . com/how-our-ai-got-top-10-in-the-fantasy-premier-league-using-data-science-ba88b 185 b 354
【2】https://towards data science . com/creating-a-fantasy-cricket-team-application-of-of-linear-programming-4b 60 c 261702d
【3】https://medium . com

如何构建首次机器学习项目(带完整代码)

原文:https://towardsdatascience.com/how-to-build-a-first-time-machine-learning-project-with-full-code-3c34ab0d36c3?source=collection_archive---------20-----------------------

使用设施操作示例的机器学习演练

郭锦恩在 Unsplash 上拍照

虽然机器学习看起来势不可挡,但在寻找潜在的开始方式时,知道从哪里开始是关键。一个很好的出发点是看看企业在哪里执行可重复的过程。作为一个在设施运营和可靠性工程领域有几年职业背景的人,我的日常经验让我深入了解了机器学习如何应用于可重复流程的运营。

当我第一次对机器学习感兴趣时,我正在寻找通过开发实际创造商业价值的技术解决方案来应用我新发现的兴趣的方法。然而,我经常发现,我在早期学习中去的许多来源都是推销他们专有的 ML 平台或软件,而我并不想购买。虽然这些公司可能有价值,但我决心学习如何在不依赖昂贵的第三方解决方案的情况下应用机器学习。

出于这个原因,我创建了一个样本机器学习项目,它可以通过开放源代码技术免费完成,进入门槛相对较小,并去除了一些你不想购买的软件的任何“专有数据”或“隐藏的销售宣传”。相反,它旨在成为一个起点,激励其他人尝试机器学习,并可能利用代码来创建他们自己的解决方案。(尽管这个示例与设施行业相关,但是这个演练可以应用于您可能拥有的任何领域专业知识中的任何“重复过程”。)

问题陈述和背景

按时完成维护对于设施可靠地提供其商业价值至关重要,如今许多运营都使用 CMMS(计算机化维护管理系统)来记录和控制正在进行的工作。存储在这些企业数据库系统中的是工作是否按时完成的所有历史记录(通常称为工作订单)。机器学习可以用来帮助找到数据中的模式,以便做出主动决策,确保按时完成正确的工作。

机器学习项目概述

以下是我们的机器学习项目将做什么的高级概述:

  1. 从历史工单数据中学习
  2. 将工作单的特性作为输入
  3. 预测未来的工作订单是否会延迟
  4. 提供输入如何影响预测的详细解释

模型概述(图片由 Cory Randolph 提供)

详细演练

对于这个详细的演练,我将只显示和解释相关的代码部分,因为整个代码可以在 Google Colab 这里查看和运行。

数据

许多工厂运营依赖于存储工作订单历史信息的企业数据库。为了这个项目,我创建了 500 个虚构的工作指令,反映了在这种系统中发现的信息类型。当试图识别自己的数据时,我发现在开始机器学习项目时有 5 个好问题可以问。我在我的文章5 个简单的问题为一个机器学习项目寻找数据 中对这个过程做了详细的解释

样本数据(图片由 Cory Randolph 提供)

每个特征/列的解释:

部门 =给定工单/维护任务中正在执行的工作类型的部门名称。(例如,电气、机械等)

姓名 =完成工作的技术人员的姓名。(为此示例数据随机生成的虚构名称)

预计工时 =给定工单/任务预计需要的大概工时数。

频率 =必须再次完成这些工作指令/任务的频率间隔。(例如,90 天的任务意味着每年要完成 4 次(365 天/ 90 天))。

过期 =特定工单是否过期的标签。(例如,1 =工作订单过期,0 =工作订单按时完成。)

要获得 Jupyter 笔记本中的完整数据:

# Set the url of where the csv data can be downloaded fromurl = 'https://raw.githubusercontent.com/coryroyce/Facilities_ML_Project/main/Data/Maintenace_Past_Due_Sample_Data.csv'# Load the csv data into a Pandas DataFrame to easily work with the data in pythondf = pd.read_csv(url)

接下来,我们处理数据,以便通过将特征/输入(表示为“X”)与标签/输出(表示为“y”)分离,ML 模型可以使用该数据。然后保存 20%的数据作为测试数据,用于验证 ML 模型是否真的在学习模式,而不仅仅是记忆训练数据。

# Separate the features/inputs from the labels/outputsX = df.copy()y = X.pop('Past_Due')# Split the data into train and test data with 20% of the data to test the modelX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

机器学习模型

既然数据已经加载并准备好进行处理,我们就可以开始创建机器学习模型了。如果您刚刚开始使用 ML,值得注意的是,我们的模型是一个监督分类模型,具有数值和分类特征数据。Catboost 是一个 ML 框架,在简单性和良好性能方面非常适合,不需要太多的超参数调整。为了更好地理解这些 ML 模型如何更详细地工作,一个好的起点是谷歌的机器学习速成班。

因为我们使用的是 CatBoost 库,所以我们可以只用两行代码创建和构建一个性能良好的模型:首先,将模型设置为 CatBoost 分类器。接下来,根据我们之前设置的数据对其进行拟合/训练。

# Select the ML Model typemodel = CatBoostClassifier()# Fit the model to the training datamodel.fit(X_train, y_train, cat_features=['Department', 'Name', 'Frequency'], eval_set=(X_test, y_test))

运行上面的代码块后,我们现在有了一个经过训练的机器学习模型,我们可以用它来预测未来的工作订单是否会延迟。

衡量标准

现在,我们已经有了一个训练有素的机器学习模型,我们需要检查我们的模型有多“好”,并了解它是否可以提供关于工作订单是否可能延迟的有用预测。虽然有大量的指标或方法来评估一个模型有多好,但最有用和最容易理解的指标是准确性(要更深入地了解准确性,请查看杰瑞米·乔登的文章, 评估机器学习模式 l )。简而言之,准确性是模型做出正确预测的百分比。因此,在决定工作订单是否会延迟时,50%的准确率与随机猜测或抛硬币是一样的。

使用一个名为 SKlearn 的通用 ML 库使得获得我们模型的准确性变得非常简单。

# Store the predicted scores from the test datasetpreds_test = model.predict(X_test)# Print the accuracy of the test predictionsprint(f'Model Accuracy on test data: {metrics.accuracy_score(y_test, preds_test)*100}%')

虽然根据数据分割和模型训练,整体精度可能略有不同,但我最近获得的精度是 89%。这意味着我们有一个模型可以正确预测一个工作订单是否会延迟大约 10 次。

预测

有了我们有效且准确的模型,价值就来自于对未来工作订单的预测。这使业务人员能够洞察何时需要调整流程,以确保有可能延迟的工作能够提前得到主动解决。

接下来的代码块显示了如何预测单个工作订单,但可以很容易地修改为进行批量预测,以检查下个月到期的所有工作订单,然后将它们导出到 csv、excel 或 Google 表中,以最适合您的企业正在使用的操作流程。

# Manually input any combination of features to get a prediction (Note: Order of data has to match the column orders)sample = ['Electrical', 'Chris', 4,'90 Days']# Send the sample to the model for predictionsample_prediction = model.predict(sample)# Display predictionprint(f'Current Sample is predicted as {sample_prediction} \n(Note: 1 = Past Due, 0 = On Time)')

解释(奖金)

这种预测工作订单是否会延迟的工作机器学习模型已经在一个很好的地方增加了商业价值,但打开机器学习的“黑匣子”可以帮助我们更多地理解数据,并提供对“为什么”模型做出某种预测的洞察。能够提供详细的解释有助于在内部以及向客户/顾客建立项目的可信度。

一个越来越受欢迎的帮助解释的工具叫做 SHAP 。为了让文章的以下部分更容易阅读,我将省略详细的代码,只展示视觉效果和解释(完整的代码可以在这里找到)。

第一层解释来自模型概要层,需要回答的一个重要问题是:“哪些特性/输入是最重要的,它们有多重要?”有几种不同的方法可以直观地看到 SHAP,为了简单起见,我们将使用条形图汇总图。

SHAP 特征重要性汇总图(图片由 Cory Randolph 提供)

此汇总条形图显示部门对模型的影响最大,而估计工时对模型的影响最小。

下一个需要回答的问题是:“每个输入实际上对模型的预测有多大影响?”这里,SHAP 工具再次为任何单个工单提供了一种查看这种情况的方法。

单一预测的 SHAP 瀑布图(图片由 Cory Randolph 提供)

为了理解该图,我们从左下方的 E[f(x)]开始,它基本上是给定工单的预期输出,向右移动(红色)显示工单延迟的变化增加,向左移动(蓝色)显示工单延迟的机会减少。

  • 估计工时为 16 小时,增加了此工作单延迟的可能性。
  • 将 Nathan 作为技术人员分配给工作单也增加了工作单延迟的可能性。
  • 一年 360 天的频率也会增加迟到的几率。
  • 将管道作为一个部门可以显著降低工作订单延迟的可能性。

总的来说,由于最终的 f(x)位于起始位置 E[f(x)]的右侧,因此该工作单将被预测为延迟,但是现在我们有了一个关于为什么会得出该结论的详细解释。

最后要问的问题是:“是哪几组详细的数据导致工单延期?”在 SHAP,帮助回答这个问题的工具叫做依赖图。这些图帮助我们深入了解输入的实际值(包括分类值和数值值),并了解它们如何影响模型的预测。虽然完整代码文件显示了每个特性/输入的这些图,但让我们只看一下部门的依赖图。

SHAP 依赖情节的部门(图像由科里伦道夫)

为了理解该图,如果您在 0 值处画一条水平线,那么该线以上的值将指示该部门的工作订单延迟的可能性,而 0 以下的值将指示工作订单将按时完成。总之,HAVC 部门有很高的延迟工作订单的可能性,而管道有很低的延迟工作订单的可能性。电气和机械相当平衡,有相似数量的延迟和准时工作订单。

这也成为可操作的数据。既然我们看到 HVAC 和延迟工作订单之间存在关联,我们可以进一步询问业务问题;暖通是不是人手不足?暖通空调中是否有特定类型的工作会导致迟到问题?管道系统做了哪些改变,让他们能够按时完成工作?

摘要

总之,早期 ML 项目可以分为 4 个主要阶段:

  • 定义最初的业务问题
  • 确定哪些可重复的过程提供可用的数据
  • 创建工作机器学习模型
  • 生成详细的解释

使用提供的代码作为模板,我希望你将通过这 4 个阶段中的每一个来创造一些有价值的东西。

如果你读完了这篇教程,并且能够在你自己的项目中使用它,请在下面的评论部分分享你的经验和应用。我真的很想知道你是如何利用机器学习来解决问题的。

快速参考

  • 全码
  • 为一个机器学习项目寻找数据的 5 个简单问题
  • 谷歌的机器学习速成班
  • Catboost

如何将 Streamlit 应用程序库构建为单个 Web 应用程序

原文:https://towardsdatascience.com/how-to-build-a-gallery-of-streamlit-apps-as-a-single-web-app-466682190629?source=collection_archive---------12-----------------------

数据可视化

下载一个免费模板,插入多个 Streamlit 应用程序,就大功告成了

作者图片

我使用 Streamlit 已经有一段时间了,并且已经编写了一些实验性的应用程序。虽然我对它们很满意(就它们而言——它们只是简单的例子),但没有一个值得拥有专门的网页。

那么,呈现可以从单个网页访问的应用程序库的最佳方式是什么呢?

你可以把所有代码放在一个应用程序中,然后用一个if语句在它们之间进行选择(正如我在本文的中所做的那样),但是这不是很容易扩展——一旦你使用了几个以上的应用程序,就会变得混乱。

那么,如何创建一个应用程序库,用一个调度程序根据下拉菜单中的选择调用每个应用程序呢?这样,应用程序就被编写成独立的功能。您只需创建一个库文件夹来包含应用程序,然后 dispatcher 调用相应的文件夹。

我认为那听起来更好。

Mustrapp 一个简单的框架

因此,为此,我创建了一个名为Mustrapp(Mul pleStreamlitApps)的应用程序模板(可以免费下载),这使得创建多个 Streamlit 应用程序的过程变得非常简单。

为了让应用程序工作,你需要将它们组织起来,使它们位于一个名为run()的可调用函数中。并且,理想情况下(但不是必须的),包含一个描述字符串,该字符串将被用作下拉菜单中的文本(如果您没有提供,将使用模块名称)。

所以,一个应用程序看起来会像这样:

description = "My first app"
def run():
   st.header("This is my first app")
   st.write("I hope you like it")if __name__ == "__main__":
   run()

你可以在一个应用中拥有尽可能多的功能,但是它必须从一个叫做run 的功能开始,这是唯一的要求。最后一个if语句是可选的,但是很有用,因为它允许您将单个应用程序作为独立应用程序运行,或者作为多应用程序的一部分运行。它主要检查该函数是否作为主模块被调用(在这种情况下,它的__name__将是 __main__)。如果它作为一个库模块被调用(这就是我们想要做的),那么__name__将是模块名。

能够将应用程序作为一个独立的功能来运行对于调试非常有用,因为您不需要应用程序的其他部分来运行。

假设你写了上面的 app,保存在一个文件app1.py里。

然后,您可以编写另一个应用程序app2.py,如下所示:

description = "My second app"
def run():
   st.header("This is my second app")
   st.write("Here is an image:")
   st.image("image.png")if __name__ == "__main__":
   run()

然后,我们将这些文件放在一个名为stlib 的文件夹中——这将是我们的库文件夹,我们所有的应用程序都将存放在这里。为了让 Python 将这个文件夹识别为一个库,它需要包含一个名为__init__.py的文件。如果你已经下载了模板,它已经在那里了。

调度程序位于个人文件夹中。这是我们启动 Streamlit 应用程序时将运行的程序。我打算把它叫做index.py

所以我们完整的应用程序是这样构建的:

/home
 |
 |-- index.py
 |
 |-- /stlib
       |
       |-- __init__.py
       |
       |-- app1.py
       |
       |-- app2.py

要运行应用程序,请执行以下命令:

streamlit run index.py

这将在您的浏览器中弹出:

示例应用程序—作者图片

您可以在本文末尾的要点中看到 dispatcher 的完整代码(太长了,这里不包括)。最后,我还会提供一个 Github 资源库的链接,您可以在这里克隆或下载完整模板的 zip 文件,包括调度程序、目录结构和几个虚拟应用程序。

但基本上是这样运作的。

首先,我们导入 Streamlit 库(当然)以及我们需要的其他库。(它还将布局设置为宽。这个是可选的,但在我看来,如果你打算使用侧边栏,看起来会更好,就像我们在这里做的一样——如果你愿意,可以删除它。)

然后我们开始识别库中的应用程序(stlib,并在名为namesmodulesdescriptions的全局数组中记录应用程序的名称、模块引用和描述。stlib库中的任何模块都被视为 Streamlit 应用,除非其名称以_字符开头。通过这种方式,您可以添加非应用程序库模块(例如_mylibrary.py),如果您需要的话,它们不会被作为 Streamlit 应用程序选中。

完成此操作后,我们创建一个包含模块名称的下拉菜单(显示描述,如果可用),一旦选择,从modules数组中选择适当的模块,并执行其功能run()。换句话说,对应于选择的应用程序正在运行。

就算我自己说,这个也挺管用的。将 dispatcher 应用程序与任意数量的可调用应用程序一起使用很容易,维护起来也非常简单。现在,我们可以在一个网页上一次性部署任意数量的迷你应用程序。

这些都不是火箭科学,但我希望它有用。你可以在这里看到一个使用这个模板的示例网站,你可以从它的 Github 库下载或者克隆完整的模板。

一如既往地感谢阅读,如果你想知道我什么时候发表新文章,请考虑在这里注册一个电子邮件提醒。我也偶尔在子栈上发布免费的时事通讯。请在下面留下任何评论,或者您可以通过 LinkedIn 或 Twitter 联系。

https://alanjones2.github.io/

有趣的是,这里是调度程序代码:

调度员代码

如何使用开源工具构建 GitHub 活动仪表板

原文:https://towardsdatascience.com/how-to-build-a-github-activity-dashboard-with-open-source-b3d60277e9a3?source=collection_archive---------19-----------------------

将 Airbyte 和 Metabase 结合在一起

作者形象

在本文中,我们将利用 Airbyte (一种开源数据集成平台)和元数据库(一种供贵公司每个人提问和从数据中学习的开源方式)来构建上面的 GitHub 活动仪表板。

Airbyte 为我们提供了一套丰富的源连接器,其中之一就是 GitHub 连接器,它允许我们从 GitHub repo 中获取数据。

我们将使用这个连接器获取 airbyte repo 的数据,并将它们复制到 Postgres 数据库目的地。

然后,我们将该数据库连接到元数据库,以便创建活动仪表板。

我们需要的是:

  • 饭桶
  • 码头工人
  • 码头工人写作
  • Airbyte
  • Postgres 数据库
  • GitHub 访问令牌
  • 元数据库

第 1 步:使用 Airbyte 将数据从 GitHub 复制到 Postgres

设置 Airbyte

如果您的机器上已经有 Airbyte,您可以跳过这一步。

要在您的机器上设置 Airbyte,请确保您有 Docker 和 Docker 编写设置以及 git。然后,打开一个终端,并前往您想下载 Airbyte 的位置,然后运行:

git clone [https://github.com/airbytehq/airbyte.git](https://github.com/airbytehq/airbyte.git)‍

您需要通过运行 cd airbyte 进入克隆的 airbyte repo,然后运行:

docker-compose up

或者如果您使用的是最新版本的 Docker CLI,您可以运行:

docker compose up

上述命令将创建并启动 Airbyte 容器。完成后,您可以通过 http://localhost:8000/ 访问 Airbyte(您可以继续设置您的首选项,然后保持 Airbyte web 应用程序打开,我们很快会回来)

建立 Postgres 数据库

该数据库将是来自 GitHub 的数据的目的地。为了设置这个,我们将通过 docker 运行 postgres 容器,如下所示:

docker run --rm --name github-destination -e POSTGRES_PASSWORD=password -p 3003:5432 -d postgres‍

如果您是第一次运行上述命令,它将从 Docker Hub 注册表下载 Postgres 映像,然后将其作为名为 github-destination 的容器运行。

我们还通过将环境变量 POSTGRES_PASSWORD 传递给密码值来设置数据库密码。

我们还将容器的 5432 端口绑定到 3003 端口上的主机。最后,我们在后台运行带有-d 标志的容器。

现在我们已经建立了目标数据库,让我们转到 Airbyte web 应用程序,并创建一个从 Airbyte GitHub 源到 Postgres 数据库的连接。

创建 Airbyte 连接

回到浏览器中的 Airbyte web 应用程序,单击应用程序右上角的新来源按钮,进入添加新 Airbyte 来源的页面。

输入名称 github-source 作为信号源名称,点击下拉菜单,选择 Github connector 作为信号源类型。选择 GitHub 源类型后,您将看到两个文本框。首先是输入您想要的存储库。在这个框中,键入 airbytehq/airbyte ,然后,在第二个框中,您需要提供一个 GitHub 访问令牌,您可以从这里的获得。

确保您授予令牌 repo 和 write:discussion 权限。填写完所有字段后,点击“设置来源”按钮。

如果设置成功,您将被带到目的地屏幕,在那里您将添加一个新的目的地。

点击添加目的地按钮,在随后的下拉菜单中,点击添加新目的地。然后,您将看到一个添加目的地名称的页面。输入我们之前创建的 Postgres 容器的名称(github-destination),然后选择 Postgres 作为目的地类型。

之后,您将看到一些文本框,用于输入数据库连接的详细信息。为我们之前创建的 Postgres 容器输入值:

  • 主机—本地主机
  • 3003 年后
  • 模式-公共(保留默认值)
  • 数据库— postgres
  • 密码—密码
  • 用户名— postgres

然后点击基本的标准化切换按钮来检查它,因为我们希望 Airbyte 标准化来自 GitHub 的数据。总的来说,用户界面应该是这样的:

作者图片

然后点击设置目的地按钮。如果您的凭证对于数据库来说都是正确的,那么 postgres 目的地应该已经设置好了,现在您需要建立从源(GitHub)到目的地(Postgres)的连接。

您应该选中下面截图中的复选框,然后在同步频率下拉列表中选择 Airbyte 每小时尝试复制数据的频率。然后,点击设置连接按钮。

作者图片

您将被带到源页面,单击源,您将看到您的同步状态。同步需要一段时间才能完成。

完成后,您将看到状态从运行更改为成功。此外,字节数指的是 Airbyte 从 GitHub 提取到 Postgres 数据库中的数据字节。‍

那不是很多工作,是吗?你可以拍拍自己的背,因为你刚刚将数据从 GitHub 同步到 Postgres 数据库。

让我们继续将该数据库连接到元数据库,这样我们就可以开始创建我们的仪表板了。

步骤 2:将 PostgreSQL 数据库连接到元数据库

正在安装元数据库


Metabase 是一个开源的分析工具,你可以通过几种方式开始使用它;使用。jar 文件,将其安装为 Mac 应用程序或使用 Docker 容器。

在本教程中,我们将使用 Mac 应用程序(你也可以在这里找到适合你的安装)。为此,只需运行:

如果你用的是 Mac,你可以从这里下载元数据库应用。下载后,启动应用程序并完成帐户注册,您将看到元数据库仪表板:

作者图片

在元数据库中设置 Postgres 数据库

为了设置我们的数据库,我们将单击 Metabase 应用程序菜单栏上的 cog(设置)图标,并选择 admin 选项以进入 admin 视图,我们可以在其中添加数据库:

作者图片

单击 add a database 按钮,您将看到一个表单,您应该选择 PostgreSQL 作为您选择的数据库,然后填写连接参数,这将是我们为保存来自 GitHub 的数据而创建的 PostgreSQL 数据库的参数

填写详细信息,以匹配我们之前创建的 PostgreSQL 数据库的凭据。‍

作者图片

然后,当您输入完数据库凭据后,单击 save,您的数据库将被完全加载到元数据库中,为我们开始创建仪表板做好准备。

步骤 3:在元数据库中创建仪表板

Metabase 基于对数据的提问,因此为了构建我们的 GitHub 仪表板,我们将提出以下问题:

  • 每天都有新的天文学家
  • 贡献了新的问题
  • 每天 PR 贡献者的数量
  • 每天来自非团队成员的新评论
  • 每天来自非团队成员的新问题

每天都有新的天文学家

注意:我们通常需要处理日期时间类型,以便为我们的仪表板找到演化度量,所以如果您注意到您需要的字段不是合适的类型,比如 starred_atVARCHAR 类型而不是数据时间,您可以转到元数据库中的管理视图,单击数据模型选项,并告诉元数据库转换该字段

因此,我们将使用 Metabase 的一般工作流程是单击菜单栏顶部的提问按钮。然后选择你想问的问题类型。我们将从一个简单的问题开始:

作者图片

然后你选择你想要处理的数据。如果一切配置正确,应该会出现一个名为 Airbyte_GitHub 的数据源。然后让我们选择我们想要使用的表,因为对于第一个问题,我们想要观星者的数量,我们选择观星者表。‍

作者图片

然后,您将看到所选表格中的数据。对于这第一个,我们将看到 Stargazers 表中的数据。‍

作者图片

为了计算我们第一个问题的答案,点击“总结”按钮,按分组,以开始,按计数总结,然后你就有了第一个问题的答案:一天中新的观星者的数量。

作者图片

点击右上角的蓝色保存按钮来保存问题,并确保你在线模式下进行可视化。保存时,Metabase 会提示您将其添加到仪表板中,这正是我们想要的!‍

作者图片

点击创建一个新的仪表板,命名您的仪表板,并点击创建。然后,您可以根据自己的情况调整仪表板卡的大小,点击保存,我们的第一个问题就有了答案!

作者图片

对于我们需要问的其余问题,步骤非常相似,因此我们将只提及我们正在使用的表,并显示可视化以及我们在到达那里时使用的设置。

公关人员数量的变化

表:拉取请求

作者图片

发行人数量的演变

表格:问题

作者图片

来自非团队成员的新评论数量的变化

表:注释

我们将使用“作者关联”字段过滤掉合作者的任何评论。

作者图片

来自非团队成员的新问题数量的变化

表:问题

作者图片

结束了。

在本文中,我们使用 GitHub Airbyte 连接器从 GitHub repo 获取数据,并将数据存储在 PostgreSQL 数据库中。然后,我们设置元数据库,并提出问题来可视化数据。

这是 GitHub 仪表板的成品,带有我们在 Metabase 上的可视化效果:

作者图片

额外学分

以下是使用相同过程可以获得答案的其他问题:

  • 来自非团队成员的#新评论的演变
  • 来自非团队成员的#新问题的演变
  • 来自非团队成员的#新 PRs 的演变
  • 非团队成员互动的首次评论时间(第 50、90 百分位)
  • PR 第一次审核前的时间(第 50、90 百分位)

最初发表于 Airbyte

如何用 Neo4J 和变形金刚搭建知识图

原文:https://towardsdatascience.com/how-to-build-a-knowledge-graph-with-neo4j-and-transformers-72b9471d6969?source=collection_archive---------2-----------------------

使用自定义命名实体识别和关系提取模型

图片作者:Neo4j 中的知识图谱

介绍

在我的上一篇文章“使用 BERT Transformer 构建求职知识图”中,我们探讨了如何使用定制 Transformer 模型提取的实体和关系,从职位描述中创建知识图。虽然我们能够使用 Python 库 networkX 获得节点和关系的良好视觉效果,但实际的图形存在于 Python 内存中,而不是存储在数据库中。当试图创建一个可伸缩的应用程序时,这可能会有问题,因为您必须存储一个不断增长的知识图。这就是 Neo4j 的优势所在,它使您能够将图表存储在一个功能齐全的数据库中,从而允许您管理大量数据。此外,Neo4j 的 Cypher 语言丰富,易于使用,非常直观。

在本文中,我将展示如何使用基于转换器的命名实体识别(NER)和 spacy 的关系提取模型,从工作描述中构建知识图。这里描述的方法可以用于任何不同的领域,例如生物医学、金融、保健等。

以下是我们将要采取的步骤:

  • 在 google colab 中加载我们微调过的变压器 NER 和空间关系提取模型
  • 创建一个 Neo4j 沙箱并添加我们的实体和关系
  • 查询我们的图表,找到与目标简历最匹配的工作,找到三个最受欢迎的技能和最高技能的共现

有关如何使用ubai生成训练数据以及微调 NER 和关系提取模型的更多信息,请查看以下文章:

  • 【UBIAI 简介:面向自然语言处理应用的易用文本注释
  • 如何使用具有空间 3 的 BERT 变换器训练联合实体和关系提取分类器
  • 如何用空间 3 微调 BERT 变压器

工作描述数据集在 Kaggle 中公开。

在本教程结束时,我们将能够创建如下所示的知识图。

作者图片:职位描述知识图

命名实体和关系抽取

  • 首先,我们加载 NER 和关系模型的依赖关系以及 NER 模型本身,该模型之前已经过微调,可以提取技能、文凭、文凭专业和多年经验:

  • 加载我们要从中提取实体和关系的作业数据集:

  • 从作业数据集中提取实体:

在将提取的实体输入到关系提取模型之前,我们可以先看一下这些实体:

[('stock market analysis', 'SKILLS'),
 ('private investor', 'SKILLS'),
 ('C++', 'SKILLS'),
 ('Investment Software', 'SKILLS'),
 ('MS Windows', 'SKILLS'),
 ('web development', 'SKILLS'),
 ('Computer Science', 'DIPLOMA_MAJOR'),
 ('AI', 'SKILLS'),
 ('software development', 'SKILLS'),
 ('coding', 'SKILLS'),
 ('C', 'SKILLS'),
 ('C++', 'SKILLS'),
 ('Visual Studio', 'SKILLS'),
 ('2 years', 'EXPERIENCE'),
 ('C/C++ development', 'SKILLS'),
 ('data compression', 'SKILLS'),
 ('financial markets', 'SKILLS'),
 ('financial calculation', 'SKILLS'),
 ('GUI design', 'SKILLS'),
 ('Windows development', 'SKILLS'),
 ('MFC', 'SKILLS'),
 ('Win', 'SKILLS'),
 ('HTTP', 'SKILLS'),
 ('TCP/IP', 'SKILLS'),
 ('sockets', 'SKILLS'),
 ('network programming', 'SKILLS'),
 ('System administration', 'SKILLS')]

我们现在准备预测关系;首先加载关系提取模型,确保将目录更改为 rel_component/scripts,以访问关系模型所需的所有脚本。

cd rel_component/
Predicted relations:  entities: ('5+ years', 'software engineering') --> predicted relation: {'DEGREE_IN': 9.5471655e-08, 'EXPERIENCE_IN': 0.9967771}  entities: ('5+ years', 'technical management') --> predicted relation: {'DEGREE_IN': 1.1285037e-07, 'EXPERIENCE_IN': 0.9961034}  entities: ('5+ years', 'designing') --> predicted relation: {'DEGREE_IN': 1.3603304e-08, 'EXPERIENCE_IN': 0.9989103}  entities: ('4+ years', 'performance management') --> predicted relation: {'DEGREE_IN': 6.748373e-08, 'EXPERIENCE_IN': 0.92884386}

Neo4J

我们现在准备将我们的作业数据集和提取的数据加载到 neo4j 数据库中。

  • 首先,启动一个 neo4j 空白沙箱并添加您的连接细节,如下所示:

  • 接下来,我们将文档、实体和关系添加到知识图中。请注意,我们需要从实体 EXPERIENCE 的名称中提取整数年数,并将其存储为一个属性。

现在开始有趣的部分。我们准备启动知识图并运行查询。让我们运行一个查询来查找与目标概要文件最匹配的职务:

以表格形式显示常见实体的结果:

在图形可视化中:

作者图片:基于最佳工作匹配

虽然该数据集仅由 29 个职位描述组成,但是这里描述的方法可以应用于具有数千个职位的大规模数据集。只需几行代码,我们就可以立即提取与目标概要文件最匹配的职务。

让我们找出最受欢迎的技能:

query = """MATCH (s:SKILLS)<-[:MENTIONS]-(o:Offer)RETURN s.name as skill, count(o) as freqORDER BY freq DESCLIMIT 10"""res = neo4j_query(query)res

和需要最高年经验的技能:

query = """MATCH (s:SKILLS)--(r:Relation)--(e:EXPERIENCE) where r.type = "EXPERIENCE_IN"return s.name as skill,e.years as yearsORDER BY years DESCLIMIT 10"""res = neo4j_query(query)res

网站开发和支持需要最高年的经验,其次是安全设置。

最后,让我们检查一下最常出现的一对技能:

neo4j_query("""MATCH (s1:SKILLS)<-[:MENTIONS]-(:Offer)-[:MENTIONS]->(s2:SKILLS)WHERE id(s1) < id(s2)RETURN s1.name as skill1, s2.name as skill2, count(*) as cooccurrenceORDER BY cooccurrenceDESC LIMIT 5""")

结论:

在这篇文章中,我们描述了如何利用基于变形金刚的 NER 和斯帕西的关系提取模型,用 Neo4j 创建知识图。除了信息提取之外,图拓扑可以用作另一个机器学习模型的输入。

将 NLP 与 Neo4j 的 graph DB 结合起来,将会加速许多领域的信息发现,在医疗保健和生物医学领域有更显著的应用。

如果您有任何问题或想要为您的特定案例创建定制模型,请在下面留言或发送电子邮件至 admin@ubiai.tools。

在推特上关注我们 @UBIAI5

如何在 macOS 上使用 Django 和 Visual Studio 代码构建 Lotto Generator Web 应用程序

原文:https://towardsdatascience.com/how-to-build-a-lotto-generator-web-application-using-django-and-visual-studio-code-on-macos-91307d48165c?source=collection_archive---------25-----------------------

WEB 开发

使用 Django 构建有趣的项目

照片由来自 Unsplash 的埃里克·麦克林拍摄

介绍

在本教程中,您将使用 Django 构建一个乐透生成器 web 应用程序。

Django 是一个 Python web 框架,它简化了 web 开发中的常见实践。它是可靠的,也有一个充满活力的稳定库生态系统,支持日常开发需求。

对于这个项目,您将使用 HTML、CSS 作为前端语言,Python 作为后端语言,Django 作为后端框架。在本教程结束时,您将拥有一个完全正常工作的应用程序,它允许您随机生成两组数字 LottoMax 和 649 。你可以在这里看到现场演示。

App UI(图片来自作者)

注意:本教程的源代码可以在 GitHub 上获得。

先决条件

要完成本教程,您需要:

  1. 安装并设置 Python 3 的本地编程环境。
  2. 使用 MacOS 操作系统。
  3. 安装 Visual Studio 代码。

警告:本教程中提供的代码是用于教育目的,而不是用于生产用途。

步骤 1——创建 Django 项目。

  1. 在您的终端中运行以下命令来创建一个 Django 项目。
django-admin startproject <PROJECT_NAME>

2.通过以下方式进入项目文件夹:

cd <PROJECT_NAME>

3.运行以下代码启动一个应用程序:

python3 manage.py startapp <APP_NAME>

现在您已经创建了一个基本的 Django 应用程序。您可以运行以下命令来查看本地计算机上的 web 应用程序。

python3 manage.py runserver

你的 Django app 将在 http://127.0.0.1:8000/ 开发。在这一步,web 应用程序将如下图所示。

图片来自作者

输入 Control+C 退出服务器。

步骤 2—创建虚拟环境。

在这一步,您将创建一个虚拟环境(env)来存储这个特定项目的所有依赖项。

  1. 如果您没有安装 virtualen ,运行以下命令在您的终端中安装环境。
pip install virtualenv

2.在安装了 virtualen 之后,运行下面的代码来创建一个 env。

virtualenv <ENV_NAME>

在<env_name>中替换您的 env 的名称</env_name>

3.通过以下方式激活环境:

source <ENV_NAME>/bin/activate

您可以在需要时使用以下命令移除 env:

sudo rm -rf <ENV_NAME>

现在你的 env 已经准备好了。是时候建造一些有趣的东西了!

步骤 3—在根目录中配置 settings.py 和 urls.py

现在,在 visual studio 代码中打开 Django 项目文件夹。

您应该会看到这样的项目结构:

你的 Django 项目的结构(图片来自作者)

我使用“Lotto”作为我的项目名,“app”作为应用名,“env”作为环境名。

  1. 在您的根目录(在我的例子中是文件夹“Lotto ”)中,单击 setting.py,并将您的 APP_NAME 添加到 INSTALLED_APPS。

图片来自作者

2.在同一个文件夹中,点击 urls.py,导入库 include 并将应用中的所有 URL 添加到 urlpatterns 。urls.py 将如下所示:

图片来自作者

第 4 步—添加模板。

  1. 在你的 app 目录下,新建一个名为templates的文件夹。 Django 依靠模板动态生成 HTML。在模板中,请新建一个与你的 APP_NAME 同名的文件夹(在我这里是 app ),然后在这个文件夹中新建一个名为【index.html 的文件。您将在这个 HTML 文件中构建您的网页。
  2. 由于我们正在建立一个乐透生成器应用程序,我们希望应用程序随机生成符合乐透最大值和 649 规则的数字集,所以在网页上,我们需要两个按钮,单击按钮,生成的数字将出现在屏幕上。你可以基于这个目的或者按照下面的代码来构建应用程序:

index.html(图片来自作者)

3.你还需要导入库来使用 Jquery 和 Bootstrap,关于 HTML 文件的完整代码请参考 Github Repo (我在 Repo 中做了三个按钮,但是对于我们的教程两个就够了)。

4.在您的 APP_NAME 中创建一个名为 static 的新文件夹,然后创建一个与您的 APP_NAME 同名的新文件夹。在这个文件夹中,创建你的 CSS 文件。静态文件夹用于保存所有的静态文件,包括图片、JavaScript 和 CSS 文件。

现在,Django 项目的结构应该是这样的:

你的 Django 项目的结构(图片来自作者)

步骤 5—添加视图

  1. 在你的 app 目录下,创建一个名为 predict.py 的文件,生成一定范围内的随机数。

predict.py(图片来自作者)

2.单击 views.py,开始在这里创建视图。

每个视图都是一个 Python 函数,接受 Web 请求并返回 Web 响应。视图本身包含返回响应所需的任意逻辑。

对于 Lotto Generator 应用程序,我们将构建一个视图函数来返回两个列表:一个用于 Lotto Max,它将返回 1 到 50 范围内的 7 个随机数,一个用于 649,它将返回 1 到 50 范围内的 6 个随机数。

您的 view.py 将如下所示:

from django.shortcuts import renderfrom . import predictimport numpy as npimport pandas as pdimport random# Create your views here.def index(request):MaxLotto_range = range(1,51)MaxLotto = predict.lotto(MaxLotto_range, 7)MaxLotto = sorted(MaxLotto) six49_range = range(1, 50)six49 = predict.lotto(six49_range, 6)six49 = sorted(six49) return render(request, 'app/index.html',{"MaxLotto": MaxLotto,"six49": six49})

第 6 步—添加 urls.py

最后,在您的 app 目录中添加一个名为 urls.py 的新文件,并添加与您创建的 Python 函数(您的视图)对应的所有 URL 路径。

from django.urls import include, pathfrom . import viewsurlpatterns = [path("", views.index, name="index"),]

万岁!您的应用程序已经可以运行了!

第 6 步—运行应用程序

在您的终端上运行以下命令:

python3 manage.py runserver

Ops 似乎还没有安装依赖项。

让我们先安装它们。

在您的终端中:

 pip install Django numpy pandas

然后,跑

python3 manage.py runserver

您的终端将显示:

运行后的终端(图片来自作者)

我们把网址(http://127.0.0.1:8000/)复制粘贴到你的浏览器,看看你都建了什么!

看到了吗?然后点击按钮。现在你有你的乐透发电机运行!

结论

在本文中,您将使用 Django 和 VS 代码从头开始构建一个乐透生成器。您在根目录中配置了 settings.py 和 urls.py,在 app 目录中添加了模板、静态文件和 urls.py,并在 views.py 中创建了一个函数,该函数带有您创建的帮助器函数,用于生成随机数。

如果你想了解更多关于使用 Django 建立机器学习模型或个人投资组合的信息,欢迎访问我的 GitHub repo 或在下面发表评论。我很乐意把我一路走来学到的东西分享给公众,以尽量减少你花在搜索 Google 和 StackOverflow 上的时间。

在 Linkedin 上向我问好。

如何使用 Flask 构建机器学习 API

原文:https://towardsdatascience.com/how-to-build-a-machine-learning-api-using-flask-2fb345518801?source=collection_archive---------4-----------------------

让我们把你的 ML 模型应用到现实生活中吧!

卢卡·布拉沃在 Unsplash 上的照片

介绍

机器学习(ML)是一种很好的方式来完成无法显式编码的任务,例如图像分类。但是当模型已经构建好了,如果我们不把它部署到应用程序中,它就没有用了。

部署是机器学习工作流中的一个重要步骤。这是我们希望将 ML 模型应用到应用程序中的一个步骤。之后,我们可以在现实生活中使用该模型。

但是我们如何将模型创建为应用程序呢?我们可以构建一个应用编程接口(API)。有了它,我们可以从任何地方访问模型,无论是在移动应用程序上还是在 web 应用程序上。在 Python 中,有一个库可以帮助我们构建 API。它叫烧瓶。

本文将向您展示如何使用 Flask 为我们的机器学习模型构建 REST API。事不宜迟,我们开始吧!

REST API

在我们进入实现之前,让我解释一下 REST API。REST API 代表表述性状态转移应用程序编程接口。

REST API 的机制是这样的。假设你想在谷歌上搜索猫的照片。第一步是向谷歌发送一个请求,给他们一个类似“猫照片”的查询。然后,服务器会给你的电脑发送一个响应,就是猫咪照片的汇编。

关于 REST API 就这些了!这是作为客户端的你们之间的交流方式,通过向服务器请求一些东西,然后服务器会向你发送响应。下面是 REST API 如何工作的一个例子。

这个形象是作者创造的

履行

现在您已经理解了 REST API 的基本概念。让我们进入使用 Flask 的实现。我们将介绍几个流程:

  1. 导入库
  2. 加载机器学习模型
  3. 构建预处理和预测图像的函数
  4. 初始化 flask 对象
  5. 设置向用户浏览器返回某些内容的路径和函数
  6. 运行并测试 API

导入库

第一步是加载库。我们将导入的库是 TensorFlow、Flask、Pillow 和其他支持库。如果没有安装这些库,可以使用 pip 命令进行安装。

以下是导入库的代码:

加载模型

加载库之后,下一步是加载机器学习模型。在这种情况下,我将使用我的图像分类器模型,在使用 TensorFlow 之前,我已经对它进行了预训练。该模型将预测图像是否包含食物。

下面是加载模型的代码:

旁注:
如果你在 GPU 上训练模型,想在 CPU 上运行它们,也没问题。TensorFlow 支持这一点,你根本不需要调整模型。

构建预处理和预测图像的函数

加载模型后,下一步是创建函数来处理图像。因为我们将从客户端的请求中获取图像,所以我们将使用 io。BytesIO 函数将图像加载到我们的 Python 代码中。之后,我们只需要调用。从我们的模型预测函数来预测结果。

下面是预处理和预测图像的代码:

初始化 flask 对象

构建完函数后,现在让我们初始化 Flask 对象。此外,我们在 Flask 对象参数上设置名称。这一步是为了确保运行 web 应用程序时 python 脚本是可读的。

下面是执行该操作的命令:

设置路线和功能

现在让我们设置路线和我们想要运行的功能。路由是访问网络上特定功能的一种方式。当我们访问路由时,它将运行一个函数,并将消息返回给用户。

基于超文本传输协议(HTTP)方法,每条路由都有不同的交互方式。我们可以使用几种 HTTP 方法。

第一个是 GET 方法,我们只访问路由,不发送任何数据。第二个是 POST 方法。在这个方法中,我们可以访问路由,也可以向它发送数据。

还有像 PUT、PATCH 和 DELETE 方法这样的方法。但我们不会进一步谈论它。这次我们将只使用 GET 和 POST 方法。

现在让我们创建两条路线。第一个是“/”路由路径。该路由将返回 API 的欢迎消息。因此,我们会给这个路由一个 GET 方法。

第二个是“/predict”路由路径。该路径将从图像返回预测结果。我们将使用 POST 方法将图像发送到路由中。此外,我们需要设置密钥,这样应用程序就可以知道图像在哪里。我们将使用“file”键作为图像文件的标识符。

以下是设置路线及其功能的代码:

运行 API

在我们构建了函数和它们的路径之后,现在让我们运行 API。但是在我们运行 API 之前还有最后一步。我们需要添加。像这样将方法路由到我们的代码中:

现在转到您的终端,运行以下命令之一(确保您与 API 文件位于同一路径):

**flask run**OR**python app.py**

如果您运行该命令,它将返回如下结果:

从上面可以看到,它显示了来自 TensorFlow 的几个日志。别担心。这只是一个我们可以忽略的警告。只要你能看到“正在运行”的消息,就意味着你的 API 正在运行。

现在我们通过地址 http://127.0.0.1:5000/ 访问 API,其中 127.0.0.1 是你的本地地址,5000 是访问 API 的端口号。如果它成功了,它会在网上这样显示:

太好了!我们的 API 完美启动。让我们试试 API,看它能不能预测一个图像里面有没有食物。我们可以使用一个名为 Postman 的应用程序来测试我们之前创建的 API。你可以在这里下载。

这是结果的预览,

结束语

从上面可以看出,API 可以捕捉图像并返回预测结果。意味着我们的 API 已经在工作了。干得好!

现在,您已经使用 Flask 构建了机器学习 API。我希望这篇文章能帮助你理解 REST API 的概念。此外,它还可以指导您在自己的项目中开发自己的 API。

如果你对这篇文章感兴趣,你可以关注我的媒体以获得更多类似的文章。此外,如果您有任何问题或想与我交谈,您可以在 LinkedIn 上与我联系。

如果您仍然困于编写 API,这里是 API 的完整代码,

谢谢你看我的文章!

参考

[1]https://www . smashingmagazine . com/2018/01/understanding-using-rest-API/

如何用 Python 构建机器学习 App

原文:https://towardsdatascience.com/how-to-build-a-machine-learning-app-a9dfed2616fb?source=collection_archive---------9-----------------------

由 envato elements 的 alexdndz 使用图像创建(经许可)。

数据科学 | 机器学习

< 150 lines of Python code

Have you ever wished for a web app that would allow you to build a machine learning model automatically by simply uploading a CSV file? In this article, you will learn how to build your very own machine learning web app in Python in a little over 100 lines of code.

The contents of this article is based on a YouTube video by the same name that I published a few months ago on my YouTube channel (数据教授中从头开始的一步一步教程),作为本文的补充。

如何搭建机器学习 App | Streamlit # 13@数据教授 YouTube 频道

模型部署的重要性

在深入探讨之前,让我们先退后一步,看看全局。数据收集、数据清理、探索性数据分析、模型构建和模型部署都是数据科学生命周期的一部分。以下是生命周期的摘要信息图:

数据科学生命周期。(由 Chanin Nantasenamat 又名数据教授绘制)

作为数据科学家或机器学习工程师,能够部署我们的数据科学项目以完成数据科学生命周期对我们来说至关重要。使用 Django 或 Flask 等已建立的框架部署机器学习模型可能是一项艰巨和/或耗时的任务。

机器学习应用概述

概括地说,我们今天要构建的 web 应用程序本质上将接受一个 CSV 文件作为输入数据,应用程序将使用它来构建一个使用随机森林算法的回归模型。

现在,让我们详细了解一下 web 应用程序前端和后端的情况。

前端

用户可以将自己的数据集上传为 CSV 文件,还可以调整学习参数(在左侧面板中),调整这些参数后,将构建一个新的机器学习模型,然后显示其模型性能(在右侧面板中)。

机器学习 app 的解剖。左侧面板接受输入,右侧面板显示结果。

上传 CSV 数据作为输入
CSV 文件的第一行应该有一个标题(包含列名),随后是数据集的后续行(第 2 行及之后)。我们可以看到,在左侧面板的上传框下方有一个到示例 CSV 文件的链接( 示例 CSV 输入文件 )。让我们看看下面显示的这个示例 CSV 文件:

应用程序中链接的示例 CSV 文件的前几行摘录。

调整学习参数
上传 CSV 文件后,你应该可以看到已经建立了一个机器学习模型,其结果显示在右边的面板中。应当注意,该模型是使用默认参数构建的。用户可以通过滑块输入来调整学习参数,每次调整都会建立一个新的模型。

模型输出(右侧面板)

在右侧面板中,我们可以看到显示的第一个数据是 1 中的输入数据帧。数据集部分及其结果将显示在 2 中。型号性能部分。最后,模型构建中使用的学习参数在 3 中提供。型号参数部分。

上传输入 CSV 文件后建立的模型。

至于模型性能,显示了训练集和测试集的性能度量。由于这是一个回归模型,决定系数(R^2)and 误差(均方误差或平均绝对误差)。

后端

现在,让我们从更高的层面来看看这款应用的内部工作原理。

上传输入 CSV 文件后,该文件的内容将被转换成 Pandas 数据帧并赋给df变量。然后,数据帧将被分成Xy变量,以准备作为 Scikit-learn 的输入。接下来,这两个变量用于使用用户在左侧面板中指定的值进行数据分割(默认情况下使用 80/20 分割比率)。关于数据分割维度和列名的详细信息打印在应用程序前端的右侧面板中。然后,使用主要子集(80%子集)构建随机森林模型,并应用构建的模型对主要子集(80%)和次要子集(20%)进行预测。然后,该回归模型的模型性能被报告到 2 下的右侧面板中。模型性能部分

本教程中使用的技术堆栈

这将只使用 3 个 Python 库来实现,包括 Streamlit、Pandas 和 Scikit-learn。

Streamlit 是一个易于使用的 web 框架,允许您立即快速实施数据驱动的应用程序。

Pandas 是一个数据结构工具,可以处理、操作和转换表格数据集。

Scikit-learn 是一个强大的工具,它为用户提供了构建机器学习模型(即,可以执行各种学习任务,包括分类、回归和聚类)的能力,并配备了示例数据集和特征工程功能。

逐行解释

这个应用程序的完整代码如下所示。代码跨度为 131 行,为了使代码可读,在注释行旁边添加了空格。

第 1–6 行

  • 从 scikit-learn 库中导入由streamlitpandas和各种函数组成的必备库。

第 8–12 行

  • 第 8–10 行:注释解释了第 11–12 行的作用。
  • 第 11–12 行:使用st.set_page_config()功能设置页面标题及其布局。在这里,我们可以看到我们将page_title设置为'The Machine Learning App’,而layout设置为'wide’,这将允许应用程序的内容适合浏览器的整个宽度(即,否则默认情况下,内容将被限制在固定宽度)。

第 14–65 行

  • 第 14–15 行:解释第 16–65 行的注释。
  • 第 16 行:这里我们定义了一个名为build_model()的自定义函数,下面从第 17 行开始的语句将指示这个函数将做什么
  • 第 17-18 行:存储在df变量中的输入数据帧的内容将被分成两个变量(XY)。在第 17 行,除了最后一列之外的所有列都将被分配给X变量,而最后一列将被分配给Y变量。
  • 第 20–21 行:第 20 行是注释,说明第 21 行在做什么,就是使用train_test_split()函数对输入数据(存储在XY变量中)进行数据拆分。默认情况下,数据将以 80/20 的比例分割,80%的子集将分配给X_trainY_train,而 20%的子集将分配给X_testY_test
  • 第 23–27 行:第 23 行使用 Markdown 语法将1.2\. Data splits打印为粗体文本(也就是说,在这里我们可以看到,我们在短语之前和之后使用了**符号,我们希望使文本像在**1.2\. Data splits**中一样粗体)。接下来,我们将打印XY变量的数据维度,其中第 24 行和第 26 行将使用st.write()函数打印出Training setTesting set,而第 25 行和第 27 行将使用st.info()函数打印出数据维度,方法是分别在X_trainX_test变量后添加.shape,如X_train.shapeX_test.shape所示。请注意,st.info()功能将在变量输出周围创建一个彩色框。
  • 第 29–33 行:与第 23–27 行的代码块类似,该代码块将打印出分别存储在X.columnsY.name中的 X 和 Y 变量名。
  • 第 35–43 行:RandomForestRegressor()函数将用于建立回归模型。构建随机森林模型的各种输入参数将使用应用程序前端左侧面板中的用户指定值(在后端,对应于第 82–97 行)。
  • 第 44 行:现在将使用rf.fit()函数训练模型,作为输入参数,我们将使用X_trainY_train
  • 第 46 行:使用st.subheader()功能将打印出2\. Model performance部分的标题。
  • 第 48–54 行:第 48 行使用st.markdown()功能打印2.1\. Training set的标题。第 49 行使用rd.predict()函数,使用X_test作为输入参数,应用训练模型对训练集进行预测。第 50 行打印要为决定系数(R2)打印的性能指标的文本。第 51 行使用st.info()函数,通过使用Y_trainY_pred_train(代表训练集的实际 Y 值和预测 Y 值)作为输入参数,经由r2_score()函数打印 R2 分数。第 53 行使用st.write()函数打印下一个性能指标的文本,这是错误。接下来,第 54 行通过使用Y_trainY_pred_train作为输入参数,使用st.info()函数通过mean_squared_error()函数打印均方误差值。
  • 第 56–59 行:这段代码执行完全相同的过程,但是它将在测试集上执行,而不是在训练集上执行。因此,不使用训练集数据(Y_trainY_pred_train),而是使用测试集数据(Y_testY_pred_test)。
  • 第 64–65 行:第 64 行使用st.subheader()功能打印标题3\. Model Parameters

第 67–75 行

此处将打印 web 应用程序的标题。第 68 行和第 75 行开始和结束使用st.write()函数以 Mardown 语法编写页面标题。第 69 行使用#符号将文本设为标题 1 大小(根据 Markdown 语法)。第 71 和 73 行将打印关于 web 应用程序的描述。

第 78–100 行

  • 这里描述了左侧工具条面板的几个代码块。第 78 行注释了接下来的几个代码块是关于什么的,哪个是用于收集用户指定输入的左侧边栏面板。
  • 第 79–83 行定义了 CSV 上传框。第 79 行通过st.sidebar.header()功能将1\. Upload your CSV data打印为标题。请注意,我们在stheader之间添加了.sidebar,以指定这个标题应该进入侧边栏。否则,如果它被写成st.header(),那么它将转到右边的面板。第 80 行将st.sidebar.file_uploader()函数分配给uploaded_file变量(即,该变量现在将表示用户上传的 CSV 文件内容)。第 81–83 行将打印到示例 CSV 文件的链接,用户可以使用该文件来测试应用程序(在这里,您可以随意用 CSV 文件格式的自定义数据集替换它)。
  • 第 85–87 行以注释开始,说明下面的代码块将与随机森林模型的参数设置有关。第 86 行然后使用st.sidebar.header()函数打印2\. Set Parameters作为标题文本。最后,第 87 行使用st.sidebar.slider()函数创建了一个滑动条,其中它的输入参数指定Data split ratio (% for Training Set)作为滑块的文本标签,而 4 组数值(10, 90, 80, 5)代表最小值、最大值、默认值和增量步长值。最小值和最大值用于设置滑动条的边界,我们可以看到最小值是 10(显示在滑动条的最左边),最大值是 90(显示在滑动条的最右边)。如果用户不调整滚动条,将使用默认值 80。增量步长将允许用户以步长 5(例如 75、80、85 等)递增或递减滑块值。)
  • 第 89–93 行定义了2.1\. Learning Parameters中学习参数的各种滑动条,与第 87 行描述的方式相似。这些参数包括n_estimatorsmax_featuresmin_samples_splitmin_samples_leaf
  • 第 95–100 行以类似于第 87 行描述的方式定义了2.2\. General Parameters中通用参数的各种滑动条。这些参数包括random_statecriterionbootstrapoob_scoren_jobs

第 102–103 行

注释:接下来的代码块将把模型输出打印到主面板或右侧面板中。

第 108–134 行

  • 应用 if-else 语句来检测 CSV 文件是否已上载。首次加载 web 应用程序时,它将默认为else语句,因为尚未上传任何 CSV 文件。加载 CSV 文件后,if语句被激活。
  • 如果else语句(第 113-134 行)被激活,我们将看到一条消息,显示Awaiting for CSV file to be uploaded以及一个可点击的按钮Press to use Example Dataset(稍后我们将解释这个按钮的作用)。
  • 如果if语句(第 108-112 行)被激活,上传的 CSV 文件(其内容包含在uploaded_file变量中)将被分配给df变量(第 109 行)。接下来,使用st.markdown()函数打印标题1.1\. Glimpse of dataset(第 110 行),然后打印df变量的数据帧内容(第 111 行)。然后,df变量中的 dataframe 内容将被用作build_model()自定义函数的输入参数(即前面第 14–65 行中描述的),在该函数中将构建随机森林模型,其模型结果将被显示到前端。

运行 web 应用程序

好了,现在 web 应用程序已经编写好了。让我们继续运行 web 应用程序。

创造康达环境

让我们假设您是从零开始,您将必须创建一个新的 conda 环境(这是一个确保代码可再现性的好主意)。

首先,在终端命令行中创建一个名为ml的新 conda 环境,如下所示:

conda create -n ml python=3.7.9

其次,我们将登录到ml环境

conda activate ml

安装必备库

首先,下载 requirements.txt 文件

wget [https://raw.githubusercontent.com/dataprofessor/ml-auto-app/main/requirements.txt](https://raw.githubusercontent.com/dataprofessor/ml-auto-app/main/requirements.txt)

其次,安装如下所示的库

pip install -r requirements.txt

下载机器学习 web 应用程序文件

现在,下载数据教授的 GitHub repo 上托管的 web 应用程序文件,或者使用上面找到的 134 行代码。

wget [https://github.com/dataprofessor/ml-app/archive/main.zip](https://github.com/dataprofessor/ml-app/archive/main.zip)

然后解压缩内容

unzip main.zip

进入main目录

cd main

现在你在main目录中,你应该能够看到ml-app.py文件。

启动 web 应用程序

要启动应用程序,请在终端命令行中键入以下内容(即,还要确保ml-app.py文件位于当前工作目录中):

streamlit run ml-app.py

稍后,您将在终端提示符下看到以下消息。

> streamlit run ml-app.pyYou can now view your Streamlit app in your browser.Local URL: http://localhost:8501
Network URL: http://10.0.0.11:8501

最后会弹出一个浏览器,你会看到应用。

机器学习 web app 截图。

恭喜,您现在已经创建了机器学习 web 应用程序!

接下来呢?

要使您的 web 应用程序对全世界公开和可用,您可以将其部署到互联网。我在 YouTube 上制作了一个视频,展示如何在 HerokuStreamlit Sharing上做到这一点。

  • 如何将数据科学 Web App 部署到 Heroku
  • 如何部署 Data Science Web App 以简化 it 共享

订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我做的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。

https://www.youtube.com/dataprofessor

在社交网络上与我联系

YouTube:【http://YouTube . com/data proper/
网站:【http://data proper . org/【正在建设】
LinkedIn:【https://www . LinkedIn . com/company/data proper/

如何免费构建现代数据堆栈

原文:https://towardsdatascience.com/how-to-build-a-modern-data-stack-for-free-e1e983963062?source=collection_archive---------14-----------------------

没有工程团队的创业者的简单指南

阿克森在 Unsplash 上拍照

从大型企业到早期创业公司,各种规模的公司都在处理数据。所有行业的企业,无论是零售、金融还是教育,都面临着一个共同的分析挑战:如何最好地了解他们产品的市场?在一个经济学家称数据为数字经济最有价值的资源的世界里,那些释放数据价值的人将在竞争中脱颖而出。

对于初创公司来说,有时你需要对你的产品、市场和客户进行详细的研究,以做出战术性的商业决策,从而保持领先地位。这包括从各种数据源收集数据,如脸书等营销平台、谷歌分析的网络流量数据和您自己的应用程序数据,将这些数据集成到一个集中的平台,并创建报告和仪表板。

应对这些挑战的最常见的解决方案需要一大套工具,每个工具执行一组单独的流程。这通常需要数据工程团队学习、构建、操作和监控数据管道,这为多点故障创造了机会,并且需要一个漫长的过程来获取可用格式的数据。

没有资源或资金来雇佣技术团队来构建和管理整个工作流程的小公司正在错过他们的数据金矿。幸运的是,我们看到越来越多的工具迎合技术含量较低的用户,如摄取即服务工具,它可以使用拖放或转换工具从各种来源收集数据,这些工具只需要 SQL 知识。

本文将指导如何在不需要数据工程团队的情况下,以非常低的成本(甚至没有成本)构建现代数据堆栈。在高层次上,它遵循许多成功公司使用的设计原则。这不是一个技术指南,而是对数据生态系统中存在的工具以及如何将它们组合在一起的介绍。

例如,我们将专注于可以与 Google 云平台一起使用的工具,但是非常欢迎您为我将在每个部分列出的其他产品切换工具。

事不宜迟,我们开始吧!

现代数据堆栈

现代数据堆栈管道(来源:https://venturebeat . com/2020/10/21/the-2020-Data-and-ai-landscape/)

现代数据栈(MDS)是一套以云平台上强大的数据仓库为中心的工具。它通常由四个阶段组成:

  1. 收集:从各种数据源收集数据的摄取阶段,这些数据源包括数据库、web 应用程序和 API。
  2. 加载:一个基于云的数据仓库,数据被加载到其中。
  3. 转换:用于清理原始数据和应用业务逻辑的转换工具。
  4. 分析:终端用户可以使用数据创建报告,并通过可视化工具收集见解。

让我们看看每个阶段,看看我们可以使用什么工具来创建我们自己的现代数据堆栈。

请阅读最后部分,了解如何申请高达 20,000 美元的 GCP 信用来帮助您完成所有这些。

数据仓库

谷歌大查询(来源:https://cloud.google.com/bigquery)

数据仓库是来自多个来源的各种数据的中央存储区域。它允许您轻松地将任何规模的所有数据汇集在一起,并通过分析仪表盘、运营报告或高级分析为您的所有用户提供洞察。

大查询是 Google Cloud 的全托管企业数据仓库。它是为实现业务灵活性而设计的无服务器(不需要前期硬件配置或管理)高度可扩展(在几秒钟内查询大型数据集)经济高效(只需为使用付费)。

Big Query 的设置非常简单,可以通过 Google Cloud 控制台访问,不需要编程设置。一旦您创建了帐户和项目,它就会自动启用。官方指南可以在这里找到。

谷歌云每月免费提供 1TB 的查询 T21 和 10GB 的存储空间,这对一个刚刚开始数据之旅的公司来说绰绰有余。

该领域的其他竞争对手包括:

  • 雪花
  • 微软的 Azure Synapse 分析
  • 亚马逊的红移

摄取

摄入(来源:https://fivetran.com

现在我们已经有了数据仓库,我们需要一个摄取工具来从各种来源获取原始数据,如应用程序数据、社交媒体平台的营销数据和网站日志。

为了遵循 ELT 设计,我们将研究将数据直接加载到数据仓库的方法,而不是加载到其他存储产品,如数据库和云存储。

市场上的几个玩家提供了一个摄取即服务工具,包括 Stitch 、 Fivetran 和 Airbyte 。这些公司已经创建了连接脸书、Salesforce、Google Analytics 等热门资源的连接器。允许您通过 web UI 在几分钟内将数据接收到您的数据仓库中,这对于非技术人员来说非常有吸引力,可以快速访问他们的数据并专注于分析,而不是工程。

不幸的是,这些服务都有不同价格的付费模式。一般来说,定价结构基于配额和接收的行数。详细情况可以在他们的网站上找到。

因为这是一篇关于如何免费做这件事的文章…这里有一个你可以实现的解决方案,但是需要更多的技术知识和管理。

如果您正在寻找技术含量较低的实现,请随意跳过这一部分。

KOBU 机构在 Unsplash 上拍摄的照片

Singer 是一个开源框架,用于从数据源提取数据并将其加载到任何目的地(例如数据仓库)。你可以在他们的公共 GitHub 库中找到用 python 写的数据提取脚本的代码。

代码是开源的,这意味着任何人都可以在自己的项目中自由使用这些脚本。这个存储库由位于 Talend 的工程团队管理,开源社区对此做出了贡献。Stitch 使用相同的 Singer 代码来支持他们的产品,这意味着他们在其网站上提供的任何连接器都使用与 Singer 存储库中相同的代码。

当你使用 Stitch 的时候,你实际上是在为一个漂亮的、易于导航的 web UI 付费,它为每个连接器提供了一个调度程序,并且计算机为那个连接器运行 Singer 代码。

因此,我们的免费版本需要一个存储库来存储代码,计算资源来执行连接器的 Singer 代码,该连接器从数据源提取数据并将其加载到数据仓库,还需要一个调度器来触发该运行。

在 GCP 上,我们可以使用云资源存储库 来存储连接器的 Singer 代码。接下来,我们将构建一个 Docker 映像来安装执行 Singer 代码所需的 python 包,并将其存储在容器注册表中。

对于我们的计算,使用云运行,它用于在完全托管的无服务器平台上开发和部署可扩展的容器化应用。它使用按使用付费的结构,所以你只需在你的代码运行时付费,这使得它非常实惠。

最后,我们可以使用CloudScheduler来触发这个管道运行一个批处理作业,及时地将数据从我们的源复制到数据仓库。

有关运行无服务器批量加载的更详细的实践指南,请查看这篇文章。

在价格方面,云资源存储库对最多 5 个用户是免费的,你可以免费存储多达 50GB 的 T2。云调度程序每月给你 3 个免费工作。下表总结了 Cloud Run 提供的免费层。

云运行定价(来源:https://cloud.google.com/run/pricing

在我看来(和我的经验),如果你使用摄取即服务工具,可能会有更高的投资回报率,尤其是如果你是一个早期创业公司。您可以在一个中心位置访问数百个连接器,每个连接器都可以在几分钟内设置好,不需要管理或编程技能,节省了大量时间和精力。

转换

dbt 架构(来源:https://github.com/fishtown-analytics/dbt)

原始数据加载到数据仓库后,就可以进行转换了。在转换阶段,将一系列规则或函数应用于加载的数据。常见的转换任务包括重命名列、联接多个表和聚合数据。

dbt(数据构建工具)是一个命令行工具,使数据分析师和工程师能够更有效地转换他们仓库中的数据。使用 dbt,您可以在遵循软件工程原则的同时,用 SQL 编写数据转换代码,使其非常容易被分析师访问。最大的优势是分析师掌控整个分析工程工作流程,从编写代码到部署和文档。不需要雇佣数据工程师或 python 开发者。

dbt 是开源的,所以通过命令行界面(CLI)使用 dbt总是免费的。dbt 还提供名为 dbt Cloud 的付费服务,该服务提供各种功能,包括基于浏览器的 IDE、作业调度、CI/CD 构建、日志记录、快照等。这些功能中的大部分可以通过 CLI 版本实现,但是需要用户对 IDE 和 git 等更加熟悉。但没什么太难的。

幸运的是,dbt Cloud 为提供了一个永远免费的开发人员席位,这意味着如果你是一个单身创始人或者你已经雇佣了你的第一个分析师,你可以获得 dbt Cloud 的所有好处,而无需支付任何费用。

该领域的其他竞争对手包括:

  • 数据表单(最近被谷歌云收购)
  • Databricks (最近与谷歌云结成合作伙伴。Azure、AWS 上也支持)

分析学

谷歌广告概览报告示例(图片由作者提供)

最后但同样重要的是,我们有报告层,最终用户可以在其中访问他们的数据。分析师构建交互式仪表盘和报告来可视化他们的数据,从而做出更明智的业务决策。

Google Data Studio 是 GCP的免费数据可视化工具,可以将你的数据转化为信息丰富且完全可定制的仪表盘和报告。它将您的所有数据源同步到一个单一的报告体验中,使多个用户能够通过可视化创建和共享引人注目的故事。您可以轻松地将您的数据连接到几乎任何数据源,包括电子表格、社交媒体平台、谷歌广告、大查询等。

用户界面非常简单,易于浏览(尤其是如果你熟悉 Google Drive 的布局)。Data Studio 提供了各种各样的模板来帮助您入门,因此您不必从头开始构建。

Data Studio 提供了一整套可视化工具,您可以将它们添加到您的报告中,包括条形图、谷歌地图、数据透视表和图像等等。所有这些都是完全可定制的,能够使用拖放功能编辑可视化的格式和样式。

您可以通过电子邮件或共享报告链接,在企业内部以及与您的客户共享报告。用户可以被授予“查看”或“编辑”权限。

该领域的其他竞争对手包括:

  • 旁观者
  • 画面
  • 动力匕

结论

如果你能走到这一步,那就做得很好!我们高度概括了什么是现代数据堆栈,当前生态系统中有哪些工具可用,以及如何为您的公司构建一个工具。

现在,您已经准备好创建一个端到端的管道,从各种来源引入数据,转换数据,将其加载到一个数据仓库中,以便使用仪表板和自定义可视化进行报告。

如果你正在开始这个数据之旅,或者不确定从哪里开始,可以考虑申请谷歌云启动计划。该计划旨在通过为您提供利益和支持来帮助您茁壮成长,从而支持早期初创企业在谷歌云上建立业务。一些好处包括谷歌云积分、谷歌工作空间订阅(正式 G-Suite)、导师和技术培训资源等等。

之前,我在一家早期创业公司工作,通过这个项目,我能够获得价值 2 万美元的免费谷歌云积分,为期一年。

数据生态系统非常庞大,并且正在快速增长,因此希望本指南能让您了解现有的工具以及它们是如何组合在一起的。不言而喻,您最终设计和构建的堆栈取决于您公司的领域和用例。

随着数据的增长,将需要更多的自定义实施,这需要移出免费层,为资源付费,使用高级工具,并雇佣您的第一位工程师。但当你最终到达那里时,你很可能已经有了投资或现金流,所以是时候在数据之旅中迈出下一步了。

请在评论中告诉我,你是如何在启动时构建数据堆栈的。

如果你喜欢这篇文章,何不注册 medium,通过这个链接阅读更多精彩内容。

【https://medium.com/@jonathan.moszuti/membership】T5T6

如何从数据中构建叙事

原文:https://towardsdatascience.com/how-to-build-a-narrative-from-data-85e327940c13?source=collection_archive---------27-----------------------

数据新闻,数据科学讨论

根据设置-冲突-解决范例分析数据的一些技巧

图片来自 Pixabay

对于一个天生不会讲故事的数据科学家来说,从数据中构建一个故事并不容易。然而,通过遵循一些技巧,数据科学家可以从数据中提取知识,并基于数据构建精彩的故事。

我们用数据的形状来引导我们的焦点。

我们将分析这些数据,以便发现一些模式,这将是我们叙述的重点。

关键是一个数据叙述并不包含所有的数据,而只包含有趣的数据,也就是那些吸引观众注意力的数据!

正如这个奇谈中所描述的,每一个产生巨大影响的故事都遵循三个步骤:

  • 设置 —上下文,事情发生前的情况;
  • 冲突——一个事实,它的发生改变了现状。在商业和金融领域,这种冲突也被称为断点事件。你应该问是什么导致了这种变化。
  • 决议 —冲突后的新情况。

这三个步骤缺一个,就没有故事。比如下面这个情节就很无聊,它什么都没说,只说价值在增加。没有故事。如果你想建立一个叙事,你应该搜索其他数据。

作者图片

让我们考虑经销商的季度汽车销量,由下面的图表示,它代表了整个情况。你可以在我的 Github 库中找到几乎所有的图表和 Python 代码。

作者图片

这个情节不可读。事实上,读者不能立即识别出信息。因此,在故事的开始,我们必须确定至少一个冲突,这使得故事有趣。

为了识别冲突,我们可以横向(历时视图)或纵向(共时视图)查看图表。通过横向观察图表,我们可以发现随时间的变化。例如,对于 Lakeside,我们可以识别不同的冲突,这些冲突对应于峰值,如下图所示:

作者图片

纵向分析该图,我们寻找不同经销商的行为。比如 2018 年第一季度,几乎所有的车都有一个峰值,之后是下降。为什么?

作者图片

一旦发现冲突,数据叙述就可以开始了。每个冲突都应该单独分析,也就是说,应该用不同的叙述和一系列情节来表现。

先说湖滨线的行为。下图显示了 2018 年第一季度发生的冲突的设置-冲突-解决范式。对 2018 年第四季度发生的冲突也可以做同样的分析。

作者图片

我们注意到,湖滨销售在 2018 年第一季度出现增长,然后下降,直到 2018 年第四季度出现其他情况,湖滨销售再次开始增长。

为了发现 2018 年第一季度发生了什么,我们可以为 2018 年第一季度和第二季度对应的所有汽车拍摄两张情况图。

2018 年第一季度(图片由作者提供)

2018 年第二季度(图片由作者提供)

前两个数字无法描述这种情况,因此我们可以尝试了解 2018 年第二季度和第一季度的差异。

作者图片

在这种情况下,情况就很清楚了。几乎所有的经销商都有负值,除了奥利和诺斯。湖滨和西湖销售情况最差。

现在,下一个问题是:为什么?2018 年第一季度发生了什么事,对汽车销量产生了负面影响?让我们试着用谷歌搜索一下答案。我找到了这篇有趣的文章和这篇的报道,它们解释了 2018 年轻型卡车销量出现了不可思议的增长(约 70%),从而产生了汽车销量的下降。

相反,由于不同的政策,Orly (O'Reilly Automotive)没有经历这种下降。事实上,该协会制定了一个很好的股票回购计划,正如本文中所描述的,这使得它能够增加销售额。

综上所述,原图可以用以下两个图代替:

作者图片

现在,可以通过搜索这些年来其他经销商的财务状况来丰富叙述。但是我把这个任务留给你:)

摘要

在本文中,我展示了如何从数据中提取知识。首先,应该对整个情况有一个大致的了解。通常,这张图片是不可读的,但它可以帮助你识别有趣的方面,或冲突,可以进一步分析。

然后,应该分别调查每个冲突。可以绘制许多试探性的图表,直至正确的图表,这有助于理解冲突期间和冲突后的局势。

最后,应该通过搜索新的数据和信息,尤其是在网上搜索,来回答所有出现的问题。

关于图形改进的进一步讨论,你可以阅读我的以前的帖子,购买这些精彩的书籍并保持关注:)

如果你想了解我的研究和其他活动的最新情况,你可以在 Twitter 、 Youtube 和 Github 上关注我。

相关文章

https://pub.towardsai.net/are-data-journalism-and-data-science-the-same-thing-77ba7ec794d4

人工智能内容作者能帮助数据科学家吗?

不要浪费时间一遍又一遍地重写同一份报告。随着人工智能写作工具的普及,报告可以自动编写,无需人工干预,节省您的时间和精力。该任务只需几秒钟即可完成,因此您每次都可以停止从头开始编写。

人工智能内容写作工具是人工智能写作助手的一种形式,它可以自动生成报告。数据科学家可以使用该工具来撰写报告。

此处继续阅读。

保持联系!

  • 跟着我上媒体
  • 注册我的简讯
  • 在 LinkedIn 上连接
  • 在推特上关注我
  • 跟着我上脸书
  • 在 Github 上关注我

如何使用 Python 和 Statsmodels 构建泊松隐马尔可夫模型

原文:https://towardsdatascience.com/how-to-build-a-poisson-hidden-markov-model-using-python-and-statsmodels-f7aa3f46f847?source=collection_archive---------6-----------------------

美国制造业罢工与时间的关系(数据来源: R 数据集)(图片由作者提供)

使用泊松 HMM 的逐步教程

一个泊松隐马尔可夫模型是两个回归模型的混合:一个泊松回归模型是可见的,一个马尔可夫模型是“隐藏的”。在泊松 HMM 中,泊松模型预测的平均值不仅取决于泊松模型的回归变量,还取决于隐马尔可夫过程所处的当前状态或区域。

在之前的一篇文章中,我们研究了泊松隐马尔可夫模型的架构,并考察了它的理论基础。如果你不熟悉马尔可夫模型或泊松模型,我鼓励你在这里回顾一下:

在本文中,我们将通过 Python 和 statsmodels 中的一步一步的教程来构建和训练一个泊松 HMM,它基于美国制造业中真实世界的劳工罢工数据集,在统计建模的文献中被广泛使用。

制造业罢工数据集

为了说明模型拟合过程,我们将使用以下开源数据集:

制造业罢工(数据来源:美国 BLS 通过 R 数据集

该数据集是一个月度时间序列,显示了从 1968 年到 1976 年每月开始的美国制造业活动与美国制造业合同罢工数量之间的关系。

STRIKES 数据集(来源: R 数据集)(图片由作者)

这个数据集在 R 中可用,可以使用 Python statsmodels 数据集包获取。

本文教程用的是 Python ,不是 r

回归目标

我们的目标是调查制造业产出(产出变量)对制造业罢工发生率(罢工变量)的影响。换句话说,制造业产出的差异是否“解释”了每月罢工次数的差异?

让我们导入所有需要的包,将 strikes 数据集加载到 Pandas DaraFrame 中,并检查 strikes 相对于时间的曲线:

**import** math
**import** numpy **as** np
**import** statsmodels.api **as** sm
**from** statsmodels.base.model **import** GenericLikelihoodModel
**from** scipy.stats **import** poisson
**from** patsy **import** dmatrices
**import** statsmodels.graphics.tsaplots **as** tsa
**from** matplotlib **import** pyplot **as** plt
**from** statsmodels.tools.numdiff **import** approx_hess1, approx_hess2, approx_hess3 ***#Download the data set and load it into a Pandas Dataframe*** strikes_dataset = sm.datasets.**get_rdataset**(dataname=**'StrikeNb'**, package=**'Ecdat'**)***#Plot the number of strikes starting each month***plt.**xlabel**('Month index')
plt.**ylabel**('Number of strikes beginning each month')
strikes_data['strikes'].**plot**()
plt.**show**()

我们看到下面的情节:

打击次数与时间的关系图(图片由作者提供)

上下摆动的撞击模式表明时间序列可能是自相关的。让我们通过查看撞击列的 自相关 图来验证这一点:

tsa.**plot_acf**(strikes_data[**'strikes'**], **alpha**=0.05)
plt.**show**()

我们看到下面的情节:

走向的自相关图(图片由作者提供)

滞后 0 处的完全相关将被忽略,因为值总是与其自身完全相关。在滞后-1 时有很强的相关性。滞后 2 和 3 的相关性可能是滞后 1 相关性的多米诺骨牌效应。这可以通过绘制部分自相关 图来确认。

tsa.**plot_pacf**(strikes_data['strikes'], **alpha**=0.05)
plt.**show**()

走向的部分自相关图(图片由作者提供)

部分自相关图揭示了以下内容:

  • 在滞后-0 时,部分自相关为 1.0。这是意料之中的,可以忽略不计。
  • PACF 图在滞后-1 处显示了强的部分自相关,这表明 AR(1)过程。
  • 滞后 2 的相关性刚好在 5%的显著性界限之外。所以,它可能重要,也可能不重要。

总的来说,ACF 和 PACF 曲线表明在滞后-1 时有明确的强自回归影响。因此,除了输出变量之外,我们应该包括打击在滞后-1 的滞后版本作为回归变量。

回归策略

我们的策略将基于输出和在滞后-1 撞击的延时副本上回归撞击

由于 strikes 包含整数数据,我们将使用泊松回归模型来研究输出strikes 之间的关系。

我们将额外假设制造业在低可变性和高可变性周期之间冲击数据周期,这可以使用 2 状态离散马尔可夫过程来建模。

为什么我们只为马尔可夫模型选择了两个区域?为什么不是 3 或 4 个政权?答案很简单,最好从具有最少可能状态的马尔可夫模型开始,以避免过度拟合。

总之,我们将使用一个二态泊松隐马尔可夫模型来研究制造业产量对罢工的关系。

因此,我们有:

因变量(内生变量)

y = 罢工

回归变量(外部变量)

X=【output,strikes _ LAG _ 1】+我们即将描述的隐马尔可夫模型相关变量。

我们将首先说明模型的泊松部分,然后看看如何“混合”马尔可夫模型。

泊松模型的均值(不考虑马尔可夫模型的影响)可以表示如下:

时间 t 的预期冲击值是时间 t 的输出和前一时间步的冲击数(和回归截距)的函数(图片由作者提供)

由于我们假设走向为泊松分布,其概率质量函数如下:

泊松分布撞击变量(图片由作者提供)

处理“模型爆炸”和零值数据

我们的泊松模型有一个问题。让我们再来看看说明书的意思:

时间 t 的预期冲击值是时间 t 的输出和前一时间步的冲击数(和回归截距)的函数(图片由作者提供)

如果 (strikes)_(t-1) 项的系数 β_2 大于 0 ,我们将面临所谓的“模型爆炸”效应,这是由从 (strikes)_(t-1)(strikes)_(t)的正反馈循环引起的但是 (strikes)_(t-1) 为零时 (strikes)_(t-1) 未定义。我们将通过做两件事来解决这个问题:

  1. 我们引入一个指示变量 d_t ,当 (strikes)_(t-1) 时设置为 1,否则设置为 0 ,并且,
  2. 每当(冲击)_(t-1) 为零时,我们将(冲击)_(t-1) 设置为 1.0

以上两个干预的净效果是,每当原始数据集中的 (strikes)_(t-1) 为零时,强制优化器训练 d_t 的系数。Cameron 和 Trivedi 在他们的书 计数数据的回归分析 中详细讨论了这种方法(参见第 7.5 节:自回归模型)。

考虑到上述变化,泊松过程均值的一个更稳健的规范如下:

作为时间 t 输出、前一时间步的撞击次数的自然对数和指示变量(和回归截距)的函数的时间 t 的撞击期望值(图片由作者提供)

马尔可夫模型中的混合

现在,让我们注入 2 态马尔可夫模型的影响。这导致所有的回归系数β_ cap=【β_ cap _ 0,β_cap_1,β_cap_2,β_ cap _ 3】,因此拟合的平均值 μ_cap_t 变成马尔可夫状态特定的,如下所示。注意附加的下标 j 表示在时间 t 有效的马尔可夫状态:

对应于 state=j 马尔可夫状态特定均值(图片由作者提供)

假设马尔可夫状态变量 s_t 在时间 t 处于状态 j 中,则在时间 t 观察到特定计数的撞击的相应马尔可夫特定泊松概率如下:

在时间 t 观察到特定撞击计数的马尔可夫状态相关概率(图片由作者提供)

其中,马尔可夫状态转移矩阵 P 为:

2 状态马尔可夫过程的状态转移矩阵(图片由作者提供)

并且包含在时间 t 的状态概率分布的马尔可夫状态概率向量如下:

2 态马尔可夫模型的时间相关状态概率(图片由作者提供)

根据上下文中的上述讨论,让我们重申走向数据集的泊松隐马尔可夫模型的外生和内生变量:

因变量(内生变量)

y = 打击

回归变量(外部变量)

X = 【输出,ln (strikes_LAG_1),d_t】和 P

培训和优化

训练泊松 PMM 涉及优化回归系数的马尔可夫状态相关矩阵(注意,在 Python 代码中,我们将使用该矩阵的转置):

马尔可夫状态特定回归系数矩阵(图片由作者提供)

并且还优化状态转移概率(矩阵 P ):

2 状态马尔可夫过程的状态转移矩阵(图片由作者提供)

优化将通过 最大似然估计 完成,其中优化器将找到P 的值,这将最大化观察到 y 的可能性。我们将使用 statsmodels 提供的 BFGS 优化器来执行优化。

有一个小问题我们需要解决。在整个优化过程中,马尔可夫状态转移概率 p_ij 需要遵守以下约束,即所有转移概率都位于[0,1]区间内,并且跨越任意一行 P 的概率总和总是 1:

所有马尔可夫状态转移概率遵守的约束(图片由作者提供)

在优化期间,我们通过定义大小为 (k x k) 的矩阵 Q 来处理这些约束,该矩阵充当 P 的代理,如下所示:

代理矩阵 Q (图片作者提供)

我们不是优化 P ,而是通过允许 q_ij 在-∞到+∞之间自由变化来优化。在每次优化迭代中,我们通过将的值标准化到区间【0.0,1.0】*来获得 p_ij ,如下:***

标准化 Q 矩阵以获得 P 矩阵(图片由作者提供)

至此,让我们回到我们的打击数据集。

准备用于培训的 strikes 数据集

我们看到在打击时间序列中,在滞后-1 处有很强的相关性,添加打击的滞后-1 拷贝作为回归变量。

**strikes_data['strikes_lag1'] = strikes_data['strikes'].**shift**(1)**#Drop rows with empty cells created by the shift operation** strikes_data = strikes_data.**dropna**()**

创建指标函数,计算指标变量 d1 的值如下:如果 == 0, d1 = 1,否则 d1 = 0。

**def **indicator_func**(x):
    if x == 0:
        return 1
    else:
        return 0**

d1 的列添加到数据框中:

**strikes_data['d1'] = strikes_data['strikes_lag1'].**apply**(indicator_func)**

调整滞后的撞击变量,当其值为 0 时,将其设置为 1。

**strikes_data['strikes_adj_lag1'] = np.**maximum**(1, strikes_data['strikes_lag1'])**

添加 strikes_lag1 的自然对数作为回归变量。

**strikes_data['ln_strikes_adj_lag1'] = np.**log**(strikes_data['strikes_adj_lag1'])**

用 Patsy 语法形成回归表达式。不需要显式指定回归截距 β_0 。Patsy 将自动在 X 中包含一个占位符。

**expr = 'strikes ~ output + ln_strikes_adj_lag1 + d1'**

使用 Patsy 雕刻出 yX 矩阵。

**y_train, X_train = **dmatrices**(expr, strikes_data, return_type='dataframe')**

让我们看看 X 和 y 矩阵的结果:

****print**(y_train)**

y_train(图片由作者提供)

****print**(X_train)**

X_train(图片由作者提供)

在我们继续之前,我们需要构建PoissonHMM类。为此,我们将使用 statsmodels 提供的类[**GenericLikelihoodModel**](https://www.statsmodels.org/dev/_modules/statsmodels/base/model.html#GenericLikelihoodModel)

创建自定义泊松隐马尔可夫模型类

我们将创建的PoissonHMM类将扩展GenericLikelihoodModel类,以便我们可以使用定制的对数似然函数来训练模型。让我们从定义PoissonHMM类的构造函数开始。

****class** PoissonHMM(**GenericLikelihoodModel**):
    **def __init__**(self, endog, exog, **k_regimes**=2, **loglike**=None, 
                 **score**=None, **hessian**=None,
                 **missing**=**'**none**'**, **extra_params_names**=None, **kwds):
        **super**(**PoissonHMM**, self).**__init__**(**endog**=endog, **exog**=exog, 
            **loglike**=loglike, **score**=score, **hessian**=hessian, 
            **missing**=missing, **extra_params_names**=extra_params_names, 
            **kwds**=kwds)**

现在,让我们用下面几行代码填充构造函数,即 PoissonHMM 的*__init__* 方法:

首先,我们将因变量转换成 statsmodels 喜欢使用的 numpy 数组。我们还会复制政权的数量。

**self.y = np.**array**(self.endog)
self.k_regimes = k_regimes**

接下来,设置状态特定回归系数 β的k×m大小矩阵。 m= self.**exog**.**shape**[1]是包含截距的回归系数的个数:**

*self.beta_matrix = np.**ones**([self.k_regimes, self.**exog**.**shape**[1]])*

设置代理转移概率矩阵 Qk x k 矩阵。将其初始化为 1.0/k

*self.q_matrix = np.**ones**([self.k_regimes,self.k_regimes])*(1.0/self.k_regimes)**print**('self.q_matrix='+**str**(self.q_matrix))*

设置泊松平均的状态矩阵。这些将在优化循环期间更新。

*self.mu_matrix = []*

设置真实马尔可夫转移概率的 k x k 矩阵,该矩阵将使用前面描述的标准化技术从 q 矩阵中计算出来。初始化为 1.0/k

*self.gamma_matrix = np.**ones**([self.k_regimes, self.k_regimes])*(1.0/self.k_regimes)**print**('self.gamma_matrix='+**str**(self.gamma_matrix))*

设置马尔可夫状态概率( π 向量)。但是为了避免与回归模型的平均值(也称为)混淆,我们将遵循 Cameron 和 Trivedi 中使用的约定,并使用符号 δ 。**

**self.delta_matrix = np.**ones**([self.**exog**.**shape**[0],self.k_regimes])*(1.0/self.k_regimes)**print**('self.delta_matrix='+**str**(self.delta_matrix))**

初始化优化器将要优化的参数 βQ 的初始值向量。

**self.start_params = np.**repeat**(np.**ones**(self.**exog**.**shape**[1]), **repeats**=self.k_regimes)self.start_params = np.**append**(self.start_params, self.q_matrix.**flatten**())**print**('self.start_params='+**str**(self.start_params))**

初始化一个非常小的特定于机器的数字。它被我们即将编写的自定义对数似然函数所使用。

**self.EPS = np.**MachAr**().eps**

最后,初始化优化器的迭代计数器。

**self.iter_num=0**

PoissonHMM类的完整构造函数如下所示:

PoissonHMM 类的构造函数

接下来,我们将覆盖GenericLikelihoodModelnloglikeobs(self, params)方法。这个方法由优化器在每次迭代中调用一次,以获得与传递给它的所有params的当前值相对应的对数似然函数的当前值。

****def** nloglikeobs(self, params):**

让我们用下面的函数来填充这个方法,我们将很快定义这些函数:

从所有参数的当前值重构 Qβ 矩阵。

**self.**reconstitute_parameter_matrices**(params)**

建立泊松平均的状态矩阵。

**self.**compute_regime_specific_poisson_means**()**

通过将所有的 Q 值标准化到 0 到 1 的范围来构建马尔可夫转移概率矩阵。

**self.**compute_markov_transition_probabilities**()**

建立马尔可夫状态概率分布的 (len(y) x k) 矩阵 delta。

**self.**compute_markov_state_probabilities**()**

计算每个观察值的对数似然值。该函数返回对数似然值的大小为len(y)的数组。

**ll = self.**compute_loglikelihood**()**

递增迭代计数。

**self.iter_num=self.iter_num+1**

打印出迭代总结。

****print**('ITER='+**str**(self.iter_num) + ' ll='+**str**(((-ll).**sum**(0)))**

最后,返回求反的对数似然数组。

**return -ll**

下面是整个nloglikeobs(self, params)的方法:

下面是从nloglikeobs(self, params)方法调用的助手方法的实现:

从所有参数的当前值重建 Qβ 矩阵:

建立泊松平均的状态矩阵:

通过将所有的 Q 值标准化到 0 到 1 的范围,构建马尔可夫转移概率 P 的矩阵:

建立马尔可夫状态概率分布的 (len(y) x k) 大小 δ 矩阵。

最后,计算泊松马尔可夫模型的所有对数似然值:

让我们重写超类中的一个方法,该方法尽力计算一个可逆 Hessian,以便可以成功计算所有训练参数的标准误差和置信区间。

**def **hessian**(self, params):
    for approx_hess_func **in** [approx_hess3, approx_hess2, 
                            approx_hess1]:
        H = approx_hess_func(**x**=params, **f**=self.loglike, 
            **epsilon**=self.EPS)
        if np.**linalg**.**cond**(H) < 1 / self.EPS:
            print('Found invertible hessian using' + 
                str(approx_hess_func))
            return H
    **print**('DID NOT find invertible hessian')
    H[H == 0.0] = self.EPS
    return H**

综上所述,下面是 PoissonHMM 类的完整类定义:

现在我们已经有了自定义的PoissonHMM类,让我们继续在我们的(y _ trainX _ train)数据集上训练它,这个数据集是我们使用 Patsy 创建的。

让我们回忆一下PoissonHMM的构造函数是什么样子的:

****def** __init__(**self**, **endog**, **exog**, **k_regimes**=2, **loglike**=None, 
            **score**=None, **hessian**=None, **missing**=**'**none**'**, 
            **extra_params_names**=None, ****kwds**):**

我们将使用 2 状态 HMM 进行实验,假设数据循环通过 2 个不同但隐藏的区域,每个区域都会影响泊松过程的均值。所以我们将 k_regimes 设置为 2:

**k_regimes = 2**

注意,PoissonHMM 带有一个extra_param_names参数。除了矩阵 X_train 的列名之外,这是我们希望优化器优化的参数列表。让我们初始化并构建这个额外参数名的列表。

**extra_params_names = []**

每个状态将有len(X_train.columns)个回归系数被发送到模型中进行优化。所以,总的来说,len(X_train.columns) * k_regimes β 中的系数都要被优化。其中,对应于一个状态(比如状态 1)的系数已经以回归参数的形式被烘焙到X_train中。statsmodels 将从 X_train 矩阵中收集它们的名称。它会自动向模型提供这组参数的名称。因此,我们需要通过extra_param_names参数(因此得名*extra*_param_names)告诉 statsmodels 剩余参数集的名称,对应于剩余的政权。因此,我们将第二种状态的平衡参数组插入extra_param_names,如下所示:

*for regime_num **in range**(1, k_regimes):
    for param_name in X_train.columns:
        extra_params_names.**append**(param_name+'_R'+**str**(regime_num))*

该模型还将优化代理转移概率的k×k矩阵:矩阵 Q 所以也把它们发送到 extra_params 列表中:

*for i **in** range(k_regimes):
    for j **in range**(k_regimes):
        extra_params_names.**append**('q'+**str**(i)+**str**(j))*

注意:在 Python 代码中,我们选择使用基于 0 的马尔可夫状态索引。也就是说,我们在代码中提到的状态 1 是状态 0。

我们的extra_param_names名单现在准备好了。

创建一个PoissonHMM模型类的实例。

*poisson_hmm = **PoissonHMM**(**endog**=y_train, **exog**=X_train, 
                        **k_regimes**=k_regimes,
                        **extra_params_names**=extra_params_names)*

训练模型。注意,我们要求 statsmodels 使用 BFGS 优化器。

*poisson_hmm_results = poisson_hmm.**fit**(**method**=’bfgs’, **maxiter**=1000)*

打印出拟合的马尔可夫转移概率:

***print**(poisson_hmm.gamma_matrix)*

我们看到以下输出:

*[[0.96884629 0.03115371]
 [0.0043594  0.9956406 ]]*

这样,我们的马尔可夫状态转移矩阵T5【P】T6如下:

拟合的转移矩阵(图片由作者提供)

这对应于下面的状态转换图:

与泊松 HMM 关联的 2 状态隐马尔可夫过程的状态转移图(图片由作者提供)

状态转换图显示,一旦系统进入状态 1 或 2,它真的喜欢处于该状态,并且很少倾向于切换到另一个状态。

最后,打印出模型培训总结:

***print**(poisson_hmm_results.**summary**())*

我们看到以下输出。我已经调出了与两个马尔可夫状态 1 和 2 相对应的模型参数,以及 Q-matrix 值(如前所述,这些值恰好索引为 0)。

泊松隐马尔可夫模型的训练总结(图片由作者提供)

下面是我们在输出中观察到的一些情况:

  1. 该模型适合于两个马尔可夫状态中的每一个的不同截距。在状态 1 和状态 2 中,截距( β_0 )分别为 2.2891 和 0.7355。
  2. 产出效应( β_1 )在方案 1 中为-2.6620,表明制造业产出的增长与罢工次数成反比关系,在方案 2 中为 7.6534,表明随着制造业产出的增加,罢工次数也增加。

拟合优度

正如我们从模型训练总结中看到的,模型无法找到 β_01q_11 的有效标准误差就证明了这一点。参数 β_31 、β_22、 β_32q_01 的 p 值不具有统计学意义。

然而,这是一个好的开始。

为了实现更好的拟合,我们可能希望用 3 或 4 状态马尔可夫过程进行实验,并且也用 statsmodels 提供的大量优化程序中的另一个进行实验,例如“nm”(牛顿-拉夫森)、“powell”和“basinhopping”。

顺便说一句,由于我们使用 statsmodels 的现成方法来打印训练摘要,所以训练摘要中打印的 df_model 值 3 会产生误导,应该忽略。

最后,将该模型的拟合优度与此处描述的泊松自回归模型以及此处描述的泊松 INAR(1) 模型进行比较将是有益的。所有三个模型都适用于相同的制造业罢工数据集:

制造业罢工数据集上三个泊松时间序列模型的对数似然性比较(图片由作者提供)

我们可以看到即使考虑到泊松 HMM 使用的大量拟合参数,泊松 HMM 模型比其他两种时间序列模型更有可能观察到撞击数据集值。

从这里去哪里?

以下是一些建立在泊松 HMM 工作基础上的方法:

  1. 我们可以尝试使用不同的优化器和/或通过引入更多的马尔可夫状态来提高PoissonHMM模型类的拟合度。
  2. 我们可能要计算 PoissonHMM 类的 伪 R 平方 。伪 R 平方提供了一种比较非线性模型(如泊松-HMM)拟合异方差数据集的拟合优度的极好方法。
  3. 回想一下,我们所用的泊松模型假设,在任何马尔可夫状态下,撞击的方差与该状态下撞击的平均值相同,这是一种称为等散度的性质。我们可以通过用一个 广义泊松 或一个 负二项回归 模型代替泊松模型来间接检验这个假设。这些模型没有对数据做等分散假设。如果 GP-HMM 或 NB-HMM 比直接的泊松-HMM 产生更好的拟合优度,那么就有理由使用这些模型。

快乐造型!

以下是完整的源代码:

引用和版权

Cameron A. Colin,Trivedi Pravin K ., 计数数据的回归分析 ,计量经济学学会专论№30,剑桥大学出版社,1998 年。国际标准书号:0521635675

报纸

凯南 j ., 美国制造业合同罢工的持续时间,计量经济学杂志 ,第 28 卷,1985 年第 1 期,第 5-28 页,ISSN 0304-4076,https://doi . org/10.1016/0304-4076(85)90064-8。 PDF 下载链接

Cameron C. A .,Trivedi P. K ., 基于回归的泊松模型过度离差测试 ,《计量经济学杂志》,第 46 卷,第 3 期,1990 年,第 347-364 页,ISSN 0304-4076,https://doi . org/10.1016/0304-4076(90)90014-k .

数据集

文章中使用的制造业罢工数据集是统计软件中可供公众使用和实验的几个数据集之一,最值得注意的是,这里的是一个 R 包。在 GPL v3 许可下,Vincent Arel-Bundock 通过 vincentarelbundock.github.io/rdatasets 已经可以使用 Python 访问数据集。

形象

本文中的所有图片版权归 CC-BY-NC-SA 所有,除非图片下面提到了不同的来源和版权。

相关文章

*

感谢阅读!如果您喜欢这篇文章,请 关注我 获取关于回归和时间序列分析的技巧、操作方法和编程建议。*

纪娜和伯特的金融问答——第一部分

原文:https://towardsdatascience.com/how-to-build-a-production-ready-financial-question-answering-system-with-jina-and-bert-48335103043f?source=collection_archive---------3-----------------------

金融中的 NLP

关于如何构建生产就绪型财务 QA 系统的教程

(图片由作者提供)

第 1 部分—学习如何使用神经搜索框架, 【纪娜】 ,构建一个 金融问答(QA)搜索应用 FiQA数据集,py torch,以及https://github.com/huggingface/transformers

第二部分 —和纪娜一起学习如何评估和改善你的财务问答搜索结果

在我的硕士论文中,我使用一个名为 FinBERT-QA 的微调 BERT 模型构建了一个财务 QA 系统。受金融行业对大规模自动分析非结构化和结构化数据的新兴需求的推动, QA 系统可以通过促进金融顾问的决策为公司提供有利可图的竞争优势

我的论文的目标是搜索一个给定问题的相关答案段落的排序列表。以下是一个基于金融领域的问题示例和来自 FiQA 数据集的基本事实答案:

来自金融领域的 QA 示例。(图片由作者提供)

以下是 FiQA 提出的其他问题列表:

*• What does it mean that stocks are “memoryless”?
• What would a stock be worth if dividends did not exist?
• What are the risks of Dividend-yielding stocks?
• Why do financial institutions charge so much to convert currency?
• Is there a candlestick pattern that guarantees any kind of future profit?
• 15 year mortgage vs 30 year paid off in 15
• Why is it rational to pay out a dividend?
• Why do companies have a fiscal year different from the calendar year?
• What should I look at before investing in a start-up?
• Where do large corporations store their massive amounts of cash?*

金融 QA 是很难的,因为词汇表是上下文相关的,例如,机器很难理解什么是 ETF。尽管如此,借助 BERT 的力量,我在三个评估指标(精度、MRR、NDCG)上将最先进的(SOTA)结果平均提高了 19%

来自芬伯特-QA 的评估结果

尽管我的论文是关于金融领域的 QA,但我使用的方法可以应用于一般 QA 数据集或其他领域的 QA,如 T2 保险 T3。

目录

背景
教程
总结
下一步:评测
了解更多

背景

什么是纪娜?

(图片来自纪娜艾)

TensorFlow 和 PyTorch 等开源深度学习框架通过高级编程接口为设计和快速实现基于神经网络的应用提供了构建模块。

同样,纪娜是一个开源神经搜索框架,它为设计和实现基于神经网络的搜索应用提供了构建模块。

由 bert-as-service 和 Fashion-MNIST 的创建者共同创建,纪娜使开发者能够使用 SOTA 预先训练的深度学习模型来构建生产就绪的云原生搜索系统,其中系统的每个组件都是一个微服务,可以独立部署、扩展和维护。

(图片由作者提供)

如果你像我一样来自数据科学或学术背景,术语云原生微服务可能听起来令人生畏。这就是为什么我们将在本教程中通过示例学习,并使用 NLP 任务,财务 QA,来熟悉纪娜的核心概念!

BERT 的财务质量保证

在进入教程之前,我们先来了解一下如何用 BERT 搭建一个 QA 系统。我们的目标是当给定来自 FiQA 数据集的任务 2 的问题时,搜索前 k 个最相关的答案段落。

2018 年,谷歌预训练的用于迁移学习的 BERT 模型震动了 NLP 世界,并在众多任务上取得了 SOTA 结果,标志着 NLP 的 ImageNet moment 。

BERT 的巧妙之处在于,我们可以通过简单地将它转换为一个二进制分类任务来微调我们 QA 任务的预训练模型,其中输入是一个问题和一个答案的串联,输出是一个二进制标签,指示 QA 对的相关性分数。然后,我们可以获得每个问答配对的 softmax 分数,以获得相关性的概率,并对这些分数进行排名。

FinBERT-QA 为我们的 QA 任务提供的微调方法。输入是一个问题和一个答案的串联,输出是一个二进制标签,指示 QA 对的相关性分数。

FiQA 数据集大约有 6000 个问题和 57000 个答案。我们可以采用段落重新排序方法,而不是对每个问题计算 57,000 次的概率。我们首先使用检索器返回每个问题的前 50 个候选答案,然后使用 FinBERT-QA ,一个基于 BERT 的模型,在 FiQA 数据集上进行微调,作为重排序器来计算相关性分数,并对前 50 个 QA 对进行重排序,以获得前 10 个答案。

重新分级的质量保证管道。(图片由作者提供)

如果你对我论文的细节感兴趣,可以在这里了解更多。

为什么是纪娜?

为什么 SOTA 模型和结果不够好?

纪娜作为研究和工业之间的桥梁:

我的研究背后的动机是能够帮助财务顾问回答大规模报告中的问题。然而,我实现 QA 管道的方式是不可重用的,并且它不能扩展到业务需求。按照行业标准,它还不能投入生产。

由于纪娜使我们能够构建包含微服务的云原生系统,而不是将我的整个管道包装在单个 Docker 容器中,纪娜将把管道分解成组件(预处理器、编码器、索引器等)。).此外,这些组件中的每一个都将是一个独立 Docker 容器中的微服务,由流 API 管理。

(插图来自多像素)

对于那些不熟悉云原生概念的人,你可以将微服务视为应用的独立组件,例如,使用 FinBERT-QA 对我们的问题和答案进行编码。然后,您可以创建多个独立的组件或微服务来构建类似 BERT 支持的 QA 系统的应用程序。由于应用程序的每个组件都可以独立部署,因此它们也可以单独扩展,并响应快速变化和业务需求。

(插图来自多像素)

云原生是一种现代设计,越来越多的企业正在适应这种设计,因为它可以帮助他们节省资源并实现增长。然而,设计这样的系统并不容易。我们需要考虑许多原则、模式和最佳实践,例如,每个组件将如何相互通信?他们如何并行工作?幸运的是,纪娜没有从零开始,而是为我们做了所有的艰苦工作,为我们提供了构建模块,这样我们就可以使用一种重新排序的方法轻松构建一个基于云的 BERT 支持的 QA 系统,并随时投入生产!

辅导的

现在我们已经有了一个概述,让我们学习如何使用重新分级方法构建一个生产就绪的财务 QA 系统,并深入研究一些新的纪娜术语。我们将使用 FinBERT 将我们的问题和答案段落编码到嵌入中,并使用 FinBERT-QA 对前 50 个答案匹配进行重新排序。

本教程的最终代码可以在 这里找到

建立

克隆我们将在这里一起工作的存储库:

*git clone https://github.com/yuanbit/jina-financial-qa-search-template.git*

我们将使用jina-financial-qa-search/作为我们的工作目录。

安装要求

*pip install -r requirements.txt*

下载数据和模型

*bash get_data.sh*

对于本教程,我们不会搜索来自 FiQA 数据集的所有 57,000 个答案段落。我们将使用一个名为test_answers.csv的样本数据集,包含大约 800 个答案段落。如果您想试验完整的数据集,可以使用answer_collection.tsv

流程

在纪娜,我们将建立一个有两个管道的金融 QA 系统,一个用于索引我们的答案段落,另一个用于查询。这些管道被称为,它们也用于管理微服务的状态和上下文,以及编排它们。让我们看看索引流查询流的概况是什么样子的:

指数流。(图片由作者提供)

查询流程。(图片由作者提供)

为了理解这些流程,让我们从索引流程开始,逐一查看各个组件。

指数流

索引流背后的主要思想是使用预先训练的 BERT 模型将我们所有的答案段落编码成嵌入,然后索引这些嵌入,以便可以在查询流中搜索它们。

第一步。定义我们的数据

我们想要索引来自 FiQA 数据集的答案段落的子集,dataset/test_answers.csv:

*398960	From  [http://financial](http://financial-)  
        dictionary.thefreedictionary.com/Business+Fundamentals  The  
        facts  that  affect  a  company's      underlying  value.  
        Examples  of  business      fundamentals  include  debt,     
        sure  you  file  the  NOL...
19183	If  your  sole  proprietorship  losses  exceed  all  other  
        sources  of  taxable income...
327002	To  be  deductible,  a  business  expense  must  be  both  
        ordinary  and  necessary.  An  ordinary  expense  is  one  
        that  is  common  and  accepted  in  your  trade  or  
        business.  A  necessary  expense...*

我们的数据集由一列答案 id 和文本组成,在本教程中我们将它们分别表示为dociddoc。为了索引我们的数据,我们需要首先在一个名为Document的纪娜数据类型中定义它。

索引流——第 1 步,在一个名为 Document 的纪娜特定数据类型中定义我们的数据。(图片由作者提供)

在编程语言中,有 int、float、boolean 等数据类型。在 NumPy、TensorFlow 和 PyTorch 中,我们操作和传递诸如ndarraytensor之类的对象,它们被称为原始数据类型。类似地,Document是表示数据的特定于纪娜的数据类型。

在文档中定义我们的数据

在我们的项目目录jina-financial-qa-search/中,app.py文件由我们将要构建的财务 QA 搜索应用程序组成。注意,我们在config函数中设置了数据路径,如下所示:

您可以将路径更改为answer_collection.tsv来索引整个数据集。

让我们首先确定我们从 jina 进口:

在完成了config函数之后,让我们创建一个 Python 生成器,并定义文档以包含与答案段落相对应的 id 和文本:

文档是我们定义和查看 Protobuf 中存储的内容的高级方式,纪娜用它来使流程中的微服务能够相互通信。它就像一个包含我们数据的信封,用于在我们流的微服务之间发送消息。不用直接处理 Protobuf,它将我们的数据序列化为字节,我们可以简单地打印我们的文档,并看到一个单独的答案段落如下所示:

*id: "13755c6081bebe1a"
mime_type: "text/plain"
tags {
  fields {
    key: "id"
    value {
      number_value: 398960.0
    }
  }
}
text: "From  http://financial-dictionary.thefreedictionary.com/Business+Fundamentals  The  facts  that  affect  a  
company\'s underlying  value. Examples  of  business fundamentals  include  debt,  cash  flow, supply  of  and  demand  
for  the  company\'s      products,  and  so  forth.  For  instance, if  a  company  does  not  have  a sufficient  
supply  of  products,  it  will      fail.  Likewise,  demand  for  the  product      must  remain  at  a  certain  
level  in      order  for  it  to  be  successful.  Strong      business  fundamentals  are  considered essential  for  
long-term  success  and      stability.  See  also:  Value  Investing, Fundamental  Analysis.  For  a  stock  the  basic
fundamentals  are  the  second  column  of  numbers  you  see  on  the  google  finance  summary  page, P/E  ratio,  
div/yeild,  EPS,  shares,  beta.      For  the  company  itself  it\'s  generally  the  stuff  on  the  \'financials\'  
link    (e.g.  things  in  the  quarterly  and  annual  report,    debt,  liabilities,  assets,  earnings,  profit  etc."*

当我们沿着索引流移动时,文档的内容将被改变,例如,我们可以在索引流中看到,答案段落的嵌入在编码步骤之后被添加到文档中。

在编码步骤之后,答案段落的嵌入被添加到文档中。(图片由作者提供)

编码步骤使用一个执行器,即编码器。接下来让我们更深入地理解这一点。

第二步。编码答案段落

(图片来自纪娜艾)

我们将在以后查看其他执行器,现在只关注编码器。我们可以简单地利用纪娜中心,这是一个开放注册表,用于通过容器映像托管纪娜执行者,而不是使用 TensorFlow 或 PyTorch 结合拥抱面部变形器和我们自己实现编码器。

在纪娜中心有各种编码器和其他类型的执行器,用于不同的任务和数据类型(例如,图像、视频、音频、多模态),允许我们运送和交换可重用的组件,并构建各种基于深度学习的搜索引擎,例如,文本-图像、跨模态和多模态搜索。因为我们的任务是文本到文本的搜索,所以在本教程中我们将使用TransformerTorchEncoder。

在我们讨论如何在我们的索引流中使用编码器之前,让我们在这一步中理解三个更重要的纪娜概念:

(图片来自纪娜艾)

  • 驱动:回忆纪娜使用 Protobuf 在流程中的微服务之间发送消息,消息的形式是字节。如果我们将文档直接传递给编码器,我们会遇到一个问题,因为编码器需要答案文本作为输入,而不是字节。

纪娜没有直接处理 Protobuf,而是使用驱动为执行器翻译数据,这样我们只需要处理我们熟悉的数据类型(例如文本、图像、np、数组等等……)。对于每个执行器,都有一个相应的驱动程序来解释流中的消息,并将适当的数据传递给执行器。

编码器—驱动程序以 yes 接收文档,并将文本传递给编码器。编码器输出文本的嵌入,同一驱动程序将它们添加到文档中。(图片由作者提供)

例如,在编码步骤中,驱动程序接收以字节为单位的文档,将其解释为文档,并将文档中的文本传递给编码器。在编码器输出相应文本的嵌入内容后,同一个驱动程序再次解释嵌入内容,并将它们添加到文档中。下面的文档显示了它是如何在编码步骤中被驱动程序转换的,并将作为下一个索引步骤的输入。

驱动程序通过在编码步骤中添加嵌入来转换文档。(图片由作者提供)

(图片来自纪娜艾)

  • Pea: 由于执行者需要一个驱动程序来处理我们的数据,所以它们都是流程中微服务的必要组件。因此,我们使用一个 Pea 将执行器和驱动程序包装在一起,得到我们的编码器微服务*。*

因此,Pea 是一个微服务,它不断地监听来自网关或流中其他 Pea 的传入消息,并在收到消息时调用驱动程序。作为微服务, Peas 也可以在 Docker 中运行,在一个地方包含所有依赖和上下文。

(图片来自纪娜艾)

  • Pod: 为了优化我们的神经搜索应用,纪娜提供了现成的并行化。我们可以把它分成多个进程*,而不是只有一个编码器。编码步骤的可视化显示了编码器被分成三个进程,每个进程由一个 Pea 包装。*

为了让我们的多编码器微服务在功能上表现得像一个编码器,我们将一组同质(相同)pea 包装在一个 Pod 中。因此,Pod 是一组同类微服务*,也负责负载平衡、进一步控制和上下文管理。*

这个设计的美妙之处在于,Pod 既可以在本地主机上运行,也可以通过网络在不同的计算机上运行,这使得我们的应用程序是分布式的、高效的和可伸缩的

现在我们了解了这些基本概念, 我们如何为编码器创建一个 Pod 呢?

(图片来自纪娜艾)

这听起来可能非常复杂,但是利用纪娜提供的构建模块,我们可以 (1)设计一个索引流,以及(2)用两个简单的 YAML 文件创建一个编码器 Pod。这些 YAML 文件将允许我们在不触及纪娜代码核心的情况下定制我们的神经搜索应用程序。

I .为编码器创建一个 Pod

让我们首先在名为pods的文件夹中创建一个文件encode.yml。在encode.yml中,我们首先从纪娜中心指定我们想要使用的编码器的名称,TransformerTorchEncoder

我们可以选择我们想要使用的模型,在我们的例子中,我们使用 FinBERT ,它在一个大型金融语料库上进一步预训练了bert-base-uncased。由于TransformerTorchEncoder是使用拥抱面部变形器实现的,如果拥抱面部模型中枢上有该模型,您也可以通过指定其名称来直接使用该模型。我们还可以包括其他超参数,如最大序列长度或池策略。

就这么简单!🐣我们刚刚创建了一个基于深度学习的编码器微服务,准备进行并行化!pods文件夹也将是我们需要的其他 pod 的目录,这些 pod 也将使用 YAML 文件来定义。

二。将编码器添加到索引流

现在我们已经准备好了编码器,让我们将它放入索引流中。让我们在名为flows的文件夹中创建一个文件index.yml。在index.yml中,我们通过给出pods/encode.yml文件的路径来指定索引流中的第一个 Pod,即encoder。通过使用parallel参数,我们可以指定我们想要将编码器分成多少个进程。这将是一个在app.py中指定的环境变量,我们将在最后查看。parallel决定了我们在每个豆荚里会有多少豌豆。

干得好!💪您刚刚为深度学习驱动的微服务创建了一个初始管道!接下来,让我们通过添加另一个包含索引器的 Pod 来完成索引流的设计。

第三步。索引

(图片来自纪娜艾)

获得答案段落的嵌入后,我们将创建另一个名为索引器的执行器来存储我们的数据,以便在查询时可以检索到它们。与上一步类似,驱动程序接收文档,并将dociddocembeddings传递给索引器。

我们将使用复合索引器,它使用来自纪娜中心的 (1)向量(2)键值索引器作为单个索引器:

  1. 向量索引器:存储答案嵌入,并被问题嵌入查询,以使用 k-最近邻算法检索最接近的答案嵌入。
  2. 键值(KV)索引器:存储文档数据(文本、blob、元数据),并通过文档 id(通常从向量索引器中提取)进行查询,以检索数据的信息,如答案 id 和文本。

索引器将存储我们的数据,以便可以在查询时检索它们。(图片由作者提供)

我们再次将驱动程序和索引器包装在一个 Pea 中,将相同的 Pea 分组在一个 Pod 中,并使用 YAML 文件定义它们。

I .为索引器创建一个 Pod

让我们创建文件pods/doc.yml并将我们的复合索引器定义为!CompoundIndexer,其中组件!NumpyIndexer是矢量索引器,!BinaryPbIndexer是 KV 索引器。索引数据将分别存储在vec.gzdoc.gz中。workspace是存储索引的目录,它位于我们的工作目录中。

二。将索引器添加到索引流中

现在让我们回到flows/index.yml,将我们的索引器作为doc_indexer添加到索引流中。如果我们的数据很大,我们还可以在应用程序中添加分片来进行优化。这也将在app.py中用作环境变量,我们将在后面看到。

干得好!👏您刚刚设计了一个用于索引金融答案段落的云原生管道!我们还可以使用纪娜的流 API 来可视化索引流。首先让我们在终端中为parallelshards设置环境变量:

*export JINA_PARALLEL='1'
export JINA_SHARDS='1'*

接下来,让我们在工作目录中打开一个jupyter notebook并执行以下操作:

索引流可视化。(图片由作者提供)

这里我们看到我们的索引流有两个 Pods 编码器,encoder和索引器,doc_indexer

构建索引器应用程序

让我们看看如何在我们的搜索应用程序中使用索引流。在app.py中,我们可以更改config函数中的parallel来指示我们想要为每个 Pod 拆分多少个 pea(进程)。我们还可以更改shards来指示索引步骤期间的并行化。我们暂时不改变它们。这意味着我们每个豆荚里只有一粒豌豆。

我们先从纪娜的流程 API 中导入Flow:

在我们在步骤 1 中添加的index_generator功能之后。定义我们的数据,让我们添加index函数,该函数将首先加载我们在flows/index.yml中创建的索引流,并将输入文档从index_generator传递到该流。我们将batch_size=16设置为将答案段落编码到嵌入中。

我们现在准备索引我们的数据。在我们的工作目录中运行:

*python app.py index*

*https://asciinema.org/a/381671

最后,您将看到以下内容:

✅ done in ⏱ 1 minute and 54 seconds 🐎 7.7/s
        gateway@18904[S]:terminated
    doc_indexer@18903[I]:recv ControlRequest from ctl▸doc_indexer▸⚐
    doc_indexer@18903[I]:Terminating loop requested by terminate signal RequestLoopEnd()
    doc_indexer@18903[I]:#sent: 56 #recv: 56 sent_size: 1.7 MB recv_size: 1.7 MB
    doc_indexer@18903[I]:request loop ended, tearing down ...
    doc_indexer@18903[I]:indexer size: 865 physical size: 3.1 MB
    doc_indexer@18903[S]:artifacts of this executor (vecidx) is persisted to ./workspace/doc_compound_indexer-0/vecidx.bin
    doc_indexer@18903[I]:indexer size: 865 physical size: 3.2 MB
    doc_indexer@18903[S]:artifacts of this executor (docidx) is persisted to ./workspace/doc_compound_indexer-0/docidx.bin

好哇🙌我们完成了申请的第一部分!嵌入索引和文档数据将存储在名为workspace的目录中。

查询流程

在索引我们的数据之后,我们需要创建一个查询流。查询流背后的主要思想是使用相同的基于 BERT 的模型来将给定的问题编码到嵌入中并使用索引器来搜索最相似的答案嵌入。为了进一步改善搜索结果,我们将使用与我的论文相同的重新排序技术。因此,我们将需要添加另一个重新排序步骤,使用 FinBERT-QA 来重新计算纪娜返回的答案匹配的分数。

查询流程。(图片由作者提供)

让我们再一次一步一步地走一遍。

第一步。编码问题

让我们假设问题文本将是用户输入。纪娜将接受这个输入并定义一个新的文档。

查询流中的编码器。(图片由作者提供)

将编码器添加到查询流中

就像索引流的编码步骤一样,我们使用相同的编码器对问题进行编码。因此,我们可以在我们的查询流中使用来自pods/encode.yml的相同编码器。我们将在flows文件夹中创建一个新的query.yml文件,并将编码器窗格添加到其中:

第二步。搜索索引

对问题进行编码后,问题嵌入将由驱动程序添加到文档中。然后,该文档被发送到下一个 Pod 中的索引器,驱动程序将把问题嵌入传递到索引器。然后,索引器将使用 k-nearest neighbors 算法搜索具有最相似嵌入的答案,并将前 k 个答案匹配的列表传递给要添加到文档中的驱动程序。

索引器将搜索具有最相似嵌入的答案。(图片由作者提供)

匹配将包含诸如dociddoc和匹配match scores的数据。因为我们也使用了索引流程中的同一个索引器,所以我们需要再次将索引器 Pod 添加到flows/query.yml:

第三步。重新分级

(图片来自纪娜艾)

让我们假设索引器在此时返回前 k 个答案匹配,我们想要重新计算匹配分数以获得更好的结果。纪娜有一类称为排名器的执行者,特别是 Match2DocRankers 通过计算新的分数对查询的匹配进行重新评分。如果你看看纪娜中心的排名器, Levenshtein 排名器使用 Levenshtein 距离来重新计算比赛分数。

然而,我们不是使用距离度量来重新计算分数,而是希望在排名器中加载我们优化的 BERT 模型 FinBERT-QA,并通过使用问题和当前匹配答案的串联作为二进制分类任务的输入来重新计算分数。

这里的主要思想是将我们的查询文本和匹配(包含答案文本和匹配分数)传递给 Ranker,根据 FinBERT-QA 计算的相关性分数返回一个重新排序的匹配列表。然后,驱动程序将根据这个重新排序的列表更新文档中的匹配。

排名器使用 FinBERT-QA 重新计算匹配的分数。(图片由作者提供)

回想一下,Peas 可以在 Docker 中运行,这意味着我们可以简单地用我们的 Ranker 实现构建一个 Docker 映像,并在查询流中使用该映像。纪娜中心 API 让我们使用 Cookiecutter 来创建我们需要的所有文件的模板。让我们从确保安装了纪娜中心扩展开始:

pip install "jina[hub]"

构建自定义执行器

让我们首先创建模板,我们将需要为我们的自定义排名建立一个 Docker 图像。

1。设置。

jina-financial-qa-search/目录中键入:

jina hub new

这将弹出一个向导,帮助您完成整个过程。让我们将我们的执行器命名为FinBertQARanker,并确保选择4 - Ranker作为执行器类型。我们将使用jinaai/jina作为我们将要构建的 Docker 图像的基础图像。

You've downloaded /Users/bithiah/.cookiecutters/cookiecutter-jina-hub before. Is it okay to delete and re-download it? [yes]: yes
 executor_name [The class name of the executor (UpperCamelCase)]: FinBertQARanker
 Select executor_type:
 1 - Encoder
 2 - Crafter
 3 - Indexer
 4 - Ranker
 5 - Evaluator
 Choose from 1, 2, 3, 4, 5 [1]: 4
 description [What does this executor do?]: recomputes match scores using FinBERT-QA                
 keywords [keywords to describe the executor, separated by commas]: 
 pip_requirements []: 
 base_image [jinaai/jina]: 
 author_name [Jina AI Dev-Team (dev-team@jina.ai)]: 
 author_url [https://jina.ai]: 
 author_vendor [Jina AI Limited]: 
 docs_url [https://github.com/jina-ai/jina-hub]: 
 version [0.0.1]: 
 license [apache-2.0]:

按回车键后,你会看到一个名为FinBertQARanker的新目录。您的文件结构现在应该如下所示:

项目文件夹结构。(图片由作者提供)

我们将在__init__.py中实现我们的排序器逻辑,在tests/test_finbertqaranker.py中编写一些测试,并修改Dockerfile以包含构建图像所需的一切。

排名者的代号可以在 这里找到

2。填写重新分级的逻辑。

我们现在将在__init__.py中实现我们的逻辑,应该如下所示:

纪娜为具有不同功能的执行器包含不同的基类。我们将使用的基本排名器类称为 Match2DocRankers ,它具有重新计算匹配分数的功能。

我们先把BaseRanker的基类改成Match2DocRanker。让我们也导入 PyTorch 使用纪娜和其他一些模块,我们将需要,以及定义我们当前的目录。

我们的逻辑将在使用纪娜的TorchDeviceMatch2DocRankerFinBertQARanker类中实现。稍后我们将在Dockerfile中下载我们需要的模型。让我们假设现在在文件夹models/中有两个模型:(1) bert-qa/和(2) 2_finbert-qa-50_512_16_3e6.pt

(1) bert-qa:根据段落使用 BERT 重新排序,在 MS 宏数据集上进行 bert-base-uncased 微调

(2) 2_finbert-qa-50_512_16_3e6.pt : FinBERT-QA 模型——在 FiQA 数据集上微调bert-qa

我们首先指定bert-qa/作为将用于初始化的预训练模型,2_finbert-qa-50_512_16_3e6.pt作为将用于计算 QA 关联分数的模型,以及 QA 对的最大序列长度:

然后,我们向该类添加一个post_init函数,使用拥抱面部变形器加载二进制分类任务的模型。确保将模型设置为评估模式。

现在让我们实现一个私有的_get_score函数来计算问题和前 k 个答案匹配的相关性分数。我们首先连接问题和每个 top-k 答案,并对它们进行编码,以获得模型需要的输入(input_idstoken_type_idsatt_mask),使用来自 transformers 的标记器。

然后,我们将输入输入到模型中,并获得 QA 对相关的预测分数(label = 1)。我们将 softmax 函数应用于得分,以将预测得分转换为 0 到 1 之间的概率。然后,输出将是 QA 对的概率形式的相关性分数。

最后,让我们填写评分函数,该函数将用户的问题和纪娜的比赛分数作为输入,并使用_get_scores来重新计算新的分数:

3。编写一个单元测试

为了创建一个新的执行器,并使用纪娜中心 API 构建一个 Docker 映像,我们需要编写一个单元测试。我们可以在tests/test_finbertqaranker.py中找到这个的模板。我编写了一个简单的检查来计算给定查询的两个答案匹配的相关概率,并检查FinBertQARanker是否计算出与我们期望的相同的分数:

4。添加要求

除了纪娜,我们还在FinBertQARanker中使用 PyTorch 和变形金刚,所以让我们把它们添加到FinBertQARanker/requirements.txt:

torch==1.7.1
transformers==4.0.1

5。准备文档

让我们将我们的Dockerfile改为下面的内容,这将把模型下载到一个名为models/的文件夹中。

6。使用纪娜中心 API 构建 Docker 映像

我们终于准备好将FinBertQARanker构建成 Docker 映像了。在我们的工作目录中,让我们键入:

jina hub build FinBertQARanker/ --pull --test-uses --timeout-ready 60000

--pull如果我们的纪娜基础映像不在本地,则下载该映像。

--test-uses增加了一个额外的测试,以检查构建的映像是否可以通过纪娜的流程 API 成功运行。

--timeout-ready给我们的post_init函数加载模型的时间。

如果构建成功,您将看到以下消息:

HubIO@10240[I]:Successfully built ba3fac0f3a46
HubIO@10240[I]:Successfully tagged jinahub/pod.ranker.finbertqaranker:0.0.1-0.8.13
HubIO@10240[I]:building FinBertQARanker/ takes 6 minutes and 12 seconds (372.31s)
HubIO@10240[S]:🎉 built jinahub/pod.ranker.finbertqaranker:0.0.1-0.8.13 (sha256:ba3fac0f3a) uncompressed size: 3.3 GB

恭喜你🥳,你已经成功构建了一个标记名为jinahub/pod.ranker.finbertqaranker:0.0.1-0.8.23的 Docker 图像形式的定制执行器!接下来让我们看看如何在查询流中使用它。

一、创建自定义排名框

要使用我们的自定义排序器,FinBertQARanker,我们需要首先为排序器创建一个新的 Pod。让我们在pods文件夹中创建文件rank.yml。接下来,让我们将内容从FinBertQARanker/config.yml复制到pods/rank.yml,您应该有以下内容:

这将告诉查询流使用我们在 Exectuor 中实现的逻辑,FinBertQARanker/__init__.py。因为这个实现的代码被加载到 Docker 映像的workspace文件夹中,所以让我们在__init__.py之前添加workspace/

到目前为止,我们使用的编码器和索引器执行器都使用 Pods 中的默认驱动程序。由于我们创建了自定义执行器,我们需要告诉 Ranker Pod 使用哪个驱动程序。在这种情况下,我们将使用Matches2DocRankDriver作为Match2DocRanker基础 Ranker 类。因此,我们的rank.yml将如下所示:

好哇🎊我们现在有了一个定制的等级舱!接下来让我们看看如何在查询流中使用它。

二。在查询流中使用自定义排名器

像其他 Executor Pods 一样,我们只需要在doc_indexer之后添加ranker,并通过在标签名称前面指定前缀docker://来告诉查询流使用我们刚刚创建的 Docker image 和 Ranker Pod。最终的flows/query.yml应该如下所示:

请注意,Docker 图像的标签名称可能会根据当前的纪娜版本而改变确保相应地更改标签名称。

我们可以使用流程 API 在jupyter notebook中再次可视化查询流程,如下所示:

查询流可视化。(图片由作者提供)

这里我们看到我们的查询流有三个 pod,分别包含编码器、encoder和索引器、doc_indexer以及排序器、ranker。在查询流结束时,Ranker Pod 的驱动程序将根据我们的自定义 Ranker 计算出的概率,将文档中的匹配更改为一个重新排序的匹配列表。接下来,我们将看看如何在我们的app.py中访问这个决赛列表。

构建一个搜索应用程序

获取存储在文档中的匹配项和分数。(图片由作者提供)

由于我们的最终匹配及其关联概率存储在文档中,在app.py中,我们可以编写一个函数来打印出对用户输入的问题的响应。我们可以遍历文档中的匹配项d.matches,并打印出得分值和匹配的答案文本:

然后我们可以编写我们的search方法,该方法使用来自flows/query.yml的查询流,并将用户输入传递给print_resp。在f.search_lines()中,我们指定输入作为我们的用户查询,输出作为要打印的响应,以及我们想要检索的前 k 个答案。f.search_lines()很酷的一点是它自动为用户查询创建一个文档,就像 sugar magic 一样🍬!

万岁!🎉🎉🎉我们刚刚完成建立我们的金融问答搜索引擎!我们现在可以运行:

python app.py search

并尝试不同的问题!排名器可能需要一些时间来计算相关性分数,因为它使用的是基于 BERT 的模型。以下是问题示例列表:

• What does it mean that stocks are “memoryless”?
• What would a stock be worth if dividends did not exist?
• What are the risks of Dividend-yielding stocks?
• Why do financial institutions charge so much to convert currency?
• Is there a candlestick pattern that guarantees any kind of future profit?
• 15 year mortgage vs 30 year paid off in 15
• Why is it rational to pay out a dividend?
• Why do companies have a fiscal year different from the calendar year?
• What should I look at before investing in a start-up?
• Where do large corporations store their massive amounts of cash?

(图片由作者提供)

摘要

在这篇博客中,我介绍了纪娜的核心概念,并演示了如何构建一个生产就绪的财务 QA 系统。我还解释了如何使用纪娜中心 API 来创建一个 BERT 驱动的 Ranker 执行器。感谢纪娜提供的构建模块,我们可以在生产中轻松使用 SOTA 和强大的模型 FinBERT-QA。

我们刚刚用纪娜构建的神经搜索应用程序在我们自己的机器上本地运行,但也可以完全分布在网络中的多台机器上运行,使我们的应用程序高度可重用、可伸缩和高效。除此之外,常见的云原生特性,如持久性、调度、链接、分组和并行化都是现成的。

此外,还有其他领域的预训练 BERT 模型的变体,如生物医学、科学和法律。您可以使用这些模型来构建一个 QA 搜索应用程序,并对结果进行实验!

后续步骤:评估

如果你已经完成了本教程,你可能会疑惑,“我如何评估搜索结果?”。很棒的问题!纪娜有一个称为评估器的执行器类,并且实现了通用的评估指标,比如精度和倒数误差。评估是一个重要的步骤,可以让我们改进搜索结果。我们将在的下一篇教程中看到如何在我们的财务 QA 应用程序中添加评估器。

了解更多信息

要了解更多关于纪娜的情况,我推荐阅读以下文章:

  • 什么是纪娜和神经搜索?
  • 从那时到现在:神经搜索和纪娜的精选列表

并且查看他们的 Github 页面!

如果您想通过实践来了解纪娜,我鼓励您开始构建自己的示例并与社区分享,以帮助他们发展自己的开源生态系统!🚀例如,看看这个社区项目——与纪娜合作建造的律师变形金刚。

我们看到了纪娜是多么多才多艺和可扩展,我们可以使用自己的逻辑和模型为 NLP、计算机视觉和其他 ML 搜索应用程序创建各种搜索应用程序。 纪娜 Hub 是一个很好的起点,在这里你可以使用可用的执行器来构建其他类型的搜索引擎(针对图片、视频等……)或者使用纪娜 Hub API 创建自己的执行器!您可以随时回到本教程,再次浏览该过程。

社区

  • Slack channel —开发者讨论纪娜的交流平台
  • 社区简讯 —订阅纪娜的最新更新、发布和活动消息
  • LinkedIn——了解纪娜人工智能公司,寻找工作机会
  • 推特——关注纪娜·艾,并使用标签与他们互动#JinaSearch
  • 公司——更多地了解纪娜 AI 公司及其对开源的承诺!*

非常感谢 Joan Fontanals Martinez 的指导和反馈。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

原载于 2021 年 1 月 7 日https://jina . ai

如何使用 Python 和 Arduino 构建实时 SCADA 系统

原文:https://towardsdatascience.com/how-to-build-a-real-time-scada-system-using-python-and-arduino-7b3acaf86d39?source=collection_archive---------8-----------------------

创建记录和可视化真实世界数据的管道

SCADA 仪表板-作者可视。

介绍

我们这些曾经使用过 SCADA(监控和数据采集)系统的人,比如 OSIsoft 和 Oracle,都知道它们所提供的数据有多么宝贵。特别是对于数据和自然科学行业的许多人来说,SCADA 是按需提供真实世界数据的丰富来源。然而,这种系统并不便宜,普通人也不容易获得它们的服务。幸运的是,有一种方法可以用简单而廉价的设备创建自己的 SCADA 管道,并且很容易获得。在本教程中,我将向您展示如何设置一个环境温度信号,该信号将记录数据,并在您的计算机上显示一个实时仪表板。

1.阿尔杜伊诺

首先,我们将使用 Arduino Uno 板从 MLX9061 红外温度计读取温度值。

Arduino &红外温度计线路图——图片由作者提供。

如上所示连接红外温度计后,继续将以下程序上传到 Arduino。

如果您还没有这样做,首先使用 Arduino IDE 的库管理器在工具>管理库中下载并安装 Adafruit_MLX90614 库。

要验证 Arduino 和温度计是否按预期工作,请打开串行监视器(工具>串行监视器),确保每秒打印一次温度记录,如下所示。

Arduino 串行监视器—图片由作者提供。

或者,您也可以打开 Arduino 的串行绘图仪(“工具”>“串行绘图仪”),查看环境温度的实时曲线图,如下所示。

Arduino 串行绘图仪—图片由作者提供。

2.计算机编程语言

既然 Arduino 和红外温度计正在工作并将数值打印到串行端口,我们需要获取 Python 中的读数来生成我们的 SCADA 仪表板。要通过串行 USB 连接将 Python 脚本与 Arduino 接口,我们需要下载并安装 Pyserial。继续启动 Anaconda 或您选择的任何其他 Python IDE,并键入以下命令:

pip install pyserial

为了生成一个可以与我们的仪表板交互的图形用户界面,我们将使用 Streamlit 。这个高度通用的 web 框架允许您快速开发应用程序并将其部署到 web 服务器上,或者在您的浏览器上本地运行它们。为了显示当前温度读数以及所有先前温度记录的图表,我们将使用按钮。这是 JavaScript 的高度交互式数据可视化框架的 Python 绑定,允许您在指尖渲染令人眼花缭乱的视觉效果。

继续将以下源代码保存在本地目录中:

上述代码将启动到 Arduino 的连接,然后将按照指定的迭代次数从串行端口连续读取值。它将不断呈现和更新仪表和图表。最后,在循环完成后,端口将被关闭,一个包含所有记录的 CSV 文件将保存在您的本地目录中。

要运行上述脚本,请在 Anaconda 提示符下键入以下命令:

cd C:/Users/.../local_directory
streamlit run temperature_dashboard.py

这就是你在本地浏览器上运行的自己的实时 SCADA 仪表板。

SCADA 仪表板-作者图片。

提高

现在,您已经创建了一个具有实时数据可视化功能的 SCADA 系统,您可以通过使用 Arduino Uno WIFI 来进一步增强该系统,从而扩展您的信号范围。更多信息请参考 Arduino Uno WIFI 的配置指南。此外,您可以将各种不同的第三方传感器甚至致动器连接到同一个 Arduino,以增强监督和控制。

如果您想了解更多关于数据可视化和 Python 的知识,请随时查看以下(附属链接)课程:

使用 Streamlit 开发 Web 应用程序:

https://www.amazon.com/Web-Application-Development-Streamlit-Applications/dp/1484281101?&linkCode=ll1&tag=mkhorasani09-20&linkId=a0cb2bc17df598006fd9029c58792a6b&language=en_US&ref_=as_li_ss_tl

使用 Python 实现数据可视化:

https://www.coursera.org/learn/python-for-data-visualization?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW2aEwvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

面向所有人的 Python 专业化:

https://www.coursera.org/specializations/python?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW16Ewvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

物联网专业化编程简介:

https://www.coursera.org/specializations/iot?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgQzrEwvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

GitHub 资源库:

https://github.com/mkhorasani/arduino_python_scada_system

新到中?您可以在此订阅并解锁无限文章。

如何构建可伸缩的数据注释策略

原文:https://towardsdatascience.com/how-to-build-a-scalable-data-annotation-strategy-4d318da8e7be?source=collection_archive---------30-----------------------

找到合适的工具,雇佣或外包注释者,以及 ML 辅助注释

汤姆·威尔森在 Unsplash 上的照片

您可能知道,数据科学团队大约 80%的时间用于创建和管理培训数据。常见的问题通常与糟糕的内部工具、标记返工、查找所需数据以及与协作和迭代分布式团队数据相关的困难有关。

频繁的工作流更改、大量的数据集以及缺乏适当的数据培训工作流会阻碍公司的发展。当公司发展太快时,这些问题会变得更糟,不管是哪个行业的初创公司都是如此。

可扩展的训练数据策略的这种需求的一个完美例子来自竞争激烈的自动驾驶汽车行业。应用于自动驾驶车辆的计算机视觉是一个复杂而竞争激烈的市场。由于复杂性,高质量训练数据的定义和范围经常变化。如果您的团队不能适应(包括您注释数据的能力),客户的不满意会让您损失整个企业。

确定正确的数据注释策略

有几个原因可以解释为什么您的训练数据策略必须快速适应。这可能是因为新产品功能会产生大量需要标记的原始数据,或者您决定开发一个需要大量实时数据才能正常运行的解决方案。

此外,ML 模型的性能经常令人失望,尤其是在概念验证或早期版本中。当已经花费了大量的金钱和时间时,在开发过程的后期才找到最佳的数据注释策略。

此外,一些基于大量数据的人工智能项目通常需要一个反馈回路。通常的情况是,当神经网络被用于随着每个新的情况而改进,并且连续地处理边缘情况。ML 需要迭代的数据注释过程。数据注释反馈循环和敏捷方法是成功的关键。

不管您的情况如何,您都可以通过雇佣一个昂贵的内部注释团队、与自由职业的注释者一起工作或者依靠数据注释平台来做出反应。让我们来看看每种方法的优缺点。

内部团队

一些公司选择创建内部数据注释团队。构建内部数据注释的一个很好的理由可能与安全性有关。也许你的项目本质上需要无法在线传输的标签数据。

构建内部数据注释肯定会带来过程控制和 QA 的好处,但也会带来额外的成本和风险:

  • 人力资源,
  • 新团队的管理,
  • 支持数据注释和工作流程的软件开发,
  • 员工不断流动的风险

此方法不可伸缩。像所有与人工智能相关的公司一样,随着你在雇佣、管理和培训员工方面的投资,你的数据需求可能会根据你当前和未来的项目发生重大变化。具体地说,如果您决定建立一个内部数据注释团队,您还将需要注释工具。不幸的是,试图构建内部技术解决方案的团队通常会损失战略开发时间,而不是外包数据注释过程。

虽然这种方法在项目开始时看起来更具成本效益,但由于操作基础设施的挑战、缺乏培训数据知识以及内部注释者的技能差距,它通常不是可伸缩的解决方案。

除非你为一家大型科技公司工作,否则你的内部工具很可能永远不会像由许多专业开发人员构建并迭代数年的端到端数据标记工具那样先进。第三方数据注释工具通常更加复杂,并且配备有经验丰富的注释者和熟练的项目经理。

外包

在这种情况下,外包是指支付自由职业者执行精确的任务。报酬通常很低,并且基于工作量。这个解决方案的一个典型例子是 Amazon Mechanical Turk。

这种方法被认为是与按需工作人员协作的一种简单方式。但是,这迫使您准确定义外派,确定员工要求和支付条件。通常,工人很少被审查,或者可能对正确注释数据或对边缘情况做出反应有模糊的想法。所以,有没有必要花时间训练他们。

一些公司已经建立了一个群体即服务数据平台和许可数据平台。这些平台管理工人的工作流程和采购。利用这样的数据平台将使您能够以有竞争力的价格快速扩展。然而,因为这种方法通常用于小规模和临时的项目,所以没有反馈回路和机会来随着时间的推移培训贴标机。

另一个值得一提的因素是,外包贴标机往往缺乏专业知识,导致培训数据质量差。

数据安全也是一个挑战,因为外包贴标机通常在不安全的计算机上独立工作。根据您项目的重要性、复杂性和范围,外包平台可能是标记您数据的一种简单而廉价的解决方案。但是低价格是以降低数据集质量、一致性和保密性为代价的。

一些媒体已经调查了这些平台上贴标机的恶劣工作条件。其中一些平台以招聘低薪远程员工而闻名,并不真正关心会影响数据质量指标的工作条件。

数据平台+劳动力

市场上可用的另一种解决方案与已经构建并销售自己的数据平台的公司有关。这些自助服务平台使公司能够利用高级功能、强大的 UI、高级注释工具以及某些情况下的 ML 辅助注释功能,高效地自我管理他们的注释项目。

与外包平台相比,ML 团队可以通过利用这些平台来产生高质量的培训数据,同时减少贴标时间,从而更轻松地管理贴标工作流程。他们还可以依靠一些随需应变的项目经理来帮助构建他们的项目。非高级透明质量流程也是这些平台产品的一部分。

这些总部位于 SaaS 的平台以其快速扩展和提供有竞争力的价格的能力而闻名。然而,他们中的大多数高度依赖合作伙伴来获得必要的非合同劳动力。

这种依赖性往往导致他们的贴标机缺乏专业知识,正常运行时间问题,并最终导致低质量的标签数据集(复杂项目往往如此)。

另一个值得一提的元素是,这些平台通常主要专注于特定行业(例如,自动驾驶汽车行业的数据标签)或人工智能子领域(例如,计算机视觉或 NLP)。

平台+全面管理的员工队伍

已经建立和销售自己的数据平台并拥有完全管理的劳动力的公司在市场上提出了完整的数据注释解决方案。

与其他解决方案的显著区别在于,此类平台依赖经验丰富的贴标机和主题专家来识别边缘案例并推荐注释最佳实践。

目标是通过当天或次日实施快速适应新的指导原则或培训数据要求。

这些平台严重依赖于人工专业知识和自动化数据注释工具的组合。目标是利用人类的专业知识来主动识别边缘案例,推荐指南,并更快地将模型投入生产。此外,贴标机利用先进的工具来减少标注时间。这些平台可以处理整个训练数据周期。

在定价方面,全托管服务的成本高于其他数据注释解决方案。

ML 辅助注释

除了手动标记的高成本之外,随着公司的发展,数据量也会增长。人工标注在处理大量数据时有其局限性。 ML 辅助标注减少了对人工标注的依赖,为这一问题带来了真正的答案。

ML 辅助标注背后的主要思想是利用 AI 来完成接近完美的标注(通过覆盖所有重要的标注类型)。理想情况下,目标是让人类注释者花费更少的时间进行注释,并将更多的精力放在纠正复杂的案例上,以进一步开发 ML 模型。

从半自动到有时全自动的工具,ML 辅助注释工具的定义和自动化水平可以有很大的不同。

一种方法包括只标记少量图像,以从头开始训练神经网络模型或利用预训练的模型。之后,该模型可以预测一组未标记图像中的类别。稍后,人类注释者会在必要时检查并纠正它们。通过这样做,注释任务变成了评估任务。此外,手动注释的附加价值在于关注最困难的边缘情况。当涉及大型数据集时,ML 辅助注释工具的 ROI 已经被证明。

这个过程要快得多,因为注释者可以很容易地看到建议的标签,并且只需要检查它。其他解决方案仅显示具有最低或最高标记确认置信度的标记图像。

数据注释的灵活性意味着花几分钟而不是几天的时间在数据集中寻找错误。

ML 辅助的注释工具可以集成一个反馈环。在查看图像之后,用户可以将它们添加到训练集中,以训练新的/更准确的神经网络。其他算法,比如强化学习,可以复制标注者的决策过程。增强代理学习基于由人类专家完成的注释来注释警报数据。

一些数据注记工具在影像注记中提供了与类别无关的面标注工具。注释器标记选择的对象,网络提供多边形预测。还可以在未标记的图像上利用预训练的分割模型,自动创建粗略的遮罩。然后,用户调整蒙版的轮廓。其他功能包括在标签工具和方法之间轻松切换,以更少的点击次数更快地获得输出。

保证质量&截止日期

除了决定创建您的内部数据注释团队、外包或依赖提供精选劳动力的基于 ML 的高级数据平台之外,当您的公司快速发展时,采用能够帮助优化工作流的工具变得至关重要。理想情况下,如果您有一个工具来无缝地重新划分任务的优先级,提供反馈,并在生产中监控模型,那将是最好的。

可扩展的数据训练策略也需要报告。对训练数据集中所表示的类和边缘案例的深入了解是有价值的信息,可以优先考虑和定位要注释的数据,以实现快速模型开发。

这使我们认识到拥有一个高级的可定制的仪表板的重要性,该仪表板具有实时分析和错误报告,以保持您的项目的详细概述,并测量注释者的质量和生产力。这个仪表板还应该使您能够根据您的训练数据动态地增加或减少工作负载,设置标记规则,并轻松地集成原始数据,可能通过 Rest API。

正如本文所见,有几种解决方案可以帮助您的公司快速、轻松地创建可伸缩的数据注释策略。对于需要可扩展性的公司来说,端到端数据注释平台是最具成本效益的完整解决方案。然而,在一些特定的项目中,建立一个内部数据注释团队也是有意义的。

如果你总体上喜欢这篇文章和我的写作,请考虑通过我在这里的推荐链接注册 Medium 来支持我的写作。谢谢!

如何免费建立一个简单的作品集网站

原文:https://towardsdatascience.com/how-to-build-a-simple-portfolio-website-for-free-f49327675fd9?source=collection_archive---------11-----------------------

由 envato elements 的 alexacrib 使用图像创建(经许可)。

数据科学 | 机器学习

在不到 10 分钟的时间内从头开始一步一步的教程

在这篇文章中,你将学习如何免费建立一个作品集网站来展示你的项目,无论是数据科学、软件开发还是网页开发。投资组合网站的一些好处有助于潜在雇主看到你经验的广度和深度,如果你来自一个非常规的背景(比如自学成才的专业人士等),这可能会特别有帮助。).

我们今天将要建立的作品集网站将会在 GitHub 页面上免费托管。我会假设你有很少或没有 HTML 的经验。但是如果你有以前的经验,这个教程应该花费你更少的时间来完成。

我们这里有很多内容要讲,不再多说,让我们开始吧!

还可以看看 YouTube 上的同名视频( 如何免费建立一个简单的作品集网站 ),你可以在阅读这篇博文的同时观看。

1.注册一个 GitHub 帐户

由于我们要在 GitHub 页面上托管网站,一个先决条件是要有一个 GitHub 帐户。所以如果你还没有,那就去注册一个吧。

前往 GitHub 网站注册。(右上方链接)。

2.创建新的存储库

因此,我们现在将创建一个新的存储库,作为您的新投资组合网站的主页。网站的内容(即文本、图像和您希望在网站上显示的任何其他文件)将包含在此存储库中。显示在您网站上的文本将存储在一个 Markdown 文件(.md文件)中,而不是 HTML 网页,我们将在接下来的几分钟内处理这个文件。

登录你的 GitHub 账户,点击顶部导航栏最右边的+按钮,下拉菜单中的New repository按钮,启动一个新的资源库,如下图所示。

点击右上角的+号,启动一个新的存储库。

在此页面上,输入新存储库的名称。在本例中,我们将输入Portfolio,但是您也可以使用任何其他名称,例如您的全名(但是请确保使用下划线或破折号,而不是空格,例如John_DoeJohn-Doe)。

输入新存储库的名称。

为了允许网站公开,我们勾选了Public选项。

这里需要注意的是,我们已经勾选了一个框,这样一个README.md文件将会随着存储库的创建而自动创建。正是这个文件,网站内容将被放置在里面。

最后,点击Create repository按钮来创建存储库。

下面的屏幕截图将显示您的新存储库的主页。注意这里README.md的内容是空的。

2.为存储库设置 GitHub 页面

默认情况下,存储库还不是一个网站,所以我们必须为它激活 GitHub 页面。为此,点击选项卡最右侧的Settings按钮(如 1 所示。下图中的黄色方框)。

接下来,您要点击左侧面板上的Pages按钮(如 2 所示。下图中的红框),这将重新加载页面。

要实际激活 GitHub 页面,请单击位于GitHub Pages部分的Source子标题下的None下拉按钮(如下图 3.1 绿色框所示),这将显示main分支,一旦显示,请单击它(如下图 3.2 绿色框所示)。

为新创建的存储库激活 GitHub 页面。

既然 GitHub Pages 已激活,您应该能够看到您的作品集网站的 URL,如下图中黄色高亮框所示。

在这个例子中,正在创建的 URL 在https://dataprofessor.github.io/Portfolio处可用,其中dataprofessor是我的 GitHub 用户名,Portfolio是存储库名称。记下这个 URL 并保存在手边,因为我们将在应用网站主题后访问它。

还要注意Branch现在被设置为main,如下图红框所示。

现在,我们将为我们的网站选择一个主题。点击Theme Chooser副标题下的Choose a theme按钮。

GitHub Pages 现已激活,并显示其 URL。(以黄色高亮框显示)

正如你将在下面的截图中看到的,有几个主题供你选择。在本例中,我们将选择Cayman主题并点击Select theme按钮。

为作品集网站选择主题。

为了让你开始你的新网站的布局,你会看到README.md文件现在填充了示例文本。

向下滚动到页面底部,点击Commmit changes按钮继续。

现在,通过粘贴我们之前记下的 URL 来访问我们的网站,在本例中是https://dataprofessor.github.io/Portfolio

下面的屏幕截图显示了我们的网站,在选择主题后,示例内容已经自动填充了README.md文件。

带有示例内容的网站截图。

3.将我们的信息添加到网站

现在,让我们继续将我们自己的个人资料添加到网站中。

正如我前面提到的,网站的内容包含在README.md文件中,我们在上面也看到了选择 Cayman 主题的示例内容。

在下面的代码框中,我为您提供了一个假设的概要信息,您可以将其用作模板。

让我们将下面的内容复制并粘贴到README.md文件中。要保存文件,向下滚动并点击Commit changes按钮。

上面代码框的内容是用 Markdown 写的,这是另一篇博文的主题。关于制作网站时可以参考的减价清单,我强烈推荐来自 亚当-p 的清单。

现在,再次刷新投资组合网站以查看新添加的个人资料信息。

一个假想的有抱负的数据科学家 John Doe 的投资组合网站。

4.向网站添加图像

一张图片胜过千言万语,让我们用一些图片来增加网站的趣味吧。对于这个例子,我们将使用来自 Unsplash 的照片,它提供了大量的库存照片,您可以免费使用。

在我们的网站上搜索图片。

4.1.为项目 1 寻找图像

让我们搜索图片,用于我们假想的有抱负的数据科学家 John Doe 的作品集网站。从网站上可以看到,无名氏的项目 1 属于 加密货币 。因此,我们会找到一些相关的图像。

以下是关于加密货币图片的搜索结果。

右上角的图像看起来很适合项目 1 ,所以让我们使用它。所以你可以继续点击它。出现如下所示的弹出窗口,然后点击Download free按钮的向下箭头触发下拉菜单。这里,我们将采用Small (640x427)分辨率。

来自 Unsplash 的图像,我们将用于项目 1。照片由andréFran ois McKenzie在 Unsplash 上拍摄。

下载图像后,底部会出现一个弹出窗口,为您提供属性文本和链接。你只需点击下图所示的Copy to clipboard图标。我们会将此粘贴到README.md文件中,以便此类信息包含在投资组合网站中。

从 Unsplash 下载图像时出现的属性弹出窗口截图。

4.2.为项目 2 寻找图像

由于 John Doe 的项目 2 (参见包含来自README.md文件的内容的代码框)是关于建立一个加密货币交易机器人,那么我们将使用下面的图像。

来自 Unsplash 的图像,我们将用于项目 2。马克西姆·霍普曼在 Unsplash 上的照片。

4.3.上传图片到 GitHub 库

一旦图片下载到你的电脑,现在让我们把它上传到我们的 GitHub 库。

为此,点击Add file按钮,弹出一个下拉菜单。点击Upload files链接。

点击“添加文件”按钮时“上传文件”链接的屏幕截图。

可以通过两种方式上传文件:(1)直接将文件拖放到上传框中,或者(2)点击上传框中的choose your files链接。然后,点击页面底部的Commit changes按钮。

通过直接拖放到上传框或点击“选择您的文件”链接来上传文件。(这将弹出一个窗口,允许我们选择要上传的文件)。

GitHub 作品集截图。这里我们可以看到有 4 个文件,由 2 个上传的图片组成,README.md 文件和 _config.yml 文件(主题选择后自动生成)。

4.4.给网站中的图像添加属性

在使用 Unsplash 的免费图片时,提供图片的引用也是一个很好的做法。为了您的方便,当您从 Unsplash 下载图像时,出现的弹出窗口会让您选择获取属性文本和链接(如第 4.1 节的最后一幅图像所示),您要将它们复制并粘贴到README.md文件中。

对于项目 1项目 2 ,以下两个属性代码块分别如下:

为了通过 Markdown 语法将图像添加到网站,我们将分别对项目 1项目 2 使用以下代码行:

让我们将上述 4 个代码块添加到README.md文件中项目 1项目 2 的标题下,我们将得到以下代码:

5.完整的作品集网站

恭喜你!现在,您已经在不到 10 分钟的时间内完成了作品集网站的创建!

范例作品集网站:https://dataprofessor.github.io/Portfolio/

现在,您可以与全世界分享您的作品集网站(例如,在您的 LinkedIn、Twitter、名片等个人资料中包含 URL)。)!随着项目列表的增长,记得维护并定期更新网站。

请随意与我分享您的投资组合网站的链接。

订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

关于我

我是泰国一所研究型大学的生物信息学副教授和数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub page )。

https://www.youtube.com/dataprofessor

在社交网络上与我联系

✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:【t2t

如何打造一份扎实的数据科技简历

原文:https://towardsdatascience.com/how-to-build-a-solid-data-science-and-tech-resume-e899daceb271?source=collection_archive---------6-----------------------

给我的数据科学和技术学弟学妹们的建议

建议从谷歌和 Visa 等公司获得大的 DS-Tech 报价

来源( unsplash )

问题陈述

我如何建立我的简历?

DS-Tech 工作需要哪些简历?

在这里,我想分享我的简历,它让我被谷歌录取。我也和内部和外部的招聘人员谈过,希望这个建议能帮助你建立一份出色的简历,在一家大公司找到工作。

什么是简历?

简历类似于 pokedex。在虚拟的口袋妖怪世界中,小智每次想抓一只口袋妖怪时都会使用 pokedex。pokedex 是一个快速的描述,总结了一种口袋妖怪和关键的属性/个性。

然后 Ash 会利用这些信息迅速决定他是否要捕捉口袋妖怪。这些信息需要很好地总结,以便快速做出决定,否则口袋妖怪会先攻击或逃跑。

同样,你的招聘人员和招聘经理需要决定你是否非常适合这家公司,并决定他们是否愿意花他们的资源来雇佣你。再慢一点,其他招聘人员可能会先联系你。

你是招聘者的 KPI

所以现在的问题是:

你如何最大限度地让招聘者注意到你?

资料来源(热图生成器)

台阶

根据我的经验,制作一份有吸引力的简历有 5 个步骤。

  1. 了解你的受众:了解你申请的职位,让你的简历能够解决招聘经理的问题。
  2. 创建一个摘要:创建一个 TL:DR 来引导招聘人员了解关于你的重要片段。
  3. 讲述故事:创造一个清晰的故事来表明你产生影响的经历。这里可以用星的一般指引。
  4. 证明影响的事实:保持简单甜蜜(接吻)。写清楚历史相关的故事。
  5. 格式化简历:校对并确保简历清晰。

在更详细地剖析这些观点之前,我想和你分享一下我最近的一页简历。

我的一页简历(来源于作者)

了解你的受众

我们写作是为了让别人阅读并感兴趣。在大多数情况下,我们需要在制作一份有吸引力的简历之前了解招聘人员需要什么

以下是我们想从总体上考虑招聘人员的一些事实:

  • 招聘人员很忙。他们为一个空缺职位筛选数百份简历。
  • 招聘人员想要雇用你。他们有动力雇用你作为他们的关键绩效指标(KPI)。
  • 招聘人员关注文化/工作契合度:他们需要确保他们有适合公司/工作描述(JD)的优质候选人

考虑到这一点,你的策略应该是:

  • 用简单明了的方式压缩你的简历,以赢得招聘者的尊重。
  • 包括让你脱颖而出的艺术品/作品集/故事。例如,如果 Desc (JD)的工作重点是数据挖掘,那么就提到你最近的大规模提取-转换-加载(ETL)管道项目。
  • 理解关键词(例如:数据挖掘、编程语言等)招聘人员正在寻找并以有意义的方式放置它们。大多数招聘人员会先浏览,然后阅读其中的一小部分。。

创建摘要

尊重招聘人员的时间

你的总结应该浓缩成简单的 3-4 句话,概括你是谁以及你如何为公司增加价值。

就我个人而言,我会将它分成多个部分:

  • 【目前工作经历】 Vincent 担任机器学习工程师(MLE),拥有 Google LLC、Visa Inc .和 Lazada 的相关工作经验。
  • 【教育】 文森特是佐治亚理工学院的毕业生
  • 【当前重要任务/关键词】 谁使用了先进的 ML 算法和 MLOps 来保护 Chrome、Gmail 和 Android 用户免受钓鱼攻击。
  • 【微分器】 在空闲时间,他为在全球拥有 100 多万观众的数据科学媒体撰写文章,在 Kaggle 上编写代码,并为铁人三项训练。

显然,摘要应该与你的身份和公司的需求紧密相关。例如,如果你的工作需要具备这种技能的候选人,你可能希望专注于你的 Android 应用程序开发的总结。

讲故事

记住你是在为你的读者写作。

重点关注:

  1. 创造引人注目的故事,展示你如何为公司做出贡献。
  2. 证明你能解决问题,并把价值带到桌面上。这是每一次数据面试都在寻找的。

通过遵循这三条建议,你将会讲述一个引人注目的故事来吸引招聘者的目光。

  • 【而不是】 通过这个项目/认证,我学会了利用深度学习进行物体检测。
  • 【考虑】 通过这个项目,我使用具有深度学习的对象检测来捕捉 50%以上的滥用,这节省了 500 万美元

但是我没有一个令人信服的故事…

最终要脱颖而出,你需要准备一个伟大的投资组合,创造引人注目的故事。我在下面的文章中谈了更多的细节。

证明影响的事实

用你的事实简明扼要地突出技能。

这意味着用数字来表示你对以前公司的影响。

最终,你的数据驱动力越强,你的故事就越真实,招聘人员就越有可能抓住你。

  • 我已经从检测滥用广告中节省了很多钱
  • 我已经从检测辱骂性广告中节省了 500 万美元

格式化你的简历

招聘人员有偏见。所以他们可能会因为你简历内容之外的因素而拒绝你。

例如,招聘人员可能会根据你简历的整洁程度来判断你的文化契合度。他/她可能会根据他/她读到的东西来推测你的个性。

我听说过一个我认为非常符合职位描述的可靠候选人被拒绝,因为他们没有标准化句号(。)在他们的简历上签名。

如果你面临类似的拒绝,那将是一种耻辱。

因此,请确保:

  • 创建易于阅读的格式。它又短又干净。
  • 使用标题线突出关键信息。
  • 校对是否有错字

常见问题

LinkedIn 怎么样?

对我来说,LinkedIn 招聘人员的目标是“一般”的潜在候选人,而不是简历中的“特定”候选人。

在 LinkedIn,招聘人员会采取积极的方式进行猎头,而在简历中,申请人会采取积极的方式进入面试。

创建一个稳固的 LinkedIn 可以为你的职业生涯创造巨大的优势。比如从 LinkedIn,可以被 Google 猎头。

我的谷歌招聘人员在 LinkedIn 搜索引擎上插入“数据挖掘”一词后,发现我在顶部的个人资料中。

因此,对 LinkedIn 的一个一般建议是遵循这个 SEO 指南,放置与你的关键优势相关的故事/关键词,让 LinkedIn 搜索引擎做剩下的工作。

最佳简历长度是多少?

一般来说,如果你不申请研究,你的招聘人员应该对你的简历的 1-2 页感到满意。

就我个人而言,我建议用一页纸来确保你能抓住最重要的影响,而不是包括表面的细节。你的简历越短,你给吹毛求疵的招聘人员带来的错误就越少。

好的,下一步是什么?

在你完成一份出色的简历后,你可能想:

  • 构建终极数据科学组合。
  • 赢得你的数据面试。

我真诚地希望这些技术能帮助你在数据科学/技术领域发展事业。

结论

希望一旦你读了这篇文章,你就知道如何写简历了。如果你有进一步的想法,请在评论中告诉我。

  1. 了解你的受众:了解你申请的职位,让你的简历能够解决招聘经理的问题。
  2. 创建一个摘要:创建一个 TL:DR 来引导招聘人员了解关于你的重要信息。
  3. 讲故事:创造一个清晰的故事来表明你产生影响的经历。这里可以使用星的一般引导。
  4. 证明影响的事实:保持简单甜蜜(接吻)。写清楚历史相关的故事。
  5. 格式化简历:校对并确保简历清晰。

关于作者

文森特用 ML @ Google 对抗网络滥用。文森特使用高级数据分析、机器学习和软件工程来保护 Chrome 和 Gmail 用户。

除了在谷歌的工作,文森特还是乔治亚理工学院计算机科学硕士校友、三项全能运动员和面向数据科学媒体的特约作家,该杂志在全球拥有 100 多万观众,为有志于数据科学的人和数据从业者提供指导。

最后,请通过 LinkedIn Medium Youtube 频道 联系文森特

索利·德奥·格洛里亚

如何建立一个超级简单的手写数字识别器

原文:https://towardsdatascience.com/how-to-build-a-super-easy-handwritten-numbers-identifier-463850ab7d68?source=collection_archive---------39-----------------------

余弦相似度的初学者友好使用

当你开始机器学习时,有几个众所周知的数据集(例如🥀的虹膜数据集)。其中有一个简单、流行和有趣的图像数据集,即由大量手写数字组成的 MNIST 数据集📝 [1].

在这里,我们将使用一个令人难以置信的简单想法来从这些图像中获取信息:两个向量之间角度的余弦。因此,这对 ML 或 DS 领域的新手来说尤其有利😉。你可能熟悉矢量的点积。在这种情况下,你可能知道它可以通过两种方式获得,分量乘积之和,幅度与角度余弦的乘积,。对于三维空间中称为 A 和 B 的两个向量,我们有:

这被扩展到多个(有限)维度,并将所谓的相似度定义为角度[2]的余弦:

以这种方式,指向相同方向的两个向量,因此是“相似的”,具有接近 1 的相似度,并且当它们更不相似时,它会变得更低值(低至-1)。

到目前为止还不错,但现在让我们转向手写数字图像,以及如何使用这个概念来识别其中哪些数字是相似的。

一些 MNIST 数字。图片作者。

使用 Scikit-learn,可以轻松访问 MNIST 数据集[3]:

这里 X 包含了向量形式的每一位的数据信息。每个图像是 28×28 像素的矩阵,因此 X 向量有 784 个条目。这些向量就是我们想要比较的。为了尽可能简单起见,我将重点放在与零图像相对应的 X[1] 数字上,如下图所示:

对应于 X[1]的数字的绘图。图片作者。

任务是找到类似于X【1】的向量,并且假设它们也是零。下面的代码解决了这个问题,假设您已经导入了 numpy:

这里 j=1 (所以X【j】是我们想要的零) i 遍历前 5000 个元素。在第 6 行,我们用 pp 代表 X[i]X[j] 之间的点积。然后,在第 9 行,它除以给出角度余弦的向量范数的乘积(相似度)。请记住,我们希望这些值接近 1,所以从第 10 行到第 14 行,我们使用高斯函数来过滤接近 1 的值。sigma 的值可以考虑到最大的 sigma 来调整,我们将接受更多可能不太相似的向量。在第 13 行中,有一个条件,只取大于 0.3 的高斯函数的高度值,以确保所有向量对应于与所选向量相似的零。以下是这些值的结果:

检测到的零类似于第一次遇到的零。图片作者。

太神奇了!!它工作得很好,🥂.这里需要注意的是,这些不是所有的零,只是那些与我们选择的第一个更相似的零。但是,肯定有其他书写零的方式,让位于相同数字的不同形状。你可以用其他数字试试,只要这个数字有“好的形状”,就能得到好的结果。我的意思是,有些数字非常特殊,即使是人类也很难识别😅。

我在一个与基因组学相关的黑客马拉松中使用了同样的想法来识别肾脏疾病中表达的基因,并且工作得足够好以至于赢得了一个荣誉提名🔥。作为我的第二次黑客马拉松还不错!因此,除了简单之外,不要低估这项技术。

如果您想使用上面显示的代码,这里有 Colab 笔记本的链接:

https://github.com/napoles-uach/MediumPost/blob/main/CosineSimilarity.ipynb

感谢阅读!!

参考资料:

https://en.wikipedia.org/wiki/MNIST_database。

https://en.wikipedia.org/wiki/Cosine_similarity。

https://scikit-learn.org/stable/modules/generated

/sk learn . datasets . load _ digits . html

查看我最近写的其他帖子:

如何使用 Streamlit 为 2021 年的模型构建 UI

原文:https://towardsdatascience.com/how-to-build-a-ui-for-your-model-in-2021-using-streamlit-3d1656fce3b8?source=collection_archive---------39-----------------------

Streamlit 是一个开源的 Python 库,可以为各种目的构建 UI,它不局限于数据应用/机器学习。它简单易学,几行代码就可以创建一个漂亮的 web 应用程序。

查尔斯·德鲁维奥在 Unsplash 上拍摄的照片

目录

  • 先决条件
  • 安装所需的库
  • 逻辑回归模型
  • 简化用户界面
  • 结论

为什么应该使用 Streamlit?

Streamlit 是一个 Python 库,它帮助我们在没有 HTML/CSS/JS 的情况下为我们的模型开发 ui。大多数模特死在 Jupyter 笔记本里,没有吸引力。但是,使用 Streamlit,您可以为您的模型创建一个干净的 UI,并向其他人展示它。构建 UI 可以让用户以更友好的格式使用您的模型。

  • 你不需要处理 HTML/CSS/JSS。
  • 它支持降价。
  • 它提供了许多预构建的小部件,进一步减少了构建 UI 所花费的时间。
  • 构建响应性用户界面。
  • 使用 Streamlit 共享轻松部署 Streamlit 应用程序。
  • 它是开源的,如果需要,你可以创建自己的小部件。

本教程将建立一个逻辑回归模型来预测一个人是否会在泰坦尼克号灾难中幸存。在构建模型之后,我们将使用 Streamlit 为我们的模型构建一个 web 应用程序和一个 UI。web 应用程序将让用户输入值并获得预测的结果。

先决条件

本教程的重点是 Streamlit,所以应该熟悉使用 scikit-learn 构建 ML 模型。

  • 很好的理解 Python。
  • 对数据清理和标准技术有基本的了解,如数字编码、一键编码。
  • 熟悉 scikit-learn 库。
  • 熟悉逻辑回归有所帮助,但不是必需的。
  • 熟悉熊猫图书馆。
  • 对 Matplotlib 库的基本了解。

安装所需的库

python -m venv venv
venv/Scripts/activate
pip install streamlit,scikit-learn, pandas, matplotlib

首先,我们需要创建一个虚拟环境来管理我们的包并安装所需的包:streamlit、scikit-learn、pandas 和 matplotlib。安装完成后,键入以下命令以确保 streamlit 已按预期安装。

streamlit hello

这将启动一个样例 Streamlit 应用程序。你可以在命令行上按 ctrl+C 来停止应用程序。

导入必要的库

我们需要导入所有已安装的库。

import streamlit as st
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt

逻辑回归模型

首先,我们将加载 Titanic 数据集,并操作我们的数据集以满足我们的要求。你可以从 Kaggle 下载数据集。

加载数据帧

我们导入数据集并创建数据帧。

train_df = pd.read_csv("train.csv")
print(train_df.head())

您可以打印数据帧来检查其中的列。

在逻辑回归模型使用数据之前,我们需要对数据执行以下操作。

  • 给特征“性别”分配一个数值
  • 对功能“Pclass”使用一键编码
  • 填写年龄栏中缺少的值。
  • 仅选择所需的功能。

我们将定义一个函数来转换我们的数据,使其可用于我们的逻辑回归模型。

操纵数据

def manipulate_df(df):
	# Update sex column to numerical
	df['Sex'] = df['Sex'].map(lambda x: 0 if x == 'male' else 1)
	# Fill the nan values in the age column
	df['Age'].fillna(value = df['Age'].mean() , inplace = True)
	# Create a first class column
	df['FirstClass'] = df['Pclass'].map(lambda x: 1 if x == 1 else 0)
	# Create a second class column
	df['SecondClass'] = df['Pclass'].map(lambda x: 1 if x == 2 else 0)
	# Create a second class column
	df['ThirdClass'] = df['Pclass'].map(lambda x: 1 if x == 3 else 0)
	# Select the desired features
	df= df[['Sex' , 'Age' , 'FirstClass', 'SecondClass' ,'ThirdClass' 'Survived']]
	return df
  • 对于sex列,如果乘客是男性,我们设置值为 0,如果乘客是女性,我们设置值为 1。
  • 我们使用平均值来填充年龄列中缺失的数据。
  • 我们对Pclass.使用一次热编码。
  • 由于我们不专注于构建模型,我们将只从数据框架中选择 6 个特征。

列车测试分离

train_df = manipulate_df(train_df)
features= train_df[['Sex' , 'Age' , 'FirstClass', 'SecondClass','ThirdClass']]
survival = train_df['Survived']
X_train , X_test , y_train , y_test = train_test_split(features , survival ,test_size = 0.3)

我们将使用 70–30 的比例来分割数据集。

缩放要素数据

scaler = StandardScaler()
train_features = scaler.fit_transform(X_train)
test_features = scaler.transform(X_test)

我们需要对数据进行缩放,因此均值= 0,标准差= 1。

建立模型

# Create and train the model
model = LogisticRegression()
model.fit(train_features , y_train)
train_score = model.score(train_features,y_train)
test_score = model.score(test_features,y_test)
y_predict = model.predict(test_features)

在训练我们的模型之后,我们存储我们的模型的准确度分数。

我们已经成功建造了我们的模型。现在我们将继续简化它。

细流

要运行 streamlit 应用程序,请键入以下命令。

streamlit run app.py

您应该会看到一个空白屏幕,因为我们现在没有显示任何组件。在右上角,选择“总是重新运行”。这告诉 Streamlit 在我们每次修改代码时重新加载。

标题和输入数据帧

Webapp 截图

我们将在 web 应用程序的这一部分使用以下功能:

  • title( str ) :这个方法就像一个< h1 >标签。它接受一个字符串作为参数,并将文本显示为标题。
  • subheader( str) :类似于 title 方法,但是显示的文字字体比标题显示的字体要小。
  • table(dataframe):table()方法将一个 data frame 作为参数,并显示出来。您也可以使用。dataframe()方法,而。table()方法显示了一个更好看的表格。

代码如下:

st.title("Would you have survived the Titanic Disaster?")
st.subheader("This model will predict if a passenger would survive the Titanic Disaster or not")
st.table(train_df.head(5))

st.table()的替代方法是 st.dataframe()。它们都支持 dataframe 并可以显示它,但是我更喜欢 st.table(),因为它看起来更好。

模型性能

web 应用的屏幕截图

首先,我们需要形成混淆矩阵并计算值。

confusion = confusion_matrix(y_test, y_predict)
FN = confusion[1][0]
TN = confusion[0][0]
TP = confusion[1][1]
FP = confusion[0][1]

我们可以使用 subheader()方法来显示训练和测试分数。

st.subheader("Train Set Score: {}".format ( round(train_score,3)))
st.subheader("Test Set Score: {}".format(round(test_score,3)))

现在,我们将使用上述数据创建一个条形图。

plt.bar(['False Negative' , 'True Negative' , 'True Positive' , 'False Positive'],[FN,TN,TP,FP])

为了显示图表,我们将使用 Streamlit 的 pyplot()方法。

st.pyplot()

您可以将 st.pyplot()视为 plt.show()的等价物。

接受用户的输入

web 应用的屏幕截图

接下来,我们允许用户输入数据并显示预测。

我们将使用以下方法:

  • text_input(str) :该方法将一个字符串作为参数,并以输入参数作为标签创建一个文本输入字段。
  • st.selectbox(str,options = ) :这个方法创建一个下拉菜单。它接受两个参数,用作标签的字符串和选项列表。选项需要以字符串值列表的形式传递。
  • st.slider(str,start,end,step) :用给定的参数创建一个滑块。

代码显示如下:

name = st.text_input("Name of Passenger ")
sex = st.selectbox("Sex",options=['Male' , 'Female'])
age = st.slider("Age", 1, 100,1)
p_class = st.selectbox("Passenger Class",options=['First Class' , 'Second Class' , 'Third Class'])

每次用户输入时,脚本都会重新运行,相应的变量会存储输入值。

在我们使用这些值进行预测之前,我们需要对它们进行缩放和修改。

sex = 0 if sex == 'Male' else 1
f_class , s_class , t_class = 0,0,0
if p_class == 'First Class':
	f_class = 1
elif p_class == 'Second Class':
	s_class = 1
else:
	t_class = 1
input_data = scaler.transform([[sex , age, f_class , s_class, t_class]])
prediction = model.predict(input_data)
predict_probability = model.predict_proba(input_data)
  • 首先,我们将 sex 的值设置为 0 或 1。
  • 然后,我们对乘客类使用一键编码。
  • 最后,我们缩放输入并计算预测和概率。

展示我们的预测

if prediction[0] == 1:
	st.subheader('Passenger {} would have survived with a probability of {}%'.format(name , round(predict_probability[0][1]*100 , 3)))
else:
	st.subheader('Passenger {} would not have survived with a probability of {}%'.format(name, round(predict_probability[0][0]*100 , 3)))

基于预测,我们显示一条文本消息。

我们现在已经为我们的模型构建了一个用户界面

结论

只需几行额外的代码,我们就可以将一个简单而枯燥的脚本转换成一个具有整洁 UI 的 web 应用程序。许多人可能已经建立了一个模型来预测泰坦尼克号灾难中乘客的生存,但是为它建立一个 web 应用程序将使你脱颖而出。

我最近用 WordPress 创建了一个博客,如果你能看看的话,我会很高兴的😃

在 LinkedIn 上与我联系

https://www.linkedin.com/in/rahulbanerjee2699/

最初发表于 版块 。木卫一 2021 年 1 月 6 日

不追独角兽如何打造独角兽 AI 团队

原文:https://towardsdatascience.com/how-to-build-a-unicorn-ai-team-without-chasing-unicorns-e28c054af86e?source=collection_archive---------27-----------------------

一个优秀人工智能团队的 7 个技能角色

GIF by giphy

文章原载于 VentureBeat

你如何开始组建一个人工智能团队?好吧,雇用能够理解业务问题、能够将其转化为“正确的”人工智能构建模块、能够交付实施和生产部署的独角兽。听起来很容易!只不过这种独角兽的出现极为罕见。即使你找到了独角兽,你也很可能买不起它!

在我过去二十年领导数据+人工智能产品和平台的经验中,一个更有效的策略是专注于招募可靠的执行者,他们在团队中累计支持七个特定技能角色。

独角兽人工智能团队的 7 个技能角色

独角兽人工智能团队的七个技能角色(图片由作者提供)

数据集解释器角色

人工智能项目的生命线是数据。找到正确的数据集、准备数据并持续确保高质量是一项关键技能。有很多关于数据集的部落知识,所以你需要有人专门跟踪数据属性的含义和不同数据集的来源。与数据相关的一个挑战是处理组织内对业务指标的多种定义。在我的一个项目中,我们正在处理销售、财务和市场营销中“每月新客户”的八种定义。对于这种技能角色,一个很好的起点是一个传统的数据仓库工程师,他具有很强的数据建模技能,并且天生好奇如何将数据属性的含义与应用程序和业务操作相关联。

管道建造者角色

从多个来源获取数据到 AI 模型需要数据管道。在管道中,数据被清理、准备、转换并转化为 ML 特征。这些数据管道(传统数据仓库中称为提取-转换-加载或 ETL)会变得非常复杂。组织通常拥有管道丛林,其中有数千条使用异构大数据技术构建的管道,如 Spark 、 Hive 和 Presto 。管道建造者角色侧重于以适当的健壮性和性能大规模地建造和运行管道。寻找这种角色的最佳地点是拥有多年批处理和实时事件管道开发经验的数据工程师。

AI 全栈角色

AI 从设计、训练、部署、再训练,本质上都是迭代的。构建 ML 模型需要对代码、特性、数据集和模型配置的不同排列进行数百次实验。这个角色是人工智能领域知识和强大的系统构建技能的结合。他们专注于现有的 AI 平台,如 Tensorflow 、 Pytorch ,或基于云的解决方案,如 AWS 、 Google 和 Azure 。随着这些人工智能平台的民主化和广泛的在线课程,这种角色不再稀缺。根据我的经验,强大的软件工程背景加上他们对掌握人工智能的好奇心是一个极其有效的组合。在为这种角色招聘时,很容易遇到喜欢单飞而不是团队合作的天才——保持警惕,尽早淘汰他们。

人工智能算法角色

大多数人工智能项目很少需要从头开始或实现新的算法。这个角色的作用是在问题的背景下,在人工智能算法和技术的搜索空间上指导团队。它们有助于减少路线修正的死角,并有助于平衡解决方案的准确性和复杂性。鉴于专注于人工智能算法创新的地方的高需求,这种角色不容易获得。如果你负担不起找一个全职的人来掌握这项技能,可以考虑找一个专家做顾问或者创业顾问。另一个选择是投资培训全栈团队,给他们时间学习研究进展和算法内部。

数据+人工智能运营角色

AI 解决方案在生产中部署后,需要持续监控以确保其正常工作。生产中可能会出现很多问题:数据管道故障、质量差的数据、供应不足的模型推断端点、模型预测正确性的漂移、业务度量定义中不协调的变化,等等。该角色侧重于构建正确的监控和自动化,以确保无缝运营。与软件产品的传统开发运维相比,考虑到移动部分的数量,数据+人工智能运维要复杂得多。谷歌的研究人员将这种复杂性正确地总结为 CACE 原则:改变任何事情都会改变一切。寻找这种角色的一个很好的起点是有经验的数据运营工程师,他们渴望学习数据+人工智能领域。

假设规划者角色

人工智能项目充满惊喜!从原始数据到可用的人工智能的旅程不是一条直线。您需要灵活的项目规划——根据对数据集、功能、模型准确性、客户体验的假设的证明或否定进行调整。找到这种技能角色的一个好地方是传统的数据分析师,他们有在紧迫的期限内处理多个并发项目的经验。鉴于他们跟踪和平行假设的本能,他们可以成为优秀的项目经理。

影响所有者角色

影响所有者非常熟悉如何部署人工智能产品来实现价值的细节。例如,当使用人工智能解决与提高客户保持率相关的问题时,这个角色将完全理解与客户获取、保持和流失相关的旅程图。他们将负责定义支持团队专家如何实施人工智能解决方案中的客户流失预测,以减少流失。找到这种角色的最佳地方是在现有的业务团队中——理想情况下,是一个具有强烈产品直觉和实用主义的工程师。没有这个角色,团队最终会构建技术上可行的东西,而不是在端到端工作流中实际需要什么来产生价值。

总结一下,这七个技能人物角色是每个 AI 团队必备的。这些人物角色的重要性根据数据的成熟度、人工智能问题的类型以及更广泛的数据和应用程序团队可用的技能而有所不同。例如,与拥有少量大表的组织相比,拥有大量小表的组织中的数据解释者角色更加重要。在为 AI 团队中的每个技能角色确定正确的资历和基数时,应该考虑这些因素。希望,你现在可以开始建立你的人工智能团队,而不是等待独角兽出现!

如何使用 Python 和 AssemblyAI 构建一个转录音频的 Web 应用程序

原文:https://towardsdatascience.com/how-to-build-a-web-app-to-transcribe-audio-using-python-and-assemblyai-18f197253fd8?source=collection_archive---------11-----------------------

我们将使用 Streamlit 建立一个 web 应用程序,让用户上传他们的音频。AssemblyAI 的 API 将用于转录这个音频。我们也将建立一些很酷的动画

Web 应用程序的屏幕截图

你可以在这里找到部署的应用

转录是将音频转换为文本的过程。虽然你可以实现一个机器学习模型来从音频中获取文本,但这很麻烦。

  • 从音频信号中提取特征需要丰富的音频信号处理知识。
  • 必须从各种来源挖掘/搜集大量数据。
  • 需要具备 PyTorch 或 TensorFlow 等机器学习库的知识。

幸运的是,AssemblyAI 有一个免费的版本,让我们通过几个请求就可以转录音频。

在本文中,我们将构建一个 web 应用程序,它可以使用 AssemblyAI 和 Streamlit 转录音频,Streamlit 是一个 Python 库,用于构建机器学习模型的 ui。

你可以在这里找到带有完整源代码的回购协议。

要求

  • 一个 AssemblyAI 账户(免费注册这里
  • 一个 AssemblyAI API 密钥(你可以在这里找到它
  • Python 3.5+的基础知识(注意:本教程我将使用 Python 3.9)
  • 虽然不是必需的,但是熟悉请求库会有所帮助

我们将使用的库

AssemblyAI

AssemblyAI 用于将音频转换为文本。它提供了一个 REST API,可以在任何调用 REST API 的语言中使用,比如 JavaScript、PHP、Python 等。我们将使用 Python 向 API 发出请求。

细流

Streamlit 是一个开源的应用框架,用于构建机器学习模型的 UI,无需了解 HTML、CSS 或 JavaScript。它有一个广泛的预建组件库,可以用来在几分钟内构建一个简单的 UI。

要求

我们将使用请求库向 AssemblyAI 的 REST API 发出请求。

Python-dotenv

我们将使用 Python-dotenv 库来读取变量。环境文件。

设置项目目录

使用命令行创建新的文件夹/目录

mkdir ASSEMBLYAI

为了保持秘密凭证的秘密性,将凭证存储在. env 文件中是一个很好的做法。然后,我们可以使用 Python-dotenv 库从。环境文件。如果愿意,我们也可以将它们存储在环境变量中。

在您创建的新目录 ASSEMBLYAI 中,创建两个新的 Python 文件和一个. env 文件

如果使用 Windows:

New-Item main.py, transcribe.py, .env

如果使用 macOS 或 Linux:

touch touch main.py && transcribe.py && touch .env

文件 main.py 将包含与 Streamlit UI 相关的所有代码,而文件 transcribe.py 将包含帮助器函数和与 AssemblyAI 的 API 交互的代码。

你可以从这里下载一个样本 MP3 文件。将文件命名为“testData ”,并将其保存在 ASSEMBLYAI 目录中。

设置项目环境

确保你在 ASSEMBLYAI 目录下,如果你不只是使用 cd 命令来改变目录。

cd ASSEMBLYAI

如果这是你第一次使用虚拟环境,你必须安装 virtualenv

如果使用 Windows:

python -m pip install — user virtualenv

如果使用 macOS 或 Linux:

python3 -m pip install — user virtualenv

首先,我们需要通过在命令行上输入以下代码来创建一个虚拟环境:

如果使用 Windows:

python -m venv venv

如果使用 macOS 或 Linux:

Python3 -m venv venv

然后,我们需要在命令行中使用以下命令来激活本地虚拟环境:

如果使用 Windows:

venv/Scripts/activate

如果使用 macOS 或 Linux:

source venv/bin/activate

有关如何设置虚拟环境的更多详细信息,请参考本网站。

要分别安装 Requests、Steamlit 和 Python-dotenv 库,我们可以在命令行上输入这一行:

pip install streamlit, requests, python-dotenv

这将安装所需的最新库。

作者图片

这是你的文件结构应该看起来的样子。

将 API 密钥添加到。环境文件

  • 打开。您在“设置项目环境”一节中创建的 env 文件。
  • 添加以下内容:
API_TOKEN = “Your API Key”
  • 将字符串“Your API Key”替换为 Assembly AI 给你的 API Key。

如何克隆回购并运行它

  • 去 GitHub repo 下载。
  • 启动命令行,将目录更改为下载的文件夹。
  • 按照上一节设置虚拟环境。
  • 激活虚拟环境。
  • 在下载的文件夹中创建一个. env 文件,并添加 API 密钥。(参考上一节。)
  • 要安装所需的库,您可以手动键入名称并安装它们,或者使用提供的 requirements.txt 文件。

如果使用 Windows:

pip install streamlit, requests, python-dotenv

如果使用 macOS 或 Linux:

pip install streamlit requests python-dotenv

或者

pip install -r requirements.txt
  • 一旦成功安装了所有要求,请键入以下命令
streamlit run main.py

这应该会运行 webapp。您可以尝试上传文件。

转录 mp3 文件

在构建 UI 之前,我们需要几个助手函数,我们可以用它们将文件上传到 AssemblyAI 的服务器,供模型处理并返回转录的文本。

助手函数的代码应该写在transcripte . py文件中

导入所需的模块

这段代码应该出现在转录. py 文件的开头

import os
from dotenv import load_dotenv
import requests

助手功能 1:将本地音频文件上传到 AssemblyAI

我们需要编写的第一个函数是上传存储在本地机器上的音频文件的方法。这个函数应该存在于转录. py 文件中

AssemblyAI 模型期望文件可以通过 URL 访问。因此,我们需要将音频文件上传到 blob 存储,以便通过 URL 访问。幸运的是,AssemblyAI 提供了一种快速简单的方法来实现这一点。

我们需要向以下 AssemblyAI API 端点发出 POST 请求:

[https://api.assemblyai.com/v2/upload](https://api.assemblyai.com/v2/upload)

该响应将包含一个指向该文件的临时 URL,我们可以将该 URL 传递回 AssemblyAI ' transcript` API 端点。该 URL 是仅可由 AssemblyAI 服务器访问的私有 URL。

所有上传的内容转录后会立即删除,永远不会保存。

我们将使用之前安装的 Python 请求库来发出 POST 请求

def get_url(token,data):
 ‘’’
 Parameter:
 token: The API key
 data : The File Object to upload
 Return Value:
 url : Url to uploaded file
 ‘’’
 headers = {‘authorization’: token}
 response = requests.post(‘https://api.assemblyai.com/v2/upload',
 headers=headers,
 data=data)
 url = response.json()[“upload_url”]
 print(“Uploaded File and got temporary URL to file”)
 return url
  • 该函数接受两个参数:API 令牌和要上传的文件对象
  • 我们向上述 AssemblyAI Upload API 端点发出 POST 请求,并将 API 令牌和文件对象作为请求体的一部分。
  • 响应对象包含上传文件的 URL。该 URL 由函数返回。

助手功能 2:上传文件进行转录

现在我们有了一个函数来获取音频文件的 URL,我们将使用这个 URL 并向端点发出请求,端点将实际转录文件。这个函数也应该存在于 transcribe.py 文件中

最初,当我们请求转录时,音频文件具有“排队”状态。我们将在最后一个帮助函数中更多地讨论文件是如何从“排队”到“完成”的。现在,我们只需要向转录端点以及文件的 URL 发出请求。我们需要向以下 AssemblyAI API 端点发出请求:

[https://api.assemblyai.com/v2/transcript](https://api.assemblyai.com/v2/transcript)

这个函数与前面的函数非常相似。

def get_transcribe_id(token,url):
 ‘’’
 Parameter:
 token: The API key
 url : Url to uploaded file
 Return Value:
 id : The transcribe id of the file
 ‘’’
 endpoint = “https://api.assemblyai.com/v2/transcript"
 json = {
 “audio_url”: url
 }
 headers = {
 “authorization”: token,
 “content-type”: “application/json”
 }
 response = requests.post(endpoint, json=json, headers=headers)
 id = response.json()[‘id’]
 print(“Made request and file is currently queued”)
 return id
  • 该函数接受两个参数:API 令牌和来自前面函数的音频文件 URL。
  • 我们向 AssemblyAI“抄本”API 端点发出 POST 请求..如果音频文件当前未在处理中,则新文件会立即被处理。如果有正在进行的转录,则新的音频文件将排队,直到前一个作业完成。

如果您希望能够同时运行多个作业,您将需要升级到高级计划

  • 响应对象将包含转录的 ID。这个 ID 和一个单独的端点将用于获取转录的状态。
  • 该函数将返回这个 ID

助手功能 3:下载音频转录

一旦我们有了音频文件的转录 ID,我们就可以向以下 AssemblyAI API 端点发出 GET 请求,以检查转录的状态:

[https://api.assemblyai.com/v2/transcript/{transcribe_id}](https://api.assemblyai.com/v2/transcript/{transcribe_id})

只要没有遇到错误,转录的状态就从“排队”变为“处理中”再变为“完成”。

我们将需要轮询这个端点,直到我们得到一个状态为“completed”的响应对象。

我们可以利用一个 while 循环 不断向端点发出请求。在循环的每次迭代中,我们将检查转录的状态。循环将继续运行,直到状态为“完成”。发出请求并等待状态完成的过程称为轮询。我们将在“构建 Streamlit UI”一节中实现这个轮询特性。

下面的函数将简单地获取处方的当前状态。这个函数应该存在于转录. py 文件中

def get_text(token,transcribe_id):
 ‘’’
 Parameter:
 token: The API key
 transcribe_id: The ID of the file which is being
 Return Value:
 result : The response object
 ‘’’ 
endpoint= f”https://api.assemblyai.com/v2/transcript/{transcribe_id}"
headers = {
 “authorization”: token
 }
 result = requests.get(endpoint, headers=headers).json()
 return result

助手功能 4:从 UI 请求转录

我们的第三个函数将连续调用前面的两个函数。

该功能也将连接到我们的 Streamlit UI 中的“上传”按钮。该函数只有一个参数:file 对象。该函数将执行以下操作

  • 它将从我们的。环境文件。
  • 它将使用令牌来调用先前定义的函数
  • 它将返回转录 ID

下面是该函数的代码片段。这个函数应该存在于transcripte . py文件中:

def upload_file(fileObj):
 ‘’’
 Parameter:
 fileObj: The File Object to transcribe
 Return Value:
 token : The API key
 transcribe_id: The ID of the file which is being transcribed
 ‘’’
 load_dotenv()
 token = os.getenv(“API_TOKEN”)
 file_url = get_url(token,fileObj)
 transcribe_id = get_transcribe_id(token,file_url)
 return token,transcribe_id
  • 我们将使用 load_dotenv() 函数来加载我们的。环境文件。然后我们将使用操作系统库中的 get() 函数,从。环境文件。
  • 调用 get_url() 函数,将文件对象和令牌作为参数。
  • get_url() 函数返回的令牌和 file_url 调用get _ transcripte _ id()函数。
  • 返回令牌和转录 ID。

构建 Streamlit UI

现在我们已经有了所有需要的助手函数,我们可以开始在 Streamlit UI 上工作了。

然而,在进入 Streamlit UI 的实际代码之前,让我们看一下我们将使用的 Streamlit 组件。

  • header(string)、subheader(string)、text(string) —这些组件在我们的 UI 上显示各种大小的文本。 header() 可以认为是< h1 >标签, subheader() 是< h2 >而 text() 是< p >
  • file_uploader(label) —创建一个上传文件的按钮。参数标签是显示在按钮上方的字符串。它返回一个文件对象。我们将使用它来接受来自用户的文件
  • 进度(整数) —创建一个进度条。整数必须介于 0 和 100 之间。它表示指定任务完成的百分比。如果我们创建一个每次迭代睡眠时间为 0.1 s b/w 的 for 循环,我们就可以创建一个很酷的进度条动画。
  • spinner(label) —只要我们在标签的代码块中,标签就会显示。
  • 气球() —这是展示气球的,是啊,真酷🎈

构建用户界面的组件

下面的代码应该写在 main.py 文件中。main.py 文件将是我们的 web 应用程序的入口点。

首先,我们需要导入所有需要的模块和库

import streamlit as st
from transcribe import *
import time

转录的名字这个文件带有我们的帮助函数。

为了确保您当前已经导入了库,您可以尝试在命令行中运行以下命令。在运行该命令之前,确保您的虚拟环境已激活,并且您当前位于根文件夹(ASSEMBLYAI)中:

streamlit run main.py

您应该会看到一个空白的 web 应用程序。要重新运行应用程序,您可以单击汉堡菜单,然后单击重新运行,或者您可以打开 web 应用程序,然后按“Ctrl + R”或“Cmnd + R”

让我们首先创建一个标题和上传按钮。

main.py 文件中输入以下代码:

st.header(“Transcribe Audio”)
fileObject = st.file_uploader(label = “Please upload your file” )

重新运行应用程序后,您应该会看到以下内容

作者图片

最初,变量是“None”,一旦文件被上传,变量的值就是文件对象。

if fileObject:
 token, t_id = upload_file(fileObject)
 result = {}
 #polling
 sleep_duration = 1
 percent_complete = 0
 progress_bar = st.progress(percent_complete)
 st.text(“Currently in queue”)
 while result.get(“status”) != “processing”:
 percent_complete += sleep_duration
 time.sleep(sleep_duration)
 progress_bar.progress(percent_complete/10)
 result = get_text(token,t_id)
sleep_duration = 0.01
for percent in range(percent_complete,101):
 time.sleep(sleep_duration)
 progress_bar.progress(percent)
  • 本质上,如果变量 fileObject 不为“None”,我们调用 upload_file 函数。
  • 我们使用 while 循环来轮询端点。
  • 创建一个进度条,在 while 循环的每一次迭代中,程序会休眠一秒钟,并将进度条的百分比递增 1
  • 一旦状态变为“处理中”,睡眠时间将减少到 0.01 秒。这导致了一个非常酷的动画,开始时,进度条进展缓慢,一旦文件被处理,它的进展真的很快

作者 GIF

  • 进度条显示为 100%时,我们再次轮询端点。这一次检查状态是否为“已完成”。我们使用 spinner() 函数在投票时在屏幕上显示文本:
st.balloons()
st.header(“Transcribed Text”)
st.subheader(result[‘text’])
  • 一旦状态为“完成”,我们退出 while,并使用 balloons() 函数在屏幕上循环显示气球。
  • 最后,我们在屏幕上显示转录的文本。

作者图片

结论

恭喜你!👏您已经成功构建了一个可以转录音频的 web 应用程序。您可以在 web 应用程序的基础上构建一些附加功能

  • AssemblyAI 允许用户指定声学模型和/或语言模型。您可以使用 Streamli 的选择框构建一个类似的下拉功能。
  • 添加一个功能,让用户记录他们的声音,并转录它。这可能有点复杂,因为 Streamlit 没有任何内置组件来录制语音。但是,您可以使用 HTML 和 JavaScript 来构建这样一个特性。查看这个答案供参考。

在 LinkedIn 、 Twitter 上与我联系

我最近开始了一个修改版的#100daysofcode 挑战。我的目标是写与 Python、数据科学或编程相关的内容。关注我在媒体上的进度

如何为 BERT 构建一个词块标记器

原文:https://towardsdatascience.com/how-to-build-a-wordpiece-tokenizer-for-bert-f505d97dddbb?source=collection_archive---------1-----------------------

实践教程

从头开始构建 BertTokenizer 的简单指南

作者图片

对于许多更具体的用例来说,从头构建一个转换器模型通常是唯一的选择。尽管 BERT 和其他 transformer 模型已经针对许多语言和领域进行了预训练,但它们并没有涵盖所有内容。

通常,这些不太常见的用例会从有人来构建特定的 transformer 模型中获益最多。它可能是一种不常用的语言或者一个不太懂技术的领域。

BERT 是一系列基于语言的机器学习中最受欢迎的转换器——从情感分析到问答。BERT 已经实现了跨越许多边界和行业的多样化创新。

对于许多人来说,设计新的 BERT 模型的第一步是记号赋予器。在这篇文章中,我们将看看 BERT 使用的 WordPiece tokenizer 看看我们如何从头开始构建自己的 WordPiece tokenizer。

文字片

BERT 使用所谓的单词块记号赋予器。它的工作原理是将单词拆分成完整的形式(例如,一个单词成为一个标记),或者拆分成单词片段——其中一个单词可以拆分成多个标记。

一个有用的例子是我们有多种形式的单词。例如:

通过将单词拆分成单词块,我们已经识别出单词"surfboard""snowboard"通过单词块"##board"共享含义,我们甚至没有对我们的令牌进行编码,也没有通过 BERT 以任何方式对它们进行处理。

使用单词片段允许 BERT 轻松识别相关单词,因为它们通常共享一些相同的输入标记,然后这些标记被输入到 BERT 的第一层。

作为旁注,还有许多其他的 transformer 记号赋予器——比如 SentencePiece 或者流行的 字节级字节对编码(BPE)记号赋予器 。它们各有利弊,但是最初的 BERT 使用的是单词块标记器。

构建标记器

当构建一个新的标记器时,我们需要大量的非结构化语言数据。我的首选是 OSCAR 语料库——一个巨大的多语言数据集,涵盖了 166 种不同的语言。

然而,那里有许多数据集。HuggingFace 的datasets库也提供了对其中大部分内容的便捷访问。我们可以看到使用 Python 有多少:

一个很酷的 1306 数据集。其中许多也非常庞大——OSCAR 本身被分成 166 种语言,OSCAR 的许多“部分”包含万亿字节的数据。

我们可以用 HF 的datasets下载奥斯卡意大利语语料库。但是,我们应该小心,因为完整的数据集包含 11.3 亿个样本。总共约 69GB 的数据。HF 允许我们使用split参数指定我们只想要完整数据集的部分

在我们的split参数中,我们已经指定我们想要来自train数据集的第一个2000000样本(大多数数据集被组织成trainvalidationtest集合)。尽管这仍然会下载完整的train集——它将被缓存在本地以备将来使用。

我们可以通过将streaming=True参数添加到load_dataset来避免下载和缓存整个数据集——在这种情况下split必须设置为"train"(没有[:2000000])。

数据格式编排

下载完数据后,我们必须将其重新格式化为简单的明文文件,每个样本之间用一个换行符隔开。将每个样本存储在一个文件中会创建一个巨大的文本文件。所以,我们把它们分成许多份。

培养

一旦我们保存了所有简单的、换行符分隔的明文文件——我们继续训练我们的记号赋予器!

我们首先使用pathlib创建一个包含所有明文文件的列表。

然后,我们初始化并训练分词器。

这里有几个重要的参数需要注意,在初始化期间,我们有:

  • clean_text —通过删除控制字符并用空格替换所有空白来清除文本。
  • handle_chinese_chars —标记器是否包括汉字周围的空格(如果在数据集中找到)。
  • stripe_accents —我们是否删除重音,何时True这会使é → e、ⅳ→o 等。
  • lowercase —如果True标记器将大写和小写字符视为相等;A == a,B == b,等等。

在培训期间,我们使用:

  • vocab_size —我们的记号赋予器中记号的数量。在稍后的文本标记化过程中,未知单词将被分配一个不理想的[UNK]标记。我们应该尽可能减少这种情况。
  • min_frequency —一对令牌被合并的最小频率。
  • special_tokens—BERT 使用的特殊令牌列表。
  • limit_alphabet —不同字符的最大数量。
  • workpieces_prefix —添加到单词的片段的前缀(就像我们前面例子中的**##**board)。

在我们完成训练后,剩下的就是保存我们闪亮的新标记器。我们使用save_model方法来实现这一点——指定一个目录来保存我们的标记器和标记器名称:

就这样,我们构建并保存了我们的 BERT tokenizer。在我们的记号赋予器目录中应该找到一个文件— vocab.txt

vocab.txt 文件的屏幕截图——我们新的令牌化器文本到令牌 ID 的映射。

在标记化过程中,vocab.txt用于将文本映射到标记,然后根据vocab.txt中标记的行号将标记映射到标记 id——这些 id 然后被输入到 BERT 中!

vocab.txt 的一小部分,显示令牌及其令牌 id(如行号)。

符号化

现在我们有了记号赋予器;我们可以继续使用from_pretrained加载它,就像我们使用任何其他标记器一样,我们必须指定保存标记器的本地目录。

我们也像往常一样标记:

这里我们返回大多数 BERT 任务需要的三个张量,input_idstoken_type_idsattention_mask。我们可以看到由2代表的初始[CLS]令牌和由3代表的最终[SEP]令牌。

由于我们的vocab.txt文件包含我们的令牌和令牌 id 的映射(例如,行号)——我们可以通过将我们的input_ids令牌 id 与vocab.txt中的行对齐来访问令牌:

让我们试试另一个——如果你在意大利,这是一个不错的选择:

最后,让我们对将要拆分成多个单词片段的内容进行标记:

这就是我们构建和应用意大利 Bert tokenizer 所需的一切!

这就是本文的全部内容,涵盖了为 BERT 定制的单词块标记器的构建过程。

我希望你喜欢它!如果你有任何问题,请通过 Twitter 或在下面的评论中告诉我。如果你想要更多这样的内容,我也会在 YouTube 上发布。

感谢阅读!

🤖《变形金刚》NLP 课程 70%的折扣

参考

HuggingFace Tokenizers 文档

如何用 Python 构建 YouTube 转录 App

原文:https://towardsdatascience.com/how-to-build-a-youtube-transcription-app-in-python-f15bab6eb250?source=collection_archive---------9-----------------------

由eleven creative从 envato elements 使用图像创建(经许可)。

使用 AssemblyAI 和 Streamlit 的分步教程

背景

或许,在你的学习之旅中,你想看一个小时的 YouTube 视频,或者你有一个 YouTube 视频播放列表要看,但你时间不够?

有两个可能的选择:

  1. 找时间看视频
  2. 转录视频(你可以浏览视频以获取关键观点)

如果您选择第二个选项,您将在本文中了解如何利用自动语音识别将 YouTube 视频中的音频转录为书面形式。简而言之,我们将用 Python 实现一个语音到文本的 Streamlit 应用程序,使用 AssemblyAI API 来执行 YouTube 视频的转录。

在我们继续之前,值得注意的是,我还为本文制作了一个补充视频,除了构建 Streamlit 应用程序,我们还构建了一个具有相同功能的命令行工具(一个可以从命令行运行的简单 Python 脚本)。

如何使用 AssemblyAI 和 Streamlit 在 Python 中构建自己的语音到文本转换应用

构建转录器应用程序的概念框架

也许,提供一个关于我们将要构建的转录器应用程序的高级概述会很好。

构建转录应用程序的概念框架。由作者绘制。

现在让我们开始构建应用程序吧!

建立工作环境

首先要做的是安装conda,我们将使用它来管理我们的工作环境。

现在,让我们用 Python 版创建一个新的 conda 环境。在这里,我们将环境命名为transcriber

conda create -n transcriber python=3.9

当提示安装 Python 库依赖项时,只需输入Y,字面意思是“是”。

现在已经创建了环境,当您打开终端时,您可以键入以下内容来激活 conda 环境:

conda activate transcriber

完成后,您可以通过键入以下命令退出 conda 环境:

conda deactivate

下载 GitHub repo

我们现在将通过以下命令从 GitHub repo transcriber-app下载运行 transcriber 应用程序所需的所有文件:

git clone [https://github.com/dataprofessor/transcriber-app](https://github.com/dataprofessor/transcriber-app)

这将显示以下文件夹内容:

transcriber-app/
├─ .streamlit/
│  ├─ secrets.toml
├─ api.txt
├─ app.py
├─ requirements.txt
├─ transcriber.py
├─ README.md

接下来,安装必备库,本质上是streamlitpytube库。

您可以通过以下方式实现这一点(仅选择并执行以下一项):

pip install requirements.txt

或者通过以下方式手动安装库:

pip install -U streamlit
pip install pytube

-U选项有助于将streamlit库更新到最新版本,以确保您可以访问最新版本。

从 AssemblyAI 获取 API 密钥

在运行 Streamlit transcriber 应用程序之前,我们需要从 AssemblyAI 获取 API 密钥。

这超级简单,只要做到以下几点:

  1. 转到装配 AI
  2. 注册并登录
  3. 复制在右侧找到的 API 密钥。

演示如何获取 AssemblyAI API 的截屏。

运行命令行工具

需要注意的是,api.txttranscriber.py是作为命令行工具运行转录器 app,可以通过以下命令执行:

python transcriber.py -i "[https://youtu.be/mkVjrB8g6mM](https://youtu.be/mkVjrB8g6mM)"

确保打开api.txt文件,并用 AssemblyAI 中的 API 键替换填充文本。

(注意:请随意用您选择的 YouTube 视频替换该 URL)

在命令行中运行转录器的截屏。

运行 Streamlit 应用

如果您在本地运行 Streamlit 应用程序,请确保打开.streamlit/secrets.toml文件,并用 AssemblyAI 中的 API 密钥替换填充文本。

要启动应用程序,请在终端中输入以下内容:

streamlit run app.py

运行 Transcriber Streamlit 应用程序的截屏。

将 Streamlit 应用部署到云

如果您正在部署到云,最简单的方法是使用 Streamlit Cloud 进行部署,这需要一个到 GitHub repo 的链接。重要的是不要上传.streamlit/secrets.toml到你的 GitHub repo,而是你可以从 Streamlit 云管理界面输入 API 密钥。

为此,您可以进入应用仪表板,在应用的下拉菜单下,点击编辑机密。从secrets.toml文件中复制内容并粘贴到文本框中。

代码的解释

第 1–7 行

导入必备库。

第 9 行

打印出应用程序的标题。

第 10 行

使用st.progress()函数实例化进度条,并将初始值设置为0

第 12–111 行

定义自定义的实用函数,执行所有的任务来转录 YouTube 视频。这由 8 个任务组成,如各种注释行所述,如下:
1)从 YouTube 视频检索音频文件
2。将 YouTube 音频文件上传到 AssemblyAI
3)转录上传的音频文件
4)提取转录 ID
5)检索转录结果
6)检查转录是否完成
7)打印转录文本
8)将转录文本保存到文件

在本文的补充视频中提供了深入的解释: 如何使用 AssemblyAI 和 Streamlit 在 Python 中构建自己的语音到文本转录 App。

第 113–141 行

实际应用从这里开始。简而言之,该应用程序接受 YouTube 视频的用户输入 URL,并将该信息转发给第 12-111 行中提到的自定义实用程序函数,以执行上述 8 项任务。

结论

恭喜你!现在,您已经构建了自己的转录器应用程序,用于将 YouTube 视频转换为转录文本。只需稍加调整,你就可以定制应用程序来转录任何视频或音频文件。

接下来读这些

  • 如何掌握数据科学所需的 Python
    下面是数据科学所需的必备 Python
  • 如何掌握数据科学的熊猫
    下面是数据科学需要的必备熊猫
  • 如何用 Python 构建 AutoML App
    使用 Streamlit 库的分步教程
  • 学习数据科学的策略
    闯入数据科学的实用建议
  • 如何免费搭建一个简单的作品集网站
    不到 10 分钟从零开始的分步教程

✉️ 订阅我的邮件列表,获取我在数据科学方面的最佳更新(偶尔还有免费赠品)!

关于我

目前,我是 Streamlit 的全职开发人员。此前,我是泰国一所研究型大学的生物信息学副教授,数据挖掘和生物医学信息学负责人。在我下班后的时间里,我是一名 YouTuber(又名数据教授)制作关于数据科学的在线视频。在我制作的所有教程视频中,我也在 GitHub 上分享 Jupyter 笔记本(数据教授 GitHub 页面)。

https://www.youtube.com/dataprofessor

在社交网络上与我联系

✅YouTube:http://youtube.com/dataprofessor/
♇网站:http://dataprofessor.org/(在建)
♇LinkedIn:https://www.linkedin.com/company/dataprofessor/
♇Twitter:https://twitter.com/thedataprof
♇Facebook:http://facebook.com/dataprofessor/
♇github:https://github.com/dataprofessor/
♇insta gram:

如何使用 GPT-3 在 10 分钟内构建令人惊叹的人工智能用例?

原文:https://towardsdatascience.com/how-to-build-amazing-ai-use-cases-under-10-mins-using-gpt-3-ebc51b2b2b97?source=collection_archive---------9-----------------------

人工智能的未来

照片由 Unsplash 上的 h heyerlein 拍摄

你是否认为构建一个基于自然语言处理的人工智能应用程序,比如聊天机器人或翻译器,需要大量的数据科学技能,并且会花费大量的时间?它不总是正确的,这篇文章将帮助你更好地理解。我将展示如何使用 GPT-3 以最少的开发工作构建一些令人惊叹的基于自然语言处理的人工智能应用程序。在开始建造之前,让我们先了解一下 GPT 3 号是什么,GPT 3 号的所有特点是什么让它如此特别。

什么是 GPT-3?

GPT-3 是预训练的生成式 Transformer 3,它是一种在互联网上的大量数据集上训练的语言模型,由一家名为 OpenAI 的公司开发。GPT-3 是通过 API 提供的,目前,该 API 处于受控测试阶段,有一个等待名单,可以获得这个惊人的 API。

以下是为什么 GPT-3 模型被谈论得最多的一些原因

  • GPT-3 模型由 1750 亿个参数组成,以前的版本,GPT-2 模型只有 15 亿个参数。参数是将输入转换为输出的神经网络模型中的权重
  • 它是一个生成模型,这意味着它有能力生成一个连贯的长单词序列作为输出
  • 这种最先进的语言模型可以回答几乎任何传递给它的问题,而且以一种更人性化的方式
  • 因此,模型训练中使用的数十亿个单词、文本和代码片段使它能够用多种编程语言自动编码
  • 它的多语言文本处理也有助于处理英语以外的语言
  • 最好的部分是 GPT-3 模型可以执行特定的任务,如成为一名翻译或聊天机器人或代码生成器,无需任何定制或任何特殊调整,它需要的只是一些训练示例

要了解更多关于这个神奇模型的技术细节,请点击这里。在这篇文章中,我将向你展示如何使用这个神奇的 API 来解决不同的基于 NLP 的人工智能用例。

获取 GPT-3 测试版 API

要构建本文中涵盖的用例,您需要访问 GPT-3 测试版 API。它目前只能通过邀请获得,您可以使用下面的链接申请访问。它将带您进入一个表格,其中会询问一些关于您的组织和您计划实施的项目的问题。

https://beta.openai.com

实施背景

为了与 GPT-3 API 接口,我将使用来自下面的gp t3-沙箱仓库的脚本。我在这个库中使用的脚本是 API 文件夹中的 gpt.py,它使我能够访问 GPT-3 API,从而可以显示可以解决的不同用例。本文使用的脚本可以在这里找到

用例 1 —聊天机器人

在这里,我们不会传递任何训练示例,而只是直接访问 API 并将其用作聊天机器人。

在下面的例子中,我正在导入所需的包以及我们从“gpt3-sandbox”存储库中下载的脚本。我们将向模型传递三个参数,

  • 发动机——有四个选项供我们选择,分别是达芬奇、阿达、巴贝奇、居里。我们将使用达芬奇,因为它是使用 1750 亿个参数训练的最强大的引擎
  • 温度-通常介于 0 和 1 之间,用于控制生成输出的随机性。值为 0 使模型具有确定性,也就是说,每次执行时输出都是相同的,而另一方面,值为 1 时,生成的输出具有很高的随机性。
  • max _ tokens 最大完成长度

在下面的脚本中,需要询问的问题被传递给变量“prompt1 ”,然后使用 submit_request 函数传递给模型。结果存储在“output1”变量中,如下所示,

在上面的例子中,正如你所看到的,这个模型可以对所提的问题给出一个非常好的回答,而不需要调整。由于这里我们不提供任何训练示例,模型输出不需要总是响应,它可以提出一组类似的问题或与传递的输入相关的内容。通过提供一些训练样本,可以提高性能

用例 2 — LaTex —文本到等式

在下面的例子中,我们将看到文本到等式转换的实现,只需要很少的训练,这是其他预训练模型所不可能的。

在下面的示例中,温度值已经增加,以使响应具有一定的随机性,我们还将一些预定义的示例作为训练数据集传递给模型。只需 5 个例子,我们就可以训练模型将文本转换成方程。在使用已知示例训练模型之后,我们将以下内容作为输入“x 的平方加上 2 倍”,模型将其转换为一个等式。

用例 3—翻译(英语到法语)

就像上面的几个例子一样,我们可以训练模型像一个翻译一样工作。下面是翻译器模块的代码,我们在这里训练模型将英语文本翻译成法语,只有三个例子。

该模型能够以非常少的开发工作量执行特定的任务,如“外语翻译器”或“文本到等式转换器”,这使得它非常特别。

下面是一个教程视频,我提供了一个用例实现的演练。

一些使用 GPT-3 创建的酷应用程序

要了解更多使用 GPT3 构建的有趣应用程序,请查看本页这里。

关于我

我是一名拥有超过 10 年经验的数据科学专家,并且已经撰写了 2 本数据科学方面的书籍。我写数据科学相关的内容是为了让它简单易懂。跟我上 我也有一个 YouTube 频道,在那里我教授和谈论各种数据科学概念。如果有兴趣,可以订阅我下面的频道。

https://www.youtube.com/c/DataSciencewithSharan

如何在你的组织中建立一个人工智能道德团队?

原文:https://towardsdatascience.com/how-to-build-an-ai-ethics-team-at-your-organization-373823b03293?source=collection_archive---------25-----------------------

Javier Allegue Barros 在 Unsplash 上拍摄的照片

所以你在研究人工智能系统,并且对负责任的人工智能感兴趣?在实现这一目标的过程中,你遇到过挑战吗?许多文章提到了从原则到实践的转变,但是当你试图在实践中实现它们时,却以失败告终。那么少了什么呢?这里有一些想法,我认为会帮助你迈出实现它的第一步。

获得领导认同

是的,这很重要!为什么?嗯,在你的组织中,不同的单位有不同的激励和目标。在实践中实现负责任的人工智能需要不同单位之间的协调。领导团队可以帮助提供一个统一的命令,将不同的单位聚集在一起实现这一目标。

更重要的是,他们可以作为在你的组织中追求负责任的人工智能背后的“为什么”的中心传播点。他们有权制定政策,推动整体变革,让基层工作变得更轻松、更有效。尤其是在你面临同事不情愿的情况下,来自领导层的明确信息为每个人提供了一颗北极星。

最后,当我们(研究和从业者社区)为人工智能伦理领域的一些非常复杂的挑战找出切实可行的解决方案时,领导在为你提供必要的资源和“空中掩护”以试验工具和技术方面发挥着重要作用。

建立反馈机制

作为对上述建议的补充,我们还应该使现场的实践者能够很容易地提供关于工作良好和不良好的工具、技术和过程的反馈。当您有一个大型组织,有许多团队在开发非常不同的产品和服务时,这一点非常重要。自上而下的指导方针和任务可能会因缺乏背景和细微差别而受到影响,而这种情况只会在接近行动地点时变得更加清晰。

有效的反馈机制有两个特点:它们易于归档,并且对哪些反馈被采纳具有透明度。许多地方在第二个方面失败了,没有这一点,整个征求反馈的工作就变得毫无结果。这也从一开始就阻碍了员工分享反馈,使他们对这个过程失去信任。分享已采取行动的反馈结果(通常可以通过工具、技术和流程的变化看到),更重要的是,分享未采取行动的反馈结果以及未采取行动的原因,这将唤起组织中员工的更高信任度。

授权给人们做决定

通常,那些最接近问题和构建解决这些问题的解决方案的人具有高度的背景洞察力。我们可以通过授权这些人做出决策来利用这些见解。这种授权很重要,因为它确保人们对他们正在构建的解决方案有更大的主人翁感。他们变得更有能力解决对他们的用户和客户真正重要的问题。

一个分层的组织可以帮助不同的团队朝着一个共同的愿景团结起来。尽管如此,当辅以自下而上的方法来生成解决方案并授权员工执行这些解决方案时,我们增加了实现我们负责任的人工智能目标的可能性。

建立这种授权的实际方法是开始分配少量的直接责任来修改产品和服务提供,并随着时间的推移,随着人们表现出对 it 的能力和技能,增加这种责任的范围。更重要的是,用促进负责任人工智能决策的培训项目积极补充这种在职体验将使这种方法取得成功。

与组织价值观保持一致

当人工智能伦理被框定在与组织的使命和价值观一致的环境中时,其中一个核心的不协调之处就出现了。在它们之间建立明确的联系有助于促进理解和利用组织内的其他评估工具(如绩效评估)和政策。

它还有助于将负责任的人工智能作为组织中每个人的工作角色的关键功能进行渗透,这有助于将这些责任有机整合到现有的工作角色中,并使在组织中创建新的工作角色变得容易,这些新的工作角色的任务是在组织中实施人工智能道德。

让 RAI 成为常态而不是例外

正如微软在工具和流程方面投入了多年的努力,以使可访问性成为他们产品和服务的一等公民一样,让负责任的人工智能成为规范而不是例外应该是我们的北极星。

如果通过投资,我们可以使这些想法的实现成为一个默认的动作和简单的动作,那么我们不仅会获得更高的牵引力,而且还会阻止开发人员做除了“正确的”事情之外的任何事情。是的,最后一部分有点令人向往,但并非不切实际!

我很想听听您的意见,看看这些想法中是否有您感兴趣的,以及您是否在您的组织中尝试过这些想法。

请订阅来自蒙特利尔人工智能伦理研究所的人工智能伦理简报了解更多类似内容。

如何建立一个令人惊艳的音乐推荐系统?

原文:https://towardsdatascience.com/how-to-build-an-amazing-music-recommendation-system-4cce2719a572?source=collection_archive---------6-----------------------

利用 Spotify 的数据生成音乐推荐。

马塞拉·拉斯科斯基在 Unsplash 上的照片

你有没有想过 Spotify 是如何根据你的收听历史推荐歌曲和播放列表的?你想知道 Spotify 是如何找到与你已经听过的歌曲相似的歌曲的吗?

有趣的是,Spotify 有一个 web API,开发者可以用它来检索歌曲的音频特征和元数据,如歌曲的流行度、节奏、音量、音调和发行年份。我们可以使用这些数据来构建音乐推荐系统,根据用户所听歌曲的音频特征和元数据向用户推荐歌曲。

在本文中,我将演示如何使用 Spotify 歌曲数据集和 Spotify 的 Python 客户端 Spotipy 来构建基于内容的音乐推荐系统。

安装 Spotipy

Spotipy 是 Spotify Web API 的 Python 客户端,开发者可以轻松获取数据并查询 Spotify 的歌曲目录。在这个项目中,我使用 Spotipy 来获取数据,这些数据在我从 Kaggle 访问的原始 Spotify 歌曲数据集中并不存在。您可以使用下面的命令安装 Spotipy 和 pip。

pip install spotipy

安装 Spotipy 后,您需要在 Spotify 开发者页面上创建一个应用,并保存您的客户端 ID 和密钥。

导入库

在下面的代码中,我导入了 Spotipy 和其他一些用于数据操作和可视化的基本库。你可以在 GitHub 上找到该项目的完整代码。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import spotipy
import os
%matplotlib inline

读取数据

为了建立一个音乐推荐系统,我使用了 Spotify 数据集,它在 Kaggle 上公开,包含超过 170,000 首不同歌曲的元数据和音频特征。我使用了这个数据集中的三个数据文件。第一个文件包含单首歌曲的数据,而接下来的两个文件包含按流派和歌曲发行年份分组的数据。

spotify_data = pd.read_csv('./data/data.csv.zip')
genre_data = pd.read_csv('./data/data_by_genres.csv')
data_by_year = pd.read_csv('./data/data_by_year.csv')

我在下面加入了列元数据,它是通过为每个数据帧调用熊猫 info 函数生成的。

spotify_data

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 170653 entries, 0 to 170652
Data columns (total 19 columns):
 #   Column            Non-Null Count   Dtype  
---  ------            --------------   -----  
 0   valence           170653 non-null  float64
 1   year              170653 non-null  int64  
 2   acousticness      170653 non-null  float64
 3   artists           170653 non-null  object 
 4   danceability      170653 non-null  float64
 5   duration_ms       170653 non-null  int64  
 6   energy            170653 non-null  float64
 7   explicit          170653 non-null  int64  
 8   id                170653 non-null  object 
 9   instrumentalness  170653 non-null  float64
 10  key               170653 non-null  int64  
 11  liveness          170653 non-null  float64
 12  loudness          170653 non-null  float64
 13  mode              170653 non-null  int64  
 14  name              170653 non-null  object 
 15  popularity        170653 non-null  int64  
 16  release_date      170653 non-null  object 
 17  speechiness       170653 non-null  float64
 18  tempo             170653 non-null  float64
dtypes: float64(9), int64(6), object(4)
memory usage: 24.7+ MB

流派 _ 数据

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2973 entries, 0 to 2972
Data columns (total 14 columns):
 #   Column            Non-Null Count  Dtype  
---  ------            --------------  -----  
 0   mode              2973 non-null   int64  
 1   genres            2973 non-null   object 
 2   acousticness      2973 non-null   float64
 3   danceability      2973 non-null   float64
 4   duration_ms       2973 non-null   float64
 5   energy            2973 non-null   float64
 6   instrumentalness  2973 non-null   float64
 7   liveness          2973 non-null   float64
 8   loudness          2973 non-null   float64
 9   speechiness       2973 non-null   float64
 10  tempo             2973 non-null   float64
 11  valence           2973 non-null   float64
 12  popularity        2973 non-null   float64
 13  key               2973 non-null   int64  
dtypes: float64(11), int64(2), object(1)
memory usage: 325.3+ KB

逐年数据

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2973 entries, 0 to 2972
Data columns (total 14 columns):
 #   Column            Non-Null Count  Dtype  
---  ------            --------------  -----  
 0   mode              2973 non-null   int64  
 1   genres            2973 non-null   object 
 2   acousticness      2973 non-null   float64
 3   danceability      2973 non-null   float64
 4   duration_ms       2973 non-null   float64
 5   energy            2973 non-null   float64
 6   instrumentalness  2973 non-null   float64
 7   liveness          2973 non-null   float64
 8   loudness          2973 non-null   float64
 9   speechiness       2973 non-null   float64
 10  tempo             2973 non-null   float64
 11  valence           2973 non-null   float64
 12  popularity        2973 non-null   float64
 13  key               2973 non-null   int64  
dtypes: float64(11), int64(2), object(1)
memory usage: 325.3+ KBExploratory Data Analysis

基于上面的列描述,我们可以看到每个数据帧具有关于音频特征的信息,例如不同歌曲的可跳舞性和响度,这些信息也已经跨流派和特定年份进行了汇总。

探索性数据分析

该数据集非常有用,可用于多种任务。在建立推荐系统之前,我决定创建一些可视化工具,以便更好地理解数据和过去 100 年来音乐的趋势。

随着时间推移的音乐

使用按年份分组的数据,我们可以了解音乐的整体声音从 1921 年到 2020 年是如何变化的。在下面的代码中,我使用 Plotly 来可视化过去 100 年来歌曲的不同音频特征的值。

import plotly.express as px sound_features = ['acousticness', 'danceability', 'energy', 'instrumentalness', 'liveness', 'valence']
fig = px.line(data_by_year, x='year', y=sound_features)fig.show()

根据上面的情节,我们可以看到,音乐已经从 20 世纪初更多的声学和器乐声音过渡到 21 世纪初更多的舞曲和活力的声音。20 世纪 20 年代的大部分曲目很可能是古典和爵士风格的器乐作品。由于计算机和先进的音频工程技术的出现,2000 年代的音乐听起来非常不同,这些技术允许我们创建具有各种效果和节拍的电子音乐。

我们还可以看看音乐的平均节奏或速度在这些年里是如何变化的。下面的代码生成的图表也支持声音向电子音乐的急剧转变。

fig = px.line(data_by_year, x='year', y='tempo')fig.show()

根据上面的图表,我们可以清楚地看到,在过去的一个世纪里,音乐的发展速度明显加快了。这一趋势不仅是 20 世纪 60 年代迷幻摇滚等新流派的结果,也是音频工程技术进步的结果。

不同体裁的特点

该数据集包含不同歌曲的音频特征以及不同流派的音频特征。我们可以利用这些信息来比较不同的流派,了解它们在声音上的独特差异。在下面的代码中,我从数据集中选择了 10 个最流行的流派,并可视化了每个流派的音频特征。

top10_genres = genre_data.nlargest(10, 'popularity')
fig = px.bar(top10_genres, x='genres', y=['valence', 'energy', 'danceability', 'acousticness'], barmode='group')fig.show()

上述许多流派,如中国电穿孔是非常具体的,很可能属于一个或多个广泛的流派,如流行音乐或电子音乐。我们可以将这些高度特定的流派进行分类,并根据它们的音频特征来理解它们与其他流派的相似程度。

用 K-均值聚类流派

在下面的代码中,我使用了著名而简单的 K-means 聚类算法,根据每个流派的数字音频特征,将该数据集中的 2,900 多种流派分成 10 个聚类。

from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipelinecluster_pipeline = Pipeline([('scaler', StandardScaler()), ('kmeans', KMeans(n_clusters=10, n_jobs=-1))])X = genre_data.select_dtypes(np.number)
cluster_pipeline.fit(X)
genre_data['cluster'] = cluster_pipeline.predict(X)

既然流派已经被分配到聚类中,我们可以通过在二维空间中可视化聚类来进一步进行分析。

用 t-SNE 可视化体裁聚类

每个流派都有许多音频特征,很难在高维空间中可视化聚类。但是,我们可以使用一种称为t-分布式随机邻居嵌入的降维技术,将数据压缩到一个二维空间中,如下面的代码所示。

from sklearn.manifold import TSNEtsne_pipeline = Pipeline([('scaler', StandardScaler()), ('tsne', TSNE(n_components=2, verbose=2))])
genre_embedding = tsne_pipeline.fit_transform(X)projection = pd.DataFrame(columns=['x', 'y'], data=genre_embedding)
projection['genres'] = genre_data['genres']
projection['cluster'] = genre_data['cluster']

现在,通过使用 Plotly 的散射函数,我们可以很容易地在二维坐标平面中可视化流派簇。

import plotly.express as pxfig = px.scatter(
    projection, x='x', y='y', color='cluster', hover_data=['x', 'y', 'genres'])
fig.show()

二维空间中的流派簇。

用 K-Means 聚类歌曲

为了理解如何建立一个更好的推荐系统,我们还可以使用 K-means 对歌曲进行聚类,如下所示。

song_cluster_pipeline = Pipeline([('scaler', StandardScaler()), 
                                  ('kmeans', KMeans(n_clusters=20, 
                                   verbose=2, n_jobs=4))],verbose=True)X = spotify_data.select_dtypes(np.number)
number_cols = list(X.columns)
song_cluster_pipeline.fit(X)
song_cluster_labels = song_cluster_pipeline.predict(X)
spotify_data['cluster_label'] = song_cluster_labels

基于主成分分析的歌曲聚类可视化

歌曲数据帧比流派数据帧大得多,所以我决定使用 PCA 而不是 t-SNE 进行降维,因为它的运行速度明显更快。

from sklearn.decomposition import PCApca_pipeline = Pipeline([('scaler', StandardScaler()), ('PCA', PCA(n_components=2))])
song_embedding = pca_pipeline.fit_transform(X)projection = pd.DataFrame(columns=['x', 'y'], data=song_embedding)
projection['title'] = spotify_data['name']
projection['cluster'] = spotify_data['cluster_label']

现在,我们可以使用下面的代码在二维空间中可视化歌曲集群。

import plotly.express as pxfig = px.scatter(projection, x='x', y='y', color='cluster', hover_data=['x', 'y', 'title'])
fig.show()

二维空间中的歌曲集群。

上面的情节是交互式的,所以当你悬停在点上时,你可以看到每首歌的标题。如果你花一些时间探索上面的情节,你会发现相似的歌曲往往位于彼此附近,集群内的歌曲往往至少有些相似。这个观察是我在下一节中创建的基于内容的推荐系统背后的关键思想。

构建基于内容的推荐系统

根据上一节的分析和可视化,很明显,相似的流派往往具有彼此靠近的数据点,而相似类型的歌曲也聚集在一起。

在实践层面上,这一观察非常有意义。相似的风格听起来相似,并且来自相似的时间段,而这些风格中的歌曲也是如此。我们可以利用这种想法,通过获取用户听过的歌曲的数据点,并推荐与附近数据点对应的歌曲,来构建推荐系统。

查找不在数据集中的歌曲

在我们建立这个推荐系统之前,我们需要能够容纳原始 Spotify 歌曲数据集中不存在的歌曲。我在下面定义的 find_song 函数从 Spotify 的目录中获取任何歌曲的数据,给出歌曲的名称和发行年份。结果以熊猫数据帧的形式返回,数据字段出现在我从 Kaggle 下载的原始数据集中。

有关如何使用 Spotipy 的详细示例,请参考此处的文档页面。

生成歌曲推荐

现在终于可以搭建音乐推荐系统了!我使用的推荐算法非常简单,遵循三个步骤:

  1. 计算用户听过的每首歌曲的音频和元数据特征的平均向量。
  2. 在数据集中找到 n 个最接近这个平均向量的数据点(不包括用户收听历史中歌曲的点)。
  3. 拿这 n 点,推荐对应的歌曲

该算法遵循在基于内容的推荐系统中使用的通用方法,并且是可推广的,因为我们可以用从经典欧几里德距离到余弦距离的大范围距离度量来数学地定义术语最近。为了这个项目的目的,我使用了余弦距离,这是为两个向量 uv 定义的。

余弦距离公式。

换句话说,余弦距离是 1 减去余弦相似度,余弦是两个向量之间的夹角。余弦距离通常用在推荐系统中,并且即使当所使用的向量具有不同的量值时也能很好地工作。如果两首歌曲的向量是平行的,它们之间的角度将是零,这意味着它们之间的余弦距离也将是零,因为零的余弦是 1。

我在下面定义的函数在 Scipy 的 cdist 函数的帮助下实现了这个简单的算法,用于查找两对点集合之间的距离。

该算法背后的逻辑听起来令人信服,但这个推荐系统真的有效吗?找到答案的唯一方法是用实际例子来测试它。

比方说,我们想为听 90 年代垃圾音乐的人推荐音乐,特别是涅槃乐队的歌曲。我们可以使用 recommend_songs 函数来指定他们的收听历史并生成推荐,如下所示。

recommend_songs([{'name': 'Come As You Are', 'year':1991},
                {'name': 'Smells Like Teen Spirit', 'year': 1991},
                {'name': 'Lithium', 'year': 1992},
                {'name': 'All Apologies', 'year': 1993},
                {'name': 'Stay Away', 'year': 1993}],  spotify_data)

运行此功能会产生下面的歌曲列表。

[{'name': 'Life is a Highway - From "Cars"',
  'year': 2009,
  'artists': "['Rascal Flatts']"},
 {'name': 'Of Wolf And Man', 'year': 1991, 'artists': "['Metallica']"},
 {'name': 'Somebody Like You', 'year': 2002, 'artists': "['Keith Urban']"},
 {'name': 'Kayleigh', 'year': 1992, 'artists': "['Marillion']"},
 {'name': 'Little Secrets', 'year': 2009, 'artists': "['Passion Pit']"},
 {'name': 'No Excuses', 'year': 1994, 'artists': "['Alice In Chains']"},
 {'name': 'Corazón Mágico', 'year': 1995, 'artists': "['Los Fugitivos']"},
 {'name': 'If Today Was Your Last Day',
  'year': 2008,
  'artists': "['Nickelback']"},
 {'name': "Let's Get Rocked", 'year': 1992, 'artists': "['Def Leppard']"},
 {'name': "Breakfast At Tiffany's",
  'year': 1995,
  'artists': "['Deep Blue Something']"}]

从上面的列表中我们可以看到,推荐算法产生了一个 90 年代和 2000 年代的摇滚歌曲列表。名单中的乐队如 Metallica,Alice in Chains 和 Nickelback 与 Nirvana 相似。排行榜上的第一首歌,“生活是一条高速公路”不是一首垃圾歌曲,但如果你仔细听,吉他即兴重复的节奏实际上听起来类似于涅槃乐队的“闻起来像青少年精神”。

如果我们想为听迈克尔·杰克逊歌曲的人做同样的事情呢?

recommend_songs([{'name':'Beat It', 'year': 1982},
                 {'name': 'Billie Jean', 'year': 1988},
                 {'name': 'Thriller', 'year': 1982}], spotify_data)

推荐函数给出了下面的输出。

[{'name': 'Hot Legs', 'year': 1977, 'artists': "['Rod Stewart']"},
 {'name': 'Thriller - 2003 Edit',
  'year': 2003,
  'artists': "['Michael Jackson']"},
 {'name': "I Didn't Mean To Turn You On",
  'year': 1984,
  'artists': "['Cherrelle']"},
 {'name': 'Stars On 45 - Original Single Version',
  'year': 1981,
  'artists': "['Stars On 45']"},
 {'name': "Stars On '89 Remix - Radio Version",
  'year': 1984,
  'artists': "['Stars On 45']"},
 {'name': 'Take Me to the River - Live',
  'year': 1984,
  'artists': "['Talking Heads']"},
 {'name': 'Nothing Can Stop Us', 'year': 1992, 'artists': "['Saint Etienne']"}]

排行榜首是洛德·斯蒂沃特的歌曲,他和迈克尔·杰克逊一样,在 20 世纪 80 年代成名。该列表还包含迈克尔·杰克逊的《颤栗者》的 2003 年版本,这是有意义的,因为用户已经听过这首歌的 1982 年版本。该榜单还包括 20 世纪 80 年代乐队的流行和摇滚歌曲,如《45 岁的星星》和《会说话的脑袋》。

我们可以使用更多的例子,但是这些例子应该足以展示推荐系统如何产生歌曲推荐。要获得更完整的示例,请查看该项目的 GitHub 库。用这段代码随意创建你自己的播放列表!

摘要

Spotify 跟踪歌曲的元数据和音频特征,我们可以用它们来建立音乐推荐系统。在本文中,我演示了如何使用这些数据构建一个简单的基于内容的音乐推荐系统,该系统采用余弦距离度量。像往常一样,你可以在 GitHub 上找到这个项目的完整代码。

如果你喜欢这篇文章,并且想了解更多关于推荐系统的知识,可以看看下面列出的我以前的一些文章。

加入我的邮件列表

你想在数据科学和机器学习方面变得更好吗?您想了解数据科学和机器学习社区的最新图书馆、开发和研究吗?

加入我的邮件列表,获取我的数据科学内容的更新。当你注册的时候,你还会得到我免费的解决机器学习问题的逐步指南

来源

  1. Y.E. Ay, Spotify 数据集 1921–2020,160k+曲目【T7,】,(2020),Kaggle。
  2. 长度范德马滕和 g .辛顿,使用 t-SNE 可视化数据,(2008),《机器学习研究杂志》。
  3. 页(page 的缩写)维尔塔宁等人。al,SciPy 1.0:Python 中科学计算的基本算法,(2020),自然方法。

如何构建自动化开发管道

原文:https://towardsdatascience.com/how-to-build-an-automated-development-pipeline-d0b9820a2f3d?source=collection_archive---------14-----------------------

行业笔记

用最小的挫折开发软件的剧本

在 Unsplash 上 Manouchehr Hejazi 拍摄的照片

在过去的几年里,我领导过许多开发团队。我发现其中的一个共同点是需要建立一个自动化开发管道。你不一定需要复杂的开发管道。我发现即使是一个基本的管道也可以防止你日常开发中的许多挫折。如果你想开发一个软件产品,即使是一个小玩意,开发管道对你来说也是必不可少的。自动化开发管道帮助您持续评估产品的健全性。对于开发团队来说,没有什么比破软件更伤人的了。你必须尽你所能去阻止它。我来分享两个你发自内心感受到这种需求的场景。****

  • 场景 1(当您想要保护主分支免于意外错误时)——您在团队中工作,并且使用 git 存储库来管理开发。每天都有几个拉取请求要合并到主分支。每个人都尽最大努力编写高质量的功能代码,但不时会有错误注入主分支。结果,代码库停止运行,因此,团队变得沮丧。进度变得非常缓慢,最后期限一个接一个地错过。你希望有办法阻止这种事情发生。
  • 场景 2(当您想要加快开发速度时)——您正在开发一个 web scraper,为一个数据科学项目收集数据。数据科学团队每天都需要大量的数据。在解析机器学习管道中的数据时,您不能承受任何延迟。尽管如此,目标网站中的 HTML 结构不时会发生变化,导致 scraper 停止运行。您希望有一种方法可以自动测试刮刀,并尽快识别错误。

在本文中,我用简单的语言描述了开发管道。我还描述了构建自动化开发管道的最重要的步骤:

  • 如何构建和启动服务器
  • 如何构建容器化解决方案
  • 如何自动构建容器化的解决方案

我希望这有助于你更好地构建开发管道,远离不必要的挫折。

什么是“开发管道”?

开发管道是自动连续执行的一系列命令,用于测试、构建或部署软件产品。这些命令在不同的级别上运行,并使用不同的工具。例如,需要一个服务器来构建开发管道。一个问题是“如何配置这个服务器?”您可以手动配置,但最佳实践是使用 Docker 技术。

使用 Docker 技术有很多优势,比如能够在需要时以最少的麻烦从一个服务迁移到另一个。当您开始构建真实世界的产品时,您会发现能够从一个服务迁移到另一个服务是多么重要。几个月前我也遇到过这种情况。我们被要求从 GCloud 迁移到 OVH ,因为该公司在 OVH 基础设施上有一些其他服务。我们只需不到几天的时间就可以将所有内容从 GCloud 迁移到 OVH。想象一下,如果我们手动配置,会发生什么!

开发管道是自动连续执行的一系列命令,用于测试、构建或部署软件产品。

如何构建自动化开发管道

构建自动化开发管道需要三个步骤:(a)构建并启动服务器,(b)构建容器化的解决方案,(c)连续设置一系列命令。

照片由泰勒·维克在 Unsplash 上拍摄

—如何构建和启动服务器

启动服务器需要三个步骤:(1) 构建 docker 映像,(2) 存储 docker 映像,(3) 运行 docker 映像。如果你不想有一个自动化的开发管道,你不需要采取这一步。基本上可以在自己的机器上运行。但是,如果您想要设置 CI/CD 工具,您必须为此启动服务器。

1。构建 Docker 映像— 您需要启动服务器来构建自动化开发管道。有很多方法可以做到这一点。我的建议是构建一个基于 Linux 的 Docker 镜像并安装所有需要的库。你可以通过编写一个 Dockerfile 来构建一个 Docker 镜像。docker file 是一个文本文档,包含了所有用于安装所有必需的库和软件包的命令。您可以使用下面的代码基于 Docker 文件构建 Docker 映像。

docker **build** —f Dockerfile -t REPOSITORY_NAME/IMAGE_NAME:TAG .

要了解如何为服务器编写 Dockerfile,可以阅读本文:如何创建 Ubuntu 服务器使用 Docker 构建 AI 产品。

2。存储一个 Docker 映像— 然后,你必须Docker 注册表中存储Docker 映像T21。Docker 注册表基本上是一个存储 Docker 图像的地方,仅此而已。可以选择包括 DockerHub 或者亚马逊 ECR 在内的任何服务。如果你不知道,我推荐使用 DockerHub,因为它是 Docker 命令行界面的原生版本,与其他服务相比,它让你的生活更轻松。在选择注册中心的过程中,会有一些关于安全性和效率的问题,这些问题在现阶段并不重要。例如,如果您有一个复杂的管道,最好使用位于正在使用的其他云服务旁边的注册服务。这使得命令如docker pulldocker push执行得更快。您可以使用下面的代码将 Docker 映像推送到远程 Docker 存储库。

docker **push** REPOSITORY_NAME/IMAGE_NAME:TAG

3。运行 Docker 镜像— 你可以在许多服务上运行 Docker 镜像来启动服务器。最后两步是关于如何构建和存储一个 Docker 映像作为服务器使用。这一步是关于如何启动服务器。如果你不想有一个“自动化”的开发管道,你就不需要服务器。

让我分享一个在 CircleCI 上用于启动服务器的代码片段,circle CI 是目前使用的一个著名的 CI/CD 工具。下面的代码是定义要在服务器上运行的测试作业的一部分,该服务器使用 Docker 映像启动。这是 CircleCI 使用的语法,因此其他 CI/CD 工具可能不同,但概念是相同的。启动后,可以运行其他步骤,如checkoutcheckout是 CircleCI 用来在服务器上克隆一个代码库的特殊代码,该代码库是在之前的一个步骤中启动的。如果你想了解更多关于 CircleCI 的内容,我推荐你阅读这篇文章:如何用简单的话学习 circle ci。

jobs:  
  test:
    docker:     
      - image: REPOSITORY_NAME/DOCKERIMAGE_NAME:TAG
        auth: 
          username: $USERNAME
          password: $PASSWORD
    steps:      
      - checkout      
      - run:
          ...

照片由奥拉夫·阿伦斯·罗特内在 Unsplash 拍摄

—如何构建容器化的解决方案

构建软件最重要的一步是确保它能工作。你可以把它看作是一个“集成测试”,将单个的模块组合在一起,作为一个组进行测试。因此,如果您正在开发一个数据科学项目,您可能希望构建一个集成测试,如果您正在开发一个 web 应用程序,您可能希望使用 Docker 构建一个容器化的解决方案。

使用 Docker 技术,您可以为服务器构建一个 Docker 映像,并为您的解决方案构建一个 Docker 映像。您在为服务器和解决方案构建 Docker 映像时面临的挑战是相似的;然而,他们有不同的目的。正如你在上面读到的,你必须有一个 docker 文件作为“如何做”的处方来构建你的解决方案。当你有了一个功能 Dockerfile 文件,你就可以进入下一步了。请注意,这些是下一节将解释的开发管道的构建块。

照片由 JJ 英在 Unsplash 上拍摄

—如何自动构建容器化解决方案

开发管道是一系列连续执行的命令。您可以通过两种方式自动执行一系列命令:Bash 脚本或 CI/CD 工具。后者给你更多的选项去配置;但是,前一种可以自己解决很多问题。让我们深入了解这些工具是什么。

1。Bash 脚本(当你想要构建一个管道时)——Bash 脚本是一个文本文件,包含一系列命令,当你运行脚本时,这些命令会连续运行。Bash 脚本中的每一行都是您先前在终端中执行的一个命令,以完成特定的任务。Bash 脚本中编写的命令的顺序与您在终端中运行它们的顺序完全相同。下面的代码提示了什么是 bash 脚本。请注意,Bash 脚本在 Windows 和 macOS 上略有不同,这不是本文的重点。您可以使用下面用 Bash 脚本编写的代码来buildpushDocker 图像。

#!/bin/bash 
export IMAGE_NAME=XXX
export USERNAME=XXX
export PASSWORD=XXXdocker login -u $USERNAME -p $PASSWORD
docker build -f Dockerfile -t $IMAGE_NAME .
docker push $IMAGE_NAMEE

2。CI/CD(当你想要建立一个“自动化”的管道时)——CI/CD(即持续集成/持续部署)工具是一个专门的软件,主要运行在云上,当它们被触发时,以特定的顺序自动执行一系列命令。它们通常使用 YAML 文件进行配置,您可以在其中定义许多“作业”和“工作流”。“作业”是在单个单元中执行的步骤的集合,类似于上面解释的 Bash 脚本。“工作流”是一组规则,用于根据需要按特定顺序运行一组作业。

我强烈建议首先编写一个 Bash 脚本,然后开始配置您选择的 CI/CD 工具。你可能会问为什么?首先,您很可能需要 Bash 脚本中编写的所有代码来配置 CI/CD 工具。其次,如果你不是专家,设置 CI/CD 工具可能会有点困难。下面的代码是要在 CircleCI 上运行的作业的一部分。正如你所看到的,这些命令与上面的 Bash 脚本完全相同,但是采用了 CircleCI 可以解析的 YAML 形式

...
      - run:
          name: Authentication
          command: docker login -u $USERNAME -p $PASSWORD
      - run:
          name: Build 
          command: docker build -f Dockerfile -t $IMAGE_NAME .
      - run:
          name: Store
          command: docker push $IMAGE_NAME
...

—遗言

自动化开发管道是一个复杂的概念,可以以多种形式实现。在这篇文章中,我试图与你分享主要的概念。你肯定需要学习更多来为你的软件产品建立一个有用的管道。然而,你需要从这篇文章中学到的是,即使是一个小的自动化管道也能帮你很多。所以,我建议你今天就建立一个自动化的管道。你永远不会后悔!

感谢阅读!

如果你喜欢这个帖子,想支持我…

  • 跟我上
  • 亚马逊 上查看我的书!
  • 成为 中的一员
  • 连接上Linkedin
  • 跟我上 推特

https://pedram-ataee.medium.com/membership