[教程10]TensorFlow线性模型教程

在本教程中,我们将使用TensorFlow中的tf.estimator API来解决二进制分类问题:根据年龄,性别,教育和职业(特征)等个人的普查数据,我们将尝试预测人每年赚取5万多美元(目标标签)。我们将训练逻辑回归模型,并给出个人信息,我们的模型将输出0到1之间的数字,这可以解释为个人年收入超过5万美元的可能性。

阅读人口普查数据

我们将使用的数据集是 普查收入数据集。您可以 手动下载 培训数据 和测试数据,或使用如下代码:

import tempfile
import urllib
train_file = tempfile.NamedTemporaryFile()
test_file = tempfile.NamedTemporaryFile()
urllib.urlretrieve("https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data", train_file.name)
urllib.urlretrieve("https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test", test_file.name)

CSV文件下载后,让我们将它们读入 熊猫数据帧。

由于任务是二进制分类问题,我们将构建一个名为“label”的标签列,如果收入超过50K,则其值为1,否则为0。

train_labels = (df_train["income_bracket"].apply(lambda x: ">50K" in x)).astype(int)
test_labels = (df_test["income_bracket"].apply(lambda x: ">50K" in x)).astype(int)

接下来,我们来看看数据框架,看看我们可以使用哪些列来预测目标标签。列可以分为两种类型 - 分类和连续列:

  • 如果一个列的值只能是有限集合中的一个类别,那么该列称为分类。例如,一个人的本国(美国,印度,日本等)或教育程度(高中,大学等)是分类栏目。
  • 如果其值可以是连续范围内的任何数值,则该列称为连续。例如,一个人的资本收益(例如$ 14,084)是一个连续的列。

以下是“普查收入”数据集中列的列表:

列名称 类型 描述
年龄 连续 个人的年龄
workclass 明确的 个人拥有的雇主类型(政府,军事,私人等)。
fnlwgt 连续 人口普查员认为观察值(样本重量)的人数。该变量不会被使用。
教育 明确的 为个人所取得的最高水平的教育。
education_num 连续 数字形式最高的教育水平。
婚姻状况 明确的 个人的婚姻状况
占用 明确的 个人的职业。
关系 明确的 妻子,自己的孩子,丈夫,不在家,其他相对,未婚。
种族 明确的 白人,亚太岛民族,美印爱斯基摩人,其他黑人。
性别 明确的 女人男人。
资本收益 连续 资本收益记录。
capital_loss 连续 资本损失记录。
hours_per_week 连续 每周工作时数。
祖国 明确的 个人原籍国。
收入 明确的 “> 50K”或“<= 50K”,这意味着该人是否每年赚取超过$ 50,000。

将数据转换成传感器

构建tf.estimator模型时,通过Input Builder函数指定输入数据。此构建器函数将不会被调用,直到它后来传递给tf.estimator.Estimator方法,如trainevaluate。此函数的目的是构造以tf.Tensors或tf.SparseTensors 形式表示的输入数据。更详细地说,Input Builder函数返回以下对象

  1. feature_cols:从特征列名称到Tensors或 SparseTensors
  2. label:A Tensor包含标签列。

feature_cols将在下一节中使用键的构造列。因为我们想用不同的数据调用trainevaluate方法,我们定义一个方法,返回基于给定数据的输入函数。请注意,在构建TensorFlow图时,将不会在运行图时调用返回的输入函数。返回的是将输入数据表示为TensorFlow计算的基本单位a Tensor(或SparseTensor)。

我们使用该tf.estimator.inputs.pandas_input_fn方法从熊猫数据帧创建输入函数。火车或测试数据帧中的每个连续列将被转换成一个Tensor,通常是表示密集数据的良好格式。对于分类数据,我们必须将数据表示为a SparseTensor。该数据格式适用于表示稀疏数据。代表输入数据的另一种更先进的方法是构造一个 表示文件或其他数据源的输入和读取器,并以TensorFlow运行图形方式遍历文件。

def input_fn(data_file, num_epochs, shuffle):"""Input builder function."""df_data = pd.read_csv(tf.gfile.Open(data_file),names=CSV_COLUMNS,skipinitialspace=True,engine="python",skiprows=1)# remove NaN elementsdf_data = df_data.dropna(how="any", axis=0)labels = df_data["income_bracket"].apply(lambda x: ">50K" in x).astype(int)return tf.estimator.inputs.pandas_input_fn(x=df_data,y=labels,batch_size=100,num_epochs=num_epochs,shuffle=shuffle,num_threads=5)

模型的选择和工程特征

