翻译:如何启动数据治理计划?

作者:Amber Lee Dennis

原文:http://www.dataversity.net/starting-data-governance-program-take/

译者:TalkingData架构师 曾晓

本译文禁止商用,转载请注明来源!

根据Seiner的定义,数据治理是:“在数据与数据相关的资产管理的执行和执法权。”

他更喜欢像“执行”和“执行权”这样的激烈的单词,以便明确指出数据治理不只是一个可选的组件,而是企业的基本组成部分。

Seiner是一位作家,一位行业教育家,一位DAMA奖获得者,KIK Consulting and Educational Service的总裁兼负责人,他是Non-Invasive Data Governance™的创始人,同时他还出版了“数据管理通讯”(TDAN.com),这是一份覆盖数据管理行业整个范围的在线出版物。

在最近的DATAVERSITY®采访中,Seiner分享了开始数据治理计划的最佳实践。

争取高层领导对治理的支持​

Seiner讨论的第一个最佳实践是让高层领导支持、赞助和理解数据治理:“如果他们不支持、赞助和理解数据治理,程序就有风险,因为他们不会给你时间去做。我在所有的客户中使用了这个最佳实践。”Seiner表示,高层领导需要了解数据治理。如果他们不真正理解治理团队正在做什么以及该计划如何运作,他们将不会提供必要和长期的支持。

另一个最佳实践指出,为数据治理提供专门的人力资源至关重要。有必要找到一个能够执行该计划的人,这个人必须是有能力和关系的,并且基本上可以管理这个计划,同时也能够获得高层领导的支持。“它不会自动运行。”Seiner说,“最重要的是,你需要有人对这件事负责,并有时间做这件事,否则,你将立即面临风险。”

非侵入性治理

Seiner的非侵入式数据治理方法促进了高级管理层的支持,在尽可能少毁坏的前提下引入了数据治理。Seiner的方法不是重头建立一个数据治理计划,而是强制员工遵从或增加治理任务的工作量,并希望员工为他们腾出时间,他们的方法基于现有的角色和责任建立数据治理计划。

“如果您希望对组织进行全面的覆盖,那么非侵入性是实现数据治理的唯一途径。否则,你将给每一个人他们不曾有过的感觉,这是不容易被接受的,”他说。

在非侵入式方法中,数据管理被定义为“对数据和数据相关资产管理问责制的正规化”。数据管理员因其与数据的关系而被认可,而不是被赋予新的责任并对这些责任追究责任关系。

“定义数据的人将负责如何定义数据,包括数据定义所必需的元数据。产生数据的人需要知道如何使用这些数据。使用数据的人必须遵循与数据的使用有关的规则,无论是数据保护还是合规性。“

准备评估:制定路线图

Seiner建议进行准备评估,将现有的数据治理实践与行业最佳实践进行比较。他建议提出这些问题:

  • 你目前为每个最佳实践做了什么支持工作?
  • 哪里有机会改进与最佳实践相关的?
  • 我们正在做什么和最佳做法之间有什么差距?
  • 这种差距有哪些风险?

这个过程将有助于创建一个问题领域的清单,并有助于发现可以通过应用良好治理来缓解的风险。评估通常显示需要更好地定义与数据治理相关的角色和责任的领域,并且可以充当行动计划或“计划路线图”,他说。准备就绪评估还将发现可用于制定数据治理沟通计划的沟通差距。

非侵入性治理:不伤害所有权

Seiner说,基于对可用实施方案缺乏了解的假设,通常导致了对数据治理的抵制。

“管理层认为数据治理将会很艰难,会变得很复杂,它会干扰目前正在进行的事情,事实上情况并不一定如此。如果你采取非侵入式方法,你会看到人们已经拥有什么样的责任,而且你不一定会把他们感觉新鲜的事情交给他们。“

高级领导层也可能对数据治理有产生抵触情绪,重要的是他们知道在某种方式下,治理已经在发生:

“这只是非常非正式的。这是非常低效的。这是非常无效的。采取非侵入式数据治理方法是正式确定并提高效率,使组织中已有的权限级别更加有效。“

不要创建数据管家,识别它们

他表示,与其指定某人担任管理员并为将治理添加到他们的工作量中,不如正式承认人们与数据的关系以及他们已经做了或应该做的事情。“当100个人使用相同的数据时,你不会进入一个有100人的房间,并指出其中的10个人,并且说’这10个人需要保护数据,并承担相同的责任。’“,任何使用数据的人都需要了解数据如何使用和不能使用。

除了支持所有用户对数据治理实践的遵从性之外,该计划还为数据管理员提供了支持和信心,因为他们知道他们有更强的问责制,他们得到领导层的支持,可强制执行的政策

各种各样的数据管家

Seiner非侵入式方法的另一个原则是可以有多种类型的数据管家。运营数据管理人员是每天定义、生成和使用数据的人员。他说,还可能有战术数据管理员,负责特定的域或主题,并且他们对整个组织的数据负有更高的责任。标题’管家’承认数据的正式关系和责任。

“这不是一个新的头衔或一个新角色。对于一个组织来说,最困难的步骤是使一个角色正式化,或者确定一个人或一组人的责任增加了。”

战术数据管家将促进围绕特定数据领域的对话,并与数据中的其他利益相关者合作,同时他们的职责是针对特定的数据域,而不是他们自己对数据的特定使用。他说,找到一个能够负责整个企业领域的个人对于一些组织来说可能非常困难。

“我现在有一个客户,他正在为客户、产品和供应商数据识别此人。想想有多难,找一个有这方面知识的人,或者愿意成为那个数据主题的管事员。“

如果一个领域对一个数据管家来说太多了:
“可能有一个数据主题的子域需要子域管理员。在“客户”下,可能有人口信息、财务信息、事务信息,因此可能为每个子域都有子域管家。“

数据治理在组织中的作用

数据治理和数据管理理想地属于首席数据官(CDO)或类似职位的人,但并非所有公司都有CDO。规模和企业结构会产生一定的影响,Seiner说。“在一个较小的公司,你不一定要域管理员负责子域名。这取决于组织。”

很多人都支持“如果人们负责教育自己”,而教育部分是把整个计划结合起来的关键。各级利益相关者需要了解数据治理计划的目的、意图和必要性,以便其运作并继续良好地应对未来。

你的“数据资产”真的算“资产”吗?

作者:TalkingData数据产品经理 于兰

本文由TalkingData原创,转载请获取授权。

何谓资产?

我们来看一下“资产”的概念:“资产是指由企业过去经营交易或各项事项形成的,由企业拥有或控制的,预期会给企业带来经济利益的资源。”

一般情况下,“资产”最核心的内涵是“拥有或控制”,而“预期会给企业带来经济利益”一条,由于“预期”的不确定性,很难作为评判的标准。

但实际上,能否为企业带来经济利益一条至关重要,现在的很多理财观点中,如果不能持续给企业带来现金流,反而需要花成本去收集、整理、维护,那这对企业来说,不是“资产”,而是“负债”,它需要企业持续投入,如果长期看不到收益的“预期”,反而会摊薄企业的利润。

从以上角度来看,“数据资产”只是一个表面的概念,要成为真正的“资产”,需要将其“预期”的收益具象化,变成实实在在的收益。

“数据资产”的表现

可明确作为“资产”的数据,表现为以下两种形式:用数据帮助现有产品带来收益;将数据本身变为可带来收益的产品。

“内消”:数据助力现金牛

数据助力现金牛,即数据本身不产生价值,但通过数据作用于其他现金牛产品,使其可以在创造收益、降低成本上有更好的表现,这是一种数据“内消”的方式,即一般在企业内部发生,将生产经营中产生的数据进行收集、整理、分析,用于服务自身经营决策、业务流程,从而提升产品业绩。

(图:现金通过产品进入企业,数据辅助产品获取收益)

如在各通信运营商都有成熟的高价值客户关怀维护体系,会定期分析高价值用户的套餐状态、消费情况、使用异常等,适时的采取关情维系策略,如在用户套餐即将到期时,通过一定的续约优惠(续约送手机、充值返话费等)吸引用户续约,延长稳定收益的时间。

“出口”:也可以是现金牛

通过数据帮助其他产品提升业绩的方式,对数据本身来说是一种间接的获益方式,一般情况下数据能带来多少价值是比较难以评估的。

在合法合规的前提下,让数据以各种形式进行交易,数据赋予价值,是让数据本身成为“现金牛”的直接方式。

(图:数据从企业输出,同时现金直接进入企业)

例如各P2P平台的黑名单客户,对于其他贷款平台来说是重要信息,可以有效减少骗贷可能性,降低坏账率,对银行和金融机构来说意味着直接的收益,很容易通过共享方式将数据直接变现。

如何让数据成为“资产”?

目前市场上的数据纷繁多样,但真正发挥其价值,通过”内消“或”出口“方式带来收益的并不多。从根本上来看,是因为”数据“只是”数据“,而能为企业带来价值的,不是“数据”本身,而是可以消除信息不对称的”信息“。

因此,如何将“数据”转化为“信息”,就成为这个过程中的核心。由于“信息”在不同场景中有不同的表现,我们无法给出普适性的“灵丹妙药”,只能从数据应用的角度提供一些通用的原则。 

融入业务场景

数据在不同的业务背景下有不同的处理方式:同样是电商交易数据,有人会关注其购买内容以研究不同商品间的关联关系,以用于进行商品推荐;有人会关注下单流程,以研究人的决策过程及其影响因素。

因此,数据的收集、处理、输出过程,必须基于特定的业务问题出发,将数据融入业务问题的解决过程,才能真正将数据发挥价值。

当然,由于数据处理的链条一般较长,越往底层离业务应用越远,可能不一定涵盖全部的业务方向,这种情况可以理解。但在上层考虑问题解决时,也必须再重新回顾数据的收集、处理过程,以保证不会遗漏重要信息,用最适合的方式解决问题。

清除“连接”的障碍 

数据一般是“1+1+1>3″的,数据越多,能带来的复利效果越大,但前提是,来自不同企业、不同组织的数据可以有效的进行关联。如果数据无法关联在一起,就是一个一个的孤岛,价值大打折扣。很多企业辛苦收集的数据无法找到出路,根本就在这里。

因此,在数据的处理、输出过程中,要尽可能全面的考虑”连接“的需要,让自身数据可以更好的和其他数据关联。如一般企业在数据存储中会使用自编主键,在输出时,由于自编主键的无法通用,必须有另一个替代的主键用于和外界关联。

SDMK助力“数据资产”增值

TalkingData的智能数据服务商城(SDMK),以平台方式承载各行各业的数据需求方,以及来自各行各业的数据。

在业务场景方面,TalkingData与各行业合作伙伴共同探索数据应用,沉淀为通用型数据服务在SDMK落地;

在“连接”方面,SDMK提供统一标准的服务接口,统一数据的流通方式,让数据需求方可以简单方便的获取各种数据,降低数据引入成本。

同时,数据应用,尤其是第三方数据应用方面,要走的路还很长,TalkingData SDMK希望和行业各方面的合作伙伴一起,探索再探索,一起展望由数据串起的行业新篇章。

锐眼洞察 | 理解非结构化数据的关键——数据可视化

作者:James Ovenden

原文:https://channels.theinnovationenterprise.com/articles/why-we-need-data-visualization-to-understand-unstructured-data

译者:TalkingData解决方案架构师 张雪倩

本译文禁止商用,转载请注明来源!

我们越来越擅长理解非结构化数据,但仍未达到理想状态。

数据可视化发展近几年突飞猛进。企业使用愈发令人惊叹的软件来展现他们收集的海量信息,使用反应敏捷、互动性强、往往又非常漂亮的表现形式,让观看者参与进来——无论是会议室里的决策者还是科技馆里的孩子们。

数据可视化领域从业者面临的最重要挑战之一,就是能用非结构化数据来做什么。非结构化数据是指所有不能纳入关系数据库的数据,包括视频、幻灯片、公司记录、社交媒体、RSS、文件和文本——基本上就是绝大部分的交流。

