TowardsDataScience 博客中文翻译 2020(四百四十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

我如何在 Amazon SageMaker 上建立一个简单的假新闻检测器

原文:https://towardsdatascience.com/how-i-built-a-simple-fake-news-detector-on-amazon-sagemaker-808bf4e0c490?source=collection_archive---------36-----------------------

最近,我决定注册一个 Udacity 纳米学位,因为这个想法在我脑海里盘旋了很久。

在过去的两个月里,每天晚饭后和周末,我都跟着机器学习工程师 Nanodegree 课程,我遇到了亚马逊 SageMaker。

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

归功于 aws.amazon.com

Amazon SageMaker 是一项完全托管的服务,允许数据科学家和开发人员大规模构建、训练和部署机器学习模型。

令人惊讶的是,你真的可以在同一个平台上执行整个端到端的数据科学管道。
事实上,通过 Amazon SageMaker,您可以在一组不同的机器上创建 Jupyter 笔记本实例,这些机器基于计算(CPU/GPU)、RAM 和网络功能而有所不同。

您可以从导入数据、探索和清理数据开始,来训练模型并快速将其投入生产环境。

与 SageMaker 共同的工作流程(至少从我的小经验中学到的是这样的):

  • 数据整合与处理
  • 整合来自任何来源的数据集;
  • 探索它,做可视化和汇总统计,了解数据;
  • 如有必要,清理必须清理的部分,预处理和设计您的特征;
  • 将处理后的数据保存到 S3 存储桶中,该存储桶可以是默认的 SageMaker 实例存储桶,也可以是您选择的其他存储桶。
  • 模型搭建&部署
  • 要建立模型,Amazon SageMaker 自带了一套有监督和无监督的模型,但是你也可以为你的定制模型提供一个你自己选择的框架(Scikit-learn,TensorFlow,MXNet…)连同一个训练脚本;
  • 使用您在 S3 上保存的数据在一个或多个计算实例上训练模型
  • 在 SageMaker 端点上部署估计器以进行推断

我发现 SageMaker 对于数据科学项目来说是一个非常有价值的选择。从现在开始,我将与你分享我在 SageMaker 上进行 Udacity Capstone 项目的最后一次体验。

这个项目处理假/真新闻检测。可以毫无疑问地插入到自然语言处理问题的语境中。
当我在 Kaggle 上导航时,我发现了这个有趣的数据集
该数据集由 2 个 CSV 文件(真实、虚假新闻)组成,其中存储了文章的标题、文章、日期和主题。

问题陈述

所以,这个问题可以这样陈述:给定一篇文章的文本,我希望算法能够预测它指的是真的还是假的新闻。特别是,我将问题的解决方案组织如下:
·来自不同来源(CSV)的数据将被标记和堆叠;
“标题”和“文章”等文本特征被堆叠后,将被处理,以便生成有意义的词汇(没有标签、URL、奇怪的标点符号和停用词)
从这里,可以遵循两条道路,这取决于算法的选择。
如果使用机器学习算法,则有必要创建文本的单词包表示,或者通过使用单词计数,一种术语频率逆文档频率的热编码,可以与其他特征(例如,从日期中提取)一起使用来训练模型;
相反,如果选择深度学习模型,如递归神经网络,人们可以想到只直接使用填充到相同长度的文本序列,并用 word_to_integer 词汇表进行映射。
然后,可以训练神经网络来解决具有二元交叉熵损失的二元分类问题。

由于我的报告长达 10 页,我将只报告主要步骤:

预处理 关于 LSTM 模型的预处理步骤:

  • 我只考虑文章文本作为一个特征,过滤长度在 20 个单词以下和 500 个单词以上的文本,以避免空序列或太长的序列。这些文本已经被停用词、奇怪的标点符号过滤掉,并被转换成小写字母。
  • 我使用来自 Sklearn 的 train_test_split 来拆分训练、验证和测试数据集中的数据
  • 我将 keras 的标记器应用于训练集,然后我使用它来转换验证和测试数据集(以避免数据泄漏),然后将所有序列填充到 max_len 为 500
from tf.keras.preprocessing.text import Tokenizer
from tf.keras.preprocessing import sequencetokenizer = Tokenizer(num_words=80000)
text_tokenizer.fit_on_texts(X_train['article'].astype(str))X_train = text_tokenizer.texts_to_sequences(X_train)
X_val = text_tokenizer.texts_to_sequences(X_val)
X_test = text_tokenizer.texts_to_sequences(X_test)X_train = sequence.pad_sequences(X_train, maxlen=500, padding='post')
X_val= sequence.pad_sequences(X_val, maxlen=500, padding='post')
X_test= sequence.pad_sequences(X_test, maxlen=500, padding='post')

型号

在培训脚本中(请记住我在 SageMaker 上),我定义了环境变量,您可以在这里定义模型结构,对其进行拟合,并在 S3 上保存其工件。这是我使用的网络结构(Keras)。

from tf.keras.layers import Embedding, Bidirectional, LSTM,Dense,Activation
from tf.keras.models import Sequentialdef RNN():model = Sequential()
    layer = model.add(Embedding(80000, 128, input_length = 500))
    layer = model.add(Bidirectional(LSTM(128))
    layer = model.add(Dense(128))   
    layer = model.add(Activation('relu'))
    layer = model.add(Dense(1))
    layer = model.add(Activation('sigmoid')) return model

通过在 LSTM 层添加双向功能,我将精确度提高了 15%以上。

然后您添加代码以适应并保存模型;该代码将由 SageMaker 在培训工作中调用。

model.fit(train_X,
          train_y, 
          batch_size=256,
          epochs=args.n_epochs,
          validation_data=(val_X,val_y))model_path = '/opt/ml/model/'
model.save(os.path.join(model_path,'bi_lstm/1'), save_format='tf')

相反,在实例端,我实例化了一个 TensorFlow 对象,其中设置了训练脚本的路径、我要选择的实例的数量和类型、IAM 角色和超参数:

input_channels = {"train":train_data,
                  "validation":val_data}from sagemaker.tensorflow import TensorFlowestimator = TensorFlow(entry_point = 'source_train/train_keras_lstm.py',
                       train_instance_type='ml.p2.xlarge',
                       train_instance_count=1, 
                       role=role,
                       framework_version='2.1.0',
                       py_version='py3',
                       hyperparameters={"n_epochs":3}

正如你所看到的,我选择了一个’ ml.p2.xlarge '实例,这是一个带有 GPU 访问的亚马逊入门级机器。

使用相同的策略,我在训练模型后部署了它:

predictor = estimator.deploy(initial_instance_count=1,
                             instance_type='ml.c4.xlarge')

并对测试集执行推断(这可以通过 predict() API 来完成,也可以通过在数据较大的情况下创建批处理转换作业来完成):

from sklearn.metrics import accuracy_scorepreds_df = pd.DataFrame(predictor.predict(X_test)
target_preds = pd.concat([y_test,preds_df], axis=1)
target_preds.columns=['targetClass','preds']print(accuracy_score(target_preds['targetClass'],
                     target_preds['preds']))0.986639753940792

我在测试集上获得了 98%的准确率。

除了模型本身,我希望我引起了你对 SageMaker 功能的注意。

如果你想看完整个步骤,看报告或者看一下培训脚本,这是该项目的 GitHub repo

下次见,再见,感谢阅读!

我如何使用 Python 和 Selenium 构建 Twitter Bot?

原文:https://towardsdatascience.com/how-i-built-a-twitter-bot-using-python-and-selenium-c036bfff6af8?source=collection_archive---------36-----------------------

让你的 Python 脚本来做所有的推文吧!!

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

使用 Python 的 Twitter 机器人— Twilio

我们正在寻求这个星球上每一件事情的自动化。从表单自动填充到无人驾驶汽车,人类使用自动化流程已经走过了漫长的道路。Python 脚本在生成自动化工具和任务方面非常方便。另一方面,Selenium 以自动化浏览器和网络应用而闻名。当 Python 和 Selenium 的力量结合在一起时,人们可以轻松地自动化数百项任务。由于这两者的结合,制造机器人变得更加容易。

这篇文章是制作一个简单的 Twitter 机器人的指南,这个机器人会为你自己发微博。

图书馆

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Selenium 是我们构建 Twitter bot 所需的主要库。我已经从 selenium 导入了“webdriver”子包来访问浏览器并在其上执行任务。此外,我已经导入了“Keys”子包,以便在自动化过程中使用键盘键进行输入。

现在是肉的部分

我已经初始化了一个类“TwitterBot ”,它有一个接受 Twitter 帐户用户名和密码的构造函数。此外,它踢了自动化的 Chrome 网络驱动程序。

class TwitterBot():
    def __init__(self,username,password):
        self.browser=webdriver.Chrome("/Users/vishalsharma/Downloads/chromedriver")
        self.username=username
        self.password=password

你可以从下载 Chrome 网络驱动

我在类中定义了一个函数“SignIn ”,它通过在登录表单中输入用户名和密码来登录 twitter 句柄。我已经使用“find_element_by_name”方法来定位 web 元素并填写表单。

def signIn(self):
    self.browser.get("https://www.twitter.com/login")
    time.sleep(5)
    usernameInput=self.browser.find_element_by_name("session[username_or_email]")
    passwordInput=self.browser.find_element_by_name("session[password]")
    usernameInput.send_keys(self.username)
    passwordInput.send_keys(self.password)
    passwordInput.send_keys(Keys.ENTER)
    time.sleep(5)

对于我们的推文部分,我使用了“find_element_by_xpath”方法,并使用了“send_keys”方法。在最后一条语句中,“send_keys”有两个参数。这两个参数按 Command+Enter 键发布推文。

def TweetSomething(self):
    tweet = self.browser.find_element_by_xpath('''//*[@id='react-root']/div/div/div[2]/main/div/div/div/div/div
                                                  /div[2]/div/div[2]/div[1]/div/div/div/div[2]/div[1]/div/div
                                                  /div/div/div/div/div/div/div/div[1]/div/div/div/div[2]/div
                                                  /div/div/div''')
    tweet.send_keys("""Hello World!""")
    tweet.send_keys(Keys.COMMAND, Keys.ENTER)

在“find_element_by_xpath”中,你可能会发现大量的胡言乱语。但是,这只是一种定位 web 元素的方法。您也可以使用其他定位方法。找到他们这里

调用类

现在,在控制台中给出用户名和密码。调用“TwitterBot”类并运行该类中的方法。

if __name__=="__main__":
    username= input("Enter your username: ")
    password= input("Enter your password: ")
    t=TwitterBot(username,password)
    t.signIn()
    t.TweetSomething()

就是这样!你已经建立了一个为你发微博的推特机器人。现在,你可以查看 Instagram 的关注者,比如照片,甚至可以右键点击你的 Tinder 个人资料。现在,继续尝试使用 Python 和 Selenium 自动化您的社交媒体。

如需讨论和反馈,请联系我 Linkedin

构建 web scraper 工具来分析多伦多的公寓价格

原文:https://towardsdatascience.com/how-i-built-a-web-scraper-tool-to-analyze-condo-prices-in-toronto-56f829c55e93?source=collection_archive---------27-----------------------

尝试用数据驱动的方法来做人生中最重要的决定之一:买房

公寓一直令我着迷,在我居住的城市,它们可能是许多首次购房者脑海中的第一个(或现实的)选择。除非你一直生活在困境中,否则你会意识到多伦多的房价在过去的十年里上涨了许多倍,在过去的 5 年里更是如此。最近,公寓市场火了起来。所以,如果你和我一样,想买一套公寓,那你来对地方了。

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

桑德罗·舒赫在 Unsplash 上的照片

作为一个高度数据驱动的人,我建立了一个网络抓取工具,帮助我分析多伦多的公寓价格。我的首选网站是 Condos.ca 。它有一个良好的用户界面,并提供市场情报(我认为这将有助于验证我的结果)。在撰写本文时,它的清单跨越了 80 多个网页,我将从前 50 页中提取数据,如本文后面所述。

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

图片来自 Condos.ca 主页

这项工作有两个目标:

  • 从网站上搜集相关参数的必要数据,建立基准数据库
  • 通过对数据库进行一些探索性的 EDA 来进行市场研究,如每间卧室的平均价格、平均维护成本、平均公寓面积等。

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

数据采集(image src: Condos.ca)

我提取了每张清单上显示的信息,比如价格、街道地址、卧室、浴室的数量、是否有停车场、面积范围以及维护费用。(注:许多其他参数影响公寓价格,如楼龄、财产税、楼层数、图像等。,但为了简单起见,我留下了这些)

这里值得一提的是,在进行这个练习之前,我对 HTML 没有任何经验。但是这就是网络抓取的美妙之处。你不需要对 HTML 有很深的理解。我简单地学习了如何从 HTML 代码中的标签瀑布中提取所需的值。剩下的都是 python!这里的是关于如何抓取网站的有用资源。

那么让我们开始吧!

我们从导入必要的模块开始。

from bs4 import BeautifulSoup *# For HTML parsing* from time import sleep *# To prevent overwhelming the server between connections* import pandas as pd *# For converting results to a dataframe and bar chart plots**# For Visualizations*
import matplotlib.pyplot as plt
import plotly.offline as py
import plotly.graph_objs as go*%matplotlib inline* 

当我请求抓取网站时,我遇到了一个错误。这是因为许多网站试图阻止用户抓取任何数据,这可能是非法的,取决于一个人计划如何处理这些数据(不过我已经获得了 condos.ca 的许可)。为了解决这个问题,我使用了一个名为 Selenium 的 API。它是一个 API ,允许你像一个真正的用户那样以编程的方式与浏览器交互。虽然 Selenium 主要用于帮助测试 web 应用程序,但是它也可以用于任何需要浏览器自动化的任务。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver.get(“[https://condos.ca](https://condos.ca)")

使用过滤器

运行前面的代码会打开一个新的浏览器并加载网站,帮助您像真实用户一样与网站进行交互。例如,Selenium 不需要手动点击网站来选择过滤器,如卧室数量、房屋类型或提供价格范围,而是通过传递几行命令来轻松完成。该模型使用户能够选择多个过滤器。
例如,要获得 2 间卧室的选项,我使用以下代码单击按钮:

*two_bed = driver.find_element_by_css_selector( ‘insert_css_path’)* *two_bed.click()*

同样,要获得 Gym 的所有结果,我只需使用以下代码:

*Gym = driver.find_element_by_css_selector('insert_css_path')
Gym.click()*

定义一个函数来迭代多个页面

因为我希望能够对其他城市进行这种分析,所以我定义了一个函数,该函数使用参数’ city’ 、’ mode’ 和’ page no’ )创建一个漂亮的 soup 对象。这里,’ mode’ ‘参数接受’ Sale ‘或’ Rent '作为值,使用户能够分析租赁价格!

**def** get_page(city, mode, page):
    url= f'https://condos.ca/{city}/condos-for-{mode}?mode=                 {mode}&page={page}'
    driver.get(url) 
    page_source = driver.page_source
    soup = BeautifulSoup(page_source, 'lxml')
    return soup

该函数利用名为beautiful Soup的模块,为给定的网页返回一个名为 soup 的对象。它还会加载所请求的网页。(稍后我将遍历所有网页来提取所有页面的 soup 对象)

现在我们有了 soup 对象,我们可以提取一些有用的信息,比如清单总数、每页清单总数等。,通过解析网页 HTML。没有听起来那么难!我们使用 soup.find() 来获取相关的标签。一种有用的方法是从提取第一页上的数据开始。如果您能成功做到这一点,rest 只需在所有页面上重复这个过程!

#Defining soup object for page 1
soup = get_page('toronto', 'Sale',1)

从第一页中提取一些关于列表的相关信息。

  • 多伦多的物品总数:
#The total number of Condo Listings in Toronto*soup.find(‘div’,class_ = ‘sc-AxjAm dWkXrE’).find(‘span’,class_ = _5FYo1’).get_text()* *#no. of listings : 3560*
  • 首页上的列表数量:
*len(soup.find_all(‘div’,class_ = ‘_3O0GU’))* *#43*

现在我们对这个有点满意了,我们可以更大胆一点,提取第 1 页上的所有价格。

*prices=[]
for tag in soup.find_all(‘div’,class_ = ‘_2PKdn’):
prices.append(tag.get_text())
prices[:5]*['$450,000',
'$649,900',
'$399,999',
'$599,900',
'$780,000']

为了使事情更简单,我定义了一个名为 condo_container 的变量,它将保存所有相关数据(价格、位置、大小等)。)页面上的所有列表

*condo_container = soup.find_all('div','_3SMhd')*

现在,我们要做的就是从这个 condo_container 中提取价格和其他数据。请参见下面的示例:

#Obtaining Location of all listings on page 1Location_list=[]
for i in range(len(condo_container)):
for tag in condo_container[i].find('span',class_='_1Gfb3'):
Location_list.append(tag)
Location_list[:5]['1001 - 19 Four Winds Dr',
'306 - 2 Aberfoyle Cres',
'911 - 100 Echo Pt',
'524 - 120 Dallimore Circ',
'1121 - 386 Yonge St']

对所有变量重复上述过程,我们得到了构建数据框所需的所有列表(参见下面的示例代码)。由于 HTML 结构的原因,在试图提取浴室、大小和停车场等参数时,这个过程变得有点棘手,但只需一点点努力,就可以完成!(我不是故意分享完整的代码,以避免代码的复制)。

最终数据集

现在我们有了所有的列表,我们简单地将它们添加到一个名为数据的字典中,定义如下。有些标签有点令人困惑,但那是因为它们已经根据需要从字符串类型格式化为整数。

data = {'Prices':[],
'Location':[],
'Date_listed':[],
'Bedrooms':[],
'Bathrooms':[],
'Maint_Fees':[],
'Size':[],
'Parking':[]
}final_list=[]
for page in range(50):
    soup = get_page('toronto', 'Sale',page)
    condo_container = soup.find_all('div','_3SMhd')
    sleep(random())
    print(page) for i in range(len(condo_container)):
    listing = [] price_tag = condo_container[i].find('div',class_= '_2PKdn').get_text()
    formatted_tag = int(price_tag.split('$')[1].replace(',',''))
    data['Prices'].append(formatted_tag) 

    location_tag =    condo_container[i].find('span',class_='_1Gfb3').get_text() data['Location'].append(location_tag) if maint_tag != '':

        Maintenance_Fees = int(maint_tag.split('$')    [1].replace(',',''))
        data['Maint_Fees'].append(Maintenance_Fees)
    else:
        data['Maint_Fees'].append('error') for info_tag in condo_container[i].find('div',class_='_3FIJA'):
            listing.append(info_tag)

        final_list.append(listing)

一旦我们准备好词典,我们就把它转换成 pandas 数据框架,以便进一步处理和 EDA。得到的数据帧有 2031 行。

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

熊猫数据框(图片由作者提供)

快速浏览数据集告诉我们,卧室、浴室、维护费、大小是对象类型变量,因为它们在 HTML 中被存储为字符串类型。

这些变量被清理并转换成整数或浮点类型。此外,我从大小变量创建了一个变量 Avg_Size 。通过进一步的数据检查,我发现了错误值,我用相应列的平均值替换了这些错误值。我还在 Location 变量的基础上设计了一个街道地址变量,以防以后我想执行某种位置分析。数据集被处理为异常值,这扭曲了我的平均值(昂贵的公寓可以变得非常昂贵!).缺失值用各自列中的平均值或最大出现值进行估算。

现在,我们的数据集看起来既漂亮又干净,我们可以继续进行一些基本的探索性分析了!

分析/结果

我很好奇,平均价格和面积是如何随着卧室数量的变化而变化的,我认为这是任何买家首先想到的事情!所以我使用 Plotly 创建了一些情节(见下面的示例代码)。

price_by_bed = condos.groupby(['Bedrooms']['Prices'].mean()data = go.Bar(
    x=price_by_bed.index,
    y=price_by_bed.values,
             )layout = go.Layout(
    title='Average Condo Price',
    xaxis_title="No. of Beds",
    yaxis_title="Value in $M"
                  )
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)

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

病床平均价格(图片由作者提供)

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

按床位划分的平均大小(图片由作者提供)

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

按床位分类的价格和尺寸汇总(图片由作者提供)

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

多伦多每平方英尺的平均价格(Image Src: Condos.ca

每平方英尺的平均价格(仅包括子集中的 1、2 和 3 间卧室)为 897 美元,略高于 827 美元/平方英尺的报价。(注:自 COVID 开始以来,平均价格一直在逐渐下降,因此此处显示的值可能与当前值不同)。

我还可以根据卧室的数量来分析平均维护值。一个有趣的发现是,维修费可以决定你对公寓的投资成败,因为它几乎占你每月抵押贷款价值的 25%!(需要记住的是,不要只关注昂贵的价格)

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

公寓大小的平均维护费用(图片由作者提供)

下面,我按平均面积分析了房源数量,发现大多数待售公寓的面积在 600-699 平方米之间。金融时报类别。

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

按大小排列的列表数量(按作者排列的图片)

这些是我从这次网络抓取练习中得到的一些有趣的见解。我确信,现在有了这些知识,我会成为一个“消息灵通的买家”。

如果你有任何有趣的观点要分享,我很乐意在下面听到你的评论。

感谢 condos.ca 的团队允许我进行这个有趣而有价值的练习!

免责声明 : 请注意,文中表达的观点、想法和意见仅属于作者,不一定属于作者的雇主、组织、委员会或其他团体或个人。这不是投资建议,作者不打算将数据用于任何商业目的,只是出于个人原因。

我如何使用 Python 和 Spotify Web API 构建基于音频的音乐流派预测器

原文:https://towardsdatascience.com/how-i-built-an-audio-based-music-genre-predictor-using-python-and-the-spotify-web-api-a957e427a515?source=collection_archive---------12-----------------------

音乐信息检索(MIR)导论——一个涉及音乐数据分析和分类的跨学科领域

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

阿格巴洛斯Unsplash 上拍摄的照片

你很可能订阅了某种流行音乐流媒体服务。无论是 Spotify 还是 Apple Music,你都可能接触过音乐信息检索的应用程序。想想这个——当使用 Spotify 建立播放列表时,该应用程序会根据您之前添加的歌曲或播放列表标题为您提供歌曲建议。在 Apple Music 中,您会看到根据您之前的收听历史为您量身定制的混音。这里的幕后没有任何魔法。(嗯,也许你,苹果——我们不知道苹果公园的魔法王国里发生了什么)这些例子是由音乐信息检索驱动的流行应用程序。

音乐信息检索是分析和分类音乐数据的科学MIR 的一些应用与数据科学领域密切相关,同时还结合了心理声学、信号处理、机器学习和计算智能等多个领域。

在本文中,我将给出 MIR 的一个应用的高级演示:体裁预测。这个项目由 Python 构建,包含两个分类器模型,可以预测歌曲的风格。这两个模型都暴露于从一堆歌曲中收集的各种数据点。第一个模型根据歌词预测歌曲的风格。第二个模型根据歌曲的音频属性或声音来预测歌曲的风格。我们将专注于第二个基于音频的模型,但是可以随时在 GitHub 上查看整个项目!让我们开始吧。

我对音乐的热爱和我接触过的 MIR 的许多应用极大地激发了我在这里的工作。我一直在寻找新的音乐,由于 Spotify 和 Apple Music 的推荐,我已经发现了大量的艺术家。

1.收集数据

为了开始构建一个分类器,我们需要数据——以及大量的数据。对于分类者来说,不仅仅是更好的教他们如何钓鱼;这是要求的。我们需要向他们提供大量的数据,以便他们做出准确的类别标签分配。

我们的分类器将根据歌曲的声音进行预测。幸运的是,Spotify 有一个特别有用的 web API ,我们可以利用它来获取我们需要的数据。在这个项目中,我们将使用 Spotipy Python 库访问 Spotify 的歌曲数据。这个轻量级 Python 库支持 Spotify 的 Web API 的所有特性。通过使用 Spotipy,我们可以检索任何给定歌曲的各种数据点,如下所示。

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

给定曲目、艺术家和流派,使用 Spotipy 收集数据

在预测一首歌曲的风格时,我们可以考虑相当多的数据点。只要看看上面提供的例子,我们就可以知道 Empire Cast 的嘻哈歌曲比它上面的两首朋克/金属歌曲具有更高的可跳舞度。语音的清晰度也更高,这并不奇怪。朋克/金属歌曲的歌词经常在嘈杂的乐器上尖叫或呼喊,使它们更难理解,而嘻哈歌曲包含的歌词与节奏乐器一起演唱或说唱,几乎不会碍事。

为了获得足够数量的歌曲数据,我首先从 Kaggle 和 Ranker 导入了两个数据集。两个数据集都包含成千上万首歌曲,以及它们相关的流派。为了获得这些歌曲的音频属性,我创建了一个函数,该函数贯穿这两个数据集,在每首歌曲处停下来搜索歌曲的音频属性。感谢 Spotipy,我能够获得大量数据来训练这些模型。

2.探索性数据分析

如上面的例子所示,我们能够对收集到的一些歌曲有一个小小的了解。**然而,上面显示的歌曲甚至连整个数据集中歌曲数量的百分之一都不到,所以我们还不能做任何假设。**为了对每种风格的音频属性得出结论,我们必须进行探索性数据分析,或 EDA。

EDAs 允许我们总结一个数据集的主要特征。**这是一个允许数据科学家熟悉他们的数据的过程,收集关于正在实验的数据的本质的关键理解。**它也用于检查数据的质量;我们的实验是否会产生任何有意义的结果。

从我的 EDA 开始,我首先将歌曲按流派分组,然后找到每个音频属性的数字平均值。接下来,我对数据集的属性进行了规范化,以便更好地理解每种风格的音频特征之间的差异。我使用了一个差异阈值函数来找出每种风格的音频属性之间的差异,然后将差异列在一行中,显示在数据帧的底部。添加之后,我按照方差对列进行了降序排序。我最终得到了一个数据框架,它显示了每种风格的平均音频属性,以及不同风格之间哪些属性有最多的相似性和差异性。

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

各列按差异(底行)排序,或者按各种类型之间每个属性的差异程度排序

根据上面显示的数据框架判断,我们现在可以对数据集做出一些关键假设。乐器、声音和语速在每种风格之间的差异最大,而拍号、基调和速度的差异最小。直观地说,这是有意义的,尤其是当我们考虑本文第一节中的例子时。朋克/金属具有非常高的乐器性,因为通常存在尖叫的吉他、重低音、误解的歌词和雷鸣般的鼓声。由于通常存在电子节拍和合成低音,嘻哈音乐的乐器性很低。乡村/民间/摇滚介于两者之间。

还有哪些方法可以将你的音乐直觉运用到上面显示的结果中?

3.构建分类器

一个决策树,机器学习领域的流行工具,利用其树状结构来做决策。

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

照片由 Stephen Milborrow 在维基百科上“一棵树显示了 泰坦尼克号 上乘客的存活数(“sibsp”是船上配偶或兄弟姐妹的数量)。叶子下面的数字显示了存活的概率和叶子中观察到的百分比。总结:如果你是(1)女性或(2)小于 9.5 岁且兄弟姐妹少于 2.5 个的男性,你存活的机会很大。

上图是在决策树学习维基百科文章上找到的图片。这个树参考了电影《泰坦尼克号》,给我们一个直观的例子来说明决策树是如何工作的。

**基于音频的分类器将通过做出由每片树叶确定的预测来利用决策树。例如,一片树叶可能会有这样的陈述“声音度>是 0.5 吗?”**然后它将决定所讨论的歌曲是被预测为嘻哈歌曲还是朋克/金属歌曲。现在,我们数据集中的歌曲肯定比泰坦尼克号上的人有更多的属性,所以我们的树看起来会比上面列出的树复杂得多。上面,我们看到决策树只考虑了三个属性。我们的歌有 12 个属性。**这些属性是决策树进行预测的基础,**因此,这棵树变得更大是有道理的——更不用说我们将向它输入大量的歌曲。

我选择使用 scikit-learn 的 Python 工具——特别是训练-测试-分割函数决策树分类器。构建分类器时,我们必须采取的第一步叫做拟合分类器。我们可以认为拟合是将分类器暴露给数据,并告诉它属于哪个分类。

这和学习的想法很相似。当你为考试而学习时,你会接触到很多信息,到了考试的时候你必须记住这些信息。这里的关键 (这一点很重要) 是在考试上,你会看到你必须解决的问题,而这些问题是你从未见过的——但这些问题与你考试前所学的问题有相似之处。利用你所知道的你所研究的问题,你尽你所能解决这些测试问题,希望你最终能取得一个好的考试成绩。

当适合决策树分类器时,其决策树叶子由它所暴露的数据生成。拟合后,我们可以通过将分类器暴露于它从未见过的数据来测试它,希望它能做出准确的预测。

我通过将整个数据集分成 70%的训练数据30%的测试数据来构建决策树分类器。我还决定不考虑两个音频属性,因为流派之间的差异太小了。在研究了如何避免过度拟合之后,我做出了这些决定。

在拟合之前,我使用了一种叫做 打包 的方法来进一步优化分类器。Bagging 本质上是获取你的初始分类器,创建一堆它的副本,然后在原始数据集的随机子集上训练它们。在训练之后取它们的所有平均值,产生一个单一的平均分类器。 Bagging 在分类器的构造中引入了随机化,使其成为改进单个复杂树分类器的一种很好的方式。

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

最终的决策树

4.结果

现在来最后拟合和测试分类器。我们运行一个简单的评分函数,看看分类器在面对以前从未见过的数据时表现如何。

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

分类器得分约为 79%

不错——分数略低于 80%。让我们喂它一些歌曲,看看它的行动;保罗麦卡特尼,德雷克和冠军争夺战的歌曲。

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

预测是正确的!

三个预测都是正确的!科学,宝贝

结论

数据科学是一个巨大的领域。这也是我如此热爱它的原因之一。它让我能够将我的计算机科学技能与我对音乐的热情结合起来,MIR field 为我提供了一个完美的游乐场,让我在获得音乐洞察力的同时进一步发展我的技能。

GitHub 项目链接

我如何从优步旅行时间数据中构建时间序列数据

原文:https://towardsdatascience.com/how-i-built-time-series-data-out-of-cross-sectional-uber-travel-times-data-e0de5013ace2?source=collection_archive---------44-----------------------

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

我知道我在写学士论文的过程中想做两件事:提高我的编程技能和从事时间序列数据预测工作。

然而,我不知道的是我想学的东西。然而,它必须是我真正喜欢的东西,不一定与我的专业相关。

由于我喜欢地图和……移动的东西,我决定以某种方式使用我最近偶然发现并爱上的一个网站的数据(可能是在我十几岁时玩了几个小时的模拟城市之后)——优步运动网站。

它允许您可视化从某个点(或区域)到同一城市中任何其他点的平均行驶时间的匿名数据。

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

我的家乡圣保罗的旅行时间示例。

“太好了!”,我想。“让我下载旅行时间并绘制一些数字,这样我就可以继续进行探索性数据分析(EDA)。”

事实证明,我想要的数据不是那么容易提取的。

问题是

为了有一个更精确的统计结果,我需要我能得到的所有数据。我拥有的数据行越多,我的模型的预测能力就越强(潜在的)。时间增量越小越好。因此,我需要得到日报的旅行时间。

优步运动网站允许你从城市的任何一个区域下载数据到其他区域。然而,有一个问题。无论您想获取哪个日期范围的旅行时间,都不是由每天的数据组成的。

也就是说,如果您选择下载 2020 年 1 月至 2020 年 3 月的值,您将不会收到 90 个值,这大致是该范围内的天数。相反,它会生成一个 csv 文件,其中的是每对区域的三个月平均旅行时间的单个值

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

您可以为每个给定的区域对下载不同格式的行驶时间数据。

这意味着我必须在整个时间内的数据点数量上做出妥协,以获得单个时间点的大量值。

TL;博士:优步运动不提供时间序列数据,但单电子/横截面数据。

当然,还有其他限制因素,例如,我只能获得我称之为“径向”的数据,而不能获得每个可能的区域对之间的行驶时间,只能获得从最中心点到其他点的行驶时间。从统计学的角度来说,我不确定这是否能为我提供一个给定城市的平均出行时间的合理准确的测量值。

以下是您可以下载的两种地理空间数据的(非常难看的)描述:

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

“径向”数据与每对区域。

尽管如此,还是有希望的。

我解决这个问题的天真尝试

可以选择的最大可能日期范围是 3 个月。另一方面,最短的时间是一天,这正是我所需要的。

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

优步运动日历,您可以在其中选择所需的日期范围。

所以我想:“为什么不点击每一天并下载相应的数据集呢?”。

嗯…我试过了。

我知道自动化这个过程会容易得多,但是我没有编码技能,也不知道我需要用什么包来完成这个任务。

我花了大约 6 分 30 秒下载一个月的数据。在可用的城市中,数据天数最多的是 3.25 年(2016 年 1 月至 2020 年 3 月)或 39 个月。我总共要花 253 分钟,或者连续点击 4 个多小时,才能下载一个城市的所有数据集。总之,我想从 31 个城市提取数据,所以 4 小时乘以 31 个城市大约等于手动下载 5 天。

那就是不吃不睡。

是时候解决房间里的大象了。因为我不想花几乎整整一周的时间点击下载按钮,所以我自动完成这项工作。

解决方案

我实际上使用了两个 Python 包来自动下载每日数据集:Selenium,用于自动执行操作(比如单击和等待页面响应); datetime,使用精确的数据类型来读取日期和时间,而不仅仅是使用字符串。

代码的很大一部分是由 XPaths 和 CSS 选择器对变量的简单赋值以及对这些变量执行的点击操作组成的。对我来说,这本身就是一次学习练习,因为我从未使用过谷歌 Chrome 开发者工具。

酷,我刚学会自动点击。然后,我有了点击日历上每一天的想法。很简单。

然而,我现在面临着一个巨大的障碍。

为了遍历日期,我必须从下载按钮所在的页面返回到带有日历的窗口(这样我就可以点击下一个日期)。为此,我必须刷新页面。当您刷新页面时,DOM(文档对象模型)也会更新。

也就是说,引用特定 web 元素的任何代码都不能在刷新后的页面上工作,因为 web 元素已经过时了。

例如,Selenium 会给我以下错误消息:

selenium.common.exceptions.StaleElementReferenceException: Message: <element_name>'stale element reference: element is not attached to the page document

这是一场噩梦,也是一个我无法克服的挑战,不管我读了多少 StackOverflow 的帖子。绝望随之而来。

因此,我联系了一位我认识的有 CSS 和 Java 经验的前同事,看他是否能帮助我。虽然我的希望很低,但他提出了一个简单而优雅的想法:“为什么不点击日期并刷新页面,而是更新 URL 本身以包含您想要的日期?”

这是我的项目的一个转折点。(瓦雷乌·爱德华多!).

如果你仔细查看某个城市的优步运动网址,你会注意到它包含了你想要登陆的页面所需的所有信息。

我只需创建一个初始 URL,其中包含城市名称、所需的区域类型和区域原始代码等信息,然后找出一种算法来遍历日期并相应地更新 URL。

URL 创建函数如下:

*# Create URLs for the desired date range* **def** getURL():
    *""""*
 *Function that creates one URL per date between the specified    date range*
 *"""*
    date = datetime(2016,2,2)
    **while** date <= datetime(2020,3,31):
        **yield** ('https://movement.uber.com/explore/' + city + '/travel-times/query?si' + origin_code + '&ti=&ag=' + zone_type + '&dt[tpb]=ALL_DAY&dt[wd;]=1,2,3,4,5,6,7&dt[dr][sd]=' +
               date.strftime('%Y-%m-**%d**') + '&dt[dr][ed]=' + date.strftime('%Y-%m-**%d**') + '&cd=&sa;=&sdn=' + coordinates + '&lang=en-US')
        date += timedelta(days=1)

最后,我们只需要创建一个迭代机制来执行 getURL 函数中的下一个 URL。

*# Perform iteration through URLs downloading the datasets for each URL*
iterated_URLs = []
i = 0
print('Number of generated URLs: ' + str(len(list(getURL()))))
**for** url **in** getURL():
    i += 1
    driver.execute_script("window.open('"+url+"', '_self')")
    iterated_URLs.append(url)

这是运行中的机器人:

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

数据集下载机器人在行动。

就是这样!

接下来的步骤是将每个 csv 文件连接成一个文件,并执行清理和格式化以启动 EDA 这对熊猫来说很容易做到。

有了这个,任何人都可以充分利用优步免费提供给我们的惊人数据。由于网站上提供的数据结构的性质,时间序列分析是不可能的,现在我们可以扩大对优步旅行时间和地理空间数据的研究范围。

当然,这两段代码并不是故事的全部,所以你可以在 GitHub 上查看我的这个和其他项目。

我如何将 S3 桶连接到 Databricks 笔记本进行分析。

原文:https://towardsdatascience.com/how-i-connect-an-s3-bucket-to-a-databricks-notebook-to-do-analytics-a7b5258619b8?source=collection_archive---------19-----------------------

连接亚马逊 S3 和 databricks 笔记本的基本用例。

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

在一个项目中,我必须对来自 Kinesis 流并由消防软管排序的数据流进行一些分析,这项技术允许我们简单地将来自流的数据存储在 S3 中。

要做这些分析,你首先必须从 kinesis 笔记本连接到 S3 桶,然后使用 SPARK 对其进行查询以分发计算。

在这个用例中,我们将使用 databricks 的社区版,它的优点是完全免费。

添加新的 AWS 用户

为了能够从我们的 S3 存储桶中读取数据,我们必须提供从 AWS 的访问权限,为此我们需要添加一个新的 AWS 用户:

我们首先转到 AWS IAM 服务->用户->添加用户

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

我们输入用户名和访问类型。然后,我们授予该用户访问 S3 的权限。

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

您可以跳过接下来的步骤,直接进入用户验证。

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

我们点击“查看”并保存这些密钥以备后用。
现在已经创建了用户,我们可以从 Databricks 转到连接。

配置您的数据块笔记本

现在我们的用户已经可以访问 S3,我们可以在 databricks 中启动这个连接。
如果你的账户刚刚创建,你就必须创建一个新的集群来运行你的笔记本。转到集群选项卡- >创建集群

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

给它一个你想要的名字和一个最新的稳定运行版本。对于本教程,我将使用 Scala 来处理数据。然后点击“创建集群”

现在,您必须创建一个笔记本来运行您的代码。为此,进入工作区->“用户名”->“创建”

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

同样,给它起你想要的名字,选择 Scala 作为语言,然后选择你刚刚创建的集群。你准备好做云编码了吗,这很简单,不是吗?

从数据块中连接和检索 S3 数据

关系

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

要将您刚刚创建的笔记本连接到您的 AWS S3 桶,您只需将您的访问和密钥替换为您之前创建用户时保存的密钥,记得吗?
您还必须将“AwsBucketName”属性替换为您的 S3 时段名称。
挂载名称正好对应于包含 S3 数据的变量的本地名称。你可以选择你想要的名字。

检索数据

要从 S3 存储桶中检索数据,请使用以下代码。

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

这里只是要注意路径。注意 S3 的存储结构,以便只检索您感兴趣的数据。

现在只需使用这行代码将您的数据转换成一个漂亮的数据集。

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

现在,我们准备好发出请求并可视化我们的数据集。准备好了吗?

使用 SPARK 实现数据帧的可视化

为了可视化你的数据框架,你只需要在上面提出请求。

这是一个如何使用 SPARK 在数据帧上进行请求的例子

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

  • filter 方法用于选择您感兴趣的数据集部分。
  • groupBy 用于根据数据框中的分类列对您刚刚选择的数据进行分组。你必须在它之后使用一个聚合函数,比如计数
  • 最后一种方法,过滤器,顾名思义,允许您根据数据帧中的一列对数据进行排序。

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

您将获得一个包含已处理数据的表,作为该请求的输出。

为了形象化,你只需点击底部的绘图按钮,选择你想要的绘图类型。

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

你可以从 databricks 中找到一些关于数据帧用法和关于可视化的有趣文档。

一旦你有了一组精彩的情节,你就可以用它来创建一个仪表板。
只需点击 View - > new Dashboard,选择您想要的图表……瞧,您就拥有了一个出色的 Databricks 仪表板。

这看起来可能是这样的:

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

有时很难找到使用这些新的大数据工具的方法。
在本文中,我们一起看了一个详细的用例,如何连接到 S3 桶,并在数据块上创建强大的可视化。
我希望这篇文章能够启发您,并激发您在大数据项目中的创造力。

我如何不断地将我的机器学习模型的准确率从 80%提高到 90%以上

原文:https://towardsdatascience.com/how-i-consistently-improve-my-machine-learning-models-from-80-to-over-90-accuracy-6097063e1c9a?source=collection_archive---------9-----------------------

改进机器学习模型的 5 个技巧和提示

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

里卡多·阿尔塞在 Unsplash 上的照片

介绍

如果你已经完成了一些自己的数据科学项目,你现在可能已经意识到达到 80%的准确率并不算太坏!但在现实世界中,80%是不会切的。事实上,我工作过的大多数公司都期望至少 90%的准确率(或者他们所关注的任何指标)。

因此,我要谈谈你可以做的 5 件事来显著提高你的准确性。我强烈建议你通读这五点内容,因为我包含了很多大多数初学者不知道的细节。

到此结束时,你应该明白,有比你想象的更多的变量在决定你的机器学习模型的表现方面发挥着作用。

也就是说,你可以做 5 件事来改进你的机器学习模型!

1.处理缺失值

我看到的最大错误之一是人们如何处理缺失的价值观,这不一定是他们的错。网络上的许多资料表明,您通常通过**均值插补、**用给定特征的均值替换空值来处理缺失值,这通常不是最佳方法。

例如,假设我们有一个显示年龄和健康分数的表格,并假设一个 80 岁的老人缺少健康分数。如果我们从 15 岁到 80 岁的年龄范围内取平均健康分数,那么 80 岁的人看起来会有一个比他实际应该有的高得多的健康分数。

因此,你要问自己的第一个问题是为什么数据一开始就丢失了。

接下来,考虑处理缺失数据的其他方法,除了均值/中值插补:

  • 特征预测建模:回到我关于年龄和健康分数的例子,我们可以对年龄和健康分数之间的关系建模,然后使用该模型找到给定年龄的预期健康分数。这可以通过几种技术来完成,包括回归、方差分析等。
  • K 最近邻插补:使用 KNN 插补,缺失的数据用另一个相似样本的值填充,对于不知道的人,使用距离函数(即欧几里德距离)确定 KNN 的相似性。
  • 删除行:最后,可以删除行。这通常不被推荐,但是当你有一个巨大的数据量时,这是可以接受的。

2.特征工程

第二种可以显著改善机器学习模型的方法是通过特征工程。特征工程是将原始数据转化为更好地代表人们试图解决的潜在问题的特征的过程。这一步没有特定的方法,这使得数据科学既是一门科学,也是一门艺术。话虽如此,以下是一些你可以考虑的事情:

  • 转换日期时间变量以仅提取星期几、月份等…
  • 为变量创建容器或桶。(例如,对于高度变量,可以有 100-149 厘米、150-199 厘米、200-249 厘米等。)
  • 组合多个要素和/或值以创建一个新要素和/或值。例如,泰坦尼克号挑战最准确的模型之一设计了一个新的变量,称为“是女人还是孩子”,如果这个人是女人或孩子,这个变量为真,否则为假。

3.特征选择

第三个可以大幅提高模型精度的领域是要素选择,即选择数据集最相关/最有价值的要素。过多的特征会导致算法过拟合,过少的特征会导致算法欠拟合。

我喜欢使用两种主要方法来帮助您选择功能:

  • **特性重要性:**像 random forests 或 XGBoost 这样的算法允许您确定哪些特性在预测目标变量的值时是最“重要”的。通过快速创建其中一个模型并进行特征重要性分析,您将了解哪些变量比其他变量更有用。
  • 降维:最常见的降维技术之一,主成分分析(PCA)取大量特征,利用线性代数将其降维为较少的特征。

4.集成学习算法

改善你的机器学习模型的一个最简单的方法就是简单地选择一个更好的机器学习算法。如果你还不知道什么是集成学习算法,现在是时候学习它了!

集成学习是一种结合使用多种学习算法的方法。这样做的目的是让您获得比单独使用单个算法更高的预测性能。

流行的集成学习算法包括随机森林、XGBoost、梯度增强和 AdaBoost。为了解释为什么集成学习算法如此强大,我将给出一个随机森林的例子:

随机森林涉及使用原始数据的自举数据集创建多个决策树。然后,该模型选择每个决策树的所有预测的模式(大多数)。这有什么意义?依靠“多数获胜”模型,它降低了单个树出错的风险。

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

例如,如果我们创建一个决策树,第三个,它会预测 0。但是如果我们依赖所有 4 个决策树的模式,预测值将是 1。这就是集成学习的力量!

5.调整超参数

最后,有一点很少被提及,但仍然非常重要,那就是调整模型的超参数。这是你清楚地理解你正在使用的 ML 模型的必要条件,否则很难理解每个超参数是什么。

看看随机森林的所有超参数:

*class* sklearn.ensemble.**RandomForestClassifier**(*n_estimators=100*, ***, *criterion='gini'*, *max_depth=None*, *min_samples_split=2*, *min_samples_leaf=1*, *min_weight_fraction_leaf=0.0*, *max_features='auto'*, *max_leaf_nodes=None*, *min_impurity_decrease=0.0*, *min_impurity_split=None*, *bootstrap=True*, *oob_score=False*, *n_jobs=None*, *random_state=None*, *verbose=0*, *warm_start=False*, *class_weight=None*, *ccp_alpha=0.0*, *max_samples=None*

例如,了解 min _ infinity _ decrease 是什么可能是一个好主意,以便当您希望您的机器学习模型更加宽容时,您可以调整该参数!;)

感谢阅读!

通过阅读本文,您现在应该对如何将模型的准确性从 80%提高到 90%以上有了更多的想法。这些信息还将使您未来的数据科学项目进行得更加顺利。我祝你在数据科学的努力中好运。

特伦斯·申

我是如何在脸书大学通过 MLE 面试的

原文:https://towardsdatascience.com/how-i-cracked-my-mle-interview-at-facebook-fe55726f0096?source=collection_archive---------0-----------------------

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

蒂姆·班尼特在 Unsplash 上拍摄的照片

办公时间

我成为 MLE 的旅程

那是去年八月,我正在接受采访。到那个时候,我已经分别面试了谷歌印度和亚马逊印度的机器学习和数据科学职位。然后我的学长建议我申请脸书伦敦的一个角色。

于是我照做了。我在 LinkedIn 上联系了一位招聘人员,他给我介绍了另一位,几天后我就开始了机器学习工程师的招聘过程。

现在,在雇佣机器学习工程师方面,脸书有一个非常不同的流程。他们通过编码、系统设计和机器学习设计面试来选择未来的员工。就我作为数据科学家的经历而言,我对机器学习设计面试相当满意,但其他面试仍然让我感到害怕。我最近没有通过谷歌机器学习软件工程师的第一轮面试,仅仅是因为我没有准备好数据结构的问题。

后来,当我为 FB 编码面试学习时,我意识到我把它看得有点轻,我根本没有为编码面试做准备。

在这篇文章中,我将概述我对所有这些不同面试的方法,以及对于那些对 FB 这样的大机构的 MLE 职位感兴趣的人来说,整个过程是如何进行的。

所以,一旦我和招聘人员联系上了,下一步就是电话面试。

1.电话采访:

这是一次非常基本的数据结构面试,也是一次基本的健康检查。我猜 FB 只是想给你更多的时间来准备接下来的几轮,并看看是否值得打电话给你进行现场查房。对我来说,这次视频电话采访持续了 45 分钟。面试官一开始告诉我他在脸书的简介,然后在开始的 10 分钟左右问我的简介。

然后,我有两个非常基本的数组和基于字典的问题要解决。采访者分享了一个 coderpad 链接,在这个链接上,我必须在没有任何代码格式选项的情况下,用我选择的任何语言(不是伪代码)无错误地解决这些问题。我也被问及这些问题的基于时间和基于空间的限制。面试的进展是我得出了一个像 O(n)这样糟糕的运行时间,面试官问我是否可以做得更好,并在需要的时候给出提示。

由于我不允许分享确切的问题,我只会分享一些难度相当但不相同的公共 Leetcode 问题给你,以便你可以了解难度水平并相应地练习。

a) 单调数组:一个数组是单调的,如果它或者是单调递增的,或者是单调递减的。当且仅当给定数组A单调时,返回true

b) 有效回文:给定一个字符串,判断它是否是回文,只考虑字母数字字符,忽略大小写。

我这次面试的行动计划?

这只是我参加的第二次数据结构面试,在第一次表现不佳后,我想做一点准备。因此,我开始使用 Gayle Laakmann McDowell 的《破解编码访谈》一书来理解数据结构的基础知识。这本书也包含了很多准备技巧,你应该谨慎地去阅读它们。我最喜欢这本书的一点是,它非常简洁,不像托马斯·科尔曼的《算法导论》,它只是给出了编码采访的适量背景。每一个数据结构都用 2-3 页的篇幅进行了非常简明的解释,一些问题是围绕特定主题解决的,然后给出了一些练习题。这本书还限制了自己,只提供最常被问到的数据结构。例如,AVL 树和红黑树被放在高级部分,而不是在树和图表章节,因为它们在有时间限制的面试环境中不常被问到。

我首先列出了我需要准备的主题清单。你可以准备更多的话题,但这些是面试的最低要求。

**数据结构:**数组、集合、栈/队列、Hashmap/字典、树/二叉树、堆、图。

**算法:**分治、DP/记忆化、递归、二分搜索法、BFS/DFS、树遍历。

然后我继续用《破解编码访谈录》阅读他们,并为他们解决了许多 Leetcode 上的简单问题和一些中级问题。也有其他平台可以在线练习,但我喜欢 Leetcode,因为它没有广告的良好设计和基于类的解决方案编程结构。它还提供了一个很好的方法来搜索各种主题和难度的问题。我还在 Leetcode 上做了很多模拟采访,只是为了练习。我这样做了大约一两个星期,每天花大约 3-4 个小时。

在这段时间里,我还开始审核 UCSanDiego 在 Coursera 上的 算法专业,这让我对本科大学教授什么内容来应对编码面试有了一些想法。

我也围绕我所学到的东西写了一些博文,试图简单的解释一下。你可以在我的博客上免费查看。

TLDR; 只要把你要准备的题目记下来,每个题目练很多容易的题就行了。也许还有一些中等的。

有一次,我完成了电话面试,招聘人员在短短的一天内回来了,并打电话解释了现场面试的过程。 现场参观将在伦敦进行,我真的很期待去伦敦旅行。免费旅行。大约还有 5 个回合,这是我接下来要说的。我两个月后就要去面试了,这样我就有时间准备了。不管怎样,签证和整个过程花费的时间比这多一点。

一到伦敦,我就在 D 日 9 点左右从他们提供的酒店到达了脸书办事处。比预定时间提前了整整一个小时,因为我很紧张,我通常会尽量准时/提前到达面试地点(当我给他们面试机会时更是如此)。我事先知道当天的整个行程,因为我的招聘人员告诉了我。我也知道哪个采访将在什么时间进行,谁将接受采访。事实上,这是我经历过的最有条理的面试。

2.现场编码第 1 轮

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

图片由 StartupStockPhotos 来自 Pixabay

我从事数据科学已经很久了,所以我把 DS 作为数据科学而不是数据结构来读。这次采访对我来说是一个痛点。这是我在两个月内学到的东西,而不是我的全部经历。在这里,我是基于这一点而不是我所有的经验和数据科学背景进行评估的。但正如招聘人员告诉我的那样,他们有非常固定的流程,我不得不通过这些轮次来获得 MLE 职位。所以我就配合了。

至于面试,它准时开始,像以前一样,面试官在进入我的个人资料之前做了自我介绍,然后直接进入面试问题。有人问我一个中等水平的字符串问题,我能很快解决,还有一个中等水平的二分搜索法问题,花了我大部分时间,但最终我还是解决了。Leetcode 中的一些类似问题(不是相同的问题):

a) 复数乘法:给定代表两个复数的两个字符串。您需要返回一个表示它们相乘的字符串

b) 排序矩阵中的第 k 个最小元素:给定一个 n x n 矩阵,其中每一行和每一列都按升序排序,找出矩阵中的第 k 个最小元素。

面试官还给了我一个在自己的笔记本电脑上编码的选项,因为招聘人员已经告诉了我在白板/笔记本电脑上编码的选项,所以我特意带着笔记本电脑。但是记住他们不允许使用任何代码格式和 ide。我只有一个基本的编辑器来写代码。

我的编码面试行动计划?

和电话一样的计划,但是更广泛的远程编码。我记得我连续 30 天都在做 Leetcode,每天大约 3-4 个小时。我过去常常尽可能多地解决中等水平的问题,而很少花时间解决高水平的问题。

3。第二轮现场编码:

直到这个时候,我还处于数据结构的最佳状态,并准备好应对面试官抛给我的任何问题。我的心态是——“最坏的情况会是什么?”。所以我只是继续。脸书的人真的很好,他们在每次采访前后都要求提供茶点,并注意不要延长采访时间。很多人认为,每次面试都在需要的时间准时开始,两次面试之间有 15 分钟的冷静期。

同样,一些类似的(不是相同的)问题很难练习,并附有 Leetcode 的简要描述:

a) 基于 API 的问题基于时间的键值存储:创建一个键值存储类,支持两个操作——set 和 get。

