实施类似于机器学习的优化器

A. *_*ion 5 python machine-learning

我正在尝试预测互联网发布的趋势。

发布2分钟后,我可以获得该帖子的评论和投票数(可以更改,但应该足够了)。

目前,我使用以下公式:

predicted_votes = (votes_per_minute + n_comments * 60 * h) * k
Run Code Online (Sandbox Code Playgroud)

然后我k通过实验找到了。我收到了发布数据,请等待一个小时,然后执行

k = (older_k + actual_votes/predicted_votes) / 2
Run Code Online (Sandbox Code Playgroud)

等等。这种作品。准确性非常低(40-50%),但它使我对帖子的反应情况有了一个大概的了解。

我想知道是否可以采用更复杂的方程式,例如:

predicted_votes = ((votes_per_minute * x + n_comments * y) * 60 * hour) * k # Hour stands for 'how many hours to predict'
Run Code Online (Sandbox Code Playgroud)

然后优化参数以使其更好一些。

我假设我可以使用机器学习,尽管我没有可用的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()
Run Code Online (Sandbox Code Playgroud)

我不确定如何填充我拥有的数据(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()
Run Code Online (Sandbox Code Playgroud)

Ale*_*xis 4

你不需要机器学习来做到这一点(我认为这里太过分了)。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
Run Code Online (Sandbox Code Playgroud)

定义数据以适应一些噪音:

>>> 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')
Run Code Online (Sandbox Code Playgroud)

然后我们使用 scipy 将函数 (ax+b=y) 拟合到数据:

popt, pcov = curve_fit(func, xdata, ydata)
Run Code Online (Sandbox Code Playgroud)

您可以为此添加约束,但对于您的问题来说,这是没有必要的。顺便说一下,这个例子位于我提供的链接的末尾。您应该了解的使用曲线拟合的所有信息都可以在此页面上找到。

编辑

您似乎很难弄清楚如何使用它。让我们慢慢地进行分析,以确保我们每一步都没有问题:

  • 你想预测评论数量,这是你的y。我们都知道。未计算
  • 您在条目中有三个参数: 、votes_per_minuten_comments小时 h
  • 最后但并非最不重要的一点是,函数有三个参数(x,y,k)

所以X[i](一个样本)应该如下所示:[votes_per_minute,n_comments,h] 并使用公式 y = ((votes_per_一分钟 * 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 
Run Code Online (Sandbox Code Playgroud)

进而:

popt, pcov = curve_fit(func, X, y) 
Run Code Online (Sandbox Code Playgroud)

(如果我理解你的问题......如果不理解,我不明白问题出在哪里)

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]
Run Code Online (Sandbox Code Playgroud)