【SAS】変数を区分値化する

たとえば、確率を1%区切りにして、1%の集団での契約確率を出したいときなどには、連続値の確率を1%ごとの区分値化する必要がある。(データをエクセルに移して、図を描きたいときとかですね)

PROBが確率で0から1の連続値が入っている変数だとすると

CAT_PROB = INT(PROB * (10 ** 2)) / 10 ** 2;

というようにすると、小数点2位以下が切り捨てられて、0.01区切り(1%区切り)の区分値となる。

【Python】MacでPythonの機械学習系ライブラリ入れようとしたら、fortranが無いって怒られた

インストールしたいもの

homebrewとpipで↓のライブラリを入れたい

  • NumPy
  • pandas
  • matplotlib
  • iPython
  • SciPy

前提

homebrewとpythonとpipはインストール済み
(pyenvでpython2とpython3を共存させるとか、パスの通し方などは別途検索してください)

homebrewのインストール
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Homebrew — OS X用パッケージマネージャー

pythonのインストール
brew install python
pipのインストール
curl -kL https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python

Installation — pip 6.0.8 documentation

ライブラリインストール

pipさえ入ってしまえば、以下のコマンドで簡単にインストールできるはずでした…
(pyenvでAnacondaをインストールすれば良かったんじゃない?ということはあとで気づいた)

pip install NumPy
pip install pandas
pip install matplotlib
pip install iPython
pip install SciPy

SciPyをインストールしている際に、「Fortranコンパイラが無いけどどうなってるの?」とエラーが返ってきました。

Fortranのインストール

homebrewでfortranをインストールするコマンドは次の通りです。

brew install gcc --all-language
# gcc単独ではダメで、オプションで全ての言語と指定する必要があるみたいです
# brew install gfortranは使えなくなったみたいです

これでfortranが入ったので、心置きなくpip install SciPyと打てました。
おしまい。

【SAS】正規表現の取り扱い

SASPerl仕様の正規表現を使ってみよう

SAS正規表現を使用したい場合はPRXの関数を使うことになります。
ただし、2バイト文字の取り扱いには非常に苦労しました。
SASはShift-JISとあまり相性が良くないと思います。
そのくせ、日本語版のSAS EGとかだとExcelから読み込むデータセット名がデフォルト2バイト文字になったりするんだけど、怖いから英語名に直しています)
正規表現 - CatTail Wiki*

PRX関数を使う前の前処理

やっておくと良い前処理は次の通り

  • TRIM関数とLEFT関数で前後の空白を除去
  • KCOMPRESS関数で中間の空白を除去
  • KTRANSLATE関数で全角英数を半角英数に置換
  • TRANWRD関数で全角から半角に置換しておきたい文字列を置換

住所で3桁以上の数字を検索するときはこんな感じ

DATA;
  ADD = '東京都品川区広町2丁目1-306';
  /** 前処理 **/
  ADD_WRD = TRANWRD(KTRANSLATE(KCOMPRESS(TRIM(LEFT(ADD)), "  "), "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"), "丁目", "-");
  /** 3桁以上の数字が含まれるか検索 **/
  ADD_NUM = PRXMATCH('/[0-9]{3,}/', ADD_WRD);
RUN;

【SAS】グループで最大値を持つレコードの抽出

グループで最大値を持つレコードを取りだそう!

たとえば、次の様なテーブルがあったとして
f:id:tetchi-kun:20150109150945p:plain
同一IDで最大の金額を持つレコードを取り出した次の様なテーブルが作りたいとします。
f:id:tetchi-kun:20150109145815p:plain

並び替えて最初のレコードを取り出す

PROC SQLだけで書けそうで書けなかったので、昔やった並び替えて最後のレコードを取り出すという方式でやってみることにしました。

/** IDと金額順に並び替える(PROC SORTでも可) **/
PROC SQL;
  CREATE TABLE data2 AS
  SELECT
     ID
    ,取引方法
    ,金額
  FROM data1
  ORDER BY ID, 金額;
