Codong's Development Diary RSS 태그 관리 글쓰기 방명록
분류 전체보기 (48)
2021-03-11 21:34:31

👋 개요


한글 자연어처리 라이브러리로 konlpy나 mecab을 사용하여 형태소 분석이나, 명사추출을 할 때, 신조어나 복합명사들이 제대로 추출되지 않는 경우가 있다. 그런 경우 따로 분석기에 사용자 사전을 추가해서 그러한 문제를 보완할 수 있다.

하지만 매번 사람이 일일이 다 찾아서 작성할 순 없는 노릇이다. 그러면 어떻게 하면 좋을까? 🤔

 

👍 soynlp


한국어 분석을 위한 한국어 자연어처리 라이브러리다. 학습데이터를 이용하지 않으면서 데이터에 존재하는 단어를 찾거나, 문장을 단어열로 분해, 혹은 1품사 판별을 할 수 있는 비지도학습 접근법을 지향한다. 여러가지 버전의 명사 추출기를 제공하고 있다.

from soynlp.noun import NewsNounExtractor

noun_extractor_news = NewsNounExtractor(
    max_left_length=10, 
    max_right_length=7,
    predictor_fnames=None,
    verbose=True
)
nouns_news = noun_extractor_news.train_extract(sentences)

# 출력
used default noun predictor; Sejong corpus based logistic predictor
/Users/dong/opt/anaconda3/envs/cow_word/lib/python3.7/site-packages/soynlp
local variable 'f' referenced before assignment
local variable 'f' referenced before assignment
scan vocabulary ... 
done (Lset, Rset, Eojeol) = (518797, 290268, 289869)
predicting noun score was done                                        
before postprocessing 138637
_noun_scores_ 30616
checking hardrules ... done0 / 30616+(이)), NVsubE (사기(당)+했다) ... done
after postprocessing 21026
extracted 985 compounds from eojeolss ... 45000 / 45737

 

그 중에서 나는 많은 기능을 포함하고 있는 NewsNounExtractor 를 사용했다. 왜냐하면 뉴스 데이터를 사용하기도 하고, 여러가지 속성들을 가지고 있기 때문이다.

아직 감이 안오니 어서 출력해보자. score를 기준으로 내림차순 정렬을 해서 200개만 출력해봤다.

 

sort_nouns_news = sorted(nouns_news.items(), key=lambda x:-x[1].score)[:200]
print(tmp_)

# 출력
[('기초수급자',
  NewsNounScore(score=1.0, frequency=16, feature_proportion=0.25, eojeol_proportion=0.5, n_positive_feature=1, unique_positive_feature_proportion=1.0)),
 ...]

 

출력결과를 보면 7개 가량의 속성이 있음을 알 수 있다. 그 중에서 나는 score, frequency, feature_proportion 이 세 가지에 집중해봤다.

 

1️⃣ score : 명사 가능성을 점수로 표현했으며, 튜토리얼 문서에 따르면 한국어는 L + [R] 구조이며, 명사 뒤에 나오는 R set을 모아 명사 가능 점수를 학습 시켜놨다. R set에 '있게'는 1.0점, '있는'은 0.3 점이라 등록되었다 가정하고, '재미 + 있게' 3번, '재미 + 있는' 2번 등장하였다면 재미의 명사 가능 점수는 (3 x 1.0 + 2 x 0.33) / 5 = 0.732점 이라고 한다.
2️⃣ frequency : 딱 보면 느낌오겠지만, 그 단어가 나온 빈도수이다.
3️⃣ feature_proportion : 이것에 대해 제대로 나오진 않았지만, 번역기 돌려보면 특성이 있는지(?) 정도로 추측이 된다.

 

🤩 아이디어


soynlp를 활용하여 미등록단어 문제를 해결할 수 있지 않을까? 라는 생각을 해보았다.

그래서 떠오른 아이디어는 뉴스데이터를 크롤링하여 soynlp의 명사추출기로 추출된 명사를 10개씩 ' '(공백)으로 이어 붙여 형태소 분석기(사용한 것은 mecab)을 통해 명사 분석한다. mecab을 통해 나온 output을 input으로 넣었던 명사와 비교하여 분석되지 않은 명사가 어떤 것인지 살펴보는 것이다!

글로 적으니까 햇갈리니 허접하지만 직관적인 플로우 차트를 그려봤다.

