#b-navbar { height:0px; display:none; visibility:hidden; }

ページ

2014年8月4日月曜日

R言語:nnet:plot.nn:線が出ないときの対処方法

ニューラルネットワークの解析結果を視覚化するplot.nnは素晴らしい。



参考:http://hosho.ees.hokudai.ac.jp/~kubo/ce/NeuralNetwork.html
  • nnet() で作った neural network の例 (作図は久保先生の自作関数 plot.nn())
    http://hosho.ees.hokudai.ac.jp/~kubo/log/2007/img07/plot.nn.txt



ただ、線が出ないときがある。ニューロンだけ表示されて、あとが真っ白という感じ。



↓

11行目
col.w = function(w) ifelse(w > 0, "#ff400040", "#0000ff40"),

このカラーコードが8桁になっているためであろう。


そこで、
色をここから選んで持ってきて
http://html-color-codes.info/japanese/


↓

修正した例

col.w = function(w) ifelse(w > 0, "#0000FF", "#FF0040"),


↓


線が出た








keywords: R nnet grahical graph draw figures bug display line show 

余談ですが、線を太くしたいときは、10行目の w * 3 を w * 5 とか大きい数字に変えるとええで


2014年6月25日水曜日

OCR用のフォント、バーコード数字フォント




バーコードに使われている数字のフォントです。

有償版なら2万円ぐらい
http://www.flashbackj.com/ocr-b/
http://www.ricoh.co.jp/font/  など
エプソンLPユーザーなら
http://www.epson.jp/dl_soft/readme/7038.htm など


<無料>
非商用なら
≫Link:フォント http://ansuz.sooke.bc.ca/fonts-jp.php

海外のサイト(特に条件なし)OCR-A
http://sourceforge.net/projects/ocr-a-font/files/OCR-A/1.0/
OCR-AとB
http://sourceforge.jp/projects/tsukurimashou/releases/56948
上記のバックアップ
http://hp.vector.co.jp/authors/VA023120/data/OCRB.ttf
http://hp.vector.co.jp/authors/VA023120/data/OCRA.ttf

時系列データのシンプルな予測公式

近傍での1次式を仮定するなら、

  • \(f \left(n+1\right) =2f \left(n\right) -f \left(n-1\right) \)


で、次の値を近似できる。
今日と昨日の値から、明日のデータ値を予測する感じです。


2次式を仮定するなら、
今日と昨日とおとといの値から、明日を予測する感じになる。

  • \(f \left(n+1\right) =3f \left(n\right) -3f \left(n-1\right) +f \left(n-2\right) \)


上記で、次の値を近似できるものの・・・精度は下がる気がする。(結局一番最初の式がシンプルでベストなことがほとんどかもしれない)
。
以降、同様に順次漸化式を適用すれば


  • \(f \left(n+1\right) =4f \left(n\right) -6f \left(n-1\right) +4f \left(n-2\right) -f \left(n-3\right) \)
  • \(f \left(n+1\right) =5f \left(n\right) -10f \left(n-1\right) +10f \left(n-2\right) -5f \left(n-3\right) +f \left(n-4\right) \)
  • :

係数は二項定理っぽくなりますが、あまり実用性はなさそう。


超単純なモデルによる外挿なので
誤差が多いことや長期予測には向かないことに注意しつつ
サクッと1点外挿したいときにどうぞ。

離散データをもっと正確にするには、
回帰分析、重回帰分析、ARIMAなどを検討しましょう。



2014年6月22日日曜日

PHP:単回帰分析(係数と重決定R2値)(1次関数~n次関数)

まず1次関数での近似を行った。

出典:http://PolynomialRegression.drque.net/
最新版は上記から取得してください。


PolynomialRegression.php のソース
class PolynomialRegression
{
  private $xPowers;
  private $xyPowers;
  private $numberOfCoefficient;
  private $forcedValue;

  public function __construct( $numberOfCoefficient = 3 )
  {
    $this->numberOfCoefficient = $numberOfCoefficient;
    $this->reset();

  } // __construct

  public function reset()
  {
    $this->forcedValue = array();
    $this->xPowers = array();
    $this->xyPowers = array();

    $squares = ( $this->numberOfCoefficient - 1 ) * 2;

    // Initialize power arrays.
    for ( $index = 0; $index <= $squares; ++$index )
    {
      $this->xPowers[ $index ] = 0;
      $this->xyPowers[ $index ] = 0;
    }

  } // reset

