python-for-data-analysis-II

2024. 1. 21. 18:31python/intermediate

재무 항목 처리

In [ ]:
import pandas as pd
   
james_bond_data = pd.read_csv("jamesbond.csv").convert_dtypes()

james_bond_data.head()

new_column_names = {
    "Release": "release_date",
    "Movie": "movie_title",
    "Bond": "bond_actor",
    "Bond_Car_MFG": "car_manufacturer",
    "US_Gross": "income_usa",
    "World_Gross": "income_world",
    "Budget ($ 000s)": "movie_budget",
    "Film_Length": "film_length",
    "Avg_User_IMDB": "imdb",
    "Avg_User_Rtn_Tom": "rotten_tomatoes",
    "Martinis": "martinis_consumed",
    "Kills_Bond": "bond_kills",
}

data = james_bond_data.rename(columns=new_column_names)

data.columns

data.info()

data.loc[data.isna().any(axis="columns")]

data = james_bond_data.rename(columns=new_column_names).combine_first(
     pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}})
)

pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}})

data.info() 이전에 실행한 코드에서도 미묘한 문제가 드러났습니다. income_usa, income_world, movie_budget 및 film_length 열의 데이터 유형은 모두 유형입니다. 열도 string. 그러나 문자열은 계산에 거의 사용되지 않으므로 이러한 유형은 모두 숫자 유형이어야 합니다. 마찬가지로 출시 날짜가 포함된 release 컬럼도 문자열이어야 합니다.

In [ ]:
data[
    ["income_usa", "income_world", "film_length"]
].head()

여러 열에 액세스하려면 열 이름의 목록을 DataFrame의 [] 연산자에 전달합니다. data.loc[]를 사용할 수도 있지만 data[]만 사용하는 것이 더 깔끔합니다. 두 옵션 모두 해당 열의 모든 데이터가 포함된 DataFrame을 반환합니다. 관리 가능한 상태를 유지하려면 .head() 메소드를 사용하여 처음 5개 레코드로 출력을 제한하세요.

보시다시피 3개의 재무 열에는 각각 달러 기호와 쉼표 구분 기호가 있고 film_length 열에는 "mins"가 포함되어 있습니다. 분석에 남은 숫자를 사용하려면 이 항목을 모두 제거해야 합니다. 이러한 추가 문자로 인해 데이터 유형이 문자열로 잘못 해석됩니다.

전체 DataFrame에서 $ 기호를 바꿀 수 있지만 이렇게 하면 원하지 않는 위치에서 기호가 제거될 수 있습니다. 한 번에 한 열씩 제거하는 것이 더 안전합니다. 이를 위해 DataFrame의 .assign() 메소드를 효과적으로 활용할 수 있습니다. DataFrame에 새 열을 추가하거나 기존 열을 업데이트된 값으로 바꿀 수 있습니다.

시작점으로 DataFrame의 열에 있는 $ 기호를 바꾸고 싶다고 가정해 보겠습니다

In [ ]:
data = (
   james_bond_data.rename(columns=new_column_names)
   .combine_first(
       pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}})
   )
   .assign(
       income_usa=lambda data: (
           data["income_usa"]
           .replace("[$,]", "", regex=True)
           .astype("Float64")
       ),
   )
)

income_usa 열을 수정하려면 새 데이터를 pandas Series로 정의하고 이를 data DataFrame의 .assign() 방법으로 전달해야 합니다. 그런 다음 이 메서드는 기존 열을 새 시리즈로 덮어쓰거나 이를 포함하는 새 열을 만듭니다. 새 데이터 계열을 참조하는 명명된 매개 변수로 업데이트하거나 생성할 열의 이름을 정의합니다. 이 경우 income_usa.라는 매개변수를 전달합니다.

람다 함수를 사용하여 새 시리즈를 만드는 것이 가장 좋습니다. 이 예제에 사용된 람다 함수는 data DataFrame을 인수로 받은 다음 .replace() 메서드를 사용하여 $ 및 쉼표를 제거합니다. income_usa 열의 각 값을 구분합니다. 마지막으로 현재 string 유형인 나머지 숫자를 Float64로 변환합니다.

