文章目录

  • 挖掘建模
    • 1、机器学习与建模
    • 2、训练集、测试集、验证集
    • 3、监督学习中的分类模型
      • (1)KNN
      • (2)朴素贝叶斯——适合离散数据
      • (3)生成模型与判别模型
      • (4)决策树
      • 安装Graphviz:
      • (5)SVM(支持向量机)
      • (6)集成方法—袋装法(随机森林)
      • 在使用和训练时有几个因素是尤其需要我们注意的:
      • (7)集成方法—提升法(Adaboost)
    • 4、监督学习中的回归模型
      • (1)回归——线性回归(连续值)
      • (2)回归分类——逻辑斯特回归
      • (3)回归分类—人工神经网络
        • 反向传播算法
        • 梯度下降法
        • 人工神经网络当中需要我们注意的问题:
      • (4)回归树与提升树
        • GBDT详细算法:
    • 5、无监督学习
      • (1)聚类——K-means
      • (2)聚类——DBSCAN算法
      • (3)聚类——层次聚类
      • (4)聚类——图分裂
      • (5)非监督算法——关联规则
      • (6)半监督学习——标签传播算法

挖掘建模

1、机器学习与建模

学习:通过接收到的数据,归纳提取相同与不同
机器学习:让计算机以数据为基础,进行归纳与总结
模型:数据解释现象的系统
机器学习依据是否有标注可以分为:

监督学习就是有标注的机器学习过程。标注相当于告诉模型在什么样的数据特征下应该输出什么样的结果,机器学习的任务就是提炼出输入与标注间的关系,并进行预测。根据标注是离散值还是连续值,监督学习又分为分类过程和回归过程,如果标注是离散值,但它就是分类学习;如果标注是连续值,他就是回归学习。如果这个机器学习的过程没有标注,那它就是非监督学习,非监督学习是完全让数据自己说话,将数据自身的特征在不同的模型中进行不同的表现,非监督学习常见的有聚类分析和关联分析。有些机器学习的过程是部分有标注,部分没有标注的,这样的机器学习叫做半监督学习。半监督学习中有标注的数据可以作用于没有标注的数据,规范与引导聚类或者关联的方向,同时没有标注的数据也可以作用于有标注的数据,时刻获得模型对于数据整体的影响与反馈。

2、训练集、测试集、验证集

我们会把一份数据集,分成三个部分,即训练集,验证集和测试集。这三部分数据集的比例一般可以取6:2:2,它们各有各的用途。
训练集:用来训练与拟合模型,也就是说一个模型的参数是由训练集决定的。训练集的数据量越多,模型相对于整个数据集就会越准确。但训练集的数据量的增多,应该是以数据集整体数量的增多而不是通过提升训练集在整个数据集的比例来增长数据量。
验证集:当通过训练集训练出多个模型后,为了能找到效果最佳的模型,使用各个参数对验证集数据进行预测,并记录模型的准确率等评价指标,选出效果最佳的模型所对应的参数作为模型的最终参数。
测试集:通过训练集和验证集得出最优模型后,使用测试集进行模型的预测,用来衡量这个模型的性能和分类能力,我们可以把测试集当做从来不存在的数据集,将已经确定模型的参数使用测试集进行模型的泛化能力评价。
泛化能力:这里说的泛化能力就是模型面对训练集和验证集以外的未知数据或者实际场景的数据时预测能力的大小。如果一个模型在训练集和验证集表现良好,而测试集表现不好,那么该模型的泛化能力就比较差,这种现象也叫做过拟合现象。
交叉验证:一份数据集切分训练集、验证集、测试集的方法,这种方法可以叫做交叉验证。有的时候,我们会忽略验证集通过不断地重复的尝试来达到验证的目的,这样一个数据集就会只分为训练集和测试集,它的比例通常取4:1,也就是8:2,这些切分一般是随机的,为了全面衡量模型的质量,我们有时也会采取K折交叉验证。
K折交叉验证的思路就是把数据分成k份,如果不考虑验证集拿其中一份做测试集,其它的作为训练集考察模型一次,然后再拿另外一份做测试集,其它的作训练集再考察一次,以此类推,直到k份数据全部被当做过测试集,此时对模型的考察是比较全面且稳妥的。

def hr_modeling(features,label):#区分训练集和测试集from sklearn.model_selection import train_test_split#features、label是dataframef_v=features.valuesl_v=label.values#我们需要得到6:2:2的比例,需要分两步进行切分#第一步,先得到验证集的数量,它占总体的20%X_tt,X_validation,Y_tt,Y_validation = train_test_split(f_v,l_v,test_size=0.2)#第二步,训练集:测试集=3:1,测试集占25%X_train,X_test,Y_train,Y_test = train_test_split(X_tt,Y_tt,test_size=0.25)print(len(X_train),len(X_validation),len(X_test))#结果为:8999 3000 3000

3、监督学习中的分类模型

分类模型主要涉及:KNN,朴素贝叶斯,决策树,支持向量机,集成方法,罗吉斯特映射,人工神经网络。其中罗吉斯特映射和人工神经网络大多数既可以做分类,也可以做回归。它们主要是以回归为主。

(1)KNN

距离的概念:
上一章我们已经学会了,怎么把属性都转换成数值类型。如果属性都成了数值,那每个属性都可以看作是一个维度,每个对象都是一个空间中的坐标,那么数据表中的对象与对象之间就会有它的距离。关于距离我们常用的公式有:


闵可夫斯距离公式中的P,P=1即曼哈顿距离;P=2即欧氏距离。
KD-Tree的概念:


如果一个空间中有很多的点,那么怎么去找我们随机指定的一个点附近的最近的k个点呢?
法1就是遍历每个点,然后进行从小到大的排序,但效率低下。
法2即KD-Tree,通过树形的结构,可以达到快速寻找最近点的目的。举例:首先将空间上的十六个数据用一种维度(竖线)分成两部分,两部分数量尽可能保持一致,然后拿其中的一个部分,再进行另外一个维度上(横线)的切分,又分成两部分,以此类推,直到不能切分为止,其它部分同样如此。之后,这个空间里就会分成许多大小不一的格子,每个格子都通过我们这里的线建立成一个树形的索引。这些深色的点对应图当中的线(即中间节点),而这些白色的点(即叶子结点)对应图当中的点,就可以形成这么一个树形结构。有了这样的树形结构,我们就可以很好的去找到一位点附近的最近的k个点。
比如我们这里出现一点,我们要找到离他最近的一个点:我们通过索引可以快速找到这个点,和哪个叶子结点在同一个区间内。于是我们可以计算出这个距离,但这个点不一定是离他最近的一个点,所以我们需要以这段距离为半径做一个圆,我们会发现一个或者几个与它相交的线。这样的话,我们就找到了这么一个中心节点,而通过这个中心节点,我们就可以快速的锁定的哪个叶子节点,可能离他更近。
KNN(k-Nearest Neighbors,K个最近的邻居)主要思想:
一个数据集都会有它的标注,如果说我找到了一个点,它K个最近的邻居,一种标注大于了另外一种标注,那么我们就认为这个点更倾向于与多数点是一致的。

举例:假设黑点为未知点,指定KNN的K=5,我们找到它最近的五个邻居,可以看到红色的点有三个,白色的点有两个,这样的话我们这个锁定的黑点就会判别成和这个红色的点同一个类型。

