目录
4. 无监督学习(Unsupervised Learning)(如:聚类)
3.7 正规方程(区别于迭代方法求J(Ѳ)min的直接解法)
一、机器学习(ML)简介
1. 人工智能、机器学习、深度学习的关系
机器学习是人工智能的子领域,也是人工智能的核心。它囊括了几乎所有对世界影响最大的方法(包括深度学习)。
机器学习理论主要是设计和分析一些让计算机可以自动学习的算法。
深度学习(DeepLearning,DL)属于机器学习的子类。它的灵感来源于人类大脑的工作方式,是利用深度神经网络来解决特征表达的一种学习过程。
深度神经网络本身并非是一个全新的概念,可理解为包含多个隐含层的神经网络结构。为了提高深层神经网络的训练效果,人们对神经元的连接方法以及激活函数等方面做出了调整。其目的在于建立、模拟人脑进行分析学习的神经网络,模仿人脑的机制来解释数据,如文本、图像、声音。
概括来说:人工智能包括机器学习,机器学习包括深度学习
2. 机器学习与深度学习的比较
2.1、应用场景
机器学习在指纹识别、特征物体检测等领域的应用基本达到了商业化的要求。
深度学习主要应用于文字识别、人脸技术、语义分析、智能监控等领域。目前在智能硬件、教育、医疗等行业也在快速布局。
2.2、所需数据量
机器学习能够适应各种数据量,特别是数据量较小的场景。
如果数据量迅速增加,那么深度学习的效果将更加突出,这是因为深度学习算法需要大量数据才能完美理解。
2.3、执行时间
执行时间是指训练算法所需要的时间量。
一般来说,深度学习算法需要大量时间进行训练。这是因为该算法包含有很多参数,因此训练它们需要比平时更长的时间。
相对而言,机器学习算法的执行时间更少。
2.4、解决问题的方法
机器学习算法遵循标准程序以解决问题。它将问题拆分成数个部分,对其进行分别解决,而后再将结果结合起来以获得所需的答案。
深度学习则以集中方式解决问题,而不必进行问题拆分。
3. 监督学习(Supervised Learning)
指我们给算法一个数据集,其中包含了正确答案,算法的目的就是给出更多的正确答案。也被成为 回归问题(Regression)
回归问题:目的 预测连续的数值输出。
分类问题:目的 预测离散值得输出。
在监督学习中,我们有一个数据集,它被称为一个训练集。
4. 无监督学习(Unsupervised Learning)(如:聚类)
吴恩达建议:先用Octave建立起原型,再用其他编程语言(Python)实现速度会大大提高效率!(可以试一试)
无监督学习:指(给定一组无标签的数据集)根据类别未知(没有被标记)的训练样本解决模式识别中的各种问题。
5.一些符号代表一些定义:
m:表示训练样本的数量
x:代表输入变量(或输入特征)
y:代表输出变量(即需要预测的目标变量)
(x,y):表示一个训练样本
(x^(i), y^(i)):表示第i个训练样本
h(hypothesis<假设>):表示假设函数
二、线性回归
1. Python设计的一些第三方库的使用
1.1 简单的练习
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
A = np.eye(5)
A
运行结果:
array([[1., 0., 0., 0., 0.], [0., 1., 0., 0., 0.], [0., 0., 1., 0., 0.], [0., 0., 0., 1., 0.], [0., 0., 0., 0., 1.]])
2.单变量的线性回归
这个部分需要根据城市人口数量,预测开小吃店的利润。
数据在ex1data1.txt里,第一列是城市人口数量,第二列是该城市小吃店利润。
2.1 Plotting the data
读入数据,然后展示数据
数据说明
ex1data1.txt需要根据学生的2次测试成绩,预测该学生是否被录取。第一列是第一次测试成绩,第二列是第二次测试成绩
path = 'E:/Python/machine learning/data/ex1_data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head() # head()是观察前5行
# 运行结果如下图
Population | Profit | |
---|---|---|
0 | 6.1101 | 17.5920 |
1 | 5.5277 | 9.1302 |
2 | 8.5186 | 13.6620 |
3 | 7.0032 | 11.8540 |
4 | 5.8598 | 6.8233 |
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8)) #figsize(a,b)设置图形的大小,a为图形的宽,b为图形的高,单位为英寸
plt.show() # scatter代表散点图
2.2 代价函数(cost function)
有时也叫平方误差函数(square error function)
,或者平方误差代价函数(square error cost function)
。
对于大多数问题,特别是回归问题,都是一个合理的选择。
一个好的代价函数需要满足两个最基本的要求:能够评价模型的准确性,对参数θ可微。
在线性回归中,最常用的是均方误差(Mean squared error),具体形式为:
m:训练样本的个数;
hθ(x):用参数θ和x预测出来的y值;
y:原训练样本中的y值,也就是标准答案
上角标(i):第i个样本
目标:找到θ0,θ1使J(θ)的值最小。目标函数:minmizeJ(θ)
图像:通常用等高线图表示,J(θ)是一个碗状的图形,并且有全局最小值。全局最小值就是θ0和θ1的最优解。梯度下降的每一步都会更接近这个最小值
2.3 梯度下降
这个部分你需要在现有数据集上,训练线性回归的参数θ
公式:
如下图所示梯度下降算法的定义。不断更新θj,直到收敛。
其中 :=
表示赋值; =
表示真假判断;α
表示学习速率,来控制梯度下降时,“迈的步子”,α越大,下降越快;α太小,收敛速度太慢,α太大,会导致无法收敛甚至发散。当达到最优解时,偏导数为0,θ收敛
微妙之处:1.看for可得,需要同时
更新θ0和θ1;2.不必减小α,因为当越来越接近最优解时,偏导数会变得越来越小!!!
2.4 关于矩阵的一些知识
矩阵和向量
矩阵(matrix)的维度 = 行数 x 列数
向量(vector):rows x 1 维度的矩阵
通常用大写字母表示 矩阵 ,用 y 表示向量
矩阵的加法 和 与标量的乘法
两个矩阵相加:对应位置元素相加即可
标量矩阵 = 矩阵中每个元素都标量(除法同理)
与矩阵乘法
矩阵前提:一个矩阵的列数=另一个矩阵的行数
A1 x A2 = A1行对应的元素 x A2列对应的元素 然后相加求和 得:rowsA1 x colsA2维度的矩阵
矩阵乘法的特性
A x B != B x A
A x B x C == A x (B x C) == (A x B) x C
单位矩阵:I(n*n) A x I == I x A
矩阵的逆(inverse)和转置(transpose)
2.5 实现梯度下降算法在线性回归中的应用
#数据前面已经读取完毕,我们要为加入一列x,用于更新Ѳ,然后我们将Ѳ初始化为0,学习率初始化为0.01,迭代次数为1500次
data.insert(0, 'Ones', 1)
# 初始化x,y
cols = data.shape[1]
X = data.iloc[:,:-1] #X是data里的除最后列
y = data.iloc[:,cols-1:cols] #y是data最后一列
# 观察下 X (训练集) and y (目标变量)是否正确.
X.head()
y.head()
# 代价函数应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))
#看下维度
X.shape, theta.shape, y.shape
((97, 2), (1, 2), (97, 1))
#这个部分计算J(Ѳ),X是矩阵
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))
#2.2.3计算J(θ)计算代价函数 (theta初始值为0)
computeCost(X, y, theta)
32.072733877455676
#2.2.4梯度下降
'''记住J(θ)的变量是θ,而不是X和y,意思是说,我们变化的值来使J(θ)变化,而不是变化X和y的值。
一个检查梯度下降是不是在正常运作的方式,是打印出每一步J(θ)的值,看他是不是一直都在减小,并且最后收敛至一个稳定的值。
最后的结果会用来预测小吃店在35000及70000人城市规模的利润。'''
#这个部分实现了Ѳ的更新
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (X * theta.T) - y
for j in range(parameters):
term = np.multiply(error, X[:,j])
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
#初始化一些附加变量 - 学习速率α和要执行的迭代次数,2.2.2中已经提到。
alpha = 0.01
iters = 1500
#现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。
g, cost = gradientDescent(X, y, theta, alpha, iters)
g
matrix([[-3.63029144, 1.16636235]])
#预测35000和70000城市规模的小吃摊利润
predict1 = [1,3.5]*g.T
print("predict1:",predict1)
predict2 = [1,7]*g.T
print("predict2:",predict2)
predict1: [[0.45197679]] predict2: [[4.53424501]]
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * x)
#原始数据以及拟合的直线
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
3. 多变量(多特征)的线性回归
3.1 Notation
3.2 多元梯度下降法
上面的假设函数的参数:Ѳ0~Ѳn看做一个n+1维的向量
3.3 向量化
在很多特征时,用循环实现Ѳ的更新很慢,用向量代替上图式子中Ѳ-的内个求和式,再用代码可以更简洁的实现并且提高速度
3.4 特征缩放¶
当 不同特征的取值在相近的范围内,这样梯度下降就能更好的收敛。 所以,当范围相差太大的时候,可以使用特征缩放的方法。以两个特征量为例理解:
通常将特征的取值约束在 -1到+1 的范围内,本身范围很近超一点点的也是ok的。
x>>1 / <0x<<1 / x<<-1 / -1<<x<0都是不合适的
均值归一化(Mean normalization)
do:(xi-μi)/Si (μi:x的平均值,Si:范围大小(最大-最小)) 让你的特征值具有为0的平均值(x0除外,x0永远为1)
3.5 学习率α
首先通过 J(Ѳ) 关于迭代次数的曲线图检验算法是否执行正常。当曲线成上升趋势时,很可能是 α 太大了
选α时,try:α=0.001/0.003/0.01/0.03/0.1/0.3/1...(通常每隔大约3倍取一个值),然后通过绘制J(Ѳ)与迭代次数的曲线,选择使J(Ѳ)下降最快的α值
3.6 特征和多项式回归
特征可以任意选择(例如:已知特征长和宽,可以定义长*宽作为新的特征):有算法可以自动识别选择什么特征特征,后面会学习。
多项式回归:(需要注意每个变量的范围会差很多,需要特征缩放)
3.7 正规方程(区别于迭代方法求J(Ѳ)min的直接解法)
正规方程法:可以一步得到最优解 (原理:Ѳ为实数时,求导;Ѳ为向量时,对每一个Ѳ求偏导。)
此方法不需要特征缩放。
n越大,计算X的转置和逆时间(O(n^3))越长。该方法在后面学学习的更复杂的算法中不能用,梯度下降算法更为常用,该算法是特定模型下的替代算法。
选择:通常,当n>1百万时,选择梯度下降法或其他算法;当n<10000时,选择正规方程法。
3.8 正规方程之矩阵不可逆情况下的解决方法
原因:1.有多余的特征 2.特征太多(m<=n时)
解决:寻找是否有线性关系的特征,删掉一个;否则,如果有太多特征,删去一些不影响的或考虑使用正规化方法。
3.9 多变量线性回归应用
ex1data2.txt里的数据,第一列是房屋大小,第二列是卧室数量,第三列是房屋售价
根据已有数据,建立模型,预测房屋的售价
path = 'E:/Python/machine learning/data/ex1_data2.txt'
data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
data2.head()
Size | Bedrooms | Price | |
---|---|---|---|
0 | 2104 | 3 | 399900 |
1 | 1600 | 3 | 329900 |
2 | 2400 | 3 | 369000 |
3 | 1416 | 2 | 232000 |
4 | 3000 | 4 | 539900 |
特征归一化¶
观察数据发现,size变量是bedrooms变量的1000倍大小,统一量级会让梯度下降收敛的更快。做法就是,将每类特征减去他的平均值后除以标准差。
梯度下降
# 加一列常数项
data2.insert(0, 'Ones', 1)
# 初始化X和y
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]
# 转换成matrix格式,初始化theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0,0,0]))
# 运行梯度下降算法
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
g2
matrix([[-1.10898288e-16, 8.84042349e-01, -5.24551809e-02]])
# 正规方程
def normalEqn(X, y):
theta = np.linalg.inv(X.T@X)@X.T@y# X.T@X等价于X.T.dot(X)
return theta
final_theta2=normalEqn(X, y)#这里用的是data1的数据
final_theta2
matrix([[-3.89578088], [ 1.19303364]])
梯度下降得到的结果是matrix([[-3.24140214, 1.1272942 ]])
三、分类
对于要预测的变量y为离散值时的分类问题,一种新的分类算法:logistic 回归算法。该算法:0<=h(Ѳ)<=1
二分类:y∈{0,1},多分类:y∈{1,2,...}(一些离散的值)
1. logistic 回归(逻辑回归)¶
1.1 假设陈述
1.2 决策界限
决策边界是假设函数的一个属性,决定于假设函数的参数Ѳ的取值,不取决于数据集。是两个取值样本的分界线。
1.3 代价函数
即如何拟合逻辑回归模型的参数Ѳ。通过数据集,确定Ѳ
J(Ѳ)为非凹函数,无法得到局部最优解
1.4 简化代价函数与梯度下降
上面的特征缩放仍然适用于逻辑回归
2. 逻辑回归的应用
在训练的初始阶段,我们将要构建一个逻辑回归模型来预测,某个学生是否被大学录取。设想你是大学相关部分的管理者,想通过申请学生两次测试的评分,来决定他们是否被录取。现在你拥有之前申请学生的可以用于训练逻辑回归的训练样本集。对于每一个训练样本,你有他们两次测试的评分
和最后是被录取的结果
。
2.1 数据可视化
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path = 'E:/Python/machine learning/data/ex2_data1.txt'
data = pd.read_csv(path, header=None, names=['Exam 1', 'Exam 2', 'Admitted'])
data.head()
positive = data[data['Admitted'].isin([1])]
negative = data[data['Admitted'].isin([0])]
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive['Exam 1'], positive['Exam 2'], s=50, c='b', marker='o', label='Admitted')
ax.scatter(negative['Exam 1'], negative['Exam 2'], s=50, c='r', marker='x', label='Not Admitted')
ax.legend()
ax.set_xlabel('Exam 1 Score')
ax.set_ylabel('Exam 2 Score')
plt.show()
2.2 sigmoid 函数
# 实现sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
2.3 代价函数和梯度
# 实现代价函数
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))
return np.sum(first - second) / (len(X))
# 加一列常数列
data.insert(0, 'Ones', 1)
# 初始化X,y,θ
cols = data.shape[1]
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]
theta = np.zeros(3)
# 转换X,y的类型
X = np.array(X.values)
y = np.array(y.values)
# 检查矩阵的维度
X.shape, theta.shape, y.shape
((100, 3), (3,), (100, 1))
# 用初始θ计算代价
cost(theta, X, y)
0.6931471805599453
# 实现梯度计算的函数(并没有更新θ)
def gradient(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
parameters = int(theta.ravel().shape[1])
grad = np.zeros(parameters)
error = sigmoid(X * theta.T) - y
for i in range(parameters):
term = np.multiply(error, X[:,i])
grad[i] = np.sum(term) / len(X)
return grad
2.4 用工具库计算θ的值
在此前的线性回归中,我们自己写代码实现的梯度下降(ex1的2.2.4的部分)。当时我们写了一个代价函数、计算了他的梯度,然后对他执行了梯度下降的步骤。这次,我们不自己写代码实现梯度下降,我们会调用一个已有的库。这就是说,我们不用自己定义迭代次数和步长,功能会直接告诉我们最优解。 andrew ng在课程中用的是Octave的“fminunc”函数,由于我们使用Python,我们可以用scipy.optimize.fmin_tnc做同样的事情。 (另外,如果对fminunc有疑问的,可以参考下面这篇百度文库的内容matlab最小值优化问题中fminunc、fmincon的应用 - 百度文库 )
import scipy.optimize as opt
result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))
result
(array([-25.16131863, 0.20623159, 0.20147149]), 36, 0)
# 用θ的计算结果代回代价函数计算
cost(result[0], X, y)
0.20349770158947458
# 画出决策曲线
plotting_x1 = np.linspace(30, 100, 100)
plotting_h1 = ( - result[0][0] - result[0][1] * plotting_x1) / result[0][2]
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(plotting_x1, plotting_h1, 'y', label='Prediction')
ax.scatter(positive['Exam 1'], positive['Exam 2'], s=50, c='b', marker='o', label='Admitted')
ax.scatter(negative['Exam 1'], negative['Exam 2'], s=50, c='r', marker='x', label='Not Admitted')
ax.legend()
ax.set_xlabel('Exam 1 Score')
ax.set_ylabel('Exam 2 Score')
plt.show()
2.5 评价逻辑回归模型
在确定参数之后,我们可以使用这个模型来预测学生是否录取。如果一个学生exam1得分45,exam2得分85
# 实现hθ
def hfunc1(theta, X):
return sigmoid(np.dot(theta.T, X))
hfunc1(result[0],[1,45,85])
0.7762906240463825
另一种评价θ的方法是看模型在训练集上的正确率怎样。写一个predict的函数,给出数据以及参数后,会返回“1”或者“0”。然后再把这个predict函数用于训练集上,看准确率怎样。
# 定义预测函数
def predict(theta, X):
probability = sigmoid(X * theta.T)
return [1 if x >= 0.5 else 0 for x in probability]
# 统计预测正确率
theta_min = np.matrix(result[0])
predictions = predict(theta_min, X)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y)]
accuracy = (sum(map(int, correct)) % len(correct))
print ('accuracy = {0}%'.format(accuracy))
accuracy = 89%
3. 正则化逻辑回归
在训练的第二部分,我们将实现加入正则项提升逻辑回归算法。 设想你是工厂的生产主管,你有一些芯片在两次测试中的测试结果,测试结果决定是否芯片要被接受或抛弃。你有一些历史数据,帮助你构建一个逻辑回归模型。
3.1 数据可视化
path = 'E:/Python/machine learning/data/ex2_data2.txt'
data_init = pd.read_csv(path, header=None, names=['Test 1', 'Test 2', 'Accepted'])
data_init.head()
positive2 = data_init[data_init['Accepted'].isin([1])]
negative2 = data_init[data_init['Accepted'].isin([0])]
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive2['Test 1'], positive2['Test 2'], s=50, c='b', marker='o', label='Accepted')
ax.scatter(negative2['Test 1'], negative2['Test 2'], s=50, c='r', marker='x', label='Rejected')
ax.legend()
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
plt.show()
以上图片显示,这个数据集不能像之前一样使用直线将两部分分割。而逻辑回归只适用于线性的分割,所以,这个数据集不适合直接使用逻辑回归。
3.2 特征映射
一种更好的使用数据集的方式是为每组数据创造更多的特征。所以我们为每组添加了最高到6次幂的特征
degree = 6
data2 = data_init
x1 = data2['Test 1']
x2 = data2['Test 2']
data2.insert(3, 'Ones', 1)
for i in range(1, degree+1):
for j in range(0, i+1):
data2['F' + str(i-j) + str(j)] = np.power(x1, i-j) * np.power(x2, j)
#此处原答案错误较多,已经更正
data2.drop('Test 1', axis=1, inplace=True)
data2.drop('Test 2', axis=1, inplace=True)
data2.head()
3.3 代价函数和梯度
在原来的基础上加上正则项
(缩小每一个Ѳ) 记住Ѳ0是不需要正则化的,下标从1开始。 梯度的第j个元素的更新公式为:对上面的算法中 j=1,2,...,n 时的更新式子进行调整可得:把初始(所有元素为0)带入,代价应为0.693这一部分要实现计算逻辑回归的代价函数和梯度的函数。代价函数公式如下:
# 实现正则化的代价函数
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))
reg = (learningRate / (2 * len(X))) * np.sum(np.power(theta[:,1:theta.shape[1]], 2))
return np.sum(first - second) / len(X) + reg
# 实现正则化的梯度函数
def gradientReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
parameters = int(theta.ravel().shape[1])
grad = np.zeros(parameters)
error = sigmoid(X * theta.T) - y
for i in range(parameters):
term = np.multiply(error, X[:,i])
if (i == 0):
grad[i] = np.sum(term) / len(X)
else:
grad[i] = (np.sum(term) / len(X)) + ((learningRate / len(X)) * theta[:,i])
return grad
# 初始化X,y,θ
cols = data2.shape[1]
X2 = data2.iloc[:,1:cols]
y2 = data2.iloc[:,0:1]
theta2 = np.zeros(cols-1)
# 进行类型转换
X2 = np.array(X2.values)
y2 = np.array(y2.values)
# λ设为1
learningRate = 1
# 计算初始代价
costReg(theta2, X2, y2, learningRate)
0.6931471805599454
3.4 用工具库求解参数
result2 = opt.fmin_tnc(func=costReg, x0=theta2, fprime=gradientReg, args=(X2, y2, learningRate))
result2
(array([ 1.27271027, 0.62529965, 1.18111686, -2.01987399, -0.9174319 , -1.43166929, 0.12393227, -0.36553118, -0.35725403, -0.17516292, -1.45817009, -0.05098418, -0.61558552, -0.27469165, -1.19271298, -0.24217841, -0.20603297, -0.04466178, -0.27778952, -0.29539513, -0.45645981, -1.04319155, 0.02779373, -0.29244872, 0.01555761, -0.32742406, -0.1438915 , -0.92467487]),32,1)
最后,我们可以使用第1部分中的预测函数来查看我们的方案在训练数据上的准确度。
theta_min = np.matrix(result2[0])
predictions = predict(theta_min, X2)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y2)]
accuracy = (sum(map(int, correct)) % len(correct))
print ('accuracy = {0}%'.format(accuracy))
accuracy = 98%
3.5 画出决策的曲线
def hfunc2(theta, x1, x2):
temp = theta[0][0]
place = 0
for i in range(1, degree+1):
for j in range(0, i+1):
temp+= np.power(x1, i-j) * np.power(x2, j) * theta[0][place+1]
place+=1
return temp
def find_decision_boundary(theta):
t1 = np.linspace(-1, 1.5, 1000)
t2 = np.linspace(-1, 1.5, 1000)
cordinates = [(x, y) for x in t1 for y in t2]
x_cord, y_cord = zip(*cordinates)
h_val = pd.DataFrame({'x1':x_cord, 'x2':y_cord})
h_val['hval'] = hfunc2(theta, h_val['x1'], h_val['x2'])
decision = h_val[np.abs(h_val['hval']) < 2 * 10**-3]
return decision.x1, decision.x2
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive2['Test 1'], positive2['Test 2'], s=50, c='b', marker='o', label='Accepted')
ax.scatter(negative2['Test 1'], negative2['Test 2'], s=50, c='r', marker='x', label='Rejected')
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
x, y = find_decision_boundary(result2)
plt.scatter(x, y, c='y', s=10, label='Prediction')
ax.legend()
plt.show()
3.6 改变λ,观察决策曲线
λ=0时 过拟合
learningRate2 = 0
result3 = opt.fmin_tnc(func=costReg, x0=theta2, fprime=gradientReg, args=(X2, y2, learningRate2))
result3
(array([ 9.11192364e+00, 1.18840465e+01, 6.30828094e+00, -8.39706468e+01, -4.48639810e+01, -3.81221435e+01, -9.42525756e+01, -8.14257602e+01, -4.22413355e+01, -3.52968361e+00, 2.95734207e+02, 2.51308760e+02, 3.64155830e+02, 1.61036970e+02, 5.70100234e+01, 1.71716716e+02, 2.72109672e+02, 3.12447535e+02, 1.41764016e+02, 3.22495698e+01, -1.75836912e-01, -3.58663811e+02, -4.82161916e+02, -7.49974915e+02, -5.03764307e+02, -4.80978435e+02, -1.85566236e+02, -3.83936243e+01]), 280, 3)
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive2['Test 1'], positive2['Test 2'], s=50, c='b', marker='o', label='Accepted')
ax.scatter(negative2['Test 1'], negative2['Test 2'], s=50, c='r', marker='x', label='Rejected')
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
x, y = find_decision_boundary(result3)
plt.scatter(x, y, c='y', s=10, label='Prediction')
ax.legend()
plt.show()
λ=100时欠拟合
learningRate3 = 100
result4 = opt.fmin_tnc(func=costReg, x0=theta2, fprime=gradientReg, args=(X2, y2, learningRate3))
fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive2['Test 1'], positive2['Test 2'], s=50, c='b', marker='o', label='Accepted')
ax.scatter(negative2['Test 1'], negative2['Test 2'], s=50, c='r', marker='x', label='Rejected')
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
x, y = find_decision_boundary(result4)
plt.scatter(x, y, c='y', s=10, label='Prediction')
ax.legend()
plt.show()
暑假大概就看这么多,先保存下来趴。