本笔记摘录清华大学工业工程系朱成礼老师的python教案与授课内容,并在此基础上进行实操性的拓展,希望能对大家有所帮助。
一、数据分析简介
数据分析的一般流程:需求分析——>获取数据——>数据预处理——>分析与建模——>评价与优化——>部署
二、数据分析实例
1、数据集情况简介
2、数据预处理(清洗)
2.1 数据探索分析
快速了解数据全貌,发现数据特征
编号、类名、非空数的数量、数据类型
import pandas as pd
# 加载csv数据集,指定第一列为索引
iris_data = pd.read_csv('data/Iris_0625.csv)
iris_data.info() # 查看数据集信息
# 显示前5行数据
print(iris_data.head())
# 描述性统计信息
print(iris_data.describe())
2.2 重复行分析与处理
输出重复行标记,若要查看重复行,则print(a[df......])
id一样,标记为重复;定义某一列,若该列重复则就算重复(用subject指定)。keep=‘first'表示第一个不标记为重复,后面的算重复
inplace = True在原来DataFrame上做操作;False生成DataFrame副本
2.3缺失值分析与处理
缺失值的处理方法:
• 删除含有缺失值的记录
• 数据补齐(就近补齐、均值补齐、利用同类均值补齐、拟合补齐)
• 不处理
2.3.1 缺失值检测
2.3.2 使用describe检测缺失值
count列表示非空的数字个数
2.3.3 使用fillna()填充缺失值
df.fillna(value=None, method=None, axis=None)
# method:{‘ffill’用前面的值填充, ‘bfill’用后面的值填充, None用value去填充}
df1 = df.fillna('missing')
df2 = df.fillna(method='ffill')
values = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
# A,B,C,D指列的名字
df3 = df.fillna(value=values, limit=1)
2.3.4 用dropna()删除
df.dropna(axis=0, how='any', thresh=None)
df1 = df.dropna() # 删除含有缺失值的行
df2 = df.dropna(how='all') # 删除全为缺失值的行
df3 = df.dropna(thresh=2) # 删除至少含有2个缺失值的行
2.3.5 使用同类均值填补缺失值
df_data = pd.read_csv('data/iris_deldup.csv',
index_col=[0])
# 按类别分组
iris_group = df_data.groupby(‘Species’)
# 用类别均值填充缺失值
for x in iris_group: # 对每一个组都进行同样的操作
values = x[1].mean().to_dict() # 以列为key,以均值为value生成字典
x[1].fillna(value=values, inplace=True)
df_data.update(x[1])
# 填充后的数据保存至硬盘
df_data_fillna.to_csv('data/iris_fillna.csv')
2.4 异常值分析与处理.
2.4.1 基于偏差的方法
绘制直方图,若服从正态分布,则可使用此法
2.4.2 箱线图分析法
上限之上、下限之下的数据被认为是异常值
删除异常值
sw_q1 = df_data['SepalWidth'].quantile(0.25) # 计算上四分位数
sw_q3 = df_data['SepalWidth'].quantile(0.75) # 计算下四分位数
sw_iqr = sw_q3 - sw_q1 # 计算四分位间距
sw_low = sw_q3 - 1.5 * sw_iqr # 计算下限
sw_up = sw_q1 + 1.5 * sw_iqr # 计算上限
delabnormal_data = df_data.query(f'SepalWidth > {sw_low} and
SepalWidth < {sw_up}')
# 绘制去除异常值之后,花萼宽度箱线图
delabnormal_data[['SepalWidth']].plot(kind='box', grid=False)
plt.savefig('figure/iris_sepalwidth_box')
delabnormal_data.to_csv('data/iris_delabnormal.csv')
2.5 应用实例1
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
# 数据快速探索性分析
# 加载数据集
iris_data = pd.read_csv('Iris_0625.csv')
# 查看数据集信息
iris_data.info()
# 输出前六行数据
print(iris_data.head(6))
# 输出数据统计量(最大值、均值、四分数、标准差)
print(iris_data.describe())
# 重复行及缺失值处理
# 输出重复行,统计重复行数
dup_row = iris_data.duplicated(keep=False)
print(f'重复行:{iris_data[dup_row]}')
dup_count = dup_row.sum()
print(f'重复行数:{dup_count}')
# 保留一行并删除其余行
df_result = iris_data.drop_duplicates(keep='first')
df_result.to_csv('iris_delduplicated.csv', index=False)
iris_delduplicated = pd.read_csv('iris_delduplicated.csv')
# 统计缺失信息
df_r1 = iris_delduplicated.isnull()
print(f'是否有缺失值:\n{df_r1}')
df_r2 = iris_delduplicated.isnull().any(1)
print(f'行的缺失值信息为::{df_r2}')
df_r3 = iris_delduplicated.isnull().any(1).sum()
print(f'有缺失值的行的个数为:{df_r3}')
# 输出各行缺失值个数
df_r4 = iris_delduplicated.isnull().sum(axis=1)
print(f'各行缺失值个数为:{df_r4}')
# 输出缺失值总数
a = df_r4.sum(axis=0)
print(f'缺失值总数为:{a}')
# 使用列均值填充缺失值
values = iris_delduplicated.mean().to_dict()
df_fill = iris_delduplicated.fillna(value=values, limit=1)
iris_delduplicated.update(df_fill)
iris_delduplicated.to_csv('iris_fillna1.csv')
# 使用同类均值填充缺失值
# 按类别分组
iris_group = iris_delduplicated.groupby('Species')
# 用类别均值填充缺失值
for x in iris_group:
values = x[1].mean().to_dict()
x[1].fillna(value=values, inplace=True)
iris_delduplicated.update(x[1])
# 将填充后的数据保存至硬盘
iris_delduplicated.to_csv('iris_fillna2.csv')
# 异常值分析与处理
# 绘制各属性列的箱线图
plt.figure(figsize=(8, 6), num='箱线图')
plt.subplot(221)
plt.boxplot(iris_delduplicated['SepalLength'], labels=['花萼长度'])
plt.subplot(222)
plt.boxplot(iris_delduplicated['SepalWidth'], labels=['花萼宽度'])
plt.subplot(223)
plt.boxplot(iris_delduplicated['PetalLength'], labels=['花瓣长度'])
plt.subplot(224)
plt.boxplot(iris_delduplicated['PetalWidth'], labels=['花瓣宽度'])
# 调整子图之间的距离
plt.subplots_adjust(wspace=0.2, hspace=0.25)
plt.savefig('iris-box.png')
# 删除含有异常值的行
sw_q1 = iris_delduplicated['SepalWidth'].quantile(0.25) # 计算下四分位数
sw_q3 = iris_delduplicated['SepalWidth'].quantile(0.75) # 计算上四分位数
sw_iqr = sw_q3 - sw_q1 # 计算四分位间距
sw_low = sw_q1 - 1.5 * sw_iqr # 计算下限
sw_up = sw_q3 + 1.5 * sw_iqr # 计算上限
delabnormal_data = iris_delduplicated.query(f'SepalWidth > {sw_low} and SepalWidth < {sw_up}')
# 绘制去除异常值之后,花萼宽度箱线图
# 将处理后的数据保存至csv文件
delabnormal_data[['SepalWidth']].plot(kind='box', grid=False)
plt.savefig('iris_sepalwidth_box')
delabnormal_data.to_csv('iris_delabnormal.csv')
3、数据特征分析
3.1 分布分析
揭示数据的分布特征和分布类型,显示其分布情况。可用直方图表示
3.2 统计量分析
包括描述数据集中趋势的统计值(平均数、中位数和众数)、描述数据离中趋势的统计量(极 差、四分位数、平均差、方差、标准差和变异系数)和描述数据分布状况的统计量(偏态系 数)。
3.3 相关性分析
是研究两个或两个以上的变量间的相关关系。可用相关系数、散点图来反映。
3.4 特征选择
当数据预处理完成后,需要选择有意义的特征来构建数据分析模型,好的特征能够构造出 较好的分析模型。
特征选择主要有两个目的: (1)减少特征数量、降维,使模型泛化能力更强,减少过拟合 (2)增强对特征和特征值之间的理解
3.5 应用实例2
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
# 特征分析
# 加载预处理后的数据文件
iris_data = pd.read_csv('iris_delabnormal.csv', index_col=[0])
# 在一个Figure上绘制杂色鸢尾花(Species=2)四个属性的直方图(bins=20)
iris_group = iris_data.query("Species==2")
# 绘制变量直方图
plt.figure(figsize=(8, 6), num=1) # 设置图形大小和编号
plt.subplot(221) # 绘制第一个图
plt.hist(iris_group['SepalLength'], bins=20, density=True,
edgecolor='black', linewidth='1.0')
plt.xlabel('花萼长度')
plt.ylabel('频率')
plt.title('花萼长度分布图')
plt.subplot(222) # 绘制第一个图
plt.hist(iris_group['SepalWidth'], bins=20, density=True,
edgecolor='black', linewidth='1.0')
plt.xlabel('花萼宽度')
plt.ylabel('频率')
plt.title('花萼宽度分布图')
plt.subplot(223) # 绘制第一个图
plt.hist(iris_group['PetalLength'], bins=20, density=True,
edgecolor='black', linewidth='1.0')
plt.xlabel('花瓣长度')
plt.ylabel('频率')
plt.title('花瓣长度分布图')
plt.subplot(224) # 绘制第一个图
plt.hist(iris_group['PetalLength'], bins=20, density=True,
edgecolor='black', linewidth='1.0')
plt.xlabel('花瓣宽度')
plt.ylabel('频率')
plt.title('花瓣宽度分布图')
# 调整子图之间的距离
plt.subplots_adjust(wspace=0.25, hspace=0.4)
plt.savefig('iris_hist.png')
plt.show()
# 绘制三种鸢尾花SepalLength和PetalLength变量之间的散点图,并将此图保存至png文件
setosa_data = iris_data[iris_data.Species == 1]
versicolor_data = iris_data[iris_data.Species == 2]
virginica_data = iris_data[iris_data.Species == 3]
s1 = plt.scatter(setosa_data['PetalLength'],
setosa_data['PetalWidth'],
color='red', marker='.')
s2 = plt.scatter(versicolor_data['PetalLength'],
versicolor_data['PetalWidth'],
color='orange', marker='x')
s3 = plt.scatter(virginica_data['PetalLength'],
virginica_data['PetalWidth'],
color='blue', marker='+')
plt.title('花瓣长度与宽度散点图')
plt.xlabel('花瓣长度')
plt.ylabel('花瓣宽度')
plt.legend((s1, s2, s3), ('setosa', 'versicolor', 'virginica'),
loc='best')
plt.savefig('petal_lenth_width.png')
plt.show()
# 选择特征属性
# 计算各属性之间的相关系数
corr_matrix = iris_data.corr()
print(corr_matrix)
# PetalLength与PetalWidth相关系数约为0.95,保留一个变量
select_data = iris_data[['SepalLength', 'SepalWidth',
'PetalLength', 'Species']]
# 保存筛选变量后的数据
select_data.to_csv('iris_selvariables.csv', encoding='utf_8_sig')
4、分类模型
4.1 决策树分类
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
# 加载csv数据集,指定第一列为索引
df_data = pd.read_csv('data/iris_delabnormal.csv', index_col=[0])
# 将Species列赋值于y,为分类标号,其余列赋值给x,为属性集
x = df_data[['SepalLength','SepalWidth',
'PetalLength', 'PetalWidth']]
y = df_data['Species']
# 将对数据集分成训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
model_dtc = DecisionTreeClassifier() # 建立决策树模型
model_dtc.fit(x_train, y_train) # 训练模型
y_pred = model_dtc.predict(x_test) #用模型用测试集
# 计算决策树分类模型的准确率
print("决策树模型评分(acc):", model_dtc.score(x_test, y_test))
print('计算准确率(acc):', metrics.accuracy_score(y_test, y_pred))
4.2 回归分析
4.3 逻辑回归
4.4 应用案例3
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
# 加载csv数据集,指定第一列为索引
df_data = pd.read_csv('iris_delabnormal.csv', index_col=[0])
# 将Species列赋值给y,其余列赋值给x
x = df_data[['SepalLength', 'SepalWidth',
'PetalLength', 'PetalWidth']]
y = df_data['Species']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
model_dtc = DecisionTreeClassifier() # 建立决策树模型
model_dtc.fit(x_train, y_train) # 训练模型
y_pred = model_dtc.predict(x_test) # 用测试集形成一系列预测值
# 计算决策树分类模型的准确率
print(f'决策树模型评分(acc):{model_dtc.score(x_test, y_test)}')
print(f'计算准确率:{metrics.accuracy_score(y_test,y_pred)}')
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
# 加载csv数据集,指定第一列为索引
df_data = pd.read_csv('iris_delabnormal.csv', index_col=[0])
# 将Species列赋值给y,其余列赋值给x
x = df_data[['SepalLength', 'SepalWidth',
'PetalLength', 'PetalWidth']]
y = df_data['Species']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
# 建立逻辑回归模型
model_lr = LogisticRegression(max_iter=500)
model_lr.fit(x_train, y_train)
# 预测测试集
y_pred = model_lr.predict(x_test) # 返回ndarray
print(f'逻辑回归模型评分(acc):{model_lr.score(x_test, y_test)}')
print(f'逻辑回归模型评分:{metrics.accuracy_score(y_test, y_pred)}')
# 保存预测结果
y_test.to_csv('lr_test.csv')
np.savetxt('lr_pred.csv', y_pred, fmt='%0.1f', delimiter=',', newline='\n')
我们的授课内容就到此结束了,随后我还会更新更多对数据分析和机器学习的自学内容。感谢观看!