TPC-DS标准规范(5)

TPC-DS是一套决策支持系统测试基准,主要针对零售行业。提供99个SQL查询(SQL99或2003),分析数据量大,测试数据与实际商业数据高度相似,同时具有各种业务模型(分析报告型,数据挖掘型等等)。国内目前相关的翻译文章较少。本文尝试对官网的TPC BENCHMARK DS Standard Specification(下称“原文”)进行翻译。翻译主要参照的是2017年发布的2.6.0版本。

由于原文一共137页,本文在翻译的时候会进行一定的压缩,突出较为关键的信息。本文章节名称,序号,小标题等均严格按照原文翻译排序。

5 数据维护

5.1 实现要求和定义

5.1.1 数据维护操作是基准执行的一部分,这些操作包括处理刷新。基准中刷新运行的总数等于一次吞吐量测试中的查询流的数量。在每次刷新时,都要执行第5.3节中定义的所有数据维护功能。每个刷新都有自己的dsdgen生成的数据集,必须按照dsdgen生成的顺序使用。数据维护操作与查询分开执行。刷新运行不重叠; 同一时刻最多运行一个刷新。

5.1.2 每次刷新,要在第5.2节中定义的刷新数据上,将5.3节中定义的所有数据维护功能都跑一遍。对于任何一个数据维护功能而言,必须等所有数据维护功能都运行了n次刷新,才能开始运行它的第n+1次刷新(见7.4.8.5)。

5.1.3 数据维护功能可以分解或组合成任何数量的数据库操作,只要满足以下条件,就可以自由选择数据维护功能的执行顺序,同时也可以并行执行。

a) 数据可访问性(见第6.1条)

b) 无论是否被约束强制执行,所有的主/外键关系必须保持不变(见2.5.4)。这并不意味着必须明确定义引用完整性约束。

c) 当数据维护过程完成时,发送带time-stamp的输出消息。

5.1.4 在这些数据维护操作中,必须更新受任何数据维护操作影响的EADS。刷新过程执行的所有更新都可以查询到。

5.1.5 数据维护功能必须在SQL中实现。数据维护的实施过程必须由审核人员审核,审核人员可以要求进一步的测试,以确定数据维护功能是否按照基准要求执行。

5.1.6 分段区域(staging area)是用于实现数据维护功能的数据库对象(例如表,索引,视图等)的可选集合。在分段区域中创建的数据库对象只能在执行数据维护阶段时使用,并且不能在基准测试的任何其他阶段使用。需要在FDR中标明在分段区域中创建的任何对象。

5.1.7 用于分段区域的任何磁盘存储必须定价。必须注明磁盘存储的任何映射或虚拟化。

5.2 刷新数据

5.2.1 刷新数据由一系列数据组成,编号为1,2,3...n。<n>与基准测试的吞吐量测试中的使用流的数量相同。每个刷新数据集由<N>个flat files组成,flat files的内容可用于填充附录A中定义的source schema(并不强制填充)。为每个刷新数据集生成的flat files及其对应的source schema表如下表所示。

5.2.2 表5-1列出了每个flat files的,标度因子为1的刷新数据集的行数。

5.2.3 必须使用dsdgen生成每个数据维护功能的刷新数据集。dsdgen的执行时间不必计时,输出为一个文本文件。刷新数据集的存储应为定价配置的其中一部分。

5.2.4 可以通过以下方式修改dsdgen生成的刷新数据集:刷新数据集中每个表的输出文件可以分为n个文件,其中每个文件包含原始输出的总行数的大约1 / n 文件。必须保留原始输出文件中行的顺序,以使所有n个文件的连接与原始文件相同。

5.2.5 数据维护过程时,读取刷新数据需要计时。在刷新运行的过程中,必须对特定刷新运行的数据集进行加载和计时。数据的加载必须通过数据处理系统中通用的过程,严禁使用专门为TPC-DS设计的加载工具。

5.3 数据维护功能

5.3.1 数据维护功能执行伪码中定义的插入和删除操作,根据维护功能执行的操作和哪种类型的表,将它们分类为方法1-3。

方法1:事实插入数据维护

方法2:事实删除数据维护

方法3:库存删除数据维护

5.3.2 下表列出了所有数据维护功能、其操作类型、以及目标表。视图中的行数必须等于表5-4第6列中列出的source schema表中的行数(列在表5-2中)。

5.3.3 方法1从视图V中读取行(参见第5.3.2节中的视图名称列表),并将行插入数据仓库表T。V和T都被定义为数据维护功能的一部分。T作为数据仓库初始加载的一部分创建。V是不需要实例化的逻辑表。

5.3.4 V的主键在数据维护功能中定义。每个数据维护功能包含一个表,其视图V与其数据仓库表T之间具有列映射关系。V的主键在该映射表的左侧以粗体字表示(例如表5-5)。

5.3.5 商务键在数据维护功能的映射表的右侧以粗体字表示(例如表5-5)。

5.3.6 维度表的主键值为递增序列。如果为维度表生成新的主键值,假设当前主键最大值为x,则新的主键值为x + 1。

5.3.7 方法1:事实表加载

for every row v in view V corresponding to fact table F
get row v into local variable lv
for every type 1 business key column bkc in v
get row d from dimension table D corresponding to bkc
where the business keys of v and d are equal
update bkc of lv with surrogate key of d
end for
for every type 2 business key column bkc in v
get row d from dimension table D corresponding to bkc
where the business keys of v and d are equal and rec_end_date is NULL

update bkc of lv with surrogate key of d

end for
insert lv into F
end for

5.3.8 方法2:销售和退货事实表删除

Delete rows from R with corresponding rows in S
where d_date between Date1 and Date2
Delete rows from S
where d_date between Date1 and Date2

5.3.9 方法3:库存事实表删除

Delete rows from I where d_date between Date1 and Date2

5.3.10 维度表和事实表中,插入或更新行的每个数据维护功能,由以下几部分定义:

a) 描述符,描述数据维护方法的名称。对于维度表,描述符的格式是“DM_<数据仓库表的缩写>”。对于事实表,描述符的格式是“LF_<数据仓库事实表的缩写>”。扩展名表示使用此数据维护功能填充的数据仓库表。

b) 数据维护方法描述数据维护功能的伪代码。

c) SQL视图V描述source schema需要join哪些表,以加载正确的行。

d) 列映射,定义source schema列映射到哪个数据仓库列。

5.3.11 每个从事实表中删除行的数据维护功能,由以下几部分定义:

a) 描述符,以DF_ <数据仓库事实表的缩写>形式表示数据维护功能的名称。该扩展名显示删除行的数据仓库事实表。
b) 表:S和R,在库存情况下是I
c) 两个日期:Date1和Date2
d) 显示数据如何被删除的数据维护方法

5.3.11.1 LF_SS

CREATE view ssv as
SELECT d_date_sk ss_sold_date_sk,
t_time_sk ss_sold_time_sk,
i_item_sk ss_item_sk,
c_customer_sk ss_customer_sk,
c_current_cdemo_sk ss_cdemo_sk,
c_current_hdemo_sk ss_hdemo_sk,
c_current_addr_sk ss_addr_sk,
s_store_sk ss_store_sk,
p_promo_sk ss_promo_sk,
purc_purchase_id ss_ticket_number,
plin_quantity ss_quantity,
i_wholesale_cost ss_wholesale_cost,
i_current_price ss_list_price,
plin_sale_price ss_sales_price,
(i_current_price-plin_sale_price)*plin_quantity ss_ext_discount_amt,
plin_sale_price * plin_quantity ss_ext_sales_price,
i_wholesale_cost * plin_quantity ss_ext_wholesale_cost,
i_current_price * plin_quantity ss_ext_list_price,
i_current_price * s_tax_precentage ss_ext_tax,
plin_coupon_amt ss_coupon_amt,
(plin_sale_price * plin_quantity)-plin_coupon_amt ss_net_paid,
((plin_sale_price * plin_quantity)-plin_coupon_amt)*(1+s_tax_precentage) ss_net_paid_inc_tax,
((plin_sale_price * plin_quantity)-plin_coupon_amt)-(plin_quantity*i_wholesale_cost)
ss_net_profit
FROM s_purchase
LEFT OUTER JOIN customer ON (purc_customer_id = c_customer_id)
LEFT OUTER JOIN store ON (purc_store_id = s_store_id)
LEFT OUTER JOIN date_dim ON (cast(purc_purchase_date as date) = d_date)
LEFT OUTER JOIN time_dim ON (PURC_PURCHASE_TIME = t_time)
JOIN s_purchase_lineitem ON (purc_purchase_id = plin_purchase_id)
LEFT OUTER JOIN promotion ON plin_promotion_id = p_promo_id
LEFT OUTER JOIN item ON plin_item_id = i_item_id
WHERE purc_purchase_id = plin_purchase_id
AND i_rec_end_date is NULL
AND s_rec_end_date is NULL;

5.3.11.2 LF_SR

CREATE view srv as
SELECT d_date_sk sr_returned_date_sk
,t_time_sk sr_return_time_sk
,i_item_sk sr_item_sk
,c_customer_sk sr_customer_sk
,c_current_cdemo_sk sr_cdemo_sk
,c_current_hdemo_sk sr_hdemo_sk
,c_current_addr_sk sr_addr_sk
,s_store_sk sr_store_sk
,r_reason_sk sr_reason_sk
,sret_ticket_number sr_ticket_number
,sret_return_qty sr_return_quantity
,sret_return_amt sr_return_amt
,sret_return_tax sr_return_tax
,sret_return_amt + sret_return_tax sr_return_amt_inc_tax
,sret_return_fee sr_fee
,sret_return_ship_cost sr_return_ship_cost
,sret_refunded_cash sr_refunded_cash
,sret_reversed_charge sr_reversed_charge
,sret_store_credit sr_store_credit
,sret_return_amt+sret_return_tax+sret_return_fee
-sret_refunded_cash-sret_reversed_charge-sret_store_credit sr_net_loss
FROM s_store_returns
LEFT OUTER JOIN date_dim
ON (cast(sret_return_date as date) = d_date)
LEFT OUTER JOIN time_dim
ON (( cast(substr(sret_return_time,1,2) AS integer)*3600
+cast(substr(sret_return_time,4,2) AS integer)*60
+cast(substr(sret_return_time,7,2) AS integer)) = t_time)
LEFT OUTER JOIN item ON (sret_item_id = i_item_id)
LEFT OUTER JOIN customer ON (sret_customer_id = c_customer_id)
LEFT OUTER JOIN store ON (sret_store_id = s_store_id)
LEFT OUTER JOIN reason ON (sret_reason_id = r_reason_id)
WHERE i_rec_end_date IS NULL
AND s_rec_end_date IS NULL;

5.3.11.3 LF_WS

