gpt4 book ai didi

python - 如何在 DataFrame 中将 Column 声明为分类特征以在 ml 中使用

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:19 25 4
gpt4 key购买 nike

如何声明我的 DataFrame 中的给定列包含分类信息?

我有一个从数据库加载的 Spark SQL DataFrame。此 DataFrame 中的许多列都有分类信息,但它们被编码为 Longs(出于隐私考虑)。

我希望能够告诉 spark-ml,尽管此列是数值列,但信息实际上是分类的。类别索引可能有一些漏洞,这是可以接受的。 (例如,一列可能具有值 [1, 0, 0 ,4])

我知道存在 StringIndexer,但我更愿意避免编码和解码的麻烦,特别是因为我有很多具有这种行为的列。

我会寻找类似下面的东西

train = load_from_database()
categorical_cols = ["CategoricalColOfLongs1",
"CategoricalColOfLongs2"]
numeric_cols = ["NumericColOfLongs1"]

## This is what I am looking for
## this step detects the min and max value of both columns
## and adds metadata to indicate this as a categorical column
## with (1 + max - min) categories
categorizer = ColumnCategorizer(columns = categorical_cols,
autoDetectMinMax = True)
##

vectorizer = VectorAssembler(inputCols = categorical_cols +
numeric_cols,
outputCol = "features")
classifier = DecisionTreeClassifier()
pipeline = Pipeline(stages = [categorizer, vectorizer, classifier])
model = pipeline.fit(train)

最佳答案

I would prefer to avoid the hassle of encoding and decoding,

您无法真正完全避免这种情况。分类变量所需的元数据实际上是值和索引之间的映射。尽管如此,仍无需手动执行或 create a custom transformer .假设您有这样的数据框:

import numpy as np
import pandas as pd

df = sqlContext.createDataFrame(pd.DataFrame({
"x1": np.random.random(1000),
"x2": np.random.choice(3, 1000),
"x4": np.random.choice(5, 1000)
}))

您只需要一个汇编器和索引器:

from pyspark.ml.feature import VectorAssembler, VectorIndexer
from pyspark.ml import Pipeline

pipeline = Pipeline(stages=[
VectorAssembler(inputCols=df.columns, outputCol="features_raw"),
VectorIndexer(
inputCol="features_raw", outputCol="features", maxCategories=10)])

transformed = pipeline.fit(df).transform(df)
transformed.schema.fields[-1].metadata

## {'ml_attr': {'attrs': {'nominal': [{'idx': 1,
## 'name': 'x2',
## 'ord': False,
## 'vals': ['0.0', '1.0', '2.0']},
## {'idx': 2,
## 'name': 'x4',
## 'ord': False,
## 'vals': ['0.0', '1.0', '2.0', '3.0', '4.0']}],
## 'numeric': [{'idx': 0, 'name': 'x1'}]},
## 'num_attrs': 3}}

此示例还显示了您提供什么类型的信息来将向量的给定元素标记为分类变量

{
'idx': 2, # Index (position in vector)
'name': 'x4', # name
'ord': False, # is ordinal?
# Mapping between value and label
'vals': ['0.0', '1.0', '2.0', '3.0', '4.0']
}

因此,如果您想从头开始构建它,您所要做的就是正确的架构:

from pyspark.sql.types import *
from pyspark.mllib.linalg import VectorUDT

# Lets assume we have only a vector
raw = transformed.select("features_raw")

# Dictionary equivalent to transformed.schema.fields[-1].metadata shown abov
meta = ...
schema = StructType([StructField("features", VectorUDT(), metadata=meta)])

sqlContext.createDataFrame(raw.rdd, schema)

但由于需要序列化、反序列化,效率很低。

Spark 2.2 开始,您还可以使用元数据参数:

df.withColumn("features", col("features").alias("features", metadata=meta))

另见 Attach metadata to vector column in Spark

关于python - 如何在 DataFrame 中将 Column 声明为分类特征以在 ml 中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37473380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com