아무튼 느낌은 왔으니 실제로 해봐야 알 것 아닌가??

 

🤔 진행과정


데이터는 우선 네이버 뉴스데이터에서 크롤링을 했고, soynlp로 추출된 명사는 score * frequency * feature_proportion 계산을 하여 높은 순서대로 상위 200개를 사용했다.(➕ 글자수가 2개 이하인 것들은 제외했다.)

nouns_news_tmp = {key: value for key, value in nouns_news.items() if len(key) > 2} 
top_news = sorted(nouns_news_tmp.items(), 
    key=lambda x:-x[1].frequency * x[1].score * x[1].feature_proportion)[:200]
for i, (word, score) in enumerate(top_news):
    if i % 4 == 0:
        print()
    print('%6s (%.2f)' % (word, score.score), end='')

# 출력
오마이뉴스 (0.99)   이재명 (0.96) 코로나19 (0.95)  페이스북 (0.89)
   상대적 (1.00)   시민들 (0.82)최고위원회의 (0.97)   간담회 (0.88)
   김현정 (1.00)   그동안 (0.82)  세금으로 (1.00) 정책협의회 (0.99)
   마스크 (0.96)  제3지대 (0.94)수원컨벤션센터 (1.00)  CCTV (0.84)
  거리두기 (0.82)  민주주의 (0.87)   바람직 (0.99)   공동체 (0.95)
   대체재 (0.98)  장례식장 (0.96)  포퓰리즘 (0.80)   일자리 (0.80)
   여배우 (0.99)   취재진 (0.98)   불가능 (0.90) 글래드호텔 (1.00)
   있었기 (1.00)한국사회여론연구소 (1.00)   아이들 (0.72)  경기지사 (0.73)
   더불어민주당 (0.61)   재보선 (0.80)   부적절 (1.00)연합뉴스TV (1.00)
   ...

 

이렇게 추출된 명사들을 10개씩 문장으로 만들어서 mecab에 넣어서 비교를 해봤다. 정확도는 전체 개수 중 맞춘 개수이다.

 

# 추출된 명사를 단어만 뽑아 리스트화 시킨후
word_list=[i[0] for i in top_news]

str_dic={}
# 10개씩 나눠서 끝에 마침표를 찍어 딕셔너리에 담는다.
for n in range(0,len(word_list),10):
        word_dic[n]=word_list[n:n+10]
        tmp_str=' '.join(word_dic[n])
        str_dic[n]=tmp_str+'.'

...

# 출력
입력텍스트(soy_nlp 명사) : ['아이들 경기지사 단일화 어떠한 리얼미터 실시간 더불어민주당 재보선 부적절 연합뉴스TV.']
출력텍스트(mecab 통과) : ['실시간', '리얼미터', '경기지사', '단일', '아이', '연합', '부적', '보선', '뉴스', '민주당']
정확도 : 0.3
맞춘명사 : ['실시간', '리얼미터', '경기지사']
없는명사 : ['아이들', '단일화', '어떠한', '더불어민주당', '재보선', '부적절', '연합뉴스TV']

 

코드가 좀 더럽고 길어서 다 올리긴 좀 그래서 초반부만 올렸다.. 생각보다 결과는 처참했다..

 

😳 결과


  • 첫번째 문제점은 추출된 명사를 공백으로 이어 붙여서 완전한 문장이 아니라 그냥 명사로만 이루어진 문장이라 그런지 mecab이 제대로 인식하지 못하는 경우가 많았다. 이 부분은 mecab의 명사 추출 과정을 이해하지 못했기에 신경쓰지 못했다.
  • 그리고 추출된 명사도 200개를 뽑았을 때 더불어민주당, 거리두기, 재보선과 같이 복합명사나 신조어(줄임말 등)가 보이긴 하지만, 있었기, 세금으로와 같이 이상한 결과들도 많다..

 

🙌 마무리


그래도 나름 하면서 재밌다고 생각했던 시도였다. 다만 생각보다 결과가 좋지 않아서 문제다... 저것만 사용해서 미등록단어를 자동으로 등록하게 한다면 결과가 좋지 않을게 뻔하다... 다음엔 우선적으로 내가 사용하는 모델의 원리에 대한 이해하는 과정을 충분히 거친 뒤, 이러한 작업을 시도하면 더 좋은 결과를 낼 수 있지 않을까 싶다. 앞으로 더 분발하자 ~~ 🔥

 

reference

