python机器学习入门

1.人工智能概述

1.1机器学习与人工智能、深度学习

1.1.1机器学习和人工智能,深度学习的关系

  • 机器学习是人工智能的一个实现途径
  • 深度学习是机器学习的一个方法发展而来

1.1.2机器学习、深度学习能做些什么

  • 传统预测
    店铺销量预测、量化投资、广告推荐
  • 图像识别
    街道交通标志检测、人脸识别
  • 自然语言处理
    文本分类、情感分析、自动聊天、文本检测

1.2 什么是机器学习

1.2.1 定义

机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测
在这里插入图片描述

1.2.2 数据集构成

在这里插入图片描述
注:
对于每一行数据我们可以称之为样本
有些数据集可以没有目标值

1.3 机器学习算法分类

1.3.1监督学习

1.3.1.1 分类问题

eg:特征值:猫/狗的图片;目标值:猫/狗-类别

1.3.1.2 回归问题

eg:特征值:房屋的各个属性信息;目标值:房屋价格-连续型数据

1.3.2 无监督学习

eg:特征值:人物的各个属性信息;目标值:无
在这里插入图片描述

1.3.3 机器学习算法分类

  • 监督学习(supervised learning)(预测)

定义:输入数据是由输入特征值和目标值所组成。函数的输出可以是一个连续的值(称为回归),或是输出是有限个离散值(称作分类)。
分类 :k-近邻算法、贝叶斯分类、决策树与随机森林、逻辑回归、神经网络
回归 :线性回归、岭回归

  • 无监督学习(unsupervised learning)

定义:输入数据是由输入特征值所组成。
聚类: k-means

1.4 机器学习开发流程

  1. 获取数据
  2. 数据处理 : 缺失值处理等
  3. 特征工程 :也算是在做数据处理,只不过处理成为算法使用的数据
  4. 选择合适的算法-得到模型
  5. 模型评估 如果评估不合适,回到数据处理
  6. 应用

在这里插入图片描述

2 特征工程

2.1 数据集

2.1.1 可用数据集

学习阶段可用的数据集:
在这里插入图片描述
Kaggle网址:https://www.kaggle.com/datasets

UCI数据集网址: http://archive.ics.uci.edu/ml/

scikit-learn网址:http://scikit-learn.org/stable/datasets/index.html#datasets

1 Scikit-learn工具介绍
  • Python语言的机器学习工具
  • Scikit-learn包括许多知名的机器学习算法的实现
  • Scikit-learn文档完善,容易上手,丰富的API

2.1.2 sklearn数据集

1 scikit-learn数据集API介绍

sklearn.datasets
加载获取流行数据集

  • datasets.load_*()

获取小规模数据集,数据包含在datasets里

  • datasets.fetch_*(data_home=None)

获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载到的目录,默认是 ~/scikit_learn_data/

2 sklearn小数据集
  • sklearn.datasets.load_iris()

加载并返回鸢尾花数据集

3 sklearn大数据集
  • sklearn.datasets.fetch_20newsgroups(data_home=None,subset=‘train’)

subset:‘train’或者’test’,‘all’,可选,选择要加载的数据集。
训练集的“训练”,测试集的“测试”,两者的“全部”

4 sklearn数据集返回值

load和fetch返回的数据类型datasets.base.Bunch(继承自字典,有键值对)
key值可取:
data:特征数据数组,是 [n_samples * n_features] 的二维 numpy.ndarray 数组
target:标签数组,是 n_samples 的一维 numpy.ndarray 数组
DESCR:数据描述
feature_names:特征名,新闻数据,手写数字、回归数据集没有
target_names:标签名

dict[“key”] = values
bunch.key = values

eg:鸢尾花数据集

from sklearn.datasets import load_iris


def datasets_demo():
    iris = load_iris()
    print("鸢尾花数据集:\n", iris)
    print("查看数据集描述:\n", iris["DESCR"])
    print("查看特征值名字:\n",iris.feature_names)
    print("查看特征值\n", iris.data,iris.data.shape)
    return None


if __name__ == "__main__":
    datasets_demo()

2.1.3 数据集的划分

机器学习一般的数据集会划分为两个部分:
训练数据:用于训练,构建模型
测试数据:在模型检验时使用,用于评估模型是否有效

测试集: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.datasets import load_iris
from sklearn.model_selection import train_test_split


