web-dev-qa-db-ja.com

相互検証なしのScikit Learn GridSearchCV(教師なし学習)

相互検証なしでGridSearchCVを使用することは可能ですか?グリッド検索を介してKMeansクラスタリングのクラスター数を最適化しようとしているため、相互検証は必要ありません。

documentation も私を混乱させます。これは、fit()メソッドの下で、教師なし学習のオプションがあるためです(教師なし学習にNoneを使用するなど)。しかし、教師なし学習を行いたい場合は、相互検証なしで行う必要があり、相互検証を取り除くオプションはないようです。

17
DataMan

たくさん検索したところ、 このスレッド が見つかりました。以下を使用する場合、GridSearchCVの相互検証を取り除くことができるようです。

cv=[(slice(None), slice(None))]

私はこれをクロス検証なしの独自のコード化バージョンのグリッド検索に対してテストしましたが、両方の方法から同じ結果が得られました。他の人が同じ問題を抱えている場合に備えて、私は自分の質問にこの回答を投稿しています。

編集:コメントでjjrrの質問に答えるために、ここにユースケースの例があります:

from sklearn.metrics import silhouette_score as sc

def cv_silhouette_scorer(estimator, X):
    estimator.fit(X)
    cluster_labels = estimator.labels_
    num_labels = len(set(cluster_labels))
    num_samples = len(X.index)
    if num_labels == 1 or num_labels == num_samples:
        return -1
    else:
        return sc(X, cluster_labels)

cv = [(slice(None), slice(None))]
gs = GridSearchCV(estimator=sklearn.cluster.MeanShift(), param_grid=param_dict, 
                  scoring=cv_silhouette_scorer, cv=cv, n_jobs=-1)
gs.fit(df[cols_of_interest])
16
DataMan

まだ答えられていないようですので、お答えします。並列処理メソッドをforループで使用すると、multiprocessingモジュールを使用できます。

from multiprocessing.dummy import Pool
from sklearn.cluster import KMeans
import functools

kmeans = KMeans()

# define your custom function for passing into each thread
def find_cluster(n_clusters, kmeans, X):
    from sklearn.metrics import silhouette_score  # you want to import in the scorer in your function

    kmeans.set_params(n_clusters=n_clusters)  # set n_cluster
    labels = kmeans.fit_predict(X)  # fit & predict
    score = silhouette_score(X, labels)  # get the score

    return score

# Now's the parallel implementation
clusters = [3, 4, 5]
pool = Pool()
results = pool.map(functools.partial(find_cluster, kmeans=kmeans, X=X), clusters)
pool.close()
pool.join()

# print the results
print(results)  # will print a list of scores that corresponds to the clusters list
6
Scratch'N'Purr

私は最近 この答え に基づいて、次のカスタム相互検証ツールを発表しました。私はそれをGridSearchCVに渡しましたが、クロスバリデーションを適切に無効にしました:

import numpy as np

class DisabledCV:
    def __init__(self):
        self.n_splits = 1

    def split(self, X, y, groups=None):
        yield (np.arange(len(X)), np.arange(len(y)))

    def get_n_splits(self, X, y, groups=None):
        return self.n_splits

お役に立てれば幸いです。

5
MrD

Cv = ShuffleSplit(test_size = 0.20、n_splits = 1)をn_splits = 1で使用することは、このようなより良い解決策だと思います post を提案

4
ihebiheb