前提・実現したいこと
文章の定義:いくつかの文がまとまったもの。
文章の中でSCDVを利用し12000次元に特徴量を持つクラス分けされた文の中で、比較したい文章が、どのクラスに属するのかをSVMを使って判定するプログラムを作りたい。
(win10 64bit python3.7)
参考URL:
・文書分散表現SCDVと他の分散表現を比較してみた
そのためにどういったアプローチか(理想と実際の違いも含む)
1:3種類の文を(戦国武将、財務系、食べ物)集めて、クラス分けをします。その際にそれぞれの種類の文1つ1つが12000次元の特徴量を持つことができました。
実施のデータ:(487, 12000)←487文あり、各々が12000ベクトルを持つ状態
2:次に一文を任意に用意しましす。
「体調を崩した欧州の銀行家のために即興で提供した料理であると考えられている。」(食べ物のドリアの説明文のひとつです。)
3:この任意の文をまったく同じ経路でプログラムを通します。
理想の結果:(1, 12000)←1文が12000次元のベクトルを持つ状態
実際の結果:途中のパラメータを変えなければ作れない。作れても
(1, 200)←1文が200次元ベクトルを持つ状態
発生している問題・エラーメッセージ
ValueError: X.shape[1] = 200 should be equal to 12000, the number of features at training time
該当のソースコード
~問題の箇所は以下です~
python
1from sklearn.svm import SVC 2clf = SVC(kernel="linear") 3one_y_pred = clf.fit(scdvs, train_target).predict(test_scdvs)
~こちらは全体のソースコードです~
python
1記載しましたが、teratailの質問文制限文字に引っかかってしまい、以下のGoogle Driveに共有保存しました。
試したこと
1
元々は、min_word_countは10でした。多数の文を束ねた文章をクラス分けするのが目的のコードのため、これは10でした。
python
1min_word_count = 10 2tfidf_vectorizer = TfidfVectorizer(analyzer=analyzer, min_df=min_word_count) 3tfidfs = tfidf_vectorizer.fit_transform(test_corpus_before)
しかし、その場合ですと、全体の文章を通したプログラムに1文だけを通したときに、以下エラーが起きました。
cmd
1 File "C:\ProgramData\Anaconda3\envs\lstm\lib\site-packages\sklearn\feature_extraction\text.py", line 1214, in fit_transform 2 "max_df corresponds to < documents than min_df") 3ValueError: max_df corresponds to < documents than min_df
このため私は10を1に変えました。
python
1min_word_count = 1 # 片方がフリー文の1文だけのため10⇒1へ変更 2tfidf_vectorizer = TfidfVectorizer(analyzer=analyzer, min_df=min_word_count)
すると、そこは通過できたのですが、以下のコードでエラーになりました。
python
1clusters_num = 60 2gmm = mixture.GaussianMixture(n_components=clusters_num, covariance_type='tied', max_iter=50) 3gmm.fit(word_vectors)
cmd
1ValueError: Expected n_samples >= n_components but got n_components = 60, n_samples = 22
確かに、1文しかないため、クラスターを60個に設定するのもおかしいと思い、以下を1個に変えました。
python
1clusters_num = 1 # 片方がフリー文の1文だけのため60⇒1へ変更 2gmm = mixture.GaussianMixture(n_components=clusters_num, covariance_type='tied', max_iter=50) 3gmm.fit(word_vectors)
すると、出来上がった1文のベクトルは(1, 200)と200次元になってしまいました。
これが一番上に書いたエラーになります。
ここからの対処法として以下を実行しました。
2
12000次元ある方のベクトルを200次元に調整してみました。
python
1new_scdvs = scdvs.reshape(-1, 200) 2from sklearn.svm import SVC 3clf = SVC(kernel="linear") 4one_y_pred = clf.fit(new_scdvs, train_target).predict(test_scdvs)
しかしその場合、文章の個数が逆に増えてしまい、以下のSVMの式で有効に計算できなくなってしまいました。
python
1(Pdb) new_scdvs = scdvs.reshape(-1, 200) 2(Pdb) new_scdvs.shape 3(28440, 200)
python
1from sklearn.svm import SVC 2clf = SVC(kernel="linear") 3one_y_pred = clf.fit(new_scdvs, train_target).predict(test_scdvs)
scdvsは、487文に対して、train_target(正解ラベルを詰めたリスト)の正解と学習させて、test_scdvsの1文のベクトルは、どこに属するかを予測しています。
エラーは以下です。
cmd
1 File "C:\ProgramData\Anaconda3\envs\lstm\lib\site-packages\sklearn\utils\validation.py", line 257, in check_consistent_length 2 " samples: %r" % [int(l) for l in lengths]) 3ValueError: Found input variables with inconsistent numbers of samples: [28440, 474]
どのようにすればSCDVを利用する多量の特徴を利用して1文と比較できるのでしょうか。一番上に記載した参考サイトの方は200次元としてやられていますが、私の作りでの改変で詰まってしまいました。
次元削除などでそもそもベクトル比較する際によいのか含め、このあとの取るべきアプロ―チなどアドバイス頂けないでしょうか。よろしくお願い致します。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。