关于python:sklearn没有属性”datasets”

sklearn doesn't have attribute 'datasets'

我已经开始使用sckikit learn来完成我的工作。因此,我正在学习教程,其中给出了加载一些数据集的标准过程:

1
2
3
4
$ python
>>> from sklearn import datasets
>>> iris = datasets.load_iris()
>>> digits = datasets.load_digits()

但是,为了方便起见,我尝试以下方式加载数据:

1
2
3
In [1]: import sklearn

In [2]: iris = sklearn.datasets.load_iris()

但是,这会引发以下错误:

1
2
3
4
5
6
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-db77d2036db5> in <module>()
----> 1 iris = sklearn.datasets.load_iris()

AttributeError: 'module' object has no attribute 'datasets'

但是,如果我使用明显相似的方法:

1
2
3
In [3]: from sklearn import datasets

In [4]: iris = datasets.load_iris()

它毫无问题地工作。实际上,以下内容也有效:

1
In [5]: iris = sklearn.datasets.load_iris()

我对此完全困惑。我是不是错过了一些微不足道的东西?这两种方法有什么区别?


sklearn是一个包。这个答案非常简洁:

when you import a package, only variables/functions/classes in the __init__.py file of that package are directly visible, not sub-packages or modules.

datasetssklearn的一个子包。这就是发生这种情况的原因:

1
2
3
4
5
6
7
8
9
In [1]: import sklearn

In [2]: sklearn.datasets
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-325a2bfc35d0> in <module>()
----> 1 sklearn.datasets

AttributeError: module 'sklearn' has no attribute 'datasets'

然而,这项工作的原因是:

1
2
3
4
In [3]: from sklearn import datasets

In [4]: sklearn.datasets
Out[4]: <module 'sklearn.datasets' from '/home/ethan/.virtualenvs/test3/lib/python3.5/site-packages/sklearn/datasets/__init__.py'>

当您通过执行from sklearn import datasets加载子包datasets时,它会自动添加到包sklearn的名称空间中。这是Python导入系统中一个鲜为人知的"陷阱"。

另外,请注意,如果您查看sklearn__init__.py,您将看到'datasets'__all__的成员,但这只允许您执行以下操作:

1
2
3
In [1]: from sklearn import *
In [2]: datasets
Out[2]: <module 'sklearn.datasets' from '/home/ethan/.virtualenvs/test3/lib/python3.5/site-packages/sklearn/datasets/__init__.py'>

最后要注意的一点是,如果您检查sklearndatasets,您会发现,尽管它们是包,但它们的类型是module。这是因为所有的包都被视为模块——然而,并不是所有的模块都是包。