版权声明:本文为博主原创文章,转载请注明出处算法
机器学习的研究领域是发明计算机算法,把数据转变为智能行为。机器学习和数据挖掘的区别多是机器学习侧重于执行一个已知的任务,而数据发掘是在大数据中寻找有价值的东西。数据库
用于分类:k近邻,朴素贝叶斯,决策树,规则学习,神经网络,支持向量机
用于数值预测:线性回归,回归树,模型树,神经网络,支持向量机网络
用于模式识别(数据之间联系的紧密性):关联规则
用于聚类:k均值聚类app
llibrary(class) library(gmodels) #prepare data set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] iris_z <- as.data.frame(scale(iris_rand[,-5])) #z score normalize train <- iris_z[1:105,] test <- iris_z[106:150,] train.label <- iris_rand[1:105,5] test.label <- iris_rand[106:150,5] #kNN pred <- knn(train,test,train.label,k=10) #comfusion matrix CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)
这个结果显示kNN对测试数据所有预测正确dom
library(e1071) library(gmodels) set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train <- iris_rand[1:105,-5] test <- iris_rand[106:150,-5] train.label <- iris_rand[1:105,5] test.label <- iris_rand[106:150,5] #tranform numerical variable to classified variable conver_counts <- function(x){ q <- quantile(x) sect1 <- which(q[1] <= x & x<= q[2]) sect2 <- which(q[2 ]< x & x <= q[3]) sect3 <- which(q[3]< x & x <= q[4]) sect4 <- which(q[4]< x & x <= q[5]) x[sect1] <- 1 x[sect2] <- 2 x[sect3] <- 3 x[sect4] <- 4 return(x) } train <- apply(train,2,conver_counts) #naiveBayes m <- naiveBayes(train,train.label,laplace=1) pred <- predict(m,test,type="class") #comfusion matrix CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)
可见对第一类(setosa)分类上预测错误率很高,这可能反映了朴素贝叶斯算法的缺点,对于处理大量数值特征数据集时并不理想机器学习
library(C50) library(gmodels) set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train <- iris_rand[1:105,-5] test <- iris_rand[106:150,-5] train.label <- iris_rand[1:105,5] test.label <- iris_rand[106:150,5] #C50 m <- C5.0(train,train.label,trials = 10) pred <- predict(m,test,type="class") #comfusion matrix CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)
library(RWeka) library(gmodels) set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train <- iris_rand[1:105,] test <- iris_rand[106:150,-5] test.label <- iris_rand[106:150,5] m <- OneR(Species ~ .,data=train) pred <- predict(m,test) CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)
查看生成的规则,按照Petal的宽度,分红三类,正确分类了105个里面的101个
对于测试数据的混合矩阵以下
可见只使用了一个规则也能,也作到了不错的效果ide
对于复杂的任务,只考虑单个规则可能过于简单,考虑多个因素的更复杂的规则学习算法可能会有用,但也可能所以会变得更加难以理解。早期的规则学习算法速度慢,而且对于噪声数据每每不许确,后来出现增量减小偏差修剪算法(IREP),使用了生成复杂规则的预剪枝和后剪枝方法的组合,并在案例从所有数据集分离以前进行修剪。虽然这提升了性能,可是仍是决策树表现的更好。直到1995年出现了重复增量修剪算法(RIPPER),它对IREP算法进行改进后再生成规则,它的性能与决策树至关,甚至超过决策树。函数
library(RWeka) library(gmodels) set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train <- iris_rand[1:105,] test <- iris_rand[106:150,-5] test.label <- iris_rand[106:150,5] m <- JRip(Species ~ .,data=train) pred <- predict(m,test) CrossTable(pred,test.label,prop.r = F,prop.t = F,prop.chisq = F)
此次使用了三个规则,(Petal.Width >= 1.8为virginica ,Petal.Length >= 3为versicolor,其它为setosa
可见虽然增长了规则可是并无提升模型的性能性能
回归主要关注一个惟一的因变量(须要预测的值)和一个或多个数值型自变量之间的关系。学习
x: 输入矩阵,每列表示变量(特征),每行表示一个观察向量,也支持输入稀疏矩阵(Matrix中的稀疏矩阵类);
y: 反应变量,对于gaussian或者poisson分布族,是相应的量;对于binomial分布族,要求是两水平的因子,或者两列的矩阵,第一列是计数或者是比例,第二列是靶向分类;对于因子来讲,最后的水平是按照字母表排序的分类;对于multinomial分布族,能有超过两水平的因子。不管binomial或者是multinomial,若是y是向量的话,会强制转化为因子。对于cox分布族,y要求是两列,分别是time和status,后者是二进制变两,1表示死亡,0表示截尾,survival包带的Surv()函数能够产生这样的矩阵。对于mgaussian分布族,y是量化的反应变量的矩阵;
family: 反应类型,参数family规定了回归模型的类型:family="gaussian"适用于一维连续因变量(univariate)family="mgaussian",适用于多维连续因变量(multivariate),family="poisson"适用于非负次数因变量(count),family="binomial"适用于二元离散因变量(binary),family="multinomial"适用于多元离散因变量(category)
weights: 权重,观察的权重。若是反应变量是比例矩阵的话,权重是总计数;默认每一个观察权重都是1;
offset: 包含在线性预测中的和观察向量一样长度的向量,在poisson分布族中使用(好比log后的暴露时间),或者是对于已经拟合的模型的从新定义(将旧模型的因变量做为向量放入offset中)。默认是NULL,若是提供了值,该值也必须提供给predict函数;
alpha: 弹性网络混合参数,0 <= a <=1,惩罚定义为(1-α)/2||β||_2^2+α||β||_1.其中alpha等于1是lasso惩罚,alpha等于0是ridge(岭回归)的惩罚;
nlambda:lambda值个数;拟合出n个系数不一样的模型
lambda.min.ratio:lambda的最小值,lambda.max的比例形式,好比所有系数都是0的时候的最小值。默认值依赖于观察的个数和特征的个数,若是观察个数大于特征个数,默认值是0.0001,接近0,若是观察个数小于特征个数,默认值是0.01。在观察值个数小于特征个数的状况下,很是小的lambda.min.ratio会致使过拟合,在binominal和multinomial分布族性,这个值未定义,若是解释变异百分比老是1的话程序会自动退出;
lambda:用户提供的lambda序列。一个典型的用法基于nlambada和lambda.min.ratio来计算自身lambda序列。若是提供lambda序列,提供的lambda序列会覆盖这个。需谨慎使用,不要提供单个值给lambda(对于CV步骤后的预测,应使用predict()函数替代)。glmnet依赖于缓慢开始,而且它用于拟合全路径比计算单个拟合更快;
standardize:对于x变量是否标准化的逻辑标志,倾向于拟合模型序列。 系数老是在原有规模返回,默认standardize=TRUE。若是变量已是同一单位,你可能并不能获得想要的标准化结果。
intercept:是否拟合截距,默认TRUE,或者设置为0(FALSE)
thresh:坐标降低的收敛域值,每一个内部坐标降低一直进行循环,直到系数更新后的最大改变值比thresh值乘以默认变异要小,默认thresh为1E-7;
dfmax:在模型中的最大变量数,对于大量的变量数的模型但咱们只须要部分变量时能够起到做用;
pmax:限制非零变量的最大数目;
exclude:要从模型中排除的变量的索引,等同于一个无限的惩罚因子;
penalty.factor:惩罚因子,分开的惩罚因子可以应用到每个系数。这是一个数字,乘以lambda来容许不一样的收缩。对于一些变量来讲能够是0,意味着无收缩,默认对所有变量是1,对于列在exlude里面的变量是无限大。注意:惩罚因子是内部对nvars(n个变量)的和进行从新调整,而且lambda序列将会影响这个改变;
lower.limits:对于每一个系数的更低限制的向量,默认是无穷小。向量的每一个值须非正值。也能够以单个值呈现(将会重复),或者是(nvars长度);
upper.limit:对于每一个系数的更高限制的向量,默认是无穷大;
maxit:全部lambda值的数据最大传递数;
type.gaussian:支持高斯分布族的两种算法类型,默认nvar < 500使用"covariance“,而且保留全部内部计算的结果。这种方式比"naive"快,"naive"经过对nobs(n个观察)进行循环,每次内部计算一个结果,对于nvar >> nobs或者nvar > 500的状况下,后者每每更高效;
type.logistic:若是是"Newton“,会使用准确的hessian矩阵(默认),当用的是"modified.Newton“时,只使用hession矩阵的上界,会更快;
standardize.response:这个参数时对于"mgaussian“分布族来讲的,容许用户标准化应答变量;
type.multinomial:若是是"grouped",在多项式系数的变量使用分布lasso惩罚,这样能确保它们彻底在一块儿,默认是"ungrouped"。
glmnet返回S3类,"glmnet","*","*"能够是elnet,lognet,multnet,fishnet(poisson),merlnet
call:产生这个对象的调用;
a0:截距;
beta:对于elnet, lognet, fishnet和coxnet模型,返回稀疏矩阵格式的系数矩阵(CsparseMatrix),对于multnet和mgaussian模型,返回列表,包括每一类的矩阵;
lambda:使用的lambda值的实际序列;当alpha=0时,最大的lambda值并不仅仅等于0系数(原则上labda等于无穷大),相反使用alpha=0.01的lambda,由此导出lambda值;
dev.ratio:表示由模型解释的变异的百分比(对于elnet,使用R-sqare)。若是存在权重,变异计算会加入权重,变异定义为2x(loglike_sat-loglike),loglike_sat是饱和模型(每一个观察值具备自由参数的模型)的log似然。所以dev.ratio=1-dev/nulldev;越接近1说明模型的表现越好
nulldev:NULL变异(每一个观察值),这个定义为2*(loglike_sat-loglike(Null));NULL模型是指截距模型,除了Cox(0 模型);
df:对于每一个lambda的非零系数的数量。对于multnet这是对于一些类的变量数目;
dfmat:仅适用于multnet和mrelnet。一个包括每一类的非零向量数目的矩阵;
dim:系数矩阵的维度;
nobs:观察的数量;
npasses:所有lambda值加和的数据的总的通量;
offset:逻辑变量,显示模型中是否包含偏移;
jerr:错误标记,用来警告和报错(很大部分用于内部调试验)
而直接显示的结果有三列,分别是df,%Dev (就是dev.ratio),lambda是每一个模型对应的λ值
predict(object,newx,s=NULL,type=c("link","reponse","coefficients","nonzero","class"),exact=FALSE,offset,...)
coef(object,s=NULL,exact=FALSE)
object:glmnet返回的对象;
newx:用来预测的矩阵,也能够是系数矩阵;这个参数不能用于type=c(""coefficents","nonzero");
s:惩罚参数lambda的值,默认是用来建立模型的所有lambda值;
type:预测值的类型;"link”类型给"binomial",“multinomial","poisson"或者"cov"模型线性预测的值,对于"gaussian”模型给拟合值。"response"类型,对于"binominal“和"multinomial”给拟合的几率,对于"poisson“,给拟合的均值,对于"cox",给拟合的相对未及;对于"gaussion",response等同于"link“类型。"coefficients"类型对于需求的s值计算系数。注意,对于"binomial”模型来讲,结果仅仅对因子应答的第二个水平的类返回。“class"类型仅仅应用于"binomial”和"multinomial“模型,返回最大可能性的分类标签。"nonzero”类型对每一个s中的值返回一个列表,其中包含非0参数的索引;
exact:这个参数仅仅对于用于预测的s(lambda)值不一样于原始模型的拟合的值时,这个参数起到做用。若是exact=FALSE(默认),预测函数使用线性解释来对给的s(lambda)值进行预测。这时一个很是接近的结果,只是稍微有点粗糙。若是exact=TRUE,这些不一样的s值和拟合对象的lambda值进行sorted和merged,在做出预测以前进行模型的从新拟合。在这种状况下,强烈建议提供原始的数据x=和y=做为额外的命名参数给perdict()或者coef(),predict.glmnet()须要升级模型,而且指望用于建立接近它的数据。尽管不提供这些额外的参数它也会运行的很好,在调用函数中使用嵌套序列极可能会中断。
offset:若是使用offset参数来拟合,必须提供一个offset参数来做预测。除了类型"coefficients"或者"nonzero“
...:能够提供参数其它参数的机制,好比x=when exact=TRUE,seeexact参数。
library(glmnet ) library(psych) #dummy variable encoding iris$issetosa <- ifelse(iris$Species=="setosa",1,0) iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0) iris_dt <- iris[,-5] pairs.panels(iris_dt) #scatterplot matrix
pairs.panel画出散点图矩阵,对角线上方显示的是变量之间的相关系数,每一个散点图中呈椭圆形的对象称为相关椭圆,它提供一种变量之间是如何密切相关的可视化信息。位于椭圆中间的的点表示x轴变量和y轴变量的均值所肯定的点。两个变量之间的相关性由椭圆的形状表示,椭圆越被拉伸,其相关性就越强。散点图中绘制的曲线称为局部回归平滑,它表示x轴和y轴变量之间的通常关系。iris数据画出的散点图矩阵中的相关系数和散点图曲线均可见Petal.Length和Petal.Width有着强的相关性,而从散点图曲线也可看出,彷佛Sepal.Length超出必定阈值后,Sepal.Length增长,Petal.Length也增长,而且也和品种是setosa或者versicolor也有关系。以Petal.Width做为因变量做线性回归。
library(glmnet ) #dummy variable encoding iris$issetosa <- ifelse(iris$Species=="setosa",1,0) iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0) #divided into training sets and test sets set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train <- iris_rand[1:105,-c(4,5)] test <- iris_rand[106:150,-c(4,5)] train_value <- iris_rand[1:105,4] test_value <- iris_rand[106:150,4] #lasso m_lasso <- glmnet(as.matrix(train),train_value,family = "gaussian") plot(data.frame(df=m_lasso$df,dev.ratio=m_lasso$dev.ratio),type="b",cex=0.6) coef(m_lasso, s=0.0497000) #min df
查看变量个数与模型解释变异百分比的点图,发如今df=1时已经开始平缓,已经能够解释93%的变异。所以取df=1的能够解释最大变异的lambda,0.0452800,查看系数发现使用了两个特征,其中一个系数很是低,并非咱们须要的,所以lambda改成第二个解释最大变异的lambda,0.0497000.
用coef取出参数以下
lambda=0.0452800
lambda=0.0497000
用选出的lambda值进行预测
pred <- predict(m_lasso,newx=as.matrix(test),s=0.0497000) summary(pred) summary(test_value) cor(test_value,pred) MAE <- mean(abs(pred - test_value)) mean(abs(mean(train_value) - test_value))
发现预测值和真实值范围很是接近
相关系数高
MAE(平均绝对偏差,反映预测值和真实值的差距)仅为0.1981803,若是只是拿训练集的均值预测的话,MAE高达0.6551746)
综合以上的度量标准,说明咱们的模型预测的不错。
library(rpart) library(RWeka) library(rpart.plot) #dummy variable encoding iris$issetosa <- ifelse(iris$Species=="setosa",1,0) iris$isversicolor <- ifelse(iris$Species=="versicolor",1,0) #divided into training sets and test sets set.seed(12345) #set random seed in order to repeat the result iris_rand <- iris[order(runif(150)),] train_dt <- iris_rand[1:105,-5] test <- iris_rand[106:150,-c(4,5)] test_value <- iris_rand[106:150,4] #rpart m.rpart <- rpart(Petal.Width ~ Sepal.Length+Sepal.Width+Petal.Length+issetosa+isversicolor,data = train_dt) summary(m.rpart) rpart.plot(m.rpart) pred <- predict(m.rpart,test) cor(test_value,pred) mean(abs(pred - test_value)) #rpart MAE mean(abs(mean(train_dt$Petal.Width) - test_value)) #mean MAE #M5P m.M5P <- M5P(Petal.Width ~ Sepal.Length+Sepal.Width+Petal.Length+issetosa+isversicolor,data = train_dt) summary(m.M5P) pred <- predict(m.M5P,test) cor(test_value,pred) mean(abs(pred - test_value)) #rpart MAE mean(abs(mean(train_dt$Petal.Width) - test_value)) #mean MAE
回归树的结果以下
rpart.plot结果
相关性到达0.9797762,回归树(MAF0.1242998)明显比直接用均值预测(MAF0.7255238)更接近于真实的Petal.Width
模型树的结果以下
相关系数到达0.9714331,MAF0.1410668,在这个模型树中,只有一个根节点,相应创建了一个线性模型,直接用Sepal.Length ,Sepal.Width ,Petal.Length三个特征进行预测,和lasso回归模型同样,特征前面的系数表明该特征对Petal.Width的静影响,注意,这里的净影响是指在当前节点这个线性模型中的净影响,在这个线性模型中,每增长一点Sepal.Width和Petal.Length,Petal.Width都会增长,而系数小于0的Sepal.Length ,意味着每增长一点Sepal.Length,Petal.Width就会减小。从结果能够看出,在这个案例中,模型树没有回归树的效果好。
此处模型树在没有生成多个树节点的状况下,只是对特征作了线性回归,MAF达到0.1410668,和以前对数据做线性回归的lasso模型结果(MAF0.1981803)相比,貌似作的更好,但其实以前的lasso回归模型咱们限制了特征值个数来避免过拟合,若是增长特征值数量和调整labda参数,同样能够达到比较小的MAF。
本文主要讲了机器学习的一些基本概念,还有部分机器学习方法的基本原理及R语言实现。包括用于分类的机器学习方法:k近邻,朴素贝叶斯,决策树,规则学习;用于数值预测的机器学习方法:lasso回归,回归树,模型树,它们都属于监督学习。下篇文章会说到监督学习中的神经网络和支持向量机,还有其余非监督学习的一些方法。
本文能够做为一个速查和简单的入门,一些函数只列举了部分重要的参数,具体的使用参数能够经过查看R里面的帮助得到。另外若是要用于实践,还须要了解一些K折交叉检验,kappa统计量,ROC曲线内容,以对模型的性能进行评价和对不一样的模型进行对比。
Brett Lantz:机器学习与R语言
薛毅,陈立萍: 统计建模与R软件(下册)
侯澄钧:热门数据挖掘模型应用入门(一): LASSO : https://cosx.org/2016/10/data-mining-1-lasso
slade_sha的博客 Lasso算法理论介绍 :http://blog.csdn.net/slade_sha/article/details/53164905