如何在两个二维numpy数组之间执行线性/非线性回归并用matplotlib可视化?
首先,我想说明一下,我需要对一个大国家的数据进行回归分析,这些数据涉及一种疾病和一些环境因素,所以我有很多数据。
现在,我把这些数据存储在 tiff
文件中,并通过 gdal
读取到 numpy
数组里。每个数据集被读取成一个形状为 <54L,53L>
的 numpy
数组。我有多个这样的数组,每个数据集都有。接下来,我需要在这两个二维 numpy
数组之间进行回归分析。数组中的值是 Float64
类型。举个例子:
[[ 162.32145691 158.19345093 153.15704346 ..., 123.77481079 123.63883972 123.6770401 ]
[ 164.55152893 160.59266663 155.75968933 ..., 121.28504181 121.1164093 121.16275024] ...,
[ 321.38272095 329.53326416 338.85699463 ..., 193.69404602 192.50938416 191.42672729]]
比如说,疾病数据集和环境因素1之间的关系,疾病数据集和环境因素2之间的关系等等。由于这些关系比较复杂且不太明确,我想先把这两个二维数组画出来,但我找不到合适的方法。
那么,我该如何在 matplotlib
中绘制这两个二维数组的散点图呢? 我说散点图是因为这样我更容易推断出它们之间的关系,然后再选择合适的回归模型(线性、非线性、对数等)。我用以下代码逐行绘制每个 numpy
数组之间的关系:
for i in range(55):
plt.scatter(JanTemp[i],can02[i])
plt.title('Disease vs Temperature')
plt.ylabel('DiseaseCases')
plt.xlabel('Temp')
plt.show()
在这里,can02
是响应变量,JanTemp
是预测变量。正如我所预期的,我得到了54个连续的图表,并且两个变量的颜色是一样的,这让我很沮丧(这是我第一次使用 matplotlib
,我不知道怎么让每个变量有不同的颜色)。 有没有更好的方法呢?如果有,请建议一下。 我觉得可以用三维可视化,但那样我又该如何从中推断呢?所以请建议一种在二维空间中更好的可视化方法。
由于从图表中得不到太多信息,我决定先从线性回归开始。我使用 scipy.stats.linregress
,像上面那样对每一行进行迭代,方法如下:
months =[JanTemp,FebTemp,MarTemp1,AprTemp,MayTemp,JunTemp,JulTemp,AugTemp,SepTemp,OctTemp,NovTemp,DecTemp]
for month in months:
csum=0
pcsum=0
for i in range(54):
slope, intercept, r_value, p_value, std_err = stats.linregress(month[i],can02[i])
csum +=r_value
pcsum += (r_value**2)*100
print "mean correlation coefficient is", csum/53
print "The avg COD is", pcsum/53
在这里,JanTemp
、FebTemp
等等是每个维度为 54,53
的文件。对于每个文件,我进行53次行对行的回归。这也显得有些单调。 有没有更好的方法,比如函数、模块等?
我知道的另一种方法是使用 statsmodels.api
模块的普通最小二乘法(OLS),方法如下:
y = can02
x = JanTemp
X = sm.add_constant(x) #Adds a constant to the linear eq of regression
est = sm.OLS(y, X) #OLS performs the regression of predictor on response
est = est.fit() #fit object of OLS fits the mode
est.summary() #Gives the summary of whole calculation
est.params #gives the coefficient of regression
但我遇到了以下长长的错误信息:
Traceback (most recent call last):
File "H:\Python\results.py", line 77, in <module>
est.summary() #Gives the summary of whole calculation
File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 1230, in summary
top_right = [('R-squared:', ["%#8.3f" % self.rsquared]),
File "C:\Python27\lib\site-packages\statsmodels\tools\decorators.py", line 95, in __get__
_cachedval = self.fget(obj)
File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 959, in rsquared
return 1 - self.ssr/self.centered_tss
File "C:\Python27\lib\site-packages\statsmodels\tools\decorators.py", line 95, in __get__
_cachedval = self.fget(obj)
File "C:\Python27\lib\site-packages\statsmodels\regression\linear_model.py", line 931, in ssr
return np.dot(wresid, wresid)
ValueError: matrices are not aligned
我不明白为什么矩阵没有对齐。无论如何,回到我最初的问题,有没有其他类似的方法可以进行回归,我该如何在二维数组上进行操作呢? 谢谢,我知道我在这个长问题上占用了你们很多宝贵的时间,但我想说得清楚。我在这个网站和其他网站上搜索了很多问题,但没有找到合适或相关的解决方案。谢谢。
1 个回答
你手上真的有带有坐标、参数和年份的三维数据吗?如果是这样的话,这里面的地理信息就很少了。
我觉得问题根本不在于 numpy
,而是在于你分析数据的方式。(如果你知道自己想要什么,可能会对 pandas
感兴趣。)
对于这种类型的工作,有一些非常复杂的统计方法,但你可以从一些简单的概念开始,就像你之前做的线性回归那样。首先,你应该把依赖变量(结果,比如疾病)和独立变量(比如温度)分开,并一次只关注一个依赖变量。
举个简单的例子:只考虑一种疾病。你在 N 个地点收集了 M 年的病例数。然后把所有的 P 个环境因素都拿出来。现在你可以计算每个地点的疾病和所有 P 个环境因素之间的时间序列相关性。这样每个 N 个地点就会得到 P 个数字。
如果你把这些数据做成图像(N 行,P 列),你可以寻找那些强烈的列。它们代表在很多地方似乎重复出现的疾病和环境因素的组合。这种方法虽然不够严格,但能快速给你一个概览。
我不会给太多代码示例,因为在进行任何可视化之前,需要先考虑统计基础。可视化的部分通常会简单一些。不幸的是,对于你手上的数据类型,没有简单的可视化方法。
不过关于散点图,你可以参考这个链接:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter。比如,如果你想用红色标记代替蓝色标记,可以这样写:scatter(x, y, c='r')
。如果你只想为每个数据系列使用单一颜色,也可以用 plt.plot(x, y, 'r.')
(r
定义颜色,.
表示我们想要分开的数据点。)