シェルスクリプトマガジン

Pythonあれこれ(Vol.100掲載)

著者:飯尾 淳

本連載では「Pythonを昔から使っているものの、それほど使いこなしてはいない」という筆者が、いろいろな日常業務をPythonで処理することで、立派な「蛇使い」に育つことを目指します。その過程を温かく見守ってください。皆さんと共に勉強していきましょう。第30回では、筆者らが実施している、異文化間交流を体験する国際プロジェクトの評価アンケートを対象に、回答状況を分析してみます。

シェルスクリプトマガジン Vol.100は以下のリンク先でご購入できます。

図4 NPSを計算するコード

promoters = df[df['Evaluation'] >= 9].shape[0]
detractors = df[df['Evaluation'] <= 6].shape[0]
total_respondents = df.shape[0]
promoter_percentage = (promoters / total_respondents) * 100
detractor_percentage = (detractors / total_respondents) * 100
nps = promoter_percentage - detractor_percentage
print(f"NPS: {nps:.1f}")

図5 NPS計算用のnps()関数を定義するコード

def nps(df):
  promoters = df[df['Evaluation'] >= 9].shape[0]
  detractors = df[df['Evaluation'] <= 6].shape[0]
  total_respondents = df.shape[0]

  promoter_percentage = (promoters / total_respondents) * 100
  detractor_percentage = (detractors / total_respondents) * 100
  return promoter_percentage - detractor_percentage

図6 感情分析をするコード

from transformers import AutoModelForSequenceClassification, \
                         AutoTokenizer, pipeline

model_name = "llm-book/bert-base-japanese-v3-marc_ja"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
cls = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
text = "迷子の子豚ちゃん。あなたの家はどこですか?"
print(cls(text))

図7 文単位に感情分析をするコード

df[‘NegaPosi’] \
= df[‘Comments(JP)’] \
.apply(lambda x: [cls(y)[0][‘label’] \
for y in x.strip().split(‘。’) if y != “”] \
if isinstance(x, str) else [])
df

図8 ネガティブな文を含むコメントを抽出するコード

for row in df[df['NegaPosi'] \
             .apply(lambda x: 'negative' in x)].iterrows():
  comments = [x for x in row[1]['Comments(JP)'].strip().split('。') \
              if x != ""]
  negaposi = row[1]['NegaPosi']
  for i in range(len(comments)):
    print(f"{negaposi[i]}: {comments[i]}")
  print()

図10 コメントの長さを国別に集計するコード

df['CommentsLength'] \
  = df[df['ST'].str.contains('Student')]['Comments(JP)'] \
      .apply(lambda x: len(x) if isinstance(x, str) else None)
df[['Country', 'CommentsLength']].groupby('Country') \
  .mean().sort_values('CommentsLength', ascending=False)