github:https://github.com/iluccica/MLPractice/tree/master/LinearRegression
数据集:从卫健委找的几条新冠肺炎数据 ,长这样:
目标:对新增确诊病例(increment)做回归分析。
1.单元线性回归
预测新增病例随天数的变化。
#处理exel数据的库
import xlrd
import matplotlib.pyplot as plt
import numpy as np
#get the table
table = data.sheet_by_index(0)
# get x and y
X = table.col_values(0)[1:table.nrows]
Y = table.col_values(1)[1:table.nrows]
X = np.array(X)
Y = np.array(Y)
## preprocessing
# X = X/abs(X.max())
# Y = Y/abs(Y.max())
单元线性回归求参数模型:
#bulid model
Xsum = 0
X2sum = 0
Ysum = 0
XY = 0
#样本数
n = table.nrows - 1
for i in range(n):
Xsum += X[i]
Ysum += Y[i]
X2sum += X[i]**2
XY = X[i] * Y[i]
k = (XY - Xsum * Ysum / n) / (X2sum - Xsum**2/n)
b = (Ysum - k * Xsum) / n
#预测20天的
days = range(0,20)
Y_pred = k*days + b
#plot
plt.plot(X,Y,'go', label='Original Data')
plt.plot(days,Y_pred,'r-', label='Fitted Line')
plt.title('pneumonia prediction')
plt.xlabel('Date')
plt.ylabel('Increment')
plt.legend()
plt.show()
2.多元线性回归
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
#画散点图好用的
import seaborn as sns
from sklearn.preprocessing import StandardScaler
#读数据
data = pd.read_csv('pneumonia.csv')
#数据归一,标准化
# ss = StandardScaler()
# scale_features = data.columns.values
# data[scale_features] = ss.fit_transform(data[scale_features])
# print(data)
##计算统计量,均值 标准差
#print(data.describe())
##找到缺失值
#print(data[data.isnull()==True].count())
#特征箱型图,看下特征值的分布
# data.boxplot()
# plt.show()
# plt.savefig("boxplot.jpg")
特征值分布有点分散,可以考虑归一化。
#相关系数矩阵
# print(data.corr())
#单类特征对结果的回归图
# sns.pairplot(data,x_vars=['days','Suspected cases(1 day before)','close exposure(1 day before)'],y_vars='increment',
# size=4,kind='reg')
# plt.show()
阴影为95%置信区间。
#建立模型
#这里没设置test集和accuracy,epoch没必要
epoch = 10
model = LinearRegression()
w_total = np.empty([10,3])
for i in range(0,epoch):
model.fit(data[np.delete(data.columns,1)],data['increment'])
b = round(model.intercept_,3)
np.set_printoptions(precision=3, suppress=True)
w = model.coef_
# print("b = ",b,"\nw = ",w)
w_total[i] = w
#权重增加列名
w_total = pd.DataFrame(w_total,columns=['days','Suspected cases(1 day before)','close exposure(1 day before)'])
#这个例子里十次的权重都是一样的,随便拿一组,来计算解释环节用到的影响程度
new_w = w_total.loc[0]
#计算某个特征对结果的影响
effect = data[np.delete(data.columns,1)]
for idx in np.delete(data.columns,1):
effect[idx] = effect[idx]*new_w[idx]
#影响图
effect.boxplot(vert = False)
plt.show()
影响图可以用来向客户、使用者解释模型,具体如何解释:《解释性机器学习》笔记(一):理解线性回归模型中的权重、特征和结果。