R のニューラルネットパッケージの利用

Python の pyper モジュールにより、R を利用できる。R のパスを通しておく。

In [1]:
import csv
import random
from matplotlib import pyplot as plt
%matplotlib inline

import pyper

モジュールのインポート。

In [2]:
reader = csv.reader(open('data.csv', 'r'))

next(reader)
data = [r for r in reader]

n = len(data)

min1 = min([float(d[1]) for d in data])
max1 = max([float(d[1]) for d in data])
min2 = min([float(d[2]) for d in data])
max2 = max([float(d[2]) for d in data])

input_data_a = []
input_data_b = []
output_data = []

for i in xrange(n):
    a = (float(data[i][1]) - min1)/(max1 - min1)
    b = (float(data[i][2]) - min2)/(max2 - min2)
    input_data_a.append(a)
    input_data_b.append(b)
    output_data.append(float(data[i][0]))

データの用意。

In [3]:
R = pyper.R()

R('library(nnet)')

R['a'] = input_data_a
R['b'] = input_data_b
R['r'] = output_data

R('input <- cbind(a, b)')
R('output <- as.matrix(r)')

print R('''
set.seed(1)
learn <- nnet(input, output, size=3, rang=0.1, maxit=2000, abstol=1e-4, reltol=1e-8)
result <- predict(learn, input)
''')
result = R['result']
try({

+ set.seed(1)

+ learn <- nnet(input, output, size=3, rang=0.1, maxit=2000, abstol=1e-4, reltol=1e-8)

+ result <- predict(learn, input)

+ })

# weights:  13

initial  value 50.215160 

iter  10 value 25.777767

iter  20 value 14.096988

iter  30 value 13.889653

iter  40 value 13.871819

iter  50 value 13.854247

iter  60 value 13.803369

iter  70 value 13.757349

iter  80 value 13.586169

iter  90 value 13.407570

iter 100 value 13.303368

iter 110 value 12.943464

iter 120 value 12.628125

iter 130 value 12.490595

iter 140 value 12.489820

iter 150 value 12.489188

iter 160 value 12.487289

iter 170 value 12.484179

iter 180 value 12.481235

iter 190 value 12.478328

iter 200 value 12.478286

iter 210 value 12.474977

iter 220 value 10.246867

iter 230 value 9.208970

iter 240 value 8.888419

iter 250 value 8.845831

iter 260 value 8.810029

iter 270 value 8.636624

iter 280 value 8.626812

iter 290 value 8.613981

iter 300 value 8.426608

iter 310 value 8.397529

iter 320 value 8.366464

iter 330 value 8.355397

iter 340 value 8.348733

iter 350 value 8.267425

iter 360 value 8.240701

iter 370 value 8.222612

iter 380 value 8.222154

iter 390 value 8.213362

iter 400 value 8.157622

iter 410 value 8.092069

iter 420 value 8.083021

iter 430 value 8.061233

iter 440 value 8.058471

iter 450 value 8.031218

iter 460 value 7.877708

iter 470 value 7.665097

iter 480 value 7.375306

iter 490 value 6.789829

iter 500 value 6.518929

iter 510 value 5.937787

iter 520 value 5.801265

iter 530 value 5.742900

iter 540 value 5.662508

iter 550 value 5.264907

iter 560 value 4.339047

iter 570 value 2.010191

iter 580 value 2.000381

iter 590 value 2.000288

iter 600 value 2.000125

iter 610 value 2.000027

final  value 2.000007 

converged


R のコードの実行。nnet によりデータの学習を行う。

In [4]:
count = 0
for i in xrange(n):
    if result[i] >= 0.5:
        v = 1
    else:
        v = 0
    
    if output_data[i] == v:
        count += 1

print 'n = ', n, 'right = ', count, '(%.2f %%)' % (100.*count/n)
n =  200 right =  198 (99.00 %)

成績。PyBrain より成績がよい上に処理も速い。

In [5]:
data0_a = [input_data_a[i]*(max1 - min1) + min1 for i in xrange(n) if result[i] < 0.5]
data0_b = [input_data_b[i]*(max2 - min2) + min2 for i in xrange(n) if result[i] < 0.5]
data1_a = [input_data_a[i]*(max1 - min1) + min1 for i in xrange(n) if result[i] >= 0.5]
data1_b = [input_data_b[i]*(max2 - min2) + min2 for i in xrange(n) if result[i] >= 0.5]

plt.plot(data0_a, data0_b, '+')
plt.plot(data1_a, data1_b, 'r+');

学習結果。

In [6]:
random.seed(2)

data0_a = []
data0_b = []
data1_a = []
data1_b = []

data_a = []
data_b = []

for i in xrange(n):
    a = random.random()
    b = random.random()
    
    data_a.append(a)
    data_b.append(b)

R['a'] = data_a
R['b'] = data_b

R('''
input <- cbind(a, b)
result <- predict(learn, input)
''')
data_r = R['result']

data0_a = [data_a[i]*(max1 - min1) + min1 for i in xrange(n) if data_r[i] < 0.5]
data0_b = [data_b[i]*(max2 - min2) + min2 for i in xrange(n) if data_r[i] < 0.5]
data1_a = [data_a[i]*(max1 - min1) + min1 for i in xrange(n) if data_r[i] >= 0.5]
data1_b = [data_b[i]*(max2 - min2) + min2 for i in xrange(n) if data_r[i] >= 0.5]

plt.plot(data0_a, data0_b, '+')
plt.plot(data1_a, data1_b, 'r+');

ランダムに選んだ点における予測結果。