《数据仓库与数据挖掘》课件 第11-13章 聚类与关联;数据预处理、特征选择与降维;NLP、知识图谱与神经网络_第1页
《数据仓库与数据挖掘》课件 第11-13章 聚类与关联;数据预处理、特征选择与降维;NLP、知识图谱与神经网络_第2页
《数据仓库与数据挖掘》课件 第11-13章 聚类与关联;数据预处理、特征选择与降维;NLP、知识图谱与神经网络_第3页
《数据仓库与数据挖掘》课件 第11-13章 聚类与关联;数据预处理、特征选择与降维;NLP、知识图谱与神经网络_第4页
《数据仓库与数据挖掘》课件 第11-13章 聚类与关联;数据预处理、特征选择与降维;NLP、知识图谱与神经网络_第5页
已阅读5页,还剩115页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第11章

聚类与关联本章主要内容11.1无监督学习11.2聚类算法11.3模型的保存和导入11.4关联算法11.5课后习题11.1

无监督学习有监督学习与无监督学习前面介绍了逻辑回归、决策树、随机森林、SVM和XGBoost等分类算法。聚类算法和分类算法一样,都是把对象集合分成不同的类,但分类算法面向的是有监督学习,而聚类面向的是无监督学习。什么是有监督学习呢?就在训练模型过程中,历史数据中的标签是有结果的,如乳腺癌历史数据中,样本是否是恶性的是明确的,换言之,模型在训练的时候,既需要历史数据中的数据部分X,也需要历史数据中的结论部分y。而无监督学习中,历史数据中没有明确的标签,模型是根据某些指标自行去挖掘样本的规律,完成分类。聚类就是典型的无监督学习,其目的是将数据划分成有意义或有用的组(聚类中的“类”一般被称为“簇”)。例如很多企业会对客户进行分类,但之前没有成型的历史数据,无法使用分类算法进行监督学习,那就只好使用聚类。11.2

聚类算法10.2.1K-MeansK-Means是最常用的聚类算法之一,它的计算依据是节点之间的距离。首先将样本按照各个特征值映射为某个空间的点,例如样本有两个特征值,就可以把样本映射到二维坐标上的点;如果样本有三个特征,就可以把样本映射到三维空间上的点,以此类推。10.2.1K-Means假设要将所有样本聚成K簇,则按照如下步骤进行:步骤一:在所有样本中随机选出K个点,作为簇心(又称为“质心”);步骤二:将其他每个样本点分配到离他们最近簇心点的簇,生成了K个簇;步骤三:在每个簇内,计算所有被分到这个簇样本点的各特征平均值作为新的簇心;步骤四:重复步骤二、步骤三,直到达到某个中止条件(如达到迭代次数,或簇心不再变化,或簇心变化带来的节点与簇心之间的距离变化量小于某个阈值等)。10.2.1K-Means其中x表示簇中的某个样本点的特征向量,i表示特征列号,n表示每个样本点中的特征数目,μ为当前簇心的特征向量。聚类时所有样本点到质心的距离之和越小,我们就认为这个簇中的样本越相似,簇内差异就越小,分簇效果越好。10.2.1K-Means#第一步:导入数据#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_julei.csv',index_col='Patien')10.2.1K-Means#第二步:数据预处理#缺失值处理df.dropna()#数据标准化fromsklearn.preprocessingimportMinMaxScalerscaler=MinMaxScaler()df=scaler.fit_transform(df)#其他数据预处理将在第6次课介绍10.2.1K-Means#导入Kmeans包fromsklearn.clusterimportKMeans#聚3类,随机状态(随机选取初始簇心)为0,迭代300次cluster=KMeans(n_clusters=3,max_iter=300,random_state=0)clu=cluster.fit_predict(df)print(pd.Series(clu))左列是样本编号右列是类别号10.2.1K-Means可以看到,输出结果就是每一个样本聚类之后所属的类别。再次强调,虽然使用的是乳腺癌数据,但与结果恶性与否没有关系,只是单纯的将样本聚类成3簇。上例中聚类为3簇,具体的簇数是如何确定的呢?方法一:业务指定,这是最常见的,例如某家公司要将客户分成3类并发放礼品,这就需要指定簇数是3。方法二:根据指标选择合理的簇数(例如使用学习曲线方法)。但因为训练模型用的历史数据中没有标签列,所以就不会有准确率等指标。那如何判断一个分簇的好坏呢?10.2.1K-Means——聚类的衡量指标:簇内平方和(1)簇内平方和,如下公式所示其中,m为一个簇中样本的个数,j是每个样本的编号。这个公式被称为簇内平方和(clusterSumofSquare),又叫做Inertia。而将一个数据集中的所有簇的簇内平方和相加,就得到了整体平方和(TotalClusterSumofSquare),又叫做totalinertia。TotalInertia越小,代表着每个簇内样本越相似,聚类的效果就越好。可以使用kmeans的inertia_属性查看聚类后的簇内平方和。虽然目标是整体平方和越小越好,但这是指对某一个聚类过程而言的,但对于簇数的选择没有太大帮助。假设有n个节点,如果将它聚成n簇,那整体平方和就是0,从整体平方和指标来看效果最好,但是没有实际意义。10.2.1K-Means——聚类的衡量指标:轮廓系数(2)轮廓系数:轮廓系数是对每个样本来定义的,设样本与其自身所在的簇中的其他样本的相似(相异)度a,等于样本与同一簇中所有其他点之间的平均距离;设样本与其他簇中的样本的相似(相异)度b,等于样本与下一个最近的簇中的所有点之间的平均距离,根据聚类的要求“簇内差异小,簇外差异大”,我们希望b永远大于a,并且大得越多越好。单个样本的轮廓系数如下公式对于一个样本点而言,当它的轮廓系数接近1是说明它与自己所处的簇其他样本很相似,与其他簇样本不相似,这是我们希望的结果;但当一个样本的轮廓系数接近-1时,说明它与自己所处簇的其他样本不相似,与其他簇样本相似,这是聚类很糟糕的效果,即它应该属于其他簇;当轮廓系数为0时,说明它属于哪个簇都可以(从这个样本角度看,自己所处的簇和其他的簇应该是一个簇)将所有样本轮廓系数汇总,就得到了总轮廓系数和平均轮廓系数,我们当然希望这个数越高越好。10.2.1K-Means——聚类的衡量指标:轮廓系数实现#引入轮廓系数计算工具包fromsklearn.metricsimportsilhouette_score#计算整体平均轮廓系数fromsklearn.metricsimportsilhouette_samples#计算每个样本的轮廓系数print("数据集聚类后平均轮廓系数为:")print(silhouette_score(df,clu))print("数据集聚类后每个样本轮廓系数为:")print(silhouette_samples(df,clu))10.2.1K-Means——聚类的衡量指标:卡林斯基-哈拉巴斯指数(3)卡林斯基-哈拉巴斯指数(Calinski_harabaszIndex)轮廓系数的最大缺点是计算起来比较麻烦(因为需要每个样本计算一遍),因此人们又想出了使用矩阵的方式进行计算。卡林斯基-哈拉巴斯指数如下所示。其中N为数据集中的样本量,k为簇的个数,Bk是组间离散矩阵,即不同簇之间的协方差矩阵,Wk是簇内离散矩阵,即一个簇内数据的协方差矩阵,而tr表示矩阵的迹。(一个n×n矩阵A的主对角线上各个元素的总和被称为矩阵A的迹,记为Tr(A))。数据之间的离散程度越高,协方差矩阵的迹就会越大。组内离散程度低,协方差的迹就会越小,Tr(Wk)也就越小,同时,组间离散程度大,协方差的的迹也会越大,Tr(Bk)就越大,这正是我们希望的,因此calinski_harabasz指数越高越好。

10.2.1K-Means——聚类的衡量指标:卡林斯基-哈拉巴斯指数#引入calinski_harabaz指数工具包fromsklearn.metricsimportcalinski_harabasz_score#计算calinski_harabaz指数print("卡林斯基-哈拉巴斯指数为:")print(calinski_harabasz_score(df,clu))10.2.1K-Means——K-Means重要参数n_clusters:簇数max_iter:计算迭代次数random_state:随机找质心的种子10.1.2DBSCAN在弄清楚DBSCAN聚类原理之前,先要搞清楚一些重要概念:(1)核心点:若某个点的密度达到算法设定的阈值(min_samples)则其为核心点。(2)ε邻域的距离阈值:可以理解为一个区域的半径ε(3)直接密度可达:若p点在q点的邻域内,且q是核心点,则称p和q直接密度可达。(4)密度可达:假设有一系列点:a0、a1、…、ak,对任意ai与ai-1是直接密度可达的,则称a0与ak密度可达,这实际上是直接密度可达的“传播”。(5)密度相连:若有某核心点a0,它与点am和点an都是密度可达的,则称点am和点an是密度相连的。(6)边界点:属于某一个类的非核心点,边界点不能发展“下线”了。(7)噪声点:不属于任何一个类簇的点,从任何一个核心点出发都是密度不可达的。10.1.2DBSCAN有了以上概念,DBSCAN的聚类思想就很清楚:由密度可达关系导出的最大密度相连的样本集合,就是聚成的一个簇。假设一个数据集有两个特征列,将它们映射到一个二维空间,如下图所示。如果说K-means是在找到簇心之后,其他样本点向簇心靠拢的话,那么DBSCAN则是样本主动去找同伴10.1.2DBSCAN从A点开始,以A点为圆心画一个圆,规定这个圆的半径(ε)以及圆内最少包含的样本点数(min_samples),如果在圆内有足够多的样本点,那么A点就是一个核心点,以A为圆心画的圆内其他样本点就是A点的直接密度可达点。从A点的直接密度可达点为圆心,重复上面步骤,继续寻找直接密度可达点(也就是与A密度可达的点),直到再没有办法找到新的A点密度可达点(如左图中,B和C就没有办法再找到直接密度可达点,也就没有办法再找A密度可达点,但B和C与A是密度相连的),这时将A点、A所有直接密度可达点、A密度可达点及所有密度相连的点共同组成了一个簇,但N点就不属于这个簇。10.1.2DBSCAN比起K-means,DBSCAN有以下特点:(1)DBSCAN可以处理非凸数据集聚类问题,所谓凸数据集如下图所示(以二维为例),这种图形K-means处理起来比较困难,聚类的结果不是太合理。(2)DBSCAN不需要指定簇数,整个模型只能指定ε和min_samples(只有这两个参数),聚出多少簇则是模型自行计算。10.1.2DBSCAN#第一步:导入数据#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_julei.csv',index_col='Patien')10.1.2DBSCAN#第二步:数据预处理#缺失值处理df.dropna()#数据标准化fromsklearn.preprocessingimportMinMaxScalerscaler=MinMaxScaler()df=scaler.fit_transform(df)#其他数据预处理将在第6次课介绍10.1.2DBSCAN#引入DBSCAN工具包fromsklearn.clusterimportDBSCAN#指定DBSCAN的ε为0.2、min_samples为3cluster=DBSCAN(eps=0.2,min_samples=3)clu=cluster.fit_predict(df)print(pd.Series(clu)+1)左列是样本编号右列是类别号10.1.2DBSCANfromsklearn.metricsimportsilhouette_scorefromsklearn.metricsimportcalinski_harabasz_scoreprint("数据集聚类后平均轮廓系数为:")print(silhouette_score(df,clu))print("卡林斯基-哈拉巴斯指数为:")print(calinski_harabasz_score(df,clu))11.3

模型的保存和导入保存与调用模型:方法一#导入pickle包importpickle#使用pickle中的dump方法将cluster模型保存为cluster1.dat文件,后面的wb表示以二进制写入pickle.dump(cluster,open(r"E:\cluster1.dat","wb"))#保存成功后,可以在其他地方调用,后面的rb表示以二进制读出my_model=pickle.load(open(r"E:\cluster1.dat","rb"))#导出后的模型使用方法与普通模型一模一样result=my_model.fit_predict(df)print(result)保存与调用模型:方法二#导入joblib包importjoblib#使用joblib中的dump方法将cluster模型保存为cluster1.dat文件,后面的wb表示以二进制写入joblib.dump(cluster,open(r"E:\cluster2.dat","wb"))#保存成功后,可以在其他地方调用,后面的rb表示以二进制读出my_model=joblib.load(open(r"E:\cluster2.dat","rb"))#导出后的模型使用方法与普通模型一模一样result=my_model.fit_predict(df)print(result)11.4

关联算法11.4.1Apriori算法在日常生活中,经常会遇到关联问题,寻找关联规则。所谓关联规则是反映一个事物与其他事物之间的相互依存性和关联性。如果两个或者多个事物之间存在一定的关联关系,那么,其中一个事物就能够通过其他事物预测到。例如沃尔玛超市经典案例:沃尔玛通过对超市一年多的原始交易数据进行详细分析,发现了尿布与啤酒这一神奇组合——跟尿布一起购买最多的商品竟是啤酒。这是因为美国太太们常叮嘱丈夫下班后为小孩买尿布,而丈夫们在买尿布后又随手带回了他们喜欢的啤酒,于是尿布就和啤酒关联在了一起,也就找到了由尿布和啤酒组成的关联规则。计算机是如何发现不同事物之间的关联规则呢?可以使用Apriori算法。要想研究Apriori算法,首先要清楚几个概念:(1)支持度(Support):关联规则X=>Y对事物集T的支持度定义为T中同时包含有事务X和Y的百分比,即support(X=>Y)=P(X∪Y)(2)置信度(Confidence):关联规则X=>Y对事物集T的置信度定义为T中包含有X的事务数中包含Y的百分比,即:confidence(X=>Y)=P(Y|X)11.4.1Apriori算法——实现Apriori算法的实现,需要使用另一个工具库:mlxtend。Anaconda中没有这个库,需要在AnacondaPrompt中pipinstallmlxtend进行安装11.4.1Apriori算法——实现Apriori算法的实现,需要两个环节首先计算频繁项集其次寻找强关联规则#从mlxtend中导入apriori,association_rulesfrommlxtend.frequent_patternsimportapriori,association_rules

#计算频繁项集frequent_item_sets=apriori(data,min_support=0.5,use_colnames=True)print(frequent_item_sets)1#寻找强关联规则2rules=association_rules(frequent_item_sets,metric='confidence',min_threshold=0.7)3print(rules)11.4.2协同过滤算法除了找到事物之间的联系外,关联算法的另一个应用场景是“推荐系统”。例如一些购物APP会根据客户已买的商品推荐“可能喜欢”的商品,或者某些视频APP会根据用户观看视频的历史记录,推荐“可能喜欢”的视频。这些推荐系统又是依据什么原理进行推荐呢?除了前文提到的Apriori算法,比较常用的是协同过滤算法。目前sklearn或mlxtend中并没有协同过滤等算法的工具包。除了自己编写程序外,还可以在GitHub平台寻找合适的代码。GitHub

是全球最大的开源社区之一,它聚集了全球众多的开发者、组织和项目。开发者可以在

GitHub

上搜索、发现和加入自己感兴趣的开源项目代码,也可以贡献自己的代码和技能。目前,GitHub

已经成为是程序员学习和教育的重要平台之一,开发者可以通过阅读这些代码学习新技术和开发方法。同时,GitHub

上也有许多教育资源和课程,如编程实验、教学材料等,使得学习编程更加容易和有趣,可自行研究GitHub。11.5

课后习题11.5课后习题1.请解释有监督学习与无监督学习的区别。2.针对乳腺癌数据集,使用K-means算法根据生理指标对患者进行聚类,并以卡林斯基-哈拉巴斯指数为依据进行调参。3.在GitHub上下载一个协同过滤算法代码,尝试在本地运行。第12章

