东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 18245|回复: 24

[课堂笔记] 11、机器学习实战案例:普通最小二乘法求线性回归_笔记

[复制链接]

1366

主题

1857

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14466
QQ
发表于 2018-3-30 15:28:53 | 显示全部楼层 |阅读模式


11、机器学习实战案例:普通最小二乘法求线性回归_笔记

  1. # -*- coding: utf-8 -*-
  2. __author__ = 'dongfangyao'
  3. __date__ = '2018/3/29 下午4:17'
  4. __product__ = 'PyCharm'
  5. __filename__ = 'least_squares1'



  6. # 线性回归的类
  7. from sklearn.linear_model import LinearRegression
  8. # 原始数据= 训练数据 + 测试数据  数据划分的类
  9. from sklearn.model_selection import train_test_split
  10. # 数据标准化
  11. from sklearn.preprocessing import StandardScaler

  12. import numpy as np
  13. import pandas as pd
  14. import matplotlib as mpl
  15. import matplotlib.pyplot as plt
  16. from pandas import DataFrame
  17. import time

  18. ## 设置字符集,防止中文乱码
  19. mpl.rcParams['font.family'] = 'sans-serif'
  20. mpl.rcParams['font.sans-serif'] = 'SimHei'
  21. mpl.rcParams['axes.unicode_minus'] = False

  22. # 加载数据
  23. # 日期、时间、有功功率、无功功率、电压、电流、厨房用电功率、洗衣服用电功率、热水器用电功率
  24. path1 = 'datas/household_power_consumption_1000.txt'
  25. df = pd.read_csv(path1, sep=';', low_memory=False)
  26. # 没有混合类型的时候可以通过low_memory=False调用更多内存,加快效率)

  27. # print(df.head(2))
  28. # print(df.index)
  29. # print(df.columns)

  30. # 查看数据结构
  31. # print(df.info())

  32. # 异常数据处理(异常数据过滤)
  33. # 替换非法字符为np.nan
  34. new_df = df.replace('?', np.nan)
  35. # 只要有一个数据为空,就进行行删除操作
  36. datas = new_df.dropna(axis=0, how='any')
  37. # 观察数据的多种统计指标(只能看数值型的 本来9个的变7个了)
  38. # print(datas.describe().T)


  39. # 需求:构建时间和功率之间的映射关系,可以认为:特征属性为时间;目标属性为功率值。
  40. # 获取x和y变量, 并将时间转换为数值型连续变量

  41. # 创建一个时间函数格式化字符串
  42. def date_format(dt):
  43.     # dt显示是一个Series
  44.     # print(dt.index)
  45.     # print(dt)
  46.     t = time.strptime(' '.join(dt), '%d/%m/%Y %H:%M:%S')
  47.     return (t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)

  48. X = datas.iloc[:, 0:2]
  49. # print(X)
  50. X = X.apply(lambda x: pd.Series(date_format(x)), axis=1)
  51. Y = datas['Global_active_power']
  52. # print(Y.head(4))
  53. # print(X.head(4))
  54. # print(type(X))
  55. # print(type(Y))


  56. # 对数据集进行测试集、训练集划分
  57. # X:特征矩阵(类型一般是DataFrame)
  58. # Y:特征对应的Label标签或目标属性(类型一般是Series)

  59. # test_size: 对X/Y进行划分的时候,测试集合的数据占比, 是一个(0,1)之间的float类型的值
  60. # random_state: 数据分割是基于随机器进行分割的,该参数给定随机数种子;
  61. # 给一个值(int类型)的作用就是保证每次分割所产生的数数据集是完全相同的
  62. # 默认的随机数种子是当前时间戳 random_state=None的情况下
  63. X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=0)

  64. # print(X_train.shape)
  65. # print(X_test.shape)
  66. # print(Y_train.shape)
  67. # print(Y_test.shape)

  68. # 查看训练集上的数据信息(X)
  69. print(X_train.describe().T)

  70. # 特征数据标准化(也可以说是正常化、归一化、正规化)
  71. # StandardScaler:将数据转换为标准差为1的数据集(有一个数据的映射)
  72. # scikit-learn中:如果一个API名字有fit,那么就有模型训练的含义,没法返回值
  73. # scikit-learn中:如果一个API名字中有transform, 那么就表示对数据具有转换的含义操作
  74. # scikit-learn中:如果一个API名字中有predict,那么就表示进行数据预测,会有一个预测结果输出
  75. # scikit-learn中:如果一个API名字中既有fit又有transform的情况下,那就是两者的结合(先做fit,再做transform)

  76. # 模型对象创建
  77. ss = StandardScaler()
  78. # 训练模型并转换训练集
  79. X_train = ss.fit_transform(X_train)
  80. # 直接使用在模型构建数据上进行一个数据标准化操作 (测试集)
  81. X_test = ss.transform(X_test)

  82. # print(X_train.describe().T)
  83. # print(type(X_train))
  84. # print(X_train.shape, X_train.ndim)
  85. print(pd.DataFrame(X_train).describe().T)


  86. # 模型训练
  87. # 模型对象构建
  88. # fit_intercept fit训练 intercept截距
  89. # LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
  90. # n_jobs模型训练的任务数 是否并行 并行需要至少2个cpu的 基本没什么用这个参数
  91. lr = LinearRegression(fit_intercept=True)
  92. # 训练模型
  93. lr.fit(X_train, Y_train)
  94. # 模型校验
  95. # 预测结果
  96. y_predict = lr.predict(X_test)

  97. # 回归中的R^2就是准确率 后面会说
  98. print("训练集上R^2:", lr.score(X_train, Y_train))
  99. print("测试集上R^2:", lr.score(X_test, Y_test))
  100. # 预测值与实际值的差值 平方和 再求均值
  101. mse = np.average((y_predict-Y_test)**2)
  102. rmse = np.sqrt(mse)
  103. print("rmse:", rmse)

  104. # 输出模型训练得到的相关参数
  105. # 注意:第1、2、6个系数为0
  106. print("模型的系数(θ):", end="")
  107. print(lr.coef_)
  108. print("模型的截距:", end='')
  109. print(lr.intercept_)


  110. # 模型保存/持久化(跳过)
  111. # 加载模型 并进行预测(跳过)

  112. # 预测值和实际值画图比较
  113. t = np.arange(len(X_test))
  114. # 建一个画布,facecolor是背景色
  115. plt.figure(facecolor='w')
  116. plt.plot(t, Y_test, 'r-', linewidth=2, label='真实值')
  117. plt.plot(t, y_predict, 'g-', linewidth=2, label='预测值')
  118. # 显示图例,设置图例的位置
  119. plt.legend(loc = 'upper left')
  120. plt.title("线性回归预测时间和功率之间的关系", fontsize=20)
  121. # 加网格
  122. plt.grid(b=True)
  123. plt.show()



