まとめ: 言語処理100本ノックで学べることと成果

**言語処理の入門とも言える[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)を終えました**:angel:
2015年版なので少し古いですが、少し自分なりに内容変えたりしながらやりました。今は[2020年版](https://nlp100.github.io/)がありますが、内容は同じものも多いです。ノックをやることで**言語処理入門者が初中級くらいのレベルになり、Pythonの腕も上がります**(やる前が大したことがないので当然上がる)。
ただ、私は最初はすごい流してやっていたのですが、すべてをやりきった後にもう一度見返しました。最初の方の章は全然身についていないと感じ、流していた部分は2度目をやり直しブログ記事にしました。やはり時間をかけて考え、何かに(私の場合ブログ記事に)アウトプットしないとあまり意味ないですね。ただ、途中仕事が忙しかったり他の勉強に浮気していたりと1年半かかったのが原因でもあります。

# サマリ

|項目|内容|
|:-:|:--|
|目的|言語処理の基礎を学ぶため|
|期間|約1年半(他のこともやっていたので・・・)|
|総時間(実績)|184時間弱|
|使用プログラム言語|Python(ほぼJupyter Lab)/Unixコマンド|
|環境|Ubuntu18.04.01LTS + Pyenv + venv + Jupyter|

## 学んだことサマリ
**言語処理において必要な知識・技術について体系的に学べました。**私にとっては機械学習以外はどれも未経験領域で非常に学ぶことが多かったです。
３章以降はそれぞれの内容が深いので、ただコピペでわかった気になると得るものが少ないかもしれません(体験談)。また、**プログラム上で課題を達成できたとしても、裏で動いているアルゴリズムや理論を理解しているかは別問題**です。その辺は個人でどこまでの学習成果を目標とすべきかを明確にして取り組むことをおすすめします。
一方でBERTなどディープラーニング系がありません。そちらを重視するのであれば、2015年版ではななく2020年版を、または両者をやる必要があります。

# 環境について
**環境をどのように構築するか(Pyenvを使うなど)は大事**です。私は、最初[Google Colaboratory](https://qiita.com/FukuharaYohei/items/18bc4465923bdda81826)使っていたのですが、ファイルのアップロード系やCaboCha等のインストールが面倒だったので途中でローカルWindows環境に切り替えました。しかしWindowsはCaboChaインストールで詰まり、Ubuntuに切り替えました(私のスキルで64bit Windowsにインストールできませんでした)。また、Pythonを辞書型を使うときに[順序性保証をするためにPython3.7.1以上](https://docs.python.org/ja/3/whatsnew/3.7.html)をおすすめします。
私にとっては[「UbuntuにpyenvとvenvでPython開発環境構築」](https://qiita.com/FukuharaYohei/items/2820f7bda6678ce26ea7)で書いた**Ubuntu + Pyenv + venvがとてもおすすめ**です(+ JupyterLabも)。
**まとめるとおすすめは以下の通り**ですが、Macユーザの方はUbuntuにこだわらなくてもいいと思います。

|種類|バージョンなど|
|:-:|:-:|
|OS|Ubuntu|
|Pythonバージョン管理|Pyenv(慣れているから)|
|Pythonバージョン|3.7.1以上|
|Pythonパッケージ管理|venv(慣れているから)|
|Python実行|JupyterLab|

# 前提知識
## 言語処理
**言語処理の前提知識は不要**です。ゼロから学べます。私はゼロからはじめました。正規表現ですらも1から2回程度使ったことがあるレベルでした。

## Python
**Pythonの前提知識不要**です。私は、100本ノックを始めた頃は初心者、中断後に再開したときは初中級レベルでした。やりながら学んでいくくらいでちょうどいいのではないかと思います。その方法だと気持ち悪いと思う方は、[「スッキリわかるPython入門 (スッキリシリーズ)」](https://amzn.to/3b0A6Fi)など初心者用の本を1冊読破した後にやる程度でもいいと思います。

## NoSQL
**NoSQLに関する前提知識不要**です。私はこのノックで初めて触りました(RDBMSは経験あり)。ただ、第7章を始める前に[「RDB技術者のためのNoSQLガイド」](https://amzn.to/2HOijWj)を購入して基本を学習しました。

## 機械学習
**機械学習に関する前提知識不要**です。ただ、前提知識がないと第8章で時間がかかると思います。私は[Coursera機械学習入門オンライン講座](https://qiita.com/FukuharaYohei/items/b2143413063376e97948)などで学んでいたので機械学習という点では苦労はしませんでした。しかし、パッケージ`scikit-learn`はあまり使ったことがなかったことや、結構こだわって精度をあげようとしたので、それでも「第8章：機械学習」に時間がかかっています。

## 数学
基本的にほとんどはパッケージ側で計算してくれるので、**ただ問題を解くだけなら前提知識不要**です。自分で計算をしているのは[「84本目「単語文脈行列の作成」](https://qiita.com/FukuharaYohei/items/3f1d448ac706ea1fb50e)と[87本目「単語の類似度」](https://qiita.com/FukuharaYohei/items/a11597c9dcfbbd212557)くらいなもので、高校数学を忘れていてもググったりしながら理解できます。
ただ、**機械学習部分を理解するなら高校卒業レベルは必要**です。「第8章：機械学習」に出てくるロジスティック回帰の数理を理解するには高校数学レベルは必須です。

# 学習の進め方
[「素人の言語処理100本ノックシリーズ」](https://qiita.com/segavvy/items/fb50ba8097d59475f760)を参考にしながらJupyter Labで問題を解いていきました。問題を解き終えたら、問題の奥にある理論などをある程度調べてブロクにまとめつつ頭の整理をしています(「まとめつつ」ではありますが記事の品質低いです)。

# 各章概要
各章の概要と学習時間、個人的難易度評価です。

|章|内容|学習時間(h)|難易度|
|:-:|:--|--:|:-:|
|第1章: 準備運動|Pythonの基礎的な練習。Python初心者に最適。|4.3|簡単|
|第2章: UNIXコマンドの基礎|UNIXコマンド基礎。Pandasについても学習。|6.6|簡単|
|第3章: 正規表現|文字列操作に欠かせない正規表現の基礎。|24.1|普通|
|第4章: 形態素解析|MeCabを使った日本語の形態素解析|14.3|普通|
|第5章: 係り受け解析|CabochaとMeCabを使った日本語の係り受け解析|28|難|
|第6章: 英語テキストの処理|Stanford CoreNLPを使った英語の言語処理|27.7|難|
|第7章: データベース|RedisとMongoDBを使ったDB処理|10.9|普通|
|第8章: 機械学習|Standord NLPとscikit-learnを使った機械学習|34.8|難|
|第9章: ベクトル空間法 (I)|scipy, numpy, scikit-learnを使った自作word2vec|23.4|普通|
|第10章: ベクトル空間法 (II)|Gensimのword2vecとクラスタリング|9.7|普通|

各章学習時間(棒)と累積学習時間(折れ線)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134273/9f516063-47c1-c5e6-f5bd-58a829186034.png)


# 各章詳細
## [第1章:準備運動](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch1)
### 学習内容
> テキストや文字列を扱う題材に取り組みながら，プログラミング言語のやや高度なトピックを復習します．

### 学習の感想など
まさに「準備運動」という名前がしっくりとくる簡単な内容。文字列処理に関する基本的な内容なので時間がかからないですが、初心者が始めるにはとてもよい教材。

|No.|項目|学んだこと|
|:-:|:--|:--|:--|
|0|[文字列の逆順](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#00-%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E9%80%86%E9%A0%86)|スライス|
|1|[「パタトクカシーー」](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#01-%E3%83%91%E3%82%BF%E3%83%88%E3%82%AF%E3%82%AB%E3%82%B7%E3%83%BC%E3%83%BC)|スライス|
|2|[「パトカー」＋「タクシー」＝「パタトクカシーー」](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#02-%E3%83%91%E3%83%88%E3%82%AB%E3%83%BC%E3%82%BF%E3%82%AF%E3%82%B7%E3%83%BC%E3%83%91%E3%82%BF%E3%83%88%E3%82%AF%E3%82%AB%E3%82%B7%E3%83%BC%E3%83%BC)|for, zip, join, リスト型内包表記|
|3|[円周率](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#03-%E5%86%86%E5%91%A8%E7%8E%87)|split, strip, len|
|4|[元素記号](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#04-%E5%85%83%E7%B4%A0%E8%A8%98%E5%8F%B7)|pprint.pprint, 辞書型, enumerate, 辞書型内包表記(if-elseあり), 辞書型ソート|
|5|[n-gram](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#05-n-gram)|n-gram, replace, rangeとfor|
|6|[集合](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#06-%E9%9B%86%E5%90%88)|set, 和集合とunion, 差集合とintersection, 積集合とdifference|
|7|[テンプレートによる文生成](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#07-%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B%E6%96%87%E7%94%9F%E6%88%90)|str, printとformat|
|8|[暗号文](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#08-%E6%9A%97%E5%8F%B7%E6%96%87)|文字コードとchr, 小文字判断とislower|
|9|[Typoglycemia](https://qiita.com/FukuharaYohei/items/72626a799c094d2cd03e#09-typoglycemia)|タイポグリセミア, random.shuffle, list関数|

## [第2章:UNIXコマンドの基礎](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch2)

### 学習内容
> 研究やデータ分析において便利なUNIXツールを体験します．これらの再実装を通じて，プログラミング能力を高めつつ，既存のツールのエコシステムを体感します．

### ノック内容
> [hightemp.txt](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/hightemp.txt)は，日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである．以下の処理を行うプログラムを作成し，hightemp.txtを入力ファイルとして実行せよ．さらに，同様の処理をUNIXコマンドでも実行し，プログラムの実行結果を確認せよ．

### 学習の感想など

|No.|項目|学んだこと|
|:-:|:--|:--|:--|
|10|[行数のカウント](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#10-%E8%A1%8C%E6%95%B0%E3%81%AE%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88)|ファイルの行数カウント, with, open, readlines, UNIX(wc)|
|11|[タブをスペースに置換](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#11%E3%82%BF%E3%83%96%E3%82%92%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%AB%E7%BD%AE%E6%8F%9B)|文字列置換, replace, UNIX(sed)|
|12|[1列目をcol1.txtに，2列目をcol2.txtに保存](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#121%E5%88%97%E7%9B%AE%E3%82%92col1txt%E3%81%AB2%E5%88%97%E7%9B%AE%E3%82%92col2txt%E3%81%AB%E4%BF%9D%E5%AD%98)|列の抽出, pandas(read_table, to_csv), UNIX(cut)|
|13|[col1.txtとcol2.txtをマージ](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#13col1txt%E3%81%A8col2txt%E3%82%92%E3%83%9E%E3%83%BC%E3%82%B8)|列のマージ, pandas(read_csv), UNIX(paste)|
|14|[先頭からN行を出力](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#14%E5%85%88%E9%A0%AD%E3%81%8B%E3%82%89n%E8%A1%8C%E3%82%92%E5%87%BA%E5%8A%9B)|ファイル先頭出力, input, break, UNIX(head)|
|15|[末尾のN行を出力](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#15%E6%9C%AB%E5%B0%BE%E3%81%AEn%E8%A1%8C%E3%82%92%E5%87%BA%E5%8A%9B)|ファイル末尾出力, writelines, math.ceil, UNIX(tail)|
|16|[ファイルをN分割する](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#16%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92n%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B)|ファイル分割, UNIX(split)|
|17|[１列目の文字列の異なり](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#17%EF%BC%91%E5%88%97%E7%9B%AE%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E7%95%B0%E3%81%AA%E3%82%8A)|ユニーク出力(重複削除), pandas(unique), UNIX(uniq, sort)|
|18|[各行を3コラム目の数値の降順にソート](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#18%E5%90%84%E8%A1%8C%E3%82%923%E3%82%B3%E3%83%A9%E3%83%A0%E7%9B%AE%E3%81%AE%E6%95%B0%E5%80%A4%E3%81%AE%E9%99%8D%E9%A0%86%E3%81%AB%E3%82%BD%E3%83%BC%E3%83%88)|ソート, pandas(sort_values)|
|19|[各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#19%E5%90%84%E8%A1%8C%E3%81%AE1%E3%82%B3%E3%83%A9%E3%83%A0%E7%9B%AE%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6%E3%82%92%E6%B1%82%E3%82%81%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6%E3%81%AE%E9%AB%98%E3%81%84%E9%A0%86%E3%81%AB%E4%B8%A6%E3%81%B9%E3%82%8B)|出現頻度カウント, pandas(value_counts)|

## [第3章:正規表現](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch3)

### 学習内容
> Wikipediaのページのマークアップ記述に正規表現を適用することで，様々な情報・知識を取り出します．

### ノック内容
> Wikipediaの記事を以下のフォーマットで書き出したファイル[jawiki-country.json.gz](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/jawiki-country.json.gz)がある．

> - 1行に1記事の情報がJSON形式で格納される
> - 各行には記事名が"title"キーに，記事本文が"text"キーの辞書オブジェクトに格納され，そのオブジェクトがJSON形式で書き出される
> - ファイル全体はgzipで圧縮される

> 以下の処理を行うプログラムを作成せよ．

### 学習の感想など
正規表現についてのとてもよい教材兼練習問題。今まで正規表現をググりながら対応してきた私にはとてもよかったです。正規表現に関して学んだことは記事[「ゼロから覚えるPython正規表現の基本とTips」](https://qiita.com/FukuharaYohei/items/459f27f0d7bbba551af7)にまとめました。

|No.|項目|学んだこと|
|:-:|:--|:--|
|20|[JSONデータの読み込み](https://qiita.com/FukuharaYohei/items/7c44961a31c637ecb863) |JSON読込, pandas(read_json)|
|21|[カテゴリ名を含む行を抽出](https://qiita.com/FukuharaYohei/items/a60defdda417fd2c17ed) |正規表現(全検索), raw文字列, トリプルクォート, re(findall, VERBOSE, MULTILINE)|
|22|[カテゴリ名の抽出](https://qiita.com/FukuharaYohei/items/3b0df4d9893b98537e95) |正規表現(非貪欲マッチ, キャプチャ対象外)|
|23|[セクション構造](https://qiita.com/FukuharaYohei/items/af3141e4cc594306801a) |正規表現(後方参照, m回の繰返)|
|24|[ファイル参照の抽出](https://qiita.com/FukuharaYohei/items/e24be2d947c3e9f9354e) |正規表現(和集合(or))|
|25|[テンプレートの抽出](https://qiita.com/FukuharaYohei/items/a0ae7f6548db309b7500) |正規表現(肯定の先読み), 順序付き辞書, re(DOTALL), collections(OrderDict)|
|26|[強調マークアップの除去](https://qiita.com/FukuharaYohei/items/57e763d01f311cd71e14) |正規表現(置換), re(sub)|
|27|[内部リンクの除去](https://qiita.com/FukuharaYohei/items/8c2cf248cf02127957c5) ||
|28|[MediaWikiマークアップの除去](https://qiita.com/FukuharaYohei/items/95a9ceaaf60858c3e483) ||
|29|[国旗画像のURLを取得する](https://qiita.com/FukuharaYohei/items/942011f53a8c66cc93aa) |REST API消費, urllib(request, parse), json(loads)|

## [第4章:形態素解析](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch4)

### 学習内容
> 夏目漱石の小説『吾輩は猫である』に形態素解析器MeCabを適用し，小説中の単語の統計を求めます．

### ノック内容
> 夏目漱石の小説『吾輩は猫である』の文章[（neko.txt）](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/neko.txt)をMeCabを使って形態素解析し，その結果をneko.txt.mecabというファイルに保存せよ．このファイルを用いて，以下の問に対応するプログラムを実装せよ．
> なお，問題37, 38, 39は[matplotlib](https://matplotlib.org/)もしくは[Gnuplot](http://www.gnuplot.info/)を用いるとよい．

### 学習の感想など
`pandas`パッケージを利用しているので、プログラム自体はだいたいシンプルで簡単です。形態素解析に馴染むための章と考えています。

|No.|項目|学んだこと|
|:-:|:--|:--|
|30|[形態素解析結果の読み込み](https://qiita.com/FukuharaYohei/items/98e3f72d323566c540b9) |MeCab, DataFrameのループ, append, pandas(to_dict, iterrows, loc)|
|31|[動詞](https://qiita.com/FukuharaYohei/items/ab58859e861afda1a301) ||
|32|[動詞の原形](https://qiita.com/FukuharaYohei/items/7cba4bcebfa8b53e5511) ||
|33|[サ変名詞](https://qiita.com/FukuharaYohei/items/24fddf5c5a8d7363e04b) ||
|34|[「AのB」](https://qiita.com/FukuharaYohei/items/f46c089f45d58bae24bc) ||
|35|[名詞の連接](https://qiita.com/FukuharaYohei/items/88b59502559731f7e8fd) ||
|36|[単語の出現頻度](https://qiita.com/FukuharaYohei/items/5d3f8fb723981b47dc50) |pandas(startswith)|
|37|[頻度上位10語](https://qiita.com/FukuharaYohei/items/dc355bcc038c2cee4de8) |matplotlibのグラフ日本語表示, pandasからの棒グラフ表示, pandas(bar)|
|38|[ヒストグラム](https://qiita.com/FukuharaYohei/items/f9e48a904fbd55dddcfe) |pandasからのヒストグラム表示, pandas(hist), matplotlib(set_xlabel, set_ylabel)|
|39|[Zipfの法則](https://qiita.com/FukuharaYohei/items/c8889b0ed0180145a282) |Zipf(ジップ)の法則, 散布図, ログスケール, matplotlib(xscale, yscale, xlim, ylim, xlabel, ylabel, scatter)|

## [第5章:係り受け解析](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch5)

### 学習内容
> 『吾輩は猫である』に係り受け解析器CaboChaを適用し，係り受け木の操作と統語的な分析を体験します．

### ノック内容
> 夏目漱石の小説『吾輩は猫である』の文章[（neko.txt）](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/neko.txt)をCaboChaを使って係り受け解析し，その結果をneko.txt.cabochaというファイルに保存せよ．このファイルを用いて，以下の問に対応するプログラムを実装せよ．

### 学習の感想など
言語処理100本ノックに鬼門に感じます。前章と異なり、パッケージの力を活用できないので、自分で面倒なアルゴリズムを組む必要があります。面倒くさがり屋としては、結構大変に感じました。新人などにやって欲しい内容。49本目は、複雑な処理を長く書くので鬼門:japanese_ogre:
また、CaboChaをWindowsにインストールできず、Linuxに開発環境にすっぱり切り替える覚悟を決めさせてくれたのはいい思い出。

|No.|項目|学んだこと|
|:-:|:--|:--|
|40|[係り受け解析結果の読み込み（形態素）](https://qiita.com/FukuharaYohei/items/0d82c43bff5ec333fb69) |クラス, クラスの変数一覧出力(__dict__), re(match)|
|41|[係り受け解析結果の読み込み（文節・係り受け）](https://qiita.com/FukuharaYohei/items/62c5336549b767b0e849) ||
|42|[係り元と係り先の文節の表示](https://qiita.com/FukuharaYohei/items/8f61dda5a974f136212d) ||
|43|[名詞を含む文節が動詞を含む文節に係るものを抽出](https://qiita.com/FukuharaYohei/items/5e6c2435bcb3f6e3789c) ||
|44|[係り受け木の可視化](https://qiita.com/FukuharaYohei/items/322447d75549f0d00f3c) |Pythonからシェルの実行, 有効グラフ表示, subprocess(run), pydot(graph_from_edges, write_png)|
|45|[動詞の格パターンの抽出](https://qiita.com/FukuharaYohei/items/8fa85ad5b2bc6937a850) |シェルでのファイル検索, ファイル書込, write, UNIX(grep)|
|46|[動詞の格フレーム情報の抽出](https://qiita.com/FukuharaYohei/items/569fbb3da8e5d0bc4b0a) |リストのソート, sort|
|47|[機能動詞構文のマイニング](https://qiita.com/FukuharaYohei/items/3ceb819fbcb3381591cd) ||
|48|[名詞から根へのパスの抽出](https://qiita.com/FukuharaYohei/items/21d5c9eb94461e6f4424) ||
|49|[名詞間の係り受けパスの抽出](https://qiita.com/FukuharaYohei/items/a9acd0abc11229b35d52) |endwith, extend|

## [第6章:英語テキストの処理](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch6)

### 学習内容
> Stanford Core NLPを用いた英語のテキスト処理を通じて，自然言語処理の様々な基盤技術を概観します．

### ノック内容
> 英語のテキスト[（nlp.txt）](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/nlp.txt)に対して，以下の処理を実行せよ．

### 学習の感想など
日本語にはなかった「レンマ」などを含んだ英語の言語処理を学びます。5章と同様に自分でロジック組む必要がある程度あり時間がかかります。59本目でS式のパーサーを作らなければならず鬼門:japanese_ogre:
※Stanford CoreNLPは2020年4月にバージョン4.0になっています。私がやった内容といろいろ違うかもしれません。

|No.|項目|学んだこと|
|:-:|:--|:--|:--|
|50|[文区切り](https://qiita.com/FukuharaYohei/items/58f3d298c397f61bf808) |printでのファイル出力|
|51|[単語の切り出し](https://qiita.com/FukuharaYohei/items/145e34319636259a1594) ||
|52|[ステミング](https://qiita.com/FukuharaYohei/items/34bb3997df85490eea3d) |ステミング, nltk(stem)|
|53|[Tokenization](https://qiita.com/FukuharaYohei/items/c50eb3b7bd079b1ac447) |Stanford CoreNLPの基本, XML解析, xml(parse, iter)|
|54|[品詞タグ付け](https://qiita.com/FukuharaYohei/items/fa5347a0d5060fd34bce) |Stanford CoreNLP(レンマ, 品詞), xml(findtext)|
|55|[固有表現抽出](https://qiita.com/FukuharaYohei/items/522ff6fef8f620c0b37a) |Stanford CoreNLP(固有表現, 人名), xml(iterfind)|
|56|[共参照解析](https://qiita.com/FukuharaYohei/items/c4df21a134f52fffc02f) |Stanford CoreNLP(共参照), xml(get), 改行なしのprint|
|57|[係り受け解析](https://qiita.com/FukuharaYohei/items/3531858c7c05ffd90363) |Stanford CoreNLP(係り受け), pydot(write_jpeg)|
|58|[タプルの抽出](https://qiita.com/FukuharaYohei/items/2a3851cc5194653a6cd1) |Stanford CoreNLP(係り受け間の関係性)|
|59|[S式の解析](https://qiita.com/FukuharaYohei/items/a2220cfe425033ba18b2) |Stanford CoreNLP(句構造解析), S式, パーサー, re(split)|

## [第7章:データベース](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch7)

### 学習内容
> Key Value Store (KVS) やNoSQLによるデータベースの構築・検索を修得します．また，CGIを用いたデモ・システムを開発します．

### ノック内容
> [artist.json.gz](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/artist.json.gz)は，オープンな音楽データベース[MusicBrainz](https://musicbrainz.org/)の中で，アーティストに関するものをJSON形式に変換し，gzip形式で圧縮したファイルである．このファイルには，1アーティストに関する情報が1行にJSON形式で格納されている．JSON形式の概要は以下の通りである．

JSON形式省略

> artist.json.gzのデータをKey-Value-Store (KVS) およびドキュメント志向型データベースに格納・検索することを考える．KVSとしては，LevelDB，Redis，KyotoCabinet等を用いよ．ドキュメント志向型データベースとして，MongoDBを採用したが，CouchDBやRethinkDB等を用いてもよい．

### 学習の感想など
第6章ではNoSQLとしてKVSとドキュメント指向DBを学びます。前者はRedisを、後者はMongoDBを使いました。言語処理100本ノックとしはLevelDBを想定しているようですが、筆者が取り組んだ2019年ではRedisの方がメジャーと考えRedisを使っています。
今までRDBMSしか扱ったことがなかったので、[「RDB技術者のためのNoSQLガイド」](https://amzn.to/2HOijWj)を購入して基本を学習しました。言語処理に限らずRDBMSの苦手部分に対応できる仕組みになっており、非常に興味深かったです。
Redisの環境構築に関しては記事[「最新RedisのUbuntuへのインストールとPythonで使うまで」](https://qiita.com/FukuharaYohei/items/4485d1b11f88fd4d1f55)に、Redisの基本については[「【初心者向け】Redisのデータ型とPythonでの使い方サンプル」](https://qiita.com/FukuharaYohei/items/48209d488bc7f412c3d7)に、MongoDBの環境構築は[「MongoDBのUbuntuへのインストールとシェルとPythonで動作確認」](https://qiita.com/FukuharaYohei/items/d109f5c3f5dce0d972e4)記録しています。

※64から69についてはQiita記事を書いておらず、GitHubのリンクのみ。「66.検索件数の取得」はシェル実行のみなのでリンクなし。

|No.|項目|学んだこと|
|:-:|:--|:--|
|60|[KVSの構築](https://qiita.com/FukuharaYohei/items/cb9c0333b1a341c74473)|NoSQL, KVS, Redis, reids-py,  Hashesデータ型, jsonパッケージ|
|61|[KVSの検索](https://qiita.com/FukuharaYohei/items/f53f2ccbd2e417118a5c)|hgetall|
|62|[KVS内の反復処理](https://qiita.com/FukuharaYohei/items/444ae057b1e8adaee5f4)|scan_iter, hvals|
|63|[オブジェクトを値に格納したKVS](https://qiita.com/FukuharaYohei/items/f30b7f2b228b0a3832fc)|hset, hvals|
|64|[MongoDBの構築](https://github.com/YoheiFukuhara/nlp100/blob/master/07.%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/064.MongoDB%E3%81%AE%E6%A7%8B%E7%AF%89.ipynb)|pymongo, list_database_names, drop, insert_many, create_index|
|65|[MongoDBの検索](https://github.com/YoheiFukuhara/nlp100/blob/master/07.%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/065.MongoDB%E3%81%AE%E6%A4%9C%E7%B4%A2.ipynb)|find, bson(Binary JSON)|
|66|検索件数の取得|count|
|67|[複数のドキュメントの取得](https://github.com/YoheiFukuhara/nlp100/blob/master/07.%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/067.%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E5%8F%96%E5%BE%97.ipynb)|input|
|68|[ソート](https://github.com/YoheiFukuhara/nlp100/blob/master/07.%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/068.%E3%82%BD%E3%83%BC%E3%83%88.ipynb)|sort, limit|
|69|[Webアプリケーションの作成](https://github.com/YoheiFukuhara/nlp100/tree/master/07.%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/069.Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90)|flask, render_template, Class|

## [第8章:機械学習](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch8)

### 学習内容
> 評判分析器（ポジネガ分析器）を機械学習で構築します．さらに，手法の評価方法を学びます．

### ノック内容
> 本章では，Bo Pang氏とLillian Lee氏が公開している[Movie Review Data](http://www.cs.cornell.edu/people/pabo/movie-review-data/)の[sentence polarity dataset v1.0](http://www.cs.cornell.edu/people/pabo/movie-review-data/rt-polaritydata.README.1.0.txt)を用い，文を肯定的（ポジティブ）もしくは否定的（ネガティブ）に分類するタスク（極性分析）に取り組む．

### 学習の感想など
機械学習についてで、「73.学習」を徹底的にやっていたら自然と第7章ほぼ全部の学習内容が終わっていました。これも[Coursera機械学習入門コース](https://www.coursera.org/learn/machine-learning/)のおかげですね。
[記事「Coursera機械学習入門オンライン講座虎の巻(文系社会人にオススメ)」](https://qiita.com/FukuharaYohei/items/b2143413063376e97948)に書いているだけの時間をかけたので当然かもしれませんが。
使っていアルゴリズムはロジスティクス回帰なので、そんなに精度出ないですが学習の基本としてとっつきやすいです。

|No.|項目|学んだこと|
|:-:|:--|:--|
|70|[データの入手・整形](https://qiita.com/FukuharaYohei/items/a78e9118c0be8a7f76a6)|codecsパッケージ|
|71|[ストップワード](https://qiita.com/FukuharaYohei/items/60719ddaa47474a9d670)|nltk, StanfordNLP, ストップワード(nltk.corpus.stopwords), stanfordnlp.Pipeline, ステム(nltk.stem), レンマ(lemma), Universal POS(upos)|
|72|[素性抽出](https://qiita.com/FukuharaYohei/items/f1a12d8e63fc576a456f)|素性(Feature), warnings.simplefilter, writerow(csvパッケージ), collections(Counterパッケージ), Pandas(value_counts, sort_values, head, describe, sort_index)|
|73|[学習](https://qiita.com/FukuharaYohei/items/ce5cc32499e87aca9298)|tf-idf, 単語のベクトル化, ロジスティクス回帰, ハイパーパラメータ探索, グリッドサーチ, パイプライン化, 交差検定, scikit-learn(CountVectorizer, TfidfVectorizer, LogisticRegression, GridSearchCV, Pipeline, BaseEstimator, TransformerMixin, fit, transform), Pandas(from_dict, to_csv)|
|74|[予測](https://qiita.com/FukuharaYohei/items/ecb71f1c2f52e89f1d72)|予測(推論), scikit-learn(train_test_split, predict_proba), numpy(argmax), Pandas(T(転置), rename)|
|75|[素性の重み](https://qiita.com/FukuharaYohei/items/adb97ac7b0ae76708f4a)|貢献度, scikit-learn(get_feature_names), matplotlib(barh)|
|76|[ラベル付け](https://qiita.com/FukuharaYohei/items/5170e189332dab71ac16)|scikit-learn(predict)|
|77|[正解率の計測](https://qiita.com/FukuharaYohei/items/534c8f63003a42d54fae)|正解率, 適合率, 再現率, F1スコア, 混合行列, scikit-learn(classification_report, confusion_matrix)|
|78|5分割交差検定|交差検定|
|79|[適合率-再現率グラフの描画](https://qiita.com/FukuharaYohei/items/4cf62ffb76b85ccbee6d)|適合率-再現率グラフ, ROC曲線, AUC, 学習曲線, scikit-learn(precision_recall_curve, roc_curve, auc, learning_curve)|

## [第9章:ベクトル空間法 (I)](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch9)

### 学習内容
> 大規模なコーパスから単語文脈共起行列を求め，単語の意味を表すベクトルを学習します．その単語ベクトルを用い，単語の類似度やアナロジーを求めます．

### ノック内容
> [enwiki-20150112-400-r10-105752.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-400-r10-105752.txt.bz2)は，2015年1月12日時点の英語のWikipedia記事のうち，約400語以上で構成される記事の中から，ランダムに1/10サンプリングした105,752記事のテキストをbzip2形式で圧縮したものである．このテキストをコーパスとして，単語の意味を表すベクトル（分散表現）を学習したい．第9章の前半では，コーパスから作成した単語文脈共起行列に主成分分析を適用し，単語ベクトルを学習する過程を，いくつかの処理に分けて実装する．第9章の後半では，学習で得られた単語ベクトル（300次元）を用い，単語の類似度計算やアナロジー（類推）を行う．
>
>なお，問題83を素直に実装すると，大量（約7GB）の主記憶が必要になる． メモリが不足する場合は，処理を工夫するか，1/100サンプリングのコーパス[enwiki-20150112-400-r100-10576.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-400-r100-10576.txt.bz2)を用いよ．

### 学習の感想など
言語処理100本ノックの鬼門と言われているようです。データ量が多いため処理時間もかかり面倒です。しかし、面倒な反面、**単語ベクトルおよびWord2Vecについてじっくりと学ぶことができ非常に有意義**なノックかと感じています。

|No.|項目|学んだこと|
|:-:|:--|:--|
|80|[コーパスの整形](https://qiita.com/FukuharaYohei/items/56a5a34ab8417baead76)||
|81|[複合語からなる国名への対処](https://qiita.com/FukuharaYohei/items/67be619ce9dd33392fcd)|正規表現の小文字・大文字識別なし(IGNORECASE), rstrip|
|82|[文脈の抽出](https://qiita.com/FukuharaYohei/items/64e20ced30cba76383dc)|対象語, 文脈語, 文脈幅(Context Window Size), writelines|
|83|[単語／文脈の頻度の計測](https://qiita.com/FukuharaYohei/items/9696afb342aa367ae5d1)|ファイルの行指定部分保存, ファイルで特定行出力, Pandas(to_pickle, groupby, agg)|
|84|[単語文脈行列の作成](https://qiita.com/FukuharaYohei/items/3f1d448ac706ea1fb50e)|PPMI(正の相互情報量), 疎行列, 変数使用メモリの出力, Pandas(read_pickle), Scipy(lil_matrix, savemat)|
|85|[主成分分析による次元圧縮](https://qiita.com/FukuharaYohei/items/f3d975e7a9a801dd29fc)|主成分分析, 特異値分解, 次元圧縮, Scipy(loadmat), scikit-learn(TruncatedSVD, explained_variance_ratio_), numpy(savez_compressed)|
|86|[単語ベクトルの表示](https://qiita.com/FukuharaYohei/items/7ae747911b42622393c1)|numpy(load)|
|87|[単語の類似度](https://qiita.com/FukuharaYohei/items/a11597c9dcfbbd212557)|コサイン類似度, numpy(dot, linalg.norm)|
|88|[類似度の高い単語10件](https://qiita.com/FukuharaYohei/items/fa4985ada2d57d60023d)|numpy(count_nonzero)|
|89|[加法構成性によるアナロジー](https://qiita.com/FukuharaYohei/items/337070e2d5e2dd0f42e4)|ベクトル計算, numpy(argsort)|

## [第10章:ベクトル空間法 (II)](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch10)

### 学習内容
> word2vecを用いて単語の意味を表すベクトルを学習し，正解データを用いて評価します．さらに，クラスタリングやベクトルの可視化を体験します．

### ノック内容
> 第10章では，前章に引き続き単語ベクトルの学習に取り組む．

### 学習の感想など
第9章と同じ内容をパッケージGensimを使って実行するのと、クラスタリング、可視化をします。オリジナルでは[Google社の`word2vec`](https://code.google.com/p/word2vec/)を使うように指示がありますが、パッケージの更新頻度からGensimの方が優れていそうなので変えています。Gensimが第9章で作った内容より優れていてパッケージの素晴らしさが体感できます。
また、クラスタリング・次元削減による単語ベクトルの可視化方法も学びます。

|No.|項目|学んだこと|
|:-:|:--|:--|
|90|[word2vecによる学習](https://qiita.com/FukuharaYohei/items/0ab5e4ccca7e1083db1f)|word2vec, Gensim(Word2Vec, Text8Corpus, save, most_similar)|
|91|[アナロジーデータの準備](https://qiita.com/FukuharaYohei/items/29d7e75cdfd8e5e2fe5b)||
|92|[アナロジーデータへの適用](https://qiita.com/FukuharaYohei/items/13310de94cdfcdf168cd)|Gensim(load)|
|93|[アナロジータスクの正解率の計算](https://qiita.com/FukuharaYohei/items/21911743de1b84462717)|Pandas DataFrameの計算|
|94|[WordSimilarity-353での類似度計算](https://qiita.com/FukuharaYohei/items/bbd3212411a14ccedb90)||
|95|[WordSimilarity-353での評価](https://qiita.com/FukuharaYohei/items/e267b49266fb31d8cdb1)|スピアマン相関係数, corr(Pandas)|
|96|[国名に関するベクトルの抽出](https://qiita.com/FukuharaYohei/items/6fe9de01d313b151dff3)||
|97|[k-meansクラスタリング](https://qiita.com/FukuharaYohei/items/072272c076a7cb5d7830)|非階層型クラスタリング, K-Means, scikit-learn(KMeans, fit_predict)|
|98|[Ward法によるクラスタリング](https://qiita.com/FukuharaYohei/items/8648da8bbad27c841479)|階層型クラスタリング, Ward法, デンドログラム(樹形図), Scipy(linkage, dendrogram)|
|99|[t-SNEによる可視化](https://qiita.com/FukuharaYohei/items/bef37174397f8c6ef8e7)|t-SNE, scikit-learn(TSNE), matplotlib(get_cmap, subplots, scatter, annotate)|


# [2020年版](https://nlp100.github.io/)との差分
最後におまけです。ニューラルネットワークを強化しているのが[2020年版](https://nlp100.github.io/)ですね。以下が差分一覧です。いつか挑戦したらこの記事に結果のアップデートをしようかと考えています。

- 2015年版の[「第6章: 英語テキストの処理」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch6)が消えた
- 2015年版の[「第7章: データベース」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch7)が消えた
- 2015年版の[「第9章: ベクトル空間法 (I)」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch9)と[「第10章: ベクトル空間法 (II)」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch10)が合体して1つの章になる
- 2020年版に[「第8章: ニューラルネットワーク」](https://nlp100.github.io/#ch08)が新設
- 2020年版に[「第9章: RNN, CNN, アテンション」](https://nlp100.github.io/#ch09)が新設
- 2020年版に[「第10章: エンコーダ・デコーダ」](https://nlp100.github.io/#ch10)が新設