import numpy as np
import pandas as pd
导入数据
data= pd. read_csv( r"F:\数据集\dataset\boston.csv" )
data. head( )
Unnamed: 0 crim zn indus chas nox rm age dis rad tax ptratio black lstat medv 0 1 0.00632 18.0 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90 4.98 24.0 1 2 0.02731 0.0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90 9.14 21.6 2 3 0.02729 0.0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83 4.03 34.7 3 4 0.03237 0.0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63 2.94 33.4 4 5 0.06905 0.0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90 5.33 36.2
编写线性回归-梯度下降类
class LinearRegression :
"""
使用python语言实现线性回归算法(梯度下降法)
"""
def __init__ ( self, alpha, times) :
"""
初始化方法:
Parameters:
——————————
alpha:float
学习率,用来控制步长。(权重调整的幅度)
times:int
循环迭代的次数
"""
self. alpha= alpha
self. times= times
def fit ( self, X, y) :
"""
根据提供的训训练数据,对模型进行训练
Parameters:
____________
X:类数组类型。形状:[样本数量,特征数量]
待训练的样本特征属性。(特征矩阵)
y:类数组类型。形状:[样本数量]
目标值(标签信息)
"""
X= np. asarray( X)
y= np. asarray( y)
self. w_= np. zeros( 1 + X. shape[ 1 ] )
self. loss_= [ ]
for i in range ( self. times) :
y_hat= np. dot( X, self. w_[ 1 : ] ) + self. w_[ 0 ]
error= y- y_hat
self. loss_. append( np. sum ( error** 2 ) / 2 )
self. w_[ 0 ] += self. alpha* np. sum ( error)
self. w_[ 1 : ] += self. alpha* np. dot( X. T, error)
def predict ( self, X) :
"""
根据参数传递的样本,对样本数据进行预测。
Parameters:
_____________
X:类数组类型,形状:[样本数量,特征数量]
需要进行测试的样本
Returns:
___________
result:数组类型
预测的结果
"""
X= np. asarray( X)
result= np. dot( X, self. w_[ 1 : ] ) + self. w_[ 0 ]
return result
测试
发现效果并不理想
lr= LinearRegression( alpha= 0.001 , times= 20 )
t= data. sample( len ( data) , random_state= 0 )
train_X= t. iloc[ : 400 , : - 1 ]
train_y= t. iloc[ : 400 , - 1 ]
test_X= t. iloc[ 400 : , : - 1 ]
test_y= t. iloc[ 400 : , - 1 ]
lr. fit( train_X, train_y)
result= lr. predict( test_X)
display( np. mean( ( result- test_y) ** 2 ) )
1.1804176210461773e+210
特征缩放(标准化)–编写标准化类
发现上面的效果并不好,甚至出现损失函数值越来越大的情况,究其原因,发现其各个特征的数量级相差较大,故进行特征缩放,使各个特征相差变小
class StandardScaler :
"""
该类对数据进行标准化处理
"""
def fit ( self, X) :
"""
根据传递的样本,计算每个特征列的均值与标准差。
Parameters:
______________
X:类数组类型
训练数据,用来计算均值与标准差。
"""
X= np. array( X)
self. std_= np. std( X, axis= 0 )
self. mean_= np. mean( X, axis= 0 )
def transform ( self, X) :
"""
对给定的数据X ,进行标准化处理(将X 的每一列都变成标准正态分布的数据)
Parameters:
——————————————
X:类数组类型
带转换的数据
Return:
_________
result:类数组类型。
参数X转换成标准正态分布后的结果
"""
return ( X- self. mean_) / self. std_
def fit_transform ( self, X) :
"""
对数据进行训练,并转换,返回转换之后的结果。
Parameters:
____________
X:类数组类型
待转换的数据
Return:
————————————
result:类数组类型
参数X转换成标准正态分布后的结果。
"""
self. fit( X)
return self. transform( X)
测试标准化类
lr= LinearRegression( 0.0005 , times= 20 )
t= data. sample( len ( data) , random_state= 0 )
train_X= t. iloc[ : 400 , : - 1 ]
train_y= t. iloc[ : 400 , - 1 ]
test_X= t. iloc[ 400 : , : - 1 ]
test_y= t. iloc[ 400 : , - 1 ]
s= StandardScaler( )
train_X= s. fit_transform( train_X)
test_X= s. fit_transform( test_X)
s2= StandardScaler( )
train_y= s2. fit_transform( train_y)
test_y= s2. fit_transform( test_y)
lr. fit( train_X, train_y)
result= lr. predict( test_X)
display( np. mean( ( result- test_y) ** 2 ) )
0.14911890500740144
可视化
import matplotlib as mpl
import matplotlib. pyplot as plt
mpl. rcParams[ "font.family" ] = "SimHei"
mpl. rcParams[ "axes.unicode_minus" ] = False
1. 绘制预测值
plt. figure( figsize= ( 10 , 10 ) )
plt. plot( result, "ro-" , label= "预测值" )
plt. plot( test_y. values, "go--" , label= "真实值" )
plt. title( "线性回归预测--梯度下降" )
plt. xlabel( "样本序号" )
plt. ylabel( "房价" )
plt. legend( )
plt. show( )
2.绘制累计误差值
plt. plot( range ( 1 , lr. times+ 1 ) , lr. loss_, "o-" )
[<matplotlib.lines.Line2D at 0xa2b7870888>]
3.绘制 直线拟合 散点图
lr= LinearRegression( alpha= 0.0005 , times= 50 )
t= data. sample( len ( data) , random_state= 0 )
train_X= t. iloc[ : 400 , 6 : 7 ]
train_y= t. iloc[ : 400 , - 1 ]
test_X= t. iloc[ 400 : , 6 : 7 ]
test_y= t. iloc[ 400 : , - 1 ]
s= StandardScaler( )
train_X= s. fit_transform( train_X)
test_X= s. fit_transform( test_X)
s2= StandardScaler( )
train_y= s2. fit_transform( train_y)
test_y= s2. fit_transform( test_y)
lr. fit( train_X, train_y)
result= lr. predict( test_X)
display( np. mean( result- test_y** 2 ) )
-1.0000000000000002
plt. scatter( train_X[ "rm" ] , train_y)
lr. w_
x= np. arange( - 5 , 5 , 0.1 )
y= - 3.07531778e-16 + 6.54984608e-01 * x
plt. plot( x, y, "r" )
[<matplotlib.lines.Line2D at 0xa2b2775048>]