该文章对机器学习中常见的diamond的数据及进行探索及可视化.
目录
文章目录
前言
一、diamond数据集的介绍
二、数据集探索性分析
1.各特征的相关性
(1).成对分析图(成对散点图)
(2).成对分析图带拟合线
(3).diamond数据集的热力图
2.价格的直方图(带拟合线)
3.carat克拉的直方图
编辑
4.钻石的总深度与钻石的桌面比例的直方图
5.各特征的饼图
(1)cut切割质量饼图
(2)color颜色等级饼图
(3)clarity透明度等级饼图
6.各特征的核密度图
(1)价格与切割质量的核密度图
(2)价格与颜色的核密度图
(3)价格与透明度的核密度图
7.气泡散点图
(1)按照切割质量分类克拉与价格的气泡散点图
(2)按照颜色分类克拉与价格的气泡散点图
8.箱型图
(1)各钻石透明度价格的箱型图
(2)各钻石切割质量价格的箱型图
9 .堆积直方图
10 .分布直方图
(1)颜色
(2)透明度
(3)切割质量
总结
该数据及是在机器学习常见数据集中的diamond数据集.diamonds是包括近54000颗钻石的价格和其他属性的内置数据集,共53940行个10变量.
对该数据集进行探索性分析,并做数据可视化处理,探索钻石的价格、重量分布,及钻石价格与重量、形状、切割状态、颜色、透明度之间的关系。接下来,进行非参数检验,探究不同切割类型、颜色和透明度的钻石,价格是否具有显著性差异.
我们所用到的绘图库为seaborn
大家要没有的话可以安装以下
打开cmd输入以下代码安装seaborn
pip install seaborn
安装完导入即可
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
使用jupyternotebook.
那么我们就来具体的看一下吧!
carat |
cut |
color |
clarity |
depth |
table |
price |
x |
y |
z |
0.23 |
Ideal |
E |
SI2 |
61.5 |
55 |
326 |
3.95 |
3.98 |
2.43 |
0.21 |
Premium |
E |
SI1 |
59.8 |
61 |
326 |
3.89 |
3.84 |
2.31 |
0.23 |
Good |
E |
VS1 |
56.9 |
65 |
327 |
4.05 |
4.07 |
2.31 |
0.29 |
Premium |
I |
VS2 |
62.4 |
58 |
334 |
4.2 |
4.23 |
2.63 |
0.31 |
Good |
J |
SI2 |
63.3 |
58 |
335 |
4.34 |
4.35 |
2.75 |
0.24 |
Very Good |
J |
VVS2 |
62.8 |
57 |
336 |
3.94 |
3.96 |
2.48 |
0.24 |
Very Good |
I |
VVS1 |
62.3 |
57 |
336 |
3.95 |
3.98 |
2.47 |
0.26 |
Very Good |
H |
SI1 |
61.9 |
55 |
337 |
4.07 |
4.11 |
2.53 |
0.22 |
Fair |
E |
VS2 |
65.1 |
61 |
337 |
3.87 |
3.78 |
2.49 |
0.23 |
Very Good |
H |
VS1 |
59.4 |
61 |
338 |
4 |
4.05 |
2.39 |
cut:钻石的切工,由低到高依次为Fair, Good, Very Good, Premium, Ideal;
color:钻石的颜色,从最低的J到最高的D;
clarity:钻石的纯净度,从低到高依次为I1, SI1, SI2, VS1, VS2, VVS1, VVS2, IF;
depth:钻石的总深度;
table:钻石的桌面比例;
price:钻石的价格;
x:钻石的长度;
y:钻石的宽度;
z:钻石的深度;
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as mpl
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['savefig.dpi'] = 300 #图片像素
plt.rcParams['figure.dpi'] = 300 #分辨率
data = pd.read_csv(r"C:\\Opencv\\Data_Visualization\\data\\datasets-master\\diamonds.csv")
data.head()
data.info()
columns = ["克拉","切割质量","钻石颜色","钻石透明度","总深度百分比","钻石顶部相对于最宽点的宽度","钻石价格(美元)","钻石长度","钻石宽度","钻石深度"]
[*zip(data.columns,columns)]
数据的描述性统计
data.describe([0.01,0.05,0.1,0.25,0.5,0.75,0.9,0.99]).T
这里对数据的描述性统计的结果大家可以仔细分析一下,会对数据的分析会更加理解.
首先拿来个数据无从下手,那我们直接画成对分析图直接来观察各特征的相关性.
import matplotlib.pyplot as plt
import seaborn as sns
# 用Seaborn画成对关系
sns.pairplot(data)
plt.show()
从这个图大概我们可以看出各变量的相关程度,从图中我们可以发现钻石的克拉随着钻石的长度,钻石的宽度,钻石的深度增加而增加.
sns.pairplot(data #数据,各个特征和标签
,kind ='reg'#要绘制的图像类
)
这就比较明显了但总觉得少了点什么,那么接下来我们画第一各正式的图.
coef = data.corr()
coef
#确保正常显示中文+负号
plt.rcParams['font.sans-serif']=['Simhei']
plt.rcParams['axes.unicode_minus']=False
#绘制图像
plt.figure(figsize=(12,10), dpi= 400) # dpi图像分辨率
sns.heatmap(data.corr() #需要输入的相关性矩阵
, xticklabels=coef.columns #横坐标标签
, yticklabels=coef.columns #纵坐标标签
, cmap='RdYlGn' #使用的光谱,一般来说都会使用由浅至深,或两头颜色差距较大的光谱
, center=0 #填写数据的中值,注意观察此时的颜色条,大于0的是越来越靠近绿色,小于0的越来越靠近红色
, annot=True
)
#装饰图像
plt.title('diamonds数据集的相关矩阵', fontsize=22)
plt.xticks(fontsize=12 #字体大小
,rotation=45 #字体是否进行旋转
,horizontalalignment='right' #刻度的相对位置
)
plt.yticks(fontsize=12)
plt.show()
分析热力图
sns.distplot(data['price'],bins=50,kde_kws={"color":"seagreen", "lw":3 }, hist_kws={ "color": "b" })
plt.gca().set(xlim=(0.0, 21000),yticks = [],
xlabel='price', ylabel='counts')
plt.show()
在价格方面上数据主要分布在<7500美元,折合人民币5万多,最多的主要大概分布在1500美元左右.
plt.hist(x=data.loc[:,"carat"] , bins=50, histtype='stepfilled' , orientation='vertical', color='blue')
plt.xlabel("the carat")
plt.ylabel("counts")
plt.show()
可见数据在克拉这个特征上的分布主要在carat<=2这个范围,钻石本身比较珍贵越大越稀有价格越贵.
import matplotlib.pyplot as plt
fig,(ax1,ax2) = plt.subplots(1,2)
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.5)
plt.figure(figsize=(20,15),dpi=200)
ax1.hist(x=data.loc[:,"depth"] , bins=50, histtype='stepfilled' , orientation='vertical', color='blue')
ax2.hist(x=data.loc[:,"table"] , bins=50, histtype='stepfilled' , orientation='vertical', color='blue')
ax1.set_xlabel("the depth")
ax1.set_ylabel("the number of diamonds")
ax2.set_xlabel("the table")
ax2.set_ylabel("the number of diamonds")
plt.show()
#数据准备
df = data.groupby('cut').size().reset_index(name = 'counts')
explode = [0,0,0,0,0.1]
#绘制图像
fig, ax = plt.subplots(figsize=(7, 7), dpi= 200)
wedges, texts, autotexts = ax.pie(x=X,
autopct=lambda x:"{:.2f}%({})".format(x,int(x*df["counts"].sum())),
colors=plt.cm.Dark2.colors, #图形的颜色
startangle=150, #第一瓣扇叶从什么角度开始
explode=explode #扇叶与扇叶之间的距离
)
#装饰图像
categories = lables_cut #选取图例
ax.legend(categories #输入数据
, title="Cut Class" #图例的标题
, loc="center left"
, bbox_to_anchor=(1, 0, 0.5, 1) #还记得bbox_to_anchor的用法么?
)
ax.set_title("Class of diamonds: cut")
plt.setp(autotexts, size=12, weight=700, color="w"
) #设置某个对象(Artist)的属性(Property)
plt.show()
lables_color = ['D', 'E', 'F', 'G', 'H', 'I', 'J']
df = data.groupby('color').size().reset_index(name = 'counts')
#数据准备
explode = [0.1,0,0,0,0,0,0]
X = df["counts"]
#绘制图像
fig, ax = plt.subplots(figsize=(7, 7), dpi= 200)
wedges, texts, autotexts = ax.pie(x=X,
autopct=lambda x:"{:.2f}%".format(x),
colors=plt.cm.Dark2.colors, #图形的颜色
startangle=150, #第一瓣扇叶从什么角度开始
explode=explode #扇叶与扇叶之间的距离
)
#装饰图像
categories = lables_color #选取图例
ax.legend(categories #输入数据
, title="Color Class" #图例的标题
, loc="center left"
, bbox_to_anchor=(1, 0, 0.5, 1)
)
ax.set_title("Class of diamonds: color")
plt.setp(autotexts, size=12, weight=700, color="w"
) #设置某个对象(Artist)的属性(Property)
plt.show()
lables_clarity = ['I1','SI2', 'SI1','VS2','VS1','VVS2','VVS1','IF']
df = data.groupby('clarity').size().reset_index(name = 'counts')
#数据准备
explode = [0,0,0,0,0,0,0,0.1]
X = df["counts"]
#绘制图像
fig, ax = plt.subplots(figsize=(7, 7), dpi= 200)
wedges, texts, autotexts = ax.pie(x=X,
autopct=lambda x:"{:.2f}%".format(x),
colors=plt.cm.Dark2.colors, #图形的颜色
startangle=150, #第一瓣扇叶从什么角度开始
explode=explode #扇叶与扇叶之间的距离
)
#装饰图像
categories = lables_clarity #选取图例
ax.legend(categories #输入数据
, title="Clarity Class" #图例的标题
, loc="center left"
, bbox_to_anchor=(1, 0, 0.5, 1)
)
ax.set_title("Class of diamonds: clarity")
plt.setp(autotexts, size=12, weight=700, color="w"
) #设置某个对象(Artist)的属性(Property)
plt.show()
我们为什么要画和密度图呢
首先对于我们普通人来说钻石是很昂贵的奢饰品,会选择那些价格相对比较低的钻石.
对于富人来说可能会选择更大的价格更高的钻石,针对人群不同我们就需要对这些特征在价格上的分布情况,来分析对于某一类人来说,选择什么样的钻石会更好.
对于seaborn来说也就是一行代码.
sns.jointplot(x="cut_no", y="price", data=data1, kind='kde')
sns.jointplot(x="cut_no", y="price", data=data1, kind='hex')
plt.show()
对于切割质量这个特征来说是唯一一个可以进行认为干预的特征看,所以分布偏向于好的.
sns.jointplot(x="color_no", y="price", data=data1, kind='kde')
sns.jointplot(x="color_no", y="price", data=data1, kind='hex')
plt.show()
sns.jointplot(x="clarity_no", y="price", data=data1, kind='kde')
sns.jointplot(x="clarity_no", y="price", data=data1, kind='hex')
plt.show()
import numpy as np
#plt.style.use('seaborn-whitegrid')
#sns.set_style("white")
#预设图像的各种属性
large = 22; med = 16; small = 12
params = {'axes.titlesize': large, #子图上的标题字体大小
'legend.fontsize': med, #图例的字体大小
'figure.figsize': (16, 10), #图像的画布大小
'axes.labelsize': med, #标签的字体大小
'xtick.labelsize': med, #x轴上的标尺的字体大小
'ytick.labelsize': med, #y轴上的标尺的字体大小
'figure.titlesize': large} #整个画布的标题字体大小
plt.rcParams.update(params) #设定各种各样的默认属性
#plt.style.use('seaborn-whitegrid') #设定整体风格
#sns.set_style("white") #设定整体背景风格
df = data.loc[:,["carat","price"]]
#准备标签列表
categories = np.unique(data['cut'])
colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
#布置画布
fig = plt.figure(figsize=(14,8), dpi=120, facecolor='w', edgecolor='k')
#循环绘图
#之前在给散点加入颜色的时候,我们提到X轴,Y轴上的值和我们的颜色是一一对应的
#那只要点的尺寸和我们的坐标点(x1,x2)一一对应,那我们就可以相应地给每一个点添加尺寸信息
for i, category in enumerate(categories):
plt.scatter('carat', 'price', data=data.loc[data.cut==category,:]
#, s = midwest.loc[midwest.category==category, "percasian"]*500 #调整尺寸,让散点图成为气泡图
, s = "depth" #现在的特征为我们的点的尺寸大小
#, s=20 #size
, c= np.array(colors[i]).reshape(1,-1)
, label=str(category)
, edgecolors = np.array(colors[i]).reshape(1,-1) #点的边缘的颜色
#, edgecolors="k"
, alpha = 0.7 #图像的透明度
, linewidths=0.5 #点的外圈的线条的宽度
)
sns.regplot(x='carat', y='price', order=4, data=df,scatter_kws = {'alpha' : 0})
#装饰图像
plt.gca().set(xlim=(0.0, 6.0), ylim=(0, 20000),
xlabel='carat', ylabel='price')
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.title("按照切割质量分类克拉与价格的气泡散点图", fontsize=22)
plt.legend(fontsize=12
,markerscale=0.5 #现有的图例气泡的某个比例
)
plt.show()
这个图这样看就会乱但是还是可以看出大致大价格随着carat的规律
画了个分解图以便大家更好的观察
import numpy as np
#plt.style.use('seaborn-whitegrid')
#sns.set_style("white")
#预设图像的各种属性
large = 22; med = 16; small = 12
params = {'axes.titlesize': large, #子图上的标题字体大小
'legend.fontsize': med, #图例的字体大小
'figure.figsize': (16, 10), #图像的画布大小
'axes.labelsize': med, #标签的字体大小
'xtick.labelsize': med, #x轴上的标尺的字体大小
'ytick.labelsize': med, #y轴上的标尺的字体大小
'figure.titlesize': large} #整个画布的标题字体大小
plt.rcParams.update(params) #设定各种各样的默认属性
#plt.style.use('seaborn-whitegrid') #设定整体风格
#sns.set_style("white") #设定整体背景风格
#准备标签列表
categories = np.unique(data['cut'])
colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
fig, ax = plt.subplots(5,1,figsize=(14*5,8*5))
#布置画布
fig = plt.figure(figsize=(14,8), dpi=120, facecolor='w', edgecolor='k')
#循环绘图
#之前在给散点加入颜色的时候,我们提到X轴,Y轴上的值和我们的颜色是一一对应的
#那只要点的尺寸和我们的坐标点(x1,x2)一一对应,那我们就可以相应地给每一个点添加尺寸信息
for i, category in enumerate(categories):
ax[i].scatter('carat', 'price', data=data.loc[data.cut==category,:]
, s = "depth" #现在的特征为我们的点的尺寸大小
#, s=20 #size
, c= np.array(colors[i]).reshape(1,-1)
, label=str(category)
, edgecolors = np.array(colors[i]).reshape(1,-1) #点的边缘的颜色
#, edgecolors="k"
, alpha = 0.7 #图像的透明度
, linewidths=0.5 #点的外圈的线条的宽度
)
import numpy as np
#plt.style.use('seaborn-whitegrid')
#sns.set_style("white")
#预设图像的各种属性
large = 22; med = 16; small = 12
params = {'axes.titlesize': large, #子图上的标题字体大小
'legend.fontsize': med, #图例的字体大小
'figure.figsize': (16, 10), #图像的画布大小
'axes.labelsize': med, #标签的字体大小
'xtick.labelsize': med, #x轴上的标尺的字体大小
'ytick.labelsize': med, #y轴上的标尺的字体大小
'figure.titlesize': large} #整个画布的标题字体大小
plt.rcParams.update(params) #设定各种各样的默认属性
#plt.style.use('seaborn-whitegrid') #设定整体风格
#sns.set_style("white") #设定整体背景风格
df = data.loc[:,["carat","price"]]
#准备标签列表
categories = np.unique(data['color'])
colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
#布置画布
fig = plt.figure(figsize=(14,8), dpi=120, facecolor='w', edgecolor='k')
#循环绘图
#之前在给散点加入颜色的时候,我们提到X轴,Y轴上的值和我们的颜色是一一对应的
#那只要点的尺寸和我们的坐标点(x1,x2)一一对应,那我们就可以相应地给每一个点添加尺寸信息
for i, category in enumerate(categories):
plt.scatter('carat', 'price', data=data.loc[data.color==category,:]
#, s = midwest.loc[midwest.category==category, "percasian"]*500 #调整尺寸,让散点图成为气泡图
, s = "depth" #现在的特征为我们的点的尺寸大小
#, s=20 #size
, c= np.array(colors[i]).reshape(1,-1)
, label=str(category)
, edgecolors = np.array(colors[i]).reshape(1,-1) #点的边缘的颜色
#, edgecolors="k"
, alpha = 0.7 #图像的透明度
, linewidths=0.5 #点的外圈的线条的宽度
)
sns.regplot(x='carat', y='price', order=4, data=df,scatter_kws = {'alpha' : 0})
#装饰图像
plt.gca().set(xlim=(0.0, 6.0), ylim=(0, 20000),
xlabel='carat', ylabel='price')
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.title("按照颜色分类克拉与价格的气泡散点图", fontsize=22)
plt.legend(fontsize=12
,markerscale=0.5 #现有的图例气泡的某个比例
)
plt.show()
#分割画布
fig = plt.figure(figsize=(16, 10), dpi= 80,facecolor="white")
grid = plt.GridSpec(1, 8, hspace=0.5, wspace=0.2)
colors = [plt.cm.coolwarm(i/float(7)) for i in range(8)]
ax = []
for i in range(0,8):
ax.append(fig.add_subplot(grid[i],xticklabels=[], yticklabels=[]))
for i,s in enumerate(lables_clarity):
sns.boxplot(x=data[(data['clarity'] == s)]['price'].apply(np.sqrt),
ax=ax[i],
orient="v", color=colors[i])
#装饰图像
for i in range(1,8):
fig.add_subplot(ax[i],xticklabels=[], yticklabels=[]).set(xlabel='')
fig.add_subplot(ax[i],xticklabels=[], yticklabels=[]).set(ylabel='')
for i in range(0,8):
ax[i].set_xlabel(lables_clarity[i])
ax[0].set_ylabel('sqrt(price)')
fig.suptitle('各钻石透明度价格的箱型图')
plt.show()
#分割画布
fig = plt.figure(figsize=(16, 10), dpi= 80,facecolor="white")
grid = plt.GridSpec(1, 5, hspace=0.5, wspace=0.2)
colors = [plt.cm.coolwarm(i/float(4)) for i in range(5)]
ax = []
for i in range(0,5):
ax.append(fig.add_subplot(grid[i],xticklabels=[], yticklabels=[]))
for i,s in enumerate(lables_cut):
sns.boxplot(x=data[(data['cut'] == s)]['price'].apply(np.sqrt),
ax=ax[i],
orient="v", color=colors[i])
#装饰图像
for i in range(1,5):
fig.add_subplot(ax[i],xticklabels=[], yticklabels=[]).set(xlabel='')
fig.add_subplot(ax[i],xticklabels=[], yticklabels=[]).set(ylabel='')
for i in range(0,5):
ax[i].set_xlabel(lables_cut[i])
ax[0].set_ylabel('sqrt(price)')
fig.suptitle('各钻石切割质量价格的箱型图')
plt.show()
这里的箱线图就不带大家分析了,因为不是太好分析.画出来的箱线图有很多异常值点大家可以试着分析一下异常值点的情况.
这个是可以反应连续型变量与分类型变量的关系.
data = pd.read_csv(r"C:\\Opencv\\Data_Visualization\\data\\datasets-master\\diamonds.csv")# Import Data
# Prepare data
x_var = 'carat' #横坐标所需特征
groupby_var = 'cut' #分类变量
data_agg = data.loc[:, [x_var, groupby_var]].groupby(groupby_var) #根据分类变量将所需数据分组
vals = [data[x_var].values.tolist() for i, data in data_agg] #提取出每一组中的数据
# Draw
plt.figure(figsize=(16,9), dpi= 300)#创建画布并设定画布大小
#colors = [plt.cm.Spectral(i/float(len(vals)-1)) for i in range(len(vals))] #生成颜色列表
colors = [plt.cm.Spectral(i/float(len(vals))) for i in range(len(vals))]
n, bins, patches = plt.hist(vals, 100, stacked=True, density=False, color=colors[:len(vals)]) #绘制直方图
# Decoration
plt.legend({group:col for group, col in zip(np.unique(data[groupby_var]).tolist(), colors[:len(vals)])}) #添加图例
plt.title("carat与cut的堆积直方图", fontsize=22) #添加标题
plt.xlabel(x_var) #添加 X轴标题
plt.ylabel("Frequency")#添加 Y轴标题
plt.ylim(0, 10000) #设定Y轴刻度范围
plt.xlim(0,5) #设定Y轴刻度范围
plt.xticks(ticks=bins[::3], labels=[round(b,1) for b in bins[::3]],rotation=45)#设定 X轴刻度
plt.show() #本地显示图形
#分割画布
fig = plt.figure(figsize=(16, 10), dpi= 80,facecolor="white")
grid = plt.GridSpec(3, 3, hspace=0.5, wspace=0.3)
colors = [plt.cm.Spectral(i/float(7)) for i in range(8)]
ax = []
for i in range(0,3):
for j in range(0,3):
if (i == 2 and (j == 1 or j == 2)):
pass
else:
ax.append(fig.add_subplot(grid[i,j],xticks=[0,5000,10000,15000,20000], yticks=[0,1000,2000,3000]))
for i in range(0,7):
ax[i].hist(x=data[data['color'] == lables_color[i]].price , bins=40, histtype='stepfilled' , orientation='vertical', color=colors[i])
ax[i].set_xlim(0,20000)
ax[i].set_ylim(0,3000)
for i in range(0,7):
ax[i].set_xlabel(lables_color[i])
ax[i].set_ylabel("counts")
fig.suptitle('Price distribution of diamonds of different colors')
plt.show()
#分割画布
fig = plt.figure(figsize=(16, 10), dpi= 80,facecolor="white")
grid = plt.GridSpec(3, 3, hspace=0.5, wspace=0.3)
colors = [plt.cm.Spectral(i/float(7)) for i in range(8)]
ax = []
for i in range(0,3):
for j in range(0,3):
if (i == 2 and j == 2):
pass
else:
ax.append(fig.add_subplot(grid[i,j],xticks=[0,5000,10000,15000,20000], yticks=[0,1000,2000,3000]))
for i in range(0,8):
ax[i].hist(x=data[data['clarity'] == lables_clarity[i]].price , bins=40, histtype='stepfilled' , orientation='vertical', color=colors[i])
ax[i].set_xlim(0,20000)
ax[i].set_ylim(0,3000)
for i in range(0,8):
ax[i].set_xlabel(lables_clarity[i])
ax[i].set_ylabel("counts")
fig.suptitle('Price distribution with different transparency')
plt.show()
#分割画布
fig = plt.figure(figsize=(16, 10), dpi= 80,facecolor="white")
grid = plt.GridSpec(2, 3, hspace=0.5, wspace=0.3)
colors = [plt.cm.Spectral(i/float(7)) for i in range(8)]
ax = []
for i in range(0,2):
for j in range(0,3):
if (i == 1 and (j == 1 or j == 2)):
pass
else:
ax.append(fig.add_subplot(grid[i,j],xticks=[0,5000,10000,15000,20000], yticks=[0,1000,2000,3000,4000,5000]))
for i in range(0,4):
ax[i].hist(x=data[data['cut'] == lables_cut[i]].price , bins=50, histtype='stepfilled' , orientation='vertical', color=colors[i])
ax[i].set_xlim(0,20000)
ax[i].set_ylim(0,5000)
for i in range(0,4):
ax[i].set_xlabel(lables_cut[i])
ax[i].set_ylabel("counts")
fig.suptitle('Price distribution of diamonds in different cut states')
plt.show()