Range Object - Excel 97

Matrix
Mathematics
Range
Cells
Rows
Columns
Excel
VBA
Tips to calculate Matrix in Range Objects using Excel VBA.
本文を折り畳む 本文を開く

はじめに

Range Object数学 の行列計算に利用するサンプルです。 Excel のセル計算機能の中に含まれる行列機能は、データの入力や更新に慣れが必要なため、ユーザーに提供するワークシートでは使いにくい機能です。しかし、VBA と Range Object を組み合わせて、この行列機能を、もっと簡単に利用できます。
このサンプルでは、セルに通常の入力を行った状態で、行列演算に利用します。したがって、単純な Value や Formula プロパティを使います。一方、Excel の行列入力機能そのものを VBA から利用したいなら、 FormulaArray プロパティを用います。 FormulaArray については、ここでは説明しません。

実例

回帰分析

  1. 共分散行列と回帰分析

    回帰分析
     ABCDEFGH
    1 x y y.理論値   データ数 X平均 Y平均 相関係数
    2 10.70062 28.50423 28.55283   20 8.090876 20.70548 0.999589
    3 10.85146 28.78956 29.00641          
    4 10.77595 28.73815 28.77935   共分散行列      
    5 12.1984 33.20097 33.05659   10.89166 32.75062    
    6 8.918948 23.19617 23.19545   32.75063 98.56029    
    7 9.669958 25.12148 25.45369          
    8 3.824069 7.665826 7.875423   相関行列      
    9 12.76625 35.01392 34.76406   1 0.999589    
    10 12.24241 33.68759 33.18892   0.999589 1    
    11 3.497153 7.117502 6.892404          
    12 3.512967 6.789227 6.939953   回帰係数A 回帰係数B 決定係数  
    13 7.163585 17.55715 17.91716   3.006946 -3.623346 0.999179  
    14 6.593862 16.47019 16.20404          
    15 5.63871 13.20293 13.33195   別解      
    16 9.593617 24.93599 25.22414   3.006946 -3.623346    
    17 3.149212 6.27938 5.846164          
    18 11.8024 31.58255 31.86582          
    19 4.556542 9.724923 10.07793          
    20 8.223249 21.23062 21.10352          
    21 6.138166 15.30122 14.83379          
    Function Initialize50() As Range
    ' 行列計算を行う。
    ' 統計計算用サンプルデータ作成。
    ' y=3x-3.5 のまわりに分布するランダムなデータ群を作る。
        Dim rRet As Range
        Dim x As Single, y As Single
        Dim I As Long, data(19, 1) As Single
        Set rRet = Sheet2.Range("A2:B21")
        rRet.EntireRow.Clear
        rRet.Rows(0).EntireRow.Clear
        Randomize
        For I = 0 To 19
            x = 10 * Rnd() + 3
            y = 3 * x - 4 + Rnd()
            data(I, 0) = x
            data(I, 1) = y
        Next I
        rRet.Rows(0) = Array("x", "y")
        rRet = data
        Set Initialize50 = rRet
    End Function
    
    Sub Range51()
    ' 行列計算を行う。
    ' 共分散行列と回帰分析。
        Dim A As Range, B As Range, C As Range, D As Range
        Dim E As Range, F As Range
        Dim x As Range, y As Range, z As Range
        Dim P(3) As Double, Q(1, 1) As Double, R(2) As Double
        ' 初期化
        Set A = Initialize50
        Set B = Sheet2.Range("E2:H2")
        Set C = Sheet2.Range("E5:F6")
        Set D = Sheet2.Range("E9:F10")
        Set E = Sheet2.Range("E13:G13")
        Set F = Sheet2.Range("E16:F16")
        ' データ領域の特定
        Set x = A.Columns(1)
        Set y = A.Columns(2)
        Set z = A.Columns(3)
        ' 平均等の計算
        P(0) = Application.Count(x)
        P(1) = Application.Average(x)
        P(2) = Application.Average(y)
        P(3) = Application.Correl(x, y)
        B = P
        B.Rows(0) = Array("データ数", "X平均", "Y平均", "相関係数")
        ' 共分散行列の計算
        Q(0, 0) = Application.Var(x)
        Q(1, 1) = Application.Var(y)
        Q(0, 1) = P(0) / (P(0) - 1) * Application.Covar(x, y)
        Q(1, 0) = Q(0, 1)
        C = Q
        C.Rows(0).Cells(1) = "共分散行列"
        ' 回帰係数の計算
        R(0) = Q(0, 1) / Q(0, 0)
        R(1) = P(2) - R(0) * P(1)
        R(2) = R(0) ^ 2 * Q(0, 0) / Q(1, 1)
        E = R
        E.Rows(0) = Array("回帰係数A", "回帰係数B", "決定係数")
        z.FormulaR1C1 = "=RC[-2]*(" & R(0) & ")+(" & R(1) & ")"
        z.Rows(0) = "y.理論値"
        ' 相関行列の計算
        Q(0, 1) = Q(0, 1) / Sqr(Q(0, 0)) / Sqr(Q(1, 1))
        Q(1, 0) = Q(0, 1)
        Q(0, 0) = 1
        Q(1, 1) = 1
        D = Q
        D.Rows(0).Cells(1) = "相関行列"
        
        ' Excel 機能による回帰係数の計算(別解)
        F = Application.LinEst(y, x)
        F.Rows(0).Cells(1) = "別解"
    End Sub
    
    上記のコードを実行すると、ワークシート Sheet2 に、乱数を基に計算したサンプルデータを作成して、実際にそのデータに対する回帰分析を行います。その様子は最初に掲げたとおりです。
  2. サンプルデータに関する説明

    データジェネレーター Function Initialize50 は、(x,y) という2次元データを20組生成します。データの生成には乱数を利用し、x は 3 から 13 の間の乱数、y は 0 から 1 の間の乱数 e を利用して、y=3x-4+e として計算します。この結果、適当な測定誤差を伴った、 y=3x-3.5 のまわりに分布するデータ群が得られます。この関数は、Range A2:B21 に、データを書き出し、同時にその Range Object を返します。
  3. 基本的な統計値の計算

    Excel のセル関数には、標準で、多くの統計関数が用意されています。VBA を利用する場合でも、これらの Range Object を対象とした統計関数は有益です。
    合計     = Application.Sum(x)
    データ数 = Application.Count(x)
    平均     = Application.Average(x)
    二乗和   = Application.SumSq(x)
    内積     = Application.SumProduct(x, y)
    相関係数 = Application.Correl(x, y)
    
  4. 共分散行列

    共分散行列も、Excel の標準関数で簡単に求めることができます。ただし、自分の扱う資料が、標本なのか母集団なのか、という区別を明確に持つ必要があります。
    標本の分散     = Application.Var(x)
    母集団の分散   = Application.VarP(x)
    母集団の共分散 = Application.CoVar(x, y)
    
    実務面で必要になる統計計算の多くは、標本集団を対象にしたものです。したがって、分散は素直に Var を用いればいいのですが、共分散については、母集団とみなした場合の数値を求めてから、変換する必要があります。このサンプルコードでは、標本集団としての共分散行列を計算するために、その対角成分を Var 関数で求め、非対角成分を Covar 関数に n/(n-1) を乗じて求めています。
  5. 相関行列

    共分散行列が求められれば、標準化するだけで、相関行列が得られます。
  6. 回帰分析

    (x, y) データ群が、 y = A x + B に従っていると仮定して、係数 A および B を求める手法を、回帰分析といいます。係数 A B は、共分散行列 V と平均 S から簡単に求められます。
    係数 A      = Vxy / Vx      = [xとyの共分散] ÷ [xの分散]
    係数 B      = Sy - A * Sx   = [yの平均] − A × [xの平均]
    決定係数 R2 = A^2 * Vx / Vy = [理論値yの分散] ÷ [実測値yの分散]
    
  7. 別解

    Excel には、回帰分析を直接行えるセル関数が用意されています。これを利用すれば、回帰係数を一発で計算できます。引数として、目的変数の Range y を先に、説明変数の Range x を次に指定します。計算結果は係数の配列として返されます。
    ( 係数 A , 係数 B ) = Application.LinEst(y, x)
    
    係数が欲しいだけなら、これが最も簡単な方法です。ただし、ここでは数学的な興味を重視して、共分散行列から解を計算する手順を示しました。

