Python Orange入门之第一节:数据输入格式

1 篇文章 0 订阅
1 篇文章 0 订阅

数据

本节介绍如何在Orange中加载数据。我们还将展示如何探索数据,执行一些基本统计以及如何对数据进行采样。

数据输入

Orange可以以原生制表符分隔格式读取文件,也可以从任何主要标准电子表格文件类型(如CSV和Excel)加载数据。本机格式以带有要素(列)名称的标题行开头。第二个标题行提供属性类型,可以是连续,离散,时间或字符串。第三个标题行包含用于标识依赖特征(类),不相关特征(忽略)或元特征(元)的元信息。加载和保存数据(io)中提供了更详细的规范。以下是数据集中的前几行lenses.tab

age       prescription  astigmatic    tear_rate     lenses
discrete  discrete      discrete      discrete      discrete
                                                    class
young     myope         no            reduced       none
young     myope         no            normal        soft
young     myope         yes           reduced       none
young     myope         yes           normal        hard
young     hypermetrope  no            reduced       none

值是制表符限制的。该数据集具有四个属性(患者年龄,眼镜处方,散光概念,泪液产生率信息)和相关的三值因变量编码镜片处方(硬性隐形眼镜,软性隐形眼镜,无镜片) )。功能描述只能使用一个字母,因此该数据集的标题也可以是:

age       prescription  astigmatic    tear_rate     lenses
d         d             d             d             d
                                                    c

表格的其余部分给出了数据。请注意,上表中有5个实例。对于完整数据集,请检出或下载lenses.tab到目标目录。您也可以跳过此步骤,因为Orange预装了几个演示数据集,镜头就是其中之一。现在,打开一个python shell,导入Orange并加载数据:

>>> import Orange
>>> data = Orange.data.Table("lenses")
>>>

请注意,对于文件名,不需要后缀,因为Orange会检查当前目录中的任何文件是否为可读类型。调用Orange.data.Table创建了一个名为对象data包含您的数据集和有关镜头域的信息:

>>> data.domain.attributes
(DiscreteVariable('age', values=['pre-presbyopic', 'presbyopic', 'young']),
 DiscreteVariable('prescription', values=['hypermetrope', 'myope']),
 DiscreteVariable('astigmatic', values=['no', 'yes']),
 DiscreteVariable('tear_rate', values=['normal', 'reduced']))
>>> data.domain.class_var
DiscreteVariable('lenses', values=['hard', 'none', 'soft'])
>>> for d in data[:3]:
   ...:     print(d)
   ...:
[young, myope, no, reduced | none]
[young, myope, no, normal | soft]
[young, myope, yes, reduced | none]
>>>

以下脚本包含了我们目前所做的所有事情,并列出了前5个数据实例和soft处方:

import Orange
data = Orange.data.Table("lenses")
print("Attributes:", ", ".join(x.name for x in data.domain.attributes))
print("Class:", data.domain.class_var.name)
print("Data instances", len(data))

target = "soft"
print("Data instances with %s prescriptions:" % target)
atts = data.domain.attributes
for d in data:
    if d.get_class() == target:
        print(" ".join(["%14s" % str(d[a]) for a in atts]))

请注意,数据是一个包含域中数据和信息的对象。我们在上面展示了如何访问属性和类名,但是有更多的信息,包括关于要素类型,分类要素的值集等。

保存数据

数据对象可以保存到文件中:

>>> data.save("new_data.tab")
>>>

这次,我们必须提供文件扩展名来指定输出格式。原生Orange的数据格式的扩展名为“.tab”。以下代码仅使用myope perscription保存数据项:

import Orange
data = Orange.data.Table("lenses")
myope_subset = [d for d in data if d["prescription"] == "myope"]
new_data = Orange.data.Table(data.domain, myope_subset)
new_data.save("lenses-subset.tab")

我们通过传递data(data.domain)结构和数据实例子集的信息创建了一个新的数据表。

探索数据域

数据表存储有关数据实例以及数据域的信息。Domain包含属性,可选类及其类型的名称,以及值名称(如果是分类)。以下代码:

import Orange

data = Orange.data.Table("imports-85.tab")
n = len(data.domain.attributes)
n_cont = sum(1 for a in data.domain.attributes if a.is_continuous)
n_disc = sum(1 for a in data.domain.attributes if a.is_discrete)
print("%d attributes: %d continuous, %d discrete" % (n, n_cont, n_disc))

print("First three attributes:",
      ", ".join(data.domain.attributes[i].name for i in range(3)))

print("Class:", data.domain.class_var.name)

输出:

25 attributes: 14 continuous, 11 discrete
First three attributes: symboling, normalized-losses, make
Class: price

Orange的对象通常表现得像Python列表和字典,可以通过功能名称编制索引或访问:

