【问题标题】:How do i display labels and predictions - PySpark我如何显示标签和预测 - PySpark
【发布时间】:2018-12-03 23:22:25
【问题描述】:

创建一个算法来对市场产品进行分类,所以我无法返回预测的标签,我尝试了几个命令,但它们都有一个错误(如下)。如何返回标签和百分比预测(我正在使用交叉验证)?

例子:

我想通知您产品“7 Chakra Bracelet 7 chakra 手链,蓝色或黑色”,并知道哪个是标签和准确度(此产品的标签返回“Bracelet”)

训练数据

data = spark.createDataFrame([
("Bracelet"," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
("Bracelet"," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
("Bracelet"," Bangle Bracelet Gold bangle bracelet with studded jewels."),
("Bracelet"," Boho Bangle Bracelet Gold boho bangle bracelet with multicolor tassels."),
("Earrings"," Boho Earrings Turquoise globe earrings on 14k gold hooks."),
("Necklace"," Choker with Bead Black choker necklace with 14k gold bead."),
("Necklace"," Choker with Triangle Black choker with silver triangle pendant."),
("Necklace"," Dainty Gold Necklace Dainty gold necklace with two pendants."),
("Necklace"," Dreamcatcher Pendant Necklace Turquoise beaded dream catcher necklace. Silver feathers adorn this beautiful dream catcher, which move and twinkle as you walk."),
("Earrings"," Galaxy Earrings One set of galaxy earrings, with sterling silver clasps."),
("Necklace"," Gold Bird Necklace 14k Gold delicate necklace, with bird between two chains."),
("Earrings"," Gold Elephant Earrings Small 14k gold elephant earrings, with opal ear detail."),
("Earrings"," Guardian Angel Earrings Sterling silver guardian angel earrings with diamond gemstones."),
("Bracelet"," Moon Charm Bracelet Moon 14k gold chain friendship bracelet."),
("Necklace"," Origami Crane Necklace Sterling silver origami crane necklace."),
("Necklace"," Pretty Gold Necklace 14k gold and turquoise necklace. Stunning beaded turquoise on gold and pendant filled double chain design."),
("Necklace"," Silver Threader Necklace Sterling silver chain thread through circle necklace."),
("Necklace"," Stylish Summer Necklace Double chained gold boho necklace with turquoise pendant.")

], ["id", "description"])

令牌、文本处理和矢量计数器

from pyspark.ml.feature import RegexTokenizer, StopWordsRemover, CountVectorizer
from pyspark.ml.classification import LogisticRegression
# regular expression tokenizer
regexTokenizer = RegexTokenizer(inputCol="description", outputCol="words", pattern="\\W")
# stop words
add_stopwords = ["http","https","amp","rt","t","c","the"] 
stopwordsRemover = StopWordsRemover(inputCol="words", outputCol="filtered").setStopWords(add_stopwords)
# bag of words count
countVectors = CountVectorizer(inputCol="filtered", outputCol="features", vocabSize=10000, minDF=5)

标签创建和数据集创建

from pyspark.ml import Pipeline
from pyspark.ml.feature import OneHotEncoder, StringIndexer, VectorAssembler
label_stringIdx = StringIndexer(inputCol = "id", outputCol = "label")
pipeline = Pipeline(stages=[regexTokenizer, stopwordsRemover, countVectors, label_stringIdx])
# Fit the pipeline to training documents.
pipelineFit = pipeline.fit(data)
dataset = pipelineFit.transform(data)

到目前为止,我的数据集的结果是这样的

填充交叉算法

from pyspark.ml.evaluation import MulticlassClassificationEvaluator
evaluator = MulticlassClassificationEvaluator(predictionCol="prediction")

lr = LogisticRegression(maxIter=20, regParam=0.3, elasticNetParam=0)
from pyspark.ml.tuning import ParamGridBuilder, CrossValidator
# Create ParamGrid for Cross Validation
paramGrid = (ParamGridBuilder()
             .addGrid(lr.regParam, [0.1, 0.3, 0.5]) # regularization parameter
             .addGrid(lr.elasticNetParam, [0.0, 0.1, 0.2]) # Elastic Net Parameter (Ridge = 0)
#            .addGrid(model.maxIter, [10, 20, 50]) #Number of iterations
#            .addGrid(idf.numFeatures, [10, 100, 1000]) # Number of features
             .build())
# Create 5-fold CrossValidator
cv = CrossValidator(estimator=lr, \
                    estimatorParamMaps=paramGrid, \
                    evaluator=evaluator, \
                    numFolds=5)
cvModel = cv.fit(dataset)

创建要分类的数据

testData = spark.createDataFrame([
(10," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
(11," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
(12," Bangle Bracelet Gold bangle bracelet with studded jewels."), 
(13," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
(14," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
(15," Bangle Bracelet Gold bangle bracelet with studded jewels."), 
  (100," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
(16," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
(17," Bangle Bracelet Gold bangle bracelet with studded jewels."), 
  (101," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
(18," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
(19," Bangle Bracelet Gold bangle bracelet with studded jewels."), 
  (104," 7 Shakra Bracelet 7 chakra bracelet, in blue or black."),
(20," Anchor Bracelet Mens Black leather bracelet with gold or silver anchor for men."),
(21," Bangle Bracelet Gold bangle bracelet with studded jewels.")
], ["rowid", "description"])

我创建了一个新数据集,应该通过仅删除 labelIndex 列进行排序

pipeline = Pipeline(stages=[regexTokenizer, stopwordsRemover, countVectors])
# Fit the pipeline to training documents.
pipelineFit = pipeline.fit(testData)
datasetTest = pipelineFit.transform(testData)

这里我用 datasetTest 计算新的预测

这里一切正常

现在问题来了,我无法从变量预测中看到任何信息

我尝试了下面的命令,但所有错误都发生了

【问题讨论】:

    标签: python pyspark cross-validation databricks azure-databricks


    【解决方案1】:

    如果您进一步查看错误跟踪,您会发现:

    java.lang.IllegalArgumentException:要求失败:A 的列与 x 的元素数不匹配。答:6,x:19

    这意味着您的训练数据和测试数据之间的特征数量不匹配(测试中的 6 个特征和测试中的 19 个特征)。

    训练数据

    +--------+--------------------+--------------------+--------------------+--------------------+-----+
    |      id|         description|               words|            filtered|            features|label|
    +--------+--------------------+--------------------+--------------------+--------------------+-----+
    |Bracelet| 7 Shakra Bracele...|[7, shakra, brace...|[7, shakra, brace...|       (6,[3],[2.0])|  1.0|
    |Bracelet| Anchor Bracelet ...|[anchor, bracelet...|[anchor, bracelet...|(6,[0,2,3,4],[1.0...|  1.0|
    

    测试数据

    +---+--------------------+--------------------+--------------------+--------------------+-----+
    | id|         description|               words|            filtered|            features|label|
    +---+--------------------+--------------------+--------------------+--------------------+-----+
    | 10| 7 Shakra Bracele...|[7, shakra, brace...|[7, shakra, brace...|(19,[0,1,2,3,10,1...|  8.0|
    | 11| Anchor Bracelet ...|[anchor, bracelet...|[anchor, bracelet...|(19,[0,2,3,4,5,7,...|  4.0|
    

    您正在尝试分别对测试和训练数据进行编码,这会导致编码数据不匹配。

    您需要从一个组合数据集 (trainData.union(testData)) 开始,其中 testData 没有标签。然后通过使用管道进行转换来编码这个数据集。然后将数据拆分回训练和测试,然后训练您的模型并进行预测。

    【讨论】:

    • Manoj,我不知道我是否理解正确,但这不是我在这部分代码中所做的“我创建了一个新数据集,该数据集应该通过仅删除 labelIndex 列进行排序” ,我在哪里创建一个新的数据集来排序?
    • 试试这个简单的改变。注释掉重新创建 pipelineFit 对象的 2 行。 #pipeline = Pipeline(stages=[regexTokenizer, stopwordsRemover, countVectors]) #pipelineFit = pipeline.fit(testData) 并重新运行您的代码。您必须使用相同的 pipelineFit 来转换您的训练和测试数据以获得相同数量的特征。
    • Manoj,代码停止显示错误,显示预测的列(rowid、描述、单词、过滤、特征、rawPrediction、概率、预测),但不显示标签列。您知道如何显示标签吗?
    • 标签=预测。我假设模型的全部目的是预测测试数据的标签。我建议您阅读完整的教程和示例测试并训练数据准备和模型创建,因为您的方法中有一些事情没有正确完成。
    • Manoj,非常感谢您的帮助。因为模型总是响应相同的标签,所以评论的必须是相同的。 :-D。我将应用停用词、词干提取等过程,看看模板是否正确响应。再次非常感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多