Python3でmatplotlibを使用して単語の頻度をグラフ化する方法

提供:Dev Guides
移動先:案内検索

序章

テキストデータは、ジャーナリズムからソーシャルメディア、電子メールまで、さまざまな形で存在します。 テキストデータを分析して視覚化すると、テキストの解釈方法を変える可能性のある一般的な傾向を明らかにすることができます。

このチュートリアルでは、テキストコーパス内の単語の頻度をグラフ化する方法について説明します。 私たちが作成するプログラムは、プレーンテキストドキュメントを検索し、それぞれの固有の単語をその頻度で整理します。 次に、matplotlibを使用して見つけたデータをグラフ化します。

前提条件

このチュートリアルを使用できるようにするには、次の前提条件があることを確認してください。

最後に、ステップ1 — Python3でデータをプロットする方法のmatplotlibをインポートすることを確認してください。このプロジェクトにはmatplotlibをインストールする必要があるため、matplotlibを使用します。 。

ステップ1—プログラムファイルの設定

コンピューターにmatplotlibがインストールされたので、プロジェクトの作成を開始できます。

選択したテキストエディタを使用して、新しいPythonファイルを作成し、それをword_freq.pyと呼びます。 これがメインファイルになります。

このプログラムでは、 import matplotlibと必要なクラスpyplot)をインポートし、pltを渡します。 ]エイリアス。 これは基本的に、pltをスクリプト全体で使用されるグローバル変数として宣言します。

word_freq.py

import matplotlib.pyplot as plt

次に、Pythonでいくつかのデフォルトパッケージをインポートします。 これらは、コマンドライン入力を設定および取り込むために使用されます。 注意すべき重要なパッケージはargparseです。 これは、コマンドラインから情報を取得し、ユーザーのヘルプテキストを含めるために使用するものです。

次のデフォルトパッケージをPythonにインポートしてみましょう。

word_freq.py

import matplotlib.pyplot as plt
import sys
import operator
import argparse

最後に、標準のmainメソッドを作成して呼び出します。 mainメソッドの中には、ほとんどのコードを記述する場所があります。

word_freq.py

import matplotlib.pyplot as plt
import sys
import operator
import argparse


def main():

if __name__ == "__main__":
  main()

すべてをインポートし、プロジェクトのスケルトンを設定したので、インポートしたパッケージの使用に進むことができます。

ステップ2–引数パーサーの設定

この部分では、コマンドライン引数を作成し、それらを変数に格納してすばやくアクセスできるようにします。

mainメソッドで、パーサー変数を作成し、それをargparseが提供するデフォルトのコンストラクターに割り当てましょう。 次に、ファイルで探している単語に期待される引数を割り当てます。 最後に、単語が含まれているファイルに期待される引数を割り当てます。 これは.txtファイルになります。

word_freq.py

...
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "word",
      help="the word to be searched for in the text file."
  )
  parser.add_argument(
      "filename",
      help="the path to the text file to be searched through"
  )

if __name__ == "__main__":
  main()

今のところ、メソッドの最初の引数は、コマンドラインで期待するもののタイトルです。 2番目の引数help= "..."は、コマンドライン引数がどうあるべきかについての情報をユーザーに提供するために使用されます。

次に、指定された引数をargsと呼ぶ別の変数に保存します。

word_freq.py

...
def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "word",
      help="the word to be searched for in the text file."
  )
  parser.add_argument(
      "filename",
      help="the path to the text file to be searched through"
  )

  args = parser.parse_args()

if __name__ == "__main__":
  main()

適切な方法として、コマンドライン引数にタイプミスがある場合に備えて、常に入力を確認する必要があります。 これは、スクリプトが突然クラッシュするのを防ぐためでもあります。 したがって、tryステートメントを使用してエラーを処理しましょう。

word_freq.py

...
def main():
    ...
    args = parser.parser_args()

    try:
        open(args.filename)

    except FileNotFoundError:
        sys.stderr.write("Error: " + args.filename + " does not exist!")
        sys.exit(1)

if __name__ == "__main__":
  main()

sys.exit(1)を使用して、コードに問題があり、正常に完了できなかったことをユーザーに示しています。

これで、プロジェクトはコマンドライン引数を受け入れることができるようになります。 次のステップは、入力ファイルを解析することです。

ステップ3—ファイルの解析

このステップでは、ファイルを取り込み、各単語を読み取り、それらが出現する頻度をログに記録し、すべてを辞書データ型に保存します。

2つのコマンドライン引数(単語とファイル名)を受け取るword_freq()という名前の関数を作成し、main()でその関数を呼び出しましょう。

word_freq.py

...
def main():
    ...
    word_freq(args.word, args.filename)

