我正在尝试实现这个算法来找到单变量的截距和斜率:
这是我用来更新截距和斜率的Python代码。但是它没有收敛。RSS随着迭代增加而不是减少,并且在一些迭代后变得无穷大。我没有发现实现算法时有任何错误。我该如何解决这个问题?我也附上了csv文件。以下是代码。
import pandas as pdimport numpy as np#定义梯度下降#这个函数接受X值,Y值和w0(截距),w1(斜率)的向量#输入特征=X(房屋面积的平方英尺)#目标值=Y(房屋价格)#W=np.array([w0,w1]).reshape(2,1)#W=[w0,# w1]def gradient_decend(X,Y,W): intercept=W[0][0] slope=W[1][0] #这里我会得到一个列表 #列表像这样 #gd=[sum(predicted_value-(intercept+slope*x)), # sum(predicted_value-(intercept+slope*x)*x)] gd=[sum(y-(intercept+slope*x) for x,y in zip(X,Y)), sum(((y-(intercept+slope*x))*x) for x,y in zip(X,Y))] return np.array(gd).reshape(2,1)#定义残差平方和def RSS(X,Y,W): return sum((y-(W[0][0]+W[1][0]*x))**2 for x,y in zip(X,Y))#读取训练数据training_data=pd.read_csv("kc_house_train_data.csv")#定义固定参数#学习率n=0.0001iteration=1500#截距w0=0#斜率w1=0#创建w0,w1参数的2,1向量W=np.array([w0,w1]).reshape(2,1)#运行梯度下降for i in range(iteration): W=W+((2*n)* (gradient_decend(training_data["sqft_living"],training_data["price"],W))) print RSS(training_data["sqft_living"],training_data["price"],W)
这里是CSV文件。
回答:
我已经解决了自己的问题!
这是解决的方法。
import numpy as npimport pandas as pdimport mathfrom sys import stdout#函数接受pandas数据框,输入特征列表和目标列名def get_numpy_data(data, features, output): #在数据框中添加一个值为1的常数列。 data['constant'] = 1 #在特征列表中添加常数列的名称。 features = ['constant'] + features #创建特征矩阵(选择列并转换为矩阵)。 features_matrix=data[features].as_matrix() #目标列转换为numpy数组 output_array=np.array(data[output]) return(features_matrix, output_array)def predict_outcome(feature_matrix, weights): weights=np.array(weights) predictions = np.dot(feature_matrix, weights) return predictionsdef errors(output,predictions): errors=predictions-output return errorsdef feature_derivative(errors, feature): derivative=np.dot(2,np.dot(feature,errors)) return derivativedef regression_gradient_descent(feature_matrix, output, initial_weights, step_size, tolerance): converged = False #初始权重转换为numpy数组 weights = np.array(initial_weights) while not converged: #根据特征矩阵和权重计算预测值: predictions=predict_outcome(feature_matrix,weights) #计算错误值为预测值 - 输出值: error=errors(output,predictions) gradient_sum_squares = 0 # 初始化梯度 #在未收敛时,单独更新每个权重: for i in range(len(weights)): #回想feature_matrix[:, i]是与weights[i]相关联的特征列 feature=feature_matrix[:, i] #计算weight[i]的导数: #predict=predict_outcome(feature,weights[i]) #err=errors(output,predict) deriv=feature_derivative(error,feature) #将平方导数加到梯度大小中 gradient_sum_squares=gradient_sum_squares+(deriv**2) #根据步长和导数更新权重: weights[i]=weights[i] - np.dot(step_size,deriv) gradient_magnitude = math.sqrt(gradient_sum_squares) stdout.write("\r%d" % int(gradient_magnitude)) stdout.flush() if gradient_magnitude < tolerance: converged = True return(weights)#实现示例#导入训练和测试数据# train_data=pd.read_csv("kc_house_train_data.csv")# test_data=pd.read_csv("kc_house_test_data.csv")# simple_features = ['sqft_living', 'sqft_living15']# my_output= 'price'# (simple_feature_matrix, output) = get_numpy_data(train_data, simple_features, my_output)# initial_weights = np.array([-100000., 1., 1.])# step_size = 7e-12# tolerance = 2.5e7# simple_weights = regression_gradient_descent(simple_feature_matrix, output,initial_weights, step_size,tolerance)# print simple_weights