svm的训练集预测100%是不是svm过拟合合了

SVM过拟合问题? - 知乎19被浏览2457分享邀请回答712 条评论分享收藏感谢收起使用SVM预测大盘涨跌的简单策略
我的图书馆
使用SVM预测大盘涨跌的简单策略
&本策略是为了验证SVM对于大盘涨跌的预测是否有效,相比于纯随机策略,是否有明显的提高。
SVM模型用06~14年的数据训练,16年1月~12月的数据用来回测,这样是为了避免因为在模型中投入了现阶段的数据导致的过拟合。
从结果来看,在16年的小范围下跌中,该模型表现还凑合吧……
import&numpy&as&np&&import&pandas&as&pd&&from&CAL.PyCAL&import&Date&&from&CAL.PyCAL&import&Calendar&&from&CAL.PyCAL&import&BizDayConvention&&from&sklearn&import&svm&&start&=&''&&&&&&&&&&&&&&&&&&&&&&&#&回测起始时间&&end&=&''&&&&&&&&&&&&&&&&&&&&&&&&&#&回测结束时间&&benchmark&=&'HS300'&&&&&&&&&&&&&&&&&&&&&&&&#&策略参考标准&&universe&=&set_universe('HS300')&&#&证券池,支持股票和基金&&capital_base&=&100000&&&&&&&&&&&&&&&&&&&&&&#&起始资金&&freq&=&'d'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#&策略类型,'d'表示日间策略使用日dw线回测,'m'表示日内策略使用分钟线回测&&re&&
fields&=&['tradeDate','closeIndex',&'highestIndex','lowestIndex',&'turnoverVol','CHG','CHGPct']&&2&&stock&=&'000300'&&3&&#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌&&4&&index_raw&=&DataAPI.MktIdxdGet(ticker=stock,beginDate=u"",endDate=u"",field=fields,pandas="1")&&5&&#获取日到日,上一行代码设定的所有索引的相关信息。&&6&&&&7&&index_date&=&index_raw.set_index('tradeDate')&&8&&index_date&=&index_date.dropna()&&9&&index_date['max_difference']&=&index_date['highestIndex']&-&index_date['lowestIndex']&&10&&&&11&&index_date['max_of_30day']&=&None&&12&&index_date['min_of_30day']&=&None&&13&&index_date['max_difference_of_30day']&=&None&&14&&index_date['closeIndex_after30days']&=&None&&15&&#预设需要处理的值为None,方便之后直接用dropna函数去掉无效数据&&16&&&&17&&for&i&in&xrange(len(index_date)-30):&&18&&&&&&#对数据进行处理&&19&&&&&&index_date['max_of_30day'][i+30]&=&max(index_date['highestIndex'][i:i+30])&&20&&&&&&#找出前30天最大值。&&21&&&&&&index_date['min_of_30day'][i+30]&=&min(index_date['lowestIndex'][i:i+30])&&22&&&&&&#找出前30天最小值&&23&&&&&&index_date['max_difference_of_30day'][i+30]&=&max(index_date['max_difference'][i:i+30])&&24&&&&&&#找出前30天最大日波动&&25&&&&&&index_date['closeIndex_after30days'][i]=index_date['closeIndex'][i+30]&&26&&&&&&#找出30天后的收盘价。&&27&&&&28&&index_date&=&index_date.dropna()&&&#去掉前30个和后30个无效的数据。&&29&&lables_raw&=&index_date['closeIndex_after30days']&#提取出需要预测的数据&&30&&lables&=&index_date['closeIndex_after30days']&&&index_date['closeIndex']&#为分类处理数据,判断30天后的收盘价是否大于今日收盘价&&31&&lables_ud&=&lables.replace({True:'up',False:'down'})&#方便他人阅读,将True和False改为up和down,意味着30天后收盘价涨了还是跌了&&32&&features&=&index_date.drop(['closeIndex_after30days'],axis&=&1)&#在特征值中去掉我们要预测的数据。&&
在未调参之前,我们先获取一次准确率:
from&sklearn&import&cross_validation&&from&sklearn&import&preprocessing&&scaler&=&preprocessing.StandardScaler().fit(features)&&features_scaler&=&scaler.transform(features)&&#上面两行代码用来标准化数据&&&&X_train,X_test,&y_train,&y_test&=&cross_validation.train_test_split(features_scaler,&lables,&test_size&=&0.2,&random_state&=&0)&&&&clf_svm&=&svm.SVC()&&&#使用SVM分类器来判断涨跌&&clf_svm.fit(X_train,&y_train)&&print&"预测准确率为:%0.2f"&%&(clf_svm.score(X_test,&y_test))&&
然后调C值,这里我是先让C在1~100的range跑,然后100~200……到300~400的时候发现不会进一步提高了。其实可以直接从1~1000跑一次,很快就能绘画出整个变动的图,然而我电脑渣带不动。
i_list&=&[]&&score_list&=&[]&&for&i&in&range(300,400,1):&&&&&&i=i/1.&&&&&&clf_svm&=&svm.SVC(C&=&i)&&&#使用SVM分类器来判断涨跌&&&&&&clf_svm.fit(X_train,&y_train)&&&&&&i_list.append(i)&&&&&&score_list.append(clf_svm.score(X_test,&y_test))&&&&score_list_df&=&&pd.DataFrame({'i_list':i_list,'score_list':score_list})&&score_list_df.plot(x='i_list'&,y='score_list',title='score&change&with&c')&&
然后是gamma值,和C值调参上也是同理。
i_list&=&[]&&score_list&=&[]&&for&i&in&range(100,200,1):&&&&&&i=i/100.&&&&&&clf_svm&=&svm.SVC(C=350&,&&gamma&=&i)&&&#使用SVM分类器来判断涨跌&&&&&&clf_svm.fit(X_train,&y_train)&&&&&&i_list.append(i)&&&&&&score_list.append(clf_svm.score(X_test,&y_test))&&&&score_list_df&=&&pd.DataFrame({'gamma_list':i_list,'score_list':score_list})&&score_list_df.plot(x='gamma_list'&,y='score_list',title='score&change&with&gamma')&&
虽说没什么卵用……还是假吧意思的比对一下不同核函数下的准确率吧。理所当然的是默认的高斯核表现最好。
i_list&=&[]&&score_list&=&[]&&&&kernels&&=&&['linear',&'rbf','sigmoid']&&for&i&in&kernels&:&&&&&&clf_svm&=&svm.SVC(C=350&,&gamma&=&1.8&,&kernel&=&i&)&&&&&&&&&clf_svm.fit(X_train,&y_train)&&&&&&i_list.append(i)&&&&&&score_list.append(clf_svm.score(X_test,&y_test))&&&&score_list_df&=&&pd.DataFrame({'kernels':i_list,'score_list':score_list})&&score_list_df.plot(x='kernels'&,y='score_list',title='score&change&with&kernels',kind='bar')&&
知道了大致参数最优范围以后,我们使用grisearchCV在这个范围内找到最优解。
from&sklearn.grid_search&import&GridSearchCV&&from&sklearn.cross_validation&import&ShuffleSplit&&i&=&range(100,200,1)&&params&=&{'C':range(300,400,1),'gamma':[x&/100.&for&x&in&range(100,200,1)]}&&&&#&X_train,X_test,&y_train,&y_test&=&cross_validation.train_test_split(features_scaler,&lables,&test_size&=&0.2,&random_state&=&0)&&&&clf_svm&=&svm.SVC()&&#&cv_sets&=&ShuffleSplit(X_train.shape[0],&n_iter&=&10,&test_size&=&0.20,&random_state&=&0)&&&&grid&=&GridSearchCV(clf_svm,&params&)&&grid&=&grid.fit(X_train,&y_train)&&print&grid.best_estimator_&&
然后在最优解的基础上再次计算一次准确率
from&sklearn&import&cross_validation&&from&sklearn&import&preprocessing&&scaler&=&preprocessing.StandardScaler().fit(features)&&features_scaler&=&scaler.transform(features)&&#上面两行代码用来标准化数据&&&&X_train,X_test,&y_train,&y_test&=&cross_validation.train_test_split(features_scaler,&lables,&test_size&=&0.2,&random_state&=&0)&&&&clf_svm&=&svm.SVC(C&=&300,gamma&=&1.03)&&&#使用SVM分类器来判断涨跌&&clf_svm.fit(X_train,&y_train)&&print&"预测准确率为:%0.2f"&%&(clf_svm.score(X_test,&y_test))&&
为了判断模型是否稳健,我们让训练集合处于变化中,然后观察随着训练集合的变化,准确率的波动范围图。这里采取的是数据每10个变化一次。
发现最低没有低于过0.72的准确率,波动较大在0.14左右,模型稳健度一般。
num_list&=&[]&&score_list&=&[]&&for&i&in&xrange((len(features_scaler)-1000)/10):&&&&&&num_now&=&len(features_scaler)%10&+&10*i&+1000&&&&&&X_train,X_test,&y_train,&y_test&=&cross_validation.train_test_split(features_scaler[:num_now],&lables[:num_now],&test_size&=&0.2,&random_state&=&0)&&&&&&clf_svm&=&svm.SVC(C=350,gamma&=&1.8)&&&#使用SVM分类器来判断涨跌&&&&&&clf_svm.fit(X_train,&y_train)&&&&&&num_list.append(num_now)&&&&&&score_list.append(clf_svm.score(X_test,&y_test))&&&&&&&&score_list_df&=&&pd.DataFrame({'sets_num':num_list,'accuracy':score_list})&&score_list_df.plot(x='sets_num'&,y='accuracy',title='Accuracy&with&sets')&&
接下来是比对用的空白组,纯随机策略(不控制风险,只是随机买,1.20倍卖出)
import&random&&start&=&''&&&&&&&&&&&&&&&&&&&&&&&#&回测起始时间&&end&=&''&&&&&&&&&&&&&&&&&&&&&&&&&#&回测结束时间&&benchmark&=&'HS300'&&&&&&&&&&&&&&&&&&&&&&&&#&策略参考标准&&universe&=&set_universe('HS300')&&#&证券池,支持股票和基金&&capital_base&=&100000&&&&&&&&&&&&&&&&&&&&&&#&起始资金&&freq&=&'d'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#&策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测&&refresh_rate&=&1&&&&&&&&&&&&&&&&&&&&&&&&&&&#&调仓频率,表示执行handle_data的时间间隔,若freq&=&'d'时间间隔的单位为交易日,若freq&=&'m'时间间隔为分钟&&&&def&initialize(account):&&&&&&&&&&&&&&&&&&&#&初始化虚拟账户状态&&&&&&pass&&&&features_list&=&[]&&def&handle_data(account):&&&&&&random.shuffle(account.universe)&&&&&&&#&随机化股票池一遍随机策略&&&&&&for&stock&in&account.universe:&&&&&&&&&#&股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票&&&&&&&&&&p&=&account.reference_price[stock]&&&&&&&&#&股票前一天的收盘价&&&&&&&&&&cost&=&account.security_cost.get(stock)&&#&股票的平均持仓成本&&&&&&&&&&if&not&cost:&&&&&&&&&&&&&&&&&&&&&&&&&&&#&判断当前没有买入该股票&&&&&&&&&&&&&&order_pct_to(stock,&0.10)&&&&&&&&&&#&将满足条件的股票买入,总价值占虚拟帐户的10%&&&&&&&&&&elif&cost&and&p&&=&cost&*&1.20:&&&&&&&&#&卖出条件,当p这个价格涨幅到买入价的1.20倍;&&&&&&&&&&&&&&order_to(stock,&0)&&&&&&&&#&将满足条件的股票卖到剩余0股,即全部卖出&&
然后是纯随机策略基础上,只增加一个预测盘指的涨跌,如果预测涨,则随机买入,否则不买。和纯随机策略比,的确好了一丢丢。
import&random&&2&&start&=&''&&&&&&&&&&&&&&&&&&&&&&&#&回测起始时间&&3&&end&=&''&&&&&&&&&&&&&&&&&&&&&&&&&#&回测结束时间&&4&&benchmark&=&'HS300'&&&&&&&&&&&&&&&&&&&&&&&&#&策略参考标准&&5&&universe&=&set_universe('HS300')&&#&证券池,支持股票和基金&&6&&capital_base&=&100000&&&&&&&&&&&&&&&&&&&&&&#&起始资金&&7&&freq&=&'d'&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#&策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测&&8&&refresh_rate&=&1&&&&&&&&&&&&&&&&&&&&&&&&&&&#&调仓频率,表示执行handle_data的时间间隔,若freq&=&'d'时间间隔的单位为交易日,若freq&=&'m'时间间隔为分钟&&9&&stock&=&'000300'&#预测的指数,沪深300指数。和策略参考池一致。&&10&&fields&=&['tradeDate','closeIndex',&'highestIndex','lowestIndex',&'turnoverVol','CHG','CHGPct']&&&11&&#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌&&12&&&&13&&def&initialize(account):&&&&&&&&&&&&&&&&&&&#&初始化虚拟账户状态&&14&&&&&&pass&&15&&&&16&&features_list&=&[]&&17&&def&handle_data(account):&&18&&&&&&#&生成买入列表&&19&&&&&&last_date&=&account.previous_date.strftime("%Y-%m-%d")&#获取上一个交易日日期并格式化&&20&&&&&&begin_date&=&pd.date_range(end=last_date,periods=60)[0]&#获取60日之前的交易日日期&&21&&&&&&begin_date&=&begin_date.strftime("%Y-%m-%d")&#格式化这个日期&&22&&&&&&to_class&=&DataAPI.MktIdxdGet(ticker='000300',beginDate=begin_date,endDate=last_date,field=fields,pandas="1")&&23&&&&&&to_class&=&to_class.dropna()&&24&&&&&&to_class&=&to_class[-30:]&#获取我们要的30天的指数信息&&25&&&&&&to_class_date&=&to_class.set_index('tradeDate')&&26&&&&&&to_class_date['max_difference']&=&to_class_date['highestIndex']&-&to_class_date['lowestIndex']&&27&&&&&&&&28&&&&&&to_class_date_max_of_30day&=&max(to_class_date['highestIndex'])&&29&&&&&&#找出前30天最大值。&&30&&&&&&to_class_date_min_of_30day&=&min(to_class_date['lowestIndex'])&&31&&&&&&#找出前30天最小值&&32&&&&&&to_class_date_max_difference_of_30day&=&max(to_class_date['max_difference'])&&33&&&&&&#找出前30天最大日波动&&34&&&&&&&&35&&&&&&features_for_predict&=&to_class_date[-1:]&&36&&&&&&features_for_predict['max_of_30day']&=&to_class_date_max_of_30day&&37&&&&&&features_for_predict['min_of_30day']&=&to_class_date_min_of_30day&&38&&&&&&features_for_predict['max_difference_of_30day']&=&to_class_date_max_difference_of_30day&&39&&&&&&&&40&&&&&&features_fp_scaler&=&scaler.transform(features_for_predict)&&41&&&&&&predict_up&=&clf_svm.predict(features_fp_scaler)&&42&&&&43&&&&&&#预测30天后的收盘是涨还是跌。&&44&&&&&&random.shuffle(account.universe)&&45&&&&&&for&stock&in&account.universe:&&&&&&&&&#&股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票&&46&&&&&&&&&&p&=&account.reference_price[stock]&&&&&&&&#&股票前一天的收盘价&&47&&&&&&&&&&cost&=&account.security_cost.get(stock)&&#&股票的平均持仓成本&&48&&&&&&&&&&if&predict_up&and&not&cost:&&&&&&&&&&&&&&&&&&&&&&&&#&判断当前没有买入该股票&&49&&&&&&&&&&&&&&order_pct_to(stock,&0.10)&&&&&&&&&&#&将满足条件的股票买入,总价值占虚拟帐户的10%&&50&&&&&&&&&&elif&cost&and&p&&=&cost&*&1.20:&&&&&&&&#&卖出条件,当p这个价格涨幅到买入价的1.20倍;&&51&&&&&&&&&&&&&&order_to(stock,&0)&&&&&&&&#&将满足条件的股票卖到剩余0股,即全部卖出&&
TA的最新馆藏
喜欢该文的人也喜欢您的访问出错了(404错误)
很抱歉,您要访问的页面不存在。
1、请检查您输入的地址是否正确。
进行查找。
3、感谢您使用本站,3秒后自动跳转至网站首页拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(38c70-ua98).
重新安装浏览器,或使用别的浏览器查看: 2839|回复: 1
机器学习——海量数据挖掘解决方案
主题帖子积分
问题导读:
1.机器学习分为哪几种?2.有哪几种统计分析模型?3.怎样合理调节模型参数?
大数据时代里,互联网用户每天都会直接或间接使用到大数据技术的成果,直接面向用户的比如搜索引擎的排序结果,间接影响用户的比如网络游戏的流失用户预测、支付平台的欺诈交易监测等等。达观数据技术团队开发过智能文本内容审核系统、作弊监测系统、用户建模系统等多个基于大数据技术的应用系统。机器学习是大数据挖掘的一大基础,本文以机器学习为切入点,将达观在大数据技术实践时的一些经验与大家分享。
互联网的海量数据不可能靠人工一个个处理,只能依靠计算机批量处理。最初的做法是人为设定好一些规则,由机器来执行。比如明确指定计算机给男性、30岁的用户推送汽车广告。很明显如此粗略的规则不会有好效果,因为对人群的定位不够精确。要提高精度必须增加对用户的特征描述。但特征一多规则就很难制定,即使定下了规则也没法根据实际情况灵活变化。机器学习可以很好的解决以上问题,从一定程度上赋予了计算机以“学习”的能力,使得千人千面成为可能。
000.png (1.79 MB, 下载次数: 1)
15:55 上传
图 1 面对大量的特征,人工难以确定使用的规则
有监督机器学习技术机器学习以统计学为理论基础,利用算法让机器具有类似人类一般的自动“学习”能力,即对已知的训练数据做统计分析从而获得规律,再运用规律对未知数据做预测分析。机器学习主要包含四大类别:有监督学习,无监督学习,半监督学习和增强学习。
有监督学习,顾名思义,是在“人类监督”下学习,要求训练数据既有特征也有目标,目标是人为设定好的。以文本分类为例,一篇文章的字、词、句、段是其特征(文本的内容是什么),文章的类别(时事、科技、娱乐等等)就是目标。训练集文章的类别是人为设定的,相当于明确告诉机器什么样的内容该属于什么类别,机器在此基础上总结规律。无监督学习就是数据只有特征没有目标,最常见的算法是聚类。聚类算法会把相似的样本聚集成一个子集,优点是数据无需人工标注,但缺点也很明显——无法给出子集的实际含义。半监督学习介于有监督学习和无监督学习之间,其训练集数据有一小部分是人工标注过的。增强学习强调基于环境而行动,在探索未知领域和遵从现有只是之间寻求平衡。
有监督学习的研究起步较早,方法比较成熟。在大多数应用场景中,我们希望机器输出的结果具有实际含义,比如文本分类就是让机器告诉我们一篇文章是时事还是科技类文章。这样的场景下有监督学习也更为适用。有监督学习主要包含回归分析和统计分类两大类算法。
回归分析——预估点击率的利器
回归分析建模的是自变量和因变量之间的相关关系(如图2所示),在机器学习领域,自变量是样本的特征向量,因变量是预测值。回归分析最经典的应用场景是广告点击率(CTR)预估。简单而言,CTR预估是根据用户数据和广告数据,估计用户点击某个广告的可能性大小。我们假设用户数据+广告数据和广告点击率之间的关系符合某个分布,使用回归分析方法在已有点击数据上拟合出该分布。达观科技在线上预测时就把用户数据和广告数据作为输出传给拟合出的分布,得到用户点击该广告的概率值。
001.png (27.92 KB, 下载次数: 1)
15:56 上传
图 2 回归分析示意图
统计分类——被广泛应用的机器学习方法
统计分类要解决的问题是,如何将一个样本点分到类别集合中的一个或多个类,比如图3所表示的就是将数据分为3个类。
002.png (46.87 KB, 下载次数: 1)
15:58 上传
图 3 统计分类示意图
现实场景中我们往往需要把数据分成不同的类别,以方便我们分析和使用,因而统计分类方法具有广阔的应用范围。达观数据团队开发的用户建模、内容审核系统、反作弊系统等都使用到了统计分类模型。比如反作弊系统,目的是区分用户行为是否作弊,抽象出来就是个分类问题:输入是用户的各种行为数据经过处理后得到的特征,输出只有两个类别——“作弊”和“非作弊”。接下来我就简单介绍一下最具代表性的分类算法——支持向量机(Support Vector Machine, SVM),一窥机器学习的工作原理。SVM绝不是入门级的机器学习算法,选择介绍它是因为,机器学习需要解决的数据线性不可分、过拟合等问题,SVM都给出了比较可靠的解决方案,借此我们也可以对机器学习有个大概的认识。
理想情况下SVM的理论模型
SVM针对分类问题的前提假设直观易懂,由此推演出的模型求解过程也是顺理成章一气呵成。我们通常先从最简单的情况入手,假设数据是线性可分的。SVM认为此时的最优分类面,是使得样本集到分类面的最小几何距离最大化的超平面,这个距离成为“间隔(margin)”。如图4所示,黑色实线就是最优分类面,两边两条虚线之间的几何距离就是此时的最优间隔。数据点离分类面越远,分类的置信度也越高。
003.png (155.42 KB, 下载次数: 1)
15:58 上传
图 4 SVM最优分类面示意图
SVM假设线性分类面的函数形式为
鉴于篇幅关系,我们略去推导过程。在最大化间隔的假设下,可以得到SVM的原目标函数为:
其中表示第i个样本的特征向量,是第i个样本的类标签,SVM令。由约束条件可知,样本点必然落在最优间隔的边缘(图4中虚线)上或外面,通过推导分析最终可以知道,只有落在间隔边缘上的少量数据点决定了分类面,这些样本被称为支持向量,而其他的点没有任何作用。这一特性大大节省了求解SVM的计算量。
线性不可分情况的处理
按照达观数据的经验,真实环境的问题往往是线性不可分的,数据采集的时候也不可避免的会引入噪声。应对这两种情况只需对原始SVM模型做有限的一点改进。针对数据线性不可分的情况,SVM通过引入核函数(Kernel Function)将数据映射到高维空间来解决,图5直观的表示了映射的过程。核函数实际上是两个数据点在高维空间中的内积。它先在原空间进行计算再将结果映射到高维空间,避免了先把数据点映射到高维空间再计算所可能导致的维数灾难问题。核函数可以从容的处理包括无限维在内的任何特征空间映射。
006.png (137.07 KB, 下载次数: 1)
16:08 上传
图 5 SVM核函数的作用原理图
SVM如何规避过拟合
过拟合(Overfitting)表现为在训练数据上模型的预测错误很低,在未知数据上预测错误却很高。图6的蓝色曲线代表训练错误,红色曲线代表真实错误,可以看到随着模型复杂度的升高,模型对训练数据的拟合程度越好(训练错误越低),但到了一定程度之后真实错误反而上升,即为过拟合。
007.png (10.24 KB, 下载次数: 1)
16:09 上传
图 6 过拟合
过拟合主要源于我们采集的训练样本带有噪声,有部分样本严重偏离其正常位置,统计学上称之为outlier。前面已经提到,决定SVM最优分类面的只是占少数的支持向量,如果碰巧这些支持向量中存在outlier,而我们又要求SVM尽可能完美的去拟合这样的数据,得到的分类面可能就会有问题。如图7所示,黑色加粗虚线代表最优分类面,带黑圈的蓝色数据点代表outlier。可以看到outlier严重偏离了正常蓝色数据点的位置,所在位置又恰巧使其成为了支持向量,导致了最终的分类面(深红色实线)严重偏离最优分类面。
008.png (15.2 KB, 下载次数: 1)
16:10 上传
图 7 数据噪声对SVM的影响
解决办法非常简单而巧妙, 与Vapnik为SVM引入了松弛变量(slack variable),将公式(2)的约束条件修改为:
其中即为松弛变量。从图8可以看到,引入松弛变量即容忍了outlier的偏移量,抵消了outlier对分类面的负面影响。
010.png (15.99 KB, 下载次数: 1)
16:10 上传
图 8 松弛变量的作用
但容忍也不可以是无限制的,否则任意超平面都可以是“最优”超平面。因此公示(2)中的目标函数也需要相应的修改,限制松弛变量的总和尽量的小:
011.png (11.58 KB, 下载次数: 1)
16:12 上传
公示(3)可以理解为,在对outlier做出有限度的容忍情况下寻找使间隔最大化的最优超平面,至此才是一个能实际应用的完整SVM。如果想详细了解SVM的来龙去脉,推荐《An Introduction to Support Vector Machines and other kernel-based learning methods》(中文译本《支持向量机导论》,李国正翻译)。
达观数据运用机器学习技术的经验
经过长期的不断摸索,我们积累了不少让机器学习理论能真正实用的经验。机器学习的方法都各有特点,SVM也不是万能的算法,实际应用中应该根据具体情况选择合适的方法。选好方法,到获得我们预期的效果之间,还需要经过一番细心调校,调校的基础是对所选方法的数学模型的理解,以及对当前问题和数据的深入分析。
简单又不简单的参数调节
调参数是最基础的步骤,虽看似简单却也内有乾坤。不同模型可以调节的参数数量不同,可以采取“抓大放小”的原则,调节少数几个(数量最好控制在1到2个)影响最大的参数,否则参数的组合呈指数级增长会变得难以调节。
大多数模型都有一个控制过拟合的参数,据我们的经验来看,一般情况下这个参数对预测效果的好坏影响最大。对于SVM模型,前文提到过的限制松弛变量部分的C参数就起到控制过拟合的作用,调节C参数一般也能看到预测效果出现较大变化。此外,如果使用了高斯核函数将原始特征空间映射到无限维,那高斯核参数往往需要调节。因为太小的可以把任何数据都映射成线性可分,导致非常严重的过拟合问题。相反,太大会使得映射后的空间仍然是低维空间,起不到升维的效果。
交叉检验和AB测试
调参数需要用预测效果来比较还坏,有人可能会问,那该如何测试才能比较客观的检验参数甚至模型的有效性?我们的测试方法主要有两种:离线测试和在线测试。离线测试时我们只有训练数据,一般会采用学术界常用的交叉验证方法。如图9所示,我们将训练数据平均分为n份,在这n份数据上进行n次循环,每次取其中一份作为检验集(Validation Set),其他n-1份作为训练集(Training Set)。最后对n次预测的结果求平均,以平均得分来对比不同的参数和模型。n一般取5、10或者20。
012.png (15.9 KB, 下载次数: 1)
16:13 上传
图 9 交叉验证
离线测试得到满意的性能提升之后,就可以进行在线测试。离线测试效果好,并不意味着上线就能取得满意效果。在线测试采用工业界广泛使用的AB测试,首先我们会从线上切一小部分流量(B流量)给新模型、新参数,将效果和使用原先的模型和参数的主流量(A流量)进行对比,如果效果有所提升,再增加B流量的比例。测试通过了就可以全流量上线。
特征工程(feature engineering)的探讨
业界这么多年的实践经验已经证明,能给机器学习系统的性能带来较大提升的,不是换新模型或者调参数,而是特征工程,andrew ng也说过,“Applied machine learning& is basically feature engineering.”。机器学习只是提供了通用的算法,不可能根据不同的应用场景去调整自身的数学模型或算法。这就需要我们加入一些人工干预。
特征工程基于不同应用的领域知识对样本提取关键特征,让机器学习算法能够发挥出最优效果。相对而言特征工程是比较耗费人力的步骤,实际操作中也会遇到较多困难,解决办法只有一个:了解你的问题,了解你的数据。做反作弊检测的时候,我们是细致观察过作弊用户的行为数据,做过一些简单的统计分析。对作弊用户的行为模式有一定的概念,才能设计出有用的特征让预测效果达到要求。
非线性模型 V.S. 线性模型
进入大数据时代,我们面临的都是海量数据的处理问题。我们处理的大数据集合,在完成特征工程之后,通常得到的特征维数很高,上千万维的特征也不少见。在某些应用场景下,比如文本分类,当样本数量足够多、特征维数足够大的时候,我们发现非线性模型的效果并没有比线性模型高出多少,但计算效率明显差很多。这也是台湾林智仁教授及其团队继LIBSVM之后又推出了LIBLINEAR的原因,LIBLINEAR确实更符合当下大数据处理的要求:快速、高效、性能有保证。如果数据量较大特征维数较多,线性模型是不错的选择;一方面,线性模型可以在效果达到使用要求的前提下保证在线应用的及时响应,另一方面也节约了离线训练的计算时间,可以提高特征工程迭代的效率。
大数据时代之下,如何从已经积累的数据中挖掘出“金矿”以提高企业效益,已日渐成为各行各业的普遍痛点。设想一下如果能让每个企业都用上大数据技术,我们整体的经济效率必将有明显的提升。达观数据科技非常愿意与所有企业分享我们的经验和能力,助力各个企业享受大数据技术的成果。
主题帖子积分
注册会员, 积分 166, 距离下一级还需 34 积分
注册会员, 积分 166, 距离下一级还需 34 积分
不错 受益匪浅
站长推荐 /4
云计算hadoop视频大全(新增 yarn、flume|storm、hadoop一套视频
等待验证会员请验证邮箱
新手获取积分方法
技术类问答,解决学习openstack,hadoop生态系统中遇到的问题
Powered by

我要回帖

更多关于 svm解决过拟合问题 的文章

 

随机推荐