Python sklearn OneHotEncoding categorical and sometimes repeated values - python

This is my problem with sklearn's OneHotEncoder.
with an array a = [1,2,3,4,5,6,7,8,9,22] i.e ALL UNIQUE of a.shape=[10,1] (after reshape(-1,1), a [10,10] matrix of OneHotEncoded values is returned.
array([[ 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[ 0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
[ 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]])
But with an array like a = [1,2,2,4,4,6,7,8,9,22] i.e NON UNIQUE of a.shape=[10,1] (after reshape(-1,1), a [10,8] matrix of OneHotEncoded values is returned.
array([[ 1., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 0., 1., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 1.]])
But I cannot use this as my input placeholder expects a [10,10] matrix as input. Can anyone help me handle non-unique values in sklearn's OneHotEncoder?
P.S Adding the parameter n_values= 10 gives an error saying ValueError: Feature out of bounds for n_values=10

Do you know all the values your categorical feature can take? If so, you can do something like this:
enc = OneHotEncoder()
enc.fit(np.asarray([1,2,3,4,5,6,7,8,9,22]).reshape(-1, 1)) #fit your encoder to the values
data_for_encoding = np.asarray([1,2,2,4,4,6,7,8,9,22]).reshape(-1, 1) #your data
sparse_matrix = enc.transform(data_for_encoding) #encoded data

Related

Batching irregularities with data loader

I have some data in .txt files and an instance formed by two lines which both have 100 elements in them. First line defines the problem and the second line defines the solution. Even though it is not a great idea I tried to use a supervised setting among the data. However, I am facing problems with batching. I have added the code for both the data loader and the main for loop that does the job.
The problem I get is that if
I set the batch_size to 5 and preds array has the correct form. However, labels array has one more dimension and instead of having 5 integers in it, it has 5 complete problem solutions.
I believe the problem is in the data loader but couldn't solve it. I am kinda new to the concept, I have been trying to find this for over a week but nothing has settled so far.
Data Loader:
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import pdb
import numpy as np
from torch.utils.data import Dataset
class load_dataset(Dataset):
def __init__(self, data_file='data.txt', transform=None):
super().__init__()
data = np.loadtxt(data_file)
data = torch.Tensor(data)
self.data = data[::2]
self.targets = data[1::2]
def __len__(self):
return len(self.targets)
def __getitem__(self, index):
adj, target = self.data[index], self.targets[index]
return adj, target
Main Loop:
for inputs, labels in loaders["train"]:
inputs, labels = inputs.view([batch_size, 100]), labels.data
scores = mps(inputs)
_, preds = torch.max(scores, 1)
print("preds: ")
print(preds)
print("labels: ")
print(labels)
Output:
preds:
tensor([0, 0, 0, 0, 0])
labels:
tensor([[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.,
0., 1., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,
0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.,
0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.,
0., 0., 0., 0., 1., 0., 0., 0., 0., 0.]])
You haven't shown how you defined your dataloader, but assuming you are wrapping load_dataset with a torch.utils.data.DataLoader and setting batch_size=5.
If you set your batch size to 5, then you will have 5 "problems" and the corresponding 5 "solutions" in a single batch. Each having 100 components. This means inputs and labels will be two tensors shaped as (batch_size=5, 100).

Is there a way of reshaping a multidimensional array into a 1-D Vector in Python?

so I'm trying to turn this array
array([[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.,1.],
[0., 0., 0., 0., 0., 0., 1., 0., 0.,0.]])
[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.]])
into this array
array([ 0, 4, 9, 6, 0])
So each row of the original array, is replaced with a single value that is equal to where the "1" is located in the row.
You can use numpy.argmax:
a = np.array([[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.,1.],
[0., 0., 0., 0., 0., 0., 1., 0., 0.,0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.]])
print( np.argmax(a, axis=1) )
Prints:
[0 3 9 6 0]
Try this:
array = np.array([[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 1., 0., 0., 0., 0., 0.,0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0.,1.],
[0., 0., 0., 0., 0., 0., 1., 0., 0.,0.],
[1., 0., 0., 0., 0., 0., 0., 0., 0.,0.]])
print(np.where(array == 1)[1]
Output:
array([0, 3, 9, 6, 0])

How can I element-wise multiply tensors with different dimensions?

I have a tensor expanded_mask, which has a size of torch.Size([1, 208]) and another one inputs which has a size of torch.Size([1, 208, 161]).
I want to elementwise multiply expanded_mask and input such that all 161 elements of the third dimension are multiplied with the 208 elements of expanded_mask.
As per jodag's answer, I tried:
masked_inputs = expanded_mask.unsqueeze(2) * inputs
inputs is:
tensor([1.8851e-02, 4.4921e-02, 7.5260e-02, 3.8994e-02, 3.5651e-02, 3.0457e-02,
1.2933e-02, 2.5496e-02, 2.3260e-04, 2.4903e-03, 6.5678e-03, 1.0501e-02,
1.2387e-02, 1.9434e-03, 1.0831e-03, 6.5691e-03, 5.3792e-03, 9.1925e-03,
1.8146e-03, 4.9215e-03, 1.4623e-03, 9.4454e-03, 1.0504e-03, 3.3749e-03,
2.1361e-03, 8.0782e-03, 1.7916e-03, 1.1577e-03, 1.1246e-04, 2.2520e-03,
2.2255e-03, 2.1072e-03, 9.8782e-03, 2.2909e-03, 2.9957e-03, 5.8540e-03,
1.1067e-02, 9.0582e-03, 5.6360e-03, 6.3841e-03, 5.9298e-03, 1.9501e-04,
2.7967e-03, 3.5786e-03, 9.2363e-03, 8.3934e-03, 8.8185e-04, 5.4591e-03,
2.2451e-04, 2.2307e-03, 2.4871e-03, 3.6736e-03, 1.3842e-04, 2.7455e-03,
6.2199e-03, 1.1924e-02, 9.5953e-03, 1.6939e-03, 4.1919e-04, 9.3509e-05,
1.8351e-03, 6.3350e-04, 1.1076e-03, 1.5472e-03, 1.2104e-03, 3.1803e-04,
8.6507e-04, 3.0083e-03, 2.8435e-03, 1.6740e-03, 8.1023e-05, 7.5767e-04,
9.1442e-04, 2.0204e-03, 1.3987e-03, 3.7729e-03, 5.2012e-04, 2.0367e-03,
1.5177e-03, 1.6948e-03, 9.5833e-04, 1.2050e-03, 1.8356e-03, 9.4503e-04,
4.8612e-04, 1.6844e-04, 1.2222e-04, 1.7526e-03, 2.6397e-04, 1.3026e-03,
1.0704e-03, 3.6407e-04, 1.3135e-03, 2.6665e-03, 1.8639e-03, 3.0385e-05,
1.0212e-03, 7.6236e-04, 1.7878e-03, 2.4298e-03, 7.2158e-05, 1.2488e-03,
2.1347e-03, 3.9256e-03, 3.1436e-03, 3.1648e-03, 3.4657e-03, 1.3746e-03,
1.6927e-03, 1.0794e-03, 8.8152e-04, 1.1757e-04, 3.2254e-04, 4.1866e-04,
9.2787e-04, 2.0020e-03, 1.4813e-03, 1.1912e-03, 2.4577e-03, 2.2247e-03,
1.7862e-03, 1.7460e-03, 1.4388e-03, 4.3175e-04, 6.7808e-04, 2.6875e-04,
3.6475e-04, 8.7643e-04, 3.6790e-04, 2.1274e-04, 6.3725e-04, 2.0949e-03,
2.4069e-03, 1.7348e-03, 1.0026e-03, 1.2451e-03, 4.7888e-04, 5.9790e-04,
1.4343e-03, 4.0900e-03, 1.0176e-03, 5.5178e-04, 2.0624e-03, 1.2878e-03,
6.9607e-04, 4.3259e-04, 1.8573e-03, 7.5521e-04, 5.2949e-04, 3.4758e-04,
4.7898e-04, 7.5599e-04, 6.0631e-04, 1.7585e-03, 1.8156e-03, 3.2421e-04,
8.9446e-04, 7.2131e-04, 6.2817e-04, 1.0827e-03, 2.0211e-03],
device='cuda:0')
expanded_mask is:
tensor([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], device='cuda:0',
grad_fn=<AsStridedBackward>)
then masked_inputs is:
tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
device='cuda:0', grad_fn=<SelectBackward>)
Looks like the 1's isn't being multiplied through.
Another way of using broadcasting:
import torch
mask = torch.tensor([[1, 0, 1]])
inputs = torch.randn(1, 3, 2)
masked = inputs * mask[..., None]
print(mask)
print(inputs)
print(masked)
result:
tensor([[1, 0, 1]])
tensor([[[ 2.2820, 2.7476],
[-0.1738, -0.5703],
[ 0.7077, -0.6384]]])
tensor([[[ 2.2820, 2.7476],
[-0.0000, -0.0000],
[ 0.7077, -0.6384]]])
The ellipsis operator denotes all dimensions, then None adds a dimension at the end.
You can rely on broadcasting semantics here. We start by using Tensor.unsqueeze(2) on expanded_mask to add a unitary dimension onto the end making it a size [1, 154, 1] tensor. Then the multiplication operation will implicitly use numpy-like broadcasting semantics to multiply each of the 161 channels of inputs with expanded_mask.
So the final result is
expanded_mask.unsqueeze(2) * inputs

Appending matrix A with matrix B

Say I have two matrices A and B. For example,
A = numpy.zeros((5,5))
B = np.eye(5)
Is there a way to append A and B?
It sounds to me like you're looking for np.hstack:
>>> import numpy as np
>>> a = np.zeros((5, 5))
>>> b = np.eye(5)
>>> np.hstack((a, b))
array([[ 0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.]])
np.vstack will work if you want to stack them downward:
>>> np.vstack((a, b))
array([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0.],
[ 0., 0., 1., 0., 0.],
[ 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 1.]])

Assigning subvectors to multidimensional arrays in Numpy

Say I have a matrix:
from numpy import *
a = zeros(shape=(nRows,nColumns));
and I would like to fill in the first column with ones, when I try to do:
a[:][0] = ones(shape=(nRows,1))
I get:
ValueError: output operand requires a reduction, but reduction is not enabled
Why is it not working?
It should be as easy as:
a[:,0] = 1
broadcasting will handle the details.
>>> a = np.zeros((10,10))
>>> a
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
>>> a[:,0]=1
>>> a
array([[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

Categories

Resources