学习视频来源于黑马程序员的python机器学习快速入门,根据视频做的学习笔记,感谢黑马程序员的开源精神。
1.机器学习概述
1.人工智能概述
人工智能、机器学习、深度学习的关系:
- 机器学习是人工智能的一个实现途径。
- 深度学习是机器学习的一个方法发展而来。
机器学习、深度学习的应用场景:
- 传统预测
- 图像识别
- 自然语言处理
2.什么是机器学习
通过历史数据训练模型,然后通过训练出来的模型来预测新的数据。
- 数据
- 模型
- 预测
数据集:就是那些历史数据。由特征值和目标值构成。
3.机器学习算法分类
目标值:有 - 监督学习
目标值:类别 - 分类问题
目标值:连续型的数据 - 回归问题
目标值:无 - 无监督学习
监督学习:
分类问题:k-近邻算法、贝叶斯分类、决策树和随机森林、逻辑回归。
回归问题:线性回归、岭回归。
无监督学习:
聚类:k-means。
4.机器学习开发流程
- 获取数据
- 数据处理
- 特征工程
- 机器学习算法进行训练 - 模型
- 模型评估 (如果评估结果不合适则循环2-5步骤,直到通过第五步)
- 应用
5.学习框架
- 算法是核心,数据与计算是基础。
- 找准定位
- 学习步骤
简单应用
实战类书籍
理论书籍(机器学习、统计学习方法、深度学习)
2.特征工程
1.数据集
可用数据集:
scikit-learn链接:数据量较小,方便学习。
kaggle链接:大数据竞赛平台,真实数据,大量数据。
UCI数据集链接:收录大量数据集,覆盖科学、生活、经济等领域,数据量大。
scikit-learn:
Python语言的机器学习工具。
包括绝大多机器学习算法的实现
文档完善,上手容易,具有丰富的API
数据集API介绍:
sklaern.datasets 加载获取流行数据集
datasets.load_*() (获取小规模数据集)
获取小规模数据集,数据包含在datasets里。
datasets.fetch_*(data_home=None) (获取大规模数据集)
获取大规模数据集,需要从网络上下载,函数的第一个参数是data_home,表示数据集下载的目录,默认是:~/scikit_learn_data/
sklearn数据集的使用:load和fetch返回的数据类型:datasets.base.Bunch(继承于字典格式)
data:特征数据数组,是[n_samples * n_features]的二维numpy.ndarray数组
target:标签数组,是n_samples的一维numpy.ndarray数组
DESCR:数据描述
feature_names:特征名,新闻数据,手写数字、回归数据集没有。
target_names:标签名。
数据集划分API:
数据集的划分:
训练数据集:用于训练,构建模型。
测试数据集:在模型检验时使用,用于评估模型是否有效。
测试集:占20%~30%.
sklearn.model_selection.train_test_split(arrays, *options)
x:数据集的特征值。
y:数据集的标签值。
test_size:数据集的大小,一般为float。
random_state:随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
return:训练集特征值,测试集特征值;训练集目标值,测试集目标值。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def datasets_demo():
"""
sklearn数据集使用
:return:
"""
# 获取鸢尾花数据集
iris = load_iris()
print("鸢尾花数据集的返回值:\n", iris)
# 返回值是一个继承自字典的Bench
print("鸢尾花的特征值:\n", iris["data"])
print("鸢尾花的目标值:\n", iris.target)
print("鸢尾花特征的名字:\n", iris.feature_names)
print("鸢尾花目标值的名字:\n", iris.target_names)
print("鸢尾花的描述:\n", iris.DESCR)
# 训练集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
print("训练集的特征值:\n", x_train, x_train.shape)
return None
if __name__ == "__main__":
# 代码1:sklearn数据集的使用
datasets_demo()
2.特征工程介绍
为什么要做特征工程?
数据和特征决定了机器学习的上线,而算法和模型只是逼近这个上限而已。
特征工程:
使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
能够直接影响机器学习的效果。
pandas: 数据读取非常方便以及基本的处理格式的工具。
sklearn: 对于特征的处理提供了强大的接口。
3.特征抽取
机器学习算法 - 统计方法 - 数学公式
特征提取:sklearn.feature_extraction
字典特征提取:将属于类别的转换成 one-hot编码。
sklearn.feature_extraction.DictVectorizer(sparse=True,...)
DictVectorizer.fit_transform(X) X:字典或者包含字典的迭代器返回值:返回sparse矩阵。
DictVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式。
DictVectorizer.get_feature_names_out() 返回类别名称。
应用场景:
1. pclass,sex 数据集当中类别特征比较多。
1. 将数据集的特征 --> 字典类型。
2. DictVectorizer转换。
2. 本身拿到的数据就是字典类型。
文本特征抽取:对文本数据进行特征值化。
sklearn.feature_extraction.text.CountVectorizer(stop_words=[]) :返回词频矩阵。 stop_words:停用词。
CountVertorizer.fit_transform(X) X:文本或者包含文本字符串的可迭代对象。 返回值:sparse矩阵。
CountVectorizer.inverse_transform(X) X:array数组或者sparse矩阵 返回值:转换之前数据格式。
CountVectorizer.get_feature_names_out() 返回类别名称。
tf-idf文本特征提取:(分类机器学习算法进行文章分类中前期数据处理方式)
用于评估一字词对于一个文件集或一个语料库中的其中一个文件的重要程度。
公式:
词频(tf):某一个给定的词语在该文件中出现的频率。
逆向文档频率(idf):一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到。
关键词:在某一个类别的文章中出现的次数很多,但是在其他类别的文章中出现的次数很少。
sklearn.feature_extraction.text.TfidfVectorizer
t f i d f i , j = t f i × i d f i , j tfidf_{i,j} = tf_i \times idf_{i,j} tfidfi,j=tfi×idfi,j
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import jieba
def dict_demo():
"""
字典特征抽取
:return:
"""
data = [{'city': '北京', 'temperature': 100}, {'city': '上海', 'temperature': 60}, {'city': '深圳', 'temperature': 30}]
# 实例化一个转换器类
transfer = DictVectorizer(sparse=False)
"""
sparse=True(默认)
data_new:
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
默认返回一个sparse矩阵:也就是一个稀疏矩阵,就是将下面的二维矩阵将非零位置表示出来。
使用稀疏矩阵的优点:当类别特别大的时候,可以节省内存空间
sparse=False
data_new:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
"""
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
print("特征名字:\n", transfer.get_feature_names_out())
return None
def count_demo():
"""
文本特征值抽取:CountVectorizer
:return:
"""
data = ["life is short, i like like python", "life is too long , i dislike python"]
# 1.实例化一个转换器
transfer = CountVectorizer()
# 2.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", type(data_new))
print("data_new:\n", data_new)
print("data_new:\n", data_new.toarray())
"""
data_new:
[[0 1 1 2 0 1 1 0]
[1 1 1 0 1 1 0 1]]
特征值的名字:
['dislike' 'is' 'life' 'like' 'long' 'python' 'short' 'too']
作用:统计每个样本特征值出现的个数
"""
print("特征值的名字:\n", transfer.get_feature_names_out())
"""
<class 'scipy.sparse.csr.csr_matrix'>
此类型可以直接使用 .toarray() 转换成数组
"""
return None
def cut_words(text):
"""
进行中文分词
:return:
"""
text = ' '.join(list(jieba.cut(text)))
return text
def count_chinese_demo():
"""
中文文本特征抽取,自动分词
:return:None
"""
# 1.将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_words(sent))
# 2.实例化一个转换器
transfer = CountVectorizer(stop_words=["一种", "所以"])
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray())
print("特征值的名字:\n", transfer.get_feature_names_out())
return None
def tfidf_demo():
"""
用tf-idf方法进行文本特征提取
:return:
"""
# 1.将中文文本进行分词
data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝大部分是死在明天晚上,所以每个人不要放弃今天。",
"我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。",
"如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"]
data_new = []
for sent in data:
data_new.append(cut_words(sent))
# 2.实例化一个转换器
transfer = TfidfVectorizer(stop_words=["一种", "所以"])
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray())
print("特征值的名字:\n", transfer.get_feature_names_out())
return None
if __name__ == "__main__":
# 代码1:字典特征抽取
dict_demo()
# 代码2:文本特征抽取
count_demo()
# 代码3:中文文本分词
count_chinese_demo()
# 代码4:TF-IDF进行文本特征提取
tfidf_demo()
4.特征预处理
什么是特征预处理: 通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程。
特征预处理API
sklearn.preprocessing
数值型数据的无量纲化:
- 归一化
为什么要进行归一化/标准化: 要进行无量纲化,是不同规格的数据转化为同一规格。(就是让每一类数据在之后的计算中,所占的权重一样,不会出现某一个的单位太大,导致最终结果几乎由这一项数据所影响。)
定义: 通过对原始数据进行变换把把数据映射到(默认为[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'\times (mx-mi)+mi
X′=max−minx−minX′′=X′×(mx−mi)+mi
作用于每一列,max为一列的最大值,min为一列的最小值,X’'为最终结果。mx,mi分别为指定区间mx=1,mi=0。
API
sklearn.preprocessing.MinMaxScaler(feature_range=(0,1)…)
MinMaxScaler.fit_transform(X)
X:numpy array格式的数据[n_samples, n_features]
返回值:转换后的形状相同的array。
- 标准化
定义: 通过对原始数据进行变换把数据变换到均值为0,标准差为1的范围内。
公式:
X
′
=
x
−
m
e
a
n
σ
X'=\frac{x-mean}{\sigma }
X′=σx−mean
作用于每一列,mean为平均值,
σ
\sigma
σ为标准差。
API
sklearn.preprocessing.StandardScaler()
处理之后,对每列来说,所有数据都聚集在均值为0附近,标准差为1.
StandardScaler.fit_transform(X)
X:numpy array格式的数据[n_samples, n_features]
返回值:转换后的形状相同的array。
标准化适合大量数据的场景。
- 对于归一化来说:如果出现异常点,影响了最大值和最小值,那么结果显然会发生改变。
- 对于标准化来说:如果出现异常点,由于具有一定的数据量,少量的异常点对于平均值的影响并不大,从而方差改变较小。
from sklearn.preprocessing import MinMaxScaler, StandardScaler
import pandas as pd
def minmax_demo():
"""
归一化
:return:
"""
# 1.获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, : 3]
print("data:\n", data)
# 2.实例化一个转换器类
transfer = MinMaxScaler()
# 3.调用fit——transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
def stand_demo():
"""
标准化
:return:
"""
# 1.获取数据
data = pd.read_csv("dating.txt")
data = data.iloc[:, : 3]
print("data:\n", data)
# 2.实例化一个转换器类
transfer = StandardScaler()
# 3.调用fit——transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
# 代码1:归一化
minmax_demo()
# 代码2:标准化
stand_demo()
5.降维
什么是降维: 在某些限定条件下,降低随机变量(特征)个数,得到一组 “不相关” 主变量的过程。
维数:数组嵌套的层数
此处的降维:降低特征的个数。
相关特征:类似于湿度和降雨量之间的关系。
降维的两种方式:
- 特征选择降维
- 主成分分析降维
5.1特征降维
定义: 数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征。
方法:
- Filter(过滤式):主要探究特征本身特点、特征于特征和目标值之间的关系。
- 方差选择法:低方差特征过滤。
- 相关系数
- Embedded(嵌入式):算法自动选择特征(特征于目标值之间的关联)
- 决策树:信息熵、信息增益。
- 正则化:L1、L2
- 深度学习:卷积等。
模块: sklearn.feature_selection
5.1.1过滤式
低方差特征过滤
删除低方差的一些特征,再结合方差的大小来考虑。
特征方差小:某个特征大多样本的值比较相近。
特征方差大:某个特征很多样本的值都有差别
API
- sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
- 删除所有低方差特征
- Variance.fit_transform(X)
- X:numpy array格式的数据[n_samples, n_features]
- 返回值:训练集差异低于threshold的特征将被删除。默认值是保留所有非零方差特征,即删除所有样本中具有相同值的特征。
数据计算
相关系数
- 皮尔逊相关系数
- 反映变量之间相关关系密切程度的统计指标
公式
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)2n∑y2−(∑y)2n∑xy−∑x∑y
相关系数的取值:
−
1
≤
r
≤
1
-1\le r\le 1
−1≤r≤1
- 当 r > 0 r>0 r>0时,表示两变量正相关, r < 0 r<0 r<0时,两变量负相关。
- 当 ∣ r ∣ = 1 |r|=1 ∣r∣=1时,表示两变量为完全相关,当 r = 0 r=0 r=0时,表示两变量间无相关关系。
- 当 0 < ∣ r ∣ < 1 0<|r|<1 0<∣r∣<1时,表示两变量存在一定程度的相关关系,且 ∣ r ∣ |r| ∣r∣越接近1,两变量间线性关系越密切; ∣ r ∣ |r| ∣r∣越接近于0,表示两变量间线性关系越弱。
- 一般可按三级划分: ∣ r ∣ < 0.4 |r|<0.4 ∣r∣<0.4为低度相关; 0.4 < ∣ r ∣ < 0.7 0.4<|r|<0.7 0.4<∣r∣<0.7为显著性相关; 0.7 < ∣ r ∣ < 1 0.7<|r|<1 0.7<∣r∣<1为高度线性相关。
API
- from scipy.stats import pearsonr
- x:(N,) array_like
- y:(N,) array_like Returns: (pearson’s correlation coefficient, pvalue)
特征与特征之间相关性很高:
- 选取其中一个为代表
- 加权求和
- 主成分分析
from sklearn.feature_selection import VarianceThreshold
import pandas as pd
def variance_demo():
"""
过滤低方差特征
:return:
"""
# 1.获取数据
data = pd.read_csv("factor_returns.csv")
print("data:\n", data)
data = data.iloc[:, 1:-2]
# 2.实例化一个转换器类
transfer = VarianceThreshold(threshold=20)
# 3.调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new, data_new.shape)
# 4.计算某两个变量之间的相关系数
r = pearsonr(data["pe_ratio"], data["pb_ratio"])
print("r:\n", r)
return None
if __name__ == "__main__":
# 代码:过滤低方差特征
variance_demo()
5.2主成分分析降维
定义: 高维数据转换为低维数据的过程,在此过程中可能会舍弃原有数据、创造新的变量。
作用: 是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
应用: 回归分析或者聚类分析中。
API
- sklearn.decomposition.PCA(n_components=None)
- 将数据分解为较低维数空间
- n_components:
- 小数:表示百分之多少的信息
- 整数:减少到多少特征
- PCA.fit_transform(X) X:numpy array格式的数据[n_samples, n_features]。
- 返回值:转换后指定维数的array。
from sklearn.decomposition import PCA
def pca_demo():
"""
PCA降维
:return:
"""
data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]]
# 实例化一个转换器类
transfer = PCA(n_components=0.99)
# 调用fit_transform
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
# 代码:过滤低方差特征
pca_demo()
5.3简单案例:探究用户对物品类别的喜好细分
数据:
- 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放在同一个表中 - 合并
- 找到user_id和aisle - 交叉表和透视表
- 特征冗余过度 - PCA降维
from sklearn.decomposition import PCA
import pandas as pd
# 1.获取数据
aisles = pd.read_csv("aisles.csv")
order_products_prior = pd.read_csv("order_products__prior.csv")
orders = pd.read_csv("orders.csv")
products = pd.read_csv("products.csv")
# 2.合并表
# 合并aisles和products
table1 = pd.merge(aisles, products, on=["aisle_id", "aisle_id"])
table2 = pd.merge(table1, order_products_prior, on=["product_id", "product_id"])
table3 = pd.merge(table2, orders, on=["order_id", "order_id"])
# 3.找到user_id和aisle之间的关系
table = pd.crosstab(table3["user_id"], table3["aisle"])
# 1.实例化一个转换器类
transfer = PCA(n_components=0.95)
# 2.调用transform
data_new = transfer.fit_transform(table)
print(data_new)
有可能会报错
- numpy.core._exceptions.MemoryError: Unable to allocate 742. MiB for an array with shape (3, 32434489) and data type int64
这个是由于数据量太大了,也就是cpu内存小导致的,解决方法:修改pycharm的运行内存。
- 点击Help ——》下拉菜单选择 Find Action ——》输入 VM Options ——》选择 Edit Custom VM Options ——》将-Xmx**m 修改为 -Xmx4096m(4G运行,按情况自行分配)