無料のDatabricks Community EditionでSpark NLPを使って自然言語処理をやってみる

無料で利用できるDatabricksコミュニティエディションがあることは意外と知られていないと思います。

コミュニティエディションについてはこちらの記事をご覧ください。機能制限はありますが、Databricksの使用感を体験していただくには好適な環境です。

https://databricks.com/jp/international-blogs/get-started-with-databricks-community-edition-jp

https://qiita.com/taka_yayoi/items/800fd2714f460a9a1c40

Spark NLPがマイブームなのでコミュニティエディションで自然言語処理にトライしてみました。

https://www.johnsnowlabs.com/spark-nlp/

画像編は[こちら](https://qiita.com/taka_yayoi/items/1c02542125bc327282d5)です。

# Databricksコミュニティエディションへのサインアップ

以下のリンク先の手順に従ってアカウントを作成し、Databricksコミュニティエディションにログインします。

https://qiita.com/taka_yayoi/items/fb4f57c069e1f272e88a#%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%B8%E3%81%AE%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%A2%E3%83%83%E3%83%97

![Screen Shot 2022-04-23 at 8.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ec6d3594-f9fe-3571-b788-c0911c5a44e8.png)

ランディングページが表示されます。
![Screen Shot 2022-04-23 at 8.52.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ef86c97e-64c2-90b1-55c4-0ff390dcd7bb.png)

# 言語設定

GUIの言語設定が英語なので日本語に変更します。

1. 画面左のサイドメニューの下にある歯車のマークをクリックし**User Settings**を選択します。
![Screen Shot 2022-04-23 at 8.54.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7355c3d5-ea97-c079-73b7-4613b6005b91.png)

2. 画面右上にある**Language settings**をクリックします。
![Screen Shot 2022-04-23 at 8.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/31f77761-8579-cfed-6662-ebe0880b21fb.png)

3. **Change your language**で**日本語**を選択します。
![Screen Shot 2022-04-23 at 8.56.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b76760af-37c5-13bf-5b02-b1e35e16e62d.png)

これでGUIが日本語になりました。
![Screen Shot 2022-04-23 at 8.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/da4f72af-bd33-6bcb-bb28-c219c0187fb1.png)

# クラスターの作成

DatabricksでPythonを実行するなど計算処理を行うためには計算資源である「クラスター」が必要となります。

1. サイドメニューの**クラスター**をクリックします。
![Screen Shot 2022-04-23 at 8.58.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/760aae58-4d62-de0b-0154-7f816b117c0c.png)

1. **クラスターの作成**ボタンをクリックします。
![Screen Shot 2022-04-23 at 8.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e2a9db9d-812b-e978-e015-e2c8eac6e25c.png)

1. **クラスター名**にクラスターの名前を入力します。**Databricks Runtime**とは、クラスター上にインストールされるソフトウェアパッケージです。ここでは、**Runtime: 10.3 ML (Scala 2.12, Spark 3.2.1)** を選択します。表示されている文字の意味は以下の通りです。
    - **Runtime:** の後ろの数字はバージョンです。
    - **ML**は機械学習ランタイムを意味し、scikit-learnやPyTorch、TensorFlowなど著名なライブラリも一緒にインストールされます。機械学習に関わる作業を行う際には機械学習ランタイムを選択すると環境構築の手間を省くことができます。
    - **LTS**はLong Term Supportの略で現時点で最もサポート期間が長いランタイムであることを意味します。
    - 括弧内の文字はScalaとSparkのバージョンです。
![Screen Shot 2022-04-23 at 11.02.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/714434b2-c8aa-a186-8d9e-efbcf0f55c63.png)

1. 他はそのままで**クラスターを作成**ボタンを押すとクラスターの作成が始まります。
![Screen Shot 2022-04-23 at 9.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/f5a22cff-fa1e-21e8-521e-47877847110c.png)
1. クラスターが起動すると、クラスター名の右にチェックマーク入りの緑の丸が表示されます。
![Screen Shot 2022-04-23 at 10.55.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/90c55870-cdc7-1139-829e-dcc4864e465f.png)


コミュニティエディションではクラスターのスペックを変更することはできませんが、フルバージョンであれば、GPUマシンを含む任意のスペックのインスタンスでクラスターを構成することができます。

# ライブラリのインストール

クラスターの実態はクラウドサービスで提供されている仮想マシンです。クラスターを停止すると背後の仮想マシンは削除されます。このため、永続化したいデータは専用のファイルシステム(DBFS: Databricks File System)に保存する必要があります。

また、インストールしたライブラリも削除されるので、従来であればクラスターを再起動するたびに`pip`などでライブラリをインストールする必要があります。これは手間なので、ライブラリを**クラスターライブラリ**としてインストールすると、クラスター起動時に自動でライブラリがインストールされるようになります。クラスターにアクセスするユーザーは誰でもこのライブラリを利用することができます。

:::note info
**注意**
コミュニティエディションでは、一度停止したクラスターを再度起動することはできません。このため、コミュニティエディションではクラスターライブラリの意義は少ないですが、フルバージョンのDatabricksではクラスターライブラリ活用するのでこちらで紹介させていただいています。
:::

以下の手順に従ってクラスターライブラリをインストールします。

https://nlp.johnsnowlabs.com/docs/en/install#databricks-support

:::note
マニュアルには追加のSpark設定が必要と記述がありますが、なくても動くので今回は割愛します。実際には以下の手順が追加となります。

1. 作成したクラスターの画面右上の**編集**をクリックします。
1. 画面下にある**Spark**タブをクリックします。
1. **Spark構成**に以下の内容を追加します。

    ```
    spark.serializer org.apache.spark.serializer.KryoSerializer
    spark.kryoserializer.buffer.max 2000M
    ```
1. **確認して再起動**をクリックしてクラスターを再起動し設定を反映させます。
:::

以下の2つのライブラリをインストールします。

- spark-nlp
- com.johnsnowlabs.nlp:spark-nlp-spark32_2.12:3.4.3

1. クラスターが起動していることを確認(クラスター名の右にチェックボックス入りの緑の丸が表示されます)して、**ライブラリ**をクリックします。ここからクラスターライブラリをインストールすることができます。
![Screen Shot 2022-04-23 at 10.02.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e9744925-fbb8-f7c2-b19e-cf082a178cdb.png)

1. **新規をインストール**をクリックします。
1. **ライブラリのソース**で**PyPI**を選択し、**パッケージ**に`spark-nlp`と入力し、**インストール**をクリックします。
![Screen Shot 2022-04-23 at 11.03.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/793a311d-ee7d-1c2a-d184-2d136420ec60.png)

1. **新規をインストール**をクリックします。
1. **ライブラリのソース**で**Maven**を選択し、**座標**に`com.johnsnowlabs.nlp:spark-nlp-spark32_2.12:3.4.3`と入力し、**インストール**をクリックします。
![Screen Shot 2022-04-23 at 11.25.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/66790c52-da08-c52e-6726-bd1a894d2adc.png)

1. ライブラリの**ステータス**が`保留中`から`インストール済み`になったことを確認します。
![Screen Shot 2022-04-23 at 11.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1b730bfd-8595-46e5-5be5-482cce87fd5a.png)

# ノートブックの作成

自然言語処理のコードをノートブックに記述します。

1. サイドメニューの**ワークスペース**をクリックすると、ワークスペース上のフォルダーが表示されます。
1. 右上の**ホーム**をクリックすると自分のホームディレクトリに移動します。
![Screen Shot 2022-04-23 at 11.26.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/738d120f-7d6d-842f-cc5e-db44b6bee46c.png)
1. 自分のユーザー名の右にある下向き矢印をクリックします。
1. **作成 > ノートブック**を選択します。
![Screen Shot 2022-04-23 at 11.28.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/56af9bd6-f36f-5c8b-d258-078ead2479fc.png)
1. ダイアログが表示されます。
![Screen Shot 2022-04-23 at 11.29.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1c963439-5650-62e8-ba1e-4bb84848a4e6.png)

    以下の内容を入力します。
    - 名前: ノートブックの名前を入力します。例えば`DatabricksでNLP`
    - デフォルト言語: Python
    - クラスター: [上のステップ](#クラスターの作成)で作成したクラスターを選択します。

    ![Screen Shot 2022-04-23 at 11.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d2a6773d-5c4b-7b0e-12ba-3309d42d471c.png)
1. **作成**をクリックします。
1. ノートブックが表示されます。

# 自然言語処理(NLP)のコードの記述

1. 1つ目のセルにカーソルを移動し、以下の内容を入力します。必要なライブラリをインポートします。

    ```py:Python
    import sparknlp
    from pyspark.ml import Pipeline
    from sparknlp.annotator import *
    from sparknlp.base import *
    from sparknlp.training import *
    ```

1. 1つ目のセルの下にマウスカーソルを移動すると+マークが表示されるので、これをクリックします。新規セルが追加されます。
![Screen Shot 2022-04-23 at 11.33.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/45d62cc0-a015-0e3b-af70-1ebab177f2c5.png)
![Screen Shot 2022-04-23 at 11.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/de9c6566-5f24-ccbe-3d44-bf7dc876edaa.png)

1. 2つ目のセルに以下の内容を入力します。テキストの分かち書きを行うNLPのパイプラインを構築し、パイプラインを実行します。

```py:Python
document_assembler = DocumentAssembler() \
  .setInputCol("text") \
  .setOutputCol("document")

sentence_detector = SentenceDetector() \
  .setInputCols(["document"]) \
  .setOutputCol("sentence")

word_segmenter = WordSegmenterModel.pretrained("wordseg_gsd_ud", "ja").setInputCols(["sentence"]).setOutputCol("token")

pipeline = Pipeline(stages=[document_assembler, sentence_detector, word_segmenter])

ws_model = pipeline.fit(spark.createDataFrame([[""]]).toDF("text"))

example = spark.createDataFrame([['データブリックスは、学術界とオープンソースコミュニティをルーツとするデータ＋AIの企業です。']], ["text"])
result = ws_model.transform(example)
display(result)
```

# コードの実行

画面右上にある**すべてを実行**をクリックするとノートブックの全てのセルが実行されます。
![Screen Shot 2022-04-23 at 11.36.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8edc22c1-a03d-19ab-b61d-d56c8fadb0c6.png)

2つ目のセルの実行結果を右にスクロールすると`token`列に分かち書きされた結果が格納されています。
![Screen Shot 2022-04-23 at 11.38.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/32363e0c-640a-a5e0-1a9b-95fb748cee0b.png)

セルごとに実行する場合には、セルの右上の▶︎をクリックし、**セルを実行**を選択します。キーボードの`<Ctrl> + <Enter>`でショートカットできます。
![Screen Shot 2022-04-23 at 11.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6aebd963-4dd4-381b-f03b-5b67eb071549.png)

例えば、上を実行した後で3つ目のセルに以下の内容を記述し、このセルだけを実行することでいろいろなテキストを対象に処理を行うことも可能です。

```py:Python
example = spark.createDataFrame([['お腹が空きました']], ["text"])
result = ws_model.transform(example)
display(result)
```

# 結果を見やすくするために一時ビューを活用

上の結果はネストされており一覧性に難があります。ここでは、Databricksのデータベース機能を活用してSQLで結果を整形します。

DatabricksにはHiveメタストアが同梱されているので、データベースの用途としても使用することができます。

以下のコマンドを実行してデータフレームを一時ビューとして登録します。なお、テーブルとして永続化することも可能です。

```py:Python
result.createOrReplaceTempView("result")
```

これで`result`という一時ビューが作成されました。これに対してSQLのクエリーを実行することができます。ところで、ノートブックを作成する際にデフォルト言語を**Python**にしたことを覚えていますでしょうか。このノートブックはPythonノートブックなので、SQLを実行するには専用の関数(`spark.sql`)を使わなくてはいけないのでしょうか...そんなことは不要です！

Databricksノートブックでは、セル単位で言語を切り替えることができます。以下のようにセルの先頭にマジックコマンド`%sql`を記述するだけで、このセルでSQLを実行することができるようになります。他にも`%r`、`%scala`、`%sh`(シェル)、`%md`(マークダウン)などがサポートされています。

```sql:SQL
%sql
SELECT token.result FROM result;
```

このようなクエリーを実行することで、ネストされている中身のみを取り出すことができます。
![Screen Shot 2022-04-23 at 11.50.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/5c76a42f-b463-4896-502a-e2c99e7ca1b9.png)

# さいごに

先日の[ウェビナー(近いうちにオンデマンド視聴できるようになります)](https://databricks.com/p/webinar/202204-apj-ve-fundamental-series-nlp)でこちらのSpark NLPをご紹介させていただきましたが、大量テキストデータに対するスケーラビリティの確保にSparkの並列分散処理機能を活用でき、かつ、日本語にも対応しているので非常に使い勝手のいいライブラリだと思います。私もいろいろ試してみようと思っています。

自然言語処理の技術の進展によって以下のようなユースケースが実現されているのは、20年近くNLPに携わってきた人間からすると非常に興味深いです。

- [ヘルスケアにおける大規模テキストデータへの自然言語処理の適用](https://qiita.com/taka_yayoi/items/fcf396cf75418e87ec76)
- [自然言語処理によるリアルワールド診療データからのオンコロジー\(腫瘍学\)に関する洞察の抽出](https://qiita.com/taka_yayoi/items/7bebfa4bc107b0638eab)
- [NLPを用いた薬害イベント検知による薬品安全性の改善](https://qiita.com/taka_yayoi/items/35863e696c72f0d08909)
- [ソリューションアクセラレータ：ゲームにおける有害行為の検知](https://qiita.com/taka_yayoi/items/c8f26711420d3a7f16a8)
- [ESGに対するデータドリブンアプローチ](https://qiita.com/taka_yayoi/items/fb5c5d79a9f73cd4896d)

この他にもSpark NLPを紹介している記事を書いています。ほぼ翻訳ですが。

- [日本語に対してSpark NLPを使う](https://qiita.com/taka_yayoi/items/f34a5accaa8f7cad603a)
- [Apache Spark向け自然言語処理ライブラリのご紹介](https://qiita.com/taka_yayoi/items/fd7d099dfd8b25486499)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)