mei_13のPython講座 ロゴ

【解説】Pythonで自然言語処理の扉を開く:NLTK(Natural Language Toolkit)入門ガイド




Pythonで自然言語処理の扉を開く:NLTK(Natural Language Toolkit)入門ガイド


Yukiのアイコン
【Yuki】 Hirokiくん、こんにちは。今日はとても静かな夜ですね...。外も落ち着いていて、こういう時間はプログラミングの学習にとても集中できる気がします。今日は、以前お話ししていた自然言語処理(NLP)の世界をのぞいてみませんか?Pythonで最も歴史があり、教育的にも素晴らしいと言われているNLTK(Natural Language Toolkit)というライブラリについて解説しようと思います。少し難しい部分もあるかもしれませんが、ゆっくり進めていきましょうね...。


Hirokiのアイコン
【Hiroki】 Yukiさん、こんにちは!夜は静かでいいですよね。僕もこのくらいの時間の方が、新しいことを学ぶ意欲がわいてきます。NLTK、名前は聞いたことがあります。人間の言葉をコンピューターで処理するためのツールですよね?具体的にどんなことができるのか、すごく気になっていました。よろしくお願いします!

NLTKとは何か、その役割を知る


Yukiのアイコン
【Yuki】 はい、よろしくお願いします...。まず、NLTKがどういうものかをお話ししますね。NLTKは、その名の通り「自然言語」を扱うための「道具箱(ツールキット)」です。僕たちが普段使っている日本語や英語のような言葉は、コンピューターにとっては非常に曖昧で、理解するのが難しいものなんです。NLTKは、そういった人間の言葉を解析して、構造化するための便利な機能がたくさん詰まったライブラリなんですよ...。


Hirokiのアイコン
【Hiroki】 なるほど、人間の言葉はコンピューターにとって「曖昧」なんですね。確かに、同じ言葉でも文脈で意味が変わったりしますもんね。


Yukiのアイコン
【Yuki】 ええ、まさにその通りです。NLTKを使うことで、例えば文章を単語ごとに区切ったり、品詞を特定したり、単語の出現頻度を調べたりすることができます。もともとは教育や研究のために作られたものなので、ドキュメントが非常に充実していて、初心者が理論を学びながら実践するのには最適だと思います...。ただ、NLTKは歴史が長い分、英語の処理には非常に強いのですが、日本語を扱うには少し工夫が必要になることもあります。今日はまず、基本となる英語のテキストを使って、その仕組みを学んでいきましょう。

NLTKのインストールと準備


Yukiのアイコン
【Yuki】 それでは、実際に手を動かしてみましょうか...。まずはNLTKを自分の環境にインストールする必要があります。ターミナルやコマンドプロンプトで、以下のコマンドを入力してみてください。

pip install nltk


Hirokiのアイコン
【Hiroki】 インストールできました!これだけで準備完了ですか?


Yukiのアイコン
【Yuki】 あ、すみません...大切なことを言い忘れていました。NLTKは本体をインストールした後に、コーパス学習済みモデルといった追加データをダウンロードする必要があるんです。これがないと、単語の分割などの高度な処理ができないんですよ。Pythonの対話型シェルやエディタで、以下のコードを実行してみてください。

import nltk

# 初めて使うときは、必要なパッケージをダウンロードします
# 全てダウンロードする場合は 'all' ですが、時間がかかるので
# 最初は主要なものを個別に指定するのがいいかもしれません
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('averaged_perceptron_tagger')
nltk.download('wordnet')


Hirokiのアイコン
【Hiroki】 ダウンロードが始まりました。結構たくさんのデータがあるんですね。punktとかstopwordsとか、これらは何に使うものなんですか?


Yukiのアイコン
【Yuki】 いい質問ですね...。それらはこれから説明する各ステップで使われる専用のデータなんです。例えば、punktは文章を句読点で区切るためのルールが入ったデータで、stopwordsは「a」や「the」などの重要度の低い単語のリストです。準備ができたら、まずは一番基本の「トークン化」から見ていきましょう。

テキストを細かく分解する「トークン化」


Yukiのアイコン
【Yuki】 自然言語処理の最初のステップは、長い文章を意味のある最小単位に分けることです。この単位をトークンと呼び、分ける作業をトークン化(Tokenization)と言います...。まずは「文」に分ける方法と、「単語」に分ける方法を見てみましょう。

import nltk
from nltk.tokenize import sent_tokenize, word_tokenize

text = "Hello! This is a simple tutorial. Are you enjoying learning NLTK with Yuki?"

# 文ごとに分割
sentences = sent_tokenize(text)
print("【文の分割】")
print(sentences)

