StandardScaler.inverse_transform() 返回与输入相同的数组:/ sklearn 坏了还是我坏了?

问题描述

晚上好,

我目前正在攻读化学博士学位,在这个框架中,我试图应用我在 Python 和统计方面的一些知识,根据样品的红外光谱来区分样品。 经过几周的数据采集,我终于能够构建我的数据集,并且即将看到 PCA 可以提供什么(这是最简单的部分)。

我能够构建我的脚本并获得负载、分数以及我可能需要或想要的所有其他内容。但是,我使用 sklearn.preprocessing 中的 StandardScaler 来缩小我的数据,因此(如果我错了,请纠正我的错误)我应该在这个“标准缩放”空间中重新加载。

由于我的数据是实际的 IR 光谱,因此这些负载具有化学意义(即使认为没有真正的光谱),例如如果我的 PC1 负载在 XX cm-1 处有一个峰值,我知道具有高 PC1 的样品可能包含在该波数处吸收的化合物。 所以我想反转 StandardScaler 转换。我试过使用 StandardScaler.inverse_transform() 但是它似乎返回了我给他的相同数组......这非常令人沮丧...... 我正在尝试对我的样本光谱做同样的事情,但它再次给了我相同的结果:这是我尝试此操作的脚本部分:

<!DOCTYPE html>
<html lang="en">

<head>
    <Meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <Meta name="viewport" content="width=device-width,initial-scale=1" />
    <Meta name="theme-color" content="#000000" />
    <Meta name="description" content="Web site created using create-react-app" />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <title>Welcome to DevConnector!</title>
</head>

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
</body>

</html>

问题很可能是语法或我如何使用 StandardScaler,但是我周围没有人可以寻求帮助。谁能告诉我我做错了什么?或者给我一个关于如何在“实际真实红外光谱”空间中恢复负载提示

PS:对不起,古怪的英语,我希望可以理解

解决方法

晚上好,

把这个问题搁置几天后,我终于重新编写了我需要的函数(如 Robert Dodier 所建议的)。

提醒一下,我想要一个函数,它可以从 Pandas 数据框中获取我的数据并以均值为中心,以便进行 PCA,但也可以反转预处理以备后用。

这是我最终得到的代码:

import pandas as pd
import numpy as np

class Scaler:
  std =[]
  mean = []
  def fit(self,DF):
    self.std=[]
    self.mean=[]
    for c in DF.columns:
      self.std.append(DF[c].std())
      self.mean.append(DF[c].mean())
  def transform(self,DF):
    X = np.zeros(shape=DF.shape)
    for i,c in enumerate(DF.columns):
      for j in range(len(DF.index)):
        X[j][i] = (DF[c][j] - self.mean[i]) / self.std[i] 
    return X
  def reverse(self,X):
    Y = np.zeros(shape=X.shape)
    for i in range(len(X[0])):
      for j in range(len(X)):
        Y[j][i] = X[j][i] * self.std[i] + self.mean[i]
    return Y
  def fit_transform(self,DF):
    self.fit(DF)
    X = self.transform(DF)
    return X

它很慢,而且技术含量肯定很低,但它似乎可以很好地完成这项工作。希望它能为其他 python 初学者节省一些时间。 我将它设计得与我认为的 sklearn.preprocessing.StandardScaler 一样接近。

示例:

S = Scaler() #create scaler object
S.fit(DF) #fit the scaler to the dataframe (calculate mean and std for every columns in DF /!\ DF must be a pd.dataframe)
X=S.transform(DF) # return a np.array with mean centered data
Y = S.reverse(X) # reverse the transformation to get back original data

再次为快速提示英语感到抱歉。并感谢罗伯特花时间回答。