일상에서의 문자 표현 C언어 문자 표현법
문자 A 'A', '65', '\0x41'
문자 [엔터키] '\n'
문자열  홍길동 "홍길동" (O), '홍길동' (X)

 

'홍길동'과 같이 두 개 이상의 문자를 넣을 수 없으며 이 경우 컴파일할 때 문법 오류가 발생한다.

C 문법에서 한글 한 문자 또한 단일 따옴표로 표현할 수 없다. "홍길동", "홍"과 같이 이중 따옴표를 사용(문자열)해야한다.

 

탈출문자

탈출문자  ASCII 문자 의미
\b BS 백스페이스
\t TAB
\n LF 개행
\" " 이중인용부호

 

 

++

C언어의 정수 상수 표현법

 

제일 앞에 보고 2진수인지 8진수인지 16진수인지 판단할 수 있음. 

=========

0b : 이진수

0 : 8진수

0x : 16진수

=========

 

 

 

'프로그래밍 > C,C++' 카테고리의 다른 글

C,C++ - 다양한 연산  (0) 2024.04.03
C,C++ - 입력함수 scanf()  (0) 2024.04.02
C,C++ - 필드폭과 정밀도 지정  (0) 2024.04.02
C, C++ - 변수 생성  (0) 2024.04.01
C언어와 코딩 (INTRO)  (0) 2024.04.01

코딩

> 문제해결과정 + 알맞은 언어

> 컴퓨팅적 사고력, 알고리즘, 코딩

 

기계어

> 0,1의 이진 코드만 이해할 수 있음.

 

어셈블리어 

> 기계어의 이진 명령 대신 ADD나 SUB와 같이 사람이 이해하기 쉬운 기호를 사용하도록 개발된 언어 

> 그런데 이것도 사람이 쓰는 자연어와는 거리가 멀어서 프로그램을 작성하는데에는 어려움이 여전히 있음.

 

고급언어

> 사람이 알아듣기 쉬움.

 

저급언어

> 컴퓨터와 밀접함,

> 기계어나 어셈블리어가 여기에 속함.

 

프로그램 개발 과정

  1. 요구사항 분석
  2. 설계(모듈 - 함수)
  3. 구현
  4. 테스트
  5. 배포 및 유지보수

소스파일은 기계어로 번역함.(컴파일)

 

 

C언어로 작성한 소스 파일에서 실행형 파일을 만들어 실행하는 과정 

 

소스파일 ---(컴파일링 - 컴파일러)---> 목적파일 ---(링킹)---> 실행파일 

(*.c, *.cpp)                                            (*.obj)                          (라이브러리 파일)

 

디버깅: 프로그램의 오류를 찾아내서 수정하는 과정

 

디버깅의 종류

  • 구문오류(컴파일 시간 오류 - 문법이 틀린 경우)
  • 링크오류(ex. 여러 소스 파일에 같은 이름의 함수가 중복으로 정의된 경우...)
  • 실행시간 오류(파일을 열고자 하는데 파일을 찾을 수 없을 때, )
  • 논리오류 (디버깅도구, 로그메시지 - 실행은 되지만 알고리즘이 잘못되어 의도한 대로 작동 X)

 

변수선언 > 입력 > 처리 > 출력

 

컴퓨터는 이산적 데이터만을 처리함.

 

비트는 데이터 표현의 최소 단위

ex) 8bits = 1byte

 

주석처리

  • // (한 줄)
  • /**/ (여러 줄)

'프로그래밍 > C,C++' 카테고리의 다른 글

C,C++ - 다양한 연산  (0) 2024.04.03
C,C++ - 입력함수 scanf()  (0) 2024.04.02
C,C++ - 필드폭과 정밀도 지정  (0) 2024.04.02
C, C++ - 변수 생성  (0) 2024.04.01
C,C++ - 문자, 문자열 상수 표현 문법  (1) 2024.04.01

한글폰트 적용 - 코랩

!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf

 

Fixed Random Seed 

seed 값에 의해 동일한 코드를 사용해도 결과가 다를 수 있기에, 동일한 결과를 위해 seed값을 고정시킵니다.

import numpy as np
import random
import os

def seed_everything(seed):
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)

seed_everything(42) # Seed 고정

 

데이터 불러오기 및 확인 

import pandas as pd

train_df = pd.read_csv('/content/sample_data/train.csv')
test_df = pd.read_csv('/content/sample_data/test.csv')