def datasets_demo():
    iris = load_iris()
    print("鸢尾花数据集:\n", iris)
    print("查看数据集描述:\n", iris["DESCR"])
    print("查看特征值名字:\n", iris.feature_names)
    print("查看特征值\n", iris.data, iris.data.shape)

    # 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
    print("训练集的特征值", x_train, x_train.shape)

    return None


if __name__ == "__main__":
    datasets_demo()

在这里插入图片描述

2.2 特征工程介绍

2.2.1 为什么需要特征工程(Feature Engineering)

能让算法更加发挥作用

2.2.2 什么是特征工程

特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程
特征工程包含内容
特征抽取
特征预处理
特征降维

2.3 特征提取

机器学习算法:统计方法:数学公式
文本类型转换为数值
类型转换为数值

2.3.1 特征提取

1 将任意数据(如文本或图像)转换为可用于机器学习的数字特征

注:特征值化是为了计算机更好的去理解数据

字典特征提取(特征离散化)
文本特征提取
图像特征提取(深度学习将介绍)

2 特征提取API

sklearn.feature_extraction

2.3.2 字典特征提取

sklearn.feature_extraction.DictVectorizer(sparse=True,…)
DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵
sparse稀疏矩阵: 将非零值 按位置显示出来,可以节省内存,提高运行效率
在这里插入图片描述
DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式
DictVectorizer.get_feature_names() 返回类别名称

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer


def datasets_demo():
    iris = load_iris()
    print("鸢尾花数据集:\n", iris)
    print("查看数据集描述:\n", iris["DESCR"])
    print("查看特征值名字:\n", iris.feature_names)
    print("查看特征值\n", iris.data, iris.data.shape)

    # 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
    print("训练集的特征值", x_train, x_train.shape)

    return None


def dict_demo():
    data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}]
    transfer = DictVectorizer(sparse=False)
    data_new = transfer.fit_transform(data)
    print("data_new:\n", data_new)
    print("特征名字:\n", transfer.get_feature_names())
    return None


if __name__ == "__main__":
    # datasets_demo()
    dict_demo()

字典特征抽取:对于特征当中存在类别信息的我们都会做one-hot编码处理
应用场景:

  • pclass,sex 数据集中类别特征比较多的情况

将数据集的特征转换为字典类型
DictVectorizer转换

  • 本身拿到的数据就是字典类型

2.3.3 文本特征提取

单词作为特征
句子或短语,字母都可 但是单词最合适

  • 方法1:sklearn.feature_extraction.text.CountVectorizer(stop_words=[])
    stop_words=[] 停用词假如stop_words=[“is”] 那么is就不会统计
    统计每个样本特征词出现的次数
    CountVectorizer.fit_transform(X) X:文本或者包含文本字符串的可迭代对象 返回值:返回sparse矩阵
    CountVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格
    CountVectorizer.get_feature_names() 返回值:单词列表
def count_demo():
    data = ["life is short,i like like python", "life is too long,i dislike python"]
    # 实例化转换器类
    transfer = CountVectorizer()
    # 调用fit_transform
    data_new = transfer.fit_transform(data)
    print("data_new:\n", data_new.**toarray()**)
    print(transfer.get_feature_names())
    return None

在这里插入图片描述

遇到中文无法分组的问题
使用jieba库
def cut_word(text): text = " ".join(list(jieba.cut(text))) return text

def count_chine_demo2():
    data_new = []
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    for i in data:
        data_new.append(cut_word(i))
    transfer = CountVectorizer()
    # 调用fit_transform
    data_final = transfer.fit_transform(data_new)
    print("data_final:\n", data_final.toarray())
    print(transfer.get_feature_names())
    return None

在这里插入图片描述

  • 方法2:sklearn.feature_extraction.text.TfidfVectorizer
  • TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类
  • TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度

词频(term frequency,tf)

指的是某一个给定的词语在该文件中出现的频率

逆向文档频率(inverse document frequency,idf)

是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
在这里插入图片描述

def tfidf_demo():
    data_new = []
    data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。",
            "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
            "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
    for i in data:
        data_new.append(cut_word(i))
    transfer = TfidfVectorizer()
    # 调用fit_transform
    data_final = transfer.fit_transform(data_new)
    print("data_final:\n", data_final.toarray())
    print(transfer.get_feature_names())
    return None

