ShanTianQi

Python机器学习入门

第一章 机器学习概述


机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测

数据集的构成

机器学习算法分类

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

无监督学习(unsupervised learning)

开发流程


第二章 特征工程


2.1 数据集


可用数据集

2.1.1 Scikit-learn

sklearn.datasets

sklearn小数据集

加载并返回鸢尾花数据集

名称数量
类别3
特征4
样本数量150
每个类别数量50

加载并返回波士顿房价数据集

名称数量
目标类别5-50
特征13
样本数量506

sklearn大数据集

数据集返回值

数据集的划分

机器学习一般的数据集汇划分为两个部分:

划分比例:

数据集划分api


2.2 特征工程介绍


特征工程时使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程

特征工程位置与数据处理的比较

特征工程包含内容


2.3 特征抽取


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

特征提取API

2.3.1 字典特征提取

作用:对字典数据进行特征值化

稀疏矩阵:将非0值 按位置表示出来

import sklearn
from sklearn.feature_extraction import DictVectorizer

data = [{'city': '北京', 'temperature': 100},
      {'city': '上海', 'temperature': 60},
      {'city': '深圳', 'temperature': 30}]

# 实例化类DictVectorizer
transfer = DictVectorizer()
# 调用fit_transform方法输入数据并转换
data_new = transfer.fit_transform(data)

print(data_new) # 没有加上sparse = False参数的结果
# <Compressed Sparse Row sparse matrix of dtype 'float64'
# 	with 6 stored elements and shape (3, 4)>
#   Coords	Values
#   (0, 1)	1.0
#   (0, 3)	100.0
#   (1, 0)	1.0
#   (1, 3)	60.0
#   (2, 2)	1.0
#   (2, 3)	30.0

transfer = DictVectorizer(sparse = False)
print(data_new)
# [[  0.   1.   0. 100.]
#  [  1.   0.   0.  60.]
#  [  0.   0.   1.  30.]]

print(transfer.get_feature_names_out())
# ['city=上海' 'city=北京' 'city=深圳' 'temperature']

对于特征当中存在的类别信息,都会做one-hot编码处理

2.3.2 文本特征提取

作用:对文本数据进行特征值化

from sklearn.feature_extraction.text import CountVectorizer

data = ["life is short, i like python",
        "life is too long, i dislike python"]

transfer = CountVectorizer()
data_new = transfer.fit_transform(data)

print(data_new.toarray()) # 统计每个样本特征词出现的个数
print(transfer.get_feature_names_out())

# [[0 1 1 1 0 1 1 0]
#  [1 1 1 0 1 1 0 1]]
# ['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']

中文分词,jieba

jieba.cut()

from idlelib.pyparse import trans

import jieba
from sklearn.feature_extraction.text import CountVectorizer

data = ["活着的意义,不是为了死去,而是为了活着本身。",
        "活着本身就有一种力量,这种力量支撑着我们度过苦难,也让我们在苦难中依然能够感受到生活的温暖。"]

data_new = []
for text in data:
    data_new.append(" ".join(list(jieba.cut(text))))

transformer = CountVectorizer()
X_transformed = transformer.fit_transform(data_new)
print(X_transformed.toarray())
print(transformer.get_feature_names_out())

# [[0 1 2 0 0 0 1 0 0 0 1 1 2 0 0 1 0 0 0]
#  [1 0 0 1 2 1 0 1 2 1 1 0 1 1 1 0 1 2 1]]
# ['一种' '不是' '为了' '依然' '力量' '度过' '意义' '感受' '我们' '支撑' '本身' '死去' '活着' '温暖'
#  '生活' '而是' '能够' '苦难' '这种']

2.3.3 Tf-idf文本特征提取

公式

API

from idlelib.pyparse import trans

import jieba
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer

data = ["活着的意义,不是为了死去,而是为了活着本身。",
        "活着本身就有一种力量,这种力量支撑着我们度过苦难,也让我们在苦难中依然能够感受到生活的温暖。"]

