I will then learn to convert my time series data into a network map using visibility_graph. But when I typed in my data, I didn't get a very obvious network, and most of them just presented a ring.
https://github.com/rgarcia-herrera/visibility_graph
Below is my data example
[ 8.34 3.24 9.82 2.09 6.43 2.88 6.51 6.47 12.41 6.52 5.65 6.13
5.28 6.87 13.22 7.05 13.65 5.7 16.88 3.43 15.81 4.87 9.74 4.43
18.77 8.24 16.2 10.58 18.31 10.4 12.33 8.21 22.74 5.67 19.18 8.55
16.9 10.22 21.68 8.61 17.81 11.4 27.51 11.19 25.78 8.31 29.87 6.35
24.14 10.36 20.13 12.01 25.47 6.66 14.09 10.72 23.52 7.11 24.88 9.75
22.6 7.24]
Below is the code I tried (I tried smoothing)
from visibility_graph import visibility_graph
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import scipy as sp
import scipy.ndimage
for user, group in data.groupby('cons_no'):
for i in range(12): # every month
u = pd.DataFrame(group)
u.sort_index(inplace=True) # Time sorting
values = []
for row in u.itertuples():
if row.Index.year == 2017 and row.Index.month == i + 1:
values.append((round(row.pap_r1, 1), round(row.pap_r2, 1)))
temp = []
for v in values:
temp.append(v[0])
temp.append(v[1])
temp = np.array(temp)
# Min = np.min(temp)
# Max = np.max(temp)
# temp = [max_min(x, Max, Min) for x in temp]
temp = sp.ndimage.gaussian_filter(temp, sigma=1, mode='constant')
print(temp)
temp = [round(x, 1) for x in temp]
temp = np.log10(temp)
values = temp
# print(values)
G = visibility_graph(values)
plt.subplot(121)
nx.draw_networkx(G, with_labels=False, node_size=50)
plt.title(str(user))
plt.savefig('./user_' + str(user) + '_com.png')
print('./user_' + str(user) + '_com.png')
# plt.show()
I hope someone can help me understand how to properly modify my data so that visibility_graph appears on the network.
Answer my own question.
I think there is a bug in this package.
So I modified the source code to make it work properly.
from itertools import combinations
import networkx as nx
def visibility_graph(series):
g = nx.Graph()
# convert list of magnitudes into list of tuples that hold the index
tseries = []
n = 0
for magnitude in series:
tseries.append( (n, magnitude ) )
n += 1
# contiguous time points always have visibility
for n in range(0,len(tseries)-1):
(ta, ya) = tseries[n]
(tb, yb) = tseries[n+1]
g.add_node(ta, mag=ya)
g.add_node(tb, mag=yb)
g.add_edge(ta, tb)
for a,b in combinations(tseries, 2):
# two points, maybe connect
(ta, ya) = a
(tb, yb) = b
connect = True
# let's see all other points in the series
for tc, yc in tseries:
# other points, not a or b
if tc != ta and tc != tb and ta < tc < tb: # The condition here is the key.
# does c obstruct?
if yc > yb + (ya - yb) * ( (tb - tc) / (tb - ta) ):
connect = False
if connect:
g.add_edge(ta, tb)
return g
Modified renderings.
Related
I need to compute the standard deviation in a neighborhood of a point for each point in a large (10M pixel) image. The end result should produce two results:
Get a feeling what is the standard deviation for sharp vs blurred images
Produce a mask for a new image that shows blurred and sharp areas of an image
At first, I've tried this approach, but it is very slow
b_arr, g_arr, r_arr = [], [], []
pad = 3
def compute_std(img, h, w):
arr = [0, 0, 0]
for c in range(len(arr)):
arr[c] = np.std(img[h-pad:h+pad+1, w-pad:w+pad+1, c])
return arr
img = cv2.imread('image_path.png')
for h in range(pad, img.shape[0] - pad):
for w in range(pad, img.shape[1] - pad):
b, g, r = compute_std(img, h, w)
b_arr.append(b)
g_arr.append(g)
r_arr.append(r)
This approach takes minutes to produce the result.
What is the right way to compute the standard deviations for each pixel of an image quickly?
Alternatively, is it faster to generate first several layers of a CNN, turn them to a vector for each point and then use some sort of a decision tree to classify a pixel as "sharp" or "blurred"?
You can either use numpy.lib.stride_tricks.sliding_window_view or scipy.signal.convolve2d (see https://stackoverflow.com/a/25912169/13636407):
def std_windowed(img, win_size):
win_h, win_w = win_size
win_view = sliding_window_view(img, (win_h, win_w), axis=(0, 1))
return win_view.std(axis=(-2, -1))
def std_convoluted(img, win_size):
img = np.moveaxis(img, -1, 0) # HWC -> CHW
img2 = img**2
kernel = np.ones(win_size)
kernel = kernel / kernel.size
conv = lambda x: convolve2d(x, kernel, mode="valid")
img_mean = np.stack([conv(band) for band in img], axis=-1)
img2_mean = np.stack([conv(band) for band in img2], axis=-1)
return np.sqrt(np.clip((img2_mean - img_mean**2), 0, None))
The one using the convolution is ~4x faster on 10M pixels image:
# Inputs
img = get_image()
win_size = 7, 7
# Compute both ways
std_win = std_windowed(img, win_size)
std_conv = std_convoluted(img, win_size)
# Maximum absolute error
print(np.abs(std_win - std_conv).max())
# Performance
%timeit std_windowed(img, win_size)
%timeit std_convoluted(img, win_size)
1.2651919518872833e-05
13.7 s ± 213 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
2.92 s ± 90.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Plots:
fig, (ax_orig, ax_std1, ax_std2) = plt.subplots(ncols=3)
ax_orig.set_title("Original")
ax_orig.imshow(minmax_scale(img))
ax_std1.set_title("std_windowed")
ax_std1.imshow(minmax_scale(std_win))
ax_std2.set_title("std_convoluted")
ax_std2.imshow(minmax_scale(std_conv))
plt.show()
Complete code for reference:
from io import BytesIO
import matplotlib.pyplot as plt
import numpy as np
import requests
from numpy.lib.stride_tricks import sliding_window_view
from PIL import Image
from scipy.signal import convolve2d
def std_windowed(img, win_size):
win_h, win_w = win_size
win_view = sliding_window_view(img, (win_h, win_w), axis=(0, 1))
return win_view.std(axis=(-2, -1))
def std_convoluted(img, win_size):
img = np.moveaxis(img, -1, 0) # HWC -> CHW
img2 = img**2
kernel = np.ones(win_size)
kernel = kernel / kernel.size
conv = lambda x: convolve2d(x, kernel, mode="valid")
img_mean = np.stack([conv(band) for band in img], axis=-1)
img2_mean = np.stack([conv(band) for band in img2], axis=-1)
return np.sqrt(np.clip((img2_mean - img_mean**2), 0, None))
def get_image():
url = "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Firefox_brand_logo%2C_2019.svg/2048px-Firefox_brand_logo%2C_2019.svg.png"
response = requests.get(url)
img = Image.open(BytesIO(response.content))
return np.array(img)[..., :3].astype(float)
def minmax_scale(arr, *, vmin=0, vmax=1):
amin, amax = arr.min(), arr.max()
arr_std = (arr - amin) / (amax - amin)
return arr_std * (vmax - vmin) + vmin
# Inputs
img = get_image()
win_size = 7, 7
# Compute both ways
std_win = std_windowed(img, win_size)
std_conv = std_convoluted(img, win_size)
# Maximum absolute error
print(np.abs(std_win - std_conv).max())
# Plot results
fig, (ax_orig, ax_std1, ax_std2) = plt.subplots(ncols=3)
ax_orig.set_title("Original")
ax_orig.imshow(minmax_scale(img))
ax_std1.set_title("std_windowed")
ax_std1.imshow(minmax_scale(std_win))
ax_std2.set_title("std_convoluted")
ax_std2.imshow(minmax_scale(std_conv))
plt.show()
# Performance
%timeit std_windowed(img, win_size)
%timeit std_convoluted(img, win_size)
You can try to do it in the following way:
import skimage
img = cv2.imread('image_path.png')
pad = 3
c = 3
blks=skimage.util.view_as_windows(img,(pad,pad,c))
# get the image as blocks with shape (pad, pad, c)
blks = np.squeeze(blks) # squeeze the single dimension
# get std along height and width of each blk
std_view = blks.std(axis=(-3,-2))
How can I generate a price time series using the following equation:
p(t) = p0(1+A * sin(ωt +0.5η(t)))
where t ranges from 0 to 1 in 1000 time steps, p0 = 100, A = 0.1, and ω = 100. η(t) is a sequence of i.i.d Gaussian random variables with zero mean and unit variance.
I have use the code as follows to generate price, but it seems not as required. So I need helps from the community. Thanks in advance.
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt
mu = 0
sigma = 1
np.random.seed(2020)
dist = norm(loc = mu,scale=sigma)
sample = dist.rvs(size = 1000)
stock_price = np.exp(sample.cumsum())
print(stock_price)
plt.plot(stock_price)
plt.xlabel("Day")
plt.ylabel("Price")
plt.title("Simulated Stock price")
plt.show()
Assuming I haven't missed anything, this should do the trick
import numpy as np
import matplotlib.pyplot as plt
n_t = np.random.normal(0, 1, 1000)
t = np.arange(0, 1, 1/1000)
p_0, A, w = 100, 0.1, 100
ts = p_0 * (1 + A * np.sin(w * t + 0.5 * n_t))
plt.plot(t, ts)
plt.xlabel("Day")
plt.ylabel("Price")
plt.show()
which gives the plot
My trial, not sure if it's correct, welcome to give me some comments.
import numpy as np
import math
np.random.seed(2020)
mu = 0
sigma = 1
dt = 0.01
p0 = 100
A = 0.1
w = 100
N = 1000
for t in np.linspace(0, 1, 1000):
X = np.random.normal(mu * dt, sigma* np.sqrt(dt), N)
X = np.cumsum(X)
pt = p0 * (1+ A*np.sin(w*t + 0.5*X))
# print(pt)
plt.plot(pt)
plt.xlabel("Day")
plt.ylabel("Price")
plt.title("Simulated Stock price")
plt.show()
Out:
I have a SQL Database with Dates in one row and values in the other
0 2019-09-30 12:03:35 363
1 2019-09-30 12:03:35 362
2 2019-09-30 12:03:35 363
3 2019-09-30 12:03:35 363
4 2019-09-30 12:03:35 363
I want to create a graph with >1000 values. My Code works as i want it, but the labeling on the x-axis is overloaded. I searched for a solution and it should work somehow with "ticks", but I cant make it fit my specific Datetime from my database.
The x-axis Labels are crowded and not readable.
I want to Label only in specific periods.
I tried several tutorials and documentation about the "ticks" but they dont handle given Datestrings like i have in my Database already.
import sqlite3 as lite
import pandas as pd
import matplotlib as matplt
import matplotlib.pyplot as plt
from fpdf import FPDF
import numpy as np
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter, AutoMinorLocator)
datei = lite.connect("C://Users/Loos/Desktop/datenbankVersuch01.db")
conn = datei.cursor()
befehl = conn.execute('''SELECT * FROM sensorNeu''')
ausgeben = befehl.fetchall()
dataframeeins = pd.DataFrame(ausgeben)
print(dataframeeins.head(5))
print(dataframeeins.tail(5))
# info = dataframeeins[1].describe()
# print(dataframeeins.describe())
anzahlWerte = 400
periode = 400000
i = 0 # Zähler für die Werte
k = 0 # Nummerierung der Zwischenwerte
dates = []
values = []
zwischenspeicherSekunden = 0
zwischenspeicherWert = 0
for x in range(0, anzahlWerte):
# values.append(dataframeeins[1][(i * 4) + periode])
# dates.append(dataframeeins[0][(i * 4) + periode])
aktuelleZeit = dataframeeins[0][i + periode]
letzteZeichen = aktuelleZeit[17:19]
umwandeln = int(letzteZeichen)
zweiteZeit = dataframeeins[0][i + periode + 1]
letzteZeichenNeu = zweiteZeit[17:19]
umwandelnNeu = int(letzteZeichenNeu)
if k == 0:
#zwischenspeicherSekunden = umwandeln
zwischenspeicherSekunden = dataframeeins[0][i + periode]
# print(zwischenspeicherSekunden)
zwischenspeicherWert = dataframeeins[1][i+periode]
# print(zwischenspeicherWert)
k += 1
elif k != 0 and umwandeln == umwandelnNeu:
zwischenspeicherWert = (zwischenspeicherWert+dataframeeins[1][i+periode])/2
k += 1
elif k != 0 and umwandeln != umwandelnNeu:
# Wie groß ist der Abstand zwischen "umwandeln" und "umwandelnNeu"? eine oder mehrere sekunden
values.append(zwischenspeicherWert)
dates.append(zwischenspeicherSekunden)
k = 0
else:
print("FEHLER 0001: Keine Bedinung erfüllt!!!")
i += 1
aktuelleZeiten = dataframeeins[0][500000]
letzteZeichenn = aktuelleZeiten[17:19]
umwandeln = int(letzteZeichenn)
if umwandeln == 41:
print("Das letzte Zeichen ist 41")
#print(letzteZeichenn)
#print(dates[0])
#print(dates[1])
#print(dates[2])
#print(dates[3])
f, ax = plt.subplots()
# ax.set_xticks(np.arange(0))
# ax.xaxis.set_major_formatter(FormatStrFormatter('%s'))
plt.title("Der erste Versuch")
plt.suptitle("Prototyp01")
plt.plot(dates, values, marker='o', linestyle='--') # add linestyle=' ' or marker='o' or color='red'
plt.xlabel("Verlauf in Sekunden")
plt.ylabel("Sensorwert in mV/g")
plt.grid(True)
plt.show()
datei.commit()
datei.close()
How can I Label the x-Axis like just Label every 2,5 or 10 seconds and not every second?
import numpy as np
def cost_function(X,Y,B):
J = np.sum((X.T.dot(B)-Y) ** 2) / (2 * len(Y))
return J
def gradient_descent(X,Y,B,alpha,iterations):
cost_history = [0] * iterations
for iteration in range(iterations):
h = X.T.dot(B)
loss = h - Y
gradient = X.dot(loss) / len(Y)
B = B + (alpha * gradient)
cost = cost_function(X,Y,B)
cost_history[iteration] = cost
return B,cost_history
B--weights (2,1)
X--input(2,700)
Y--output(700,1)
alpha--learning rate (0.001)
iterations -- 3000
i am using cost function to calculate the error
import pandas as pd
import matplotlib.pyplot as plt
# I'm trying to code the utter basic func of LinearRegression
# from sklearn.linear_model import LinearRegression
dataframe = pd.read_fwf('brain_body.txt') # link given below
x_values = dataframe[['Brain']]
y_values = dataframe[['Body']]
lr = LinearRegression(0.0001, 10) # sending learning_rate and iterations
lr.fit(x_values, y_values)
# commenting out because the values are insane
# plt.scatter(x_values, y_values)
# plt.plot(x_values, clf.predict(x_values))
# plt.show()
Link to brain_body.txt
Here's the class I've written
class LinearRegression:
def __init__(self, learning_rate, iterations):
self.b = 0 # b as in y=mx+b
self.m = 0 # m as in y=mx+b
self.learning_rate = learning_rate
self.iterations = iterations
def get_y(self, x):
return self.m * float(x) + self.b
def step_gradient(self, x_values, y_values):
print()
print("Values before: m =", self.m, " b =", self.b)
m_gradient = 0
b_gradient = 0
N = float(len(x_values.ix[:, 0]))
print('%11s' % "d(m)", '%11s' % "m_gradient", '%11s' % "d(b)", '%11s' % "b_gradient")
for i in range(int(N)):
x = x_values.iloc[i][0]
y = y_values.iloc[i][0]
# EDIT: I missed a * -1 here
# But that wouldn't just fix everything, adjusting learning rate does
pm = (y - self.get_y(x)) * x # partial derivative of m
pb = (y - self.get_y(x)) * -1 # partial derivative of b
m_gradient += pm * 2 / N
b_gradient += pb * 2 / N
print('%11s' % pm, '%11s' % m_gradient, '%11s' % pb, '%11s' % b_gradient)
self.m -= self.learning_rate * m_gradient # adjust current m
self.b -= self.learning_rate * b_gradient # adjust current b
print("Values after: m =", self.m, " b =", self.b)
print()
def fit(self, x_values, y_values): # equivalent to train_model
for i in range(self.iterations):
self.step_gradient(x_values, y_values)
return
def predict(self, x_values): # equivalent to get_output
predictions = []
for x in x_values.ix[:, 0]:
predictions.append(self.get_y(x))
return predictions
I watched Siraj Raval's How to do Linear Regression the right way and followed almost the same way he did. I did learn what partial derivatives and gradient descents are, but I do not what the values of partial derivatives be (or to guess them). And the numbers are going like crazy in the first iteration itself:
Values before: m = 0 b = 0
d(m) m_gradient d(b) b_gradient
150.6325 4.85911290323 -44.5 -1.43548387097
7.44 5.09911290323 -15.5 -1.93548387097
10.935 5.45185483871 -8.1 -2.19677419355
196695.0 6350.45185484 -423.0 -15.8419354839
4341.435 6490.49814516 -119.5 -19.6967741935
3180.9 6593.10782258 -115.0 -23.4064516129
1456.306 6640.08543548 -98.2 -26.5741935484
5.72 6640.26995161 -5.5 -26.7516129032
243.02 6648.10930645 -58.0 -28.6225806452
2.72 6648.19704839 -6.4 -28.8290322581
0.404 6648.21008065 -4.0 -28.9580645161
5.244 6648.37924194 -5.7 -29.1419354839
6.6 6648.59214516 -6.6 -29.3548387097
0.0007 6648.59216774 -0.14 -29.3593548387
0.06 6648.59410323 -1.0 -29.3916129032
37.8 6649.81345806 -10.8 -29.74
24.6 6650.60700645 -12.3 -30.1367741935
10.71 6650.95249032 -6.3 -30.34
11723841.0 384839.371845 -4603.0 -178.823870968
0.0069 384839.372068 -0.3 -178.833548387
78394.9 387368.23981 -419.0 -192.349677419
341255.0 398376.465616 -655.0 -213.478709677
2.7475 398376.554245 -3.5 -213.591612903
1150.0 398413.651019 -115.0 -217.301290323
84.48 398416.376181 -25.6 -218.127096774
1.0 398416.408439 -5.0 -218.288387097
24.675 398417.204406 -17.5 -218.852903226
359720.0 410021.075374 -680.0 -240.788387097
84042.0 412732.107632 -406.0 -253.88516129
27625.0 413623.236665 -325.0 -264.369032258
9.225 413623.534245 -12.3 -264.765806452
81840.0 416263.534245 -1320.0 -307.346451613
38007648.0 1642316.69554 -5712.0 -491.604516129
13.65 1642317.13586 -3.9 -491.730322581
1217.2 1642356.40037 -179.0 -497.504516129
1960.0 1642419.62618 -56.0 -499.310967742
68.85 1642421.84715 -17.0 -499.859354839
0.12 1642421.85102 -1.0 -499.891612903
0.0092 1642421.85132 -0.4 -499.904516129
0.0025 1642421.8514 -0.25 -499.912580645
17.5 1642422.41591 -12.5 -500.315806452
122500.0 1646374.02882 -490.0 -516.122258065
30.25 1646375.00462 -12.1 -516.512580645
9712.5 1646688.31107 -175.0 -522.157741935
15700.0 1647194.76269 -157.0 -527.222258065
22950.4 1647935.09817 -440.0 -541.415806452
1893.725 1647996.18607 -179.5 -547.206129032
1.32 1647996.22865 -2.4 -547.283548387
4860.0 1648153.00285 -81.0 -549.896451613
75.6 1648155.44156 -21.0 -550.573870968
168.0896 1648160.8638 -39.2 -551.838387097
0.532 1648160.88096 -1.9 -551.899677419
0.09 1648160.88387 -1.2 -551.938387097
0.366 1648160.89567 -3.0 -552.03516129
0.01584 1648160.89619 -0.33 -552.045806452
34560.0 1649275.73489 -180.0 -557.852258065
75.0 1649278.15425 -25.0 -558.658709677
27040.0 1650150.41231 -169.0 -564.110322581
2.34 1650150.4878 -2.6 -564.194193548
18.468 1650151.08354 -11.4 -564.561935484
0.26 1650151.09193 -2.5 -564.642580645
213.444 1650157.97722 -50.4 -566.268387097
Values after: m = -165.015797722 b = 0.0566268387097
Values after 10 iteration: m = -1.76899770934e+22 b = 4.21166966984e+18
How do I rightly do LinearRegression from scratch?
This might not be a true answer as it's using R (I could probably figure this out in python, but it would take me longer). I think your issue is in the size of your learning_rate. I'm taking this machine learning class at the moment and so I'm familiar with what you're doing and attempted to implement it myself. Here was my code:
library(ggplot2)
## create test data
data <- data.frame(x = 1:10, y = 1:10)
n <- nrow(data)
## initialize values
m <- 0
b <- 0
alpha <- 0.01
iters <- 100
results <- data.frame(i = 1:iters,
pm = 1:iters,
pb = 1:iters,
m = 1:iters,
b = 1:iters)
for (i in 1:iters) {
y_hat <- (m * data$x) + b
pm <- (1/n) * sum((y_hat - data$y) * data$x)
pb <- (1/n) * sum(y_hat - data$y)
m <- m - (alpha * pm)
b <- b - (alpha * pb)
## uncomment if you want; shows "animated" change
## p <- ggplot(data, aes(x = x, y = y)) + geom_point()
## p <- p + geom_abline(intercept = b, slope = m)
## print(p)
## this turned out to be key for looking at output
results[i, 2:5] <- c(pm, pb, m, b)
}
Now, note the end of results with a big alpha, 0.1:
> tail(results)
i pm pb m b
95 95 -2.864612e+45 -4.114745e+44 2.135518e+44 3.067470e+43
96 96 8.390457e+45 1.205210e+45 -6.254938e+44 -8.984628e+43
97 97 -2.457567e+46 -3.530062e+45 1.832073e+45 2.631600e+44
98 98 7.198218e+46 1.033956e+46 -5.366146e+45 -7.707961e+44
99 99 -2.108360e+47 -3.028460e+46 1.571745e+46 2.257664e+45
100 100 6.175391e+47 8.870365e+46 -4.603646e+46 -6.612702e+45
See how m and b are flip flopping? The learning rate alpha is so high that alpha * derivative are jumping over the minima! In the linked class this is shown in the gradient descent videos, but the concept is the same as this image I found:
Look at results using alpha = 0.01:
> tail(results)
i pm pb m b
95 95 -0.003483741 0.02425319 0.9834438 0.1152615
96 96 -0.003476426 0.02420226 0.9834785 0.1150195
97 97 -0.003469127 0.02415144 0.9835132 0.1147780
98 98 -0.003461842 0.02410073 0.9835478 0.1145370
99 99 -0.003454573 0.02405012 0.9835824 0.1142965
100 100 -0.003447319 0.02399962 0.9836169 0.1140565
It's slow, but we're honing in on m = 1 and b = 0 as expected. With your real data, I had a similar issue. The main code body is the same, with this replacing the data <- data.frame() line at the beginning:
data <- read.table(file = "https://raw.githubusercontent.com/llSourcell/linear_regression_demo/master/brain_body.txt",
header = T, sep = "", stringsAsFactors = F)
names(data) <- c("y", "x")
Everything else is the same, except that I played with alpha and iters. Here's what I found!
## your learning rate; diverging/flip-flopping
## alpha <- 0.0001
> tail(results)
i pm pb m b
95 95 -3.842565e+190 -1.167811e+187 3.801319e+186 1.155276e+183
96 96 3.541406e+192 1.076285e+189 -3.503393e+188 -1.064732e+185
97 97 -3.263851e+194 -9.919315e+190 3.228817e+190 9.812842e+186
98 98 3.008048e+196 9.141894e+192 -2.975760e+192 -9.043766e+188
99 99 -2.772294e+198 -8.425404e+194 2.742537e+194 8.334966e+190
100 100 2.555018e+200 7.765068e+196 -2.527592e+196 -7.681718e+192
## 1/10 as big; still diverging!
## alpha <- 0.00001
> tail(results)
i pm pb m b
95 95 -2.453089e+92 -7.455293e+88 2.189776e+87 6.655047e+83
96 96 2.040052e+93 6.200012e+89 -1.821074e+88 -5.534508e+84
97 97 -1.696559e+94 -5.156089e+90 1.514452e+89 4.602638e+85
98 98 1.410902e+95 4.287936e+91 -1.259457e+90 -3.827672e+86
99 99 -1.173342e+96 -3.565957e+92 1.047397e+91 3.183190e+87
100 100 9.757815e+96 2.965541e+93 -8.710418e+91 -2.647222e+88
## even smaller; that's better!
## alpha <- 0.000001
> tail(results)
i pm pb m b
95 95 -0.01579109 51.95899 0.8856351 -0.004667159
96 96 -0.01579107 51.95894 0.8856352 -0.004719118
97 97 -0.01579106 51.95889 0.8856352 -0.004771077
98 98 -0.01579104 51.95885 0.8856352 -0.004823036
99 99 -0.01579103 51.95880 0.8856352 -0.004874995
100 100 -0.01579102 51.95875 0.8856352 -0.004926953
With this final result, I plotted the results which look reasonable?
p <- ggplot(data, aes(x = x, y = y)) + geom_point()
p <- p + geom_abline(intercept = b, slope = m)
print(p)
So, to wrap up:
I didn't verify/check your python code
I did implement my understanding of gradient descent in R and try with a test to verify behavior
I re-tried this with your actual data to find it appears to work
thus, my recommendation would be to re-try your method with simplified data (sounds like you already might have) and then look at the initial steps with a very small learning rate to see if that fixes it. If not, there may still be something wrong with your math?
Hope that helps!