b) 合并 k 排序列表:给你一个k链表lists的数组,每个链表按升序排序。将所有链表合并成一个排序后的链表并返回。

我在这次编码面试中的目标是能够在 40 分钟内解决面试官提出的两个问题。但是,这是一个困难的面试,我花了大部分时间在第二个问题上,这是一个困难的水平。尽管面试官给了我一些提示,引导我找到正确的数据结构和算法。最后,我完全解决了问题 1 和问题 2 的大部分问题。

给受访者的一个建议是,说出你所有的解决方案以及所涉及的时间复杂性,只有当你们双方都同意一个好的解决方案时,才开始编写代码。

此外,通过这两次面试,我发现在工作中与面试官交谈并解释你的方法真的很有帮助。他们有时会提供提示,有时会阻止你走向错误的切线。甚至告诉你的面试官你陷入了什么困境也会对你有所帮助,因为这会给面试官一个信号,告诉他你在往哪个方向思考。这也使得整个面试更具协作性,我认为这是面试官在一个人身上寻找的品质之一。

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

FB 的食物棒极了。尽管如此,我还是不能享受太多,因为我有点焦虑。照片由丹金Unsplash 上拍摄

到目前为止,我对所有的白板编码和一般的面试压力感到有些疲惫,因为快到午饭时间了,我和一个指定的同事/朋友去了脸书自助餐厅。这是你可以询问公司情况的部分,这段时间不在面试之列,所以你可以开诚布公地问一些关于脸书人寿的问题。在脸书自助餐厅,你可以品尝到各种各样的食物。

