离散化

1. cut

1
2
3
4
5
6
7
8
9
labels = list('ABCD')
height = np.array([173,192,186,167,159,159,176,160,162,167])
height = pd.cut(height,4,labels=labels)
print(height)

/*
['B', 'D', 'D', 'A', 'A', 'A', 'C', 'A', 'A', 'A']
Categories (4, object): ['A' < 'B' < 'C' < 'D']
*/

2. qcut

1
2
3
4
5
6
7
8
9
10
#每一段都是均分             
height = np.array([173,192,186,167,159,159,176,160,162,167])
height = pd.qcut(height,4)
print(height)

/*
[(167.0, 175.25], (175.25, 192.0], (175.25, 192.0], (160.5, 167.0], (158.999, 160.5], (158.999, 160.5], (175.25, 192.0], (158.999, 160.5], (160.5, 167.0], (160.5, 167.0]]
Categories (4, interval[float64, right]): [(158.999, 160.5] < (160.5, 167.0] < (167.0, 175.25] <
(175.25, 192.0]]
*/

哑变量编码

对于需要分类的变量进行哑变量编码或者one hot编码以方便距离或相似度的计算

eg, 性别/星期/颜色等分类变量的度量

pandas库中的get_dummies()函数可以实现分类变量的哑变量编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gender = np.array(['M','F','M','F',None,'M','F','M','F'],prefix='Gender')
ybl = pd.get_dummies(gender)
print(ybl)

/*
Gender_F Gender_M
0 0 1
1 1 0
2 0 1
3 1 0
4 0 0
5 0 1
6 1 0
7 0 1
8 1 0

*/

什么是机器学习

  1. 从数据中学习 特征值 + 目标值
  2. 学习结果为模型
  3. 预测、识别…

机器学习开发流程

  1. 获取数据
  2. 数据处理
  3. 特征工程
  4. 机器学习算法训练 + 模型
  5. 模型评估
  6. 应用

入门

例子

1
比如有🚚和🚗,我怎么让机器去识别?
image-20230601190609584
  • 特征(维度) Feature

    1
    车长   车宽   车高

    这样就是判别是否为卡车还是轿车,so 我们也称它有三个维度

    image-20230601190246118
  • 算法

    1
    我现在知道了车宽和车高去判断卡车还是轿车,只需要根据已有的样本空间去判断距离他们的远近即可
    image-20230601190530813
  • 标签 Label

    1
    就是卡车和货车
  • 预测 Prediction

    1
    未知的标签,从已知的特征中预测出来

监督学习与非监督学习

监督学习(有目标值)

监督学习是以任务为驱动的方法

这里任务 -----> 就是标签(判断是否为🚚, 判断百公里油耗为多少)

这里就可以看出来,非监督学习就是没有标签

1
2
3
预测股票
预测某人50岁得某病的可能
判断物体是什么

分类任务(离散)

image-20230601191124148 image-20230601191318163

回归任务(连续)

image-20230601191218514 image-20230601191450551

非监督学习(无目标值)

就是没有标签,让你胡乱推测

  • 比如你去百度搜索某个东西,他会预测你是不是想买,或者想要了解,就会给你推送链接
  • 分析用户行为,游戏氪金,大佬就被割韭菜,大数据杀熟
  • 基因组,判断每一串基因对人类的影响

聚类

image-20230601192117920

训练,验证,测试与评估

有点乱七八糟的不好理解 多写写代码就懂了

1.训练

总结数据的信息,从中学习有用的规律

2.验证

不参与模型参数的求解 但是 参与模型的学习过程

更多的是属于训练过程

我理解的就是一个做课后作业的过程,查缺补漏

3.测试

与训练过程和模型绝缘用来评估模型的最终效果

属于测试过程

我理解就是期末考试

4.评估

根据指标来判断模型是好是坏

  • 腾讯医疗-癌症预测100000

    1. 训练集80000

      1
      用于 训练和验证
    2. 测试集20000

      1
      用于 评估

Sklearn

1. Sklearn数据集

1
2
3
sklearn.databasets
load_* 获取小规模数据集
fetch_* 获取大规模数据集

1.1 sklearn小数据集

例如我要引用鸢尾花的小规模的数据集就可以使用

1
sklearn.databasets.load_iris()

波士顿房价数据集

1
sklearn.databasets.load_boston()

1.2 sklearn大数据集

1
sklearn.databasets.fetch_20newsgroups(data_home=None,subset='train')
  • subset: ‘train’或者’test’,’all‘
  • 训练集的训练,测试,全部

