机器学习

00-课程介绍

集成后文档比较大,加载图片可能服务器返回 503 错误,所以可以点击链接访问原始网页:

https://cloud.seatable.cn/dtable/external-links/621babd7e22b4ceb88ec/

课程介绍

黑马出品的三天入门机器学习课程,不介绍具体算法实现,简单介绍相关的库怎么使用。

视频链接:https://www.bilibili.com/video/BV1nt411r7tj

个人目标:了解机器学习基本原理,了解常用库和技术,可以根据案例做一个小 demo。

机器学习:属于人工智能的一个技术实现分支,深入研究需要扎实的数理基础(高数,统计,线代等),多元统计分析(判别,聚类,回归等),计算机基础(c++ java python)。

其他资料:Sklearn 库:https://scikit-learn.org/stable/modules/linear_model.html

其他参考笔记,在附件列

目录

第一章:机器工程概述

第二章:特征工程(数据集,特征工程,特征抽取,预处理,数据降维,主成分分析)

第三章:分类算法

第四章:回归算法+聚类算法

01-人工智能概述

机器学习概述+特征工程

机器学习是人工智能的一部分,原理部分需要很深的数学(多元统计分析)+计算机功底(CPP Python),短期学会难度较大。

人工智能包括机器学习,机器学习包括深度学习。

机器学习包括:传统预测,图像视频识别,自然语言处理,数据挖掘。

机器学习是一种人工智能的子领域,涉及计算机程序能够从数据中自动学习,并改进其性能的技术。机器学习的目标是让计算机能够从数据中学习,并预测未来的结果。

人工智能是一个更广泛的概念,涵盖了机器学习以及其他一些技术,例如自然语言处理、计算机视觉等。人工智能的目标是创建能够模拟人类智能的计算机系统。

02-什么是机器学习

从数据中自动分析获取模型,利用模型对未知数据进行预测(数据+模型+预测)。

特征值(多个属性)+目标值

03-机器学习算法分类

目标值是离散值(布尔值)——类别-分类——K 近邻算法,贝叶斯分类、决策树随机森林、逻辑回归

目标值是连续值(数值)——回归——线性回归,岭回归

没有目标值——无监督学习(输入的数据没有明确结果)—— kmeans 聚类

04-机器学习开发流程

  1. 获取数据(公开数据,或者公司内部数据)

  2. 数据预处理(去掉脏数据,补充缺失数据)

  3. 特征工程(提取特征值和特征向量)

  4. 机器学习(获取模型)

  5. 模型评估(模型是否满足测试数据,如果不满足,重复第二步)

  6. 模型上线

05-学习框架和资料介绍

算法是核心,大量数据和计算能力(硬件水平)是基础

定位是什么?如果是算法工程师,需要专业技术过硬

实际上大部分工程师主要是分析数据,然后应用已有的模型等(调参数+优化模型)

快速学习过程(适合了解)

  • 入门介绍
  • 实战类书籍(某框架学习)
  • 机器学习(西瓜书,周志华)
  • 统计学习方法(李航)
  • 深度学习(花书)

06-可用数据集

公司内部的用户数据集;或者其他搜索引擎的数据集,学习阶段可使用下面几个数据集

Scikit-learn、kaggle、UCI

我们这里使用 sklearn(分类、回归、聚类、降维、特征工程、模型选择等)

07-sklearn 数据集使用

1、scikit-learn 库 API 介绍

scikit-learn 内置了小数据集,初始直接下载到本地;同时也支持联网下载大型数据集。

2、小数据集

1
2
3
4
5
6
7
from sklearn import sklearn

# sklearn.datasets 数据集
# 鸢尾花数据
sklearn.datasets.load_iris()
# 波士顿房地产数据
sklearn.datasets.load_boston()

不同数据集的返回值可能不同,包括特征,样本数量,目标类别等。

以鸢尾花 iris 结果,分析返回值结果。返回值是 datasets.base.Bunch 字典格式,包括下面字段。

1
2
from sklearn.datasets import load_iris
iris = load_iris()
1
2
3
4
5
data: 特征数据数组,二维数组
target: 标签数组
DESCR: 数据描述
feature_names: 特征名
target_names: 标签名

3、大数据集