data_new = []
for text in data:
    data_new.append(" ".join(list(jieba.cut(text))))

transformer = TfidfVectorizer()
X_transformed = transformer.fit_transform(data_new)
print(X_transformed.toarray())
print(transformer.get_feature_names_out())

# Building prefix dict from the default dictionary ...
# Loading model from cache /var/folders/vv/y2k4cvj91fjbmw1cp4415wtr0000gn/T/jieba.cache
# [[0.         0.30814893 0.61629785 0.         0.         0.
#   0.30814893 0.         0.         0.         0.2192505  0.30814893
#   0.438501   0.         0.         0.30814893 0.         0.
#   0.        ]
#  [0.21314023 0.         0.         0.21314023 0.42628046 0.21314023
#   0.         0.21314023 0.42628046 0.21314023 0.15165103 0.
#   0.15165103 0.21314023 0.21314023 0.         0.21314023 0.42628046
#   0.21314023]]
# ['一种' '不是' '为了' '依然' '力量' '度过' '意义' '感受' '我们' '支撑' '本身' '死去' '活着' '温暖'
#  '生活' '而是' '能够' '苦难' '这种']
# Loading model cost 0.264 seconds.
# Prefix dict has been built successfully.

2.4 特征预处理


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

数值型数据的无量纲化

特征预处理API

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

2.4.1 归一化

通过对原始数据进行变换把数据映射到(默认为[0, 1])之间

公式
$$
X’ = \frac{x - min}{\max-min}
$$

$$
X” = X’ * (mx - mi) + mi
$$

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

API

transfer = MinMaxScaler()
data_new = transfer.fit_transform(data)

缺点:最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性(稳定性)较差,只适合传统精确小数据场景

2.4.2 标准化

通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内
$$
X’ = \frac{x - mean}{σ}
$$
作用于每一列,mean为平均值,σ为标准差

API

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


2.5 特征降维


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

正是因为在进行训练的时候,我们都是使用特征进行学习,如果特征本身存在问题或者特征之间相关性较强,对于算法学习预测会影响较大

两种降维方式

2.5.1 特征选择

数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征

方法

模块

过滤式

一、低方差特征过滤

删除低方差的一些特征

API

transfer = VarianceThreshold()
data_new = transfer.fit_transform(data)

二、相关系数
$$
r=\frac{n \sum x y-\sum x \sum y}{\sqrt{n \sum x^{2}-\left(\sum x\right)^{2}} \sqrt{n \sum y^{2}-\left(\sum y\right)^{2}}}
$$
特点

相关系数的值介于-1与+1之间,即-1 <= r <= 1,其性质如下:

API


2.6 主成分分析(PCA)


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

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

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

API


第三章 分类算法


3.1 sklearn转换器和估计器


转换器——特征工程的父类

特征工程的接口称之为转换器,其中转换器调用有这么几种形式

1、实例化(实例化的是一个转换器类(Transformer))

2、调用fit_transform(对于文档建立分类词频矩阵,不能同时调用)

标准化:

(x - mean) / std

fit_transform()

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

在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API

1、用于分类的估计器:

2、用于回归的估计器

3、用于无监督学习的估计器

1、实例化一个estimator

2、estimator.fit(x_train, y_train)计算——调用完毕,模型生成

3、模型评估


3.2 K-近邻算法


如果一个样本在特征空间中的k个最相似(即特征空间中最临近)的样本中的大多数属于某一个类别,则该样本也属于这个类别

来源:KNN算法最早是由Cover和Hart提出的一种分类算法

距离公式

两个样本的距离可以通过如下公式计算,又称欧式距离
$$
比如说,a(a1, a2, a3), b(b1, b2, b3)\ \sqrt{(a 1-b 1)^{2}+(a 2-b 2)^{2}+(a 3-b 3)^{2}}
$$

API

