特征相关性分析

一、绘图判断

根据画图就能判断是否相关。
包括散点线性图、散点图、折线图

二、计算方差

计算特征的方差,如果方差接近于0,也就是该特征的特征值之间基本上没有差异,说明这个特征对于样本的区分没什么用,可以剔除。

from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.1)#默认threshold=0.0
selector.fit_transform(offline_data_shuffle1[numerical_features])
 
# 查看各个特征的方差,
selector.variances_ ,len(selector.variances_)
 
# 特征对应方差
all_used_features_dict = dict(zip(numerical_features,selector.variances_ ))
all_used_features_dict

sklearn.feature_selection.VarianceThreshold类使用方法

三、协方差

计算两个特征的协方差,
如果协方差为正,说明两个特征正相关,协方差越大说明相关程度越高;
如果协方差为负,说明两个特征负相关,协方差越小说明相关程度越高;
如果协方差为0,说明两个特征相互独立,不相关。

四、Pearson皮尔逊相关系数

相关系数:相当于剔除了两个特征量纲影响、标准化后的特殊协方差。

Pearson系数适用条件:

  • 两个特征之间是线性关系,都是连续数据。
  • 两个特征总体是正态分布,或接近正态的单峰分布。
  • 两个特征的观测值是成对的,每对观测值之间相互独立。

Pearson系数特性:

  • 可以反映两个特征是正相关还是负相关;
  • 它是标准化后的协方差,消除了两个特征量纲的影响,只是单纯反应两个变量每单位变化时的相似程度。

Pearson系数相关程度分类:

  • 0.8-1.0 极强相关;
  • 0.6-0.8 强相关;
  • 0.4-0.6 中等程度相关;
  • 0.2-0.4 弱相关;
  • 0.0-0.2 极弱相关或无相关。
  • 如果>0.8,说明2个特征有明显线性关系,只保留一个就可以了。一般保留与label的皮尔逊系数较大的那个或 lightgbm AUC 最大的那个。
皮尔逊系数相关程度分类。
.00-.19 “very weak”
.20-.39 “weak”
.40-.59 “moderate”
.60-.79 “strong”
.80-1.0 “very strong”

Pearson系数缺点

  • 无法利用这种关系对数据进行预测,即没有对变量间的关系进行提炼和固化,形成模型。要利用变量间的关系进行预测,需要使用回归分析。

Pearson系数样例代码1:

# 方法1,numpy.corrcoef,求多个数组的相关系数
import numpy as np
np.corrcoef([a,b,c,d])
 
# 方法2.计算特征间的pearson相关系数,画heatmap图
plt.figure(figsize = (25,25))
corr_values1 = data[all_used_features].corr() # pandas直接调用corr就能计算特征之间的相关系数
sns.heatmap(corr_values1, annot=True,vmax=1, square=True, cmap="Blues",fmt='.2f')
plt.tight_layout()
# plt.savefig('prepare_data/columns37.png',dpi=600)
plt.show()
 
# 方法3.Scipy的pearsonr方法能够同时计算相关系数和p-value
import numpy as np
from scipy.stats import pearsonr
 
np.random.seed(0)
size = 300
x = np.random.normal(0, 1, size)
print("Lower noise", pearsonr(x, x + np.random.normal(0, 1, size)))
print("Higher noise", pearsonr(x, x + np.random.normal(0, 10, size)))

Pearson系数样例代码2:

# 计算各特征与label的相关系数,并画出直方图
x_cols = [col for col in train_csv.columns if col not in ['信用分'] if train_csv[col].dtype!='object']#处理目标的其他所有特征
labels = []
values = []
for col in x_cols:
    labels.append(col)
    values.append(np.corrcoef(train_csv[col].values, train_csv.信用分,values)[0, 1])
 
corr_df = pd.DataFrame({
    
    'col_labels':labels, 'corr_values':values})
corr_df = corr_df.sort_values(by = 'corr_values')
 
ind = np.arange(len(labels))
width = 0.5
fig,ax = plt.subplots(figsize = (12,40))
rects = ax.barh(ind, np.array(corr_df.corr_values.values), color='y')
 
ax.set_yticks(ind)
ax.set_yticklabels(corr_df.col_labels.values, rotation='horizontal')
ax.set_xlabel('Correlation coefficient')
ax.set_title('Correlation coefficient of the variables')

五、距离相关系数

有时候即便Pearson相关系数是 0,也不能断定这两个特征是独立的(有可能是非线性相关);为了克服Pearson相关系数这个弱点,就有了距离相关系数。如果距离相关系数是 0,那么这两个特征就是独立的。

注意:
当特征之间的关系接近线性相关时,Pearson相关系数仍然是不可替代的。

  1. Pearson相关系数计算速度快;
  2. Pearson相关系数的取值区间是[-1,1],MIC和距离相关系数都是[0,1]。Pearson相关系数能够表示负相关,但MIC和距离相关系数不能表示负相关。

如何计算距离相关系数?

  1. 计算数组间每行数据之间的范数距离,假设有n维(X,Y)统计样本
    a j k = ∣ ∣ X j − X k ∣ ∣ , b j k = ∣ ∣ Y j − Y k ∣ ∣ a_{jk}=||X_j-X_k|| ,b_{jk}=||Y_j-Y_k|| ajk=∣∣XjXk∣∣,bjk=∣∣YjYk∣∣
