【데이터 분석편】RaspberryPi + 물체 검출 로 실내의 인원수를 slack 에 가시화

16793 단어 파이썬slack-api

개요



【구축편】RaspberryPi + 물체 검출 로 실내의 인원수를 slack 에 가시화의 계속입니다.

Slack의 채널에 실내의 인원수가 흐르게 되었습니다.


이번에는이 채널의 로그에서 과거 인원수 데이터를 얻고 그 데이터를 분석하려고합니다.

절차



채널 로그를 얻고 CSV 형식으로 저장



사전에 Slack API를 사용하여 데이터 검색을위한 앱을 만들고 토큰을 삼가합니다.
  • 주는 권한
  • channels:history
  • channels:read


  • 또한 채널 ID를 확인합니다.
    참고 : 슬랙의 채널 ID를 확인하는 방법

    필요한 정보를 검색하고 csv 형식으로 저장하는 Python 스크립트를 만들었습니다.

    logall.py
    import requests
    import re
    import time
    import json
    import pandas as pd
    
    url = "https://slack.com/api/channels.history"
    token = "(あなたのトークン)"
    channel_id = "(あなたのチャンネルID)"
    prog = re.compile("現在ゼミ室には [0-9]+名います.")
    
    # 他の発言を拾わないように,正規表現でマッチングする
    def is_match(text: str) -> bool:
        return prog.fullmatch(text) is not None
    
    # 人数抽出
    def text2people_num(text: str) -> int:
        return int(text.split('現在ゼミ室には ')[1].split('名います.')[0])
    
    def main():
        payload = {
            "token": token,
            "channel": channel_id,
            "count": 1000,
            }
        response = requests.get(url, params=payload)
    
        df = pd.DataFrame(columns=["timestamp", "people_num",])
    
        json_data = response.json()
        messages = json_data["messages"]
        for message in messages[::-1]:
            if is_match(message['text']):  # 欲しいデータであるとき
                ts = time.ctime(int(message['ts'].split('.')[0]))
                people_n = text2people_num(message["text"])
                print(ts, people_n)
                df = df.append(pd.Series([ts, people_n], index=df.columns), ignore_index=True)
    
        df.to_csv("room_log.csv")
    
    if __name__ == '__main__':
        main()
    

    csv 파일의 내용은 대체로 이런 느낌이 됩니다(Jupyter Notebook에서 열었기 때문에 id가 흔들리고 있는 점에 주의). 실제로 더 많은 행이 있습니다.


    csv 형식의 데이터를 Jupyter Notebook에서 열고 분석



    [1]
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    %matplotlib inline
    

    [2]
    df = pd.read_csv('room_log.csv', index_col=0)
    df
    

    데이터를 확인한 후 전처리를 수행합니다.
    타임 스탬프를 그대로 사용하기가 어렵 기 때문에 날짜와 시간 열을 추가합니다.
    또한 나중에 지난 달의 기록을 시각화하므로 달의 열도 추가합니다.
    이번에 원래 타임 스탬프는 여기에서 버렸습니다.

    [3]
    from calendar import month_abbr
    
    def timestamp2disc_time(ts: str) -> str:
        elms = ts.split()[-2]
        elms = elms.split(':')
        correct_minute = int(elms[1]) // 15 * 15
        return elms[0] + ':' + "%02d" % correct_minute
    
    def timestamp2date(ts: str) -> str:
        elms = ts.split()
        day = str("%02d" % int(elms[2]))
        elms = [elms[4], elms[1], day, '(' + elms[0] + ')']
        return " ".join(elms)
    
    month2int = dict()
    for i, key in enumerate(month_abbr):
        month2int[key] = i
    
    df['month'] = df['timestamp'].apply(lambda elm: month2int[elm.split()[1]])
    df['time'] = df['timestamp'].apply(timestamp2disc_time)
    df['date'] = df['timestamp'].apply(timestamp2date)
    df = df.drop('timestamp', axis=1)
    df
    

    이 시점의 데이터 프레임은 다음과 같습니다.


    seaborn의 히트 맵을 사용하여이 데이터를 명확하게 시각화합니다.
    히트 맵을 만들 때 seaborn에 제공하는 데이터 프레임을 만듭니다.
    참고 : Python으로 데이터 시각화 - 멋진 히트 맵을 그립니다.

    [4]
    df_pivot = pd.pivot_table(data=df[df['month'] == 6], values='people_num', columns='date', index='time', aggfunc=np.mean)
    df_pivot
    

    히트 맵을 그립니다. 세로로 길어지기 때문에 figsize 를 변경해 보기 쉽게 합니다.

    [5]
    plt.figure(figsize=(9, 20)) 
    sns.heatmap(df_pivot, annot=True, fmt='2g', cmap='Reds')
    



    히트 맵이므로, 실내의 인원수가 많았던 시간대만큼 색이 진하게 표시됩니다,

    요약



    데이터를 검색하고 처리하고 시각화하는 절차를 보여줍니다.
    향후는 요일마다의 이용 상황을 보거나, 기계 학습에 의해 이용 경향의 모델화를 행하면 재미있을지도 모른다고 생각하고 있습니다.

    좋은 웹페이지 즐겨찾기