R 영화 시나리오 씬구분하기

이전 시간에 이어 R 언어를 활용하여 영화 시나리오 분석하는 프로젝트를 진행해보도록 하겠습니다. R 영화 시나리오 씬구분 작업을 진행해보겠습니다. 로딩한 시나리오 샘플데이타를 씬 별로 분류해서 데이타를 생성하는 방법을 알아보겠습니다.

시나리오 로딩에 대한 내용은 아래 링크를 참고바랍니다.

[R 영화 시나리오 로딩하기]

목표

R을 활용해서 영화 시나리오의 씬구분하는 방법을 알아봅니다.

R 영화 시나리오 씬구분하기

복습 차원에서 이전 포스팅에서 대본을 로딩한 R Code와 로딩한 실행결과는 아래와 같습니다.

## R Read Data

raw_moon <- readLines("data/km-theking", encoding = "UTF-8")
head(raw_moon)
[1] "1. 프롤로그 / 바닷가 항구"                                                       
[2] "밤바다의 풍경이 아름다운데, 그 위로 비명소리가 들린다."                          
[3] "사내 으악- 악- 아아악. 이 새끼들아! 이거 놔 이 개새끼야!"                        
[4] "보면, 말끔한 정장 차림의 한 사내가 여러명의 건달들에게 바다쪽으로 끌려가고 있다."
[5] "건달 아이 씨발 좆나 시끄럽네. (퍽 - 발로 찬다.) 사내 아아. 아파. 아파요!"        
[6] "항구 위, 그들을 기다리던 다른 건달들." 
...

1. 씬구분하기

씬을 구분하기 위한 R 코드는 아래와 같습니다.

d_moon <- raw_moon %>%
   str_squish() %>%
   as_tibble() %>%
   filter(nchar(value)>0) %>%
   mutate(type = ifelse(str_detect(value, "\d\.") == TRUE, "scene", "etc"),
   scene_no = ifelse(str_detect(value, "\d\.") == TRUE, str_extract(value, "\d+") , 0 ))

실행 결과는 다음과 같습니다.

  • Tibble 컬럼값
valuetypescene_no
tibble 컬럼값
  • 실제 데이타 형태
valuetypescene_no
11. 프롤로그 / 바닷가 항구scene1
2밤바다의 풍경이 아름다운데, 그 위로 비명소리가 들린다.etc0
3사내 으악- 악- 아아악. 이 새끼들아! 이거 놔 이 개새끼야!etc0
4보면, 말끔한 정장 차림의 한 사내가 여러명의 건달들에게 바다쪽으로 끌려가고 있다.etc0
5건달 아이 씨발 좆나 시끄럽네. (퍽 – 발로 찬다.) 사내 아아. 아파. 아파요!etc0
6항구 위, 그들을 기다리던 다른 건달들.etc0
7건달1 아따, 몇시요! 추어 죽는줄 알아당게.etc0
8건달2 아이 개새끼. 차에서 문잡고 십분을 안 놓고.. 힘은 어찌나 쎄분지.etc0
9아주 살아보겠다고…etc0
10하며 사내의 다리에 콘크리트 덩어리를 묶기 시작하는 건달들.etc0
11처음으로 드러나는 40대 초반의 주인공 박동수. 잘생긴 외􏰁지만 공포와 땀이 범벅이다. 턱- 하고 항구에 다이빙하듯 동수를 세우는 건달들.etc0
12동수 야야. 너희들. 내가 내가 누군지 알아? 응? 알고 이러는거야? 건달 알지라. 검사나리.etc0
13동수 야이 개새끼야.etc0
14너희들.. 검사를 이렇게 만들면 어떻게 되는지 알아? 어? 이 개새끼들아. 무기징역. 사형이야 이씨발놈들아.etc0
15싸인주자. 그대로 콘크리트덩어리를 발로 밀어버리는 건달, 그러자 줄이 팍- 당􏰂지며- 풍덩하고 그대로 바다에 빠져버리는 동수다.etc0
162. 바닷속scene2
17풍- 하고 밑으로 쭉 빠져드는 동수.etc0
18동수 난 정말 몰랐다. 내가 이런 좆같은 깡패새끼들한테 죽게 될 줄은… 바다로 빠져들며 고개를 쳐 들자, 바다 위 빛이 점점 사라져간다.etc0
19동수 난. 씨발… 세상의 왕이 되고 싶었다.etc0
20으악- 하고 소리치는 우스꽝스런 동수의 표정에서-etc0
213. 84년도심거리/낮scene3
22더킹etc0
23쇼윈도 안, 흑백 TV에서 􏰃성􏰃 콤비가 춤을 추고 있다. 그 옆으로 사내들이 문을 따고 들어간다. 동수 내 아버지는 양아치였다.etc0
24그리고는, TV를 싣고 나와 차에 싣는 사내, 동수의 아버지 박명훈. 은 이리저리 눈치를 보다가 사람들이, 도둑이야! 외치자 재 빨리 차를 몰고 출발한다.etc0
25동수 당시엔 TV가 귀할때라 전국을 돌아다니며 티비를 훔쳤지만, 라디오, 비디오, 밥솥 뭐돈될만한것들은 그때 그때 유행따라 바꿔서훔쳤고,etc0
R Tibble

이제 코드를 하나씩 살펴보도록 하겠습니다.

d_moon <- raw_moon %>%   # 1
str_squish() %>%   # 2
as_tibble() %>%   # 3
filter(nchar(value)>0) %>%   # 4
mutate(type = ifelse(str_detect(value, "\d\.") == TRUE, "scene", "etc"),  
scene_no = ifelse(str_detect(value, "\d\.") == TRUE, str_extract(value, "\d+") , 0 )) # 5

# 1 – ‘%>%’

R에서 ‘%>%’는 파이프 연산자라고 합니다. 파이프 연산자는 하나의 함수의 출력을 다음 함수의 입력으로 전달하는 데 사용됩니다. 즉, 코드를 더 간결하고 읽기 쉽게 만들 수 있습니다.

예를 들어, 다음 코드는 데이터 프레임의 값을 정렬하고, 상위 10개 행을 출력합니다.

df <- read.csv("data.csv")
df <- arrange(df, mpg)
df <- head(df, 10)

이 코드를 파이프 연산자로 작성하면 다음과 같습니다.

df <- read.csv("data.csv") %>%
arrange(mpg) %>%
head(10)

이처럼 파이프 연산자는 R에서 유용한 연산자입니다. 코드를 더 간결하고 읽기 쉽게 만들 수 있습니다.

참고로 ‘<-‘ 는 해당 변수에 결과값을 할당한다는 의미입니다.

# 2 – str_squish()

모든 문자열의 공백문자들을 단일 문자로 변경합니다. 예를 들어 연속된 공백 문자가 ‘ ‘ 이렇게 많다면 ‘ ‘처럼 하나의 공백문자로 변경해주는 함수입니다.

# 3 – as_tibble()

이 함수를 설명하기에 앞서 tibble에 대한 데이타 개념부터 살펴보도록 하겠습니다.

R에서 tibble은 data.frame의 확장된 버전입니다. tibble은 data.frame과 같은 기능을 제공하지만, 더 읽기 쉽고, 더 편리하게 사용할 수 있습니다.

tibble은 data.frame보다 더 읽기 쉽습니다. tibble은 data.frame과 같은 열 이름을 사용하지만, 열 이름의 너비를 자동으로 조절합니다. 따라서 tibble은 화면에 더 잘 표시됩니다.

그리고 tibble은 data.frame보다 더 편리하게 사용할 수 있습니다. data.frame과 같은 함수를 사용할 수 있지만, tibble은 data.frame보다 더 빠르고, 더 효율적으로 사용할 수 있습니다.

