BASEMENT
Python 8주차 - 1 본문
파이썬 실습
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
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 |