文章目录
- 致谢
- 3 特征工程
- 3.1 Sklearn工具及数据集
- 3.2 数据集
- 3.3 数据集的划分
- 3.4 特征工程介绍
- 3.4.1 为什么需要特征工程
- 3.4.2 什么是特征工程
- 3.4.3 特征提取
- 3.4.3.1 字典特征提取
- 3.4.3.2 文本特征提取
- 3.4.3.3 中文文本特征提取
- 3.4.3.4 TF-IDF算法
- 3.5 特征预处理
- 3.5.1 特征预处理主要内容
- 3.5.2 大局看待
- 3.5.3 归一化
- 3.5.4 标准化
- 3.6 降维
- 3.6.1 特征选择
- 3.6.2 过滤式
- 3.6.2.1 低方差特征过滤
- 3.6.2.2 相关系数法
- 3.6.3 主成分分析
致谢
本文参照了下列文章的些许知识:
TF-IDF算法介绍及实现_Asia-Lee-CSDN博客_tf-idf
Python入门:jieba库的使用_点滴记录-CSDN博客_jieba
Python jieba库的基本使用_Test_Box-CSDN博客_python的jieba库怎么使用
数据归一化(标准化)的两种方法简介_哔哩哔哩_bilibili
归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered) - 简书 (jianshu.com)
标准化和归一化,请勿混为一谈,透彻理解数据变换_夏洛克江户川-CSDN博客_归一化和标准化
3 特征工程
我们需要的不仅仅是只会靠个嘴说这些理论,更重要的是能够用代码实现上述的知识。但是实现这些算法和模型,我们需要有数据集使用,数据集如果没有可用的我们可以人工捏造,而如果想要实战我们可以前往一些网址去寻找人们整理好的数据集。下面推荐一些常用的数据集来源:
Kaggle网址:Find Open Datasets and Machine Learning Projects | Kaggle
UCI数据集网址:UCI Machine Learning Repository
Sklearn网址:scikit-learn: Machine Learning in Python — scikit-learn 1.0.2 文档
3.1 Sklearn工具及数据集
Sklearn全名为Scikit-learn
,它是python语言的机器学习工具,其包内具有许多知名的机器学习算法的实现,而且官方文档完善,容易上手,具有丰富的API。
如果你是使用Anaconda3的玩家,那你不需要再去官网安装这个包了,使用下列指令看看你所有包里面有没有它吧!
pip list
3.2 数据集
让我们使用这个包加载一些数据集如何?
datasets.load_*() #获取小规模数据集,数据包含在datasets中
datasets.fetch_*() #获取大规模数据集,需要从网上下载,函数的第一个参数时data_home,表示数据集下载的目录里,默认是~/scikit_learn_data/
当然,我们首先使用小规模数据集,其使用方法如下:
sklearn.datasets.load_boston() #其中load_后面跟的名字即为数据集的名字
如果我们想要导入大数据集的话,我们可以这么写:
sklearn.datasets.fetch_名字(data_home = None, subset = 'train')
不过奇怪的是,我使用的是下列的方式导入数据集无效
import sklearn
sklearn.datasets.load_boston() #其中load_后面跟的名字即为数据集的名字
而用下面的方式导入却成功了
from sklearn.datasets import load_iris
subset属性可以指定加载哪一部分的数据集,可以是训练集train,可以是测试集test,也可以是所有all。
说了这么多不如动手实现一下,下面跟着我敲一下下面的代码吧!
from sklearn.datasets import load_irisdef datasets_demo():"""sklearn数据集的使用"""#获取数据集iris = load_iris()print("鸢尾花数据集:\n",iris)print("查看数据集描述:\n",iris["DESCR"])print("查看特征值的名字:\n",iris.feature_names)print("查看特征值:\n",iris.data,iris.data.shape)return Nonedatasets_demo()
通过上面的操作我们可以发现load和fetch返回的数据集一般是字典格式,其中包含有几个属性,如下所示:
- data:特征数据数组,是[n_samples*n_features]的二维numpy.ndarray数组
- target:标签数组,是n_samples的一维numpy.ndarray数组
- descr:数据描述
- feature_names:特征名
- feature_names:标签名
sklearn自带的数据集有以下几种:
自带的小的数据集为:sklearn.datasets.load_name
自带的大的数据集为:sklearn.datasets.fetch_name
需要注意的是,在导入大数据集时,一般需要下载,运行程序的速度可能会较慢。
3.3 数据集的划分
通过对之前的学习,我们知道数据集分为训练集和测试集。所以对于我们从sklearn导入的数据集中,我们不应该全部用于训练,而应该留一部分用于测试。
对于训练集和测试集的划分比例比较经典的就是73划分,即训练集百分之七十,而测试集为百分之三十。
那我们怎么划分?我们自己写算法来划分吗?其实不然,sklearn早就知道你会有此一步,所以你只需要调用其API即可。sklearn中用于分割数据集的函数如下:
sklearn.model_selection.train_test_split(arrays,*options)
x:数据集的特征值
y:数据集的特征值
test_size:测试集的大小,一般为float
random_state:随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
return:训练集特征值,测试集特征值,训练集目标值,测试集目标值。
让我们看看代码怎么写:
#记得调用函数!
from sklearn.model_selection import train_test_split#定义分割打印函数
def DataSplit():'''数据集划分'''#用四个变量来接收分割函数返回的值x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.3,random_state=22)#打印看看!print("训练集的特征值:\n",x_train,x_train.shape)return None#调用
DataSplit()
3.4 特征工程介绍
3.4.1 为什么需要特征工程
运用不同的机器学习模型,所分类或预测的结果大相径庭,这是因为有时候在特征工程阶段不同的操作导致结果的不同。机器学习领域的大神吴恩达曾经说过:业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法知识逼近这个上限罢了。
3.4.2 什么是特征工程
特征工程师使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程,其意义会直接影响机器学习的效果。
对于特征工程来说,其使用的工具有别于数据分析中我们用的pandas,而是采用了sklearn中对于特征处理更为强大的接口。特征工程包含的步骤有:
- 特征提取
- 特征预处理
- 特征降维
3.4.3 特征提取
特征提取就是将非结构化数据转为结构化数据的过程,或者说,将任意数据(如文本或图像)转换为可用于机器学习的数字特征。特征值化是为了计算机更好的去理解数据。不同的原始数据有不同的转换方法,如下所示:
- 字典特征提取(特征离散化)
- 文本特征提取
- 图像特征提取(深度学习领域)
在机器学习中,我们可以使用sklearn.feature_extraction这个API来满足我们的需求。
3.4.3.1 字典特征提取
字典特征提取会将键值对中的键转换为独热编码
。假如我们要对字典数据进行特征值化,我们可以采用以下的函数:
sklearn.feature_extraction.DicVectorizer(sparse = True…)
DicVectorizer.fit_transform(X):其中X是字典或者包含字典的迭代器返回值,其返回sparse(稀疏)矩阵
DicVectorizer.inverse_tranform(X):其中X是array数组或者sparse(稀疏)矩阵,其返回值是转换之前的数据格式
DicVectorizer.get_feature_names():返回类别名称
我们来尝试对下列数据进行提取:
from sklearn.feature_extraction import DictVectorizer #导包def load_dic():data = [{'city':'北京','temperature':100},{'city':'上海','temperature':60}]#实例化一个转换器类transfer = DictVectorizer(sparse=False)#调用其方法data_new = transfer.fit_transform(data)#打印特征提取后的新数据print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_dic()
这里需要科普两个知识:
独热编码(one-hot编码)
如果只是二分分类,这种分类我们大可只用0或者1来表示。
假设每次输入是一个2×2的灰度图像。我们可以用一个标量表示每个像素值,每个图像对应四个特征x1,x2,x3,x4x_1,x_2,x_3,x_4x1,x2,x3,x4,此外,假设每个图像属于类别"猫",“鸡”,"狗"中的一个。
接下来,我们要选择如何表示标签,如同我们前面所说,我们肯定不可能说P = “猫”,我们有两个明显地选择:最直接的想法是选择y∈{1,2,3},其中正数分别代表{“狗”,“猫”,“鸡”}。
但是统计学家很早之前就发明了一种表示分类数据的简单方法:独热编码。独热编码是一个向量,它的分量和类别一样多。类别对应的分量设置为1,其他所有分量设置为0。比如说应用到我们这个例子上的话,我们就可以用独热编码来表示我们的标签y,其中猫对应(1,0,0),鸡对应(0,1,0),狗对应(0,0,1)。
稀疏矩阵
在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。
当我们采用独热编码时,如果类别过多,就会导致向量中含有大量的0,而采用稀疏矩阵来表示可以将非零值按位置表示出来,这么做可以省去大量的0,提高计算速度。
学完了字典特征提取,我们拿到数据集怎么判断该不该用这个方法呢?我们可以从两点来判断:
- 本身就是字典或字典迭代器
- 类别特征较多,那么可以将数据集的特征转换为字典类型,再进行字典提取
3.4.3.2 文本特征提取
文本特征提取可以将文本数据进行特征值化。这里所说的文本包括句子、短语、单词、字母,但是我们一般是把单词来作为特征。假如我们要采用文本特征提取,我们可以采用以下的函数:
sklearn.feature_extraction.text.CountVectorizer(stop_words = [])
其返回的是一个词频矩阵
CountVectorizer.fit_transform(X):其中X是文本或者文本字符串的可迭代对象,返回一个sparse矩阵。
CountVectorizer.inverse_transform(X):其中X是数组或者sparse矩阵,返回值为转换之前的数据格。
CountVectorizer.get_feature_names():其返回值是一个单词列表。
我们来尝试对下列数据进行提取:
from sklearn.feature_extraction.text import CountVectorizerdef load_string():"""文本特征抽取"""data = ["lift is short,i lke python","life is too long , i disllike python"]#实例化一个转换器类transfer = CountVectorizer()#调用其方法data_new = transfer.fit_transform(data).toarray()#打印print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_string()
如果传入的数据是中文,在单词没有空格分隔符的情况下,其按句子分。
def load_chinese_string():"""中文文本特征提取"""data = ["我爱北京,我很喜欢北京","我很愿意去北京居住"]#实例化一个转换器类transfer = CountVectorizer()#调用其方法data_new = transfer.fit_transform(data).toarray()#打印print("new data:\n",data_new)print("feature name:\n",transfer.get_feature_names())load_chinese_string()
如果不想对一些语气词做统计,可以在实例化CountVectorizer类的时候以列表的形式将停用词传给该类。
3.4.3.3 中文文本特征提取
我们在前面说过,对于中文的文本特征提取无法像英文一般提取单词,只能提取句子,因为其没有如英文一般一句话好几个单词用空格分割的特性,如果在中文中一句话几个单词之间要手动加空格,显然是不现实的。我们可以利用一些库来帮我们分割中文单词,以便做特文本特征提取。
我们这里使用jieba
库,该库是一款优秀的python第三方中文分词库,jieba支持三种分词模式:精确模式、全模式和搜索引擎模式。
- 精确模式,试图将句子最精确地切开,适合文本分析;
- 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
- 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
- paddle模式,利用PaddlePaddle深度学习框架,训练序列标注(双向GRU)网络模型实现分词。同时支持词性标注。paddle模式使用需安装paddlepaddle-tiny,
pip install paddlepaddle-tiny==1.6.1
。目前paddle模式支持jieba v0.40及以上版本。jieba v0.40以下版本,请升级jieba,pip install jieba --upgrade
。PaddlePaddle官网
很多同学可能是使用anaconda3来进行机器学习的学习的,所以其没有自带jieba库,我们打开shell窗口,然后输入以下指令来安装jieba库。
pip install jieba
jieba库三种模式简单使用方法如下:
import jiebaseg_str = "好好学习,天天向上。"print("/".join(jieba.lcut(seg_str))) # 精简模式,返回一个列表类型的结果
print("/".join(jieba.lcut(seg_str, cut_all=True))) # 全模式,使用 'cut_all=True' 指定
print("/".join(jieba.lcut_for_search(seg_str))) # 搜索引擎模式
需要注意的是,通过jieba的cut方法返回的是一个迭代器对象,你可以用list包装它或者用其他的方式也可以。在新版本的jieba中,调用lcut
方法可以使得效果和cut+list
的效果一样。
学会了上面的操作,让我们来按照下面的代码敲一次再熟悉一下:
from sklearn.feature_extraction.text import CountVectorizer
import jiebadef cut_word(text):"""进行中文分词"""return " ".join(list(jieba.cut(text)))def count_chinese_demo():data = ["每个男人的心中都有两朵玫瑰,娶了红玫瑰,久而久之,红的变成了墙上的一抹蚊子血,白的还是“床前明月光”;娶了白玫瑰,白的便是衣服上的一粒饭粘子,红的却是心口上的一颗朱砂痣。"]data_new = []for sent in data:data_new.append(cut_word(sent))#print(data_new)#实例化一个转换器类transfer = CountVectorizer()#调用其方法data_final = transfer.fit_transform(data_new).toarray()#打印print("new data:\n",data_final)print("feature name:\n",transfer.get_feature_names())count_chinese_demo()
3.4.3.4 TF-IDF算法
上面的特征提取显然是有问题的,为何?因为我们通常如果有做中文文本特征提取,一般都是用于情感分析,即自然语言处理。我们做自然语言处理NLP的步骤是根据一些情感词来判断其句子中包含的情感,而如果你将一个句子事无巨细的全部提取,显然没有必要。
我们对句子关键词的提取采用的是API中TfidfVectorizer,人们更喜欢叫他TF-IDF
。
通过关键词的提取,我们更加容易地可以掌握句子的意思和文章的感情或大概。
TF-IDF的主要思想是:如果某一个词或者短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。而TF-IDF的作用就是用来评估词或短语在一份文件中的重要程度。
TFIDF是根据下面两项指标来判断关键词或关键短语的:
词频(term frequency,TF)
是指给定的词语在该文件中出现的频率逆向文档频率(inverse document frequency , IDF)
是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语文件的数目,再将得出的商取以10为底的对数得到
当我们想要看某个词的关键程度,只需将该词对应的TF和IDF相乘即可。
讲完理论,接下来让我们看一下sklearn库中有哪些API供我们完成这项工作。
sklearn.feature_extraction.text.TfidfVectorizer(stop_words = None…)
- TfidfVectorizer.fit_transform(X):其中X表示文本或者文本字符串的可迭代对象,返回值为sparse矩阵
- TfidfVectorizer.inverse_transform(X):其中X代表array数组或者sparse矩阵,返回值为转换之前的数据格式
- TfidfVectorizer.get_feature_names():其返回值为一个单词列表
了解了上面的原理后,让我们敲一下下面的代码体会一下吧。
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
import jiebadef tfidf_demo():"""用tdidf的方法进行文本特征抽取"""data = ["每个男人的心中都有两朵玫瑰,娶了红玫瑰,久而久之,红的变成了墙上的一抹蚊子血,白的还是“床前明月光”;娶了白玫瑰,白的便是衣服上的一粒饭粘子,红的却是心口上的一颗朱砂痣。"]data_new = []for sent in data:data_new.append(cut_word(sent))#print(data_new)#实例化一个转换器类transfer = TfidfVectorizer()#调用其方法data_final = transfer.fit_transform(data_new)#打印print("new data:\n",data_final)print("feature name:\n",transfer.get_feature_names())tfidf_demo()
综上所述,实际上TF-IDF算法是分类机器学习算法进行文章分类中前期数据处理的一种方式。
3.5 特征预处理
特征预处理是通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程。
3.5.1 特征预处理主要内容
特征预处理主要包括两种,即数值型数据的归一化
和标准化
。在sklearn中,我们可以通过:
sklearn.preprocessing
这个API来达到我们想要的结果。
3.5.2 大局看待
那么归一化和标准化又是什么呢?我们为什么要用它们呢?这就要涉及到数据的维度了。在有些数据中具有多个特征,各个特征之间的数量级差别很大,比如男生的学生号和男生吃过的米饭数,一个是以接近无穷的数量,一个仅仅是六位数或三位数。相差如此巨大的数量级会让我们的机器误以为某些特征不重要,而且计算会变慢。
让我们再看一个例子:
这个条形图中横坐标是国家,纵坐标是人口数量,由于中国人口基数过大,导致其他国家的人口看起来几乎为0,难以看出数据间的具体差异。而且条形图后半部分的国家人口增长速度过快,从澳大利亚开始人口基数逐渐明显,这影响条形图的美观。
如何解决上述的问题呢?
这时候就要引入我们的0-1归一化
了。归一化能把数据通过某种函数映射到(0,1)或者(1,1)之间的小数,这样做事为了数据处理方便,在转换的过程中,不同单位或量级的指标在函数的作用下会加权,导致数据间的差异变化不要那么巨大,即让数值差异过大的几组数据缩小在同一数量级中。这么做的好处不仅仅体现在后续处理方便,更重要的是在参数估计时使用梯度下降求解最优化问题时,归一化/标准化可以加快梯度下降的求解速度。
通过归一化对上述的问题映射到0-1上后,我们可以看到效果如下:
虽然压缩为同一个数量级了,但是还是没有达到解决差异过大导致前几个国家数据不明显的问题,这个时候我们就要引入我们第二个方法:零均值规范化(Z-score标准化)
。通过标准化后的数据如下:
3.5.3 归一化
归一化前面说过,其可以通过函数将原始数据进行变换映射到(默认)[0,1]之间。其公式如下所示:
X=x−minmax−min其中max指的是统一特征下不同数据的最大特征反之则为minX = \frac{x-min}{max-min}\\ 其中max指的是统一特征下不同数据的最大特征\\ 反之则为min X=max−minx−min其中max指的是统一特征下不同数据的最大特征反之则为min
让我们来计算一下吧!
假设我要对特征1上的90这个数据做归一化,只需X=90−6090−60=1X = \frac{90-60}{90-60} = 1X=90−6090−60=1。
如果你不想投到[0,1]区间,而想投到其他区间,可以将上述的X代入下面这个公式:
X′=X∗(mx−mi)+mi其中mx为指定区间的右端点,mi为指定区间的左端点X' = X*(mx - mi)+mi \\其中mx为指定区间的右端点,mi为指定区间的左端点 X′=X∗(mx−mi)+mi其中mx为指定区间的右端点,mi为指定区间的左端点
如我们要投到[-1,1],只需X′=1∗(1+1)−1=1X' = 1*(1+1)-1 = 1X′=1∗(1+1)−1=1。
以上就是归一化的计算过程,下面让我们看看如何用API来实现吧!
归一化使用的API方法如下所示:
sklearn.preprocessing.MinMaxScaler(feature_range = (0,1)…)
MinMaxScalar.fit_transform(X):其中X是numpy中array格式的数据,返回值为于转化前形状相同的array。
下面跟着我敲一下下面的代码:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import jieba
from sklearn.preprocessing import MinMaxScalerdef minmax_demo():"""归一化"""# 实例化转换器类transfer = MinMaxScaler()# 调用其方法# 获取数据集iris = load_iris()x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target)iris_new = transfer.fit_transform(x_train)print(iris_new)minmax_demo()
归一化公式是由最大值和最小值计算得到的,因此当数据中有异常值的情况下会影响归一化效果,所以这种方法鲁棒性比较差,只适用传统精确小数据场景。
3.5.4 标准化
标准化的公式如下:
X=x−meanσX = \frac {x - mean}{\sigma} X=σx−mean
让我们来看看其使用的API:
sklearn.preprocessing.StandardScaler()
StandardScaler.fit_transform(X):其中X为numpy中array格式的数据,返回值为转换前形状相同的array。
让我们跟着下面的代码来试一下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScalerdef stand_demo():"""标准化"""# 实例化转换器类transfer = StandardScaler()# 获取数据集iris = load_iris()x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target)iris_train = transfer.fit_transform(x_train)print(iris_train)stand_demo()
标准化适用于在已有样本足够多的情况下使其比较稳定,适合现代嘈杂大数据场景。
3.6 降维
要提到降维,我们首先就要知道维度是什么。在数学中,0维度一般指标量,1维一般指向量,2维一般指矩阵,3维及以上一般指多个矩阵嵌套。
降维是指在某些限定条件下,降低随机变量特征的个数,得到一组“不相关”主变量的过程。用通俗的话来讲就是,特征太多了,后来很难输入到算法之中,我们需要舍弃一些维度,或者将一些维度合二为一来达到降维的效果。
通常在进行降维后,特征和特征之间能够达到一种不相关的效果。如果没有达到这种效果,就说明你的降维工作做的不够好,因为在训练模型的时候,我们都是使用特征和标签来训练模型,如果特征本身之间存在问题或者特征之间相关性较强,算法学习预测效果会大打折扣。
降维的方式有两种:即特征选择和主成分分析。在下一小节中,我们会细讲它们。
3.6.1 特征选择
特征选择是指在数据中包含冗余或相关变量中寻找出主要特征。
特征选择包含有四种方法,为了入门,我们只讲其中两种:过滤式
和嵌入式
。详见:特征选择(Feature Selection)_hren_ron的博客-CSDN博客_特征选择。
- Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联。其主要的方法有方差选择法和相关系数法。
- Embedded(嵌入式):算法自动选择特征(特征和目标值之间的关联)。其主要方法有决策树、正则化、深度学习卷积等。
对于特征选择的使用,我们可以使用sklearn给我们提供的模块:
sklearn.feature_selection
3.6.2 过滤式
3.6.2.1 低方差特征过滤
对于一些地方差的特征,其稳定性良好导致所有的特征基本处于同一堆位置。而在聚类和密度聚类算法中(无监督学习),其就是要根据数据的分布特点来划分类别的,如果你的数据全部凑在一起没有分布特点还划分啥?所以低方差特征过滤就是删除所有低方差的特征。我们可以使用sklearn中的API来达到我们需要的效果。
sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
其API中提供了Variance.fit_transform(X)函数:其中X代表numpy型数组[n_sample,n_feature],返回的数组中会被删除原来数组中低方差的特征。
让我们来用这个方法来对鸢尾花数据集进行特征选择吧!
# 导包
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import VarianceThresholddef datademo():# 加载鸢尾花数据集iris = datasets.load_iris()x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target)# 实例化转换器类transfer = VarianceThreshold(threshold=0)iris_new = transfer.fit_transform(x_train)print(iris_new)datademo()
3.6.2.2 相关系数法
皮尔逊相关系数是相关系数法的其中一种,其反映了变量之间相关关系密切程度的统计指标。
我不是很建议你去了解这个相关系数的公式,因为我们不是在学概率论。如果你想了解这个公式,你可以先去学学概率论。
r=n∑xy−∑x∑yn∑x2−(∑x)2n∑y2−(∑y)2r = \frac{n \sum xy- \sum x \sum y}{\sqrt {n \sum x^2 - (\sum x)^2} \sqrt{n \sum y^2 - (\sum y)^2}} r=n∑x2−(∑x)2n∑y2−(∑y)2n∑xy−∑x∑y
当计算出r之后,如果其值介于-1到+1之间,那么其性质如下:
当r >0时,表示两变量正相关,r<0时,两变量为负相关。
当| r | = 1时,表示两变量为完全相关,r = 0时,表示两变量间无相关关系。
当0< | r |<1时,表示两变量存在一定程度的相关,且| r |越解决1,两变量间线性关系越密切,| r |越接近于0,表示两变量的线性相关越弱。
一般可按三级划分:| r |<0.4为低度相关,0.4<= | r |<0.7为显著性相关,0.7<= | r |<1为高度线性相关。
我们可以使用scipy库中的pearsonr来达到我们的目的。
from scipy.stats import pearsonr
x:(N,)array _like
y:(N, )array_like Returns:(Pearson’s correlation coefficient, p -value)
由于这里没有合适的数据集,这里我就不演示了。
需要注意的是,两个特征相关性很高的话,我们选取其中一个即可。或者我们可以使用主成分分析
。
3.6.3 主成分分析
主成分分析是指高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量。其作用是将数据维数压缩,尽可能降低原数据的维数,损失少量信息。
主成分分析一般用于回归分析或者聚类分析中。
如何更好地讲述主成分分析呢?我们可以这么理解。
在现实生活中任何物体都是三维的,当结果素描将图像印于纸上时,三维就转换为了二维,这就是PCA。
我们首先将二维降到一维。在平面直角坐标系中我们有一些点,降维的方式就是画一条直线,然后将所有点投影到这条线上,如图所示:
以上的图实际上是有5个点的,但是由于选出直线的不合理,导致点和线重合了,高维信息的损失了一部分。而在降维的过程中,我们应该保持高维度尽可能多的信息。
而如果采用下面的方式降维,这时候就非常不错了。
我们要将一个三维的特征向量降至一个二维的特征向量。过程是与上面类似的,我们将三维向量投射到一个二维的平面上,强迫使得所有的数据都在同一个平面上,降至二维的特征向量。同通俗的话来讲就是,拿一张白纸摆在空间中,然后让所有的点投影到纸上。需要注意的是,与上面相同,我们不希望降维的过程中高维度信息受到损失。
弄清楚上面的原理后,让我们开始看看sklearn中有哪些API供我们调用吧!
sklearn.decomposition.PCA(n_components = None)
其中n_components可以是小数也可以是整数,小数表示保留百分之多少的信息,整数为减少到多少特征。
方法PCA.fit_transform(X):其中X只能传入numpy array格式的数据[n_samples,n_features],其返回的是转换后指定维度的array。
让我们来试试!
from sklearn.decomposition import PCAdef pca_demo():"""PCA降维"""data = [[2,8,4,5],[6,3,0,8],[5,4,9,1]]#实例化一个转换器类transfer = PCA(n_components=0.95)#调用转换方法data_new = transfer.fit_transform(data)print(data_new)pca_demo()