AttributeError when I use libsvm on python

617 Views Asked by At

I'm trying to overcome some errors being thrown by the following snippet:

import os
from libsvm.svmutil import *
from scipy.io import loadmat

data = loadmat(os.path.join('Data','ex6data1.mat'))
X,y = data['X'],data['y'][:,0]
model = svm_train(y,X,'-s 0 -t 2 -c 0.2 -g 2.8')
print(model)

Which produces this error:

Traceback (most recent call last):
  File "E:\Pythonlean\machine\venv\lib\site-packages\scipy\__init__.py", line 214, in __getattr__
    return globals()[name]
KeyError: 'ctypeslib'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "E:\Pythonlean\machine\Exercise6\test2.py", line 7, in <module>
    model = svm_train(y,X,'-s 0 -t 2 -c 0.2 -g 2.8')
  File "E:\Pythonlean\machine\venv\lib\site-packages\libsvm\svmutil.py", line 92, in svm_train
    prob = svm_problem(y, x, isKernel=(param.kernel_type == PRECOMPUTED))
  File "E:\Pythonlean\machine\venv\lib\site-packages\libsvm\svm.py", line 218, in __init__
    scipy.ctypeslib.as_array(self.y, (self.l,))[:] = y
  File "E:\Pythonlean\machine\venv\lib\site-packages\scipy\__init__.py", line 216, in __getattr__
    raise AttributeError(
AttributeError: Module 'scipy' has no attribute 'ctypeslib'

All package versions:

  • libsvm-official(3.25.0)
  • scipy(1.9.0)
  • numpy(1.23.1)
1

There are 1 best solutions below

0
Andras Deak -- Слава Україні On

The library code of libsvm-official for version 3.25.0 contains a reference using scipy.ctypeslib, which doesn't exist. You have to either patch their code or update the library.

To quote this issue comment:

ctypeslib is actually from numpy. It is best to import it directly from there.

Mirroring all of the numpy symbols in the scipy namespace was an early design decision that we probably wouldn't make again. FWIW, I recommend only using scipy for the subpackages it explicitly provides and ignoring all of the stuff mirrored from numpy. Import numpy stuff from numpy directly.

The numpy mirrors were deprecated in #10290 (and the actual removal of ctypeslib and other modules imports from numpy in #15230, though that looks mostly incidental). Only functions got the deprecation warning treatment because it's hard to implement a deprecation of accessing a module, unlike calling a function.

The corresponding PR where these were deprecated was released in SciPy 1.4.0. Current code has to use numpy.ctypeslib. It's a bit surprising that libsvm-official 3.25.0 was released in April 2021, but the deprecation PR was merged in October 2019. Oh well.

The good news is that according to the libsvm changelog the newest version 3.3 has this fixed:

3.3: 2022/8/11 One-class probabilistic outputs introduced Use numpy Use numpy stuff directly instead of mirrored ones in scipy

So updating the library to libsvm-official==3.3 should hopefully fix this issue. The release is brand new (the date above is pretty much "today" when I'm posting this), but it's not on PyPI yet. Hopefully they will upload the release to PyPI soon.