目录
一、回归方法简介
回归指研究一组随机变量 (Y1 ,Y2 ,…,Yi) 和另一组 (X1,X2,…,Xk) 变量之间关系的统计分析方法,又称多重回归分析。通常前者叫做因变量,后者叫做自变量。
事物之间的关系可以抽象为变量之间的关系。变量之间的关系可以分为两类:一类叫确定关系,也叫函数关系,其特征是一个变量随着其他变量的确定而确定;另一类关系叫相关关系,变量之间的关系很难用一种精确的方法表示出来。例如,通常人的年龄越大血压越高,但人的年龄和血压之间没有确定的数量关系,人的年龄和血压之间的关系就是相关关系。回归方法就是处理变量之间相关关系的一种数学方法。其解决问题的大致方法、步骤如下:
- 收集一组包含因变量和自变量的数据。
- 选定因变量和自变量之间的模型,即一个数学定量关系式,利用数据按照一定准则(如最小二乘法)计算模型中的系数。
- 利用统计分析方法对不同的模型进行比较,找出效果最好的模型。
- 判断得到的模型是否适合于这组数据。
- 利用模型对因变量作出预测或解释。
回归在数据挖掘中是最为基础的方法,也是应用领域和应用场景最多的方法,只要是量化型问题,我们一般都会先尝试用回归方法来研究或分析。
二、Logistic 回归
在回归分析中,因变量 y 可能有两种情形:(1)y 是一个定量的变量,这时就用通常的回归函数对 y 进行回归;(2)y 是一个定性的变量,比如 y=0 或 1,这时就不能用通常的回归函数进行回归,而是使用所谓的 Logistic 回归。Logistic 方法主要应用在研究某些现象发生的概率 p。Logistic 回归模型的基本形式为:
其中,类似于多元线性回归模型中的回归系数。该式表示当自变量为
时,因变量 p 为 1 的概率。对该式进行对数变换,可得:
至此,我们会发现,只要对因变量 p 按照 ln(p/(1-p)) 的形式进行对数变换,就可以将 Logistic 回归问题转化为线性回归问题,此时就可以按照多元线性回归的方法会得到回归参数。但对于定性实践,p 的取值只有 0 和 1(二分类),这就导致 ln(p/(1-p)) 形式失去意义。为此,在实际应用 Logistic 模型的过程中,常常不是直接对 p 进行回归,而是先定义一种单调连续的概率 π,令
有了这样的定义,Logistic 模型就可变形为:
虽然形式相同,但此时的 π 为连续函数。然后只需要对原始数据进行合理的映射处理,就可以用线性回归方法得到回归系数。最后再由 π 和 p 的映射关系进行反映射而得到 p 的值。
三、MADlib 中的 Logistic 回归方法相关函数
MADlib 中的二分类 Logistic 回归模型,对双值因变量和一个或多个预测变量之间的关系建模。因变量可以是布尔值,或者是可以用布尔表达式表示的分类变量。在该模型中,训练函数作为预测变量的函数,描述一次训练可能结果的概率。
1. 训练函数
(1)语法
Logistic 回归训练函数形式如下:
logregr_train( source_table,
out_table,
dependent_varname,
independent_varname,
grouping_cols,
max_iter,
optimizer,
tolerance,
verbose
)
(2)参数
source_table:TEXT 类型,包含训练数据的表名。
out_table:TEXT 类型,包含输出模型的表名。由 logistic 回归训练函数生成的输出表可以具有以下列:
<...> | Text 类型,分组列,取决于 grouping_col 输入,可能是多个列。 |
coef | FLOAT8 类型,回归系数向量。 |
log_likelihood | FLOAT8 类型,对数似然比 l(c)。 |
std_err | FLOAT8[] 类型,系数的标准方差向量。 |
z_stats | FLOAT8[] 类型,系数的 z-统计量向量。 |
p_values | FLOAT8[] 类型,系数的 P 值向量。 |
odds_ratios | FLOAT8[] 类型,比值比 exp(ci)。 |
condition_no | FLOAT8[] 类型,X*X 矩阵的条件数。高条件数说明结果中的一些数值不稳定,产生的模型不可靠。这通常是由于底层设计矩阵中有相当多的共线性所造成的,在这种情况下可能更适合使用其他回归技术。 |
num_iterations | INTEGER 类型,实际迭代次数。如果提供了 tolerance 参数,并且算法在所有迭代完成之前收敛,此列的值将会与 max_iter 参数的值不同。 |
num_rows_processed | INTEGER 类型,实际处理的行数,等于源表中的行数减去跳过的行数。 |
num_missing_rows_skipped | INTEGER 类型,训练时跳过的行数。如果自变量名是 NULL 或者包含 NULL值,则该行被跳过。 |
训练函数在产生输出表的同时,还会创建一个名为 <out_table>_summary 的概要表,具有以下列:
source_table | 源数据表名称。 |
out_table | 输出表名。 |
dependent_varname | 因变量名。 |
independent_varname | 自变量名。 |
optimizer_params | 包含所有优化参数的字符串,形式是‘optimizer=..., max_iter=..., tolerance=...’ |
num_all_groups | 用 logistic 模型拟合了多少组数据。 |
num_failed_groups | 有多少组拟合过程失败。 |
num_rows_processed | 用于计算的总行数。 |
num_missing_rows_skipped | 跳过的总行数。 |
dependent_varname:TEXT 类型,训练数据中因变量列的名称(BOOLEAN 兼容类型),或者一个布尔表达式。
independent_varname:TEXT 类型,评估使用的自变量的表达式列表,一般显式地由包括一个常数 1 项的自变量列表提供。
grouping_cols(可选):TEXT 类型,缺省值为 NULL。和 SQL 中的“GROUP BY”类似,是一个将输入数据集分成离散组的表达式,每个组运行一个回归。此值为 NULL 时,将不使用分组,并产生一个单一的结果模型。
max_iter(可选):INTEGER 类型,缺省值 20,指定允许的最大迭代次数。
optimizer(可选):TEXT 类型,缺省值为‘irls’,指定所使用的优化器的名称:
- ‘newton’或‘irls’ 加权迭代最小二乘。
- ‘cg’ 共轭梯度法。
- ‘igd’ 梯度下降法。
tolerance(可选):FLOAT8 类型,缺省值为 0.0001,连续的迭代次数的对数似然值之间的差异。零不能作为收敛准则,因此当连续两次的迭代差异小于此值时停止执行。
verbose(可选):缺省值为 FALSE,提供训练的详细输出结果。
2. 预测函数
(1)语法
MADlib 提供两个预测函数,预测因变量的布尔值,或预测因变量是“真”的概率值。两个函数语法相同。
预测因变量的布尔值的函数:
logregr_predict(coefficients,
ind_var
)
预测因变量是“真”的概率值的函数:
logregr_predict_prob(coefficients,
ind_var
)
(2)参数
coefficients:DOUBLE PRECISION[] 类型,来自 logregr_train() 的模型系数。
ind_var:自变量构成的 DOUBLE 数组,其长度应该与调用 logregr_train() 函数时,由 independent_varname 参数所赋值的数组相同。
四、Logistic 回归示例
1. 问题提出
企业到金融商业机构贷款,金融商业机构需要对企业进行评估。设评估结果为 0 或 1 两种形式,0 表示企业两年后破产,将拒绝贷款,而 1 表示企业两年后具备还款能力,可以贷款。现在已知 20 家企业(编号 1-20)的三项评价指标值和评估结果,试建立模型对其他 5 家企业(编号 21-25)进行评估。
对于该问题,很明显可以用 Logistic 模型来求解,已知的三项评价指标为自变量,能否贷款的评价结果是因变量。我们可以调用 madlib.logregr_train 函数,用已知的 20 条数据训练,然后调用 madlib.logregr_predict 函数对其他 5 条数据进行预测,还可以用 madlib.logregr_predict_prob 函数得到预测值为“真”的概率。
2. 建立测试数据表并装载原始数据
通常训练数据与被预测数据是不同的数据集合,因此这里分别建立两个表。
drop table if exists source_data;
create table source_data
( id integer not null,
x1 float8,
x2 float8,
x3 float8,
y int);
copy source_data from stdin with delimiter '|';
1 | -62.8 | -89.5 | 1.7 | 0
2 | 3.3 | -3.5 | 1.1 | 0
3 | -120.8 | -103.2 | 2.5 | 0
4 | -18.1 | -28.8 | 1.1 | 0
5 | -3.8 | -50.6 | 0.9 | 0
6 | -61.2 | -56.2 | 1.7 | 0
7 | -20.3 | -17.4 | 1 | 0
8 | -194.5 | -25.8 | 0.5 | 0
9 | 20.8 | -4.3 | 1 | 0
10 | -106.1 | -22.9 | 1.5 | 0
11 | 43 | 16.4 | 1.3 | 1
12 | 47 | 16 | 1.9 | 1
13 | -3.3 | 4 | 2.7 | 1
14 | 35 | 20.8 | 1.9 | 1
15 | 46.7 | 12.6 | 0.9 | 1
16 | 20.8 | 12.5 | 2.4 | 1
17 | 33 | 23.6 | 1.5 | 1
18 | 26.1 | 10.4 | 2.1 | 1
19 | 68.6 | 13.8 | 1.6 | 1
20 | 37.3 | 33.4 | 3.5 | 1
\.
drop table if exists source_data_predict;
create table source_data_predict
( id integer not null,
x1 float8,
x2 float8,
x3 float8,
y int);
copy source_data_predict from stdin with delimiter '|' NULL AS '';
21 | -49.2 | -17.2 | 0.3 |
22 | -19.2 | -36.7 | 0.8 |
23 | 40.6 | 5.8 | 1.8 |
24 | 34.6 | 26.4 | 1.8 |
25 | 19.9 | 26.7 | 2.3 |
\.
2. 训练回归模型
drop table if exists loan_logregr, loan_logregr_summary;
select madlib.logregr_train( 'source_data',
'loan_logregr',
'y',
'array[1, x1, x2, x3]',
null,
20,
'irls'
);
注意本例中我们从列名动态创建自变量数组。如果自变量的数目很大,以至于超过了 PostgreSQL 对于每个表中最多列数的限制时(一个表中的列不能超过 1600 个,这是个硬限制),应该于建立自变量数组,并存储于一个单一列中。
3. 查看回归结果
-- set extended display on for easier reading of output
\x on
select * from loan_logregr;
查询结果:
-[ RECORD 1 ]------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
coef | {-20.3054440772,0.134709458428,1.28765916465,10.7681982398}
log_likelihood | -4.48829442567e-05
std_err | {1101.17383721456,24.8599419656016,49.3232233288482,581.736058622661}
z_stats | {-0.0184398170306725,0.00541873583672866,0.0261065493644831,0.018510453461137}
p_values | {0.985287988438418,0.995676495495108,0.979172353206886,0.98523163833896}
odds_ratios | {1.51864996572236e-09,1.1442042971378,3.62429274574795,47486.3813170937}
condition_no | 271.215610391935
num_rows_processed | 20
num_missing_rows_skipped | 0
num_iterations | 15
variance_covariance | {{1212583.81976583,-25583.8124207287,44737.5274291919,-617222.483665909},{-25583.8124207287,618.016714533079,-1130.75907254962,12251.6705251574},{44737.5274291919,-1130.75907254962,2432.78035954743,-21716.2262122956},{-617222.483665909,12251.6705251574,-21716.2262122956,338416.841901828}}
4. 可选地格式化输出
\x off
select unnest(array['intercept', 'treatment', 'trait_anxiety']) as attribute,
unnest(coef) as coefficient,
unnest(std_err) as standard_error,
unnest(z_stats) as z_stat,
unnest(p_values) as pvalue,
unnest(odds_ratios) as odds_ratio
from loan_logregr;
5. 使用 logistic 回归预测因变量
\x off
select p.id, madlib.logregr_predict(coef, array[1, x1, x2, x3])
from source_data_predict p, loan_logregr m
order by p.id;
结果:
id | logregr_predict
----+-----------------
21 | f
22 | f
23 | t
24 | t
25 | t
(5 rows)
预测的结果是 21、22 两家企业应拒绝贷款,其他三家企业可以贷款。
6. 预测因变量为“真”的概率
\x off
select p.id, madlib.logregr_predict_prob(coef, array[1, x1, x2, x3])
from source_data_predict p, loan_logregr m
order by p.id;
结果:
id | logregr_predict_prob
----+----------------------
21 | 1.22296014464276e-20
22 | 1.88777536644339e-27
23 | 0.999993946936041
24 | 1
25 | 1
(5 rows)
21、22 为“真”的概率几乎为 0,其他三个为“真”的概率为 1。
7. 在训练数据上执行预测函数
\x off
select p.id, madlib.logregr_predict(coef, array[1, x1, x2, x3]), p.y
from source_data p, loan_logregr m
order by p.id;
id | logregr_predict | y
----+-----------------+---
1 | f | 0
2 | f | 0
3 | f | 0
4 | f | 0
5 | f | 0
6 | f | 0
7 | f | 0
8 | f | 0
9 | f | 0
10 | f | 0
11 | t | 1
12 | t | 1
13 | t | 1
14 | t | 1
15 | t | 1
16 | t | 1
17 | t | 1
18 | t | 1
19 | t | 1
20 | t | 1
(20 rows)
可以看到,Logistic 模型预测的结果与训练数据完全一致。
五、Logistic 回归分析时需要注意的问题
实际应用中,以下几个因素对预测模型的可靠性有较大影响。
1. 样本量问题
Logistic 回归分析中,到底样本量多大才算够,这一直是个令许多人困惑的问题。尽管有人从理论角度提出了 Logistic 回归分析中的样本含量估计,但从使用角度来看多数并不现实。直到现在,这一问题尚无广为接受的答案。一般认为,如果样本量小于 100,Logistic 回归的最大似然估计可能有一定的风险,如果大于 500 则显得比较充足。当然,样本大小还依赖于变量个数、数据结构等条件。每一个自变量至少要 10 例结局保证估计的可靠性。注意:这里是结局例数,而不是整个样本例数。
2. 混杂因素的影响
混杂因素一般可以通过三个方面确定:一是该因素对结局有影响;二是该因素在分析因素中的分布不均衡;三是从专业角度来判断,该因素是分析因素与结局中间的一个环节。也就是说,分析因素引起该因素,通过该因素再引起结局。
3. 交互作用的影响
交互作用有时也叫效应修饰,是指在该因素的不同水平(不同取值),分析因素与结局的关联大小有所不同。在某一水平上(如取值为 0)可能分析因素对结局的效应大,而在另一个水平上(如取值为 1)可能效应小。
参考:
- 《大数据挖掘——系统方法与实力分析》:讲述回归方法的基本概念及 Logistic 回归示例。
- Logistic Regression:Madlib官方文档对 Logistic 回归的说明。
- Logistic回归分析时几个需要注意的问题:说明关于样本量等问题。