目录
一、异常检测
1.1可以用到的案例
- 欺诈检测:盗刷信用卡检测
- 入侵检测:检测网络入侵或计算机入侵行为
- 医疗:缺陷基因检测
- 生态系统:预测飓风、洪水、干旱、热浪和火灾的发生
1.2监督式异常检测
- 提前使用带“正常”与“异常”标签的数据对模型进行训练,机器基于训练好的模型判断新数据是否为异常数据
1.3无监督式异常检测
- 通过寻找与其他数据最不匹配的实例来检测出未标记测试数据的异常
1.4定义
- 基于数据分布,寻找与其他数据最不匹配的实例
- 寻找发生可能性比较低的事件
二、概率密度函数
- 在连续分布事件中,用于描述连续随机变量的输出值在某个确定的取值点附近的可能性的函数,通过其可计算取值点附近区间发生事件的概率
2.1基于高斯分布的概率密度函数
- 现实生活中,很多事件发生的频率都符合高斯分布,比如:工业产品的强力、抗压强度、口径、长度等指标;人体的身高、体重等指标;同一品种种子的重量;某个地区的年降水量,等等
2.2基于高斯分布概率密度函数实现异常检测
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))
三、数据降维
3.1问题
- 想建立一个AI模型,筛选金融股票,潜在数据指标:价格、交易量、换手率、股东人数、最近N日涨跌幅、RSI指标、市值、营业额、净利润、负债率、利润增长率…多达几百\上千个因子
- 两大问题:求解困难、模型过拟合
3.2定义
- 在一定的限定条件下,按照一定的规则,尽可能保留原始数据集重要信息的同时,降低数据集特征的个数
3.3为什么需要数据降维
- 维数灾难:随着特征数量越来越多,为了避免过拟合,对样本数量的需求会以指数速度增长
- 数据可视化:高维数据不能可视化,只有降低到二维或三维才能可视化
- 3D数据降维到2D数据
四、数据降维最常用的方法——主成分分析(PCA)
- 也称主分量分析,按照一定规则把数据变换到一个新的坐标系统中,使得任何数据投影后尽可能可以分开(新数据尽可能不相关,分布方差最大化)。
- 核心:投影后的数据尽可能分得开(即不相关)
4.1PCA的实现
- 使投影后数据得方差最大,因为方差越大数据也越分散
- 数据预处理(数据分布标准化:μ=0,α=1)
- 计算协方差矩阵特征向量、及数据在各特征向量投影后的方差
- 根据需求(任务指定或方差比例)确定降维维度K
- 选取K维特征向量,计算数据在其形成空间得投影
#数据标准化处理,均值变为0,标准差变为1
from sklearn.preprocessing import StandardScaler
X_norm=StandardScaler().fit_transform(X)
print(X_norm)
##数据降维到2维
from sklearn.decomposition import PCA
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_
print(var_ratio2)
五、任务
5.1任务一:异常消费行为检测:基于数据,基于高斯分布得概率密度函数实现异常消费行为检测
- 可视化消费数据、数据分布次数、及其对应高斯分布得概率密度函数
- 设置概率密度阈值0.03,建立模型,实现异常数据点预测
- 可视化异常检测处理结果
- 修改概率密度为0.1、0.2,查看阈值改变对结果得影响
- 修改概率密度阈值为0-0.2,以0.01为递增间隔,查看保存结果、生成动态gif图
# In[]
from matplotlib import pyplot as plt
import pandas as pd
import numpy as np
data=pd.read_csv('PCA_AnomalyPay.csv')
import matplotlib as mpl
mpl.rcParams['font.family']='SimHei'
# In[]
fig1=plt.figure(figsize=(8,6))
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x')
plt.title('原始数据')
plt.xlabel('频率')
plt.ylabel('消费')
plt.show()
x1=data.loc[:,'frequency']
x2=data.loc[:,'payment']
# In[]
#数据分布的可视化操作
fig2=plt.figure(figsize=(20,5))
fig2_1=plt.subplot(121)
plt.hist(x1,bins=100) #频次图,bins划分成多少块
plt.title('频率数据')
plt.xlabel('频率')
plt.ylabel('统计')
fig2_2=plt.subplot(122)
plt.hist(x2,bins=100) #频次图,bins划分成多少块
plt.title('消费数据')
plt.xlabel('消费')
plt.ylabel('统计')
plt.show()
x1_mean=x1.mean()
x1_sigma=x1.std()
#计算数据均值、标准差
x2_mean=x2.mean()
x2_sigma=x2.std()
print(x1_mean,x1_sigma,x2_mean,x2_sigma)
# In[]
#计算对应得高斯分布数值
#norm正态分布模块
from scipy.stats import norm
x1_range=np.linspace(0,10,300) #0-10,300个点
x1_normal1=norm.pdf(x1_range,x1_mean,x1_sigma)
#生成曲线
x2_range=np.linspace(0,400,300)
x2_normal1=norm.pdf(x2_range,x2_mean,x2_sigma)
# In[]
#原始数据的高斯分布概率密度函数可视化
fig3=plt.figure(figsize=(20,10))
plt3_1=plt.subplot(121)
plt.plot(x1_range,x2_normal1)
plt.title('x1频率高斯分布')
plt.xlabel('x1频率')
plt.ylabel('p(x1)')
plt3_2=plt.subplot(122)
plt.title('x2频率高斯分布')
plt.xlabel('x2消费')
plt.ylabel('p(x2)')
plt.plot(x2_range,x2_normal1)
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)
#meshgrid生成网格点坐标矩形
#展开矩阵数据
x_range = np.c_[xx.ravel(), yy.ravel()]
x1 = np.c_[xx.ravel()] #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])
# In[]
#3D高斯分布概率函数图形可视化
from matplotlib import cm
#上色
from mpl_toolkits.mplot3d import Axes3D
#3D模块
import matplotlib.pyplot as plt
fig5=plt.figure()
axes3d=Axes3D(fig5)
axes3d.plot_surface(xx,yy,p_2d,cmap=cm.rainbow)
#cmpa:以彩虹色进行上色
#高斯模型的建立和训练
from sklearn.covariance import EllipticEnvelope
ad_model=EllipticEnvelope(contamination=0.03)
#contamination:阈值
ad_model.fit(data)
# In[]
#模型预测
y_predict=ad_model.predict(data)
print(pd.value_counts(y_predict))
# In[]
#异常数据可视化
fig7=plt.figure(figsize=(8,6))
plt.scatter(data.loc[:,'frequency'][y_predict==-1],data.loc[:,'payment'][y_predict==-1],marker='o',facecolor='none',edgecolor='red',s=150,label='abnoraml data')
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x',label='raw data')
#空心的圆 facecolor='none'
plt.legend(loc='upper left')
#生成gif
x=np.linspace(0, 0.2,20)
for i in range(20):
from sklearn.covariance import EllipticEnvelope
ad_model=EllipticEnvelope(contamination=x[i])
#contamination:阈值
ad_model.fit(data)
y_predict=ad_model.predict(data)
fig7=plt.figure(figsize=(8,6))
plt.scatter(data.loc[:,'frequency'][y_predict==-1],data.loc[:,'payment'][y_predict==-1],marker='o',facecolor='none',edgecolor='red',s=150,label='abnoraml data')
plt.scatter(data.loc[:,'frequency'],data.loc[:,'payment'],marker='x',label='raw data')
plt.title('阈值为{}'.format(x[i]))
plt.legend(loc='upper left')
plt.savefig('阈值{}.png'.format(i))
# In[]
import imageio
def create_gif(image_list, gif_name, duration=0.35):
frames = []
for image_name in image_list:
frames.append(imageio.imread(image_name))
imageio.mimsave(gif_name, frames, 'GIF', duration=duration)
return
def main():
image_list = ['阈值0.png', '阈值1.png', '阈值2.png', '阈值3.png', '阈值4.png', '阈值5.png', '阈值6.png', '阈值7.png', '阈值8.png', '阈值9.png', '阈值10.png', '阈值11.png', '阈值12.png', '阈值13.png', '阈值14.png', '阈值15.png', '阈值16.png', '阈值17.png', '阈值18.png', '阈值19.png']
gif_name = '异常数据检测.gif'
duration = 0.35
create_gif(image_list, gif_name, duration)
if __name__ == '__main__':
main()
5.2任务二:基于数据,结合PCA降维技术与逻辑回归预测检查者患病情况
- 对于原数据建立逻辑回归模型,计算模型预测准确性
- 对数据进行标准化处理,选取glucose维度数据可视化处理后的效果
- 进行与原数据等维度PCA,查看各主成分的方差比例
- 保留2个主成分,可视化降维后的数据
- 基于降维后数据建立逻辑回归模型,与原数据表现进行对比,思考结果变化原因
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family']='SimHei'
data=pd.read_csv('PCA_diabetes.csv')
# In[]
X=data.drop(['label'],axis=1)
y=data.loc[:,'label']
# In[]
#逻辑回归预测
from sklearn.linear_model import LogisticRegression
model1=LogisticRegression(max_iter=1000)
model1.fit(X,y)
# In[]
y_predict=model1.predict(X)
print(y_predict)
# In[]
#模型评估
from sklearn.metrics import accuracy_score
accuracy=accuracy_score(y,y_predict)
print(accuracy)
#数据标准化处理,均值变为0,标准差变为1
from sklearn.preprocessing import StandardScaler
X_norm=StandardScaler().fit_transform(X)
print(X_norm)
# In[]计算均值与标准差
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()
print(x1_mean,x1_norm_mean,x1_sigma,x1_norm_sigma)
# In[]
fig1=plt.figure(figsize=(12,5))
fig1_1=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分析
from sklearn.decomposition import PCA
pca=PCA(n_components=8)
X_pca=pca.fit_transform(X_norm)
print(X_pca.shape)
#计算分析后各成分的方差以及方差比例
var=pca.explained_variance_
var_ratio=pca.explained_variance_ratio_
print(var) #方差
print(var_ratio) #方差比例
print(sum(var_ratio))
#可视化方差比例
fig1=plt.figure(figsize=(20,5))
plt.bar([1,2,3,4,5,6,7,8],var_ratio)
#plt.bar条形图
plt.xticks([1,2,3,4,5,6,7,8],['PC1','PC2','PC3','PC4','PC5','PC6','PC7','PC8'])
plt.ylabel('variance ratio of each PC')
plt.show()
#数据降维到2维
from sklearn.decomposition import PCA
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_
print(var_ratio2)
# In[]
#可视化降维后的数据
negative=plt.scatter(X_pca[:,0][y==0],X_pca[:,1][y==0],c='r',marker='x',label='negative')
positive=plt.scatter(X_pca[:,0][y==1],X_pca[:,1][y==1],marker='*',label='positive')
plt.legend()
plt.show()
# In[]
#降维后逻辑回归预测
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)