作者 | hecongqing

来源 | AI算法之心(ID:AIHeartForYou)

【导读】PySpark作为工业界常用于处理大数据以及分布式计算的工具,特别是在算法建模时起到了非常大的作用。PySpark如何建模呢?这篇文章手把手带你入门PySpark,提前感受工业界的建模过程!

任务简介  在电商中,了解用户在不同品类的各个产品的购买力是非常重要的!这将有助于他们为不同产品的客户创建个性化的产品。在这篇文章中,笔者在真实的数据集中手把手实现如何预测用户在不同品类的各个产品的购买行为。如果有兴趣和笔者一步步实现项目,可以先根据上一篇文章的介绍中安装PySpark,并在网站中下载数据。https://datahack.analyticsvidhya.com/contest/black-friday/数据集简介  某零售公司想要了解针对不同类别的各种产品的顾客购买行为(购买量)。他们为上个月选定的大批量产品分享了各种客户的购买汇总。该数据集还包含客户人口统计信息(age, gender, marital status, city_type, stay_in_current_city),产品详细信息(product_id and product category)以及上个月的purchase_amount总数。现在,他们希望建立一个模型来预测客户对各种产品的购买量,这将有助于他们为不同产品的客户创建个性化的产品。手把手实战项目  1. 导入数据这里我们使用PySpark的读数据接口read.csv读取数据,和pandas读取数据接口迷之相似。

from pyspark.sql import SparkSessionspark = SparkSession \    .builder \    .appName("test") \    .config("spark.some.config.option", "setting") \    .getOrCreate()    train = spark.read.csv('./BlackFriday/train.csv', header=True, inferSchema=True)test = spark.read.csv('./BlackFriday/test.csv', header=True,  inferSchema=True

2. 分析数据的类型要查看Dataframe中列的类型,可以使用printSchema()方法。让我们在train上应用printSchema(),它将以树格式打印模式。

train.printSchema()"""root |-- User_ID: integer (nullable = true) |-- Product_ID: string (nullable = true) |-- Gender: string (nullable = true) |-- Age: string (nullable = true) |-- Occupation: integer (nullable = true) |-- City_Category: string (nullable = true) |-- Stay_In_Current_City_Years: string (nullable = true) |-- Marital_Status: integer (nullable = true) |-- Product_Category_1: integer (nullable = true) |-- Product_Category_2: integer (nullable = true) |-- Product_Category_3: integer (nullable = true) |-- Purchase: integer (nullable = true)"""

3. 预览数据集在PySpark中,我们使用head()方法预览数据集以查看Dataframe的前n行,就像python中的pandas一样。我们需要在head方法中提供一个参数(行数)。让我们看一下train的前5行。

train.head(5)"""[Row(User_ID=1000001, Product_ID='P00069042', Gender='F', Age='0-17', Occupation=10, City_Category='A', Stay_In_Current_City_Years='2', Marital_Status=0, Product_Category_1=3, Product_Category_2=None, Product_Category_3=None, Purchase=8370), Row(User_ID=1000001, Product_ID='P00248942', Gender='F', Age='0-17', Occupation=10, City_Category='A', Stay_In_Current_City_Years='2', Marital_Status=0, Product_Category_1=1, Product_Category_2=6, Product_Category_3=14, Purchase=15200),  Row(User_ID=1000001, Product_ID='P00087842', Gender='F', Age='0-17', Occupation=10, City_Category='A', Stay_In_Current_City_Years='2', Marital_Status=0, Product_Category_1=12, Product_Category_2=None, Product_Category_3=None, Purchase=1422), Row(User_ID=1000001, Product_ID='P00085442', Gender='F', Age='0-17', Occupation=10, City_Category='A', Stay_In_Current_City_Years='2', Marital_Status=0, Product_Category_1=12, Product_Category_2=14, Product_Category_3=None, Purchase=1057), Row(User_ID=1000002, Product_ID='P00285442', Gender='M', Age='55+', Occupation=16, City_Category='C', Stay_In_Current_City_Years='4+', Marital_Status=0, Product_Category_1=8, Product_Category_2=None, Product_Category_3=None, Purchase=7969)]"""

要查看数据框架中的行数,我们需要调用方法count()。让我们核对一下train上的行数。Pandas和Spark的count方法是不同的。4. 插补缺失值通过调用drop()方法,可以检查train上非空数值的个数,并进行测试。默认情况下,drop()方法将删除包含任何空值的行。我们还可以通过设置参数“all”,当且仅当该行所有参数都为null时以删除该行。这与pandas上的drop方法类似。

train.na.drop('any').count(),test.na.drop('any').count()"""(166821, 71037)"""

在这里,为了填充简单,我使用-1来填充train和test的null值。虽然这不是一个很好的填充方法,你可以选择其他的填充方式。

train = train.fillna(-1)test = test.fillna(-1)

5. 分析数值特征我们还可以使用describe()方法查看Dataframe列的各种汇总统计信息,它显示了数字变量的统计信息。要显示结果,我们需要调用show()方法。

train.describe().show()"""+-------+------------------+----------+------+------+------------------+-------------+--------------------------+-------------------+------------------+------------------+------------------+-----------------+|summary|           User_ID|Product_ID|Gender|   Age|        Occupation|City_Category|Stay_In_Current_City_Years|     Marital_Status|Product_Category_1|Product_Category_2|Product_Category_3|         Purchase|+-------+------------------+----------+------+------+------------------+-------------+--------------------------+-------------------+------------------+------------------+------------------+-----------------+|  count|            550068|    550068|550068|550068|            550068|       550068|                    550068|             550068|            550068|            550068|            550068|           550068||   mean|1003028.8424013031|      null|  null|  null| 8.076706879876669|         null|         1.468494139793958|0.40965298835780306| 5.404270017525106| 6.419769919355425| 3.145214773446192|9263.968712959126|| stddev| 1727.591585530871|      null|  null|  null|6.5226604873418115|         null|         0.989086680757309| 0.4917701263173259| 3.936211369201324| 6.565109781181374| 6.681038828257864|5023.065393820593||    min|           1000001| P00000142|     F|  0-17|                 0|            A|                         0|                  0|                 1|                -1|                -1|               12||    max|           1006040|  P0099942|     M|   55+|                20|            C|                        4+|                  1|                20|                18|                18|            23961|+-------+------------------+----------+------+------+------------------+-------------+--------------------------+-------------------+------------------+------------------+------------------+-----------------+"""

上面看起来好像比较乱,这里我们选择某一列来看看。让我们从一个列中选择一个名为“User_ID”的列,我们需要调用一个方法select并传递我们想要选择的列名。select方法将显示所选列的结果。我们还可以通过提供用逗号分隔的列名,从数据框架中选择多个列。

train.select('User_ID','Age').show(5)"""+-------+----+|User_ID| Age|+-------+----+|1000001|0-17||1000001|0-17||1000001|0-17||1000001|0-17||1000002| 55+|+-------+----+only showing top 5 rows"""
6. 分析categorical特征

为了建立一个模型,我们需要在“train”和“test”中看到分类特征的分布。这里我只对Product_ID显示这个,但是我们也可以对任何分类特性执行相同的操作。让我们看看在“train”和“test”中Product_ID的不同类别的数量。这可以通过应用distinct()和count()方法来实现。

train.select('Product_ID').distinct().count(), test.select('Product_ID').distinct().count()"""(3631, 3491)"""

在计算“train”和“test”的不同值的数量后,我们可以看到“train”和“test”有更多的类别。让我们使用相减方法检查Product_ID的类别,这些类别正在"test"中,但不在“train”中。我们也可以对所有的分类特征做同样的处理。

diff_cat_in_train_test=test.select('Product_ID').subtract(train.select('Product_ID'))diff_cat_in_train_test.distinct().count()"""(46, None)"""diff_cat_in_train_test.distinct().show(5)"""+----------+|Product_ID|+----------+| P00322642|| P00300142|| P00077642|| P00249942|| P00294942|+----------+only showing top 5 rows"""

以上你可以看到46个不同的类别是在"test"中,而不在"train"中。在这种情况下,我们要么收集更多关于它们的数据,要么跳过那些类别(无效类别)的“test”。

7. 将分类变量转换为标签

我们还需要通过在Product_ID上应用StringIndexer转换将分类列转换为标签,该转换将标签的Product_ID列编码为标签索引的列。

from pyspark.ml.feature import StringIndexerplan_indexer = StringIndexer(inputCol = 'Product_ID', outputCol = 'product_id_trans')labeller = plan_indexer.fit(train)

在上面,我们将fit()方法应用于“train”数据框架上,构建了一个标签。稍后我们将使用这个标签来转换我们的"train"和“test”。让我们在labeller的帮助下转换我们的train和test的Dataframe。我们需要调用transform方法。我们将把转换结果存储在Train1和Test1中。

Train1 = labeller.transform(train)Test1 = labeller.transform(test)Train1.show(2)"""+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+|User_ID|Product_ID|Gender| Age|Occupation|City_Category|Stay_In_Current_City_Years|Marital_Status|Product_Category_1|Product_Category_2|Product_Category_3|Purchase|product_id_trans|+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+|1000001| P00069042|     F|0-17|        10|            A|                         2|             0|                 3|                -1|                -1|    8370|           766.0||1000001| P00248942|     F|0-17|        10|            A|                         2|             0|                 1|                 6|                14|   15200|           183.0|+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+only showing top 2 rows"""Train1.select('product_id_trans').show(2)"""+----------------+|product_id_trans|+----------------+|           766.0||           183.0|+----------------+only showing top 2 rows"""

上面已经显示了我们在以前的"train" Dataframe中成功的添加了一个转化后的列“product_id_trans”,("Train1" Dataframe)。8. 选择特征来构建机器学习模型首先,我们需要从pyspark.ml.feature导入RFormula;然后,我们需要在这个公式中指定依赖和独立的列;我们还必须为为features列和label列指定名称。

from pyspark.ml.feature import RFormulaformula = RFormula(formula="Purchase ~ Age+ Occupation +City_Category+Stay_In_Current_City_Years+Product_Category_1+Product_Category_2+ Gender",                   featuresCol="features",labelCol="label")

在创建了这个公式之后,我们需要将这个公式应用到我们的Train1上,并通过这个公式转换Train1,Test1。让我们看看如何做到这一点,在拟合变换train1之后,

t1 = formula.fit(Train1)train1 = t1.transform(Train1)test1 = t1.transform(Test1)train1.show(2)"""+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+--------------------+-------+|User_ID|Product_ID|Gender| Age|Occupation|City_Category|Stay_In_Current_City_Years|Marital_Status|Product_Category_1|Product_Category_2|Product_Category_3|Purchase|product_id_trans|            features|  label|+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+--------------------+-------+|1000001| P00069042|     F|0-17|        10|            A|                         2|             0|                 3|                -1|                -1|    8370|           766.0|(16,[6,10,13,14],...| 8370.0||1000001| P00248942|     F|0-17|        10|            A|                         2|             0|                 1|                 6|                14|   15200|           183.0|(16,[6,10,13,14],...|15200.0|+-------+----------+------+----+----------+-------------+--------------------------+--------------+------------------+------------------+------------------+--------+----------------+--------------------+-------+only showing top 2 rows"""

在应用了这个公式之后,我们可以看到train1和test1有两个额外的列,称为features和label,并对我们在公式中指定的列进行标记(featuresCol= features和labelCol= label)。直观上,train1和test1中的features列中的所有分类变量都被转换为数值,数值变量与之前应用ML时相同。我们还可以查看train1和test1中的列特性和标签。

train1.select('features').show(2)"""+--------------------+|            features|+--------------------+|(16,[6,10,13,14],...||(16,[6,10,13,14],...|+--------------------+only showing top 2 rows"""train1.select('label').show(2)"""+-------+|  label|+-------+| 8370.0||15200.0|+-------+only showing top 2 rows"""

9. 建立机器学习模型在应用RFormula和转换Dataframe之后,我们现在需要根据这些数据开发机器学习模型。我想为这个任务应用一个随机森林回归。让我们导入一个在pyspark.ml中定义的随机森林回归器。然后建立一个叫做rf的模型。我将使用随机森林算法的默认参数。

from pyspark.ml.regression import RandomForestRegressorrf = RandomForestRegressor()

在创建一个模型rf之后,我们需要将train1数据划分为train_cv和test_cv进行交叉验证。这里,我们将train1数据区域划分为train_cv的70%和test_cv的30%。

(train_cv, test_cv) = train1.randomSplit([0.7, 0.3])

在train_cv上建立模型,在test_cv上进行预测。结果将保存在predictions中。

model1 = rf.fit(train_cv)predictions = model1.transform(test_cv)

10. 模型效果评估让我们评估对test_cv的预测,看看rmse和mse是多少。为了评估模型,我们需要从pyspark.ml.evaluation中导入RegressionEvaluator。我们必须为此创建一个对象。有一种方法叫 evaluate for evaluator ,它对模型求值。我们需要为此指定度量标准。

from pyspark.ml.evaluation import RegressionEvaluatorevaluator = RegressionEvaluator()mse = evaluator.evaluate(predictions,{evaluator.metricName:"mse" })import numpy as npnp.sqrt(mse), mse"""(3832.4796474051345, 14687900.247774584)"""

经过计算,我们可以看到我们的rmse是3827.767295494888。现在,我们将在所有的train1数据集上再次训练一个模型。

model = rf.fit(train1)predictions1 = model.transform(test1)

预测之后,我们得到测试集预测结果,并将其保存成csv文件。

df = predictions1.selectExpr("User_ID as User_ID", "Product_ID as Product_ID", 'prediction as Purchase')df.toPandas().to_csv('./BlackFriday/submission.csv')

写入csv文件后(submission.csv)。我们可以上传我们的第一个解决方案来查看分数,我得到的分数是3844.20920145983。总结  在本文中,我以一个真实案例介绍了PySpark建模流程。这只是本系列文章的开始。在接下来的几周,我将继续分享PySpark使用的教程。同时,如果你有任何问题,或者你想对我要讲的内容提出任何建议,欢迎留言。

(*本文为AI科技大本营转载文章,转载联系原作者)

精彩推荐

2019 中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读,深入解析热门技术在行业中的实践落地。6.6 折票限时特惠(立减1400元),学生票仅 599 元!

推荐阅读

  • 12306系统的秒杀“艺术”:如何抗住100万人同时抢1万张票?

  • 实战:基于技术分析的Python算法交易

  • 90 后技术宅研发 Magi 一夜爆红,新一代知识化结构搜索新时代来了?

  • 谷歌“夜莺计划”秘密采集数百万美国人健康隐私;联发科首款7nm产能的5G芯片;2019年天猫双11落幕,最终成交额2684亿……

  • 云计算软件生态圈:摸到一把大牌

  • 女明星因自拍瞳孔倒影暴露住址惨遭跟踪,一张照片是怎么出卖你?

  • 重大利好!人民日报海外版整版报道:区块链“链”向未来,既要积极又要稳妥

  • 云计算软件生态圈:摸到一把大牌

你点的每个“在看”,我都认真当成了AI

pyspark读取csv_手把手教你实现PySpark机器学习项目——回归算法相关推荐

  1. pyspark读取csv_手把手实现 PySpark 机器学习项目回归算法

    点击上方"AI有道",选择"星标"公众号 重磅干货,第一时间送达 摘要   PySpark作为工业界常用于处理大数据以及分布式计算的工具,特别是在算法建模时起到 ...

  2. 手把手教你实现PySpark机器学习项目——回归算法

    作者 | hecongqing 来源 | AI算法之心(ID:AIHeartForYou) [导读]PySpark作为工业界常用于处理大数据以及分布式计算的工具,特别是在算法建模时起到了非常大的作用. ...

  3. 【PySpark入门】手把手实现PySpark机器学习项目-回归算法

    摘要   PySpark作为工业界常用于处理大数据以及分布式计算的工具,特别是在算法建模时起到了非常大的作用.PySpark如何建模呢?这篇文章手把手带你入门PySpark,提前感受工业界的建模过程! ...

  4. 手把手教你做关键词匹配项目(搜索引擎)---- 第九天

    第九天 回顾: 8. 手把手教你做关键词匹配项目(搜索引擎)---- 第八天 7. 手把手教你做关键词匹配项目(搜索引擎)---- 第七天 6. 手把手教你做关键词匹配项目(搜索引擎)---- 第六天 ...

  5. 手把手教你做关键词匹配项目(搜索引擎)---- 第二十一天

    客串:屌丝的坑人表单神器.数据库那点事儿 面向对象升华:面向对象的认识----新生的初识.面向对象的番外----思想的梦游篇(1).面向对象的认识---如何找出类 负载均衡:负载均衡----概念认识篇 ...

  6. 手把手教你新建一个winform项目(史上最全)

    文章目录 前言: 第1步.打开Microsoft Visual Studio(简称vs),本人这里使用的是Visual Studio 2017 专业版,如下图: 1.2 Visual Studio C ...

  7. 手把手教你做出数据可视化项目(七)可视化图表数据动态获取及界面跳转

    数据可视化前言:https://blog.csdn.net/diviner_s/article/details/115933789 Apache Echarts简介:https://blog.csdn ...

  8. 手把手教你在gitcode创建项目,并上传项目,完成项目的搭建

    文章目录 摘要 安装与配置git 下载git 安装git 注册.登录gitcode注册账号并新建项目 新建项目 命令指引 生成SSH密钥 上传文件到仓库中 摘要 GitCode 是 CSDN 为开发者 ...

  9. 百变冰冰!手把手教你实现CVPR2021最新妆容迁移算法

    作者:小潘师兄 来源:AI算法与图像处理 简介 在本文中,我们从不同的角度将妆容迁移问题分解为两步提取-分配过程.为此,我们提出了一种基于风格的可控GAN模型,该模型由三个部分组成,每个部分分别对应于 ...

最新文章

  1. centos 6.8 启动损坏修复实验
  2. 洛谷P4199 万径人踪灭(manacher+FFT)
  3. python 正则学习笔记
  4. 河南acret计算机报名,Acret, Ex Parte U.S. Supreme Court Transcript of Record with Supporting Pleadings...
  5. SAP Commerce Cloud OAuth 实现介绍
  6. python自学笔记_python学习笔记(4)
  7. Ros学习——launch文件解析
  8. 使用 TeamCity 实现持续集成(CI)
  9. java web 登录demo_JavaWeb之Servlet登录demo
  10. Touch Panel 调试技巧 01
  11. repair table accessright
  12. Pr入门系列之六:使用标记
  13. Elasticsearch应用案例1:百度
  14. android 8.0设置横幅通知,安卓微信8.0.3正式更新:新增公告横幅提醒等8大更新!...
  15. 项目js文件修改后浏览器不能及时更新的解决办法
  16. linux下截图软件,Flameshot - Linux下功能强大的屏幕截图软件
  17. 用了python之后笔记本卡了_用chrome运行的Jupyter笔记本在服务器res上卡住了
  18. PYNQ搭建系统-Petalinux上网方式
  19. html制作电影界面,电影网站界面设计HTML_CSS模板
  20. 手撸架构,Kafka 面试42问

热门文章

  1. [20180614]删除bootstrap$记录无法启动2.txt
  2. python笔记14-读取yaml配置文件(pyyaml)
  3. Springboot启动报错Error handling failed
  4. [20150705]从AWR抽取有问题的sql语句.txt
  5. poj1019(打表预处理+数学)
  6. leetcode127. Word Ladder
  7. 【VMCloud云平台】SCSM(十)服务请求到资源落地
  8. Hibernate怎么提升数据库查询的性能 (1)
  9. Proxmox VE2.2虚拟化安装配置学习笔记(三)
  10. JDK 11,Tomcat卡在Deploying web application directory