热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

人工智能小白日记之10ML学习篇之6特征组合

人工智能小白日记之10 ML学习篇之6特征组合Feature Crosses

  • 前言
  • 课程内容
    • 1 利用合成特征学习非线性规律
    • 2 组合独热矢量
    • 3 Playground 练习1
    • 4 Playground 练习2
      • 任务 1
      • 任务 2
      • 任务 3
  • 编程练习
    • 1 FTRL 优化算法
    • 2 离散特征的独热编码
    • 3 分桶(分箱)特征
      • 3-1 分桶特征的特征列
      • 3-2 计算分桶边界
      • 3-3 分桶特征的特征列
    • 任务 1:使用分桶特征列训练模型
    • 任务 2:使用特征组合训练模型
  • 小结

前言

前面处理的都是线性问题,比如这样的
人工智能小白日记之10 ML学习篇之6特征组合
可以用一个简单的线性模型来实现分类。
y = w1x1+w2x2+b.
但是如果是这样的呢?
人工智能小白日记之10 ML学习篇之6特征组合
不能用简单的线性模型来处理,怎么处理呢?可以引入合成特征

课程内容

1 利用合成特征学习非线性规律

这里观察蓝点和红点的分布,是有规律的。第一和第三象限的
x1x2乘积为负,二四象限的乘积为正,利用这个特征交叉特征交叉乘积),可以在线性模型中学习非线性规律。这样可以创建组合特征x1x2,给它一个权重w3,更新公式为:
人工智能小白日记之10 ML学习篇之6特征组合
事实上,多年来线性学习器是我们真正拥有的 可以扩展到数十亿或数千亿规模数据集的唯一方法。现在我们还有扩展效果不错的深度神经网络, 这是另一种方案。

2 组合独热矢量

现实中很多特征是非数值型的,假设我们具有以下两个特征:国家/地区和语言,他们都是字符串。前面的学习让我们知道要采用独热编码,比如上节例子中的latitude,经过分桶,我们得到了10个桶,这10个特征构成了一个矢量。
人工智能小白日记之10 ML学习篇之6特征组合

3 Playground 练习1

任务:尝试创建一个能够通过手动更改以下三个输入特征的权重将蓝点与橙点分开的模型:

  • x1
  • x2
  • x1 x2(特征组合)
    人工智能小白日记之10 ML学习篇之6特征组合
    分析:这题属于简单题,刚才已经分析过了,一三象限的
    x1x2乘积为负,二四象限的乘积为正,能很干脆的划分出来。所以x1x2应该给予最高权重,三个权重给0.1,0.1,0.8看看效果。
    人工智能小白日记之10 ML学习篇之6特征组合
    基本ok

4 Playground 练习2

现在,我们来使用一些高级特征组合。此 Playground 练习中的数据集看起来有点像飞镖游戏中的飞镖击中位置,中间是蓝点,外圈是橙点。
人工智能小白日记之10 ML学习篇之6特征组合
分析:圆形很容易让人想起一个特点,半径固定,如果我们把蓝色点的分布位置想象成一个圆,那么x12+x22<=r2。所以这里,果断选这两个作为特征。

任务 1

按照指定方式运行此线性模型。花一两分钟时间(不再更多)尝试不同的学习速率设置,看看是否出现任何改进。线性模型可以针对此数据集得出有效结果吗?

ps:指定方式就是x1和x2作为特征,不看好结果
人工智能小白日记之10 ML学习篇之6特征组合
看吧,损失达到了一半以上,毕竟画直线肯定无法完成任务。

任务 2

现在,尝试添加向量积特征(例如 x1x2),以尝试优化效果。

  • 哪些特征最有帮助?
  • 您可以实现的最佳效果是什么?

ps:加乘积肯定也没啥卵用
人工智能小白日记之10 ML学习篇之6特征组合
损失也在一半以上。哪些特征最有用?一开始就分析了,就是那两个平方x12和x22。全部加上看效果
人工智能小白日记之10 ML学习篇之6特征组合
损失显著降低,其实我们用这两个特征,顺便调节下学习速率,达到最佳效果:
人工智能小白日记之10 ML学习篇之6特征组合
训练损失只有0.164

任务 3

如果您有一个出色的模型,请检查该模型的输出面(以背景颜色显示)。

  • 看起来像线性模型吗?不像
  • 您会如何描述该模型?
编程练习

进入该节的练习
人工智能小白日记之10 ML学习篇之6特征组合
人工智能小白日记之10 ML学习篇之6特征组合
看来还是在之前的基础上做优化

1 FTRL 优化算法

高维度线性模型可受益于使用一种基于梯度的优化方法,叫做 FTRL。该算法的优势是针对不同系数以不同方式调整学习速率,如果某些特征很少采用非零值,该算法可能比较实用(也非常适合支持 L1 正则化)。我们可以使用 FtrlOptimizer 来应用 FTRL。
ps:这里告诉我们可以采用新的评估器了,之前采用的GradientDescentOptimizer。这里就涉及比较高端的东西了,我大概查了一下,不是当前做应用能看懂的,比如这样的,随便感受一下哈,http://www.cnblogs.com/EE-NovRain/p/3810737.html。
我们知道有这个东西就行了,以后慢慢加深学习。

2 离散特征的独热编码

通常,在训练逻辑回归模型之前,离散(即字符串、枚举、整数)特征会转换为二元特征系列。

字符串的我们见过了,枚举和整型的,比如有个特征的值是1,2,3,4,5中的一个,那么我们可以用log2(5)<3个特征来表示,每个特征的值只有0或者1。比如5可以表示为(1,1,1)。

3 分桶(分箱)特征

分桶之前聊过,但是那种方式是透明的,我们先打印了整个随机抽样数据知道latitude的范围32-44,然后再做的分桶。原文中也再次举例:
人工智能小白日记之10 ML学习篇之6特征组合
这里有必要贴出来,因为这里是分桶索引。没错,最后的特征矢量,是以索引的方式存在。比如[42004]是属于>25000的范围,所以归属于bucket_2,索引为2。这些索引被视为离散特征,一般来说需要将[[1], [2], [0], [1]]这些离线特征,用第2点中的独热编码来表示。

3-1 分桶特征的特征列

前面,我们构建数值类型的特征列用的是numeric_column
人工智能小白日记之10 ML学习篇之6特征组合
对于分桶特征,用的是
bucketized_column(
source_column, # 必须是numeric_column
boundaries
)
根据这个函数,我们需要先定义数值特征列,然后提供它的分桶边界,比如之前的latitude是以整数33,34,35等为分桶边界的。

3-2 计算分桶边界

原文中给了方法

def get_quantile_based_boundaries(feature_values, num_buckets):
  boundaries = np.arange(1.0, num_buckets) / num_buckets
  quantiles = feature_values.quantile(boundaries)
  return [quantiles[q] for q in quantiles.keys()]

我们利用打印大法来研究一下这个函数做了啥。
为了方便,我们加上输出,然后用之前用过的latitude试试

def get_quantile_based_boundaries(feature_values, num_buckets):
  boundaries = np.arange(1.0, num_buckets) / num_buckets
  print(boundaries)
  quantiles = feature_values.quantile(boundaries)
  print(quantiles)
  return [quantiles[q] for q in quantiles.keys()]

latitude_boundaries=get_quantile_based_boundaries(
    california_housing_dataframe["latitude"], 10)

print(latitude_boundaries)

人工智能小白日记之10 ML学习篇之6特征组合

知识扩展
1)np.arange(1.0, num_buckets) / num_buckets 这里根据你输入的分桶数量,均分生成边界点的位置比例
2)feature_values.quantile(boundaries),其实原型是
人工智能小白日记之10 ML学习篇之6特征组合
这里q传入了boundaries数组,interpolation则使用了默认的线性插值。最后根据q,返回对应的分位点。
人工智能小白日记之10 ML学习篇之6特征组合
比如这个例子,当q=0.5时,分位点2.5利用默认线性插值怎么算的呢?(max-min)*q+min
所以q=0.5 返回(4-1)*0.5+1 = 2.5
q=0.25 时,返回(4-1)*0.25+1 = 1.75
q=0.75 时,返回(4-1)*0.75+1 = 3.25
所以,我们用latitude也是这么算出来对应的分位点

3-3 分桶特征的特征列

根据以上原理,分别得到households和longitude的特征列

def get_quantile_based_boundaries(feature_values, num_buckets):
  boundaries = np.arange(1.0, num_buckets) / num_buckets
  quantiles = feature_values.quantile(boundaries)
  return [quantiles[q] for q in quantiles.keys()]