2021-03-08 21:58:06

개요


대게는 데이터를 csv 파일이나 excel파일, txt파일로 접하게 되었다. 하지만 이 데이터들을 파이썬에 옮겨서 지지든, 볶든, 어떻게든 요리하고 싶다면 어쩌면 좋을까? 엑셀처럼 다룰 수 있으면 얼마나 좋을까? 그래서 준비한게 PANDAS 라이브러리다!

pandas 란?

pandas는 데이터 조작 및 분석을 위해 Python 프로그래밍 언어로 작성된 소프트웨어 라이브러리다. 특히 숫자 테이블과 시계열을 조작하기위한 데이터 구조와 연산을 제공힌다. 그리고 pandas의 DataFrame은 여러 개의 Series들의 조합으로 구성되어 있다. 뒤에 예제를 통해 알 수 있다.

글로만 봐선 잘 모르겠다... 어서 시작해보자!

 

Pandas 요리하기


1. DataFrame 생성하기

생성하는 것은 상당히 쉽다. 제일 먼저 pandas 라이브러리를 pip install pandas로 설치한 후 import 하고 생성하자!

 import pandas as pd # pd로 줄여 사용하는게 국룰

 # 1) 딕셔너리로 생성하기 dic의 key가 컬럼이 되고, value가 값이 된다.
 data={'name':['철수','영희'],'Phone_num':['01033334444','01011112222']}
 df = pd.DataFrame(data,index=['1번','2번'])

 # 2) 이중 리스트로 만들기
 data=[
     ['철수','01033334444'],
    ['영희','01011112222']
         ]
 # 또는 np.array로 만들기
 data=np.array([
    ['철수','01033334444'],
    ['영희','01011112222']
    ])

 df = pd.DataFrame(data,columns=['name','phone_num'],index=['1번','2번'])

 print(df)
 # 출력  name     phone_num
 # 1번   철수        01033334444
 # 2번   영희        01011112222

DataFrame 에는 인풋으로 다음과 같이 넣어줘야 한다. pd.DataFrame(value, index, columns) 에서 value의 shape이 (n,m)인 행열이 있다면, index의 길이(len(indax))와 n이 같아야 하고, columns의 길이(len(columns))가 m과 같아야 한다. 어찌보면 당연한 건데 헷갈린다,,

2. 열 / 행 추출

df의 매력적인 부분이 원하는 행, 또는 열을 쉽게 가져올 수 있다. 위 예제를 그대로 사용하여 이름 _열 데이터_만 가져오고 싶다면,

 print(df.name)
 # 또는
 print(df['name'])
 # 또는 iloc은 숫자로 접근. 컴마로 열부분임을 명시
 print(df.iloc[:,0])
 # 또는 loc은 값으로 접근
 print(df.loc[:,'name'])

 # 출력
 # 1번    철수
 # 2번     영희
 # Name:name, dtype: object

반대로 행의 데이터에 접근하고 싶다면,

 # iloc은 그 행의 번호(숫자)로 접근한다.
 print(df.iloc[0])
 # 또는 리스트처럼 인덱스 슬라이싱한다.
 print(df[:1])
 # 또는 loc은 index의 값으로 접근한다.
 print(df.loc['1번'])


 # 출력
 # name             철수
 # phone_num    영희
 # Name: 1번, dtype: object

이 둘의 공통점은 Series 객체로 반환된다. 이 Series를 이용하여 더 멋진 인덱싱이 가능하다!

3. 조건에 맞는 데이터 추출

실제 데이터들은 정말 많고 많을 것이다. 위의 예제의 경우 이름이 철수인 데이터만 보고 싶을 땐 어떻게 하면 좋을까? Series를 이용하면된다!

print(df['name']=='철수')
# 출력
# 1번    True
# 2번    False
# Name: name. dtype: bool

# 본 df의 인덱스로 넣어주면 철수에 해당한 값만 가진 dataframe 출력
df[df['name']=='철수']

# 출력   name     phone_num
# 1번    철수        01033334444

위 코드를 실행하면 DataFrame에서 철수가 포함되는 행의 데이터는 True로 이루어진 boolean형태의 시리즈를 반환한다. 이 시리즈를 이용하여 본 데이터 프레임안에 넣어주면 True인 행, 즉 철수인 행만 출력이 된다.

4. 열 / 행 추가 및 수정

