AIって結局何なのかよく分からないので、とりあえず100日間勉強してみた Day47
経緯についてはこちらをご参照ください。
■本日の進捗
- LDAを理解
■はじめに
引き続き「Pythonではじめる機械学習(オライリー・ジャパン)」で学んでいきます。
今回はテキストデータに対する(主に)教師なし学習として用いられるトピックモデリング手法からLDAをIMDbデータセットに適用してみます。
■LDA
LDA(latent dirichlet allocation)とは、コーパスの各ドキュメントに対して1つ以上のトピックを含むと仮定してこれを割り当てるトピックモデリング(topic modeling)手法のひとつで、教師なし学習における成分分析手法にあたります。
各ドキュメントはいくつかのトピック(ここでいうトピックは「話題」というよりも「特徴量」と考えた方が理解しやすいかもしれません。つまり人間に解釈可能なトピックもあればそうではない可能性もあります。)の「混合物」であり、そのトピックは(同じトピックであれば)複数の単語から成り立っていると考えます。トピックの混合分布や単語の出現確率からドキュメントを分析し潜在変数を教えてくれます。
ストップワードなどにも表現される頻出単語のトピックへの影響を減らすためにも一般的な単語は予め除いておくことが推奨されます。
トピックの生成に乱数性があること、単語の順序や文脈を考慮されない可能性があること、スケーラビリティが得られ難いことなどにも注意が必要です。
これまでお世話になってきたIMDbデータセットをLDAで分析してみます。
import numpy as np from sklearn.datasets import load_files from sklearn.feature_extraction.text import CountVectorizer from sklearn.decomposition import LatentDirichletAllocation reviews_train = load_files("C:/Users/****/Documents/Python/aclImdb/train") text_train, y_train = reviews_train.data, reviews_train.target vectorizer = CountVectorizer(max_features=10000, max_df=0.15) X = vectorizer.fit_transform(text_train) lda = LatentDirichletAllocation(n_components=100, learning_method="batch", max_iter=25, random_state=8, n_jobs=-1) document_topics = lda.fit_transform(X) sorting = np.argsort(lda.components_, axis=1)[:, ::-1] feature_names = np.array(vectorizer.get_feature_names_out()) for topic_idx in range(10): top_words = feature_names[sorting[topic_idx, :10]] print(f"topic {topic_idx + 1}: {', '.join(top_words)}")
topic 1: mystery, murder, detective, nick, powell, william, case, london, solve, mysteries
topic 2: brando, professor, accents, accent, southern, self, new, league, sisters, jerry
topic 3: play, shakespeare, true, every, day, heart, work, branagh, performance, brilliant
topic 4: bill, mary, ted, dog, green, lou, house, robinson, heston, douglas
topic 5: simon, oliver, matthau, reed, walter, neil, jack, oscar, gadget, felix
topic 6: peter, jeff, taylor, paul, falk, town, com, last, hunter, hunt
topic 7: king, animation, disney, bugs, lion, new, voice, voices, bug, timon
topic 8: script, worst, actors, director, awful, poor, nothing, actor, terrible, minutes
topic 9: show, episode, season, shows, episodes, tv, match, television, keaton, seasons
topic 10: sweet, romantic, baseball, cry, sports, charming, sad, true, red, jimmy
トピックを100個抽出し、最初(もちろん順番に意味はない)の10トピックを表示させてみました。前述の通りこの「トピック」はあくまで機械学習モデルにとって類似性が確認できるだけで、僕ら人間にとって理解できる範疇にない可能性もありますが、topic 1は明らかに殺人事件が関連するミステリー作品だったり、topic 7は動物や虫が出てくるアニメーションで、topic 9はテレビシリーズなのでしょう。
この直観が実際に正しいかどうかを確認してみます。個人的にはtopic 7が本当にディズニーアニメーション(使っていい単語?お金請求されたりしますか?)と関連があるのかが気になるので、topic 7が含まれているドキュメントをいくつか見てみます。
import numpy as np from sklearn.datasets import load_files from sklearn.feature_extraction.text import CountVectorizer from sklearn.decomposition import LatentDirichletAllocation reviews_train = load_files("C:/Users/****/Documents/Python/aclImdb/train") text_train, y_train = reviews_train.data, reviews_train.target reviews_test = load_files("C:/Users/hamni/Documents/Python/aclImdb/test") text_test, y_test = reviews_test.data, reviews_test.target vectorizer = CountVectorizer(max_features=10000, max_df=0.15) X = vectorizer.fit_transform(text_train) lda = LatentDirichletAllocation(n_components=100, learning_method="batch", max_iter=25, random_state=8, n_jobs=-1) document_topics = lda.fit_transform(X) sorting = np.argsort(lda.components_, axis=1)[:, ::-1] feature_names = np.array(vectorizer.get_feature_names_out()) animation = np.argsort(document_topics[:, 6])[::-1] for i in animation[:10]: print(b".".join(text_train[i].split(b".")[:2]) + b".\n")
b'Bugs Bunny accidentally ends up at the South Pole while trying to vacation in Florida. Where he meets a little penquin, which he tries to save from an Eskimo.\n'
b'[CONTAINS SPOILERS!!!]<br /><br /> Timon and Pumbaa are watching The Lion King. Timon decides to go back BEFORE the beginning, to when the story really began.\n'
b'This, along with "Hare Tonic," ranks as one of the best Bugs cartoons, indeed one of the best Bugs, ever. There are some comments about how Bugs in these cartoons is "basic," meaning, I guess, that he is as yet not fully developed.\n'
b'The Lion King 1 1/2 is a very cute story to go along with The Lion King. It basically follows the original story of The Lion King but with a couple of twists.\n'
b"I think Lion King 1 1/2 is one of the best sequels ever as if not the best out of the three Lion King movies! In the movie Timon and Pumbaa tell us where they came from and having trouble fitting in with others such as Timon having trouble digging tunnels with other Meercats! Timon and Pumbaa journey off into finding their dream place and find it and soon find it and also Simba who they raise but soon they must choose between their dream place or helping Simba face his evil Uncle Scar and proclaim his right as the Lion King of Pride Rock! Filled with wonderful new characters like Timon's Ma(Julie Kavner) and Uncle Max (Jerry Stiller). I think my favorite character was Uncle Max because he was very funney and was voiced by a funney comedian Jerry Stiller the father of Ben Stiller.\n"
b"A great Bugs Bunny cartoon from the earlier years has Bugs as a performer in an window display at a local department store. After he's done for the day the manager comes in to tell him that he'll be transferring soon.\n"
b'This movie is the next segment in the pokemon movies which supplies everything on hopes and dreams of a pokemon warrior named Ash Ketchim and his friends. they go out and they look battle and run into new pokemon and take on new adventures with Pikachu and other pokemon favorites.\n'
b'The Lion King series is easily the crowning achievement in Disney animation. The original Lion King is the greatest masterpiece in cel animation.\n'
b"If the Lion King was a Disney version of Hamlet, then the Lion King 3: Hakuna Matata is a Disney version of Guildenstern and Rosencrantz are Dead. Just like Tom Stoppard's beguiling film, we get to view the action from the point of view of two of the minor characters from the original: Timon, the meerkat with a penchant for breaking into song at the drop of a hat, and Pumbaa, the warthog with flatulence issues.\n"
b'There was a Bugs Bunny cartoon titled "Baby Buggy Bunny" that was EXACTLY this plot. Baby-faced Finster robbed a bank and the money in the carriage rolled away and fell into Bug\'s rabbit hole.\n'
実際にtopic 7(インデックスは6)は、「ライオンキング1 1/2」(ディズニーの知見がなくて申し訳ないのですが、調べたらこういう作品があるみたいです)や、「ライオンキング3」、「バッグスバニー」、「ポケモン」のアニメーション作品に関連するトピックであったみたいです。”bug” が虫ではなかったことを除いては、当初の直観通りにLDAも分析していたということになります。「バグズライフ」かな、とか思ってました…。
■おわりに
LDAでトピックを生成した後は、このトピックをこれまでも構築してきた教師あり学習に組み込んでもいいですが、もう既に実際に誰もが触れているサービスに組み込まれているモデルでもあるのです。
例えば先ほど挙げたようなレビューを書いているユーザーにはディズニーやポケモン、あるいはその他のアニメーション映画をレコメンドしてみるのはどうでしょう。
論文やコミュニティの投稿をタグ付けのように分類したり、その内容を要約することも出来そうです。
SNSの投稿から(いわゆる普段僕ら人間が使う意味での)トピックを抽出して、「映画のトレンド」、「音楽のトレンド」、「社会問題のトレンド」と提案してみるのもいいかもしれません。特に「タイヤ」や「空力」といった単語から「スポーツのトレンド」ではなく「モータースポーツのトレンド」というところまで分析できるでしょう。
製品レビューなどから顧客が良く話題にあげるトピックを分析し、どんなことが購買に影響するかを抽出できればビジネスにも利用できそうです。
機械学習モデルの勉強として簡単なクラス分類や回帰タスクを予測してきましたが、ようやく一般人が想像するいわゆる “AI” っぽくなってきたのではないでしょうか。
■参考文献
- Andreas C. Muller, Sarah Guido. Pythonではじめる機械学習. 中田 秀基 訳. オライリー・ジャパン. 2017. 392p.
- ChatGPT. 4o mini. OpenAI. 2024. https://chatgpt.com/
- API Reference. scikit-learn.org. https://scikit-learn.org/stable/api/index.html
- Maas, Andrew L. and Daly, Raymond E. and Pham, Peter T. and Huang, Dan and Ng, Andrew Y. and Potts, Christopher, Learning Word Vectors for Sentiment Analysis, Proceedings of the 49th Annual Meeting of the Association for Computational Linguistics: Human Language Technologies, June, 2011, Portland, Oregon, USA, Association for Computational Linguistics, 142–150, http://www.aclweb.org/anthology/P11-1015
- Potts, Christopher. 2011. On the negativity of negation. In Nan Li and David Lutz, eds., Proceedings of Semantics and Linguistic Theory 20, 636-659.