CREATE VIEW wsv AS
SELECT d1.d_date_sk ws_sold_date_sk,
t_time_sk ws_sold_time_sk,
d2.d_date_sk ws_ship_date_sk,
i_item_sk ws_item_sk,
c1.c_customer_sk ws_bill_customer_sk,
c1.c_current_cdemo_sk ws_bill_cdemo_sk,
c1.c_current_hdemo_sk ws_bill_hdemo_sk,
c1.c_current_addr_sk ws_bill_addr_sk,
c2.c_customer_sk ws_ship_customer_sk,
c2.c_current_cdemo_sk ws_ship_cdemo_sk,
c2.c_current_hdemo_sk ws_ship_hdemo_sk,
c2.c_current_addr_sk ws_ship_addr_sk,
wp_web_page_sk ws_web_page_sk,
web_site_sk ws_web_site_sk,
sm_ship_mode_sk ws_ship_mode_sk,
w_warehouse_sk ws_warehouse_sk,
p_promo_sk ws_promo_sk,
word_order_id ws_order_number,
wlin_quantity ws_quantity,
i_wholesale_cost ws_wholesale_cost,
i_current_price ws_list_price,
wlin_sales_price ws_sales_price,
(i_current_price-wlin_sales_price)*wlin_quantity ws_ext_discount_amt,
wlin_sales_price * wlin_quantity ws_ext_sales_price,
i_wholesale_cost * wlin_quantity ws_ext_wholesale_cost,
i_current_price * wlin_quantity ws_ext_list_price,
i_current_price * web_tax_percentage ws_ext_tax,
wlin_coupon_amt ws_coupon_amt,
wlin_ship_cost * wlin_quantity WS_EXT_SHIP_COST,
(wlin_sales_price * wlin_quantity)-wlin_coupon_amt ws_net_paid,
((wlin_sales_price * wlin_quantity)-wlin_coupon_amt)*(1+web_tax_percentage) ws_net_paid_inc_tax,
((wlin_sales_price * wlin_quantity)-wlin_coupon_amt)-(wlin_quantity*i_wholesale_cost)
WS_NET_PAID_INC_SHIP,
(wlin_sales_price * wlin_quantity)-wlin_coupon_amt + (wlin_ship_cost * wlin_quantity)
+ i_current_price * web_tax_percentage WS_NET_PAID_INC_SHIP_TAX,
((wlin_sales_price * wlin_quantity)-wlin_coupon_amt)-(i_wholesale_cost * wlin_quantity)
WS_NET_PROFIT
FROM s_web_order
LEFT OUTER JOIN date_dim d1 ON (cast(word_order_date as date) = d1.d_date)
LEFT OUTER JOIN time_dim ON (word_order_time = t_time)
LEFT OUTER JOIN customer c1 ON (word_bill_customer_id = c1.c_customer_id)
LEFT OUTER JOIN customer c2 ON (word_ship_customer_id = c2.c_customer_id)
LEFT OUTER JOIN web_site ON (word_web_site_id = web_site_id AND web_rec_end_date IS NULL)
LEFT OUTER JOIN ship_mode ON (word_ship_mode_id = sm_ship_mode_id)
JOIN s_web_order_lineitem ON (word_order_id = wlin_order_id)
LEFT OUTER JOIN date_dim d2 ON (cast(wlin_ship_date as date) = d2.d_date)
LEFT OUTER JOIN item ON (wlin_item_id = i_item_id AND i_rec_end_date IS NULL)
LEFT OUTER JOIN web_page ON (wlin_web_page_id = wp_web_page_id AND wp_rec_end_date IS NULL)
LEFT OUTER JOIN warehouse ON (wlin_warehouse_id = w_warehouse_id)
LEFT OUTER JOIN promotion ON (wlin_promotion_id = p_promo_id);

5.3.11.4 LF_WR

