2013년 1월 21일 월요일

Subtractive Clustering (in Excel VBA)

※ Elliott Pattern Helper Add In
  • Download Add In for Excel 2007 
  • Download Add In for Excel 2003 

  Data clustering techniques are used in conjunction with radial basis function networks or fuzzy modeling primarily to determine initial locations for radial basis functions or fuzzy if-then rules.

  They are validated on the basis of the following assumptions:
  1. Similar inputs to the target system to be modeled should produce similar outputs.
  2. These similar input-output pairs are bundled into clusters in the training data set.
  One of the most common methods for data clustering is subtractive clustering proposed by S. L. Chiu.


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
'' Subtractive Clustering (by S. L. Chiu)
'' in Fuzzy Time Series beta1.
'' Authored by KyungSeog Kim, Copyright ⓒ 2012, all rights reserved.
'' May be redistributed for free,
'' but may not be sold without the author's explicit permission.
''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Private Const DEFAULT_RA = 0.5
Private Const DEFAULT_SF = 1.25
Private Const DEFAULT_AR = 0.5
Private Const DEFAULT_RR = 0.15

Private n As Integer        'the number of vectors
Private d As Integer        'the dimension of vectors
Private p() As Double       'potentials of all vectors
Private cp_ra As Double     'SC param Radius
Private cp_sf As Double     'SC param Squash Factor
Private cp_rr As Double     'SC param Reject Ratio
Private cp_ar As Double     'SC param Accept Ratio
Private ddots() As Double   'For performance, ddots are stored as they are computed

Function slc_sc(v, cp, b)   'v: 2-dim array, cp: SC params, b: normalized flag
    Dim c_idx() As Integer  'id's of clusters found
    Dim n_c As Integer      'number of clusters found
    Dim p1 As Double
    Dim skip As Boolean     'skip flag
    Dim idx_k As Variant
    Debug.Print "[MSubtractiveClustering.slc_sc]s, " & Timer
    On Error GoTo EH_slc_sc:
   
    n = UBound(v, 1)
    d = UBound(v, 2)
    If Not init_sc_params(cp) Then _
        Err.Raise 9401, "MSubtractiveClustering.slc_sc", "Init SC params failed"
   
    ReDim c_idx(1 To n)
    If Not b Then v = shrink2D(v, 0, 1)
    Call init_potentials(v)
    skip = False
    n_c = 1
    p1 = WorksheetFunction.Max(p)
    c_idx(n_c) = WorksheetFunction.Match(p1, p, 0)
   
    Do While n_c < n
        If Not skip Then
            Call potential(v, c_idx(n_c), n_c + 1)
            n_c = n_c + 1
        Else
            skip = False
        End If
       
        p_k = WorksheetFunction.Max(p)
        idx_k = WorksheetFunction.Match(p_k, p, 0)
       
        If p_k > cp_ar * p1 Then
            c_idx(n_c) = idx_k
        ElseIf p_k < cp_rr * p1 Then
            n_c = n_c - 1
            GoTo SkipLoop:
        Else
            Dim d_min As Double, distances() As Double
            d_min = 0
            ReDim distances(1 To n_c - 1)
            For i = 1 To n_c - 1
                ddot = 0
               
                If idx_k < c_idx(i) Then
                    ddot = ddots(idx_k, c_idx(i))
                Else
                    ddot = ddots(c_idx(i), idx_k)
                End If
               
                distances(i) = ddot
            Next i
           
            d_min = WorksheetFunction.Min(distances) ^ (1 / 2)
            If (d_min / cp_ra + p_k / p1) >= 1 Then
                c_idx(n_c) = idx_k
            Else
                p(idx_k) = 0
                skip = True
            End If
        End If
    Loop
SkipLoop:
   
    ReDim Preserve c_idx(1 To n_c)
    slc_sc = c_idx
    Debug.Print "[MSubtractiveClustering.slc_sc]e, " & Timer
    Exit Function
   
EH_slc_sc:
    MsgBox "Error(" & Err.Number & ") " & Err.Description & " [.slc_sc]"
    Err.Raise Err.Number, "slc_sc", Err.Description
End Function

