使用ml
,Spark 2.0
(Python)和1.200万行数据集,我试图创建一个模型,预测购买倾向与Random Forest Classifier
。然而,当将变换应用于分裂的test
数据集时,预测总是0。
数据集如下所示:
[Row(tier_buyer=u'0', N1=u'1', N2=u'0.72', N3=u'35.0', N4=u'65.81', N5=u'30.67', N6=u'0.0'....
tier_buyer
是用作label indexer
的字段。其余字段包含数值数据。
步骤
1.-加载 parquet 文件,并填充可能的空值:
parquet = spark.read.parquet('path_to_parquet')
parquet.createOrReplaceTempView("parquet")
dfraw = spark.sql("SELECT * FROM parquet").dropDuplicates()
df = dfraw.na.fill(0)
2.-创建特征向量:
features = VectorAssembler(
inputCols = ['N1','N2'...],
outputCol = 'features')
3.-创建字符串索引器:
label_indexer = StringIndexer(inputCol = 'tier_buyer', outputCol = 'label')
4.-拆分训练和测试数据集:
(train, test) = df.randomSplit([0.7, 0.3])
- 生成的训练数据集 *
- 结果测试数据集 *
5.-定义分类器:
classifier = RandomForestClassifier(labelCol = 'label', featuresCol = 'features')
6.-管道化阶段并拟合列车模型:
pipeline = Pipeline(stages=[features, label_indexer, classifier])
model = pipeline.fit(train)
7.-转换测试数据集:
predictions = model.transform(test)
8.-输出按预测分组的测试结果:
predictions.select("prediction", "label", "features").groupBy("prediction").count().show()
如你所见,结果总是0。我尝试了多个特征变体,希望减少噪音,也尝试了不同的来源和推断模式,没有运气和相同的结果。
常见问题
- 如上所述,当前设置是否正确?
- 在原始
Dataframe
上填充的null
值是否可能是无法有效执行预测的原因? - 在上面显示的屏幕截图中,有些功能看起来是
tuple
的形式,而另一些是list
的形式,为什么?我猜这可能是一个可能的错误来源。(它们是密集和稀疏向量的表示)
3条答案
按热度按时间o2gm4chl1#
看来你的特性
[N1, N2, ...]
是字符串。你想把你所有的特征都转换成FloatType()
或者类似的东西。谨慎的做法是fillna()
after 型铸造。s5a0g9ez2#
您的训练数据集高度不平衡。
通过预测每条记录都有一个标签0,你的模型可以达到98的准确度。78%(896389/907455),如您所述,该方法不起作用,因为它完全无法识别标签=1的样本。
要创建一个更好的训练数据集,使样本在两个输出标签中的分布更加平衡,您可以使用两种方法。.
1.对多数类进行低采样,e。g仅取11,000个随机样本(标签= 0),取11,000个样本(标签= 0)
1.对minority类进行过采样,创建label = 1的数据副本。
在这种情况下,您的少数类样本只有1。大多数类样本的2%,因此简单地复制数据将导致其自身的过拟合问题。您可以考虑将SMOTE用于合成少数过采样。
xriantvc3#
高度不平衡的数据集。
上采样少数类、下采样多数类或两者。
SMOTE可以提供帮助,synthetic data将使它更好。