CREATE VIEW wrv AS
SELECT d_date_sk wr_return_date_sk
,t_time_sk wr_return_time_sk
,i_item_sk wr_item_sk
,c1.c_customer_sk wr_refunded_customer_sk
,c1.c_current_cdemo_sk wr_refunded_cdemo_sk
,c1.c_current_hdemo_sk wr_refunded_hdemo_sk
,c1.c_current_addr_sk wr_refunded_addr_sk
,c2.c_customer_sk wr_returning_customer_sk
,c2.c_current_cdemo_sk wr_returning_cdemo_sk
,c2.c_current_hdemo_sk wr_returning_hdemo_sk
,c2.c_current_addr_sk wr_returing_addr_sk
,wp_web_page_sk wr_web_page_sk
,r_reason_sk wr_reason_sk
,wret_order_id wr_order_number
,wret_return_qty wr_return_quantity
,wret_return_amt wr_return_amt
,wret_return_tax wr_return_tax
,wret_return_amt + wret_return_tax AS wr_return_amt_inc_tax
,wret_return_fee wr_fee
,wret_return_ship_cost wr_return_ship_cost
,wret_refunded_cash wr_refunded_cash
,wret_reversed_charge wr_reversed_charge
,wret_account_credit wr_account_credit
,wret_return_amt+wret_return_tax+wret_return_fee
-wret_refunded_cash-wret_reversed_charge-wret_account_credit wr_net_loss
FROM s_web_returns LEFT OUTER JOIN date_dim ON (cast(wret_return_date as date) = d_date)
LEFT OUTER JOIN time_dim ON ((CAST(SUBSTR(wret_return_time,1,2) AS integer)*3600
+CAST(SUBSTR(wret_return_time,4,2) AS integer)*60+CAST(SUBSTR(wret_return_time,7,2) AS integer))=t_time)
LEFT OUTER JOIN item ON (wret_item_id = i_item_id)
LEFT OUTER JOIN customer c1 ON (wret_return_customer_id = c1.c_customer_id)
LEFT OUTER JOIN customer c2 ON (wret_refund_customer_id = c2.c_customer_id)
LEFT OUTER JOIN reason ON (wret_reason_id = r_reason_id)
LEFT OUTER JOIN web_page ON (wret_web_page_id = WP_WEB_PAGE_id)
WHERE i_rec_end_date IS NULL AND wp_rec_end_date IS NULL;

5.3.11.5 LF_CS

CREATE view csv as
SELECT d1.d_date_sk cs_sold_date_sk
,t_time_sk cs_sold_time_sk
,d2.d_date_sk cs_ship_date_sk
,c1.c_customer_sk cs_bill_customer_sk
,c1.c_current_cdemo_sk cs_bill_cdemo_sk
,c1.c_current_hdemo_sk cs_bill_hdemo_sk
,c1.c_current_addr_sk cs_bill_addr_sk
,c2.c_customer_sk cs_ship_customer_sk
,c2.c_current_cdemo_sk cs_ship_cdemo_sk
,c2.c_current_hdemo_sk cs_ship_hdemo_sk
,c2.c_current_addr_sk cs_ship_addr_sk
,cc_call_center_sk cs_call_center_sk
,cp_catalog_page_sk cs_catalog_page_sk
,sm_ship_mode_sk cs_ship_mode_sk
,w_warehouse_sk cs_warehouse_sk
,i_item_sk cs_item_sk
,p_promo_sk cs_promo_sk
,cord_order_id cs_order_number
,clin_quantity cs_quantity
,i_wholesale_cost cs_wholesale_cost
,i_current_price cs_list_price
,clin_sales_price cs_sales_price
,(i_current_price-clin_sales_price)*clin_quantity cs_ext_discount_amt
,clin_sales_price * clin_quantity cs_ext_sales_price
,i_wholesale_cost * clin_quantity cs_ext_wholesale_cost
,i_current_price * clin_quantity CS_EXT_LIST_PRICE
,i_current_price * cc_tax_percentage CS_EXT_TAX
,clin_coupon_amt cs_coupon_amt
,clin_ship_cost * clin_quantity CS_EXT_SHIP_COST
,(clin_sales_price * clin_quantity)-clin_coupon_amt cs_net_paid
,((clin_sales_price * clin_quantity)-clin_coupon_amt)*(1+cc_tax_percentage) cs_net_paid_inc_tax
,(clin_sales_price * clin_quantity)-clin_coupon_amt + (clin_ship_cost * clin_quantity) CS_NET_PAID_INC_SHIP
,(clin_sales_price * clin_quantity)-clin_coupon_amt + (clin_ship_cost * clin_quantity)
+ i_current_price * cc_tax_percentage CS_NET_PAID_INC_SHIP_TAX
,((clin_sales_price * clin_quantity)-clin_coupon_amt)-(clin_quantity*i_wholesale_cost) cs_net_profit
FROM s_catalog_order
LEFT OUTER JOIN date_dim d1 ON
(cast(cord_order_date as date) = d1.d_date)
LEFT OUTER JOIN time_dim ON (cord_order_time = t_time)
LEFT OUTER JOIN customer c1 ON (cord_bill_customer_id = c1.c_customer_id)
LEFT OUTER JOIN customer c2 ON (cord_ship_customer_id = c2.c_customer_id)
LEFT OUTER JOIN call_center ON (cord_call_center_id = cc_call_center_id AND cc_rec_end_date IS NULL)
LEFT OUTER JOIN ship_mode ON (cord_ship_mode_id = sm_ship_mode_id)
JOIN s_catalog_order_lineitem ON (cord_order_id = clin_order_id)
LEFT OUTER JOIN date_dim d2 ON
(cast(clin_ship_date as date) = d2.d_date)
LEFT OUTER JOIN catalog_page ON
(clin_catalog_page_number = cp_catalog_page_number and clin_catalog_number = cp_catalog_number)
LEFT OUTER JOIN warehouse ON (clin_warehouse_id = w_warehouse_id)
LEFT OUTER JOIN item ON (clin_item_id = i_item_id AND i_rec_end_date IS NULL)
LEFT OUTER JOIN promotion ON (clin_promotion_id = p_promo_id);