据估计,世界上80%的数据都是非结构化的而且这一数字正迅速增长,IDC预测非结构化数据将从2015年的9.3ZB到2020年增长至44.1ZB。它对企业的重要性也同样迅速增长着。墨尔本大学客座讲师与(商业分析)研究员Ranko Cosic曾指出:“在我看来,运用数据的方式在接下来几年中的变化将是,虽然企业会继续收集和分析数据仓库、传统数据库和关系数据库中的结构化数据,也将更多关注收集和分析传统网站与社交媒体网站上的以录音、图像、音乐、文本、视频和交互式内容形式出现的非结构化数据。”

非结构化数据如此重要,其原因是它所提供的语境。分析结构化数据能够告诉我们什么正在发生,但是通过分析复杂的非结构化数据流才能知道为什么会发生。结构化数据包含收入表现和运营指标,但是非结构化数据的文本能够展示对公司产品的看法、员工信息和竞争优势。

然而,对非结构化数据的分析则是一门相对来说比较新的科学,其规模和复杂性以往使得人们难以理解。高效处理非结构化数据是许多创业公司的目标,他们中的大部分现在关注于使用机器学习算法对其进行解锁,而不是像以前会将非结构化数据转化为结构化数据。他们将分析和可视化都自动化,所以公司能够立即从非结构化数据库得到结果。

BrainSpace和DeepDive是其中取得重大进展的两个创业公司,而且它们都获得了大型融资。Brainspace的CEO Dave Copps告诉我们:“之前,我们能够对非结构化数据做的只有搜索,搜集起来一堆文件,然后用关键词去尝试(搜索)。Tableau和Quickview之类的技术通常适合检索结构化数据,但是一旦你从文件中抽出词来看,语境就不在了。所以,比如说你在分析简历,如果你从一名软件开发者的简历中找到了‘Java’,但你不知道这个词的存在是否只是因为那个人写了‘我的Java很差劲’。我们做的,不仅仅只是分析词句,而是着眼于词与词之间的空白——语境。”

然而,我们在非结构化数据的分析上取得了一些显著进步的同时,实际上仍未发挥信息的全部潜力在动态数据专家Logtrust最近受委托的451研究中,有反馈的IT经理中有89%表示他们将结构化数据方案在企业中提升到很高的优先级,然而只有43%的人认为非结构化数据方案有一样的优先级。

改变这些态度的关键就是数据可视化。像BrainSpace这样的公司提供具有参与性、互动性的自动可视化,但仍有许多未被发现的潜力。洛克希德马丁的首席数据科学家Walter Storm指出:“技术确实使得非结构化数据更易被分析——一大问题却是:‘这种分析有什么用?’ 主题建模、图表分析、甚至降维和可视化都有许多艺术可言。有多少特征?都是些什么?深网中有多少层?有多少节点?多大的粒宽能展现良好的差异性?第二、第三顺序衍生出的特征空间中相邻两者之间的关系是什么?这种算法到底刚学习到了什么?我的假设是什么来着?”

探索新鲜事物是件很棒的事情,但是如果你不能说服决策者,让他们相信你想探索的东西确实是存在的,使他们采取合适的行动,那么这对企业来说就完全没有意义数据可视化是实现这一点最好的方法,它揭示了数据中无法以其它方式来理解的复杂结构。人类大脑处理信息的方式意味着,通过视觉的方式将它传达给人们并使得他们参与其中,让你可以描述出你所发现的模式,甚至可以发现这种模式的洞察。这也能让更多的人更易理解数据,可能有助于提升整个企业的数据平民化,并带来更多的洞察。

相较于传统数字化的数据,非结构化数据可视化带来了独特的挑战,且仍处于初期阶段。在最近旧金山数据可视化峰会上,通用汽车的数据可视化专家Ken Cherven使用以往所有国情咨文做了示范。他的示范结果显示了为什么可视化对于理解非结构化数据是非常有必要的,它也为我们提供了激动人心的机会,来创造性地以之前被认为是不可能的方式来展示信息,并为我们提供从中学习的机会。

延伸阅读:

① 两个工具帮你实现酷炫的数据可视化

② 手把手教你简单快速实现5种数据可视化

③ TalkingData 可视化能力及 iView 开发实践分享

技术专栏 | 微服务架构初探

作者:TalkingData 徐蓓

本译文禁止商用,转载请注明来源!

什么是微服务 

首先微服务并没有一个官方的定义,想要直接描述微服务比较困难,我们可以通过对比传统Web应用,来理解什么是微服务。

传统的Web应用核心分为业务逻辑、适配器以及API或通过UI访问的Web界面。业务逻辑定义业务流程、业务规则以及领域实体。适配器包括数据库访问组件、消息组件以及访问接口等。

一个打车软件的架构图如下:

尽管也是遵循模块化开发,但最终它们会打包并部署为单体式应用。例如Java应用程序会被打包成WAR,部署在Tomcat或者Jetty上。

这种单体应用比较适合于小项目,优点是:

  • 开发简单直接,集中式管理
  • 基本不会重复开发
  • 功能都在本地,没有分布式的管理开销和调用开销

当然它的缺点也十分明显,特别对于互联网公司来说:

  • 开发效率低:所有的开发在一个项目改代码,递交代码相互等待,代码冲突不断
  • 代码维护难:代码功能耦合在一起,新人不知道何从下手
  • 部署不灵活:构建时间长,任何小修改必须重新构建整个项目,这个过程往往很长
  • 稳定性不高:一个微不足道的小问题,可以导致整个应用挂掉
  • 扩展性不够:无法满足高并发情况下的业务需求

所以,现在主流的设计一般会采用微服务架构。其思路不是开发一个巨大的单体式应用,而是将应用分解为小的、互相连接的微服务。一个微服务完成某个特定功能,比如乘客管理和下单管理等。每个微服务都有自己的业务逻辑和适配器。一些微服务还会提供API接口给其他微服务和应用客户端使用。

比如,前面描述的系统可被分解为:

每个业务逻辑都被分解为一个微服务,微服务之间通过REST API通信。一些微服务也会向终端用户或客户端开发API接口。但通常情况下,这些客户端并不能直接访问后台微服务,而是通过API Gateway来传递请求。API Gateway一般负责服务路由、负载均衡、缓存、访问控制和鉴权等任务。

微服务架构的优点 

微服务架构有很多重要的优点。

首先,它解决了复杂性问题。它将单体应用分解为一组服务。虽然功能总量不变,但应用程序已被分解为可管理的模块或服务。这些服务定义了明确的RPC或消息驱动的API边界。微服务架构强化了应用模块化的水平,而这通过单体代码库很难实现。因此,微服务开发的速度要快很多,更容易理解和维护。

其次,这种体系结构使得每个服务都可以由专注于此服务的团队独立开发。只要符合服务API契约,开发人员可以自由选择开发技术。这就意味着开发人员可以采用新技术编写或重构服务,由于服务相对较小,所以这并不会对整体应用造成太大影响。

第三,微服务架构可以使每个微服务独立部署。开发人员无需协调对服务升级或更改的部署。这些更改可以在测试通过后立即部署。所以微服务架构也使得CI/CD成为可能。

最后,微服务架构使得每个服务都可独立扩展。我们只需定义满足服务部署要求的配置、容量、实例数量等约束条件即可。比如我们可以在EC2计算优化实例上部署CPU密集型服务,在EC2内存优化实例上部署内存数据库服务。

微服务架构的缺点和挑战 

实际上并不存在silver bullets,微服务架构也会给我们带来新的问题和挑战。其中一个就和它的名字类似,微服务强调了服务大小,但实际上这并没有一个统一的标准。业务逻辑应该按照什么规则划分为微服务,这本身就是一个经验工程。有些开发者主张10-100行代码就应该建立一个微服务。虽然建立小型服务是微服务架构崇尚的,但要记住,微服务是达到目的的手段,而不是目标。微服务的目标是充分分解应用程序,以促进敏捷开发和持续集成部署。

微服务的另一个主要缺点是微服务的分布式特点带来的复杂性。开发人员需要基于RPC或者消息实现微服务之间的调用和通信,而这就使得服务之间的发现、服务调用链的跟踪和质量问题变得的相当棘手。

微服务的另一个挑战是分区的数据库体系和分布式事务。更新多个业务实体的业务交易相当普遍。这些类型的事务在单体应用中实现非常简单,因为单体应用往往只存在一个数据库。但在微服务架构下,不同服务可能拥有不同的数据库。CAP原理的约束,使得我们不得不放弃传统的强一致性,而转而追求最终一致性,这个对开发人员来说是一个挑战。

微服务架构对测试也带来了很大的挑战。传统的单体WEB应用只需测试单一的REST API即可,而对微服务进行测试,需要启动它依赖的所有其他服务。这种复杂性不可低估。

微服务的另一大挑战是跨多个服务的更改。比如在传统单体应用中,若有A、B、C三个服务需要更改,A依赖B,B依赖C。我们只需更改相应的模块,然后一次性部署即可。但是在微服务架构中,我们需要仔细规划和协调每个服务的变更部署。我们需要先更新C,然后更新B,最后更新A。

部署基于微服务的应用也要复杂得多。单体应用可以简单的部署在一组相同的服务器上,然后前端使用负载均衡即可。每个应用都有相同的基础服务地址,例如数据库和消息队列。而微服务由不同的大量服务构成。每种服务可能拥有自己的配置、应用实例数量以及基础服务地址。这里就需要不同的配置、部署、扩展和监控组件。此外,我们还需要服务发现机制,以便服务可以发现与其通信的其他服务的地址。因此,成功部署微服务应用需要开发人员有更好地部署策略和高度自动化的水平。

以上问题和挑战可大体概括为:

  • API Gateway
  • 服务间调用
  • 服务发现
  • 服务容错
  • 服务部署
  • 数据调用

幸运的是,出现了很多微服务框架,可以解决以上问题。

第一代微服务框架 

Spring Cloud

Spring Cloud为开发者提供了快速构建分布式系统的通用模型的工具(包括配置管理、服务发现、熔断器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态等)。

主要项目包括:

  • spring cloud config:由git存储库支持的集中式外部配置管理。配置资源直接映射到Spring Environment,但是如果需要可以被非Spring应用程序使用。
  • spring cloud netflix:与各种Netflix OSS组件(Eureka,Hystrix,Zuul,Archaius等)集成。
  • spring cloud bus:用于将服务和服务实例与分布式消息传递联系起来的事件总线。用于在集群中传播状态更改(例如配置更改事件)
  • spring cloud for cloud foundry:将您的应用程序与Pivotal Cloudfoundry集成。提供服务发现实现,还可以轻松实现通过SSO和OAuth2保护资源,还可以创建Cloudfoundry服务代理。
  • spring cloud cloud foundry service broker:提供构建管理一个Cloud Foundry中服务的服务代理的起点。
  • spring cloud cluster:领导选举和通用状态模型(基于zookeeper,redis,hazelcast,Consul的抽象和实现)
  • spring cloud consul:结合Hashicorp Consul的服务发现和配置管理
  • spring cloud security:在Zuul代理中为负载平衡的OAuth2休眠客户端和认证头中继提供支持。
  • spring cloud sleuth:适用于Spring Cloud应用程序的分布式跟踪,与Zipkin,HTrace和基于日志(例如ELK)跟踪兼容。
  • spring cloud data flow:针对现代运行时的可组合微服务应用程序的云本地编排服务。易于使用的DSL,拖放式GUI和REST-API一起简化了基于微服务的数据管道的整体编排。
  • spring cloud     stream:轻量级事件驱动的微服务框架,可快速构建可连接到外部系统的应用程序。使用Apache Kafka或RabbitMQ在Spring Boot应用程序之间发送和接收消息的简单声明式模型。
  • spring cloud stream app starters:Spring Cloud任务应用程序启动器是Spring Boot应用程序,可能是任何进程,包括不会永远运行的Spring Batch作业,并且它们在有限时间的数据处理之后结束/停止。
  • spring cloud zookeeper:Zookeeper的服务发现和配置管理
  • spring cloud for amazon web services:轻松集成托管的Amazon的Web Services服务。它通过使用spring的idioms和APIs便捷集成AWS服务,例如缓存或消息API。开发人员可以围绕托管服务,不必关心基础架构来构建应用。
  • spring cloud connectors:使PaaS应用程序在各种平台上轻松连接到后端服务,如数据库和消息代理(以前称为”Spring Cloud”的项目)
  • spring cloud starters:作为基于spring boot的启动项目,降低依赖管理(在Angel.SR2后,不在作为独立项目)
  • spring cloud cli:插件支持基于Groovy预言快速创建spring cloud的组件应用

Dubbo

Dubbo是一个阿里巴巴开源出来的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

其核心部分包含:

  • 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及”请求-响应”模式的信息交换方式。
  • 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持。
  • 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

但是显而易见,无论是Dubbo还是Spring Cloud都只适用于特定的应用场景和开发环境,它们的设计目的并不是为了支持通用性和多语言性。并且它们只是Dev层的框架,缺少DevOps的整体解决方案(这正是微服务架构需要关注的)。而随之而来的便是Service Mesh的兴起。

下一代微服务:Service Mesh? 

Service Mesh

Service Mesh又译作”服务网格”,作为服务间通信的基础设施层。如果用一句话来解释什么是Service Mesh,可以将它比作是应用程序或者说微服务间的TCP/IP,负责服务之间的网络调用、限流、熔断和监控。对于编写应用程序来说一般无须关心TCP/IP这一层(比如通过 HTTP 协议的 RESTful 应用),同样使用Service Mesh也就无须关系服务之间的那些原来是通过应用程序或者其他框架实现的事情,比如Spring Cloud、OSS,现在只要交给Service Mesh就可以了。

Service Mesh有如下几个特点:

  • 应用程序间通讯的中间层
  • 轻量级网络代理
  • 应用程序无感知
  • 解耦应用程序的重试/超时、监控、追踪和服务发现

Service Mesh的架构如下图所示:

Service Mesh作为Sidebar运行,对应用程序来说是透明,所有应用程序间的流量都会通过它,所以对应用程序流量的控制都可以在Service Mesh中实现。

目前流行的Service Mesh开源软件有Linkerd、Envoy和Istio,而最近Buoyant(开源Linkerd的公司)又发布了基于Kubernetes的Service Mesh开源项目Conduit。

Linkerd

Linkerd是开源网络代理,设计为以服务网格部署:用于管理,控制和监控应用程序内的服务与服务间通讯的专用层。

Linkerd旨在解决Twitter,Yahoo,Google和Microsoft等公司运营大型生产系统时发现的问题。根据经验,最复杂,令人惊奇和紧急行为的来源通常不是服务本身,而是服务之间的通讯。Linkerd解决了这些问题,不仅仅是控制通讯机制,而是在其上提供一个抽象层。

它的主要特性有:

  • 负载平衡:linkerd提供了多种负载均衡算法,它们使用实时性能指标来分配负载并减少整个应用程序的尾部延迟。
  • 熔断:linkerd包含自动熔断,将停止将流量发送到被认为不健康的实例,从而使他们有机会恢复并避免连锁反应故障。
  • 服务发现:linkerd 与各种服务发现后端集成,通过删除特定的(ad-hoc)服务发现实现来帮助您降低代码的复杂性。
  • 动态请求路由:linkerd 启用动态请求路由和重新路由,允许您使用最少量的配置来设置分段服务(staging service),金丝雀(canaries),蓝绿部署(blue-green deploy),跨DC故障切换和黑暗流量(dark traffic)。
  • 重试次数和截止日期:linkerd可以在某些故障时自动重试请求,并且可以在指定的时间段之后让请求超时。
  • TLS:linkerd 可以配置为使用 TLS 发送和接收请求,您可以使用它来加密跨主机边界的通信,而不用修改现有的应用程序代码。
  • HTTP代理集成:linkerd 可以作为 HTTP 代理,几乎所有现代 HTTP 客户端都广泛支持,使其易于集成到现有应用程序中。
  • 透明代理:您可以在主机上使用 iptables 规则,设置通过 linkerd 的透明代理
  • gRPC:linkerd 支持 HTTP/2 和 TLS,允许它路由 gRPC 请求,支持高级 RPC 机制,如双向流,流程控制和结构化数据负载。
  • 分布式跟踪:linkerd 支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。
  • 仪器仪表: linkerd 支持分布式跟踪和度量仪器,可以提供跨越所有服务的统一的可观察性。

Envoy

Envoy 是一个面向服务架构的L7代理和通信总线而设计的,这个项目诞生是出于以下目标:

对于应用程序而言,网络应该是透明的,当发生网络和应用程序故障时,能够很容易定位出问题的根源。

Envoy可提供以下特性:

  • 外置进程架构:可与任何语言开发的应用一起工作;可快速升级
  • 基于新C++11编码:能够提供高效的性能
  • L3/L4过滤器:核心是一个L3/L4网络代理,能够作为一个可编程过滤器实现不同TCP代理任务,插入到主服务当中。通过编写过滤器来支持各种任务,如原始TCP代理、HTTP代理、TLS客户端证书身份验证等。
  • HTTP L7过滤器:支持一个额外的HTTP L7过滤层。HTTP过滤器作为一个插件,插入到HTTP链接管理子系统中,从而执行不同的任务,如缓冲,速率限制,路由/转发,嗅探Amazon的DynamoDB等等。
  • 支持HTTP/2:在HTTP模式下,支持HTTP/1.1、HTTP/2,并且支持HTTP/1.1、HTTP/2双向代理。这意味着HTTP/1.1和HTTP/2,在客户机和目标服务器的任何组合都可以桥接
  • HTTP L7路由:在HTTP模式下运行时,支持根据content type、runtime values等,基于path的路由和重定向。可用于服务的前端/边缘代理
  • 支持gRPC:gRPC是一个来自谷歌的RPC框架,使用HTTP/2作为底层的多路传输。HTTP/2承载的gRPC请求和应答,都可以使用Envoy的路由和LB能力
  • 支持MongoDB L7:支持获取统计和连接记录等信息
  • 支持DynamoDB L7:支持获取统计和连接等信息
  • 服务发现:支持多种服务发现方法,包括异步DNS解析和通过REST请求服务发现服务
  • 健康检查:含有一个健康检查子系统,可以对上游服务集群进行主动的健康检查。也支持被动健康检查。
  • 高级LB:包括自动重试、断路器,全局限速,阻隔请求,异常检测。未来还计划支持请求速率控制
  • 前端代理:可作为前端代理,包括TLS、HTTP/1.1、HTTP/2,以及HTTP L7路由
  • 极好的可观察性:对所有子系统,提供了可靠的统计能力。目前支持statsd以及兼容的统计库。还可以通过管理端口查看统计信息,还支持第三方的分布式跟踪机制
  • 动态配置:提供分层的动态配置API,用户可以使用这些API构建复杂的集中管理部署

Istio

Istio是一个用来连接、管理和保护微服务的开放平台。Istio提供一种简单的方式来建立已部署服务网络,具备负载均衡、服务间认证、监控等功能,而不需要改动任何服务代码。想要为服务增加对Istio的支持,您只需要在环境中部署一个特殊的边车(sidecar),使用Istio控制面板功能配置和管理代理,拦截微服务之间的所有网络通信。

Istio目前仅支持在Kubernetes上的服务部署,但未来版本中将支持其他环境。

Istio提供了一个完整的解决方案,通过为整个服务网格提供行为洞察和操作控制来满足微服务应用程序的多样化需求。它在服务网络中统一提供了许多关键功能:

  • 流量管理:控制服务之间的流量和API调用的流向,使得调用更可靠,并使网络在恶劣情况下更加健壮
  • 可观察性:了解服务之间的依赖关系,以及它们之间流量的本质和流向,从而提供快速识别问题的能力
  • 策略执行:将组织策略应用于服务之间的互动,确保访问策略得以执行,资源在消费者之间良好分配。策略的更改是通过配置网格而不是修改应用程序代码
  • 服务身份和安全:为网格中的服务提供可验证身份,并提供保护服务流量的能力,使其可以在不同可信度的网络上流转

Istio服务网格逻辑上分为数据面板和控制面板:

  • 数据面板由一组智能代理(Envoy)组成,代理部署为边车,调解和控制微服务之间所有的网络通信
  • 控制面板负责管理和配置代理来路由流量,以及在运行时执行策略

下图显示了构成每个面板的不同组件:

Conduit

Conduit是为Kubernetes设计的一个超轻型服务网格服务,它可透明地管理在Kubernetes上运行的服务的运行时通信,使得它们更安全可靠。Conduit提供了可见性、可靠性和安全性的功能,而无需更改代码。

Conduit service mesh也是由数据面板和控制面板组成。数据面板承载应用实际的网络流量。控制面板驱动数据面板,并对外提供北向接口。

对比

Linkerd和Envoy比较相似,都是一种面向服务通信的网络代理,均可实现诸如服务发现、请求路由、负载均衡等功能。它们的设计目标就是为了解决服务之间的通信问题,使得应用对服务通信无感知,这也是Service Mesh的核心理念。Linkerd和Envoy像是分布式的Sidebar,多个类似Linkerd和Envoy的proxy互相连接,就组成了service mesh。

而Istio则是站在了一个更高的角度,它将Service Mesh分为了Data Plane和Control Plane。Data Plane负责微服务间的所有网络通信,而Control Plane负责管理Data Plane Proxy:

并且Istio天生的支持Kubernetes,这也弥合了应用调度框架与Service Mesh之间的空隙。

关于Conduit的资料较少,从官方介绍看它的定位和功能与Istio类似。

Kubernetes + Service Mesh 

= 完整的微服务框架 

Kubernets已经成为了容器调度编排的事实标准,而容器正好可以作为微服务的最小工作单元,从而发挥微服务架构的最大优势。所以我认为未来微服务架构会围绕Kubernetes展开。

而Istio和Conduit这类Service Mesh天生就是为了Kubernetes设计,它们的出现补足了Kubernetes在微服务间服务通讯上的短板。虽然Dubbo、Spring Cloud等都是成熟的微服务框架,但是它们或多或少都会和具体语言或应用场景绑定,并只解决了微服务Dev层面的问题。若想解决Ops问题,它们还需和诸如Cloud Foundry、Mesos、Docker Swarm或Kubernetes这类资源调度框架做结合:

但是这种结合又由于初始设计和生态,有很多适用性问题需要解决。

Kubernetes则不同,它本身就是一个和开发语言无关的、通用的容器管理平台,它可以支持运行云原生和传统的容器化应用。并且它覆盖了微服务的Dev和Ops阶段,结合Service Mesh,它可以为用户提供完整端到端的微服务体验。

所以我认为,未来的微服务架构和技术栈可能是如下形式

多云平台为微服务提供了资源能力(计算、存储和网络等),容器作为最小工作单元被Kubernetes调度和编排,Service Mesh管理微服务的服务通信,最后通过API Gateway向外暴露微服务的业务接口。

我相信未来随着以Kubernetes和Service Mesh为标准的微服务框架的盛行,将大大降低微服务实施的成本,最终为微服务落地以及大规模使用提供坚实的基础和保障。

参考资料:

  • Introduction to Microservices:https://www.nginx.com/blog/introduction-to-microservices
  • Pattern: Microservice Architecture:http://microservices.io/patterns/microservices.html
  • Spring Cloud for Microservices Compared to Kubernetes:https://developers.redhat.com/blog/2016/12/09/spring-cloud-for-microservices-compared-to-kubernetes
  • Istio:https://istio.io
  • Envoy:https://www.envoyproxy.io
  • Linkerd:https://linkerd.io
  • 微服务(Microservice)那点事:https://yq.aliyun.com/articles/2764?spm=a2c4e.11153959.blogcont8611.3.7ea85f19HP1APU
  • Istio中文文档:http://istio.doczh.cn
  • Linkerd中文文档:http://linkerd.doczh.cn

两个工具帮你实现酷炫的数据可视化

你想到的数据可视化

通常可能是这样的

但我们能实现的数据可视化

还可以是这样的

这样的

以及这样的

如此高端大气酷炫的数据可视化

是如何实现的?

秘诀在于两个工具

inMap & iView

inMap

