在python2中取消勾选python3保存的sklearn.ensemble.RandomForestClassifier
我遇到了与的类似问题,但stackoverflow.com/questions/1385096/上的链接解决方案似乎不适合我 在尝试使用python2加载 sklearn是我在python3中保存的一个分类器 我把它归结为一个核心问题,即加载一个结构化的numpy数组,该数组被保存以表示树中的节点,这会导致在python2中取消勾选python3保存的sklearn.ensemble.RandomForestClassifier,python,numpy,scikit-learn,pickle,Python,Numpy,Scikit Learn,Pickle,我遇到了与的类似问题,但stackoverflow.com/questions/1385096/上的链接解决方案似乎不适合我 在尝试使用python2加载 sklearn是我在python3中保存的一个分类器 我把它归结为一个核心问题,即加载一个结构化的numpy数组,该数组被保存以表示树中的节点,这会导致 ValueError:Numpy数据类型中的非字符串名称取消勾选 我创建了一个MWE 在python 3中 import numpy as np import pickle data = n
ValueError:Numpy数据类型中的非字符串名称取消勾选
我创建了一个MWE
在python 3中
import numpy as np
import pickle
data = np.array(
[( 1, 26, 69, 5.32214928e+00, 0.69562945, 563, 908., 1),
( 2, 7, 62, 1.74883020e+00, 0.33854101, 483, 780., 1),
(-1, -1, -2, -2.00000000e+00, 0.76420451, 7, 9., -2),
(-1, -1, -2, -2.00000000e+00, 0. , 62, 106., -2)],
dtype=[('left_child', '<i8'), ('right_child', '<i8'),
('feature', '<i8'), ('threshold', '<f8'), ('impurity',
'<f8'), ('n_node_samples', '<i8'),
('weighted_n_node_samples', '<f8'), ('missing_direction',
'<i8')])
# Save using pickle
with open('data.pkl', 'wb') as file_:
# Use protocol 2 to support python2 and 3
pickle.dump(data, file_, protocol=2)
# Save with numpy directly
np.save('data.npy', data)
然而,这仍然不能使sklearn在2和3之间发挥出色。
那么,我们如何让pickle正确加载这个numpy对象呢?
以下是链接中建议的修复方法:
from lib2to3.fixes.fix_imports import MAPPING
import sys
import pickle
# MAPPING maps Python 2 names to Python 3 names. We want this in reverse.
REVERSE_MAPPING = {}
for key, val in MAPPING.items():
REVERSE_MAPPING[val] = key
# We can override the Unpickler and loads
class Python_3_Unpickler(pickle.Unpickler):
def find_class(self, module, name):
if module in REVERSE_MAPPING:
module = REVERSE_MAPPING[module]
__import__(module)
mod = sys.modules[module]
klass = getattr(mod, name)
return klass
with open('data.pkl', 'rb') as file_:
data = Python_3_Unpickler(file_).load()
这仍然不起作用
from lib2to3.fixes.fix_imports import MAPPING
import sys
import pickle
# MAPPING maps Python 2 names to Python 3 names. We want this in reverse.
REVERSE_MAPPING = {}
for key, val in MAPPING.items():
REVERSE_MAPPING[val] = key
# We can override the Unpickler and loads
class Python_3_Unpickler(pickle.Unpickler):
def find_class(self, module, name):
if module in REVERSE_MAPPING:
module = REVERSE_MAPPING[module]
__import__(module)
mod = sys.modules[module]
klass = getattr(mod, name)
return klass
with open('data.pkl', 'rb') as file_:
data = Python_3_Unpickler(file_).load()