Python之数据分析(numpy线性模型、线性预测、线性拟合)


线性模型分为两种:线性预测和线性拟合,这两种都可以起到预测走势和数据点的作用,当然,预测是存在一定误差的,因此这种预测图像仅供参考。

一、线性预测

1、基本概念
线性预测(a*x=b)

/a b c\        /A\      / d \
|b c d|   X   | B |  =  | e |
\c d e/        \C/      \ f /

2、numpy进行预测的函数

  • numpy.linalg.lstsq(a, b)
    需要预测的就是x

3、价格预测案例

import datetime as dt
import numpy as np
import matplotlib.pylab as mp
import matplotlib.dates as md
import pandas as pd  # 日期计算

def dmy2ymd(dmy):
    dmy = str(dmy, encoding='utf-8')  # 转码dmy日期
    date = dt.datetime.strptime(dmy, '%d-%m-%Y').date()  # 获取时间对象
    ymd = date.strftime('%Y-%m-%d')
    return ymd

dates, closing_prices = np.loadtxt(
    '0=数据源/beer_price.csv', delimiter=',',
    usecols=(0, 4), unpack=True,
    dtype=np.dtype('M8[D], f8'),
    converters={0: dmy2ymd}
)

'''
收盘价格预测
'''
N = 5  # 最开始是数组是2*N个,
# 初始化预测价格
pred_prices = np.zeros(closing_prices.size - 2*N + 1)  # 2*N是表示无法预测的
# 给预测价格数组填入职
for i in range(pred_prices.size):
    a = np.zeros((N, N))  # 初始化N*N的矩阵
    # a[0, ] = closing_prices[0: 5]  # a的第0行,对应收盘价的0到5个元素
    # a[1, ] = closing_prices[1: 6]
    # a[2, ] = closing_prices[2: 7]
    # 得到a矩阵:用循环表示以上的效果
    for j in range(N):
        a[j, ] = closing_prices[i+j: i+j+N]  # +i表示跟上起点位置

    # 得到b向量
    b = closing_prices[i+N: i+N*2]

    x = np.linalg.lstsq(a, b)[0]  # 第0个值才是解方程的根

    pred_prices[i] = b.dot(x)  # b点乘x

    # 检验计算
    # print(a.dot(x), b)  # a点乘x就是b

# 曲线图基础设置
mp.figure('Stock Price Prediction', facecolor='lightgray')
mp.title('Stock Price Prediction', fontsize=20)
mp.xlabel('Date', fontsize=14)
mp.ylabel('Price', fontsize=14)

# 主刻度设置为以周一为起始的星期格式
ax = mp.gca()  # 获取刻度线(坐标轴)
ax.xaxis.set_major_locator(
    md.WeekdayLocator(byweekday=md.MO)
)
# 次刻度设置为以天为单位
ax.xaxis.set_minor_locator(
    md.DayLocator()
)
# 主刻度的格式化
ax.xaxis.set_major_formatter(
    md.DateFormatter('%d %b %Y')
)

mp.tick_params(labelsize=10)  # 字体
mp.grid(linestyle=':')  # 网格线

# 绘制曲线
dates = dates.astype(md.datetime.datetime)  # 将日期标准化成numpy的日期
mp.plot(dates, closing_prices, 'o-', c='lightgray', label="Closing Price")  # 绘制曲线

# 新增一个日期:计算两个时间点的距离
dates = np.append(dates, dates[-1] + pd.tseries.offsets.BDay())  # 在dates后面加上后面这个新的日期

# 绘制预测的股价,起点是N*2,o-表示点图
mp.plot(dates[N*2: ], pred_prices, 'o-', c='orangered', label='Predicted Price')

# 打印预测价格
# print(pred_prices)


mp.legend()  # 显示图例
mp.gcf().autofmt_xdate()  # 设置格式展示的自动化调整
mp.show()  # 显示图像

csv数据:
![11

4、测试效果
22

二、线性拟合

1、基本概念

kx1 + b = y1
kx2 + b = y2
...
kxn + b = yn
/ x1 \    / k \    / y1 \
| x2  | x | b |  = | y2 |
|...  |   \   /    |... |
\ xn /             \ yn /
  
   a           x          b

2、numpy的对应函数
x = np.linalg.lstsq(a, b)

3、统计学知识

  • 趋势点:设定的某几项数据的平均值(此处为最高价、最低价与收盘价的平均值)
  • 压力点:趋势点+每天的幅度
  • 支撑点:趋势点-每天的幅度
  • 计算趋势线:日期乘斜率+截距

4、线性拟合趋势图案例

import datetime as dt
import numpy as np
import matplotlib.pylab as mp
import matplotlib.dates as md

# 转换时间格式
def dmy2ymd(dmy):
    dmy = str(dmy, encoding='utf-8')
    # 利用python能够解析日-月-年的时间格式,来解析成时间信息,再转化成年-月-日的numpy时间格式
    date = dt.datetime.strptime(dmy, '%d-%m-%Y').date()  # 得到日期子对象
    ymd = date.strftime('%Y-%m-%d')  # 将时间信息格式化成字符串
    return ymd

# 解包取出:时间,开盘价,最高价,最低价,收盘价
dates, opening_prices, highest_prices, lowest_prices, closing_prices = np.loadtxt(
    '0=数据源/beer_price.csv', delimiter=',',
    usecols=(0, 1, 2, 3, 4), unpack=True,
    dtype='M8[D], f8, f8, f8, f8',
    converters = {0:dmy2ymd}
)
# M是numpy 的时间数据类型,[]表示精度,D是日,以日为单位的时间
# 由于数据内时间格式是日-月-年,需要用converter转化成年月日
# {0:dmy2ymd}表示将第0列的数据全部用dmy2ymd执行一遍
# print(opening_prices)

# 得到b向量(趋势点):将趋势点定位最高价、最低价和收盘价的平均值,不管开盘价
trend_points = (highest_prices + lowest_prices + closing_prices) / 3  # 每天三个价格平均值的数组
# 每天的幅度
spreads = highest_prices - lowest_prices
# 压力点:趋势点+每天的幅度
resistance_points = trend_points + spreads
# 支撑点:趋势点-每天的幅度
support_points = trend_points - spreads

# 日期类型转换:将日期换成以天为单位,直接用int
days = dates.astype(int)
# 得到a矩阵:将天数与全是1的矩阵按列组合在一起
a = np.column_stack((days, np.ones_like(days)))  # ones_like得到一个全是1的矩阵,矩阵格式与days相等
# 计算趋势线:日期乘斜率+截距
x1 = np.linalg.lstsq(a, trend_points)[0]
trend_line = days * x1[0] + x1[1]
# 计算压力线:
x2 = np.linalg.lstsq(a, resistance_points)[0]
resistance_line = days * x2[0] + x2[1]
# 计算支撑线:
x3 = np.linalg.lstsq(a, support_points)[0]
support_line = days * x3[0] + x3[1]



# 图像基本参数
mp.figure('Trend', facecolor='lightgray')
mp.title('Trend', fontsize=20)
mp.xlabel('Date', fontsize=14)  # 横轴、纵轴的标签
mp.ylabel('Price', fontsize=14)

# 坐标轴设置
ax = mp.gca()  # 获取坐标轴
# 设置主、副刻度定位器
ax.xaxis.set_major_locator(
    md.WeekdayLocator(byweekday=md.MO)  # 星期定位器,MO(Monday)表示以星期一作为主刻度定位
)
ax.xaxis.set_minor_locator(
    md.DayLocator()  # 日定位器
)
# 日期的格式
ax.xaxis.set_major_formatter(md.DateFormatter('%d %b %Y'))
mp.tick_params(labelsize=10)  # 设置标签所用的字体
mp.grid(linestyle=':')  # 网格线


# 将日期转换成matplotlib.dates(md)的类型
dates = dates.astype(md.datetime.datetime)

# 获取价格差:数组相减再做判断等于一个装满布尔值的数组
rise = closing_prices - opening_prices >= 0.01  # 上涨
fall = opening_prices - closing_prices >= 0.01  # 下跌

# 确定每根K线的颜色
# 初始化颜色数组为0,个数为dates的个数,颜色数据格式是3个float
fc = np.zeros(dates.size, dtype='3f4')  # 填充色
ec = np.zeros(dates.size, dtype='3f4')  # 边框色
fc[rise], fc[fall] = (1, 1, 1), (0.85, 0.85, 0.85)
# 将fc中为真的(上涨)设置颜色为(1, 1, 1)白色,下跌的设置为(0, 0.5, 0)绿色
ec[rise], ec[fall] = (0.85, 0.85, 0.85), (0.85, 0.85, 0.85)

# 画引线:矩形条
mp.bar(dates, highest_prices-lowest_prices, 0, lowest_prices, color=fc, edgecolor=ec)
# 纵坐标是最高价-最低价(数组),0表示矩形条宽度(最窄),1表示最宽;
# 起点位以最低价为起点,边框颜色是ec
mp.bar(dates, closing_prices-highest_prices, 0.8, opening_prices, color=fc, edgecolor=ec)
# 绘制趋势线:将这些趋势点(最高、最低、收盘)用点一个个小蓝点表示出来
mp.scatter(dates, trend_points, c="dodgerblue", alpha=0.5, s=60, zorder=2)  # 点
mp.plot(dates, trend_line, c="dodgerblue", linewidth=3, label="Trend")  # 线
# 绘制压力线
mp.scatter(dates, resistance_points, c="limegreen", alpha=0.5, s=30, zorder=2)  # 点
mp.plot(dates, resistance_line, c="limegreen", linewidth=1.5, label="Resistance")  # 线
# 绘制支撑线
mp.scatter(dates, support_points, c="orangered", alpha=0.5, s=30, zorder=2)  # 点
mp.plot(dates, support_line, c="orangered", linewidth=1.5, label="Support")  # 线


# 自动格式化水平方向的日期
mp.gcf().autofmt_xdate()
mp.legend()
mp.show()

csv数据:
33

5、测试效果
44

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸿蒙Next

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值