web-dev-qa-db-ja.com

TfidfVectorizerを保存してscikit learnで再利用する

ScikitでTfidfVectorizerを使用して、テキストデータから行列を作成する方法を学びます。次に、このオブジェクトを保存して、後で再利用する必要があります。漬物を使ってみましたが以下のエラーが出ました。

loc=open('vectorizer.obj','w')
pickle.dump(self.vectorizer,loc)
*** TypeError: can't pickle instancemethod objects

私はsklearn.externalsでjoblibを使用しようとしましたが、同様のエラーが発生しました。このオブジェクトを保存して後で再利用できるようにする方法はありますか?

これが私の完全なオブジェクトです:

class changeToMatrix(object):
def __init__(self,ngram_range=(1,1),tokenizer=StemTokenizer()):
    from sklearn.feature_extraction.text import TfidfVectorizer
    self.vectorizer = TfidfVectorizer(ngram_range=ngram_range,analyzer='Word',lowercase=True,\
                                          token_pattern='[a-zA-Z0-9]+',strip_accents='unicode',tokenizer=tokenizer)

def load_ref_text(self,text_file):
    textfile = open(text_file,'r')
    lines=textfile.readlines()
    textfile.close()
    lines = ' '.join(lines)
    sent_tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
    sentences = [ sent_tokenizer.tokenize(lines.strip()) ]
    sentences1 = [item.strip().strip('.') for sublist in sentences for item in sublist]      
    chk2=pd.DataFrame(self.vectorizer.fit_transform(sentences1).toarray()) #vectorizer is transformed in this step 
    return sentences1,[chk2]

def get_processed_data(self,data_loc):
    ref_sentences,ref_dataframes=self.load_ref_text(data_loc)
    loc=open("indexedData/vectorizer.obj","w")
    pickle.dump(self.vectorizer,loc) #getting error here
    loc.close()
    return ref_sentences,ref_dataframes
15
Joswin K J

まず、クラス内ではなく、コードの先頭にインポートを残すことをお勧めします。

from sklearn.feature_extraction.text import TfidfVectorizer
class changeToMatrix(object):
  def __init__(self,ngram_range=(1,1),tokenizer=StemTokenizer()):
    ...

次のStemTokenizerは正規のクラスではないようです。おそらくあなたはそれを http://sahandsaba.com/visualizing-philosophers-and-scientists-by-the-words-they-used-with-d3js-and-python.html またはたぶん他のどこかで文字列のリストを返すと仮定します

class StemTokenizer(object):
    def __init__(self):
        self.ignore_set = {'footnote', 'nietzsche', 'plato', 'mr.'}

    def __call__(self, doc):
        words = []
        for Word in Word_tokenize(doc):
            Word = Word.lower()
            w = wn.morphy(Word)
            if w and len(w) > 1 and w not in self.ignore_set:
                words.append(w)
        return words

今あなたの実際の質問に答えるために、ピクルをダンプする前にバイトモードでファイルを開く必要がある可能性があります、すなわち:

>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> from nltk import Word_tokenize
>>> import cPickle as pickle
>>> vectorizer = TfidfVectorizer(ngram_range=(0,2),analyzer='Word',lowercase=True, token_pattern='[a-zA-Z0-9]+',strip_accents='unicode',tokenizer=Word_tokenize)
>>> vectorizer
TfidfVectorizer(analyzer='Word', binary=False, decode_error=u'strict',
        dtype=<type 'numpy.int64'>, encoding=u'utf-8', input=u'content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(0, 2), norm=u'l2', preprocessor=None, smooth_idf=True,
        stop_words=None, strip_accents='unicode', sublinear_tf=False,
        token_pattern='[a-zA-Z0-9]+',
        tokenizer=<function Word_tokenize at 0x7f5ea68e88c0>, use_idf=True,
        vocabulary=None)
>>> with open('vectorizer.pk', 'wb') as fin:
...     pickle.dump(vectorizer, fin)
... 
>>> exit()
alvas@ubi:~$ ls -lah vectorizer.pk 
-rw-rw-r-- 1 alvas alvas 763 Jun 15 14:18 vectorizer.pk

:I/Oファイルアクセスにwithイディオムを使用すると、withスコープを抜けると、ファイルが自動的に閉じます。

SnowballStemmer()の問題については、SnowballStemmer('english')はオブジェクトであり、ステミング関数はSnowballStemmer('english').stemであることに注意してください。

[〜#〜]重要[〜#〜]

  • TfidfVectorizerのtokenizerパラメータは文字列を受け取り、文字列のリストを返すことを期待しています
  • ただし、Snowballステマーは文字列を入力として取りません。文字列のリストを返します。

したがって、これを行う必要があります:

>>> from nltk.stem import SnowballStemmer
>>> from nltk import Word_tokenize
>>> stemmer = SnowballStemmer('english').stem
>>> def stem_tokenize(text):
...     return [stemmer(i) for i in Word_tokenize(text)]
... 
>>> vectorizer = TfidfVectorizer(ngram_range=(0,2),analyzer='Word',lowercase=True, token_pattern='[a-zA-Z0-9]+',strip_accents='unicode',tokenizer=stem_tokenize)
>>> with open('vectorizer.pk', 'wb') as fin:
...     pickle.dump(vectorizer, fin)
...
>>> exit()
alvas@ubi:~$ ls -lah vectorizer.pk 
-rw-rw-r-- 1 alvas alvas 758 Jun 15 15:55 vectorizer.pk
8
alvas