5.3.11.6 LF_CR

CREATE VIEW crv as
SELECT d_date_sk cr_return_date_sk
,t_time_sk cr_return_time_sk
,i_item_sk cr_item_sk
,c1.c_customer_sk cr_refunded_customer_sk
,c1.c_current_cdemo_sk cr_refunded_cdemo_sk
,c1.c_current_hdemo_sk cr_refunded_hdemo_sk
,c1.c_current_addr_sk cr_refunded_addr_sk
,c2.c_customer_sk cr_returning_customer_sk
,c2.c_current_cdemo_sk cr_returning_cdemo_sk
,c2.c_current_hdemo_sk cr_returning_hdemo_sk
,c2.c_current_addr_sk cr_returing_addr_sk
,cc_call_center_sk cr_call_center_sk
,cp_catalog_page_sk CR_CATALOG_PAGE_SK
,sm_ship_mode_sk CR_SHIP_MODE_SK
,w_warehouse_sk CR_WAREHOUSE_SK
,r_reason_sk cr_reason_sk
,cret_order_id cr_order_number
,cret_return_qty cr_return_quantity
,cret_return_amt cr_return_amt
,cret_return_tax cr_return_tax
,cret_return_amt + cret_return_tax AS cr_return_amt_inc_tax
,cret_return_fee cr_fee
,cret_return_ship_cost cr_return_ship_cost
,cret_refunded_cash cr_refunded_cash
,cret_reversed_charge cr_reversed_charge
,cret_merchant_credit cr_merchant_credit
,cret_return_amt+cret_return_tax+cret_return_fee
-cret_refunded_cash-cret_reversed_charge-cret_merchant_credit cr_net_loss
FROM s_catalog_returns
LEFT OUTER JOIN date_dim
ON (cast(cret_return_date as date) = d_date)
LEFT OUTER JOIN time_dim ON
((CAST(substr(cret_return_time,1,2) AS integer)*3600
+CAST(substr(cret_return_time,4,2) AS integer)*60
+CAST(substr(cret_return_time,7,2) AS integer)) = t_time)
LEFT OUTER JOIN item ON (cret_item_id = i_item_id)
LEFT OUTER JOIN customer c1 ON (cret_return_customer_id = c1.c_customer_id)
LEFT OUTER JOIN customer c2 ON (cret_refund_customer_id = c2.c_customer_id)
LEFT OUTER JOIN reason ON (cret_reason_id = r_reason_id)
LEFT OUTER JOIN call_center ON (cret_call_center_id = cc_call_center_id)
LEFT OUTER JOIN catalog_page ON (cret_catalog_page_id = cp_catalog_page_id)
LEFT OUTER JOIN ship_mode ON (cret_shipmode_id = sm_ship_mode_id)
LEFT OUTER JOIN warehouse ON (cret_warehouse_id = w_warehouse_id)
WHERE i_rec_end_date IS NULL AND cc_rec_end_date IS NULL;