选择和制作右侧的特征列是学习有效模型的关键。甲特征柱可以是在原来的数据帧(让我们称它们为原料的列中的任一个基本特征的列)的基础上在一个或多个碱基列(我们称它们限定一些转化或创建任何新列得出的特征列)。基本上,“特征列”是可用于预测目标标签的任何原始或派生变量的抽象概念。

基本分类特征列

要定义分类功能的功能列,我们可以CategoricalColumn使用tf.feature_column API 创建一个 。如果您知道列的所有可能的特征值的集合,并且只有其中的几个可以使用categorical_column_with_vocabulary_list。列表中的每个键将从0开始分配一个自动增量ID。例如,对于gender 列,我们可以通过执行以下操作将特征字符串“Female”分配给整数ID为0,将“Male”分配给1。

gender = tf.feature_column.categorical_column_with_vocabulary_list("gender", ["Female", "Male"])

如果我们不提前知道一组可能的价值呢?不是问题 我们可以用

categorical_column_with_hash_bucket

occupation = tf.feature_column.categorical_column_with_hash_bucket("occupation", hash_bucket_size=1000)

将会发生的是,occupation 在训练中遇到这些特征列时,每个可能的值将被哈希到一个整数ID。见下面的示例图:

ID 特征
...  
9 "Machine-op-inspct"
...  
103 "Farming-fishing"
...  
375 "Protective-serv"
...

无论我们选择哪种方式定义一个SparseColumn,每个特征字符串将通过查找固定映射或散列来映射到整数ID。请注意,散列碰撞是可能的,但可能不会显着影响模型质量。在引擎盖下,LinearModel该类负责管理映射和创建tf.Variable以存储每个功能ID的模型参数(也称为模型权重)。模型参数将通过后面的模型训练过程学习。

我们将采取类似的技巧来定义其他分类功能:

education = tf.feature_column.categorical_column_with_vocabulary_list("education", ["Bachelors", "HS-grad", "11th", "Masters", "9th","Some-college", "Assoc-acdm", "Assoc-voc", "7th-8th","Doctorate", "Prof-school", "5th-6th", "10th", "1st-4th","Preschool", "12th"])
marital_status = tf.feature_column.categorical_column_with_vocabulary_list("marital_status", ["Married-civ-spouse", "Divorced", "Married-spouse-absent","Never-married", "Separated", "Married-AF-spouse", "Widowed"])
relationship = tf.feature_column.categorical_column_with_vocabulary_list("relationship", ["Husband", "Not-in-family", "Wife", "Own-child", "Unmarried","Other-relative"])
workclass = tf.feature_column.categorical_column_with_vocabulary_list("workclass", ["Self-emp-not-inc", "Private", "State-gov", "Federal-gov","Local-gov", "?", "Self-emp-inc", "Without-pay", "Never-worked"])
native_country = tf.feature_column.categorical_column_with_hash_bucket("native_country", hash_bucket_size=1000)

基本连续特征列

类似地,我们可以NumericColumn为模型中要使用的每个连续特征列定义一个

age = tf.feature_column.numeric_column("age")
education_num = tf.feature_column.numeric_column("education_num")
capital_gain = tf.feature_column.numeric_column("capital_gain")
capital_loss = tf.feature_column.numeric_column("capital_loss")
hours_per_week = tf.feature_column.numeric_column("hours_per_week")

通过Bucketization进行连续分类

有时,连续特征与标签之间的关系不是线性的。作为一个假设的例子,一个人的收入可能随着职业生涯的早期阶段的年龄而增长,那么增长可能会在某个时候慢一些,最后退休后的收入就会下降。在这种情况下,将raw age作为实值特征列可能不是一个好的选择,因为模型只能学习三种情况之一:

  1. 随着年龄的增长,收入总是以一定的速度增长(正相关),
  2. 收入总是随着年龄的增长而下降(负相关),或
  3. 无论什么年龄(无相关性),收入保持不变

如果我们想要分别了解收入和每个年龄组之间的细粒度关联,我们可以利用桶化。Bucketization是将连续特征的整个范围划分成一组连续的仓/桶的过程,然后根据该值所在的桶将原始数值特征转换为桶ID(作为分类特征)。因此,我们可以定义一个bucketized_column以上age为:

age_buckets = tf.feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])

哪里boundaries是桶边界的列表。在这种情况下,有10个边界,导致11个年龄组的桶(从17岁及以下,18-24,25-29,...,到65岁以上)。

用交叉列相交多个列

