'머신러닝 > 스터디 정리' 카테고리의 다른 글

numpy 연산  (0) 2018.08.18
numpy 기본  (0) 2018.08.18
상관계수  (0) 2018.08.16
PCA  (0) 2018.08.14
정규분포 표준화  (0) 2018.08.13

공분산의 문제점

X와 Y의 단위의 크기에 영향을 받는다는 것이다.


즉 다시말해 100점만점인 두과목의 점수 공분산은 별로 상관성이 부족하지만 100점만점이기 때문에 큰 값이 나오고 10점짜리 두과목의 점수 공분산은 상관성이 아주 높을지만 10점만점이기 때문에 작은값이 나온다. 이것을 보완하기 위해 상관계수(Correlation)가 나타난다.


상관계수

확률변수의 절대적 크기에 영향을 받지 않도록 단위화 시켰다고 생각하면 된다.

즉, 분산의 크기만큼 나누었다고 생각하면 된다.





상관계수와 내적

다시 상관 계수의 식을 보자.

이 중에서

는 정규화 과정과 매우 관련이 있어 보이긴 한다. 하지만 이번에는 (xiX¯)와 (yiY¯)를 떼어서

생각해보자. 그리고 sX¯와 sY¯는 (xiX)(yiY¯)와 관계가 있다는

사실을 알고 있으니 식을 아래와 같이 변경할 수 있다.

여기서라 하자.

그러면 위 식은 다음과 같이 쓸 수 있다.





[참고]

http://destrudo.tistory.com/15

https://wikidocs.net/6957

'머신러닝 > 스터디 정리' 카테고리의 다른 글

numpy 기본  (0) 2018.08.18
경사하강법  (0) 2018.08.17
PCA  (0) 2018.08.14
정규분포 표준화  (0) 2018.08.13
Aprior 알고리즘  (0) 2018.08.12

PCA요약

차원의 저주를 막기위해 PCA를 분석하는데 

이때 공분산이 가지는 최대 고유벡터를 가지고 데이터를 선형변환(정사영) 한다.


공분산은 변수간의 연관성 정도를 파악해준다.

공분산이 가지는 최대 고유벡터를 쓰는 이유는 고유벡터에 데이터를 정사영 했을때 분산이 최대가 되기 때문이다.

분산이 최대가 되어야하는 이유는 정사영후 데이터가 겹치지 않아야 원본 데이터와 최대한 동일한 효과를 낼수 있기 때문이다.


따라서 우리가 알아야 할 수학적 방법은 주어진 데이터에 대해서 어떻게 하면 variability가 큰 방향을 가리키는 벡터를 찾을 수 있을 것인가에 관한 것이다. <- 고유벡터 구하기(공분산구하기)


공분산이란 둘 이상의 변량이 연관성을 가지며 분포하는 모양을 전체적으로 나타낸 분산으로 정의


공분산행렬(각변수간의 연관정도를 볼수있음 / 내적활용)에서 가장 큰 고유벡터와 고유값


차원의저주(Curse of dimensionality)

차원의 저주는 데이터 과학에서는 차원이 증가함에 따라 차원 내의 부피도 증가하게 되는데, 데이터가 해당 공간 내에 놓일 수 있는 위치는 한정되게 되어 있어 빈 공간(sparsity)이 많아지기 때문에 발생한다. 아래의 그림을 보도록 하자. 이처럼 관찰한 데이터의 차원이 증가할수록 공간의 volume의 크기는 기하급수적으로 증가하게 되고 빈 공간도 많아지게 되는 것이다. 그만큼 불필요한 공간이 남아있게 되어 계산량도 증가한다. 이것이 큰 차원의 데이터를 다룰 때, 어떻게 하면 데이터의 전반적인 구조는 바꾸지 않고 중복적인 정보를 가지는 차원을 감소시켜야 하는 이유이다.




공분산행렬


XTX 행렬이 가지는 문제는 숫자 n이 커질수록 내적 값은 계속 커진다는 것이다.(계속 합해지니까 값이 계속 커짐) 