数据预处理、特征选择与降维本章主要内容12.1数据预处理12.2特征选择12.3降维12.4课后习题12.1数据预处理12.1数据预处理数据无量纲化缺失值处理编码分段特征选择降维12.1.1数据无量纲化什么是数据的无量纲化,例如在医学数据挖掘时“亚油酸”指标的数值都是数千,而“肉豆蔻脑酸”多为百以下甚至十以下的数据。二者在量纲上不同,因此在使用某些模型建模(例如逻辑回归、SVM、Kmeans等涉及数据运算的模型),这两个特征在模型中发挥作用就会“不公平”,但二者的医学意义并不是像它们的量纲一样有很大差别,甚至有些时候“肉豆蔻脑酸”的医学意义更重要。这就需要我们在建模之前相对数据进行无量纲化,将数据都压缩到某一个范围之内,这样建模时各个特征之间才会公平的发挥作用。12.1.1数据无量纲化——归一化归一化是指用一列数据中的每一个数减去这列数据中最小的数,然后除以这列数据中最大数与最小数之差的方法,这样就可以将数据压缩到0-1之间。具体公式如下所示:其中x是某个属性的向量,x-min(x)是x中每个元素减去x特征中的最小值,max(x)-min(x)是x中的最大值减去最小值,x*是计算后新的属性向量。12.1.1数据无量纲化——归一化实现#第一步:导入数据#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_lishi.csv',index_col='Patien')#X为原始数据中不包括target列部分,是由历史数据中“非结果列”组成的数据X=df.loc[:,(df.columns!='target')]#Y为原始数据中target列部分,是由历史数据中“结果列”组成的数据Y=df.loc[:,df.columns=='target']12.1.1数据无量纲化——归一化实现#导入归一化包fromsklearn.preprocessingimportMinMaxScaler#使用归一化方法对X各列数据进行统一量纲scaler=MinMaxScaler()X_sca=scaler.fit_transform(X)print(X_sca)12.1.1数据无量纲化——数据归一化之后模型的表现fromsklearn.model_selectionimportcross_val_scorefromsklearn.linear_modelimportLogisticRegressionasLR#通过默认的逻辑回归模型,比较使用原始数据训练模型的交叉验证结果和使用归一化后数据训练模型交叉验证结果型lr=LR()score_test_ori=cross_val_score(lr,X,Y,cv=10).mean()score_test_sca=cross_val_score(lr,X_sca,Y,cv=10).mean()print("使用原始数据训练模型的结果:{0}".format(score_test_ori))print("使用归一化后数据训练模型的结果:{0}".format(score_test_sca))12.1.1数据无量纲化——标准化除了使用归一化方法统一量纲之外,还可以使用标准化法,公式如下所示:其中x是某个属性列所有值的向量,μ是属性列的平均值,σ是一个属性列的标准差,因此整个公式的意思是x属性列中每个数值分别减去列平均值,除以标准差,得到新的属性向量。12.1.1数据无量纲化——标准化实现#第一步:导入数据#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_lishi.csv',index_col='Patien')#X为原始数据中不包括target列部分,是由历史数据中“非结果列”组成的数据X=df.loc[:,(df.columns!='target')]#Y为原始数据中target列部分,是由历史数据中“结果列”组成的数据Y=df.loc[:,df.columns=='target']12.1.1数据无量纲化——标准化实现#第二步,数据标准化#导入标准化包fromsklearn.preprocessingimportStandardScaler#使用标准化方法对X各列数据进行统一量纲scaler=StandardScaler()X_std=scaler.fit_transform(X)print(X_std)12.1.1数据无量纲化——标准化实现fromsklearn.model_selectionimportcross_val_scorefromsklearn.linear_modelimportLogisticRegressionasLR#通过默认的逻辑回归模型,比较使用原始数据训练模型的交叉验证结果和使用标准化后数据训练模型交叉验证结果型lr=LR()score_test_ori=cross_val_score(lr,X,Y,cv=10).mean()score_test_std=cross_val_score(lr,X_std,Y,cv=10).mean()print("使用原始数据训练模型的结果:{0}".format(score_test_ori))print("使用标准化后数据训练模型的结果:{0}".format(score_test_std))12.1.1数据无量纲化——归一化VS标准化无量纲化时,标准化和归一化哪个方法更好呢。归一化方法容易受到异常值(例如不正常的最大值和最小值)影响,所以建议先使用标准化试试。树形模型(决策树、随机森林、XGBoost等)对数据量纲要求不大。sklearn中还提供了很多无量纲化方法,例如当出现明显异常值时可以使用robustscaler方法,感兴趣的同学可以自行研究。12.1.2缺失值处理第一步:导入数据#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_queshi.csv',index_col='Patien')#X为原始数据中不包括target列部分,是由历史数据中“非结果列”组成的数据X=df.loc[:,(df.columns!='target')]#Y为原始数据中target列部分,是由历史数据中“结果列”组成的数据Y=df.loc[:,df.columns=='target']print(np.isnan(X).sum())#检查各列是否有缺失值12.1.2缺失值处理#逻辑回归无法处理带有缺失值的数据fromsklearn.linear_modelimportLogisticRegressionasLRlr=LR()lr.fit(X,Y)12.1.2缺失值处理除XGBoost等个别模型外,大多数模型训练和预测时,数据集中都不能有缺失值。所以缺失值必须要处理。处理缺失值常用的几个方法包括:

方法一:删除缺失值。当有缺失值的样本数占总样本数的10%以下时,就可以删除带有缺失值的样本,删除方法如下:#针对有缺失值的数据表格(DataFrame类型)df

df.dropna()12.1.2缺失值处理方法二:使用统计量填充当缺失值不能删除时,可以使用统计量进行填充,例如某一列的缺失值可以使用这一列的平均数或众数或中位数等进行填充。#针对有缺失值的数据表格(DataFrame类型)df#用0填充df中缺失值print(df.fillna(0))#用非空值的均值填充df中缺失值print(df.fillna(df.mean()))12.1.2缺失值处理

方法三:使用模型对缺失值进行预测填充可以将包含缺失值的特征列当做目标列,其他特征列当成特征矩阵,其中包含缺失值的记录是待遇测样本,不包含缺失值的记录是训练样本集,然后通过训练样本训练模型,这样就通过模型预测待遇测样本记录中的缺失值。比较经典的是miceforest方法。例如用处理如右表所示的缺失值。12.1.2缺失值处理——使用miceforest预测缺失值第一步:找到缺失值最少的列,右表为A列第二步:随机使用B列中的数据,填充B列中的缺失值,可以重复填充同一个随机数;随机使用C列中的数据,填充C列中的缺失值,可以重复填充同一个随机数;第三步:将B列和C列作为“数据部分”,A列作为“结论部分”,建立随机森林模型,其中A类中没有缺失值的记录作为训练集,A列中的缺失值作为预测的目标,并使用预测结果进行填充,至此A列缺失值填充完毕;第四步:恢复B列和C列,也就是将第二步随机填入的数据删除,然后找到二者中缺失值最少的列,右表B列;12.1.2缺失值处理——使用miceforest预测缺失值

第五步:A列数据缺失值填充完毕;随机使用C列中的数据,填充C列中的缺失值,可以重复填充同一个随机数;第六步:将A列和C列作为“数据部分”,B列作为“结论部分”,建立随机森林模型,其中B列中没有缺失值的记录作为训练集,B列中的缺失值作为预测的目标,并使用预测结果进行填充,至此B列缺失值填充完毕。第七步:恢复C列数据,也就是将第五步随机填入的数据删除,此时A列和B列都已经填充完毕,只有C列有缺失值。12.1.2缺失值处理——使用miceforest预测缺失值第八步:将A列和B列作为“数据部分”,C列作为“结论部分”,建立随机森林模型,其中C列中没有缺失值的记录作为训练集,C列中的缺失值作为预测的目标,并使用预测结果进行填充,至此整个数据填充完毕。第九步:重新恢复A列数据,即将已经补全的A列缺失值删除,以B和C列为“数据部分”,A列为“结论部分”,其中A列中没有缺失值的记录作为训练集,A列中的缺失值作为预测的目标,并使用预测结果进行填充,B和C列处理方式以此类推,开启新一轮轮迭代,一般建议迭代3-5次。12.1.2缺失值处理——使用miceforest预测缺失值

Miceforest的中文名称叫多重链式随机森林填补缺失值,“链式”很好理解,正如上面步骤所示,填充是一个链式操作,即使用上一步的填充结果来填充下一步。那“多重”又是什么意思呢?所谓“多重”就是可以生成多个补全后的数据集。经过上面九个步骤,完成了一次数据集补全,这被称为一重补全。多个一重补全可以并行进行,例如上面步骤中的第一步,可以同时生成4组随机填充的B列和C列,然后并行执行后续步骤,这样就会出现4个补全的数据集,可以经过分析选择最好的数据集作为补全结果,或者进行加权生成一个更合理的数据集。12.1.2缺失值处理——miceforest的实现#第一步,导入乳腺癌原始数据,并人为创造缺失值(这里创造缺失值,只是为了演示miceforest,没有任何业务意义)#导入numpy和pandas数据包importnumpyasnpimportpandasaspd#引入miceforest包importmiceforestasmf#从boston_lishi.csv文件中导入原始数据df=pd.read_csv(r'E:\ruxian_lishi.csv',index_col='Patien')#X为原始数据中不包括target列部分,是由历史数据中“非结果列”组成的数据X=df.loc[:,(df.columns!='target')]#Y为原始数据中target列部分,是由历史数据中“结果列”组成的数据Y=df.loc[:,df.columns=='target']#在原乳腺癌数据中随机生成20%比例的缺失值X_missing=mf.ampute_data(X,perc=0.2,random_state=10)print(X_missing.head(10))12.1.2缺失值处理——miceforest单次插补的实现

#进行单次插补kds=mf.KernelDataSet(X_missing,#指定需要补充缺失值的数据集save_all_iterations=True,#指定中间迭代过程所生成的数据是否被保留#random_state=10#指定随机状态)kds.mice(iterations=3)#指定迭代次数X_complete=plete_data()#开始补充缺失值,并返回填充后的特征矩阵print(X_complete.head(10))12.1.2缺失值处理——miceforest多重插补的实现#进行多重插补mik=mf.MultipleImputedKernel(X_missing,#指定需要补充缺失值的数据集datasets=4,#指定生成4个完整数据集save_models=1,#只保留一个生成的模型(也就是只保留最后一个随机森林模型)save_all_iterations=True,#指定中间迭代过程所生成的模型是否被保留random_state=10,#指定随机状态)mik.mice(iterations=3)#指定迭代次数X0_complete=plete_data(0)#一共补全了4个数据集,这里指定返回第0个数据集print(X0_complete.head(10))#还可以通过print(plete_data(2).head(10))查看2号补全数据集在之前的示例中,一直使用数值型数据建立模型并预测,例如乳腺癌预测数据,所有数据都是数值型,即使结论部分也是用0和1表示是否为恶性肿瘤。换一组数据,以互联网上著名的泰坦尼克号船难幸存数据为例,原始数据中很多列的值都是字符串型。例如结论部分survived列,直接用yes和no表示是否幸存。12.1.3编码数据中有“字符串”12.1.3编码#读入数据importpandasaspdimportnumpyasnpdata_train=pd.read_csv(r"E:\titanic_training.csv")data_train.head(10)#读取前10行数据#建立决策树模型,并使用交叉验证衡量模型表现fromsklearn.treeimportDecisionTreeClassifierfromsklearn.model_selectionimportcross_val_scoreclf=DecisionTreeClassifier(random_state=25)score=cross_val_score(clf,data_train.loc[:,data_train.columns!='survived'],data_train.loc[:,data_train.columns=='survived'],cv=10).mean()print(score)12.1.3编码上页代码返回结果:

ValueError:couldnotconvertstringtofloat:'First'很明显,无法将字符串转成数值型,决策树模型无法建立。其实不仅是决策树模型,几乎所有的模型都无法处理字符串数据。sklearn中提供了很多方法用于将字符串类型数据转成数字型数据。12.1.3编码——编码方法一:labelEncoder#该方法主要目标是将标签中的字符型数据转成数字型数据。实现方法如#导入LabelEncoder工具包fromsklearn.preprocessingimportLabelEncoder#LabelEncoder的使用方法与普通模型使用方法一致le=LabelEncoder()y=le.fit_transform(data_train.loc[:,data_train.columns=='survived'])print(y)12.1.3编码——编码方法一:labelEncoder由结果可见,已将标签列所有的字符串都转成了数字型(Yes为1,No为0)。前页代码运行结果如下:12.1.3编码——编码方法二:OrdinalEncoder