tibble을 사용하려면 tidyverse 패키지를 설치해야 합니다. tidyverse 패키지를 설치한 후에는 tibble() 함수를 사용하여 tibble을 생성할 수 있습니다.

다음은 tibble을 생성하는 예입니다.

library(tidyverse)

tibble <- tibble(
name = c("John Doe", "Jane Doe"),
age = c(30, 25)
)

tibble을 출력하려면 print() 함수를 사용할 수 있습니다.

print(tibble)

# Output
A tibble: 2 x 2
name age
1 John Doe 30
2 Jane Doe 25

tibble을 더 편리하게 사용하려면 dplyr 패키지를 사용할 수 있습니다. dplyr 패키지에는 tibble을 조작하는 데 사용할 수 있는 다양한 함수가 포함되어 있습니다.

다음은 dplyr 패키지를 사용하여 tibble을 조작하는 예입니다.

library(dplyr)

# tibble의 이름 열을 출력합니다.
tibble %>% select(name)

# tibble의 age 열의 평균을 계산합니다.
tibble %>% summarise(age_mean = mean(age))

따라서 위에서 사용한 as_tibble() 함수는 데이타를 tibble 타입으로 변경하는 역할을 합니다.

# 4 – filter() , nchar()

R 언어에서 filter 함수는 데이터프레임에서 특정 조건을 만족하는 행을 추출하는 함수입니다. filter 함수는 다음과 같은 형식으로 사용됩니다.

filter(data, 조건)

여기서 data는 데이터프레임이고, 조건은 행을 추출하기 위한 조건입니다. 조건은 논리 표현식 또는 리터럴 값을 사용할 수 있습니다.

예를 들어, 다음 코드는 데이터프레임 mpg에서 도시 연비가 20 mpg 이상인 행을 추출합니다.

mpg <- read.csv("mpg.csv")

filtered_mpg <- filter(mpg, cty >= 20)
head(filtered_mpg)

#Output
manufacturer model displ year cyl cty hwy
1 audi a4 1.8 1999 4 21 29
2 audi a4 1.8 2008 4 21 29
3 audi a4 2.0 2007 4 21 28
4 audi a4 2.0 2008 4 21 28
5 audi a4 2.0T 2009 4 22 31
6 audi a4 3.2 2008 6 18 26

filter 함수는 데이터프레임에서 특정 조건을 만족하는 행을 추출하는 데 유용한 함수입니다.

nchar() 함수는 R 언어에서 nchar 함수는 문자열의 길이를 반환하는 함수입니다. nchar 함수는 다음과 같은 형식으로 사용됩니다.

nchar(문자열)

예를 들어, 다음 코드는 문자열 “Hello World”의 길이를 반환합니다.

nchar("Hello World")
[1] 11

nchar 함수는 문자열의 길이를 반환하는 데 유용한 함수입니다.

따라서 아래의 함수는 문자열의 길이가 1 이상인 라인만 데이타로 추출하라는 명령입니다. 즉, 빈 라인은 삭제합니다.

filter(nchar(value)>0)

# 5 – mutate, str_detect, str_extract 함수

  • mutate

R 언어에서 mutate 함수는 데이터 프레임에 새로운 변수를 추가하는 함수입니다. mutate 함수는 데이터 프레임의 기존 변수에 대한 수학적 연산이나 논리 연산을 사용하여 새로운 변수를 생성합니다. 예를 들어, mutate 함수를 사용하여 데이터 프레임의 age 변수에 대한 평균을 계산하여 새로운 age_mean 변수를 생성할 수 있습니다.

mutate 함수의 구문은 다음과 같습니다.

mutate(data_frame, new_variable = expression)

여기서 data_frame은 mutate 함수를 적용할 데이터 프레임이고, new_variable은 새로운 변수의 이름이고, expression은 새로운 변수를 생성하는 수학적 연산이나 논리 연산입니다.

mutate 함수는 다음과 같이 사용할 수 있습니다.

# Create a data frame

data_frame <- data.frame(
age = c(20, 30, 40),
gender = c("male", "female", "male")
)
# Add a new variable called age_mean

data_frame <- mutate(data_frame, age_mean = mean(age))
# Print the data frame
print(data_frame)

이 코드를 실행하면 다음과 같은 결과가 출력됩니다.

age gender age_mean
1 20 male 25.0
2 30 female 30.0
3 40 male 35.0


mutate 함수는 데이터 프레임에 새로운 변수를 추가하는 데 유용한 함수입니다. mutate 함수를 사용하여 데이터 프레임을 분석하고 시각화할 수 있습니다.

  • str_detect

R 언어에서 str_detect 함수는 문자열에 특정 패턴이 있는지 여부를 확인하는 함수입니다. str_detect 함수는 문자열과 패턴을 인자로 받아서 문자열에 패턴이 있는지 여부를 나타내는 논리 값을 반환합니다.

str_detect 함수의 구문은 다음과 같습니다.

str_detect(string, pattern)

여기서 string은 문자열이고, pattern은 패턴입니다. 패턴은 정규 표현식을 사용하여 지정할 수 있습니다.

str_detect 함수는 다음과 같이 사용할 수 있습니다.

# Create a string
string <- "Hello, world!"

# Create a pattern
pattern <- "world"

# Check if the string contains the pattern
if (str_detect(string, pattern)) {
  print("The string contains the pattern")
} else {
  print("The string does not contain the pattern")
}

이 코드를 실행하면 다음과 같은 결과가 출력됩니다.

The string contains the pattern

str_detect 함수는 문자열에 특정 패턴이 있는지 여부를 확인하는 데 유용한 함수입니다. str_detect 함수를 사용하여 문자열을 분석하고 처리할 수 있습니다.

  • str_extract

R 언어에서 str_extract 함수는 문자열에서 특정 패턴을 추출하는 함수입니다. str_extract 함수는 문자열과 패턴을 인자로 받아서 문자열에서 패턴에 해당하는 부분을 추출하여 문자열로 반환합니다.

str_extract 함수의 구문은 다음과 같습니다.

str_extract(string, pattern)

여기서 string은 문자열이고, pattern은 패턴입니다. 패턴은 정규 표현식을 사용하여 지정할 수 있습니다.

str_extract 함수는 다음과 같이 사용할 수 있습니다.

# Create a string
string <- "Hello, world!"

# Create a pattern
pattern <- "world"

# Extract the pattern from the string
extracted_pattern <- str_extract(string, pattern)

# Print the extracted pattern
print(extracted_pattern)

# Output
world

str_extract 함수는 문자열에서 특정 패턴을 추출하는 데 유용한 함수입니다. str_extract 함수를 사용하여 문자열을 분석하고 처리할 수 있습니다.

  • 정규식

str_detect와 str_extract 함수에 사용된 코드는 보면 “\d\.”,”\d+” 란 문자열이 사용되었습니다. 이것은 문자열의 패턴을 파악하기 위한 정규식 표현입니다. d는 숫자를 의미하고 “.”는 기호 “.” 를 의미합니다. 앞에 “\”가 붙은 이유는 각각 숫자와 기호임을 명시하고자 함입니다. 만약 “\” 붙지 않는다면 “d”는 알파벳 d, “.”는 모든 문자를 나타냅니다. “+”는 숫자가 연속으로 나와야 한다는 조건입니다.

최종 명령은 아래 명령은 아래와 같습니다.

mutate(type = ifelse(str_detect(value, "\d\.") == TRUE, "scene", "etc"),  
scene_no = ifelse(str_detect(value, "\d\.") == TRUE, str_extract(value, "\d+") , 0 ))

2. tibble 데이타 출력해보기