4.系统设计

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

照片由杰斯温·托马斯Unsplash 上拍摄

这又是一次我害怕的面试。正如你所看到的,我害怕大部分的面试,因为这对我来说是非常不自然的面试形式。在系统设计面试中,您需要在白板上创建一个端到端的服务。供您练习的一些示例问题如下:

  • 你会如何设计网飞?
  • 你会如何设计 Youtube?
  • 你会如何设计推特/脸书?

虽然这看起来令人生畏,但当你为此做准备时,它实际上是开放的。因为没有错误的答案。

我喜欢这样的面试方式是:

  1. 设计一个非常基本的系统,类似于平台,具有面试官要求的基本功能。对于大多数平台来说,它包括在白板上绘制服务器、客户机和数据库的方框。
  2. 创建我希望系统具备的功能列表。例如,在社交网络中关注,或在优步上预订出租车,或在 Whatsapp 上阅读消息时双击,或 Twitter 上的转发功能,或 FB newsfeed 等。谈到功能,天空是无限的,因为我们都已经看到了这些平台提供的功能,所以列出一个功能列表应该不难。
  3. 在整个面试过程中增加特色,在非常基础的设计上扩展/改变。这可能涉及添加功能,以及讨论缩放、处理边缘情况、讨论涉及的数据结构和数据库、使用缓存等。
  4. 继续添加功能并通过询问面试官他们希望根据我提供的功能列表添加什么功能来进化系统,直到最后。

