线性回归
1.交叉验证和网格搜索
1.1 交叉验证
- 将训练集划分为 K 份,其中一份做测试集,其他各份做测试集
- 提高模型评估的准确性
1.2 网络搜索
- 使用不同的超参数对模型进行评估,返回评估最好的模型
1.3 两者结合
- 通过对不同的模型,分别进行K折进行交叉验证,得出多个模型对应的评分,从而确定最优模型
1.4 API
- sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
- estimator 估计器,例如:KNN 对象
- param_grid 超参数,字典格式,例如:KNN 的 K 值
- cv 多少折交叉验证
- 结果分析
- bestscore__:在交叉验证中验证的最好结果
- bestestimator:最好的参数模型
- cvresults:每次交叉验证后的验证集准确率结果和训练集准确率结果
- fit
- 输入训练数据
- score
- 评估准确率
2.案例:Facebook 签到位置预测
2.1 案例介绍
-
预测目标
根据用户的位置,准确性和时间戳等预测用户下一次的签到位置
-
数据字段
- 数据来源:https://www.kaggle.com/c/facebook-v-predicting-check-ins
- row id 签入事件的id
- x y 坐标
- accuracy 准确度,定位精度
- time 时间戳
- place_id 签到的位置,即:目标值
-
数据信息
- 数据形状 29118021 行 6 列
- 训练集大小 1.27G
2.2 步骤分析
-
获取数据
-
数据基本处理
- 缩小数据集范围
- 选取有用的时间特征
- 删除签到少于 N 个用户的数据
- 确定特征值和目标值
- 分割数据集
-
特征工程-标准化
-
K近邻+网格搜索模型训练
-
模型预测
-
代码实现
-
from sklearn.neighbors import KNeighborsClassifier # 模型训练 from sklearn.model_selection import GridSearchCV # 网络搜索 from sklearn.model_selection import train_test_split # 数据处理与划分 from sklearn.preprocessing import StandardScaler # 标准化 import pandas as pd
-
# 数据获取 facebook_data = pd.read_csv("./data/FBlocaltion/train.csv") facebook_data.head()
-
# 查看行列 facebook_data.shape
-
# 查看列的类型 facebook_data.info()
-
# 数据处理 -缩小范围 # 选取 x,y 在 2,2.5 之间的数据 facebook_data = facebook_data.query("x>2 & x<2.5 & y>2 & y<2.5") facebook_data.head()
-
# 查看范围是都缩小 facebook_data.shape
-
# 选取有用的时间特征 facebook_data["time"].head()
-
# 将时间戳转换为日期时间格式 sign_time = pd.to_datetime(facebook_data["time"], unit="s") # 告诉 to_datetime ,我这个时间是以秒为单位 sign_time.head()
-
# 将内部时间格式拆分开,可以单独读取 sign_time = pd.DatetimeIndex(sign_time) sign_time.day
-
# 将提取的数据重新赋予新的变量 facebook_data["day"] = sign_time.day facebook_data["weekday"] = sign_time.weekday facebook_data["hour"] = sign_time.hour facebook_data.head()
-
# 删除签到少于N个用户的数据 # 删除签到次数少于 3 的列 place_count = facebook_data.groupby("place_id").count() place_count = place_count[place_count["row_id"]>20] facebook_data = facebook_data[facebook_data.place_id.isin(place_count.index)] facebook_data.shape
-
# 查看前五列 facebook_data.head()
-
# 确定特征值和目标值 X = facebook_data[["x", "y", "accuracy", "day", "weekday", "hour"]] y = facebook_data["place_id"]
-
# 查看特征值的前五列 X.head()
-
# 查看目标值的前五列 y.head()
-
# 分割数据集 x_train, x_test, y_train, y_test = \ train_test_split(X, y, test_size=0.2, random_state=2)
-
# 查看训练集有几行几列 x_train.shape
-
# 查看测试集有几行几列 x_test.shape
-
# 特征工程——标准化 transfer = StandardScaler() x_train = transfer.fit_transform(x_train) x_test = transfer.fit_transform(x_test)
-
# K近邻+网格搜索训练 # K近邻对象 knn = KNeighborsClassifier() # 网格搜索对象 estimator = GridSearchCV(knn, param_grid={"n_neighbors": [3, 5, 7, 9]}, cv=3, n_jobs=-1) # 模型训练 estimator.fit(x_train, y_train.values)
-
# 模型评估 estimator.score(x_test, y_test) estimator.best_score_ # 在交叉验证中验证的最好结果 estimator.cv_results_ # 每次交叉验证后的验证集准确率结果和训练集准确率结果
-
3.数据分割
3.1 数据划分
- 训练集 训练学习模型
- 验证集 在训练过程中,辅助评估训练的模型
- 测试集 训练结束后,最终对模型进行评估
3.2 留出法
“留出法”(hold-out)直接将数据集D划分为两个互斥的集合,其中一个集合作为训练集S,另一个作为测试集T
- api from sklearn.model_selection import train_test_split
3.3 交叉验证法
-
留一法
- 每次抽取一个样本做为测试集,其他样本作为训练集
- api from sklearn.model_selection import LeaveOneOut
-
K折交叉验证
将训练/测试数据集划分n_splits个互斥子集,每次用其中一个子集当作验证集,剩下的n_splits-1个作为训练集
- api from sklearn.model_selection import KFold,StratifiedKFold
- 区别 KFold 随机采样,StratifiedKFold 分层采样
- api from sklearn.model_selection import KFold,StratifiedKFold
3.4 自助法
-
自助法
有放回的抽样,约有 1/3 未被采样到的样本组成测试集
3.5 总结
- 当我们数据量足够时,选择留出法简单省时,在牺牲很小的准确度的情况下,换取计算的简便;
- 当我们的数据量较小时,我们应该选择交叉验证法,因为此时划分样本集将会使训练数据过少;
- 当我们的数据量特别少的时候,我们可以考虑留一法。
4. 线性回归介绍
4.1 定义
利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式
4.2 通用公式
4.3 按照自变量个数分类
- 单变量回归: 只有一个自变量(特征值)
- 多元回归: 有多个自变量
4.4 按线性回归模型与目标关系
- 线性关系
- 非线性关系
4.5 大白话
线性回归就是要求解线性方程中,每个特征对于预测的重要性,即:权重系数
5.API 使用
5.1 sklearn.linear_model.LinearRegression()
5.2 方法
- 训练: fit(x_train, y_train)
- 根据训练样本要每一个特征的权重系数,偏置 b
- 预测: predict(x_test)
- 根据已知的线性方程,将预测样本代入,计算出结果
5.3 属性
- 模型系数: coef_
6.线性回归的损失函数优化
6.1 损失
- 最小二乘法: (预测值-真实值)的平方求和
- 通过误差平方和来求解权重系数
6.2 优化
6.2.1 定义: 求解损失函数最小值
6.2.2 两种方式:
-
正规方程
- 缺点
- 计算量很大
- 当样本数量很大时候, 很难求解
- 缺点
-
梯度下降
-
梯度
- 如果是单变量, 这一点切线斜率
- 如果是多变量, 就是这个点偏导数,
- 是有方向的, 它方向就是函数上升最快的方向
-
关键点
- 梯度下降公式
-
- α: 学习率(步长). 不能太大 也 不能太小.
- 梯度乘以负号的原因: 梯度是上升最快的方向, 我们需要是下降最快的方向, 所以需要加 负号
-
梯度下降与正规方程对比
-
梯度下降 正规方程
- 需要选择学习率 不需要
- 迭代求解 一次求解
- 特征数量较大可用 需要计算方程, 时间复杂度很高, 求解很慢.
-
-
选择
- 小规模数据
- 正规方程: LinearRegression
- 岭回归: Ridge
- 大规模数据
- 梯度下降: SGDRegressor
- 小规模数据
7.梯度下降
- 全梯度下降算法(FGD)
- 每次迭代的时候, 都代入所有的样本计算损失求和求平均值, 作为目标函数
- 随机梯度下降算法(SGD)
- 每次迭代的时候, 只随机选择一个样本计算损失, 作为目标函数
- 小批量梯度下降算法(mini-bantch)
- 每次迭代的时候, 随机选择一个小批量的数据集, 使用FG对小批量的数据集进行梯度下降
- 随机平均梯度下降算法(SAG)
- 每次迭代的时候, 只随机选择一个样本计算损失, 每次计算梯度都存储在内存中, 在更新θ值时候, 求解所有梯度均值, 更新θ值.
- 结论(扩展)
- FG方法由于它每轮更新都要使用全体数据集,故花费的时间成本最多,内存存储最大。
- SAG在训练初期表现不佳,优化速度较慢。这是因为我们常将初始梯度设为0,而SAG每轮梯度更新都结合了上一轮梯度值。
- 综合考虑迭代次数和运行时间,SG表现性能都很好,能在训练初期快速摆脱初始梯度值,快速将平均损失函数降到很低。但要注意,在使用SG方法时要慎重选择步长,否则容易错过最优解。
- mini-batch结合了SG的“胆大”和FG的“心细”,从6幅图像来看,它的表现也正好居于SG和FG二者之间。在目前的机器学习领域,mini-batch是使用最多的梯度下降算法,正是因为它避开了FG运算效率低成本大和SG收敛效果不稳定的缺点
时候, 求解所有梯度均值, 更新θ值.
- 结论(扩展)
- FG方法由于它每轮更新都要使用全体数据集,故花费的时间成本最多,内存存储最大。
- SAG在训练初期表现不佳,优化速度较慢。这是因为我们常将初始梯度设为0,而SAG每轮梯度更新都结合了上一轮梯度值。
- 综合考虑迭代次数和运行时间,SG表现性能都很好,能在训练初期快速摆脱初始梯度值,快速将平均损失函数降到很低。但要注意,在使用SG方法时要慎重选择步长,否则容易错过最优解。
- mini-batch结合了SG的“胆大”和FG的“心细”,从6幅图像来看,它的表现也正好居于SG和FG二者之间。在目前的机器学习领域,mini-batch是使用最多的梯度下降算法,正是因为它避开了FG运算效率低成本大和SG收敛效果不稳定的缺点