知识点小结
1、线性回归模型
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(x。reshape(-1,1),y)
y_ = lr.predict(x.reshape(-1,1))
2、机器学习自带的数据
import sklearn.datasets as datasets
diabetes = datasets.load_diabetes() #存在本地的数据
datasets.fetch_ #从网路上下载数据
各种线性回归使用方法:
一般情况下 用普通线性回归即可 图片中的情况用rr
如果有很多特征 但是其中的一部分特征肯能是没用的 这个时候可以用lasso试一试
通俗解释线性回归:画一条线,将图上的点都尽量多的压住
原理: 最小二乘法(算法)
回归曲线: 通过最小二乘法画出回归曲线。
f(x) = wx + b 这个就是一条线的公式
在画图中, 将w称为斜率,b称为偏移(截距)
这里 w(weight)权重 称为b(bias)称为偏差
根据已有的点,通过调整w和b的值,所有点到回归曲线的距离之和最小(点到线的距离也成为损失,目的让损失最小,称为损失函数)
给出一些训练数据,使用训练数据训练线性回归模型,再使用训练模型预测结果。 一般用来预测!
在坐标系上 画出一些点
让机器学习模型通过线性回归 去划线来拟合这些点
产生一些点
x = np.arange(0,10,1)
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y = 3*x+4
y
array([ 4, 7, 10, 13, 16, 19, 22, 25, 28, 31])
注意:这里传入的训练数据格式需要时一个多纬的数组
from sklearn.linear_model import LinearRegression
#获取模型 训练模型
lr = LinearRegression()
lr.fit(x.reshape(-1,1),y) #注意这里需要二维数组
lr.coef_
array([3.])
lr.intercept_
4.000000000000005
y_ = lr.coef_[0]*x+lr.intercept_
plt.plot(x,y_)
plt.scatter(x,y)
注意:这里传入的测试数据格式
y_ = lr.predict(x.reshape(-1,1))
array([ 4., 7., 10., 13., 16., 19., 22., 25., 28., 31.])
x = np.arange(0,10,1) # 从0到10 每隔一个取一个
x
#这里先不看w和b的值是什么
w = np.random.random()*10
b = np.random.random()*5
y = w*x+b
y
array([ 1.89477686, 2.83718029, 3.77958372, 4.72198715, 5.66439058,
6.60679401, 7.54919744, 8.49160087, 9.4340043 , 10.37640773])
lr = LinearRegression()
lr.fit(x.reshape(-1,1),y)
lr.coef_ , lr.intercept_
(array([8.86449376]), 1.8902864471553258)
lr.coef_ , lr.intercept_
(array([2.55223749]), 4.499348433359231)
w ,b
(2.5522374924290614, 4.499348433359228)
可以看出线性回归预测出来的还是挺准确的。
# 糖尿病的数据集 是sklearn的datasets里面自带的
import sklearn.datasets as datasets
diabetes = datasets.load_diabetes()
diabetes
data = diabetes.data # 数据
feature_names = diabetes.feature_names # 特征名
target = diabetes.target # 目标值
lr = LinearRegression()
lr.fit(data,target) # 传入各个样本的特征 和 结果值
w = lr.coef_ # 斜率
w #这里的样本因为有10个特征,所以有10个斜率,在计算时,使用x 与 w点乘,让样本的每个特征和每个斜率进行计算,加上截距,得出样本值
array([ -10.01219782, -239.81908937, 519.83978679, 324.39042769,
-792.18416163, 476.74583782, 101.04457032, 177.06417623,
751.27932109, 67.62538639])
b = lr.intercept_ # 截距
b
152.1334841628965
随机产生一个索引 按照索引从原来的样本中抽取一个数据
看带入模型后算出的结果 和 真实值的偏差
在样本范围内随机产生一个索引
再用产生的随机索引在训练数据中取出一个样本和一个目标值
index = np.random.randint(0,442,size=1)[0]
index #随机索引
data[index] #用随机索引取出一个随机样本
target[index] # 样本值
注意:这里的训练模型的斜率是一个元素数量为10的数组
在预测值的时候要将测试样本与斜率点乘。
y_ = np.dot(w,data[index]) + b
# 看看预测出来的结果和真实结果 差别大不大
print('真实的结果是:',target[index])
print('回归的结果是:',y_)
真实的结果是: 293.0
回归的结果是: 199.6971235680727
lr.predict(data[index].reshape(1,-1))
array([199.69712357])
拿出数据某一列来研究与样本值得关系
研究 bmi 和糖尿病严重程度的关系
我们将bmi这一列拿出来
bmi_data = data[:,2]
机器学习的训练数据要求有 样本和特征,从data中拿出来的数据是一个Series。你能给机器模型直接使用。
bmi_data = bmi_data.reshape(-1,1)
X_train = bmi_data # 特征
y_train = target # 目标值
lr = LinearRegression()
lr.fit(X_train,y_train)
w = lr.coef_
array([949.43526038])
b = lr.intercept_
152.1334841628967
y_ = w*X_train + b
y_
plt.scatter(X_train,y_train)
plt.plot(X_train,y_,color='red')
1、阶:方阵的行数(列数)(方阵的行数和列相等)
2、秩:方阵中有用的行的数量
3、 满秩矩阵:秩 = 阶的方阵
4、奇异矩阵:秩 < 阶 的方阵(某些行没用)
5、主对角线:左上角到右下角的对角线
6、单位矩阵:主对角线上是1 其他地方都是0的方阵
线性回归本质上可以理解为 求各个特征的权重
但是如果特征比样本还多的时候
用线性回归就不能求解了。
比如:
线型回归求这些值可以求出 w
y1 = w1*x1 + w2*x2 + w3*x3
y2 = w1*x1 + w2*x2 + w3*x3
y3 = w1*x1 + w2*x2 + w3*x3
但是观察这些类似于样本的数据:
w1*1 + w2*2 + w3*3 = 10 1 2 3
w1*2 + w2*4 + w3*6 = 20 ==》2 4 6
w1*4 + w2*8 + w3*12 = 40 4 8 12
实际是无法求处w的唯一解的
遇到这种数据时为了求出线性相关,可以给这些数据加一些值造成一点误差。
1 2 3 1 0 0 2 2 3
2 4 6 + 0 1 0 = 2 5 6
4 8 12 0 0 1 4 8 13
这样就可以求类似线性回归的问题了
一般在特征比样本数据多的时候就可以使用岭回归来处理数据。
一般用于图片处理
使用糖尿病例子比较岭回归和普通线性回归
import sklearn.datasets as datasets
diabetes = datasets.fetch_mldata
diabetes
data = diabetes.data
target = diabetes.target
rr = Ridge(alpha=10)
alpha: 岭回归缩减系数
默认为 1
如果参数alpha的值为0 的话,各个特征的权重与普通线性回归一样了。
如果偏差太大,各个特征的权重就几乎为0了。
一般在图像处理的时候
from sklearn.linear_model import Ridge
rr = Ridge(alpha=100) #alpha 引入的误差大小,alpha值越大,误差越大
rr.fit(data,target) #模型训练
rr.coef_
array([ 0.03040324, 0.00695983, 0.09491727, 0.07145177, 0.03430439,
0.02815743, -0.06389202, 0.06965804, 0.09158435, 0.0618977 ])
rr.intercept_
152.1334841628965
from sklearn.linear_model import LinearRegression
lr = LinearRegression() #创建模型
lr.fit(data,target) #训练模型
lr.coef_
array([ -10.01219782, -239.81908937, 519.83978679, 324.39042769,
-792.18416163, 476.74583782, 101.04457032, 177.06417623,
751.27932109, 67.62538639])
lr.intercept_
152.1334841628965
Ridge(alpha=1)
不同的alpha对的值对模型权重的影响
np.arange(1,10,1).reshape(-1,1)
array([[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8],
[9]])
np.arange(0,10,1)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
将上面两个加起来
np.arange(1,10,1).reshape(-1,1)+np.arange(0,10,1)
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
[ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
[ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
[ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14],
[ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
[ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
[ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]])
再1除以这个数据中的每个元素
作为测试集
X = 1/(np.arange(1,10,1).reshape(-1,1)+np.arange(0,10,1)) # 里面都是0到1的数据
X
array([[1. , 0.5 , 0.33333333, 0.25 , 0.2 ,
0.16666667, 0.14285714, 0.125 , 0.11111111, 0.1 ],
[0.5 , 0.33333333, 0.25 , 0.2 , 0.16666667,
0.14285714, 0.125 , 0.11111111, 0.1 , 0.09090909],
[0.33333333, 0.25 , 0.2 , 0.16666667, 0.14285714,
0.125 , 0.11111111, 0.1 , 0.09090909, 0.08333333],
[0.25 , 0.2 , 0.16666667, 0.14285714, 0.125 ,
0.11111111, 0.1 , 0.09090909, 0.08333333, 0.07692308],
[0.2 , 0.16666667, 0.14285714, 0.125 , 0.11111111,
0.1 , 0.09090909, 0.08333333, 0.07692308, 0.07142857],
[0.16666667, 0.14285714, 0.125 , 0.11111111, 0.1 ,
0.09090909, 0.08333333, 0.07692308, 0.07142857, 0.06666667],
[0.14285714, 0.125 , 0.11111111, 0.1 , 0.09090909,
0.08333333, 0.07692308, 0.07142857, 0.06666667, 0.0625 ],
[0.125 , 0.11111111, 0.1 , 0.09090909, 0.08333333,
0.07692308, 0.07142857, 0.06666667, 0.0625 , 0.05882353],
[0.11111111, 0.1 , 0.09090909, 0.08333333, 0.07692308,
0.07142857, 0.06666667, 0.0625 , 0.05882353, 0.05555556]])
X.shape
(9, 10) #这是一个9 行10 列的矩阵
# 这个X就是测试集
结果集
y = np.ones(9)
y
array([1., 1., 1., 1., 1., 1., 1., 1., 1.])
lr = LinearRegression()
lr.fit(X,y)
lr.coef_
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
这里可以看出使用线性回归处理特征数量大于样本数量的数据时,权重都为0。找到的特征和结果无关!
lr.intercept_
1.0
来让岭回归模型来关闭差值,不让差值调整结果值
这样我们获得的斜率就不是0了。
rr = Ridge(fit_intercept=False)
rr.fit(X,y)
rr.coef_
array([0.50338083, 0.4975694 , 0.44988445, 0.40522804, 0.36730309,
0.33543542, 0.3084947 , 0.2854958 , 0.2656627 , 0.24839685])
rr.intercept_
0.0
用以验证种不同alpha值对预测数据的结果的影响
np.logspace(1,3,3) #从1-3分为三个 1 2 3 分别
# 1**10 2**10 3**10
array([ 10., 100., 1000.])
一般alpha的范围取 -1000,200之间,太大会影响结果值
alphas = np.logspace(-10,2,100) # -10 到 2 取100份
alphas
array([1.00000000e-10, 1.32194115e-10, 1.74752840e-10, 2.31012970e-10,
3.05385551e-10, 4.03701726e-10, 5.33669923e-10, 7.05480231e-10,
9.32603347e-10, 1.23284674e-09, 1.62975083e-09, 2.15443469e-09,
。。。
1.51991108e+00, 2.00923300e+00, 2.65608778e+00, 3.51119173e+00,
4.64158883e+00, 6.13590727e+00, 8.11130831e+00, 1.07226722e+01,
1.41747416e+01, 1.87381742e+01, 2.47707636e+01, 3.27454916e+01,
4.32876128e+01, 5.72236766e+01, 7.56463328e+01, 1.00000000e+02])
创建很多的 模型 分别设置不同的 alpha 观察变化
coefs = []
for alpha in alphas:
# 获取模型 设置参数
rr = Ridge(alpha=alpha,fit_intercept=False)
rr.fit(X,y)
coefs.append(rr.coef_)
plt.figure(figsize=(12,8)) #设置画布大小
plt.plot(alphas,coefs) #绘图
# 设置坐标轴 不是以均匀的方式展示 设置x轴线 而是 以10的倍数来显示
plt.xscale('log')
通过观察 岭际线 发现
大于10的-3次方 各个特征的权重就几乎为0了
小于10的-7次方 某些特征的权重的变化幅度就会非常大 很容易出问题
比较保守的猜测 我们在 10的-7次方 到 10的-3次方 之间 取一个alpha值比较合适
线性回归时使 权重的绝对值相加 让其结果不能大于某个值
一般在特征很多的时候,很多特征对结果的影响几乎为0,我们就可以限制 拉姆达的值,让加和小于某个值,其中权重最小的就会被归零,加和的值还大于拉姆达的话,再让最小的归零,知道小于拉姆达为止。
np.random.seed(10) # 给随机数一个种子,他就不会再产生其他的随机数了。
samples = 50 # 有几个样本就有几行
features = 100 # 有几个特征就有几列
X = np.random.randn(samples,features) # 以0为中心,标准差为1的数 参数为形状
# X 作为特征值
w = 10*np.random.randn(features) # 有几个特征就有几个权重的值 给每个权重扩大10倍
w
通过打乱权重的索引,打乱权重的值
然后再通过打乱的索引,取前90个
然后再在原来的权重值中,将随机索引的前90个对应的w值归零,这样就随机归零了90个权重
index = np.random.permutation(features) # 打乱的 各个权重的索引
index[:90] # 找出前九十个索引
w[index[:90]] = 0 # 把前九十个打乱顺序的所对应的权重值 归零
# 各个样本的特征 X
# 各个特征的权重是 w
y = np.dot(X,w)
y
from sklearn.linear_model import LinearRegression,Ridge,Lasso
lr = LinearRegression()
rr = Ridge(alpha=1,fit_intercept=False) #这里主要研究 w 的值,所以为了不受影响,不使用偏差值
lasso = Lasso(alpha=0.8) #alpha 用来设置权重的上限,不过alpha 的值为0-1的小数 用来表示有用的特征的比例
注意:Lasso中的alpha 表示有用特征的比例
例如 共有 5 个特征, 有用的 只有一个,那么 alpha = 0.2
lr.fit(X,y)
rr.fit(X,y)
lasso.fit(X,y)
plt.figure(figsize=(12,8)) #设置画布大小
axes1 = plt.subplot(2,2,1) # 先绘制真实的权重
axes1.plot(w)
axes1.set_title('real')
# 普通线性回归
axes2 = plt.subplot(2,2,2)
axes2.plot(lr.coef_)
axes2.set_title('lr')
# 岭回归
axes3 = plt.subplot(2,2,3)
axes3.plot(rr.coef_)
axes3.set_title('rr')
# 拉索回归
axes4 = plt.subplot(2,2,4)
axes4.plot(lasso.coef_)
axes4.set_title('lasso')