실제로 기호와쉼표를제거하려면정규표현식[,]을 .replace()에 전달합니다. []에 두 문자를 모두 포함하면 두 문자를 모두 제거하도록 지정하는 것입니다. 그런 다음 대체 항목을 ""으로 정의합니다. 또한 regex 매개변수를 True로 설정하면 [$,]가 정규 표현식으로 해석될 수 있습니다.

람다 함수의 결과는 $ 또는 쉼표 구분 기호가 없는 시리즈입니다. 그런 다음 이 시리즈를 변수 income_usa에 할당합니다. 이로 인해 .assign() 메소드가 기존 income_usa 열의 데이터를 정리된 업데이트로 덮어쓰게 됩니다.

위 코드를 다시 살펴보면 이 모든 것이 어떻게 조화를 이루는지 알 수 있습니다. 업데이트된 콘텐츠가 포함된 시리즈를 계산하는 람다 함수를 참조하는 .assign() 매개변수 income_usa를 전달합니다. 람다가 생성하는 시리즈를 income_usa라는 매개변수에 할당합니다. 이 매개변수는 .assign()에게 기존 income_usa 열을 새 열로 업데이트하도록 지시합니다.

이제 이 코드를 실행하여 income_usa 열에서 문제가 되는 문자를 제거하세요. 작업을 테스트하고 교체했는지 확인하는 것을 잊지 마세요. 또한 income_usa의 데이터 유형이 실제로 Float64인지 확인해야 합니다.

참고: assign()를 사용할 때 .assign(income_usa=data["income_usa"]...)을 사용하여 열을 직접 전달할 수도 있습니다. 그러나 파이프라인에서 income_usa 열이 이전에 변경된 경우 이로 인해 문제가 발생합니다. 이러한 변경 사항은 업데이트된 데이터 계산에 사용할 수 없습니다. 람다 함수를 사용하면 해당 데이터의 최신 버전을 기반으로 새로운 열 데이터 세트를 강제로 계산하게 됩니다.

물론 income_usa 열만 작업해야 하는 것은 아닙니다. income_world 열에도 동일한 작업을 수행해야 합니다. 동일한 .assign() 방법을 사용하여 이를 달성할 수도 있습니다. 이를 사용하여 원하는 만큼 많은 열을 생성하고 할당할 수 있습니다. 별도의 명명된 인수로 전달하기만 하면 됩니다.

income_world 열에서 동일한 두 문자를 제거하는 코드를 작성할 수 있는지 확인해 보세요. 이전과 마찬가지로 코드가 예상대로 작동하는지 확인하는 것을 잊지 말고 올바른 열을 확인하는 것도 잊지 마세요!

참고: 열을 업데이트하기 위해 .assign() 내에서 사용하는 매개변수 이름은 유효한 Python 식별자여야 합니다. 이는 데이터 정리 초기에 했던 방식으로 열 이름을 변경하는 것이 좋은 또 다른 이유였습니다.

남은 통화 기호 및 구분 기호 제거 아래 코드에서는 이전 코드를 사용했지만 나머지 ""및구분문자열을제거하기위해람다를추가했습니다.파이썬����=(�������������.������(�������=��������������).������������(��.���������("����":10:7.1,"��������������":10:6.8)).������(���������=����������:(����["���������"].�������("[,]", "", regex=True) .astype("Float64") ), income_world=lambda data: ( data["income_world"] .replace("[$,]", "", regex=True) .astype("Float64") ), ) ) 12행은 income_world 데이터를 처리합니다. 보시다시피 두 가지 람다는 모두 같은 방식으로 작동합니다. 수정한 후에는 data.info()을 사용하여 코드를 테스트하는 것을 잊지 마세요. 재무 수치는 더 이상 string 유형이 아니라 Float64 숫자임을 알 수 있습니다. 실제 변경 사항을 보려면 data.head().를 사용하세요.

잘못된 데이터 유형 수정

다음으로 필름 길이 값에서 "mins" 문자열을 제거한 다음 열을 정수 유형으로 변환해야 합니다. 이를 통해 값을 분석할 수 있습니다. 문제가 되는 "mins" 텍스트를 제거하기 위해 pandas의 .str.removesuffix() 시리즈 방법을 사용하기로 결정했습니다. 이를 통해 film_length 열의 오른쪽에서 전달된 문자열을 제거할 수 있습니다. 그런 다음 .astype("Int64")를 사용하여 데이터 유형을 관리할 수 있습니다.

하위 문자열 제거 아래 코드에서는 이전 코드를 사용하고 있지만 22번째 줄에서 시작하는 "mins" 문자열을 제거하기 위해 람다를 추가하고 있습니다. data = ( james_bond_data.rename(columns=new_column_names) .combine_first( pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}}) ) .assign( income_usa=lambda data: ( data["income_usa"] .replace("[,]","",�����=����).������("�����64")),�����������=����������:(����["�����������"].�������("[,]", "", regex=True) .astype("Float64") ), film_length=lambda data: ( data["film_length"] .str.removesuffix("mins") .astype("Int64") ), ) ) 보시다시피 람다는 24행에서 .removesuffix()을 사용하여 원본의 데이터를 기반으로 새 시리즈를 생성함으로써 film_length 열을 업데이트합니다. film_length 열이지만 각 값 끝에서 "mins" 문자열을 뺍니다. 열의 데이터를 숫자로 사용하려면 .astype("Int64").를 사용하세요. 이전과 마찬가지로 이전에 사용한 .info() 및 .head() 메소드로 코드를 테스트하세요. 이제 film_length 열에 더 유용한 Int64 데이터 유형이 있으며 "mins"가 제거되었습니다.

재무 데이터 문제 외에도 release_date 열이 문자열로 처리되는 것을 확인했습니다. 데이터를 datetime 형식으로 변환하려면 pd.to_datetime()을 사용하세요.

to_datetime()을 사용하려면 시리즈 data["release_date"]를 여기에 전달하고 형식 문자열을 지정하는 것을 잊지 마세요.

업데이트된 열 데이터의 연도 부분을 저장하기 위해 release_year라는 이름의 DataFrame에 ["release_date"]라는 새 열을 생성할 수도 있습니다. 이 값에 액세스하는 코드는 datadata["release_date"].dt.year입니다. 각 연도를 분리하면 향후 분석은 물론 향후 DataFrame 인덱스에도 유용할 수 있다고 생각합니다.

위 정보를 사용하여 release_date 열을 올바른 유형으로 업데이트할 수 있는지 확인하고 다음을 포함하는 새 release_year 열을 생성할 수도 있습니다. 각 영화가 나온 해. 이전과 마찬가지로 .assign() 및 람다를 사용하여 두 가지를 모두 달성할 수 있으며 이전과 마찬가지로 노력을 테스트하는 것을 잊지 마세요.

날짜 조정 아래 코드에서는 람다가 추가된 이전 코드를 사용하여 release_date 열의 데이터 유형을 업데이트하고 출시 연도가 포함된 새 열을 만듭니다. data = ( james_bond_data.rename(columns=new_column_names) .combine_first( pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}}) ) .assign( income_usa=lambda data: ( data["income_usa"] .replace("[,]","",�����=����).������("�����64")),�����������=����������:(����["�����������"].�������("[,]", "", regex=True) .astype("Float64") ), film_length=lambda data: ( data["film_length"] .str.removesuffix("mins") .astype("Int64") ), release_date=lambda data: pd.to_datetime( data["release_date"], format="%B, %Y" ), release_year=lambda data: ( data["release_date"] .dt.year .astype("Int64") ), ) ) 보시다시피 27행의 release_date에 할당된 람다는 release_date 열을 업데이트하고 30행의 람다는 release_date 열로 부터 날짜 부분의 year 부분을 포함하는 새 release_year열을 생성합니다.

이제 초기 문제를 해결했으므로 data.info() 다시 실행하여 초기 문제가 모두 해결되었는지 확인하십시요.

In [ ]:
data.info()

보시다시피, 원래 27개 항목에는 이제 모두 데이터가 포함되어 있습니다. release_date 열은 datetime64 형식을 가지며 세 개의 수입 및 film_length 열은 모두 숫자 유형을 갖습니다. 이 시점에서는 데이터에서 누락된 부분이 없고 모두 올바른 유형인지 확인했습니다. 다음으로 실제 데이터 자체에 주의를 돌립니다.

데이터의 불일치 수정

수량 조정 아래 코드는 이전 버전과 유사합니다. 람다 결과를 곱하려면 곱셈을 사용합니다. data = ( james_bond_data.rename(columns=new_column_names) .combine_first( pd.DataFrame({"imdb": {10: 7.1}, "rotten_tomatoes": {10: 6.8}}) ) .assign( income_usa=lambda data: ( data["income_usa"] .replace("[,]","",�����=����).������("�����64")),�����������=����������:(����["�����������"].�������("[,]", "", regex=True) .astype("Float64") ), film_length=lambda data: ( data["film_length"] .str.removesuffix("mins") .astype("Int64") ), release_date=lambda data: pd.to_datetime( data["release_date"], format="%B, %Y" ), release_year=lambda data: ( data["release_date"] .dt.year .astype("Int64") ), ) )

정리된 데이터 저장

교육의 일환으로 정리된 DataFrame을 새로운 파일에 저장해야 한다는 점을 배웠습니다. 그러면 다른 분석가가 이를 사용하여 동일한 문제를 다시 한 번 정리해야 하는 수고를 덜 수 있을 뿐만 아니라 참조용으로 필요할 경우 원본 파일에 액세스할 수도 있습니다. .to_csv() 방법을 사용하면 다음과 같은 모범 사례를 수행할 수 있습니다.

In [ ]:
data.to_csv("james_bond_data_cleansed.csv", index=False)

정리된 DataFrame을 james_bond_data_cleansed.csv이라는 CSV 파일에 작성합니다. index=False를 설정하면 색인이 아닌 순수 데이터만 작성됩니다. 이 파일은 미래의 분석가에게 유용할 것입니다.

계속 진행하기 전에 잠시 시간을 내어 지금까지 달성한 ​​내용을 되돌아보세요. 이제 누락된 내용, 중복된 내용, 잘못된 데이터 유형이나 이상값 없이 구조적으로 건전하도록 데이터를 정리했습니다. 또한 유사한 데이터 값 간의 철자 오류와 불일치도 제거했습니다.

지금까지의 엄청난 노력을 통해 데이터를 자신있게 분석할 수 있을 뿐만 아니라 이러한 문제를 강조함으로써 데이터 소스를 다시 방문하고 거기에서 해당 문제를 해결할 수도 있습니다. 실제로 원본 데이터를 획득하는 프로세스의 결함을 강조하면 향후 유사한 문제가 다시 발생하는 것을 방지할 수 있습니다.

데이터 정리는 실제로 시간과 노력을 들일 가치가 있으며 중요한 이정표에 도달했습니다. 이제 데이터를 정리하고 저장했으므로 임무의 주요 부분으로 넘어갈 차례입니다. 이제 목표 달성을 시작할 시간입니다.

Python을 사용하여 데이터 분석 수행

데이터 분석은 거대한 주제이며 마스터하려면 광범위한 연구가 필요합니다. 그러나 분석에는 네 가지 주요 유형이 있습니다.

  • 설명 분석은 이전 데이터를 사용하여 과거에 발생한 일을 설명합니다. 일반적인 예로는 판매 동향이나 고객 행동을 파악하는 것이 있습니다.
  • 진단 분석은 상황을 한 단계 더 발전시켜 왜 그러한 사건이 발생했는지 알아내려고 노력합니다. 예를 들어 판매 추세는 왜 발생 했습니까? 그리고 고객이 그런 행동을 한 이유는 정확히 무엇입니까?
  • 예측 분석은 이전 분석을 기반으로 하며 기술을 사용하여 미래에 어떤 일이 일어날지 예측합니다.
  • 규정 분석은 이전 분석 유형에서 발견한 모든 정보를 사용하여 미래 전략을 수립합니다. 예를 들어 판매 추세 예측이 하락하는 것을 방지하거나 고객이 다른 곳에서 구매하는 것을 방지하기 위한 조치를 구현할 수 있습니다.