案例 预测鸢尾花

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler


def knn_iris():
    """
    使用KNN 算法对鸢尾花进行分类
    :return:
    """
    # 1、获取数据
    iris = load_iris()

    # 2、划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state = 6)

    # 3、特征工程:标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4、KNN算法预估器
    estimator = KNeighborsClassifier(n_neighbors = 3)
    estimator.fit(x_train, y_train)

    # 5、模型评估
    y_predict = estimator.predict(x_test)
    print("y_predict:" , y_predict)
    print("对比真实值和预测值:", y_test == y_predict)

    score = estimator.score(x_test, y_test)
    print("准确率:", score)
    return None

if __name__ == "__main__":
    knn_iris()
    
# y_predict: [0 2 0 0 2 1 1 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1 2]
# 对比真实值和预测值: [ True  True  True  True  True  True False  True  True  True  True  True
#   True  True  True False  True  True  True  True  True  True  True  True
#   True  True  True  True  True  True  True  True  True  True False  True
#   True  True]
# 准确率: 0.9210526315789473

优点

缺点

使用场景


3.3 模型选择与调优


3.3.1 交叉验证

交叉验证:将拿到的训练数据,分为训练和验证集,如 将数据分成4份,其中一份作为验证集,然后经过4次(组)的测试,每次都更换不同的验证集,即得到4组模型的结果,取平均值作为最终结果,又称4折交叉验证

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

模型选择与调优API

鸢尾花

def knn_iris_gscv():
    """
    使用KNN 算法对鸢尾花进行分类, 添加网格搜索和交叉验证
    :return:
    """
    # 1、获取数据
    iris = load_iris()

    # 2、划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state = 6)

    # 3、特征工程:标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4、KNN算法预估器
    estimator = KNeighborsClassifier(n_neighbors = 3)
    estimator.fit(x_train, y_train)

    # 加入网格搜索和交叉验证
    estimator = GridSearchCV(estimator, param_grid = {'n_neighbors': [1, 3, 5, 7, 9, 11]}, cv = 10)
    estimator.fit(x_train, y_train)

    # 5、模型评估
    y_predict = estimator.predict(x_test)
    print("y_predict:" , y_predict)
    print("对比真实值和预测值:", y_test == y_predict)

    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_)
    return None
  
# y_predict: [0 2 0 0 2 1 2 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1
#  2]
# 对比真实值和预测值: [ True  True  True  True  True  True  True  True  True  True  True  True
#   True  True  True False  True  True  True  True  True  True  True  True
#   True  True  True  True  True  True  True  True  True  True False  True
#   True  True]
# 准确率: 0.9473684210526315
# 最佳参数 {'n_neighbors': 11}
# 最佳结果 0.9734848484848484
# 最佳估计器 KNeighborsClassifier(n_neighbors=11)
# 交叉验证结果 {'mean_fit_time': array([0.00012665, 0.0001209 , 0.00011959, 0.00011954, 0.00012078,
#        0.0001174 ]), 'std_fit_time': array([1.49413711e-05, 1.09113690e-05, 5.32714825e-06, 4.85601935e-06,
#        5.19424300e-06, 2.41309756e-06]), 'mean_score_time': array([0.00033486, 0.00030804, 0.00029821, 0.00030265, 0.00033834,
#        0.00031242]), 'std_score_time': array([8.85420127e-05, 3.18315144e-05, 1.89715283e-05, 7.72137627e-06,
#        1.12072276e-04, 7.35798518e-06]), 'param_n_neighbors': masked_array(data=[1, 3, 5, 7, 9, 11],
#              mask=[False, False, False, False, False, False],
#        fill_value=999999), 'params': [{'n_neighbors': 1}, {'n_neighbors': 3}, {'n_neighbors': 5}, {'n_neighbors': 7}, {'n_neighbors': 9}, {'n_neighbors': 11}], 'split0_test_score': array([1., 1., 1., 1., 1., 1.]), 'split1_test_score': array([0.91666667, 0.91666667, 1.        , 0.91666667, 0.91666667,
#        0.91666667]), 'split2_test_score': array([1., 1., 1., 1., 1., 1.]), 'split3_test_score': array([1.        , 1.        , 1.        , 1.        , 0.90909091,
#        1.        ]), 'split4_test_score': array([1., 1., 1., 1., 1., 1.]), 'split5_test_score': array([0.90909091, 0.90909091, 1.        , 1.        , 1.        ,
#        1.        ]), 'split6_test_score': array([1., 1., 1., 1., 1., 1.]), 'split7_test_score': array([0.90909091, 0.90909091, 0.90909091, 0.90909091, 1.        ,
#        1.        ]), 'split8_test_score': array([1., 1., 1., 1., 1., 1.]), 'split9_test_score': array([0.90909091, 0.81818182, 0.81818182, 0.81818182, 0.81818182,
#        0.81818182]), 'mean_test_score': array([0.96439394, 0.95530303, 0.97272727, 0.96439394, 0.96439394,
#        0.97348485]), 'std_test_score': array([0.04365767, 0.0604591 , 0.05821022, 0.05965639, 0.05965639,
#        0.05742104]), 'rank_test_score': array([5, 6, 2, 3, 3, 1], dtype=int32)}

