Scikit-learn: فشلت خوارزمية EM في GMM لمجموعات البيانات أحادية البعد باستخدام 0.16.1 (ولكن جيدة مع 0.15.2)

تم إنشاؤها على ١٣ مايو ٢٠١٥  ·  4تعليقات  ·  مصدر: scikit-learn/scikit-learn

يؤدي تركيب توزيع غاوسي أحادي البعد باستخدام GMM.fit () إلى حدوث خطأ في وقت التشغيل باستخدام الإصدار 0.16.1 من scikit-Learn ، ولكنه ينتج معلمات مناسبة باستخدام 0.15.2.

مثال قصير لتوضيح المشكلة:

import sklearn
from sklearn import mixture
import numpy as np
from scipy import stats
import sys

# the version info 
print("Python version: %s.%s" %(sys.version_info.major, sys.version_info.minor))
print("scikit-learn version: %s" %(sklearn.__version__))

# some pretend data
np.random.seed(seed=0)
data = stats.norm.rvs(loc=100, scale=1, size=1000)
print("Data mean = %s, Data std dev = %s" %(np.mean(data), np.std(data)))

# Fitting using a GMM with a single component
clf = mixture.GMM(n_components=1)
clf.fit(data)
print(clf.means_, clf.weights_, clf.covars_)

يؤدي تشغيل رمز المثال هذا باستخدام scikit-Learn 0.15.2 إلى إنتاج الإخراج الصحيح:

Python version: 3.4
scikit-learn version: 0.15.2
Data mean = 99.9547432925, Data std dev = 0.987033158669
[[ 99.95474329]] [ 1.] [[ 0.97523446]]

ومع ذلك ، فإن نفس الكود تمامًا باستخدام scikit-Learn 0.16.1 يعطي هذا التتبع:

Python version: 3.4
scikit-learn version: 0.16.1
Data mean = 99.9547432925, Data std dev = 0.987033158669
/home/rebecca/anaconda/envs/new_sklearn/lib/python3.4/site-packages/numpy/lib/function_base.py:1890: RuntimeWarning: Degrees of freedom <= 0 for slice
  warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
/home/rebecca/anaconda/envs/new_sklearn/lib/python3.4/site-packages/numpy/lib/function_base.py:1901: RuntimeWarning: invalid value encountered in true_divide
  return (dot(X, X.T.conj()) / fact).squeeze()
Traceback (most recent call last):
  File "test_sklearn.py", line 18, in <module>
    clf.fit(data)
  File "/home/rebecca/anaconda/envs/new_sklearn/lib/python3.4/site-packages/sklearn/mixture/gmm.py", line 498, in fit
    "(or increasing n_init) or check for degenerate data.")
RuntimeError: EM algorithm was never able to compute a valid likelihood given initial parameters. Try different init parameters (or increasing n_init) or check for degenerate data.

لقد جربت قيمًا مختلفة مختلفة لمعلمات n_init و n_iter و covariance_type. لقد جربت أيضًا مجموعة من مجموعات البيانات المختلفة. كل هذا يؤدي إلى هذا الخطأ أو ما شابه باستخدام 0.16.1 ، ولكن لا توجد مشكلات على الإطلاق باستخدام 0.15.2. يبدو أن المشكلة مرتبطة بالمعلمات الأولية المستخدمة في تعظيم التوقع ، لذلك من المحتمل أن يكون هذا مرتبطًا بهذه المشكلة: # 4429

في حال كانت هذه معلومات مفيدة ، كنت أستخدم بيئة افتراضية أناكوندا مع تثبيت نظيف لبرنامج scikit-Learn ، تم إعداده على النحو التالي (للإصدار 0.16.1):

conda create -n new_sklearn python=3.4
source activate new_sklearn
conda install sklearn
Bug

التعليق الأكثر فائدة

من المحتمل أن يكون هذا مشكلة في شكل البيانات.
هل لديك X 1 ndim أم 2 ndim؟
قد يكون هناك تغيير غير مقصود في السلوك بين 0.15 و 0.16 ، لكنني أعتقد أننا قررنا أنه في المستقبل ، لن ندعم إدخال 1ndim ، لذلك يجب أن يكون شكل الإدخال الخاص بك X.shape = (n_samples, 1) .
يمكنك ان تفعل

X = X.reshape(-1, 1)

وإلا فإنه يكون غامضًا إلى حد ما إذا كنت تقصد عينة واحدة أو ميزة واحدة.

ال 4 كومينتر

من المحتمل أن يكون هذا مشكلة في شكل البيانات.
هل لديك X 1 ndim أم 2 ndim؟
قد يكون هناك تغيير غير مقصود في السلوك بين 0.15 و 0.16 ، لكنني أعتقد أننا قررنا أنه في المستقبل ، لن ندعم إدخال 1ndim ، لذلك يجب أن يكون شكل الإدخال الخاص بك X.shape = (n_samples, 1) .
يمكنك ان تفعل

X = X.reshape(-1, 1)

وإلا فإنه يكون غامضًا إلى حد ما إذا كنت تقصد عينة واحدة أو ميزة واحدة.

نعم ، بمجرد إعادة تشكيل بيانات الإدخال ، فإنها تعمل بشكل جيد. شكرا لك!

مرحبًا ، الكود أعلاه يصلح الخطأ ، لكن السلوك مختلف على ما أعتقد. أقوم بتشغيل هذا الكود التعليمي ولكن بعد إعادة تشكيل بيانات الإدخال ، لا يمكنني إعادة إنتاج المؤامرة.

هل هناك شيء يمكنني تغييره (المعلمات ، ربما) حتى أحصل على نفس النتيجة؟ شكرا!

imadie

في البرنامج التعليمي ، أشار التغيير إلى الأسطر التالية إلى:

clf = GMM (4، n_iter = 500، random_state = 3)
x.shape = (x.shape [0] ، 1)
clf = clf.fit (x)

xpdf = np.linspace (-10، 20، 1000)
xpdf.shape = (xpdf.shape [0]، 1)
الكثافة = np.exp (clf.score (xpdf))

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات