スライド 1

Similar documents
Proc luaを初めて使ってみた -SASでの処理を条件に応じて変える- 淺井友紀 ( エイツーヘルスケア株式会社 ) I tried PROC LUA for the first time Tomoki Asai A2 Healthcare Corporation

要旨 : データステップ及び SGPLOT プロシジャにおける POLYGON/TEXT ステートメントを利用した SAS プログラムステップフローチャートを生成する SAS プログラムを紹介する キーワード :SGPLOT, フローチャート, 可視化 2

Microsoft Word - sample_adv-programming.docx

プログラミング入門1

4-4 while 文 for 文と同様 ある処理を繰り返し実行するためのものだが for 文と違うのは while 文で指定するのは 継続条件のみであるということ for 文で書かれた左のプログラムを while 文で書き換えると右のようになる /* 読込んだ正の整数値までカウントアップ (for

PowerPoint プレゼンテーション

データ構造の作成 一時 SAS データセットと永久 SAS データセットの作成 テキストファイルから SAS データセットを作成するための DATA ステップの使用例 : Data NewData; Infile "path.rawdata"; Input <pointer-control> var

Microsoft Word - VBA基礎(3).docx

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

sinfI2005_VBA.doc

スライド 1

ご利用のコンピュータを設定する方法 このラボの作業を行うには 事前設定された dcloud ラボを使用するか 自身のコンピュータをセットアップします 詳細については イベントの事前準備 [ 英語 ] とラボの設定 [ 英語 ] の両方のモジュールを参照してください Python を使用した Spar

Java講座

Rmenuフレームワーク


スクールCOBOL2002

PowerPoint プレゼンテーション

情報処理概論(第二日目)

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

スクールCOBOL2002

Exam : A JPN Title : SAS Base Programming for SAS 9 Vendor : SASInstitute Version : DEMO Get Latest & Valid A JPN Exam's Question and Answ

PowerPoint Presentation

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

MMC Unity講座

Exam : 1z1-809-JPN Title : Java SE 8 Programmer II Vendor : Oracle Version : DEMO Get Latest & Valid 1z1-809-JPN Exam's Question and Answers 1 from Ac

メソッドのまとめ

PowerPoint プレゼンテーション

外周部だけ矩形配列

Microsoft Word - VBA基礎(6).docx

NLMIXED プロシジャを用いた生存時間解析 伊藤要二アストラゼネカ株式会社臨床統計 プログラミング グループグルプ Survival analysis using PROC NLMIXED Yohji Itoh Clinical Statistics & Programming Group, A

Microsoft Word Proself-guide4STD+Prof.docx

cp-7. 配列

要旨 : SAS9.4 より Output Derivery System( 以下 ODS) に追加された Report Writing Interface( 以下 RWI) を使用して HTML 形式のレポート作成の実用性と可能性について検討する なお HTML 出力には タグの綺麗さから ODS

概要 ABAP 開発者が SAP システム内の SAP ソースまたは SAP ディクショナリーオブジェクトを変更しようとすると 2 つのアクセスキーを入力するよう求められます 1 特定のユーザーを開発者として登録する開発者キー このキーは一度だけ入力します 2 SAP ソースまたは SAP ディクシ

PowerPoint プレゼンテーション

帳票 Mockup からの RTF 用テンプレート SAS プログラム自動作成ツール Taiho TLF Automated Tool の紹介 伊藤衡気 1 栗矢芳之 2 銭本敦 2 ( 株式会社タクミインフォメーションテクノロジー 1 大鵬薬品工業株式会社 2 )

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

ガイダンス

Sequel のすすめ 私が SQL を嫌いな理由 とみたまさひろ RubyHiroba Sequel のすすめ - 私が SQL を嫌いな理由 Powered by Rabbit 2.0.7

分析のステップ Step 1: Y( 目的変数 ) に対する値の順序を確認 Step 2: モデルのあてはめ を実行 適切なモデルの指定 Step 3: オプションを指定し オッズ比とその信頼区間を表示 以下 このステップに沿って JMP の操作をご説明します Step 1: Y( 目的変数 ) の

Boost.Preprocessor でプログラミングしましょう DigitalGhost

人工知能入門

VelilogHDL 回路を「言語」で記述する

ステップ 2 テンプレートを はめ込む FC2 ブログ専用のセールスレターテンプレートをはめ込む方法を解説します 次のような手順です 1. テンプレートサイトにアクセス 2. セールスレターの背景色を決める 3. サンプルサイトを表示させておく ( 好みの背景色の ) 4. FC2 ブログのテンプレ

Microsoft PowerPoint - å®�æ−•試é¨fi3ㆮ対ç�Œ.pptx

Actual4Test Actual4test - actual test exam dumps-pass for IT exams

intra-mart Accel Platform — IM-Repository拡張プログラミングガイド   初版  

プログラミングI第10回

.NETプログラマー早期育成ドリル ~VB編 付録 文法早見表~

PowerPoint プレゼンテーション

コンピュータ工学講義プリント (7 月 17 日 ) 今回の講義では フローチャートについて学ぶ フローチャートとはフローチャートは コンピュータプログラムの処理の流れを視覚的に表し 処理の全体像を把握しやすくするために書く図である 日本語では流れ図という 図 1 は ユーザーに 0 以上の整数 n

データアダプタ概要

API 連携方式 外部 DLL の呼び出し宣言 外部 DLL の呼び出し宣言のサンプルコード (Microsoft Visual C#.NET の場合 ) プログラムコードの先頭で using System.Runtime.InteropServices; が必要 クラスの内部に以下のような外部 D

テキストファイルの入出力1

C言語講座 ~ファイル入出力編~

Transcription:

SAS ハッシュオブジェクトを利用したデータ集計 - アイテムセットのカウントを例として - 森岡裕株式会社日経リサーチ CRM 事業本部データサイエンス部 Using SAS Hash Objects to summary data Counting Item-Set as an example Yutaka Morioka CRM Solutions Unit Data Processing & Science Division, Nikkei Research Inc

要旨 : KEY と DATA 要素で構成されるテーブルにデータを入れ それをデータステップ内で自由に出し入れすることができるハッシュオブジェクト 昨年発表の論文ではデータ結合に利用する例を多く紹介しましたが 応用範囲はまだまだそんなものじゃない!! アイデア次第でいくらでも楽しいことができるハッシュオブジェクト ちょっと難しい話は他の発表者の方々にお任せして この発表では データを数えたり 合計したり どんな分野のユーザーでも日々行う基本的な処理をハッシュオブジェクトでやってみます 論文の方は一応真面目に書いてますが 発表の方はできるだけ多くの方に気軽に聞いて欲しいので だいぶ柔らかい内容にしております データステップをもっと楽しもう!! 2

きちんとした理解は 後でオンラインヘルプから公式のリファレンスを読みましょう 3

SAS 9.X 言語リファレンス : 解説編 22 章 DATA ステップコンポーネントオブジェクトの使用 ハッシュオブジェクトの概略や基本的な使い方が説明されている 詳しいメソッド ( 命令式 ) の 1 つ 1 つについては次にあげる資料を参照する 4

SAS 9.X コンポーネントオブジェクト : リファレンス 2 章ハッシュオブジェクトとハッシュ反復子オブジェクトのディクショナリ SAS ハッシュオブジェクトで使用可能な全メソッドが 1 つ 1 つヘルプ的に紹介されている 5

な なんと過去 30 年分のユーザー総会発表資料が去年から無料公開!!! 衝撃 SAS プレミアムラウンジからダウンロードできる!! 小職の昨年の論文を今回の予習に読んでいただけると嬉しいです 6

data OUTPUT; if _N_=0 then set MASTER; if _N_=1 then do; declare hash hq1(dataset:'master'); hq1.definekey('code'); hq1.definedata('name'); hq1.definedone(); end; set ZAIKO; rc = hq1.find(); if rc ^= 0 then CODE = ''; run; 昨年のおさらい ハッシュにしかでてこない変数のために初期化が必要 ハッシュの定義はステップ中 1 回でいいので _N_=1 通常のデータステップ ハッシュオブジェクト定義部分 ハッシュオブジェクト名は hq1 中身はデータセット MASTER key に CODE data に NAME find メソッド CODE の値と同じ値を持つデータをハッシュオブジェクトから GET rc( 変数名はなんでもよし ) には メソッドが成功すると0 失敗すると0 以外の数値が入る 失敗した場合は 値を消さないと前の値が残ってしまう 7

カウントしよう! ID の値が 何回でてきたかを TOTAL に累積カウントしていく 8

data OUT1; run; if _N_=1 then do; end; declare hash h1(suminc:'y'); h1.definekey('id'); h1.definedone(); set DATA1; Y=1; h1.ref(); h1.sum(sum:total); suminc オプションで指定した変数の値が key 値がメソッドに参照される度に内部的に累積されていく ref メソッドは check メソッドと add メソッド両方の働きを持つ! まず check で値がハッシュオブジェクトにないかをチェックし なければ追加する 値がチェック または追加される度に Y の値 (1 を割り当ててるよね ) が ハッシュオブジェクトの中に key ごとに蓄積されていくのがポイント sumメソッドで ハッシュオブジェクト内に溜まってる合計値を keyの値で紐付けて 任意の変数にだす ( 例ではTOTAL) 9

入力データセット ハッシュオブジェクト 1 合計 1 ref メソッド sum メソッド ハッシュ内にまだない key 値だから追加されてるよ 出力データセット 10

入力データセット ハッシュオブジェクト 1 合計 1 3 合計 1 ref メソッド sum メソッド ハッシュ内にまだない key 値だから追加されてるよ 出力データセット 11

入力データセット ハッシュオブジェクト 1 合計 2 3 合計 1 ref メソッド ハッシュ内に既にある key 値だからチェックされるだけ でもカウントはされる 出力データセット sum メソッド 12

合計しよう! ID の値ごとの X の累積合計値を TOTAL にいれていく 13

さっきのコードとの違いをみよう data OUT2; if _N_=1 then do; declare hash h1(suminc:'x'); h1.definekey('id'); h1.definedone(); end; set DATA1; h1.ref(); h1.sum(sum:total); run; 1ずつカウントするコード data OUT1; if _N_=1 then do; declare hash h1(suminc:'y'); h1.definekey('id'); h1.definedone(); end; set DATA1; Y=1; h1.ref(); h1.sum(sum:total); run; 14

入力データセット ハッシュオブジェクト 1 合計 100 ref メソッド sum メソッド ハッシュ内にまだない key 値だから追加されてるよ Suminc に X を指定だから 100 になった 出力データセット 15

入力データセット ハッシュオブジェクト 1 合計 100 3 合計 10 ref メソッド sum メソッド ハッシュ内にまだない key 値だから追加されてるよ 出力データセット 16

入力データセット ハッシュオブジェクト 1 合計 150 3 合計 10 ref メソッド ハッシュ内に既にある key 値だからチェックされるだけ でも合計はされる 出力データセット sum メソッド 17

グループ化された合計結果だけでいいの!! ID の値ごとに集約して X の合計値を出力 18

data _NULL_ ; if _N_=1 then run; do; end; declare hash h1(suminc:'total', ordered: D'); h1.definekey('id'); h1.definedata('id', 'TOTAL'); h1.definedone(); set DATA1 end=eof; TOTAL=X; h1.ref(); h1.sum(sum:total); h1.replace(); data ステートメントでデータセットを作らない if eof then h1.output(dataset:'out3'); suminc に TOTAL が指定 ordered: A は key(id) でハッシュの中身を昇順にしておく命令 ( 降順は A) TOTAL を data 指定している end= オプションで最終オブザベーションに立つフラグをセット 最後の時点で outputメソッドを使って ハッシュオブジェクトの中身そのものを OUT3 というデータセットに出力する 19

つまり TOTAL にいったん X の値を割り当てて ref メソッドの働きで 合計値に TOTAL( つまり X なんだけど ) の値を足し上げて sum メソッドで TOTAL という変数名に返して それを使って replace メソッドでハッシュオブジェクト内の data を更新している Definedata で TOTAL が data に定義されているから この時 ハッシュオブジェクトの中の data としての TOTAL にはそこまでの累積合計値が入っている replace メソッドを使うと それまで内部的に保持されていた合計値はリセットされるけど その代わりに data として保持しちゃってるわけですね そしてまた足してリセットする つまり このコードは実は累積で合計していくというよりは 現在の X の値 +data として格納されているそれまでの累積合計値 TOTAL を繰り返してるわけです わけわからんですね 20

data _NULL_; if _N_=1 then do; declare hash h1(ordered:'a'); h1.definekey('id'); h1.definedata('id', 'TOTAL'); h1.definedone(); end; set DATA1 end=eof; if h1.find() = 0 then TOTAL +X; else TOTAL=X; h1.replace(); if eof then h1.output(dataset:'_out3'); run; 今回の処理でいうと suminc と sum メソッドで処理するよりも 左のコードのように書いた方が何をやっているかわかりやすい 21

マニアックなコードの話ばっかりで正直飽きたと思われた方 22

少しだけ具体的な話にしましょう 23

よく聞くバスケット分析 24

1 4 2 5 3 紙オムツとビールを一緒に買ってる人が多いから 売り場近くしたら 儲かったぜ! っていう例の話です ( その例自体は創作らしいですが ) 25

Aの商品とBの商品を同時に買っているという現象を AとBの1セットを1つ買っているという風に考えてカウントしてみる 26

1 1 さんは 4 つの商品を同時に購入した 2 つ 1 組を 1 アイテムセットと定義すると 6 つのアイテムセットがカウントできる これを全顧客に対して行ってアイテムセットを集計すれば良い 27

やりたいのはこういうこと 28

楽勝そうだけど 商品の種類が 100 とか超えてくると SAS でやるのが結構むずかしくなってくる よくあるのが まずデータを下図のように 1ID につき 1obs で 商品購入有無を横に 01 変数で展開して マトリクス構造のデータセットを作る それを Proc summary 等の集計プロシジャで有無変数を class ステートメントに全部突っ込んで集計する方法 ID 紙おむつ 牛乳 リンゴ ビール パン 1 1 1 1 1 0 2 0 0 1 1 0 3 1 0 0 1 0 4 1 1 0 1 0 5 0 0 0 1 0 29

問題点 データが大きい ( 顧客数が多い or 商品数が多い ) と まず横展開型のデータセットに変形するのに処理時間がかかる 商品数が多いと 横に展開される変数の数が同様に多くなる Class ステートメントに多くの変数を指定すると メモリ容量エラーになって実行が停止する場合がある 30

理想は データ構造を変えず 元データをそのまま流し込んで結果が欲しい 少ないステップで効率よく処理したい 31

data _NULL_; informat ID ITEM ITEM2 COUNT2; if _N_=1 then do; declare hash h2 (suminc:'count2', hashexp:2); h2.definekey ('ITEM', 'ITEM2'); h2.definedata('item', 'ITEM2', 'COUNT2'); h2.definedone (); end; do while(^fl); set DATA3 end=fl; do i=1 to tobs; set DATA3(rename=(ID=_ID ITEM=ITEM2)) point=i nobs=tobs; if ID=_ID and ITEM < ITEM2 then do; COUNT2=1; h2.ref(); h2.sum (sum: COUNT2); h2.replace(); output; end; end; if FL then do; h2.output(dataset:'out7'); end; end; stop; run; たった 1 ステップ! 入力データはそのままの形 コードの詳しい解説は論文で 32

発表スライドでの紹介はここまでです 論文の方では 発表で省略した例や ここからさらに突っ込んで アソシエーション分析をやったりしているので そちらを参照ください! 論文集は会場でも買えたはず 一年待てばまたアップされるはず 一応プログラムは全てプレミアムラウンジからダウンロードしてもらえるようにする予定です 33

ただし 内部で直積を作成しているので 元データのオブザベーション数が多い場合 サンプルコードのままだと実行が絶対終わらない! 状況に応じて アイテムセットのレベルごとにプログラムを小分けにして 頻度の低いものを削るようにするなどのカスタマイズが必要 今回の例は あくまで説明用の例なので 34

おわりに 昨年 発表したハッシュオブジェクトについて その後反響メールが多くて驚きました 会社でいきなり使ったら上司や先輩に怒られたっていう文句? もあって面白かったです それはスミマセン データステップを工夫して書くのが楽しくなって 仕事も楽しくなったという感想をくれた方がいて 凄く感動しました 書いてて楽しいというのは案外大事なことだと思います 無料版 SAS のリリース等により 分野 年齢問わず SAS ユーザーが増えているようです もっとユーザー同士が様々な垣根を超えて 気軽に工夫を発表しあえるようになれば良いと思います 35

ご清聴有難うございました 36