我们已经将标签列转成了数字型,那其他特征列的字符型数据怎么办呢?可以使用OrdinalEncoder,使用方法如下所示:fromsklearn.preprocessingimportOrdinalEncoderoe=OrdinalEncoder()#下面的fit_transform方法相当于fit和transform方法放在一块进行操作data_train.loc[:,data_train.columns=='passenger_class']=oe.fit_transform(data_train.loc[:,data_train.columns=='passenger_class'])data_train.loc[:,data_train.columns=='sex']=oe.fit_transform(data_train.loc[:,data_train.columns=='sex'])x=data_train.loc[:,data_train.columns!='survived']print(x.head(10))12.1.3编码——编码方法二:OrdinalEncoder

从结果可见,passenger_class、sex两列已经变成了数字型,每一个种类对应一个数字,之后就可以进行建模运算12.1.3编码——编码方法三:OnehotencoderOrdinalEncoder编码虽然解决了字符型数据不能建模的问题,但在一些情况下却不完美。例如通过OrdinalEncoder编码,sex列中的Female被编成了0.0,Male被编成了1.0。但0.0和1.0本身就有数值性,1.0比0.0大,可是没有道理说Male比Female大。于是人们想出了一种Onehotencoder(独热编码)的方法。为了直观,我们假设有如下表格,记录第一天、第二天、第三天餐普12.1.3编码——编码方法三:Onehotencoder

现对第一天、第二天、第三天的早餐、午餐和晚餐进行独热编码,实现方式如下:#引入OneHotEncoder工具包fromsklearn.preprocessingimportOneHotEncoder#将数据指定为一个DataFramedf=pd.DataFrame({"早餐":pd.Series(['馒头','花卷','馄饨'],index=[1,2,3]),"午餐":pd.Series(['红烧肉','清蒸鱼','红烧茄子'],index=[1,2,3]),"晚餐":pd.Series(['包子','饺子','糖包'],index=[1,2,3])})#使用OneHotEncoder对数据进行编码ohe=OneHotEncoder()a=ohe.fit_transform(df)print(a)12.1.3编码——编码方法三:Onehotencoder前页代码输出结果:这是什么?真成编码了,完全看不懂,我们将结果变成列表再看看,使用语句print(a.toarray()),输出结果为:12.1.4分段所谓分段就是将连续型变量划分为分类变量(也是数值型),相当于将连续型变量排序后按顺序分箱再编码,例如某列一共30个数据,按照从小到大排序,分3类,前10个数据都编码为0,中间10个编码为1,最后10个编码为2。分段代码如下:#引入分段的工具包fromsklearn.preprocessingimportKBinsDiscretizer#分段的使用方法与普通模型一样#strategy='uniform'表示使用等宽分段,quantitle表示等频分段,kmeans表示聚类分段kbd=KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='uniform')x=kbd.fit_transform(data_train.loc[:,data_train.columns!='survived'])print(x)12.1.4分段前页代码输出结果为每一列都是三个数值,表示原始数据分到了“第几段”Sklearn中KBinsDiscretizer方法的主要参数:(1)n_bins,内容是整数,意思是将源数据分成几段;(2)encode,内容是字符串,意思是如何进行编码,还可以是“onehot”;(3)Strategy,内容是字符串,意思是符合分段,本例中的uniform表示等宽分箱,即每个特征中的每个箱的最大值之间的差为(特征最大值-特征最小值)/(n_bins);还可以是"quantile",表示等位分箱,即每个特征中的每个箱内的样本数量都相同。还可以是”kmeans”,表示使用kmean对样本聚类后进行分箱12.2特征选择12.2特征选择什么是特征选择?进入到大数据时代,数据的特征以指数级增长,换句话说,数据的列会很多很多,多到让模型的运算性能明显下家,甚至还会有过拟合。所以可以先对特征列进行筛选,留下有用的特征列。如何决定特征的去留呢?首先要请业务专家从业务角度来看,哪些特征列对待解决问题有帮助;其次请统计学家通过统计学(如P检验、T检验)等方法删除一些逻辑不合理的数据。然后才进入到数据挖掘阶段。特征选择常用方法包括:(1)过滤法(2)嵌入法(3)包装法导入乳腺癌原始数据df=pd.read_csv(r'E:\ruxian_lishi.csv',index_col='Patien')X=df.loc[:,df.columns!='target']Y=df.loc[:,df.columns=='target']12.2.1过滤法——方差过滤过滤法又称“飞刀法”,通过计算各个列数据的指标(方差、卡方值、互信息量等),根据指标对列进行筛选。方法一:方差过滤。在介绍R2(详见第三次课),方差其实是数据所携带信息量的一种表现,如果一个特征列的方差过小,就说明这列没有携带足够的特征,可以删除,至少0方差的特征必须删除。#针对乳腺癌数据进行方差过滤,导入乳腺癌原始数据df=pd.read_csv(r'E:\ruxian_lishi.csv',index_col='Patien')X=df.loc[:,df.columns!='target']Y=df.loc[:,df.columns=='target']print(X.shape)输出结果为:(569,30)即原始数据包括30列12.2.1过滤法——方差过滤#使用方差过滤法,去掉方差较小的15列#引入方差过滤的工具包fromsklearn.feature_selectionimportVarianceThreshold#找到所有列方差的中位数,将这个中位数设为阈值,删除所有方差小于阈值的列#方差过滤包的使用方法与普通模型一一致selector=VarianceThreshold(np.median(X.var().values))X_var=selector.fit_transform(X)print(X_var.shape)输出结果为:(569,15)可见通过方差过滤,数据只剩15列12.2.1过滤法——卡方过滤方法二:卡方过滤卡方检验是统计学中判断假设成立与否的方法。如下表所示数据,判断性别是否与喜欢小说有关系,提出假设:二者独立。