inMap是TalkingData可视化团队开源的一款基于 Canvas 的大数据可视化库,专注于大数据方向的散点、热力图、网格、聚合等方式展示,致力于让大数据可视化变得简单易用。

它具有以下特性:

  • 高性能
  • 多线程
  • 多图层叠加
  • 友好的 AP
  • 可以自定义主题

inMap 采用更加智能的地理可视化框架,主要面向从事数据可视化应用相关的工程师和设计师。

底层绘图引擎:目前基于 canvas 2d 提供基础绘图能力,基于 WebGL 的版本正在规划中;

算法:内置了经纬度墨卡托转换、文字避让算法、最佳标记点算法、自动分组标记配色算法等。

inMap 的每个算法都是为了增强用户体验,追求极致效果,打造伟大的产品。

inMap 的接口设计非常友好,希望让开发者通过简单的配置,就能快速构建出优美的可视化效果。

官网:http://inmap.talkingdata.com

GitHub:https://github.com/TalkingData/inmap

iView

iView 是TalkingData可视化团队开源的一套基于 Vue.js 的 UI 组件库,主要服务于 PC 界面的中后台产品。

它具有以下特性:

  • 高质量、功能丰富
  • 友好的 API ,自由灵活地使用空间,面向任何技术水平的开发者
  • 细致、漂亮的 UI
  • 事无巨细的文档
  • 可自定义主题

同时 iView 也是一整套的前端解决方案,包括了设计规范、多语言(目前 iView 支持 15 国语言)、自定义主题、服务端渲染。

iView 支持 Vue.js 2.x、Vue.js 1.x、服务端渲染、Nuxt.js、Electron等。

iView 目前在 GitHub 上有 13,000 多 star,从 star 数量、口碑和功能性、UI / UE上,iView 都排在全球同类产品的 Top3。

官网:https://www.iviewui.com

GitHub:https://github.com/iView/iView

 iView 新版本发布

在过去的两个多月里,iView 陆续发布了 2.9.0 和 2.10.0 两个重要版本。这两个版本总共有 255 个 commit,超过 40 项更新。来看一下,iView 具体有哪些更新:

一、日期组件 DatePicker 的重构

首先是在 2.10.0 对日期组件 DatePicker 的重构。DatePicker 是 iView 48 个组件里最复杂的组件之一。复杂的功能使得代码逻辑非常重,在许多新特性的支持上,比如兼容不同国家的日历规范等都很难在此基础上迭代,不得不推倒重来。

SergioCrisostomo 之前有开发过日期相关的 JS 库(https://github.com/SergioCrisostomo/js-calendar),所以对日期相关的功能点和 API 非常熟,iView 也是基于此库进行的重构。

新的日期组件主要增加了以下功能:

1. 范围选择支持从右往左选择。

之前在范围选择时,必须先选起点,再选终点,也就是从左往右选,但很多用户的习惯却刚好相反。该版本则同时支持两个方向的选择。

2. 新增 split-panels 属性,开启后,左右两面板可以不联动。

之前在范围选择时,左右两个面板是联动的,也就是右边永远比左边大一个月,任何一个面板切换月份或年份,另一个面板都会自动切换。该版本则可以设置为不联动,这样方便定位起始月份和结束月份。如图所示:

3. 新增 multiple 属性,开启后,可以选择多个日期。

虽然之前版本可以用其它 iView 组件组合出来一个多选的日期,但效果和交互多少会打折扣,该版本只要增加属性 multiple,就可以在一个日期面板上同时选择和呈现多个日期了。如图所示:

4. 新增属性 show-week-numbers,开启后,可以显示星期数。

增加这个属性,就可以在日历面板上显示当前是一年的第几周。如图所示:

还有其它很多项的更新,比如新增 start-date 属性,可以设置面板展开时默认显示的日期。新增属性 time-picker-options,可以在 type 为 datetime 和 datetimerange 下,配置 TimePicker 的属性,比如时间间隔 steps。完整的更新可以产看更新日志,这里不一一列举了。

二、键盘可访问性的支持

键盘的可访问性,主要是通过键盘的方向键、tab键、空格键等完成表单组件的切换和交互。在填写一个表单时(iView Form 组件),尤其有用,你可以离开鼠标,就完成一个复杂表单的填写与提交。

目前 iView 最新版本支持键盘可访问性的组件有:

Button、Input、Radio、Checkbox、Switch、AutoComplete、Slider、InputNumber。更多组件还在陆续支持中。

事实上,原生的表单控件,浏览器都是支持键盘的可访问性的,比如 <button>、<input type=”radio”> 等等。iView 对这些原生控件进行了重塑,不仅仅使得 UI 好看和统一,更重要的是功能的丰富和交互体验的提升。

目前上述的组件,都是可以通过键盘的 tab键 选中的,这是第一步,如图所示:

可以看到,组件在被选中时,外面多了一个高亮层,表明当前选中的控件,这时就可以通过键盘其它按键继续操作了,比如单选组件 Radio,在选中状态下,可以通过键盘的方向键直接切换选项;Checkbox 在被激活时,可以通过空格键选择和取消选择某小项,通过 tab 键激活下一个小项。

三、其他更新

还有一些更新,是无法直接看见和体会到的。

比如更新了大量的依赖:

  • babel 系列全部更新
  • 使用了 browserslist
  • 使用了 sourcemap

部分组件的重构,虽然功能无任何变化,但代码结构和逻辑都做了优化和可维护性设计。

还有部分组件的自动化测试、持续集成对 GitHub travis-ci 的兼容等等。

外表需要优化,内部同样也是,就像一个人,既要有外在美,也要有内在美。

这两个版本都需要感谢两位瑞典大神 SergioCrisostomo 和 Xotic750 的贡献,iView 才得以越来越完善。

完整的更新日志可以到 GitHub releases 查看:

2.9.0: https://github.com/iview/iview/releases/tag/v2.9.0

2.10.0: https://github.com/iview/iview/releases/tag/v2.10.0

数据可视化可以很简约也可以很酷炫

别让工具限制了你的想象力

锐眼洞察 | 手把手教你简单快速实现5种数据可视化

作者:George Seif

原文:https://towardsdatascience.com/5-quick-and-easy-data-visualizations-in-python-with-code-a2284bae952f

译者:TalkingData数据工程师 新壮

本译文禁止商用,转载请注明来源!

数据可视化是数据科学家工作中的一个重要部分。在项目的早期阶段,你通常会进行探索性数据分析(EDA),以获得对数据的一些见解。创建可视化确实有助于使数据更易懂,特别是对于更大的高维数据集。在你的项目即将结束时,重要的是能够以清晰、简明和令人信服的方式展示你的最终结果,让你的听众可以理解,而他们通常是不懂技术的客户。

Matplotlib是一种流行的Python库,可以非常容易地用来创建数据可视化。然而,每次创建一个新项目时,设置数据、参数、图形和绘图都会非常混乱和乏味。在这篇博客中,我们会使用Matplotlib库写一些快速且简单的函数,实现5种图形可视化。同时,这里有一个非常好的图表,可以为你在工作中选择合适的可视化提供参考!

根据不同情况选择合适的数据可视化技术

散点图 

散点图很好地显示了两个变量之间的关系,因为你可以直接看到数据的原始分布。您也可以通过颜色编码来查看不同组数据之间的关系,如下图所示。想可视化三个变量之间的关系吗?没问题!只需使用另一个参数,比如点大小,对第三个变量进行编码就可以,如下面的第二个图所示。

颜色分组散点图

按颜色分组并对三个变量进行了大小编码的散点图

现在该展示代码了。我们首先引入Matplotlib的pyplot并命名为“plt”。通过调用plt.subplots()创建一个新的图。我们将X轴和Y轴的数据传入ax.scatter()绘制出散点图。我们还可以设置点大小、点颜色和alpha透明度。你甚至可以设置y轴使用对数刻度。然后针对具体的图像设置标题和轴标签。这是一个好用的函数,它从端到端地创建了一个散点图!

import matplotlib.pyplot as plt
import numpy as np

def scatterplot(x_data, y_data, x_label="", y_label="", title="", color = "r", yscale_log=False):

   # Create the plot object
   _, ax = plt.subplots()

   # Plot the data, set the size (s), color and transparency (alpha)
   # of the points
   ax.scatter(x_data, y_data, s = 10, color = color, alpha = 0.75)

   if yscale_log == True:
       ax.set_yscale('log')

   # Label the axes and provide a title
   ax.set_title(title)
   ax.set_xlabel(x_label)
   ax.set_ylabel(y_label)

线形图 

当你想清楚展示一个变量随另一个变量明显变化时(例如它们有很高的协方差),最好使用线形图。让我们通过下图来说明。

我们可以清楚地看到,所有专业的百分比随着时间的推移有很大的变化。用散点图来绘制这些图形会非常混乱,很难真正理解并看出正在发生的事情。对这种情况来说,线形图则是完美的,因为它们基本上快速地给我们总结了这两个变量的协方差(百分比和时间)。同样,我们还可以使用颜色编码对其分组。

线形图示例

下面是线形图的代码。它和上面的散点图很相似,只是变量有一些细微的变化。

def lineplot(x_data, y_data, x_label="", y_label="", title=""):
   # Create the plot object
   _, ax = plt.subplots()

   # Plot the best fit line, set the linewidth (lw), color and
   # transparency (alpha) of the line
   ax.plot(x_data, y_data, lw = 2, color = '#539caf', alpha = 1)

   # Label the axes and provide a title
   ax.set_title(title)
   ax.set_xlabel(x_label)
   ax.set_ylabel(y_label)
view raw

直方图 

直方图对于显示或发现数据点的分布非常有用。看看下面的直方图,我们画出频率 vs IQ直方图。我们可以清楚地看到均值和中位数是什么。我们也可以看到它遵循高斯分布。使用直方图(而不是散点图)可以让我们清楚地看到每个bin(直方)频率之间的相对差异。使用bin(经过离散化)确实帮助我们看到“更大的图景”,因为如果我们使用所有的数据点而不是离散化后的bin,那么在可视化中可能会有很多噪音,很难看清到底发生了什么。

直方图实例

使用Matplotlib绘制直方图的代码如下所示。有两个参数需要注意。首先,n_bins参数控制我们希望我们的直方图有多少个离散箱。更多的bins会给我们提供更详细的信息,但也可能会带来噪音,使我们远离更大的画面;另一方面,减少bins给我们更多的“鸟瞰”,描述发生了什么事情而没有更详细的细节。其次,cumulative参数是一个布尔值,它允许我们选择我们的直方图是否累积。也就是说选择的是概率密度函数(PDF)还是累积密度函数(CDF)。

def histogram(data, n_bins, cumulative=False, x_label = "", y_label = "", title = ""):
   _, ax = plt.subplots()
   ax.hist(data, n_bins = n_bins, cumulative = cumulative, color = '#539caf')
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)

假设我们要比较数据中两个变量的分布。有人可能认为你必须制作两个单独的直方图,并把它们并排进行比较。但是,实际上有一个更好的方法:我们可以用不同的透明度覆盖直方图。查看下图。均匀分布被设置为透明度为0.5,这样我们就可以看到它后面是什么。这允许直接查看同一图形上的两个分布。

覆盖直方图

在代码中设置了一些用于覆盖直方图的参数。首先,我们设置水平范围来容纳两个变量分布。根据这个范围和所需的箱数,实际上可以计算每个箱子的宽度。最后,我们将两个直方图绘制在同一个图上,其中一个稍微透明一些。

# Overlay 2 histograms to compare them
def overlaid_histogram(data1, data2, n_bins = 0, data1_name="", data1_color="#539caf", data2_name="", data2_color="#7663b0", x_label="", y_label="", title=""):
   # Set the bounds for the bins so that the two distributions are fairly compared
   max_nbins = 10
   data_range = [min(min(data1), min(data2)), max(max(data1), max(data2))]
   binwidth = (data_range[1] - data_range[0]) / max_nbins


   if n_bins == 0
     bins = np.arange(data_range[0], data_range[1] + binwidth, binwidth)
   else: 
     bins = n_bins

   # Create the plot
   _, ax = plt.subplots()
   ax.hist(data1, bins = bins, color = data1_color, alpha = 1, label = data1_name)
   ax.hist(data2, bins = bins, color = data2_color, alpha = 0.75, label = data2_name)
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)
   ax.legend(loc = 'best')