이 튜토리얼 시작 부분에서 본 워크플로 다이어그램의 분석 단계의 목적은 정리된 데이터를 처리하는 것입니다. 다른 이해관계자에게 유용한 통찰력과 관계를 추출합니다. 다른 사람들이 귀하의 결론에 관심을 가질 수도 있지만, 귀하가 어떻게 그러한 결론에 도달했는지 의문이 든다면 귀하의 주장을 뒷받침할 소스 데이터가 있습니다.

이 튜토리얼의 나머지 부분을 완료하려면 matplotlib 및 scikit-learn 라이브러리를 모두 설치해야 합니다. python -m pip install matplotlib scikit-learn을 사용하여 이 작업을 수행할 수 있지만 Jupyter Notebook 내에서 사용하는 경우 ! 접두사를 붙이는 것을 잊지 마세요.

분석하는 동안 데이터의 일부 플롯을 그리게 됩니다. 이를 위해 Matplotlib 라이브러리의 플로팅 기능을 사용합니다.

또한 회귀 분석을 수행하게 되므로 scikit-learn 라이브러리의 일부 도구를 사용해야 합니다.

In [ ]:
!python -m pip install matplotlib scikit-learn

회귀 분석 수행

귀하의 데이터에는 Rotten Tomatoes 및 IMDb. 첫 번째 목표는 Rotten Tomatoes 등급과 IMDb 등급 사이에 관계가 있는지 알아내는 것입니다. 이를 위해 회귀 분석을 사용하여 두 평가 세트가 관련되어 있는지 확인합니다.

회귀 분석을 수행할 때 좋은 첫 번째 단계는 분석 중인 두 데이터 세트의 산점도를 그리는 것입니다. 이 플롯의 모양은 그들 사이에 어떤 관계가 있는지에 대한 빠른 시각적 단서를 제공합니다.

아래 코드는 최종적으로 두 등급 세트의 산점도를 생성하도록 설정합니다.

In [ ]:
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv("james_bond_data_cleansed.csv").convert_dtypes()

먼저 pandas 라이브러리를 가져와 새 james_bond_data_cleansed.csv를 DataFrame으로 읽을 수 있도록 합니다. 또한 실제 산점도를 생성하는 데 사용할 matplotlib.pyplot 라이브러리를 가져옵니다.

그런 다음 다음 코드를 사용하여 실제로 산점도를 생성합니다.

In [ ]:
fig, ax = plt.subplots()
ax.scatter(data["imdb"], data["rotten_tomatoes"])
ax.set_title("Scatter Plot of Ratings")
ax.set_xlabel("Average IMDb Rating")
ax.set_ylabel("Average Rotten Tomatoes Rating")
fig.show()

subplots() 함수를 호출하면 동일한 Figure에 하나 이상의 플롯을 추가할 수 있는 인프라가 설정됩니다.

초기 산점도를 생성하려면 수평 계열을 데이터의 imdb 열로 지정하고 수직 계열을 rotten_tomatoes 열로 지정합니다. 관심을 끄는 것은 둘 사이의 관계이므로 여기서 순서는 임의적입니다.

독자가 플롯을 이해할 수 있도록 다음으로 플롯 제목을 지정한 다음 두 축에 적절한 레이블을 제공합니다. Jupyter Notebook에서 선택 사항인 fig.show() 코드는 플롯을 표시하는 데 필요할 수 있습니다.

산점도는 왼쪽에서 오른쪽으로 뚜렷한 기울기를 보여줍니다. 이는 한 등급 세트가 증가하면 다른 등급 세트도 증가한다는 것을 의미합니다. 더 깊이 파고들어 한 세트를 다른 세트를 기반으로 추정할 수 있는 수학적 관계를 찾으려면 회귀 분석을 수행해야 합니다. 이는 이전 코드를 다음과 같이 확장해야 함을 의미합니다.

In [ ]:
from sklearn.linear_model import LinearRegression

x = data.loc[:, ["imdb"]]
y = data.loc[:, "rotten_tomatoes"]

선형 회귀 계산을 수행하려면 LinearRegressio이 필요합니다. 그런 다음 pandas DataFrame과 pandas Series를 만듭니다. x는 imdb 열의 데이터를 포함하는 DataFrame이고, y는 rotten_tomatoesx은 열 목록이 있는 DataFrame으로 정의됩니다.

이제 선형 회귀 계산을 수행하는 데 필요한 모든 것이 준비되었습니다.

In [ ]:
model = LinearRegression()
model.fit(x, y)

r_squared = f"R-Squared: {model.score(x, y):.2f}"
best_fit = f"y = {model.coef_[0]:.4f}x{model.intercept_:+.4f}"
y_pred = model.predict(x)

먼저 LinearRegression 인스턴스를 생성하고 .fit()를 사용하여 두 데이터 세트를 여기에 전달합니다. 그러면 실제 계산이 수행됩니다. 이를 위해 기본적으로 일반 최소 제곱(OLS)을 사용합니다.

인스턴스를 만들고 채우면 LinearRegression 인스턴스의 .score() 메소드가 R 제곱, 즉 결정 계수 값을 계산합니다. 이는 최적선이 실제 값에 얼마나 가까운지를 측정합니다. 분석에서 R-제곱 값 0.79는 최적선과 실제 값 사이의 정확도가 79%임을 나타냅니다. 나중에 플로팅하기 위해 r_squared이라는 문자열로 변환합니다.

가장 적합한 직선 방정식의 문자열을 구성하려면 LinearRegression 개체의 .coef_ 속성을 ​​사용하여 그라데이션을 가져오고 .intercept_ 속성을 ​​사용하여 y절편을 찾습니다. 방정식은 나중에 플롯할 수 있도록 best_fit라는 변수에 저장됩니다.

참고: 왜 model.coef_ 및 model.intercept_ 변수에 밑줄 접미사가 있는지 궁금할 것입니다. 이는 추정값이 포함된 변수를 나타내는 scikit-learn 규칙입니다.

마지막으로 산점도를 생성합니다.

In [ ]:
fig, ax = plt.subplots()
ax.scatter(x, y)
ax.plot(x, y_pred, color="red")
ax.text(7.25, 5.5, r_squared, fontsize=10)
ax.text(7.25, 7, best_fit, fontsize=10)
ax.set_title("Scatter Plot of Ratings")
ax.set_xlabel("Average IMDb Rating")
ax.set_ylabel("Average Rotten Tomatoes Rating")
fig.show()

처음 세 줄은 산점도에 가장 적합한 선을 추가합니다. text() 함수는 r_squared 및 best_fit를 전달된 좌표에 배치하고 .plot() 방법은 가장 적합한 선(빨간색)을 산점도에 추가합니다. 이전과 마찬가지로 fig.show() Jupyter Notebook에는 필요하지 않습니다.

통계 분포 조사

귀하의 데이터에는 다양한 본드 영화의 상영 시간에 대한 정보가 포함되어 있습니다. 두 번째 목표는 영화의 길이를 분석하여 얻을 수 있는 통찰력이 있는지 알아보는 것입니다. 이를 위해 영화 타이밍의 막대 그래프를 만들고 여기에 흥미로운 내용이 나타나는지 확인합니다.

In [ ]:
fig, ax = plt.subplots()
length = data["film_length"].value_counts(bins=7).sort_index()
length.plot.bar(
     ax=ax,
     title="Film Length Distribution",
     xlabel="Time Range (mins)",
     ylabel="Count",
)
fig.show()

이번에는 Pandas의 플로팅 기능을 사용하여 막대 그래프를 만듭니다. Matplotlib만큼 광범위하지는 않지만 Matplotlib의 기본 기능 중 일부를 사용합니다. 데이터의 Film_Length 열에 있는 데이터로 구성된 시리즈를 생성합니다. 그런 다음 .value_counts()를 사용하여 각 영화의 길이를 포함하는 시리즈를 만듭니다. 마지막으로 bins=7.를 전달하여 7개의 범위로 그룹화합니다.

시리즈를 만든 후에는 .plot.bar()을 사용하여 빠르게 구성할 수 있습니다. 이를 통해 그림과 같이 플롯의 제목과 축 레이블을 정의할 수 있습니다. 결과 플롯은 매우 일반적인 통계 분포를 보여줍니다.

원하는 경우 보다 구체적인 통계 값을 찾을 수 있습니다.

