Python_ML-Day03: 线性回归、岭回归、逻辑回归、k-means 1. 回归问题的判定 - 目标值是一个连续的值 - 寻找一种能预测的趋势 - 线性关系的函数: y = kx + b - b 偏置 2. 线性关系模型 - 一个通过属性xn 的线性组合来进行预测的函数 - 线性回归通过一个或者多个 特征值x1,x2 与 目标值f(x) 之间进行建模的回归分析 - f(x) = w0 + w1*x1 + w2*x2 + w3*x3 - f(x) = W * X - W:[w0,w1,w2,w3] 矩阵 - X:[1,x1,x2,x3] 矩阵 3. 损失函数[误差大小] - 误差的平方和 - 最小二乘法 - f(&) = (h(x1) - y1)^2 + (h(x2) - y2)^2 + ... + (h(xn) - yn)^2 - h(xn): 第n个样本预测值 - yn: 第n个样本的真实值,目标值 4. 求解W权重矩阵的方式 - 最小二乘法之正规方程 1. w = (X`t * X)^-1 * X`t * Y - X: 特征值矩阵 - X`t: 特征值矩阵的逆矩阵 - Y:目标值矩阵 2. 直接能求出最小损失下的w权重矩阵 3. 缺点 - 当特征值过于复杂,求解速度太慢,甚至无法求解 4. sklearn.linear_model.LinearRegression() 5. 返回 coef_: 回归系数w - 最小二乘法的梯度下降 0. 公式 w1 = -w1 - & * k w2 = -w2 - & * k 1. 学习速率 & 2. 梯度下降方向k,根据公式计算 k = cos(w0 + w1x1) / w1 3. 理解: 随机一个w初始值,然后沿着这个函数下降的方向去查找最小值,每次迭代都更新W的值,直到W最小 4. 适用 训练数据规模非常庞大的场景 5. sklearn.linear_model.SGDRegerssion() 6. 返回 coef_: 回归系数w 5. 房价预测案列分析 - 获取 房价数据 - 房价数据 分割 - 数据标准化 - 公式中涉及到 不同特征值之间相加,相减等操作,就需要标准化。比如一个是10000,一个是0.0001,怎么相加? - 使用正规方程和梯度下降进行线性回归模型预测 6. 回归性能评估 - 均方误差 1. 均方误差评价机制 - MSE = [(y1 - `y1)^2 + (y2 - `y2)^2 + ... +(ym - `ym)^2] / m - y1,y2,y3: 预测值 - `y1, `y2, `y3 真实值 2. 均方误差回归损失 metrics.mean_squard_error(y_true, y_pred) - y_true 真实值 - y_pred 预测值 - 返回: 浮点数的结果 - 注意: 此处的预测值和真实值均为 标准化之前的值。如果数据已经标注化,要进行inverse_transform - 对数似然损失函数 - 逻辑回归评估 1. 对数似然损失函数 - 如果预测结果为1 if y = 1, cos(h) = -log(h(x)) - 如果预测结果为0 if y = 0, cos(h) = -log(1 - h(x)) - cos(h) 越小,那么预测的准确度越高 - h(x): 预测概率值 - 目标值是1 类,预测为1 类的概率 2. 使用梯度下降,去更新权重,从而降低损失函数的值 - 怎么保证梯度下降最低点的最低? - 多次随机初始化,选择多个起始点,去执行梯度下降,每个起始点都应一个最低点,在这些最低点中选择一个最最低的 - 求解过程中,调整学习率 - 注意: 上面两种解决办法,不能100% 找到全局最低点,但是效果也很好 7. 正规方程和梯度下降的对比 梯度下降 正规方程 需要选择学习率 & 不需要 需要多次迭代 一次运算得出结果 特征数量很大,适用 特征数量很大,运算代价大,大于10000不建议 适用各种类型的预测 只适用线性模型 8. 欠拟合 和 过拟合 - 欠拟合 1. 学习的不足,模型不能很好的表述特征值 2. 数学表现为 训练误差大,并且测试误差也大 3. 特点: 模型过于简单 4. 原因: 学习到的特征过少 5. 解决: 增加数据的特征数量 - 过拟合 0. 普通线性回归很容易过拟合 1. 学习的太充足了,以至于有一些本属于类别的也被排除了 2. 数学表现为 训练误差小,但是测试误差大 3. 特点是: 模型过于复杂,比如决策树 4. 原因: 原始特征过于多。存在一些嘈杂特征。 模型要尝试去兼顾所有的测试点,往往导致模型复杂 5. 解决: - 特征选择: 消除关联性很大的特征(很难做) - 交叉验证: 让所有的数据都能训练到 - 正则化:L2正则化:岭回归 9.正则化 - px = w1 * x1 + w2 * x2^2 + w3 * x3^3 + w4 * x4^4 ... - 随机去减小 特征值x的权重系数 w1,w2,w3,w4 的值, 直到其慢慢为0 - 然后去查找 变化最大的那些系数,然后去掉这些系数对应的特征值 - 如公式的 w3, w4 对用的4次方,肯定影响很大,拟合的是一个锯齿曲线, 而让w3,w4 = 0 , 则锯齿消失,变成平滑的曲线 10.Ridge 岭回归: 带有正则化的线性回归 - sklearn.linear_model.Ridge(alpha = 1.0) - 具有L2正则化的线性最小二乘法回归 - alpha:正则化力度,超参数 - coef_: 回归系数 - alpha 正则化力度越大,权重越趋近于0,模型越简单,取值 0-1, 1-10 - 优点 0.解决过拟合 1.回归得到的回归系数更符合实际,更加可靠 2.能让估计参数的波动范围变小,变得更稳定。模型稳定且简单 3.在存在病态数据,嘈杂数据较多的数据中,有较大的实用价值 11.模型的保存与加载 - 保存与加载模型 1. from sklearn.externals import joblib 2. joblib.dump(estimator, 'D:/model.pkl') 3. estimator = joblib.load('D:/model.pkl') 12.分类算法 - 逻辑回归 - 用回归的算法去解决分类问题 - 将回归的问题转换成分类的算法去求解 - 解决二分类问题的利器 1.广告点击率 2.是否为垃圾邮件 3.是否患病 4.金融诈骗 5.虚假账号 - sigmoid 函数 1.将连续性的函数,转换成离散的点,并且点的y值介于[0-1] 2.[0-1] 恰恰符合了概率的范围 3.这个函数就将线性回归的输入转换成分类问题的概率值 4.g(z) = 1/[1 + e ^(-z)] 5.g(z): 作为函数的输出,表现为[0-1]之间的概率值 6.e的(-z)次幂: 中的z 表示回归算法的结果,作为函数的输入 7.如果z=0,g(z) = 0.5 作为阈值,比如,大于0.5 = 1,小于0.5 = 0,就输出了二分类 - 逻辑回归的评估 - 对数似然损失函数 1. 对数似然损失函数 - 如果预测结果为1 if y = 1, cos(h) = -log(h(x)) - 如果预测结果为0 if y = 0, cos(h) = -log(1 - h(x)) - cos(h) 越小,那么预测的准确度越高 - h(x): 预测概率值 - 目标值是1 类,预测为1 类的概率 - LogisticRegression 回归分类器 1. sklearn.linear_model.LogisticRegression(penalty='l2',C=1.0) 2. penalty: 正则化 默认l2 正则化 3. C:正则化力度,超参数 4. coef_: 回归系数 - 解决过拟合 - 案例分析: 1.原始数据的下载地址: - https://archive.ics.uci.edu/ml/machine-learning-databases/ 2.数据描述 - 699条样本,共11列数据,第一列用语检索的id,后9列分别是与肿瘤 相关的医学特征,最后一列表示肿瘤类型的数值。 - 包含16个缺失值,用”?”标出。 3.正例: 哪个类别少,判断概率值 (= 1) 的就是哪个 4.pd.read_csv(’’,names=column_names) column_names:指定类别名字,['Sample code number','Clump Thickness', 'Uniformity of Cell Size','Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size','Bare Nuclei','Bland Chromatin','Normal Nucleoli','Mitoses','Class'] return:数据 replace(to_replace=’’,value=):返回数据 dropna():返回数据 5.流程 - 网上获取数据(工具pandas) - 数据缺失值处理、标准化 - LogisticRegression估计器 - 应用场景 广告点击率预测、电商购物搭配推荐 - 优点 适合需要得到一个分类概率的场景 - 缺点 当特征空间很大时,逻辑回归的性能不是很好(看硬件能力) 只能解决二分类 13.判别模型与生成模型 - 看是否有先验概率P(c) 1.有,生成模型: K近邻,决策树,随机森林,神经网络等 2.五,判别模型: 朴素贝叶斯 - 先验概率P(c) 1. 需要通过历史数据去统计计算出来的一些概率值 14.非监督学习 - 聚类 k-means, 在预测分类之前 - k: 把数据划分成多少个类别 - 划分步骤 k=3 1.在数据中,随机抽取三个样本,当做三个类别的中心点k1,k2,k3 2.分别计算其余的点到 k1,k2,k3的距离,得到其余的每个点到三个点的距离(a,b,c) 3.距离哪个中心点(k1,k2,k3)近(a,b,c中值最小),就将这个点划分到哪个类中。 4.从而形成三个族群 5.分别计算三个族群的平均值(中心点),作为新的中心点k1,k2,k3 6.然后与旧的中心点进行比较 7.如果新的中心点与旧的中心点全部重合,则聚类结束 如果不同,那么使用新的中心点,继续重复以上步骤 直到新旧中心点全部重合 - sklearn.cluster.KMeans(n_cluster=8,init='k-means++') 1. n_cluster: 开始聚类中心的数量 k 2. init: 初始化方法。默认为k-means++ - 案例分析Instacart Market - k-means 的评估指标 1. 轮廓系数[-1,1],越靠近1 聚类效果越好,一般 0, 0.1 就还可以了 - 计算公式:sc = bi - ai / max(bi,ai) - 点i:数据集中的每一个点 - bi: 点i 到其他族群所有样本点的距离的最小值 - ai: 点i 到自身族群所有样本点的距离的平均值 - 最好:外部距离最大化,内部距离最小化(bi 远远大于ai, sc = 1) - 最差的情况: ai 远远大于bi, sc = -1 - 计算所有样本的平均轮廓系数: sklearn.metrics.silhouette_score(X, labels) - X:样本集 - labels:目标值[预测的结果] - 源码 def kmains(): # 读取四张表的数据 prior = pd.read_csv("./KaggleData/order_products__prior.csv") products = pd.read_csv("./KaggleData/products.csv") orders = pd.read_csv("./KaggleData/orders.csv") aisles = pd.read_csv("./KaggleData/aisles.csv") # 合并4张表到一张表 _mg = pd.merge(prior, products, on=['product_id', 'product_id']) _mg = pd.merge(_mg, orders, on=['order_id', 'order_id']) mt = pd.merge(_mg, aisles, on=['aisle_id', 'aisle_id']) mt.head(10) # 交叉表 -- 特殊的分组工具 cross = pd.crosstab(mt['user_id'], mt['aisle']) # 进行主成分分析,进行降维操作 pca = PCA(n_components=0.9) data = pca.fit_transform(cross) # k-means k=4 假设分为4个类别 from sklearn.cluster import KMeans # 把样本数量减少 x = data[:500] x.shape km = KMeans(n_clusters=4) km.fit(x) pre = km.predict(x) print(pre) import matplotlib.pyplot as plt plt.figure(figsize=(10, 10)) # 建立4个颜色的列表 colord = ['orange', 'green', 'blue', 'red'] colr = [colord[i] for i in pre] plt.scatter(x[:, 1], x[:, 20], color=colr) plt.show() # 评判聚类效果 - 轮廓系数 sc = silhouette_score(x, pre) print(sc) 15.源码 from sklearn.datasets import load_boston from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error, classification_report from sklearn.externals import joblib import pandas as pd import numpy as np def linear(lr): """ 线性回归 :param lr: 回归器 :return: """ # 加载数据 dt = load_boston() x = dt.data y = dt.target # 分割数据 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25) # 标准化 - 注意,特征值和目标值都要标准化,而且 特征值和目标值的StandScalar 不能是同一个 # 因为 两个的数据不同 sd = StandardScaler() x_train = sd.fit_transform(x_train) x_test = sd.transform(x_test) sd = StandardScaler() y_train = sd.fit_transform(y_train.reshape(-1, 1)) y_test = sd.transform(y_test.reshape(-1, 1)) # 使用线性回归算法 lr.fit(x_train, y_train) y_pre = lr.predict(x_test) y_pre = sd.inverse_transform(y_pre) # 使用 均方误差回归损失 评估模型 y_pre_true = sd.inverse_transform(y_test) mean = mean_squared_error(y_pre_true, y_pre) # print("回归系数:", lr.coef_) print("预测房价1:", y_pre) # print("均方误差", mean) # 模型的保存与加载 joblib.dump(lr, 'D:/model.pkl') model = joblib.load('D:/model.pkl') y_pre = model.predict(x_test) print("预测房价2:", sd.inverse_transform(y_pre)) def logisticRegression(): """ 逻辑回归做二分类预测 :return: """ # 读取数据 column = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class'] dt = pd.read_csv( "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column) print(dt) # 缺失值替换以及删除 dt = dt.replace(to_replace='?', value=np.nan) dt = dt.dropna() # 数据分割 x_train, x_test, y_train, y_test = train_test_split(dt[column[1:10]], dt[column[10]], test_size=0.25) # 标准化 std = StandardScaler() x_train = std.fit_transform(x_train) x_test = std.transform(x_test) # 逻辑回归预测 lg = LogisticRegression(C=1.0, penalty='l2') lg.fit(x_train, y_train) pre = lg.predict(x_test) print("w权重系数:", lg.coef_) print("准确率:", lg.score(x_test, y_test)) print("召回率:", classification_report(y_test, pre, labels=[2, 4], target_names=["良性", "恶性"])) if __name__ == '__main__': # # 普通线性回归 # linear(LinearRegression()) # # 梯度下降线性回归 # linear(SGDRegressor()) # l2正则化的线性回归-岭回归 # linear(Ridge(alpha=1.0)) logisticRegression()