#接在def hr_modeling(features,label):函数里面
#KNNfrom sklearn.neighbors import NearestNeighbors,KNeighborsClassifiermodels=[]#n_neighbors指定邻居的数量knn_clf = KNeighborsClassifier(n_neighbors=3)knn_clf_n5=KNeighborsClassifier(n_neighbors=5)#对训练集进行拟合,得到一个模型knn_clf.fit(X_train,Y_train)knn_clf_n5.fit(X_train,Y_train)#用验证集进行验证Y_pred = knn_clf.predict(X_validation)Y_pred_n5 = knn_clf_n5.predict(X_validation)#衡量指标from sklearn.metrics import accuracy_score,recall_score,f1_scoreprint("validation,n=3:")print("ACC:",accuracy_score(Y_validation,Y_pred))print("REC:",recall_score(Y_validation,Y_pred))print("F_Score:",f1_score(Y_validation,Y_pred))   print("validation,n=5:")print("ACC:",accuracy_score(Y_validation,Y_pred_n5))print("REC:",recall_score(Y_validation,Y_pred_n5))print("F_Score:",f1_score(Y_validation,Y_pred_n5)) #用测试集进行对比Y_pred = knn_clf.predict(X_test)print("test:")print("ACC:",accuracy_score(Y_test,Y_pred))print("REC:",recall_score(Y_test,Y_pred))print("F_Score:",f1_score(Y_test,Y_pred))   #用训练集进行对比Y_pred = knn_clf.predict(X_train)print("train:")print("ACC:",accuracy_score(Y_train,Y_pred))print("REC:",recall_score(Y_train,Y_pred))print("F_Score:",f1_score(Y_train,Y_pred)) #综上对比来看:#多次刷新结果进行对比,发现每次测试集都略低于训练集,#可能是有些过拟合,但是不明显,可以忽略#存储模型from sklearn.externals import joblibjoblib.dump(knn_clf,"knn_clf")#使用模型knn_clf=joblib.load("knn_clf")


改进的KNN代码

    #改进的KNNfrom sklearn.neighbors import NearestNeighbors,KNeighborsClassifier#衡量指标from sklearn.metrics import accuracy_score,recall_score,f1_scoremodels=[]#n_neighbors指定邻居的数量models.append(("KNN",KNeighborsClassifier(n_neighbors=3)))for clf_name,clf in models:clf.fit(X_train,Y_train)#下标为0是(X_train,Y_train);下标为1是(X_validation,Y_validation);#下标为2是(X_test,Y_test)xy_lst=[(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]for i in range(len(xy_lst)):#i=0即训练集,i=1即验证集,i=2即测试集x_part=xy_lst[i][0]y_part=xy_lst[i][1]y_prd=clf.predict(x_part)print(i)print(clf_name,"-ACC:",accuracy_score(y_part,y_prd))print(clf_name,"REC:",recall_score(y_part,y_prd))print(clf_name,"F_Score:",f1_score(y_part,y_prd)) 

(2)朴素贝叶斯——适合离散数据


举例:账号是真实占比多的可能性大,还是虚假?



朴素贝叶斯的朴素的含义:特征之间相互独立


若数据中有0的存在,会使得结果无意义,我们就将所有的概率加1再计算,这就是拉普拉斯平滑。

(3)生成模型与判别模型

生成模型:通过先求输入与输出的联合概率分布,再求解类别归类的概率。例如:朴素贝叶斯。对数据要求高,速度快一些。
判别模型:不通过联合概率分布,直接可以获得输出对应最大分类的概率。例如:KNN。对数据容忍程度高,速度慢一点,使用范围更广。

(4)决策树

决策树就是模仿我们做决策的过程,一步步按照特征进行判断。
举个例子:小红的妈妈对小红说,我给你介绍个对象呗。女孩儿就问,跟他大于30岁了吗?等等

上图就叫决策树,决策树的叶子节点都是我们所认为的标注的内容(见或者不见),中间节点都是特征(年龄,收入,是否帅气)。特征确定,标注也确定,那么根据特征和标注,我们就可以构成这样一颗树来帮助我们去进行决策。在构造决策树的时候,有一个问题就是说这些特征的顺序应该如何摆放?–评价手段、方法
信息增益-ID3:
熵代表的是随机变量或整个系统的不确定性,熵越大,随机变量或系统的不确定性就越大。信息增益就是一个事件的熵减去一个事件(在一个条件下)的熵,两个熵相减就是熵的变化的大小,而熵变化的大小就可以认为x这个特征对他影响的大小。X影响越大,熵的增益就越大,x这个特征越应该优先考虑。


举例:

信息增益率-C4.5:

Gini系数-CART:

Ck:各个因子的数量 D:它的总数
决策树的几个问题:

连续值切分:将连续值进行从小到大的排序,然后对每个间隔进行一次切分,计算这个切分后的各个因子,取该因子性能最好的连续值切分,作为它的切分。(计算每个分隔)
规则用尽:比如说我们前面的例子,它有四个特征,有可能四个特征都用完了,但是所剩的最后的数据集合,它还没有切分干净,那么这样我们可以采用投票的方式,就是哪个样本多,我们就选那个。当然我们也可以接着使用特征进行切分,也就说一个特征,可以用多次这样的方式来进行进一步的细分,最终得到没有杂质的叶子节点,这也是一种方法。(投票)
过拟合:如果一个特征可以切分多次的话,那么最终我们总可以得到一个100%的切分方案,但是这样也可能会带来一些过拟合的问题。也就是说你训练的时候可以训练到百分之百,但是在真实用的时候,它有性能可能会非常的差。这时候我们要考虑进行剪枝。
剪枝分为前剪枝和后剪枝。前剪枝:构造决策树之前,我就规定了每个叶子节点,他最多有多少个样本,或者规定了这颗决策树的最大深度。后剪枝:我们先想尽一切办法构造出这个决策树,然后我们对一些样本值比较悬殊的枝叶进行修剪。比如说在收入一般的情况下,帅:不帅=100:1,比例非常悬殊,那就说明我们的样本当中可能不帅的样本比较少,没必要再做这一步的决策了,所以这个时候我们就可以直接选择见面,把帅不帅的选择删掉。


绘制决策树:

#接在def hr_modeling(features,label):函数里面#决策树from sklearn.tree import DecisionTreeClassifier,export_graphviz#绘制决策树import osimport pydotplusos.environ["PATH"]+=os.pathsep+"E:/Graphviz/bin" #设置环境变量from sklearn.externals.six import StringIO#衡量指标from sklearn.metrics import accuracy_score,recall_score,f1_scoremodels=[]#n_neighbors指定邻居的数量#models.append(("KNN",KNeighborsClassifier(n_neighbors=3)))#models.append(("GaussianNB",GaussianNB()))#models.append(("BernoulliNB",BernoulliNB()))models.append(("DecisionTree",DecisionTreeClassifier()))#信息增益的决策树models.append(("DecisionTreeEntropy",DecisionTreeClassifier(criterion="entropy")))for clf_name,clf in models:clf.fit(X_train,Y_train)#下标为0是(X_train,Y_train);下标为1是(X_validation,Y_validation);#下标为2是(X_test,Y_test)xy_lst=[(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]for i in range(len(xy_lst)):#i=0即训练集,i=1即验证集,i=2即测试集x_part=xy_lst[i][0]y_part=xy_lst[i][1]y_prd=clf.predict(x_part)print(i)print(clf_name,"-ACC:",accuracy_score(y_part,y_prd))print(clf_name,"REC:",recall_score(y_part,y_prd))print(clf_name,"F_Score:",f1_score(y_part,y_prd)) #绘制决策树法1dot_data=export_graphviz(clf,out_file = None,feature_names=f_names,class_names=["NL","L"],filled=True,rounded=True,special_characters=True)graph=pydotplus.graph_from_dot_data(dot_data)graph.write_pdf("dt_tree.pdf")#绘制决策树法2#dot_data=StringIO()#export_graphviz(clf,out_file = dot_data,#feature_names=f_names,#class_names=["NL","L"],#filled=True,rounded=True,#special_characters=True)#graph=pydotplus.graph_from_dot_data(dot_data.getvalue())#graph.write_pdf("dt_tree2.pdf")def main():features,label=hr_preprocessing()hr_modeling(features,label)if __name__=='__main__':main()

安装Graphviz:

下载安装包:https://graphviz.org/download/,点击安装
win+r进入cmd,查看是否安装成功:dot -version

在anaconda prompt中输入conda install pydotplus,安装pydotplus包

(5)SVM(支持向量机)

