質問: "precomputed" ``` ここもどういったものになっているのかわかりません。具体的には@propertyと"precomputed"です pythonはおろかプログラミングも完全素人なのでstep by stepで例など込みで教えてもらえると助かります。よろしくお願いします。 以下にリンクを貼っておきます。 sklearnのリンク
回答: はじめに 分からない関数や書き方があったとき、まずは Python や周辺ライブラリのドキュメントやマニュアルを確認するようにしましょう。基本的にドキュメントを読めば使い方が載っています。「Python callable」や「callable site:docs.python.org/ja」などでウェブ検索するのも有効です。Python 2.7 のドキュメントに限定したい場合は「callable site:docs.python.org/ja/2.7」とできます。 `**params` について 変数 `params` は `sklearn.metrics.pairwise.pairwise_kernels` の引数として使われているので、まずはこの関数のドキュメントを確認してみます。scikit-learn 0.19.1 のドキュメントには、この関数の説明が以下のように書かれています。 > > sklearn.metrics.pairwise.**pairwise_kernels**(*X*, *Y*=*None*, *metric*=*’linear’*, *filter_params*=*False*, *n_jobs*=*1*, ***kwds*) > > > 特に今回注目すべきは `**kwds` という引数です。この引数はどういう意味でしょうか? 「Python double asterisk」 で検索すると "What does ** (double star/asterisk) and * (star/asterisk) do for parameters?" という投稿が見つかります。投稿を元にドキュメントを見ると Python 2.7 ドキュメント 4.7.2 キーワード引数 には以下のように書かれています。 > > 仮引数の最後に `**name` の形式のものがあると、それまでの仮引数に対応したものを除くすべてのキーワード引数が入った辞書 (マッピング型 --- dict を参照) を受け取ります。 > > > つまり `**kwds` とは、`Y`, `metric`, `filter_params`, `n_jobs` 以外のキーワード引数を一手に引き受ける辞書型の引数なわけです。実際、`kwds` は keywords の略でしょう。 さてここで `pairwise_kernels` のドキュメントに戻ると、引数の説明欄には以下のように書かれています。 > > ****kwds** : optional keyword parameters > > Any further parameters are passed directly to the kernel function. > > > したがって `**kwds` は、`pairwise_kernels` で使うカーネル関数に渡すキーワード引数として用意されていることが分かります。用いるカーネル関数によって必要なキーワード引数が違うので、`**kwds` として用意することで対応したということでしょう。 ところで質問文中のコードにおいて `**params` は `**kwds` として渡す引数なのでした。実際 `params` は辞書として以下のように初期化されています。 ``` params = {"gamma": self.gamma, "degree": self.degree, "coef0": self.coef0} ``` `gamma` や `degree` 等のキーワードが具体的にどのように使われるのかは scikit-learn のこちらのドキュメントに詳しいです。というわけで `**params` とは、カーネルで使用するパラメータ設定のための任意引数なのです。 `callable` について まず `callable` とはどういう関数なのでしょうか。これは Python の組み込み関数で、与えられたオブジェクトが呼び出し可能かを調べるものです。詳細なドキュメントはこちらにあります。 質問文のプログラムでは変数 `self.kernel` が呼び出し可能かどうかを調べています。これは `pairwise_kernel` のキーワード引数 `metric` へ「文字列」または「呼び出し可能オブジェクト」を渡せることに対応しようとしています。`metric` へ `'rbf'` や `'linear'` などの文字列を渡すと scikit-learn 側に用意されたカーネル関数が使われますが、ユーザー側で適当なカーネル関数 `f` を定義して `metric=f` のように渡すこともできる、ということです。 つまり、`self.kernel` が呼び出し可能かどうかで `params` の内容を変えるために組み込み関数 `callable` を使っている、ということです。 `"precomputed"` について ところで `self.kernel` に文字列を渡す場合、`"precomputed"` という文字列を渡すと特別に扱われます。具体的には `pairwise_kernel` のドキュメントに以下のように書かれています。 > > **metric** : string, or callable > > (前略) If metric is “precomputed”, X is assumed to be a kernel matrix. (後略) > > > `@property` について Python において `@` (アットマーク) から始まる識別子が関数定義の前に置かれているものは、デコレータです。`@property` もデコレータの一種です。「python at property」で検索すると "How does the @property decorator work?" がヒットします。`@property` について完全に解説すると長いので省きますが、要するにこのクラスのインスタンスが `kkm` だとすると `kkm._pairwise` が使えるようになります。 `@property` の詳しい解説は、Python 2.7 における組み込み関数のドキュメントにある `property` の解説をご覧ください。