열 추가는 상당히 간단하다. 열을 추출할 때처럼 추가 시킬 column명을 적고, index의 길이에 맞춰 값을 리스트로 추가해주면 된다.

# 추가
df['sex']=['남','여']
print(df)
# 출력    name    phone_num    sex
# 1번    철수        01033334444    남
# 2번     영희        01011112222    여

# 수정 
df['phone_num']=['01034567890','01012345678']
print(df)
# 출력    name    phone_num    sex
# 1번    철수        01034567890    남
# 2번     영희        01012345678    여

행의 수정도 같은 맥락이다.

# 추가
df = df.append({'name':'코린','phone_num':'01025552223','sex':'남'},ignore_index=True)

# 인덱스까지 추가하고 싶다면 series로 만들어 추가
add_row=pd.Series({'name':'코린','phone_num':'01025552223','sex':'남'},name='3번')
df=df.append(add_row)

# 출력    name    phone_num    sex
# 1번    철수        01034567890    남
# 2번     영희        01012345678    여
# 3번    코린        01025552223    남

# 수정
df.iloc[1]=['희영','폰없음','남']

# 출력    name    phone_num    sex
# 1번    철수        01034567890    남
# 2번     희영        폰없음           남
# 3번    코린        01025552223    남

append를 이용하면, index가 상관없으면 위 처럼 딕셔너리 형태로 적용, ignore_index옵션 True로 해줘야함. 그렇지만, append만 하면 리스트처럼 바로 적용되지 않는다. 그래서 위와 같이 df = df.append()처럼 값을 재정의 해준다.

5. 자주쓰는 속성

데이터들을 표로 관리하는 것도 좋지만, 다른 모델의 인풋으로 넣어줘야 할 때가 있다. 그래서 자주 쓰는 메서드들을 적어보았다.

  1. index 가져오기
print(df.index)

# 출력
Index(['1번','2번','3번'], dtype='object')

# 리스트로 가져오기
index_list = df.index.to_list
print(index_list)

# 출력
['1번','2번','3번']
  1. columns 가져오기
print(df.index)

# 출력
Index(['name','phone_num','sex'], dtype='object')

# 리스트로 가져오기
columns_list = df.index.to_list
print(columns_list)

# 출력
['name','phone_num','sex']
  1. values 가져오기 array 객체로 다른 모델의 인풋으로 많이 사용한다.
print(df.values)

# 출력
array([['철수','01034567890','남'],
        ['희영','폰없음','남'],
        ['코린','01025552223','남']], dtype='object')

마무리


항상 편리한 도구들은 많다고 생각한다. 내가 어떤 작업을 할것인지, 그 작업에 가장 효율적인 도구를 찾아 사용하는 것이 제일 중요하다고 생각한다. 그렇지만 모르면 못쓴다^^ 찾아보고 까먹지 않게 한 번 썼을 때 정리 잘해놓자 !

2021-02-24 20:27:35

👋 개요


제일 처음 사용해본 DB는 SQLite 이다. 간단하게 DB를 사용해보기도 부담이 없고, python에서 기본으로 연동되는 DB이기도하고 사용하게 되었다. 아주 소량의 데이터를 관리할 때 쓰이기 때문에 실제 서비스를 제작하거나 할 때에는 사용불가할 것이다..


🕹 사용법


시작하기에 앞서, 눈으로 DB의 생성, 읽기, 수정, 삭제 등을 확인할 수 있도록 제공하고 있는 프로그램이 있다.

https://sqlitebrowser.org/ 이 곳에서 다운 받으면되고, 귀찮으면 command창에 sqlite3 를 입력하면 사용할 수 있기에 굳이 안써도 된다.


1️⃣ DB 연결하기 (생성하기) 및 cursor 생성

python에서는 라이브러리 설치도 필요없다 그냥 바로 import 하면 된다!

import sqlite3
connect = sqlite3.connect("db명", isolation_level=None)
# isolation_level=None 시 오토커밋 사용.

cur = connect.cursor()

cur.execute("select text from db")

DB파일이 있다면 그 DB와 연결될 것이고, 없다면 생성될 것이다! 제일 먼저 DB를 다루기 위해서는 커서를 생성한다. 그리고 execute 함수를 이용해 쿼리문을 작성해 실행시킬 수 있다. 쿼리문은 주로 str 타입 변수로 작성해 사용한다.