在之前处理数据的过程中,我们应该可以感受到,如果把一条数据的每个属性都当做一个维度的话,那么一条数剧所代表的对象就是一个空间中的点,我们经常可以容易想象到二维空间或者三维空间中的点儿,对高维空间中的点缺乏想象,所以接下来我们用二维空间来直观的说明SVM。
下图左图所示:这个示例图里有两个标注的数据。如果我们想一个简单的分类器,即用一条线把它们区分开,我们可以怎么分呢?类似的方法有无数多种,但这无数多种划线的方法当中只有一种区分方法,在我们可以充分将样本分开的情况下,它可以最大限度地将两个标注的样本进行区分。也就是说两个标注样本中分别找出离这条线最近的点,它们离这条线的距离是一样的,并且他们离这条线的距离和是最大的,这样的切分就是区分度最大的切分方法。此时离这条线最近的两个标注中的样本就是SVM中的所谓的支持向量。


上图所示:实线代表了切分的超平面。两个虚线的位置为经过支持向量与超平面平行的位置,它们分别与实线的距离就是ε。
多维空间中的维度可以用向量x来表示,它的分量代表各个维度,w向量是它的参数(参数是未知的)。多维空间中的面,也叫超平面,我们就可以用如下的式子来表示。分界面是指将两种样本都区分开来。考虑到多数情况下样本点不会到到这条直线上,会与这条直线会有一段距离,所以我们可以假设这段距离为ε。在同尺度变换的情况下,w和b实际上代表了超平面的方向相对于方向的位置,所以可以等效为不变,但实际上这些变化隐藏在了我们最终求得的答案里。y代表的就是标注(1-1)。

在三维空间下,点到面的距离公式如下:

说明:这里的A、B、C就等效于我们的参数w,D就是偏置b,x0,y0,z0就是待求的一个三维点,点到面的距离就是d,高维空间中,这个公式依然是成立的。那么在刚才的式子当中呢,在支持向量中,分子是可以取到等号的。也就是说它的分子实际上就等于1,我们最终的目的是求使这个间隔最大的切分,所以我们求两组支持向量距超平面的距离的和的最大值就是如下表示。

它通过一个式子,把所有的标注都考虑进来,然后我们求它的最大值即可解除我们的w和这里出现的其他参数,如a和b等等。需要注意的是,这里的参数a一定是大于零的。
上述计算都是在理想情况下的,实际的情况可能会复杂许多。
通常情况下正负标注不是线性可分的。我们就有了两种思路来解决这些问题,第一种思路就是容忍一部分的错误归类。

虽然我控制不住越过了超平面,但我可以控制让你的影响尽可能小。这个是我们说的第一个思路。
那第二个思路就是扩维。比如:我们可以在x1和x2两个维度基础上,再生成一个第三维度,即x1的平方加上x2的平方,相当于将每个标注坐标离中心距离这个特征进行的提取。映射到三维就会得到如图所示的结果,可以通过一个三维上的超平面将它区分开。

扩维:很难确定到底扩维到哪里最好,所以只能不断尝试。–淘汰

改进扩维方法:


多项式核函数在确定d之后,它的维度也就确定了。
RBF核函数可以将空间切分为无限维,但也极可能导致过拟合。
对比:

几个问题:
少部分异常:



SVM最佳分类切分如图。但有一个点对整个分类的影响非常大,如果不考虑它,对着它切分,我们就可以得到一个间距更大的分类器。对于这种情况引入松弛变量的含义,松弛变量就是在原来的式子里加入一个变量,这个变量就是松弛度的衡量,它为了达到一个更宽的分界线,可以容忍少量的错分点。加入松弛变量后,我们的超平面就变成上述中间图所示。它虽然有一个错分类,但得到了更宽的分类间隔,很有可能会减少过拟合的出现。
样本不平衡:

如图,白色点有这么多,而红色的点只有一个,如果用SVM分类,我们会在正中间切分,但实际上因为白色点很多,拿分布的概率来说,集中的分布概率是很小的,所以其实更有可能这个边界是靠近白色的部分。这类问题通常是根据实际业务场景来定最后的方案的。如果确实只是由于采样不科学等操作误差引起的,那么我们就可以对不同的标注赋予不同的权值,从而影响超平面的边界位置。
多分类问题:
我们之前讲到的都是二分类,如果有多个分类,我们该怎么处理呢?有两种思路,一种思路是有几个分类,我们就建几个SVM。找成功分类,并且离超平面距离最远的那一个作为正确分类。而另外一个思路就是分类的两两之间分别建立SVM。比如说我们有四个分类的话,一共就有6个支持向量机;要么就是过来的时候,我们两两间进行比较进行分类,取出一个被分类次数最多的那一个类,作为我们的svm分类。
代码尝试:

#接在def hr_modeling(features,label):函数里面
#SVMfrom sklearn.svm import SVCmodels.append(("SVM Classifier",SVC()))#C指的是对错分类的点的惩罚,C越大,惩罚越高,分类越准确,计算速度越慢。#C控制分类的准确性#models.append(("SVM Classifier",SVC(C=10000)))

(6)集成方法—袋装法(随机森林)

每种算法的复杂程度不同,适用的范围也不一样。同一个问题我们可以用不同的分类器进行判别,针对于某一条数据,可能不同的分类器的判断会有不同,那如果充分考虑这几个分类器判对或者判错的规律
就很有可能发现进一步提升分类整体质量的方法,那么在机器学习的问题中,将很多的机器学习算法组合在一起得到可能会比单一算法
性能更好的计算结果,这样的思路就是集成学习的方法。
集成学习就是组合多个模型以获得更好的效果。
我们的分类器其实就是一种算法,一个算法就会有它的算法的复杂度。我们常见的算法复杂度一般有以下这些

n指的是我们的数据规模;p、m都是常数
现在统一把时间复杂度和空间复杂度叫做它的算法复杂度。
第一个:算法复杂度是一个n的p次方,也叫做多项式复杂度。p决定了它多项式的阶数。第二个叫做阶层复杂度;第三个叫做指数级的复杂度。
所有算法的复杂度随着规模的扩大复杂度都会扩大。
因此我们设计的算法应该尽可能的设计出多项式复杂度的算法,另外两个容易耗尽数据。
如果一个分类计算法是一个多项式复杂度的学习算法,如果这个算法的效果比较明显比较好,我们就把它叫做强可学习。反之,它的效果不是很明显不是很好,我们就认为它是弱可学习。
模型的集成方法就可以理解成将几个弱可学习的分类器集合成一个强可学习的分类器的过程。
集成思想用到的具体的方法分为两个大类:袋装法、提升法。
袋装法的思想就是我们用训练集同时训练出几个独立的模型,而在进行预测和判断时,我们分别让被训练出的几个子模型去进行判断,然后对于分类问题,我们让他们去投票,他们投票选出的最多的结果就是我们最终判断的结果。对于回归问题,回归时这里取的就不是投票的结果了而是各个结果的参数。
注意:各个训练模型都是相互独立的,它没有之间的关系。
袋装法最典型的一个应用就是随机森林算法。森林里都是树,所以随机森林里就会有很多的决策树,就像袋装法定义的一样,这些决策树都是相互独立的,它们都是独立训练的,它们之间互不影响,那么最终的分类器我们要看每棵树的结果,然后让他们投票,选择票数最高的结果作为最终的判别结果。

在使用和训练时有几个因素是尤其需要我们注意的:

第一个就是树的数量,树的数量越多,考虑到的样本的局部性的可能情况也就越多。但树的数量越多,就越容易过拟合。树的数量和样本数量、特征数量都有关系,这个需要我们不断的尝试进行确定。
第二个就是每棵树用到的特征数,如果我们假定树的数量是n颗,那么每棵树选择多少个特征比较合适,这是一个问题。那么在特征比较少的时候,一般是少于50个特征的时候,我们就可以选择采用全部的特征来进行训练,也就是说每棵树都采用全部的特征。
树与树之间的差异性,我们主要通过训练集的差异性来进行体现。
如果特征比较多的时候,比如说达到了几百个或者上千个特征,那么每棵树我们就可以随机的选择少于全部特征数量的特征进行训练。与此同时,我们可以通过增加树的数量和增加并行计算的能力来平衡特征减少带来的可能的损失。
第三个就是树的训练集该怎么选,一般每棵树的训练集都是我们模型训练集整体的一个子集。子集怎么产生,数量怎么定也是一个问题。
这里介绍一种选择子集的方法:我们可以把选择的子集数量定位和输入的模型的训练数量是一致的,只是我们对它进行有放回的采样。采用过后大概率的会有某些样本被采样到两次或者更多,某些样本根本就没有被采样到,某些样本在某棵树被采样而在其他树没有被采用到,这样就通过样本构成了树的差异性。当然我们也可以不放回,每棵树都采用全量的样本。如果是这样,那要体现出数的差异性就必须通过缩减特征的规模来使树的特征有差异。试想每棵树如果我们都使用全量的测试集同样也使用全量的特征,那么每棵树产生的结果也都是一样的,也就是说每棵树都是一样的决策树,那么这样只是浪费了资源,得不到其成应有的效果。
可见随机两个字,可以认为每棵树训练及样本的随机,也可以是每棵树特征的随机,也可以是特征和样本这两方面的随机。
决策树带来的好处:首先,每棵树可以不使用全部特征,这样减小了计算规模和模型的复杂度但也可以得到不错的效果。其次,我们通过前面的例子知道,如果决策数把参数定的灵活一些就非常容易出现过拟合,而随机森林因为分成了多棵树,即使一棵树过拟合了,由于最终结果是个投票的结果,所以整体对过拟合是有很好的抵御性的。
代码:

#接在def hr_modeling(features,label):函数里面
#随机森林from sklearn.ensemble import RandomForestClassifiermodels.append(("RandomForest",RandomForestClassifier()))#不填参数,默认十个决策树(n_estimators),方法为gini,特征为auto-sqrt,,#bootstrap(是否进行有放回的采样)默认为TRUE(放回),#输入样本数和样本数规模相同models.append(("RandomForest1",RandomForestClassifier(max_features=None)))#max_features=None表示取全集#--结果总体和之前默认的差不多models.append(("RandomForest2",RandomForestClassifier(max_features=None,bootstrap=False)))#--结果总体不如之前默认的models.append(("RandomForest3",RandomForestClassifier(n_estimators=71,max_features=None)))#--结果总体比之前默认的好一点

(7)集成方法—提升法(Adaboost)

袋装法是把几个不同的分类模型进行独立袋装,然后投票表决。几个子模型间是互相独立的、互不影响的。如果我们把这些子模型串联起来,一个模型以另一个模型的结果为基础进行训练和预测,然后多个模型级联,最终将每个训练模型的结果进行加权求和得到判决结果。这样的思路就是提升法。
注意:最后的结果是各个模型的加权叠加,它并不是最后一个模型的输出。子模型对样本的差别的影响,更大程度上取决于最终的权值,而不是它的顺序。
提升法的一个例子——Adaboost
首先,是初始化训练数据的权值分布D1。假设有N个训练样本数据,则每一个训练样本最开始时,都被赋予相同的权值:w1=1/N。
然后,训练弱分类器hi。具体训练过程中是:如果某个训练样本点,被弱分类器hi准确地分类,那么在构造下一个训练集中,它对应的权值要减小;相反,如果某个训练样本点被错误分类,那么它的权值就应该增大。权值更新过的样本集被用于训练下一个分类器,整个训练过程如此迭代地进行下去。
最后,将各个训练得到的弱分类器组合成一个强分类器。各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。
换而言之,误差率低的弱分类器在最终分类器中占的权重较大,否则较小。
优点:如果我们不考虑它的复杂度的话,它的精度是非常高的,并且是可以灵活调控的;几乎不用担心过拟合的问题;因为它会不断的进行适应性的一种提升,所以我们可以简化特征工程的流程。
代码:

#接在def hr_modeling(features,label):函数里面
#AdaBoost
from sklearn.ensemble import AdaBoostClassifiermodels.append(("AdaBoost",AdaBoostClassifier()))#random_state随机数种子值 #base_estimator进行弱分类的基本分类器,默认决策树#n_estimators级联分类器数量,默认50个#learning_rate,默认为1,--根据0~1的数进行衰减,不断*learning_rate#algorithm:依据base_estimator进行选择models.append(("AdaBoost1",AdaBoostClassifier(n_estimators=100)))#结果差不多,不太能提升models.append(("Adaboost2",AdaBoostClassifier(base_estimator=SVC(),algorithm="SAMME",n_estimators=100)))#结果差不多,不太能提升

4、监督学习中的回归模型

(1)回归——线性回归(连续值)

回归分析即确定多个变量间相互依赖的定量关系的一种统计方法。其中自变量叫特征,因变量叫标注。如果多个变量间的关系用线性关系去表示即线性回归,如果用多项式关系去表示即多项式回归等等。
如何去判断哪个拟合效果会更好?——模型的复杂度和准确度两方面,最重要的是它对未知数据的预测的准确性。
——用验证集的误差大小去评判回归效果最终的好坏
如果我们感觉到一个变量和几个变量间是正相关关系或者是负相关关系,可以先试试线性回归,用它做个粗略的估计,如果效果比较好,就可以直接用线性回归作为我们的回归分类器。也可以把线性回归的结果当做一个标准,如果一个回归函数它的效果好于线性回归并且也能够有效的预测未知变量,那么我们就可以使用回归函数。
最小二乘法是一种解决线性回归的问题的解法。
线性回归的过程(当然这些都是连续值):
参数矩阵W就是我们的系数;矩阵X就是数据的特征所构成的矩阵,
这里的x1、x2对应特征表格的一行;Y就是我们的标注的矩阵。
我们的目标是在线性变换后,让H(X)值与Y的差尽可能小。

两种方法:上面的是用矩阵理论的知识求解最小二乘法的方法,下面的是根据最小二乘法确定参数。这两个方法实际上是等效的,只是表达方式不同。
最小二乘法的本质上是在求这个函数的最小值。

这里的1m/2是一个系数的作用;也可以写成m/1,表示平均误差和;或者在求解时我们可以把它略去,它在表征含义时有它的作用,但实际计算时其实我们是可以不考虑这个参数的。

凸函数满足于如下性质:如果函数上的值小于它们两个值中间的连线上的值,那么它就是凸函数。如果说一个函数是凸函数的话,那么它的极小值就是最小值,相应的优化过程也叫做凸优化。
参数间的间距可能会非常大,或者它虽然是个极小值但不是我们需要的最小值——结果就是可能有些特征的权值就会被放大,有些权值就会被弱化,也有可能最终结果的预测效果非常的差。——我们可以利用正则化来解决这些问题。

+后面式子的意义就是说有的参数可能会比较大,有的参数可能会比较小,那么如果加上这一项,它就更倾向于选择参数比较小的值,而放弃参数比较大的选择。
如图:α取得越来越小,即这一块的权值取得越来越小,会造成W的大小差距会非常的大,有可能过拟合大的权值,它的决定权就更大一些,而小的权值就基本上没有什么话语权,从而造成了过拟合。
代码:

#改变main函数,并新增一个函数
#线性回归
def regr_test(features,label):#print("X",features)#print("Y",label)from sklearn.linear_model import LinearRegression,Ridge,Lasso#回归方程#regr=LinearRegression()#岭回归#regr=Ridge(alpha=1)#不断改变的值,可以发现岭回归在这里的作用不太明显#Lassoregr=Lasso(alpha=0.002)regr.fit(features.values,label.values)Y_pred=regr.predict(features.values)#拟合之后确定的参数print("Coef:",regr.coef_)#衡量回归方程的好坏from sklearn.metrics import mean_squared_error#平均平方误差print("MSE:",mean_squared_error(Y_pred,label.values))def main():features,label=hr_preprocessing()regr_test(features[["number_project","average_montly_hours"]],features["last_evaluation"])#hr_modeling(features,label)#print(hr_preprocessing(lower_d=False,ld_n=3))

(2)回归分类——逻辑斯特回归

s曲线来模拟一个生物的种群由诞生到发展到顶峰最后衰退(此处删去)的过程,这样的模型叫做逻辑斯特增长模型/逻辑斯蒂增长模型。它实际上是一个微分关系,拟合了一个函数,n指的是种群的数量,t时间。这里就有n和t两个变量,而它的增长速度是和种群数量直接相关的。这个式子就是逻辑斯特的基本解。


