您的位置:首页 > 数据库

MADlib——基于SQL的数据挖掘解决方案(14)——回归之多类回归

2018-02-01 14:15 495 查看

一、多类回归简介

1. 基本介绍

        如上篇所述,逻辑回归比较常用的是因变量为二分类的情况,这也是比较简单的一种形式。但在现实中,因变量的分类有时候多于两类,如疗效可能是“无效”“显效”“痊愈”三类,当然可以把其中两类进行合并,然后仍然按照二分类逻辑回归进行分析,但是合并的弊端是显而易见的,它可能损失一定的信息。而多分类则充分利用了完整的信息,可能提供更多的结果。如果目标类别数超过两个,这时就需要使用多类回归(Multinomial Regression)。
 
        在统计学里,多类回归是一个将逻辑回归一般化成多类别问题得到的分类方法。用更加专业的话来说,它是用来预测一个具有类别分布的因变量不同可能结果的概率的模型。在多类回归中,因变量是根据一系列自变量(就是我们所说的特征、观测变量)来预测得到的。具体来说,就是通过将自变量和相应参数进行线性组合之后,使用某种概率模型来计算预测因变量中得到某个结果的概率,而自变量对应的参数,即回归系数,是通过训练数据计算得到的。
 

2. 模型介绍

        实现多类回归模型最简单的方法是,对于所有K个可能的分类结果,运行K−1个独立二元逻辑回归模型,在运行过程中把其中一个类别看成是主类别,然后将其它K−1个类别和所选择的主类别分别进行回归。通过这样的方式,如果选择结果K作为主类别的话,我们可以得到以下公式:


        上面的公式中已经引入了所有可能结果对应的回归系数集合了。然后对公式左右两边进行指数化处理可得以下公式:


需要注意的是,最后得到的概率之和必须等于1,基于这个事实我们可以得到:


 
这样就可以把以上公式代入到前面的公式中得到:


        通过这样的方法我们就能计算出所有给定未预测样本情况下得到某个结果的概率。上面公式中所涉及的每一个权重向量

中的未知系数,可以通过最大后验概率(MAP)来计算,同时也可以使用其它方法来计算,如一些基于梯度的算法。
 
        如果使用二元逻辑回归公式的对数模型的话,可以直接将其扩展成多类回归模型,形式如下:


这里用一个额外项

来确保所有概率能够形成一个概率分布,使得这些概率的和等于1。


 
然后将等式两边进行指数化,得到以下公式:


由于所有概率之和等于1,因此可以得到Z的推导公式:


 
综合以上公式,最后可以得到每一个结果对应的概率公式:



        仔细观察的话可以发现,所有的概率都具有以下形式:


 
        我们把具有以下形式的函数称为softmax函数:


 
        这个函数能够将

之间的差别放大,当存在一个

比所有值中的最大值小很多的话,那么它对应的softmax函数值就会趋于0。相反,当

是最大值的时候,除非排在第二大的值跟它很接近,否则softmax函数值会趋于1。所以softmax函数可以构造出一个类似平滑函数一样的加权平均数。我们可以把上面的公式写成如下softmax函数的形式:


 

二、MADlib的多类回归函数

1. 训练函数

(1)  语法
multinom(source_table,
model_table,
dependent_varname,
independent_varname,
ref_category,
link_func,
grouping_col,
optim_params,
verbose
)  
(2)  参数
[align=center]
参数名称数据类型描述
source_tableVARCHAR包含训练数据的表名。
model_tableVARCHAR
包含输出模型的表名。主输出表列和概要输出表列如表2、3所示。
dependent_varnameVARCHAR
因变量列名。
independent_varnameVARCHAR
评估使用的自变量的表达式列表,一般显式地由包括一个常数1项的自变量列表提供。
link_function(可选)VARCHAR
缺省值为'logit'。连接函数参数,当前仅支持logit。
ref_category(可选)VARCHAR
缺省值为'0',该参数指定参考类别。在做多类回归时,如果因变量Y有n个值,以其中一个类别作为参考类别,其它类别都同它相比较生成n-1个非冗余的logit变量模型。对于参考类别,其模型中所有系数均为0。
grouping_col(可选)VARCHAR
缺省值为NULL。和SQL中的“GROUP BY”类似,是一个将输入数据集分成离散组的表达式,每个组运行一个回归。此值为NULL时,将不使用分组,并产生一个单一的结果模型。
optim_params(可选)VARCHAR
缺省值为'max_iter=100,optimizer=irls,tolerance=1e-6',指定优化参数。
verbose(可选)BOOLEAN缺省值为FALSE,指定是否提供训练的详细输出结果。
[/align]表1 multinom函数参数说明 
[align=center]
列名数据类型描述
<...>
TEXT
分组列,取决于grouping_col输入,可能是多个列。
category
VARCHAR
表示分类值的字符串
coef
FLOAT8[]
回归系数向量。
log_likelihood
FLOAT8
对数似然比l(c)。
std_err
FLOAT8[]
系数的标准方差向量。
z_stats
FLOAT8[]
系数的z-统计量向量。
p_values
FLOAT8[]
系数的P值向量。
num_rows_processed
INTEGER
实际处理的行数。
num_missing_rows_skipped
INTEGER
训练时因为缺失值或错误跳过的行数。
num_iterations
INTEGER
实际迭代次数。
[/align]表2 multinom函数主输出表列说明 
        训练函数在产生输出表的同时,还会创建一个名为<model_table>_summary的概要表,具有以下列:
[align=center]
列名数据类型描述
Method
VARCHAR
'multinom',描述模型的字符串。
source_table
VARCHAR
源表名。
model_table
VARCHAR
模型表名。
dependent_varname
VARCHAR
因变量表达式。
independent_varname
VARCHAR
自变量表达式。
ref_category
VARCHAR
参考类别的字符串表示。
link_func
VARCHAR
连接函数参数,当前只实现了'logit'。
grouping_col
VARCHAR
分组列。
optimizer_params
VARCHAR
包含所有优化参数的字符串,形式是‘optimizer=..., max_iter=..., tolerance=...’。
num_all_groups
INTEGER
分组数。
num_failed_groups
INTEGER
失败分组数。
total_rows_processed
BIGINT
所有分组处理的总行数。
total_rows_skipped
BIGINT
所有组由于缺少值或失败跳过的总行数。
[/align]表3 multinom函数概要输出表列说明 

2. 预测函数

(1)  语法
multinom_predict(model_table,
predict_table_input,
output_table,
predict_type,
verbose,
id_column
)
(2)  参数[align=center]
参数名称
数据类型描述
model_tableTEXT训练函数生成的模型表名,是multinom()函数的输出表。
predict_table_inputTEXT
包含被预测数据的表名。表中必须有作为主键的ID列。
output_tableTEXT
包含预测结果的输出表名。输出表的列根据predict_type参数而有所不同。当predict_type = response时,输出表中包含两列:SERIAL类型的id,表示主键,TEXT类型的category列,包含预测的类别。predict_type = probability时,除id列外,每个类别输出一列,列名就是类别值,列值数据类型为FLOAT8,表示预测为该类别的概率。
predict_typeTEXT
'response'或'probability'。使用前者将输出预测最大概率的类别值,使用后者将输出每种类别的预测概率。
verboseBOOLEAN
控制是否显示详细信息,缺省值为FALSE。
id_columnTEXT
输入表中的ID列名。
[/align]表4 multinom_predict函数参数说明 

三、示例

1. 问题提出

        下表给出了对某中学20名视力低下学生视力监测的结果数据。试用多类回归方法分析视力低下程度(由轻到重共3级)与年龄、性别(1代表男性,2代表女性)之间的关系。
[align=center]
编号视力低下程度性别年龄
11115
21115
32114
42216
53216
63217
72217
82118
91114
103218
111117
121217
131115
142118
151215
161215
173217
181115
191115
202216
[/align]表5 视力监测结果 

2. 训练模型

-- 建立测试数据表并装载原始数据
drop table if exists t1;
create table t1 (id int, y int, x1 int, x2 int);
insert into t1 values
(1, 1, 1, 15), (2, 1, 1, 15), (3, 2, 1, 14), (4, 2, 2, 16),
(5, 3, 2, 16), (6, 3, 2, 17), (7, 2, 2, 17), (8, 2, 1, 18),
(9, 1, 1, 14), (10, 3, 2, 18), (11, 1, 1, 17), (12, 1, 2, 17),
(13, 1, 1, 15), (14, 2, 1, 18), (15, 1, 2, 15), (16, 1, 2, 15),
(17, 3, 2, 17), (18, 1, 1, 15), (19, 1, 1, 15), (20, 2, 2, 16);