# 単語ごとに分割
words = word_tokenize(text)
print("\n【単語の分割】")
print(words)


Hirokiのアイコン
【Hiroki】 わあ、すごい!記号も含めて綺麗にバラバラになりました。sent_tokenizeが文章ごと、word_tokenizeが単語ごとですね。これなら僕でも理解できます。


Yukiのアイコン
【Yuki】 ふふ、よかったです...。単語に分けることで、コンピューターはやっと「どんな言葉が使われているか」を数える準備ができるんです。でも、ただ分けただけでは、まだ不十分なことが多いんですよ。例えば、「running」と「run」は同じ意味ですが、コンピューターはこれらを別の単語として認識してしまいます。それを解決する方法を次に見ていきましょう。

単語を基本の形に戻す「ステミング」と「レンマ化」


Yukiのアイコン
【Yuki】 単語の形を整える作業には、大きく分けてステミング(Stemming)レンマ化(Lemmatization)の2種類があります。ステミングは、単語の末尾を削って強引に語幹を取り出す方法で、レンマ化は辞書を引いて正しい基本形を導き出す方法です...。まずはコードを見てみてください。

from nltk.stem import PorterStemmer
from nltk.stem import WordNetLemmatizer

stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()

words = ["running", "ran", "runs", "better"]

print("【ステミング結果】")
for w in words:
    print(f"{w} -> {stemmer.stem(w)}")

print("\n【レンマ化結果】")
# 'better' を形容詞(a)として基本形にする
print(f"better -> {lemmatizer.lemmatize('better', pos='a')}")
for w in words[:3]:
    print(f"{w} -> {lemmatizer.lemmatize(w, pos='v')}")


Hirokiのアイコン
【Hiroki】 ステミングはちょっと強引ですね。「running」が「run」になるのはいいけど、他の言葉だともっと変な削られ方をしそうです。レンマ化の方が丁寧な感じがしますね。


Yukiのアイコン
【Yuki】 そうなんです...。ステミングは計算が速いのですが、正確さには欠けることがあります。一方でレンマ化は、文脈(品詞)を教えてあげると「better」を「good」に戻してくれるほど賢いです。ただし、辞書データを使うので少し処理に時間がかかります。どちらを使うかは、作りたいアプリの目的次第ですね...。

不要な単語を取り除く「ストップワード」


Yukiのアイコン
【Yuki】 次に、ストップワードについてお話しします。文章を分析するとき、「is」「the」「a」といった単語は、どの文章にも頻繁に出てきますよね。これらは文の特徴を捉えるときには邪魔になることが多いんです。NLTKには、あらかじめこれらを除外するためのリストが用意されています...。

from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

# 英語のストップワード一覧を取得
stop_words = set(stopwords.words('english'))

text = "This is a sample sentence, showing off the stop words filtration."
words = word_tokenize(text)

# ストップワードに含まれない単語だけを残す
filtered_sentence = [w for w in words if not w.lower() in stop_words]

print("【元の単語】")
print(words)
print("\n【除去後の単語】")
print(filtered_sentence)


Hirokiのアイコン
【Hiroki】 本当だ!「is」や「a」、「the」が消えて、意味を持つキーワードだけが残りましたね。これで文章のメインテーマが分かりやすくなりそうです。


Yukiのアイコン
【Yuki】 ええ、その通りです...。検索エンジンを作ったり、文章の感情分析をしたりするときには、こうやってノイズを減らす作業がとても重要になるんですよ。Hirokiくん、飲み込みが早くて助かります...。

言葉の役割を判定する「品詞タグ付け」


Yukiのアイコン
【Yuki】 次は少し高度な、品詞タグ付け(POS Tagging)に挑戦してみましょう。文章の中の各単語が「名詞」なのか「動詞」なのかを判定する機能です...。これは機械翻訳や、特定の情報を抽出する際に欠かせない技術です。

import nltk
from nltk.tokenize import word_tokenize

text = "Yuki is teaching Python to Hiroki in the quiet night."
words = word_tokenize(text)

# 品詞タグ付けを実行
tagged = nltk.pos_tag(words)

print("【品詞タグ付け結果】")
print(tagged)


Hirokiのアイコン
【Hiroki】 実行結果に NNP とか VBZ とか、見慣れない記号が出てきました。これが品詞を表しているんですか?


Yukiのアイコン
【Yuki】 はい、そうです...。例えば NNP は固有名詞(Proper Noun)、VBZ は動詞の現在形(3人称単数)といった意味を持っています。これを使うと、「文章の中から固有名詞だけを抜き出す」といった処理がプログラムで簡単にできるようになります。NLTKの公式ドキュメントには、これらのタグの意味が一覧で載っているので、必要になったら調べてみるといいかもしれませんね...。

