TowardsDataScience 博客中文翻译 2016~2018(二百二十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 NLP 模型预测产品成功

原文:https://towardsdatascience.com/predict-product-success-using-nlp-models-b3e87295d97?source=collection_archive---------9-----------------------

预测时尚电子商务下一个趋势的教程

先决条件

特定主题的经验:新手

专业经验:无行业经验

机器学习的知识不是必需的,如果读者熟悉基本的数据分析会有所帮助。文章中的所有概念都是为初学者从头开始详细解释的。要跟进,请在此下载样本数据集。本教程解释了自然语言处理的商业应用,以获得可操作的见解。

自然语言处理和商业用例介绍

在线上常见的自然语言处理(NLP)的一个非常简单的定义是,它是对自然形式、书面文本或语音中使用的语言应用计算技术,以分析并从中获得某些见解。这些见解可以有很大的不同,从理解一段文字中的情感到识别句子中的主题。

分析的复杂程度也可能从简单到非常复杂。例如,你可能想将文本分类,比如来自 Twitter 的数据,分为正面情绪和负面情绪。另一方面,您可能希望从大型数据集中的产品评论数据中提取产品建议/投诉,以确定新产品发布策略。聊天机器人正在做的工作,理解文本查询并对其做出回应;垃圾邮件检测等。属于 NLP 的范围。

这个领域可能包含许多应用程序,因此也包含许多技术,这使得它成为一个相当大的主题。在这个特别的教程中,我们将详细讨论 NLP 的商业案例应用,以获得电子商务领域中实用且可行的见解。

了解业务场景

本教程使用了 Kaggle 上的一个数据集,来自电子商务时尚领域。这可以在https://www . ka ggle . com/nica potato/women-ecommerce-clothing-reviews找到

这个数据集似乎是大多数电子商务市场的典型,因此它是一个很好的代表。这是一个数据集,其中有数字评级数据以及对几件女装的文本评论。这些商品有一个“服装 ID ”,这是一个唯一的标识符。有两种评级——数字 1 到 5 表示产品评级,1 或 0 表示是否推荐产品,二项式属性,即只有两个可能的值。还有其他描述项目类别、评论者年龄等的属性。仔细想想,该数据集中提供的这些属性是大多数此类在线购物门户的典型特征。事实上,这并不仅限于时尚领域,因此这里应用的技术也应该可以扩展到其他领域。

有了这个数据集,探索文本评论是否可以预测该项目是否会成为趋势将是有趣的。这对时装业来说是非常有用的信息。如果这种对产品的洞察是准确的,产品或品类经理就可以对产品的库存策略、促销等做出合理的决策。这是我们的业务问题。

因此,我们的目标是建立一个自动化系统,可以分析客户对新产品最初的一些评论,并预测新推出的产品是否会成功。有了这些信息,就可以建立产品库存,并通过供应链进行销售。通过这种方式,人们可以实施软产品发布,并响应市场对产品的接受度。

本实验使用的两个工具是 Excel 和 Rapidminer。这个工作流程有两个部分。首先在 excel 中执行一些功能工程,然后在 Rapidminer 中执行实际的模型训练和测试。

第 1 部分:Excel 中的特征工程

有了给定的数据,我们需要首先得出“趋势产品”的数学定义。在这个阶段,业务领域的知识就派上了用场。我们知道,如果一个产品做得很好,如果客户对它满意,他们会努力写关于它的正面评价。人们通常倾向于写详细的评论,如果他们非常高兴或者非常不满意。如果他们开心,他们倾向于写好的评论,并给予高度评价。此外,做得好的产品会得到很多评论,大多数评论者会对评级高的产品有类似的看法。

用数学方法来解释。产品的成功与评论数量、产品的平均评级有直接关系,与产品评级的标准偏差有反比关系。也就是说,如果市场喜欢它,许多客户往往会在没有太大变化的情况下给予它很高的评价。基于这种理解,我们可以创建一个新的特征。

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

借用在神经网络训练中使用的 tanh 激活函数,我们可以如下定义新的特征“评级强度”。

【评级强度=(评级因子)

在哪里,

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

其中,“评论比例”是项目从完整数据集
收到的评论的比例,平均值和标准差不言自明。

这将创建一个值介于 0 和 1 之间的新要素。接近 1 的值被分配给有大量评论、评级良好且评级差异非常低的项目,即每个人都给它评级良好。更接近 0 的值被分配给没有产生太多兴奋的项目-评论的数量很少,并且评级很低,差异很大。这个数学定义的主要目的是获得一个代表产品成功的数字特征,最好是 0 到 1 之间的值,而不是未缩放的大值。

这样,您可以创建一个名为“Item_success”的二项式标签,其中有两个可能的值“trending”或“Not trending”,其中“Trending”被分配给评级强度高于某个临界值的项目,而“Not trending”被分配给低于该临界值的项目。对于这个数据集,我选择了临界值 0.00036。这个截止值是通过简单地查看数据集来确定的,但是可以有更好的自动化方法来完成这个任务。然而,这种手动决策是一种非常简单快捷的解决方案。对于使用这些产品的人来说,这是一个相当直接的决定。下面是数据集的一个片段。

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

Feature engineered dataset (snippet)

根据可用要素在数据集中创建新要素的过程称为要素工程。这是一个有用的步骤,可以部署到机器学习问题。到目前为止,所有的活动都是在 Microsoft Excel 中进行的。下一步是开发一个模型来预测我们创建的这个二项式标签。预测建模部分在 Rapidminer 中进行。

第 2 部分:Rapidminer 中的预测建模

设置

这一部分是在 Rapidminer 中进行的。问题基本上是语言处理。给定一个新的评论,我们希望预测该项目是否会成为趋势。在评论的语言中肯定包含了一些信息,这些信息可以提供该项目是否会成功的线索。给定过去的数据,我们应该能够预测正在审查的新项目。

本质上,我们需要使用过去的数据来建立一个模型,该模型可以从已知成功产品的评论语言中学习,并在未来产品的新评论中使用这种学习来预测其成功的机会。

Rapidminer 中使用的工艺流程如下所示:

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

Model training in Rapidminer

Rapidminer 是一个非常易于使用的机器学习平台,非常适合业务经理,他们可能不是数据科学家,但热衷于将这些技术快速应用于他们的业务需求。在 Rapidminer 中,通过将相关操作符拖放到工作空间中,并以图形方式连接输入数据,即可轻松执行每项操作。在上图中,您可以看到每个阶段的数据流和处理过程。

让我们来看一下上面使用的每个运算符:

1.检索:我们首先需要检索我们在第 1 部分中创建的数据集。为此,我们可以读取 excel 文件本身,或者首先将数据导入 Rapidminer,然后访问它。在这种情况下,我们采取的是后者。首先必须导入数据,这非常简单,有一个向导可以一步一步地进行导入,您可以通过单击 Rapidminer 中的“添加数据”按钮开始导入。在 Retrieve 操作符的设置中,我们定义了要访问的数据集的名称,该名称是在导入过程中定义的。

2.示例:数据集包含近 19500 行。但是我们不想使用完整的数据集。这将耗费时间,并可能导致过度拟合。因此,在样本运算符中,我们可以定义要选择多少样本。我选择了 4500 个样品。

3.设置角色:我们需要定义哪个特征是我们感兴趣的,我们想要预测的。对于我们来说,它是“Item_success”列,我们将此功能定义为标签*。标签是需要预测的特征。*

4。 选择属性:在我们的数据集中,我们定义了新的列,如平均评分、评分的标准差、评论的比例等。以达到“项目成功”特征。从将被提供来训练模型的训练数据中移除这些特征是非常重要的。这一点非常重要。这些列将不可用于未来的实时数据,在此包含它们可能会给出错误的准确性级别,并且模型在部署中将不起作用。您可以浏览 excel 文件来更好地理解这些列。所以实际选择的特性如下:
年龄
类别名称
部门名称
部门名称
项目 _ 成功
评分
推荐 IND
审核文本
标题
这些特性在部署时都可以用于新数据。

5。 名义到文本:这是一个数据类型转换器。我们用它将评论文本转换成文本数据类型。这对于流程中的下一个操作员是必要的。

6.处理文档:这是此类文本分类应用的关键步骤。这是一个嵌套运算符,即该运算符中有一个流程,如下所示:

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

Process flow to generate n-Grams

它将文本分解成符号化的 n 元文法,这里 n 被设置为 2。这些 n 元语法成为单词包的一部分,模型稍后使用该单词包来理解评论中的单词和标签特征之间的关系。对文档进行分词,提取词干并过滤掉停用词(如 a、an 等。)都是标准做法。词干标记都转换为小写,我们过滤掉少于 5 个字符或多于 25 个字符的标记。最后,生成 2 个字母的单词,形成一大袋短语。这是模型学习的主要数据。

7.存储:存储操作符用于存储流程文档步骤生成的词表。在对新数据应用学习模型时,必须使用这种方法。这是需要记住的重要一点。

8。分割验证:下一个任务是训练和测试模型。拆分验证运算符用于此目的。这也是一个嵌套操作符。它将数据分为训练数据和测试数据,并对测试数据使用训练好的模型。该运算符的内部流程如下所示:

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

Split validation sub-process

这里使用了梯度增强树,再次使用如上所示的存储操作符来存储训练的模型以供将来使用。应用模型操作符对数据的测试部分应用训练模型,性能二项式分类操作符用于测量模型对测试数据的性能。性能运算符生成一个 2x2 表,其中包含模型预测的分类和实际分类的详细信息。

培训和评估

在 Rapidminer 中设置流程后的下一个阶段是尝试各种模型,看看什么能产生好的结果。这是你实际训练你的机器学习模型的部分。

有几种算法可以尝试。从 k-NN 这样的简单模型开始通常是很好的做法。k-NN 技术是最简单的可能模型,可以用于几乎所有的机器学习问题。这有助于您建立一个好的基准,然后您可以根据它来尝试更高级的技术。使用 Rapidminer,只需用您选择的任何其他预测模型替换上图所示的梯度增强树模型,只需右键单击运算符并选择替换即可。当然,不是所有的模型都适用于所有的情况。有些模型只接受数字数据。这个阶段最好的方法是试错,通过实践,事情会变得清晰。

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

Replacing an operator for trials

k-NN 模型获得的结果如下所示。

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

k-NN results

继续该过程,尝试了以下模型,这些模型的相应结果在下面给出。

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

Naive Bayes results

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

Decision Tree results

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

Random Tree results

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

Gradient Boosted Trees’ results

梯度推进树(GBT)给出了所有试验模型的最佳结果。对整个数据集的子集进行了反复试验。现在,我们可以重复使用学习过的 GBT 模型,并将其应用于整个数据集,并检查结果如何。检索存储的 GBT 模型和相关单词列表的过程如下所示,重要的是使用在模型训练期间生成的相同单词列表。该步骤有助于检查学习的模型没有过度拟合训练数据;如果它确实过拟合,那么它对于实时应用将不是非常有用。以下流程也可用于将学习到的模型应用于新数据,即在生产中使用该模型——只需用新数据替换第一个操作符,其他一切将保持不变。

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

Applying the learnt GBT model to the full dataset

较大数据集的 GBT 结果如下所示:

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

GBT results for wider dataset

能够预测这样的产品的成功机会在计划库存和分销中非常有用。也许可以预测不同人口统计和地理位置的成功率,这对规划正确的产品分销非常有用。与任何模型一样,通过与实时数据并行运行来进一步测试它以进一步优化模型的准确性是非常重要的。这种应用清楚地显示了这种技术的效用,并且它们的普及只会增加。

一旦经过训练的模型和单词列表被存储,它可以被重新用于新数据的应用。这将涉及以与训练数据相同的格式获得新产品的审查和评级数据,并在上述应用学习的 GBT 模型的过程中,用新数据替换第一个操作员。运行这个过程,看看预测是什么。处理各种产品的品类经理可以以设定的频率运行这一过程,系统将帮助他在几分钟内找到正确的方向。当然,也有方法将预测数据输出到 excel 文件中,该文件可以分发给团队,以帮助他们对产品的供应链方面做出决策。

仍然有办法进一步改进这个系统。也许不需要用数学方法来定义成功的产品,如果可以挖掘出提供产品实际成功或失败的数据,准确性就可以提高。在本教程中,我们创建了一种基于可用数据的技术,人们甚至可以尝试不同的方法来获取丰富的数据,知道可以使用的工作流,这也需要一些工作来实现这样的数据创建和收集,但可能是最准确的。预先了解数据将如何使用以及机器学习系统如何使用 NLP 工作,对于设计数据收集和准备过程非常有用。

总之,我们已经实现了一个基于 NLP 的快速模型,它根据产品的文本评论来预测产品的成功几率。这样的系统可以帮助品类经理处理大量的产品和 SKU。将模型应用于新数据所消耗的时间仅仅是几分钟甚至几秒钟的事情,这可以被高频率地利用。Rapidminer 流程、数据集和结果可从这个 Github 存储库获得。

使用机器学习预测在线零售商的搜索相关性

原文:https://towardsdatascience.com/predict-search-relevance-using-machine-learning-for-online-retailers-5d3e47acaa33?source=collection_archive---------4-----------------------

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

Photo credit: Unsplash

高质量的搜索就是返回相关的结果,即使数据在变化或结构不良,查询也不精确。

大型在线零售商通常使用基于查询的搜索来帮助消费者在其网站上找到信息/产品。他们能够利用技术为用户提供更好的体验。因为他们知道搜索相关性的重要性,而且长时间和/或不成功的搜索会让他们的用户离开,因为用户习惯于并期待即时的相关搜索结果,就像他们从谷歌和亚马逊得到的一样。

似乎产品搜索只在亚马逊有效。例如,键入搜索术语“淋浴专用水龙头”,一种水龙头,我得到我正在寻找的。

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

Source: Amazon.ca

尽管搜索对任何电子商务业务的成功都至关重要,但它并不总是像看起来那么容易,尤其是对中小型在线零售商而言,因为它通常需要大量人工标记的数据和机器学习技术。

高质量的搜索就是返回相关的结果,即使数据在变化或结构不良,查询也不精确。我们今天要做的是:只给定原始文本作为输入,我们的目标是预测产品与家得宝网站搜索结果的相关性,从而帮助他们改善顾客的购物体验。我们开始吧!

数据

该数据集包含了家得宝网站上的大量产品和真实顾客搜索词。为了创建基本事实标签,家得宝将搜索/产品配对众包给了多个人工评级机构。我们将从 Kaggle 下载三个表格:

  • 训练集 train.csv 包含产品、搜索和相关性分数。
  • 包含每个产品的文本描述。
  • attributes.csv 提供了关于产品子集的扩展信息。

这三个表包含以下数据字段:

  • id,一个唯一的 Id 字段,表示一个(搜索术语,产品 uid)对。
  • product_uid,产品的 id。
  • 产品标题,产品标题。
  • product_description,产品的文本描述(可能包含 HTML 内容)。
  • search_term,搜索查询。
  • 相关性,给定 id 的相关性评级的平均值(我们将为给定的搜索词预测的特征)。
  • 名称,一个属性名称。
  • 值,属性的值。
import numpy as np
import pandas as pd
from nltk.stem.porter import *
stemmer = PorterStemmer()
import re
import randomrandom.seed(2018)df_train = pd.read_csv('train_depot.csv', encoding="ISO-8859-1")
df_pro_desc = pd.read_csv('product_descriptions.csv')
df_attr = pd.read_csv('attributes.csv')

对于属性表,我们只对品牌名称感兴趣,因为有时查询包含品牌名称。然后我们通过“product_uid”合并这三个表。

df_brand = df_attr[df_attr.name == "MFG Brand Name"][["product_uid", "value"]].rename(columns={"value": "brand"})
df_all = pd.merge(df_train, df_pro_desc, how='left', on='product_uid')
df_all = pd.merge(df_all, df_brand, how='left', on='product_uid')

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

Figure 1

文本预处理

在应用任何机器学习 NLP 算法之前,文本处理是一个重要的阶段。虽然文本处理在技术上可以在特征生成过程中完成,但我想先进行所有处理,然后再进行特征生成。这是因为相同的处理过的文本被用作输入来生成几个不同的特征。在我们的数据集中,有几个方面的文本处理。

  • 搜索词拼写纠正。我们将使用来自 Kaggle 论坛的谷歌词典
df_all['search_term']=df_all['search_term'].map(lambda x: google_dict[x] if x in google_dict.keys() else x)
  • 统一单位。
  • 删除特殊字符。
  • 词干文本
  • 标记文本

str_stem

我们将对所有文本特征应用 str_stem 函数。

df_all['product_title'] = df_all['product_title'].apply(str_stem)
df_all['search_term'] = df_all['search_term'].apply(str_stem)
df_all['product_description'] = df_all['product_description'].apply(str_stem)
df_all['brand'] = df_all['brand'].apply(str_stem)

之后,我们的文本看起来干净多了。

a = 0 
for i in range(a,a+2):
    print(df_all.product_title[i])
    print(df_all.search_term[i])
    print(df_all.product_description[i])
    print(df_all.brand[i])
    print(df_all.relevance[i])
    print()

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

Figure 2

特征生成

任何机器学习项目中最重要也是最耗时的部分是特征工程。在我们的例子中没有例外,特别是,我们的主要数据是文本。新创建的特征可以分为几类:

  • 计数特征:查询长度、标题长度、描述长度、品牌长度、查询和标题之间的共克数、查询和描述之间的共克数、查询和品牌之间的共克数。

例如,查询是“仅淋浴龙头”,相关联的产品标题是“铬制 Delta Vero 1-手柄仅淋浴龙头装饰套件(不包括阀门)”,相关联的产品描述是“用铬制 Delta Vero 单手柄淋浴龙头装饰套件更新您的浴室”。它具有时尚、现代和简约的美感。多选择通用阀将水温保持在+/-3 华氏度范围内,有助于防止烫伤。加利福尼亚居民:参见 65 号提案信息仅包括阀内件套件,粗进套件(R10000-UNBX)单独出售包括手柄即使在系统其他地方打开或关闭阀门时,也能保持冷热水压力平衡。由于纽约州的水感法规,请确认您的运输邮政编码没有被限制使用不符合水感要求的物品。

在本例中,整个查询只在产品标题中出现过一次,而没有在产品说明中出现。

在同一个例子中,在查询中出现的三个单词也出现在产品标题中,因此,在查询和产品标题之间有三个共同的单词。在查询中出现的两个词也在产品描述中出现,因此,在查询和产品描述之间有两个共同的词,等等。

  • 统计特征:标题长度与查询长度之比、描述长度与查询长度之比、标题与查询常用字数与查询长度之比、描述与查询常用字数与查询长度之比、查询与品牌常用字数与品牌长度之比。

为了创建新的特性,我们需要创建几个函数来计算普通克数和普通整词数。

str_common_whole_word

接下来是新功能的创建过程:

feature_generation

df_all.drop(['id', 'product_uid', 'product_title', 'search_term', 'product_description', 'brand', 'product_info', 'attr'], axis=1, inplace=True)

删除我们不再需要的列后,下面是我们将要开发的功能:

df_all.columns

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

Figure 3

模型

在文本处理和特征工程之后,训练/预测将变得快速和容易。

from sklearn.model_selection import train_test_splitX = df_all.loc[:, df_all.columns != 'relevance']
y = df_all.loc[:, df_all.columns == 'relevance']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

随机森林回归

random_forest_regression

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

Figure 4

岭回归

ridge_regression

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

Figure 5

用于回归的梯度增强

gradient_boosting_regressor

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

Figure 6

Xgboost 用于回归

Xgboost_regressor

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

Figure 7

XGBoost 库提供了一个名为plot_importance()的内置函数,用于绘制按重要性排序的特性。

from xgboost import plot_importance
plot_importance(xgb);

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

Figure 8

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

参考:卡格尔

预测 Instagram 上的赞数

原文:https://towardsdatascience.com/predict-the-number-of-likes-on-instagram-a7ec5c020203?source=collection_archive---------1-----------------------

在本文中,我们将展示我们预测 Instagram 帖子点赞数的方法。我们首先回顾一下如何收集数据集和分析数据。然后,我们将提供一个基本模型,而不用使用 XGBoost 查看图像。下一步,将使用自然语言处理(NLP)来提取一些特征。最后,卷积神经网络(CNN)被开发用于从图像中提取特征。

Github 链接:https://github.com/gvsi/datascience-finalproject

一、动机

  • **目标:**预测给定 Instagram 帖子的赞数。
  • 背景:社交媒体影响者从数字营销商那里获得报酬,以推广产品或服务。
  • **应用:**使用在线营销中开发的模型来寻找对给定帖子产生最多印象的影响者。

举一个这样的帖子的例子,这个有影响力的人正在旅行,在这张照片中,她放置了一种产品,一种除臭剂,很可能是公司为此支付的。

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

Post by Léa Camilleri: https://www.instagram.com/p/BRNlFUBAG5i/

2。数据

构建数据集

与项目相关的挑战之一是为我们正在处理的用例聚集足够的相关数据。

建立数据集的第一步是收集 Instagram 影响者的名单,也就是说,作为职业的一部分,用户会发布营销 Instagram 帖子。

找到这类信息本身就是一个挑战,因为这类名单不容易被公众获得。

最终,我们遇到了 Inconosquare 指数影响者,这是一个由 2000 多个 Instagram 影响者组成的列表。这个索引可以在https://influence.iconosquare.com上找到。

我们不得不爬取 70 多页的影响者,以获得他们在可用列表中的句柄。

现在真正的挑战来了:搜集这些用户的 Instagram 资料。这包括从个人资料中读取元数据(关注者/跟随的数量,帖子的数量,个人资料的描述),从用户那里抓取 17 个最新的图像(JPG 格式的图像,喜欢的数量,评论的数量,时间戳,描述文本)。

最终结果是每个用户的 JSON 文件,如下所示:

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

JSON file obtained for a given user

刮刀

Instagram 的 API 对其后端服务器的请求限制为每小时 60 个,这使得它对任何真正的应用程序或数据收集完全无用。官方 API 的替代方法是以编程方式抓取每个页面。

我们使用的 scraper 是用 Selenium 编写的,Selenium 是一个旨在为 web 应用程序构建功能测试的框架。Selenium 在这种情况下用于抓取网页并从中收集数据。

scraper 最初线性扫描用户的最新帖子,然后打开每个帖子来检索与每个图像相关的更细粒度的信息。

下面是铲运机的运行演示:

Scraper in action

收集了来自 972 名 Instagram 影响者的 16539 张图像来训练和测试我们的模型。

数据集分析

关于所收集数据的一些简要数据指标。我们可以看到,点赞数有一个很高的标准差,61 224.20。看起来差距很大,平均值为 24 416.38,但 75%的帖子的赞数少于 18 359。

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

Dataset summary

下面的直方图证实了表中显示的值,大多数帖子的赞数都低于 20 万。在我们感兴趣的应用程序中,删除拥有大量关注者(超过 1 00 万关注者)和高平均点赞数(超过 20 万)的人是有意义的,因为他们不再被视为有影响力的人,而是名人/明星。这也将有助于减少我们模型的误差。

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

我们过滤了我们的数据集,只保留平均点赞数低于 20 万的 Instagramers,并且他们的粉丝必须少于 1 00 万。经过筛选,我们保留了 746 个 Instagramers,对应 12678 个帖子。点赞数的标准差下降到 9999.27,均值下降到 8306.93。上图右侧显示了点赞数量的直方图。

关注者数量不一定意味着影响力大

我们绘制了点赞数和关注数的图表。

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

有增加的趋势,但是,不显著。它似乎有很多噪音。仅关注者的数量可能不是预测给定帖子的点赞数量的好指标,因为我们可以看到,拥有大量关注者的人不一定有大量的点赞。

3.模型

我们将首先开发一个基本模型,其中包含从数据集获得的一些基本特征。然后,我们将添加从自然语言处理(NLP)获得的特征,最后,添加从卷积神经网络生成的特征。

为了比较不同的模型,我们将使用两个性能指标:均方根误差(RMSE)和 R 值。

A .基础模型

基本模型包括以下特征:

给定功能:

  • 关注者数量
  • 下列数量
  • 员额数

提取的特征:

  • 网站:我们将用户描述中提供的网站分为不同的类别:Youtube、脸书、Twitter、博客、音乐和其他。然后我们对不同的类别进行一次性编码。
  • 星期几:使用每个数据贴的数据,我们对星期几进行了热编码

生成的特征:

  • 平均点赞数:我们观察到,关注者的数量不一定会产生高点赞数。不活跃和虚假的追随者会影响结果,一个更好的衡量标准似乎是每个用户的平均点赞数。其余的功能应该根据平均点赞数来增减点赞数。

从生成的特征中,我们发现:

网站

11%的用户拥有 Youtube 频道或视频作为他们的网站,4%的用户拥有脸书个人资料,2%的用户拥有博客,1%的用户拥有与音乐相关的网站(Soundcloud 或 Spotify)。88%的用户在他们的用户档案中有一个网站。

星期几

上传图片数量最多的一天是周日,占 18%,然后是周六和周四,占 15%,周五和周三,占 14%,最后是周一,占 11%。似乎只有两天有不同的统计数据,周日有更多的帖子,周一较少。

XGB

对这些特征应用具有以下参数的 XGBoost 模型:max_depth=4,learning_rate=0.01,n_estimators=596,我们获得了 2876.17 的 RMSE 和 0.92 的 R。

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

从 XGBoost 给出的特征重要性图中,我们可以看到平均点赞数显著影响了 XGB 模型的结果。F 值 4084,比其他所有特征加起来都大。在基本特征方面,帖子数量、关注人数和关注人数的 F 值较低。就提取的特征而言,星期六似乎比其他日子有更大的影响。或许这表明周六发帖会比其他时间获得更多的赞。之前有人说,一周内的帖子分布比较均匀,周日发布的帖子多,周一发布的帖子少。

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

B.自然语言处理

我们的数据集包含一些我们处理过的文本数据。首先,有用户传记数据。此字段包含用户为介绍自己和其个人资料所写的信息。第二个字段是每篇文章的标题。这个标题还包含用户添加到标题中的任何相关的标签。第三个字段包含帖子中提到的所有用户。最后,有一个字段用于显示 post 发生的位置。

由于我们没有太多的时间,我们决定采取词汇袋的方法。首先,我们清理数据,并使其进入可工作状态。然后,我们删除了文本中所有的标点符号、停用词和表情符号(稍后会详细介绍表情符号)。然后,我们拆分单词,并使用 scikit-learn 函数 CountVectorizer 对文本进行矢量化。我们还尝试对 TF-IDF 使用 scikit 函数,但是,似乎 CountVectorizer 工作得更好。当我们为帖子的标题做这个过程时,我们最终得到了 7000 多个独特的单词。这导致非常稀疏的 16k×7k 矩阵。为了减少矩阵的稀疏性,我们采用了一种技术,在这种技术中,我们只使用文本中顶部的单词,而不是所有的单词。因此,在评估我们的功能时,我们能够使用前 100、200、300 个词。

研究表情符号很有趣,因为在 Instagram 上使用表情符号非常流行。与实际的文本数据不同,我们必须以不同的方式处理表情符号。然而,因为表情符号是 unicode 的,所以我们能够为它们创建自己的 CountVectorizer 函数。然后,像标题文本数据一样,我们能够根据出现的次数,将热门表情符号的子集作为特征。

当试图找出我们将在最终模型中使用的 NLP 特征子集时,我们试图预测给定 NLP 数据子集的帖子的点赞数。我们选择了降低 RMSE 最大的数据子集。在测试了几个子集后,我们发现最好的子集是这样的:来自个人帖子标题的前 500 个单词/标签,以及出现超过 175 次的表情符号(37 个表情符号)。

下面是一些前 500 个单词的例子(我展示的是前 500 个单词中长度超过 5 个字符的子集):

实际上冒险几乎已经总是惊人的另一个任何人任何事物建筑周围可用真棒巴塞罗那美丽的美丽的景点美丽成为落后相信柏林更好的生日早餐加利福尼亚照相机挑战机会改变巧克力科切拉咖啡收藏即将评论社区保护夫妇课程美味的灯杆设计细节不同的复活节足够欧洲每个人都兴奋的体验探索家庭时尚最喜爱的特色感觉最后健身跟随追随者忘记法国星期五朋友地理感恩指南标签健康图像重要的不可思议的灵感激发 insta gram island journey liketk liketkit like know little living location London looking 可爱的 madwhips 杂志化妆制作梅赛德斯百万富翁时刻周一早晨母亲山 natgeo natgeo creative national natural natural natural natural natural natural natural natural nature nothing 官方网上装备人们完美的表演摄影摄影师摄影照片图片地点请 porque pretty prints profile project 真的食谱记得周六季系列分享某人某事有时特别赞助春季开始的故事夏季周日日落支持感谢 photosociety 的事情虽然明天晚上想在一起旅行尝试土耳其度假想穿周末没有狼百万富翁的精彩工作锻炼昨天 youtube

以下是排名前 37 位的表情符号:

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

Top 37 emojis

当我们将这些特征添加到基础模型的特征中时,我们的 RMSE 实际上恶化了。事实是,这些额外的 NLP 特征与基本模型特征中的平均特征相比并不重要。由于基础+ NLP 模型较少依赖均值特征来预测喜欢,我们的 RMSE 实际上恶化了。我们的 RMSE 分数上升到 2895.90,我们的 R 分数变成了 0.9163。由于有超过 500 个特性,这个模型的特性重要性图很难读懂。

但是,使用此功能:

vec = model_xgb.feature_importances_for i in range(len(vec)):if vec[i] > .01:print(X_train.columns[i])

我们发现最重要的自然语言处理特征是单词:ada amazing AMG code El going to make man thank time

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

C.迁移学习

我们采用的另一种方法与图像处理和计算机视觉有关。

目的是识别与图像相关的特征,这些特征可能对确定最终的点赞数有意义。

虽然基本模型中的特性是我们认为在这个回归问题中最有意义的,但我们认为在我们的模型中实现最微小的改进是一个巨大的成功。

迁移学习涉及使用预先训练的深度 ConvNet 的过程,并以此为起点建立考虑图像特征的模型。

有两种使用预训练模型的方法,我们都可以解决:

  • **使用 Inception V3 对 ConvNet 进行微调:**这是采用预训练的 ConvNet 权重,移除最后完全连接的层,并根据需要扩展网络。然后,我们通过继续反向传播来微调预训练网络的权重。我们使用的模型是 Inception v3。最后两个完全连接的层被删除,我们添加了三个额外的层。我们在 EC2 机器上用 GPU 对我们的数据点进行了重新训练。
  • 使用 VGG 的固定特征提取器 19: 这是移除最后一个完全连接的层,然后将 ConvNet 的剩余部分视为新数据集的固定特征提取器。VGG 19 是一个图像分类网络,在 ImageNet 数据集上的 1400 多万张图像上进行了预训练。移除最后一个完全连接的层为每个图像产生大小为 4096 的特征向量。我们可以使用这个(稀疏)向量作为基础模型中的特征。

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

结果

不幸的是,这两种方法都没有对我们的基本模型产生显著的改进。我们将这一点与这样一个事实联系起来,即这些深度网络是在头脑中有一个分类任务的情况下被训练的,这可能不一定适应像我们这样的回归问题。此外,我们的基本分类器使用了一个 XGBoost 模型,我们将其余的特征拟合到该模型中。XGBoost 通常具有混合的结果和非常稀疏的特征矩阵。

D .卷积回归神经网络

动机

我们推测转移学习方法不成功,因为转移网络是为分类问题训练的,而我们有一个回归目标。因此,我们的下一个想法是用谷歌的 TensorFlow 机器学习平台建立和训练我们自己的卷积神经网络(CNN),这是专门为回归设计的。

设计

像所有 CNN 一样,我们的设计从 c 卷积层开始,卷积层被展平成 f 全连接层。完全连接的层将过滤成最后一层 1 ReLU 激活的神经元,该神经元将输出喜欢的数量。我们首先想到的是连接我们在基本模型中使用的数字元特征(如关注者数量、数字跟随等。)作为图像分析的控制参数。我们认为这是有帮助的,因为不管图片如何,一个帖子获得的赞数都受到用户帖子的严重影响。例如,一个非常受欢迎的用户可能会发布一个普通物体的图片,比如一把椅子,但仍然会收到相对大量的赞。

建筑

选择神经网络的体系结构是一个艺术过程。在所有的机器学习问题中,模型设计者总是被以正确的方式选择超参数所困扰,既要给模型足够的自由来捕捉数据中的模式,又要对模型进行足够的约束以避免过度拟合。在神经网络设计中,这一问题因以下事实而变得更加复杂,即一切都是超参数——层数、层大小、通道数量、卷积滤波器大小、滤波器步幅等。为了解决这个问题,我们以这样一种方式编写代码,即模型初始化参数采用一种描述网络架构的紧凑形式。这使得我们能够非常快速地测试许多不同的架构,而无需重写任何代码。我们架构的标准是,在几个训练时期之后,模型不会很快开始过度拟合,并且 ReLU 激活不会太稀疏。下面是我们选定的架构。它成批接收 256 x 256 个图像,有 4 个卷积层和 5 个全连接层。对于卷积层,方框顶部的数字表示每个通道的输出形状,底部的数字表示通道的数量。对于完全连接的层,该数字简单地描述了该层中神经元的数量。

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

结果

CNN 被训练为一个独立的模型,但是为了将它集成到整个模型中,我们删除了每个图像的最终层的 8 个输出,并将它们用作主 XGBoost 中的功能。不幸的是,正如我们在 NLP 和迁移学习方法中看到的,我们的测试 RMSE 从 2876 增加到 2964。

改版

我们推断 RMSE 的上升可以归因于用户元特征被连接到完全连接的层。因为这些特征比图像本身更具预测性,网络学会了忽略图像,本质上像标准神经网络一样训练这些特征。下一步是简单地从网络中移除这些特征,并仅在图像上进行训练。当只对图像进行训练时,独立模型的 RMSE 预期要差得多。然而,当进行特征提取并与联合模型集成时,我们发现我们的 RMSE 比基本模型从 2876 减少到 2837。当分析联合 XGBoost 回归的重要特征时,我们发现实际上它从图像中发现了一个重要的特征。绘制所有样本的这一特征,我们看到它呈现高斯分布的形状。由此我们推测,它是所有图像的连续特征,如对比度或亮度,而不是离散值,如“这张照片中有一个人吗?”。下面你可以看到标记为“1_”的第二个特征来自卷积神经网络

这是感兴趣的特征的分布,关于所有的样本帖子。

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

Histogram of NN feature 1_

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

结论

在我们的基础模型上添加不同的子模型,如 NLP 或 CNN,表明除了用户特定的功能外,很难从 instagram 帖子中提取额外的预测能力。此外,即使有了基本模型,那些喜欢远远超出典型范围的用户也被大大低估了,他们丢掉了 RMSE 或者需要过滤。在我们的模型中缺乏帖子敏感性可能是由于每个用户都有一个具有足够独特品味的追随者,我们的模型无法在广泛的范围内概括这些偏好。一些可能的解决方案是创建特定于用户的模型,或者收集大量数据(数百万条帖子,而不是数千条),试图准确概括所有 instagram。最后,我们所有的模型和子模型都可以进行更优化的调整,希望获得更好的后期灵敏度,但我们的开发时间限制极大地限制了我们找到这个高度复杂问题的创造性解决方案的能力。

Corentin Dugué、Giovanni Alcantara、Joseph Shalabi 和 Sahil Shah。

预测新用户将在哪里预订他们的第一次旅行体验

原文:https://towardsdatascience.com/predict-where-a-new-user-will-book-their-first-travel-experience-e6c9ada67cf4?source=collection_archive---------11-----------------------

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

Photo credit: Pixabay

用户意图预测,学习排名

Airbnb 网站的核心是它的搜索。其搜索的一个最重要的特点是搜索排名。

Airbnb 显示的搜索结果是个性化的,针对他们预测最适合该用户的列表和体验。

这篇文章详细介绍了对 Airbnb 发布的两个数据集的探索,其目的是预测 Airbnb 用户预订旅行的第一个国家。更具体地说,以相关性递减的顺序预测前 5 个旅游目的地国家。

我们希望通过根据客人的人口统计信息和会议活动推断客人的偏好来实现一定程度的个性化,因为客人通过参与列表和进行查询来计划他们的旅行。

数据

数据集可以从 Kaggle 下载,我们将使用三个数据集:

  • train _ users.csv
  • 测试 _ 用户. csv
  • sessions.csv

有 16 个特征来描述每个用户,它们是:

  • id:用户 id
  • date_account_created:帐户创建日期
  • timestamp_first_active:第一个活动的时间戳,注意它可以早于 date_account_created 或 date_first_booking,因为用户可以在注册之前进行搜索
  • date_first_booking:首次预订的日期
  • 性别
  • 年龄
  • 注册方法
  • 注册流:用户注册的页面
  • 语言:国际语言偏好
  • affiliate_channel:什么样的付费营销
  • affiliate_provider:营销的地方,如谷歌,craigslist,其他
  • first_affiliate_tracked:用户在注册之前互动的第一个营销是什么
  • 注册应用程序
  • 第一设备类型
  • 第一个浏览器
  • country_destination:这是我们要预测的目标变量

描述每个 web 会话有 6 个特征,它们是:

  • user_id:与 users 表中的列’ id '连接
  • 行为
  • 动作类型
  • 行动 _ 详细信息
  • 设备类型
  • secs _ elapsed

用户探索

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plttrain_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
print("There were", train_users.shape[0], "users in the training set and", test_users.shape[0], "in the test set.")
print("In total there were", train_users.shape[0] + test_users.shape[0], "users.")

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

Figure 1

我们将探索训练和测试数据集中的所有用户。

df = pd.concat((train_users, test_users), axis=0, ignore_index=True)

缺失数据

在性别栏和第一浏览器栏中有“未知”,我们将用“男”填充“未知”。此外,在测试集的 date_first_booking 列中没有任何信息,因此,我们将放弃这个特性。

在此之后,我们可以看到有许多数据丢失。

df.gender.replace('-unknown-', np.nan, inplace=True)
df.first_browser.replace('-unknown-', np.nan, inplace=True)
df.drop('date_first_booking', axis=1, inplace=True)
df.isnull().sum()

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

Figure 2

用户年龄

df.age.describe()

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

Figure 3

最大年龄是 2014,这是不可能的。好像有些用户填了一年而不是年龄。同样,1 岁的最小年龄听起来很荒谬。根据服役期限,官方规定的最低年龄是 18 岁,但实际上这并不是强制性的。如果你不满 18 岁,拥有信用卡或借记卡,并且相当有礼貌和成熟,你使用 Airbnb 不会有任何问题。

df.loc[df['age'] > 1000]['age'].describe()

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

Figure 4

df.loc[df['age'] < 18]['age'].describe()

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

Figure 5

因此,我们将首先纠正每个错误填写的年龄,然后为年龄设置限制,并为异常值设置“NaN”。

df_with_year = df['age'] > 1000
df.loc[df_with_year, 'age'] = 2015 - df.loc[df_with_year, 'age']df.loc[df.age > 95, 'age'] = np.nan
df.loc[df.age < 16, 'age'] = np.nandf['age'].describe()

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

Figure 6

看起来更合理。我们现在可以可视化用户的年龄。

plt.figure(figsize=(12,6))
sns.distplot(df.age.dropna(), rug=True)
sns.despine()

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

Figure 7

不出所料,Airbnb 用户最常见的年龄在 25 岁到 40 岁之间。

用户性别

plt.figure(figsize=(12,6))
df["gender"] = df['gender'].fillna('M')
sns.countplot(data=df, x='gender')
plt.xticks(np.arange(4), ("NaN", "Male", "Female", "Other"))
plt.ylabel('Number of users')
plt.title('Users gender distribution')
sns.despine()

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

Figure 8

近似的 45%的用户性别未显示。并且在 Airbnb 的平台上,女性和男性用户之间没有显著差异。

旅游目的地国家

这是我们将在测试数据中预测的。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
sns.despine()

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

Figure 9

近 60%的用户没有预订任何目的地(NDF)。预订最多的国家是美国(近 30%的用户预订了我们),因为数据集中的所有用户都来自美国。我们可以说,数据集中的美国旅行者更有可能在美国境内旅行。

从现在开始,我们将只研究至少进行了一次预订的用户。

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.boxplot(y='age' , x='country_destination',data=df_without_NDF)
plt.xlabel('Destination Country box plot')
plt.ylabel('Age of Users')
plt.title('Country destination vs. age')
sns.despine()

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

Figure 10

预订不同目的地的用户之间没有明显的年龄差异。然而,预订英国的用户往往比预订西班牙和葡萄牙的用户年龄稍大。

用户注册

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.countplot(x='signup_method', data = df_without_NDF)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method distribution')
sns.despine()

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

Figure 11

数据中超过 70%的预订者使用基本的电子邮件方式注册 Airbnb,不到 30%的预订者使用他们的 facebook 帐户注册。数据中只有 0.26%的预订者使用他们的谷歌账户注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data = df_without_NDF, hue = 'signup_method')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method vs. destinations')
sns.despine()

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