#生成一个3行2列的数组
X = np.random.randint(-100,100,(3,2))0.1
out:
array([[ 4.8, 7.7],
[-2.6, 6.8],
[ 5.9, 9. ]])
Y = X**2
#取数据集的行
col = X.shape[0]
#做成nn的零矩阵,用于盛放数据
a = np.zeros((col,col))
b = np.zeros((col,col))
A = np.zeros((col,col))
B = np.zeros((col,col))
#计算数组间每行数据之间的范数距离
for j in range(col):
    for k in range(col):
        a[j,k] = np.linalg.norm(X[j]-X[k])
        b[j,k] = np.linalg.norm(Y[j]-Y[k])
        # 这里的a和b最后生成的都是对称矩阵
部分打印信息:
X数据集索引为0的数据与索引为0的数据的范数距离为0
计算a列之间的距离: 0.0
计算b列之间的距离: 0.0
X数据集索引为0的数据与索引为1的数据的范数距离为
计算a列之间的距离: 8.174350127074325
计算b列之间的距离: 25.112168365157167
  1. 中心化处理所有的成对距离
    A j k = a j k − a ˉ j ⋅ − a ˉ ⋅ k + a ˉ . . B j k = b j k − b ˉ j ⋅ − b ˉ ⋅ k + b ˉ . . A_{jk}=a_{jk}-\bar a_{j\cdot}-\bar a_{\cdot k}+\bar a.. \\ B_{jk}=b_{jk}-\bar b_{j\cdot}-\bar b_{\cdot k}+\bar b.. Ajk=ajkaˉjaˉk+aˉ..Bjk=bjkbˉjbˉk+bˉ..
    其中, a ˉ j ⋅ \bar a_{j\cdot} aˉj是第 j 行平均值, a ˉ ⋅ k \bar a_{\cdot k} aˉk是第 k 列平均值, a ˉ . . \bar a.. aˉ..是 X 样本的距离矩阵的平均值。
for m in range(col):
    for n in range(col):
        #计算a,b中心化的值,并赋值给A,B
        A[m,n] = a[m,n] - a[m].mean()-a[:,n].mean()+a.mean()
        B[m,n] = b[m,n] - a[m].mean()-b[:,n].mean()+b.mean()
  1. 计算样本距离的平方协方差(标量)的算数平均:
    d C o v n 2 ( X , Y ) : = 1 n 2 ∑ j = 1 n ∑ k = 1 n A j k B j k dCov_n^2(X,Y):=\frac{1}{n^2}\sum_{j=1}^{n}\sum_{k=1}^{n}A_{jk}B_{jk} dCovn2(X,Y):=n21j=1nk=1nAjkBjk
cov_xy=np.sqrt((1/(col**2))((AB).sum()))
  1. 计算样本距离方差
    d V a r n 2 ( X ) : = d C o v n 2 ( X , X ) = 1 n 2 ∑ j = 1 n ∑ k = 1 n A j k 2 dVar_n^2(X):=dCov_n^2(X,X)=\frac{1}{n^2}\sum_{j=1}^{n}\sum_{k=1}^{n}A_{jk}^2 dVarn2(X):=dCovn2(X,X)=n21j=1nk=1nAjk2
cov_xx=np.sqrt((1/(col2))((AA).sum()))
cov_yy=np.sqrt((1/(col2))((BB).sum()))
  1. 将两个特征的距离协方差除以它们的距离标准差的乘积,得到它们的距离相关性
    d C o r ( X , Y ) = d C o v ( X , Y ) d V a r ( X ) d V a r ( Y ) dCor(X,Y)=\frac{dCov(X,Y)}{\sqrt{dVar(X)dVar(Y)}} dCor(X,Y)=dVar(X)dVar(Y) dCov(X,Y)
dcor = cov_xy/np.sqrt(cov_xx*cov_yy)

计算距离相关系数的完整代码如下:

import numpy as np
import pandas as pd
def dist_corr(x,y):#如果x,y是二维数组,应通过行矢量形成距离矩阵
    #获取数据集的行
    col=x.shape[0]
    #生成a、b、A、B三个colcol的0矩阵
    a=np.zeros((col,col))
    b=np.zeros((col,col))
    A=np.zeros((col,col))
    B=np.zeros((col,col))
    #通过双层循环计算出列之间的范数距离
    for j in range(col):
        for k in range(col):
            #求范数
            a[j,k]=linalg.norm(x[j]-x[k])
            b[j,k]=linalg.norm(y[j]-y[k])
            #print(a,b)
    #通过循环对其进行中心化处理
    for m in range(col):
        for n in range(col):
            A[m,n]=a[m,n]-a[m].mean()-a[:,n].mean()+a.mean()
            B[m,n]=b[m,n]-b[m].mean()-b[:,n].mean()+b.mean()
    #求协方差
    cov_xy=np.sqrt((1/(col**2))((AB).sum()))
    cov_xx=np.sqrt((1/(col**2))((AA).sum()))
    cov_yy=np.sqrt((1/(col**2))((BB).sum()))
return cov_xy/np.sqrt(cov_xxcov_yy)

未完待续。。。

猜你喜欢

转载自blog.csdn.net/weixin_46838605/article/details/126590215
今日推荐