机器学习-回归

回归(regression)是一种统计学的数据拟合方法,逐步的逼近最佳拟合曲线,这个过程中数据看起来似乎渐渐的“回到”这条曲线上。回归分析不仅用于产生拟合曲线,还可以分析数据有“多符合”这条拟合曲线,也即是拟合的置信度。 所以可以简单的认为拟合是目的,回归是实现数据拟合的一种分析方法,除了回归分析以外,还有曲线平滑等其他拟合方法。

多项式回归

假设函数: y = b 0 x 0 + b 1 x 1 + b 2 x 2 + … + b n x (1) y = b_0x^{0} + b_1x^1 + b_2x^2 +\ldots+ b_nx \tag{1} y=b0x0+b1x1+b2x2++bnx(1)
损失函数:和简单线性回归、多变量线性回归一样,多项式回归也是使用mse作为误差。对于这三种回归方法,我们都希望拟合一条线,使得这条线的mse --> min。
M S E = ∑ i = 1 n ( y i − y i ′ ) 2 (2) MSE = \sum_{i=1}^n(y_i - y_i')^2 \tag{2} MSE=i=1n(yiyi)2(2)

案例:使用多项式回归根据岗位级别预测岗位工资

实现步骤:

  • 导入包和数据集
  • 生成合适的自变量
  • 建立多项式回归模型
  • 得到多项式回归算法公式
  • 将预测结果可视化
  • 预测当岗位级别为6.5时,工资应该是多
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib.inline
dataset = pd.read_csv(r'D:\data\Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2].values
plt.figure()
plt.scatter(X,y, color = 'red')
plt.title('Level vs Salary')
plt.xlabel('Position level')
plt.ylabel('Salary')

在这里插入图片描述

# 先构造多项式的特征(升维)
from sklearn.preprocessing import PolynomialFeatures
# interaction_only=True 设置没有变量自己与自己相乘的特征,这个参数默认为False
# include_bias= True 有偏置量,False为没有偏置量,默认为True
poly = PolynomialFeatures(degree=4).fit_transform(X)
#  将特征放在模型中训练
from sklearn.linear_model import LinearRegression
poly_LR = LinearRegression().fit(poly,y)
# 可视化
from sklearn.linear_model import LinearRegression
# 多项式模型lin_reg_1
lin_reg_1 = LinearRegression()
lin_reg_1.fit(X, y)
# 线性模型lin_reg_2
lin_reg_2 = LinearRegression()
lin_reg_2.fit(X_poly, y)

# Visualising the Polynomial Regression results
plt.figure()
plt.scatter(X, y, color = 'red')
plt.plot(X, lin_reg_2.predict(X_poly), color = 'blue')
plt.plot(X, lin_reg_1.predict(X), color = 'green')
plt.title('Truth or Bluff (Polynomial Regression)')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()

在这里插入图片描述

支持向量机回归

在简单线性回归、多变量线性回归、多项式回归中,自变量与因变量都对应一种数学关系(可解释性强)。但是在现实中自变量和因变量有时候没有明确的数学关系,像下图一样不规则的趋势该怎样生成模型;在数据量比较少的情况下,如何保证模型的准确率。
在这里插入图片描述

引入支持向量机回归,SVM的核函数可以通过升维将非线性数据转换为线性数据,最终在原始数据上拟合出一个不规则的曲线。但是支持向量机最初始为解决分类问题而产生的,所以关于支持向量机的具体原理会在分类中具体描述。
SVM有多种核函数,核函数将数据转换到更高纬度,是得非线性的数据变成线性的。如下图中,左图为原始图像,看不出线性关系,右图是经过核函数转换后的数据。
在这里插入图片描述

案例:使用支持向量机根据岗位级别预测岗位工资

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 读取数据
dataset = pd.read_csv(r'D:\data\Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2].values
y_test=y.reshape(-1, 1)
# 标准化
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
sc_y = StandardScaler()
scaled_X = sc_X.fit_transform(X)
scaled_y = np.ravel(sc_y.fit_transform(y.reshape(-1, 1)))
# 观察不同核函数的效果
from sklearn.svm import SVR
# 高斯核函数
rbf_regressor = SVR(kernel = 'rbf', verbose = 1)
rbf_regressor.fit(scaled_X, scaled_y)
# 多项式线性回归核函数
poly_regressor = SVR(kernel = 'poly', degree=3, verbose = 1)
poly_regressor.fit(scaled_X, scaled_y)
# sigmoid核函数
sigmoid_regressor = SVR(kernel = 'sigmoid', degree=3, verbose = 1)
sigmoid_regressor.fit(scaled_X, scaled_y)
# 线性回归核函数
linear_regressor = SVR(kernel = 'linear', degree=3, verbose = 1)
linear_regressor.fit(scaled_X, scaled_y)
# 可视化结果
plt.figure()
plt.scatter(X, y, color = 'red')
plt.plot(X, sc_y.inverse_transform(rbf_regressor.predict(scaled_X)), color = 'blue', label = 'rbf')
plt.plot(X, sc_y.inverse_transform(poly_regressor.predict(scaled_X)), color = 'green', label = 'poly')
plt.plot(X, sc_y.inverse_transform(sigmoid_regressor.predict(scaled_X)), color = 'orange', label = 'sigmoid')
plt.plot(X, sc_y.inverse_transform(linear_regressor.predict(scaled_X)), color = 'purple', label = 'linear')
plt.title('Truth or Bluff (SVR)')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.legend()
plt.show()

在这里插入图片描述

线性回归、多项式回归与支持向量机回归的比较

回归模型优点缺点
线性回归在任何规模的数据集上都能使用,得到自变量和因变量的相关性,解释性强自变量和因变量存在线性关系才可使用
多项式回归在任何规模的数据集上都可以使用,得到自变量与因变量的非线性关系 ,解释性强需要找到合适的幂
支持向量机回归擅长解决非线性问题,不偏向与异常值强制特征缩放,解释性弱

Lasso回归和岭回归(Ridge )

  • 不同点:
    1、Lasso回归使用L1正则是帮助参数等于0的,是权重变得稀疏;岭回归使用L2正则是让参数趋近与0,很少等于0。
    2、从贝叶斯角度,lasso等价于参数 w的先验概率分布满足拉普拉斯分布,而 岭回归等价于参数 的先验概率分布满足高斯分布。
    3、Lasso可以用特征选择,岭回归不行。

  • 相同点:都可以解决过拟合问题

案例:使用支Lasso回归和岭回归根据岗位级别预测岗位工资

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
dataset = pd.read_csv(r'D:\data\Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
y = dataset.iloc[:, 2].values

# 多项式
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=4).fit_transform(X)

from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.linear_model import SGDRegressor

# Lasso
Lasso_ = Lasso().fit(poly,y)

# Ridge
Rigde_ = Ridge().fit(poly,y)

print('Lasso:',Lasso_.coef_)
print('Rigde:',Rigde_.coef_)
# out >>> 
#Lasso: [ 0.00000000e+00  1.12096627e+05 -2.06567040e+04  7.02615912e+00  1.97675472e+02]
## Rigde: [    0.         -6397.56562921 23714.21579411 -6137.96307511 479.28612486]
SGD_l1 = SGDRegressor(penalty='l1').fit(poly,y)
SGD_l1.coef_
# array([-1.61227566e+09,  2.66093991e+10,  1.31047505e+11,  6.45539429e+11,  5.51381791e+12])
SGD_l2 = SGDRegressor(penalty='l2').fit(poly,y)
SGD_l2.coef_
# array([ 7.26042597e+10,  2.63236962e+11,  9.64828266e+11,  2.62773696e+12, -6.65436703e+12])

练习

import pandas as pd
Train=pd.read_excel(r'D:\data\训练集.xlsx',index_col=[0,1])
Test=pd.read_excel(r'D:\data\测试集.xlsx',index_col=[0,1])
#删除湖北武汉的数据   异常值,会影响数据
Train.drop(index=('湖北','武汉'),inplace=True)    
Test.drop(index=('湖北','武汉'),inplace=True)

#将迁入迁出求和和比例求和,作为2个X
# Train.iloc[:,0:14].sum(axis=1)是前14项之和
New_train=pd.DataFrame(Train.iloc[:,0:14].sum(axis=1),columns=['迁徙指数(训练集)'])
# 比例之和
New_train['武汉出来的比例(训练集)']=Train.iloc[:,14:21].sum(axis=1).values
# y_训练集
New_train['新增感染人数']=Train.iloc[:,-1].values

X = New_train.iloc[:, 0:2].values      # 两个参数

y = New_train.iloc[:, 2].values

# 标准化
from sklearn.preprocessing import StandardScaler
sc_x = StandardScaler()
sc_y = StandardScaler()

sc_X_stder = sc_x.fit_transform(X)
sc_y_stder = sc_y.fit_transform(y.reshape(-1,1))

# 训练多项式多项化
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=3)
poly_X = poly.fit_transform(sc_X_stder)

from sklearn.linear_model import LinearRegression  # 普通的线性回归
from sklearn.linear_model import Lasso             # Lasso回归
from sklearn.linear_model import Ridge             # 岭回归

Line = LinearRegression()
Lass = Lasso()
Ridg = Ridge()

Lin = Line.fit(poly_X, sc_y_stder)
Las = Lass.fit(poly_X, sc_y_stder)
Rid = Ridg.fit(poly_X, sc_y_stder)

New_test=pd.DataFrame(Test.iloc[:,0:14].sum(axis=1),columns=['迁徙指数(训练集)'])

New_test['武汉出来的比例(训练集)']=Test.iloc[:,14:21].sum(axis=1).values

New_test['新增感染人数']=Test.iloc[:,-1].values


test_X = New_test.iloc[:,0:2].values
test_y = New_test.iloc[:, 2].values


# 对测试集中的数据进行标准化
sc_X_test = sc_x.fit_transform(test_X)
sc_y_test = sc_y.fit_transform(test_y.reshape(-1,1))

# 多项化
poly_test_X = poly.fit_transform(sc_X_test)

# 预测
Lin_pre = Lin.predict(poly_test_X)
Las_pre = Las.predict(poly_test_X)
Rid_pre = Rid.predict(poly_test_X)

# 预测值反归一化
Lin_pre_new = sc_y.inverse_transform(Lin_pre)
Las_pre_new = sc_y.inverse_transform(Las_pre)
Rid_pre_new = sc_y.inverse_transform(Rid_pre)

# 真实值反归一化
sc_y_test_new = sc_y.inverse_transform(sc_y_test)

# 评分
from sklearn.metrics import r2_score
print('LinearRegression: ',r2_score(sc_y_test_new, Lin_pre_new))
print('Lasso: ',r2_score(sc_y_test_new, Las_pre_new))
print('Ridge: ',r2_score(sc_y_test_new, Rid_pre_new))
# out>>>
# Lin_pre_new:  0.9238911294847607
# Las_pre_new:  0.7371704164355565
# Rid_pre_new:  0.9261945421124463
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值