使用matplotlib制做分类散点图与气泡图

在机器学习中,一类常见的问题即是监督学习问题,有时也称为分类问题,即经过对数据现有的特征与分类标签进行分析,创建特定的模式与函数,从而能够为的新的数据创建分类标签。在数据特征为二维时,一般能够经过绘制分类散点图观察数据的特征,从而使得分类问题变得更加直观,也可使用这种方法来选择分类性能最好的特征。分类散点图与传统散点图的最大区别是其数据点带有分类标签,一般使用颜色与符号来区分不一样的类别。一个典型的分类散点以下:python

1340694-c39d9f6ee5d4d8ce.jpg
image

图中使用了蓝色圆形标签表示本国汽车,使用红色星形标签表示外国汽车,横轴为汽车的重量,竖轴为汽车的长度,能够看出这个变量没法很好的区分本国与外国汽车。算法

Python的matplotlib库提供了散点图的绘制模块,但为了绘制分类散点图还须要进行多重设置,若是每次都进行这些设置则略显繁琐。为此,笔者编写了一个专门绘制分类散点图的函数,能够简化相关的设置工做。首先,咱们须要导入相关库:机器学习

# coding = utf-8
    import numpy as np
    import matplotlib.pyplot as plt
    import warnings
    warnings.filterwarnings("ignore")
    import seaborn as sns
    import pandas as pd
    from algo import latex
    sns.set(style="white",context='poster',color_codes=True)

其中algo是笔者自身编写的库,其中latex函数能够将普通文本转化为latex格式,使得相关图片标签更加美观,最好一行使用seaborn库描述了所绘制图形的风格与格式。接下来即是函数自己:函数

def kindScatter(x,y,group,size=100,legendloc=2):
        kind = list(set(group))
        if len(kind) > 7:
            print "there is too much groups!"
        else:
            markers = ['o', '*', '+', 'x','s', 'p','h']
            col = ['b','r','g','c','y','m','k']
            for i in range(len(kind)):
                xx = x[group==kind[i]]
                yy = y[group==kind[i]]      
                plt.scatter(xx,yy,marker=markers[i],s=size,c=col[i],
                alpha=0.8,label=latex(kind[i]))
                plt.legend(loc=legendloc,frameon=True)

函数的原理是将分类标签不一样的数据分组,并分别使用不一样的颜色与标记绘制散点图,最后获得的散点图能够经过颜色与标记明确区分不一样的类别。函数包括五个参数,前两个参数分别为X轴变量与Y轴变量,第三个参数为分类标签变量,以上三个变量都为pandas中的series格式,一般能够用DataFrame.x的形式来表示。第四个参数为数据点的大小,默认为100,能够根据数据点的稀疏来放大或缩小数据点;第五个参数为legend的位置,能够用一、二、三、4表示legend位于右上角、左上角、左下角与右下角。须要注意的是,因为可供选择的颜色与数据标签有限,函数最多支持七个类别,若是超过七个类别,则函数会报错。不过一般来讲,七个类别已经足够,再多的类别也会使得图形很是混乱,变量更加不直观。post

鸢尾花数据示例

为检验函数的功能,使用该函数对著名的iris数据集进行了绘制。iris数据集,也称鸢尾花卉数据集,是经常使用的分类实验数据集,由Fisher(1936)收集整理。数据集包含150个数据,分为3类,每类50个数据,每一个数据包含4个属性。可经过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。其中的Setosa与另外两个种类是线性可分离的,然后两个种类是非线性可分离的。性能

能够看出,使用sepal length与speal widthd两个特征能够很轻易地对setosa与其它两种花进行区别,但没法有效的区分viginica与versicolor两种花。以上现象说明了,选择不一样的数据特征,其分类性能是不一样的。学习

1340694-eb13fbe342d90bf5.jpg
image

决策边界

对于某些分类散点图,画出决策边界(decision boundary)一般有利于对分类有更进一步的认识。如在Andrew Ng的机器学习课程中,给出了个学生考试成绩与经过状况的数据集。数据共包括100个案例,3个变量,前两个变量分别为两门考试的分类,最后一项表示学生是否经过考试,经过了则为1,未经过则为0。与以上相似,咱们能够画出该数据集的分类散点图。另外,咱们想画出决策边界,以使咱们直观的认识分类算法的性能。测试

咱们使用logistic回归来决定决策边界,即两科考试分数为自变量,考试经过状况为因变量进行回归,获得如下模型:

回归结果以下:

为获得决策边界,通常令,如此能够解出:

将这一直线绘制在分类散点图上,即可以获得决策边界,以下图所示:3d

1340694-d1aca31c7b3751d0.jpg
image

气泡图

气泡图与分类散点图相似,都是在对基础散点图的基础上修改而成的。区别在于,分类散点图适用于如分类数据这样的离散变量,而气泡图则适用于连续变量。前者一般将离散变量映射到数据点的颜色与标记上,然后者将连续变量映射到数据点的大小与颜色上。这一思想来自于R语言的经典绘图包ggplot2,正是在这一绘图包里,Hadley Wickham建立了一种新型绘图语法,引入了映射、标度与变换等概念,使数据分析师可以更加简洁地作出更增强大的统计图形。借用ggplot2的思想,咱们用python语言编写了一个绘制气泡图的函数,函数以下:code

def bubble(xx,yy,size,col,data,base=100):
        x = data[xx]
        y = data[yy]
        area = data[size]
        colors = data[col]
        mincol = min(colors)
        maxcol = max(colors)
        std = (area-float(min(area)))/(max(area)-min(area))
        stdArea = base + 500*std
        stdColor = (colors-float(min(colors)))/(max(colors)-min(colors))
        fig, ax = plt.subplots()
        cax = ax.scatter(x,y,s=stdArea,c=stdColor,cmap='jet',alpha=0.8)
        cbar = fig.colorbar(cax, ticks=[0,0.5,1])
        cbar.ax.set_yticklabels([str(mincol),latex(col),str(maxcol)])
        plt.xlabel(latex(xx))
        plt.ylabel(latex(yy))

函数包含六个参数:前四个参数的数据分别映射到气泡图的X轴、Y轴、数据点的大小以及颜色,最后两个参数对应的数据应是一致的。Data参数为一个pandas的dataframe,base参数描述数据点的最小尺寸。须要注意的是,因为函数以后须要绘制相关数据标签,则前四个参数应是文本格式,如:

bubble('weight','length','price','price',data=auto,base=200)

函数为将相应数据映射到数据点的颜色与大小上,首先须要将相应数据标准化,标准化的方式是将每一个数据减去其最小值再除以最大值与最小值之差,如此数据集将被映射到0-1闭区间,在最小值时取0,最大值时取1。此外,为气泡图加上了colorbar,以明确不一样颜色对应的取值范围。为测试函数功能,使用stata自带的auto数据集。

将汽车的weight与length映射到X轴与Y轴,将汽车的价格映射到数据点的颜色与大小,则能够获得:

1340694-2ddf5b7788f68e57.jpg
image