sas 變量降維、變量聚類、變量去除共線性

今天的文章的使用場(chǎng)景是,是因?yàn)槲液軣嶂蕴幚砟欠N別人不喜歡整理的各種流水?dāng)?shù)據(jù),例如運(yùn)營(yíng)商通話流水啊,銀行卡流水啊,信用卡流水等等,那么這些數(shù)據(jù)做衍生變量有個(gè)經(jīng)常會(huì)碰到的問(wèn)題,就是像這種“最近一天的通話次數(shù)”有可能跟“最近三天的通話次數(shù)”這種相關(guān)性很強(qiáng),但是在擬合的之后,這種相關(guān)性強(qiáng)的只能進(jìn)一個(gè),不然共線性就來(lái)找你啦,所以這時(shí)候你要處理是:1、你要讓那個(gè)變量進(jìn)去。2、那些變量是一類的,他們共線性在一起很強(qiáng)。

你跟我說(shuō),這誰(shuí)不會(huì)啊,這不就是vif嘛,一看我就知道那幾個(gè)相關(guān)性高了,是的,我們經(jīng)常會(huì)有vif,但是模型做多了,你會(huì)發(fā)現(xiàn),vif無(wú)論要多方便,但是有時(shí)候vif過(guò)了,但是還是存在共線性,所以你這時(shí)候還是要去看相關(guān)矩陣。所以vif并不會(huì)萬(wàn)能,我今天也不是要說(shuō)相關(guān)矩陣,我今天要說(shuō)的是sas的一個(gè)過(guò)程步叫做“proc varclus”,看著是不是很像聚類的那個(gè)過(guò)程步,是這個(gè)這個(gè)是變量的聚類,將相關(guān)性強(qiáng)的變量聚在一起,這里我不展開(kāi)細(xì)講,我給你鏈接,你自己去看,我今天不是來(lái)介紹這個(gè)過(guò)程的,我是來(lái)給代碼~~

鏈接在這里:http://blog.sina.com.cn/s/blog_5d3b177c0100equm.html

https://wenku.baidu.com/view/7c4929f34693daef5ef73de1.html。

這是思路

? 代碼主要實(shí)現(xiàn)其實(shí)就是對(duì)變量降維,而且是降維后,給你提取同類變量中那個(gè)最好的。代碼的思路是這樣子的:

1、?輸入一批數(shù)值變量,現(xiàn)在的代碼只能實(shí)現(xiàn)數(shù)值變量的。我建議兩百以內(nèi),你想要一千,我絕不攔你。

2、?使用proc varclus過(guò)程將變量聚類,控制群的數(shù)目

????????Minclusters(minc)=正整數(shù):指定最少要有幾個(gè)群。

????????Maxclusters(maxc)=正整數(shù):指定最多有幾個(gè)群。

????????Proportion(percent)=正有理數(shù):群主成份所能解釋的變異數(shù)百分比。注意,這里proportion=0.75與percent=75是一樣的。

????????Maxeigen=實(shí)數(shù):規(guī)定每個(gè)群內(nèi)第二特征值的最大可能值。

????請(qǐng)自行選擇,本人最常使用第二特征根。

3、?每一簇的變量都去跑一遍iv,再結(jié)合變量聚類結(jié)果指標(biāo)和業(yè)務(wù)進(jìn)行變量篩選。?

????挑選變量的原則如下:

????????選擇IV值最大的變量

????????選擇1-R平方最小的變量

????????選擇業(yè)務(wù)解釋性好的變量。

4、 選擇取出這一簇里面,iv最高的或者1-R方最小的。

5、?我知道你會(huì)說(shuō),但是我想看下其他變量的怎么樣,我也給你保留了!

代碼:

%macro varclus(DSin=,target=,Maxclusters=,group=,method=,DSout=);

*method=1每組取iv最大;method=2每組取1-R方最小;

%let lib=%upcase(%scan(&DSin.,1,'.'));

? ? %let dname=%upcase(%scan(&DSin.,2,'.'));

proc sql noprint;

? ? ? ? select name into:name_list? SEPARATED by " "

? ? ? ? from sashelp.VCOLUMN

? ? ? ? where left(libname)="&lib." and left(memname)="&dname."? and lowcase(name)^=lowcase("user_id.") and lowcase(name)^=lowcase("&target") ;

? ? quit;

? %put &name_list.;

ods listing close;

ods output clusterquality=summary

? ? ? ? ? rsquare=clusters;

proc varclus data=&DSin.

? ? ? ? ? ? Minclusters=2

Maxclusters=&Maxclusters.

percent=75

Maxeigen=7

? ? ? ? ? ? outtree=fortree

? ? ? ? ? ? short;

var &name_list.;

run;

ods listing;

data _null_;

? ? set summary;

? ? call symput('nvar',compress(NumberOfClusters));

run;

data clusters_&nvar;

set clusters;

where NumberOfClusters=&nvar;

run;

data var_select;

set clusters_&nvar;

? ? retain Cluster1;

? ? if Cluster~="" then Cluster1=Cluster;

