机器学习基础算法三:线性回归算法的实验(最小二乘法)

线性回归算法实验(最小二乘法)

一、前期准备

1、导出数据集:

我们在进行机器学习各种算法的实验时,遇到的第一个问题都应该是,如何找到需要的数据集,有了数据集我们才能去对相应的数据集进行实验处理。像鸢尾花、波士顿房价等经典的数据集在网上都可以下载到,但是如果每需要一个数据集就都去网上下载的话,也挺麻烦的。这个时候可以用到“sklearn”这个包,这个包里包含了很多机器学习所需的数据集。需要用到某数据集的时候直接从sklearn中导出即可。这个sklearn包也像其他包一样可以在pycharm里直接导入。

  • 数据集的导出方法:
	import numpy as np
	import pandas as pd
	from sklearn.datasets import load_boston #从sklearn的数据集中导出波士顿房价的数据集。
	data = load_boston()
	print(data)
  • 在我们导出数据集之后又会遇到新的问题:导出的数据集不经处理的话会显示的很混乱。就如同下图所示:
    在这里插入图片描述

  • 解决数据显示混乱和显示不完整的问题:

    import numpy as np
    import pandas as pd
    from sklearn.datasets import load_boston
    
    # 增加表格的列数行数和每行的宽度以此让数据集完整表示
    pd.set_option('display.max_rows', 1000)
    pd.set_option('display.max_columns', 1000)
    pd.set_option('display.width', 1000)
    
    # 将sklearn数据集转换为csv格式
    if __name__ == '__main__':
      	boston = load_boston()
     	data = pd.DataFrame(boston.data, columns=boston.feature_names)
    	data['MEDV'] = boston['target']
    	data.to_csv('./boston.csv', index=None)
    
    print(data)
    

    在这里插入图片描述

2、数据集中的各个标签名词解释:

- CRIM:城镇人均犯罪率。
- ZN:住宅用地超过 25000 sq.ft. 的比例。
- INDUS:城镇非零售商用土地的比例。
- CHAS:查理斯河空变量(如果边界是河流,则为1;否则为0)。
- NOX:一氧化氮浓度。
- RM:住宅平均房间数。
- AGE:1940 年之前建成的自用房屋比例。
- DIS:到波士顿五个中心区域的加权距离。
- RAD:辐射性公路的接近指数。
- TAX:每 10000 美元的全值财产税率。
- PTRATIO:城镇师生比例。
- B:1000(Bk-0.63)^ 2,其中 Bk 指代城镇中黑人的比例。
- LSTAT:人口中地位低下者的比例。
- MEDV:自住房的平均房价,以千美元计。

3、对数据进行检测。

  1. 查看数据的基本信息。同时可以查看各个特征列是否有缺失值。

    data.info()
    

    在这里插入图片描述

  2. 检查数据是否有重复

    # 检查data里面是否有重复的值
    data.duplicated().any()
    

二、什么是线性回归。

  • 线性回归就是用一条直线来解释自变量与因变量之间的关系。

三、算法实现。

  • 回归函数:
class LinearRegression:
    """使用Python实现的线性回归(最小二乘法)"""

    def fit(self,X,y):
        """根据提供的训练数据X,对模型进行训练。
        :parameter
        X:类数组类型。形状:[样本数量,特征数量]
            特征矩阵,用来对模型进行训练。

        y:类数组类型,形状:[样本数量]
        """
        # 将X,y转化为矩阵的形式
        # 说明:如果X是数组对象的一部分,而不是完整的对象数据(例如:X是由其他对象通过切片传递过来的),
        # 则无法完成矩阵的转换。这里创建X的拷贝对象,避免转换矩阵的时候失败
        X = np.asmatrix(X.copy())
        # y是一维结构(行向量或列向量),一维的格式不需要进行拷贝。
        # 注意:我们现在要进行矩阵的运算,因此需要时二维的结构,我们通过reshape的方法进行转换。
        y = np.asmatrix(y).reshape(-1, 1)  # 只有一列,行数自适应。
        # 通过最小二乘公式,求解出最佳的权重值
        self.w_ = (X.T * X).I * X.T * y

    def predict(self, X):
        """根据参数传递的样本X,对样本数据进行预测。
        :parameter
        X:类数组类型。形状:[样本数量,特征数量]
            待预测的样本特征(属性)。
        :return
        result:数组类型
            预测的结果。
        """
        # 将X装换成矩阵,注意要对X进行拷贝。
        X = np.asmatrix(X.copy())
        result = X * self.w_
        # 将矩阵转换成ndarray数组,进行扁平化处理,然后返回结果。
        # 使用ravel可以实现扁平化处理
        return np.array(result).ravel()
  • 进行训练测试并打印结果:
  1. 不考虑截距:
    # 不考虑截距的情况
    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 = LinearRegression()
    # 开始训练
    lr.fit(train_X, train_y)
    # 开始测试
    result = lr.predict(test_X)
    print(result)
    
  • 测试的结果:
    在这里插入图片描述
    测试结果与实际值得误差
    # 计算一下测试结果与实际结果的误差
    print(np.mean((result - test_y) ** 2))
    # 查看模型的权重值
    print(lr.w_)
    
  1. 考虑截距:
  • 添加一列值为1的数据将截距w0带入计算:
    # 考虑截距:增加一列,让该列的所有值都是1。
    t = data.sample(len(data),random_state=0)  # 打乱数据顺序
    # 按照习惯,截距为w0,我们为之而配上一个x0,x0列放在最前面。
    new_columns = t.columns.insert(0, "intercept")
    # 重新安排列的顺序,如果值为空,则使用fill_value参数指定的值进行填充
    t = t.reindex(columns=new_columns, fill_value=1)
    
    • 训练测试:
    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 = LinearRegression()
    # 开始训练
    lr.fit(train_X, train_y)
    # 开始测试
    result = lr.predict(test_X)
    print(result)
    
    # 计算一下测试结果与实际结果的误差
    print(np.mean((result - test_y) ** 2))
    # 查看模型的权重值
    print(lr.w_)
    
  • 测试结果:
    在这里插入图片描述