现在我们常说的逻辑回归,它表面上是回归,其实更多的情况下我们是把它当做一个分类器来用的,式子如上右图。如果有标注0和1,通过回归方程,它可以通过最后拟合结果是小于0.5还是大于0.5来进行分类判断,而分类时用到的参数和特征是以线性变化的方式放在函数上。
从本质上来说,逻辑回归也是一种特殊的线性回归,是一种有形变的线性回归,它不能说是一种完全意义上的非线性回归。一般的线性回归它的值域是无穷大的,逻辑回归的值域它是有限的。逻辑回归解决非线性问题的思路和我们之前讲到的支持向量机是一致的。如果我们可以把特征映射到高维,那么也可以用逻辑回归的思想来解决高维分类问题。逻辑回归的解题思路,和回归方法的思想是一致的,它也是求这么一个函数的最小值,而这里h代表的就是逻辑方程的式子,也可以通过梯度下降方法求解。

#接在def hr_modeling(features,label):函数里面
#Logistic回归from sklearn.linear_model import LogisticRegressionmodels.append(("LogisticRegression",LogisticRegression(C=1000,tol=1e-10,solver="sag",max_iter=10000)))#penalty:"l1","l2"使用L1还是L2正则化#tol:最终计算的精度,到达多少时停止计算#C:C越大,则正则化因子所在比例越小#solver:默认线性算法(liblinear)还有sag,saga,lbfgs,newton-cg#max_iter:最大迭代次数

(3)回归分类—人工神经网络

人工神经网络也是一个分类和回归都可以使用的模型。
其实分类就是一种有限状态的回归,也可以认为是一种无限定序数据的分类,所以分类和回归的界限其实并不大,这些方法一般是可以在分类和回归中互相借鉴使用的。只是在处理的细节上可能需要我们特殊对待。
理解监督学习的分类和回归的目的:就是给了一些特征和特征对应的标注,通过整理这些特征和分类标注或者连续值。当一个未知数据过来的时候,我们应该尽可能的让新来的数据的特征和我们整理好的被给定的数据特征中最相似的数据特征保持一致的分类,或者保持相近的连续值。也就是说我们的测试集验证集的数据应该尽可能的找到训练集中与他们相近的数据的标注作为他们的标注,如果和它相似的标注不止一个,就可以采用投票或者取平均值的方式决定最终的值。这就是分类和回归。
分类和回归最简单的就是线性模型。分类是线性回归的特殊情况,即它回归的值只有0和1两类。但是分类效果很大程度上会受到离群点和异常值的影响,所以后来我们有了逻辑回归,把它的形状变成了曲线,这就有效的避免了刚才的问题。把一个线性回归硬生生的给掰成了罗吉斯特回归,就更有了作为一个分类器的样子。
我们可以从一种结构化的思维来理解这个模型
感知器:通过对特征的感知来做出它的判断
非线性变换:将感知器进行并联
如果我们纳入更多的感知器一级一级的连起来,就构成了我们今天要说的人工神经网络。
神经网络的这些线代表的都是参数,一条线代表一个参数,这些参数都是相互独立的每个节点。这里的节点都是将各个属性与参数乘积后进行相加再进行转换的过程。
神经网络一般是按照层级结构进行排列的。和特征直接相连的这一层就是输入层,神经网络的输入层是要求将全部的特征进行归一化的,也就是说要转换成0~1之间的数。
训练时直接与标注相连的这一层,也就是模型训练后要输出的这一层就是输出层。输出层也是有要求的,它必须是one-hot形式的。也就是说如果有三个类别,就必须是每个类别都占一位。
如果是回归问题,输出层可以只有一个输出,也可以一次性对于所有特征进行多个回归的计算,这样的话它的输出层也可能有多个输出。中间可以有一层也可以有多层,这些都是隐含层。隐含层是输入与输出进行非线性变换的重要过程,这其中对最终的收敛影响较大的是节点中的转换函数(激活函数)。
针对神经网络会有两种不同的解题方法,

反向传播算法

它主要分4步,第一步前向计算,当我们确定了人工神经网络的结构以后,参数就会被赋上随机值,不管这些值是多少,我们先把特征都输入,然后让他去进行前向的计算。第二步计算误差,第三步反向单层调整,是一个梯度调整的过程,但是我们只调整离输出层最近的这一层的参数,根据我们的误差,利用梯度下降进行调整。第四步传播,我们计算出了这一步的误差,然后我们就可以紧接着再往后走一层,调整下一层的误差,一层一层调整下去,直到进行一轮计算以后我们的调整结束,然后不断的迭代这个过程,直到最后模型达到收敛。收敛的条件我们可以认为达到一定的误差范围以内就认为它是收敛,也可以设定它的迭代次数,只要迭代次数到了也认为它是处于收敛的。

梯度下降法

但梯度下降法的参数特别多,针对特别多的数据进行参数的调整会比较复杂,所以这里我们引入了一个随机梯度下降法(Stochastic Gradient Decent)。它其实就是在每次调整权值的时候,不选取全量的样本进行梯度下降而是选取部分样本进行下降。好处很显然收敛速度更快,计算开销更少。问题是因为数据不全容易陷入局部的最优解而得不到我们的全局最优解。

人工神经网络当中需要我们注意的问题:

第一个问题 人工神经网络它比较易受离群点的影响容易被过拟合,解决的方法就是通过正则化或者drop out。正则化就是加一个l2正则因子或者l2正则因子,让神经网络倾向于选择参数比较小的解。drop out就是我们在每一层都随机的选出部分的节点组成多个神经网络模型,这样对于每一个神经网络来说,我们形成了多个简单的网络,最终的结果我们通过这多个网络的结果进行投票选出一个投票最高的结果认定最终的值,对于回归模型我们可以取平均。思路有点像我们之前讲过的集成的思想。
第二个问题 它的特征属性和结果都要在0~1之间,而且它的结果一定要是one-hot形式存在的。
第三个问题 它输出结果要进行softmax转换,它每个输出值其实就代表着这个输出所代表的概率。
神经网络的优势在于它可以将非线性做到特别好,拟合能力特别强。数学上我们也可以证明,只要宽度足够大深度足够深,神经网络就可以拟合任何非线性的映射。如果神经网络我们把它的深度加深,就是深度神经网络。通常用它来做图像识别、语音识别、自然语言处理等。
代码:利用Python来实现一个用作数据分析的神经网络模型
我们实现的方案是用Keras来构造一个基于随机梯度下降算法的神经网络模型

#更改hr_modeling(features,label)函数
def hr_modeling(features,label):#区分训练集和测试集from sklearn.model_selection import train_test_split#features、label是dataframe,求特征值f_v=features.valuesl_v=label.values#特征名称f_names=features.columns.values#我们需要得到6:2:2的比例,需要分两步进行切分#第一步,先得到验证集的数量,它占总体的20%X_tt,X_validation,Y_tt,Y_validation = train_test_split(f_v,l_v,test_size=0.2)#第二步,训练集:测试集=3:1,测试集占25%X_train,X_test,Y_train,Y_test = train_test_split(X_tt,Y_tt,test_size=0.25)print(len(X_train),len(X_validation),len(X_test))    #衡量指标from sklearn.metrics import accuracy_score,recall_score,f1_score#人工神经网络from keras.models import Sequential#Sequential可以理解为神经网络的一个容器,它是序列的from keras.layers.core import Dense,Activation#Dense神经网络层,即稠密层#from keras.optimizers import SGD--现在的版本已经不用这个代码表示了from keras import optimizers#SGD随机梯度下降算法mdl=Sequential()#构建模型#先建立一个稠密层表示它的输入#Dense表示输入层层数为50,input_dim表示它的维度,要和你的特征维度一致mdl.add(Dense(50,input_dim=len(f_v[0])))mdl.add(Activation("sigmoid"))mdl.add(Dense(2))#设置输出层为2维mdl.add(Activation("softmax"))#构建优化器#lr:learning ratesgd = optimizers.gradient_descent_v2.SGD(learning_rate=0.01)#编译#mean_squared_error:平均平方误差mdl.compile(loss="mean_squared_error",optimizer=sgd)#拟合#循环是为了将转变为one-hot形式#epochs:迭代次数#batch_size:每一次随机梯度下降所选取的数量mdl.fit(X_train,np.array([[0,1] if i==1 else [1,0] for i in Y_train]),epochs=1000,batch_size=2048)#这种参数设置召回率和F1都是0,效果不好,我们可以选择全部的数据,并且增大迭代次数#要是效果还不太好,我们可以增大学习率,但是学习率不宜增加太多,会导致错过全局最小点#所以在增大学习率到一定量后,可以选择更改优化器,可以将sgd换成adamxy_lst=[(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]for i in range(len(xy_lst)):#i=0即训练集,i=1即验证集,i=2即测试集x_part=xy_lst[i][0]y_part=xy_lst[i][1]#predict:输出的是连续值#predict_classes:输出的是分类值#有下面两行代码是因为现在的Keras已经不支持predict_classes了,#利用下面两行代码进行转换y_prd=mdl.predict(x_part)y_prd=np.argmax(y_prd,axis = -1)print(i)print("NN","-ACC:",accuracy_score(y_part,y_prd))print("NN","REC:",recall_score(y_part,y_prd))print("NN","F_Score:",f1_score(y_part,y_prd))         def main():features,label=hr_preprocessing()       hr_modeling(features,label)#print(hr_preprocessing(lower_d=False,ld_n=3))
if __name__=='__main__':main()