5.3.11.7 LF_I:

5.3.11.8

CREATE view iv AS
SELECT d_date_sk inv_date_sk,
i_item_sk inv_item_sk,
w_warehouse_sk inv_warehouse_sk,
invn_qty_on_hand inv_quantity_on_hand
FROM s_inventory
LEFT OUTER JOIN warehouse ON (invn_warehouse_id=w_warehouse_id)
LEFT OUTER JOIN item ON (invn_item_id=i_item_id AND i_rec_end_date IS NULL)
LEFT OUTER JOIN date_dim ON (d_date=invn_date);

5.3.11.9 DF_SS:

S=store_sales
R=store_returns
Date1 as generated by dsdgen
Date2 as generated by dsdgen

5.3.11.10 DF_CS:

S=catalog_sales
R=catalog_returns
Date1 as generated by dsdgen
Date2 as generated by dsdgen

5.3.11.11 DF_WS:

S=web_sales
R=web_returns
Date1 as generated by dsdgen
Date2 as generated by dsdgen

5.3.11.12 DF_I:

I=Inventory
Date1 as generated by dsdgen
Date2 as generated by dsdgen

1. HMM

HMM属于生成模型,是关于时序的概率模型。假设我们现在有一串状态序列Z,对于任意状态Z_{i},都存在一个对应的观测X_{i},因此也就存在观测序列X。

Z_{1}无法观测时,Z_{2}X_{1}之间就不是独立的,递推可知,X与Z不独立。同理易知X_{1}X_{2}Z_{1}Z_{2}不可观测的情况下也不独立。

因此,HMM的模型可以解决样本不独立的问题。对于样本之间存在关系的结构化数据,联合概率并不等于边缘概率的乘积,因此很多模型的前提假设并不满足,在这种情况下,HMM或许是一个很好的选择。一个HMM模型,由初始概率分布\pi,状态转移概率分布A,以及观测概率分布B确定。设状态Q一共有N种可能,观测V一共有M种可能,状态序列I的长度为T,O是对应的观测序列,则状态转移概率矩阵A=\left [a_{ij} \right ]_{N\times N},其中a_{ij}=P\left ( i_{t+1}=q_{j}|i_{t}=q_{i}\right )代表的是t时刻,已知状态为q_{i}的情况下,t+1时刻状态为q_{j}的概率。观测概率矩阵B=\left [b_{ik} \right ]_{N\times M},其中b_{ik}=P\left ( o_{t}=v_{k}|i_{t}=q_{i}\right )代表的是t时刻,已知状态为q_{i}的情况下,观测结果为v_{k}的概率。初始概率分布\pi指的其实就是t=1时,状态Q的各个取值的概率。

HMM的一个经典例子就是李航博士的《统计学习方法》中提到的“盒子和球模型”:假设有4个盒子,每个盒子里都装有红白两种颜色的球,盒子里的红白球如下:

各盒子的红白球数
盒子1234
红球数5368
白球数5742

开始时,从四个盒子里一等概率随机选取1个盒子,随机从该盒子里抽出一个球,记录颜色后放回。然后从当前盒子随机转移到下一个盒子,转移规则为:如果当前盒子是1,则下一个盒子一定是2;如果当前盒子是2或3,则分别以0.4和0.6的概率转移到左边和右边的盒子;如果当前盒子是4,则以0.5的概率转移到3,以0.5的概率继续留在4。确定转移后的新盒子之后,继续抽出一个球,记录颜色后放回。重复5次之后,得到一个球的颜色的观测序列:O={红,红,白,白,红}。整个过程无法观测,只能观测最终的球的结果。

