python – Spark中的PCA输出与scikit-learn不匹配

前端之家收集整理的这篇文章主要介绍了python – Spark中的PCA输出与scikit-learn不匹配前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我在Spark ML中尝试PCA(主成分分析).

data = [(Vectors.dense([1.0,1.0]),),(Vectors.dense([1.0,2.0]),(Vectors.dense([4.0,4.0]),(Vectors.dense([5.0,)]

df = spark.createDataFrame(data,["features"])
pca = PCA(k=1,inputCol="features",outputCol="pcaFeatures")
model = pca.fit(df)
transformed_feature = model.transform(df)
transformed_feature.show()

输出

+---------+--------------------+
| features|         pcaFeatures|
+---------+--------------------+
|[1.0,1.0]|[-1.3949716649258...|
|[1.0,2.0]|[-1.976209858644928]|
|[4.0,4.0]|[-5.579886659703326]|
|[5.0,4.0]|[-6.393620130910061]|
+---------+--------------------+

当我在scikit上尝试使用相同数据的PCA时 – 如下所示,给出了不同的结果

X = np.array([[1.0,1.0],[1.0,2.0],[4.0,4.0],[5.0,4.0]])
pca = PCA(n_components=1)
pca.fit(X)
X_transformed = pca.transform(X)
for x,y in zip(X,X_transformed):
    print(x,y)

输出

[ 1.  1.] [-2.44120041]
[ 1.  2.] [-1.85996222]
[ 4.  4.] [ 1.74371458]
[ 5.  4.] [ 2.55744805]

如您所见,输出存在差异.

为了验证结果,我在数学上计算了相同数据的PCA.我得到了与scikit-learn相同的结果.下面的片段是第一个数据点(1.0,1.0)的pca变换计算:

enter image description here

你可以看到它与scikit学习结果匹配.

似乎火花ML不从数据矢量X中减去平均矢量MX,即它使用Y = A *(X)代替Y = A *(X-MX).

对于点(1.0,1.0):

Y = (0.814*1.0)+(0.581*1.0)) = 1.395 

这与火花ML得到的结果相同.

Spark ML是错误的结果还是我错过了什么?

最佳答案
在Spark中,PCA转换不会自动为您扩展输入数据.在应用该方法之前,您需要自己处理.要标准化数据的平均值,可以通过以下方式使用StandardScaler:

scaler = StandardScaler(inputCol="features",outputCol="scaledFeatures",withStd=False,withMean=True)
scaled_df = scaler.fit(df).transform(df)

然后可以以与之前相同的方式在scaled_df上应用PCA方法,结果将与scikit-learn给出的结果相匹配.

我建议使用Spark ML管道来简化流程.要将标准化和PCA结合使用,它可能如下所示:

scaler = StandardScaler(inputCol="features",withMean=True)
pca = PCA(k=1,inputCol=scaler.getOutputCol(),outputCol="pcaFeatures")
pipeline = Pipeline(stages=[scaler,pca])

model = pipeline.fit(df)
transformed_feature = model.transform(df)

猜你在找的Python相关文章