python数据科学-单变量数据分析

时间:2022-05-08
本文章向大家介绍python数据科学-单变量数据分析,主要内容包括01|背景:、02|单变量数据分析:、2.2对单变量数据进一步分析:、涉及的知识点总结:、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

总第85篇

01|背景:

我们在做机器学习之前,需要自己先对数据进行深入的了解(这些数据是什么类型,总共有多少数据,有没有缺失值,均值是多少之类的),只有自己对数据足够了解了,才能够更好地利用机器学习。我们把在正式开始机器学习之前对数据的了解过程成为探索性分析 , 简称 EDA。

02|单变量数据分析:

单边量数据是指数据集中只有一个变量 ,也可以是多列中的某一列(可以理解成是某一个指标)。比如一个班的体测成绩表是一个数据集(包含身高、体重、1000 米用时之类的各种指标),那么该数据集里面的某一个指标就可以看作是一个单变量数据。

我们本篇以美国总统历年在国情咨询中对国会提起的诉求数量作为实例。

2.1数据整体情况了解:

我们在拿到一批/列数据时,第一件事就是看一下这批数据的一个整体分布情况,而要看分布情况最好的方法就是绘制该批数据的散点图。

#加载需要的库%matplotlib inline
import numpy as np
plt.style.use("ggplot")
from matplotlib.pylab import frange
import matplotlib.pyplot as plt

#导入相应的数据
fill_data=lambda x:int(x.strip() or 0)#用来处理缺失值,如果缺失,用0填充
data=np.genfromtxt("D:\Data-Science\Exercisedata\python数据科学指南配套文件\president.csv",
                   dtype=(int,int),delimiter=",",converters={1:fill_data})
x=data[:,0]
y=data[:,1]

#绘制数据图表以观察趋势
ax1=plt.subplot(1,1,1)
ax1.set_title("All data")
ax1.scatter(x,y,c="r")
ax1.set_xlabel("year")
ax1.set_ylabel("No presdential Request")

通过上图我们可以看出,大部分数据分布还是相对比较集中,但是这是主观上感觉,我们需要采用更科学的方法来进行衡量,这里采用分位数去衡量。

分位数是指在统计学中把所有数值由小到大排列按所处的位置进行分割,一般会把所有的数据用三个点(25、50、75位置的)分成四份。

#计算数据的百分位数(第25、50、75位数)以了解数据分布
perc_25=np.percentile(y,25)
perc_50=np.percentile(y,50)
perc_75=np.percentile(y,75)
print("25th Percentile=%0.2f"%(perc_25))
print("50th Percentile=%0.2f"%(perc_50))
print("75th Percentile=%0.2f"%(perc_75))

在得到相应的分位数以后,我们将分位数对应的图表绘制到散点图中。

#将这些百分位数添加到之前绘制的图表中作为参考
ax1=plt.subplot(1,1,1)
ax1.set_title("All data")
ax1.scatter(x,y,c="r")
ax1.set_xlabel("year")
ax1.set_ylabel("No presdential Request")
ax1.axhline(perc_25,label="25th",c="y")
ax1.axhline(perc_50,label="50th",c="g")
ax1.axhline(perc_75,label="75th",c="m")
ax1.legend(loc="best")

现在可以看到,大部分数据确实是分布在 50 分位数(中间值)的两侧,只有左上角和右下角的几个点离 50 分位数比较远,,这里把他们当作异常值来看待。

异常值的处理方式可以直接删除,也可以把异常值当作缺失值对待进行值替换,具体选择哪种根据不同情况来定,我们这里选择把异常值删除掉。

#在图形中查找是否存在异常值
#使用mask函数删除异常值
#删除异常值0和54
y_masked=np.ma.masked_where(y==0,y)
y_masked=np.ma.masked_where(y==54,y_masked)

重新绘制图表,并将对应的分位数线也绘制进去。

