Gensim公式チュートリアル翻訳(2)-コーパスとベクトル空間(コーパスとベクトル空間)

翻訳のソース:https//blog.csdn.net/questionfish/article/details/46739207

オリジナルの公式チュートリアル:http//radimrehurek.com/gensim/tut2.html

個人学習データのバックアップ、侵入、削除のみ

====================正==========文====================

ログに記録する場合は、以下を設定することを忘れないでください。

 

 
  1. >>> import logging

  2. >>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

文字列からベクトルへ

今回は、文字列startで表されるドキュメントを作成しましょう

 
  1. >>> from gensim import corpora, models, similarities

  2. >>>

  3. >>> documents = ["Human machine interface for lab abc computer applications",

  4. >>> "A survey of user opinion of computer system response time",

  5. >>> "The EPS user interface management system",

  6. >>> "System and human system engineering testing of EPS",

  7. >>> "Relation of user perceived response time to error measurement",

  8. >>> "The generation of random binary unordered trees",

  9. >>> "The intersection graph of paths in trees",

  10. >>> "Graph minors IV Widths of trees and well quasi ordering",

  11. >>> "Graph minors A survey"]

これは9つのドキュメントのミニチュアコーパスであり、各ドキュメントは1つの文のみで構成されています。

(トークン化またはトークン化)

まず、これらのドキュメントをトークン化(トークン化、トークン化など)して、一般的な単語(stop vocabularyを使用)とコーパス全体に1回だけ出現する単語をブロックしましょう。

 
  1. >>> # 去除停用词并分词

  2. >>> # 译者注:这里只是例子,实际上还有其他停用词

  3. >>> # 处理中文时,请借助 Py结巴分词 https://github.com/fxsjy/jieba

  4. >>> stoplist = set('for a of the and to in'.split())

  5. >>> texts = [[word for word in document.lower().split() if word not in stoplist]

  6. >>> for document in documents]

  7. >>>

  8. >>> # 去除仅出现一次的单词

  9. >>> from collections import defaultdict

  10. >>> frequency = defaultdict(int)

  11. >>> for text in texts:

  12. >>> for token in text:

  13. >>> frequency[token] += 1

  14. >>>

  15. >>> texts = [[token for token in text if frequency[token] > 1]

  16. >>> for text in texts]

  17. >>>

  18. >>> from pprint import pprint # pretty-printer

  19. >>> pprint(texts)

  20. [['human', 'interface', 'computer'],

  21. ['survey', 'user', 'computer', 'system', 'response', 'time'],

  22. ['eps', 'user', 'interface', 'system'],

  23. ['system', 'human', 'system', 'eps'],

  24. ['user', 'response', 'time'],

  25. ['trees'],

  26. ['graph', 'trees'],

  27. ['graph', 'minors', 'trees'],

  28. ['graph', 'minors', 'survey']]

ここでは、スペースを使用して文字列を分割し、トークン化して小文字に変換します。ドキュメントの処理方法は異なる可能性があります。実際、私はこの特別な(単純で非効率的な)設定を使用して、Deerwester etalによる元のLSA記事の実験を模倣しています。[1]

(要約属性辞書)

書類の処理方法は、申請状況や言語によって異なりますので、処理方法に制限を設けないことにしました。代わりに、ドキュメントは、リテラル形式だけでなく、そこから抽出された属性で表す必要があります。これらの属性を抽出する方法は、ユーザー次第です(単語、ドキュメントの長さなど)。次に、一般的な汎用メソッド(bag-of-wordsと呼ばれる)について説明しますが、アプリケーション領域ごとに異なる属性を使用する必要があることに注意してください。そうでない場合は、ガベージイン、ガベージアウト
ドキュメントをベクトルに変換するために、bag ofwordsと呼ばれるドキュメント表現方法を使用しますこの表現方法では、各ドキュメントはベクトルで表され、ベクトルの各要素は次のような質問と回答の権利を表します。

「「システム」という言葉は何回現れますか?一度だけです。」

これらの質問の代わりに、これらの質問の(整数)数を使用することをお勧めします。質問と数字の間のマッピング、私たちはそれを辞書(辞書)と呼びます。

 
  1. >>> dictionary = corpora.Dictionary(texts)

  2. >>> dictionary.save('/tmp/deerwester.dict') # 把字典保存起来,方便以后使用

  3. >>> print(dictionary)

  4. Dictionary(12 unique tokens)

上記の手順では、gensim.corpora.dictionary.Dictionaryクラスを使用して、コーパスに表示される各単語に一意の整数を割り当てます。この操作は、単語数およびその他の関連する統計を収集します。最後に、コーパスに12の異なる単語があることがわかります。これは、各ドキュメントが12の数字(つまり、12次元のベクトル)で表されることを意味します。単語と数字のマッピング関係を表示する場合:

 

 
  1. >>> print(dictionary.token2id)

  2. {'minors': 11, 'graph': 10, 'system': 5, 'trees': 9, 'eps': 8, 'computer': 0,

  3. 'survey': 4, 'user': 7, 'human': 1, 'time': 6, 'interface': 2, 'response': 3}

 

