⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form03.frm

📁 本文档包括了对软件中用到的多元统计分析中判别分析与聚类分析的主要方法(包括距离判别分析,费希尔判别分析,贝叶斯判别分析,逐步判别分析及聚类分析)原理及在本软件中使用的基本方法与设计流程图进行了详尽的阐
💻 FRM
📖 第 1 页 / 共 2 页
字号:
    Next j, i
End If
End Sub

Function Determinant(m1() As Double) As Double
'****************************************************************************************
'  功能  :  求矩阵的行列式
'  参数  :  m1待求矩阵
'  返回值:  Determinant返回m矩阵的行列式值,为Double类型
'  说明  :  该函数运行后,矩阵m中的数据被改变
'****************************************************************************************
Dim i, j, kk, row, order, r, c As Long
Dim Pivot, Pivot2 As Single
Dim temp() As Double
Determinant = 1
row = UBound(m1, 1)
If UBound(m1, 2) <> row Then MsgBox "这不是方阵": Exit Function
ReDim temp(1 To row)
For i = 1 To row
    Pivot = 0
    For j = i To row
        For kk = i To row
            If Abs(m1(kk, j)) > Pivot Then
                Pivot = Abs(m1(kk, j))
                r = kk:       c = j
            End If
        Next kk
    Next j
    If Pivot = 0 Then Determinant = 0: Exit Function
    If r <> i Then
        order = order + 1
        For j = 1 To row
            temp(j) = m1(i, j)
            m1(i, j) = m1(r, j)
            m1(r, j) = temp(j)
        Next j
    End If
    If c <> i Then
        order = order + 1
        For j = 1 To row
            temp(j) = m1(j, i)
            m1(j, i) = m1(j, c)
            m1(j, c) = temp(j)
        Next j
    End If
    Pivot = m1(i, i)
    Determinant = Determinant * Pivot
    For j = i + 1 To row
        Pivot2 = m1(j, i)
        If Pivot2 <> 0 Then
            For kk = 1 To row
                m1(j, kk) = m1(j, kk) - m1(i, kk) * Pivot2 / Pivot
            Next
        End If
    Next
Next
Determinant = Determinant * (-1) ^ order
End Function

Function SelectSort(px() As Double)
'****************************************************************************************
'功能:   用简单选择法进行排序(由大到小)
'参数:   px矩阵的第一行为待排序的数列
'返回值: 排序后原矩阵px第一行存储排序后由大到小的结果,第二行存储对应的排序前的下标
'****************************************************************************************
For i = 1 To UBound(px(), 2) - 1
    shao1 = i                                 'shao1做数据的哨兵
    For j = i + 1 To UBound(px(), 2)
        If (px(1, shao1) < px(1, j)) Then shao1 = j
    Next j
    If shao1 = i Then
        px(2, i) = i
    Else
        shao2 = px(1, shao1)                  'shao2做下标的哨兵
        px(1, shao1) = px(1, i)
        px(1, i) = shao2
        px(2, i) = shao1
        px(2, shao1) = i
    End If
Next i
If px(2, i) = 0 Then px(2, i) = i
End Function

Private Sub Command1_Click()
For i = 1 To n
    For j = 1 To m + 1
        vsFlexArray1.row = i
        vsFlexArray1.Col = j
        vsFlexArray1.Text = ""
    Next j, i
Text3.Text = ""
End Sub


Private Sub Command2_Click()
'n = Val(Text1.Text)
'm = Val(Text2.Text)
'k = Val(Text.Text)
'Me.Cls
'Dim Y(), X() As Double, Lxx() As Double, L() As Double, m%, n%, nn%, k%, k1(3) As Integer, k2(3) As Integer
ReDim k1(k): ReDim k2(k): ReDim x(m, n)
Dim xx() As Double: ReDim xx(m + 1, n)
If Option2.Value = True Then
    Y = Split(Text3.Text, ",")
    For i = 0 To UBound(Y)
        xx(i Mod (m + 1) + 1, i \ (m + 1) + 1) = Val(Y(i))
    Next i
    Call putout(xx(), m + 1, n)
    For i = 1 To n
         For j = 1 To m
          Print xx(j, i)
    Next j, i
    For i = 1 To n
         For j = 1 To m
         x(j, i) = xx(j, i)
     Next j, i
     pp = 1
     k1(pp) = 1
     For i = 2 To n
         If (Val(xx(m + 1, i)) = pp) Then
             k2(pp) = i
         Else
             k2(pp) = i - 1
             pp = pp + 1
             k1(pp) = i
         End If
     Next i
     k2(pp) = n