print("First attribute:", data.domain[0].name)
name = "fuel-type"
print("Values of attribute '%s': %s" %
      (name, ", ".join(data.domain[name].values)))

上面代码的输出是:

First attribute: symboling
Values of attribute 'fuel-type': diesel, gas

数据实例

数据表存储数据实例(或示例)。这些可以像任何Python列表一样被索引或遍历。数据实例可以视为向量,通过元素索引或通过功能名称访问。

import Orange

data = Orange.data.Table("iris")
print("First three data instances:")
for d in data[:3]:
    print(d)

print("25-th data instance:")
print(data[24])

name = "sepal width"
print("Value of '%s' for the first instance:" % name, data[0][name])
print("The 3rd value of the 25th data instance:", data[24][2])

上面的脚本显示以下输出:

First three data instances:
[5.100, 3.500, 1.400, 0.200 | Iris-setosa]
[4.900, 3.000, 1.400, 0.200 | Iris-setosa]
[4.700, 3.200, 1.300, 0.200 | Iris-setosa]
25-th data instance:
[4.800, 3.400, 1.900, 0.200 | Iris-setosa]
Value of 'sepal width' for the first instance: 3.500
The 3rd value of the 25th data instance: 1.900

我们上面使用的Iris数据集有四个连续属性。这是一个计算其平均值的脚本:

average = lambda x: sum(x)/len(x)

data = Orange.data.Table("iris")
print("%-15s %s" % ("Feature", "Mean"))
for x in data.domain.attributes:
    print("%-15s %.2f" % (x.name, average([d[x] for d in data])))

上面的脚本还说明了使用存储功能的对象索引数据实例; in d[x]variable x是一个Orange对象。这是输出:

Feature         Mean
sepal length    5.84
sepal width     3.05
petal length    3.76
petal width     1.20

一个稍微复杂但也更有趣的代码,用于计算每个类的平均值:

average = lambda xs: sum(xs)/float(len(xs))

data = Orange.data.Table("iris")
targets = data.domain.class_var.values
print("%-15s %s" % ("Feature", " ".join("%15s" % c for c in targets)))
for a in data.domain.attributes:
    dist = ["%15.2f" % average([d[a] for d in data if d.get_class() == c])
            for c in targets]
    print("%-15s" % a.name, " ".join(dist))

在这四个特征中,花瓣宽度和长度看起来对于虹膜的类型非常有区别:

Feature             Iris-setosa Iris-versicolor  Iris-virginica
sepal length               5.01            5.94            6.59
sepal width                3.42            2.77            2.97
petal length               1.46            4.26            5.55
petal width                0.24            1.33            2.03

最后,这是一个快速代码,用于计算另一个数据集的类分布:

import Orange
from collections import Counter

data = Orange.data.Table("lenses")
print(Counter(str(d.get_class()) for d in data))

橙色数据集和NumPy的

橙色数据集实际上是包装的NumPy数组。执行包装以保留有关功能名称和值的信息,NumPy数组用于提高与橙色所依赖的不同机器学习工具箱(如scikit-learn)的兼容性。让我们为虹膜数据集的前三个数据实例显示这些数组的值:

>>> data = Orange.data.Table("iris")
>>> data.X[:3]
array([[ 5.1,  3.5,  1.4,  0.2],
       [ 4.9,  3. ,  1.4,  0.2],
       [ 4.7,  3.2,  1.3,  0.2]])
>>> data.Y[:3]
array([ 0.,  0.,  0.])

请注意,我们使用data.X和分别访问属性和类的数组data.Y。然后可以通过以下方式有效地计算属性的平均值:

>>> import np as numpy
>>> np.mean(data.X, axis=0)
array([ 5.84333333,  3.054     ,  3.75866667,  1.19866667])

我们还可以从numpy数组构造一个(无类)数据集:

>>> X = np.array([[1,2], [4,5]])
>>> data = Orange.data.Table(X)
>>> data.domain
[Feature 1, Feature 2]

如果我们想为属性提供有意义的名称,我们需要构建一个合适的数据域:

>>> domain = Orange.data.Domain([Orange.data.ContinuousVariable("lenght"),
                                 Orange.data.ContinuousVariable("width")])
>>> data = Orange.data.Table(domain, X)
>>> data.domain
[lenght, width]

这是另一个例子,这次是构建一个包含数字类和不同类型属性的数据集:

size = Orange.data.DiscreteVariable("size", ["small", "big"])
height = Orange.data.ContinuousVariable("height")
shape = Orange.data.DiscreteVariable("shape", ["circle", "square", "oval"])
speed = Orange.data.ContinuousVariable("speed")

domain = Orange.data.Domain([size, height, shape], speed)

X = np.array([[1, 3.4, 0], [0, 2.7, 2], [1, 1.4, 1]])
Y = np.array([42.0, 52.2, 13.4])

data = Orange.data.Table(domain, X, Y)
print(data)

运行此脚本会产生:

