2014-11-12 2 views
1

python을 사용하여 임의의 스파 스 대칭 행렬을 생성하는 방법은 무엇입니까? MATLAB에서Python : Python을 사용하여 임의의 희소 대칭 행렬을 생성하는 방법은 무엇입니까?

, 우리는 "sprandsym (size, density)"

을하는 기능을하지만 어떻게 파이썬에서 그렇게 할 수 있나요?

+0

숫자가 적은 행렬입니까, 아니면 중첩 된 배열입니까? matlab을 에뮬레이션하려는 경우, numpy 및 scipy는 좋은 팀입니다. unutbu 노트는 –

답변

5

scipy가있는 경우 sparse.random을 사용할 수 있습니다. 아래의 sprandsym 함수는 스파 스 (sparse) 무작위 행렬 X를 생성하고, 그 위 삼각형 절반을 취하여 그 자체에 대치를 추가하여 대칭 행렬을 형성합니다. 이 값은 대각선 값을 두 배로하므로 대각선은 한 번 뺍니다.

0이 아닌 값

정상적으로 Kolomogorov - 스 미르 노프 테스트는 비 - 제로 값은 정규 분포에서 도면과 일치 것을 확인하는 데 사용되는 평균 0과 표준 편차 (1)의 배포하고되는 히스토그램 및 분포를 시각화하기 위해 QQ- 플롯이 생성됩니다.
import numpy as np 
import scipy.stats as stats 
import scipy.sparse as sparse 
import matplotlib.pyplot as plt 
np.random.seed((3,14159)) 

def sprandsym(n, density): 
    rvs = stats.norm().rvs 
    X = sparse.random(n, n, density=density, data_rvs=rvs) 
    upper_X = sparse.triu(X) 
    result = upper_X + upper_X.T - sparse.diags(X.diagonal()) 
    return result 

M = sprandsym(5000, 0.01) 
print(repr(M)) 
# <5000x5000 sparse matrix of type '<class 'numpy.float64'>' 
# with 249909 stored elements in Compressed Sparse Row format> 

# check that the matrix is symmetric. The difference should have no non-zero elements 
assert (M - M.T).nnz == 0 

statistic, pval = stats.kstest(M.data, 'norm') 
# The null hypothesis is that M.data was drawn from a normal distribution. 
# A small p-value (say, below 0.05) would indicate reason to reject the null hypothesis. 
# Since `pval` below is > 0.05, kstest gives no reason to reject the hypothesis 
# that M.data is normally distributed. 
print(statistic, pval) 
# 0.0015998040114 0.544538788914 

fig, ax = plt.subplots(nrows=2) 
ax[0].hist(M.data, normed=True, bins=50) 
stats.probplot(M.data, dist='norm', plot=ax[1]) 
plt.show() 

enter image description here


PS

. 내가 (X + X.T)/2.0의 비 - 제로 요소가 바로 분포를 가지고 자신을 설득 할 수 없기 때문에 내가 대신

result = (X + X.T)/2.0 

upper_X = sparse.triu(X) 
result = upper_X + upper_X.T - sparse.diags(X.diagonal()) 

을 사용했다. 첫째, X이 밀도가 높고 평균 0 및 분산 1, 즉 N(0, 1)으로 정규 분포 된 경우 (X + X.T)/2.0N(0, 1/2)이됩니다. 물론 우리는 대신
result = (X + X.T)/sqrt(2.0) 

를 사용하여이 문제를 해결할 수 있습니다. 그러면 resultN(0, 1)이됩니다. 그러나 또 다른 문제가 있습니다. X이 희박한 경우 0이 아닌 위치에서 X + X.T은 대개 정규 분포의 확률 변수에 0을 더한 값이됩니다. sqrt(2.0)으로 나누면 일반 분포가 0에 가까워 질 것이므로 더 강하게 분포하게됩니다. X은 드문 드문 해지므로 정규 분포와 비슷하거나 적을 수 있습니다.

(X + X.T)/sqrt(2.0)이 어떤 분포를 생성했는지 알지 못했기 때문에 X의 위쪽 삼각형 반을 복사하여 (따라서 정규 분포가 아닌 값을 알고 있음을 반복합니다).

+0

Thx이지만 'symmetric'속성은 누락되었습니다. – guanglei

+0

어떻게 대각 요소가 0이 아니어야합니까? – Shyamkkhadka

+0

symetric propery를 놓치지 않은 것 외에'scipy.sparse.rand'의 값은 uniformlly 분포하고,'sprandsym'의 값은 정상적으로 분포합니다. – hipoglucido

1

unutbu의 답변은 성능과 확장 성을 위해 가장 좋습니다 - numpy와 scipy는 함께 matlab에서 많은 기능을 가지고 있습니다.당신이 어떤 이유에서 사용할 수 없거나 순수 파이썬 솔루션을 찾고 있다면 그것은 당신에게 unutbu의 솔루션보다 조금 더 제어 할 수 있지만

, 당신은 당신이

from random import randgauss, randint 
sparse = [ [0 for i in range(N)] for j in range(N)] 
# alternatively, if you have numpy but not scipy: 
# sparse = numpy.zeros(N,N) 
for _ in range(num_terms): 
    (i,j) = (randint(0,n),randint(0,n)) 
    x = randgauss(0,1) 
    sparse[i][j] = x 
    sparse[j][i] = x 

을 시도 할 수 상당히 느릴 것으로 예상해야합니다. scipy는 피할 수없는 의존성입니다.

2

매트릭스는 대칭이어야하며 여기에는 두 가지 대답이 있습니다.

def sparseSym(rank, density=0.01, format='coo', dtype=None, random_state=None): 
    density = density/(2.0 - 1.0/rank) 
    A = scipy.sparse.rand(rank, rank, density=density, format=format, dtype=dtype, random_state=random_state) 
    return (A + A.transpose())/2 

이렇게하면 드문 드문 한 행렬이 만들어지고 대칭으로 변환됩니다.

두 값을 함께 추가하면 밀도가 증가한다는 사실과 대각선 용어에서 밀도가 추가로 증가하지 않는다는 사실을 고려합니다.

+0

여기서는 모든 비 대각선 요소가 0이 아니고 최대 수가 아닌 0이 필요합니다. 어떤 생각? – Shyamkkhadka