Ola92
Ola92

Reputation: 1

Why when I press button "run" in python it does not give any output?

I have started a python course few days ago. I am having problems with my loop in the python assignment which is:

Given a set of N measurements, (r1, r2, . . . , rN ), we will initially assign the odd-numbered measurements to class 1 and the even numbered measurements to class 2. Then the following two steps are repeated:

• Update step: Compute the mean value (average) of the measurements within each cluster.

• Assignment step: Assign each measurement to the cluster with the closest mean value. In case of a tie, assign the measurement to cluster 1.

Repeat the above steps until the cluster assignments do not change. It can not be determined in advance how many steps will be needed before the clustering assignment stabilizes.

Problem definition Create a function that takes as an input a vector of reflectance measurements and returns a vector of cluster assignments computed using the algorithm described above.

I have created a code:

import numpy as np
import math
def clusterAnalysis(reflectance):
    ref=np.size(reflectance)# all N measurements
    even=np.any(ref %2==0)# N measurements are even numbers
    uneven=np.any(ref%2>0)# N measurements are odd number
    mean1=np.mean(even)#average of even numbers in cluster 2
    mean2=np.mean(uneven)# average of odd numbers in cluster 1
    sub1=abs(ref-mean1)
    sub2=abs(ref-mean2)
    while sub1<=sub2:
        clusterAssigment="1"
    else:
        clusterAssigment="2"
    return clusterAssigments
#print(clusterAnalysis(np.array([1.7, 1.6, 1.3, 1.3, 2.8, 1.4,
#2.8, 2.6, 1.6, 2.7])))

**New code:

import math
def clusterAnalysis(reflectance):
    reflectance=np.arange(reflectance.size)
    evens =reflectance % 2 == 0 # N measurements are even numbers
    clusters = np.ones(reflectance.shape)
    clusters[evens] = 2
    while True:
        mean_even=np.mean(reflectance[evens])
        mean_odd=np.mean(reflectance[np.logical_not(evens)])
        diff_even = np.abs(reflectance - mean_even) 
        diff_odd = np.abs(reflectance - mean_odd)
        new_clusters= np.ones(reflectance.shape)
        new_clusters[diff_even < diff_odd] = 2
        clusterAssigments= new_clusters

        if np.all(clusters == new_clusters):
            break
        clusters = new_clusters
        clusterAssigments= new_clusters
    return clusterAssigments 
print(clusterAnalysis(np.array([1.7, 1.6, 1.3, 1.3, 2.8, 1.4,2.8, 2.6, 1.6, 2.7])))```**



The code above does not work at all. My output should be :`2 2 2 2 1 2 1 1 2 1 `
I have been working on this for last 2 days and I just dont know what I am doing wrong...

Upvotes: 0

Views: 152

Answers (1)

n00dle
n00dle

Reputation: 6043

Your while loop never ends. You never modify sub1 or sub2, so the while loop just spins and spins and sub1 is always less than sub2.

The problem you've got is that at each iteration of the while loop, you to work out the new clusters, based on the mean from the old clusters, then check if they've changed.

You're right that you need a while loop, you can use something like this:

def clusterAnalysis(reflectance):
    # Work out your odd/even clusters to start it off
    # EDIT: I misread how this bit works - see the update.
    # You don't want to use the size here:
    #     you want to use a list of numbers the size
    # of reflectance [0, 1, 2, ..., n]
    even_numbers = np.arange(reflectance.size) % 2 == 0

    # Now we'll create an array to hold the cluster ids, that's the
    # same shape as reflectance.
    # By default it'll store ones. Then we'll change all the entries
    # for even numbers to hold twos
    clusters = np.ones(reflectance.shape)

    # This uses what's called "logical indexing" - it'll change all the elements
    # that equal "true" in even_numbers
    clusters[even_numbers] = 2

    # This will create a never-ending while loop, but we'll manually
    # end it using 'break'
    while True:
        # Work out the new clusters, by working out the means of the two 
        # clusters and finding the closest to the reflectance numbers
        # Clue: You can use logical indexing here like we did above
        cluster_1_mean = ...
        cluster_2_mean = ...
        new_clusters = ...

        # This is the really important bit - we've created the new array 
        # `new_clusters` above and we want to check if it's the same as 
        # the last one. If it is, we'll use `break` which tells python
        # to stop doing the loop now.
        if np.all(clusters == new_clusters):
            break

        # We'll only reach here if we haven't called 'break' - so we'll update with the new clusters and we can go again
        clusters = new_clusters

    # Once the while loop is finished, we should return the clusters array.
    return clusters

EDIT: I'll try to give you the pieces of the puzzle for the clustering bit.

Lets say I have two list of 20 random numbers between 0 and 200, and I want to get the mean of the odd and even values:

x = np.random.randint(200, size=(20))

# Just like above, we'll get the id of each element in an array [0, 1, ..., 20]
x_ids = np.arange(x.size)
evens = x_ids % 2 == 0

# We'll get the mean of all the even `x`'s
mean_even = np.mean(x[evens])

# And we can do it the other way round for the odds
mean_odd = np.mean(x[np.logical_not(evens)])

Another edit:

OK, last puzzle piece :)

So we want to find which of x is closest to mean_even and which is closest to mean_odd. We can do something similar to your original attempt:

diff_even = np.abs(x - mean_even) 
diff_odd = np.abs(x - mean_odd)

# Start by creating a new clusters array, just like we did before,
# where all the ids are originally set to `1`.    
new_clusters = np.ones(x.shape)

# Now get the numbers closest to `diff_even` and set their cluster to
# two.
# Because we're using less-than, it means that any that are equally
# close to both means will stay in cluster one. If we wanted it to
#  work so they went to cluster 2 by default, we could use `<=`.
new_clusters[diff_even < diff_odd] = 2

You'll need to change some variable names around to use logical indexing to get the means from the clusters array instead of the evens array, but this should give you basically everything you need.

Note that I made a mistake earlier when I did the mean_odd. I broke the logical indexing by accidentally turning the boolean array into numbers, which is why I've updated it to use np.logical_not. I can explain how that works in more detail if of interest.

Upvotes: 1

Related Questions