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

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

さいきん読んだ本など

あるごりずむ

特にネタがないので(おい)、今日は最近読んだ本の話でも。
私はどんな問題も

  1. 楽ができる機能がないか探す
  2. 楽ができるライブラリを探す
  3. StackOverFlowで答えを探す

という方法で解決するゆとりコーダーです。はい、あまりプログラムは出来ません…
友人に「例えばリストの中身をひっくり返すとしたら、どうする?」と聞かれて「り、list.reverse()メソッドがあるしおすし…」と回答するくらいには無能です。
ということで、

なっとく! アルゴリズム

なっとく! アルゴリズム

こんな本を買いました。そもそもアルゴリズムってちゃんと勉強したことないですしね。
本の内容ですが、分割統治の例などかなり格好良く、読んでて飽きません。気の抜けたイラストが、いい感じに肩の力を抜いてくれます。文字数もそんなにないですが、とはいえ漫画というほど軽くもない、絶妙なところですね。
例となるコードは全てPythonになっており、Pythonユーザーには優しいです。

えりくさー

プログラミングElixir

プログラミングElixir

Programming Phoenix: Productive |> Reliable |> Fast

Programming Phoenix: Productive |> Reliable |> Fast

なぜかElixirを勉強し始めました。
ElixirはRubyっぽい文法で書けるErlangです…という説明で通じたら苦労はいりませんね。
えーと、なんか並行処理にすごく強くて速い、厨二病かっけーな言語です(違
2012年に登場したばかりの、かなり若い言語ですが、もうWebフレームワークが作られています。
Phoenixというのですが、これが非常に便利で、Flaskよりずっと楽…というか、Python界隈がWebフレームワークに恵まれてないんじゃ…?と思うくらいには楽です。
DBの面倒はぜんぶフレームワークが見てくれますし(自分でPostgresやSQLiteを見る必要がない)、いー感じにフレームワークがコードを自動生成して面倒見てくれます。
Flaskでは全てが手作業で、だからこそ挙動を把握できるところもありますから、良し悪しもありますが…

Electronアプリ DPCチェッカー0.2を公開

えー、前回のリリースから一ヶ月以上サボってましたが、0.2が出来ましたので公開します。
例によってこちらからどうぞ。

変更点

Python版にあったダッシュボード機能を移植しました。
今回こんなに時間がかかったのは、方向性を決めあぐねて、色々フレームワークをいじって遊んでたからです。
JavaScriptの世界は本当にジャングルみたいに繁栄してますね・・・
一時期は「フロント部分をReactで書き直す」とか正気じゃないことを考えてました。
その後は「Reactはやり過ぎだ。Vue.jsで書き直せばいいだろう」と思ってました。うーん、迷走ですね!
(そもそも力を入れるべきはそこではない)

今後の方向

いい加減単月データだけを見る構造は卒業して、最低でも1年分は保存出来るようにしたいですが、設計どうするか迷っています。
割と見切り発車でアップデートするかも知れません。
あとPythonベースの高度なダッシュボードも作ってみたいなあ・・・

Pandasでささっと前年度比較

毎月レセプトが終わると、前年同月比較をやることが多いです。
まあ、手術がガクンと落ちたり上がったり、どうしても波があるからです。
今回は、EFからささっとデータを取ってくる方法を考えてみました。 わかりやすく、今年のデータはdf17、去年のデータはdf16としましょう。

df17 = pd.read_sql("""select 診療科区分,解釈番号,診療明細名称,出来高実績点数,行為回数
from etable17
Where データ区分 BETWEEN 50 AND 59
AND 解釈番号 LIKE 'K%'
AND 解釈番号 NOT LIKE 'K92%'""",connection)

df16 = pd.read_sql("""select 診療科区分,解釈番号,診療明細名称,出来高実績点数,行為回数
from etable16
Where データ区分 BETWEEN 50 AND 59
AND 解釈番号 LIKE 'K%'
AND 解釈番号 NOT LIKE 'K92%'""",connection)

ひとまず手術手技だけに着目することにします。
解釈番号がKで始まるものに固定し、かつK92系(輸血です)を除いて、純粋に手術手技だけを見てみましょう。

df16['year'] = 16
df17['year'] = 17

df_merged = pd.concat([df16,df17])

あとで集計しやすいように、yearカラムを追加して年を入れます。
pd.concatはデータフレームを縦方向に連結する関数です。SQLでいうところのUNIONですね。

df_merged.groupby(['診療科区分','year']).describe()

で診療科区分別の状態を、年別にサクッと確認できます。
また、

df_merged.sort_values(by='出来高実績点数', ascending=False)

とすれば、手技の高い順にソートをすることも出来ます。

また、メソッドは連結が可能です。
つまり、

df16.groupby(['診療科区分','診療明細名称']).sum().sort_values(by='出来高実績点数', ascending=False)

こうすれば、診療科区分・手技別に総計を出し、金額順に並び替える、という処理がワンライナーで出来ます。
こんな風に、その場その場の問題をぱぱっと解決するのにPandasは便利ですね。

EFファイル統合スクリプトをアップしました

4月分のレセプトチェックのため、EF統合ツールを使ったところ「2017年度以降のデータが入っています」と蹴られました。 あれ?と思って調べてみたら…PRISMのEF統合ツール、今年度分は6月公開予定なんですね!(白目

うーん、困りました。そういえば、去年も同じようなことがあって困ってた記憶があります。
ほじくり返すと、どうやらEF統合を自力でやろうとしてたみたいですね。
仕方ないので今年もそうしますが、去年のに少しだけ手を加えて、ヘッダを用意しなくても使えるように修正しました。
こちらEF統合(2016).pyをご利用ください。
EファイルとFファイルのあるフォルダに置いて実行すれば、outputEF.txtが出力されます。

なお、このスクリプトの用途はあくまでDB取り込み用であり、提出仕様ではないのでご注意を。
エンコーディングUTF-8になってるので、このまま提出すれば100%弾かれます。

Bokehで動的なグラフを描画する

そもそもBokehって?

大分前に一度紹介しましたが、PythonのグラフライブラリにBokehというものがあります。
Pythonのデータ可視化というと、matplotlibが圧倒的なデファクトになってます。
そのラッパーであるseabornも有名で、最近のPython本を見るとseabornを使う例も多いですね。
今回紹介するBokehはかなり違った出自で、HTMLを吐き出すのが特徴です。ライブラリはPython側とJavaScript側に分かれており、実際の描画はJavaScript側が行います。
また、グラフの描画レベルが2つに分かれているのも特徴です。

ローレベルのbokeh.plotting

  • 折れ線グラフ、単純な散布図、棒や円などを描画できる
  • D3.jsほどローレベルではないが、割りと近い感じ
  • 当然自由度は高いが、これでグラフを組み上げるのは大変そう…

ハイレベルのbokeh.charts

  • 既に用意された形式で、棒グラフやヒストグラム、散布図など一通り描画できる
  • ユーザーサイドから見ると、seabornと似たような感覚で使える

Bokehのいいところ

グラフは動的にいじれるし、見栄えも良い。HTMLとJavaScriptなので、Webアプリにも簡単に組み込める。

Bokehの悪いところ

ライブラリの性質上、データはPython側で用意し、描画のコードを書くのだが、実際にはJavaScriptにコンバートされることになる。 Python側のデータとJavaScript側のデータは必ずしも同一ではない(!)のに注意しないといけない。
400列の巨大データから、2行だけ使ってグラフを描画するケースなどもあるので、DataFrameを全てJavaScript側に流し込むわけにはいかない、という話だけど…



こんな感じでしょうか。 後は下にJupiter Notebookを貼っておきますので、マウスでいじってみて下さい。 (前回みたいにGistも用意したんですが、JavaScriptのロードでコケました…nbviewerだと動くのは、何でなんでしょうね?)

Jupyter Notebook Viewer

DPC入院料を月別/科別に可視化する

さて今日も元気にJavaScriptでガンガンフロントを書いていきましょう!
…という趣旨の記事を書きそうになって正気に返ったスタゲイラです。こんばんは。
えーと。ここしばらくはこんな本を読んでました。

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

このままだと、ブログが「日曜プログラマのWebサイト作り」になってしまうので、路線を戻します。
今回はSQLからは離れて、既に「DPC入院料」「科名」「診療月」が入ったデータセットがあるものと仮定し、簡単な可視化をやってみましょう。
使うのはpandasのプロット機能と、seabornです。
Jupyter Notebookをそのまま載せてみました。実務でも、大体こんな感じでやってます。

DPC入院料のグラフ化テスト

実務では月別の推移を見ることが多いです。
そして、大雑把に「今月は入院料が高い」「今月はなんか低い」と分かったら、そこから細かく見ていくわけですが、真っ先に切り分けるのは診療科であることが殆どです。
このように時系列を折れ線グラフで描いたり、分布をヒストグラムや箱ひげ図で確認するのはとても重要です。 分布に異常がないかヒストグラムでチェックして、箱ひげ図で異常値がないか見る感じですね。
最後に外れ値除去を行って再び箱ひげ図を見る、なんてこともやってます。

なんでPythonでGUIアプリを書かないの?

さて、前回はElectronを使ってでっち上げたアプリケーションを公開しました。
ElectronはJavaScriptベースのライブラリです。私が普段使っているのはPythonで、JavaScriptはロクに分かっていません。
が、いざデスクトップアプリを書く段になって、選択したのはElectronでした。

PythonGUIライブラリを使わない理由は?

当初は、PythonGUIライブラリを覚えるべきだ、と思っていました。代表的なものとして、PyQtとKivyがあります。
早速いじってみたのですが、どちらも「テーブルを表示する」というだけのことが、妙に複雑になっていて好きになれませんでした。
例えば、テーブルのデータを変数dfに格納したとします。
Pandasでhtmlテーブルを作るのは、df.to_html()というメソッド1行で事足りてしまいます。
PyQtでの実装は、えーと、StackOverFlowによるとこうみたいですね。
???うーん…???
QtCore.QAbstractTableModelを継承したPandas表示用のクラスを作成し、そこにデータを流し込むみたいです。ほ、ほほう・・・
もちろん、この辺の情報は全て公式の英語ドキュメントをきっちり読み込まないといけません。
Kivyだと、うーん、recycleviewなるものを使いみたいですね。英語のドキュメントを読みましょう。

他の言語を見てみると…

ちなみに同じことをScala-swingで実装すると、まあ、最初からテーブル用のモデルがあるので、大して苦労せず実装できます。
まー、こっちはこっちで英語のドキュメントなのは変わらないんですが、swingそのものが用途に向いているんでしょう。
本来このような用途に最も向いているのは、間違いなくC#ですが、今更新たな言語と格闘する時間もありませんでした。

結局HTMLが簡単だ

まー、UI部品を組み立てていくなら、HTMLが断然簡単ですね。
見た目はCSSで幾らでも変えられるし、プレビューはブラウザですぐ見れるし… Pythonでも、HTMLベースのGUIライブラリがあるといいんですけど。