精华内容
下载资源
问答
  • 一个典型的SaaS模式需要的三种计算模型支撑本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: 1)分布式计算模型 这是基本的模型,也是后两种模型的基础;现在非常火的Hadoop其实只是...

    一个典型的SaaS模式需要的三种计算模型支撑

    本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:
    1)分布式计算模型
    这是基本的模型,也是后两种模型的基础;现在非常火的Hadoop其实只是分布式计算模型中一种,而且并不是特别的复杂;
    2)分布式数据存储和访问模型
    这种模型很多,GFS,HFS,TFS都属于这类,当然一些分布式数据库包括阿里的Ocean数据库都属于这一类;分布式数据库访问和存取模型是SaaS企业应用的基础,对于企业级的应用底层数据节点不采用数据库当然是可以的,但如果采用数据库,好处也是非常多的,至少要简单很多。现有的分布式数据库对于SaaS应用,特别是SaaS企业应用来说采用GreenPlum这类数据库并不是不可以,但需要根据你的SaaS应用的业务本身进行权衡(主要是数据分离方式和效率的问题)。特别是牵扯到关联查询的时候,对于一个按用户分离和隔离的企业应用,如果数据节点采用关系数据库,那么80%的企业应用的关联查询都会落到一个节点中,查询的效率会比较高。如果采用分布式数据库,一般都很难做到这点,因为分布式数据库处理这类查询的时候,都需要把数据集中到一个节点进行处理,虽然可以采用一些策略来减少无效数据的传输,但往往效果不大。(分布式数据库中的A表和B表并不一定在一个数据节点的),这也是我一直以来的观点:对于分布式计算,通用往往代表着效率更低。我比较认同Google的GFS设计理念:面向应用设计接口。
    3)分布式部署与运维模型
    作为云计算下的SaaS应用,必须是可以支撑横向扩展(Scala out)的,而这些节点(包括应用节点和数据节点)的增加和管理完全靠人力去完成,基本是不可能的事情,因此只要是云计算模型下的SaaS应用,分布式部署与运维支撑模型就是必须的:应用程序节点的实时监控,管理和部署,数据节点的实时监控和部署,缓存节点的监控,管理和部署,文件服务器的监控,管理和部署等等。
    以上三种模型就构成了SaaS应用的基础,但SaaS应用又有自己的特殊性,因为牵扯到商务逻辑、事务处理(高一致性和准确性)以及数据的整理和分离等,SaaS应用的分布式数据存储和访问往往不能简单的采用已有的一些开源分布式系统,或者一些开源的分布式数据库系统,因为在大型的SaaS应用中,数据的分割(分布的基础)往往也不能做到单一,而数据的分割又会影响数据访问的路由策略。这就导致通用型的做法不太适合具体的需求。
    SaaS的这种基础实际上就已经非常具有技术含量了,而SaaS业务应用本身,在逻辑上就更难了,并不是访问数据库加上一个隔离字段那么简单。一般SaaS系统除了基本的多用户租赁(注意,设计SaaS的时候一定要以软隔离为基础,这样可以做到最大化的自由,而且不会影响数据库隔离和数据库实例隔离的需求 )还会牵扯到在线许可,多时区,多语言,以及功能、页面、流程的可配置。特别是更深层次的应用更会涉及到在线跨企业资源共享和流程协作的问题,处理这类问题会非常棘手。特别是SaaS在线企业级应用,你需要面对的问题会更加复杂(业务规则的分与合)。如果在做架构的时候,如果没有考虑到这些问题,后面的噩梦会很多。甚至你可能玩不转。
    SaaS应用其实并不简单,哪怕就是一个CRM在线应用,也是非常具有业务和技术含量的。根据我的分析,纷享销客和销售易虽然融了不少的资,但他们的系统架构还算不上真正意义下的云计算模式下的SaaS。金蝶,用友,速达的在线应用虽然没有深入研究,但通过他们用户的一些反馈,我感觉60%的可能性是伪云计算SaaS应用。当然,如果知道内幕的,可以告诉我。
    SaaS企业应用涉及的点非常多,而且很多点之间是有关联的,因此你必须在这些问题点的处理中不断地进行平衡,进行取舍。比如,采用面向服务(SOA)的架构,在一定程度上是可以减少一些复杂性,但这样一来也降低了应用系统的整体性,SOA的粒度和边界的划分就是非常重要的权衡点。
    在进行企业SaaS应用架构的时候,最好先弄清以下几个点:

    • 1) 数据隔离和数据分布的路由策略;
    • 2) 需要做哪些业务,是否需要做用户间进行资源共享和流程协作;
    • 3) 如果需要资源共享和协作,那么这个过程中的用户数据归属问题;
    • 4) 企业数据的规范性和统一性问题(这会涉及到参照,统计等后续一系列问题点);

    快捷键

    • 加粗 Ctrl + B
    • 斜体 Ctrl + I
    • 引用 Ctrl + Q
    • 插入链接 Ctrl + L
    • 插入代码 Ctrl + K
    • 插入图片 Ctrl + G
    • 提升标题 Ctrl + H
    • 有序列表 Ctrl + O
    • 无序列表 Ctrl + U
    • 横线 Ctrl + R
    • 撤销 Ctrl + Z
    • 重做 Ctrl + Y

    Markdown及扩展

    Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— [ 维基百科 ]

    使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

    本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考Github.

    表格

    Markdown Extra 表格语法:

    项目 价格
    Computer $1600
    Phone $12
    Pipe $1

    可以使用冒号来定义对齐方式:

    项目 价格 数量
    Computer 1600 元 5
    Phone 12 元 12
    Pipe 1 元 234

    定义列表

    Markdown Extra 定义列表语法:
    项目1
    项目2
    定义 A
    定义 B
    项目3
    定义 C

    定义 D

    定义D内容

    代码块

    代码块语法遵循标准markdown代码,例如:

    @requires_authorization
    def somefunc(param1='', param2=0):
        '''A docstring'''
        if param1 > param2: # interesting
            print 'Greater'
        return (param2 - param1 + 1) or None
    class SomeClass:
        pass
    >>> message = '''interpreter
    ... prompt'''

    脚注

    生成一个脚注1.

    目录

    [TOC]来生成目录:

    数学公式

    使用MathJax渲染LaTex 数学公式,详见math.stackexchange.com.

    • 行内公式,数学公式为:Γ(n)=(n1)!nN
    • 块级公式:

    x=b±b24ac2a

    更多LaTex语法请参考 这儿.

    UML 图:

    可以渲染序列图:

    Created with Raphaël 2.1.0张三张三李四李四嘿,小四儿, 写博客了没?李四愣了一下,说:忙得吐血,哪有时间写。

    或者流程图:

    Created with Raphaël 2.1.0开始我的操作确认?结束yesno
    • 关于 序列图 语法,参考 这儿,
    • 关于 流程图 语法,参考 这儿.

    离线写博客

    即使用户在没有网络的情况下,也可以通过本编辑器离线写博客(直接在曾经使用过的浏览器中输入write.blog.csdn.net/mdeditor即可。Markdown编辑器使用浏览器离线存储将内容保存在本地。

    用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览器或者其它异常情况下,内容不会丢失。用户再次打开浏览器时,会显示上次用户正在编辑的没有发表的内容。

    博客发表后,本地缓存将被删除。 

    用户可以选择 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。

    注意:虽然浏览器存储大部分时候都比较可靠,但为了您的数据安全,在联网后,请务必及时发表或者保存到服务器草稿箱

    浏览器兼容

    1. 目前,本编辑器对Chrome浏览器支持最为完整。建议大家使用较新版本的Chrome。
    2. IE9以下不支持
    3. IE9,10,11存在以下问题
      1. 不支持离线功能
      2. IE9不支持文件导入导出
      3. IE10不支持拖拽文件导入


    1. 这里是 脚注内容.
    展开全文
  • 论文研究-基于市盈率模型的风险投资企业价值评估方法研究.pdf, 文章主要从风险投资家的视角 ,运用市盈率模型对风险企业的股权价值进行估价 ,在选取市盈率的基础上 ,采用...
  • 最喜欢的一句话:今日事,今日毕 前期准备工作 企业级360°全方位用户画像:标签开发(前期准备工作) 价格敏感度模型-PSM PSM模型引入 点击下面链接了解大数据杀熟 人人憎恨的大数据杀熟你了解吗? 大数据杀熟”是否真...

    絮叨两句:
    博主是一名数据分析实习生,利用博客记录自己所学的知识,也希望能帮助到正在学习的同学们
    人的一生中会遇到各种各样的困难和折磨,逃避是解决不了问题的,唯有以乐观的精神去迎接生活的挑战
    少年易老学难成,一寸光阴不可轻。
    最喜欢的一句话:今日事,今日毕

                                                                                   前期准备工作

    企业级360°全方位用户画像:标签开发(前期准备工作)
                                                             价格敏感度模型-PSM

    PSM模型引入

    👇 点击下面链接了解大数据杀熟
    人人憎恨的大数据杀熟你了解吗? 大数据杀熟”是否真的存在?

    PSM模型在网游中的运用

    PSM(Price Sensitivity Measurement)模型是在70年代由Van Westendrop所创建,其目的在于衡量目标用户对不同价格的满意及接受程度,了解其认为合适的产品价格,从而得到产品价格的可接受范围。

    PSM的定价是从消费者接受程度的角度来进行的,既考虑了消费者的主观意愿,又兼顾了企业追求最大利益的需求。

    此外,其价格测试过程完全基于所取购买对象的自然反应,没有涉及到任何竞争对手的信息。

    虽然缺少竞品信息是PSM的缺陷所在,由于每个网络游戏均自成一个虚拟的社会体系,一般来说,其中每个道具或服务的销售均没有竞品(除非开发组自己开发了类似的道具或服务,产生了内部竞争),从这个角度来说,PSM模型比较适合用于网游中的道具或服务的定价。

    此外,该模型简洁明了,操作简单,使用非常方便。


    PSM模型实施具体步骤

    第一步:通过定性研究,设计出能够涵盖产品可能的价格区间的价格梯度表。

    该步骤通常对某一产品或服务追问被访者4个问题,并据此获得价格梯度表。
    梯度表的价格范围要涵盖所有可能的价格点最低和最高价格一般要求低于或高出可能的市场价格的三倍以上

    1. 便宜的价格:对您而言什么价格该道具/服务是很划算,肯定会购买的?
    2. 太便宜的价格:低到什么价格,您觉得该道具/服务会因为大家都可以随便用,而对自己失去吸引力(或对游戏造成一些不良影响)?
    3. 贵的价格:您觉得“有点高,但自己能接受”的价格是多少?
    4. 太贵的价格:价格高到什么程度,您肯定会放弃购买?

    第二步:取一定数量有代表性的样本,被访者在价格梯度表上做出四项选择:

    • 有点低但可以接受的价格
    • 太低而不会接受的价格
    • 有点高但可以接受的价格
    • 太高而不会接受的价格。

    第三步 :对所获得的样本数据绘制累计百分比曲线图,四条曲线的交点得出产品的合适价格区间以及最优定价点和次优定价点。

    如下图:
    对“便宜”和“太便宜”向下累计百分数(因为价格越低消费者越觉得便宜,即认为某价格便宜的消费者也会认为低于此价格的价格便宜)

    “贵”和“太贵”向上累计百分数(因为价格越高消费者越觉得贵,即认为某价格贵的消费者也会认为高于此价格的价格贵)能够得到四条累计百分比曲线

    “太便宜”和“贵”的交点意味着此价格能够让最多的人觉得“不会便宜到影响购买意愿,即使可能有点贵也是能够接受的”

    “便宜”和“太贵”的交点意味着此价格能够让最多的人觉得“不会贵到不能接受,还是挺划算的”

    因此这两个交点分别为价格区间的下限和上限。低于前者,消费者会因为担心“过于大众不能体现优越感,或会给游戏带来不好影响如游戏平衡性”而不愿购买;高于后者,消费者会认为价钱太高而不能接受

    一般来说,“太便宜”和“太贵”的交点作为最优价格点,因为在此处觉得“不过于便宜也不过于昂贵”的消费者最多

    但是也有人认为“便宜”和“贵”的交点是最优价格,因为该交点取得了“划算,肯定会买”及“贵,但能接受”的平衡点,是能让最多消费者满意的价格

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

    在这里插入图片描述

    PSM模型的缺陷

                                                          存在的问题                                                
    1. 只考虑到了消费者的接受率,忽视了消费者的购买能力,即只追求最大的目标人群数。但事实上,即使消费者觉得价格合理,受限于购买力等因素,也无法购买。

    1. 研究中消费者可能出于各种因素(比如让价格更低能让自己收益,出于面子问题而抬高自己能接受的价格等)有意或无意地抬高或压低其接受的价格。由于消费者知道虚拟世界中的产品(道具或服务)没有成本,其压低价格的可能性较高。

    1. 没有考虑价格变化导致的购买意愿(销量)变化。

    解决

    1. 为了避免购买力的影响, 问卷或访谈研究中要强调“定这个价格,以自己目前的情况是否会购买”,而非仅仅去客观判断该产品值多少钱。

    1. 为了解决玩家抬高或压低价格的问题,可以增大样本量,预期随机误差可以相互抵消。

    1. 仅仅从曲线获得最优价格,受到玩家压低或抬高价格的影响较大。由于该误差可能是系统误差,对此,可以用所获得的价格区间设计不同的价格方案,然后设计组间实验设计,每个参与研究的消费者只接触其中一种或几种价格方案,并对该价格方案下是否购买及购买数量做出决策,通过计算那种价格方案下玩家消费金钱量最高来分析出最佳价格方案。如下表。

    1. 通过前一条中提到的组间实验设计,可以计算出不同价格下玩家购买意愿的变化,从而得知价格调整会对整体收益带来的影响。此外,价格接受比例还可以作为消费者对某价格满意度的指标,用于计算某价格下企业该产品的良性收益。
      注意,我们的上述对策部分基于统计学和实验心理学理论,部分基于我们工作中的实践,欢迎大家讨论和优化。

    在这里插入图片描述

    真实案例:用KANO模型和PSM价格敏感度确定产品功能和定价

    今天和大家分享的是关于产品功能上线和合理定价的问题。

    记得一个产品姐姐在分享的时候说过一句话受益匪浅“一个产品从出生到长大,要先保证能用,再保证好用。”是的,在产品功能选择上,什么功能是保证用户能用的,什么功能是为了让用户好用的,每类功能会带给用户什么样的体验。这个问题一直也是我们在做产品过程中不断整理和思考的,用户说什么就做什么,功能丰富且齐全,但最终还是做死了的例子不胜枚举。那么一个新的功能到底上不上,这个功能/服务如果收费,价格应该是怎样的。今天就来给大家分享一下关于我之前项目遇到的这些问题和我们的解决办法。

    功能到底要不要上——KANO模型

    KANO模型_:东京理工大学教授狩野纪昭(Noriaki Kano)发明的对用户需求分类优先排序的有用工具,以分析用户需求对用户满意的影响为基础,体现了产品性能和用户满意之间的非线性关系。

    根据不同类型的质量特性与顾客满意度之间的关系,狩野教授将产品服务的质量特性分为五类:

    基本(必备)型质量——Must-be Quality/ Basic Quality
    期望(意愿)型质量——One-dimensional Quality/ Performance Quality
    兴奋(魅力)型质量—Attractive Quality/ Excitement Quality
    无差异型质量——Indifferent Quality/Neutral Quality
    反向(逆向)型质量——Reverse Quality,亦可以将 ‘Quality’ 翻译成“质量”或“品质”。
    前三种需求根据绩效指标分类就是基本因素、绩效因素和激励因素。

    简单说就是N个功能摆在这里,我们如何判定该功能符合基本型需求、期望型需求还是兴奋型需求?
    KANO模型就可以帮助我们解决这个问题,但是这里有必要说一下,评定一个需求的优先级绝对不是仅仅根据这个就直接判定的


    直接分享我之前的项目:
    项目背景:因为临近一个关键节日,我司产品希望能增加功能A、功能B、功能C、功能D、功能E,那么如何判定哪一些功能是可以排在前面,哪些可以稍微排后?我们设置了调研问卷来让用户对这5个功能进行评价。具体问卷形式如下图。
    (为保护我司隐私,对具体内容进行隐藏。啊哈哈,我价值观很正的!)

    在这里插入图片描述
    这样一份问卷收到之后呢,你将会得到这样一个格式的数据。数据已经过处理。
    在这里插入图片描述
    这是一份“如果提供功能A五选项的选择人数如果不提供功能A五选项的选择人数的交叉表。分别是交叉选择人数和人数在该选项总人数的占比。
    这个图表怎么用嘞。这下我就必须要找一个解释图上来了。请见下图:

    在这里插入图片描述
    大家看到了这里面AQIRMO之类的标记了,后续的所有指数都是这些类别的求和。
    比如:

    • 所有分布在Q的格子里的值相加,就是Q的总体系数。
    • 所有R的格子里的值相加,就是R的总体系数。
    • 和我上面一张数据图一一对应。解释的够清楚了昂~
      下面解释一下这些神奇AQIRMO都是什么意思:
      A–魅力属性
      O–期望属性(一维属性)
      M–必备属性
      I –无差异属性(次要属性)
      R –反向属性
      Q–可疑结果
      得分最高的属性就是这个功能的最后属性归属。

    最后,增加了这个功能或者没有这个功能又会对用户满意度造成什么影响呢?
    这就是better-worse系数
    增加后的满意系数(better):(魅力属性+期望属性)/(魅力属性+期望属性+必备属性+无差异因素)
    • 消除后的不满意系数(worse):(期望属性+必备属性)/(魅力属性+期望属性+必备属性+无差异因素×(-1)
    • 注:系数越接近于1或-1,说明对提供后产生满意或不提供后产生不满的影响越大
    • 就酱紫,我们得到了这样的一些系数。就可以画一个逼格比较高的象限图啦。横坐标worse系数,纵坐标better系数。把四类属性分布于各个象限中。这个是用SPSS做的散点图。

    在这里插入图片描述
    • 综上所述,我们就确认了功能ABCDE的各个属性归类和优先级啦~昂。功能的优先级确定就酱紫结束了。

    确定了功能/服务,该如何为其定价

    不是每个功能的出现都是为了实现用户更好的操作而存在的,比如购物车、收藏夹之类的功能。还有一些功能的存在是为了能够赚钱的!是不是很直接!是不是说到了很多人的心里去!比如说卖东西寄快递,卖家愿意给你送货上门,为你提供这个功能虽然是为了用户体验更好,说到底还是起码不赚钱但不亏本的。那么快递费定价多少合适?(我就是举个例子,不要告诉我快递费多少钱是快递公司说的算)就我司这次项目中,有一些功能是需要付一些费用的,那么要付多少钱能够保本,多少钱可以盈利,多少钱用户就觉得你有病了呢?比起拍脑袋猜,或者设置不同价格用市场来验证,我更建议在最开始的时候能确定一个价格范围值。那么用户接受的价格到底在哪个区间呢?
    这里就给大家隆重介绍——PSM价格敏感度测试
    简单说PSM就是帮助你能够获取到一个功能或者服务的用户可接受价格区间,并确定最佳价格。为了保护我司的数据。我来举个朋友卖水果的定价案例。一盒现切的水果拼盘,定价在多少最合适呢?市场容忍度是多少呢?首先,我们做了用户调研。问卷结构见下图。

    在这里插入图片描述

    这里就是问卷的结构啦。用户对每一档价格进行4个选项的评价,价格从最低到最高,最好极值设置的高一点点避免天花板和地板效应。区间取得尽量细一点,这样后面得到的结果会比较精准。
    回收到问卷之后,我们将会得到这样一份数据,再来一波图。

    在这里插入图片描述

    我们得到了各类价格区间的“比较便宜太便宜有点贵可以忍太贵了放弃”的频率值。
    然后每个选项都计算累计总和,比如:比较便宜右边,是从下往上的累计总和。为什么是从下至上求和呢?
    因为,如果觉得8-10块都是比较便宜的话,5-1块钱当然都会觉得便宜啊。
    同理,如果觉得1-2块钱都贵的话,3-10块肯定都是觉得贵啊。
    这里就是需要注意的点啦!很便宜和太便宜都是从下往上求和的,而有点贵和太贵了都是从上往下求和的。
    求好了和值。计算当前这一行的和值的累计百分比(本行累计和值/累计总和)就阔以啦。举例:比较便宜列,累计和值=6,百分比=6/20;累计和值=13,百分比=13/20.以此类推。酱紫是不是就有4列百分比了?然后肿么做呢?——画图!

    在这里插入图片描述
    数据是我为了演示随便填的,图画的有点丑。好好统计出来的数据应该画的比较好看。
    P1–比较贵太便宜曲线交叉点
    P2–太贵
    太便宜曲线交叉点
    P3–比较便宜太贵交叉点
    P4–比较便宜
    比较贵交叉点

    可接受价格范围:
    P1–P3两点之间的价格都是用户可接受价格
    低于P1——用户会认为太便宜而怀疑质量问题,高于P3——用户会觉得太贵而放弃
    可接受价格点:P4——在此点,用户觉得价位太高的比例和价位太低的比例相等
    最优价格点:P2——在此点,用户觉得价格既不会太贵也不会太便宜
    就是这样的计算之后,我们将会得到最优价格。并且在这样一个合理的价格范围里去不断调试。这相对于直接拍脑袋来说,真的是靠谱多了呢~

    参考资料:

    1. 东京理工大学教授狩野纪昭(Noriaki Kano)和Fumio Takahashi《质量的保健因素和激励因素》(Motivator and Hygiene Factor in Quality)
    2. 周达,梁英瑜,贺成功.基于KANO模型的顾客需求分析——以校园咖啡吧商品及服务项目筛选为例
    3. PSM价格敏感度测试——2006.7.20 (百度文库)

    添加标签

    价格敏感度模型Price Sensitivity Meter
    有时在实际业务中,会把用户分为3-5类,
    比如分为极度敏感、较敏感、一般敏感、较不敏感、极度不敏感。
    然后将每类的聚类中心值与实际业务所需的其他指标结合,最终确定人群类别,判断在不同需求下是否触达或怎样触达。

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

    价格敏感度规则:inType=HBase##zkHosts=192.168.10.20##zkPort=2181##hbaseTable=tbl_orders##family=detail##selectFields=memberId,orderSn,orderAmount,couponCodeValue
    

    业务代码

    价格敏感度模型

    psm=优惠订单占比 + 平均优惠金额占比 + 优惠总金额占比


    优惠订单占比=优惠的总次数/订单总次数

    平均优惠金额占比=优惠金额平均数/平均每单应收金额

    ------ 优惠金额平均数= 优惠总金额/优惠的总次数

    ------平均每单应收金额= 订单应收总金额/订单总次数

    优惠总金额占比=优惠总金额/订单应收总金额


    由上面可以得出:
    ------优惠的总次数
    ------优惠总金额
    ------订单总次数
    ------订单应收总金额


    package cn.itcast.userprofile.up24.newexcavate
    
    import cn.itcast.userprofile.up24.public.PublicStaticCode
    import org.apache.spark.ml.clustering.KMeans
    import org.apache.spark.ml.feature.VectorAssembler
    import org.apache.spark.sql.{DataFrame, SparkSession}
    
    import scala.collection.immutable
    /**
     * Author 真情流露哦呦
     * Desc 价格敏感度模型Price Sensitivity Meter
     * 有时在实际业务中,会把用户分为3-5类,
     * 比如分为极度敏感、较敏感、一般敏感、较不敏感、极度不敏感。
     * 然后将每类的聚类中心值与实际业务所需的其他指标结合,最终确定人群类别,判断在不同需求下是否触达或怎样触达。
     * 比如电商要通过满减优惠推广一新品牌的麦片,
     * 此时可优先选择优惠敏感且对麦片有消费偏好的用户进行精准推送,
     * 至于优惠敏感但日常对麦片无偏好的用户可暂时不进行推送或减小推送力度,
     * 优惠不敏感且对麦片无偏好的用户可选择不进行推送。
     * 可见,在实际操作中,技术指标评价外,还应结合业务需要,才能使模型达到理想效果。
     * //价格敏感度模型
     * psm=优惠订单占比+平均优惠金额占比+优惠总金额占比
     * 优惠订单占比 --->    (优惠的次数/购买次数)
     *
     * 平均优惠金额占比 --->  (优惠金额平均数/平均每单应收金额)
     *     优惠金额平均数=   优惠总金额/优惠的次数
     *     平均每单应收金额=  订单应收总金额/购买次数
     * 优惠总金额占比 --->   ( 优惠总金额/订单的应收总金额)
     *目的:
     * 优惠的次数
     * 购买次数
     *优惠总金额
     *订单的应收金额
     */
    
    
    object PSM extends  PublicStaticCode{
      override def SetAppName: String = "PSM"
    
      override def Four_Name: String = "价格敏感度"
      /**
       * 开始计算
       *inType=HBase##zkHosts=192.168.10.20##zkPort=2181##
       * hbaseTable=tbl_orders##family=detail##selectFields=memberId,orderSn,orderAmount,couponCodeValue
       * @param five  MySQL中的5级规则 id,rule
       * @param tblUser 根据selectFields查询出来的HBase中的数据
       * @return userid,tagIds
       */
    
      override def compilerAdapterFactory(spark: SparkSession, five: DataFrame, tblUser: DataFrame): DataFrame = {
        import spark.implicits._
        import scala.collection.JavaConversions._
        import org.apache.spark.sql.functions._
    
    //    five.show()
    
        /**
         * +------+----+
         * |tagsId|rule|
         * +------+----+
         * |    51|   1|
         * |    52|   2|
         * |    53|   3|
         * |    54|   4|
         * |    55|   5|
         * +------+----+
         */
    //    tblUser.show()
    
        /**
         * orderSn	订单号
         * orderAmount	订单总金额,等于商品总金额+运费
         * couponCodeValue	优惠码优惠金额
         * +---------+-------------------+-----------+---------------+
         * | memberId|            orderSn|orderAmount|couponCodeValue|
         * +---------+-------------------+-----------+---------------+
         * | 13823431| ts_792756751164275|    2479.45|           0.00|
         * |  4035167| D14090106121770839|    2449.00|           0.00|
         * |  4035291| D14090112394810659|    1099.42|           0.00|
         * |  4035041| fx_787749561729045|    1999.00|           0.00|
         * | 13823285| D14092120154435903|    2488.00|           0.00|
         * |  4034219| D14092120155620305|    3449.00|           0.00|
         * |138230939|top_810791455519102|    1649.00|           0.00|
         * |  4035083| D14092120161884409|       7.00|           0.00|
         */
        //0.定义常量
        val psmScoreStr: String = "psmScore"
        val featureStr: String = "feature"
        val predictStr: String = "predict"
    
    
    
        //1.先将用户每个订单是否优惠了进行处理
        /**
         * state 优惠订单为1, 非优惠订单为0
         * 在订单没有优惠的时候,金额为0.00
         */
        var state=when(col("couponCodeValue").cast("Int")===0.00,0)
          .when(col("couponCodeValue").cast("Int")=!=0.00,1) as "state"
        /**
         * practicalAmount:订单应收总金额
         *
         */
          var practicalAmount='orderAmount+'couponCodeValue as "pa"
        val order_State: DataFrame = tblUser.select('memberId, practicalAmount, 'orderAmount,'couponCodeValue, state)
    //    order_State.show()
    
        /**
         * memberId 用户Id
         * pa	订单应收总金额
         * orderAmount	订单总金额
         * couponCodeValue	优惠码优惠金额
         * state 订单是否优惠
         * +---------+-------+-----------+---------------+-----+
         * | memberId|     pa|orderAmount|couponCodeValue|state|
         * +---------+-------+-----------+---------------+-----+
         * | 13823431|2479.45|    2479.45|           0.00|    0|
         * |  4035167| 2449.0|    2449.00|           0.00|    0|
         * |  4035291|1099.42|    1099.42|           0.00|    0|
         * |  4035041| 1999.0|    1999.00|           0.00|    0|
         * | 13823285| 2488.0|    2488.00|           0.00|    0|
         * |  4034219| 3449.0|    3449.00|           0.00|    0|
         * |138230939| 1649.0|    1649.00|           0.00|    0|
         */
    
        /**
         *优惠的次数
         *购买次数
         *优惠总金额
         *订单的应收金额
         * Discount:优惠次数
         * PurchaseCount:购买次数
         * TotalAmount:优惠总金额
         * TotalReceivable订单的应收总金额
         */
        var disCount=sum('state) as "disCount"
        var purchaseCount=count('state) as "purchaseCount"
        var totalAmount=sum('couponCodeValue) as "totalAmount"
        var totalReceivable=sum('pa) as "totalReceivable"
    
        val psm_Score = order_State.groupBy('memberId).agg(disCount, purchaseCount, totalAmount, totalReceivable)
    //    psm_Score.show()
        /**
         * disCount:优惠次数
         * purchaseCount:购买次数
         * totalAmount:优惠总金额
         * totalReceivable:订单的应收总金额
         * +---------+--------+-------------+-----------+------------------+
         * | memberId|disCount|purchaseCount|totalAmount|   totalReceivable|
         * +---------+--------+-------------+-----------+------------------+
         * |  4033473|       3|          142|      500.0|         252430.92|
         * | 13822725|       4|          116|      800.0|         180098.34|
         * | 13823681|       1|          108|      200.0|          169946.1|
         * |138230919|       3|          125|      600.0|240661.56999999998|
         * | 13823083|       3|          132|      600.0|         234124.17|
         */
        /**
         * psm=优惠订单占比+平均优惠金额占比+优惠总金额占比
         * 优惠订单占比 --->    (优惠的次数/购买次数)
         *
         * 平均优惠金额占比 --->  (优惠金额平均数/平均每单应收金额)
         *     优惠金额平均数=   优惠总金额/优惠的次数
         *     平均每单应收金额=  订单应收总金额/购买次数
         * 优惠总金额占比 --->   ( 优惠总金额/订单的应收总金额)
         */
        //优惠订单占比
        var  DiscountProportion='disCount / 'purchaseCount
        //平均优惠金额占比
        var  DiscountAverageProportion=('totalAmount/'disCount)/('totalReceivable/'purchaseCount)
        //优惠总金额占比
        var TotalDiscountProportion='totalAmount/'totalReceivable
        //psm=优惠订单占比+平均优惠金额占比+优惠总金额占比
        var psm=DiscountProportion+DiscountAverageProportion+TotalDiscountProportion as "psmScore"
    
        /**
         * +--------+--------+-------------+-----------+---------------+
         * |memberId|disCount|purchaseCount|totalAmount|totalReceivable|
         * +--------+--------+-------------+-----------+---------------+
         * |13822841|       0|          113|        0.0|      205931.91|
         * +--------+--------+-------------+-----------+---------------+
         * 优惠订单占比 --->    (优惠的次数/购买次数)
         * disCount:优惠次数
         * purchaseCount:购买次数
         * purchaseCount/ disCount
         * 113 / 0  (除数不能为0)
         * 所以要进行判断 where('psmScore.isNotNull)
         */
        val psm_Result = psm_Score.select('memberId, psm).where('psmScore.isNotNull)
    //    psm_Result.show()
        /**
         * +---------+-------------------+
         * | memberId|           psmScore|
         * +---------+-------------------+
         * |  4033473|0.11686252330855691|
         * | 13822725|0.16774328728519597|
         * | 13823681|0.13753522440350205|
         * |138230919| 0.1303734438365045|
         * | 13823083| 0.1380506927739941|
         * | 13823431|0.15321482374431458|
         * |  4034923|0.13927276336831218|
         * |  4033575|0.11392752155030905|
         */
        //3.聚类
        //为方便后续模型进行特征输入,需要部分列的数据转换为特征向量,并统一命名,VectorAssembler类就可以完成这一任务。
        //VectorAssembler是一个transformer,将多列数据转化为单列的向量列
        val vectorDF = new VectorAssembler()
          .setInputCols(Array("psmScore"))
          .setOutputCol(featureStr)
          .transform(psm_Result)
    //    vectorDF.show()
        /**
         * +---------+-------------------+--------------------+
         * | memberId|           psmScore|             feature|
         * +---------+-------------------+--------------------+
         * |  4033473|0.11686252330855691|[0.11686252330855...|
         * | 13822725|0.16774328728519597|[0.16774328728519...|
         * | 13823681|0.13753522440350205|[0.13753522440350...|
         * |138230919| 0.1303734438365045|[0.1303734438365045]|
         * | 13823083| 0.1380506927739941|[0.1380506927739941]|
         * | 13823431|0.15321482374431458|[0.15321482374431...|
         * |  4034923|0.13927276336831218|[0.13927276336831...|
         * |  4033575|0.11392752155030905|[0.11392752155030...|
         */
    
        val ks: List[Int] = List(2,3,4,5,6,7,8)
        //集合内误差平方和:Within Set Sum of Squared Error, WSSSE
        //对于那些无法预先知道K值的情况,可以通过WSSSE的计算构建出 K-WSSSE 间的相关关系,从而确定K的值,
        //一般来说,最优的K值即是 K-WSSSE 曲线拐点Elbow的位置
        //当然,对于某些情况来说,我们还需要考虑K值的语义可解释性,而不仅仅是教条地参考WSSSE曲线
        /*val WSSSEMap: mutable.Map[Int, Double] = mutable.Map[Int,Double]()
        for(k<- ks){
          val kMeans: KMeans = new KMeans()
            .setK(k)
            .setMaxIter(20)//最大迭代次数
            .setFeaturesCol(featureStr) //特征列
            .setPredictionCol(predictStr)//预测结果列
          val model: KMeansModel  = kMeans.fit(vectorDF)
          val WSSSE: Double = model.computeCost(vectorDF)
          WSSSEMap.put(k,WSSSE)
        }
        println("训练出来的K对应的WSSSE如下:")
        println(WSSSEMap)
        //训练出来的K对应的WSSSE如下:
        //Map(8 -> 0.1514833272915443, 2 -> 1.2676013396202386, 5 -> 0.3205627518783058, 4 -> 0.4336353113133625, 7 -> 0.16381158476261476, 3 -> 0.8254005284535515, 6 -> 0.20131609978279763)
        val mined: (Int, Double) = WSSSEMap.minBy(_._2)
        val minK: Int = mined._1
        println("训练出来的WSSSE值最小的K是:"+minK)
        //一般来说,同样的迭代次数和算法跑的次数,这个值越小代表聚类的效果越好。
        //但是在实际情况下,我们还要考虑到聚类结果的可解释性,不能一味的选择使 computeCost 结果值最小的那个 K
        */
        //4.训练模型
        val model = new KMeans()
          .setK(5)
          .setSeed(10)
          .setMaxIter(30)
          .setFeaturesCol(featureStr)
          .setPredictionCol(predictStr)
          .fit(vectorDF)
        //5.预测
        val result: DataFrame = model.transform(vectorDF)
    //    result.show()
        /**
         * +---------+-------------------+--------------------+-------+
         * | memberId|           psmScore|             feature|predict|
         * +---------+-------------------+--------------------+-------+
         * |  4033473|0.11686252330855691|[0.11686252330855...|      0|
         * | 13822725|0.16774328728519597|[0.16774328728519...|      0|
         * | 13823681|0.13753522440350205|[0.13753522440350...|      0|
         * |138230919| 0.1303734438365045|[0.1303734438365045]|      0|
         * | 13823083| 0.1380506927739941|[0.1380506927739941]|      0|
         * | 13823431|0.15321482374431458|[0.15321482374431...|      0|
         * |  4034923|0.13927276336831218|[0.13927276336831...|      0|
         * |  4033575|0.11392752155030905|[0.11392752155030...|      0|
         * | 13823153|0.15547466292943982|[0.15547466292943...|      0|
         * |  4034191|0.11026694172505715|[0.11026694172505...|      0|
         * |  4033483|0.15976480445774954|[0.15976480445774...|      0|
         * |  4033348|0.13600092999496663|[0.13600092999496...|      0|
         * |  4034761|0.13114429909634118|[0.13114429909634...|      0|
         * |  4035131|0.39147259141650464|[0.39147259141650...|      2|
         * | 13823077|0.12969603277907024|[0.12969603277907...|      0|
         * |138230937|0.15212864394723766|[0.15212864394723...|      0|
         * |  4034641|0.14954686999636585|[0.14954686999636...|      0|
         * |        7|0.13128367494800738|[0.13128367494800...|      0|
         * |138230911|0.11824736419948352|[0.11824736419948...|      0|
         * |  4035219|0.08062873693483025|[0.08062873693483...|      3|
         * +---------+-------------------+--------------------+-------+
         */
        //问题: 每一个簇的ID是无序的,但是我们将分类簇和rule进行对应的时候,需要有序
        //6.按质心排序,质心大,该类用户价值大
        //[(质心id, 质心值)]
        val center = for (i <- model.clusterCenters.indices) yield (i, model.clusterCenters(i).toArray.sum)
        val centerSortBy: immutable.IndexedSeq[(Int, Double)] = center.sortBy(_._2).reverse
    //    centerSortBy.foreach(println)
        /**
         * (1,0.5563226557645843)
         * (2,0.31754213552513205)
         * (4,0.21281283437093323)
         * (0,0.1320103555777084)
         * (3,0.08401071578741981)
         */
        //[(质心id, rule值)]
        val centerAndRule = for (i <- centerSortBy.indices) yield (centerSortBy(i)._1, i + 1)
        val centerDF = centerAndRule.toDF(predictStr, "rule")
    //    centerDF.show()
        /**
         * +-------+----+
         * |predict|rule|
         * +-------+----+
         * |      1|   1|
         * |      2|   2|
         * |      4|   3|
         * |      0|   4|
         * |      3|   5|
         * +-------+----+
         */
        //7.将rule和5级规则进行匹配
        val ruleTagDf = centerDF.join(five, "rule").select(predictStr, "tagsId")
    //    ruleTagDf.show()
    
        /**
         * +---------+-------------------+--------------------+-------+
         * | memberId|           psmScore|             feature|predict|
         * +---------+-------------------+--------------------+-------+
         * |  4033473|0.11686252330855691|[0.11686252330855...|      0|
         * | 13822725|0.16774328728519597|[0.16774328728519...|      0|
         * | 13823681|0.13753522440350205|[0.13753522440350...|      0|
         */
        /**
         * +-------+------+
         * |predict|tagsId|
         * +-------+------+
         * |      1|    51|
         * |      2|    52|
         */
    //        val new_Tag = ruleTagDf.join(result, ruleTagDf.col("predict")===result.col("predict"))
    //    new_Tag.show()
      val ruleMap = ruleTagDf.map(t => {
      val predict = t.getAs("predict").toString
      val tagsId = t.getAs("tagsId").toString
      (predict, tagsId)
    }).collect().toMap
        println(ruleMap)
    
        var rule_UDF=udf((pre:String)=>{
          val tag = ruleMap(pre)
          tag
        })
        val new_Tag = result.select('memberId as "userId", rule_UDF('predict).as("tagsId"))
        /**
         * +---------+------------+
         * | memberId|UDF(predict)|
         * +---------+------------+
         * |  4033473|          54|
         * | 13822725|          54|
         * | 13823681|          54|
         * |138230919|          54|
         * | 13823083|          54|
         * | 13823431|          54|
         * |  4034923|          54|
         * |  4033575|          54|
         * | 13823153|          54|
         * |  4034191|          54|
         * |  4033483|          54|
         * |  4033348|          54|
         * |  4034761|          54|
         * |  4035131|          52|
         * | 13823077|          54|
         * |138230937|          54|
         * |  4034641|          54|
         * |        7|          54|
         * |138230911|          54|
         * |  4035219|          55|
         * +---------+------------+
         */
        new_Tag
      }
    
      def main(args: Array[String]): Unit = {
        startMain()
      }
    }
    
    

    使用K-Means算法进行挖掘的标签:
    企业级用户画像: 用户活跃度模型-RFE
    企业级用户画像:开发RFM模型实例


    以上就是价格敏感度模型-PSM
    若有错误及时私信我,立马修改
    如能帮助到你或对大数据有兴趣的可以关注一下,希望能点个赞支持一下谢谢!
    在这里插入图片描述

    展开全文
  • TCG可信计算技术的信任链模型由于存在以上分析的内在缺陷,TXT技术由于度量不彻底问题,事实上造成了可信计算技术在应用上多年徘徊不前的尴尬局面。因而TCG技术从十多年以前提出最初理念,TXT技术推出也有不少年头了...
    目前信息技术的使用正在开始转向云服务,不可避免的对云安全的需求随之而来。云安全有许多含义。在公有云方面,用户会担心受网络稳定性、带宽速度所影响的服务体验,解决这些问题可以理解为提供一种初级的安全保障。而入侵检测、病毒控制和防火墙等等传统网络安全技术手段可以进而保证云端免遭网络来自外部入侵的威胁。
    

    云计算中除了Web2.0,搜索引擎,电子商务,社交网络应用等等终端用户不愿意或不习惯付费使用的服务之外(让我们姑且认为云计算广义上含有这些内容,比如云杀毒,云拼音,云游戏,等诸如此类带有云的叫法),剩下来能够对终端用户真正提供价值的-----真正的含义是能够让用户愿意掏腰包购买-----是处理用户私有数据的服务。个人认为只有提供处理用户私有数据的服务才算是真正意义(狭义)上的云计算。顺便提一句:用户不付费使用的广义云服务具有一个共性:即服务提供商处理的数据是它自己的而不是用户的,这也是为何那些广义云服务提供商往往通过商务或业务安排(比如广告,餐饮,购物等)来获得服务收入。狭义云计算服务处理用户私有数据则不可避免要保障用户数据的安全。

    除了第一段提到的传统网络安全技术手段之外,如何保证用户私有数据在云计算数据中心接受处理服务时不被非法非授权访问,不仅要免遭源自于外部入侵的威胁,特别还要防范可能由云服务数据中心系统管理人员发起的内部攻击所造成的危害,这才是云计算安全需求有别于传统网络安全需求之处:传统网络安全偏重或仅须防范来自于外部的攻击,云安全则一定还要有手段防范内部攻击。对于企业来说,在云服务环境中要掌握控制管理措施:不仅要明确知晓谁有权限访问数据,并有能力在客户端有效管理和控制数据的访问策略。这些都是企业采用云服务必须考虑的问题。

    有人说云安全是服务安全,是服务诚信问题,我同意这样的说法。传统诚信的建立一般是靠服务提供商长期提供优质可靠服务的历史而建立起来的。但云计算还在“婴儿”时期,所以这个长期历史考察还有待时日,工业界等不及。通过可信第三方认证方法可以加速诚信的建立。这方面相关的技术是可信计算。可信计算的核心是一个装在物理计算平台上的硬件模块叫做可信平台模块TPM(Trusted Platform Module),又叫做基于硬件的信任根(Hardware Based Root of Trust)。这个TPM硬件模块是打不开,绕不过的,里面有密码算法,从外部无法影响模块内部由密码算法所制定安全策略的执行,所以TPM信任根可以理解为服务平台上的一个可信第三方,能够通过由密码学方法强制执行的安全策略,确保平台服务提供方与服务使用方的利益。云服务数据中心,比如系统管理员,如果想要通过不当方法获取用户数据,如果违反由硬件信任根所设定的安全策略,他是无法操作的。TPM信任根是一个带有私钥的硬件,相对应的公钥可以让一个可信第三方做认证,就是通常公钥认证的方法,可信第三方认证方可以是持有由政府或工业标准组织颁发资质的服务商。当然,云安全也需要有一些法律框架层面的做法来制定游戏规则,激励云服务商提供可信服务,提高攻击的成本。所以,可信计算是解决一个诚信问题的技术手段,通过技术手段证明云服务提供商所采用的安全信息处理方法值得信任。从多方面来看可信计算技术应用于加强云安全是一个方向,是增加服务方诚信的一个有效方法。配备有可信计算技术强制的安全策略执行,法律框架层面制定的服务规则也变得容易,具有可操作性。

    云计算数据中心广泛使用虚拟化计算平台,这个虚拟化架构上的VMM,叫做类型1 虚拟机监控器(Type 1 Hypervisor),又叫做Bare-metal(直接跑在硬件上的)Hypervisor,它的系统优先权很高,它又是一段静态代码,所以它可以被可信计算技术“度量”,也就是对二进制代码取哈希值,将结果存入TPM。经过度量以后我们可以说,比如在公开源代码的情况,这个VMM是一个玻璃的盒子,是透明的,如有设计错误可以比较容易找出来,而度量呢,实际上是把玻璃盒子硬化形成了一个钢化玻璃的盒子。度量完了以后就不能再更改了,改过的东西是不会通过平台报告的。客户端用户希望你服务端那边跑的是一个什么什么版本的VMM,是不是我同意的版本,里面是否可能存在漏洞,攻击者能不能去利用它,这些用户关心的的问题都可以通过可信平台报告方法让客户端用户使用公钥验证方法得到验证确认。公钥验证方法还得到可信第三方颁发证书得到认证,这就是采用技术手段让用户验证确认服务方的诚信度。

    在采用虚拟化架构的云计算数据中心里用户租用虚拟机处理数据,一个虚拟机只是一堆数字,不用的时候就存放在数据中心磁盘上。和物理硬件机器一样,虚拟机中不可避免保存有用户秘密信息,比如最起码要有用户登录所需的密钥或证书(Crypto Credential),否则数据中心就连用户身份都无法识别区分。既然虚拟机只不过是一堆数字,虚拟机中的用户秘密也是作为数字以明文的形式存储在外部存储器上的。与用户持有并通常会妥善保管自己的物理机器时情况不同,在云计算情况用户的虚拟机是以数字形式存储在数据中心磁盘上。所以虚拟机中的用户秘密信息,若不加以保护,则是以明文形式直接暴露在数据中心磁盘上的。攻击者可以简单从磁盘拷贝获得用户虚拟机,然后换一台主宿虚拟架构平台就可启动使用他人的虚拟机,进而非法获取用户私密数据。我们需要提醒:拷贝虚拟机至另一虚拟架构上运行,这是一种十分简单容易得逞的攻击技术,云计算数据中心虚拟化计算平台必须采取有效手段防止此类简单攻击。然而根据我们调研了解,至今工业界在云安全方面尚未推出实用有效的虚拟化安全产品或解决方案可以防范此类简单的虚拟机拷贝攻击。

    将可信计算技术应用于虚拟化计算平台提供安全服务,比如防止上述拷贝用户客体虚拟机的简单攻击,可信计算技术十分有效。用户客体虚拟机中的秘密,比如密钥,可以由主宿物理服务器上的可信平台模块TPM保护起来。用户虚拟机可以设计成压根不含有任何用户秘密信息。如果将这样的用户虚拟机拷贝到另一台主宿虚拟架构上,则或者由于该主宿虚拟架构根本不配备有可信计算技术,或者由于支撑该主宿虚拟架构的硬件信任根不同于原宿主虚拟架构的信任根因而不含有被拷贝客体虚拟机的用户秘钥,无论哪一种情况,被拷贝的用户虚拟机不能正常跑起来。即便攻击者通过重置虚拟机的credential 强行让它跑起来,或直接分析该虚拟机映像文件,也因为该虚拟机中没有相应密钥而无法解密虚拟机中被原主宿虚拟化架构下硬件信任根所加密的用户数据。

    现在让我们转而讨论可信计算技术的问题,包括可信计算集团TCG标准与Intel公司的可信执行技术TXT。国内外在可信云计算技术方面尚处于依赖从硬件信任根向上逐级度量系统软件栈中每一软件,所谓建立信任链的方法(TCG方法)。此方法如果限于应用至系统底层软件,比如类型1虚拟机监控器,还是可行的。这是因为此类系统软件,或位于此类系统之下信任链中更低层的系统软件,具有静态、不含用户态系统配置数据、无对外通信功能等“简单”性质。度量这样具有“简单”性质的软件具有确定性,所以可以很容易检查度量结果。然而一旦一个系统软件开始具有“非简单”性质,比如动态代码(如使用动态联编库连接外设驱动器),含有用户态系统配置数据(如需要配置可信第三方IP地址用以下载认证证书等),或可以与外部世界通信(如在通信端口收发解析IP包),诸如此类等等“非简单”性质,则再对其做TCG意义上的软件度量就几乎会失去软件度量原本定义、设计所赋予的含义。单说系统配置这一件事,就需要人的参与才可能准确完成。所谓无人值守云数据中心的设想,大概可以用共产主义理想来比拟吧,似乎比人工智能更具野心,个人感觉应该具有自动判定停机问题那样的难度。具体将该问题映射到虚拟化架构上,比如Xen VMM的Dom0,ESX VMM的Service Console,等操作系统就属于此类系统软件。请注意此类系统不可避免需要人工(系统管理员)参与才能完成系统配置工作。若采用TCG可信计算方法对其做度量,由于不可能对人的不可靠行为做度量,此类系统的行为,即便应用TCG可信计算方法度量后,仍然是不可确定的。又由于此类系统专门用于部署、管理虚拟架构上其它虚拟机,处于TCG可信计算方法期望建立的信任链之中间要害部位,所以它们的不确定性导致了所期望建立的信任链恰恰断裂于此处。Intel公司已经认识到了TCG可信计算方法在这方面的缺陷,推出的TXT技术仅强调可信度量链终止于所谓的“度量过的启动环境”(Measured Launch Environment,MLE),这个MLE大致是一个Type 1 Hypervisor。个人看法:在Type 1虚拟化架构上采用TCG可信计算方法逐层度量系统软件建立信任链直至客体虚拟机(包括如IBM Research推出的“vTPM“系统架构中的后端服务vTPM虚拟机),用TCG这种“强攻”(Brute Force)度量方法来建立可信软件环境应该属于说起容易做到难的事情。建立可信软件计算环境,尤其是在虚拟架构上,如何穿透不可度量的“非简单”性质服务系统(service console),至今仍还是一个科技攻关难题。严格讲ESX(Type 1),KVM(Type 2)这一类宏 hypervisors,也因为含有外设驱动,通信等等功能,也不再具有“简单”可度量性质。还是个人看法:若在虚拟架构上退而求其次,采用Intel TXT做法将度量链终止于MLE,则Type 1 Hypervisor中属于轻量级的Xen VMM最具有可信计算的可度量意义,应属于实现可信虚拟架构的首选VMM。但是TXT技术仅将有效软件度量终止于MLE这样的底层系统,无法让可信软件环境旁路掉Service Console这类不可度量系统而达到用户客体虚拟机(也无法达到IBM推出的vTPM后端服务虚拟机),我们所以说:在虚拟架构上建立可信云计算环境是:“革命尚未成功,同志仍需努力!”

    TCG可信计算技术的信任链模型由于存在以上分析的内在缺陷,TXT技术由于度量不彻底问题,事实上造成了可信计算技术在应用上多年徘徊不前的尴尬局面。因而TCG技术从十多年以前提出最初理念,TXT技术推出也有不少年头了,迄今未能取得商业上成功的应用。这个问题已经成为实现可信虚拟化云计算数据中心的瓶颈。

    道里云公司自主创新研究开发,提出并实现了一种叫做“无信任链可信计算技术”,专门针对TCG技术可信链断裂及TXT技术度量不彻底等难题提供了一种解决方案。这一技术能够让一个客体虚拟机与主宿Type 1 VMM二者实现互信,居于它们中间的“非简单”性质不可度量的服务console系统可以被完全绕过,仅用其提供与信息安全策略强制执行无关的服务业务。让我们共同努力创新,为可信计算技术与标准的进一步发展及其在可信云计算虚拟化架构上的有效应用做出应有的贡献。

    展开全文
  • RFM会员价值模型

    千次阅读 2020-12-14 19:11:05
    会员价值度用来评估用户的价值情况,是区分会员价值的重要模型和参考依据,也是衡量不同营销效果的关键指标之一。 1.2 定义 价值模型一般基于交易行为产生,衡量的是有实体转化价值的行为。常用的价值模型是...

    1. 简介

    1.1 作用

    • 会员价值度用来评估用户的价值情况
    • 是区分会员价值的重要模型和参考依据
    • 也是衡量不同营销效果的关键指标之一

    1.2 定义

    • 价值度模型一般基于交易行为产生,衡量的是有实体转化价值的行为。常用的价值度模型是RFM
    • RFM模型是根据会员
      • 最近一次购买时间R(Recency)
      • 购买频率F(Frequency)
      • 购买金额M(Monetary)计算得出RFM得分
      • 通过这3个维度来评估客户的订单活跃价值,常用来做客户分群或价值区分
      • RFM模型基于一个固定时间点来做模型分析,不同时间计算的的RFM结果可能不一样

    RFM模型

    1.3 基本实现过程

    • ①设置要做计算时的截止时间节点(例如2017-5-30),用来做基于该时间的数据选取和计算。
    • ②在会员数据库中,以今天为时间界限向前推固定周期(例如1年),得到包含每个会员的会员ID、订单时间、订单金额的原始数
      据集。一个会员可能会产生多条订单记录。
    • ③ 数据预计算。从订单时间中找到各个会员距离截止时间节点最近的订单时间作为最近购买时间;以会员ID为维度统计每个用户
      的订单数量作为购买频率;将用户多个订单的订单金额求和得到总订单金额。由此得到R、F、M三个原始数据量。
    • ④ R、F、M分区。对于F和M变量来讲,值越大代表购买频率越高、订单金额越高;但对R来讲,值越小代表离截止时间节点越
      近,因此值越好。对R、F、M分别使用五分位(三分位也可以,分位数越多划分得越详细)法做数据分区。需要注意的是,对于
      R来讲需要倒过来划分,离截止时间越近的值划分越大。这样就得到每个用户的R、F、M三个变量的分位数值。
    • ⑤ 将3个值组合或相加得到总的RFM得分。对于RFM总得分的计算有两种方式,一种是直接将3个值拼接到一起,例如RFM得分为312、333、132;另一种是直接将3个值相加求得一个新的汇总值,例如RFM得分为6、9、6。

    2. 应用

    2.1 Excel实现RFM划分

    以某电商公司为例

    • R:例如:正常新用户注册1周内交易,7天是重要的值,日用品采购周期是1个月,30天是重要的值
    • F:例如:1次购买,2次购买,3次购买,4~10次,10次以上
    • M:例如:客单价300,热销单品价格240 等

    常见的确定RFM划分区间的套路

    • 业务实际判断
    • 平均值或中位数
    • 二八法则

    提取用户最近一次的交易时间,算出距离计算时间的差值

    • 获取当前时间=TODAY()

    获取当前时间

    • 计算时间间隔
      计算时间间隔

    根据天数长短赋予对应的R值

    =IF(D2>60,1,IF(D2>30,2,IF(D2>14,3,IF(D2>7,4,5))))
    

    根据天数长短付宇对应的R值

    • 从历史数据中取出所有用户的购买次数,根据次数多少赋予对应的F分值
    =IF(E2>10,5,IF(E2>3,4,IF(E2>2,3,IF(E2>1,2,1))))
    

    从历史数据中取出所有用户的购买次数,根据次数付宇对应的F分值

    • 从历史数据中汇总,求得该用户的交易总额,根据金额大小赋予对应的M值
    =IF(F2>1000,5,IF(F2>500,4,IF(F2>300,3,IF(F2>230,2,1))))
    

    从历史数据中汇总,求得该用户的交易总额,根据金额大小付宇对应的M值

    • 求出RFM的中值,例如中位数,用中值和用户的实际三值进行比较,高于中值的为高,否则为低

    RFM的中值

    • 在得到不同会员的RFM之后,根据步骤⑤产生的两种结果有两种应用思路
      • 思路1:基于3个维度值做用户群体划分和解读,对用户的价值度做分析
        • 得分为212的会员往往购买频率较低,针对 购买频率低的客户应定期发送促销活动邮件
        • 得分为321的会员虽然购买频率高但是订单金额低等,这些客户往往具有较高的购买黏性,可以考虑通过关联或搭配销售的
          方式提升订单金额。
      • 思路2:基于RFM的汇总得分评估所有会员的价值度价值,并可以做价值度排名。同时,该得分还可以作为输入维度与其他维度一起作为其他数据分析和挖掘模型的输入变量,为分析建模提供基础。

    2.2 RFM计算

    1. 案例背景

    • 用户价值细分是了解用户价值度的重要途径,针对交易数据分析的常用模型是RFM模型
    • 业务对RFM的结果要求
      • 对用户做分组
      • 将每个组的用户特征概括和总结出来,便于后续精细化运营不同的客户群体,且根据不同群体做定制化或差异性的营销和关怀
    • 规划目标将RFM的3个维度分别做3个区间的离散化
      • 用户群体最大有3×3×3=27个
      • 划分区间过多则不利于用户群体的拆分
      • 区间过少则可能导致每个特征上的用户区分不显著
    • 交付结果
      • 给业务部门做运营的分析结果要导出为Excel文件,用于做后续分析和二次加工使用
      • RFM的结果还会供其他模型的建模使用,RFM本身的结果可以作为新的局部性特征,因此数据的输出需要有本地文件和写数据库
        两种方式
    • 数据说明
      • 选择近4年订单数据,从不同的年份对比不同时间下各个分组的绝对值变化情况,方便了解会员的波动
      • 案例的输入源数据sales.xlsx
      • 程序输出RFM得分数据写入本地文件sales_rfm_score.xlsx和MySQL数据库sales_rfm_score表中

    2. 用到的技术点

    • 通过Python代码手动实现RFM模型,主要用到的库包括
      • time、numpy和pandas
      • 在结果展示时使用了pyecharts的3D柱形图

    3. 案例数据

    • 案例数据是某企业从2015年到2018年共4年的用户订单抽样数据,数据来源于销售系统
    • 数据在Excel中包含5个sheet,前4个sheet以年份为单位存储为单个sheet中,最后一张会员等级表为用户的等级表
    • 前4张表的数据概要如下。
      • 特征变量数:4
      • 数据记录数:30774/41278/50839/81349
      • 是否有NA值:有
      • 是否有异常值:有
        ·会员ID:每个会员的ID唯一,由纯数字组成。 ·提交日期:订单日提交日期。 ·订单号:订单ID,每个订单的ID唯一,由纯数字组成。 ·订单金额:订单金额,浮点型数据。
    • 具体数据特征如下:
      • 会员ID:每个会员的ID唯一,整型
      • 提交日期:订单日提交日期
      • 订单号:订单ID,每个订单的ID唯一,整型
      • 订单金额:订单金额,浮点型数据
    • 会员登记表中是所有会员的会员ID对应会员等级的情况,包括以下两个字段
      • 会员ID:该ID可与前面的订单表中的会员ID关联
      • 会员等级:会员等级以数字区分,数字越大,级别越高

    4. 实现

    1. 导入模块

    import time # 时间库 
    import numpy as np # numpy库 
    import pandas as pd # pandas库 
    import pymysql # mysql连接库 
    from pyecharts.charts import Bar3D # 3D柱形图
    
    • 用到了6个库:time、numpy、pandas、pymysql、sklearn和pyecharts。
      • time:用来记录插入数据库时的当前日期
      • numpy:用来做基本数据处理等
      • pandas:有关日期转换、数据格式化处理、主要RFM计算过程等
      • pymysql:数据库连接工具,读写MySQL数据库。
      • sklearn:使用其中的随机森林库
      • pyecharts:展示3D柱形图

    2. 读取数据

    sheet_names = ['2015','2016','2017','2018','会员等级']
    sheet_datas = [pd.read_excel('data/sales.xlsx',sheet_name=i) for i in sheet_names]
    

    3. 查看基本数据情况

    for each_name,each_data in zip(sheet_names,sheet_datas): 
    	print('[data summary for ============={}===============]'.format(each_name))
    	print('Overview:','\n',each_data.head(4))# 展示数据前4条
    	print('DESC:','\n',each_data.describe())# 数据描述性信息 
        print('NA records',each_data.isnull().any(axis=1).sum()) # 缺失值记录数 
    	print('Dtypes',each_data.dtypes) # 数据类型
    

    结果说明:

    • 每个sheet中的数据都能正常读取,无任何错误
    • 日期列(提交日期)已经被自动识别为日期格式,后期不必转换
    • 订单金额的分布是不均匀的,里面有明显的极大值
      • 例如2016年的数据中,最大值为174900,最小值仅为0.1
      • 极大极小值相差过大,数据会受极值影响
    • 订单金额中的最小值包括0、0.1这样的金额,可能为非正常订单,与业务方沟通后确认
      • 最大值的订单金额有效,通常是客户一次性购买多个大家电商品
      • 而订单金额为0.1元这类使用优惠券支付的订单,没有实际意义
      • 除此之外,所有低于1元的订单均有这个问题,因此需要在后续处理中去掉
    • 有的表中存在缺失值记录,但数量不多,选择丢弃或填充均可

    4. 数据预处理

    # 去除缺失值和异常值 
    for ind,each_data in enumerate(sheet_datas[:-1]):
     	sheet_datas[ind] = each_data.dropna()# 丢弃缺失值记录 
     	sheet_datas[ind] = each_data[each_data['订单金额'] > 1]# 丢弃订单金额<=1的记录 
     	sheet_datas[ind]['max_year_date'] = each_data['提交日期'].max() # 增加一列最大日期值
    
    • 通过for循环配合enumerate方法,获得每个可迭代元素的索引和具体值
    • 处理缺失值和异常值只针对订单数据,因此sheet_datas通过索引实现不包含最后一个对象(即会员等级表)
    • 直接将each_data使用dropna丢弃缺失值后的dataframe代原来sheet_datas中的dataframe
    • 使用each_data[each_data[‘订单金额’]>1]来过滤出包含订单金额>1的记录数,然后替换原来sheet_datas中的dataframe
    • 最后一行代码的目的是在每个年份的数据中新增一列max_year_date,通过each_data[‘提交日期’].max()获取一年中日期的最大
      值,这样方便后续针对每年的数据分别做RFM计算,而不是针对4年的数据统一做RFM计算。
    # 汇总所有数据 data_merge = pd.concat(sheet_datas[:-1],axis=0)
     # 获取各自年份数据
     data_merge['date_interval'] = data_merge['max_year_date']-data_merge['提交日期'] 
     data_merge['year'] = data_merge['提交日期'].dt.year 
     # 转换日期间隔为数字 
     data_merge['date_interval'] = data_merge['date_interval'].apply(lambda x: x.days) 
     data_merge.head()
    

    输出结果:
    在这里插入图片描述

    • 汇总所有数据: 将4年的数据使用pd.concat方法合并为一个完整的dataframe data_merge,后续的所有计算都能基于同一个
      dataframe进行,而不用写循环代码段对每个年份的数据单独计算
    • 获取各自年份数据:
      • 先计算各自年份的最大日期与每个行的日期的差,得到日期间隔
      • 再增加一列新的字段,为每个记录行发生的年份,使用data_merge[‘提交日期’].dt.year实现
    • 关于pandas的 datetime类型
      • dt是pandas中Series时间序列datetime类属性的访问对象
      • 除了代码中用到的year外,还包括:date、dayofweek、dayofyear、days_in_month、freq、days、hour、
        microsecond、minute、month、quarter、second、time、week、weekday、weekday_name、weekofyear等
    • 转换日期间隔为数字:data_merge[‘date_interval’].apply(lambda x: x.days) 是将data_merge[‘date_interval’]的时间间隔转换
      为数值型计算对象,这里使用了apply方法。Apply方法是对某个Pandas对象(dataframe或Series)使用自定义函数
    # 按会员ID做汇总 
    rfm_gb = data_merge.groupby(['year','会员ID'],as_index=False).agg(
    	{'date_interval': 'min', # 计算最近一次订单时间
    	 '提交日期': 'count', # 计算订单频率 
    	 '订单金额': 'sum'}) # 计算订单总金额 
    # 重命名列名 
    rfm_gb.columns = ['year','会员ID','r','f','m'] rfm_gb.head()
    

    输出结果:
    在这里插入图片描述

    • 上面代码框中的第一行代码,是基于年份和会员ID,分别做RFM原始值的聚合计算
    • 这里使用groupby分组,以year和会员ID为联合主键,设置as_index=False意味着year和会员ID不作为index列,而是普通的数据
      框结果列。后面的agg方法实际上是一个“批量”聚合功能的函数,它实现date_interval、提交日期、订单金额三列分别以min、count、sum做聚合计算的功能。否则,我们需要分别写3条goupby来实现3个聚合计算

    5. 确定RFM划分区间

    • 在做RFM划分时,基本逻辑是分别对R、F、M做离散化操作,然后再计算RFM。而离散化本身有多种方法可选,由
      于我们要对数据做RFM离散化,因此需要先看下数据的基本分布状态
    # 查看数据分布 
    desc_pd = rfm_gb.iloc[:,2:].describe().T 
    desc_pd
    

    输出结果:
    在这里插入图片描述

    # 定义区间边界 
    r_bins = [-1,79,255,365] # 注意起始边界小于最小值 f_bins = [0,2,5,130] 
    m_bins = [0,69,1199,206252]
    
    • 从基本概要看出
      • 汇总后的数据总共有14万条
      • r和m的数据分布相对较为离散,表现在min、25%、50%、75%和max的数据没有特别集中
      • 而从f(购买频率)则可以看出,大部分用户的分布都趋近于1,表现是从min到75%的分段值都是1且mean(均值)才为
        1.365
      • 计划选择25%和75%作为区间划分的2个边界值
    • f的分布情况说明
      • r和m本身能较好地区分用户特征,而f则无法区分(大量的用户只有1个订单)
      • 行业属性(家电)原因,1年购买1次比较普遍(其中包含新客户以及老客户在当年的第1次购买)
      • 与业务部门沟通,划分时可以使用2和5来作为边界
        • 业务部门认为当年购买>=2次可被定义为复购用户(而非累计订单的数量计算复购用户)
        • 业务部门认为普通用户购买5次已经是非常高的次数,超过该次数就属于非常高价值用户群体
        • 该值是基于业务经验和日常数据报表获得的
    • 区间边界的基本原则如下
      • 中间2个边界值:r和m是分别通过25%和75%的值获取的,f是业务与数据部门定义的。
      • 最小值边界:比各个维度的最小值小即可。
      • 最大值边界:大于等于各个维度的最大值即可
      • 最小值边界为什么要小于各个维度的最小值:
        • 这是由于在边界上的数据归属有一个基本准则,要么属于区间左侧,要么属于区间右侧。如,f_bins中的2处于边界
          上,要么属于左侧区间,要么属于右侧区间
        • 在后续使用pd.cut方法中,对于自定义边界实行的是左开右闭的原则,即数据属于右侧区间,f_bins中的2就属于右侧
          区间。最左侧的值是无法划分为任何区间的,因此,在定义最小值时,一定要将最小值的边界值
        • 举例:[1,2,3,4,5],假如数据划分的区间边界是[1,3,5],即划分为2份
          • 其中的2/3被划分到(1,3]区间中
          • 3/4/5被划分到(3,5]区间中
          • 1无法划分到任何一个正常区间内

    6. RFM计算过程

    # RFM分箱得分 
    rfm_gb['r_score'] = pd.cut(rfm_gb['r'], r_bins, labels=[i for i in range(len(r_bins)-1,0,-1)]) # 计算R得 分
    rfm_gb['f_score'] = pd.cut(rfm_gb['f'], f_bins, labels=[i+1 for i in range(len(f_bins)-1)]) # 计算F得分 
    rfm_gb['m_score'] = pd.cut(rfm_gb['m'], m_bins, labels=[i+1 for i in range(len(m_bins)-1)]) # 计算M得分
    
    • 每个rfm的过程使用了pd.cut方法,基于自定义的边界区间做划分
    • labels用来显示每个离散化后的具体值。F和M的规则是值越大,等级越高
    • 而R的规则是值越小,等级越高,因此labels的规则与F和M相反
    • 在labels指定时需要注意,4个区间的结果是划分为3份
    #计算RFM组合 
    rfm_gb['r_score'] = rfm_gb['r_score'].astype(np.str)
    rfm_gb['f_score'] = rfm_gb['f_score'].astype(np.str)
    rfm_gb['m_score'] = rfm_gb['m_score'].astype(np.str)
    rfm_gb['rfm_group'] = rfm_gb['r_score'].str.cat(rfm_gb['f_score']).str.cat( rfm_gb['m_score'])
    
    • 将3列作为字符串组合为新的分组
      • 代码中,先针对3列使用astype方法将数值型转换为字符串型
      • 然后使用pandas的字符串处理库str中的cat方法做字符串合并,该方法可以将右侧的数据合并到左侧
      • 再连续使用两个str.cat方法得到总的R、F、M字符串组合
    • Series.str.cat(others=None, sep=None, na_rep=None) 参数: others : 列表或复合列表,默认为None,如果为None则连接本身的
      元素 sep : 字符串 或者None,默认为None na_rep : 字符串或者 None, 默认 None。如果为None缺失值将被忽略。 返回值:
      concat : 序列(Series)/索引(Index)/字符串(str)
    #如果连接的是两个序列,则会对应 
    >>> pd.Series(['a', 'b', 'c']).str.cat(['A', 'B', 'C'], sep=',') 
    0 a,A
    1 b,B
    2 c,C 
    dtype: object 
    #否则则会连接自身序列里的值 
    >>> pd.Series(['a', 'b', 'c']).str.cat(sep=',') 
    'a,b,c' 
    #也可以同时连接复合列表 
    >>> pd.Series(['a', 'b']).str.cat([['x', 'y'], ['1', '2']], sep=',') 
    0 a,x,1
    1 b,y,2
    dtype: object
    

    7. 保存结果到Excel

    rfm_gb.to_excel('sales_rfm_score1.xlsx') # 保存数据为Excel
    

    8. 写数据到数据库

    # 数据库信息
    config = {'host': '127.0.0.1', # 默认127.0.0.1 
    		'user': 'root', # 用户名 
    		'password': 'MyNewPass', # 密码 
    		'port': 3306, # 端口,默认为3306 
    		'database': 'test', # 数据库名称 
    		'charset': 'utf8' # 字符编码 
    		}
    
    # 建表操作
    con = pymysql.connect(**config) # 建立mysql连接 
    cursor = con.cursor() # 获得游标 
    cursor.execute("show tables") # 查询表 
    table_list = [t[0] for t in cursor.fetchall()] # 读出所有库 # 查找数据库是否存在目标表,如果没有则新建 
    table_name = 'sales_rfm_score' # 要写库的表名 
    if not table_name in table_list: # 如果目标表没有创建 
    	cursor.execute(''' 
    	CREATE TABLE %s ( 
    	userid VARCHAR(20), 
    	r_score int(2), 
    	f_score int(2), 
    	m_score int(2), 
    	rfm_group VARCHAR(10), 
    	insert_date VARCHAR(20) 
    	)ENGINE=InnoDB DEFAULT CHARSET=utf8 
    	''' % table_name) # 创建新表
    
    # 梳理数据 
    write_db_data = rfm_gb[['会员ID','r_score','f_score','m_score','rfm_group']] # 主要数据 
    timestamp = time.strftime('%Y-%m-%d', time.localtime(time.time())) # 日期
    
    # 写库 
    for each_value in write_db_data.values: 
    	insert_sql = "INSERT INTO `%s` VALUES ('%s',%s,%s,%s,'%s','%s')" % \ 
    		(table_name, each_value[0], each_value[1], each_value[2], \ 
    		each_value[3],each_value[4], 
    		timestamp) # 写库SQL依据 
    	cursor.execute(insert_sql) # 执行SQL语句,execute函数里面要用双引号 
    	con.commit() # 提交命令 
    cursor.close() # 关闭游标 
    con.close() # 关闭数据库连接
    

    9. RFM图形展示

    • 为了更好地了解不同周期下RFM分组人数的变化,通过3D柱形图展示结果
    • 展示结果时只有3个维度,分别是年份、rfm分组和用户数量。
    # 图形数据汇总 
    display_data = rfm_gb.groupby(['rfm_group','year'],as_index=False)['会员ID'].count() 
    display_data.columns = ['rfm_group','year','number'] 
    display_data['rfm_group'] = display_data['rfm_group'].astype(np.int32) 
    display_data.head()
    

    输出结果:
    在这里插入图片描述

    • 第1行代码使用数据框的groupby以rfm_group和year为联合对象,以会员ID会为计算维度做计数,得到每个RFM分组、年份下的
      会员数量
    • 第2行代码对结果列重命名
    • 第3行代码将rfm分组列转换为int32形式
    # 显示图形 
    from pyecharts.commons.utils import JsCode 
    range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', 
    			'#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'] 
    range_max = int(display_data['number'].max()) 
    c = (
    	Bar3D()#设置了一个3D柱形图对象 
    	.add(
    		"",#标题 
    		[d.tolist() for d in display_data.values],#数据 
    		xaxis3d_opts=opts.Axis3DOpts( type_="category",name='分组名称'),#x轴数据类型,名称 
    		yaxis3d_opts=opts.Axis3DOpts( type_="category",name='年份'),#y轴数据类型,名称 
    		zaxis3d_opts=opts.Axis3DOpts(type_="value",name='会员数量'),#z轴数据类型,名称 
    	).set_global_opts(#设置颜色,及不同取值对应的颜色 
    		visualmap_opts=opts.VisualMapOpts(max_=range_max,range_color=range_color), 
    		title_opts=opts.TitleOpts(title="RFM分组结果"),#设置标题 
    	) 
    )c.render_notebook() #在notebook中显示
    

    输出结果:

    在这里插入图片描述

    • 输出3D图像中
      • X轴为RFM分组、Y轴为年份、Z轴为用户数量
      • 该3D图可旋转、缩放,以便查看不同细节
      • 调节左侧的滑块条,用来显示或不显示特定数量的分组结果

    5. 案例结论

    5.1 基于图形的交互式分析

    • 重点人群分布:
      • 在整个分组中,212群体的用户是相对集中且变化最大的
      • 从2016年到2017年用户群体数量变化不大,但到2018年增长了近一倍
      • 这部分人群将作为重点分析人群
    • 重点分组分布:
      • 除了212人群外,312、213、211及112人群都在各个年份占据很大数量
      • 虽然各自规模不大,但组合起来的总量超过212本身,也要重点做分析。
      • 如果拖动左侧的滑块,仅过滤出用户数量在4085以内的分组结果。观察图形发现,很多分组的人群非常少,甚至没有人

    5.2 基于RFM分组结果的分析

    • 通过RFM分组的Excel结果数据,我们将更进一步确定要分析的主要目标群体。 打开导出的sales_rfm_score.xlsx,然后建立数据透视表,从Excel中得出的数据可以看出,与用Python代码分析的结果是一致的
      在这里插入图片描述

    5.3 RFM用户特征分析

    • 经过上面的分析,得到了要分析的重点客户群体。可根据用户的量级分为两类
      • 第1类是用户群体占比超过10%的群体
      • 第2类是占比在个位数的群体。这两类人由于量级不同,因此需要分别有针对性的策略场景。
      • 除此以外,我们还会增加第3类人群,虽然从用户量级上小,但是单个人的价值度非常高。
    • 第1类人群:占比超过10%的群体。由于这类人群基数大,必须采取批量操作和运营的方式落地运营策略,一般需要通过系统或产
      品实现,而不能主要依赖于人工
      • 212:可发展的一般性群体。这类群体购买新近度和订单金额一般,且购买频率低。考虑到其最大的群体基础,以及在新近
        度和订单金额上都可以,因此可采取常规性的礼品兑换和赠送、购物社区活动、签到、免运费等手段维持并提升其消费状
        态。
      • 211:可发展的低价值群体。这类群体相对于212群体在订单金额上表现略差,因此在211群体策略的基础上,可以增加与订
        单相关的刺激措施,例如组合商品优惠券发送、积分购买商品等
      • 312:有潜力的一般性群体。这类群体购买新近度高,说明最近一次购买发生在很短时间之前,群体对于公司尚有比较熟悉
        的接触渠道和认知状态;购物频率低,说明对网站的忠诚度一般;订单金额处于中等层级,说明其还具有可提升的空间。因
        此,可以借助其最近购买的商品,为其定制一些与上次购买相关的商品,通过向上销售等策略提升购买频次和订单金额
      • 112:可挽回的一般性群体。这类群体购买新近度较低,说明距离上次购买时间较长,很可能用户已经处于沉默或预流失、
        流失阶段;购物频率低,说明对网站的忠诚度一般;订单金额处于中等层级,说明其还可能具有可提升的空间。因此,对这
        部分群体的策略首先是通过多种方式(例如邮件、短信等)触达客户并挽回,然后通过针对流失客户的专享优惠(例如流失用户专享优惠券)措施促进其消费。在此过程中,可通过增加接触频次和刺激力度的方式,增加用户的回访、复购以及订单
        价值回报
      • 213:可发展的高价值群体。这类人群发展的重点是提升购物频率,因此可指定不同的活动或事件来触达用户,促进其回访
        和购买,例如不同的节日活动、每周新品推送、高价值客户专享商品等。
    • 第2类人群:占比为1%~10%的群体。这部分人群数量适中,在落地时无论是产品还是人工都可接入
      • 311:有潜力的低价值群体。这部分用户与211群体类似,但在购物新近度上更好,因此对其可采取相同的策略。除此以
        外,在这类群体的最近接触渠道上可以增加营销或广告资源投入,通过这些渠道再次将客户引入网站完成消费。
      • 111:这是一类在各个维度上都比较差的客户群体。一般情况下,会在其他各个群体策略和管理都落地后才考虑他们。主要
        策略是先通过多种策略挽回客户,然后为客户推送与其类似的其他群体,或者当前热销的商品或折扣非常大的商品。在刺激
        消费时,可根据其消费水平、品类等情况,有针对性地设置商品暴露条件,先在优惠券及优惠商品的综合刺激下使其实现消
        费,再考虑消费频率以及订单金额的提升。
      • 313:有潜力的高价值群体。这类群体的消费新近度高且订单金额高,但购买频率低,因此只要提升其购买频次,用户群体
        的贡献价值就会倍增。提升购买频率上,除了在其最近一次的接触渠道上增加曝光外,与最近一次渠道相关的其他关联访问
        渠道也要考虑增加营销资源。另外,213中的策略也要组合应用其中
      • 113:可挽回的高价值群体。这类群体与112群体类似,但订单金额贡献更高,因此除了应用112中的策略外,可增加部分人
        工的参与来挽回这些高价值客户,例如线下访谈、客户电话沟通等
    • 第3类群体:占比非常少,但却是非常重要的群体
      • 333:绝对忠诚的高价值群体。虽然用户绝对数量只有355,但由于其各方面表现非常突出,因此可以倾斜更多的资源,例
        如设计VIP服务、专享服务、绿色通道等。另外,针对这部分人群的高价值附加服务的推荐也是提升其价值的重点策略
      • 233、223和133:一般性的高价值群体。这类群体的主要着手点是提升新近购买度,即促进其实现最近一次的购买,可通过
        DM、电话、客户拜访、线下访谈、微信、电子邮件等方式直接建立用户挽回通道,以挽回这部分高价值用户
      • 322、323和332:有潜力的普通群体。这类群体最近刚完成购买,需要提升的是购买频次及购买金额。因此可通过交叉销
        售、个性化推荐、向上销售、组合优惠券、打包商品销售等策略,提升其单次购买的订单金额及促进其重复购买

    6. 案例应用

    • 针对上述得到的分析结论,会员部门采取了以下措施
      • 分别针3类群体,按照公司实际运营需求和当前目标,制定了不同的群体落地的排期
      • 录入数据库的RFM得分数据已经应用到其他数据模型中,成为建模输入的关键维度特征之一

    7. 案例注意点

    • 不同品类、行业对于RFM的依赖度是有差异的,即使是一个公司在不同的发展阶段和周期下,3个维度的优先级上也会有调整
      • 大家电等消费周期较长的行业,R和M会更重要一些
      • 快消等消费周期短且快的行业,更看重R和F
      • 具体要根据当前运营需求与业务部门沟通
    • 对R、F、M区间的划分是一个离散化的过程,具体需要划分为几个区间需要与业务方确认
      • 本案例划分为3个区间,结果对于业务分析而言有些多,意味着业务方需要制定十几套甚至更多的策略
      • 如果业务方要求简化,也可以划分为2个区间,这样出来的分组数最多有8组,策略制定更加简单
      • 具体是划分为2个还是3个,取决于当前业务方有多少资源可以投入到这个事情中来。
    • R、F、M的权重打分
      • 除了案例中提到的建模方式外,结合业务经验的专家打分法也是常用的思路
      • 虽然订单数据库中的数据质量相对较高,但可能由于数据采集、数据库同步、ETL、查询、误操作等问题,还是会导致NA值的出
        现,而NA值的处理非常重要。
      • R、F、M三个维度的处理(包括计算、离散化、组合、转换)之前都需要注意其数据类型和格式,尤其是有关时间项的转换操作应提前完成

    8. 总结

    • RFM模型是经典的一种用户分群方法,操作起来比较简单,如果数据量不是很大的时候,直接使用Excel就可以实现
    • RFM并不是在所有业务场景下都可以使用,一般用于零售行业(复购率相对高的行业)
    • 使用Python的cut方法对数据进行分组,需要注意分组区间默认是左开右闭
    • 使用Pyecharts可以方便的绘制出可以交互的3D图,在修改弹出提示信息内容时,需要注意字符串拼接的格式
    展开全文
  • 1.DDM模型(Dividend discount model /股利折现模型) 2.DCF /Discount Cash Flow /折现现金流模型) (1)FCFE ( Free cash flow for the equity equity/股权自由现金流模型)模型 (2)FCFF模型( Free c...
  • 免信任型计算的扩容模型

    万次阅读 2019-05-12 09:01:12
    这些权衡关系不只反映了某些具体特征的存在与否,更体现了关于“何为免信任型(Trustless)计算”的各种不同观点。 本文旨在提供一个条理清晰的框架,以便读者理解这些权衡关系以及它们如何影响了加密领域的一些...
  • 企业画像在企业活动中的价值

    千次阅读 2020-04-09 16:08:57
    从海量冗杂的企业活动数据中挖掘有价值的数据,帮助政府、银行、券商、会计师、律师、投资方、企业自身等挖掘和计算企业360度全方位的信息,包括发现和挖掘企业之间的关联关系,找寻未知关系以促进企业合作,识别企业...
  • 科技云报道原创。 9月8日,由中国信息通信研究院(简称:中国信通院)云计算与大数据研究所、中国通信标准化协会...同时,中国信通院云大所正式发布了企业数字化转型首个成熟度模型IOMM标准,中国建设银行股份有限公
  • 企业价值分析框架

    千次阅读 2019-10-10 18:31:23
    安全边际与估值——价值评估 优秀企业家与股权结构 K 线可以看做是一家公司的影子,K 线总是跟随公司而变化,想要研究 K 线,应该从公司本身来研究。 什么是行业的天花板 行业或者企业的产品或者服务趋于饱和,达到...
  • 在过去的几年里,建立在机器学习算法、自然语言处理、分布式存储和计算等技术之上的大数据理论研究和技术应用越来越受到关注。有这样两个客观事实推动了本文的撰写:传统信贷服务依赖人工、基于流程的风险管理特点,...
  • RFM模型引入 比如电商网站要做一次营销活动,需要针对不同价值的客户群体进行分群,对于高价值的用户推荐手表,珠宝等高端商品,对于...在传统企业和电商众多的客户细分模型中,RFM模型是被广泛提到和使用的。 RFM模
  • 利用RFM模型做电商客户价值分析

    万次阅读 2016-04-11 16:51:59
    客户细分是客户关系管理的一个主要的组成部分,本文尝试以电商企业为研究对象根据其客户特点,提出了一种基于客户价值分析RFM 模型,从而对客户进行分类,并对此结果进行动态的客户分析,以达到对不同的客户采取...
  • 惠普企业的边缘计算产品名叫「Edgeline Converged Edge Systems」,其主要客户群体是工业领域,比如油田、煤矿等,这些特定行业的工作环境里,无法满足云端数据的处理条件,因此边缘计算就成为一个重要需求。...
  • 大数据【企业级360°全方位用户画像】基于RFM模型的挖掘型标签开发),本篇博客,我们来学习基于RFE(用户活跃度模型)的挖掘型标签开发。 文章目录RFE模型引入RFE详解基于RFE模型的实践应用具体代码实现知识拓展小...
  • 业成本法(ABC,Activity-Based Costing)是20世纪80年代美国学者Robin Cooper和RobertKaplan提出的一种新颖的成本管理方法,它在传统的成本和资源之间...作业成本法在20世纪90年代以来在企业界和学术界一直被广泛研
  • 今天的介绍的是另外一个拓展的模型:航空公司客户价值分析模型LRFCM。 RFM模型的复习 在客户分类中,RFM模型是一个经典的分类模型模型利用通用交易环节中最核心的三个维度——最近消费(Recency)、消费频率...
  • 目前越来越多的初创企业会参考一些指标来进行商业决策,如上市、融资等。其中,最常使用的指标是 LTV / CAC(客户全生命周期价值/客户获取成本)的比率。下面我们先简单介...
  • 本篇博客,我们将结合当前阶段正在做的用户画像项目,为大家介绍RFM模型和KMeans聚类算法。         先赞后看,养成习惯! 文章目录一、RFM模型引入1、RFM详解1.1 R值:...
  • IBM特别开发出一套全新的企业模型 组件化商业模式 Component Business Model CBM
  •         在前面的几篇博客中,博主不仅为大家...大数据【企业级360°全方位用户画像】之RFM模型和KMeans聚类算法~         我们
  • 基于RFM模型的用户价值的数据分析报告 分析背景与目的   目前企业的业务逐步从产品为主导转向以客户的需求为主导。一种全新的”以客户为中心“的业务模式正在形成并提升的前所未有的高度。然而与客户保持关系...
  • 题目来源: 《Python数据分析与应用》第8章 财政收入预测分析 实训部分 【 黄红梅、张良均主编 中国工信出版集团和人民邮电出版社】 ...实训1 求取企业所得税各特征间的相关系数 1.训练要点 (1)掌...
  • 添加两个KMV模型文档 2009-6-5 http://www.business.uiuc.edu/gpennacc/MoodysKMV.pdf ... 风险管理KMV模型Matlab计算----实例分析 %test KMV%r: risk-fre...
  • 核心内容:使用python的sklearn的KMeans算法对电商用户进行分类。 包含内容:数据概览、特征构建、k值选择、模型训练、可视化等。
  • 并行计算

    千次阅读 2012-04-15 09:23:22
    并行计算 求助编辑百科名片 ...并行计算或称平行计算是相对于串行计算来说的。所谓并行计算可分为时间上的并行和...计算模型 网络设置 静态连接 动态连接 基本术语 并行计算机性能度量 并行计算与云计算
  • 关于内在价值计算

    2009-08-24 17:46:00
    关于内在价值计算 昨天的问题,如何计算不是问题,主要的是为了揭示市净率不是计算内在价值的根本,对于市净率的判断必须得结合净资产收益率(未来复合增长率)来综合性判断其内在价值,否则就有失偏颇。这个计算...
  • 计算 --荆兆春  衡量一个企业是否赚钱,通常看的是企业的利润表,净利润是正数就是赚钱了,否则就是亏钱了,比如两个企业,一个投资500万,一个投资5000,假如两家的净利润都是100万,那么,从现行会计制度的利润...
  • 评价模型

    万次阅读 多人点赞 2018-07-11 22:35:30
    评价模型 HeartGo 关注2017.01.19 12:10* 字数 4802 阅读 2941评论 0喜欢 6数据挖掘之评价模型层次分析法(AHP)基本思想:是定性与定量相结合的多准则决策、评价方法。将决策的有关元素分解成目标层、准则层和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,606
精华内容 33,442
关键字:

企业价值计算模型