# Divide households into 7 buckets.
households = tf.feature_column.numeric_column("households")
bucketized_households = tf.feature_column.bucketized_column(
  households, boundaries=get_quantile_based_boundaries(
    california_housing_dataframe["households"], 7))

# Divide longitude into 10 buckets.
longitude = tf.feature_column.numeric_column("longitude")
bucketized_longitude = tf.feature_column.bucketized_column(
  longitude, boundaries=get_quantile_based_boundaries(
    california_housing_dataframe["longitude"], 10))

输出结果为:
人工智能小白日记之10 ML学习篇之6特征组合

任务 1:使用分桶特征列训练模型

在前面的代码块中,两个实值列(即 householdslongitude)已被转换为分桶特征列。您的任务是对其余的列进行分桶,然后运行代码来训练模型。您可以采用各种启发法来确定分桶的范围。本练习使用了分位数技巧,通过这种方式选择分桶边界后,每个分桶将包含相同数量的样本。

分析:这个任务简单,复制一下代码就可以完成了

def construct_feature_columns():
  """Construct the TensorFlow Feature Columns.

  Returns:
    A set of feature columns
  """ 
  households = tf.feature_column.numeric_column("households")
  longitude = tf.feature_column.numeric_column("longitude")
  latitude = tf.feature_column.numeric_column("latitude")
  housing_median_age = tf.feature_column.numeric_column("housing_median_age")
  median_income = tf.feature_column.numeric_column("median_income")
  rooms_per_person = tf.feature_column.numeric_column("rooms_per_person")
  
  
  # Divide households into 7 buckets.
  bucketized_households = tf.feature_column.bucketized_column(
    households, boundaries=get_quantile_based_boundaries(
      training_examples["households"], 7))

  # Divide longitude into 10 buckets.
  bucketized_longitude = tf.feature_column.bucketized_column(
    longitude, boundaries=get_quantile_based_boundaries(
      training_examples["longitude"], 10))

  #
  # YOUR CODE HERE: bucketize the following columns, following the example above:
  #
  bucketized_latitude = tf.feature_column.bucketized_column(
    latitude, boundaries=get_quantile_based_boundaries(
      training_examples["latitude"], 10))
  bucketized_housing_median_age = tf.feature_column.bucketized_column(
    housing_median_age, boundaries=get_quantile_based_boundaries(
      training_examples["housing_median_age"], 10))
  bucketized_median_income =tf.feature_column.bucketized_column(
    median_income, boundaries=get_quantile_based_boundaries(
      training_examples["median_income"], 10))
  bucketized_rooms_per_person =tf.feature_column.bucketized_column(
    rooms_per_person, boundaries=get_quantile_based_boundaries(
      training_examples["rooms_per_person"], 10))
  
  
  feature_columns = set([
    bucketized_longitude,
    bucketized_latitude,
    bucketized_housing_median_age,
    bucketized_households,
    bucketized_median_income,
    bucketized_rooms_per_person])
  
  return feature_columns

不过这里分桶个数,怎么定,我还不清楚,都放了10上去
人工智能小白日记之10 ML学习篇之6特征组合

任务 2:使用特征组合训练模型

longitude 与 latitude 组合,产生的组合特征则代表一个明确的城市街区。目前,特征列 API 仅支持组合离散特征。要组合两个连续的值(比如 latitude 或 longitude),我们可以对其进行分桶。

如果我们组合 latitude 和 longitude 特征(例如,假设 longitude 被分到 2 个分桶中,而 latitude 有 3 个分桶),我们实际上会得到 6 个组合的二元特征。当我们训练模型时,每个特征都会分别获得自己的权重。

请参阅有关 crossed_column() 的 TensorFlow API 文档,了解如何为您的组合构建特征列。hash_bucket_size 可以设为 1000。

**分析:也就是说分桶的特征进行组合的特征列要用到crossed_column,有点乱啊,貌似针对不同的特征需要用到对应的方法生成特征列。撸一下,我们现在遇到了三种,一种是数值特征用的num_column,一种是分桶特征用的bucketized_column,现在是第三种特征组合要用到crossed_column。**我们来看看官方api:
人工智能小白日记之10 ML学习篇之6特征组合
人工智能小白日记之10 ML学习篇之6特征组合
keys:需要传入被cross的特征,可以是字符串,也可以是_CategoricalColumn特征列。我们现在的bucketized_latitude和bucketized_longitude,就是符合条件的分桶特征列。

