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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

黑色星期五的消费者行为分析

原文:https://towardsdatascience.com/an-analysis-of-consumer-behavior-on-black-friday-9dd7952fc172?source=collection_archive---------25-----------------------

使用pandasmatplotlibseaborn从客户数据中产生洞察力的教程

W 无论你是在 B2C 还是 D2C 公司工作,你都很有可能会被要求查看一些销售数据集,以创建预测模型或了解消费者行为。在本帖中,我们将探讨一些我们可能想问的关于数据的问题,以及如何尽快提取这些答案。为此,我们将编写两个函数来简化我们的工作,因为我们将绘制一些条形图来回答不同的问题。

我们将使用黑色星期五数据集,该数据集可以在 Analytics Vidhya 网站上找到。您可以查看我们将使用的工具下面的数据信息。

你可以在我的Github页面 上查看我开发的所有代码

工具:

-Seaborn 和 matplotlib 用于数据可视化

  • Pandas 和 numpy 用于数据分析

我们想要回答的问题:

年龄组分析:

-各年龄段购买总额
-各年龄段及城市购买均值

产品类别分析:

  • 各产品类别各城市购买次数
    -产品 _ 类别 1 各城市购买平均数
    -产品 _ 类别 2 各城市购买平均数
    -产品 _ 类别 3 各城市购买平均数

性别分析:

-按性别分列的购买均值
-按性别和年龄组分列的购买均值
-按性别和城市分列的购买均值

职业分析:

-按职业分类的购买均值
-按职业和城市分类的购买均值

序数变量之间的相关性:

-热图
-聚类图

变量:

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

数据帧:

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

虽然我们对数据的第一印象是它们似乎是有组织的,但仍有一些值缺失。Product_Category (2 和 3)列有大量 NaNs 变量,而不是数字表示。我们可以从中获得的信息是,每个 NaN 代表一个事实,即该给定行的产品不属于该特定类别。例如,第一行的产品(Product_id = P00069042)被标识为产品 3,并且只属于类别 1。另一方面,第二行的产品在类别 1 中被标识为 1,在第二类别中被标识为 6,在第三类别中被标识为 14,这意味着它属于所有类别。

除此之外,我们还要注意一个事实,即 g roupby 和 pivot_table 自动忽略 NaNs。这使得我们的工作变得非常容易,因为我们将使用这两种技术来对一些数据进行分组并对它们进行计算操作。除此之外,重要的是要提到,即使我们的数据可能有一些异常值,我们也会认为它已经在这个问题上挖掘出来了。

年龄组分析:

按年龄组划分的购买总量

我们将通过确定年龄组的购买总量以及年龄组和城市的购买方式来开始这个项目。为了做到这一点,我们必须首先使用 value_counts()方法来统计每个组的购买数量,并绘制一个简单的酒吧聊天。其次,我们必须创建一个多级数据透视表数据框架,其中的索引是列 Age 和 City_Category,然后绘制一个条形图。

下图显示,26 岁至 35 岁之间的人在购买数量方面占据首位,其次是 36 岁至 45 岁和 18 岁至 25 岁年龄组,与第一组相比,这两个年龄组的购买量约为第一组的一半。

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

按年龄组和城市划分购买均值

如果我们绘制一个直观的图像来回答这个问题,我们将得到下图。

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

尽管上面的情节给了我们想要的信息,但还是有点混乱。我们必须记住,越容易理解故事情节,读故事的人就会越“快乐”。作为数据科学家或数据分析师,我们有义务尽可能清晰地传递信息,以便那些查看图表或仪表板的人能够立即理解所有内容。因此,为了清楚地比较这些组,我们将分别对它们进行绘图。

您可能会想:“我不想为每个不同的情节编写代码!”。你是对的!谁有时间做那个?!记住时间就是金钱!因此,让我们编写一个函数来完成这项工作,另一个函数来设置轴列表,使其长度与我们在每个可视化中需要的长度完全相同。

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

那些情节不是比我们之前做的那个更好理解吗?现在我们可以清楚地看到,例如,从 0 岁到 55 岁,C 城市的平均购买量大于其他城市。我们还可以看到,B 城市仅在 55 岁以上年龄组中占据首位。简而言之,我们可以从那些情节中获得很多信息,那些需要它们来做商业决策的人可能会很高兴。

产品类别分析:

我们的第二个任务是分析类别和产品。我们将首先绘制一个条形图,显示每个城市每个类别的总购买量。然后,我们将利用我们构建的函数为每个类别的所有产品绘制单独的图表。值得一提的是,一个产品可能属于不同的类别和群体。例如,产品 P00248942 属于所有类别,但在第一类中被命名为组 1,在第二类中被命名为组 6,在第三类中被命名为组 14。说完这些,我们开始分析吧。

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

按城市划分的每个产品类别的购买数量:

下面的图表显示了我们在购买数量方面的某种模式。正如我们所看到的,在所有城市中,产品类别 1 占据首位,其次是产品类别 2 和产品类别 3。每个城市在购买数量上的不同之处在于,城市 B 的消费者比城市 A 和 c 购买更多的所有类别的产品。

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

按城市划分的产品 _ 类别 1 的购买均值:

从现在起,您将会注意到,对于每个可视化,我们将组合数据帧来选择我们想要可视化的数据,并应用我们已经创建的两个函数。

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

我们不会仔细检查所有的情节。相反,让我们只关注我们能从他们那里得到的主要信息。也就是说,首先引起我注意的是产品 19,与其他产品相比,它的购买价格更低(平均不到 40 美元)。此外,我们可以注意到,产品 4 的购买意愿最强,城市 C 排名第一,其次是城市 B,城市 B 比城市 C 稍有优势。

按城市划分产品 _ 类别 2 的购买均值:

现在让我们分析类别 2 的所有产品。正如数据描述中提到的,该产品可能属于其他类别,我们可以通过查看下面的图表来注意到这一点。我们有一组也属于第一类的 17 种产品,可以看出,产品 10 具有最大的购买意义。城市 C 再次占据第一位,其次是城市 B 和 A(类似于产品类别 1)。

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

按城市划分产品 _ 类别 3 的购买均值:

下图显示了第三个产品类别的信息。我们可以看到,这一类别有 15 种产品,产品 3 在所有城市中具有最高的购买价值。

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

性别分析:

我们都知道了解性别对购买决策的影响的重要性。事实上,许多研究已经提出了一些问题,例如,在家庭中谁做购买决定。除此之外,考察性别在购买决策风格和产品类别、价格和其他特征方面的差异也很重要。

也就是说,让我们进行数据分析,获得一些简单但相关的客户行为洞察。首先,我们将绘制总购买量和每个性别的平均购买量。然后,我们将按年龄组绘制购买均值图,最后,我们将看到在城市 A、B 和 c,男性和女性在购买产品方面的差异。

按性别分列的购买数量和购买均值

现在,看下面的图表我们可以看到男性消费者的总数( 414259 )大约是女性( 135809 )的三倍。我们还可以注意到,令人惊讶的是,两性的购买手段并没有太大的差异。尽管男女人数存在明显差异,但男性消费者的平均购买量仅略高于女性(700 美元)。基于这一点,我会说这些女性消费者对企业来说真的很重要,例如,可以成为特别营销活动的目标。

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

按性别和年龄组划分的购买均值:

出于比较不同年龄段和性别的购买模式的目的,我们可以看看下面的条形图。他们显示,对于 18 至 25 岁的顾客,男性群体的购买均值比女性群体的购买均值高出 1000 美元以上。我们还可以看到,男性消费者在所有年龄组中都占据首位,尽管这种差异在 18-25 岁年龄组中并不明显。

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

按性别和城市划分的购买均值:

最后一项性别分析包括了解每个城市的两性是如何购物的。为了实现这一目标,让我们花一点时间来分析下面的条形图,它准确地描述了我们正在寻找的东西。他们显示,在所有城市中,男性比女性花费更多的钱(这一差异仅在 C 市有显著意义),C 市在两性的购买手段方面都名列第一。同样值得注意的是,居住在 B 市的男性比居住在 A 市的男性购买更多,而来自 A 市的女性比居住在 B 市的女性购买更多。

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

职业分析:

你认为消费者的职业类型会影响他们的购买行为吗?嗯,我希望职业和消费者对他们所花金额的态度之间有一些联系。让我们通过绘制条形图来检验这一点。

让我们从绘制每个职业的购买均值开始。该柱状图为我们提供了每位消费者在职业方面的购买习惯的综合信息。

看下面的图,我们可以注意到,职业 12、15 和 17 位于购买方式的前三位。我们还可以看到,职业 9、19 和 20 比其他职业花费的钱少。这些信息真的有帮助吗?我们能利用关于每个专业人员在城市花费的金额的洞察力吗?这正是我们在随后的可视化中看到的。

虽然第一个条形图给了我们重要的信息,但第二个数据 viz 让我们更好地了解了 A、B、c 三个城市中每个职业所花的钱。

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

城市职业:

下面的条形图描述了每个城市中每个职业的购买均值。有趣的是,在几乎所有的职业中,C 城拥有最大的购买手段。我们只在职业 8、9 和 19 中看到了这种模式的变化。另一个有趣的事实是,在 A 城市,数字 8 是他们职业的人花费最多的钱。

所以,关键是,如果我们在不同的图表中把每个职业分开,我们更有可能轻松地利用洞察力。换句话说,这使得其他团队(如市场部)的同事使用我们的发现变得特别容易。我们可以简单地将它们导出到 plots 文件夹,人们可以浏览这些图像,并能够将它们拖放到 PowerPoint 演示文稿或其他报告中。

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

热图:

基本上,热图是一种图形数据表示,使用颜色编码方案来表示不同的值。在我们的例子中,我们正在生成数据集特征之间相关性的热图。

为了生成热图,我们必须对分类数据进行数字编码。换句话说,我们必须将列 Product_ID、Gender、Age、City_Cat 和 Stay_In_Current_City_Years 转换为数字列,如下面的代码行所示。

编码之后,我们得到了下图。有趣的是,这两种产品之间存在正相关关系,这正是我们可能期望看到的,因为它们可能属于不同的类别。此外,年龄和婚姻状况之间的相关性还有一点值得一提。

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

聚类图:

我们将通过绘制一个集群图来完成这个分析。聚类图使用层次聚类将要素按其相关程度进行分组。当我们分析变量之间的关系时,这使得变量之间的相关性特别有用。在我们的例子中,我们有 11 个要研究的特性,因此,不是目测变量是正相关还是负相关的热图,而是将图表分割成簇,这样更容易分析。

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

查看上面的图,我们可以看到,聚类算法认为产品类别 2 和 3 聚类在一起,而年龄和婚姻状况形成了另一个强关联的聚类。我们可以通过查看它们之间的
链接来观察。它们首先形成并具有最短的分支,这表明它们更类似于具有最高分支的那些。

我希望你和我一样喜欢这个分析。我们已经看到,当我们需要尽快产生洞见时,写作如何快速生成我们的发现的可视化,并使我们的生活变得更容易。如果你有更有效的方法,请随意评论。

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

爱尔兰房地产价格分析

原文:https://towardsdatascience.com/an-analysis-of-property-prices-in-ireland-6fc34a56ac87?source=collection_archive---------19-----------------------

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

都柏林正处于住房危机之中。城市的部分地区已经引入了租金控制,但是还没有对价格产生影响。许多年轻工人无力租房,更不用说凑钱购买住宅了。作为数据探索的一个练习,我想看看爱尔兰的房屋购买价格以及影响房产成本的因素。

2011 年,物业服务监管局(PRSA)建立了一个住宅物业价格登记册,以努力使物业价格对买家更加透明。从他们的站点:

它包括自 2010 年 1 月 1 日以来在爱尔兰购买的所有住宅物业的销售日期、价格和地址,已向税收专员申报,用于征收印花税。

处理数据

所有记录均可从 PPR 物业价格登记处网站以 CSV 格式下载。在这篇文章中,我们将看看过去两年的数据。应该注意的是,PPR 页面包含一个免责声明:

PSRA 不以任何方式编辑数据。它只是以完全透明的方式公布向税务专员提交的申报数据。如果数据文件包含印刷错误,那么这些错误将出现在登记册上。

让我们来看看使用 Pandas 清理原始信息的一些步骤:

  1. 删除价格不是完全市场价格的属性,并删除包含少量爱尔兰语言属性描述的行。
df = df[df['Not Full Market Price'] == 'No']df = df.drop('Not Full Market Price', axis=1)df = df[(df['Description of Property'] == 'Second-Hand Dwelling house /Apartment') | (df['Description of Property'] == 'New Dwelling house /Apartment')]

2.看看 2017 年以后的数据子集。

df['Date of Sale (dd/mm/yyyy)'] = pd.to_datetime(df['Date of Sale (dd/mm/yyyy)'], dayfirst=True, format='%d/%m/%Y')df = df.rename(columns={'Date of Sale (dd/mm/yyyy)': 'Date of Sale', 'Price (€)': 'Price'})df = df[(df['Date of Sale'] > '2017-01-01')].reset_index(drop=True)

3.将 price 列从字符串解析为浮点数。

df['Price'] = df['Price'].apply(lambda x: x.lstrip('\x80'))df['Price'] = df['Price'].apply(lambda x: float(x.split()[0].replace(',', ''))).astype(float)

4.尝试使用谷歌的 API 进行地理编码,以获取属性的纬度和经度。

为了清楚起见,我应该指出,我为过去两年的 PPR 数据获得的坐标证明是不够准确的,所以我没有把结果包括在这篇文章中。错误很可能在于数据中包含的记录地址(这是 PRSA 自行报告和未经编辑的),而不是谷歌的实际 API。如果将每个房产的县附加到地址的末尾(有些地址包含县,但有些不包含),则准确性可能会提高。不管有多不准确,我觉得包含请求坐标的代码是很重要的。

获取请求 url 创建者功能:

def url_creator(address, url='https://maps.googleapis.com/maps/api/geocode/json?address=', api_key=''):
    logger.debug('Creating API request URL')
    add_list = address.split()
    add_list = [line + '+' for line in add_list[:-1]]
    add_list.append(address.split()[-1])
    add_url = "".join(add_list)
    return url + add_url + '&key=' + api_key

纬度和经度请求功能:

def lat_lng(address, api_key=''):
    logger.debug('Requesting geospatial info from Google API')
    url = url_creator(address, api_key=api_key)
    try:
        response = requests.get(url)
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        logger.error(e)

    results = response.json()['results']
    if len(results) != 0:
        logger.debug('Found geospatial coordinates')
        return results[0]['geometry']['location']['lat'], results[0]['geometry']['location']['lng']
    else:
        logger.debug('Could not find geospatial coordinates')
        return np.nan, np.nan

我之所以编写自己的代码来使用地理编码 API 完成这些(以及更多)工作,而不是使用流行的 geocoder 库,是因为该库中强加的 API 的配额行为已经过时。Google 最近已经可以对其地理编码 API 进行无限数量的请求,但是 geocoder 的 Google 地理编码方法似乎将 API 调用限制在 2500 次。如果您感兴趣,我在本文末尾链接的 GitHub repo 中包含了我用于处理数据和地理编码的所有代码。

房地产价格登记册分析

查看数据的标题,我们可以看到每一列都包括分类数据,不包括房产的实际价格。

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

Figure 1: Head of PPR data.

大多数列也只包含 2-3 个唯一值。缺乏数字数据(如卧室数量、可用设施、房产的确切面积,单位为平方米)。m 等。)和重要的分类变量(例如,该物业所面向的方向)使得该数据对于机器学习来说不是最佳的。然而,我们仍然可以对影响爱尔兰房地产价格的因素获得一些有价值的见解。

让我们看看每个县在数据中的表现如何:

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

Figure 2: Value counts for counties in PPR data.

我们可以看到,都柏林、科克、基尔代尔、戈尔韦和米斯在过去两年中购买房产的数量最多。绘制这 5 个县的房地产价格分布图:

Figure 3: Distributions of 5 most represented counties.

一些明显的异常值,尤其是在都柏林,正在打破小提琴阴谋的规模。让我们只看看高达€200 万英镑的价格。

Figure 4: Distributions of 5 most represented counties with property price limit at €2m.

不出所料,都柏林拥有最昂贵的住宅物业(即使在剔除极端异常值后),平均房价在€17 万到€15 万之间,高于上述其他 4 个县。有趣的是,基尔代尔和米斯的平均房价更高,尽管科克和戈尔韦提供了蓬勃发展的学生文化、夜生活、旅游以及熟练和非熟练工作机会。这可以归结为他们靠近都柏林的城市扩张。让我们深入研究这个问题,并把与都柏林接壤的另一个县——威克洛纳入我们的分析,看看那里的房价是否与基尔代尔和米斯的房价相当。

Figure 5: Distributions of counties bordering Dublin with property price limit at €2m.

从图 5 来看,维克罗的平均房价甚至比基尔代尔和米斯还要高。似乎大多数人宁愿住在都柏林的郊区,也不愿搬到更远的地方,如戈尔韦或科克。都柏林及其周边县的综合房价中值为€31 万英镑,而爱尔兰其他地区的房价中值正好是€15.5 万英镑的一半。人们想要住在爱尔兰的经济中心或附近,这并不完全令人震惊,但这些县和都柏林之间的住宅价格差异的确切程度看起来很明显。

让我们回到图 3,仔细看看极端的异常值。我们可以看到,都柏林 2017 年至 2018 年间的最高房价为€7500 万英镑。让我们看看所有其他县的最高房价,因为我们也可以看到,在过去的两年里,科克的一所房子以 6770 万英镑的价格卖给了€。

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

Figure 6: Most expensive residential property in each county.

都柏林、科克、戈尔韦,有趣的是,克莱尔在过去几年拥有最昂贵的住宅。但是这些仅仅是整栋公寓大楼吗?无数公寓的价格被汇总并列在一个地址下?正如 PPR 网站所述,情况很可能就是这样:

在许多公寓以单一价格出售的情况下(例如橡树大道 1 号至 15 号公寓以€200 万英镑的价格出售),登记册上的信息取决于向税务专员提交的内容。

例如,文件管理器可能已经输入了-

-只有一套公寓(如橡树路 1 号)的价格为 200 万€;

-每套公寓分开,并在每套公寓之间划分价格(例如,1 号公寓为€133,333,2 号公寓为€133,333,依此类推,15 号公寓为€133,333)。

-所有公寓(如橡树大道 1 号至 15 号),价格为 200 万€。

出售日期是印花税报税表的申报人输入的日期,作为转让物业所有权的契据日期。

深入挖掘构成前 4 名最昂贵房产的个人地址,发现它们确实都是公寓楼(其中一栋是学生宿舍)。然而,基尔代尔的小幅上涨是一栋单房以 800 万€的价格售出。我敢肯定,如果我们挖掘都柏林的离群值,我们会发现一些非常富有的个人的昂贵房产。各县卖的最便宜的楼盘呢?

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

Figure 7: Cheapest residential property in each county.

这里的县与县之间有很多相似之处。我把这归因于都柏林、科克和戈尔韦的大量公寓,它们打破了图 6 中的比例。每个县最便宜的住宅可能是小公寓(在城市地区)或小屋(在农村地区)。这个情节最有趣的一面是,都柏林实际上在过去的两年里卖出了最便宜的住宅。