1
2
3
4
# 加载线上大数据集
datasets.fetch_iris(data_home = None, subset="train")
# 第一个参数,data_home, 表示数据集下载到本地的目录,默认下载到 ~ 中
# 第二个参数, subset,表示子集类型(train, test, all),训练集,测试集,全部集

4、数据集划分

数据集:训练数据(训练构建模型)和测试数据(评估模型是否有效)

通常训练数据越多,模型越准确(70%-80%)

1
2
3
from sklearn import sklearn

sklearn.model_selection.train_test_split(x, y, test_size, random_state, *options)

参数说明:

1
2
3
4
5
6
- x 数据集特征值
- y 数据集特征值
- test_size 测试集合的大小(float, 0.8)
- random_state 随机数种子
- return 返回值(训练集特征值,测试集特征值,训练集目标值,测试集目标值)
	x_train, x_test, y_train, y_test = train_test_aplit()

5、demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

def datasets_demo():
  """
  learn sklearn dataset
  """
  # load data from local dataset
  iris = load_iris()
  # print("iris datasets test", iris["DESCR"])
  # print(iris.feature_names, iris.target_names)
  # print(iris.data, iris.data.shape)
  # split data into two subset, train set and target set
  x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size = 0.2, random_state = 20)
  print(x_train, x_test, y_train, y_test)
  return None

if __name__ == "__main__":
  datasets_demo()

结果

数据集描述:iris[‘DESCR’],包括数据集的样本容量,四个变量,统计学参数等

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Iris plants dataset
--------------------

**Data Set Characteristics:**

:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
    - sepal length in cm
    - sepal width in cm
    - petal length in cm
    - petal width in cm
    - class:
            - Iris-Setosa
            - Iris-Versicolour
            - Iris-Virginica

:Summary Statistics:

============== ==== ==== ======= ===== ====================
                Min  Max   Mean    SD   Class Correlation
============== ==== ==== ======= ===== ====================
sepal length:   4.3  7.9   5.84   0.83    0.7826
sepal width:    2.0  4.4   3.05   0.43   -0.4194
petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)
============== ==== ==== ======= ===== ====================

特征值的名字:iris.feature_names

1
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

特征值:iris.data.shape

1
(150, 4)

08-字典特征抽取

2.2 特征工程

Feature engineering

特征工程:使用专业背景知识处理数据,使得特征在机器学习算法中更好的发挥过程。

为什么用特征工程:各个公司的机器学习算法都差不多(pytorch),主要区别是数据集和特征值。例如百度的搜索数据和抖音的播放数据,使用的算法是类似的,但是数据集和特征值完全不同,特征值决定了最终机器学习的结果。

pandas 数据清洗;数据处理

sklearn 特征工程(特征抽取,特征预处理,特征降维)

2.3 特征抽取

特征提取:把离散数据(字符串)或者连续的数据(数值)进行分析,转换成数学算法可以提取的数据。包括字典特征提取(离散数据),文本特征提取,图像特征提取(深度学习,比较复杂,本课程不介绍)

1
sklearn.feature_extraction

字典特征提取:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 字典向量化(默认抽取稀疏矩阵)
sklearn.feature_extration.DictVectorizer(sparse = True)

# 字典转换成向量
DictVectorizer.fit_transform()

# 向量转换成字典
DictVectorizer.inverse_transform()

# 获取描述信息
DictVectorizer.get_feature_names()

矩阵 matrix

向量 vector

稀疏矩阵:sparse matrix:在矩阵中,若数值为0的元素数目远远多于非0元素的数目,并且非0元素分布没有规律时,则称该矩阵为稀疏矩阵;与之相反,若非0元素数目占大多数时,则称该矩阵为稠密矩阵。定义非零元素的总数比上矩阵所有元素的总数为矩阵的稠密度。稀疏矩阵的计算速度更快,只对非零元素进行操作。

例如,右侧是一个实际矩阵,左侧是稀疏矩阵。实际数据中不同类别很多,矩阵中0比较多,占用内存计算较大。所以改成稀疏矩阵实现,计算较少。

术语是热编码-one hot

1
2
3
4
5
def dict_extract_demo():
    from funds_info import funds
    transfer = DictVectorizer(sparse=False)
    new_funds = transfer.fit_transform(funds)
    return None

