Python入门到实战(十二)异常检测、数据降维、异常消费行为检测、糖尿病预测分析
- 异常检测
- 监督式异常检测:
- 无监督式异常检测:
- 概率
- 概率密度函数
- 基于高斯分布(正态分布)的概率密度函数
- 基于高斯分布的概率密度函数实现异常检测(单一维度)
- 高维度数据集
- 数据降维
- 为什么要数据降维?
- Curse of dimensionality-维数灾难
- 数据可视化
- PCA主成分分析
- 实战部分
- 异常消费行为检测
- 数据加载和展示
- 数据分布可视化
- 综合高斯分布概率密度函数的可视化
- 建模和预测
- 皮马印第安人糖尿病预测分析
- 建立逻辑回归模型预测模型准确率
- 数据标准化处理及分布可视化
- PCA分析可视化方差比例
- 降维操作及降维后数据可视化
- 用降维后的数据进行逻辑回归训练,判断准确率
异常检测
监督式异常检测:
提前使用带有标签的数据训练模型,之后基于训练好的模型判断是否为异常数据
无监督式异常检测:
通过寻找与其他数据最不匹配的实例,从而检测出未标记测试数据的异常
概率
概率密度函数
连续分布事件中,用于描述连续随机变量的输出值在某个确定的取值点附近可能性的函数
可用于计算取值点附近区间发生时间的概率
基于高斯分布(正态分布)的概率密度函数
其中μ为数据均值,σ为标准差μ决定中间轴位置,σ为决定分布集中度
生活中许多事件发生概率都服从高斯分布
基于高斯分布的概率密度函数实现异常检测(单一维度)
STEP1:根据输入x,计算u和sigma
STEP2:根据计算出来的据μ、σ得到对应的高斯分布概率函数
STEP3:根据数据点概率密度进行判断
if p(x)<阈值ε
then 判断为异常点
高维度数据集
STEP1:根据输入x,计算u1,u2,u3…和差σ1, σ2,…,σn
STEP2:根据计算出来的据μ、σ计算概率密度函数
STEP3:根据数据点概率密度进行判断
if p(x)<阈值ε
then 判断为异常点
数据降维
为什么要数据降维?
Curse of dimensionality-维数灾难
现实应用场景中有大量维度的特征,为了避免过拟合,对样本数量的需求会以指数速度上涨
数据可视化
高维数据由于维数过多无法可视化,此时通过降到二维或三维才能可视化
PCA主成分分析
也称主分量分析,按照一定规则把数据变换到一个新的坐标系统中,使得任何数据投影后尽可能可以分开(新数据尽可能不相关、分布方差最大化)
计算过程:
- 数据预处理(数据分布标准化:μ =0,σ =1)
- 计算协方差矩阵特征向量、及数据在各特征向量投影后的方差
- 根据需求(任务指定或方差比例)确定降维维度k
- 选取k维特征向量,计算数据在其形成空间的投影
实战部分
异常消费行为检测
数据加载和展示
#数据输入
import pandas as pd
import numpy as np
data=pd.read_csv('PCA_task1_data.csv')
#数据可视化
from matplotlib import pyplot as plt
fig1=plt.figure()
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x')
plt.title('raw data')
plt.xlabel('frequency')
plt.ylabel('payment')
plt.show()
数据分布可视化
x=data
x1=data.loc[:,'frequency']
x2=data.loc[:,'payment']
#数据分布可视化操作
fig2=plt.figure(figsize=(20,5))
fig2_1=plt.subplot(121)#一行两列第一个图
plt.hist(x1,bins=100)#切成100份
plt.title('frequency data')
plt.xlabel('frequency')
plt.ylabel('counts')
fig2_1=plt.subplot(122)#一行两列第二个图
plt.hist(x2,bins=100)#切成100份
plt.title('payment data')
plt.xlabel('payment')
plt.ylabel('counts')
plt.show()
#计算平均u,和标准差sigma
x1_mean=x1.mean()
x1_sigma=x1.std()
x2_mean=x2.mean()
x2_sigma=x2.std()
#计算基于高斯分布的概率密度函数
from scipy.stats import norm
x1_range=np.linspace(0,10,300)
x1_normal=norm.pdf(x1_range,x1_mean,x1_sigma)
x2_range=np.linspace(0,400,300)
x2_normal=norm.pdf(x2_range,x2_mean,x2_sigma)
#原始数据的高斯分布概率密度函数可视化
fig3=plt.figure(figsize=(20,5))
fig3_1=plt.subplot(121)
plt.plot(x1_range,x1_normal)
plt.title('x1(frequency)Gaussiam Distribution')
plt.xlabel('x1(frequency)')
plt.ylabel('p(x1)')
fig3_2=plt.subplot(122)
plt.plot(x2_range,x2_normal)
plt.title('x2(payment)Gaussiam Distribution')
plt.xlabel('x2(payment)')
plt.ylabel('p(x2)')
plt.show()
综合高斯分布概率密度函数的可视化
import math
#设置范围
x_min, x_max = 0, 10
y_min, y_max = 0, 400
h1 = 0.1
h2 = 0.1
#生成矩阵数据
xx, yy = np.meshgrid(np.arange(x_min, x_max, h1), np.arange(y_min, y_max, h2))
print(xx.shape,yy.shape)
#展开矩阵数据
x_range = np.c_[xx.ravel(), yy.ravel()]
x1 = np.c_[xx.ravel()]
x2 = np.c_[yy.ravel()]
x_range_df = pd.DataFrame(x_range)
#x_range_df.to_csv('data.csv')
#高斯分布参数
u1 = x1_mean
u2 = x2_mean
sigma1 = x1_sigma
sigma2 = x2_sigma
#计算高斯分布概率
p1 = 1/sigma1/math.sqrt(2*math.pi)*np.exp(-np.power((x1-u1),2)/2/math.pow(sigma1,2))
p2 = 1/sigma2/math.sqrt(2*math.pi)*np.exp(-np.power((x2-u2),2)/2/math.pow(sigma2,2))
p = np.multiply(p1,p2)
#对概率密度维度转化
p_2d = p.reshape(xx.shape[0],xx.shape[1])
#综合高斯分布概率密度函数的可视化
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
fig5=plt.figure()
axes3d=Axes3D(fig5)
axes3d.plot_surface(xx,yy,p_2d,cmap=cm.rainbow)
(4000, 100) (4000, 100)
建模和预测
#建立异常检测模型
from sklearn.covariance import EllipticEnvelope
model=EllipticEnvelope(contamination=0.03)
model.fit(x)
#预测
y_predict=model.predict(x)
fig6=plt.figure()
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x',label='rawdata')
plt.scatter(data.loc[:,'frequency'][y_predict==-1],data.loc[:,'payment'][y_predict==-1],marker='o',facecolor='none',edgecolor='red',s=150,label='anomaly_data')
plt.title('raw data')
plt.xlabel('frequency')
plt.ylabel('payment')
plt.legend()
plt.show()
修改概率分布阈值为0.1,0.2:
model=EllipticEnvelope(cnotallow=0.1)
model=EllipticEnvelope(cnotallow=0.2)
结果可视化如下
皮马印第安人糖尿病预测分析
建立逻辑回归模型预测模型准确率
#基于数据结合PCA降维技术与逻辑回归预测检查者患病情况
import pandas as pd
import numpy as np
data=pd.read_csv('PCA_task2_data.csv')
#x,y赋值
x=data.drop(['label'],axis=1)
y=data.loc[:,'label']
#逻辑回归模型
from sklearn.linear_model import LogisticRegression
model1=LogisticRegression(max_iter=1000)#设置最大迭代次数
model1.fit(x,y)
#结果预测
y_predict=model1.predict(x)
#模型评估
from sklearn.metrics import accuracy_score
accuracy=accuracy_score(y,y_predict)
print(accuracy)
0.9183333333333333
数据标准化处理及分布可视化
#数据标准化/均值变为0,标准差变为1
from sklearn.preprocessing import StandardScaler
x_norm=StandardScaler().fit_transform(x)
#计算均值与标准差
x1_mean=x.loc[:,'glucose'].mean()
x1_norm_mean=x_norm[:,1].mean()
x1_sigma=x.loc[:,'glucose'].std()
x1_norm_sigma=x_norm[:,1].std()
from matplotlib import pyplot as plt
fig1=plt.figure(figsize=(12,5))
fig1_1=plt.subplot(121)
#plt.subplot(121)
plt.hist(x.loc[:,'glucose'],bins=100)
fig1_2=plt.subplot(122)
plt.hist(x_norm[:,1],bins=100)
plt.show()
PCA分析可视化方差比例
#pca分析
from sklearn.decomposition import PCA
pca=PCA(n_components=8)
x_pca=pca.fit_transform(x_norm)
#计算分析后各成分的方差以及方差比例
var=pca.explained_variance_
var_ratio=pca.explained_variance_ratio_
#可视化方差比例
fig2=plt.figure(figsize=(10,5))
plt.bar([1,2,3,4,5,6,7,8],var_ratio)
plt.show()
降维操作及降维后数据可视化
#数据降维到2维
pca=PCA(n_components=2)
x_pca=pca.fit_transform(x_norm)
print(x_pca.shape,x_norm.shape)
#计算方差比例
var_ratio2=pca.explained_variance_ratio_
#降维数据的可视化
fig3=plt.figure()
plt.scatter(x_pca[:,0][y==0],x_pca[:,1][y==0],marker='x',label='negative')
plt.scatter(x_pca[:,0][y==1],x_pca[:,1][y==1],marker='x',label='positive')
plt.legend()
plt.show()
用降维后的数据进行逻辑回归训练,判断准确率
#降维后的模型建立与训练
model2=LogisticRegression()
model2.fit(x_pca,y)
#模型预测
y_predict_pca=model2.predict(x_pca)
accuracy_pca=accuracy_score(y,y_predict_pca)
print(accuracy_pca)
0.8766666666666667
显而易见从8维降到2维,准确率仅从百分之91.8下降到百分之87.6、PCA降维过后的二维数据极大保留了原始数据的主要特征、同时大幅提升了模型训练的效率、是可以接受的