你可能会认为都柏林周围的价格如此之高是因为人口过剩和城市的溢出。快速浏览一下全国售出的房屋数量就可以发现,情况并不一定如此。都柏林购买了 33,074 套房产,都柏林及其周边各县购买了 45,742 套房产,除都柏林、基尔代尔、米斯和威克洛之外,该国其他地区购买了 54,557 套房产。同样,整个公寓楼在登记册中被列为一个地址的事实可能会使这些数字偏离一个很好的位置,但有趣的是,尽管该国大多数人口生活在都柏林或其周围,但仍有大量住宅物业在首都以外被购买。在过去的两年里,爱尔兰总共购买了 100,299 套住房。其中 81,886 套是二手房,其余 18,413 套是新房/公寓。€新房的中值价格是 28.1 万英镑,而€旧房的中值价格是 20.7 万英镑——两者之间的平均差距接近€的 8 万英镑。看起来购买一套二手房可能是个不错的选择(如果你安顿下来后不需要太多的维修)。

此时,你可能会说“好吧,我明白了。都柏林的房价很贵”,你不会错的。但你会问,都柏林哪里的房子平均最贵?从图 8 来看,答案就在南边。

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

Figure 8: Median property prices per Dublin postcode.

并非所有都柏林的邮政编码都出现在最近两年的 PPR 数据中。有很多缺失值,在这些值中,提交房产购买的人没有包括邮政编码,或者只是在地址中包括了邮政编码,而没有填写实际的邮政编码字段。查看我们现有的数据,我们发现都柏林 6 区和 6w 区的平均房价最高。这些都是都柏林富裕南区的特别富裕的地区。都柏林 14 酒店也位于该区域旁边,因此它拥有第二贵的酒店是有道理的。都柏林 4 和 16 完成了这个图表的南部统治。任何熟悉该地区的人都不会感到惊讶,该县西部和北部的邮政编码构成了这里最便宜的房产。当然,这并不是对这些地区的任何人的轻视——都柏林 15 区(我住的地方)也是房产价值中值最低的地区之一。

那么我们从这个分析中学到了什么呢?嗯,我们知道,如果我们想省钱,我们应该在都柏林及其周边 3 个县之外购买一处房产(也许有人可以对搬到奥法利和通勤到都柏林所节省的钱进行成本效益分析?).然而,PPR 的数据远非完美,因此,任何基于这些数据的房地产价格分析都应持保留态度。房产价值被像整个公寓大楼被列为一个地址这样的事情打乱了——特别是在都柏林、科克和戈尔韦,这些地方已经建起了城镇中心,并拥有爱尔兰最大的大学。最后,这些数据的自我报告、未被触及的性质带来了错误,使得地理编码等工作比发布前编辑数据要困难一些。

Chirag Chadha 是爱尔兰都柏林 UnitedHealth Group/Optum 的数据科学家。你可以通过他的电子邮件(chadhac@tcd.ie)或通过他的 LinkedIn 联系到他。

[## cchadha 2/PPR-外壳

使用房地产价格登记数据预测爱尔兰的房价- cchadha2/ppr-housing

github.com](https://github.com/cchadha2/ppr-housing)

《奇异星球》系列漫画解析

原文:https://towardsdatascience.com/an-analysis-of-the-strange-planet-comic-series-56410af3a5b1?source=collection_archive---------24-----------------------

以及构建分类模型以从任意长度的列表中选择项目的挑战

对于那些不熟悉陌生星球的人来说:

这是什么?

奇异星球是内森·w·派尔创作的网络漫画。在这些漫画和他拟人化鸽子的周末故事之间,他的是我最喜欢关注的 instagrams 之一。在漫画中,派尔发表了关于普通人类互动的文章,将人类描绘成外星生物

我花时间分析了 instagram 上发布的所有漫画,以便建立一个模型,可以预测任何给定漫画的帖子描述。

为什么会有人想预测描述?

几乎每篇帖子都包括一个单词的漫画描述,格式如下:

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

随着时间的推移,追随者在阅读这个单词之前就已经开始猜测它了(并且在他们猜对的时候宣布)。这引发了如下讨论:

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

如果你不跟着漫画走,很难解释为什么玩这个猜谜游戏很有趣或令人兴奋,但对我和许多其他人来说,就是这样。

这一切都启发了我,让我看看我是否能创造出一种能替我猜测的算法。

选择用于分析的漫画

为了更容易地训练我的预测模型,我只分析了符合以下标准的漫画:

  • 漫画正好是 4 个面板
  • 漫画中准确地列出了描述
  • 描述只有一个词

几乎每部漫画都符合这些标准,给了我 138 部漫画。

探索性数据分析

字数

《奇异星球》漫画平均 35 个字。最短的漫画有 5 个字,最长的漫画有 74 个字。第三面板最有可能没有文字(14%的漫画第三面板是空的)。

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

随着时间的推移,漫画也变得稍微长了一些:

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

漫画中帖子描述的位置

关于漫画中描述出现的字数,似乎没有明显的趋势。然而,描述更有可能出现在第三个或第四个面板中,而不是第一个或第二个面板中(如果描述性单词在漫画中出现不止一次,所有实例都会在下面显示)。

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

词汇使用频率

我运行了两个模型,看看哪些词在帖子中使用频率最高。在第一个模型中,我没有排除停用词,因为我认为陌生星球宇宙中的生物的语言可能没有 Python 分配给英语的停用词。我发现漫画中最常用的 20 个单词都属于停用词的范畴,所以我做了一个新的模型,把停用词排除在外。(经常阅读的读者不会惊讶,找到了走向巅峰的“寄托”。)

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

从第二个词表开始,我还构建了一个词云,展示《奇异星球》中最常用的词。

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

情感分析

我利用了 TextBlob 库中的朴素贝叶斯情感分析。从这个分析中,我记录了一个漫画或描述词有积极情绪的可能性。

从这个情绪分析中需要注意一些事情:

  • 该描述更有可能被分析为具有中性情绪(概率=0.5)。这是有意义的,因为描述比整个漫画更少的材料来推断情绪。
  • 蓝线表示图表中漫画的情感和描述的情感相同的区域。在这条线以上,描述比漫画更可能是正面的。在这条线以下,漫画比描述更可能是正面的。大多数点都在这条线以下,表明漫画倾向于被解释为更积极的。
  • 一般来说,奇怪的星球漫画很可能有积极的情绪(更多的点在图表的右侧)。

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

单词长度

描述往往比漫画中的平均单词长,如下面的两个直方图所示。漫画中的单词长度倾向于右偏,而描述性单词具有更正态/双峰分布,平均为更长的单词。

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

模型

一些假设

到目前为止,停用词从未被用作描述。为了简化我的模型并使它(可能)表现得更好,我假设一个停用词永远不会被用来描述一篇文章。

在所有的漫画中,只有两个描述性的词用了两次(其余的都是独一无二的):

d e l i b e r a t e

c o m p l e t i o

为了建立模型,我做了一个类似的假设,即一个描述词永远不会被重新使用。即使我知道这不是真的,但这种情况经常发生,我更愿意使用正确的假设,因为我知道当一个单词被重复时,我将是不正确的。

模型构建挑战

通常,在创建分类模型时,您希望它接受输入数据并输出该数据的分类:

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

然而,在这种情况下,我们并不是确切地看着一个单词并猜测它是否是描述。相反,我们查看不同长度的列表,并预测列表中的哪个单词是描述。

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

为了解决这个问题,我将我的训练数据转换成一个传统的分类问题,其中漫画中的每个单词都是一个独特的样本。对每个单词样本进行的预测是将它放入两个类别之一:“是描述”或“不是描述”这允许我建立一个标准的分类模型(在这个项目中,是一个随机的森林模型)。

一旦我建立了模型,我就以稍微不同的方式处理我的测试数据。对于漫画中的每个单词,我使用分类模型来分配成为漫画中每个单词的描述的概率。然后,一个单独的模型选择概率最高的单词作为其对描述的猜测。

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

不平衡的班级

由于我用来创建训练数据集的方法,我的数据被拆分为:

  • 我的样本中有 3.8%属于“描述”组
  • 我的样本中有 96.2%属于“不是描述”组

对于不平衡的类,我努力创建一个模型,它不会只是假设所有的样本都不是描述。为了解决这个问题,我在我的训练数据上使用了这里列出的过采样和欠采样技术。

为了传达重采样如何改变我的模型所基于的数据,这里有两个配对图,显示了我的模型正在使用的一些输入要素。在下面的图中,蓝点表示漫画中的单词,而不是描述中的单词。橙色圆点表示描述词。

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

左边是我重新平衡之前的数据。右边是我重新平衡后的数据。请注意右图中橙色点的百分比有多大。

还要注意,EDA 部分列出的一些观察结果可以在上面的散点图和直方图中看到。例如:

  • 描述词的长度通常比漫画中的其他词长(参见第 2 行第 2 列的直方图,其中描述的分布更长)
  • 漫画情感与描述(紫色点)的早期散点图表明,描述比整体漫画更可能是中性的。然而,该配对图包括单独的所有单词,利用该数据,我们看到不是描述单词的单词最有可能是中性的,而描述单词相对于其他单词具有相当正常的情感分布(参见配对图中的第三行)。

结果呢

我很难过地说,我的模特表现得很可怜。在我试图用数据拟合的 37 部漫画中,我没有一个单词是正确的。下面是我试图猜测的单词(“单词”)和我的模型预测的单词(“rf_predict”)。

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

当我在重新采样的训练数据上拟合模型时,我有理由相信模型会表现良好。我的 f1 成绩是 0.95,准确率是 0.97。这远远高于我采样的 75%的基线精度。

那么为什么我的模型表现这么差呢?

对于在训练数据中表现良好而在测试数据中表现不佳的模型,我的第一直觉是该模型过度适合训练数据。然而,在这种情况下,这可能是也可能不是一个问题。

训练数据有一个更容易解决的分类问题:

一个给定的词是不是描述?

通过随机猜测,这个模型有 50%的可能性是正确的。

然而,测试数据是一个更具挑战性的问题:

在这个单词列表中,哪个单词最有可能是描述?

通过随机猜测,正确的几率从 20%到 2%不等。

其他一些很难预测的原因描述如下:

  • 虽然 138 幅漫画对于创作者来说在短时间内完成是一个很大的数目,但这真的不足以制作一个好的模型。
  • 在这个训练营中,我的数据建模工具每天都在增加。我在两周内学到的一项新技能可能会帮助我更好地构建这个模型。一整年后,有了新的漫画和新的技能,谁知道我的准确度还能提高多少。
  • 我使用的输入特征可能不能很好地预测输出
  • 我用来对数据进行重采样以改善不平衡类的方法可能会引入新的问题。

结论

我本来非常希望做一个模型,能在大部分时间(或者部分时间,或者至少一次)告诉你一个帖子的描述。不幸的是,在对我的模型进行多次更新后,我无法到达那里。

作为对派尔先生的敬意,也为了表达我看到我的预测模型的性能时的感受,我画了下面这幅漫画。

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

a n t i c i p a t e

我还欣慰地知道,已经有一部奇怪的星球漫画承认做出某些预测是多么具有挑战性:

[1]停用词是既频繁使用又传达不了什么意思的词。在英语中,这些单词包括:I,the,it,who,that,因为,any…删除这些单词通常很有用,因为它们主要是给模型添加噪声。

[2]在自然语言处理(NLP)中,朴素贝叶斯模型从所有单词相互独立的假设开始。在某些情况下,这可能是有问题的(例如,如果文本说“不快乐”,单词“不”和“快乐”被解释为不相关)。虽然这看起来像是一个天真的假设(明白吗?明白了吗?😃 ),它通常可以创建有用的预测。在这种情况下,我将漫画的情感分析与漫画分析中的一个词进行比较,我相信通过独立地分析每个词,我会得到最好的结果。

[3]在建立预测模型时,您总是希望将现有的数据拆分为训练数据和测试数据。您的模型是围绕给定的训练数据构建的。然后,为了让您看到模型实际上有多预测,您给它您的测试数据集(它以前没有见过)来进行预测。

在大多数情况下,您会以相同的方式处理训练数据和测试数据。然而,为了更清晰地训练我的模型和更真实地测试我的数据,我对训练数据和测试数据进行了不同的处理。

知识工作者度量方法

原文:https://towardsdatascience.com/an-approach-to-knowledge-worker-metrics-55574efc210c?source=collection_archive---------26-----------------------

如果你不能管理你不能衡量的东西,那么我们中的很多人实际上都是无法管理的。这是我如何解决这个问题的方法。

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

Photo by Austin Distel on Unsplash

在最近的一次“振作起来”的探索中,我首先确定了基石目标——能够有效地成就或毁灭我的世界的大的、影响广泛的生活组成部分。当列出这些目标时,我立即写下“在工作中更加有效”。这是我最大的挑战之一(也是潜在回报最大的潜在改进领域)。我缺乏专业效率表现在很多方面:虽然我的实际工作成果高于平均水平,但这是以加班和周末加班为代价的,在工作日把自己磨得筋疲力尽,发现自己经常处于近乎疯狂的状态,这与我周围的文化格格不入。我工作的方式不是…工作。

解决复杂挑战的第一步总是研究,了解比我聪明得多的人对这个问题的看法。由于我的研究必须支持我更大的跨职能目标(不仅限于工作效率,还包括我更大的目标“让我的 sh*t 在一起”),如果没有上下文,这些来源可能会显得有点古怪;然而,来自每个工作线程的位一起建立该方法所基于的给定原则。以下是我阅读清单中的相关标题,排名不分先后:

出于多种原因,所有这些作品都值得一读,如果你有时间,直接去阅读它们的来源会更好。从综合的假设、断言和普遍支持的结论中,我得出了这些原则:

  • 手艺可以赋予生活意义,可能是通往幸福的捷径。自从尼采宣布上帝已死,我们被迫寻找自己的人生目标;掌握一门手艺并从我们的劳动中结出实实在在的果实,这种行为已经被证明是做到这一点的方法。
  • ***手艺要求一个人深深地投入到自己的工作中。*这种深度参与有多种名称(“心流”、“深度工作”以及某种程度上的“实际掌握”),是收获工艺益处的关键因素。
  • 对于知识工作者来说,手工艺(通常)的投资回报率最高。一名年薪 15 万美元的资深营销人员最有价值的实践是:在这种情况下,设计大获成功的新活动或提高广告支出的效率。离开他们的工作(如填充报告)的时间会产生非常低的投资回报率。
  • 因为知识工作很难衡量,我们默认用“忙碌”来衡量这在 Newport 的深度工作中得到了很好的扩展;没有具体的、短期的迭代(即每日)度量来定义成功,商业文化倾向于关注谁在做最 可见的 工作——而不考虑工作的价值。谁在聊天中回复最快,或者凌晨 3 点发送的电子邮件最多?谁和老板见面次数最多,cc 的人最多?这通常是知识工作者价值的实际衡量标准。
  • 对于大多数知识工作者来说,忙碌是成本中心,而不是利润中心。回复电子邮件、参与即时消息聊天和在状态会议中坐在幻灯片台前都不是有利可图的任务。没有针对“很少使用的中层管理电子邮件链”的第三方市场;客户购买创新的产品、有影响力的服务、更高效的流程和令人兴奋的功能。这些有价值的东西是知识工作者执行工艺的产品——设计、发明、工程、审计和营销——这几乎总是与繁忙的工作不一致。电子邮件、聊天和开放式办公室飞临都属于商务旅行中的销售费用。奖励凌晨 3 点发邮件者的知识工作的公司文化,也可能会根据销售人员在销售活动中的花费来奖励他们。
  • 如果知识工作者从工艺中获得最大的投资回报,并且工艺最有可能为知识工作者提供意义和快乐的源泉,那么管理知识工作者就变成了让他们在工作日尽可能多的时间从事深度工艺工作。

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

Woah. You said it NDT.

该理论

我的职业是数据工程师。我一直认为,与其他知识工作者不同,我们这些从事软件工作的人拥有真正的生产力指标优势——我们有故事点,对吗?除了当我更深入地探究我在效率上的挫折和失败时,它们几乎从未植根于架构和开发软件的技术工作中。我能够把我的团队锁在一个有白板的房间里并解决一个复杂问题的时候,是我感到活着、有目标并深深沉浸在“心流”中的时候。这些时期充满活力。会议的冲击,像俄罗斯方块一样塞满我收件箱的电子邮件流,像数字爆米花一样充斥在我的通知栏中的松弛脉冲,成为我精疲力竭的重压。更重要的是,这些工作没有一项是我的度量标准可追踪的;回复一封 25 人的电子邮件链已经有 3 周了,有多少敏捷故事点?

所以我收集了我所做的所有不同类型的工作,并把它们分成不同的商业价值类型。然后我把它们按照从深度工艺工作→浅度无用功的等级分类(深度工作、浅度工作和这个一般概念的大部分直接来自纽波特的书,同样 100%值得一读)。这是我想到的:

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

Gradient of different types of knowledge work

我的排序是从最忙碌的工作(最没有价值)到最有技术含量的工作(最有价值):

  1. 业务的业务是我所说的公司会议、管理和评估工作,以及通常知识工作者作为员工需要做的与他们的实际角色无关的所有事情。
  2. 充当人类路由器直接取自深度工作*,这可能是我听到的关于大量电子邮件和即时消息的最佳描述,这些邮件和即时消息用于移动信息,而没有在这个过程中增加任何高技能价值。经常包括“请指教”这样的话。*
  3. 作为代表出席会议,通常表现为“我们这里应该有一个<的人插入你的团队>”。
  4. “随机”即传统上被认为是“偷懒”的事情,比如聊足球比赛或在社交媒体上看视频。
  5. 一般思维&执行像医生给病人量血压。
  6. 捷径思维,比如一个经验丰富的营销人员告诉一个初级人员发送电子邮件应该使用什么样的模板。
  7. 公共场合比如建筑师在会议上演讲。
  8. 跨学科学习即数学家阅读有关拿破仑的战术。
  9. 高技能学习就像一名工程师阅读应用程序设计的新理论。
  10. 广泛而有影响力的思维比如一名机械工程师在考虑一种新的内燃机方法。
  11. 高技能思维比如一名会计师在为一家大公司考虑最佳的税收方案。
  12. 高度熟练的执行比如做你擅长的手术。
  13. 极具影响力的执行即建立一项改变世界的技术,如反重力或汽车。

其他知识工作者可以并且应该移动这些,添加它们,根据需要取走一些,直到感觉合适为止。不同的组织会对不同的工作有不同的评价——因此,虽然一个团队可能都同意前 3 条,但管理层可能会觉得高技能学习比考虑大事更重要。一些要点:

  • 与许多人相比,我把捷径思维放在了较低的位置,因为“快速提问”对深入工作的过程极具破坏性。为新开发人员节省 10 分钟搜索代码库的时间(无论如何,他们可能会从中受益)可能会打破高级开发人员的创造性思维,这将会是一笔财富。
  • 一般的想法是,当人们被“因为他们聪明”而卷入一些他们不需要的事情时。首席执行官想要一个有经验的人来检查这个电子表格,所以他们指派了一个首席会计师,这个人非常胜任这项工作。
  • 注意,这个模型中的“随机”比参加一个松散相关的会议更有价值。如果一个知识工作者一天中长时间沉浸在工艺中,花 15 分钟看一段猫视频(一种精神净化)来冷却他们的大脑可能是他们投入“第二轮”所需要的
  • 我在公众面前挣扎。对于一些公司来说,在招聘人才时保持公众的关注是至关重要的。对于一些知识工作者来说,这是他们职业自我形象的重要组成部分。但是在两端都有一些公司和一些知识工作者,他们根本不在乎宣传,这将导致这种情况。

如果它有价值,就有衡量标准

所以我现在对我每天做的不同类型的知识工作有了一个标量值。如果我记录了我在每种知识工作上花费的时间,我就有了第二个数据点来矢量化我的工作分解。我可以将这些看做单独的条形图(每种类型的工作一个条形图,高度代表我每周投入的时间),或者我可以将 x 轴作为“工艺等级”,值为 1 代表业务的业务工作,值为 13 代表具有广泛影响力的执行工作,值为 13 代表具有广泛影响力的执行工作,值为 T3,y 轴代表累计小时数。然后我们有一个理想主义的国家目标,在一张图中,看起来像这样:

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

现在这和我现在的工作曲线看起来相差甚远。但这给了我和我的领导一套清晰可追踪的衡量标准,告诉我时间的使用效率(本质上是我的“知识工作者投资回报率”)。

在实践中

过去我在组织系统上失败的地方之一是保留我现有的工作流,同时试图从技术上从它们中提取指标。我设计了复杂的系统,从几十个应用程序中导入数据,从一个应用程序中的动作触发带时间戳的警报,以在另一个应用程序中捕捉。正如软件开发人员经常了解到,与其构建复杂的测试流程,不如首先编写更多可测试的代码,我也了解到,最好调整我的工作流程和习惯,使其更易于管理。以下是方法。

  1. ****放好电话。认真。我不是说“与世隔绝”,我是说通过只使用一个设备来克服管理多个设备的第一个主要障碍。我们通过电话交流的任何方式都有一个桌面等价物;短信、社交媒体和大多数聊天应用都可以在浏览器中使用。如果这意味着我的一些朋友需要停止使用他们坚持使用的任何深奥的聊天应用程序,选择一个主流应用程序,那么就这样吧。我不想错过我的另一半打来的紧急电话,所以为了以防万一,我把手机锁在了桌子上,把铃声的音量调到最大。
  2. *****简化工具集。**目前,我仅使用几个组件来跟踪我的知识型员工的投资回报率。
    *谷歌日历(我的工作日历)
    • 本网站转换下载的日历。ics 文件到 a .csv
    • 这个 Chrome 扩展来跟踪我的浏览器使用
    • Google Sheets 来收集和整理数据
      我想建立一个完全自动化的系统,每天从每个来源 ETLs 数据(毕竟我是一个数据工程师),但我决定最好是证明然后润色。如果几个月的手动生成的报告证明是有价值的,我将采取下一步,将实现为一个完全自动化的系统。而且我保证让它开源:)。***
  3. 单任务。你可以自己阅读所有关于注意力残留的内容,但是可以说,一心多用对生产力有复合的负面影响。同样,如果我试图同时做几件不同的事情,也没有合理的方法来跟踪我在每一项任务上花了多少时间。这意味着当我在解决一个软件问题时,我会关闭我的电子邮件、Slack、Instagram 等。
  4. 从日历开始。对于我日历上的每一项,我都在描述中添加了一个标签,类似于KWV=3,其中 KWV 代表“知识工作者的价值”,3 代表工作类型(在我的量表中是“作为代表”)。对于我不拥有的会议,这只会显示在我的个人副本上,对于我拥有的会议,没有人会知道这意味着什么。现在,我可以在我的日历上安排一些块来代表对特定任务的专注。如果我要在午饭前处理一张 JIRA bug 票,我可以在我的日历中创建这个块,并在主体中包含适当的KWV=12标记。
  5. 跟踪其余的。对于白天需要做的所有“肤浅的工作”,使用我的浏览器可以让跟踪插件替我做这些工作。写电子邮件、回复邮件、给朋友发短信、查看黑客新闻——这一切都发生在时间紧迫的时候。如果你认同“创造者/管理者”理论(我也认同),这些应该发生在一个指定的时间段,与你一天中最有效率的时间相对(所以对我来说,我在早上状态最好,所以我会在午饭后处理这个“肤浅的工作”)。
  6. ****仅使用浏览器(无操作系统应用)。因为我们使用一个简单的 Chrome 插件来跟踪参与时间,你不会想用 Slack 应用这样的原生工具把事情复杂化。使用基于浏览器的工具也使得锁定和保持专注变得格外容易。
  7. ****导出、收集和测量。每周从我的谷歌日历导出(使用设置中的手动“导出”按钮)上传到这个网站进行转换。浏览器扩展的设置页面也有一个简单的 csv 导出功能。结合这两个数据集,做一点清理并添加一个 v-lookup 来快速分类具有相同KWV=值的常见网站,然后嘣!您有基本的指标来分析您的知识工人的投资回报率。(注意:我意识到对于许多人来说,这可能是说起来容易做起来难,所以我将尝试一个非常基本的手动数据转换器,并在后续文章中发布在这里)。