我的系统设计面试行动计划?

网上有很多很好的资源可以为这次采访做准备,但我想提两个我觉得非常有用的资源:

  • 多恩·马丁的《系统设计初级读本》:这是任何准备系统设计的人都应该至少看一遍但老实说要看很多遍的资料。这里要学习的最重要的主题是性能、可扩展性、延迟、吞吐量、可用性、一致性、cdn、数据库、缓存、负载平衡等。
  • Youtube 上关于最受欢迎的服务的各种系统设计的视频:我说的是大的——网飞/Youtube/WhatsApp/脸书/Gmail/亚马逊等。你可以在 youtube 上找到很多关于所有这些服务的系统设计的视频。我绝对想喊出来的一个 YouTuber 是 Techdummies ,我在所有这些大平台上都看过他们的视频。至少对我来说,他用最简单的方式解释了概念。

我花了一周的时间来来回回地从观看视频跳到阅读多恩·马丁的知识库,为这次采访做准备,我认为这是正确的方式。此外,理解许多工程师使用的术语也很有趣,所以这也是一次很好的学习经历。

最后,在这次面试中最重要的是,你需要用面试官最少的投入来推动讨论。 有时面试官可能会要求你提供一个特定的功能,你应该实现它,但最终,这是你的系统,你需要以最符合逻辑的方式创建和添加你想要的功能,才能在这一轮中取得成功。

5.行为的

这次面试试图考察你是如何处理困难局面的。而且,你可以通过吸收和组织你过去所有的工作经验,你所面临的问题和你设计的解决方案来准备这次面试。你需要收集所有你解决了一个不可能的情况或者没能解决的例子。

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

米歇尔·邦克斯基在 Unsplash 上的照片

综上所述,掌控面试的最佳方式就是做你自己!

对我来说,这次面试就像是和面试官的一次讨论。他首先介绍了自己和他在 FB 所做的工作。然后他问了我正在做的项目,我们就项目的 ML 部分进行了一个小讨论。然后是一个非常正常的讨论,关于我会如何解决/处理类似“你在职业生涯中犯过什么不值得骄傲的错误?”(这不是我被问到的确切问题)。如果你在准备这次面试的时候能回忆起所有好的和不好的经历,并构思一些小故事,这将会很有帮助。但是最重要的一点还是要诚实,并且是对诸如“你和你的同事有过分歧吗?”这样的问题的一个完全正常的回答如果你没有异议,那就没有。对你的回答要非常诚实,因为这些行为轮的面试官很容易看穿一个说谎的人。

我认为,对我来说,这次面试进行得很顺利。

6.ML 系统设计

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

来源:脸书 ML 视频系列

这是一次发挥了我优势的面试,老实说,我并没有为此做太多准备。在这次面试中,我被期望创建一个系统来端到端地解决一个 ML 问题。

在这次面试中,面试官只是在评估你将商业问题转化为机器学习系统的能力。因此,你可能会得到一个问题陈述,比如开发一个系统来使用机器学习创建新闻提要,或者创建一个系统来过滤有害的评论,或者诚实地说,任何机器学习系统。

然后,您需要设计一个端到端的系统,同时讨论数据和数据收集的各个方面、EDA、功能工程、模型评估、模型测试、将模型投入生产以及最后的维护和反馈。

准备这次面试的一个很好的资源来自脸书本身:介绍机器学习视频系列脸书现场指南,这是我为这次面试做的唯一准备。

那是一天!

这是多么美好的一天。采访结束后,我去了伦敦和特拉法尔加广场,看人们表演各种各样的把戏和滑稽动作。然后步行回我的酒店。

总之,这是一次很好的面试经历,我没想到会对我有好处。数据结构是我从未申请大公司 ML 职位的主要原因,但当我读到它们时,我发现它们非常可行,而且如果你能花些时间,你可以学到一些东西。

因此,一年后,我加入了脸书伦敦公司,担任软件工程师(MLE ),由于 COVID 相关原因,我的加入期延长了。希望这次经历顺利。

继续学习

如果你想以更结构化的方式阅读更多关于算法和数据结构的内容,这里有一个由 UCSanDiego 在 Coursera 上提供的 算法专门化。 我在准备的时候旁听了这门课。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。关注我在 媒体 或订阅我的 博客 了解他们**。**

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