  public function setDegree( $numberOfCoefficient )
  {
    $this->numberOfCoefficient = $numberOfCoefficient;

  } // setDegree

  public function setNumberOfCoefficient( $numberOfCoefficient )
  {
    $this->numberOfCoefficient = $numberOfCoefficient;

  } // setNumberOfCoefficient

  public function getNumberOfCoefficient( $numberOfCoefficient )
  {
    return $this->numberOfCoefficient;

  } // getnumberOfCoefficient

  public function setForcedCoefficient( $coefficient, $value )
  {
    $this->forcedValue[ $coefficient ] = $value;

  } // setForcedCoefficient

  public function getForcedCoefficient( $coefficient, $value )
  {
    $result = null;
    if ( isset( $this->forcedValue[ $coefficient ] ) )
      $result = $this->forcedValue[ $coefficient ];

    return $result;

  } // getForcedCoefficient

  public function addData( $x, $y )
  {
    $squares = ( $this->numberOfCoefficient - 1 ) * 2;

    // Remove the effect of the forced coefficient from this value.
    foreach ( $this->forcedValue as $coefficient => $value )
    {
      $sub = bcpow( $x, $coefficient );
      $sub = bcmul( $sub, $value );
      $y = bcsub( $y, $sub );
    }

    // Accumulate new data to power sums.
    for ( $index = 0; $index <= $squares; ++$index )
    {
      $this->xPowers[ $index ] =
        bcadd( $this->xPowers[ $index ], bcpow( $x, $index ) );

      $this->xyPowers[ $index ] =
        bcadd
        (
          $this->xyPowers[ $index ],
          bcmul( $y, bcpow( $x, $index ) )
        );
    }

  } // addData


  public function getCoefficients( $numberOfCoefficient = -1 )
  {
    // If no number of coefficients specified, use standard.
    if ( $numberOfCoefficient == -1 )
      $numberOfCoefficient = $this->numberOfCoefficient;

    $matrix = array();
    for ( $row = 0; $row < $numberOfCoefficient; ++$row )
    {
      $matrix[ $row ] = array();
      for ( $column = 0; $column < $numberOfCoefficient; ++$column )
        $matrix[ $row ][ $column ] =
          $this->xPowers[ $row + $column ];
    }

    // Create augmented matrix by adding X*Y powers.
    for ( $row = 0; $row < $numberOfCoefficient; ++$row )
      $matrix[ $row ][ $numberOfCoefficient ] = $this->xyPowers[ $row ];

    foreach ( $this->forcedValue as $coefficient => $value )
    {
      for ( $index = 0; $index < $numberOfCoefficient; ++$index )
      {
        $matrix[ $index ][ $coefficient ] = "0";
        $matrix[ $coefficient ][ $index ] = "0";
      }

      $matrix[ $coefficient ][ $coefficient ] = "1";
      $matrix[ $coefficient ][ $numberOfCoefficient ]      = $value;
    }

    // Determine number of rows in matrix.
    $rows = count( $matrix );

    // Initialize done.
    $isDone = array();
    for ( $column = 0; $column < $rows; ++$column )
      $isDone[ $column ] = false;

    $order = array();
    for ( $column = 0; $column < $rows; ++$column )
    {
      // Find a row to work with.
      // A row that has a term in this column, and has not yet been
      // reduced.
      $activeRow = 0;
      while ( ( ( 0 == $matrix[ $activeRow ][ $column ] )
             || ( $isDone[ $activeRow ] ) )
           && ( $activeRow < $rows ) )
      {
        ++$activeRow;
      }

      // Do we have a term in this row?
      if ( $activeRow < $rows )
      {
        // Remember the order.
        $order[ $column ] = $activeRow;

        // Normalize row--results in the first term being 1.
        $firstTerm = $matrix[ $activeRow ][ $column ];
        for ( $subColumn = $column; $subColumn <= $rows; ++$subColumn )
          $matrix[ $activeRow ][ $subColumn ] =
            bcdiv( $matrix[ $activeRow ][ $subColumn ], $firstTerm );

        // This row is finished.
        $isDone[ $activeRow ] = true;

        // Subtract the active row from all rows that are not finished.
        for ( $row = 0; $row < $rows; ++$row )
          if ( ( ! $isDone[ $row ] )
            && ( 0 != $matrix[ $row ][ $column ] ) )
          {
             // Get first term in row.
             $firstTerm = $matrix[ $row ][ $column ];
             for ( $subColumn = $column; $subColumn <= $rows; ++$subColumn )
             {
               $accumulator = bcmul( $firstTerm, $matrix[ $activeRow ][ $subColumn ] );
               $matrix[ $row ][ $subColumn ] =
                 bcsub( $matrix[ $row ][ $subColumn ], $accumulator );
             }
          }
      }
    }

    // Reset done.
    for ( $row = 0; $row < $rows; ++$row )
     $isDone[ $row ] = false;

    $coefficients = array();

    for ( $column = ( $rows - 1 ); $column >= 0; --$column )
    {
      // The active row is based on order.
      $activeRow = $order[ $column ];

      // The active row is now finished.
      $isDone[ $activeRow ] = true;

      // For all rows not finished...
      for ( $row = 0; $row < $rows; ++$row )
        if ( ! $isDone[ $row ] )
        {
          $firstTerm = $matrix[ $row ][ $column ];

          // Back substitution.
          for ( $subColumn = $column; $subColumn <= $rows; ++$subColumn )
          {
            $accumulator =
              bcmul( $firstTerm, $matrix[ $activeRow ][ $subColumn ] );
            $matrix[ $row ][ $subColumn ] =
              bcsub( $matrix[ $row ][ $subColumn ], $accumulator );
          }
        }

      // Save this coefficient for the return.
      $coefficients[ $column ] = $matrix[ $activeRow ][ $rows ];
    }

    // Coefficients are stored backward, so sort them.
    ksort( $coefficients );

    // Return the coefficients.
    return $coefficients;

  } // getCoefficients