这个例子中,盒子的选择序列可以被视作无法观测的状态序列。根据条件,HMM三要素分别表示为:状态集合Q={盒子1,盒子2,盒子3,盒子4},N=4;观测集合V={红,白},M=2;序列长度T=5。

初始概率分布:

状态转移概率分布:

观测概率分布:

2. 观测序列的生成过程

HMM的观测序列O的生成过程,在《统计学习方法》中被描述为:

  1. 按照初始状态分布\pi产生状态i_{1}​​
  2. 令t=1
  3. 按照状态i_{t}的观测概率分布b_{i_{t}(k)}生成o_{t}
  4. 按照状态i_{t}的状态转移概率分布{a_{i_{t}i_{t+1}}}产生状态i_{t+1}i_{t+1}=1,2,...,N
  5. 令t=t+1;如果t<T,转步(3);否则,终止

3. HMM的三个核心问题

HMM有三个核心问题:

  1. The Decoding Problem:已知模型\lambda及观测序列O,求该情况下使P(I|O)最大的状态序列I
  2. The Learning Problem:已知观测序列O,使用maximum likelihood估计模型参数A,B,\pi使P(O|\lambda)最大
  3. The Evaluation Problem:给定模型\lambda和观测序列P,求该模型下观测序列出现的概率P(O|\lambda)

3.1 The Decoding Problem and Viterbi Algorithm

重点说说decoding problem。我在QMUL读硕士的时候,毕业论文做的内容是和自动编曲相关的,当时导师Dr. Dorien Herremans问我懂不懂神经网络,我说不太懂,然后她就推荐了这个复古的HMM给我。HMM在二十世纪基本是自动编曲领域应用的最主流的模型,那个年代还没有深层的神经网络,基本所有论文都是在讨论HMM观测一个什么玩意然后推测对应的状态序列,这个状态序列实际上就是各种和弦。因此HMM在这个领域算得上是功勋卓著的奠基石。

Viterbi Algorithm是由USC的Dr. Andrew Viterbi发明的,Viterbi是Qualcomm的cofounder,专利狂魔,基本上Qualcomm早期通信产品都是靠他撑起来的,学EE的道友肯定不会陌生。这套算法的实质就是DP求概率最大的路径,该路径也就对应着需要求解的状态序列。

如果最优路径在t时刻通过i_{t},则从i_{t}i_{T}的这段子路径中,最优路径所走的一定是该子路径集合的最优子路径。因此我们只要从t=1时刻开始DP任何时刻t对应的各个状态i的各条部分路径的最大概率即可。

定义变量\delta

这里的\delta,指的是t时刻位于状态i的概率最大值。

定义变量\psi

这里的\psi,指的是使t时刻位于状态i的所有单个路径中概率最大的路径的t-1时刻的状态。

初始化\delta\psi

对t=2,3,...,T进行递推:

求得最优路径在T时刻时的状态:

对t=T-1,T-2,... ,1回溯最终得到最优路径I:

《统计学习方法》中,还给出了一种“近似算法”,大概意思就是对于观测序列中每一个观测值,通过maximum likelihood反求对应的最可能状态值,然后直接将这些对应的状态组成状态序列。这个方法我如果没有理解错的话,应该是一个貌似greedy algorithm的做法。李航博士也在书中说了,会存在无法实现的可能,比如最终的状态序列为(1, 2, 3, 3, 1),可是a_{23}=0。这个近似算法精度上还是有一些问题的,即使得到可行解,也无法像DP那样保证为global optima。不过正是因为不进行回滚,近似算法的计算更加简单,对于精度要求不高的项目,近似算法依旧是一种高效的堪用算法。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值