python - 用于python回归聚类的库?

标签 python numpy scipy scikit-learn

最近我发现了一篇关于回归聚类算法的有趣文章,它可以同时处理回归和聚类任务:

http://ncss.wpengine.netdna-cdn.com/wp-content/themes/ncss/pdf/Procedures/NCSS/Regression_Clustering.pdf

我只是好奇 - 是否有一些技术(库)可以通过 Python 来完成?谢谢!

最佳答案

据我所知,Spath的算法没有用Python实现。

但是您可以在 scikit-learn 中使用高斯混合模型复制其结果:

import numpy as np
from sklearn.mixture import GaussianMixture 
import matplotlib.pyplot as plt
# generate random data
np.random.seed(1)
n = 10
x1 = np.random.uniform(0, 20, size=n)
x2 = np.random.uniform(0, 20, size=n)
y1 = x1 + np.random.normal(size=n)
y2 = 15 - x2 + np.random.normal(size=n)
x = np.concatenate([x1, x2])
y = np.concatenate([y1, y2])
data = np.vstack([x, y]).T
model = GaussianMixture (n_components=2).fit(data)
plt.scatter(x, y, c=model.predict(data))
plt.show()

此代码生成图片,类似于论文中的图片:

enter image description here

GMM 与 Spath 算法不同,因为前者试图最大化所有数据(X 和 y)的预测精度,而后者仅最大化 y 的 R^2。在我看来,对于大多数实际问题,您更喜欢 GMM。

如果您仍然想要 Spath 算法,可以使用这样的类来完成,实现 EM 算法的一个版本:

import numpy as np
from sklearn.linear_model import Ridge
from sklearn.base import RegressorMixin, BaseEstimator, clone

class ClusteredRegressor(RegressorMixin, BaseEstimator):
    def __init__(self, n_components=2, base=Ridge(), random_state=1, max_iter=100, tol=1e-10, verbose=False):
        self.n_components = n_components
        self.base = base
        self.random_state = random_state
        self.max_iter = max_iter
        self.tol = tol
        self.verbose = verbose

    def fit(self, X, y):
        np.random.seed(self.random_state)
        self.estimators_ = [clone(self.base) for i in range(self.n_components)]
        # initialize cluster responsibilities randomly
        self.resp_ = np.random.uniform(size=(X.shape[0], self.n_components))
        self.resp_ /= self.resp_.sum(axis=1, keepdims=True)
        for it in range(self.max_iter):
            old_resp = self.resp_.copy()
            # Estimate sample-weithted regressions
            errors = np.empty(shape=self.resp_.shape)
            for i, est in enumerate(self.estimators_):
                est.fit(X, y, sample_weight=self.resp_[:, i])
                errors[:, i] = y - est.predict(X)
            self.mse_ = np.sum(self.resp_ * errors**2) / X.shape[0]
            if self.verbose:
                print(self.mse_)
            # Recalculate responsibilities
            self.resp_ = np.exp(-errors**2 / self.mse_)
            self.resp_ /= self.resp_.sum(axis=1, keepdims=True)
            # stop if change in responsibilites is small
            delta = np.abs(self.resp_ - old_resp).mean()
            if delta < self.tol:
                break
        self.n_iter_ = it
        return self

    def predict(self, X):
        """ Calculate a matrix of conditional predictions """
        return np.vstack([est.predict(X) for est in self.estimators_]).T

    def predict_proba(self, X, y):
        """ Estimate cluster probabilities of labeled data """
        predictions = self.predict(X)
        errors = np.empty(shape=self.resp_.shape)
        for i, est in enumerate(self.estimators_):
            errors[:, i] = y - est.predict(X)
        resp_ = np.exp(-errors**2 / self.mse_)
        resp_ /= resp_.sum(axis=1, keepdims=True)
        return resp_

这段代码类似于 Spath 算法,唯一的区别是它对每个观察使用每个集群的软“责任”,而不是硬集群分配(这样更容易优化)。可以看到生成的聚类分配与 GMM 类似:

model = ClusteredRegressor()
model.fit(x[:, np.newaxis], y)
labels = np.argmax(model.resp_, axis=1)
plt.scatter(x, y, c=labels)
plt.show()

enter image description here

不幸的是,该模型不能应用于预测测试数据,因为它的输出取决于数据标签 (y)。但是,如果您进一步修改我的代码,您可以预测以 X 为条件的聚类概率。在这种情况下,该模型可用于预测。

关于python - 用于python回归聚类的库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39208679/

相关文章:

python - 在 python 中将列表写入文本文件的最佳方法?

python - 如何将 SQLite3 数据库导入 Python Jupyter Notebook?

python - 如何将 int32 类型的 4D numpy 数组转换为 tfrecords?

python - 恢复向量的排列

python - 从网页链接直接加载图像到 NumPy 数组 (Python)

python - numpy数组eval表示公式

python - 加快计算不同列的数量

python - Numpy 逐元素比较

python - 查找 scipy.sparse 矩阵中的第一个非零列

numpy - 涉及 Scitools、NumPy 和 SciPy 的推荐设置