【问题标题】:Normal equation in linear regression return theta coefficients as 'NaN'线性回归中的正态方程将 theta 系数返回为“NaN”
【发布时间】:2016-03-13 16:54:23
【问题描述】:

我正在尝试使用 正规方程 方法进行线性回归。在我的数据中,我有 n = 143 个特征和 m = 13000 个训练示例。我知道当特征数大于 10000 时,推荐使用正规方程法。但我只有 143 个特征。我的代码返回 'nan' 作为我的 thetas 数组(线性系数)。

在我的 csv 文件中显示的数据没有标题。所以我在 csv 文件中的数据看起来像这样(只有前 15 个训练示例,还没有一列):

2;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;1;0;0;0;0;0;1986;9;1;16;5;1;1.65;1;0;0;0;4;2;1;0;0;0;1;1;0;0;0;0;2.8;1;0;15000
2;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;6;0;0;1;0;0;0;0;2006;8;0;23;5;2;1.65;1;0;0;0;2;2.23;1;0;0;0;1;1;0;0;0;0;2.79;1;0;12900
1;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;1;0;0;0;0;0;1987;6;0;29;6;2;1;0;1;0;0;2;1;0;1;0;0;2.12;0;1;0;0;0;2.8;3;0;23438
2;1;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;1;0;0;0;2009;3;0;56;5;3;1;1;0;0;0;4;2;1;0;0;0;2;1;0;0;0;0;2.79;1;0;67000
1;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;10;0;1;0;0;0;0;0;1978;5;1;115;6;2;2;1;0;0;0;4;2;1;0;0;0;3;0;1;0;0;0;2.8;3;0;230000
3;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;6;0;0;1;0;0;0;0;2006;7;0;250;4.93;4;4;1;0;0;0;3.91;2.23;0;0;1;0;2.12;0;0;1;0;0;3;2;0;224000
1;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;8;0;0;1;0;0;0;0;2007;3;0;31;5;2;1;1;0;0;0;3.91;2.23;0;1;0;0;2.12;0;1;0;0;0;2.79;1;0;45000
1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;4;0;1;0;0;0;0;0;1975;8;1;31;6;3;2;1;0;0;0;4;2;1;0;0;0;2;0;1;0;0;0;2.79;2;0;66000
1;1;0;0;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;5;0;0;0;1;0;0;0;1992;1;1;32;5;2.52;1.65;0;1;0;0;3.91;2.23;0;1;0;0;2.12;0;0;1;0;0;2.79;1;0;34000
1;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;3;0;0;1;0;0;0;0;2012;16;1;32;5;2;2;1;0;0;0;4;2;1;0;0;0;2;1;0;0;0;0;2.79;1;0;36000
2;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;8;0;1;0;0;0;0;0;1977;3;0;33;6;2;1.65;1;0;0;0;4;2.23;0;1;0;0;2.12;0;1;0;0;0;2.79;1;0;38000
2;1;0;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;8;0;0;1;0;0;0;0;2007;3;0;33;4.93;2;1;1;0;0;0;4;2.23;0;1;0;0;2.12;1;0;0;0;0;2.79;2;0;37000
1;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;8;0;1;0;0;0;0;0;1990;3;0;33;5;2;1;1;0;0;0;4;2;1;0;0;0;2;1;0;0;0;0;2.79;1;0;38000
2;1;0;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;8;0;0;1;0;0;0;0;2012;4;0;33;5;2;2;1;0;0;0;4;4;1;0;0;0;2;1;0;0;0;0;2.79;1;0;45000
3;1;0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;7;0;0;0;0;1;0;0;1982;1;1;35;5;2;1.65;1;0;0;0;4;2.23;0;0;0;1;2;1;0;0;0;0;2.7;1;0;45000

注意: 数据包含这么多零和一的原因是因为我对某些特征使用了虚拟编码。有些功能有相当数量的类。


Python 代码:

import pandas as pd
import numpy as np

path = 'DB2.csv'  
data = pd.read_csv(path, header=None, delimiter=";")

data.insert(0, 'Ones', 1)

print np.linalg.cond(data)
print np.linalg.matrix_rank(data)

cols = data.shape[1] 
X = data.iloc[:,0:cols-1]  
y = data.iloc[:,cols-1:cols] 