四、可视化操作

  • 实现代码:
# 导入绘图包
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False

# 绘制预测值
plt.plot(result,"ro-", label="预测值")
# 绘制真实值
plt.plot(test_y.values,"go--",label = "真实值")
plt.title("线性回归预测-最小二乘法")
plt.xlabel("样本序号")
plt.ylabel("房价")
plt.legend()
plt.show()
  • 最终结果:
    在这里插入图片描述

五、完整代码。

import numpy as np
import pandas as pd
from sklearn.datasets import load_boston

# 增加表格的列数行数和每行的宽度以此让数据集完整表示
pd.set_option('display.max_rows', 1000)
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)

# 将sklearn数据集转换为csv
if __name__ == '__main__':
    boston = load_boston()
    data = pd.DataFrame(boston.data, columns=boston.feature_names)
    data['MEDV'] = boston['target']
    data.to_csv('./boston.csv', index=None)

# # 查看数据的基本信息。同时可以查看各个特征列是否有缺失值。
# data.info()
# # 检查data里面是否有重复的值
# data.duplicated().any()

class LinearRegression:
    """使用Python实现的线性回归(最小二乘法)"""

    def fit(self,X,y):
        """根据提供的训练数据X,对模型进行训练。
        :parameter
        X:类数组类型。形状:[样本数量,特征数量]
            特征矩阵,用来对模型进行训练。

        y:类数组类型,形状:[样本数量]
        """
        # 将X,y转化为矩阵的形式
        # 说明:如果X是数组对象的一部分,而不是完整的对象数据(例如:X是由其他对象通过切片传递过来的),
        # 则无法完成矩阵的转换。这里创建X的拷贝对象,避免转换矩阵的时候失败
        X = np.asmatrix(X.copy())
        # y是一维结构(行向量或列向量),一维的格式不需要进行拷贝。
        # 注意:我们现在要进行矩阵的运算,因此需要时二维的结构,我们通过reshape的方法进行转换。
        y = np.asmatrix(y).reshape(-1, 1)  # 只有一列,行数自适应。
        # 通过最小二乘公式,求解出最佳的权重值
        self.w_ = (X.T * X).I * X.T * y

    def predict(self, X):
        """根据参数传递的样本X,对样本数据进行预测。
        :parameter
        X:类数组类型。形状:[样本数量,特征数量]
            待预测的样本特征(属性)。
        :return
        result:数组类型
            预测的结果。
        """
        # 将X装换成矩阵,注意要对X进行拷贝。
        X = np.asmatrix(X.copy())
        result = X * self.w_
        # 将矩阵转换成ndarray数组,进行扁平化处理,然后返回结果。
        # 使用ravel可以实现扁平化处理
        return np.array(result).ravel()

# 不考虑截距的情况
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 = LinearRegression()
# 开始训练
lr.fit(train_X, train_y)
# 开始测试
result = lr.predict(test_X)
print(result)

# 计算一下测试结果与实际结果的误差
print(np.mean((result - test_y) ** 2))
# 查看模型的权重值
print(lr.w_)

# 考虑截距的情况:
# 增加一列,让该列的所有值都是1。
t = data.sample(len(data),random_state=0)  # 打乱数据顺序
# 按照习惯,截距为w0,我们为之而配上一个x0,x0列放在最前面。
new_columns = t.columns.insert(0, "intercept")
# 重新安排列的顺序,如果值为空,则使用fill_value参数指定的值进行填充
t = t.reindex(columns=new_columns, fill_value=1)

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 = LinearRegression()
# 开始训练
lr.fit(train_X, train_y)
# 开始测试
result = lr.predict(test_X)
print(result)

# 计算一下测试结果与实际结果的误差
print(np.mean((result - test_y) ** 2))
# 查看模型的权重值
print(lr.w_)


import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False

# 绘制预测值
plt.plot(result,"ro-", label="预测值")
# 绘制真实值
plt.plot(test_y.values,"go--",label = "真实值")
plt.title("线性回归预测-最小二乘法")
plt.xlabel("样本序号")
plt.ylabel("房价")
plt.legend()
plt.show()
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值