本人现在一名求职狗,在面试的过程中受到多重打击,现把面试过程中常问到的机器学习算法的原理和优缺点整理出来供自己复习也给大家分享一下。本文内容参照了多个来源,书、博客、百度等等,因此就不在添加引用,望各位海涵。
三大常见的机器学习任务:回归、分类、聚类
还有两大数据降维问题在下节讲述…
线性回归:通常使用正则化方法,正则化算法的目的是,对系数给予惩罚,防止过拟合。L2范数构成的区域是一个圆,L1范数构成的区域是一个四边形。包括岭回归(L1正则)、Lasso(L2正则)
优点:理解与解释比较直观,能够通过正则化来降低过拟合的风险,容易使用随机梯度下降法和新数据更新模型权重。
缺点:在变量是非线性关系时表现很差。不能灵活的捕捉更为复杂的模式。
实现:from sklearn import preprocessing,linear_model
x_scale=preprocessing.scale(x)#标准化
clf=linear_model.LinearRegression()
clf=clf.fit(x_scale,y)#线性回归
from sklearn.linear_model import Ridge
ridge=Ridge().fit(x_scale,y)#岭回归
from sklearn.linear_model import Lasso
lasso=Lasso(alpha=0.01,max_iter=100000).fit(x_scale,y)# Lasso回归
回归树:最大化信息增益
优点:能学习非线性关系,对异常值具有很强的鲁棒性。
缺点:无约束的单棵树很容易过拟合(不剪枝)。
实现:from sklearn import tree
clf = tree.DecisionTreeClassifier(criterion='entropy')
clf = clf.fit(dummyX, dummyY)
KNN(k近邻):为了判断未知实例的类别,以所有已知类别的实例作为参照。选择最近K个已知实例,计算未知实例与所有已知实例的距离。根据少数服从多数的投票法则(majority-voting),让未知实例归类为K个最邻近样本中最多数的类别
实现:from sklearn import neighbors
knn.fit(iris.data, iris.target)
Logistic回归:通过sigmoid函数将预测映射到0到1中间,因此预测值可以看成是某个类别的概率。
优点:输出有很好的概率解释,并且算法也能正则化而避免过拟合
缺点:只有在数据是线性可分时,算法才能有优秀的表现
实现:import statsmodels.api as sm
#将prestige设为虚拟变量
dummy_ranks = pd.get_dummies(df['prestige'], prefix='prestige')
cols_to_keep = ['admit', 'gre', 'gpa']
data = df[cols_to_keep].join(dummy_ranks.ix[:, 'prestige_2':])
logit = sm.Logit(data['admit'], data[train_cols])
result = logit.fit()
分类树(CART):与回归方法相似,不同的是分类树的预测变量为分类变量。决策树通过把实例从根节点排列到某个叶子结点来分类实例,叶子结点即为实例所属的分类。树上的每一个结点指定了对实例的某个属性的测试,并且该结点的每一个后继分支对应于该属性的一个可能值。分类实例的方法是从这棵树的根节点开始,测试这个结点的属性,然后按照给定实例的属性值对应的树枝向下移动。然后这个过程在以新结点的根的子树上重复。
优点:分类树的集成方法(随机森林)在实践中表现十分优良,对异常数据具有相当的鲁棒性和可扩展性。
缺点:无约束的单棵树很容易过拟合,使用集成方法可以削弱这一方面的影响。
支持向量机:可以使用一个称为核函数的技巧扩展到非线性分类问题,而该算法本质上就是计算两个称之为支持向量的观测数据之间的距离,SVM寻找的决策边界即最大化其与样本间隔的边界。这族分类器的特点是他们能够同时最小化经验误差与最大化几何边缘区,因此支持向量机也被称为最大边缘区分类器。SVM使用线性核函数就能得到类似于logistic回归的结果,可以使用非线性核函数对非线性决策边界建模。
优点:SVM能对非线性决策边界建模,并有许多可选的核函数形式,SVM对过拟合有相当大的鲁棒性,这一点在高维空间中尤为突出。
缺点:SVM是内存密集型算法,由于选择正确的核函数是很重要的,所以其很难调参,也不能扩展到较大的数据集中。目前在工业界中,随机森林通常优于支持向量机算法
实现:from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
clf = GridSearchCV(SVC(kernel='rbf', class_weight='auto'), param_grid)
clf = clf.fit(X_train_pca, y_train)
朴素贝叶斯:NB是一种基于贝叶斯定理和特征条件独立假设的分类方法。本质上朴素贝叶斯模型就是一个概率表,其通过训练数据更新这张表中的概率。为了预测一个新的观察值,它就是根据样本的特征值在概率表中寻找最大概率的那个类别。之所以称之为朴素,是因为该算法的核心是特征条件独立性假设(每个特征之间相互独立)。
优点:即使条件独立性假设很难成立,但是朴素贝叶斯算法在实践中表现出乎意料的好。该算法很容易实现并能随数据集的更新而扩展。在数据较少的情况下仍然有效,可以处理多类别问题。
缺点:对于输入数据的准备方式较为敏感。
实现:from sklearn.naive_bayes import GaussianNB
GNB= GaussianNB()
GNB.fit(x,y)
NN(神经网络): 使用神经网络训练数据之前,必须确定神经网络的层数,以及每层单元的个数;特征向量在被传入输入层时通常被先标准化(normalize)到0和1之间 (为了加速学习过程);离散型变量可以被编码成每一个输入单元对应一个特征值可能赋的值;神经网络即可以用来做分类(classification)问题,也可以解决回归(regression)问题(对于分类问题,如果是2类,可以用一个输出单元表示(0和1分别代表2类);如果多余2类,每一个类别用一个输出单元表示,所以输入层的单元数量通常等于类别的数量);没有明确的规则来设计最好有多少个隐藏层,根据实验测试和误差,以及准确度来实验并改进。
实现:from sklearn.preprocessing import LabelBinarizer
from NeuralNetwork import NeuralNetwork
nn = NeuralNetwork([64, 100, 10], 'logistic')#3层的特征数,以及选用的sigmoid函数
labels_train = LabelBinarizer().fit_transform(y_train)#将分类变量转化为哑变量
nn.fit(X_train, labels_train, epochs=3000)
K均值:将事先输入的n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
优点:K均值聚类是最流行的聚类算法,因为该算法足够快速、简单,并且如果你的预处理数据和特征工程十分有效,那么该聚类算法将拥有令人惊叹的灵活性。
缺点:最终结果跟初始点选择相关,容易陷入局部最优。该算法需要指定集群的数量,而K的选择通常都不是那么容易确定的。如果训练数据中的真实集群并不是类球状的,那么K均值聚类会得出一些比较差的集群。K-means对于噪声比较敏感。
实现:from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3).fit(df1)
层次聚类:假设有N个待聚类的样本,对于层次聚类来说步骤:
1、(初始化)把每个样本归为一类,计算每两个类之间的距离,也就是样本与样本之间的相似度;
2、寻找各个类之间最近的两个类,把他们归为一类(这样类的总数就少了一个);
3、重新计算新生成的这个类与各个旧类之间的相似度;
4、重复2和3直到所有样本点都归为一类,结束
整个聚类过程其实是建立了一棵树,在建立的过程中,可以通过在第二步上设置一个阈值,当最近的两个类的距离大于这个阈值,则认为迭代可以终止。
优点:层次聚类最主要的优点是集群不再需要假设为类球形,还可以扩展到大数据集。
缺点:该算法也需要设定集群的数量。
实现:from scipy.cluster.hierarchy import linkage, dendrogram
X = linkage(features, method='single', metric='euclidean')
#method是指计算类间距离的方法,比较常用的有3种:
#single:最近邻,把类与类间距离最近的作为类间距
#average:平均距离,类与类间所有pairs距离的平均
#complete:最远邻,把类与类间距离最远的作为类间距
更多集成和关联规则算法将会在下节列出。