精华内容
下载资源
问答
  • 效果如下所示,通过该方法可以使一张二的数据转换为一的简单数据明细,以便使用数据透视做统计分析。 该方法主要是利用《数据透视和数据透视图向导》这一工具实现的,首先需要在excel中找到这一工具 ...

           数据透视表作为一个十分强大的分析工具的同时,其对数据也是有一定的要求的,如果使用不符合要求的数据,不但达不到预计的效果,还可能出现统计错误。下面介绍一种简单的处理数据的方法。效果如下所示,通过该方法可以使一张二维的数据表转换为一维的简单数据明细表,以便使用数据透视表做统计分析。

    该方法主要是利用《数据透视表和数据透视图向导》这一工具实现的,首先需要在excel中找到这一工具

    方法一:(如图一和图二、图三),添加好后只要点击一下就可以弹出向导的对话框 (图三)

    方法二:主要是利用快捷键ALT +D+P 依次按下这三个按钮即可以马上调出(图四)

           有了工具之后就可以开始了,在图三中选择多重合并计算区域,并点击下一步弹出图五 对话框 ,其中两个随便选择一个就可以不影响结果,至于他们的区别这里暂不做讨论,然后点击下一步

           出现图6对话框,在选定区域内输入数据范围(可以使用鼠标选择数据表或者任选数据表单元按下ctrl+A即可),选择好后按下添加 按钮,使其添加到下面的列表内。并点击完成弹出图7,选择新建或者现有的工作表都可以,这里采用的是新工作表

     

     单击完成之后,找到最下面的总计并双击(如图8)位置,这时会形成一张新的表格(图9)

    图9中的页1列可以直接去掉,对左侧一列的时间值明显不对,对单元格式进行设置,在单元格式-数字-自定义中进行设置,然后更改列字段名字,如图10、11所示

    在图11中选中GDP字段列(即C列),按下F5或者CTRL+G 弹出<定位>对话框,点击定位条件 选择空值最后点确定如下图12所示) 

    然后鼠标移动C列右键 选择删除 表行(如图十一),效果如图13,之所以这样做是考虑当数据量大的时候,不可能手动对空值的单元格进行删除处理

    调整A列和B列的位置,将数据表按照省市一列的升序或者降序进行排列

     复制真个表选择性粘贴为“值和数字格式”到要使用该数据的位置即可。

    说明:这一步最好选择选择粘贴为“值和数字格式”,如果选择粘贴为数值的话日期会变成对应的数字格式,当然如果你统计的第一列不是日期的话是可以直接粘贴为数值的。效果如图15:

    展开全文
  • 以汽油、煤油和柴油为研究对象,并将其作为整体研究,不考虑其中具体组分,利用荧光光谱分析技术,提出一种通过将光谱数据矩阵首尾相连,求取其包络线,利用其观统计量(选用标准偏差、峰度系数和偏度系数)将三光谱降为...
  • 降维

    2018-09-17 10:48:00
    降维 机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据...

    降维

    机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据点映射后的低维向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。

    降维有什么作用呢?

    1. 数据在低维下更容易处理、更容易使用;
    2. 相关特征,特别是重要特征更能在数据中明确的显示出来;如果只有两维或者三维的话,更便于可视化展示;
    3. 去除数据噪声
    4. 降低算法开销
     常见的降维算法有主成分分析(principal component analysis,PCA)、LDA(线性判别分析),其中PCA是目前应用最为广泛的方法。下面将会介绍这几种方法:

    PCA

    PCA是不考虑样本类别输出的无监督降维技术。

    总结一下PCA的算法步骤:

    设有m条n维数据。

    1)将原始数据按列组成n行m列矩阵X

    2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

    3)求出协方差矩阵

    4)求出协方差矩阵的特征值及对应的特征向量

    5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

    6)即为降维到k维后的数据

    实例分析(以二维特征举例):

    现在假设有一组数据如下:

    主成分分析(PCA)原理详解

          行代表了样例,列代表特征,这里有10个样例,每个样例两个特征。

    第一步,分别求x和y的平均值,然后对于所有的样例,都减去对应的均值。这里x的均值是1.81,y的均值是1.91,得到

    主成分分析(PCA)原理详解

         第二步,求特征协方差矩阵,如果数据是3维,那么协方差矩阵是

    主成分分析(PCA)原理详解

         因为这里只有x和y,所以协方差矩阵为

    主成分分析(PCA)原理详解

         对角线上分别是x和y的方差,非对角线上是协方差。协方差是衡量两个变量同时变化的变化程度。协方差大于0表示x和y若一个增,另一个也增;小于0表示一个增,一个减。如果x和y是统计独立的,那么二者之间的协方差就是0;但是协方差是0,并不能说明x和y是独立的。协方差绝对值越大,两者对彼此的影响越大,反之越小。协方差是没有单位的量,因此,如果同样的两个变量所采用的量纲发生变化,它们的协方差也会产生树枝上的变化。

    第三步,求协方差的特征值和特征向量,得到

    主成分分析(PCA)原理详解

          上面是两个特征值,下面是对应的特征向量,这里的特征向量都归一化为单位向量。

    第四步,将特征值按照从大到小的顺序排序,选择其中最大的k个,然后将其对应的k个特征向量分别作为列向量组成特征向量矩阵。

    这里特征值只有两个,我们选择其中最大的那个,这里是1.28402771,对应的特征向量是(-0.677873399, -0.735178656)T。

    第五步,将样本点投影到选取的特征向量上。

        得到的结果是

    *   (-0.677873399, -0.735178656)T=    主成分分析(PCA)原理详解

          这样,就将原始样例的n维特征变成了k维,这k维就是原始特征在k维上的投影。

    代码实现:

    from sklearn.decomposition import PCA
    import numpy as np
    from sklearn.preprocessing import StandardScaler
    
    x=np.array([[10001,2,55], [16020,4,11], [12008,6,33], [13131,8,22]])
    x_scaler = StandardScaler()
    x = X
    x_scaler.fit_transform(x) pca
    = PCA(n_components=2) pca.fit(x) Z=pca.transform(x)

     

     

     LDA

     LDA是一种监督学习的降维技术,也就是说它的数据集的每个样本是有类别输出的。这点和PCA不同。LDA的思想可以用一句话概括,就是“投影后类内方差最小,类间方差最大”。什么意思呢? 我们要将数据在低维度上进行投影,投影后希望每一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大。

    LDA算法步骤:

    1) 计算类内散度矩阵

    2) 计算类间散度矩阵

    3) 计算矩阵

    4)计算的最大的d个特征值和对应的d个特征向量,得到投影矩阵[Math Processing Error]W

    5) 对样本集中的每一个样本特征,转化为新的样本

    6) 得到输出样本集

    部分代码实现:

    # -*- coding: utf-8 -*-
    """
    Created on Fri Dec  1 10:49:37 2017
    LDA_learning
    @author: BruceWong
    """
    import pandas as pd
    import matplotlib.pyplot as plt
    from sklearn.model_selection import train_test_split
    from sklearn import datasets
    from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
    import numpy as np
    
    def main():
        iris = datasets.load_iris() #典型分类数据模型
        #这里我们数据统一用pandas处理
        data = pd.DataFrame(iris.data, columns=iris.feature_names)
        data['class'] = iris.target
    
        #这里只取两类
    #     data = data[data['class']!=2]
        #为了可视化方便,这里取两个属性为例
        X = data[data.columns.drop('class')]
        Y = data['class']
    
        #划分数据集
        x_train, x_test, y_train, y_test =train_test_split(X, Y)
        lda = LinearDiscriminantAnalysis(n_components=2)
        lda.fit(x_train, y_train)
    
        #显示训练结果
        print(lda.means_) #中心点
        print(lda.score(x_test, y_test)) #score是指分类的正确率
        print(lda.scalings_)#score是指分类的正确率
    
        x_2d = lda.transform(X) #现在已经降到二维X_2d=np.dot(X-lda.xbar_,lda.scalings_)
        #对于二维数据,我们做个可视化
        #区域划分
        lda.fit(x_2d,Y)
        h = 0.02
        x_min, x_max = x_2d[:, 0].min() - 1, x_2d[:, 0].max() + 1
        y_min, y_max = x_2d[:, 1].min() - 1, x_2d[:, 1].max() + 1
        xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                             np.arange(y_min, y_max, h))
        Z = lda.predict(np.c_[xx.ravel(), yy.ravel()])
        Z = Z.reshape(xx.shape)
        plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
    
        #做出原来的散点图
        class1_x = x_2d[Y==0,0]
        class1_y = x_2d[Y==0,1]
        l1 = plt.scatter(class1_x,class1_y,color='b',label=iris.target_names[0])
        class1_x = x_2d[Y==1,0]
        class1_y = x_2d[Y==1,1]
        l2 = plt.scatter(class1_x,class1_y,color='y',label=iris.target_names[1])
        class1_x = x_2d[Y==2,0]
        class1_y = x_2d[Y==2,1]
        l3 = plt.scatter(class1_x,class1_y,color='r',label=iris.target_names[2])
    
        plt.legend(handles = [l1, l2, l3], loc = 'best')
    
        plt.grid(True)
        plt.show()
    
    if __name__ == '__main__':
        main()

     

     两者对比

    1、相同点

    (1)两者的作用是用来降维的

    (2)两者都假设符合高斯分布

    2、不同点

    (1)LDA是有监督的降维方法,PCA是无监督的。

    (2)LDA降维最多降到类别数K-1的维数,PCA没有这个限制。

    (3)LDA更依赖均值,如果样本信息更依赖方差的话,效果将没有PCA好。

    (4)LDA可能会过拟合数据。

     

    参考博客:https://blog.csdn.net/Chenzhi_2016/article/details/79451201

     

     
     
     

    转载于:https://www.cnblogs.com/r0825/p/9639902.html

    展开全文
  • 在记忆化搜索中,可以为正在处理的项声明一个引用,简化对它的读写操作;动态规划解决的是多阶段决策问题;初始状态→│决策1│→│决策2│→…→│决策n│→结束状态和分治法最大的区别在于:适合于用动态规划...

    1 动态规划

    1.1 定义

    动态规划的核心是状态和状态转移方程。

    在记忆化搜索中,可以为正在处理的表项声明一个引用,简化对它的读写操作;

    动态规划解决的是多阶段决策问题;

    初始状态→│决策1│→│决策2│→…→│决策n│→结束状态

    和分治法最大的区别在于:适合于用动态规划的问题,经过分解以后得到的子问题往往不是相互独立的(即下一个子阶段的求解是建立在上一个子阶段的基础之上,进行进一步的求解,而不是相互独立的问题)

    动态规划问题一般由难到易分为一维动态规划,二维动态规划,多维动态规划,以及多变量动态规划问题。其中多维动态规划问题又可以进行降维。动态规划问题求解的最重要的一步就是求解出 状态转移方程

    1.2 特性

    最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理.

    无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关

    有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势,动态规划可以避免多次计算)

    1.3 例子

    还是做题最实在!

    1.3.1 最长公共子序列

    问题描述:给定两个序列:X[1...m]和Y[1...n],求在两个序列中同时出现的最长子序列的长度。

    如果按照最普通的方法,就是遍历所有可能的情况(将较短字符串中所有的子串和较长字符串中的子串进行比较),取所有可能的情况中最长的子串;

    int DP::LongestCommonSubsequence(string &X, string &Y, int m, int n) {

    if (m == 0 || n == 0) {

    return 0;

    }

    if (X[m-1] == Y[n-1]) {

    return LongestCommonSubsequence(X, Y, m-1, n-1) + 1;

    }

    else {

    return max(LongestCommonSubsequence(X, Y, m-1, n), LongestCommonSubsequence(X, Y, m, n-1));

    }

    }

    void DP::testLongestCommonSubstring() {

    string x = "abcdefg", y = "efg";

    int result = LongestCommonSubsequence(x, y, (int)x.size(), (int)y.size());

    cout << "result:" << result;

    }

    很显然,这花费的时间是指数级的,非常慢;

    那么采用动态规划是怎么做的?

    思路:我们可以想象成树,两个字符串都分别进行发散,对于一个结点来说,左边是左边的字符串进行改变,右边则是右边的字符串进行改变,直到两个字符串都相等。

    第一步应该是找出递推公式:

    这里的 C[i,j] 代表的意思是字符串 X 中到达下标 i 和字符串 Y 中到达下标 j 的时候的最长子串个数;

    第二步是写出伪代码

    LCS(x,y,i,j)

    if x[i] = y[j]

    then C[i,j] ← LCS(x,y,i-1,j-1)+1

    else C[i,j] ← max{LCS(x,y,i-1,j),LCS(x,y,i,j-1)}

    return C[i,j]

    最后是写出代码

    上面的伪代码对于每一种情况都会往前重新计算一遍,完全没有必要,用一个数组保存之前计算的值即可;

    int DP::LongestCommonSubsequence(string &X, string &Y, int m, int n) {

    vector> dp(X.size() + 1, vector(Y.size() + 1, 0));

    for (int i = 1; i <= m; i++) {

    for (int j = 1; j <= n; j++) {

    // 因为是从1开始的,所以字符串下标要减去1

    if (X[i-1] == Y[j-1]) {

    dp[i][j] = dp[i-1][j-1] + 1;

    }

    else {

    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);

    }

    }

    }

    return dp[m][n];

    }

    void DP::testLongestCommonSubsequence() {

    string x = "abcdefg", y = "efg";

    int result = LongestCommonSubsequence(x, y, (int)x.size(), (int)y.size());

    cout << "result:" << result;

    }

    看看dp数组:

    0 0 0 0 0 0

    0 1 1 1 1 1

    0 1 2 2 2 2

    0 1 2 3 3 3

    0 1 2 3 3 3

    0 1 2 3 3 3

    0 1 2 3 4 4

    0 1 2 3 4 5

    1.3.2 最长公共子串

    和上面最长公共子序列不同的是,子串要求连续,不像子序列只要顺序保证是正确的就行了,所以使用一个变量来记录;

    /**************************************

    * // 最长公共子串问题

    ***************************************/

    int DP::LongestCommonSubstring(string &X, string &Y, int m, int n) {

    vector> dp(X.size() + 1, vector(Y.size() + 1, 0));

    int max = 0;

    for (int i = 1; i <= m; i++) {

    for (int j = 1; j <= n; j++) {

    // 因为是从1开始的,所以字符串下标要减去1

    if (X[i-1] == Y[j-1]) {

    if (dp[i-1][j-1]) {

    dp[i][j] = dp[i-1][j-1] + 1;

    }

    else {

    dp[i][j] = 1;

    }

    if (dp[i][j] > max) {

    max = dp[i][j];

    }

    }

    }

    }

    for (int i = 0; i <= m; i++) {

    for (int j = 0; j <= n; j++) {

    cout << " " << dp[i][j];

    }

    cout << endl;

    }

    return max;

    }

    void DP::testLongestCommonSubstring() {

    string x = "abcdefg", y = "abcfg";

    int result = LongestCommonSubstring(x, y, (int)x.size(), (int)y.size());

    cout << "result:" << result << endl;

    }

    看看dp数组:

    0 0 0 0 0 0

    0 1 0 0 0 0

    0 0 2 0 0 0

    0 0 0 3 0 0

    0 0 0 0 0 0

    0 0 0 0 0 0

    0 0 0 0 1 0

    0 0 0 0 0 2

    可以发现,对角线上连续大于0的值则为长度;最长的子串为abc,长度为3,次长为fg,长度为2;

    1.3.3 最长递增子序列

    问题描述:给定一个序列:X[1...m],求在这个序列中出现的最长递增子序列的长度。

    /**************************************

    * // 最长递增子串问题

    ***************************************/

    int DP::LongestIncreasingSubstring(string &X, int m) {

    vector dp(X.size(), 0);

    int max = 0;

    for (int i = 0; i < m; i++) { //到达

    dp[i] = 1;

    for (int j = 0; j < i; j++) {

    if (X[i] > X[j]) {

    dp[i] = dp[j] + 1;

    }

    else { //因为是连续的,所以只要不符合就重置

    dp[i] = 1;

    }

    }

    }

    for (int i = 0; i < m; i++) {

    cout << " " << dp[i];

    if (dp[i] > max) {

    max = dp[i];

    }

    }

    cout << endl;

    return max;

    }

    void DP::testLongestIncreasingSubstring() {

    string x = "babcak";

    int result = LongestIncreasingSubstring(x, (int)x.size());

    cout << "result:" << result << endl;

    }

    1.3.4 矩阵链乘积

    题目描述

    给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。

    思路

    对于矩阵连乘问题,最优解就是找到一种计算顺序,使得计算次数最少;

    假设 dp[i, j] 表示第 i 个矩阵到达第 j 个矩阵这段的最优解;

    将矩阵连乘积 简记为A[i:j] ,这里i<=j.假设这个最优解在第k处断开,i<=k

    状态转移方程

    当i=j时,A[i,j]=Ai, m[i,j]=0;(表示只有一个矩阵,如A1,没有和其他矩阵相乘,故乘的次数为0)

    当i

    也就是

    实现

    /**************************************

    * // 矩阵链乘积,求最小乘积次数

    ***************************************/

    void DP::MatrixChainMultiplication(vector data, int n,vector>& m_dp, vector>& s_dp) {

    //矩阵段长度为1,则 dp[][] 中对角线的值为0,表示只有一个矩阵,没有相乘的.

    for(int i = 1;i<=n;i++)

    m_dp[i][i] = 0;

    // 从第二个开始(第一个也是0),当前的乘次数取决于下一个的乘次数

    // 对角线循环,r表示矩阵的长度(2,3…逐渐变长)

    for(int r = 2;r<=n;r++) {

    // 行循环

    for(int i = 1; i<=n-r+1; i++) {

    // 列的控制,当前矩阵段(Ai~Aj)的起始为Ai,尾为Aj

    int j = r+i-1;

    //例如对(A2~A4),则i=2,j=4,下面一行的m[2][4] = m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)

    m_dp[i][j] = m_dp[i+1][j] + data[i-1]*data[i]*data[j]; //计算次数

    s_dp[i][j] = i;//记录断开点的索引

    //循环求出(Ai~Aj)中的最小数乘次数,遍历所有可能的情况

    for(int k = i+1 ; k

    //将矩阵段(Ai~Aj)分成左右2部分(左m[i][k],右m[k+1][j])

    //再加上左右2部分最后相乘的次数(p[i-1] *p[k]*p[j])

    int t = m_dp[i][k] + m_dp[k+1][j] + data[i-1] *data[k]*data[j];

    if(t < m_dp[i][j]) {

    m_dp[i][j] = t;

    s_dp[i][j] = k; //保存最小的,即最优的结果

    }

    }

    }

    }

    }

    void DP::testMatrixChainMultiplication() {

    vector data = {30,35,15,5,10,20,25};//记录6个矩阵的行和列,注意相邻矩阵的行和列是相同的

    vector> m_dp(7, vector(7, 0));//存储第i个矩阵到第j个矩阵的计算代价(以乘法次数来表示)

    vector> s_dp(7, vector(7, 0));//存储第i个矩阵到第j个矩阵的最小代价时的分为两部分的位置

    int n=6;//矩阵个数

    MatrixChainMultiplication(data, n , m_dp, s_dp);

    cout << "---计算代价---" << endl;

    for (int i = 0; i < m_dp.size(); i++) {

    for (int j = 0; j < m_dp[0].size(); j++) {

    cout << " " << m_dp[i][j];

    }

    cout << endl;

    }

    cout << "---最小代价时分为两边的位置" << endl;

    for (int i = 0; i < s_dp.size(); i++) {

    for (int j = 0; j < s_dp[0].size(); j++) {

    cout << " " << s_dp[i][j];

    }

    cout << endl;

    }

    }

    运行结果为:

    ---计算代价---

    0 0 0 0 0 0 0

    0 0 15750 7875 9375 11875 15125

    0 0 0 2625 4375 7125 10500

    0 0 0 0 750 2500 5375

    0 0 0 0 0 1000 3500

    0 0 0 0 0 0 5000

    0 0 0 0 0 0 0

    ---最小代价时分为两边的位置

    0 0 0 0 0 0 0

    0 0 1 1 3 3 3

    0 0 0 2 3 3 3

    0 0 0 0 3 3 3

    0 0 0 0 0 4 5

    0 0 0 0 0 0 5

    0 0 0 0 0 0 0

    表示第i个矩阵到第j个矩阵的计算代价矩阵m[i][j]和表示第i个矩阵到第j个矩阵的最小代价时的分为两部分的位置矩阵s[i][j]的结果如下图:

    从上面左图的m矩阵可以看出任意第i个到第j个矩阵连乘的乘法次数。最终的加括号形式为:(A1(A2A3))((A4A5)A6)

    1.3.5 数塔问题

    问题描述:

    数塔第i层有i个结点,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

    用二维数组则为:

    9

    1215

    1068

    2 1895

    19710416

    假设9首先被输入,是第 0 层,越往下层数不断递增;

    思路

    为了保证整条路径的和是最大的,下一层的走向取决于再下一层上的最大值是否已经求出才能决定,所以要做一个自顶向下的分析,自底向上的计算;

    状态转移方程

    dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + data[i][j]

    dp[i+1][j] 为左结点,dp[i+1][j+1] 为右结点;

    实现

    /**************************************

    * // 数塔问题

    ***************************************/

    int DP::MaxSumTower(vector> nums, int m, int n) {

    vector> dp(m, vector(n, 0));

    // 用底层的值来初始化dp,m为行,n为列

    for (int i = 0; i < n; i++) {

    dp[m-1][i] = nums[m-1][i];

    }

    // 自底向上,父结点的最大值取决于左结点或者右结点的最大值

    for (int i = m-2; i >= 0; i--) {

    for (int j = 0; j < n; j++) {

    if (i >= j) { //过滤多余的

    dp[i][j] = std::max(dp[i+1][j], dp[i+1][j+1]) + nums[i][j];

    }

    }

    }

    for (int i = 0; i < m; i++) {

    for (int j = 0; j < n; j++) {

    cout << " " << dp[i][j];

    }

    cout << endl;

    }

    return dp[0][0];

    }

    1.3.6 01背包问题

    题目描述

    有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

    思路

    dp[x][y] 表示体积不超过 y 且可选前 x 种物品的情况下的最大总价值

    递归关系:

    mp[0][y] = 0

    mp[x][0] = 0

    当 v[x] > y 时,mp[x][y] = mp[x-1][y]

    当 v[x] <= y 时,mp[x][y] = max{ mp[x-1][y], p[x] + mp[x-1][y-v[x]] }

    解释如下:

    表示体积不超过 y 且可选前 0 种物品的情况下的最大总价值,没有物品可选,所以总价值为 0

    表示体积不超过 0 且可选前 x 种物品的情况下的最大总价值,没有物品可选,所以总价值为 0

    因为 x 这件物品的体积已经超过所能允许的最大体积了,所以肯定不能放这件物品, 那么只能在前 x-1 件物品里选了

    x 这件物品可能放入背包也可能不放入背包,所以取前两者的最大值就好了, 这样就将前两种情况都包括进来了

    实现

    /**************************************

    * // 01背包问题

    ***************************************/

    int DP::ZeroOneBackpack(vector goods, int limit_weight) {

    int m = goods.size();

    int n = limit_weight;

    vector> dp(m + 1, vector(n + 1, 0));

    // 没有选择物品的时候价值为0

    for (int i = 1; i < n; i++) {

    dp[0][i] = 0;

    }

    // 重量为0的时候什么物品都选不了,价值自然也为0

    for (int i = 1; i < m; i++) {

    dp[i][0] = 0;

    }

    for (int i = 1; i <= m; i++) {

    for (int j = 1; j <= n; j++) {

    if (goods[i-1].weight > j) { //超出限制的重量

    dp[i][j] = dp[i-1][j];

    }

    else { //可能放入背包也可能不放入背包,取两者情况的最大值

    dp[i][j] = std::max(dp[i-1][j], dp[i-1][j - goods[i-1].weight] + goods[i-1].value);

    }

    }

    }

    for (int i = 0; i < m; i++) {

    for (int j = 0; j < n; j++) {

    cout << " " << dp[i][j];

    }

    cout << endl;

    }

    return dp[m][n];

    }

    void DP::testZeroOneBackpack() {

    vector goods;

    goods.emplace_back(0, 0);

    goods.emplace_back(60, 10);

    goods.emplace_back(100, 20);

    goods.emplace_back(120, 30);

    int result = ZeroOneBackpack(goods, 50);

    cout << "result:" << result << endl;

    }

    1.3.7 最大连续子序列之和

    问题描述:给定一个序列:X[1...m],求在这个序列中出现的最大的连续子序列之和。

    状态转移方程

    dp[i] = std::max(dp[i-1] + nums[i], nums[i]);

    实现

    /**************************************

    * // 最大连续子序列和

    ***************************************/

    int DP::MaxContinusSubsequenceSum(int* nums, int m) {

    vector dp(m, 0);

    int max = INT_MIN;

    dp[0] = nums[0];

    for (int j = 1; j < m; j++) {

    dp[j] = std::max(dp[j-1] + nums[j], nums[j]);

    }

    for (int i = 0; i < m; i++) {

    cout << " " << dp[i];

    if (dp[i] > max) {

    max = dp[i];

    }

    }

    cout << endl;

    return max;

    }

    void DP::testMaxContinusSubsequenceSum() {

    int data[] = {

    1,-2,3,-1,7

    };

    int result = MaxContinusSubsequenceSum(data, 5);

    cout << "result:" << result << endl;

    }

    展开全文
  • PCA降维

    2020-01-12 15:17:19
    数组中的每一张(一张最多二),都可以是一个特征矩阵或一个DataFrame,这些结构永远只有一张,所以一定有行列,其中行是样本,列是特征。针对每一张,维度指的是样本的数量或特征的数量,一般无特别说明...

    维度和降维

    数组中的每一张表(一张表最多二维),都可以是一个特征矩阵或一个DataFrame,这些结构永远只有一张表,所以一定有行列,其中行是样本,列是特征。针对每一张表,维度指的是样本的数量或特征的数量,一般无特别说明,指的都是特征的数量。除了索引之外,一个特征是一维,两个特征是二维,n个特征是n维。
    降维算法中的”降维“,指的是降低特征矩阵中特征的数量。降维的目的是为了让算法运算更快,效果更好,但其实还有另一种需求:数据可视化
    sklearn中降维算法都被包括在模块decomposition中,这个模块本质是一个矩阵分解模块。
    在这里插入图片描述

    PCA

    我们希望能够找出一种办法来帮助我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等。
    在降维中,PCA使用的信息量衡量指标,就是样本方差,又称可解释性方差,方差越大,特征所带的信息量越多。
    在这里插入图片描述
    Var代表一个特征的方差,n代表样本量,Xi代表每一个特种中的每个样本的取值,x>代表这一列样本的均值。n-1是为了得到样本方差的无偏估计

    降维是如何实现的?

    sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver=’auto’, tol=0.0,iterated_power=’auto’, random_state=None)]

    • 降维的过程
      在这里插入图片描述
      让数据能够被压缩到少数特征上并且总信息量不损失太多的技术就是矩阵分解
    • 降维和特征选择有什么不同?
      在这里插入图片描述
      在新的特征矩阵生成之前,我们无法知晓PCA都建立了怎样的新特征向量,新特征矩阵生成之后也不具有可读性。

    参数n_components

    n_components是我们降维后需要的维度,即降维后需要保留的特征数量
    如果我们希望可视化一组数据来观察数据分布,我们往往将数据降到三维以下,很多时候是二维,即n_components的取值为2。

    高维数据的可视化

    采用鸢尾花数据集为例
    将4维数据降到2维,并可视化处理

    import matplotlib.pyplot as plt
    from sklearn.datasets import load_iris #鸢尾花数据集 
    from sklearn.decomposition import PCA
    iris = load_iris()
    y = iris.target
    x = iris.data
    X_dr = PCA(n_components = 2).fit_transform(x) 
    # 降维完毕
    # 可视化
    # 可视化
    plt.figure()  # 画布
    plt.scatter(X_dr[y==0, 0],X_dr[y==0, 1], c= "red", label=iris.target_names[0])
    plt.scatter(X_dr[y==1, 0],X_dr[y==1, 1], c="black",label=iris.target_names[1])
    plt.scatter(X_dr[y==2, 0],X_dr[y==2, 1], c="orange",label=iris.target_names[2])
    plt.legend()
    plt.title("PCA of IRIS dataset")
    plt.show()
    # 当然也可以用for循环来写
    

    可视化结果:
    在这里插入图片描述
    这个图是鸢尾花数据集在他的两个特征向量(降维后)的分布。

    • expained_variance_
      查看降维后每个新特征向量上所带的信息量的大小(可解释方差的大小)
    # 探索降维后的数据 
    pca.explained_variance_
    

    代码结果:array([4.22824171, 0.24267075])

    • explained_variance_ratio_
      查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比(可解释方差贡献率)
    pca.explained_variance_ratio_
    

    代码结果:array([0.92461872, 0.05306648])
    大部分有效信息都被集中在了第一个特征上
    这两个小数的加和,就是降维后的特征矩阵带有的原特征矩阵的信息量。

    如何选取最好的n_components

    当参数n_components中不填写任何值,则默认返回min(X.shape)个特征,一般来说,样本量都会大于特征数目,所以什么都不填就相当于转换了新特征空间,但没有减少特征的个数。一般来说,不会使用这种输入方式。但我们却可以使用这种输入方式来画出累计可解释方差贡献率曲线,以此选择最好的n_components的整数取值。
    累积可解释方差贡献率曲线是一条以降维后保留的特征个数为横坐标,降维后新特征矩阵捕捉到的可解释方差贡献率为纵坐标的曲线,能够帮助我们决定n_components最好的取值。

    import numpy as np
    pca_line = PCA().fit(x)
    plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
    plt.xticks([1,2,3,4])
    plt.xlabel("number of components after dimension reduction")
    plt.ylabel("cumulative explained variance")
    plt.show()
    

    在这里插入图片描述
    2和3都是理想的n_components的取值

    最大似然估计自选超参数

    最大似然估计(maximum likelihood estimation)自选超参数的方法,输入“mle”作为n_components的参数输入

    pca_mle = PCA(n_components='mle')
    pca_mle = pca_mle.fit(x)
    x_mle = pca_mle.transform(x)
    x_mle.shape
    pca_mle.explained_variance_ratio_.sum()
    

    代码结果:
    (150, 3)
    0.9947878161267247

    按信息量占比选超参数

    输入[0,1]之间的浮点数,并且让参数svd_solver ==‘full’,表示希望降维后的总解释性方差占比大于n_components指定的百分比,即是说,希望保留百分之多少的信息量。比如说,如果我们希望保留97%的信息量,就可以输入n_components = 0.97,PCA会自动选出能够让保留的信息量超过97%的特征数量

    pca_f = PCA(n_components=0.97,svd_solver="full")
    pca_f = pca_f.fit(x)
    x_f  = pca_f.transform(x)
    pca_f.explained_variance_ratio_
    

    可以看到自动选择了二维,降维后特征的可解释方差为
    array([0.92461872, 0.05306648])

    PCA中的SVD

    简而言之,SVD在矩阵分解中的过程比PCA简单快速,虽然两个算法都走一样的分解流程,但SVD可以作弊耍赖直接算出V。但是遗憾的是,SVD的信息量衡量指标比较复杂,要理解”奇异值“远不如理解”方差“来得容易,因此,sklearn将降维流程拆成了两部分:一部分是计算特征空间V,由奇异值分解完成,另一部分是映射数据和求解新特征矩阵,由主成分分析完成,实现了用SVD的性质减少计算量,却让信息量的评估指标是方差,具体流程如下图:
    在这里插入图片描述
    通过SVD和PCA的合作,sklearn实现了一种计算更快更简单,但效果却很好的“合作降维“。很多人理解SVD,是把SVD当作PCA的一种求解方法,其实指的就是在矩阵分解时不使用PCA本身的特征值分解,而使用奇异值分解来减少计算量。这种方法确实存在,但在sklearn中,矩阵U和Σ虽然会被计算出来(同样也是一种比起PCA来说简化非常多的数学过程,不产生协方差矩阵),但完全不会被用到,也无法调取查看或者使用,因此我们可以认为,U和Σ在fit过后就被遗弃了。奇异值分解追求的仅仅是V,只要有了V,就可以计算出降维后的特征矩阵。在transform过程之后,fit中奇异值分解的结果除了V(k,n)以外,就会被舍弃,而V(k,n)会被保存在属性components_ 当中,可以调用查看。

    PCA(2).fit(x).components_ #2表示n_components=2
    

    array([[ 0.36138659, -0.08452251, 0.85667061, 0.3582892 ],
    [ 0.65658877, 0.73016143, -0.17337266, -0.07548102]])
    2行4列
    返回的是降维过后的新特征空间V(k,n)

    重要参数svd_solver与random_state

    参数svd_solver是在降维过程中,用来控制矩阵分解的一些细节的参数。有四种模式可选:“auto”, “full”, “arpack”,“randomized”,默认”auto"。在这里插入图片描述
    而参数random_state在参数svd_solver的值为"arpack" or "randomized"的时候生效,可以控制这两种SVD模式中的随机模式。通常我们就选用”auto“。

    重要属性components_

    通常来说,在新的特征矩阵生成之前,我们无法知晓PCA都建立了怎样的新特征向量,新特征矩阵生成之后也不具有可读性,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。
    V(k,n)是新特征空间,是我们要将原始数据进行映射的那些新特征向量组成的矩阵。我们用它来计算新的特征矩阵,但我们希望获取的毕竟是X_dr,我们把V(k,n)这个矩阵保存在n_components这个属性中。

    from sklearn.datasets import fetch_lfw_people
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    import numpy as np
    faces = fetch_lfw_people(min_faces_per_person=60) #实例化
    fig, axes = plt.subplots(4,5
                            ,figsize=(8,4)# 画布的尺寸和比例
                            ,subplot_kw={"xticks":[],"yticks":[]}) # 不要显示坐标轴
    for i, ax in enumerate(axes.flat):
            ax.imshow(faces.images[i,:,:],cmap="gray")#选择色彩的模式
    

    在这里插入图片描述
    下面进行降维

    X = faces.data
    pca = PCA(150).fit(X)
    #原本有2900维,我们现在来降到150维
    V = pca.components_  
    fig, axes = plt.subplots(3,8
                            ,figsize=(8,4)# 画布的尺寸和比例
                            ,subplot_kw={"xticks":[],"yticks":[]}) # 不要显示坐标轴
    for i, ax in enumerate(axes.flat):
            ax.imshow(V[i,:].reshape(62,47),cmap="gray")#选择色彩的模式
    

    在这里插入图片描述
    这张图稍稍有一些恐怖,但可以看出,比起降维前的数据,新特征空间可视化后的人脸非常模糊,这是因为原始数据还没有被映射到特征空间中。但是可以看出,整体比较亮的图片,获取的信息较多,整体比较暗的图片,却只能看见黑漆漆的一块。在比较亮的图片中,眼睛,鼻子,嘴巴,都相对清晰,脸的轮廓,头发之类的比较模糊。

    这说明,新特征空间里的特征向量们,大部分是"五官"和"亮度"相关的向量,所以新特征向量上的信息肯定大部分是由原数据中和"五官"和"亮度"相关的特征中提取出来的。到这里,我们通过可视化新特征空间V,解释了一部分降维后的特征:虽然显示出来的数字看着不知所云,但画出来的图表示,这些特征是和”五官“以及”亮度“有关的。这也再次证明了,PCA能够将原始数据集中的重要数据进行聚集。

    PCA参数

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    PCA属性列表

    在这里插入图片描述

    PCA接口列表

    在这里插入图片描述

    展开全文
  • §6 动态规划应用举例 1 资源分配问题 2 生产与存储问题 3 排序问题 4 设备更新问题 1 资源分配问题 1.1 一资源分配问题 1. 资源平行分配问题 例1 某部门拟建某种高效设备五台分配给所属的甲、乙、丙三个工厂,各...
  • 各种降维方法在2空间上的可视化

    千次阅读 2017-11-18 21:16:33
    利用digits手写数据集实现降维方法在2空间上的可视化表达。 from time import time import numpy as np import matplotlib.pyplot as plt from matplotlib import offsetbox from sklearn import (manifold, ...
  • 哪种情况下可以可以对dp进行滚动数组优化? 直观的讲,在某一维度的跨度仅仅是1的时候(出现 i - 1 或者 j - 1 ),就可以直接删掉一,即进行滚动数组优化。 滚动数组优化的代码怎么写? 由于滚动数组会让原先...
  • 维方维表暴露行过预算有(在执主要缺点程中出的复式。保险我国的社相结模式会统合的养老账户个人筹和筹资实行,目标于(基本上属。的做以减轻其称为法被税负,要数据示使把一定的些合特殊乎规准许支出企业。维方维表的...
  • 4 降维

    2020-01-09 14:47:06
    对原始数据特征提取,有时会得到较高的特征向量 在这些向量所处的高维空间中,含很多的冗余和噪声。 通过降维的方式来寻找数据内部的特性,从而提升特征表达能力,降低训练复杂度。 Principal Components Analysis...
  • 常用降维方法-常用降维方法解读1.... y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。目前大部分降维算法处理向量表达的数...
  • y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。 目前大部分降维算法处理向量表达的数据,也有一些降维算法处理高
  • sklearn_降维算法

    2020-06-27 16:15:38
    除了索引之外,一个特征是一,两个特征是二,n个特征是n降维算法中的”降维“,指的是降低特征矩阵中特征的数量。 降维的目的: 让算法运算更快,效果更好, 数据可视化 1.2 sklearn中的降维算法——...
  • 引言:机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f ...目前大部分降维算法处理向量表达的数据,也有一些降维算法处理高阶张量...
  • 简述多种降维算法

    千次阅读 2018-09-23 23:24:38
    本文首先给出了七种算法的一个信息,归纳了关于每个算法可以调节的(超)参数、算法主要目的等等,然后介绍了降维的一些基本概念,包括降维是什么、为什么要降维降维可以解决数灾难等,然后分析可以从什么样的...
  • 引言:机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f ...目前大部分降维算法处理向量表达的数据,也有一些降维算法处理高阶张量...
  • 【机器学习】简述多种降维算法

    千次阅读 2018-01-06 14:51:16
    最近看了一些关于降维算法的东西,本文首先给出了七种算法的一个信息,归纳了关于每个算法可以调节的(超)参数、算法主要目的等等,然后介绍了降维的一些基本概念,包括降维是什么、为什么要降维降维可以解决数...
  • 笔者利用波的向下降维干涉解决了这个问题,而非全部直接使用以往的四方法。 这就是这一章要研究的。这个看似被数学理论放弃的空白区,西方已经在应用结论,但是不说;而我们可能还没想这个问题。古人早就想过这个...
  • 数据预处理--数据降维

    千次阅读 2017-07-20 17:10:48
    数据规约产生更小但保持数据完整性的新数据集。在规约后的数据集上进行数据分析和挖掘将更有效... y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的
  • 这是第325篇原创1 t-SNE 背景介绍最易被我们视觉观察到的数是一,二维和三...当我们想对高维数据集进行分类,但又不清楚这个数据集有没有很好的可分性(同类之间间隔小、异类之间间隔大)时,可以通过降维算法将数...
  • 寻求其高维数据流形本征结构的一表示向量,将其作为图像数据的特征表达向量。举一个例子通过指纹图像的实例说明,将非线性降维方法(如Laplacian Eigenmap方法)应用于图像数据识别问题,在实际中是可行的,在计算上是...
  • 机器学习四大降维方法

    万次阅读 2018-09-07 09:27:23
    引言: 机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x-&... y是数据点映射后的低向量表达,通常y的维度...
  • python降维总结(超全)

    万次阅读 2018-09-19 17:41:52
    一、数据降维了解 1.1、数据降维原理:机器学习领域... y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的; 1.2、不进行数据降维的...
  • 四大机器学习降维方法

    万次阅读 多人点赞 2016-08-22 16:39:25
    y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。 目前大部分降维算法处理向量表达的数据,也有一些降维算法处理
  • PCA-数据降维实战

    2019-03-20 11:46:41
    概述 数据降维是机器学习领域中... y是数据点映射后的低向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。 目前大部分降维算法处理向量表达的数据,也有...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 248
精华内容 99
关键字:

维表降维