单独使用每个基本特征列可能不足以解释数据。例如,不同职业的教育与标签(赚取> 50,000美元)的相关性可能会有所不同。因此,如果我们只学了一个模型的权重education="Bachelors"education="Masters",我们就无法捕捉到每一个教育,职业组合(例如区分education="Bachelors" AND occupation="Exec-managerial" 和education="Bachelors" AND occupation="Craft-repair")。要了解不同功能组合之间的差异,我们可以向模型添加交叉的特征列

education_x_occupation = tf.feature_column.crossed_column(["education", "occupation"], hash_bucket_size=1000)

我们也可以创建CrossedColumn超过两列。每个构成列可以是基本特征列,分类(SparseColumn),分段实值特征列(BucketizedColumn)或甚至另一个CrossColumn。这里有一个例子:

age_buckets_x_education_x_occupation = tf.feature_column.crossed_column([age_buckets, "education", "occupation"], hash_bucket_size=1000)

定义逻辑回归模型

在处理输入数据并定义所有特征列之后,我们现在可以将它们全部放在一起,构建一个Logistic回归模型。在上一节中,我们看到了几种类型的基础和派生的功能列,其中包括:

  • CategoricalColumn
  • NumericColumn
  • BucketizedColumn
  • CrossedColumn

所有这些都是抽象FeatureColumn类的子类,并且可以添加到feature_columns模型的字段中:

base_columns = [gender, native_country, education, occupation, workclass, relationship,age_buckets,
]
crossed_columns = [tf.feature_column.crossed_column(["education", "occupation"], hash_bucket_size=1000),tf.feature_column.crossed_column([age_buckets, "education", "occupation"], hash_bucket_size=1000),tf.feature_column.crossed_column(["native_country", "occupation"], hash_bucket_size=1000)
]model_dir = tempfile.mkdtemp()
m = tf.estimator.LinearClassifier(model_dir=model_dir, feature_columns=base_columns + crossed_columns)

该模型还自动学习一个偏离项,它控制预测,而不需要观察任何特征(参见“逻辑回归如何运作”以获得更多的解释)。学习的模型文件将被存储model_dir

培训和评估我们的模型

在将所有功能添加到模型之后,现在来看看如何实际训练模型。训练一个模型只是一个使用tf.estimator API的单行:

# set num_epochs to None to get infinite stream of data.
m.train(input_fn=input_fn(train_file_name, num_epochs=None, shuffle=True),steps=train_steps)

在模型训练后,我们可以评估我们的模型在预测保持数据的标签方面有多好:

results = m.evaluate(input_fn=input_fn(test_file_name, num_epochs=1, shuffle=False),steps=None)
print("model directory = %s" % model_dir)
for key in sorted(results):print("%s: %s" % (key, results[key]))

输出的第一行应该是这样accuracy: 0.83557522,这意味着精度是83.6%。随意尝试更多的功能和变革,看看你能做得更好!

如果您希望看到一个有效的端对端示例,您可以下载我们的 示例代码。并设置model_type标志wide

添加正则化以防止过度配合

正则化是一种用于避免过度拟合的技术。当您的模型对其进行培训的数据执行情况良好时,会发生过度拟合,但对于模型以前未见过的测试数据(如实时流量)更糟。通常,当模型过于复杂时,通常发生过拟合,例如相对于观察到的训练数据的数量具有太多的参数。正则化允许您控制您的模型的复杂性,并使模型更可概括为看不见的数据。

在线性模型库中,您可以将L1和L2正则化添加到模型中:

m = tf.estimator.LinearClassifier(model_dir=model_dir, feature_columns=base_columns + crossed_columns,optimizer=tf.train.FtrlOptimizer(learning_rate=0.1,l1_regularization_strength=1.0,l2_regularization_strength=1.0),model_dir=model_dir)

L1和L2正则化之间的一个重要区别在于L1正则化趋向于使模型权重保持为零,创建较为稀疏的模型,而L2正则化也试图使模型权重接近零但不一定为零。因此,如果增加L1正则化的强度,则您将具有较小的模型大小,因为许多模型权重将为零。当特征空间非常大但稀疏时,并且当存在阻止您提供太大模型的资源约束时,这通常是希望的。

在实践中,您应该尝试L1,L2正则化强度的各种组合,并找到最佳控制过拟合的最佳参数,并为您提供所需的模型大小。

转载于:https://www.cnblogs.com/yinghuali/p/7750273.html

