机器学习基本概念
名词解释
-
样本集:一般就是一个表格数据 ,我们研究数据的集合,每一列就是样本的一条属性,每一行就是一个数据样本
-
样本标签:我们要研究的数据指标, 可能是数据的一条属性
-
训练集:从样本集中,拆分出来的一部分样本,样本个数多 8:2 9:1 7:3,用来训练算法模型的数据集合
-
测试集:从样本集中,拆分出来的一部分样本,样本个数少 8:2 9:1 7:3,用来测试模型学习效果的集合
-
算法模型:我们选择一个算法对象 .fit()训练的函数 .predidct()预测的函数
-
表示方法
- 样本集:samples train 标准的二维数组
训练集:X_train
测试集:X_test - 样本标签:target y
训练集标签:y_train
测试集标签:y_test - 预测结果:y_
- 样本集:samples train 标准的二维数组
-
有监督学习:样本集、测试集、训练集都有对应的标签
- 分类(预测男女):样本标签一般是离散值(A\B、红黄蓝、男\女)
- KNN Logistic SVC 决策树…
- 回归(房价预测):样本标签一般是连续值(1.2,1.5,1.8.2.3.2.6)在一个数据区间的任意取值
- LinearRegression、SVR、Ridge、Lasso
- 分类(预测男女):样本标签一般是离散值(A\B、红黄蓝、男\女)
-
无监督学习:样本集、测试集、训练集都没有有对应的标签
-
聚类 :KMeans
-
半监督学习:
-
深度学习
-
特征空间:由样本集的特征,展开的空间,称为特征空间。所有的样本都属于这个特征空间
-
过拟合:,当学习器把训练样本学得"太好"了的时候,很可能巳经把训练样本自身的一些特点当作了所有潜在样本都 会具有的一般性质,这样就会导致泛化性能下降这种现象在机器学习中称为
“过拟合” (overfitting).
-
欠拟合:对数据学习的太简陋,没有学习到共性特征,导致模型的泛化能力变弱。
-
经验误差:学习器的实际预测输出与样本的真实输出之间的差异称为"误差" (error), 学习器在训练集上的误差称为"训练误差" (training error) 或"经验误差" (empirical error)
-
泛化误差:在新样本上的误差称为"泛化误差" (generalization
error).
-
鲁棒性:Huber从稳健统计的角度系统地给出了鲁棒性3个层面的概念:
- 模型具有较高的精度或有效性,这也是对于机器学习中所有学习模型的基本要求;
- 对于模型假设出现的较小偏差,只能对算法性能产生较小的影响; 主要是:噪声(noise)
- 对于模型假设出现的较大偏差,不可对算法性能产生“灾难性”的影响;主要是:离群点(outlier)
k-近邻算法(kNN)
原理
简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。
- 优点:精度高、对异常值不敏感、无数据输入假定。
- 缺点:时间复杂度高、空间复杂度高。
- 适用数据范围:数值型和标称型。
k近邻(k Nearest eighbo ,简称 kNN )学习是一种常用的监督学习 方法, 其工作机制非常简单 给定测试样本,基于某种距离度量找出 练集中 与其最 靠近的k 个训练样本,然后基于这 个k"邻居 “的信息来进行预测 在分 类任务中可使用"投票法” 即选择这 k个样本中出现最多的类别标记作为预 测结果;在回归任务中时使用"平均法" ,即将 k个样本的实值输出标记 平均值作为预测结果;还可基于距离远近进行加权平均或加权投票,距离越近 的样本权重越大.
- 欧几里得距离(Euclidean Distance)
欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:
在scikit-learn库中使用k-近邻算法,用于分类
-
用途:对离散型的数据进行分类
-
分类问题:from sklearn.neighbors import KNeighborsClassifier
电影案例分析
#导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from pandas import Series,DataFrame
#读取xlsx文件
train = pd.read_excel('film.xlsx')[0:9] ==>
电影名称 爱情 动作 电影类别
0 大话西游 3.0 9.0 动作
1 星语心愿 10.0 2.0 爱情
2 叶问 2.0 11.0 动作
3 黄飞鸿 2.0 9.0 动作
4 最好的我们 11.0 3.0 爱情
#删除不关联的特征
train.drop(labels=["电影名称"],axis=1, inplace=True)
# 获取样本集和标签
# 标签
y = train["电影类别"]
# 样本集
X = train[["爱情","动作"]]
#绘制样本特征之间的散点图(图一)
X1 = X[y == "动作"]
X2 = X[y == "爱情"]
plt.scatter(X1["爱情"],X1["动作"], label="ACTION FILM", color="green")
plt.scatter(X2["爱情"],X2["动作"], label="LOVE FILM", color="black")
plt.xlabel("LOVE")
plt.ylabel("ACTION")
plt.legend()
# 1、构建一个算法模型,本案例适合分类模型
from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressor
## k必须是一个奇数
# 经验值:不要超过样本个数的平方根
knnclf = KNeighborsClassifier(n_neighbors=5)
#2、训练模型
# 有监督学习的fit函数,都接收两个参数,X 样本集 应该保证 样本分布比较均匀,y 样本标签
knnclf.fit(X, y)
#3、预测
#(1),对样本集(学习过的)预测 经验误差(回归模型)
# (2),对未知(没学习过的)数据预测 泛化误差(回归模型)
y_ = knnclf.predict(X) ==>
array(['动作', '爱情', '动作', '动作', '爱情', '爱情', '动作', '爱情', '动作'], dtype=object)
# 4、准确率 求得的是在训练集上的准确率
accuracy_rate = (y == y_).sum()/y.size
#泛化数据的预测绘图(图二)
# 【注意】要使用二维数组作为测试数据
X_test = np.array([[5,8],[11,5]])
plt.scatter(X_test[:,0], X_test[:,1], label="Predict", color="orange")
plt.legend()
# 预测函数中,只接收测试集,不接收标签
knnclf.predict(X_test) ==>
array(['动作', '爱情'], dtype=object)
图一
图二
系统现有数据:鸢尾花的品种分析
# 导入系统中的数据
from sklearn.datasets import load_iris
#1、获取样本集和标签
iris = load_iris()
data = iris.data
target = iris.target
target_names = iris.target_names
feature_names = iris.feature_names
df = DataFrame(data=data, columns=feature_names)
df.shape ==>(150, 4)
# 样本集
train = data
# 样本标签
target = target
#2、均匀的拆分训练集和测试集
from sklearn.model_selection import train_test_split
# random_state 随机数种子 种子固定,随机数就固定
# 如果设定random_state,每一次分割的样本集都一样,这样可以横向比较不同算法的效果好坏
# 如果不设定random_state,每一次分割的样本集都不一样,这样可以多次训练和预测同一个模型,来查看该模型的综合效果
#封装函数得到训练集和测试集的平均得分
#准确率只能用在分类模型的评价上
def knn_score(k):
# 记录测试机评分
scores = []
# 记录训练集的评分
scores1 = []
for _ in range(100):
X_train,X_test,y_train,y_test = train_test_split(train, target, test_size=0.2)
knn = KNeighborsClassifier(n_neighbors=k)
# 训练集进行训练
knn.fit(X_train, y_train)
# 测试集进行预测
y_ = knn.predict(X_test
# 训练集进行预测
y1_ = knn.predict(X_train)
scores.append((y_ == y_test).sum()/y_.size)
scores1.append((y1_ == y_train).sum()/y1_.size)
# print("测试集得分:%.3f, 训练集得分:%.3f"%(np.array(scores).mean(), np.array(scores1).mean()))
return (np.array(scores).mean(), np.array(scores1).mean())
#3、测试不同的k值对平均值的影响
ks = np.arange(3,13,step=2)
train_scores = []
test_scores = []
# 训练集得分和测试集得分越相近越好
for k in ks:
print(k)
train_s, test_s = knn_score(k)
train_scores.append(train_s)
test_scores.append(test_s)
# 绘制k值和平均准确率的关系图(图三)
# 根据图像,发现当k=3时候,经验误差和泛化误差最接近,说明此时算法模型表现最好
plt.plot(ks, np.array(train_scores),color="green", label="train_scores")
plt.plot(ks, np.array(test_scores), color="black", label="test_scores")
plt.legend()
图三
定义KNN分类
# 获取样本空间所有点,绘出背景色
xmin, xmax = train[:,0].min(), train[:,0].max()
ymin, ymax = train[:,1].min(), train[:,1].max()
x = np.linspace(xmin, xmax, 100)
y = np.linspace(ymin, ymax, 100)
#使用meshgrid对一维数据升维,变为(100,100)
xx, yy = np.meshgrid(x, y)
X_test = np.concatenate((xx.reshape(-1,1), yy.reshape(-1,1)),axis=1)
# 选择算法模型,进行训练
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(train, target)
#得到样本空间所有点的标签
y_ = knn.predict(X_test)
#绘出分类图
from matplotlib.colors import ListedColormap
plt.scatter(X_test[:,0], X_test[:,1],c = y_, cmap = ListedColormap(np.random.random(size=(3,3))))
plt.scatter(train[:,0], train[:,1], c = target, cmap=cmap)
- 总结:
- 样本集要拆分的均匀,不影响预测结果
- 模型应该多次预测取均值,更能说明模型的综合能力
- 经验误差和泛化误差应尽量接近,算法的泛化能力才更强
- 算法稳定性可以多次训练预测模型,看评分的标准方差,越小说明算法越稳定(受数据的影响波动不大)
KNN算法用于回归
- 用途:回归用于对趋势的预测
- 回归问题:from sklearn.neighbors import KNeighborsRegressor
- 用正弦函数作为分析案例
# 1、生成样本数据
X = np.linspace(0,2*np.pi,60)
y = np.sin(X)
#对标签加上适当的噪音 模拟现实数据
noise = np.random.random(size=30)*0.4 - 0.2
y[::2] += noise
plt.scatter(X, y)
# 2、生成测试数据的结果
from sklearn.neighbors import KNeighborsRegressor(解决回归问题)
knn = KNeighborsRegressor()
knn.fit(X.reshape(-1,1), y)
X_test = np.linspace(0,np.pi*2,52)
y_ = knn.predict(X_test.reshape(-1,1))
#3、绘制真实值和回归模型的分布图
plt.plot(X_test, y_, color="green",label="PREDICT")
plt.scatter(X, y, color="black", label="TRUE")
plt.legend()
#4、使用不同的k值训练相同的数据,观察不同的结果
knn1 = KNeighborsRegressor(n_neighbors=1)
knn2 = KNeighborsRegressor(n_neighbors=5)
knn3 = KNeighborsRegressor(n_neighbors=15)
X = X.reshape(-1,1)
#分别训练
knn1.fit(X,y)
knn2.fit(X,y)
knn3.fit(X,y)
#得到测试标签
X_test = X_test.reshape(-1,1)
y1 = knn1.predict(X_test)
y2 = knn2.predict(X_test)
y3 = knn3.predict(X_test)
#5、绘制三种k值的图像,进行比较
plt.figure(figsize=(16,4))
ax1 = plt.subplot(1,3,1)
#k=1
ax1.set_title("K=1")
plt.plot(X_test, y1, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")
ax2 = plt.subplot(1,3,2)
#k=5
ax2.set_title("K=5")
plt.plot(X_test, y2, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")
ax3 = plt.subplot(1,3,3)
#k=15
ax3.set_title("K=15")
plt.plot(X_test, y3, color="green", label="Predict")
plt.scatter(X, y, color="black", label="TRUE")
#结论:当k=5时经验误差和泛化误差都相对较小
线性回归
- 先复习一下大学的函数的导数及运算
① C’=0(C为常数);
② (xn)’=nx(n-1) (n∈Q);
③ (sinx)’=cosx;
④ (cosx)’=-sinx;
⑤ (ex)’=ex;
⑥ (ax)’=axIna (ln为自然对数)
⑦ loga(x)’=(1/x)loga(e) - 导数的运算
①(u±v)’=u’±v’
②(uv)’=u’v+uv’
③(u/v)’=(u’v-uv’)/ v^2
④[u(v)]’=[u’(v)]*v’ (u(v)为复合函数f[g(x)]) - 最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。
注: xT 表示的是向量
- 矩阵的阶:一个m行n列的矩阵简称为mn矩阵,特别把一个nn的矩阵成为n阶正方阵,或者n阶矩阵
- 矩阵的秩:用初等行变换将矩阵A化为阶梯形矩阵, 则矩阵中非零行的个数就定义为这个矩阵的秩, 记为r(A)
- 满秩矩阵:满秩矩阵(non-singular matrix): 设A是n阶矩阵, 若r(A) = n, 则称A为满秩矩阵。但满秩不局限于n阶矩阵。若矩阵秩等于行数,称为行满秩;若矩阵秩等于列数,称为列满秩。既是行满秩又是列满秩则为n阶矩阵即n阶方阵。行满秩矩阵就是行向量线性无关,列满秩矩阵就是列向量线性无关;所以如果是方阵,行满秩矩阵与列满秩矩阵是等价的。满秩有行满秩和列满秩,既是行满秩又是列满秩的话就一定是是方阵
- 奇异矩阵:奇异矩阵是线性代数的概念,就是该矩阵的秩不是满秩。首先,看这个矩阵是不是方阵(即行数和列数相等的矩阵。若行数和列数不相等,那就谈不上奇异矩阵和非奇异矩阵)
#计算矩阵的秩
a = np.array([[3,3.5,2],[3.2,3.6,3],[6,7,4]])
np.linalg.matrix_rank(a)
- 矩阵求逆:AA-¹=A-¹A=E(单位矩阵)
- 逆矩阵的作用:逆矩阵是经常遇到的一个概念。教科书中讲解了逆矩阵的求法,但是没有说清楚为何需要逆矩阵,逆矩阵的意义是什么。逆矩阵可以类比成数字的倒数,比如数字5的倒数是1/5,矩阵A的“倒数”是A的逆矩阵。5*(1/5)=1, A*(A的逆矩阵) = I,I是单位矩阵。引入逆矩阵的原因之一是用来实现矩阵的除法。比如有矩阵X,A,B,其中XA = B,我们要求X矩阵的值。本能来说,我们只需要将B/A就可以得到X矩阵了。但是对于矩阵来说,不存在直接相除的概念。我们需要借助逆矩阵,间接实现矩阵的除法。具体的做法是等式两边在相同位置同时乘以矩阵A的逆矩阵,如下所示,XA*(A的逆矩阵)= B*(A的逆矩阵)。由于A*(A的逆矩阵) = I,即单位矩阵,任何矩阵乘以单位矩阵的结果都是其本身。所以,我们可以得到X = B*(A的逆矩阵)。
#numpy求逆矩阵
a_ = np.linalg.inv(a)
- 求算法的系数和截距
# 算法的系数
lr.coef_
# 截距
lr.intercept_
【普通线性回归求解过程】
- 求解的过程 f(x) = WX + b
- 普通线性回归、Ridge、Loasso又叫 狭义线性回归
- 确定一个估计函数 f(x) = WX
- 带入数据,构造一个损失函数cost (y-y’)**2
- 对损失函数求最优解 对w求导数等于0
- 如果有截距,就是用梯度下降法求最优解
普通线性回归LinearRegression(狭义线性回归
)
- 原理:分类的目标变量是标称型数据,而回归将会对连续型的数据做出预测。
- 适用场景:一般来说,只要我们觉得数据有线性关系,LinearRegression类是我们的首先。如果发现拟合或者预测的不好,再考虑用其他的线性回归库。如果是学习线性回归,推荐先从这个类开始第一步的研究。
接下来就以糖尿病数据做线性回归分析
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
#1、获取数据
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
# 样本集
data = diabetes.data
# 样本标签
target = diabetes.target
#简便写法(直接获取样本集和样本标签)
# X, y = load_diabetes(return_X_y=True)
#2、抽取训练数据和预测数据
#创建数学模型
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
#分割样本集得到训练集合测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=1)
#训练
lr.fit(X_train, y_train)
#预测
y_ = lr.predict(X_test)
#3、绘制残差图
# 一般使用损失来评价回归模型
# 可以使用残差直方图来观察数据的预测结果
errs = (y_ - y_test)
plt.hist(errs, bins=10)
# 4、线性回归和Knn回归算法比较(通过绘图)
from sklearn.neighbors import KNeighborsRegressor
#计算KNN算法误差
knn = KNeighborsRegressor()
knn.fit(X_train, y_train)
y1_ = knn.predict(X_test)
errs1 = (y1_ - y_test)
errs = (y_ - y_test)
#绘图
plt.hist(errs, bins=10, label="Lieaner",alpha=0.5, color="y")
plt.hist(errs1, bins=10, label="KNN",alpha=0.5, color="m")
plt.legend()
# 5、均方误差MSE来比较回归模型的好坏
from sklearn.metrics import mean_squared_error
# mean_squared_error传入两个参数:真值和预测值
lr_score = mean_squared_error(y_test, y_)
knn_score = mean_squared_error(y_test, y1_)
# 误差越小越好 这里LR优于KNN
print(lr_score, knn_score) ==>
2992.55768145 3957.18292135
LinearRegression残差图
KNN和LinearRegression比较
- 单独查看某一个特征对结果的影响
feature_names = diabetes.feature_names
df = DataFrame(data=data, columns=feature_names) ==>
age sex bmi bp s1 s2 s3 s4 s5 s6
0 0.038076 0.050680 0.061696 0.021872 -0.044223 -0.034821 -0.043401 -0.002592 0.019908 -0.017646
1 -0.001882 -0.044642 -0.051474 -0.026328 -0.008449 -0.019163 0.074412 -0.039493 -0.068330 -0.092204
#这里研究BMI(体重指数)对结果的影响
#1、获取数据
train = df["bmi"]
target = target
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.2)
#2、抽取训练数据和预测数据(使用普通线性回归)
lr = LinearRegression()
#lr.fit(X_train.reshape(-1,1), y_train)
#lr.predict(X_test.reshape(-1,1))
#训练全部样本
lr.fit(train.reshape(-1,1), target)
#测试线性数据
X_test = np.linspace(train.min(), train.max(),100).reshape(-1,1)
y_ = lr.predict(X_test)
# 3、绘制真值和线性回归图
plt.scatter(train, target, color="black", alpha=0.5, label="True")
plt.plot(X_test, y_, color="green", label="Predict")
plt.legend()
plt.xlabel("BMI")
plt.ylabel("Target")
岭回归Ridge:L2正则项
- 原理:缩减系数来“理解”数据
如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归和之前的方法来做预测?
答案是否定的,即不能再使用前面介绍的方法。这是因为输入数据的矩阵X不是满秩矩阵。非满秩矩阵在求逆时会出现问题。
为了解决这个问题,统计学家引入了岭回归(ridge regression)的概念
- 优点:缩减方法可以去掉不重要的参数,因此能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果
- 岭回归是加了二阶正则项的最小二乘,主要适用于过拟合严重或各变量之间存在多重共线性的时候,岭回归是有bias的,这里的bias是为了让variance更小。
- 缺点:这个类最大的缺点是每次我们要自己指定一个超参数α,然后自己评估α的好坏,比较麻烦
- 总结:
1.岭回归可以解决特征数量比样本量多的问题
2.岭回归作为一种缩减算法可以判断哪些特征重要或者不重要,有点类似于降维的效果
3.缩减算法可以看作是对一个模型增加偏差的同时减少方差 - 使用场景:
1.数据点少于变量个数
2.变量间存在共线性(最小二乘回归得到的系数不稳定,方差很大)
3.应用场景就是处理高度相关的数据 - 参数alpha对系数的影响
from sklearn.linear_model import Ridge
# 1、存储每一个alpha训练出来的每一组系数
alphas = np.logspace(-10,-2,100,endpoint=False)
coefs = []
ridge = Ridge()
for alpha in alphas:
ridge.set_params(alpha=alpha)
ridge.fit(X,y)
#coef_函数可以获取机器学习模型中各个特征值的系数
coef = ridge.coef_
coefs.append(coef)
#2、绘制alpha和coefs的关系图
plt.figure(figsize=(10,6))
plt.plot(alphas, coefs)
plt.xscale("log")
plt.xlabel("ALPHA")
plt.ylabel("COEFS")
- 结论:
- alpha值的选择如果太大:无限趋向于0,算法没有意义
- 如果太小:系数波动太大,算法不稳定
- 应该选择在0左右,比较稳定的区间
lasso回归:L1正则项
- 原理:与岭回归类似,它也是通过增加惩罚函数来判断、消除特征间的共线性。
【拉格朗日乘数法】
在lambda足够小的时候,一些系数会因此被迫缩减到0
一般来说,对于高维的特征数据,尤其线性关系是稀疏的,我们会采用Lasso回归。或者是要在一堆特征里面找出主要的特征,那么Lasso回归更是首选了。但是Lasso类需要自己对α调优,所以不是Lasso回归的首选,一般用到的是下一节要讲的LassoCV类。
对比各个算法的训练数据系数coef
#使用numpy创建数据X,创建系数,对系数进行处理,对部分系数进行归零化操作,然后根据系数进行矩阵操作求得目标值
# 1、获取数据
#样本数
n_samples = 50
#特征数
n_featrues = 200
X = np.random.random(size=(n_samples, n_featrues))
#系数
w = np.random.random(size=200)
# 在200个系数中,随机选择一些有效系数,而其他系数就清零
index = np.random.permutation(200)
idx = index[10:]
w[idx] = 0
#样本标签
y = np.dot(X,w)
# 2、训练数据和测试数据
lr = LinearRegression()
ridge = Ridge(alpha=6)
lasso = Lasso(alpha=0.0001)
lr.fit(X,y)
ridge.fit(X,y)
lasso.fit(X,y)
#3、数据视图,此处获取各个算法的训练数据的coef_:系数
coefs = [w, lr.coef_, ridge.coef_, lasso.coef_]
models = ["True","Linear","Ridge", "Lasso"]
plt.figure(figsize=(12,8))
loc = 1
for coef, model in zip(coefs, models):
ax = plt.subplot(2,2,loc)
loc += 1
ax.set_title(model)
ax.plot(coef, color=np.random.random(size=3))
波士顿房价的影响因素分析
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.datasets import load_boston
#导入数据
boston = load_boston()
data = boston.data
target = boston.target
feature_names = boston.feature_names
df = DataFrame(data=data, columns=feature_names)
df.head() ==>
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
0 0.00632 18.0 2.31 0.0 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98
1 0.02731 0.0 7.07 0.0 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14
2 0.02729 0.0 7.07 0.0 0.469 7.185 61.1 4.9671 2.0 242.0 17.8 392.83 4.03
#分割训练数据和测试数据
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
#封装函数多次查看模型的均方误差的平均值、
def model_mse(model):
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=2)
model.fit(X_train, y_train)
#测试误差
test_err = mean_squared_error(y_test, model.predict(X_test))
#训练误差
train_err = mean_squared_error(y_train, model.predict(X_train))
return test_err, train_err
#计算100次训练的平均误差
def ave_err(model):
ridge = model
test_errs = []
train_errs = []
for i in range(100):
ret = model_mse(ridge)
test_errs.append(ret[0])
train_errs.append(ret[1])
print("经验误差:%.2f, 泛化误差:%.2f"%(np.array(train_errs).mean(), np.array(test_errs).mean()))
return np.array(train_errs).mean(), np.array(test_errs).mean()
#岭回归
r = Ridge(alpha=3)
ave_err(r) ==>经验误差:22.33, 泛化误差:21.88
# KNN回归
knn = KNeighborsRegressor()
ave_err(knn) ==>经验误差:23.92, 泛化误差:41.64
#普通线性回归
lr = LinearRegression()
ave_err(lr) ==>经验误差:21.89, 泛化误差:24.97
#劳斯回归
lasso = Lasso()
ave_err(lasso) ==>lasso = Lasso()
ave_err(lasso)
lasso = Lasso()
ave_err(lasso)
经验误差:26.82, 泛化误差:23.35
#以上可以看出【岭回归】更适合
# 算法调参
alphas = [0.1,0.5,1,3,5,10,20]
errs_train = []
errs_test = []
for alpha in alphas:
ridge = Ridge(alpha=alpha)
print("alphe = {}".format(alpha))
train_err, test_err = ave_err(ridge)
errs_train.append(train_err)
errs_test.append(test_err) ==>
alphe = 0.1
经验误差:21.54, 泛化误差:24.49
alphe = 0.5
经验误差:21.86, 泛化误差:23.73
alphe = 1
经验误差:21.66, 泛化误差:24.99
alphe = 3
经验误差:22.31, 泛化误差:23.91
alphe = 5
经验误差:22.28, 泛化误差:24.80
alphe = 10
经验误差:22.46, 泛化误差:24.95
alphe = 20
经验误差:22.59, 泛化误差:25.34
plt.plot(alphas, errs_train, lab
# 绘制误差随着alpha参数的变化曲线
plt.plot(alphas, errs_train, label = "train err", color="green")
plt.plot(alphas, errs_test, label = "test err", color="black")
plt.legend()
鲍鱼年龄预测
# 需求: 找出预测鲍鱼年龄的最佳算法并且对该算法进行调参
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
# 1、获取样本集和样本标签
abalone = pd.read_csv('abalone.txt',sep='\t',header=None)
#样本集
train = abalone.loc[:,0:7]
#样本标签
target = abalone[8]
#查看数据信息
abalone.shape
abalone.describe()
abalone.info()
target.unique()
#分析数据的出此问题是线性回归问题
#选择线性回归模型并计算各个模型的均方误差进行比较
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
#1.封装函数进行算法比较
# 算法选择
def model_err(model):
test_errs = []
train_errs = []
for i in range(10):
X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.2)
model.fit(X_train, y_train)
test_err = mean_squared_error(y_test, model.predict(X_test))
train_err = mean_squared_error(y_train, model.predict(X_train))
test_errs.append(test_err)
train_errs.append(train_err)
return np.array(test_errs).mean(), np.array(train_errs).mean()
# 普通线性回归
model_err(LinearRegression())</