3. python下编写代码实现PCA+SVD

1. PCA原理介绍

见我的另一篇博客: PCA原理介绍

2. PCA+SVD原理介绍

见我的另一篇博客: PCA+SVD原理介绍


3. python下编写代码实现PCA+SVD

3.1 训练集和测试集怎么处理?

在PCA降维数据预处理时,很多人都会遇到一个疑问:

  • a. 我该把训练集和测试集放在一块,PCA降维后再分开吗?
  • b. 还是说我该把训练集和测试集直接分开PCA降维?
  • c. …还有什么办法吗…?

我开始也遇到了这样的疑问,但是b的方法肯定是直接拒绝的!因为b的方法会导致训练集测试集完全在两个分布下,他们的均值不一样,标准化的标准也不一样,训练出来的结果肯定会非常不准确!
所以:
b. 还是说我该把训练集和测试集直接分开PCA降维? → False

那看到这,你肯定觉得,还是a得做法靠谱,确实我之前有段时间没有想到解决办法,也用的a办法,a办法不会有太大的损害,但是在把训练集和测试集放在一块PCA的时候,相当于训练集和测试集互相引入了信息,后来训练的网络很可能过拟合,准确率也虚高。
所以:
a. 我该把训练集和测试集放在一块,PCA降维后再分开吗? → False

正确做法应该是:

预处理时:

1. 训练集 测试集提前分开,划分好;
2. 训练集预处理时,保存好训练集的均值+方差,它的零均值化,标准化正常进行;
3. 测试集利用刚保存的训练集的均值+方差进行零均值化,标准化;

PCA降维时:

1. 预处理后的训练集 测试集依然分开;
2. 用训练集进行PCA降维,得到投影矩阵P;
3. 测试集利用刚训练集得到的投影矩阵P进行降维;


这节重点讲代码:

3.2 预处理的代码:

整体调用函数:
        data, dataTest = get_data()  # 获取训练集data  测试集 dataTest准备PCA
        print(len(data), '个样本', len(data.columns), '个属性')

        print('----------------  PCA my data ...   --------------------	')

        dataY = data[['allcase']]  # 去除训练集的结果属性
        dataX = data.drop('allcase', axis=1, inplace=False)  # 保留训练集的普通属性 用于PCA

        dataTestY = dataTest[['allcase']]   # 去除测试集的结果属性
        dataTestX = dataTest.drop('allcase', axis=1, inplace=False)   # 保留测试集的普通属性 用于PCA

		# 用训练集的平均数,方差去 预处理测试集
        dataX, dataTestX = NormalizeData(dataX, dataTestX)

        dataAfterPca, newColLen, dataTestAfterPca = myPCA(per, dataX, dataTestX)  # PCA降维
预处理 NormalizeData(dataX, dataTestX):
def NormalizeData(data, dataTest):
    scaler = StandardScaler()   # 建立标准化模型
    dataAttr = scaler.fit_transform(data)  # fit_transform:采用训练集fit 模型,保存均值,方差 然后对训练集进行标准化
    dataTestAttr = scaler.transform(dataTest)   # transform:采用训练集的均值,方差 然后对测试集进行标准化

    return dataAttr, dataTestAttr
注意: transform和fit_transform的是不一样的! fit_transform 是有两个步骤: 1. fit 训练模型; 2. transform; transform 只有transform这个步骤。
PCA降维:对协方差矩阵做SVD
def myPCA(mcomponent, dataAttr, dataTestAttr):
	
    p, n = np.shape(dataAttr)  # shape of dataAttr  p=row , n=col
    # 求协方差矩阵cov_Mat
    cov_Mat = np.dot(dataAttr.T, dataAttr) / (p - 1)  # 对训练集得到协方差矩阵
    u, d, v = np.linalg.svd(cov_Mat, full_matrices=False)  # 对协方差矩阵做SVD U=UA  就是对原始样本SVD得到的Vb,即投影矩阵
    # 翻转特征向量符号以强制执行确定性输出操作(svd_flip),这才是SVD每次PCA相差负号的原因。
    u, v = svd_flip(u, v)  

    Index = index_lst(d, rate=mcomponent)  # choose how many main factors

    dataAttrAfterPca = pd.DataFrame(np.dot(dataAttr, u[:, :Index]))  # 训练集利用PCA降维
    print(len(dataAttrAfterPca.columns))

    dataTestAttrAfterPca = pd.DataFrame(np.dot(dataTestAttr, u[:, :Index]))  #  测试集利用PCA降维
    print(len(dataTestAttrAfterPca.columns))
    
    for each in dataAttrAfterPca.columns:
        dataAttrAfterPca.rename(columns={each: str(each)}, inplace=True)  # 把属性名字改成字符型的  便于存储CSV

    for each in dataTestAttrAfterPca.columns:
        dataTestAttrAfterPca.rename(columns={each: str(each)}, inplace=True)

    # data transformation
    return dataAttrAfterPca, int(Index), dataTestAttrAfterPca

4. python里使用成熟的现有PCA包

见我的另一篇博客:python里如何使用成熟的现有PCA包

PCA(Principal Component Analysis)是一种常用的数据降维技术,而线性回归则是一种常用的机器学习方法。下面分别介绍如何使用Python实现PCA和线性回归。 1. PCA 使用Python实现PCA通常需要使用NumPy和SciPy这两个库。下面是一个简单的PCA实现示例: ```python import numpy as np from scipy.linalg import svd # 定义PCA函数 def pca(X): # 去均值 X_mean = X.mean(axis=0) X = X - X_mean # 计算协方差矩阵 cov = np.cov(X.T) # 奇异值分解 U, S, V = svd(cov) # 返回降维结果 return np.dot(X, U[:, :2]) # 生成数据 X = np.random.rand(100, 4) # PCA降维 X_pca = pca(X) # 打印降维结果 print(X_pca) ``` 上述代码中,我们定义了一个名为`pca`的函数,它接受一个`n*m`的数据矩阵`X`作为输入,并返回一个`n*2`的降维结果。函数的具体实现如下: 1. 去均值:计算数据矩阵每列的均值,并将其从数据矩阵中减去; 2. 计算协方差矩阵:使用`np.cov`函数计算去均值后的数据矩阵的协方差矩阵; 3. 奇异值分解:使用`scipy.linalg.svd`函数对协方差矩阵进行奇异值分解; 4. 返回降维结果:将去均值后的数据矩阵乘以前两个奇异向量,得到一个`n*2`的降维结果。 2. 线性回归 使用Python实现线性回归可以使用scikit-learn库。下面是一个简单的线性回归实现示例: ```python from sklearn.linear_model import LinearRegression # 生成数据 X = np.random.rand(100, 2) y = np.dot(X, [2, 3]) + 0.5 * np.random.randn(100) # 线性回归 reg = LinearRegression().fit(X, y) # 打印系数和截距 print(reg.coef_) print(reg.intercept_) ``` 上述代码中,我们首先生成了一个`n*2`的数据矩阵`X`和一个长度为`n`的目标向量`y`。然后使用`scikit-learn`库中的`LinearRegression`类对数据进行线性回归,最后打印了线性回归的系数和截距。 以上就是使用Python实现PCA和线性回归的示例代码。需要注意的是,这只是两个非常简单的示例,实际应用中可能需要更复杂的算法和更多的代码
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值