LoginSignup
1
1

More than 5 years have passed since last update.

Lesson11: Text Learning まとめ Intro to Machine learning@Udacity

Last updated at Posted at 2018-12-29

Lessonに入る前に

UdacityのIntro to Machine learningを受けはじめてしばらく経つが、学習しては忘れている気がするので、Lesson11からだけど、備忘録として記録に残していこうと思う。

少しでも、皆さんの参考になれば。

PCはWindows 10 64bit 最近SSDに換装した10年選手のノートパソコンです。
Anaconda5.2.0(Python3)入れました。

ただ、UdacityのIntro to Machine learningはPython2とのこと。
ここここを参照させてもらって、Python3とPython2を共存させました。

Lesson11:Text Learningのまとめ

このレッスンの概要

課題:文章へ機械学習(Naive BayesやSVM)を適用する場合、入力の次元を統一できないため、学習が大変。
→入力したい各文章を集めて、次元の統一をしよう!が今回のレッスン。Lesson2:Naive BayesやLesson3:SVMで使っていたデータをどのように作っていたのか学ぶ。

前処理の流れは
Tokenize(文章を単語に分割)→Stemming(単語をrootに丸める)→TfIdf処理(情報量で重みづけ)

処理の手順

STEP1, Tokenize(NLTKのword_tokenize参照)

入力:文章
出力:各単語

文章をそれぞれの単語に分けること。ここではNLTK(Natural Language Took Kit)を使用。


from nltk.tokenize import word_tokenize
s = '''Good muffins cost $3.88\nin New York.  Please buy me two of them.\n\nThanks.'''
word_tokenize(s)
['Good', 'muffins', 'cost', '$', '3.88', 'in', 'New', 'York', '.',
'Please', 'buy', 'me', 'two', 'of', 'them', '.', 'Thanks', '.']

STEP2, Stemming(レッスンはNLTKのSnowballstemmer使用)

入力:単語
出力:単語の根(root)
単語の根(root)例えばrespond, response, responsivelyはすべてresponの根(root)に変換される。 

STEP3, TfIdf処理 = TfidfVectorizer

入力:単語(なるべく根を入力する。でないと同じ根の単語を別物としてカウントするので、出てくるMatrixが膨大になる=後の機械学習で処理に時間かかる)
出力:単語の頻度の重みづけ

  • Tf:Term Frequency:ほぼBag of Wordsと同じだが、内部表現が違う。Bag of Wordsは出現回数だが、Term Frequencyは出現回数ではなく重みづけ(weight)で表現されている。

  • Idf Inverse Document Frequency:各単語の重みづけ。出現頻度が低い単語が情報量の多い単語として重みづけするため、Inverseとなっていることには納得した。
    言葉覚えやすくなるかも。

上記TfとIdfを整合性を取った形で、出力Matrixを作ってくれるのかなたぶん。

例)


from sklearn.feature_extraction.text import TfidfVectorizer
corpus = [
...     'This is the first document.',
...     'This document is the second document.',
...     'And this is the third one.',
...     'Is this the first document?',
... ]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
print(X.shape)
(4, 9)
print(X)
(0, 8)        0.38408524091481483
(0, 3)        0.38408524091481483
(0, 6)        0.38408524091481483
(0, 2)        0.5802858236844359
(0, 1)        0.46979138557992045
(1, 8)        0.281088674033753
(1, 3)        0.281088674033753
(1, 6)        0.281088674033753
(1, 1)        0.6876235979836938
(1, 5)        0.5386476208856763
(2, 8)        0.267103787642168
(2, 3)        0.267103787642168
(2, 6)        0.267103787642168
(2, 0)        0.511848512707169
(2, 7)        0.511848512707169
(2, 4)        0.511848512707169
(3, 8)        0.38408524091481483
(3, 3)        0.38408524091481483
(3, 6)        0.38408524091481483
(3, 2)        0.5802858236844359
(3, 1)        0.46979138557992045

出展にprint(X)加えた。

参考1:Bag of Words = CountVectorizer

入力:複数の文章
出力:複数文章内に出てくる単語が、それぞれ何回出てきたかをカウント(Matrix形式で)
→レッスンではBag of Wordsが先に解説される。おそらくTfIdfをわかりやすくするためだと思われる。

参考2:Stop Words

例えばand, the, I, you, have
頻繁に出てくるが、情報量はかなり低いため除外する。Vectorizer(TfidfVectorizer)の引数で除外するかどうか指定できる。
下記英語のStopWordsを除外する場合。


from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(word_data)

感想

時間をかけてレッスンをやっていると、最初のビデオで見たことを忘れてしまい、最後は何やってるんだかわかんなくなってしまった。一つ一つ身になるようにするには、時間がかかるけど、こうやってまとめるのが一番の近道のような気がする。

個人的には上記のような処理は人間が言葉を使うときのプロセスとは大分違うかなと感じた。
例えば、Stemmerで微妙なニュアンスをまとめてしまうのは違和感がある。
そのような必要が本当にないのなら、Stemmerでまとめた単語の根だけで人間が会話してもいい気がするが。これからの言語の進化はその方向に行くのだろうか。もしくは、計算機の性能が上がって、Stemしなくてもよくなれば、コンピューターがもっと自然な感じで会話できるようになるのかな。
機械に人間が近づくのか、人間に機械が近づくのか。。。

英語、フランス語、スペイン語とかのラテン語系は根でまとめられるかもだけど、
ヒンディー語、タイ語とかのサンスクリット語系はまた全然違うんだろうね。
日本語は根がありそうだ。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1