一、绘图判断
根据画图就能判断是否相关。
包括散点线性图、散点图、折线图
二、计算方差
计算特征的方差,如果方差接近于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相关系数仍然是不可替代的。
- Pearson相关系数计算速度快;
- Pearson相关系数的取值区间是[-1,1],MIC和距离相关系数都是[0,1]。Pearson相关系数能够表示负相关,但MIC和距离相关系数不能表示负相关。
如何计算距离相关系数?
- 计算数组间每行数据之间的范数距离,假设有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=∣∣Xj−Xk∣∣,bjk=∣∣Yj−Yk∣∣
#生成一个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
- 中心化处理所有的成对距离
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=ajk−aˉj⋅−aˉ⋅k+aˉ..Bjk=bjk−bˉj⋅−bˉ⋅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()
- 计算样本距离的平方协方差(标量)的算数平均:
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=1∑nk=1∑nAjkBjk
cov_xy=np.sqrt((1/(col**2))((AB).sum()))
- 计算样本距离方差
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=1∑nk=1∑nAjk2
cov_xx=np.sqrt((1/(col2))((AA).sum()))
cov_yy=np.sqrt((1/(col2))((BB).sum()))
- 将两个特征的距离协方差除以它们的距离标准差的乘积,得到它们的距离相关性
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)