ElseIf vsFlexArray1.Enabled = True Then
    pp = 1
    k1(pp) = 1
    For i = 1 To n
        vsFlexArray1.row = i
        For j = 1 To m
        vsFlexArray1.Col = j
        x(j, i) = Val(vsFlexArray1.Text)
    Next j, i
    For i = 2 To n
        vsFlexArray1.row = i
        vsFlexArray1.Col = m + 1
        If (Val(vsFlexArray1.Text) = pp) Then
            k2(pp) = i
        Else
            k2(pp) = i - 1
            pp = pp + 1
            k1(pp) = i
        End If
    Next i
    k2(pp) = n
End If



'************************************以下进行求平均运算*****************************************
Dim pj() As Double: ReDim pj(m, 1)             '用来调用pingjun函数
Dim xzpj() As Double: ReDim xzpj(m, 1)         '以m维行向量储存总体的平均值
Dim xpj() As Double: ReDim xpj(m, k)           '以m*n矩阵储存n类的m维样本的平均值
For p = 1 To k
    Call pingjun(x(), m, k1(p), k2(p), pj())   '调用平均函数,计算每类的平均值
    For i = 1 To m
        xpj(i, p) = pj(i, 1)

Next i, p
Call pingjun(x(), m, k1(1), k2(k), xzpj())
'Print "总平均为:";: Call putout(xzpj(), m, 1) '输出总平均



'************************************以下进行求离差运算******************************************
Dim lc() As Double, flag As Boolean              '用来调用licha函数
Dim xlc() As Double: ReDim xlc(m, m)            '总离差阵,即Lxx
Dim xlcn() As Double: ReDim xlcn(m, m)          '总离差阵的逆
For p = 1 To k
    Call licha(x(), m, k1(p), k2(p), lc())      '调用各类的离差阵
    For i = 1 To m
        For j = 1 To m
        xlc(i, j) = xlc(i, j) + lc(i, j)        '各类离差阵进行累加得到总体离差阵
Next j, i, p
Text5.Text = Text5.Text & vbNewLine & "总离差阵为:" & vbNewLine
For i = 1 To m
    For j = 1 To m
        Text5.Text = Text5.Text & Space(5) & xlc(i, j)
    Next j
    Text5.Text = Text5.Text & vbNewLine
Next i
Call MRinv(m, xlc(), xlcn(), flag)              '调用求逆函数MRinv(),求离差阵的逆xlcn
If flag = False Then
    Text5.Text = Text5.Text & vbNewLine & vbNewLine & "离差阵无逆矩阵,不能建立判别函数,请选用其他方法进行判别分析"
    Exit Sub                                    '强行退出过程,结束运算,以下的程序不再进行
End If



'*********************************以下为进行统计检验或判别分析做准备****************************
Dim z() As Double: ReDim z(m, k)                   'z=(xpj(i)-xzpj)/(k2(i)-k1(i)+1)  i=1……k
Dim z2() As Double: ReDim z2(k, m)                 'z2存储z的转置矩阵
Dim B() As Double: ReDim B(m, m)                   'B=z*z2为组间离差阵
Dim he() As Double: ReDim he(m, m)                 'he矩阵储存Lxx+B,其中Lxx在计算中用xlc()表示
For i = 1 To m
    For j = 1 To k
        z(i, j) = (xpj(i, j) - xzpj(i, 1)) * Sqr(k2(j) - k1(j) + 1)
Next j, i
Call zhuanzhi(z(), z2())
Call chengfa(z(), z2(), B())
'Print: Print "B=z*z2为:";: Call putout(B(), m, m) '输出z与z2的乘积B
Call xiangjia(xlc(), B(), he())



'**************************************以下为进行统计检验***************************************
Dim xerf As Double                                 '用来进行卡尔方分布检验
WILKS = Determinant(xlc()) / Determinant(he())     '威尔克斯分布统计量=|Lxx|/|Lxx+B|
Text5.Text = Text5.Text & vbNewLine & "经计算威尔克斯统计量|Lxx|/|Lxx+B|为:" & WILKS
WILKSd = -(n - 1 - (m + k) / 2) * Log(WILKS)       '威尔克斯统计量的方差
Text5.Text = Text5.Text & Chr(13) & ",其方差V为:" & WILKSd
xerf = Val(InputBox("    请输入自由度为" & m * (k - 1) & "的卡尔方分布在水平0.01处的值:", "统计检验"))
If WILKSd > xerf Then
   Text5.Text = Text5.Text & vbNewLine & vbNewLine & "检验后可知,H01(各类总体均值相等)假设被否定,应建立判别函数。"
Else
   Text5.Text = Text5.Text & vbNewLine & vbNewLine & "检验后可知,H01(各类总体的均值相等)假设被接受,无需建立判别函数。"
    Exit Sub                                   '无需进行判别分析,则强行退出过程,下面的程序不再进行
End If