hash_bucket_size:桶数量,为啥要设1000呢?
hash_key:这个忽略了,fingerprintcat64函数都不知道是啥

打印一下:
人工智能小白日记之10 ML学习篇之6特征组合
有戏。更新特征列代码:

def construct_feature_columns():
  """Construct the TensorFlow Feature Columns.

  Returns:
    A set of feature columns
  """ 
  households = tf.feature_column.numeric_column("households")
  longitude = tf.feature_column.numeric_column("longitude")
  latitude = tf.feature_column.numeric_column("latitude")
  housing_median_age = tf.feature_column.numeric_column("housing_median_age")
  median_income = tf.feature_column.numeric_column("median_income")
  rooms_per_person = tf.feature_column.numeric_column("rooms_per_person")
  
  # Divide households into 7 buckets.
  bucketized_households = tf.feature_column.bucketized_column(
    households, boundaries=get_quantile_based_boundaries(
      training_examples["households"], 7))

  # Divide longitude into 10 buckets.
  bucketized_longitude = tf.feature_column.bucketized_column(
    longitude, boundaries=get_quantile_based_boundaries(
      training_examples["longitude"], 10))
  
  # Divide latitude into 10 buckets.
  bucketized_latitude = tf.feature_column.bucketized_column(
    latitude, boundaries=get_quantile_based_boundaries(
      training_examples["latitude"], 10))

  # Divide housing_median_age into 7 buckets.
  bucketized_housing_median_age = tf.feature_column.bucketized_column(
    housing_median_age, boundaries=get_quantile_based_boundaries(
      training_examples["housing_median_age"], 7))
  
  # Divide median_income into 7 buckets.
  bucketized_median_income = tf.feature_column.bucketized_column(
    median_income, boundaries=get_quantile_based_boundaries(
      training_examples["median_income"], 7))
  
  # Divide rooms_per_person into 7 buckets.
  bucketized_rooms_per_person = tf.feature_column.bucketized_column(
    rooms_per_person, boundaries=get_quantile_based_boundaries(
      training_examples["rooms_per_person"], 7))
  
  # YOUR CODE HERE: Make a feature column for the long_x_lat feature cross
  long_x_lat = tf.feature_column.crossed_column([bucketized_latitude, bucketized_longitude], 1000)
  
  feature_columns = set([
    bucketized_longitude,
    bucketized_latitude,
    bucketized_housing_median_age,
    bucketized_households,
    bucketized_median_income,
    bucketized_rooms_per_person,
    long_x_lat])
  
  return feature_columns

训练结果:
人工智能小白日记之10 ML学习篇之6特征组合

小结

本篇描述了特征组合,在加利福利亚州的案例中进行了应用,由于latitude和longitude是连续型数据,需要进行分桶后再进行组合,组合方式是cross,类似笛卡尔积。


推荐阅读
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 本文介绍了几种常用的图像相似度对比方法,包括直方图方法、图像模板匹配、PSNR峰值信噪比、SSIM结构相似性和感知哈希算法。每种方法都有其优缺点,适用于不同的应用场景。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 重要知识点有:函数参数默许值、盈余参数、扩大运算符、new.target属性、块级函数、箭头函数以及尾挪用优化《深切明白ES6》笔记目次函数的默许参数在ES5中,我们给函数传参数, ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • 基于Linux开源VOIP系统LinPhone[四]
    ****************************************************************************************** ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 超分辨率技术的全球研究进展与应用现状综述
    本文综述了图像超分辨率(Super-Resolution, SR)技术在全球范围内的最新研究进展及其应用现状。超分辨率技术旨在从单幅或多幅低分辨率(Low-Resolution, LR)图像中恢复出高质量的高分辨率(High-Resolution, HR)图像。该技术在遥感、医疗成像、视频处理等多个领域展现出广泛的应用前景。文章详细分析了当前主流的超分辨率算法,包括基于传统方法和深度学习的方法,并探讨了其在实际应用中的优缺点及未来发展方向。 ... [详细]
author-avatar
看电影天堂4
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有