QUIT;

/** 最後のレコードだけ取り出す **/
DATA data3;
  SET data2;
  BY ID;
  IF LAST.ID THEN OUTPUT;
RUN;

SQLで書いてみる

ちょっと調べてみたら、SQLでも書けました。
サブクエリ使えば良かったんですね。

PROC SQL;
  CREATE TABLE data2 as
  SELECT
     ID
    ,取引方法
    ,金額
  FROM data1
  INNER JOIN (SELECT ID, max(金額) FROM data1 GROUP BY ID)
    AS data3 on data1.ID = data3.ID;
QUIT;

【SAS】ROC曲線のAUCを計算する方法

SASのLOGISTICプロシジャでAUC計算

SASでロジスティック回帰などを実行する際にROC曲線を描いてAUCを計算したいと思うことがあるだろう。
その場合、もちろんPROC LOGISTICのオプションでROC曲線とAUCを出すことができる。

プログラム例
/** LOGISTICプロシジャの実行 **/
PROC LOGISTIC DATA=data1 descending;
  MODEL y=x /outroc=roc;
RUN;

/** ROC曲線の作成 **/
PROC GPLOT DATA=roc;
  PLOT _sensit_*_1mspec_;
  SYMBOL1 i=join v=none;
RUN;
LOGISTICプロシジャの出力例
     Association of Predicted Probabilities and Observed Responses

   Percent Concordant     66.7     Somers' D     0.333
   Percent Discordant     33.3     Gamma         0.333
   Percent Tied            0.0     Tau-a         0.190
   Pairs                    12     c             0.667 ← この値

Technical Support
※上記の出力例で「← この値」で示した「c」の値が、AUCとなる。

LOGISTICのオプションが使えない場合

ただ、実際にやってみたらうまくいかなかった。(残念)
うまくいかなかったところは2つ。

  1. メモリ不足が原因かPROC GPLOTで曲線を描けなかった
  2. ロジスティック回帰のモデルをinmodelで使用する場合には、LOGISTICプロシジャの出力例が出なかった
LOGISTICでINMODELの使用例
/** LOGISTICプロシジャでINMODELを使う **/
PROC LOGISTIC INMODEL=inmodel;
  SCORE DATA=indata OUT=outdata OUTROC=roc;
RUN;

というわけで、AUCとか計算してくれる関数とかないかなと頑張って探してみた結果、ありました。
ウィルコクソンの順位和検定を利用してAUC計算しています。

AUCを計算するSASマクロ
%macro AUC( dsn, Target, score);
ods select none;
ods output WilcoxonScores=WilcoxonScore;
proc npar1way wilcoxon data=&dsn ;
     where &Target^=.;
     class &Target;
     var  &score; 
run;
ods select all;

data AUC;
    set WilcoxonScore end=eof;
    retain v1 v2 1;
    if _n_=1 then v1=abs(ExpectedSum - SumOfScores);
    v2=N*v2;
    if eof then do;
       d=v1/v2;
       Gini=d * 2;    AUC=d+0.5;    
       put AUC=  GINI=;
       keep AUC Gini;
     output;
   end;
run;
%mend;

SAS Programming for Data Mining: AUC calculation using Wilcoxon Rank Sum Test
ROC曲線は、面倒だったので、エクセルで描きました。

【統計基礎】変動係数

ばらつきを見る尺度として標準偏差があるが、ばらつきを比較する尺度としては必ずしも適切では無い。
個々の値の大きい(平均値の大きい)集団の方が、標準偏差が大きくなる可能性が高いからである。

この場合、標準偏差をそれぞれの平均で割った変動係数(CV)がばらつきの比較に用いられる。

{ \displaystyle
CV=\frac{\sqrt{\sigma^2}} {\overline x}
}

たとえば、幼稚園児と高校生の身長を比較した場合、標準偏差は平均値の大きい高校生の方が大きいが、変動係数は幼稚園児が大きいことから、幼稚園児の方が高校生に比べて身長にばらつきのあることがわかる。