实际上,字典类型的数据,类似单选列,不同的值是不同的字符串,那么为什么不用 1234 表示若干选项呢?因为1234实际上有不同的权重,混合型基金是1,FOF 基金是4,实际上不是4倍的关系。所以使用 one-hot 处理,增加两个布尔类型字段,是否是混合型基金,是否是 FOF 基金,值为0-1,这样就避免了4倍的关系,结果就是系数矩阵(N个字段M个特征,实际上只有N个稀疏的1数据,其他都是0)

09-文本特征抽取 CountVectorizer

对英文文本数据进行特征值化

1
2
3
from sklearn import sklearn

sklearn.feature_extration.text.CountVectorize(stop_words = [])

默认处理英文(以单词作为特征,不是句子或者字母作为特征)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def en_text_extract_demo():
    novel = [
        'Rosaria had to be the one stuck carrying the unconscious person',
        'a tremor occurs, which causes another small avalanche to come hurling their way'
    ]
    vectorizer = CountVectorizer()
    X = vectorizer.fit_transform(novel)
    print(X.shape)
    print(X.toarray())
    # note: 视频教程旧版是 get_feature_names() ,2024 新版本 sklearn 是 get_feature_names_out()
    # print(vectorizer.get_feature_names())
    # 英文有自动分词器,中文没有,需要使用 jieba 等分词库进行处理
    print(vectorizer.get_feature_names_out())

10-中文文本特征抽取

单独使用 CountVectorize 可以处理英文,不能处理中文(没有分词)可以使用 jieba 等第三方库处理分词

分词函数

1
2
3
4
import jieba

def cut_words(text):
  return " ".join(list(jieba.cut(text)))

中文预处理+特征抽取

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def zhcn_text_extract_demo():
    zhcn_novel = [
        '纯真的绫华小姐一点也没有怀疑',
        '绫华从荷包中拿钱的动作做了一半',
        '今天一大早就去离岛接待了一下',
    ]
    
    # 中文分词
    en_novel = []
    for novel in zhcn_novel:
        en_novel.append(cut_words(novel))
    # 中文文本进行特征提取
    vectorizer = CountVectorizer(stop_words = ['一半', '一下'])
    X = vectorizer.fit_transform(en_novel)
    print(X.shape)
    print(X.toarray())
    print(vectorizer.get_feature_names_out())

结果

1
2
3
4
5
6
(3, 23)
[[0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 1 0 1 1 1 0 0 1]
 [0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0]
 [1 0 0 0 1 1 1 0 0 0 1 1 0 0 1 0 1 0 0 0 0 1 0]]
['一大早' '一点' '中拿钱' '亏心事' '人员' '今天' '其它' '其实' '动作' '反应' '商会' '国家' '小姐' '怀疑'
 '接待' '没有' '离岛' '纯真' '绫华' '缘故' '荷包' '赶过来' '这么']

11-文本特征抽取 TfidfVevtorizer

上面的案例中,我们按照文本出现的频率进行抽取,但是通常会包括通用词汇,这不是我们想要的结果。该如何处理某个词或短语在多篇文章中出现的次数高这种情况?

关键词:我们希望得到在某篇文章中出现较多,但是在其他文章出现较少的词汇。

TF-IDF文本特征提取

TF-IDF的主要思想是: 如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。

TF-IDF作用: 用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。

  • TF:词频 (term frequency,tf) 指的是某一个给定的词语在该文件中出现的频率。

  • IDF:逆向文档频率 (inverse document frequency,idf) 是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到。

最终这两个的乘积就是 TF-IDF,可以理解为重要程度

实际计算 TF-IDF 的案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
TF-IDF 计算
TF 词频 (term frequency,tf)
IDF 逆向文档频率

两个关键词 “经济", “非常”
全部1000篇文章-语料库
其中100篇文章含有-"非常"
其中10篇文章含有~“经济”

分析其中两篇文章

文章A(100词) : 出现了10次“经济”
tf:10/100 = 0.1
idf:lg(1000/10) = 2
tfidf = 0.1 * 2 = 0.2

文章B(100词) : 出现了10次“非常”
tf:10/100 = 0.1
idf: lg(1000/100) = 1
tfidf = 0.1 * 1 = 0.1

API 和上述类似

1
from sklearn.feature_extraction.text import TfidfVectorizer

