机器学习 入门详细解析(二)决策树、随机森林
试图学得一个通过属性的线性组合来进行预测的函数:
f ( x ) = w 1 x 1 + w 2 x 2 + … + w d x d + b ; f(x)=w_1x_1+w_2x_2+…+w_dx_d+b; f(x)=w1x1+w2x2+…+wdxd+b;
注:w为权重,b称为偏置项,可以理解为:w_0×1
定义:线性回归通过一个或者多个自变量与因变量之间之间进行建模的回归分析。其中特点为一个或多个称为回归系数的模型参数的线性组合
一元线性回归:涉及到的变量只有一个
多元线性回归:涉及到的变量两个或两个以上
通用公式:
h ( w ) = w 0 + w 1 x 1 + w 2 x 2 + … = w T x ℎ(w)= w_0+w_1x_1+w_2x_2+…= w^Tx h(w)=w0+w1x1+w2x2+…=wTx
如何去求模型当中的W,使得损失最小?(目的是找到最小损失对应的W值)
求解:
w = ( X T X ) − 1 X T y w=(X^TX)^−1X^Ty w=(XTX)−1XTy
X为特征值矩阵,y为目标值矩阵
缺点:当特征过于复杂,求解速度太慢。 对于复杂的算法,不能使用正规方程求解(逻辑回归等)
我们以单变量中的w0,w1为例子:
sklearn.linear_model.LinearRegression #正规方程
sklearn.linear_model.SGDRegressor #梯度下降
sklearn.linear_model.LinearRegression()
# 普通最小二乘线性回归
# coef_:回归系数
sklearn.linear_model.SGDRegressor( )
# 通过使用SGD最小化线性模型
# coef_:回归系数
波士顿房价数据案例分析流程
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression,SGDRegressor,Ridge
import numpy as np
np.random.seed(1)
def mylinear():
# 获取数据
lb = load_boston()
# 分割数据
x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
print(y_train, y_test)
# 特征值标准化处理
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)
# 目标值标准化处理
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))
# 预测房价结果
model = joblib.load("./tmp/test.pkl")
y_predict = std_y.inverse_transform(model.predict(x_test))
print("保存的模型预测的结果:", y_predict)
if __name__ == "__main__":
mylinear()
sklearn 回归评估 API
sklearn.metrics.mean_squared_error
mean_squared_error(y_true, y_pred)
# 均方误差回归损失
# y_true:真实值
# y_pred:预测值
# return:浮点数结果
# 注:真实值,预测值为标准化之前的额值
**过拟合:**一个假设在训练数据上能够获得比其他假设更好的拟合, 但是在训练数据外的数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
**欠拟合:**一个假设在训练数据上不能获得更好的拟合, 但是在训练数据外的数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
解决方法
作用:可以使得W的每个元素都很小,都接近于0
优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
sklearn.linear_model.Ridge(alpha=1.0)
# 具有l2正则化的线性最小二乘法
# alpha:正则化力度
# coef_:回归系数
观察正则程度的变化,对结果的影响
线性回归 LinearRegression 与 Ridge 对比
# estimator预测
# 正规方程求解方式预测结果
lr = LinearRegression()
lr.fit(x_train, y_train)
print("系数:", lr.coef_)
# 保存好训练好的模型
joblib.dump(lr, "./tmp/test2.pkl")
# 预测测试集的房价
y_lr_predict = std_y.inverse_transform(lr.predict(x_test))
print("正规方程测试集里面每个房子的预测价格:", y_lr_predict)
print("正规方程的均方误差:", mean_squared_error(std_y.inverse_transform(y_test),y_lr_predict))
# 梯度下降求解方式预测结果
sgd = SGDRegressor()
sgd.fit(x_train, y_train)
print("梯度下降系数:", sgd.coef_)
# 梯度下降测试集的预测结果
y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test).reshape(-1, 1))
print("梯度下降测试集里面每个房子的预测价格:", y_sgd_predict)
print("梯度下降的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))
# 岭回归求解方式预测结果
rd = Ridge(alpha=1.0)
rd.fit(x_train, y_train)
print("岭回归系数:", rd.coef_)
# 梯度下降测试集的预测结果
y_rd_predict = std_y.inverse_transform(rd.predict(x_test).reshape(-1, 1))
print("岭回归测试集里面每个房子的预测价格:", y_rd_predict)
print("岭回归的均方误差:", mean_squared_error(std_y.inverse_transform(y_test), y_rd_predict))
逻辑回归是解决二分类问题的利器
sigmoid函数为:
sklearn.linear_model.LogisticRegression(penalty=‘l2’, C = 1.0)
# Logistic回归分类器
# coef_:回归系数
原始数据的下载地址:
https://archive.ics.uci.edu/ml/machine-learning-databases/
数据描述
(1)699条样本,共11列数据,第一列用语检索的id,后9列分别是与肿瘤
相关的医学特征,最后一列表示肿瘤类型的数值。
(2)包含16个缺失值,用”?”标出。
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():返回数据
代码实例
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
import pandas as pd
import numpy as np
def logistic():
"""
逻辑回归做二分类进行癌症预测(根据细胞的属性特征)
:return: NOne
"""
# 构造列标签名字 名字自定,但是数目要一致
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']
# 读取数据
data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data", names=column)
print(data)
# 缺失值进行处理
data = data.replace(to_replace='?', value=np.nan)
data = data.dropna()
# 进行数据的分割
x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]], data[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)
lg.fit(x_train, y_train)
print(lg.coef_)
y_predict = lg.predict(x_test)
print("准确率:", lg.score(x_test, y_test))
print("召回率:", classification_report(y_test, y_predict, labels=[2, 4], target_names=["良性", "恶性"]))
return None
if __name__ == "__main__":
logistic()
结果为:
[[1.20978993 0.2487854 0.63901048 0.73015212 0.39714288 1.40510768
0.97045854 0.40176488 0.80020768]]
准确率: 0.9707602339181286
召回率: precision recall f1-score support
良性 0.97 0.99 0.98 114
恶性 0.98 0.93 0.95 57
accuracy 0.97 171
macro avg 0.97 0.96 0.97 171
weighted avg 0.97 0.97 0.97 171
sklearn.cluster.KMeans(n_clusters=8,init=‘k-means++’)
# k-means聚类
# n_clusters:开始的聚类中心数量
# init:初始化方法,默认为'k-means ++’
# labels_:默认标记的类型,可以和真实值比较(不是值比较)
轮廓系数:
$$
计算公式:_= (_− _)/(max(_ ,_))
$$
注:对于每个点i 为已聚类数据中的样本 ,b_i 为i 到其它族群的所有样本的平均距离,a_i 为i 到本身簇的距离平均值最终计算出所有的样本点的轮廓系数平均值
如果〖〗_ 小于0,说明_ 的平均距离大于最近的其他簇。
聚类效果不好
如果〖〗_ 越大,说明_ 的平均距离小于最近的其他簇。
聚类效果好
轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优
sklearn.metrics.silhouette_score(X, labels)
计算所有样本的平均轮廓系数
X:特征值
labels:被聚类标记的目标值
特点分析: 采用迭代式算法,直观易懂并且非常实用
缺点:容易收敛到局部最优解(多次聚类),需要预先设定簇的数量(k-means++解决)