IT
-
[Go] 왕초보 grpc 튜토리얼 - 간단한 서버-클라이언트 메시지 교환2022.03.28
-
[Go] protocol buffer 왕초보 실습2022.03.28
-
[오류] VM VirtualBox 시작 오류2022.02.24
[데이터 사이언스] R - 숫자가 아닌 값(범주형,명목형)들을 숫자로 변환(매핑)
우리가 데이터 마이닝을 할 때, 수치형 변수가 아닌 값을 수치형으로 변환시켜야하는 경우가 많다.
직접 하나하나 숫자를 대입시켜 주기는 너무 힘들다. 그 때 이 방법을 유용하게 쓸 수 있다.
결과는 다음과 같다.
숫자로 모두 매핑하기 전의 데이터 프레임과, 변환하여 완성한 새로운 데이터프레임의 값을 비교한 것이다.
passanger 열의 값을 보면 잘 변환된 것을 알 수 있을 것이다.
이렇게 문자열 형태의 값들을 숫자로 매핑시키는 아주 쉬운 방법을 소개한다.
그 방법은 이거다.
as.numeric(변수 열(행)) # factor형 값이라면
as.numeric(as.factor(변수 열(행)) # character형 값이라면
이게 끝이다.
활용 예시 :
d <- data.frame("toCoupon_GEQ25min"=df$toCoupon_GEQ25min ,"destination"=as.numeric(df$destination),
"passanger"=as.numeric(df$passanger), "weather"= as.numeric(df$weather),
"time"=as.numeric(df$time), "coupon"=as.numeric(df$coupon),"expiration"= as.numeric(df$expiration), "CoffeeHouse"=as.numeric(as.factor(df$CoffeeHouse)),"Y"=as.numeric(df$Y))
이런 식으로 기존 데이터프레임의 명목형 값들을 수치형으로 모두 변환한 새로운 데이터프레임을 구성할 수 있다.
'IT > Data & AI' 카테고리의 다른 글
[데이터 사이언스] 검색 엔진은 어떤 원리로 작동할까? + tf-idf 유사도 예제 풀이 (0) | 2022.06.27 |
---|---|
[데이터 사이언스 / R] 결측치와 이상치(극단치)를 처리하는 방법 (예시) (0) | 2022.06.04 |
[데이터 사이언스 / R] 주성분 분석(PCA), 활용 예시 (feat. k-means 군집화) (0) | 2022.06.03 |
[데이터 사이언스 / R] iris 데이터셋을 이산화. 수치형(연속형) 변수를 명목형 변수로 변환 (0) | 2022.04.08 |
[데이터 사이언스 / R] iris 데이터셋을 이산화. 수치형(연속형) 변수를 명목형 변수로 변환
요즘 학교에서 데이터 사이언스 수업을 듣는데, 과제가 아주 많다.. ㅠㅠ
팀플이라서 항상 코드가 많은데, 뭐 다 구글링으로 만든거기도 해서 정리를 잘 안해뒀다.
그치만 r 코드 관련 자료는 그렇게 엄청 많지도 않아서, 검색해도 잘 안나오기도 한다. 원하는 자료를 찾으려면 영어로 검색하는 게 훨씬 쉬울 정도이다.
그래서 내가 만든 코드라도 남들에게 도움이 될까해서 올려본다.
댓글과 지적 환영합니다~
nomi_data <- data
nomi_data <- transform(nomi_data,
sepal_length = cut(sepal_length, breaks = c(seq(min(data[1]), max(data[1]), length=4)),
include.lowest = TRUE,
right = FALSE,
labels = c("S", "M", "L")
),
sepal_width = cut(sepal_width, breaks = c(seq(min(data[2]), max(data[2]), length=4)),
include.lowest = TRUE,
right = FALSE,
labels = c("S", "M", "L")
),
petal_length = cut(petal_length, breaks = c(seq(min(data[3]), max(data[3]), length=4)),
include.lowest = TRUE,
right = FALSE,
labels = c("S", "M", "L")
),
petal_width = cut(petal_width, breaks = c(seq(min(data[4]), max(data[4]), length=4)),
include.lowest = TRUE,
right = FALSE,
labels = c("S", "M", "L")
))
nomi_data
참고로, data는 iris 데이터셋의 dataframe을 미리 불러온 것이다.
명목형 변수로 바꾼 값들은 nomi_data라는 형식으로 새롭게 저장해준다.
seq(min(data[i]), max(data[i]), length=4))를 통해, 해당 속성에서 최대값과 최소값 사이의 4개의 구간의 경계점을 구했다.
(참고로, 구해온 값은 벡터 형식)
그리고 cut()의 breaks 변수에 이를 넣어 그 구간에 맞춰 나누어주었다. 이때, 각각 S, M, L의 3개의 명목형 변수를 붙여주었다.
length에 n+1을 넣고 labels에 n개의 라벨을 넣어준다고 생각하자!
참고로 라벨 이름은 스몰, 미들, 라지 사이즈의 이니셜을 따와 붙인 것이다. ㅎㅎ
코드 실행 예시.
내가 사용한 dataset이 150줄인가 그렇다. 15페이지까지 있으니 뒤로 넘기면 더 다양한 결과를 볼 수 있을 것이다.
summary()를 통해 이렇게 분포가 된 것을 확인할 수도 있다.
'IT > Data & AI' 카테고리의 다른 글
[데이터 사이언스] 검색 엔진은 어떤 원리로 작동할까? + tf-idf 유사도 예제 풀이 (0) | 2022.06.27 |
---|---|
[데이터 사이언스 / R] 결측치와 이상치(극단치)를 처리하는 방법 (예시) (0) | 2022.06.04 |
[데이터 사이언스 / R] 주성분 분석(PCA), 활용 예시 (feat. k-means 군집화) (0) | 2022.06.03 |
[데이터 사이언스] R - 숫자가 아닌 값(범주형,명목형)들을 숫자로 변환(매핑) (0) | 2022.04.29 |
[Go] 왕초보 grpc 튜토리얼 - 간단한 서버-클라이언트 메시지 교환
이 포스팅은 아래의 유튜브 영상 튜토리얼 내용을 정리한 것입니다. 문제 시 댓글 주십시오. 삭제하겠습니다.
이전의 제 protocol buffer 왕초보 튜토리얼을 먼저 보고 오시면 본 포스팅을 이해하는 데 더욱 도움이 될 것입니다.
본 포스팅과 동시에 저 영상을 시청할 것을 권합니다. 과정을 한 단계 한 단계 따라가시면 더욱 공부하기 좋습니다. 완성된 코드를 보는 것보다 코드의 과정을 처음부터 하나씩 따라가며 익히는게 왕초보공부의 핵심입니다.
gRPC란?
gRPC란 원격 procedure call을 지원해주는 프레임워크이다. 어디서든 실행될 수 있다.
원격 procedure call은 분산 시스템에서 주로 쓰이는 것으로, application 간의 통신을 가능하게 해준다.
참고로 grpc 쓰려면 golang이 1.17 버전 이상이여야하는 것 같다. 그래서 다시 까느라 애 무지 먹었다 ㅠㅠ. 다음 링크를 참고해서 1.17 버전의 go를 설치해주자. 이떄 기존의 go를 삭제하고 깔아주는 것 명심하자. (더보기 클릭)
https://www.youtube.com/watch?v=BdzYdN_Zd9Q
위의 튜토리얼을 따라하며 gRPC를 이용한 간단한 채팅 서비스를 만들어본다.
들어가기에 앞서 명령어를 통해 grpc 패키지를 설치한다.
go get -u google.golang.org/grpc
제일 처음으로 server.go라는 파일을 만들어준다.
- net 패키지를 사용하여, tcp 포트 9000번에서 client의 신호를 기다린다. lis는 listener라는 뜻이다.
- grpc를 패키지를 사용하여, 그grpcServer를 생성한 뒤에, 그곳에 listener을 등록해준다.
- → TCP 연결에 전달하기 전에, grpc 서버에 endpoint들을 등록할 수 있게 해준다.
참고로, NewServer()은 chat.pb.go에 자동으로 만들어진 함수이다.
// server.go
package main
import (
"log"
"net"
"google.golang.org/grpc"
)
func main()
{
lis, err := net.Listen("tcp", ":9000") // tcp 연결을 만든다. (포트 9000번에서)
if err != nil {
log.Fatalf("Failed to listend on port 9000: %v", err)
}
grpcServer := grpc.NewServer()
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("Failed to serve gRPC server over port 9000: %v", err)
}
}
이렇게 서버를 만들어주면, 아무 일 안하는 서버가 하나 만들어진다.
이제는 다음과 같이 chat.proto 파일을 만들어준다.
client로 부터 메시지를 받고, 바로 서버 측 메시지를 돌려주는 프로그램을 만들 예정이다.
- 보내줄 메시지의 형식으로 string 타입의 body를 선언해준다.
- proto에 저장되는 데이터 구조체는 message 타입으로 정의된다.
- 서비스 또한 정의해주었다.
- service 타입의 chatService를 선언해준다.
- rpc 타입의 함수를 정의했다.
- → 어떤 언어로 쓰인 grpc 클라이언트던 간에 모두 호출할 수 있는 함수가 된다.
- SayHello()는 인자로 메시지를 받고, 리턴으로 메시지를 돌려주는 함수이다.
// chat.proto
syntax = "proto3";
package chat;
message Message {
string body = 1;
}
service ChatService {
rpc SayHello(Message) returns (Message) {}
}
그 다음으로 chat 폴더 안에 chat 패키지를 만들 것이다.
터미널에다 대고 다음 명령어를 입력해, proto 파일을 컴파일해준다. 이러면 chat 디렉토리 안에 chat.pb.go 파일이 생성된다.
mkdir chat
protoc --go_out=plugins=grpc:chat chat.proto
chat.pb.go에는 chat service와 대화하거나 grpc에 서버나 클라이언트를 등록하는 데 필요한 것들이 갖춰져 있게된다.
이제 chat 패키지의 일부가 될 chat.go 파일을 만들어주자.
- 비어있는 Server 구조체를 만들고, SayHello rpc 함수를 만들어준다. 리턴값으로는 메시지 포인터 혹은 에러를 리턴할 것이다.→ 따라서 아무것도 추가로 import 할 필요가 없다.
- → 이때, chat.pb.go 안에 SayHello의 프로토타입이 아래와 같이 만들어져있다.
- SayHello에서는 서버에 client가 받은 메시지를 띄워준 다음, 클라이언트로 서버의 메시지를 보내주게 된다.
- 참고) context란?→ 한마디로 context는 하나의 “맥락”이고, 이 “맥락”을 프로세스나 API에 전달해서 모든 연계되는 작업들이 하나의 맥락 안에서 이뤄지도록 하는 것이다. (참고 : https://devjin-blog.com/golang-context/ )
→ 하나의 “맥락”을 유지하기 위해, 다른 함수를 호출할 때 예제와 같이 context를 첫번째 인자로 전달한다고 한다.
// chat.go
package chat
import (
"log" // 들어오는 모든 request들을 log에 저장한다.
"golang.org/x/net/context" // context를 request로 받을 수 있게 한다.
)
type Server struct { // 비어있는 서버 구조체 생성
}
func (s *Server) SayHello(ctx context.Context, message *Message) (*Message, error)
{
log.Printf("Recieved message body from client: %s", message.Body)
return &Message{Body: "Hello From the Server!"}, nil // 실패 시 error로 nil 리턴
}
먼저 다음 명령어를 실행해서 모듈(go.mod)을 만들어주자. 모듈이라는 건 로컬에서 만든 패키지를 import 하는 데 필요한 것 같다.
go mod init github.com/Seo-A-Nam/Etc/go_grpc_practice
이제 server.go를 수정해준다.
chat.RegisterChatServiceSever()을 통해 말그대로 chat 서비스 서버를 등록해준다.
→ 인자로 grpc 서버와 서버 구조체를 넣어준다.
// server.go 수정
package main
import (
"log"
"net"
"google.golang.org/grpc"
"github.com/Seo-A-Nam/Etc/go_grpc_practice/chat"
)
func main()
{
lis, err := net.Listen("tcp", ":9000") // tcp 연결을 만든다. (포트 9000번에서)
if err != nil {
log.Fatalf("Failed to listend on port 9000: %v", err)
}
s := chat.Server{} // 서버 구조체를 선언
grpcServer := grpc.NewServer() // grpc 서버를 생성한다.
chat.RegisterChatServiceServer(grpcServer, &s) // chat service에 서버 등록
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("Failed to serve gRPC server over port 9000: %v", err)
}
}
이제 server.go를 실행해주자.
그럼 이렇게 계속 메시지를 대기하고 있는 상태가 된다.
로컬 호스트의 9000번 포트에서 listening을 시작한 것이다.
이제 client.go라는 클라이언트 파일을 만들어주자
참고로, grpc.WithInsecure()라는 옵션은 insecure connection을 생성한다는 것으로, 둘 사이 통신에서 별다른 보안을 챙기지 않겠다는 뜻이다. 보안이 중요하고 서버 간 통신이 외부에 노출될 수 있는 상황이면, 이 옵션을 제거해서 connection을 맺을 때 credential을 확인하는 절차가 필요하다고 한다.
// client.go
package main
import (
"log"
"golang.org/x/net/context"
"google.golang.org/grpc"
"github.com/Seo-A-Nam/Etc/go_grpc_practice/chat"
)
func main() {
var conn *grpc.ClientConn // grpc 클라이언트의 connection을 저장하는 포인터
conn, err := grpc.Dial(":9000", grpc.WithInsecure())
// 로컬 호스트의 9000번 포트에 있는 grpc 서버와 연결을 시도한다. (connection을 생성해준다)
if err != nill {
log.Fatalf("could not connect: %s", err)
}
defer conn.Close() // defer : 함수가 끝나려고 할 때 이 코드를 실행한다.
c := chat.NewChatServiceClient(conn) // 연결포인터를 인자로 전달
message := chat.Message { // 클라이언트 메시지
Body: "Hello from the client!",
}
response, err := c.SayHello(context.Background(), &message)
if err != nill {
log.Fatalf("Error when calling SayHello: %s", err)
}
log.Printf("Response from Server: %s", response.Body)
}
이제 client.go도 실행해보고 결과가 어떻게 되는 지 보자.
이런 결과가 나타나게 되는 것을 볼 수 있다.
원래 처음 해보면 하나도 안 이해 되는게 정상이지만, 점점 하다보면 익숙해지면서 간단하게 느껴질 것이라고 한다.
그러니 나도 계속 복습해야겠다...
'IT > 개발 언어 및 도구' 카테고리의 다른 글
[연구] 컨테이너넷 (containernet) 프레임워크 소개 (0) | 2022.07.13 |
---|---|
[Go] 고 루틴(go routine)의 활용 - 기초 (0) | 2022.05.27 |
[Go] protocol buffer 왕초보 실습 (0) | 2022.03.28 |
[Go] protocol buffer 왕초보 실습
뇽안뇽안!
오늘도 돌아온 왕초보 강의이다. 내가 왕초보라 왕초보 눈에 맞게 쓰려고 노력했다. ㅎㅎ 나도 진짜 처음 배운 지식이라 간단한 단계의 강좌 겸 포스팅을 마련하였으니, 처음 배우는 사람들도 따라오기 적합할 것이다.
용기를 가지고 다음의 완전 간단한 예제를 따라서 코딩해보도록 하자. 딱 예제 코드 2개다! 이것만 마스터한다는 생각으로 가보자~
나도 처음에는 튜토리얼 영상보단 블로그 자료로 독학하려고 했었다. 그런데, 한국 자료들 중에는 어렵게 설명한 자료도 많고, 직접 따라해봐도 이해가지 않는 경우가 많았다.
그러나, 외국 개발자 유튜버의 튜토리얼 영상을 따라하니 10분만에 바로 쉽게 배울 수 있었다! 아래에있는 golang protocolbuffer 튜토리얼 영상을 보길 적극 권장한다. 이 포스팅은 저 영상의 내용을 정리한 것이다. (문제가 된다면 댓글 주십시오)
게다가, 완성된 코드 하나만 보고 이해하려는 게 아니라 코드를 짜는 과정을 한 단계 한 단계 따라가는 게 배우는 데 훨씬 배우기 좋다.
꼭 이 블로그 정리본을 오른쪽에, 영상을 왼쪽에 켜놓고 같이 보면서 한줄 한줄 코드 짜는 것을 따라해보자!!
어렵게만 느껴지던 protocol buffer가 이해가 되기 시작할 것이다.
https://www.youtube.com/watch?v=NoDRq6Twkts
그러니까..protocol buffer는 일종의 구조체 데이터 저장 형식이라고 보면 된다. 그 중에서도 protocol buffer는 **“직렬화”**의 원리를 사용하여 데이터 용량을 압축시켜준다고 한다.
→ 구조체 데이터를 객체에 압축 저장해주는 도구라고 보면 편할 듯하다.
1. 사전 설치 작업
protoc 패키지 설치
protoc은 proto 파일을 컴파일 하기 위한 명령어/컴파일러라고 보면 된다. 따로 설치해주자.
go get github.com/golang/protobuf
go get github.com/golang/protobuf/proto
protoc-gen-go 의존성 설치
go에서는 .proto 파일을 protoc 하기 위해 별도 의존성을 따로 제공하고 있다.
go install google.golang.org/protobuf/cmd/protoc-gen-go
proto 파일을 go 언어로 컴파일
proto 파일이 있는 디렉토리에 접근해 터미널에 다음의 명령어를 입력한다.
protoc --go_out=. *.proto
→ person.proto 파일을 컴파일하니 person.pb.go 파일이 생겼다.
protocol buffer를 사용한 go 파일의 실행
go run main.go person.pb.go
2. go에서 protocol buffer 사용하기
ex01
다음은 elliot이라는 객체에 사람의 이름, 그 사람의 나이를 함께 저장하고 압축(marshal), 압축해제(unmarshal) 해주며 각각의 값을 출력해주는 예제이다.
(엄밀히 말하자면 압축보다는 010101 등의 binary로 바꾸는 직렬화이지만, 지금 단계에서는 그냥 압축-압축해제라고 연상해서 이해하는 게 더 좋다)
일단 다음과 같이 protocol buffer 파일을 만들었다. 이때 파일 명은 person.proto 라고 정했다.
여기서 데이터 객체의 type은 모두 message이다.
syntax="proto3";
package main;
message Person {
string name=1;
int32 age=2;
}
golang으로 main.go 코드를 만들었다.
package main
import "fmt"
import "github.com/golang/protobuf/proto"
import "log"
func main() {
fmt.Println("Hello World!")
// proto 객체 형식에 맞게 데이터 저장
elliot := &Person{
Name: "Elliot",
Age: 24,
}
// data를 marshalling한 뒤, 그 data 를 출력
data, err := proto.Marshal(elliot)
if err != nill {
log.Fatal("Marshalling error", err)
}
fmt.Println(data)
// data를 unmarshalling 한 뒤, 그 data를 출력
newElliot := &Person{}
err = proto.Unmarshall(data, newElliot)
if err != nil {
log.Fatal("unmarshalling error: ", err)
}
fmt.Println(newElliot.GetAge())
fmt.Println(newElliot.GetName())
// GetAge(), GetName()은 proto.pb.go에 있는 함수
}
- marshal과 unmarshall 실행 시 모두 에러를 체크해준다.
- 두 함수 모두 동작 실패 시 nil을 리턴한다.
- unmarshalling 할 때는 새로운 빈 객체를 생성해준 뒤, unmarshal 함수에 각각 (marshal된 데이터, 새 객체)를 넣어준다.
→ marshal된 데이터 ⇒ 새 객체로 unmarshal된 데이터가 들어가는 것 같다.
→ 비유하자면, marshal ↔ unmarshal은 [암호화 ↔ 복호화], [압축 ↔ 압축해제] 이런 식으로 연상해서 생각할 수 있을 것 같다.
그런데 한가지 신기한 점으로, 저기에 GetAge()와 GetName() 함수를 볼 수 있다. 일단 내가 만든 함수는 아닌데 저게 어디서 난걸까?
저건 person.proto 파일을 person.pb.go로 컴파일할 때, pb.go 파일에 저런 함수가 자동으로 만들어진 것이다.
→ unmarshalling한 데이터 값을 저런 함수를 통해 받을 수 있어 매우 편리하다
실행 결과 다음과 같은 값을 볼 수 있다.
ex02
이제 개인정보에 sns 팔로워들 = {트위터 팔로워, 유튜브 팔로워 ... } 등의 정보도 함께 넣어볼 것이다.
다음과 같이 proto 파일을 변경하였다.
syntax="proto3"
package main;
message SocialFollowers {
int32 youtube = 1;
int32 twitter = 2;
}
message Person {
string name = 1;
int32 age = 2;
SocialFollowers socialFollowers = 3;
}
main.go 파일에서 elliot의 구조체 정의를 바꾸고, 코드 아래에 sns팔로워를 가져와 출력하는 코드도 2줄 넣었다.
elliot := &Person {
Name: "Elliot",
Age: 24,
SocialFollowers: &SocialFollowers{
Twitter: 1400,
Youtube: 2500,
},
}
fmt.Println(newElliot.SocialFollowers.GetTwitter())
fmt.Println(newElliot.SocialFollowers.GetYoutube())
실행 결과 다음과 같은 값을 볼 수 있다.
'IT > 개발 언어 및 도구' 카테고리의 다른 글
[연구] 컨테이너넷 (containernet) 프레임워크 소개 (0) | 2022.07.13 |
---|---|
[Go] 고 루틴(go routine)의 활용 - 기초 (0) | 2022.05.27 |
[Go] 왕초보 grpc 튜토리얼 - 간단한 서버-클라이언트 메시지 교환 (0) | 2022.03.28 |
[개인적인 팁] 영어 논문 쉽게 읽는 법
본 포스팅은 영어 논문 읽기를 헤메는 입문자용 야매 가이드라인입니다.
특히 공학이나 IT 논문을 읽는 중에 참고하시면 좋을 것입니다^^.
논문을 많이 읽어오신 능숙한 분께서는 본인 방식대로 하시는게 제일 좋습니다.
이건 아주 개인적인 팁이므로, 참고만 해주세요~
근황 - 연구실 인턴 출근 (학기 병행)
최근 포스텍 MCNL 연구실에서 연구실 인턴을 하게 되었습니다. (학교가 비대면 수업으로 확정되면 3학년 복학과 동시에 병행할 생각이고, 그렇지 않다면 쭉 1학기 간은 연구실에만 대면 출근할 생각입니다.)
과거에 학술동아리에서 AI논문 리뷰활동을 한 적이 있지만, 그때는 내용을 이해도 못하고 얼추 캡쳐만 해서 정리한 내용만 ppt에 넣고 그랬던 것 같습니다. 최근에 제대로 논문을 읽으려니 너무 힘들더라구요.
영어를 해석하는 것의 문제가 아니라 그냥 내용이 한줄 한줄 머리에 안들어오고 흘러나간다고 할까요. 흐름도 잡기 힘들었습니다.
그러던 와중 좋은 방법을 발견해서 논문을 끝까지 잘 읽을 수 있게 되었습니다. 개인적인 팁이지만, 처음 논문을 읽기 시작하는 분들께 도움이 될 수 있을까 싶어 그 방법을 공유합니다.
그럼 시작합니다~
논문을 읽는 것은 어렵다.
더군다나 그게 영어라면 더 그렇다. 또 논문은 한 문장이 너무 길고, 또 모르는 전문 용어로만 가득차있다. 그래서 번역기 돌려서 한글로 봐도 뭔뜻인지 알기 힘들다.
읽다가 흐름을 놓치는 경우가 대부분이다. 읽기 시작해봐도 이전 단락 내용들을 계속 까먹으니, 흐름을 잃게 된다. 막히기 시작하니 점점 한줄 조차 읽기 힘들다.
수능 비문학 지문처럼 분석하며 읽어라.


문제 원인 - 영어가 아니라 '독해력'이 문제다.
일단 영어 논문이다보니, 영어 실력이 있으면 물론 너무 좋다.
근데 영어 논문은 기본적인 영어 해석이 가능한 경우에도 읽기가 힘들다... 문장 구조부터가 복잡하니까. 즉, 영어 실력만의 문제가 아니라는 소리다.
알고보니, 우리의 문제는 독해력이었다...!

국어 수능 비문학 킬러 지문들을 생각해보자. 아니면 검색해서 읽어보자. 한국말인데도 외국어 같은 그 지문이 잘 읽히는 가? 당연히 아니다... 그게 영어로 되있는게 영어 논문인데, 이건 더욱이 잘 읽힐 리가 없다.
영어실력보다는 독해력의 문제인거다.
읽은 글 흐름들을 머리속에 잘 잡아둬야하는데, 이걸 잡아두지 못하니 읽는 데 진도를 못나가는 거였다.
특히 영어 + 전문용어에 더불어 수식구가 길게 달린 글이다보니, 아무래도 글 흐름을 잡고 기억해놓기 너무 힘들지 않은가!
국어 수능비문학도 외계어 같은데, 하물며 영어라고 하면... 쉽지 않을 것이다.
해결 방안 - 메모를 통해 글의 흐름을 붙잡자.
그러니 이걸 해결하기 위해서는 밑줄과, 각 단락의 핵심 + 주제 찾기를 하는 것이 좋다.
맞다. 우리가 고3 시절 국어 비문학 지문을 읽고 풀 때 주로 쓰던 풀이 방법이다.
눈알만 굴리지 말고 손으로 바쁘게 밑줄 치고 메모를 하자.
손이 바쁠수록 머리는 편하게 읽을 수 있게 된다!!!!!
흐름을 놓쳐도, 이전 단락 요약문(1줄)만 보는 것으로 다시 흐름을 잡을 수 있게되니까 말이다.
내 방식은 3회독을 기본으로 하니, 1회독은 부담없이 시작해보도록 한다.
1회독 방법
1회독에는 디테일을 완벽하게 잡는다는 마음을 버리자. 첫 술에 배부르랴? 자세히 공부하는 것은 2~3회독부터이다.
흐름만 슥 훑는다는 느낌으로 가본다. 1회독에서는 흐름만 잡아도 훌륭한거다!
먼저, 비문학 분석을 위한 기본적인 팁 2가지를 먼저 소개한다.
1. 형광펜으로 밑줄 긋기
나는 이 테크닉만으로 읽는 속도 + 이해하는 속도를 훨씬 올릴 수 있었다.
일단 형광펜을 3가지 준비한다.
-
- 연핑크 - 중요한 것. 흐름 상 메인 문장.
- 연핑크색 밑줄 부분은 짧아야한다. 따라서, 수식어와 보충설명 부분은 다 빼고 딱 본론만 쳐놓는다.
- 이렇게 하면, 연핑크색만 봐도 흐름을 잃지 않고 따라갈 수 있다.
- 핫핑크 - 핵심 문장. 주제문.
- 핫핑크색 문장은 가장 중요한 주제 문장에만 쳐놓자.
- 연두 - 모르는 것, 더 공부할 것
- 논문을 보면 모르는 용어가 굉장히 많이 나오는데, 당장 필요한 부분만 간단히 찾아보자.
- 연핑크 - 중요한 것. 흐름 상 메인 문장.
모르는 부분이 많아도 되니까, 흐름을 잃지 않고 따라가는 것을 최우선으로 하자.
2회독 때부터 연두색 부분에 대한 조사 및 정리를 할 것이니, 1회독 시점에서는 맘을 편히 가져도 된다.
논문의 서론 파트에 언급된 것들 중 중요한 배경지식들이 당연히 존재하지만, 직접적으로 연관되지 않는 단어들도 굉장히 많기 때문이다. 어차피 중요한 용어는 뒤에도 반복해서 나오게 되니, 그때 그 용어들만 다시 공부해보면 된다.
또, 모르는 영단어 같은 경우는 중간중간 아래에 작게 한글 뜻을 써놓기도 했다.
2. 각 단락 요약하기
밑줄을 치며 읽었는가?
이제 각 단락 아래에 1줄 요약을 남겨보자.
단락 아래에 단락 요약을 1줄 이내로 이렇게 짧게 남기기만 해도, 흐름을 잡기 굉장히 수월해진다.
이런 식으로 단락 요약을 하게되면, 중요하지 않은 서론 부분에 긴 시간을 빼앗기지 않으면서 흐름을 잡기 매우 편하다.
본론 부분의 흐름도 잃지 않고 따라가는 데 큰 도움이 된다.
강력 추천하는 방식.
3. 논문 구조에 따라 읽기
이제 논문 구조에 따라서 어떻게 읽어야하는 지 요령을 준다.
논문 구조는 주로
- 개요-서론
- 실험 과정 & 원리
- 결과 분석
- 결론
이런 구조로 되어있다.
개요 - 서론
개요에는 주로 배경지식이나 현재 상황 등이 나오기 마련이다.
그런데 모르는 게 너무 많은 경우에는 답이 없다. 모르는 걸 전부 찾아보느라 흐름을 놓치기도 쉽고, 찾아봤던 내용들도 다 까먹고 만다.
그러니 이 부분에서 모르는 용어가 좀 나와도 초록색으로 밑줄 치고, 간단하게 검색만 해보고 넘어가자. 1회독이기도 하고, 지금 앞부분에 집착해봐야 시간만 날릴 가능성이 높다.
어차피 뒤에 반복될 부분이 그 중 절반도 안된다. 반복되는 부분은 그때 가서 다시 검색해보게 될 것이라 상관 없다.
개요에서 제일 중요한 것은, 연구 주제와 목표 부분이 나오는 핵심 문장 하나를 건지는 것이다. 그 외에는 무시하고 넘어가자.
개요 부분에서 너무 많은 시간을 뺏기지 말고, 적당히 넘어가는 것이 좋다. 그 시간에 이 논문의 실험과 그 원리 파트를 이해하는 것이 훨씬 이득이다.
서론에서는 이 논문에 관련된 배경분야의 지식-인용 논문들이 많이 소개된다. 따라서 단락 요약으로 대강 흐름만 잡고 넘어가자.
실험 과정 & 원리
제일 중요한 부분이다. 개요 부분에서 봤던 핵심 주제문을 되새기며 들어간다.
서론-개요에서 연두색으로 밑줄친 부분이 다시 반복되는 지 보자. 여기서 그게 또 등장한다면, 그 용어에 대해서는 다시 검색해서 확실히 이해해줘야한다.
그 다음엔, 실험의 구조나 원리같은 것들을 천천히 정독하며 이해해보자. 이 부분만 잘 잡아놔도 끝까지 무사히 완주할 수 있다. 그렇지만 복잡한 수식이나 그런 부분이 나오면 이해하기가 어려워진다. 이때는 논문에 나오는 각 수식/도표 파트에 대한 부연설명을 해당 수식에 직접 표기해가며 읽어준다. 수식이나 도표만 봐도 해당 설명이 덕지덕지 붙어있으면, 글을 왔다갔다해가며 설명을 찾을 필요가 없어진다. 이때, 단락 요약도 빼먹으면 안된다.
손을 바쁘게 쓸 수록 머리가 덜 아픈 부분이니, 손으로 많이 써가면서 표기해주자.
결과 비교 & 분석
이 부분도 단락 요약으로 흐름을 잡아가며 넘어간다.
어떤 면에서 어떤 성능이 어떻게 향상되고 어쩌고~ 이런 디테일하고 복잡한 부분은 지금 이해할 필요 없다. 2회독 3회독에서 자세히 볼 거다.
결론
이 부분에서 실험 결과가 어땟는 지 대강 요약 해주는 경우가 많다.
내가 앞서 흐름에 잘 맞게 논문을 읽었는 지 확인할 수 있다.
복습하는 느낌으로 가볍게 쭉 읽어가며 끝내자.
2회독 방법
1회독에서 밑줄 긋기와 단락 요약을 전부 해놓은 상태이니, 할 것이 많이 줄었다.
흐름은 대략 잡을 수 있게 되었으니, 이전에 연두색으로 밑줄 쳐놓은 부분을 모두 다시 검색해보며 알아두자.
그 부분에 대해서는 따로 메모장, 블로그, 노트 등에 기록하며 정리해두면 더 좋다. 논문을 확실히 이해하기 위해서는, 논문에 언급된 배경지식들도 알아놓으면 좋기 때문이다.
또, 다시 흐름을 따라 읽어내려가면서 지난 번에 중요했던 부분들도 다시 복습해준다.
이제 복습의 효과로 실험이나 그 원리 관련해서 이해도가 좀 더 높아진 상태일 것이다.
이 상태에서 실험 결과와 과정 관련해서 디테일한 부분들도 이해해가며 읽어준다. 이해가 안되면 이부분도 직접 요약문을 옆에 메모해가며 읽는다.
너무 이해가 안되는 부분은 몇번 읽어주고 넘어가자. 3회독도 남았으니 이때 반복 학습해주면 이해 될 것이다.
3회독 방법
중요한 배경지식와 그 용어 관련해서는 따로 어디에 정리를 하며 공부하면 더욱 좋다. (블로그나 메모장, 노트 등)
2회독과 같은 방법으로 논문을 다시 읽는다. 이해가 안되는 부분이 남아있을테니 그 부분을 집중적으로 읽으며 이해하려 노력한다.
이제는 논문 관련해서 논문 리뷰 또는 그와 같은 정리 자료(블로그 포스팅이나 ppt)를 만들어도 좋다.
추가) 요즘 알게된 사실인데, 번역기에 영어 -> 중국어 -> 한국어 이렇게 3단계를 거쳐 변환하면 매끄럽게 번역이 된다는 이야기도 있더라구요. 영어랑 중국어 어순이 비슷해서 그렇다나요. 저는 이 방법을 써본 적은 없는데, 혹시 참고하실 분은 한번 시도해보셔도 좋을 것 같아요~
이렇게 개인적인 야매 가이드라인이 끝났습니다. ㅎㅎ
도움이 되셨다면 좋아요 눌러주세요~
댓글이나 지적 환영합니다 ^^
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
이전에 만든 Ren'Py 튜토리얼 모음 (0) | 2025.05.23 |
---|---|
서비스 디자인 (기술 / 기획) 가이드 배포 (2) | 2025.05.02 |
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
[오류] VM VirtualBox 시작 오류
오늘 ubuntu의 가장 최신버전을 다운 받아, 가상머신(vmbox)에 설치하려고 했다.
그러던 와중, 다음과 같은 문제점이 발생했다. 이 문제를 해결하려고 한참 삽질했었는데, 윈도우에서 BIOS에 진입하는 방법을 잘 몰라 시간이 한참 걸렸다. 그러던 중, 다음과 같은 방식으로 너무 쉽게 해결이 되었다.
따라서, 나와 같은 오류를 겪는 분들에게 이 포스팅이 많은 참고가 되길 바란다.
오류 메시지 :
Not in a hypervisor partition (HVP=0) (VERR_NEM_NOT_AVAILABLE).
VT-x is disabled in the BIOS for all CPU modes (VERR_VMX_MSR_ALL_VMX_DISABLED).
결과 코드: E_FAIL (0x80004005)
구성 요소: ConsoleWrap
인터페이스: IConsole {872da645-4a9b-1727-bee2-5585105b9eed}
이런 식의 오류가 뜰 수 있다.
이때 나는 bios에 진입하여 virtualization 설정을 바꿔주는 것으로 이 문제를 해결했다.
참고로 나는 지금 윈도우10의 pc를 사용 중이다.
윈도우10 빠른부팅 바이오스 진입하기 - 아이티온즈넷
메인보드 BIOS (UEFI) 설정에서 빠른부팅(Fast Boot/Ultra Fast)이 설정되어 있으면 바이오스(BIOS) 진입이 힘들 수 있습니다. 그래서 윈도우10 에서 쉽게 바이오스로 진입할 수 있습니다.
itons.net
위의 링크를 통해, 바이오스에 진입하자.
나는 다음과 같은 화면이 떳고, 저기 현재 시간 옆에 english, 그리고 그 옆에 search가 있는 걸 볼 수 있다.
search를 클릭한 뒤, virtualization을 검색하여 설정을 enable로 바꾸어주었다. 그리고 Save&Exit을 눌러 컴퓨터를 시작해주었다.
그러니까 짜잔~ 마법같이 문제가 해결되었다. ㅎㅎ 행복하다.
BIOS가 아닌, Hyper-V가 켜진 경우에도 저런 문제가 발생한다 하니, 아직 문제가 해결되지 않았다면 그 부분도 체크해봅시다~ 다음의 링크를 참고하세요.
https://blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=yundongcheol&logNo=221315290857
Virtualbox : VT-x is not available 오류 조치 방법
VirtualBox 에서 VM 실행시 VT-x is not available 오류가 나온다면 크게 2가지 이유일 거 같습니다....
blog.naver.com
'IT > 개발 환경 및 설치' 카테고리의 다른 글
[ARM64] M1 맥북에서 윈도우 사용하기 (feat. Parrellels) (0) | 2022.07.04 |
---|---|
[ARM64] 맥북 M1 위에 설치한 리눅스 가상환경에서 vscode 설치하기 (0) | 2022.06.28 |
[오류] 맥북 m1 : gdb 설치 오류 - Error: gdb: no bottle available! (0) | 2022.01.23 |
리눅스에 GUI가 설치되어있는 지 확인하는 방법 (명령어) (0) | 2021.11.21 |