3

テキスト分類にscikitlearnモジュールを使用しようとしています。ユニークな単語がたくさんあるデータセットです。その性質は、次の例から明らかになります。

train_counts = count_vect.fit_transform(data)
train_counts.shape

print len(range(len(data)-1)) 

clf = MultinomialNB(alpha=1).fit(train_counts, range(len(data)) )

docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']

new_counts = count_vect.transform(docs_new)
predicted = clf.predict(new_counts)

for doc, category in zip(docs_new, predicted):
    print '%r => %s' % (doc, target_names[category])

出力は次のようになります。

763
'Modern Warfare 2' => Call of Duty: Modern Warfare 3
'Modern Warfare 3' => Call of Duty: Modern Warfare 3
'Modern Warfare 1' => Call of Duty: Modern Warfare 3
'Modern Warfare 4' => Call of Duty: Modern Warfare 3
'Modern Warfare' => Call of Duty: Modern Warfare 3
'Mahjong Kakutou Club' => Mahjong Kakutou Club
'Mass Effect 2' => Mass Effect 2

これは多項の例ですが、ベルヌーイの例と同じ結果が得られます。私は0から1000000までのアルファ値で試しました。なぜこれが当てはまるのか誰かが私に説明できますか?

編集:私はそれを明確にすべきでした、次のクラスが存在しますCall of Duty:Modern Warfare、Call of Duty:Modern Warfare 2 ...他のほとんどのゲーム、すべてのプレイステーションゲームのリストはウィキペディアから取られました。

また、フルバージョン、たとえばCall of Duty:Modern Warfare 2をテスト文字列として使用すると、同じ結果が得られます。

私はもともとNLTK分類子を使っていましたが、どういうわけか、他の例にはない「角とう」のような価値のある単語をあまり配置していませんでした。(明らかにScikitのものはそうです)それはscikit分類子がするように数に問題がありませんでした。

ここでのガイダンスや情報は非常に価値があります。

ありがとう

編集:データセットはここからhttp://en.wikipedia.org/wiki/List_of_PlayStation_3_gamesの最初の列にあり、各例には同じラベルとコンテンツがあります

4

1 に答える 1

1

コードはcount_vectがどのように構築されるかを示していませんが、デフォルトで初期化されている場合CountVectorizerは、文字トークン(つまりシリーズ番号)を無視して、すべての「ModernWarfare...」タイトルを「ModernWarfare」と同じようにトークン化します。

>>> from sklearn.feature_extraction.text import CountVectorizer as CV
>>> count_vect=CV()
>>> docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare A', 'Modern Warfare 44', 'Modern Warfare AA', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']
>>> new_counts = count_vect.fit_transform(docs_new)
>>> count_vect.inverse_transform(new_counts)
[array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'44', u'modern', u'warfare'], 
      dtype='<U7'), array([u'aa', u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'club', u'kakutou', u'mahjong'], 
      dtype='<U7'), array([u'effect', u'mass'], 
      dtype='<U7')]

これは、scikit vectorizersのデフォルト設定がtoken_pattern=r'(?u)\b\w\w+\b' 、トレーニングも予測もこれらのタイトル間の違いを認識しないため、モデルが任意に関係を断ち切っているためです。これを回避するには、token_pattern=r'(?u)\b\w+\b'

>>> from sklearn.feature_extraction.text import CountVectorizer as CV
>>> count_vect=CV(token_pattern=r'(?u)\b\w+\b')
>>> docs_new = ['Modern Warfare 2', 'Modern Warfare 3', 'Modern Warfare 1', 'Modern Warfare 4', 'Modern Warfare A', 'Modern Warfare 44', 'Modern Warfare AA', 'Modern Warfare', 'Mahjong Kakutou Club', 'Mass Effect 2']
>>> new_counts = count_vect.fit_transform(docs_new)
>>> count_vect.inverse_transform(new_counts)
[array([u'2', u'modern', u'warfare'], 
      dtype='<U7'), array([u'3', u'modern', u'warfare'], 
      dtype='<U7'), array([u'1', u'modern', u'warfare'], 
      dtype='<U7'), array([u'4', u'modern', u'warfare'], 
      dtype='<U7'), array([u'a', u'modern', u'warfare'], 
      dtype='<U7'), array([u'44', u'modern', u'warfare'], 
      dtype='<U7'), array([u'aa', u'modern', u'warfare'], 
      dtype='<U7'), array([u'modern', u'warfare'], 
      dtype='<U7'), array([u'club', u'kakutou', u'mahjong'], 
      dtype='<U7'), array([u'2', u'effect', u'mass'], 
      dtype='<U7')]
于 2014-05-08T01:29:58.003 に答える