序章

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

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

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

という名前の関数を作成しましょう word_freq() これは2つのコマンドライン引数(単語とファイル名)を取り、その関数をで呼び出します 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 loopは、ファイルを開いて最初の行を取得するように設計されています。 次に、各行にあるものを取得し、単語を配列に格納しながら、単語間の空白文字の文字列に基づいて分割します。

二番目 for loopはこの配列を受け取り、それが辞書にあるかどうかをチェックしてループします。 そうである場合は、それに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 これは、単語が出現した回数を保持するデータです。 他の変数は 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() 関数は各軸のラベルです。

The plt.loglog() 関数がかかります just_the_rankjust_the_occur x軸とy軸にそれぞれ。

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

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

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

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

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

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

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

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

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

  1. 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ライブラリチュートリアルもご覧ください。