复制代码




  1. ## 功率和电流之间的关系
  2. X = datas.iloc[:,2:4]
  3. Y2 = datas.iloc[:,5]

  4. ## 数据分割
  5. X2_train,X2_test,Y2_train,Y2_test = train_test_split(X, Y2, test_size=0.2, random_state=0)

  6. ## 数据归一化
  7. scaler2 = StandardScaler()
  8. X2_train = scaler2.fit_transform(X2_train) # 训练并转换
  9. X2_test = scaler2.transform(X2_test) ## 直接使用在模型构建数据上进行一个数据标准化操作

  10. ## 模型训练
  11. lr2 = LinearRegression()
  12. lr2.fit(X2_train, Y2_train) ## 训练模型

  13. ## 结果预测
  14. Y2_predict = lr2.predict(X2_test)

  15. ## 模型评估
  16. print("电流预测准确率: ", lr2.score(X2_test,Y2_test))
  17. print("电流参数:", lr2.coef_)

  18. ## 绘制图表
  19. #### 电流关系
  20. t=np.arange(len(X2_test))
  21. plt.figure(facecolor='w')
  22. plt.plot(t, Y2_test, 'r-', linewidth=2, label=u'真实值')
  23. plt.plot(t, Y2_predict, 'g-', linewidth=2, label=u'预测值')
  24. plt.legend(loc = 'lower right')
  25. plt.title(u"线性回归预测功率与电流之间的关系", fontsize=20)
  26. plt.grid(b=True)
  27. plt.show()
复制代码

普通最小二乘法求线性回归_案例.png
Figure_1.png
Figure_11.png
画板 1.png
画板 2.png
画板 3.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1366

主题

