机器学习流程(spark 和 sklearn)
概述
人工智能发展必备三要素:数据、算法、计算力
人工智能和机器学习,深度学习的关系:
- 机器学习是人工智能的一个实现途径
- 深度学习是机器学习的一个方法发展而来
机器学习概述:从数据中自动分析获取模型,并利用模型对未知数据进行预测
需要安装:scikit-learn
机器学习流程
机器学习工作流程总结:
- 获取数据
- 数据基本处理
- 特征工程
- 模型训练 (算法阶段)
- 模型评估
评估结果达到要求,上线服务
没有达到要求,重复2-5步
数据处理和特征工程决定了机器学习的上限,而模型训练和优质算法只是为了逼近这个上限
一 获取数据(pandas)
我们的数据大部分存在于文件当中,所以pandas
会支持复杂的IO
操作,pandas
的API
支持众多的文件格式,例如CSV
,SQL
,XLS
,JSON
,HDF5
。
注:最常用的HDF5
和CSV
文件
CSV
读取CSV
数据
pandas.read_csv(filepath_or_buffer,sep =',',usecols=[])
filepath_or_buffer
:文件路径(相对路径和绝对路径均可使用)sep
:分隔符,默认用,
usecols=[]
:指定读取的列名,列表形式chunksize
:分批加载,每次加载的多少条数据iterator
:读取的数据 呈 可迭代类型 输出(可遍历)
保存数据为 CSV
文件
DataFrame对象名.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)
path_or_buf
:文件路径sep
:分隔符,默认用,
columns
:选择需要写入文件的列索引名header
:是否写入列索引,布尔值或字符串列表,默认为True
,index
:是否写入 行索引,False
为不写入行索引;读取时会将其当做一列数据而非列索引mode
:写入方式 。w
:删除原文件数据写入,a
追加写入
HDF5(二进制)
需要安装安装tables
模块,否则不能读取HDF5
文件
pip install tables
HDF5
文件可以保存多张表,因此读取和存储需要指定一个key
来 标识 DataFrom
读取格式:pandas.read_hdf(path_or_buf,key =None,** kwargs)
保存格式:pandas.to_hdf(path_or_buf,key =None,** kwargs)
path_or_buffer
:文件路径key
:保存和读取时 用来标识DataFrom
的键return
:Theselected object
注意:优先选择使用HDF5
文件存储
HDF5
在存储的时候支持压缩,使用的方式是blosc
- 速度最快,也是
pandas
默认支持的 - 使用压缩可以提磁盘利用率,节省空间
HDF5
还是跨平台的,可以轻松迁移到hadoop
上面
JSON
pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)
-
将
JSON
格式准换成默认的Pandas DataFrame
格式 -
orient
:string
,Indication of expected JSON string format
-
split
:dict like {index -> [index], columns -> [columns], data -> [values]}
split 将索引总结到索引,列名到列名,数据到数据。将三部分都分开了s='{"index":["stu1", "stu2", "stu3"],'\ '"columns":["name","age"],'\ '"data":[["xiaomaimiao", 20],["xxt", 18],["xmm", 1]]'\ '}' print(pd.read_json(s,orient='split')) 执行结果: age name stu1 20 xiaomaimiao stu2 18 xxt stu3 1 xmm
-
records
:list like [{column:value}, ... , {column:value}]
最常规s='[{"name":"xiaomaimiao","age":20},'\ '{"name":"xxt","age":18},'\ '{"name":"xmm","age":1}]' print(pd.read_json(s,orient='records')) 执行结果: age name 0 20 xiaomaimiao 1 18 xxt 2 1 xmm
-
index
:index: {columns:values, ...}...
s='{"stu1":{"name": "xiaomaimiao", "age":20},'\ '"stu2":{"name": "xxt", "age": 18},'\ '"stu3":{"name": "xmm", "age": 1},}' print(pd.read_json(s,orient='index')) 执行结果: age name stu1 20 xiaomaimiao stu2 18 xxt stu3 1 xmm
-
columns
:columns: {index:values,...}
s='{"name":{"stu1": "xiaomaimiao", "stu2": "xxt", "stu3": "xmm"},'\ '"age":{"stu1": 20, "stu2": 18 "stu3": 1}}' print(pd.read_json(s,orient='columns')) 执行结果: name age stu1 xiaomaimiao 20 stu2 xxt 18 stu3 xmm 1
-
values
:just the values array
values
直接输出值s='[["a",1],["b",2]]' print(pd.read_json(s,orient='values')) 执行结果: 0 1 0 a 1 1 b 2
-
-
lines
:boolean, 默认False
按照每行读取json
对象,json
与DataFrom
行行对应 -
typ
:默认 ‘frame’
, 指定转换成的对象类型series
或者dataframe
DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
- 将
Pandas
对象存储为json
格式 path_or_buf=None
:文件地址orient
:存储的json
形式,{‘split’,’records’,’index’,’columns’,’values’}
lines
:一个对象存储为一行
获取数据(spark)
算法中的数据一般以 数据集的形式存在:
- 数据集类似于二维表格
- 一行数据 称为 一个样本
- 一列数据 成为 一个特征
数据集分类
根据数据集中是否包含目标值和目标值类型分为:
- 连续型目标值
特征值+目标值(目标值是连续)
- 离散型目标值
特征值+目标值(目标值是离散的)
- 没有目标值
只有特征值,没有目标值
将本地数据导入spark
连接 pyspark
RDD的程序入口
1. 导入pyspark库中的SparkContext类
from pyspark import SparkContext
2. 创建SparkContext实例,并设置Spark应用的基本信息
sc = sparkContext('local','test')
源码:pyspark.SparkContext(master = None,appName = None,sparkHome = None,pyFiles = None,environment = None,batchSize = 0,
serializer = PickleSerializer(),conf = None,gateway = None,jsc = None,
profiler_cls = <class'pyspark .profiler.BasicProfiler'> )
参数:master:要连接的群集URL (例如:mesos:// host:port,spark:// host:port,local [4])
appName:您的工作的名称,将显示在群集Web UI上。
sparkHome:在群集节点上安装Spark的位置。
pyFiles:.zip或.py文件的集合,以发送到集群并添加到PYTHONPATH
这些可以是本地文件系统或HDFS,HTTP,HTTPS或FTP URL上的路径。
environment:在工作节点上设置的环境变量字典
batchSize:表示为单个的Python对象的数量Java对象。
设置1禁用批处理,
设置0以根据对象大小自动选择批处理大小
设置-1以使用无限的 批处理大小
serializer :RDD的序列化器。
conf:AL {SparkConf}对象设置Spark属性。
gateway:使用现有的网关和JVM,否则将实例化新的JVM
jsc:JavaSparkContext实例(可选)。
profiler_cls:一类用于进行概要分析的自定义Profiler
(默认为pyspark.profiler.BasicProfiler)。
DataForm的程序入口
4. 导入pyspark库中的SparkSession类
from pyspark.sql import SparkSession
5. 创建sparkSession实例,并设置Spark应用的基本信息
sparkSession实例名 = SparkSession.builder.appName("xxx").getOrCreate()
类方法:
.appName:工作名称,将显示在群集 Spark Web UI上( host:4040 )
.getOrCreate():获取一个现有的SparkSession,如果不存在,则根据此构建器中设置的选项创建一个新的。
.config(key = None,value = None,conf = None ):设置配置选项
使用此方法设置的选项会自动传播到SparkConf和SparkSession自己的配置中。
.enableHiveSupport():启用Hive支持,包括与持久性Hive Metastore的连接,对Hive Serdes的支持以及Hive用户定义的功能。
.master:要连接的群集URL (例如,mesos:// host:port,spark:// host:port,local [4])
传入local代表本地模式, local[4]代表本地模式4内核运行 , 或者spark://master:7077 提交到 standalone集群模式运行
创建 RDD 或 DataFrom
-
创建成
RDD
-
由本地或
HDFS
文件创建# 读取本地文件 sparkContext实例名.textFile("file:///xxx/xxx.txt") # sc为创建的sparkcontext对象 # 读取本地压缩包 sparkContext实例名.textFile("file:///xxx/xxx.gz") # 读取hdfs的上的文件 sparkContext实例名.textFile("hdfs://node-teach:8020/xxx/xxx.log")
支持整个目录、多文件、通配符
-
集合并行化:把
非RDD
数据转换为RDD
- 调用
SparkContext
的parallelize
方法 将 现有的可迭代对象或者集合 转化# 定义一个列表,并将列表序列化为 RDD data=[1,2,3,4,5] rdd1 = sparkContext实例名.parallelize(data, 指定分区数量)
- 分区数量 需要根据
CPU核数
指定(每个CPU核
有2-4个分区) - 若不指定分区数量,则
Spark
会自动设置分区(CPU核数*2
)
- 分区数量 需要根据
- 调用
-
-
创建
DataFrom
-
基于本地
RDD、csv、json、parquet、orc、jdbc
文件,通过sparkSession.read.数据源格式.local(数据源文件名)
生成# 基于 Java文件 生成 (两种方法,两种书写方法) 方法一:反射自动推测,适合静态数据 jsonDF = sparkSession实例名.read.json("xxx.json") jsonDF = sparkSession实例名.read.format('json').load('xxx.json') 方法二:程序指定,适合程序运行中动态生成的数据 from pyspark.sql.types import StructType, StructField # 根据json的具体数据类型指定DataFrom的Schema(两种写法) jsonSchema = StructType() \ # StructType表示的是一个对象,在json中的体现为 大括号 {} .add("id", StringType(),True) \ # (json中的键,该键对应值的数据类型,是否为空) .add("city", StringType()) \ .add("pop" , LongType()) \ .add("state",StringType()) jsonSchema = StructType([ StructField("id", StringType(), True), StructField("city", StringType(), True), StructField("loc" , ArrayType(DoubleType())), # 表示 键loc值的数据类型为数组,并且数组中的元素为 Double类型(双精度小数) StructField("pop", LongType(), True), StructField("state", StringType(), True) ]) jsonSchema = StructType() \ # 有嵌套类型的json .add("dc_id", StringType()) \ .add("source", MapType(StringType(), # 表示 键source值中嵌套了几个并列的json,其中嵌套json的键数据类型为StringType,值为StructType(......) StructType() \ .add("description", StringType()) \ .add("ip", StringType()) \ .add("id", LongType()) \ .add("geo", StructType() \ # 表示 键geo值中嵌套了一个json .add("lat", DoubleType()) \ .add("long", DoubleType()) ) ) ) jsonDF = sparkSession实例名.read.schema(jsonSchema).format('json').load('xxx.json') # json字符串的解析 explodedDF = jsonDF.select("dc_id",explode("source")) # explode("source") 表示 获取 source嵌套json内部的 key 和 value notifydevicesDS = explodedDF.select( "dc_id", "key"
-