在这里插入图片描述

2.4 特征预处理

2.4.1 什么是特征预处理

通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程

1 包含内容

数值型数据的无量纲化:
归一化
标准化

2 特征预处理API

数值型数据的无量纲化:

  • 归一化
  • 标准化

sklearn.preprocessing

3 为什么我们要进行归一化/标准化?

特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标结果,使得一些算法无法学习到其它的特征

2.4.2 归一化

1 定义

通过对原始数据进行变换把数据映射到(默认为[0,1])之间
在这里插入图片描述

作用于每一列,max为一列的最大值,min为一列的最小值,那么X’’为最终结果,mx,mi分别为指定区间值默认mx为1,mi为0

在这里插入图片描述

2 API

sklearn.preprocessing.MinMaxScaler (feature_range=(0,1)… )
MinMaxScalar.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array

def minmax_demo():
    # 获取数据
    data = pd.read_csv("./dating.txt")
    data = data.iloc[:, :3]

    # 实例化一个转换器类
    transfer = MinMaxScaler()
    # 调用fit_transform
    data_new = transfer.fit_transform(data)
    print(data_new)
    return None

在这里插入图片描述

3 归一化总结

注意最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法健壮性较差,只适合传统精确小数据场景

2.4.3 标准化

1 定义

通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
在这里插入图片描述
对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变
对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。

2 API

sklearn.preprocessing.StandardScaler( )
处理之后每列来说所有数据都聚集在均值0附近标准差差为1
StandardScaler.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回值:转换后的形状相同的array

def stand_demo():
    data = pd.read_csv("./dating.txt")
    data = data.iloc[:, :3]

    # 实例化一个转换器类
    transfer = StandardScaler()
    # 调用fit_transform
    data_new = transfer.fit_transform(data)
    print(data_new)
    return None

在这里插入图片描述

3 应用场景

在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。

2.5 特征降维

2.5.1 降维

降维 - 降低纬度
ndarray
0维 标量 0 1 2 3…
1维 向量
2维 矩阵
3维…

但在特征将维中 为 二维数组
降低特征的个数

降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
得到效果为 :特征与特征之间不相关

2.5.2 降维的两种方式

特征选择
主成分分析(可以理解一种特征提取的方式)

2.5.3 什么是特征选择

1 定义
数据中包含冗余或无关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。
2 方法
Filter(过滤式):主要探究特征本身特点、特征与特征和目标值之间关联
方差选择法:低方差特征过滤
相关系数:特征与特征之间的相关程度
Embedded (嵌入式):算法自动选择特征(特征与目标值之间的关联)
决策树:信息熵、信息增益
正则化:L1、L2
深度学习:卷积等
4 过滤式
4.1 低方差特征过滤
删除低方差的一些特征,前面讲过方差的意义。再结合方差的大小来考虑这个方式的角度。

特征方差小:某个特征大多样本的值比较相近
特征方差大:某个特征很多样本的值都有差别

4.1.1 API
sklearn.feature_selection.VarianceThreshold(threshold = 0.0)低于threshold的特征就会被删除
删除所有低方差特征
Variance.fit_transform(X)
X:numpy array格式的数据[n_samples,n_features]
返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。

4.2 相关系数
皮尔逊相关系数(Pearson Correlation Coefficient)
反映变量之间相关关系密切程度的统计指标
4.2.1 特点
相关系数的值介于–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为高度线性相关
4.2.2 API
from scipy.stats import pearsonr
x : (N,) array_like
y : (N,) array_like Returns: (Pearson’s correlation coefficient, p-value)

    r = pearsonr(data["pe_ratio"], data["pb_ratio"])
    print(r)

在这里插入图片描述

特征与特征之间相关性很高的话:

  • 选取其中一个作为代表
  • 加权求和 作为新的特征
  • 主成分分析

2.6 主成分分析

2.6.1 什么是主成分分析(PCA)

1 定义:高维数据转化为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量

作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。

应用:回归分析或者聚类分析当中

2 API

sklearn.decomposition.PCA(n_components=None)
将数据分解为较低维数空间
n_components:
小数:表示保留百分之多少的信息
整数:减少到多少特征

PCA.fit_transform(X) X:numpy array格式的数据[n_samples,n_features]
返回值:转换后指定维度的array

def pca_demo():
    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)
    return None

在这里插入图片描述
在这里插入图片描述

分类算法

sklearn转换器和估计器
转换器: - 特征工程的父类
1.实例化
2.调用fit_transform()
eg:标准化
(x - mean) / std
fit_transform()
fit():计算每一列的平均值、标准差
transform():(x-mean)/std 进行最终的转换

估计器(sklearn机器学习算法的实现)

在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API
1.实例化一个estimator
2.estimator.fit(x_train,y_train) 计算
调用完毕,得到模型
3.模型评估
1)直接比对真实值和预测值
y_predict = estimator.predict(x_test)
y_test == y_predict
2)计算准确率
accuracy = estimator.score(x_test,y_test)

K-近邻算法(KNN)

什么是K-近邻算法

核心思想:根据你的“邻居”来推断出你的类别
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别

如何确定谁是邻居?
距离公式
两个样本的距离可以通过如下公式计算,又叫欧式距离
在这里插入图片描述

k值取得过大,样本不均衡的影响
k值取得过小,容易受到异常点影响

K-近邻算法API

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
n_neighbors:int,可选(默认= 5),k_neighbors查询默认使用的邻居数
algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法:‘ball_tree’将会使用 BallTree,‘kd_tree’将使用 KDTree。‘auto’将尝试根据传递给fit方法的值来决定最合适的算法。 (不同实现方式影响效率)

  • 案例1:鸢尾花种类预测
    1)获取数据
    2)数据集划分
    3)特征工程
    标准化
    4)KNN预估器
    5)模型评估