데이타 정상적으로 입력되었는지 각 행의 문자길이를 계산해서 50개만 표시해보겠습니다.

nc <- 50
for (i in 1:nc) {
   print(nchar(d_moon[i,1]))
}
  • nchar

R 언어에서 nchar 함수는 문자열의 길이를 구하는 함수입니다. nchar 함수는 문자열을 인자로 받아서 문자열의 길이를 정수로 반환합니다.

nchar 함수의 구문은 다음과 같습니다.

nchar(string)

여기서 string은 문자열입니다.

nchar 함수는 다음과 같이 사용할 수 있습니다.

# Create a string
string <- "Hello, world!"

# Get the length of the string
length_of_string <- nchar(string)

# Print the length of the string
print(length_of_string)

# Output
12

nchar 함수는 문자열의 길이를 구하는 데 유용한 함수입니다. nchar 함수를 사용하여 문자열을 분석하고 처리할 수 있습니다.

3. 모든 문자열에 씬번호 부여하기

모든 행의 문자열의 scene_no 칼럼에 씬번호를 기입해보겠습니다. 앞서 씬을 명시하는 행이 아니면 0이 아닌 씬번호를 넣었기 때문에 0이 곳에 해당 씬번호를 입력하면 됩니다.

아래는 위 설명한 대로 진행하는 코드입니다. scene_no는 현 tibble 구조체에서 3번째 컬럼에 해당하므로 “d_moon[i,3]”으로 접근하면 됩니다.

for (i in 1:nc) {

   if( d_moon[i,3] != 0 )
   {
      d = d_moon[i,3]
   }
   else
   {
      d_moon[i,3] = d
   }
}

d_moon

위 코드의 결과값은 아래와 같습니다.

valuetypescene_no
11. 프롤로그 / 바닷가 항구scene1
2밤바다의 풍경이 아름다운데, 그 위로 비명소리가 들린다.etc1
3사내 으악- 악- 아아악. 이 새끼들아! 이거 놔 이 개새끼야!etc1
4보면, 말끔한 정장 차림의 한 사내가 여러명의 건달들에게 바다쪽으로 끌려가고 있다.etc1
5건달 아이 씨발 좆나 시끄럽네. (퍽 – 발로 찬다.) 사내 아아. 아파. 아파요!etc1
6항구 위, 그들을 기다리던 다른 건달들.etc1
7건달1 아따, 몇시요! 추어 죽는줄 알아당게.etc1
8건달2 아이 개새끼. 차에서 문잡고 십분을 안 놓고.. 힘은 어찌나 쎄분지.etc1
9아주 살아보겠다고…etc1
10하며 사내의 다리에 콘크리트 덩어리를 묶기 시작하는 건달들.etc1
11처음으로 드러나는 40대 초반의 주인공 박동수. 잘생긴 외모지만 공포와 땀이 범벅이다. 턱- 하고 항구에 다이빙하듯 동수를 세우는 건달들.etc1
12동수 야야. 너희들. 내가 내가 누군지 알아? 응? 알고 이러는거야? 건달 알지라. 검사나리.etc1
13동수 야이 개새끼야.etc1
14너희들.. 검사를 이렇게 만들면 어떻게 되는지 알아? 어? 이 개새끼들아. 무기징역. 사형이야 이씨발놈들아.etc1
15싸인주자. 그대로 콘크리트덩어리를 발로 밀어버리는 건달, 그러자 줄이 팍- 당지며- 풍덩하고 그대로 바다에 빠져버리는 동수다.etc1
162. 바닷속scene2
17풍- 하고 밑으로 쭉 빠져드는 동수.etc2
18동수 난 정말 몰랐다. 내가 이런 좆같은 깡패새끼들한테 죽게 될 줄은… 바다로 빠져들며 고개를 쳐 들자, 바다 위 빛이 점점 사라져간다.etc2
19동수 난. 씨발… 세상의 왕이 되고 싶었다.etc2
씬 정보
Back to top