Y=aX+b
从解释变量
和被解释变量
看,Y是被X解释的变量。因此,X是解释变量,Y是被解释变量。
从自变量
和因变量
看,X是自身变量的量,Y是随着X变化而变化的量。因此,X是自变量,Y是因变量。
在进行线性回归分析时,容易出现自变量(解释变量)之间彼此相关的现象,我们称这种现象为多重共线性。
适度的多重共线性不成问题,但当出现严重共线性问题时,会导致分析结果不稳定,出现回归系数的符号与实际情况完全相反的情况。
本应该显著的自变量不显著,本不显著的自变量却呈现出显著性,这种情况下就需要消除多重共线性的影响。
多重共线性问题就是指一个解释变量的变化引起另一个解释变量的变化。
原本自变量应该是各自独立的,根据回归分析结果能得知:哪些因素对因变量Y有显著影响,哪些没有影响。
如果各个自变量x之间有很强的线性关系,就无法固定其他变量,也就找不到x和y之间真实的关系了。
除此以外,多重共线性的原因还可能包括:
有多种方法可以检测多重共线性,较常使用的是回归分析中的VIF——方差扩大因子(variance inflation factor)值,VIF值越大,多重共线性越严重。一般认为VIF大于10时(严格是5),代表模型存在严重的共线性问题。
有时候也会以容差值作为标准,容差值=1/VIF,所以容差值大于0.1则说明没有共线性(严格是大于0.2),VIF和容差值有逻辑对应关系,两个指标任选其一即可。
除此之外,
共线性会导致回归参数不稳定,即增加或删除一个样本点或特征,回归系数的估计值会发生很大变化。
这是因为某些解释变量之间存在高度相关的线性关系,XTX会接近于奇异矩阵,即使可以计算出其逆矩阵,逆矩阵对角线上的元素也会很大,这就意味着参数估计的标准误差较大,参数估计值的精度较低,这样,数据中的一个微小的变动都会导致回归系数的估计值发生很大变化。
总结共线性对线性模型影响:
多重共线性是普遍存在的,通常情况下,如果共线性情况不严重(VIF<5),不需要做特别的处理。如存在严重的多重共线性问题
,可以考虑使用以下几种方法处理
:
岭回归是一种改良的最小二乘法,其通过放弃最小二乘法的无偏性,以损失部分信息为代价来寻找效果稍差但回归系数更符合实际情况的模型方程。针对共线性的病态数据,岭回归的耐受性远强于普通线性最小二乘法回归。
其他方法:
对模型施加某些约束条件
将模型适当变形
差分法
时间序列数据、线性模型:将原模型变换为差分模型。
主成分分析(PCA)
简单相关系数检验法
变量聚类、方差膨胀因子vif、相关系数、L1 L2正则化:在特征比较多的时候,先变量聚类,每类中选择单特征比较强的,也可以根据1-r²小的选择有代表性的特征(r²表示的是其他变量能否线性解释的部分,1-r²表示的是容忍度,也就是其他变量不能解释的部分;变量聚类是多选一,因此需要选择一个具有代表性的变量,选择容忍度小的变量;另vif就是容忍度的倒数); 在变量聚类的步骤中也可以结合 方差膨胀因子、相关系数以及业务理解来筛选特征; vif选择多少合适(一般样本集在10w以上VIF>10就有严重的共线性问题了,样本集在10w以下,VIF>5也是严重的共线性问题。在小样本时,一般保证在2以下。当然,这也不能保证一定排除了,最后在检验下模型参数,判断是否仍旧存在共线性)
检验模型参数:
往往
不影响预测结果。(这个“往往不影响预测结果”结论小编自己觉得前提条件“拟合程度好”很重要,小编觉得可能还是有些许影响的,有查到一些论文《多重共线性的检验及对预测目标影响程度的定量分析 》)目前业界检验共线性最常用的方法是VIF检验。VIF越高,多重共线性的影响越严重。
两种方式,一种方式是直接掉包(https://zhuanlan.zhihu.com/p/56793236?utm_source=qq),另一种方式是自己写的函数,两个结果一致。
import pandas as pd
import numpy as np
#数据
df = pd.DataFrame([[15.9,16.4,19,19.1,18.8,20.4,22.7,26.5,28.1,27.6,26.3]
,[149.3,161.2,171.5,175.5,180.8,190.7,202.1,212.1,226.1,231.9,239]
,[4.2,4.1,3.1,3.1,1.1,2.2,2.1,5.6,5,5.1,0.7]
,[108.1,114.8,123.2,126.9,132.1,137.7,146,154.1,162.3,164.3,167.6]]).T
columns = ["var1","var2","var3","var4"]
df.columns=columns
#方式1:直接调包
#def_function
def calulate_vif(X):
from statsmodels.stats.outliers_influence import variance_inflation_factor
#✨✨✨务必注意✨✨✨,一定要加上常数项,#如果没有常数项列,计算结果天差地别,可能VIF等于好几千
X[X.shape[1]]=1
#vif
vif=[]
for i in range(X.shape[1]-1):
#计算第i+1个变量的(第i+1列)的方差膨胀因子
vif.append(variance_inflation_factor(X.values,i))
#result_out
yy=pd.DataFrame(X.columns[:-1,])
yy.rename(columns={0:"var_name"},inplace=True)
yy["vif"]=vif
print(yy)
#call
calulate_vif(df[["var1","var2","var3","var4"]])
#函数2:自定义函数,结果与调包的结果一致
#def_function
def calulate_vif2(x_data):
var_name=pd.DataFrame(x_data.columns)
var_name.rename(columns={0:"var_name"},inplace=True)
vif=[]
for i in range(x_data.shape[1]):
y=x_data.loc[:,x_data.columns[i]]
y.values.reshape(-1,1)
x=x_data.drop([x_data.columns[i]],axis=1)
x.values.reshape(-1,1)
model=linear.fit(x,y)
R_2=linear.score(x,y)
vif_re=1/(1-R_2)
vif.append(vif_re)
var_name["vif"]=vif
print(var_name)
#call
calulate_vif2(df[["var1","var2","var3","var4"]])
#生成数据集
df = pd.DataFrame([[15.9,16.4,19,19.1,18.8,20.4,22.7,26.5,28.1,27.6,26.3]
,[149.3,161.2,171.5,175.5,180.8,190.7,202.1,212.1,226.1,231.9,239]
,[4.2,4.1,3.1,3.1,1.1,2.2,2.1,5.6,5,5.1,0.7]
,[108.1,114.8,123.2,126.9,132.1,137.7,146,154.1,162.3,164.3,167.6]]).T
columns = ["var1","var2","var3","var4"]
df.columns=columns
def calulate_cor(cor_data):
# calculate pearson cor
coefficient1 =cor_data.corr(method = 'pearson')
print(coefficient1)
# Plot
plt.figure(figsize=(12,10), dpi= 80)
sns.heatmap(cor_data.corr(), xticklabels=cor_data.corr().columns, yticklabels=cor_data.corr().columns, cmap='RdYlGn', center=0, annot=True)
# Decorations
plt.title('Correlogram of mtcars', fontsize=22)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
calulate_cor(df[["var1","var2","var3","var4"]])
可能不是很好用
#生成数据集
df = pd.DataFrame([[15.9,16.4,19,19.1,18.8,20.4,22.7,26.5,28.1,27.6,26.3]
,[149.3,161.2,171.5,175.5,180.8,190.7,202.1,212.1,226.1,231.9,239]
,[4.2,4.1,3.1,3.1,1.1,2.2,2.1,5.6,5,5.1,0.7]
,[108.1,114.8,123.2,126.9,132.1,137.7,146,154.1,162.3,164.3,167.6]]).T
columns = ["var1","var2","var3","var4"]
df.columns=columns
#方式一:
def var_cluster(clusterNum,cluster_data):
from scipy.cluster.vq import vq,kmeans,whiten
transed=whiten(np.array(cluster_data.T)) #归一化
transed
#cluster
model = kmeans(transed,clusterNum)
#cluster_result
result = vq(transed,model[0])[0]
result
#result_out
aa=pd.DataFrame(cluster_data.columns)
aa.rename(columns={0:"var_name"},inplace=True)
bb=pd.DataFrame(result)
bb.rename(columns={0:"cluster"},inplace=True)
var_cluster=pd.concat([aa,bb],axis=1)
var_cluster.sort_values(by=["cluster"],ascending=(True),inplace=True)
print(var_cluster)
#call
var_cluster(2,df[["var1","var2","var3","var4"]])
#方式二:
def var_cluster2(clusterNum,cluster_data):
import numpy as np
from sklearn.cluster import KMeans
#array
transed=np.array(cluster_data.T)
#model_fit
kmeans=KMeans(n_clusters=clusterNum).fit(transed)
pred=kmeans.predict(transed)
print(pred)
#result_out
aa=pd.DataFrame(cluster_data.columns)
aa.rename(columns={0:"var_name"},inplace=True)
bb=pd.DataFrame(pred)
bb.rename(columns={0:"cluster"},inplace=True)
var_cluster=pd.concat([aa,bb],axis=1)
var_cluster.sort_values(by=["cluster"],ascending=(True),inplace=True)
print(var_cluster)
#call
var_cluster2(2,df[["var1","var2","var3","var4"]])
参考:
参考:https://zhuanlan.zhihu.com/p/88025370
太多相关度很高的特征并没有提供太多的信息量,并没有提高数据可以达到的上限,相反,数据集拥有更多的特征意味着更容易收到噪声的影响,更容易收到特征偏移的影响等等。
简单举个例子:
N个特征全都不受到到内在或者外在因素干扰的概率为k,则2N个特征全部不受到内在或外在因素干扰的概率必然远小于k。这个问题实际上对于各类算法都存在着一定的不良影响。
逻辑回归的梯度更新公式用代码表示为:
weights = weights - alpha * dataMatrix.transpose()* error
其中alpha
为学习率,dataMatrix.transpose()
为原始数据的矩阵,error=y_pred-y_true
。
从这里可以看出,共线性问题对于逻辑回归损失函数的最优化没影响,参数都是一样更新,一样更新到收敛为止。所以对于预测来说没什么影响。
那共线性会引发的问题:
其实多重共线性这样理解会简单很多:
> 假设原始的线性回归公式为:y=w1*x1+w2*x2+w3*x3
> 训练完毕的线性回归公式为:y=5x1+7x2+10x3
> 此时加入一个新特征x4,假设x4和x3高度相关,x4=2x3,则:
> y=w1*x1+w2*x2+w3*x3+w4*x4=w1*x1+w2*x2+(w3+2w4)*x3
> 因为我们之前拟合出来的最优的回归方程为:y=5x1+7x2+10x3
> 显然w3+2w4可以合并成一个新的权重稀疏 w5,则:y=w1*x1+w2*x2+w5*x3
> 显然:y=w1*x1+w2*x2+w3*x3和y=w1*x1+w2*x2+w5*x3是等价的。
> 那么最终最优的模型应该也是 y=5x1+7x2+10x3
> 但是考虑到引入了x4,所以w4和w3的权重是分开计算出来的,这就导致了w5=10=w3+2w4,
> 显然这个方程有无穷多的解,比如w3=4,w4=3,或者w4=-1,w3=12等,
> 因此导致了模型系数估计的不稳定并且可能会出现负系数的问题。
statsmodels(http://www.statsmodels.org)是一个Python库,用于拟合多种统计模型,执行统计测试以及数据探索和可视化。statsmodels包含更多的“经典”频率学派统计方法。
总结:https://blog.csdn.net/zm147451753/article/details/83107535
statsmodel的检验项目比较全面,实际上逻辑回归与线性回归比我们想象的要复杂。
等于 观测数也就是样本数(No. Observations)-参数数目(Df Model+1(常量参数,权重加上偏置的数量))
R 2 = 1 − ∑ i ( y ^ i − y i ) 2 ∑ i ( y ^ i − y ˉ i ) 2 R^{2}=1-\frac{\sum_{i}\left(\hat{y}_{i}-y_{i}\right)^{2}}{\sum_{i}\left(\hat{y}_{i}-\bar y_{i}\right)^{2}} R2=1−∑i(y^i−yˉi)2∑i(y^i−yi)2
上面分子就是我们训练出的模型预测的所有误差。
下面分母就是不管什么我们猜的结果就是y的平均数。(瞎猜的误差)
R a d j 2 = 1 − ( n − 1 ) ( 1 − R 2 ) n − p − 1 R_{a d j}^{2}=1-\frac{(n-1)\left(1-R^{2}\right)}{n-p-1} Radj2=1−n−p−1(n−1)(1−R2)
右边式子的R就是原始的R-sqaure,n是样本数量,p是特征的数量。