'**************************************以下进行Fisher判别分析**********************************
'---------------------------------------首先求出第一判别函数-----------------------------------
Dim v() As Double, mv As Double                     'mv存储按模最大的特征值,v存储其对应的特征向量
Dim vn() As Double: ReDim vn(1, m)                  'vn为特征向量v的转置
Call chengfa(xlcn(), B(), z())                      '离差阵的逆矩阵xlcn与B矩阵的乘积覆盖了原来的z阵
'Print "离差阵的逆矩阵与B矩阵的乘积为:": Call putout(z(), m, m)
Call tezheng(z(), mv, v())
Call zhuanzhi(v(), vn())
Text5.Text = Text5.Text & vbNewLine & vbNewLine & "所建立的判别函数x1,x2…xm项的系数为:"
For i = 1 To m
    Text5.Text = Text5.Text & Space(2) & vn(1, i)  '以v的转置形式输出
Next i
                  
Text5.Text = Text5.Text & vbNewLine & vbNewLine & "以下进行费希尔(Fisher)评判:(按照样品输入的顺序输出)--------------------------"

Dim fv As Double                                    '用来储存回判结果的符合率,后面两种方法都用到



'------------------------Fisher判别方法一:用类间临界值划分的规则-----------------------------------
'计算每类关于判别函数的值,再排序,经每相邻两个加权取平均得k-1各标准,若对任一样品Xi,其对应的值yi,再与判别标准进行大小比较从而得到判别
Dim yzpj() As Double: ReDim yzpj(2, k)
'yzpj(2, k)进行排序后,第一行存储判别函数值由大到小的结果,第二行存储原判别函数值对应的下标
For p = 1 To k
    For q = 1 To m
    yzpj(1, p) = v(q, 1) * xpj(q, p) + yzpj(1, p)
Next q, p
'Call putout(yzpj(), 2, k)                                        '输出各类对应的判别函数的值
Call SelectSort(yzpj())
Dim stand() As Double: ReDim stand(k - 1)
Text5.Text = Text5.Text & vbNewLine & vbNewLine & "类间临界值的辨别标准为:"
For i = 1 To UBound(stand)
    stand(i) = ((k2(yzpj(2, i)) - k1(yzpj(2, i)) + 1) * yzpj(1, i) + (k2(yzpj(2, i + 1)) - k1(yzpj(2, i + 1)) + 1) * yzpj(1, i + 1)) / (k2(yzpj(2, i)) - k1(yzpj(2, i)) + k2(yzpj(2, i + 1)) - k1(yzpj(2, i + 1)) + 2)
     Text5.Text = Text5.Text & Space(2) & stand(i)                '输出加权平均取得的标准
Next i
Dim jieguo() As Double: ReDim jieguo(1, n)
Call chengfa(vn(), x(), jieguo())
Text5.Text = Text5.Text & vbNewLine & "用类间临界值划分的判别结果为:" & vbNewLine & Space(5) '以下用标准进行判别
For p = 1 To UBound(k1())
    For i = k1(p) To k2(p)
        For j = 1 To UBound(stand())
        If jieguo(1, i) >= stand(j) Then
            jieguo(1, i) = yzpj(2, j)
            Text5.Text = Text5.Text & Space(1) & jieguo(1, i)     '输出此判别方法计算得到的类别
            Exit For
        End If
        Next j
        If j > UBound(stand()) Then
            jieguo(1, i) = yzpj(2, j)
            Text5.Text = Text5.Text & Space(1) & jieguo(1, i)     '输出此判别方法计算得到的类别
        End If
        If jieguo(1, i) = p Then fv = fv + 1
Next i, p
fv = fv / UBound(jieguo(), 2)
Text5.Text = Text5.Text & vbNewLine & Space(5) & "该方法的回判结果的符合率为:" & Format(fv, "00.0000%")



'---------------------------Fisher判别分析方法二:用马氏距离的判别规则--------------------------------
'对任一样品Xi,求出其判别函数对应的值yi,再求出它与各体的马氏距离di,若di=min{dj}(j=1…k),则判断Xi属于Gi
Dim cha() As Double: ReDim cha(m, n)          'cha用来存储样本总体X与各类平均xpj(1…m,i)(i=1,2…k)的差
Dim result() As Double: ReDim result(2, n)    'result的第一行存储距离最小的类别,第二行存储最小距离
Dim jg() As Double: ReDim jg(n, n)            'jg存储求总体的马氏距离方阵,其中对角线是求得的马氏距离
Dim f1() As Double: ReDim f1(1, n)
Dim f2() As Double: ReDim f2(n, 1)
Dim f3() As Double: ReDim f3(n, 1)
Dim g1() As Double: ReDim g1(1, m)
Dim g2() As Double: ReDim g2(1, 1)

