100日後にエンジニアになるキミ - 68日目 - プログラミング - TF-IDFについて

昨日までのはこちら

[100日後にエンジニアになるキミ - 66日目 - プログラミング - 自然言語処理について](https://qiita.com/otupy/items/5828ac7450c5ba8d6931)

[100日後にエンジニアになるキミ - 63日目 - プログラミング - 確率について1](https://qiita.com/otupy/items/0196897ae4d2134794fa)

[100日後にエンジニアになるキミ - 59日目 - プログラミング - アルゴリズムについて](https://qiita.com/otupy/items/f1a5e81633b868f3b5ed)

[100日後にエンジニアになるキミ - 53日目 - Git - Gitについて](https://qiita.com/otupy/items/0abaad82a7f3fea73f1f)

[100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて](https://qiita.com/otupy/items/d1765f1541a104ed6133)

[100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて](https://qiita.com/otupy/items/7af17635d576677606dc)

[100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1](https://qiita.com/otupy/items/6d1e5453f530e07b7aec)

[100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1](https://qiita.com/otupy/items/2f71d5f9c754b29d9555)

[100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1](https://qiita.com/otupy/items/61a97863f6df14171994)

[100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1](https://qiita.com/otupy/items/cd2315dcb38671cfded0)

今回はTF-IDFについてです。

## TF-IDFとは

`TF-IDF`は索引語頻度逆文書頻度のことで
`TF(Term Frequency)`単語の出現頻度と
`IDF(Inverse Document Frequency)`単語の希少度とを
掛け合わせたものになります。

$$
{TF: 文書における指定単語の出現頻度:  \frac{文書内の指定単語の出現回数}{文書内の全単語の出現回数}\\ 
}
$$

$$
{IDF: 逆文書頻度(指定単語の希少度): log\frac{総文書数}{指定単語を含む文書数}}
$$

$$
{TFIDF(索引語頻度逆文書頻度) = TF * IDF}
$$

参考：
https://ja.wikipedia.org/wiki/Tf-idf

### ワードカウント

まずは文章の単語数を数えてみましょう。

カウント用の文章を作っておきます。

```python
result_list = []
result_list.append('吾輩 は 猫 で ある')
result_list.append('吾輩 は 猫 で ある')
result_list.append('吾輩 も です')
result_list.append('どうぞ どうぞ 猫 です')
```

以下のようなコードで単語の出現頻度を数える事ができます。

```python
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings('ignore')

count_vectorizer = CountVectorizer(token_pattern='(?u)\\b\\w+\\b')

count_vectorizer.fit(result_list)
X = count_vectorizer.transform(result_list)

print(len(count_vectorizer.vocabulary_))
print(count_vectorizer.vocabulary_)

pd.DataFrame(X.toarray(), columns=count_vectorizer.get_feature_names())
```
8
{'吾輩': 6, 'は': 4, '猫': 7, 'で': 1, 'ある': 0, 'も': 5, 'です': 2, 'どうぞ': 3}

|  | ある | で | です | どうぞ | は | も | 吾輩 | 猫 |
|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 |
| 2 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 |
| 3 | 0 | 0 | 1 | 2 | 0 | 0 | 0 | 1 |

各文章で単語が何回登場するかを数える事ができます。

次はTF-IDFを求めてみましょう。

以下のようなコードで求める事ができます。

```python
from sklearn.feature_extraction.text import TfidfVectorizer
import warnings
import numpy as np
import pandas as pd
warnings.filterwarnings('ignore')

tfidf_vectorizer = TfidfVectorizer(token_pattern='(?u)\\b\\w+\\b')
tfidf_vectorizer.fit(result_list)

print(len(tfidf_vectorizer.vocabulary_))
print(tfidf_vectorizer.vocabulary_)

X = tfidf_vectorizer.fit_transform(result_list)
pd.DataFrame(X.toarray(), columns=tfidf_vectorizer.get_feature_names())
```
8
{'吾輩': 6, 'は': 4, '猫': 7, 'で': 1, 'ある': 0, 'も': 5, 'です': 2, 'どうぞ': 3}

|| ある | で | です | どうぞ | は | も | 吾輩 | 猫 |
|--:|--:|--:|--:|--:|--:|--:|--:|--:|
| 0 | 0.481635 | 0.481635 | 0 | 0 | 0.481635 | 0 | 0.389925 | 0.389925 |
| 1 | 0.481635 | 0.481635 | 0 | 0 | 0.481635 | 0 | 0.389925 | 0.389925 |
| 2 | 0 | 0 | 0.553492 | 0 | 0 | 0.702035 | 0.4481 | 0 |
| 3 | 0 | 0 | 0.35157 | 0.891844 | 0 | 0 | 0 | 0.284626 |

TF-IDFは0から1の間の数値がでます。
たくさんの文章に出てくるものの値は小さくなります。
1つの文章でたくさん出てくるものは重要なワードだと考えられます。

1に近いほど希少性の高いワードであると考えることもできます。


## まとめ

文章をベクトル化する手法と、単語の希少性を算出する手法があります。
文章を数値化する事ができるので、いろいろな計算を行う事ができるようになります。

こう言った手法は機械学習などでは良く用いられるので
名前とかを抑えておきましょう。

君がエンジニアになるまであと32日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython