Python scikit-learn - TypeError

Python scikit-learn - TypeError

我正在编写一个小程序来绘制 SVM 和朴素贝叶斯的学习曲线,用于具有交叉的数据集validation.This 是绘图函数的代码

import numpy as np
import matplotlib.pyplot as plt
from sklearn import cross_validation
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.learning_curve import learning_curve

def plot_learning_curves(X, y, nb=GaussianNB, svc=SVC(kernel='linear'), ylim=None, cv=None, n_jobs=1,
                     train_sizes=np.linspace(.1, 1.0, 5)):
    plt.figure()
    plt.title('Learning Curves with NB and SVM')
    if ylim is not None:
        plt.ylim(*ylim)

    train_sizes_nb, test_scores_nb = learning_curve(
        nb, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    test_scores_mean_nb = np.mean(test_scores_nb, axis=1)

    train_sizes_svc, test_scores_svc = learning_curve(
        svc, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    test_scores_mean_svc = np.mean(test_scores_svc, axis=1)

    plt.grind()

    plt.plot(train_sizes_nb, test_scores_mean_nb, 'o-', color="g",
             label="NB")
    plt.plot(train_sizes_svc, test_scores_mean_svc,'o',color="r",label="SVM")    

return plt

这是函数调用:

digits = load_digits()
X, y = digits.data, digits.target

cv = cross_validation.ShuffleSplit(digits.data.shape[0], n_iter=100,
                               test_size=0.2, random_state=0)
plot_learning_curves(X, y, ylim=(0.7, 1.01), cv=cv,n_jobs=1)
plt.show()

我不知道出了什么问题,但我收到了这个错误:

Traceback (most recent call last):
File "C:/Users/Gianmarco/PycharmProjects/Learning/plotLearningCurves.py", line 43, in <module>
plot_learning_curves(X, y, ylim=(0.7, 1.01), cv=cv,n_jobs=1)
File "C:/Users/Gianmarco/PycharmProjects/Learning/plotLearningCurves.py", line 19, in plot_learning_curves
nb, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
File "C:\Users\Gianmarco\Anaconda\lib\site-packages\sklearn\learning_curve.py", line 136, in learning_curve
for train, test in cv for n_train_samples in train_sizes_abs)
File "C:\Users\Gianmarco\Anaconda\lib\site-packages\sklearn\externals\joblib\parallel.py", line 652, in __call__
for function, args, kwargs in iterable:
File "C:\Users\Gianmarco\Anaconda\lib\site-packages\sklearn\learning_curve.py", line 136, in <genexpr>
for train, test in cv for n_train_samples in train_sizes_abs)
File "C:\Users\Gianmarco\Anaconda\lib\site-packages\sklearn\base.py", line 45, in clone
new_object_params = estimator.get_params(deep=False)
TypeError: unbound method get_params() must be called with GaussianNB instance as first argument (got nothing instead)

Process finished with exit code 1

我不明白 "TypeError: unbound method get_params() must be called with GaussianNB instance as first argument (got nothing instead)" 这行是什么意思。

可能的解决方案是什么?

解决方案非常简单。 这不是

nb=GaussianNB

但是

nb=GaussianNB()

TypeError: unbound method get_params() must be called with GaussianNB instance as first argument (got nothing instead)

此错误意味着方法 get_params() 收到了 None 而不是 GaussianNB 对象。

错误发生在 sklearn 模块内部的几个步骤中。因此,如果不使用调试工具进入代码并阅读 sklearn 源代码,就很难调试确切的原因。

如果您正在使用 ipython,%debug 魔术命令对于调查此类异常非常有用。

查看您的代码,问题可能出在您将 class GaussianNB 而不是 class 的实例传递给 sklearn.learning_curve.learning_curve()

docs learning_curve

Parameters: estimator : object type that implements the “fit” and “predict” methods An object of that type which is cloned for each validation.

我觉得这有歧义。但是在示例代码中,使用了 GaussianNB 实例,而不是类型。

除此之外,使用 mutables as default arguments 通常不是一个好主意。对象实例是可变的。它还使您的代码更难阅读和调试。

有了这么多可选的关键字参数,像这样的东西可读性会更高。

def plot_learning_curves(x, y, ylim=None, **kwargs):
    """ Plots learning curves with NB and SVM """
    nb = kwargs.get('nb', GaussianNB())
    svc = kwargs.get('svc', SVC(kernel='linear'))
    train_sizes = kwargs.get('train_sizes', np.linspace(.1, 1.0, 5))     

您可能根本不需要那些关键字参数。看起来您是从复制一些示例代码并添加您自己的东西开始的。最好先简化示例代码并确保您了解正在发生的事情。

def plot_learning_curves(x, y, ylim=None):
    nb = GaussianNB()
    svc = SVC(kernel='linear')
    train_sizes = np.linspace(.1, 1.0, 5)