def word_freq(word, filename):

if __name__ == "__main__":
  main()

ファイルを解析する最初のステップは、docと呼ぶ辞書データ型を作成することです。 これにより、ファイル内で見つかったすべての単語が保持され、出現した回数が追跡されます。

word_freq.py

...
def word_freq( word, filename ):
    doc = {}

if __name__ == "__main__":
  main()

次のステップは、指定されたファイルを反復処理することです。 これは、ネストされたforループを使用して行われます。

最初のforループは、ファイルを開いて最初の行を取得するように設計されています。 次に、各行にあるものを取得し、単語を配列に格納しながら、単語間の空白文字の文字列に基づいて分割します。

2番目のforループはこの配列を受け取り、それが辞書にあるかどうかをチェックするためにループします。 そうである場合は、それに1つのカウントを追加します。 そうでない場合は、新しいエントリを作成し、1として初期化します。

word_freq.py

...
def word_freq(word, filename):
    doc = {}

    for line in open(filename):
        split = line.split(' ')
        for entry in split:
            if (doc.__contains__(entry)):
                doc[entry] = int(doc.get(entry)) + 1
            else:
                doc[entry] = 1

if __name__ == "__main__":
  main()

現在、プロジェクトは途中です。

要約すると、our main()メソッドは、コマンドライン入力を設定し、それらをword_freq()関数に渡す必要があります。 word_freq()は、コマンドラインから単語とファイル名を取得し、テキストファイルで見つかった一意の単語をそれぞれ保存する必要があります。

次に、このデータを取得して、グラフで使用できるように整理します。

ステップ4—データの保存と並べ替え

グラフを作成する前に、開いたファイルに単語が実際に含まれていることを確認する必要があります。 これは、if条件文で実行できます。

word_freq.py

...
def word_freq(word, filename):
    ...
      else:
          doc[entry] = 1
    if (not word in doc):
        sys.stderr.write("Error: " + word + " does not appear in " + filename)
        sys.exit(1)

if __name__ == "__main__":
  main()

単語がファイルに含まれていることがわかったので、グラフのデータの設定を開始できます。

まず、辞書のデータ型を発生率の高いものから低いものへと並べ替え、後で使用するために変数を初期化することから始めなければなりません。 グラフ上で適切に視覚化されるように、辞書を並べ替える必要があります。

word_freq.py

...
def word_freq(word, filename):
    ...
    if (not word in doc):
        sys.stderr.write("Error: " + word + " does not appear in " + filename)
        sys.exit(1)

    sorted_doc = (sorted(doc.items(), key = operator.itemgetter(1)))[::-1]
    just_the_occur = []
    just_the_rank = []
    word_rank = 0
    word_frequency = 0

if __name__ == "__main__":
  main()

注意すべき2つの変数は、just_the_occurです。これは、単語が出現した回数を保持するデータです。 もう1つの変数はjust_the_rankで、これは単語のランクに関するデータを保持する変数です。

ソートされた辞書ができたので、それをループして単語とそのランクを見つけ、グラフにこのデータを入力します。

word_freq.py

...
def word_freq( word, filename ):
    ...

  sortedDoc = (sorted(doc.items(), key = operator.itemgetter(1)))[::-1]
  just_the_occur = []
  just_the_rank = []
  word_rank = 0
  word_frequency = 0

    entry_num = 1
    for entry in sorted_doc:
        if (entry[0] == word):
            word_rank = entryNum
            word_frequency = entry[1]

        just_the_rank.append(entry_num)
        entry_num += 1
        just_the_occur.append(entry[1])

if __name__ == "__main__":
  main()

ここでは、変数just_the_occurjust_the_rankの両方が同じ長さであることを確認する必要があります。そうでない場合、matplotlibではグラフを作成できません。

また、ループにifステートメントを追加して、単語(すでにそこにあることがわかっている)を見つけ、そのランクと頻度を引き出します。

これで、グラフを作成するために必要なものがすべて揃いました。 次のステップは、最終的にそれを作成することです。

ステップ5—グラフの作成

この時点で、最初に作成したplt変数をプラグインできます。 グラフを作成するには、タイトル、y軸ラベル、x軸ラベル、スケール、およびグラフタイプが必要です。

この例では、データを整理するために10を底とする対数グラフを作成します。 タイトルと軸のラベルは、任意のラベルにすることができますが、グラフを見ている人にとっては、説明が多いほど良いものになります。

word_freq.py

...
def word_freq( word, filename ):
    ...
  just_the_rank.append(entry_num)
  entry_num += 1
  just_the_occur.append(entry[1])

  plt.title("Word Frequencies in " + filename)
  plt.ylabel("Total Number of Occurrences")
  plt.xlabel("Rank of word(\"" + word + "\" is rank " + str(word_rank) + ")")
  plt.loglog(
    just_the_rank,
    just_the_occur,
    basex=10
  )
  plt.scatter(
    [word_rank],
    [word_frequency],
    color="orange",
    marker="*",
    s=100,
    label=word
  )
  plt.show()

if __name__ == "__main__":
  main()

タイトル、plt.ylabel()、およびplt.xlabel()関数は、各軸のラベルです。

plt.loglog()関数は、x軸とy軸にそれぞれjust_the_rankjust_the_occurを取ります。

ログベースを変更して10に設定します。

次に、プロットを分散してポイントを強調表示するように設定します。 サイズ100のオレンジ色の星にしたので、発音します。 最後に、私たちはそれを私たちの言葉でラベル付けしました。

グラフのすべてが完了したら、plt.show()で表示するように指示します。

コードが最終的に完成したので、テスト実行できます。

ステップ6—プログラムの実行

テキストサンプルの場合、読み取るテキストファイルが必要になるため、読者に無料の電子書籍(主にパブリックドメイン)を提供するボランティアプロジェクトであるProjectGutenbergからダウンロードしてみましょう。

チャールズ・ディケンズの小説二都物語のテキストをcities.txtというファイルとしてcurlとともに、Pythonスクリプトを保持する現在のディレクトリに保存しましょう。

curl http://www.gutenberg.org/files/98/98-0.txt --output cities.txt

次に、選択した単語のパラメーター(「魚」を使用します)とテキストファイルの名前を渡してコードを実行しましょう。

python word_freq.py fish cities.txt

すべてが正しく機能した場合は、次のように表示されます。

「魚」という単語のランキングは5309であり、発生を視覚化したものです。

これで、さまざまな単語やさまざまなテキストファイルを試してみることができます。 Python 3 チュートリアルでプレーンテキストファイルを処理する方法を読むと、テキストファイルの操作について詳しく知ることができます。

完成したコードとコードの改善

この時点で、.txtファイル内の特定の単語の単語頻度を決定する完全に機能するプログラムが必要です。

以下は、このプロジェクトの完成したコードです。

word_freq.py

import matplotlib.pyplot as plt
import sys
import operator
import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "word",
        help="the word to be searched for in the text file."
    )
    parser.add_argument(
        "filename",
        help="the path to the text file to be searched through"
    )

    args = parser.parse_args()

    try:
        open(args.filename)
    except FileNotFoundError:

        # Custom error print
        sys.stderr.write("Error: " + args.filename + " does not exist!")
        sys.exit(1)

    word_freq(args.word, args.filename)


def word_freq(word, filename):
    doc = {}

    for line in open(filename):

        # Assume each word is separated by a space
        split = line.split(' ')
        for entry in split:
            if (doc.__contains__(entry)):
                doc[entry] = int(doc.get(entry)) + 1
            else:
                doc[entry] = 1

    if (word not in doc):
        sys.stderr.write("Error: " + word + " does not appear in " + filename)
        sys.exit(1)

    sorted_doc = (sorted(doc.items(), key=operator.itemgetter(1)))[::-1]
    just_the_occur = []
    just_the_rank = []
    word_rank = 0
    word_frequency = 0

    entry_num = 1
    for entry in sorted_doc:

        if (entry[0] == word):
            word_rank = entry_num
            word_frequency = entry[1]

        just_the_rank.append(entry_num)
        entry_num += 1
        just_the_occur.append(entry[1])

    plt.title("Word Frequencies in " + filename)
    plt.ylabel("Total Number of Occurrences")
    plt.xlabel("Rank of word(\"" + word + "\" is rank " + str(word_rank) + ")")
    plt.loglog(just_the_rank, just_the_occur, basex=10)
    plt.scatter(
        [word_rank],
        [word_frequency],
        color="orange",
        marker="*",
        s=100,
        label=word
    )
    plt.show()

if __name__ == "__main__":
    main()

すべてが完了したので、このコードに対して実行できるいくつかの潜在的な改善と変更があります。

2つの単語の頻度を比較する場合は、コマンドライン引数に単語の位置を追加します。 これを実現するには、単語用に別のチェッカーを追加し、単語用にさらに変数を追加する必要があります。

また、各単語の長さを比較するようにプログラムを変更することもできます。 これを行うには、単語を長さで比較し、それぞれの一意の長さを辞書に保存します。

結論

テキストファイルを読み、データを整理して、テキスト内の他の単語と比較した特定の単語の頻度を確認するプログラムを作成しました。

データの視覚化に興味がある場合は、JavaScriptを使用して棒グラフを作成する方法とD3ライブラリチュートリアルもご覧ください。