抽样方法高级技巧
在Hive中,抽样是一种常用的手段,主要应用于几个场景。
首先,在一些机器学习的应用中,数据仓库作为样本数据的提供者,会提供数据以供分析。其次,当数据计算结果或指标出现异常时,我们常常需要验证数据源是否存在问题。此外,当SQL性能不佳时,抽样也可以帮助我们查看数据,从而进行SQL调优。在大规模数据分析和建模任务中,针对全量数据的挖掘分析往往耗时且占用集群资源,因此通常只需抽取一小部分数据进行分析和建模。
随机抽样(Rand()函数)
我们通常使用排序函数结合Rand()函数完成随机抽样,使用LIMIT关键字限制返回的数据量。这里的不同在于,我们选择使用哪个排序函数。
利用Rand()函数进行抽取是因为它返回一个0到1之间的随机double值。
以下示例使用了大约4603089条记录的表,具体数据可以参考Hive进阶中的数据存储格式获取。
CREATE TABLE ods_User_bUCket_log (
id INT,
naMe STRING,
cITy STRING,
phone STRING,
acctiMe STRING
) CLUSTERED BY (id) INTO 5 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\'\''
STORED AS TEXTFILE;
INSERT OVERWRITE TABLE ods_User_bUCket_log SELECT * FROM ods_User_log;
使用ORDER BY Rand():
SELECT * FROM ods_User_bUCket_log ORDER BY Rand() LIMIT 10;
使用SORT BY Rand():
SELECT * FROM ods_User_bUCket_log SORT BY Rand() LIMIT 10;
在这种情况下,SORT BY提供了单个Reducer内的排序功能,但并不保证整体有序,因此无法实现真正的随机抽样。
使用DISTRIBUTE BY Rand() SORT BY Rand():
SELECT * FROM ods_User_bUCket_log DISTRIBUTE BY Rand() SORT BY Rand() LIMIT 10;
该方法能够确保数据在Mapper和Reducer阶段随机分布,从而实现真正的随机抽样。
使用CLUSTER BY Rand():
SELECT * FROM ods_User_bUCket_log CLUSTER BY Rand() LIMIT 10;
CLUSTER BY的功能结合了DISTRIBUTE BY和SORT BY的能力,进行一次随机操作,速度要快于前一种方法。
TABLESAMPLE()抽样函数
在Hive中,分桶抽样是通过根据某一字段的哈希值进行取模,将数据放入指定的桶中。例如,将表按照ID分成100个桶,算法为hash(id) % 100。
分桶抽样的语法为:
TABLESAMPLE (BUCKET x OUT OF y [ON colName])
其中,x为抽样的桶编号,colName表示分桶的列,y为桶的总数。
例如:
SELECT * FROM ods_User_bUCket_log TABLESAMPLE (BUCKET 1 OUT OF 100000 ON Rand());
数据块抽样自Hive 0.8开始提供,使用TABLESAMPLE可以抽取指定的行数、比例或大小。
按行数抽样:
SELECT * FROM ods_User_data TABLESAMPLE(1000 ROWS);
按比例抽样:
SELECT * FROM ods_User_bUCket_log TABLESAMPLE(20 PERCENT);
特定大小的数据抽样:
SELECT * FROM ods_User_bUCket_log TABLESAMPLE(1M);
需要注意的是,这里的M必须是整数,尝试使用小数会导致错误。
抽取特定行数:
SELECT * FROM ods_User_bUCket_log TABLESAMPLE(10 ROWS);
注意:
1. 必须保留并原样返回所有 [[[IMG_n]]] 占位符。