Figure 12

对于至少预订过一次的用户来说,他们中的大多数都是通过基本的电子邮件方式与 Airbnb 签约的,无论他们要去哪个国家旅行。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_app', data=df_without_NDF)
plt.xlabel('Signup app')
plt.ylabel('Number of users')
plt.title('Signup app distribution')
sns.despine()

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

Figure 13

数据集中超过 85%的预订者在 Airbnb 的网站上注册,超过 10%的预订者在 iOs 上注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destinatiuon country based on signup app')
sns.despine()

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

Figure 14

美国旅行者比其他国家的旅行者有更多种类的注册应用。为了看得更清楚,我们去掉了我们。

df_without_NDF_US = df_without_NDF[df_without_NDF['country_destination']!='US']
plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destinatiuon country based on signup app without the US')
sns.despine()

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

Figure 15

在数据中,通过 Airbnb 网站报名是预订每个目的地国家最常见的报名。

关联公司

plt.figure(figsize=(12,6))
sns.countplot(x='affiliate_channel', data=df_without_NDF)
plt.xlabel('Affiliate channel')
plt.ylabel('Number of users')
plt.title('Affiliate channel distribution')
sns.despine()

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

Figure 16

plt.figure(figsize=(20,6))
sns.countplot(x='affiliate_provider', data=df_without_NDF)
plt.xlabel('Affiliate provider')
plt.ylabel('Number of users')
plt.title('Affiliate provider distribution')
sns.despine()

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

