在 scikit-learn 中创建一个添加集群标签的自定义转换器

Creating a custom transformer in scikit-learn that adds cluster labels

我正在 scikit-learn 中编写一个自定义转换器,它使用股票 KMeans 添加集群标签作为新列到 pandas 数据框。 自定义转换器应适合现有数据,然后通过添加具有索引名称 'Cluster' 的新列和 return 具有附加列的新数据帧来转换看不见的数据,而无需修改原始数据帧。 下面是我想出的代码:

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 的修改意见后查看下面的代码。 它现在完美运行。

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)

fit 方法必须始终 return self.

这里的问题是 fit_transform(X, y),继承自 TransformerMixin,只是 fit(X, y).transform(X);您的 fit 现在 return 是底层 KMeans 转换器,并且 那个 用于转换 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 转换器之后将其用作管道中的一个步骤,因为它们将 return numpy 数组。)