質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

2回答

2133閲覧

,python x-means: 多次元空間に応用したいがLinAlgError: singular matrixとなる

ak_miyamoto

総合スコア31

R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

1グッド

1クリップ

投稿2018/04/18 06:58

編集2018/04/18 08:07

初学者です。データフレームの3つ以上のカラムを用いて、多次元空間におけるクラスタリングを行いたいと考えています。

以下は2次元空間におけるxmeans適用の関数です。(出所)
これを3次元以上の多次元空間に応用すべく、修正したいと考えています。

import numpy as np from scipy import stats from sklearn.cluster import KMeans import matplotlib.pyplot as plt from IPython.display import display, HTML # Jupyter notebook用 import pandas as pd %matplotlib inline class XMeans: """ x-means法を行うクラス """ def __init__(self, k_init = 2, **k_means_args): """ k_init : The initial number of clusters applied to KMeans() """ self.k_init = k_init self.k_means_args = k_means_args def fit(self, X): """ x-means法を使ってデータXをクラスタリングする X : array-like or sparse matrix, shape=(n_samples, n_features) """ self.__clusters = [] clusters = self.Cluster.build(X, KMeans(self.k_init, **self.k_means_args).fit(X)) self.__recursively_split(clusters) self.labels_ = np.empty(X.shape[0], dtype = np.intp) for i, c in enumerate(self.__clusters): self.labels_[c.index] = i self.cluster_centers_ = np.array([c.center for c in self.__clusters]) self.cluster_log_likelihoods_ = np.array([c.log_likelihood() for c in self.__clusters]) self.cluster_sizes_ = np.array([c.size for c in self.__clusters]) return self def __recursively_split(self, clusters): """ 引数のclustersを再帰的に分割する clusters : list-like object, which contains instances of 'XMeans.Cluster' 'XMeans.Cluster'のインスタンスを含むリスト型オブジェクト """ for cluster in clusters: if cluster.size <= 3: self.__clusters.append(cluster) continue k_means = KMeans(2, **self.k_means_args).fit(cluster.data) c1, c2 = self.Cluster.build(cluster.data, k_means, cluster.index) beta = np.linalg.norm(c1.center - c2.center) / np.sqrt(np.linalg.det(c1.cov) + np.linalg.det(c2.cov)) alpha = 0.5 / stats.norm.cdf(beta) bic = -2 * (cluster.size * np.log(alpha) + c1.log_likelihood() + c2.log_likelihood()) + 2 * cluster.df * np.log(cluster.size) if bic < cluster.bic(): self.__recursively_split([c1, c2]) else: self.__clusters.append(cluster) class Cluster: """ k-means法によって生成されたクラスタに関する情報を持ち、尤度やBICの計算を行うクラス """ @classmethod def build(cls, X, k_means, index = None): if index is None: index = np.array(range(0, X.shape[0])) labels = range(0, k_means.get_params()["n_clusters"]) return tuple(cls(X, index, k_means, label) for label in labels) # index: Xの各行におけるサンプルが元データの何行目のものかを示すベクトル def __init__(self, X, index, k_means, label): self.data = X[k_means.labels_ == label] self.index = index[k_means.labels_ == label] self.size = self.data.shape[0] self.df = self.data.shape[1] * (self.data.shape[1] + 3) / 2 self.center = k_means.cluster_centers_[label] self.cov = np.cov(self.data.T) def log_likelihood(self): return sum(stats.multivariate_normal.logpdf(x, self.center, self.cov) for x in self.data) def bic(self): return -2 * self.log_likelihood() + self.df * np.log(self.size)

この関数に対して、あるデータフレームから取ってくる3×Nの行列を渡します。

data = pd.read_csv(r"file/to/path/data.csv") data = data.replace(np.inf,np.nan).dropna() if __name__ == "__main__": import matplotlib.pyplot as plt test_array = np.array([data["A"].tolist(),data["B"].tolist(),data["C"].tolist()], np.int32).T # クラスタリングの実行 x_means = XMeans(random_state = 1).fit(test_array)

しかし、以下のようなエラーとなります。逆行列を計算できないとあります。

--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-21-450bc8bb6146> in <module>() 11 12 # クラスタリングの実行 ---> 13 x_means = XMeans(random_state = 1).fit(test_array) 14 print(x_means.labels_) 15 print(x_means.cluster_centers_) <ipython-input-5-4709a667a908> in fit(self, X) 19 20 clusters = self.Cluster.build(X, KMeans(self.k_init, **self.k_means_args).fit(X)) ---> 21 self.__recursively_split(clusters) 22 23 self.labels_ = np.empty(X.shape[0], dtype = np.intp) <ipython-input-5-4709a667a908> in __recursively_split(self, clusters) 50 51 if bic < cluster.bic(): ---> 52 self.__recursively_split([c1, c2]) 53 else: 54 self.__clusters.append(cluster) <ipython-input-5-4709a667a908> in __recursively_split(self, clusters) 50 51 if bic < cluster.bic(): ---> 52 self.__recursively_split([c1, c2]) 53 else: 54 self.__clusters.append(cluster) #中略 このまとまりと同じエラーが何度も繰り返されます <ipython-input-5-4709a667a908> in __recursively_split(self, clusters) 47 beta = np.linalg.norm(c1.center - c2.center) / np.sqrt(np.linalg.det(c1.cov) + np.linalg.det(c2.cov)) 48 alpha = 0.5 / stats.norm.cdf(beta) ---> 49 bic = -2 * (cluster.size * np.log(alpha) + c1.log_likelihood() + c2.log_likelihood()) + 2 * cluster.df * np.log(cluster.size) 50 51 if bic < cluster.bic(): <ipython-input-5-4709a667a908> in log_likelihood(self) 77 78 def log_likelihood(self): ---> 79 return sum(stats.multivariate_normal.logpdf(x, self.center, self.cov) for x in self.data) 80 81 def bic(self): <ipython-input-5-4709a667a908> in <genexpr>(.0) 77 78 def log_likelihood(self): ---> 79 return sum(stats.multivariate_normal.logpdf(x, self.center, self.cov) for x in self.data) 80 81 def bic(self): /usr/local/lib/python3.6/dist-packages/scipy/stats/_multivariate.py in logpdf(self, x, mean, cov, allow_singular) 478 dim, mean, cov = self._process_parameters(None, mean, cov) 479 x = self._process_quantiles(x, dim) --> 480 psd = _PSD(cov, allow_singular=allow_singular) 481 out = self._logpdf(x, mean, psd.U, psd.log_pdet, psd.rank) 482 return _squeeze_output(out) /usr/local/lib/python3.6/dist-packages/scipy/stats/_multivariate.py in __init__(self, M, cond, rcond, lower, check_finite, allow_singular) 155 d = s[s > eps] 156 if len(d) < len(s) and not allow_singular: --> 157 raise np.linalg.LinAlgError('singular matrix') 158 s_pinv = _pinv_1d(s, eps) 159 U = np.multiply(u, np.sqrt(s_pinv)) LinAlgError: singular matrix

クラス修正が必要と存じていますが、直し方がわかりません。教えて下さると幸いです。よろしくお願いいたします。

OwLN👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

クラスター数を自動で決定する方法が必要ということなら、sklearnに実装済みのものから試したほうが簡単かもしれません。sklearnのcheat sheetによるとMeanShiftとVBGMMが提唱させています。
また、sklearnにはクラスター数を評価するsilhouette_scoreという関数があるので、これを使ってkmeansの結果を評価して、一番良さそうなものを選ぶという方法もあります

投稿2018/04/18 08:49

R.Shigemori

総合スコア3376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

x-meansが入っててそれなりにしっかり開発されてそうなライブラリを見つけたので、貼っておきます。参考にどうぞ。

annoviko/pyclustering: pyclustring is a Python, C++ data mining (clustering, oscillatory networks, neural networks, etc.) library.

投稿2018/04/18 07:31

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問