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

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

持参薬の記録についてあれこれ

10月から持参薬の記録が必須になりました。
面倒極まりない仕様ですが、データを扱うときにも注意点が増えます。
というのも、この持参薬情報、

出来高実績点数や明細点数情報を保持したままなのです!

つまり、普通にEFファイルを集計すると、持参薬込の点数が出てしまいます。 (ひょっとすると、それが狙いでこういう仕様なのかも知れませんが…)

持参薬の有無や種別は行為明細区分情報の3桁目に記録されますので、こちらを利用すれば区分けは可能です。 例えば以下に、持参薬を除外した出来高点数集計の例を挙げます。

SELECT データ識別番号,入院年月日,SUM(出来高実績点数*行為回数) AS 出来高総点数
FROM ef1610
WHERE データ区分 <> 92
AND データ区分 <> 97
AND 行為明細区分情報 LIKE '__0_________'
group by データ識別番号,入院年月日

該当のポイントはAND 行為明細区分情報 LIKE '__0_________'です。
SQLなら大して難しいことではありませんが、面倒くさいですね。

再びのアプリケーション考察

データ分析をやっていると、やっぱり「アプリケーションで配布したい!」と思うときがあります。
(このブログで書いている諸々のSQL文も、まとめてアプリケーションにバンドルしてしまいたいのです)
最近真剣に選択肢を検討してみたので、結果をつらつら書くことにしました。

1. Pythonのままアプリケーション化する

ネットで検索すると色々な方法が見つかりますが、Pyinstallerを使うのが最も現実的でしょう。
他の方法、例えばPy2exeなんかは更新が止まっちゃってますし… とはいえ、環境によってはPandasを含むアプリが上手くビルド出来なかったりします。 私が正にそうで、GitHubの開発中のビルドをぶっ込んだら走りましたが、うーん、安定はしてなさそうですね…
また、GUIをどうするか、という問題もあります。 PyQtが一番有名みたいですが、ライセンスがややこしそうです。別の選択肢として、Kivyが熱いみたいですが日本語の情報があまり出回っていません。
FlaskでWebアプリを作ってブラウザで使う、という手もありますけど…うーん…

2. Javascript + Node.js + Electronでアプリケーション化する

自分でもなぜこうしようと思ったのか分かりませんが、Node.jsで組んだウェブアプリをElectronというライブラリでデスクトップアプリに変換出来ます。
実際に使ってみようと、しばらくJavascriptとNode.jsの勉強をしてましたが…ましたが…うーん…csvを開くための方法が何パターンかあり、dataframeっぽいライブラリを使うにはbabelが必要で、うーん…
ただし、素の状態でJavascriptPythonより速いです。numpy / PandasのようなC言語ライブラリを使えば話は変わってきますが。
ちょっと大きなデータの分析にも十分使えそう。今回は、学習時間が全く足りなかったということで…

3. 素直にC#を使う

初めからそうしろよ、と言われそうですがC#をいじってます。Visual Studioすごいべんりですね!(今更
別にJavaでもいいんですが、せっかくVisual Studioが無料化されたので。 Windowsをターゲットにするなら、最初っからこれで良かったですね… ただ、グラフのプロット周りはあんまり期待できそうにありません。
(こちらはPythonが充実し過ぎているだけ、とも言えますが)

pandasql : DataFrameにSQLクエリを発行するライブラリ

やっぱりDataFrameにもSQLをゴリゴリ書きたい!

Pandasをいじっていると、そう思うことはよくあります。
別にDataFrameに不満があるわけではありませんが、例えば次のような例を見てみましょう。

df = pd.DataFrame({'category':['game','game','game','PC','Tablet'],'machine': ['XBOX','PS','DS','ThinkPad','iPad'],
                       'price': [300,300,150,2000,600]})
category machine price
game XBOX 300
game PS 300
game DS 150
PC ThinkPad 2000
Tablet iPad 600

上記のようなDataFrameのうち、machineがXBOXiPadであるものを選択するとします。

df[(df['machine']=='XBOX')|(df['machine']=='iPad')]

こんな感じになります。率直に言って、あまり見やすい構文ではありません。
もし条件を5つ、6つと増やしていくと、とても素敵なコードになると思います。

pandasqlでSQL文を書いてしまう

pandasqlは、アメリカのベンチャー企業Yhatが公開したライブラリです。 紹介はこちらをどうぞ。
では早速、上の例をSQLに書き直してみましょう。

import pandas as pd
from pandasql import sqldf

q = """
    SELECT *
    FROM df
    WHERE machine IN ('XBOX','iPad');"""

sqldf(q,locals())

多少冗長になりましたが、後で読みやすいのは断然こっちです。
条件が増えても、INの中身を追加するなり、ANDで繋げていったり、いくらでも書きようがあります。 実装はsqlite3相当だそうで、大抵のSQLなら走るでしょう。
もちろん、groupbyも使えます。

q = """
    SELECT category,sum(price)
    FROM df
    group by category;"""

まさに即戦力ライブラリと言えます。是非使ってみてください。

電子点数本を使ってDPCデータを拡張する(2)

前回はDPC点数本をDBに取り込むと便利かも、みたいな話で終わりました。
例えば

分類番号 病名 入院期間1 入院期間2 入院期間3
040080xx 肺炎 5 12 30

みたいなテーブルを用意します。今回は仮にdpcmasterというテーブル名とします。 Dファイルには分類番号が記録されていますので、それを結合キーに利用しましょう。 SQLだとこんな感じになります。

select データ識別番号,入院年月日,実施年月日,SUM(行為点数*行為回数),d.分類番号,
実施年月日 - 入院年月日 + 1 AS 在院日数,dpc.入院期間1,dpc.入院期間2,dpc.入院期間3,
CASE WHEN 実施年月日 - 入院年月日 + 1 <= dpc.入院期間1 THEN '入院期間I'
     WHEN 実施年月日 - 入院年月日 + 1 > dpc.入院期間1 AND 実施年月日 - 入院年月日 + 1 <= dpc.入院期間2 THEN '入院期間2'
     WHEN 実施年月日 - 入院年月日 + 1 > dpc.入院期間2 AND 実施年月日 - 入院年月日 + 1 <= dpc.入院期間3 THEN '入院期間3'
ELSE '出来高'
END AS DPC期間
from d1607 AS d
LEFT OUTER JOIN dpcmaster AS dpc
USING(分類番号)
Where データ区分 <> 97
group by データ識別番号,入院年月日,実施年月日,d.分類番号,dpc.入院期間1,dpc.入院期間2,dpc.入院期間3

あまり綺麗なSQLとは言い難いですが、とりあえずその日のDPC期間をカテゴライズ可能です。
こんなのスクリプトにやらせろよ!という向きに、Pythonのコードも用意しました。

import pandas.io.sql as psql
import psycopg2 as pg
import pandas as pd
import numpy as np


connection = pg.connect(database='DB名',
                user='ユーザー名',
                host='localhost',
                password='パスワード',
                port=ポート番号)

df = psql.read_sql("select データ識別番号,入院年月日,退院年月日,実施年月日,分類番号,簡易病名,入院期間1,入院期間2,入院期間3, \
sum(行為点数*行為回数) AS DPC総点数,実施年月日-入院年月日 + 1 AS 在院日数 \
from d1607 \
LEFT OUTER JOIN dpcmaster \
USING(分類番号) \
where データ区分 <> 97 \
group by データ識別番号,入院年月日,退院年月日,実施年月日,分類番号,簡易病名,入院期間1,入院期間2,入院期間3",connection)


#入院期間列を作成
Zaiin = df['在院日数']
Kikan1 = df['入院期間1']
Kikan2 = df['入院期間2']
Kikan3 = df['入院期間3']
DPCKIKAN = []

for zaiin,kikan1,kikan2,kikan3 in zip(Zaiin,Kikan1,Kikan2,Kikan3):
    if zaiin == 0:
        dpckikan = '出来高分岐'
    elif zaiin <= kikan1:
        dpckikan = '期間I'
    elif zaiin > kikan1 and zaiin <= kikan2:
        dpckikan = '期間II'
    elif zaiin > kikan2 and zaiin <= kikan3:
        dpckikan = '期間III'
    else:
        dpckikan = 'DPC期間超'
    DPCKIKAN.append(dpckikan)
df['DPC期間'] = DPCKIKAN

ひたすらelifを叩くばかりです。 あんまり綺麗じゃないですね…ただ、ちょっと込み入った分析をやろうとすれば、どうせPythonでやることになりますから、さっさとDataFrameに落としてしまうのは一つの手です。

電子点数本を使ってDPCデータを拡張する(1)

DPCのDファイルには、DPC分類番号が記録されています。 理論的には、これを利用し紐付けすれば、その日の診療データがDPC期間のどの区分に該当するか、といった分析も可能になる筈です。 そのためのデータが厚生労働省のページで配布されているので、今回はその紹介をしようと思います。

まずは電子点数本を入手しましょう。

