前言
课程代码和数据文件:
一、机器学习概述
1.1.人工智能概述
- 机器学习和人工智能,深度学习的关系
- 机器学习是人工智能的一个实现途径
- 深度学习是机器学习的一个方法发展而来
- 达特茅斯会议-人工智能的起点
- 1956年8月,在美国汉诺斯小镇宁静的达特茅斯学院中约翰·麦卡锡(John McCarthy)、马文·闵斯基(Marvin Minsky,人工智能与认知学专家)、克劳德·香农(Claude Shannon,信息论的创始人)、艾伦·纽厄尔(Allen Newell,计算机科学家)、赫伯特·西蒙(Herbert Simon,诺贝尔经济学奖得主)等科学家正聚在一起讨论着一个完全不食人间烟火的主题:用机器来模仿人类学习以及其他方面的智能。会议足足开了两个月的时间,虽然大家没有达成普遍的共识,但是却为会议讨论的内容起了一个名字:人工智能。
- 机器学习、深度学习可以做些什么
- 机器学习的应用场景非常多,可以说渗透到了各个行业领域当中。医疗、航空、教育、物流、电商等等领域的各种场景。
- 机器学习领域主要包括三个方面:自然语言处理、图像识别、传统预测。
- 用在挖掘、预测领域,应用场景:店铺销量预测、量化投资、广告推荐、企业客户分类、SQL语。句安全检测分类等等
- 用在图像领域,应用场景:街道交通标志检测、人脸识别等等
- 用在自然语言处理领域,应用场景:文本分类、情感分析、自动聊天、文本检测等等
1.2.什么是机器学习
- 定义:机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测
- 数据集构成
- 结构:特征值+目标值
- 有些数据集可以没有目标值
1.3.机器学习算法分类
- 监督学习:输入数据是由输入特征值和目标值所组成。函数的输出可以是一个连续的值(称为回归),或是输出是有限个离散值(称作分类)
- 分类问题
- 特征值:猫/狗的图片;
- 目标值:猫/狗的类别;
- 分类算法:k-近邻算法、贝叶斯分类、决策树、随机森林、逻辑回归;
- 回归问题
- 特征值:房屋的各个属性信息;
- 目标值:房屋的价格-连续性数据;
- 回归算法:线性回归、岭回归;
- 分类问题
- 无监督学习:输入数据是由输入特征值所组成。
- 特征值:人物的各个属性信息;
- 目标值:无
- 聚类算法:k-means
1.4.机器学习开发流程
1、原始数据
=>
2、数据特征工程(训练数据和测试数据)
=>
3、算法进行学习
=>
4、模型
=>
5、模型评估(测试数据)
=>
6、模型选择
=>
7、判断模型是否合格
=>
8、模型应用
如果模型不合格,重复进行 3 - 7 阶段,知道模型符合要求。
二、特征工程
2.1.数据集
2.1.1.可用数据集
- scikit-learn:Find Open Datasets and Machine Learning Projects | Kaggle
- 数据量较小
- 方便学习
- UCI:UCI Machine Learning Repository
- 收录了300+个数据集
- 覆盖科学、生活、经济等领域
- 数据量几十万
- Kaggle:scikit-learn: machine learning in Python — scikit-learn 1.6.1 documentation
- 大数据竞赛平台
- 80万科学家
- 真实数据
- 数据量巨大
2.1.2.Scikit-learn工具
1、介绍
- Python语言的机器学习工具;
- Scikit-learn包括许多知名的机器学习算法的实现:分类、回归、聚类、降维、模型选择、特征工程;
- 文档完善,容易上手,丰富的API;
2、安装
pip install scikit-learn
3、Scikit-learn数据集API介绍
- sklearn.datasets
- 加载获取流行数据集
- datasets.load_*()
- 获取小规模数据集,数据包含在datasets
- datasets.fetch_*(data_home=None)
- 获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是~/scikit_learn_data/
4、数据集的使用
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)
5、数据集的划分
- 机器学习一般的数据集会划分为两个部分
- 训练数据:用于训练,构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效
- 划分比例
- 训练集:70%80%75%
- 测试集:30%20%25%
- 数据集划分api
- sklearn.model_selecion.train_test_split(arrays, *options)
- x 数据集的特征值
- y 数据集的标签值
- test _size 测试集的大小,一般为float
- random_state 随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
- return 训练集特征值,测试集特征值,训练集目标值,测试集目标值
- sklearn.model_selecion.train_test_split(arrays, *options)
from sklearn.model_selection import train_test_split
# 训练集的特征值:x_train, 测试集的特征值:x_test, 训练集的目标值:y_train, 测试集的目标值:y_test, test_size:随机数种子
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
2.2.特征工程
1、为什么需要特征工程
业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。
2、什么是特征工程
特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
2.3.特征抽取
2.3.1.什么是特征抽取
将任意数据(如文本或图像)转换为可用于机器学习的数字特征
注:特征值化是为了计算机更好的去理解数据
- 字典特征提取(特征离散化)
- 文本特征提取
- 图像特征提取(会在深度学习中涉及到)
2.3.2.特征提取API
sklearn.feature_extraction
2.3.3.字典特征提取
1、作用:对字典数据进行特征值化
- sklearn.feature_extraction.DictWectorizer(sparse=True,...)
- DictVectorizer.fit_transform(X)
- X:字典或者包含字典的迭代器
- 返回值:返回sparse矩阵
- DictVectorizer.inverse_transform(X)
- X:array数组或者sparse矩阵
- 返回值:转换之前数据格式
- DictVectorizer.get _feature_names()
- 返回类别名称
- DictVectorizer.fit_transform(X)
2、Demo
这里有一个独热(one-hot)编码的概念:机器学习:数据预处理之独热编码(One-Hot)详解-优快云博客
from sklearn.feature_extraction import DictVectorizer
def dict_demo():
"""
字典特征抽取
:return:
"""
data = [{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
# 1、实例化一个转换器类
transfer = DictVectorizer(sparse=True)
# 2、调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray(), type(data_new))
print("特征名字:\n", transfer.get_feature_names())
return None
2.3.4.文本特征提取
1、作用:对文本数据进行特征值化
- sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
- stop_words:停用词表,把不需要的词语去掉
- 返回词频矩阵
- CountVectorizer.fit_transform(X)
- X:文本或者包含文本字符串的可迭代对象
- 返回值:返回sparse矩阵
- CountVectorizer.inverse_transform(X)
- X:array数组或者sparse矩阵
- 返回值:转换之前数据格
- CountVectorizer.get_feature_names()
- 返回值:单词列表
- sklearn.feature extraction.text.TfidfVectorizer
- Tf-idf 文本特征提取
- TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类
- TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度;
- 公式:
- 词频(term frequency,tf)指的是某一个给定的词语在该文件中出现的频率
- 逆向文档频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的 idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
- tfidf = tf x idf
- 例子:语料库-1000篇文章,其中100篇文章中有“非常”这个词,现在有一篇文章,她有100个词,“非常”这个词出现了10次,那它的 tf = 10/100 = 0.1, idf = lg 1000/100 = 1,tfidf = 0.1 x 1 = 0.1
- Tf-idf 文本特征提取
2、Demo1:文本特征抽取
from sklearn.feature_extraction.text import CountVectorizer
def count_demo():
"""
文本特征抽取:CountVecotrizer
:return:
"""
data = ["life is short,i like like python", "life is too long,i dislike python"]
# 1、实例化一个转换器类
transfer = CountVectorizer(stop_words=["is", "too"])
# 2、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
3、Demo2:中文文本抽取
from sklearn.feature_extraction.text import CountVectorizer
def count_chinese_demo():
"""
中文文本特征抽取,自动分词
:return:
"""
# 将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
# 1、实例化一个转换器类
transfer = CountVectorizer(stop_words=["一种", "所以"])
# 2、调用fit_transform
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
def cut_word(text):
"""
进行中文分词:"我爱北京天安门" --> "我 爱 北京 天安门"
:param text:
:return:
"""
return " ".join(list(jieba.cut(text)))
4、Demo3:用TF-IDF的方法进行文本特征抽取
from sklearn.feature_extraction.text import TfidfVectorizer
def tfidf_demo():
"""
用TF-IDF的方法进行文本特征抽取
:return:
"""
# 将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# print(data_new)
# 1、实例化一个转换器类
transfer = TfidfVectorizer(stop_words=["一种", "所以"])
# 2、调用fit_transform
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征名字:\n", transfer.get_feature_names())
return None
def cut_word(text):
"""
进行中文分词:"我爱北京天安门" --> "我 爱 北京 天安门"
:param text:
:return:
"""
return " ".join(list(jieba.cut(text)))
2.4.特征预处理
2.4.1.什么是特征预处理
通过一些转换函数将特征数据转换成更加适合算法模型的特征数据的过程。
2.4.2.特征预处理的方法
- 归一化
- 标准化
2.4.3.特征预处理的API
sklearn.preprocessing
2.4.4.为什么要进行归一化/标准化?
特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其它的特征。
2.4.5.归一化
1、定义
通过对原始数据进行变换把数据映射到(默认为[0,1])之间
2、公式
作用于每一列,max为一列的最大值,min为一列的最小值,X''为最终结果,mx,mi分别为指定区间,默认mx为1,mi为0
3、例子
对60进行归一化,X' = (60 - 60) / (90 - 60) = 0;X'' = 0 * (1 - 0) + 0 = 0
对3进行归一化,X' = (3 - 2) / (4 - 2) = 0.5;X'' = 0.5 * (1 - 0) + 0 = 0.5
4、API
- sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)...)
- MinMaxScalar.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
- MinMaxScalar.fit_transform(X)
5、Demo
如果报错的话,将[2, 3]改为(2, 3)
sklearn.utils._param_validation.InvalidParameterError: The 'feature_range' parameter of MinMaxScaler must be an instance of 'tuple'. Got [2, 3] instead.
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
def minmax_demo():
"""
归一化
:return:
"""
# 1、获取数据
data = pd.read_csv("datingg.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2、实例化一个转换器类
transfer = MinMaxScaler(feature_range=[2, 3])
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
6、总结
最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响所以这种方法鲁棒性较差,只适合传统精确小数据场景。
2.4.6.标准化
1、定义
通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
2、公式
作用于每一列,mean为平均值,ó为标准差
3、API
- sklearn.preprocessing.StandardScaler()
- 处理之后,对每列来说,所有数据都聚集在均值为0附近,标准差为1
- StandardScaler.fit_transform(X)
- "X:numpy array格式的数据[n_samples,n_features]
- 返回值:转换后的形状相同的array
5、Demo
from sklearn.preprocessing import StandardScaler
def stand_demo():
"""
标准化
:return:
"""
# 1、获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, :3]
print("data:\n", data)
# 2、实例化一个转换器类
transfer = StandardScaler()
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
6、总结
在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
2.5.特征降维
2.5.1.什么是特征降维
降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程。
正是因为在进行训练的时候,我们都是使用特征进行学习。如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测会影响较大。
2.5.2.降维的两种方式
- 特征选择
- 主成分分析(可以理解为一种特征提取的方式)
2.5.3.特征选择
1、定义
数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。
2、方法
- Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
- 方差选择法:低方差特征过滤
- 相关系数
- Embedded(嵌入式):算法自动选择特征(特征与目标值之间的关联)
- 决策树:信息熵、信息增益
- 正则化:L1、L2
- 深度学习:卷积等
3、模块
sklearn.feature_selection
2.5.3.1.特征选择 - 过滤式
2.5.3.1.1.低方差特征过滤
1、低方差特征过滤
删除低方差的一些特征,前面讲过方差的意义。再结合方差的大小来考虑这个方式的角度。
- 特征方差小:某个特征大多样本的值比较相近
- 特征方差大:某个特征很多样本的值都有差别
2、API
- sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
- 删除所有低方差特征
- Variance.fit_transform(X)
- X:numpy array格式的数据[n_samples,n_features]
- 返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。
3、案例
我们对某些股票的指标特征之间进行一个筛选,数据在“factor_returns.csv”文件当中,除去'index,'date',return'列不考虑(这些类型不匹配,也不是所需要指标)
from sklearn.feature_selection import VarianceThreshold
import pandas as pd
def variance_demo():
"""
过滤低方差特征
:return:
"""
# 1、获取数据
data = pd.read_csv("factor_returns.csv")
data = data.iloc[:, 1:-2]
print("data:\n", data)
# 2、实例化一个转换器类
transfer = VarianceThreshold(threshold=10)
# 3、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new, data_new.shape)
return None
2.5.3.1.2.相关系数
1、相关系数
- 皮尔逊相关系数(Pearson Correlation Coefficient)
- 反应变量之间相关关系密切程度的统计指标
2、公式
3、计算案例
比如说计算广告费和月平均销售额的相关性
那么之间的相关系数怎么计算
最终计算
所以我们最终得出结论是广告投入费与月平均销售额之间有高度的正相关关系。
4、特点
相关系数的值介于 -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为高度线性相关
5、API
- from scipy.stats import pearsonr
- x:(N,) array_like
- y:(N,) array_like Returns:(Pearson's correlation coefficient, pvalue)
6、案例:股票的财务指标相关性计算
from scipy.stats import pearsonr
def pearsonr_demo():
"""
相关系数
:return:
"""
# 1、获取数据
data = pd.read_csv("factor_returns.csv")
data = data.iloc[:, 1:-2]
print("data:\n", data)
# 2、计算某两个变量之间的相关系数
r1 = pearsonr(data["pe_ratio"], data["pb_ratio"])
print("相关系数:\n", r1)
r2 = pearsonr(data['revenue'], data['total_expense'])
print("revenue与total_expense之间的相关性:\n", r2)
return None
2.5.4.主成分分析
1、什么是主成分分析(PCA)
- 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
- 作用:使数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
- 应用:回归分析或者聚类分析当中
例子:
将下面二维平面上的5个点,降维到一维向量上
2、API
- sklearn.decomposition.PCA(n_components=None)
- 将数据分解为较低维数空间
- n_components:
- 小数:表示保留百分之多少的信息
- 整数:减少到多少特征
- PCA.fit_transform(X)
- X:numpy array格式的数据[n_samples,n features]
- 返回值:转换后指定维度的array
3、Demo
def pca_demo():
"""
PCA降维
:return:
"""
data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]
# 1、实例化一个转换器类
transfer = PCA(n_components=0.95)
# 2、调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
4、案例
Instacart市场菜篮子分析
Instacart消费者将购买哪些产品?
参考:day01_instacart_pca.ipynb