(4)回归树与提升树

回归树也是决策树的一种算法,只是我们要回归的值将会是一个连续值。
回归树和分类树区别:在分类树中,我们只要最终的叶子节点是有分类的判断值就可以了,而回归树当中,每个节点包括叶子节点、中间节点,都会得到一个预测值。一般来说预测值就是这些连续标注的平均值。
如果我们要针对某个特征进行分类,那么切分属性的依据也不再是商或者是基尼系数,而是相对于连续值更可靠的一种切分方法即最小方差的切分方法。也就是说如果我们根据某一个特征进行切分,一定要满足在切分后这两个部分的方差的和是最小的。
比如说在这里我们通过Feature_x0进行了切分,那么切分以后我们一定要保证这两部分的Label的方差它们的和是最小的。然后我们就可以套用其他特征进行同样的过程,那么这个过程中一个特征也是可以被使用多次的,直到满足回归数的停止条件,整个流程结束。
如果我们要进行预测,顺着回归树的特征一直到达叶子节点,取叶子节点的平均值作为它的预测值就可以了。
回归树直接应用的场景相对来说是比较少见的,更常见的是一种基于回归树的提升方法叫做提升树。
在提升树里,梯度提升决策树(Gradient Boosting Decision Tree,GBDT)效果最佳。

类比集成方法,第一棵树一般来说就是一个弱的学习器,它的拟合效果的误差应该会比较大,这个时候我们就要引入下一棵树了。下一棵树有一点不同,就是它的连续值的label不再是原来的值,而是在上一步预测后与原来的值的差分值。
比如:我们在上一步分类以后label:1、5 ,它的value是3;Label:20、22,它的value是21,那么它的差分值就是1-3=-2,5-3=2,20-21=-1,22-21=1,即label=-2,2,-1,1。然后第二棵树针对这些差分的值再进行同样的回归方法得到label,如果有第三棵树,就接着把第二棵树的差分值带入第三棵树当中,根据这些差分值进行回归分析。
一般来说梯度提升的这种决策树结构,它的泛化效果是非常不错的。

GBDT详细算法:

我们首先需要确定它的loss函数,目的是为了使loss函数最小。
首先我们初始一个值,初始这个值实际上我们可以认为它就是均值。
第二步实际上是一个迭代的过程。迭代一共有M步(M可指定),N指的是样本数量,这里是指对每个样本都计算它的梯度分量。
然后针对这些值我们进行一个拟合,会得到非常多的区域。这些非常多的区域就是我们最终做的判别区域。然后我们最小化这个函数,这个函数是上一棵树的预测值加上了这个差分值。那么直到最终M步迭代结束以后输出结果。
GBDT也是可以作为分类器的,只是分类器的连续值只有0和1。这里的导数也会换成我们刚才说的直接相减的差分值。
这几年有一个叫做陈天齐的大牛研究了一种类似于GBDT树的结构
它起名字叫Extreme greet boosting简称叫Xgboost
相比于GBDT,Xgboost不仅考虑了一阶导数,还有可能会用到更高阶的导数,并且Xgboost支持较大规模的并行计算,分类器的选择上更加灵活。

5、无监督学习

分类和回归都属于监督学习,监督学习的特点就是它们都有一个标注,而标注的存在就是给分类任务或者回归任务一个指引,告诉算法不同特征数据的名字,哪些数据是一样的,哪些数据是不一样的,都是通过标注来进行区分的。无监督学习是没有标注的,那我们的目的就是试图给这些数据加上标注,加标注有一个原则和假设。我们希望给没有标注的数据加过标注以后,同一个标注内的数据尽可能的相似,而不同标注内的数据应该尽可能的不同。即使是这样,由于应用的目的不同、方法不同,所以算法也不同。
无监督学习用的最多的是聚类算法和关联规则。

(1)聚类——K-means

聚类:将集合分成由类似的对象组成的多个类的过程。
四中聚类算法:基于切割的K-means算法、基于层次的聚类算法、基于密度的DBSCAN距离算法、基于图的Split距离算法。
基于切割的K-means算法采取的原则:所有类都有一个中心,属于一个类的点到它中心的距离相比于他到其他类的中心的距离会更近。
两个问题:中心如何定义;这个距离如何衡量——欧式距离。
K-means提出一种确定中心的方法:取数据各个维度的均值。
K-means具体算法:从n个样本中随机选取k个作为初始化的质心,k就是我们最终要聚的类的个数;对每个样本测量它到每个质心的距离,并把它归到最近的质心的类;重新计算已经得到的各个类的质心;重复往返的迭代第二三步,直到新的质心与原来的质心相等或者小于指定的阈值,算法结束。
注意几个问题:初始质心位置可能会影响最终聚类结果——解决思路:多试几次,取最稳定结果;个别离群值会影响整体聚类效果——解决思路:将取质心换成取中点(K-Medoids)。中点定是一个样本点,它的性质就是中点距其它和它同一类的点的距离的和是最小的。以中点作为判断思路的算法叫做K-Medoids算法;K-means算法的K怎么指定——解决思路:借鉴其他的衡量因子进行辅助(如轮廓系数、最小误差等)。
代码:

#k-means聚类
import numpy as np
import matplotlib.pyplot as plt
#生成样本
from sklearn.datasets import make_circles,make_blobs,make_moons
from sklearn.cluster import KMeansn_samples=1000
circles=make_circles(n_samples=n_samples,factor=0.5,noise=0.05)
#circles数据由样本点和标注组成
#factor指的是小圆和圆之间的间距
moons=make_moons(n_samples=n_samples,noise=0.05)
blobs=make_blobs(n_samples=n_samples,random_state=8)
random_data=np.random.rand(n_samples,2),None#2维colors="bgrcmyk"
data = [circles,moons,blobs,random_data]models=[("None",None),("KMeans",KMeans(n_clusters=2))]
#模型分为模型的名字和模型的实体,假设实体为Nonef=plt.figure()#inx,clt分别表示得到下标、实体
#聚类之前所有的点都是一个类,聚类之后所有的点都有了标注
#所以我们可以认为如果实体是空的话,定义一个clt_res代表聚类之后的标注,
#没有聚类之前默认它的值都是0
#如果有实体的话,这里是指KMeans
for inx,clt in enumerate(models):clt_name,clt_entity=cltfor i,datasets in enumerate(data):X,Y=datasetsif not clt_entity:clt_res=[0 for item in range(len(X))]#得到一个和X长度一致的全0序列,即它的标注是相同的else:clt_entity.fit(X) #实体拟合Xclt_res=clt_entity.labels_.astype(np.int)#聚类后得到labels,并转换为int格式#画图#行数:len(models)列数:len(data)绘图位置:inx*len(data)+i+1 f.add_subplot(len(models),len(data),inx*len(data)+i+1)plt.title(clt_name)#散点图利用scatter进行绘制[plt.scatter(X[p,0],X[p,1],color=colors[clt_res[p]]) for p in range(len(X))]
plt.show()