  static public function interpolate( $coefficients, $x )
  {
    $numberOfCoefficient = count( $coefficients );

    $y = 0;
    for ( $coefficentIndex = 0; $coefficentIndex < $numberOfCoefficient; ++$coefficentIndex )
    {
      // y += coefficients[ coefficentIndex ] * x^coefficentIndex
      $y =
        bcadd
        (
          $y,
          bcmul
          (
            $coefficients[ $coefficentIndex ],
            bcpow( $x, $coefficentIndex )
          )
        );
    }

    return floatval( $y );

  } // interpolate

} // Class

テスト実行

データは、配列で指定する。 中の array(1,0),・・・が、array(Xの値,Yの値(目的変数))の順である。

require_once( 'inc_PolynomialRegression.php' ); //class読込

//テスト配列定義

 $data = array (
  array(1,0),
  array(2,4),
  array(3,3),
  array(4,2),
  array(5,5),
  array(6,3),
  array(7,8)
 );
 

//print_r ( $data ) ;

// Precision digits in BC math. 
  bcscale( 10 ); 

  // Start a regression class of order 2--linear regression. 
  $PolynomialRegression = new PolynomialRegression( 2 ); //変数の数、次数+1

  // Add all the data to the regression analysis. 
  foreach ( $data as $dataPoint ) 
    $PolynomialRegression->addData( $dataPoint[ 0 ], $dataPoint[ 1 ] ); 

  // Get coefficients for the polynomial. 
  $coefficients = $PolynomialRegression->getCoefficients(); 

  // 
  // Get average of Y-data. 
  // 
  $Y_Average = 0.0; 
  foreach ( $data as $dataPoint ) 
    $Y_Average += $dataPoint[ 1 ]; 

  $Y_Average /= count( $data ); 

  // 
  // Calculate R Squared. 
  // 

  $Y_MeanSum  = 0.0; 
  $Y_ErrorSum = 0.0; 
  foreach ( $data as $dataPoint ) 
  { 
    $x = $dataPoint[ 0 ]; 
    $y = $dataPoint[ 1 ]; 
    $error  = $y; 
    $error -= $PolynomialRegression->interpolate( $coefficients, $x ); 
    $Y_ErrorSum += $error * $error; 

    $error  = $y; 
    $error -= $Y_Average; 
    $Y_MeanSum += $error * $error; 
  } 

 $R_Squared = 1.0 - ( $Y_ErrorSum / $Y_MeanSum ); 
 
 
 
 
 

// Print slope and intercept of linear regression. 
// 四捨五入 4桁目

$para_a = round( $coefficients[ 1 ], 4 );
$para_b = round( $coefficients[ 0 ], 4 );
$para_R = round(  $R_Squared ,4 );



//結果出力
print "$para_a,$para_b,$para_R" ;





出力結果
0.8571,0.1429,0.5455