따라서 내적값들을 n으로 나누어주면(값의 평균을 구하면) 그 문제를 피할 수 있을 것이다. 


각 원소의 의미는 Xi와 Xj가 얼마나 연관성이 있는지를 보여준다


1) 각원소가 양수이면 양의 상관관계

2) 음이면 음의 상관관계

3) 0이면 서로 독립관계임을 뜻한다. (두 변수가 독립적이라면 공분산은 0이 되지만, 공분산이 0이라고 해서 항상 독립적이라고 할 수 없다.)

 
공분산의 성질
공분산의 많은 성질은 내적이 가지는 성질과 유사하다.:
(1) 이중선형연산: 상수 a와 b 그리고 확률변수 X, Y, U, Cov(aX + bY, U) = a Cov(X, U) + bCov(Y, U)
(2) 대칭성: Cov(X, Y) = Cov(Y, X)
(3) 양수값: Var(X) = Cov(X, X) ≥ 0이고 Cov(X, X) = 0 이란 것은 X가 상수확률변수(K)라는 뜻이다.
공분산은 확률변수들의 벡터 공간 상에서의 내적을 의미한다. 벡터에서 적용되는 벡터합 X + Y 및 aX와 같은 스칼라곱의 성질도 지닌다.

고유벡터/고유값

어떤 N x N행렬 A에 대하여 AK=λK가 만족하는 K를 고유벡터, λ고유값이라고 한다.

그리고 위 식은 (A−λI)K=0을 만족하고

벡터 K=[k1,k2,⋯,kn] T에 대해 벡터 K가 nontrivial solution을 가지기 위한 필요충분 조건은 det(A−λI)=0(I는 단위행렬)이다.

고유벡터와 고유값은 다음과 같은 의미를 가지고 있다.

K = 선형변환 A를 했을 때, 그 크기만 변하고 방향이 변하지 않는 벡터

λ = 그 K 벡터의 크기는 얼마만큼 변했는지

기본적으로 고유벡터는 선형 변환에 대한 주축을 찾는 문제를 해결할 수 있게 해줄 것이다. 
주축(principal axis)을 찾는 문제는 PCA등의 분석법에서 굉장히 중요한 issue가 되게 된다. 
또한, eigen-시리즈는 더 나아가서 양자역학에서 굉장히 중요한 역할을 한다고 한다.

차원 감소의정도

다차원의 데이터에서 차원 감소를 시켜주는 것이 PCA의 주목적인 것은 알겠지만, 

그렇다면 고차원의 데이터를 어디까지 차원감소 시켜주는 것이 타당할까?


가령 d차원의 데이터를 m차원까지 감소시켜준다고 해보자 (여기서 m<d). 

d 차원의 데이터이므로 총 d개의 eigenvalue를 계산 할 수 있다. 

(물론 데이터의 공분산 행렬이 full rank임을 가정했을 때이다.)


이것을 λ1 ,λ2, ⋯, λd로 표현해주자 (여기서 λ1≥λ2≥⋯,≥λd)


1. 전체 데이터의 variance 중 가령 90%만큼을 설명하는 차원까지 감소


인 적절한 m을 찾아 그 차원까지 감소시켜주는 것이다.


2. scree plot

이 방법은 다소 주관적일 수 있는데 2차원 plot을 그리는데 x 축에는 dimensions, y 축에는 해당 dimension의 eigenvalue를 기재한다. 

예를 들어 다음과 같은 그림일 수 있다.


여기서 보면 세 번째 eigenvalue부터 갑자기 꺾이는 현상이 보인다.


그러면 이때는 3차원까지 차원 감소를 시켜준다는 식으로 결정하는 것이 scree plot을 이용한 방법이다.

 scree plot은 PCA외에도 많은 method에서 사용된다.




[참고] 

https://wikidocs.net/7646

https://wikidocs.net/4050

http://yamalab.tistory.com/32

http://rfriend.tistory.com/145