1.3 数据集的返回值

  • databasets.base.Bunch  (字典)
    dict['key'] = values
    
    1
    2
    3
    4
    5

    - data:特征值

    - ```
    iris['data']
    - target:标签值 - ```python iris.target
    1
    2
    3
    4
    5

    - DESCR:数据描述

    - ```
    iris.DESCR
    - feature_name:特征名 - ``` iris.feature_names
    1
    2
    3
    4
    5

    - target_name:标签名

    - ```
    iris.target_names

1.4 数据集的划分

  • 训练集:70% 80% 75%
  • 测试集:30% 20% 25%
1
2
3
4
5
6
7
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("训练集的特征值:\n",x_train,x_train.shape)
print("测试集的特征值:\n",x_test,x_test.shape)
print("训练集的目标值:\n",y_train,y_train.shape)
print("测试集的目标值:\n",y_test,y_test.shape)

特征工程

数据和特征决定了机器学习的上线,模型和算法知识在逼近这个上限

1
就是处理数据

特征工程内容

  • 特征提取
    • 机器学习算法 - 统计方法 - 数学公式
    • 例如:文本类型 -> 数值
    • 类型 -> 数值
      • 这里可以用One-hot编码或者哑变量
  • 特征预处理

  • 特征降维

特征提取

1. 将数据转换为可用于机器学习的数字特征

就是为了计算机更好的理解数据

  • 字典特征提取(特征离散化)
  • 文本特征提取
  • 图像特征提取

2. 特征提取API

1
sklearn.feature.extraction

字典特征提取

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

1
from sklearn.feature_extraction import DictVectorizer
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
28
29
30
31
32
33
34
35
36
37
38
39
import pandas as pd
import numpy as np

from sklearn.feature_extraction import DictVectorizer

"""
字典特征抽取
"""


def dict_demo():
dict = [{'city': '上海', 'temperature': 100},
{'city': '北京', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]

# 1.实例化一个转换器类
transfer = DictVectorizer()

# 2.调用fit_transform
# 返回了sparse稀疏矩阵 将非零值 按位置表示 可以节省内存 提高加载效率
data = transfer.fit_transform(dict)
print("data_dict:\n", data)
print("特征名字:\n", transfer.feature_names_)
"""
data_dict:
(0, 0) 1.0
(0, 3) 100.0
(1, 1) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
"""


if __name__ == '__main__':
dict_demo()

应用场景

  • 当数据集中类别特征比较多的情况下

    1
    2
    1.将数据集中的特征=》字典类型
    2.DictVectorizer转换
  • 当本身拿到的数据就是字典类型就可以用字典特征提取

文本特征提取

单词 作为 特征

句子、短语、单词、字母

1
特征:特征词

英文文本

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
28
29
from sklearn.feature_extraction.text import CountVectorizer

def count_demo():
data = ["Life is short,i like python",
"Lift is too long,i dislike python"]
text = CountVectorizer()

sparse = text.fit_transform(data)
print(sparse)
print("特征名字:\n", text.get_feature_names_out())
"""
(0, 2) 1
(0, 1) 1
(0, 7) 1
(0, 4) 1
(0, 6) 1
(1, 1) 1
(1, 6) 1
(1, 3) 1
(1, 8) 1
(1, 5) 1
(1, 0) 1
特征名字:
['dislike' 'is' 'life' 'lift' 'like' 'long' 'python' 'short' 'too']
"""


if __name__ == '__main__':
count_demo()

中文文本

由于英文每个单词之间默认就是按照空格隔开,但是中文"你好"这种就没有空格

所以要借助一些分词工具 例如jieba分词…

这里引出一个概念:停用词 stop_words

不止是中文这种,比如想一些未知的文本不容易进行分词的就可以使用停用词不将其进入

停用词表

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
28
29
30
31
32
33
34
from sklearn.feature_extraction.text import CountVectorizer
import jieba

def chinescount_demo():
data = ["引力,电磁力,强与弱相互作用力——四大基本力是我掌控的权能,是我永恒的冠冕,是我不朽的王座 。",
"无知愚昧之物称我为暴君,但是智者,以我为王。",
"有人对我闻风丧胆,有人对我顶礼膜拜,他们,都同样臣服于我。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))

trans = CountVectorizer()
res = trans.fit_transform(data_new)
print("转换结果:\n",res.toarray())
print("特征名字:\n", trans.get_feature_names_out())
"""
转换结果:
[[1 0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 0 0]
[0 1 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0]
[0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 1 1 1]]
特征名字:
['不朽' '之物' '他们' '但是' '冠冕' '力是' '同样' '四大' '基本' '引力' '愚昧' '掌控' '无知' '智者'
'暴君' '有人' '权能' '永恒' '王座' '电磁力' '相互作用' '臣服于' '闻风丧胆' '顶礼膜拜']
"""

def cut_word(text):
"""
进行中文分词
"""
return " ".join(list(jieba.cut(text)))

if __name__ == '__main__':
chinescount_demo()

但是按照这种分类会有一个弊病,比如说文章中有很多 因为 、所以 、…这样的词,在别的文章中同样也有很多,这样就会导致特征值的抽取中存在错误

Tf-idf文本特征提取

如果某个词或者短语,在一篇文章中出现的概率高,并且在其它文章中很少出现,则认为这个词或者短语具有很好的类别区分能力,适合用来分类

image-20230603201325407

总结:

TF-IDF就是衡量一个词或短语的重要程度

  • TF - 词频

  • IDF - 逆向文档频率 是一个词语普遍重要性的度量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    比如现在
    1000篇文章 - 语料库
    100篇文章 - ”非常“
    10篇文章 - ”经济

    两篇文章
    文章A(100词):10次“经济” TF-IDF = TF x IDF = 0.1 X 2 = 0.2
    tf: 10/100 = 0.1
    idf: lg 1000/10 = 2

实用

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba

def chinescount_demo():
data = ["引力,电磁力,强与弱相互作用力——四大基本力是我掌控的权能,是我永恒的冠冕,是我不朽的王座 。",
"无知愚昧之物称我为暴君,但是智者,以我为王。",
"有人对我闻风丧胆,有人对我顶礼膜拜,他们,都同样臣服于我。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))

trans = TfidfVectorizer()
res = trans.fit_transform(data_new)
print("转换结果:\n",res.toarray())
print("特征名字:\n", trans.get_feature_names_out())
"""
转换结果:
[[0.28867513 0. 0. 0. 0.28867513 0.28867513
0. 0.28867513 0.28867513 0.28867513 0. 0.28867513
0. 0. 0. 0. 0.28867513 0.28867513
0.28867513 0.28867513 0.28867513 0. 0. 0. ]
[0. 0.40824829 0. 0.40824829 0. 0.
0. 0. 0. 0. 0.40824829 0.
0.40824829 0.40824829 0.40824829 0. 0. 0.
0. 0. 0. 0. 0. 0. ]
[0. 0. 0.33333333 0. 0. 0.
0.33333333 0. 0. 0. 0. 0.
0. 0. 0. 0.66666667 0. 0.
0. 0. 0. 0.33333333 0.33333333 0.33333333]]
特征名字:
['不朽' '之物' '他们' '但是' '冠冕' '力是' '同样' '四大' '基本' '引力' '愚昧' '掌控' '无知' '智者'
'暴君' '有人' '权能' '永恒' '王座' '电磁力' '相互作用' '臣服于' '闻风丧胆' '顶礼膜拜']

"""

def cut_word(text):
"""
进行中文分词
"""
return " ".join(list(jieba.cut(text)))

if __name__ == '__main__':
chinescount_demo()

特征提取总结

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba


"""
字典特征提取
"""

def dict_count():
dict = [{'city': '上海', 'temperature': 100},
{'city': '北京', 'temperature': 60},
{'city': '深圳', 'temperature': 30}]
transfer = DictVectorizer()
data = transfer.fit_transform(dict)
print("字典特征提取:\n",data.toarray())

def english_count():
data = ["Life is short,i like like like python",
"Life is too long,i dislike python"]
transfer = CountVectorizer()
data = transfer.fit_transform(data)
print("英文文本提取:\n",data.toarray())

def chinese_count():
chinese_data = ["蒸汽与机械的浪潮中,谁能触及非凡?历史和黑暗的迷雾里,又是谁在耳语?我从诡秘中醒来,睁眼看见这个世界:",
"枪械,大炮,巨舰,飞空艇,差分机;魔药,占卜,诅咒,倒吊人,封印物……光明依旧照耀,神秘从未远离,这是一段“愚者”的传说。 ",
"然而一句,半睡半醒之时,意志总是飘忽如同烟雾,难以控制,难以收束,他再怎么努力,依旧忍不住思维发散,杂念浮现。",
"  看来我还没有真醒,还在梦里……等下说不定还会出现自以为已经醒了,实际依然在睡的情况……对类似遭遇不算陌生的周明瑞竭力集中意志,以彻底摆脱黑暗和迷幻的桎梏。",
"  照耀视线先是模糊,继而蒙上了淡淡的绯红,目光所及绯红,周明瑞看见面前是一张原木色泽的书桌,正中央放着一本摊开的笔记,纸张粗糙而泛黄,抬头用奇怪的字母文字书写着一句话语,墨迹深黑,醒目欲滴。"]
transfer = CountVectorizer()
data = []
for i in chinese_data:
data.append(" ".join(jieba.cut(i)))
datas = transfer.fit_transform(data)
print(datas)
print(transfer.get_feature_names_out())

def TF_IDF():
chinese_data = ["蒸汽与机械的浪潮中,谁能触及非凡?历史和黑暗的迷雾里,又是谁在耳语?我从诡秘中醒来,睁眼看见这个世界:",
"枪械,大炮,巨舰,飞空艇,差分机;魔药,占卜,诅咒,倒吊人,封印物……光明依旧照耀,神秘从未远离,这是一段“愚者”的传说。 ",
"然而一句,半睡半醒之时,意志总是飘忽如同烟雾,难以控制,难以收束,他再怎么努力,依旧忍不住思维发散,杂念浮现。",
"  然而看来我还没有真醒,还在梦里……等下说不定还会出现自以为已经醒了,实际依然在睡的情况……对类似遭遇不算陌生的周明瑞竭力集中意志,以彻底摆脱黑暗和迷幻的桎梏。",
"  照耀视线先是模糊,继而蒙上了淡淡的绯红,目光所及绯红,周明瑞看见面前是一张原木色泽的书桌,正中央放着一本摊开的笔记,纸张粗糙而泛黄,抬头用奇怪的字母文字书写着一句话语,墨迹深黑,醒目欲滴。"]
transfer = TfidfVectorizer()
data = []
for i in chinese_data:
data.append(" ".join(jieba.cut(i)))
datas = transfer.fit_transform(data)
print(datas)
print(transfer.get_feature_names_out())




if __name__ == '__main__':
dict_count()
english_count()
chinese_count()
TF_IDF()

特征预处理

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

内容

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

API

1
sklearn.preprocessing

案例

image-20230604112108821

  • 为什么要进行归一化/标准化
    • 特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出来几个数量级,容易影响分配

就比如对于这样一种数据,如果你用KNN算法,那么误差会极大,因为消耗时间百分比 与 里程数之间相差太大这样就会直接把消耗时间百分比当作一个无用数据

而归一化 就是将这些数据规划成同等重要,即为无量纲化

归一化

1.定义

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

百度

2.公式

$$
归一化 X’ = x - min/max-min
X’’ = X’ * (mx - mi) + mi
$$

作用与每一列,max为每一列的最大值,min为一列的最小值,那么X’'为最终结果,

mx,mi分别为指定区间默认mx为1,mi为0

3.API
3.1MinMaxScaler
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from sklearn.preprocessing import MinMaxScaler
import pandas as pd

"""
归一化
"""
def minmax_demo():
# 1. 获取数据
data = pd.read_csv("E:\Code\Pywork\Machine\data\dating.txt")
# 每一行都要只要前三列
data = data.iloc[:, :3]
print("data:\n", data)

# 2. 实例化一个转换器类
transfer = MinMaxScaler()

# 3.调用
data_new = transfer.fit_transform(data)
print("data_new:\n",data_new)

return None

"""
data:
milage Liters Consumtime
0 40920 8.326976 0.953952
1 14488 7.153469 1.673904
2 26052 1.441871 0.805124
3 75136 13.147394 0.428964
4 38344 1.669788 0.134296
.. ... ... ...
995 11145 3.410627 0.631838
996 68846 9.974715 0.669787
997 26575 10.650102 0.866627
998 48111 9.134528 0.728045
999 43757 7.882601 1.332446

[1000 rows x 3 columns]
data_new:
[[0.44832535 0.39805139 0.56233353]
[0.15873259 0.34195467 0.98724416]
[0.28542943 0.06892523 0.47449629]
...
[0.29115949 0.50910294 0.51079493]
[0.52711097 0.43665451 0.4290048 ]
[0.47940793 0.3768091 0.78571804]]
"""


if __name__ == '__main__':
minmax_demo()
4.缺陷

异常值:最大值、最小值

标准化

1.定义

通过对原始数据进行变换把数据变换到均值为0,标准差为1范围内

2.公式

$$
标准化 X’ = (x - mean) / 标准差
$$

作用于每一列,mean为平均值

标准差: 集中程度

3.API
3.1StandardScaler
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
28
29
30
31
from sklearn.preprocessing import StandardScaler
import pandas as pd

def stand_demo():
# 1. 获取数据
data = pd.read_csv("E:\Code\Pywork\Machine\data\dating.txt")
# 每一行都要只要前三列
data = data.iloc[:, :3]
print("data:\n", data)

# 2. 实例化一个转换器类
transfer = StandardScaler()

# 3.调用
data_new = transfer.fit_transform(data)
print("data_new:\n",data_new)
"""
data_new:
[[ 0.33193158 0.41660188 0.24523407]
[-0.87247784 0.13992897 1.69385734]
[-0.34554872 -1.20667094 -0.05422437]
...
[-0.32171752 0.96431572 0.06952649]
[ 0.65959911 0.60699509 -0.20931587]
[ 0.46120328 0.31183342 1.00680598]]
"""

return None

if __name__ == '__main__':
stand_demo()

总结

标准化更适合用于大数据

特征降维

  • 处理对象二维数组
    • 降低(随机变量)特征的个数
      • 得到一组不相关的主变量的过程
1
2
3
比如有一组数据相对湿度与降雨量之间的相关
我们要将这两组数据之间搞成不不相关管,否则会导致数据冗余,计算量太大
会对算法学习的预测影响较大

降维方式

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

特征选择

Filter过滤式
  • 方差选择法:地方查特征过滤
  • 相关系数
    • 衡量特征与特征之间的相关性
Embeded嵌入式
  • 决策树
  • 正则化
  • 深度学习

过滤式

1.方差选择法

有小鸟🐦 判断它的品种,你不能看它是否有爪子,因为所有的鸟都有爪子

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import pandas as pd
from sklearn.feature_selection import VarianceThreshold


def variance_demo():
data = pd.read_csv(r"E:\Code\Pywork\Machine\data\factor_returns.csv")
print("data:\n",data)
data = data.iloc[:, 1:-2]
print("data:\n",data)
# 这里的threshold是阈值大于它的就会被删去
transfer = VarianceThreshold(threshold=5)
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new, data_new.shape)


"""
D:\Programming\anaconda3\python.exe E:/Code/Pywork/Machine/机器学习/特征工程/特征降维/Filter过滤式/低方差过滤/低方差过滤.py
data:
index pe_ratio pb_ratio ... total_expense date return
0 000001.XSHE 5.9572 1.1818 ... 1.088254e+10 2012-01-31 0.027657
1 000002.XSHE 7.0289 1.5880 ... 2.378348e+10 2012-01-31 0.082352
2 000008.XSHE -262.7461 7.0003 ... 1.203008e+07 2012-01-31 0.099789
3 000060.XSHE 16.4760 3.7146 ... 7.935543e+09 2012-01-31 0.121595
4 000069.XSHE 12.5878 2.5616 ... 7.091398e+09 2012-01-31 -0.002681
... ... ... ... ... ... ... ...
2313 601888.XSHG 25.0848 4.2323 ... 1.041419e+10 2012-11-30 0.060727
2314 601901.XSHG 59.4849 1.6392 ... 1.089783e+09 2012-11-30 0.179148
2315 601933.XSHG 39.5523 4.0052 ... 1.749295e+10 2012-11-30 0.137134
2316 601958.XSHG 52.5408 2.4646 ... 6.009007e+09 2012-11-30 0.149167
2317 601989.XSHG 14.2203 1.4103 ... 4.132842e+10 2012-11-30 0.183629

[2318 rows x 12 columns]
data:
pe_ratio pb_ratio ... revenue total_expense
0 5.9572 1.1818 ... 2.070140e+10 1.088254e+10
1 7.0289 1.5880 ... 2.930837e+10 2.378348e+10
2 -262.7461 7.0003 ... 1.167983e+07 1.203008e+07
3 16.4760 3.7146 ... 9.189387e+09 7.935543e+09
4 12.5878 2.5616 ... 8.951453e+09 7.091398e+09
... ... ... ... ... ...
2313 25.0848 4.2323 ... 1.148170e+10 1.041419e+10
2314 59.4849 1.6392 ... 1.731713e+09 1.089783e+09
2315 39.5523 4.0052 ... 1.789082e+10 1.749295e+10
2316 52.5408 2.4646 ... 6.465392e+09 6.009007e+09
2317 14.2203 1.4103 ... 4.509872e+10 4.132842e+10

[2318 rows x 9 columns]
data_new:
[[ 5.95720000e+00 1.18180000e+00 8.52525509e+10 ... 1.21144486e+12
2.07014010e+10 1.08825400e+10]
[ 7.02890000e+00 1.58800000e+00 8.41133582e+10 ... 3.00252062e+11
2.93083692e+10 2.37834769e+10]
[-2.62746100e+02 7.00030000e+00 5.17045520e+08 ... 7.70517753e+08
1.16798290e+07 1.20300800e+07]
...
[ 3.95523000e+01 4.00520000e+00 1.70243430e+10 ... 2.42081699e+10
1.78908166e+10 1.74929478e+10]
[ 5.25408000e+01 2.46460000e+00 3.28790988e+10 ... 3.88380258e+10
6.46539204e+09 6.00900728e+09]
[ 1.42203000e+01 1.41030000e+00 5.91108572e+10 ... 2.02066110e+11
4.50987171e+10 4.13284212e+10]] (2318, 8)

Process finished with exit code 0

"""



if __name__ == '__main__':
variance_demo()

2.相关系数

  • 皮尔逊相关系数
    • 反应变量之间相关关系密切程度的统计指标

image-20230604153425798

看最终r的值

  • 大于 0 正相关 小于 0 负相关

  • r = 1 完全相关 r = 0 毫无关系

  • 0<|r|<1时,存在相关 r ~ 1线性关系密切 r ~ 0 相关变弱

  • 一般分为三级

    |r| < 0.4低相关

    0.4<|r|<0.7显著相关

    0.7<=|r|<=1高度相关

3.API

1
from scipy.stats import pearsone

4.计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
from sklearn.feature_selection import VarianceThreshold
from scipy.stats import pearsonr


def variance_demo():
data = pd.read_csv(r"E:\Code\Pywork\Machine\data\factor_returns.csv")
data = data.iloc[:, 1:-2]
r = pearsonr(data['pe_ratio'],data['pb_ratio'])
print("相关系数:",r)
# 相关系数: PearsonRResult(statistic=-0.004389322779936274, pvalue=0.8327205496564927)

if __name__ == '__main__':
variance_demo()

如果特征与特征之间相关性很高

  1. 选取其中一个
  2. 加权求和
  3. 主成分分析

主成分分析

多维转成二维能看出来是什么的

做降维尽可能的保留原有的特征

API
1
sklean.decomposition.PCA(n_components=None)
  • 将数据降维
  • n_components:
    • 小数:保留百分之多少的信息
    • 整数:减少到多少特征

instacart降维案例

先了解几个概念

  • 联表(交叉表): http://www.zzvips.com/article/188950.html

  • 透视表:

    1
    - 数据透视表是一种对大量数据快速汇总分析的交互式动态表格,它能够帮助用户统计分析数据。简单来说,数据透视表也就是对原始表进行分组聚合,压缩数据信息,把不必要的信息从原始数据中剔除,而只将我们想看到的数据信息展示到我们面前!
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 1、获取数据
# 2、合并表
# 3、找到user_id和aisle之间的关系
# 4、PCA降维

import pandas as pd
import os

# 1、获取数据
products = pd.read_csv(r"C:\Users\beihai\Desktop\competition\数据\instacart\products.csv")
order_products = pd.read_csv(r"C:\Users\beihai\Desktop\competition\数据\instacart\order_products__prior.csv")
orders = pd.read_csv(r"C:\Users\beihai\Desktop\competition\数据\instacart\orders.csv")
aisles = pd.read_csv(r"C:\Users\beihai\Desktop\competition\数据\instacart\aisles.csv")

# 2、合并表
# 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 order_dow order_hour_of_day days_since_prior_order

# aisles.csv: 商品所属具体物品类别
# 字段: aisle_id aisle


# 合并aisles和products
table1 = pd.merge(aisles,products, on=["aisle_id","aisle_id"])

# 合并table1和order_products
table2 = pd.merge(table1, order_products, on=['product_id','product_id'])

# 合并table2和orders
table3 = pd.merge(table2,orders, on=['order_id','order_id'])

# 找到user_id和aisle之间的关系
# 交叉表
table = pd.crosstab(table3['user_id'],table3['aisle'])

# 数据量太大先选取前10000条数据
data = table[:10000]
# 特征值太多需要降维

# PCA 降维
from sklearn.decomposition import PCA

# 1)实例化一个转换器类
transfer = PCA(n_components=0.95)

# 2)调用fit_transform
data_new = transfer.fit_transform(data)

print(data_new,data_new.shape)


"""
(array([[-2.36456828e+01, 2.30028678e+00, -2.71706275e+00, ...,
8.24685231e-01, -5.20365905e-01, 2.99847178e+00],
[ 6.95477119e+00, 3.54966052e+01, 2.52655545e+00, ...,
-1.15326520e+00, -1.37969318e+00, -1.07115466e-02],
[-7.47792843e+00, 2.83147785e+00, -1.07306519e+01, ...,
-3.55104796e-01, 3.85595697e-02, 1.92318882e+00],
...,
[-2.86664024e+01, -1.26446961e+00, -1.14908062e+00, ...,
1.13859569e-03, 4.14189764e-01, 4.46163585e-01],
[-2.88378748e+01, -1.70490822e+00, -1.47059942e+00, ...,
-1.62743887e-01, 6.72795951e-01, 9.64403654e-02],
[ 2.10412407e+02, -3.51935647e+01, 1.33671987e+01, ...,
1.46544596e+01, 1.56764794e+01, 1.67432890e+01]]),
(10000, 42))
"""

第一节课总结:跟着黑马口说一遍

https://www.bilibili.com/video/BV1nt411r7tj/?p=19&spm_id_from=pageDriver&vd_source=bed2588951fb9fd0821dd2ef0191e48b

3.分类算法

目标值: 类别 连续

1、sklearn:转换器和预估器

2、KNN算法

3、模型选择与调优

4、朴素贝叶斯算法

5、决策树

6、随机森林

3.1sklearn转换器和预估器

3.1.1转换器

1
2
3
4
5
6
特征工程的->父类
这里就是相当与之前我在做特征工程的使用用到的东西:
1.先实例化
2.调用fit_transform()
fit() 计算
transform() 最终转换

3.1.2估计器(esimator)

1
2
3
4
5
6
7
8
9
10
sklearn机器学习算法的实现
1.实例化一个esimator
2.esimator.fit(x_train,y_train) 计算
-调用完毕,模型生成
3.模型评估
(1)对比真实值,测试值
y_predict = esimator.predict(x_test)
y_test == y.predict
(2)计算准确率
accuracy = esimator.score(x_test,y_test)
image-20230606161951864

可以看出来它们都被完整的封装,所以机器学习有一套固定的流程

3.2 K-近邻算法

KNN算法

根据邻居来判断类别

近朱者赤,近墨者黑

3.2.1 KNN简述与距离度量

KNN(K-Nearest Neighbors,K近临算法), 机器学习中最简单的算法

”离谁进,就是谁“

用人眼看就知道这个绿色三角形就是轿车

但是机器没眼,只能靠精密的计算所以这里就引出来了距离度量的算法

image-20230601195802325

3.2.1.1 距离度量

$$
欧式距离(L2)=sqrt((x1-x2)^2 + (y1-y2)^2)
$$

image-20230601200248895

image-20230601200653325
1.欧式距离
1
空间之中 两点之间的直线距离
image-20230601200820970
2.曼哈顿距离
1
2
就是我走路,不可能沿着直线走,所以我会拐着弯走
这种方式就像在曼哈顿的街区里面去行走,最终到达目的地的距离

image-20230601201204108

欧式距离和曼哈顿距离的使用
  • 欧式距离都比较可以适用

  • 曼哈顿距离

    1
    2
    3
    4
    适用于:
    求解过程中使得离群点的影响更小
    维度极高的数据 ---> 特征的数量
    更适合数据维度没有归一化/不平衡
3.明氏距离

image-20230601201711733

代码初体验

image-20230601202516052

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
28
29
30
31
32
33
34
35
36
37
38
import numpy as np

# 数据集
A = np.array([4.8, 2.2])
B = np.array([4.7, 2.1])

# 欧式距离
def cal_dist_L2(A, B):
distance_L2 = np.sqrt(np.sum((A-B) ** 2))

return distance_L2

print(cal_dist_L2(A, B))

# 曼哈顿距离
def manhattan_distance(A, B):
distance = 0
for i in range(len(A)):
distance += abs(A[i] - B[i])
return distance

print(manhattan_distance(A, B))

# 明氏距离
def minkowski_distance(A, B, p):
distance = 0
for i in range(len(A)):
distance += np.sqrt(abs(A[i] - B[i]) ** p) ** p
return distance

print(minkowski_distance(A, B, 2))



#0.1414213562373093
#0.19999999999999973
#0.01999999999999995

可以看出来算法不同相差的结果很大

所以看那些比赛中的排名就是对数据的处理和算法的选择不同而导致得分相差

3.2.2 KNN算法实现步骤

2.1 算法基本思路
  1. 计算距离
  2. 排序
  3. 取前K个样本 ----> 超参数:K值,调参和优化
1
2
3
4
5
6
7
8
这玩意就是
1.首先我先用距离度量公式去计算每个样本空间中与样本之间的距离
2.其次我对这些距离进行排序,从小到大,然后取前K个样本
3.然后我看这些里面有多少个🚚多少个🚗,然后计算占比
最终根据这个占比就可以得出谁的概率大


我就感觉这里有些不对劲 那如果我选的样本中🚗本来就少,那我取前K个样本,肯定🚗占比就少了,所以合理选择这个K有点说法,这算法有待提高

这里对于优化超参数

通常就是取若干个超参数:K值 —> 取得若干个结果 ----> 若干个评估

最后这个评估最优的就选这个K值作为超参数

k值选取策略
  • 奇数
  • k < 一个值 通常是 20

3.2.3 KNN算法的优缺点及改进

优点
  • 易于理解

  • 不需要庞大的样本数量

  • 对于异常值不敏感

    1
    对离它近的敏感,太远的不鸟它
  • 是天然的多分类器

    1
    只需要关注距离它的几个
  • 不需要训练,求解参数

    1
    有些鸡肋
缺点
  • 数据量大时计算量太大

  • 不平衡样本处理能力差

    image-20230601212555814
  • 并不“学习”

  • 速度慢、准确率低

改进

加权平均KNN
1
2
正常情况下是只看投票结果
加权,就是把所带的类型也算上通过一定的计算方法

权重算法:

就是距离离得远的权重就低,距离离的近的权重就高

image-20230602000608822

3.2.4 KNN机器学习应用

3.2.4.1 徒手写

麻烦,正常不会使用

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
import pandas as pd
import matplotlib.pylab as plt

data = pd.read_csv("vehicle.csv")

plt.scatter(data['length'][data['label']=='car'],data['width'][data['label']=='car'],edgecolors='y')
plt.scatter(data['length'][data['label']=='truck'],data['width'][data['label']=='truck'],edgecolors='r')
plt.show()

feature = np.array(data.iloc[:,0:2])
labels = data['label'].tolist()
print(feature)
print(labels)

test=[4.7, 2.1]
numSamples = data.shape[0]

# 距离
diff = np.tile(test, (numSamples, 1)) - feature
squreDiff = diff ** 2
squreDiff = np.sum(squreDiff, axis = 1)
distance = squreDiff ** 5

# 排序
sorteDisIndices = np.argsort(distance)
k = 9
classCount = {}
label_count = []

for i in range(k):
voteLabel = labels[sorteDisIndices[i]]
classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
label_count.append(voteLabel)

from collections import Counter

word_counts = Counter(label_count)
top = word_counts.most_common(1)

# [('truck', 5)]
3.2.4.2 Sklearn(Scikit-learn)框架
鸢尾花种类预测
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

"""
获取数据
数据集划分
特征工程:
标准化 降维
KNN预估器
模型评估
"""

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():
# 获取数据
iris = load_iris()

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

# 实例化对象
transfer = StandardScaler()

#特征工程 无量纲化
x_train = transfer.fit_transform(x_train)
# 只标准化 不计算
x_test = transfer.transform(x_test)

#实现算法 K值设置
estimator = KNeighborsClassifier(n_neighbors=3)
# 算法计算 训练集特征值 训练集目标值
estimator.fit(x_train,y_train)

# KNN预估器 训练集特征值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

score = estimator.score(x_test, y_test)
print("准确率为: \n", score)



if __name__ == '__main__':
knn_iris()

3.2.5 案例:预测facebook签到位置

流程分析:

  1. 获取数据

  2. 数据处理

    目的:

    ​ 特征值 x

    ​ 目标值 y

    ​ a. 缩小数据范围

    ​ 2 < x < 2.5

    ​ 1.0 < y < 1.5

    ​ b.time -> 年月日时分秒

    ​ c.过滤签到次数少的地点

  3. 特征工程:标准化

  4. KNN算法预估流程

  5. 模型选择与调优

  6. 模型评估

1

3.3 模型选择与调优

3.3.1 交叉验证

1
2
就是将训练集再分为 训练集和验证集,
例如分为四份,分别测试训练,得到准确率,最终平均值作为最优的

API

image-20230607100157679
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
"""
获取数据
数据集划分
特征工程:
标准化 降维
KNN预估器
模型评估
"""

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


def knn_iris():
# 获取数据
iris = load_iris()

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

# 实例化对象
transfer = StandardScaler()

# 特征工程 无量纲化
x_train = transfer.fit_transform(x_train)
# 只标准化 不计算
x_test = transfer.transform(x_test)

# 实现算法 K值设置
estimator = KNeighborsClassifier(n_neighbors=3)
# 算法计算 训练集特征值 训练集目标值
estimator.fit(x_train, y_train)

# KNN预估器 测试集特征值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

score = estimator.score(x_test, y_test)
print("准确率为: \n", score)


def knn_iris_gscv():
# 获取数据
iris = load_iris()

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

# 实例化对象
transfer = StandardScaler()

# 特征工程 无量纲化
x_train = transfer.fit_transform(x_train)
# 只标准化 不计算
x_test = transfer.transform(x_test)

# 实现算法
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)

# KNN预估器 测试集特征值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

score = estimator.score(x_test, y_test)
print("准确率为: \n", score)

print("最佳参数:\n", estimator.best_params_)
print("最佳结果:\n", estimator.best_score_)
print("最佳估计器:\n", estimator.best_estimator_)
print("交叉验证结果:\n", estimator.cv_results_)


if __name__ == '__main__':
# knn_iris()
knn_iris_gscv()

3.4 朴素贝叶斯

image-20230607145322451

image-20230611085809644