1 数据挖掘基础
-
从大量数据中挖掘出其对决策的潜在关系,并将这些关系运用于决策模型,提供预测性决策支持的方法、工具和过程,这就是数据挖掘。 -
数据挖掘的基本任务:分类与预测、聚类分析、关联规则、时序模式、偏差检测、智能推荐等。 -
数据挖掘建模过程
-
定义挖掘目标 -
数据取样 -
数据探索 异常值分析、缺失值分析、相关分析、周期性分析等(详见第3章) -
数据预处理 数据筛选、数据变量转换、缺失值处理、坏数据处理、数据标准化、主成分分析、属性选择、数据归约等(详见第3章) -
挖掘建模 -
模型评价
- 从所建立模型中找出一个最好的
- 根据业务对模型进行解释和应用(详见第5章)
2 Python数据分析简介
2.1 函数式编程
map()
a=[1,2,3]
b=[i+2 for i in a]
b=map(lambda x:x+2)
b=list(b)
列表解析的本质是for循环,map()效率更高
reduce()
s=1
for i in range(1,n+1):
s=s*i
from functools import reduce
reduce(lambda x,y:x*y,range(1,n+1))
filter()
b=[i for i in range(10) if i>5 and i<8]
b=filter(lambda x:x>5 and x<8,range(10))
b=list(b)
3 数据探索
3.1 数据质量分析
3.1.1 缺失值分析
处理方式:
? 删除存在缺失值的记录、对可能值进行插补、不处理。详见4.1.1节
查看缺失值:
describe()中的count是非空数值,通过与len作差可以得到缺失值数量。
3.1.2 异常值分析
-
简单统计量分析 -
3σ原则 ? 数据服从正态分布、在3σ原则下,异常值被定义为一组测定值中与平均值偏差超过三倍标准差的值。 ? 在正态分布的假设下,距离平均值3σ之外的值出现的概率为P(|x-μ|>3σ)≤0.003,属于极小个别的小概率事件。 ? 如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。 -
箱形图分析 ? 异常值:小于
Q
L
?
1.5
I
Q
R
Q_L-1.5IQR
QL??1.5IQR或大于
Q
U
+
1.5
I
Q
R
Q_U+1.5IQR
QU?+1.5IQR的值。
Q
L
Q_L
QL?:下四分位数,表示全部观察值中有四分之一的数据取值比它小。
Q
U
Q_U
QU?:上四分位数,表示全部观察值中有四分之一的数据取值比它大。
I
Q
R
IQR
IQR:四分位间距,是上四分位数和下四分位数之差。
餐饮数据异常值检测
import pandas as pd
catering_sale = './data/catering_sale.xls'
data = pd.read_excel(catering_sale, index_col=u'日期')
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure()
p = data.boxplot(return_type='dict')
x = p['fliers'][0].get_xdata()
y = p['fliers'][0].get_ydata()
y.sort()
for i in range(len(x)):
if i > 0:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.05 - 0.8 / (y[i] - y[i - 1]), y[i]))
else:
plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.08, y[i]))
plt.show()
结合实体业务,确定过滤规则为400以下5000以上为异常数据。
3.2 数据特征分析
3.2.1分布分析
? 对于定量数据,欲了解其分布形式是对称还是非对称的,发现某些特大或特小的可疑值,可通过绘制频率分布表、频率分布直方图、茎叶图进行直观地分析。
? 对于定性数据,可用饼图和条形图直观地显示分布情况。
1. 定量数据的分布分析
选择“组数”和“组宽”是做频率分析时最主要的问题,一般按以下步骤:
- 求极差
- 决定组距和组数
- 决定分点
- 列出频率分布表
- 绘制频率分布直方图
要遵循以下原则:
- 各组之间是相互排斥的。
- 各组必须将所有的数据包含在内。
- 各组的组宽最好相等
2. 定性数据的分布分析
import pandas as pd
dish_profit = './data/catering_dish_profit.xls'
data = pd.read_excel(dish_profit, index_col = u'菜品名')
data = data[u'盈利'].copy()
data.sort_index(ascending = False)
sizes=[i/data.sum() for i in data]
colors=['red','green']
plt.pie(sizes,labels=data.index,colors=colors,autopct='%1.1f%%',shadow=True,startangle=90)
plt.axis('equal')
3.2.2 周期性的分析
用电量时序图
3.2.3 贡献度分析
又称帕累托分析,原理是帕累托法则,又称20/80定律。
plt.figure()
data.plot(kind='bar')
plt.ylabel(u'盈利(元)')
p = 1.0*data.cumsum()/data.sum()
p.plot(color = 'r', secondary_y = True, style = '-o',linewidth = 2)
plt.annotate(format(p[6], '.4%'), xy = (6, p[6]), xytext=(6*0.9, p[6]*0.9), arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=0.02"))
plt.ylabel(u'盈利(比例)')
plt.show()
3.2.4 相关性分析
- 绘制散点图
-
绘制散点图矩阵 -
计算相关系数
-
Pearson相关系数
- 两个连续变量之间的关系
- 要求连续变量的取值服从正态分布
-
Spearman秩相关系数
- 不服从正态分布的变量、分类或等级变量之间的关联性
-
判定系数
-
相关系数的平方,用来衡量回归方程对y的解释程度。 -
判
定
系
数
取
值
范
围
:
0
≤
r
2
≤
1
,
越
接
近
1
相
关
性
越
强
。
判定系数取值范围:0≤r^2≤1,越接近1相关性越强。
判定系数取值范围:0≤r2≤1,越接近1相关性越强。
分析菜品销售量之间的相关性,得到不同菜品之间的关系。
菜品相关系数矩阵:
data.corr()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rwCR2avc-1630063913270)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20210825152043826.png)]
- DF.coor()
- 计算数据样本的Spearman(Pearson)相关数据矩阵。
- method="",支持pearson(默认)、kendall、spearman;
- S1.coor(S2,method=“pearson”)
3.2 主要函数扩展
3.2.1统计作图函数
plot
功能:绘制线性二维图、折线图
使用格式:
- plt.plot(x,y,S)
- S是字符串参量指定图形类型、样式、颜色,如:'b’为蓝色,‘+’为加号标记,‘o’为圆圈,‘–’为虚线,‘-’为实线。
- D.plt(kind=‘box’)
- 默认以index为横坐标,每列数据为纵坐标,支持:line、bar、harh、hist、box、kde、area、pie等
pie
功能:绘制饼型图
使用格式:plt.pie(size)#size:各个扇形比例
labels='A','B','C','D'
sizes=[15,30,45,10]
colors=['yellow','gold','blue','green']
explode=(0,0.1,0,0)
plt.pie(sizes,explode=explode,labels=labels,colors=colors,autopct='%1.1f%%',shadow=True,startangle=90)
plt.axis('equal')
tips:0-20等分成100份:x=np.linspace(0,20,100)
hist
功能:绘制二维条形直方图,可显示数据的分布情况
使用格式:plt.hist(x,y)
x是待绘制直方图的一维数组,y可以是整数,表示均分为y组,也可以是列表,列表各个数字为分组的边界点。
boxplot
功能:绘制样本数据的箱形图
使用格式:D.boxplot()/D.plot(kind=‘box’)
plot(logx=True)/plot(logy=True)
功能:绘制x或y轴的对数图形。
使用格式:D.plot(logx=True)
plot(yerr=error)
功能:绘制误差条形图
使用格式:D.plot(yerr=error)
如果设置参数xerr=error,则在x轴方向画出误差棒图。
4 数据预处理
4.1 数据清洗
? 删除原始数据集中的无关数据、重复数据,平滑噪声数据,筛选掉与挖掘主题无关数据,处理缺失值、异常值等。
4.1.1 缺失值处理
插值法处理:拉格朗日插值法(Scipy支持)、牛顿插值法
def ployinterp_column(s, n, k=5):
y = s[list(range(n - k, n)) + list(range(n + 1, n + 1 + k))]
y = y[y.notnull()]
return lagrange(y.index, list(y))(n)
for i in data.columns:
for j in range(len(data)):
if (data[i].isnull())[j]:
data.loc[[j], [i]] = ployinterp_column(data[i], j)
4.2 数据变换
4.2.1 规范化
不同评价指标往往具有不同量纲,不进行处理会影响数据分析结果。
-
最小-最大规范化
- (data-data.min())/(data.max()-data.min())
-
零-均值规范化
- (data-data.mean())/data.std()
-
小数定标规范化
- data/10**np.ceil(np.log10(data.abs().max()))
4.2.2 连续属性离散化
有些数据挖掘算法,特别是某些分类算法(如ID3算法、Apripri算法等),要求数据是分类属性形式,会用到将连续属性变换成分类属性的方法,即连续属性离散化。
- 等宽法:将属性值域分成具有相同宽度的区间。
- 等频法:将相同数量的记录放进每个区间。
- 基于聚类分析的方法:
- 先将连续属性的值用聚类算法进行聚类。
- 再将聚类得到的簇合并到一个簇的连续属性值,并做同一标记。
d1 = pd.cut(data, k, labels=range(k))
w = [1.0 * i / k for i in range(k + 1)]
w = data.describe(percentiles=w)[4:4 + k + 1]
w[0] = w[0] * (1 - 1e-10)
d2 = pd.cut(data, w, labels=range(k))
from sklearn.cluster import KMeans
kmodel = KMeans(n_clusters=k, n_jobs=4)
kmodel.fit(data.values.reshape((len(data), 1)))
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0)
w = c.rolling(2).mean().iloc[1:]
w = [0] + list(w[0]) + [data.max()]
d3 = pd.cut(data, w, labels=range(k))
def cluster_plot(d, k):
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 3))
for j in range(0, k):
plt.plot(data[d == j], [j for i in d[d == j]], 'o')
plt.ylim(-0.5, k - 0.5)
return plt
cluster_plot(d1, k).show()
cluster_plot(d2, k).show()
cluster_plot(d3, k).show()
4.3 数据规约
? 数据规约产生更小但保持原数据完整性的新数据集。
4.3.1 属性规约
主成分分析
import pandas as pd
inputfile = './data/principal_component.xls'
data = pd.read_excel(inputfile, header=None)
from sklearn.decomposition import PCA
pca = PCA()
pca.fit(data)
pca.components_
pca.explained_variance_ratio_
5 挖掘建模
5.1 常见的分类与预测算法
5.1.1 logistic回归
- logistic回归属于概率型非线性回归。
- 是可实现二分类或多分类的回归模型。
建模步骤:
- 筛选数据、设置指标自变量和因变量、筛选特征。
- 列出线性回归方程,估计出模型中的回归系数。
- 模型检验:正确率、混淆矩阵、ROC曲线、KS值等。
- 模型应用。
特征筛选:方法主要包含在Scikit_Learn的feature_selection库中
- F检验(f_regression):选择F值大或P值小的特征。
- 递归特征消除
- 稳定性选择
对银行降低贷款拖欠率的数据进行逻辑回归建模:
import pandas as pd
filename="./data/bankloan.xls"
data=pd.read_excel(filename)
x=data.iloc[:,:8]
y=data.iloc[:,8]
from sklearn.linear_model import LogisticRegression as LR
from sklearn.linear_model import RandomizedLogisticRegression as RLR
rlr=RLR()
rlr.fit(x,y)
rlr.get_support()
rlr.scores_
print(u'有效特征为:%s' % ','.join(data.columns[rlr.get_support(indices=True)]))
x=data.loc[:,data.columns[rlr.get_support(indices=True)]]
lr=LR()
lr.fit(x,y)
print("模型平均正确率:%s" % lr.score(x,y))
5.1.2 ID3算法
- 基于信息熵来选择最佳测试属性,选最大信息增益值的属性作为测试属性。
- 测试属性有多少不同取值就将样本集划分为多少子样本集。
- 采用划分后样本集的不确定性作为划分好坏的标准,用信息增益度量不确定性。
- 每个非叶节点选择信息增益最大的属性作为测试属性,得到最小的决策树。
import pandas as pd
filename='./data/sales_data.xls'
data=pd.read_excel(filename,index_col=u'序号')
data[data==u"好"]=1
data[data==u"是"]=1
data[data==u"高"]=1
data[data!=1]=-1
x=data.iloc[:,:3].astype(int)
y=data.iloc[:,3].astype(int)
from sklearn.tree import DecisionTreeClassifier as DTC
dtc=DTC(criterion='entropy')
dtc.fit(x,y)
from sklearn.tree import export_graphviz
with open('tree.dot', 'w') as f:
f = export_graphviz(dtc, feature_names=x.columns, out_file=f)
5.1.3 人工神经网络
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
model=Sequential()
model.add(Dense(input_dim=3, units=10))
model.add(Activation('relu'))
model.add(Dense(input_dim=10, units=1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam')
model.fit(x, y, nb_epoch = 100, batch_size = 10)
yp = model.predict_classes(x).reshape(len(y))
5.2 聚类分析
- 聚类是在没有给定划分类别的情况下,根据数据相似度进行样本分组的方法。
- 聚类模型可以建立在无类标记的数据上,是非监督学习。
- 聚类划分原则:组内距离最小化,组间距离最大化。
5.2.1 K-Means
- 对于连续属性,要先对各属性进行零-均值规范。
- 使用误差平方和SSE作为度量聚类质量的目标函数。
import pandas as pd
inputfile = './data/consumption_data.xls'
k = 3
iteration = 500
data = pd.read_excel(inputfile, index_col='Id')
data_zs = 1.0 * (data - data.mean()) / data.std()
from sklearn.cluster import KMeans
model = KMeans(n_clusters=k, n_jobs=4, max_iter=iteration)
model.fit(data_zs)
r1 = pd.Series(model.labels_).value_counts()
r2 = pd.DataFrame(model.cluster_centers_)
r = pd.concat([r2, r1], axis=1)
r.columns = list(data.columns) + [u'类别数目']
print(r)
r = pd.concat([data, pd.Series(model.labels_, index=data.index)], axis=1)
r.columns = list(data.columns) + [u'聚类类别']
r
TSNE提供有效数据降维方式,能在2维或3维空间中展示聚类结果。
from sklearn.manifold import TSNE
tsne = TSNE(random_state=0)
tsne.fit_transform(data_zs)
tsne = pd.DataFrame(tsne.embedding_, index=data_zs.index)
plt.figure()
d = tsne[r[u'聚类类别'] == 0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚类类别'] == 1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚类类别'] == 2]
plt.plot(d[0], d[1], 'b*')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9C7ue8m-1630063913274)(C:\Users\86139\AppData\Roaming\Typora\typora-user-images\image-20210827111149254.png)]
5.3 关联规则
5.3.1 Apriori
from __future__ import print_function
import pandas as pd
inputfile = r'.\data\menu_orders.xls'
outputfile = r'.\data\apriori_rules.xls'
data = pd.read_excel(inputfile, header=None)
print(data)
print(u'\n转换原始数据至0-1矩阵...')
ct = lambda x: pd.Series(1, index=x[pd.notnull(x)])
b = list(map(ct, data.values))
data = pd.DataFrame(b).fillna(0)
print(u'\n转换完毕.')
print(data)
print(data.sum(),len(data))
del b
support = 0.2
confidence = 0.5
ms = '---'
find_rule(data,support,confidence,ms).to_excel(outputfile)
5.4 时序模式
5.4.1 预处理
-
拿到一个观察值序列,首先进行纯随机性和平稳性检验,将序列分为不同类型后采用不同的分析方法:
- 白噪声序列:无分析价值。
- 平稳非白噪声序列:AR、MA、ARMA进行拟合。
- 非平稳序列:转变为平稳序列进行分析。若经差分运算后具有平稳性(差分平稳序列),可使用ARIMA模 型。
差分法:时间序列在t与t-1时刻的差值。 -
平稳性检验:
- 时序图检验
- 自相关ACF图、偏自相关PACF图检验
- 单位根检验:选取标准为0.05,大于0.05则认为非平稳
- 平稳性:
- 要求经由样本时间序列所得到的拟合曲线在未来的一段时间内仍能顺着现有的形态“惯性”地延续下去。
- 平稳性要求序列的均值和方差不发生明显变化。
- 模型
- 自回归模型(AR):
- 描述当前值与历史值之间的关系,用变量自身的历史时间数据对自身进行预测。
- 限制:
- 用自身数据来进行预测。
- 必须满足平稳性的要求。
- 必须具有相关性,如果相关系数小于0.5,则不宜采用。
- 只适用于预测与自身前期相关的现象。
- 移动平均模型(MA):
- 关注的是自回归模型中的误差项的累加,不考虑历史数据的影响。
- 移动平均法能有效消除预测中的随机波动。
- 自回归移动平均(ARMA)
- 差分自回归移动平均模型(ARIMA):
- AR是自回归,p为自回归项;MA为移动平均,q为移动平均项数,d为时间序列成为平稳时所做的差分次数。
- 原理:将非平稳时间序列转化为平稳时间序列然后将因变量仅对它的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型。
- 相关函数评估方法:
- 自相关函数ACF:
- 有序的随机变量序列与其自身相比较。
- 自相关系数反映了同一序列在不同时序取值之间的相关性。
- 偏自相关函数(PACF):
- ACF还包含了其他变量的影响,而偏自相关系数PACF是严格这两个变量之间的相关性。
- ARIMA(p,d,q)阶数确定:
模型 | ACF | PACF |
---|
AR§ | 衰减趋于零(几何型或振荡型) | p阶后截尾 | MA(q) | q阶后截尾 | 衰减趋于零(几何型或振荡型) | ARMA(p,q) | q阶后衰减趋于零(几何型或振荡型) | p阶衰减趋于零(几何型或振荡型) |
截尾:落在置信区间内(95%的点都符合规则)
5.4.2 ARIMA
ARIMA建模流程:
- 将序列平稳(差分法确定d)
- 白噪声检验
- 计算ACF、PACF
- 模型识别
- 参数估计
- 模型检验
- 模型优化
- 模型预测
import pandas as pd
discfile = './data/arima_data.xls'
forecastnum = 5
data = pd.read_excel(discfile, index_col=u'日期')
data.head(3)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
data.plot()
plt.show()
D_data = data.diff().dropna()
D_data.columns = [u'销量差分']
D_data.plot()
plot_acf(D_data)
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(D_data,lags=12)
plot_pacf(D_data)
print(u'差分序列的ADF检验结果为:',ADF(D_data[u'销量差分']))
from statsmodels.stats.diagnostic import acorr_ljungbox
print(u'差分序列的白噪声检验结果为:', acorr_ljungbox(D_data, lags=1))
from statsmodels.tsa.arima_model import ARIMA
pmax = int(len(data)/10)
qmax = int(len(data)/10)
bic_matrix = []
for p in range(pmax+1):
tmp = []
for q in range(qmax+1):
try:
tmp.append(ARIMA(data, (p,1,q)).fit().bic)
except:
tmp.append(None)
bic_matrix.append(tmp)
print(bic_matrix)
from statsmodels.tsa.arima_model import ARIMA
data['销量'] = data['销量'].astype(float)
pmax = int(len(D_data) / 10)
qmax = int(len(D_data) / 10)
bic_matrix = []
for p in range(pmax + 1):
tmp = []
for q in range(qmax + 1):
try:
tmp.append(ARIMA(data, (p, 1, q)).fit().bic)
except:
tmp.append(None)
bic_matrix.append(tmp)
bic_matrix = pd.DataFrame(bic_matrix)
p, q = bic_matrix.stack().idxmin()
print(u'BIC最小的p值和q值为:%s、%s' % (p, q))
model = ARIMA(data, (p, 1, q)).fit()
model.summary2()
model.forecast(5)
预测结果4873.9665477在置信区间[4730.72112437, 5017.21197102]内,预测结果是较为准确的。
5.5 离散点检测
也称为偏差检测,广泛应用于电信和信用卡的诈骗检测、贷款审批、电子商务、网络入侵和天气预报等领域。
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
inputfile = r'.\data\consumption_data.xls'
k = 3
threshold = 2
iteration = 500
readExcel = pd.ExcelFile(inputfile)
data = pd.read_excel(readExcel,index_col='Id')
data_zs = 1.0*(data-data.mean(axis=0))/data.std(axis=0)
model = KMeans(n_clusters=k,n_jobs=4,max_iter=iteration)
model.fit(data_zs)
r = pd.concat([data_zs,pd.Series(model.labels_,index=data.index)],axis = 1)
r.columns = list(data.columns) + [u'聚类类别']
norm =[]
for i in range(k):
norm_tmp = r[['R','F','M']][r[u'聚类类别'] == i]-model.cluster_centers_[i]
norm_tmp = norm_tmp.apply(np.linalg.norm,axis=1)
norm.append(norm_tmp/norm_tmp.median())
norm = pd.concat(norm)
norm[norm <= threshold].plot(style = 'go' )
discrete_points = norm[norm>threshold]
discrete_points.plot(style='ro')
for i in range(len(discrete_points)):
id = discrete_points.index[i]
n = discrete_points.iloc[i]
plt.annotate('(%s , %0.2f)'%(id,n),xy = (id,n),xytext = (id,n))
plt.xlabel(u'编号')
plt.ylabel(u'相对距离')
plt.show()
|