データサイエンティストとは何か論争にAI(gpt-2)で終止符を打とうとした話

みなさん、こんにちは！

こちらは[「ABEJA AdventCalendar　2021」](https://qiita.com/advent-calendar/2021/abeja) の15日目の記事です。

# データサイエンティストとは？

いきなりですが、データサイエンティストとは何でしょうか？

私自身、データサイエンティストとして働いていますが、最近よく「データサイエンティストになるにはxxxxのスキルが必要だ」とか「データサイエンティストとはxxxxだ」みたいな~~論争~~話題をよく聞きます。

データサイエンティストという職業をよく耳にするようになってから、まだ時間も経っていないですし、今後どうなっていくのかも分かりません。
そんな中、データサイエンティストになるべく、データサイエンティストとして今後もキャリアを続けていけるようになるべく、各々がキャリアについて考えているので、色々な意見が出てくるのは自然なことかもしれません。

しかしまぁよく分からないですよね。


ということで、人々による議論も大事ですが、終止符を打ちたくなってきました。

# AIに聞いてみよう

もういっそAIにデータサイエンティストとは何か聞いてみましょう（唐突）

データサイエンティストが作り上げてきたAIに、データサイエンティストとは何かを聞いてみるわけです。
彼ら（AI）のほうがデータサイエンティストについて詳しいのではないか？ということです。（謎）

もう少し具体的には、自然言語処理の分野で話題となっている文章生成モデル「GPT」に聞きます。

~~文書生成やったことなかったので、遊びたかっただけです。~~


gpt-3を試したいとこですが、日本語の公開モデルはない＆スクラッチで学習させるのはコスト的に現実的ではないので、今回はgpt-2を使います。


# どうやって聞くか

次の章で詳細は説明しますが、gpt-2は文書生成が出来る深層学習モデルです。文章を入力すると、その続きの文章を生成することが可能です。
そこで今回は「データサイエンティストとは」と入力したときの出力結果を見ます。
結果として、「データサイエンティストとはxxxxx」という出力がでて、データサイエンティストとは何かの答えを導いてくれることを期待します。 :hugging: 



# gpt-2とは

gpt-2は「[Language Models are Unsupervised Multitask Learners」](https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf)というOpenAIから出ている論文で発表されたモデルです。

簡単に言うと、

- Transformerと言うBERTなどで使われている構造を使って、よりたくさんのパラメータを持ったモデルを、よりたくさんのデータで事前学習させた
- いろんな言語タスクで、タスクごとにチューニングしなくても良い精度が出た

というものです。
そしてこの言語タスクの一つとして、文書生成があります。

精度が高すぎて、フェイクニュースなどに悪用されるのではないか？危険すぎるのでは?と発表された当時は話題になっていました。

ちなみに、gpt-3ではさらに、これよりも更に大きなパラメータ・データで学習させて、より良い精度が出ています。

# 文書生成について

文書生成について簡単に説明します。
（そんなことより結果が見たい人は読み飛ばしてください）

まずgpt-2では、事前学習として次の単語を予測するタスクを解きます。

例えば、入力として：
`「私は明日ピクニックに」`
と入力されたときにモデルは次の単語として、
`出かける: 0.3`
`行く: 0.2`
`友達: 0.1`
`車: 0.08`
みたいな形で予測します。
そして、実際の次の単語を正解データとして、学習していきます。

文書生成ではこのタスクを連続的に行います。

例えば、↑の例を使うと
`「私はピクニックに」`→ `「出かける」` と予測
`「私はピクニックに出かける」`→`「途中」`と予測
`「私はピクニックに出かける途中」`→`「に」`と予測
`「私はピクニックに出かける途中に」`→`「お弁当」`と予測
`「私はピクニックに出かける途中にお弁当」`→`「を」`と予測
`「私はピクニックに出かける途中にお弁当を」`→`「忘れた」`と予測

というように再帰的に予測をしていくことで、「私はピクニックに」という入力から、「私はピクニックに出かける途中にお弁当を忘れた」という文章を作ることができます。

## もう少し細かく

上記の再帰的に予測していく部分について、実際にはいくつかの方法があります。
今回複数の方法を試そうと思うので少しだけ記載します。

一つ一つの単語の予測時には、`出かける: 0.3, 行く: 0.2, ...`という形で複数の候補が予測スコアとして出力されます。
これをどう活用するかが以下の方法毎に違います。

以下のサイトに分かりやすく説明されており、こちらの図を拝借して説明します。
より詳しく知りたい方はこちらを直接見ていただいたほうが良いかもしれません。

https://huggingface.co/blog/how-to-generate

### Greedy Search

最もシンプルで、各予測時の最もスコアが高いものを選択します。
下図において、`The`がinputとしたときに、`nice`が0.5で最もスコアが高いので`The nice`とします。次に`woman`が0.4で最も高いので`The nice woman`と生成します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854045/b369e478-afed-e1e9-8d8f-eee35fba61aa.png)