[教程10]TensorFlow线性模型教程相关推荐

  1. Tensorflow快餐教程(1) - 30行代码搞定手写识别

    摘要: Tensorflow入门教程1 去年买了几本讲tensorflow的书,结果今年看的时候发现有些样例代码所用的API已经过时了.看来自己维护一个保持更新的Tensorflow的教程还是有意义的 ...

  2. Tensorflow快餐教程(12) - 用机器写莎士比亚的戏剧

    高层框架:TFLearn和Keras 上一节我们学习了Tensorflow的高层API封装,可以通过简单的几步就生成一个DNN分类器来解决MNIST手写识别问题. 尽管Tensorflow也在不断推进 ...

  3. TensorFlow Eager 教程(转)

    TensorFlow Eager 教程(转) ApacheCN_飞龙 0.3 2018.07.25 22:41* 字数 9550 TensorFlow Eager 教程 来源:madalinabuza ...

  4. TensorFlow Eager 教程

    TensorFlow Eager 教程 来源:madalinabuzau/tensorflow-eager-tutorials 译者:飞龙 协议:CC BY-NC-SA 4.0 一.如何使用 Tens ...

  5. TensorFlow入门教程(1)安装、基础、Tensorboard

    TensorFlow入门教程 本教程适合人群: - 会些python但不是特别精通 - 机器学习的初学者 本教程预计耗时: - 2-3小时 本教程预计效果: - 掌握TensorFlow的基础操作 - ...

  6. 深度学习教程(10) | 卷积神经网络解读(吴恩达·完整版)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/35 本文地址:http://www.showmeai.tech/article-det ...

  7. 全网唯一一套labview深度学习教程:tensorflow+目标检测:龙哥教你学视觉—LabVIEW深度学习教程

    全网唯一一套labview深度学习教程:tensorflow+目标检测:龙哥教你学视觉-LabVIEW深度学习教程 一.知识背景: 随着自动化技术的快速发展,在工业生产中很多需要人工操作的环节逐渐转由 ...

  8. TensorFlow入门教程:1:安装和第一个例子程序

    TensorFlow™ 是Google开源的一个采用数据流图用于数值计算的开源库.截止到目前为止在github上已经获得超过6万个Star,已经成为深度学习和机器学习方面最为受欢迎的项目,炙手可热.这 ...

  9. tensorflow入门教程(三十四)疲劳检测之开眼闭眼识别

    # #作者:韦访 #博客:https://blog.csdn.net/rookie_wei #微信:1007895847 #添加微信的备注一下是CSDN的 #欢迎大家一起学习 # ------韦访 2 ...

最新文章

  1. 三藏一面:为什么要用 NoSQL
  2. 清空SQL Server日志
  3. visual c++出错:link问题
  4. Pycharm2018最新激活方式
  5. local sandbox getBootstrapScriptPath
  6. 语言程序设计第4版黄洪艺_谭浩强《C程序设计》第4版网授精讲班【教材精讲+考研真题串讲】视频网课讲义课程资料...
  7. 都说“先卖人,后卖货”,或者说要想卖货,先卖人
  8. 48.本地Hyper-V虚拟机的异地(Azure)容灾(下)
  9. 上一家单位离职的原因_员工离职再入职,专项附加扣除该如何变更?
  10. 集成计算引擎在大型企业绩效考核系统的应用方案
  11. https阿里云证书购买与apache环境配置
  12. PostgreSQL之Foreign Data Wrappers使用指南
  13. matlab求车辆调度问题的代码,车间作业调度问题遗传算法_matlab源代码
  14. React生命周期详解
  15. Validation进行参数校验
  16. 如何写出如散文般的代码――《代码整洁之道》读书笔记(Ch1-Ch3)
  17. 信息搜集:网络空间搜索引擎(Shodan)语法及API应用案例
  18. weixin-java-pay实现APP微信支付与退款
  19. 苹果 iPhone4 ios7.0 无法下载应用程序 此时无法
  20. ChatGPT神器免费使用,告别昂贵低效工具

热门文章

  1. 会比Kubernetes和无服务器更有前途的是Istio
  2. 易迅网接入微信支付,为消费者提供购物体验
  3. ubuntu16.04 LTS安装ROS Kinetic详细步骤(包含出现的错误)
  4. C++11后的STL算法
  5. 我们欺骗了活动主办方
  6. import 和 require
  7. VUE中IE浏览器下载文件的解决方案
  8. 游戏行业回暖,但距离春天还有一段距离
  9. centos系统性能监控常用软件介绍
  10. python 3标准库道格_《PYTHON 3标准库 [美] 道格·赫尔曼》[美] 道格·赫尔曼(Doug Hellmann)著【摘要 书评 在线阅读】-苏宁易购图书...