그리고 DB 수정시 commit 또는 rollback 을 사용한다. connect.commit()은 수정된 사항을 DB에 반영하는 것이고, connect.rollback은 이전으로 되돌린다는 뜻이다. 원래는 매번 수정 후 반영을 위해 '꼭!' commit을 해야하지만, 위에서 isolation_level=None 이용했기에, 안해도 된다.

➕ command 창으로 이용시, .open (파일명) 을 입력해 DB에 접근한다. 그리고 쿼리문 작성시 끝에 꼭 ';'(세미콜론)을 붙여줘야 한다.


2️⃣ DB 다루기


위에서 잠깐 나온 쿼리를 실행시키는 cur.execute를 이용해 DB를 다루는 방법들을 본격적으로 알아보겠다.


1. Table 생성하기

cur.execute("CREATE TABLE (옵션:IF NOT EXISTS) (테이블명:table1) \
    ((컬럼:id) (타입:integer) (키설정:PRIMARY KEY), (컬럼2:name) (타입:text) ...")
  • 테이블 목록 조회 방법:SELECT name FROM sqlite_master WHERE type='table';
  • 테이블 구조 확인 : select * from sqlite_master where tbl_name='table명';

2. 데이터 삽입 (CREATE)

INSERT INTO (테이블명) VALUES (값)

cur.execute("INSERT INTO testtable \
    VALUES(1, 'dong')")

# 여러 행 삽입시
values_tuple = (
    (3, 'hi'),
    (4, 'hello'),
    (5, 'annyeong')
)
cur.executemany("INSERT INTO table1(id, name) VALUES(?,?)", values_tuple) 

한번에 여러번 하고싶으면 executemany 를 사용한다.


3. 데이터 조회 (READ)

SELECT (필드명) FROM (테이블명) (WHERE(조건절,생략가능)) (컬럼명)='(값)'

# 필드명에 *(와일드카드)를 이용하여 해당 테이블에 모든 행 불러와서 가져온 값 출력
cur.execute("SELECT * FROM testtable")
print(cur.fetchall())

# WHERE 절을 사용하여 필터링 가능.
# ? 를 써서 파라미터를 받을 수도 있고,
cur.execute("SELECT * FROM testtable=?", parameter)

# 문자열 포메팅도 가능
cur.execute("SELECT * FROM testtable={}".format(parameter))
# dictionary 형태로 받을 수도 있고 다양하게 가능..

SELECT 문을 사용하여 cur에 값이 오면, cur.fetchone()를 써서 값을 가져온다. 모든 값을 가져오려면 cur.fetchall()을 사용하면 iterable 한 객체가 반환되어 for문을 이용하여 값을 하나씩 가져올 수 있다.


4. 데이터 수정 (UPDATE)

UPDATE (테이블명) SET (필드명)=(값) (WHERE(조건절))

cur.execute("UPDATE testtable SET name=? WHERE id=?", ('bye', 1))
# 또는 
cur.execute("UPDATE testtable SET name=:name WHERE id=:id", {"name": 'bongju', 'id': 3})

5. 데이터 삭제 (DELETE)

DELETE FROM (테이블명) (WHERE(조건절))

cur.execute("DELETE FROM testtable WHERE id=?", (1))

# 이외 등등..
cur.execute("DELETE FROM testtable WHERE id=:id", {'id': 3})