### Beam Search

`The`の時点で、１つの予測だけを見ると、`dog`より`nice`のほうがスコアが高いので良いように見えますが、その次まで見てみると、
`The nice`(0.5) → `woman`: 0.4
`The dog`(0.4) → `has`: 0.9

確率として考えると、1つ目では0.5x0.4=0.2、２つ目では0.4x0.9=0.36であり、`The dog has`を選んだほうがトータルとしてのスコアは高くなります。
ビームサーチでは、１つ先の予測だけでなく、さらに先の予測も含めてスコアの高いものを選ぶようにします。
何個先まで見るか？はBeam Searchでの一つのパラメータになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854045/14625bcc-941f-447c-7f8b-f0445cacfb80.png)



### Sampling

最も高いものを選ぶのではなく、確率的に選びます。

下図において、`The`がinputとしたときに、`car`が10%の確率で選ばれ`The car`とします。次に`drives`が50%の確率で選ばれ`The car drives`と生成します。
確率的なので、同じinputから複数個の文章を生成できます。

Samplingでは、あまりにマイナーなものを選ばないようにTopK個の中から選ぶ、スコアを出すSoftmaxを温度付きにして調整する等、様々なパラメータでの調整が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854045/7ba2059b-2fcf-6c9c-b0f2-a765a5cca420.png)




# まずは事前学習済みモデルで試してみる