NLTK Tagset List (Alphabetical)

重要なキーワードを見つける「固有表現抽出(NER)」


Yukiのアイコン
【Yuki】 品詞タグ付けを応用すると、さらに面白いことができます。固有表現抽出(Named Entity Recognition, NER)というのですが、文章の中から「人名」「地名」「組織名」などを自動で見つける機能です...。

import nltk

text = "Hiroki studies at a high school in Japan."
words = nltk.word_tokenize(text)
tagged = nltk.pos_tag(words)

# 固有表現を抽出
named_entities = nltk.ne_chunk(tagged)

print("【固有表現抽出】")
print(named_entities)


Hirokiのアイコン
【Hiroki】 結果の中に (GPE Japan/NNP) と出てきました!GPE って何ですか?


Yukiのアイコン
【Yuki】 GPE は「Geopolitical Entity」の略で、国や都市などを指します...。ちゃんと「Japan」が場所であることを認識しているんですね。すごいと思いませんか?コンピューターが文章の「中身」を少しずつ理解し始めている証拠なんです。僕はこういう、小さなツールが誰かの言葉を理解しようとしている姿を見ると、なんだか少し、心が温かくなります...。

単語の頻度を可視化する


Yukiのアイコン
【Yuki】 最後に、文章全体の傾向を掴むのに役立つ「頻度分布」についても触れておきましょう。どの単語が何回使われているか、簡単に数えることができます...。

from nltk import FreqDist
from nltk.tokenize import word_tokenize

text = "Python is great. NLTK is also great. Learning Python with NLTK is fun."
words = word_tokenize(text.lower()) # 全て小文字にして統一

# 頻度を計算
fdist = FreqDist(words)

print("【単語の出現回数】")
for word, count in fdist.most_common(5):
    print(f"{word}: {count}回")


Hirokiのアイコン
【Hiroki】 「is」が3回、「python」が2回...。短い文章だと簡単ですけど、何万文字もある小説とかを分析したら面白そうですね!


Yukiのアイコン
【Yuki】 そうですね...。特定の作家さんの文章のクセを調べたり、流行のキーワードを抽出したり、いろいろな楽しみ方があると思います。もし興味があれば、自分の好きなテキストデータを読み込ませて遊んでみるのもいい勉強になるかもしれません。

さらなるステップへ向けて


Yukiのアイコン
【Yuki】 さて...今日はNLTKの基本的な機能を一通り見てきました。いかがでしたか、Hirokiくん?


Hirokiのアイコン
【Hiroki】 すごく面白かったです!最初は「自然言語処理」って聞くと、すごく難解な数学が必要なイメージでした。でも、NLTKを使えば、単語に分けたり品詞を調べたりといった作業がこんなに簡単にできるなんて驚きです。もっと複雑なこともしてみたくなりました。


Yukiのアイコン
【Yuki】 そう言ってもらえると嬉しいです...。自然言語処理はとても奥が深くて、今日やったことはまだ入り口にすぎません。最近ではディープラーニングを使ったより高度な手法(spaCyやHugging FaceのTransformersなど)が主流になりつつありますが、NLTKで学べる基礎知識は、それらを使う上でも必ず役に立ちます。

より詳しく学びたい場合は、公式のドキュメントや、オンラインで無料で公開されている通称「NLTK Book」を読んでみるのがおすすめです。英語ですが、コード例が豊富でとても勉強になりますよ...。

NLTK Official Website NLTK Book (Natural Language Processing with Python)


Hirokiのアイコン
【Hiroki】 ありがとうございます!まずは今日習ったコードを自分なりに改造して、いろんな文章を読み込ませてみます。また分からないことがあったら教えてください、Yukiさん。


Yukiのアイコン
【Yuki】 はい、喜んで...。Hirokiくんのペースで、ゆっくり進んでいきましょうね。夜も深まってきましたし、今日はこのあたりにしましょうか。お疲れ様でした...。あ、そうだ...もしお腹が空いたら、何か少し食べて休んでくださいね。夜更かしもほどほどに...。


Hirokiのアイコン
【Hiroki】 はい、ありがとうございます!Yukiさんもお疲れ様でした!



< PyTorch
コラム一覧に戻る
音声処理 >

この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。

「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。

「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。

➡ ココナラで制作・相談を依頼する(見積もり無料)


初心者から始められるPythonレッスン

プログラミング未経験者・初心者歓迎!
月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
テキストベースで時間を選ばない
● 高品質なサンプルコード
詳細はこちら
興味がある方はまず質問だけでもどうぞ!



AIアシスタント Yuki