https://ko.wikipedia.org/wiki/%EA%B3%B5%EB%B6%84%EC%82%B0

'머신러닝 > 스터디 정리' 카테고리의 다른 글

경사하강법  (0) 2018.08.17
상관계수  (0) 2018.08.16
정규분포 표준화  (0) 2018.08.13
Aprior 알고리즘  (0) 2018.08.12
K-means 알고리즘  (0) 2018.08.12

평균, 분산, 표준편차 공식



정규분포 표준화

정규 분포 또는 가우시안 분포 연속 확률 분포의 하나이다. 정규분포는 수집된 자료의 분포를 근사하는 데에 자주 사용되며, 이것은 중심극한정리에 의하여 독립적인 확률변수들의 평균은 정규분포에 가까워지는 성질이 있기 때문이다.

정규분포는 2개의 매개 변수 평균  표준편차 에 대해 모양이 결정되고, 이때의 분포를 로 표기한다. 특히, 평균이 0이고 표준편차가 1인 정규분포  표준정규분포(standard normal distribution)라고 한다.

정규 분포 밀도 함수에서 를 통해 X를 Z로 정규화함으로써 평균이 0, 표준편차가 1인 표준정규분포를 얻을 수 있다.

z-분포라고도 부른다. z-분포로 하는 검정(test)을 z-검정(z-test)이라고 한다.


에서 k값이 변화함에 따라 구해지는 값을 불확실성(uncertainty)이라고 한다. 예를 들어 를 90% 불확실성, 는 95% 불확실성, 은 99% 불확실성이다. 특히, 를 50% 불확실성이라고 하며, 확률오차(probable error)라고도 한다. 이는 관측값이 전체 관측값의 50%에 있을 확률을 의미한다.


[참고]

https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%EB%B6%84%ED%8F%AC

'머신러닝 > 스터디 정리' 카테고리의 다른 글

상관계수  (0) 2018.08.16
PCA  (0) 2018.08.14
Aprior 알고리즘  (0) 2018.08.12
K-means 알고리즘  (0) 2018.08.12
Json.Net  (0) 2018.08.09

Apriori 알고리즘의 개요

-어떤 Item 집합의 존재가 다른 Item 집합의 존재를 암시하는 것을 의미하며 다음과 같이 표시한다.

(Item set A) => (Item set B ) ( if A then B : 만일 A 가 일어나면 B 가 일어난다. ) 

     - 함께 구매하는 상품의 조합이나 서비스 패턴 발견하는데 이용

     - 특정 제품 또는 사건들이 동시에 발생 하는 패턴을 파악하는데 이용

ex) 가정 용품 판매 기간 동안 같이 판매해야 하는 상품의 패턴 발견 


- 데이터들에 대한 발생 빈도를 기반으로 각 데이터 간의 연관관계를 밝히기 위한 방법

- 구현이 간단하고 성능 또한 만족할 만한 수준을 보여주는 알고리즘으로 패턴 분석을 위해 자주 이용되는 알고리즘

- Apriori는 K번째 항목집합이 K+1번째 항목집합을 발견하기 위해 사용되는 레벨단위로 진행되는 반복 접근법을 사용


- 예를 들어서 A->B일때 0.75의 확률을 가진다고해서, B->A일확률일 0.75라는 것을 보장해주지는 못한다. 따라서 한 트랜잭션에 대해서 A가 나오고 B가 나오는 예와 B가 나오고 A가 나오는 것에 대한 확률은 input데이터를 따로 정렬해서 구해야한다.


- 여기서 사용할 set()은 순서가 없는 집합형 자료형이므로 순서는 신경쓰지 않아야한다.



Apriori알고리즘 적용예시

교차 판매 ( Cross Selling )


상품 진열 ( Inventory Display )


부정탐지(fraud detection)

- 상당히 높은 신뢰도를 갖는 규칙에 대해 특정 고객이 그 규칙이 적용이 않되다면 수상할 수 있음


Category Design

