机器学习--线性回归模型

 

线性回归模型属于经典的统计学模型,是根据已知的自变量来预测某个连续的数值因变量。她属于有监督的学习算法,也就是在建模过程中需要同时具备自变量x和因变量y。

1.、一元线性回归模型

一元线性回归模型是入门算法,是指变量中只含有一个自变量和一个因变量,用来建模的数据可以表示为{(x1,y1)…(xn,yn)},其中xi表示自变量x的第i个值,yi为预测因变量的y值。也就是:y = a + b*x + C
其中,a为模型的截距项、b为模型的斜率项、C为模型的误差项,C是无法解释的部分。
求解目标:很明显、这个模型就是寻找误差最小的拟合线的函数方程。
引入一个例子来进行求解过程的解释:(该例子是探究工作年限与收入之间的关系)
导入数据进行分析:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 导入数据集
fileData = pd.read_csv(r'Salary_Data.csv') 
print(len(fileData))
fileData[:5]

 

结果如下:【自变量为工作年限、因变量为收入】
image.png
对数据进行简单的可视化分析,作散点图查看数据的大致分布:

#绘制散点图
sns.lmplot(x='YearsExperience',y='Salary',data=fileData,ci=None)
#显示图形
plt.show()

 

结果是工作与收入存在明显的正相关(这是常识):
image.png
可视化散点图中是一条近似线性回归拟合线,下面求解这条拟合线:

分析:
误差项C是为了平衡等号两边的值、但却是一个无法解释的存在。假设拟合线是完全理想状态的,那么对应的误差项应该为0,因为完全理想状态下是没有误差存在的。 所以,要想得到最优的拟合线、就必须使误差项达到最小,误差是y与(a+b*x)的差,结果可正可负。因此应该给其差加一个绝对值或者加平方或者其它能够达到去除负号影响的方法。这里选择将问题转换为求误差平方和最小的问题,也就是说明可以使用最小二乘法。

过程:

  1. k(a,b) = sum(c.pow(2)) 【也就是展开误差平方和,得到平方损失函数】
  2. 展开平方项k(a,b)
  3. 将k(a,b)分别对a对b求偏导,并令其导数分别为0(因为要使目标函数达到最小,是一个求极值的问题,所以令其偏导数为0)
  4. 之后两个未知数两条方程,必定可以求出a和b。
  5. 结果是:a = y-bx     ;    b=(sum(xy)-1/n*sum(x)sum(y))/(sum(x**2)-1/n(sum(x)**2))

下面是算法实现:

#使用最小二乘法进行拟合 线性回归模型

n = fileData.shape[0]  #样本量  用len(filedata)也一样

sum_x = fileData.YearsExperience.sum() #经验总和 159.4
sum_y = fileData.Salary.sum()  #薪资总和  2280090.0

sum_x2 = fileData.YearsExperience.pow(2).sum() #经验的平方和
xy = fileData.YearsExperience * fileData.Salary
sum_xy = xy.sum()

#求解a、b回归系数
b = (sum_xy-sum_x*sum_y/n)/(sum_x2-sum_x**2/n)
a = fileData.Salary.mean()-b*fileData.YearsExperience.mean()
print('a:',a)
print('b:',b,'\n')

print("y={}x+{}".format(a,b))

 

至此,就得到了这个模型的数学表达式,可以拿他来做预测或者其它研究,也可以进行改进与优化。
其实,由于Python的计算功能和便利性,资深的开发者开发并封装开源了第三方库用于实现机器学习算法、以及各种场景的应用与调优。
stasmodels模块是专门用于统计建模的第三方库,如果需要求解线性回归模型的参数,调用子模块的ols函数即可求解。

#使用statsmodels库的api进行建模操作
import statsmodels.api as sm

#使用数据集进行建模
model = sm.formula.ols('Salary~YearsExperience',data=fileData)
modelrst = model.fit() #训练模型、进行拟合
modelrst.params  #查看模型的参数

 

ols函数详解:
ols(formula,data,subset=None,drop_cols=None)
formula:以字符串的形式指定线性线性回归模型的公式,如’y~x’表示简单线性回归模型。
data:指定建模的数据集。
subset:通过一个bool类型的数组对象,获取data的子集用于建模。
drop_cols:指定需要从data中删除的变量。

最终,该一元线性回归模型表示为:

y=25792.200198668666x+9449.962321455081

2.多元线性回归模型

多元线性回归中、y是一维向量,x是二维矩阵,虽然不像一元线性回归模型那样求解简单,但是,思路是完全一致的。
思路:把y变量看成n行1列的向量,把x变量看成n行p列的矩阵(p是代表有p个自变量),然后模型其实就是:y=a0+a1x1+a2x2+a3x3+…+anxn+C
其中,C是误差项。
根据线性代数知识,可以表示成:y=AX+C,其中,A是p1的一维向量,是偏回归系数。C为n*1的一维向量,代表了拟合之后每一个样本的误差值。然后根据最小二乘法知识构建目标函数式子,展开平方项,求偏导,然后求偏回归系数的值。
调用ols函数对产品的利润数据集进行多元线性回归模型建模。
读入数据:(其中,Profit为因变量)

#多元线性回归模型
from sklearn import model_selection
import statsmodels.api as sm
# from sklearn import linear_model

Profit = pd.read_excel(r'Predict to Profit.xlsx')
Profit.head(8)

 

image.png
数据集中的State变量是字符型离散变量,无法直接代入计算,需要进行处理(一般是哑变量处理方式)。

对State变量进行哑变量处理:

#对于state这一列数据来说,它是非数值的离散变量(也就是字符串),故需要将他设置为哑变量即套在C()中,表示将其当作分类变量处理
#因为State包含了 【New York、California、Florida】,所以有三个类别:State[New York]、State[California]、State[Florida]
#由于默认的拆分哑变量并不是最好的和需要的,所以认为的去拆哑变量


#处理哑变量
dumm = pd.get_dummies(Profit.State)
Profit_New = pd.concat([Profit,dumm],axis=1)
# Profit_New
Profit_New.drop(labels=['State','New York'],axis=1,inplace=True)  
#删除State和New York,因为State被分解成哑变量了,而New York被作为参照组了

 

使用哑变量处理过后的数据进行建模:

#拆分数据
train,test = model_selection.train_test_split(Profit_New,test_size=0.25,random_state=1234)
# #建模
model = sm.formula.ols('Profit ~ RD_Spend + Administration + Marketing_Spend + Florida + California',data=train)
# #训练数据
modelrst = model.fit()
print('模型的偏回归系数:\n',modelrst.params)

 

得到模型的偏回归系数如下:
image.png

得到模型之后,使用模型对测试集进行预测:

#删除Profit变量,因为预测的结果就是要预测他的,然后使用剩下的变量进行预测
test_x = test.drop(labels='Profit',axis=1)
predictRST = modelrst.predict(exog = test_x)
print("对比预测值和真实值:\n",pd.DataFrame({'预测值':predictRST,'真实值':test.Profit}))

 

image.png

另外,进行线性回归模型的评估,可以使用均方根误差来评估。

posted @ 2019-08-24 14:47  Tony学长  阅读(584)  评论(0编辑  收藏  举报