柱状图 

当你试图把类别较少(大概是10个)的分类数据可视化时,柱状图最有效。如果我们有太多的类别,那么柱状图将是非常混乱,并且难以理解。它们对于分类数据是很好的,因为你可以很容易地根据柱状的形状(例如大小)来区分类别之间的区别;类别也很容易划分和进行颜色编码。我们要看3种不同类型的柱状图:常规的、分组的和堆积的。下图中代码的顺序与图的顺序一致。

常规柱状图是下面的第一个图。在barplot()函数中,x_data代表X轴上的tickers和y_data代表Y轴上的柱状高度。error线是一条在每一柱状中间的额外的线,可以画出以显示标准差。

常规柱状图

分组柱状图允许我们比较多个分类变量。看看下面的第二个柱状图。我们首先比较的变量是分数如何根据组(G1,G2等)而变化。我们还通过颜色编码比较了他们的性别。我们来看一看代码,y_data_list变量现在真的是一个列表的列表,其中每个子列表代表一个不同的组。然后我们遍历每个组,对于每个组绘制x轴上的每一个刻度条,每组也是颜色编码的。

分组柱状图

堆积柱状图非常适合可视化不同变量的类别构成。在下面的堆积柱状图中,我们一天天地比较服务器负载。通过颜色编码后的堆,我们可以很容易地看到并理解哪一台服务器每天工作最多,以及一台服务器负载如何与其他服务器进行比较。此代码遵循与分组柱状图相同的样式。除了我们遍历每个组时在旧的上面画新的条,而不是在它们旁边。

堆积柱状图

def barplot(x_data, y_data, error_data, x_label="", y_label="", title=""):
   _, ax = plt.subplots()
   # Draw bars, position them in the center of the tick mark on the x-axis
   ax.bar(x_data, y_data, color = '#539caf', align = 'center')
   # Draw error bars to show standard deviation, set ls to 'none'
   # to remove line between points
   ax.errorbar(x_data, y_data, yerr = error_data, color = '#297083', ls = 'none', lw = 2, capthick = 2)
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)

   
def stackedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
   _, ax = plt.subplots()
   # Draw bars, one category at a time
   for i in range(0, len(y_data_list)):
       if i == 0:
           ax.bar(x_data, y_data_list[i], color = colors[i], align = 'center', label = y_data_names[i])
       else:
           # For each category after the first, the bottom of the
           # bar will be the top of the last category
           ax.bar(x_data, y_data_list[i], color = colors[i], bottom = y_data_list[i - 1], align = 'center', label = y_data_names[i])
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)
   ax.legend(loc = 'upper right')

   
def groupedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
   _, ax = plt.subplots()
   # Total width for all bars at one x location
   total_width = 0.8
   # Width of each individual bar
   ind_width = total_width / len(y_data_list)
   # This centers each cluster of bars about the x tick mark
   alteration = np.arange(-(total_width/2), total_width/2, ind_width)

   # Draw bars, one category at a time
   for i in range(0, len(y_data_list)):
       # Move the bar to the right on the x-axis so it doesn't
       # overlap with previously drawn ones
       ax.bar(x_data + alteration[i], y_data_list[i], color = colors[i], label = y_data_names[i], width = ind_width)
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)
   ax.legend(loc = 'upper right')

箱线图 

我们以前研究过直方图,其对于可视化变量的分布非常有用。但是如果我们需要更多的信息呢?也许我们想更清楚地看一下标准差?也许中位数与平均值有很大的不同,因此我们有很多离群值。如果数据有倾斜,许多值集中在一边呢?

那就是箱线图发挥作用的时候了。箱线图给了我们上面所有的信息实线盒的底部和顶部总是第一和第三分位(即数据的25%和75%),以及箱内的实线总是第二分位(中位数)。“胡须”(例如虚线条一端的条线)从箱中延伸出以显示数据的范围。

由于箱线图绘制自每一个组或变量,所以设置起来相当容易。x_data是组/变量列表。Matplotlib中boxplot()函数对y_data的每一列或y_data序列中的每个向量绘制箱线图;因此x_data中每个值对应于y_data中的列/矢量。所有我们要设定的就是绘图的美学。

箱线图示例

def boxplot(x_data, y_data, base_color="#539caf", median_color="#297083", x_label="", y_label="", title=""):
   _, ax = plt.subplots()

   # Draw boxplots, specifying desired style
   ax.boxplot(y_data
              # patch_artist must be True to control box fill
              , patch_artist = True
              # Properties of median line
              , medianprops = {'color': median_color}
              # Properties of box
              , boxprops = {'color': base_color, 'facecolor': base_color}
              # Properties of whiskers
              , whiskerprops = {'color': base_color}
              # Properties of whisker caps
              , capprops = {'color': base_color})

   # By default, the tick label starts at 1 and increments by 1 for
   # each box drawn. This sets the labels to the ones we want
   ax.set_xticklabels(x_data)
   ax.set_ylabel(y_label)
   ax.set_xlabel(x_label)
   ax.set_title(title)

结论 

以上就是使用Matplotlib简单快速实现的5种数据可视化。把事情抽象成函数总能让代码更易于阅读和使用。希望你喜欢这篇文章,并学到一些新的、有用的东西。如果你没有,就随便给它一些掌声吧~

技术专栏 | 走进分布式一致性协议

作者:TalkingData 战鹏弘

本文由TalkingData原创,转载请获取授权。

在分布式系统中,每一个机器节点虽然都能明确的知道自己在进行事务操作过程中的结果是成功或失败,但却无法直接获取其它分布式节点的操作结果。因此,当一个事务操作需要跨越多个分布式节点的时候,为了保证事务处理的ACID特性,需要引入一个成为“协调者”的组件来统一调度所有分布式节点的执行逻辑,这些被调度的分布式节点则被称为“参与者”。协调者负责调度参与者的行为,并最终决定这些参与者是否要把事务真正进行提交。基于这个思想,衍生出了二阶段提交(2PC)和三阶段提交(3PC)。

2PC

为了使分布式系统下所有节点在进行事务处理的时候能够保持原子性和和一致性而设计的算法。

两个阶段

阶段一:提交事务请求

协调者向各个参与者发送事务内容,询问是否可以执行事务操作,等待参与者响应。

参与者接收到询问之后,执行事务操作,但是不commit,将undo和redo信息保存到事务日志中。

参与者根据执行情况向协调者返回是否可以执行事务的响应。

阶段二:执行事务提交

阶段一参与者都返回yes

协调者收到所有的yes信号之后,通知参与者执行最后的commit,参与者执行完成之后,想协调者返回ACK信息。

协调者接收到所有的ACK信息之后,完成分布式事务操作

阶段一某个参与者返回no

说明其中一个参与者无法成功执行事务,协调者通知所有参与者回滚事务。

参与者进行事务回滚,完成之后向协调者返回ACK信息

协调者接收到所有的ACK信息之后,事务中断完成

协调者的作用

阶段一

发送给参与者信息

接收参与者反馈,确定下一步需要发送给参与者的信息

阶段二

根据阶段一获得的响应,确定需要发送给参与者的信息(此时如果协调者出问题,无法通知参与者执行commit,参与者的资源会一直被锁住)

接收参与者的反馈,事务结束

注意问题

同步阻塞
第一阶段各个参与者执行事务操作的过程都是阻塞的,各个所有参与者全部完成响应之前,资源都是被加锁的,无法进行其它操作。

协调者的单点问题
两个阶段都需要协调者进行协调,第二阶段中协调者向参与者发送事务commit的新号时,一旦出问题,参与者将无法提交commit操作,资源一直会处于锁定状态,无法释放。

数据不一致
第二阶段协调者发送事务commit信息时,如果与某个参与者的连接出问题,会出现其他参与者成功提交事务,而该参与者事务无法提交,各个参与者的数据会出现不一致的情况。

3PC

阶段一(canCommit)

区别于2PC,3PC的第一阶段会询问所有的参与者是否可以进行事务提交,但是不去执行事务(2PC的第一阶段实际上去执行了事务,但是没有commit而已),这一阶段可以在不锁定资源的前提下,判断各个参与者是否能够执行事务,当然各个参与者返回yes不代表后续执行事务一定会成功。

2PC的第一阶段会真正执行事务,如果某个参与者出现问题,消耗了很长时间返回给协调者no信号,再这个很长时间内,其它的参与者会一直锁定资源,block在那里。3PC的第一阶段有效的解决了该问题。

阶段二(preCommit)

阶段二同2PC的阶段一实际上是相同的,会执行事务但是不提交,但是很大程度上减少了2PC在他的阶段一出现阻塞的问题

阶段一参与者都返回YES

各个参与者执行事务,但是不提交,返回给协调者ACK信号

阶段一有某个参与者返回no

协调者通知参与者中断事务,因为第一阶段中没有执行操作,所以不需要回滚

阶段三(doCommit)

阶段二所有参与者返回yes

说明各个参与者事务执行成功,通知参与者进行commit,返回给协调者ACK,完成事务

阶段二某个参与者返回No

通知所有参与者回滚事务,返回给协调者ACK,中断事务

注意问题

进入阶段三之后,如果协调者出现故障或者与参与者之间的连接出现问题,参与者等待commit信号超时之后,会继续进行事务提交。这种机制一定程度上在协调者故障或者连接出问题时,解决数据不一致问题。

2PC和Paxos

2PC和Paxos作为分布式一致性协议,分别适用于两类一致性:操作原子性和副本一致性。

2PC:保证分布式环境中的多台机器的操作的原子性,要么全部成功,要么全部不成功

Paxos:保证同一个数据分片的多个副本之间的数据一致性

Paxos算法

Paxos算法是莱斯利-兰伯特于1990年提出的一种基于消息传递且具有高度容错性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。

Paxos算法需要解决的问题是如何在一个可能发生机器宕机或者网络异常等异常的分布式系统中,快速且正确的在集群内部对某个数据的值达成一致,并且保证无论发生上述任何异常,都不会破坏整个系统的一致性。

分布式系统的存在为了解决单点问题,例如典型的master slave模式,一旦master宕机之后,需要将slave节点切换为master节点,条件是slave和master节点的数据是一致的,也就是说在master上的一切操作都需要同步到slave节点上,这样的slave才具备选举为master的条件。Paxos算法可以为这种数据一致性提供有效的保障。

Paxos算法可以分为两个阶段,prepare阶段和accept阶段,下面简单阐述一下这两个阶段。

prepare阶段

假设现在分布式集群中有三个节点:A、B、C,A把申请操作的请求发送给A、B、C,发送的请求会携带一个Sequence Number(这个值会不断递增,且是唯一的),接受节点在prepare阶段会拒绝接受到的任何提案号小于当前提案号的请求。

如果接受节点接收到的提案号大于当前提案号,节点会给节点A返回yes,并且不在接受提案号更小的提案,也就是说节点总会对最新的提案号做承诺。

accept阶段

如果提案者A收到了半数以上的节点返回yes,他会再次向接收节点发送accept request,仍会携带一个sequence number(n),当接收节点收到accept request信号之后,如果n是接收者接收到的最新的提案号,那么会最终通过提案,如果发现存在比n更大的提案号,拒绝该request,同时提案者会重新进行第一阶段(prepare阶段)。

具体的执行过程如下图所示:

(图片来自:https://www.cnblogs.com/cchust/p/5617989.html)

分布式一致性算法的工程实践

Chubby

Google Chubby是一个有名的分布式锁服务,Google的GFS和Big Table等大型分布式系统都是用它来解决分布式写作、元数据存储和Master选举等一系列与分布式锁相关的问题。

假设Chubby集群中有5台服务器:A B C D E,其中A是当前的master,另外4台服务器实际上是A的副本。Chubby实际运行过程中,只有作为master的A服务器会对外提供写操作服务,其他四台服务器通过Paxos协议从A服务器中同步数据的操作,Paxos协议能够有效的保证副本节点的数据和master节点之间保持一致性。

Chubby中每次提案value的选定是一个Paxos instance,提案由多个proposer提出,最终得到一个value。每次提案的选举都会计入到底层的log日志中,由于Chubby需要不间断的对外提供服务,因此会不断产生Paxos instance,事务日志也会不断增长。每个Paxos instance负责确定一个value,多个instance之间是互不相关的,可以并发进行。将Paxos每两个阶段的提交prepare→promise→propose→accept记作一个round,每个Paxos instance执行过程中可能会经历多轮round,最终才能确定最后的提案。

上述基本的Paxos算法执行过程存在可优化的地方:多个proposer的活锁问题会严重影响效率,导致一个instance最终选定提案需要执行多轮round。

实际执行过程中,可以将多个instance的prepare阶段合并成一个阶段。首先必须在多个proposer中选举出一个master作为唯一的proposer,原本多个instance之间是互相独立的,只需要保证instance内部的round序号不重复即可。现在为了合并prepare阶段,多个instance之间公用一套序号,具体做法如下:

当某个replica通过选举获得master资格后,用新分配的编号N广播一个prepare消息,这个prepare消息被所有未达成一致的instance和将来还未开始的instance共用。

当acceptor接收到prepare后,现在必须对多个instance同时做出回应,这可以封装在一个数据包中,假设最多允许K个instance同时选举,那么:

当前至多有K个未达成一致的instance,将这些未决的instance各自最新accept的value(若没有用null代替)封装进一个数据包,作为promise消息返回

同时,标记这些未决instance和所有未来instance的highestPromisedNum为N,如果N比它们原先的值大的话。这样,这些未决instance和所有未来instance都不能再accept编号小于N的proposal。

然后master就可以对所有未决instance和所有未来instance分别执行propose→accept阶段,始终使用编号N,如果这个master保持稳定的话,就再也不需要prepare→promise了。但是,一旦发现acceptor返回了一个reject消息,说明另一个master启动,用更大的编号M>N发送了Prepare消息,这时自己就要分配新的编号(必须比M更大)再次进行prepare→promise阶段。

ZooKeeper

在ZooKeeper中,client向ZooKeeper提出一个事务,例如创建一个znode,请求会发送到ZooKeeper中的所有机器上,leader需要协调事务的执行,只要集群中半数以上的机器成功执行了该事务,leader便会通知follower进行事务提交。leader作为ZooKeeper中最重要的角色,协调事务执行过程中会保存一个全局的变更序列,可以保证如果一个状态变更已经被处理了,那么所有以来的状态变更应该已经被提前处理了。
ZooKeeper中使用的分布式一致性协议ZooKeeper Atomic Broadcast(ZAB,ZooKeeper原子消息广播协议),ZAB协议的消息广播过程使用的是一个原子广播协议,类似于一个二阶段提交过程。根据客户端的事务请求,leader服务器会为其生成对应的事务poposal,并发送给集群中其余所有的机器,然后收集各自的选票,最后进行事务的提交。

与二阶段提交不同的是,ZAB协议移除了终端逻辑,所有的follower服务器要么正常反馈leader提出的事务proposal,要么抛弃leader服务器,这意味着leader可以在过半的follower服务器已经反馈ACK信号之后就开始提交事务proposal,而不需要等待所有的follower服务器都反馈响应。当时,这种简化的二阶段提交下,无法处理leader服务器崩溃退出而带来的数据不一致问题,因此ZAB协议添加了崩溃恢复模式来解决这个问题。

ZAB协议的执行过程

ZAB主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段,分别是发现(Discovery)、同步(Synchronization)、广播(Broadcast)阶段。ZAB的每一个分布式进程会循环执行这三个阶段,称为主进程周期。

发现:选举产生PL(prospective leader),PL收集Follower epoch(cepoch),根据follower的反馈,PL产生new epoch(每次选举产生新Leader的同时产生新epoch)。

同步:PL补齐相比follower多数派缺失的状态、之后各Follower再补齐相比PL缺失的状态,PL和follower完成状态同步后PL变为正式leader(established leader)。

广播:leader处理客户端的写操作,并将状态变更广播至follower,follower多数派通过之后leader发起将状态变更落地(deliver/commit)。

在正常运行过程中,ZAB协议会一直运行于阶段三来反复进行消息广播流程,如果出现崩溃或其他原因导致leader缺失,那么此时ZAB协议会再次进入发现阶段,选举新的leader。

leader可能在事务提交完成或者提交了一半的时候崩溃,因此leader选举算法需要确保提交已经被leader提交的事务的proposal,同时丢弃已经被跳过的事务proposal。

如果让leader选举算法能够保证新选举出来的leader服务器拥有集群中所有机器最高编号(ZXID最大)的事务proposal,那么就可以保证这个新选举出来的leader一定具有所有已经提交的提议,更为重要的是如果让具有最高编号事务的proposal机器称为leader,就可以省去leader服务器查询proposal的提交和丢弃工作这一步骤了。

锐眼洞察 | 如何正确构建数据平台

作者:Michelle Knight

原文:Predictive Customer Analytics — Part Ihttp://www.dataversity.net/data-architecture-need-choose-right-data-platform/

译者:TalkingData数据工程师 孙强

本译文禁止商用,转载请注明来源!

做了不够理想的数据架构和数据平台,就像是买东西时找不到钱包或现金。 正如McKnight咨询集团总裁McKnight在其DATAVERSITY Database Now! Online 2017 Conference的主题演讲中提到的:“我们可能会被数据淹没,该选择合适的平台了!”

McKnight是一位经验丰富的信息管理战略家,也是《信息管理:利用数据获得竞争优势的策略》的作者。他在发言中强调:

“我们的经济完全依赖于数据的自然资源。 我们的组织拥有(数据)这个黄金资产。我们的组织在未来十年如何竞争并获得优势,完全取决于我们如何使用数据。”

作为推荐数据平台的专家,McKnight在他的职业生涯中进行了多项成熟的研究。他指出,那些更充分运用数据的行业以及行业内的企业,比那些没有充分运用数据的行业和企业做的更好。 McKnight观察到“这些表现最佳的行业和企业们正在扩展其大数据应用。”

那么,为什么现在要考虑数据架构呢? McKnight表示,我们需要摆脱“快我一些数据”和“高效的给我优质的数据”的思路,转向“快速、高效的提供所有数据”。为了实现这种需求,“是时候做些跳出常规、与众不同的事情了。”McKnight表示:

“要处理超出能力范畴的需求很难。 但是我们必须使平台正确适用于工作负载,并使其与数据集成和数据可视化一起工作。 数据仓库不再是宇宙的中心。 那些非关系型平台实际上为我们提供了有价值的参考。”

选择数据平台时该考虑什么?

对于在组织的整个数据架构中构建更高效的数据平台来说,选择正确的数据存储类型至关重要。

McKnight表示:“过去一切都是数据库。 但是现在还有很多其他的选择,比如“严格来讲不在位和字节级的数据库”的基于文件的扩展系统。 基于文件的扩展系统没有围绕数据的相同框架。他建议这样的系统尤其适用于非结构化或半结构化数据。 其他必要考虑的包括:

  • 数据存储位置:McKnight表示:“并不是必须将数据存储在数据中心。”现在有很多更具性价比的云可供选择。 比如私有云、公有云和很多混合云的选择。
  • 工作负载架构:“区分操作性或分析性的工作负载,”McKnight建议。 “短交易请求和更复杂(通常更长)的分析请求需要不同的体系结构。”分解工作负载的需求并围绕这些工作负载正确设计数据平台至关重要。
  • 内存:McKnight观察到,很多人仍执迷于HDDs(硬盘驱动器),他敦促组织“开放一点点”。现在市场上还有很多选择,比如固态硬盘(SSD) 、内存(In-Memory)以及其他较低成本的存储器。

他举了可提供超快速性能的内存数据存储作为示例: “对于选择性的工作负载,它具有很高的专用功能性,为ROI提供更多机会。 我们现在开始更多探索内存的利用。”

他将内存选择比喻为“吹动风帆的风”,这让帆船行驶的更快,并超越其他竞争对手。他表示,内存可能会“在我们进行设计过程时给出更多的容错空间。

不要忘记Data Profile

所谓数据成熟度,就是“创建一个高效的环境,我们可以向环境里添加内容,而无需每次重新开始。”为此,组织需要查看Data Profile。 “我们中的许多人在排列优先事项时是颠倒的。”McKnight说:

“我可以从Data Profile中获得很多信息。 比如数据的大小和类型、是结构化的还是非结构化的、一些示例记录以及数据输入的频率。数据来自哪里? 被访问的频率如何?数据的质量如何?”

云提供了有吸引力的选择

McKnight表示,当他与客户一起为数据平台选项融资时,“许多公司不想处理资本化支出。 他们更愿意操作他们,这就是云模式,对吧?“在思考云时,紧密集成是势在必行。

McKnight提供了以下例子:

“你可能会把你的数据仓库放到云中。 那商业智能呢,你会把它们放到云端吗?数据集成如何? MDM呢,可以放在云端吗? 以上所有都是可以的。 当开始认真思考数据,这些问题就会随之产生。”

他表示,一个成熟的数据架构“现在不是有一些、而是有很多云可以选择”。McKnight强调说,现在有不同的云模型,重要的是找到适合的。

新的选择维度

除了上述因素之外,还需要为数据平台权衡新的选择维度。 如:

  • SQL的稳健性:“SQL中有一些新发现的功能使其具有重要意义。”
  • 内置优化:全面考虑云和数据虚拟化。 优化器现在有更多的作用。
  • 即时弹性:问问自己,是否真的拥有它? 是否真的需要它?
  • 动态环境适应性:评估同时使用并发使用模式的能力。
  • 将计算从存储中分离出来:这对于云计算来说非常重要,可以分别对这两种情况进行扩展。
  • 支持多种数据:需要考虑到,会有JSON、XML和各种形式的非结构化数据流入企业数据环境。

用数据平台取得成功

基于McKnight过去几年所合作的客户,他指出:“用户数量、性能预期、数据量、分析复杂性等方面需求已经开始大幅增加”。因此,成功建立数据平台至关重要,可以通过以下方式来确定:

  • 性能:McKnight将性能视为首要点。他认为:

“我们可以通过平台决策为用户提供更好的性能。 随着他们在数据中的能力而增长并不会受到限制,因为每个查询将需要5分钟。 如果这些查询出现,他们将进入更深层次。 如果您一段时间没有考虑数据平台,那这些就不会发生。”

  • Provisioning:McKnight将其描述为“可以多快地启动并运行数据平台? 它有多敏捷?“
  • 规模:建议考虑:“我可以从小型开始再逐步扩大吗?”
  • 成本:不要过度消耗成本。 保持在组织所能负担的成本。

用数据平台取得成功

McKnight为成功搭建数据平台提供了七条最终建议:

  1. 针对不同规模的企业,现在有各种数据平台可供选择
  2. 选择正确的平台并按规划进行
  3. 从数据的存储类型、布局和工作负载架构开始
  4. 将Data Profile作为选择正确平台的重要依据
  5. 确保数据平台能够支持现有的和未指定的需求
  6. 分析平台应该是分级操作数据存储(ODS)或数据仓库(DW)或数据集市(来自DW或专门供应)或Hadoop
  7. 云现在能够提供更经济的更有吸引力的选择

重磅!TalkingData2017年移动互联网行业发展报告

本文由TalkingData原创,转载请获取授权。

自2016年第二季度起,中国移动智能终端规模增速连续七个季度低于2%。增长困局下,移动数据的应用场景细化、与线下消费的深度融合成为了破局点。2017年的新零售、无人货架等热点,皆是围绕这两个主题。智慧经济,就是将人工智能、 大数据、互联网自动化能力融入各行各业。移动互联网推动了各行业的数字化进程。从业务数字化到效益数字化,线上线下数据融合后的数据资产将帮助企业和组织实现智能化决策,打造智慧经济。

本报告中,我们将关注增长困局下的人本洞察、移动应用、智能终端,回顾移动数据与各行各业的深化融合,并提出智慧经济趋势下的数字化转型方法论。

移动智能终端低增速时代开启已有七个季度

中国移动智能终端设备规模季度增速放缓,自2016年第二季度起,移动智能终端增速就跌破2%。移动智能终端用户规模步入低增速时代已有七个季度。

移动智能终端用户在经济发达地区集中度更高

截至2017年12月,我国移动智能终端用户TOP10省份占据了整体近六成用户。位居2017省市人均GDP排名前六位的北京、江苏 、浙江、广东作为经济发达地区,移动智能终端用户集中度更高,其智能终端用户占比要高于人口占比,人才吸附能力更强。

城市人生活愈加繁忙,生活半径在增大、通勤距离在增加

通过分析北京地区上班族的活动范围,可以观察到现代人在城市中的生活半径在扩大,长距离通勤的人群比例在增加,都市生活愈加繁忙,人们对于生活、交通便捷性的需求值得被关注。

城市存在时空折叠,均衡的资源不代表将被均衡利用

通过分析北京地区高消费与低消费人群利用商业设施的状况发现,虽然北京不同区域的商业设施配置和分布相对均衡,但两个群体对设施的利用在时间和空间上却鲜少重合。

 

男性用户占比下降,性别分布趋于平衡

2017年,随着移动智能终端用户趋于饱和,移动智能终端用户性别特征逐渐趋近人口学特征,预计2018年中国智能终端用户中男性用户占比将会下降至52.5%。

 

年轻人群仍为用户主体,90后成未来消费主力

2017年,我国移动智能终端用户中35岁及以下用户的比例达69.9%,年轻用户仍然是移动互联网用户的主体。

随着更多90后人群步入职场,他们将成长为消费主力。相比80后,他们的生活状态已被移动互联网深度影响。

90后人群开始逃离北上广深

 相比80后,90后人群城市层级分布中一线城市占比要更低。90后人群开始逃离北上广深,更多的选择郑州、武汉等区域中心城市作为个人发展的起点。

活跃用户规模下降,主流行业应用增长乏力

2017年,通讯社交、视频、游戏等主流行业应用活跃用户规模增长乏力,而教育、旅游、健康美容等行业类别应用覆盖率及活跃率出现双增长,行业潜力正在释放。

每日打开应用数量下降,首屏应用竞争加剧

移动智能终端用户平均安装与平均每日打开应用款数已连续两年出现下滑,设备一个屏幕上的应用已可基本满足日常使用。存量时代移动应用对于用户的争夺更加激烈,现有数据价值的深挖成为运营关键。

头部应用把持主流用户,新应用面临艰巨挑战

2017年,移动互联网头部应用覆盖率领先优势明显,细分行业中的TOP5应用覆盖了行业主流用户。

OPPO、vivo市场份额增长,线下渠道价值得到体现

2017年表现最为亮眼的移动智能设备品牌是主打线下渠道的OPPO与vivo,两个品牌的市场份额分别从2016年12月份的8.6%、7.3%增长至2017年12月份的12.6%、10.3%。

从派生到原生,资源融合丰富用户数据价值

移动互联网已从派生模式发展到原生模式,相比于新闻资讯、搜索、视频等派生模式服务内容,原生模式对于线下资源的融合度更高,实体资源为服务商带来更多的用户流量与交互数据资产。

运营模式过重,原生模式赛道洗牌速度加快

资源融合加重移动互联网原生模式运营成本,行业竞争成为资本之争。头部应用融资、并购速度加快,而缺少资本支持的小玩家迅速走向消亡。

资本热潮之后,共享经济用户向二三线城市下沉

作为2017年原生模式新赛道的代表,共享充电宝、无人货架在经历了初期的资本热潮后,运营模式逐渐向二三线城市倾斜,用户下沉成为验证商业模式的突破口。

双管齐下,互联网巨头布局数据融合生态

通过手机支付、微信小程序等数据融合工具的运营,以及线下对百货商超、零售集团、生鲜超市等零售业态的投资布局,阿里巴巴与腾讯正在围绕线下消费打造数据融合生态。

重构人、货、场,数据融合推动零售新探索

以盒马鲜生等生鲜超市为代表,移动数据正在融入零售各个环节,人、货、场关系被重构,交易、交互等数据的融合在推动零售产业链的数字化探索。

精准触达,移动数据深化金融服务场景

借助移动应用数据,金融服务能够精准触达大货车司机、留学生等细分人群,围绕应用描绘人群理财偏好。线上数据的融入让金融服务触达的服务场景更加细化,金融普惠性得到提升。

从数字到数字,业务决策将走向智能化

以业务数字化为起点,以效益数字化为节点,通过数据资产化、分析模型化、应用场景化、流程自动化四项能力构建,线上线下数据融合后的数据资产将帮助企业和组织实现智能化决策,打造智能化组织。

获取本报告完整版

请点击:http://mi.talkingdata.com/report-detail.html?id=719

锐眼洞察 | 预测性客户分析Part 4——借助聚类和预测分析优化售后服务(翻译)

作者:Ryan Aminollahi

原文:Predictive Customer Analytics — Part 4

译者:TalkingData研发副总裁 阎志涛 

本译文禁止商用,转载请注明来源!

本篇是这个系列文章的最后一个部分,将要说明的重点案例是利用聚类分析对售后问题进行分组,对不同分组进行分析,进而采取针对性的优化或者行动。

如果你读过以前的几篇文章,你知道在故事中,顾客X已经购买了一台笔记本电脑。现在想象一下,他正尝试在家里设置这台电脑。在设置的时候,他发现该电脑无法与无线键盘正常连接。他认为自己搞砸了设置并试图找到解决办法:他浏览产品网站查看是否有任何自助视频可帮助他找出原因,但他并没找到任何有用的信息。然后他打电话给公司,得到了一个自动提示让他提供所有的信息。

他在接下来的15分钟排队等候,最终,他排到了一位客户代表,客户代表再次要求他提供所有信息。正如你可以想象的那样,X变得更加恼火。客户代表在听到他的问题后,通过电话向他提供了一些指示,但X无法理解并按照步骤来操作。他要求提供现场帮助,但客户代表拒绝了他,说他的保修不包含现场服务。X感觉非常沮丧,开始考虑再也不从这家供应商购买任何东西。

这是因低质量服务和支持而感到沮丧的无数顾客中的一个例子。在今天的互联网世界中,更换供应商只需点击一下鼠标即可。企业需要更努力、更聪明地保持现有客户的满意度,并且通过他们的推荐获得新的客户。客户服务流程从为客户提供交互选项开始,从网站自助、电子邮件到电话支持,今天的支持中心运行在全方位的各种渠道上。

一旦客户发起联系,企业就需要为他们提供优质的服务:询问最少的问题并迅速解决问题。

这就要求企业不仅要了解客户,还要了解客户当前问题发生的背景以及与客户交互的整个过程。企业需要让客户感觉到企业真正了解并关心他的问题。

今天的客户服务世界已经开始转向使用交互式语音和聊天机器人的自助服务和自动化的时代。

这些自动化的服务需要智能地预测客户正在经历的事情,并能理解客户问题,提供快速的解决方案。预测性分析肯定会对客户服务领域有所帮助。

预测客户发起联系的目的

让我们思考一下前面做错了什么。假定客户X在销售阶段已经将自己的电话号码提供给了公司,客户支持难道不应该通过他的呼叫ID自动识别他吗?

客户X在笔记本电脑交付给他两天之内打电话,是否意味着这通电话非常有可能与这次购买有关呢?在第一次电话过程中,客户支持针对他的笔记本电脑键盘问题创建了一个问题记录,并且给了他一些建议。

然而,过了两个小时之后他又打电话过来,客户支持能否推测到他的第二个电话非常有可能与第一个问题记录有关系?这个用例的目标是建立一个预测模型,这个预测模型可以预测客户联系企业的可能性原因。知道这个原因可以帮助企业快速将客户对接到能解决相应问题的人那里,从而让问题在第一次交互时得到解决。这个用例中的数据是过去的所有客户和企业之间的交易数据。

这些数据包含销售的交易信息,包括产品、状态以及交付的详细数据。我们将来也会使用客户与企业以往联系的数据。对于每一次联系,我们会使用原因、处理这次联系的客户代表、时长、根本原因、解决方案、状态等数据。这是一个分类问题,因此前面我们使用过的算法就比较适合。让目标分类的数量小于10是非常重要的。

将要使用的算法会被用来产生预测目的模型,我们将会使用销售交易和与以前的联系相关的数据去产生这个模型,并将用模型预测客户联系的目的。行动计划如下:这个分类模型会离线进行构建,当一个客户通过电话或者聊天工具联系企业时,使用呼叫者ID或者用户ID去识别客户,然后使用算法去预测这次呼叫的原因。如果预测呼叫的原因是上一次的购买,则通过IVR回答客户“您好,请问您是因最近购买的笔记本电脑有问题而需要帮助吗”。客户一定会感到非常高兴,因为企业能够猜测他的问题,尽管这不一定是真正的原因。

这恰当地表明了我们理解他并且知道他正在经历什么困难。

寻找不满意的客户

一个企业该如何发现他的客户对于企业的产品或者服务是满意还是不满意呢?

第一, 不满意的客户通常会对调查问卷进行反馈。仔细想一下,因为X先生对服务以及产品感到不满意,他通常更愿意花时间去填写调查问卷和发泄。但是Y女士则未必会如此。

第二, 通常仅仅有10%的客户会对调查进行反馈。那么企业如何能够识别出那些沉默的、想要或者已经转移到其他企业的客户呢?这个用例的目标是构建一个模型,这个模型能够预测企业的所有用户的满意度,不管这个用户是否填写了调查问卷。构建这个模型的数据是从那些真实的已填写调查问卷的客户中得来的。

这份数据包括客户的人口统计学数据以及用户历史行为数据,包括与公司之间的事件和交易数据以及结果。特别需要指出的是,这些数据包括缺陷、退货、客户支持的记录、解决问题的时间以及呼叫服务电话的次数,这些数据构成了特征变量。目标变量是从调查问卷得来的度的分数。比较典型的是这个分数是从0到5或者是从0到10的有一位到两位小数的数字。

如果分数是离散的值,比如1、2、3、4、5,那么我们可以使用Gordon分类来处理。在我们的用例中,我们假定分数值是连续的,因此我们将会使用线性回归算法。利用人口统计学和历史的数据,构建一个可以用来预测客户满意度分数的线性回归方程。这个用例的行动计划是:利用真正回答了调查问卷的客户的数据构建一个预测模型,来预测客户满意度分数。我们需要将调查数据进行规范化,从而去掉可能会影响整体模型的异常值,然后我们将模型应用到所有客户,来发现客户的满意度评分。

然后我们的客户支持团队得到一个最不满意的客户列表,可以去主动联系这些客户,询问他们使用产品的感受和问题或者最终给他们一些折扣。

将问题进行类型分组

客户支持团队每天在处理不同的问题,有些问题会被经常问到并且简单直接,技术工程师甚至可以在客户解释完问题之前就能给出解决方案。另外一些问题则不那么常见并且比较复杂,需要多次的电话沟通以及现场服务才能解决。一个网络连接问题是非常容易诊断的,但是诊断一个笔记本电脑的蓝屏问题则要困难得多。实际上人力资源成本是非常高的,因此企业需要找到优化使用人力资源的方法。

这包含对一些问题提供在线帮助,包括对技术支持团队更严格的培训或者对复杂问题建立新的专家职位。为了帮助企业做这些决策,需要基于相似的属性对问题进行分组。这是这个用例的目标,对于一个问题类型列表,企业需要识别逻辑的问题分组,从而使用它们去开发优化那些消耗最少人力资源的解决方案。

这个用例的数据,是从技术支持团队记录下来的问题库数据中得到的问题统计数据。问题数据按照问题类型做汇总。特征数据是解决问题的平均时间、平均电话的次数、替换率等等。既然我们要创建逻辑分组,我们将要使用K-Means聚类算法或者相关的一些变种算法。通过多次采用不同的K值进行试验来衡量出一个最佳的分组数量。

利用问题统计数据,我们能够将相似的问题进行分组。行动计划如下:当问题类型已经被分组,我们将会分析每个分组去发现分组里边的相似性,比如解决问题花了更长的时间或者非常低的发生率。然后我们就可以得出优化解决方案的计划,例如在我们的网站上提供自帮助、在YouTube提供视频或者对这个问题领域的技术人员做更好的培训。

作为一个企业,我们想要达到客户支持的效率和有效性的最大化。这个用例帮助我们达到这个目标。

问题分组用例

我们如何能够将相似的问题分组到不同的问题类型,然后在组里对它们进行分析来判断是否有任何模式,紧接着采取某些行动去解决效率和有效性问题?

载入数据集

In [1]:

(注:左右滑动即可查看完整代码,下同)

%matplotlib inlinefrom pandas import Series, DataFrame
import pandas as pd
import numpy as np
import os
import matplotlib.pylab as plt
from sklearn.model_selection  import train_test_split
from sklearn.cluster import KMeans
import sklearn.metrics

raw_data = pd.read_csv(“issues.csv”)
raw_data.dtypes

Out [1]:

PROBLEM_TYPE             object
COUNT                     int64
AVG_CALLS_TO_RESOLVE    float64
AVG_RESOLUTION_TIME       int64
REOCCUR_RATE            float64
REPLACEMENT_RATE        float64
dtype: object

这个数据集对于每个唯一的问题类型有一条记录,每个类型包含一些度量值,例如总量,解决问题平均电话次数,解决问题平均时常等等。

raw_data.head()

将数据分到不同的相似聚类组中

现在我们将会使用K-Means聚类去根据属性将数据聚类到不同的组当中。首先,我们需要决定分组的最优的数量,为此,我们采用膝部法来测试确定什么时候这个膝状发生。(参照https://datasciencelab.wordpress.com/2013/12/27/finding-the-k-in-k-means-clustering/)

In [3]:

clust_data = raw_data.drop(“PROBLEM_TYPE”,axis=1)#Finding optimal no. of clusters
from scipy.spatial.distance import cdist
clusters=range(1,10)
meanDistortions=[]

for k in clusters:
model=KMeans(n_clusters=k)
model.fit(clust_data)
prediction=model.predict(clust_data)
meanDistortions.append(sum(np.min(cdist(clust_data, model.cluster_centers_, ‘euclidean’), axis=1)) / clust_data.shape[0])

#plt.cla()
plt.plot(clusters, meanDistortions, ‘bx-‘)
plt.xlabel(‘k’)
plt.ylabel(‘Average distortion’)
plt.title(‘Selecting k with the Elbow Method’)

Out [3]:

<matplotlib.text.Text at 0x27298f49eb8>

观察那些点,我们发现膝状发生在cluster=3的时候,这是聚类的最佳的数量,因此我们在实际操作中将会设置聚类的数量是3。然后我们在原始的数据集上添加聚类的ID。

In [4]:

#Optimal clusters is 3
final_model=KMeans(3)
final_model.fit(clust_data)
prediction=final_model.predict(clust_data)#Join predicted clusters back to raw data
raw_data[“GROUP”] = prediction
print(“Groups Assigned : \n”)
raw_data[[“GROUP”,“PROBLEM_TYPE”]]
Groups Assigned :

对分组进行分析

我们现在可以做一系列的箱型图去看这些不同组在不同的特征变量上的差异。我们从count先开始。

In [5]:

plt.cla()
plt.boxplot([[raw_data[“COUNT”][raw_data.GROUP==0]],
             [raw_data[“COUNT”][raw_data.GROUP==1]] ,
               [raw_data[“COUNT”][raw_data.GROUP==2]] ],
           labels=(‘GROUP 1′,’GROUP 2′,’GROUP 3’))

Out[5]:

{‘boxes’: [<matplotlib.lines.Line2D at 0x27299349ef0>,
<matplotlib.lines.Line2D at 0x27299362390>,
<matplotlib.lines.Line2D at 0x27299375cc0>],
‘caps’: [<matplotlib.lines.Line2D at 0x272993589b0>,
<matplotlib.lines.Line2D at 0x27299358ac8>,
<matplotlib.lines.Line2D at 0x2729936abe0>,
<matplotlib.lines.Line2D at 0x2729936eb38>,
<matplotlib.lines.Line2D at 0x2729937ec50>,
<matplotlib.lines.Line2D at 0x2729937ed68>],
‘fliers’: [<matplotlib.lines.Line2D at 0x2729935db38>,
<matplotlib.lines.Line2D at 0x27299375ba8>,
<matplotlib.lines.Line2D at 0x27299385dd8>],
‘means’: [],
‘medians’: [<matplotlib.lines.Line2D at 0x2729935d320>,
<matplotlib.lines.Line2D at 0x2729936ec50>,
<matplotlib.lines.Line2D at 0x272993855c0>],
‘whiskers’: [<matplotlib.lines.Line2D at 0x27299350940>,
<matplotlib.lines.Line2D at 0x27299350a58>,
<matplotlib.lines.Line2D at 0x27299362b00>,
<matplotlib.lines.Line2D at 0x2729936aac8>,
<matplotlib.lines.Line2D at 0x27299379be0>,
<matplotlib.lines.Line2D at 0x27299379cf8>]}

我们可以看到在不同的分组中问题的数量有明显的区别。
接下来我们看解决问题的平均电话数量。

In [6]:

#Now for Avg. Calls to resolve
plt.cla()
plt.boxplot([[raw_data[“AVG_CALLS_TO_RESOLVE”][raw_data.GROUP==0]],
             [raw_data[“AVG_CALLS_TO_RESOLVE”][raw_data.GROUP==1]] ,
               [raw_data[“AVG_CALLS_TO_RESOLVE”][raw_data.GROUP==2]] ],
           labels=(‘GROUP 1′,’GROUP 2′,’GROUP 3’))

Out[6]:

{‘boxes’: [<matplotlib.lines.Line2D at 0x272993f2ba8>,
<matplotlib.lines.Line2D at 0x27299405da0>,
<matplotlib.lines.Line2D at 0x2729941a710>],
‘caps’: [<matplotlib.lines.Line2D at 0x272993f8cc0>,
<matplotlib.lines.Line2D at 0x272993fdc18>,
<matplotlib.lines.Line2D at 0x2729940fd30>,
<matplotlib.lines.Line2D at 0x2729940fe48>,
<matplotlib.lines.Line2D at 0x27299421f60>,
<matplotlib.lines.Line2D at 0x27299428eb8>],
‘fliers’: [<matplotlib.lines.Line2D at 0x27299405c88>,
<matplotlib.lines.Line2D at 0x27299415eb8>,
<matplotlib.lines.Line2D at 0x2729942ef28>],
‘means’: [],
‘medians’: [<matplotlib.lines.Line2D at 0x272993fdd30>,
<matplotlib.lines.Line2D at 0x272994156a0>,
<matplotlib.lines.Line2D at 0x27299428fd0>],
‘whiskers’: [<matplotlib.lines.Line2D at 0x272993f2a90>,
<matplotlib.lines.Line2D at 0x272993f8ba8>,
<matplotlib.lines.Line2D at 0x2729940acc0>,
<matplotlib.lines.Line2D at 0x2729940add8>,
<matplotlib.lines.Line2D at 0x2729941ae80>,
<matplotlib.lines.Line2D at 0x27299421e48>]}

Group 2基本上不需要任何时间就能解决,这表明问题是非常简单和直接的。企业需要去看看这些问题然后给客户提供一个自服务的路径(产品帮助、在线帮助)而不是浪费客户代表的时间。

In [7]:

plt.cla()
plt.boxplot([[raw_data[“REOCCUR_RATE”][raw_data.GROUP==0]],
             [raw_data[“REOCCUR_RATE”][raw_data.GROUP==1]] ,
               [raw_data[“REOCCUR_RATE”][raw_data.GROUP==2]] ],
           labels=(‘GROUP 1′,’GROUP 2′,’GROUP 3’))

Out[7]:

{‘boxes’: [<matplotlib.lines.Line2D at 0x27299485c88>,
<matplotlib.lines.Line2D at 0x27299499e80>,
<matplotlib.lines.Line2D at 0x272994b07f0>],
‘caps’: [<matplotlib.lines.Line2D at 0x2729948eda0>,
<matplotlib.lines.Line2D at 0x27299494cf8>,
<matplotlib.lines.Line2D at 0x272994a4e10>,
<matplotlib.lines.Line2D at 0x272994a4f28>,
<matplotlib.lines.Line2D at 0x272994bc780>,
<matplotlib.lines.Line2D at 0x272994bcf98>],
‘fliers’: [<matplotlib.lines.Line2D at 0x27299499d68>,
<matplotlib.lines.Line2D at 0x272994a8f98>,
<matplotlib.lines.Line2D at 0x272994c2ef0>],
‘means’: [],
‘medians’: [<matplotlib.lines.Line2D at 0x27299494e10>,
<matplotlib.lines.Line2D at 0x272994a8780>,
<matplotlib.lines.Line2D at 0x272994c20f0>],
‘whiskers’: [<matplotlib.lines.Line2D at 0x27299485b70>,
<matplotlib.lines.Line2D at 0x2729948ec88>,
<matplotlib.lines.Line2D at 0x2729949eda0>,
<matplotlib.lines.Line2D at 0x2729949eeb8>,
<matplotlib.lines.Line2D at 0x272994b0f60>,
<matplotlib.lines.Line2D at 0x272994b6f28>]}

Group 2有非常高的复发率,这些问题需要进行分析去看看产品质量如何改进以防止这些问题再次发生。

In [8]:

plt.cla()
plt.boxplot([[raw_data[“REPLACEMENT_RATE”][raw_data.GROUP==0]],
             [raw_data[“REPLACEMENT_RATE”][raw_data.GROUP==1]] ,
               [raw_data[“REPLACEMENT_RATE”][raw_data.GROUP==2]] ],
           labels=(‘GROUP 1′,’GROUP 2′,’GROUP 3’))

Out[8]:

{‘boxes’: [<matplotlib.lines.Line2D at 0x27299526e10>,
<matplotlib.lines.Line2D at 0x27299538f98>,
<matplotlib.lines.Line2D at 0x2729954e978>],
‘caps’: [<matplotlib.lines.Line2D at 0x2729952ef28>,
<matplotlib.lines.Line2D at 0x27299532e80>,
<matplotlib.lines.Line2D at 0x27299544f98>,
<matplotlib.lines.Line2D at 0x272995497f0>,
<matplotlib.lines.Line2D at 0x2729955a908>,
<matplotlib.lines.Line2D at 0x2729955aa20>],
‘fliers’: [<matplotlib.lines.Line2D at 0x27299538ef0>,
<matplotlib.lines.Line2D at 0x2729954e860>,
<matplotlib.lines.Line2D at 0x2729955fa90>],
‘means’: [],
‘medians’: [<matplotlib.lines.Line2D at 0x27299532f98>,
<matplotlib.lines.Line2D at 0x27299549908>,
<matplotlib.lines.Line2D at 0x2729955f278>],
‘whiskers’: [<matplotlib.lines.Line2D at 0x27299526cf8>,
<matplotlib.lines.Line2D at 0x2729952ee10>,
<matplotlib.lines.Line2D at 0x2729953ff28>,
<matplotlib.lines.Line2D at 0x27299544780>,
<matplotlib.lines.Line2D at 0x27299555898>,
<matplotlib.lines.Line2D at 0x27299555fd0>]}

Group 1具有非常广的替换率,它不能给出任何实际可以操作的模式。

Group 2没有任何的替换,这是非常棒的。现在看到的组级别的一些倾向,我们可以基于这些分析做一些组级别的决策。例如Group 2呼叫了很多次,但是解决基本不需要花时间,因此我们可以对Group 2利用自服务。Group 1则不同,呼叫的次数少,但是花了很多的时间去解决,并且有很高的替换率以及复发率,我们可能需要去看看产品是否有问题或者已修复问题是否还在发生。

这就是我们如何利用聚类和预测分析去将我们的问题进行分组,然后基于组进行分析。

—  本系列文章完结  —