python - 为什么我的 sklearn 自定义转换器在 ColumnTransformer 中使用时不保存属性?

标签 python machine-learning scikit-learn

我正在使用 scikit-learn 中的加州住房数据集。我想设计两个二元特征:“旧金山 10 公里以内”和“洛杉矶 10 公里以内”。我创建了一个自定义转换器,它自己可以正常工作,但是当我将它放入 ColumnTransformer 时抛出 TypeError .这是代码:

from math import radians
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer
from sklearn.metrics.pairwise import haversine_distances
from sklearn.datasets import fetch_california_housing
import numpy as np
import pandas as pd

# Import data into DataFrame
data = fetch_california_housing()
X = pd.DataFrame(data['data'], columns=data['feature_names'])
y = data['target']

# Custom transformer for 'Latitude' and 'Longitude' cols
class NearCity(BaseEstimator, TransformerMixin):
    def __init__(self, distance=10):
        self.la = (34.05, -118.24)
        self.sf = (37.77, -122.41)
        self.dis = distance

    def calc_dist(self, coords_1, coords_2):
        coords_1 = [radians(_) for _ in coords_1]
        coords_2 = [radians(_) for _ in coords_2]
        result = haversine_distances([coords_1, coords_2])[0,-1]
        return result * 6_371

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        dist_to_sf = np.apply_along_axis(self.calc_dist, 1, X, coords_2=self.sf)
        dist_to_sf = (dist_to_sf < self.dis).astype(int)

        dist_to_la = np.apply_along_axis(self.calc_dist, 1, X, coords_2=self.la)
        dist_to_la = (dist_to_la < self.dis).astype(int)

        X_trans = np.column_stack((X, dist_to_sf, dist_to_la))
        return X_trans

ct = ColumnTransformer([('near_city', NearCity(), ['Latitude', 'Longitude'])],
                       remainder='passthrough')

ct.fit_transform(X)
#> /Users/.../anaconda3/envs/data3/lib/python3.7/site-packages/sklearn/base.py:197: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.
#>   FutureWarning)
#> Traceback (most recent call last):
#> <ipython-input-13-603f6cd4afd3> in transform(self, X)
#>      17     def transform(self, X):
#>      18         dist_to_sf = np.apply_along_axis(self.calc_dist, 1, X, coords_2=self.sf)
#> ---> 19         dist_to_sf = (dist_to_sf < self.dis).astype(int)
#>      20 
#>      21         dist_to_la = np.apply_along_axis(self.calc_dist, 1, X, coords_2=self.la)
#> TypeError: '<' not supported between instances of 'float' and 'NoneType'

reprexpy package 创建于 2020-04-23

问题是 self.dis 属性不会持续存在。如果我自己实例化转换器,没问题:self.dis = distance = 10。但在 ColumnTransformer 中,它最终为 NoneType。奇怪的是,如果我只是在 self.dis = 10 中进行硬编码,它就可以工作。

人们认为发生了什么事?

Session info --------------------------------------------------------------------
Platform: Darwin-18.7.0-x86_64-i386-64bit (64-bit)
Python: 3.7
Date: 2020-04-23
Packages ------------------------------------------------------------------------
numpy==1.18.1
pandas==1.0.1
reprexpy==0.3.0
scikit-learn==0.22.1

最佳答案

原来问题出在sklearn.base .

deep_items = value.get_params().items()

get_params() 函数查看 init 参数以找出类参数是什么,然后假设它们与内部变量名称相同。

所以我可以通过将我的 init 方法更改为来解决这个问题:

def __init__(self, distance=10):
    self.la = (34.05, -118.24)
    self.sf = (37.77, -122.41)
    self.distance = distance # <-- give same name

非常感谢我的一位同事解决了这个问题!

关于python - 为什么我的 sklearn 自定义转换器在 ColumnTransformer 中使用时不保存属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61394346/

相关文章:

python - 如何在启动时在 Python IDLE 中预加载 Python 模块?

python - Python中的最小曲面解决方案

python - TfidfVectorizer 和 SelectPercentile 返回什么?

python - 生物变异或真正受影响的基因。

machine-learning - 为训练实例分配特定权重的策略

scikit-learn - 如何将 `sklearn.neighbors.KDTree` 对象转储到 hdf5?

python - 如何更改数据框中保存的数据的格式?

python - 如何在 Python3 文件中打印 __repr__? (不在 shell 中)

machine-learning - LSTM 批处理与时间步

python - 值错误 : unknown is not supported in sklearn. RFECV