文章目录
一、人工智能概述
- 达特茅斯会议-人工智能的起点
- 机器学习和人工智能,深度学习的关系
- 机器学习是人工智能的一个实现途径
- 深度学习是机器学习的一个方法发展而来
- 机器学习、深度学习能做些什么
- 传统预测
- 应用场景:店铺销量预测、量化投资、广告推荐、企业客户分类、SQL语句安全检测分类
- 图像识别
- 应用场景:街道交通标志检测、人脸识别等等
- 自然语言处理
- 文本分类、情感分析、自动聊天、文本检测等
- 传统预测
- 人工智能课程
- 机器学习
- 特征工程
- 分类算法
- 回归、聚类算法
- 深度学习
- TensorFlow框架
- 卷积神经网络
- 验证码识别
- 量化交易
- 回测平台
- 因子处理
- 因子分析
- 选股策略
- 机器学习
二、机器学习概述
2.1、什么是机器学习
- 定义:机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测
- 解释:我们人类从大量的日常经验中归纳规律,当面临新的问题的时候,就可以利用以往总结的规律去分析现实状况,采取最佳策略
2.2、数据集的构成
- 结构:特征值 + 目标值
- 注:每一行数据称之为样本
- 有些数据集可以没有目标值
2.3、机器学习算法分类
- 监督学习
- 定义:输入数据是由输入特征值和目标值组成。函数的输出可以是一个连续的值(回归),或是输出是有限个离散值(分类)。输入数据有特征、有标签,即有标准答案
- 分类问题
- 目标值:类别
- 分类问题算法:k-近邻算法、贝叶斯分类、决策树与随机森林、逻辑回归
- 回归问题
- 目标值:连续型的数据
- 回归问题算法:线性回归、岭回归
- 无监督学习
- 定义:输入数据是由输入特征值所组成。输入数据有特征、无标签,即无标准答案
- 无目标值
- 算法:聚类 k-means
2.4、机器学习开发流程
- 获取数据
- 数据处理
- 特征工程
- 机器学习算法进行训练 - 得到模型
- 模型评估 - 判断模型是否合格 ,不合格重新进行2
- 应用
2.5、学习框架和资料
-
定位
-
算法是核心,数据与计算是基础
-
找准定位
-
-
大部分复杂模型的算法设计都是算法工程师再做,我们
- 分析很多的数据
- 分析具体的业务
- 应用常见的算法
- 特征工程、调参数、优化
-
怎么做
- 入门
- 机器学习库与框架
- 传统机器学习算法
- learn
- 深度学习框架
- Pytorch
- T
- theano
- Caffe2
- Chainer
- 传统机器学习算法
- 实战类书籍
- 提升书籍
- 机器学习 - 周志华 ”西瓜书“
- 统计学习 - 李航
- 深度学习 - ”花书“
三、特征工程
3.1、数据集
- 目标:知道数据集的分为训练集和测试集
- 会使用sklearn的数据集
3.1.1、可用数据集
-
企业内部数据、数据接口
-
学习阶段可用的数据集
-
sklearn
https://scikit-learn.org/stable/datasets
-
kaggle
https://www.kaggle.com/datasets
-
UCI
http://archive.ics.uci.edu/
-
3.1.2、Scikit-learn工具
-
工具简介
-
Python语言的机器学习工具
-
Scikit-learn工具包括许多知名的机器学习算法的实现
-
Scikit-learn文档完善,容易上手,丰富的API
-
-
安装
-
pip install sklearn
-
-
Scikit-learn包含的内容
- 分类、回归、聚类、降维、模型选择、特征工程
3.1.2、sklearn数据集
-
sklearn数据集API介绍
-
sklearn.datasets
-
加载获取流行数据集
-
datasets.load_*()
- 获取小规模数据集
- 例如:sklearn.datasets.load_iris()
-
datasets.fetch_*(data_home=None)
-
获取大规模数据集
-
例如
sklearn.datasets.fetch_20newsgroups(data_home=None, subset='train')
- subset:train训练集、test测试集、all全部
-
-
数据集的返回值
- datasets.base.Bunch(继承自字典)
- data:特征数据数组
- target:标签数组
- DESCR:数据描述
- feature_names:特证名
- target_names:标签名
- 取值方式
- bunch.key
- bunch[‘key’]
- datasets.base.Bunch(继承自字典)
-
-
-
数据集的使用
-
加载鸢尾花数据集
from sklearn.datasets import load_iris def datasets_demo(): """ sklearn数据集使用 :return: """ # 获取数据集 iris = load_iris() print("数据集key列表:\n", str(iris.keys())) print("数据集描述:\n", iris['DESCR']) print("特征值的名字:\n", iris.feature_names) print("特征值:\n", iris.data, iris.data.shape) return None if __name__ == '__main__': datasets_demo()
-
-
数据集的划分
-
机器学习一般的数据集会划分两个部分
- 训练数据:用于训练,构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效
- 测试集占比:20%~30%
-
数据集划分api
-
sklearn.model_selection.train_test_split(arrays, *options)
- x数据集的特征值
- y数据集的标签值
- test_size测试集大小,一般为float
- random_state 随机数种子,不同的终止会造成不同的随机采样结果,相同的种子采样结果相同
- return 训练集特征值 x_train、测试机特征值 x_test、训练集目标值 y_train、测试集目标值 y_test
from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2) print("训练集的特征值:", x_train, x_train.shape)
-
-
3.2、特征工程介绍
- 目标
- 了解特征工程在机器学习当中的重要性
- 知道特征工程的分类
3.2.1、为什么需要特征工程(Feature Engineering)
- 数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
3.2.2、什么是特征工程
- 特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
- 意义:会直接影响机器学习的效果
3.2.3、特征工程的位置与数据处理的比较
- pandas和sklearn比较
- pandas:一个数据读取非常方便以及基本的处理格式的工具
- sklearn:对于特征的处理提供了强大的接口
3.2.4、特征工程内容
- 特征抽取
- 特征预处理
- 特征降维
3.3、特征抽取
3.3.1、什么是特征抽取(特征提取)
- 引入
- 机器学习算法:统计方法:数学公式
- 文本类型 -> 数值
- 类型 -> 数值
- 概念:将任意数据(文本或图像)转换为可用于机器学习的数字特征。特征值化是为了让计算机更好的去理解数据
- 字典特征提取(特征离散化)
- 文本特征提取
- 图像特征提取(深度学习算法)
3.3.2、特征提取API
sklearn.featrue_extraction
3.3.2.1、字典特征提取
-
作用:对字典数据进行特征值化
-
sklearn.featrue_extraction.DictVectorizer(sparse=True,…)
- vector 向量、矢量
- 矩阵 matrix 二维数组
- 向量 vector 一维数组
- DictVectorizer.fit_transform(X) :X 字典或者包含字典的迭代器,返回值:返回sparse矩阵
- sparse 稀疏矩阵
- sparse=True 时返回稀疏矩阵
- 将非零值 按位置表示出来
- 节省内存 ,提高加载效率
- sparse 稀疏矩阵
- DictVectorizer.inverse_transform(X):X array数组或者sparse矩阵,返回值 :转换之前数据格式
- DictVectorizer.get_feature_names_out() 返回类别名称
- vector 向量、矢量
-
def dict_demo(): """ 字典特征抽取 :return: """ data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}] # 实例化一个转换器类 transfer = DictVectorizer(sparse=True) # 调用fit_transform(data) data_new = transfer.fit_transform(data) print(data_new) print("特征名称\n", transfer.get_feature_names_out()) return None
-
应用场景:
- 数据集当中类别特征比较多,将数据集的特征转换成字典类型,再进行特征值化
- 本身拿到的数据就是字典类型
3.3.2.2、文本特征提取-CountVectorizer
-
作用:对文本数据进行特征值化
-
单词作为特征
- 特征:特征词
-
sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
-
统计样本特征词出现次数
-
返回词频矩阵
-
CountVectorizer.fit_transform(X)
-
X:文本或者包含文本字符串的可迭代对象,
-
返回sparse矩阵
-
-
CountVectorizer.inverse_transform(X):
-
X array数组或者sparse矩阵
-
返回值 :转换之前数据格式
-
-
CountVectorizer.get_feature_names_out()
- 返回单词列表
-
stop_words 停用词 网上查停用词表
-
def count_demo_cn(): """ 中文文本特征抽取 CountVectorizer :return: """ data = ["我 爱 北京 天安门", "天安门 上 太阳 升"] # 实例化转换器 transfer = CountVectorizer() # 调用 data_new = transfer.fit_transform(data) print(transfer.get_feature_names_out()) print(data_new.toarray()) return None
-
-
中文分词
- jieba分词库
def count_chinese_demo(): """ 中文文本特征抽取,自动分词 :return: """ data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] data_new = [] for sent in data: data_new.append(cut_word(sent)) # # 实例化转换器 transfer = CountVectorizer(stop_words=["一种"]) # 调用 data_final = transfer.fit_transform(data_new) print(transfer.get_feature_names_out()) print(data_final.toarray()) # import jieba def cut_word(text): """ 中文分词 :param text: :return: """ return " ".join(list(jieba.cut(text)))
3.3.2.3、TF-IDF文本特征提取
-
关键词:在某一个类别的文章中,出现的次数很多,但是在其他类别的文章中出现很少
-
Tf-idf文本特征提取
-
主要思想:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很号的类别区分能力,适合用来分类
-
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度
-
-
公式
- 词频(term frequency,tf)指的是在某一个给定的词语在该文件中出现的频率
- 逆向文档频率(inverse document frequency ,idf)时一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语的文件数目,再将得到的商取以10为底的对数得到
- tfidf = tf * idf
-
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_out()
- 返回单词列表
-
def tfidf_demo(): """ 使用tfidf进行文本特征抽取 :return: """ data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] data_new = [] for sent in data: data_new.append(cut_word(sent)) # # 实例化转换器 transfer = TfidfVectorizer(stop_words=["一种"]) # 调用 data_final = transfer.fit_transform(data_new) print(transfer.get_feature_names_out()) print(data_final.toarray())
-
-
3.4、特征预处理
3.4.1、什么是特征与预处理
-
定义:通过一些转换函数将特征数据转换成更加适合算法模型的特征数据的过程
-
无量纲化
- 归一化
- 标准化
-
特征处理API
sklearn.preprocessing
-
为什那么要进行归一化/标准化
- 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其他的特征
3.4.2、归一化
- 定义
- 通过对原始数据进行变换把数据映射到(默认0-1)之间
- 公式
x ′ = x − m i n m a x − m i n , x ′ ′ = x ′ ∗ ( m x − m i ) + m i x' = \frac{x-min}{max-min} ,x''=x' * (mx-mi) + mi x′=max−minx−min,x′′=x′∗(mx−mi)+mi
-
sklearn.preprocessing.MinMaxScaler(feature_range(0,1)…)
-
MinMaxScalar.fit_transform(X)
- X:numpy array格式的数据
-
def minmax_demo(): """ 归一化 :return: """ # 获取数据 data = pd.read_csv("dating.txt") data = data.iloc[:, :3] # 实例化一个转换器类 transfer = MinMaxScaler(feature_range=[0, 1]) # 调用fit_transform() data_new = transfer.fit_transform(data) print(data_new)
-
-
注意最大值、最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景。
3.4.3、标准化
-
定义:通过对原始数据进行变换,把数据变换到均值为0,标准差为1范围内
-
公式
x ′ = x − m e a n σ , m e a n 是平均值, σ 是标准差 x' = \frac{x - mean}{σ},mean是平均值,σ是标准差 x′=σx−mean,mean是平均值,σ是标准差 -
对于标准化来说如果出现异常点,由于具有一定数量,少量的异常点对于平均值影响并不大,从而方差改变较小
-
sklearn.preprocessing.StandardScaler()
- 处理之后,对每列来说,所有数据都聚集在均值为0附近,标准差为1
- StandardScaler.fit_transform(X)
- X:numpy array格式的数据
- 返回值:相同形状的array
-
应用场景:在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据环境
3.5、特征降维
3.5.1、降维
- 降维是指在某些特定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
- 相关特征(correlated feature)
- 相对湿度与降雨量之间的相关等等
- 因为在进行训练的时候,我们使用特征进行学习。如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测影响较大
3.5.2、降维的两种方式
- 特征选择
- 主成分分析(可以理解一种特征提取的方式)
3.5.3、特征选择
-
定义:数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征
-
方法:
- Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
- 方差选择法:低方差特征过滤
- 相关系数:特征与特征之间的相关程度
- Embedded(嵌入式)
- 决策树:信息熵、信息增益
- 正则化:L1、L2
- 深度学习:卷积等
- Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
-
模块
sklearn.feature_selection
3.5.4、过滤式
-
低方差特征过滤
- sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
- 删除所有低方差特称
- VarianceThreshold.fit_transform(X)
- X : numpy array格式的数据
- 返回值:训练集差异低于threshold的特征将被删除。默认值式保留所有非零方差特征,即删除所有样本中具有相同值的特征。
def variance_demo(): """ 低方差特征过滤 :return: """ # 获取数据 data = pd.read_csv('factor_returns.csv') data = data.iloc[:, 1:-2] # 实例化转换器 transfer = VarianceThreshold(threshold=10) # fit_transform data_new = transfer.fit_transform(data) print(data_new.shape)
- sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
-
相关系数
-
皮尔逊相关系数
-
反应变量之间相关关系密切程度的统计指标
-
公式
r = n ∑ x y − ∑ x ∑ y n ∑ x 2 − ( ∑ x ) 2 − n ∑ y 2 − ( ∑ y ) 2 r = \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)2−n∑y2−(∑y)2n∑xy−∑x∑y -
相关系数的取值范围 [-1,1]
- 系数大于0 正相关, 小于0 为负相关
- 相关等级
- |r| < 0.4 为低度相关
- 0.4 <= |r| < 0.7 为显著相关
- 0.7 <= |r| <1 为高度线性相关
-
API
from scipy.stats import pearsonr # 计算某两个变量之间的相关系统 r = pearsonr(data['pe_ratio'], data['pb_ratio'])
-
-
特征与特征之间相关性很高时如何处理
- 选取其中一个
- 加权求和
- 主成分分析
3.5.4、主成分分析
-
定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量
-
作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息
-
应用:回归分析或者聚类分析当中
-
过程:找到一个合适的直线,通过一个矩阵运算得出主成分分析的结果
-
API
- sklearn.decomposition.PCA(n_components = None)
- 将数据分解为较低维数空间
- n_components
- 小数:表示保留百分之多少的信息
- 整数:减少到多少特征
- PCA.fit_transform(X)
- 返回值:转换后指定维度的array
def pca_demo(): """ PCA降维 :return: """ data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]] # 实例化转换器 transfer = PCA(n_components=0.95) # fit_transform data_new = transfer.fit_transform(data) print(data_new)
- sklearn.decomposition.PCA(n_components = None)
3.6、案例
-
需求:探究用户对物品类别的喜好
# 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 # 分析user_id 和 aisle的关系
-
四、分类算法
4.1、sklearn转换器和预估器
4.1.1、转换器
- 转换器类(Transformer)
- fit_transform()
- fit() :计算平均值、标准差等
- transform:计算结果带入公式
- fit_transform()
- 转换器是特征工程的父类
4.1.2、预估器
- 预估器(estimator)是sklearn机器学习算法的父类
- 预估器
- 实例化一个estimator
- estimator.fit(x_train, y_train) 计算
- 机器学习模型训练,计算完成后生成模型
- 模型评估
- 直接比对真实值和预测值
- 预估值 y_predict = estimator.predict(x_test)
- 判断 y_test == y_predict
- 计算准确率
- accuracy = estimator.score(x_test, y_test)
- 直接比对真实值和预测值
- 在sklearn中,预估器(estimator) 是一个重要的角色,是一类实现了算法的API
- 用于分类的预估器
- sklearn.neighbors :k-近邻算法
- sklearn.naive_bayes:贝叶斯
- sklearn.linear_model.LogisticRegression 逻辑回归
- sklearn.tree 决策树与随机森林
- 用于回归的预估器
- sklearn.linear_model.LinearRegression 线性回归
- sklearn.linear_model.Ridge 岭回归
- 用于无监督学习的预估器
- sklearn.cluster.KMeans 聚类
- 用于分类的预估器
4.2、K-近邻算法(KNN)
4.2.1、什么是K-近邻算法
-
K Nearest Neighbor算法又叫做KNN算法,这个算法是机器学习里一个比较经典的算法。
-
定义:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
-
距离公式
-
a,b两点为 a(a1,a2,a3),b(b1,b2,b3)
-
欧式距离
( a 1 − b 1 ) 2 + ( a 2 − b 2 ) 2 + ( a 3 − b 3 ) 2 \sqrt{(a1-b1)^2 + (a2-b2)^2 + (a3-b3)^2} (a1−b1)2+(a2−b2)2+(a3−b3)2 -
曼哈顿距离(绝对值距离)
∣ a 1 − b 1 ∣ + ∣ a 2 − b 2 ∣ + ∣ a 3 − b 3 ∣ |a1-b1| + |a2-b2| + |a3-b3| ∣a1−b1∣+∣a2−b2∣+∣a3−b3∣ -
明可夫斯基距离
-
-
K取值问题
- K值过小,容易受到异常点的影响
- K值过大,样本不均衡的影响
4.2.2、K-近邻算法API
- sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, algorithm=‘auto’)
- n_neighbors:int 可选,默认为5 ,K近邻算法的K值
- algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法;
4.2.3、案例
4.2.3.1、案例1:鸢尾花种类预测
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
def knn_iris():
"""
用KNN算法对鸢尾花进行分类
:return:
"""
# 获取数据
iris = load_iris()
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 特征工程 标准化
transfer = StandardScaler()
# 训练集
x_train = transfer.fit_transform(x_train)
# 测试集
x_test = transfer.transform(x_test)
# KNN预估器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train, y_train)
# 模型评估
y_predict = estimator.predict(x_test)
print(y_predict)
print(y_predict == y_test)
score = estimator.score(x_test, y_test)
print(score)
4.2.4、K-近邻总结
- 优点
- 简单,易于理解,易于实现,无需训练
- 缺点:
- 懒惰算法,对测试样本分类时的计算量大,内存开销大
- 必须执行K值,K值选择不当则分类精度不能保证
- 适用场景:
- 小数据场景,几千~几万样本
4.3、模型选择与调优
4.3.1、什么时交叉验证(cross validation)
- 交叉验证:将拿到的训练数据,分为训练和验证集。如分为4份,其中一份作为验证集,然后经过4组测试,每次更换不同的验证集,即得到4组模型的结果,取平均值作为最终结果。又称4折交叉验证
- 为什么进行交叉验证
- 为了让被评估的模型结果更加准确
4.3.2、超参数搜索-网格搜索
- 通常情况下,有很多参数需要手动指定的(如K近邻算法的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型
- API
- sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
- 对预估器的指定参数值进行详尽搜索
- estimator:估计器对象
- param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
- cv:指定几折交叉验证
- fit():输入训练数据
- score():准确率
- 结果分析
- 最佳参数:best_params_
- 最佳结果:best_score_
- 最佳估计器:best_estimator_
- 交叉验证结果:cv_results_
- sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
4.3.3、鸢尾花案例增加K值调优
def knn_iris_gscv():
"""
用KNN算法对鸢尾花进行分类,添加网格搜索和交叉验证
:return:
"""
# 获取数据
iris = load_iris()
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=22)
# 特征工程 标准化
transfer = StandardScaler()
# 训练集
x_train = transfer.fit_transform(x_train)
# 测试集
x_test = transfer.transform(x_test)
# KNN预估器流程
estimator = KNeighborsClassifier()
# 网格搜索与交叉验证
params = {
"n_neighbors": [1, 3, 5, 7, 9, 11]
}
estimator = GridSearchCV(estimator, param_grid=params, cv=10)
estimator.fit(x_train, y_train)
# 模型评估
y_predict = estimator.predict(x_test)
print(y_predict)
print(y_predict == y_test)
score = estimator.score(x_test, y_test)
print(score)
print("最佳参数:", estimator.best_params_)
print("最佳结果:", estimator.best_score_)
print("最佳估计器:", estimator.best_estimator_)
print("交叉验证结果:", estimator.cv_results_)
4.3.4、案例:预测facefook签到位置
4.4、朴素贝叶斯算法
4.4.1、什么是朴素贝叶斯算法
- 朴素:
- 假设特征与特征之间是相互独立的
4.4.2、概率基础
- 概率定义为一件事情发生的可能性
- P(X) : 取值在[0,1]
- 联合概率:
- 包含多个条件,且所有条件同时成立的概率
- 记作:P(A,B)
- 包含多个条件,且所有条件同时成立的概率
- 条件概率
- 就是在事件A在另一个事件B已经发生的条件下发生的概率
- 记作:P(A|B)
- 就是在事件A在另一个事件B已经发生的条件下发生的概率
- 相互独立:
- 如果P(A,B) = P(A)P(B), 则称事件A与事件B相互独立
4.4.3、贝叶斯公式
- W为给定文档的特征值(频数统计,预测文档提供),C为文档类别
P ( C ∣ W ) = P ( W ∣ C ) P ( C ) P ( W ) P(C|W) = \frac{P(W|C)P(C)}{P(W)} P(C∣W)=P(W)P(W∣C)P(C)
4.4.4、应用场景
-
文本分类
-
公式(贝叶斯公式在文章分类场景中可表示为):
P ( C ∣ F 1 , F 2 , . . . ) = P ( F 1 , F 2 , . . . ∣ C ) P ( C ) P ( F 1 , F 2 , . . . ) P(C|F1,F2,...) = \frac{P(F1,F2,...|C)P(C)}{P(F1,F2,...)} P(C∣F1,F2,...)=P(F1,F2,...)P(F1,F2,...∣C)P(C)- 公式分为三个部分:
- P©:每个文档类别的概率(某文档类别数/总文档数量)
- P(W|C):给定类别下特征(被预测文档中出现的词)的概率
- 计算方法:P(F1 | C) = Ni / N (训练文档中取计算)
- Ni为该F1词在C类别所有文档中出现的次数
- N为所属类别C下的文档所有词出现的次数和
- 计算方法:P(F1 | C) = Ni / N (训练文档中取计算)
- P(F1,F2,…):预测文档中每个词的概率
- 公式分为三个部分:
-
拉普拉斯平滑系数
-
目的:为了防止计算出的分类概率为0
-
公式
P ( F 1 ∣ C ) = N i + α N + α m P(F1|C) = \frac{Ni + α}{N + αm} P(F1∣C)=N+αmNi+α- α为指定的系数一般为1,m为训练文档中统计出的特征词个数
-
-
4.4.5、sklearn朴素贝叶斯API
- sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
- 朴素贝叶斯分类
- alpha:拉普拉斯平滑系数
4.4.6、朴素贝叶斯算法总结
- 优点:
- 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率
- 对缺失数据不太敏感,算法也比较简单,常用于文本分类
- 分类准确率高,速度快
- 缺点
- 由于使用了样本属性独立性的假设,所以如果特征属性有关联性时其效果不好
4.5、决策树
4.5.1、认识决策树
- 如何高效的进行决策
- 特征的先后顺序
4.5.2、决策树分类原理详解
-
信息论基础
-
信息
- 香农:消息是消除随机不确定性的东西
-
信息的衡量
-
信息熵
- 定义
H ( X ) = − ∑ P ( X i ) l o g b P ( X i ) H(X) = - \sum P(Xi)logbP(Xi) H(X)=−∑P(Xi)logbP(Xi)
- 定义
-
信息增益
- 特征A对训练集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A) = H(D) - H(D|A) g(D,A)=H(D)−H(D∣A)
- 特征A对训练集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
-
-
-
决策树的划分依据之一----信息增益
- 其他依据
- C4.5 信息增益比
- CART
- 分类树,基尼系数
- 其他依据
4.5.3、决策树API
- sklearn.tree.DecisionTreeClassifier(criterion=‘gini’,max_depth=None,random_state=None)
- 决策树分类器
- criterion,默认是gini系数,也可以选择信息增益的熵’entropy’
- max_depth:树的深度大小
- random_state:随机数种子
4.5.4、决策树可视化
- 保存树的结构到dot文件
- sklearn.tree.export_graphviz() 该函数能够导出DOT格式
- tree.export_graphviz(estimator, out_file=‘tree.dot’,feature_names=[‘’,‘’])
- sklearn.tree.export_graphviz() 该函数能够导出DOT格式
4.5.5、决策树总结
- 优点:
- 可视化 - 可解释能力强
- 缺点:
- 决策树学习者可以创建不能很好推广数据的过于复杂的树,这被称为过拟合
- 改进
- 剪枝cart算法
- 随机森林
4.5.6、案例:泰坦尼克号乘客生存预测
4.6、随机森林
4.6.1、什么是集成学习方法
- 集成学习通过建立几个模型组合来解决单一的预测问题,工作原理是生成多个分类器/模型,各自独立的学习和作出预测,这些预测最后结合成组合预测,因此优于任何一个单分类的预测。
4.6.2、随机森林
-
随机森林
- 随机
- 森林
- 多个决策树
-
在机器学习中,随机森林是一个包含多个决策树的分类器,并且输出的类别是由个别树输出的类别的众数而定。
4.6.3、随机森林原理
- 两个随机
- 训练集随机
- bootstrap 随机有放回抽样
- N个样本中随机有放回的抽样N个
- 特征随机
- 从M个特征中随机抽取m个特征
- M >> m
- 从M个特征中随机抽取m个特征
- 训练集随机
4.6.4、随机森林API
- sklearn.ensemble.RandomforestClassifier(n_estimators, criterion=‘gini’, max_depth=None, bootstrap=True,random_state=None, min_samples_split=2)
- 随机森林分类器
- n_estimators:森林里的数目数量
- criteria: 分割特征的测量方法
- max_depth: 树的最大深度
- max_features=“auto”,每个决策树的最大特征数量
- auto 、sqrt:sqrt(总特征)
- log2:log2(总特征)
- None: 总特征
- bootstrap:是否在构建树时使用放回抽样
- min_samples_split:节点划分最少样本数
- min_samples_leaf : 叶子节点的最小样本数
- 超参数:n_estimators、max_depth、min_samples_split、min_samples_leaf
4.6.5、随机森林总结
- 在当前所有算法中,具有极好的准确率
- 能够有效地运行在大数据集上,处理具有高维特征的输入样本,而且不需要降维
- 能够评估各个特征在分类问题上的重要性
五、回归算法
5.1、线性回归
5.1.1、线性回归的原理
5.1.1.1、定义与公式
-
线性回归(Linear regression)是利用回归方程(函数)对一个变量或者多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。
-
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
-
通用公式:
h ( W ) = w 1 x 1 + w 2 x 2 + w 3 x 3... + b = w t x + b h(W) = w1x1 + w2x2 + w3x3... + b = w^tx + b h(W)=w1x1+w2x2+w3x3...+b=wtx+b- 其中 w,x可以理解为矩阵:
w = { b w 1 w 2 } , x = { 1 x 1 x 2 } w=\left\{ \begin{matrix} b \\ w_1 \\ w_2 \end{matrix} \right\}, x= \left\{\begin{matrix} 1 \\ x_1 \\ x_2 \end{matrix}\right\} w=⎩ ⎨ ⎧bw1w2⎭ ⎬ ⎫,x=⎩ ⎨ ⎧1x1x2⎭ ⎬ ⎫
- 其中 w,x可以理解为矩阵:
5.1.1.2、广义线性模型
-
广义线性模块
-
线性关系
- 自变量一次
-
非线性关系
- 参数一次
y = w 1 x 1 + w 2 x 1 2 + w 3 x 1 3 + . . . + b y = w1x1 + w2x1^2 + w3x1^3 + ... + b y=w1x1+w2x12+w3x13+...+b
- 参数一次
-
-
线性模式不等于线性关系
- 线性关系一定是线性模型
- 线性模型不一定是线性关系
5.1.2、线性回归的损失和优化原理
5.1.2.1、回归损失
-
目标:求模型参数能使得预测准确
-
损失函数
-
又称cost、成本函数、目标函数
-
定义
J ( θ ) = ( h w ( x 1 ) − y 1 ) 2 + ( h w ( x 2 ) − y 2 ) 2 + . . . + ( h w ( x m ) − y m ) 2 = ∑ i = 1 m ( h w ( x i ) − y i ) 2 J(\theta) = (h_w(x_1) - y1)^2 + (h_w(x_2) - y2)^2 + ... + (h_w(x_m) - ym)^2 = \sum_{i=1}^{m}(h_w(x_i) -y_i)^2 J(θ)=(hw(x1)−y1)2+(hw(x2)−y2)2+...+(hw(xm)−ym)2=i=1∑m(hw(xi)−yi)2
-
5.1.2.2、优化算法
-
正规方程
-
直接求解w
-
公式
w = ( X T X ) − 1 X T y w = (X^TX)^{-1} X^Ty w=(XTX)−1XTy- X为特征值矩阵,y为目标值矩阵 。直接求到最好的结果
- 缺点:当特征值过多且复杂时,求解速度太慢并且得不到结果
- 矩阵求逆 : A * B = E(单位矩阵) ,B是A的逆矩阵
-
-
梯度下降
-
公式
$$
w1 := w1 - \alpha \frac{\delta cos t(w0 + w1x1)}{\delta w1}w0 := w0 - \alpha \frac{\delta cos t(w0 + w1x1)}{\delta w1}
$$
-
5.1.3、线性回归API
-
正规方程
- sklearn.linear_model.LinearRegression(fit_intercept=True)
- fit_intercept:是否计算偏置
- LinearRegression.coef_:回归系数
- LinearRegression.intercept_:偏置
-
梯度下降
- sklearn.linear_model.SGDRegressor(loss=“squared_loss”, fit_intercept=True, learning_rate=‘’invscaling“ , eta0 = 0.01)
- SGDRegressor类实现了随机梯度下降学习,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型
- loss:损失模型
- loss=“squared_loss” :普通最小二乘法
- fit_intercept:是否计算偏置
- learning_rate:string, optional
- 学习率填充
- ‘constant’: eta = eta0
- ‘optimal’:eta = 1.0 / (alpha * (t + t0))[default]
- ‘invscaling’ : eta = eta0 /pow(t, power_t)
- power_t = 0.25 存在父类当中
- 对于一个常数值的学习率来说,可以使用constant,并使用eta0来指定学习率
- LinearRegression.coef_:回归系数
- LinearRegression.intercept_:偏置
- sklearn.linear_model.SGDRegressor(loss=“squared_loss”, fit_intercept=True, learning_rate=‘’invscaling“ , eta0 = 0.01)
-
回归性能评估
-
均方误差评价机制
M S E = 1 m ∑ i = 1 m ( y i − y ) 2 MSE = \frac{1}{m}\sum_{i=1}^{m}(y^i - y)^2 MSE=m1i=1∑m(yi−y)2 -
sklearn.metrics.mean_squared_error(y_true, y_pred)
- 均方误差回归损失
- y_true:真实值
- y_pred:预测值
- return:浮点数结果
-
5.1.4、案例:波士顿房价预测
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error
def linear1():
"""
正规方程对波士顿房价进行预测
:return:
"""
# 1.获取数据
boston = load_boston()
# 2.划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3.标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4.预估器
estimator = LinearRegression()
estimator.fit(x_train, y_train)
# 得出模型
print("正规方程权重系数:", estimator.coef_)
print("正规方程偏置率", estimator.intercept_)
# 模型评估
y_predict = estimator.predict(x_test)
print("预测房价:", y_predict)
error = mean_squared_error(y_test, y_predict)
print("正规方程-均方误差为", error)
def linear2():
"""
梯度下降对波士顿房价进行预测
:return:
"""
# 1.获取数据
boston = load_boston()
# 2.划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3.标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4.预估器
estimator = SGDRegressor(max_iter=10000, eta0=0.01, learning_rate='constant')
estimator.fit(x_train, y_train)
# 得出模型
print("梯度下降权重系数:", estimator.coef_)
print("梯度下降偏置率", estimator.intercept_)
# 模型评估
y_predict = estimator.predict(x_test)
print("预测房价:", y_predict)
error = mean_squared_error(y_test, y_predict)
print("梯度下降-均方误差为", error)
5.1.4、线性回归总结
-
正规方程与梯度下降对比
梯度下降 正规方程 需要选择学习率 不需要 需要迭代求解 一次运算出 特征数量较大可以使用 需要计算方程,时间复杂度高O(n^3) - 选择
- 小规模数据
- 正规方程(不能解决拟合问题)
- 大规模数据
- 梯度下降
- 小规模数据
- 选择
-
梯度下降优化方法
- GD
- 原始梯度下降,计算量大
- SGD
- 随机梯度下降
- SAG
- 随机平均梯度
- GD
5.2、欠拟合与过拟合
5.2.1、什么是过拟合与欠拟合
- 过拟合
- 一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据集上却不能很好的拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
- 欠拟合
- 一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好的拟合数据,此时认为这个假设出现了欠拟合现象(模型过于简单)
5.2.1、原因以及解决办法
-
欠拟合原因以及解决办法
- 原因:学习到数据的特征过少
- 解决办法:增加数据的特征数量
-
过拟合原因以及解决办法
- 原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试取兼顾各个测试数据点
- 解决办法:
- 回归:正则化
- 分类等:特征选择
-
正则化
-
L2正则化(Ridge)
-
作用:可以使得其中一些W的值都很小,都接近于0,削弱某个特征的影响
-
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
-
加入L2正则化后的损失函数
J ( w ) = 1 2 m ∑ i = 1 m ( h w ( x i ) − y i ) 2 + λ ∑ j = 1 n w j 2 J(w) = \frac{1}{2m} \sum_{i=1}^{m}(h_w(xi) - y_i)^2 + λ \sum_{j=1}{n}w_j^2 J(w)=2m1i=1∑m(hw(xi)−yi)2+λj=1∑nwj2
-
-
L1正则化(LASSO)
- 作用:可以使得其中一些W的值直接为0,删除这个特征的影响
-
5.3、岭回归
5.3.1、岭回归
- 岭回归,其实也是一种线性回归。只不过在算法建立回归方程的时候,加上正则化的限制,从而达到解决过拟合的效果
5.3.2、API
- sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True, solver=‘auto’, normalize=False)
- alpha: 正则化力度,也叫λ
- 取值 0~1 1~10
- solver:会根据数据自动选择优化方法
- sag:如果数据集、特征都比较大,选择该随机梯度下降优化
- normalize: 数据是否进行标准化
- 相当于 preprocessing.StandardScaler标准化数据
- Ridge.coef_:回归权重
- Ridge.intercept_: 回归偏置
- alpha: 正则化力度,也叫λ
5.4、分类算法-逻辑回归
5.4.1、逻辑回归的应用场景
- 逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法。
- 应用场景
- 广告点击率
- 是否为垃圾邮件
- 是否患病
- 金融诈骗
- 虚假账号
- 逻辑回归就是解决二分类问题的利器
5.4.2、逻辑回归的原理
-
输入:逻辑回归的输入就是一个线性回归的结果
h ( w ) = w 1 x 1 + w 2 x 2 + . . . + b h(w) = w_1x_1 + w_2x_2 + ... + b h(w)=w1x1+w2x2+...+b -
激活函数
-
sigmoid函数
g ( θ T x ) = 1 1 + e − θ T x g(\theta^Tx) = \frac{1}{1+e^{-\theta^Tx}} g(θTx)=1+e−θTx1 -
分析
- 回归结果输入到sigmoid函数当中
- 输出结果:[0,1]区间中的一个概率值,默认为0.5为阈值
-
-
对数似然损失
c o s t ( h θ , y ) = { − l o g ( 1 − h θ ( x ) ) , y = 0 − l o g ( h θ ( x ) ) , y = 1 cost(h_{\theta},y) = \{^{-log(h_\theta(x)), y=1}_{-log(1-h_\theta(x)),y=0} cost(hθ,y)={−log(1−hθ(x)),y=0−log(hθ(x)),y=1c o s t ( h θ ( x ) , y ) = ∑ i = 1 m − y i l o g ( h θ ( x ) ) − ( 1 − y i ) l o g ( 1 − h θ ( x ) ) cost(h_\theta(x),y) = \sum_{i=1}^{m}-y_ilog(h_\theta(x)) - (1-y_i)log(1-h_\theta(x)) cost(hθ(x),y)=i=1∑m−yilog(hθ(x))−(1−yi)log(1−hθ(x))
5.4.3、逻辑回归API
- sklearn.linear_model.LogosticRegression(solver=‘liblinear’, penalty=‘l2’, C = 1.0)
- solver:优化求解方式
- penalty:正则化种类
- C:正则化力度
- SGDClassifier 也可用于逻辑,未实现SAG
5.4.4、案例:癌症分类预测
#%%
import pandas as pd
import numpy as np
#%%
# 1、读取数据
path = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape',
'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin',
'Normal Nucleoli', 'Mitoses', 'Class']
data = pd.read_csv(path, names=column_name)
#%%
data
#%%
# 缺失值处理
data = data.replace(to_replace='?', value=np.nan)
#%%
data.dropna(inplace=True)
#%%
data.isnull().any()
#%%
data
#%%
# 划分数据集
x = data.iloc[:, 1:-1]
y = data['Class']
#%%
from sklearn.model_selection import train_test_split
#%%
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
#%%
x_train
#%%
# 特征工程
from sklearn.preprocessing import StandardScaler
#%%
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#%%
x_train
#%%
# 逻辑回归预估器
from sklearn.linear_model import LogisticRegression
#%%
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
#%%
# 逻辑回归模型参数查看
estimator.coef_
#%%
estimator.intercept_
#%%
# 模型评估
print("预测值与真实值对比", y_test == estimator.predict(x_test))
print("准确率为:", estimator.score(x_test, y_test))
#%%
5.4.5、精确率与召回率
-
混淆矩阵
预测结果与真实结果的四种不同结果
预测结果 正例 假例 真实结果 正例 真正例TP 伪反例FN 假例 伪正例FP 真反例TN -
精确率
- 预测结果为正例样本中真实为正例的比例
-
召回率
- 真实为正例的样本中预测结果为正例的比例
-
F1-score
- 模型的稳健性
F 1 = 2 T P 2 T P + F N + F P F1 = \frac{2TP}{2TP+FN+FP} F1=2TP+FN+FP2TP
- 模型的稳健性
-
分类评估报告API
- sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None)
- y_true:真实目标值
- y_pred:估计器预测目标值
- labels:指定类别对应的数字
- target_names:目标类别名称
- return:每个类别精确率与召回率
- sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None)
5.4.6、ROC曲线与AUC指标
- ROC曲线
- TPR
- TPR = TP / (TP + FN)
- FPR
- FPR = FP / (FP + TN)
- ROC曲线
- ROC曲线的横轴是FPR,纵轴是TPR,当二者相等时,表示的意义是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5
- TPR
- AUC指标
- AUC的概率意义是随机取一对正负样本,正样本得分大于负样本的概率
- AUC的最小值为0.5, 最大值为1,取值越高越好
- AUC=1,完美分类器
- 0.5<AUC < 1, 优于随机猜测,这个分类器模型妥善设定阈值的话,由预测价值
- AUC计算API
- sklearn.metrics.roc_auc_score(y_true, y_score)
- 计算ROC曲线面积,即AOC值
- y_true:每个样本的真实类别,必须为0,1
- y_score:预测得分
- sklearn.metrics.roc_auc_score(y_true, y_score)
- 总结
- AUC只能用来评价二分类
- AUC非常适合评价样本不平衡中的分类器性能
5.5、模型保存和加载
5.5.1、sklearn模型保存和加载API
- import joblib
- 保存:joblib.dump(rf, ‘test.pkl’)
- 加载:estimator = joblib.load(‘test.pkl’)
5.5.2、线性回归的模型保存加载案例
# 保存模型
# joblib.dump(estimator, 'my_ridge.pkl')
# 加载模型
estimator = joblib.load('my_ridge.pkl')
六、无监督学习
6.1、什么是无监督学习
- 无目标值
6.2、无监督学习包含算法
- 聚类
- K-means(K均值聚类)
- 降维
- PCA
6.3、K-means原理
1、K-means聚类步骤
-
- 随机设置K个特征空间的点作为初始的聚类中心
- 对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
- 接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
- 如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步骤
6.4、K-means的API
- sklearn.cluster.KMeans(n_clusters= 8, init=‘k-means++’)
- k-means聚类
- n_clusters:开始的聚类中心数量
- init:初始化方法,
- labels:默认标记的类型,可以和真实值比较(不是值比较)
6.5、案例:
6.6、聚类Kmeans性能指标评估
-
轮廓系数
S C i = b i − a i m a x ( b i , a i ) SC_i = \frac{b_i - a_i}{max(b_i,a_i)} SCi=max(bi,ai)bi−ai- bi:外部距离,i到其他族群的所有样本的距离最小值
- ai:内部距离,i到本身簇的距离平均值
-
轮廓系数(-1, 1),越接近于1效果越好,接近于-1效果不好
-
API
- sklearn.metrics.silhouette_score(X, labels)
- 计算所有样本的平均轮廓系数
- X:特征值
- labels:被聚类标记的目标值
- sklearn.metrics.silhouette_score(X, labels)
6.7、K-means总结
- 特点分析:采用迭代式算法,直观易懂且非常实用
- 缺点:容易收敛到局部最优解
- 可以通过多次聚类解决
- 应用场景:在没有目标值时做聚类,后续做分类