# where 절 생략시 모든 행 지움
cur.execute("DELETE FROM testtable)

모든 작업이 끝나면 connect.close() 사용해 연결을 해제해야 한다.


👋 마무리


이상으로 SQLite의 사용법을 알아봤다. SQLite는 거의 쓰지 않는 DB라서 사용하지 않을 것 같지만, SQL은 RDBMS에서는 문법이 비슷비슷하니 이참에 감을 익혀두는 것도 좋은 것 같다! 테스트 용도로도 쓰기도 하니까 알아놓으면 좋지 않겠는가~


reference

2021-02-24 00:30:41

🧐 정규표현식이란?


정규 표현식(regular expression, 간단히 regexp 또는 regex, rational expression) 또는 정규식(正規式)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다. 정규 표현식은 많은 텍스트 편집기와 프로그래밍 언어에서 문자열의 검색과 치환을 위해 지원하고 있으며, 특히 펄과 Tcl은 언어 자체에 강력한 정규 표현식을 구현하고 있다.

즉, text에서 패턴을 파악해 찾고, 바꾸고, 지우고 등등을 할 수 있다! 전처리 단계에서 빠질 수 없는 부분! (언제까지 .split,.strip 등 만 쓸래??!!)


📝 사용법

아주 간단하다. import re를 한다음 여러가지 메서드를 사용하면 된다~~😆 자세한 설명은 밑에서..


💱메타문자


  1. 문자 클래스 [ ]
    문자 클래스로 만들어진 정규식은 "[ ] 사이의 문자들과 매치"라는 의미를 갖는다. 주로 [0-9] : 숫자, [가-힣] : 한글, [a-z] 이런식으로 많이 사용한다. 이 괄호 사이에 들어가는 다른 메타 문자들은 다 문자로 인식되므로 주의하기! 그리고 ^ 이 들어가면 not의 의미가 되므로 주의!

자주 사용하는 문자 클래스

  • \d : 숫자 [0-9]와 같다.
  • \D : 비숫자 [^0-9]와 같다.
  • \w : 숫자 + 문자 [a-zA-Z0-9]와 같다.
  • \W : 숫자 + 문자가 아닌 것 [^a-zA-Z0-9]와 같다.
  • \s : 공백 [ \t\n\r\f\v]와 같다.
  • \S : 비공백 [^ \t\n\r\f\v]와 같다.
  • \b : 단어 경계 ('\w'와 '\W'의 경계)
  • \B : 비단어 경계
  • .(dot) : \n을 제외한 모든 문자와 매칭

이것들은 한번만 쓰면 한 글자를 매칭한다. 그렇다고 3자리 숫자를 표현하는데 \d\d\d 이렇게 쓸 순없지 않는가? (사실 가능) 100자리 숫자면? \d\d\d\ ... \d\d? 말이 안된다. 그렇기에 등장한 것이...

  1. 반복
    문자 클래스 뒤에 붙이면 반복 된다.(ex. \d*) 종류는 다양하다
  • * : 0번째부터 반복된다.
  • + : 1번째부터 반복된다. ex) txt = aadd 일때 'aaddc*' (o) 'aaddc+' (x)
  • {m,n} : m부터 n까지 반복된다.
  • ? : 0번 아니면 1번 일때. {0,1} 이랑 같지만 이게 생각보다 쓸모있는게 태그 같은건 <h1> </h1> 이런식으로 /가 있을 수도 없을 수도 있기에 편리함.

제공되는 기능

search, findall,match, sub 등등 다양한 것이 있다.


👀 내가 자주 썻던 부분


한 줄로 re.sub( , , ) 로 간단하게 사용할 수 있지만, re.compile( 'Pattern' )을 사용하여 변수로 저장해두면 재사용 가능!

1️⃣ re.search('검색할 텍스트','패턴') : 텍스트 내에서 내가 원하는 패턴 위치 찾기

import re

text='지금 날짜는 2021. 02. 23 이래용 ㅎㅎㅎ'
p = re.compile(r'\d{4}.\s\d{1,2}.\s\d{1,2}')

# search 함수로 해당 텍스트의 시작 위치, 끝 위치 검색
# .span은 start index와 end index를 튜플로 반환
idx=p.search(text).span()

# 원래 text에서 위의 인덱스를 이용해 발췌
date = text[idx[0]:idx[1]]

print(date) # 출력 결과 >> 2021. 02. 23

2️⃣ re.sub('바꿀텍스트', '입력텍스트', '패턴') : '입력텍스트' 에서 '패턴'에 해당하는 부분을 '바꿀텍스트'로 바꾼다.

text='<h1>지금 날짜는 2021. 02. 23 이래용 ㅎㅎㅎ</h1>'

# [/]?는 /는 있어도 되고 없어도 되고, 알파벳 하나와 숫자하나 그리고 제일 밖 괄호
p = re.compile(r'\<[/]?[a-z][0-9]\>')

# 패턴에 해당하는 부분을 ''으로 바꿈 곧 없앰
pre_text=p.sub('',text)

print(pre_text) # 출력 결과 >> 지금 날짜는 2021. 02. 23 이래용 ㅎㅎㅎ

마무리

간만에 사용하게 되면서 생각보다 재밌음을 느꼈다. 물론 내가 적은 것 말고 그룹핑, 컴파일 옵션, 다양한 기능들... 등등 많지만 내가 사용하기엔 쓸만한 부분들은 적어뒀다고 생각한다. 다음에 다시 만났을 때 내가 안까먹길 바라면서 ... 이만 ... 👋

