2016-09-01 2 views
0

Мне нужно сохранить данные для обучения в Data Pickle. Вот код. При выполнении этого кода произошла ошибка. Как исправить эту ошибку. Мне нужно сохранить переменные featureCounts и labelCounts в двух соленьях.Ошибка в данных Рассеяние в Python

from __future__ import division 
import collections 
import math 
import pickle 

class TrainClassifier: 
    def __init__(self, arffFile): 
     self.trainingFile = arffFile 
     self.features = {} 
     self.featureNameList = [] 
     self.featureCounts = collections.defaultdict(lambda: 1) 
     self.featureVectors = [] 
     self.labelCounts = collections.defaultdict(lambda: 0) 

    def DataTraning(self): 
     for fv in self.featureVectors: 
      self.labelCounts[fv[len(fv)-1]] += 1 #udpate count of the label 
      for counter in range(0, len(fv)-1): 
       self.featureCounts[(fv[len(fv)-1], self.featureNameList[counter], fv[counter])] += 1 

     for label in self.labelCounts: 
      for feature in self.featureNameList[:len(self.featureNameList)-1]: 
       self.labelCounts[label] += len(self.features[feature]) 

    def GetValues(self): 
     file = open(self.trainingFile, 'r') 

     for line in file: 
      if line[0] != '@': #start of actual data 
       self.featureVectors.append(line.strip().lower().split(',')) 
      else: #feature definitions 
       if line.strip().lower().find('@data') == -1 and (not line.lower().startswith('@relation')): 
        self.featureNameList.append(line.strip().split()[1]) 
        self.features[self.featureNameList[len(self.featureNameList) - 1]] = line[line.find('{')+1: line.find('}')].strip().split(',') 

     file.close() 

    def SaveOnPickle(self): 
     f = open('dict.pickle', 'wb') 
     pickle.dump(self.labelCounts, f) 
     f.close() 

if __name__ == "__main__": 
    Predic = TrainClassifier("Military.arff") 
    Predic.GetValues() 
    Predic.DataTraning() 
    Predic.SaveOnPickle() 

Вот ошибка

Traceback (most recent call last): 
    File "C:\wamp64\www\M360\M360py\src\TrainClassifier.py", line 69, in <module> 
    Predic.SaveOnPickle() 
    File "C:\wamp64\www\M360\M360py\src\TrainClassifier.py", line 43, in SaveOnPickle 
    pickle.dump(self.labelCounts, f) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 1370, in dump 
    Pickler(file, protocol).dump(obj) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 224, in dump 
    self.save(obj) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 331, in save 
    self.save_reduce(obj=obj, *rv) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 401, in save_reduce 
    save(args) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 562, in save_tuple 
    save(element) 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Users\Udara\AppData\Roaming\NetBeans\8.1\jython-2.7.0\Lib\pickle.py", line 746, in save_global 
    raise PicklingError(
pickle.PicklingError: Can't pickle <function <lambda> at 0x5>: it's not found as __main__.<lambda> 
+0

Я бы не сказал, что это точный дубликат. В этом конкретном случае нет необходимости сериализовать функцию, можно было бы использовать более простое решение. Интересный вопрос/ответы на связь, хотя! –

ответ

1

вы не можете сериализовать self.labelCounts, потому что это defaultdict (нет проблем с этим) с lambda в нем: вот загвоздка: Рассол не может сериализовать функции.

Вы писали:

self.labelCounts = collections.defaultdict(lambda: 0) 

Но вам повезло: вы не нужен лямбда здесь (вам нужен лямбда для изменяемых объектов, таких как списки, но с 0 без проблем), просто сделать:

self.labelCounts = collections.defaultdict(0) 

(конечно, это та же проблема и решение для вашего другого dict featureCounts). Сделайте это:

self.featureCounts = collections.defaultdict(1) 
+0

Мне также нужно сохранить featureCounts. Должен ли я удалить лямбда из него? В чем причина использования лямбда для этих переменных? –

+0

Когда я попробую ваше решение, есть такая ошибка. 'Traceback (самый последний вызов последнего): Файл "C: \ wamp64 \ WWW \ M360 \ M360py \ SRC \ TrainClassifier.py", строка 66, в Predic = TrainClassifier (" C:/Users/Удара/Рабочий стол/CDAP/Музей 360 (Система) /Nadeeraka/Dataset/Military.arff ") Файл" C: \ wamp64 \ www \ M360 \ M360py \ src \ TrainClassifier.py ", строка 14, в __init__ self.featureCounts = collections.defaultdict (list()) TypeError: первый аргумент должен быть вызванным' –

+0

'self.featureCounts = collections.defaultdict (1) self.labelCounts = collections.defaultdict (0)' Это код, который я заменил в мой код. Но выше ошибка была создана для этого кода также –