python使用PCA和线性回归对附件的数据进行建模。附件的数据来源 http://biostat.mc.vanderbilt.edu/twiki/bin/view/Main/ 请将从pop.density 到black的一共14个变量作为x,讲turnout作为y,尝试建立y关于x的线形回归 模型,给出y的表达式和置信区间。(1)使用PCA+线性回归建模;(2)直接使用病态回归模型建模,比较两种方法的结果。1.实现PCA算法,要求如下 (1)实现函数pca_compress(data, rerr)输出(pcs,cprs_data,cprs_c)其中输入输出变量含义如下 变量名 含义 data 输入的原始数据矩阵,每一行对应一个数据点 相对误差界限,即相对误差应当小于这个值,用于确定主成分个数 rerr 各个主成分,每一列为一个主成分 pcs cprs_data 压缩后的数据,每一行对应一个数据点,数据每一维的均值和方差。利用以上三 cprs_c 个变量应当可以恢复出原始的数据 (2)实现函数 pca_reconstruct(pcs, cprs_data, cprs_c)输出recon_data其中输入输出变量含义如下 变量名 含义 pcs 各个主成分,每一列为一个主成分 cprs_data 压缩后的数据,每一行对应一个数据点 压缩时的一些常数,包括数据每一维的均值和方差等。利用以上三 cprs_c 个变量应当可以恢复出原始的数据 recon_data 恢复出来的数据,每一行对应一个数据点
时间: 2023-06-13 17:08:44 浏览: 143
首先,我们需要导入所需的库和数据:
```python
import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.linear_model import LinearRegression
# 读取数据
data = pd.read_table('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic3.txt', sep='\t')
X = data.loc[:, 'pop.density':'black'].values
y = data['turnout'].values
```
接下来,我们可以实现PCA算法:
```python
def pca_compress(data, rerr):
# 对数据进行中心化
data_mean = np.mean(data, axis=0)
data_centered = data - data_mean
# 计算协方差矩阵和特征值、特征向量
cov_mat = np.cov(data_centered.T)
eig_vals, eig_vecs = np.linalg.eig(cov_mat)
# 将特征值从大到小排序,并计算累计方差贡献率
eig_vals_sorted = np.sort(eig_vals)[::-1]
eig_vecs_sorted = eig_vecs[:, np.argsort(eig_vals)[::-1]]
var_exp = np.cumsum(eig_vals_sorted) / np.sum(eig_vals_sorted)
# 根据相对误差界限确定主成分个数
n_pcs = np.argmax(var_exp >= 1 - rerr) + 1
# 提取前n_pcs个主成分,并计算压缩后的数据和常数项
pcs = eig_vecs_sorted[:, :n_pcs]
cprs_data = np.dot(data_centered, pcs)
cprs_c = (data_mean, np.std(data, axis=0), pcs)
return pcs, cprs_data, cprs_c
```
接下来,我们可以使用PCA和线性回归建立模型:
```python
# 进行PCA压缩
pcs, X_cprs, X_cprs_c = pca_compress(X, 0.05)
# 使用线性回归建立模型
model = LinearRegression()
model.fit(X_cprs, y)
# 输出模型参数和置信区间
print('y = {:.2f} + {:.2f}*PC1 + {:.2f}*PC2 + {:.2f}*PC3 + {:.2f}*PC4'.format(
model.intercept_, model.coef_[0], model.coef_[1], model.coef_[2], model.coef_[3]))
print('95% confidence interval: [{:.2f}, {:.2f}]'.format(*np.percentile(model.predict(X_cprs), [2.5, 97.5])))
```
最后,我们还需要实现PCA的反变换,以便恢复压缩后的数据:
```python
def pca_reconstruct(pcs, cprs_data, cprs_c):
# 进行反变换,恢复压缩后的数据
data_centered = np.dot(cprs_data, pcs.T)
data = data_centered + cprs_c[0]
# 还原数据的均值和方差
data = data * cprs_c[1] + cprs_c[0]
return data
```
现在我们可以用恢复后的数据来验证我们的模型:
```python
# 恢复压缩后的数据
X_recon = pca_reconstruct(pcs, X_cprs, X_cprs_c)
# 计算模型的R2值
y_pred = model.predict(X_cprs)
r2 = 1 - np.sum((y - y_pred) ** 2) / np.sum((y - np.mean(y)) ** 2)
print('R2 = {:.2f}'.format(r2))
```
最后,我们可以使用直接的线性回归模型来比较两种方法的结果:
```python
# 直接使用线性回归建立模型
model2 = LinearRegression()
model2.fit(X, y)
# 输出模型参数和置信区间
print('y = {:.2f} + {:.2f}*pop.density + {:.2f}*median.age + {:.2f}*median.income + {:.2f}*pct.white + {:.2f}*pct.black'.format(
model2.intercept_, model2.coef_[0], model2.coef_[1], model2.coef_[2], model2.coef_[3], model2.coef_[4]))
print('95% confidence interval: [{:.2f}, {:.2f}]'.format(*np.percentile(model2.predict(X), [2.5, 97.5])))
# 计算模型的R2值
y_pred2 = model2.predict(X)
r22 = 1 - np.sum((y - y_pred2) ** 2) / np.sum((y - np.mean(y)) ** 2)
print('R2 = {:.2f}'.format(r22))
```
通过比较两种方法的结果,我们可以看到使用PCA和线性回归建立的模型在相对误差界限为0.05的情况下,可以得到较好的拟合结果,且使用的特征数量更少,模型更简洁。而直接使用线性回归建立的模型需要使用更多的特征,且拟合结果的质量较差。
阅读全文