Duncan's Blog


  • menu.主页

  • menu.分类

  • menu.关于

  • menu.归档

  • menu.标签
Duncan's Blog

Spark笔记

Veröffentlicht am 2019-09-23 | in Learning

Spark笔记

1.数据结构方式

RDD是Spark处理数据的数据结构,可以通过两种方式加载数据创建RDD

  • 从程序中parallelize一种现有的数据:如Array
  • 从外部读取文件:CSV,Hive等

2.RDD操作类型

2.1 RDD的计算方式是lazy加载,即用的时候再计算。

2.2 如果一个变量需要经常使用,可以持久化persist

2.3 封装函数有多种方式:

  • 封装静态方法,创建object
  • 封装方法以及变量参数等等,创建class

2.3 常用转换方法

Transformation Meaning
map(func) Return a new distributed dataset formed by passing each element of the source through a function func.
filter(func) Return a new dataset formed by selecting those elements of the source on which funcreturns true.
flatMap(func) Similar to map, but each input item can be mapped to 0 or more output items (so func should return a Seq rather than a single item).
mapPartitions(func) Similar to map, but runs separately on each partition (block) of the RDD, so func must be of type Iterator => Iterator when running on an RDD of type T.
mapPartitionsWithIndex(func) Similar to mapPartitions, but also provides func with an integer value representing the index of the partition, so func must be of type (Int, Iterator) => Iterator when running on an RDD of type T.
sample(withReplacement, fraction, seed) Sample a fraction fraction of the data, with or without replacement, using a given random number generator seed.
union(otherDataset) Return a new dataset that contains the union of the elements in the source dataset and the argument.
intersection(otherDataset) Return a new RDD that contains the intersection of elements in the source dataset and the argument.
distinct([numPartitions])) Return a new dataset that contains the distinct elements of the source dataset.
groupByKey([numPartitions]) When called on a dataset of (K, V) pairs, returns a dataset of (K, Iterable) pairs. Note: If you are grouping in order to perform an aggregation (such as a sum or average) over each key, using reduceByKey or aggregateByKey will yield much better performance. Note: By default, the level of parallelism in the output depends on the number of partitions of the parent RDD. You can pass an optional numPartitions argument to set a different number of tasks.
reduceByKey(func, [numPartitions]) When called on a dataset of (K, V) pairs, returns a dataset of (K, V) pairs where the values for each key are aggregated using the given reduce function func, which must be of type (V,V) => V. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.
aggregateByKey(zeroValue)(seqOp, combOp, [numPartitions]) When called on a dataset of (K, V) pairs, returns a dataset of (K, U) pairs where the values for each key are aggregated using the given combine functions and a neutral “zero” value. Allows an aggregated value type that is different than the input value type, while avoiding unnecessary allocations. Like in groupByKey, the number of reduce tasks is configurable through an optional second argument.
sortByKey([ascending], [numPartitions]) When called on a dataset of (K, V) pairs where K implements Ordered, returns a dataset of (K, V) pairs sorted by keys in ascending or descending order, as specified in the boolean ascending argument.
join(otherDataset, [numPartitions]) When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (V, W)) pairs with all pairs of elements for each key. Outer joins are supported through leftOuterJoin, rightOuterJoin, and fullOuterJoin.
cogroup(otherDataset, [numPartitions]) When called on datasets of type (K, V) and (K, W), returns a dataset of (K, (Iterable, Iterable)) tuples. This operation is also called groupWith.
cartesian(otherDataset) When called on datasets of types T and U, returns a dataset of (T, U) pairs (all pairs of elements).
pipe(command, [envVars]) Pipe each partition of the RDD through a shell command, e.g. a Perl or bash script. RDD elements are written to the process’s stdin and lines output to its stdout are returned as an RDD of strings.
coalesce(numPartitions) Decrease the number of partitions in the RDD to numPartitions. Useful for running operations more efficiently after filtering down a large dataset.
repartition(numPartitions) Reshuffle the data in the RDD randomly to create either more or fewer partitions and balance it across them. This always shuffles all data over the network.
repartitionAndSortWithinPartitions(partitioner) Repartition the RDD according to the given partitioner and, within each resulting partition, sort records by their keys. This is more efficient than calling repartition and then sorting within each partition because it can push the sorting down into the shuffle machinery.