아참! 간단하게 테스트를 해볼 수 있는 사이트가 있다! 이곳에서 연습해서 적용시키는 것을 추천!

>> 실습하러가기 <<

reference

2021-02-18 21:35:42

🔥Pytorch를 이용한 딥러닝


Pytorch를 사용해 딥러닝 모델을 사용하려고 한다면 당연히 설치가 우선 아닌가? 이제 하나씩 해보자.


1. Pytorch 설치


간단하다. 공홈으로 가서 >>공식홈페이지링크<<

start 버튼을 누르고,


본인 컴퓨터 환경에 맞게 눌러주면 명령어가 뙇.


.
.
.
.
.


은 개뿔 cuda 설치하러 가자~~


2. CUDA 설치


CUDA는 NVIDIA 에서 개발한 GPU 개발 툴이다. GPU를 이용해 프로그램의 계산을 병렬로 처리하도록 한다. CUDA를 설치하려면 우선 본인의 그래픽카드를 알아야 한다. 자 그러면 우선 그래픽 카드부터 확인하러 가자.


🧐window 10 그래픽 카드 확인 법

시작 - 검색 - 장치 관리자 - 디스플레이 어댑터를 보면 NVIDIA 어쩌고 적힌 것을 확인할 수 있다.

위의 내용을 기억하고, https://developer.nvidia.com/cuda-gpus 이곳에 들어가서 본인 그래픽 카드 시리즈에 맞는 것을 눌러보면


Compute Capability 를 알 수 있다.(필자는 Geforce GTX 1060이라 6.1임을 알 수 있다.) 다음으로 이곳을 보면,


6.1에 맞는 것이 여러개 있음을 알 수 있다. 조건에 맞는 원하는 버전을 설치하면 된다. (필자는 pytorch1.4가 호환이 되는 cuda10.1으로 설치)

마지막으로 https://developer.nvidia.com/cuda-toolkit-archive 이 링크에서 이제 맞는 것을 설치하면 된다. OS에 맞게 고르고 Installer type은 local을 선택해서 한번에 받는다.


3. cuDNN 설치


CUDA 설치가 끝났으면 https://developer.nvidia.com/cudnn 이 링크에 들어가서 CUDA 버전에 맞게 cnDNN설치를 하자. 참고로 NDIVIA 로그인을 해야 받을 수 있다.

파일을 받은 후에, 압축을 풀고 CUDA가 설치된 경로로 들어가서 ex) C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
그 경로 안에 압축 푼 파일안의 내용물을 전부 옮긴다. 이후 커맨드창에 nvcc --version 입력하여 설치가 완료된지 확인한다.

.
.
.
.

자! 이제 다 설치했으니, 다시 파이토치 설치화면으로 가자! 🥳


그런데 봤더니 1.7.1 최신버전 기준이라 필자는 1.4를 쓸 예정이기 때문에 파란 밑줄 부분을 누르면 다른 버전의 커맨드를 알 수 있다.
어서 커맨드 창 키고 pip install torch==1.4.0 torchvision==0.5.0 가즈아아~~


마무리

결국 ERROR: Could not find a version that satisfies the requirement ... error가 떳다고 한다,,, 😱
아마 pip이 torch 1.4 버전과 내 피시의 환경과 맞는 whl파일을 못찾아서 그런 것 같다. 저와 같은 에러 뜨시는 분들 맞는 버전을 찾아서 -f (설치URL)로 해결이 된다고 하네요. pytorch 1.4 쓰실거면 파이썬 3.6 64bit 에서 호환이 되는 것 같습니다. 혹시라도 도움 되시길 바라면서 오늘도 마칩니다~~

2021-02-15 17:42:11

1. 🧐python 가상환경이란?


한 PC local 환경에서 하나의 프로젝트만 진행한다면 아무런 문제가 없다. 하지만 여러개의 프로젝트를 진행하게 되거나 협업시 각자의 버전대로 진행할 경우 문제가 발생한다. 프로젝트마다 라이브러리들의 버전이 다를 수 있고, 각 모듈에 대한 의존성이 다르기에 막 설치하다보면 충돌이 날 수도 있다. 그렇다고 다른 버전의 라이브러리를 일일히 지웠다가 설치 할 수 없기에 이를 방지하기 위한 독립적인 가상환경을 제공한다.

 

2. 📃python 가상환경의 종류 및 간단한 사용법


2.1 venv

파이썬3 에서는 pip install을 통해 설치할 필요도 없는 venv 라는 가상환경 라이브러리가 기본적으로 제공된다.

  1. 생성 : 원하는(프로젝트를 진행할) 폴더에서 아래와 같은 명령어를 작성하면 끝.

    python -m venv 가상환경이름
    # 또는 python -m venv 가상환경이름 --system-site-packages
    # 뒤에 --system-site-packages을 붙이면 기본 파이썬 사용시 설치했던 전역 패키지들을 깔고 시작.

    그러면 가상환경이름과 같은 폴더가 하나 생기는데, 실제 작업은 그 폴더에 들어가지 말고, 있는 곳(프로젝트 폴더)에서 하면된다.

  2. 활성화 및 비활성화

    # 윈도우 cmd
    > 가상환경이름\Scripts\activate.bat
    # bash
    $ source 가상환경이름/bin/activate

    비활성화는 deactivate를 입력하면 된다.

  3. 가상환경 내 패키지 설치 및 삭제
    pip install과 pip uninstall을 사용하면 된다.

  4. 패키지 목록 관리
    pip freeze를 입력하면 확인할 수 있다.

  5. 삭제 : 만들었던 가상환경 폴더를 제거하면 끝.


2.2 virtualenv

거의 venv와 동일하다.
pip install virtualenv 명령어로 라이브러리 다운 받고, virtualenv 가상환경명으로 생성한다.
+ 추가로 --python=python3.7과 같이 뒤에 옵션을 붙여서 원하는 파이썬 버전으로 생성이 가능하다.

pip freeze > requirements.txt를 사용하여 설치한 패키지들을 명시해두는 것이 팁. 다른 개발환경에서 변경된 패키지 의존성을 반영할 때에는 pip install -r requirements.txt을 사용한다.


2.3 pipenv

pipenv는 프로젝트 의존성 관리에 필요한 세세한 설정을 개발자가 일일이 신경쓸 필요가 없다는 것이 큰 장점이다. 의존성을 pipfile로 관리를 해주므로 requirements.txt를 대신한다. 그런 기능엔 대가가 따르는 법. 가장 큰 단점은 속도 문제이다.

  • 작동법

    # 설치
    pip install pipenv
    # 생성 및 활성화 (원하는 프로젝트 폴더에서 실행)
    pipenv shell
    # 비활성화
    exit
    # 패키지 설치
    pipenv install (패키지명. 생략시 pipfile에 적혀있는 패키지들이 한번에 설치됨)

※ 카카오 PyPI 미러 서버로 pip 설치 속도 높이기

+ pipenv 관련 정리 잘해두신분 링크 pipenv속도 올리기
pip 문서(pip문서 바로가기)의 configuration 부분에서 Global에 운영체제에 맞는 곳에 pip.ini 파일을 만들어서 아래의 내용을 편집기를 이용해 작성해주면 된다. 나의 경우 window 10 을 사용하는데 경로는 C:\ProgramData\pip\pip.ini 이곳에다 작성했다.

[global]
index-url=http://ftp.daumkakao.com/pypi/simple
trusted-host=ftp.daumkakao.com

설치중에 Looking in indexes: http://ftp.daumkakao.com/pypi/simple 이런 부분이 뜬다면 성공! 그래도 pipenv는 패키지를 다운 받을 때 locking 도 하므로 시간이 걸릴 수 밖에 없다.


2.4 pyenv

위의 가상환경들은 패키지 관리를 해줘서 편리하지만, 파이썬 버전을 다르게 가상환경을 생서할 때 설치되어있는 버전만 가능하다. 하지만 pyenv는 파이썬 여러 버전을 손쉽게 바꿔가면서 쓸 수 있도록 해주는 도구이다. 그야말로 위의 가상환경들과의 짝궁이라 보면 되겠다.

window

참고 링크 : https://github.com/pyenv-win/pyenv-win#pyenv-win-commands

mac

home brew로 간편하게 설치.

brew install pyenv

 

마무리


위의 가상환경 도구들 말고 또 다른 다양한 많지만, 각각 장단점이 있는 것 같다. 본인이 진행하는 프로젝트나 상황에 맞춰 사용을 하는 것이 좋은 것 같다. 이후에도 더 좋은 것들을 알게 되면 포스팅 해야지 오늘은 20000 ~~ 👋

reference