DPCデータの分析とかやるブログ

DPCデータの分析なんかをテキトーにやってます。

2016年の終わりに

このブログを始めたのが今年の1月でしたので、年が明ければ一周年となります。
お読み頂いた皆さんには、お付き合い頂き有り難うございました。
来年はもう少しマシな内容になると思います・・・うーん、なる、はず・・・なるといいな・・・

2016年のまとめ

今年はずっとPostgresとPandasの話ばっかり書いていました。
個人的には2015年からやっていましたが、今年はPython本がたっぷり出版されて、いよいよ「データ分析=Python」という空気が広まった感があります。
また、Rについてもたくさん本が出ましたから、そういう年だったのでしょう。

個人的な体験からすると、Pythonプログラマではない人のための第一言語です。
更に言えば、日々の仕事を楽にするために、ちょっとしたハックが必要な人に最適です。シェルスクリプトより汎用性があり、習得が楽で、しかも最高のデータ操作ライブラリを持っています。こんな言語は他に見当たりません。

今年仕事をしながら感じたのは、そろそろ事務仕事にもコードが必要な頃合いだ、ということです。別にプロのプログラマを必要としているわけじゃありません・・・たぶん、10行か20行、ぱぱっとでっち上げるだけで、随分助かるという仕事は多いんじゃないでしょうか。

2017年の展望

出来れば来年は、もう少し応用的な話を書けるようになりたいものです。
Pythonを使った統計分析や、機械学習は、私自身も実務での適用例がありません。
基礎の勉強はそこそこやっていたので、来年はいよいよ実践かなあ・・・

また、ブログの趣旨からは外れますが、余談を少し。

ウェブは世の中全てにやって来ます。「ウェブ」という言葉で意味するのは、HTML/CSS/JavaScriptです。私の読みが間違いでなければ、恐らく新規のデスクトップアプリケーションの多くがElectronベースに、すなわちNode.js上に構築されるようになるでしょう。
自分でもElectronでプロトタイプを組んだのですが、思った以上に簡単にアプリケーションが出来てしまうので驚きました。
ウェブアプリケーションをそのままデスクトップに持ってこれる、というのは本当に大きいです。
ということで、来年は

あたりにチャレンジしようかなあ、と思います。
それでは皆様、よいお年を。

Pythonでのデータ可視化について色々

Pythonでグラフを描こうと思ったら

まあ、普通はmatplotlibですね。
matplotlibは事実上のデファクトであり、これで困ることはまずありません。以上、今回はこれで終わり・・・
というわけには行きませんね。他にも幾つかの選択肢がありますので、見ていきましょう。

seaborn

seabornはmatplotlibをベースに構築されたグラフライブラリです。
matplotlibのスタイルはいかにも「研究論文に載せてください!」というものですが、seabornはもうちょっと洗練された見た目になります。
「あんまりスタイルをいじってる時間は無いけど、綺麗なグラフが欲しい」という時に重宝しますね。
また、matplotlibとseabornをimportしてグラフを描くと、自動的にseabornのスタイルが適用されます。単にmatplotlibのグラフを綺麗に描画したい、というときにもいいでしょう。
が、それだけに使うにはちょっと勿体ないというか、オーバーキル気味のライブラリでもあります。
heatmapの例を見れば分かるとおり、ゴリゴリの理系論文で使いそうなライブラリで、出自や想定される用途はmatplotlibに近いんだろうなあ・・・

Pandas

なんとPandasにもグラフ描画機能があります!
ドキュメントを読めば分かるとおり、DataFrameのメソッドにplotがあるのです。やった!これで可視化の方法は決まりだ!
・・・と、なるかどうかはともかく、さっとグラフを描くにはとても便利です。
ちなみに実体はmatplotlibですので、勘違いしないように。

Bokeh

Bokehは期待の新星で、上の3つ(matplotlib/seaborn/pandas)とは全くの別系統です。
というよりは、上の3つか同一系統というのが正しいですが・・・ BokehはJavascriptベースの可視化ライブラリで、結果はHTMLファイルか、scriptタグで返ります。
Webアプリケーションに組み込むには非常に便利で、かつ書く分にはPythonで完結し、一行もJavaScriptを書かなくていいというお手軽さ。
Pandasとの相性もいいです。
問題点は、まだ荒削りなこと。バージョン0.9x系までは外れ値を含むデータを描画するとヒストグラムが壊れたりしました。
現行バージョンでも、データ量が多くなるとフリーズしたり、描画が変になったりすることがあります。

まとめ

