简单线性回归
而简单线性回归是属于回归(regression),即label为连续数值型(continuous numerical variable),如:房价、股票价格、降雨量等。
所谓简单,是指只有一个样本特征,即只有一个自变量;所谓线性,是指方程是线性的;所谓回归,是指用方程来模拟变量之间是如何关联的。
简单线性回归,其思想简单,实现容易(与其背后强大的数学性质相关。同时也是许多强大的非线性模型(多项式回归、逻辑回归、SVM)的基础。并且其结果具有很好的可解释性。
其实就是用一个线性代数方程组既可以求出来,需要一条直线,最大程度的拟合样本特征和样本数据标记之间的关系。 在二维平面中,这条直线的方程就是 y = ax + b
推导思路
我们所谓的建模过程,其实就是找到一个模型,最大程度的拟合我们的数据。 在简单线回归问题中,模型就是我们的直线方程:y = ax + b
。
要想最大的拟合数据,本质上就是找到没有拟合的部分,也就是损失的部分尽量小,就是损失函数
(loss function)(也有算法是衡量拟合的程度,称函数为效用函数
(utility function)):
因此,推导思路为:
- 通过分析问题,确定问题的损失函数或者效用函数;
- 然后通过最优化损失函数或者效用函数,获得机器学习的模型
近乎所有参数学习算法都是这样的套路,区别是模型不同,建立的目标函数不同,优化的方式也不同。
回到简单线性回归问题,目标:
最小二乘法
损失函数
在机器学习中,所有的算法模型其实都依赖于最小化或最大化某一个函数,我们称之为“目标函数”。
最小化的这组函数被称为“损失函数”。什么是损失函数呢?
损失函数描述了单个样本预测值和真实值之间误差的程度。用来度量模型一次预测的好坏。
这里引入相关观点:
以下引入相关风险函数解释
小结
- 损失函数:单个样本预测值和真实值之间误差的程度。
- 期望风险:是损失函数的期望,理论上模型f(X)关于联合分布P(X,Y)的平均意义下的损失。
- 经验风险:模型关于训练集的平均损失(每个样本的损失加起来,然后平均一下)。
- 结构风险:在经验风险上加上一个正则化项,防止过拟合的策略。\
代码的实现
一元线性回归
import numpy as np
#创建数据
data = np.array([[150,50],
[152,52],
[160,55],
[164,57],
[165,58],
[168,59],
[170,60],
[171,61],
[173,61],
[173,61],
[176,63],
[177,64],
[180,67],
[183,70],
[184,71]], np.int32)
#提取特征和标签
x = data[:,0:-1]#从第0列开始到倒数第2列停止
y = data[:,-1] #取出最后一列
print(np.shape(x), np.shape(y))
#提取特征和标签
x = data[:,0:-1]#从第0列开始到倒数第2列停止
y = data[:,-1] #取出最后一列
print(np.shape(x), np.shape(y))
(15, 1) (15,)
#可视化数据
import matplotlib.pyplot as plt
%matplotlib inline
plt.scatter(x,y)
plt.show()
#通过线性回归模型来拟合给定的数据
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit(x,y)
print(model.predict([[169]])) #注意model.predict()中要预测的数据跟训练数据x的shape保持一致
print(model.coef_)#coef_:回归系数(斜率)
#对于线性回归问题计算得到的feature的系数。
#如果输入的是多目标问题,则返回一个二维数组(n_targets, n_features);
#如果是单目标问题,返回一个一维数组(n_features,)。
print(model.intercept_)#intercept_:截距项
print(model.score(x,y))# 返回预测的决定系数R^2;
#其结果等于1-(((y_true - y_pred) **2).sum() / ((y_true - y_true.mean()) ** 2).sum())
[60.18051615]
[0.57202343]
-36.49144321405692
0.961913488834442
#把学出来的直线和训练数据可视化在同一个图里面
plt.scatter(x,y)
plt.plot(x, model.predict(x))
plt.show()
通过这样我们就构建了自己的简单一元线性回归方程
多元线性回归
以经典的波士顿房价数据集为例
#加载导入数据集
from sklearn.datasets import load_boston
boston = load_boston()
print(boston.DESCR)
#加载数据集并试着分析特征
boston.keys()
#dict_keys(['data', 'target', 'feature_names', 'DESCR'])
#查看数据集关键字
#将数据集转化为dataframe
import pandas as pd
bostonDf_X = pd.DataFrame(boston.data,columns=boston.feature_names)
bostonDf_y = pd.DataFrame(boston.target,columns=['houseprice'])#注意加列名称
#合并dataframe
bostonDf = pd.concat([bostonDf_X,bostonDf_y],axis=1)#axis=1为横向操作
bostonDf.shape#(506, 14)
bostonDf.head() #看一下数据集
#将数据集转化为dataframe
import pandas as pd
bostonDf_X = pd.DataFrame(boston.data,columns=boston.feature_names)
bostonDf_y = pd.DataFrame(boston.target,columns=['houseprice'])#注意加列名称
#合并dataframe
bostonDf = pd.concat([bostonDf_X,bostonDf_y],axis=1)#axis=1为横向操作
bostonDf.shape#(506, 14)
bostonDf.head() #看一下数据集
#对整体数据进行大致分析
print("最大值:",np.max(boston.target))
print("最小值:",np.min(boston.target))
print("平均值:",np.mean(boston.target))
bostonDf.describe()
#CRIM 特征分析
df= bostonDf_X
y=bostonDf_y
plt.scatter(df['CRIM'], y)
plt.title('城镇人均犯罪率与房价散点图')
plt.xlabel('城镇人均犯罪率')
plt.ylabel('房价')
plt.show()
#进行数据预处理
#对数据进行正则化处理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
#将数据归化到正态分布,均值为0,方差为1
bostonStd_1 = scaler.fit_transform(bostonDf.values)
showbostonStd_1 = pd.DataFrame(bostonStd_1,columns=bostonDf.columns)
showbostonStd_1.head(10)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(bostonStd_1[:,[0,13]],bostonStd_1[:,[13]],test_size=0.3,random_state=0)
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(x_train,y_train)
y_pred = regr.predict(x_test)
regr.score(x_test,y_test)
此时得到分数1.0 存在过拟合,一般多元线性回归方程多使用网格调参进行优化处理,这里我们直接进行GridSearchCV
调包使用,请大家注意,在不同版本中他的对应包名不同
- from sklearn.grid_search import GridSearchCV
- from sklearn.model_selection import GridSearchCV
# from sklearn.grid_search import GridSearchCV
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import GridSearchCV
knn_reg = KNeighborsRegressor()
grid_param = [
{
'weights':['uniform'],
'n_neighbors':[i for i in range(1,11)]
},
{
'weights':['distance'],
'n_neighbors':[i for i in range(1,11)],
'p':[i for i in range(1,6)]
}
]
knn_reg = KNeighborsRegressor()
grid_search = GridSearchCV(knn_reg,grid_param,n_jobs=-1,verbose=2,cv=10)
# 调用fit方法执行网格搜索
grid_search.fit(x_train,y_train.astype('int'))
print(grid_search.best_params_)
print(grid_search.best_score_)
print(grid_search.best_estimator_.score(x_test,y_test))
输出最佳参数为{‘n_neighbors’: 5, ‘p’: 1, ‘weights’: ‘distance’}
最佳分数为0.9551059795336231
在验证集上的分数为0.7585309601137702 简单的通过网格调参,已经模型的拟合,可以初步实现一个多元线性回归模型方程