def get_linreg_w(X, Y):
    """ X: dataframe of x1, x2, x..., xn
    Y: array of y
    return: w as matrix """
    print X
    X['b'] = 1
    Xt = X.transpose()
    w_den = np.dot(Xt, X)
    w_pre = np.dot(utils.matrix_inverse(w_den), Xt)
    w = np.dot(w_pre, Y)
    del X['b']
    return w
def get_linridge_w(X_uncentered, Y, learning_rate):
    """ Linear ridge
    X: dataframe of x1, x2, x..., xn
    Y: array of y
    return: w as matrix """
    #TODO - add mean back in before predict

    X = X_uncentered

    X['b'] = 1
    Xt = X.transpose()

    I = np.identity(X.shape[1])
    w_den = np.dot(Xt, X) + np.dot(learning_rate, I)
    #w_den = np.cov(X) + np.dot(learning_rate, I)
    w_pre = np.dot(utils.matrix_inverse(w_den), Xt)
    w = np.dot(w_pre, Y)
    return w