programing

NumPy 어레이를 단위 벡터로 정규화하는 방법

randomtip 2022. 9. 30. 09:35
반응형

NumPy 어레이를 단위 벡터로 정규화하는 방법

NumPy 배열을 단위 벡터로 변환하고 싶습니다.구체적으로는 이 정규화 함수와 동등한 버전을 찾고 있습니다.

def normalize(v):
    norm = np.linalg.norm(v)
    if norm == 0: 
       return v
    return v / norm

이 함수는 벡터가 다음과 같은 상황을 처리합니다.v의 표준값은 0 입니다.

에 제공되는 유사한 기능이 있습니까?sklearn또는numpy?

skikit-learn을 사용하는 경우 다음을 사용할 수 있습니다.

import numpy as np
from sklearn.preprocessing import normalize

x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = normalize(x[:,np.newaxis], axis=0).ravel()
print np.all(norm1 == norm2)
# True

그러한 기능이 부속 라이브러리의 일부라면 좋을 것이라고 생각합니다.하지만 내가 알기로는 그렇지 않다.최적의 성능을 제공하는 임의의 축을 위한 버전입니다.

import numpy as np

def normalized(a, axis=-1, order=2):
    l2 = np.atleast_1d(np.linalg.norm(a, order, axis))
    l2[l2==0] = 1
    return a / np.expand_dims(l2, axis)

A = np.random.randn(3,3,3)
print(normalized(A,0))
print(normalized(A,1))
print(normalized(A,2))

print(normalized(np.arange(3)[:,None]))
print(normalized(np.arange(3)))

이 방법도 도움이 될 수 있습니다.

import numpy as np
normalized_v = v / np.sqrt(np.sum(v**2))

하지만 실패하면v의 길이는 0 입니다.

이 경우 제로 나눗셈을 방지하기 위해 작은 상수를 도입하면 해결됩니다.

제로 나눗셈을 피하기 위해 나는 eps를 사용하지만, 그것은 좋지 않을 수 있다.

def normalize(v):
    norm=np.linalg.norm(v)
    if norm==0:
        norm=np.finfo(v.dtype).eps
    return v/norm

다차원 데이터가 있고 각 축을 최대값 또는 합계로 정규화하려는 경우:

def normalize(_d, to_sum=True, copy=True):
    # d is a (n x dimension) np array
    d = _d if not copy else np.copy(_d)
    d -= np.min(d, axis=0)
    d /= (np.sum(d, axis=0) if to_sum else np.ptp(d, axis=0))
    return d

numpys peak to peak 함수를 사용합니다.

a = np.random.random((5, 3))

b = normalize(a, copy=False)
b.sum(axis=0) # array([1., 1., 1.]), the rows sum to 1

c = normalize(a, to_sum=False, copy=False)
c.max(axis=0) # array([1., 1., 1.]), the max of each row is 1

Sci-kit Learn이라고 하셨는데, 다른 해결책을 공유하겠습니다.

공상 과학 키트 학습MinMaxScaler

sci-kit learn에는 API라는 것이 있습니다.MinMaxScaler원하는 대로 값 범위를 사용자 지정할 수 있습니다.

그것은 또한 우리를 위해 NaN 문제를 다룬다.

NaN은 결측값으로 취급됩니다.적합은 무시되고 변환으로 유지됩니다.참조 자료 [1] 참조해 주십시오.

코드샘플

코드는 간단합니다. 그냥 입력하세요.

# Let's say X_train is your input dataframe
from sklearn.preprocessing import MinMaxScaler
# call MinMaxScaler object
min_max_scaler = MinMaxScaler()
# feed in a numpy array
X_train_norm = min_max_scaler.fit_transform(X_train.values)
# wrap it up if you need a dataframe
df = pd.DataFrame(X_train_norm)
Reference

기능도 있습니다.unit_vector()Christoph Gohlke의 인기 변환 모듈의 벡터를 정규화하려면:

import transformations as trafo
import numpy as np

data = np.array([[1.0, 1.0, 0.0],
                 [1.0, 1.0, 1.0],
                 [1.0, 2.0, 3.0]])

print(trafo.unit_vector(data, axis=1))

