Claude-Light实验技能Skill claude-light

这个技能是关于使用Claude-Light远程实验仪器进行RGB LED控制和光谱测量的实验设计、数据收集、统计分析、回归建模、优化和机器学习应用。关键词:远程实验、光谱分析、数据科学、实验设计、机器学习、Claude-Light、Python编程、统计分析。

实验设计 1 次安装 2 次浏览 更新于 3/12/2026

名称: claude-light 描述: 专家助手,用于使用Claude-Light进行远程实验——一个可通过网络访问的RGB LED和光谱传感器仪器,用于统计、回归、优化和实验设计 允许工具: “*”

Claude-Light实验技能

您是使用Claude-Light设计和进行实验的专家助手,Claude-Light是一个远程实验室仪器,用于控制RGB LED并测量光谱响应。帮助用户执行统计分析、回归建模、优化和实验设计工作流程。

什么是Claude-Light?

Claude-Light是一个基于树莓派的远程实验仪器,它:

  • 控制RGB LED(输入:R、G、B值从0到1)
  • 测量10个光谱通道的光强度
  • 提供网络接口和REST API以进行远程访问
  • 支持实验方法和数据科学的实践学习

关键特性:

  • 无需特殊软件(网络浏览器或Python请求)
  • 自动记录所有实验
  • 通过相机记录LED状态
  • 多个复杂度级别(网络表单、API、Python脚本)

安装

基本API使用无需安装——只需使用Python的requests库。

# 基本要求
pip install requests

# 用于数据分析
pip install numpy pandas matplotlib scipy scikit-learn

API访问

端点

https://claude-light.cheme.cmu.edu/api

参数

  • R: 红色通道(0.0到1.0)
  • G: 绿色通道(0.0到1.0)
  • B: 蓝色通道(0.0到1.0)

响应格式

返回JSON,包含:

  • 输入参数(R、G、B)
  • 10个通道的光谱测量:
    • 415nm445nm480nm515nm555nm590nm630nm680nm
    • clear(总强度)
    • nir(近红外)

基本用法

import requests

# 发送实验
response = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': 0.5, 'G': 0.3, 'B': 0.8})

# 获取数据
data = response.json()
print(data)

# 访问特定波长
intensity_515 = data['out']['515nm']

实验工作流程

1. 可重复性和统计

目标:评估测量变异性和统计属性

import requests
import numpy as np

# 多次重复相同测量
R, G, B = 0.5, 0.5, 0.5
measurements = []

for i in range(30):
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()
    measurements.append(data['out']['515nm'])

# 计算统计
measurements = np.array(measurements)
print(f"均值: {np.mean(measurements):.2f}")
print(f"标准差: {np.std(measurements):.2f}")
print(f"中位数: {np.median(measurements):.2f}")
print(f"95% 置信区间: {np.percentile(measurements, [2.5, 97.5])}")

分析任务:

  • 计算均值、中位数、标准差
  • 绘制直方图并评估正态性
  • 计算置信区间
  • 确定测量精度

2. 线性回归(单变量)

目标:建立输入-输出关系

import requests
import numpy as np
from scipy.stats import linregress

# 变化一个输入,保持其他恒定
R_values = np.linspace(0, 1, 11)
outputs = []

for R in R_values:
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': 0, 'B': 0})
    data = resp.json()
    outputs.append(data['out']['630nm'])  # 红色波长

# 拟合线性模型
slope, intercept, r_value, p_value, std_err = linregress(R_values, outputs)

print(f"斜率: {slope:.2f}")
print(f"截距: {intercept:.2f}")
print(f"R²: {r_value**2:.4f}")
print(f"标准误差: {std_err:.2f}")

# 预测目标输出的输入
target_output = 25000
predicted_R = (target_output - intercept) / slope
print(f"预测R对于输出{target_output}: {predicted_R:.3f}")

分析任务:

  • 拟合线性模型
  • 计算R²、RMSE、MAE
  • 量化参数不确定性
  • 实验验证预测

3. 多元回归

目标:建模多个输入影响多个输出

import requests
import numpy as np
from sklearn.linear_model import LinearRegression

# 实验设计 - 网格采样
R_vals = np.linspace(0.1, 0.9, 5)
G_vals = np.linspace(0.1, 0.9, 5)

# 收集数据
X = []  # 输入
y_515 = []  # 输出在515nm
y_630 = []  # 输出在630nm

for R in R_vals:
    for G in G_vals:
        resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                           params={'R': R, 'G': G, 'B': 0})
        data = resp.json()

        X.append([R, G])
        y_515.append(data['out']['515nm'])
        y_630.append(data['out']['630nm'])

X = np.array(X)
y_515 = np.array(y_515)

# 拟合模型
model = LinearRegression()
model.fit(X, y_515)

print(f"R系数: {model.coef_[0]:.2f}")
print(f"G系数: {model.coef_[1]:.2f}")
print(f"截距: {model.intercept_:.2f}")
print(f"R²分数: {model.score(X, y_515):.4f}")

# 预测目标输出的输入
target = 30000
# 求解: target = coef[0]*R + coef[1]*G + intercept

分析任务:

  • 多输入、多输出建模
  • 特征重要性分析
  • 交互效应
  • 同时约束满足

4. 优化

目标:找到产生期望输出的输入

import requests
import numpy as np
from scipy.optimize import minimize

def objective(inputs):
    """最小化与目标输出的差异。"""
    R, G, B = inputs

    # 约束到有效范围
    R = np.clip(R, 0, 1)
    G = np.clip(G, 0, 1)
    B = np.clip(B, 0, 1)

    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()

    # 目标不同波长的特定输出
    target_515 = 30000
    target_630 = 20000

    actual_515 = data['out']['515nm']
    actual_630 = data['out']['630nm']

    # 平方误差
    error = (actual_515 - target_515)**2 + (actual_630 - target_630)**2
    return error

# 优化
initial_guess = [0.5, 0.5, 0.5]
result = minimize(objective, initial_guess,
                 bounds=[(0, 1), (0, 1), (0, 1)],
                 method='Nelder-Mead')

print(f"最优R, G, B: {result.x}")
print(f"最终误差: {result.fun}")

优化方法:

  • Scipy.optimize(Nelder-Mead、Powell、L-BFGS-B)
  • 贝叶斯优化(scikit-optimize)
  • 网格搜索插值
  • 主动学习方法

5. 实验设计(DOE)

目标:高效实验设计以获得最大信息

import requests
import numpy as np
from scipy.stats import qmc

# 拉丁超立方采样
sampler = qmc.LatinHypercube(d=3)  # 3维: R, G, B
n_samples = 20
sample = sampler.random(n=n_samples)

# 缩放至[0, 1]
samples = qmc.scale(sample, [0, 0, 0], [1, 1, 1])

# 运行实验
results = []
for R, G, B in samples:
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()
    results.append({
        'R': R, 'G': G, 'B': B,
        'output_515': data['out']['515nm'],
        'output_630': data['out']['630nm']
    })

# 分析空间填充设计
import pandas as pd
df = pd.DataFrame(results)

DOE策略:

  • 拉丁超立方采样
  • 析因设计(全、分式)
  • 响应曲面方法
  • 最优设计准则(D-optimal、A-optimal)

6. 机器学习方法

目标:使用先进ML模型进行预测

import requests
import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline

# 收集训练数据(使用先前方法)
X_train = # 输入RGB值
y_train = # 输出测量值

# 随机森林
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
print(f"RF R²分数: {rf.score(X_train, y_train):.4f}")

# 神经网络
mlp = MLPRegressor(hidden_layer_sizes=(50, 30), max_iter=1000)
mlp.fit(X_train, y_train)
print(f"MLP R²分数: {mlp.score(X_train, y_train):.4f}")

# 多项式回归
poly_model = Pipeline([
    ('poly', PolynomialFeatures(degree=2)),
    ('linear', LinearRegression())
])
poly_model.fit(X_train, y_train)

ML模型尝试:

  • 正则化线性模型(Ridge、Lasso)
  • 决策树和随机森林
  • 神经网络(MLPRegressor)
  • 高斯过程
  • XGBoost、LightGBM
  • 支持向量回归

7. 不确定性量化

目标:量化预测置信度

import requests
import numpy as np
from scipy import stats

# 引导不确定性估计
def bootstrap_regression(X, y, n_bootstrap=1000):
    slopes = []
    intercepts = []

    for _ in range(n_bootstrap):
        # 重采样替换
        indices = np.random.choice(len(X), size=len(X), replace=True)
        X_boot = X[indices]
        y_boot = y[indices]

        # 拟合模型
        slope, intercept, _, _, _ = stats.linregress(X_boot, y_boot)
        slopes.append(slope)
        intercepts.append(intercept)

    return np.array(slopes), np.array(intercepts)

# 使用引导结果计算置信区间
slopes, intercepts = bootstrap_regression(R_values, outputs)
print(f"斜率: {np.mean(slopes):.2f} ± {np.std(slopes):.2f}")
print(f"95% CI: {np.percentile(slopes, [2.5, 97.5])}")

不确定性方法:

  • 引导重采样
  • 预测区间
  • 参数协方差矩阵
  • 交叉验证
  • 蒙特卡洛模拟

最佳实践

数据管理

# 保存实验到CSV
import pandas as pd

experiments = []
for R in np.linspace(0, 1, 10):
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': 0, 'B': 0})
    data = resp.json()
    experiments.append({
        'R': R, 'G': 0, 'B': 0,
        **data['out']  # 解包所有光谱测量
    })

df = pd.DataFrame(experiments)
df.to_csv('experiments.csv', index=False)

背景减法

# 测量环境光
def get_background():
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': 0, 'G': 0, 'B': 0})
    return resp.json()['out']

bg = get_background()

# 从测量中减去
def corrected_measurement(R, G, B):
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()

    corrected = {}
    for wavelength in data['out']:
        corrected[wavelength] = data['out'][wavelength] - bg[wavelength]

    return corrected

平均降噪

def averaged_measurement(R, G, B, n_repeats=5):
    """进行多次测量并返回平均值。"""
    measurements = []

    for _ in range(n_repeats):
        resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                           params={'R': R, 'G': G, 'B': B})
        data = resp.json()
        measurements.append(data['out'])

    # 平均所有波长
    avg = {}
    for wavelength in measurements[0]:
        values = [m[wavelength] for m in measurements]
        avg[wavelength] = np.mean(values)

    return avg

缓存结果

import pickle
from pathlib import Path

def cached_experiment(R, G, B, cache_dir='experiments_cache'):
    """缓存实验以避免冗余API调用。"""
    Path(cache_dir).mkdir(exist_ok=True)

    # 创建唯一文件名
    cache_file = Path(cache_dir) / f"R{R:.3f}_G{G:.3f}_B{B:.3f}.pkl"

    if cache_file.exists():
        with open(cache_file, 'rb') as f:
            return pickle.load(f)

    # 执行实验
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()

    # 缓存结果
    with open(cache_file, 'wb') as f:
        pickle.dump(data, f)

    return data

可视化

import matplotlib.pyplot as plt

# 绘制光谱响应
def plot_spectrum(R, G, B):
    resp = requests.get('https://claude-light.cheme.cmu.edu/api',
                       params={'R': R, 'G': G, 'B': B})
    data = resp.json()

    wavelengths = ['415nm', '445nm', '480nm', '515nm',
                   '555nm', '590nm', '630nm', '680nm']
    intensities = [data['out'][wl] for wl in wavelengths]
    wl_values = [int(wl.replace('nm', '')) for wl in wavelengths]

    plt.figure(figsize=(10, 6))
    plt.plot(wl_values, intensities, 'o-')
    plt.xlabel('波长 (nm)')
    plt.ylabel('强度')
    plt.title(f'光谱对于 R={R}, G={G}, B={B}')
    plt.grid(True)
    plt.show()

# 绘制输入-输出关系
def plot_response_curve(channel='R', wavelength='515nm'):
    values = np.linspace(0, 1, 20)
    outputs = []

    for val in values:
        params = {'R': 0, 'G': 0, 'B': 0}
        params[channel] = val

        resp = requests.get('https://claude-light.cheme.cmu.edu/api', params=params)
        data = resp.json()
        outputs.append(data['out'][wavelength])

    plt.figure(figsize=(10, 6))
    plt.plot(values, outputs, 'o-')
    plt.xlabel(f'{channel} 输入')
    plt.ylabel(f'输出在 {wavelength}')
    plt.title(f'{channel} 响应在 {wavelength}')
    plt.grid(True)
    plt.show()

常见实验模式

模式1:单变量扫描

# 系统变化一个输入
for value in np.linspace(0, 1, 10):
    data = get_measurement(R=value, G=0, B=0)
    analyze(data)

模式2:析因设计

# 测试所有组合
for R in [0, 0.5, 1]:
    for G in [0, 0.5, 1]:
        for B in [0, 0.5, 1]:
            data = get_measurement(R, G, B)

模式3:梯度下降

# 迭代接近目标
current = [0.5, 0.5, 0.5]
learning_rate = 0.1

for iteration in range(10):
    gradient = estimate_gradient(current)
    current = current - learning_rate * gradient

错误处理

import requests
from requests.exceptions import Timeout, ConnectionError

def safe_experiment(R, G, B, max_retries=3):
    """具有重试逻辑的稳健实验。"""
    for attempt in range(max_retries):
        try:
            resp = requests.get(
                'https://claude-light.cheme.cmu.edu/api',
                params={'R': R, 'G': G, 'B': B},
                timeout=10
            )
            resp.raise_for_status()
            return resp.json()

        except (Timeout, ConnectionError) as e:
            if attempt == max_retries - 1:
                raise
            print(f"尝试 {attempt + 1} 失败,正在重试...")
            continue

资源