目录
- 1.数学核心基础 | 矩阵运算法则(花书)
- 2.数学核心基础 | 特征值分解(花书)
- 任务3:数学核心基础 | 信息熵(花书)
- 任务4:概率论
- 任务5:数学核心基础 | 贝叶斯方法(花书)
- 任务6:数学核心基础 | 极大似然估计(花书)
- 任务7:数学核心基础 | 梯度下降(花书)
- 任务8:数学核心基础 | 交叉验证(花书)
- 任务17:机器学习基础知识
- 任务18:最小二乘和logistic回归
- 任务19:朴素贝叶斯和KNN
- 任务20:SVM
- 任务21:关联规则(apriori)
- 任务22:集成学习
- 任务23:降维(pca)
- 任务24:集成学习(blending和stacking)
- 任务10:pytorch的机器学习实践(logistic回归)
1.数学核心基础 | 矩阵运算法则(花书)
乘:
1.Hadamard 乘积:卷积操作 对应位置相乘:两个矩阵大小相似
2.矩阵乘积:全连接神经网络,行列相乘再求和:前者的列等于后者的行
import pandas as pd
import numpy as np
a = np.random.randint(10, size=[3,3])
print('a:',a)
b = np.random.randint(10, size=[3,3])
print('b:',b)
c = a * b
d = np.matmul(a,b)
print('c:',c)
print('d:',d)
除:
矩阵求逆
np.linalg.inv(a) #如果a是数组
A=np.matrix(a)
A.I
2.数学核心基础 | 特征值分解(花书)
特征值:(寻找和矩阵在一个维度下的方向向量和缩放)(方阵(行列数相等))
实数范围里,特征值是拉伸的大小,特征向量是拉伸的方向
# 特征值分解
# X=np.random.rand(3,3)
# val,featurevector = np.linalg.eig(X)
# print(val)
# print(featurevector)
#svd
a=np.array([[1,2,3],[2,3,9]])
u,d,v=np.linalg.svd(a)
# print(v)
t=d.tolist()
t=np.array(t)
t=np.diag(t)
t2=[[0],[0]]
t=np.concatenate([t,t2],axis=1)
print(np.matmul(np.matmul(u,t),v))
#PCA:降维,就是把相关性的变量数目变少,用较少的变量来取代原先的变量。如果原始变量互相正交,即没有相关性,则主成分分析没有效果
任务3:数学核心基础 | 信息熵(花书)
信息熵越大,携带的信息量越大,不确定度越大。
交叉熵(loss): 两个分布的概率的相似性。其用来衡量在给定的真实分布下,使用非真实分布所指定的策略消除系统的不确定性所需要付出的努力的大小。
举个例子,假设有一个3分类问题,某个样例的正确答案是(1,0,0),这个模型经过softmax回归之后的预测答案是(0.5,0.4,0.1),那么预测和正确答案之间的交叉熵为:
H
(
(
1
,
0
,
0
)
,
(
0.5
,
0.4
,
0.1
)
)
=
−
(
1
∗
l
o
g
0.5
+
0
∗
l
o
g
0.4
+
0
∗
l
o
g
0.1
)
=
0.3
H((1,0,0),(0.5,0.4,0.1))=-(1*log0.5+0*log0.4+0*log0.1)=0.3
H((1,0,0),(0.5,0.4,0.1))=−(1∗log0.5+0∗log0.4+0∗log0.1)=0.3
如果另一个模型的预测是(0.8,0.1,0.1),那么这个预测值和真实值之间的交叉熵是:
H
(
(
1
,
0
,
0
)
,
(
0.8
,
0.1
,
0.1
)
)
=
−
(
1
∗
l
o
g
0.8
+
0
∗
l
o
g
0.1
+
0
∗
l
o
g
0.1
)
=
0.1
H((1,0,0),(0.8,0.1,0.1))=-(1*log0.8+0*log0.1+0*log0.1)=0.1
H((1,0,0),(0.8,0.1,0.1))=−(1∗log0.8+0∗log0.1+0∗log0.1)=0.1
显然我们看到第二个预测要优于第一个。这里的(1,0,0)就是正确答案p,(0.5,0.4,0.1)和(0.8,0.1,0.1)就是预测值q,显然用(0.8,0.1,0.1)表达(1,0,0)的困难程度更小。
KL散度(相对熵loss):衡量两个概率分布之间的差异。
P样本真实分布,Q模型预测分布
Q的分布越接近P,散度值越小,损失值越小
等于交叉熵减信息熵
KL散度是非负的并且衡量两个分布之间的差异
任务4:概率论
概论为0不等于不可能事件
二项分布多次以后就是伯努利分布
任务5:数学核心基础 | 贝叶斯方法(花书)
先验,后验(因果关系)
因–》果
果–》因
sigmoid函数
1.y在(0,1)
2.一层神经网络可以拟合所有函数
3.缺点梯度爆炸没有斜率
4.导数等于原函数乘以1-原函数
softplus
1.y在[-1,1]
relu(CNN)–》LRelu–》PRelu
任务6:数学核心基础 | 极大似然估计(花书)
任务7:数学核心基础 | 梯度下降(花书)
激活函数把线性函数变成非线性函数
激活函数有relu
tanh区间在[-1,1]
softmax区间在[0,1]
sigmoid区间在[0,1]
单层的神经网络
import numpy as np
X = np.random.rand(100)
y = 2. * X + 3
w = np.random.rand()
b = np.random.rand()
def model_loss(X,y):
global w,b
y2 = w * X + b
loss = 0.5 * np.square(y - y2)
return loss, y2
for i in range(100):
train_x, train_y = X[i],y[i]
loss, y2 = model_loss(train_x, train_y)#计算loss,模型的输出
delw = (train_y - y2) * train_x#计算权重变化量
delb = (train_y - y2)#计算便置变化量
w += delw
b += delb
print(w, b)
矩阵乘法加法(构建神经网络的基石)
学习率,控制参数变化快慢的量
批(SGD随机梯度下降)
Batch Gradient Descent,BGD
Stochasitc Gradient Descent,SGD
Mini-Batch Gradient Descent,MBGD
批进去以后loss怎么求
任务8:数学核心基础 | 交叉验证(花书)
训练集
验证集(Validation Set)----->数据集少于1w的时候,为了提升效果,就需要使用交叉验证
测试集
验证集和测试集的区别,测试集绝对不能拿来训练数据,保证数据的纯洁性
1简单交叉验证:将数据简单分成训练集和测试集,然后用训练集来训练模型,在测试集上验证模型及参数。接着把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后选择损失函数评估最优的模型和参数。
2S折交叉验证:样本随机分成S份,每次随机选择S-1份作为训练集,剩下一份做测试集。当这轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)后,选择损失函数评估最优的模型和参数。
3留一验证,样本数据极少,是S折交叉验证的特殊情况,S=样本数N(N小于50),对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。
4.自助法(bootstrapping)m个样本(m较小,小于20个),每次在这m个样本中随机采集一个样本,放入训练集,采样完成后把样本放回,这样重复采样m次,这样得到m个样本组成的训练集。可能有重复的样本数据。
归一化是减去最小值,正则化是减去均值
分层,groups的区别
from sklearn.model_selection import train_test_split,cross_val_score,cross_validate # 交叉验证所需的函数
from sklearn.model_selection import KFold,LeaveOneOut,LeavePOut,ShuffleSplit # 交叉验证所需的子集划分方法
from sklearn.model_selection import StratifiedKFold,StratifiedShuffleSplit # 分层分割
from sklearn.model_selection import GroupKFold,LeaveOneGroupOut,LeavePGroupsOut,GroupShuffleSplit # 分组分割
from sklearn.model_selection import TimeSeriesSplit # 时间序列分割
from sklearn import datasets # 自带数据集
from sklearn import svm # SVM算法
from sklearn import preprocessing # 预处理模块
from sklearn.metrics import recall_score # 模型度量
iris = datasets.load_iris() # 加载数据集
print('样本集大小:', iris.data.shape, iris.target.shape)
# =======数据集划分,训练模型=========
X_train,X_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size = 0.4, random_state=0) # 交叉验证划分训练集和测试集
print('训练集大小',X_train.shape,y_train.shape)
print('测试集大小',X_test.shape,y_test.shape)
clf = svm.SVC(kernel='linear',C=1).fit(X_train, y_train)# 使用训练集训练模型
print('准确率:', clf.score(X_test, y_test)) # 计算测试集的度量值(准确率)
# 如果涉及到归一化,则在测试集上也要使用训练集模型提取的归一化函数
scaler = preprocessing.StandardScaler().fit(X_train) # 通过训练集获得归一化函数模型
X_train_transformed = scaler.transform(X_train)
clf =svm.SVC(kernel='linear',C=1).fit(X_train_transformed, y_train) # 使用训练集训练模型
X_test_transformed = scaler.transform(X_test)
print('归一化的准确率',clf.score(X_test_transformed, y_test)) # 计算测试集的度量值(准确度)
# ================直接调用交叉验证评估模型============
clf = svm.SVC(kernel='linear', C=1)
scores = cross_val_score(clf, iris.data, iris.target, cv=5) #cv为迭代次数
print(scores)
print('Accuracy:%0.2f (+/- %0.2f)'%(scores.mean(), scores.std() ** 2)) # 获取置信区间(也就是均值和方差)
# ===============多种度量结果=============
scoring = ['precision_macro','recall_macro'] # precision_macro为精度,recall_macro为召回率
scores = cross_validate(clf, iris.data, iris.target, scoring=scoring, cv=5, return_train_score=True)
sorted(scores.keys())
print('测试结果:',scores) #scores类型为字典,包含训练得分,拟合次数,score-times (得分次数)
# ==============K折交叉验证、留一交叉验证、留p交叉验证、随机排列交叉验证===========
# k折划分子集
kf = KFold(n_splits=2)
for train, test in kf.split(iris.data):
print("K折划分:%s %s"%(train.shape, test.shape))
break
# 留一划分子集
loo = LeaveOneOut()
for train, test in loo.split(iris.data):
print("留一划分:%s %s"%(train.shape, test.shape))
break
# 留p划分子集
lpo = LeavePOut(p=2)
for train, test in lpo.split(iris.data):
print("留p划分: %s %s"%(train.shape, test.shape))
break
# 随机排列划分子集
ss = ShuffleSplit(n_splits=3, test_size=0.25, random_state=0)
for train_index, test_index in ss.split(iris.data):
print("随机排列划分: %s %s"%(train_index.shape, test_index.shape))
break
# ===================分层K折交叉验证、分层随机交叉验证==============
skf = StratifiedKFold(n_splits=3) #各个类别的比例大致和完整数据集中相同
for train, test in skf.split(iris.data, iris.target):
print("分层K折划分: %s %s"%(train_index.shape, test_index.shape))
break
skf = StratifiedShuffleSplit(n_splits=3) #划分中每个类的比例和完整数据集中相同
for train, test in skf.split(iris.data, iris.target):
print("分层随机划分: %s %s" % (train_index.shape, test_index.shape))
break
# =====================组k-fold交叉验证、留一组交叉验证、留p组交叉验证、Group Shuffle Split==========
X = [0.1,0.2,2.2,2.4,2.3,4.55,5.8,8.8,9,10]
y = ["a","b","b","b","c","c","c","d","d","d"]
groups = [1,1,1,2,2,2,3,3,3,3]
# k折分组
gkf = GroupKFold(n_splits=3) # 训练集和测试集属于不同的组
for train, test in gkf.split(X, y, groups=groups):
print("组 k-fold分割: %s %s"%(train, test))
# 留一分组
logo = LeaveOneGroupOut() # 训练集和测试集属于不同的组
for train, test in logo.split(X, y, groups=groups):
print("留一组分割: %s %s"%(train, test))
# 留p分组
lpgo = LeavePGroupsOut(n_groups=2) # 训练集和测试集属于不同的组
for train, test in lpgo.split(X, y, groups=groups):
print("留p组分割: %s %s"%(train, test))
#随机分组
gss = GroupShuffleSplit(n_splits=4, test_size=0.5, random_state=0) # 训练集和测试集属于不同的组
for train, test in gss.split(X, y, groups=groups):
print("随机分割: %s %s"%(train, test))
#======================时间寻列分割=================
tscv = TimeSeriesSplit(n_splits=3)
TimeSeriesSplit(max_train_size=None, n_splits=3)
for train, test in tscv.split(iris.data):
print("时间序列分割: %s %s"%(train, test))
任务17:机器学习基础知识
目标函数由两个部分个哦,误差函数和正则化项
误差函数:训练误差
正则化:模型的误差
类别
分类:KNN,决策树,svm
回归:一元回归,多元回归,逻辑回归,岭回归,回归树
关联规则:啤酒尿布湿,aproior
聚类:k-means(基于距离的聚类),基于密度的聚类,层次聚类,谱聚类
降维:pca,svd
集成学习:多个模型一起用,bagging,boost
数据清洗:
x-mean/(max-min)
x-mean/std
任务18:最小二乘和logistic回归
#-----最小二乘的拟合------#
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
n = 100
# a = np.linspace(-5,5,n).reshape([100,1])
# y = 5. * a + 2. + np.random.rand(n).reshape([100,1])
# 多维线性拟合
a = np.random.randn(n*3).reshape([n,3])
y = 5. * a[:,0] + 2. * a[:,1] + a[:,2] + np.random.randn(n)
print(y[:10])
# 数据分割
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(a, y, test_size=1/4, random_state=0)
print(X_train.shape, X_test.shape, Y_train.shape, Y_test.shape)
# 加载模型并训练
from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor = regressor.fit(X_train, Y_train)
# 预测
Y_pred = regressor.predict(X_test)
print(Y_pred)
print(Y_test)
# 训练效果
# plt.scatter(X_train, Y_train, color = 'red')
# plt.plot(X_train, regressor.predict(X_train), color = 'blue')
# plt.show()
# 测试效果
# plt.scatter(X_test, Y_test, color='red')
# plt.plot(X_test, regressor.predict(X_test), color = 'blue')
# plt.show()
#画sigmoid函数
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 1000)
y = 1/(1 + np.exp(-x))
plt.grid(axis="x",color='r')
plt.grid(axis="y",color='r')
plt.plot(x,y)
plt.show()
任务19:朴素贝叶斯和KNN
knn推荐里使用的
欧氏距离
曼哈顿距离
闵可夫斯基距离
余弦距离
汉明距离
KNN的k怎么选,3,5,7,9交叉验证选择合适的k
为什么要用kd树?不用暴力枚举所有的点,计算距离
贝叶斯不好用的情况,变量之间相关性比较高
任务20:SVM
svm的三大法宝:最大化间隔(理论基础),对偶算法(减少计算量),核技巧(提供了svm非线性计算的能力)
软间隔和硬间隔区别
核函数怎么选,先选线性,不行,用高斯,参数用交叉验证
任务21:关联规则(apriori)
关联规则就是将所有可能进行遍历
支持度:频率
原则(定理):
1.非频繁项集的组合是非频繁项集
2.频繁项集的子集都是频繁的
任务22:集成学习
bagging是并行计算,得到多个模型。如果是分类,最后用投票的方式。如果是回归就用均值 random forest
Boosting是串行计算,用第一个模型得到的东西(loss),然后第二个模型才能继续使用
1)样本选择上
Bagging:训练集在原始集中是有放回选取的
Boosting:每一轮的训练集不变的
2)样例权重上
Bagging:使用均匀取样,每个样例的权重相等
Boosting:根据错误率不断调整样例的权值,错误率越大权重越大
3)预测函数
Bagging:所有预测函数的权重相等
Boosting:每个弱分类器都有相应的权重,对于分类误差小的分类器也有更大的权重
4)并行计算
Bagging:各个预测函数可以并行生成
Boosting:各个预测函数只能按照顺序生成,因为后一个模型参数需要前一轮模型的结果
提升树:基于Boosting,三颗树,第一个树x到y,第二棵树是y到loss,第三棵树是loss到loss间
任务23:降维(pca)
无监督学习:关联规则,KNN,PCA
为什么要降维?
减少计算量,便于可视化,高维数据的反常识性
反常识性质:
1.高维空间里球的体积接近于0
2.超立方体的内接超球体积也应该是0,点只能分布在立方体和球体积之间的夹缝中
3薄壳的体积接近于1
4超空间的对角线为1
5多元正态的密度为空心的圈
目标:保留重要的信息,删除不重要的维度
1.计算维度的重要性,方差衡量变化。之前需要归一化
pca和svd区别,前者特征值分解,后者任意的矩阵都可以
tsne先聚类再把去维度
任务24:集成学习(blending和stacking)
Blending 流程
Blending相较于Stacking来说要简单一些,其流程大致分为以下几步:
1将数据划分为训练集和测试集(test_set),其中训练集需要再次划分为训练集(train_set)和验证集(val_set);
2创建第一层的多个模型,这些模型可以使同质的也可以是异质的;
3使用train_set训练步骤2中的多个模型,然后用训练好的模型预测val_set和test_set得到val_predict, test_predict1;
4创建第二层的模型,使用val_predict作为训练集训练第二层的模型;
5使用第二层训练好的模型对第二层测试集test_predict1进行预测,该结果为整个测试集的结果
Stacking 流程
Stacking流程比较复杂因为涉及到交叉验证的过程,其流程与Blending类似,具体如下:
1.将数据划分为训练集和测试集(test_set),对训练集进行划分为K个大小相似的集合,取其中一份作为验证集val_set,其余的为训练集train_set;
2.创建第一层的多个模型,这些模型可以使同质的也可以是异质的;
3.对于每一个模型来说,train_set和val_set是不一样的,如2.2图所示;然后利用各自的train_set训练各自的模型,训练好的模型对各自的val_set和test_set进行预测,得到val_predict和test_predict;
4.创建第二层的模型,将每个模型对应的val_predict拼接起来作为第二层的训练集,将所有模型的test_predict取平均值作为第二层的测试集;用训练好的第二层模型对第二层的测试集进行预测,得到的结果即为整个测试集的结果
创新:
1.bagging的权重可以有Gmean来表示
blending把多个模型得到的y进行组合
ensembling模型融合的方法:
1.average
2.bagging
3.boosting
4.stacking
5.stacknet
Blending与Stacking对比
Blending的优点在于:
1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)
2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集
3.在团队建模过程中,不需要给队友分享自己的随机种子
而缺点在于:
1.使用了很少的数据(是划分hold-out作为测试集,并非cv)
2.blender可能会过拟合(其实大概率是第一点导致的)
3.stacking使用多次的CV会比较稳健
任务10:pytorch的机器学习实践(logistic回归)
1.数据标准化(回归不做标准化)
2.建立模型
3.定义损失函数(mse)
4.定义优化器(梯度下降)
5.训练
epoch:使用训练集的全部数据对模型进行一次完整训练,被称之为“一代训练”
Batch:使用训练集中的一小部分样本对模型权重进行一次反向传播的参数更新,这一小部分样本被称为“一批数据”
Iteration:使用一个Batch数据对模型进行一次参数更新的过程,被称之为“一次训练”