day01-概述-数据预处理-一元线性回归-岭回归-多项式回归
一、概述
1、什么是机器学习
人工智能:
通过人工的方法,实现或近似实现某些需要人类智能处理的问题,
都可以称为人工智能
机器学习:
机器学习是一门能够让编程计算机从数据中学习的计算机科学。
一个计算机程序在完成任务T之后,获得经验E,而该经验的效果
可以通过P得以表现,如果随着T的增加,借助P来表现的E也可以
同步增进,即P与T成正增长关系,则称这样的程序为机器学习系统。
即:自我完善、自我修正、自我增强
2、为什么需要机器学习
1、有助于提高系统的可维护性和可扩展性:
简化或替换人工方式的模式识别,易于系统的开发维护和升级换代。
2、用于解决算法非常复杂或没有算法的问题:
对于那些算法过于复杂,或者没有明确解法的问题,机器学习
系统具有得天独厚的优势。
3、规则发现,算法自动生成,获得对业务的洞见:
通过借鉴机器学习的过程,反向推理出隐藏在业务数据背后的规则
----数据挖掘
3、机器学习的类型
1、按照学习方式划分:有监督学习、无监督学习、半监督学习、强化学习
强化学习:决策奖励的办法,划分奖励与惩罚的,鼓励奖励类学习
2、按照学习过程划分:批量学习、增量学习
3、按照学习策略划分:规则学习(基于模型)、实例学习(基于经验)
4、机器学习的基本流程
1、数据准备:
数据采集
数据清洗
2、机器学习:
数据预处理
选择模型
训练模型
验证模型
3、业务应用:
使用模型
维护和升级
5、机器学习的基本问题
回归问题:
由已知的分布于连续域中的输入和输出,通过不断模拟训练,
找到输入和输出之间的联系,通常这种联系可以通过一个函数
方程被形式化,如:y=w0+w1x+w2x^2+w3x^3...,当提供未知
输出的输入时,就可以根据以上函数方程,预测出与之对应的
连续输出。这就就是回归问题。
例:
根据输入预测分布于连续域中的输出。
1 2
2 4
3 6 -----> 得到预测函数y = 2 x
3.5 7
4.5 ? -> 9
分类问题:
如果将回归问题中的输出为连续域,若变为输出离散域,那么
该问题就是一个分类问题。
可以说,分类问题是一个特殊的回归问题。
例:
根据输入预测分布于离散域中的输出。
1 0
2 1
3 0 ------>奇偶判断:奇数 0 , 偶数 1
4 1
5 ? -> 0
聚类问题:
从已知的输入中寻找某种模式,比如相似性,根据该模式将
输入划分为不同的集群,并对新的输入应用同样的划分方式,
以确定其归属的集群。
即:根据样本特征的相似性将其划分为不同的族群
降维问题:
在不影响学习效果的前提下减少样本的特征数
从大量的特征中
例如高斯模糊,浮雕效果,等等都是保留关键特征的方法
二、数据预处理
1.框架
import sklearn
经典机器学习框架
用于学习的科学工具包,使用比较广泛的一种机器学习工具
import sklearn.preprocessing as sp
2.样本矩阵
在我们所面对的数据中,通常我们会调整为数据结构
这个数据结构叫:样本矩阵,即训练样本
分为输入数据和输出数据:
输入数据 输出数据
特征1 特征2 特征3 ...
身高 体重 年龄 性别
样本1 1.7 60 25 男
样本1 1.5 50 20 女
...
输出数据通常为一个一位数组或列向量
通过机器学习来获得输入数据和输出数据之间关系,以便输出数据
一个样本,与一个输出数据元素,是一一对应关系。
3.均值移除(标准化:标准正态分布)
标准正态分布特征:均值为0,方差为1
均值移除主要解决问题:
在一个样本中,不同特征和均值分散度不一致的问题
如:特征A 均值为10 误差+-5
特征B 均值为1000 误差+-5000
此时两个特征体现在一个事件时,特征A就很难体现出来,
被特征B淹没了(特征淹没)。
解决:通过算法调整令样本矩阵中特征的平均值为0,标准差为1,
这样一来,所有特征对最终模型的预测结构结果都有接近一致
的贡献,模型对每个特征的倾向更加平衡
标准化过程:
1.均值移除过程:
如有三个特征,[a b c] 平均值为:m = (a+b+c)/3
设a'=a-m b'=b-m c'=c-m,
得到新的特征值[a' b' c']
新特征值的平均值为:
m' = (a+b'+c')/3
= (a-m+b-m+c-m)/3
= (a+b+c-3m)/3
= (a+b+c)/3-m = m-m
=0 (均值移除成功)
2.标准差计算过程:
离差分别为: (a-m) (b-m) (c-m)
离差方分别为:(a-m)^2 (b-m)^2 (c-m)^2
方差为:((a-m)^2+(b-m)^2+(c-m)^2)/3
得到标准差s =sqrt(((a-m)^2+(b-m)^2+(c-m)^2)/3)
得出:(a-m)^2+(b-m)^2+(c-m)^2) = 3s^2
将新的特征值除以标准差,得到新的数组:[a" b" c"]
其中:a"=a'/s b"=b'/s c"=c'/s
对新的数组再次求标准差:
计算可得知新数组的均值m"=0
标准差s"=sqrt(((a"-m")^2+(b"-m")^2+(c"-m")^2)/3)
=sqrt((a"^2+b"^2+c"^2)/3)
=sqrt(((a'/s)^2+(b'/s)^2+(c'/s)^2)/3)
=sqrt((a'^2+b'^2+c'^2)/(3s^2))
=sqrt(((a-m)^2+(b-m)^2+(c-m)^2)/(3s^2))
=sqrt((3s^2)/(3s^2))
=1
自动计算模块:
sp.scale(原始样本矩阵)-->获得均值移除后的样本矩阵
代码示例:std.py
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([ #样本
[3, -1.5, 2, -5.4],
[0, 4, -0.3, 2.1],
[1, 3.3, -1.9, -4.3]
])
#以下手动完成均值移除过程
print(raw_samples.mean())#这是计算所有元素的平均值
print(raw_samples.mean(axis=0))#这是按列方向计算平均值
print(raw_samples.std(axis=0))#按列方向计算标准差
std_samples = raw_samples.copy()
for col in std_samples.T: #T转置,通过遍历获得列数据
col_mean = col.mean()
col_std = col.std()
col -= col_mean
col /= col_std
print(std_samples)
#均值手动移除成功,机器学习训练模型矩阵就用std_samples
print(std_samples.mean(axis=0)) #都是-16次方以上,为0
print(std_samples.std(axis=0))#标准差为1
#以下用sklearn模块自动移除均值
std_samples = sp.scale(raw_samples)
print(std_samples)
print(std_samples.mean(axis=0))
print(std_samples.std(axis=0))
4.范围缩放
概念引例:
如果有三组平均分数:A:90, B:80, C:5
就怎么看,哪组分数最高?认为90?
其实不尽然,因为A是150分制,B是100分制,C是5分制
如此看来,5分最高
所以在此情况下拿分数去训练,显然是不行的,
此时就需要使用范围缩放:
要么统一为0-150方式,要么0-100,要么0-1 ,...
概念:
将样本矩阵中每列元素通过某种线性变换(y=kx+b),
使得所有列的元素都处在同样的范围区间。
实现过程:
设有一个特征数组中有最大值max,最小值min
已知目标范围最大值max' 1,最小值min' 0
求解 kx + b = y 的方程组中的k,b
即:
k min + b = min'
k max + b = max'
| min | * | k | = | min' |
| max | | b | | max' |
---------- ----- ---------
a x b
解线性方程组:
x = np.linalg.solve(a, b) 得出k ,b
模块:
范围缩放器=sp.MinMaxScaler(
feature_range=(min', max'))
范围缩放器.fit_transform(原始样本矩阵)
->获得范围缩放后的样本矩阵
注:有时候也把[0,1]区间作为目标范围的缩放,称为“归一化”
代码示例:mms.py
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([ #样本
[3, -1.5, 2, -5.4],
[0, 4, -0.3, 2.1],
[1, 3.3, -1.9, -4.3]
])
mms_samples = raw_samples.copy()
#以下手动方法计算范围缩放:
for col in mms_samples.T:
col_max = col.max()
col_min = col.min()
a = np.array([
[col_min,1],
[col_max,1]
])
b = np.array([0,1])
x = np.linalg.solve(a,b)
#根据:y=kx+b
col *= x[0] # kx
col += x[1] # kx + b
print(mms_samples)
#以下模块缩放器计算范围缩放:
mms = sp.MinMaxScaler(feature_range=(0, 1)) #创建缩放器
mms_samples = mms.fit_transform(raw_samples)#获得范围缩放后的样本矩阵
print(mms_samples)
5.归一化
概念:
用每个样本的各个特征值占该样本所有特征值的绝对值的总和
的比例来代替该特征值本身。
即:特征值占比来代替特征值
概念引例:
以下为各语言各年份使用人数的样本:
Python Java C++ PHP
2017 10 20 5 2
2018 20 10 10 1
2019 5 2 1 0
样本值 / 特征值之和:
10/37 --> (10+20+5+2)/37 *100% = 1
20/41 所以叫归一
5/8 通过占比反映增量趋势
模块:sp.normalize(, norm='l1')
->归一化后的样本矩阵
norm= 'l1':绝对值之和,l1范数
'l2':绝对值平方之和,l2范数
...
'ln':绝对值n次方之和,ln范数
代码示例:nor.py
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([ #样本
[3, -1.5, 2, -5.4],
[0, 4, -0.3, 2.1],
[1, 3.3, -1.9, -4.3]
])
nor_samples = raw_samples.copy()
#以下手动归一化
for row in nor_samples:
row_abssum = abs(row).sum()
row /= row_abssum
print(nor_samples)
print(abs(nor_samples).sum(axis=1))
#以下使用模块归一化
nor_samples = sp.normalize(raw_samples,norm='l1')
print(nor_samples)
print(abs(nor_samples).sum(axis=1))
6.二值化
概念:
根据给定的阈值,将样本矩阵中的每一个特征值与该阈值进行
比较,凡是大于该阈值者为1,否则为0,将样本矩阵简化为只
由0和1组成的矩阵,以此来简化学习模型。
可称为0,1化,或者叫开关化
对细节不关心
模块:
二值化器=sp.Binarizer(threshold=阈值)
二值化器.transform(原始样本矩阵)
->二值化后的样本矩阵
代码示例:bin.py
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([ #样本
[3, -1.5, 2, -5.4],
[0, 4, -0.3, 2.1],
[1, 3.3, -1.9, -4.3]
])
bin_samples = raw_samples.copy()
#假如设定阈值为1.4
bin_samples[bin_samples <= 1.4] =0
bin_samples[bin_samples > 1.4] =1
print(bin_samples)
#模块创建
bin = sp.Binarizer(threshold=1.4)
bin_samples = bin.transform(raw_samples)
print(bin_samples)
7.独热编码
概念:
用一个只包含一个1和若干个0的序列来表达每个特征值的编码方式,
借此即保留了样本矩阵的所有细节,同时又得到一个只包含1、0
的稀疏矩阵,即可以提供模型的容错性,同时还能节省内存空间。
概念引例:
假如有以下4个样本,3个特征:
1 3 2
7 5 4
1 8 6
7 3 9
--------------------------
第一列:1用10表示,7用01表示
第二列:3用100表示,5用010表示,8用001表示
第三列:2用1000表示,4用0100表示,6用0010表示,9用0001表示
得到以下编码字典:
1:10 3:100 2:1000
7:01 5:010 4:0100
8:001 6:0010
9:0001
将编码字典对原矩阵进行替换如下:
101001000
010100100
100010010
011000001
变为典型的二值稀疏矩阵,就形成了独热编码
模块:
独热编码器=sp.OneHotEncoder(categories='auto',
sparse=是否紧凑, dtype=元素类型)
独热编码器.fit_transform(原始样本矩阵)
->独热编码后的样本矩阵
代码示例:ohe.py:
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array([ #样本
[1 , 3 , 2],
[7 , 5 , 4],
[1 , 8 , 6],
[7 , 3 , 9]
])
#以下手动创建独热编码:
code_tables = []#建立编码字典列表
for col in raw_samples.T:
#针对一列创建编码字典
code_table={}
for val in col:
code_table[val] = None
code_tables.append(code_table)
#为编码字典列表中的编码字典添加值
for code_table in code_tables:
size = len(code_table)
#code_table.keys()对每个列键排序
#enumerate(sorted(code_table.keys())),获得排序序号
for one,key in enumerate(sorted(code_table.keys())):
code_table[key]=np.zeros(shape=size,dtype=int)
code_table[key][one] = 1
#根据编码字典表对原始样本矩阵做独热编码
ohe_samples = []
for raw_sample in raw_samples:
ohe_sample = np.array([],dtype=int)
for i,key in enumerate(raw_sample):
ohe_sample = np.hstack((ohe_sample,code_tables[i][key]))
ohe_samples.append(ohe_sample)
ohe_samples = np.array(ohe_samples)
print(ohe_samples)
#使用独热编码器模块:
ohe = sp.OneHotEncoder(sparse=False,dtype=int,categories='auto')
ohe_samples = ohe.fit_transform(raw_samples)
print(ohe_samples)
8.标签编码
概念:
将文本形式的特征值变为数值形式的特征值
将样本矩阵中的非数值列,按照字典序中的序号进行替换,
以此把非数值形式的特征值数值化,便于在学习模型中参与运算。
概念引例:
职务 编码1 车 编码2
员工 3 丰田 3
组长 4 福特 4
经理 1 奥迪 1
老板 2 宝马 2
编码数值顺序按照字符顺序,与本身含义顺序无关
如有关,则不能使用标签编码
模块:
标签编码器=sp.LabelEncoder()
标签编码器.fit_transform(原始非数值列)
->标签编码后的数值列
逆向标签编码器.inverse_tansform(标签编码后的数值列)
->原始非数值列
代码示例:lab.py:
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array(
['audi' ,'ford','audi','toyota','ford','bmw','toyota','bmw'])
lbe = sp.LabelEncoder()
lbe_samples = lbe.fit_transform(raw_samples)
print(lbe_samples)
raw_samples = lbe.inverse_transform(lbe_samples)
print(raw_samples)
三、一元线性回归
1.预测函数
根据输入预测分布于连续域中的输出。
1 2
2 4
3 6 -----> 得到预测函数y = 2 x
3.5 7
4.5 ? -----> 9
一元预测函数模型为:y=w0+w1x
注:一元线性回归的方程一定是这样的模型格式
任务就是通过寻找预测函数模型参数w0和w1,
以便满足输入和输出之间的联系
2.单样本误差
假定有一值为x,对应的实际值为y,
带入方程后,得到预测值,即y':
x--->[y=w0+w1x]-->y'-->y-y'就是样本误差
单样本误差e = (1/2)*(实际值y-预测值y')^2
3.总样本误差
E=∑(e)=∑((1/2)*(y-y')^2)
4.损失函数
Loss(w0,w1)= ∑((1/2)*(y-y')^2) = ∑((1/2)*(y-(w0+w1x))^2)
一元线性回归任务变为:
寻找可以使损失函数取得最小值的模型参数w0和w1。
5.梯度下降法
随机选择一组模型参数w0和w1
计算损失函数在该模型参数处的梯度<------+
[∂loss/∂w0,∂loss/∂w1] |
再计算与该梯度反方向的修正步长 |
[-η∂loss/∂w0,-η∂loss/∂w1] η学习率 |
再计算下一组模型参数: |
w0 = w0-η∂loss/∂w0 |
w1 = w1-η∂loss/∂w1 ----------------->+
注:η学习率 (learning rate),控制模型的学习进度
学习率设置
在训练过程中,一般根据训练轮数设置动态变化的学习率。
刚开始训练时:学习率以 0.01 ~ 0.001 为宜。
一定轮数过后:逐渐减缓。
接近训练结束:学习速率的衰减应该在100倍以上。
再执行下一个循环,计算梯度,逐渐逼近
直到满足迭代终止条件:
迭代次数足够多,如10万次
或损失值已经足够小
或损失值已经不再明显减少
Loss(w0,w1)= ∑((1/2)*(y-y')^2) , y'= w0 + w1x
∂loss/∂w0
=∑(∂(1/2)*(y-y')^2)/∂w0)
=∑((y-y')*∂(y-y')/∂w0)
=∑((y-y')*(∂y/∂w0-∂y'/∂w0)) 因为y是已知常量,所以∂y/∂w0=0
=-∑((y-y')*(∂y'/∂w0)) 因为∂y'/∂w0=1
=-∑((y-y'))
∂loss/∂w1
=∑(∂(1/2)*(y-y')^2)/∂w1)
=∑((y-y')*∂(y-y')/∂w1)
=∑((y-y')*(∂y/∂w1-∂y'/∂w1)) 因为y是已知常量,所以∂y/∂w1=0
=-∑((y-y')*(∂y'/∂w1)) 因为∂y'/∂w1=x
=-∑((y-y')*x)
6.多元线性回归
即样本函数模型为:y=w0+w1x1+w2x1+...+wnxn
其实质同一元线性回归是一样的。
Loss(w0,w1,w2,...,wn) = ∑((1/2)*(y-(w0+w1x1+w2x2+...+wnxn]))^2)
w0 = w0-η∂loss/∂w0
w1 = w1-η∂loss/∂w1
w2 = w2-η∂loss/∂w2
... ...
wn = wn-η∂loss/∂wn
∂loss/∂w0 = -∑((y-y'))
∂loss/∂w1 = -∑((y-y')*x1)
∂loss/∂w2 = -∑((y-y')*x2)
... ...
∂loss/∂wn = -∑((y-y')*xn)
预测函数:y'= w0+w1x1+w2x2+...+wnxn
6.模块
import sklearn.linear_model as lm
线性回归器 = lm.LinearRegression()
线性回归器.fit(已知输入,已知输出) #计算模型参数
线性回归器.predict(新的输入)-->获得新的输出(预测输出)
7.模型保存与调用
import pickle
保存:
预测输出成功后,即可保存预测模型
with open('文件名','wb') as f:
pickle.dump(model,f)
调用:
with open('模型文件','rb') as f:
model = pickle.load(f)
8.示例代码:
示例一:手动处理 gd.py (手动处理线性回归)
import numpy as np
import matplotlib.pyplot as mp
from mpl_toolkits.mplot3d import axes3d
train_x = np.array([0.5,0.6,0.8,1.1,1.4]) #输入样本
train_y = np.array([5.0,5.5,6.0,6.8,7.0]) #输出样本
#手动方法实现一元线性回归:
n_epoches = 1000 #设定迭代终止条件:最大迭代次数
lrate = 0.01 # η学习率
epoches,losses = [],[] #epoches迭代批次列表 , losses 每次迭代损失值
w0,w1 = [1],[1] #保存每次迭代得出的值,初始值设为1
for epoch in range(1,n_epoches + 1):
epoches.append(epoch)
furch_y = w0[-1] + w1[-1] * train_x #预测输出y'
losses.append(
((train_y - furch_y)**2/2).sum())#Loss(w0,w1)= ∑((1/2)*(y-y')^2)计算损失值
# print('{:4}>w0={:.8f},|w1={:.8f},loss={:.8f}'.format(
# epoches[-1],w0[-1],w1[-1],losses[-1]
# ))
d0 = -(train_y - furch_y).sum() #∂loss /∂w0 = -∑((y-y'))
d1 = -((train_y - furch_y) * train_x).sum() #∂loss/∂w1 = -∑((y-y')* x)
w0.append(w0[-1] - lrate * d0) # w0 = w0 - η∂loss/∂w0
w1.append(w1[-1] - lrate * d1) # w1 = w1 - η∂loss/∂w1
w0 = np.array(w0[:-1]) #注:实际w0会产生1001组数据,所以少去一个。
w1 = np.array(w1[:-1])
sorted_indexes = train_x.argsort()
test_x = train_x[sorted_indexes]
test_y = train_y[sorted_indexes]
pred_test_y = w0[-1] + w1[-1] * test_x #预测输出,一元线性方程y = w0 + w1 * x
grid_w0,grid_w1 = np.meshgrid( #创建点阵并网格化
np.linspace(0,9,500), np.linspace(0,3.5,500))
#用网格化计算对应损失值
flat_w0,flat_w1 = grid_w0.ravel(),grid_w1.ravel() #扁平化视图
flat_loss = (((flat_w0 + np.outer(train_y,flat_w1))-\
train_y.reshape(-1,1))**2).sum(axis=0)/2 #outer外积 计算损失值
grid_loss = flat_loss.reshape(grid_w0.shape)
mp.figure('Linear Regression',facecolor='lightgray')
mp.title('Linear Regression',fontsize=20)
mp.xlabel('x',fontsize=14)
mp.xlabel('y',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(train_x,train_y,marker='s',c='dodgerblue',
alpha=0.5,s=80,label='Traning') #训练样本点
mp.scatter(test_x,test_y,marker='D',c='orangered',
alpha=0.5,s=40,label='Testing')
mp.scatter(test_x,pred_test_y,c='orangered',
alpha=0.5,s=40,label='Predicted') #预测输出
for x,y,pred_y in zip(test_x,test_y,pred_test_y):#连线长度即为单样本误差
mp.plot([x,x],[y,pred_y],c='orangered',alpha=0.5,linewidth=1)
mp.plot(test_x,pred_test_y,'--',c='limegreen',
label='Regression',linewidth=1)
mp.legend()
#训练过程
mp.figure('Training Progress',facecolor='lightgray')
mp.subplot(311)
mp.title('Training Progress',fontsize=20)
mp.ylabel('w0',fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches,w0,c='dodgerblue',label='w0')
mp.legend()
mp.subplot(312)
mp.ylabel('w1',fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches,w1,c='limegreen',label='w1')
mp.legend()
mp.subplot(313)#损失值
mp.title('loss',fontsize=20)
mp.xlabel('epoch',fontsize=14)
mp.ylabel('loss',fontsize=14)
mp.gca().xaxis.set_major_locator(mp.MultipleLocator(100))
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.plot(epoches,losses,c='orangered',label='loss')
mp.legend()
mp.tight_layout()
mp.figure('Loss function')
ax = mp.gca(projection='3d')
mp.title('Loss function',fontsize=20)
ax.set_xlabel('w0',fontsize=14)
ax.set_ylabel('w1',fontsize=14)
ax.set_zlabel('loss',fontsize=14)
mp.tick_params(labelsize=10)
#mp.grid(linestyle=':')
ax.plot_surface(grid_w0,grid_w1,grid_loss,
rstride=10,cstride=10,cmap='jet')
ax.plot(w0,w1,losses,'o-',c='orangered',label='BGD')
mp.legend()
#梯度下降
mp.figure('Batch Gradient Descent',facecolor='lightgray') #批量梯度下降
mp.title('Batch Gradient Descent',fontsize=20)
mp.xlabel('x',fontsize=14)
mp.xlabel('y',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.contourf(grid_w0,grid_w1,grid_loss,1000,cmap='jet')#等高线图
cntr = mp.contour(grid_w0,grid_w1,grid_loss,10,colors='black',
linewidths=0.5)
mp.clabel(cntr,inline_spacing=0.1,fmt='%.2f',
fontsize=8)#标准等高线高度值
mp.plot(w0,w1,'o-',c='orangered',label='BGD')
mp.legend()
mp.show()
示例二:模块处理 line.py(模块处理线性回归)
import numpy as np
import matplotlib.pyplot as mp
import sklearn.linear_model as lm
import sklearn.metrics as sm
# train_x = np.array([0.5,0.6,0.8,1.1,1.4]) #输入样本
# train_y = np.array([5.0,5.5,6.0,6.8,7.0]) #输出样本
# lm = lm.LinearRegression()
# lm.fit(train_x.reshape(train_x.size,1),train_y)
# print(lm.predict(train_x.reshape(train_x.size,1)))
x,y = [],[]
with open('./data/single.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y)
model = lm.LinearRegression()
model.fit(x,y)
pred_y = model.predict(x)#预测输出 y是实际输出,两者之差为样本误差
#sm.r2_score二次得分,看看二者有多少相等,多少不等
r2score =sm.r2_score(y,pred_y) # 计算公式:1/(1+E) 误差归一化
#print(r2score) #误差越小,r2score越接近1
mp.figure('Linear Regression',facecolor='lightgray')
mp.title('Linear Regression',fontsize=20)
mp.xlabel('x',fontsize=14)
mp.xlabel('y',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x,y,marker='s',c='dodgerblue',
alpha=0.75,s=60,label='Traning') #样本散点图
sorted_indices = x.ravel().argsort()#画图前排序
mp.plot(x[sorted_indices],pred_y[sorted_indices],
c='orangered',label='Regression') #绘制回归线:预测输出线
mp.legend()
mp.tight_layout()
mp.show()
示例三:保存预测模型 dump.py
import pickle #序列号工具,内存和文件进行序列号
import numpy as np
import sklearn.linear_model as lm
import sklearn.metrics as sm
x,y = [],[]
with open('./data/single.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y)
model = lm.LinearRegression()
model.fit(x,y)
pred_y = model.predict(x)#预测输出 y是实际输出,两者之差为样本误差
#sm.r2_score二次得分,看看二者有多少相等,多少不等
r2score =sm.r2_score(y,pred_y) # 计算公式:1/(1+E) 误差归一化
#print(r2score) #误差越小,r2score越接近1
with open('./data/linear.pkl','wb') as f: #保存训练模型
pickle.dump(model,f)
示例四:调用训练模型 load.py
import pickle #序列号工具,内存和文件进行序列号
import numpy as np
import sklearn.metrics as sm
x,y = [],[]
with open('./data/single.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y)
with open('./data/linear.pkl','rb') as f: #调查已经存在的模型
model = pickle.load(f)
pred_y = model.predict(x)
r2score =sm.r2_score(y,pred_y)
print(r2score)
四、岭回归
1.概念
因loss(w0,w1)=∑((1/2)*(y-(w0+w1x]))^2)
岭回归方程为:
Loss(w0,w1)=loss(w0,w1)-正则强度*f(w0,w1)(正则项)
f(w0,w1)称为正则项
目的是要让Loss(w0,w1)达到最小,但因为有了
正则强度*正则项的存在,loss(w0,w1)则会偏离最小值
如果正则强度*正则项越大,则loss(w0,w1)对异常样本的
倾向性就会越弱。通过正则强度进行控制。
通过正则的方法,即在损失函数中加入正则项,
以减弱模型参数对熟练数据的匹配度,以此规避少量样本
因为明显偏移正常范围的异常而影响模型的回归效果。
注:此处正则不是对字符串的操作,不是正则表达式的意思
而是让步的意思
普通的线性回归,在计算总样本误差即损失值时,对所有训
练样本一视同仁,因此极少数"坏"样本会使得预测模型偏离
于大多数好样本所遵循的规则,影响模型的预测精度。
岭回归就是:
在线性回归的基础之上,为每个训练样本分配不同的权重,越是
能够反应一般规律的大多数好样本所得到的权重越大,而极少数
偏离于一般规律的坏样本则只能获得较低的权重,从而使得最终
的预测模型尽可能偏向于多数好样本,而弱化少数坏样本对模型
的影响。
2.模块
model = lm.Ridge(正则强度,fit_intercept=True)
fit_intercept:是否约束斜率和截距,
True反向破坏样本匹配效果
正则强度:也是叫惩罚力度:[0, oo)
正则强度越小,权重差异就越小,0表示无差异,等同线性回归
类似正则强度这些数据,叫超参数,因为无法通过算法得出,
只能通过实验或试验人为获得的数据。
但有一种自动化选优的方式获取超参数
网格搜索是一种自动化选优的方法:把所有超参数排列组合到
一个表中,可以自动一个一个去测试,然后将结果分值都返回,
然后挑选一个分值(或效果)最好的作为最终使用的参数。
可不同行业,不同的数据源,创建超参数经验数据表
代码示例:rdg.py
import numpy as np
import matplotlib.pyplot as mp
import sklearn.linear_model as lm
x,y = [],[]
with open('./data/abnormal.txt','r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y)
model1 = lm.LinearRegression() #model1为线性回归模型
model1.fit(x,y)
pred_y1 = model1.predict(x)#线性回归预测值
model2 = lm.Ridge(300,fit_intercept=True)#model2为岭回归模型
model2.fit(x,y)
pred_y2 = model2.predict(x)#岭回归预测值
mp.figure('Linear & Ridge Regression',facecolor='lightgray')
mp.title('Linear & Ridge Regression',fontsize=20)
mp.xlabel('x',fontsize=14)
mp.xlabel('y',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(x,y,marker='s',c='dodgerblue',
alpha=0.75,s=60,label='Traning') #样本散点图
sorted_indices = x.ravel().argsort()
mp.plot(x[sorted_indices],pred_y1[sorted_indices],
c='orangered',label='Linear') #绘制线性回归线
mp.plot(x[sorted_indices],pred_y2[sorted_indices],
c='dodgerblue',label='Ridge') #绘制岭回归线
#可以看出,岭回归线受上方三个不良样本的影响较小
#正则强度如果0,则岭回归就同线性回归重叠
mp.legend()
mp.tight_layout()
mp.show()
五、多项式回归
1.概念
y = w0+w1x+w2x^2+w3x^3+...+wnx^n
令:x=x1, x^2=x2, x^3=x3 ,..., x^n=xn
以上多项式回归方程就简化为多元线性回归方程
即:y = w0+w1x1+w2x2+w3x3+...+wnxn
loss = Loss(w0,w1,...,wn)
x->多项式特征扩展-x1,x2,x3,...,xn->线性回归->w0~wn
\________________________________/
管线
2.模块
import sklearn.pipeline as pl
import sklearn.preprocessing as sp
多项式特征扩展器=sp.PolynomialFeatures(最高次幂)
线性回归器=lm.LinearRegression()
管线模型=pl.make_pipeline(多项式特征扩展器,线性回归器)
管线模型.fit(x,y) # [x,y]-BGD->[w0,w1,w2,w3,...,wn]
管线模型.predict(x)->pred_y
3.欠拟合:过于简单的模型,或者训练集的规模过小,导致模型无法真实
地反应输入和输出之间的规律,出现训练集和测试集的评估分值都比
较低的现象。可以通过增加模型的复杂度,或者增加训练集的规模,
提高模型的拟合度,优化其性能。
4.过拟合:过于复杂的模型,或者特征数过多,导致模型失去足够的一般性,
即太过于倾向训练数据,反而对训练集以外的预测性能大幅下降。可以
减少特征数,或者降低模型的复杂度,在训练集和测试集的拟合程度上
寻求一个折衷,提高模型的泛化能力。
5.代码示例:poly.py
import numpy as np
import sklearn.pipeline as pl
import sklearn.preprocessing as sp
import sklearn.metrics as sm
import matplotlib.pyplot as mp
import sklearn.linear_model as lm
train_x,train_y = [],[]
with open('./data/single.txt','r') as f:
#with open('./data/abnormal.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr in line.split(',')]
train_x.append(data[:-1])
train_y.append(data[-1])
train_x = np.array(train_x)
train_y = np.array(train_y)
#在多项式特征扩展器的参数是超参数,合适的大小才能真实反映样本情况
#过大,容易形成过拟合,太小,欠拟合
sp = sp.PolynomialFeatures(10)#多项式特征扩展器,最高为x**10,增加9列,共10列
lm = lm.LinearRegression() #线性回归器
model = pl.make_pipeline(sp,lm) #创建多项式管线模型
model.fit(train_x,train_y) #计算模型参数(w0,w1,...w10)
pred_train_y = model.predict(train_x) #获得多项式回归预测值
print(sm.r2_score(train_y,pred_train_y))
test_x = np.linspace(train_x.min(),train_x.max(),1000).reshape(-1,1)
pred_test_y = model.predict(test_x)
mp.figure('Polynomial Regression',facecolor='lightgray')
mp.title('Polynomial Regression',fontsize=20)
mp.xlabel('x',fontsize=14)
mp.xlabel('y',fontsize=14)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.scatter(train_x,train_y,c='dodgerblue',
alpha=0.75,s=60,label='Sample')
mp.plot(test_x,pred_test_y,c='orangered',label='Regression')
mp.legend()
mp.tight_layout()
mp.show()
python MachinelEarning机器学习笔记day01
猜你喜欢
转载自blog.csdn.net/pinecn/article/details/89743056
今日推荐
周排行