#Normal equation:
xTx = X.T.dot(X)
XtX = np.linalg.inv(xTx)
XtX_xT = XtX.dot(X.T)
theta = XtX_xT.dot(y)

print theta

这个公式用于正规方程:

程序的输出(thetas 数组):

[[ nan]
 [ nan]
 [ nan]
 [ nan]
 [ nan]
 ...
 [ nan]]

在程序中我也尝试通过代码检查矩阵的条件数

print np.linalg.cond(data) 

这行代码也返回了'nan'

但是这行代码用于检查矩阵等级

print np.linalg.matrix_rank(data)

返回 0


我需要澄清发生了什么。我不知道出了什么问题以及为什么我得到nan

【问题讨论】:

  • 使用 np.sum 打印每列的总和会发生什么?那里有 NaN 吗?
  • 在这种情况下没有 Nans。 np.sum 正确返回列中元素的总和
  • xTx = X.T.dot(X) 也没有 NaN?那么xTx的条件数是多少? xTx 的奇异值? xTx 的等级? xTx 基本上是单数吗?
  • 现在我解决了获取 NaN 的问题。现在我收到了条件编号和等级的值:CN:7.13391822002e+22 等级:132
  • 这似乎真的是矩阵奇异的问题。我必须做正则化。

标签: python machine-learning regression nan linear-regression


【解决方案1】:

使用虚拟/指标变量时需要注意的事项,可能会发生在此处:

包含一个常数向量 + 完整指标(或多个具有完整指标的类别)会创建一个秩亏数据矩阵

假设您有一个晚上的虚拟变量、一个白天的虚拟变量、一个下雪的虚拟变量和一个不下雪的虚拟变量。您的数据可能类似于:

           I_day    I_night     I_snow     I_no_snow
obs 1:         1          0          1             0
obs 2:         0          1          1             0
obs 3:         1          0          0             1
obs 4:         0          1          0             1
etc...

出现了一个微妙但 HORRIBLE 的错误,数据矩阵秩不足I_day + I_night 始终是 1 的向量,I_snow + I_no_snow 也是如此。我们有线性依赖关系:I_day+I_night = I_snow+I_no_snow!数据矩阵是 3 级,而不是 4 级。X'*X 将是 3 级(而不是 4)。

做什么:

  • 如果在数据矩阵 X 中包含一个常数,那么对于 每个分类变量,您始终需要将 1 个类别的虚拟变量留在矩阵 X 之外。(虚拟变量将指示相对的效果到这个被遗漏的类别)。

在这个例子中,我可以如下形成我的数据矩阵 X:

           const    I_day     I_snow 
obs 1:         1        1          1
obs 2:         1        0          1
obs 3:         1        1          0
obs 4:         1        0          0
etc...
  • 如果不包含常量,您可以为恰好一个分类变量包含完整个虚拟变量。

基本思想是数据矩阵中应该只有 1 个常量向量。 2+ 个类别的完整虚拟模型就像在数据矩阵中包含 2+ 个常数向量。

【讨论】:

    【解决方案2】:

    拥有实际数据以了解实际情况会有所帮助,但根据您的描述,您的数据矩阵,即 X 是病态的。因此,条件估计返回 NaN 并且您的等级为 0。因此 (X^T*X) 不能倒置。 为了解决这个问题,你需要正则化,即计算

    (X^T*X+lambda * 1)^(-1)*X^T 代替,其中 1 是适当维度的单位矩阵,而 lambda 是您的正则化参数。

    【讨论】:

    • 我查看了正则化。我唯一的问题是,为什么在互联网的某些公式中确实需要将正则化参数 lambda 乘以单位矩阵,但在 Andrew Ng 的讲座中,他也使用了 lambda,但将其乘以不完全单位矩阵。 Andrew Ng 的公式在页面末尾:napitupulu-jon.appspot.com/posts/…。为什么他在单位矩阵的 1 个元素处为零?
    • 这取决于特定的问题,但通常情况下,您会正则化所有元素。在您的情况下,排名为 0,您应该在正则化之前检查您的数据,因为只有当 X 全部为零时您才会得到。
    猜你喜欢
    • 2018-08-27
    • 2021-06-12
    • 2019-12-31
    • 2015-05-08
    • 2018-10-02
    • 2017-11-04
    • 1970-01-01
    • 2021-08-20
    • 2016-06-29
    相关资源
    最近更新 更多