Last active
December 17, 2015 07:49
-
-
Save 2GMon/5575830 to your computer and use it in GitHub Desktop.
# パーセプトロン(2クラスかつ線形分類可能なデータのみ)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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