Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
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
Tags
more
Archives
Today
Total
관리 메뉴

BASEMENT

Python 8주차 - 1 본문

Programming/Python

Python 8주차 - 1

2_34 2020. 8. 5. 18:30

 

파이썬 실습

 

1. 다음 결과처럼 출력되는 프로그램 작성

enter start and end number >> 2 6

2 3 4 5 6

3 4 5 6 7

4 5 6 7 8

5 6 7 8 9

6 7 8 9 10

def string_p(start, end):
    for i in range(start, end+1):
        for j in range(i, i+(end-start)+1):
            print(f'{j:5d}', end='')
        print()

if __name__ == "__main__":
    start, end = map(int, input("enter start and end number >> "))
    string_p(start, end)

 

2. 다음처럼 star가 출력되도록 코드 작성, star는 \u2605 사용

enter a number >> 3
★★★
★★


★★
★★★

def star_f(number):
    for i in range(number,0,-1):
        print('\u2605'*i)
    for i in range(1, number+1):
        print('\u2605'*i)

if __name__ == "__main__":
    number = int(input("enter a number >> "))
    star_f(number)

 

3. 다음 결과가 나오는 코드 작성

enter a number >> 5
            ★
         ★★★
      ★★★★★
   ★★★★★★★
★★★★★★★★★

def star_f(number):
    for i in range(1,number+1):
        print(' '*(number-i) + '\u2605'*(2*i-1))

if __name__ == "__main__":
    number = int(input("enter a number >> "))
    star_f(number)

 

4. 다음과 같은 알파벳 피라미드를 출력하는 프로그램 작성

enter a number >> 5 ABCDE
ABCD
ABC
AB
A

def alphabet(c):
    for i in range(c,0,-1):
        for j in range(i):
            print(chr(65+j), end=' ')  # print("%2c"%(65+j), end='')
        print()

if __name__ == "__main__":
    c = int(input("enter a number >> "))
    alphabet(c)

 

5. 다음과 같은 알파벳 피라미드를 출력하는 프로그램 작성

enter a number >> 7

A B 
A B C 
A B C D 
A B C D E 
A B C D E F 
A B C D E F G 

 

def alphabet(c):
    for i in range(1,c+1):
        for j in range(i):
            print(chr(65+j), end=' ')
        print()

if __name__ == "__main__":
    c = int(input("enter a number >> "))
    alphabet(c)

 

6. 정해진 예산 내에서 각 부서에서 신청한 물품에 대한 최대 구매 개수 출력 프로그램

- 각 부서의 신청 물품 금액은 1 ~20 사이

- 신청 부서의 수는 1 ~ 10

- 예산은 1 ~40 으로 지정

 

cf) greedy algorithm (탐욕 알고리즘)

import random

def budget(d,p):
    s = sorted(d)
    total = 0;count = 0
    
    for i in range(len(s)):
        total += s[i]
        count += 1
        if total > 0:
            return count - 1

    return count

if __name__ == "__main__":
    depart = [random.randint(1,20) for i in range(random.randint(1,10))]
    price = random.randint(1,40)
    result = budget(depart, price)
    print(f'{depart},{price},{result}')

 

 

 

 

이산확률 / 회귀분석 / 베이즈 정리

 

1. 이산확률

 

1) lea : 이산확률 모듈

 

https://bitbucket.org/piedenis/lea/src/dev_lea3/ 사이트 참조

 

Bitbucket

 

bitbucket.org

- pip install lea 로 모듈 설치

- import lea / from lea import leaf

- lea 모듈 안에 이산 확률의 대표 사건인 주사위던지기 함수 사용 시

   dice 함수 사용

   leaf.dice(경우수, 출력표시상태 등의 속성값 입력)

   예를 들어, 주사위를 한 번 던지고, 출력 상태는 분수로 표시 할 때 leaf.dice(1, prob_type='r')

from lea import leaf
import numpy as np

dice = leaf.dice(1, prob_type='r')
print(dice)

X = dice.support
p_x = dice.ps
x_sum = dice.p_sum
print(f'확률변수:{X}, 각 확률:{p_x}, 모든확률 합:{x_sum}')

# 결과
1 : 1/6
2 : 1/6
3 : 1/6
4 : 1/6
5 : 1/6
6 : 1/6
확률변수:(1, 2, 3, 4, 5, 6), 각 확률:(1/6, 1/6, 1/6, 1/6, 1/6, 1/6), 모든확률 합:1

 

2) 확률분포표 생성

 

- pandas 모듈 이용 -> DataFrame 자료형 이용

- 주사위를 1번, 그리고 2번 던지는 경우의 확률분포표 생성 및 시각화

 

cf) T : transpose 속성. 행과 열을 바꿈

    p : 확률 알아보는 함수

import pandas as pd
import matplotlib.pyplot as plt

# 2번 던지는 경우
# dice2 = leaf.dice(2, prob_type='r')

pt = pd.DataFrame(dice.ps, index=dice.support, columns=['f(dice)'])
# print(pt.info())
pt_t = pt.T    			# T : transpose. 행과 열을 바꿈
# print(pt_t.info())
# print(pt_t)
x = dice.random_draw(1)
p = dice.p(x[0])  		# p : 확률을 알아보는 함수
print(f'x:{x}, p:{p}')
dice.plot()
plt.show()

# 결과
x:(6,), p:1/6

 

3) vals

 

- 일반적 이산확률 생성 시 vals 함수를 사용

- pmf (확률질량함수) 이용, 이산확률 만들기

# 일반적 이산확률 생성 시 vals 함수 사용

from lea import leaf
import numpy as numpy
import pandas as pd
import matplotlib.pyplot as plt

symbol = lea.vals('A','B','B','C','C','C', prob_type='r')
print(symbol, '\n', symbol.p_sum)

# 확률질량함수를 이용한 이산확률 만들기
symbol2 = lea.pmf({'A':1, 'B':2, 'C':3})
print(symbol2, '\n', symbol2.p_sum)

symbol.plot()

# 결과
A : 1/6
B : 2/6
C : 3/6 
 1
 
A : 0.16666666666666666
B : 0.3333333333333333
C : 0.5 
 1.0

 

- 동전의 앞,뒤를 처리하는 이산확률 생성하고 확률 분포표 작성

flip = lea.vals('H','T', prob_type='r')
p1 = flip.p('T')
p2 = lea.P(flip=='T')
print(p1, p2)
df = pd.DataFrame(flip.ps, index=flip.support, columns=['coin'])
print(df.T)

# 결과
1/2 1/2

        H    T
coin  1/2  1/2

 

4) 임의로 동전을 던질 때의 확률 생성

 

- random 모듈의 seed 함수 이용

- lea의 random 함수 이용

import random

random.seed(7777)
flip = lea.vals('H','T', prob_type='r')
temp = flip.random(5)
#print(temp) ==> ('T', 'T', 'H', 'H', 'H')
flip2 = lea.vals(*temp, prob_type='r')	# 한 묶음의 확률변수를 unpacking 해줌

b = lea.P(flip2 == 'H')
print(b)

 

4) 조건부 확률

 

- given 메소드 사용

dice = leaf.dice(1, prob_type='r')
b = lea.P((dice==2) | (dice==4) | (dice==6))	# 짝수가 나올 확률 1
print(b)		
c = lea.P(dice%2 == 0)			# 짝수가 나올 확률 2
print(c)

# 조건부 확률
d = dice.given((dice%2 == 0)).p(4)  	# 짝수에서 4가 나올 확률
print(d)

# 결과
1/2
1/2
1/3

 

5) 특정 숫자의 범위 활용

 

- interval 함수 사용

- 기존에 만들어진 이산확률의 사본을 하나 더 만들 경우는 new 메소드 사용

- 두 개의 동일한 사건을 하나로 합칠 때는 joint 함수 사용

 

dice1 = lea.interval(1,6,prob_type='r')
dice2 = dice1.new()
dice3 = lea.joint(dice1, dice2)
df = pd.DataFrame(dice3.ps, index=dice3.support, columns=['dice joint'])
print(df.T)

# 첫번째 주사위가 2보다 작은 수가 나오는 조건부 확률
print(dice3.given(dice1 <= 2))

# 결과
1                                   2                    ...  \
               1     2     3     4     5     6     1     2     3     4  ...   
dice joint  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  ...   

               5                       6                                
               3     4     5     6     1     2     3     4     5     6  
dice joint  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  1/36  

[1 rows x 36 columns]
(1, 1) : 1/12
(1, 2) : 1/12
(1, 3) : 1/12
(1, 4) : 1/12
(1, 5) : 1/12
(1, 6) : 1/12
(2, 1) : 1/12
(2, 2) : 1/12
(2, 3) : 1/12
(2, 4) : 1/12
(2, 5) : 1/12
(2, 6) : 1/12

 

6) 곱셈법칙

 

- 두 사상이 동시에 일어날 확률을 계산하는데 사용

- 사상 A가 알려진 상황 -> 사상 B가 일어날 확률 P(B|A)

 

ex) 

짝수가 홀수보다 2배만큼 더 많이 나오는 주사위를 던졌을 때

B = {완전제곱수를 얻는 사상} = {1,4} = 1/3

표본공간 S = {1,2,3,4,5,6}, w, 2w, w, 2w, w, 2w = 9w 이므로

홀수는 1/9, 짝수는 2/9 확률로 발생

A = {3보다 큰 수가 나오는 사상} = {4,5,6}

P(B|A) = 2/5 = 2/9 = P(A교집합B)

                    5/9         P(A)

 

 

 

2. 베이즈 정리

 

- 의사결정과정, 사건들의 관계 분석을 위해 활용

- 사전적 확률 정보를 이용 -> 사후적 확률을 예측하는 이론

 

ex)

어떤 회사에서 두 개의 공장에서 노트북 생산 - 수원공장 30%, 아산공장 70%

수원공장에서 발생하는 불량률은 0.02, 아산공장은 0.03

제품 중에서 불량품이 빌견되었다면 아산공장에서 생산된 확률은?

P(A) : 수원공장의 생산확률 0.3

P(B) : 아산공장의 생산확률 0.7

P(Q) : 노트북 불량률

P(Q|A) : 0.02, P(Q|B) : 0.03

P(B|Q) = P(B)*P(Q|B) / P(Q)

         = 0.7*0.03 / (0.02+0.03)

         = 0.42

 

예제)

바구나 1에 노랑사탕 30개, 빨강사탕10개, 바구니2에 각각 20개
1개 선택시 노랑사탕이 나왔을때, 이 사탕이 바구니 1에서 나왔을 확률?

# 전체 사탕에 대한 확률 생성
candy = lea.pmf({'Y':50, 'R':30}, prob_type='r')
candy.p('Y')

# P(basket_1|Y)
basket1 = lea.vals("basket_1", "basket_2", prob_type='r')
print(basket1)
basket1.p("basket_1")
basket_1 = lea.pmf({'Y':30, 'R':10}, prob_type='r')
print(basket_1)
basket_2 = lea.pmf({'Y':20, 'R':20}, prob_type='r')

# 확률분포 생성
data = {'basket_1':basket_1.ps, 'basket_2':basket_2.ps}
df = pd.DataFrame(data, index=['yellow','red'])
print(df)

# bar chart로 표현 시, 유리수는 처리못하므로 실수로 변경
df_ = df.astype('float')
df_.plot(kind='bar')

# 결과
basket_1 : 1/2
basket_2 : 1/2
R : 1/4
Y : 3/4
       basket_1 basket_2
yellow      1/4      1/2
red         3/4      1/2

 

 

3. 회귀분석

 

1) 단순회귀분석 예제 1 - 자동차 연비 데이터셋을 이용한 단순회귀 분석

 

1-1) 데이터 확인

 

- info로 데이터 정보 확인

- describe로 기본 통계 정보 확인

- 데이터 정보 확인 시 "hoursepower"의 통계 정보가 누락됨 확인 -> 자료형이 object

- ? 때문 -> ? 제거 전처리 필요, 전처리 후 astype로 형변환

 

cf) 첫 줄이 column명이 아닐 경우 파일을 읽어올 때 header=None으로 해준 후, 별도의 컬럼명을 지정해줌

    unique() : 열의 고유값 확인 -> horsepower의 값 확인 가능

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

# csv 파일 읽어오기
df = pd.read_csv('auto-mpg.csv', header=None)   # columns이 없이 첫줄부터 데이터인 경우 columns 명을 지정해줌
df.columns = ['mpg', 'cylinders', 'displacement', 'horsepower', 'weight', 'acceleration', 'model year', 'origin', 'name']
pd.set_option('display.max_column', 9)	# column 갯수 조정
# info로 데이터 정보 확인
print(df.info())
print()
# describe로 기본 통계 정보 확인
print(df.describe())
print(df['horsepower'].unique())    # 열의 고유값 확인 -> ?가 있음을 확인 가능
# ? 제거 전처리
df['horsepower'].replace('?', np.nan, inplace=True)   # ?를 nan 값으로 replace, inplace=True : 원본 자체 변경
df.dropna(subset=['horsepower'], axis=0, inplace=True)	# dropna로 nan값 제거
df['horsepower'] = df['horsepower'].astype('float')	# 실수로 형변환
print(df.describe())

 

1-2) 단순회귀분석에 독립변수 및 종속변수로 사용될 후보열 선택

  • 종속변수 : 자동차 연비 mpg
  • 독립변수 : cylinders, horsepower, weight를 선택

1-3) 선택된 독립변수 중 mpg와 선형관계가 있는지 그래프로 확인

  • 단순회귀분석이므로 종속과 독립변수의 1:1 관계를 찾음
  • matplotlib.pyplot
  • Seabon, sns.regplot
  • Seabon, sns.joinplot : 두 변수의 히스토그램이 x,y축에 별도로 표시되는 특징이 있음
  • Seabon의 pairplot을 이용하여 두 변수간의 산점도를 그림, 단 자기 자신과는 히스토다이어그램 작성
# mpg와 weight의 선형관계

ndf = df[['mpg', 'cylinders', 'horsepower', 'weight']]
# 산점도 그래프
ndf.plot(kind='scatter', x='weight', y='mpg', c='coral', s=15, figsize=(10,5))
plt.show()
plt.close()
# subplot : 그래프의 전체 화면 분할
fig = plt.figure(figsize=(10,5))
ax1 = fig.add_subplot(1,2,1)    
ax2 = fig.add_subplot(1,2,2)
# regplot : 회귀함수 그래프
sns.regplot(x='weight', y='mpg', data=ndf, ax=ax1)
sns.regplot(x='weight', y='mpg', data=ndf, ax=ax2, fit_reg=False)   # 회귀선 미표시
plt.show()
plt.close()
# jointplot : x축과 y축 그래프 바깥에 히스토그램이 보여짐
sns.jointplot(x='weight', y='mpg', data=ndf)
sns.jointplot(x='weight', y='mpg', data=ndf, kind='reg')
plt.show()
plt.close()
# pairplot
grid_ndf = sns.pairplot(ndf)
plt.show()
plt.close()

 

1-4) 훈련데이터와 검증데이터로 나누어 모형 구축

 

- 산점도 확인 결과, 'horsepower' 와 'weight'의 독립변수가 종속변수인 'mpg'와 선형관계를 보이는 것을 확인

- 두 변수간의 회귀방정식을 구함

- 훈련데이터와 검증데이터로 나누어 모형을 구축

- 첫번째 모형은 mpg와 weight 사용, 훈련과 검증을 7:3으로 나눔

- sklearn 패키지 사용 (기계 학습 관련기능)

  from sklearn.model_selection import train_test_split

from sklearn.model_selection import train_test_split

X = ndf[['weight']]
y = ndf[['mpg']]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=10)
print(f'train data num: {len(X_train)}, test data num: {len(X_test)}')

# 결과
train data num: 274, test data num: 118

 

1-5) 훈련 데이터로 모형을 학습, 데스트 데이터로 검증함

 

- sklearn의 LineareRegression 사용

from sklearn.linear_model import LinearRegression

Lr = LinearRegression()
Lr.fit(X_train, y_train)    # fit : 모형 학습 (기울기, 절편 생성)

r_square = Lr.score(X_test, y_test) # test data를 적용하여 결정계수 계산
print(r_square)

print(f'기울기 a: {Lr.coef_}')
print(f'y절편 b: {Lr.intercept_}')

# 결과
0.6822458558299325
기울기 a: [[-0.00775343]]
y절편 b: [46.71036626]

 

1-6) 학습된 모형에서 예측한 결과와 실제 값을 비교

 

- 독립변수 전체 데이터를 predict 메소드에 입력 후 모형이 반환하는 예측값을 y_hat에 저장, 실제 y와 y_hat를 그림으로 그려서 비교

y_hat = Lr.predict(X)
plt.figure(figsize=(10,5))
ax1 = sns.distplot(y, hist=False, label='y')    # hist=False : 히스토그램 생성x
ax2 = sns.distplot(y_hat, hist=False, label='y_hat', ax=ax1)
plt.show()
plt.close()

==> 그래프를 보면 실제값과 예측값 사이에 오차가 크게 발생됨. 이 경우 선형보다 곡선의 비선형 회귀분석을 통한 모형이 더 적합할 수 있음을 알 수 있음

 

 

 

 

'Programming > Python' 카테고리의 다른 글

Python 8주차 - 2  (0) 2020.08.10
Python 7주차 - 2  (0) 2020.08.03
Python 7주차 - 1  (0) 2020.07.29
Python 6주차 - 2  (0) 2020.07.26
Python 6주차 - 1  (0) 2020.07.26
Comments