- 상품의 배치문제, 패키지 상품의 구성, 쿠폰 발행, 카탈로그의 구성, 신상품의 카테고리 선정

Apriori 알고리즘 설명

- Database로부터 후보 항목 집합(Candidate Itemset)을 생성하고, 

이를 데이터베이스 트랜잭션과 비교하여 빈발 항목 집합(Large Itemset)을 찾아내는 과정, 

더 이상의 빈발 k-항목 집합이 없을 때까지 반복하는 과정을 거친 후 최종 빈발 항목 집합을 생성함


- 빈발 항목 집합들(Large Item Sets)을 찾기 위해서 미리 결정된 최소 지지도(Minimum Support) 이상의 트랜잭션 지지도를 가지는 항목 집합들의 모든 집합들을 빈발 항목 집합들이라고 하며 그 외 모든 항목 집합들은 작은 항목 집합들(Small Itemsets)이라 함.


- 데이터베이스로부터 연관 규칙을 생성하기 위하여 빈발 항목 집합을 이용. 

지지도(Support)와 신뢰도(Confidence)는 다음의 식을 통해 계산

여기서 지지도란, 전체 건수중에 몇 개 이상 포함되어있는 항목들이 무엇인지 찾아내기 위한 척도이며, 신뢰도란, 지지도를 가진 건수가 전체 항목중에 몇개나 있는지를 볼 수 있는 것이라고 생각하면 쉽다.


Apriori알고리즘 구현

여기서는 최소지지도가 2이상인 빈발항목을 구하는 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import itertools
 