#在图中添加25、50、75分位数线
ax2=plt.subplot(1,1,1)
ax2.scatter(x,y_masked,c="r")
ax2.set_title("Masked data")
ax2.set_xlabel("year")
ax2.set_ylabel("No Presedential Request")
ax2.set_ylim(0,60)
ax2.axhline(perc_25,label="25th perc",c="y")
ax2.axhline(perc_50,label="50th perc",c="g")
ax2.axhline(perc_75,label="75th perc",c="m")
ax2.legend(loc="best")

现在看起来是不是就顺眼很多了哈。通过上表我们可以看出,该批数据大部分还是集中 50 分位数(中间位置数)附近,绝对值大小为 20 左右。散点图能帮我们对数据有一个大概的认识,但是还不够具体,我们接下来通过其他几个角度继续对该批数据集进行探索。

2.2对单变量数据进一步分析:

看了整体数据分布以后我们还想看得更具体一点,比如:哪一年的诉求量最多?哪个量级的诉求量最多之类的。

对诉求数量的绝对量级进行分析:

#对数据出现的频率进行统计
x_freq=Counter(y)
x_=list(x_freq.keys())#某一个量级诉求数量出现的次数
y_=list(x_freq.values())#诉求数量绝对值

#绘制分组数据的点阵图
plt.subplot(111)
plt.title("Dot Plot by Frequency")

#绘制频率plt.plot(y_,x_,"yo")
plt.xlabel("Count")
plt.ylabel("Presdential Request")

#设置x轴的最小值和最大值
plt.xlim(min(y_)-1,max(y_)+1)
plt.ylim(-5,60)

通过上图可以看出,超过30的诉求数量只出现一次,出现2次,3次的诉求数量均低于30,说明生活还是很稳定,人们的诉求并不是那么多。(我瞎说的)

对不同年份的诉求数量分析:

#采用年份范围进行分组
x_group=collections.OrderedDict()
group=5group_count=1
keys=[]
values=[]
for i,xx in enumerate(x):
    keys.append(xx)
    values.append(y[i])    
    if group_count==group:
        x_group[tuple(keys)]=values
        keys=[]
        values=[]
        group_count=0
    group_count+=1x_group[tuple(keys)]=values
print(x_group) 

#绘制散点图plt.subplot(111)    
x_vals=[]
x_labels=[]
y_vals=[]
x_tick=1
for k,v in x_group.items():    
    for i in range(len(k)):
        x_vals.append(x_tick)
        x_label="-".join([str(kk) if not i else str(kk)[-2:] for i ,kk in enumerate(k)])
        x_labels.append(x_label)
    y_vals.extend(list(v))
    x_tick+=1plt.title("Dot Plot by Year Grouping")
plt.xlabel("Year Group")
plt.ylabel("No Presedential Request")try:
    plt.plot(x_vals,y_vals,"co")except ValueError:
    print(len(x_vals),len(y_vals))

plt.xticks(x_vals,x_labels,rotation=-50)
plt.ylim(-5,60)

年份分析里面我们以5年为一个界限进行分组,通过图表我们可以看出1961-1965的诉求数量最低,且均低于20,1986-1990年的诉求数量较分散,且诉求数量的绝对值在该范围内,1981-1985年之间的诉求数量较平稳,且5年中有4年的诉求数量是低于10的。

涉及的知识点总结:

  • np.genfromtxt()#numpy库中用来读取文件的,相当于pandas中的read_csv()。
  • np.percentile()#用来计算一批数据的分位数。
  • np.ma.masked_where()#用来屏蔽满足某一条件的数值,常用来处理缺失数据。
  • Collections.OrderedDict()#用来创建一个有序字典。
  • Counter()#用于统计一批数据中不同点出现的次数,返回一个字典,键为值,值为键在该批数据中出现的次数。
  • enumerate()#用于返回一个值在一批数据中出现的顺序。
  • np.repeat()#用于重复某一个序列数据。