display(train_df.head(3))
display(test_df.head(3))

 

 

EDA

범주형 변수 확인

# 시각화 패키지 불러오기
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

# 한글 폰트 설정하기
fe = fm.FontEntry(fname = 'MaruBuri-Regular.otf', name = 'MaruBuri')
fm.fontManager.ttflist.insert(0, fe)
plt.rc('font', family='NanumBarunGothic')

fig, axes = plt.subplots(2, 2, figsize=(25,10)) # 2x2 형식으로 4개 그래프 동시에 표시

sns.countplot(x = train_df['대출기간'], ax=axes[0][0]).set_title('대출기간')
sns.countplot(x = train_df['근로기간'], ax=axes[0][1]).set_title('근로기간')
sns.countplot(x = train_df['주택소유상태'], ax=axes[1][0]).set_title('주택소유상태')
sns.countplot(x = train_df['대출목적'], ax=axes[1][1]).set_title('대출목적')

plt.show()

 

근로기간에서 < 1 year이랑 <1 year이 있는걸 확인했습니다.

둘 다 똑같은 의미를 취하는 것이기에 같게 만들어주는 작업이 필요할 듯 합니다.

그런데 근로기간의 데이터를 다시 한번 살펴보니 year에 3이 들어가있는걸 확인했고 10+ year, 1year도 중복이 되기에 마찬가지로 바꿔줍니다.

 

fig, axes = plt.subplots(2, 2, figsize=(25,10)) # 2x2 형식으로 4개 그래프 동시에 표시

sns.countplot(x = train_df['대출기간'], ax=axes[0][0]).set_title('대출기간')
sns.countplot(x = train_df['근로기간'], ax=axes[0][1]).set_title('근로기간')
sns.countplot(x = train_df['주택소유상태'], ax=axes[1][0]).set_title('주택소유상태')
sns.countplot(x = train_df['대출목적'], ax=axes[1][1]).set_title('대출목적')

plt.show()

 

다시 확인해주면 잘 처리된걸 확인할 수 있습니다.

 

세분화된 변수형 찾기

# '범주형 변수 찾기'
numeric_columns = train_df.select_dtypes(include=['number'])
categorical_col_names = train_df.select_dtypes(include=['object']).columns.tolist()

# '범주형 변수 정보 확인하기'
summary = {}
unique_counts = {}
for col in categorical_col_names:
    summary[col] = train_df[col].value_counts().to_dict()
    unique_counts[col] = train_df[col].nunique()

print(unique_counts)

 

범주형 변수의 경우 범주가 너무 세분화되어 있을 경우, One-Hot Encoding시 차원의 저주에 빠지기 쉽습니다. 따라서 너무 세분화된 범주형 변수를 제거해주기로 결정합니다.

따라서 ID를 제거해줍니다.

 

 

EDA: 수치형 변수 확인하기

결측치 확인

numeric_columns_train = train_df.select_dtypes(include=['number'])
numeric_columns_test = test_df.select_dtypes(include=['number'])

null_tot_train = numeric_columns_train.isnull().sum()
null_tot_test = numeric_columns_test.isnull().sum()

print(null_tot_train)
print(null_tot_test)

 

Describe & info

numeric_columns_train.describe()

부채_대비_소득_비율: max가 9999인게 조금 이상합니다.

총계좌수: max가 169인게 이상합니다. 

최근_2년간_연체_횟수: max가 30번인게 이상합니다.

연간소득: 0인데 대출이 가능했는지 의문이 듭니다. 

min_income = train_df['연간소득'].min()
rows_with_min_income = train_df[train_df['연간소득'] == min_income]
rows_with_min_income

부채_대비_소득_비율의 값이 9999인 것과 연간소득 0인데이터가 중복되는걸 확인할 수 있습니다.

 

이 데이터는 모델을 학습시킬 때 좋지 않다고 판단하여 제거하기로 결정했습니다.

수치형 변수 시각화

# 수치형 변수들을 시각화 (예: 히스토그램)
numeric_columns_train.hist(bins=10, figsize=(10, 6))
plt.suptitle('Numeric Variables Distribution')
plt.show()

 

대출금액을 제외하고 대부분의 데이터들이 좌측편향돼있다는 걸 확인할 수 있습니다.

이걸 로그변환시킬지 아니면 이상치의 값들을 제거해야할지 결정을 해줘야할 듯합니다.

그러나 저는 로그변환을 시도한 데이터가 좋지 않은 예측값을 냈기에 이상치의 값들을 일부분 제거하여 모델을 학습시키는게 좋을 듯 합니다. 

데이터 전처리 1: 학습 및 추론 데이터 설정

제출을 위한 코드와 제가 확인할 코드를 나눠서 진행하였습니다.

from sklearn.model_selection import train_test_split

X = train_df.drop(columns=['ID', '근로기간','대출등급'])
y = train_df['대출등급']
train_x = train_df.drop(columns=['ID', '근로기간', '대출등급'])
train_y = train_df['대출등급']

test_x = test_df.drop(columns=['ID', '근로기간'])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)

데이터 전처리 2: 범주형 변수 수치화

LabelEncoder를 통해 범주형 변수 수치화를 진행합니다.

from sklearn.preprocessing import LabelEncoder

categorical_features = ['대출기간', '주택소유상태', '대출목적']

for i in categorical_features:
    le = LabelEncoder()
    le=le.fit(train_x[i])
    le=le.fit(X[i])

    train_x[i]=le.transform(train_x[i])
    X[i]=le.transform(X[i])

    for case in np.unique(test_x[i]):
        if case not in le.classes_:
            le.classes_ = np.append(le.classes_, case)
    test_x[i]=le.transform(test_x[i])

display(train_x.head(3))
display(test_x.head(3))

 

 

모델 선정 및 학습

RandomForestClassifier

from sklearn.ensemble import RandomForestClassifier

RFC = RandomForestClassifier()
RFC.fit(X_train, y_train)
max_depth_list = range(20,25)
accuracy = []

for m in max_depth_list:
    RFC = RandomForestClassifier(random_state = 42, max_depth = m)
    RFC.fit(X_train, y_train)
    pred = RFC.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(max_depth_list, accuracy)
plt.xlabel('max_depth')
plt.ylabel('accuracy')
plt.show()

최적의 깊이를 찾기위한 코드

from sklearn.metrics import accuracy_score

pred = RFC.predict(X_test)
score = accuracy_score(pred, y_test)
print(f"정확도: {score}")

가장 잘 나온 max_depth의 값을 선택하여 예측한 결과 정확도는 0.8231이 나왔습니다.

 

DecisionTreeClassifier

DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = 5)
DT.fit(X_train, y_train)
max_depth_list = range(1,101)
accuracy = []

for m in max_depth_list:
    DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = m)
    DT.fit(X_train, y_train)
    pred = DT.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(max_depth_list, accuracy)
plt.xlabel('max_depth')
plt.ylabel('accuracy')
plt.show()

가장 최적의 max_depth

DT = DecisionTreeClassifier(random_state = 42, criterion = 'entropy', max_depth = 19)
DT.fit(train_x, train_y)

 

가장 잘 나온 max_depth로 학습시켜줍니다.

 

KNeighborsClassifier

n_neighbors_list = range(1,10)
accuracy = []

for m in n_neighbors_list:
    KNN = KNeighborsClassifier(n_neighbors = m)
    KNN.fit(X_train, y_train)
    pred = KNN.predict(X_test)
    score = accuracy_score(pred, y_test)
    accuracy.append(score)

plt.plot(n_neighbors_list, accuracy)
plt.xlabel('n_neighors')
plt.ylabel('accuracy')
plt.show()

정확도가 앞서 실행한 두 모델에 비해 현저하게 낮기에 이 모델은 채택안하기로 결정합니다.

 

그래서 예측을 수행하여 데이콘 대회에 제출한 결과

0.79의 정확도를 얻었습니다.

처음으로 대회에 참여하여서 이정도면 나쁘지 않은 결과라고 생각합니다. 

앞으로 더욱 정진하겠습니다!

'프로그래밍 > 프로젝트' 카테고리의 다른 글

ARIMA 모델 검증 및 예측 정확도 평가  (0) 2024.05.21
ARIMA 모델  (0) 2024.05.21
고객 유지를 위한 필요한 행동 예측  (1) 2024.01.14
원본 데이터 보존  (0) 2023.11.28
머신러닝 기초 및 순서  (0) 2023.11.21

코칭스터디 2024