In [ ]:
data["film_length"].agg(["min", "max", "mean", "std"])

각 Pandas 데이터 시리즈에는 함수 목록을 전달할 수 있는 유용한 .agg() 메소드가 있습니다. 그런 다음 이들 각각은 시리즈의 데이터에 적용됩니다. 보시다시피 평균은 실제로 122~130분 범위에 있습니다. 표준편차가 작다는 것은 영화 상영 시간 범위가 크게 분산되지 않았음을 의미합니다. 최소값과 최대값은 각각 106분과 148분입니다.

관계 없음 찾기

In [ ]:
fig, ax = plt.subplots()
ax.scatter(data["imdb"], data["bond_kills"])
ax.set_title("Scatter Plot of Kills vs Ratings")
ax.set_xlabel("Average IMDb Rating")
ax.set_ylabel("Kills by Bond")
fig.show()

코드는 이전 산점도에서 사용한 코드와 거의 동일합니다. 분석에 IMDb 데이터를 사용하기로 결정했지만 대신 Rotten Tomatoes 데이터를 사용할 수도 있었습니다. 둘 사이에 긴밀한 관계가 있다는 것을 이미 확인했으므로 무엇을 선택하든 상관없습니다.

보시다시피 산점도는 데이터가 무작위로 분포되어 있음을 보여줍니다. 이는 영화 평점과 본드 킬 횟수 사이에 아무런 관계가 없음을 나타냅니다. 피해자가 Walther PPK의 반대편에 섰는지, 비행기에서 빨려 나갔는지, 아니면 우주로 표류하게 되었는지, 본드 영화 팬들은 본드가 제거한 악당의 수에 별로 관심을 두지 않는 것 같습니다.

데이터를 분석할 때 항상 유용한 정보를 찾을 수는 없다는 점을 인식하는 것이 중요합니다. 실제로 데이터 분석을 수행할 때 피해야 할 함정 중 하나는 데이터를 분석하기 전에 데이터에 자신만의 편향을 도입한 다음 이를 사용하여 정당화하는 것입니다.

결과 전달

데이터 모델링이 완료되고 유용한 정보를 얻은 후 다음 단계는 결과를 다른 이해관계자에게 전달하는 것입니다. 결국, 눈으로만 볼 수 있는 것은 아닙니다. 보고서나 프리젠테이션을 사용하여 이를 수행할 수 있습니다. 결론을 내리기 전에 데이터 소스와 분석 방법에 대해 논의하게 될 것입니다. 결론을 뒷받침하는 데이터와 방법론이 있으면 그 결론에 권위가 부여됩니다.

결과를 발표하고 나면 향후 분석이 필요한 질문이 나올 수도 있습니다. 다시 한번, 이러한 새로운 문제를 해결하기 위해 추가 목표를 설정하고 전체 워크플로 프로세스를 진행해야 할 수도 있습니다. 다이어그램을 다시 보면 데이터 분석 워크플로에 순환적 특성과 반복적 특성이 있음을 알 수 있습니다.

어떤 경우에는 분석 방법을 재사용할 수도 있습니다. 그렇다면 이전 버전과 동일한 방식으로 데이터의 향후 버전을 읽고 정리하고 분석하는 스크립트를 작성하는 것을 고려할 수 있습니다. 이를 통해 향후 결과를 귀하의 결과와 비교할 수 있으며 귀하의 노력에 확장성이 추가될 것입니다. 나중에 분석을 반복함으로써 원래 결과를 모니터링하여 미래 데이터에 얼마나 잘 부합하는지 확인할 수 있습니다.

또는 방법론에서 결함을 발견하여 데이터를 다르게 재분석해야 할 수도 있습니다. 다시 말하지만, 워크플로 다이어그램에서도 이러한 가능성이 언급되어 있습니다.

'python > intermediate' 카테고리의 다른 글

프롬프트 엔지니어링 실제 사례  (1) 2024.01.23
상속과 구성 Python OOP 가이드  (1) 2024.01.22
python-for-data-analysis  (0) 2024.01.20
Python에서 JSON 데이터 작업  (1) 2024.01.07
Python으로 데이터 직렬화2  (1) 2024.01.06