当前位置: 首页 > 面试题库 >

如何在XML中将列声明为DataFrame中的分类功能

徐友樵
2023-03-14
问题内容

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

我有一个DataFrame从数据库加载的Spark SQL
。其中的许多列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)

问题答案:

我宁愿避免编码和解码的麻烦,

您无法真正完全避免这种情况。分类变量所需的元数据实际上是值和索引之间的映射。仍然不需要手动执行此操作或创建自定义转换器。假设您具有如下数据框:

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))


 类似资料:
  • 问题内容: 当我得知该类在Java中被声明为final时,我想知道为什么会这样。那时我没有找到任何答案,但是这篇文章:如何在Java中创建String类的副本?让我想起了我的疑问。 当然,String提供了我所需要的所有功能,而且我从未想过需要扩展String类的任何操作,但是您仍然永远不会知道有人可能需要什么! 那么,有谁知道设计师决定将其定稿时的意图是什么? 问题答案: 将字符串实现为不可变对

  • 问题内容: 为什么不能在Java中将类声明为静态类? 问题答案: 只有嵌套的类可以是静态的。这样,你可以使用嵌套类而无需外部类的实例。

  • 下面是我做的方式: 我只是想知道,这是正确的方法吗,因为在运行逻辑回归时,我得到了一些错误,所以我想知道,这是麻烦的原因吗。

  • 我有一个Pandas DataFrame列,其中包含一个列表中的多个列表。类似于这样: 我想将列表拆分为多列,因此输出应该是这样的: 请帮我做这件事。预先感谢

  • 问题内容: 我正在使用espresso-contrib在上执行操作,它可以正常运行,例如: 我需要对此进行断言。像这样: 但是,由于RecyclerViewActions当然期望执行某个操作,因此它说出了错误的第二个参数类型。浓咖啡没有。 有什么方法可以在回收者视图上执行断言吗? 问题答案: 您应该查看Danny Roa的解决方案Custom RecyclerView Actions并按以下方式

  • 问题内容: 有以下代码: 显然,的调用以某种方式改变了类的属性和行为。 这是怎么发生的?如何在代码中使用这种方法? 示例代码是zope.interface模块的一部分。 问题答案: 详细的“会发生什么” 该函数检查框架堆栈并更改构造类的名称空间(python )。python语句中的所有内容都在该命名空间中执行,结果形成类主体。 该函数为类命名空间添加了额外的值,其中包含一些数据(已传递给该函数的