Private Function init_sc_params(cp) As Boolean
    init_sc_params = False
    On Error GoTo EH_init_sc_params:
   
    lb = LBound(cp)
    If UBound(cp) - lb <> 3 Then _
        Err.Raise 9402, "init_sc_params", "Invalid SC params"
   
    cp_ra = cp(lb)
    cp_sf = cp(lb + 1)
    cp_ar = cp(lb + 2)
    cp_rr = cp(lb + 3)
    If cp_ra < 0 Or cp_ra > 1 Then cp_ra = DEFAULT_RA
    If cp_sf < 1 Then cp_sf = DEFAULT_SF
    If cp_ar < 0 Or cp_ar > 1 Then cp_ar = DEFAULT_AR
    If cp_rr < 0 Or cp_rr > 1 Then cp_rr = DEFAULT_RR
   
    init_sc_params = True
    Exit Function
   
EH_init_sc_params:
    MsgBox "Error(" & Err.Number & ") " & Err.Description & " [init_sc_params]"
End Function

Private Function init_potentials(v)
    On Error GoTo EH_init_potentials:
    Debug.Print "[MSubtractiveClustering.init_potentials]s, " & Timer
    ReDim p(1 To n)
    ReDim ddots(1 To n, 1 To n)
   
    For i = 1 To n
        Dim value As Double
       
        value = 0
        For k = 1 To i - 1
            ddot = ddots(k, i)
            value = value + Exp(-1 * (4 / cp_ra ^ 2) * ddot)
        Next k
        For k = i To n
            ddot = 0
            For j = 1 To d
                ddot = ddot + (v(i, j) - v(k, j)) ^ 2
            Next j
           
            ddots(i, k) = ddot
            value = value + Exp(-1 * (4 / cp_ra ^ 2) * ddot)
        Next k
       
        p(i) = value
    Next i
   
    Debug.Print "[MSubtractiveClustering.init_potentials]e, " & Timer
    Exit Function
   
EH_init_potentials:
    MsgBox "Error(" & Err.Number & ") " & Err.Description & " [init_potentials]"
    Err.Raise 9403, "init_potentials", Err.Description
End Function

Private Function potential(v, k, c)
    On Error GoTo EH_potential:
    Debug.Print "[MSubtractiveClustering.potential]s, " & Timer
    p_k = p(k) 'potential of vector at k
   
    For i = 1 To n
        p_i = p(i) 'potential of vector at i
        ddot = 0
       
        If i < k Then
            ddot = ddots(i, k)
        Else
            ddot = ddots(k, i)
        End If
       
        p_i = p_i - p_k * Exp(-ddot * 4 / ((cp_sf ^ c * cp_ra) ^ 2))
        p(i) = p_i
    Next i
   
    Debug.Print "[MSubtractiveClustering.potential]e, " & Timer
    Exit Function
   
EH_potential:
    MsgBox "Error(" & Err.Number & ") " & Err.Description & " [potential]"
    Err.Raise 9403, "potential", Err.Description
End Function

Public Function shrink2D(v, l, u) 'normalize in all dimension, i.e., making hypercube
    Dim c() As Double
    On Error GoTo EH_shrink2D:
    Debug.Print "[MSubtractiveClustering.shrink2D]s, " & Timer
   
    lb = LBound(v, 1)
    ub = UBound(v, 1)
    ReDim c(lb To ub)
    For j = LBound(v, 2) To UBound(v, 2)
       
        If j = LBound(v, 2) Then
            For i = lb To ub
                c(i) = v(i, j)
            Next i
        End If
        c = shrink(c, l, u)
       
        If j < UBound(v, 2) Then
            For i = lb To ub
                v(i, j) = c(i)
                c(i) = v(i, j + 1)
            Next i
        Else
            For i = lb To ub
                v(i, j) = c(i)
            Next i
        End If
    Next j
   
    shrink2D = v
    Debug.Print "[MSubtractiveClustering.shrink2D]e, " & Timer
    Exit Function
   
EH_shrink2D:
    MsgBox "Error(" & Err.Number & ") " & Err.Description & " [shrink2D]"
    Err.Raise 9403, "shrink2D", Err.Description
End Function


Public Function shrink(y As Variant, d1, d2)
    Dim v() As Double
    lb = LBound(y)
    ub = UBound(y)
    ReDim v(lb To ub)
    mn = WorksheetFunction.Min(y)
    mx = WorksheetFunction.Max(y)
   
    For k = lb To ub
        v(k) = d1 + (d2 - d1) * ((y(k) - mn) / (mx - mn))
    Next k
   
    shrink = v
End Function


댓글 없음:

댓글 쓰기