
1.1 数据类别
程序员把数据分成3个主要类别——非结构化数据、结构化数据和半结构化数据。在数据处理流程中,初始数据通常是非结构化的;基于初始数据,可以得到结构化数据或者半结构化数据,以做进一步处理。但是,一些数据处理流程从一开始便使用结构化数据。例如,处理地理位置信息的应用程序可能直接从GPS传感器接收结构化数据。接下来几节将探讨主要数据类别和时间序列数据。时间序列数据是一种特别的结构化或者半结构数据。
1.1.1 非结构化数据
非结构化数据是指没有预先定义的结构或者模式的数据。这是广泛存在的数据形式,常见的示例包括图片、视频、音频和自然语言文本。考虑某制药公司的如下财务报表。
GoodComp shares soared as much as 8.2% on 2021-01-07 after the company announced positive early-stage trial results for its vaccine.
该文本应被视为非结构化数据,因为其中的信息没有组织成预先定义的模式,而随机地散乱在文本中,用户可以把该文本改写成其他形式,但是仍然可以传递同样的信息。例如:
Following the January 7, 2021, release of positive results from its vaccine trial, which is still in its early stages, shares in GoodComp rose by 8.2%.
虽然缺乏结构,但是非结构化数据可能包含重要的信息。通过适当的变换和分析,用户可以从中提取出结构化或者半结构化数据。例如,图像识别工具首先将图像的像素集合转化为预先定义格式的数据,然后分析数据并实现图像识别。同样地,1.1.2节将展示从财务报表提取出结构化数据的几种方式。
1.1.2 结构化数据
结构化数据有预定义的格式,用于明确数据的组织形式。此类数据通常存储在数据库中,如关系数据库、.csv 文件。数据库中的每一行数据称为记录,记录的信息由字段构成,字段顺序必须与预期结构相匹配。在一个数据库中,相同结构的记录保存在一起,形成一个表。一个数据库可能包含多个表,每个表都有一组字段。
结构化数据有两种基本类型——数值数据和分类数据。分类数据是指可以根据相似特征进行分类的数据。例如,汽车可以按品牌和型号进行分类。另外,数值数据以数字形式表达信息,允许对其进行数学运算。
注意,分类数据(如邮政编码或者电话号码)有时候也使用数字表示。虽然它们看上去像数字,但是对其进行数学运算(例如,计算邮政编码的中间值或者电话号码的平均值)是没有意义的。
我们如何把1.1.1 节的文本示例转化成结构化数据呢?我们可能对文本中的某些具体信息(如公司名称、日期和股票价格)感兴趣。我们希望使用以下格式在字段中显示这些信息,以便插入数据库。
Company: ABC Date: yyyy-mm-dd Stock: nnnnn
我们可以使用NLP技术从文本中为这些字段提取出相应的信息技术,NLP是一个训练机器理解人类语言的学科。例如,我们通过识别分类数据的变量寻找公司名称,该变量只能是许多预设值(如Google、Apple或GoodComp)中的一个。同样,我们可以通过将日期的排序与一组给定的排序格式进行匹配(如yyyy-mm-dd)识别日期。在这里的示例中,识别、提取并把如下数据表示为上述格式。
Company: GoodComp Date: 2021-01-07 Stock: +8.2%
为了把这条记录存储在数据库中,最好将其字段放在一行。因此,我们可以将记录重新组织为矩形形式的数据对象或二维矩阵。
Company | Date | Stock --------------------------- GoodComp |2021-01-07 | +8.2%
一般来说,从非结构化数据中提取什么信息取决于你的需求。该示例文本不仅包含GoodComp某一天的股价变动情况,还指出了股价变动的原因,即“the company announced positive early-stage trial results for its vaccine”。从这个角度来看,使用如下字段创建一条记录。
Company: GoodComp Date: 2021-01-07 Product: vaccine Stage: early-stage trial
请将其与第1条记录进行比较。在第1条记录中,我们提取了如下信息。
Company: GoodComp Date: 2021-01-07 Stock: +8.2%
注意,这两条记录包含不同的字段,有不同的结构。因此,它们必须存储在两个不同的表中。
1.1.3 半结构化数据
当信息本身的格式无法满足严格的格式化要求时,我们可能需要使用半结构化数据结构。这样的结构可以让我们在同一个容器(数据库表或者文件)中保存不同结构的记录。与非结构化数据一样,半结构化数据没有完全遵从预定义的模式。然而,与非结构化数据不同,半结构化数据的样本通常以自我描述的标记或者其他标志的形式表现出一定程度的结构。
常见的半结构化数据的格式包括XML和JSON。财务报表可以用如下JSON格式表示。
{ "Company": "GoodComp", "Date": "2021-01-07", "Stock": 8.2, "Details": "the company announced positive early-stage trial results for its vaccine." }
在这里,可以看到我们之前从财务报表提取出的关键信息。每一条信息都有一个描述性标记,如"Company"或"Date"。由于有这些标记,因此信息的结构与1.1.2节中数据的结构相似。但是,现在有第4个标记——"Details",它表示的是原始财务报表的一个片段,这是非结构化的。这个示例展示了半结构化数据格式如何在单条记录中同时包含结构化数据和非结构化数据。
另外,你还可以把多条结构不同的记录放在同一个容器中。这里,在同一个JSON文档中存储来自财务报表的两条不同记录。
[ { "Company": "GoodComp", "Date": "2021-01-07", "Stock": 8.2 }, { "Company": "GoodComp", "Date": "2021-01-07", "Product": "vaccine", "Stage": "early-stage trial" } ]
作为一个结构严格的数据存储库,关系数据库无法在同一表格中容纳不同结构的记录。
1.1.4 时间序列数据
时间序列数据是按时间顺序列出的一组数据点。因为金融数据通常由多个时间点的观测数据组成,所以很多金融数据存储为时间序列数据。时间序列数据可以是结构化的,也可以是半结构化的。想象一下,你每隔1min从出租车的GPS跟踪设备接收位置数据,数据可能表示为如下形式。
[ { "cab": "cab_238", "coord": (43.602508,39.715685), "tm": "14:47", "state": "available" }, { "cab": "cab_238", "coord": (43.613744,39.705718), "tm": "14:48", "state": "available" } ... ]
每分钟都有一条新的数据记录,包括编号为cab_238的出租车最新的位置坐标(纬度/经度)。每条记录都有相同的字段,在每条记录中,每个字段都具有一致的结构,允许你将该时间序列数据作为常规结构化数据存储在关系数据库表中。
现在考虑更加实际的情况,假设在1min内可能接收到多组坐标。新的数据结构可以表示为如下形式。
[ { "cab": "cab_238", "coord": [(43.602508,39.715685),(43.602402,39.709672)], "tm": "14:47", "state": "available" }, { "cab": "cab_238", "coord": (43.613744,39.705718), "tm": "14:48", "state": "available" } ]
在该示例中,第1个coord字段包含两组坐标,因此与第2个coord字段不一致。该数据是半结构化的。