(2)聚类——DBSCAN算法

与K-means相比较,它只是换了一个假设,它的假设是一定区域内密度达到一定的程度它才是一个类,否则只能叫离群点。
两个问题:这个区域到底有多大;我们指定的密度有多大
E领域:给定对象半径为E的区域内称为该对象的E领域;核心对象:如果给定对象E领域内的样本点数大于等于MinPts,则称该对象为核心对象;直接密度可达:对于样本集合D,如果样本点q在p的E领域内,并且p为核心对象,那么我们就说对象q从对象p直接密度可达;密度可达:对于样本集合D,给定一串样本点p1,p2…pn,p=p1,
q=pn,假如有对象pi从pi-1直接密度可达,那么对象q从对象p是密度可达;密度相连:如果存在样本集合D中的一个点o,如果对象o到对象p和对象q都是密度可达的,那么p和q就是密度相连的。
DBSCAN算法最主要的任务就是找到密度相连对象的最大集合。
优点:如果我们指定了合适的E领域的半径和E领域的点,那么它对离群点是不敏感的。缺点:计算一个点相邻的点不是特别容易的,所以我们需要一些辅助的数据结构来帮助我们。并且如果使用DBSCAN的话,需要先尝试解决这两个参数的问题再进行计算。
代码:

#DBSCAN算法
#在k-means聚类的基础上修改代码,下面只列出需要修改的部分
from sklearn.cluster import KMeans,DBSCAN#这里增加center_box让x、y轴的范围属于(-1,1),增加cluster_std(方差)用来调参
blobs=make_blobs(n_samples=n_samples,random_state=8,center_box=(-1,1),cluster_std=0.1)#增加DBSCAN模型,并利用eps进行调参
models=[("None",None),("KMeans",KMeans(n_clusters=3)),("DBSCAN",DBSCAN(min_samples=3,eps=0.3))]
#模型分为模型的名字和模型的实体,假设实体为None

(3)聚类——层次聚类

层次聚类的思路:聚类要求相近的点要尽可能的接近,我们这里有六个点,我们每一层挑选最近的两个点相连,不断分类。聚类是一层一层进行的,直到不能再分为止。
簇和簇间的距离衡量方法:最短距离,把这两个簇中最相近的两个点的距离作为他们之间的衡量距离;最长距离,把这两个簇中相距最远的两个点的距离作为他们之间的衡量距离;平均距离,把这两个簇的中点之间的的距离作为他们之间的衡量距离;Ward法,它是利用一个公式来进行衡量。如果两个簇合成一个簇,它的ESS(离差平方和)增加的量越小,就越应该将它们合成一个簇。选择了ESS增加值比较小的那个值作为下一步的训练方法。
层次聚类,它的优点就是它聚类比较灵活,缺点,因为我每次在计算距离的时候,都会计算两点之间的距离,所以它的计算复杂度是比较高的。同时,他受到离群点影响比较大。

#层次聚类算法
#在DBSCAN算法的基础上修改代码,下面只列出需要修改的部分
from sklearn.cluster import KMeans,DBSCAN,AgglomerativeClusteringmodels=[("None",None),("KMeans",KMeans(n_clusters=3)),("DBSCAN",DBSCAN(min_samples=3,eps=0.3)),("Agglomerative",AgglomerativeClustering(n_clusters=3,linkage="ward"))]
#模型分为模型的名字和模型的实体,假设实体为None

(4)聚类——图分裂

第一步,根据坐标点的位置关系形成连通图;第二步,将形成好的连通图逐一的进行分裂。第一步可以采用类似DBSCAN的算法思路,找到最大范围的点数并用边将它们连接起来。第二步分裂的思路可以用两个因子辅助进行判断。
t乘数因子;w1选定边左边区域点的数量;w2选定边右边区域点的数量;n把一个图分裂开所需要的边的个数;分裂阈值;x最大连通图边的数量;y最大连通图点的数量;
t越小越不应该分开,越大越应该分开,利用分裂阈值来判断何时该分开(t比它大时分开,反之)。
注意:与基本层次聚类思路相反,为从顶向下;图建立方式、分裂方式可以非常灵活。

(5)非监督算法——关联规则

关联规则和序列规则相似,可以暂时认为是一种算法。
关联规则是反映一个事物与其他事物之间相互依存性与关联性。这其中最著名的一个例子,就是啤酒和尿布的例子。
关联规则的几个概念:
假设:100人去超市买东西,得到100张小票。
项目:一个字段,对交易来说一般是指一次交易中的一个物品。比如小票中每一个人所购买的物品就是一个项目,如尿布。
事务:某个客户在一次交易中,发生的所有项目的集合。比如:小票上买了好多东西,那么我们所买的这些东西的集合,就是事务。
项集:包含若干个项目的集合(一次事务中的)。比如:有一张小票,小票上各个项目和项目,它们之间的组合,我们可以构成一个集合。比如我买了啤酒、尿布、牛奶。它们之间可以有七种组合,(啤酒)、(啤酒、尿布)等等。
支持度:是项集{X,Y}在总项集中出现的概率(support)。比如,100个人中50个人买了啤酒和尿布,那么啤酒和尿布的支持度就是0.5。
频繁项集:某个项集的支持度大于设定的阈值(人为设定的,或者是根据数据的分布和经验来设定的),则称这个项集为频繁项集。如果说包含了某些固定项目的集合和数量特别多,就比如说今天有100个人中大部分人都买了啤酒和尿布,然后我们设定一个阈值,假设是50,那么只要有50个人同时购买了啤酒和尿布,我们就认为啤酒和尿布是频繁项集。
置信度:在先决条件X发生的条件下,由关联规则{X->Y}推出Y的概率(confidence)。其实就是一个条件概率的概念,在X发生的前提下Y发生的概率。100个人有60个购买了尿布,那关联规则就是尿布->啤酒,发现在这60个购买的尿布的人当中,有30个购买了啤酒也就说共同购买了啤酒和尿布的一共有30个人,只是购买了尿布的有60个人,置信度就是由30÷60=0.5。
提升度:表示含有X的条件下同时含有Y的概率,与无论含不含X含有Y的概率之比。它是一个比值,就是X->Y的置信度比上Y的支持度。当比值大于1,则意味着X对Y的概率具有提升作用,反之,则可以认为X和Y是无关的。
关联规则的目的就是找到其中的频繁项集,并且根据它的置信度、提升度,找到这些特征明显的相关关系,发现这些规律就有相应的算法。Apriori算法,基本思想是先指定一个支持度的阈值(因为支持度>阈值即为频繁项集)。项集中的个数可以分别代表1频繁项集,2频繁项集等等。两个1频繁项集组成的2项集不一定是频繁项集。比如,啤酒和尿布分别是两个1频繁项集,它们的数量比较多,但是它们构成的2频繁项集个数一定是小于等于原来1频繁项集的最小值的,这个数再和阈值比较,不一定依旧比它大。两个非频繁项集的组合一定不是频繁的。一个频繁项集和一个不频繁项集组合,也肯定是不频繁的。得到了这些规律,找频繁项集的方法,也就显而易见了。首先,我要找1频繁项集,然后去掉非频繁的1项集。因为他们的组合不会出现频繁项集。我们将1频繁项集组合在2项集中,然后根据阈值删去非频繁的2项集。使用2频繁项集再进行组合,再用阈值删去非频繁的3项集,以此类推,直到找到最高阶的,那么所有组合遍历完毕,全部的频繁项集算法结束,只需要输出频繁项集即可。
序列规则将时间因素考虑进来,剔除关联规则中时间点靠后的项对时间点靠前的项的支持。
Apriori-all算法分为两步:①Forward:Apriori;
②Backward:去掉时间序列之后的项对之前的项的支持。
应用距离:预测用户购买某物品后下次会购买啥物品作为搭配。

(6)半监督学习——标签传播算法