为什么这很重要

任何类型的管理都包括两个主要部分:量表和杠杆。
量表是管理者用来确定当前状态、方向性和未来可能状态的度量、输入和指标。
杠杆是一个经理可以对量表做出反应的事情。
报告您的知识型员工投资回报为我的管理团队提供了这两个方面。这些指标本身就充当了标尺——经理们可以看到我在低价值会议上花费了越来越多的时间,或者发现电子邮件的突然激增或现成的深度技术工作的匮乏。它们还为杠杆创造了基础:经理们可以联系那些长期滥用会议的人,他们掌握着这些过程正在损害我的工作效率的数据,或者恳求那些热衷于发送状态邮件的人(“我们这个月的工作效率如此接近峰值,你是否认为你可以检查一下你这个月机票上的 JIRA 状态,而不是给开发人员发电子邮件,这样我们就可以多发送两张机票?”).
将这些知识工作者 ROI 指标与传统的成功衡量指标(如软件团队的故事点、营销人员的广告收入归属等)结合起来,我们就有了一个完整的仪表板,从中我们可以准确地了解现代知识工作者的生产力状况。

未来状态(科技产品)

这个想法仍处于萌芽阶段,看看我的价值尺度、测量技术和组织对数据的反应将如何展开,将会很有趣。我已经可以看到手动提取和清理数据的感觉很“恶心”,我不得不阻止自己构建那个预定的提取器。我在想,它会将原始数据上传到 Postgres(可能是 RDS),通过 DBT 模型运行清理和整合转换,然后生成一些简单的 matplotlib 或 Google charts HTML,直接从 s3 桶提供给每日 KWVROI 仪表板。只有时间会证明一切!

卷积递归神经网络的一种方法

原文:https://towardsdatascience.com/an-approach-towards-convolutional-recurrent-neural-networks-a2e6ce722b19?source=collection_archive---------7-----------------------

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

Proposed CRNN

卷积递归神经网络是两个最重要的神经网络的结合。CRNN(卷积递归神经网络)包括 CNN(卷积神经网络),之后是 RNN(递归神经网络)。所提出的网络类似于 CRNN,但是产生更好或最优的结果,特别是对于音频信号处理。

网络的组成

该网络从传统的 2D 卷积神经网络开始,然后进行批量归一化、ELU 激活、最大池化和 50%退出率的退出。三个这样的卷积层以它们相应的激活顺序放置。卷积层之后是置换和整形层,这对于 CRNN 是非常必要的,因为特征向量的形状在 CNN 和 RNN 之间是不同的。卷积层是在三维特征向量上开发的,而递归神经网络是在二维特征向量上开发的。

置换层改变特征向量的轴的方向,随后是整形层,整形层将特征向量转换为二维特征向量。RNN 与二维特征向量兼容。所提出的网络包括两个双向 GRU 层,每层中有“n”个 GRU 单元,其中“n”取决于使用相应网络执行的分类的类别数。使用双向 GRU(门控循环单元)代替单向 RNN 层,因为双向层不仅考虑未来时间戳,还考虑未来时间戳表示。结合来自两个时间戳的二维表示允许以非常优化的方式结合时间维度特征。

最后,双向层的输出被馈送到时间分布密集层,随后是全连接层。

建议网络的实施如下:

def get_model(data_in, data_out, _cnn_nb_filt, _cnn_pool_size, _rnn_nb, _fc_nb):spec_start = Input(shape=(data_in.shape[-3], data_in.shape[-2], data_in.shape[-1]))
 spec_x = spec_start
 for _i, _cnt in enumerate(_cnn_pool_size):
 spec_x = Conv2D(filters = cnn_nb_filt, kernel_size=(2, 2), padding=’same’)(spec_x)
 spec_x = BatchNormalization(axis=1)(spec_x)
 spec_x = Activation(‘relu’)(spec_x)
 spec_x = MaxPooling2D(pool_size=(1, _cnn_pool_size[_i]))(spec_x)
 spec_x = Dropout(dropout_rate)(spec_x)
 spec_x = Permute((2, 1, 3))(spec_x)
 spec_x = Reshape((data_in.shape[-2], -1))(spec_x)for _r in _rnn_nb:
 spec_x = Bidirectional(
 GRU(_r, activation=’tanh’, dropout=dropout_rate, recurrent_dropout=dropout_rate, return_sequences=True),
 merge_mode=’concat’)(spec_x)for _f in _fc_nb:
 spec_x = TimeDistributed(Dense(_f))(spec_x)
 spec_x = Dropout(dropout_rate)(spec_x)spec_x = TimeDistributed(Dense(data_out.shape[-1]))(spec_x)
 out = Activation(‘sigmoid’, name=’strong_out’)(spec_x)_model = Model(inputs=spec_start, outputs=out)
 _model.compile(optimizer=’Adam’, loss=’binary_crossentropy’,metrics = [‘accuracy’])
 _model.summary()
 return _model

可以显示模型摘要,如下所示:

# Load model”
model = get_model(X, Y, cnn_nb_filt, cnn_pool_size, rnn_nb, fc_nb)

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

Model Summary for a 10 class classification for audio analysis.

一个增强的艺术家

原文:https://towardsdatascience.com/an-augmented-artist-e9b5ba3081ab?source=collection_archive---------24-----------------------

最近一段时间,我们看到大量基于人工智能的艺术作品涌入,这些艺术作品来自现实生活中的数据集,如照片和绘画。在这样的作品中,机器从人类的艺术作品中学习并获得灵感,创造出类似的东西。但创造力的真正本质不仅仅在于重复或模拟部分或全部灵感,还在于能够创造惊喜、新的联系和独特的东西(不可重复)。这就是为什么可以说机器无法取代人类的创造力。一件原创的艺术品可能是灵感激发的,但人类添加了独特的价值,使其具有原创性。

上个月,我和一个朋友致力于一个生活在云中的人工智能艺术家的想法,从日常生活中创造诗歌和艺术。我们给她取名为奥瑞亚。她能够从世界中获得灵感来创作艺术。但是她的作品中缺少某种独特性或惊喜。生成艺术可以重复的事实一直是我要填补的空白(我的赌注是在涌现领域)。这让我想到-如果一个人工智能艺术家可以从人类世界中获得灵感,那么人类艺术家可以从人工智能中获得灵感吗?

[## auria Kathi——云中的艺术家。

什么是艺术?是没说出口吗?令人不安的?

towardsdatascience.com](/auriakathi-596dfb8710d6)

让我解释一下,首先告诉你灵感是如何为我工作的。

我练习冥想已经有一段时间了,并且挖掘一个想法的根源——一个想法是如何产生的?虽然我还没有成功到成为一个明师,但是我已经有了一定的感悟。首先,一个想法来自一种感觉(因为没有更好的词)。现在这种感觉是非常原始和可解释的。基于我们的经验,我们将从这个“思想前身”中获得直接的洞察力,或者我们可以进一步解释它以获得不同的含义。想象你有一种长方形白色嗡嗡声的“感觉”。(是的,形状、颜色和声音结合在一起)。如果你刚乘过飞机,你会马上联想到飞机的机翼,或者进一步解释,你会联想到你工作的工厂里的人行道。这些“思想前辈”通常是图像、声音、触觉或任何其他感官感觉。我们如何解释,我们优先考虑哪种感觉,最终会变成一种思想。思想然后变成行动,如此等等。很大程度上,当我们做梦时,我们看到一系列这些思想前辈,我们以自己的方式解释和联想。因为解释是基于我们的经验,我们觉得梦是相关的。事实上,一般来说,解释(或者把你的脑袋包起来)在很大程度上是我们生活和学习的方式。

回到我们最初的想法,什么是增强艺术家?增强艺术家是从人工智能中获得灵感的人。相反,人工智能增强了人类艺术家的能力。

让我们把所有的争论都放在“人工智能会取代人类的创造力吗?”休息一下,想想人工智能如何增强人类的创造力。

我做了一个实验来尝试这种增强的艺术性:

成为一名增强艺术家

奥瑞亚从一首生成的诗中产生艺术,并根据她的“心情”来绘画。她的一些作品如下:

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

Image by Auria Kathi (created by Fabin Rasheed and Sleeba Paul)

在这里阅读更多关于 Auria 的信息

正如你所看到的,她的作品是抽象的,但你觉得你可以从中得到一些联系。例如,如果你问“这看起来像什么?”你可以在脑海中找到你所知道的物体的图像。我决定建立这些关系。我用奥瑞亚的作品作为我艺术的“思想前身”。我开始解读她的作品,并加入我自己的创造力。我选择了一种媒介来表达这一点,它是纸上的丙烯酸。让我向你们展示同样的过程:

我选择了奥瑞亚的一首诗和相应的艺术作品:

艾诗:

神圣的狗屎。

没有。你只是想玩玩

就在旁边,这很了不起

你可以找到你的生活。

我有种感觉

我也是,但我不打算去

做一整年。

AI 艺术:

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

Image by Auria Kathi (created by Fabin Rasheed and Sleeba Paul)

我开始重新想象诗歌,把它作为思想的前身。我用了奥瑞亚诗中的单词和短语。我脑海中形成的关系和意象被用来创作一首不同的诗歌,其概念植根于这些关系和意象:

扩充诗:

神圣的狗屎!

你以为你在边上玩

但是生活就像今天一样

其实只是我内心的一种感觉

未来几天也不会…

我觉得这首诗是关于我们内心是如何描绘出一幅美丽的世界图景的。当我们意识到世界的图景是完全不同的和令人震惊的时候,这种震惊让我们想到我们的视野是多么的浅薄。由于人类的发展,稳定的气候变得短暂,这是我们每天都看到的事情,然而我们用双手覆盖着我们的外围设备,并在自己的内心描绘出一幅关于发展、突破性技术、更好的生活水平和更长的寿命的画面。

这个概念是从奥瑞亚的诗中得到灵感的。Auria 创作的相应艺术启发我创作了以下图像:

增强艺术:

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

Image by Fabin Rasheed

这再一次展示了一个可能是立体派的乌托邦世界,在那里建筑被视为接近自然。我们知道在背景中有一个灰色的现实,但我们仍然试图通过忽略它们而不是纠正它们的唯一方法来隐藏我们的不完美。这种“幸福”的形象建立在我们的脑海中,我们忽略了一个事实,那就是我们曾经认为很接近的东西(这里是绿色植物)开始显示出它难以驾驭的阴暗面。

正如你所看到的,一个来自我个人经历的概念的美丽表达是由人工智能艺术引发的。我们如何从人工智能中获得这种艺术,这种艺术作品如何成为原创。正如你可能已经观察到的,这不仅仅是人工智能帮我想出的一个概念,而是形状、调色板甚至风格。我在人工智能如何被用于艺术灵感和创造新的艺术风格中看到了巨大的力量。这种人工智能艺术可以增强和强化人类的创造过程。基于人工智能的灵感可以衍生出不同的表达方式。

最后,为了吊起你的胃口,下面是我做的一些增强的艺术品(左边是奥瑞亚,右边是我的):

1.神入

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

Left-Image by Auria Kathi (created by Fabin Rasheed and Sleeba Paul) , Right-Image by Fabin Rasheed

2.差别

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

Left-Image by Auria Kathi (created by Fabin Rasheed and Sleeba Paul) , Right-Image by Fabin Rasheed

3.打孔

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

Left-Image by Auria Kathi (created by Fabin Rasheed and Sleeba Paul) , Right-Image by Fabin Rasheed

希望你喜欢这个项目。请在评论中分享你的想法。谢谢你。

S3 解释了 AWS 数据湖!

原文:https://towardsdatascience.com/an-aws-data-lake-with-s3-explained-c67c5f161db3?source=collection_archive---------8-----------------------

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

了解 S3 如何帮助你在 AWS 中设计一个理想的数据湖

如果你与数据世界有过任何联系,你可能听说过一些令人难忘的,通常是古怪的关于数据有多有价值的短语。我在想这样的短语…

  • “数据是新的石油。”
  • “没有大数据,你在高速公路上就像聋子和瞎子一样。”
  • “数据是新的培根!”🥓

说实话,炒作是值得的。(除了我不确定我是否同意关于熏肉的那个……)**从分析的角度来看,数据帮助我们做出明智的决定,决定我们应该在业务中采取的下一步措施。**这可以通过表格报告和数据仪表板的形式体现出来,这是一种被称为机器学习的新事物,受到了很多宣传。“昔日”的人们对如何做出最佳商业决策一无所知,而今天我们有大量的数据资源来帮助我们。使用我为以前的博客帖子创建的图标后备目录(😃),我说下面视觉里的东西都能产生有价值的数据,一点都不夸张。

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

因此,鉴于所有这些东西都在创造数据,下一个合乎逻辑的问题是…我们如何最好地利用它?

这就是数据湖概念的由来。**简而言之,数据湖是一个统一的空间,用于放置所有结构化和非结构化数据,以构建分析解决方案。**因为我是一个喜欢图片的人,这里有一张简单的图片可以说明这一点。

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

当然,您希望管理这个数据湖,以确保它不会成为数据转储场。数据治理非常重要,因此您需要确保使用您放入这个数据湖的东西来管理元数据、数据质量等等。这已经超出了这篇文章的范围,但是如果我不至少提一下的话,我就是在伤害你。

对于这篇文章,我特别想关注在 Amazon Web Services (AWS)中构建一个数据湖意味着什么。随着云解决方案风靡一时,人们希望在 AWS 中构建自己的数据湖是有道理的。更具体地说,人们希望使用 AWS 简单存储服务(S3)作为数据湖的基础是有道理的。

问题来了…无意冒犯 AWS,但我不认为他们在解释 S3 如何不同于“旧世界”概念方面做得很好。我拥有四个 AWS 认证,包括大数据专业,我遇到的学习这些认证的学习材料中没有一个真正很好地解释了我在这篇文章中将要解释的内容。我将在这篇文章中分享的内容可能会从根本上改变你对如何正确设计 AWS 数据湖的想法。

但是在我们进入那个之前,让我们谈论那些“旧世界”的概念…

物理数据隔离的内部世界

在 AWS 和云计算时代到来之前,公司确实有责任确保他们能够使用正确的物理基础架构来支持所有的数据库需求。我说的是购买这些巨大笨重的机器,有人必须用服务器补丁之类的东西来连接网络和维护。这并不容易(如果您目前维护一个内部基础架构,这仍然不容易),当然,从一个硬件只能容纳有限数量的数据的意义上来说,这是有限的。如果你想保存更多的数据,你必须加快新硬件的速度。如果你想把测试数据从生产数据中分离出来,你可能还需要安装新的硬件。

因此,如果您在一个物理环境中的数据必须在另一个物理环境中用于分析目的,您可能必须将该数据复制到新的副本环境中。当然,您可能还与源环境保持联系,以确保副本环境中的内容仍然是最新的。

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

上面的小图表示将数据从一个运营源复制到一个分析副本。当然,您的运营源数据很可能不在一个单一的环境中。您可能有数十个(如果不是数百个)收集数据的操作源。这是大量的数据移动!但是由于字面上的物理限制,复制必须完成。数据不可能同时出现在两个地方,对吧?

