maven에 새 jar를 추가하고 application을 실행해보니 아래와 같은 메세지가 나온다.

오류메세지

:A child container failed during start  
[java.util.concurrent.ExecutionException:](java.util.concurrent.ExecutionException:) [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [java.util.concurrent.FutureTask.report(FutureTask.java:122)](java.util.concurrent.FutureTask.report(FutureTask.java:122)) ~\[?:1.8.0\_77\]  
at [java.util.concurrent.FutureTask.get(FutureTask.java:192)](java.util.concurrent.FutureTask.get(FutureTask.java:192)) ~\[?:1.8.0\_77\]  
at [org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)](org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:911)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)](org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:890)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)](org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)) \[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [java.util.concurrent.FutureTask.run(FutureTask.java:266)](java.util.concurrent.FutureTask.run(FutureTask.java:266)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)](java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)) \[?:1.8.0\_77\]  
at [java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)](java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)) \[?:1.8.0\_77\]  
at [java.lang.Thread.run(Thread.java:745)](java.lang.Thread.run(Thread.java:745)) \[?:1.8.0\_77\]  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
... 6 more  
Caused by: [org.apache.catalina.LifecycleException:](org.apache.catalina.LifecycleException:) Failed to start component \[Pipeline\[StandardEngine\[Tomcat\].StandardHost\[localhost\].StandardContext\[\]\]\]  
at [org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)](org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  
at [org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)](org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5099)) ~\[[tomcat-embed-core-8.5.5.jar:8.5.5\]](tomcat-embed-core-8.5.5.jar:8.5.5])  

해결방법

검색해보니 servlet-api.jar를 exclude하라는 말이 많이 나왔는데
나의 경우 아래 설정을 pom에 추가하니 실행 성공하였다.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

provided 는 무엇을 의미하는지?

This scope is used to mark dependencies that should be provided at runtime by JDK or a container, hence the name.

A good use case for this scope would be a web application deployed in some container, where the container already provides some libraries itself.
컨테이너에서 deploy도는 어플리케이션에서 컨테이너는 이미 자체적인 라이브러리를 제공한다.

For example, a web server that already provides the Servlet API at runtime, thus in our project, those dependencies can be defined with the provided scope:
런타임에 의존성을 가지지 않고 컴파일/테스트단계에서만 제공되는 dependency.

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

The provided dependencies are available only at compile-time and in the test classpath of the project; what's more, they aren't transitive.

라이브러리 의존성을 피하기 위한 방법이리라.

  • embedding 벡터를 합치기 위해서는 np.zeros()를 통해 초기화를 진행하고
  • 초기화된 embed에 누적해서 벡터의 값을 더해주고
  • 마지막으로 합치는 벡터의 개수로 나눠준다.
def agg_embed(terms):
  embed = np.zeros(128) 
  for term in terms: 
      embed += np.array(term['embedding'])
  embed /= len(terms)
  return embed

sentence embedding을 얻었다면, 두개의 유사도를 계산하기 위해서는 cosine similarity를 이용해서 계산을 해야한다.

pandas에서 udf를 통해 계산하는 방법은 아래와 같다.
keywordcontext에는 문자열이 들어가면 된다.

ex: keyword: 안녕, context: 잘가요. 멀리 안가요


import numpy as np
from scipy import spatial

def sim(x, y): 
  embed1 = get_embed(x)  
  embed2 = get_embed(y) 
  return 1 - spatial.distance.cosine(embed1, embed2)

def sim_udf(x): 
  sim_value = sim(x['keyword'], x['context'])  
  return sim_value 


df['cosim'] = df.apply(sim_udf, axis=1)

python에서 Counter를 이용하면 list로 받은 값들의 개수를 계산한 해서 아래와 같이 결과를 받을 수 있다.

from collections import Counter
Counter(['apple','red','apple','red','red','pear'])
Counter({'red': 3, 'apple': 2, 'pear': 1})
  • 파이썬에서 한글, 영문, 숫자가 포함된 문자열에서 한글만 추출하는 방법에 대해서 설명한다.
  • python을 이용해서 한글처리를 하다보면 ㅋㅋㅋ, ㅎㅎㅎ와 같은 모음, 자음이 따로 있는 경우가 있는데 보통은 의미가 없다. 감정을 나타내는 문제에서는 의미가 있으려나...
  • 모/자음만 있는 한글을 추려내는 방법은 정규식을 사용하면 쉽게 추출, 제거 할 수 있다.

