精华内容
下载资源
问答
  • 叶季节变化的计算方法
  • 目的在试验基础上对建筑用顶柱的受力性能进行有限元分析,建立稳定承载力计算方法。方法通过有限元软件对支撑高度为 2400~3400 mm的建筑用顶柱进行了受力性能分析,将分析得到的数据和现有规范稳定系数计算公式...
  • 正如我的另外一篇文章种所描述的方法: ...其他标签统计某某行为最近三个的数据可能通过对数据进行筛选计算,可以降低统计的数据量,无非是多几个脚本而已。但是这里必须从基表中统计客户行为,数据量相当可观。 ...

    正如我的另外一篇文章种所描述的方法:

    Hive中如何统计用户三个月或者以上的行为数据

    此处,是我在做客户画像标签开发的过程中,遇到的一个非常严峻的问题。其他标签统计某某行为最近三个月的数据可能通过对数据进行筛选计算,可以降低统计的数据量,无非是多几个脚本而已。但是这里必须从基表中统计客户行为,数据量相当可观。

    展开全文
  • 最近有一个需求,统计新老用户,日,周月活;这里日,当然了周月活就是一个count(distinct(guid))语句。 #!/usr/bin/python # -*- coding:utf-8 -*- # hive更新历史用户表,日常查询,保存到MySQL ...

    Hive系列文章

    1. Hive表的基本操作
    2. Hive中的集合数据类型
    3. Hive动态分区详解
    4. hive中orc格式表的数据导入
    5. Java通过jdbc连接hive
    6. 通过HiveServer2访问Hive
    7. SpringBoot连接Hive实现自助取数
    8. hive关联hbase表
    9. Hive udf 使用方法
    10. Hive基于UDF进行文本分词
    11. Hive窗口函数row number的用法
    12. 数据仓库之拉链表

    最近有一个需求,统计每天的新老用户,日活,周活,月活。
    我们每天的增量数据会加入到hive历史数据表中,包含用户访问网站的一些信息,字段有很多,包括用户唯一标识guid。
    当然了日活,周活,月活就是一个count(distinct(guid))语句,非常常用的sql。

    但是这里的问题是:

    A:每天的新老用户应该怎么统计呢?
    B:这还不简单,判断用户guid是否存在与历史库guid中嘛?
    A:历史数据几十个T,大概一百亿行,你要每天将当日数据(2~3亿行)与历史数据几亿行进行join判断?
    B:额,这个,这个,好像不行哦!

    是的,历史数据里面是用户网站访问行为,同一个用户在同一天,不同的天都有可能出现,guid在历史表中会有多次。如果直接join,性能很差,实际上是做了很多不必要的工作。

    解决方案:

    维护一张用户表,里面有4列:guid, starttime, endtime, num,分别是用户的guid,第一次访问时间,最后一次访问时间,访问天数;
    从某个状态开始,历史表中guid是唯一的;
    当天数据去重后,与历史库join,如果guid在历史库出现过,则将endtime更新为当天时间,num加一;
    否则,这是一个新用户,插入历史库,starttime, endtime都为当天时间,num初始值为1。

    维护了这么一张用户表后,接下来就可以写hql统计业务了,计算当天新老用户时,只需要与这个历史库进行join就行了(目前为止4千万),当日guid去重后是1千多万,这样就是4千万1千万的join了,与开始4千万100亿的join,性能会有巨大提升。

    hive历史表的设计与hive相关配置
    可以看到这里hive历史表history_helper需要频繁修改,hive表支持数据修改需要在${HIVE_HOME}/conf/hive-site.xml中添加事务支持:

    <property>
        <name>hive.support.concurrency</name>
        <value>true</value>
    </property>
    <property>
        <name>hive.exec.dynamic.partition.mode</name>
        <value>nonstrict</value>
    </property>
    <property>
        <name>hive.txn.manager</name>
        <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
    </property>
    <property>
        <name>hive.compactor.initiator.on</name>
        <value>true</value>
    </property>
    <property>
        <name>hive.compactor.worker.threads</name>
        <value>1</value>
    </property>
    

    为了提高查询速度,hive历史表与增量表这里都分桶,hive-xite.xml配置:

    <property>
        <name>hive.enforce.bucketing</name>
        <value>true</value>
    </property>
    

    为了提高reduce并行度,也设置一下:

    set mapred.reduce.tasks = 50;
    

    这个最好在hive命令行配置,表明只在当前程序使用该配置,就不要配置配置文件了。
    历史库建表语句:

    create external table if not exists hm2.history_helper
    (
      guid string,
      starttime string,
      endtime string,
      num int
    )
    clustered by(guid) into 50 buckets
    stored as orc TBLPROPERTIES ("transactional"="true");
    

    当天增量表,保存去重后的guid,建表语句:

    create table if not exists hm2.daily_helper
    (
      guid string,
      dt string
    )
    clustered by(guid) into 50 buckets
    stored as orc TBLPROPERTIES ("transactional"="true");
    

    思路

    由于这种需要写成定时模式,所以这里用python脚本来实现,将hive查询结果保存到本地文件result.txt,然后python读取result.txt,连接数据库,保存当天的查询结果。

    代码

    helper.py

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    
    # hive更新历史用户表,日常查询,保存到MySQL
    
    import sys
    import datetime
    import commands
    import MySQLdb
    
    # 获取起始中间所有日期
    def getDays(starttime,endtime,regx):
    	datestart=datetime.datetime.strptime(starttime,regx)
    	dateend=datetime.datetime.strptime(endtime,regx)
    	days = []
    	while datestart<=dateend:
    		days.append(datestart.strftime(regx))
    		datestart+=datetime.timedelta(days=1)
    	return days
    
    # 获得指定时间的前 n 天的年、月、日,n取负数往前,否则往后
    def getExacYes(day, regx, n):
    	return (datetime.datetime.strptime(day,regx) + datetime.timedelta(days=n)).strftime(regx)
    
    # 获得距离现在天数的年、月、日,n 取值正负含义同上,昨天就是getYes(regx,-1)
    def getYes(regx, n):
    	now_time = datetime.datetime.now()
    	yes_time = now_time + datetime.timedelta(days=n)
    	yes_time_nyr = yes_time.strftime(regx)
    	return yes_time_nyr
    
    # 执行hive命令
    def execHive(cmd):
    	print cmd
    	res = commands.getstatusoutput(cmd)
    	return res
    
    # 获得当前是星期几
    def getWeek(regx):
    	now_time = datetime.datetime.now()
    	week = now_time.strftime(regx)
    	return week
    
    # 格式化日期,加上双引号
    def formatDate(day):
    	return "\"" + day + "\""
    
    # 数据保存到mysql
    def insertMysql(dt, path, tbName, regx):
    	# new, dayAll, stay
    	values = []
    	with open(path) as file:
    		line = file.readline()
    		while line:
    			values.append(line.strip())
    			line = file.readline()
    	dayAll = int(values[1])
    	new = float(values[0])/dayAll
    	old = 1 - new
    
    	# 获取数据库连接
    	conn = MySQLdb.connect("0.0.0.0", "statistic", "123456", "statistic")
    	# 获取游标
    	cursor = conn.cursor()
    
    	# 查询昨天的用户人数
    	yesDay = getExacYes(dt, regx, -1)
    	sql = 'select dayAll from %s where dt = %s'%(tbName, formatDate(yesDay))
    	try:
    		cursor.execute(sql)
    	except Exception as e:
    		print e
    
    	yesAll = int(cursor.fetchall()[0][0])
    	stay = float(values[2]) / yesAll
    	print stay
    	# 获取游标
    	cursor2 = conn.cursor()
    	sql = 'insert into  %s\
    	values("%s",%f,%f,%f,%d)'%(tbName, dt, new, old, stay, dayAll)
    	print sql
    	try:
    		cursor2.execute(sql)
    		conn.commit()
    	except:
    		conn.rollback()
    	finally:
    		conn.close()
    
    # 初始化,删除临时表,并且创建
    def init():
    	# 设置分桶环境
    	cmd = 'source /etc/profile;hive -e \'set hive.enforce.bucketing = true;set mapred.reduce.tasks = 50;\''
    	(status,result) = execHive(cmd)
    	# 清除当天的临时表,结果保存
    	cmd = 'source /etc/profile;hive -e \'drop table hm2.daily_helper;\''
    	(status,result) = execHive(cmd)
    	if status == 0:
    		print '%s昨天临时表删除完毕...'%(day)
    	else:
    		print result
    		sys.exit(1)
    	cmd = 'source /etc/profile;hive -e \'create table if not exists hm2.daily_helper\
    	(\
    	guid string,\
    	dt string\
    	)\
    	clustered by(guid) into 50 buckets \
    	stored as orc TBLPROPERTIES ("transactional"="true");\''
    	(status,result) = execHive(cmd)
    	if status == 0:
    		print '%s临时表创建完毕...'%(day)
    	else:
    		print result
    		sys.exit(1)
    
    # 主函数入口
    if __name__ == '__main__':
    	regx = '%Y-%m-%d'
    	resultPath = '/home/hadoop/statistic/flash/helper/result.txt'
    	days = getDays('2018-07-01','2018-07-20',regx)
    	tbName = 'statistic_flash_dailyActive_helper'
    	for day in days:
    		init()
    		# 当天数据去重后保存到临时表daily_helper
    		cmd = 'source /etc/profile;hive -e \'insert into hm2.daily_helper select distinct(guid),dt from hm2.helper \
    		where dt = "%s" and guid is not null;\''%(day)
    		print '%s数据正在导入临时表...'%(day)
    		(status,result) = execHive(cmd)
    		if status == 0:
    			print '%s数据导入临时表完毕...'%(day)
    		else:
    			print result
    			sys.exit(1)
    		# guid存在则更新 endtime 与 num
    		cmd = 'source /etc/profile;hive -e \'update hm2.history_helper set endtime = "%s",num = num + 1 \
    		where guid in (select guid from hm2.daily_helper);\''%(day)
    		print '正在更新endtime 与 num...'
    		(status,result) = execHive(cmd)
    		if status == 0:
    			print '%s history_helper数据更新完毕'%(day)
    		else :
    			print result
    			sys.exit(1)
    		# 当天新用户
    		cmd = 'source /etc/profile;hive -e \'select count(1) from hm2.daily_helper \
    		where guid not in (select guid from hm2.history_helper);\' > %s'%(resultPath)
    		(status,result) = execHive(cmd)
    		if status != 0:
    			print result
    			sys.exit(1)
    		# 不存在插入
    		cmd = 'source /etc/profile;hive -e \'insert into hm2.history_helper\
    		select daily.guid,dt,dt,1 from hm2.daily_helper daily\
    		where daily.guid not in (select guid from hm2.history_helper where guid is not null);\''
    		print '正在插入数据到history_helper表...'
    		(status,result) = execHive(cmd)
    		if status == 0:
    			print '%s数据插入hm2.history_helper表完成'%(day)
    		else:
    			print result
    			sys.exit(1)
    		# 当天总人数
    		cmd = 'source /etc/profile;hive -e \'select count(1) from hm2.daily_helper;\' >> %s'%(resultPath)
    		(status,result) = execHive(cmd)
    		if status != 0:
    			print result
    			sys.exit(1)
    		# 次日活跃留存
    		cmd = 'source /etc/profile;hive -e \'select count(1) from\
    		(select guid from hm2.helper where dt = "%s" group by guid) yes\
    		inner join\
    		(select guid from hm2.helper where dt = "%s" group by guid) today\
    		where yes.guid = today.guid;\' >> %s'%(getExacYes(day, regx, -1), day, resultPath)
    		(status,result) = execHive(cmd)
    		if status != 0:
    			print result
    			sys.exit(1)
    		# 结果保存到mysql
    		insertMysql(day, resultPath, tbName, regx)
    		print '=========================%s hive 查询完毕,结果保存数据到mysql完成=============================='%(day)
    
    

    这是在处理历史数据,然后就是每天定时处理了,在linux crontab里加个定时器任务就好了。


    分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!
    点击浏览教程
    微信扫一扫关注我

    展开全文
  • 行业资料-交通装置-一种截干后立木马褂木树干3D可视化及材积计算方法.zip
  • 所以 HyperLogLog 是否适合在比如统计日活月活此类的对精度要不不高的场景。 这是一个很惊人的结果,以如此小的内存来记录如此大数量级的数据基数。下面我们就带大家来深入了解一下 HyperLogLog 的使用,基础原理,...

    点击上方"程序员历小冰",选择“置顶或者星标”

       你的关注意义重大!

    640?wx_fmt=jpeg

    HyperLogLog 是一种概率数据结构,用来估算数据的基数。数据集可以是网站访客的 IP 地址,E-mail 邮箱或者用户 ID。

    基数就是指一个集合中不同值的数目,比如 a, b, c, d 的基数就是 4,a, b, c, d, a 的基数还是 4。虽然 a 出现两次,只会被计算一次。

    使用 Redis 统计集合的基数一般有三种方法,分别是使用 Redis 的 HashMap,BitMap 和 HyperLogLog。前两个数据结构在集合的数量级增长时,所消耗的内存会大大增加,但是 HyperLogLog 则不会。

    Redis 的 HyperLogLog 通过牺牲准确率来减少内存空间的消耗,只需要12K内存,在标准误差0.81%的前提下,能够统计2^64个数据。所以 HyperLogLog 是否适合在比如统计日活月活此类的对精度要不不高的场景。

    这是一个很惊人的结果,以如此小的内存来记录如此大数量级的数据基数。下面我们就带大家来深入了解一下 HyperLogLog 的使用,基础原理,源码实现和具体的试验数据分析。

    HyperLogLog 在 Redis 中的使用

    Redis 提供了 PFADD 、 PFCOUNT 和 PFMERGE 三个命令来供用户使用 HyperLogLog。

    PFADD 用于向 HyperLogLog 添加元素。

    &gt; PFADD visitors alice bob carol	
    (integer) 1	
    &gt; PFCOUNT visitors	
    (integer) 3

    如果 HyperLogLog 估计的近似基数在 PFADD 命令执行之后出现了变化, 那么命令返回 1 , 否则返回 0 。 如果命令执行时给定的键不存在, 那么程序将先创建一个空的 HyperLogLog 结构, 然后再执行命令。

    PFCOUNT 命令会给出 HyperLogLog 包含的近似基数。在计算出基数后, PFCOUNT 会将值存储在 HyperLogLog 中进行缓存,知道下次 PFADD 执行成功前,就都不需要再次进行基数的计算。

    PFMERGE 将多个 HyperLogLog 合并为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的并集基数。

    &gt; PFADD customers alice dan	
    (integer) 1	
    &gt; PFMERGE everyone visitors customers	
    OK	
    &gt; PFCOUNT everyone	
    (integer) 4

    内存消耗对比实验

    我们下面就来通过实验真实对比一下下面三种数据结构的内存消耗,HashMap、BitMap 和 HyperLogLog。

    我们首先使用 Lua 脚本向 Redis 对应的数据结构中插入一定数量的数,然后执行 bgsave 命令,最后使用 redis-rdb-tools 的 rdb 的命令查看各个键所占的内存大小。

    下面是 Lua 的脚本,不了解 Redis 执行 Lua 脚本的同学可以看一下我之前写的文章《基于Redis和Lua的分布式限流》

    local key = KEYS[1]	
    local size = tonumber(ARGV[1])	
    local method = tonumber(ARGV[2])	
    for i=1,size,1 do	
      if (method == 0)	
      then	
        redis.call('hset',key,i,1)	
      elseif (method == 1)	
      then	
        redis.call('pfadd',key, i)	
      else	
        redis.call('setbit', key, i, 1)	
      end	
    end

    我们在通过 redis-cli 的 script load 命令将 Lua 脚本加载到 Redis 中,然后使用 evalsha 命令分别向 HashMap、HyperLogLog 和 BitMap 三种数据结构中插入了一千万个数,然后使用 rdb 命令查看各个结构内存消耗。

    [root@VM_0_11_centos ~]# redis-cli -a 082203 script load "$(cat HyperLogLog.lua)"	
    "6255c6d0a1f32349f59fd2c8711e93f2fbc7ecf8"	
    [root@VM_0_11_centos ~]# redis-cli -a 082203 evalsha 6255c6d0a1f32349f59fd2c8711e93f2fbc7ecf8 1 hashmap 10000000 0	
    (nil)	
    [root@VM_0_11_centos ~]# redis-cli -a 082203 evalsha 6255c6d0a1f32349f59fd2c8711e93f2fbc7ecf8 1 hyperloglog 10000000 1	
    (nil)	
    [root@VM_0_11_centos ~]# redis-cli -a 082203 evalsha 6255c6d0a1f32349f59fd2c8711e93f2fbc7ecf8 1 bitmap 10000000 2	
    (nil)	
    [root@VM_0_11_centos ~]# rdb -c memory dump.rdb 	
    database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry	
    0,string,bitmap,1310768,string,1250001,1250001,	
    0,string,hyperloglog,14392,string,12304,12304,	
    0,hash,hashmap,441326740,hashtable,10000000,8,

    我们进行了两轮实验,分别插入一万数字和一千万数字,三种数据结构消耗的内存统计如下所示。

    640?wx_fmt=png

    从表中可以明显看出,一万数量级时 BitMap 消耗内存最小, 一千万数量级时 HyperLogLog 消耗内存最小,但是总体来看,HyperLogLog 消耗的内存都是 14392 字节,可见 HyperLogLog 在内存消耗方面有自己的独到之处。

    基本原理

    HyperLogLog 是一种概率数据结构,它使用概率算法来统计集合的近似基数。而它算法的最本源则是伯努利过程。

    伯努利过程就是一个抛硬币实验的过程。抛一枚正常硬币,落地可能是正面,也可能是反面,二者的概率都是 1/2 。伯努利过程就是一直抛硬币,直到落地时出现正面位置,并记录下抛掷次数k。比如说,抛一次硬币就出现正面了,此时 k 为 1; 第一次抛硬币是反面,则继续抛,直到第三次才出现正面,此时 k 为 3。

    对于 n 次伯努利过程,我们会得到 n 个出现正面的投掷次数值 k1, k2 ... kn , 其中这里的最大值是k_max。

    根据一顿数学推导,我们可以得出一个结论: 2^{k_ max} 来作为n的估计值。也就是说你可以根据最大投掷次数近似的推算出进行了几次伯努利过程。

    640?wx_fmt=png

    下面,我们就来讲解一下 HyperLogLog 是如何模拟伯努利过程,并最终统计集合基数的。

    HyperLogLog 在添加元素时,会通过Hash函数,将元素转为64位比特串,例如输入5,便转为101(省略前面的0,下同)。这些比特串就类似于一次抛硬币的伯努利过程。比特串中,0 代表了抛硬币落地是反面,1 代表抛硬币落地是正面,如果一个数据最终被转化了 10010000,那么从低位往高位看,我们可以认为,这串比特串可以代表一次伯努利过程,首次出现 1 的位数为5,就是抛了5次才出现正面。

    所以 HyperLogLog 的基本思想是利用集合中数字的比特串第一个 1 出现位置的最大值来预估整体基数,但是这种预估方法存在较大误差,为了改善误差情况,HyperLogLog中引入分桶平均的概念,计算 m 个桶的调和平均值。

    640?wx_fmt=png

    Redis 中 HyperLogLog 一共分了 2^14 个桶,也就是 16384 个桶。每个桶中是一个 6 bit 的数组,如下图所示。

    640?wx_fmt=png

    HyperLogLog 将上文所说的 64 位比特串的低 14 位单独拿出,它的值就对应桶的序号,然后将剩下 50 位中第一次出现 1 的位置值设置到桶中。50位中出现1的位置值最大为50,所以每个桶中的 6 位数组正好可以表示该值。

    在设置前,要设置进桶的值是否大于桶中的旧值,如果大于才进行设置,否则不进行设置。示例如下图所示。 640?wx_fmt=png

    此时为了性能考虑,是不会去统计当前的基数的,而是将 HyperLogLog 头的 card 属性中的标志位置为 1,表示下次进行 pfcount 操作的时候,当前的缓存值已经失效了,需要重新统计缓存值。在后面 pfcount 流程的时候,发现这个标记为失效,就会去重新统计新的基数,放入基数缓存。

    在计算近似基数时,就分别计算每个桶中的值,带入到上文将的 DV 公式中,进行调和平均和结果修正,就能得到估算的基数值。

    Redis 源码分析

    我们首先来看一下 HyperLogLog 对象的定义

    struct hllhdr {	
        char magic[4];      /* 魔法值 "HYLL" */	
        uint8_t encoding;   /* 密集结构或者稀疏结构 HLL_DENSE or HLL_SPARSE. */	
        uint8_t notused[3]; /* 保留位, 全为0. */	
        uint8_t card[8];    /* 基数大小的缓存 */	
        uint8_t registers[]; /* 数据字节数组 */	
    };

    HyperLogLog 对象中的 registers 数组就是桶,它有两种存储结构,分别为密集存储结构和稀疏存储结构,两种结构只涉及存储和桶的表现形式,从中我们可以看到 Redis 对节省内存极致地追求。

    640?wx_fmt=png

    我们先看相对简单的密集存储结构,它也是十分的简单明了,既然要有 2^14 个 6 bit的桶,那么我就真使用足够多的 uint8_t 字节去表示,只是此时会涉及到字节位置和桶的转换,因为字节有 8 位,而桶只需要 6 位。

    所以我们需要将桶的序号转换成对应的字节偏移量 offsetbytes 和其内部的位数偏移量 offsetbits。需要注意的是小端字节序,高位在右侧,需要进行倒转。

    当 offset_bits 小于等于2时,说明一个桶就在该字节内,只需要进行倒转就能得到桶的值。

    640?wx_fmt=png

    如果 offset_bits 大于 2 ,则说明一个桶分布在两个字节内,此时需要将两个字节的内容都进行倒置,然后再进行拼接得到桶的值,如下图所示。

    640?wx_fmt=png

    HyperLogLog 的稀疏存储结构是为了节约内存消耗,它不像密集存储模式一样,真正找了那么多个字节数组来表示2^14 个桶,而是使用特殊的字节结构来表达。

    640?wx_fmt=png

    Redis 为了方便表达稀疏存储,它将上面三种字节表示形式分别赋予了一条指令。

    • ZERO : 一字节,表示连续多少个桶计数为0,前两位为标志00,后6位表示有多少个桶,最大为64。

    • XZERO : 两个字节,表示连续多少个桶计数为0,前两位为标志01,后14位表示有多少个桶,最大为16384。

    • VAL : 一字节,表示连续多少个桶的计数为多少,前一位为标志1,四位表示连桶内计数,所以最大表示桶的计数为32。后两位表示连续多少个桶。

    640?wx_fmt=png

    所以,一个初始状态的 HyperLogLog 对象只需要2 字节,也就是一个 XZERO 来存储其数据,而不需要消耗12K 内存。当 HyperLogLog 插入了少数元素时,可以只使用少量的 XZERO、VAL 和 ZERO 进行表示,如下图所示。

    640?wx_fmt=png

    Redis从稀疏存储转换到密集存储的条件是:

    • 任意一个计数值从 32 变成 33,因为 VAL 指令已经无法容纳,它能表示的计数值最大为 32

    • 稀疏存储占用的总字节数超过 3000 字节,这个阈值可以通过 hllsparsemax_bytes 参数进行调整。

    具体 Redis 中的 HyperLogLog 源码由于涉及较多的位运算,这里就不多带大家学习了。大家对 HyperLogLog 有什么更好的理解或者问题都欢迎积极留言。

    -关注我

    640?wx_fmt=png

    -推荐阅读

    十二张图带你了解 Redis 的数据结构和对象系统

    基于Redis和Lua的分布式限流

    Redis Cluster 的数据分片机制

    参考

    - https://thoughtbot.com/blog/hyperloglogs-in-redis 

    - https://juejin.im/post/5c7fe7525188251ba53b0623

    - https://juejin.im/post/5bef9c706fb9a049c23204a3

    展开全文
  • 依据我国煤炭行业标准MT313-1992《液压支架立柱技术条件》,通过建立双伸缩立柱计算模型,研究了双伸缩立柱强度计算方法,以某360型双伸缩立柱为例,根据其结构特点,分别进行了全行程伸出加1.5倍额定轴向载荷时柱、...
  • 《机器学习实战》学习笔记(一):机器学习基础

    万次阅读 多人点赞 2019-08-19 17:01:32
    就是让计算机拥有学习的能力,也就是根据数据积累/计算经验等训练,获得分析解决问题的能力。】 【机器学习】《机器学习》周志华西瓜书读书笔记:第1章 - 绪论 中说到【正如我们根据过去的经验来判断明天的天气,...

    欢迎关注WX公众号:【程序员管小亮】

    【机器学习】《机器学习实战》读书笔记及代码 总目录

    GitHub代码地址:

    ——————————————————————————————————————————————————————

    本章内容

    • 机器学习的简单概述
    • 机器学习的主要任务
    • 学习机器学习的原因
    • Python语言的优势

    1、何谓机器学习

    什么是机器学习?书中举了一个很有意思的例子,我们来听一下,就当开胃菜了。

    最近我和一对夫妇共进晚餐,他们问我从事什么职业,我回应道:“机器学习。”妻子回头问丈夫:“亲爱的,什么是机器学习?”她的丈夫答道:“T-800型终结者。”在《终结者》系列电影中,T-800是人工智能技术的反面样板工程。
    在这里插入图片描述

    哈哈,承包了我一天的笑点,极其学习的概念到底是什么,这个我们在很多博客中都又提到过。

    如果你还是不清楚的话,实在是很过分了 😐,在深度学习大火的如今,机器学习也正是出现在人们视野中,现今,机器学习已应用于多个领域,远超出大多数人的想象,比如NLP,再比如推荐系统。
    在这里插入图片描述

    机器学习在日常生活中的应用,从左上角按照顺时针方向依次使用到的机器学习技术分别为:人脸识别、手写数字识别、垃圾邮件过滤和亚马逊公司的产品推荐。

    在本书中,给出的定义是:【简单地说,机器学习就是把无序的数据转换成有用的信息。】

    1. 传感器和海量数据

    虽然已从互联网上获取了大量的人为数据,但最近却涌现了更多的非人为数据。传感器技术并不时髦,已经发展了好多年的传统行业,但是如何将它们接入互联网这确实是新的挑战。地震预测是一个很好的例子,传感器手机了海量的数据,但是如何从这些数据中抽取出有价值的信息是一个非常值得研究的课题。

    1. 机器学习非常重要

    在过去的半个世纪里,发达国家的多数工作岗位都已从体力劳动转化为脑力劳动。过去的工作基本上都有明确的定义,类似于把物品从A处搬到B处,或者在这里打个洞,但是现在这类工作都在逐步消失。现今的情况具有很大的二义性,类似于“最大化利润”,“最小化风险”、“找到最好的市场策略”……诸如此类的任务要求都已成为常态。虽然可从互联网上获取到海量数据,但这并没有简化知识工人的工作难度。针对具体任务搞懂所有相关数据的意义所在,这正成为基本的技能要求。

    2、关键术语

    通过构建下面的鸟类分类系统,来对机器学习领域的常用术语进行一个总结。
    在这里插入图片描述
    机器学习的主要任务就是 分类。如何判断飞入进食器的鸟是不是象牙喙啄木鸟呢?(任何发现活的象牙喙啄木鸟的人都可以得到5万美元的奖励。)这个任务就是 分类,有很多机器学习算法非常善于 分类。本例中的类别就是鸟的物种,更具体地说,就是区分是否为象牙喙啄木鸟。

    我们决定使用某个机器学习算法进行 分类,首先需要做的是算法训练,即学习如何 分类。通常我们为算法输入大量已分类数据作为算法的 训练集训练集 是用于训练机器学习算法的数据样本集合,表1-1是包含六个训练样本的训练集,每个训练样本有4种 特征(体重、翼展、脚蹼和后背颜色)、一个 目标变量(种属),目标变量 是机器学习算法的预测结果,在 分类 算法中目标变量的类型通常是标称型的,而在 回归 算法中通常是连续型的。训练样本集必须确定知道 目标变量 的值,以便机器学习算法可以发现 特征目标变量 之间的关系。正如前文所述,这里的目标变量 是种属,也可以简化为标称型的数值。我们通常将分类问题中的目标变量称为 类别,并假定分类问题只存在有限个数的 类别

    为了测试机器学习算法的效果,通常使用两套独立的样本集:训练数据测试数据。当机器学习程序开始运行时,使用 训练样本集 作为算法的输入,训练完成之后输入 测试样本。输入 测试样本 时并不提供 测试样本目标变量,由程序决定样本属于哪个类别。比较 测试样本 预测的 目标变量 值与 实际样本类别 之间的差别,就可以得出算法的实际精确度。

    假定这个鸟类分类程序,经过测试满足精确度要求,是否我们就可以看到机器已经学会了如何区分不同的鸟类了呢?这部分工作称之为 知识表示,某些算法可以产生很容易理解的知识表示,而某些算法的知识表示也许只能为计算机所理解。知识表示 可以采用规则集的形式,也可以采用概率分布的形式,甚至可以是训练样本集中的一个实例。在某些场合中,人们可能并不想建立一个专家系统,而仅仅对机器学习算法获取的信息感兴趣。此时,采用何种方式 表示知识 就显得非常重要了。

    3、机器学习的主要任务

    分类问题的主要任务是将实例数据划分到合适的分类中;回归问题的主要任务是预测数值型数据。分类和回归属于监督学习,之所以称之为 监督学习,是因为这类算法必须知道预测什么,即 目标变量的分类信息,也就是label。

    监督学习 相对应的是 无监督学习,此时数据没有 类别信息,也不会给定 目标值。在 无监督学习 中,将数据集合分成由类似的对象组成的多个类的过程被称为 聚类;将寻找描述数据统计值的过程称之为 密度估计。此外,无监督学习 还可以减少数据特征的维度,以便我们可以使用二维或三维图形更加直观地展示数据信息。

    在这里插入图片描述

    4、如何选择合适的算法

    从上面的表格中可以看出,如果我们能确定算法的目的,想要算法完成何种任务,再加上确定需要分析或手机的数据是什么,就能大概确定哪一个算法更适合了。

    首先考虑使用机器学习算法的目的。

    • 如果想要预测目标变量的值,则可以选择监督学习算法
      • 如果目标变量是离散型,则可以选择分类器算法
      • 如果目标变量是连续型的数值,则需要选择回归算法
    • 如果不想预测目标变量的值,则可以选择无监督学习算法
      • 进一步分析是否需要将数据划分为离散的组。如果这是唯一的需求,则使用聚类算法;
      • 如果还需要估计数据与每个分组的相似程度,则需要使用密度估计算法。

    其次需要考虑的是数据问题。主要应该了解数据的以下特性:特征值是离散型变量还是连续型变量,特征值中是否存在缺失的值,何种原因造成缺失值,数据中是否存在异常值,某个特征发生的频率如何(是否罕见得如同海底捞针),等等。

    一般说来发现最好算法的关键环节是反复试错的迭代过程。

    5、开发机器学习应用程序的步骤

    机器学习算法开发应用程序通常遵循以下的步骤。
    (1) 收集数据
    (2) 准备输入数据
    (3) 分析输入数据
    (4) 训练算法
    (5) 测试算法
    (6) 使用算法

    6、Python 语言的优势

    选择Python作为实现机器学习算法的编程语言的原因:
    (1) Python的语法清晰;
    (2) 易于操作纯文本文件;
    (3) 使用广泛,存在大量的开发文档。

    7、NumPy 函数库基础

    机器学习算法涉及很多线性代数知识,因此在使用Python语言构造机器学习应用时,会经常使用NumPy函数库。如果不熟悉线性代数也不用着急,这里用到线性代数只是为了简化不同的数据点上执行的相同数学运算。将数据表示为矩阵形式,只需要执行简单的矩阵运算而不需要复杂的循环操作。

    8、总结

    尽管现在引起很多人的注意,但是机器学习算法其实还是一个专业的学科,很多人都是道听途说,仍然有很长的路要走。随着每天我们需要处理的数据在不断地增加,能够深入理解数据背后的真实含义,是数据驱动产业必须具备的基本技能。如果你想走这个方向,就要下定决心,走到黑,加油,共勉。

    下一章我们将介绍第一个分类算法——k-近邻算法。

    参考文章

    • 《机器学习实战》
    展开全文
  • 工程造价接收费标准与计费方法计算公式(2021年版).pdf
  • HyperLogLog 是一种概率数据结构,用来估算数据的基数。...虽然 a 出现两次,只会被计算一次。 精确的计算数据集的基数需要消耗大量的内存来存储数据集。在遍历数据集时,判断当前遍历值是否已经存在唯一...
  • matlab元胞自动机入门详解

    万次阅读 多人点赞 2019-02-09 11:13:08
    元胞自动机(CA)是一种用来仿真局部规则和局部联系的方法。典型的元 胞自动机是定义在网格上的,每一个点上的网格代表一个元胞与一种有限的状 态。变化规则适用于每一个元胞并且同时进行。 元胞的变化规则&amp;...
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    访问SVN 157 进销存项目 158 2011年1020日 158 进销存项目总结 160 测试需求分析 160 1、定义测试范围 160 2、建立需求项 160 3、细化需求项 162 4、需求覆盖率分析 164 课前复习: 164 判定表 166 3.1....
  • 计算从出生到现在了多少天

    千次阅读 2018-07-16 17:36:53
    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date;... * 计算活了多少天   *   *   */ public class CountLif...
  • 活期存款利息的计算方法

    千次阅读 2018-11-17 21:20:28
    活期存款利息的计算方法
  • 【数据库学习】数据库总结

    万次阅读 多人点赞 2018-07-26 13:26:41
    实体化视图是用于汇总,预计算,复制或分发数据的对象, 在大型的数据库中使用它可以提高涉及到的SUM,COUNT,AVG,MIN,MAX等的表的查询的速度。 物化视图的快速刷新采用了增量的机制,在刷新时,只针对基表上发生变化的...
  • 用户留存率详解与计算方法案例

    万次阅读 2017-10-19 10:38:13
    第7日留存率和周留存率是不同的概念和计算方法。下面我们分类看看几种留存率的定义和计算公式。 新增用户留存率    谈用户留存率,必须先搞清楚新增用户,用户活跃。通常我们说的用户留存率,一般是指...
  • 实现层面:大数据是一套数据处理技术活方法体系,实现具体以上特征的数据的存储、计算、共享、备份和容灾、保密等,保证数据处理的时效性和拓展性 服务层面:大数据的数据技术变革引发的新型信息服务模式,例如从...
  • 基于LSTM的股票预测模型_python实现_超详细

    万次阅读 多人点赞 2019-07-05 22:25:13
    门机制是让信息选择式通过的方法,通过sigmoid函数和点乘操作实现。sigmoid取值介于0~1之间,乘即点乘则决定了传送的信息量(每个部分有多少量可以通过),当sigmoid取0时表示舍弃信息,取1时表示完全传输(即完全...
  • 深度学习入门

    万次阅读 多人点赞 2017-11-05 21:23:46
    (2)更为严重的问题是,即使使用当时最先进的计算机,也没有足够计算能力,完成神经网络模型所需要的超大的计算量(比如调整网络中的权重参数)。   鉴于明斯基的江湖地位(1969年刚刚获得大名鼎鼎的图灵奖),...
  • 3. 计算你从出生到今天了多少天,今年多少岁    var birthday=new Date("1996/06/21");//定义自己的生日  var today=new Date();  //getTime() 返回从 1970 年 1 1 日至今的毫秒数。  //1秒=1000...
  • 峰值的部分计算方法

    万次阅读 2015-12-28 15:57:15
    若80%的访问量集中在20%的时间里,可用此分析方法,其图形就是一个正态分布图,如下。 ---性能测试需求收集" alt="性能测试(1) ---性能测试需求收集" src=...
  •  一.实战之前,先介绍一个概念bitmap 这个bitmap有啥用?...看这副图片,假如更精简的话,只有2个...下面,我将讲解如何用bitmap原理来存储日数据 思路:把每一天,当做一个图,谁访问了,就在哪个点上,设置1
  • 机房承重标准及承重计算方法

    万次阅读 2017-10-13 00:00:00
    所以机房要有较高的承重能力,满足设备的承重要求,但现在很多建筑并非为机房所建,其承重达不到机房要求,所以在建设机房之前就要考虑到承重问题,下面详解机房的承重标准,以及机房承重计算内容及计算方法。...
  • 并发用户数的计算方法

    千次阅读 2018-07-13 15:25:28
    在实际性能测试中,测试人员常常会关心到并发用户数,也就是从业务角度关注究竟应该设置多少个并发数比较合理,以下是一个估算并发用户数的方法: (1) 计算平均的并发用户数: C = nL/T (2) 并发用户数峰值: ...
  • 日活跃用户「MAU」 和活跃用户「DAU」 1、日的概念 ...也就是说一个里面你每天都打开,也只算 1 个月活,但是 100 个人,分别在一个内的不同时间打开产品,就会计算为 100 个月活。 3、日...
  • VBA辅助ANSYS分析箱梁桥载空间效应方法尝试,王清泉,柴冰,讨论了箱梁桥载空间效应简化计算原理,针对同类型结构,利用ANSYS的二次开发功能(APDL)计算其影响面,用VBA实现影响面空间加载,
  • 计算来到这个时间多长时间的步骤: 1.输入你的出现日期; 2.利用日期转换,将字符串转换成date类型 3.然后将date时间换成毫秒时间 4.然后获取当前毫秒时间; 5.最后计算出来到这个时间多少天; package ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,009
精华内容 31,203
关键字:

月活计算方法