---0. 소개 



 PL/SQL을 통해서 엔트로피를 구하는 프로시져입니다. 보통 의사결정나무(Decision Tree)를 구현할 때에 엔트로피를 구할일이 종종 생기는데 윈도우의 cmd 환경에서 정보획득량을 엔트로피 계산을 통해 구할 때 쓸 수 있는 패키지 입니다. 


 보통 R 언어의 통계패키지에서 회귀분석은 lm()으로 굉장히 간단하게 구할 수 있고 이러한 정보획득량을 구할 때 쓸 수있는 패키지 또한 많기 때문에 저처럼 피치못할(?) 사정으로 PL/SQL을 쓰시는 분들이나 연습하시는 분들이 참고용으로 보시면 좋을 것 같습니다.






---1. 테이블 생성 스크립트 및 패키지 명세 작성


--- 테이블 생성 스크립트


drop table  entropy_test2;


create  table  entropy_test2
( cust_name  varchar2(20),
  card_yn     varchar2(10),
  review_yn   varchar2(10),
  before_buy_yn  varchar2(10),
  buy_yn   varchar2(10) );


insert  into entropy_test2 values ('SCOTT','Y','Y','Y','Y');
insert  into entropy_test2 values ('SMITH','Y','Y','Y','Y');
insert  into entropy_test2 values ('ALLEN','N','N','Y','N');
insert  into entropy_test2 values ('JONES','Y','N','N','Y');
insert  into entropy_test2 values ('WARD','Y','Y','Y','Y');


commit;



--- 패키지 명세

create or replace package entropy

is

procedure aft_entropy ( p_table in varchar2,

  p_col_1 in varchar2 ) ;


end entropy;

/



패키지 안에 프로시져 한개만 넣을거면 도대체 왜 패키지화를 시키느냐.. 하면 할말은 없지만 언젠가 패키지에 프로시져를 가득 담을 날을 그리며 한번씩 실행해봅시다.






---2. 패키지 바디 작성


Create or replace package body entropy

is

procedure aft_entropy 

( p_table in varchar2,

  p_col_1 in varchar2 )

Is 


v_stmt varchar2(2000) ;

v_col  varchar2(20)   ;

cnt1 number(10, 7)  ;

buy number(10, 7)  ;

no_buy number(10, 7)  ;

temp number(10, 7) := 0 ;

v_all number(10, 7) := 0 ;

res number(10, 7) := 0;

v_change_name varchar2(100) ;


type refcursor is ref cursor ;

emp_cv  refcursor ;


cursor emp_cursor is

  select column_name

        from cols

where table_name = upper(p_table)

and column_name not in ('CUST_NAME', upper(p_col_1));



begin


for emp_record in emp_cursor loop


v_stmt := 'select ' || emp_record.column_name || ' , count(*) as cnt1,  

                  sum(decode(buy_yn, ''Y'', 1, 0)) as buy_cnt, 

                  sum(decode(buy_yn, ''Y'', 0 ,1)) as no_buy_cnt 

        from entropy_test2 

      group by ' || emp_record.column_name ;


open emp_cv for v_stmt ;

loop 

fetch emp_cv into v_col, cnt1, buy, no_buy ;

exit when emp_cv%notfound ;


  if v_col = 'Y' then 

             

              if buy != 0 then 

             

                temp := temp + ( (buy/-cnt1)*log(2,(buy/cnt1)) ) ; 

           end if; 

  

          if no_buy != 0 then 

                 temp := temp  + ( (no_buy/-cnt1)*log(2,(no_buy/cnt1)) ) ; 

  

            end if; 

  

            res := res + (cnt1/5) * temp;

temp := 0; 

  

          elsif v_col = 'N' then 

  

            if buy != 0 then 

                temp := temp + ( (-buy/cnt1)*log(2,(buy/cnt1)) ) ; 

            end if; 

  

            if no_buy != 0 then 

                temp := temp  + ( (-no_buy/cnt1)*log(2,(no_buy/cnt1)) ) ; 

            end if; 

  

            res := res + (cnt1/5) * temp;

temp := 0; 

  

            end if; 

end loop;


dbms_output.put_line ( emp_record.column_name || ' : ' || res );

res := 0;


end loop;

end aft_entropy;


end entropy;








---3. 실행



exec entropy.aft_entropy('ENTROPY_TEST2', 'BUY_YN');



exec : 패키지 혹은 프로시져 실행을 위한 명령어

entropy.aft_entropy : 패키지명.프로시져명 의 형태로 불러오게 됩니다.
('ENTROPY_TEST2', 'BUY_YN') : 내부에 ' '처리가 안되어있기 때문에 테이블명과 컬럼명을 넘기실 때 꼭 Single quotation으로 감싸주셔야 잘 실행이 됩니다.


구현된 코드로는 독립변수까지는 지정할 수 없고, 분석을 원하는 범주형 자료가 Y나 N으로 이뤄져있을 때만 쓸 수 있다는 한계가 있습니다.






---4. 결과



CARD_YN : 0

REVIEW_YN : 0.4

BEFORE_BUY_YN : 0.6490225










반응형
Posted by JoeSung
,