よって
y=0.8571 x + 0.1429
重決定 R2 は 0.5455


※X,Yの入れ替えに注意



エクセルとの比較:OK





二次関数で近似するときは

$PolynomialRegression = new PolynomialRegression( 3 );//2→3にする

$para_a = round( $coefficients[ 2 ], 4 );//増やす
$para_b = round( $coefficients[ 1 ], 4 );
$para_c = round( $coefficients[ 0 ], 4 );
$para_R = round(  $R_Squared ,4 );

出力:0.0952,0.0952,1.2857,0.5657
エクセルと比較:OK

/*=========================================================================*/ /* Name: PolynomialRegression.php */ /* Uses: Calculates and returns coefficients for polynomial regression. */ /* Date: 06/01/2009 */ /* Author: Andrew Que (http://www.DrQue.net/) */ /* Revisions: */ /* 0.8 - 06/01/2009- QUE - Creation. */ /* 0.9 - 06/14/2012- QUE - */ /* + Bug fix: removed notice causes by uninitialized variable. */ /* + Converted naming convention. */ /* + Fix spelling errors (or the ones I found). */ /* + Changed to row-echelon method for solving matrix which is much */ /* faster than the determinant method. */ /* 0.91 - 05/17/2013- QUE - */ /* = Changed name to Polynonial regression as this is more fitting to */ /* to the function. */ /* 0.92 - 12/28/2013- QUE - */ /* + Added forced offset. */ /* 1.00 - 12/29/2013 - QUE - */ /* + Forced offset changed to allow any term to be forced. */ /* Unit complete. Correlation coefficient (r-squared) has been */ /* implemented externally in the demos. */ /* 1.1 - 2014/05/05 - QUE - */ /* + 'interpolate' is now static as it does not need an instance to */ /* operate. Useful if coefficients have been calculated elsewhere. */ /* - Deprecated 'setDegree' function. This is the wrong terminology for */ /* what the function does. It actually sets the number of */ /* coefficients for the polynomial. The degree of the polynomial is */ /* the number of coefficients less one. Made the identical function */ /* 'setNumberOfCoefficient' to replace it. */ /* + Added getter functions for anything that has a set function. */ /* */ /* This project is maintained at: */ /* http://PolynomialRegression.drque.net/ */ /* */ /* ----------------------------------------------------------------------- */ /* */ /* Polynomial regression class. */ /* Copyright (C) 2009, 2012-2014 Andrew Que */ /* */ /* This program is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation, either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program. If not, see . */ /* */ /* ----------------------------------------------------------------------- */ /* */ /* (C) Copyright 2009, 2012-2014 */ /* Andrew Que */ /* > */ /*=========================================================================*/ /** * Polynomial regression. * *

* Used for calculating polynomial regression coefficients. Useful for * linear and non-linear regression, and polynomial curve fitting. * * @package PolynomialRegression * @author Andrew Que ({@link http://www.DrQue.net/}) * @link http://PolynomialRegression.drque.net/ Project home page. * @copyright Copyright (c) 2009, 2012-2014, Andrew Que * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version 1.1 */ /** * Used for calculating polynomial regression coefficients and interpolation using * those coefficients. Useful for linear and non-linear regression, and polynomial * curve fitting. * * Note: Requires BC math to be compiled into PHP. Higher-degree polynomials end up * with very large/small numbers, requiring an arbitrary precision arithmetic. Make sure * to set "bcscale" as coefficients will likely have decimal values. * * Quick example of using this unit to calculate linear regression (1st degree polynomial): * * * $regression = new PolynomialRegression( 2 ); * // ... * $regression->addData( $x, $y ); * // ... * $coefficients = $regression->getCoefficients(); * // ... * $y = $regression->interpolate( $coefficients, $x ); * * * * @package PolynomialRegression * @link http://PolynomialRegression.drque.net/ Project home page.

PHPで相関係数(行列)を計算する

参考:http://lib.stat.cmu.edu/multi/pca.c


/** 
* Creates a correlation matrix from a given data matrix.  
* 
* @see http://lib.stat.cmu.edu/multi/pca.c 
* 
* @author   Paul Meagher 
* @version  0.2 
* @modified Mar 23, 2008 
*/ 

   
     
class CorrelationMatrix { 
     
    private $eps    = 0.005; 

    public $nrows   = 0; 
    public $ncols   = 0;     
     
    public $means   = array(); 
    public $stddevs = array();     
    public $cormat  = array();     
     