def knn_iris():
    # 获取数据
    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) # 要使得测试集使用和训练集一样的方法进行 标准化  所以使用transfer()方法
    # KNN算法估计
    estimator = KNeighborsClassifier(n_neighbors=3)
    estimator.fit(x_train, y_train)
    # 算法评估
    y_predict = estimator.predict(x_test)
    print(y_predict)
    print(y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print(score)
    return None

在这里插入图片描述
KNN优缺点:
优点:简单,易于理解,易于实现,无需训练
缺点:必须指定K值,K值选择不当则分类精度不能保证
懒惰算法,对测试样本分类时的计算量大,内存开销大
使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试

模型选择与调优

什么是交叉验证(cross validation)

交叉验证:将拿到的训练数据,分为训练和验证集。
交叉验证目的:为了让被评估的模型更加准确可信

超参数搜索-网格搜索(Grid Search)

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

模型选择与调优

sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
对估计器的指定参数值进行详尽搜索
estimator:估计器对象
param_grid:估计器参数(dict){“n_neighbors”:[1,3,5]}
cv:指定几折交叉验证
fit():输入训练数据
score():准确率
结果分析:
bestscore:在交叉验证中验证的最好结果_
bestestimator:最好的参数模型
cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果

def knn_iris_gscv():
    # 获取数据
    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()
    # 加入网格搜索与交叉验证
    param_dict = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=10)
    estimator.fit(x_train, y_train)
    # 算法评估
    y_predict = estimator.predict(x_test)
    print(y_predict)
    print(y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print(score)
    print("-----------")
    # 最佳参数
    print(estimator.best_params_)
    # 最佳结果
    print(estimator.best_score_)
    # 最佳估计qi
    print(estimator.best_estimator_)
    # 交叉验证结果
    print(estimator.cv_results_)
    return None

朴素贝叶斯算法

概率基础

概率(Probability)定义
概率定义为一件事情发生的可能性
扔出一个硬币,结果头像朝上
某天是晴天
P(X) : 取值在[0, 1]

条件概率与联合概率、相互独立
联合概率:包含多个条件,且所有条件同时成立的概率
记作:P(A,B)
特性:P(A, B) = P(A)P(B)
条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率
记作:P(A|B)
特性:P(A1,A2|B) = P(A1|B)P(A2|B)
相互独立:如果P(A,B) = P(A) * P(B),则称事件A与事件B相互独立。

p(程序员, 匀称) = P(程序员)P(匀称) =3/7*(4/7) = 12/49
P(产品, 超重|喜欢) =P(产品|喜欢)P(超重|喜欢)=1/2 * 1/4 = 1/8

朴素?
意思是->假设特征与特征之间是相互独立的

贝叶斯公式

在这里插入图片描述
总结:
朴素贝叶斯:朴素 + 贝叶斯
应用场景:文本分类

P(W│C)计算方法:给定类别下特征(被预测文档中出现的词)的概率
计算方法:P(F1│C)=Ni/N (训练文档中去计算)
Ni为该F1词在C类别所有文档中出现的次数
N为所属类别C下的文档所有词出现的次数和

  • P(W│C)某个概率可能为0,该怎么解决?

拉普拉斯平滑系数 计算的时候 所有的一起用,公平!!!
目的:防止计算出的分类概率为0
在这里插入图片描述

API

sklearn.naive_bayes.MultinomialNB(alpha = 1.0)
朴素贝叶斯分类
alpha:拉普拉斯平滑系数

案例:20类新闻分类

def nb_news():
    # 获取数据
    news = fetch_20newsgroups(data_home="F:\lqb", subset="all")
    # 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)
    # 特征工程
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    # 朴素贝叶斯算法的预估其流程
    estimator = MultinomialNB()
    estimator.fit(x_train, y_train)
    # 模型评估
    y_predict = estimator.predict(x_test)
    print(y_predict)
    print(y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print(score)
    return None

优点:
朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
对缺失数据不太敏感,算法也比较简单,常用于文本分类。
分类准确度高,速度快
缺点:
由于使用了样本属性独立性的假设,所以如果特征属性有关联时其效果不好

决策树

认识决策树

如何高效的进行决策?
特征的先后顺序

决策树分类原理详解

原理
信息

信息:消除随机不定性的东西
信息的衡量 - 信息量 - 信息熵
在这里插入图片描述

决策树的划分依据之一------信息增益

定义与公式
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
在这里插入图片描述
在这里插入图片描述

决策树API

class sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
决策树分类器
criterion:默认是’gini’系数,也可以选择信息增益的熵’entropy’
max_depth:树的深度大小
random_state:随机数种子
其中会有些超参数:max_depth:树的深度大小
其它超参数我们会结合随机森林讲解

def tree_iris():
    # 获取数据
    iris = load_iris()
    # 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,random_state=22)
    # 使用决策树预估器分类
    estimator = DecisionTreeClassifier(criterion="entropy")
    estimator.fit(x_train, y_train)
    # 模型评估
    y_predict = estimator.predict(x_test)
    print(y_predict)
    print(y_test == y_predict)
    score = estimator.score(x_test, y_test)
    print(score)
    return None

在这里插入图片描述

决策树可视化

sklearn.tree.export_graphviz() 该函数能够导出DOT格式
tree.export_graphviz(estimator,out_file='tree.dot’,feature_names=[‘’,’’])

    # 可视化决策树
    export_graphviz(estimator, out_file="iris_tree.dot", feature_names=iris.feature_names)
    return None

得到iris_tree.dot文件,如下:

digraph Tree {
node [shape=box, fontname=“helvetica”] ;
edge [fontname=“helvetica”] ;
0 [label=“petal width (cm) <= 0.75\nentropy = 1.584\nsamples = 112\nvalue = [39, 37, 36]”] ;
1 [label=“entropy = 0.0\nsamples = 39\nvalue = [39, 0, 0]”] ;
0 -> 1 [labeldistance=2.5, labelangle=45, headlabel=“True”] ;
2 [label=“petal width (cm) <= 1.75\nentropy = 1.0\nsamples = 73\nvalue = [0, 37, 36]”] ;
0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel=“False”] ;
3 [label=“petal length (cm) <= 5.05\nentropy = 0.391\nsamples = 39\nvalue = [0, 36, 3]”] ;
2 -> 3 ;
4 [label=“petal width (cm) <= 1.65\nentropy = 0.183\nsamples = 36\nvalue = [0, 35, 1]”] ;
3 -> 4 ;
5 [label=“entropy = 0.0\nsamples = 34\nvalue = [0, 34, 0]”] ;
4 -> 5 ;
6 [label=“sepal width (cm) <= 2.75\nentropy = 1.0\nsamples = 2\nvalue = [0, 1, 1]”] ;
4 -> 6 ;
7 [label=“entropy = 0.0\nsamples = 1\nvalue = [0, 0, 1]”] ;
6 -> 7 ;
8 [label=“entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]”] ;
6 -> 8 ;
9 [label=“petal width (cm) <= 1.55\nentropy = 0.918\nsamples = 3\nvalue = [0, 1, 2]”] ;
3 -> 9 ;
10 [label=“entropy = 0.0\nsamples = 2\nvalue = [0, 0, 2]”] ;
9 -> 10 ;
11 [label=“entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]”] ;
9 -> 11 ;
12 [label=“petal length (cm) <= 4.85\nentropy = 0.191\nsamples = 34\nvalue = [0, 1, 33]”] ;
2 -> 12 ;
13 [label=“entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]”] ;
12 -> 13 ;
14 [label=“entropy = 0.0\nsamples = 33\nvalue = [0, 0, 33]”] ;
12 -> 14 ;
}