重回帰分析

  1. 共分散行列と重回帰分析

    重回帰分析
     ABCDEFGHIJKL
    1 x y z z.理論値   データ数 X平均 Y平均 Z平均 相関係数xy 相関係数yz 相関係数zx
    2 8.240333 -1.96253 6.403214 6.594325   20 7.297687 -1.37755 6.463584 0.021048 0.717694 0.710525
    3 6.012874 -3.90847 -4.15435 -3.94466                
    4 5.047682 -0.23197 4.974654 5.380912   共分散行列       相関行列    
    5 6.610178 -2.98983 0.346189 0.101145   6.605293 0.093526 13.80296   1 0.021048 0.710525
    6 3.985169 -3.29598 -6.38485 -6.21105   0.093526 2.989103 9.379013   0.021048 1 0.717694
    7 7.301219 -0.59324 9.116891 8.881565   13.80296 9.379013 57.13398   0.710525 0.717694 1
    8 4.991375 0.075976 6.322593 6.212226                
    9 7.947371 -2.16976 5.324396 5.357918   回帰係数A 回帰係数B 回帰係数C 理論値の分散 決定係数    
    10 10.32483 -0.81996 14.64453 14.37149   2.046161 3.073713 -4.23446 57.07148 0.998906    
    11 7.646456 1.120483 14.91891 14.85547                
    12 12.23491 -2.23091 14.09716 13.94297   説明変数の共分散行列   その逆行列   目的変数の共分散 係数の解 FG*K
    13 12.61849 -1.65173 16.3227 16.50808   6.605293 0.093526 0.151461 -0.00474 13.80296 2.046161 13.80296
    14 5.046794 -0.82568 3.576429 3.554183   0.093526 2.989103 -0.00474 0.334697 9.379013 3.073713 9.379013
    15 4.911745 0.032566 6.329481 5.915863                
    16 5.097991 -4.06149 -5.92613 -6.28701   別解            
    17 9.11659 -0.45862 12.77727 13.00989   3.073713 2.046161 -4.23446        
    18 4.463925 0.492336 6.5096 6.412752                
    19 6.774698 -4.66748 -4.94279 -4.71882                
    20 6.910084 1.15484 12.99503 13.45433                
    21 10.67103 -0.55961 16.02074 15.88011                
    Function Initialize50b() As Range
    ' 行列計算を行う。
    ' 統計計算用サンプルデータ作成。
    ' z=2x+3y-4 のまわりに分布するランダムなデータ群を作る。
        Dim rRet As Range
        Dim x As Single, y As Single, z As Single
        Dim I As Long, data(19, 2) As Single
        Set rRet = Sheet2.Range("A2:C21")
        rRet.EntireRow.Clear
        rRet.Rows(0).EntireRow.Clear
        Randomize
        For I = 0 To 19
            x = 10 * Rnd() + 3
            y = 7 * Rnd() - 5
            z = 2 * x + 3 * y - 4 + Rnd() - 0.5
            data(I, 0) = x
            data(I, 1) = y
            data(I, 2) = z
        Next I
        rRet.Rows(0) = Array("x", "y", "z")
        rRet = data
        Set Initialize50b = rRet
    End Function
    
    Sub Range52()
    ' 行列計算を行う。
    ' 共分散行列と重回帰分析。
        Dim A As Range, B As Range, C As Range, D As Range
        Dim E As Range, F As Range, G As Range, H As Range
        Dim I As Range, J As Range, K As Range
        Dim x As Range, y As Range, z As Range, z2 As Range
        Dim P(6) As Double, Q(2, 2) As Double
        Dim nQ As Double
        ' 初期化
        Set A = Initialize50b
        Set B = Sheet2.Range("F2:L2")
        Set C = Sheet2.Range("F5:H7")
        Set D = Sheet2.Range("J5:L7")
        Set E = Sheet2.Range("F10:J10")
        Set F = Sheet2.Range("F13:G14")
        Set G = Sheet2.Range("H13:I14")
        Set H = Sheet2.Range("J13:J14")
        Set I = Sheet2.Range("K13:K14")
        Set J = Sheet2.Range("L13:L14")
        Set K = Sheet2.Range("F17:H17")
        ' データ領域の特定
        Set x = A.Columns(1)
        Set y = A.Columns(2)
        Set z = A.Columns(3)
        Set z2 = A.Columns(4)
        ' 平均等の計算
        P(0) = Application.Count(x)
        P(1) = Application.Average(x)
        P(2) = Application.Average(y)
        P(3) = Application.Average(z)
        P(4) = Application.Correl(x, y)
        P(5) = Application.Correl(y, z)
        P(6) = Application.Correl(z, x)
        B = P
        B.Rows(0) = Array("データ数", "X平均", "Y平均", "Z平均", _
            "相関係数xy", "相関係数yz", "相関係数zx")
        ' 共分散行列の計算
        nQ = P(0) / (P(0) - 1)
        Q(0, 0) = Application.Var(x)
        Q(1, 1) = Application.Var(y)
        Q(2, 2) = Application.Var(z)
        Q(0, 1) = nQ * Application.Covar(x, y)
        Q(1, 2) = nQ * Application.Covar(y, z)
        Q(0, 2) = nQ * Application.Covar(z, x)
        Q(1, 0) = Q(0, 1)
        Q(2, 1) = Q(1, 2)
        Q(2, 0) = Q(0, 2)
        C = Q
        C.Rows(0).Cells(1) = "共分散行列"
        ' 回帰係数の計算
        F = Q
        F.Rows(0).Cells(1) = "説明変数の共分散行列"
        G = Application.MInverse(F)
        G.Rows(0).Cells(1) = "その逆行列"
        H(1) = Q(0, 2)
        H(2) = Q(1, 2)
        H.Rows(0).Cells(1) = "目的変数の共分散"
        I = Application.MMult(G, H)
        I.Rows(0).Cells(1) = "係数の解"
        E = Application.Transpose(I)
        J = Application.MMult(F, I)
        J.Rows(0).Cells(1) = "FG*K"
        E(3) = P(3) - I(1) * P(1) - I(2) * P(2)
        E(4) = Application.MMult(E.Range("A1:B1"), J)
        E(5) = E(4) / Q(2, 2)
        E.Rows(0) = Array("回帰係数A", "回帰係数B", "回帰係数C", _
            "理論値の分散", "決定係数")
        z2.FormulaR1C1 = "=RC[-3]*(" & E(1) & ")+RC[-2]*(" & _
            E(2) & ")+(" & E(3) & ")"
        z2.Rows(0) = "z.理論値"
        ' 相関行列の計算
        Q(0, 1) = Q(0, 1) / Sqr(Q(0, 0)) / Sqr(Q(1, 1))
        Q(1, 2) = Q(1, 2) / Sqr(Q(1, 1)) / Sqr(Q(2, 2))
        Q(0, 2) = Q(0, 2) / Sqr(Q(0, 0)) / Sqr(Q(2, 2))
        Q(1, 0) = Q(0, 1)
        Q(2, 1) = Q(1, 2)
        Q(2, 0) = Q(0, 2)
        Q(0, 0) = 1
        Q(1, 1) = 1
        Q(2, 2) = 1
        D = Q
        D.Rows(0).Cells(1) = "相関行列"
    
        ' Excel 機能による回帰係数の計算(別解)
        K = Application.LinEst(z, Union(x, y))
        K.Rows(0).Cells(1) = "別解"
    End Sub
    
    上記のコードを実行すると、ワークシート Sheet2 に、乱数を基に計算したサンプルデータを作成して、実際にそのデータに対する重回帰分析を行います。その様子は最初に掲げたとおりです。
  2. サンプルデータに関する説明

    データジェネレーター Function Initialize50b は、(x,y,z) という3次元データを20組生成します。データの生成には乱数を利用し、x は 3 から 13 の間の乱数、y は -5 から 2 の間の乱数、z は -0.5 から 0.5 の間の乱数 e を利用して、z=2x+3y-4+e として計算します。この結果、適当な測定誤差を伴った、 z=2x+3y-4 のまわりに分布するデータ群が得られます。この関数は、Range A2:C21 に、データを書き出し、同時にその Range Object を返します。
  3. 統計値と共分散行列

    基本的な統計値を計算する方法や、共分散行列・相関行列の求め方は、先の回帰分析の時とまったく同じです。今回は変数が 3 つになるため、そこから選ぶ 2 つの変数の組すべてに対して共分散等を計算するため、共分散行列は 3行 3列になります。
  4. 重回帰分析

    (x, y, z) データ群が、 z = A x + B y + C に従っていると仮定して、係数 A および B C を求める手法を、重回帰分析といいます。係数 A B C は、共分散行列 V と平均 S から簡単に求められます。
    [説明変数の共分散行列]・[回帰係数を成分とする行列] 
       = [目的変数と各説明変数の共分散を成分とする行列]
    すなわち
    [xとyの共分散行列]・[係数A B の行列] = [zとxの共分散, zとyの共分散, の行列]
    これは A B についての連立方程式です。
    逆行列を利用して、解 A B を求められます。
    A B が求まれば、平均を利用して、次のように C を求めます。
    係数 C = Sz - A * Sx - B * Sy 
       = [zの平均] − A × [xの平均] − B × [yの平均]
    最後に、理論値の分散を計算して、決定係数を求めます。
    [理論値zの分散] = [係数A B の行列]T・[xとyの共分散行列]・[係数A B の行列]
    決定係数 R2 = [理論値zの分散] ÷ [実測値zの分散]
    
  5. 別解

    Excel には、重回帰分析を直接行えるセル関数が用意されています。これを利用すれば、回帰係数を一発で計算できます。引数として、目的変数の Range z を先に、説明変数 x y の Range を次に指定します。計算結果は係数の配列として返されます。
    ( 係数 B , 係数 A , 係数 C ) = Application.LinEst(z, xy )
    
    係数が欲しいだけなら、これが最も簡単な方法です。ただし、ここでは数学的な興味を重視して、共分散行列から解を計算する手順を示しました。

Download a Sample Code

上記の解説で用いたサンプルコードは、以下のリンクからダウンロードできます。テキストファイルとして用意しているので、保存して Excel の Visual Basic Editor にインポートしてください。
  1. Save a program source (sample-vbaxlra1-1.bas) on your local disk.
  2. Start Microsoft Excel with a blank(new) book.
  3. Open the Visual Basic Editor. (Tool/Macro/Visual Basic Editor)
  4. Import the downloaded program source. (File/Import Files)

History

2002/3/24
URL移転
2001/3/25
sample-vbaxlra1-1.bas revised
2001/3/25
初版
本文を折り畳む back to home index of VBA index of Mathematics