診断群分類(DPC)電子点数表について |厚生労働省

中身はxlsxファイルです。
(率直に言って、中立であるべき政府機関がマイクロソフトのエクセル使用を前提にするのはどうなんだ、と思いますが)
幾つもシートがありますが、その中の「11)診断群分類点数表」を見てみましょう。
全ての診断群分類番号と、それに対応する傷病名・入院期間が載っているはずです。
何を思ったのか、カテゴリ名のカラムが幾つか結合されていたり、二次利用のことを一切考えていない作りですが、そこは手作業でどうにかなる範囲ですね。 素直にcsvで分割しろと言いたい
このうち、どのデータを利用するかは人それぞれです。
私は分類番号、病名、入院期間くらいがあればいいので、カラムを幾つか削って以下のようなテーブル定義で取り込んでいます。

CREATE TABLE dpcmaster
(分類番号 VARCHAR(255),
病名 VARCHAR(255),
手術分岐 VARCHAR(255),
入院期間1 INTEGER,
入院期間2 INTEGER,
入院期間3 INTEGER,
点数1 INTEGER,
点数2 INTEGER,
点数3 INTEGER,
id SERIAL PRIMARY KEY);

別に全項目を取り込んでもいいと思いますが、今のところ思いつく用途がDPC期間の判定くらいなもので…
ちなみにDPC期間ですが、まず在院日数を'実施年月日-入院年月日+1`で算出し、それと入院日I~IIIを比較することで出すことが出来ます。
SQL上で頑張って出してもいいんですが、中間テーブルを作る羽目になるか、WITH句とCASE式を使った複雑なシロモノになるでしょう。
私は面倒くさいのでスクリプト側で処理しました。次回は、実際の処理例を見てみようと思います。

【雑談】 「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」読んでます

以前に「Python 機械学習プログラミング」を読んでましたが、原理的な部分の理解が今ひとつだったので別な本に手を出しました。
「ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装」です。

最初からこれ読めば良かった

機械学習の初心者に最適な一冊です。
とても丁寧に、一からひとつひとつ教えてくれます。
Python3とnumpyしか使わない、という触れ込みだったので実用性に疑問を抱いていましたが、むしろそのお陰できちんとロジックが追えます。
scikit-learnのようなライブラリを使う取っかかりを作るための、基礎固めの一冊ですね。
私が知る限りでは、こういう本は無かったので大変助かっています。
まあ、実務ではscikit-learnなどのライブラリ使用は必須になるので、 「ゼロから作るDeep Learning」→「Python 機械学習プログラミング」という流れで読むといいのではないでしょうか。

しかし今年になってPython機械学習絡みの本が沢山出版されてますね。 勢いを感じます。

DPC「病院情報の公表」についての雑感

今年度より、「病院情報の公表」という制度が始まりました。
DPC導入病院は、所定のフォーマットに沿って情報を公表することで、評価を受けられるようになります。
さて、私の病院では大過なく公開にこぎつけましたが、マニュアルを読んでいて思った雑感などを。

これhtml/cssの知識が無いと辛くない?

「病院情報の公表ページの作成方法」という詳細なマニュアルが用意してありますが、初っ端からCSSやJS、TSVといった用語が、大した解説なしに連発されます。
まあ、ちょっとWEBアプリをでっち上げたことのある人なら「ふーん、なるほどね」で終わりますが、そうでない人は面食らうのではないでしょうか。

各病院のページに置くのはいいが、どこかで一括公開しないの?

今回の公開は、各病院が自分のホームページに置けばいいことになっています。
せっかく統一されたtsvファイルで公開させるんですから、厚生労働省のサイトか何かで、全病院のファイルが一括でダウンロード出来るようにして欲しいものです。
在野のアナリストは「頑張ってWEBスクレイピングしてね!」ということなんでしょうか…

作成ツールのツッコミどころ

えーと、「病院指標公開ページ作成ツール」でhtmlファイルを出力すると、titleタグが空っぽのまま出てきます。
ちゃんとソースを見れば「ここに病院名を入れてね!」と書いてありますが、気付かずアップしてしまう病院さんもあるのでは…


以上、適当な雑感でした。
まあ、大変なのはデータを集計したり医師に記載をお願いするところで、アップロード自体は大して難しくありません。
ただ、それは前提知識ありきの話で、うーん、そろそろ事務員もhtmlくらい分かるようになりなさい、ということなのか…
もちろん、ちゃんとしたシステム管理部門のある病院なら「これくらい出来るわい!」という話ですが、中小の病院だと中々辛そうです。