[[big, 3.400, circle | 42.000],
 [small, 2.700, oval | 52.200],
 [big, 1.400, square | 13.400]

元属性

通常,我们希望在数据中包含不会用于任何计算(距离估计,建模)的描述性字段,但将用于识别或附加信息。这些被称为元属性,并meta在第三个标题行中标记:

name	hair	eggs	milk	backbone	legs	type
string	d	d	d	d	d	d
meta						class
aardvark	1	0	1	1	4	mammal
antelope	1	0	1	1	4	mammal
bass	0	1	0	1	0	fish
bear	1	0	1	1	4	mammal

元属性和所有其他(非元)属性的值在Orange中类似地处理,但存储在单独的numpy数组中:

>>> data = Orange.data.Table("zoo")
>>> data[0]["name"]
>>> data[0]["type"]
>>> for d in data:
    ...:     print("{}/{}: {}".format(d["name"], d["type"], d["legs"]))
    ...:
aardvark/mammal: 4
antelope/mammal: 4
bass/fish: 0
bear/mammal: 4
>>> data.X
array([[ 1.,  0.,  1.,  1.,  2.],
       [ 1.,  0.,  1.,  1.,  2.],
       [ 0.,  1.,  0.,  1.,  0.],
       [ 1.,  0.,  1.,  1.,  2.]]))
>>> data.metas
array([['aardvark'],
       ['antelope'],
       ['bass'],
       ['bear']], dtype=object))

Orange.data.Table在为属性和类值提供数组之后,可以传递元属性:

from Orange.data import Table, Domain
from Orange.data import ContinuousVariable, DiscreteVariable, StringVariable
import numpy as np

X = np.array([[2.2, 1625], [0.3, 163]])
Y = np.array([0, 1])
M = np.array([["houston", 10], ["ljubljana", -1]])

domain = Domain([ContinuousVariable("population"), ContinuousVariable("area")],
                [DiscreteVariable("snow", ("no", "yes"))],
                [StringVariable("city"), StringVariable("temperature")])
data = Table(domain, X, Y, M)
print(data)

脚本输出:

[[2.200, 1625.000 | no] {houston, 10},
 [0.300, 163.000 | yes] {ljubljana, -1}

为了构造一个无类域,我们可以传递None类值。

缺少值

考虑以下对美国参议院投票数据集的探索:

>>> import numpy as np
>>> data = Orange.data.Table("voting.tab")
>>> data[2]
[?, y, y, ?, y, ... | democrat]
>>> np.isnan(data[2][0])
True
>>> np.isnan(data[2][1])
False

特定数据实例包括第一个和第四个属性的缺失数据(用'?'表示)。在原始数据集文件中,默认情况下,缺失值用空格表示。我们现在可以检查每个属性并报告未定义此功能的数据实例的比例:

data = Orange.data.Table("voting.tab")
for x in data.domain.attributes:
    n_miss = sum(1 for d in data if np.isnan(d[x]))
    print("%4.1f%% %s" % (100.*n_miss/len(data), x.name))

此脚本输出的前三行是:

 2.8% handicapped-infants
11.0% water-project-cost-sharing
 2.5% adoption-of-the-budget-resolution

报告具有至少一个缺失值的数据实例数的单行程序是:

>>> sum(any(np.isnan(d[x]) for x in data.domain.attributes) for d in data)
203

数据选择和采样

除了数据文件的名称,Orange.data.Table可以接受数据域和数据项列表并返回新的数据集。这对任何数据子集都很有用:

data = Orange.data.Table("iris.tab")
print("Dataset instances:", len(data))
subset = Orange.data.Table(data.domain,
                           [d for d in data if d["petal length"] > 3.0])
print("Subset size:", len(subset))

代码输出:

Dataset instances: 150
Subset size: 99

并从原始数据集继承数据描述(域)。更改域需要设置新的域描述符。此功能适用于任何类型的功能选择:

data = Orange.data.Table("iris.tab")
new_domain = Orange.data.Domain(list(data.domain.attributes[:2]),
                                data.domain.class_var)
new_data = Orange.data.Table(new_domain, data)

print(data[0])
print(new_data[0])

我们还可以构建数据集的随机样本:

>>> sample = Orange.data.Table(data.domain, random.sample(data, 3))
>>> sample
[[6.000, 2.200, 4.000, 1.000 | Iris-versicolor],
 [4.800, 3.100, 1.600, 0.200 | Iris-setosa],
 [6.300, 3.400, 5.600, 2.400 | Iris-virginica]
]

或随机抽样属性:

>>> atts = random.sample(data.domain.attributes, 2)
>>> domain = Orange.data.Domain(atts, data.domain.class_var)
>>> new_data = Orange.data.Table(domain, data)
>>> new_data[0]
[5.100, 1.400 | Iris-setosa]

Orange数据挖掘库

导航

 

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值