次のクラスを検討してください。
class SquareErrorDistance(object):
def __init__(self, dataSample):
variance = var(list(dataSample))
if variance == 0:
self._norm = 1.0
else:
self._norm = 1.0 / (2 * variance)
def __call__(self, u, v): # u and v are floats
return (u - v) ** 2 * self._norm
これを使用して、ベクトルの 2 つの要素間の距離を計算します。基本的に、この距離測定を使用するベクトルの次元ごとに、そのクラスの 1 つのインスタンスを作成します (他の距離測定を使用する次元があります)。プロファイリングにより、__call__
このクラスの関数が私の knn 実装の実行時間の 90% を占めていることが明らかになりました (誰が考えたでしょう)。これを高速化する純粋な Python の方法はないと思いますが、C で実装した場合はどうでしょうか。
上記の式を使用してランダム値の距離を計算する単純な C プログラムを実行すると、Python より桁違いに高速になります。そこで、 ctypesを使用して、計算を行う C 関数を呼び出してみましたが、結果のコードがはるかに遅くなるため、パラメータと戻り値の変換にコストがかかるようです。
もちろん、knn 全体を C で実装してそれを呼び出すこともできますが、問題は、前述したように、ベクトルの一部の次元に対して異なる距離関数を使用しており、これらを C に変換するのは手間がかかりすぎることです。
では、私の代替手段は何ですか?Python C-APIを使用して C 関数を作成すると、オーバーヘッドがなくなりますか? この計算を高速化する他の方法はありますか?