机器学习案例--回归分析
2018-03-31 11:03
381 查看
目录
1、最小二乘法1.1 原理推导
1.2 代码样例
2、SKlearn
2.1 代码样例
2.2 多项式扩展
2.3 正则化
2.4 逻辑回归和多酚类
1、最小二乘法解
1.1 算法原理
回归算法推导根据中心极限定理,误差服从正态分布,将误差带入之后用极大似然估计,取对数得到目标函数,目标函数是最小二乘的形式,求导得出的解是:
θ=(XTX)−1XTYθ=(XTX)−1XTY
1.2 样例
数据集下载:http://archive.ics.uci.edu/ml/datasets/Individual+household+electric+power+consumption
处理代码:
# 引入所需要的全部包 from sklearn.model_selection import train_test_split # 数据划分的类 import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import pandas as pd from pandas import DataFrame import time ## 设置字符集,防止中文乱码 mpl.rcParams['font.sans-serif']=[u'simHei'] mpl.rcParams['axes.unicode_minus']=False # 加载数据 # 日期、时间、有功功率、无功功率、电压、电流、厨房用电功率、洗衣服用电功率、热水器用电功率 path1='datas/household_power_consumption_1000.txt' df = pd.read_csv(path1, sep=';', low_memory=False)#没有混合类型的时候可以通过low_memory=F调用更多内存,加快效率) #查看前两行数据 df.head(2)
## 通过active_power 和 reactive_power 预测intensity X = df.iloc[:,2:4] Y2 = df.iloc[:,5] ## 数据分割 X2_train,X2_test,Y2_train,Y2_test = train_test_split(X, Y2, test_size=0.2, 4000 random_state=0) # 将X和Y转换为矩阵的形式 X = np.mat(X2_train) Y = np.mat(Y2_train).reshape(-1,1) # 计算θ theta = (X.T * X).I * X.T * Y print(theta) #[[4.20324605] # [1.36676171]] # 对测试集合进行测试 y_hat = np.mat(X2_test) * theta # 画图 #### 电流关系 t=np.arange(len(X2_test)) plt.figure(facecolor='w') plt.plot(t, Y2_test, 'r-', linewidth=2, label=u'真实值') plt.plot(t, y_hat, 'g-', linewidth=2, label=u'预测值') plt.legend(loc = 'lower right') plt.title(u"线性回归预测功率与电流之间的关系", fontsize=20) plt.grid(b=True) plt.show()
2 SKLearn 线性回归
class sklearn.linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)[source]传入参数
fit_intercept: 是否要截距,也就是θ0θ0
normalize:是否标准化
copy_X:是否复制训练集,不改变原数据
n_jobs:并行计算
返回
coef_:各个特征前的系数 [ array, shape (n_features, ) or (n_targets, n_features) ]
intercept_:截距
2.1 例子:找时间和电压之间的关系
# 引入所需要的全部包 from sklearn.model_selection import train_test_split # 数据划分的类 from sklearn.linear_model import LinearRegression # 线性回归的类 from sklearn.preprocessing import StandardScaler # 数据标准化 import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import pandas as pd from pandas import DataFrame import time ## 设置字符集,防止中文乱码 mpl.rcParams['font.sans-serif']=[u'simHei'] mpl.rcParams['axes.unicode_minus']=False ## 创建一个时间函数格式化字符串 def date_format(dt): # dt显示是一个series/tuple;dt[0]是date,dt[1]是time import time t = time.strptime(' '.join(dt), '%d/%m/%Y %H:%M:%S') return (t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec) X = datas.iloc[:,0:2] X = X.apply(lambda x: pd.Series(date_format(x)), axis=1) #按行读取 Y = datas['Global_active_power'] #数据集划分 X_train,X_test,Y_train,Y_test = train_test_split(X, Y, test_size=0.2, random_state=0) #标准化操作,使各个变量的方差为1 ss = StandardScaler() # 模型对象创建 X_train = ss.fit_transform(X_train) # 训练模型并转换训练集 X_test = ss.transform(X_test) ## 直接使用在模型构建数据上进行一个数据标准化操作 (测试集) ## 模型训练 lr = LinearRegression(fit_intercept=True) # 模型对象构建 lr.fit(X_train, Y_train) ## 训练模型 ## 模型校验 y_predict = lr.predict(X_test) ## 预测结果 print("训练集上R2:",lr.score(X_train, Y_train)) print("测试集上R2:",lr.score(X_test, Y_test)) mse = np.average((y_predict-Y_test)**2) rmse = np.sqrt(mse) print("rmse:",rmse) #训练集上R2: 0.24409311805909026 #测试集上R2: 0.12551628513735869 #rmse: 1.1640923459736248 # 输出模型训练得到的相关参数 print("模型的系数(θ):", end="") print(lr.coef_) print("模型的截距:", end='') print(lr.intercept_) ## 模型保存/持久化 # 在机器学习部署的时候,实际上其中一种方式就是将模型进行输出;另外一种方式就是直接将预测结果输出 # 模型输出一般是将模型输出到磁盘文件 from sklearn.externals import joblib # 保存模型要求给定的文件所在的文件夹比较存在 joblib.dump(ss, "result/data_ss.model") ## 将标准化模型保存 joblib.dump(lr, "result/data_lr.model") ## 将模型保存 # 加载模型 ss3 = joblib.load("result/data_ss.model") ## 加载模型 lr3 = joblib.load("result/data_lr.model") ## 加载模型 # 使用加载的模型进行预测 data1 = [[2006, 12, 17, 12, 25, 0]] data1 = ss3.transform(data1) print(data1) lr3.predict(data1) ## 预测值和实际值画图比较 t=np.arange(len(X_test)) plt.figure(facecolor='w')#建一个画布,facecolor是背景色 plt.plot(t, Y_test, 'r-', linewidth=2, label='真实值') plt.plot(t, y_predict, 'g-', linewidth=2, label='预测值') plt.legend(loc = 'upper left')#显示图例,设置图例的位置 plt.title("线性回归预测时间和功率之间的关系", fontsize=20) plt.grid(b=True)#加网格 plt.show()
可以看到比较欠拟合,可以进行多项式扩充。
2.2 多项式扩展
一般比较少用,计算复杂度比较大,一般会用高斯函数映射。含义:找特征之间的关系和多次的关系。
例如:(x1,x2,x3)(x1,x2,x3)进行2次项扩展变成:
(x1,x2,x3,x1x2,x1x3,x2x3,x21,x32,x23)(x1,x2,x3,x1x2,x1x3,x2x3,x12,x23,x32)
继续上面的例子,加入多项式扩展,代码例子:
# 多项式扩展包 from sklearn.preprocessing import PolynomialFeatures # pipeline可以让训练集进行一系列处理 # 即先扩展再放入线性回归之中 from sklearn.pipeline import Pipeline models = [ Pipeline([ ('Poly', PolynomialFeatures()), # 给定进行多项式扩展操作, 第一个操作:多项式扩展 ('Linear', LinearRegression(fit_intercept=False)) # 第二个操作,线性回归 ]) ] model = models[0] # 模型训练 t=np.arange(len(X_test)) N = 5 d_pool = np.arange(1,N,1) # 阶 m = d_pool.size clrs = [] # 颜色 for c in np.linspace(16711680, 255, m): clrs.append('#%06x' % int(c)) line_width = 3 plt.figure(figsize=(12,6), facecolor='w')#创建一个绘图窗口,设置大小,设置颜色 for i,d in enumerate(d_pool): plt.subplot(N-1,1,i+1) plt.plot(t, Y_test, 'r-', label=u'真实值', ms=10, zorder=N) ### 设置管道对象中的参数值,Poly是在管道对象中定义的操作名称, 后面跟参数名称;中间是两个下划线 model.set_params(Poly__degree=d) ## 设置多项式的阶乘 model.fit(X_train, Y_train) # 模型训练 # Linear是管道中定义的操作名称 # 获取线性回归算法模型对象 lin = model.get_params()['Linear'] output = u'%d阶,系数为:' % d # 判断lin对象中是否有对应的属性 if hasattr(lin, 'alpha_'): idx = output.find(u'系数') output = output[:idx] + (u'alpha=%.6f, ' % lin.alpha_) + output[idx:] if hasattr(lin, 'l1_ratio_'): idx = output.find(u'系数') output = output[:idx] + (u'l1_ratio=%.6f, ' % lin.l1_ratio_) + output[idx:] print (output, lin.coef_.ravel()) # 模型结果预测 y_hat = model.predict(X_test) # 计算评估值 s = model.score(X_test, Y_test) # 画图 z = N - 1 if (d == 2) else 0 label = u'%d阶, 准确率=%.3f' % (d,s) plt.plot(t, y_hat, color=clrs[i], lw=line_width, alpha=0.75, label=label, zorder=z) plt.legend(loc = 'upper left') plt.grid(True) plt.ylabel(u'%d阶结果' % d, fontsize=12) ## 预测值和实际值画图比较 plt.suptitle(u"线性回归预测时间和功率之间的多项式关系", fontsize=20) plt.grid(b=True) plt.show()
可以看到随着阶数增多,拟合的情况会变好,但是会带来过拟合的问题,所以加入正则化,让参数不会过大。
2.3 正则化
from sklearn.linear_model import LinearRegression, LassoCV, RidgeCV, ElasticNetCV三种方法:
正则化有三种 L1(Lasso), L2(RidgeCV), ElasticNet
L1: 能得到比较稀疏的解,训练速度快,但稳定性较差
L2: 稳定行比较好
Elastic: 综合前两项
models = [ Pipeline([ ('Poly', PolynomialFeatures(include_bias=False)), ('Linear', LinearRegression(fit_intercept=False)) ]), #通过交叉验证确定参数,L2正则化。 Pipeline([ ('Poly', PolynomialFeatures(include_bias=False)), # alpha给定的是Ridge算法中,L2正则项的权重值 # alphas是给定CV交叉验证过程中,Ridge算法的alpha参数值的取值的范围 ('Linear', RidgeCV(alphas=np.logspace(-3,2,50), fit_intercept=False)) ]), Pipeline([ ('Poly', PolynomialFeatures(include_bias=False)), ('Linear', LassoCV(alphas=np.logspace(0,1,10), fit_intercept=False)) ]), Pipeline([ ('Poly', PolynomialFeatures(include_bias=False)), # la_ratio:给定EN算法中L1正则项在整个惩罚项中的比例,这里给定的是一个列表; # 表示的是在CV交叉验证的过程中,EN算法L1正则项的权重比例的可选值的范围 ('Linear', ElasticNetCV(alphas=np.logspace(0,1,10), l1_ratio=[.1, .5, .7, .9, .95, 1], fit_intercept=False)) ]) ]
2.4 逻辑回归与多项式回归
class sklearn.linear_model.LogisticRegressionCV(Cs=10, fit_intercept=True, cv=None, dual=False, penalty=’l2’, scoring=None, solver=’lbfgs’, tol=0.0001, max_iter=100, class_weight=None, n_jobs=1, verbose=0, refit=True, intercept_scaling=1.0, multi_class=’ovr’, random_state=None)[source]¶相关文章推荐
- 机器学习回归算法—线性回归及案例分析
- 机器学习回归算法—岭回归及案例分析
- [机器学习]回归分析案例 --- 网游排名分析
- 【机器学习笔记三】回归分析 - 岭回归
- 【机器学习经典算法源码分析系列】-- 逻辑回归
- 机器学习:浅析使用二元决策树进行回归分析
- Hive+Druid 实现快速查询;回归分析是机器学习吗;StructuredStreaming 可用于生产环境
- (机器学习笔记一)回归分析
- 七月机器学习之回归分析与工程应用5
- 机器学习入门系列02,Regression 回归:案例研究
- 机器学习入门系列02-Regression 回归:案例研究
- 公开课机器学习笔记(1)回归分析
- 机器学习-sklearn逻辑回归分析
- 课程笔记-深度学习之逻辑回归(Regression)pokemon案例分析
- 机器学习 - 回归分析
- python机器学习案例系列教程——逻辑分类/逻辑回归LR/一般线性回归(softmax回归)
- 机器学习笔记--回归分析(3)
- SPSS-相关性和回归分析(一元线性方程)案例解析
- 回归,分类与聚类:三个方向分析机器学习
- R语言案例分析:财政收入的多元相关与回归分析