matplotlib系統が返すのはグラフオブジェクトで、それをpngなりX11ウインドウなりで描画することになります。
ウェブアプリケーションなどに組み込むのであれば、Bokehの方が扱いやすいかも知れません。
一方、得体の知れないデータがあって、どんなメチャクチャな描画になってもいいから、とにかく一度グラフにして状況を見てみたい!というときは、seabornを使うのが無難でしょう。
Pythonを使ってデータ分析をする場合、そういうトライアンドエラーを繰り返すのが多いですので、普段使いにはseabornがオススメです。
Pandasから直接接続できるBIツールみたいのがあればいいんですけどね・・・

DPCチェッカー0.10 ダッシュボード機能を追加

例によってこちらです。

バージョン0.08の変更点:ダッシュボード機能

予告通りダッシュボードをつけました。
開くと科別・病棟別の出来高対比グラフ、また同じく科別・病棟別の収益分布がグラフで描画されます。
ネタが思いつけば追加は簡単なので、順次増やしていくつもりです。

ビジュアライゼーションについて

今回はC3.jsを利用させて頂きました。 こちらは有名なD3.jsのラッパーで、棒グラフや円グラフをある程度簡単に描画出来ます。
ただし、JSONを知らない界隈から来ると(私がそうです)、結構面食らいますね。
Pythonのグラフライブラリは殆どがPandasのDataFrameを想定しているので、一般的な表形式データ(即ちcsvのようなもの)を頭に浮かべればすぐ理解できます。
が、JavaScriptの世界で想定されているのはJSONです。頭の切り替えには結構苦労しました。

最初っからMatplotlibなりSeabornなり使えば楽なのですが、どちらも配布するにはフォントの問題があります。
具体的には、ユーザー側でフォントファイルの追加をしないと日本語が文字化けする筈です。
Pythonから使うにはダントツで簡単なんですけどね・・・

DPCチェッカー0.08 デザインをちょっと修正

例によってこちらからどうぞ。

バージョン0.08の変更点:デザイン修正

これを書いている人間は、残念ながら「デザイン」とか「絵心」というものは皆無です。
ということでGoogle様のMaterial Design Liteに乗っかりました。
といっても所々昔のままで、ツギハギ感がひどいですが、ドキュメント読み始めてまだ数時間なので…
しかしこういうデザインテンプレートがオープンソースで山ほど転がってるのが、Web技術のいいところです。
デスクトップ向けのUIだと、あんまりこういうのは見つからないので…

次回アップデートではようやくグラフ描画機能を追加する予定です。
Flaskの勉強もちょこちょこしてますので、各種の挙動がもう少しマシになると思います。

SQL方言について(ついでにDPCチェッカーにクエリを追加)

SQLの方言

残念なことですが、SQLは実装ごとに方言があります。
私はPostgreSQLばっかりいじってたので気にも留めていませんでしたが、今回DPCチェッカーを作っていて否が応でも気付かざる得ませんでした。
DPCチェッカーは組み込みで配布するため、SQLite3を使っています。exe単体で実行できるSQLで、Pythonには何とビルトインされています。
こちらの実装はPostgreSQLとかなり違っていて、例えば日付データをネイティブで扱うことが出来ません。
そこにさえ目をつむれば、大抵のクエリは走るのですが、今回はここで詰まりました。

select データ識別番号,実施年月日,診療明細名称,SUM(明細点数・金額*行為回数) 
from etable
Where データ区分 = 60 
AND (データ識別番号,実施年月日) IN (select データ識別番号,実施年月日 from dtable Where データ区分 = 93) 
group by データ識別番号,実施年月日,診療明細名称
HAVING SUM(明細点数・金額*行為回数) > 0;

以前このブログで紹介した、DPC期間中に行った検査を探すクエリです。 INを使った相関サブクエリで、「Dファイル上でDPC入院料を算定した患者と日付」に条件に絞る、ということをやっています。
このクエリはPostgresでは走りますが、SQLiteでは走りません。 AND (データ識別番号,実施年月日) IN...の部分が問題です。
これをAND データ識別番号 IN...とすると走ります(これでは条件を満たしませんが)。
()でカラムを複数指定するやり方は、行値式というそうで、実装されているSQLは限られています。 (メジャーどころでは、MicrosoftSQL Serverも対応していないとか)
どんなに頭を悩ましたところで、実装されていないものは走りません。書き方を変えます。

select e.データ識別番号,e.実施年月日,e.診療明細名称,SUM(明細点数・金額*行為回数) 
from etable AS e
Where データ区分 = 60 
AND EXISTS (select d.データ識別番号,d.実施年月日 from dtable Where データ区分 = 93
AND dtable.データ識別番号 = etable.データ識別番号
AND dtable.実施年月日 = etable.実施年月日)
group by e.データ識別番号,e.実施年月日,e.診療明細名称
HAVING SUM(明細点数・金額*行為回数) > 0;

