質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1089閲覧

word2vec コーパスの学習方法にてエラー発生

maro

総合スコア13

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/01/10 12:11

前提

word2vecでレビューの名詞を学習させて,その名詞の分散表現を取得したいと考えています.実装はできているのですが,期待通りに動きません.

実現したいこと

  • word2vecコーパスを学習させる.
  • コーパスの全単語を学習させる.

発生している問題

ソースコード1のword_listにはレビュー文の名詞が二次元リストの形式で格納されています.len(c)では,そのリストに格納されている名詞を重複なしでカウントしています.その結果は2728と出力されています.

しかし,ソースコード2では,452件の単語しか学習できていないことが確認できます.また,「昼過ぎ」という単語の分散表現を取得しようとしたところ,該当する単語がないとエラーが出力されます.もちろん,word_listの中に「昼過ぎ」があることは確認済みです.

この問題を解決したく,2728件の単語を学習させたいです.また,エラーメッセージ1の警告も気になります.batch_wordsを小さくすることを推奨されているようですが,このbatch_wordsがどこに該当するのかもわかりません.

どなたかわかる方,お教えいただければ幸いです.

該当のソースコード1

python

1# Word2Vecライブラリのロード 2from gensim.models import word2vec 3from collections import Counter 4import collections 5 6# size: 圧縮次元数 7# min_count: 出現頻度の低いものをカットする 8# window: 前後の単語を拾う際の窓の広さを決める 9# iter: 機械学習の繰り返し回数(デフォルト:5)十分学習できていないときにこの値を調整する 10# model.wv.most_similarの結果が1に近いものばかりで、model.dict['wv']のベクトル値が小さい値ばかりの 11# ときは、学習回数が少ないと考えられます。 12# その場合、iterの値を大きくして、再度学習を行います。 13 14# 事前準備したword_listを使ってWord2Vecの学習実施 15 16#docs = word2vec.LineSentence("/content/test1.txt") 17 18 19for words in word_list: 20 for word in words: 21 new_word.append(word) 22c = collections.Counter(new_word) 23print(len(c)) 24 25 26model = word2vec.Word2Vec(word_list, sg = 1, size=100, min_count=5, window=5, iter=10) 27 28 29model.save("kokoro.model")

エラーメッセージ1

2728 WARNING:gensim.models.base_any2vec:under 10 jobs per worker: consider setting a smaller `batch_words' for smoother alpha decay

該当のソースコード2

python

1print("分散表現の形状:\n{}".format(model.wv.vectors.shape)) 2 3 4 5分散表現の形状: 6(452, 100)

エラーメッセージ1

KeyError Traceback (most recent call last) <ipython-input-71-703caa5902ad> in <module> ----> 1 print(model.__dict__['wv']['昼過ぎ']) 2 frames /usr/local/lib/python3.8/dist-packages/gensim/models/keyedvectors.py in word_vec(self, word, use_norm) 450 return result 451 else: --> 452 raise KeyError("word '%s' not in vocabulary" % word) 453 454 def get_vector(self, word): KeyError: "word '昼過ぎ' not in vocabulary"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

回答ではありません

とりあえず全部入れるにはmin_count=1にしないと駄目なんじゃないかと思います。ただし、

https://rare-technologies.com/word2vec-tutorial/

Bigger size values require more training data, but can lead to better (more accurate) models. Reasonable values are in the tens to hundreds.

とのことなので、wvのsizeが1000を超えるのは妥当じゃないようです。

質問の仕方の問題

環境が全く記載されていないので、再現させるために回答者が試行錯誤しないと答えられない質問になっています。

jupyterを使ってるなら(エラーメッセージにipythonが見えるので)、それらを使っている旨が必ず必要です。またその際にcpythonではなくanacondaを使っていたり、pipではなくconda(anacondaの標準的な環境ツール)を使っているならそれは明記する必要があり、インストールしているpythonのパッケージがあるならそれも記載が必要です。そしてそれら各々にバージョンの記載が必要になります。そして当然pythonやOSやそのバージョンも必要です。それらが異なるだけで現象は全く異なってしまいます。

再現環境に近い環境の構築

近いコードを書いてみました。本来ならshell scriptかbatファイル(もしくはpowershellだが懸念点が多すぎる)で書くところだけど、なるべく共通にすべくpythonで書きました。venvで構築した環境に

  • mecab-python3 1.0.6(最新)
  • unidic-lite 1.0.8(最新)
  • gensim 4.3.0(最新)

を入れて、hoge.pyというサンプルコードを含んだファイルを出力して実行します。実行するとサンプルドキュメントを適当に文に分解し、mecabで形態素解析した後、名詞だけにしてword2vecに突っ込んで最後にvocab相当を出力させています。

min_countを2以上にすると、出現回数がその数字未満の単語は消えてしまうのが分かります。

python

1import os 2import venv 3import subprocess 4ENV = 'env' 5if os.name == 'posix': 6 BIN = 'bin' 7else: 8 BIN = 'Scripts' 9builder = venv.EnvBuilder(with_pip=True) 10builder.create(ENV) 11python = os.path.join('.', ENV, BIN, 'python') 12p = subprocess.run([python, '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools']) 13p = subprocess.run([python, '-m', 'pip', 'install', 'mecab-python3', 'unidic-lite', 'gensim']) 14with open('hoge.py', 'wt', encoding='utf8') as f: 15 f.write("""\ 16document = \"\"\"\\ 17前提 18 19word2vecでレビューの名詞を学習させて,その名詞の分散表現を取得したいと考えています.実装はできているのですが,期待通りに動きません. 20実現したいこと 21 22 word2vecコーパスを学習させる. 23 コーパスの全単語を学習させる. 24 25発生している問題 26 27ソースコード1のword_listにはレビュー文の名詞が二次元リストの形式で格納されています.len(c)では,そのリストに格納されている名詞を重複なしでカウントしています.その結果は2728と出力されています. 28 29しかし,ソースコード2では,452件の単語しか学習できていないことが確認できます.また,「昼過ぎ」という単語の分散表現を取得しようとしたところ,該当する単語がないとエラーが出力されます.もちろん,word_listの中に「昼過ぎ」があることは確認済みです. 30 31この問題を解決したく,2728件の単語を学習させたいです.また,エラーメッセージ1の警告も気になります.batch_wordsを小さくすることを推奨されているようですが,このbatch_wordsがどこに該当するのかもわかりません. 32 33どなたかわかる方,お教えいただければ幸いです. 34\"\"\" 35import re 36sentences = [*filter(lambda x: x != '', map(str.strip, re.split(r'.|\\n\\n', document)))] 37import MeCab 38chasen = MeCab.Tagger() 39words_list = [[*map(lambda x: x[0], filter(lambda x: len(x)>=5 and '名詞' in x[4], [elmline.split() for elmline in chasen.parse(sentence).splitlines()]))] for sentence in sentences] 40print(words_list) 41new_word = [word for words in words_list for word in words] 42import collections 43c = collections.Counter(new_word) 44print(len(c)) 45from gensim.models import word2vec 46model = word2vec.Word2Vec(words_list, vector_size = 100, min_count=1) 47print(f'分散表現の形状:\\n{model.wv.vectors.shape}') 48print(f'単語:\\n{model.wv.index_to_key}') 49""") 50p = subprocess.run([python, 'hoge.py'])

投稿2023/01/10 17:47

dameo

総合スコア943

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maro

2023/01/12 09:15

ありがとうございます.解決できました.また,その他のご指摘も助かりました.
guest

0

min_count=1 で実行してください。

投稿2023/01/11 05:06

t98907

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問