3.4 朴素贝叶斯算法


3.4.1 概率基础

扔出一个硬币,结果头像朝上

P(X):取值在[0, 1]

朴素:特征与特征之间是相互独立的

3.4.2 联合概率、条件概率与相互独立

3.4.3 贝叶斯公式

$$
P(C|W) = \frac{P(W|C)P(C)}{P(W)}
$$

W为给定文档的特征值(频数统计,预测文档提供),c为文档类别

应用场景:文本分类 (单词作为特征)

那么这个公式如果应用在分章分类的场景中,我们可以这样看:
$$
P(C|F1,F2,…) = \frac{P(F1,F2,…|C)P(C)}{P(F1,F2,…)}
$$
其中c可以是不同类别

公式分为三个部分:

3.4.4 拉普拉斯平滑系数

目的:防止计算出的分类概率为0
$$
P(F1|C) = \frac{Ni + α}{N + αm}
$$

3.4.5 API

def nb_news():
    '''
    用朴素贝叶斯算法对新闻进行分类
    :return: 
    '''
    # 1、获取数据
    news = fetch_20newsgroups(subset = 'all')
    
    # 2、划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)
    
    # 3、特征工程:文本特征抽取-tfidf
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)
    
    # 4、朴素贝叶斯算法预估器流程
    estimator = MultinomialNB()
    estimator.fit(x_train, y_train)
    
    # 5、模型评估
    # 方法一:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:" , y_predict)
    print("直接比对真实值和预测值:", y_test == y_predict)
    
    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:", score)
    
    return None
  
# y_predict: [ 4  9  4 ... 16  9 12]
# 直接比对真实值和预测值: [ True  True  True ...  True  True  True]
# 准确率为: 0.8406196943972836

优点:

缺点:


3.5 决策树


一、原理

二、信息熵的定义

$$
H(X)=-\sum_{i=1}^{n}P\left(x_{i}\right)\log_{b}P\left(x_{i}\right)
$$

三、决策树划分依据之一 信息增益

特征A对训练数据集D的信息增益g(D, A)定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
$$
g(D,A) = H(D) - H(D|A)
$$

信息熵计算
$$
H(D)=-\sum_{k=1}^{k}\frac{|C_{k}|}{|D|}log\frac{|C_{k}|}{|D|}
$$
条件熵的计算
$$
H(D|A)=\sum_{i=1}^{n}\frac{|D_{i}|}{|D|}H(D_{i}) = -\sum_{i=1}^{n}\frac{|D_{i}|}{|D|}\sum_{k=1}^{k}\frac{|D_{ik}|}{|Di|}log\frac{|D_{ik}|}{|Di|}
$$
Ck表示属于某个类别的样本数

