我正在尝试预测互联网帖子的趋势。
发布2分钟后,我可以获得该帖子的评论和投票数(可以更改,但应该足够)。
当前我使用以下公式:
predicted_votes = (votes_per_minute + n_comments * 60 * h) * k
然后我通过实验找到了k
。我收到了发布数据,请等待一个小时,然后执行
k = (older_k + actual_votes/predicted_votes) / 2
以此类推。这种作品。准确率很低(40-50%),但是它使我对帖子的反应情况有了一个大概的认识。
我想知道是否可以采用更复杂的方程式,例如:
predicted_votes = ((votes_per_minute * x + n_comments * y) * 60 * hour) * k # Hour stands for 'how many hours to predict'
然后优化参数以使其更好一点。
我认为我可以使用机器学习,尽管我没有可用的GPU(是的,我在集成显卡上运行,怪莫哈韦),所以我正在尝试这种方法。
所以问题归结为,如何优化这些参数(k,x,y
)以获得更好的准确性?
编辑:
我尝试遵循@Alexis所说的,这就是我现在的位置:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
initial_votes_list = [1.41, 0.9, 0.94, 0.47, 0]
initial_comment_list = [0, 3, 0, 1, 64]
def func(x, k, t, s):
votes_per_minute = x[0]
n_comments = x[1]
return ((votes_per_minute * t + n_comments * s) * 60) * k
xdata = [1.41,0]
y = func(xdata, 2.5, 1.3, 0.5)
np.random.seed(1729)
ydata = y + 5
plt.plot(xdata, ydata, 'b-', label='data')
popt, pcov = curve_fit(func, xdata, ydata)
plt.plot(xdata, func(xdata, *popt), 'g--',
label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.xlabel('Time')
plt.ylabel('Score')
plt.legend()
plt.show()
我不确定如何填充我拥有的数据(votes_per_minute,n_comments),也不确定如何告诉算法y
轴实际上是时间。
编辑2:
尝试执行@Alexis告诉我的操作,但是我不确定用什么作为actual_score
,一个数字不起作用,一个列表也不起作用。此外,我想预测“分数”而不是数字评论。
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
initial_votes_list = [1.41, 0.9, 0.94, 0.47, 0]
initial_comment_list = [0, 3, 0, 1, 64]
final_score = [26,12,13,14,229]
def func(x,k,t,s):
return ((x[0]*k+x[1]*t)*60*x[2])*s
X = [[a,b,c] for a,b,c in zip(initial_votes_list,initial_comment_list,[i for i in range(len(initial_votes_list))])]
y = actual_votes # What is this?
popt, pcov = curve_fit(func, X, y)
plt.plot(xdata, func(xdata, *popt), 'g--',
label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
plt.xlabel('Time')
plt.ylabel('Score')
plt.legend()
plt.show()
答案 0 :(得分:4)
您不需要ML来这样做(我认为这里过分杀伤力)。 Scipy提供了一种简便的方法来使曲线适合您的观测结果。
scipy.optimize.curve_fit允许您将参数未知的函数拟合到观察结果中。您已经知道该函数的一般形式,优化超参数是一个众所周知的统计问题,因此scipy应该足够了。
我们可以举一个小例子来说明这一点: 首先我们生成数据
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.optimize import curve_fit
>>>
>>> def func(x, a, b, c):
... return a * np.exp(-b * x) + c
定义数据以使其具有一定的噪声:
>>> xdata = np.linspace(0, 4, 50)
>>> y = func(xdata, 2.5, 1.3, 0.5)
>>> np.random.seed(1729)
>>> y_noise = 0.2 * np.random.normal(size=xdata.size)
>>> ydata = y + y_noise
>>> plt.plot(xdata, ydata, 'b-', label='data')
然后使用scipy将函数(ax + b = y)拟合到数据:
popt, pcov = curve_fit(func, xdata, ydata)
您可以为此添加约束,但是对于您的问题,这不是必需的。 顺便说一句,此示例位于我提供的链接的末尾。您可以在此页面上找到使用曲线拟合的所有知识。
修改
看来您很难弄清楚如何使用它。让我们慢慢地分析,以确保我们在每个步骤中都可以:
y
。我们都知道。没有计算votes_per_minute
,n_comments
和小时h (x,y,k)
的三个参数因此X[i]
(一个示例)应如下所示:[votes_per_minute,n_comments,h]
并使用您的公式y =((votes_per_minute * k + n_comments * t)* 60 * h)* s,方法是替换名称:
def func(x,k,t,s):
return ((x[0]*k+x[1]*t)*60*x[2])*s
X = np.array([[a,b,c] for a,b,c in zip(initial_votes_list,initial_comment_list,[i for i in range(len(initial_votes_list))])]).T
y = score
然后:
popt, pcov = curve_fit(func, X, y)
(如果我了解您的问题...否则,我看不出问题出在哪里)
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
initial_votes_list = [1.41, 0.9, 0.94, 0.47, 0]
initial_comment_list = [0, 3, 0, 1, 64]
final_score = [26,12,13,14,229]
def func(x,k,t,s):
return ((x[0]*k+x[1]*t)*60*x[2])*s
X = np.array([[a,b,c] for a,b,c in zip(initial_votes_list,initial_comment_list,[i for i in range(len(initial_votes_list))])]).T
y = [0.12,0.20,0.5,0.9,1]
popt, pcov = curve_fit(func, X, y)
print(popt)
>>>[-6.65969099e+00 -6.99241803e-02 -9.33412000e-04]