数据的探索性分析
IBM Machine Learning是Coursera上的一门课程,学习的内容简略记录一下,第一周内容是Exploratory Data Analysis for Machine Learning,也就是探索性分析(EDA),主要章节包含六个部分,以下一一介绍:
1. 读入数据
数据的来源有很多种,例如csv文件、json文件、数据库文件等,需要用到的库为pandas
(1)csv文件读取
import pandas as pd
filepath = " "
data = pd.read_csv(filepath)
# 一些重要参数:
# 以tab作为分隔符的文件(.tsv)
data = pd.read_csv(filepath, sep = "\t")
# 以空格作为分隔符的文件
data = pd.read_csv(filepath, delim_whitespace = True)
# 不使用第一行作为列名
data = pd.read_csv(filepath, header=None)
# 选择需要的列名读取
data = pd.read_csv(filepath, names = ["name", "age"])
# 读取时使特定值变为缺失值
data = pd.read_csv(filepath, na_values="NA")
(2)json文件读取
# 读取json文件
data = pd.read_json(filepath)
# 将dataframe导出为json
data.to_json("output.json")
(3)SQL数据库读取
SQL数据库有很多种类,例如MySQL、Oracle DB、Db2 Family等,从这些数据库中读取文件时需要用到不同种类的库。
以sqlite3为例:
import sqlite3 as sq3
path = " "
con = sq3.Connection(path)
query = ''' SELECT * FROM rock_songs;
'''
data = pd.read_sql(query, con)
(4)Not-only SQL (NoSQL)读取
一些NoSQL数据库,例如MongoDB、 Hbase、Neo4j等,许多NoSQL数据库以json形式存储数据
以MongoDB为例;
from pymongo import MongoClient
con = MongoClient()
db = con.database_name
cursor = db.collection_name.find(query)
df = pd.DataFrame(list(cursor))
注:这部分代码是复制的,未经证实,本人对SQL不太了解
(5)从网络中获取
data_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/autos/imports-85.data"
data = pd.read_csv(data_url, header = None)
2. 数据清洗
数据清洗对于数据分析有着重要作用,数据清洗主要包括重复值/无意义数据、文本输入问题、缺失值、异常值、数据来源问题等,主要需要处理的问题为缺失值和异常值
(1)缺失值问题
处理缺失值的办法:
- 删除含有缺失值的行/列
优点:处理速度快
缺点:由于数据量变少,会丢失较多信息 - 使用平均数/中位数/众数等特征来填充缺失值
优点:不会丢失太多数据
缺点:添加了额外的不确定性 - 将缺失值作为一个新的类别
优点:不会丢失太多数据
缺点:添加了额外的不确定性,即假设所有的缺失值意义相同
(2)异常值问题
异常值不会对模型造成非常巨大的影响,但也会产生某种程度的影响
寻找异常值的方法有很多种,这里介绍三种:
- 画图
import seaborn as sns
sns.distplot(data, bins=20)
- 箱线图
简单实现:
sns.boxplot(data)
箱线图的具体原理:
import numpy as np
q25, q50, q75 = np.percentile(data, [25, 50, 75])
iqr = q75 - q25
min = q25 - 1.5*iqr
max = q75 + 1,5*iqr
print(min, q25, q50, q75, max)
- 通过残差
残差是指实际值和预测值的 区别,包含以下几种:
- 标准化残差(standardized): 残差除以其标准差后得到的数值
- 剔除残差(deleted):去除掉某异常值后得到的残差
- 学生化残差(studentized):剔除残差除以其标准差。包含两种
- 学生化外残差就是异常点检验的t统计量
- 学生化内残差可得到异常点检验的似然比统计量
在找到异常值后,处理办法如下:
- 删除含有缺失值的行/列
优点:处理速度快
缺点:由于数据量变少,会丢失较多信息 - 使用平均数/中位数/众数等特征来填充缺失值
优点:不会丢失太多数据
缺点:添加了额外的不确定性 - 将数据进行变换,例如取对数,减小异常值的影响
- 通过回归或利用相似样本预测该异常值可能的值
- 使用对异常值容忍度高的模型
3. 数据探索性分析(EDA)
EDA是一种探索数据集并总结数据特征的方法,经常和可视化方法一起使用
sample = data.sample(n=5, replace=False)
print(sample.iloc[:,-3:])
在读入数据时可以随机采样观察数据的结构
EDA技术包括:
- 统计特征:平均数、中位数、最大值、最小值、相关性等
- 可视化:直方图、散点图、箱线图等
EDA使用的工具:pandas、matplotlib、seaborn
以鸢尾花数据集为例,数据参考下图,包含四个特征,三个类别
import numpy as np
import pandas as np
data = pd.read_csv(filepath)
print(data.head())
print(data.shape)
print(data.columns)
print(data.dtypes)
查看数据的前五列、形状、列名、数据类型
data.species.value_counts()
statas_df = data.describe()
status_df.loc["range"] = status_df.loc["max"] - status_df.loc["min"]
value_counts查看每种数值的数量,describe方法查看数据的统计特征
data.groupby(["species"]).agg(["mean", "median"])
按照species分组并查看平均数和中位数
import matplotlib.pyplot as plt
%matplotlib inline
ax = plt.axes()
ax.scatter(data.sepal_length, data.sepel_width)
ax.set(xlabel = "xlabel", ylabel="ylabel", title="title")
绘制散点图
# matplotlib方法
ax = plt.axes()
ax.hist(data.sepal_length, bins=25)
ax.set(xlabel = "xlabel", ylabel="ylabel", title="title")
# pandas方法
ax = data.sepal_length.plot.hist(bins=25)
ax.set(xlabel = "xlabel", ylabel="ylabel", title="title")
绘制直方图的两种方法
data.boxplot(by="species")
使用pandas画箱线图
import seaborn as sns
sns.set_context('talk')
plot = sns.pairplot(data, hue = "species")
print(plot)
绘制pairplot查看变量间的相关程度
4. 特征工程
(1)数据转换
对于线性回归,一般假定特征是正态分布的,但很多情况下,特征的分布会和正态分布有差别,此时应用数据转换有可能解决问题。
数据转换包括很多种,比如进行log变换、加入多项式特征等
- log变换
log_data = [math.log(d) for d in data["score"]]
sns.distplot(data, bins=25)
sns.distplot(log_data, bins=25)
下面的图片体现了进行log变换后数据的分布情况
- 加入多项式特征
当对于线性模型 y=wx+b无法拟合时,可以尝试加入更高阶的项
from skllearn.preprocessing import PolynomialFeatures
polyFeat = PolynomialFeatures(degree=2)
polyFeat = polyFeat.fit(x_data)
x_poly = polyFeat.transform(x_data)
(2)特征编码
对于类别特征这种非数值型特征,需要先将其编码,类别特征主要有两种:
- 没有明确顺序的特征,例如红色,黄色,绿色
- 有明确顺序的特征,例如高,中等,矮
编码的方法包括:
- 二进制编码:对于有两类的特征,分别将其编码为0,1
- one-hot编码:对于两类以上的特征使用one-hot编码
from sklearn.preprocessing import LabelEncoder, LabelBinarizer, OneHotEncoder
from pandas import get_dummies
- 有序编码:对于有序特征,可编码为1,2,3…
from sklearn.preprocessing import OrdinalEncoder
from sklearn.feature_extraction import DictVectorizer
(3)特征缩放
由于不同的连续性变量有着不同的数值范围,会导致模型对于范围较小的特征不敏感,因此要将特征进行缩放变换。
缩放的方法有:
- 标准化:减去平均值除以标准差
- 最大最小值缩放:转换到(0,1)之间,最大值视为1,最小值视为0.这种方法对异常值很敏感
- 鲁棒性缩放:和最大最小值缩放类似,但将四分之三分位点减去四分之一分位点映射到(0,1)之间
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
5. 估计和推理(estimation and inference)
本节内容比较抽象,表示没怎么看懂
估计vs推理
- 估计(estimation):是算法的应用,统计不同因素的影响,例如取平均
- 推理(inference):对估计进行准确度计算,例如标准差
有参数模型vs无参数模型
-
有参数模型(parametric model):是一种统计模型,也是一个分布或者回归的集合,有有限的参数。例如正态分布
在有参数模型中估计参数的方法:极大似然估计
常见的数据分布:均匀分布、高斯分布、log正态分布、指数分布、泊松分布等
-
无参数模型(non-parametric model):假设数据不属于任何分布,通过已有数据自行创造数据分布
频率派vs贝叶斯派;略
假设检验:略