import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
In [2]:
#创建一个矩阵
a = np.array([[1, 2], [3, 4]])
m = np.mat(a)
m
[2]:
In [4]:
#矩阵运算回顾
# 矩阵转秩
m.T
# 矩阵乘法
m * m
a * a
# 矩阵⾏列式
np.linalg.det(m)
# 求逆矩阵
m.I
#转换成array
m.A
#降维成一维
m.fattlen
Out[4]:
假设输入数据为DataFrame格式,最后一列为标签值,在此基础上编写线性回归自定义函数(最小二乘)
In [ ]:
#矩阵公式
w=(x.T * x).I * X.T * y
In [53]:
#根据最小二乘法推导得 w=(x.T * x).I * X.T * y 注:如果(x.T * X)不满足可逆性,那么最小二乘无解,另不满足凸函数,也无解
#又因为特征矩阵在存在多重共线性的情况下,特征矩阵不满足可逆性,所以在做回归之前,需要消除多重共线性
def standRegres(dataSet):
#把DataFrame转换成array 在转换成matrix,因为DateFrame每一列数据可以不一样,不能直接计算,转换成matirx同时,数据格式也会统一
xMat = np.mat(dataSet.iloc[:, :-1].values)
yMat = np.mat(dataSet.iloc[:, -1].values).T
xTx = xMat.T*xMat
if np.linalg.det(xTx) == 0:#判断xTx是否是满秩矩阵,若不满秩,则⽆法对其进⾏求逆矩阵的操作
print("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T*yMat)
return ws
#这⾥需要注意的是,当使⽤矩阵分解来求解多元线性回归时,必须添加⼀列全为1的列,⽤于表征线性⽅程截距b。
In [54]:
ex0 = pd.read_table('ex0.txt', header=None)
ex0.head()
Out[54]:
In [55]:
ws = standRegres(ex0)
ws
#返回结果即为各列特征权重,其中数据集第⼀列值均为1,因此返回结果的第⼀个分量表示截距
Out[55]:
In [56]:
#可视化展示
yhat = ex0.iloc[:, :-1].values * ws
plt.plot(ex0.iloc[:, 1], ex0.iloc[:, 2], 'o')
plt.plot(ex0.iloc[:, 1], yhat)
Out[56]:
模型评价指标残差平⽅和SSE
In [23]:
y = ex0.iloc[:, -1].values
yhat = yhat.flatten()
rss = np.power(yhat - y, 2).sum()
rss
Out[23]:
In [26]:
#将SSE做一个封装
def sseCal(dataSet, regres):#设置参数为 数据集 与 回归方法
n = dataSet.shape[0]
y = dataSet.iloc[:, -1].values
ws = regres(dataSet)
yhat = dataSet.iloc[:, :-1].values * ws
yhat = yhat.reshape([n,])
rss = np.power(yhat - y, 2).sum()
return rss
In [29]:
sseCal(ex0,standRegres)
Out[29]:
模型评价指标 决定系数R_square,决定系数分布在[0, 1]区间内,且越趋近于1,表明拟合程度越好。
In [21]:
sse = sseCal(ex0, standRegres)
y = ex0.iloc[:, -1].values
sst = np.power(y - y.mean(), 2).sum()
1 - sse / sst
Out[21]:
In [31]:
#封装R**2
2
def rSquare(dataSet, regres):#设置参数为 数据集 与 回归方法
sse = sseCal(dataSet, regres)
y = dataSet.iloc[:, -1].values
sst = np.power(y - y.mean(), 2).sum()
return 1 - sse / sst
In [32]:
rSquare(ex0, standRegres)
Out[32]:
线性回归的Scikit-Learn实现
In [60]:
from sklearn import linear_model
reg = linear_model.LinearRegression(fit_intercept=True)
reg.fit(ex0.iloc[:, :-1].values, ex0.iloc[:,-1].values)
Out[60]:
In [61]:
reg.coef_#返回系数
Out[61]:
array([0. , 1.69532264])
In [62]:
reg.intercept_#返回截距
Out[62]:
3.0077432426975905
然后计算模型MSE和决定系数
In [63]:
from sklearn.metrics import mean_squared_error, r2_score
yhat = reg.predict(ex0.iloc[:, :-1])
mean_squared_error(y, yhat)
Out[63]:
In [64]:
mean_squared_error(y, yhat)*ex0.shape[0]
Out[64]:
In [65]:
r2_score(y, yhat)
Out[65]:
来源:oschina
链接:https://my.oschina.net/u/4332911/blog/3343318