1. 데이터 구성

  • Kaggle 데이터셋( https://www.kaggle.com/blastchar/telco-customer-churn )은 통신사 고객 이탈(Churn)에 대한 정보
  • IBM에서 제공했으며 고객 데이터를 분석하여 고객 유지 프로그램을 개발하는 데 도움이 됨.
    • 고객 인구 통계 정보(Demographic info): 고객의 성별, 연령대, 배우자 및 부양 가족의 유무(Gender, SeniorCitizen, Partner, Dependents)
    • 고객 이탈(Churn) 정보: 서비스를 중단 여부에 대한 정보
    • 서비스 가입 정보(Services subscribed): 고객들이 가입한 서비스들, 예를 들어 전화, 다중 라인, 인터넷, 온라인 보안, 온라인 백업, 장치 보호, 기술 지원, 스트리밍 TV 및 영화( honeService, MultipleLine, InternetService, OnlineSecurity, OnlineBackup, DeviceProtection, TechSupport, StreamingTV, StreamingMovies) 등에 대한 정보
    • 고객 계정 정보(Customer account info): 고객이 얼마나 오래 서비스를 이용했는지, 계약 유형, 결제 방법, 무페이퍼 청구 여부, 월별 요금, 총 요금 (CustomerID, Contract, PaperlessBilling, PaymentMethod, MonthlyCharges, TotalCharges, Tenure)등의 정보

 

2. 필요한 라이브러리로드

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

3. 데이터셋 로드

df = pd.read_csv("https://bit.ly/telco-csv", index_col="customerID")
df.shape
df.head() # 데이터 확인
df.info() # 데이터 집합과 각 열들의 자료형 확인
# df.isnull().sum()는 컬럼별로 결측치의 합계를 구합니다.
print(df.isnull().sum())
# df.isnull().sum().sum() 전체 결측치의 합계를 구합니다.
df.isnull().sum().sum()

4. 학습, 예측 데이터셋 나누기

5. 학습, 예측에 사용할 컬럼 

# 학습, 예측에 사용할 컬럼에 이름을 지정
# 범주형 데이터 (object, category)는 전처리가 따로 필요
# 따라서 수치데이터만을 사용
feature_names = df.select_dtypes(include = "number").columns
feature_names
# train 과 test 로 나누기 위해 데이터를 기준을 정함.
split_count = int(df.shape[0] * 0.8)
split_count

6. 정답값이자 예측해야할 값

label_name = "Churn"
label_name #정답값

7. 학습, 예측 데이터셋 만들기

# 데이터의 80%을 나눌 기준 인덱스(split_count)로 문제 데이터(X)를 train, test로 나눔.
# 데이터의 80%을 나눌 기준 인덱스(split_count)로 정답 데이터(y)를 train, test로 나눔.
train = df[:split_count].copy()
test = df[split_count:].copy()

X_train = train[feature_names]
y_train = train[label_name]

X_test = test[feature_names]
y_test = test[label_name]

X_train.shape, X_test.shape, y_train.shape, y_test.shape

8. 머신러닝 알고리즘 가져오기

DecisionTreeClassifier(
    *,
    criterion='gini', # 분할방법 {"gini", "entropy"}, default="gini"
    splitter='best',
    max_depth=None, # The maximum depth of the tree
    min_samples_split=2, # The minimum number of samples required to split an internal node
    min_samples_leaf=1, # The minimum number of samples required to be at a leaf node.
    min_weight_fraction_leaf=0.0, # The minimum weighted fraction of the sum total of weights
    max_features=None, # The number of features to consider when looking for the best split
    random_state=None,
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    class_weight=None,
    ccp_alpha=0.0,
)
  • 주요 파라미터
    • criterion: 가지의 분할의 품질을 측정하는 기능
    • max_depth: 트리의 최대 깊이
    • min_samples_split:내부 노드를 분할하는 데 필요한 최소 샘플 수
    • min_samples_leaf: 리프 노드에 있어야 하는 최소 샘플 수
    • max_leaf_nodes: 리프 노드 숫자의 제한치
    • random_state: 추정기의 무작위성을 제어. 실행했을 때 같은 결과가 나오도록 함.
from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier()

9. 학습(훈련)

model.fit(X_train, y_train)

10. 예측

# 데이터를 머신러닝 모델로 예측(predict)
y_predict = model.predict(X_test)
y_predict[:5]

11. 트리 알고리즘 분석하기

from sklearn.tree import plot_tree

plt.figure(figsize=(20, 10))

tree = plot_tree(model,
                 feature_names = feature_names,
                 filled = True,
                 fontsize = 10,
                 max_depth = 4)

12. 정확도 측정하기

# 피처 중요도를 시각화
sns.barplot(x = model.feature_importances_, y=feature_names)
from sklearn.metrics import accuracy_score

accuracy_score(y_test, y_predict)

 

'프로그래밍 > 프로젝트' 카테고리의 다른 글

ARIMA 모델  (0) 2024.05.21
데이콘 - 고객 대출 등급 분류 프로젝트  (1) 2024.02.09
원본 데이터 보존  (0) 2023.11.28
머신러닝 기초 및 순서  (0) 2023.11.21
데이터 프로젝트 (데이터 확인)  (1) 2023.11.01

함수를 둘러싼 환경을 유지하고 다시 꺼내서 사용하는 함수

 

def calc():
    a = 3 
    b = 5 

    def mul_add(x):
        return a * x + b

    print(f"{locals()['a'], locals()['b'] = }")

    return(mul_add)

c = calc()
print(c(1), c(2), c(3), c(4), c(5))

 

def calc():
    a = 3 
    b = 5
    return lambda x: a * x + b 

c = calc()
print(c(1), c(2), c(3))

 

def calc():
    a = 3
    b = 5
    total = 0

    def mul_add(x):
        nonlocal total
        print(total)
        total = total + a * x + b
        print(total)

    return mul_add 
    

c = calc()

c(1)
c(2)

 

def outer():
    x = 100

    def inner(y):
        nonlocal x
        return x+y
        
    return inner

foo = outer()
foo(5)

'프로그래밍 > Python' 카테고리의 다른 글

제너레이터(Generator)  (0) 2024.08.12
Python - 클래스 속성과 메서드 사용  (2) 2023.11.25
Python - 인스턴스 변수 vs 정적변수  (0) 2023.11.25
Python - 클래스 생성자  (2) 2023.11.25
Python - 클래스  (1) 2023.11.25
# 동전을 3번 던졌을 때 3번 연속 앞면이나 뒷면이 나오는 확률
n = 100000
count = 0

for(i in 1:n){
    u = runif(3, 0, 1)
    coin = as.numeric(u > 0.5)
    
    if(coin[1] == coin[2] & coin[2] == coin[3]){
        count = count + 1
    }
}

# 동전을 10번 던졌을 때 3번 연속 앞면이나 뒷면이 나오는 확률 
n = 10000
count = 0

for(i in 1:n){
    u = runif(10, 0, 1)
    coin = as.numeric(u > 0.5)
    
    for(j in 1:8){
        if(coin[j]==coin[j+1] & coin[j+1]==coin[j+2]){
            count = count + 1
            break
        }
    }
}
count/n


## 주사위 던지기 ====
### 주사위를 trial번 만큼 던져서 1/6에 근접하는지 확인 ====
trial = c(30, 50, 100, 500)

for (n in trial){
    u = runif(n, 0, 1)
    
    dot = numeric(n)
    case = numeric(n)
    
    for(i in 1:n){
        if(u[i] < 1/6){
            dot[i] = 1
        } else if(u[i] < 2/6){
            dot[i] = 2
        } else if(u[i] < 3/6){
            dot[i] = 3
        } else if(u[i] < 4/6){
            dot[i] = 4
        } else if(u[i] < 5/6){
            dot[i] = 5
        } else if(u[i] < 6/6){
            dot[i] = 6
        } 
    }
    
    ### 1 =====
    case = dot < 2 # 1인지 아닌지 구하는 것
    sum(case) # 1의 개수  = n*(1/6)
    sum(case)/n  # p = 1/6 = 0.167
    
    plot(table(dot), main = paste0("n = ",n),
         type = "h", col = "darkgreen", lwd = 5)
}


### 주사위 관련 나만의 코드 ====
### 반복문으로 만들수 있는걸 만들어봄. 
par(mfrow = c(2,2), mar = c(3, 5, 2, 2))
# mar 은 상하좌우의 마진(여백)을 나타낸 것임. 
trial = c(30, 50, 100, 500)

for(n in trial){
    u = runif(n, 0, 1)
    
    dot = numeric(n)
    case = numeric(n)
    final = matrix(NA, nr = 6, nc = 2)
    
    for(i in 1:n){
        if(u[i] < 1/6){
            dot[i] = 1
        } else if(u[i] < 2/6){
            dot[i] = 2
        } else if(u[i] < 3/6){
            dot[i] = 3
        } else if(u[i] < 4/6){
            dot[i] = 4
        } else if(u[i] < 5/6){
            dot[i] = 5
        } else if(u[i] < 6/6){
            dot[i] = 6
        }    
    }
    
    for(k in 1:length(unique(dot))){
        for(y in 1:length(dot)){
            if(dot[y] == k){
                case[k] = case[k] + 1 
            }   
        }
    }
    
    cat("시행횟수는", n, "\n")
    for(x in 1:length(unique(dot))){
        cat("주사위",x,
            "의 눈의 경우의 수는", case[x], 
            "확률은",case[x]/n,"\n")
    }
    
    plot(table(dot), main = paste0("n = ",n),
         type = "h", col = "darkgreen", lwd = 5)
}

## 자유투 =====

### 자유투를 던졌을 때 연속 2번이상 성공할 확률 ====
n = 1000
k = 0

for(i in 1:n){
    u = runif(5, 0, 1)
    shoot = as.numeric(u <= 0.2)
    

    if(sum(shoot) >= 2){
        k = k + 1
    }
}
k/n

x1 = choose(5,0)*(0.2)^0*(0.8)^5
x2 = choose(5,1)*(0.2)^1*(0.8)^5
1 - (x1 + x2)



### 2 ====
n = 1000
gathering = c(NA) ; gathering2 = numeric(n) 
# gathering2는 잘못된 방식으로 구하는 걸 보여주는 변수

for(i in 1:n){
    u = runif(100, 0, 1)
    shoot = as.numeric(u <= 0.2)
    
    for(j in 1:98){
        if(shoot[j]*shoot[j+1]*shoot[j+2] == 1){
            break
        }
    }
    
    # 잘못된 코드
    for(k in 1:98){
        if(shoot[k] == shoot[k+1] 
           & shoot[k+1] == shoot[k+2]){
            break
        }
    }
    gathering[i] = j+2
    gathering2[i] = k+2
}
mean(gathering)
mean(gathering2)

## 뷔퐁의 바늘실험 ====
needle_experiment = function(n, l, d){
    set.seed(100)
    k = 0
    
    for(i in 1:n){
        x = (d/2)*runif(1) 
        # d/2 
        # 바늘 가운데에서 가장 가까운 거리의 평행선
        # d/2 보다 클수는 없어서 
        # runif(1)
        theta = runif(1, 0, pi)
        
        if(x <= (l/2)*sin(theta)){
            k = k + 1
        }
    }
    prob = k/n
    pi.hat = 2*l/(prob*d)
    return(c(prob = prob, pi.hat = pi.hat))
}

needle_experiment(50000, 10, 20)


### 연습 ====

needle_experiment = function(n, l, d){
    k = 0
    set.seed(100)
    
    for(i in 1:n){
         x = (d/2)*runif(1)
         theta = runif(1, 0, pi)
         
         if(x <= (l/2)*sin(theta)){
             k = k + 1
         }
    }
    prob = k/n
    pi.hat = 2*l/(prob*d)
    return(c(prob = prob, pi.hat = pi.hat))
}

needle_experiment(50000, 15, 20)

 

 

중심극한정리를 사용한 정규분포

CLT_norm = function(x_bar_n, sample_m, mu, sig){
    xbar = as.numeric(x_bar_n)
    
    for(i in 1:x_bar_n){
        no = rnorm(sample_m, mu, sig)
        xbar[i] = mean(no)
    }
    
    result_mean = mean(xbar)
    result_var = var(xbar)
    ori_var= sig^2/sample_m
    return(c(result_mean = result_mean,
             result_var = result_var,
             ori_var = ori_var))
    print(h)
}


CLT_norm(10000, 100, 5, 2)

이항분포

n0 = 30; p = 0.1; mu = n0*p; var = n0*p*(1-p)

m = 1000 # 자료 set의 개수(xbar의 개수)
n = 100 # 난수 개수 (표본의 개수)

xbar = c()
for(i in 1:m){
    x = rbinom(n, n0, p) #이항분포에서 추출
    xbar[i] = mean(x)
}

xbar_mu = mean(xbar) ; mu
xbar_var = var(xbar) ; var/n

# histogram
hist(xbar, breaks = "fd", prob = T)

# theoretical curve ; N(mu, sqrt(var/n))
curve(dnorm(x, mu, sqrt(var/n)), add = T)

 

포아송분포

lamb = 5
var = lamb

m = 1000 # 자료 set의 개수 (xbar의 개수) 
n = 100 # 난수 개수 (표본개수)

xbar = c()
for(i in 1:m){
    x = rpois(n, lambda = lamb)
    xbar[i] = mean(x)
}
xbar_mu = mean(xbar) ; lamb
xbar_var = var(xbar) ; var/n

hist(xbar, breaks = "fd", prob = T)
curve(dnorm(x, lamb, sqrt(var/n)), add = T)

 

이항분포의 CLT를 n을 바꿔가며 확인

### n바꾸어서 CLT 확인 ====
p = 0.5 ; q = 1-p

par(mfrow = c(2,2))
for(n in c(10, 100, 1000, 10000)){
    
    p_hat = c()
    for(i in 1:1000){
        num = rbinom(n, 1, p)
        p_hat[i] = mean(num)
    } # for i
    
    CLT = (p_hat - p) / sqrt((p*q)/n)
    
    hist(CLT, probability = T,
         ylim = c(0, 0.5), xlim = c(-3, 3),
         main = paste0("n = ", n))
    
    curve(dnorm(x, 0, 1),
          xlim = c(-3, 3), ylim = c(0, 0.5),
          col = "tomato", lwd = 2,
          main = "X ~ N(0,1)", add = T)
} # for n

### 동전 던지기 ====
k = 0
n = 10000

for(i in 1:n){
    u = runif(3,0,1)
    coin = as.numeric(u > 0.5)
    
    if(coin[1] == coin[2] & coin[2] == coin[3]){
        k = k + 1
    }
}
k/n


### 동전 던지기 2 ====
x = 0
n = 10000

for(i in 1:n){
    u = runif(10, 0, 1)
    coin = as.numeric(u > 0.5)
    
    for(j in 1:(length(u)-2)){
        if(coin[j] == coin[j+1] & coin[j+1] == coin[j+2]){
            x = x + 1
            break # prevent double count
        }
    }
}
x/n

 

ascending_sorting = function(vec){
    sort.rank = matrix(NA, nr = length(vec), nc = 2)
    
    for(i in 1:length(vec)){
        val = vec[i]
        rank = 1
        for(j in 1:length(vec)){
            if(val > vec[j]){
                rank = rank + 1
            } else {
                rank = rank
            }
        }
        sort.rank[i,] = c(val,rank)
    }
    sort.i = c()
    
    for(k in 1:length(vec)){
        sort.i = c(sort.i, sort.rank[sort.rank[, 2] == k, 1])
    }
    return(sort.i)
}

set.seed(100)
vec = runif(3, 0, 30)
ascending_sorting(vec)

 

코드를 이해하는 흐름

> 오름차순 정렬을 위한 함수를 설정한다.

> 그러기 위해서는 매개변수가 필요하다.

> 그 매개변수는 vector의 형태로 와야한다. 

> 오름차순을 단순히 최댓값과 최솟값을 비교하는 것처럼 하기에는 무리가 있다. 따라서 우리는 matrix를 하나 설정해서 각 값에 대하여 ranking을 매길 것이다.

> ranking을 매기기 위해서는 반복문을 2번 사용해야한다.

 >> 즉, 하나의 값에 대하여 vector 안에 존재하는 모든 값들과 비교를 하는 방식으로 말이다.

> 그러고 난 다음에는 NA값으로 지정한 matrix에 값을 넣는다.

> 넣고 난 후의 matrix의 값들에 대해서 오름차순을 지정하기 위해서는 

 >> sort.i = c(sort.i, sort.rank[sort.rank[, 2] == k, 1]) 이런 식으로 코드를 짜야한다.

 >> 그 이유는 sort.rank[sort.rank[,2] == k, 1] 가 값이 여러개이기 때문에 그 값에 대해서 sort.i를 넣는 것이다.

train = raw_data_train.copy()
test = raw_data_test.copy()
submission = raw_data_submission.copy()

 

원본 데이터를 보존하면서 독립적으로 작업하기 위해 사용

원본 데이터를 직접 수정하는 대신, 복사하여 새로운 데이터프레임을 생성하면 원본 데이터의 무결성 보존 가능

 

copy() 메서드를 사용하여 원본 데이터를 복사하는 방법은 데이터프레임의 독립성을 유지하고,

원본 데이터와의 연관성을 끊을 수 있음.

 

+ Recent posts