  function CorrelationMatrix($data) { 
                 
    // num rows 
    $this->nrows = count($data);    
     
    // num cols 
    $this->ncols = count($data[0]);  
     
    // Determine mean of column vectors of input data matrix  
    for ($j=0; $j < $this->ncols; $j++) { 
      $this->means[$j] = 0.0; 
      for($i=0; $i < $this->nrows; $i++)  
        $this->means[$j] += $data[$i][$j]; 
      $this->means[$j] /= $this->nrows; 
    } 
           
    // Determine standard deviations of column vectors of data matrix.  
    for ($j=0; $j < $this->ncols; $j++) { 
      $this->stddevs[$j] = 0.0; 
      for ($i=0; $i < $this->nrows; $i++)  
        $this->stddevs[$j] += (($data[$i][$j]-$this->means[$j])*($data[$i][$j]-$this->means[$j])); 
      $this->stddevs[$j] /= $this->nrows; 
      $this->stddevs[$j] = sqrt($this->stddevs[$j]); 
      // The following in an inelegant but usual way to handle 
      // near-zero stddev values, which would cause a zero- 
      // divide error.  
      if ($this->stddevs[$j] <= $this->eps)  
        $this->stddevs[$j] = 1.0; 
    } 
     
    // Center and reduce the column vectors.  
    for ($i=0; $i < $this->nrows; $i++) { 
      for ($j=0; $j < $this->ncols; $j++) { 
        $data[$i][$j] -= $this->means[$j]; 
        $x = sqrt($this->nrows); 
        $x *= $this->stddevs[$j]; 
        $data[$i][$j] /= $x; 
      } 
    } 
   
    // Calculate the m * m correlation matrix.  
    for ($j1=0; $j1 < $this->ncols-1; $j1++) { 
      $this->cormat[$j1][$j1] = 1.0; 
      for ($j2=$j1+1; $j2 < $this->ncols; $j2++) { 
        $this->cormat[$j1][$j2] = 0.0; 
        for ($i=0; $i < $this->nrows; $i++) 
          $this->cormat[$j1][$j2] += ( $data[$i][$j1] * $data[$i][$j2]); 
        $this->cormat[$j2][$j1] = $this->cormat[$j1][$j2]; 
      } 
    } 
     
    $this->cormat[$this->ncols-1][$this->ncols-1] = 1.0; 
     
  } 
   
  function printMeans() {   
    printf("Column Means: 
"); 
    for ($j=0; $j < $this->ncols; $j++)   
      printf("%7.2f", $this->means[$j]);   
    printf("
");   
  } 

  function printStdDevs() { 
    printf("Column Standard Deviations: 
"); 
    for ($j=0; $j < $this->ncols; $j++)  
      printf("%7.2f", $this->stddevs[$j]);  
    printf("
"); 
  } 

  function printCorMat() { 
    printf("Correlation Matrix: 
"); 
    for ($i=0; $i < $this->ncols; $i++) {      
      for ($j=0; $j < $this->ncols; $j++)  
        //echo $this->cormat[$i][$j]." "; 
        printf("%7.4f", $this->cormat[$i][$j]);  
      printf("
"); 
    } 
  } 
       
} 


動作デモ

include "CorrelationMatrix.php";
 
$data[0] = array(1, 2, 3);
$data[1] = array(2, 3, 4);
$data[2] = array(3, 4, 5);
$data[3] = array(4, 6, 8);
$data[4] = array(5, 8, 10);
 
$cm = new CorrelationMatrix($data);
print "
";
$cm->printMeans();
print "
"; $cm->printStdDevs(); print "
"; $cm->printCorMat(); print "
"; print_r ( $cm->cormat ) ; print "
";

デモ出力


Column Means: 
   3.00   4.60   6.00

Column Standard Deviations: 
   1.41   2.15   2.61
Correlation Matrix: 
 1.0000 0.9848 0.9762
 0.9848 1.0000 0.9970
 0.9762 0.9970 1.0000

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 0.98479824644792
            [2] => 0.97618706018395
        )

    [1] => Array
        (
            [0] => 0.98479824644792
            [1] => 1
            [2] => 0.9969527608178
        )

    [2] => Array
        (
            [0] => 0.97618706018395
            [1] => 0.9969527608178
            [2] => 1
        )

)


10行目の、$cm = new CorrelationMatrix($data); の配列に
結果数値が入って帰ってくる。