今度はEXISTSを使いました。意味合いは違いますが、求める結果は同じです。
Postgresでは走りますので、意気揚々とSQLiteで走らせると・・・答えが返ってきません。
どうやら私がやっつけで書いたクエリに問題があって、Postgresが優しく(見えないところで)始末をつけてくれたのでしょうか。それとも、SQLiteのEXISTS実装にパフォーマンスの問題があるのでしょうか。または、その両方?
前者である可能性が高いですね。 さて困りました。もうちょっとEXISTSについて調べてもいいのですが、手っ取り早いのは以下のクエリです。

WITH d93 AS (select データ識別番号,実施年月日 from dtable Where データ区分 = 93),
e60 AS (select データ識別番号,実施年月日,診療明細名称,SUM(明細点数・金額*行為回数)  AS 出来高金額
from etable
Where データ区分 = 60 
group by データ識別番号,実施年月日,診療明細名称
HAVING SUM(明細点数・金額*行為回数) > 0)
select d93.データ識別番号,d93.実施年月日,e60.診療明細名称,e60.出来高金額
from d93
INNER JOIN e60
USING(データ識別番号,実施年月日);

WITH句でテーブルを2つ作ってINNER JOINでくっつけています。
結局、今回やりたいのは「検査を行った患者とその日付」の集合と、「DPC入院料を算定した患者とその日付」の積を求めること、つまり二つの集合の共通集合を導き出すことです。
ならばINNER JOINで良いわけですね。

(ちなみに、上記のクエリは検査版と注射版を作って、DPCチェッカーに追加しておきました)

DPCチェッカー0.07 : 外部クエリの読み込みに対応しました

例によってこちらからどうぞ。

バージョン0.07の変更点:外部クエリの読み込み機能について

今まで当ツールはコード内部にそのまんまSQLクエリが書いてあるというシロモノでした。
拡張性もへったくれもありませんので、バージョン0.07でSQLクエリは本体から切り離し、queryフォルダに置く形式となっています。
その副産物で、外部クエリの読み込みにも対応出来ました。
お好きなSQL文をqueryフォルダにtxtで置けば、メニューに選択肢が増えます。
なお、エンコーディングUTF-8にして下さい。

あと幾つかのクエリを追加してあります。 当ブログでも紹介してきましたが、

  • EF/Dファイルの区分別集計
  • 手術のカテゴリ別金額
  • 副傷病分岐なしチェック

です。 本来ならばDPC中に行った検査/注射のチェック機能も追加する筈でしたが、当該のクエリがSQLiteで走りません・・・
移植にはもう少しかかりそうですので、気長にお待ち下さい。
(この件で「SQLクエリの移植」というひどい問題にも出会いました。これは追々記事にします)

今後の課題と予定

見た目がひどい

ほんとにひどい。見づらい。
ということで、多分レイアウト修正をやります。ついでにbootstrapでも勉強するつもりです。

ビジュアライゼーション

かっこいい分析機能とかあるといいですね。こう、どかーんとダッシュボードが開いて、グラフがぬるぬるっとアニメーションして描画されるようなの。
すごい適当なことを書きましたが、こういう機能を楽に実装するなら、もうJavaScriptのライブラリを使うしかありません。
(このブログで紹介したBokehはPythonで動くグラフを作れますが、出力結果はJavaScriptです)
このツールがウェブアプリなのは、私がC#に挫折しただけではなく、グラフ描画にまつわる問題もあるのでした。
まあ、D3.jsみたいなのは他にありませんしね。

DPCチェッカーを0.06にアップデートしました

といっても、csvエクスポート機能をつけただけですが…
例によってこちらからどうぞ。
今後の予定としては

  • さっさと外部クエリ読み込みを実装する
  • というか今までブログに上げてきたクエリを整理してGitHubにまとめる
  • Bokehを使った可視化は業務でやってるので、早めに組み込む

となっております。
如何せん片手間仕事なのでペースは遅いですけど。

もし時間があれば、ロジックをそのまんま流用してJavaScriptで書き直し、Electronでアプリ化したものを配布したいですが、うーん。
今の状況だと難しそうです。
ちなみにPyinstallerを使えば、Pythonのままでexeに出来るのですが、様々なライブラリを全てバンドルしてしまうようで、500MB超にまで膨れ上がります。ソースのサイズを考えると無駄があり過ぎますね。