Python(英文のデータベース化003: 文から単語の抽出)

■文から単語を抽出する。
前回、ピリオドやクエスションマーク区切りの文にまで分解できたので、それぞれの文から単語を抽出する。まずは1文に対して、スペース区切りで単語ごとに分けてみる。

スペース区切りでは、次の文を例にすると下のようになる。
With sea levels expected to rise between 20 and 90 centimeters over the next century, those involved in urban development will face significant obstacles.

With
sea
levels
expected
to
rise
between
20
and
90
centimeters
over
the
next
century,
those
involved
in
urban
development
will
face
significant
obstacles.

単語のデータベース化でやりたいこととしては、難しい単語や珍しい使用例の単語を保存しておきたい。上の例で挙げるとすれば、sea levels, urban development, obstaclesあたりかな。少なくとも、with, to, the, andなど前置詞や冠詞、接続詞は逐一保存しても仕方ない。完全な単語レベルで保存するなら機械的にスペース区切りでもいいけど、イディオムや熟語もセットとして保存する場合、ユーザーから選択する工程がほしそう。
過去形や進行形、3人称単数、複数形など、同じ単語で末尾の形が変わるものは機械的に処理したい。

ユーザーから選択する工程はまた考えるとして、単語の末尾処理までコードを組んでみた。

def line_to_words(line):
    wordlist = []
    while True:
        space_location_num = line.find(" ")

        if space_location_num == -1:
            word = line.strip()
        else:
            word = line[:space_location_num].strip()

        if word[-1] == ",":
            word = word[:-1]
        elif word[-2:] == "ed":
            word = word[:-2]
        elif word[-1:] == "s":
            word = word[:-1]
        elif word[-2:] == "es":
            word = word[:-2]
        elif word[-3:] == "ing":
            word = word[:-3]

        word = word.lower()
        wordlist.append(word)
        line = line[space_location_num + 1:]

        if space_location_num == -1:
            break
    return wordlist

ここで、line.find(" ")で、スペース区切りにし、スペースがない場合は(-1)、残っているのは最後の単語と判断し、スペースがあった場合は、文の始めからスペースの位置までを抽出する。末尾がコンマ(,)、過去形(ed)、複数形 (s, es) 、進行形(ing)の場合、それらを削除する。文頭の文字は大文字となるので、小文字に変換(lower()メソッド)。

この状態での実行結果は下の通り。
involvなど必要な部分まで削除されているけど、これは個々の単語を見る必要があると思う。もしPythonの中でオートコレクト機能みたいなものが使えれば、修正する方法があるかもしれないけど。
with
sea
level
expect
to
rise
between
20
and
90
centimeter
over
the
next
century
those
involv
in
urban
development
will
face
significant
obstacle

とりあえず1文に対する単語の抽出ができた体で、単語の種類ごとのカウントも組んでみた。

def plus_count_wordlist(wordcount, wordlist):
    for word in wordlist:
        if word in wordcount[0]:
            print(wordcount[0].index(word))
            wordcount[1][wordcount[0].index(word)] = wordcount[1][wordcount[0].index(word)] + 1
        else:
            wordcount[0].append(word)
            wordcount[1].append(1)
    return wordcount

ここで、wordcountは2次元配列、[(0番目のリスト:単語リスト), (1番目のリスト:単語の出現する数)]。単語リストの中にすでに単語が含まれている場合、indexメソッドでその位置を取得し、出現する数に+1する。もし、含まれてない場合、新しい単語として追加して、出現する数に1を設定する。wordcountは文章に対する配列として、1文ずつに対するwordlistを入力してwordcountの中身を更新する。

ここまでのコードを使って、前回の文章のサンプルを入れてみるとtoやwillなどは複数回カウントされており、正しく動いている模様。

with:1
sea:1
level:1
(略)
to:3
(略)

今回調べながら思ったけど、Pythonでは、要素がリストに含まれるかを「(要素) in (リスト)」で簡単に判断できたのが便利だった。