株式会社NTTデータ Data & Intelligence事業部 の nttd-saitouyun です。
本記事は長文になってしまったため、2回に分けてお伝えします。
はじめに
私はDatabricksのエバンジェリストとして活動しております。
その活動の中でお客様のデータ活用の課題や要望をお伺いすることが多いのですが、「DICOMデータを活用したい」とご要望をいただいた際に、私の不勉強でお役立てできなかったため、今回は勉強も兼ねて、「DICOM」と「DICOMをDatabricksで活用する方法」 について調べた結果をご紹介します。
前編では、「DICOM」と DICOMデータをPythonで扱うライブラリである「PyDicom」の基本操作と大規模環境における課題を説明しました。
本記事では、大規模環境における課題を解決する「DICOMをDatabricksで活用する方法」をご説明します。
DICOMをDatabricksで活用する方法
それでは、Databricks ソリューションアクセラレータで公開されているDICOMデータの活用方法を見ていきましょう。
Databricksソリューションアクセラレータとは
公式ページには以下の説明があります。
Databricks ソリューションアクセラレータは、さまざまな業界・業種に共通の主要なユースケースに対応する、フル機能の Notebook やベストプラクティスを含む目的に特化したガイドです。
分析のプラットフォームだけでなく、分析のナレッジまで提供しているのはDatabricksの大きな強みだと言えます。
databricks.pixels Solution Accelerator
今回は「databricks.pixels Solution Accelerator」を活用します。アクセスするとGithubに遷移し、以下のページが表示されます。
このソリューションを活用することで、DICOMのメタデータをSQLで分析することができるようになることがわかります。
databricks.pixels
databricks.pixels
は今回活用するライブラリです。以下の特徴があります。
- DICOMデータを、SQLでアクセス可能なメタデータ、サムネイルに変換できる。
- 画像処理を複数サーバで分散処理することで、何百万もの画像ファイルを処理できる。
- Delta Lake & Delta Engineを分析に利用できる。つまり、ACIDトランザクションやタイムトラベルができる。
リポジトリへの追加
Gitに公開されているコードを活用するには、Databricks Workspaceのリポジトリに登録します。GithubのURL を入力して、「リポジトリの作成」をクリックしてください。
追加したリポジトリには、以下の3つのノートブックが含まれています。内容は後述します。
- 00-setup
- 01-dcm-demo
- 02-dcm-browser
クラスタの作成
デフォルト値でクラスタを作成してください。私が実行したときは以下のランタイム、構成を使用しました。
- Databricks Runtimeのバージョン:11.3 LTS (includes Apache Spark 3.3.0, Scala 2.12)
- クラスタの構成
- インスタンスタイプ:i3.xlarge(4vCPU、30.5GBメモリ)
- ドライバーノード:1台
- ワーカーノード:2~8台(クラスタ全体で、8~32vCPU、61~244GBメモリ)
クラスタの設定について、より詳細な情報が知りたい方は以下の記事を参照ください。
前準備(00-setup)
前準備のノートブックで、後述する2つのノートブックから呼び出されます。よって、単体で実行する必要はありません。次の処理を実施しています。
-
ライブラリのインストールを実施
- pydicom、s3fs、python-gdcm のインストールを実施。
- pydicom、s3fs、python-gdcm のインストールを実施。
-
インプットパラメータの定義
- 1.0 Path to directory tree containing files. /dbfs or s3:// supported
DICOMデータの格納先のパス。S3のURLかDBFSのパスを指定する。「s3://hls-eng-data-public/dicom/ddsm/」がデフォルト値で、サンプルデータが格納されている。
- 2.0 Catalog Schema Table to store object metadata into
DICOMデータから抽出したメタデータやサムネイルを保存するテーブルを指定する。デフォルト値は「hive_metastore.pixels_solacc.object_catalog」となる。
- 3.0 Update mode on object metadata table
メタデータの更新方法の指定。「overwrite(上書き)」「append(追加)」から選択する。デフォルト値は「overwrite(上書き)」となる。
これらの定義により、ノートブックの上部に以下のようなインプットウィジェットが表示されるようになります。
- 1.0 Path to directory tree containing files. /dbfs or s3:// supported
-
スキーマの初期化
- インプットパラメータの2.0で指定されたスキーマが存在しない場合は作成する。
DICOMデータの分析(01-dcm-demo)
いよいよ本処理です。10426個のサンプルファイルに対して、DICOMデータからメタデータの抽出とサムネイル画像の生成を行い、データをテーブル化します。その後、SQLを用いていくつかの分析を行います。
私が実行したときはデータをテーブル化するところまでに約40分かかりました。よって、1000ファイルの処理に約4分のスピード感です。お手元の環境とぜひ比較して見てください!
それでは、細かい処理を見ていきましょう。
データの読み込み
ライブラリをインポートして、ファイルを読み込みます。table
とpath
変数にはインプットパラメータの値が格納されています。
from databricks.pixels import Catalog
from databricks.pixels.dicom import DicomMetaExtractor, DicomThumbnailExtractor # The Dicom transformers
catalog = Catalog(spark, table=table)
catalog_df = catalog.catalog(path=path)
各カラムの意味は以下はREADMEに記載されているER図を見るとわかります。
データの例も以下に示します。
rowId | path | modificationTime | length | relative_path | local_path | extension | path_tags |
---|---|---|---|---|---|---|---|
6157 | s3://hls-eng-data-public/dicom/ddsm/normals/patient6419/6419.LEFT_CC.dcm | 2022-11-16T17:15:13.000+0000 | 5155662 | s3://hls-eng-data-public/dicom/ddsm/normals/patient6419/6419.LEFT_CC.dcm | s3://hls-eng-data-public/dicom/ddsm/normals/patient6419/6419.LEFT_CC.dcm | dcm | ["patient6419","6419","LEFT","CC","dcm"] |
7075 | s3://hls-eng-data-public/dicom/ddsm/cancers/patient8189/8189.LEFT_CC.dcm | 2022-11-16T17:05:44.000+0000 | 4899574 | s3://hls-eng-data-public/dicom/ddsm/cancers/patient8189/8189.LEFT_CC.dcm | s3://hls-eng-data-public/dicom/ddsm/cancers/patient8189/8189.LEFT_CC.dcm | dcm | ["patient8189","8189","LEFT","CC","dcm"] |
7947 | s3://hls-eng-data-public/dicom/ddsm/benigns/patient9669/9669.RIGHT_MLO.dcm | 2022-11-16T16:56:28.000+0000 | 4672102 | s3://hls-eng-data-public/dicom/ddsm/benigns/patient9669/9669.RIGHT_MLO.dcm | s3://hls-eng-data-public/dicom/ddsm/benigns/patient9669/9669.RIGHT_MLO.dcm | dcm | ["patient9669","9669","RIGHT","MLO","dcm"] |
8917 | s3://hls-eng-data-public/dicom/ddsm/benigns/patient8186/8186.RIGHT_MLO.dcm | 2022-11-16T16:54:42.000+0000 | 4403956 | s3://hls-eng-data-public/dicom/ddsm/benigns/patient8186/8186.RIGHT_MLO.dcm | s3://hls-eng-data-public/dicom/ddsm/benigns/patient8186/8186.RIGHT_MLO.dcm | dcm | ["patient8186","8186","RIGHT","MLO","dcm"] |
... | ... | ... | ... | ... | ... | ... | ... |
DICOMデータからメタデータを抽出
先ほど作成したcatalog_dfからDICOMデータを読み込み、メタデータを抽出します。内部では、PyDicom と gdcmを使用してファイルを解析しています。メタデータは、meta
カラムにJSON文字列として格納されます。
meta_df = DicomMetaExtractor(catalog).transform(catalog_df)
作成されたデータフレームの構造は以下の通りです。is_anon
とmeta
というカラムが追加されていることがわかります。
DICOMデータからサムネイルを抽出
先ほど作成したmeta_dfからDICOMから画像データを読み込み、メタデータとともにインラインでサムネイル(約45KB) を保存します。
thumbnail_df = DicomThumbnailExtractor().transform(meta_df)
作成されたデータフレームの構造は以下の通りです。thumnail
というSTRUCT型のカラムが追加されていることがわかります。
このthumnail
カラムの中には、origin
、height
、width
、・・・というカラムがネストされていますが、Apache Sparkの Image data source という画像をテーブルとして処理、格納する機能が使われています。
thumnail
のデータの例も以下に示します。テーブルの中に画像が保存されていますね。
テーブルとして保存
これまで作成してきたthumbnail_df
をDeltaテーブルとして保存します。
catalog.save(thumbnail_df, mode=write_mode)
テーブルにクエリを実行して見ましょう。
${c.table}
には、インプットパラメータ02の設定値であるhive_metastore.pixels_solacc.object_catalog
が格納されています。
※%sql
は、DatabricksノートブックでSQLを実行する際に指定するマジックコマンドです。
%sql describe ${c.table}
コードを実行すると以下のようにスキーマ情報が出力され、テーブルとして定義されていることがわかります。データエクスプローラからも参照できるようになっています。
以下のようにselect文を実行するとthumbnail_df
と同じ内容を取得できます。
%sql select * from ${c.table}
ここまでの手順で、Amazon S3に格納されていたDICOMファイルをテーブル化することができました。細かく見てきたので長く感じたかもしれませんが、実はたったの7行でこの作業を実現しています。
ファイルのメタデータ分析
このノートブックにはいくつかテーブルを分析するためのクエリが記載されているのご紹介します。
まずは、簡単なところから。10426という結果が返ってくるため、全てのサンプルデータがテーブルとして保存されていることがわかります。
%sql select count(*) from ${c.table}
もう少し複雑な集計です。サンプルデータ中のDICOMデータの統計値を算出しています。
%sql
with x as (
select
format_number(count(DISTINCT meta:['00100010'].Value[0].Alphabetic),0) as patient_count,
format_number(count(1),0) num_dicoms,
format_number(sum(length) /(1024*1024*1024), 1) as total_size_in_gb,
format_number(avg(length), 0) avg_size_in_bytes
from ${c.table} t
where extension = 'dcm'
)
select patient_count, num_dicoms, total_size_in_gb, avg_size_in_bytes from x
結果は以下の通りです。患者数、DICOMデータのファイル数、ファイルの合計サイズが出力されました。
さらに複雑なパターンです。meta
カラムに格納されているJSONデータからデータを抽出しています。
ちなみに、キーに使っている8桁の数字の意味はこちらから調べることができます。
例えば、Patient's Name
属性はここを見ると、Tag(0010,0010)で定義されているので、00100010
を指定していることがわかります。
%sql
SELECT
rowid,
meta:['00100010'].Value[0].Alphabetic patient_name,
meta:['00082218'].Value[0]['00080104'].Value[0] `Anatomic Region Sequence Attribute decoded`,
meta:['0008103E'].Value[0] `Series Description Attribute`,
meta:['00081030'].Value[0] `Study Description Attribute`,
meta:`00540220`.Value[0].`00080104`.Value[0] `projection`, -- backticks work for numeric keys
split(meta:`00081030`.`Value`[0],'_')[0] `Label`,
split(meta:`00081030`.`Value`[0],'_')[1] `Instance`
FROM ${c.table}
結果は以下の通りです。JSONからテーブル形式でデータを見ることができます。だいぶデータが整理されたように見えますね!
Databricksでは、ノートブックで表示したデータに対して、シームレスにデータの可視化やデータプロファイリングを行うこともできます。 上記のテーブルに対して、各label
に対して患者数がどのくらいいるのかをグラフにして見ました(ここはオリジナルです)。この後、機械学習を行う際に学習データの偏りを調べたりするのに便利です。
DICOMブラウザ(02-dcm-browser)
作成したテーブルを活用して、DICOMブラウザを作っています。驚きです。
ノートブックを実行すると以下のように画像の一覧が表示されます。左側にあるボタンを押すと画像の絞り込みも行えます。
画像をクリックすると拡大も行えます。
データフレームをアプリ化するには、Streamlitを使うことが多いように感じますが、ノートブックだけでもここまでできるのは正直驚きました。
参考
調査の中で見つけたDICOMデータをApache Sparkで扱うためのライブラリを参考としてご紹介します。
spark-tk
SPARK + AI Summit 2020(現在のDATA + AI Summit)で「A Predictive Analytics Workflow on DICOM Images using Apache Spark」というタイトルで事例が公開されています。
事例があることもあり、当初はこのライブラリを使用しようと考えましたが、リリースが2017年で止まっていることと、相当古いpipを使わないとREADMEの通りにインストールできないことが分かったため、調査対象から外しました。
spark-dicom
こちらは、Gitには公開されていますが、正式にリリースされていないようなので調査対象外にしています。
おわりに
いかがでしたでしょうか?
本記事では以下の3つのポイントを中心にご紹介しました。
- DICOMデータに関する知識
- 非構造化データをDatabricksで活用する方法
- Databricksソリューションアクセラレータによるデータ分析の加速
特に非構造化データを大規模に処理することができる点、分析ナレッジがソリューションアクセラレータとして公開されている点はDatabricksの大きな特徴だと思います。
データの量や種類が日々増えている昨今の状況で、データ分析を効率的に進めるため、Databricksを活用しましょう!!
仲間募集中!
NTTデータ Data&Intelligence事業部 では、以下の職種を募集しています。
1. 「クラウド技術を活用したデータ分析プラットフォームの開発・構築(ITアーキテクト/クラウドエンジニア)」の募集
クラウド/プラットフォーム技術の知見に基づき、ITアーキテクトまたはPMとして、DWH、BI、ETL領域における、ソリューション開発の推進や、コンサルティング工程のシステムグランドデザイン策定時におけるアーキテクト観点からの検討を行う人材を募集しています。2. AI/データ活用を実践する「クラウド・ソリューションアーキテクト」の募集
AI/データ活用を実践する「クラウド・ソリューションアーキテクト」として、クラウド先進テクノロジーを積極活用し、お客様のビジネス価値創出活動を実践。AI/データ活用の基本構想立案コンサルティングからクラウドプラットフォーム提供・活用を支援しています。お客様のAI・データ活用を支援するクラウド・ソリューション提案、アーキテクチャ設計・構築・継続活用支援(フルマネージドサービス提供)、および最新クラウドサービスに関する調査・検証で、クラウド分析基盤ソリューションのメニュー拡充を実施する人材を募集します。また、取り扱う主なソリューションについては、以下のページも参照ください。