【问题标题】:Creating a custom transformer in scikit-learn that adds cluster labels在 scikit-learn 中创建一个添加集群标签的自定义转换器
【发布时间】:2021-09-06 01:48:09
【问题描述】:

我正在 scikit-learn 中编写一个自定义转换器,它使用股票 KMeans 将集群标签作为新列添加到 pandas 数据帧。 自定义转换器应该适合现有数据,然后通过添加索引名称为“Cluster”的新列来转换看不见的数据,并在不修改原始数据帧的情况下返回带有附加列的新数据帧。 以下是我想出的代码:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.cluster import KMeans

class AddClustersFeature(BaseEstimator, TransformerMixin):
    def __init__(self, clusters = 10): 
        self.clusters = clusters
        self.model = KMeans(n_clusters = self.clusters)
           
    def fit(self, X):
        self.X=X
        self.model.fit (self.X)
        return self.model
       
    def transform(self, X):
        self.X=X
        X_=X.copy() # avoiding modification of the original df
        
        X_['Clusters'] = self.model.transform(self.X_).labels_
        
        return X_

cluster_enc_tr_data = AddClustersFeature().fit_transform(enc_tr_data)
cluster_enc_tr_data

不幸的是,代码确实可以正常工作。结果是一个数据框,其中簇号作为列索引,行号和未知的先前值。 任何帮助或提示将不胜感激。

6 月 21 日第 23 次更新 v2: 请在实施 Ben 修改后的 cmets 后查看下面的代码。 现在完美运行。

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.cluster import KMeans

class AddClustersFeature(BaseEstimator, TransformerMixin):
    def __init__(self, clusters = 10): 
        self.clusters = clusters
        
           
    def fit(self, X):
        self.X=X
        self.model = KMeans(n_clusters = self.clusters)
        self.model.fit (self.X)
        return self
       
    def transform(self, X):
        self.X=X
        X_=X.copy() # avoiding modification of the original df
        X_['Clusters'] = self.model.predict(X_)
        return X_

cluster_enc_tr_data = AddClustersFeature().fit_transform(enc_tr_data)

【问题讨论】:

    标签: python pandas machine-learning scikit-learn k-means


    【解决方案1】:

    fit 方法必须始终返回 self

    这里的问题是fit_transform(X, y),继承自TransformerMixin,只是fit(X, y).transform(X);你的fit 现在返回底层的KMeans 转换器,that 用于转换X 而不是你的 transform

    还有一些注意事项:

    1. KMeans.transform 给出了集群距离矩阵,但您需要集群标签。请改用predict。并删除labels_,所以只需X_['Clusters'] = self.model.predict(X_)。)

    2. __init__ 应该只设置出现在其签名中的属性,以便克隆工作(例如超参数搜索所必需的)。您可以在fit 时间定义self.model

    3. transform 中,您使用self.X_,但它从未被定义;我猜你的意思只是X_。也没有真正的理由在合适的时候保存Xself.X 真的不需要吗?

    4. 这仅适用于数据帧;这对您来说可能不是问题,但请记住。 (在内置 sklearn 转换器之后,您不能将其用作管道中的一个步骤,因为它们将返回 numpy 数组。)

    【讨论】:

    • 感谢本的回答。我不确定我是否清楚你的意思请记住我对定制变压器很陌生。请在实施您的 cmets 后查看上面有问题的代码编辑。不幸的是,它仍然无法正常工作。顺便说一句,我还毕业于伊利诺伊大学厄巴纳-香槟分校。
    • 我尝试在管道中的回归器之前使用此自定义转换器添加集群功能,但这并没有提高 cv 分数。您 Ben 或其他任何人是否认为它可以工作,或者这会导致模型过度拟合,这就是为什么 cv 分数没有提高的原因?
    • 对于 stats.SE 或 datascience.SE 来说这是一个更好的问题,但我认为它非常依赖数据。集群当然是从您的其他自变量中获得的,因此从这个意义上说,您正在建立冗余;高容量模型可能会自行构建该信息并且不会有太多好处,而低容量模型可能会从集群转换中受益。对于接下来的步骤,我将看看集群化的独立性有多好。您是否对集群标签进行一次性编码?什么回归量?
    • 我正在为 Ames Housing 数据集创建一个堆叠集合。我正在评估几个回归量 SVR、岭、内核岭、线性回归、xgboost、catboost 和 HuberRegressor。在使用创建的一些附加特征和一个热编码集群标签对标准化数据集进行聚类之后,cv 分数有一些改进,但并不令人惊叹。
    猜你喜欢
    • 2020-02-04
    • 2021-10-25
    • 2020-02-03
    • 2015-04-05
    • 2020-02-05
    • 2019-02-06
    • 2020-06-22
    • 2020-06-24
    • 2016-07-24
    相关资源
    最近更新 更多