[## 通过我的推荐链接加入 Medium-Rahul Agarwal

作为一个媒体会员,你的会员费的一部分给了你所阅读的作家,你可以在…上看到所有的故事

mlwhiz.medium.com](https://mlwhiz.medium.com/membership)

我如何创建一个歌词生成器

原文:https://towardsdatascience.com/how-i-created-a-lyrics-generator-b62bde13badb?source=collection_archive---------13-----------------------

用人工智能创作热门歌曲

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

图片: IB306660 ,经由pixabay.com(CC0)

网上有很多歌词生成器,虽然玩起来很有趣,但他们创作的歌曲没有多大意义。作为一个真正的人类歌曲作者(我已经写了 100 多首歌),我想一定有更好的方法来做到这一点,所以我决定利用机器学习的最新进展来建立自己的方法。没有好的方法来教人工智能“歌曲”的概念,但是可以使用 NLP 来训练它模仿你给它看的任何文本。我给它大量的歌曲来学习,最终,它能够输出听起来连贯的歌词。总的来说,该项目涉及了大约 50 个小时的编程,但最终结果是值得的:【https://boredhumans.com/lyrics_generator.php.

以下是我做这件事的细节:

我从微调 GPT-2 开始,这是一个开源语言模型,在超过 800 万个网页上训练,预测文本中的下一个单词。为此,我使用了 GPT-2 Simple (它有一个链接,任何人都可以通过谷歌 Colab 在免费的 GPU 上运行它)和一个包含 13,000 首诗歌的数据库。我原本打算在我下载的 400,000 首歌词的数据库上训练它,但其中许多都有脏话,性内容,毒品参考和其他不适合孩子的东西,我不想让我的模型学习所有这些。另外,我希望我的版本听起来比其他网站更“聪明”,所以使用诗歌似乎是一个更好的计划。

一旦我让它很好地用于创作诗歌,我就对我认为有诗意的艺术家(如鲍勃·迪伦、U2、泰勒·斯威夫特和几十个其他艺术家)的 7000 首歌词进行了更多的微调。但结果仍然是诗歌,所以我添加了一堆非 ML 的后期处理步骤,使它看起来更像宋立科的歌词。在 GPT-2 产生原始内容后,我使用前 6 行,称之为“第 1 节”,然后接下来的 4 行是“合唱”,然后接下来的 6 行是“第 2 节”,然后为了让合唱听起来像合唱,我再次重复第一个合唱。我还做了其他各种各样的小调整,比如过滤掉 r 级内容,删除原始歌词的最后一行,因为大部分时间它都没有完成(被剪掉),如果歌曲在所有删除后变得太短,则获得一套全新的歌词。有时它有像[重复合唱]或(乐器间歇)这样的短语,这是不好的,所以我也自动删除了这些台词。所有这些任务都是通过简单的 PHP 编程完成的,比如使用 str_replace 去掉我不想显示的各种字符:

$title = str_replace("/", "", $title);

这是为了删除重复太多的行:

// find repeated lines
  for ($i = 0; $i < count($words); $i++) {
    if (str_word_count($words[$i])) {
      if ($counts[$words[$i]] > 5) array_push($repeated_lines, $i);
    }
  }
  // remove repeated lines
  for ($i = 0; $i < count($repeated_lines); $i++) {
    if ($i > 3) {
      unset($words[$repeated_lines[$i]]);
    }

找出给每首歌起一个标题的最佳方式比我预想的要困难得多。有时人类词曲作者很难做到这一点,我不确定 ML 模型可以训练得很好,所以相反,我选择创建一些硬编码的规则来选择标题。我主要使用重复最多的行,但有限制,不能太短或太长。

这一切变得复杂的一个原因是,它是一个网站,而不仅仅是一个普通的 Python 程序。简单地找出将 Python ML 模型部署到 web 的最佳方式是一场磨难,因为它对于 Google Cloud Run 或 AWS Lambda 来说有点太大了,而在常规 AWS 服务器上运行它又太昂贵了。我最终使用了 AWS LightSail,它就像一个普通的 web 主机(如 DigitalOcean),但仍然具有普通 AWS 的许多优点。

此外,一旦部署了模型,还需要做更多的工作,使用 PHP 和 JavaScript/Ajax 使它真正发挥网站的功能。让我的 PHP 页面与 ML 模型(使用 Starlette/uvicon[类似于 Flask])的 REST API feed 一起工作时,我遇到了无尽的 CORS 跨域问题。它涉及到一些修复,比如向 Python API 部分添加如下代码行:

middleware = [Middleware(CORSMiddleware, allow_origins=['*'])]# Needed to avoid cross-domain issues
response_header = {'Access-Control-Allow-Origin': '*'}

并引用我的服务器的 SSL 证书,如:

if __name__ == '__main__':
    uvicorn.run(
        app,
        host='0.0.0.0',
        port=int(os.environ.get('PORT', 6006)),
        ssl_version=ssl.PROTOCOL_SSLv23,
        ssl_cert_reqs=ssl.CERT_OPTIONAL,
        ssl_keyfile="./ssl/server.key",
        ssl_certfile="./ssl/server.crt"
    )

我的计划是最终将人工智能生成的音乐和人工智能生成的人声添加到歌词中。我已经试验过最先进的音频程序,比如谷歌的 Magenta ,虽然它确实输出好听的音乐,但远远达不到创作一首真正的歌曲所需的水平。加入人声更是难上加难,因为除了努力让它听起来像歌手而不仅仅是普通的电脑声音,歌词还必须与旋律/音乐同步。理想情况下,所有这些都可以自动生成,以配合人工智能歌词,然后我将有一首完整的歌曲从开始到结束,所以这是我接下来要做的。

统治他们的标签👉分析公司推文

原文:https://towardsdatascience.com/how-i-created-a-monster-function-to-discover-our-brands-twitter-best-friend-556f2c90dbb4?source=collection_archive---------42-----------------------

Twitter 标签和提及的数据分析(带酷炫功能&剧情!)

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

扬·巴布拉克在 Unsplash 上拍摄的照片

我们匆匆忙忙,很少停下来闻闻花香。斯多葛派告诉我们要思考我们生活的更大图景,我决定停下来分析我们品牌的 Twitter 账户的更大图景。

我们可以将这种数据分析诗意地命名为💐碎花的味道

目标

可以用 Twitter 数据做很多事情,相信我,我几乎用尽了所有方法来折磨它(见笔记本的当前版本)。但是,在这篇文章中,我们将关注标签和提及的频率和使用。很快会有其他关于这些美味 话题的帖子,比如相关性、表情符号和一周中最悲伤的日子。

👉让我们开始吧:数据集

该数据集已从 Twitter Analytics 下载,涵盖时间为 2020 年 4 月至 9 月。尽管我很想拥有更多,但 Twitter 并不存储更早的数据,或者即使存储了,也不会向账户所有者公开。

该数据集包括账户@ makingjam 在此期间发送的所有推文。我的大部分推文都是我写的,因此任何后续的文本分析都将是对我营销头脑和幽默感的洞察——做好准备。

😩第一步:一团糟

一开始非常顺利,我们用这个简洁的脚本将所有单独的 csv 文件读入一个数据帧。

我们得到的结果是一个 529 行 40 列的杂乱数据帧。我会帮你省去所有的清洁工作,你可以在笔记本上看到。重要的是我们掉了一个没用栏目的调子。

让我们来玩玩我们“最喜欢”的数据类型日期时间

我们要做的是:

  • 创建格式正确的日期和小时列,这在以后会很重要。
  • 为一周中的每一天添加两列:一列用数字表示,另一列用友好的字符串表示。

现在,数据框的前几行如下所示。

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

在我们继续之前,我们还将添加两列来保存每条 tweet 中的标签数和被提及次数的值。

🐲第二步:进入怪物功能

我们想从数据框中的文本中提取很多内容。对于标签和提及,我们分别需要:

  • 一张所有人的名单
  • 独特标签或提及的数量
  • 一个的独特之处
  • 具有使用频率的数据帧*
  • 十大最常见的

*可能是字典。请随意重写我的 monster 函数,以包含一个字典和一个元组来完成返回数据类型的列表。👌

为了检索整个 this^,我写了一个函数的怪物。对我来说,那是个怪物。

我的额外收获是实例化一个类和对象。如果我所做的方式或者它在函数中的事实对于那些更精通 Python 的人来说是很糟糕的事情,请告诉我。老实说,这是我第一次在辅导课之外做这件事。

现在我们可以得到关于标签的所有统计数据。多么快乐!

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

分享一个截图,而不是一系列的短片。我希望你原谅我。

🍬剧情!

请记住,我们还有一个完整的数据框架,其中包含了标签的频率。什么意思?对 pyplot 和 seaborn 粉丝的款待——我们可以策划他们!

输出:

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

猜猜做果酱的牌子是关于什么的!

没错,我们使用的热门标签反映了真相:制作果酱 是关于产品管理(和事件)**。**此外,我们在推特上发布的数据框涵盖的事件包括 JAM London、Remote PM 和 JAM Barcelona。

🔎第三步:放大标签

如果我们希望看到的是绘制一个特定标签在特定时间段内的使用情况呢?

请便!

首先,我们必须创建一个列来保存每条 tweet 中使用的所有标签。为此,我们创建了一个函数,它的名字就像是西尔维斯特·史泰龙的一部电影的标题。💪

为了规划所选标签的使用,我们需要对文本进行矢量化——创建一个稀疏矩阵,反映哪个标签出现在哪个推文中。要做到这一点,我们只需要带有标签的文本列,但我们需要日期来绘制结果。

输出:

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

是的,数据帧大部分是零。**看起来很无聊,但它非常有用,**因为现在我们可以绘制一段时间内所选标签的使用频率。🎉

你可能已经注意到,我编写这些函数的方式可以在以后重用,以获得相同的提及统计。🤔向前思考🤔

让我们用标签来描述发生在 2020 年 5 月的远程总理事件。

plot_usage(hahstags_vectorized, ‘TheRemotePM’, date1=’2020–04–20', date2=’2020–05–21')

🙋‍♀️给 5 岁孩子的问题:你能猜出远程预防性维护发生在哪天吗?

输出:

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

🎖最常用的标签

我们可能还想知道特定时间段内使用最多的标签。

most_used_h_or_m(hahstags_vectorized, '2020-06-01', '2020-06-30')

输出:

('product', 14)

也是整个集合中使用最多的 hashtag。

变量‘earliest _ tweet’和‘latest _ tweet’是在笔记本的开头定义的。

输出:整个数据集使用最多的 hashtag 是:product,有 127 次提及。

**💁‍♀️结论:**这些推文大部分都是关于产品的,omnia product 的 product um,套用一句著名的悲观名言。

💙第三步:我们推特上最好的朋友

这一部分会更短,因为我们已经有了所有的函数,我们可以重复使用来处理提及。如果你读到这里,我敢肯定你已经迫不及待地想要了解这个数据集中提到的所有数据。

让我们在@上部署怪物功能。

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

分享一个截图,这样你就可以同时看到代码和输出,否则会有太多的小片段。

这里有一些很酷的人和团体!向马特·勒梅玛蒂尔德·利奥三角女孩吉布森·比德尔苏珊娜·维黛拉·洛佩斯索菲亚·金特罗蒂姆·赫比格科斯塔·科列夫亚历克西斯·奥德修斯

接下来,“西尔维斯特·史泰龙函数”再次进入,创建一个包含提及列表的列,作为向量化的准备步骤。

矢量化!

输出:

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

这个图和同一时期的标签图有明显的相似之处。🤔

马特·勒梅和远程首相有什么关系?

💁‍♀ ️He 是东道主!

最后一步:

输出:整个数据集中使用最多的提及是 mattlemay,有 37 次提及。

我承认这里的措辞有点客观化,抱歉马特。但是,我们也认为你是我们 Twitter 上最好的朋友!至少在数据集覆盖的时间段内是如此。

👀下一步是什么?

我将每月从 Twitter analytics 下载一个新的 csv 来扩充数据集。我很确定那里有自动化的空间。而且,也许一旦我掌握了画面——看这个空间!—可能会出现相应的操控板。

这是一系列帖子中的一篇,灵感来自我们品牌的 Twitter 数据集。您可以在此了解更多信息:

我如何为 COVID 创建一个实时的 Twitter 情绪分析工具

原文:https://towardsdatascience.com/how-i-created-a-real-time-twitter-sentiment-analysis-tool-for-covid-292ff6a6323b?source=collection_archive---------26-----------------------

利用机器学习和 Python,我开发了一个模型,将关于 COVID 的推文分为正面、负面或中性。

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

Twitter 是最成功的微博服务,每天有 1.5 亿用户。每秒钟写 6000 条推文。人们在推特上发布任何想到的东西,并使用标签将推文与主题联系起来。

我们可以建立一个机器学习分类器,根据他们的情绪对推文进行评级。一条推文可以表达积极、消极或中性的情绪。

我将创建一个简单的模型来实时分类此类推文,并为 COVID 的整体情绪创建一个图表。人们对这种病毒有什么看法?

1.资料组

首先,我需要一个已经分类到三个类别之一的推特数据集来训练我的模型。Sem-eval 提供了一个相对较大的数据集,包含 65.854 条已标记的推文。因为没有特定于 COVID 的 twitter 数据集,所以我将使用一个通用的 twitter 数据集。

2.文本预处理

接下来,我将使用 16 种预处理技术的组合来预处理推文。tweet 的初始形式不适合自然语言处理(NLP)。推文不干净,包含 URL、用户提及、俚语、缩写、数字、重复的标点符号、拉长的单词等。
因而有这样一段文字:

呆在家里!!注意安全!!保持快乐!!活下去。我们可以和 https://t.co/SEpa9yxg87 一起战斗

会变成:

呆在家里多感叹保持安全多感叹保持快乐多感叹保持活力。我们可以用 COVID-stayhomestaysafe stay health 网址战斗

3.机器学习

我在预处理过的数据集上训练了 10 个机器学习模型。我选择不使用深度学习模型(如 BERT ),因为我不是专家。因此,我使用了逻辑回归、朴素贝叶斯、K 近邻、随机森林和支持向量机等模型。后者在性能(f-measure)上胜过其余的,我选择了它。

执行了列车测试分割(20%测试)。TF-IDF 矢量器将文本标记转换为数字,未删除停用词,分类的性能指标如下所示。

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

ML 模型的性能。

我选择了线性 SVC,并对整个数据重新训练了模型。我记得在过去,支持向量机是 NLP 的最新技术!被训练的模型被保存在困境中。

4.实时预测

为了实时获取推文,我需要一个账户和一个 api 密匙。接下来,我可以选择关键词,只有包含这些关键词的推文才会被返回。我选择了“covid”作为关键字。

当从推文流中获取一条新推文时,经过训练的模型会预测其情绪,并将该推文保存在文本文件中。

与此同时,一个脚本正在运行,随着更多的数据添加到文本文件中,该脚本会实时绘制文本文件的内容。它使用 matplotlib 的动画功能来刷新情节。如果推文是正面的,y 轴得到+1,如果是负面的-1,中立的+0。

这是:

实时推特情感分析。

可以看出,在 1000 条关于 COVID 的推文之后,整体情绪是-80。

可以为任何关键词生成相同的实时图,脚本可以全天候运行以收集和标记推文。

感谢阅读!

我如何用投影贴图制作短片

原文:https://towardsdatascience.com/how-i-created-a-short-film-with-projection-mapping-8a950462509b?source=collection_archive---------35-----------------------

我使用 Lightform 对我的画进行投影映射,以创建一个短片,并对神奇的结果感到完全敬畏。

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

图片来源:基拉·布尔斯基(作者)

在隔离期间,我花了很多时间进行艺术实验和创作。3 月 27 日的周末,我参加了虚拟的被困在家里的 48 小时电影项目。我有整整 48 小时来制作一部完整的短片。这将是我的第十五个 48 小时电影项目…你可以说我有点痴迷。为了迎接挑战,我决定把这个项目作为一个机会,更深入地研究投影制图。

如果我创作了一部完全投影映射的电影,会发生什么?

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

视频鸣谢:基拉·布尔斯基(作者)

什么是投影映射?

投影映射,也被称为空间增强现实,是一种投影视觉互动并适合非平面三维表面的技术。你可以投影地图日常物体,建筑物,花卉,人-任何你能想象的,你可以投影地图!点击,通过投影映射中心了解更多信息。

什么是光形态?

Lightform 简化了美国创意人员的投影映射流程。他们设计了一个应用程序,就像 Photoshop 在真实的非数字世界中处理光线一样!太令人兴奋了。我完全爱上了这家公司。

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

“新思想/无思想”制作过程中的光形式应用——图片来源:基拉·布尔斯基(作者)

Lightform 简化了美国创意人员的投影映射流程。他们设计了一个应用程序,就像 Photoshop 在真实的非数字世界中处理光线一样!太令人兴奋了。

“Lightform 是一种新的设计工具,允许任何人创建投影增强现实体验。投影增强现实使用投影仪为现实生活添加数字信息和神奇效果。与目前的 AR 和 VR 形式不同,投影的 AR 可以用肉眼看到,不需要耳机或手机。

我们希望设计一个未来,在那里数字艺术和信息可以无缝地融入现实生活,不受矩形屏幕的限制。"

-轻型

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

视频鸣谢:基拉·布尔斯基(作者)

Lightform 工作原理的简化版本:

  • 投影仪发出一系列结构光,摄像机扫描场景。
  • Lightform 软件从这个过程中收集深度数据。
  • 有了这些数据,您使用 Lightform 设计的投影可以无缝地交互并集成到您的真实环境中。纯魔法!

电影概念

在“新思想/无思想”中,一幅画意识到她生活在一张纸上,并经历了意识的转变。

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

视频鸣谢:基拉·布尔斯基(作者)

我受到启发,讲述了我心理健康之旅的故事。通过冥想,我经历了对现实感知的转变。我已经超越了我曾经认为的现实范围。用语言描述这种经历是相当困难的,但它是美丽的,给人以生命。这部电影是我描绘那段经历的尝试。

物理图纸上的增强现实投影感觉像是一种非常合适的媒体,可以用来描绘一个人对现实感知的扩展。

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

视频鸣谢:基拉·布尔斯基(作者)

物理图纸上的增强现实投影感觉像是一种非常合适的媒体,可以用来描绘一个人对现实感知的扩展。

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

视频鸣谢:基拉·布尔斯基(作者)

过程

在构思出概念和故事板之后,我能够将视觉效果缩小到五幅关键的图画。这些画是我的主要镜头,我将在上面投影贴图。

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

图片来源:基拉·布尔斯基(作者)

我把图纸留得很简单,让自己在投影设计上更灵活。我可以给线条画添加生命和运动。

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

视频鸣谢:基拉·布尔斯基(作者)

接下来,我利用 Lightform 扫描我的图纸并设计投影。我利用了 Lighform 的一些内置效果和纹理,并获得了额外的免版税动画和剪辑(如窗口中的日落延时剪辑)。

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

视频鸣谢:基拉·布尔斯基(作者)

我还为其中一个场景绘制了投影图!说到混合现实…被投影映射是相当令人神往的。

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

视频鸣谢:基拉·布尔斯基(作者)

我拍摄了整张纸的“宽”镜头以及脸部特写和其他投影细节,以便在 Adobe Premiere 中进行编辑。

最终的电影

这是最后一部电影“新思想/没有思想”,全部在 48 小时内完成!

结论

在相机上捕捉投影贴图是一回事,但亲自体验它会让它达到一个全新的水平。投影映射有许多令人兴奋的可能用途:交互式装置、电影制作、现场表演等等。

我有一系列即将到来的项目,在这些项目中,我将进一步试验这项技术。说我很兴奋是一种保守的说法。请随意伸出手来,跟随我的冒险之旅。我把神奇的创意传递给你。

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

视频鸣谢:基拉·布尔斯基(作者)

基拉·伯斯基是一名电影制作人、多学科艺术家和魔法探索者。她的电影在 YouTube 上有超过 1800 万的浏览量,并在全球放映。

我如何用 D3.js 创建了一个交互式的滚动可视化,你也可以

原文:https://towardsdatascience.com/how-i-created-an-interactive-scrolling-visualisation-with-d3-js-and-how-you-can-too-e116372e2c73?source=collection_archive---------2-----------------------

通过交互式和可滚动的可视化,让您的故事栩栩如生,这通过出色的 D3.js 库成为可能

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

按类别划分的大学专业

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

动画版

[## 最佳大学专业

大多数人想要一个能让他们毕业后赚大钱的学位。这里是(几乎)所有的…

cuthchow.github.io](https://cuthchow.github.io/college-majors-visualisation/)

动机

网络上充斥着滚动和交互式可视化的惊人例子,通常是用 D3 构建的。如果你读过《彭博》或《纽约时报》的这类专题文章,我肯定你知道我在说什么。我最喜欢的这种形式的例子有:

每一次滚动事件后,视觉元素的行为方式令人满意,完全受你的控制。很多时候,当我上下滚动页面,看着所有的形状和颜色飞来飞去,我的脸上挂着灿烂的笑容。这种感觉让人想起自己发现了数据中的秘密,我相信这是这些演示如此令人信服的原因。它还提供了一个更具命令性的叙事流程,这在其他静态作品中是缺乏的。浏览这些文章,你可能会发现自己制作这样的视觉效果会非常复杂,你可能会认为它们最好留给顶级出版物的编辑和作者。但我在这里帮助消除这种观念:任何人都可以做一个,包括你!

在通读了一堆在线资源之后(我会在文章末尾列出这些资源),我决定尝试自己创建一个。正如我之前提到的,学习一项新工具、技术、技能或能力的最好方式是在你知道自己是否有能力做这件事之前,就把它投入使用。这就是我在一周内所做的。

(本文假设您对 D3.js 及其工作原理有一些基本的了解)

项目描述

在浏览了一系列数据集后,我找到了一个托管在 Kaggle 上的数据集,它最初来自分析博客 Fivethirtyeight(如果你正在寻找很酷的数据集,请查看谷歌的数据集搜索工具)。这是一个(有点过时的)关于美国大学专业的数据集。它有每个大学专业的注册人数的信息,以及这些学生的中位数,第 75 个百分点和第 25 个百分点的工资。有趣的是,它还提供了每个专业的男性/女性代表的信息,我认为这将是这篇文章的一个重点。

决定数据集后,我开始在 Jupyter 笔记本上使用 Python 和 Pandas 探索数据,寻找任何有趣的趋势或我想在可视化中强调的点。我还对我想在最终产品中展示的图表做了粗略的近似。

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

我匆忙拼凑的几张草图,只是为了大致勾勒出我希望达到的叙事流程

我对观想的总体概念是,每个大学专业都用一个泡泡来代表。然后,气泡会根据我试图强调的数据类型(如性别差异、工资中位数、类别分组等)改变形状和颜色。).当气泡被特定的属性分组时,我想通过一个 D3 力模拟来实现,这样气泡看起来会被一个看不见的力吸引。

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

我用 matplotlib 制作的性别分布与工资中位数图表的预览。我在研究这些数据,看看是否有有趣的趋势需要强调,这是其中之一

经过一番探索,我知道我想关注的是专业内的性别分布对毕业生平均工资的影响。我强烈建议你在开始任何可视化过程之前深入研究你的数据,因为在真正坐下来编码最终产品之前,你想要有一些你脑海中的交互的表象。

如果您想要一种真正快速的方法来观察变量之间的关系,python 可视化包 seaborn 有一个“pairplot()”方法来帮助您做到这一点,它会在传递给它的数据帧中的所有变量之间创建一个散点图矩阵。

**#Plotting a scatter matrix**import seaborn as snsfactors = df[['Total', 'Major_category', 'ShareWomen', 'Sample_size', 'Employed', 'Unemployed', 'Median']]sns.pairplot(factors)

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

根据数据子集创建的配对图示例

现在我们对想要包含的东西有了一个坚实的想法,我们准备开始创建。

处理滚动事件

这(显然)是你构建的每个滚动条中最重要的部分。但方便的是,它也是最可重用的部分,这意味着一旦构建完成,就可以开始使用了。

事实上,我已经创建了一个滚动条功能的模板版本,你可以在这里找到它。(再次感谢吉姆·瓦兰丁汉姆,因为使用的大部分代码来自他的原创文章。事实上,他写了一篇关于创建滚动器的类似文章,重点是滚动机制,所以你应该先读一下。在这篇文章中,我将把重点放在我发现令人困惑的元素上,并把重点放在实际创造观想的部分上。

HTML 和 CSS 大纲

整个可视化应该包含在一个 HTML 页面中。在页面中,有一个包含所有元素的 div,在这个 div 中,有两个单独的 div 用于文本和可视化。

在“sections”div 中有一组 section 元素,每个元素都有一个类“step”。这些部分中的每一个都应该包含一个不同的文本部分,并且对应于观想的一个阶段或部分。当用户在部分之间移动时,可视化将被更新,

<div id="graphic"> <div id="sections"> <section class="step"></section>
         <section class="step"></section> </div>
    <div id="vis"> </div>
</div>

您可以随意调整这些元素的大小和位置,只要您将#vis 元素固定在页面上(使用 display: fixed),这样它就不会随着用户的滚动而移动。您也可以调整每个的高度。step 元素基于您希望每个部分包含多少文本。

滚动事件

下面是处理滚动事件的代码。我添加了一些注释来澄清某些部分。

function scroller(){ let container = d3.select('body')
  let dispatch = d3.dispatch('active', 'progress');
  let sections = d3.selectAll('.step')
  let sectionPositions
  let currentIndex = -1
  let containerStart = 0;**// Binds the position function to the scroll event, and the resize function to the resize event. What these functions do are detailed below.**   function scroll(){ d3.select(window)
      .on('scroll.scroller', position)
      .on('resize.scroller', resize) resize(); let timer = d3.timer(function() {
      position();
      timer.stop();
    });
  }**//The resize function determines where each of the .step elements are on the page, relative to the top of the first element. It saves all of the co-ordinates of these elements in an array called sectionPositions** function resize(){
    sectionPositions = [];
    let startPos; sections.each(function(d, i) {
      let top = this.getBoundingClientRect().top;
      if (i === 0 ){
        startPos = top;
      }
      sectionPositions.push(top - startPos)
    });
  }**//The position function determines where the user is on the page (using window.pageYOffset), and uses that to determine which section of text should currently be in view. It then uses D3’s dispatching tools to signal the 'progress' event, which will be used in the main script, passing along the current section index so that the script knows which stage of the animation/visualisation should be showing.**   function position() {
    let pos = window.pageYOffset - 300 - containerStart;
    let sectionIndex = d3.bisect(sectionPositions, pos);
    sectionIndex = Math.min(sections.size()-1, sectionIndex); if (currentIndex !== sectionIndex){
      dispatch.call('active', this, sectionIndex);
      currentIndex = sectionIndex;
    } let prevIndex = Math.max(sectionIndex - 1, 0);
    let prevTop = sectionPositions[prevIndex]
    let progress = (pos - prevTop) / (sectionPositions[sectionIndex]   - prevTop);
    dispatch.call('progress', this, currentIndex, progress)
  }//**The code here adds an event listener to the dispatcher.** scroll.container = function(value) {
    if (arguments.legth === 0){
      return container
    }
    container = value
    return scroll
  } scroll.on = function(action, callback){
    dispatch.on(action, callback)
  };
  return scroll;}

