我正在尝试在PySpark中运行线性回归,我想创建一个包含汇总统计信息的表,例如数据集中每列的系数,P值和t值。但是,为了训练线性回归模型,我必须使用Spark的VectorAssembler
创建一个特征向量,现在对于每一行我都有一个特征向量和目标列。
当我尝试访问Spark的内置回归摘要统计信息时,它们会为每个统计信息提供一个非常原始的数字列表,并且无法知道哪个属性对应于哪个值,这很难通过手动计算出来大量的列。
如何将这些值映射回列名?
例如,我的当前输出是这样的:
系数:[ - 187.807832407,-187.058926726,85.1716641376,10595.3352802,-127.258892837,-39.2827730493,-1206.47228704,33.7078197705,99.9956812528]
P值:[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.18589731365614548,0.275173571416679,0.0]
t统计量:[-23.348593508995318,-44.72813283953004,19.836508234714472,144.49248881747755,-16.547272230754242,-9.560681351483941,-19.563547400189073,1.3228378389036228,1.0912415361190977,20.383256127350474]
系数标准误差:[8.043646497811427,4.182131353367049,4.293682291754585,73.32793120907755,7.690626652102948,4.108783841348964,61.669402913526625,25.481445101737247,91.63478289909655,609.7007361468519]
除非我知道它们对应哪个属性,否则这些数字毫无意义。但是在我的DataFrame
中,我只有一个名为“features”的列,其中包含稀疏向量行。
当我有一个热门编码特征时,这是一个更大的问题,因为如果我有一个长度为n的编码变量,我会得到n个相应的系数/ p值/ t值等。
答案 0 :(得分:13)
截至今天,Spark并未提供任何可以为您完成此任务的方法,因此如果您必须创建自己的方法。我们假设您的数据如下所示:
url(r'^password_reset/$',
auth_views.password_reset,
{'current_app': 'accounts',
'template_name': 'accounts/password_reset.html',
'email_template_name': 'accounts/password_reset_email.html',
'password_reset_form': MyPasswordResetForm,
'post_reset_redirect': '/accounts/password_reset_done/', },
name='password_reset'),
并使用以下管道进行处理:
import random
random.seed(1)
df = sc.parallelize([(
random.choice([0.0, 1.0]),
random.choice(["a", "b", "c"]),
random.choice(["foo", "bar"]),
random.randint(0, 100),
random.random(),
) for _ in range(100)]).toDF(["label", "x1", "x2", "x3", "x4"])
获取from pyspark.ml.feature import StringIndexer, OneHotEncoder, VectorAssembler
from pyspark.ml import Pipeline
from pyspark.ml.regression import LinearRegression
indexers = [
StringIndexer(inputCol=c, outputCol="{}_idx".format(c)) for c in ["x1", "x2"]]
encoders = [
OneHotEncoder(
inputCol=idx.getOutputCol(),
outputCol="{0}_enc".format(idx.getOutputCol())) for idx in indexers]
assembler = VectorAssembler(
inputCols=[enc.getOutputCol() for enc in encoders] + ["x3", "x4"],
outputCol="features")
pipeline = Pipeline(
stages=indexers + encoders + [assembler, LinearRegression()])
model = pipeline.fit(df)
:
LinearRegressionModel
转换数据:
lrm = model.stages[-1]
提取并展平ML属性:
transformed = model.transform(df)
并映射到输出:
from itertools import chain
attrs = sorted(
(attr["idx"], attr["name"]) for attr in (chain(*transformed
.schema[lrm.summary.featuresCol]
.metadata["ml_attr"]["attrs"].values())))
[(name, lrm.summary.pValues[idx]) for idx, name in attrs]
[('x1_idx_enc_a', 0.26400012641279824),
('x1_idx_enc_c', 0.06320192217171572),
('x2_idx_enc_foo', 0.40447778902400433),
('x3', 0.1081883594783335),
('x4', 0.4545851609776568)]
[(name, lrm.coefficients[idx]) for idx, name in attrs]
答案 1 :(得分:3)
您可以在此处查看列的实际顺序
df.schema["features"].metadata["ml_attr"]["attrs"]
通常会有两个类,[“binary]& [”numeric“]
pd.DataFrame(df.schema["features"].metadata["ml_attr"]["attrs"]["binary"]+df.schema["features"].metadata["ml_attr"]["attrs"]["numeric"]).sort_values("idx")
应该给出所有列的确切顺序
答案 2 :(得分:-2)
这是一行答案:
[x["name"] for x in sorted(train_downsampled.schema["all_features"].metadata["ml_attr"]["attrs"]["binary"]+
train_downsampled.schema["all_features"].metadata["ml_attr"]["attrs"]["numeric"],
key=lambda x: x["idx"])]
感谢@pratiklodha的帮助。