Tf-idf 是分类机器学习算法进行文章分类中前期数据处理方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def tfidf_extract_demo():
    # 中文案例
    zhcn_novel = [
        '纯真的绫华小姐一点也没有怀疑荧反应这么大其实是她做了亏心事的缘故',
        '绫华从荷包中拿钱的动作做了一半',
        '今天一大早就去离岛接待了一下从其它国家赶过来的商会人员',
    ]
    en_novel = []
    for novel in zhcn_novel:
        en_novel.append(cut_words(novel))
    vectorizer = TfidfVectorizer(stop_words = ['一半', '一下'])
    X = vectorizer.fit_transform(en_novel)
    print(X.toarray())
    print(vectorizer.get_feature_names_out())

第二句的结果,中拿钱,动作,荷包,绫华,结果比较高。因为内容比较短,所以差异不明显。

1
2
3
4
5
6
7
 [0.         0.         0.52863461 0.         0.         0.
  0.         0.         0.52863461 0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.40204024 0.         0.52863461 0.         0.        ]

['一大早' '一点' '中拿钱' '亏心事' '人员' '今天' '其它' '其实' '动作' '反应' '商会' '国家' '小姐' '怀疑'
 '接待' '没有' '离岛' '纯真' '绫华' '缘故' '荷包' '赶过来' '这么']

如果内容较长,那么有用的信息会相对多一些

12-数据预处理-归一化

目标

  • 了解数值型数据、类别型数据特点

  • 应用MinMaxScaler实现对特征数据进行归一化

  • 应用StandardScaler实现对特征数据进行标准化

什么是特征预处理

为什么进行特征归一化和标准化?

特征预处理:使用一些转换函数,让原始数据更便于用算法处理,包括归一化和标准化。

净值 最大回撤 夏普比率 内部占比
基金A 1.00元 0.5% 1 0.5%
基金B 1.50元 2.5% 2 0.1%
基金C 0.5元 1% 3 0.2%

例如不同特征值的单位不同,范围不动,标准差不同,用算法处理不方便。

特征预处理API

1
sklearn.preprocessing

为什么我们要进行归一化/标准化:特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响 (支配) 了目标结果,使得一些算法无法学习到其它的特征。所以使用归一化和标准化进行处理,使得不同的特征转换成相同量纲的特征。

归一化

简单说,就是把特征值的全部范围区间,缩小到统一的范围区间(例如 0~1)

其中(用净值举例)

max 表示某个特征值最大值 1.5元

min 表示某个特征值最小值 0.5元

mx 表示归一化的范围最大值,默认1

mi 表示归一化的范围最小值,默认0

X` = (1-0.5)/(1.5 - 0.5) = 0.5 / 1 = 0.5

X`` = 0.5 * (1 - 0) + 0 = 0.5

就得出归一化的值 0.5

净值(归一化)
基金A 0.5
基金B 1
基金C 0

API

1
sklearn.preprocessing.MaxMinScaler(feature_range=(0, 1))

案例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from sklearn.preprocessing import MaxMinScaler
import pandas as pd

def minmax_demo():
    # 使用 pandas 读取本地数据
    data = pd.read_csv('data/iris.csv')
    # 获取全部行和前三列
    data = data.iloc[:, :3]
    # 实例化转换器
    transfer = MaxMinScaler()
    # 调用 fit_transform 进行归一化
    data_new = transfer.fit_transform(data)
    print(data_new)

13-数据预处理-标准化

如果数据存在极端值,数据归一化可能被极端值影响。所以归一化的鲁棒性较差,适合传统小数据集,精确范围的数据集。

所以使用数据标准化进行处理。

标准化:把数据处理到均值为0,标准差为1的范围内

  • 归一化: 如果出现异常点,影响了最大值和最小值,那么结果显然会发生变化

  • 标准化: 如果出现异常点,由于具有一定数据量,少量的异常点,对于平均值的影响并不大,从而方差改变较小。 

1
sklearn.preprecessing.StandardScaler()

适合于已有的样本较多,嘈杂大数据场景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def standard_demo():
    # 使用 pandas 读取本地数据
    data = pd.read_csv('data/iris.csv')
    # 获取全部行和前三列
    data = data.iloc[:, :3]
    # 实例化转换器
    transfer = StandardScaler()
    # 调用 fit_transform 进行归一化
    data_new = transfer.fit_transform(data)
    print(data_new)

14-降维

学习目标

  • 应用VarianceThreshold实现删除低方差特征

  • 了解相关系数的特点和计算

  • 应用相关性系数,实现特征选择

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