2017-03-29 19 views
0

Mean of empty slice実行時の警告が表示されています。 私の変数が何であるか(numpy配列)を印刷すると、 にはnanの値が含まれています。ランタイム警告は、問題として 行を見ています。それを機能させるために私は何を変えることができますか?NANの問題を防ぐにはどうしたらいいですか?

プログラムが問題なく実行されることがあります。ほとんどの時間は ではありません。

これは、虹彩データセット をクラスタリングするスクラッチアルゴリズムからのK-Meansアルゴリズムです。最初に、ユーザに希望の重心(クラスタ)の セントロイドの量を入力するよう促します。次に、ロードされた の数から、指定された範囲内の前記 の数のクラスタをランダムにテキストファイルに生成する。

無限の ループを防ぐために、elseステートメントにブレーク値があります。

セントロイドをファイルのデータポイントから差し引くと、数値がゼロ以下になるためですか?

私が実行したときに私が取得エラー:

How Many Centrouds? 3 
Dimensionality of Data: (150, 4) 
Starting Centroiuds: 
[[ 1.4 7.9 0.2 3.4] 
[ 7.8 0.2 4.3 1.4] 
[ 5.7 6.9 3. 6.6]] 
t0 : 
[[[-3.7 4.4 -1.2 3.2] 
    [ 2.7 -3.3 2.9 1.2] 
    [ 0.6 3.4 1.6 6.4]] 

[[-3.5 4.9 -1.2 3.2] 
    [ 2.9 -2.8 2.9 1.2] 
    [ 0.8 3.9 1.6 6.4]] 

[[-3.3 4.7 -1.1 3.2] 
    [ 3.1 -3. 3. 1.2] 
    [ 1. 3.7 1.7 6.4]] 

..., 
[[-5.1 4.9 -5. 1.4] 
    [ 1.3 -2.8 -0.9 -0.6] 
    [-0.8 3.9 -2.2 4.6]] 

[[-4.8 4.5 -5.2 1.1] 
    [ 1.6 -3.2 -1.1 -0.9] 
    [-0.5 3.5 -2.4 4.3]] 

[[-4.5 4.9 -4.9 1.6] 
    [ 1.9 -2.8 -0.8 -0.4] 
    [-0.2 3.9 -2.1 4.8]]] 

Warning (from warnings module): 
    File "C:\Python27\lib\site-packages\numpy\core\_methods.py", line 59 
    warnings.warn("Mean of empty slice.", RuntimeWarning) 
RuntimeWarning: Mean of empty slice. 

Warning (from warnings module): 
    File "C:\Python27\lib\site-packages\numpy\core\_methods.py", line 68 
    ret, rcount, out=ret, casting='unsafe', subok=False) 
RuntimeWarning: invalid value encountered in true_divide 
--------------- 
Starting Centroids: 

[[ 1.4 7.9 0.2 3.4] 
[ 7.8 0.2 4.3 1.4] 
[ 5.7 6.9 3. 6.6]] 


Starting NewMeans: 

[[  nan   nan   nan   nan] 
[ 5.84333333 3.054  3.75866667 1.19866667] 
[  nan   nan   nan   nan]] 
Starting Centroids Now: 

[[  nan   nan   nan   nan] 
[ 5.84333333 3.054  3.75866667 1.19866667] 
[  nan   nan   nan   nan]] 


NewMeans now: 
[[  nan   nan   nan   nan] 
[ 5.84333333 3.054  3.75866667 1.19866667] 
[  nan   nan   nan   nan]] 

Pythonのコード:

import numpy as np 
from pprint import pprint 
import random 
import sys 
import warnings 

arglist = sys.argv 

#UNCOMMENT BELOW IN FINAL PROGRAM 
''' 
NoOfCentroids = int(arglist[2]) 
dataPointsFromFile = np.array(np.loadtxt(sys.argv[1], delimiter = ',')) 
''' 

dataPointsFromFile = np.array(np.loadtxt('iris.txt', delimiter = ',')) 

NoOfCentroids = input('How Many Centrouds? ') 

dataRange = ([]) 

#UNCOMMENT BELOW IN FINAL PROGRAM 
''' 
with open(arglist[1]) as f: 
    print 'Points in data set: ',sum(1 for _ in f) 
''' 
dataRange.append(round(np.amin(dataPointsFromFile),1)) 
dataRange.append(round(np.amax(dataPointsFromFile),1)) 
dataRange = np.asarray(dataRange) 