정규식에서 일치되는 부분을 리스트로 저장

import re

text = "ㅋㅋㅋ 안녕하세요"
# 정규식에서 일치되는 부분을 리스트 형태로 저장
re.compile('[ㄱ-ㅎ]+').findall(text) # 출력 ['ㅋㅋㅋ']

import re

text = "ㅋㅋㅋ 안녕하ㅏ세요"
# 정규식에서 일치되는 부분을 리스트 형태로 저장
re.compile('[ㄱ-ㅎ|ㅏ-ㅣ]+').findall(text) # 출력 ['ㅋㅋㅋ', 'ㅏ']

import re

text = "ㅋㅋㅋ 안녕하세요"
# 정규식에서 일치되는 부분을 리스트 형태로 저장
re.compile('[가-힣]+').findall(text) # 출력 ['안녕하세요']

정규식에서 일치되는 부분을 제외하고 추출

import re

text = "ㅋㅋㅋ 안녕하세요"
# 한글과 띄어쓰기을 제외하고 모든 글자 (자음, 모음만 있는경우 제외)
re.compile('[ |가-힣]+').sub('', text) # 출력 'ㅋㅋㅋ'


text = "하이 ㅋㅋㅋ 안녕하ㅏ세요"
# 정규식에서 일치되는 부분을  제외하고 저장
re.compile('[ |ㄱ-ㅎ|ㅏ-ㅣ]+').sub('',text) # 출력 '안녕하세요'

주의해야할 점

  • 주의해야 할 점은 두개의 결과가 리스트str으로 반환된다는 점이다.
  • 아래 예제를 통해서 내가 언제 어떤 상황에서 어떻게 처리해야할지 판단하면 된다.
import re

text = "ㅋㅋㅋ 안녕하ㅏ세요"
# 정규식에서 일치되는 부분을 리스트 형태로 저장
re.compile('[가-힣]+').findall(text) # 출력 ['안녕하', '세요']
text = "하이 ㅋㅋㅋ 안녕하ㅏ세요"
# 정규식에서 일치되는 부분을  제외하고 저장
re.compile('[ |ㄱ-ㅎ|ㅏ-ㅣ]+').sub('',text) # 출력 '안녕하세요'

python에서 한글 전처리를 하는 모음

from collections import Counter

special_chars = ['\n', '?', '.', '+', '~', '-', '_', ',', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', '[', ']' ,'/', '=', '`', '|']

def string_cleanup(x, notwanted):
    # import re
    for item in notwanted:
        x = x.replace(item, ' ')
        # x = re.sub(item, '', x)
    return x

def multiple_spaces_to_one(sentence):
    import re
    return re.sub(' +', ' ', sentence)

def remove_duplicated_words(sentence):

    return ' '.join(set(text.split(' ')))

def preprocessing(sentence):
    sentence = string_cleanup(sentence, special_chars) 
    sentence = re.compile('[0-9|ㄱ-ㅎ|ㅏ-ㅣ]+').sub('',sentence) # 'ㅋㅋㅋ', 'ㅏㅏ 제거'
    sentence = sentence.strip()
    sentence = sentence.lower()
    sentence = multiple_spaces_to_one(sentence)
    sentence = ' '.join(Counter(text.split(' ')).keys())
    return sentence

def preprocessing_udf(x):
  text = preprocessing(x['context'])
  return text  

result_df.head(2).apply(preprocessing_udf, axis=1)

datetime을 이용해서 날짜를 더하고 뺄수가 있다.

예를 들어서 8월 24일에서 90일 전의 날짜를 알고싶으면 datetime.timedelta를 사용하면 된다.

import datetime
t0 = datetime.datetime(2019,8,24)
delta = datetime.timedelta(days=90)
t0-delta

데이터 다운로드 받는 웹서버를 띄워서 사용하기 좋음
보통 외부 호스트에 있는 데이터를 가져올때
SimpleHTTPServer, http.server를 이용하면 좋음

  • python2에서는 python -m SimpleHTTPServer
  • python3에서는 python3 -m http.server

+ Recent posts