En este artículo, le mostraré con un ejemplo cómo la falta de atención al código puede generar resultados incorrectos en la minería de datos.
Hay un gran curso [1] en el que los estudiantes aprenden a investigar el aprendizaje automático. Al final del semestre, los estudiantes preparan un artículo. En las conferencias, se les dice simultáneamente cómo hacerlo. Por lo general, la preparación de un artículo implica realizar un experimento con datos. Con base en los resultados del semestre, varios artículos ya están listos para ser enviados a la revista.
Entonces, en el proyecto MLDev, ayudamos a crear un repositorio de plantillas para los estudiantes de este curso. Tal plantilla, o de otra manera, una plantilla, le permitirá comenzar a trabajar en un artículo más rápido y dedicar menos tiempo a estudiar las diversas herramientas necesarias.
Mientras revisaba los trabajos para la primavera de 2020, me interesó un gráfico inusual en el trabajo “Análisis de las propiedades de un conjunto de modelos de aproximación local” [2]. El gráfico con los resultados del experimento muestra claramente una brecha en los valores de la dependencia presentada. Pero según la elección de los datos iniciales y las propiedades de esta dependencia, no debería haber una brecha en este lugar.
Es curioso comprobar por qué se obtuvo un resultado tan inesperado en el trabajo.
Repitiendo el experimento
, . , , . . , .
, , . , . .
. , , [2]. . .
Google Colab . MixtureLib
GitHub [3]. MixtureLib
. . , .
!git clone https://github.com/andriygav/MixtureLib.git
!python3 -m pip install MixtureLib/src/.
from mixturelib.localmodels import EachModelLinear
from mixturelib.hypermodels import HyperExpertNN, HyperModelDirichlet
from mixturelib.mixture import MixtureEM
. , .
correlations = []
sigmas = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
1.0,0.03,0.04,0.05,0.06,0.07,0.08,0.09,
0.15,0.25,0.35,0.45,0.55,0.65,0.75,0.85,
0.95,0.11,0.12,0.13,0.14,0.15,0.22,0.27,
0.32,0.37,0.42,0.47,0.52,0.57,0.62,0.67,
0.72,0.77,0.82,0.87,0.92,0.97]
, EachModelLinear
, . . MixtureEM
HyperNetEM
, . , . , .
torch.random.manualseed(42)
first_model = EachModelLinear(input_dim=2)
second_model = EachModelLinear(input_dim=2)
list_of_models = [firstmodel, second_model]
HpMd = HyperExpertNN(inputdim=2, hiddendim=5,outputdim=2, epochs=1000)
mixture = MixtureEM(HyperParameters={'beta': 1.},
HyperModel=HpMd,
ListOfModels=listofmodels,
modeltype='sample')
. .
for i, sigma in enumerate(sigmas):
#
x1 = np.random.normal(0, 1, (200, 1))
x2 = np.random.normal(0, 1, (200, 1))
y1 = np.array([f1(x) for x in x1])
y2 = np.array([f2(x) for x in x2])
s1 = np.random.normal(0, sigma, 200).reshape((200, 1))
s2 = np.random.normal(0, sigma, 200).reshape((200, 1))
X1 = np.hstack([x1, s1])
X2 = np.hstack([s2, x2])
X = np.vstack([X1, X2])
Y = np.hstack([y1, y2])
realsecondw = np.array([[10.], [0.]])
realfirstw = np.array([[0.], [50.]])
Xtr = torch.FloatTensor(X)
Ytr = torch.FloatTensor(Y).view([-1,1])
#
# …
for i, sigma in enumerate(sigmas):
#
# ...
#
torch.random.manual_seed(42)
mixture.fit(X_tr, Y_tr)
predicted_first_w = mixture.ListOfModels[0].W.numpy()
predicted_second_w = mixture.ListOfModels[1].W.numpy()
weights = []
weights.append([predicted_first_w[0][0], predicted_first_w[1][0]])
weights.append([predicted_second_w[0][0], predicted_second_w[1][0]])
# ,
Y1 = X.dot(weights[0])
Y2 = X.dot(weights[1])
correlations.append(cor_Pearson(Y1, Y2))
, . , . , . , , . , .
, , . . , .
. , , , . , , , . , .
fit()
MixtureEM
. , , . . .
? fit()
. MixtureLib
, fit()
. .
, fit()
fit()
scikit-learn
, . partial_fit()
(. ).
, , . . , .
, . fit()
.
, .
, , . , .
, . , .
. , , ?
, , . , .
, .
[1] “ ”, - https://m1p.org
[2] - https://github.com/Intelligent-Systems-Phystech/2020_Project-51
[3] MixtureLib
- https://github.com/andriygav/MixtureLib
[4] - https://colab.research.google.com/drive/1DZoJN32EpTZVSi2N3BduRCRf-ZST8snP#scrollTo=1JopTLX4eMnX
PD: Por supuesto, contactamos y discutimos lo que encontramos con los autores del artículo y la biblioteca MixtureLib
. Se confirmó el error. El artículo se hizo en marzo, por lo que en diciembre ya es difícil reconstruir exactamente cómo se obtuvo el gráfico original y cómo se llevó a cabo el experimento. Entonces uno se pregunta si el experimento se llevó a cabo en partes. Especialmente si prestas atención a la falta de gráficos en el cuaderno original y esta lista de sigma:
sigmas = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,
1.0,0.03,0.04,0.05,0.06,0.07,0.08,0.09,
0.15,0.25,0.35,0.45,0.55,0.65,0.75,0.85,
0.95,0.11,0.12,0.13,0.14,0.15,0.22,0.27,
0.32,0.37,0.42,0.47,0.52,0.57,0.62,0.67,
0.72,0.77,0.82,0.87,0.92,0.97]