dataPoints = np.array(dataPointsFromFile) 
print 'Dimensionality of Data: ', dataPoints.shape 

randomCentroids = [] 
data = ([]) 
templist = [] 
i = 0 

while i<NoOfCentroids: 
    for j in range(len(dataPointsFromFile[1,:])): 
     cat = round(random.uniform(np.amin(dataPointsFromFile),np.amax(dataPointsFromFile)),1) 
     templist.append(cat) 
    randomCentroids.append(templist) 
    templist = [] 
    i = i+1 

centroids = np.asarray(randomCentroids) 

def kMeans(array1, array2): 
    ConvergenceCounter = 1 
    keepGoing = True 
    StartingCentroids = np.copy(centroids) 
    print 'Starting Centroiuds:\n {}'.format(StartingCentroids) 
    while keepGoing:  
     #--------------Find The new means---------# 
     t0 = StartingCentroids[None, :, :] - dataPoints[:, None, :] 
     print 't0 :\n {}'.format(t0) 
     t1 = np.linalg.norm(t0, axis=-1) 
     t2 = np.argmin(t1, axis=-1) 
     #------Push the new means to a new array for comparison---------# 
     CentroidMeans = [] 
     for x in range(len(StartingCentroids)): 
      CentroidMeans.append(np.mean(dataPoints[t2 == [x]], axis=0)) 
     #--------Convert to a numpy array--------# 
     NewMeans = np.asarray(CentroidMeans) 
     #------Compare the New Means with the Starting Means------# 
     if np.array_equal(NewMeans,StartingCentroids): 
      print ('Convergence has been reached after {} moves'.format(ConvergenceCounter)) 
      print ('Starting Centroids:\n{}'.format(centroids)) 
      print ('Final Means:\n{}'.format(NewMeans)) 
      print ('Final Cluster assignments: {}'.format(t2)) 
      for x in xrange(len(StartingCentroids)): 
       print ('Cluster {}:\n'.format(x)), dataPoints[t2 == [x]] 
      for x in xrange(len(StartingCentroids)): 
       print ('Size of Cluster {}:'.format(x)), len(dataPoints[t2 == [x]]) 
      keepGoing = False 
     else: 
      print 15*'-' 
      ConvergenceCounter = ConvergenceCounter +1 
      print 'Starting Centroids:\n' 
      print StartingCentroids 
      print '\n' 
      print 'Starting NewMeans:\n' 
      print NewMeans 
      StartingCentroids =np.copy(NewMeans) 
      print 'Starting Centroids Now:\n' 
      print StartingCentroids 
      print '\n' 
      print 'NewMeans now:' 
      print NewMeans 
      break 


kMeans(centroids, dataPoints) 
+0

'data =([])'では、 '()'は何もしません。 '([]、)'は1要素タプルを作成しますが、それはあなたが望むものではないと思います。 'templist'のように、' data = [] 'で十分です。コードの後半で 'data'を使用しますか? – hpaulj

答えて

0

私は一致(t2 == [x]がすべてFalseの場合は、警告が

np.mean(dataPoints[t2 == [x]], axis=0) 

で起動します負うものではありませんt2xの間であれば、dataPoints[...]となります空の配列であると、meanという警告が表示されます。

私はあなたがそのテストにもっと注意する必要があると思います。マスクされた配列が空の場合は、meanをスキップすることもできます。

==浮動小数点のテストは予測できません。公差で同等性をテストするには、np.iscloseまたはnp.allcloseのようなものを使用する必要があります。

mean計算の後半から、おそらく0で除算しようとすると、要素の数が2番目の警告になります。

フルmeanコードはnumpy.core._methods.pyにあります。

つまり、meanの空の配列を使用しないでください。

+0

お返事ありがとうございます!残念ながら、等価性をテストするときには、正確である必要があります。平均スライスエラーがあるかどうかをチェックし、動作するまで異なる開始セントロイドでプログラムを再実行すると、例外処理を行う方法がありますか? – cparks10

+0

'np.any(t2 == [x])'が 'mean'を取る場合は、それをスキップします。 – hpaulj

+0

ありがとう!それは動作します!それが私に残る唯一の問題は、私がプログラムの始めに求められているセントロイドの量で終わらないということです。どのように私はそれを修正するだろうか? – cparks10

関連する問題