上述所有代码都保存在一个单独的脚本文件中。然后我们创建一个主脚本文件,它负责在每次查看器改变部分时更新可视化。

let scroll = scroller().container(d3.select('#graphic'))scroll()let lastIndex, activeIndex = 0**//This is where most of the magic happens. Every time the user scrolls, we receive a new index. First, we find all the irrelevant sections, and reduce their opacity.** scroll.on('active', function(index){
  d3.selectAll('.step')
    .transition().duration(500)
    .style('opacity', function (d, i) {return i === index ? 1 : 0.1;});**//Next, we selection from a range of activationFunctions (which we create), based on the index of the current section.**   activeIndex = index
  let sign = (activeIndex - lastIndex) < 0 ? -1 : 1;
  let scrolledSections = d3.range(lastIndex + sign, activeIndex + sign, sign);
  scrolledSections.forEach(i => {
    activationFunctions[i]();
  })
  lastIndex = activeIndex;})**//I placed all the functions in an array. Each function corresponds to a different change in the visualisation. One may change the graph into a scatter plot, and another may initiate a force simulation.**let activationFunctions = [
  draw1,
  draw2,
  draw3,
  draw4,
  draw5,
  draw6,
  draw7,
  draw8
]

构建滚动条的一般建议

有了滚动条的一般组件,你从这里开始所做的将会根据你希望构建的观想类型而有很大的不同。尽管如此,我还是希望能提供一些有用的建议,我希望我能在这个过程中早点意识到。

在起点画出所有的元素

基本思想是,当页面加载时,应该创建可视化所需的所有元素。我创建了一个名为 drawInitial()的函数,并在数据加载后调用它。这包括创建所有的比例,轴,形状,用于模拟和其他你在观想中需要的元素。

一旦它们都创建好了,你可以简单地把它们的不透明度属性设置为 0,以确保它们直到可视化需要时才显示出来。确保每组特征(即特定图表的一组轴或详细标注)都有相关的类名或 ID 名,以便在需要时可以引用这些特定的特征。

我发现创建一个清理函数很有用,它会在每一步被调用。我将传入我试图创建的图表类型,该函数将移除(或者隐藏)与该图表无关的所有元素,从而使我不必编写大量重复的代码。这是函数的一部分:

function clean(chartType){
    let svg = d3.select('#vis').select('svg') if (chartType !== "isScatter") {
      svg.select('.scatter-x').transition().attr('opacity', 0)
      svg.select('.scatter-y').transition().attr('opacity', 0)
    } if (chartType !== "isMultiples"){
      svg.selectAll('.lab-text').transition().attr('opacity', 0)
      svg.selectAll('.cat-rect').transition().attr('opacity', 0)...

与原力打交道

正如我提到的,我将使用力模拟来分组几个阶段中的圆形元素。要记住的关键是,每次重新使用时,要“重新加热”力模拟。D3 的力模拟有一个 alpha 值,这是一个冷却参数,随着时间的推移逐渐减少,减少了力对节点的影响。你应该在每次重启原力时将 alpha 重置回某个值,以确保它有足够的“能量”达到期望的状态。您还可以调整 alpha 衰减率,以影响模拟稳定到平衡状态的速度。

总是使用过渡

这一部分很关键:当改变观想的状态时,总是使用过渡,即使这种改变是你想要立即发生的。通过利用 D3 的转换特性(即使持续时间为 0),您允许更改被中断。这意味着,如果用户快速滚动各个部分,一个过渡可以被下一个覆盖,从而避免出现尴尬、无效的状态。

你鼓舞了我

SVG 元素是根据它们被附加到父元素的时间来排序的。把它想象成把颜料泼在画布上:最后一层颜料是在顶部可见的。您可以通过将元素从它们的父元素中移除,然后再将它们追加到最末尾来对元素进行重新排序。或者,您可以利用 D3 的. raise()和。lower()方法,当给定一组元素时,这些方法可以方便地完成这个过程。

构建一致的调色板

颜色是良好数据可视化不可或缺的组成部分。在我的项目中,我试图用颜色对 16 种不同类别的大学专业进行编码。这导致了一个精心挑选颜色的过程,因为我想避免任何两种颜色太相似,因此很容易混淆。

我强烈推荐使用颜色搜索来构建你的调色板。这是一个网站,其他创意人员已经建立并分享了他们自己的调色板,它允许你轻松地复制你想要的颜色的十六进制代码,并保存你自己的调色板以供将来使用。

希望这至少揭开了滚动可视化过程的一部分。老实说,这比看起来容易得多,所以一定要去找一个有趣的数据集,亲自尝试一下!

参考的资源

我如何创造我的第一个 Alexa 技能

原文:https://towardsdatascience.com/how-i-created-my-first-alexa-skill-2bf36b921629?source=collection_archive---------40-----------------------

我向你展示了我如何创建我的第一个 Alexa 技能,一个简单的电话前缀信息工具

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

丹尼尔·方特内尔在 Unsplash 上拍摄的照片

我相信在未来,我们会用语音助手取代我们用手机做的大多数事情,我们会像现在携带智能手机一样携带小型入耳式耳机。

在这篇文章中,我将向你展示我如何为亚马逊的语音助手 Alexa 创建我的第一个技能。我按照亚马逊的这个叫做“蛋糕行走”的教程系列,应用这些步骤来创造我自己的技能。

语音体验设计

教程开始解释技能设计,在编写任何代码之前,从一个好的声音设计开始是非常重要的。首先画一个流程图,说明你的用户将如何使用技能,用户会说什么,Alexa 会回答什么,以及对话可以遵循的不同路径。

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

我技能的通量图

另一件要记住的事情是我们的技能说话的方式。它必须遵循一些声音设计的准则。这方面的一些例子是告诉用户有哪些选择,等待用户的回复,询问封闭式问题而不是开放式问题。使用自然口语也很重要,我们写的和说的不一样,你写的代码会被 Alexa 读取,所以要确保它听起来像自然口语。

我的想法是创建一个电话前缀信息工具。每个国家都有一个定义好的国际电话前缀,通过查看来电电话的前几个号码,你可以知道它来自哪个国家。例如,像 +34 123456789 这样的手机属于西班牙。回到我的 Alexa 技能,目标是创造一个技能,告诉你你问的前缀属于哪个国家。

让我们开始编码吧

首先,你需要一个亚马逊开发者账户来访问 Alexa 开发者控制台,在那里你可以创造自己的技能。一些示例 Hello World 代码是在开始时创建的,作为您技能的补充。你可以改变一些文本,看看每一段代码是如何影响你的技能行为的。

由于我的技能,我不得不改变文本,使它们谈论电话前缀,然后修改代码以等待对欢迎消息的回答(唯一有效的回答将是一个号码)。收集用户的答案在 Alexa 的术语中称为意图。我们需要为我们期望从用户那里得到的每个答案定义一个意图

对于我的简单技能,我只需要一个意图,用户给我一个电话前缀。对于每个意图,我们必须定义用户可以说出信息的所有不同方式,称为话语。话语可以包括后端代码可访问的变量,称为意图槽,它们也必须被定义。

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

用户可以说的一些示例话语

我的技能是用西班牙语制作的,所以话语也是用那种语言。话语的目标是尽可能多地捕捉用户可以说出的短语。

例如,用户可以说“前缀{号码}”或“前缀{号码}”。两者都应该被 Alexa 接受。对于我们的技能,我们必须定义尽可能多的话语,这样用户才能自然地说话并被理解。

我们必须考虑许多不同类型的用户和他们说话的不同方式。

最难的部分

最难的部分是创建程序逻辑,即搜索国家代码并指出它属于哪个国家的代码。我唯一能找到的是一个数据库,里面有电话前缀和国家名称的成对关键字。它是英文的,所以我必须把所有的东西都翻译成西班牙语,为此我使用了 DeepL ,这是一个人工智能翻译器,效果惊人,几乎所有的东西都在第一次尝试中被完美地翻译了。

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

国家-电话前缀数据库

然后只需将用户的话语与数据库连接,并将国家返回给用户。

最终步骤和发布

在发表之前,你必须填写一个表格,里面有关于你技能的相关数据。这是用户在 Alexa 应用程序上浏览技能商店时看到的内容。

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

然后在亚马逊的服务器上运行一些测试,检查所有需要的信息,并找出常见的错误。如果这些测试都通过了,我们可以进入下一步,发布技能!

亚马逊完成了一个验证过程,就我而言,在我的技能发表之前花了大约一周时间。

如果你用西班牙语配置了 Alexa,你可以通过说*“Alexa,abre prefijos telefónicos”*找到我的技能

我如何使用深度学习和光流算法创建锻炼运动计数应用程序

原文:https://towardsdatascience.com/how-i-created-the-workout-movement-counting-app-using-deep-learning-and-optical-flow-89f9d2e087ac?source=collection_archive---------14-----------------------

不要自己跟踪动作,让人工智能替你做!

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

来源阿洛拉·格里菲斯,经由 unsplash (CC0)

我喜欢进行锻炼和不同类型的训练,如 crossfit,但当训练强度太大或时间太长时,我注意到我经常在计算每次锻炼的运动次数时出错,这可能是因为在训练期间没有专注于运动计数任务,或者下意识地高估了完成的运动次数。作为一名计算机科学理学士三年级的学生,我决定在我的课程工作中解决这个问题,并创建了一个 Web 应用程序来计算锻炼过程中进行的移动次数。在这篇文章中,我想分享我解决这个问题的方法。你可以在 github 库中找到该应用的完整代码。

算法

为了执行运动计数,您必须知道身体在每一帧上是向上还是向下运动。通常,为了完成这样的任务,我需要使用一些 RNN 架构,因为,很明显,你不能只使用一帧来检测运动的方向。他在这张照片上是向上还是向下移动?

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

https://www.youtube.com/watch?v=7wblGkVQx3U

但我没有足够的训练数据来建立一个稳健的 RNN 模型,因为我必须自己准备和标注数据。我试着朝 PoseNet 模型的方向看,以获得每一帧上每个身体部位的坐标。

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

https://medium . com/tensor flow/real-time-human-pose-estimation-in-the-tensor flow-js-7 DD 0 BC 881 cd5

这种方法也没有好处,原因有几个:

  1. 如果我在它被训练的相同环境(相同的房间,相同的视频角度,相同的人)中尝试,该模型表现良好,但是要为一个练习制作一个健壮的模型,我仍然需要大量的训练数据。
  2. 没有使用 GPU 卡的 PoseNet 的 FPS 真的很低。
  3. 在某些帧上,检测到的身体部位的质量很低。

总而言之,我玩了很多不同的模型,它们都在某种程度上给出了一个糟糕的结果。直到有一天我了解了光流算法,尤其是密集光流实现(下图的右边部分)。简而言之,这种算法跟踪像素沿着一定数量的连续帧的运动。

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

https://nanonets.com/blog/optical-flow/

可以使用一些数学模型(例如,在 OpenCV 库中实现)来估计光流,或者可以使用深度学习来直接预测光流,这在复杂的视频场景中给出更好的结果。在我的实现中,我决定坚持使用密集光流算法,它是在 python-opencv 包中实现的。

这就是如何用密集光流对一个俯卧撑进行颜色编码。

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

【https://www.youtube.com/watch?v=xoCKHx8Yyj4 号

如你所见,密集光流将向下运动编码为绿色,将向上运动编码为紫色。因此,知道了每个帧的颜色编码表示,我可以很容易地构建一个简单的 CNN 网络来执行帧的多类分类。我只是在 PyTorch 中堆叠了一些 Conv +池层,这导致了下面的简单架构。

为了训练这个模型,我加载并按帧标记了几个 YouTube 视频,我自己也准备了一些俯卧撑视频。最后,我有一个彩色编码图像的训练集,包括 252 个向下移动的帧,202 个非上推帧和 206 个向上移动的帧。我还准备了一个由 140 个不同动作的帧组成的小验证集。在运行了 10 个时期的训练循环后,我得到了一个非常令人印象深刻的模型对数损失图。

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

训练与验证集的对数损失

显然,对于模型来说,预测这三个类别并不太难,因为只需用眼睛观察彩色编码的图像就可以很容易地做到。

更重要的是,经过训练的模型能够对框架进行分类,不仅是俯卧撑,还包括俯卧撑、深蹲和引体向上。一般来说,我想这个精确的模型可以很容易地对所有高振幅的运动进行分类,包括上下运动。

不过,要对一些练习进行分类,如仰卧起坐或一些低幅度的哑铃运动,最好收集一套新的训练集,并重新训练当前的模型。

App

为了在现实生活中应用我的模型,我使用 Django 创建了一个小的 Web 应用程序,在那里我可以创建一个新的锻炼,并在“战斗”环境中尝试我的模型。这是它的样子。

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

web 应用程序的主屏幕

总的来说,在训练的时候,我注意到俯卧撑、深蹲、引体向上的误差在 2.5% 左右。对于 burpee 来说,误差大约在 5% 左右,这是因为练习涉及到不止一个上下运动。以下是模型在锻炼过程中计算俯卧撑的方法。

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

结论

总之,这项工作对我来说是一次很好的经历,因为我必须做大量的研究,并测试锻炼过程中运动计数问题的不同假设。我的时间跟踪器显示,现在我已经在这个应用程序开发上花了大约 75 个小时,但谁知道呢,如果我决定继续这个项目,让它变得更大,我可能会花更多的时间。谢谢你的阅读!

你可以在我的 网站 上查看其他帖子

我习惯如何将数据与熊猫绑定

原文:https://towardsdatascience.com/how-i-customarily-bin-data-with-pandas-9303c9e4d946?source=collection_archive---------9-----------------------

熊猫“咔”和“咔”

您可能只使用了默认值

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

照片由斯蒂夫·约翰森Unsplash 上拍摄

动机

“这是什么鬼?”

这是初学者在查看一些硬函数的输出时经常得到的反应。很多教程和课程用一句话就介绍了这些功能,然后转到其他话题,这总是让我感到困惑。即使你从头到尾阅读他们的文档,我保证也要超过一分钟。

作为一个初学者,当我遇到这种情况时,我总是很沮丧。有一次,当我在 Udacity 攻读纳米学位时,我正在学习 Matplotlib 的热图。如果你知道,Matplotlib 不能像 Seaborn 一样自动为热图创建注释,所以你必须手工创建它们。为此,你可以使用qcutcut(这是本文的主题)将你的数据分类,我对这些函数完全陌生。

讲师用一句话简单地“解释”了这些功能,屏幕上出现了文档链接🤦‍♂️.他甚至快进了他输入语法的部分。

最近,我一直在写一个小编,解释pandas最难的功能,希望其他人不会面临同样的困难。这是第四部分,是关于使用qcutcut的宁滨数字数据。

[## 通过我的推荐链接加入 Medium-BEXGBoost

获得独家访问我的所有⚡premium⚡内容和所有媒体没有限制。支持我的工作,给我买一个…

ibexorigin.medium.com](https://ibexorigin.medium.com/membership)

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

[## 阿尔法信号|机器学习的极品。艾总结的。

留在循环中,不用花无数时间浏览下一个突破;我们的算法识别…

alphasignal.ai](https://alphasignal.ai/?referrer=Bex)

可点击的目录

动机
设置与基础探索
音程记谱复习
熊猫 qcut()
熊猫 q cut()

文中用到的笔记本可以从这个 GitHub repo 下载。

设置和基本探索

对于样本数据,我将使用内置的seaborn数据集planets:

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

>>> planets.describe()

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

planets数据集是从美国宇航局的系外行星目录下载的,包含了太阳系外行星的数据。感兴趣的三列是orbital_periodmassdistance:

  1. mass -这颗行星比木星重多少倍
  2. distance -这颗行星距离地球多少光年
  3. orbital_period -地球绕其恒星一周需要多少个地球日

区间记数复习器

为了从这篇文章中获得最大的收获,并理解我将使用的一些语言,这里有一个关于区间符号的温和复习:

  • (1,10) :两边不闭合。不要在区间中包含 1 和 10
  • 【1,10】:左闭区间。包括 1 但不包括 10
  • (1,10):右闭区间。包括 10 个,但不包括 1 个
  • 【1,10】:两边闭合。包括 1 和 10

熊猫qcut()

为了理解qcut()是如何工作的,让我们从直方图开始:

sns.histplot(planets['mass'])

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

直方图自动将一个数组或一个数字列表分成几个箱,每个箱包含不同数量的观察值。在seaborn中,可以控制箱子的数量:

sns.histplot(planets['mass'], bins=10)

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

直方图是你可能见过的第一个宁滨数据的例子。下面是使用pandasdescribe()功能的另一个例子:

默认情况下,describe()将数字列划分为 4 个桶(箱)-(最小,25 日),(25 日,中值),(中值,75 日),(75 日,最大),并显示箱边缘。您还可以为函数传递自定义百分点:

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

这些都是宁滨数据的例子。但是如果你注意到了,在上面所有的例子中,我们不能真正地控制箱子。我们只是选择箱子的数量,仅此而已。此外,你不能真的把这些箱子从它们的特定功能中分离出来。

现在,这里有一个问题:如何将每个观察值所属的 bin 存储在一个新列中,或者为以后执行一些操作?这就是qcut()cut()的用武之地。

首先,让我们探索一下qcut()功能。它作用于任何类似数字数组的对象,如列表、numpy.arraypandas.Series(数据帧列),并将它们分成多个箱(桶)。文档称其正式名称为基于分位数的离散化函数。

让我们从一般语法开始:

如果您第一次看到这个输出,它可能会非常吓人。但是请耐心听我说,你很快就会掌握这个功能。

该函数的第一个参数是要装箱的列。下一个需要的参数是q,它代表分位数qcut()将数据分成百分位箱,而不是用数字边缘构建每个箱。

让我们分别研究输出的不同部分。当我们将q设置为 4 时,我们告诉pandas创建 4 个区间或区间,并让它自己计算出放置值的位置。

最后一行给出了每个区间的边,分别是(1.349,24.498),(24.498,39.94),(39.94,59.332),(59.332,354)。区间边缘对应于一个百分点值,取决于q的值(在这种情况下,最小值、第 25 个百分点、中值、第 75 个百分点、最大值)。我们可以用describe()函数验证这一点,因为它也将数据分成 4 个分位数:

如您所见,minmaxmedian、25、75 个百分点的值都是相同的。

现在,主要的部分:如果你看实际的结果,每一行或索引被放入四个容器中的一个。默认情况下,pandas为每个观察值提供文字数字箱名称。为了更好地了解情况,让我们将输出存储到一个新列中:

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

存储后,我们可以更好地鸟瞰数据帧。您可以验证每个distance值是否放在正确的区间内。我还引入了一个新的参数precision,它让我们指定要保留的小数点位数。

然而,新专栏仍未达到最佳状态。理想的情况是,如果可以为每个区间指定特定的标签。这将提高我们数据的可读性。

为了实现这一点,我们需要创建一个标签列表,并将其传递给qcut()labels参数:

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

好多了!但是,我们仍然没有谈到qcut()的定义点。让我们在最新的列上调用value_counts()函数,看看会发生什么:

如果分布中没有太多极值,那么每个箱中的值的数量将会超级接近。如果你熟悉统计学,这是有意义的,因为我已经说过qcut()定义了箱边缘为分布的百分位数。

注意,这并不意味着容器的大小是相同的。如果你从右边减去箱子的左边,你会得到不同的结果。例如,让我们将质量分成 5 个箱,并获得每个箱的宽度:

retbins(代表返回箱)设置为True会返回一个额外的numpy.ndarray,包含我们切割的箱边缘。我用一个循环来显示每个箱子的宽度来验证我的观点。

为了下一节简单起见,我将删除新列:

熊猫cut()

在讨论了qcut()之后,你现在能够理解cut()之间的差异。

qcut()对我们的数据进行划分,使每个条柱中的值数量大致相同,但条柱范围不同。第一部分中的许多概念在这里也适用。

主要区别在于cut()使用实际的数字箱边缘,默认情况下,它将分布划分为大小相等的箱。与qcut()正好相反。我们先来看一个例子:

我们将mass列分为三个不同的类别。和以前一样,我将把结果存储回数据框,并对其调用value_counts():

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

此外,让我们看看每个箱的范围:

如您所见,这一次箱的宽度大致相同,我们在每个箱中有不同数量的观测值。

当我们想要为箱子定义自定义范围时,cut的真正威力就发挥出来了。通常,对于真实数据,您不想让pandas自动为您定义边缘。例如,如果您在一家电话公司工作,您可能希望根据服务的总体持续时间对客户进行分类。您可能会优先考虑合作时间较长的客户,并相应地对其他客户进行排序。

让我们来看一个为mass定制宁滨的例子。我们将创建 4 个间隔,并给它们定制标签:

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

这个例子清楚地显示了cut提供的灵活性。bins参数可以接受 3 种选择:

  • 一个整数:我们已经看到例子了。如果传递一个整数,该函数将创建范围相等的存储桶。
  • 一系列数字或标量:当传递一系列数字时,该函数将它们视为自定义 bin 边缘。箱的数量将总是比箱边缘的总数少 1。
  • *pandas.IntervalIndex* 对象:也可以使用pandas.interval_range函数传递自定义范围(稍后将详细介绍)。

通常,在一个列表中定义自定义的 bin 范围是很棘手的。所以最好使用numpy.arangenumpy.linspace功能。两者都创建了一个等间距的数字序列,可以作为cut的 bin 范围传递。你可以在这篇有用的文章中了解更多关于这些功能的信息。

在上面代码片段的第一行,我们创建了一个包含 5 个元素的numpy.ndarray。因此,cut将为distance减少一个间隔数。

一般的经验法则是对较少的箱使用简单的列表,但对许多区间使用numpy函数。

使用pandas.interval_range基本可以得到相同的音程。该函数,而不是列表,返回可以进一步定制的IntervalIndex对象:

是的,基本上是一样的,但是有一个额外的参数使这个函数非常有用:

closed参数接受 4 个字符串来控制间隔边缘:

  • 左侧:左侧关闭
  • 右侧:右侧()关闭(默认)
  • 两边:两边关闭
  • :()两边都不闭合

一个带有cut的例子:

使用interval_range的缺点是在cut中不能使用标签。

关于参数也有一些细微差别,所以一定要查看文档以了解本质细节。另外,这里有一篇类似的文章,比较了来自实用商业 Python 的cutqcut

如果你喜欢这篇文章,请分享并留下反馈。作为一名作家,你的支持对我来说意味着一切!

阅读更多与主题相关的文章:

***** [## 认识熊猫最难的功能,第一部分

掌握 pivot_table()、stack()、unstack()的时机和方式

towardsdatascience.com](/meet-the-hardest-functions-of-pandas-part-i-7d1f74597e92) [## 认识熊猫最难的功能,第二部分

掌握交叉表的时间和方式()

towardsdatascience.com](/meet-the-hardest-functions-of-pandas-part-ii-f8029a2b0c9b) [## 认识熊猫最难的功能,第三部分

形状像果冻的桌子有熊猫旋转()和融化()

towardsdatascience.com](/shape-tables-like-jelly-with-pandas-melt-and-pivot-f2e13e666d6) [## 来自 Kagglers:DS 和 ML 的最佳项目设置

来自顶级 Kagglers 的项目成功最佳实践的集合

towardsdatascience.com](/from-kagglers-best-project-setup-for-ds-and-ml-ffb253485f98) [## 想要 Jupyter 的进度条吗?

对你的长时间循环进行健全性检查(和一点视觉风格)

towardsdatascience.com](/ever-wanted-progress-bars-in-jupyter-bdb3988d9cfc)*****

我如何使用 Python 开发数据可视化的 Web 应用程序

原文:https://towardsdatascience.com/how-i-developed-my-web-app-for-data-visualization-with-python-93555ad83c2d?source=collection_archive---------27-----------------------

关于如何开发数据仪表板并将其上传到网上的一些建议

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

Luke Chesser 在 Unsplash 上的照片

简介

我不是 web 开发人员,但作为一名数据分析师,我认为拥有一个用于数据可视化的 web 应用程序非常有用,您可以在其中部署您的数据并向世界展示您的结果。因此,我决定开发我自己的数据仪表板,我将在其中上传我未来的结果。你可以在这里看到它。为了更好地可视化图表,我建议你用你的电脑而不是智能手机来查看我的网络应用程序。

在这篇文章中,我想给你一些建议来创建你自己的数据可视化 web 应用程序。

关于开发它的技术,唯一的要求是了解标记语言 HTML 和编程语言 Python。

你不需要知道 CSS 或者 JavaScript。事实上,为了开发我的 web 应用程序,我使用 Flask 作为 web 框架,Bootstrap 作为前端框架。

如果你需要一些关于构建你的知识库的建议,你可以以我在 GitHub 上的知识库为例。

在本文中,我将重点介绍部署 Web 应用程序所需的所有步骤。

第 1 部分:在您的操作系统上安装 Anaconda

对于部署,我使用了一个 Linux 终端,我认为它非常适合开发。如果你的操作系统是 windows,你可以点击这个链接查看对应的命令。

当您在终端中时,您必须做的第一件事是更新您的 Anaconda 版本。在这个链接中,你可以找到许多版本的列表。

使用 curl 命令下载 Anaconda 的最新版本。

curl -O [https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh](https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh)

按回车键直到结束。然后,对于许可协议,你得说 yes

当您到达您可以在下面看到的点时,按照第一个指示并按 Enter,或者您可以按照第三个指示并选择一个不同于默认位置的位置。

出局:

Anaconda3 will now be installed into this location:
/home/your_name/anacond - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below[/home/yor_name/anaconda3]>>>

当这个过程完成时,键入 yes 来确认 Anaconda 将被安装的路径。之后,您可以通过以下方式激活您的安装。

source ~/.bashrc

第二部分:创建您的虚拟环境

在这一部分,你必须创建一个虚拟环境。开始之前,请确保您已进入包含您的 web 应用程序文件的文件夹。所以使用这个命令来创建您的环境。

python3 -m venv my_environment

然后,您可以使用以下命令激活它:

source my_environment/bin/activate

现在你在你的环境里。在我个人的例子中,为了实现我的 web 应用程序,我用以下命令安装了 flask、pandas、Plotly 和 gunicorn:

pip install flask pandas plotly gunicorn

第三部分:上传到 Heroku

现在,你需要在这个环节的云平台 Heroku 上注册。

然后,按照以下方式安装 Heroku 的所有命令行工具:

**curl** https://cli-assets.heroku.com/install-ubuntu.sh | sh

使用这个简单的命令登录并应用:

heroku login

你必须输入你的 Heroku 档案的用户名和密码。

下一步是创建一个文件,目的是告诉 Heroku 当你启动你的 web 应用程序时该做什么。在我的文件中,我写下了以下状态:

web gunigorn app:app

然后,指定将要需要的库。因此,您必须将所有信息放在一个名为 requirements.txt 的文件中,该文件允许 Heroku 知道在哪里查找。命令是:

pip freeze > requirements.txt

现在我们必须初始化存储库:

git init .git add .git commit -m 'first commit'

您可以通过以下方式指定您的电子邮件地址和姓名来进行配置:

git config user.email “username@something.com”git config user.name “Your Name”

最后一步是使用以下命令创建您的 web 应用程序。

heroku create name_of_your_web_app

使用以下命令推送文件:

git push heroku master

每次您想要更新 web 应用程序上的数据时,请记住遵循以下简单指示。

使用以下命令进入您的环境:

source my_environment/bin/activate

然后,使用这些命令更新您的数据仪表板

pip freeze > requirements.txtgit add .git commit -m “make some changes”git push heroku master

结论

这是一种简单的方式,允许你拥有自己的数据仪表板,并向世界上的每个人展示你的结果,我认为这是惊人的。

如果你在创建你的 web 应用程序时遇到了一些问题,请随时私信我或在评论中写给我。

我们也可以在我的电报群 初学数据科学中取得联系。

我如何 DIY 我的预算使用 Python 制作硒和美丽的汤

原文:https://towardsdatascience.com/how-i-diyd-my-budget-using-python-for-selenium-and-beautiful-soup-4d2edc5c519?source=collection_archive---------5-----------------------

使用 Python 提取数据以满足您的个人预算需求

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

安妮·斯普拉特在 Unsplash 上的照片

我是个性测试的狂热粉丝。我喜欢通读我的预包装类型描述,我发誓这是我独有的,只有我。我喜欢他们给我的感觉,好像两个心理学家用我自己提供的答案偷瞄了一下我的灵魂。但是我知道不是每个人都同意。对于反对者,不管他们是说主流选项太老套,还是因为它在很大程度上是自我报告而对结果打折扣,我提出:预算类型指数。

对于那些现在希望收到你的个人资料的 pdf 文件的人,我希望当我告诉你这是你必须自己制作的东西时,你不会太失望。好吧,好吧,这不是传统意义上的性格测试,但我确实认为一份精心制作的预算可以告诉你很多关于你自己的事情,如果不是更多的话,就像那些诱人的在线测验一样。

当我开始做这个项目时,我想知道我的钱去了哪里,进而了解我优先考虑的是什么。我以前一直手动汇总我的多个银行账户的所有支出,包括非银行但经常使用的服务,如 Venmo。我一直在寻找一种服务,这种服务不仅可以自动完成这个过程,向我展示我的历史数据,而且不需要每月付费。没有完全符合所有这些标准的东西,所以我用 Python 创建了自己的。

对于其他想衡量和管理自己支出的人来说,收集数据是第一步,也是最重要的一步。我根据我使用的两个工具分解了本文的其余部分:

  1. 美味的汤

如果你想建立自己的预算工具,我很乐意帮助你——尽管我们不认识,但请随时联系 jenniferrkim7@gmail.com!

使用 Selenium 从您的在线银行帐户中删除交易

Selenium 自动化浏览器。最初创建它是为了测试 web 应用程序,现在它也广泛用于 web 抓取。在分解我如何使用这个工具之前,我在下面包含了我的全部代码。

进行设置

你首先需要安装两个软件包。

  • 硒包装

通过在命令提示符下键入以下命令进行安装:

pip install selenium
  • 您正在使用的浏览器的 web 驱动程序

Chrome 驱动程序(这是我正在使用的)可以在这里找到。不同版本的 Chrome 有不同的驱动程序。要了解您使用的版本,请点按浏览器右上角的三个垂直点。这将带您到设置。然后,打开菜单,点击“关于 Chrome”——这将显示你的 Chrome 版本。下载适用的驱动程序,并确保它在您的 Python 路径中。

更全面的安装说明,包括其他浏览器驱动的链接,可以在这里的文档中找到。

尺寸很重要

现在您已经有了必要的包,您可以开始指定驱动程序应该选择的 web 元素。影响这些元素位置的一个因素是窗口的大小。为了获得最大的一致性,我喜欢在启动任何进程之前全屏显示我的窗口。

# from line 8
browser.maximize_window()

定位元件

为了检索交易,我们首先希望 Selenium 登录银行的网站。我们可以通过检查网站的 HTML 页面来确定需要选择哪些元素。要打开页面,请访问网站,并识别登录框。右键单击在线 ID 字段。选择“检查”。

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

您将弹出此元素定位器,并在您选择的字段(在本例中为在线 ID)上高亮显示。

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

Chrome 的 HTML 元素定位器

有八种不同的方法来定位硒元素。这些是由:

  • 名字
elem = driver.find_element_by_name("INSERT-NAME")

这是我决定使用的一个,正如上面截图中画得不好的红圈所示。

  • 身份证明
elem = driver.find_element_by_id("INSERT-ID")

这被认为是最准确的方法,因为每个元素的 ID 都是唯一的。

  • 链接文本

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

elem = driver.find_element_by_link_text("INSERT-NAME-OF-LINK-ON-PAGE")# example if I wanted to select link circled above
elem = driver.find_element_by_link_text("Vote Is Likely to Fall Largely Along Party Lines")
  • 部分链接文本
elem = driver.find_element_by_partial_link_text("DONT-NEED-FULL-LINK")# example if I still wanted to select above NYT link
elem = driver.find_element_by_link_text("Vote Is Likely to Fa")
  • CSS 选择器
elem = driver.find_element_by_css_selector("INSERT-CSS-SYNTAX")

关于 CSS 选择器的好例子可以在这里找到:https://saucelabs . com/resources/articles/selenium-tips-CSS-selectors

  • 标签名称
# referring to an HTML tag. first element with tag is returned.
elem = driver.find_element_by_tag_name("INSERT-TAG-NAME")
  • 类别名
elem = driver.find_element_by_class_name("INSERT-CLASS-NAME")
  • XPath
elem = driver.find_element_by_xpath("INSERT-XPATH")

XPath 是一种用于在 XML 文档中定位节点的语言。当目标元素没有合适的 id 或 name 属性时,这很有用。基本格式如下:

xpath = //tagname[@attribute = "value"]

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

请注意,所有这些方法只会选择它找到的第一个元素。要选择多个元素,请使用相同的方法,但是将单词“元素”替换为“元素”(例如 driver . find elements by _ NAME(" INSERT-NAME "))

输入键

找到 login 元素后,下一步是输入您的凭证。这是通过函数send_keys()完成的。

username = browser.find_element_by_name("onlineId1").send_keys("YOUR-USERNAME")time.sleep(2)password = browser.find_element_by_name("passcode1")
password.send_keys(<YOUR PASSWORD>)

记住不要在任何地方提交密码,以保护自己。

我添加了一个等待,告诉 Selenium 在使用time.sleep()输入用户名和密码之间暂停两秒钟。我发现没有它,Selenium 移动太快,浏览器很难跟上。

我通常会在输入凭据后按“Enter”按钮,所以我想在 Selenium 中做同样的事情。幸运的是,Selenium 有一个标准键盘键列表。在这种情况下,我使用了钥匙。返回:

password.send_keys(Keys.RETURN)

现在你进来了!

要查看是否找到了元素并正确输入了凭据,可以尝试运行代码。一个新的 Chrome 实例将会弹出,你可以看到浏览器自动运行。此实例与您经常使用的浏览器不同。它不包含任何 cookies,并在您完成后消失。因此,如果你确实需要 cookies,你可以在这个网站上查看如何添加它们。

当这个 Chrome 实例将我带到我的银行账户主页时,我可以看到我的代码运行正常。我看到两个链接:一个链接到我的支票账户,另一个链接到我的信用卡。要点击这些链接,我使用find_element_by_link_text并使用click()方法进行选择。

browser.find_element_by_link_text('Bank of America Travel Rewards Visa Platinum Plus - ****').click()

一旦您进入包含您想要的交易的页面,从 web 驱动程序中检索page_source并将其存储在一个变量中。这将用于稍后的解析。

boa_travel_html = browser.page_source

现在剩下唯一要做的就是用你的其他银行账户重复。

iFrames

除了一个讨厌的 iFrame 之外,我在巴克莱的另一个账户也是如此。内嵌框架是一个 HTML 文档,嵌入在网站上的另一个 HTML 文档中。当我收到一个没有找到元素的错误时,我第一次怀疑这可能会妨碍我,尽管我通过它的名字清楚地找到了我想要的元素。幸运的是,Selenium 有一种使用switch_to方法导航到 iFrame 的简单方法。

browser.switch_to.frame(browser.find_element_by_tag_name("iframe"))
browser.find_element_by_name("uxLoginForm.username")

使用与美国银行示例中相同的方法继续检索页面源代码。

无头浏览器

一旦你知道你的代码工作了,你可以通过在下次运行你的程序时去掉弹出的浏览器来加速这个过程。

from selenium import webdriver from selenium.webdriver.chrome.options import Options
chrome_options = Options()

chrome_options.add_argument("--headless")driver = webdriver.Chrome(options = chrome_options)

现在,您已经拥有了所有必要的数据。它可能不是一种可读性很强的格式,但是让它变得可用是 Beautiful Soup 的目的。

美味的汤

美汤是一个解析 HTML 文件的 Python 包。现在我们已经有了必要的 HTML 页面,我们可以使用 Beautiful Soup 来解析它以获得我们需要的信息。同样,在深入下面之前,我已经完整地包含了代码。

漂亮的汤函数解析 HTML 银行交易页面

解析交易信息

是时候检查您之前检索的 HTML 页面了。因为混乱的纯文本页面是如此的…混乱,我选择了通过源本身来导航 HTML,通过右击银行网站上的每个交易并选择“Inspect”这突出显示了 web 页面元素检查器中的事务(之前使用 Selenium 来标识登录框)。

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

Chrome 的网页元素检查器

我想要收集的数据包括日期、交易描述和金额。如上所述,这些信息被嵌套在父“tr”标签内的多个“td”标签中。我使用了[find](https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find)[find_all](https://www.crummy.com/software/BeautifulSoup/bs4/doc/#find-all)函数的组合来沿着树移动,直到到达包含我想要的文本的标签。下面的片段是我如何检索日期的。

# narrowed down to largest parent container 
containers = rows.find_all(‘tr’, class_ = [‘trans-first-row odd’, ‘trans-first-row even’, ‘even’, ‘odd’]) dateli = [] 
descli = [] 
amtli = [] 
pending_counter = 0 for container in containers: 
    date = container.find(‘td’, headers = ‘transaction-date’)            .          .get_text(strip=True)

由于如何使用 Beautiful Soup 是针对您正在查看的网页而言的(正如我为检索到的每个页面创建的独立函数所证明的那样),因此我不想一行一行地运行我的代码,而是想指出我发现的不规则之处和有趣的花絮,以帮助您尽可能高效地完成整个过程。

类是类 _

所有漂亮的汤find函数都以 HTML 属性作为关键字参数。虽然这对于大多数属性来说非常简单,但是在 Python 中,由于class是一个保留关键字,所以您可以使用class_来表示它的 HTML 对应物。

containers = rows.find_all(‘tr’, **class_** = [‘trans-first-row odd’,    ‘trans-first-row even’, ‘even’, ‘odd’])

soup.find()中的 Lambda 函数

find函数也可以将其他函数作为参数。要快速找到符合多个标准的特定标签,请尝试插入一个 lambda 函数。

*# Example 1*
rows = boa_travel_table.find(**lambda** tag: tag.name=='tbody')*# Example 2*
boa_checking_table = boa_checking_soup.find(**lambda** tag: tag.name == 'table' and tag.has_attr('summary') and tag['summary'] == 'Account Activity table, made up of Date, Description, Type, Status, Dollar Amount, and Available balance columns.')

示例 1 非常简单。我也可以不用 lambda 函数来找到相同的元素,使用如下代码:

rows = boa_travel_table.find('tbody', class_ = 'trans-tbody-wrap')

示例 2 是 lambda 函数真正大放异彩的地方。通过结合多种标准并使用 Python 的has_attr *,*我搜索我想要的东西的能力成倍增加。lambda 有用性的另一个好例子(以及对 lambda 的解释!)可以在这里找到,作者在这里取 Python isinstance函数进行美汤搜索。

美汤的文字 vs .字符串

在上面我漂亮的 Soup 代码的第 8-19 行中,我将标签(或者我喜欢称之为容器)缩小到最大的一个,它包含了我想要为每笔交易提取的所有三条信息(日期、描述、金额)。为了从这些深入的容器中提取数据,我使用了soup.tag.get_text()

date = container.find('td', headers = 'transaction-date').**get_text(**strip=True**)**

如果你通读了漂亮的 Soup 文档,你可能已经看到过用soup.tag.string来代替提取文本。这是我第一次使用的功能,但我很快发现它在这种情况下不起作用。soup.tag.string只返回一个NavigableString类型的对象,该对象必须是标签中的唯一对象。

另一方面,soup.tag.get_text()可以访问它的所有子字符串(即使它不是直接子字符串)并返回一个 Unicode 对象。因此,如果您想要提取的文本数据存在于一个子标签中(您可以在下面的截图中看到td标签中的a标签),您应该使用soup.tag.get_text()

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

嵌套标签使得有必要使用soup.tag.get_text()

如果你喜欢稍微干净的代码,你也可以使用soup.tag.text *。*它调用get_text(),基本上做同样的事情,但是我更喜欢原来的get_text(),因为它支持关键字参数,比如分隔符、条带和类型。对于这个项目,我包含了strip=True作为关键字参数,从文本中去除任何空白。

结论

现在,您可以通过运行一个程序从数据源中检索所有财务数据。这是你开始创建自己的预算类型指数,并通过你的消费习惯找到更多关于你自己的信息。出发去收集你的数据点,成为你自己最好的金融版本!

我如何设计我的抓取数据

原文:https://towardsdatascience.com/how-i-engineered-my-grab-rides-data-f115b4257aea?source=collection_archive---------53-----------------------

快乐的数据工程师之旅

隐藏数据的 ETL(提取-转换-加载)

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

Unsplash 上由 Carlos Muza 拍摄的照片

世界上谁是谁?

作为一名在马来西亚的外国人,我需要利用现有的交通设施在全国各地旅行。马来西亚的公共交通设施确实非常好,只要你待在它们附近。默认情况下,这将是一个比更远的地区更昂贵的地方。

我的问题是从我工作的地方到经济适用房区的路线离公共交通有点远。所以,我需要坐出租车或者步行 30 分钟。在马来西亚散步挺好的,只要不下雨就行(吉隆坡总是下雨)。

作为一名技术人员,我直接决定使用现有的技术来解决我的问题,在这种情况下,没有什么比拼车服务更有帮助的了。

我的选择标准

我在 2016 年来到马来西亚,当时只有两家拼车服务提供商,Grab

对我来说,两者都是新的…我考虑的几个因素是:

  1. 司机离我的位置有多远?(我不想上班迟到)
  2. 我应该为服务支付多少?(我还没那么有钱)
  3. 是双赢吗?(这是一项共享服务)

所以,我在选择过程中的标准很简单,都是基于我作为一个新来的外国人在一家不提供弹性工作时间的小 IT 公司工作的情况。没错,我在早高峰时间去办公室,在晚高峰时间离开。(亲爱的 CEO 们,那让你们的员工压力很大!)

为什么我选择抢优步?

有几个原因导致我在马来西亚逗留期间决定选择 Grab 而不是优步**。这并不意味着优步不好或什么,但我的生活方式和我作为顾客的角色与 Grab 的关系比优步更密切。**

  1. 与优步相比,那里有更多的临时司机,这使得在高峰时间比优步更容易获得临时搭车服务……与花同样多的时间等待司机来接我相比,我绝对更愿意等待指定的司机来接我。
  2. 在我开始旅行之前,我就知道我要付多少钱…这正是我喜欢的付款方式。与此同时,优步给你看了估计的总付款额,而这个比率会根据许多因素而变化。交通堵塞,下雨,司机慢,走错路,汽油价格也变了!使用 Grab,它从一开始就给了我应该支付的确切费用,没有什么取决于其他因素,这对于像我这样的中产阶级用户来说是完全可取的……这就像是“这是交易,接受它或离开它”由您决定。
  3. **Grab 是()总是比优步便宜,当两个城市都在这个城市的时候…有时我想如果 Grab API 检查了优步 API 上的票价,那么它显示便宜 10%的票价…我 t 只是一种感觉,没有任何证实!为什么我要为同样距离和同样时长的同样服务支付更多费用?

我回答了我的主要选择标准,这也说明了当时我为什么更喜欢 Grab 而不是优步…直到 GrabMalaysia 买了优步的牌照!在那之后,情况完全不同了…根本没有竞争或基准… Grab 控制一切…

数据

现在,在马来西亚生活了四年,平均每天使用 Grab Ride 服务,我有足够的数据来了解我在交通上的支出。

我是怎么得到数据的?

不幸的是,Grab 并没有以直接的方式提供关于您的旅行和费用的报告,它只是给你发了一张最近旅行的收据,但他们没有发送你的使用和支出的每周或每月摘要…所以,如果你想知道你在 Grab Rides 服务上总共花了多少钱,没有直接的方法。

过去有一种方法可以知道你在过去 179 天(过去 6 个月)的旅行细节,从https://hub.grab.com/可以让你检查和下载你最近的旅行…所以,如果你知道那个网站,你可以很好地了解你的费用…在撰写本文时,Grab 不再提供这项服务。我试图在 2020 年使用相同的网站,但已经不可能了。它重定向我创建一个商业帐户(我已经有了),并显示应用程序本身的摘要。

但这不是我获取数据的方式…

我是如何收集数据的

作为一名数据工程师**,我工作的一部分就是找到一种聪明的方法来收集分析过程所需的数据。现实生活中的数据分散在各处,不容易被提取出来并以直接的格式使用。再加上我对解决方案架构的热情(我是一名认证的 AWS 解决方案架构师——这是我最初作为爱好学习的。从未在使用 AWS 服务的公司工作过,自学成才)**

收集我的抓取行程数据的关键点是我的电子邮件。我将我的电子邮件帐户与我的 Grab 帐户连接起来,因此我收到了我使用 Grab 应用程序完成的大多数活动的电子邮件。

只要我在电子邮件中收到收据,我就可以处理所有电子邮件,以提取从第一次旅行到现在的交通数据。电子邮件通常包含:

  • 出发点
  • 下车点
  • 票价
  • 跳闸时间

数据析取

有两种方法,批处理和流。

定量

  • 您可以存档和下载从 Grab 收到的所有电子邮件。
  • 您将拥有一个 MBOX 文件,您可以使用适当的库来处理它。
  • 我在 Apache Beam 的支持下使用 Python 来进行转换。
  • 将提取的数据存储到 CSV 文件中
  • 使用你的可视化工具可视化你的数据(我使用谷歌数据工作室)

流动

流媒体是一个更加实时的过程,可以让你更深入地了解你正在跟踪的内容。对于数据工程师来说,拥有一个流管道总是比安排修补作业更高级。在我实现了修补技术之后,我决定使用 AWS 服务将它全部转换成一个无服务器的流过程。

这是我的架构

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

我的架构使用 AWS 服务

我将这封邮件重定向到 AWS SES (简单邮件服务)

邮件将被发送到 S3 下的存储桶中(简单存储服务)

当一个新的电子邮件文件被添加到桶中时,一个λ函数被触发来处理该文件

Lambda (无服务器功能)将解析邮件文件,并提取所有数据。

它提取:

  • 收件人的电子邮件地址
  • 旅行的日期和时间。
  • 提货点
  • 目的地
  • 旅行费用

然后 Lambda 函数将这些数据存储在 DynamoDB 表中(如果需要,也可以存储在任何 RDP 中)。

然后,可视化工具或报告工具从数据库表中获取这些数据,并在我的仪表板中将其可视化。

可视化

图表总是给出你想知道的大画面。业务分析师总是提供图表来传递聚合信息。一张图胜过百万字。

以下是 2017 年上半年我从工作单位到公寓的行程。

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

以下是 2018 年上半年从我的工作场所到我的公寓的同一趟旅行的代表。

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

你可以注意到,与 2017 年相比,接送点服务得到了增强,变得更加准确,这一点很明显,因为我们在寻找司机时变得不那么费劲了。

这是我 2017 年在一整年的消费总额。****

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

这是我 2018 年在一整年的消费总额。****

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

还有我 2019 年一整年的消费总额。****

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

当你回顾和检查你的长期支出时,你可以很容易地做出很多决定:

我应该买辆车吗?

我应该使用公共交通工具吗?

真的是双赢吗?

与去年同季度相比,我现在多付了多少钱?

票价随时间变化了多少?

挑战

源格式更改

在那段时间里, Grab 多次更改了他们的电子邮件格式。这要求我多次更新我的 Lambda 函数代码,并重新部署它来处理新旧格式。所有的数据工程师都有同感;当源模式改变时,您会发现一些不匹配和错误。

出发点

当然,我是从批处理开始的。我下载了电子邮件,并在我的本地机器上进行处理。

然后我创建了一个 Chrome 扩展,直接从邮件中提取数据。然后,扩展向 AWS APIGateway 发送 API 请求,后者将数据重定向到 Lambda 函数。Lambda 随后将数据插入到 DynamoDB 中。

这不是动态的,因为我需要打开邮件并运行扩展来解析邮件并确认将数据发送到端点。

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

我的架构使用 Chrome 扩展作为数据源

错误的选择

我启动了我的流进程,将数据存储到一个 DynamoDB 表中。这个决定是基于在 DynamoDB 上创建一个表并使用 boto 库向其中接收数据是多么简单。但是,在向表中添加数据几个月后,我后悔在这个应用程序中使用它,尤其是在检索数据时。我知道模式,我知道我想要存储什么,并且我对它有完全的控制权,这都意味着一个 rational 数据库应该更好。我觉得极光无服务器应该是更好的选择。

最后一句话

数据提取过程并不容易。我们周围的数据通常不是为了提取而是为了呈现。当数据工程师开始工作时,有些问题需要回答:

  • 我需要提取哪些数据?
  • 如何提取数据?
  • 我需要对这些数据进行什么样的转换?
  • 我将在哪里存储数据?

回答这些问题将引出下一层次的问题,这些问题集中在他/她的解决方案的体系结构上:

  • 提取的最有效方法是什么?
  • 用什么来做转化?
  • 如何以最有效的方式存储数据以备将来使用?

总有更多的问题会出现在你的路上,让你的旅途更有乐趣。享受数据之旅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值