Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 14, 2013 20:26:19

Nata
От:
Зарегистрирован: 2010-10-02
Сообщения: 87
Репутация: +  6  -
Профиль   Отправить e-mail  

MemoryError

Добрый вечер,
такой вопрос: я хочу построить классификатор (Naive Bayes). у меня ок. 50 тыс. примеров (с классами) для обучения, 1852 параметрoв в каждом, храню их в виде:

[({feat1: val1, feat2: val2, ...}, classA), ({feat1: val1, feat2: val2, ...}, classB), ...]
. Когда запускаю классификатор, выходит ошибка:
Traceback (most recent call last):
File "add_values/add_values.py", line 39, in <module>
extract_features(features, get_token_set(for_set))
File "add_values/add_values.py", line 27, in extract_features
features[token]=(token in words[:-2])
MemoryError
я знаю, что словарь не самый экономный вариант для хранения данных, но их вроде не так много у меня.
Подскажите пожалуйста можно ли решить эту проблему не переписывая классификатор (он принимает в кач-ве аргумента данные именно в таком формате).
заранее спасибо!

P.S. кусок кода который дает ошибку
def extract_features(features_file, token_set):
	featureset=[]
	for line in features_file:
		features={}	
		words=line.strip().split(" ")
		for token in token_set:
			features[token]=(token in words[:-2])
		features["concept"]=words[-2]
		featureset.append((features, words[-1]))
	return featureset





Отредактировано Nata (Янв. 14, 2013 20:29:09)

Офлайн

#2 Янв. 14, 2013 22:05:20

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

MemoryError

если много объектов можно использовать __slots__, но это вряд ли спасет

features[token]=(token in words[:-2])
(token in words[:-2])
скобки зачем?

Офлайн

#3 Янв. 15, 2013 16:44:19

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

MemoryError

Nata
я знаю, что словарь не самый экономный вариант для хранения данных, но их вроде не так много у меня.
Проблема не в словаре, а в списке словарей. Тем более features - небольшой.

NaiveBayesClassifier.train() может работать с генератором.
Попробуйте:
def extract_features(features_file, token_set):
    for line in features_file:
        features = {} 
        words = line.strip().split(" ")
        first_words = set(words[:-2])
        for token in token_set:
            features[token] = token in first_words
        features["concept"] = words[-2]
        yield features, words[-1]
...
features_gen = extract_features(features_file, token_set)
classifier = nltk.classify.NaiveBayesClassifier.train(features_gen)
Не уверен, что правильно поступаю с
words[:-2]
т.к. неизвестен формат данных и размер token_set.

Если часть features используется для обучения, а часть для теста, нужно будет немного переписать генератор или использовать itertools.islice().

Отредактировано reclosedev (Янв. 15, 2013 16:47:27)

Офлайн

#4 Янв. 15, 2013 20:36:19

Nata
От:
Зарегистрирован: 2010-10-02
Сообщения: 87
Репутация: +  6  -
Профиль   Отправить e-mail  

MemoryError

спасибо, генератор помог :)
теперь другая проблема: не получается сохранить классификатор :(

temp = open("classifier.pickle", "wb")
pickle.dump(classifier, temp)
temp.close()
Traceback (most recent call last):
File "add_values.py", line 58, in <module>
pickle.dump(classifier, temp)
File "/usr/lib/python2.6/pickle.py", line 1362, in dump
Pickler(file, protocol).dump(obj)
File "/usr/lib/python2.6/pickle.py", line 224, in dump
self.save(obj)
...
File "/usr/lib/python2.6/pickle.py", line 247, in memoize
self.memo[id(obj)] = memo_len, obj
MemoryError

придется запускать каждый раз заново, training занимает ок. 30 минут; но зато работает!!!





Офлайн

#5 Янв. 15, 2013 20:48:10

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

MemoryError

А сколько памяти в системе?
Возможно поможет использование cPickle c HIGHEST_PROTOCOL:

import cPickle as pickle
...
pickle.dump(classifier, temp, pickle.HIGHEST_PROTOCOL)

Еще можно PyPy попробовать для ускорения.

Офлайн

#6 Янв. 16, 2013 12:30:34

Nata
От:
Зарегистрирован: 2010-10-02
Сообщения: 87
Репутация: +  6  -
Профиль   Отправить e-mail  

MemoryError

Traceback (most recent call last):
File "add_values.py", line 66, in <module>
pickle.dump(classifier, temp, pickle.HIGHEST_PROTOCOL)
MemoryError
reclosedev
А сколько памяти в системе?
вот meminfo
MemTotal:        4015900 kB
MemFree: 2345400 kB
Buffers: 142340 kB
Cached: 716740 kB
SwapCached: 0 kB
Active: 504488 kB
Inactive: 1016376 kB
...
я думала, что это не имеет значения и что все зависит от версии питона и его “memory allocation managment”



Офлайн

#7 Янв. 16, 2013 16:36:52

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

MemoryError

import cPickle as pickle
...
with open('classifier.pickle', 'wb') as f:
    pickler = pickle.Pickler(f, 1)
    pickler.fast = True
    pickler.dump(classifier)
pickler.fast отсюда:
http://python.6.n6.nabble.com/Memory-error-while-saving-dictionary-of-size-65000X50-using-pickle-td1441000.html

Попробовал сначала с HIGHEST_PROTOCOL, не сработало, поэтому protocol = 1.

Офлайн

#8 Янв. 16, 2013 17:59:51

Nata
От:
Зарегистрирован: 2010-10-02
Сообщения: 87
Репутация: +  6  -
Профиль   Отправить e-mail  

MemoryError

все работает!!! (с Pickler для dump() и Unpickler для load() )
И pypy построил классификатор за 4 минуты !
спасибо большое!!!



Отредактировано Nata (Янв. 16, 2013 18:01:48)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version