半监督学习:一部分有标注,一部分没有标注。在一般情况下,没有标注的样本要比有标注的样本多的多。我们的目标就是试图根据有标注的样本和样本总体的分布情况,给没有标注的样本打上标注。
半监督学习是由于标注本身的特点决定的,(1)获取标注的成本可能是比较大的,有些要买的标注是不能通过自动化方式实现和获取的。(2)无标注样本可能很容易获得,拿摄像机出去走一圈,拍好多照片,这些都是无标注的数据。
算法思路:
生成模型:先计算出样本特征的总体的联合分布,就可以根据生成模型思想,将所有有标注的样本计算出一个分布,然后把没有标注的样本放入这个分布中,看根据这个分布该如何被标注,当然这个过程有可能是迭代的,我们可以把非标注样本分批进行标注,比如我们可以先对有标注样本比较近的样本进行打标注的操作,然后调整分布,再划分接下来的样本。
判别思路:就是物以类聚的思路。典型的是标签传播算法。根据有标注的样本和周围没有标注的样本,进行相似度的比较,相似度高的,我们就把它标注成那个临近的标注。所谓的标签传播算法中的传播,实际上指的是一个类似刚才我们说的迭代过程。它优先标注样本里有标注样本比较近的无标注样本,然后把这些新被标注过的样本考虑进来,再进行传播标注。标签传播算法中有两种相似度计算的算法:rbf,knn。

rbf:x-y指的是它们之间的距离,γ是系数,是大于零的,所以距离离得越近,这个值是越接近于1的,而距离越远就接近于0,那么我们定了相似度,就可以根据相似度进行标签传播。我们随便找一个点,找到它一个个标注的相似度的大小,将无标注的数据和有标注的数据建立全连接,然后看哪个相似度更大一些。或者我们也可以看离它最近的标注的相似度是多少,就取那个值。
knn:找一个无标注的数据,然后附近取k个有标注的数据,这k个有标注的数据中哪种标注的多就赋成哪一个。
代码:lris数据集(花萼长度;花萼宽度;花瓣长度;花瓣宽度;种类:lris Setosa(山鸢尾)、lris Versicolour(杂色鸢尾)、IrisVirginica(维吉尼亚鸢尾))

#半监督——标签传播算法
import numpy as np
from sklearn import datasetsiris = datasets.load_iris()
#复制数据集中的target数据
labels = np.copy(iris.target)
#print(len(labels)),一共150条数据#标签传播算法要求未标注数据label为-1
random_unlabeled_points=np.random.rand(len(iris.target))
#设置如果<0.3为1,反之为0
random_unlabeled_points=random_unlabeled_points < 0.3
Y=labels[random_unlabeled_points]
#数组中只有0,1,这一步将1换为-1
labels[random_unlabeled_points] = -1
#打印有多少未标注数据
print("Unlabeled Number:",list(labels).count(-1))from sklearn.semi_supervised import LabelPropagation
label_prop_model = LabelPropagation()
label_prop_model.fit(iris.data,labels)
Y_pred = label_prop_model.predict(iris.data)
Y_pred = Y_pred[random_unlabeled_points]from sklearn.metrics import accuracy_score,recall_score,f1_scoreprint("ACC:",accuracy_score(Y,Y_pred))
print("REC:",recall_score(Y,Y_pred,average="micro"))
print("F-Score:",f1_score(Y,Y_pred,average="micro"))

数据分析4——挖掘建模(监督学习中的分类、回归模型,无监督学习)相关推荐

  1. 【数据分析与挖掘】基于LightGBM,XGBoost,逻辑回归的分类预测实战:英雄联盟数据(有数据集和代码)

    机器学习-LightGBM 一.LightGBM的介绍与应用 1.1 LightGBM的介绍 1.2 LightGBM的应用 二.数据集来源 三.基于英雄联盟数据集的LightGBM分类实战 Step ...

  2. 炼数成金数据分析课程---16、机器学习中的分类算法(交叉内容,后面要重点看)...

    炼数成金数据分析课程---16.机器学习中的分类算法(交叉内容,后面要重点看) 一.总结 一句话总结: 大纲+实例快速学习法 主要讲解常用分类算法(如Knn.决策树.贝叶斯分类器等)的原理及pytho ...

  3. Python3数据分析与挖掘建模实战

    <div>课程地址:http://icourse8.com/Python3_shujufenxi.html</div>复制代码 第1章 课程介绍[赠送相关电子书+随堂代码] 第 ...

  4. 【论文阅读】目标检测中的分类回归特征解耦

    论文来源:知网 以下仅仅是学习过程中的部分笔记,用作自己复习. 摘要 ..... 目标检测不仅需要判别图像中存在的目标的类别,还需要回归目标在图像中的位置. 特征耦合具体表现:分类和回归部分的网络共享 ...

  5. python数据分析与挖掘建模:交叉分析

    前言 交叉分析是属性间的数据分析.本次实验中我们主要分析离职率("left")与各部门("depar")之间的关系,各部门之间的离职率是否有明显的差异,使用到的 ...

  6. R语言书籍学习02 《R语言数据分析、挖掘建模与可视化》-第十三章 SVM模型

    SVM模型(Support Vector Machine, 支持向量机)属于一种有监督的机器学习算法,可用于离散因变量的分类和连续因变量的预测. 它可以将低维线性不可分的空间转换为高维的线性可分空间. ...

  7. Python3数据分析与挖掘建模(4)单因子分析:集中趋势与离中趋势、数据分布与抽样

    分析理论是统计学和数据分析中的重要概念,它们用于描述和理解数据的集中趋势.离中趋势.数据分布以及抽样理论.下面是对这些概念的简要说明: 集中趋势: 均值.中位数与分位数.众数 离中趋势:标准差.方差 ...

  8. Python3数据分析与挖掘建模(8)多因子分析:检验

    1. 假设检验 1.1 概述 假设检验是一种统计推断方法,用于对一个或多个总体参数提出关于其取值的假设,并根据样本数据对这些假设进行检验.假设检验的目的是根据样本数据提供统计上的证据,以便对总体参数的 ...

  9. 数据分析与挖掘建模实战001:导学,概述

    导学 数据分析概述 五步流程 六个集成包

最新文章

  1. linux+while循环多条件,有效的while循环条件客户端选择(TCP连接在Linux - C)
  2. 阿里云容器服务发布 Knative 托管服务 | 云原生生态周报 Vol. 49
  3. Leaflet中使用Leaflet.draw插件实现图形交互绘制和编辑(修改图形坐标点)
  4. 让对方qq崩溃的代码2020_解决 KUbuntu 18.04 下 Deepin Wine QQ 运行十分钟后崩溃的问题...
  5. MPEG4 (ISO/IEC 14496) 文档内容 简介
  6. DIV中class和id的区别
  7. android xml事件,安卓事件
  8. python在线学习直播-一对多直播系统开发,百万用户在线,直播弹幕系统是如何实现的?...
  9. python自动化办公入门书籍-用Python自动办公,做职场高手 | 「讲文兄博客」
  10. SQL Server2005 表分区三步曲(zz)
  11. 全国计算机二级c语言题库,计算机二级c语言题库及答案
  12. 罗永浩承认鸟巢发布会不成功,还说苹果把大家都带歪了,你怎么看?
  13. Windows系统下快速安装、配置Aira2,及图形界面配置、度盘、B站视频下载
  14. DRAM内存物理地址和地址译码器原理的剖析
  15. 手机锁屏后微信收款语音不播报?-by:nixs
  16. 太经典了,不转不行淘宝上面的对话
  17. FreeSSL.cn 申请免费HTTPS 证书
  18. android自动循环播放视频,Android编程实现VideoView循环播放功能的方法
  19. petalinux-build 报错解决
  20. 20170425めも

热门文章

  1. 赛车游戏中赛车的物理建模
  2. 大学计算机基础知识手写笔记,清华学霸手写笔记火了,如同“电脑打印版”,学渣快来“瞻仰”...
  3. Multisim应用举例实验
  4. 尝试搭建OPhone-sdk 手机模拟器的搭建
  5. el-tree实现类似windows文件列表,并支持折叠、展开和重命名
  6. 2019年的最新的最全的ava常见的面试题
  7. excel可以用python语言_用python打开excel的方法
  8. Ubuntu 20下pycharm无法使用中文输入法
  9. 5G/NR 频带详解
  10. 使markdown文档中的图片居中