把相应的数据输入到http://webgraphviz.com/网站即可看到可视化的决策树。

决策树总结

优点:
简单的理解和解释,树木可视化,可解释能力强。
缺点:
决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。(在机器学习中,我们提高了在训练数据集上的表现力时,在测试数据集上的表现力反而下降了,这就是过拟合)
改进:
减枝cart算法(决策树API当中已经实现,随机森林参数调优有相关介绍)
随机森林

随机森林

随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

随机森林原理过程

随机:
特征随机
BootStrap 随机有放回抽样

为什么采用BootStrap抽样
为什么要随机抽样训练集?  
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的
为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

训练集随机
随机去选出m个特征, m <<M,建立决策树

API

class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, random_state=None, min_samples_split=2)

随机森林分类器
n_estimators:integer,optional(default = 10)森林里的树木数量120,200,300,500,800,1200
criteria:string,可选(default =“gini”)分割特征的测量方法
max_depth:integer或None,可选(默认=无)树的最大深度 5,8,15,25,30
max_features="auto”,每个决策树的最大特征数量
If “auto”, then max_features=sqrt(n_features).
If “sqrt”, then max_features=sqrt(n_features) (same as “auto”).
If “log2”, then max_features=log2(n_features).
If None, then max_features=n_features.
bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样
min_samples_split:节点划分最少样本数
min_samples_leaf:叶子节点的最小样本数
超参数:n_estimator, max_depth, min_samples_split,min_samples_leaf

逻辑回归与二分类

逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,虽然名字中带有回归,但是它与回归之间有一定的联系。由于算法的简单和高效,在实际中应用非常广泛。

逻辑回归的应用场景

广告点击率
是否为垃圾邮件
是否患病
金融诈骗
虚假账号
看到上面的例子,我们可以发现其中的特点,那就是都属于两个类别之间的判断。逻辑回归就是解决二分类问题的利器

逻辑回归的原理
输入

逻辑回归的输入就是一个线性回归的结果。

激活函数

sigmoid函数
在这里插入图片描述
在这里插入图片描述

损失以及优化

逻辑回归的损失,称之为对数似然损失,公式如下:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

优化

同样使用梯度下降优化算法,去减少损失函数的值。这样去更新逻辑回归前面对应算法的权重参数,提升原本属于1类别的概率,降低原本是0类别的概率。

逻辑回归API
  • sklearn.linear_model.LogisticRegression(solver=‘liblinear’,penalty=‘l2’, C = 1.0)

solver:优化求解方式(默认开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数)
sag:根据数据集自动选择,随机平均梯度下降
penalty:正则化的种类
C:正则化力度
在这里插入图片描述

案例:癌症分类预测-良/恶性乳腺癌肿瘤预测
def logisticregression():
    """
    逻辑回归进行癌症预测
    :return: None
    """
    # 1、读取数据,处理缺失值以及标准化
    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("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",
                       names=column_name)

    # 删除缺失值
    data = data.replace(to_replace='?', value=np.nan)

    data = data.dropna()

    # 取出特征值
    x = data[column_name[1:10]]

    y = data[column_name[10]]

    # 分割数据集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    # 进行标准化
    std = StandardScaler()

    x_train = std.fit_transform(x_train)

    x_test = std.transform(x_test)

    # 使用逻辑回归
    lr = LogisticRegression()

    lr.fit(x_train, y_train)

    print("得出来的权重:", lr.coef_)

    # 预测类别
    print("预测的类别:", lr.predict(x_test))

    # 得出准确率
    print("预测的准确率:", lr.score(x_test, y_test))
    return None
分类的评估方法

真正患癌症是否能够被检测出来。

精确率与召回率
混淆矩阵