-- 调用训练函数
drop table if exists t1_output, t1_output_summary;
select madlib.multinom('t1',
't1_output',
'y',
'array[1, x1, x2]',
'1',
'logit'
);

-- 查看回归结果
\x on
select * from t1_output;
         结果:
-[ RECORD 1 ]------+---------------------------------------------------------
category | 2
coef | {-14.8290303728741,0.732451965917644,0.83559834958054}
log_likelihood | -13.678884731229
std_err | {8.21112520279341,1.18343112456502,0.498230781591342}
z_stats | {-1.80596812332484,0.618922344286716,1.67713112166946}
p_values | {0.0709233188904113,0.535967517828425,0.093516844250734}
num_rows_processed | 20
num_rows_skipped | 0
num_iterations | 14
-[ RECORD 2 ]------+---------------------------------------------------------
category | 3
coef | {-66.5008632884155,16.0811838608692,2.1124007986729}
log_likelihood | -13.678884731229
std_err | {755.074438584232,377.375648716325,1.1813345463193}
z_stats | {-0.088071930249824,0.0426131996475413,1.78814782421672}
p_values | {0.929819506081099,0.966009873251665,0.073752161545248}
num_rows_processed | 20
num_rows_skipped | 0
num_iterations | 14

3. 使用模型进行预测(使用源表数据)

\x off
drop table if exists t1_prd;
select madlib.multinom_predict('t1_output', 't1', 't1_prd', 'probability');
-- 显示预测值
select * from t1_prd order by id;
        结果: id | 1 | 2 | 3
----+--------------------+--------------------+----------------------
1 | 0.826726567679996 | 0.173273426274487 | 6.04551768703297e-09
2 | 0.826726567679996 | 0.173273426274487 | 6.04551768703297e-09
3 | 0.916690056274327 | 0.0833099429149167 | 8.10755888689936e-10
4 | 0.38637457408413 | 0.38848495778712 | 0.22514046812875
5 | 0.38637457408413 | 0.38848495778712 | 0.22514046812875
6 | 0.12290156351699 | 0.284982917588031 | 0.592115518894979
7 | 0.12290156351699 | 0.284982917588031 | 0.592115518894979
8 | 0.28005405528707 | 0.719944787200939 | 1.15751199141851e-06
9 | 0.916690056274327 | 0.0833099429149167 | 8.10755888689936e-10
10 | 0.0216536931969841 | 0.115794825319112 | 0.862551481483904
11 | 0.472878151884198 | 0.527121611725927 | 2.36389875351574e-07
12 | 0.12290156351699 | 0.284982917588031 | 0.592115518894979
13 | 0.826726567679996 | 0.173273426274487 | 6.04551768703297e-09
14 | 0.28005405528707 | 0.719944787200939 | 1.15751199141851e-06
15 | 0.663808165241336 | 0.289409315483704 | 0.04678251927496
16 | 0.663808165241336 | 0.289409315483704 | 0.04678251927496
17 | 0.12290156351699 | 0.284982917588031 | 0.592115518894979
18 | 0.826726567679996 | 0.173273426274487 | 6.04551768703297e-09
19 | 0.826726567679996 | 0.173273426274487 | 6.04551768703297e-09
20 | 0.38637457408413 | 0.38848495778712 | 0.22514046812875
(20 rows)
         返回预测类别值:
\x off
drop table if exists t1_prd;
select madlib.multinom_predict('t1_output', 't1', 't1_prd', 'response');
-- 显示预测值
select t0.id, t1.y realvalue, t0.category predict,
case when t1.y = t0.category then 'T' else 'F' end istrue
from t1_prd t0, t1
where t0.id = t1.id
order by id;
        结果: id | realvalue | predict | istrue
----+-----------+---------+--------
1 | 1 | 1 | T
2 | 1 | 1 | T
3 | 2 | 1 | F
4 | 2 | 2 | T
5 | 3 | 2 | F
6 | 3 | 3 | T
7 | 2 | 3 | F
8 | 2 | 2 | T
9 | 1 | 1 | T
10 | 3 | 3 | T
11 | 1 | 2 | F
12 | 1 | 3 | F
13 | 1 | 1 | T
14 | 2 | 2 | T
15 | 1 | 1 | T
16 | 1 | 1 | T
17 | 3 | 3 | T
18 | 1 | 1 | T
19 | 1 | 1 | T
20 | 2 | 2 | T
(20 rows)
        可以看到该模型在源数据上的预测正确率只有75%。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