Skip to content

Instantly share code, notes, and snippets.

@2GMon
Last active December 17, 2015 07:49
Show Gist options
  • Save 2GMon/5575830 to your computer and use it in GitHub Desktop.
Save 2GMon/5575830 to your computer and use it in GitHub Desktop.
# パーセプトロン(2クラスかつ線形分類可能なデータのみ)
# coding: utf-8
require "pp"
# dimention次元の特徴に対する拡張重みベクトルを
# 乱数によって初期化
def initialize_weight(dimention)
weight = Array.new(dimention + 1)
(dimention + 1).times do |i|
weight[i] = rand()
end
weight
end
# 内積
def inner_product(left, right)
dimention = left.size
sum = 0;
dimention.times do |i|
sum = sum + left[i] * right[i]
end
sum
end
# 重みを更新する量
def update_value(rho, feature_vector)
value = Array.new(rho.size)
rho.size.times do |i|
value[i] = rho[i] * feature_vector[i]
end
value
end
# 識別関数 >= 0 ならばc(x) = 0
# 識別関数 < 0 ならばc(x) = 1
# として、重みを学習
def learn_perceptron(train_data, train_class, rho)
dimention = train_data[0].size
weight = initialize_weight(dimention)
rho = Array.new(dimention + 1, rho)
# 全ての訓練データを正しく識別できる重みが見つかるまで繰り返す
begin
is_updated = false
train_data.each_with_index do |t, i|
# 拡張特徴ベクトル
expand_feature = [1] + t
# 識別関数
discriminant = inner_product(weight, expand_feature)
# w = w + rho * x if c(x) = 0 && predict(x) == 1
# w = w - rho * x if c(x) = 1 && predict(x) == 0
if discriminant >= 0 && train_class[i] == 1
update_value = update_value(rho, expand_feature)
(dimention + 1).times do |i|
weight[i] = weight[i] - update_value[i]
end
is_updated = true
elsif discriminant < 0 && train_class[i] == 0
update_value = update_value(rho, expand_feature)
(dimention + 1).times do |i|
weight[i] = weight[i] + update_value[i]
end
is_updated = true
else
end
end
end while is_updated
weight
end
def classfier(data, weight)
dimention = data[0].size
data.each do |t|
expand_feature = [1] + t
discriminant = inner_product(weight, expand_feature)
if discriminant > 0
print "0, "
pp t
else
print "1, "
pp t
end
end
end
train_data = []
train_class = []
50.times do |i|
a = rand(-5.0..5.0)
b = rand(-5.0..5.0)
train_data << [a, b]
if b >= a
train_class << 0
else
train_class << 1
end
end
weight = learn_perceptron(train_data, train_class, 2.0)
test = []
20.times do |i|
test << [rand(-5..5), rand(-5..5)]
end
classfier(test, weight)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment