我一定要把这个问题记录下来,因为走了太多冤枉路,花了太多时间了!

问题描述:

       在将师兄的项目移植到自己电脑上时,出现了No module named 'sklearn.svm.classes'错误,经过多次搜索查询后发现,由于我使用的是sciki-learn的最新版本,不同于师兄保存模型时使用的scikit-learn0.20.2版本,在24版本上sklearn.svm.classes已经被弃用(通过下载中间版本—22版本发现的这个问题,中间版本距离20版本很近,报错时会提示弃用之类的错误,24版本则不会),所以会报这个错误。

解决过程:

       于是,我将scikit-learn降级为0.20.2版本,结果依然报错:TypeError: an integer is required (got type bytes),经过搜索分析,发现是由于scikit-learn0.20.2与python3.8不兼容,这时就面临要升级scikit-learn还是降级python的问题。

       后面经过在代码里面错误定位我发现,这个错误是在使用pickle.load(file)语句进行反序列化时出的,这里的pickle.load是将文件中的数据解析为一个python对象,提到pickle序列化这里就有个问题,joblib仅当在保存模型的程序和加载模型的程序之间安装的软件包的版本完全相同时,才能通过进行序列化。所以这里的scikit-learn必须使用0.20.2版本,那么就需要解决TypeError: an integer is required (got type bytes)问题。

       解决TypeError: an integer is required (got type bytes)问题:

         根据报错提示,定位到这个目录D:\Python\Lib\site-packages\sklearn\externals\joblib\externals\cloudpickle\cloudpickle.py的148行:

         未修改的代码长这样:

    def inner(value):
        lambda: cell  # make ``cell`` a closure so that we get a STORE_DEREF
        cell = value

    co = inner.__code__

    # NOTE: we are marking the cell variable as a free variable intentionally
    # so that we simulate an inner function instead of the outer function. This
    # is what gives us the ``nonlocal`` behavior in a Python 2 compatible way.
    if not PY3:
        return types.CodeType(
            co.co_argcount,
            co.co_nlocals,
            co.co_stacksize,
            co.co_flags,
            co.co_code,
            co.co_consts,
            co.co_names,
            co.co_varnames,
            co.co_filename,
            co.co_name,
            co.co_firstlineno,
            co.co_lnotab,
            co.co_cellvars,  # this is the trickery
            (),
        )
    else:
        return types.CodeType(
            co.co_argcount,
            co.co_kwonlyargcount,
            co.co_nlocals,
            co.co_stacksize,
            co.co_flags,
            co.co_code,
            co.co_consts,
            co.co_names,
            co.co_varnames,
            co.co_filename,
            co.co_name,
            co.co_firstlineno,
            co.co_lnotab,
            co.co_cellvars,  # this is the trickery
            (),
        )

在else:后面开始修改,改为:

args = [
            co.co_argcount,
            co.co_kwonlyargcount,
            co.co_nlocals,
            co.co_stacksize,
            co.co_flags,
            co.co_code,
            co.co_consts,
            co.co_names,
            co.co_varnames,
            co.co_filename,
            co.co_name,
            co.co_firstlineno,
            co.co_lnotab,
            co.co_cellvars,  # this is the trickery
            (),
		]
        if sys.version_info >= (3, 8, 0):
            args.insert(2, 0)
        new_code = types.CodeType(*args)
        return new_code

这个函数的完整代码:

    def inner(value):
        lambda: cell  # make ``cell`` a closure so that we get a STORE_DEREF
        cell = value

    co = inner.__code__

    # NOTE: we are marking the cell variable as a free variable intentionally
    # so that we simulate an inner function instead of the outer function. This
    # is what gives us the ``nonlocal`` behavior in a Python 2 compatible way.
    if not PY3:
        return types.CodeType(
            co.co_argcount,
            co.co_nlocals,
            co.co_stacksize,
            co.co_flags,
            co.co_code,
            co.co_consts,
            co.co_names,
            co.co_varnames,
            co.co_filename,
            co.co_name,
            co.co_firstlineno,
            co.co_lnotab,
            co.co_cellvars,  # this is the trickery
            (),
        )
    else:
        args = [
            co.co_argcount,
            co.co_kwonlyargcount,
            co.co_nlocals,
            co.co_stacksize,
            co.co_flags,
            co.co_code,
            co.co_consts,
            co.co_names,
            co.co_varnames,
            co.co_filename,
            co.co_name,
            co.co_firstlineno,
            co.co_lnotab,
            co.co_cellvars,  # this is the trickery
            (),
		]
        if sys.version_info >= (3, 8, 0):
            args.insert(2, 0)
        new_code = types.CodeType(*args)
        return new_code

   或许运行的时候还会出一些书写格式上的小问题,解决一下就好啦!

 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