好吧,这就是 AWS 和他们的 S3 木桶的不同之处…

S3 水桶如何改变游戏

还记得我说过,我不认为 AWS 在解释 S3 桶如何被分割的整个事情上做得很好吗?如果你参加过任何 AWS 认证——包括云从业者——你可能记得 S3 对所有账户的存储桶使用一个共享的名称空间。例如,如果我在我的 AWS 帐户中创建一个名为“dkhundley”的存储桶,那么您在您的帐户中也不能创建一个名为“dkhundley”的存储桶。不幸的是,在大多数学习材料中,他们对它的解释就到此为止了。

但是你知道为什么会这样吗?如果没有也不要烦恼!也许一个简单的图片将有助于说明这一点…

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

从某种意义上说,认为 AWS 已经是一个巨大的数据湖并不公平!你不能创建一个名为“dkhundley”的桶的原因是,在这个我们称之为 S3 的巨大“数据湖”中已经有一个了。物理基础架构已经从我们身边抽象出来,所以从逻辑上来说,每个公司的数据就像是一个快乐的大家庭。

别让我吓到你!按照这种逻辑,您可能会得出一个自然的结论,即您的 S3 桶中的数据可以很容易地被其他人的公司和他们各自的 AWS 帐户访问。谢天谢地,这不是真的。AWS 一直有意为 AWS 中的所有内容提供适当的安全性,包括 S3 存储桶,因此只有在您拥有正确的凭证的情况下,您才能访问 S3 存储桶。

这是真正的问题,也是 S3 与本地基础设施如此不同的原因(这一点非常重要):您不一定要在生成 S3 存储桶中的数据的同一个帐户中才能访问这些数据。例如,如果您为我设置了正确的凭据,我就可以从我自己的个人 AWS 帐户 中看到贵公司 S3 存储区的内容,无需物理复制 。没错,伙计们。这是思维方式的巨大转变,不同于我们在内部部署环境中的行事方式。我们将时间集中在用物理基础设施隔离数据上,而云计算转移到了使用安全策略隔离数据上。

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

鉴于 AWS 采用的是现收现付模式,您希望以最大化性能和最小化成本的方式进行设计。考虑到存储和数据移动都有相关的成本,将数据从一个 S3 存储桶复制到另一个存储桶不仅成本高昂,而且效率低下。同样,在 S3 的上下文中,AWS 帐户不会隔离资源。

S3 数据湖的设计考虑

我希望到目前为止我们所涉及的内容是有意义的。需要的话再回去复习几遍!再说一次,我是一个喜欢图片的人,所以我希望我简单的插图能让你更容易理解。带着这种新的想法,让我们用一些设计考虑来结束这篇文章,当你在 S3 建立你的数据湖时,你可以考虑一下:

  • 测试与生产数据:当您创建一个对数据进行更改的新 IT 解决方案时,很自然地希望保护您的生产级数据免受该新解决方案的负面影响。在大多数内部基础设施中,这意味着在物理上隔离测试和生产环境。需要考虑如何在 S3 隔离测试和生产数据,这可以通过多种方式实现。最安全和最简单的方法是将数据完全隔离到各自的存储桶中,您可以使用存储桶命名标准或 AWS 标签来管理组织。(或者都是!)但是如果你不想复制所有的东西,有办法在每个桶中隔离某些东西。这将需要你做更多的工作,但是如果成本管理对你来说是一个重要的因素,这可能是值得的。
  • 敏感数据保护:这很像我们刚刚在上面讨论的隔离测试与生产。最简单的方法还是将敏感数据隔离到它自己的桶中,并通过许多安全措施真正锁定它,但同样,也可以将敏感数据和非敏感数据锁定在同一个桶中。我可能不想惹这种麻烦,但是朋友们,你们必须这样做。
  • 数据湖与数据仓库:让我们在这里明确一下……数据湖并不等同于数据仓库。数据仓库通常只包含结构化或半结构化的数据,而数据湖包含所有的东西:结构化的、半结构化的和非结构化的。数据湖通常与数据仓库共存,而数据仓库通常建立在数据湖之上。就 AWS 而言,最常见的实现是使用 S3 作为数据湖,使用红移作为数据仓库。当然,在 AWS 中剥猫皮的方法不止一种,所以不要以为你的仓储需求只局限于红移。
  • 数据管理&治理:我已经在这篇文章中提到过一次,但我认为值得再次提出。如果没有适当的数据管理和治理,数据湖很快就会变成数据转储。当你设计你的数据湖时,AWS 确实提供了像 AWS Glue 这样的服务来帮助你管理像数据目录这样的东西,但是它让你自己去弄清楚这些东西。如果你真的想在这个领域得到额外的帮助,也有许多第三方供应商会在这里提供很多帮助。(Oomph 是一个技术术语。😂)根据您公司的需求,引入第三方供应商来帮助您组织数据湖可能是值得的。(我对此并不太熟悉,但 AWS 确实也提供了一项名为 Lake Formation 的服务,或许也值得一试。)
  • 湖消耗:当你想在数据湖的基础上构建分析解决方案时,事情会变得有点棘手。虽然 AWS 帐户在将数据放入数据湖时并不重要,但对于您的消费解决方案来说却更重要。多个帐户可以从同一个数据湖中提取数据,但是您必须确保它们都有适当的安全凭证来访问这些底层 S3 存储桶。很有可能,您不希望让每个人都能访问您数据湖中的每个 S3 存储桶。同样,这也是数据管理和治理极其重要的地方,因此同样值得投资利用这些第三方治理工具来帮助适当地分发安全凭证。

好了,这篇文章到此为止!直到最近,这对我来说还是一个非常陌生的概念,所以即使你有 AWS 认证,如果你没有完全掌握这一点,也不要自责。如果你喜欢这篇文章,你可能也会喜欢我的其他一些文章,包括上周关于我开始使用 AWS 的五个技巧的文章。感谢阅读!

一种编码分类特征的简单方法

原文:https://towardsdatascience.com/an-easier-way-to-encode-categorical-features-d840ff6b3900?source=collection_archive---------9-----------------------

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

Photo by Ash Edmonds on Unsplash

使用 python 类别编码器库处理机器学习中的高基数变量

我最近一直在做一个机器学习项目,这个项目有几个分类特征。这些要素中的许多都具有很高的基数,或者说,具有大量的唯一值。处理分类变量最简单的方法通常是执行一键编码,其中每个唯一值被转换成一个新列,用 1 或 0 表示该值的存在或不存在。然而,当一个特征的基数很高时,这种方法通常会产生太多的新特征,从而降低模型性能。

我开始编写自己的编码器,尝试用其他方法对一些特征进行编码,从所谓的证据权重开始。在二元分类问题中证据权重使用正负类中特征的唯一值分布,并创建与这些值相关的新特征。自然,这需要一段时间来编码,然后让它在我现有的 scikit-learn 管道中工作。

然后,我偶然发现了这个名为 category_encoders 的库,它不仅有证据的权重,而且有几乎所有可能的方式来编码已经编写好并准备好使用的分类特征。这意味着我不再需要编写这个定制的编码器,我现在可以快速评估一大堆不同的编码器并选择最好的一个。在这篇文章中,我想分享这个库,并举例说明如何在 scikit-learn 管道中使用它。

类别编码器

该库包含一组遵循 scikit-learn 风格的转换器,这意味着它们不仅可以单独使用,还可以在 scikit-learn 管道中使用。转换器提供了多种方法来转换分类数据,包括非常流行的 one-hot 编码。这个库对于处理高基数特性特别有用,在这种情况下,一次性编码方法可能会导致较差的模型性能。

让我们看一个使用中的例子。在下面的例子中,我使用的是从 UCI 机器学习库下载的adults数据集。该数据包括每个人的一组特征和目标变量,该变量表示他们的年收入是低于还是高于 5 万美元。

该库可以通过 pip 安装。

pip install category_encoders

或者康达。

conda install -c conda-forge category_encoders

首先,这里是我正在使用的进口。

import pandas as pd
import numpy as npfrom sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer
from sklearn.metrics import f1_score
import category_encoders as ce

接下来,我将下载数据并将其转换成熊猫数据框。

url_data = '[https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data'](https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data')
column_names = ['age', 'workclass', 'fnlwgt', 'education', 'educational-num','marital-status',
                'occupation', 'relationship', 'race', 'gender','capital-gain', 'capital-loss', 
                'hours-per-week', 'native-country','income']
adults_data = pd.read_csv(url_data, names=column_names)

然后,我为每个特征类型(分类的和数字的)创建一个变量,供以后在管道中使用,并将值分成测试和训练数据集。需要注意的一点是,尽管 scikit-learn 可以处理非数字目标变量,但 category_encoders 库不能。所以这里的一个额外步骤是使用标签编码器来转换 y 标签。

numeric_features = adults_data.select_dtypes(include=['int64', 'float64']).columns
categorical_features = adults_data.select_dtypes(include=['object']).drop(['income'], axis=1).columnsX = adults_data.drop('income', axis=1)
y = adults_data['income']le = preprocessing.LabelEncoder()
label_encoder = le.fit(y)
y = label_encoder.transform(y)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

接下来,我运行下面的代码,它构建了一个管道,并循环遍历 category_encoders 列表,为每个模型打印分数。我使用了一个随机森林模型作为简单的例子。

encoder_list = [ce.backward_difference.BackwardDifferenceEncoder, 
               ce.basen.BaseNEncoder,
               ce.binary.BinaryEncoder,
                ce.cat_boost.CatBoostEncoder,
                ce.hashing.HashingEncoder,
                ce.helmert.HelmertEncoder,
                ce.james_stein.JamesSteinEncoder,
                ce.one_hot.OneHotEncoder,
                ce.leave_one_out.LeaveOneOutEncoder,
                ce.m_estimate.MEstimateEncoder,
                ce.ordinal.OrdinalEncoder,
                ce.polynomial.PolynomialEncoder,
                ce.sum_coding.SumEncoder,
                ce.target_encoder.TargetEncoder,
                ce.woe.WOEEncoder
                ]for encoder in encoder_list:

    numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())])
    categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('woe', encoder())])

    preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)])

    pipe = Pipeline(steps=[('preprocessor', preprocessor),
                      ('classifier', RandomForestClassifier(n_estimators=500))])

    model = pipe.fit(X_train, y_train)

    y_pred = model.predict(X_test)
    print(encoder)
    print(f1_score(y_test, y_pred, average='macro'))

输出如下。从下面可以看出,对于这个模型,顺序编码器给出了最好的分数,而留一编码器给出了最低的分数。

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

处理分类变量只是调整机器学习模型的一个方面,当然还有许多其他步骤。category_encoder 库提供了一种快速评估处理这些特性的不同方法的方法。在未来的项目中,我肯定会经常用到它。

感谢阅读!

测量等变卷积网络的简易指南

原文:https://towardsdatascience.com/an-easy-guide-to-gauge-equivariant-convolutional-networks-9366fb600b70?source=collection_archive---------4-----------------------

