Что-то не так с сигмовидной кривой для логистической регрессии

Я пытаюсь использовать логистическую регрессию популярности хитов на Spotify с 2010 по 2019 год на основе их продолжительности и долговечности, данные о которых собираются из файла .csv. По сути, поскольку значения популярности каждой песни являются числовыми, я преобразовал каждое из них в двоичные числа от «0» до «1». Если значение популярности хитовой песни меньше 70, я заменю его текущее значение на 0, и наоборот, если его значение больше 70. По какой-то причине, поскольку остальная часть моего кода довольно стандартна в создании сигмоида функция, конечным результатом является прямая линия вместо сигмовидной кривой.

 %matplotlib inline
 import numpy as np
 import matplotlib.pyplot as plt 
 import pandas as pd

 df = pd.read_csv('top10s [SubtitleTools.com] (2).csv')

 BPM = df.bpm
 BPM = np.array(BPM)
 Energy = df.nrgy
 Energy = np.array(Energy)
 Dance = df.dnce
 Dance = np.array(Dance)
 dB = df.dB
 dB = np.array(dB)
 Live = df.live
 Live = np.array(Live)
 Valence = df.val
 Valence = np.array(Valence)
 Acous = df.acous
 Acous = np.array(Acous)
 Speech = df.spch
 Speech = np.array(Speech)

 df.loc[df['popu'] <= 70, 'popu'] = 0

 df.loc[df['popu'] > 70, 'popu'] = 1

 def Logistic_Regression(X, y, iterations, alpha):
   ones = np.ones((X.shape[0], ))
   X = np.vstack((ones, X))
   X = X.T
   b = np.zeros(X.shape[1])

   for i in range(iterations):
     z = np.dot(X, b)
     p_hat = sigmoid(z)
     gradient = np.dot(X.T, (y - p_hat))
     b = b + alpha * gradient
     if (i % 1000 == 0):
       print('LL, i ', log_likelihood(X, y, b), i)
   return b

 def sigmoid(z):
   return 1 / (1 + np.exp(-z))

 def log_likelihood(X, y, b):
   z = np.dot(X, b)
   LL = np.sum(y*z - np.log(1 + np.exp(z)))
   return LL

 def LR1():
   Dur = df.dur
   Dur = np.array(Dur)
   Pop = df.popu

   Pop = [int(i) for i in Pop]; Pop = np.array(Pop)


   plt.figure(figsize=(10,8))
   colormap = np.array(['r', 'b'])
   plt.scatter(Dur, Pop, c = colormap[Pop], alpha = .4)
   b = Logistic_Regression(Dur, Pop, iterations = 8000, alpha = 0.00005)
   print('Done')

   p_hat = sigmoid(np.dot(Dur, b[1]) + b[0])
   idxDur = np.argsort(Dur)
   plt.plot(Dur[idxDur], p_hat[idxDur])
   plt.show()

 LR1()

 df

Текущий график

Файл CSV


person Brendan    schedule 01.01.2020    source источник
comment
поскольку ваш сигмоид выходит как ~0 или ~1 , аргумент для него (np.dot(Dur, b[1]) + b[0]) должен быть большим положительным или отрицательным значением. Возможно, вы пропустили нормализацию.   -  person jeremy_rutman    schedule 01.01.2020


Ответы (1)


Ваши параметры logreg не выводятся правильно, поэтому что-то не так в вашем градиентном спуске.

If I do

from sklearn.linear_model import LogisticRegression    
df = pd.DataFrame({'popu':[0,1,0,1,1,0,0,1,0,0],'dur'[217,283,200,295,221,176,206,260,217,213]})
logreg = LogisticRegression()
logreg.fit(Dur.reshape([10,1]),Pop.reshape([10,1]))
print(logreg.coef_)
print(logreg.intercept_)

Я получаю [0,86473507, -189,79655798]

тогда как ваши параметры (b) выходят [0,012136874150412973 -0,2430389407767768] для этих данных.

График ваших логов против scikit здесь

person jeremy_rutman    schedule 01.01.2020