精华内容
下载资源
问答
  • KNN的介绍与实例 K-近邻算法(KNN)概述 最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性某个训练对象的属性完全匹配时,便可以对...KNN是通过测量不同特征值之间的距离进行分...

    KNN的介绍与实例

    K-近邻算法(KNN)概述
    最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类。但是怎么可能所有测试对象都会找到与之完全匹配的训练对象呢,其次就是存在一个测试对象同时与多个训练对象匹配,导致一个训练对象被分到了多个类的问题,基于这些问题呢,就产生了KNN。
    KNN是通过测量不同特征值之间的距离进行分类。它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其中K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
    下面通过一个简单的例子说明一下:如下图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

    由此也说明了KNN算法的结果很大程度取决于K的选择。
    在KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧氏距离或曼哈顿距离:
    同时,KNN通过依据k个对象中占优的类别进行决策,而不是单一的对象类别决策。这两点就是KNN算法的优势。
    接下来对KNN算法的思想总结一下:就是在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前K个数据,则该测试数据对应的类别就是K个数据中出现次数最多的那个分类,其算法的描述为:
    1)计算测试数据与各个训练数据之间的距离;
    2)按照距离的递增关系进行排序;
    3)选取距离最小的K个点;
    4)确定前K个点所在类别的出现频率;
    5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。

    KNN : k Nearest Neighber

    分类器构造函数

     KNeighborsClassifier(n_neighbors=5, weights='uniform', 
                          algorithm='auto', leaf_size=30, 
                          p=2, metric='minkowski', 
                          metric_params=None, n_jobs=1, **kwargs)
     n_neighbors: 默认值为5,表示查询k个最近邻的数目
     algorithm:   {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’},指定用于计算最近邻的算法,auto表示试图采用最适合的算法计算最近邻
     leaf_size:   传递给‘ball_tree’或‘kd_tree’的叶子大小
     metric:      用于树的距离度量。默认'minkowski与P = 2(即欧氏度量)
     n_jobs:      并行工作的数量,如果设为-1,则作业的数量被设置为CPU内核的数量
     查看官方api:http://scikit-learn.org/dev/modules/generated/sklearn.neighbors.KNeighborsClassifier.html#sklearn.neighbors.KNeighborsClassifier
    

    示例

    # -*- coding: utf-8 -*-
    
    import numpy as np
    from sklearn import neighbors
    import warnings
    
    warnings.filterwarnings('ignore')   # warning信息不打印,可有可无
    
    knn = neighbors.KNeighborsClassifier( )   # 取得knn分类器
    
    data = np.array([[1, 1, 1, 1],
                    [0.5, 1, 1, 1],
                    [0.1, 0.1, 0.1, 0.1],
                    [0.5, 0.5, 0.5, 0.5],
                    [1, 0.8, 0.3, 1],
                    [0.6, 0.5, 0.7, 0.5],
                    [1, 1, 0.9, 0.5],
                    [1, 0.6, 0.5, 0.8],
                    [0.5, 0.5, 1, 1],
                    [0.9, 1, 1, 1],
                    [0.6, 0.6, 1, 0.1],
                    [1, 0.8, 0.5, 0.5],
                    [1, 0.1, 0.1, 1],
                    [1, 1, 0.7, 0.3],
                    [0.2, 0.3, 0.4, 0.5],
                    [0.5, 1, 0.6, 0.6]])
    
    labels = np.array(['美女',
                '淑女',
                '丑女',
                '一般型',
                '淑女',
                '一般型',
                '美女',
                '一般型',
                '淑女',
                '美女',
                '丑女',
                '可爱型',
                '可爱型',
                '淑女',
                '丑女',
                '可爱型'])
    
    knn.fit(data, labels)   # 导入数据进行训练
    
    print('预测类型为:', knn.predict([[0.8, 1, 1, 1]]))
    

    结果:

    在这里插入图片描述

    下面是不借用sklearn库的一个KNN实现

    #-*- coding: utf-8 -*-
    from numpy import *
    import operator
    def classify(inputPoint,dataSet,labels,k):
        dataSetSize = dataSet.shape[0]     #已知分类的数据集(训练集)的行数
        #先tile函数将输入点拓展成与训练集相同维数的矩阵,再计算欧氏距离
        diffMat = tile(inputPoint,(dataSetSize,1))-dataSet  #样本与训练集的差值矩阵
        sqDiffMat = diffMat ** 2                    #差值矩阵平方
        sqDistances = sqDiffMat.sum(axis=1)         #计算每一行上元素的和
        distances = sqDistances ** 0.5              #开方得到欧拉距离矩阵
        sortedDistIndicies = distances.argsort()    #按distances中元素进行升序排序后得到的对应下标的列表
        #选择距离最小的k个点
        classCount = {}
        for i in range(k):
            voteIlabel = labels[ sortedDistIndicies[i] ]
            classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
        #按classCount字典的第2个元素(即类别出现的次数)从大到小排序
        sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)
        return sortedClassCount[0][0]
    
    
    
    
    
    if __name__ == "__main__" :
        dataset = array([[1.0, 1.1], [1.0, 1.0], [0.0, 0.0], [0.0, 0.1]])
        labels = ['A', 'A', 'B', 'B'] 
        X = array([1.2, 1.1])  
        Y = array([0.1, 0.1])
        k = 3
        labelX =  classify(X,dataset,labels,k)
        labelY =  classify(Y,dataset,labels,k)
        print "Your input is:", X, "and classified to class: ", labelX
        print "Your input is:", Y, "and classified to class: ", labelY
    

    结果:

    Your input is: [ 1.2  1.1] and classified to class:  A
    Your input is: [ 0.1  0.1] and classified to class:  B
    

    SVM的介绍与实例

    SVM的资料非常多,我这里就不赘述了,可以看这篇参考资料

    SVM(支持向量机)主要用于分类问题,主要的应用场景有字符识别、面部识别、行人检测、文本分类等领域。
    通常SVM用于二元分类问题,对于多元分类通常将其分解为多个二元分类问题,再进行分类

    SVM分为SVC(用于分类)和SVG(用于回归)

    1. SVC

    sklearn提供了三种基于svm的分类方法(SVC):

    • sklearn.svm.NuSVC()
    • sklearn.svm.LinearSVC()
    • sklearn.svm.SVC()

    简书参考资料这里

    IRIS数据集介绍

    IRIS介绍

    • sklearn包中导入datasets库,库中有load_iris()方法
    • iris集有iris.data和iris.target两部分,后者是labels
    • iris.data.shape=(150, 4)
      iris.target.shape=(150,)

    打印类对象的所有属性的方法

    def prn_obj(obj):
        print '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])
    

    SVC调用示例

    # -*- coding:utf-8 -*-
    from sklearn import svm
    from sklearn import datasets
    from sklearn.model_selection import train_test_split as ts
    
    
    
    def prn_obj(obj):
        print ('\n'.join(['%s:%s' % item for item in obj.__dict__.items()]))
    
    
    #import our data
    iris = datasets.load_iris()
    X = iris.data
    y = iris.target
    
    #split the data to  7:3
    X_train,X_test,y_train,y_test = ts(X,y,test_size=0.3)
    # print(X_test.shape)
    
    # select different type of kernel function and compare the score
    
    # kernel = 'rbf'
    clf_rbf = svm.SVC(kernel='rbf')
    clf_rbf.fit(X_train,y_train)
    score_rbf = clf_rbf.score(X_test,y_test)
    # prn_obj(clf_rbf)
    print("The score of rbf is : %f"%score_rbf)
    print("预测结果为", end=":")
    print(clf_rbf.predict([[1,2.,3.,4.]]))   # 注意要给二维的ndarray嗷
    
    # kernel = 'linear'
    clf_linear = svm.SVC(kernel='linear')
    clf_linear.fit(X_train,y_train)
    score_linear = clf_linear.score(X_test,y_test)
    print("The score of linear is : %f"%score_linear)
    
    # kernel = 'poly'
    clf_poly = svm.SVC(kernel='poly')
    clf_poly.fit(X_train,y_train)
    score_poly = clf_poly.score(X_test,y_test)
    print("The score of poly is : %f"%score_poly)
    
    展开全文
  • 统计各个词组的出现次数,填充到对应词组的位置,构成文本的特征向量; 两个特征向量之间用余弦定理求夹角。这个表明向量之间的相关程度。所以用夹角而不用长度,是因为不同新闻的长度可能不同,用夹角表示不...
    转载请注明原地址:http://www.cnblogs.com/connorzx/p/4170043.html

    基本思想

    1. 建立一个字典向量,字典里包含这种语言的所有词组;
    2. 统计各个词组的出现次数,填充到对应词组的位置,构成文本的特征向量;
    3. 两个特征向量之间用余弦定理求夹角。这个值表明向量之间的相关程度。之所以用夹角而不用长度,是因为不同新闻的长度可能不同,用夹角表示不需要考虑长度(即向量的模长)的差异影响。

    自动分类

    1. 所有特征向量(N个)两两相关,将结果大于某一阈值的归为一类,共N1个小类。显然,N1<N;
    2. 将每个小类看做一个整体,计算其特征向量,每个小类之间求夹角,相关值大于阈值的归为一类,共N2类。其中,N2<N1;
    3. 重复上述步骤,直到所有相关值都小于阈值。停止操作,分类结束。 

    降低算法复杂度方法

    1. 保存每个向量的模值;
    2. 删除所有虚词。因为虚词不但不起作用,还有可能造成干扰。
    3. 计算时跳过由零元素的。 

    提高准确性方法

          采用特殊位置加权的办法,可以有效地提高算法效率。例如,标题、首位段以及每一段的第一句话出现的关键字都应该进行额外的加权。至于原因,你懂的!

    转载于:https://www.cnblogs.com/connorzx/p/4170043.html

    展开全文
  • Numpy线性代数

    2019-10-07 16:24:03
    文章目录矩阵1. 矩阵初始化2. 矩阵元素运算3. 矩阵的乘法4. 矩阵的转置5.... 矩阵的特征值特征向量(EVD)13. 奇异值分解(SVD) 矩阵 1. 矩阵初始化 Numpy函数库中存在两种不同的数据类型(矩阵mat...

    矩阵

    1. 矩阵初始化

    Numpy函数库中存在两种不同的数据类型(矩阵matrix和数组array),都可以用于处理行列表示的数字元素,虽然他们看起来很相似,但是在这两个数据类型上执行相同的数学运算可能得到不同的结果,其中Numpy函数库中的matrix与MATLAB中matrices等价。

    getA()是numpy的一个函数,作用是将矩阵转成一个ndarray,getA()函数和mat()函数的功能相反,是将一个矩阵转化为数组。

    数组array 矩阵的初始化

    import numpy as np
    
    # 全零矩阵
    
    myZero = np.zeros([3,3])
    print(myZero)
    print(type(myZero))
    
    # 全一矩阵
    
    myOnes = np.ones([3,3])
    print(myOnes)
    print(type(myOnes))
    
    # 单位矩阵
    
    myEye = np.eye(3)
    print(myEye)
    print(type(myEye))
    
    # 对称矩阵
    
    a1 = [1.,2.,3.]
    myDiag = np.diag(a1)
    print(myDiag)
    print(type(myDiag))
    
    # 随机矩阵
    
    myRand = np.random.rand(3,3)
    print(myRand)
    print(type(myRand))
    
    [[0. 0. 0.]
     [0. 0. 0.]
     [0. 0. 0.]]
    <class 'numpy.ndarray'>
    [[1. 1. 1.]
     [1. 1. 1.]
     [1. 1. 1.]]
    <class 'numpy.ndarray'>
    [[1. 0. 0.]
     [0. 1. 0.]
     [0. 0. 1.]]
    <class 'numpy.ndarray'>
    [[1. 0. 0.]
     [0. 2. 0.]
     [0. 0. 3.]]
    <class 'numpy.ndarray'>
    [[0.8047288  0.08855086 0.01365475]
     [0.27463797 0.61934569 0.59620009]
     [0.01570598 0.54358429 0.5640885 ]]
    <class 'numpy.ndarray'>
    

    矩阵matrix矩阵的初始化

    • 通过mat()函数将目标数据的类型转化成矩阵(matrix)
    a1 = [1.,2.,3.]
    myDiag = np.mat(np.diag(a1))
    print(myDiag)
    print(type(myDiag))
    
    [[1. 0. 0.]
     [0. 2. 0.]
     [0. 0. 3.]]
    <class 'numpy.matrix'>
    
    • 直接创建
    a = np.mat('1 2 3;4 5 6; 7 8 9')
    print(a)
    b = np.mat([[1,2,3],[4,5,6],[7,8,9]])
    print(b)
    c = np.mat(np.arange(9).reshape(3,3))
    print(c)
    print(type(c))
    
    [[1 2 3]
     [4 5 6]
     [7 8 9]]
    [[1 2 3]
     [4 5 6]
     [7 8 9]]
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    <class 'numpy.matrix'>
    
    2. 矩阵元素运算

    矩阵的元素运算是指矩阵在元素级别的加、减、乘、除运算。
    (1)元素相加和相减。
    条件:矩阵的行数和列数必须相同。
    数学公式:(A±B)i,j=Ai,j±Bi,j(A±B)_i,_j=A_i,_j±B_i,_j

    myOnes = np.ones([4,4])
    myEye = np.eye(4)
    print(myOnes+myEye)
    print(myOnes-myEye)
    
    [[2. 1. 1. 1.]
     [1. 2. 1. 1.]
     [1. 1. 2. 1.]
     [1. 1. 1. 2.]]
    [[0. 1. 1. 1.]
     [1. 0. 1. 1.]
     [1. 1. 0. 1.]
     [1. 1. 1. 0.]]
    

    (2)矩阵数乘:一个数乘以一个矩阵。

    数学公式:(cA)i,j=cAi,j(cA)_i,_j=c·A_i,_j

    mymat = np.arange(9).reshape(3,3)
    print(mymat)
    print(10*mymat)
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    [[ 0 10 20]
     [30 40 50]
     [60 70 80]]
    

    (3)矩阵所有元素求和。
    数学公式:sum(A)=i=1mj=1nAi,j=1,1<i<m,1<j<n其中\operatorname{sum}(A)=\sum_{i=1}^{m} \sum_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

    mymat = np.arange(9).reshape(3,3)
    print(mymat)
    print(np.sum(mymat))
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    36
    

    (4)矩阵所有元素之积

    数学公式:product(A)=i=1mj=1nAi,j=1,1<i<m,1<j<n其中\operatorname{product}(A)=\prod_{i=1}^{m} \prod_{j=1}^{n} A_{i, j}=1 其中, 1<i<m, 1<j<n

    mymat = np.arange(4).reshape(2,2)+1
    print(mymat)
    print(np.product(mymat))
    
    [[1 2]
     [3 4]]
    24
    

    (5)矩阵各元素的n次幂:n=3。
    数学公式:Aij3=Aij×Aij×AijA_{ij}^3=A_{ij}×A_{ij}×A_{ij}

    mymat = np.arange(9).reshape(3,3)
    print(mymat)
    print(np.power(mymat,3))
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    [[  0   1   8]
     [ 27  64 125]
     [216 343 512]]
    
    3. 矩阵的乘法

    (1)矩阵各元素的积:矩阵的点乘同维对应元素的相乘。当矩阵的维度不同时,会根据一定的广播规则将维数扩充到一致的形式。
    数学公式:(A×B)i,j=Ai,j×Bi,j(A×B)_i,_j =A_i,_j×B_i,_j

    mymat = np.arange(9).reshape(3,3)
    print(mymat)
    print(np.multiply(mymat,mymat))
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    [[ 0  1  4]
     [ 9 16 25]
     [36 49 64]]
    

    (2)矩阵内积

    数学公式:[A,B]i,j=Ai,1B1,j+Ai,2B2,j++AinBnj=r=1nAi,rBr,j[\boldsymbol{A}, \boldsymbol{B}]_{i, j}=\boldsymbol{A}_{i, 1} \boldsymbol{B}_{1, j}+\boldsymbol{A}_{i, 2} \boldsymbol{B}_{2, j}+\cdots+\boldsymbol{A}_{i n} \boldsymbol{B}_{n j}=\sum_{r=1}^{n} \boldsymbol{A}_{i, r} \boldsymbol{B}_{r, j^{\circ}}

    # 数组array
    a = np.arange(9).reshape(3,3)
    b = np.ones([3,3])
    print(a)
    print(b)
    print(np.dot(a,b))
    # 矩阵matrix
    c = np.mat(a)
    d = np.mat(b)
    print(c*d)
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    [[1. 1. 1.]
     [1. 1. 1.]
     [1. 1. 1.]]
    [[ 3.  3.  3.]
     [12. 12. 12.]
     [21. 21. 21.]]
    [[ 3.  3.  3.]
     [12. 12. 12.]
     [21. 21. 21.]]
    

    (3)向量内积、外积

    向量内积:xTy=i=1nxiyix^{T} y=\sum_{i=1}^{n} x_{i} y_{i}

    向量外积:xyT=(x1y1x1ynxmy1xmyn)x y^{T}=\left(\begin{array}{ccc}{x_{1} y_{1}} & {\cdots} & {x_{1} y_{n}} \\ {\vdots} & {} & {\vdots} \\ {x_{m} y_{1}} & {\cdots} & {x_{m} y_{n}}\end{array}\right)

    a = [2,1,0]
    b = [-1,2,1]
    print(a)
    print(b)
    print(np.dot(a,b))
    print(np.outer(a,b))
    
    [2, 1, 0]
    [-1, 2, 1]
    内积:0
    外积:
    [[-2  4  2]
     [-1  2  1]
     [ 0  0  0]]
    

    (4)向量叉乘(叉积):运算结果是一个向量而不是一个标量。并且两个向量的叉积与这两个向量组成的坐标平面垂直。

    数学公式:

    $$
    a=\left(x_{1}, y_{1}, z_{1}\right)

    b=\left(x_{2}, y_{2}, z_{2}\right)

    $$

    a×b=ijkx1y1z1x2y2z2=(y1z2y2z1)i(x1z2x2z1)j+(x1y2x2y1)k a \times b=\left|\begin{array}{ccc}{\mathrm{i}} & {\mathrm{j}} & {\mathrm{k}} \\ {x_{1}} & {y_{1}} & {z_{1}} \\ {x_{2}} & {y_{2}} & {z_{2}}\end{array}\right|=\left(y_{1} z_{2}-y_{2} z_{1}\right) i-\left(x_{1} z_{2}-x_{2} z_{1}\right) j+\left(x_{1} y_{2}-x_{2} y_{1}\right) k
    其中
    i=(1,0,0)j=(0,1,0)k=(0,0,1) i=(1,0,0) \quad j=(0,1,0) \quad \mathrm{k}=(0,0,1)
    根据i、j、k间关系,有:
    a×b=(y1z2y2z1,(x1z2x2z1),x1y2x2y1) a \times b=\left(y_{1} z_{2}-y_{2} z_{1},-\left(x_{1} z_{2}-x_{2} z_{1}\right), x_{1} y_{2}-x_{2} y_{1}\right)

    例1、已知,a =(2,1,0),b =(-1,2,1),试求(1)a×ba\times b(2)b×ab\times a
    解:(1)a×ba\times b =(1,-2,5):(2)$ b\times a$ =(-1,2,5)

    a = [2,1,0]
    b = [-1,2,1]
    print()
    print(np.cross(a,b))
    print(np.cross(b,a))
    
    [ 1 -2  5]
    [-1  2 -5]
    
    4. 矩阵的转置

    数学公式:(AT)ij=Aij(A^T)_{ij} = A_{ij}

    a = np.arange(9).reshape(3,3)
    print(a)
    print(a.T)
    print(a.transpose())
    
    [[0 1 2]
     [3 4 5]
     [6 7 8]]
    [[0 3 6]
     [1 4 7]
     [2 5 8]]
    [[0 3 6]
     [1 4 7]
     [2 5 8]]
    
    5. 矩阵对应列行的最大值,最小值,和
    # 随机生成一个0-9的3×3矩阵
    a = np.random.randint(0,10,(3,3))
    print(a)
    # 矩阵中的最大值
    print(a.max())
    # 计算矩阵中最大值的对应索引
    print(np.argmax(a))
    # 矩阵列中的最小值
    print(a.min(axis=0))
    # 计算矩阵列中最小值对应的列索引
    print(np.argmin(a,0))
    # 矩阵列求和
    print(a.sum(axis=0))
    # 矩阵行求和
    print(a.sum(axis=1))
    
    [[3 3 7]
     [9 8 5]
     [4 7 0]]
    9
    3
    [3 3 0]
    [0 0 2]
    [16 18 12]
    [13 22 11]
    
    6. 矩阵的其他操作:行列数、切片、复制、比较
    mymat = (np.arange(9)+1).reshape(3,3)
    mymat1 = np.random.randint(0,10,(3,3))
    print('mymat:',mymat)
    print('mymat1:',mymat1)
    
    [m,n] = np.shape(mymat)
    print('矩阵的行列数:',m,n)
    myscl1 = mymat[1]
    print('按行切片:',myscl1)
    myscl2 = mymat.T[1]
    print('按列切片:',myscl2)
    mymatcopy =mymat.copy()
    print('复制矩阵:',mymatcopy)
    # 比较
    print('矩阵元素比较:\n',mymat<mymat1)
    
    mymat: [[1 2 3]
     [4 5 6]
     [7 8 9]]
    mymat1: [[1 3 7]
     [7 8 1]
     [6 2 3]]
    矩阵的行列数: 3 3
    按行切片: [4 5 6]
    按列切片: [2 5 8]
    复制矩阵: [[1 2 3]
     [4 5 6]
     [7 8 9]]
    矩阵元素比较:
     [[False  True  True]
     [ True  True False]
     [False False False]]
    
    7. 矩阵的行列式
    import numpy as np
    from numpy import linalg
    
    A = np.full((4,4),3)
    B = np.random.randint(0,10,(4,4))
    print('A:\n',A)
    print('B:\n',B)
    print('det(A):',linalg.det(A))
    print('det(B):',linalg.det(B))
    
    A:
     [[3 3 3 3]
     [3 3 3 3]
     [3 3 3 3]
     [3 3 3 3]]
    B:
     [[0 5 2 4]
     [2 2 4 2]
     [8 1 7 5]
     [4 0 4 5]]
    det(A): 0.0
    det(B): 197.9999999999998
    
    8. 矩阵的逆和伪逆

    矩阵的逆

    import numpy as np
    from numpy import linalg
    
    B = np.random.randint(0,7,(3,3))
    print('B:\n',B)
    print('inv(B):',linalg.inv(B))
    
    B:
     [[6 2 1]
     [2 3 6]
     [6 6 0]]
    inv(B): [[ 0.24       -0.04       -0.06      ]
     [-0.24        0.04        0.22666667]
     [ 0.04        0.16       -0.09333333]]
    

    注意:矩阵不满秩,则会报错

    矩阵的伪逆

    A = np.full((3,4),4)
    print('A:\n',A)
    print('A的伪逆:\n',linalg.pinv(A))
    
    A:
     [[4 4 4 4]
     [4 4 4 4]
     [4 4 4 4]]
    A的伪逆:
     [[0.02083333 0.02083333 0.02083333]
     [0.02083333 0.02083333 0.02083333]
     [0.02083333 0.02083333 0.02083333]
     [0.02083333 0.02083333 0.02083333]]
    
    9. 矩阵的对称
    mymat = np.arange(9).reshape(3,3)
    print('mymat:\n',mymat)
    print('矩阵的对称:\n',mymat*mymat.T)
    
    mymat:
     [[0 1 2]
     [3 4 5]
     [6 7 8]]
    矩阵的对称:
     [[ 0  3 12]
     [ 3 16 35]
     [12 35 64]]
    
    10. 矩阵的秩
    import numpy as np
    from numpy import linalg
    
    A = np.full((4,4),3)
    B = np.random.randint(0,10,(4,4))
    print('A:\n',A)
    print('B:\n',B)
    print('矩阵A的秩:',linalg.matrix_rank(A))
    print('矩阵B的秩:',linalg.matrix_rank(B))
    
    A:
     [[3 3 3 3]
     [3 3 3 3]
     [3 3 3 3]
     [3 3 3 3]]
    B:
     [[7 1 2 6]
     [0 1 9 5]
     [7 7 4 0]
     [6 6 7 9]]
    矩阵A的秩: 1
    矩阵B的秩: 4
    
    11. 可逆矩阵的求解
    import numpy as np
    from numpy import linalg
    
    
    A = np.random.randint(0,10,(4,4))
    b = np.array([1,10,0,1])
    print('A:\n',A)
    print('b:\n',b)
    print('Ax=b,\nx=',linalg.solve(A,b.T))
    
    
    A:
     [[3 9 2 7]
     [2 5 4 1]
     [8 5 3 8]
     [4 2 3 4]]
    b:
     [ 1 10  0  1]
    Ax=b,
    x= [ 0.95638629  1.18691589  1.0623053  -2.09657321]
    
    12. 矩阵的特征值与特征向量(EVD)

    Av=λv Av=\lambda v

    这里AA是实对称矩阵,vv是特征向量,λ\lambda是特征值。下面我们使用Numpy求取矩阵的特征值和特征向量。

    import numpy as np
    from numpy import linalg
    
    A = np.mat(np.array([[8,1,6],[3,5,7],[4,9,2]]))
    evals,evecs = linalg.eig(A)
    print('特征值:\n',evals,'\n特征向量:\n',evecs)
    
    特征值:
     [15.          4.89897949 -4.89897949] 
    特征向量:
     [[-0.57735027 -0.81305253 -0.34164801]
     [-0.57735027  0.47140452 -0.47140452]
     [-0.57735027  0.34164801  0.81305253]]
    

    有了特征值和特征向量,可以还原出原矩阵(公式1-1):
    A=QΣQ1 A=Q \Sigma Q^{-1}
    A是实对称矩阵,Q是特征向量,Σ\Sigma是特征值构成的对角矩阵。下面是代码实现:

    sigma =evals*np.eye(3)
    print(evecs*sigma*linalg.inv(evecs))
    
    [[8. 1. 6.]
     [3. 5. 7.]
     [4. 9. 2.]]
    
    13. 奇异值分解(SVD)

    有一个m×n的实数矩阵A,我们想要把它分解成如下的形式(公式2-1):
    A=UΣVT A=U \Sigma V^{T}
    其中UUVV均为单位正交阵,即有UUT=IUU^T=IVVT=IVV^T=IUU称为左奇异矩阵VV称为右奇异矩阵ΣΣ仅在主对角线上有值,我们称它为奇异值,其它元素均为0。上面矩阵的维度分别为URm×m,ΣRm×n,VRn×nU∈R^{m×m}, Σ∈R^{m×n}, V∈R^{n×n}

    一般地ΣΣ有如下形式:
    Σ=[σ100000σ200000000000]m×n \Sigma=\left[\begin{array}{ccccc}{\sigma_{1}} & {0} & {0} & {0} & {0} \\ {0} & {\sigma_{2}} & {0} & {0} & {0} \\ {0} & {0} & {\ddots} & {0} & {0} \\ {0} & {0} & {0} & {\ddots} & {0}\end{array}\right]_{m \times n}
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBPeMS5W-1570436650483)(C:\Users\Administrator\Desktop\图像操作\opencv_python\奇异值分解.jpg)]

    对于奇异值分解,我们可以利用上面的图形象表示,图中方块的颜色表示值的大小,颜色越浅,值越大。对于奇异值矩阵ΣΣ,只有其主对角线有奇异值,其余均为0。

    正常求上面的U,V,ΣU,V,Σ不便于求,我们可以利用如下性质(公式2-2、2-3):
    AAT=UΣVTVΣTUT=UΣΣTUTATA=VΣTUTUΣVT=VΣTΣVT \begin{array}{l}{A A^{T}=U \Sigma V^{T} V \Sigma^{T} U^{T}=U \Sigma \Sigma^{T} U^{T}} \\ {A^{T} A=V \Sigma^{T} U^{T} U \Sigma V^{T}=V \Sigma^{T} \Sigma V^{T}}\end{array}
    **注:**需要指出的是,这里ΣΣTΣΣ^TΣTΣΣ^TΣ在矩阵的角度上来讲,它们是不相等的,因为它们的维数不同ΣΣTRm×mΣΣ^T∈R^{m×m},而ΣTΣRn×nΣ^TΣ∈R^{n×n},但是它们在主对角线的奇异值是相等的,即有
    ΣΣT=[σ120000σ2200000000]ΣTΣ=[σ120000σ2200000000]n×n \Sigma \Sigma^{T}=\left[\begin{array}{cccc}{\sigma_{1}^{2}} & {0} & {0} & {0} \\ {0} & {\sigma_{2}^{2}} & {0} & {0} \\ {0} & {0} & {\ddots} & {0} \\ {0} & {0} & {0} & {\ddots}\end{array}\right] \quad \Sigma^{T} \Sigma=\left[\begin{array}{cccc}{\sigma_{1}^{2}} & {0} & {0} & {0} \\ {0} & {\sigma_{2}^{2}} & {0} & {0} \\ {0} & {0} & {\ddots} & {0} \\ {0} & {0} & {0} & {\ddots}\end{array}\right]_{n \times n}
    可以看到式(2-2)与式(1-1)的形式非常相同,进一步分析,我们可以发现AATAA^TATAA^TA也是对称矩阵,那么可以利用式(1-1),做特征值分解。利用式(2-2)特征值分解,得到的特征矩阵即为U;利用式(2-3)特征值分解,得到的特征矩阵即为V;对ΣΣTΣΣ^TΣTΣΣ^TΣ中的特征值开方,可以得到所有的奇异值。

    例:对A进行奇异值分解

    A=[1576121104436752] A=\left[\begin{array}{ccccc}{1} & {5} & {7} & {6} & {1} \\ {2} & {1} & {10} & {4} & {4} \\ {3} & {6} & {7} & {5} & {2}\end{array}\right]

    A = np.mat([[1,5,7,6,1],
                [2,1,10,4,4],
                [3,6,7,5,2]])
    
    print('A:\n',A)
    
    U,evals,VT = linalg.svd(A)
    print('U=\n',U,'\nevals=\n',evals,'\nVT=\n',VT)
    sigma = np.mat([[evals[0],0,0,0,0],
                    [0,evals[1],0,0,0],
                    [0,0,evals[2],0,0]])
    #print(sigma)
    print(U*sigma*VT)
    
    A:
     [[ 1  5  7  6  1]
     [ 2  1 10  4  4]
     [ 3  6  7  5  2]]
    U=
     [[-0.55572489  0.40548161 -0.72577856]
     [-0.59283199 -0.80531618  0.00401031]
     [-0.58285511  0.43249337  0.68791671]] 
    evals=
     [18.53581747  5.0056557   1.83490648] 
    VT=
     [[-0.18828164 -0.37055755 -0.74981208 -0.46504304 -0.22080294]
     [ 0.01844501  0.76254787 -0.4369731   0.27450785 -0.38971845]
     [ 0.73354812  0.27392013 -0.12258381 -0.48996859  0.36301365]
     [ 0.36052404 -0.34595041 -0.43411102  0.6833004   0.30820273]
     [-0.5441869   0.2940985  -0.20822387 -0.0375734   0.7567019 ]]
    [[18.53581747  0.          0.          0.          0.        ]
     [ 0.          5.0056557   0.          0.          0.        ]
     [ 0.          0.          1.83490648  0.          0.        ]]
    [[ 1.  5.  7.  6.  1.]
     [ 2.  1. 10.  4.  4.]
     [ 3.  6.  7.  5.  2.]]
    

    参考资料:

    参考网站:

    https://www.jianshu.com/p/45417c05574c

    https://www.cnblogs.com/wj-1314/p/10244807.html

    https://www.cnblogs.com/endlesscoding/p/10033527.html

    参考书籍:《python科学计算》《机器学习算法原理与编程实实践》

    展开全文
  • PCA为什么要用协方差矩阵?

    万次阅读 多人点赞 2015-11-29 19:04:07
    PCA方法是数据降维的重要手段一,方法比较简单,就是将样本数据求一个维度的协方差矩阵,然后求解这个协方差矩阵的特征值和对应特征向量,将这些特征向量按照对应特征值从大到小排列,组成新的矩阵,被称为...

           PCA方法是数据降维的重要手段之一,方法比较简单,就是将样本数据求一个维度的协方差矩阵,然后求解这个协方差矩阵的特征值和对应的特征向量,将这些特征向量按照对应的特征值从大到小排列,组成新的矩阵,被称为特征向量矩阵,也可以称为投影矩阵,然后用改投影矩阵将样本数据转换。取前K维数据即可,实现对数据的降维。

           假设样本数据有r维(组成一个r维向量),共有n个样本。组成r*n矩阵A,矩阵每一列是一个样本,行是各个不同的特征维度。求解协方差矩阵S=AAT(最好先将A进行每个维度上的数据进行中心化A→C再求协方差矩阵S=CCT),S是r*r的方阵,用X(j)表示样本数据的第j维数据,则求解协方差矩阵




    其中表示两个维度之间的协方差

    很显然S是个对称矩阵,求解S的特征向量以及对应的特征值,按照特征值大小依次排列特征向量,将这些特征向量(列向量)组成一个矩阵,被称为转换矩阵或者投影矩阵。如果只取前K列特征向量组成的矩阵P,再把原样本数据用投影矩阵转换到新的坐标空间A’=PTA,可以实现数据的降维。

     

    △为什么要用协方差矩阵来做呢?

           虽然PCA降维方法我很早就知道,但是最近实验室老师让我看稀疏PCA方法解决他的三维人体建模的问题。我心里默默地在想,样本数据固定了,以上的S不就是定了吗?为神马还出来一个稀疏PCA?于是我就抱着理解原理本质的心理来重新看PCA,然后就发现一个关键的问题:PCA为什么要用协方差矩阵的特征向量矩阵来做投影矩阵呢?为神马啊为神马?想不通……这样做出来的投影矩阵一定能保证样本数据投影到另一个坐标系后,前几个坐标的值保证是最大特征?然后我找啊找,终于找到一个资料,尼玛……终于拨云见日啊~现在我用自己的理解用浅显易懂的描述来说明为嘛用协方差矩阵?!


    在说PCA的协方差矩阵之前我们先来说说投影矩阵。


    1. 关于投影矩阵/变换矩阵

           一个向量经过变换矩阵,只要变化矩阵的基分量之间是相互线性无关的就可以实现转换,什么叫线性无关呢?想象一下三维空间向量(a, b, c),每个基向量不共线就算是线性无关,当然还有一个条件,就是不能共面啊(不然其中一个基向量就可以用其他基向量来组合表示,他们组成的向量矩阵就不是满秩,不是3只有2)。扩展到N维空间就是N个基向量,每个基向量都不能由其他基向量线性组合得到。这种线性无关基向量组成的变换矩阵肯定是可逆的(方阵N*N的秩为N),可逆就可以实现两个坐标系的相互转换啊~


    坐标转换1:

    V1V2...Vn(均为列向量)是一组标准正交基,x1 x2..... xn是在该基下的一个坐标。则V1*x1+V2*x2+…+Vn*x={y1 y2......yn}T为该点在新基下的坐标。

    其中这组新基为{1, 0, ..., 0}T,{0, 1, ..., 0}T…{0, 0, ..., 1}T


    坐标转换2:

           若想将 {y1 y2......yn}T转换为在某个基V1V2...Vn下的坐标,只需左乘{V1V2...Vn}-1即可。

           一个样本在投影矩阵P的作用下,转换到另一个坐标空间,相当于求得该样本向量在P不同列向量的投影坐标。

           一个坐标系转换到另一个坐标系,转换矩阵其实不需要标准化(向量单位化,即向量的模为1),也不需要正交基的矩阵(两两向量正交,即相乘为0),只要满足上述“线性无关”的要求,数据就可以从一个度量空间转换到另一个空间,而且可以相互转换A'=P*A,A=P-1A',转换矩阵为P,而A和A'是两个空间中的不同表示。只是正交基和标准基会有一些好处:

    • 如果P是标准化矩阵,由于P-1P=I(恒等式),PTP=I(标准化矩阵性质),就会有PT=P-1,求解坐标转换速度更快,因为求转置矩阵比求逆矩阵快很多。
    • 如果P是正交矩阵,基向量两两正交,说明两个向量相关性很小,相当于数据在这两个维度上的相关性很小。线性无关不等于不相关,一个基向量在另一个基向量上有投影值,说明
    • 更进一步,标准正交矩阵更好,结合了以上两个优点,所以PCA求出来的特征向量矩阵是标准正交矩阵是一个大大大好的东西。

     

    2. 协方差矩阵:

           【我们希望去除的信息:

           1. 噪声:我们常说“噪音污染”,意思就是“噪声”干扰我们想听到的真正声音。同样,假设样本中某个主要的维度A,它能代表原始数据,是“我们真正想听到的东西”,它本身含有的“能量”(即该维度的方差),本来应该是很大的,但由于它与其他维度有那么一些千丝万缕的相关性,受到这些个相关维度的干扰,它的能量被削弱了,我们就希望通过PCA处理后,使维度A与其他维度的相关性尽可能减弱,进而恢复维度A应有的能量,让我们“听的更清楚”! 

           2. 冗余:冗余也就是多余的意思,就是有它没它都一样,放着就是占地方。同样,假如样本中有些个维度,在所有的样本上变化不明显(极端情况:在所有的样本中该维度都等于同一个数),也就是说该维度上的方差接近于零,那么显然它对区分不同的样本丝毫起不到任何作用,这个维度即是冗余的,有它没它一个样。

           降维的目的就是“降噪”和“去冗余”。“降噪”的目的就是使保留下来的维度间的相关性尽可能小,而“去冗余”的目的就是使保留下来的维度含有的“能量”即方差尽可能大。那首先的首先,我们得需要知道各维度间的相关性以及个维度上的方差啊!那有什么数据结构能同时表现不同维度间的相关性以及各个维度上的方差呢?自然是协方差矩阵!

           协方差矩阵度量的是维度与维度之间的关系,而非样本与样本之间。协方差矩阵的主对角线上的元素是各个维度上的方差(即能量),其他元素是两两维度间的协方差(即相关性)。我们要的东西协方差矩阵都有了,先来看“降噪”,让保留下的不同维度间的相关性尽可能小,也就是说让协方差矩阵中非对角线元素都基本为零。达到这个目的的方式自然不用说,线代中奖的很明确——矩阵对角化。】

           以上就是为什么要用协方差矩阵的原因!

    【而对角化后得到的矩阵,其对角线上是协方差矩阵的特征值,它还有两个身份:

    • 首先,它还是各个维度上的新方差;
    • 其次,它是各个维度本身应该拥有的能量(能量的概念伴随特征值而来)。
    这也就是我们为何在前面称“方差”为“能量”的原因。也许第二点可能存在疑问,但我们应该注意到这个事实,通过对角化后,剩余维度间的相关性已经减到最弱,已经不会再受“噪声”的影响了,故此时拥有的能量应该比先前大了。

    看完了“降噪”,我们的“去冗余”还没完呢。对角化后的协方差矩阵,对角线上较小的新方差对应的就是那些该去掉的维度。所以我们只取那些含有较大能量(特征值)的维度,其余的就舍掉即可。


           那为什么协方差矩阵求解出来的特征矩阵就能做到以上这点呢?且说我们的目的是:协方差矩阵“对角化”,不如说是我们需要找到一个转换矩阵,使得新的协方差矩阵能够尽量的对角化,即找到一个转换矩阵P使得A→A'=PA,使得新的协方差

           S=(A')(A') T = (PA) (PA)T= (PA)(ATPT) = P(AAT)PT= Λ (Λ为对角矩阵)

           下面就是数学求解的问题。

     

    3. PCA与SVD关系

           如果P是一个标准正交矩阵,以上的P(AAT)PT=Λ可以转化为:P-1P(AAT)PTP= P-1ΛP 即S=AAT= P-1ΛP看出什么了吗?看出什么了吗?这就是矩阵SVD分解啊……

     

    SVD

    a)方阵的分解

          Sr*r方阵,则存在以下矩阵分解

    其中U的列为S的特征向量,Λ为对角矩阵,其中对角线上的值为S的特征值,按从大到小排列:

     

          如果S是对称方阵,则存在

          其中U的列为矩阵S单位正交特征向量仍表示对角矩阵,其中对角线上的值为S的特征值,按从大到小排列。最后,QT=Q-1,因为正交矩阵的逆等于其转置

     

    b)奇异值分解

          上面讨论了方阵的分解,但是在LSA中,我们是要对Term-Document矩阵进行分解,很显然这个矩阵不是方阵。这时需要奇异值分解对Term-Document进行分解。奇异值分解的推理使用到了上面所讲的方阵的分解。

          假设Am*n矩阵,Um*m矩阵,其中U的列为AAT的正交特征向量,Vn*n矩阵,其中V的列为ATA的正交特征向量,再假设rA矩阵的秩,则存在奇异值分解:

    A= UΣVT

    其中AATATA的特征值相同,为λ1,λ2, …, λr

    Σm*n,其中,其余位置数值为0Σii的值按大小降序排列。以下是Σ的完整数学定义:

           σi称为矩阵A的奇异值。

          A乘以其转置矩阵AT得:AAT=(UΣVT)(VΣUT)=UΣ2UT正是在上面讨论过的对称矩阵的分解。

          奇异值分解的图形表示:


    从图中可以看到Σ虽然为m*n矩阵,但从第n+1行到m行全为零,因此可以表示成n*n矩阵,又由于右式为矩阵相乘,因此U可以表示为m*n矩阵,VT可以表示为n*n矩阵。

     

           回归到PCA,需要找到一个转换矩阵P使得P(AAT)PT=Λ也就是对S=AAT= P-1ΛP进行对称矩阵的分解,由以上知识得:P-1为矩阵S的标准正交特征向量的逆矩阵,所以先求解AAT的标准正交特征向量(列向量为特征向量),求逆只要求转置即可。

           以上就是为什么要用协方差矩阵以及它对应的特征向量原理。end!

     

    参考资料:

    1. http://wenku.baidu.com/link?url=Q28-Q3AuNGAtO6Rq3UxvkZ3AlvRnZaPChnKDoZxfmUKa09HHPeVI4rVpIBr4S7u3DtxPLqMyoWaa-N5K-7FIB0cyqQuufXEQ1ghBQo2-lLS

    2. http://blog.csdn.net/wangran51/article/details/7408414

    3. http://www.cnblogs.com/tclikang/archive/2012/12/05/2803506.html

    4. http://blog.csdn.net/sunuechao/article/details/12717771

    5. http://m.blog.csdn.net/blog/Lu597203933/45898411

    展开全文
  • 对角化

    2019-10-01 10:02:11
    对角化是指存在一个正交矩阵Q,使得 QTMQ 能成为一个对角阵(只有对角元素非...如果M是n阶实对称矩阵,则Q中的第 j 列就是第 j 个特征值对应的一个特征向量不同列的特征向量两两正交)。 转载于:https://www.cnbl...
  • 矩阵相似 同一个空间的同一个线性变换在不同坐标系下对应的两个矩阵是相似关系 矩阵相似 两个不同的空间的同一个线性变换对应的两个矩阵是合同关系 ...例如,对称矩阵由其特征值组成的对角阵...
  • KNN 算法的思想非常简单:对于任意的 n 为输入向量,其对应于特征空间一个点,输出为该特征向量对应的类别标签或者预测。KNN 算法在机器学习算法中有一个十分特别的地方,那就是它没有一个显示的...
  • 每个图 G = (V, E) 被表示为节点 V 和边 E 的集合,每个节点 i∈V 都可以和特征向量 x_i 相关联,每条边 (i, j) ∈ E 都可以和特征向量 x_ij 关联起来。这些特征可以表示节点类型、边的方向等。如果一个节点或者一条...
  • 本书围绕语言及库功能来组织,内容涉及c++的主要特征及标准库,并通过系统软件领域中的实例解释说明一些关键性的概念与技术。 本书的目的就是帮助读者了解c++是如何支持编程技术的,使读者能从中获得新的理解,从而...
  • 本书围绕语言及库功能来组织,内容涉及c++的主要特征及标准库,并通过系统软件领域中的实例解释说明一些关键性的概念与技术。 本书的目的就是帮助读者了解c++是如何支持编程技术的,使读者能从中获得新的理解,从而...
  • C++程序设计语言(特别版)--源代码

    热门讨论 2012-04-23 07:33:51
    本书围绕语言及库功能来组织,内容涉及c++的主要特征及标准库,并通过系统软件领域中的实例解释说明一些关键性的概念与技术。 本书的目的就是帮助读者了解c++是如何支持编程技术的,使读者能从中获得新的理解,从而...
  • 叉率变异率取不同的固定,以搜索不同解空间中的最优解,种群之间定期进行信息交换。多种群遗传算法能在一定程度上缓解遗传算法的不成 熟收敛问题。 8 基于量子遗传算法的函数寻优算法(王辉) 量子遗传算法...
  • 2019数据运营思维导图

    2019-03-29 21:34:09
    以区域为例 各区域充值总金额、充值人数、充值次数、付费率、arpu分布 交叉分析 以区域性别为例 不同性别+不同地域环境下,付费率数据…… 渠道分布 品牌、机型、操作系统、分辨率、联网、版本、设备均价、运营...
  • 数据运营思维导图

    2018-04-26 14:24:22
    利于在不同活跃用户规模的维度上发现掌握游戏用户规模的变动 数据去重 MAU(月活跃用户) 定义 截止到当天,最近30天(含30天)登录过游戏的用户 解决问题 游戏总体用户规模并评估用户规模稳定性 推广效果...
  • LINGO软件的学习

    2009-08-08 22:36:50
    每个集成员可能有一个或多个与有关联的特征,我们把这些特征称为属性。属性可以预先给定,也可以是未知的,有待于LINGO求解。例如,产品集中的每个产品可以有一个价格属性;卡车集中的每辆卡车可以有一个牵引力...
  • pytorch教程

    2019-01-18 00:34:18
     与PCA相似,首先将数据投影到一个特征空间,然后每个维度除以特征值来标准化这些数据。直观上就是将一个多元高斯分布转化到了一个0均值、协方差为1的多元高斯分布。  白噪声的处理增强数据中的噪声,因为其增强...
  • 第1 页共27 页 1 概述 频率计的基本原理是用一个频率稳定...向量作为程序计数器的高8 位,低8 位固定为00H,若引导向量为FCH, 则程序计数器内容为FC00H 即程序转到FC00H 地址开始执行而ISP 服务程序 就是从,FC00...
  • 数据结构(C++)有关练习题

    热门讨论 2008-01-02 11:27:18
    内容及步骤: 编写一个类Complex,定义复数的加法、减法、乘法除法运算,要求在编写该类时重载这些运算操作符,并重载I/O操作符,以便输入输出复数; 实验报告要求: 按要求写出完整的实验代码; ...
  • 5.4.1 求容器中元素之和 71 5.4.2 实例:微型算法库 73 5.5 容器与迭代器的分类 75 5.6 容器与算法的关系 76 5.7 迭代器的陷阱 76 5.8 本章小结 77 第6章 标准库中的容器 79 6.1 容器的分类及基本要求 79 ...
  • 中文文本预处理的基本步骤,包括中文分词、词性标注、数据清洗、特征提取(向量空间模型存储)、权重计算(TF-IDF)等。Jieba工具是最常用的中文文本分词处理的工具一,它能实现中文分词、词性标注、关键词抽取...
  • [2]按键式计算器操作顺序必须由用户自行指定,不具备表达式动态解释执行的特征。[3]按键式计算器运算对象较为简单,难以扩充至矩阵运算。 (读者曾见过可以计算svd、det、eig的此类计算器么?想象不能!) [4] 按键...

空空如也

空空如也

1 2
收藏数 21
精华内容 8
关键字:

不同特征值对应特征向量之和