tips:信息增益表示得知特征X的信息而息的不确定性减少的程度使得类Y的信息熵减少的程度

3.5.1 决策树API

def decision_iris():
    '''
    用决策树对鸢尾花进行分类
    :return:
    '''
    # 1、获取数据集
    iris = load_iris()

    # 2、划分数据集
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state = 6)

    # 3、决策树预估器
    estimator = DecisionTreeClassifier(criterion = "entropy")
    estimator.fit(x_train, y_train)

    # 4、模型评估
    # 方法一:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:", y_predict)
    print("直接比对真实值和预测值:", y_test == y_predict)

    # 方法二:计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率为:", score)
    return None
  
# y_predict: [0 2 0 0 2 1 2 0 2 1 2 1 2 2 1 1 2 1 1 0 0 2 0 0 1 1 1 2 0 1 0 1 0 0 1 2 1 2]
# 直接比对真实值和预测值: [ True  True  True  True  True  True  True  True  True  True  True  True
#   True  True  True False  True  True  True  True  True  True  True  True
#   True  True  True  True  True  True  True  True  True  True False  True
#   True  True]
# 准确率为: 0.9473684210526315

3.5.2 决策树可视化

1、保存树的结构到dot文件

优点:

缺点:

改进:


3.6 集成学习方法之随机森林


3.6.1 集成学习方法

集成学习通过建立几个模型组合来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和做出预测。这些预测最后结合成组合预测,因此优于任何一个单分类做出的预测

3.6.2 随机森林

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

3.6.3 随机森林原理过程

学习算法根据下列算法而建造每棵树:

3.6.4 API


第四章 回归与聚类算法


4.1 线性回归


应用场景

4.1.1什么是线性回归

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

公式:h(w) = w1x1 + w2x2 + w3x3 + b = wTx + b

其中w,x可以理解为矩阵:
$$
\mathrm{w}=\left(\begin{array}{c}b \ w_{1} \ w_{2}\end{array}\right), \mathrm{x}=\left(\begin{array}{c}1 \ x_{1} \ x_{2}\end{array}\right)
$$

线性回归当中线性模型有两种,一种是线性关系,另一种是非线性关系

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

1、损失函数

总损失定义为:
$$
J(\theta) = (h_w(x_1) - y_1)^2 + (h_w(x_2) - y_2)^2 + \cdots + (h_w(x_m) - y_m)^2
= \sum_{i=1}^{m} \left( h_w(x_i) - y_i \right)^2
$$

2、优化算法

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

线性回归经常使用的两种优化算法

​ w = (XTX)-1XTy

理解:X为特征值矩阵,y为目标值矩阵,直接求到最好的结果

缺点:当特征过多过复杂时,求解速度太慢并且得不到结果

$$
\begin{array}{l}w_{1}:=w_{1}-\alpha \frac{\partial \operatorname{cost}\left(w_{0}+w_{1} x_{1}\right)}{\partial w 1} \ w_{0}:=w_{0}-\alpha \frac{\partial \operatorname{cost}\left(w_{0}+w_{1} x_{1}\right)}{\partial w 1}\end{array}
$$

理解:α为学习速率,需要手动指定(超参数),α旁边的整体表示方向,沿着这个函数下降的方向找,最后就能找到山谷的最低点,然后更新W值

使用:面对训练数据规模十分庞大的任务,能够找到较好的结果

4.1.3 线性回归API

sklearn提供给我们两种实现的API,可以根据选择使用

from sklearn.datasets import fetch_openml
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor

import ssl
import certifi
from sklearn.model_selection import train_test_split

ssl._create_default_https_context = lambda: ssl.create_default_context(cafile=certifi.where())

