线性回归
线性回归是统计学中一个重要的应用,这个重要的应用往往是指通过一系列自变量去预测一个特殊因变量的值。在这种情况下,异常值是根据其他自变量对因变量的影响来定义的,而自变量之间相互关系中的异常则不那么重要。这里的异常点检测主要用于数据降噪,避免异常点的出现对模型性能的影响,因而这里关注的兴趣点主要是正常值(n)。
而我们通常所说的异常检测中并不会对任何变量给与特殊对待,异常值的定义是基于基础数据点的整体分布,这里我们关注的兴趣点主要是异常值(o)。
广义的回归建模只是一种工具,这种工具既可以用来进行数据降噪也可以进行异常点检测。
关于求解 线性回归 总共有两种方式 一种是最小二乘法 另外一种为梯度下降
将样本的协方差矩阵特征值分解以后,特征值就是样本投影到这个轴上后对应的方差,特征值越小,说明投影以后在这个轴上样本点分布集中,而异常点在这种情况下更容易偏移,利用这一点可以作为衡量样本异常的一个指标。在PCA做降维的时候,起作用的是大的特征值对应的特征向量,而在异常检测中,起作用的是特征值小的对应的特征向量。
根据以上思想,我们可以定义PCA中一个点x bar的异常评分
其中,e i 为第i个特征向量, λ i 为沿该方向的方差(也是特征值),可以看出,对异常得分的大部分贡献是由λ值较小的主成分的提供的
## PCA for stock return data
# covx taken from chapter 2
## real data example
## step 1 / full index
import numpy as np
import numpy.linalg as la
import pandas as pd
import os
import matplotlib.pyplot as plt
index_path = r'D:\hot\book\data\SZ399300.TXT'
index300 = pd.read_table(index_path,\
encoding = 'cp936',header = None)
idx = index300[:-1]
idx.columns = ['date','o','h','l','c','v','to']
idx.index = idx['date']
## step 2 / data preparation
stock_path = r'D:\hot\book\data\hs300-2\hs300'
names = os.listdir(stock_path)
close = []
for name in names:
spath = stock_path + '\\' + name
df0 = pd.read_table(spath,\
encoding = 'cp936',header = None)
df1 = df0[:-1]
df1.columns = ['date','o','h','l','c','v','to']
df1.index = df1['date']
df2 = df1.reindex(idx.index,method = 'ffill')
df3 = df2.fillna(method = 'bfill')
close.append(df3['c'].values)
data = np.asarray(close).T
retx = (data[1:,:]-data[:-1,:])/data[:-1,:]
covx = np.cov(retx.T)
u,v = la.eig(covx)
## second pc
id = v[:,1].argsort()[-10:]
sector1 = [names[a] for a in id] # finance sector
id = v[:,1].argsort()[:10]
sector2 = [names[a] for a in id] # media and high tech sector
cname_path = 'D:/hot/book/data/A_share_name.xlsx'
namesheet = pd.read_excel(cname_path,'Sheet1',encoding = 'gbk')
cepair = namesheet.values
cname = []
for ecode in sector2: # or in sector2
ecodex = ecode[2:-4]
id = cepair[:,0] == int(ecodex)
cname.append(cepair[id,1][0])
## pca for transposed data
covx2 = np.cov(retx)
ux,vx = la.eig(covx2)
mux = np.mean(retx.T,axis = 0) # market/mean return
xi1 = (retx.T - mux).dot(vx[:,0])
id2 = xi1.argsort()[-10:]
sector1v = [names[a] for a in id2] # finance sector
cname = []
for ecode in sector1v: # or in sector2
ecodex = ecode[2:-4]
id = cepair[:,0] == int(ecodex)
cname.append(cepair[id,1][0])
cname