前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性回归

线性回归

作者头像
听城
发布2018-04-27 14:17:03
1.2K0
发布2018-04-27 14:17:03
举报
文章被收录于专栏:杂七杂八杂七杂八

线性模型形式简单、易于建模,但却蕴含着机器学习中一些重要的基本思想。许多功能更为强大的非线性模型都可在线性模型的基础上引入层级结构或高维映射得到。

基本形式

给定由d个属性描述的示例x=(x1; x2;...;xd),其中xi是x是第i个属性上的取值,线性模型试图学得一个通过属性的线性组合来进行预测的函数,即f(x)=w1x1+w2x2+...wdxd+b,一般用向量形式写成f(x)=wTx+b,w和b学得之后模型就得以确定

线性回归

下面我们用一个预测房价的例子来说明。

选择合适模型

横轴为房屋大学,纵轴为房屋出售的价格。由上述可知,w1和w0是需要学得的参数。不同的参数会拟合成不同的直线。我们需要的是一条成本最小的直线,通常用RSS残差平方和来表示。

那如果我们用更高阶的函数来拟合这个数据呢?

二次函数

高阶函数

我们可以看到二次函数的RSS比一次稍好些,更高阶的函数则可以完全拟合给出的点,但是这种情况明显是不好的,因为过拟合了,太符合样本的特征了。

那如何来选择合适模型呢?如果给出的数据足够大,可以用下面方法取得更好的结果。

这其实就是我们通常用到的训练集和测试集。常用的方法有留出法、交叉验证法、自助法。这个在之前的文章中提到过,就不再赘述。

训练误差、测试误差和模型复杂度之间的关系

QQ截图20171109054124.png

当然这只是一个参数的情况,实际的情况肯定是多个参数。

整体流程

实际案例分析

读取数据集
代码语言:javascript
复制
import pandas as pd
df = pd.read_csv('house_data.csv')
df.head()
可视化房屋数据集的特征
代码语言:javascript
复制
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(context = 'notebook')
# 人口百分比,房屋建造时间,据市中心距离,犯罪率,房屋价格,税,房间数
cols = ['LSTAT', 'AGE', 'DIS', 'CRIM', 'MEDV', 'TAX', 'RM']
sns.pairplot(df[cols], size=2.5)
plt.show()

由此我们可以看出,房价和人口百分比成反比,与房间数成正比

通过梯度下降法计算回归参数,实现线性回归模型

关于梯度下降可以参看这篇文章

代码语言:javascript
复制
import numpy as np
class LinearRegressionByMyself(object):
    def __init__(self, Learn_rate=0.001, epoch=20):
        self.Learning_rate = Learn_rate
        self.epoch = epoch
        
    #训练方法
    def fit(self, X, y):
        #初始化参数
        self.w = np.zeros(1+X.shape[1])
        #误差
        self.cost_list = []
        
        for i in range(self.epoch):
            #将X数据集带入回归公式
            output = self.Regression_input(X)
            error = y - output
            self.w[1:] += self.Learning_rate * X.T.dot(error)
            self.w[0] += self.Learning_rate * error.sum()
            cost = (error**2).sum() / 2.0
            self.cost_list.append(cost)
        return self
    
    def Regression_input(self, X):
        return np.dot(X, self.w[1:])+self.w[0]
    
    def predict(self, X):
        return self.Regression_input(X)

此时需要的两个参数为X,y。X为一个二维数组,y是一个一维数组

代码语言:javascript
复制
X = df[['LSTAT']].values
y = df['MEDV'].values

在构造回归模型之前,先观察数据,发现数据相差比较大,这会对结果造成误差。我们用Scikie-learn里面的方法来实现归一化

代码语言:javascript
复制
from sklearn.preprocessing import StandardScaler
StandardScaler_x = StandardScaler()
StandardScaler_y = StandardScaler()
X_Standard = StandardScaler_x.fit_transform(X)
y_Standard = StandardScaler_y.fit_transform(y)

训练模型,拟合数据

代码语言:javascript
复制
model = LinearRegressionByMyself()
model.fit(X_Standard, y_Standard)

观察误差

代码语言:javascript
复制
plt.plot(range(1, model.epoch+1), model.cost_list)
plt.ylabel('SSE')
plt.xlabel('Epoch')
plt.show()
画出拟合图像
代码语言:javascript
复制
def Regression_plot(X, y, model):
    plt.scatter(X, y, c='blue')
    plt.plot(X, model.predict(X), color='red')
    return None

Regression_plot(X_Standard, y_Standard, model)
plt.xlabel('Percentage of the population')
plt.ylabel('House price')
plt.show()
使用sklearn实现线性回归模型
代码语言:javascript
复制
from sklearn.linear_model import LinearRegression
sk_model = LinearRegression()
sk_model.fit(X, y)
print('Slope: %.3f' % sk_model.coef_[0])
print('Inercept: %.3f' % sk_model.intercept_)
Regression_plot(X, y, sk_model)
plt.xlabel('Percentage of the population')
plt.ylabel('House price')
plt.show()
评估线性回归模型
代码语言:javascript
复制
from sklearn.cross_validation import train_test_split
cols = ['LSTAT', 'AGE', 'DIS', 'CRIM', 'TAX', 'RM']
X = df[cols].values
y = df['MEDV'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
sk_model = LinearRegression()
sk_model.fit(X_train, y_train)
y_train_predict = sk_model.predict(X_train)
y_test_predict = sk_model.predict(X_test)
plt.scatter(y_train_predict, y_train_predict - y_train, c='red', marker='x', label='Training data')
plt.scatter(y_test_predict, y_test_predict - y_test, c='black', marker='o', label='Test data')
plt.xlabel('Predicted values')
plt.ylabel('Residuals')
plt.legend(loc='upper left')
plt.hlines(y=0, xmin=-10, xmax=50, lw=1, color='green')
plt.xlim([-10, 50])
plt.show()

预测值和训练值残差关系图

均方误差与R2评分
代码语言:javascript
复制
from sklearn.metrics import mean_squared_error
print('MSE train %.3f, test %.3f' % (
    mean_squared_error(y_train, y_train_predict),
    mean_squared_error(y_test, y_test_predict)))#MSE train 25.106, test 36.671
代码语言:javascript
复制
from sklearn.metrics import r2_score
print('R^2 train %.3f, test %.3f' % (
    r2_score(y_train, y_train_predict),
    r2_score(y_test, y_test_predict)))#R^2 train 0.706, test 0.551,

R2越接近1,效果越好

多项式回归

代码语言:javascript
复制
X = df[['RM']].values
y = df['MEDV'].values
Regression_model = LinearRegression()
from sklearn.preprocessing import PolynomialFeatures
quadratic = PolynomialFeatures(degree=2)
cubic = PolynomialFeatures(degree=3)
X_squared = quadratic.fit_transform(X)
X_cubic = cubic.fit_transform(X)
X_fit = np.arange(X.min(), X.max(), 0.01)[: , np.newaxis]
Linear_model = Regression_model.fit(X, y)
#拟合线性
y_line_fit = Linear_model.predict(X_fit)
linear_r2 = r2_score(y, Linear_model.predict(X))
#二次模型,先二次变换再线性回归
Squared_model = Regression_model.fit(X_squared, y)
y_quad_fit = Squared_model.predict(quadratic.fit_transform(X_fit))
quadratic_r2 = r2_score(y, Squared_model.predict(X_squared))
#三次模型
Cubic_model = Regression_model.fit(X_cubic, y)
y_cubic_fit = Cubic_model.predict(cubic.fit_transform(X_fit))
cubic_r2 = r2_score(y, Cubic_model.predict(X_cubic))
#画图
plt.scatter(X, y, label='Training point', color='lightgray')
plt.plot(X_fit, y_line_fit, label='linear, $R^2=%.2f$' % linear_r2, color='blue', lw=2, linestyle=':')
plt.plot(X_fit, y_quad_fit, label='quadratic, $R^2=%.2f$' % quadratic_r2, color='red', lw=2, linestyle='-')
plt.plot(X_fit, y_cubic_fit, label='cubic, $R^2=%.2f$' % cubic_r2, color='green', lw=2, linestyle='--')
plt.xlabel('Room number')
plt.ylabel('House price')
plt.legend(loc='upper left')
plt.show()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.11.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本形式
  • 线性回归
  • 实际案例分析
  • 多项式回归
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档