精华内容
下载资源
问答
  • 对于21种主流采样算法,使用UCI官方保险数据集,不平衡数据集进行了python实验,基于AUC和F1进行了评分,所有结果进行了注释。
  • 介绍论文名: “classification, ranking, and top-k ...与常规准确率比较方式不同, 本文从另一个角度, 即推荐算法稳定性方面进行比较.详细参与比较推荐算法包括: baseline 传统基于用户 传统基于物品 oneSlope s

    介绍

    论文名: “classification, ranking, and top-k stability of recommendation algorithms”.
    本文讲述比较推荐系统在三种情况下, 推荐稳定性情况.
    与常规准确率比较的方式不同, 本文从另一个角度, 即推荐算法稳定性方面进行比较.

    详细

    参与比较的推荐算法

    包括:

    1. baseline
    2. 传统基于用户
    3. 传统基于物品
    4. oneSlope
    5. svd

    比较方式

    比较的过程分为两个阶段:

    阶段一, 将原始数据分为两个部分, 一部分为已知打分, 另一部分为未知打分, 用于预测.
    阶段二, 在用于预测打分那部分数据中, 取出一部分数据, 加入到已知打分部分, 剩余部分仍然为预测部分.

    比较阶段一中的预测结果和阶段二中预测结果的比较.
    数据划分情况如图所是.

    数据划分

    比较的方式

    预测稳定性

    预测性的评价方式有以下几种:
    MAE, RMSE

    分类稳定性

    分类型的评价方式有以下几种:
    准确率, 召回率, F-分数.

    排名稳定性

    排名型的评价方式有以下几种:
    排名相关性, Spearman的ρ评价, Kruskal的γ评价, Kendall的τ评价.

    前K项稳定性

    前k项的评价方式有以下几种:
    点击率稳定性(hit-rate), NDCG(normalized discounted cumulative gain).

    比较的场景

    稀疏性冲击

    改变数据的稀疏性, 从几个方面比较这些推荐算法的稳定性.

    结果如图所是.

    这里写图片描述

    基于内存的推荐算法和slopeone算法表现出强烈的不稳定性和对数据敏感性.
    svd和baseline算法相对稳定.

    评价数量冲击

    改变第二阶段中新加入数据的数量, 比较两次实验的差异.

    结果如图所是:

    这里写图片描述

    横坐标为比例, 即已知打分数据的倍数, 从10%到500%.

    从图中可以看出, 在新加入的数据较少时, 各个推荐算法表现出高度的稳定性.

    当新加入的数据较多时, 基于内存的推荐算法的稳定性不断下降.
    相反, 基于模型的方法相对稳定.

    打分分布冲击

    除了新加入的数据外, 新加入的数据的数据分布也一定程度上影响了推荐算法的稳定性.

    下表显示了修改数据分布的策略:

    这里写图片描述

    实验的结果如下:

    这里写图片描述

    从图中可以看出, 当加入的数据为随机时, 各个推荐算法都表现出相对较高的稳定性.
    但是, 当添加的数据出现歪斜时, 基于内存的推荐算法的稳定性降低较快, 基于模型的推荐算法的稳定性基本保持不变.

    算法参数冲击

    对于推荐算法而言, 除了数据的因素外, 还有算法本身参数对算法稳定性的影响.

    对于基于内存的算法, 相似用户/物品的数量影响着推荐算法的效果,
    对于svd算法, 隐含属性的数量影响着推荐算法的结果.

    实验通过修改推荐算法参数的方式进行比较, 结果如图所时:

    这里写图片描述

    对于top-K的比较, k值的大小也影响推荐算法的稳定性.
    通过修改k的大小, 实验的结果如图所时:

    这里写图片描述

    实验结果表示:

    对于修改算法的参数, 对svd算法的影响较少, 对于基于内存的算法影响较大.

    修改top-k中k的大小, 对基于模型的推荐算法影响较小, 对于基于内存的推荐算法的稳定性影响较大.

    总结

    对于上面多种情况的比较.
    基于模型的推荐算法在多种情况下, 稳定性较高, 特别时svd算法.
    基于内存的推荐算法稳定性较差.

    展开全文
  • 数据挖掘大作业前言本章工具 前言 聚类分析研究成果主要集中在基于距离(或者称为基于相似度)聚类方法,用距离来作为相似性度量优点是十分直观,从...本文用到数据来自我一门数据分析课程,是一个包括了2

    前言

    聚类分析的研究成果主要集中在基于距离(或者称为基于相似度)的聚类方法,用距离来作为相似性度量的优点是十分直观,从我们对物体的识别角度来分析,同类的数据样本是相互靠近的,不同类样本应该相聚较远。k-means聚类算法是划分聚类方法中最常用、最流行的经典算法,许多其他的算法都是k-means聚类算法的变种。其主要思想是通过迭代过程将数据集划分为不同类别,使评价聚类性能的准则函数达到最优,使生成的每个聚类类内紧凑,类间独立。
    本文用到的数据来自我的一门数据分析课程,是一个包括了286名NBA球员数据的csv表格。在这里插入图片描述

    本章工具

    • Anaconda3下的Jupyter Notebook编译器
    • python3.7环境

    在jupyter notebook读取数据:
    在这里插入图片描述
    通过seaborn包中的lmplot函数绘出散点图,可以看到数据的大致分布:在这里插入图片描述

    k-means介绍

    k-means原理

    Kmeans聚类算法的思路通俗易懂,通过不断计算各样本点与簇中心的距离,直到收敛为止,具体步骤如下:

    1.从数据中随机挑选k个样本点作为原始的簇中心
    2.计算剩余样本与簇中心的距离,并把各样本标记为离k个簇中心最近的类别
    3.重复计算各簇中样本点的均值,并以均值作为新的k个簇中心
    4.重复2、3步骤,直到簇中心的变化趋势趋于稳定,形成最终的k个簇

    如下图所示
    在这里插入图片描述
    Python提供了实现该算法的模块——sklearn,我们只需要调用其子模块cluster中的Kmeans类即可,该“类”的语法和参数含义如下:

    Kmeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001,
            precompute_distances='auto', verbose=0, random_state=None, 
            copy_x=True, n_jobs=1, algorithm='auto')
    
    
    • n_clusters:用于指定聚类的簇数
    • init:用于指定初始的簇中心的设置方法,如果为’k-means++’,则表示设置的初始簇中心相距较远;如果为’random’则表示从数据集中随机挑选k个样本作为初始簇中心;如果为数组,则表示用户指定具体的初始簇中心
    • n_init:用于指定Kmeans算法的运行次数,每次运行时都会选择不同的初始簇中心,目的是防止算法收敛于局部最优,默认为10
    • max_iter:用于指定单次运行的迭代次数,默认为300
    • tol:用于指定算法的收敛阈值,默认为0.0001
    • precompute_distances:bool类型参数,是否在算法运行之前计算样本之间的距离,默认为’auto’,表示当样本量与变量个数的乘积大于1200万时不计算样本之间的距离
    • verbose:通过该参数设置算法返回日志信息的频度,默认为0,表示不输出日志信息;如果为1,就表示每隔一段时间返回日志信息
    • random_state:用于指定随机数生成器的种子
    • copy_X:bool类型参数,当参数precompute_distances为True时有效,如果该参数为True,就表示提前计算距离时不改变原始数据,否则会修改原始数据
      n_jobs:用于指定算法运行时的CPU数量,默认为1,如果为-1,就表示使用所有可用的CPU
    • algorithm:用于指定Kmeans的实现算法,可以选择’auto’‘full’和’elkan’,默认为’auto’,表示自动根据数据特征选择运算的算法

    最佳k值的确定

    本文使用了两种常用的评估方法,用于确定最佳k值:“簇内离差平方和拐点法”、“轮廓系数法”

    拐点法

    在不同的k值下计算簇内的离差平方和,然后通过可视化的方法找到“拐点”所对应的k值。

    # 构造自定义函数,用于绘制不同k值和对应总的簇内离差平方和的折线图
    def k_SSE(X, clusters):
        # 选择连续的K种不同的值
        K = range(1,clusters+1)
        # 构建空列表用于存储总的簇内离差平方和
        TSSE = []
        for k in K:
            # 用于存储各个簇内离差平方和
            SSE = []
            kmeans = KMeans(n_clusters=k)
            kmeans.fit(X)
            # 返回簇标签
            labels = kmeans.labels_
            # 返回簇中心
            centers = kmeans.cluster_centers_
            # 计算各簇样本的离差平方和,并保存到列表中
            for label in set(labels):
                SSE.append(np.sum((X.loc[labels == label,]-centers[label,:])**2))
            # 计算总的簇内离差平方和 
            TSSE.append(np.sum(SSE))
    
        # 中文和负号的正常显示
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
        plt.rcParams['axes.unicode_minus'] = False
        # 设置绘图风格
        plt.style.use('ggplot')
        # 绘制K的个数与GSSE的关系
        plt.plot(K, TSSE, 'b*-')
        plt.xlabel('簇的个数')
        plt.ylabel('簇内离差平方和之和')
        # 显示图形
        plt.show()
    
    
    from sklearn import preprocessing
    # 数据标准化处理
    X = preprocessing.minmax_scale(players[['得分','罚球命中率','命中率','三分命中率']])
    # 将数组转换为数据框
    X = pd.DataFrame(X, columns=['得分','罚球命中率','命中率','三分命中率'])
    k_SSE(X, 15)
    

    在这里插入图片描述
    通过离差平方和的折线图我们能发现k值最好取在3、4、5之间,但还是很难通过观察找到最佳的k值。于是我们可以用下文的第二个方法:轮廓系数法。

    轮廓系数法

    该方法综合考虑了簇的密集性与分散性两个信息,如果数据集被分割为理想的k个簇,那么对应的簇内样本会很密集,而簇间样本会很分三,轮廓系数的计算公式如下:
    在这里插入图片描述
    其中,a(i)体现了簇内的密集性,代表样本i与同簇内其他样本点距离的平均值;b(i)反映了簇间的分散性,其计算过程是:样本i与其他非同簇样本点距离的平均值,然后从平均值中挑选出最小值。

    有关轮廓系数的计算,我们可以直接调用sklearn子模块metris中的函数silhouette_score。该函数接受的聚类簇数必须大于或等于2,下面基于该函数重新自定义一个函数,用于绘制不同k值下对应轮廓系数的折线图,具体代码如下所示:

    # 构造自定义函数,用于绘制不同k值和对应轮廓系数的折线图
    def k_silhouette(X, clusters):
        K = range(2,clusters+1)
        # 构建空列表,用于存储个中簇数下的轮廓系数
        S = []
        for k in K:
            kmeans = KMeans(n_clusters=k)
            kmeans.fit(X)
            labels = kmeans.labels_
            # 调用字模块metrics中的silhouette_score函数,计算轮廓系数
            S.append(metrics.silhouette_score(X, labels, metric='euclidean'))
    
        # 中文和负号的正常显示
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
        plt.rcParams['axes.unicode_minus'] = False
        # 设置绘图风格
        plt.style.use('ggplot')    
        # 绘制K的个数与轮廓系数的关系
        plt.plot(K, S, 'b*-')
        plt.xlabel('簇的个数')
        plt.ylabel('轮廓系数')
        # 显示图形
        plt.show()
    
    k_silhouette(X, 10)
    

    在这里插入图片描述
    观察不同k值轮廓系数折线图,我们能发现k=2时轮廓系数最大,总体随k值增大而递减,但是最大也只有0.36左右,并不能达到约等于1的理想值,所以我们综合轮廓系数法和拐点法,在之前的结论3、4、5中选出最合适的k值:3。

    聚类运算

    在上面的结论下,我们把该数据聚集为三类:

    # 将球员数据集聚为3类
    kmeans = KMeans(n_clusters = 3)
    kmeans.fit(X)
    # 将聚类结果标签插入到数据集players中
    players['cluster'] = kmeans.labels_
    # 构建空列表,用于存储三个簇的簇中心
    centers = []
    for i in players.cluster.unique():
        centers.append(players.loc[players.cluster == i,['得分','罚球命中率','命中率','三分命中率']].mean())
    # 将列表转换为数组,便于后面的索引取数
    centers = np.array(centers)
    
    # 绘制散点图
    sns.lmplot(x = '得分', y = '命中率', hue = 'cluster', data = players, markers = ['^','s','o'],
               fit_reg = False, scatter_kws = {'alpha':0.8}, legend = False)
    # 添加簇中心
    plt.scatter(centers[:,0], centers[:,2], c='k', marker = '*', s = 180)
    plt.xlabel('得分')
    plt.ylabel('命中率')
    # 图形显示
    plt.show()
    

    在这里插入图片描述

    结果分析

    在这里插入图片描述
    在这里插入图片描述从最终的结论图中我们不难发现,第一类红色部分表示该球员得分相对较低且命中率也较低,我们可以总结为得分能力不强的组织型球员,总样本中占156人。以下是此类球员名单:

    res0Series = pd.Series(kmeans.labels_)
    res0 = res0Series[res0Series.values == 0]
    print(players.iloc[res0.index])
    

    在这里插入图片描述
    第二类用紫色圆点表示,其得分低但命中率很高,我们可以归类为上场及进攻次数较少的新秀球员,占54人在这里插入图片描述
    蓝色正方形表示的球员属于第三类,特点是得分高、命中率高,我们总结其为职业生涯巅峰球员,各个球队的得分机器,样本中有76人。在这里插入图片描述

    小结

    本篇介绍并实践了一种无监督的聚类算法——Kmeans聚类,在对NBA球员数据集进行聚类之后,我们通过观察聚类的结果,可以对比球员的好坏,在实际应用中可以帮助我们进行人才的挑选。

    参考文献

    • 《数据仓库与数据挖掘》陈志泊主编 清华大学出版社
    • 《从零开始学数据分析与挖掘》 刘顺祥著 清华大学出版社
    • 还要感谢博客上大神们的帖子,我从中学到了很多,帮助我解决了很多问题
    展开全文
  • 一个算法的优劣往往通过算法复杂度来衡量,算法复杂度包括时间复杂度和空间复杂度。 时间复杂度是算法的所需要消耗的时间,时间越短,算法越好。可以算法的代码进行估计,而得到算法的时间复杂度。 一般来说,...

     

    一个算法的优劣往往通过算法复杂度来衡量,算法复杂度包括时间复杂度和空间复杂度。

    时间复杂度是算法的所需要消耗的时间,时间越短,算法越好。可以对算法的代码进行估计,而得到算法的时间复杂度。

    一般来说,算法代码简短精悍可以用来减少算法的时间复杂度!

     

    空间复杂度指的是算法程序在执行时所需要的存储空间。空间复杂度可以分为以下两个方面!

    1.程序的保存所需要的存储空间资源。即程序的大小;

    2.程序在执行过程中所需要消耗的存储空间资源,如中间变量等;

    一般来说,程序的大小越小,执行过程中消耗的资源越少,这个程序就越好!

    下面为时间复杂度和空间复杂度的计算

    时间复杂度是总运算次数表达式中受n的变化影响最大的那一项(不含系数)
    比如:一般总运算次数表达式类似于这样:
    a*2n+b*n3+c*n2+d*n*lg(n)+e*n+f
    a ! =0时,时间复杂度就是O(2n);
    a=0,b<>0 =>O(n3);
    a,b=0,c<>0 =>O(n2)依此类推
    例子:
    (1)   for(i=1;i<=n;i++)   //循环了n*n次,当然是O(n2)
                for(j=1;j<=n;j++)
                     s++;
    (2)   for(i=1;i<=n;i++)//循环了(n+n-1+n-2+...+1)≈(n2)/2,因为时间复杂度是不考虑系数的,所以也是O(n2)
                for(j=i;j<=n;j++)
                     s++;
    (3)   for(i=1;i<=n;i++)//循环了(1+2+3+...+n)≈(n^2)/2,当然也是O(n2)
                for(j=1;j<=i;j++)
                     s++;
    (4)   i=1;k=0;//循环了n-1≈n次,所以是O(n)
          while(i<=n-1){
               k+=10*i;
    i++; }
    (5) for(i=1;i<=n;i++)
                 for(j=1;j<=i;j++)
                     for(k=1;k<=j;k++)
                           x=x+1;
    //
    循环了(1
    2
    +2
    2
    +3
    2
    +...+n
    2
    )=n(n+1)(2n+1)/6(这个公式要记住哦)≈(n
    3
    )/3,不考虑系数,自然是O(n
    3
    )
    另外,在时间复杂度中,log
    2
    n与lg(n)(同lg
    10
    (n))是等价的,因为对数换底公式:
    log
    a
    b=log
    c
    b/log
    c
    a
    所以,log
    2
    n=log
    2
    10 * lg(n),忽略掉系数,二者当然是等价的
    二、计算方法
    1.一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。
    但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。
    并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。 一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。 2.一般情况下,算法的基本操作重复执行的次数是模块n的某一个函数f(n),
    因此,算法的时间复杂度记做:T(n)=O(f(n))。随着模块n的增大,算法执行的时间的增长率和f(n)的增长率成正比,
    所以f(n)越小,算法的时间复杂度越低,算法的效率越高。 在计算时间复杂度的时候,先找出算法的基本操作,然后根据相应的各语句确定它的执行次数,
    再找出T(n)的同数量级(它的同数量级有以下:1,Log
    2
    n ,n ,nLog
    2
    n ,n的平方,n的三次方,2的n次方,n!),
    找出后,f(n)=该数量级,若T(n)/f(n)求极限可得到一常数c,则时间复杂度T(n)=O(f(n))。 3.常见的时间复杂度 按数量级递增排列,常见的时间复杂度有: 常数阶O(1), 对数阶O(log
    2
    n),  线性阶O(n),  线性对数阶O(nlog
    2
    n),  平方阶O(n
    2
    ),
    立方阶O(n
    3
    ),..., k次方阶O(n
    k
    ), 指数阶O(2
    n
    ) 。
    其中,
    1.O(n),O(n
    2
    ), 立方阶O(n
    3
    ),..., k次方阶O(n
    k
    ) 为多项式阶时间复杂度,分别称为一阶时间复杂度,二阶时间复杂度。。。。
    2.O(2
    n
    ),指数阶时间复杂度,该种不实用
    3.对数阶O(log
    2
    n),   线性对数阶O(nlog
    2
    n),除了常数阶以外,该种效率最高
    例:算法:
      for(i=1;i<=n;++i)
      {
         for(j=1;j<=n;++j)
         {
             c[ i ][ j ]=0; //该步骤属于基本操作 执行次数:n
    2
              for(k=1;k<=n;++k)
                   c[ i ][ j ]+=a[ i ][ k ]*b[ k ][ j ]; //该步骤属于基本操作 执行次数:n
    3
         }
      }
      则有 T(n)= n
    2
    +n
    3
    ,根据上面括号里的同数量级,我们可以确定 n
    3
    为T(n)的同数量级
      则有f(n)= n
    3
    ,然后根据T(n)/f(n)求极限可得到常数c
      则该算法的 时间复杂度:T(n)=O(n
    3
    )
    四、定义:
    如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n),它是n的某一函数 T(n)称为这一算法的“时间复杂性”。 当输入量n逐渐加大时,时间复杂性的极限情形称为算法的“渐近时间复杂性”。 我们常用大O表示法表示时间复杂性,注意它是某一个算法的时间复杂性。大O表示只是说有上界,由定义如果f(n)=O(n),那显然成立f(n)=O(n^2),它给你一个上界,但并不是上确界,但人们在表示的时候一般都习惯表示前者。 此外,一个问题本身也有它的复杂性,如果某个算法的复杂性到达了这个问题复杂性的下界,那就称这样的算法是最佳算法。 “大O记法”:在这种描述中使用的基本参数是 n,即问题实例的规模,把复杂性或运行时间表达为n的函数。这里的“O”表示量级 (order),比如说“二分检索是 O(logn)的”,也就是说它需要“通过logn量级的步骤去检索一个规模为n的数组”记法 O ( f(n) )表示当 n增大时,运行时间至多将以正比于 f(n)的速度增长。 这种渐进估计对算法的理论分析和大致比较是非常有价值的,但在实践中细节也可能造成差异。
    例如,一个低附加代价的O(n2)算法在n较小的情况下可能比一个高附加代价的 O(nlogn)算法运行得更快。
    当然,随着n足够大以后,具有较慢上升函数的算法必然工作得更快。 O(1) Temp=i;i=j;j=temp; 以上三条单个语句的频度均为1,该程序段的执行时间是一个与问题规模n无关的常数。
    算法的时间复杂度为常数阶,记作T(n)=O(1)。如果算法的执行时间不随着问题规模n的增加而增长,
    即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。 O(n
    2
    ) 
    1) 交换i和j的内容
    sum=0; (一次)
    for(i=1;i<=n;i++) (n次 )
    for(j=1;j<=n;j++) (n
    2
    次 )    
    sum++; (n^2次 )
    解:T(n)=2n^2+n+1 =O(n^2) 2)
    for (i=1;i<n;i++) {
    y=y+1; //频度是n-1
    for (j=0;j<=(2*n);j++)
    x++; //频度是(n-1)*(2n+1)=2n
    2
    -n-1 
    }
        f(n)=2n
    2
    -n-1+(n-1)=2n
    2
    -2           该程序的时间复杂度T(n)=O(n
    2
    ).         
    O(n)                                                              
    3)
    a=0; b=1; //频度:2
    for (i=1;i<=n;i++) //频度: n
    {
    s=a+b;    //频度: n-1
     b=a;     //频度:n-1
    a=s;     //频度:n-1
    }
    T(n)=2+n+3(n-1)=4n-1=O(n).

    O(log
    2
    n )
    4)
    i=1; //频度是1
       while (i<=n)
    i=i*2; //频度是f(n),
    则:2
    f(n)
    <=n;f(n)<=log
    2
    n               取最大值f(n)= log
    2
    n,           T(n)=O(log
    2
    n )
    O(n
    3
    )
    5)
    for(i=0;i<n;i++) {
    for(j=0;j<i;j++) {
    for(k=0;k<j;k++)
    x=x+2;
    }
    }
    解:当i=m, j=k的时候,内层循环的次数为k当i=m时, j 可以取 0,1,...,m-1 , 所以这里最内循环共
    进行了0+1+...+m-1=(m-1)m/2次所以,i从0取到n, 则循环共进行了: 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6
    所以时间复杂度为O(n
    3
    ).                                   
    我们还应该区分算法的最坏情况的行为和期望行为。如快速排序的最坏情况运行时间是 O(n
    2
    ),
    但期望时间是 O(nlogn)。通过每次都仔细 地选择基准值,我们有可能把平方情况 (即O(n
    2
    )情况)
    的概率减小到几乎等于 0。在实际中,精心实现的快速排序一般都能以 (O(nlogn)时间运行。
    下面是一些常用的记法: 访问数组中的元素是常数时间操作,或说O(1)操作。一个算法如 果能在每个步骤去掉一半数据元素,
    如二分检索,通常它就取 O(logn)时间。用strcmp比较两个具有n个字符的串需要O(n)时间。
    常规的矩阵乘算法是O(n
    3
    ),因为算出每个元素都需要将n对 元素相乘并加到一起,所有元素的个数是n
    2

    指数时间算法通常来源于需要求出所有可能结果。例如,n个元 素的集合共有2n个子集,所以要求出
    所有子集的算法将是O(2n)的。指数算法一般说来是太复杂了,除非n的值非常小,因为,在 这个问题
    中增加一个元素就导致运行时间加倍。不幸的是,确实有许多问题 (如著名的“巡回售货员问题” ),
    到目前为止找到的算法都是指数的。如果我们真的遇到这种情况,通常应该用寻找近似最佳结果的算法替代之。

     二.空间复杂度

    空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。
    一个算法在计算机存储器上所占用的存储空间,
    包括程序代码所占用的空间,输入数据所占用的空间和辅助变量所占用的空间这三个方面。
    算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,
    它不随本算法的不同而改变。存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,
    就必须编写出较短的算法。算法在运行过程中临时占用的存储空间随算法的不同而异,有的算法只需要占用少量的临时工作单元,
    而且不随问题规模的大小而改变,我们称这种算法是“就地"进行的,是节省存储的算法,如这些介绍过的几个算法都是如此;
    有的算法需要占用的临时工作单元数与解决问题的规模n有关,它随着n的增大而增大,当n较大时,将占用较多的存储单元,
    例如将在第九章介绍的快速排序和归并排序算法就属于这种情况。 分析一个算法所占用的存储空间要从各方面综合考虑。如对于递归算法来说,一般都比较简短,算法本身所占用的存储空间较少,但运行时需要一个附加堆栈,从而占用较多的临时工作单元;若写成非递归算法,一般可能比较长,算法本身占用的存储空间较多,但运行时将可能需要较少的存储单元。 一个算法的空间复杂度只考虑在运行过程中为局部变量分配的存储空间的大小,它包括为参数表中形参变量分配的存储空间和为在函数体中定义的局部变量分配的存储空间两个部分。若一个算法为递归算法,其空间复杂度为递归所使用的堆栈空间的大小,它等于一次调用所分配的临时存储空间的大小乘以被调用的次数(即为递归调用的次数加1,这个1表不开始进行的一次非递归调用)。算法的空间复杂度一般也以数量级的形式给出。如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(log
    2
    n);当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n).若形参为数组,则只需要为它分配一个存储由实参传送来的一个地址指针的空间,即一个机器字长空间;若形参为引用方式,则也只需要为其分配存储一个地址的空间,用它来存储对应实参变量的地址,以便由系统自动引用实参变量。
        对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当=i自求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。另外,算法的所有性能之间都存在着或多或少的相互影响。因此,当设计一个算法(特别是大型算法)时,要综合考虑算法的各项性能,算法的使用频率,算法处理的数据量的大小,算法描述语言的特性,算法运行的机器系统环境等各方面因素,才能够设计出比较好的算法。
    
     
    空间复杂度是程序运行所以需要的额外消耗存储空间,也用o()来表示
    
      比如插入排序的时间复杂度是o(n
    2
    ),空间复杂度是o(1)
      而一般的递归算法就要有o(n)的空间复杂度了,因为每次递归都要存储返回信息
      一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量,算法执行时间的度量不是采用算法执行的绝对时间来计算的,因为一个算法在不同的机器上执行所花的时间不一样,在不同时刻也会由于计算机资源占用情况的不同,使得算法在同一台计算机上执行的时间也不一样,所以对于算法的时间复杂性,采用算法执行过程中其基本操作的执行次数,称为计算量来度量。
      算法中基本操作的执行次数一般是与问题规模有关的,对于结点个数为n的数据处理问题,用T(n)表示算法基本操作的执行次数.在评价算法的时间复杂性时,不考虑两算法执行次数之间的细小区别,而只关心算法的本质差别:
      为此,引入一个所谓的O() 记号,则T1(n)=2n=O(n),T2(n)=n+1=O(n)。一个函数f(n)是O(g(n))的,则一定存在正常数c和m,使对所有的n>m,都满足f(n)<c*g(n)。

    转载于:https://www.cnblogs.com/yinfj/p/7126643.html

    展开全文
  • 算法的性能

    2019-10-04 06:34:06
    一个算法的优劣往往通过算法复杂度来衡量,算法复杂度包括时间复杂度和空间复杂度。 时间复杂度 时间复杂度是算法的所需要消耗的时间,时间越短,算法越好。可以算法的代码进行估计,而得到算法的时间复杂度。 ...

    算法的性能评价------空间复杂度和时间复杂度

    一个算法的优劣往往通过算法复杂度来衡量,算法复杂度包括时间复杂度和空间复杂度。

    时间复杂度

    时间复杂度是算法的所需要消耗的时间,时间越短,算法越好。可以对算法的代码进行估计,而得到算法的时间复杂度。

    一般来说,算法代码简短精悍可以用来减少算法的时间复杂度!

    空间复杂度

    空间复杂度指的是算法程序在执行时所需要的存储空间。空间复杂度可以分为以下两个方面!

    1.程序的保存所需要的存储空间资源。即程序的大小;

    2.程序在执行过程中所需要消耗的存储空间资源,如中间变量等;

    一般来说,程序的大小越小,执行过程中消耗的资源越少,这个程序就越好!

    转载于:https://www.cnblogs.com/amou/p/8987820.html

    展开全文
  • 本文主要分析皆来自其他资料,借用较为权威的总结来我已经学习的这些经典算法做一个极为精简的概述(根据自身经验有一定修改),另外同时附上机器学习实战中作者各种算法的评价。另外机器学习实战这本书是本人看...
  • 算法的时间复杂度

    2018-04-01 15:15:18
    算法分析的任务就是利用某种方法,一个算法讨论其各种复杂度。算法的复杂度是度量算法优劣的重要依据。对于一个算法,复杂度的高低体现在运行该算法所需的计算机资源上。计算机资源主要包括时间资源和空间资源。...
  •  为对一个算法的代价及效率等进行分析,必须具有一个要使用的实现技术的模型,包括描述所用资源及其代价的模型。简单的说,就是必须要有相应统一的准则或模型来进行分析,才能有效比较出算法好坏。  目前通常假定...
  • 肝癌手术治疗效果评价C4.5算法预测

    千次阅读 2019-04-25 13:18:45
    病例有病人近80信息,其中包括患者病历号、性别、年龄、学历、职业、住址、基本病史、临床体征、恶性肿瘤分类、实验室检验指标、影像学检查等,经过数据预处理,选取其中20有代表性样本,选取预后有影响...
  • 近20年来可重构系统时域划分算法进行了分析,把它们分为网表级和...增强静态列表调度和多目标时城划分两个算法在三个指标之间获得了一个折中,然而,这四个算法均没有考虑划分后模块形状及模块跨层映射成本.
  • 初识算法

    2020-08-11 19:37:43
    什么是算法 非形式说,算法就是任何良定义的计算过程,该过程取某个值或值的集合作为输入并产生某个值或值的集合作为输出 。 算法的特性 1、有穷性 2、确切性 ...是对一个算法在运行过程中临时占用存储
  • 什么是算法? 算法是解决特定问题求解步骤的描述。包括自然语言描述,流程图描述,伪代码描述,程序代码描述等。 同一个问题可以使用不同的算法解决,如:1~100求和问题,可以...那么如何评价一个算法的好坏呢?.
  • 评价一个组播路由算法的重要指标包括组播树代价(cost)、时延(delay)和可扩展性(sealability )等。移动IP出现后,原有的组播路由算法受到了严重的挑战,不再适合于新的移动Internet环境。因此研究移 动环境下的...
  • 基于物品协同过滤算法实现

    千次阅读 2018-06-04 19:13:24
    基于物品的协同过滤算法实现 本内容主要通过一个算例实现学习itemCF的推荐,包括实现的基本...实现一个简单的电影网站的推荐算法,数据集合中有电影、用户、及用户电影的评价 数据集采用MovieLens中的small.csv...
  • 协同过滤算法(Collaborative Filtering, CF)是很常用的算法,在很多电商网站上都有用到。CF算法包括基于用户的CF(User-based CF)和基于物品的CF(Item-based CF)。 基于用户的CF原理如下:分析各个用户item...
  • 目标检测算法评估

    千次阅读 2019-04-08 22:23:48
    现在关于深度学习的算法层出不穷,那么我们应该用什么指标去评判一个算法的优缺点呢? 以目标检测为例,要想准确地评价目标检测算法,目标检测的评估工作肯定是少不了的。通常包括对速度的评价精度的评价...
  • 配电网重构是优化配电网络的主要措施,是指在满足支路载流、电压等约束条件下,决策联络开关或分段开关的状态,...而多目标优化问题包括目标,采用Pareto支配的概念人工鱼进行评估,从而发挥人工鱼群算法的有点。
  • 对于一个最优化问题,一定数量候选解(称为个体)抽象表示(称为染色体)种群向更好解进化。传统上,解用二进制表示(即0和1串),但也可以用其他表示方法。进化从完全随机个体种群开始,之后一代一代...
  • 、淘宝搜索一些特点 淘宝有几十亿商品,挂靠在几千叶子类目,上百...包括对数据整理、分析、索引产生索引库,如何根据用户输入关键词在索引倒排表中进行检索,完成商品与检索之间相关度评价将要输...
  • 本资源是推荐系统中最基本且最精但的协同过滤推荐算法实现,包括数据集,以及算法的评价指标MAE的计算,数据集采用MovieLens中两数据集进行测试,需要别的数据集可以根据自己需要添加,只需修改Base.java文件中的...
  • 目录 、问题描述 二、算法描述 三、评价指标 四、实验结果 五、总结 、问题描述 实现基于用户协同过滤(UserCF)算法,以...实验采用Grouplens团队提供公开数据集Movielens-latest-small,包括671用户9...
  • 粒子群优化算法

    2019-12-03 20:17:45
    粒子群优化算法的基本思想:是通过群体中个体之间的协作和信息共享来寻找最优解。 1.2算法流程 1)初始化一群微粒(群体规模为N),包括随机位置和速度; 2)评价微粒的适应度; 3)微...
  • 数据挖掘十大算法

    2019-03-09 14:31:47
    本文主要分析皆来自其他资料,借用较为权威的总结来我已经学习的这些经典算法做一个极为精简的概述(根据自身经验有一定修改),另外同时附上机器学习实战中作者各种算法的评价。另外机器学习实战这本书是本人看...
  • 【软考7】算法基础知识

    热门讨论 2015-10-25 15:37:38
    这两者之间相辅相成,设计出的算法需要校验和评价,而对算法的分析,又可以促使算法的设计更加的优良。本篇博客主要解决有关算法的基础概念知识,而后会其设计和分析进行总结。首先看算法的知识分布: 、是...
  • 本文主要分析皆来自其他资料,借用较为权威的总结来我已经学习的这些经典算法做一个极为精简的概述(根据自身经验有一定修改),另外同时附上机器学习实战中作者各种算法的评价。另外机器学习实战这本书是本人看...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 299
精华内容 119
关键字:

对一个算法的评价包括