Text5.Text = Text5.Text & vbNewLine & vbNewLine & "用马氏距离的判别结果为:" & vbNewLine & Space(5)
For p = 1 To k
    For i = 1 To m
        For j = 1 To n
            cha(i, j) = x(i, j) - xpj(i, p)    '求样本总体X与各类平均的差并用cha来存储
    Next j, i
    Call chengfa(vn(), cha(), f1())            '特征向量与差相乘放入f1
    Call zhuanzhi(f1(), f2())
    ReDim lc(m, m)
    Call licha(x(), m, k1(p), k2(p), lc())     '调用各类的离差阵
    For q1 = 1 To m
        For q2 = 1 To m
            lc(q1, q2) = lc(q1, q2) / (k2(p) - k1(p)) '结果为离差阵的无偏估计覆盖了原来的离差阵
    Next q2, q1
    Call chengfa(vn(), lc(), g1())
    Call chengfa(g1(), v(), g2())
    Call MRinv(1, g2(), g2(), flag)          'g2的逆覆盖了g2
    Call chengfa(f2(), g2(), f3())
    Call chengfa(f3(), f1(), jg())           'jg存储求总体与第k类的马氏距离方阵,其中对角线是求得的马氏距离
    If p = 1 Then
        For r = 1 To n
            result(1, r) = 1                 'result(2, r)矩阵的初始化, 第一行全赋1,第2行赋总体与第1类的马氏距离
            result(2, r) = jg(r, r):
        Next r
    Else
        For r = 1 To n

            If jg(r, r) < result(2, r) Then
                '将刚求的马氏距离与result对应位置的进行比较,若比result中的小,则取代它的值,并记下该类类别
                result(2, r) = jg(r, r):
                result(1, r) = p
            End If
        Next r
    End If
    For i = 1 To n
    Next i
Next p

For p = 1 To k                              '输出此判别方法计算得到的类别
    For q = k1(p) To k2(p)
    Text5.Text = Text5.Text & Space(1) & result(1, q)
    If result(1, q) = p Then fv = fv + 1
Next q, p
fv = fv / n
Text5.Text = Text5.Text & vbNewLine & Space(5) & "该方法的回判结果的符合率为:" & Format(fv, "00.0000%")


'本程序用到自编的absF、 chengfa 、Determinant、 licha、 MRinv、 pingjun、 SelectSort、 putout 、tezheng 、VS 、xiangjia函数


End Sub

    

Private Sub Command3_Click()
form2.Show
End Sub

Private Sub Command4_Click()
End
End Sub

'Y = Array(45, 0.2, 1903, 1,250, 10.88, 208.92,1, 225, 19.2, 146.05,1, 240, 26.4, 223.1, 1,220, 26.4, 203.1,1, 240, 26.4, 223.1,1, 97.85, 3, 68.85, 1,240, 39.6, 219.9, 1,220, 39.6, 189.9,1, 240, 39.6, 209.9, 1,110, 4.95, 67.05,1, 132, 5.2, 92.72,1, 107.2, 5.2, 65.42,1, 130, 8.25, 127.25,1, 120, 8.25, 117.75, 1,49.6, 7.75, 6.25,2, 36.68, 5.2, 15.48,2, 21.9, 5.2, 7.12,2, 16.5, 12.29, -17.29,3, 20.5, 6.91, -5.41,3, 22.71, 3, 0.71, 3,11.82, 5.2, -2.91,3, 12.38, 5.2, -2.41,3, 6.78, 5.2, -8,3, 9.35, 5.2, -2.8,3, 14.7, 4.4, -13.7,3, 8.48, 5.2, -3.66,3)
Private Sub Form_Load()
vsFlexArray1.Visible = True
vsFlexArray1.Editable = False
Text3.Visible = True
Text3.Enabled = False
End Sub

Private Sub Option1_Click()
If Text1.Text = "" Then MsgBox ("请输入样本参数!"): Exit Sub
vsFlexArray1.Visible = True
vsFlexArray1.Enabled = True
vsFlexArray1.Editable = True
vsFlexArray1.row = 0
For i = 1 To m
vsFlexArray1.Col = i
vsFlexArray1.Text = "x" & i
Next
vsFlexArray1.Col = i
vsFlexArray1.Text = "预分类"
vsFlexArray1.Col = 0
For j = 1 To n
    vsFlexArray1.row = j
    vsFlexArray1.Text = j
Next
End Sub

Private Sub Option2_Click()
If Text1.Text = "" Then MsgBox ("请输入样本参数!"): Exit Sub
Text3.Visible = True
Text3.Enabled = True
Text3.SetFocus
  
 
End Sub
Private Sub Text1_Change()
n = Val(Text1.Text)
End Sub

Private Sub Text2_Change()
m = Val(Text2.Text)
End Sub

Private Sub Text4_Change()
k = Val(Text4.Text)
End Sub

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -