分类:SVM、最近邻、随机森林、逻辑回归等。常用于垃圾邮件检测、图像识别。
回归:Lasso、岭回归等。常用于药物反应、股票价格。
聚类:k-means、谱聚类、均值偏移。常用于客户细分、分组实验结果。
降维:PCA、特征选择、矩阵分解等。常用于可视化、提高效率。
模型选择:网格搜索、交叉验证、指标矩阵等。通过参数调整来提高准确率。
预处理:特征提取、正态化等。转换输入数据以用于机器学习算法。
2. 分类监督学习:回归+分类
无监督学习:聚类
半监督学习:
3.流程1)数据加载
2)数据集划分:训练集和测试集
3)数据预处理
4)模型训练:使用训练集进行训练
5)模型评估:使用测试集进行评估
6)模型保存:保存训练好的模型
4.模型的评估与选择错误率:分类错误样本数/总样本数
精度:1-错误率
误差:模型输出与样本真实值之间的差异
训练误差(经验误差):模型在训练集上的误差
泛化误差:模型在新样本上误差
过拟合:用力过猛
欠拟合:用力不足
目的:得到泛化误差最小的模型,通常用训练误差来代替泛化误差,用模型的泛化误差进行评估。
4.1 评估方法- 留出法
训练集+测试集:互斥互补 。
训练集训练模型,测试集测试模型 。
合理划分、保持比例 。
单次留出与多次留出 。
多次留出法:如对专家样本随机进行100次训练集/测试集划分,评估结果取平均。
- 交叉验证法
k折交叉验证:
p次k折交叉验证:
- 自助法
留出法与交叉验证法的训练集数据少于样本数据
给定m个样本的数据集D,从D中有放回随机取m次数据,形成训练集D’
用D中不包含D’的样本作为测试集
D中某个样本不被抽到的概率:
测试集数据量:
缺点:改变了初始数据集的分布
4.2 性能度量 4.2.1 评价方法和评价标准回归任务的评价标准:均方误差
4.2.2 错误率与精度错误率:分类错误样本数/总样本数
精度:1-错误率,分类正确样本数/总样本数
4.2.3 查准率与查全率算法原理:算法对样本进行分类时,一般都会有置信度,即表示该样本是正样本的概率,比如99%的概率认为样本A是正例,1%的概率认为样本B是正例。通过选择合适的阈值,比如50%,对样本进行划分,概率大于50%的就认为是正例,小于50%的就是负例。通过置信度就可以对所有样本进行排序,再逐个样本的选择阈值,在该样本之前的都属于正例,该样本之后的都属于负例。每一个样本作为划分阈值时,都可以计算对应的precision和recall。
“1”代表正例,“0”代表反例。
查准率(也叫准确率,真正率)precision:P = TP/(TP+FP)
查全率(也叫召回率,灵敏度)recall:R = TP/(TP+FN)
正确率 = (TP+TN)/(TP+FN+FP+TN)
假正率 = FN/(FN+TN)
注意:查准率和查全率越接近1越好,假正率越接近0越好。
以下为混淆矩阵图:
查准率和查全率相互制约,不同场景有不同要求。
P-R曲线图:
EPR:曲线下的面积与平衡点
结果:模型A优于模型B;模型A优于模型C;模型B优于模型C.
注意:P-R图一般为非光滑非单调曲线。
F1系数:
单次训练:
综合查准率和查全率:
更一般的形式:
其中 β为正数,度量了查全率对查准率的相对重要性 。
β=1:标准的F1系数
β>1:查全率有更大影响
β<1:查准率有更大影响
多次训练/测试时的F1系数:
先分后总:先分别计算各混淆矩阵的查准率和查全率,再以均值汇总。
先总后分:先将各混淆矩阵的对应元素(TP、FP、TN、FN)进行汇总平均,再求P、R、F1值。
4.2.4 比较检验和偏差方差泛化误差可以分解为三个部分:
- 偏差:模型输出与真实值的偏离程度,刻画了算法的拟合能力。
- 方差:同样大小的训练集的变动导致的学习性能的变化,即数据扰动造成的影响。
- 噪声:表达了在当前任务上任何学习算法所能达到的期望泛化误差的下界, 即 刻画了学习问题本身的难度。
偏差大:拟合不足/欠拟合。方差大:过拟合。
5. 回归分析- Lasso回归
- 岭回归
- 线性回归
线性模型试图学得一个通过属性的线性组合来进行预测(目标属性)的函数
特点:
• 形式简单,易于建模
• 蕴含机器学习的基本思想
• 是其他非线性模型的基础
• 权重体现出各属性重要性,可解释性强
缺点:不适合用于复杂问题,容易欠拟合。
适用于:数据简单,高维稀疏矩阵。
1.对连续型数据做预测--线性回归
# 波士顿房价预测
# 1.数据加载
from sklearn.datasets import load_boston
boston = load_boston()
# 2.数据划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=0.2,
random_state=123 # 随机种子
)
# 3.数据预处理
import pandas as pd
pd.DataFrame(x_train).describe() # 描述性统计
# mms.data_max_ # 查看数据每一列的最大值
# mms.data_min_ # 查看数据每一列的最小值
#3.1 数据量纲差距太大。可通过数据标准化来缩小量纲。
#数据标准化:
#标准差标准化:(x - mean)/std
#最大最小标准化:(x - min)/(max - min)
mms = MinMaxScaler().fit(x_train)
x_train_mms = mms.transform(x_train)
#3.2 特征太多。==>降维
from sklearn.decomposition import PCA
pca = PCA(n_components=8).fit(x_train_mms)
x_train_pca = pca.transform(x_train_mms)
x_train_pca.shape
# pca.explained_variance_ratio_ # 查看可解释性方差率
# 4.模型构建(所有的线性模型都放在sklearn.linear_model)
from sklearn.linear_model import LinearRegression
#定义模型model
model2 = LinearRegression()
#学习参数
model2.fit(x_train_mms, y_train)
# 5.模型评估(所有的评估方法都放在sklearn.metrics)
from sklearn.metrics import mean_squared_error
mean_squared_error(y_train, model2.predict(x_train_mms))
model2.score(x_train_mms, y_train)# 通过coefficient of determination(决定系数),来判断回归方程拟合的程度
# 如果线性模型发生过拟合,可以通过剔除特征的方法进行修正:
#1.通过PCA等手段进行降维。
#2.Lasso回归进行特征规约。可对特征进行筛选,提取对应特征的权重不为0的特征,防止过拟合。
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=10)
lasso.fit(x_train, y_train)
lasso.coef_ #输出权重weight
lasso.intercept_#输出偏置bias
lasso.get_params()输出定义model时的参数,没有定义则返回默认参数
ps:随机数生成线性回归模型
# 生成数据 import numpy as np import matplotlib.pyplot as plt x = np.linspace(0, 10, 200) y = 3*x + 4 + np.random.random(200)*5 # 加上随机扰动,生成数据 plt.scatter(x, y) plt.show() from sklearn.linear_model import LinearRegression model = LinearRegression() # LinearRegression? model.fit(x.reshape((200,1)), y) plt.plot(x, x*model.coef_+model.intercept_, 'r') plt.scatter(x, y) plt.show() #模型评估 model.score(x[:, np.newaxis], y) # R2值 from sklearn.metrics import mean_squared_error mean_squared_error(y, model.predict(x[:, np.newaxis]))
2.线性模型做分类(二分类)--Logistics回归
案例1:乳腺癌
from sklearn.datasets import load_breast_cancer from sklearn.linear_model import LogisticRegression breast = load_breast_cancer() lr = LogisticRegression() lr.fit(breast['data'], breast['target']) lr.score(breast['data'], breast['target'])
案例2:通过分析不同的因素对研究生录取的影响来预测一个人是否会被录取。
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_score, recall_score, confusion_matrix
from sklearn.linear_model import LogisticRegression
# 1 数据读取
data = pd.read_csv(r'C:UserspcDesktopLogisticRegression.csv')
print(data.shape)
# 2 数据划分
x_train, x_test, y_train, y_test = train_test_split(
data.iloc[:, 1:], data['admit'], test_size=0.2
)
# 3 模型构建
model = LogisticRegression()
model.fit(x_train, y_train)
# 4 模型评估
y_pre = model.predict(x_test)
confusion_matrix(y_test, y_pre)
print('模型评估'.center(50, '='))
print(f'正确率:{model.score(x_test, y_test)*100:.2f}%')
print(f'查准率:{precision_score(y_test, y_pre)*100:.2f}%')
print(f'查全率:{recall_score(y_test, y_pre)*100:.2f}%')
6. 决策树
- 熵:不确定信息数量的衡量。不确定信息越多,熵值越大。
- 纯度:
当样本中有两项可以归为一类时,纯度为1。
当样本中没有两项可以归为一类时,纯度为0。
纯度度量:通过拆分最佳目标变量可以使得纯度最大化。如何拆分最佳目标变量,可以将其转化为拆分属性。衡量拆分目标变量的纯度度量包括:基尼CART、熵、信息增益ID3、信息增益率C4.5
- 信息增益:对纯度的提取程度。
其中,ID3算法只能处理离散型数据。其他算法可以出来连续型数据。
优点:
易理解
只需少量数据集
能同时处理连续和离散数据
能处理多输出问题
采用白盒模型
使用统计测试可以验证模型
即使假设点有错误也可以表现很好
缺点:
对大量样本生成复杂的树
可以创建复杂树但不能很好地推广
如果一些类占主导地位创建的树就有偏差
回归模型
#使用波士顿房价数据构建决策树回归模型
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
# 加载数据集
boston = load_boston()
x = boston['data']
y = boston['target']
# 数据划分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
# 模型构建
dtr = DecisionTreeRegressor(max_depth=10)
dtr.fit(x_train, y_train)
# 模型评估
print('决策树'.center(50, '='))
print('R方值:', dtr.score(x_test, y_test))
print('均方误差:', mean_squared_error(
y_test, dtr.predict(x_test)
))
print('线性回归'.center(50, '='))
from sklearn.linear_model import LinearRegression
lr = LinearRegression().fit(x_train, y_train)
print('R方值:', lr.score(x_test, y_test))
print('均方误差:', mean_squared_error(
y_test, lr.predict(x_test)
))
#模型选择使用交叉验证
from sklearn.model_selection import cross_validate
d = cross_validate(
LinearRegression(), x, y, cv=10,
scoring=['r2', 'explained_variance', 'neg_mean_squared_error']
)
import numpy as np
print(np.mean(d['test_r2']),np.mean(d['test_explained_variance']))
print(np.mean(d['test_neg_mean_squared_error']))
#线性回归的交叉验证
from sklearn.model_selection import cross_validate
d = cross_validate(
DecisionTreeRegressor(max_depth=10), x, y, cv=10,
scoring=['r2', 'explained_variance', 'neg_mean_squared_error']
)
import numpy as np
print(np.mean(d['test_r2']),np.mean(d['test_explained_variance']))
print(np.mean(d['test_neg_mean_squared_error']))
交叉验证的可填字符串:
分类模型
# 数据读取
import pandas as pd
titanic = pd.read_csv('../data/titanic_data.csv')
# 删除ID列
# del titanic['PassengerId']
titanic.drop('PassengerId', axis=1, inplace=True)
# 把性别转为数值型数据
# titanic.loc[titanic['Sex']=='male', 'Sex'] = 0
# titanic.loc[titanic['Sex']=='female', 'Sex'] = 1
titanic['Sex'] = titanic['Sex'].map({'male': 0, 'female': 1})
# 年龄字段缺失值处理
# 1 删除:在缺失值占比较小的情况下使用
# 2 填充:离散型数据--众数,连续型--平均数、中位数
# 3 插值:数据有规律
# titanic.describe()
titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())
# 划分数据集
x_train, x_test, y_train, y_test = train_test_split(
titanic.iloc[:, 1:], titanic['Survived'], test_size=0.2
)
# 分别构建线性模型(logistics回归)与决策树模型
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
lr = LogisticRegression()
dtc = DecisionTreeClassifier()
lr.fit(x_train, y_train)
dtc.fit(x_train, y_train)
# 模型评估: PR图、ROC图(AUC面积)
from sklearn.metrics import precision_recall_curve, roc_curve
y_pre_lr = lr.predict(x_test)
y_pre_dtc = dtc.predict(x_test)
precision, recall, thresholds = precision_recall_curve(y_test, y_pre_lr)
precision2, recall2, thresholds2 = precision_recall_curve(y_test, y_pre_dtc)
fpr, tpr, _ = roc_curve(y_test, y_pre_lr)
fpr2, tpr2, _ = roc_curve(y_test, y_pre_dtc)
# PR图
import matplotlib.pyplot as plt
plt.plot(precision, recall)
plt.plot(precision2, recall2)
plt.legend(['LogisticRegression', 'DecisionTreeClassifier'])
plt.title('precision_recall_curve')
plt.xlabel('precision')
plt.ylabel('recall')
plt.show()
# ROC图
import matplotlib.pyplot as plt
plt.step(fpr, tpr)
plt.step(fpr2, tpr2)
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.legend(['LogisticRegression', 'DecisionTreeClassifier'])
plt.title('ROC curve')
plt.xlabel('假正率')
plt.ylabel('真正率')
plt.show()