3.创建DataFrame的三种方式

  • 使用toDF函数

  • 使用createDataFrame函数

  • 通过文件直接创建

4.scala的vector和spark包中vector不一样

5.Spark优化:(美团Spark)

基础版:https://tech.meituan.com/2016/04/29/spark-tuning-basic.html

高级版:https://tech.meituan.com/2016/05/12/spark-tuning-pro.html

6.Spark保留运行环境(用于查错)

1
conf.spark.yarn.preserve.staging.files=true

7.宽依赖和窄依赖

  • 窄依赖:指父RDD的每个分区只被一个子RDD分区使用,子RDD分区通常只对应常数个父RDD分区。(map、filter、union操作)。
  • 宽依赖:指父RDD的每个分区都有可能被多个子RDD分区使用,子RDD分区通常对应父RDD所有分区。(groupByKey、partitionBy等操作)
  • 比较:宽依赖通常对应着shuffle操作,需要在运行的过程中将同一个RDD分区传入到不同的RDD分区中,中间可能涉及多个节点之间数据的传输。

8.ORC格式和PARQUET格式文件对比

impala暂时不支持orc格式的表查询

9.left anti join(某个字段过滤用)

  • left semi join —> exists
  • left anti join —> not exists

10.Shuffle过程数据倾斜

和Hive中类似,数据的倾斜都发生在shuffle过程中,下面以hive的shuffle进行总结。发生倾斜的根本原因在于,shuffle之后,key的分布不均匀,使得大量的key集中在某个reduce节点,导致此节点过于“忙碌”,在其他节点都处理完之后,任务的结整需要等待此节点处理完,使得整个任务被此节点堵塞。

要解决此问题,主要可以分为两大块:

  • 一是尽量不shuffle;
  • 二是shuffle之后,在reduce节点上的key分布尽量均匀。

方案总结如下:


解决方案:MapJoin,添加随机前缀,使用列桶表

  • mapjoin
1
2
3
-- mapjoin配置
set hive.auto.convert.join = true;
set hive.mapjoin.smalltable.filesize=25000000;
  • 手动分割成两部分进行join
1
2
3
4
5
6
7
8
9
10
11
12
select t1.*
from t1 join t2 on t1.key=t2.key
拆成以下SQL:
select t1.*
from t1 join t2 on t1.key=t2.key
where t1.key=A
union all
select t1.*
from t1 join t2 on t1.key=t2.key
where t1.key<>A
  • 当小表不是很小,不太方便用mapjoin,大表添加N中随机前缀,小表膨胀N倍数据
  • 使用Skewed Table 或者 List Bucketing Table
Duncan's Blog

Scala笔记

Veröffentlicht am 2019-09-23 | in Learning

Scala笔记

1.四种操作符的区别和联系

  • :: 该方法成为cons,表时构造,向队列头部加入元素。x::list表示向list头部加入元素。(列表构造:

    1
    2::1::2::"bar"::"foo" 表示List[Any]= (2,1,2,bar,foo)
  • :+和+:表示分别在尾部加入元素和在头部加入元素。

  • ++ 表示连接两个集合

  • ::: 该方法只能用于连接两个list类型的集合

2.日期操作(经常用到,所以记录下)

  • 获取今天0点时间戳

    1
    2
    val dateFormat = new SimpleDateFormat("yyyy-MM-dd")
    val cur = dateFormat.parse(dateFormat.format(new Date())).getTime
  • 日期格式转时间戳

    1
    2
    3
    val dateFormat = new SimpleDateFormat("yyyy-MM-dd")
    //val dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss")
    val timestamp = dateFormat.parse(dateFormat.format(new Date())).getTime
  • 时间戳转日期

    1
    2
    val dateFormat = new SimpleDateFormat("yyyy-MM-dd")
    val date = dateFormat.format(new Date())

3.删除目录或文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.File
def dirDel(path: File) {
if (!path.exists())
return
else if (path.isFile()) {
path.delete()
return
}
val file: Array[File] = path.listFiles()
for (d <- file) {
dirDel(d)
}
path.delete()
}
if(Files.exists(Paths.get(path))) {
// 先删除目录里的文件
dirDel(Paths.get(path).toFile)
}
Duncan's Blog

Redis学习

Veröffentlicht am 2019-09-23 | in Learning

Redis

1、为什么使用Redis数据库

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

2.数据类型

  • string

  • hash:键值对的集合

    hashset1 key1 val1 key2 val2```
    1
    2
    ```HGET hashset1 key1
  • list

    list1 val1```
    1
    2
    3
    4
    * set
    ```sadd set1 val1
    set1```
    1
    2
    3
    4
    * zset(有序集合,带分数)
    ```zadd key score memeber

3.set和hset区别

  • set 就是普通的已key-value 方式存储数据,可以设置过期时间。时间复杂度为 O(1)
  • hset 则是以hash 散列表的形式存储。超时时间只能设置在 大 key 上,单个 filed 则不可以设置超时

使用场景对比:set 存储单个大文本非结构化数据,hset 则存储结构化数据,一个 hash 存储一条数据,一个 filed 则存储 一条数据中的一个属性,value 则是属性对应的值。

4.Scan操作,keys()操作,线上谨慎使用

scan操作取N条出来进行scan,并保持prefix

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public HashSet<String> getKeysByScan(String pattern) {
ScanParams scanParams = new ScanParams().count(1000).match(pattern);
HashSet<String> allKeys = new HashSet<>();
cluster.getClusterNodes().values().forEach((pool) -> {
String cur = ScanParams.SCAN_POINTER_START;
do {
try (Jedis jedis = pool.getResource()) {
ScanResult<String> scanResult = jedis.scan(cur, scanParams);
allKeys.addAll(scanResult.getResult());
cur = scanResult.getStringCursor();
}
} while (!cur.equals(ScanParams.SCAN_POINTER_START));
});
return allKeys;
}
Duncan's Blog

Flink学习记录

Veröffentlicht am 2019-09-05 | in Streaming Data

Flink笔记

1.数据集类型

  • 有界数据集:具有时间边界,在处理过程中数据一定会在某个时间范围内起始和结束。提供DataSet API
  • 无界数据集: 数据从一开始就一直持续产生的。提供DataStream API

2.Flink编程接口

  • Flink SQL
  • Table API:在内存中的DataSet和DataStream基础上加上Schema信息,将数据类型抽象成表结构
  • DataStream API和DataSet API
  • Stateful Stream Process API

3.程序结构

  • 设定运行环境:

    • env = StreamExecutionEnvironment.getExecutionEnvironment```
      1
      2
      * ```/*设置并行度为5*/val env = StreamExecutionEnvironment.createLocalEnvironment(5)
    • 1
      val env = StreamExecutionEnvironment.createRemoteEnvironment("JobManagerHost",6021,5,"/user/application.jar")
  • 初始化数据:

    将外部数据转换成DataStream或者DataSet

  • 执行转换逻辑:

    • 复杂的逻辑通过实现MapFunction接口,然后调用map()方法将实现类传入
    • 匿名函数
    • RichFunction接口
  • 分区key指定

  • 根据第一个字段分区,根据第二个字段求和

    val result = DataStream.keyBy(0).sum(1)

  • 输出结果

    • 基于文件输出
    • 基于控制台输出
    • Connector
  • 程序触发

    调用ExecutionEnvironment的execute()

4.数据类型

  • 原生数据类型
  • Tuple2元组类型
  • Scala case class类型
  • POJOs类型:复杂数据结构类型
  • Flink Value类型:IntValue、DoubleValue、StringValue
  • 特殊数据类型:List,Map、Etither、Option、Try

5.DataStream API

  • DataSource
    • 内置数据源
      • 文件数据源
      • Socket数据源
      • 集合数据源
    • 外置数据源
      • Kafka
  • Transformation
    • 单DataFrame操作:Map、FlatMap、Filter、KeyBy、Reduce、Aggregation函数(min、max、sum)
    • 多DataFrame操作:Union、Connect、CoMap、CoFlatMap、Split、Select、Iterate
  • DataSink
    • 文件系统
    • Kafka
    • Apache Cassandra
    • HDFS
    • RabbitMQ

6.时间概念

  • Event Time(事件生成时间)
  • Ingestion Time(事件接入时间)
  • Process Time(事件处理时间)

    — 再记录(2019-09-05)

Duncan's Blog

FM & FFM & DeepFM

Veröffentlicht am 2019-08-18 | in MachineLearning

模型表示为:因子分解机(Factorization Machine)

1.概念

在如广告点击预测问题中,根据用户画像、广告位以及一些其他特征来预测用户是否会点击广告。当对离散特征进行One-hot编码后,将出现特征维度爆炸,而且特征数据较稀疏。因此,FM最大的特点是对于稀疏的数据具有很好的学习能力。


可以处理以下三类问题:

  • 回归问题:使用最小均方误差作为优化标准
  • 二分类问题:加一个激活函数,如sigmoid或tanh函数等
  • 排序问题:按照预测分数召回

2.优点

  • 可以在非常稀疏的数据中进行合理的参数估计
  • 在FM模型的复杂度是线性的
  • FM是一个通用模型,可以应用于任何特征为实值的情况

3.为什么有效?模型细节

  • 在一般的线性模型中,各个特征独立考虑的,没有考虑到特征与特征之间的相互关系。但实际上,大量的特征之间是有关联的。

    举例:电商中,男性购买啤酒较多,女性购买化妆品较多,性别与购买类别之间存在关联。

  • 模型

    • 一般的线性模型为

    • 对于度为2的因子分解机模型为:

      ,其中,$$表示两个大小为$k$的向量之间的点积。与线性模型相比,FM的模型多了后面特征组合的部分。

  • 如何求解?

    对每一个特征分量$xi$构造一个辅助向量$v_i=(v{i1},v{i2},…,v{ik})$,利用$v_iv_j^T$对交叉项的$w{ij}$进行估计。

  • K的选取?

    k越大能够解释的特征维度越高,但是k的选取不宜太大。

  • 为什么求解模型复杂度是线性的?

    1566111191953

  • 求解过程

    使用随机梯度下降方式求解


局部感知因子分解机(FFM)

1.基于FM改进之处

特征One-hot之后过于稀疏,因此,同一个categorical特征经过One-hot编码之后生成的数值特征可以放到同一个field。

因此在FFM中,每一维特征都会针对其他特征的每个field,分别学习一个隐变量,该隐变量不仅与特征相关,也与field相关。假设样本的$n$个特征属于$f$个field,那么FFM的二次项有$nf$个隐向量。而在FM模型中每一维特征的隐向量只有一个。如果隐向量的长度为$k$,那么FFM的二次项参数有$nfk$个,远多于FM的$nk$个。

2.模型

3.求解

随机梯度下降,同FM

4.应用

为了使用FFM方法,所有的特征必须转换成“field_id:feat_id:value”格式,field_id代表特征所属field的编号,feat_id是特征编号,value是特征的值。


DeepFM

1.概念

DeepFM目的是同时学习低阶和高阶的特征交叉,主要由FM和DNN两部分组成,底部共享同样的输入。模型可以表示为:

这里的低阶和高阶指的是特征组合的维度,虽然FM理论上可以对高阶特征组合进行建模,但实际上因为计算复杂度原因,一般都只用到了二阶特征组合。因此,FM负责二阶特征组合,DNN负责高阶特征的组合。

2.优势

  • 同时结合高阶和低阶特征组合(FM+DNN)
  • 端到端模型,无需特征工程(DNN)
  • 共享相同的输入和embedding参数,训练高效(借助FFM来做预训练,得到embedding后的向量)
  • 评估模型时,用到了新的指标“Gini Normalization”
Duncan's Blog

ubuntu下sublime中文输入问题

Veröffentlicht am 2019-08-17 | in Note

ubuntu下安装的sublime text中文不能输入问题:

a.保存下面的代码到文件sublime_imfix.c(位于~目录)

#include”gtk/gtkimcontext.h”
void gtk_im_context_set_client_window (GtkIMContext context, GdkWindow window)
{
GtkIMContextClass *klass;
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
klass = GTK_IM_CONTEXT_GET_CLASS (context);
if (klass->set_client_window)
klass->set_client_window (context, window);
g_object_set_data(G_OBJECT(context),”window”,window);
if(!GDK_IS_WINDOW (window))
return;
int width = gdk_window_get_width(window);
int height = gdk_window_get_height(window);
if(width != 0 && height !=0)
gtk_im_context_focus_in(context);
}

b.将上一步的代码编译成共享库libsublime-imfix.so,命令

gcc -shared -o libsublime-imfix.so sublime_imfix.c pkg-config --libs --cflags gtk+-2.0 -fPIC
注意:如果提示 gtk/gtkimcontext.h:没有那个文件或目录,那就是没有相关的依赖软件,安装命令:

sudo apt-get install build-essential libgtk2.0-dev

c.将libsublime-imfix.so拷贝到sublime_text所在文件夹

sudo mv libsublime-imfix.so /opt/sublime_text/

d.修改文件/usr/bin/subl的内容

sudo gedit /usr/bin/subl
将

#!/bin/sh

exec /opt/sublime_text/sublime_text “$@”

修改为

#!/bin/sh

LD_PRELOAD=/opt/sublime_text/libsublime-imfix.so exec /opt/sublime_text/sublime_text “$@”

原文链接:http://www.jianshu.com/p/1f3a3e4f4e92

Duncan's Blog

Twitter用户数据Profiling

Veröffentlicht am 2019-08-17 | in Paper

1.概念

数据摘要:One of the crucial requirements before comsuming datasets for any application is to understand the dataset at hand and its metadata.[1]
Data profiling is the set of activities and processes to determine the meta-data about a given dataset.[1]

总体地说,数据概要可以描述为是能够描述原样本数据的一个子集或者结果.比较简单地一种方式是计算平均值,总和或者统计频率最高的一些值等等方式.而较为有挑战性的是,在多列数据中找出其之间的相互函数或次序依赖等等关系.

传统的数据摘要包括data exploration/data cleansing/data integration.而之后,data management和big data analytics也开始出现.

特别地,因为大数据的数据量大,多样性等特性,传统的技术对于其查询,存储及聚合都是花费高昂的.所以,data profiling在这里就显得非常重要.

Data profiling is an important preparatory task to determine which data to mine, how to import data into various tools, and how to interpret the results.[1]

Data Profiling

Data Profiling和Data Mining的比较

1.Distinction by the object of analysis:Instance vs. schema or column vs. rows
2.Distinction by the goal of the task:Description of existing data vs. new insights beyond existing data .

2.动机或用例

Data Profiling的目的:

  • Data Exploration
  • Database management
  • Database reverse engineering
  • Data integration
  • Big data analytics

3.方法

1.依赖关系数据库,使用SQL语句查询返回结果(不能够找出所有属性列的依赖)
单列和多列分析
2.搜索最优解:启发式算法
启发式算法是一种技术,使得可接受的计算成本内去搜寻最好的解,但不一定能保证所得到的可行解和最优解,甚至在多数情况下,无法阐述所得解同最优解的近似程度.
3.聚类算法—>筛选
4.按每一维动态规划找出子集

4.twitter数据集人物特征选取

  • 地理位置特征(反映了用户的时空分布,对于POI的推荐是有用的)
  • 活跃度特征(可用于聚类分析)
  • 影响力特征(可用于聚类分析)
  • 推文特征(反映了用户的兴趣爱好,对于推荐系统是有用的)
  • 时域特征

特征处理

1.提取
2.正则化(最典型的就是数据的归一化处理,即将数据统一映射到[0,1]区间)

常见的数据归一化方法:

  • min-max,对原始数据的线性变换
  • log函数转换
  • atan函数转换
  • z-score标准化
  • Decimal scaling小数定标标准化
  • Logistic/Softmax变换
  • Softmax函数
  • 模糊量化模式

特征选取原因:该特征代表了用户的…,对于…工作是有用的.

5.twitter data profiling思路

Motivation
聚类结果的代表性:

Even though the construction of a cluster representation is an important step in decision making, it has not been examined closely by researchers.

度量准则:

特征提取
直接:location(时区),Followers/Following,category
间接:Activity,Influence,*InterestTags

距离定义
有序属性:闵可夫斯基距离(p=2时为欧式距离)
无序属性:VDM

方法

  • 1.聚类方法(LVQ)
  • 2.定义图结构来搜索

Challenge-挑战

  • a.原集和profile子集的代表性度量准则的定义
  • b.ProfileSet的大小,k的确定
  • c.寻找ProfileSet(Representation of Clustering[2])
  • d.优化搜索算法

5.参考文献

1.Data Profiling-A Tutorial SIGMOD 2017
2.Data Clustering: A Review IEEE Computer Society

Duncan's Blog

同步到腾讯云

Veröffentlicht am 2019-08-17 | in Life

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=cibtnefnj6my

Duncan's Blog

支持向量机(Support Vector Machine)学习

Veröffentlicht am 2019-08-17 | in Seminar

支持向量机(SVM-Support Vector Machine):

定义

1.SVM是一种分类算法,是一种二类分类模型,用于解决分类和回归问题。通过寻求结构化风险最小来提高学习机泛化能力,实现经验风险和置信范围最小化,从而达到在统计样本量较少的情况下,亦能获得良好统计规律的目的。

i.e.给定一个包含正例和反例的样本集合,svm的目的是寻找一个超平面来对样本进行分割,把样本中的正例面和反例面分开,但不是简单的分开,原则是使正例和反例之间的间隔最大,鲁棒性最好。

2.基本公式:在样本空间中,划分超平面的线性方程:线性方程
样本空间中任意点x到超平面(w,b)距离为距离
假设正确分类,“间隔”为
所以,现在的目标是求得“最大间隔”
这就是SVM的基本型。

3.求“最大间隔”过程中的问题转化(转换成对偶问题)

最大 -> 最小 -> 凸二次规划|拉格朗日乘子法

线性划分 -> 非线性划分

1.问题


之前的讨论是假设样本是线性可分的,然而现实生活任务中,原始样本空间也许并不存在一个能正确划分两类样本的超平面。(如“异或问题”),对于这样的问题,可以将原始样本空间映射到一个更高维的特征空间。(Fortunately,如果原始空间是有限集,那么一定存在一个高维特征空间是样本可分。)

2.解决方案

映射后求解“最大间隔”的解

3.涉及到的问题

在求解过程中涉及计算样本Xi与Xi映射到特征空间之后的内积。由于特征空间维数可能很高,甚至可能是无穷维,因此直接计算内积通常是困难的,为了避开这个问题,设想这样一个函数-核函数
求解后得到

4.常用的核函数

软间隔与正则化

软间隔:现实任务中往往很难确定合适的核函数使训练集在特征空间中线性可分,即使恰好找到了某个核函数使训练集在特征空间中线性可分,也很难判定这个貌似线性可分的结果不是由于过拟合所造成的。

解决该问题的一个方法是允许svm在一些样本上出错。如

也就是在求解最大化间隔时,同时使不满足约束的样本尽可能少。

三种常用的替代损失函数:

共性:

支持向量回归(Support Vector Regression)

给定样本D={(x1,y1),(x2,y2),…},希望学得一个回归模型,使得f(x)与y尽可能接近,w和b是待确定参数。
传统回归模型通常直接基于模型输出f(x)与真实输出y之间的差别来计算损失,当且仅当f(x)与y完全相同时,损失才为0.与次不同,SVR假设我们能容忍f(x)与y之间最多有e的偏差,小于等于e的都算0误差。SVR问题形式化为

Duncan's Blog

支持向量机(Support Vector Machine)学习(补充)

Veröffentlicht am 2019-08-17 | in Learning

SMO算法(Sequential Minimal Optimization)

1.定义

SMO算法用于训练SVM,将大优化问题分解为多个小优化问题。这些小优化问题往往很容易求解,并且对它们进行顺序求解的结构与将它们作为整体来求解的结果是完全一致。

2.目标及原理

SMO算法的工作目标是求出一系列alpha和b,一旦求出了这些alpha,就能求出权重向量w。

每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha,那么就增大其中一个同时减少另一个。这里所谓的“合适”就是指两个alpha必须要符合一定的条件,条件之一就是这两个alpha必须在间隔边界之外,而其第二个条件则是这两个alpha还没有进行过区间化处理或者不在边界上。

3.调参

SVM中有两个参数C和K1,其中C是惩罚系数,即对误差的宽容度。C越高,说明越不能容忍出误差,容易过拟合。C越小,容易欠拟合。

k1是参数是RBF函数作为核函数后,该函数自带的一个参数,隐含的决定了数据映射到新的特征空间后的分布,k1越大,支持向量越少,k1越小,支持向量越多。支持向量的个数影响训练与预测的速度。

12…7
duncan

duncan

write something useful

70 Artikel
13 Kategorien
18 Tags
RSS
GitHub instagram music zhihu
© 2019 duncan
Erstellt mit Hexo
Theme - NexT.Pisces
| Total visited times