第一步:计算自由度假设c为横轴的种类数(本例中,横轴包括男人和女人,所以c为2);r为纵轴的种类数(本例中,纵轴包括喜欢小说和不喜欢小说两类,所以r为2),则自由度=(c-1)*(r-1)=112.2.1过滤法——卡方过滤

第二步:计算ai和bj事件期望频度。计算公式如下所示。n表示总样本数1500。设“男人”是a1,“女人”是a2,“喜欢小说”是b1,“不喜欢小说”是b2。则e11=(300*450)/1500=90。e12=(300*1050)/1500e21=(1200*450)/1500e22=(1200*1050)/1500将期望频度汇总至如下表

男(人)女(人)喜欢小说90360不喜欢小说21084012.2.1过滤法——卡方过滤

第三步:计算卡方值,如公式所示:其中oij是联合事件ai和bj的观测频度(真实一起出现的频度,如左上原始表格所示),而eij是ai和bj的期望频度(第二步算出来的值,如左下表所示)。将表左上表数据和左下表数据代入计算开发值公式:即性别与是否喜欢读书之间的卡方值是507.94.

男(人)女(人)喜欢小说90360不喜欢小说21084012.2.1过滤法——卡方过滤0.990.980.990.900.050.020.010.00110.0000.0010.0040.0160.0455.146.6410.8320.0200.0400.1030.2111.367.829.2113.8230.1150.1850.3520.5842.3669.4911.3416.2740.5540.4290.7111.0643.35711.0713.2818.4750.8740.7521.1451.6104.35112.6915.0920.52第四步:验证结论第一步算出自由度是1;第二、三步算出卡方值是507.94。然后查阅卡方分布临界值表(如右表所示),表中最左列表示自由度,其他列是某一个置信水平对应的卡方值。本例中,自由度是1,所以重点关注第1行,卡方值是507.94,说明连0.001的置信水平都达不到。即原假设“二者独立”不成立,所以二者具有相关性(且根据卡方值判断,二者具有强相关性)。卡方分布临界值表12.2.1过滤法——卡方过滤#导入卡方检验工具包fromsklearn.feature_selectionimportSelectKBestfromsklearn.feature_selectionimportchi2#查看留下哪些列a=SelectKBest(chi2,k=15).fit(X,Y).get_support(indices=True)print(a)#使用卡方检验选出与标签列关联性最强的15个特征列X_chi=SelectKBest(chi2,k=15).fit_transform(X,Y)print(X_chi.shape)输出结果为:(569,15)可见通过卡方过滤,数据只剩15列注意:卡方检验主要是卡方过滤是专门针对离散型标签(即分类结论)的相关性过滤12.2.1过滤法——互信息法目前比较流行的过滤法是互信息法,所谓互信息量(MutualInformation)是信息论里一种有用的信息度量,它可以看成是一个变量中包含的关于另一个变量的信息量,或者说是一个变量由于已知另一个变量而减少的不确定性。互信息的公式如下所示:I(X,Y)为随机变量X与Y之间的互信息。以上公式能够很好地度量各种相关性,但计算复杂。后对互信息量的公式推演为:I(X,Y)=H(X)+H(Y)-H(X,Y),其中H(X)表示X的熵。12.2.1过滤法——互信息法

求X和Y互信息值:X=[10110]Y=[11100]第一步:求H(X)

根据样本的实际情况,

p(x=0)=2/5;p(x=1)=3/5;

第二步:求H(Y)

根据样本的实际情况,

p(x=1)=3/5;p(x=1)=2/5;

第三步:求H(X,Y)根据样本的实际情况。p(x=0;y=0)=1/5p(x=0;y=1)=1/5p(x=1;y=0)=1/5p(x=1;y=1)=2/5综上,I(X,Y)=H(X)+H(Y)-H(X,Y)=0.971+0.971-1.9219=0.02过滤法——互信息法

互信息值一般在[0,1]之间取值,为0则表示两个变量独立,为1则表示两个变量完全相关。上例中X和Y互信息值为0.2,但很弱。所以上例中X和Y有相关性,但很弱。互信息法实现:#导入互信息量工具包fromsklearn.feature_selectionimportSelectKBestfromsklearn.feature_selectionimportmutual_info_classifasMIC#互信息法不但可以探索特征与类别标签之间的相关性,还可以判断特征与连续数值型标签的关系,也就是可以用来判断回归中的相关性,调用feature_selection.mutual_info_regression工具包#使用互信息量过滤选出与标签列关联性最强的15个特征列X_mic=SelectKBest(MIC,k=15).fit_transform(X,Y)print(X_mic.shape)输出结果为:(569,15)可见通过互信息过滤,数据只剩15列12.2.2嵌入法特征选择的第二大类方法是嵌入法,它是与机器学习模型相互配合实现特征筛选的。例如在决策树和随机森林模型中介绍了feature_importances_属性,它返回了每个特征在构建树或森林时的重要性,这本身就是对特征的一种筛选,我们可以保留重要的特征,去掉不重要的特征。还有逻辑回归时介绍过coef_属性,返回所有特征参数,可以根据特征参数的大小筛选特征,例如在lasso回归中,有些特征的特征参数已经是0或接近0,这些特征就可以剔除。12.2.2嵌入法#导入嵌入式工具包fromsklearn.feature_selectionimportSelectFromModelfromsklearn.ensembleimportRandomForestClassifierasRFC#嵌入法与随机森林配合,保留feature_importances_大于0.005的特征列clf=RFC(n_estimators=10,random_state=0)#查看保留了哪些列a=SelectFromModel(clf,threshold=0.005).fit(X,Y).get_support(indices=True)print(a)#筛选特征列X_embedded=SelectFromModel(clf,threshold=0.005).fit_transform(X,Y)print(X_embedded.shape)输出结果为:(569,22)通过嵌入法,保留了随机森林建模时feature_importances_大于0.005的特征列12.2.3包装法包装法也是一个特征选择和算法训练同时进行的方法,这一点与嵌入法十分相似,它也是依赖于算法自身的选择,比如coef_属性或feature_importances_属性来完成特征选择。包装法在初始特征集上训练评估器,并且通过coef_属性或通过feature_importances_属性获得每个特征的重要性;然后从当前的一组特征中删除最不重要的特征。在删除的集合上递归地重复该过程,直到最终到达所需数量的要选择的特征。区别于过滤法和嵌入法的一次训练解决所有问题,包装法要使用特征子集进行多次训练,因此它所需要的计算成本是最高的。12.2.3包装法包装法实现方法:#导入包装法的工具包(RFE是包装法工具包的常用缩写方式)fromsklearn.feature_selectionimportRFE#使用迭代50次的包装法+随机森林,选出15个特征RFC_=RFC(n_estimators=10,random_state=0)#查看保留了哪些列a=RFE(RFC_,n_features_to_select=15,step=50).fit(X,Y).get_support(indices=True)print(a)#筛选特征列X_wrapper=RFE(RFC_,n_features_to_select=15,step=50).fit_transform(X,Y)print(X_wrapper.shape)输出结果为:(569,15)通过包装法,选出最适合随机森林建模15列12.3降维12.3.1降维与特征选择的区别降维和特征选择在功能上是相同的,都是减少数据维度,也就是减少特征列数,从而提升模型计算性能。但降维与特征选择的不同之处在于,特征选择是从原有数据中心原封不同的保留一部分特征列,但降维是通过一些列计算后,将原有数据携带的信息量最大限度的保留在留下的列中,这个过程留下的列较原有数据已经是面目全非。特征选择的优势在于可解释性较强,例如通过特征选择将乳腺癌中的30列数据筛选保留15列,这15列还是原始数据中的15列,在业务层面可以清楚的知道这些列的含义,从而提供业务的分析和判断的可解释性,它的缺点是筛选删除的15列所携带的信息量就彻底丢失了。通过降维方式,也可以将乳腺癌中的30列数据保留15列,但这个过程是通过一系列计算,将原有30列数据所携带的信息量最大限度的保留到留下的15列中,这15列已经不是原数据中的任何一列,而是吸收了其他列信息量之后的新列,这样做的好处是最大限度的保留了原数据中携带的信息,但降维后的数据已经完全不具备可解释性,留下的15列已经不知道具体代表什么业务含义。12.3.2PCA工作原理PCA(主成分分析法)是最长使用的降维方法之一,例如使用PCA对下表1中的数据进行降维。表1上表中的数据包括两个特征X1和X2,使用方差作为二者的信息量,可以计算得到X1列的方差是1,X2列的方差也是1,所以这两列携带的方差之和是2。现对上表进行转换,得到下表2。表212.3.2PCA工作原理表2表中X1_new的方差是2,X2_new的方差是0,且X2_new中的数据均为0,已经没有必要再保留,因此得到下表3.表3这个中拥有表3的所有信息量(方差之和相同),又将维度从2降到了1,达到了降维且最大保留原数据信息量的效果,而X1_new这个新的特征向量就被称为“主成分”,这就是PCA降维的作用。12.3.2PCA工作原理PCA使用方差作为信息量的衡量指标,并使用特征值分解来找出空间V(可以理解为进行了一次高维的坐标轴转换)。降维时,它会通过一系列计算将原特征矩阵X分解为三个矩阵。即:

其中Q和Q-1是辅助的矩阵,Σ是一个对角矩阵(即除了对角线上有值,其他位置都是0的矩阵),其对角线上的元素就是方差。空间V怎么求呢?与PCA主成分分解平行的还有一种SVD奇异值分解方法,它也是通过一系列复杂结算将原特征矩阵分为三个矩阵,

这次的Σ也是一个对角阵,但它对角线上的值是奇异值。注意,SVD分解之后的右侧出现了VT,这个V就是我们在PCA要找的特征空间。而且更为神奇的是SVD转换中有一种捷径,可以不做完奇异值分解就得到VT。所以PCA在求空间V时使用的就是这种简化的SVD转换,从而快速的得到了V。12.3.3PCA实现#PCA的实现#引入PCA工具包fromsklearn.decompositionimportPCA#使用PCA将原数据降维至15列pca=PCA(n_components=15)#降维为15列X_pca=pca.fit_transform(X)#拟合模型print(X_pca.shape)输出结果为:(569,15)通过PCA,将原30列数据转化为15列12.3.3PCA实现#查看降维后的数据print(X_pca)降维后的数据“面目全非”已经不具备可解释性#也可使用inverse_transform将降维之后的数据“在一定程度上”逆向转换pca.inverse_transform(X_pca)12.4课后习题12.4课后习题1.针对乳腺癌数据集,对比使用标准化前后,随机决策森林模型的表现2.针对乳腺癌数据集,使用互信息法,将数据集裁减至20列3.浅谈特征选择和降维的异同。第13章NLP、知识图谱与神经网络本章主要内容13.1自然语言处理13.2知识图谱13.3神经网络13.4课后习题13.1自然语言处理13.1.1什么是自然语言处理自然语言处理(NaturalLanguageProcessing,NLP)是一种人工智能技术,旨在使计算机能够理解、分析和生成人类语言。NLP涵盖了语音识别、语言理解、语言生成和机器翻译等多个领域,其目标是使计算机能够像人类一样处理和理解自然语言。13.1.2自然语言处理的作用自然语言处理(NLP)的作用非常广泛,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论