在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合,构成混淆矩阵(适用于多分类)
在这里插入图片描述

精确率(Precision)与召回率(Recall)

在这里插入图片描述
在这里插入图片描述

分类评估报告API

sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )
y_true:真实目标值
y_pred:估计器预测目标值
labels:指定类别对应的数字
target_names:目标类别名称
return:每个类别精确率与召回率

    y_predict = lr.predict(x_test)

    print("得出来的权重:", lr.coef_)

    # 预测类别
    print("预测的类别:", lr.predict(x_test))

    # 得出准确率
    print("预测的准确率:", lr.score(x_test, y_test))
    report = classification_report(y_test, y_predict, labels=[2, 4],target_names=["良性", "恶性"])
    print(report)
    return None

在这里插入图片描述

假设这样一个情况,如果99个样本癌症,1个样本非癌症,不管怎样我全都预测正例(默认癌症为正例),准确率就为99%但是这样效果并不好,这就是样本不均衡下的评估问题

问题:如何衡量样本不均衡下的评估?

根据问题引入ROC曲线与AUC指标
知道TPR与FPR

TPR = TP / (TP + FN)
所有真实类别为1的样本中,预测类别为1的比例
FPR = FP / (FP + FN)
所有真实类别为0的样本中,预测类别为1的比例

ROC曲线

ROC曲线的横轴就是FPRate,纵轴就是TPRate,当二者相等时,表示的意义则是:对于不论真实类别是1还是0的样本,分类器预测为1的概率是相等的,此时AUC为0.5
在这里插入图片描述

AUC指标

AUC的概率意义是随机取一对正负样本,正样本得分大于负样本的概率
AUC的最小值为0.5,最大值为1,取值越高越好
AUC=1,完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。
0.5<AUC<1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。
最终AUC的范围在[0.5, 1]之间,并且越接近1越好

AUC计算API

from sklearn.metrics import roc_auc_score
sklearn.metrics.roc_auc_score(y_true, y_score)
计算ROC曲线面积,即AUC值
y_true:每个样本的真实类别,必须为0(反例),1(正例)标记
y_score:每个样本预测的概率值

总结

AUC只能用来评价二分类
AUC非常适合评价样本不平衡中的分类器性能

总结

在当前所有算法中,具有极好的准确率
能够有效地运行在大数据集上,处理具有高维特征的输入样本,而且不需要降维
能够评估各个特征在分类问题上的重要性

回归算法

线性回归

回归问题:目标值-连续型数据

线性回归的原理

定义与公式

线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。

线性模型:
公式:y = w1x1+w2x2+…+wn*xn+b

在这里插入图片描述
我们看到特征值与目标值之间建立的一个关系,这个可以理解为回归方程。

广义线性模型:
线性回归当中的关系有两种,一种是线性关系,另一种是非线性关系
在这里插入图片描述
这种非线性关系也是线性模型。
只要自变量是一次或参数是一次都是线性模型。
线性关系一定是线性模型,但线性模型不一定是线性关系

线性回归的损失和优化原理

目标:求模型参数
模型参数能够预测准确

损失函数/cost/成本函数/目标函数

在这里插入图片描述

优化损失

如何去求模型当中的W,使得损失最小?(目的是找到最小损失对应的W值)

  • 正规方程:直接计算一次得到
    在这里插入图片描述

  • 梯度下降:不断迭代
    在这里插入图片描述

线性回归API

在这里插入图片描述

回归性能评估

均方误差(Mean Squared Error)MSE)评价机制:
在这里插入图片描述

注:y^i为预测值,¯y为真实值

sklearn.metrics.mean_squared_error(y_true, y_pred)
均方误差回归损失
y_true:真实值
y_pred:预测值
return:浮点数结果

案例:波士顿房价预测

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():
    # 获取数据
    boston = load_boston()
    # 划分和数据集
    x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
    # 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    # 预估器
    estimator = LinearRegression()
    estimator.fit(x_train, y_train)
    # 得到模型
    print("权重系数1:\n", estimator.coef_)
    print("偏置1为:\n", estimator.intercept_)
    # 模型评估
    y_predict = estimator.predict(x_test)
    error = mean_squared_error(y_test, y_predict)
    print(error)
    return None


