登录  /  注册
博主信息
博文 352
粉丝 0
评论 0
访问量 59052
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
人工智能产品测试 | 特征的概念:离散与连续
霍格沃兹测开学社
原创
113人浏览过

什么是特征

机器学习就是一个更加强大的大脑,一个更加强大的专家系统。在这个系统中存在大规模的规则来满足用户的需要。而在人工智能领域中这些规则中的主体就叫做特征,这些特征构成了人工智能最主要的组成部分。

比如还是信用卡反欺诈这个场景,交易城市是一个特征,交易金额是一个特征,交易时间还是一个特征,人工智能的流程就是用户需要筛选可能会对识别结果产生重要影响的特征,然后机器学习则会按照算法去训练出每个特征所占的权重。

离散特征与连续特征

  • 离散特征:职业,爱好,工种等可枚举的字段称为离散特征,如上图中title通常会被当场一个离散特征处理。
  • 连续特征:薪水,房价等这些不可枚举的具体的数字的字段称为连续特征,如上图中的薪水通常会被当成是连续特征处理。

离散特征与连续特征的区别

离散特征与连续特征最大的区别在于算法在计算对应字段的时候如何处理,对于离散特征来说算法会将每一个唯一的值作为一个独立的特征,比如我们有用户表, 其中职业这个字段中我们有100种职业,也就是说这张表不论有多少行,职业这个字段的取值就是这100个职业中的一个。

而对于算法来说每一个职业就是一个独立的特征。老师是一个特征,学生是一个特征,程序员、环卫工人、产品经理、项目经理等等这些都是独立的特征。也就是说对于这张表,不论有多少行,算法针对职业这一字段提取出来的特征就是固定的这100个。

而连续特征则完全不同,它是一个数字的数字,算法会把它当成一个独立的特征,也就是当算法把一个字段提取成为连续特征后,不管这张表有多少行,这个字段固定就只有1个特征被提出来。只不过这个特征值是会变动的。

但是一个字段是否是连续特征或者离散特征并不是固定的,职业这样的字段可以被算法进行连续化处理,像薪水这样的字段也可以被算法进行离散化处理。并不是一成不变的。

比如在spark ml中可以将连续特征进行二值化或者分桶来达到转换成离散特征的目的:

  1. # 连续特征二值化
  2. from pyspark.sql import SparkSession
  3. from pyspark.ml.feature import Binarizer
  4. spark = SparkSession.builder.config("spark.Driver.host", "192.168.1.4") \
  5. .config("spark.ui.showConsoleProgress", "false") \
  6. .appName("Binarize").master("local[*]").getOrCreate()
  7. data = spark.createDataFrame([
  8. (0.1,),
  9. (2.3,),
  10. (1.1,),
  11. (4.2,),
  12. (2.5,),
  13. (6.8,),
  14. ], ["values"])
  15. data.show()
  16. binarizer = Binarizer(threshold=2.4, inputCol="values", outputCol="features")
  17. res = binarizer.transform(data)
  18. res.show()
  19. +------+--------+
  20. |values|features|
  21. +------+--------+
  22. | 0.1| 0.0|
  23. | 2.3| 0.0|
  24. | 1.1| 0.0|
  25. | 4.2| 1.0|
  26. | 2.5| 1.0|
  27. | 6.8| 1.0|
  28. +------+--------+
  1. # 连续特征分桶离散化
  2. from pyspark.sql import SparkSession
  3. from pyspark.ml.feature import Bucketizer
  4. spark = SparkSession\
  5. .builder\
  6. .appName("BucketizerExample")\
  7. .getOrCreate()
  8. splits = [-float("inf"), -0.5, 0.0, 0.5, float("inf")]
  9. data = [(-999.9,), (-0.5,), (-0.3,), (0.0,), (0.2,), (999.9,)]
  10. dataFrame = spark.createDataFrame(data, ["features"])
  11. # splits:区间边界,outputCol:分桶后的特征名
  12. bucketizer = Bucketizer(splits=splits, inputCol="features", outputCol="bucketedFeatures")
  13. # Transform original data into its bucket index.
  14. bucketedData = bucketizer.transform(dataFrame)
  15. print("Bucketizer output with %d buckets" % (len(bucketizer.getSplits())-1))
  16. bucketedData.show()
  17. # 运行结果
  18. |features|bucketedFeatures|
  19. +--------+----------------+
  20. | -999.9| 0.0|
  21. | -0.5| 1.0|
  22. | -0.3| 1.0|
  23. | 0.0| 2.0|
  24. | 0.2| 2.0|
  25. | 999.9| 3.0|
  26. +--------+----------------+

时序特征

普通的特征都是在一行内进行提取,而在真实的场景中,仅仅是这样单行的特征是无法满足业务的需要的。在建模过程中,用户往往需要统计更加复杂的特征。

比如建模工程师会觉得用户在过去一周内的单笔最大消费额是非常有用的特征,而这样的特征明显是需要从很多行的数据中进行计算。而这样的特征一般被称作多行特征或者时序特征,因为这类特征往往都是在计算一段时间内的数据特性,所以往往被叫做时序特征。

在一些支持sql的计算框架和数据库中,窗口函数往往会被用来提取时序特征。

比如在spark中可以这样编写代码:

  1. from pyspark import SparkContext, SparkConf, SQLContext
  2. from pyspark.sql import functions as F
  3. from pyspark.sql.functions import udf
  4. from pyspark.sql.window import Window
  5. conf = SparkConf().setMaster("local").setAppName("My App")
  6. sc = SparkContext(conf=conf)
  7. sqlContext = SQLContext(sc)
  8. dicts = [['frank','男', 16, '程序员', 3600], ['alex','女', 26, '项目经理', 3000], ['frank','男', 16, '程序员', 2600]]
  9. rdd = sc.parallelize(dicts, 3)
  10. dataf = sqlContext.createDataFrame(rdd, ['name','gender', 'age', 'title', 'price'])
  11. windowSpec = Window.partitionBy(dataf.gender)
  12. windowSpec = windowSpec.orderBy(dataf.age)
  13. windowSpec = windowSpec.rowsBetween(Window.unboundedPreceding, Window.currentRow)
  14. dataf.withColumn('max_price', F.max(dataf.price).over(windowSpec)).show()
  15. # 运行结果
  16. +-----+------+---+--------+-----+---------+
  17. | name|gender|age| title|price|max_price|
  18. +-----+------+---+--------+-----+---------+
  19. |frank| 男| 16| 程序员| 3600| 3600|
  20. |frank| 男| 16| 程序员| 2600| 3600|
  21. | alex| 女| 26|项目经理| 3000| 3000|
  22. +-----+------+---+--------+-----+---------+
  • partitionBy:根据哪个字段分组
  • orderBy:根据哪个字段进行排序
  • rowsBetween:取哪些行进行计算。unboundedPreceding代表当前行之前的无限的行数,currentRow代表当前行。例如,要选择当前行的前一行和后一行。可以写为rowsBetween(-1, 1)
本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!
全部评论 文明上网理性发言,请遵守新闻评论服务协议
0条评论
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号

  • 登录PHP中文网,和优秀的人一起学习!
    全站2000+教程免费学