虹膜数据转换的更易理解的方法

时间:2018-03-23 03:22:05

标签: python numpy scikit-learn

所以,我正在读一本关于机器学习的书。但是当我遇到这个时,我感到很困惑:

  

虹膜数据集将setosa标记为零,我们必须更改所有目标   值为0到1,其他值全部为0.我们也将使用   两个特征,花瓣长度和花瓣宽度。这两个特点是   每个x值中的第三和第四个条目。

iris = datasets.load_iris()
binary_target = np.array([1. if x==0 else 0. for x in iris.target])
iris_2d = np.array([[x[2], x[3]] for x in iris.data])

迭代的实现方式对我来说非常模糊。我从未见过这样的实现。这是我不知道的常用方式吗?或者有更好,更方便的方法来实现同样的事情 感谢

3 个答案:

答案 0 :(得分:3)

第一个列表推导创建一个布尔数组,其中True个项对应于零iris.target。使用原生NumPy工具可以实现同样的目的:

binary_target = iris.target.astype(bool).astype(int)

根本不需要第二个列表理解,因为iris.data已经是NumPy数组。所以,

iris_2d = np.array([[x[2], x[3]] for x in iris.data])

必须是:

iris_2d = iris.data[:,[2,3]]

我很惊讶一本关于机器学习的书提供了如此愚蠢的建议。

答案 1 :(得分:2)

  

让我们确定代码正在做什么 - 它正在转换a   将多类分类问题转化为二元分类(一对二休息) -   重点显然是在Setosa上。

     

那就是说,这是一种非常糟糕的做法,我真的   在一本关于机器学习的书中看到它很惊讶。

请注意,

print(iris.target)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

print(iris.data)
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],
       ...

将此转换为二进制问题的一种简单方法是使用循环:

binary_target = []
for t in iris.target:
    if t == 0:
        binary_target.append(1.)
    else:
        binary_target.append(0.)

将其减少为单个班轮,列表理解,然后得到:

binary_target = [1. if t == 0 else 0. for t in iris.target]

同样,这是一种糟糕的做法。

我宁愿用np.where执行此操作,将其保留在numpy space中 -

binary_target = np.where(iris.target == 0, 1, 0)

你可能看不到很大的差异(好吧,列表推导在C空间中运行并且速度很快),但是numpy是完全矢量化的。同样,如果您正在实施机器学习分类器,这可能不会成为您的代码的瓶颈,因此我不会非常担心它。

类似于第二个,就像@DyZ提到的那样,完全没必要。只是做 -

iris_2d = iris.data[:, 2:4]

使用ndarray.__getitem__进行简单切片就足够了,您甚至不需要将结果转换为数组(切片已经是数组)。

总之,

iris = datasets.load_iris()
binary_target = np.where(iris.target == 0, 1, 0)
iris_2d = iris.data[:, 2:4]

答案 2 :(得分:1)

[1. if x==0 else 0. for x in iris.target]

这是List Comprehension。它创建一个列表。它也可以这样做:

[float(x==0) for x in iris.target]