def linear1():
    '''
    正规方程的优化方法对波士顿房价进行预测
    :return:
    '''
    # 1)获取数据
    boston = fetch_openml(name = 'boston', version = 1, as_frame = True)

    # 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)

    # 5)得出模型
    print("正规方程-权重系数为: \n", estimator.coef_)
    print("正规方程-偏置为: \n", estimator.intercept_)

    # 6)模型评估
    y_predict = estimator.predict(x_test)
    print("预测房价: \n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("正规方程-均方误差为: \n", error)

def linear2():
    '''
    梯度下降的优化方法对波士顿房价进行预测
    :return:
    '''
    # 1)获取数据
    boston = fetch_openml(name = 'boston', version = 1, as_frame = True)

    # 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()
    estimator.fit(x_train, y_train)

    # 5)得出模型
    print("梯度下降-权重系数为: \n", estimator.coef_)
    print("梯度下降-偏置为: \n", estimator.intercept_)

    # 6)模型评估
    y_predict = estimator.predict(x_test)
    print("预测房价: \n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("梯度下降-均方误差为: \n", error)

if __name__ == "__main__":
    # 代码1:正规方程的优化方法对波士顿房价进行预测
    linear1()
    # 代码2:梯度下降的优化方法对波士顿房价进行预测
    linear2()

#正规方程 - 权重系数为:
# [-0.64817766  1.14673408 - 0.05949444  0.74216553 - 1.95515269  2.70902585
#  - 0.07737374 - 3.29889391  2.50267196 - 1.85679269 - 1.75044624  0.87341624
#  - 3.91336869]
# 正规方程 - 偏置为:
# 22.621372031662272
# 预测房价:
# [28.22944896 31.5122308  21.11612841 32.6663189  20.0023467  19.07315705
#  21.09772798 19.61400153 19.61907059 32.87611987 20.97911561 27.52898011
#  15.54701758 19.78630176 36.88641203 18.81202132  9.35912225 18.49452615
#  30.66499315 24.30184448 19.08220837 34.11391208 29.81386585 17.51775647
#  34.91026707 26.54967053 34.71035391 27.4268996  19.09095832 14.92742976
#  30.86877936 15.88271775 37.17548808  7.72101675 16.24074861 17.19211608
#  7.42140081 20.0098852  40.58481466 28.93190595 25.25404307 17.74970308
#  38.76446932  6.87996052 21.80450956 25.29110265 20.427491   20.4698034
#  17.25330064 26.12442519  8.48268143 27.50871869 30.58284841 16.56039764
#  9.38919181 35.54434377 32.29801978 21.81298945 17.60263689 22.0804256
#  23.49262401 24.10617033 20.1346492  38.5268066  24.58319594 19.78072415
#  13.93429891  6.75507808 42.03759064 21.9215625  16.91352899 22.58327744
#  40.76440704 21.3998946  36.89912238 27.19273661 20.97945544 20.37925063
#  25.3536439  22.18729123 31.13342301 20.39451125 23.99224334 31.54729547
#  26.74581308 20.90199941 29.08225233 21.98331503 26.29101202 20.17329401
#  25.49225305 24.09171045 19.90739221 16.35154974 15.25184758 18.40766132
#  24.83797801 16.61703662 20.89470344 26.70854061 20.7591883  17.88403312
#  24.28656105 23.37651493 21.64202047 36.81476219 15.86570054 21.42338732
#  32.81366203 33.74086414 20.61688336 26.88191023 22.65739323 17.35731771
#  21.67699248 21.65034728 27.66728556 25.04691687 23.73976625 14.6649641
#  15.17700342  3.81620663 29.18194848 20.68544417 22.32934783 28.01568563
#  28.58237108]
# 正规方程 - 均方误差为:
# 20.627513763095397
# 梯度下降 - 权重系数为:
# [-0.53087278  0.90066527 - 0.41998411  0.78452826 - 1.66411434  2.81985555
#  - 0.1400385 - 3.06040513  1.63836989 - 0.93857943 - 1.70111028  0.86004495
#  - 3.89817913]
# 梯度下降 - 偏置为:
# [22.63581926]
# 预测房价:
# [28.3384972  31.61218432 21.46396158 32.65581505 20.30729174 19.10061829
#  21.38069526 19.53714795 19.75519481 32.800326   21.36875982 27.27413464
#  15.63267453 19.98927317 36.99754756 18.67182959  9.69770926 18.70124007
#  30.83563162 24.33599091 19.06795404 34.05033349 29.50094527 17.39985907
#  34.80737074 26.48659296 34.31171118 27.41944575 19.08627983 15.87222231
#  30.79178744 14.51153831 37.45078101  8.67125435 16.46208808 16.83277864
#  7.68156071 19.80748244 40.48142444 29.2664118  25.31618817 17.8572737
#  39.25712808  6.68761008 21.56415312 25.05111149 20.88999669 20.69732958
#  17.02796236 26.26659763  9.66659845 27.17979966 30.62987402 16.65438921
#  9.58865169 35.4414963  31.47834199 22.986851   17.64076732 21.95875243
#  23.64418027 23.96574351 20.44045063 38.17989465 25.74351719 19.66462643
#  14.15722486  6.66995377 42.40651742 21.89014826 16.70608227 22.7040728
#  40.88428941 21.79554256 36.87164444 27.16304009 21.95214659 20.7841799
#  25.38449507 23.84834719 31.51118485 20.25375911 23.99097276 31.4576435
#  27.23684728 20.89030294 29.06532415 22.1043287  26.74748695 18.82579376
#  25.18329361 23.9334069  19.94497257 17.6087464  15.47370814 18.30864154
#  24.58487929 16.74665111 20.65366946 26.82001204 20.67787656 17.98854794
#  24.13807094 23.27245058 20.34099272 36.49425084 16.10123196 22.49570103
#  32.66186733 33.62779611 20.61225142 25.97666765 23.30780317 17.74838749
#  21.55604458 21.82380492 27.54772173 25.30744437 23.6853392  14.44559773
#  15.61858598  3.65291912 29.24019186 20.68377264 22.34013216 28.08768094
#  28.35643226]
# 梯度下降 - 均方误差为:
# 21.17625015763062

分析

回归当中的数据大小不一致,是否会导致结果影响较大。所以需要做标准化处理

回归性能评估

均方误差(Mean Squared Error) MSE评价机制
$$
M S E=\frac{1}{m} \sum_{i=1}^{m}\left(y^{i}-\bar{y}\right)^{2}
$$

tips:yi为预测值,ȳ为真实值

对比

梯度下降正规方程
需要选择学习率不需要
需要迭代求解一次运算得出
特征数量较大可以使用需要计算方程,时间复杂度高O(n3)

选择:

扩展-关于优化方法GD、SGD、SAG

1、GD

梯度下降,原始的梯度下降法需要计算所有样本的值才能够得出梯度,计算量大,所以后面才会有一系列的改进

2、SGD

随机梯度下降,是一个优化方法,它在一次迭代时只考虑一个训练样本

3、SAG

随机平均梯度法,由于收敛的速度太慢,有人提出SAG等基于梯度下降的算法

Scikit-learn:岭回归、逻辑回归等当中都会有SAG优化


4.2 欠拟合与过拟合


欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象(模型过于简单)

过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象(模型过于复杂)

原因以及解决办法

4.2.1 正则化类别

1、L2正则化

$$
J(w)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{w}\left(x_{i}\right)-y_{i}\right)^{2}+\lambda \sum_{j=1}^{n} w_{j}^{2}
$$

tips:m为样本数,n为特征数

2、L1正则化


4.3 线性回归的改进-岭回归



4.4 分类算法-逻辑回归与二分类



4.5 模型保存和加载



4.6 无监督学习-K-means算法



4.7 总结


#Python#机器学习