目录
特征工程
2.1 数据集
2.1.1 可用数据集
2.1.2 sklearn数据集
2.1.3 数据集的划分
2.2 特征工程介绍
学习目标
2.2.1 为什么需要特征工程(Feature Engineering)
2.2.2 什么是特征工程
2.2.3 特征工程的位置与数据处理的比较?
2.3 特征提取
学习目标
2.3.1 特征提取
1 将任意数据(如文本或图像)转换为可用于机器学习的数字特征
2 特征提取API
2.3.2 字典特征提取
1 应用
2 流程分析
2.3 总结
2.3.3 文本特征提取
1 应用
2 流程分析
问题:如果我们将数据替换成中文?
3 jieba分词处理
4 案例分析
5 Tf-idf文本特征提取
6 Tf-idf的重要性
2.4 特征预处理
学习目标
2.4.1 什么是特征预处理
1 包含内容
2 特征预处理API
约会对象数据
2.4.2 归一化
1 定义
2 公式
3 API
4 数据计算
问题:如果数据中异常点较多,会有什么影响?
5 归一化总结
2.4.3 标准化
1 定义
2 公式
3 API
4 数据计算
5 标准化总结
2.5 特征降维
学习目标
2.5.1 降维
2.5.2 降维的两种方式
2.5.3 什么是特征选择
1 定义
2 方法
3 模块
4 过滤式
2.6 主成分分析
学习目标
2.6.1 什么是主成分分析(PCA)
1 计算案例理解(了解,无需记忆)
2 API
3 数据计算
2.6.2 案例:探究用户对物品类别的喜好细分降维
1 需求?
2 分析
3 完整代码
每日作业
特征工程
了解特征工程在机器学习当中的重要性
应用sklearn实现特征预处理
应用sklearn实现特征抽取
应用sklearn实现特征选择
应用PCA实现特征的降维
2.1 数据集
- 目标
- 知道数据集的分为训练集和测试集
- 会使用sklearn的数据集
- 应用
- 无
文章图片
Kaggle网址:Find Open Datasets and Machine Learning Projects | Kaggle
UCI数据集网址: http://archive.ics.uci.edu/ml/
scikit-learn网址:http://scikit-learn.org/stable/datasets/index.html#datasets
1 Scikit-learn工具介绍
文章图片
2.1.2 sklearn数据集
1 scikit-learn数据集API介绍
2 sklearn小数据集
- Python语言的机器学习工具
- Scikit-learn包括许多知名的机器学习算法的实现
- Scikit-learn文档完善,容易上手,丰富的API
- 目前稳定版本0.19.1
- 2 安装
-
pip3 install Scikit-learn==0.19.1
安装好之后可以通过以下命令查看是否安装成功
import sklearn
- 注:安装scikit-learn需要Numpy, Scipy等库
- 3 Scikit-learn包含的内容
- 分类、聚类、回归
- 特征工程
- 模型选择、调优
- sklearn.datasets
- 加载获取流行数据集
- datasets.load_*()
- 获取小规模数据集,数据包含在datasets里
- datasets.fetch_*(data_home=None)
- 获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是 ~/scikit_learn_data/
- sklearn.datasets.load_iris()
加载并返回鸢尾花数据集
文章图片
sklearn.datasets.load_boston()
加载并返回波士顿房价数据集
文章图片
3 sklearn大数据集
- sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)
- subset:'train'或者'test','all',可选,选择要加载的数据集。
- 训练集的“训练”,测试集的“测试”,两者的“全部”
- 以鸢尾花数据集为例:
-
sklearn数据集返回值介绍
- load和fetch返回的数据类型datasets.base.Bunch(字典格式)
- data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
- target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
- DESCR:数据描述
- feature_names:特征名,新闻数据,手写数字、回归数据集没有
- target_names:标签名
from sklearn.datasets import load_iris
# 获取鸢尾花数据集
iris = load_iris()
print("鸢尾花数据集的返回值:\n", iris)
# 返回值是一个继承自字典的Bench
print("鸢尾花的特征值:\n", iris["data"])
print("鸢尾花的目标值:\n", iris.target)
print("鸢尾花特征的名字:\n", iris.feature_names)
print("鸢尾花目标值的名字:\n", iris.target_names)
print("鸢尾花的描述:\n", iris.DESCR)
思考:拿到的数据是否全部都用来训练一个模型?
2.1.3 数据集的划分
机器学习一般的数据集会划分为两个部分:
- 训练数据:用于训练,构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效
- 训练集:70% 80% 75%
- 测试集:30% 20% 30%
- sklearn.model_selection.train_test_split(arrays, *options)
- x 数据集的特征值
- y 数据集的标签值
- test_size 测试集的大小,一般为float
- random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
- return 测试集特征训练集特征值值,训练标签,测试标签(默认随机取)
-
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_splitdef datasets_demo(): """ 对鸢尾花数据集的演示 :return: None """ # 1、获取鸢尾花数据集 iris = load_iris() print("鸢尾花数据集的返回值:\n", iris) # 返回值是一个继承自字典的Bench print("鸢尾花的特征值:\n", iris["data"]) print("鸢尾花的目标值:\n", iris.target) print("鸢尾花特征的名字:\n", iris.feature_names) print("鸢尾花目标值的名字:\n", iris.target_names) print("鸢尾花的描述:\n", iris.DESCR)# 2、对鸢尾花数据集进行分割 # 训练集的特征值x_train 测试集的特征值x_test 训练集的目标值y_train 测试集的目标值y_test x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22) print("x_train:\n", x_train.shape) # 随机数种子 x_train1, x_test1, y_train1, y_test1 = train_test_split(iris.data, iris.target, random_state=6) x_train2, x_test2, y_train2, y_test2 = train_test_split(iris.data, iris.target, random_state=6) print("如果随机数种子不一致:\n", x_train == x_train1) print("如果随机数种子一致:\n", x_train1 == x_train2)return None
特征工程包含内容
- 目标
- 了解特征工程在机器学习当中的重要性
- 知道特征工程的分类
- 应用
- 无
文章图片
机器学习领域的大神Andrew Ng(吴恩达)老师说“Coming up with features is difficult, time-consuming, requires expert knowledge. “Applied machine learning” is basically feature engineering. ”
2.2.2 什么是特征工程 特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
注:业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。
- 无
- 意义:会直接影响机器学习的效果
- 2.2.3 特征工程的位置与数据处理的比较
文章图片
- pandas:一个数据读取非常方便以及基本的处理格式的工具
- sklearn:对于特征的处理提供了强大的接口
- 特征抽取
- 特征预处理
- 特征降维
- 目标
- 应用DictVectorizer实现对类别特征进行数值化、离散化
- 应用CountVectorizer实现对文本特征进行数值化
- 应用TfidfVectorizer实现对文本特征进行数值化
- 说出两种文本特征提取的方式区别
- 应用
- 无
文章图片
2.3.1 特征提取 1 将任意数据(如文本或图像)转换为可用于机器学习的数字特征
注:特征值化是为了计算机更好的去理解数据
- 字典特征提取(特征离散化)
- 文本特征提取
- 图像特征提取(深度学习将介绍)
sklearn.feature_extraction
2.3.2 字典特征提取 作用:对字典数据进行特征值化
- sklearn.feature_extraction.DictVectorizer(sparse=True,…)
- DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵
- DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
- DictVectorizer.get_feature_names() 返回类别名称
我们对以下数据进行特征提取
[{'city': '北京','temperature':100}
{'city': '上海','temperature':60}
{'city': '深圳','temperature':30}]
文章图片
2 流程分析
- 实例化类DictVectorizer
- 调用fit_transform方法输入数据并转换(注意返回格式)
from sklearn.feature_extraction import DictVectorizerdef dict_demo():
"""
对字典类型的数据进行特征抽取
:return: None
"""
data = https://www.it610.com/article/[{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
# 1、实例化一个转换器类
transfer = DictVectorizer(sparse=False)
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(data)
print("返回的结果:\n", data)
# 打印特征名字
print("特征名字:\n", transfer.get_feature_names())return None
注意观察没有加上sparse=False参数的结果
返回的结果:
(0, 1)1.0
(0, 3)100.0
(1, 0)1.0
(1, 3)60.0
(2, 2)1.0
(2, 3)30.0
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
这个结果并不是我们想要看到的,所以加上参数,得到想要的结果:
返回的结果:
[[0.1.0.100.]
[1.0.0.60.]
[0.0.1.30.]]
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
之前在学习pandas中的离散化的时候,也实现了类似的效果。
我们把这个处理数据的技巧叫做”one-hot“编码:
文章图片
转化为:
文章图片
2.3 总结
对于特征当中存在类别信息的我们都会做one-hot编码处理
2.3.3 文本特征提取 作用:对文本数据进行特征值化
- sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
- 返回词频矩阵
- CountVectorizer.fit_transform(X) X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
- CountVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格
- CountVectorizer.get_feature_names() 返回值:单词列表
- sklearn.feature_extraction.text.TfidfVectorizer
我们对以下数据进行特征提取
["life is short,i like python",
"life is too long,i dislike python"]
文章图片
2 流程分析
- 实例化类CountVectorizer
- 调用fit_transform方法输入数据并转换 (注意返回格式,利用toarray()进行sparse矩阵转换array数组)
from sklearn.feature_extraction.text import CountVectorizerdef text_count_demo():
"""
对文本进行特征抽取,countvetorizer
:return: None
"""
data = https://www.it610.com/article/["life is short,i like like python", "life is too long,i dislike python"]
# 1、实例化一个转换器类
# transfer = CountVectorizer(sparse=False)
transfer = CountVectorizer()
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(data)
print("文本特征抽取的结果:\n", data.toarray())
print("返回特征名字:\n", transfer.get_feature_names())return None
返回结果:
问题:如果我们将数据替换成中文?
"人生苦短,我喜欢Python" "生活太长久,我不喜欢Python"
那么最终得到的结果是
文章图片
为什么会得到这样的结果呢,仔细分析之后会发现英文默认是以空格分开的。其实就达到了一个分词的效果,所以我们要对中文进行分词处理
3 jieba分词处理
- jieba.cut()
- 返回词语组成的生成器
pip3 install jieba
4 案例分析
对以下三句话进行特征值化
今天很残酷,明天更残酷,后天很美好,
但绝对大部分是死在明天晚上,所以每个人不要放弃今天。我们看到的从很远星系来的光是在几百万年之前发出的,
这样当我们看到宇宙时,我们是在看它的过去。如果只用一种方式了解某样事物,你就不会真正了解它。
了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。
- 分析
- 准备句子,利用jieba.cut进行分词
- 实例化CountVectorizer
- 将分词结果变成字符串当作fit_transform的输入值
文章图片
from sklearn.feature_extraction.text import CountVectorizer
import jiebadef cut_word(text):
"""
对中文进行分词
"我爱北京天安门"————>"我 爱 北京 天安门"
:param text:
:return: text
"""
# 用结巴对中文字符串进行分词
text = " ".join(list(jieba.cut(text)))return textdef text_chinese_count_demo2():
"""
对中文进行特征抽取
:return: None
"""
data = https://www.it610.com/article/["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
# 将原始数据转换成分好词的形式
text_list = []
for sent in data:
text_list.append(cut_word(sent))
print(text_list)# 1、实例化一个转换器类
# transfer = CountVectorizer(sparse=False)
transfer = CountVectorizer()
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(text_list)
print("文本特征抽取的结果:\n", data.toarray())
print("返回特征名字:\n", transfer.get_feature_names())return None
返回结果:
Building prefix dict from the default dictionary ...
Dumping model to file cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 1.032 seconds.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
Prefix dict has been built succesfully.
文本特征抽取的结果:
[[2 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 1 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 0 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0 0]]
返回特征名字:
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']
但如果把这样的词语特征用于分类,会出现什么问题?
请看问题:
文章图片
该如何处理某个词或短语在多篇文章中出现的次数高这种情况
5 Tf-idf文本特征提取
- TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
- TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
- 词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率
- 逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
最终得出结果可以理解为重要程度。
注:假如一篇文件的总词语数是100个,而词语"非常"出现了5次,那么"非常"一词在该文件中的词频就是5/100=0.05。而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现"非常"一词的文件数。所以,如果"非常"一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是lg(10,000,000 / 1,0000)=3。最后"非常"对于这篇文档的tf-idf的分数为0.05 * 3=0.15
5.2 案例
from sklearn.feature_extraction.text import TfidfVectorizer
import jiebadef cut_word(text):
"""
对中文进行分词
"我爱北京天安门"————>"我 爱 北京 天安门"
:param text:
:return: text
"""
# 用结巴对中文字符串进行分词
text = " ".join(list(jieba.cut(text)))return textdef text_chinese_tfidf_demo():
"""
对中文进行特征抽取
:return: None
"""
data = https://www.it610.com/article/["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
# 将原始数据转换成分好词的形式
text_list = []
for sent in data:
text_list.append(cut_word(sent))
print(text_list)# 1、实例化一个转换器类
# transfer = CountVectorizer(sparse=False)
transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要'])
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(text_list)
print("文本特征抽取的结果:\n", data.toarray())
print("返回特征名字:\n", transfer.get_feature_names())return None
返回结果:
Building prefix dict from the default dictionary ...
Loading model from cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 0.856 seconds.
Prefix dict has been built succesfully.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
文本特征抽取的结果:
[[ 0.0.0.0.436435780.0.0.
0.0.0.218217890.0.218217890.0.
0.0.0.218217890.218217890.0.43643578
0.0.218217890.0.436435780.218217890.0.
0.0.218217890.218217890.0.0.21821789
0.]
[ 0.24108220.0.0.0.24108220.2410822
0.24108220.0.0.0.0.0.
0.0.24108220.550047690.0.0.0.
0.24108220.0.0.0.0.48216441
0.0.0.0.0.0.2410822
0.0.2410822 ]
[ 0.0.6440030.483002250.0.0.0.
0.161000750.161000750.0.161000750.0.16100075
0.161000750.0.122445220.0.0.16100075
0.0.0.0.161000750.0.0.
0.32200150.161000750.0.0.161000750.0.
0.]]
返回特征名字:
['之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']
6 Tf-idf的重要性
分类机器学习算法进行文章分类中前期数据处理方式
2.4 特征预处理 学习目标
- 目标
- 了解数值型数据、类别型数据特点
- 应用MinMaxScaler实现对特征数据进行归一化
- 应用StandardScaler实现对特征数据进行标准化
- 应用
- 无
文章图片
2.4.1 什么是特征预处理
# scikit-learn的解释
provides several common utility functions and transformer classes to change raw feature vectors into a representation that is more suitable for the downstream estimators.
翻译过来:通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
可以通过上面那张图来理解
1 包含内容
- 数值型数据的无量纲化:
- 归一化
- 标准化
sklearn.preprocessing
为什么我们要进行归一化/标准化?
- 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其它的特征
文章图片
我们需要用到一些方法进行无量纲化,使不同规格的数据转换到同一规格
2.4.2 归一化 1 定义
通过对原始数据进行变换把数据映射到(默认为[0,1])之间
2 公式
文章图片
作用于每一列,max为一列的最大值,min为一列的最小值,那么X’’为最终结果,mx,mi分别为指定区间值默认mx为1,mi为0那么怎么理解这个过程呢?我们通过一个例子
文章图片
3 API
- sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
- MinMaxScalar.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- MinMaxScalar.fit_transform(X)
我们对以下数据进行运算,在dating.txt中。保存的就是之前的约会对象数据
milage,Liters,Consumtime,target
40920,8.326976,0.953952,3
14488,7.153469,1.673904,2
26052,1.441871,0.805124,1
75136,13.147394,0.428964,1
38344,1.669788,0.134296,1
- 分析
2、通过fit_transform转换
import pandas as pd
from sklearn.preprocessing import MinMaxScalerdef minmax_demo():
"""
归一化演示
:return: None
"""
data = https://www.it610.com/article/pd.read_csv("dating.txt")
print(data)
# 1、实例化一个转换器类
transfer = MinMaxScaler(feature_range=(2, 3))
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(data[['milage','Liters','Consumtime']])
print("最小值最大值归一化处理的结果:\n", data)return None
返回结果:
milageLitersConsumtimetarget
0409208.3269760.9539523
1144887.1534691.6739042
2260521.4418710.8051241
37513613.1473940.4289641
..............
998481119.1345280.7280453
999437577.8826011.3324463[1000 rows x 4 columns]
最小值最大值归一化处理的结果:
[[ 2.448325352.398051392.56233353]
[ 2.158732592.341954672.98724416]
[ 2.285429432.068925232.47449629]
...,
[ 2.291159492.509102942.51079493]
[ 2.527110972.436654512.4290048 ]
[ 2.479407932.37680912.78571804]]
问题:如果数据中异常点较多,会有什么影响?
文章图片
5 归一化总结
注意最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景。
怎么办?
2.4.3 标准化 1 定义
通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
2 公式
文章图片
作用于每一列,mean为平均值,σ为标准差所以回到刚才异常点的地方,我们再来看看标准化
文章图片
- 对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变
- 对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。
- sklearn.preprocessing.StandardScaler( )
- 处理之后每列来说所有数据都聚集在均值0附近标准差差为1
- StandardScaler.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
同样对上面的数据进行处理
- 分析
2、通过fit_transform转换
import pandas as pd
from sklearn.preprocessing import StandardScalerdef stand_demo():
"""
标准化演示
:return: None
"""
data = https://www.it610.com/article/pd.read_csv("dating.txt")
print(data)
# 1、实例化一个转换器类
transfer = StandardScaler()
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(data[['milage','Liters','Consumtime']])
print("标准化的结果:\n", data)
print("每一列特征的平均值:\n", transfer.mean_)
print("每一列特征的方差:\n", transfer.var_)return None
返回结果:
milageLitersConsumtimetarget
0409208.3269760.9539523
1144887.1534691.6739042
2260521.4418710.8051241
..............
9972657510.6501020.8666273
998481119.1345280.7280453
999437577.8826011.3324463[1000 rows x 4 columns]
标准化的结果:
[[ 0.331931580.416601880.24523407]
[-0.872477840.139928971.69385734]
[-0.34554872 -1.20667094 -0.05422437]
...,
[-0.321717520.964315720.06952649]
[ 0.659599110.60699509 -0.20931587]
[ 0.461203280.311833421.00680598]]
每一列特征的平均值:
[3.36354210e+046.55996083e+008.32072997e-01]
每一列特征的方差:
[4.81628039e+081.79902874e+012.46999554e-01]
5 标准化总结
在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
2.5 特征降维 学习目标
- 目标
- 知道特征选择的嵌入式、过滤式以及包裹氏三种方式
- 应用VarianceThreshold实现删除低方差特征
- 了解相关系数的特点和计算
- 应用相关性系数实现特征选择
- 应用
- 无
- 降低随机变量的个数
-
文章图片
- 相关特征(correlated feature)
- 相对湿度与降雨量之间的相关
- 等等
正是因为在进行训练的时候,我们都是使用特征进行学习。如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测会影响较大2.5.2 降维的两种方式
- 特征选择
- 主成分分析(可以理解一种特征提取的方式)
数据中包含冗余或无关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。
文章图片
2 方法
- Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
- 方差选择法:低方差特征过滤
- 相关系数
- Embedded (嵌入式):算法自动选择特征(特征与目标值之间的关联)
- 决策树:信息熵、信息增益
- 正则化:L1、L2
- 深度学习:卷积等
对于Embedded方式,只能在讲解算法的时候在进行介绍,更好的去理解3 模块
sklearn.feature_selection
4 过滤式
4.1 低方差特征过滤
删除低方差的一些特征,前面讲过方差的意义。再结合方差的大小来考虑这个方式的角度。
- 特征方差小:某个特征大多样本的值比较相近
- 特征方差大:某个特征很多样本的值都有差别
- sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
- 删除所有低方差特征
- Variance.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。
我们对某些股票的指标特征之间进行一个筛选,数据在"factor_regression_data/factor_returns.csv"文件当中,除去'index,'date','return'列不考虑(这些类型不匹配,也不是所需要指标)
一共这些特征
pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense
index,pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense,date,return
0,000001.XSHE,5.9572,1.1818,85252550922.0,0.8008,14.9403,1211444855670.0,2.01,20701401000.0,10882540000.0,2012-01-31,0.027657228229937388
1,000002.XSHE,7.0289,1.588,84113358168.0,1.6463,7.8656,300252061695.0,0.326,29308369223.2,23783476901.2,2012-01-31,0.08235182370820669
2,000008.XSHE,-262.7461,7.0003,517045520.0,-0.5678,-0.5943,770517752.56,-0.006,11679829.03,12030080.04,2012-01-31,0.09978900335112327
3,000060.XSHE,16.476,3.7146,19680455995.0,5.6036,14.617,28009159184.6,0.35,9189386877.65,7935542726.05,2012-01-31,0.12159482758620697
4,000069.XSHE,12.5878,2.5616,41727214853.0,2.8729,10.9097,81247380359.0,0.271,8951453490.28,7091397989.13,2012-01-31,-0.0026808154146886697
- 分析
2、调用fit_transform
def variance_demo():
"""
删除低方差特征——特征选择
:return: None
"""
data = https://www.it610.com/article/pd.read_csv("factor_returns.csv")
print(data)
# 1、实例化一个转换器类
transfer = VarianceThreshold(threshold=1)
# 2、调用fit_transform
data = https://www.it610.com/article/transfer.fit_transform(data.iloc[:, 1:10])
print("删除低方差特征的结果:\n", data)
print("形状:\n", data.shape)return None
返回结果:
indexpe_ratiopb_ratiomarket_cap\
0000001.XSHE5.95721.18188.525255e+10
1000002.XSHE7.02891.58808.411336e+10
...............
2316601958.XSHG52.54082.46463.287910e+10
2317601989.XSHG14.22031.41035.911086e+10return_on_asset_net_profitdu_return_on_equityev\
00.800814.94031.211445e+12
11.64637.86563.002521e+11
............
23162.74442.92023.883803e+10
23172.03838.61792.020661e+11earnings_per_sharerevenuetotal_expensedatereturn
02.01002.070140e+101.088254e+102012-01-310.027657
10.32602.930837e+102.378348e+102012-01-310.082352
2-0.00601.167983e+071.203008e+072012-01-310.099789
..................
23150.22001.789082e+101.749295e+102012-11-300.137134
23160.12106.465392e+096.009007e+092012-11-300.149167
23170.24704.509872e+104.132842e+102012-11-300.183629[2318 rows x 12 columns]
删除低方差特征的结果:
[[5.95720000e+001.18180000e+008.52525509e+10 ...,1.21144486e+12
2.07014010e+101.08825400e+10]
[7.02890000e+001.58800000e+008.41133582e+10 ...,3.00252062e+11
2.93083692e+102.37834769e+10]
[ -2.62746100e+027.00030000e+005.17045520e+08 ...,7.70517753e+08
1.16798290e+071.20300800e+07]
...,
[3.95523000e+014.00520000e+001.70243430e+10 ...,2.42081699e+10
1.78908166e+101.74929478e+10]
[5.25408000e+012.46460000e+003.28790988e+10 ...,3.88380258e+10
6.46539204e+096.00900728e+09]
[1.42203000e+011.41030000e+005.91108572e+10 ...,2.02066110e+11
4.50987171e+104.13284212e+10]]
形状:
(2318, 8)
4.2 相关系数
- 皮尔逊相关系数(Pearson Correlation Coefficient)
- 反映变量之间相关关系密切程度的统计指标
- 公式
文章图片
- 比如说我们计算年广告费投入与月均销售额
文章图片
文章图片
最终计算:
文章图片
= 0.9942
所以我们最终得出结论是广告投入费与月平均销售额之间有高度的正相关关系。
4.2.3 特点
相关系数的值介于–1与+1之间,即–1≤ r ≤+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为高度线性相关
这个符号:|r|为r的绝对值, |-5| = 54.2.4 API
- from scipy.stats import pearsonr
- x : (N,) array_like
- y : (N,) array_like Returns: (Pearson’s correlation coefficient, p-value)
我们刚才的股票的这些指标进行相关性计算, 假设我们以
factor = ['pe_ratio','pb_ratio','market_cap','return_on_asset_net_profit','du_return_on_equity','ev','earnings_per_share','revenue','total_expense']
这些特征当中的两两进行计算,得出相关性高的一些特征
文章图片
- 分析
- 两两特征之间进行相关性计算
import pandas as pd
from scipy.stats import pearsonrdef pearsonr_demo():
"""
相关系数计算
:return: None
"""
data = https://www.it610.com/article/pd.read_csv("factor_returns.csv")factor = ['pe_ratio', 'pb_ratio', 'market_cap', 'return_on_asset_net_profit', 'du_return_on_equity', 'ev',
'earnings_per_share', 'revenue', 'total_expense']for i in range(len(factor)):
for j in range(i, len(factor) - 1):
print(
"指标%s与指标%s之间的相关性大小为%f" % (factor[i], factor[j + 1], pearsonr(data[factor[i]], data[factor[j + 1]])[0]))return None
返回结果:
指标pe_ratio与指标pb_ratio之间的相关性大小为-0.004389
指标pe_ratio与指标market_cap之间的相关性大小为-0.068861
指标pe_ratio与指标return_on_asset_net_profit之间的相关性大小为-0.066009
指标pe_ratio与指标du_return_on_equity之间的相关性大小为-0.082364
指标pe_ratio与指标ev之间的相关性大小为-0.046159
指标pe_ratio与指标earnings_per_share之间的相关性大小为-0.072082
指标pe_ratio与指标revenue之间的相关性大小为-0.058693
指标pe_ratio与指标total_expense之间的相关性大小为-0.055551
指标pb_ratio与指标market_cap之间的相关性大小为0.009336
指标pb_ratio与指标return_on_asset_net_profit之间的相关性大小为0.445381
指标pb_ratio与指标du_return_on_equity之间的相关性大小为0.291367
指标pb_ratio与指标ev之间的相关性大小为-0.183232
指标pb_ratio与指标earnings_per_share之间的相关性大小为0.198708
指标pb_ratio与指标revenue之间的相关性大小为-0.177671
指标pb_ratio与指标total_expense之间的相关性大小为-0.173339
指标market_cap与指标return_on_asset_net_profit之间的相关性大小为0.214774
指标market_cap与指标du_return_on_equity之间的相关性大小为0.316288
指标market_cap与指标ev之间的相关性大小为0.565533
指标market_cap与指标earnings_per_share之间的相关性大小为0.524179
指标market_cap与指标revenue之间的相关性大小为0.440653
指标market_cap与指标total_expense之间的相关性大小为0.386550
指标return_on_asset_net_profit与指标du_return_on_equity之间的相关性大小为0.818697
指标return_on_asset_net_profit与指标ev之间的相关性大小为-0.101225
指标return_on_asset_net_profit与指标earnings_per_share之间的相关性大小为0.635933
指标return_on_asset_net_profit与指标revenue之间的相关性大小为0.038582
指标return_on_asset_net_profit与指标total_expense之间的相关性大小为0.027014
指标du_return_on_equity与指标ev之间的相关性大小为0.118807
指标du_return_on_equity与指标earnings_per_share之间的相关性大小为0.651996
指标du_return_on_equity与指标revenue之间的相关性大小为0.163214
指标du_return_on_equity与指标total_expense之间的相关性大小为0.135412
指标ev与指标earnings_per_share之间的相关性大小为0.196033
指标ev与指标revenue之间的相关性大小为0.224363
指标ev与指标total_expense之间的相关性大小为0.149857
指标earnings_per_share与指标revenue之间的相关性大小为0.141473
指标earnings_per_share与指标total_expense之间的相关性大小为0.105022
指标revenue与指标total_expense之间的相关性大小为0.995845
从中我们得出
- 指标revenue与指标total_expense之间的相关性大小为0.995845
- 指标return_on_asset_net_profit与指标du_return_on_equity之间的相关性大小为0.818697
import matplotlib.pyplot as plt
plt.figure(figsize=(20, 8), dpi=100)
plt.scatter(data['revenue'], data['total_expense'])
plt.show()
文章图片
这两对指标之间的相关性较大,可以做之后的处理,比如合成这两个指标。
2.6 主成分分析 学习目标
- 目标
- 应用PCA实现特征的降维
- 应用
- 用户与物品类别之间主成分分析
- 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
- 作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
- 应用:回归分析或者聚类分析当中
对于信息一词,在决策树中会进行介绍那么更好的理解这个过程呢?我们来看一张图
1 计算案例理解(了解,无需记忆)
假设对于给定5个点,数据如下
(-1,-2)
(-1, 0)
( 0, 0)
( 2, 1)
( 0, 1)
文章图片
要求:将这个二维的数据简化成一维? 并且损失少量的信息
文章图片
这个过程如何计算的呢?找到一个合适的直线,通过一个矩阵运算得出主成分分析的结果(不需要理解)
文章图片
2 API
- sklearn.decomposition.PCA(n_components=None)
- 将数据分解为较低维数空间
- n_components:
- 小数:表示保留百分之多少的信息
- 整数:减少到多少特征
- PCA.fit_transform(X) X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后指定维度的array
先拿个简单的数据计算一下
[[2,8,4,5],
[6,3,0,8],
[5,4,9,1]]
from sklearn.decomposition import PCAdef pca_demo():
"""
对数据进行PCA降维
:return: None
"""
data = https://www.it610.com/article/[[2,8,4,5], [6,3,0,8], [5,4,9,1]]# 1、实例化PCA, 小数——保留多少信息
transfer = PCA(n_components=0.9)
# 2、调用fit_transform
data1 = transfer.fit_transform(data)print("保留90%的信息,降维结果为:\n", data1)# 1、实例化PCA, 整数——指定降维到的维数
transfer2 = PCA(n_components=3)
# 2、调用fit_transform
data2 = transfer2.fit_transform(data)
print("降维到3维的结果:\n", data2)return None
返回结果:
保留90%的信息,降维结果为:
[[ -3.13587302e-163.82970843e+00]
[ -5.74456265e+00-1.91485422e+00]
[5.74456265e+00-1.91485422e+00]]
降维到3维的结果:
[[ -3.13587302e-163.82970843e+004.59544715e-16]
[ -5.74456265e+00-1.91485422e+004.59544715e-16]
[5.74456265e+00-1.91485422e+004.59544715e-16]]
2.6.2 案例:探究用户对物品类别的喜好细分降维
数据如下:
- order_products__prior.csv:订单与商品信息
- 字段:order_id, product_id, add_to_cart_order, reordered
- products.csv:商品信息
- 字段:product_id, product_name, aisle_id, department_id
- orders.csv:用户的订单信息
- 字段:order_id,user_id,eval_set,order_number,….
- aisles.csv:商品所属具体物品类别
- 字段: aisle_id, aisle
文章图片
文章图片
2 分析
- 合并表,使得user_id与aisle在一张表当中
- 进行交叉表变换
- 进行降维
import pandas as pd
from sklearn.decomposition import PCA# 1、获取数据集
# ·商品信息- products.csv:
# Fields:product_id, product_name, aisle_id, department_id
# ·订单与商品信息- order_products__prior.csv:
# Fields:order_id, product_id, add_to_cart_order, reordered
# ·用户的订单信息- orders.csv:
# Fields:order_id, user_id,eval_set, order_number,order_dow, order_hour_of_day, days_since_prior_order
# ·商品所属具体物品类别- aisles.csv:
# Fields:aisle_id, aisle
products = pd.read_csv("./instacart/products.csv")
order_products = pd.read_csv("./instacart/order_products__prior.csv")
orders = pd.read_csv("./instacart/orders.csv")
aisles = pd.read_csv("./instacart/aisles.csv")# 2、合并表,将user_id和aisle放在一张表上
# 1)合并orders和order_products on=order_id tab1:order_id, product_id, user_id
tab1 = pd.merge(orders, order_products, on=["order_id", "order_id"])
# 2)合并tab1和products on=product_id tab2:aisle_id
tab2 = pd.merge(tab1, products, on=["product_id", "product_id"])
# 3)合并tab2和aisles on=aisle_id tab3:user_id, aisle
tab3 = pd.merge(tab2, aisles, on=["aisle_id", "aisle_id"])# 3、交叉表处理,把user_id和aisle进行分组
table = pd.crosstab(tab3["user_id"], tab3["aisle"])# 4、主成分分析的方法进行降维
# 1)实例化一个转换器类PCA
transfer = PCA(n_components=0.95)
# 2)fit_transform
data = https://www.it610.com/article/transfer.fit_transform(table)data.shape
返回结果:
(206209, 44)
总结
文章图片
每日作业 1、数据集的结构是什么?
答案: 特征值+ 目标值
2、机器学习算法分成哪些类别? 如何分类
答案: 根据是否有目标值分为 监督学习和非监督学习监督学习
根据目标值的数据类型:目标值为离散值就是分类问题
? 目标值为连续值就是回归问题
3、什么是标准化? 和归一化相比有什么优点?
答案: 标准化是通过对原始数据进行变换把数据变换到均值为0,方差为1范围内
? 优点: 少量异常点, 不影响平均值和方差, 对转换影响小
推荐阅读
- 机器学习|机器学习基础教程笔记---机器学习概述
- python|python数据结构-链表
- python|python 排序算法
- python|python 第7讲 面向对象
- 数据采集|python数据采集概述
- Python Scrapy 学习笔记
- 移动开发|想学编程语言,Python、JavaScript、Swift、Java如何选()
- Python会消亡吗()
- opencv|dlib和opencv编程——人脸识别数据集的建立