INPUT: X - (array) 特征数据数组 OUTPUT: eigvalues - (list) 特征值列表,其中特征值按从大到小排列 V - (array) V矩阵
(X)
| 56 | |
| 57 | #定义奇异值分解函数,计算V矩阵和特征值 |
| 58 | def cal_V(X): |
| 59 | ''' |
| 60 | INPUT: |
| 61 | X - (array) 特征数据数组 |
| 62 | |
| 63 | OUTPUT: |
| 64 | eigvalues - (list) 特征值列表,其中特征值按从大到小排列 |
| 65 | V - (array) V矩阵 |
| 66 | |
| 67 | ''' |
| 68 | newX = X.T / np.sqrt(X.shape[1]-1) #构造新矩阵X' |
| 69 | Sx = np.matmul(newX.T, newX) #计算X的协方差矩阵Sx = X'.T * X' |
| 70 | V_T = [] #用于保存V的转置 |
| 71 | w, v = np.linalg.eig(Sx) #计算Sx的特征值和对应的特征向量,即为X’的奇异值和奇异向量 |
| 72 | tmp = {} #定义一个字典用于保存特征值和特征向量,字典的键为特征值,值为对应的特征向量 |
| 73 | for i in range(len(w)): |
| 74 | tmp[w[i]] = v[i] |
| 75 | eigvalues = sorted(tmp, reverse=True) #将特征值逆序排列后保存到eigvalues列表中 |
| 76 | for i in eigvalues: |
| 77 | d = 0 |
| 78 | for j in range(len(tmp[i])): |
| 79 | d += tmp[i][j] ** 2 |
| 80 | V_T.append(tmp[i] / np.sqrt(d)) #计算特征值i的单位特征向量,即为V矩阵的列向量,将其保存到V_T中 |
| 81 | V = np.array(V_T).T #对V_T进行转置得到V矩阵 |
| 82 | return eigvalues, V |
| 83 | |
| 84 | |
| 85 | #定义主成分分析函数 |