人文学・社会学のための統計・線形代数学カリキュラム(日記)


##  第1部：人文・社会学におけるデータリテラシー基礎

### 1.1 なぜ数理が必要か？（拡張版）

####  背景：人文学と社会科学における「データ化」の流れ

* **定性的アプローチ**（例：インタビュー、歴史資料、文献読解）は今も中心。
* しかし近年では、

  * 調査票やアンケートによる**量的データ**の収集、
  * テキストや画像をベクトル化する**自然言語処理・計量的分析**、
  * 統計的仮説検定による**エビデンスの提示**
    が、研究の信頼性を高める手段として注目されている。

####  代表的な応用事例

| 分野    | 具体例             | 数理的アプローチ      |
| ----- | --------------- | ------------- |
| 教育社会学 | 家庭の学歴・収入と進学率の関係 | クロス集計・回帰分析    |
| 文学研究  | 登場人物の関係性分析      | ネットワーク分析・行列操作 |
| 歴史学   | 地域ごとの言語・宗教の分布変化 | GISとヒストグラム    |
| 文化人類学 | 儀式の頻度・構造比較      | 主成分分析・クラスター分析 |
| 言語学   | 単語使用頻度と社会属性     | TF-IDF・相関分析   |

---


####  データリテラシーに必要な3つの力

1. **読む力**：表・グラフ・数値の意味を理解する
2. **作る力**：データを整理し、可視化・加工する
3. **疑う力**：数値の背後にあるバイアスや前提を見抜く

---

####  推奨ツール紹介（入門向け）

| ツール                       | 特徴                     | 習得目安     |
| ------------------------- | ---------------------- | -------- |
| **Excel**                 | 直感的操作、統計関数、可視化         | 数時間で可能   |
| **Google Colab (Python)** | 無料・インストール不要、再現性の高い実習   | やや中級     |
| **R（RStudio）**            | 統計分析に強い、ggplot2で美しいグラフ | 学術的利用が多い |

---




##  第2部：記述統計の実践（Descriptive Statistics in Practice）

###  目標

* 中央傾向・ばらつき・比率の理解と可視化
* 実社会のデータ（語彙数・学歴・書評など）を扱う統計力を養成

---

### 2.1 平均・中央値・最頻値（代表値）

| 項目    | 内容例                  | Python対応                        |
| ----- | -------------------- | ------------------------------- |
| 社会的な例 | 世帯所得、語彙数、文章の文字数      | `df.describe()`, `df.mode()`    |
| 実装演習  | 文学テキストの語彙数、書評文の文字数など | `len(text.split())` の集計         |
| 可視化   | 散布図、棒グラフ、ラベル付き統計表    | `sns.histplot`, `plt.axvline()` |

---

### 2.2 分散・標準偏差・偏差値（ばらつきと相対化）

| 項目     | 内容例                  | Python対応                    |
| ------ | -------------------- | --------------------------- |
| 実データの例 | 評点分布（GPA）、書評の星数の散らばり | `df.std()`, `df.var()`      |
| 偏差値の導入 | 標準化 → 相対位置の評価        | 自作関数または`StandardScaler`     |
| 可視化    | ヒストグラム、箱ひげ図、Zスコア表示   | `sns.boxplot`, `plt.hist()` |

---

### 2.3 クロス集計と比率（カテゴリ変数の整理）

| 項目     | 内容例                | Python対応                             |
| ------ | ------------------ | ------------------------------------ |
| 社会調査例  | 性別×大学進学、新聞購読×投票意向  | `pd.crosstab()`, `groupby().mean()`  |
| 割合の可視化 | ヒートマップ、積み上げ棒グラフなど  | `sns.heatmap`, `df.plot(kind='bar')` |
| 社会学的考察 | 構造的偏差やカテゴリーのバランス感覚 | 分析後の言語的考察をレポートで補完                    |

---

##  第3部：推測統計と因果関係の理解（Inference and Causal Thinking）

###  目標

* 部分から全体を推測する思考法の習得
* 社会学的に有意味な「差」や「関係性」の統計的評価

---

### 3.1 サンプリングと母集団

| 項目    | 内容例                   | Python対応                            |
| ----- | --------------------- | ----------------------------------- |
| 抽出と推定 | 世論調査、図書館利用者の一部から全体を推測 | `np.random.choice()`, `bootstrap`関数 |
| 演習課題  | 文学作品の読者層調査の擬似標本を作成    | ブートストラップ平均分布の描画                     |
| 可視化   | 標本平均の分布、標本サイズと精度の関係   | `plt.hist()`, `plt.errorbar()`      |

---

### 3.2 信頼区間と誤差の感覚

| 項目     | 内容例                      | Python対応                   |
| ------ | ------------------------ | -------------------------- |
| 調査例    | 賛否アンケートで「±5%の誤差」とは？      | `scipy.stats.t.interval()` |
| 誤差の視覚化 | 棒グラフにエラーバーを表示            | `plt.bar()` + `yerr` 引数    |
| 教育効果   | 「誤差がある推測」の感覚と、慎重な結論の引き出し | 数値＋ビジュアル両方で定着させる           |

---

### 3.3 仮説検定とp値

| 項目    | 内容例                      | Python対応                         |
| ----- | ------------------------ | -------------------------------- |
| t検定   | ジェンダー別SNS利用時間・語彙量の違い     | `scipy.stats.ttest_ind()`        |
| χ²検定  | 性別×投票傾向、メディア使用×意見の一致度    | `scipy.stats.chi2_contingency()` |
| p値の解釈 | 小さいpは「有意」？「意味がある」？の誤解を解く | `print(f"p = {p_val:.3f}")`      |

---

### 3.4 相関と回帰

| 項目    | 内容例                             | Python対応                                    |
| ----- | ------------------------------- | ------------------------------------------- |
| 相関    | SNS使用時間と幸福度、学習時間とGPA            | `df.corr()`, `sns.heatmap()`                |
| 単回帰分析 | `statsmodels.formula.api.ols()` | `ols('happiness ~ sns_use', data=df).fit()` |
| 可視化   | 散布図＋回帰直線                        | `sns.lmplot()`                              |
| 発展    | 多変量回帰、交互作用項、標準化係数の導入            | `ols('happiness ~ sns_use + study_time')`   |






---

##  第4部：線形代数学の応用（Applied Linear Algebra）

| 節   | 内容              | 学習目標とPython実装例                                                                       |
| --- | --------------- | ------------------------------------------------------------------------------------ |
| 4.1 | ベクトルの基礎と応用      | 文書や人・地域を数値特徴ベクトルで表現<br>（例：TF-IDF, トピック数など）<br>🔧 `np.array`, `.reshape()`            |
| 4.2 | 行列によるデータ表現      | 出席行列や推薦システムのユーザー×アイテム行列を構築<br>🔧 `np.dot`, `df.values.T`                             |
| 4.3 | 固有値・固有ベクトルと意味論  | グラフの構造やPageRankにおける重要性の源泉<br>🔧 `np.linalg.eig`, `networkx.eigenvector_centrality()` |
| 4.4 | 主成分分析（PCA）と文化類型 | 高次元データ（例：文化価値観や意識調査）を2次元へ圧縮し可視化＋分類<br>🔧 `sklearn.decomposition.PCA`                 |


---

##  第5部：応用編（人文学・社会調査への実装）

| 節   | 内容           | 実践課題例とPython対応                                                                  |
| --- | ------------ | ------------------------------------------------------------------------------- |
| 5.1 | テキストの数理表現    | 文学作品や新聞記事のBag-of-Words表現／TF-IDF変換<br>🔧 `TfidfVectorizer`, `CountVectorizer`    |
| 5.2 | 社会調査データの分析   | 総務省e-Stat、World Bank等のCSVを加工・分析<br>🔧 `pandas`, `groupby`, `merge`, `seaborn`   |
| 5.3 | ネットワークと関係性分析 | 文学の人物ネットワークやインタビュー応答者の関係を可視化・分析<br>🔧 `networkx`, `centrality`, `spring_layout` |







```python
# -*- coding: utf-8 -*-
# プログラム名: sociology_literature_stats_practice.py
# 社会学・文学データを用いた記述統計演習 / Descriptive Stats for Sociology & Literature

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# --- 架空の社会学・文学データセット / Example Dataset for Sociology & Literature ---
data = {
    'gender': ['M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'F'],
    'read_time_min': [35, 42, 30, 50, 60, 28, 40, 55, 38],  # 読書時間（分）/ Reading time in minutes
    'literary_vocab_size': [1200, 1500, 1100, 1600, 1700, 1300, 1400, 1800, 1250],  # 文学語彙数
    'fav_genre': ['詩', '小説', '小説', '評論', '詩', '詩', '評論', '小説', '詩'],  # 好きなジャンル
    'vote_behavior': ['保守', 'リベラル', 'リベラル', '保守', '中立', 'リベラル', '保守', '保守', '中立']  # 投票傾向
}
df = pd.DataFrame(data)

# 1. 平均・中央値・最頻値 / Mean, Median, Mode
print("【代表値】")
print("平均（読書時間, 語彙数）:\n", df[['read_time_min', 'literary_vocab_size']].mean())
print("中央値:\n", df[['read_time_min', 'literary_vocab_size']].median())
print("最頻値:\n", df.mode(numeric_only=True).iloc[0])

# 2. 標準偏差・偏差値 / Std. Dev. & Deviation
print("\n【ばらつき】")
print("標準偏差:\n", df[['read_time_min', 'literary_vocab_size']].std())

def calc_deviation(x):
    return 50 + 10 * (x - x.mean()) / x.std()

df['vocab_dev'] = calc_deviation(df['literary_vocab_size'])
print("語彙数の偏差値:\n", df['vocab_dev'])

# 3. 可視化 / Visualization
plt.figure()
sns.boxplot(data=df[['read_time_min', 'literary_vocab_size']])
plt.title('Boxplot of Reading Time and Literary Vocabulary')
plt.show()

plt.figure()
sns.histplot(df['read_time_min'], kde=True, bins=5)
plt.title('Histogram of Reading Time')
plt.xlabel('Minutes')
plt.ylabel('Count')
plt.show()

# 4. クロス集計 / Cross Tab
print("\n【クロス集計】")
genre_by_gender = pd.crosstab(df['gender'], df['fav_genre'], normalize='index')
print("性別とジャンルの関係（行比率）:\n", genre_by_gender)

vote_by_genre = pd.crosstab(df['fav_genre'], df['vote_behavior'], normalize='index')
print("\nジャンルと投票傾向（行比率）:\n", vote_by_genre)

# 5. グループ別平均
print("\nジャンルごとの平均読書時間:")
print(df.groupby('fav_genre')['read_time_min'].mean())

print("\n投票傾向ごとの平均文学語彙:")
print(df.groupby('vote_behavior')['literary_vocab_size'].mean())


```



```python

# -*- coding: utf-8 -*-
# プログラム名: inference_causality_colab_sociology.py
# 社会学の文脈で推測統計と因果分析を行うGoogle Colab用統合コード

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import statsmodels.formula.api as smf
from sklearn.utils import resample

# --- データ生成（社会学的背景を考慮） ---
np.random.seed(42)
n = 200

# 性別（Male/Female）、政治参加（Support/Oppose）、年齢層
gender = np.random.choice(['Male', 'Female'], n)
vote = np.random.choice(['Support', 'Oppose'], n)
age_group = np.random.choice(['Youth', 'Adult', 'Senior'], n, p=[0.4, 0.4, 0.2])

# SNS使用時間：若者・女性が多め
sns_use = np.random.normal(3, 1.0, n) + (gender == 'Female') * 0.3 + (age_group == 'Youth') * 0.5

# 勉強時間：成人層・女性が多め
study_time = np.random.normal(2, 0.5, n) + (age_group == 'Adult') * 0.3 + (gender == 'Female') * 0.2

# 幸福度：政治参加、学習時間が影響する
happiness = 5.5 - 0.2 * sns_use + 0.4 * study_time + (vote == 'Support') * 0.5 + np.random.normal(0, 0.5, n)

df = pd.DataFrame({
    'gender': gender,
    'vote': vote,
    'age_group': age_group,
    'sns_use': sns_use,
    'study_time': study_time,
    'happiness': happiness
})

# --- 3.1 ブートストラップ（幸福度平均） ---
boot_means = [np.mean(np.random.choice(df['happiness'], 50, replace=True)) for _ in range(1000)]
plt.hist(boot_means, bins=30, color='lightgreen', edgecolor='black')
plt.title("Bootstrapped Happiness Mean Distribution")
plt.xlabel("Mean Happiness")
plt.ylabel("Frequency")
plt.grid(True)
plt.show()

# --- 3.2 信頼区間 ---
mean_h = df['happiness'].mean()
sem_h = stats.sem(df['happiness'])
ci_low, ci_high = stats.t.interval(0.95, df=n-1, loc=mean_h, scale=sem_h)
print(f"95% 信頼区間（幸福度）: {ci_low:.3f} 〜 {ci_high:.3f}")

# --- 3.3 仮説検定 ---
# t検定（男女のSNS使用）
t_stat, p_val = stats.ttest_ind(df[df['gender'] == 'Male']['sns_use'],
                                df[df['gender'] == 'Female']['sns_use'])
print(f"\nt検定（SNS使用: 男 vs 女）p = {p_val:.4f}")

# χ²検定（性別と投票傾向）
cont_table = pd.crosstab(df['gender'], df['vote'])
chi2, chi_p, _, _ = stats.chi2_contingency(cont_table)
print(f"χ²検定（性別 × 投票傾向）p = {chi_p:.4f}")

# --- 3.4 多変量回帰とブートストラップCI ---
model_multi = smf.ols('happiness ~ sns_use + study_time + C(vote) + C(gender)', data=df).fit()
boot_coeffs = []
for _ in range(1000):
    boot_sample = resample(df)
    boot_model = smf.ols('happiness ~ sns_use + study_time + C(vote) + C(gender)', data=boot_sample).fit()
    boot_coeffs.append(boot_model.params)

boot_df = pd.DataFrame(boot_coeffs)
ci_sns = np.percentile(boot_df['sns_use'], [2.5, 97.5])
ci_study = np.percentile(boot_df['study_time'], [2.5, 97.5])

# --- 結果表示 ---
print("\n多変量回帰の結果と95%ブートストラップ信頼区間：")
print(f"SNS使用 → 幸福度: {model_multi.params['sns_use']:.3f} (CI: {ci_sns[0]:.3f}〜{ci_sns[1]:.3f})")
print(f"勉強時間 → 幸福度: {model_multi.params['study_time']:.3f} (CI: {ci_study[0]:.3f}〜{ci_study[1]:.3f})")

# --- 散布図＋回帰直線 ---
sns.lmplot(x='sns_use', y='happiness', data=df, hue='gender')
plt.title("Regression: SNS Use vs Happiness (by Gender)")
plt.grid(True)
plt.show()

```



```python
# -*- coding: utf-8 -*-
# プログラム名: linear_algebra_application_sociology_pca.py
# 内容：社会学的データに対する線形代数の応用（主成分分析と文化類型クラスタリング）

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

# --- データ生成：社会的価値観に基づく例 / Simulated cultural values dataset ---
np.random.seed(0)
n = 100
df = pd.DataFrame({
    'tradition': np.random.normal(3, 0.7, n),      # 伝統重視 / Tradition
    'individualism': np.random.normal(4, 0.6, n),  # 個人主義 / Individualism
    'authority': np.random.normal(2.5, 0.8, n),    # 権威受容 / Authority
    'rationalism': np.random.normal(3.5, 0.5, n),  # 合理主義 / Rationalism
    'hedonism': np.random.normal(2.8, 0.6, n)      # 快楽主義 / Hedonism
})

# --- 標準化 / Standardization ---
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)

# --- PCA 主成分分析 / Principal Component Analysis ---
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# --- 結果格納 / Save results ---
df_pca = pd.DataFrame(X_pca, columns=['PC1', 'PC2'])

# --- 文化類型を3分割クラスタで分類 / Categorize by PC1 ---
df_pca['cluster_label'] = pd.cut(df_pca['PC1'], bins=3, labels=['Tradition-Oriented', 'Mixed', 'Modern-Oriented'])

# --- 結果表示（表）---
print("\n主成分寄与率 / Explained Variance Ratio:", pca.explained_variance_ratio_)

# --- 可視化 / Visualization ---
plt.figure(figsize=(8, 6))
sns.scatterplot(x='PC1', y='PC2', hue='cluster_label', data=df_pca, palette='Set2', s=80)
plt.title('Cultural Types by Principal Components')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.grid(True)
plt.legend(title='Cultural Cluster')
plt.show()


```


```python

# -*- coding: utf-8 -*-
# プログラム名: applied_humanities_sociology_full.py
# 第5部：人文学・社会調査への応用を統合したPythonプログラム
# 包含内容：TF-IDFベクトル化、地域統計分析、人物ネットワーク分析

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx
from sklearn.feature_extraction.text import TfidfVectorizer

# --- 5.1 テキストの数理表現（例：新聞記事）---
documents = [
    "経済成長と雇用の関係について議論が進んでいる。",
    "環境問題への対策が求められている。",
    "AI技術の進展が社会に影響を与えている。",
    "教育改革が進められており、オンライン学習が注目されている。",
    "政治と経済のつながりが議論されている。"
]

vectorizer = TfidfVectorizer()
X_tfidf = vectorizer.fit_transform(documents)
tfidf_df = pd.DataFrame(X_tfidf.toarray(), columns=vectorizer.get_feature_names_out())
print("【TF-IDF 文書ベクトル】")
print(tfidf_df)

# --- 5.2 社会調査データの分析（地域別統計）---
demo_data = {
    'Region': ['A市', 'B市', 'C市', 'D市', 'E市'],
    'Population': [120000, 85000, 95000, 130000, 70000],
    'University_Graduates': [36000, 21000, 25000, 40000, 15000],
    'Employed': [95000, 70000, 72000, 100000, 60000]
}
demo_df = pd.DataFrame(demo_data)
demo_df['Graduate_Rate'] = demo_df['University_Graduates'] / demo_df['Population']
demo_df['Employment_Rate'] = demo_df['Employed'] / demo_df['Population']

print("\n【地域別統計と比率】")
print(demo_df[['Region', 'Graduate_Rate', 'Employment_Rate']])

# --- 5.3 ネットワーク分析（人物関係）---
G = nx.Graph()
edges = [('Alice', 'Bob'), ('Alice', 'Carol'), ('Bob', 'Dave'), ('Carol', 'Dave'), ('Dave', 'Eve')]
G.add_edges_from(edges)

centrality = nx.degree_centrality(G)
nx.set_node_attributes(G, centrality, 'centrality')

pos = nx.spring_layout(G, seed=42)
plt.figure(figsize=(8, 6))
nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=800)
nx.draw_networkx_labels(G, pos)
plt.title("Character Network (Degree Centrality)")
plt.grid(True)
plt.show()

print("\n【人物の中心性指標（degree centrality）】")
for node, c in centrality.items():
    print(f"{node}: {c:.2f}")

```