sklearn多元回归分析(线性回归,ransac)

今天主要学习的是多元回归分析.我个人的简单理解就是用

`y=ax1+bx2+cx3+...+β`

线性方程来拟合某个规律.一元的时候是最小二乘法,高中的知识.多元的时候也是,暂时还没研究具体的公式和感受公式的含义.只当是高中公式一样,单纯往里套(调用sklearn的API)
2017年数模国赛B

在这里插入图片描述
主要目标是用红框的三个因素来拟合任务标价.先上代码.

from sklearn.linear_model import LinearRegression
import openpyxl
import matplotlib.pyplot as plt 
# from mpl_toolkits import mplot3d
import numpy as np 
# import sklearn.linear_model
# ax = plt.axes(projection='3d')

excel = openpyxl.load_workbook('聚类3的数据.xlsx')
sheet = excel['Sheet2']

jiage = []
distance = []
mijidu = []
huiyuanmijidu=[]
finish = []
julei = []
for i in range(2,sheet.max_row):
    jiage.append(sheet.cell(row=i,column=4).value)
    distance.append(sheet.cell(row=i,column=7).value)
    mijidu.append(sheet.cell(row=i,column=8).value)
    huiyuanmijidu.append(sheet.cell(row=i,column=11).value)
    finish.append(sheet.cell(row=i,column=9).value)
    julei.append(sheet.cell(row=i,column=10).value)
X = []
y=[]
myfinish=[]
for i in range(len(jiage)):
    if (finish[i] == 0) or 1:
        # y.append([jiage[i]-65])
        y.append([jiage[i]])
        X.append([distance[i],mijidu[i],huiyuanmijidu[i]])
        # X.append([distance[i],mijidu[i]])
        myfinish.append(finish[i])


# X=np.array(X)
# y=np.array(y)
# color = np.array(finish)
# ax.scatter3D(X[:,0],X[:,1],y,c=color)

# plt.show()

module = LinearRegression(fit_intercept=1)
module.fit(X,y)

# ransac = sklearn.linear_model.RANSACRegressor()
# ransac.fit(X,y)
# predict_y = ransac.predict(X)
X = []
y=[]
myfinish=[]
for i in range(len(jiage)):
    if (finish[i] == 1) or 1:
        # y.append([jiage[i]-65])
        y.append([jiage[i]])
        X.append([distance[i],mijidu[i],huiyuanmijidu[i]])
        # X.append([distance[i],mijidu[i]])
        myfinish.append(finish[i])

predict_y = module.predict(X)

# inlier_mask = ransac.inlier_mask_

count=0
undo=0
allcount=0
for i in range(len(predict_y)):
    # predict = predict_y[i][0] +65
    predict = predict_y[i][0]
    sheet.cell(row=i+2,column = 6).value = predict 
    if myfinish[i] == 0:
        undo+=1
    if(predict>=jiage[i] and myfinish[i]==0):
        count+=1
    if(predict>=jiage[i] ):
        allcount+=1

plt.plot([i for i in range(len(predict_y))],predict_y,c='blue')
plt.scatter([i for i in range(len(jiage))],jiage,c='r',marker='o')
plt.show()

# print(count,undo,allcount,len(predict_y))
print(count/undo)
print(allcount/len(predict_y))
print(module.coef_)
print(module.intercept_)


# excel.save('新完整.xlsx')

这个代码可能略显混乱,尤其我还没做注释.后边有比较简化版的.整个代码有以下几个部分:

  • 读取数据
  • 将数据构造成为API要求的结构,在这一步我还会进行数据筛选,比如只选择特定一类的数据进行拟合,预测.
  • 虽然有三个因素,但我一开始是只用两个因素的,然后这段注释是将数据可视化.练习一下三维数据图.
import matplotlib.pyplot as plt 
from mpl_toolkits import mplot3d
X=np.array(X)
y=np.array(y)
color = np.array(finish)
ax.scatter3D(X[:,0],X[:,1],y,c=color)
  • 中间夹杂了一个ransac下面再具体写写
  • 接下来的一部分是再次选择数据进行预测.可以只用原数据进行预测,也可以多一些数据进行预测.
  • 最后展示拟合结果,以及系数.
  • 注:中间有关65的一些注释是在实现一个效果,固定截距.比如我想设定截距为65,那么我只需要将目标值减掉65,然后设定linerregression的intercept为0,即设置截距为0,这样就能得到β为65的拟合方程.不是很清楚API是否自带这个功能.
    在这里插入图片描述

在这里插入图片描述

  • 拟合情况如上图所示,可以看出拟合的效果不是太好,高的基本都没拟合到.需要完善一下模型,把高的几个点拟合了.数学模型需要进一步的完善.
  • 还有一点就是可以看到第一个系数和后面两个数相差比较大.主要原因就是我没有对数据进行标准化.标准化的好处,就是可以对比三个影响因素,确定三个影响因子到底有没有影响,影响有多大.(个人理解)其实标准化也是调个API的事,原理就是x-E(x)/D(x)概率论的正态分布内容.

接下来是比较简洁的代码.去掉了一些题目要求,单纯的进行拟合.

from sklearn.linear_model import LinearRegression
import openpyxl
import matplotlib.pyplot as plt 
# from mpl_toolkits import mplot3d
import numpy as np 
import sklearn.linear_model
# ax = plt.axes(projection='3d')

excel = openpyxl.load_workbook('聚类3的数据.xlsx')
sheet = excel['Sheet2']

jiage = []
distance = []
mijidu = []
huiyuanmijidu=[]
finish = []
julei = []
for i in range(2,sheet.max_row):
    jiage.append(sheet.cell(row=i,column=4).value)
    distance.append(sheet.cell(row=i,column=7).value)
    mijidu.append(sheet.cell(row=i,column=8).value)
    huiyuanmijidu.append(sheet.cell(row=i,column=11).value)
    finish.append(sheet.cell(row=i,column=9).value)
    julei.append(sheet.cell(row=i,column=10).value)
X = []
y=[]
myfinish=[]
for i in range(len(jiage)):
    if (finish[i] == 0) or 1:
        # y.append([jiage[i]-65])
        y.append([jiage[i]])
        X.append([distance[i],mijidu[i],huiyuanmijidu[i]])
        # X.append([distance[i],mijidu[i]])
        myfinish.append(finish[i])


X=np.array(X)
y=np.array(y)
# color = np.array(finish)
# ax.scatter3D(X[:,0],X[:,1],y,c=color)

# plt.show()

# module = LinearRegression(fit_intercept=1)
# module.fit(X,y)
# predict_y = module.predict(X)

ransac = sklearn.linear_model.RANSACRegressor()
ransac.fit(X,y)
predict_y = ransac.predict(X)
newX =[i for i in range(len(X))]
newX =np.array(newX)
inlier_mask = ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)
predict_y = ransac.predict(X)



plt.scatter(newX[inlier_mask], y[inlier_mask],
            c='steelblue', edgecolor='white', 
            marker='o', label='Inliers')
plt.scatter(newX[outlier_mask], y[outlier_mask],
            c='limegreen', edgecolor='white', 
            marker='s', label='Outliers')
plt.plot([i for i in range(len(predict_y))],predict_y,c='blue')


plt.legend(loc='upper left')
# plt.plot([i for i in range(len(predict_y))],predict_y,c='blue')
# plt.scatter([i for i in range(len(jiage))],jiage,c='r',marker='o')
plt.show()


# print(module.coef_)
# print(module.intercept_)


上面有提到,拟合的结果不是很好.那么怎么拟合好一些呢.有句话说的好,解决不了问题,就解决提出问题的人.把一些噪点除掉.离群点干掉.ransac就是这么一个解决离群点的方法.具体原理其实我也没弄懂…就不班门弄斧了.上面的代码就是ransac的使用方法,注释掉的是原先的多元线性回归的拟合方法.
下面展示下拟合结果.
在这里插入图片描述
拟合的是相当的好,我觉得可能都过拟合了.把不顺眼的点全干掉了…
不过数模不能这么搞,最起码这道数模题不行.数模的任务主要还是要分析一下第一道题那里的离群点离群的原因,增加一些影响因子,完善模型.这个方法,是我在尝试更好拟合时寻找到的方法,放在这里水水.

还有一个小技巧通过这个代码能将横轴刻度旋转,防止重叠的情况.

plt.xticks(my_x_ticks,rotation = -90)

在这里插入图片描述

今日感慨,调API是方便了…不过很多原理都没懂,只能说慢慢来了…

猜你喜欢

转载自blog.csdn.net/rglkt/article/details/107586490