def linear2():
    # 获取数据
    boston = load_boston()
    # 划分和数据集
    x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
    # 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    # 预估器
    estimator = SGDRegressor(eta0=0.001)
    estimator.fit(x_train, y_train)
    # 得到模型
    print("权重系数2:\n", estimator.coef_)
    print("偏置2为:\n", estimator.intercept_)
    # 模型评估
    y_predict = estimator.predict(x_test)
    error = mean_squared_error(y_test, y_predict)
    print(error)
    return None


if __name__ == "__main__":
    linear1()
    linear2()


在这里插入图片描述

欠拟合与过拟合

训练数据训练的很好啊,误差也不大,在测试集上面有问题

什么是过拟合与欠拟合

过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
在这里插入图片描述

原因以及解决办法

欠拟合原因以及解决办法
原因:学习到数据的特征过少
解决办法:增加数据的特征数量
过拟合原因以及解决办法
原因:原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点
解决办法:
正则化

正则化类别

L2正则化
作用:可以使得其中一些W的都很小,都接近于0,削弱某个特征的影响
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
Ridge回归 - 岭回归
损失函数+λ惩罚项
L1正则化
作用:可以使得其中一些W的值直接为0,删除这个特征的影响
LASSO回归

线性回归的改进-岭回归

岭回归- 带有L2正则化的线性回归
岭回归,其实也是一种线性回归。只不过在算法建立回归方程时候,加上L2正则化的限制,从而达到解决过拟合的效果。

API
  • sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver=“auto”, normalize=False)

具有l2正则化的线性回归
alpha:正则化力度,也叫 λ 惩罚项系数
λ取值:0~1 1~10
solver:会根据数据自动选择优化方法
sag:如果数据集、特征都比较大,选择该随机梯度下降优化
normalize:数据是否进行标准化
normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据

Ridge.coef_:回归权重
Ridge.intercept_:回归偏置

Ridge方法相当于SGDRegressor(penalty=‘l2’,loss=“squared_loss”),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)

  • sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)

具有l2正则化的线性回归,可以进行交叉验证
coef_:回归系数

def linear3():
    # 获取数据
    boston = load_boston()
    # 划分和数据集
    x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
    # 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    # 预估器
    estimator = Ridge(alpha=0.5, max_iter=10000)
    estimator.fit(x_train, y_train)
    # 得到模型
    print("权重系数3:\n", estimator.coef_)
    print("偏置3为:\n", estimator.intercept_)
    # 模型评估
    y_predict = estimator.predict(x_test)
    error = mean_squared_error(y_test, y_predict)
    print(error)
    return None

模型保存和加载

sklearn模型的保存和加载API
  • from sklearn.externals import joblib

保存:joblib.dump(rf, ‘test.pkl’)(序列化到本地)
加载:estimator = joblib.load(‘test.pkl’)

模型保存加载案例

在这里插入图片描述

无监督学习-K-means算法

无监督学习:没有目标值

无监督学习包含算法

  • 聚类

K-means(K均值聚类)

  • 降维

PCA

K-means原理

K-means聚类步骤
1、随机设置K个特征空间内的点作为初始的聚类中心
2、对于其他每个点计算到K个中心的距离,未知的点选择最近的一个聚类中心点作为标记类别
3、接着对着标记的聚类中心之后,重新计算出每个聚类的新中心点(平均值)
4、如果计算得出的新中心点与原中心点一样,那么结束,否则重新进行第二步过程
在这里插入图片描述

K-meansAPI

sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
k-means聚类
n_clusters:开始的聚类中心数量(k值)
init:初始化方法,默认为’k-means ++’
labels_:默认标记的类型,可以和真实值比较(不是值比较)

降维之后的数据
1)预估器流程
2)看结果
3)模型评估

from sklearn.cluster import KMeans
estimator = KMeans(n_cluster = 3)
estimator.fit(data_new)
y_predict = estimator.predict(data_new)

Kmeans性能评估指标

轮廓系数

在这里插入图片描述

结论

如果b_i>>a_i:趋近于1效果越好, b_i<<a_i:趋近于-1,效果不好。轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优。

轮廓系数API

sklearn.metrics.silhouette_score(X, labels)
计算所有样本的平均轮廓系数
X:特征值
labels:被聚类标记的目标值

K-means总结

特点分析:采用迭代式算法,直观易懂并且非常实用
缺点:容易收敛到局部最优解(多次聚类)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值