Figure 17

近似的 65%的预订者直接注册,没有任何附属计划,超过 23%的预订者通过谷歌附属计划注册,然而,如果你记得,只有 0.26%的预订者通过他们的谷歌账户注册。

第一

plt.figure(figsize=(12,6))
sns.countplot(x='first_affiliate_tracked', data=df_without_NDF)
plt.ylabel('Number of users')
plt.title('First affiliate tracked distribution')
sns.despine()

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

Figure 18

plt.figure(figsize=(18,6))
sns.countplot(x='first_device_type', data=df_without_NDF)
plt.xlabel('First device type')
plt.ylabel('Number of users')
plt.title('First device type distribution')
sns.despine()

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

Figure 19

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination')
sns.despine()

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

Figure 20

大约 60%的预订者使用苹果设备。尤其是在美国。

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination without the US')
sns.despine()

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

Figure 21

然而,在美国之外,Windows 桌面更加普遍,特别是在加拿大和澳大利亚,Mac 桌面和 Windows 桌面的使用差异很小。

plt.figure(figsize=(20,6))
sns.countplot(x='first_browser', data=df_without_NDF)
plt.xlabel('First browser')
plt.ylabel('Number of users')
plt.title('First browser distribution')
plt.xticks(rotation=90)
sns.despine()

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

Figure 22

数据中几乎 30%的预订者使用 Chrome 浏览器。

用户的首选语言

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution')
sns.despine()

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

Figure 23

绝大多数预订者的语言偏好是英语,这并不奇怪,因为数据集中的大多数用户来自美国。

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF_US)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution without the US')
sns.despine()

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

Figure 24

除了美国,英语仍然是最受欢迎的语言,有趣的是,在数据中,中文是预订者第二受欢迎的语言。

日期

为了可视化时间序列,我们首先需要将数据类型转换为日期时间。

