Python 什么';这里怎么了?意外引用现有实例而不是创建新实例
我希望能更自如地使用Python。我编写了一种迷你API,可以很容易地比较适合同一数据的不同统计模型,这样我就可以预先设置所有模型超参数,然后迭代不同的模型以适合它们 这就是我想做的本质:Python 什么';这里怎么了?意外引用现有实例而不是创建新实例,python,class,python-3.x,scikit-learn,instance,Python,Class,Python 3.x,Scikit Learn,Instance,我希望能更自如地使用Python。我编写了一种迷你API,可以很容易地比较适合同一数据的不同统计模型,这样我就可以预先设置所有模型超参数,然后迭代不同的模型以适合它们 这就是我想做的本质: 围绕Scikit学习构建包装类分类器,然后基于Scikit学习的一个内置估计器构建,例如 创建这些未安装的分类器的字典,以及要循环的不同参数字典 迭代两个字典,让每个未安装的分类器生成基础管道的新实例,使用其[Pipeline.fit][1]方法对其进行安装,并将新安装的管道保存在不同的字典中 然而,在每次迭
分类器
,然后基于Scikit学习的一个内置估计器构建,例如分类器的字典,以及要循环的不同参数字典
分类器
生成基础管道的新实例,使用其[Pipeline.fit][1]
方法对其进行安装,并将新安装的管道保存在不同的字典中Pipeline.fit
方法修改了管道(和基础估计器),因此先前迭代的拟合结果都会被最终迭代的拟合结果覆盖
问题是,我不知道这个“父实例”是在哪里创建的,以及它是如何被引用的
这个问题的一个可复制的例子的基本设置是(在这里复制粘贴有点太长)。我在最后添加了一份打印声明来说明这个问题
对不起,如果这是一个有点模糊,但我不容易描述它。希望从示例中可以清楚地看到问题。问题在于
结果['0']['rf']
和结果['1']['rf']
实际上是同一个对象。因此,当您在循环中安装管道时:
results = dict()
for k in features.keys():
results[k] = dict()
for m in classifiers.keys():
print(len(features[k]))
results[k][m] = classifiers[m].fit(features[k], 'species', iris)
您正在重新安装一条已安装的管道,丢失了以前的工作
要解决这个问题,您需要在每次安装时创建一个新的分类器实例。一种可能的方法是将分类器
字典从包含分类器
实例的字典更改为包含创建分类器所需的参数的字典:
classifiers = {
'rf': (RandomForestClassifier, n_estimators=100, oob_score=True, bootstrap=True),
'ab': (AdaBoostClassifier, n_estimators=50)
}
现在,在循环中,您应该使用一种称为“tuple unpacking”的Python习惯用法来解压参数,并为每个组合创建一个单独的分类器实例
for k in features:
results[k] = dict()
for m in classifiers:
print(len(features[k]))
classifier = Classifier(*classifiers[m])
results[k][m] = classifier.fit(features[k], 'species', iris)
请注意,要迭代字典中的键,只需为dct中的键编写:
,而不是为dct中的键编写。keys()
这就是我认为我正在做的事情。这是make_pipe
函数的作用,顺便说一句,我知道这是你的意思,但实际上是results['0']['rf'].steps[2][1]
和id(results['1']['rf'].steps[2][1]
相同:打印(id(results['0']['rf'].steps[2][1]),id(results['1']['rf 1'].steps[2][1]),sep=\n']
与打印(id(结果['0']['rf'])、id(结果['1']['rf'])、sep='\n')
@ssdecontrol啊,我看我看错了你的代码。我以为fit
是在修改分类器
,但实际上它调用了make_pipe
,它创建了一个新的管道对象,然后拟合该管道并返回它。所以你是对的。真正的问题是你正在创建一个RandomFores的实例tClassifier
或AdaBoostClassifier
当您初始化分类器时,每次使用make\u pipe
创建新管道时都会使用相同的实例。当然,您可以通过将创建分类器的代码从\uu init\uuuuu
移动到make\u pipe
来解决这个问题。是的这正是我所做的。谢谢!这是我在R中开发的功能,但还没有找到令人满意的解决方案。