課題レポート5: 基本的な自然言語処理を実装してみよう(その2)。

本課題は課題レポート4の続きである。まだレポート4を終えていない場合にはそちらから取り組むこと。

課題概要

  • 文章を数値ベクトルとして表現してみよう。

  • 文字列・リスト・辞書の代表的な処理に慣れよう。

  • (数値ベクトル同士の類似度により文章の類似度を計測してみよう。)


取り組み方

  • 友人らと話し合って取り組んで構わないが、考察は自分自身の言葉で述べること。試して分かったこと、自身で解決できなかった部分等についてどう取り組んだか、といった過程がわかるように示すこと。考えを図表や文章を駆使して表現して報告する練習です。

    • ある事象について妥当と思われる表現が思い浮かばないのなら、そのことを先輩らに尋ねてみよう。


レベル1「ドキュメント、テストを書け」

  • 課題

    • 課題レポート4で作成した2つの関数 count_unique_words, make_word_list についてドキュメント(pydoc)、テストを書け。テストは課題レポート4の実行例で示したものとするが、戻り値の形式を変更している場合にはその説明をした上で変更バージョンでのテストを書け。

  • 補足

    • レポートには、(1) テスト結果を掲載し、(2) 生成したHTMLドキュメントをアップロードせよ。


レベル2「単語文書行列を作成せよ」

  • 背景

    • 課題レポート4により、与えれた複数文書ごとに単語の出現回数を数えることができるようになっているはずだ。この結果を用いて単語文書行列を作成したい。

  • 課題

    • 単語文書行列を作成する関数を実装せよ。関数名を make_word_doc_matrix とする。

  • レポート

    • 動作を確認できる実行結果を掲載すること。

    • どのような過程を経てコードに翻訳したのか説明 すること。図等を用いても良い。

    • ソースコードは report5.py という名前で保存し、アップロードすること

  • 補足

    • 集合の取り扱い。

      • レポート4で作成した関数make_word_listの1つ目の戻り値(下記例における word_list)は集合set型オブジェクトである。集合は順序を持たないが、単語文書行列を作成するためには例えば「1列目を単語penの出現回数、2列めを単語appleの出現回数、、、」のように列の順序を固定する必要がある。このため今回作成する関数内で順序を付けてやろう。

      • 並べ替え方は必ず下記実行結果通りとなること。下記は辞書順で並べ替えている。辞書順で並べ替えるには sorted 関数を使えば良い。

  • 実行例

>>> # 2文書を用意
>>> docs = ['I have a pen', 'I have an apple']

>>> # 単語一覧を作成、ついでにレベル1の結果も返す
>>> word_list, sentence_words = make_word_list(docs)
>>> print(type(word_list))
<class 'set'>
>>> print(word_list)
{'a', 'apple', 'i', 'have', 'pen', 'an'}
>>> print(type(sentence_words))
<class 'list'>
>>> print(sentence_words)
[{'i': 1, 'have': 1, 'a': 1, 'pen': 1}, {'i': 1, 'have': 1, 'an': 1, 'apple': 1}]

# 上記までは課題レポート4。

>>> # 単語文書行列を作成
>>> column_names, matrix = make_word_doc_matrix(word_list, sentence_words)
>>> print(column_names)
['a', 'an', 'apple', 'have', 'i', 'pen']
>>> print(matrix)
[[1, 0, 0, 1, 1, 1], [0, 1, 1, 1, 1, 0]]

Note

あらゆるプログラムは一度に全てを実装する必要はない。自分なりに分解し、実装して動作確認しやすい小さな部品を考えてみよう。どのような部品が必要かを洗い出し、それをどのように組み合わせるかを考えてみよう。これが整理の本質だ。


オプション

レベル2の時点ではまだ数値ベクトル同士の類似度を算出できていない。類似度とは「似ている度合い」のことだが、これをユークリッド距離により求めてみよう。ユークリッド距離が小さいほど似ている(もしくはその反対)という設定により求めたい。具体的には、ベクトル\(x\), \(y\)のユークリッド距離\(d(x,y)\)を用い、以下の式で類似度を算出してみよう。

\[ similarity(x, y) = \frac{1}{d(x,y) + 1} \]

Tip

分母に1を足しているのは、距離dの最小値が0となるとき、分母が0になってしまうことを避けるための工夫である。