df_without_NDF['date_account_created'] = pd.to_datetime(df_without_NDF['date_account_created'])
df_without_NDF['timestamp_first_active'] = pd.to_datetime((df_without_NDF.timestamp_first_active // 1000000), format='%Y%m%d')plt.figure(figsize=(12,6))
df_without_NDF.date_account_created.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('New account created over time')
sns.despine()

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

Figure 25

plt.figure(figsize=(12,6))
df_without_NDF.timestamp_first_active.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('First active date over time')
sns.despine()

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

Figure 26

帐户创建日期和首次激活日期之间的模式看起来很相似,这是应该的。从这两个地块可以看出 Airbnb 在 2014 年到 2015 年的成长速度有多快。

df_2013 = df_without_NDF[df_without_NDF['timestamp_first_active'] > pd.to_datetime(20130101, format='%Y%m%d')]
df_2013 = df_2013[df_2013['timestamp_first_active'] < pd.to_datetime(20140101, format='%Y%m%d')]
plt.figure(figsize=(12,6))
df_2013.timestamp_first_active.value_counts().plot(kind='line', linewidth=2)
plt.xlabel('Date')
plt.title('First active date 2013')
sns.despine()

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

Figure 27

当进入 2013 年时,我们看到 Airbnb 预订者有几个高峰期,如 7 月、8 月和 10 月,而 12 月是 Airbnb 预订者最不活跃的月份。此外,它遵循相似的模式,例如相似距离处的峰值和非峰值。

用户会话探索

sessions = pd.read_csv('sessions.csv')print("There were", len(sessions.user_id.unique()), " unique user IDs in the session data.")

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

Figure 28

动作类型

动作类型有“难”和“未知”。所以我们将“未知”改为“南”。

sessions.action_type.replace('-unknown-', np.nan, inplace = True)
sessions.action_type.value_counts()

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

Figure 29

行动

sessions.action.value_counts().head(10)

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

Figure 30

行动细节

sessions.action_detail.value_counts().head(10)

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

Figure 31

设备类型

plt.figure(figsize=(18,6))
sns.countplot(x='device_type', data=sessions)
plt.xlabel('device type')
plt.ylabel('Number of sessions')
plt.title('device type distribution')
plt.xticks(rotation=90)
sns.despine()

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

Figure 32

这肯定了之前关于用户的发现。Airbnb 用户中最常见的设备类型是苹果产品。

已预订用户的会话

从前面的分析中,我们知道哪些用户通过 Airbnb 平台进行了预订,所以我们想探索这些 bookers 会话数据。和非预订者有区别吗?

Bookers 操作类型

booker_session = pd.merge(df_without_NDF, sessions, how = 'left', left_on = 'id', right_on = 'user_id')
booker_session.action_type.value_counts()

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

Figure 33

Bookers 热门活动

booker_session.action.value_counts().head(10)

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

Figure 34

不幸的是,预订者和所有用户之间的行为没有显著差异。

数据预处理和特征工程

train_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
df = pd.concat((train_users, test_users), axis=0, ignore_index=True)
df.drop('date_first_booking', axis=1, inplace=True)

日期时间特性

  • 将日期时间列转换为属性日期时间格式。
  • 将日期分为日、周、月、年。
  • 获取帐户创建日期和首次激活日期之间的差异(时滞)。
  • 最后,我们删除不再需要的列。

datetime_features

年龄特征

将年份转换为年龄,设置年龄限制,并用-1 填充 NaNs。

age_features

用户会话动作特征

有 10,567,737 个记录的会话,数据中有 135,483 个独立用户。

我们将按 user_id 分组,计算每个用户执行操作的次数、操作类型和操作细节。做groupby.agg(len)大概比groupby.size()快一倍。因此,我使用groupby.agg(len)。对于设备类型,我们按 user_id 分组,合计每个用户的总秒数。最后,我们为每个用户最常用的设备添加一个名为“最常用设备”的新列。

sessions_features

用户会话 secs_elapsed 特性

我们将从每个用户的 secs_elapsed 特征中提取信息,例如总和、平均值、最小值、最大值、中值、方差,如果 secs_elapsed 的总和大于 86,400 秒,我们考虑 day_pause,如果 secs_elapsed 的总和大于 300,000 秒,我们考虑它是长暂停,如果 secs_elapsed 的总和小于 3,600 秒,我们考虑它是短暂停。之后,我们将会话数据与用户数据合并。

以下脚本借用自 Kaggle

secs_elapsed

编码分类特征

categorical_features = ['gender', 'signup_method', 'signup_flow', 'language','affiliate_channel', 'affiliate_provider', 'first_affiliate_tracked', 'signup_app', 'first_device_type', 'first_browser', 'most_used_device', 'weekday_account_created', 'weekday_first_active']
df = pd.get_dummies(df, columns=categorical_features)

归一化贴现累计收益(NDCG)

NDCG 是折现累积收益(DCG) 度量的归一化。NDCG 是一个排名措施广泛使用的家庭实践。特别是,NDCG 在评估网络搜索方面非常受欢迎。

有几篇关于 NDCG 的优秀论文可以在这里这里找到。

我们的评估指标是 NDCG @k,其中 k=5。所以我们选择前 5 名,然后取平均值。

ndcg_score

使用 Xgboost 进行交叉验证

  • 我们将使用训练数据进行交叉验证
  • 我们将用-1 填充 NaN。
  • 我们如下设置通用参数、树助推器参数和学习任务参数,我们的评价指标是 mlogloss(多类 logloss)。关于如何设置 Xgboost 参数的详细指南可以在其官方网站上找到。

xgb_cv

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

Figure 35

从上面的脚本中,我们已经达到的最高平均测试 NDCG 分数是 0.827582。

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

用分类和回归树预测 90 多种葡萄酒

原文:https://towardsdatascience.com/predicting-90-wines-with-classification-regression-trees-7a30b4577e4c?source=collection_archive---------4-----------------------

分类回归树(CART)是解决分类问题的灵活工具。它很受欢迎,因为它的适应性和性能很好,几乎不需要调整。我将使用 CART 从葡萄酒评论数据中预测 90+点的葡萄酒,并展示它的特点和陷阱。

我将使用的数据来自《葡萄酒爱好者》杂志,可以在 https://www.kaggle.com/zynicide/wine-reviews 免费获得。它包含了 150,000 种葡萄酒的分数,以及每瓶葡萄酒的价格、酒厂、产区、品种&等信息。对于这个项目,我将只使用美国种植的葡萄酒。

一个合理的假设是,价格较高的葡萄酒比价格较低的葡萄酒更容易获得 90+分。正如下面的 hexbin 图所示,有一些证据支持这一点——但更尖锐的是,有相当多的昂贵葡萄酒根本得不到很高的分数。

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

另一个假设可能是,某些地区可靠地种植 90 度以上的葡萄酒,而其他地区注定只能种植得分较低的葡萄酒。同样,数据显示了对此的一些支持——但在任何给定的地区,评分结果都有很大的差异。下面的小提琴图描绘了 30 个得分最高的地区的葡萄酒得分密度,每个地区都有 50 种或更多的葡萄酒。

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

单独使用这些标准中的任何一个,人们都可以开发出一套预测 90+葡萄酒的规则——但这样一个模型的准确性会很差。CART 模型允许跨许多不同特征的直观分类,并且易于在许多不同类型的数据(分类的、定量的)上实现。CART 模型识别将数据分割成越来越同质的组的方式,并且递归地执行这些分割,直到(a)不可能进一步分割或者(b)达到一些用户定义的终止标准。

为了说明这一点,让我们使用 sci-kit learn 的工具在葡萄酒评论数据上训练一个购物车模型:

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

我的购物车模型由 20,081 个不同的终端“叶子”组成,在这种情况下,每个叶子都由一个或多个来自训练数据的观察结果组成,这些观察结果不能再进一步分割,要么是因为它们是 100%同质的,要么是因为这些观察结果之间不存在特征差异。

上面,我们观察了 CART 模型的主要缺陷:它们很容易过度适应训练它们的数据。当我在一个 30%随机维持数据集(名为“test”)上测试我的 CART 模型时,分类准确率下降了 10%以上。

解决这一缺点的最佳方法是构建不超过必要大小的树。这个标准有点主观,但是本质上在模型复杂性(叶子的数量)和你正在寻找的过度拟合之间有一个平衡。本讨论的其余部分将直接解决这个问题。

CART 模型的一个有用特性是能够比较不同模型特性的“重要性”。这里重要的是每个特征对分类同质性的贡献。

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

在使用的四个特征中,每种葡萄酒的产地和葡萄酒品种的特征重要性最低。让我们再次运行该模型,这一次删除了这两个特征:

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

在这里,我们看到训练和测试数据的预测准确率都有所下降,但两者之间的差异也有所下降。这离我们最终要寻找的东西越来越近了:一个可以预测各种数据样本的模型。

除了移除对观察同质性贡献低的特征之外,解决过度拟合的第二个工具是修剪树枝。实际上,修剪是通过在训练模型时设置终止标准来完成的。终止标准可以设置在增长新分割之前所需的最小样本数上,或者设置在模型的最大深度上——起始节点下的子分割数。

对于我的 90+分葡萄酒分类器,我运行了数以千计的购物车模型,每一个我都在增长过程中更快地停止。下图说明了模型精度和我的终止标准(最大叶子数)之间的权衡。

当叶子的数量被限制在大约 7,500 时,CART 模型的准确性开始下降,并且在该点之上相对稳定。但有趣的是,当用于测试数据时,在大约 6000 片叶子以下,4 特征和 2 特征模型之间几乎没有区别。在 2,500 个最大叶子的情况下,仍然有接近 80%的测试样本准确率,并且 2 特征训练和测试样本准确率之间只有大约 5%的差异。

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

最终,购物车模型标准的选择将取决于手头任务的独特目标。如果对于 90+点的葡萄酒预测,80%是可接受的平均准确率,那么具有大约 2,500 片叶子的 2 特征 CART 模型将为我们提供一个模型,该模型将以合理的确定性在样本间表现一致。

[## dasotelo/Wine_Classify.py

github.com](https://github.com/dasotelo/Python_Projects/blob/master/Wine_classify.py)

预测波士顿(昂贵的)房地产市场

原文:https://towardsdatascience.com/predicting-bostons-expensive-property-market-bdcd9db6a218?source=collection_archive---------14-----------------------

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

Boston’s Back Bay Neighborhood

众所周知,波士顿是一个生活成本很高的城市。

(如果你需要令人信服的话,这个 238 平方英尺的工作室公寓卖了 40 万美元,这个停车位 待定 35 万美元。)

使用来自波士顿城市的公开可用的 2018 年房地产评估数据,我开始发现一些关于波士顿房地产的更有见地的发现,并使用机器学习来尝试和预测整个城市的房地产价值。

完整的 Python 项目代码和更详细的发现可以在这里找到

我们正在处理哪些数据?

与任何项目一样,第一次打开一个数据集会带来更多的问题而不是答案。有哪些最值得关注的数据点?可用的特征中,哪些与我们的发现实际相关?

幸运的是,数据附有一张有用的表格来解释每一个变量。我可以用它来删除大约 12 个我无法想象会在任何分析中使用的列。接下来,我只过滤了住宅物业代码,因为我想给项目一个更有针对性的重点。

生成的数据只有不到 140,000 行(观测值)和 60 多列(要素)。每个观察值代表一个单独的住宅物业,特征包括物业的特征,如位置(邮政编码、街道、单元号)、应纳税价值、平方英尺、建造/改造年份、状况等。

数据有什么有趣的地方?

波士顿是什么时候建成的?

知道了波士顿有许多历史建筑,我们可以从看看这些年来今天的城市是如何建造的开始:

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

波士顿大约一半的现有住宅建于 1925 年,在 1880-1930 年间有了显著的增长。

从下图中,我们可以看到这种分布在一些更受欢迎的社区中是如何变化的。到 1900 年,比肯山已有近 80%的建筑建成,而这个海港的住宅建筑几乎有一半是在 21 世纪初建成的。

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

波士顿房产价值

转移到房地产价值,正如所料,豪华市场主导着波士顿。约 60%的城市住宅物业总价值(约 113,057,142,300 美元)来自 20%的财产。

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

当然,在数据中还可以找到更多——在伴随代码的中也有更多——但是为了简洁起见,本文的其余部分将集中在该项目的机器学习方面。

预测波士顿房产价值

该项目的目标是创建一个预测波士顿房地产价值的模型。我之前只过滤了住宅物业的数据,对于预测,我进一步过滤了数据,只包括了公寓和总价值(约 300 万美元)的 98.5%的数据。

上述原因是:( 1)我需要在我的计算机上本地处理数据,因此多次使用 4 个模型的全部 100,000+文件是不可行的,所以我必须缩减数据;( 2)有少量大的异常值可能会影响预测,我需要一个可以概括大多数属性的模型。

型号选择

从表面上看,这是一个经典的回归问题:获取一系列输入,计算每个输入的相对影响(斜率),并预测一个连续变量。

事实上,在这个项目的过程中,我测试了 Python 的 sklearn 库中的 4 个回归模型——线性、随机森林、KNeighbors 和梯度推进。

每个型号是什么?

线性回归试图通过最小化均方误差产生一条最佳拟合的线。或者,换句话说,该线被构造成使得所有输入和预测线之间的距离最小化。

随机森林回归创建一系列单独预测属性值的决策树,然后对所有树的预测值进行平均,得到最终预测值。 KNeighbors 回归找到最接近的(即大小、卧室数量、邻居等。)“k”个数据点指向每个输入,然后对这些“k”(用户自定义)点的总数进行平均,作为预测值。

最后,梯度推进回归器是我最近学到的一个新模型,概念上我理解它,但是算法背后的数学需要更多的工作。该模型通过分析误差并根据误差移动不同点的权重(误差越大=下一次迭代中的重点越多),迭代地建立在每个连续的预测集上。

准备数据

机器学习和预测不仅对大量、多样和准确的数据是有效的,而且当数据在输入模型之前准备妥当时也是有效的。

我们的数据预处理将采取两个步骤。首先,我们要缩放连续变量。接下来,我们要对分类列进行编码和二进制化。

我们将使用的连续变量包括总平方英尺、卧室数量、公寓所在的楼层,以及自装修以来的年数(如果公寓从未装修,则为自建造以来的年数)。

平方英尺明显大于卧室的数量,但不一定更重要。为了抵消这种缩放偏差,我们将应用标准缩放器,使每一列的平均值为 0,标准差为 1。

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

对于分类变量,我们创建二进制(值为 1 或 0)列,当列值与新的二进制列匹配时,这些列被“激活”。例如,在左边的例子中,在我们的预处理步骤之前,5 个属性中的 4 个具有值“A ”,而另一个不包含这些值。

view_dummies = pd.get_dummies(predict_df.U_VIEW, prefix='View')view_df = pd.concat([predict_df, view_dummies], axis=1)

模型创建和测试

准备好数据后,建模过程分为 3 个步骤:

  1. 特征工程和模型测试
  2. 最终特征选择
  3. 模型调整

特征工程和模型测试:

我的模型构建过程从使用最基本的特性开始,然后测试添加附加特性的影响。我只从数据中的连续变量开始(在预处理中提到过),结果非常糟糕。均方根误差为 250,000 美元以上,而平均绝对误差为 150,000 美元以上(预测误差平均超过 150,000 美元)。

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

然而,有足够的机会用其他变量来改进模型。第一个增加是为房产所在的社区创建并包含虚拟变量,因为正如下面的箱线图所示,价值因位置而有显著变化。

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

事实上,包括邻居极大地改善了结果。例如,Random Forest 的 MAE 从大约 150,000 美元下降到大约 63,000 美元,降幅接近 60%。

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

我继续添加数据特征,如视图(特殊到差)和方向(后方、前方、通过等。)和测试模型,每一个都显示出递增的改进。

然后,我希望从数据本身开发额外的功能。例如,我创建了一个“奢华”变量(其思想是,在其他条件相同的情况下,奢华的房产可以卖更高的价格),将厨房或浴室风格的房产标记为奢华。我还创建了多项式特性来尝试捕捉连续变量和属性值之间的非线性和交互关系。

最后,我引入了邮政编码级别的外部数据。我找到了一个 Python 包,它接受邮政编码并返回平均收入、土地面积和人口密度等信息。

**import** **uszipcode**
**from** **uszipcode** **import** ZipcodeSearchEnginezips_list = []

**for** zipcode **in** zips:

    search = ZipcodeSearchEngine()
    zippy = search.by_zipcode(zipcode)
    zips_list.append(zippy)

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

A sample result for the above code

我还搜索并最终找到了邮政编码级别的人口统计数据,并将其合并到预测数据信息中,如该社区的种族构成(白人与少数族裔)和年龄细分(千禧一代与中年人和退休者),目的是找到其他相关变量。

虽然没有一个对添加像邻域这样的东西的大小产生影响,但我们确实看到了每种模型类型的误差度量(平均绝对误差,MAE)的总体下降趋势,没有一个较新模型的 KNeighbors 出现单个峰值。平均绝对误差从开始到结束的级数如下。

框中的值代表最终模型在每条虚线之前的 MAE,最左边的框是只有连续变量的第一个模型的 MAE:

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

功能选择

虽然创建和添加要素有助于了解不同要素如何影响我们的模型,但我们的最终结果不一定是最佳输入集。我们可能有多重共线性需要在我们的要素中解决(要素之间的相关性),而其他可能对我们的预测没有帮助。

有几种不同的方法来处理特性选择,我尝试了两种不同的方法。首先是主成分分析 (PCA),它基于特征的解释方差来减少维数。这一过程分为两步:用未定义数量的成分拟合 PCA,分析解释的方差,然后用最少数量的成分重新拟合,以获得最大的方差。

pca = PCA()
pca.fit(poly_df_s, predict_df.AV_TOTAL)

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

我们看到几乎 100%的差异是由大约一半的特征解释的。然后,我们可以对 PCA 和 40 个特征使用维数减少,目标是实现与所有特征相似的结果。

fitted_pca = pd.DataFrame(PCA(n_components=40).fit_transform(poly_df_s, predict_df.AV_TOTAL))

对具有 40 个分量的 PCA 转换数据运行模型,对于梯度增强算法产生了类似的结果-证明我们大约一半的特征对于该模型是无关紧要的-而 KNeighbors 和 Random Forest 的性能略有下降。

第二种方法使用 SelectKBest 函数搜索要使用的最佳特性。我针对从 20 到最大列数的 5 个 k 值测试了模型,结果是 60 产生了最好的结果。

# select_k_best_model_test is a function defined earlier in the code # that fits a SelectKBest model, tests the models on that data, and # returns both the results of the test (MAE, RMSE, score) plus a    # data frame of the condensed columnsk_to_test = [20, 30, 40, 60, 84]

**for** i **in** k_to_test:

    result, df = select_k_best_model_test(i)

    print('The results for the best **%i** features' %i)
    print(result)
    print('**\n**')

在用 60 列拟合 SelectKBest 模型之后,我试图通过删除相关列(我认为是那些相关性高于 0.8 的列)来抵消多重共线性问题。

corr_matrix = best_k.corr().abs()

*## Select upper triangle of correlation matrix*

upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

*## Find index of feature columns with correlation greater than 0.8*

to_drop = [column **for** column **in** upper.columns **if** any(upper[column] > 0.8)]*## Drop columns with a correlation about 0.8* best_k_consolidated = best_k.drop(to_drop, axis=1)

最终结果是一个有 37 列的模型——比我们最初的 84 列减少了很多——的表现和其他任何模型一样好,甚至更好。 其余栏目包括居住面积的抽样(sq。脚)、基础楼层(即一楼、二楼等。)、看法(一般、优秀等。)、多个邻域虚拟变量等;大约三分之一的最终列是我们的特征工程和/或引入其他外部数据的结果。

模型调整

在经历了变量创建和从这些变量中选择特征之后,是时候看看我们是否可以通过调整超参数来改进开箱即用的模型了。

我根据模型使用了 GridSearchCVRandomizedSearchCV 的组合来搜索最佳结果的参数。这些函数要么搜索参数输入的每个组合(GridSearch),要么搜索一定数量的随机选择的输入(RandomizedSearch)。

params_grid_gbr = {'loss':['ls','lad','huber'], 'learning_rate':np.arange(0.02, 0.4, 0.03), 
                   'n_estimators':np.arange(100, 500, 50), 'min_samples_split': np.arange(2, 50, 5), 
                   'max_depth':np.arange(3, 15, 3)}

gbr = GradientBoostingRegressor(random_state=66)

gbr_grid = RandomizedSearchCV(gbr, params_grid_gbr, n_iter=10, cv=5, scoring='neg_mean_absolute_error',)gbr_grid.fit(tr_x, tr_y)

运行这些算法的结果是,对于每个被调整的模型,基于被测试的输入的一组最佳参数。这里需要注意的是,最优参数是我们测试的参数的函数,因此实际上它们可以被认为是局部最优而不是全局最优(即,如果我们要测试每一个可能的参数组合)。

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

梯度推进回归器从调优中获得了最大的改善,MAE 从大约 80,000 美元下降到大约 55,900 美元,改善了大约 30%!其他的,比如 Random Forest,没有看到任何有意义的调整,而由 MAE 测量的 KNeighbors 的性能下降了 6%多一点。

胜负

完成以上所有工作后,是时候看看我们的工作成果了。我们将从查看一些指标开始,然后是我们的一个模型的错误的说明性可视化表示。

根据一个简单的“基线”模型,该模型预测房地产价值是所有房地产的平均值,我们的最佳预测将 MAE 从 290,000 美元减少到 53,600 美元。从第一个连续变量模型到调整后的模型,最小 MAE 从大约 150,000 美元下降到 53,600 美元,降幅为 64%,R2 从 0.5-.68 的范围提高到 0.8–0.95。

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

Untuned first model scoring

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

Untuned final model scoring

最终调整后的模型的平均绝对误差值为:

  • 兰登森林:53699 美元
  • 邻居:63230 美元
  • 梯度推进:55906 美元

总的来说,我们的模型与实际的财产价值相差约 10%。我们的预测绝非完美,但也大致如此。我很想知道其他人可以在我进行的过程之上做出的改进,或者超出我当前技能的更复杂的模型的结果会是什么。

我将提供的最后一个视觉效果是检查我们的一个模型的错误,并寻找是否有任何模型无法捕捉的系统偏差(例如,通过属性值、邻域、一致的过/欠预测)。下图显示了随机森林模型的绝对误差,按邻域着色,气泡大小是误差的大小(因此中间 45 度线上的空白区域-小误差=小气泡)。

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

事实上,我们没有看到任何明确的数据误差模式。我们看到的最大错误分组是,模型预测的价值在大约 100 万美元到大约 100 万美元 2M 之间,而实际价值不到 100 万美元。我很想知道是什么属性“愚弄”了模型,以至于预测如此之远。

结论:我们学到了什么?

这些项目的目标不仅是能够分享有趣的结果,而且是发展更好的数据技能。考虑到这一点,我从这个项目中得到的一些最大的收获如下:

  • 预测房产难!我确信,第一个包含平方英尺和卧室等变量的线性模型至少会产生一个令人尊敬的预测,但它还远远不够,而且随着时间的推移,增加变量的大量努力提供了递减的回报。
  • 不同回归模型的性能存在显著差异,并且测试多个模型很重要。如果使用我们的最终特征,简单的线性模型不会比大约 130,000 美元的平均误差做得更好,但是通过其他回归模型,我们能够将平均误差降低近 60%。
  • 最大的收益来自功能工程,这还远远不够。虽然超参数调整从选择的特征中提取了最后的预测能力(特别是对于梯度增强),但它是在从更好的特征中显著减少的基础上增加的。
  • 特征工程超越了缩放或测试样品内特征。大约 30%的最终特征是根据现有数据(即添加奢侈品标签或多项式特征)或外部数据(邮政编码级别的人口统计数据、收入)创建的。数据集变量之外的特征工程降低了我们的误差幅度,从约 6%(近邻)到约 30%(梯度增强)
  • 最后… 功能选择具有挑战性!我在该项目的大部分时间都在试图了解不同的特征选择标准,以便在不过度拟合模型的情况下获得最大的预测能力。我以为会有一种简单的方法来插入特性和目标——瞧!—完美的特征依然存在。相反,我循环使用了几种不同的方法,在这个过程中加深了我的学习。

该模型并不完美,但至少它是一个案例,说明了添加额外特征(样本内外)的价值以及特征选择的重要性。 我们的模型对于右边的 37 列和所有的 84 个 一样强大。

所以,是的,波士顿的房地产很贵,预测它是一个挑战,但最终我觉得对我的城市和我的数据技能都更了解了。

我欢迎任何人对代码、功能或想法的反馈。请随时到 jordan@jordanbean.com 找我。

用人工智能预测大学录取

原文:https://towardsdatascience.com/predicting-college-acceptance-with-ai-6d8abd702385?source=collection_archive---------2-----------------------

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

大约在去年的这个时候,我正忙着敲击键盘,向世界各地的大学申请。当我填写面前看似无穷无尽的申请表时,我突然意识到这完全是低效和冒险的。

每年有超过 200 万份大学申请被提交,每一份都带有一定的偶然性。即使是学术水平最高的学生申请也带有一定的随意性,结果往往会面临困境——大学录取中固有的精英制度让位于不确定性、怀疑和焦虑。

当然,许多因素影响录取,但众所周知,有两个因素在决定录取时举足轻重:GPA 和 SAT/ACT 分数。虽然其他因素肯定会被考虑在内,但不可否认的是,这两个指标对学生的申请有着不可思议的重要性——尽管没有人真正知道大学是如何判断和筛选这些指标的。

但是说到底,这两个指标是指标:可以使用数据科学分析趋势和关系来轻松评估的数字。因此,尽管我非常不耐烦和焦虑,我还是决定尝试预测大学录取情况,而不是等待决定出台。虽然有成千上万种统计方法来分析 GPA/考试成绩和申请结果之间的趋势,但我选择了一种最近流行的预测方法:机器学习。

机器学习是一个广泛的领域,有许多解决方案和应用,但我特别专注于人工神经网络。鉴于我的输入完全是数字,我的输出可以一次性编码成二进制值(0 表示拒绝,1 表示接受),人工神经网络工作得相当好。

Tensorflow 中实现了一个架构之后,我在专门为卡内基梅隆大学收集的数据集上训练了我的网络(这只是一个例子,大约有 90 个数据点)。经过大约 150,000 次迭代(在 GeForce 1060 GPU 上大约 1 分钟),我能够达到介于**75–80%**之间的精确度。虽然这可能看起来不太准确,但它足以得出一些结论,并且肯定比任意的线性模型更好。

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

Decreasing Loss over 150,000 steps (faded blue line is cross validation, no overfitting + room for more training)

从命令行中,我能够收集到一些相当不错的预测大学录取的结果:

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

Using a randomly high GPA and high SAT.

(美丽的日志由来源构建的[console-logging](https://github.com/pshah123/console-logging)提供)

为了便于使用,我用 Bootstrap 3 设计了一个简单的 GUI:

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

总而言之,它不仅在平息我的焦虑方面,而且在过滤我的申请以限制我可能进入的学校方面,证明是有点用的。具有讽刺意味的是,它甚至预言了我被卡内基梅隆大学拒绝!

该项目的完整来源可在 Github 在这个回购。

[## pshah123/ChanceyNN

利用人工智能预测大学申请结果

github.com](https://github.com/pshah123/ChanceyNN)

像这样,还有更多?在 Aiko AI ,我们热爱开源项目以及探索和可视化数据!

预测新西兰道路交通事故的严重程度

原文:https://towardsdatascience.com/predicting-crash-severity-for-nz-road-accidents-6214117e73fb?source=collection_archive---------27-----------------------

从技术和业务角度对机器学习项目进行端到端的工作——顶点项目回顾

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

P values for the Chi2 Test of independence of every (categorical) feature pair in the dataset.

最近看完了 Udacity 的机器学习 Nanodegree。这是一次伟大的经历,以著名的顶点项目而告终,在这篇文章中,我想分享我的经历。

TL;博士:

理解数据及其上下文比选择和调整超参数的算法更重要。这就是 EDA 至关重要的原因。另外,它也是一个很好的第一轮功能选择。

降维并不总是产生有用的结果。

过采样技术通常是克服目标变量类别不平衡的好策略。

有一个基准来比较性能是很重要的。如果这是不可能的,那么理解问题的背景和领域就变得更加重要。

最终,成功应该总是在业务目标、可用时间和追求任何特定想法或分析的成本的背景下定义。

首先,简单介绍一下我是谁

这些年来,我一直是各种类型的软件开发人员。我创建了数据密集型的内部网系统,并开发了使用相同数据的网络应用程序。我做过业务、功能和技术分析师;理解并确定这些应用和系统应该做什么以及应该如何做。我一直是企业数字化转型的顾问,这些企业希望通过自动化将数据货币化并简化运营。

目前,我是一名*产品经理和投资组合专员;*创造新产品和服务,将我公司的数据货币化,并利用这些服务推动我们客户各自的业务;也是我们自己的。

我有一个未完成的纯数学学位——这是我最大的爱好,其次是技术。

最后,我未来五年的目标是参与可再生能源、可持续发展和智能城市。我确信这些主题——以及区块链和物联网(IIoT)——将在很大程度上驱动和定义我们未来几十年将生活的社会和世界。

关于车祸

车祸和交通事故可能被认为是一个老话题。然而,随着汽车的进步和它们所承载的技术能力,更重要的是要有工具和手段来减少它们的发生,以及它们对所涉及的人的影响和后果。但是预测车祸的严重程度并不容易。即使在可能的情况下,精度水平也会有很大差异,这取决于许多因素,包括可用的数据和问题建模的好坏。

数据集

在为我的顶点项目寻找有意义的数据集时,我偶然发现了data . govt . NZ由中央政府发布的与新西兰各种活动相关的开放数据集的存储库。所选的数据集直接来自于新西兰运输署。它包含从 2000 年 1 月 1 日至今的车祸数据,并且每季度自动更新一次。数据集附带一个 pdf 文件,其中包含每个可用要素的清晰定义。

项目大纲

本文的大部分内容摘自该项目的最终报告。该报告连同所有笔记本、代码和数据都可以在我的 GitHub 个人资料这里找到。此外,还有一个 Tableau 工作簿,我在其中构建了大部分初始 EDA 可视化,我在整个项目以及报告中都使用了它。该工作簿可在我的 Tableau 公共档案这里获得。

我们的目标是预测车祸的严重程度。在数据集中,目标变量称为 crashSeverity ,取四个不同的值: N 表示无伤害M 表示轻微S 表示严重,以及 F 表示致命

为了实现我们的目标,我们将经历以下步骤:

功能探索(带数据清理)

降维

模型构建(包括基准和基线模型)

优化和最终型号选择

考虑到我们的问题是一个多类分类问题,我们将使用 F1 分数来评估我们将训练的不同模型的性能。对于每个模型,全局得分的值将依次是每个类别的 F1 得分的平均值。因此,我们将使用一对一对全部的方法。不过,我们也会仔细看看精度精度召回;因为它们都为理解模型如何运行提供了有价值的见解。

最后,我们将解释并详细说明进一步提高所选模型的整体性能和可解释性的一些可能的后续步骤。

功能探索(又名 EDA)

数据集最初总共有 655,697 个样本。每个都有 89 个不同的特征,既有数字的也有分类的。

简单地从上面提到的 pdf 中读取每个特性的定义,我们可以看到有一些特性的值是从其他特性中派生出来的。这些衍生的特征并没有给数据集增加内在价值,因为它们被用于,例如,以一种更简洁的方式总结车祸的特征,正如 pdf 所描述的,用于管理目的。因此,我们将移除它们以防止不必要的特征相关性。这同时将有助于将数据集的大小保持在最小,这将有助于模型的训练时间。

另一方面,有一些特性的值是在崩溃被报告和处理后根据其严重性提供的。具体来说,minorinjuricount、 *seriousInjuryCount、*和 fatalCount (不言自明)就是这样提供的。因此,它们会将数据泄漏到我们的目标变量中,我们必须移除它们。此外,这些功能在首次报告事故时不可用——这是我们的模型进行实时预测的时候——紧急机构需要尽快做出适当的反应。

除了这些特殊的特征,其余的大部分都是绝对的。表明撞车时的状况不同。像 weatherAweatherB,都用来表示天气的两个不同方面。或光、道路曲率、交通控制车道数,用于描述不同的自然光条件、道路曲率水平、是否有交通信号以及道路有哪些车道和车道数;分别是。

最后,大多数数字特征代表指示碰撞中涉及的物体数量的计数器。

在理解了每个特性代表什么之后,我们需要探究它们各自的值,以理解它们的分布,以及它们的定义是否有任何不一致之处。

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

top left: distribution of crashes by region; top right: distribution by crash type (multiVehicle); bottom left: distribution by road curvature: bottom right: distribution by junction type

对于每个特性,我们需要考虑值不一致和/或缺失的情况。这导致要么输入缺失值,要么丢弃特定样本,甚至完全丢弃某个特性——详细信息可在 GitHub 上的 EDA 笔记本中找到。在对每个分类和数字特征做了这些之后,我们最终放弃了 22 个与我们的问题无关的特征;或者由于太多缺失/不一致的值,并且没有明确的方法来估算它们。此外,我们还丢弃了一些样本,这些样本的某些特性的值不一致,而这些特性的行为与预期的不同。

无论如何,我们从这一步中学到的最重要的事情是,对于我们的目标变量来说存在着巨大的类别不平衡:

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

假定非伤害性碰撞是最常见的,并且随着碰撞严重性的增加,做出良好预测的重要性也增加;我们需要解决这个问题,如果我们希望产生一个良好的运作模式。为此,我们将求助于欠采样和过采样技术,这将在模型构建一节中介绍。

除了这一点,数据集没有呈现任何特定的趋势或模式,让我们能够直观地了解哪些特征最具预测能力。

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

Distribution for eight different feature. All of them behave similarly, where the only similarity they share is how they behave with regard to the target variable.

既然我们已经单独研究了每个特性,我们需要检查一对特性之间可能的相关性。由于大多数特征是绝对的,我们将通过 Chi2 独立性检验来实现。我们采用 p 值来测试每一对特征,并考虑 0.05 阈值的 假设的独立性。结果汇总在下图中,其中红色表示给定特征对之间的相关性,绿色表示独立性:

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

我们可以看到,每个功能都依赖于几乎所有其他功能。使得由于相关性而几乎不可能移除它们中的任何一个,因为它们都携带有价值的信息。

因此,我们决定保留所有剩余的功能。

主成分分析降维

在完成初始探索之后,我们可以尝试通过应用 PCA 来获得新的特征,以原始特征的线性组合的形式揭示可能的潜在特征,这些潜在特征可能证明是比原始特征更好(和更简单)的预测器。

然而,在用 10 个主成分应用 PCA 之后,我们得到了一个在类之间不可分的数据集。以下是前两个 PC 的每个碰撞严重度的分布情况,这两个 PC 占数据可变性的 97%以上:

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

如您所见,这四个类的分布非常相似。此外,这些课程相互重叠。以至于在一个图表中包含这四个类,除了几个清晰的点之外,您无法区分它们。

此外,即使在对数据进行最小最大缩放后,结果甚至更糟:

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

这在某种程度上是可以理解的;考虑到具有许多分类特征的数据集的维数减少往往比具有更多数值特征的数据集更棘手。

这在一定程度上是因为我们已经通过一个热编码过程运行了数据集。这将原始样本矩阵变成了本质上稀疏的另一个样本矩阵。不仅如此,这个稀疏矩阵大部分是二进制的(除了计数器和很少的连续特征);这意味着不是 0 的条目或单元格实际上是 1 。所有这些细节不仅影响应用 PCA 的结果,而且影响分类器本身的开发和实现。例如,如果我们要选择一种依赖于使用某种距离定义的算法,比如 L1(闵可夫斯基)、L2(欧几里得)或 L 无穷(切比雪夫或曼哈顿),我们可能会面临一些问题。

模型结构

正如我们刚刚提到的,数据集中的大多数要素都是分类的。同样,也不清楚哪些是最有意义的或者与分类任务相关的。因此,我们将关注决策树作为基础(和弱)学习器,并训练两个集成模型;一个用于装袋,一个用于增压。具体来说,我们将训练和优化随机森林和 AdaBoost GBM。这将为我们提供两种模型,能够处理刚才提到的两个棘手问题。

对于多类分类问题,这两种算法是很好的选择。然而,随机森林对类别不平衡是敏感的,而 AdaBoost 对噪声和异常值是敏感的。所有这些特殊性都很重要,我们将通过对数据集的三种变化训练这两个模型来解决它们:原始(完整)数据集、欠采样变化和过采样变化。对于目标变量中的每个类,欠采样和过采样变化将具有相同数量的样本。如何获得这些变化的详细信息可在 GitHub repo 的最终报告和笔记本中找到。

标杆管理

为了评估训练模型的性能,我们将使用两个参考值。第一个是专门为我们的问题训练的人工神经网络的性能。Sharaf alk heder 2016 年发表的这篇论文提供了详细信息;马德哈尔·塔姆奈和萨拉赫·塔姆奈:

利用人工神经网络预测交通事故的严重程度

论文摘要描述了一个最终的人工神经网络,其测试精度为 74.6%。

第二个参考将是一个基本的朴素贝叶斯分类器,用作我们集合模型的基线。作为参考,我们将使用所有班级的平均 F1 分数以及班级级别的得分值

基线-朴素贝叶斯分类器

在对每个变化训练 NB 分类器之后,我们得到将用于评估集合模型的以下性能值:

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

Averaged scores across classes

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

Class level scores

现在,对于所选的两种算法(RF 和 AdaBoost)。我们遵循了相同的流程:

  1. 以 75/25 的训练/测试比率分割数据集。
  2. 为数据集的每个变体训练一个基线模型(使用默认参数值)。这一步骤的结果是原始变化的一个训练模型;一个用于欠采样变异;一个用于过采样变化。
  3. 分析基线模型的性能指标,并选择性能最佳的模型和变体。在这一步中,我们考虑了准确性;所有目标类别的平均精确度、召回率和 F1 分数;和类级别的相同指标。这样做是因为,虽然我们想获得一个很高的 F1 分数,但我们处于一个多职业的环境中,因此,我们希望分数能代表所有职业。此外,考虑到阶级分布的不均衡性,这变得更加重要。
  4. 使用从最佳性能基线模型的特征导出的参数网格,使用最佳性能变化执行网格搜索。该步骤的结果是基于来自 3 重交叉验证的平均 F1 分数的最佳估计值。

随机森林

基线模型

首先,我们给出基线模型的结果,即所有默认参数。当然,分数对应于每个变体的测试集。

射频基线的准确度和平均 F1 分如下:

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

Performance of RF baseline model on all variations of the dataset.

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

Class level scores

正如我们所看到的,最佳精度是在原始变量紧跟过采样变量的情况下获得的。然而,最好的 F1 分数是通过过采样变化获得的。

此外,通过查看类级别的性能指标,我们清楚地看到原始变体的平均 F1 分数主要是由于类 *N、*的分数,而其他类的分数要低得多。另一方面,过采样变化的 F1 分数是由类级别的 F1 分数生成的,这些 F1 分数彼此之间更加平衡。因此,过采样变异的 F1 分数 0.6879 更能代表类级别的情况。

此外,对于过采样变异中的每个类别,F1 分数证明是精确度和召回率之间的非常好的平衡。所有这些细节使得过采样变化成为执行网格搜索的最佳候选。

网格搜索

接下来,我们呈现对参数最大深度n 估计量最小样本分割做网格的结果;以及它们相应的 F1 分数。在这里,分数是三重交叉验证过程的平均值。

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

得到的最佳估计器是用参数 *max_depth=70、*n _ estimates = 200 和 min_samples_split=2 训练的估计器。

作为一个额外的见解,有趣的是注意到,对于每个被考虑的 n_estimatormax_depth ,最高分是针对 min_samples_split=2 的。通过观察 viz 上的彩色条纹,这一点变得很明显。有人可能会说,如果我们只考虑这三个参数,那么提高性能的最佳方式就是在森林中增加更多的树。

此外,当我们使用最佳估计量对测试集进行预测时,我们得到的准确度为 0.7227,F1 值为 0.7231。其高于它们相应的训练值。

ADA 增强

同样,首先,我们呈现基线模型的结果。

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

Averaged scores

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

Class level scores

在这种情况下,最佳准确度和平均 F1 分数都是用原始变异获得的。然而,与 RF 一样,这主要是由类别 N 的分数驱动的。由于我们希望有一个平均代表每个类的分数,所以我们不能选择这个变量。相反,我们将选择过采样变化,虽然其值低得多,但其跨类行为与 RF 非常相似。

网格搜索

对于该算法,我们给出了具有参数 n_estimatorslearning_rate 的网格搜索的结果。

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

在这种情况下,有趣的部分来自于注意到对于每一个 n_estimators 的值,最好的测试分数是以 1 的学习率获得的。这在某种程度上是有道理的。算法本身已经为正确和错误分类的样本分配了权重,以便训练下一个树桩,从而改善前一个树桩的错误分类。

对于这个最佳估计量,测试集上的准确度是 0.6089,平均 F1 分数是 0.6058。

随机森林和 AdaBoost 比较

最后,在通过网格搜索优化每个模型之后,我们可以在它们之间以及与基准进行比较。

由于我们已经使用过采样变化训练了这两种算法,以克服类的不平衡,因此我们仅给出该变化的性能指标:

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

对于这两个指标,执行网格搜索后,性能最好的模型是随机森林。在某种程度上,这是意料之中的。至少事实上,在这种情况下,通过网格搜索,最佳执行模型将是一个优化的模型。

但也许最有趣的是两种算法的不同方法。

虽然 AdaBoost 在每一步都试图改善由基于单个特征进行预测的前一个树桩的集合所产生的错误分类,但随机森林是一种确定性方法,它通过找到在分割后产生最大杂质减少的分割来生长树。

通过这样做,随机森林开发出非常精确但过度拟合的树。然而,通过添加许多树,每个树都有一个样本包,并在每次分割时引导特征,它克服了单个树的过度拟合,创建了一个非常强大的模型。

总体准确度分数仅为 0.72 这一事实表明,可用数据缺乏可预测的能力来使这一指标超过我们为参考人工神经网络选择的 74.6%准确度的第一个基准。

Tableau 工作手册有几个例子来支持这个结论。具体来说,随着网格搜索的进行,性能的增加逐渐减少(边际);这表明利用现有数据,搜索和模型只能完成这么多。

结论和可能的改进

RF 只能产生 0.72 的准确度和 0.72 的 F1 分数。虽然 F1 分数在各个类别之间是平衡的——这意味着每个类别的 F1 分数与平均分数具有相似的值——但整体性能低于我们在项目开始时选择的人工神经网络基准。这使得我们的模型相关,但几乎不可用。

尽管如此,仍有很大的改进余地。例如,考虑到数据集的形状和形式,其他一些被证明有用的算法有 SVM、XGBoost 和 LGMB。这些也可以合并,包括随机森林。

我们还可以为每个类训练一个二进制分类器,以便有一个更加定制的一对一方法。还可以尝试其他评估方法,如 AUC/ROC 和 Precision/Recall 曲线。在这种情况下,我们可以为最终的分类器实现一个表决器。我们还可以对每一类的预测概率进行更深入的分析。有助于更好地理解每个类别最具代表性的特征。

与此同时,我们可以通过其他维度缩减技术和无监督学习算法来探索特征选择/工程的途径,这些技术和算法可以帮助发现数据中的隐藏结构。

对于数据集的不平衡性质,一些成本敏感性算法可能非常有用。

最后但同样重要的是,我们可以尝试其他具有其他优点和缺点的库。例如 H2O,它可以处理分类特征,并用于并行计算,这将有助于模型的总训练时间。允许更长的训练时间和更彻底的网格搜索。

总而言之,如果在这一点上不明显,每个机器学习项目的指导北应该是所谓的商业案例;虽然它显然不属于商业范畴,但这个想法仍然成立。业务案例对什么是有意义的,什么是没有意义的有最终决定权:对 2%的性能提升是否值得在截止日期后额外花费 10%的时间和 5%的额外成本,这两者对组织的其他领域和团队来说可能都是合理的。

最终,没有完美的解决方案,只有对预期目的足够好的解决方案。然而,随着研究结果被证明越来越有用,并提供了一个关于如何改进自己的反馈回路,这一目的可以——在许多情况下也应该——变得越来越复杂。

用 Python 预测登革热:看天气

原文:https://towardsdatascience.com/predicting-dengue-fever-with-python-look-at-the-weather-8945b615301f?source=collection_archive---------6-----------------------

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

步骤 Pandas、matplotlib 和 Python 中的特性探索

驱动数据公司目前正在举办一场竞赛,预测秘鲁伊基托斯和波多黎各圣胡安的登革热病例。我在我之前的职位中探究了每周的案件量。在这篇文章中,我将探讨竞争对手提供的特性。

功能

天气天气天气。所有提供的预测病例数的变量都是基于天气。这 20 项功能分为:

  • 温度
  • 湿度
  • 降雨
  • 植被水平

我的第一步,总是,是看哪些特征彼此相关,哪些特征与目标相关。Seaborn 的热图功能有助于可视化这些相关性。在这种情况下,我对所有相关值进行平方,因为我不关心正相关或负相关,只关心相关的强度。越接近 1,相关性越强。

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

Correlation Heatmap for Iquitos (left) and San Juan (right)

圣胡安和伊基托斯具有不同的要素关系集。NDVI 水平在伊基托斯高度相关,但在圣胡安不太相关。圣胡安的温度特征会一起移动,但伊基托斯不会。这再次表明每个城市需要不同的模式。

温度、降雨量和湿度

蚊子需要水和合适的温度才能茁壮成长。我的假设是:更多的雨和热=更多的蚊子。下面的图表解释了这些特征平均来说是如何随时间变化的。

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

我将所有的天气特征标准化,使它们保持在相同的尺度上。例如,在波多黎各的圣胡安,大多数特征都在 0 左右。这意味着它们接近整个数据集的平均温度。值为 1 或-1 表示变量高于或低于平均值 1 个标准偏差。像这样标准化可以让我们比较不同尺度上变量的变化(温度变化 1 度和降雨量增加 1 英寸具有完全不同的意义)。

绘制所有特征的目的是看它们是否一起移动。看precipitation_amt_mm是否每周都在变化并不重要,重要的是看它是否与其他特征同步变化。

圣胡安的天气变化比秘鲁的伊基托斯更为紧密。特征之间的变化,尤其是在基于时间的分析中,对于具有更大的预测能力是重要的。但这也可能导致更多的噪音。

归一化差异植被指数

美国国家海洋和大气管理局(NOAA)拍摄各个城市的卫星图像,并确定该地区的有机增长数量。该级别被归一化为归一化差异植被(NDVI),并提供给每个城市的四个象限。关于 NDVI 是如何计算的更多信息,请点击这里。

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

Normalized Difference Vegetation Index for Iquitos, Peru (left) and San Juan, Puerto Rico (right)

第一,这个数据是有噪音的。每张图片的上半部分显示了每周的观察结果。取一年中每周的平均值,我们可以得出圣胡安和伊基托斯植被水平的年度趋势。随着时间的推移,伊基托斯的趋势比圣胡安强得多。此外,所有四个象限在伊基托斯总是几乎相同。圣胡安南部象限的 NDVI 分数几乎总是低于北部象限。

结论

建模将向我们展示哪些特征以及特征的哪些组合将是病例数量的良好预测器。然而,重要的是要记住,并不是当前的天气决定了蚊子的数量,从而决定了登革热病例的数量。之前的几周和几个月为蚊子的繁殖提供了潜伏期。

下一篇文章将探讨如何确定月趋势(不考虑天气特征)。之后,我将描述使用历史天气预测当前登革热病例数量的方法。

密码

我的 GitHub repo here 上有 Jupyter 笔记本,上面有我的可视化 python 代码。请随意阅读我未来的帖子。

利用季节性 ARIMAX 模型和气象数据预测登革热传播

原文:https://towardsdatascience.com/predicting-dengue-spread-using-seasonal-arimax-model-on-meteorology-data-3f35979ec5d?source=collection_archive---------6-----------------------

在过去的几十年中,登革热病毒已经在世界的亚热带地区传播,严重形式的登革热的数量增加,例如严重出血、低血压,甚至死亡。由于疾病由蚊子传播,登革热的传播与温度和降水等气象变量有关。在这篇博文中,我将回顾一下我是如何应对邓艾竞赛的论文和代码可以在我的 github 上找到!

这是游戏计划:

  1. 数据分割
  2. 描述性分析和数据可视化
  3. 处理缺失值
  4. 模型诊断
  5. 模型形成
  6. 预测

数据分割

邓艾竞赛数据集本质上是一个杂乱的数据集,包含两个不同的城市和两个不同的时间框架。我根据两个城市将数据集分成两个小数据集:圣胡安和伊基托斯。从两个数据集中,我将每个数据集分为训练集和验证集,以便在选择最佳模型在最终测试集上执行之前测试不同的模型。

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

Figure 1: Data Split

描述性分析和数据可视化

圣胡安和伊基托斯的数据处理非常相似,所以我在这一节只展示圣胡安的图表。伊基托斯的图表将在我的论文中提供。

每个数据集包含 25 个变量,包括气象和地理变量。在此查看每个变量的详细信息。

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

Figure 2: Descriptive Analysis of San Juan

相关图将有助于诊断两个变量之间是否存在任何线性关系。我们可以看到,这些变量中没有一个与总病例数**(图 3)** 高度相关。然而,如果我们包括 2 个以上的变量并运行多元线性回归,每个预测因子的大小可能会改变。

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

Figure 3: Correlation Plot of San Juan

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

Figure 4: Time Series Plot of Total Cases of San Juan

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

Figure 5: Scatter Plots of Total Cases and Climate Variables of San Juan

时间序列图表明数据中可能存在季节性,因为每年夏季前后总病例数达到高峰。两个散点图也表明了总病例数和两个气候变量之间可能的线性关系。(温度和湿度)

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

Figure 6: Time Series Plot of Total Cases and Climate Variables of San Juan

查看总例数和温度以及总例数和湿度的双时间序列图,我们可以看到有时例数和气候值一起上下移动;有时天气变量首先达到峰值或直线下降,然后总病例数在 3 -4 周后上下波动。更有趣的是,登革热症状通常在被受感染的蚊子叮咬后 4 至 7 天开始出现。蚊子在 70 华氏度时可能需要 14 天完成其生命周期,而在 80 华氏度时只需要 10 天。因此,在温度、降雨量或湿度上下波动后,平均需要 3-4 周才能报告病例。

描述性分析和数据可视化提出了一个具有额外预测变量的时间序列模型,并且可能有一些预测变量的先前滞后。

处理缺失值

我通过使用 R 中的最后一次观察结转方法来处理缺失数据,这基本上是用之前最近的非 NA 替换每个 NA。这里我假设本周的天气与上周的天气不会有太大的不同。

*# build a function to impute data with the most recent that is non missing*
  na.locf.data.frame <- 
    **function**(object, **...**) replace(object, TRUE, lapply(object, na.locf, **...**))

  *#fill in NAs - SJ*
  sjdata.train.imputed <- na.locf.data.frame(sjdata.train)

  *#fill in NAs - IQ*
  iqdata.train.imputed <- na.locf.data.frame(iqdata.train)

模型诊断

一个增强的 Dickey-Fuller 检验表明时间序列数据集是平稳的。该数据集具有复杂的季节性,每周数据点(频率= 52.18)。ETS、分解等方法大多要求季节周期为整数。即使我们把它四舍五入到 52,大多数方法也不会有效地处理这么大的季节周期。一种可能的方法是通过在 ARIMA 模型中包括傅立叶项来使用动态谐波回归模型。

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

Figure 7: ACF and PACF Plots of Total Cases of San Juan Time Series

接下来,为了挑选 MA 和 AR 术语,我首先检查了早期滞后(1,2,3,…)来判断非季节性术语。在低滞后时,ACF 中的这些峰值表示非季节性 MA 术语。此外,PACF 在低滞后时的峰值表明可能存在非季节性 AR 项。

模型形成

通过经验审查和数据诊断,我决定尝试 3 种模型:SARIMA、SARIMAX 和神经网络。我从一个只有全部病例的基本而简单的季节性 ARIMA 开始,然后我在模型中添加了更多的预测因子,如温度、湿度、降雨量。最后,我用 r 中的 NNETAR 包建立了神经网络模型(多层前馈网络)。这里我将只报告建立最佳模型的过程,即季节性 ARIMAX。

季节性 ARIMAX

在研究了影响蚊子繁殖的因素后,我使用 xreg 参数将这些变量添加到季节性 ARIMA 中:

  • 降水量 _ 金额 _ 毫米
  • 再分析露点温度 k
  • 再分析 _ 相对湿度 _ 百分比
  • 车站平均温度 c
  • 车站 _ 昼夜 _ 温度 _rng_c
  • 车站最高温度 c
  • 车站最低温度 c

基本上,如果你在一个热带国家长大,你可能知道蚊子的生命周期包括在水中和空气中的四个不同的阶段。因此,降水、温度和湿度在加速蚊子数量方面起着重要作用。请参考此链接了解更多信息。

有时,包含在回归模型中的预测因子的影响不是简单而直接的。例如,高温和高降雨量可能在几周之后的一段时间内影响所有病例。我运行了 CCF(交叉相关函数),以查看预测因子的任何先前滞后是否与总病例的当前滞后高度相关。似乎前 4 周的露水温度可能与当前的病例数正相关。

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

Figure 8: CCF Plots of Total Cases and Dew Temperature of San Juan Time Series

ARIMA 模型的选择是使用赤池的信息标准(AIC)进行的。在所有测试的模型中,a SARIMAX (3,0,2)(0,0,1)[52]是最适合圣胡安市的模型,而 ARIMAX (0,1,2)的季节傅立叶项 K = 1 是伊基托斯市的最佳模型。

在 ARIMA 和 NNET 之间的最终选择基于使用 MAE 作为主要参数的样本内交叉验证。

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

预测

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

这是两个城市的预测图。我综合了圣胡安和伊基托斯总病例的预测,并将结果提交给数据驱动网站。我 MAE 得了 25.6587,排名 674/4392。

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

Figure 9: Forecasted Values of Total Cases of San Juan and Iquitos

最终的模型有一些缺点,可以在将来解决。首先,我完全忽略了“ndvi”(地理变量和卫星植被指数),而这些变量可能对疾病的爆发很重要。然而,为了包括这些变量,我需要做更多的研究,以更好地理解它们是什么、为什么以及如何重要。其次,该模型没有完全捕捉到导致登革热传播的所有因素。更多与这两个城市的基础设施和医疗保健系统相关的变量应该包括在模型中。最后,可以使用多季节周期模型来显示周、月和年的不同季节模式,因为当前模型仅捕获每周的季节性。

预测 Airbnb 新用户的目的地国家

原文:https://towardsdatascience.com/predicting-destination-countries-for-new-users-of-airbnb-eb0d7db7579f?source=collection_archive---------7-----------------------

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

我在 3 年前发现了 Airbnb 在 Kaggle 上发布的这个有趣的挑战。但是,让您参与刺激的数据挑战永远不会太晚!😃

这个 Kaggle 挑战提出了一个预测哪个国家将成为新用户预订目的地的问题。为了这个挑战,我们将使用 Airbnb 提供的三个数据集。

  1. 训练集
  2. 测试设备
  3. 会话数据

让我们了解一下用户资料在训练和测试数据集中的样子。

描述每个用户的 16 个特征如下

  1. id:用户 id
  2. date_account_created:帐户创建日期
  3. timestamp_first_active:第一个活动的时间戳,注意它可以早于 date_account_created 或 date_first_booking,因为用户可以在注册之前进行搜索
  4. date_first_booking:首次预订的日期
  5. 性别
  6. 年龄
  7. 注册方法
  8. 注册流:用户注册的页面
  9. 语言:国际语言偏好
  10. affiliate_channel:什么样的付费营销
  11. affiliate_provider:营销的地方,如谷歌,craigslist,其他
  12. first_affiliate_tracked:用户在注册之前互动的第一个营销是什么
  13. 注册应用程序
  14. 第一设备类型
  15. 第一个浏览器
  16. country_destination:这是我们要预测的目标变量

类似地,有 6 个特征来描述用户的每个 web 会话,如下所示:

  1. user_id:与 users 表中的列’ id '连接
  2. 行为
  3. 动作类型
  4. 行动 _ 详细信息
  5. 设备类型
  6. secs _ elapsed

我把对这个挑战的分析分成了两部分—

一.探索性分析

二。预测建模

让我们首先开始探索数据集。

一.探索性分析

# Importing the necessary libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
import warnings
warnings.filterwarnings("ignore")

让我们现在加载数据。

train_users = pd.read_csv("train_users_2.csv")
test_users = pd.read_csv("test_users.csv")print("There were", train_users.shape[0], "users in the training set and", test_users.shape[0], "users in the test set.") print("In total there were",train_users.shape[0] + test_users.shape[0], "users in total." )

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

现在,我们将探索训练集和测试集中的所有用户。

df = pd.concat((train_users, test_users), axis = 0, ignore_index = True, sort = True)

检查空值。

display(df.isnull().sum())

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

我们看到“年龄”、“国家/地区 _ 目的地”、“日期 _ 首次预订”、“首次会员 _ 追踪”列中有空值。

我们尝试检查每一列中的唯一值,以确定是否有任何丢失的数据。我们发现“性别”和“第一浏览器”列中有未知数。

df.gender.unique()

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

df.first_browser.unique()

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

我们用 NaNs 替换 unknowns,并删除列“date_first_booking ”,因为它在我们的测试集中没有任何值。

df.gender.replace("-unknown-", np.nan, inplace=True)
df.first_browser.replace("-unknown-", np.nan, inplace=True)
df.drop("date_first_booking", axis = 1, inplace=True)

用户年龄

现在让我们检查年龄的统计摘要,看看是否有任何明显的异常。

df.age.describe()

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

最大年龄是 2014,这是不可能的。看起来用户无意中填写了年份而不是年龄。还有,最小年龄 1 看起来很荒谬。

df.loc[df['age']>1000]['age'].describe()

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

df.loc[df['age']<18]['age'].describe()

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

我们纠正错误填写的年龄,然后设置年龄限制(18-下限和 95-上限)。

df_with_year = df['age'] > 1000
df.loc[df_with_year, 'age'] = 2015 - df.loc[df_with_year, 'age']
df.loc[df_with_year, 'age'].describe()

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

df.loc[df.age > 95, 'age'] = np.nan
df.loc[df.age < 18, 'age'] = np.nan

可视化用户的年龄。

plt.figure(figsize=(12,6))
sns.distplot(df.age.dropna(), rug=True)
plt.show()

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

Fig.1: Plot visualizing the age bracket of the users

正如我们在图 1 中看到的,大多数用户群都在 20 到 40 岁之间。

用户性别

plt.figure(figsize=(12,6))
sns.countplot(x='gender', data=df)
plt.ylabel('Number of users')
plt.title('Users gender distribution')
plt.show()

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

Fig.2: Plot visualizing gender distribution of the users

正如我们在图 2 中看到的,男性和女性用户之间没有显著差异。

旅游目的地

这是我们预测问题的目标变量。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df)
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.show()

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

Fig.3: Plot showing popular destinations among users

我们在图 3 中看到,近 60%的用户最终没有预订 NDF 代表的任何旅行。考虑到这个问题中的用户群来自美国,大多数用户预订了美国的目的地(约 30%)。因此,我的推断是,美国旅行者倾向于在我们自己内部旅行。

我们现在将只分析那些至少进行了一次预订的用户。

plt.figure(figsize=(12,6))
df_without_NDF = df[df['country_destination']!='NDF']
sns.boxplot(y='age' , x='country_destination',data=df_without_NDF)
plt.xlabel('Destination Country')
plt.ylabel('Age of users')
plt.title('Country destination vs. age')
plt.show()

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

Fig.4: Plot showing choice of destination countries varies across ages

图 4 示出了在预订到图表中显示的目的地的旅行的用户中没有显著的年龄差异。然而,预订去英国旅行的用户似乎比预订去西班牙和荷兰旅行的用户年龄更大。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_method', data = df_without_NDF)
plt.xlabel('Signup Method')
plt.ylabel('Number of users')
plt.title('Users sign up method distribution')
plt.show()

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

Fig.5: Plot showing sign up method distribution

图 5 显示,在至少预订过一次的所有用户中,近 70%的人使用基本方法(电子邮件)在 Airbnb 注册。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data = df_without_NDF, hue = 'signup_method')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Users sign up method vs. destinations')
plt.legend(loc='upper right')
plt.show()

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

Fig.6: Plot showing distribution of sign-up methods vs. destinations

图 6 告诉我们,在至少预订过一次的用户中,无论预订的目的地是哪个国家,大多数人都使用电子邮件的方式注册 Airbnb。

plt.figure(figsize=(12,6))
sns.countplot(x='signup_app', data=df_without_NDF)
plt.xlabel('Signup app')
plt.ylabel('Number of users')
plt.title('Signup app distribution')
plt.show()

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

Fig.7: Plt showing signup app distribution

在所有预订者中,大多数人都是使用 Airbnb 的网站注册的。接下来,大多数用户使用 iOS 注册(图 7)。

plt.figure(figsize=(12,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='signup_app')
plt.xlabel('Destination Country')
plt.ylabel('Number of users')
plt.title('Destination country based on signup app')
plt.legend(loc = 'upper right')
plt.show()

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

Fig.8: Plot showing distribution of destination countries based on signup app

我们看到,美国用户在 Airbnb 上注册时使用了各种各样的应用程序。在其他国家,用户似乎更喜欢只在 Airbnb 的网站上注册(图 8)。

接纳

plt.figure(figsize=(12,6))
sns.countplot(x='affiliate_channel', data=df_without_NDF)
plt.xlabel('Affiliate channel')
plt.ylabel('Number of users')
plt.title('Affiliate channel distribution')
plt.show()

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

Fig.9: Plot showing distribtution of affiliate channels

我们看到,近 70%的用户直接来到 Airbnb 的网站,没有任何附属机构的参与(图 9)。

plt.figure(figsize=(18,6))
sns.countplot(x='first_device_type', data=df_without_NDF)
plt.xlabel('First device type')
plt.ylabel('Number of users')
plt.title('First device type distribution')
plt.show()

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

Fig.10: Plot showing distribution of first device type used by users

从图 10 来看,用户首次访问 Airbnb 网站时最常用的设备似乎是 Mac 桌面(40%),其次是 Windows 桌面(30%)。

plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination')
plt.legend(loc = 'upper right')
plt.show()

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

Fig.11: Plot showing distribution of first device type vs. country destination

从图 11 中可以看出,无论预订的目的地是哪个国家,Mac Desktop 都是用户访问 Airbnb 网站的首选设备。这似乎是美国最高的。紧随其后的是 Windows 桌面。

df_without_NDF_US = df_without_NDF[df_without_NDF['country_destination']!='US']
plt.figure(figsize=(18,6))
sns.countplot(x='country_destination', data=df_without_NDF_US, hue='first_device_type')
plt.ylabel('Number of users')
plt.title('First device type vs. country destination without the US')
plt.legend(loc = 'upper right')
plt.show()

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

Fig.12: Plot showing distribution of first device type vs. destinations (excluding US)

在美国以外,苹果设备似乎比 Windows 设备更受欢迎(图 12)。

plt.figure(figsize=(20,6))
sns.countplot(x='first_browser', data=df_without_NDF)
plt.xlabel('First browser')
plt.ylabel('Number of users')
plt.title('First browser distribution')
plt.xticks(rotation=90)
plt.show()

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

Fig.13: Plot showing distribution of first browsers used by users

正如预期的那样,30%的预订者使用 Chrome 浏览器访问 Airbnb 网站。接下来最受欢迎的似乎是 Safari 浏览器(图 13)。

用户的首选语言

plt.figure(figsize=(12,6))
sns.countplot(x='language', data=df_without_NDF)
plt.xlabel('language')
plt.ylabel('Number of users')
plt.title('Users language distribution')
plt.show()

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

Fig.14: Plot showing user language distribution

几乎所有用户的语言偏好都是英语。这是合理的,因为我们的人口问题来自我们。

日期

为了直观地显示预订如何随月份和年份而变化,让我们首先将日期列转换为 datetime 类型。

df_without_NDF['date_account_created'] = pd.to_datetime(df_without_NDF['date_account_created'])
df_without_NDF['timestamp_first_active'] = pd.to_datetime((df_without_NDF.timestamp_first_active)//1000000, format='%Y%m%d')
plt.figure(figsize=(12,6))
df_without_NDF.date_account_created.value_counts().plot(kind='line', linewidth=1.2)
plt.xlabel('Date')
plt.title('New account created over time')
plt.show()

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

Fig.15: Plot showing trend of user account creation

2014 年后,账户创建量将大幅增加。Airbnb 在 2014 年后突飞猛进(图 15)。

#Creating a separate dataframe for the year 2013 to analyse it further.
df_2013 = df_without_NDF[df_without_NDF['timestamp_first_active'] > pd.to_datetime(20130101, format='%Y%m%d')]
df_2013 = df_2013[df_2013['timestamp_first_active'] < pd.to_datetime(20140101, format='%Y%m%d')]plt.figure(figsize=(12,6))
df_2013.timestamp_first_active.value_counts().plot(kind='line', linewidth=2)
plt.xlabel('Date')
plt.title('First active date 2013')
plt.show()

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

Fig.16: Plot showing trend of first activity of users in 2013

如果我们看到用户每月的活跃程度,那么高峰月份是 7 月、8 月和 10 月。另一方面,最不活跃的月份是 12 月(图 16)。

用户会话数据探索性分析

正在加载会话数据。

sessions = pd.read_csv("sessions.csv")print("There were", len(sessions.user_id.unique()),"unique user ids in the sessions data.")

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

检查空值。

display(sessions.isnull().sum())

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

检查未知数。

sessions.action_type.unique()

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

我们看到“action_type”列中有 nan 和 unknown,因此我们将所有 unknown 转换为 nan。

sessions.action_type.replace('-unknown-', np.nan, inplace=True)sessions.action.value_counts().head(10)

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

sessions.action_type.value_counts().head(10)

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

sessions.action_detail.value_counts().head(10)

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

plt.figure(figsize=(18,6))
sns.countplot(x='device_type', data=sessions)
plt.xlabel('Device type')
plt.ylabel('Number of sessions')
plt.title('Device type distribution')
plt.xticks(rotation=90)
plt.show()

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

Fig.17: Plot showing device type distribution

正如我们在更早的时候研究用户数据时发现的那样,访问 Airbnb 最流行的设备似乎是 Mac Desktop。现在让我们来看看至少预订了一次的用户的会话行为(图 17)。

session_booked = pd.merge(df_without_NDF, sessions, how = 'left', left_on = 'id', right_on = 'user_id')#Let us see what all columns we have for session_booked
session_booked.columns

让我们来看看预订者通常会做的 5 大行为。

session_booked.action.value_counts().head(5)

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

二。预测建模

#Importing necessary libraries
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

加载数据集并在此过程中进行一些数据预处理。

train_users = pd.read_csv('train_users_2.csv')
test_users = pd.read_csv('test_users.csv')
df = pd.concat((train_users, test_users), axis=0, ignore_index=True)
df.drop('date_first_booking', axis=1, inplace=True)

特色工程

df['date_account_created'] = pd.to_datetime(df['date_account_created'])df['timestamp_first_active'] = pd.to_datetime((df.timestamp_first_active // 1000000), format='%Y%m%d')df['weekday_account_created'] = df.date_account_created.dt.weekday_name
df['day_account_created'] = df.date_account_created.dt.day
df['month_account_created'] = df.date_account_created.dt.month
df['year_account_created'] = df.date_account_created.dt.yeardf['weekday_first_active'] = df.timestamp_first_active.dt.weekday_name
df['day_first_active'] = df.timestamp_first_active.dt.day
df['month_first_active'] = df.timestamp_first_active.dt.month
df['year_first_active'] = df.timestamp_first_active.dt.year

计算时间滞后变量。

df['time_lag'] = (df['date_account_created'] - df['timestamp_first_active'])
df['time_lag'] = df['time_lag'].astype(pd.Timedelta).apply(lambda l: l.days)df.drop( ['date_account_created', 'timestamp_first_active'], axis=1, inplace=True)

让我们用-1 来代替年龄一栏中的 NaNs。

df['age'].fillna(-1, inplace=True)

让我们按 user_id 分组,并计算每个用户的动作数量、动作类型和动作细节。

#First we rename the column user_id as just id to match the train and test columnssessions.rename(columns = {'user_id': 'id'}, inplace=True)action_count = sessions.groupby(['id', 'action'])['secs_elapsed'].agg(len).unstack()
action_type_count = sessions.groupby(['id', 'action_type'])['secs_elapsed'].agg(len).unstack()
action_detail_count = sessions.groupby(['id', 'action_detail'])['secs_elapsed'].agg(len).unstack()
device_type_sum = sessions.groupby(['id', 'device_type'])['secs_elapsed'].agg(sum).unstack()sessions_data = pd.concat([action_count, action_type_count, action_detail_count, device_type_sum],axis=1)
sessions_data.columns = sessions_data.columns.map(lambda x: str(x) + '_count')# Most used device
sessions_data['most_used_device'] = sessions.groupby('id')['device_type'].max()print('There were', sessions.shape[0], 'recorded sessions in which there were', sessions.id.nunique(), 'unique users.')

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

secs_elapsed = sessions.groupby('id')['secs_elapsed']secs_elapsed = secs_elapsed.agg(
    {
        'secs_elapsed_sum': np.sum,
        'secs_elapsed_mean': np.mean,
        'secs_elapsed_min': np.min,
        'secs_elapsed_max': np.max,
        'secs_elapsed_median': np.median,
        'secs_elapsed_std': np.std,
        'secs_elapsed_var': np.var,
        'day_pauses': lambda x: (x > 86400).sum(),
        'long_pauses': lambda x: (x > 300000).sum(),
        'short_pauses': lambda x: (x < 3600).sum(),
        'session_length' : np.count_nonzero
    }
)
secs_elapsed.reset_index(inplace=True)
sessions_secs_elapsed = pd.merge(sessions_data, secs_elapsed, on='id', how='left')
df = pd.merge(df, sessions_secs_elapsed, on='id', how = 'left')print('There are', df.id.nunique(), 'users from the entire user data set that have session information.')

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

#Encoding the categorical features
categorical_features = ['gender', 'signup_method', 'signup_flow', 'language','affiliate_channel', 'affiliate_provider', 'first_affiliate_tracked', 'signup_app', 'first_device_type', 'first_browser', 'most_used_device', 'weekday_account_created', 'weekday_first_active']df = pd.get_dummies(df, columns=categorical_features)df.set_index('id', inplace=True)

分裂训练和测试

#Creating train dataset
train_df = df.loc[train_users['id']]train_df.reset_index(inplace=True)
train_df.fillna(-1, inplace=True)#Creating target variable for the train dataset
y_train = train_df['country_destination']train_df.drop(['country_destination', 'id'], axis=1, inplace=True)from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
encoded_y_train = label_encoder.fit_transform(y_train) #Transforming the target variable using labels#We see that the destination countries have been successfully encoded now
encoded_y_train

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

#Creating test set
test_df = df.loc[test_users['id']].drop('country_destination', axis=1)
test_df.reset_index(inplace=True)id_test = test_df['id']
test_df.drop('id', axis=1, inplace=True)

从训练和测试中移除副本(如果有)。

duplicate_columns = train_df.columns[train_df.columns.duplicated()]duplicate_columns

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

我们发现有重复的,因此我们删除它们。

#Removing the duplicates 
train_df = train_df.loc[:,~train_df.columns.duplicated()]

类似地,处理测试集中的重复项。

test_df.columns[test_df.columns.duplicated()]

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

test_df = test_df.loc[:,~test_df.columns.duplicated()]

训练模型并进行预测

对于给定的预测问题,我们使用 XGBoost 模型。

import xgboost as xgb
xg_train = xgb.DMatrix(train_df, label=encoded_y_train)#Specifying the hyperparameters
params = {'max_depth': 10,
    'learning_rate': 1,
    'n_estimators': 5,
    'objective': 'multi:softprob',
    'num_class': 12,
    'gamma': 0,
    'min_child_weight': 1,
    'max_delta_step': 0,
    'subsample': 1,
    'colsample_bytree': 1,
    'colsample_bylevel': 1,
    'reg_alpha': 0,
    'reg_lambda': 1,
    'scale_pos_weight': 1,
    'base_score': 0.5,
    'missing': None,
    'nthread': 4,
    'seed': 42
          }num_boost_round = 5print("Train a XGBoost model")
gbm = xgb.train(params, xg_train, num_boost_round)

对测试集进行预测

y_pred = gbm.predict(xgb.DMatrix(test_df))

为每个用户 id 选择前 5 个目的地。

ids = []  #list of ids
cts = []  #list of countries
for i in range(len(id_test)):
    idx = id_test[i]
    ids += [idx] * 5
    cts += label_encoder.inverse_transform(np.argsort(y_pred[i])[::-1])[:5].tolist()

创建一个包含用户及其五大目的地国家的数据框架。

predict = pd.DataFrame(np.column_stack((ids, cts)), columns=['id', 'country'])

创建最终预测 csv。

predict.to_csv('prediction.csv',index=False)

我们已经成功预测了 Airbnb 新用户的目的地国家!

下一步:

  1. 由于我们知道哪些目的地国家更受用户欢迎,Airbnb 可以实施有针对性的营销。这意味着,将这些特定国家的营销策略集中于上述练习中确定的用户。
  2. Airbnb 可以提前计划他们应该更多地搜寻哪些国家,以获得住宿提供商的支持,因为他们可以清楚地看到用户访问这些国家的倾向。
  3. 根据特定用户对目的地国家的选择,Airbnb 可能会想到类似的目的地国家(在气候、地形、娱乐选择等方面)。)作为其他可行的旅行选项提供给用户。
  4. 该分析提供了关于用户简档看起来如何的广泛想法。Airbnb 利用这一优势来试验新的营销策略,或者头脑风暴未来几年的需求变化。

如果你喜欢看我的分析,一定要给我掌声!😃

源代码托管在 GitHub 上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值