阅读更多
本篇文章意在对github仓库里不同编程语言中的高频词进行可视化展现。

数据源自2016年年中至年末期间,约300万套开源GitHub库。其结果以文本词云的形式展示如下:


这里保存了来自各套代码库中不同编程语言的对应常用词。GitHub的语言识别功能将这套库的大部分内容视为C++。这样的结果不无道理,毕竟其中相当一部分语言的诞生是受到C/C++的启发:

许可文本一般位于每种编程语言的注释当中。在全部语言内,Java代码以显著优势胜出,其在全部966个来自许可文本的词中占据127个:

Java的优势太过明显,因此对许可文本进行过滤。

Lua是惟一一款在前1000条常用词中包含一个脏话的编程语言——感兴趣的朋友可以来找找看。
在Go语言中,err的使用频率与return一样。

下面,将这些数据是如何产生的。
如何归纳?
利用BigQuery从github_repos数据集中提取单个词汇。每个词汇在提取时,都会伴随其出现时所在的前十行代码。

在保存各个词之前,使用以下几项限制条件:
  • 此词汇出现的行应不超过120个字符。这能帮助我们过滤掉那些并非人为编写的代码,例如经过精简的JavaScript代码。
  • 忽略掉了标点符号(, ; : .)、运算符(+ - * ...)与数字。因此如果该代内容为a+b+42,那么过滤后的内容仅为:a与b。
  • 忽略掉了那些包含“许可标记”的行——即那些出现在许可文本内的词汇(例如license、noninfringement等)。许可文本在代码中非常常见,虽然初看起来确实非常有趣,但通过归纳结果可以发现其内容数量太多,因此决定将其过滤掉。
  • 对各词的大小写状态进行了区分:This与this被视为两个独立的词。
数据是如何进行收集的?
在这部分内容中,我们将深入了解词汇提取方式。如果大家不感兴趣,也可直接跳转至词云算法部分。

来自GitHub公共数据集内的数据由BigQuery负责索引:github_repos

BigQuery以明文形式在一套表中存储各索引文件的具体内容,相当于key-value 的形式:

要建立这样一套词汇云,需要使用权重以进行词汇扩展。而要获取权重值,可以将各文本拆分为独立词汇(分词)

遗憾的是,这种简单的方法得出的结果并不理想——因为人们无法理解各个词出现的具体上下文。

目标是希望能够避免这种问题,并保证人们能够查看各个词及其出现的实际语境:

为了实现这一目标,创建了一套临时表,而非直接计算各行中词汇的出现次数:

这不仅让我得以将每个词汇与其“上下文”配合起来,同时也将整体数据量由数TB缩减至约12 GB。

为了从这份表中获得出现频率最高的词汇,我们可以采用之前提到的方法,即将内容拆分成具体词汇,而后利用表对每个词进行分组。如果我们将原始行保留在中间表内,亦可获取各词汇的对应上下文:

通过这种中间表示方式,我们可以使用SQL窗口函数对各词汇进行分组,并获得各个词的前十行(更多细节信息,请参阅:为每个分类选定前十条记录,英文原文)。

现在大家可以在此查看提取到的代码:extract_words.sql。

备注一:作者的SQL水平不高,所以如果大家其中的错误或者更理想的数据获取方式,请在评论中指出。另外,虽然目前的脚本能够正常起效,但其中某些结果可能略有偏差。

备注二:BigQuery的表现非常出色。其强大、灵活且速度极快。在这里,要向能够玩转它的朋友表达十二分的敬意。

如何进行词汇云渲染?
词汇云的核心部分,使用的其实是一条非常简单的算法:
    for each word `w`: 
      repeat: 
        place word `w` at random point (x, y) 
      until `w` does not intersect any other word 

为了避免发生内部无限循环,可以尝试限定次数数量并/或去掉那些字体大小不符合要求的词汇。

从抽象的角度来讲,可以用矩形来表达这个问题:对于每个矩形,尝试将其放在画布上,直到其任何像素皆不与其它图形相交。

很明显,当画布被大量占用时,为新的矩形找到放置点将变得非常困难甚至完全不可能。

我们可以通过多种方法对已占用空间进行索引,从而加速此项算法:
  • 使用区域求和表以快速通过O(1)次计算判断新矩形是否与其下矩形相交。这种方法的弊端在于,每一次画布进行更新时,整套表也需要进行一次更新,这会导致O(N2)性能;
  • 使用R-Tree来维护排序可以快速判断某一新的候选矩形是否与其下任何矩形相交。利用这种方法,像素相交查找速度要比区域求和表的效果更慢,但索引的维护速度则更快。
作者认为这两种方法都存在一种重要弊端,即很可能在找到适合新矩形的空间之前浪费大量尝试次数,这对于性能保障非常不利。

作者希望尝试一些不同的实现方式。建立一套索引,利用其快速选择一个足够大的矩形来匹配我新加入的矩形。这意味着为空余空间构建索引,而非对占用空间构建索引。

这里,选择了四叉树作为索引方案。其中每一个非旁枝节点都包含有可用于其下子枝的空余像素信息。从基础层面来讲,这就能够快速回答我们的问题:“是否还有足够的空间来容纳M个像素?”如果四叉树中的可用像素空间低于M,则不再需要进一步查询其子分枝。

至此,完成了具体算法的选择。

下面我们闲言少叙,一同来看其实际表现以及由此得到的具体结论。
首先来看JavaScript logo的四叉树结构:

空白矩形代表的是具备可用空间的四边形。如果候选矩形小于其中任意空白四边形,则代表可以将其立即放置在对应四边形之内。
通过简单的四叉树索引能够提供合理的结果,也很容易实现某些视觉层面的效果。大家可以看到各象限的边界——即无法将文本放置如所在四边形的位置:

作者并没有发布自己使用的最终四叉树词汇云代码,因为作者觉得在其它场景下并没有复用价值。

网站是如何构建完成的?
(1)渲染文本
总体而言,对于词汇云的生成速度是比较令人满意的。不过对于common-words即常用词网站而言,这样的速度还是太过缓慢。

作者使用SVG来渲染屏幕上的每个词汇。单独渲染这么多文本元素可能导致UI线程发生数秒钟的停顿,而且根本没有充足的CPU资源来完成文本布局计算。但好消息是,作者找到了另一种解决办法。

相较于每次打开页面时一次又一次计算词汇布局,我决定只对布局进行一次计算,而后将结果保存在一个JSON文件当中。这能帮助作者专注于进行UI线程优化。

为了避免UI发生长时间卡顿,需要以异步方式进行词汇添加。在每个事件循环周期内,会添加N个词汇,同时允许浏览器处理用户的命令与更新。在第二轮循环周期内添加更多词汇,并以此类推。为了实现这一目标,作者编写了anvaka/rafor,这是一款面向循环迭代器的异步方案,能够跨越多个事件循环周期并充分利用CPU负载。

(2)平移与缩放
此网站支持类似于谷歌地图的SVG场景导航机制, 同时适用于移动设备及台式电脑。这些特性都可通过panzoom库加以实现。

(3)应用结构
在这里,作者使用vue.js作为渲染框架选项。这主要是因为其非常简单且速度惊人。单一文件组件及热重载机制可以获得理想的开发速度。

应用的整体状态被存储在单一对象当中,而各语言的对应文件则会在用户从下拉菜单中选定对应选项时进行加载。

作为消息分派器,作者使用的是ngraph.events,这是一套以速度为主要诉求的小型消息传递库。

作者还使用anvaka/query-state来将当前选中的语言存储在查询字符串当中。

工具汇总

为什么采取词汇云的形式?

事实上,出于以下几个理由,很多朋友并不太喜欢词汇云这种表现形式:将词汇从上下文中剥离出来,因此good并不总是代表好的意思(例如not good中的not部分并不会被显示出来)。对词汇进行缩放以适应图形显示,因此各词汇的显示大小无法保证。其会直接舍弃部分常用词汇(例如a、the、not等)。

不过作者还是非常喜欢利用各类算法将词汇填充进图形内以生成词汇云。很多时候,艺术感才是最重要的——不是吗?

  • 大小: 291.4 KB
  • 大小: 13 KB
  • 大小: 478 KB
  • 大小: 38.4 KB
  • 大小: 15.1 KB
  • 大小: 463.3 KB
  • 大小: 22.6 KB
  • 大小: 33.9 KB
  • 大小: 129 KB
  • 大小: 259.2 KB
来自: 51cto
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 超详细的系统概要设计说明书 高清版

    超详细的概要说明书系统概要设计说明书超详细的概要说明书系统概要设计说明书

  • 【机房】概要设计说明书

    引言 1.1编写目的 1.2背景 1.3定义 1.4参考资料 总体设计 2.1需求规定 2.2运行环境 2.3基本设计概念和处理流程 2.4结构 2.5功能器求与程序的关系 2.6人工处理过程 2.7尚未解决的问题 接口设计 3.1用户接口 3.2外部接口 3.3内部接口 运行设计 4.1运行模块组合 4.2运行控制 4.3运行时间 系统数据结构设计 5.1逻......

  • 概要设计

    一、概要设计的目的   将软件系统需求转换为未来系统的设计;  逐步开发强壮的系统构架;  使设计适合于实施环境,为提高性能而进行设计;  结构应该被分解为模块和库。   二、概要设计的任务   制定规范: 代码体系、接口规约、命名规则。这是项目小组今后共同作战的基础,有了开发规范和程序模块之间和项目成员彼此之间的接口规则、方式方法,大家就有了共同的工作语言、共同的工作平台,使整个软件开...

  • 信管

    填空 1. 信息系统的开发方式 (原型法)、(结构化开发方法)、(面型对象方法)、(信息工程方法)、(企业系统规划方法) 2. 三行两列一个表格 结构化开发方法 开发周期短、需求不明确、用户不熟悉计算机系统、分析员不熟悉用户专业 原型法 系统需求可以明确提出且需求稳定的 面向对象的开发方法 对于环境复杂多变、功能和数据旁庞大、类型复杂不稳定却容易出现变化的情况 3.名词英译汉 面向对象的程序设计 OOP 面向对象的分析 OOA 面向对象的设计 OOD 原型法

  • (软件工程)——概要设计说明书

    步骤:概要设计和详细设计 软件设计的目标和任务 用信息域表示的软件需求,以及功能和性能需求,进行:数据设计、系统结构设计、过程设计 信息阶段的信息流 软件设计任务: 从工程管理的角度来看,软件设计分为两部: 概要设计(总体设计):软件的需求转化为数据结构或者软件结构 详细设计(过程设计):通过对结构进行细化,得到软件的详细结构或者算法。 如何判断设计的好坏? 1、设计必须实现分析模型描述的显示需...

  • 【软件文档】概要设计说明书(Word2024完整版)

    6.1运行模块的组合。7.3 系统维护设计。

  • 概要设计说明书(GB8567——88)基于协同的在线表格forture-sheet

    给出本系统内所使用的每个数据结构中的每个数据项的存储要求,访问方法、存取单位、存取的物理关系(索引、设备、存储区域)、设计考虑和保密条件。TypeScript:TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。用户登录时需要进行身份认证,用户名,密码和数据库中的一直且根据不同而登录不同的环境。本系统的主要的输入输出项目、处理的功能性能要求,详细的说明可参见附录C。说明将向用户提供的命令和它们的语法结构,以及软件的回答信息。

  • 【软工】概要设计说明书

    概要设计说明书 1.引言 1.1编写目的 设计软件结构的具体任务是将一个复杂系统按功能进行模块划分、建立模块的层次结构及调用关系、确定模块间的接口及人机界面等。数据结构设计包括数据特征的描述、确定数据的结构特性、以及数据库的设计。 此概要设计说明书是为了说明整个系统的体系架构,以及需求用例的各个功能点在架构中的体现,为系统的详细设计人员进行详细设计师的输入参考文档。 1.2背景 说明:...

  • 数据结构之道:如何选择适合你的数据存储

    不同的数据结构适用于不同的应用场景,根据应用程序的需求来选择合适的数据结构可以提高程序的性能和可维护性。在选择数据结构时,请考虑数据的特性、操作的复杂度、内存占用和并发性等因素,并根据具体情况做出明智的选择。数据结构的选择不仅会影响到你的应用程序的性能,还会决定你在处理数据时的便利性。本文将探讨数据结构的基本原理,介绍几种常见的数据结构,以及如何根据你的需求选择适合的数据存储方式。在编写代码时,不仅要选择适当的数据结构,还要编写高质量的代码,以确保代码的可读性和可维护性。首先,需要考虑你的数据的特性。

  • 概要设计说明书的书写

    1引言....................................................................................................................................... 21.1编写目的.................................................

  • 网狐棋牌游戏平台服务器架构设计分析

    网狐棋牌游戏平台服务器架构设计分析 基本设计概念和处理流程 调用模型 模仿COM组件接口模式,利用面向对象思想多态性polymorphism,调用方保存着被调用方的基础接口指针(interface or sink钩子)(Pure Virtual Function),调用方直接调用接口指针内声明的纯虚方法,而此纯虚函数的具体逻辑由该接口的派生类实现。 示意图: 基于事件驱动...

  • 概要设计说明书 模板

    用一览表及框图的形式说明本系统的系统元素(各层模块、子程序、公用程序等)的划分,扼要说明每个系统元素的标识符和功能,分层次地给出各元素之间的控制与被控制关系.给出本系统内所使用的每个数据结构的名称、标识符以及它们之中每个数据项、记录、文卷和系的标识、定义、长度及它们之间的层次的或表格的相互关系。给出本系统内所使用的每个数据结构中的每个数据项的存储要求,访问方法、存取单位、存取的物理关系(索引、设备、存储区域)、设计考虑和保密条件。说明本系统之内的各个系统元素之间的接口的安排。

  • 软件工程概要设计

    请根据需求分析,编写软件体系结构设计报告、界面设计报告、数据库设计报告及模块设计报告。 总体设计说明书的内容包括引言(编写目的、背景、定义、参考资料)、总体设计(需求规定、运行环境、基本设计概念和处理流程、结构、功能需求与程序的关系、人工处理过程、本阶段尚未解决的问题等)、接口设计(用户接口、外部接口、内部接口)、运行设计(运行模块组合、运行控制、运行时间)、系统数据结构设计(逻辑结构设计、物理结构设计、数据结构与程序的关系)、系统出错处理设计(出错信息、补救措施、系统维护设计)。 可能需要用到的图形包括E

  • 概要设计、详细设计:概念、方法、实践步骤

    完整软件开发流程: 需求分析、概要设计、详细设计 一 1.概念、方法、实践步骤 设计是指根据需求开发的结果,对产品的技术实现由粗到细进行设计的过程。根据设计粒度和目的的不同可以将设计分为概要设计、详细设计等阶段以便于管理和确保质量。设计内容也要根据软件系统的实际情况进行定义,比如对于交互性要求高的系统可以有视觉设计等等。 一般来说可...

  • 图解!24张图彻底弄懂九大常见数据结构!

    ​数据结构想必大家都不会陌生,对于一个成熟的程序员而言,熟悉和掌握数据结构和算法也是基本功之一。数据结构本身其实不过是数据按照特点关系进行存储或者组织的集合,特殊的结构在不同的应用场景中往往会带来不一样的处理效率。 常用的数据结构可根据数据访问的特点分为线性结构和非线性结构。线性结构包括常见的链表、栈、队列等,非线性结构包括树、图等。数据结构种类繁多,本文将通过图解的方式对常用的数据结构进行理论上的介绍和讲解,以方便大家掌握常用数据结构的基本知识。 本文提纲: 1数组 数组可以说是最基本最...

  • 【软件工程】概要设计说明书

    概要设计说明书 1引言 1.1编写目的 这篇文章的编写目的主要是为了开发此系统为系统做一个总体的结构设计,经评审后进一步细化,分别对每一模块进行详细细化的解决方案、接口和数据库等方面的设计,明确描述所有输入输出参数、类型逻辑算法以及调用关系。作为开发人员和测试人员进一步变成和编写测试用例依据。 1.2背景 a.待开发软件系统的名称:机房收费系统 b.列出此项目的任务提出者:米新江教授 ...

  • 如何写软件概要设计?

    概要设计 概要设计是一个将用户目标与需求转换成具体界面设计方案的重要阶段,在这里我们需要由前一阶段的需求分析得到软件(包括移动应用和网站等)的设计和数据结构。 其通常是将复杂的系统按照不同的功能进行模块化,理清模块之间的层次关系以及调用关系、确定模块间的接口以及用户界面。而数据结构部分则是要根据数据的特征来确定数据的结构并设计出相应...

  • 数据库设计:物理结构设计

    数据库物理设计阶段的任务是根据具体计算机系统(DBMS和硬件等)的特点,为给定的数据库模型确定合理的存储结构和存取方法。所谓的“合理”主要有两个含义:一个是要使设计出的物理数据库占用较少的存储空间,另一个对数据库的操作具有尽可能高的速度。为了设计数据库的物理结构,设计人员必须充分了解所用DBMS的内部特征;充分了解数据系统的实际应用环境,特别是数据应用处理的频率和响应时间的要求;充分了解外存储

Global site tag (gtag.js) - Google Analytics