京公网安备 11010802034615号
经营许可证编号:京B2-20210330
sas字符变量基于iv值的最优分类
1.IV的用途
IV的全称是Information Value,中文意思是信息价值,或者信息量。
我们在用逻辑回归、决策树等模型方法构建分类模型时,经常需要对自变量进行筛选。比如我们有200个候选自变量,通常情况下,不会直接把200个变量直接放到模型中去进行拟合训练,而是会用一些方法,从这200个自变量中挑选一些出来,放进模型,形成入模变量列表。那么我们怎么去挑选入模变量呢?
挑选入模变量过程是个比较复杂的过程,需要考虑的因素很多,比如:变量的预测能力,变量之间的相关性,变量的简单性(容易生成和使用),变量的强壮性(不容易被绕过),变量在业务上的可解释性(被挑战时可以解释的通)等等。但是,其中最主要和最直接的衡量标准是变量的预测能力。
“变量的预测能力”这个说法很笼统,很主观,非量化,在筛选变量的时候我们总不能说:“我觉得这个变量预测能力很强,所以他要进入模型”吧?我们需要一些具体的量化指标来衡量每自变量的预测能力,并根据这些量化指标的大小,来确定哪些变量进入模型。IV就是这样一种指标,他可以用来衡量自变量的预测能力。类似的指标还有信息增益、基尼系数等等。
2.对IV的直观理解
从直观逻辑上大体可以这样理解“用IV去衡量变量预测能力”这件事情:我们假设在一个分类问题中,目标变量的类别有两类:Y1,Y2。对于一个待预测的个体A,要判断A属于Y1还是Y2,我们是需要一定的信息的,假设这个信息总量是I,而这些所需要的信息,就蕴含在所有的自变量C1,C2,C3,……,Cn中,那么,对于其中的一个变量Ci来说,其蕴含的信息越多,那么它对于判断A属于Y1还是Y2的贡献就越大,Ci的信息价值就越大,Ci的IV就越大,它就越应该进入到入模变量列表中。
3.IV的计算
前面我们从感性角度和逻辑层面对IV进行了解释和描述,那么回到数学层面,对于一个待评估变量,他的IV值究竟如何计算呢?为了介绍IV的计算方法,我们首先需要认识和理解另一个概念——WOE,因为IV的计算是以WOE为基础的。
3.1WOE
WOE的全称是“Weight of Evidence”,即证据权重。WOE是对原始自变量的一种编码形式。
要对一个变量进行WOE编码,需要首先把这个变量进行分组处理(也叫离散化、分箱等等,说的都是一个意思)。分组后,对于第i组,WOE的计算公式如下:
其中,pyi是这个组中响应客户(风险模型中,对应的是违约客户,总之,指的是模型中预测变量取值为“是”或者说1的个体)占所有样本中所有响应客户的比例,pni是这个组中未响应客户占样本中所有未响应客户的比例,#yi是这个组中响应客户的数量,#ni是这个组中未响应客户的数量,#yT是样本中所有响应客户的数量,#nT是样本中所有未响应客户的数量。
从这个公式中我们可以体会到,WOE表示的实际上是“当前分组中响应客户占所有响应客户的比例”和“当前分组中没有响应的客户占所有没有响应的客户的比例”的差异。
对这个公式做一个简单变换,可以得到:
变换以后我们可以看出,WOE也可以这么理解,他表示的是当前这个组中响应的客户和未响应客户的比值,和所有样本中这个比值的差异。这个差异是用这两个比值的比值,再取对数来表示的。WOE越大,这种差异越大,这个分组里的样本响应的可能性就越大,WOE越小,差异越小,这个分组里的样本响应的可能性就越小。
关于WOE编码所表示的意义,大家可以自己再好好体会一下。
3.2 IV的计算公式
有了前面的介绍,我们可以正式给出IV的计算公式。对于一个分组后的变量,第i 组的WOE前面已经介绍过,是这样计算的:
同样,对于分组i,也会有一个对应的IV值,计算公式如下:
有了一个变量各分组的IV值,我们就可以计算整个变量的IV值,方法很简单,就是把各分组的IV相加:
其中,n为变量分组个数。
还是简单粗暴上代码吧!
options compress=yes mprint validvarname=any;
libname center1 oracle user=datacenter password=datacenter path=datacenter schema=MFBMSAPP;
libname center oracle user=datacenter password=datacenter path=datacenter;
libname oracle oracle user=DATAHOUSE password=DATAHOUSE path=DATAHOUSE schema=DATAHOUSE;
libname mydata oracle user=zhanpx password=000000 path=DATAHOUSE ;
libname raw"F:\data";
%macro GValue(BinDS, Method, M_Value);
proc sql noprint;
%local i j R N;
select max(bin) into : R from &BinDS;
select sum(total) into : N from &BinDS;
%do i=1 %to &R;
%local N_&i._1 N_&i._2 N_&i._s N_s_1 N_s_2;
Select sum(Ni1) into :N_&i._1 from &BinDS where Bin =&i ;
Select sum(Ni2) into :N_&i._2 from &BinDS where Bin =&i ;
Select sum(Total) into :N_&i._s from &BinDS where Bin =&i ;
Select sum(Ni1) into :N_s_1 from &BinDS ;
Select sum(Ni2) into :N_s_2 from &BinDS ;
%end;
quit;
%if (&Method=4) %then %do; /* Information value */
%local IV;
%let IV=0;
%do i=1 %to &r;
%if (&&N_&i._1=.) or (&&N_&i._1=0) or
(&&N_&i._2=.) or (&&N_&i._2=0) or
(&N_s_1=) or (&N_s_1=0) or
(&N_s_2=) or (&N_s_2=0) %then %do ;
%let &M_Value=.;
%return;
%end;
end;
%do i=1 %to &r;
%let IV = %sysevalf(&IV + (&&N_&i._1/&N_s_1 - &&N_&i._2/&N_s_2)*%sysfunc(log(%sysevalf(&&N_&i._1*&N_s_2/(&&N_&i._2*&N_s_1)))) );
%end;
%let &M_Value=&IV;
%end;
%mend;
%macro CalcMerit(BinDS, ix, method, M_Value);
%local n_11 n_12 n_21 n_22 n_1s n_2s n_s1 n_s2;
proc sql noprint;
select sum(Ni1) into :n_11 from &BinDS where i<=&ix;
select sum(Ni1) into :n_21 from &BinDS where i> &ix;
select sum(Ni2) into : n_12 from &BinDS where i<=&ix ;
select sum(Ni2) into : n_22 from &binDS where i> &ix ;
select sum(total) into :n_1s from &BinDS where i<=&ix ;
select sum(total) into :n_2s from &BinDS where i> &ix ;
select sum(Ni1) into :n_s1 from &BinDS;
select sum(Ni2) into :n_s2 from &BinDS;
quit;
%if (&method=4) %then %do;
%local IV;
%let IV=%sysevalf( ((&n_11/&n_s1)-(&n_12/&n_s2))*%sysfunc(log(%sysevalf((&n_11*&n_s2)/(&n_12*&n_s1))))
+((&n_21/&n_s1)-(&n_22/&n_s2))*%sysfunc(log(%sysevalf((&n_21*&n_s2)/(&n_22*&n_s1)))) );
%let &M_Value=&IV;
%return;
%end;
%mend;
%macro BestSplit(BinDs, Method, BinNo);
%local mb i value BestValue BestI;
proc sql noprint;
select count(*) into: mb from &BinDs where Bin=&BinNo;
quit;
%let BestValue=0;
%let BestI=1;
%do i=1 %to %eval(&mb-1);
%let value=;
%CalcMerit(&BinDS, &i, &method, Value);
%if %sysevalf(&BestValue<&value) %then %do;
%let BestValue=&Value;
%let BestI=&i;
%end;
%end;
data &BinDS;
set &BinDS;
if i<=&BestI then Split=1;
else Split=0;
drop i;
run;
proc sort data=&BinDS;
by Split;
run;
data &BinDS;
retain i 0;
set &BinDs;
by Split;
if first.split then i=1;
else i=i+1;
run;
%mend;
%macro CandSplits(BinDS, Method, NewBins);
proc sort data=&BinDS;
by Bin PDV1;
run;
%local Bmax i value;
proc sql noprint;
select max(bin) into: Bmax from &BinDS;
%do i=1 %to &Bmax;
%local m&i;
create table Temp_BinC&i as select * from &BinDS where Bin=&i;
select count(*) into:m&i from Temp_BinC&i;
%end;
create table temp_allVals (BinToSplit num, DatasetName char(80), Value num);
run;quit;
%do i=1 %to &Bmax;
%if (&&m&i>1) %then %do;
%BestSplit(Temp_BinC&i, &Method, &i);
data temp_trysplit&i;
set temp_binC&i;
if split=1 then Bin=%eval(&Bmax+1);
run;
Data temp_main&i;
set &BinDS;
if Bin=&i then delete;
run;
Data Temp_main&i;
set temp_main&i temp_trysplit&i;
run;
%let value=;
%GValue(temp_main&i, &Method, Value);
proc sql noprint;
insert into temp_AllVals values(&i, "temp_main&i", &Value);
run;quit;
%end;
%end;
proc sort data=temp_allVals;
by descending value;
run;
data _null_;
set temp_AllVals(obs=1);
call symput("bin", compress(BinToSplit));
run;
Data &NewBins;
set Temp_main&Bin;
drop split;
run;
proc datasets nodetails nolist library=work;
delete temp_AllVals %do i=1 %to &Bmax; Temp_BinC&i temp_TrySplit&i temp_Main&i %end; ;
run;
quit;
%mend;
%macro ReduceCats(DSin, IVVar, DVVar, Method, Mmax, DSVarMap);
proc freq data=&DSin noprint;
table &IVVar*&DVvar /out=Temp_cross;
table &IVVar /out=Temp_IVtot;
run;
proc sort data=temp_cross;
by &IVVar;
run;
proc sort data= temp_IVTot;
by &IVvar;
run;
data temp_cont;
merge Temp_cross(rename=count=Ni2 ) temp_IVTot (rename=Count=total);
by &IVVar;
PDV1=Ni2/total;
Ni1=total-Ni2;
label Ni2= total=;
if &DVVar=1 then output;
drop percent &DVVar;
run;
proc sort data=temp_cont;
by PDV1;
run;
%local m;
data temp_cont;
set temp_cont (Rename=&IVVar=Var);
i=_N_;
Bin=1;
call symput("m", compress(_N_));
run;
%local Nbins ;
%let Nbins=1;
%DO %WHILE (&Nbins <&MMax);
%CandSplits(temp_cont, &method, Temp_Splits);
Data Temp_Cont;
set Temp_Splits;
run;
%let NBins=%eval(&NBins+1);
%end;
data &DSVarMap ;
set temp_cont(Rename=Var=&IVVar);
drop Ni2 PDV1 Ni1 i ;
label Bin ='New Category Group'
Category ='Old Category Group'
total ='Number of Records';
run;
proc sort data=&DSVarMap;
by Bin;
run;
proc datasets library=work nodetails nolist;
delete temp_cont temp_cross temp_ivtot temp_Splits;
run;quit;
%mend;
%let DSin=raw.jxl_total_3;
%let IVVar=PROVINCE;
%let DVVar=APPL_STATUS_1;
%let Method=4;
%let Mmax=5;
%let DSVarMap=aa;
%ReduceCats(&DSin., &IVVar., &DVVar., &Method., &Mmax.,&DSVarMap.);
DSin:填入原数据集;
ivvar:填入要分段的变量
dvvar:因变量
method:这里就填4,至于为什么你别管。
mmax:填入你想分几组;
DSVarMap:填入输出的数据集;
代码我已经调试过了,可以直接用的
现在我们来看前后结果:
PROVINCE_1是分段后的iv(0.06475553399),至于为什么是6组,不是5组,是因为还有缺失。PROVINCE是分段前的iv(0.0677179533)值。首先我们知道iv值会随着分的组数越多iv值就越高。但是我们经过最优分段之后,虽说iv值小了,但是小的幅度是可以接受,降的基数也是比原来少了很多,更有助我们之后的模型拟合。数据分析师培训
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
CDA数据分析师 出品 作者:李诗怡 1. 销售漏斗阶段判断 题目:销售漏斗模型中,通过广告、社交媒体等方式触达品牌信息(如浏览品 ...
2026-09-07在Python数据分析中,Pandas库的DataFrame是最核心、最常用的结构化数据表对象,类似于Excel的二维表格,具备规整的行列结构、字 ...
2026-09-07在数据分析、经营复盘、业绩预测与经济统计工作中,平均增速(平均增长率)是衡量数据长期变化趋势、业务发展快慢的核心指标。不 ...
2026-09-07 很多数据分析师精通Excel单元格操作,但当被问到“表结构数据的基本处理单位是什么”“字段和记录的本质区别”“为什么表结 ...
2026-09-07随着大数据技术的快速发展,商业竞争逐步从传统的经验式经营转变为数据驱动的精细化运营。海量的用户行为数据、交易数据、运营数 ...
2026-09-04CDA数据分析师 出品 作者:李诗怡 1. 波士顿矩阵(BCG Matrix) 定义: BCG于1970年提出的业务组合分析工具,以"市场增长率"(纵 ...
2026-09-04 数据分析师八成以上的时间在和数据表格打交道,但许多人拿到Excel后习惯性地先算、先分析,结果回头发现漏了一列关键数据, ...
2026-09-04数据透视表是Excel与Power BI中最核心的数据分析工具,具备快速汇总、维度拆分、动态筛选的能力,可高效完成数据归类与统计展示 ...
2026-09-03在Power BI数据分析可视化场景中,堆积柱状图+折线图是最常用的复合图表组合。堆积柱状图适合展示各细分维度当期数值、结构占比 ...
2026-09-03 很多数据分析师每天与Excel打交道,但当被问到“表格结构数据的基本处理单位是什么”“数据类型误判会引发哪些分析错误”“ ...
2026-09-03CDA数据分析师 出品 作者:李诗怡 一、8个核心数据清洗函数 1. TRIM:一键清除多余空格(最常用) 作用:仅保留文本中"单词/字 ...
2026-09-02数据分析的核心并非单纯操作工具、整理报表或绘制图表,而是依靠科学的思维逻辑挖掘数据价值、解释业务现象、指导经营决策。在完 ...
2026-09-02在社会经济、产业研究、区域治理与大数据实证分析中,面板数据是最具研究价值的数据类型。面板数据同时包含截面维度与时间维度信 ...
2026-09-02 很多数据分析师能熟练计算均值、标准差,但当被问到“如何用一张图让业务方3秒内看懂核心结论”“面对不同数据类型该怎么选 ...
2026-09-02在数据驱动决策的体系中,数据分析按照分析目的可分为描述性分析、诊断性分析、预测性分析与指导性分析四大类型。其中,诊断性分 ...
2026-09-01网络请求是Python爬虫开发、接口测试、数据拉取的核心基础功能,Python生态中主要依靠 urllib 和 requests 两大库实现HTTP请求操 ...
2026-09-01 很多数据分析师面对业务问题时,常常感到“知道要分析,却不知道用什么方法”。其实,数据分析并非无章可循——从三大基础范 ...
2026-09-01在数据库设计与业务数据维护中,自增ID是数据表最常用的主键字段,用于唯一标识每一条业务数据,正常状态下ID应保持连续递增。但 ...
2026-08-31在数理统计、数据分析、经济测算与日常量化评估中,平均值是刻画数据集中趋势、反映整体水平的基础核心指标。在实际应用中,最常 ...
2026-08-31在数据驱动的时代,数据分析早已不是“凭经验、靠感觉”的零散操作,而是一套具备固定逻辑、标准化流程的系统方法——这就是数据 ...
2026-08-31