事前学習済みモデルとしては、[rinna社](https://rinna.co.jp/) が提供してくれている日本語モデルを利用させていただきます。

`gpt2-small`と `gpt2-medium`があり、今回はよりパラメータの多い`gpt-medium`を採用します。

事前学習済みモデルでの非常に言語生成は非常に簡単で、以下のような形で出力ができます。

```shell
$ pip install transformers sentencepiece
```

```python
from transformers import T5Tokenizer, AutoModelForCausalL

# modelとtokenizerを定義
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt2-medium")
tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt2-medium")
tokenizer.do_lower_case = True

PREFIX_TEXT = "私はピクニックに"

# textをtokenizerでencoding
input = tokenizer.encode(PREFIX_TEXT, return_tensors="pt")
# テキストの生成(こちらはSamplingでの出力)
output = model.generate(input, do_sample=True, num_return_sequences=5) 
# モデルの出力を文字列に直す
outputs = tokenizer.batch_decode(output)
for s in outputs:
    print(s)

```

以下の結果では各条件について以下の設定で出力しました。

```python
# greedy search
model.generate(input,  max_length=50, repetition_penalty=3.0) 

# beam search
model.generate(input, do_sample=True, max_length=50, num_beams=10, repetition_penalty=3.0) 

# sampling
output = model.generate(input, do_sample=True, max_length=50, num_return_sequences=5)
```

ここで設定したもの以外にもたくさんのパラメータがあって、それについては下記の公式ドキュメントを見るのをおすすめします。

https://huggingface.co/docs/transformers/master/en/main_classes/model#transformers.generation_utils.GenerationMixin.generate

では早速結果を見てみましょう！
上記の複数の手法、最初の句点「。」までの結果を表示しています。

### 事前学習済みモデルでの結果


**データサイエンティストとは、コンピュータの処理能力や計算資源を活用する専門家。 (greedy)**

**データサイエンティストとは、機械学習や人工知能(ai)などの技術を活用して問題を解決する専門家。 (beam search)**

**データサイエンティストとは、データを収集・分析して課題の発見、解決、創出するスペシャリストである。  (sampling)**


おぉ、それっぽいですね！
beam searchとsamplingでの結果は、いかにも教科書に載ってそうな説明です。（samplingは複数出力の中で1つのみ記載しています。）

greedyの結果は、少し面白いですね。
コンピュータの処理能力や計算資源を活用すること自体あくまで手段という感じではありますが、深層学習ブームでより計算資源が重要になっているので言わんとしていることは分かります。ただ、深読みすると皮肉がきいた文章にも思えてきます笑

というかgptさん、あなたこそコンピュータの処理能力や計算資源のおかげで生まれたんやで？


# AIベンチャー（弊社）の知見をgpt-2に詰め込んだ上で改めて聞いてみる

上記のgpt-2はあくまで公開データを中心に事前学習しています。
よりビジネスに近いところで貯められた知見を学習させれば、もっとデータサイエンティストの本質に近づけるのではないでしょうか？

ということで、自社に溜まったテキストデータを使って学習をしたいと思います。
弊社ABEJAは創業から10年近くAI・データサイエンスを中心に様々なビジネスをやってきました。
この中にこそ、何かデータサイエンティストの鍵を握るものがあるかもしれません！

ちょうど社内のドキュメントツールをNotionに移行したところ（[こちら](https://qiita.com/Z-me/items/575cdd6f7903043382cb)の記事で紹介しています。）で、前に使っていたDocbaseのログが出力されていたので、それを連携してもらい、学習に使いました。

## 前処理

Docbaseのメモテキストをそのまま入れても上手く生成できなかったため、試行錯誤の結果、以下のようなテキスト前処理を行いました。
詳細は割愛します。

- Markdown特有の記号系（リンク表記、表題、チェックボックスなど）を消去
- 明らかに短い文を除去
- 英語のみの文章を除去
- 「DS」という単語を「データサイエンティスト」に置き換える
    - できるだけデータサイエンティストを含んだ文章を学習させたかったが、弊社ではデータサイエンティストのことをDSと略すことが多かったため
    - 具体的にはSudachiで形態素解析して「DS」という単語であればそれをデータサイエンティストに置き換えるようにした
    - 例： DSがRDSを使った　→　データサイエンティストがRDSを使った　（RDSはそのままにする）

## 学習

学習については、以下の記事も参考にさせていただきながら、transformersのコードを使って学習を実行しました。
(`transformers/examples/pytorch/language-modeling/run_clm.py`)

[GPT-2をファインチューニングしてニュース記事のタイトルを条件付きで生成してみた。](https://qiita.com/m__k/items/36875fedf8ad1842b729)
[gpt2-japaneseの使い方 (2) - GPT-2のファインチューニング](https://note.com/npaka/n/ne55d063e1ed8)


## 結果

あまりうまく行きませんでした:innocent:

具体的にはデータサイエンティストとは何か？の答えになっていない、どこかの文章をそのままコピーしているだけのような形になりました。

実質社内情報に近いものが多く、載せられないものが多いですが問題なさそうな失敗例を記載します。

`データサイエンティストとは、データサイエンスという言葉が世の中で一般化されるようになったのは、最近になってからだ。`
`データサイエンティストとは、4.slackでメンバーに共有をお願いします。`
`データサイエンティストとは、AIやIoTなどの最先端技術を活用したデータ活用推進の実務経験`

「データサイエンティスト」という単語だけ拾ってきて、それに近しい場面で出てきた文章を生成している印象です。
あとは、社内の文章のため、「xxxとはyyyである」というより「xxxとは一緒にやっていけそうだ」というような 「とは」を別の意味で使うことが多かった可能性もありますし、そもそも文章の質だったり量だったりの問題もあると思います。

学習自体もパラメータ調整に十分時間を取れなかったことから、もう少し改善の余地があると思われます。


ただ、1つだけ良さそうなものが生成できていたのでそれを紹介したいと思います。

**データサイエンティストとは、お客さんに寄り添って、データを見て分析をすることで、ビジネスをより面白くしたり、楽しくしたりすることができる人です。** 

個人的には弊社の文化や考え方が反映されている気がしていて、納得感もあり、非常に好きな文です。
これが生成されただけでも個人的には良かったです。
（ちなみに同一の文章が存在するわけではありませんでした。）


# 最後に

結局、データサイエンティストとは何か、AIに聞いても終止符を打てませんでした（それはそう）。
ですが、いくつか面白い答えも得られましたし、文書生成で遊べたので満足です。


最後にgpt-2の言葉を借りて、**お客さんに寄り添って、データを見て分析をすることで、ビジネスをより面白くしたり、楽しくしたり**を一緒にしてくれる方をABEJAでは募集しています。

「世の中にとっての、ABEJAにとってのデータサイエンティストとは何か？」といったカジュアルな話からでもウェルカムです！
データサイエンティスト以外も募集しています。[こちら](https://hrmos.co/pages/abeja/jobs)から募集職種一覧は確認できます。

ご応募・ご連絡をお待ちしております！