几何深度学习是一个非常令人兴奋的新领域,但它的数学正在慢慢漂移到代数拓扑和理论物理的领域。对于 Cohen 等人的论文“规范等变卷积网络和二十面体 CNN”来说尤其如此。艾尔。(https://arxiv.org/abs/1902.04615),这正是我想在这篇文章中探讨的。这篇论文使用了规范理论的语言,规范理论是物理学中任何喜欢同时使用“量子”和“场”这两个词的事物的核心。它承诺给规范理论的基础一个直观的理解,我必须说,它提供了并且可能是我迄今为止看到的最好的介绍。但是它仍然是一个困难的课题。

我在这里想做的是给出一个纯粹直观的理解,没有数学。虽然我没有完全遵循文章的结构,但您仍然可以并排打开文章,因为我会尝试突出所有重要的术语。

在下文中,我假设你知道卷积神经网络(CNN)是如何工作的,但不知道它们与流形有什么关系。所以我们走吧!

多支管

一个总管是一件简单的事情。你看到的每一个二维表面都可以被认为是一个流形。球体的表面,立方体的表面,所有的流形。但是它并不局限于二维,见鬼,它甚至不局限于可以想象的东西。曲线是流形。四维时空是一个流形。它非常笼统,描述了一个空间。但是让我们关注二维表面。最简单的曲面是平面,比如电脑屏幕。当我们用 CNN 做卷积时,我们通常在这些平面图像上做。

比方说,我们想用 CNN 预测天气。对于一个国家来说,这很简单:使用当地的天气数据作为输入,然后喀拉斯喀拉斯嘣,你就有了一个训练好的模型。如果我们想对整个地球的天气进行分类呢?你如何把它放到一张图片上?或许:

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

(Image by Pixabay)

但是有一个问题。左边和右边实际上是同一个点。此外,整个上边缘对应于单个点,下边缘也是如此。整件事都被扭曲了。试过压扁乒乓球吗?是啊,情况不妙。当我们试图应用卷积时,我们会得到奇怪的结果。非物质的事情可能发生在边缘。它可能会在图像的最右侧预测到强烈的东风,但在图像的左侧却没有,即使它们代表的是同一个地点。CNN 就是不明白地球是绕着转的。

或者,我们可以为地球创建多个重叠的地图,并让 CNN 对这些地图进行操作。这本地图集也被称为地图集将 CNN 切换到所有这些单独的地图上,确保在下一张地图上它们重叠的同一点上继续,这样就能让它明白地球是圆的。这是几何深度学习背后的基本思想:直接将深度学习应用于曲面或流形,以保留它们的几何结构。然而,有一个问题。一个大的。

我们去新加坡吧!

现在,让我们暂时忘记天气,拿出指南针。假设你在新加坡。向北,经过泰国,穿过中国,蒙古,到达北极。并且不改变方向,一直往前走。你将穿过加拿大和美国,直到你到达中美洲的某个地方。停在那里,开始横向游过太平洋,不要改变方向!中风几百万次后,你应该会回到新加坡。但是等等。你从来没有改变方向,为什么你要向南看?

让我们重复一遍,但是这一次我们到达北极后向左侧身。我们将在尼格拉附近停下来,开始往回走,同样不改变方向。一旦我们回到新加坡,这一次我们要向西看?奇怪…不相信我?自己试试吧,拿个指南针开始游吧…

这个问题是由于球体的曲率造成的,我们将“四处移动而不改变方向”称为平行运输。你看到平行传输非常依赖于球体上的路径。然而,在二维平面上,这无关紧要。你可以走每一条路而不改变方向,并且一旦你回来就有相同的方向。因此,我们说平面是可平行化的(一旦你返回,你的方向向量保持平行),而球体不是。

你可以看到这是我们 CNN 在一个球体上的问题。如果我们在所有地图上以不同的方式移动 CNN,方向似乎会改变。我们需要找到一种方法来确保这种怪异不会影响我们的结果!或者说,至少要知道怎么处理。

毛茸茸的球

在找到解决方案之前,我们必须引入更多的数学概念。指南针可以被看作是平面上指向某个方向的向量,主要是指向北方。指针旋转的这个平面与地球表面相切,我们称之为地球在该点的切向空间。即使地球是圆的,切空间也是完全平坦的。它就像一个本地坐标系,以北方和东方为其坐标向量。而且,我们可以在地球上的任何一个地方拿出指南针,每个地方都有自己的切线空间。但是我们也可以定义 40 和 130 为坐标向量。在这种情况下,北和其他方向没有什么特别,选择是任意的。

现在,让我们在切空间中选择任意方向,然后向前一步。我们确保选择最短的路径(测地线)并在一个新的点结束。你可能会称之为“前进”,但为了混淆每个人,我们将把这个过程称为指数图(它来自于所有这些微小的步骤神奇地类似于指数函数的级数展开……但现在这并不重要)。

让我们再看看我们的指南针。指南针给地球上“每一个”点分配一个矢量的事实被称为**(正切)矢量场**。风也可以被视为一个矢量场,因为它为每个点指定一个方向。我特意把“每”放在引号里,因为当你直接站在磁北极或磁南极时,罗盘指针会出问题。事实上,对于球面上每一个非零的连续向量场都是错误的。我们必须在球体上的磁场中有磁极。这种现象被称为毛球定理,因为它类似于无法在不创建旋转的情况下梳理毛球:

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

(Image from Wikipedia)

向量场不需要和切空间有相同的维数。相反,它们可以在每个点上有自己的任意维数的矢量空间**。这很重要,因为我们还希望能够给地球上的每个点分配 3-D 或 99-D 向量,而不仅仅是 2-D 方向。在场的每个点处的这个向量空间也被称为纤维。**

(一种特殊类型的字段是标量字段。它只有一个维度,温度可以被视为这样的标量场)

测量

各地测量温度的方法不同。在德国,我们用摄氏度。在美国他们使用华氏温度。这种选择被称为标尺。是的,这个词来源于测量仪器。现在,当我阅读美国的天气预报时,我必须计算华氏温度在摄氏温度中的含义。我们有不同的参照系。这个计算叫做规范变换。请注意,实际的温度并没有改变,只是我们用来理解它的值改变了,转换是一个简单的线性函数。

如果我们看向量场,比如风向,事情会变得更复杂。让我们假设有一个国家,Gaugeland,它并不在乎南北,它有自己的方向系统,基于星座或者刺猬害怕时的方向。当这些人描述风时,我们必须执行一个规范转换来理解他们所说的方向。现在,规范变换变成了乘以一个可逆矩阵(显然它必须双向进行)。这组矩阵称为****一般线性群GL

对于一个理论上平坦的地球来说,风的规格的选择可以是全球性的。但是在球体上,我们会遇到问题。我们不能定义一个单一的全局量规,而是必须依赖多个量规和地图。从我们在球面上的平行化问题和毛球定理,我们应该有一些直觉,为什么一定是这样。

这自然意味着,我们需要多个风地图。然而,我们不再允许所有的 Gaugeland 的诡计,并要求至少他们使用的矢量(风速)的大小必须与我们的相同。我们只允许他们使用不同的方向。因此,每次规范变换都简化为一次旋转。这些变换也形成一个组,即特殊正交组SO ,它是 GL 的一个子组。通过选择不同的结构群**,我们有效地减少了我们规范理论所允许的变换。**

回到深度学习

我们回到最初的问题,想对一个风向矢量场进行卷积。这里,风表示输入要素。假设我们想要找到龙卷风的方向作为输出。我们可以在“小块”上执行卷积,从风向中提取这些输出特征。(注:我不知道这是否有气象意义…输入向量到输出向量…这就是我们需要知道的一切

但是“小补丁”是一个非常模糊的描述。在 2-D 平面上,很简单,我们可以把所有的东西都放在一个小球的中心。在某种程度上,这也适用于完美的球体。但是在任意流形上呢?事情变得棘手。看看这个时髦的流形:

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

(Image from Wikipedia)

它被称为克莱因瓶,我们可以看到,点之间的原始距离是…有问题的。我们可能永远不会需要克莱因瓶来进行深度学习,但我们希望尽可能保持事物的普遍性。

我们需要的是一种方法,只包括在流形上附近的卷积中的点。我们确实有办法做到这一点。回想一下,指数地图在我们的流形上做微小的移动来寻找附近的点。所以让我们利用这一点。从中心开始,我们在切线空间允许的每个方向上前进一步,并将该点包含在我们的卷积中。

我们现在只需要一些函数来做卷积。所以,我们定义了一个内核**,它给每个点分配一个矩阵-…等等,不,我们用指数图去切空间的每个方向。这有点奇怪,但当你观察经典二维卷积时,它实际上也是如此。只是没那么明显,因为它在飞机上。**

这个矩阵乘以一个输入向量并产生一个输出向量。在这里,作者确定了第一个问题。这个矩阵只为中心定义。但是我们将它应用于附近点的场矢量,它们有自己奇怪的属性。在平面上,这不是问题,但是在我们的球体上,它们略有不同,我们不能只应用内核。

让我们解决这个问题,将这些点上的向量平行传输回我们的小面片的中心。在这里,我们可以应用我们的矩阵,而不必担心怪异的曲率问题。

规范等方差

到目前为止,我们定义的卷积似乎是合理的。我们将我们的内核应用到风数据中,得到了一个很好的结果:龙卷风向东移动。但不知何故,我们还是得到了与高格兰德不同的结果?他们预测龙卷风正在移动刺猬-左**

啊,是的:我们需要测量将他们的结果转换到我们的框架中,瞧:他们预测龙卷风将向西移动…。还是错了…

发生了什么事?我们忘了使我们的卷积规范等变*。简而言之,内核的结果必须依赖于所选择的规范和变换。如果没有,我们只会得到奇怪的结果,无法相互关联或比较。***

但是输出向量可能与输入向量有不同的维度或不同的解释,我们如何将输入向量的规范变换与输出向量的等变“规范变换”联系起来呢?因为结构组只作用于输入,所以想法是找到作用于输出向量的同一个组的一个表示*。例如,以旋转组作为其结构组的 2-D 输入向量的变换可以由绕单个轴旋转的 3-D 输出向量来表示。当二维向量旋转时,三维输出也绕固定轴旋转。一般来说,可以有许多表示,就像在三维空间中可以有许多不同的旋转轴。关键是,它做一些表示相同动作的事情。***

有了表象的概念,我们可以使卷积规范等变。我们只需要确保输入向量的规范变换导致输出向量的等变变换(即,相同的变换,但是在适当的表示中)。

现在,使用规范等方差,当我们在不同的图上执行卷积时,我们在数值上得到不同的结果,但是它们的结果是一致的。这是我们定义卷积在整个球面上有意义的最好方法。

二十面体?

我们基本上涵盖了论文的第 2 部分。作者现在转向二十面体,它在拓扑学上与球体非常相似,但更好。它们更好,因为我们可以比球体更容易地将它们离散化。

就像我们用多张地图覆盖地球一样,让我们用 5 张重叠的地图覆盖二十面体(重叠部分由微小的全白三角形表示):

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

(Image from the paper)

漂亮,地图甚至是同样的大小。难怪他们选择这个流形。我们也可以把它看作一个图表。请注意,每个节点(即每个交叉点)都是流形上具有输入特征向量的点(在上图中不可见)。每个小三角形有三个角,每个角是这些节点中的一个。我们对它们感兴趣。

所以,我们来做卷积吧!

首先,我们需要看看我们的指数图是什么样的。在我们的离散流形上,这很简单。我们只是从一个节点开始,向任何方向走一步。在上面的图像中,连接节点的线表示方向。所以,大多数节点都有 6 个邻居,除了那些在二十面体角落的节点,它们有 5 个邻居。

接下来,我们需要一个内核函数。但是我们懒,不想多此一举。因此,我们将使用来自标准 2D 卷积的 3 x 3 滤波器。这些 3×3 滤波器有一个中心点和 8 个邻居。那比我们需要的多。因此,让我们忽略 3 x 3 网格中的右上和左下邻居,将它们设置为 0,并假设它只有 6 个邻居。

剩下的就是让这个东西规范等变。好,让我们看看我们的二十面体的结构群。我们已经注意到,我们只能去 6 个不同的方向。如果我们要描述这个结构上的风,我们只有 6 个不同的参照系,每个都旋转 60 度。这也可以被公式化为具有 6 阶的循环群,或 C6 作为其结构群。****

最后,我提到我们的地图是重叠的。因此,如果我们想要在有重叠的区域上移动卷积滤波器,我们基本上是使用来自不同映射的值。我们如何利用这些价值呢?在使用它们之前,我们把它们转换成正确的框架。瞧,我们在二十面体上做卷积。

结论

在我看来,这篇论文为几何深度学习领域提供了一个基础性的结果。在进行卷积时,理解规范等变的整体思想和重要性是这里的主要收获。

我希望我的非数学解释有助于理解论文中提出的观点。如果你觉得这类东西很有趣,想要核心的数学,一定要看看中原的《几何、拓扑和物理》。

使用 Matplotlib 进行 3D 绘图的简单介绍

原文:https://towardsdatascience.com/an-easy-introduction-to-3d-plotting-with-matplotlib-801561999725?source=collection_archive---------1-----------------------

想获得灵感?快来加入我的 超级行情快讯 。😎

每个数据科学家都应该知道如何创建有效的数据可视化。没有观想,你将会被困在试图处理数字和在你的头脑中想象成千上万的数据点!

除此之外,它还是与非技术业务利益相关者进行有效沟通的重要工具,这些利益相关者通过图片而非文字更容易理解您的结果。

大多数数据可视化教程都展示了相同的基本内容:散点图、线图、箱线图、条形图和热图。这些对于快速获得对数据集的高层次洞察都是非常棒的。

但是如果我们更进一步。2D 图只能显示一对轴 x - y 之间的关系;另一方面,3D 绘图允许我们探索 3 对轴的关系: x - yx - zy - z

在本文中,我将向您简单介绍如何使用 Matplotlib 实现 3D 数据可视化。最终,您将能够将 3D 绘图添加到您的数据科学工具包中!

在我们开始之前,请查看 人工智能智能简讯以阅读人工智能、机器学习和数据科学方面的最新和最棒的信息!

三维散点图和折线图

Matplotlib 中的 3D 绘图从启用实用工具包开始。我们可以通过导入mplot3d库来启用这个工具包,这个库通过 pip 与您的标准 Matplotlib 安装一起提供。只是要确保你的 Matplotlib 版本是 1.0 以上。

导入该子模块后,可通过将关键字projection="3d"传递给 Matplotlib 中的任何常规轴创建函数来创建 3D 图:

**from* mpl_toolkits *import* mplot3d

*import* numpy *as* np
*import* matplotlib.pyplot *as* plt

fig = plt.figure()
ax = plt.axes(projection="3d")

plt.show()*

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

现在我们的轴已经创建好了,我们可以开始 3D 绘图了。3D 绘图功能非常直观:我们不仅仅调用scatter而是调用scatter3D,不仅仅传递 xy 数据,而是传递 xyz 。所有其他功能设置,如颜色和线型,与 2D 绘图功能保持一致。

这是一个绘制 3D 线和 3D 点的示例。

*fig = plt.figure()
ax = plt.axes(projection="3d")

z_line = np.linspace(0, 15, 1000)
x_line = np.cos(z_line)
y_line = np.sin(z_line)
ax.plot3D(x_line, y_line, z_line, 'gray')

z_points = 15 * np.random.random(100)
x_points = np.cos(z_points) + 0.1 * np.random.randn(100)
y_points = np.sin(z_points) + 0.1 * np.random.randn(100)
ax.scatter3D(x_points, y_points, z_points, c=z_points, cmap='hsv');

plt.show()*

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

下面是 3D 绘图最棒的部分:交互性。一旦你在 3D 中绘图,绘图的交互性对于探索你的可视化数据变得非常有用。查看我通过简单的点击和拖动创建的一些不同的视图!

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

表面图

表面图可以很好地显示整个 3D 景观中 3 个变量之间的关系。它们给出了一个完整的结构和视图,显示了每个变量的值如何在其他两个变量的轴上变化。

在 Matplotlib 中构建曲面图需要三个步骤。

(1)首先,我们需要生成构成表面图的实际点。现在,生成 3D 表面的所有点是不可能的,因为它们的数量是无限的!因此,我们将生成足以估计表面的数据,然后外推其余的点。我们将定义 xy 点,然后使用函数计算 z 点。**

*fig = plt.figure()
ax = plt.axes(projection="3d")*def* z_function(*x*, *y*):
    *return* np.sin(np.sqrt(*x* ** 2 + *y* ** 2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = z_function(X, Y)*

(2)第二步是绘制一个线框——这是我们对表面的估计。

*fig = plt.figure()
ax = plt.axes(projection="3d")ax.plot_wireframe(X, Y, Z, color='green')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')

plt.show()*

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

(3)最后,我们将把我们的表面投影到我们的线框估计上,并外推所有点。

*ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1,
                cmap='winter', edgecolor='none')
ax.set_title('surface');*

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

美女!这是我们丰富多彩的 3D 表面!

三维条形图

柱状图在数据可视化项目中经常使用,因为它们能够以简单直观的方式传达信息,通常是某种类型的比较。三维条形图的美妙之处在于,它们保持了 2D 条形图的简单性,同时扩展了其表示比较信息的能力。

条形图中的每一条都需要 2 样东西:位置和大小。对于 3D 条形图,我们将为所有三个变量 x,y,z 提供该信息。

*我们将选择 z 轴来编码每个条形的高度;因此,每个条形将从 z = 0 开始,其大小与我们试图显示的值成比例。 xy 位置将代表横过 *z = 0 的 2D 平面的杆的坐标。我们将把每个条形的 xy 尺寸设置为 1,这样所有的条形都具有相同的形状。

查看下面的代码和 3D 图作为示例!

*fig = plt.figure()
ax = plt.axes(projection="3d")

num_bars = 15
x_pos = random.sample(xrange(20), num_bars)
y_pos = random.sample(xrange(20), num_bars)
z_pos = [0] * num_bars
x_size = np.ones(num_bars)
y_size = np.ones(num_bars)
z_size = random.sample(xrange(20), num_bars)

ax.bar3d(x_pos, y_pos, z_pos, x_size, y_size, z_size, color='aqua')
plt.show()*

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

深度学习中生成对抗网络的简单介绍

原文:https://towardsdatascience.com/an-easy-introduction-to-generative-adversarial-networks-6f8498dc4bcd?source=collection_archive---------10-----------------------

了解深度学习最强大的网络!

想获得灵感?快来加入我的 超级行情快讯 。😎

生成对抗网络 (GANs)是一种神经网络架构,能够自行生成新数据。对这些 gan 的研究是深度学习中的热门话题,因为它们的力量。短短几年间,他们已经从生成模糊的数字发展到创造照片般逼真的人脸图像。

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

GANs 如何工作

生成对抗网络(gan)被分类在生成模型组中。这意味着它们能够生成全新的“有效”数据。所谓有效数据,我们的意思是网络的输出应该是我们认为目标可以接受的。

为了说明,考虑一个例子,其中我们希望生成一些新图像来训练一个图像分类网络。当然,对于这样的应用程序,我们希望我们的训练数据尽可能真实,也许在风格上与其他图像分类训练数据集非常相似。

下图显示了 GAN 生成的一组图像的示例。它们看起来很真实!如果我们没有被告知它们是计算机生成的,我们可能真的会相信这些是人类收集的!

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

An example output of Progressive GANs. Source

为此,gan 由两个独立的反向网络组成:发生器和鉴别器。当仅给定噪声图像阵列作为输入时,生成器被训练来创建看起来逼真的图像。鉴别器被训练来分类图像是否是真实的。

GANs 的真正力量来自他们所遵循的对抗训练风格。基于鉴别器的损耗学习发电机网络的权重。因此,生成器被推动以这样一种方式训练,即对于它生成的图像,很难辨别它们是否真实。在这些图像看起来越来越真实的同时,鉴别器也越来越好地分辨出哪些图像是真实的,不管肉眼看起来有多相似。

从技术角度来说,鉴别器的损失将是对哪些图像是假的,哪些是真的进行分类的误差;我们正在测量它辨别真假图像的能力。发生器损耗将基于其利用假图像“愚弄”鉴别器的能力——即鉴别器对假图像的分类误差仅在假图像上出现,因为发生器希望该误差尽可能高。

因此,GANs 建立了一种反馈回路,发电机帮助训练鉴别器,鉴别器帮助训练发电机。他们一起变得更好。下图有助于说明这一点。

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

An illustration of the structure of a Generative Adversarial Network

训练 GAN 在 Pytorch 中生成数字

现在我们将通过一个例子来说明如何在 Pytorch 中构建和训练我们自己的 GAN! MNIST 数据集包含 60,000 张黑白数字的训练图像,范围从 1 到 9,其中每张图像的大小为 28x28。它非常适合我们的用例,因为它仍然非常常用于机器学习概念验证,并且是一个成熟的集合。

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

Part of the MNIST dataset. Source

我们将从我们的进口开始。我们只需要 Pytorch 的东西!

接下来,我们将为训练数据准备我们的数据加载器。记住,我们要为 MNIST 生成随机数,即从 0 到 9。因此,我们需要为这 10 位数字设置标签。

现在我们可以建立我们的网络。我们从下面的鉴频器网络开始。回想一下,鉴别器网络对图像是否真实进行分类,这是一个图像分类网络。因此,我们的输入是一个标准 MNIST 大小的图像:28x28 像素。我们将该图像展平成长度为 784 的单个向量。输出是一个单一值,表示图像是否是一个真正的 MNIST 数字。

现在来看看下面的发电机。发生器网络负责创建实际的图像——它可以从纯噪声输入中做到这一点!对于本例,我们将让发生器从一个长度为 100 的向量开始,这也是一个纯粹的随机噪声。从这个向量,我们的生成器将输出一个长度为 784 的向量,稍后我们可以将它整形为标准的 MNIST 28x28 像素。

要设置我们的培训,我们需要一些东西:

  • 损失函数
  • 每个网络的优化器
  • 时代数
  • 批次数量

Pytorch 还要求,如果我们希望我们的网络在 GPU 上运行,我们必须显式地将模型移到它上面。所有代码如下所示。

现在是我们的训练循环。Pytorch 中的训练循环通常由遍历历元的外循环和遍历批数据的内循环组成。训练 gan 的关键部分是我们需要在一个循环中更新生成器和鉴别器。查看下面的代码来训练 GAN 和 Pytorch。这些步骤在代码下面有更详细的描述。

(1)我们开始为鉴别器准备我们的真实图像数据。输入是一批真实的 MNIST 图像。输出是全 1 的向量,因为 1 表示图像是真实的。

(2)接下来,我们将为生成器准备输入向量,这样我们就可以生成假图像。回想一下,我们的生成器网络采用长度为 100 的输入向量,所以这就是我们在这里创建的。images.size(0)表示批量大小

(3)根据我们在步骤(2)中创建的随机噪声数据向量,我们可以绕过向量到生成器来生成我们的伪图像数据。这将与我们在步骤 1 中获得的真实数据结合使用,以训练鉴别器。还要注意,这一次我们的标签向量全是零,因为 0 代表假图像的类别标签。

(4)给定伪图像和真实图像以及它们的标签,我们可以训练我们的鉴别器进行分类。总损失将是伪图像的损失+真实图像的损失

(5)现在我们的鉴别器已经更新,我们可以使用它来进行预测。这些预测的损失将通过发生器反向传播,使得发生器的权重根据它欺骗鉴别器的程度而被特别更新。
(5a)生成一些伪图像在
(5b)使用鉴别器对该批伪图像进行预测并保存输出。

(6)使用来自鉴别器的预测,我们训练我们的生成器。请注意,我们使用全 1 的 real_labels 作为目标,因为我们的生成器的目标是创建看起来真实并且预测为 1 的图像!因此,发生器丢失 0 将对应于鉴别器预测全 1。

瞧啊。这就是我们训练 GAN 生成 MNIST 图像的全部代码!你需要做的就是安装 Pytorch 来运行它。查看下面的 gif,查看 40 多个时期生成的图像的输出!

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

喜欢学习?

推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

机器学习推荐系统简介

原文:https://towardsdatascience.com/an-easy-introduction-to-machine-learning-recommender-systems-efc8f7ece829?source=collection_archive---------12-----------------------

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

我为学习者写了一份名为《强大的知识》的时事通讯。每一期都包含链接和最佳内容的关键课程,包括引文、书籍、文章、播客和视频。每一个人都是为了学习如何过上更明智、更快乐、更充实的生活而被挑选出来的。 在这里报名

YouTube 怎么知道你会看什么视频?谷歌似乎总是知道你会读到什么新闻,这是怎么回事?他们使用一种叫做 推荐系统机器学习技术。

实际上,推荐系统包括一类能够向用户建议“相关”项目的技术和算法。理想情况下,建议的项目尽可能与用户相关,这样用户就可以参与这些项目:YouTube 视频、新闻文章、在线产品等等。

根据项目的相关性对项目进行排序,并向用户显示最相关的项目。相关度是推荐系统必须确定的,并且主要基于历史数据。如果你最近看了 YouTube 上关于大象的视频,那么 YouTube 将开始向你展示许多标题和主题相似的大象视频!

推荐系统通常分为两大类:协同过滤和基于内容的系统。

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

Figure 1: A tree of the different types of Recommender Systems

协同过滤系统

协同过滤推荐系统的方法是仅基于用户和目标项目之间的过去交互的方法。因此,对协同过滤系统的输入将是用户与目标项目交互的所有历史数据。这些数据通常存储在一个矩阵中,其中行是用户,列是项目。

这种系统背后的核心思想是,用户的历史数据应该足以做出预测。也就是说,我们不需要比历史数据更多的东西,不需要来自用户的额外推送,不需要当前的趋势信息等等。

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

Figure 2: Illustration of how collaborative filtering works for predicting a user’s rating of 4 things: an image, a book, a video, and a video game. Based on the users’ historical data, the likes and dislikes of each item, the system tries to predict how the user would rate a new item that they haven’t rated yet. The predictions themselves are based on past ratings of other users, whose ratings and therefore supposed preferences, are similar to the active user. In this case, the system made the prediction / recommendation that the active user won’t like the video. Source by Moshanin

除此之外,协同过滤方法被进一步分为两个子组:基于记忆和基于模型的方法。

基于记忆的方法是最简单的,因为它们不使用任何模型。他们假设可以根据过去数据的纯“记忆”进行预测,并且通常只采用简单的距离测量方法,如最近邻法。

另一方面,基于模型的方法总是假设某种潜在的模型,并且基本上试图确保无论什么预测都将很好地装备模型。

例如,假设我们有一个用户偏好午餐项目的矩阵,其中所有用户都是喜欢芝士汉堡的美国人(它们非常棒)。基于记忆的方法将只查看用户在过去的一个月里吃了什么,而不考虑他们是喜欢奶酪汉堡的美国人这一小事实。另一方面,基于模型的方法将确保预测总是更倾向于奶酪汉堡,因为潜在的模型假设是数据集中的大多数人应该喜欢奶酪汉堡!

代码

我们可以使用 Graph Lab 轻松创建一个协同过滤推荐系统!我们将采取以下步骤:

  1. 用熊猫加载数据
  2. 将熊猫数据帧转换为图形实验室帧
  3. 训练模型
  4. 提出建议

基于内容的系统

与协同过滤相比,基于内容的方法将使用关于用户和/或项目的附加信息来进行预测。

例如,在我们上面看到的 gif 中,基于内容的系统在进行预测时可能会考虑年龄、性别、职业和其他个人用户因素。如果我们知道这个视频是关于滑板的,但是用户已经 87 岁了,那么预测这个人不喜欢这个视频就容易多了!

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

这就是为什么当你注册许多在线网站和服务时,他们会要求你(选择性地)提供你的出生日期、性别和种族!这只是为他们的系统提供了更多的数据来做出更好的预测。

因此,基于内容的方法更类似于经典的机器学习,也就是说,我们将基于用户和/或项目数据构建特征,并使用这些特征来帮助我们进行预测。我们的系统输入是用户的特征和物品的特征。我们的系统输出是对用户是否喜欢或不喜欢该商品的预测。

代码

我们可以使用 Graph Lab 轻松创建一个协同过滤推荐系统!我们将采取以下步骤:

  1. 用熊猫加载数据
  2. 将熊猫数据帧转换为图形实验室帧
  3. 训练模型
  4. 提出建议

喜欢学习?

在 twitter 上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上与我联系!

神经网络 Pytorch 的简单介绍

原文:https://towardsdatascience.com/an-easy-introduction-to-pytorch-for-neural-networks-3ea08516bff2?source=collection_archive---------8-----------------------

感受 Pytorch 之火!

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

想获得灵感?快来加入我的 超级行情快讯 。😎

深度学习重新点燃了公众对人工智能的兴趣。原因很简单:深度学习就是管用。它让我们有能力建立以前无法建立的技术。它创造了新的商业机会,从整体上改善了技术世界。

为了进行深度学习,你需要知道如何编码,尤其是用 Python。从那里,有一个不断增长的深度学习库可供选择:TensorFlow,Keras,MXNet,MatConvNet,以及最近的 Pytorch!

Pytorch 发行后不久就迅速流行起来。人们称它为 TensorFlow 杀手,因为它更加用户友好和易于使用。事实上,您将看到使用 Pytorch 启动和运行深度学习是多么容易。

Pytorch 入门

Pytorch 开发的核心目标是尽可能地与 Python 的 Numpy 相似。这样做可以让常规 Python 代码、Numpy 和 Pytorch 之间的交互变得简单流畅,从而实现更快更简单的编码。

首先,我们可以通过 pip 安装 Pytorch:

pip3 install torch torchvision

如果你对具体的特性感兴趣,Pytorch 文档非常棒。

张量

任何深度学习库最基本的构建块都是张量。张量是类似矩阵的数据结构,在功能和属性上非常类似于 Numpy 数组。事实上,在大多数情况下,您可以将它们想象成 Numpy 数组。两者最重要的区别在于,现代深度学习库中张量的实现可以在 CPU 或 GPU 上运行(非常快)。

在 PyTorch 中,可以使用简单的张量对象来声明张量:

import torch 
x = torch.Tensor(3, 3)

上面的代码创建了一个大小为(3,3)的张量,即 3 行 3 列,用浮点零填充:

0\.  0\.  0.
0\.  0\.  0.
0\.  0\.  0.
[torch.FloatTensor of size 3x3]

我们还可以创建张量填充的随机浮点值:

x = torch.rand(3, 3)
print(x)"""
Prints out:tensor([[0.5264, 0.1839, 0.9907],
        [0.0343, 0.9839, 0.9294],
        [0.6938, 0.6755, 0.2258]])
"""

使用 Pytorch,张量相乘、相加和其他基本数学运算非常简单:

x = torch.ones(3,3)
y = torch.ones(3,3) * 4
z = x + y
print(z)"""
Prints out:tensor([[5., 5., 5.],
        [5., 5., 5.],
        [5., 5., 5.]])
"""

Pytorch 张量甚至提供了类似 Numpy 的切片功能!

x = torch.ones(3,3) * 5
y = x[:, :2]
print(y)"""
Prints out:tensor([[5., 5.],
        [5., 5.],
        [5., 5.]])
"""

所以 Pytorch 张量可以像 Numpy 数组一样被使用和处理。现在,我们将看看如何使用这些简单的 Pytorch 张量作为构建模块来构建深度网络!

用 Pytorch 构建神经网络

在 Pytorch 中,神经网络被定义为 Python 类。定义网络的类从 torch 库中扩展了 torch.nn.Module 。让我们为卷积神经网络(CNN)创建一个类,我们将应用于 MNIST 数据集。

查看下面定义我们网络的代码!

Pytorch 网络类中最重要的两个函数是 init()forward() 函数。 init() 用于定义您的模型将使用的任何网络层。在 forward() 函数中,您实际上是通过将所有层堆叠在一起来建立模型。

对于我们的模型,我们在 init 函数中定义了 2 个卷积层,其中一个我们将重复使用几次(conv2)。我们有一个最大池层和一个全局平均池层,将在最后应用。最后,我们有我们的全连接(FC)层和一个 softmax 来获得最终的输出概率。

在 forward 函数中,我们确切地定义了我们的层如何堆叠在一起以形成完整的模型。这是一个标准网络,具有堆叠的 conv 层、池层和 FC 层。Pytorch 的美妙之处在于,我们可以在 forward() 函数中的任何地方,通过简单的 print 语句打印出中间层中任何张量的形状和结果!

培训、测试和保存

加载数据

是时候为训练准备好我们的数据了!我们将开始,但准备好必要的导入,初始化参数,并确保 Pytorch 设置为使用 GPU。下面使用torch.device()的一行检查 Pytorch 是否安装了 CUDA 支持,如果是,则使用 GPU!

我们可以直接从 Pytroch 检索 MNIST 数据集。我们将下载数据,并将训练集和测试集放入单独的张量中。一旦数据被加载,我们将把它传递给 torch DataLoader ,它只是准备好以特定的批量和可选的混洗传递给模型。

培养

训练时间到了!

optimzer(我们将使用 Adam)和 loss 函数(我们将使用交叉熵)的定义与其他深度学习库非常相似,如 TensorFlow、Keras 和 MXNet。

在 Pytorch 中,所有的网络模型和数据集都必须明确地从 CPU 转移到 GPU。我们通过将.to()函数应用于下面的模型来实现这一点。稍后,我们将对图像数据进行同样的操作。

最后,我们可以写出我们的训练循环。查看下面的代码,看看它是如何工作的!

  1. 所有 Pytorch 训练循环将在训练数据加载器中经历每个时期和每个批次。
  2. 在每次循环迭代中,图像数据和标签都被传输到 GPU。
  3. 每个训练循环还明确应用向前传递、向后传递和优化步骤。
  4. 将该模型应用于该批中的图像,然后计算该批的损失。
  5. 计算梯度并通过网络反向传播

测试和保存

在 Pytorch 中测试网络的性能会建立一个与训练阶段类似的循环。主要的区别是我们不需要做梯度的反向传播。我们仍将进行前向传递,只在网络的输出端获取具有最大概率的标签。

在这种情况下,经过 10 个时期后,我们的网络在测试集上获得了 99.06%的准确率!

要将模型保存到磁盘以备后用,只需使用torch.save()功能,瞧!

喜欢学习?

twitter 上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上与我联系!

面向数据科学家的 SQL 简单介绍

原文:https://towardsdatascience.com/an-easy-introduction-to-sql-for-data-scientists-83363ae004b9?source=collection_archive---------6-----------------------

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

想获得灵感?快来加入我的 超级行情快讯 。😎

SQL(结构化查询语言)是一种为数据存储和管理而设计的标准化编程语言。它允许人们快速、轻松地创建、解析和操作数据。

随着近年来人工智能的大肆宣传,服务于各种行业的技术公司被迫变得更加数据驱动。当一家为数以千计的客户提供服务的公司由数据驱动时,他们将需要一种方法来存储和频繁访问大约数百万甚至数十亿个数据点的数据。

这就是 SQL 的用武之地。

SQL 很受欢迎,因为它既快又容易理解。它被设计成以类似于英语的方式阅读和书写。当使用 SQL 查询来检索数据时,数据不会被复制到任何地方,而是直接在存储数据的地方被访问,这使得该过程比其他方法快得多。

本教程将教您 SQL 的基础知识,包括:

  • 创建数据库表
  • 用真实数据填充数据库表
  • 检索数据以用于数据科学或机器学习任务

让我们直接开始吧!

安装 MySQL

我们要做的第一件事就是安装我们的 SQL server!这将为我们提供一个工作台,开始使用数据库和 SQL 查询。

要安装 MySQL 服务器,您可以从终端运行以下命令:

sudo apt-get install mysql-server

现在我们将启动我们的 MySQL 服务器。这类似于我们在终端中通过键入“python”来启动 Python。这里唯一的区别是给我们的服务器 root 特权很方便,这样我们就可以灵活地访问任何东西。

sudo mysql -u root -p

太好了!现在我们的 mysql 服务器正在运行,我们可以开始发出 MySQL 命令了。

在我们继续前进之前,需要记住几件事:

  • 所有 MySQL 命令都以分号结尾。如果你输入的命令不是以分号结尾,那么它就不起作用!
  • MySQL 命令通常以大写字母书写,而任何用户定义的文本或数字都以小写字母书写,以便于区分。这并不是严格要求的(如果不遵循这一点,您不会得到任何错误),但是为了可读性,通常推荐这样做。

创建 SQL 数据库和表

现在我们准备创建我们的第一个 SQL 数据库。

数据库 是有组织的数据集合。实际上,您可以将数据库视为层次结构中的最高级别。

一个在行(元组)和列(属性)中存储数据。一个数据库可以并且通常由多个表组成

在本教程的其余部分,我们将使用足球(或者您喜欢的足球)运动员的统计数据作为数据库中的数据。

我们要做的第一件事是用“create”命令创建一个名为“soccer_data”的数据库。然后,我们可以用“USE”命令“激活”我们的新数据库。

CREATE DATABASE soccer_stats
USE soccer_stats

就像我们在 Excel 或 Google Sheets 中创建任何表格一样,我们将定义每一列的名称,以及该列中的数据类型。

我们的“统计”表将跟踪每个足球运动员的进球、助攻、得分和射门次数:

CREATE TABLE stats (id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, name TEXT, goals INTEGER, assists INTEGER, points INTEGER, shots INTEGER);

上面的命令为我们做了几件事:

  1. 它在“soccer_stats”数据库中创建了一个名为“stats”的表
  2. 我们在表格中设置了 6 列——id、姓名、进球、助攻、得分和射门
  3. 对于每一列,我们已经定义了希望该列存储的数据类型。
  4. “id”列有一个特殊的类型(INTEGER NOT NULL PRIMARY KEY AUTO _ INCREMENT ),它自动对每一行进行编号。在构建 SQL 表时,最好给每一行一个惟一的 id,以防两行数据完全相同。

我们可以检查数据库中有哪些表,如下所示:

SHOW TABLES;+------------------------+
| Tables_in_soccer_stats |
+------------------------+
| stats                  |
+------------------------+

更进一步,我们可以看到关于我们新创建的表的一些信息:

DESCRIBE stats;+---------+---------+------+-----+---------+----------------+
| Field   | Type    | Null | Key | Default | Extra          |
+---------+---------+------+-----+---------+----------------+
| id      | int(11) | NO   | PRI | NULL    | auto_increment |
| name    | text    | YES  |     | NULL    |                |
| goals   | int(11) | YES  |     | NULL    |                |
| assists | int(11) | YES  |     | NULL    |                |
| points  | int(11) | YES  |     | NULL    |                |
| shots   | int(11) | YES  |     | NULL    |                |
+---------+---------+------+-----+---------+----------------+

向我们的 SQL 表添加数据

现在我们开始用足球统计数据填充我们的表!

还记得我说过 SQL 非常易读吗?可以使用名为 INSERT 的命令将数据插入到我们的表中,该命令后跟表名和我们想要插入的数据的简单元组。

INSERT INTO stats VALUES (NULL, "John", 26, 22, 26+22, 104);
INSERT INTO stats VALUES (NULL, "Jessica", 126, 82, 126+82, 312);
INSERT INTO stats VALUES (NULL, "Nick", 8, 25, 8+25, 51);
INSERT INTO stats VALUES (NULL, "Mike", 52, 12, 52+12, 174);
INSERT INTO stats VALUES (NULL, "Katie", 26, 92, 26+92, 188);

插入数据时要记住几件事:

  • 我们可以将 id 设置为 NULL,因为它会自动递增(如前一节所述)
  • 请确保正在插入的数据的数据类型与已定义的表的数据类型相匹配

要显示表中的所有数据,只需运行:

SELECT * FROM stats;+----+---------+-------+---------+--------+-------+
| id | name    | goals | assists | points | shots |
+----+---------+-------+---------+--------+-------+
|  1 | John    |    26 |      22 |     48 |   104 |
|  2 | Jessica |   126 |      82 |    208 |   312 |
|  3 | Nick    |     8 |      25 |     33 |    31 |
|  4 | Mike    |    52 |      12 |     64 |   174 |
|  5 | Katie   |    26 |      92 |    118 |    88 |
+----+---------+-------+---------+--------+-------+

这是我们所有的足球数据。

请注意“SELECT *”是如何从我们的表中获取所有内容的。如果您只需要目标的名称和数量,您可以指定要检索的列:

SELECT name,goals FROM stats;
+---------+-------+
| name    | goals |
+---------+-------+
| John    |    26 |
| Jessica |   126 |
| Nick    |     8 |
| Mike    |    52 |
| Katie   |    26 |
+---------+-------+

要更新表中的一行,我们可以使用……你猜对了,更新命令!

UPDATE stats SET goals=28 WHERE name="John";
SELECT * FROM stats;+----+---------+-------+---------+--------+-------+
| id | name    | goals | assists | points | shots |
+----+---------+-------+---------+--------+-------+
|  1 | John    |    28 |      22 |     48 |   104 |
|  2 | Jessica |   126 |      82 |    208 |   312 |
|  3 | Nick    |     8 |      25 |     33 |    31 |
|  4 | Mike    |    52 |      12 |     64 |   174 |
|  5 | Katie   |    26 |      92 |    118 |    88 |
+----+---------+-------+---------+--------+-------+

在上面的查询中:

  • 更新允许我们选择要更新数据的表
  • SET 执行实际的更新
  • 其中定义了哪个数据单元将接收特定的更新

使用 SQL 查询检索数据

现在我们已经用数据填充了表,我们将学习如何实际检索它。对于那些从事数据科学或机器学习的人来说,这将是大量 SQL 工作的地方——检索数据,为探索和培训做准备。

在上一节中,您已经使用 SELECT 命令完成了一个查询。这次我们将运行一些更复杂的查询。

我们可以限制检索的行数:

SELECT * FROM stats LIMIT 3;+----+---------+-------+---------+--------+-------+
| id | name    | goals | assists | points | shots |
+----+---------+-------+---------+--------+-------+
|  1 | John    |    28 |      22 |     48 |   104 |
|  2 | Jessica |   126 |      82 |    208 |   312 |
|  3 | Nick    |     8 |      25 |     33 |    31 |
+----+---------+-------+---------+--------+-------+

或者根据球员的进球数对我们的输出进行排序:

SELECT * FROM stats ORDER BY goals DESC;+----+---------+-------+---------+--------+-------+
| id | name    | goals | assists | points | shots |
+----+---------+-------+---------+--------+-------+
|  2 | Jessica |   126 |      82 |    208 |   312 |
|  4 | Mike    |    52 |      12 |     64 |   174 |
|  1 | John    |    28 |      22 |     48 |   104 |
|  5 | Katie   |    26 |      92 |    118 |    88 |
|  3 | Nick    |     8 |      25 |     33 |    31 |
+----+---------+-------+---------+--------+-------+

我们可以将 SELECT 语句与 WHERE 命令结合起来,创建一种用于检索数据的 if-else 查询:

SELECT * FROM stats WHERE goals > 20 and assists > 50;+----+---------+-------+---------+--------+-------+
| id | name    | goals | assists | points | shots |
+----+---------+-------+---------+--------+-------+
|  2 | Jessica |   126 |      82 |    208 |   312 |
|  5 | Katie   |    26 |      92 |    118 |    88 |
+----+---------+-------+---------+--------+-------+

MySQL 甚至为我们提供了执行计算的能力。看看我们如何计算每个球员的投篮命中率,并根据这些数字对表格进行排序:

SELECT *, points/shots FROM stats ORDER BY points / shots DESC;+----+---------+-------+---------+--------+-------+--------------+
| id | name    | goals | assists | points | shots | points/shots |
+----+---------+-------+---------+--------+-------+--------------+
|  2 | Jessica |   126 |      82 |    208 |   312 |       0.6667 |
|  3 | Nick    |     8 |      25 |     33 |    51 |       0.6471 |
|  5 | Katie   |    26 |      92 |    118 |   188 |       0.6277 |
|  1 | John    |    28 |      22 |     48 |   104 |       0.4615 |
|  4 | Mike    |    52 |      12 |     64 |   174 |       0.3678 |
+----+---------+-------+---------+--------+-------+--------------+

我们对 SQL 的简单介绍到此结束!

如果你想练习使用 SQL 查询,我强烈建议你试试 HackerRank challenges ,它已经为查询练习提供了预构建的数据库和表格。

喜欢学习?

推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

用 4 种基本技术简单介绍无监督学习

原文:https://towardsdatascience.com/an-easy-introduction-to-unsupervised-learning-with-4-basic-techniques-da7fbf0c3adf?source=collection_archive---------17-----------------------

想获得灵感?快来加入我的 超级行情快讯 。😎

深度学习得到了人工智能社区和普通公众的大量喜爱。但最近,研究人员开始质疑和怀疑深度学习真的是人工智能的未来。

今天使用的突出的深度学习技术都依赖于监督学习,然而我们非常清楚地看到,人类在没有太多监督的情况下学习事物、模式和概念。从某种意义上说,我们的学习是相当无人监督的

无监督学习没有得到那么多的喜爱,这有几个明显的原因。这很难,效果也不好(目前为止),还没有做太多的工作,而且无监督框架本身很难具体定义。

也就是说,我们确实有一些无监督学习技术的基础,在某些应用和设置中工作得很好。这些技术可能为人工智能研究的未来提供线索。在这篇文章中,我们将学习 4 种基本的无监督学习技术以及如何应用它们!

使聚集

聚类是一种涉及数据点分组的技术。给定一组数据点,我们可以使用聚类算法将每个点分类到特定的组中。

理论上,同一组中的数据点应该具有相似的属性和/或特征,而不同组中的数据点应该具有非常不同的属性和/或特征。点之间的相似性通常由基于某种特征变量集的距离度量来量化。

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

The popular K-means clustering algorithm

聚类技术简单而有效;它们几乎不需要密集的工作,但通常可以给我们提供非常有价值的数据洞察力。因此,数十年来,它已被用于许多应用中,包括:

  • 生物学,用于遗传和物种分组
  • 医学成像,用于区分不同种类的组织
  • 市场研究,用于根据一些属性了解不同的企业和客户群体
  • 推荐系统,比如给你更好的亚马逊建议

…仅举几个例子!

自动编码器

在进行机器学习时,我们可能会遇到某些情况,我们的特征表示太大而无法处理。例如,假设我们正在做一个人脸识别应用程序,我们希望将每个人的人脸模板保存在我们的数据库中,以便以后可以再次识别它们。如果我们要保存一张 128x128 的人脸彩色图像,我们必须为每张脸保存 128 * 128 * 3 = 49152 个浮点值!如果我们只需要存储 100 张脸,那么对于这样一个看似简单的任务来说,这将会占用大量的磁盘空间!

这就是自动编码器的用武之地。有了自动编码器,我们可以对我们的特征进行编码,这样它们占用的空间就少得多,但仍能有效地表达同样的东西。

为了做到这一点,我们将训练一个神经网络来预测它自己的输入。听起来很奇怪,对吧?!这就是为什么有一个小问题:我们的自动编码器的中间层的比我们的输入和输出少得多。这个想法是,我们可以训练我们的神经网络来学习我们的特征表示的压缩版本。一旦我们这样做了,我们可以简单地存储这些压缩的要素制图表达,占用更少的存储空间,同时仍然能够准确地表示我们的数据!

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

An illustration of a typical autoencoder

特征分离技术

特征分离技术允许我们分解数据集的整体特征表示,并独立地查看每个特征。了解我们的每个要素如何对数据集的形成做出贡献,或者单独输出预测,通常会很有用。这样,我们就可以知道哪些特征是重要的,以及每个特征在我们的整体数据中扮演什么角色。

两种最流行的特征分离技术是:

  • 主成分分析(PCA): 它寻找数据中包含最多方差和信息的线性组合
  • 奇异值分解(SVD): 它将你的数据分解成 3 个小得多的矩阵的乘积

实际上,这两种技术都可以用来创建可以独立分析的孤立特征向量。由于它们都得到比原始数据集小得多的矩阵,它们也可以通过降维用于数据压缩。

给定孤立的特征向量,我们可以选择最能代表我们的数据及其变化的特征向量,然后将我们的数据重新投影到孤立的向量上。两种降维技术之间的过程和联系如下所示。

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

PCA and SVD for dimensionality reduction

期望值最大化算法

期望最大化(EM)算法是一类迭代方法,旨在估计某些统计模型的参数,以便准确地对数据建模。例如,假设我们的数据如下图所示呈高斯分布,我们希望找到高斯分布的最佳参数来对其建模。期望值最大化算法为我们提供了一种自动估计高斯参数的方法:每个方向的均值和标准差!

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

在 EM 算法中,我们在期望(E)步骤和最大化(M)步骤之间交替。E 步骤使用当前参数创建我们的统计模型,并将其应用于我们的数据。

基于我们的数据和我们的数据的统计模型表示之间的误差(即值的差异),M 步骤为模型计算一组新的参数。新的参数被设置成使得我们最小化误差,或者等效地,最大化我们的数据属于我们的统计模型的概率。EM 算法可以用在任何我们想要创建一个统计模型来表示我们的数据的地方,同时自动估计参数。

喜欢学习?

推特上关注我,我会在那里发布所有最新最棒的人工智能、技术和科学!也在 LinkedIn 上和我联系吧!

一种高效快速的方法来控制你的机器人。真的。

原文:https://towardsdatascience.com/an-efficient-and-fast-way-to-control-your-robots-truly-92ee93aadff5?source=collection_archive---------21-----------------------

去年,我们的教授提出了一个新的课堂项目。从零开始创造机器人手臂。在机器人爱好者的生活中,第一个 DIY 机器人可能会改变游戏规则。应该是!—一个简单的机器人项目肯定是从这个问题开始的:这个机器人的目的是什么?

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

School project (Sorbonne Université, Paris)

为了解决这个问题,你自然要探索硬件设计领域。那么你可能会在系统的电子架构中找到一些灵感。在这个思考过程的最后,你设计的机器人看起来很棒,你可能对你的机器人会是什么有一个清晰的想法。这是你需要暂停的时候。你考虑过如何驾驶机器人吗?需要什么样的软件或几何模型?对我来说,这一步是一个巨大的挫折。事实上,命令软件可能是你的项目中最模糊的一点。

在下面的文件中,我会试着给你一些我希望去年在项目实施过程中知道的信息。

如何获得和使用你的机器人的几何模型?

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

基本上,直接的几何模型非常容易获得。它是关于根据关节的角度位置计算效应器的最终位置。这是一个简单的数学演算。

让我们使用机器人手臂的简化模型来确定直接模型,您可以通过更改这些方程中的一些参数来将解决方案推广到所有项目。

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

Simplified Model of a 3 joints robotic arm

使用这个简单的 3 关节机械臂模型,我们得到:

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

X coordinate

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

Y coordinate

使用这个直接模型,我们现在可以根据角度三元组创建一组笛卡尔坐标。这是一个单向过程——这是几何求解的最初步骤。实际上,人们通常对另一种方式感兴趣:从笛卡尔的一对数字(X,Y)到角度三元组:(θ1,θ2,θ3)

好的,那么你的最终目标是获得关于机器人效应器位置的角度三元组。

为此,您可以尝试计算间接模型。这是人们首先要做的,但有时可能会很困难和/或很耗时。为了解决这个问题,我想给你介绍一下监督学习过程。

命令软件可能是你项目最模糊的点。

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

Supervised Learning Model

我们之前计算的直接模型用于计算分别与所谓的角三元组关联的笛卡尔坐标。

使用 MLP 回归器预测角形三胞胎

首先你需要实现你的模型并定义你的机器人关节的参数。这些参数是机器人关节的不同长度。它们也可能是一些预先确定的常数参数,限制你的机器人的移动。

Robot’s model

S 秒您需要创建用于生成模型的数据集。该数据集由角度三元组和笛卡尔位置组成,两者都与直接模型相关联并通过直接模型计算。

Dataset Generation

您还需要生成数据集的分割。第一部分用来训练你的模型,另一部分用来评估它的性能。您应该使用某种洗牌率来避免“糟糕”的学习和灾难性的泛化-永远不要忘记在数据集生成过程中引入洗牌,尽管您可能希望在没有洗牌的情况下尝试观察结果。

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

T hird,我们使用 keras 顺序实现定义多层感知器。随意改变网络的超参数:隐藏层的数量、学习率、网络的深度、退出、正则化等。所有这些变化都将是适合你自己的基于数据的问题的关键。

MLP

然后,您需要使用 Keras API 函数训练模型以适应您的数据:

model.fit

第四,你应该为你的模型建立一个基准来评估它的性能和准确性。要对其评分,您可以使用 Keras 函数并将其应用于验证数据集:

model.evaluate

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

Evaluation of the model

图形评估

我相信机器人的模型达到了一个很好的精度水平,特别是如果你看一下培训时间,碰巧是很短的一段时间。下面是一些使用 Matplotlib 的结果显示。查看 colab 以获得关于这个问题的更多注释和细节。

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

Command is x = 20 and y = 20–40

你应该尝试许多轨迹来弄清楚你的机器人是否能够响应你最初的目的。

别忘了这是基于数据的问题。

有时您会想要约束角度范围。基本上,我的机器人的第一个关节在物理上不能承受负角度:因此,我没有在我的三联输入中引入任何负角度θ1。

用途

最后,利用模型进行预测。您可以使用同一个 Keras API 中的函数:

model.predict#Save the model
model.save_weights(‘model_weights.h5’)model.save(‘model.h5’)

预测的输入可能如下所示:

posCartesian = np.array([[posX, posY]])prediction = model.predict(posCartesian)

非常感谢您的阅读,如果您有任何问题,或者您有合理的批评,或者只是想交流您的项目,请随时联系我们。

下一篇文章将关注使用 Python-Arduino 协作在真实机器上的模型部署。敬请期待!

参考资料:

您应该在此处访问该项目的 Colab:

https://gist . github . com/momento 624/d5c 3d 85 f 6 ff 1 BD 507 f 092 DDB 53d 655 f 0

张量流:https://en.wikipedia.org/wiki/TensorFlow

https://en.wikipedia.org/wiki/Scikit-learn

https://en.wikipedia.org/wiki/NumPy

https://en.wikipedia.org/wiki/Matplotlib

https://en.wikipedia.org/wiki/Keras

电力公司神经网络调峰三部曲指南。

原文:https://towardsdatascience.com/an-electric-utilitys-3-part-guide-to-peak-shaving-with-neural-networks-de5c7752d946?source=collection_archive---------33-----------------------

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

协同 研究开放式建模框架

预测技术给了公用事业单位一个机会来拉平他们的负荷曲线,提出了一系列全新的问题。以下是一些重要问题的解决方案,它们可以通过降低电厂调峰的资本和运营费用,为电力公司节省大量资金。所有测试都可以在这里找到。

这项研究也可以在我的网站上查看:

[## 基于神经网络的⚡️负荷预测和调峰

预测技术给了公用事业单位一个机会来拉平他们的负荷曲线,提出了一个全新的家庭…

www.kmcelwee.com](https://www.kmcelwee.com/load-forecasting/)

第一部分:明天的负荷是多少?

[## 用神经网络预测明天的用电量

最小的错误都会在一天内造成数千美元的损失。神经网络可以帮助确保…

towardsdatascience.com](/using-neural-nets-to-predict-tomorrows-electric-consumption-cc1ae3ae7cc2)

主要要点:

  • 要获得任何有用的能源消耗预测,简单的机器学习是不合适的。然而,深度学习可以让我们获得我们需要的准确性。
  • 给定历史负荷和温度数据,一个简单的神经网络可以给出 24 小时的预测,准确率约为 97%。

[## 用神经网络预测日用电量。

一个简单的三维结构如何减少错误,战胜更复杂的模型,并加倍节省。

medium.com](https://medium.com/@kevinrmcelwee/predict-daily-electric-consumption-with-neural-networks-8ba59471c1d)

主要要点:

  • 一整天的负荷预测方法比一小时一小时的方法更准确。
  • 尽管两种方法之间只有 1 MAPE 的误差差异,但测试表明,由于发电量减少,该方法在调峰时使我们的节约翻倍。

第二部分:但这是月高峰吗?

[## 神经网络的短期预测如何影响长期决策。

电力公司只需三天的天气预报就能探测到每月的高峰。

towardsdatascience.com](/how-short-term-forecasting-with-neural-nets-can-inform-long-term-decisions-9f65eba6fb7e)

主要要点:

  • 每天进行调峰调度可能成本很高。
  • 多天预测可以帮助我们大幅减少每月的派单次数,而不会错过每月的高峰
  • 公用事业公司需要设定他们自己的优先级,但在大多数情况下,他们大约每周只能调度一次,而每隔几年只会错过一次高峰。

第三部分:好的,我们正在派遣。我们应该在多大程度上相信预测?

[## 预测不可靠的调峰。

一个 19 世纪的物理方程如何能让电力公司节约超过 60%

towardsdatascience.com](/peak-shaving-with-unreliable-forecasts-78bb9623e6b0)

主要要点:

  • 因为我们的预测不可避免地存在误差,所以预测的“最优”调度解决方案不一定是实践中的最佳调度。
  • 热量等式可用于分散我们的调度(例如,如果我们的预测预报建议在下午 12 点调度 500 千瓦,则等式可能会在上午 11 点返回 150 千瓦,下午 12 点返回 200 千瓦,下午 1 点返回 150 千瓦。)
  • 这个简单的方法可以节省很多钱。一个地区的储蓄增加了 60%以上。
  • 该方程需要两个常量作为输入,但是对于实用程序来说,优化它们应该不难。

疑问?更正?联系我,查看更多项目在 我的网站

GANs 的端到端介绍

原文:https://towardsdatascience.com/an-end-to-end-introduction-to-gans-bf253f1fa52f?source=collection_archive---------4-----------------------

柠檬榨汁机

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

我敢打赌,我们大多数人最近都见过很多人工智能生成的人脸,无论是在报纸上还是博客上。我们已经到达了一个阶段,在这个阶段,区分真实的人脸和人工智能生成的人脸变得越来越困难。

在这篇文章中,我将帮助读者理解他们如何自己创建和构建这样的应用程序。

对于初学者来说,我会尽可能保持这篇文章的直观性,同时不会让它变得太简单。

这个帖子是关于了解GANs如何工作的。

任务概述

我将致力于使用动漫人物数据集创建我们自己的动漫人物。

我在这里使用的 DC-甘风格的甘不仅可以生成人脸或者新的动漫角色;它还可以用于创建现代时尚风格,用于一般的内容创建,有时也用于数据扩充目的。

在我看来,GANs 将会改变视频游戏和特效的制作方式。这种方法可以按需创建逼真的纹理或角色。

你可以在 Github 库中找到本章的完整代码。我还把代码上传到了谷歌实验室,这样你就可以自己尝试了。

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

使用 DCGAN 架构生成动漫图像

像往常一样,在我们进入编码之前,深入研究一下理论会有所帮助。

DC-甘的主要思想源于亚历克·拉德福德、卢克·梅斯和索史密斯·钦塔拉在 2016 年写的论文深度卷积生成对抗网络的无监督表示学习

虽然我将在接下来的几节中解释这篇论文,但是请务必看一看它。这是一篇优秀的论文。

直觉:生成假图像的 GANs 简介

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

通常情况下, GANs 采用两个决斗神经网络来训练计算机学习数据集的性质,足以生成令人信服的假货。

我们可以将此视为两个系统,其中一个神经网络工作以生成假货(生成器),另一个神经网络(鉴别器)试图对哪个图像是假货进行分类。

由于发生器和鉴别器网络都重复这样做,网络最终会更好地完成各自的任务。

把这个想成剑术那么简单。 两个 noobs 开始互相对打。过了一会儿,两人的剑术都变得更好。

或者你也可以把这个想成一个强盗(发电机)和一个警察(鉴别器)。在多次盗窃之后,强盗变得更擅长偷窃,而警察变得更擅长抓强盗。在理想的世界里。

这些神经网络中的损耗主要是另一个网络表现如何的函数:

  • 鉴别器网络损耗是发生器网络质量的函数——如果鉴别器被发生器的假图像欺骗,那么鉴别器的损耗很高
  • 发电机网络损耗是鉴频器网络质量的函数,如果发电机不能欺骗鉴频器,损耗就很高。

在训练阶段,我们依次训练鉴别器和发生器网络,以提高鉴别器和发生器的性能。

目标是最终得到帮助生成器生成逼真图像的权重。 最后,我们可以使用生成器神经网络从随机噪声中生成假图像。

发电机架构

我们面对的一个主要问题是 GANs 的训练不是很稳定。因此,我们必须想出一个生成器架构来解决我们的问题,并产生稳定的训练。

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

上图摘自论文,解释了 DC-GAN 发生器的架构。这可能看起来有点混乱。

本质上,我们可以将生成器神经网络视为一个黑盒,它接受一个 100 大小的正常生成的数字向量作为输入,并为我们提供一个图像:

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

我们如何得到这样的架构?

在下面的架构中,我们使用大小为 4x4x1024 的密集层从这个 100 维向量中创建一个密集向量。然后,我们用 1024 个滤镜将这个密集矢量重新塑造成 4x4 的图像形状,如下图所示:

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

我们现在不必担心任何权重,因为网络本身会在训练时学习这些权重。

一旦我们有了 1024 个 4x4 的贴图,我们就使用一系列转置卷积进行上采样,在每次操作之后,图像的大小加倍,贴图的数量减半。在最后一步中,虽然我们没有将贴图的数量减半,但是将每个 RGB 通道的贴图数量减少到 3 个通道/贴图,因为我们需要 3 个通道来输出图像。

什么是转置卷积?

最简单地说, 转置卷积为我们提供了一种对图像进行上采样的方法。 在卷积运算中,我们试图从 4x4 图像到 2x2 图像,而在转置卷积中,我们从 2x2 到 4x4 进行卷积,如下图所示:

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

Upsampling a 2x2 image to 4x4 image

问: 我们知道,在卷积神经网络(CNN)中,Un-pooling 普遍用于对输入特征图进行上采样。为什么我们不使用取消池?

这是因为取消汇集不涉及任何学习。然而,转置卷积是可以学习的,这就是为什么我们更喜欢转置卷积而不是反池。它们的参数可以被发电机学习,我们将在一段时间内看到。

鉴别器架构

现在,我们已经理解了生成器架构,这里是作为黑盒的鉴别器。

实际上,它包含一系列的卷积层,并在末端包含一个密集层,以预测图像是否是假的,如下图所示:

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

将图像作为输入,并预测它是真是假。conv 网曾经的每一个形象。

数据预处理和可视化

我们要做的第一件事是查看数据集中的一些图像。以下是可视化数据集中部分影像的 python 命令:

结果输出如下:

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

我们可以看到图像的大小和图像本身。

在这种特殊情况下,我们还需要函数将图像预处理为 64x64x3 的标准大小,然后再继续我们的训练。

在我们使用它来训练我们的 GAN 之前,我们还需要标准化图像像素。你可以看到它的代码被很好地注释了。

正如您将看到的,我们将在代码的培训部分使用前面定义的函数。

DCGAN 的实现

这是我们定义 DCGAN 的部分。我们将定义噪声发生器功能、发生器架构和鉴别器架构。

为发电机生成噪声矢量

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

Kids: Normal Noise generators

下面的代码块是一个帮助器函数,为生成器创建一个预定义长度的噪声向量。它将产生噪声,我们希望使用我们的发生器架构将其转换为图像。

我们使用正态分布

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

要生成噪声矢量,请执行以下操作:

发电机架构

发电机是 GAN 中最关键的部分。

在这里,我通过添加一些转置卷积层来创建一个生成器,以便对图像的噪声向量进行上采样。

正如你所注意到的,这个发生器的结构与 DC-甘最初的论文中给出的不同。

我需要对架构进行一些更改,以更好地适应我们的数据,因此我在中间添加了一个卷积层,并从生成器架构中删除了所有密集层,使其完全卷积。

我也用了很多动量为 0.5,漏 ReLU 激活的 Batchnorm 层。我用的是β=0.5 的亚当优化器。下面的代码块是我将用来创建生成器的函数:

您可以绘制最终的发电机模型:

plot_model(generator, to_file='gen_plot.png', show_shapes=True, show_layer_names=True)

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

Generator Architecture

鉴别器架构

这是鉴别器架构,我使用一系列卷积层和最后的密集层来预测图像是否是假的。

以下是鉴别器的架构:

plot_model(discriminator, to_file='dis_plot.png', show_shapes=True, show_layer_names=True)

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

Discriminator Architecture

培养

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

理解 GAN 中的培训是非常重要的。或许还有点意思。

我首先使用上一节中定义的函数创建我们的鉴别器和生成器:

discriminator = get_disc_normal(image_shape)
generator = get_gen_normal(noise_shape)

然后,发生器和鉴别器相结合,形成最终的 GAN。

discriminator.trainable = False# Optimizer for the GAN
opt = Adam(lr=0.00015, beta_1=0.5) #same as generator
# Input to the generator
gen_inp = Input(shape=noise_shape)GAN_inp = generator(gen_inp)
GAN_opt = discriminator(GAN_inp)# Final GAN
gan = Model(input = gen_inp, output = GAN_opt)
gan.compile(loss = 'binary_crossentropy', optimizer = opt, metrics=['accuracy'])plot_model(gan, to_file='gan_plot.png', show_shapes=True, show_layer_names=True)

这是我们整个 GAN 的架构:

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

训练循环

这是一个主要的区域,我们需要了解到目前为止我们所创建的模块是如何组装和协同工作的。

别担心,我会在这里一步步尝试破解上面的代码。每个训练迭代的主要步骤是:

步骤 1: 从数据集目录中采样一批归一化图像

# Use a fixed noise vector to see how the GAN Images transition through time on a fixed noise. 
fixed_noise = gen_noise(16,noise_shape)# To keep Track of losses
avg_disc_fake_loss = []
avg_disc_real_loss = []
avg_GAN_loss = []# We will run for num_steps iterations
for step in range(num_steps): 
    tot_step = step
    print("Begin step: ", tot_step)
    # to keep track of time per step
    step_begin_time = time.time() 

    # sample a batch of normalized images from the dataset
    real_data_X = sample_from_dataset(batch_size, image_shape, data_dir=data_dir)

**第二步:**产生输入到发电机的噪声

# Generate noise to send as input to the generator
    noise = gen_noise(batch_size,noise_shape)

**第三步:**使用随机噪声生成器生成图像。

# Use generator to create(predict) images
    fake_data_X = generator.predict(noise)

    # Save predicted images from the generator every 100th step
    if (tot_step % 100) == 0:
        step_num = str(tot_step).zfill(4)save_img_batch(fake_data_X,img_save_dir+step_num+"_image.png")

**第四步:**使用生成器图像(伪图像)和真实归一化图像(真实图像)及其噪声标签训练鉴别器。

# Create the labels for real and fake data. We don't give exact ones and zeros but add a small amount of noise. This is an important GAN training trick
    real_data_Y = np.ones(batch_size) - np.random.random_sample(batch_size)*0.2
    fake_data_Y = np.random.random_sample(batch_size)*0.2

    # train the discriminator using data and labelsdiscriminator.trainable = True
    generator.trainable = False# Training Discriminator seperately on real data
    dis_metrics_real = discriminator.train_on_batch(real_data_X,real_data_Y) 
    # training Discriminator seperately on fake data
    dis_metrics_fake = discriminator.train_on_batch(fake_data_X,fake_data_Y) 

    print("Disc: real loss: %f fake loss: %f" % (dis_metrics_real[0], dis_metrics_fake[0]))

    # Save the losses to plot later
    avg_disc_fake_loss.append(dis_metrics_fake[0])
    avg_disc_real_loss.append(dis_metrics_real[0])

步骤 5: 使用噪声作为 X,1(有噪声的)作为 Y 来训练 GAN,同时保持鉴别器不可训练。

# Train the generator using a random vector of noise and its labels (1's with noise)
    generator.trainable = True
    discriminator.trainable = FalseGAN_X = gen_noise(batch_size,noise_shape)
    GAN_Y = real_data_Y

    gan_metrics = gan.train_on_batch(GAN_X,GAN_Y)
    print("GAN loss: %f" % (gan_metrics[0]))

我们使用 for 循环重复这些步骤,最终得到一个好的鉴别器和生成器。

结果

最终的输出图像如下所示。正如我们所看到的,GAN 可以为我们的内容编辑朋友生成非常好的图像。

它们可能有点粗糙,但仍然是我们 GAN 之旅的开始。

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

训练期间的损失

这是为损失生成的图表。我们可以看到,随着步骤的增加,GAN 损耗平均在下降,方差也在下降。为了获得更好的结果,可能需要进行更多的迭代训练。

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

每 1500 步生成一幅图像

您可以在 Colab 中看到输出和运行代码:

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

下面给出了在不同的训练步骤中生成一些图像的代码。正如我们所见,随着步数的增加,图像变得越来越好。

下面给出了 GAN 在不同时间步长的结果:

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

结论

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

Power in your hands

在本帖中, 我们了解了 s的基本知识。我们还了解了 DC-甘的生成器和鉴别器架构,并构建了一个简单的 DC-甘来从头开始生成动画图像。

这个模型不太擅长生成假图像,但我们通过这个项目了解了 GANs 的基本知识,并且随着我们的发展,我们有信心建立更多令人兴奋和复杂的 GANs。

GANs 的 DC-GAN 风格不仅可以广泛应用于生成人脸或新的动画角色,还可以用于生成新的时尚风格,用于一般的内容创建,有时也用于数据增强目的。

如果我们手头有训练数据,我们现在可以按需变出逼真的纹理或角色,这可不是一个小壮举。

如果你想了解更多关于深度学习的应用和用例,可以看看 Andrew NG 的深度学习专业化中的序列模型课程。Andrew 是一位很棒的讲师,这门课程也很棒。

我以后也会写更多这样的帖子。让我知道你对这个系列的看法。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

一名工程师成为数据科学家的旅程

原文:https://towardsdatascience.com/an-engineers-journey-to-become-a-data-scientist-85edeaaaa932?source=collection_archive---------23-----------------------

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

Unsplash

Neha 有工程和 MBA 背景。她在休了几年个人休假后,希望重新加入劳动力大军。她上一份工作涉及业务流程分析、规划和市场研究。她不想回到过去。

当她开始探索更令人满意的职业生涯时,分析成为一个强有力的竞争者。她一直喜欢数据和模式。

阿林很快出现在她的雷达上。她参加了阿林的能力评估。她的好成绩为她确定了道路。她知道她有这个能力!

Neha 报名参加了 Aryng 的 ACAP -职业过渡课程。

她完成了业务分析、A/B 测试和预测分析的数据科学实践课程。她准备好了她的真实世界的客户项目。

她和我们的客户 JustAnswer 一起做实时分析项目培训。他们需要帮助识别诽谤者,以获得付费的专家答案。

Neha 直接与负责主页的利益相关者合作,以了解用户流失的地方和最佳转化率的来源。

在这个项目中,她作为她的导师在后台和我一起工作。

根据她的分析,她建议对主页和流程进行四项主要改变——添加快速点击标签以实现最佳转化,根据最高下降率将漏斗从五个页面减少到四个页面,在支付页面上添加一个新按钮,以及优化移动体验。这些变化可以帮助 JustAnswer 获得超过 100 万美元的增量收入。

产品团队立即开始工作。他们设计了一个实验来测试她的建议,在完成她的项目后的一个月内,公司采纳了 Neha 建议的所有改变来获取增量收入。

培训和后续项目改变了 Neha 的游戏规则。该项目让她对整个分析工作流程有了一个完整的“从头到尾”的体验。她现在切身体会到了数据科学的强大。

在她的实时项目结束后,作为她的职业教练课程的一部分,她和我一起针对具体的分析师工作,并相应地修改她的简历。几经周折后,她有了一份完美的 8 秒简历,开始申请工作。一旦她开始接受面试,她就和我安排了另一次职业辅导会议,帮助她获得了梦想中的工作。

如今,Neha 是圣克拉拉县的一名数据分析师。她已经成功过渡了。

就我而言,我看到 Neha 从一个害羞、不自信、刚刚重返职场的专业人士转变为一个自信的分析师,她可以在面试中回答棘手的分析问题,证明自己对公司的价值,并获得结果。

快乐的 Neha 打电话给我,告诉我她在圣克拉拉县的工作机会,她是另一个 Neha,一年前她安排了 15 分钟的聊天,询问 Aryng 的 ACAP-职业过渡轨道。

我沉迷于这种转变。我想和那些准备实现梦想的人一起踏上这个旅程。这就是我教授数据科学的原因,也是我邀请你参加这个免费的大师班的原因,该班讲述了将你的职业生涯成功过渡到分析的 5 个步骤。

Neha 和成千上万的其他人已经做到了,你也可以!

Python 中的“等式到代码”机器学习项目演练—第 1 部分线性可分问题

原文:https://towardsdatascience.com/an-equation-to-code-machine-learning-project-walk-through-in-python-part-1-linear-separable-fd0e19ed2d7?source=collection_archive---------13-----------------------

数学方程式背后的详细解释,为您的机器学习或深度学习之旅奠定实用的数学基础

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

Photo: Halfpoint/Shutterstock

从工程师到机器学习工程师的一大差距是将数学方程转换为真实代码的能力。有时我们真的需要从头实现一些基本概念,以更好地理解幕后的魔力,而不是在没有进一步理解的情况下只导入库。

所以我决定写一些文章来解释如何将数学方程式转换成真正的代码。这是第 1 部分,我将给出一个使用逻辑回归对一个线性可分问题进行分类的例子。我会尽可能简单地解释。

这里是数据代码

内容结构如下。看起来有点长,

  1. 看数据
  2. 线性可分问题
  3. 向量表示法
  4. 标准化
  5. 添加偏差
  6. Sigmoid 函数
  7. 似然函数
  8. 更新参数θ
  9. 绘制直线
  10. 摘要

1 看数据

下面是数据, linear_data.csv

x1,x2,y
153,432,0
220,262,0
118,214,0
474,384,1
485,411,1
233,430,0
396,321,1
484,349,1
429,259,1
286,220,1
399,433,0
403,300,1
252,34,1
497,372,1
379,416,0
76,163,0
263,112,1
26,193,0
61,473,0
420,253,1

首先,我们需要绘制这些数据,看看它是什么样子的。我们创建一个 Python 文件,并将其命名为 logistic_regression.py。

import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", *delimiter*=',', *skiprows*=1)
train_x = data[:, 0:2]
train_y = data[:, 2]# plot
plt.plot(train_x[train_y == 1, 0], train_x[train_y == 1, 1], 'o')
plt.plot(train_x[train_y == 0, 0], train_x[train_y == 0, 1], 'x')
plt.show()

运行上面的脚本后,您应该会看到下图。

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

我们可能认为一条直线应该能很好地把 X 和 O 分开。而这是一个线性可分问题

2 线性可分问题

我们需要为这样的问题找到一个模型。最简单的情况是使用线性函数

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

我们用θ来表示参数。左边的θ标记表示函数 f(x)有参数θ。右边的θ表示有两个参数。

我们可以把它写成代码

import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", *delimiter*=',', *skiprows*=1)
train_x = data[:, 0:2]
train_y = data[:, 2]theta = np.random.randn(2)**def f(x):
    return theta[0] + theta[1] * x**

3 矢量表示法

我们也可以把线性函数改写成更简单的方式,向量方式。

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

这里的θ和 x 都是列向量。

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

之所以用θ的转置,是因为可以用矩阵乘法。

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

我们可以写下面的代码

import numpy as np
import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", *delimiter*=',', *skiprows*=1)
train_x = data[:, 0:2]
train_y = data[:, 2]# initialize parameter
theta = np.random.randn(2)**# dot product
def f(x):
    return np.dot(theta, x)**

你可能想知道为什么我们不写np.dot(theta.T, x)?因为文档如果两个向量都是一维数组,那么就是向量的内积(没有复共轭)。所以np.dot(theta, x)做和np.dot(theta.T, x)一样的事情。

4 标准化

为了使训练快速收敛,我们使用标准化,也叫 z - 评分。我们是按列来做的。

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

  • 𝜇在每一栏都很刻薄
  • 𝜎是每列的标准偏差
import numpy as np
import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", *delimiter*=',', *skiprows*=1)
train_x = data[:, 0:2]
train_y = data[:, 2]# initialize parameter
theta = np.random.randn(2)**# standardization
mu = train_x.mean(axis=0)
sigma = train_x.std(axis=0)****def standardizer(x):
    return (x - mu) / sigma
std_x = standardizer(train_x)**# dot product
def f(x):
    return np.dot(theta, x)

5 添加偏差

我们需要在函数中加入一个偏差项,使我们的模型具有更好的泛化能力。所以我们把参数从 2 增加到 3。并且添加常数 x0=1,以便对齐矢量表示。

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

为了使计算更简单,我们把 x 转换成矩阵。

import numpy as np
import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", *delimiter*=',', *skiprows*=1)
train_x = data[:, 0:2]
train_y = data[:, 2]**# initialize parameter
theta = np.random.randn(3)**# standardization
mu = train_x.mean(axis=0)
sigma = train_x.std(axis=0)def standardizer(x):
    return (x - mu) / sigma
std_x = standardizer(train_x)**# get matrix
def to_matrix(std_x):
    return np.array([[1, x1, x2] for x1, x2 in std_x])
mat_x = to_matrix(std_x)**# dot product
def f(x):
    return np.dot**(x, theta)**

std_x的尺寸为(20, 2)to_matrix(std_x)之后mat_x的尺寸为(20, 3)。至于点积部分,注意这里我们改变了 x 和θ的位置,θ的量纲是(3,)。所以点生成的结果应该是(20,3) x (3,)->(20,),这是一个包含 20 个样本预测的一维数组。

6 Sigmoid 函数

下面是我们到目前为止讲过的线性函数。

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

熟悉了线性函数之后。我们将在此基础上构建一个更强大的预测函数,sigmoid 函数。

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

我们用 z 来表示线性函数,并将其传递给 sigmoid 函数。sigmoid 函数将给出每个数据样本的概率。我们的数据中有两个类,一个是1,另一个是0

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

我们可以看到模型基于线性函数部分预测样本。

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

我们可以写下面的代码

import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", delimiter=',', skiprows=1)
train_x = data[:, 0:2]
train_y = data[:, 2]# initialize parameter
theta = np.random.randn(3)# standardization
mu = train_x.mean(axis=0)
sigma = train_x.std(axis=0)
def standardizer(x):
    return (x - mu) / sigma
std_x = standardizer(train_x)# get matrix
def to_matrix(std_x):
    return np.array([[1, x1, x2] for x1, x2 in std_x])
mat_x = to_matrix(std_x)**# sigmoid function
def f(x):
    return 1 / (1 + np.exp(-np.dot(x, theta)))**

7 似然函数

如果你对方程式的解释不感兴趣,你可以直接跳到第 7 步的最后一部分。

好了,我们准备了数据、模型(sigmoid ),还需要什么?是的,一个目标函数。**目标函数可以指导我们如何以正确的方式更新参数。**对于 sigmoid(逻辑回归),我们通常使用对数似然作为目标函数

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

等等,等等…这些东西到底是怎么回事!

不要慌。冷静点。

让我们把它拆开。

  • 1->2(如何从第 1 行到第 2 行):log(ab) = log a + log b
  • 2->3: log(a)^b = b * log a
  • 3->4:由于我们只有两个类,y=0 和 y=1,所以我们可以使用下面的等式:

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

3->4

  • 4->5:我们使用下面的变换使等式更具可读性

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

所以我们得到了最后一部分。

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

别忘了我们为什么开始这个。目标函数可以指导我们如何以正确的方式更新参数。

我们需要用这个来计算损耗,以更新参数。更具体地说,我们需要计算对数似然函数的导数。这里我直接给出最后的更新方程式。(如果你对如何得到这个方程感兴趣,这个视频应该会有帮助)

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

第六步,最重要的方程就是这个。如果你不明白如何做到这一点,这是完全可以的。我们需要做的就是把它写成真正的代码。

8 更新参数θ

第八步稍微长一点,但是很重要。别慌。我们会破解它。

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

θj 是第 j 个参数。

  • η是学习率,我们设为 0.001 (1e-3)。
  • n 是数据样本的数量,在我们的例子中,我们有 20 个。
  • I 是第 I 个数据样本

因为我们有三个参数,所以可以写成三个方程。

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

:=符号就像=。你可以在这里找到解释

最难的部分是σ(求和符号),所以为了更好地理解,我扩展了σ。

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

仔细看。

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

我给等式中的三个部分涂上颜色,因为我们可以用矩阵来表示它们。看第一行红色和蓝色的部分,我们更新了θ0。

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

我们把红色部分和蓝色部分写成列向量。

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

因为我们有 20 个数据样本,所以f的维数是(20,1)x0的尺寸为(20,1)。我们可以用转置写矩阵乘法。

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

所以尺寸应该是(1, 20) x (20, 1) -> (1,)。我们得到一个标度来更新θ0。

x1x2也是列向量。我们可以把它们写成一个 X 矩阵。

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

θ是一个行向量

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

回到等式。

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

我们可以写为

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

写作是一个等式。

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

类似 Numpy 数组的版本可能容易理解。

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

让我们做一点计算,以确保尺寸是正确的。

θ: (1, 3) 
f^T: (1, 20) 
x: (20, 3)dot production: (1, 20) x (20, 3) -> (1, 3)

一切看起来都那么正确。让我们写代码。实际上,只有两行。

import numpy as np
import matplotlib.pyplot as plt# read data
data = np.loadtxt("linear_data.csv", delimiter=',', skiprows=1)
train_x = data[:, 0:2]
train_y = data[:, 2]# initialize parameter
theta = np.random.randn(3)# standardization
mu = train_x.mean(axis=0)
sigma = train_x.std(axis=0)
def standardizer(x):
    return (x - mu) / sigma
std_x = standardizer(train_x)# get matrix
def to_matrix(std_x):
    return np.array([[1, x1, x2] for x1, x2 in std_x])
mat_x = to_matrix(std_x)# dot product
def f(x):
    return np.dot(x, theta)# sigmoid function
def f(x):
    return 1 / (1 + np.exp(-np.dot(x, theta)))# update times
epoch = 2000# learning rate
ETA = 1e-3# update parameter
**for _ in range(epoch):
**    """
    f(mat_x) - train_y: (20,)
    mat_x: (20, 3)
    theta: (3,)

    dot production: (20,) x (20, 3) -> (3,)
    """ **theta = theta - ETA * np.dot(f(X) - train_y, mat_x)**

奇怪的事?还记得我们在代码前写了什么吗?

dot production: (1, 20) x (20, 3) -> (1, 3)The dimension changes make sense here.

但是为什么我们写代码的时候要用(20,) x (20, 3) -> (3,)

实际上,这不是真正的数学符号,这是 Numpy 符号。而且如果你用的是 TensorFlow 或者 PyTroch 的话,应该很熟悉。

(20,)表示这是一个包含 20 个数字的一维数组。它可以是行向量,也可以是列向量,因为它只有一维。如果我们将其设置为二维数组,像(20, 1)(1, 20),我们可以很容易地确定(20, 1)是一个列向量而(1, 20)是一个行向量。

但是为什么不显式设置维度来消除歧义呢?

好吧。相信我,我第一次看到这个的时候就有接缝问题。但是经过一些编码实践,我想我知道原因了。

因为它可以节省我们的时间!

我们以(20,) x (20, 3) -> (3,)为例。如果我们想得到(1, 20) x (20, 3) -> (1, 3),我们需要用(20,) x (20, 3) -> (3,)做什么?

  • 将(20,)转换为(1,20)
  • 计算(1,20) x (20,3) -> (1,3)
  • 因为(1,3)是一个二维列向量,我们需要将其转换为一维数组。(1,3) -> (3,)

老实说,这很令人沮丧。为什么我们不能一步到位?

对,所以我们才能写(20,) x (20, 3) -> (3,)

好了,我们来看看 numpy.dot() doc 是怎么说的。

numpy.dot() :如果 a 是一个 N 维数组, b 是一个 1 维数组,那么它就是 ab 最后一个轴上的和积。

嗯,事实上我不明白。但是 np.matmul() 描述了与(20,1)或(1,20)的整形类似的计算,以执行标准的 2d 矩阵乘积。也许我们能得到一些灵感。

np.matmul() :如果第一个参数是 1-D,则通过在它的维数前加上 1 来将其提升为矩阵。在矩阵乘法之后,前置的 1 被移除。

哈,这就是缺失的部分!所以在我们的例子中,(20,)变成了(1, 20),因为(20,3)的第一维度是 20。还有(1, 20) * (20, 3) -> (1, 3)。然后前置 1 被删除,所以我们得到(3,)。一步到位。

9 画出这条线

在更新参数 2000 次后,我们应该绘制结果来查看我们的模型的性能。

我们将一些数据点做为 x1,根据我们所学的参数计算 x2。

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

# plot line
x1 = np.linspace(-2, 2, 100)
**x2 = - (theta[0] + x1 * theta[1]) / theta[2]**plt.plot(std_x[train_y == 1, 0], std_x[train_y == 1, 1], 'o') # train data of class 1
plt.plot(std_x[train_y == 0, 0], std_x[train_y == 0, 1], 'x') # train data of class 0
**plt.plot(x1, x2, linestyle='dashed') # plot the line we learned** plt.show()

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

10 摘要

恭喜你!我很高兴你能来。希望我的文章对你有帮助。你可以在下面找到完整的代码。留下评论让我知道我的文章是否易懂。请继续关注我的下一篇关于非线性可分性问题的文章。

查看我的其他帖子 中等 分类查看
GitHub:
bramble Xu LinkedIn:徐亮 博客:bramble Xu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值