Spark-MLlib系列-上手小实验

机器学习

  • 机器学习(Machine Learning)通过算法、使用历史数据进行训练,训练完成后会产生模型。未来当有新的数据提供时,我们可以使用训练产生的模型进行预测。

一般流程

  • 一般的机器学习都是固定流程的,一般为:收集数据、输入数据、数据探索与预处理、训练、预测算法、建模、评估。

在这里插入图片描述


机器学习的架构:

  • 训练阶段
  • 预测阶段
    在这里插入图片描述

训练数据

  • 机器学习训练数据有Feature、Label组成。
  • **Feature:**数据的特征。比如:湿度、风向、风速、季节、气压。
  • **Label:**数据的标签。比如:希望预测的目标,列如:降雨(0.不会下雨、1.会下雨)、天气(1.晴天、2.雨天、3.阴天、4.下雪)、气温等等。

训练阶段和预测阶段

  • 训练阶段是过去累积的历史数据,可能时文本文件、数据库、或者其他数据来源。经过Feature Extraction(特征提取),产生Feature(数据特征)与Label(预测目标),然后经过机器学习算法的训练后产生模型。
  • 预测阶段,新输入数据,经过Feature Extraction(特征提取)产生Feature(特征数据),使用训练完成的模型进行预测,最后产生预测结果。

机器学习的分类

  • 监督学习
    • 监督学习是根据给定的标签(Label)已知的训练数据集,通过选定的算法在该训练数据集上进行训练学习,最后得到一个可以描述该数据集规律的预测函数,也就是我们所说的模型。有了模型,对于未知标签的输入数据,可以通过该预测函数预测出它的标签。典型的监督学习方法,如分类、回归等。
  • 无监督学习
    • 无监督学习是根据给定的标签(Label)未知的训练数据集,通过训练学习从训练数据集中发现隐藏的模式或结构。典型的无监督学习方法,如聚类分析。
  • 半监督学习
    • 在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据来进行预测。
  • 强化学习
    • 强化学习是人工智能中的策略学习的一种,从动物学习、参数扰动自适应控制理论发展而来。这种学习方法是从环境状态到动作映射的学习方法,使动作从环境中获得的累计奖赏值最大。通过不断地试错来学习,从而发现最优行为策略。常用的强化学习算法,如Q学习算法、SARSA算法。

机器学习的模型分类

在这里插入图片描述

  • 使用标注好的训练数据集学习一个模型
  • K-近邻、决策树
    在这里插入图片描述
  • 有训练数据集但无标签,自主推断数据
  • 主成分分析、随机森林、K-means

在这里插入图片描述

  • 介于监督学习和无监督学习之间,少量标注数据
  • 模式识别

在这里插入图片描述

  • 通过奖励函数,输入数据对模型进行反馈
  • Q-learning

Spark 机器学习库MLlib

  • Spark机器学习库目前分为两个包:spark.mllibspark.ml

  • spark.mllib 包含基于RDD的原始算法API。Spark MLlib 历史比较长,在1.0 以前的版本即已经包含了,提供的算法实现都是基于原始的 RDD

  • spark.ml 则提供了基于DataFrames 高层次的API,可以用来构建机器学习工作流(PipeLine)。ML Pipeline 弥补了原始 MLlib 库的不足,向用户提供了一个基于 DataFrame 的机器学习工作流式 API 套件。

分类算法

  • 分类算法属于监督式学习,使用类标签已知的样本建立一个分类函数或分类模型,应用分类模型,能把数据库中的类标签未知的数据进行归类。分类在数据挖掘中是一项重要的任务,目前在商业上应用最多,常见的典型应用场景有流失预测、精确营销、客户获取、个性偏好等。MLlib 目前支持分类算法有:逻辑回归、支持向量机、朴素贝叶斯和决策树。

回归算法

  • 回归算法属于监督式学习,每个个体都有一个与之相关联的实数标签,并且我们希望在给出用于表示这些实体的数值特征后,所预测出的标签值可以尽可能接近实际值。MLlib 目前支持回归算法有:线性回归、岭回归、Lasso和决策树。

聚类算法

  • 聚类算法属于非监督式学习,通常被用于探索性的分析,是根据“物以类聚”的原理,将本身没有类别的样本聚集成不同的组,这样的一组数据对象的集合叫做簇,并且对每一个这样的簇进行描述的过程。它的目的是使得属于同一簇的样本之间应该彼此相似,而不同簇的样本应该足够不相似,常见的典型应用场景有客户细分、客户研究、市场细分、价值评估。MLlib 目前支持广泛使用的KMmeans聚类算法。

协同过滤

  • 协同过滤常被应用于推荐系统,这些技术旨在补充用户-商品关联矩阵中所缺失的部分。MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,并且这些因子也用于预测缺失的元素。

本地向量

(1)本地向量:Mllib支持两种类型的本地向量:密集向量(dense)和稀疏向量(sparse)。密集向量只有一个浮点数组组成,而一个稀疏向量必须有索引和一个浮点向量组成。例如,(2.1,3.2,4.3)代表一个密集向量。(3,[1.1,2.3],[5.6,4.3,4.4])代表一个稀疏向量。

转换器

(2)Transformer:翻译成转换器,是一种可以将一个DataFrame转换为另一个DataFrame的算法。比如一个模型就是一个 Transformer。它可以把一个不包含预测标签的测试数据集 DataFrame 打上标签,转化成另一个包含预测标签的 DataFrame。 技术上,Transformer实现了一个方法transform(),它通过附加一个或多个列将一个DataFrame转换为另一个DataFrame

评估器

(3)Estimator:翻译成估计器或评估器,它是学习算法或在训练数据上的训练方法的概念抽象。在 Pipeline 里通常是被用来操作 DataFrame 数据并生成一个 Transformer。从技术上讲,Estimator实现了一个方法fit(),它接受一个DataFrame并产生一个转换器。比如,一个随机森林算法就是一个 Estimator,它可以调用fit(),通过训练特征数据而得到一个随机森林模型。

参数

(4)Parameter:所有Transformers和Estimators现在共享一个用于指定参数的通用API

代码研读

阅读并运行以下代码,请对输出的label,prob,prediction的意义进行说明。

from __future__ import print_function
 
# $example on$
from pyspark.ml.linalg import Vectors
from pyspark.ml.classification import LogisticRegression
# $example off$
from pyspark.sql import SparkSession
 
if __name__ == "__main__":
    spark = SparkSession\
        .builder\
        .appName("EstimatorTransformerParamExample")\
        .getOrCreate()
 
    # label 列为标记,features 是特征向量
    training = spark.createDataFrame([
        (1.0, Vectors.dense([0.0, 1.1, 0.1])),
        (0.0, Vectors.dense([2.0, 1.0, -1.0])),
        (0.0, Vectors.dense([2.0, 1.3, 1.0])),
        (1.0, Vectors.dense([0.0, 1.2, -0.5]))], ["label", "features"])
 
    # 创建一个逻辑回归算法,算法是 Estimator.
    # maxIter 最大迭代次数,regParam 是正则化参数
    lr = LogisticRegression(maxIter=10, regParam=0.01)
    # Print out the parameters, documentation, and any default values.
    # print("LogisticRegression parameters:\n" + lr.explainParams() + "\n")
 
    # 算法是一个Estimator,学习训练数据以后,会返回一个模型,模型是Transformer
    model1 = lr.fit(training)
 
    #下面两行去掉注释,会打印model1的相关参数
    #print("Model 1 was fit using parameters: ")
    #print(model1.extractParamMap())
 
    # paramMaps可以调整算法的参数,是字典类型
    paramMap = {lr.maxIter: 20}
    paramMap[lr.maxIter] = 30  # Specify 1 Param, overwriting the original maxIter.
    #调整了算法正则系数regParam,和判断概率阈值
    paramMap.update({lr.regParam: 0.1, lr.threshold: 0.55})  # Specify multiple Params.
 
    #你可以通过合并字典修改参数。
    paramMap2 = {lr.probabilityCol: "probability"}  # 这个可以修改预测列名称
    paramMapCombined = paramMap.copy()
    paramMapCombined.update(paramMap2)
 
    # 调整参数以后再学习一个新的模型
    # paramMapCombined overrides all parameters set earlier via lr.set* methods.
    model2 = lr.fit(training, paramMapCombined)
     #下面两行去掉注释,会打印model2的相关参数
    #print("Model 2 was fit using parameters: ")
    #print(model2.extractParamMap())
 
    # 测试数据
    test = spark.createDataFrame([
        (1.0, Vectors.dense([-1.0, 1.5, 1.3])),
        (0.0, Vectors.dense([3.0, 2.0, -0.1])),
        (1.0, Vectors.dense([0.0, 2.2, -1.5]))], ["label", "features"])
 
    predictions = (model1.transform(test),model2.transform(test))
 
    
    for prediction in predictions:
        result = prediction.select("features", "label", "probability", "prediction").collect()
        for row in result:
            print("features=%s, label=%s -> prob=%s, prediction=%s "
              % (row.features, row.label, row.probability, row.prediction))
        print("\n")
 
    spark.stop()


欢迎各位把意义说明回复在评论区哦!~~~

上手实验-协同过滤算法-电影推荐

  • Spark Mllib支持ALS(Alternating Least Squares)(交替最小二乘) 推荐算法,是使用交替最小二乘求解的一个协同过滤常用的算法。通过观察所有用户给产品的评价来推断每个用户的喜好,并向用户推荐适合的多个产品,也可以把某一个产品推荐给多个用户。(基于用户的协同过滤算法、基于物品的协同过滤算法

ALS

  • 要使用ALS 算法,要有一个评分RDD(Rating RDD),这个RDD的格式为(userid,productid,rating)。即包含一个用户ID,一个产品ID和一个评分
  • ALS返回值是一个MaxtrixFactorizationModel对象。可以调用predict()来对一个由(useid,productid)对组成的RDD进行评分。也可以使用recommendProducts(useid,numproducts)来为一个给定用户找到最值得推荐的前numproducts个产品。还可以使用recommendUsers(productid,numusers)来为一个给定产品找到最值得推荐的前numusers个用户。

推荐系统–实例

  • 为了方便展示算法的性能,这里使用组名的MovieLens公开数据集,他由美国明尼苏达大学的GroupLens项目组收集,网址http://files.grouplens.org/datasets/movielens,下载ml-100k.zip压缩文件,解压缩后一共由23个文件。
    在这里插入图片描述
  • 搜索数据
    解压数据unzip -j ml-100k.zip
    在这里插入图片描述
    在这里插入图片描述
  • 数据解读
    • u.data:完整的数据集文件,包含943位用户对1682部电影的100000评分,每个用户至少对20部电影评分。文件的每行是一个用户对一个电影的评分数据,数据间用‘\t’分割。顺序为:用户id、电影id、评分、时间戳
    • u.item:关于电影的信息。由“|”字符分割,顺序为:电影id、电影标题、发布日期、视频发布日期、IMDb URL、未知、动作片、儿童片、。。。最后19个字段是影片流派,1表示属于该流派,0表示不属于。

【实验要求】
1、 使用协同过滤算法训练模型
2、 调用模型根据用户id和电影推荐的数量进行推荐

【实验环境】
• 操作系统:Linux
• Spark2.x
• PyCharm 或 Jupyter Notebook

【实验数据】
在这里插入图片描述
https://pan.baidu.com/s/1B9vjxCq-lRfnscihXkPGaA#提取码:9fy2

【实验步骤】
MovieLens数据集包含多个用户对多部电影的评级数据,也包括电影元数据信息和用户属性信息。这个数据集经常用来做推荐系统,机器学习算法的测试数据集。尤其在推荐系统领域,很多著名论文都是基于这个数据集的。
下载后解压文件,本实验使用其中三个文件,用户信息、影片信息、评分数据。

from pyspark import SparkContext
from pyspark.sql import SQLContext, Row, SparkSession
from pyspark.sql import Row
from pyspark.mllib.recommendation import ALS 
#导入 Spark 机器学习包: 协同过滤算法(需要之前安装好numpy)

#退出已有的sc
sc.stop()
#不能一次性开多个sc(SparkContext),因为之前已经存在一个Spark Contexts,所以再创建一个新的sc会报错。
sc = SparkContext("spark://master:7077", "movietitle")

#读取用户数据
inputFile1 = '/home/hadoop/spark-MLlib/u.user'
user_df = sc.textFile(inputFile1)


#为用户数据添加 schema
user_rdd=user_df.map(lambda x:x.split('|')).map(lambda x:Row(id=x[0],age=x[1],sex=x[2],job=x[3],code=x[4]))
print(user_rdd.take(5))

#创建用户 dataframe
sqlContext = SparkSession.builder.getOrCreate()
user_df=sqlContext.createDataFrame(user_rdd)

#注册临时表
user_df.registerTempTable("user")
sqlContext.sql('select id,age,sex,job,code from user').show()


#读取评分数据
inputFile2 = '/home/hadoop/spark-MLlib/u.data'
rating_df = sc.textFile(inputFile2)


#为评分数据添加 schema
rating_rdd=rating_df.map(lambda x:x.split()).map(lambda x:Row(user_id=x[0],film_id=x[1],rating=x[2],time=x[3]))
print(rating_rdd.take(5))

#创建评分 dataframe
rating_df=sqlContext.createDataFrame(rating_rdd)

#注册评分临时表
rating_df.registerTempTable('rating')
sqlContext.sql("select user_id,film_id,rating,time from rating").show()


#读取电影信息
inputFile3 = '/home/hadoop/spark-MLlib/u.item'
film_df = sc.textFile(inputFile3)


#为电影数据添加 schema
film_rdd=film_df.map(lambda x:x.split('|')).map(lambda x:Row(id=x[0],title=x[1],post_time=x[2],url=x[4]))
print(film_rdd.take(5))

#创建电影 dataframe
film_df=sqlContext.createDataFrame(film_rdd)

#注册电影临时表
film_df.registerTempTable('film')
sqlContext.sql('select * from film').show()

#ALS.trainImplicit 中第一个参数 RDD 是固定格式( 用户编号, 电影编号, 评分值)
rdd=rating_rdd.map(lambda x:(x[3],x[0],x[1]))
rdd.take(5)


#训练模型,其中ALS.train()函数的4个参数分别是训练用的数据集,特征数量,迭代次数,和正则因子。
model=ALS.train(rdd,10,10,0.01)

#使用模型进行推荐, 参数为用户 id, 推荐个数
user_film=model.recommendProducts(112,3)
print(user_film)

#显示推荐电影名称
for film in user_film:
 sqlContext.sql("select id ,title,post_time,url , "+str(film[2])+" as similar from film where id="+str(film[1])).show()

#查看用户看过的电影
sqlContext.sql("select a.user_id,b.title from rating a,film b where a.film_id=b.id and a.user_id=112").show()

小结&后续

  • 熟悉SparkMLlib的常用操作,熟悉协同过滤算法的原理,更好的理解推荐算法的应用场景。
  • Spark-MLlib示例到此尾声,如有纰漏,欢迎各位指出~
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Klingx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值