run;

data _null_;

set var_select;

call symputx(compress("varname"||_n_),compress(Variable));

call symputx(compress("n"),compress(_n_));

run;

data total_result;

length varname$30.;

length group_id 8.;

length new_min 8.;

length new_max 8.;

length interval$30.;

length group_num 8.;

length bad_num 8.;

length good_num 8.;

length good_rate 8.;

length bad_rate 8.;

length woe 8.;

length iv 8.;

run;

%do i=1 %to &n.;

%put &&varname&n.;

proc rank data=&DSin.(keep =&&varname&i. &target.) out = tmp ties = low groups = &group.;

var &&varname&i.;

ranks new_var;

run;

proc sql noprint;

create table result1 as

select distinct

"&&varname&i." as varname,

new_var,

min(&&varname&i.) as min,

max(&&varname&i.) as max,

case when new_var^=. then compress(put(min(&&varname&i.),8.)||"-"||put(max(&&varname&i.),8.)) else "null " end as interval,

count(*) as group_num,

sum(&target.) as bad_num,

count(*)-sum(&target.) as good_num

from tmp

group by new_var;

quit;

proc sql noprint;

select count(*)into:good_total from tmp(where=(&target.=0));

select count(*)into:bad_total from tmp(where=(&target.=1));

create table result2 as

select

varname,

case when new_var=. then 0 else new_var end as group_id,

case when min=min(min) then . else min end as new_min,

case when max=max(max) then . else max end as new_max,

interval,group_num,bad_num,good_num,

good_num/&good_total. as good_rate,

bad_num/&bad_total. as bad_rate,

log((bad_num/&bad_total.)/(good_num/&good_total.)) as woe,

log((bad_num/&bad_total.)/(good_num/&good_total.))*((bad_num/&bad_total.)-(good_num/&good_total.)) as iv

from result1 a;

quit;

proc append base=total_result data=result2 force;run;

proc sql;

create table iv_result as

select distinct varname, sum(iv) as iv

from total_result(where=(varname^=''))

group by varname;

quit;

%end;

/*合并篩選指標(biāo)*/

proc sql noprint;

create table var_select_m as?

select * from var_select as a left join iv_result as b on a.Variable=b.varname;

quit;

/*變量篩選*/

%if &method.=1 %then %do;

proc sort data=var_select_m;

? ? by Cluster1 descending iv /* iv*/;

run;

%end;

%else %do;

proc sort data=var_select_m;

? ? by Cluster1 RSquareRatio /* RSquareRatio*/;

run;

%end;

data var_selected(where=(row=1));

set var_select_m;

? ? if first.Cluster1 then row=1;

? ? else row+1;

? ? by Cluster1;

run;

%global var_clus;

proc sql noprint;

select Variable into :var_clus separated by ' '

? ? from Var_selected;

quit;

%put &var_clus;

data &DSout.;

set &DSin.;

keep target &var_clus;

run;

%mend;


這是代碼講解

varclus(DSin=,target=,Maxclusters=,group=,method=,DSout=)

DSin:你的數(shù)據(jù)集

Maxclusters:填的是你想最多變成多少簇。

Group:跑iv的時(shí)候你想分幾組算iv。

method:method=1每組取iv最大;method=2每組取1-R方最小;

以上就是這個(gè)宏的參數(shù)填寫(xiě),接下來(lái)我跟大家說(shuō)下結(jié)果有哪些。

結(jié)果:這個(gè)結(jié)果產(chǎn)出的全部數(shù)據(jù)集。主要看兩張表:

1、Var_select_d:

保留的是每一簇篩選出來(lái)的變量,如果想換取變量,請(qǐng)參考下一張表。

2、Var_select_m

這張表保存的是每個(gè)簇的各個(gè)變量的指標(biāo)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,734評(píng)論 18 399
  • 身邊的朋友一個(gè)個(gè)的都結(jié)婚了,朋友問(wèn),你呢?親戚說(shuō),找個(gè)差不多的嫁了吧到了30歲就晚了。 前幾年的我聽(tīng)到...
    一年一班閱讀 936評(píng)論 1 0
  • 兜兜轉(zhuǎn)轉(zhuǎn)那山那峰 未知身邊潛伏贏到了最后 還未飲左正餐 即得你兵臨城下的婚訊 身后的護(hù)城墻何時(shí)決了堤 這鎧甲明明偽...
    JS_cdb4閱讀 396評(píng)論 0 1
  • 虹,還是那道美麗的虹 那《童年》的《星》 依然在記憶的河底 悠揚(yáng)燦爛 曾經(jīng) 沉醉在你的歌聲 心弛神往的天籟 陪我走...
    一枚冰兒閱讀 300評(píng)論 0 0
  • A1 老公愛(ài)吃水果,本來(lái)是個(gè)好習(xí)慣,但是他單次吃的量太大,比如吃橘子可以一次吃1斤,吃西瓜可以一次吃一個(gè)。他本身...
    wlhuiyi閱讀 243評(píng)論 0 0

友情鏈接更多精彩內(nèi)容