1857

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14466
QQ
 楼主| 发表于 2019-9-12 09:31:26 | 显示全部楼层
  1. import numpy as np
  2. from .metrics import r2_score

  3. class LinearRegression:

  4.     def __init__(self):
  5.         """初始化Linear Regression模型"""
  6.         self.coef_ = None
  7.         self.intercept_ = None
  8.         self._theta = None

  9.     def fit_normal(self, X_train, y_train):
  10.         """根据训练数据集X_train, y_train训练Linear Regression模型"""
  11.         assert X_train.shape[0] == y_train.shape[0], \
  12.             "the size of X_train must be equal to the size of y_train"

  13.         X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
  14.         self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

  15.         self.intercept_ = self._theta[0]
  16.         self.coef_ = self._theta[1:]

  17.         return self

  18.     def fit_gd(self, X_train, y_train, eta=0.01, n_iters=1e4):
  19.         """根据训练数据集X_train, y_train, 使用梯度下降法训练Linear Regression模型"""
  20.         assert X_train.shape[0] == y_train.shape[0], \
  21.             "the size of X_train must be equal to the size of y_train"

  22.         def J(theta, X_b, y):
  23.             try:
  24.                 return np.sum((y - X_b.dot(theta)) ** 2) / len(y)
  25.             except:
  26.                 return float('inf')

  27.         def dJ(theta, X_b, y):
  28.             # res = np.empty(len(theta))
  29.             # res[0] = np.sum(X_b.dot(theta) - y)
  30.             # for i in range(1, len(theta)):
  31.             #     res[i] = (X_b.dot(theta) - y).dot(X_b[:, i])
  32.             # return res * 2 / len(X_b)
  33.             return X_b.T.dot(X_b.dot(theta) - y) * 2. / len(X_b)

  34.         def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):

  35.             theta = initial_theta
  36.             cur_iter = 0

  37.             while cur_iter < n_iters:
  38.                 gradient = dJ(theta, X_b, y)
  39.                 last_theta = theta
  40.                 theta = theta - eta * gradient
  41.                 if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
  42.                     break

  43.                 cur_iter += 1

  44.             return theta

  45.         X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
  46.         initial_theta = np.zeros(X_b.shape[1])
  47.         self._theta = gradient_descent(X_b, y_train, initial_theta, eta, n_iters)

  48.         self.intercept_ = self._theta[0]
  49.         self.coef_ = self._theta[1:]

  50.         return self

  51.     def fit_sgd(self, X_train, y_train, n_iters=5, t0=5, t1=50):
  52.         """根据训练数据集X_train, y_train, 使用梯度下降法训练Linear Regression模型"""
  53.         assert X_train.shape[0] == y_train.shape[0], \
  54.             "the size of X_train must be equal to the size of y_train"
  55.         assert n_iters >= 1

  56.         def dJ_sgd(theta, X_b_i, y_i):
  57.             return X_b_i * (X_b_i.dot(theta) - y_i) * 2.

  58.         def sgd(X_b, y, initial_theta, n_iters, t0=5, t1=50):

  59.             def learning_rate(t):
  60.                 return t0 / (t + t1)

  61.             theta = initial_theta
  62.             m = len(X_b)

  63.             for cur_iter in range(n_iters):
  64.                 indexes = np.random.permutation(m)
  65.                 X_b_new = X_b[indexes]
  66.                 y_new = y[indexes]
  67.                 for i in range(m):
  68.                     gradient = dJ_sgd(theta, X_b_new[i], y_new[i])
  69.                     theta = theta - learning_rate(cur_iter * m + i) * gradient

  70.             return theta

  71.         X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
  72.         initial_theta = np.random.randn(X_b.shape[1])
  73.         self._theta = sgd(X_b, y_train, initial_theta, n_iters, t0, t1)

  74.         self.intercept_ = self._theta[0]
  75.         self.coef_ = self._theta[1:]

  76.         return self

  77.     def predict(self, X_predict):
  78.         """给定待预测数据集X_predict,返回表示X_predict的结果向量"""
  79.         assert self.intercept_ is not None and self.coef_ is not None, \
  80.             "must fit before predict!"
  81.         assert X_predict.shape[1] == len(self.coef_), \
  82.             "the feature number of X_predict must be equal to X_train"

  83.         X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
  84.         return X_b.dot(self._theta)

  85.     def score(self, X_test, y_test):
  86.         """根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""

  87.         y_predict = self.predict(X_test)
  88.         return r2_score(y_test, y_predict)

  89.     def __repr__(self):
  90.         return "LinearRegression()"
复制代码
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

0

主题

96

帖子

202

积分

中级会员

Rank: 3Rank: 3

积分
202
发表于 2019-12-22 20:48:07 | 显示全部楼层
this is good idea
回复

使用道具 举报

0

主题

96

帖子

202

积分

中级会员

Rank: 3Rank: 3

积分
202
发表于 2019-12-22 20:50:34 | 显示全部楼层
this is good idea
回复

使用道具 举报

0

主题

24

帖子

54

积分

注册会员

Rank: 2

积分
54
发表于 2020-3-17 12:40:09 | 显示全部楼层
66666666666
回复

使用道具 举报

0

主题

46

帖子

155

积分

注册会员

Rank: 2

积分
155
发表于 2020-3-17 17:04:57 | 显示全部楼层
66666666666
回复

使用道具 举报

0

主题

4

帖子

91

积分

注册会员

Rank: 2

积分
91
发表于 2020-3-24 11:26:39 | 显示全部楼层
非常好非常好,very good
回复

使用道具 举报

0

主题

100

帖子

214

积分

中级会员

Rank: 3Rank: 3

积分
214
发表于 2020-5-22 10:43:56 | 显示全部楼层

非常好非常好,very good
回复

使用道具 举报

0

主题

100

帖子

214

积分

中级会员

Rank: 3Rank: 3

积分
214
发表于 2020-5-22 10:44:20 | 显示全部楼层

非常好非常好,very
good
回复

使用道具 举报

0

主题

100

帖子

214

积分

中级会员

Rank: 3Rank: 3

积分
214
发表于 2020-5-22 10:44:51 | 显示全部楼层

非常好非常好,very good
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-7-22 14:50 , Processed in 0.212408 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表