數據
本節介紹如何在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數據挖掘庫
導航
- 數據模型(
data
) - 數據預處理(
preprocess
) - 分類(
classification
) - 迴歸(
regression
) - 聚類(
clustering
) - 距離(
distance
) - 評價(
evaluation
) - 投影(
projection
) - 雜項(
misc
)