Hatena::ブログ(Diary)

はすけるとぱいそん

2011-11-08

k近傍法(k-NN法)を今度はPythonで。

一つ前のエントリーの例があまりに酷かったので、
今回はとんでもなく単純な例だけれどまともな例で、k近傍法をPythonで書きました。
距離による重みはガウス関数でやりました。

ワインの価格を年代から決めます。
集合知プログラミングの本の例をさらにカンタンにしました。

#coding:shiftjis

import math 

# ガウス関数(距離が近い時1〜距離が遠い時0近く)までを重みとして取れる。
def gaussian(x,sigma=10000):
	return math.e**(-x**2/(2*sigma**2))

# ワインの[(年代,価格)]。5年おきのデータのリスト。
wine_data = [(1950,5000),
			 (1955,8000),
			 (1960,10000),
			 (1965,20000),
			 (1970,45000),
			 (1975,50000),
			 (1980,42000),
			 (1985,38000),
			 (1990,21000),
			 (1995,10000),
			 (2000,5000)
			 ]

# ガウス関数による重み付けK近傍法なう。
def k_nn(data,year,k):
	dlist = [] #指定したyearに距離が近い順のワインリスト。
	sum = 0 #価格*距離のガウス関数重みの総和。
	w = 0 #重みの総和
	
	for d in data:
		dlist += [( (year-d[0])**2 , d[1] )] #(距離,価格)のタプルをdlistに入れていく。
	dlist.sort() #距離でソートする。
	
	for d in dlist[0:k]: #距離が短い上位k個をひとつずつ。
		sum += d[1]*gaussian(d[0]) #価格に距離のガウス関数重みを。
		w += gaussian(d[0]) #距離のガウス関数重みの総和。
	return sum/w

# 1968年のワイン価格を、近い年代3つのワイン価格の平均として予測。
print(k_nn(wine_data,1968,3))

なんか小学生レベルのコードですがとりあえずうp。

集合知プログラミング

集合知プログラミング