Bobo老师机器学习笔记第七课-主成分分析法

思维导图笔记

算法原理推导过程

代码实现

# -*- 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

猜你喜欢

转载自blog.csdn.net/sxb0841901116/article/details/83618486