최고의 정밀도를 필요로 하지 않는 경우, 다음과 같이 기능을 축소할 수 있습니다.

v_norm = v / (np.linalg.norm(v) + 1e-16)

다차원 어레이를 사용하는 경우 다음과 같은 빠른 솔루션이 가능합니다.

예를 들어 마지막 축으로 정규화하려는 2D 배열이 있지만 일부 행에는 표준이 없습니다.

import numpy as np
arr = np.array([
    [1, 2, 3], 
    [0, 0, 0],
    [5, 6, 7]
], dtype=np.float)

lengths = np.linalg.norm(arr, axis=-1)
print(lengths)  # [ 3.74165739  0.         10.48808848]
arr[lengths > 0] = arr[lengths > 0] / lengths[lengths > 0][:, np.newaxis]
print(arr)
# [[0.26726124 0.53452248 0.80178373]
# [0.         0.         0.        ]
# [0.47673129 0.57207755 0.66742381]]

3D 벡터를 사용하는 경우 툴벨트 vg를 사용하여 이를 간결하게 수행할 수 있습니다.Numpy 위에 라이트 레이어이며 단일 값과 누적 벡터를 지원합니다.

import numpy as np
import vg

x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = vg.normalize(x)
print np.all(norm1 == norm2)
# True

저는 지난 번 스타트업에서 라이브러리를 만들었습니다.이 라이브러리는 다음과 같은 용도로 사용되었습니다.NumPy에서는 너무 장황한 단순한 아이디어입니다.

없이.sklearn사용방법만numpy. 함수를 정의하기만 하면 됩니다.

행이 변수이고 열이 표본이라고 가정합니다.axis= 1

import numpy as np

# Example array
X = np.array([[1,2,3],[4,5,6]])

def stdmtx(X):
    means = X.mean(axis =1)
    stds = X.std(axis= 1, ddof=1)
    X= X - means[:, np.newaxis]
    X= X / stds[:, np.newaxis]
    return np.nan_to_num(X)

출력:

X
array([[1, 2, 3],
       [4, 5, 6]])

stdmtx(X)
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.]])

3D 텐서에 저장된 n개의 차원 피쳐 벡터를 정규화하려면 PyTorch를 사용할 수도 있습니다.

import numpy as np
from torch import FloatTensor
from torch.nn.functional import normalize

vecs = np.random.rand(3, 16, 16, 16)
norm_vecs = normalize(FloatTensor(vecs), dim=0, eps=1e-16).numpy()

단순한 도트 제품이라면 충분할 것이다.추가 패키지는 필요 없습니다.

x = x/np.sqrt(x.dot(x))

만약 이 ㅇㅇㅇㅇㅇ라면, ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ.x는 0이고 본질적으로 0 벡터이며 단위 벡터(노름 1을 갖는 것)로 변환할 수 없습니다.★★★★★★★★★★★★★★★★★★★★★★의 경우.np.array([0,0,...0]) 쓰세요.

norm = np.sqrt(x.dot(x))
x = x/norm if norm != 0 else x

2D 배열의 경우 다음과 같은 한 개의 라이너를 사용하여 여러 행에 걸쳐 정규화할 수 있습니다.컬럼을 ""를 설정합니다.axis=0.

a / np.linalg.norm(a, axis=1, keepdims=True)

; ] [ 0 ; 1 ]의 모든 for 1d-array 그냥 하세요.

(a - a.min(axis=0)) / (a.max(axis=0) - a.min(axis=0))

서 ★★★★★a의 것입니다1d-array.

예:

>>> a = np.array([0, 1, 2, 4, 5, 2])
>>> (a - a.min(axis=0)) / (a.max(axis=0) - a.min(axis=0))
array([0. , 0.2, 0.4, 0.8, 1. , 0.4])

메서드에 대해 메모합니다.값 사이의 비율을 저장하려면 다음과 같은 제한이 있습니다.1d-array적어도 1개는 있어야 합니다.0 and and and 、 and 、 습 、 습 、 습 、 and 。0 ★★★★★★★★★★★★★★★★★」positive번호를 입력합니다.

언급URL : https://stackoverflow.com/questions/21030391/how-to-normalize-a-numpy-array-to-a-unit-vector

반응형