思维导图笔记
算法原理推导过程
代码实现
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
# 创建一个只有2个特征的测试数据
X = np.empty((100, 2))
X[:, 0] = np.random.uniform(0., 100.0, size=100)
# 为了直观查看PCA后的效果,在这里初始化时候让两个特征值具有线性关系
X[:, 1] = X[:, 0] * 0.75 + 3.0 + np.random.normal(0, 10.0, size=100)
# 降维后的w向量
final_w = None
def demean(X):
"""
进行均值为0的处理
:param X: 为一个矩阵
:return:
"""
return X - np.mean(X, axis=0)
def draw_graph():
"""
画图直观展示PCA效果
:return:
"""
X_demean = demean(X)
plt.scatter(X[:, 0], X[:, 1], label='OriginalData')
plt.scatter(X_demean[:, 0], X_demean[:, 1], color='g', label='Demean Data', marker='+')
x_data = final_w[0] * np.linspace(-40, 40, 10)
y_data = final_w[1] * np.linspace(-40, 40, 10)
print y_data
plt.plot(x_data, y_data, color='r', label='PCA Line', marker='.')
plt.legend()
plt.show()
def J(X, w):
"""
损失函数,这里X是已经进行demean处理过的数据
"""
return np.sum((X.dot(w) ** 2)) / len(X)
def DJ(X, w):
"""
求梯度的函数
"""
return X.T.dot(X.dot(w)) * 2.0 / len(X)
def direction(w):
"""
针对向量进行单位化,即让向量的模等于1
"""
return w / np.linalg.norm(w)
def gredient_ascent(X, initial_w, n_inters=1e4, eta=0.001, epsilon=1e-8):
"""
梯度上升法的代码实现
:param X:
:return:
"""
cur_inter = 0
w = direction(initial_w)
while cur_inter < n_inters:
last_w = w
gradient = DJ(X, last_w)
w = w + eta * gradient
w = direction(w) # 每一次都要格式化为单位向量
if abs(J(X, w) - J(X, last_w)) < epsilon:
break
cur_inter += 1
return w
def test():
# 初始化w,此处不能为0向量
init_theta = np.random.random(X.shape[1])
global final_w
final_w = gredient_ascent(demean(X), init_theta)
draw_graph()
if __name__ == '__main__':
test()
运行结果:
最佳向量为(0.77409214 0.63307295)
要是你在西安,感兴趣一起学习AIOPS,欢迎加入QQ群 860794445