# set자료형 사용이 핵심!
# Apriori알고리즘 자체가 순서가 없다. 데이터는 편의대로 정렬해놓은것!(180811)
class Apriori:
    
    def __init__(self,input, min_support):
        self.min_support = min_support
        self.origin_set = input
        self.distinct_list = self.distinct_input(input)
        self.distinct_set = list(map(set,self.distinct_list))
        
       
    #DataSet을 중복없이 나열하는 함수
    #return { }
    def distinct_input(self, input):
 
        # { }은 set에 사용하는 기호지만 인수없이쓰면 dict로 인식한다
        # 따라서 set()을 사용한다.
        data_set = set()
        
        for idx in list(input):
            data_set.update(idx)
 
        return list(data_set)
                            
    #빈도수를 구하는 함수
    #원본데이터에서 경우의수를 구한데이터를 가지고 빈도수를 구한다.
    #param n경우의수 step수 / data distinct_list
    #return []
    def get_freq(self,n):
        freq_dic = dict()
        case_list = self.number_of_case_n(n, self.distinct_list)

        for j in list(self.origin_set) :
            for i in list(case_list) :
 
                if(j.issuperset(i)):
                    if freq_dic.get(i, 0== 0 :
                        freq_dic[i] = 1
                    else :
                        freq_dic[i] += 1
 
        return freq_dic
        
    #param : freq_dic
    def rm_minsup(self, freq_dic):
        
        cp_freq_dic = freq_dic.copy()
        
        sum_val = len(cp_freq_dic.keys())
        
 
        for i in list(cp_freq_dic.items()):
            
            if i[1< self.min_support:
                del cp_freq_dic[i[0]]
        
        return list(cp_freq_dic)
    
    
    #DataSet의 모든 경우의수를 구하는 함수
    #return []
    def number_of_case_n(self, n, data):
        n_list = list()
        for subset in itertools.combinations(data, n):
            n_list.append(subset)
            
        return list(map(frozenset, n_list))
    
    
    def start(self):
 
        i = 1
        step_result = None
        while True:
            
            
            step_result = list(map(set, self.rm_minsup(self.get_freq(i))))
            self.distinct_list = self.distinct_input(step_result)
            
            print(step_result)
            print(i)
            
            if len(step_result) <= 1:
                break
            
            if i >= 100:
                break
                
            i += 1
 
        conf = [ a for a in self.origin_set if a.issuperset(step_result[0])]
        #최소지지도 : 전체 건수중에 3개 이상 포함되어있는 항목들이 무엇인지 => {2,5}
        print(self.min_support / len(self.origin_set))
        #신뢰도 : 전체 건수중에 포함되어있는 항목중에 2,5가 포함되어있는 건은 몇건인지 => 3건 
        print(len(conf) / len(self.origin_set))
        
        
if __name__== "__main__":
    min_support = 2
    
    ##4장의 영수증 내역의 리스트 모음이라고 생각하자.
    input = [{'A''C''D'}, {'B''C''E'}, {'A''B''C''E'}, {'B''E'}]  
    apriori = Apriori(input,min_support)
    apriori.start()
 
cs


 결과:

[{'E'}, {'D'}, {'A'}, {'B'}, {'C'}]  #최초 중복을 제거한 데이터

[{'A'}, {'C'}, {'E'}, {'B'}] # 최소 지지도이하 1차 제거후

1

[{'A', 'C'}, {'E', 'C'}, {'E', 'B'}, {'B', 'C'}] # 최소 지지도 이하 2차 제거후

2

[{'E', 'B', 'C'}] # 최소지지도 이하 3차 제거후

3

0.5 #최소지지도

0.5 #신뢰도



지지도 기반의 탐색을 하고 싶으면 데이터 셋의 각 경우를 구해서 모두 issubset해서 지지도를 구해서 확인하면 된다.


신뢰도 기반의 탐색을 하고 싶으면 주어진 데이터 셋의 각 경우를 구해서 모두 issubset해서 지지도를 구하고 이 지지도를 기반으로 신뢰도를 구하면 된다.




[참고]

http://www.jidum.com/jidums/view.do?jidumId=1099

http://hamait.tistory.com/743?category=132470

http://contents.kocw.net/KOCW/document/2014/Chungbuk/choisanghyun/12.pdf

'머신러닝 > 스터디 정리' 카테고리의 다른 글

상관계수  (0) 2018.08.16
PCA  (0) 2018.08.14
정규분포 표준화  (0) 2018.08.13
K-means 알고리즘  (0) 2018.08.12
Json.Net  (0) 2018.08.09

군집화(K-means)란,

- 전체 데이터를 몇 개의 집단으로 그룹화하여 각 집단의 성격을 파악함으로써 데이터 전체의 구조에 대한 이해를 돕고자 하는 분석법

- 모집단 또는 범주에 대한 사전 정보가 없는 경우 주어진 관측 값들 사이의 거리 또는 유사성을 이용하는 분석법

- 주어진 데이터들의 특성을 고려해 데이터 집단(클러스터)을 정의하고 데이터 집단의 대표할 수 있는 대표점을 찾는 것으로 데이터 마이닝의 한 방법


군집분석의 활용

- 군집분석은 속성이 비슷한 잠재 고객들끼리 그룹화 하여 시장을 세분화 하는 방법에 자주 활용

- 기업의 수익에 기여 정도를 파악해서 우수고객의 인구통계적 요인, 생활패턴 파악하거나 개별고객에 대한 맞춤관리를 해야할때

- 구매패턴을 파악해서 신상품 판촉하거나 교차판매를 위한 목표집단을 구성해야할때


군집분석알고리즘

1. k개의 random 값을 구한다.

2. random값 에 대한 군집을 구성한다.

3. 군집에 대한 중앙점을 구한다.

4. 만약 이 중앙점들이 이전에 구한 중앙값과 동일하다면 종료한다.

5. 그렇지 않으면 현재 중앙점을 가지고 2.를 수행한다.


k-means알고리즘

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import random
import matplotlib.pyplot as plt
 
class KMeans:
    
    #__init__ : 생성자
    #classify : 분류메서드
    #train : 훈련메서드
    
    def __init__(self, k) :
        self.k = k
        self.means = None
        
    #a와 b의 거리를 구함
    def squared_distance(self,a, b):
        return ((b[0- a[0])**2 + (b[1- a[1])**2)
    
    #군집간(i_point)의 중앙점을 구함
    def vector_mean(self, i_points):
        sum_x = 0;
        sum_y = 0
        for i in list(i_points):
            sum_x += i[0]
            sum_y += i[1]
            
        avg_x = (sum_x / len(i_points))
        avg_y = (sum_y / len(i_points))
       
        return [avg_x, avg_y]
        
    #군집을 분류함
    def classify(self, input) :
        #range(self.k)에 key를 적용해서 min값을 구함
        return min(range(self.k), key = lambda i: self.squared_distance(input, self.means[i]))
    
    
    def train(self, inputs) :
    
        self.means = random.sample(inputs, self.k)
        assignment = None
        
        while True :
            new_assignment = list(map(self.classify , inputs))
 
            if assignment == new_assignment:
                return assignment
 
            assignment = new_assignment
            
            for i in range(self.k):
 
                i_points = [p for p, a in zip(assignment, inputs) if a == i]
 
                if i_points:
                    self.mean[i] = self.vector_mean(i_points)
    
    #그래프를 그리기위해서 데이터를 가공함
    def make_praph_data(self, data):
        axis_x = list()
        axis_y = list()
        for i in list(data):
            axis_x.append(i[0])
            axis_y.append(i[1])
        
        return axis_x, axis_y
 
 
if __name__ == "__main__":
    inputs = inputs = [
                        [-14,-5],[13,13],[20,23],[-19,-11],[-9,-16],[21,27],[-49,15],
                        [26,13],[-46,5],[-34,-1],[11,15],[-49,0],[-22,-16],[19,28],
                        [-12,-8],[-13,-19],[-41,8],[-11,-6],[-25,-9],[-18,-3]
                      ]
 
    clus = KMeans(3)
    
    clus.train(inputs)
    
    print(clus.means)
   
    axis_x_mean, axis_y_mean = clus.make_praph_data(clus.means)
    axis_x, axis_y = clus.make_praph_data(inputs)
    
    plt.scatter(axis_x, axis_y)
    plt.scatter(axis_x_mean, axis_y_mean, marker='>', c='r')
    
    plt.show()
cs






k-means의 k값 구하기

k-means는 k값을 임의로 정해주어야한다. k값을 찾는 방법에 대해서 알아보자.
방법은 각 k값에 대하여 군집들의 거리를 구해서 합한다음 이것에 대해 가장 가파르게 꺾이는 부분을 찾는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
k_value = list();
 
for k in range(1,10):
    model = KMeans(k)
    model.train(inputs)
    means = model.means
    assignments = map(model.classify, inputs)
    k_value.append(sum(model.squared_distance(input, means[cluster]) 
for input, model in zip(inputs, assignments)))
print(k_value)
plt.plot(k_value)
plt.show()
cs




결과해석 :

가장 가파르게 하강한 부분이 2-3 부분이므로 이 군집은 2-3개의 군집으로 나누는 것이 합리적이다.

k-means알고리즘 단점

1. 최초 초기화하는 값에 따라 시작하기때문에, 중심점과 점간의 거리가 Global optimum인 최소 값을 찾는 게 아니라 중심점이 Local optimum 에 에 수렴하여 잘못된 분류를 할 수 있다는 취약점을 가지고 있다. 


2. 군집의 크기다 다를 경우 원하는 대로 분류되지않을수 있다.



3. 군집의 밀도가 다를경우도 분류가 잘되지 않을수 있다.


4. 데이터 분포가 특이한 경우에도 군집이 잘일어나지 않을수 있다.




k-mean 알고리즘의 문제점을 해결할수 있는 알고리즘으로 비지도 학습 기반의 클러스터링 알고리즘중의 하나인 Hierachical Clustering 알고리즘이 있다.  Hierarchical Clustering은 이름에서도 알 수 있듯이 각 클러스터가 유사한 특징을 가지고 있는 여러 계층으로 되어 있을 때 효과적으로 사용할 수 있으며, 클러스터의 수 n을 정의하지 않고도 사용이 가능하다. 


[참고]

http://bcho.tistory.com/1203

http://hamait.tistory.com/740?category=132470

http://www.jidum.com/jidums/view.do?jidumId=1099

https://ratsgo.github.io/machine%20learning/2017/04/19/KC/

'머신러닝 > 스터디 정리' 카테고리의 다른 글

상관계수  (0) 2018.08.16
PCA  (0) 2018.08.14
정규분포 표준화  (0) 2018.08.13
Aprior 알고리즘  (0) 2018.08.12
Json.Net  (0) 2018.08.09

Json.net이란,

jackson과 gson처럼 object를 json 형태로 바꿔주고 json을 object로 바꿔주는 라이브러리를 말합니다.


다운은 https://www.newtonsoft.com/json 이곳에서 할 수 있습니다. 또는 NuGet패키지로 다운받으시면 됩니다.


Json Object를 만드는것은 다운로드링크에도 잘 나와있기 때문에

이번 포스트에는 Json Array를 받아서 Objcect로 바꾸는 예제를 보겠습니다.


JsonArray를 던지면 결과값으로 JsonArray가 return된다 가정하겠습니다.



사용법


우선


1
2
3
using Newtonsoft.Json.Linq;
 
using Newtonsoft.Json;
cs


를 추가해줍니다.


1. DataTable -> Object -> jsonArray 

본 예제에서는 파라미터로 DataTable을 받아서 시작하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private string Dt2Json(DataTable dt)
{
    // DataTable -> List -> Object
    List<Obj> lisObj = new List<Obj>();
 
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        Obj Obj = new Obj();
 
        //필수값
        Obj.code1 = dt.Rows[i]["code1"].ToString();
        Obj.code2 = dt.Rows[i]["code2"].ToString();
 
        lisObj.Add(Obj);
    }
 
    return JsonConvert.SerializeObject(lisObj.ToArray());
}
cs

핵심은 17줄 return절이겠죠? ㅎㅎ




2. JsonArray -> List

JsonObject를 받을때는 DeSerializeObject이 되는걸로 아는데 Array를 받을때는 다른 방법을 사용해야합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private List<Obj> ResJson2List(string Msg)
{
    List<Obj> lis_Obj = new List<Obj>();
 
    JArray jArray = JArray.Parse(Msg);
 
    foreach (JObject obj in jArray.Children<JObject>())
    {
        Obj Obj = new Obj();
 
        foreach (JProperty prop in obj.Properties())
        {
            if(prop.Name == "code1")
            { 
                Obj.code1 = prop.Value.ToString(); 
            }
            else if(prop.Name == "code2")
            {
                Obj.code2= prop.Value.ToString(); 
            }
            else if(prop.Name == "code3")
            {
                Obj.code3 = prop.Value.ToString(); 
            }
        }
        lis_Obj.Add(Obj);
    }
    return lis_Obj;
}
 
cs


설명을 하자면 파라미터는 Json Array가 넘어온다 가정합니다.


내부자료형은 차례대로 JArray > JObject > JProperty > JToken로 구현되어있습니다.


JArray.Parse(Msg)를 통해서 JsonContainer에 담습니다.


그리고 jArray.Childeren<JObject>()의 길이만큼 돌면서 JProperty를 찾습니다.


11줄에서는 각 JsonArray에 담긴 원소갯수만큼 for문을 돌기때문에  prop.Name과 prop.Value를 이용하여 원소에 순차적으로 접근할수 있습니다.


그리고 마지막으로 각 객체에 대한 list로 담아서 return해주면 됩니다.


제가 포스팅한것보다 더 좋은 방법있으시면 댓글달아주시면 감사하겠습니다!


'머신러닝 > 스터디 정리' 카테고리의 다른 글

상관계수  (0) 2018.08.16
PCA  (0) 2018.08.14
정규분포 표준화  (0) 2018.08.13
Aprior 알고리즘  (0) 2018.08.12
K-means 알고리즘  (0) 2018.08.12

+ Recent posts