1. 机器学习的主要分类
2. 机器学习的主要流程
3 数据预处理
数据预处理指当录入或读取数据后,对数据进行必要的清理,包括查错纠错、异常观察值和无效样本的处理、转换、填补缺失值、数据重编码、样本不平衡处理等,这是数据分析的重要前提,是描述统计、定性定量分析的基础。其主要目的是为后续的分析工作提供经过清理、质量较好的数据集。
3.1 异常值处理
异常值:指测量数据中的随机错误或偏差,包括错误值或偏离均值的孤立点值。在数据处理中,异常值会极大的影响回归或分类的效果。为了避免异常值造成的损失,需要在数据预处理阶段进行异常值检测。
主要检测方法:
一、用箱线图检测异常值(异常值被定义为小于Q1-1.5IQR或大于Q3+1.5IQR的值。IQR位Q3-Q1)
二、使用局部异常因子法(LOF法)检测异常值(将一个点的局部密度与分布在它周围的点的密度相比较,如果前者明显的比后者小,那么这个点相对于周围的点来说就处于一个相对比较稀疏的区域,这就表明该点事一个异常值。LOF算法的缺点是它只对数值型数据有效,R包:DMwR,dprep)
三、用聚类方法检测异常值(PCA、层次聚类)
3.2 填补缺失值
缺失值产生原因:
1.在数据收集阶段,某些记录或字段丢失,被访者拒绝透露相关信息,随机因素。
判断缺失模式:
mice程序包中的 md.pattern() 用于显示缺失数据的模式,判断是否是随机缺失。
处理缺失数据:
- 删除缺失样本(样本缺失值较多时,如果过度填充可能带来噪声);
- 均值填充(在特征是随机缺失的情况下可以考虑使用均值填充);
- 多重插补填充(该方法通过变量间关系来预测缺失数据,利用蒙特卡罗随机模拟
方法生成多个完整数据集,再对这些数据集分别进行分析,
最后对这些分析结果进行汇总处理。mice 包)
3.3 样本不平衡处理
样本(类别)不平衡(class-imbalance)指的是分类任务中不同类别的训练样例数目差别很大的情况,一般地,样本类别比例(Imbalance Ratio)(多数类vs少数类)明显大于1:1(如4:1)就可以归为样本不均衡的问题。那么其分类器会大大地因为数据不平衡性而无法满足分类要求的。因此在构建分类模型之前,需要对分类不均衡性问题进行处理。
样本不平衡处理方法:
- 过采样:复制标签少的样本使得两组比满足建模需要
- 欠采样:抽取标签多的样本使得两组比满足建模需要
(会丢失样本信息) - EasyEnsemble:标签多的样本进行n份,每份都和标签少的全部样本组合成n份训练样本,利用集成学习训练n个弱分类器
- BalanceCascade:对标签多的样本进行欠采样,和标签少的全部样本组合成训练样本,弱分类器分类正确的标签多数样本不放回,分类错误的放回。 R包:ROSE
4. 常见算法
4.1 决策树算法
决策树(Decision Tree)作为一个常用的机器学习算法,在风险性决策问题上有着广泛的应用。决策树呈现出来的是一种树状结构(二叉树或非二叉树),其中每一个内部节点(internal node)代表的是一个属性的判断,每一个分支代表一个判断结果的输出,每一个叶节点(leaf)代表一种分类结果。
决策树通过对样本数据的学习,运用某种生成算法,构造出一个具备互斥且完备的决策树,再用其对待处理样本进行分类。通俗地说,决策树就是一组判别条件的有机堆砌,像树的枝干一样,从主树干到分树干,分树干再到分枝干,当中每一个组合都是不同的一条判别规则链条。而特定算法其实就是一套决定哪个判别条件作为主树干,或者说筛选出哪个判别条件的影响比重在所有条件中最大,以此类推分树干的确定、第三级枝干等等。
决策树的基本流程:
1. 首先从开始位置,将所有数据划分到一个节点,即根节点。
2. 然后经历橙色的两个步骤,橙色的表示判断条件:
若数据为空集,跳出循环。如果该节点是根节点,返回null;如果该节点是中间节点,将该节点标记为训练数据中类别最多的类
若样本都属于同一类,跳出循环,节点标记为该类别;
3. 如果经过橙色标记的判断条件都没有跳出循环,则考虑对该节点进行划分。既然是算法,则不能随意的进行划分,要讲究效率和精度,选择当前条件下的最优属性划分(什么是最优属性,这是决策树的重点,后面会详细解释)
4. 经历上步骤划分后,生成新的节点,然后循环判断条件,不断生成新的分支节点,直到所有节点都跳出循环。
5. 结束。这样便会生成一棵决策树。
library(rpart)
library(tibble)
library(bitops)
library(rattle)
library(rpart.plot)
library(RColorBrewer)
library(data.table)
library(pROC)
library(e1071)
library(mice)
# 读取数据(示例数据,不需要预处理)
mydata <- read.csv("data.csv",header=T)
colnames(mydata) #index1-6都是特征量,可以替换成任意特征量
# [1] "age" "sex" "dishistory" "index1" "index2" "index3" "index4" "index5" "index6" "group"
# 训练集与验证集划分,50个样例作为训练集,其余作为测试集
sub<-sample(1:100,50)
train<-mydata[sub,]
test<-mydata[-sub,]
#构建决策树并绘制图形,利用训练集构建决策树:
model <- rpart(group~age+dishistory+index1+index2+index3+index4+index5+index6,data = train)
fancyRpartPlot(model)
可以看到,决策树根据index4>=60和index2<5.9来判断group属于case还是control
#测试模型,利用验证集对模型结果进行验证:
x<-subset(test,select=-group)
pred<-predict(model,x,type="class")
k<-test[,"group"]
table(pred,k)
# k
# pred case control
# case 7 0
# control 3 40
4.2 随机森林算法
基于决策树的集成学习算法——随机森林算法(Random Forest Algorithm)
将多个决策树结合在一起,每次数据集是随机有放回的选出,同时随机选出部分特征作为输入,所以该算法被称为随机森林算法。随机森林算法是以决策树为估计器的Bagging算法。
使用randomForest包在R中创建随机林的基本语法是
randomForest(formula, data)
formula-是描述预测变量和响应变量的公式
data-是使用的数据集的名称
# 安装R包
# install.packages("randomForest")
# install.packages("party")
# 输入数据我们将使用名为readingSkills的R内置数据集来创建一个决策树
# 如果我们知道变量:"age","shoesize","score"以及"nativeSpeaker"表示该人员是否为讲母语的人,那么它描述某个人员的阅读技能的得分
library(party)
library(pROC)
library("randomForest")
data("readingSkills")
# Create the forest.
set.seed(100)
output.forest <- randomForest(nativeSpeaker~age+shoeSize+score,data = readingSkills)
# View the forest results.
print(output.forest)
output.forest$importance
# Importance of each predictor.
print(importance(output.forest,type = 2))
#变量重要性的判断
varImpPlot(output.forest, main = "variable importance")
4.3 支持向量机(SVM)算法
支持向量机(support vector machines, SVM)一般应用于二分类问题(二分分类即分类结果标签只有两个)。其学习策略是:在分类超平面的正负两边各找到一个离分类超平面最近的点(也就是支持向量),使得这两个点距离分类超平面的距离和最大。这个分类策略的目的是:在保证对训练数据分类正确的基础上,对噪声设置尽可能多的冗余空间,提高分类器的鲁棒性。SVM 的终极目标是求出一个最优的线性分类超平面 WX+b =0。主要有两个要求:
1)所有训练数据点距离最优分类超平面的距离都要大于支持向量距离此分类超平面的距离;
2)支持向量点到最优分类超平面距离越大越好。目标函数是为了使支持向量点到最优分类超平面距离越大越好,约束项保证了所有训练数据点距离最优分类超平面的距离都要大于支持向量距离此分类超平面的距离。
# 读取数据
data=fread('data.csv')
data=as.data.frame(data)
data$group =factor(data$group)
# 数据预处理
imputed_Data <- mice(data) # 利用mice包填补缺失值
data=complete(imputed_Data)
# 按 7:3 分训练集和测试
set.seed(1234) # 随机抽样设置种子
train <- sample(nrow(data),0.7*nrow(data)) # 抽样函数
tdata <- data[train,] # 根据抽样参数列选择样本,都好逗号是选择行
vdata <- data[-train,] # 删除抽样行
# 模型构建
cats_svm_model <- svm(group~.,data = tdata,
type="C-classification", kernel="linear",cost=10,scale=FALSE)
# 模型预测
predtree <- predict(cats_svm_model,newdata=vdata,type="group") # 利用预测集进行预测
# 输出混淆矩阵
table(vdata$group,predtree,dnn=c("true", "predit")) # 输出混淆矩阵
# predit
# true case control
# case 8 0
# control 0 22
# 绘制ROC曲线
ran_roc <-roc(vdata$group ,as.numeric(predtree))
png(file = "ROC.png")
plot(ran_roc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
grid.col=c("green", "red"),max.auc.polygon=TRUE,auc.polygon.col="skyblue",
print.thres=TRUE,main='SVM')
dev.off()
4.4 朴素贝叶斯
朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法。对于给定的训练集,首先基于特征条件独立假设学习输入输出的联合概率分布(朴素贝叶斯法这种通过学习得到模型的机制,显然属于生成模型);然后基于此模型,对给定的输入 x,利用贝叶斯定理求出后验概率最大的输出 y。
R语言贝叶斯分类函数包caret中train函数,klaR包中的NavieBayes函数,e1071包中的naiveBayes函数。
library(e1071); library(klaR)
# 按照8:2的比例进行拆分数据
sub <- sample(nrow(iris),0.8*nrow(iris))
tdata <- iris[sub,]
vdata <- iris[-sub,]
naiveBayes.model <- naiveBayes(Species ~ ., data = tdata)
iris_predict <- predict(naiveBayes.model, newdata = vdata)
table_iris <- table(vdata$Species, predict = iris_predict,dnn = c('true','predict'))
1 - sum(diag(table_iris))/sum(table_iris) # 计算误差
# [1] 0.03333333
4.5 Xgboost
XGBoost本质上还是一个GBDT(Gradient Boosting Decision Tree) ,但是力争把速度和效率发挥到极致,所以叫X (Extreme) GBoosted。两者都是boosting方法(Boosting方法就是从弱学习算法出发,反复学习,得到一系列弱分类器,然后组合弱分类器,得到一个强分类器)。
梯度提升决策树(Gradient Boosting Decision Tree,GBDT)是一种基于boosting集成思想的加法模型,训练时采用前向分布算法进行贪婪的学习,每次迭代都学习一棵CART树来拟合之前 t-1 棵树的预测结果与训练样本真实值的残差。
url <- 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
redwine <- read.csv(url,sep = ';')
url1 <- 'https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv'
whitewine <- read.csv(url1,sep = ';')
data <- rbind(redwine,whitewine)
#训练集、测试集划分
set.seed(17)
index <- which( (1:nrow(data))%%3 == 0 )
train <- data[-index,]
test <- data[index,]
# 数据预处理,将数据转化为gb.DMatrix类型,并对label进行处理,超过6分为1,否则为0。
library("xgboost")
library("Matrix")
library("Ckmeans.1d.dp")
train_matrix <- sparse.model.matrix(quality ~ .-1, data = train)
test_matrix <- sparse.model.matrix(quality ~ .-1, data = test)
train_label <- as.numeric(train$quality>6)
test_label <- as.numeric(test$quality>6)
train_fin <- list(data=train_matrix,label=train_label)
test_fin <- list(data=test_matrix,label=test_label)
dtrain <- xgb.DMatrix(data = train_fin$data, label = train_fin$label)
dtest <- xgb.DMatrix(data = test_fin$data, label = test_fin$label)
#模型训练
xgb <- xgboost(data = dtrain,max_depth=6, eta=0.5,
objective='binary:logistic', nround=25)
#重要重要性排序
importance <- xgb.importance(train_matrix@Dimnames[[2]], model = xgb)
head(importance)
xgb.ggplot.importance(importance)
#混淆矩阵
pre_xgb = round(predict(xgb,newdata = dtest))
table(test_label,pre_xgb,dnn=c("true","pre"))
# pre
# true 0 1
# 0 1633 95
# 1 197 240
#ROC曲线
xgboost_roc <- roc(test_label,as.numeric(pre_xgb))
plot(xgboost_roc, print.auc=TRUE, auc.polygon=TRUE,
grid=c(0.1, 0.2),grid.col=c("green", "red"),
max.auc.polygon=TRUE,auc.polygon.col="skyblue",
print.thres=TRUE,main='ROC curve')
4.6 主成分分析(PCA)算法
主成分分析(PCA, principal component analysis)是一种数学降维方法,利用正交变换(orthogonal transformation)把一系列可能线性相关的变量转换为一组线性不相关的新变量,也称为主成分,从而利用新变量在更小的维度下展示数据的特征。主成分是原有变量的线性组合,其数目不多于原始变量。组合之后,相当于我们获得了一批新的观测数据,这些数据的含义不同于原有数据,但包含了之前数据的大部分特征,并且有着较低的维度,便于进一步的分析。
在空间上,PCA可以理解为把原始数据投射到一个新的坐标系统,第一主成分为第一坐标轴,它的含义代表了原始数据中多个变量经过某种变换得到的新变量的变化区间;第二成分为第二坐标轴,代表了原始数据中多个变量经过某种变换得到的第二个新变量的变化区间。
#将R自带的范例数据集iris储存为变量data;
data<-iris
head(data)
#对原数据进行z-score归一化;
dt<-as.matrix(scale(data[,1:4]))
head(dt)
#计算相关系数矩阵;
rm1<-cor(dt)
rm1
# 求解特征值和相应的特征向量
rs1<-eigen(rm1)
rs1
#提取结果中的特征值,即各主成分的方差;
val <- rs1$values
#换算成标准差(Standard deviation);
(Standard_deviation <- sqrt(val))
#计算方差贡献率和累积贡献率;
(Proportion_of_Variance <- val/sum(val))
(Cumulative_Proportion <- cumsum(Proportion_of_Variance))
#碎石图绘制;
par(mar=c(6,6,2,2))
plot(rs1$values,type="b",
cex=2,
cex.lab=2,
cex.axis=2,
lty=2,
lwd=2,
xlab = "主成分编号",
ylab="特征值(主成分方差)")
# 计算主成分得分
#提取结果中的特征向量(也称为Loadings,载荷矩阵);
(U<-as.matrix(rs1$vectors))
#进行矩阵乘法,获得PC score;
PC <-dt %*% U
colnames(PC) <- c("PC1","PC2","PC3","PC4")
head(PC)
# 绘制主成分散点图
#将iris数据集的第5列数据合并进来;
df<-data.frame(PC,iris$Species)
head(df)
#载入ggplot2包;
library(ggplot2)
#提取主成分的方差贡献率,生成坐标轴标题;
xlab<-paste0("PC1(",round(Proportion_of_Variance[1]*100,2),"%)")
ylab<-paste0("PC2(",round(Proportion_of_Variance[2]*100,2),"%)")
#绘制散点图并添加置信椭圆;
p1<-ggplot(data = df,aes(x=PC1,y=PC2,color=iris.Species))+
stat_ellipse(aes(fill=iris.Species),
type ="norm", geom ="polygon",alpha=0.2,color=NA)+
geom_point()+labs(x=xlab,y=ylab,color="")+
guides(fill=F)
p1
# 尝试使用3个主成分绘制3D散点图
# 载入scatterplot3d包;
library(scatterplot3d)
color = c(rep('purple',50),rep('orange',50),rep('blue',50))
scatterplot3d(df[,1:3],color=color,
pch = 16,angle=30,
box=T,type="p",
lty.hide=2,lty.grid = 2)
legend("topleft",c('Setosa','Versicolor','Virginica'),
fill=c('purple','orange','blue'),box.col=NA)
4.7 聚类算法
聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
聚类和分类的区别
聚类(Clustering):是指把相似的数据划分到一起,具体划分的时候并不关心这一类的标签,目标就是把相似的数据聚合到一起,聚类是一种无监督学习(Unsupervised Learning)方法。(无标签)
分类(Classification):是把不同的数据划分开,其过程是通过训练数据集获得一个分类器,再通过分类器去预测未知数据,分类是一种监督学习(Supervised Learning)方法。(有标签)
聚类方法主要可以分为划分式聚类方法(Partition-based Methods)、基于密度的聚类方法(Density-based methods)、层次化聚类方法(Hierarchical Methods)等
# kmeans对iris进行聚类分析
iris2<-iris[,1:4]
iris.kmeans<-kmeans(iris2,3)
?kmeans
iris.kmeans
#用table函数查看分类结果情况
table(iris$Species,iris.kmeans$cluster)
#下边我们将分类以及中心点打印出来
plot(iris2$Sepal.Length,iris2$Sepal.Width,
col=iris.kmeans$cluster,pch="*")
points(iris.kmeans$centers,pch="X",cex=1.5,col=4)
#-----使用K-mediods方法来进行聚类分析
#k-mediods中包含pam、clara、pamk三种算法,我们通过iris数据集来看看三者表现
# install.packages("cluster")
library(cluster)
## pam
iris2.pam<-pam(iris2,3)
table(iris$Species,iris2.pam$clustering)
layout(matrix(c(1,2),1,2)) #每页显示两个图
plot(iris2.pam)
layout(matrix(1))
## clara
iris2.clara<-clara(iris2,3)
table(iris$Species,iris2.clara$clustering)
layout(matrix(c(1,2),1,2)) #每页显示两个图
plot(iris2.clara)
layout(matrix(1))
## pamk
#install.packages("fpc")
library(fpc)
iris2.pamk<-pamk(iris2)
table(iris2.pamk$pamobject$clustering,iris$Species)
layout(matrix(c(1,2),1,2)) #每页显示两个图
plot(iris2.pamk$pamobject)
layout(matrix(1))
通过上述分类结果可以看到,pam和calra算法分类结果基本类似,但是pamk将三类分为了两类。
4.8 DBSCAN算法
DBSCAN(Density Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法。与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类。主要关注参数 :距离参数(EPS)和邻域内点最少个数(MinPts)密度。
密度(Density)
空间中任意一点的密度是以该点为圆心,以EPS为半径的圆区域内包含的点数目N的密度为1,B、C的密度为2,A的密度为4
邻域(Neighborhood)空间中任意一点的邻域是以该点为圆心、以EPS为半径的圆区域内包含的点集合
核心点(Core Points)空间中某一点的密度,如果大于某一给定阈值MinPts,则称该点为核心点设MinPts为3,则核心点为A
边界点(Border Points)空间中某一点的密度>1并且小于MinPts图中的边界点为B、C
噪声点(Noise Points)数据集中不属于核心点,也不属于边界点的点,密度值为1图中噪声点为N
#---基于密度的聚类分析
library(fpc)
iris2<-iris[-5]
ds<-dbscan(iris2,eps=0.42,MinPts = 5)
table(ds$cluster,iris$Species)
#打印出ds和iris2的聚类散点图
plot(ds,iris2)
#打印出iris第一列和第四列为坐标轴的聚类结果
plot(ds,iris2[,c(1,4)])
#另一个表示聚类结果的函数,plotcluster
plotcluster(iris2,ds$cluster)
4.9 层次聚类算法
层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法。自下而上法:凝聚型层次聚类,就是一开始每个个体(object)都是一个类,然后根据linkage寻找同类,最后形成一个“类”。自上而下法:分裂型层次聚类,就是反过来,一开始所有个体都属于一个“类”,然后根据linkage排除异己,最后每个个体都成为一个“类”。
层次的聚类方法(Hierarchical Clustering),从字面上理解,其是层次化的聚类,最终得出来的是树形结构。专业一点来说,层次聚类通过 计算不同类别数据点间的相似度 来创建一棵有层次的嵌套聚类树。
层次聚类的好处是不需要指定具体类别数目的,其得到的是一颗树,聚类完成之后,可在任意层次横切一刀,得到指定数目的簇。
#---层次聚类
dim(iris)#返回行列数
idx<-sample(1:dim(iris)[1],40)
iris3<-iris[idx,-5]
iris3
hc<-hclust(dist(iris3),method = "ave") #注意hcluster里边传入的是dist返回值对象
plot(hc,hang=-1,labels=iris$Species[idx]) #这里的hang=-1使得树的节点在下方对齐
#将树分为3块
rect.hclust(hc,k=3)
groups<-cutree(hc,k=3)
网友评论