(スパースドキュメントベクトルを生成します)

トークン化されたドキュメントを実際にベクターに変換するには、次のものが必要です。

 
  1. >>> new_doc = "Human computer interaction"

  2. >>> new_vec = dictionary.doc2bow(new_doc.lower().split())

  3. >>> print(new_vec) # "interaction"没有在dictionary中出现,因此忽略

  4. [(0, 1), (1, 1)]

関数doc2bow()は、異なる単語の出現回数をカウントし、その単語をその数に変換して、結果をスパースベクトルの形式で返します。したがって、スパースベクトル[(0、1)、(1、1)]は、「コンピューター」(id 0)と「人間」(id 1)がそれぞれ「ヒューマンコンピューターインタラクション」に1回出現し、他の10個の辞書に出現することを意味します。その言葉は一度も現れたことがありません(暗黙的)。

 
  1. >>> corpus = [dictionary.doc2bow(text) for text in texts]

  2. >>> corpora.MmCorpus.serialize('/tmp/deerwester.mm', corpus) # 存入硬盘,以备后需

  3. >>> print(corpus)

  4. [(0, 1), (1, 1), (2, 1)]

  5. [(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]

  6. [(2, 1), (5, 1), (7, 1), (8, 1)]

  7. [(1, 1), (5, 2), (8, 1)]

  8. [(3, 1), (6, 1), (7, 1)]

  9. [(9, 1)]

  10. [(9, 1), (10, 1)]

  11. [(9, 1), (10, 1), (11, 1)]

  12. [(4, 1), (10, 1), (11, 1)]

(上記の操作を通じて、今回取得したコーパスを確認しました。)これまでのところ、上記の出力が次のことを示していることは明らかです。最初の6つのドキュメントでは、番号10の属性値は0です。これは、問題を意味します。文書」「グラフ」が数回登場しましたが、答えは「0」ですが、他の文書の答えは1です。実際、「クイックスタート」からサンプルコーパスを入手しました

コーパスフロー-一度に1つのドキュメント

上記のコーパス全体がPythonリストとしてメモリに保存されていることに注意してください。この簡単な例では、それは確かに重要ではありません。しかし、何百万ものドキュメントのコーパスがあると仮定すると、コーパス全体をメモリに保存することは不可能であることを明確にする必要があります。これらのドキュメントがハードディスク上のファイルに保存されており、1行に1つのドキュメントがあるとします。Gemsimでは、一度に1つのコーパスが1つのドキュメントベクトルを返すことができる必要があります。

 
  1. >>> class MyCorpus(object):

  2. >>> def __iter__(self):

  3. >>> for line in open('mycorpus.txt'):

  4. >>> # assume there's one document per line, tokens separated by whitespace

  5. >>> yield dictionary.doc2bow(line.lower().split())

サンプルファイルmycorpus.txtをここからダウンロードしてください

ここでの前提は、各ドキュメントが別々のファイルの1行を占めることはそれほど重要ではないということです。フォルダのトラバース、XMLの解析など、入力形式に関係なく、入力形式に合わせて__iter__関数を変更できます。ネットワークへのアクセスなど。各ドキュメントのトークンのクリーンリストを解析し、辞書を使用してこれらのシンボルをIDに変換し、最後に__iter__関数でスパースベクトルを生成するだけです。

 
  1. >>> corpus_memory_friendly = MyCorpus() # 没有将整个语料库载入内存

  2. >>> print(corpus_memory_friendly)

  3. <__main__.MyCorpus object at 0x10d5690>

現在のコーパスはオブジェクトです。印刷するメソッドを定義しなかったため、メモリ内のオブジェクトのアドレスしか印刷できません。これは役に立ちません。ベクトルの構成を確認するために、コーパス内の各ドキュメントベクトルを(一度に1つずつ)繰り返し取り出して印刷します。

 
  1. >>> for vector in corpus_memory_friendly: # 一次读入内存一个向量

  2. ... print(vector)

  3. [(0, 1), (1, 1), (2, 1)]

  4. [(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]

  5. [(2, 1), (5, 1), (7, 1), (8, 1)]

  6. [(1, 1), (5, 2), (8, 1)]

  7. [(3, 1), (6, 1), (7, 1)]

  8. [(9, 1)]

  9. [(9, 1), (10, 1)]

  10. [(9, 1), (10, 1), (11, 1)]

  11. [(4, 1), (10, 1), (11, 1)]

出力は通常のPythonリストと同じですが、一度に最大1つのベクトルをメモリに格納できるため、現在のコーパスの方がメモリに適しています。あなたのコーパスはあなたが今考えることができるのと同じくらい大きくなることができます!
同様に、辞書を作成するために、すべてのドキュメントをメモリに読み込む必要はありません。

 
  1. >>> # 收集所有符号的统计信息

  2. >>> dictionary = corpora.Dictionary(line.lower().split() for line in open('mycorpus.txt'))

  3. >>> # 收集停用词和仅出现一次的词的id

  4. >>> stop_ids = [dictionary.token2id[stopword] for stopword in stoplist

  5. >>> if stopword in dictionary.token2id]

  6. >>> once_ids = [tokenid for tokenid, docfreq in dictionary.dfs.iteritems() if docfreq == 1]

  7. >>> dictionary.filter_tokens(stop_ids + once_ids) # 删除停用词和仅出现一次的词

  8. >>> dictionary.compactify() # 消除id序列在删除词后产生的不连续的缺口

  9. >>> print(dictionary)

  10. Dictionary(12 unique tokens)

少なくとも言葉の袋モデルの観点からは、これが彼のために準備する必要があるすべてです。もちろん、このコーパスで何をするかについてのもう1つの質問は、さまざまな単語の頻度を計算することが本当に役立つかどうかわからないということです。本当に役に立たないことがわかりました。最初にこの単純な表現で変換を実行して、いくつかの意味のあるドキュメントとドキュメントの類似性を計算する必要があります。
コンテンツの変換は次のチュートリアルで説明します。その前に、コーパスが長持ちすることに一時的に注意を向けましょう。
 

さまざまなコーパス形式

(ストレージコーパス)

ベクトル空間コーパス(〜ベクトルシーケンス)をシリアル化してハードディスクに保存するためのファイル形式がいくつかあります。Gemsimは、ハードディスクからドキュメントを読み取る(または書き込む)怠惰な方法を使用して、前述のコーパスストリームインターフェイスを介してこれらのメソッドを実装します。一度に1つのドキュメントで、コーパス全体がメインメモリに読み込まれることはありません。
すべてのコーパス形式の中で、非常によく知られているファイル形式は MarketMatrix形式です。この形式でコーパスを保存したい:

 
  1. >>> from gensim import corpora

  2. >>> # 创建一个玩具级的语料库

  3. >>> corpus = [[(1, 0.5)], []] # 让一个文档为空,作为它的heck

  4. >>>

  5. >>> corpora.MmCorpus.serialize('/tmp/corpus.mm', corpus)

他のフォーマットには、JoachimのSVMlightBleiのLDA-CGibbsLDA ++などが含まれます。

 
  1. >>> corpora.SvmLightCorpus.serialize('/tmp/corpus.svmlight', corpus)

  2. >>> corpora.BleiCorpus.serialize('/tmp/corpus.lda-c', corpus)

  3. >>> corpora.LowCorpus.serialize('/tmp/corpus.low', corpus)

(コーパスにロードされます)

代わりに、MatrixMarketファイルからコーパスをロードします。

>>> corpus = corpora.MmCorpus('/tmp/corpus.mm')

コーパスオブジェクトはストリーミングされているため、直接印刷することはできません

 
  1. >>> print(corpus)

  2. MmCorpus(2 documents, 2 features, 1 non-zero entries)

コーパスの内容を本当に見たいのであれば、方法はありません。

 
  1. >>> # 将语料库全部导入内存的方法

  2. >>> print(list(corpus)) # 调用list()将会把所有的序列转换为普通Python List

  3. [[(1, 0.5)], []]

または

 
  1. >>> # 另一种利用流接口,一次只打印一个文档

  2. >>> for doc in corpus:

  3. ... print(doc)

  4. [(1, 0.5)]

  5. []

2番目の方法は明らかにメモリに優しい方法ですが、テストと開発のためだけの場合は、list()を呼び出すよりも簡単な方法はありません。(* ^ _ ^ *)

(コーパスに転送)

このコーパスをMatrixMarket形式でBleiのLDA-C形式に変換するには、次のことを行うだけで済みます。

>>> corpora.BleiCorpus.serialize('/tmp/corpus.lda-c', corpus)

このように、gensimはメモリを節約するI / Oフォーマットコンバーターとして使用できます。1つのファイルフォーマットストリームを使用してコーパスをロードし、それを他のフォーマットで直接保存するだけです。新しいフォーマットを追加するのは簡単すぎます。SVMlightコーパス用設計したコードを参照してください

NumPyおよびSciPyとの互換性

Gensimには、コーパスとnumpyマトリックス間の変換に役立つ多くの効率的なツール関数が含まれています。

 
  1. >>> corpus = gensim.matutils.Dense2Corpus(numpy_matrix)

  2. >>> numpy_matrix = gensim.matutils.corpus2dense(corpus, num_terms=number_of_corpus_features)

そして、コーパスとscipyスパース行列の間の変換:

 
  1. >>> corpus = gensim.matutils.Sparse2Corpus(scipy_sparse_matrix)

  2. >>> scipy_csc_matrix = gensim.matutils.corpus2csc(corpus)

より包括的なリファレンス(たとえば、圧縮された辞書サイズ、最適化されたコーパス変換、NumPy / SciPy配列変換)については、APIドキュメントを参照するか、次の「テーマと変換」チュートリアルを読み続けてください。

 

==================================================

[1]これはDeerwesterらで使用されているものと同じコーパスです。(1990):潜在意味解析による索引付け、 表2。

おすすめ

転載: blog.csdn.net/yocencyy/article/details/89736723